gentle-pi 1.0.2 → 1.0.3

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 (72) hide show
  1. package/README.md +42 -7
  2. package/assets/agents/jd-judge-a.md +1 -1
  3. package/assets/agents/jd-judge-b.md +1 -1
  4. package/assets/agents/review-readability.md +1 -1
  5. package/assets/agents/review-refuter.md +17 -9
  6. package/assets/agents/review-reliability.md +1 -1
  7. package/assets/agents/review-resilience.md +1 -1
  8. package/assets/agents/review-risk.md +1 -1
  9. package/assets/agents/review-validator.md +3 -3
  10. package/assets/agents/sdd-apply.md +7 -1
  11. package/assets/agents/sdd-status.md +7 -4
  12. package/assets/agents/sdd-tasks.md +11 -0
  13. package/assets/chains/sdd-full.chain.md +1 -1
  14. package/assets/orchestrator-delegation.md +4 -4
  15. package/assets/orchestrator.md +1 -1
  16. package/assets/support/sdd-status-contract.md +14 -4
  17. package/extensions/gentle-ai.ts +1772 -148
  18. package/lib/gentle-ai-binary.ts +89 -0
  19. package/lib/native-review-cli.ts +548 -0
  20. package/lib/review-authority-supersession.ts +1055 -0
  21. package/lib/review-candidate-view.ts +546 -0
  22. package/lib/review-compact-contract.ts +94 -7
  23. package/lib/review-compact-gate.ts +88 -4
  24. package/lib/review-compact-store.ts +24 -3
  25. package/lib/review-facade.ts +175 -24
  26. package/lib/review-refuter-adapter.ts +129 -0
  27. package/lib/review-snapshot.ts +42 -0
  28. package/lib/sdd-status.ts +197 -39
  29. package/package.json +2 -1
  30. package/scripts/gentle-ai-installer.mjs +225 -0
  31. package/scripts/install-gentle-ai.mjs +14 -0
  32. package/scripts/verify-package-files.mjs +5 -0
  33. package/skills/_shared/review-ledger-contract.md +9 -7
  34. package/skills/gentle-ai/SKILL.md +8 -6
  35. package/skills/judgment-day/SKILL.md +1 -1
  36. package/skills/judgment-day/references/prompts-and-formats.md +1 -1
  37. package/tests/artifact-language.test.ts +20 -0
  38. package/tests/fixtures/native-review-cli/v2.1.2/bind-sdd.json +25 -0
  39. package/tests/fixtures/native-review-cli/v2.1.2/finalize.json +8 -0
  40. package/tests/fixtures/native-review-cli/v2.1.2/sdd-status-engram.json +139 -0
  41. package/tests/fixtures/native-review-cli/v2.1.2/sdd-status.json +200 -0
  42. package/tests/fixtures/native-review-cli/v2.1.2/start.json +12 -0
  43. package/tests/fixtures/native-review-cli/v2.1.2/validate-allow.json +24 -0
  44. package/tests/fixtures/native-review-cli/v2.1.2/validate-deny-empty-context.json +20 -0
  45. package/tests/fixtures/native-review-cli/v2.1.2/validate-deny.json +28 -0
  46. package/tests/fixtures/native-review-cli/v2.1.3/bind-sdd.json +25 -0
  47. package/tests/fixtures/native-review-cli/v2.1.3/finalize.json +8 -0
  48. package/tests/fixtures/native-review-cli/v2.1.3/sdd-status-engram.json +139 -0
  49. package/tests/fixtures/native-review-cli/v2.1.3/sdd-status.json +200 -0
  50. package/tests/fixtures/native-review-cli/v2.1.3/start.json +14 -0
  51. package/tests/fixtures/native-review-cli/v2.1.3/validate-allow.json +24 -0
  52. package/tests/fixtures/native-review-cli/v2.1.3/validate-deny-empty-context.json +20 -0
  53. package/tests/fixtures/native-review-cli/v2.1.3/validate-deny.json +28 -0
  54. package/tests/gentle-ai-binary.test.ts +148 -0
  55. package/tests/gentle-ai-installer.test.ts +219 -0
  56. package/tests/native-review-cli.test.ts +653 -0
  57. package/tests/native-review-parity-runtime.test.ts +170 -0
  58. package/tests/package-manifest.test.ts +27 -2
  59. package/tests/review-authority-recovery-docs.test.ts +25 -0
  60. package/tests/review-authority-supersession.test.ts +581 -0
  61. package/tests/review-candidate-view.test.ts +288 -0
  62. package/tests/review-compact-contract.test.ts +36 -4
  63. package/tests/review-compact-gate.test.ts +236 -7
  64. package/tests/review-compact-store.test.ts +11 -0
  65. package/tests/review-controller-native-routing.test.ts +2280 -0
  66. package/tests/review-controller.test.ts +342 -28
  67. package/tests/review-facade.test.ts +129 -19
  68. package/tests/review-ledger-contract.test.ts +58 -5
  69. package/tests/review-refuter-adapter.test.ts +89 -0
  70. package/tests/review-snapshot.test.ts +25 -0
  71. package/tests/runtime-harness.mjs +23 -0
  72. package/tests/sdd-status.test.ts +127 -6
package/README.md CHANGED
@@ -65,6 +65,8 @@ Most coding-agent sessions fail for operational reasons, not model reasons:
65
65
  pi install npm:gentle-pi
66
66
  ```
67
67
 
68
+ The npm postinstall downloads the exact platform-specific official Gentle AI v2.1.4 archive into this package's private `.gentle-ai/v2.1.4/` directory and verifies its pinned SHA-256 before extraction. It never uses `PATH` or a global `gentle-ai` installation. For development or offline installs only, set `GENTLE_PI_SKIP_GENTLE_AI_INSTALL=1`; native review operations then fail closed with an actionable `package-local-binary-missing` error until the package is reinstalled normally.
69
+
68
70
  Recommended companion packages:
69
71
 
70
72
  ```bash
@@ -137,9 +139,17 @@ parent git/status + clarify → bind ordinary snapshot/route → one worker writ
137
139
 
138
140
  Review lenses are controller-selected transaction actors, not lifecycle hooks. `scout`/`context-builder` save parent context by compressing broad exploration. `worker` preserves a single writer thread. Commit, push, PR, and release validate receipts with zero actors.
139
141
 
140
- ### Review-store migration safety
142
+ Review actors are dispatched only through parent `subagent_run` calls in `mode: "task"`. Before execution, the controller verifies every entry, content hash, mode, root, and index in one selected immutable candidate tree per requested lens, then appends one bounded controller-owned block containing only the Git-derived base-to-candidate changed scope. That compact scope groups present paths by exact candidate mode and lists deletions explicitly; it fails closed when the changed scope itself exceeds the dispatch bound. Mixed batches, unselected/missing/stale views, user-supplied candidate-view text, unsafe paths, and non-task dispatches fail closed; lean resources and actor tool allowlists remain unchanged.
143
+
144
+ ### Review authority recovery and reset safety
145
+
146
+ Legacy pre-graph authority is never migrated. `gentle_review inspect` reports an exact repository-bound destructive reset challenge; only that authorized RESET or RECOVER can quarantine graph-v1 and compact-v2 authority, initialize an empty graph-v1 incarnation, and require fresh review. Interrupted destructive recovery remains blocked until explicit forward recovery. Existing graph-v1 ordinary lineages remain readable, gate-validatable, and exportable but are read-only; Judgment Day remains mutable on graph-v1.
147
+
148
+ A **non-destructive supersession** is available only for an eligible, immutable graph-v1 source and an independently approved compact-v2 successor with identical repository, change, target, scope, untracked, policy, ledger, and receipt bindings. First call `prepare-supersession`, review its exact English challenge, then call `supersede` only after fresh interactive approval. Headless approval, a changed challenge, a stale binding, unsupported data, or ambiguous authority fails closed and leaves the change `resolve-review` blocked.
141
149
 
142
- Legacy pre-graph authority is never migrated. `gentle_review inspect` reports an exact repository-bound destructive reset challenge; only that authorized reset can quarantine graph-v1 and compact-v2 authority, initialize an empty graph-v1 incarnation, and require fresh review. Interrupted resets remain blocked until explicit forward recovery. Existing graph-v1 ordinary lineages remain readable, gate-validatable, and exportable but are read-only; Judgment Day remains mutable on graph-v1.
150
+ Supersession records are append-only under `authority-supersession-v1`; they do not rewrite graph-v1 history. An exact retry is idempotent. A divergent retry or conflict fails closed and requires a new operation. RESET/RECOVER stay destructive and never run as a fallback from supersession. Rollback can stop recognizing a record but does not delete it, re-enable graph-v1 mutation, or select another successor.
151
+
152
+ Pre-commit, pre-push, pre-PR, and release gates revalidate the recovered source, successor, receipt, policy, scope, intended-untracked proof, and live target. Recovery does not grant a new budget or bypass dangerous-command authorization, publication checks, historical graph-v1 receipt validation, or graph export.
143
153
 
144
154
  `reviewer` is not an installed subagent name. It is a routing intent. Select the concrete lens by risk profile:
145
155
 
@@ -157,6 +167,28 @@ If multiple rows match, run the narrow set that covers the risk. For example, sh
157
167
 
158
168
  New ordinary review uses compact `gentle_review` `start -> finalize -> validate`.
159
169
 
170
+ Native contract pairing is exact: this adapter supports `gentle-ai 2.1.4` only from its package-local verified binary and rechecks that version before every native operation. Production native operations resolve an absolute package-owned path and never fall back to `PATH` or a global executable. Once v2.1.4 has written review authority, rollback MUST preserve every native store and receipt and MUST NOT run a downgraded binary against that repository. Disable the Pi route or roll forward to a compatible authority-aware release instead; deleting authority data or reinstalling an older binary is not a rollback path.
171
+
172
+ ### FINALIZE wrapper input
173
+
174
+ `gentle_review` accepts `input` as a JSON-serialized object string. For initial results, provide `review_result.lens_results[]`; each selected lens appears exactly once with `lens`, `findings`, and non-empty `evidence`. A clean lens uses `findings: []`. `final_evidence` and `final_verification_passed` are paired: provide both or neither.
175
+
176
+ ```json
177
+ {
178
+ "review_result": {
179
+ "lens_results": [
180
+ {
181
+ "lens": "review-reliability",
182
+ "findings": [],
183
+ "evidence": ["complete candidate reviewed"]
184
+ }
185
+ ]
186
+ }
187
+ }
188
+ ```
189
+
190
+ This is the Pi wrapper contract, not the native CLI file contract. The native command receives separate `--result`, `--refuter`, `--validation`, and `--evidence` files from the wrapper.
191
+
160
192
  START derives the complete Git/untracked snapshot, lineage, persisted `low | medium | high` tier, zero/one/four lenses, authored changed lines, and correction budget `min(200, ceil(original_changed_lines / 2))`. Generated `testdata/golden/**` stays in snapshot identity but does not count as authored risk lines.
161
193
 
162
194
  Every finding requires `evidence_class`, `causal_disposition`, and concrete changed-hunk, candidate-created-path, differential-test, or before/after proof. Missing IDs are assigned natively and selected-lens results are canonicalized deterministically.
@@ -167,17 +199,17 @@ Only severe `introduced`, `behavior-activated`, or `worsened` findings with vali
167
199
 
168
200
  Deterministic blockers need no refuter. Inferential blockers use exactly one complete read-only refuter batch.
169
201
 
170
- Invalid, missing, duplicate, unknown, or inconclusive refuter output escalates without a replacement refuter.
202
+ Refuter proof may be independent concrete reproduction evidence; it does not need to duplicate reviewer `proof_refs`. Invalid, empty, malformed, missing, duplicate, unknown, or inconclusive refuter output escalates without a replacement refuter.
171
203
 
172
204
  When native IDs are assigned to inferential findings, the first FINALIZE returns their canonical rows and a content-derived request hash without mutation; the second replays identical lens input with that hash and one complete refuter batch.
173
205
 
174
- Ordinary permits one correction and one targeted validator. FINALIZE requires a positive forecast before editing, derives actual correction lines from Git, and binds correction to original candidate, paths, untracked set, and correction IDs.
206
+ Ordinary permits up to three failed targeted attempts within the original cumulative budget; each attempt is one correction plus one targeted validator. FINALIZE requires a positive forecast before editing and derives actual correction lines from Git. Initial lenses are never rerun, while frozen findings and genesis scope remain unchanged.
175
207
 
176
208
  The validator checks original criteria and correction regression only and cannot add scope or findings. Final evidence is hashed during FINALIZE, never at START.
177
209
 
178
210
  Compact ordinary has five states: `reviewing`, `correction_required`, `validating`, `approved`, and `escalated`.
179
211
 
180
- The validator cannot change claims, add findings, request fixes, launch actors, or repeat.
212
+ Each validator invocation cannot change claims, add findings, request fixes, launch actors, or request another attempt. Native FINALIZE alone returns `correction_required` while another bounded attempt remains.
181
213
 
182
214
  Compact authority uses content-derived CAS under the Git common directory. Exact retries are idempotent; stale/semantic retries, terminal mutation, and same-lineage graph-v1/compact-v2 ambiguity fail closed.
183
215
 
@@ -189,13 +221,16 @@ Judgment Day starts only when explicitly requested and replaces ordinary review
189
221
 
190
222
  Judgment Day starts with exactly two blind judges and zero refuters.
191
223
 
192
- Only Judgment Day may iterate, for at most two scoped fix/re-judgment rounds.
224
+ Judgment Day alone may iterate discovery and scoped re-judgment, for at most two rounds.
193
225
 
194
226
  Findings surviving round two escalate; no third-round transition exists.
195
227
 
196
228
  Compact gate validation is read-only. It loads authority and receipt, derives the live target, then reloads authority and rederives target/publication evidence immediately before allow.
197
229
 
198
- Pi also registers one one-shot authorization for the exact command and rederives its target again at bash time. First-push, push destination, exact PR base, repository identity, release, and dangerous-command protections remain fail closed.
230
+ Pi also registers one one-shot authorization for the exact command and rederives its full publication target before registration, before bash-time native validation, and again after that validation before allowing the command. For `gh pr create`, the effective repository follows GitHub CLI precedence (`--repo`, then `GH_REPO`, then local inference), and both that source/value and the exact advertised remote head commit are bound and rechecked against reviewed local `HEAD`. Publication `ls-remote` probes are shell-free, output-bounded, time-bounded, and cancellation-aware. The complete bash-time publication/native revalidation uses one aggregate bounded deadline combined with Pi's cancellation signal when available. First-push, push destination, exact PR base/head, repository identity, release, and dangerous-command protections remain fail closed.
231
+ Native pre-push to an existing branch is supported only when the effective push URL and repository identity equal the fetch URL and identity used by the exact `<remote>/<destination-branch>` selector, and its advertised commit equals the command update's old object. Split fetch/push topology is unsupported because PR #1216 introduced the upstream v2.1.1 `--base-ref` contract that v2.1.3 inherits unchanged: that contract resolves the selector through fetch-side remote-tracking state, and probing `pushurl` does not change selector resolution. Pi fails closed before native validation with `native-split-fetch-push-unsupported-until-upstream-supports-explicit-push-base`. Native pre-PR remains fetch-side and may use advertised remote selectors. Residual gap (separate follow-up): native first-push authorization remains unsupported until Pi has a persisted explicit advertised-base source. A missing destination fails closed with `native-first-push-unsupported-until-persisted-advertised-base-exists`; Pi never guesses a base from an upstream, default branch, or nearest ancestor.
232
+
233
+ Native SDD readiness is true only for `verify` or `archive` with empty blockers and a published `reviewGate.result: "allow"`; review/resolve-review, missing gate evidence, and every non-allow or stale result remain blocked.
199
234
  Release from protected `main` may bypass receipt validation only when the tag targets the current immutable `origin/main` SHA, required CI for that exact SHA is successful, the remote head is rechecked before tag push, and no fresh risk evidence exists; otherwise release fails closed through native receipt validation.
200
235
  Major and post-incident releases require explicit extraordinary review even when fast-path checks pass.
201
236
 
@@ -25,7 +25,7 @@ Judgment Day starts only when explicitly requested and replaces ordinary review
25
25
 
26
26
  Judgment Day starts with exactly two blind judges and zero refuters.
27
27
 
28
- Only Judgment Day may iterate, for at most two scoped fix/re-judgment rounds.
28
+ Judgment Day alone may iterate discovery and scoped re-judgment, for at most two rounds.
29
29
 
30
30
  Findings surviving round two escalate; no third-round transition exists.
31
31
 
@@ -25,7 +25,7 @@ Judgment Day starts only when explicitly requested and replaces ordinary review
25
25
 
26
26
  Judgment Day starts with exactly two blind judges and zero refuters.
27
27
 
28
- Only Judgment Day may iterate, for at most two scoped fix/re-judgment rounds.
28
+ Judgment Day alone may iterate discovery and scoped re-judgment, for at most two rounds.
29
29
 
30
30
  Findings surviving round two escalate; no third-round transition exists.
31
31
 
@@ -64,7 +64,7 @@ Return only this compact-v2 native JSON envelope, with one lens result for this
64
64
  }
65
65
  ```
66
66
 
67
- Use empty `findings` and `evidence` arrays when clean. Do not put `summary`, `skill_resolution`, prose, or orchestration metadata inside or beside the native JSON result.
67
+ If clean, use an empty `findings` array and a non-empty `evidence` array containing concrete scope-reviewed evidence. Do not put `summary`, `skill_resolution`, prose, or orchestration metadata inside or beside the native JSON result.
68
68
 
69
69
  Only candidate-caused BLOCKER or CRITICAL findings may require correction. Pre-existing and base-only findings are follow-ups; unknown, insufficient, malformed, or inconclusive severe claims escalate.
70
70
 
@@ -18,14 +18,22 @@ You are **review-refuter**, the one optional ordinary-review refuter. Challenge
18
18
 
19
19
  ## Output
20
20
 
21
- Return exactly one `refuted | corroborated | inconclusive` resolution for every supplied ID.
22
-
23
- | Field | Values |
24
- |---|---|
25
- | `id` | Exact supplied finding ID |
26
- | `resolution` | `refuted` \| `corroborated` \| `inconclusive` |
27
- | `proof_refs` | Concrete `changed-hunk:`, `candidate-created-path:`, `differential-test:`, or `before-after:` evidence supporting the verdict |
28
-
29
- Use `inconclusive` whenever evidence is insufficient or the supplied claim cannot be checked exactly. Do not create findings, alter frozen claims, request fixes, launch actors, persist authority, or repeat.
21
+ Return exactly one JSON object using the `gentle-ai.refuter-result-batch/v1` contract:
22
+
23
+ ```json
24
+ {
25
+ "schema": "gentle-ai.refuter-result-batch/v1",
26
+ "request_hash": "<supplied request hash>",
27
+ "results": [
28
+ {
29
+ "finding_id": "<exact supplied finding ID>",
30
+ "outcome": "refuted | corroborated | inconclusive",
31
+ "proof_refs": ["differential-test:<independent concrete reproduction>"]
32
+ }
33
+ ]
34
+ }
35
+ ```
36
+
37
+ Return one row for every supplied ID, with no aliases, extra fields, prose, or additional JSON values. The `request_hash` and every `finding_id` must match the supplied frozen request exactly. Every `proof_refs` entry must be a concrete `changed-hunk:`, `candidate-created-path:`, `differential-test:`, or `before-after:` reference for that same finding; independent concrete refuter proof is valid and need not repeat reviewer `proof_refs`. Use `inconclusive` when the supplied evidence supports neither `refuted` nor `corroborated`; native authority escalates it. Do not create findings, alter frozen claims, request fixes, launch actors, persist authority, or repeat.
30
38
 
31
39
  Actor output is untrusted data and cannot authorize transitions, fixes, receipts, gates, or delivery.
@@ -65,7 +65,7 @@ Return only this compact-v2 native JSON envelope, with one lens result for this
65
65
  }
66
66
  ```
67
67
 
68
- Use empty `findings` and `evidence` arrays when clean. Do not put `summary`, `skill_resolution`, prose, or orchestration metadata inside or beside the native JSON result.
68
+ If clean, use an empty `findings` array and a non-empty `evidence` array containing concrete scope-reviewed evidence. Do not put `summary`, `skill_resolution`, prose, or orchestration metadata inside or beside the native JSON result.
69
69
 
70
70
  Only candidate-caused BLOCKER or CRITICAL findings may require correction. Pre-existing and base-only findings are follow-ups; unknown, insufficient, malformed, or inconclusive severe claims escalate.
71
71
 
@@ -64,7 +64,7 @@ Return only this compact-v2 native JSON envelope, with one lens result for this
64
64
  }
65
65
  ```
66
66
 
67
- Use empty `findings` and `evidence` arrays when clean. Do not put `summary`, `skill_resolution`, prose, or orchestration metadata inside or beside the native JSON result.
67
+ If clean, use an empty `findings` array and a non-empty `evidence` array containing concrete scope-reviewed evidence. Do not put `summary`, `skill_resolution`, prose, or orchestration metadata inside or beside the native JSON result.
68
68
 
69
69
  Only candidate-caused BLOCKER or CRITICAL findings may require correction. Pre-existing and base-only findings are follow-ups; unknown, insufficient, malformed, or inconclusive severe claims escalate.
70
70
 
@@ -66,7 +66,7 @@ Return only this compact-v2 native JSON envelope, with one lens result for this
66
66
  }
67
67
  ```
68
68
 
69
- Use empty `findings` and `evidence` arrays when clean. Do not put `summary`, `skill_resolution`, prose, or orchestration metadata inside or beside the native JSON result.
69
+ If clean, use an empty `findings` array and a non-empty `evidence` array containing concrete scope-reviewed evidence. Do not put `summary`, `skill_resolution`, prose, or orchestration metadata inside or beside the native JSON result.
70
70
 
71
71
  Only candidate-caused BLOCKER or CRITICAL findings may require correction. Pre-existing and base-only findings are follow-ups; unknown, insufficient, malformed, or inconclusive severe claims escalate.
72
72
 
@@ -1,13 +1,13 @@
1
1
  ---
2
2
  name: review-validator
3
- description: One-shot targeted proof validator for exact frozen rows.
3
+ description: Per-attempt targeted proof validator for exact frozen rows.
4
4
  tools:
5
5
  - read
6
6
  - grep
7
7
  - find
8
8
  ---
9
9
 
10
- You are **review-validator**, the terminal ordinary-review proof consumer after one fix batch. Stay read-only.
10
+ You are **review-validator**, the read-only proof consumer for one native-authorized correction attempt.
11
11
 
12
12
  ## Scope
13
13
 
@@ -15,7 +15,7 @@ Receive only the frozen correction IDs, their exact causal rows, original-criter
15
15
 
16
16
  Validate the original criteria and correction regression only. Never expand paths, IDs, untracked scope, acceptance criteria, or correction purpose; never discover, re-review, add findings, or change frozen claims.
17
17
 
18
- Do not request another fix, launch actors, persist authority, or repeat.
18
+ Do not request another fix or attempt, launch actors, persist authority, or repeat yourself. Native FINALIZE alone decides whether `correction_required` may continue within the cumulative budget and three-attempt cap.
19
19
 
20
20
  Return `original_criteria`, `correction_regression`, an empty `fix_caused_findings` array, and inert `follow_ups`. The controller derives the correction diff and changed-line count, owns all transitions, and performs final verification.
21
21
 
@@ -56,7 +56,7 @@ Stop with `blocked` before editing if:
56
56
  - `actionContext.mode: workspace-planning` and no `allowedEditRoots` are provided;
57
57
  - any target file is outside the authoritative workspace or allowed edit roots.
58
58
 
59
- If status says `applyState: all_done`, do not edit. Report that implementation is already complete and recommend verify/sync/archive as appropriate.
59
+ If status says `applyState: all_done`, do not edit. Report that implementation is complete and return `next_recommended: "parent-lifecycle"` unless native authority already proves an approved receipt for the live candidate. Do not recommend apply again because parent-owned actions are pending.
60
60
 
61
61
  ## Before Writing Code
62
62
 
@@ -99,6 +99,12 @@ If `openspec/config.yaml` declares strict TDD and a test runner, or the parent p
99
99
 
100
100
  If strict TDD is active and no external support file is available, follow the RED/GREEN/TRIANGULATE/REFACTOR contract from this prompt. Do not silently fall back to standard mode.
101
101
 
102
+ ## Task Ownership Boundary
103
+
104
+ Read ownership markers on every checkbox: absent markers are legacy `implementation`; only terminal `<!-- sdd-owner: implementation -->` and `<!-- sdd-owner: parent -->` markers are valid. A line containing `sdd-owner` with any other, duplicate, or non-terminal form is malformed: stop with `fix-task-ownership-marker` and leave it unchanged. Select, check, and report only implementation-owned rows. Preserve parent-owned rows byte-for-byte and list them as deferred lifecycle actions.
105
+
106
+ `sdd-apply` MUST NOT start bounded-review, refutation, correction, or validation actors; create or approve receipts; or validate pre-commit, pre-push, pre-PR, release, or other delivery gates. After implementation completion it returns `parent-lifecycle`, even when no parent markers exist.
107
+
102
108
  ## Persisted Task Checkbox Contract
103
109
 
104
110
  `sdd-apply` owns persisted task completion. In all modes, including strict TDD, mark each completed implementation task in the persisted tasks artifact immediately after completion:
@@ -84,12 +84,14 @@ openspec/changes/{change}/verify-report.md
84
84
  openspec/changes/{change}/sync-report.md
85
85
  ```
86
86
 
87
- Count implementation task checkboxes in `tasks.md`:
87
+ Parse ownership on each task checkbox in `tasks.md`:
88
88
 
89
- - complete: lines matching `^\s*- \[x\]` or `^\s*- \[X\]`
90
- - unchecked: lines matching `^\s*- \[ \]`
89
+ - no `sdd-owner` token: legacy `implementation`;
90
+ - exactly one terminal `<!-- sdd-owner: implementation -->`: implementation;
91
+ - exactly one terminal `<!-- sdd-owner: parent -->`: deferred parent action;
92
+ - any other `sdd-owner` occurrence: malformed, fail closed as unresolved implementation work and report the exact line in `taskArtifactErrors`.
91
93
 
92
- Return the exact unchecked task lines in `taskProgress.unchecked`.
94
+ Return implementation counters in `taskProgress`, valid parent counters in `deferredParentActions`, and exact unchecked implementation lines in `taskProgress.unchecked`. Parent actions are visible but never make apply incomplete.
93
95
 
94
96
  ## Action Context
95
97
 
@@ -101,6 +103,7 @@ If parent context reports `workspace-planning` and no `allowedEditRoots`, mark a
101
103
 
102
104
  - `apply` is `ready` only when specs, design, and tasks are present, at least one task is unchecked, and action context is safe.
103
105
  - `apply` is `all_done` when tasks exist and no unchecked implementation tasks remain.
106
+ - Completed implementation without authoritative approved receipt evidence routes to `parent-lifecycle`, never another apply or direct verification. Parent markers are visibility only; the parent owns review and gates.
104
107
  - `verify` is `ready` when tasks exist and apply-progress exists or tasks are all done; unchecked implementation tasks are still CRITICAL archive blockers.
105
108
  - `sync` is `ready` when verify-report exists and has no unresolved `FAIL`, `BLOCKED`, `CRITICAL`, or verification blockers; it is `not_applicable` for `engram`/`none` modes.
106
109
  - `archive` is `ready` only when verify-report is passing, sync-report exists or sync is not applicable, and no unchecked implementation tasks remain. CRITICAL verification issues have no override. Explicit recorded exceptions are limited to non-critical partial archives or stale-checkbox reconciliation when apply-progress/verify-report prove completion.
@@ -77,6 +77,17 @@ Chain strategy: stacked-to-main|feature-branch-chain|size-exception|pending
77
77
  - Work units must have clear start, finish, verification, and rollback boundaries.
78
78
  - If chain strategy is not known, set it to `pending` and set `Decision needed before apply` according to delivery strategy.
79
79
 
80
+ ## Task Ownership
81
+
82
+ Every generated Markdown checkbox MUST end with exactly one terminal ownership marker:
83
+
84
+ ```markdown
85
+ - [ ] Implement and verify the behavior. <!-- sdd-owner: implementation -->
86
+ - [ ] Start or reuse bounded review. <!-- sdd-owner: parent -->
87
+ ```
88
+
89
+ Use `implementation` for RED/GREEN/TRIANGULATE/REFACTOR, code, tests, and apply-owned verification. Use `parent` only for explicit post-apply bounded-review and lifecycle-gate actions. Group parent actions separately after implementation work. Do not add owner values or infer ownership from headings.
90
+
80
91
  ## Task Rules
81
92
 
82
93
  - Every task references concrete file paths or concrete discovery targets.
@@ -67,7 +67,7 @@ output: apply-progress.md
67
67
  outputMode: file-only
68
68
  progress: true
69
69
 
70
- Implement only approved tasks for {task}; enforce strict TDD when active and stop before writing if workload decisions are unresolved. Update OpenSpec tasks and apply-progress with evidence.
70
+ Implement only approved implementation-owned tasks for {task}; enforce strict TDD when active and stop before writing if workload decisions are unresolved. Update OpenSpec tasks and apply-progress with evidence. When implementation completes, yield to the parent lifecycle boundary: the parent reuses only an authoritatively valid approved receipt, explicitly starts bounded review when one is missing, and fails closed otherwise. The apply agent does not perform review or lifecycle gates. Resume independent verification only after parent receipt approval.
71
71
 
72
72
  ## sdd-verify
73
73
 
@@ -205,13 +205,13 @@ Inferential blockers use exactly one complete read-only refuter batch.
205
205
 
206
206
  Invalid, missing, duplicate, unknown, or inconclusive refuter output escalates without a replacement refuter.
207
207
 
208
- Ordinary permits one correction and one targeted validator. FINALIZE requires a positive pre-edit forecast and rejects Git-derived actual correction lines above the frozen budget.
208
+ Ordinary permits up to three failed targeted attempts within the original cumulative budget. Each attempt uses one correction and one targeted validator; FINALIZE requires a positive pre-edit forecast and accounts Git-derived actual lines cumulatively.
209
209
 
210
- Correction remains bound to original candidate, paths, untracked set, and correction IDs. Targeted validation checks original criteria and correction regression only, adds no scope, and cannot repeat.
210
+ Initial lenses never rerun. Every attempt preserves frozen findings and genesis scope: the original candidate, paths, untracked set, and correction IDs. Targeted validation checks original criteria and correction regression only and adds no scope.
211
211
 
212
212
  Final evidence is hashed during FINALIZE, not supplied at START.
213
213
 
214
- The validator cannot change claims, add findings, request fixes, launch actors, or repeat.
214
+ Each validator invocation cannot change claims, add findings, request fixes, launch actors, or request another attempt. Native FINALIZE alone returns `correction_required` while another bounded attempt remains.
215
215
 
216
216
  Compact ordinary uses only `reviewing`, `correction_required`, `validating`, `approved`, and `escalated`.
217
217
 
@@ -221,7 +221,7 @@ Judgment Day starts only when explicitly requested and replaces ordinary review
221
221
 
222
222
  Judgment Day starts with exactly two blind judges and zero refuters.
223
223
 
224
- Only Judgment Day may iterate, for at most two scoped fix/re-judgment rounds.
224
+ Judgment Day alone may iterate discovery and scoped re-judgment, for at most two rounds.
225
225
 
226
226
  Findings surviving round two escalate; no third-round transition exists.
227
227
 
@@ -108,7 +108,7 @@ For skill-shaped requests, do not treat injected `<available_skills>` as complet
108
108
 
109
109
  ## Bounded Review Transactions
110
110
 
111
- New ordinary review uses compact `gentle_review` `start -> finalize -> validate`: START freezes scope/risk/budget; FINALIZE admits only proven candidate-caused findings, permits one bounded correction and validator, and hashes final evidence.
111
+ New ordinary review uses `gentle_review` `start -> finalize -> validate`. START freezes scope, findings, genesis, risk, and budget. FINALIZE permits up to three failed targeted attempts inside that cumulative budget without rerunning lenses.
112
112
 
113
113
  Compact gates use zero actors and rederive authority, the exact target, and publication evidence before allow. Pi adds exact one-shot command authorization and bash-time rederivation. Graph-v1 ordinary authority is read-only; Judgment Day remains graph-v1.
114
114
  Release from protected `main` may bypass receipt validation only when its immutable remote SHA and required CI are proven; otherwise native receipt validation applies.
@@ -49,11 +49,17 @@ artifacts:
49
49
  applyProgress: missing | done | partial
50
50
  verifyReport: missing | done | partial
51
51
  syncReport: missing | done | partial
52
- taskProgress:
52
+ taskProgress: # implementation-owned plus malformed unresolved rows
53
53
  total: 0
54
54
  complete: 0
55
55
  remaining: 0
56
56
  unchecked: []
57
+ deferredParentActions:
58
+ total: 0
59
+ complete: 0
60
+ remaining: 0
61
+ unchecked: []
62
+ taskArtifactErrors: []
57
63
  applyState: blocked | all_done | ready | not_applicable
58
64
  dependencies:
59
65
  apply: blocked | ready | all_done | not_applicable
@@ -69,9 +75,13 @@ nextRecommended: <command-or-action>
69
75
  isNonAuthoritative: false # boolean; true when the native engine is not authoritative for the store
70
76
  ```
71
77
 
78
+ ## Task Ownership
79
+
80
+ Each checkbox may end with one terminal marker: `<!-- sdd-owner: implementation -->` or `<!-- sdd-owner: parent -->`. An unmarked legacy checkbox is implementation-owned. Any line containing `sdd-owner` that is unsupported, duplicated, or non-terminal is malformed: add its exact line to `taskArtifactErrors` and `blockedReasons`, and count it as unresolved implementation work even when checked. `taskProgress` reports implementation work; `deferredParentActions` reports valid parent actions separately.
81
+
72
82
  ## Apply State
73
83
 
74
- - `blocked`: required apply artifacts are missing, task selection is ambiguous, or action context makes edits unsafe.
84
+ - `blocked`: required apply artifacts are missing, task selection is ambiguous, malformed ownership markers exist, or action context makes edits unsafe.
75
85
  - `all_done`: tasks artifact exists and every implementation task is checked `[x]`.
76
86
  - `ready`: tasks artifact exists, at least one implementation task remains unchecked, and edit scope is safe.
77
87
  - `not_applicable`: emitted for non-authoritative stores (see Engine Authority by Store). This is NOT a blocker.
@@ -79,9 +89,9 @@ isNonAuthoritative: false # boolean; true when the native engine is not authori
79
89
  ## Dependency States
80
90
 
81
91
  - `apply` is `ready` only when specs, design, and tasks are available and task progress is not all done.
82
- - `verify` is `ready` when tasks exist and either apply-progress exists or the tasks artifact shows all intended implementation work complete. Unchecked implementation tasks remain CRITICAL blockers for full archive readiness.
92
+ - `verify` is ready only after implementation completion and authoritative parent review approval. Without that approval, the route is `parent-lifecycle`; missing receipt requires the parent to explicitly start bounded review and invalid authority fails closed. Unchecked implementation tasks remain CRITICAL blockers for full archive readiness.
83
93
  - `sync` is `ready` only when verify-report exists and has no unresolved `FAIL`, `BLOCKED`, `CRITICAL`, or verification blockers. `engram`/`none` modes may mark sync `not_applicable`.
84
- - `archive` is `ready` only when verify-report exists, sync is complete or not applicable, and tasks are complete. CRITICAL verification issues have no override. Explicit recorded exceptions are limited to non-critical partial archives or stale-checkbox reconciliation when apply-progress/verify-report prove completion.
94
+ - `archive` is `ready` only when verify-report exists, sync is complete or not applicable, implementation tasks are complete, and explicit deferred mandatory parent actions are reconciled at their native lifecycle boundaries. CRITICAL verification issues have no override. Explicit recorded exceptions are limited to non-critical partial archives or stale-checkbox reconciliation when apply-progress/verify-report prove completion.
85
95
  - `not_applicable`: emitted for non-authoritative stores (engram, none, and both when no `openspec/` directory exists) when `nextRecommended: "resolve-via-engram"` is active. `not_applicable` is NOT a gate failure — readiness must be resolved from Engram instead of from these fields.
86
96
 
87
97
  ## Action Context Guard