@afokapu/atdd-bun 0.10.31 → 0.10.32

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (50) hide show
  1. package/README.md +2 -112
  2. package/conventions/atdd-bun.profiles/atdd-bun.profiles.presets.convention.yaml +2 -3
  3. package/conventions/planner.docs/planner.docs.area-index-required.convention.yaml +2 -2
  4. package/conventions/planner.docs/planner.docs.artifact-path-shape.convention.yaml +1 -1
  5. package/conventions/planner.docs/planner.docs.asciidoc-only.convention.yaml +0 -1
  6. package/conventions/planner.docs/planner.docs.identity-required.convention.yaml +1 -1
  7. package/conventions/planner.docs/planner.docs.undeclared-change.convention.yaml +1 -2
  8. package/detectors/bun_interlocking_coverage/checks/interlocking_train_sequence.mjs +7 -5
  9. package/detectors/planner_docs_capability/README.md +1 -1
  10. package/integrity.json +21 -49
  11. package/package.json +1 -1
  12. package/relationships.yaml +0 -151
  13. package/src/agent.ts +2 -18
  14. package/src/cli.ts +0 -8
  15. package/src/docs-capability.ts +6 -24
  16. package/src/enforce.ts +1 -2
  17. package/src/hooks.ts +1 -5
  18. package/src/index.ts +0 -2
  19. package/src/integrity.ts +3 -9
  20. package/src/setup.ts +1 -3
  21. package/templates/agents/AGENTS.block.md +0 -2
  22. package/templates/github/atdd-bun.yml +0 -5
  23. package/conventions/delivery/delivery.approved-sha-resolves.convention.yaml +0 -33
  24. package/conventions/delivery/delivery.board.convention.yaml +0 -60
  25. package/conventions/delivery/delivery.config-schema.convention.yaml +0 -49
  26. package/conventions/delivery/delivery.evidence-schema.convention.yaml +0 -34
  27. package/conventions/delivery/delivery.findings-resolved.convention.yaml +0 -42
  28. package/conventions/delivery/delivery.merge-gate.convention.yaml +0 -46
  29. package/conventions/delivery/delivery.model-allowed.convention.yaml +0 -29
  30. package/conventions/delivery/delivery.operating-model.convention.yaml +0 -97
  31. package/conventions/delivery/delivery.review.convention.yaml +0 -42
  32. package/conventions/delivery/delivery.reviewer-independent.convention.yaml +0 -34
  33. package/conventions/delivery/delivery.stages-complete.convention.yaml +0 -33
  34. package/detectors/delivery_evidence/atdd.implementation.yaml +0 -33
  35. package/detectors/delivery_evidence/detect.mjs +0 -9
  36. package/detectors/delivery_evidence/fixtures/clean/atdd-bun.yaml +0 -8
  37. package/detectors/delivery_evidence/fixtures/clean/docs/delivery/tranches/api/evidence.yaml +0 -54
  38. package/detectors/delivery_evidence/fixtures/dirty/atdd-bun.yaml +0 -3
  39. package/detectors/delivery_evidence/fixtures/dirty/docs/delivery/tranches/api/evidence.yaml +0 -31
  40. package/detectors/delivery_evidence/fixtures/dirty/docs/delivery/tranches/data/evidence.yaml +0 -8
  41. package/detectors/delivery_evidence/fixtures/dirty/docs/delivery/tranches/orphan/README.md +0 -1
  42. package/detectors/delivery_evidence/fixtures/dirty/docs/delivery/tranches/ui/evidence.yaml +0 -5
  43. package/detectors/planner_docs_capability/fixtures/dirty_missing_index/docs/delivery/release.adoc +0 -10
  44. package/detectors/planner_docs_capability/fixtures/dirty_missing_index/docs/purpose/index.adoc +0 -5
  45. package/planner-schemas/delivery-config.schema.json +0 -95
  46. package/planner-schemas/delivery-evidence.schema.json +0 -103
  47. package/src/board-ui.ts +0 -91
  48. package/src/board.ts +0 -222
  49. package/src/delivery.ts +0 -567
  50. package/templates/agents/delivery/SKILL.md +0 -15
@@ -1,29 +0,0 @@
1
- schema_version: 1.1.0
2
- rule_id: delivery.model-allowed
3
- kind: rule
4
- status: active
5
- name: Authors and reviewers are allowed models, and every fallback says why
6
- statement: >-
7
- Each work entry's writer is a model its stage allows for writers, and each review's reviewer a model it allows for reviewers. A stage's list is the set of allowed models, in no order; "*" allows any model. Which allowed model does the work is the operator's choice at any moment, so no fallback has to explain it; the record names the model that actually ran (REQUIRED).
8
- terms:
9
- - term_id: fallback
10
- text: >-
11
- a recorded switch from a preferred model to a later one in the stage's list, with role (writer or reviewer) and a reason: an outage, a rate limit, or no auditable report, counted by failures; or the operator's order, referenced by its ruling. A REQUEST CHANGES verdict is never a reason.
12
- content:
13
- summary: >-
14
- The lists are the operator's choice of which models may do the work. Switching between allowed models needs no policy edit and no paperwork, so a rate limit or a preference change is handled on the spot; a model outside the list is still reported.
15
- normative_text: |
16
- The record must name the model that ran. Reviewer independence (a reviewer is never the model that wrote the work it reviews, under different-model) is judged by delivery.reviewer-independent, and a disputed finding upheld on a fresh review blocks the tranche, so switching reviewers cannot buy an approval.
17
- A fallback entry (kind outage, rate_limit, no_report, timeout or operator) may still record why a model was used; it is optional and, when present, must be well formed.
18
- fix_hint: |
19
- Use a model the stage lists, or have the operator add it (or "*") to the stage's list in atdd-bun.yaml; the integrity check reports an added model once for the operator to approve.
20
- metadata:
21
- aliases:
22
- - DELIVERY-MODEL-ALLOWED-001
23
- severity: 2
24
- # strict: atdd-bun fails on every finding; it has no advisory mode and no ratchet baseline.
25
- disposition: strict
26
- introduced_in: 0.8.0
27
- implementation:
28
- type: validator
29
- ref: delivery_evidence
@@ -1,97 +0,0 @@
1
- schema_version: 1.1.0
2
- rule_id: delivery.operating-model
3
- kind: policy
4
- status: active
5
- name: How a program is delivered in tranches, and who does what
6
- statement: >-
7
- A coordinator splits the program into tranches and keeps every slot busy; one persistent driver per tranche runs its lifecycle stages in order (plan, red, green, refactor, final), dispatching each stage's writer and reviewer from the delivery policy in atdd-bun.yaml as fresh headless processes, and records who wrote each stage and every review in the tranche's evidence.yaml.
8
- terms:
9
- - term_id: coordinator
10
- text: >-
11
- Owns throughput, never the work. It splits the program into tranches with explicit dependencies and writes why, the scope and the split in docs/delivery/index.adoc; activates a tranche once its own dependencies have merged (one still waiting may run plan and its review, nothing after); starts one driver per tranche in its own worktree; keeps provider health for the program, telling every driver to skip a model that is down; intervenes when a tranche is idle without being blocked, or has deliverables and no commit after two hours; and hands BLOCKED disputed-finding to a human with both sides. It never writes, reviews or merges.
12
- - term_id: driver
13
- text: >-
14
- Owns one tranche end to end. For each stage of delivery.stages, in order, it starts the stage's writer (any model in its writer list, as the operator chooses) in the tranche worktree, commits red on its own before green starts, passes the stage's gate, and appends a work entry; for each stage with a reviewer it starts a review. It never reviews.
15
- - term_id: review_run
16
- text: >-
17
- Every review is a fresh process in its own detached worktree at the exact SHA (git worktree add --detach), launched with a prompt that gives it the delivery.review convention, the stage, the base SHA, the SHA and the RED commit. Afterwards git status --porcelain must be empty and HEAD still the SHA, or the review is a REVIEWER_FAILURE and does not count. The raw output is kept in the tranche folder and named in the review's report.
18
- - term_id: fallback
19
- text: >-
20
- Any model a stage lists may be used, so a switch needs no fallback: when a model is down or rate-limited, the driver moves to another listed model and records the one that ran. A fallback entry may still say why (outage, rate limit, no auditable report, timeout, or the operator's order); it is optional. A request-changes verdict is never a reason to switch reviewers: a disputed finding upheld on a fresh review blocks the tranche. When no listed model is available, when_exhausted block emits BLOCKED provider-unavailable.
21
- - term_id: repair
22
- text: >-
23
- For each finding of a request-changes review the writer either fixes it or writes one rebuttal with evidence; a fresh review of the same stage follows. If that reviewer upholds a disputed finding, the driver emits BLOCKED disputed-finding and never disputes it again. Any commit, regenerated file, conflict fix or rebase after an approval cancels it and the change goes back to that stage's review.
24
- - term_id: ready
25
- text: >-
26
- When the last reviewed stage approves, the driver sets status ready and approved_sha to that SHA, commits the evidence and its reports alone, pushes, and merges with a merge commit once CI is green. A squash or rebase merge writes a commit no reviewer saw, and CI fails it after the merge.
27
- - term_id: events
28
- text: >-
29
- One line each, for the coordinator to wait on: PROGRAM_EVENT <tranche> <STAGE <stage> <sha> | WORKER_START <role> <model> <sha> | WORKER_END <role> <model> <verdict> | FALLBACK <role> <from>→<to> <reason> | PR_OPENED <url> | MERGED <sha> | BLOCKED <reason> | HEARTBEAT>.
30
- - term_id: commands
31
- text: >-
32
- The default headless command per model, overridden per model under delivery.commands.<model>.author (the writer's command) and .review. {prompt} and {worktree} are substituted. Claude runs take project settings only, so a user's own allowances cannot widen a reviewer. glm, kimi (Moonshot kimi-k3, a replacement for codex and claude-opus) and deepseek-flash (a smaller coding model beside claude-sonnet) run through Pi, which has no permission system; kimi and deepseek-flash take their keys from MOONSHOT_API_KEY and DEEPSEEK_API_KEY, or point delivery.commands at a wrapper that provides them. Through Pi, as a reviewer it gets the read tool alone (the driver puts the diff in its prompt and records its output), and as a writer it runs only inside a container or sandbox limited to the worktree.
33
- values:
34
- codex:
35
- author: codex exec --cd {worktree} --sandbox workspace-write "{prompt}"
36
- review: codex exec --cd {worktree} --sandbox read-only "{prompt}"
37
- claude-opus:
38
- author: cd {worktree} && claude --model opus --setting-sources project --permission-mode acceptEdits --allowedTools Read Grep Glob Edit Write "Bash(bun:*)" "Bash(git:*)" --output-format json -p "{prompt}"
39
- review: cd {worktree} && claude --model opus --setting-sources project --allowedTools Read Grep Glob "Bash(git show:*)" "Bash(git diff:*)" "Bash(git log:*)" --disallowedTools Edit Write NotebookEdit --output-format json -p "{prompt}"
40
- claude-sonnet:
41
- author: cd {worktree} && claude --model sonnet --setting-sources project --permission-mode acceptEdits --allowedTools Read Grep Glob Edit Write "Bash(bun:*)" "Bash(git:*)" --output-format json -p "{prompt}"
42
- review: cd {worktree} && claude --model sonnet --setting-sources project --allowedTools Read Grep Glob "Bash(git show:*)" "Bash(git diff:*)" "Bash(git log:*)" --disallowedTools Edit Write NotebookEdit --output-format json -p "{prompt}"
43
- glm:
44
- author: cd {worktree} && pi -p --no-session --no-extensions --no-skills --no-context-files --tools read,bash,edit,write "{prompt}"
45
- review: cd {worktree} && pi -p --no-session --no-extensions --no-skills --no-context-files --tools read "{prompt}"
46
- kimi:
47
- author: cd {worktree} && pi --provider moonshotai --model kimi-k3 -p --no-session --no-extensions --no-skills --no-context-files --tools read,bash,edit,write "{prompt}"
48
- review: cd {worktree} && pi --provider moonshotai --model kimi-k3 -p --no-session --no-extensions --no-skills --no-context-files --tools read "{prompt}"
49
- deepseek-flash:
50
- author: cd {worktree} && pi --provider deepseek --model deepseek-flash -p --no-session --no-extensions --no-skills --no-context-files --tools read,bash,edit,write "{prompt}"
51
- review: cd {worktree} && pi --provider deepseek --model deepseek-flash -p --no-session --no-extensions --no-skills --no-context-files --tools read "{prompt}"
52
- - term_id: example_record
53
- text: >-
54
- A tranche in progress: the plan written by codex and approved by glm; red, green and refactor written by glm; the final review requesting changes. Only the finding's outcome is ever added to an earlier entry.
55
- values:
56
- tranche: api
57
- status: open
58
- base_sha: 3f2a91c
59
- work:
60
- - { stage: plan, sha: 8b10e44, writer: { model: codex, run: codex-plan-1 } }
61
- - { stage: red, sha: 91aa0b2, writer: { model: glm, run: glm-red-1 } }
62
- - { stage: green, sha: a4c0f11, writer: { model: glm, run: glm-green-1 } }
63
- - { stage: refactor, sha: a4c0f11, writer: { model: glm, run: glm-refactor-1 } }
64
- reviews:
65
- - stage: plan
66
- sha: 8b10e44
67
- reviewer: { model: glm, run: glm-plan-review-1 }
68
- verdict: approve
69
- checked: [ACC-API-001, planner.decomposition]
70
- report: docs/delivery/tranches/api/plan-1.json
71
- - stage: final
72
- sha: a4c0f11
73
- reviewer: { model: codex, run: codex-final-1 }
74
- verdict: request_changes
75
- checked: [ACC-API-001, src/wagons/api, coder.bun.error-response-*]
76
- findings:
77
- - { id: F1, severity: high, evidence: "src/wagons/api/handler.ts:42", invariant: "coded error bodies", affects: [ui], proposed_fix: "return { code: 'API_NOT_FOUND' }" }
78
- report: docs/delivery/tranches/api/final-1.json
79
- content:
80
- summary: >-
81
- The policy says who may write and review each stage; this convention says how the coordinator and drivers carry it out. The record they leave is what the delivery rules judge.
82
- normative_text: |
83
- With delivery.board set, the coordinator and drivers talk on the board (delivery.board), and each driver posts its workers' tasks, results, review requests and verdicts there; workers never use the board. Without it, a task is the prompt an agent is launched with and its result is the run's output, which the driver keeps. Agents run in panes of the multiplexer named in delivery.multiplexer (default herdr) only for humans to watch; learn its commands from its own help before the first dispatch. Never deliver work to an agent by typing into its pane.
84
- Before a hosted model receives private repository content, confirm the user or organization authorized it.
85
- Never edit the delivery skill, these conventions, or loosen the delivery policy to get a tranche through. If the policy must change, stop and ask the human.
86
- fix_hint: |
87
- Follow the driver's order: writer, gate, work entry; review, repair, fresh review; ready and merge commit. The example_record term shows a record the profile accepts.
88
- exceptions:
89
- - >-
90
- A stage the policy does not name has no writer and no review; a stage with a writer but no reviewer is held by its gate alone.
91
- metadata:
92
- aliases:
93
- - DELIVERY-OPERATING-MODEL-001
94
- introduced_in: 0.10.0
95
- # A policy, not a rule: how agents carry out the delivery policy cannot be validated. The record they leave is.
96
- implementation:
97
- type: none
@@ -1,42 +0,0 @@
1
- schema_version: 1.1.0
2
- rule_id: delivery.review
3
- kind: policy
4
- status: active
5
- name: What each review establishes, and how a reviewer works
6
- statement: >-
7
- A reviewer is a fresh, read-only process for one stage of one tranche, given the stage, the base SHA, the SHA and the RED commit. It reviews the change between the base and the SHA, working through its stage's checklist systematically, systemically, adversarially and economically, and returns one review entry with verdict, checked and findings.
8
- terms:
9
- - term_id: plan
10
- text: >-
11
- Are we building the right thing? The plan files the change adds or modifies: the decomposition (wagon, WMBT, acceptance, train, journey, contract) covers the intent; every acceptance is testable with one observable outcome and every WMBT has a SMOKE acceptance; edge cases, migrations, security and architecture constraints are represented; the acceptances can prove the feature; the plan builds on the wagons, contracts and components that already exist wherever they fit, and plans no machinery outside the tranche's scope; it follows the accepted architecture decisions (docs/architecture/decisions/index.adoc), and a new technology choice comes with its own ADR; owned files do not overlap other tranches.
12
- - term_id: final
13
- text: >-
14
- Does the change satisfy the approved plan? The tests, implementation and refactoring the change brings are read together. Every acceptance the plan names has a test bound by URN that asserts the behaviour, not a mock; each acceptance test differs from its RED commit only by the removed RED marker and Phase header, and any other change is justified; behaviour is correct on edge and error paths; the changed code keeps layering, composition, DTO, error-response and security sound; SMOKE runs through the real entry point; the change reuses what the codebase already has, duplicates nothing, and adds no machinery beyond what the plan needs; it uses what the accepted ADRs chose and brings in no alternative to them; nothing drifts from the plan.
15
- - term_id: red
16
- text: >-
17
- Where the policy gives red a reviewer. Every acceptance has a RED test bound by URN that fails for the missing behaviour and would still fail for a wrong implementation, asserting observable output rather than mocks.
18
- - term_id: green_refactor
19
- text: >-
20
- Where the policy gives green or refactor a reviewer. Every behaviour is correct against its acceptance on edge and error paths; the changed code keeps layering, composition, DTO, error-response and security sound, reuses what exists and duplicates nothing; SMOKE runs through the real entry point.
21
- - term_id: method
22
- text: >-
23
- Systematic, the whole checklist, with everything checked listed in checked, not only what failed. Systemic, from the change to what it affects (callers, contracts, other tranches, downstream owners), named in affects; code the change does not touch or affect is out of scope. Adversarial, assuming the change is wrong and proving it; a finding needs a file and line, a failing command or a counter-example. Economical, the change does its job with the least new machinery: it reuses what exists, duplicates nothing, and adds no framework, abstraction, configuration, tooling or meta machinery (machinery for building or checking machinery) beyond the tranche's scope; such a finding names the existing piece to reuse or the part to remove. Economy never trades away effectiveness: a smaller change that no longer satisfies an acceptance is not an improvement. A small change gets a short review.
24
- content:
25
- summary: >-
26
- The two default reviews carry the judgement no gate can: the plan before RED, and the whole change at its head. The gates between them are deterministic.
27
- normative_text: |
28
- The reviewer runs in a detached worktree at the SHA and reads the change with git diff base..SHA. The gates are CI's, not the reviewer's: it does not re-run them, and judges what they cannot. It may read, search and use git show, git diff and git log. It never edits, commits or writes, including output-file options such as git diff --output=; the driver checks the worktree afterwards, and a review that wrote does not count (delivery.reviewer-independent). It judges and proposes; the author applies.
29
- A finding carrying the author's rebuttal is withdrawn, left out, when the rebuttal holds, or upheld, repeated with the same id; there is no second round (delivery.findings-resolved).
30
- The reviewer returns exactly one JSON object (valid YAML, so it goes into evidence.yaml unchanged, and a # inside a string is never read as a comment), the review entry of delivery-evidence.schema.json without fallback or report, which the driver adds: stage, sha, verdict (approve only with no critical or high finding), checked, and findings, each with id, severity (critical, high, medium, low), evidence, invariant, affects and proposed_fix, a precise description or short snippet, never a rewrite.
31
- fix_hint: |
32
- Give the reviewer this convention, the stage, the base SHA, the SHA and the RED commit. A review that skipped part of its checklist shows it in checked; run the stage again with a fresh reviewer.
33
- exceptions:
34
- - >-
35
- A stage the policy does not name has no review; its checklist applies only where the policy names it.
36
- metadata:
37
- aliases:
38
- - DELIVERY-REVIEW-001
39
- introduced_in: 0.10.0
40
- # A policy, not a rule: what a reviewer judges cannot be validated. The record it leaves is, by the delivery rules.
41
- implementation:
42
- type: none
@@ -1,34 +0,0 @@
1
- schema_version: 1.1.0
2
- rule_id: delivery.reviewer-independent
3
- kind: rule
4
- status: active
5
- name: Every reviewer is a fresh process independent of the writers
6
- statement: >-
7
- A reviewer's run never wrote anything in the tranche and never reviewed another entry; where the stage requires different-model independence (the default), the reviewer's model wrote none of the work the review answers for: its own stage and every stage since the previous reviewed one (REQUIRED).
8
- terms:
9
- - term_id: run
10
- text: >-
11
- the identity of one process: a session id, a pane id with its start time, or the retained report. Two entries with the same run were produced by the same process.
12
- - term_id: independence
13
- text: >-
14
- fresh-process: the reviewer is a new process that wrote nothing. different-model: additionally, its model wrote none of the work it reviews; the final review answers for red, green and refactor when none of them is reviewed, and a review whose range recorded no work answers for the latest recorded work before it.
15
- content:
16
- summary: >-
17
- A reviewer that edits becomes a writer, and a reviewer that already saw an earlier round is anchored to it. Independence is what makes an approval evidence.
18
- normative_text: |
19
- Every review is a new process. The run identifiers make that checkable: a reviewer run that appears as a writer anywhere in the tranche, or on a second review, is not independent. The stricter mode is chosen per stage in the policy.
20
- fix_hint: |
21
- Re-run the review in a fresh process and record its own run; under different-model, use the next reviewer model in the list that wrote none of the reviewed work.
22
- exceptions:
23
- - >-
24
- The persistent driver dispatches the work and opens the PR; its run may never review.
25
- metadata:
26
- aliases:
27
- - DELIVERY-REVIEWER-INDEPENDENT-001
28
- severity: 3
29
- # strict: atdd-bun fails on every finding; it has no advisory mode and no ratchet baseline.
30
- disposition: strict
31
- introduced_in: 0.8.0
32
- implementation:
33
- type: validator
34
- ref: delivery_evidence
@@ -1,33 +0,0 @@
1
- schema_version: 1.1.0
2
- rule_id: delivery.stages-complete
3
- kind: rule
4
- status: active
5
- name: A ready record has every configured stage approved
6
- statement: >-
7
- A record with status ready has, for every stage the policy gives a reviewer, a last review that approves (a stage with nothing written records no work); its approved_sha is the SHA the last review of the closing stage approved; and every review names its retained raw report, which exists (REQUIRED).
8
- terms:
9
- - term_id: closing_stage
10
- text: >-
11
- the last reviewed stage in lifecycle order (plan, red, green, refactor, final); by default final, the review of the PR head, which answers for everything written since the plan review.
12
- content:
13
- summary: >-
14
- Ready is the driver's claim that the tranche can merge. It is only true when no stage is missing and the approval covers the commit being merged.
15
- normative_text: |
16
- Each stage may take several rounds; only its last review counts. The closing stage's approval names the SHA the whole tranche stands on, and approved_sha must be that SHA: the merge gate compares the branch head against it.
17
- fix_hint: |
18
- Run the missing review, or set status back to open until it has run. Set approved_sha to the SHA the final review approved.
19
- exceptions:
20
- - >-
21
- A ready record is judged by the policy in atdd-bun.yaml at its approved_sha, the policy it was approved under; a later policy change does not re-judge it. A record in progress is judged by the current policy.
22
- - >-
23
- A stage the policy omits is not required. Omitting one loosens the policy and is reported by the integrity check until a human approves it.
24
- metadata:
25
- aliases:
26
- - DELIVERY-STAGES-COMPLETE-001
27
- severity: 3
28
- # strict: atdd-bun fails on every finding; it has no advisory mode and no ratchet baseline.
29
- disposition: strict
30
- introduced_in: 0.8.0
31
- implementation:
32
- type: validator
33
- ref: delivery_evidence
@@ -1,33 +0,0 @@
1
- schema_version: "1.0.0"
2
- kind: implementation
3
- subtype: validator
4
- implementation_id: delivery.evidence.impl
5
- targets_workspace: atdd.workspace.bun
6
- contract_version: "1.0.0"
7
- # The delivery record: one <root>/<tranche>/evidence.yaml per tranche, judged against the `delivery:` policy
8
- # in atdd-bun.yaml. Runs only under the delivery profile and is inert until the repository adopts it
9
- # (a `delivery:` block, or `delivery` named in `profiles:`).
10
- emits_rule_ids:
11
- - delivery.config-schema
12
- - delivery.evidence-schema
13
- - delivery.model-allowed
14
- - delivery.reviewer-independent
15
- - delivery.findings-resolved
16
- - delivery.stages-complete
17
- - delivery.approved-sha-resolves
18
- # Emitted only at the merge gate (ATDD_DELIVERY_GATE=merge, set by the generated CI on pull requests and the
19
- # merge queue): it needs a change set against the base branch. tests/delivery.test.ts triggers it in a real
20
- # repository.
21
- api_emits_rule_ids:
22
- - delivery.merge-gate
23
- realizes_convention:
24
- - delivery.config-schema
25
- - delivery.evidence-schema
26
- - delivery.model-allowed
27
- - delivery.reviewer-independent
28
- - delivery.findings-resolved
29
- - delivery.stages-complete
30
- - delivery.approved-sha-resolves
31
- - delivery.merge-gate
32
- entrypoint: detect.mjs
33
- report: detect.mjs
@@ -1,9 +0,0 @@
1
- import { mkdir, writeFile } from "node:fs/promises";
2
- import { dirname } from "node:path";
3
- import { validateDelivery } from "../../src/delivery.ts";
4
-
5
- const roots = JSON.parse(process.env.ATDD_SCAN_ROOTS ?? "[]"), report = process.env.ATDD_VIOLATIONS_REPORT;
6
- if (!report) throw new Error("ATDD_VIOLATIONS_REPORT is required");
7
- const violations = (await Promise.all(roots.map(root => validateDelivery(root)))).flat().map(item => ({ ...item, line: 1, col: 1, source_line: "" }));
8
- await mkdir(dirname(report), { recursive: true });
9
- await writeFile(report, JSON.stringify({ violations }, null, 2));
@@ -1,8 +0,0 @@
1
- profiles: [delivery]
2
- delivery:
3
- independence: fresh-process
4
- stages:
5
- plan_review: { authors: [codex], reviewers: [glm, claude] }
6
- test_review: { authors: [glm, claude], reviewers: [codex, claude] }
7
- code_review: { authors: [glm, claude], reviewers: [glm, claude], independence: different-model }
8
- final_review: { authors: [codex], reviewers: [codex, claude] }
@@ -1,54 +0,0 @@
1
- # In progress: every stage reviewed, the code-review dispute settled, the PR not yet marked ready.
2
- tranche: api
3
- status: open
4
- base_sha: 3f2a91c
5
- reviews:
6
- - stage: plan_review
7
- sha: 8b10e44
8
- author: { model: codex, run: driver-api }
9
- reviewer: { model: glm, run: glm-plan-1 }
10
- verdict: approve
11
- checked: [ACC-API-001, ACC-API-002, planner.decomposition]
12
- - stage: test_review
13
- sha: 91aa0b2
14
- author: { model: glm, run: glm-red-1 }
15
- reviewer: { model: codex, run: codex-test-1 }
16
- verdict: approve
17
- checked: [ACC-API-001, ACC-API-002, tester.bun.red]
18
- - stage: code_review
19
- sha: a4c0f11
20
- author: { model: glm, run: glm-green-1 }
21
- reviewer: { model: claude, run: claude-code-1 }
22
- fallback:
23
- - { from: glm, kind: rate_limit, failures: 3, window: { from: "2026-09-25T09:00:00Z", to: "2026-09-25T09:08:00Z" }, reason: "rate limit: 3 failures in 10 minutes" }
24
- verdict: request_changes
25
- checked: [ACC-API-001, ACC-API-002, src/wagons/api, coder.bun.error-response]
26
- findings:
27
- - id: F1
28
- severity: high
29
- evidence: src/wagons/api/handler.ts:42 returns a bare string
30
- invariant: every error response carries a coded body
31
- affects: [ui]
32
- proposed_fix: return { code "API_NOT_FOUND" } instead of the bare string
33
- outcome: fixed
34
- - id: F2
35
- severity: medium
36
- evidence: src/wagons/api/handler.ts:57 retries without a bound
37
- invariant: outbound calls are bounded
38
- proposed_fix: cap the retry loop at three attempts
39
- rebuttal: "The loop is bounded by the caller's AbortSignal; see handler.test.ts:31 which proves it stops."
40
- outcome: withdrawn
41
- - stage: code_review
42
- sha: c77d0a2
43
- author: { model: glm, run: glm-green-2 }
44
- reviewer: { model: claude, run: claude-code-2 }
45
- fallback:
46
- - { from: glm, kind: rate_limit, failures: 3, window: { from: "2026-09-25T09:00:00Z", to: "2026-09-25T09:08:00Z" }, reason: "rate limit: 3 failures in 10 minutes" }
47
- verdict: approve
48
- checked: [ACC-API-001, ACC-API-002, src/wagons/api, F1, F2]
49
- - stage: final_review
50
- sha: c77d0a2
51
- author: { model: codex, run: driver-api }
52
- reviewer: { model: codex, run: codex-final-1 }
53
- verdict: approve
54
- checked: [src/wagons/api, contracts, ui]
@@ -1,3 +0,0 @@
1
- profiles: [delivery]
2
- delivery:
3
- independence: loose
@@ -1,31 +0,0 @@
1
- # Ready, but the approved SHA is not what final_review approved and exists nowhere, a reviewer is off-list,
2
- # one reviewer also authored, and a finding was never resolved.
3
- tranche: api
4
- status: ready
5
- base_sha: 3f2a91c
6
- approved_sha: "0000000"
7
- reviews:
8
- - stage: plan_review
9
- sha: 8b10e44
10
- author: { model: codex, run: driver-api }
11
- reviewer: { model: gpt, run: gpt-plan-1 }
12
- verdict: approve
13
- checked: [ACC-API-001]
14
- - stage: final_review
15
- sha: 91aa0b2
16
- author: { model: codex, run: codex-green-1 }
17
- reviewer: { model: codex, run: driver-api }
18
- verdict: request_changes
19
- checked: [ACC-API-001]
20
- findings:
21
- - id: F1
22
- severity: high
23
- evidence: src/wagons/api/handler.ts:42 returns a bare string
24
- invariant: every error response carries a coded body
25
- proposed_fix: return a coded error body
26
- - stage: final_review
27
- sha: a4c0f11
28
- author: { model: codex, run: codex-green-2 }
29
- reviewer: { model: codex, run: codex-final-2 }
30
- verdict: approve
31
- checked: [ACC-API-001, F1]
@@ -1,8 +0,0 @@
1
- # A reviewer without a verdict or a checklist.
2
- tranche: data
3
- status: open
4
- base_sha: 3f2a91c
5
- reviews:
6
- - stage: plan_review
7
- sha: 8b10e44
8
- reviewer: { model: glm, run: glm-plan-1 }
@@ -1 +0,0 @@
1
- The orphan tranche has a folder and no evidence.yaml.
@@ -1,5 +0,0 @@
1
- # The folder says ui, the record says web.
2
- tranche: web
3
- status: open
4
- base_sha: 3f2a91c
5
- reviews: []
@@ -1,10 +0,0 @@
1
- = Release
2
- :doc-id: delivery.release
3
- :status: current
4
-
5
- The delivery area exists and holds this document — but carries no index.adoc.
6
-
7
- This file is what makes the fixture REAL. Expressing "the area exists with no
8
- index" as an empty directory made the defect invisible to git, so the fixture
9
- arrived empty on a fresh clone and the rule it proves never fired. A fixture that
10
- only works on the machine that authored it proves nothing.
@@ -1,5 +0,0 @@
1
- = Purpose
2
- :doc-id: purpose.index
3
- :status: current
4
-
5
- WHY and WHAT.
@@ -1,95 +0,0 @@
1
- {
2
- "$schema": "http://json-schema.org/draft-07/schema#",
3
- "title": "Delivery Profile Configuration",
4
- "description": "The `delivery:` block of atdd-bun.yaml: which models may author and review each lifecycle stage, in preference order, how independent a reviewer must be, and when a model counts as unavailable. Every key is optional; an omitted key takes the package default (src/delivery.ts). `stages`, when given, replaces the default stage set: a stage it omits is not required.",
5
- "$comment": "Shipped by the delivery profile (delivery_evidence). Cross-field checks (a reviewer listed twice, a stage override naming an unknown mode) are schema-level; loosening against the base branch is judged by the integrity check.",
6
- "type": "object",
7
- "additionalProperties": false,
8
- "properties": {
9
- "root": {
10
- "type": "string",
11
- "pattern": "^[a-z0-9_][a-z0-9_.-]*(?:/[a-z0-9_][a-z0-9_.-]*)*$",
12
- "description": "Repository-relative folder holding one <tranche>/evidence.yaml per tranche, in canonical form: no leading, trailing or doubled slash, no dot segments. Default: docs/delivery/tranches, beside the program's reasoning in the docs profile's delivery area. Changing it after adoption is a loosening the integrity check reports."
13
- },
14
- "require_record": {
15
- "type": "boolean",
16
- "description": "At the gate, a change outside the delivery root needs a tranche record in the same change, unless atdd-bun.yaml is the only such file. Default: true; turning it off is a loosening."
17
- },
18
- "multiplexer": {
19
- "type": "string",
20
- "pattern": "^[a-z][a-z0-9-]*$",
21
- "description": "The terminal multiplexer the coordinator drives agents through, named by its command. Default: herdr. Any other name is accepted; the agent learns its commands from the multiplexer's own help."
22
- },
23
- "board": {
24
- "type": "object",
25
- "additionalProperties": false,
26
- "description": "Opt-in: when present, agents talk through this local message board (delivery.board); when absent there is no board. $ATDD_BOARD_URL moves it on one machine but never switches it on.",
27
- "properties": {
28
- "url": { "type": "string", "pattern": "^https?://(127\\.0\\.0\\.1|localhost|\\[::1\\])(:[0-9]{1,5})?/?$", "description": "A local address only. Default: http://127.0.0.1:2586." }
29
- }
30
- },
31
- "independence": { "$ref": "#/definitions/independence" },
32
- "stages": {
33
- "type": "object",
34
- "additionalProperties": false,
35
- "minProperties": 1,
36
- "properties": {
37
- "plan": { "$ref": "#/definitions/stage" },
38
- "red": { "$ref": "#/definitions/stage" },
39
- "green": { "$ref": "#/definitions/stage" },
40
- "refactor": { "$ref": "#/definitions/stage" },
41
- "final": { "$ref": "#/definitions/stage" },
42
- "plan_review": { "$ref": "#/definitions/stage" },
43
- "test_review": { "$ref": "#/definitions/stage" },
44
- "code_review": { "$ref": "#/definitions/stage" },
45
- "final_review": { "$ref": "#/definitions/stage" }
46
- }
47
- },
48
- "fallback": {
49
- "type": "object",
50
- "additionalProperties": false,
51
- "properties": {
52
- "after_failures": { "type": "integer", "minimum": 1, "description": "Failures (outage, rate limit, no auditable report) before a model counts as unavailable. A REQUEST CHANGES verdict is never a failure." },
53
- "within_minutes": { "type": "integer", "minimum": 1 },
54
- "when_exhausted": { "enum": ["block", "wait"], "description": "block: the tranche emits BLOCKED provider-unavailable and the coordinator reassigns the slot. wait: the driver keeps retrying the last model in the list." }
55
- }
56
- },
57
- "commands": {
58
- "type": "object",
59
- "description": "Headless invocation per model, overriding the skill's built-in defaults. {prompt} and {worktree} are substituted by the driver. Adding or changing an entry after adoption is a loosening the integrity check reports; removing one returns to the default.",
60
- "additionalProperties": {
61
- "type": "object",
62
- "additionalProperties": false,
63
- "properties": {
64
- "author": { "type": "string", "minLength": 1 },
65
- "review": { "type": "string", "minLength": 1 }
66
- }
67
- }
68
- }
69
- },
70
- "definitions": {
71
- "independence": {
72
- "enum": ["fresh-process", "different-model"],
73
- "description": "fresh-process: the reviewer is a new process that wrote nothing in the tranche. different-model (the default): additionally, its model wrote none of the work the review covers."
74
- },
75
- "models": {
76
- "type": "array",
77
- "minItems": 1,
78
- "uniqueItems": true,
79
- "items": { "type": "string", "pattern": "^(\\*|[a-z][a-z0-9-]*)$" },
80
- "description": "The models allowed for the role, in no order: any listed model may do the work, and \"*\" allows any model."
81
- },
82
- "stage": {
83
- "type": "object",
84
- "additionalProperties": false,
85
- "anyOf": [{ "required": ["writer"] }, { "required": ["reviewer"] }, { "required": ["reviewers"] }],
86
- "properties": {
87
- "writer": { "$ref": "#/definitions/models", "description": "Who may write this stage, in preference order. Absent: nobody writes it, as for final." },
88
- "reviewer": { "$ref": "#/definitions/models", "description": "Who reviews this stage, in preference order. Absent: the stage is held by its gate alone." },
89
- "authors": { "$ref": "#/definitions/models", "description": "0.9 spelling of writer, on a 0.9 stage name." },
90
- "reviewers": { "$ref": "#/definitions/models", "description": "0.9 spelling of reviewer, on a 0.9 stage name." },
91
- "independence": { "$ref": "#/definitions/independence" }
92
- }
93
- }
94
- }
95
- }