Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
121 commits
Select commit Hold shift + click to select a range
c3c65f8
feat(build): generate per-op GitHub tracker references from an MDS mo…
dean0x Sep 13, 2026
4a2c11b
test(tracker): pin the byte budget before any text moves (P2-S1, AC-2.5)
dean0x Sep 13, 2026
17ffa60
feat(git-agent): add the provider-resolution preamble (P2-S3, GAP-10)
dean0x Sep 13, 2026
08c1190
test(tracker): add the containment oracle and its 101bda7 baselines (…
dean0x Sep 13, 2026
6f7230f
test(tracker): anchor generated references and split the conventions …
dean0x Sep 13, 2026
fcec744
test(git-agent): widen the D11 inline-body guard on pattern and scope…
dean0x Sep 13, 2026
82d8b86
refactor(git-skill): cut skills/git/SKILL.md to the byte budget (P2-S…
dean0x Sep 13, 2026
16baec2
refactor(git-skill): move github-api.md's tracker sections to per-op …
dean0x Sep 13, 2026
ac9bd3e
refactor(git-agent): cut the marker legend to D4 and D11 (P2-S5 cut 3…
dean0x Sep 13, 2026
a3ec0a0
refactor(git-agent): move setup-task mechanics to its GitHub referenc…
dean0x Sep 13, 2026
81a3fc0
refactor(git-agent): move fetch-issue mechanics to its GitHub referen…
dean0x Sep 13, 2026
1e0c6dd
refactor(git-agent): move the fetch-issues-batch query to its GitHub …
dean0x Sep 13, 2026
3c0ede3
refactor(git-agent): move manage-debt mechanics to its GitHub referen…
dean0x Sep 13, 2026
c13b02c
refactor(git-agent): move create-release's Closed Issues step to its …
dean0x Sep 13, 2026
541d515
refactor(git-agent): move gather-release-evidence's ref-parsing step …
dean0x Sep 13, 2026
9c704df
fix(git-agent): make release-evidence ref resolution batch-first (P2-…
dean0x Sep 13, 2026
373f996
refactor(git-agent): move backlink-shipped-issues mechanics to its re…
dean0x Sep 13, 2026
879c860
refactor(git-agent): move ensure-traceable-issue mechanics to its ref…
dean0x Sep 13, 2026
1b87b3c
refactor(git-agent): move post-wave-report mechanics to its reference…
dean0x Sep 13, 2026
4942a73
refactor(git-agent): move ensure-pr-ready step 4b to its GitHub refer…
dean0x Sep 13, 2026
5435b50
refactor(git-agent): cut learn-conventions' scan into a generated ref…
dean0x Sep 13, 2026
7fedbb1
refactor(git-agent): cut the D10 publication gate into a generated re…
dean0x Sep 13, 2026
bcff97d
refactor(git-agent): split the D4/D11 invariants from their GitHub de…
dean0x Sep 13, 2026
0329031
refactor(git-agent): state the retained mechanics pointer identically…
dean0x Sep 13, 2026
caae772
feat(commands): add _partials/_tracker.mds and adopt it in five hosts…
dean0x Sep 13, 2026
2ae0893
feat(code-agent): consume the Git agent's Handoff Values (P2-S10, GAP…
dean0x Sep 14, 2026
1953114
refactor(commands): adopt {ISSUE_REF}/{ISSUE_ID} vocabulary (P2-S11, …
dean0x Sep 14, 2026
bbf0936
refactor(commands): let operations own their markers and side-effect …
dean0x Sep 14, 2026
b65a8c0
test(dynamic): pin the wave skeleton's caller-side containment wrap (…
dean0x Sep 14, 2026
47352d6
test(installer): add the reference-overlay guard and its known-bad pr…
dean0x Sep 14, 2026
c288d98
feat(installer): converge the generated git references with an atomic…
dean0x Sep 14, 2026
b48919f
test(packaging): pin the generated skill references in the packed tar…
dean0x Sep 14, 2026
eed0ca1
test(guards): register the generated-reference manifest floors (P2-S14)
dean0x Sep 14, 2026
09bb698
docs(installer): keep non-github provider names out of src (§14.5)
dean0x Sep 14, 2026
179ba71
test(guards): land the Phase-2 guard battery (P2-S15)
dean0x Sep 14, 2026
dd42ea1
test(helpers): retarget the status-line extractor onto the split tree
dean0x Sep 14, 2026
e4876e0
test(goldens): re-capture github-status-lines.txt once for the Phase-…
dean0x Sep 14, 2026
2e019a5
test(goldens): regenerate git-agent.md after the Phase-2 contract/mec…
dean0x Sep 14, 2026
1ed56df
docs: sweep the branch's final tree for Phase-2 artifacts (P2-S17)
dean0x Sep 14, 2026
ce73efd
refactor: drop redundant re-trim and array-backed lookups in tracker …
dean0x Sep 14, 2026
b902bee
fix(installer): restore the displaced unit when a reference promotion…
dean0x Sep 14, 2026
2bf69ce
fix(git-refs): compose every tracker body before posting it, and scop…
dean0x Sep 14, 2026
e8f0838
test(tracker): close three vacuity gaps in the Phase-2 guard battery
dean0x Sep 14, 2026
10ac94c
test(goldens): regenerate git-agent.md after the Scrutinize-pass agen…
dean0x Sep 14, 2026
f2591aa
test(guards): make capability-hoist prove it scanned both halves of i…
dean0x Sep 14, 2026
efe667a
fix(commands): forward ISSUE_PR_LINK to the Code agent at every spawn…
dean0x Sep 14, 2026
fede786
test(guards): close the Scrutinize-pass P2 gaps
dean0x Sep 14, 2026
79afbea
fix(tracker): scope the issue-capture contract to its real producers
dean0x Sep 14, 2026
8282503
test(dynamic): pin the four AC-2.10 renderings by occurrence count
dean0x Sep 14, 2026
e14c871
test(tracker): account for cross-cutting references in the byte budget
dean0x Sep 14, 2026
5cad6ee
test(tracker): walk the full reference manifest for AC-2.7 reachability
dean0x Sep 14, 2026
aea2bb6
test(guards): close two manifest gaps in the Phase-2 battery
dean0x Sep 14, 2026
0c69e24
docs(changelog): refresh Phase-2 figures to the final tree
dean0x Sep 14, 2026
71b2d5c
docs(knowledge): add tracker-references feature knowledge base
dean0x Sep 14, 2026
bec3a2c
docs(knowledge): update test-harness feature knowledge base
dean0x Sep 14, 2026
c416295
docs(knowledge): update installer-shadowing feature knowledge base
dean0x Sep 14, 2026
769fa12
docs(knowledge): update feature-knowledge-system feature knowledge base
dean0x Sep 14, 2026
067355b
docs(knowledge): update compliance-feature feature knowledge base
dean0x Sep 14, 2026
7bc3071
docs(knowledge): update dynamic-workflow-engine feature knowledge base
dean0x Sep 14, 2026
c98889f
test(build): pin the reference-tree orphan prune
dean0x Sep 14, 2026
176227e
docs(knowledge): record the reference-prune describe in feature-knowl…
dean0x Sep 14, 2026
59c0e56
docs(knowledge): correct the preamble line count in tracker-references
dean0x Sep 14, 2026
34b6346
fix(git-skill): scrub-then-post the inline bodies in github-api.md
dean0x Sep 14, 2026
c9180f2
style(git-skill): tighten the D11 blockquote and dedupe the D11 probe…
dean0x Sep 14, 2026
f45d2b6
fix(git-skill): pair the notes file with --notes-file in the D11 note
dean0x Sep 14, 2026
ed9b494
test(git-agent): drive the file-scoping half of the D11 forward probe
dean0x Sep 14, 2026
a715851
docs(knowledge): record the #340 end state in tracker-references and …
dean0x Sep 14, 2026
6c3caf6
fix(d11): scrub-then-post the six inline sinks the guard could not se…
dean0x Sep 15, 2026
87c3283
fix(git-agent): name close-comments as posted bodies in the D11 contr…
dean0x Sep 15, 2026
65e5470
test(goldens): regenerate git-agent.md after the D11 close-comment cl…
dean0x Sep 15, 2026
3c1d8c2
style(tests): end-state D11 comments in git-agent and golden tests
dean0x Sep 15, 2026
cb87788
docs(d11): state the inline-body matcher's non-goals and clear retire…
dean0x Sep 15, 2026
737baaf
test(d11): control the inline-body scan against a --json field that s…
dean0x Sep 15, 2026
ecfb459
docs(knowledge): record the #341 end state
dean0x Sep 15, 2026
10ea0d5
Merge remote-tracking branch 'origin/main' into feat/324-tracker-phas…
dean0x Sep 15, 2026
4fdc541
fix(tests): make section extraction fence-aware and guard per-op refe…
dean0x Sep 15, 2026
667c497
fix(git-agent): render external-thread containment in the post-wave-r…
dean0x Sep 15, 2026
ce491f9
test(goldens): regenerate git-agent.md after the post-wave-report con…
dean0x Sep 15, 2026
031e1bd
docs(knowledge): record the fence-aware extractor and post-wave-repor…
dean0x Sep 15, 2026
13f24be
fix(review-methodology): restore the PR Comment Violations subsections
dean0x Sep 15, 2026
d5e313a
docs(docs-framework): define ISSUE_ID at first use (resolve B05: docu…
dean0x Sep 15, 2026
357dcd0
docs: complete guard roster and document ceiling direction
dean0x Sep 15, 2026
5c6a4cc
fix(implement): use the ISSUE_ID placeholder style on every spawn blo…
dean0x Sep 15, 2026
89b68d9
fix(tests): give the two floor entries distinct pinned text (resolve …
dean0x Sep 15, 2026
3cc6877
fix(git-skill): restore the conventions refresh procedure within budg…
dean0x Sep 15, 2026
0768935
fix(tests): count only live guards in the census (resolve B01: testin…
dean0x Sep 15, 2026
7ac9515
refactor(build-mds): discriminate HostPlan on variant and extract pla…
dean0x Sep 15, 2026
1de05fa
docs(tests): cite PF-018/PF-064 for the probe doctrine, not ADR-024
dean0x Sep 15, 2026
a989e2a
refactor(mds-variants): return an immutable, total section map from s…
dean0x Sep 15, 2026
34df2ae
fix(commands): state where the issue-token re-check runs and name fet…
dean0x Sep 15, 2026
6318ef3
fix(tests): bound and fence-guard the ## section anchor (resolve B11:…
dean0x Sep 15, 2026
2669544
fix(reference-sweep): share the depth bound with the build prune and …
dean0x Sep 15, 2026
ff1cb50
refactor(core): own the generated-reference manifest and skill name i…
dean0x Sep 15, 2026
b26b61b
test(reference-structure): assert the manifest against its registered…
dean0x Sep 15, 2026
07c20d1
test(build-mds): derive the prune depth probe from the shared bound
dean0x Sep 15, 2026
287c788
test(byte-budget): pin github-api.md, record the pointer round-trip t…
dean0x Sep 15, 2026
cb9f8ce
refactor(tests): move CONTAINMENT_EXEMPTIONS to its own fixture modul…
dean0x Sep 15, 2026
4e672e2
fix(git-agent): shrink the Mechanics pointer and fund the D11 notes p…
dean0x Sep 15, 2026
829f905
test(harness): probe every fence-grammar rule and assert the corpus h…
dean0x Sep 15, 2026
7982e8d
fix(git-skill): chain compose into the D11 scrub-then-post, validate …
dean0x Sep 15, 2026
6b253b8
test(harness): make ref()'s refusal typed and bound walkFiles with th…
dean0x Sep 15, 2026
539419a
fix(installer): report the overlay's real end state and keep the .old…
dean0x Sep 15, 2026
9a7dfca
fix(installer): fail loud when the compiled references tree is absent…
dean0x Sep 15, 2026
fd45fa1
test(git-agent): word-bound the provider detectors and memoise the co…
dean0x Sep 15, 2026
c316423
test(harness): derive gitOp through the fence-aware extractor and pro…
dean0x Sep 15, 2026
c1fec6c
fix(git-agent): append tech-debt items to the backlog body so the arc…
dean0x Sep 15, 2026
b289544
refactor(installer): split unit promotion by unit kind (resolve B26: …
dean0x Sep 15, 2026
fcd5ec7
test(guards): widen the heredoc matcher to the shell grammar and reco…
dean0x Sep 15, 2026
c0b9860
test(goldens): regenerate git-agent.md and re-freeze github-status-li…
dean0x Sep 15, 2026
7ca3a00
test(goldens): assert TOTAL_CHARS against a measured baseline and spa…
dean0x Sep 15, 2026
6d8f057
docs: correct the CHANGELOG and knowledge-base figures and claims, ad…
dean0x Sep 15, 2026
d23f365
fix(installer): process-unique staging under the converged subtree, b…
dean0x Sep 15, 2026
b4cff0f
fix(git-skill): one D4 stop-and-report spelling, fail-closed rate pro…
dean0x Sep 15, 2026
bf4b3f9
refactor(installer): type recordSweep's parameter as SweepResult (res…
dean0x Sep 15, 2026
b002ea6
docs(tracker-references): end-state KB claims, one reproducible margi…
dean0x Sep 15, 2026
3bf7916
refactor(tests): clear stale BUDGET_GIT_MD figures and dedup the gold…
dean0x Sep 15, 2026
f6bcb35
refactor(tests): scope runMdsBuild to its module, trim a narrating co…
dean0x Sep 15, 2026
5ad16e6
refactor(tests): share collectTrackerNamingLines and cite PF-018 for …
dean0x Sep 15, 2026
a1c93db
docs(knowledge): record the PR #339 resolve-wave end state across the…
dean0x Sep 16, 2026
3035369
docs(knowledge): reconcile the wave-refresh and build-pipeline knowle…
dean0x Sep 16, 2026
dd30e3f
chore(tracker): leave the end state in comments, knowledge bases and …
dean0x Sep 16, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
158 changes: 115 additions & 43 deletions .devflow/features/compliance-feature/KNOWLEDGE.md

Large diffs are not rendered by default.

128 changes: 94 additions & 34 deletions .devflow/features/dynamic-workflow-engine/KNOWLEDGE.md

Large diffs are not rendered by default.

209 changes: 126 additions & 83 deletions .devflow/features/feature-knowledge-system/KNOWLEDGE.md

Large diffs are not rendered by default.

11 changes: 6 additions & 5 deletions .devflow/features/index.md

Large diffs are not rendered by default.

319 changes: 97 additions & 222 deletions .devflow/features/installer-shadowing/KNOWLEDGE.md

Large diffs are not rendered by default.

327 changes: 197 additions & 130 deletions .devflow/features/test-harness/KNOWLEDGE.md

Large diffs are not rendered by default.

213 changes: 213 additions & 0 deletions .devflow/features/tracker-references/KNOWLEDGE.md

Large diffs are not rendered by default.

20 changes: 19 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,23 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0

### Changed

- **The Git agent is now compiled from an MDS generator host** — before: `src/assets/agents/git.md` was a hand-authored file the installer copied verbatim; the build owned command files only. After: `src/assets/agents/git.mds` declares `output-dir: dist/agents` in a leading steering block and compiles to `dist/agents/git.md`, which is byte-identical to the file it replaces (66,180 bytes, unchanged SHA-256). Both agent readers take their directory order from one owner, `agentSourceDirs()` in `src/core/assets.ts` — `dist/agents/`, then `src/assets/agents/`. The installer resolves each declared agent against that list and copies the first hit, throwing with both candidate paths and `npm run build:mds` named when neither directory has it; `loadShippedDefaults()` walks the same list first-wins and warns through its `onWarning` channel when a registry-declared agent has no shipped default in either. The compiled artifact wins for a generated agent and the other 15 agents install exactly as before. The 13 compiled command outputs in `dist/commands/` are byte-unchanged, and the hand-authored `release.md` beside them is untouched — 14 deployed command files in all. Zero user-visible change.
- **The Git agent's GitHub mechanics now live in generated skill references** — before: `git.md` was 65,677 characters re-sent on every Git spawn, roughly 9,400 of them GitHub-specific mechanics (`gh` invocations, header names, rate-limit thresholds) interleaved with the provider-independent contract — each operation's `**Input:**`, `**Output:**` template and `**Degradation (D4):**` clause. There was no single place a tracker provider was resolved, so a provider token would have had to be threaded through roughly thirty filename-composition sinks. After: the compiled agent is 55,664 characters (56,075 bytes), against the `BUDGET_GIT_MD` ceiling of 55,750 characters that `tests/tracker/byte-budget.test.ts` asserts on every run — the ceiling is the number that must hold; the measurement is what it holds against today. A ≤40-line provider-resolution preamble resolves the provider **once per spawn** and states the **one** load instruction that composes a mechanics path; thirteen generated references carry what moved — ten per-operation GitHub files under `references/tracker/github/`, plus `learn-conventions.md`, `publication-gate.md` and `decision-markers.md`. Every move is byte-identical unless it is one of 63 named, individually justified exemptions, and a containment oracle compares the pre-split tree against the post-split one line by line to prove it — over the whole branch diff, 150 of the 160 content lines the golden lost are byte-present elsewhere in the loadable set and the remaining 10 fall inside a named exemption range, with none unaccounted. Zero user-visible change: `Tracked = #{n}`, `Depends on: #{n}`, `42-jwt-auth.{ts}.md` and `issue: 42` all render exactly as before. This entry is an internal refactor — it adds no new prompt and no new file to any user's project tree.

- **The D4 and D11 cross-cutting contracts are provider-independent in fact, not only in claim** — before: the always-loaded degradation contract named `gh` as the thing that can be unauthenticated and stated GitHub's own rate-limit signals (a 403/429 body, `X-RateLimit-Remaining < 10`, the `< 50` backpressure rung) in the same sentences as the provider-independent STOP/THROTTLED rules; the comment-sink scrub said it applied to bodies posted "to GitHub". Two authorities on the redaction path. After: the invariants stay inline and unchanged — the scrub is still unconditional, still fail-closed, still `&&` and never a pipeline, and the scrubber invocation itself is never made loadable — while the cross-cutting blocks themselves name no provider. D11's shell recipe now posts through a `<the resolved provider's post command>` placeholder that the operation's own generated reference resolves. D4's GitHub-specific detail — the 403/429 rate-limit body, the `X-RateLimit-Remaining < 10` STOP threshold and the `< 50` backpressure rung — left the cross-cutting block entirely and is *explained* once, in the GitHub reference of `backlink-shipped-issues`, the operation that owns the fan-out. It is not *stated* only there, and deliberately so: `skills/git/SKILL.md` is preloaded on every Git spawn and keeps the `< 10` STOP threshold, which is the mitigation that makes the move safe, and each fan-out operation's own `**Degradation (D4):**` clause still names the signal it acts on inline beside the `THROTTLED` report it triggers — in the agent and in the generated references alike. A threshold an agent must recognise before it acts is worth restating at the point of use; a header name, a status code and a shell command are not.

- **`skills/git/SKILL.md` no longer contradicts the agent it is preloaded with** — before: 9,205 characters preloaded on every Git spawn, carrying two live safety contradictions — `if [ "$REMAINING" -lt 10 ]; then sleep 60; fi`, which tells the agent to wait out exactly the secondary rate limit D4 tells it to STOP for (waiting extends the provider's penalty window), and `gh release create … --notes "$NOTES"`, an inline-body recipe where the release operation mandates `--notes-file` after a scrub whose failure is a hard stop. Both were invisible to every guard. After: 6,581 characters, both contradictions removed, and the inline-body guard widened to see `gh release … --notes` and rescoped to the skill files. Three `sleep 60` sites in all — the third in `references/github-api.md` — are gone.

- **Every shipped recipe that posts a body posts the scrubber's output** — before: sixteen recipes across `references/github-api.md`, `references/patterns.md`, the generated tracker references and the review-methodology skill built a body inline — `--body "$(cat <<'EOF' …)"`, `-f body="$BODY"`, `--notes "$changelog"`, `--notes-file CHANGELOG.md` — so the text reached GitHub without passing `redact-secrets.cjs` at all, in the same files that tell an agent the scrub is unconditional. After: each one composes to `$DEVFLOW_BODY_RAW` (release notes to `$DEVFLOW_NOTES_RAW`, or `CHANGELOG.md` read as raw input), runs the scrubber, and posts the scrubbed file through `--body-file` / `-F body=@` / `--notes-file`, chained with `&&` so a non-zero scrubber exit means the post does not happen. The tech-debt archive closes its predecessor with **no comment body**: before, it closed with a `--comment` placeholder reading `(see linked issue)` and then posted the real number in a second comment; after, it creates the successor first and posts one scrubbed archive comment carrying that number, so the close is a close. Reviews write reports and only the Git agent publishes — the review-methodology skill's own comment-creation recipe is replaced by a pointer to `post-review-summary`, where the repo-visibility gate (D10) and the comment-sink scrub (D11) already live, so there is one publication path instead of two. The inline-body guard that polices this folds shell line-continuations before matching (a `--body` four lines below its `gh` verb is one command, not four lines), names its five posting shapes separately so each is proven live by its own known-bad probe, and scans **every installed agent, command, rule and skill** rather than the Git agent's own neighbourhood; the pre-split baseline tree is kept as a permanent known-bad corpus so the widening is proven against text that really did post unscrubbed bodies. Two `gh … --json number` flags that neither `gh issue create` nor `gh pr create` accepts are replaced by deriving the number from the URL each command prints. Every recipe renders the same text it always did; what changes is what reaches the tracker when a body carries a secret — before, a shipped recipe posted it, and after, the post does not happen (#340, #341).

- **The installer converges the generated references rather than merging into them** — before: nothing installed generated skill references, because none existed. After: `devflow init` overlays them onto the installed `devflow:git` skill directory with a **converge-not-merge** contract — a shadow-supplied file under `references/tracker/**` that the build manifest does not name is removed, and a shadowed `devflow:git` still receives the canonical GitHub references. The swap is **atomic per unit**: each provider directory (and the flat cross-cutting set) is built under a `.tmp` sibling and promoted by rename, so a per-file failure aborts that unit and leaves the previously installed files byte-unchanged instead of promoting a partial tree. Two new install-time failure modes come with it, both reported rather than silent: a unit that could not be refreshed is named in the install summary (`Could not refresh the generated references for "{provider}" …`), and a **declared reference missing from the build** fails loudly with a `npm run build:mds` hint rather than installing an agent instructed to read a file that is not there.

- **The command layer speaks one issue-reference vocabulary** — before: five command hosts each carried their own inline `#N` parsing rule, and the design-artifact naming convention used a `{issue}` placeholder. After: one partial, `_partials/_tracker.mds`, states the grammar and the capture contract once and is imported by `plan`, `implement`, `debug`, `dynamic-build` and `dynamic-plan`; the placeholder vocabulary is `{ISSUE_REF}` (the rendered reference) and `{ISSUE_ID}` (the filesystem-safe form), each site also stating its GitHub rendering so the rendered bytes are pinned. `ISSUE_NUMBER` is kept at all fourteen Code-agent spawn sites. Commands no longer restate a dedup marker literal — the operation owns its marker.

- **Byte budgets for the Git spawn are now constants with derivations, asserted as a four-shape table** — `chars(dist/agents/git.md) ≤ 55,750`, `chars(skills/git/SKILL.md) ≤ 6,600`, and the worst-case tracker spawn's loaded set `≤ 77,824` characters (the pre-split preloaded set, so the split cannot be "satisfied" while the total gets worse). The formula counts every reference a single operation's load instructions can name, checked bidirectionally against what the compiled agent can actually name, and the four candidate file shapes are recorded as computed rows so the shape decision is not re-litigated from memory.

- **`tests/fixtures/golden/github-status-lines.txt` was re-captured twice** — the frozen fixture samples prompt-internal process steps, which is precisely the text this refactor relocates. The first re-capture followed the D4 invariant/detector cut, which split two of its sampled sentences, so preserving the fixture and making the split were mutually exclusive; the second followed the review-wave condensing of the `**Mechanics:**` pointer lines it samples, and moved only the two byte-count lines that shift when the agent is regenerated. Each was a single fixture-only commit under its own explicit authorisation, and the fixture is frozen again from the second. The four user-visible byte-identity claims have their own assertions and are untouched.

- **The Git agent is now compiled from an MDS generator host** — before: `src/assets/agents/git.md` was a hand-authored file the installer copied verbatim; the build owned command files only. After: `src/assets/agents/git.mds` declares `output-dir: dist/agents` in a leading steering block and compiles to `dist/agents/git.md`, which was byte-identical to the hand-authored file it replaced at the conversion (66,180 bytes, unchanged SHA-256); the contract/mechanics split is what changes its size. Both agent readers take their directory order from one owner, `agentSourceDirs()` in `src/core/assets.ts` — `dist/agents/`, then `src/assets/agents/`. The installer resolves each declared agent against that list and copies the first hit, throwing with both candidate paths and `npm run build:mds` named when neither directory has it; `loadShippedDefaults()` walks the same list first-wins and warns through its `onWarning` channel when a registry-declared agent has no shipped default in either. The compiled artifact wins for a generated agent and the other 15 agents install exactly as before. The 13 compiled command outputs in `dist/commands/` are byte-unchanged, and the hand-authored `release.md` beside them is untouched — 14 deployed command files in all. Zero user-visible change.

- **`npm run build:cli` alone no longer produces installable agents** — before: `build:cli` (TypeScript) plus the shipped `src/assets/agents/*.md` were enough to install every agent. After: an agent authored as a generator host exists only as a `.mds` source until `npm run build:mds` compiles it, so a publish or install path that runs `build:cli` alone would ship without a Git agent. `npm run build` runs both and is unchanged; the packaging and pack-install guards now fail loudly if the compiled agent is missing from the tarball.

Expand All @@ -19,6 +35,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0

### Fixed

- **Shipped recipes posted bodies the scrubber had never seen** (#340, #341) — before: sixteen recipes across `references/github-api.md`, `references/patterns.md`, the generated tracker references and the review-methodology skill composed a body inline and handed it straight to `gh`, so an agent following the shipped text reached the tracker without `redact-secrets.cjs` running at all — in the same files that tell it the scrub is unconditional. The tech-debt archive was the same defect in a second shape: it closed its predecessor with a `--comment` placeholder and posted the real number in a separately-composed follow-up. After: each one composes to `$DEVFLOW_BODY_RAW` (release notes to `$DEVFLOW_NOTES_RAW`), runs the scrubber, and posts the scrubbed file through `--body-file` / `-F body=@` / `--notes-file`, `&&`-chained so a non-zero scrubber exit means the post does not happen. This sink has no erasure path — a comment lands at the repository's visibility, GitHub keeps edit history, and notifications have already fired — so anything that got through had to be answered by rotating the credential, not by editing the comment. The **Changed** entry above carries the full inventory and the guard that now polices it.

- **`/debug #42` wrong Git-op spawn key** — before: `debug.mds` passed `ISSUE: {issue number}` to the `fetch-issue` Git operation, which declares `ISSUE_INPUT:`; the key mismatch meant no issue was ever fetched. After: `debug.mds` passes `ISSUE_INPUT: {issue reference}` — the key the op declares. (AC-0.1)

- **`/plan` with issue references: issue body never fetched** — before: `/plan #42` parsed the issue reference but never retrieved it; the design was built without the issue content. After: `/plan #42` spawns the Git agent with `OPERATION: fetch-issue`; `/plan #12 #15 #18` uses `OPERATION: fetch-issues-batch` (≤50 issues, `TRUNCATED ({n} not processed)` beyond the cap). (AC-0.3)
Expand Down
Loading