From 8d153bfd7c73519dd974307a0357dd3fee2a7ec8 Mon Sep 17 00:00:00 2001 From: AG Werschky Date: Mon, 3 Aug 2026 11:26:46 -0600 Subject: [PATCH 1/3] Make internal skills discoverable on grok and codex; add ticket-queue-discipline Wire .grok/skills and .codex/skills as symlinks to the canonical .agents/skills tree (matching .claude/skills), record verified harness discovery evidence, and add an agent-only skill for tracker-backed ticket judgment. --- .../skills/ticket-queue-discipline/SKILL.md | 68 ++++++++++++ .codex/skills | 1 + .github/workflows/ci.yml | 2 + .grok/skills | 1 + AGENTS.md | 5 +- CONTRIBUTING.md | 4 +- README.md | 3 +- docs/documentation-audiences.json | 8 ++ docs/verification/harness-skill-discovery.md | 100 ++++++++++++++++++ 9 files changed, 189 insertions(+), 3 deletions(-) create mode 100644 .agents/skills/ticket-queue-discipline/SKILL.md create mode 120000 .codex/skills create mode 120000 .grok/skills create mode 100644 docs/verification/harness-skill-discovery.md diff --git a/.agents/skills/ticket-queue-discipline/SKILL.md b/.agents/skills/ticket-queue-discipline/SKILL.md new file mode 100644 index 0000000000..e34692312b --- /dev/null +++ b/.agents/skills/ticket-queue-discipline/SKILL.md @@ -0,0 +1,68 @@ +--- +name: ticket-queue-discipline +description: >- + Agent-only judgment for tracker-backed ticket work. + Load before claiming, dispatching, closing, or auditing tickets in a project tracker + so readiness, claims, and close reasons stay tied to live canon rather than scratch state. +user-invocable: false +metadata: + internal: true +--- + +# ticket-queue-discipline + +This skill is judgment only. +Mechanizable claim, close, and status mutations belong in code and trackers, not here. +Load before claiming, dispatching, closing, or auditing tracker-backed ticket work. + +## One live tracker + +Treat one tracker as authoritative. +A per-ship scratch copy is never a source of readiness or claims - it drifts the moment work lands elsewhere. +Query live; never cache tracker state in durable firstmate records. + +## Claim at dispatch + +Claim atomically at dispatch (`bd update --claim` or the project's equivalent write-to-canon claim). +The value is the forced write to canon at the moment work is chosen, which is the verification step that catches already-delivered tickets before a worker starts. + +## Verify at pickup + +Check acceptance criteria against code and merge history, not against an impression of the ticket. +"Unclear" is a permitted answer and escalates - guessing acceptance criteria ships the wrong work. + +## Close with a satisfied-by reason + +Close only with a satisfied-by reason that names the merged PR. +A close without a land pointer makes later audits invent causality. + +## Decision classes + +- **Decide alone** - defects inside accepted criteria. + Reason: the ticket already authorized that fix surface. +- **Decide-and-report** - converging fix rounds, or fail-closed refusals that still leave the ticket on its intended path. + Reason: the captain needs the trail without owning every mechanical correction. +- **Stop-and-escalate** - the same defect family surviving twice, a new schema/contract/public interface, or a finding where the ticket fails its own criteria either way. + Reason: continuing alone burns cycles or freezes a bad contract. +- **Stop-for-the-captain** - widening or narrowing the product, accepting a residual, production, credentials, or customer data. + Reason: those choices are authority, not implementation detail. + +Log real decisions only - never routine mechanics - because the log is sampled and noise hides the few lines that matter. + +## Convergence + +Falling counts of distinct defects means keep going. +The same family surviving repeatedly means stop and reassess. +Without that distinction, thrash looks like progress. + +## Decision becomes a test + +Every decision becomes an executable test that would fail if the decision were reversed or dropped. +An untested decision is an oral history and will be lost on the next pass. + +## Evidence honesty + +A check rollup containing any FAILURE is not "green" without naming what failed and why it no longer counts. +"No checks reported" means UNPROVEN, never green. +Never report an instruction delivered without confirming it landed. +False green is worse than a visible red: it ends supervision of work that is still broken. diff --git a/.codex/skills b/.codex/skills new file mode 120000 index 0000000000..2b7a412b8f --- /dev/null +++ b/.codex/skills @@ -0,0 +1 @@ +../.agents/skills \ No newline at end of file diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 8530c5f9b2..177ab3ba2c 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -357,6 +357,8 @@ jobs: set -eu [ "$(readlink CLAUDE.md)" = "AGENTS.md" ] || { echo "::error::CLAUDE.md must be a symlink to AGENTS.md"; exit 1; } [ "$(readlink .claude/skills)" = "../.agents/skills" ] || { echo "::error::.claude/skills must be a symlink to ../.agents/skills"; exit 1; } + [ "$(readlink .codex/skills)" = "../.agents/skills" ] || { echo "::error::.codex/skills must be a symlink to ../.agents/skills"; exit 1; } + [ "$(readlink .grok/skills)" = "../.agents/skills" ] || { echo "::error::.grok/skills must be a symlink to ../.agents/skills"; exit 1; } - name: Personal fleet paths must not be tracked run: | set -eu diff --git a/.grok/skills b/.grok/skills new file mode 120000 index 0000000000..2b7a412b8f --- /dev/null +++ b/.grok/skills @@ -0,0 +1 @@ +../.agents/skills \ No newline at end of file diff --git a/AGENTS.md b/AGENTS.md index 23a33cda59..c1e5272828 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -60,7 +60,9 @@ README.md public overview and development notes .github/workflows/ shared CI and PR enforcement, committed .tasks.toml tracked tasks-axi markdown backend config for the default backlog backend (section 10) .agents/skills/ firstmate-loaded internal skills, committed; each carries metadata.internal=true for installers -.claude/skills symlink to .agents/skills for claude compatibility +.claude/skills symlink to .agents/skills for claude project discovery +.codex/skills symlink to .agents/skills for codex project discovery +.grok/skills symlink to .agents/skills for grok project discovery skills/ standalone public installer-facing skills, committed; not loaded by firstmate bin/ helper scripts, committed; read each script's header before first use .env optional X-mode pairing token; LOCAL, gitignored; presence-gates section 14 @@ -500,6 +502,7 @@ These skills are not captain-invocable; load them only at their precise triggers - `fmx-respond` - load on an `x-mention ` `check:` wake to handle the mention, on an `x-mode-error ...` `check:` wake to report the X-mode configuration blocker, on a `public-followup ...` `check:` wake or a startup-surfaced public commitment, and on any milestone or terminal wake for an X-mode-linked task before posting its completion follow-up; relevant only when X mode is on. - `firstmate-codexapp` - load before coordinating a visible Codex Desktop thread, evaluating a Codex App backend request, or reconciling Codex Desktop host-tool smoke evidence for Firstmate work. - `firstmate-coding-guidelines` - load before changing firstmate's shared, tracked material, as defined by section 1's list, whether editing directly or briefing a crewmate for a firstmate-repo task. +- `ticket-queue-discipline` - load before claiming, dispatching, closing, or auditing tracker-backed ticket work. ## 14. X mode diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index effd31a891..da8f0bbd09 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -34,7 +34,7 @@ See the [no-mistakes quick start](https://kunchenguid.github.io/no-mistakes/star ## Repo conventions - This repo is a template for running a firstmate orchestrator agent. - `AGENTS.md` is the agent's main job description and names when to load bundled firstmate skills; `CLAUDE.md` is a symlink to it, and `.claude/skills` is a symlink to `.agents/skills`. + `AGENTS.md` is the agent's main job description and names when to load bundled firstmate skills; `CLAUDE.md` is a symlink to it, and `.claude/skills`, `.codex/skills`, and `.grok/skills` are symlinks to `.agents/skills` so claude, codex, and grok project discovery share one canonical skill tree (see [`docs/verification/harness-skill-discovery.md`](docs/verification/harness-skill-discovery.md)). - Only shared material is tracked: `AGENTS.md`, `README.md`, `CONTRIBUTING.md`, `.tasks.toml`, `.github/workflows/`, `bin/`, `.agents/skills/`, and `skills/`. `.agents/skills/` holds agent-loaded skills that assume a live firstmate home and carry `metadata.internal: true` so installers such as [skills.sh](https://skills.sh) hide them from discovery; `skills/` holds standalone, installer-facing public skills with no firstmate dependency (see the README's "Two-tier skill layout"). Everything personal to one captain's fleet (`.env`, `data/`, `state/`, `config/`, `projects/`, `.no-mistakes/`) is gitignored; never commit it. @@ -84,6 +84,8 @@ bin/fm-test-isolation-proof.sh --list # proven parallel candidate set (Phase 2 bin/fm-test-isolation-proof.sh --jobs 4 --json /tmp/fm-isolation-proof.json # re-run concurrent isolation proof only [ "$(readlink CLAUDE.md)" = "AGENTS.md" ] [ "$(readlink .claude/skills)" = "../.agents/skills" ] +[ "$(readlink .codex/skills)" = "../.agents/skills" ] +[ "$(readlink .grok/skills)" = "../.agents/skills" ] tmp=$(mktemp -d) && printf 'done: smoke\n' > "$tmp/smoke.status" && FM_STATE_OVERRIDE="$tmp" FM_SIGNAL_GRACE=1 FM_POLL=1 FM_HEARTBEAT=999999 bin/fm-watch-arm.sh # watcher re-arm smoke test (prints arm status, then an actionable signal) ``` diff --git a/README.md b/README.md index ac54cf7025..84ec32f3a9 100644 --- a/README.md +++ b/README.md @@ -188,7 +188,7 @@ Agent-only reference skills live under `.agents/skills/` and are loaded by first Firstmate's skills live in two separate places with different audiences: -- `.agents/skills/` - agent-loaded skills (this section's table, plus firstmate's agent-only reference skills). Every one of these assumes a live firstmate home and is meaningless, or actively misleading, installed anywhere else, so each carries `metadata.internal: true` in its frontmatter. That flag hides them from installer discovery (tools like the [skills.sh](https://skills.sh) `npx skills add` installer) without affecting how firstmate itself loads them - frontmatter metadata is inert to the agent's own skill loader. +- `.agents/skills/` - agent-loaded skills (this section's table, plus firstmate's agent-only reference skills). Every one of these assumes a live firstmate home and is meaningless, or actively misleading, installed anywhere else, so each carries `metadata.internal: true` in its frontmatter. That flag hides them from installer discovery (tools like the [skills.sh](https://skills.sh) `npx skills add` installer) without affecting how firstmate itself loads them - frontmatter metadata is inert to the agent's own skill loader. Project discovery for claude, codex, and grok is wired through tracked symlinks (`.claude/skills`, `.codex/skills`, `.grok/skills`) that all point at this tree; see [`docs/verification/harness-skill-discovery.md`](docs/verification/harness-skill-discovery.md). - `skills/` - public, installer-facing skills meant to be installed standalone into any project, independent of firstmate. Each one is a self-contained skill with no dependency on firstmate's paths, tools, or vocabulary. Today that is `skills/stow`, a generic session-knowledge-sweep skill that routes findings by explicit instruction first, then existing local conventions, then a private `.stow-notes.md` fallback in the current directory, and closes with a resume pointer for the next session. @@ -207,6 +207,7 @@ Firstmate's skills live in two separate places with different audiences: - [docs/cmux-backend.md](docs/cmux-backend.md) - current setup, socket security, and limits for the experimental cmux backend. - [docs/codex-app-backend.md](docs/codex-app-backend.md) - the current blocked Codex App backend boundary and rollout contract. - [docs/verification/runtime-backends.md](docs/verification/runtime-backends.md) - active maintainer verification for runtime backend guarantees. +- [docs/verification/harness-skill-discovery.md](docs/verification/harness-skill-discovery.md) - active maintainer verification for claude, codex, and grok project skill discovery. - [docs/gitlab-merge-watch.md](docs/gitlab-merge-watch.md) - maintainer verification for GitLab merge watching on arbitrary instances. - [docs/turnend-guard.md](docs/turnend-guard.md) - the primary session's current "no turn ends blind" backstop, scope, loop safety, and compatibility limits. - [docs/verification/supervision.md](docs/verification/supervision.md) - active maintainer verification for session-start, guard, continuity, and wedge integrations. diff --git a/docs/documentation-audiences.json b/docs/documentation-audiences.json index f6075ab085..84e9284459 100644 --- a/docs/documentation-audiences.json +++ b/docs/documentation-audiences.json @@ -171,6 +171,10 @@ "path": ".agents/skills/stuck-crewmate-recovery/SKILL.md", "audience": "agent-runtime" }, + { + "path": ".agents/skills/ticket-queue-discipline/SKILL.md", + "audience": "agent-runtime" + }, { "path": ".agents/skills/updatefirstmate/SKILL.md", "audience": "agent-runtime" @@ -307,6 +311,10 @@ "path": "docs/verification/dispatch-auth.md", "audience": "maintainer-verification" }, + { + "path": "docs/verification/harness-skill-discovery.md", + "audience": "maintainer-verification" + }, { "path": "docs/verification/public-followup.md", "audience": "maintainer-verification" diff --git a/docs/verification/harness-skill-discovery.md b/docs/verification/harness-skill-discovery.md new file mode 100644 index 0000000000..499edf6101 --- /dev/null +++ b/docs/verification/harness-skill-discovery.md @@ -0,0 +1,100 @@ +# Harness skill discovery verification + +Audience: maintainer verification. + +This record supports the shared project-skill layout: `.agents/skills/` is the single canonical tree, and harness-native paths are symlinks to it (`.claude/skills`, `.codex/skills`, `.grok/skills`). +It records what each harness actually resolved on the versions below. +Task chronology stays in private reports or PR evidence. + +Verified 2026-08-03 in a linked git worktree of firstmate at +`/Users/agwerschky/.treehouse/firstmate-87f082/1/firstmate` +(`git rev-parse --show-toplevel` equals that path; `git-common-dir` points at the primary repo `.git`). + +## Versions + +| Harness | Binary | Version | +| --- | --- | --- | +| claude | `/Users/agwerschky/.local/bin/claude` | 2.1.220 (Claude Code) | +| codex | `/Users/agwerschky/.local/bin/codex` | codex-cli 0.146.0-alpha.9.2 | +| grok | `/Users/agwerschky/.local/bin/grok` | grok 0.2.118 (1e1687c1cf6a) [stable] | + +## Repo layout under test + +- Canonical tree: real directory `.agents/skills//SKILL.md` (no copy of skill bodies). +- Claude: existing tracked symlink `.claude/skills -> ../.agents/skills`. +- Codex and Grok: tracked symlinks `.codex/skills -> ../.agents/skills` and `.grok/skills -> ../.agents/skills` (added on this branch; same relative target as Claude). + +## What each harness resolved + +### Grok + +Commands: + +```sh +grok inspect --json +# plus disposable probe repos under /tmp with distinct skills in +# .agents/skills, .grok/skills, .claude/skills, and .codex/skills +``` + +Findings: + +- Project discovery works. +- Documented and observed project roots include `.grok/skills/`, `.agents/skills/`, and `.claude/skills/` (Claude compat). +- Grok does **not** treat project `.codex/skills/` as a skill root (probe skill there never appeared). +- With only the canonical `.agents/skills` tree present (before harness symlinks), every firstmate internal skill resolved as `source.type=project` with path under `.../firstmate/.agents/skills//SKILL.md`. +- After adding `.grok/skills -> ../.agents/skills`, the same skills resolve once (name-deduped) with path under `.../firstmate/.grok/skills//SKILL.md`. +- User-level skills still come from `~/.grok/skills/` (and optional Claude user compat paths). + +### Codex + +Commands: + +```sh +codex debug prompt-input "x" +# parse the model-visible ## Skills / ### Skill roots section +``` + +Findings: + +- Project discovery works for **both** `$REPO/.agents/skills` and `$REPO/.codex/skills` when they are distinct real directories (both appeared as separate skill roots; probe skills under each loaded). +- Official Codex docs also document walking `.agents/skills` from CWD up to the repo root (and user/admin/system locations). +- With only the real `.agents/skills` tree, every firstmate internal skill (all 18 pre-change names, then 19 including `ticket-queue-discipline`) appeared under skill root `.../firstmate/.agents/skills`. +- When `.codex/skills` is a symlink to `.agents/skills`, Codex lists a single project root at the resolved `.agents/skills` path and does **not** double-list the same skill. +- User-level skills come from `~/.codex/skills` (and related plugin/system roots). + +### Claude + +Commands: + +```sh +readlink .claude/skills # ../.agents/skills +test -f .claude/skills/afk/SKILL.md +git ls-files -s .claude/skills # mode 120000 (symlink) +``` + +Findings: + +- Claude project discovery is wired through `.claude/skills`, which is the long-standing tracked symlink to `../.agents/skills`. +- In this linked worktree the symlink resolves and skill files are readable through it. +- CI and CONTRIBUTING assert `[ "$(readlink .claude/skills)" = "../.agents/skills" ]` (and the same check for `.codex/skills` and `.grok/skills` after this branch). + +## Symlinks, worktrees, and clone + +Separate disposable git repo probe (not firstmate content): + +```sh +# after git add/commit of .agents/skills plus +# .claude/skills, .codex/skills, .grok/skills each -> ../.agents/skills +git clone +git worktree add HEAD +# in both clone and worktree: readlink and test -f /skills/x/SKILL.md +``` + +All three symlinks survived clone and linked worktree checkout and resolved to readable `SKILL.md` files when `core.symlinks` is enabled (default on this host). + +## Contract that follows + +1. Authors edit only `.agents/skills/`; never copy skill bodies into harness directories. +2. Harness-native paths stay symlinks to that tree so clone, worktree, and checkout stay one source of truth. +3. Do not invent a project path a harness does not scan; Grok's project `.codex/skills` is not a discovery root, while Codex does scan project `.codex/skills` when present. +4. Re-verify this record when a harness version changes skill-root behavior. From 5939a39fbf2e52a6fe8e22a56d42cfdc2c8a65b0 Mon Sep 17 00:00:00 2001 From: AG Werschky Date: Mon, 3 Aug 2026 11:41:47 -0600 Subject: [PATCH 2/3] no-mistakes(review): Record Claude runtime skill resolution evidence --- docs/verification/harness-skill-discovery.md | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/docs/verification/harness-skill-discovery.md b/docs/verification/harness-skill-discovery.md index 499edf6101..26471f2660 100644 --- a/docs/verification/harness-skill-discovery.md +++ b/docs/verification/harness-skill-discovery.md @@ -74,9 +74,17 @@ git ls-files -s .claude/skills # mode 120000 (symlink) Findings: +- The supervising Claude session at `/Users/agwerschky/git/firstmate` loaded five project skills from the repository path during this task session: `ask-user-authority`, `secondmate-provisioning`, `stuck-crewmate-recovery`, `bootstrap-diagnostics`, and `harness-adapters`. +- Each invocation returned the skill body. +- Each skill resolves through `.claude/skills -> ../.agents/skills` to `.agents/skills//SKILL.md`, as confirmed by `readlink -f`. +- This is a live load observation, not an inference from the symlink alone. +- `ticket-queue-discipline` itself has not been loaded by a Claude session because it exists only on the feature branch and is not yet in the main home. +- Claude project-skill resolution is observed for existing internal skills through the same symlink the new skill uses, and `ticket-queue-discipline` inherits that path. +- A post-merge Claude load of `ticket-queue-discipline` is the remaining confirmation and must be performed after merge. - Claude project discovery is wired through `.claude/skills`, which is the long-standing tracked symlink to `../.agents/skills`. - In this linked worktree the symlink resolves and skill files are readable through it. - CI and CONTRIBUTING assert `[ "$(readlink .claude/skills)" = "../.agents/skills" ]` (and the same check for `.codex/skills` and `.grok/skills` after this branch). +- These filesystem and CI checks support the wiring evidence but do not substitute for the runtime load observation above. ## Symlinks, worktrees, and clone From 8610bc42b554840ce70d3fd97057b3942da5a346 Mon Sep 17 00:00:00 2001 From: AG Werschky Date: Mon, 3 Aug 2026 11:56:12 -0600 Subject: [PATCH 3/3] no-mistakes(document): Document cross-harness skill discovery evidence --- docs/verification/harness-skill-discovery.md | 65 +++++++++++++++----- 1 file changed, 50 insertions(+), 15 deletions(-) diff --git a/docs/verification/harness-skill-discovery.md b/docs/verification/harness-skill-discovery.md index 26471f2660..34be037130 100644 --- a/docs/verification/harness-skill-discovery.md +++ b/docs/verification/harness-skill-discovery.md @@ -6,9 +6,9 @@ This record supports the shared project-skill layout: `.agents/skills/` is the s It records what each harness actually resolved on the versions below. Task chronology stays in private reports or PR evidence. -Verified 2026-08-03 in a linked git worktree of firstmate at -`/Users/agwerschky/.treehouse/firstmate-87f082/1/firstmate` -(`git rev-parse --show-toplevel` equals that path; `git-common-dir` points at the primary repo `.git`). +Verified 2026-08-03 in the isolated firstmate worktree at +`/Users/agwerschky/.no-mistakes/worktrees/e661563b090a/01KZ4B0458NGJFN2BJ5QTM3VFN` +at commit `5939a39fbf2e52a6fe8e22a56d42cfdc2c8a65b0`. ## Versions @@ -36,6 +36,21 @@ grok inspect --json # .agents/skills, .grok/skills, .claude/skills, and .codex/skills ``` +Relevant output for the new skill, after confirming that neither it nor `firstmate-coding-guidelines` existed under `~/.grok/skills`: + +```json +{ + "skill": { + "name": "ticket-queue-discipline", + "source": { + "type": "project", + "path": "/Users/agwerschky/.no-mistakes/worktrees/e661563b090a/01KZ4B0458NGJFN2BJ5QTM3VFN/.grok/skills/ticket-queue-discipline/SKILL.md" + }, + "userInvocable": false + } +} +``` + Findings: - Project discovery works. @@ -43,6 +58,7 @@ Findings: - Grok does **not** treat project `.codex/skills/` as a skill root (probe skill there never appeared). - With only the canonical `.agents/skills` tree present (before harness symlinks), every firstmate internal skill resolved as `source.type=project` with path under `.../firstmate/.agents/skills//SKILL.md`. - After adding `.grok/skills -> ../.agents/skills`, the same skills resolve once (name-deduped) with path under `.../firstmate/.grok/skills//SKILL.md`. +- `firstmate-coding-guidelines` and `ticket-queue-discipline` were both absent from `~/.grok/skills`, so their observed `source.type=project` results did not come from user-level copies. - User-level skills still come from `~/.grok/skills/` (and optional Claude user compat paths). ### Codex @@ -54,6 +70,13 @@ codex debug prompt-input "x" # parse the model-visible ## Skills / ### Skill roots section ``` +Relevant model-visible output: + +```text +- `r0` = `/Users/agwerschky/.no-mistakes/worktrees/e661563b090a/01KZ4B0458NGJFN2BJ5QTM3VFN/.agents/skills` +- ticket-queue-discipline: Agent-only judgment for tracker-backed ticket work. Load before claiming, dispatching, closing, or auditing tickets in a project tracker so readiness, claims, and close reasons sta (file: r0/ticket-queue-discipline/SKILL.md) +``` + Findings: - Project discovery works for **both** `$REPO/.agents/skills` and `$REPO/.codex/skills` when they are distinct real directories (both appeared as separate skill roots; probe skills under each loaded). @@ -67,27 +90,39 @@ Findings: Commands: ```sh -readlink .claude/skills # ../.agents/skills -test -f .claude/skills/afk/SKILL.md -git ls-files -s .claude/skills # mode 120000 (symlink) +claude -p --output-format stream-json --verbose --no-session-persistence \ + --permission-mode dontAsk --tools Skill \ + --debug-file /var/folders/bd/ky17fvwx45353ky4s2bg8ys80000gn/T/no-mistakes-evidence/01KZ4B0458NGJFN2BJ5QTM3VFN/claude-skill-debug.log \ + --system-prompt 'Use the Skill tool when instructed. Do not use any other tool.' \ + 'Load the project skill ticket-queue-discipline. Then reply only: LOADED ticket-queue-discipline.' +rg 'Loading skills from:|SkillTool returning' \ + /var/folders/bd/ky17fvwx45353ky4s2bg8ys80000gn/T/no-mistakes-evidence/01KZ4B0458NGJFN2BJ5QTM3VFN/claude-skill-debug.log ``` Findings: -- The supervising Claude session at `/Users/agwerschky/git/firstmate` loaded five project skills from the repository path during this task session: `ask-user-authority`, `secondmate-provisioning`, `stuck-crewmate-recovery`, `bootstrap-diagnostics`, and `harness-adapters`. -- Each invocation returned the skill body. -- Each skill resolves through `.claude/skills -> ../.agents/skills` to `.agents/skills//SKILL.md`, as confirmed by `readlink -f`. -- This is a live load observation, not an inference from the symlink alone. -- `ticket-queue-discipline` itself has not been loaded by a Claude session because it exists only on the feature branch and is not yet in the main home. -- Claude project-skill resolution is observed for existing internal skills through the same symlink the new skill uses, and `ticket-queue-discipline` inherits that path. -- A post-merge Claude load of `ticket-queue-discipline` is the remaining confirmation and must be performed after merge. -- Claude project discovery is wired through `.claude/skills`, which is the long-standing tracked symlink to `../.agents/skills`. -- In this linked worktree the symlink resolves and skill files are readable through it. +- Claude's debug log names the project skill root as this worktree's `.claude/skills` path. +- The agent invoked `Skill` with `{"skill":"ticket-queue-discipline"}`. +- The runtime returned `Launching skill: ticket-queue-discipline`, logged `SkillTool returning 2 newMessages for skill ticket-queue-discipline`, and the agent replied `LOADED ticket-queue-discipline.` with `subtype=success` and `is_error=false`. +- This is a live load of the new skill in the feature worktree, not an inference from the symlink alone. +- `.claude/skills -> ../.agents/skills` resolves that runtime root to the same canonical body used by Codex and Grok. - CI and CONTRIBUTING assert `[ "$(readlink .claude/skills)" = "../.agents/skills" ]` (and the same check for `.codex/skills` and `.grok/skills` after this branch). - These filesystem and CI checks support the wiring evidence but do not substitute for the runtime load observation above. ## Symlinks, worktrees, and clone +The target commit records all three harness paths as git symlinks with the same link-target blob: + +```sh +git ls-files -s .claude/skills .codex/skills .grok/skills +``` + +```text +120000 2b7a412b8fa0fb7e985b0793321bd4e698f2b6cd 0 .claude/skills +120000 2b7a412b8fa0fb7e985b0793321bd4e698f2b6cd 0 .codex/skills +120000 2b7a412b8fa0fb7e985b0793321bd4e698f2b6cd 0 .grok/skills +``` + Separate disposable git repo probe (not firstmate content): ```sh