@aperant/framework 0.11.0 → 0.12.0

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 (147) hide show
  1. package/CHANGELOG.md +213 -30
  2. package/agents/apt-planner.md +15 -0
  3. package/agents/apt-verifier.md +15 -10
  4. package/bin/apt-proof-video.mjs +256 -76
  5. package/dist/cli/commands/apply-recipe.d.mts +6 -0
  6. package/dist/cli/commands/apply-recipe.d.mts.map +1 -0
  7. package/dist/cli/commands/apply-recipe.mjs +98 -0
  8. package/dist/cli/commands/apply-recipe.mjs.map +1 -0
  9. package/dist/cli/commands/mobile-prepare.d.mts +53 -0
  10. package/dist/cli/commands/mobile-prepare.d.mts.map +1 -0
  11. package/dist/cli/commands/mobile-prepare.mjs +139 -0
  12. package/dist/cli/commands/mobile-prepare.mjs.map +1 -0
  13. package/dist/cli/commands/recipe-diff.d.mts +6 -0
  14. package/dist/cli/commands/recipe-diff.d.mts.map +1 -0
  15. package/dist/cli/commands/recipe-diff.mjs +75 -0
  16. package/dist/cli/commands/recipe-diff.mjs.map +1 -0
  17. package/dist/cli/commands/roadmap.d.mts.map +1 -1
  18. package/dist/cli/commands/roadmap.mjs +53 -0
  19. package/dist/cli/commands/roadmap.mjs.map +1 -1
  20. package/dist/cli/commands/validate-evidence.d.mts +1 -1
  21. package/dist/cli/commands/verify-sandbox.d.mts +6 -0
  22. package/dist/cli/commands/verify-sandbox.d.mts.map +1 -0
  23. package/dist/cli/commands/verify-sandbox.mjs +200 -0
  24. package/dist/cli/commands/verify-sandbox.mjs.map +1 -0
  25. package/dist/cli/consistency/parse-qa.d.mts.map +1 -1
  26. package/dist/cli/consistency/parse-qa.mjs +18 -4
  27. package/dist/cli/consistency/parse-qa.mjs.map +1 -1
  28. package/dist/cli/consistency/rules/r5-verdict-consistency.d.mts.map +1 -1
  29. package/dist/cli/consistency/rules/r5-verdict-consistency.mjs +11 -10
  30. package/dist/cli/consistency/rules/r5-verdict-consistency.mjs.map +1 -1
  31. package/dist/cli/coverage-check/user-outcomes.d.mts +7 -2
  32. package/dist/cli/coverage-check/user-outcomes.d.mts.map +1 -1
  33. package/dist/cli/coverage-check/user-outcomes.mjs +50 -17
  34. package/dist/cli/coverage-check/user-outcomes.mjs.map +1 -1
  35. package/dist/cli/design/frontmatter-schema.d.mts +8 -8
  36. package/dist/cli/dispatch.d.mts.map +1 -1
  37. package/dist/cli/dispatch.mjs +28 -0
  38. package/dist/cli/dispatch.mjs.map +1 -1
  39. package/dist/cli/gate/gates/verify-approved.d.mts +0 -48
  40. package/dist/cli/gate/gates/verify-approved.d.mts.map +1 -1
  41. package/dist/cli/gate/gates/verify-approved.mjs +23 -80
  42. package/dist/cli/gate/gates/verify-approved.mjs.map +1 -1
  43. package/dist/cli/install/mcp-server-specs.d.mts +6 -5
  44. package/dist/cli/install/mcp-server-specs.d.mts.map +1 -1
  45. package/dist/cli/install/mcp-server-specs.mjs +22 -4
  46. package/dist/cli/install/mcp-server-specs.mjs.map +1 -1
  47. package/dist/cli/personas/sidecar.d.mts +1 -1
  48. package/dist/cli/roadmap/backend-adapter.d.mts +43 -0
  49. package/dist/cli/roadmap/backend-adapter.d.mts.map +1 -0
  50. package/dist/cli/roadmap/backend-adapter.mjs +222 -0
  51. package/dist/cli/roadmap/backend-adapter.mjs.map +1 -0
  52. package/dist/cli/roadmap/lifecycle.d.mts +1 -1
  53. package/dist/cli/roadmap/rollup.d.mts +2 -2
  54. package/dist/cli/util/runtime-capabilities.d.mts +7 -0
  55. package/dist/cli/util/runtime-capabilities.d.mts.map +1 -1
  56. package/dist/cli/util/runtime-capabilities.mjs +65 -0
  57. package/dist/cli/util/runtime-capabilities.mjs.map +1 -1
  58. package/dist/cli/verify-proof/manifest-validator.mjs +13 -0
  59. package/dist/cli/verify-proof/manifest-validator.mjs.map +1 -1
  60. package/dist/cli/verify-proof/resolver.d.mts +10 -7
  61. package/dist/cli/verify-proof/resolver.d.mts.map +1 -1
  62. package/dist/cli/verify-proof/resolver.mjs +28 -7
  63. package/dist/cli/verify-proof/resolver.mjs.map +1 -1
  64. package/dist/cli/verify-proof/sandbox/apply.d.mts +64 -0
  65. package/dist/cli/verify-proof/sandbox/apply.d.mts.map +1 -0
  66. package/dist/cli/verify-proof/sandbox/apply.mjs +379 -0
  67. package/dist/cli/verify-proof/sandbox/apply.mjs.map +1 -0
  68. package/dist/cli/verify-proof/sandbox/gate-predicate.d.mts +63 -0
  69. package/dist/cli/verify-proof/sandbox/gate-predicate.d.mts.map +1 -0
  70. package/dist/cli/verify-proof/sandbox/gate-predicate.mjs +115 -0
  71. package/dist/cli/verify-proof/sandbox/gate-predicate.mjs.map +1 -0
  72. package/dist/cli/verify-proof/sandbox/pattern-matcher.d.mts +57 -0
  73. package/dist/cli/verify-proof/sandbox/pattern-matcher.d.mts.map +1 -0
  74. package/dist/cli/verify-proof/sandbox/pattern-matcher.mjs +124 -0
  75. package/dist/cli/verify-proof/sandbox/pattern-matcher.mjs.map +1 -0
  76. package/dist/cli/verify-proof/sandbox/recipe-diff.d.mts +28 -0
  77. package/dist/cli/verify-proof/sandbox/recipe-diff.d.mts.map +1 -0
  78. package/dist/cli/verify-proof/sandbox/recipe-diff.mjs +190 -0
  79. package/dist/cli/verify-proof/sandbox/recipe-diff.mjs.map +1 -0
  80. package/dist/cli/verify-proof/sandbox/sandbox-config.d.mts +25 -0
  81. package/dist/cli/verify-proof/sandbox/sandbox-config.d.mts.map +1 -0
  82. package/dist/cli/verify-proof/sandbox/sandbox-config.mjs +85 -0
  83. package/dist/cli/verify-proof/sandbox/sandbox-config.mjs.map +1 -0
  84. package/dist/cli/verify-proof/sandbox/self-test.d.mts +39 -0
  85. package/dist/cli/verify-proof/sandbox/self-test.d.mts.map +1 -0
  86. package/dist/cli/verify-proof/sandbox/self-test.mjs +248 -0
  87. package/dist/cli/verify-proof/sandbox/self-test.mjs.map +1 -0
  88. package/dist/plugin/.claude-plugin/plugin.json +1 -1
  89. package/dist/plugin/agents/apt-planner.md +15 -0
  90. package/dist/plugin/agents/apt-verifier.md +15 -10
  91. package/dist/plugin/skills/apt-plan/SKILL.md +23 -0
  92. package/dist/plugin/skills/apt-run/SKILL.md +1 -1
  93. package/dist/plugin/skills/apt-setup/SKILL.md +56 -0
  94. package/dist/plugin/skills/apt-verify/SKILL.md +20 -15
  95. package/dist/plugin/skills/apt-verify-proof/SKILL.md +146 -11
  96. package/dist/proof-report.d.ts.map +1 -1
  97. package/dist/proof-report.js +4 -1
  98. package/dist/proof-report.js.map +1 -1
  99. package/dist/types/config.d.ts +42 -4
  100. package/dist/types/config.d.ts.map +1 -1
  101. package/dist/types/qa-scoring.d.ts +45 -9
  102. package/dist/types/qa-scoring.d.ts.map +1 -1
  103. package/dist/types/qa-scoring.js +34 -13
  104. package/dist/types/qa-scoring.js.map +1 -1
  105. package/dist/types/state.d.ts +7 -2
  106. package/dist/types/state.d.ts.map +1 -1
  107. package/dist/types/task-record.d.ts +10 -2
  108. package/dist/types/task-record.d.ts.map +1 -1
  109. package/drivers/mobile/README.md +40 -0
  110. package/drivers/mobile/driver.mjs +106 -0
  111. package/drivers/mobile/manifest.json +49 -0
  112. package/package.json +138 -138
  113. package/prompts/inbox-clarification.md +11 -0
  114. package/prompts/inbox-triage.md +20 -0
  115. package/prompts/qa_orchestrator_agentic.md +18 -17
  116. package/prompts/qa_reviewer.md +17 -15
  117. package/skills/apt-plan/SKILL.md +23 -0
  118. package/skills/apt-run/SKILL.md +1 -1
  119. package/skills/apt-setup/SKILL.md +56 -0
  120. package/skills/apt-verifier.md +7 -4
  121. package/skills/apt-verify/SKILL.md +20 -15
  122. package/skills/apt-verify-proof/SKILL.md +146 -11
  123. package/src/cli/commands/apply-recipe.mjs +105 -0
  124. package/src/cli/commands/mobile-prepare.mjs +151 -0
  125. package/src/cli/commands/recipe-diff.mjs +81 -0
  126. package/src/cli/commands/roadmap.mjs +54 -0
  127. package/src/cli/commands/verify-sandbox.mjs +231 -0
  128. package/src/cli/consistency/parse-qa.mjs +20 -4
  129. package/src/cli/consistency/rules/r5-verdict-consistency.mjs +11 -13
  130. package/src/cli/coverage-check/user-outcomes.mjs +52 -17
  131. package/src/cli/dispatch.mjs +27 -0
  132. package/src/cli/gate/gates/verify-approved.mjs +22 -81
  133. package/src/cli/install/mcp-server-specs.mjs +24 -4
  134. package/src/cli/roadmap/backend-adapter.mjs +231 -0
  135. package/src/cli/util/runtime-capabilities.mjs +67 -0
  136. package/src/cli/verify-proof/manifest-validator.mjs +15 -0
  137. package/src/cli/verify-proof/resolver.mjs +27 -7
  138. package/src/cli/verify-proof/sandbox/apply.mjs +401 -0
  139. package/src/cli/verify-proof/sandbox/gate-predicate.mjs +126 -0
  140. package/src/cli/verify-proof/sandbox/pattern-matcher.mjs +127 -0
  141. package/src/cli/verify-proof/sandbox/recipe-diff.mjs +208 -0
  142. package/src/cli/verify-proof/sandbox/sandbox-config.mjs +82 -0
  143. package/src/cli/verify-proof/sandbox/sandbox-schema.json +33 -0
  144. package/src/cli/verify-proof/sandbox/self-test.mjs +265 -0
  145. package/templates/config.json +10 -1
  146. package/templates/proof-verification.md +27 -8
  147. package/workflows/verify-proof.md +376 -302
package/CHANGELOG.md CHANGED
@@ -3,39 +3,222 @@
3
3
  All notable changes to `@aperant/framework` are documented here. See
4
4
  [`VERSIONING.md`](VERSIONING.md) for the per-tier contract.
5
5
 
6
- ## Unreleased
6
+ ## 0.12.0 — 2026-05-31 — Mobile verification surface for verify-proof (iOS + Android)
7
7
 
8
- ## 0.11.0 2026-05-26 Collaboration catch-up
9
-
10
- Adds a collaboration catch-up panel that greets you with your own
11
- half-finished work and what teammates merged since you were last here, so
12
- returning to a shared repo no longer means re-deriving state by hand.
8
+ Adds a mobile verification surface so `/apt:verify-proof` can drive native
9
+ iOS + Android apps. One unified `mobile-mcp` driver covers both platforms
10
+ (platform = device choice inside the driver); the original two-server RFC
11
+ design was reversed via `apt:discuss` + a 3-round `apt:spar` (decisions
12
+ D-01…D-09).
13
13
 
14
14
  ### Added
15
15
 
16
- - **Collaboration catch-uproute envelope `catch_up` field + `apt-catch-up`
17
- skill.** On every interactive (TTY) `/apt` call the router folds a top-level
18
- `catch_up` field onto the route envelope (alongside `update_check`), and
19
- `apt/SKILL.md` renders it before the mode handler runtime-agnostic, no
20
- Claude-only hook. It carries two panels: the always-on **Welcome-Back
21
- Summary** (your own half-finished work) and the gated **Team-Change Digest**
22
- (teammates' PRs merged since your last pull, attributed by introduced commit;
23
- team/oss visibility only). Merged-PR attribution is parsed from local git
24
- history with no network call (default-branch ref resolved locally). The new
25
- read-only `/apt:catch-up` skill re-views the same panel on demand **without
26
- advancing the marker**. Non-TTY / background / spawned calls carry no
27
- `catch_up` and never touch the marker. State lives in a per-machine,
28
- gitignored Last-Seen Marker (`.aperant/last-seen/{email-slug}.json`) persisted
29
- via the `CoordinationStore` seam.
30
- - **`/apt:setup` collaboration config block.** New `config.json.collaboration`
31
- keys (`welcome_back.{enabled,threshold_hours}`,
32
- `team_digest.{enabled,max_entries}`) surfaced through a `/apt:setup` mini-flow
33
- (Batch 10).
34
-
35
- > **Re-install required (R5):** the new `apt-catch-up` skill and the `catch_up`
36
- > envelope field require adopters to re-run
37
- > `apt-tools init . --<runtime> --team|--solo` (or `/apt:update`) so each
38
- > per-runtime manifest picks up the new skill.
16
+ - **`mobile` driver** (`packages/framework/drivers/mobile/`)unified iOS +
17
+ Android UI driver wrapping `mobile-mcp` (`{ mcp_server_id: "mobile-mcp" }`,
18
+ targets `ios`/`android`/`expo`/`react-native`). `preflight[]` validates
19
+ `xcrun`/`adb` so `apt-tools driver doctor` surfaces missing system prereqs.
20
+ - **`mobile` User-Outcomes surface** a `[mobile]` outcome tag resolves to the
21
+ mobile driver (new `ios`/`android` `matchesRuntime` cases + an `is_mobile`
22
+ surface mask in the resolver).
23
+ - **`apt-tools mobile prepare`** resolves the app launch sequence
24
+ (`expo run:*` / `xcrun simctl` / `adb`) plus the launch-readiness gate
25
+ (foregrounded + JS-bundle-connected + no redbox) that the verify-proof
26
+ workflow runner executes before driving UI.
27
+ - **Native project detection** `is_ios_native` / `is_android_native`
28
+ (`*.xcodeproj` / `build.gradle` fs-walk in `loadRuntimeCapabilities`;
29
+ `detectFromPackageJson` stays pure). Reuses existing `is_expo` /
30
+ `is_react_native`.
31
+ - **`mobile-mcp` auto-provisioning** — `npx -y @mobilenext/mobile-mcp@latest`
32
+ is provisioned when a mobile project is detected. System prereqs
33
+ (idb / adb / Xcode / Android SDK) are validated, never auto-installed.
34
+
35
+ ### Scope
36
+
37
+ The live simulator/emulator path is local-dev only (needs Xcode/Android SDK +
38
+ idb/adb) and is covered by the pure-seam unit tests; real-device runs, Flutter,
39
+ and Mac Catalyst are out of scope (separate RFCs).
40
+
41
+ ## 0.11.0 — 2026-05-27 — Sandbox setup for parallel /apt:verify-proof
42
+
43
+ Adds the recipe-driven sandbox setup flow so adopters can opt their
44
+ project into parallel-safe `/apt:verify-proof --parallel` (e.g. from
45
+ fan-out worker terminals) without `SQLITE_BUSY`, port collision, or
46
+ Electron `requestSingleInstanceLock` denial. v2-aligned end-to-end —
47
+ the precondition gate's failure envelope shares the
48
+ `verdict: "needs_human"` vocabulary verify-proof v2 emits per-outcome.
49
+
50
+ **New CLI subcommands** (three; all opt-in):
51
+
52
+ - `apt-tools recipe-diff <dir> [--format json|md]` — read-only Markdown
53
+ preview of the proposed config + source-code changes. Exits 0 on
54
+ match, 1 on no-recipe-match with `code: 'E_NO_RECIPE'`.
55
+ - `apt-tools apply-recipe <dir> [--confirm] [--accept-all]` — dry-run
56
+ by default (writes ZERO files, ZERO audit row).
57
+ - `--confirm` alone enters live mode but defers per-change accept/skip
58
+ to the caller (every change records as `user_declined`, source
59
+ files untouched — ID-02 fail-safe).
60
+ - `--confirm --accept-all` writes every change non-interactively
61
+ (pipeline / scripted / SKILL.md mini-flow after the user reviewed
62
+ the diff).
63
+ - `--force` overrides the TOFU non-clobber `user_modified` guard.
64
+ When present, `apply-recipe` overwrites files whose SHA-256 diverges
65
+ from the recipe's expected `before` value (i.e. the user has already
66
+ edited the file). Use with caution — the recipe's expected-before
67
+ anchor is skipped. Files that contain the recipe's marker substring
68
+ (`already_applied`) are still skipped even with `--force`.
69
+ - TOFU non-clobbering (already_applied / user_modified /
70
+ malformed_json / non_object_root) mirrors `install/mcp-provision.mjs`.
71
+ - Audit trail at `.aperant/recipes-applied/{recipe-id}.json` (one
72
+ row per apply invocation).
73
+ - **v1 limitation — text-insert kinds APPEND** the template at
74
+ end-of-file. The recipe template comment usually says "insert near
75
+ the top of X" — review the diff and move the block manually after
76
+ apply if your runtime requires exact positioning. The
77
+ per-change-confirmation flow surfaces this before any write lands.
78
+ - **Path-traversal defense** — recipe `change.path` / `change.template`
79
+ are validated to stay under the adopter root / recipe templates dir
80
+ respectively. A malicious community recipe attempting `../../etc/...`
81
+ is rejected at apply time, regardless of schema acceptance.
82
+ - `apt-tools verify-sandbox <dir>` — spawns TWO instances of the
83
+ recipe's launch command concurrently (`Promise.all`, jittered 50-150
84
+ ms) and writes
85
+ `.aperant/state/verify-proof-sandbox-verified.json` with the
86
+ v2-shaped envelope `{verified, verdict:'approved'|'needs_human',
87
+ reason, recipeId, recipeVersion, verifiedAt, host, durationMs}`.
88
+ win32 short-circuits to `reason:'platform_unsupported'`.
89
+
90
+ **New SKILL.md gate.** `apt-verify-proof/SKILL.md` § Step 2c reads the
91
+ state file BEFORE the outcome walker enters Step 2.5 (Deferred-tool-
92
+ load). When `--parallel` is requested with no verified state, exit
93
+ with the structured envelope
94
+ `{status:"error", code:"E_SANDBOX_UNVERIFIED", verdict:"needs_human",
95
+ reason:"sandbox_unverified", remediation:"/apt:verify-proof setup"}`
96
+ and stderr `"sandbox not verified — run /apt:verify-proof setup first"`.
97
+ When `--parallel` is requested and the state file's `recipeVersion` is no
98
+ longer in the active recipe's `compatibleWithApplied[]`, exits with
99
+ `{code:"E_SANDBOX_VERDICT_STALE", verdict:"needs_human",
100
+ reason:"sandbox_recipe_version_drift"}` — re-run `apt-tools verify-sandbox`
101
+ to refresh.
102
+
103
+ **New error codes in `verify-sandbox` envelope.**
104
+ - `E_STATE_WRITE_FAILED` — `withFileLock` exhausted retries (e.g. ELOCKED
105
+ on Windows). Verdict is `needs_human`; the sandbox run itself may have
106
+ completed. Re-run `apt-tools verify-sandbox` to retry the state write.
107
+ - `E_UNKNOWN_CHANGE_KIND` — a recipe `changes[]` entry carries a `kind`
108
+ not in `{file-create, json-merge, text-insert, text-replace}`. The
109
+ recipe is malformed; do not apply it.
110
+ - `E_INVALID_RECIPE_ID` — `recipeId` fails the `^[a-z][a-z0-9_-]*$`
111
+ pattern (path-traversal guard). The recipe is rejected before any file
112
+ read or write.
113
+
114
+ **New first-run hook.** `apt-setup/SKILL.md` Step 2 and
115
+ `apt-verify-proof/SKILL.md` Step 1 prompt only when
116
+ `host.capabilities.structured_prompts:true` AND `process.stdout.isTTY:true`
117
+ AND `verification.sandbox` is absent (ID-08). Non-interactive surfaces
118
+ print a one-line `[apt] tip:` and skip — never block CI / fan-out.
119
+
120
+ **New config block.** Optional `verification.sandbox` in
121
+ `.aperant/config.json` (mirrored by JSON-schema at
122
+ `packages/framework/src/cli/verify-proof/sandbox/sandbox-schema.json`).
123
+ Absent block = today's behavior, byte-identical Fast Path Guarantee
124
+ (ID-07).
125
+
126
+ **New recipe library.** `packages/framework/recipes/` ships
127
+ `recipe-manifest-schema.json` + the v1 canned `electron-libsql/`
128
+ recipe (config block + APERANT_SANDBOX_DB_PATH reader + singleton-lock
129
+ test-mode gate + `scripts/run-sandbox.sh` helper). v1 ships ONE
130
+ recipe; unknown runtimes get a doc pointer to
131
+ `docs/verify-proof-sandbox-patterns.md`.
132
+
133
+ **Anti-queue invariant (ID-01).** TD-09 grep guard locks: no file
134
+ under `packages/framework/src/cli/verify-proof/sandbox/**` may import
135
+ from `install/install-semaphore.mjs` or reference
136
+ `acquireInstallSlot` / `releaseInstallSlot`. The founder explicitly
137
+ rejected queue semantics in spar round 3 ("queue means parallel isn't
138
+ actually working").
139
+
140
+ **Docs.** `docs/verify-proof-sandbox-patterns.md` carries the worked
141
+ electron-libsql walkthrough (recipe-diff → apply-recipe → verify-
142
+ sandbox), tauri-rusqlite + nextjs-sqlite config stubs, the
143
+ manual-integration template for unrecognized runtimes, and the v2
144
+ vocabulary cross-reference.
145
+
146
+ **Multi-runtime re-install.** Adopters MUST re-run `/apt:update` (or
147
+ `apt-tools init . --<runtime>`) after the version bump to propagate
148
+ the new SKILL.md gate text + apt-planner.md v2-envelope-citation
149
+ guidance into each installed runtime.
150
+
151
+ ### verify-proof v2 — outcome walker + two-gate verdict
152
+
153
+ `/apt:verify-proof` is rewritten end-to-end as an outcome walker. Closes
154
+ four root causes from the 2026-05-26 17:00 run:
155
+
156
+ - **A1 — automation gate hard-stops on the `enforced_at_commit` dodge.**
157
+ Step 3 of the workflow requires `automated_checks.{tests,typecheck,lint}.status`
158
+ to be in the closed set `{pass, fail}`. The legacy `"enforced_at_commit"`
159
+ string is REJECTED. Verdict rolls up to `rejected` on any single check
160
+ failing.
161
+ - **A2 — renderer rewrite from feature-grouped to outcome-rooted.**
162
+ `mapVerificationJson` groups tests by `outcome_id` (not by
163
+ `registry_id.split('-')[0]`). The HTML renderer emits one card per
164
+ outcome with `data-outcome-id` + `data-surface` attributes, inferred
165
+ children inside a `<details>` block, and two gate badges in the header.
166
+ Report envelope returns `outcomesCount`; `featuresCount` becomes a `0`
167
+ sentinel for one release.
168
+ - **A4 — feature-registry fallback REMOVED.** When `spec.md` lacks
169
+ `## User Outcomes`, the workflow aborts at Step 2 with a clear error.
170
+ The legacy "discover features from the registry" code path is gone.
171
+ - **A5 — deferred-tool-load directive in the skill + workflow.**
172
+ Claude Code / OpenCode hosts MUST load MCP driver tools via
173
+ `ToolSearch(query='select:mcp__<server>__<tool>')` BEFORE driving any
174
+ UI-surface outcome. The real manifest field name is `transport.mcp_server_id`;
175
+ the hallucinated `mcp_transport.tool_prefix` is grep-guarded out.
176
+
177
+ ### Cutover details
178
+
179
+ - **Verdict enum is the closed set `{approved, rejected, needs_human}`.**
180
+ `approved_with_notes` is DELETED — no shim, no silent re-map. Reading a
181
+ legacy verdict from a stale `qa_signoff.json` throws a migration error
182
+ pointing at this CHANGELOG entry. **Affected workflow:** re-run
183
+ `/apt:verify-proof` on any in-flight task whose `qa_signoff.json`
184
+ carries `approved_with_notes`; that mints a fresh signoff under the
185
+ new enum.
186
+ - **Two-gate envelope.** `verification.json :: gates: {automation_gate,
187
+ proof_gate}`. `automation_gate = pass` iff lint + typecheck + tests
188
+ are all green. `proof_gate = pass` iff every outcome has
189
+ surface-appropriate evidence. Verdict = `approved` iff both gates
190
+ pass; `needs_human` when proof_gate fails on a UI-surface transport
191
+ gap; `rejected` otherwise.
192
+ - **Proof-gate fail-closed on file-evidence.** A UI-surface test
193
+ (`electron | web | electron+web`) carrying `evidence: "file-evidence:
194
+ ..."` is coerced to `result: "needs_human_with_transport"`
195
+ regardless of its written `result`. The overall verdict rolls up to
196
+ `needs_human`, NOT `approved`.
197
+ - **Inferred bullets in spec.md.** `apt:plan` Section 5.B now instructs
198
+ the planning LLM to write indented child bullets under each `**ON**`
199
+ parent outcome representing inferred sub-checks. `parseUserOutcomes`
200
+ reads them and attaches them as `inferred: string[]`. **NO** patterns
201
+ library, **NO** `surfaces/<name>/manifest.json` tree, **NO**
202
+ `OUTCOMES.md` file — inferred bullets live IN spec.md. Author edits
203
+ once if the inferred list is wrong; the runner does not re-derive
204
+ them at proof time.
205
+ - **Cross-link.** A3 (features-audit nested-worktree merge-back gap)
206
+ surfaced in the same run is filed as a follow-up in
207
+ [`docs/frameworks/spec-gaps.md#a3`](../../docs/frameworks/spec-gaps.md#a3)
208
+ — explicitly out of scope for this cutover.
209
+
210
+ ### Migration
211
+
212
+ - Tasks whose `qa_signoff.json` carries `approved_with_notes` must
213
+ re-run `/apt:verify-proof`. The new run mints a fresh signoff under
214
+ the closed `{approved, rejected, needs_human}` enum. There is no
215
+ silent compatibility layer.
216
+ - `qa.approved_with_notes_threshold` in `.aperant/config.json` is
217
+ silently dropped at read time (logged once) — projects that opted
218
+ into the legacy threshold-gated acceptance no longer get it. Tasks
219
+ that previously shipped `approved_with_notes` ship `approved` only
220
+ if both gates pass; everything else needs a code fix (`rejected`)
221
+ or a transport install (`needs_human`).
39
222
 
40
223
  ### Fixed
41
224
 
@@ -55,7 +238,7 @@ returning to a shared repo no longer means re-deriving state by hand.
55
238
  regression does not return). The per-PR / global `authorship_override` lever
56
239
  is unchanged and still wins over auto-detection — set it to `owned` to
57
240
  deliberately fix-and-push on a PR you did not author. Behavior-only fix: no
58
- CLI flag, signature, or output-shape change.
241
+ CLI flag, signature, or output-shape change, and no version bump.
59
242
 
60
243
  ## 0.10.0 — 2026-05-26 — Tauri driver + MCP auto-provision
61
244
 
@@ -217,6 +217,21 @@ Fast Path Guarantee). QUICK-routed tasks keep the existing 4-section
217
217
  shape; STANDARD/DEEP/COMPLEX tasks get a PRD-shaped artifact that
218
218
  survives the task as a second-consumer document.
219
219
 
220
+ **Sandbox-gated parallel verify-proof — cite the v2 envelope verbatim.**
221
+ When the plan calls for parallel `/apt:verify-proof` (e.g. fan-out
222
+ worker spawned a verify-proof child, or `--parallel` is passed to
223
+ `/apt:verify-proof`), the spec's User Outcomes section MUST cite the
224
+ sandbox gate's v2 failure envelope verbatim:
225
+ `{verdict: "needs_human", reason: "sandbox_unverified"}` (plus the
226
+ structured error code `E_SANDBOX_UNVERIFIED` and the remediation
227
+ `/apt:verify-proof setup`). Downstream agents reading the spec
228
+ dispatch on these exact strings; paraphrasing them breaks the
229
+ contract. The gate runs BEFORE Step 2.5 (Deferred-tool-load) and
230
+ BEFORE the outcome walker — sandbox-unverified is a precondition
231
+ failure, not a per-outcome transport failure. See
232
+ `apt-verify-proof/SKILL.md` Step 2c for the gate definition and
233
+ `docs/verify-proof-sandbox-patterns.md` for the worked adopter flow.
234
+
220
235
  ### 4.A. QUICK track / SIMPLE complexity — legacy 4-section spec
221
236
 
222
237
  ```markdown
@@ -80,10 +80,13 @@ If the planner claims a dimension is covered but the implementation does not act
80
80
  | **Code Quality** | Clean, idiomatic, lint-clean | Good, minor style issues | Acceptable, needs cleanup | Poor quality | Unacceptable |
81
81
  | **Test Coverage** | Comprehensive, edge cases | Good main-path coverage | Basic tests exist | Minimal tests | No coverage |
82
82
 
83
- ## 4. Derive Verdict
84
- - **approved:** ALL dimensions >= 7, no critical issues
85
- - **approved-with-notes:** ALL dimensions >= 5
86
- - **rejected:** ANY dimension < 5 or critical issues
83
+ ## 4. Derive Verdict (v0.9.0 two-gate envelope)
84
+
85
+ Verdict is the closed set `{approved, rejected, needs_human}`. Derived from the two-gate envelope (`automation_gate` AND `proof_gate`); dimensions are informational rationale only.
86
+
87
+ - **approved:** `automation_gate: pass` AND `proof_gate: pass`.
88
+ - **needs_human:** `automation_gate: pass` AND `proof_gate: fail` (typically: a UI-surface outcome lacked driver transport — see `/apt:verify-proof`).
89
+ - **rejected:** `automation_gate: fail` (any of lint/typecheck/tests red) OR critical findings unresolved.
87
90
 
88
91
  ## 5. Write QA Sign-off
89
92
  Write `{task_dir}/qa_signoff.json` with scores, checks, issues, and verdict.
@@ -105,14 +108,16 @@ Either shape is accepted:
105
108
 
106
109
  Gate G8 (`consistency-check`) enforces this on ship via rules R4
107
110
  (finding-propagation) and R5 (verdict-consistency):
108
- - `verdict: "approved"` or `verdict: "approved-with-notes"` is incompatible
109
- with any unresolved `critical` or `major` review finding (G42 Phase 1).
110
- Neither verdict escapes R5 for blocking-severity findings. The sole bypass
111
- is `--force --reason "<why>"` on the gate CLI (audit-logged). For
112
- non-blocking findings (suggestion/note/info/nitpick), cite them in
113
- `findings.notes` and use `approved-with-notes`.
111
+ - `verdict: "approved"` is incompatible with any unresolved `critical` or
112
+ `major` review finding (G42 Phase 1). The sole bypass is `--force --reason
113
+ "<why>"` on the gate CLI (audit-logged). For non-blocking findings
114
+ (suggestion/note/info/nitpick), cite them in `findings.notes` and keep
115
+ the verdict `approved`.
114
116
  - `verdict: "rejected"` requires at least one cited finding (rejected
115
117
  without evidence is treated as drift).
118
+ - `verdict: "needs_human"` signals a transport gap (e.g. UI-surface outcome
119
+ with no MCP driver). The R5 rule does not gate on it; re-run verify-proof
120
+ after installing the missing transport.
116
121
 
117
122
  ## 6. Report
118
123
  Output verdict with dimension scores and next step recommendation.