From 235bf3ea778dd913191bda7023f5da406960446f Mon Sep 17 00:00:00 2001 From: Aaron Trowbridge Date: Thu, 10 Sep 2026 18:10:16 -0400 Subject: [PATCH 1/2] fix(agents): mode cards load their mode-protocol skill at kickoff, not just director-core (#989) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Both director cards' first-action directive named only the engine-neutral spine skill; the mode's own binding (spec-gate mechanics, roles, probe/experiment boundary) was never invoked — observed cutting the corner in a 2026-09-10 research pickup. The directive now requires BOTH skills, in order, and a mode-cards floor test pins the pairing per card. --- packages/extension/agents/develop.md | 13 ++++---- packages/extension/agents/research.md | 11 ++++--- packages/extension/test/mode_cards.test.ts | 35 ++++++++++++++++++++++ 3 files changed, 50 insertions(+), 9 deletions(-) diff --git a/packages/extension/agents/develop.md b/packages/extension/agents/develop.md index 07ca43be..ba2d1540 100644 --- a/packages/extension/agents/develop.md +++ b/packages/extension/agents/develop.md @@ -14,11 +14,14 @@ the shipped skill library). You automate the *walk*, never the *gate*: every package edit still requires an issue and a PR, CI green is still the merge condition, and promotions stay human-only. -**First action (kickoff or resume): invoke the `director-core` skill and follow it.** -It is the canonical loop protocol; the spine below is its summary, never a -replacement. Your mode's specifics — the phase graph, gates, and roles — are the -**dev gate pack** (`modes/develop/pack.toml` in the amicode repo, schema'd and -fixture-tested): phases decompose → implement → integrate. +**First actions (kickoff or resume): invoke the `director-core` skill, THEN the +`autodev` skill — both, before acting on the loop.** `director-core` is the +canonical, engine-neutral loop protocol; `autodev` is this mode's binding of it +(the gate pack's phases, the implementer cast, the dispatch and gate discipline) — +the spine below is a summary of both, never a replacement for either. Your mode's +specifics — the phase graph, gates, and roles — are the **dev gate pack** +(`modes/develop/pack.toml` in the amicode repo, schema'd and fixture-tested): +phases decompose → implement → integrate. ## The spine diff --git a/packages/extension/agents/research.md b/packages/extension/agents/research.md index ba15338e..01894d55 100644 --- a/packages/extension/agents/research.md +++ b/packages/extension/agents/research.md @@ -14,10 +14,13 @@ principle is fixed: **the context window is a cache; the vault is the database.* piece of load-bearing state lives in vault notes; the context holds only the working set; any compaction costs a cache refill, never state. -**First action (kickoff or resume): invoke the `director-core` skill and follow it.** It -is the canonical loop protocol; the spine below is its summary, never a replacement. -Your mode's specifics — the phase graph, gates, and roles — are the **research gate -pack** (`modes/research/pack.toml` in the amicode repo, schema'd and fixture-tested): +**First actions (kickoff or resume): invoke the `director-core` skill, THEN the +`research` skill — both, before acting on the loop.** `director-core` is the +canonical, engine-neutral loop protocol; `research` is this mode's binding of it +(the loop steps, the spec-gate mechanics, the roles, the probe/experiment boundary) +— the spine below is a summary of both, never a replacement for either. Your mode's +specifics — the phase graph, gates, and roles — are the **research gate pack** +(`modes/research/pack.toml` in the amicode repo, schema'd and fixture-tested): phases hypothesize → deliberate → experiment → gate → analyze. ## The spine diff --git a/packages/extension/test/mode_cards.test.ts b/packages/extension/test/mode_cards.test.ts index 3c7ad1e1..b029c711 100644 --- a/packages/extension/test/mode_cards.test.ts +++ b/packages/extension/test/mode_cards.test.ts @@ -237,6 +237,41 @@ describe("mode cards — frontmatter (boot-check fields)", () => { } }); +// ── #989: first-actions skill pairing ──────────────────────────────────────── +// Each mode card must wire the director into BOTH the shared spine AND its +// own mode-protocol skill at kickoff/resume, in that order. The 2026-09-10 +// research pickup loaded only director-core (the directive named no mode +// skill, so the director treated the spine summary as sufficient and skipped +// the mode binding — spec-gate mechanics, roles, probe/experiment boundary); +// the cards now name both, and this floor pins the pairing. +const MODE_SKILL: Record = { + // the dev mode's protocol skill (its id keeps the pre-rename mode name) + "develop.md": "autodev", + // the research mode's protocol skill (ex-autoresearch; old id read-resolves) + "research.md": "research", +}; + +describe("mode cards — first-actions skill pairing (#989)", () => { + for (const name of CARDS) { + it(`${name}: first-action directive loads director-core AND its mode skill`, () => { + const text = cardText(name); + // the directive lives in the preamble, before the delimited spine + const preamble = text.slice(0, text.indexOf(SPINE_START)); + const coreAt = preamble.indexOf("`director-core`"); + const modeAt = preamble.indexOf(`\`${MODE_SKILL[name]}\``); + expect( + coreAt, + "the card names the shared spine skill in its first-action directive", + ).toBeGreaterThan(-1); + expect( + modeAt, + `the card names its mode-protocol skill (\`${MODE_SKILL[name]}\`) in its first-action directive`, + ).toBeGreaterThan(-1); + expect(modeAt, "the mode skill is named after the spine skill").toBeGreaterThan(coreAt); + }); + } +}); + describe("mode cards — blocklist (open-protocol vocabulary)", () => { for (const name of CARDS) { it(`${name}: zero blocklisted proprietary strings`, () => { From 18c1e63e41b2299f2aca11842c42d09b44dc7273 Mon Sep 17 00:00:00 2001 From: Aaron Trowbridge Date: Thu, 10 Sep 2026 18:32:59 -0400 Subject: [PATCH 2/2] fix(agents): mirror the first-actions directive into the mode-bundle cards (AC9 parity, #989) --- packages/extension/modes/develop/card.md | 13 ++++++++----- packages/extension/modes/research/card.md | 11 +++++++---- 2 files changed, 15 insertions(+), 9 deletions(-) diff --git a/packages/extension/modes/develop/card.md b/packages/extension/modes/develop/card.md index 07ca43be..ba2d1540 100644 --- a/packages/extension/modes/develop/card.md +++ b/packages/extension/modes/develop/card.md @@ -14,11 +14,14 @@ the shipped skill library). You automate the *walk*, never the *gate*: every package edit still requires an issue and a PR, CI green is still the merge condition, and promotions stay human-only. -**First action (kickoff or resume): invoke the `director-core` skill and follow it.** -It is the canonical loop protocol; the spine below is its summary, never a -replacement. Your mode's specifics — the phase graph, gates, and roles — are the -**dev gate pack** (`modes/develop/pack.toml` in the amicode repo, schema'd and -fixture-tested): phases decompose → implement → integrate. +**First actions (kickoff or resume): invoke the `director-core` skill, THEN the +`autodev` skill — both, before acting on the loop.** `director-core` is the +canonical, engine-neutral loop protocol; `autodev` is this mode's binding of it +(the gate pack's phases, the implementer cast, the dispatch and gate discipline) — +the spine below is a summary of both, never a replacement for either. Your mode's +specifics — the phase graph, gates, and roles — are the **dev gate pack** +(`modes/develop/pack.toml` in the amicode repo, schema'd and fixture-tested): +phases decompose → implement → integrate. ## The spine diff --git a/packages/extension/modes/research/card.md b/packages/extension/modes/research/card.md index ba15338e..01894d55 100644 --- a/packages/extension/modes/research/card.md +++ b/packages/extension/modes/research/card.md @@ -14,10 +14,13 @@ principle is fixed: **the context window is a cache; the vault is the database.* piece of load-bearing state lives in vault notes; the context holds only the working set; any compaction costs a cache refill, never state. -**First action (kickoff or resume): invoke the `director-core` skill and follow it.** It -is the canonical loop protocol; the spine below is its summary, never a replacement. -Your mode's specifics — the phase graph, gates, and roles — are the **research gate -pack** (`modes/research/pack.toml` in the amicode repo, schema'd and fixture-tested): +**First actions (kickoff or resume): invoke the `director-core` skill, THEN the +`research` skill — both, before acting on the loop.** `director-core` is the +canonical, engine-neutral loop protocol; `research` is this mode's binding of it +(the loop steps, the spec-gate mechanics, the roles, the probe/experiment boundary) +— the spine below is a summary of both, never a replacement for either. Your mode's +specifics — the phase graph, gates, and roles — are the **research gate pack** +(`modes/research/pack.toml` in the amicode repo, schema'd and fixture-tested): phases hypothesize → deliberate → experiment → gate → analyze. ## The spine