Conversation
Adopts the template's development/ tree: the agent-facing docs, ADRs and per-feature work units move out of docs/ and work/, leaving docs/ for user documentation (docs/api.md) as the new convention reserves it. The move is done as a pre-step so _skip_if_exists protects the project-authored docs; a bare `copier update` deletes them and substitutes the template scaffolds, because _skip_if_exists does not cover the delete side of a rename. Harness changes absorbed from v0.6.0: - report.md as a fifth work-unit artifact, owned by the Developer and audited by the Reviewer for honesty. - DECISION-PENDING: escalation marker plus the decision register in development/adr/README.md, seeded with the two decisions already granted (the ADR 0003 GPU-suite waiver and the coverage thresholds). - development/glossary.md, the document-liveness table, and the architecture > spec > plan > tasks authority order. - Role playbook skills (product-owner, architect, developer, reviewer) over a shared design-principles core. - PreToolUse hook fails closed when jq cannot parse the tool input. - .github/PULL_REQUEST_TEMPLATE.md with the definition-of-done checklist. AGENTS.md keeps devmm's stricter rule that a required runtime dependency needs an ADR, rather than the template's softer ADR-bar wording: the empty required-dependency set is a design invariant tests/test_packaging.py enforces. Gate: make verify green — 900 passed, 75 skipped (GPU suites, off hardware). Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
… contract Review of #3 found the hardened PreToolUse guard bricks a session on any host without jq: it fails closed, jq is not installed by the bootstrap, and the denial covers the `apt-get install jq` that would fix it. Verified — with jq off PATH, `make verify` returns exit 2. The pre-update wiring failed *open* instead, allowing destructive commands through unchecked, so neither form was right. Keep fail-closed and make it self-explanatory: - The guard checks for jq up front and names it as the reason, with the install command; the other two deny paths explain themselves too. - block-destructive.sh reports which deny-list pattern matched, instead of a bare exit 2 that reads as an unexplained refusal and invites a reword-retry loop. - ensure-toolchain.sh warns at SessionStart when jq is absent, so the problem surfaces before the first Bash call rather than as a mystery denial. Warning only — it must not abort the uv bootstrap. - tool-bootstrap.md states jq is required, not merely standard. The decision-register contract was self-defeating: it keyed on the literal `DECISION-PENDING:` text, which this PR itself adds 15 times as documentation, so `/verify` would have raised a dozen fabricated MAJOR defects while a real escalation hid among the quotes. A marker is now defined by location — its own line inside a development/work/*/report.md — with the scan command to match. Also: register rows sourced from an ADR or a human grant are marker-less by construction and no longer read as out-of-scope (both seeded rows are of that kind); the Developer is named owner of the paired row, the only role that can write it; and a PR with no work unit has the spec/plan/register axes marked n/a rather than failed. Remaining: gate-output rules now point at development/testing.md, which is authoritative and records the sanctioned DEVMM_GPU skips; the Developer gets the Architect's scratch.md clobber guard; development/README.md drops a scaffold-marker section describing artifacts this repo no longer has and no longer claims development/ is unpublished (the sdist ships it, the wheel does not); README.md uses absolute links, as it is also the PyPI project page. Gate: make verify green — 900 passed, 75 skipped, unchanged. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
| { | ||
| "type": "command", | ||
| "command": "S=\"${CLAUDE_PROJECT_DIR:-.}/.agents/hooks/block-destructive.sh\"; [ -r \"$S\" ] || exit 2; jq -r '.tool_input.command // empty' | sh \"$S\"" | ||
| "command": "S=\"${CLAUDE_PROJECT_DIR:-.}/.agents/hooks/block-destructive.sh\"; [ -r \"$S\" ] || { echo \"PreToolUse: $S missing or unreadable — denying Bash.\" >&2; exit 2; }; command -v jq >/dev/null 2>&1 || { echo 'PreToolUse: jq not found, so the destructive-command guard cannot read the tool input — denying Bash. Install jq (apt-get install jq / brew install jq) from a shell outside the agent, then retry.' >&2; exit 2; }; c=$(jq -r '.tool_input.command // empty') || { echo 'PreToolUse: jq could not parse the hook payload — denying Bash.' >&2; exit 2; }; [ -n \"$c\" ] || { echo 'PreToolUse: hook payload carried no .tool_input.command — denying Bash.' >&2; exit 2; }; printf '%s' \"$c\" | sh \"$S\"" |
There was a problem hiding this comment.
[CONFIRMED] correctness — ✅ Fixed in e245a65
c=$(jq -r …) || exit 2 turns a missing or failing jq into a blanket denial of every Bash tool call, and jq is an assumed-present system tool that ensure-toolchain.sh does not install. [same root cause also at: .claude/settings.json:49, .claude/settings.json:49, .claude/settings.json:49, .claude/settings.json:49]
Failure scenario
On a minimal container / CI image / cloud sandbox without jq (documented in development/tool-bootstrap.md:23 only as "standard on dev machines", and not installed by the SessionStart bootstrap, which installs uv alone), the very first Bash call dies: verified exit=2, stderr='sh: 1: jq: not found'. The agent cannot run make verify, cannot run the test suite, and cannot even run apt-get install jq to self-recover, because the remedy is itself a Bash call. Every subsequent attempt fails the same way, so the session is unusable. The previous wiring degraded to allow-with-no-check instead.
| **this register alone** records the outcome — to see what is still open, scan | ||
| the table for `pending` rows, not the reports. The reviewer checks the | ||
| contract per change: a marker added in the diff without a row here is a defect. | ||
|
|
There was a problem hiding this comment.
[CONFIRMED] correctness — ✅ Fixed in e245a65
The decision-register contract keys on the literal colon form DECISION-PENDING: while this PR introduces 14 colon-form prose mentions, so the marker is indistinguishable from documentation. [same root cause also at: .agents/subagents/reviewer.md:111, development/adr/README.md:57, development/adr/README.md:62]
Failure scenario
The register declares "The marker is the colon form, DECISION-PENDING:; mentions of the token without the colon are prose", and .agents/subagents/reviewer.md:125 makes "a DECISION-PENDING: line added without its register row" an automatic MAJOR/NEEDS-WORK. This diff adds 14 colon-form lines (AGENTS.md:60, .agents/subagents/developer.md, reviewer.md:64/111/125, .github/PULL_REQUEST_TEMPLATE.md:15, harness-usage.md:254/277, and README.md:52/57/61/62 itself) and zero register rows for them. Running /verify on this PR — or on any later PR that quotes the convention — produces a NEEDS-WORK verdict with a dozen fabricated MAJOR defects, and conversely a real escalation in a report.md is invisible among the prose hits, so a genuinely unauthorized decision merges unnoticed.
| `report.md`, or the body of an existing ADR is an automatic MAJOR | ||
| defect unless the plan explicitly called for it. The two registers | ||
| have their own scope contracts instead: a decision-register row must | ||
| pair with an escalation marker in this diff *unless* its Source is an |
There was a problem hiding this comment.
[CONFIRMED] correctness — ✅ Fixed in e245a65
The reviewer's scope rule requires every new decision-register row to pair with a DECISION-PENDING: line in the same diff, but the register explicitly admits rows for decisions a human granted with no marker — both existing rows are of that kind.
Failure scenario
A maintainer verbally grants a tolerance mid-feature; the developer appends the sanctioned register row (development/adr/README.md:52-53: "or that a human granted outside an ADR (a tolerance, a pin, a one-line operational fact)"). /verify finds a register row with no paired marker in the diff and, per this line, must rank it an out-of-scope MAJOR — automatic NEEDS-WORK. The loop cannot reach GO except by deleting the record the register was created to hold, or by fabricating a DECISION-PENDING: line in report.md for a decision that was never escalated. Both seeded rows (2026-07-p12.1, 2026-07-p12.2) have Source = an ADR / testing.md rather than a report, confirming marker-less rows are the intended norm.
| and an undeclared deviation is a review defect. | ||
| - When a decision exceeds your authority — loosening a test tolerance | ||
| or assertion, adding a dependency, changing behaviour the spec froze — | ||
| write a `DECISION-PENDING:` line in `report.md` and stop. Do not |
There was a problem hiding this comment.
[PLAUSIBLE] correctness — ✅ Fixed in e245a65
The DECISION-PENDING: escalation tells the Developer to write the marker in report.md and stop, but no role anywhere is assigned the paired decision-register row that development/adr/README.md:57 makes a same-PR contract and .agents/subagents/reviewer.md:111 makes an automatic MAJOR — the reviewer has write: deny, the architect/product-owner may not write outside the work dir, and .agents/commands/build.md:28-29 mentions only recording the marker.
Failure scenario
Developer hits a tolerance question, writes DECISION-PENDING: relax the pitch-alignment tolerance in report.md and stops; the user answers in chat and runs /verify; the reviewer applies its own rule ("a DECISION-PENDING: line in the diff without a row here is a defect") and returns an automatic MAJOR / NEEDS-WORK; /build re-invokes the developer, whose instructions still say only "write the line and stop. Do not resolve it locally", so the row is never added and the phase cannot leave NEEDS-WORK without the human noticing the missing owner.
| - **Fast loop**: `make test` — must finish in <60s. Add slow suites under | ||
| `make test-all`. | ||
|
|
||
| ## Reading gate output |
There was a problem hiding this comment.
[CONFIRMED] cleanup — ✅ Fixed in e245a65
The gate-output reading policy is now restated in four places, and only this copy carries the ADR-0003 GPU-skip exception.
Failure scenario
The same rules (passed counts may only grow, no -x/-k/--ignore narrowing, no marker/assertion edits, new skips are findings) appear at development/testing.md:9-20, .agents/subagents/developer.md:65-70, .agents/subagents/reviewer.md:104-108, and .agents/skills/developer-playbook/SKILL.md, violating design-principles/SKILL.md:29 ("Every piece of knowledge — code, schema, doc, config — has one authoritative representation"). Only testing.md:19-20 carries the carve-out that the GPU suites "skip by design off hardware (development/adr/0003), so their skips are expected, not findings", so a reviewer or developer reading only its own role file treats the DEVMM_GPU skips as defects to explain, and any future change to the policy must be applied in four files or they drift. Fix: keep the rules in testing.md and have the role files link that section.
| { | ||
| "type": "command", | ||
| "command": "S=\"${CLAUDE_PROJECT_DIR:-.}/.agents/hooks/block-destructive.sh\"; [ -r \"$S\" ] || exit 2; jq -r '.tool_input.command // empty' | sh \"$S\"" | ||
| "command": "S=\"${CLAUDE_PROJECT_DIR:-.}/.agents/hooks/block-destructive.sh\"; [ -r \"$S\" ] || { echo \"PreToolUse: $S missing or unreadable — denying Bash.\" >&2; exit 2; }; command -v jq >/dev/null 2>&1 || { echo 'PreToolUse: jq not found, so the destructive-command guard cannot read the tool input — denying Bash. Install jq (apt-get install jq / brew install jq) from a shell outside the agent, then retry.' >&2; exit 2; }; c=$(jq -r '.tool_input.command // empty') || { echo 'PreToolUse: jq could not parse the hook payload — denying Bash.' >&2; exit 2; }; [ -n \"$c\" ] || { echo 'PreToolUse: hook payload carried no .tool_input.command — denying Bash.' >&2; exit 2; }; printf '%s' \"$c\" | sh \"$S\"" |
There was a problem hiding this comment.
[PLAUSIBLE] correctness — ✅ Fixed in e245a65
All three deny paths in the wrapper exit 2 with no stderr text, so the delegate's verdict and the wrapper's own failure reasons are indistinguishable to the caller. [same root cause also at: .claude/settings.json:49, .claude/settings.json:49]
Failure scenario
block-destructive.sh prints nothing before exit 2, and the two new guards (|| exit 2, [ -n "$c" ] || exit 2) print nothing either. A blocked call therefore surfaces to the agent as a bare "hook error ... No stderr output" (observed verbatim in this session when a review command contained rm -rf as text), giving no way to distinguish "your command matched the destructive deny-list" from "jq is missing" from "this tool has no command field". The agent's recovery is to reword and re-issue the same command repeatedly — burning turns and, in the jq/no-command cases, never succeeding — while the user sees unexplained refusals.
| feature branch) before judging anything. | ||
| - Read `spec.md`, `plan.md`, the current `tasks.md`, `report.md` (if the | ||
| Developer has started it), and the diff (`git diff` against the | ||
| integration branch, plus `git log` for the feature branch) before |
There was a problem hiding this comment.
[PLAUSIBLE] correctness — ⏭️ Not fixed here
If plan.md has a **Review checklist** section, it is part of your instructions grants an architect-authored, human-approved-at-plan-time document unbounded authority over the review, with none of the "never overrides the verdict rules" subordination clause that lines 46-49 and reviewer-playbook.md:63-65 apply to the playbook.
Failure scenario
A plan's Review checklist (template at architect.md:124-127) includes "the coverage thresholds and GPU-marker skips are out of scope for this phase — don't flag them"; the reviewer reads it as instructions, suppresses a genuine new skip that its own rules class as a defect ("any new skip is a defect to explain, not to ignore"), and returns GO — and the user who approved plan.md for its phases never realised they were also approving a narrower review.
Left for upstream: this is a gap in the template's role protocol rather than something this migration introduced, and fixing it here would deepen the divergence that every future copier update has to re-merge.
| - When reading gate output, follow | ||
| [`development/testing.md`](../../development/testing.md#reading-gate-output) — | ||
| it is authoritative and names this project's sanctioned skips (the | ||
| `DEVMM_GPU` suites skip by design off hardware, so they are not |
There was a problem hiding this comment.
[PLAUSIBLE] correctness — ✅ Fixed in e245a65
.agents/subagents/architect.md:77-80 adds an explicit "append with Edit, never replace with Write — it is gitignored, so what you clobber is gone" guard for the shared scratch.md, but the same guard is absent from the Developer, which holds both Write and Edit and is directed to leave notes in scratch.md in three places (lines 35-36, 75, 80) — as is .agents/commands/build.md:16, where the main agent drops an explorer summary into the same file.
Failure scenario
/plan leaves SPIKE-REQUEST:/SPIKE-FINDING: history in scratch.md, then /build starts; the developer discovers the plan is wrong and follows line 74-76 by writing its 2-3 sentence hand-back note with Write, truncating the file; the spike record is unrecoverable because .gitignore excludes development/work/*/scratch.md, and the re-invoked architect — told at architect.md:35-39 that scratch.md "holds the answer to the question you asked" — re-asks a question that was already answered and burns one of /plan's three spike rounds.
| `DECISION-PENDING:` escalations are recorded when they happen. | ||
| - Run `make verify` at every phase boundary. | ||
| - Stop at the end of each phase and hand off to `/verify` | ||
| (Reviewer) before starting the next. |
There was a problem hiding this comment.
[PLAUSIBLE] correctness — ⏭️ Not fixed here
/build forwards only the developer subagent's "phase complete" hand-back; the developer's other documented stop (a scratch.md note requesting an explorer pass, developer.md:80) has no servicing step, unlike /plan's explicit SPIKE-REQUEST round-trip.
Failure scenario
The developer hits a search it cannot summarise inline, follows developer.md:78-81, writes "requesting an explorer pass" into scratch.md and stops mid-phase with tasks.md boxes unticked. build.md step 5 has exactly one branch — "When the developer reports a phase complete, stop and ask the user to run /verify" — so the parent reports the stop as a completed phase and routes the user to /verify. The reviewer then reviews half-implemented work and returns NEEDS-WORK (unticked tasks, missing tests), /build re-delegates to a fresh developer that hits the same wall, and the explorer request is never serviced: the phase ping-pongs between /build and /verify with no progress until the user reads scratch.md by hand.
Left for upstream: this is a gap in the template's role protocol rather than something this migration introduced, and fixing it here would deepen the divergence that every future copier update has to re-merge.
| `report.md`, or the body of an existing ADR is an automatic MAJOR | ||
| defect unless the plan explicitly called for it. The two registers | ||
| have their own scope contracts instead: a decision-register row must | ||
| pair with an escalation marker in this diff *unless* its Source is an |
There was a problem hiding this comment.
[PLAUSIBLE] correctness — ✅ Fixed in e245a65
The new scope-check rules (register row must pair with a marker; glossary entry must match a reviewed spec Glossary term) have no defined behaviour for a PR with no work unit, and this PR violates both. [same root cause also at: .agents/subagents/reviewer.md:61]
Failure scenario
.github/PULL_REQUEST_TEMPLATE.md:3 explicitly permits PRs that skip the four-phase loop, and this PR is one: it adds two decision-register rows (development/adr/README.md) with no DECISION-PENDING: line in any report, and a whole new development/glossary.md with no spec Glossary section anywhere in the repo. A reviewer following reviewer.md:57-68 literally reports both as MAJOR ("a glossary edit with no matching spec term … is out of scope (MAJOR)"), and its mandatory reads (spec.md, plan.md, tasks.md, report.md) do not exist, so /verify returns NEEDS-WORK on a correct change with defects the author cannot possibly clear.
| decisions** block (with a one-line rationale and an "ADR needed: | ||
| <topic>" marker); the human or the Developer authors the ADR file | ||
| under `development/adr/` as a separate step. | ||
| - `scratch.md` belongs to every role, not to you: **append** to it with |
There was a problem hiding this comment.
[PLAUSIBLE] cleanup — ✅ Fixed in e245a65
Architect is forbidden from ever using Write on scratch.md, but the spike protocol requires creating it when it does not yet exist.
Failure scenario
.agents/commands/spec.md:3-9 deliberately does not pre-create scratch.md ("whoever needs it first creates it"), so on a feature whose first hand-back is a spike, development/work/<slug>/scratch.md does not exist. Line 77-80 says "append to it with Edit, never replace it with Write", and Edit on a nonexistent file errors. The architect either loops on a failing Edit or violates its instructions, so the SPIKE-REQUEST: line the /plan loop reads back (plan.md:4, architect.md:139-141) is never recorded and the spike round-trip silently degrades into the architect guessing the assumption it was told never to guess. Fix: allow Write when the file is absent, forbid it when it exists.
| the user, then re-invoke the product-owner subagent with the question | ||
| and the user's answer included in the prompt.* State it every time. Do | ||
| not assume the caller loaded `/spec` — the role is also reached by | ||
| description match, and then the slash command's instructions were never |
There was a problem hiding this comment.
[PLAUSIBLE] cleanup — ⏭️ Not fixed here
Round caps for the question/spike loops live only in the slash commands, which both subagents state may never have been read.
Failure scenario
The five-round cap is only in .agents/commands/spec.md:28 and the three-round spike cap only in .agents/commands/plan.md:27, yet product-owner.md:110-113 and architect.md:148-150 both warn "Do not assume the caller loaded /spec|/plan — the role is also reached by description match, and then the slash command's instructions were never read." On the description-match path (e.g. a user saying "spec out feature X", which the playbook descriptions are written to trigger) the loop has no termination condition: the subagent asks one question and stops, the main agent relays and re-invokes, forever, burning a context window on ping-pong with no spec produced. Fix: restate the cap inside the subagent files, which are the only instructions guaranteed to load.
Left for upstream: this is a gap in the template's role protocol rather than something this migration introduced, and fixing it here would deepen the divergence that every future copier update has to re-merge.
| | [`harness-usage.md`](harness-usage.md) | how to drive the agent harness (Claude Code & OpenCode): phases, subagents, hooks, document liveness | | ||
| | [`architecture.md`](architecture.md) | orientation: system structure, boundaries, invariants | | ||
| | [`style.md`](style.md) | code style, comments, commit messages, changelog | | ||
| | [`glossary.md`](glossary.md) | the project's ubiquitous language: domain terms used in specs, code, and conversation | |
There was a problem hiding this comment.
[CONFIRMED] cleanup — ✅ Fixed in e245a65
Scaffold-marker section describes template artifacts that do not exist anywhere in this repo.
Failure scenario
Lines 21-34 document _Fill in: …_ blocks, <placeholder> conventions, and "the example work/ unit" — but this brownfield repo has no example work unit (all 13 units are real, completed phases) and rg 'Fill in:' development/ returns only lines 24-25 of this file itself, i.e. the command it advertises for finding remaining scaffold matches nothing but its own documentation. An agent onboarding through this index spends context on 14 lines of instructions for markers it will never encounter, and may go looking for the nonexistent example unit. Fix: drop the section (or keep one line) until a scaffolded work unit actually exists.
|
|
||
| Everything agents and developers need to work on this repo: conventions, | ||
| decisions, and the per-feature work-document lifecycle. This tree is | ||
| **repo-internal**: it is never rendered to a documentation site and nothing |
There was a problem hiding this comment.
[PLAUSIBLE] cleanup — ✅ Fixed in e245a65
"Never published" claim for development/ is contradicted by the packaging config and by README.md linking into it.
Failure scenario
Line 5 asserts the tree is "repo-internal — never published, never linked from a documentation site", but pyproject.toml declares no [tool.hatch.build.targets.sdist] section, so hatchling's default include ships all ~45 files of development/ (design doc, ADRs, 13 work units) inside every published sdist; and README.md:10 — the PyPI long description (readme = "README.md", pyproject.toml:5) — links development/devmm-design.md as "the authoritative design", a relative link that resolves to nothing on the PyPI project page. The invariant is stated in prose with nothing enforcing it, so pip download --no-binary :all: devmm hands users the agent process memory. Fix: add an sdist exclude for development/ (and tests/test_packaging.py coverage for it) or drop the claim.
|
|
||
| ### Changed | ||
|
|
||
| - Repository layout: the agent-facing docs, ADRs and per-feature work units moved |
There was a problem hiding this comment.
[PLAUSIBLE] cleanup — ✅ Fixed in e245a65
Single changelog bullet bundles five unrelated harness-internal changes, against the one-bullet-per-change rule.
Failure scenario
development/style.md:117-119 requires "one concise bullet per change" for "every user-facing change", yet lines 19-24 pack the docs/work -> development move, the template v0.6.0 bump, per-unit report.md, the decision register, the glossary, and the playbook skills into one six-line entry. None of these is user-facing for a library consumer reading the 0.1.x changelog, so the release notes now advertise agent-harness plumbing, and a reader scanning ### Changed for behaviour changes to devmm gets none of the separability the format exists to provide.
|
Filed the three skipped review findings upstream, where the fix belongs — each needs a change across several template role files, which would deepen the divergence every future
The other 12 findings are fixed in |
|
Superseded by #4, which carries these commits forward and lands on the template's v0.7.0 release tag. Closing rather than merging: the template cut three releases while this was open, and two of them rewrote the same files this PR touches. Merging here and then immediately rewriting those files would leave a confusing pair of commits in Nothing here is lost. The migration commits are carried over intact, and the only patches dropped are the ones upstream has since superseded with better versions — the The three findings this PR's review sent upstream are all fixed there and arrive via #4: harness-copier-template#28, #29 and #32. CI here was 9/9 green at |
Feature
Harness maintenance, not a product feature — no
development/work/unit. Thetemplate moved from
v0.5.0tov0.6.0(4 upstream commits, 59 files) and thisreapplies it.
The headline is structural: the agent-facing docs, ADRs and per-feature work
units move out of
docs/andwork/intodevelopment/, leavingdocs/foruser documentation (
docs/api.md) as the new convention reserves it.Why the move is its own first commit
A bare
copier updateexits 0, reports no conflict, and deletesdocs/architecture.md,docs/style.md,docs/testing.mdanddocs/tool-bootstrap.md, substituting the template scaffolds at the new path —_skip_if_existsdoes not cover the delete side of a rename. Moving the treefirst, in
ae0c46d, puts the files where_skip_if_existscan see them, so theupdate preserves them. Verified both ways on throwaway clones before touching
this branch.
Line counts after the update, against
1beb326:architecture.md78 → 78,style.md133 → 133,tool-bootstrap.md122 → 122,testing.md107 → 121(the grafted section below).
Harness changes absorbed
report.mdas a fifth work-unit artifact, written by the Developer as workhappens and audited by the Reviewer for honesty.
DECISION-PENDING:escalation marker plus the decision register indevelopment/adr/README.md, seeded with the two decisions already granted:the ADR 0003 GPU-suite waiver and the coverage thresholds.
development/glossary.md, the document-liveness table, and thearchitecture.md>spec.md>plan.md>tasks.mdauthority order.shared
design-principlescore; each role subagent now reads its playbook.PreToolUsehook fails closed whenjqcannot parse the tool input.trade-off).
Two files
_skip_if_existsshielded were hand-merged, since it is all-or-nothingand upstream is strictly better in both:
development/harness-usage.md(262 → 308) and
development/adr/README.md(29 → 74). Neither hadproject-authored content. Upstream's new Reading gate output section was
grafted into our own
development/testing.md.One deliberate divergence
AGENTS.mdkeeps devmm's stricter rule that a required runtime dependencyneeds an ADR, instead of the template's softer "check whether it clears the ADR
bar". The empty required-dependency set is a design invariant that
tests/test_packaging.pyenforces, so the generic wording would understate it.Definition of done
make verifyrun locally, exit 0 — 900 passed, 75 skippedreport.mdwritten, deviations declared — n/a, no work unit; thedeviation above is declared in this description
ROCm suites off hardware (ADR 0003), unchanged from
1beb326. Thetests/diff is prose-only path references in docstrings andtraceability.mdDECISION-PENDING:line added by this PR has a register row — noneadded; the register is seeded with two pre-existing accepted decisions
layout rather than deciding one
Also checked: every relative Markdown link in every tracked
.mdresolves;.claude/.opencodesymlinks intact;docs/api.mddoctests still collectedand green (4 passed);
AGENTS.mdat 125 lines, under the 200 target.Deviations & notes for the reviewer
Two problems that surfaced only in verification, both fixed here:
(
work/p00/→development/work/p00/), so their../devmm-design.mdtargetsneeded
../../. The bulk rewrite corrected root-relative label text; thesetargets were already relative and needed a depth bump instead. A link checker
over every tracked
.mdnow passes..gitignoreentry.post_gen.pyis incremental in v0.6.0,so it added
development/work/*/scratch.mdbefore the rewrite converted theexisting
work/*/scratch.mdinto the same line. The managed block is restoredto upstream's exact ordering so future updates see it complete.
Worth knowing before the next feature, because the loop behaves differently:
/specmay ask up to five clarifying questions before writing anything,/plancan hand back
SPIKE-REQUEST:lines for the main agent to run (three roundsmax, as the architect cannot execute code),
/verifyranks defectsMAJOR/MINOR/INFO with any MAJOR forcing NEEDS-WORK, and
scratch.mdisredefined from the Developer's notepad to the feature's shared channel.
🤖 Generated with Claude Code