codex-workflow-v2 2.0.0-beta.12.7 → 2.0.0-beta.12.9

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 (36) hide show
  1. package/README.md +9 -1
  2. package/dist/src/alpha6/review.d.ts +6 -0
  3. package/dist/src/alpha6/review.js +12 -0
  4. package/dist/src/alpha6/review.js.map +1 -1
  5. package/dist/src/cli.js +37 -3
  6. package/dist/src/cli.js.map +1 -1
  7. package/dist/src/contracts.d.ts +37 -1
  8. package/dist/src/dependency-provenance.d.ts +2 -2
  9. package/dist/src/dependency-provenance.js +21 -5
  10. package/dist/src/dependency-provenance.js.map +1 -1
  11. package/dist/src/git.js +1 -0
  12. package/dist/src/git.js.map +1 -1
  13. package/dist/src/historical-step-provenance.d.ts +20 -0
  14. package/dist/src/historical-step-provenance.js +111 -0
  15. package/dist/src/historical-step-provenance.js.map +1 -0
  16. package/dist/src/state/corrective-replan-executor.js +5 -0
  17. package/dist/src/state/corrective-replan-executor.js.map +1 -1
  18. package/dist/src/version.d.ts +1 -1
  19. package/dist/src/version.js +1 -1
  20. package/dist/src/workflow.d.ts +7 -2
  21. package/dist/src/workflow.js +206 -11
  22. package/dist/src/workflow.js.map +1 -1
  23. package/docs/pdf/codex-workflow-v2-architecture-ru.pdf +0 -0
  24. package/docs/pdf/codex-workflow-v2-chat-only-guide-ru.pdf +0 -0
  25. package/docs/pdf/codex-workflow-v2-technical-reference-ru.pdf +0 -0
  26. package/docs/pdf/sources/codex-workflow-v2-architecture-ru.md +23 -6
  27. package/docs/pdf/sources/codex-workflow-v2-chat-only-guide-ru.md +28 -28
  28. package/docs/pdf/sources/codex-workflow-v2-technical-reference-ru.md +41 -26
  29. package/docs/release.md +9 -1
  30. package/docs/updating-existing-project.md +30 -0
  31. package/docs/validation-report.md +90 -96
  32. package/package.json +1 -1
  33. package/plugins/codex-workflow-gateway/.codex-plugin/plugin.json +1 -1
  34. package/plugins/codex-workflow-gateway/references/protocol.md +15 -0
  35. package/plugins/codex-workflow-gateway/skills/codex-workflow-gateway/SKILL.md +35 -0
  36. package/schemas/task.schema.json +43 -0
@@ -1,110 +1,104 @@
1
- # V2 beta.12.7 Validation Report
1
+ # V2 beta.12.9 Validation Report
2
2
 
3
- Release candidate `2.0.0-beta.12.7` was validated on 2026-08-29 (Europe/Moscow) with
3
+ Release candidate `2.0.0-beta.12.9` was validated on 2026-08-30 (Europe/Moscow) with
4
4
  Node.js 24.17.0.
5
5
 
6
6
  ## Automated release evidence
7
7
 
8
- - `npm ci` completed from the lockfile with 0 reported vulnerabilities.
9
- - The final post-fix `npm run validate` passed typecheck and `338/338` sequential tests with no
10
- failures, skips, cancellations, or todos in 1,641,977.92675 ms. The same suite also passed after
11
- the clean install (`338/338` in 1,661,195.192667 ms) and before it (`338/338` in
12
- 1,347,257.496667 ms).
13
- - `npm run test:signal-t03-replan-e2e` independently passed the full Signal-shaped compatibility
14
- scenario. The focused dependency-provenance, downstream-proof, and lifecycle-model suite passed
15
- `23/23`.
16
- - The Signal-shaped E2E starts with the exact six-path ownership split and the beta.12.6 accidental
17
- post-invalidation Knowledge rebind. It then proves: read-only source eligibility, two
18
- dependency-only transport commits, `HEAD^`/`HEAD` provenance validation, bounded dependency
19
- registration, atomic replan recovery, required Project Knowledge refresh, mandatory replacement
20
- `plan-set`, one-Step dirty carryover admission, hostile concurrency and rollback/restart checks,
21
- Core-owned Step commit, passed strict Step Review, and fresh navigation to `task submit`.
22
- - Negative regressions reject stale Plan rebind, unrelated dirty files, changed content hash,
23
- unknown history, a wider dependency candidate, current legacy-Plan audit/authorization, extra Task
24
- revisions, active lease, pending transaction, corrupted invalidation/recovery sidecars, and a
25
- replacement Plan that does not give one Step authority over the complete dirty set.
26
- - `npm run pack:check` built the exact beta.12.7 package: 275 files, 1.0 MB packed and 4.1 MB
27
- unpacked. The sandboxed attempt
28
- could not write the user npm cache (`EPERM`); the exact authorized retry passed.
8
+ - `npm ci` completed from the exact lockfile with 0 reported vulnerabilities.
9
+ - `npm run validate` passed typecheck and `343/343` sequential tests with no failures, skips,
10
+ cancellations, or todos in 1,894,344.070542 ms.
11
+ - The focused Signal-shaped E2E proves both recovery entry points. It preserves the active dirty
12
+ worktree and HEAD, registers the exact historical Step commit, reaches fresh
13
+ `task step-complete`, completes that Step with a new Core-owned commit, and validates the resulting
14
+ Task history.
15
+ - Negative cases reject pending or damaged strict review, absent final acceptance, multiple or wrong
16
+ commits, unrelated dirty paths, changed dirty content, active/stale leases, transactions, version
17
+ divergence, and a dependency candidate wider than package/lock.
18
+ - Corrective-replan executor tests prove that future replacement Plans retain evidence commits of
19
+ omitted completed Steps in `invalidatedStepCommits`.
20
+ - `npm run pack:check` built the exact beta.12.9 package with 278 files, 1.0 MB packed and 4.1 MB
21
+ unpacked. The initial sandboxed invocation could not write the user npm cache (`EPERM`); the exact
22
+ authorized retry passed.
29
23
  - `npm run smoke:downstream` packed and installed the tarball in a disposable consumer project and
30
24
  returned `ok=true`. The sandboxed attempt could not resolve the npm registry (`ENOTFOUND`); the
31
25
  exact network-authorized retry passed.
32
- - `npm run plugin:check`, `npm run docs:pdf:check`, and exact
33
- `RELEASE_TAG=v2.0.0-beta.12.7 npm run release:check` passed after the final source changes. The
34
- bundled gateway cachebuster is `0.1.0+codex.20260829143747`.
35
-
36
- ## Root causes corrected by beta.12.7
37
-
38
- - beta.12.6 correctly invalidated the completed migration predecessor and required a replacement
39
- Plan. A later Project Knowledge approval nevertheless mechanically rebound the rejected two-Step
40
- Plan and returned the Task to `awaiting_execution_authorization`. The required `plan-set` boundary
41
- was therefore lost.
42
- - The stranded state could not be fixed by another review attempt: no Step was runnable and the
43
- current Plan was the artifact whose authority had already been rejected. The defect was routing
44
- and recovery authority, not insufficient implementation effort.
45
- - A one-transition repair was also insufficient. The full E2E exposed two additional dead ends:
46
- the exact dependency-only update makes Project Knowledge stale before repair, and the ordinary
47
- `task run` clean-checkout precondition rejected the deliberately preserved dirty bytes even after
48
- a correct replacement Plan.
49
- - beta.12.7 adds a closed compatibility sequence. The external source preflight recognizes only the
50
- exact beta.12.6 stranded shape. Dependency registration binds the update commit to the original
51
- invalidation, rebound Plan, preserved HEAD, dirty paths, and content hash. Replan recovery returns
52
- the same Task to `needs_fix` without requiring the now-stale live Knowledge Map to be active.
53
- - Project Knowledge can then be reconciled and approved, but refresh/rebind routing cannot replace
54
- the mandatory `task plan-set`. The old Plan receives no execution authority.
55
- - Dirty bytes are not adopted as completed evidence. After a fresh Plan Risk Audit and execution
56
- authorization, `task run` permits carryover only when one planned Step owns every bound path and
57
- current HEAD/path/content hashes exactly match the recovery event. All ordinary checks, Core Git
58
- ownership, and strict-review requirements remain in force.
59
-
60
- ## Exact Signal project evidence
61
-
62
- - The Signal repository `/Users/home-pc/htdocs/projects/signal_v4` was inspected and exercised on
63
- branch `codex/task-01m0wxjad4-processing-persistence-schema` at
64
- `4606eaf98f3c5f1f0dec4c361f34e2abe9aefa66`.
65
- - Its Workflow remains on exact `2.0.0-beta.12.6`. Task
66
- `TASK-01M0WXJAD4GZGVNRJ284ND95C6` remains revision 106 and
67
- `awaiting_execution_authorization`; live Workflow state was not mutated by beta.12.7 validation.
68
- - The dirty set remains exactly six paths: five modified processing-migration files and untracked
69
- `tools/postgres/run-processing-integration.ts`. After temporary hostile-test additions were
70
- removed, the beta.12.7 source preflight returned `eligible=true`, empty blockers, the preserved
71
- HEAD above, and dirty-worktree SHA-256
72
- `1cbeb0ccb4883ade6f2ea751423385cf504f5c18e45473f40cb9a39ca850ece1`.
73
- - The real Signal PostgreSQL harness was temporarily extended with two concurrent migrators and a
74
- forced mid-migration conflict followed by restart. `npm run processing:postgres:test` passed clean
75
- bootstrap/repeat, advisory-lock serialization, transaction rollback with no partial ledger/schema,
76
- unchanged restart convergence, tamper/order denial, catalog fingerprint, immutable evidence, and
77
- least-privilege checks against the pinned PostgreSQL image.
78
- - Those temporary product changes were then removed exactly and the original runner bytes were
79
- verified against a parallel Signal checkout before the recovery fingerprint was re-read. This
80
- proves product feasibility without falsely presenting pre-authorized test bytes to Workflow.
81
- - This is strong live read-only entry evidence plus real product proof. It is not a claim that the
82
- unpublished beta.12.7 package has already updated Signal or mutated its Task. Final live continuation
83
- still requires release publication, exact dependency-only transport, and following fresh
84
- project-local `next` through the tested sequence.
26
+ - `npm run plugin:check` passed for bundled gateway
27
+ `0.1.0+codex.20260830183000`.
28
+ - `npm run docs:pdf:check` reported an empty stale set and exact beta.12.9 package binding.
29
+ - `RELEASE_TAG=v2.0.0-beta.12.9 npm run release:check`, JSON parsing and `git diff --check` passed.
30
+
31
+ ## Root cause corrected by beta.12.9
32
+
33
+ The corrective-replan paths replaced `task.steps` but did not preserve evidence commits belonging to
34
+ completed Steps omitted from the new Plan. Git correctly retained those commits, while Task history
35
+ authority no longer named them. A later `task step-complete` therefore rejected a legitimate,
36
+ previously reviewed and accepted commit as unregistered history.
37
+
38
+ Increasing implementation or review attempts cannot correct this condition. The historical Step had
39
+ already passed strict review and final acceptance; the defect was loss of provenance during Plan
40
+ replacement.
41
+
42
+ ## Implemented lifecycle contract
43
+
44
+ - Both legacy `setTaskPlan` and journaled corrective-replan execution now retain omitted completed
45
+ Step evidence commits in `invalidatedStepCommits`.
46
+ - `task historical-step-provenance-preflight/recover` repairs an already-installed beta.12.9 state
47
+ only when Core proves exactly one omitted commit, one active Step, confined dirty paths, a complete
48
+ hash-valid passed strict Step Review chain, verified reviewer isolation, and matching prior
49
+ hash-bound final acceptance.
50
+ - `update historical-step-dependency-preflight/recover` handles installation itself when the exact
51
+ beta.12.9 dependency-only commit is the unregistered HEAD. It binds `HEAD^`, dependency `HEAD`, all
52
+ version surfaces, active Plan/Step, historical SHA, dirty paths/content hash, and the absence of
53
+ leases or pending operations.
54
+ - The update transition records the dependency commit and retained historical commit in one Task
55
+ revision. Neither recovery rewrites Git, changes product bytes, adopts the old completed Step into
56
+ the current Plan, or weakens ordinary strict review.
57
+ - Fresh `next` advertises these routes before ordinary dependency recovery and returns to the normal
58
+ credential/`task step-complete` flow after successful registration.
59
+ - The public handshake exposes `historical-step-provenance-recovery-v1`.
60
+
61
+ ## Exact Signal diagnosis evidence
62
+
63
+ At release-candidate validation time the Signal project
64
+ `/Users/home-pc/htdocs/projects/signal_v4` was on exact beta.12.8 with Task
65
+ `TASK-01M0WXJAD4GZGVNRJ284ND95C6` at revision 136 and status `in_progress`. Current Plan hash was
66
+ `1ba67296f352cb67fa4d46c3ec9cd2ee2f50059903a5fffc7b0b2198f6dbae4e`; HEAD was
67
+ `272d6258e4ce169aa9f5cf2b5a4de29970d82eb7`.
68
+
69
+ The active Step `STEP-004-DIRECT-LOGIN-PRIVILEGE-DENIAL` had exactly five dirty files, all inside its
70
+ `allowedWrites`. Historical commit `f7ba8533314ee27f176968a6314bf3df40285ef2` had a passed strict
71
+ Step Review and prior final acceptance, but was absent from current Step evidence and retained
72
+ history authority. No active/stale lease, pending/corrupt transaction, or Core operation remained.
73
+ Milestone progress was `2/8` merged Tasks and T04 remained blocked by T03.
74
+
75
+ The recurring Signal audit automation that had created an unrelated dirty journal was paused, and
76
+ its latest journal was archived outside the checkout with matching SHA-256. The release process did
77
+ not rewrite Signal history or mutate its five product files. Live package transport and recovery are
78
+ separate post-publication actions and must follow the exact advertised beta.12.9 route.
85
79
 
86
80
  ## PDF release documentation evidence
87
81
 
88
- - Three tracked Russian PDFs were regenerated from current Markdown sources;
89
- `npm run docs:pdf:check` reported an empty stale set.
90
- - All 28 pages were rendered and visually inspected: architecture is 8 pages, the delegated
91
- chat-only guide is 9 pages, and the technical reference is 11 pages.
92
- - Titles, beta.12.7 version headers, Cyrillic glyphs, tables, code blocks, new recovery commands,
93
- page edges, and footers show no visible clipping, overlap, or unreadable content.
82
+ - All three tracked Russian PDFs were regenerated from the beta.12.9 Markdown sources.
83
+ - Architecture is 8 pages, the delegated chat-only guide is 9 pages, and the technical reference is
84
+ 12 pages. All pages were rendered to PNG contact sheets; changed recovery/update pages were also
85
+ inspected at full page resolution.
86
+ - Titles, version headers, Cyrillic text, tables, command names, margins, page footers and section
87
+ transitions have no visible clipping, overlap, unreadable content, or orphaned tail page.
94
88
 
95
89
  ## Existing boundaries and non-claims
96
90
 
97
- - Structural replacement remains intentionally disabled. beta.12.7 does not implement P04-B,
98
- topology rewiring, completed-Step adoption, or a wider delegation surface.
99
- - The new bridge is limited to the proven beta.12.6 invalidation-plus-accidental-rebind sequence.
100
- It is not a general permission for dirty update, arbitrary Plan rollback, or manual state repair.
101
- - A negative Plan Risk Audit decision may truthfully return the same Task to planning, but no
102
- automatic component decides product semantics or widens Task objective, requirements, acceptance,
103
- or Milestone topology.
104
- - Git transport commits remain agent-executed operations on exact advertised boundaries. Runtime
105
- does not create, amend, merge, reset, publish, tag, or push release history.
106
- - Validation performed no npm publication, Git commit, tag, remote push, Signal dependency update,
107
- or local plugin reinstall. Those remain separate release/deployment actions.
108
- - Confidence is high for the implementation, package artifact, synthetic Workflow E2E, and real
109
- PostgreSQL proof. Confidence in final live Signal continuation remains conditional on installing
110
- the published exact package and observing the same project-local recovery sequence.
91
+ - Recovery is intentionally unavailable for arbitrary or multiple commits, pending/failed review,
92
+ missing final acceptance, post-assessment drift, unrelated dirty paths, or active ownership.
93
+ - Protocol version remains 2 and state schema remains 2; the optional audit fields are backward
94
+ compatible and no semantic migration is introduced.
95
+ - Structural replacement remains disabled. beta.12.9 does not implement P04-B, topology rewiring,
96
+ completed-Step adoption, or a wider delegation surface.
97
+ - No Git commit, tag, remote push, npm publication, Signal dependency transport, or Signal Task
98
+ completion is claimed by this pre-publication validation report.
99
+
100
+ Confidence is high for the package implementation, prevention path, bounded legacy recovery,
101
+ dependency-install compatibility, negative evidence gates, complete Step continuation, tarball,
102
+ downstream installation, plugin and documentation. Live Signal confidence remains conditional on
103
+ publishing beta.12.9, transporting only package/lock commits to its active base and Task branch, and
104
+ following fresh project-local `status -> next` without manual history or state edits.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "codex-workflow-v2",
3
- "version": "2.0.0-beta.12.7",
3
+ "version": "2.0.0-beta.12.9",
4
4
  "description": "Requirements-first Codex development workflow with local state and explicit Git ownership.",
5
5
  "repository": {
6
6
  "type": "git",
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "codex-workflow-gateway",
3
- "version": "0.1.0+codex.20260829143747",
3
+ "version": "0.1.0+codex.20260830183000",
4
4
  "description": "Thin personal Codex gateway for exact project-local Codex Workflow V2 packages and codebase-memory-mcp.",
5
5
  "author": {
6
6
  "name": "Codex Workflow Maintainers"
@@ -33,6 +33,15 @@
33
33
  `retainedHistoricalCommits`.
34
34
  Task-local manifest/lock fields from recorded history may differ from the base, but the candidate
35
35
  commit must preserve them exactly while changing only the Workflow dependency entries.
36
+ - `task historical-step-provenance-preflight --id <TASK-ID>` is read-only. The matching
37
+ `task historical-step-provenance-recover` is available only for one unexpected product commit
38
+ with an intact passed strict-review chain, matching prior final acceptance, no lease or pending
39
+ operation, and dirty files confined to the current active Step. It retains historical authority
40
+ without changing Git, worktree bytes, or the current Plan.
41
+ - `update historical-step-dependency-preflight/recover` handles the same proof when the beta.12.9
42
+ dependency-only commit is the unregistered HEAD. It binds the exact dependency candidate and the
43
+ reviewed historical Step commit in one recovery record, preserves active product bytes, and then
44
+ requires fresh `status` and `next`.
36
45
  - `task stop-override-prepare` is a read-only Human gate for the exact beta.11 attempt-four stop
37
46
  shape. `task stop-override-apply` requires the same Task revision, Step, actor, reason, Plan, HEAD,
38
47
  evidence binding, and returned `SOO-*` code in a later user turn. It appends evidence without
@@ -300,6 +309,12 @@ working memory. In claimed C1 posture, fresh `next` exposes `writerTokenContract
300
309
  pass the receipt token through its declared `--writer-token` option on the first run call. The
301
310
  successful run returns the refreshed writer receipt for later lease-bound transitions.
302
311
 
312
+ `task result-set` is also lease-bound. It requires the active `--writer-token` and the exact C1
313
+ claimant in `--actor` when the Task is claimed. Success releases the lease before the Task enters
314
+ `awaiting_final_acceptance`; the token is no longer valid. The Human gate must therefore remain
315
+ lease-free for an arbitrary amount of time. After acceptance, obtain the new merge credential only
316
+ through the `writerCredentialRecovery` action advertised by fresh `next`.
317
+
303
318
  ## Milestone assembly, autonomy, and human gate
304
319
 
305
320
  During initial planning, materialize every linked Task and then call `milestone plan-set` once
@@ -50,6 +50,31 @@ pending/corrupt transaction. After success run sequential `status` then `next` a
50
50
  returned lifecycle action; Knowledge reconciliation or atomic Task context refresh may legitimately
51
51
  be next because the dependency files changed.
52
52
 
53
+ When beta.12.9 fresh `next` advertises `task historical-step-provenance-recover`, Core has found
54
+ exactly one product commit that a corrective Plan omitted from current Step evidence even though the
55
+ commit still has a complete hash-valid passed strict Step Review chain and a matching prior final
56
+ acceptance. First run the advertised read-only `task historical-step-provenance-preflight --id
57
+ <TASK-ID>` and require `eligible=true`, the exact Task revision/Plan/Brief/HEAD, the advertised
58
+ commit SHA, no lease/transaction/Core operation, and dirty files confined to the one active Step's
59
+ `allowedWrites`. Invoke recovery with that exact commit, actor, and a substantive reason. The
60
+ transition records the commit as invalidated historical Step authority plus an audit record; it does
61
+ not adopt the completed Step into the current Plan and does not create, remove, amend, reset, rebase,
62
+ or merge Git commits. Reject multiple or arbitrary unexpected commits, pending/failed review,
63
+ mismatched final acceptance, unrelated dirty files, or damaged sidecars. After success run
64
+ sequential `status` then `next`; the active corrective Step should resume through its ordinary
65
+ credential and `task step-complete` route.
66
+
67
+ When beta.12.9 must itself be installed while this exact historical Step blocker is active, preserve
68
+ the Task worktree and create only two dependency transport commits: one on the active Milestone base
69
+ and one at Task-branch HEAD, each changing exactly `package.json` and `package-lock.json` to the exact
70
+ beta.12.9 package. Do not switch the dirty Task checkout to update the base; use a separate temporary
71
+ worktree. Install the repository-local target package, then require fresh `next` to advertise
72
+ `update historical-step-dependency-recover`. Run the matching read-only preflight and require the
73
+ exact dependency HEAD/parent, Task revision, active Step/Plan, retained historical SHA, dirty-file
74
+ set and dirty-worktree hash, with no lease or pending operation. The matching recover registers both
75
+ authorities without modifying product bytes or Git. After recovery run sequential `status` and
76
+ `next`; do not substitute ordinary dependency recovery, manual state edits, rebase, reset, or amend.
77
+
53
78
  Beta.12.1 permits product-owned manifest/lock fields already present in the exact recorded Task
54
79
  history to differ from the Milestone base. Core compares candidate parent to candidate HEAD after
55
80
  removing only the Workflow dependency entries, so the dependency commit must preserve every such
@@ -226,6 +251,16 @@ the fresh `next.writerTokenContract` requires it. Successful `task run` returns
226
251
  `writerLeaseReceipt`; retain it only until Core releases that lease.
227
252
  Never search later payload fields for either credential and never copy credentials into evidence.
228
253
 
254
+ When a passed final Task review routes to `task result-set`, pass the active writer credential and,
255
+ for claimed C1 posture, the exact claimant as `--actor`. A successful `result-set` consumes that
256
+ execution lease before entering `awaiting_final_acceptance`; never reuse the old token and never
257
+ leave or manufacture a lease while waiting for the Human decision. After `task accept`, follow fresh
258
+ `next`: local merge or external merge confirmation normally advertises
259
+ `task writer-credential-replace`, which acquires a new bounded lease for the exact recovery actor.
260
+ If a Task created under beta.12.7 or earlier is already at the Human gate with a stale lease, use
261
+ only the exact `locks repair` route returned by repository-level `next`, verify that Task revision,
262
+ review, Result/Evidence hashes, and HEAD did not change, and stop before acceptance.
263
+
229
264
  Command discovery with `codex-workflow <noun> [action] --help` is read-only. Use it only when the
230
265
  exact invocation syntax is not already available from `next` and this protocol. Consume declared
231
266
  `requiredOptions` and `optionalOptions`; when `exactOptionContractAvailable=false`, consult the
@@ -60,6 +60,33 @@
60
60
  "uniqueItems": true,
61
61
  "items": { "type": "string", "pattern": "^[a-f0-9]{40}$" }
62
62
  },
63
+ "historicalStepProvenanceRecoveries": {
64
+ "type": "array",
65
+ "items": {
66
+ "type": "object",
67
+ "required": [
68
+ "commitSha",
69
+ "actor",
70
+ "reason",
71
+ "recordedAt",
72
+ "sourceFinalAcceptanceRecordedAt",
73
+ "sourcePlanHash",
74
+ "sourceResultHash",
75
+ "sourceEvidenceHash"
76
+ ],
77
+ "properties": {
78
+ "commitSha": { "type": "string", "pattern": "^[a-f0-9]{40}$" },
79
+ "actor": { "type": "string", "minLength": 1 },
80
+ "reason": { "type": "string", "minLength": 1 },
81
+ "recordedAt": { "type": "string", "format": "date-time" },
82
+ "sourceFinalAcceptanceRecordedAt": { "type": "string", "format": "date-time" },
83
+ "sourcePlanHash": { "type": "string", "pattern": "^[a-f0-9]{64}$" },
84
+ "sourceResultHash": { "type": "string", "pattern": "^[a-f0-9]{64}$" },
85
+ "sourceEvidenceHash": { "type": "string", "pattern": "^[a-f0-9]{64}$" }
86
+ },
87
+ "additionalProperties": false
88
+ }
89
+ },
63
90
  "dependencyProvenanceRecoveries": {
64
91
  "type": "array",
65
92
  "items": {
@@ -134,6 +161,22 @@
134
161
  }
135
162
  },
136
163
  "additionalProperties": false
164
+ },
165
+ "historicalStepProvenance": {
166
+ "type": "object",
167
+ "required": ["activeStepId", "planHash", "dirtyFiles", "dirtyWorktreeHash", "retainedCommitSha"],
168
+ "properties": {
169
+ "activeStepId": { "type": "string", "pattern": "^STEP-[A-Z0-9][A-Z0-9-]{2,63}$" },
170
+ "planHash": { "type": "string", "pattern": "^[a-f0-9]{64}$" },
171
+ "dirtyFiles": {
172
+ "type": "array",
173
+ "uniqueItems": true,
174
+ "items": { "type": "string", "minLength": 1 }
175
+ },
176
+ "dirtyWorktreeHash": { "type": "string", "pattern": "^[a-f0-9]{64}$" },
177
+ "retainedCommitSha": { "type": "string", "pattern": "^[a-f0-9]{40}$" }
178
+ },
179
+ "additionalProperties": false
137
180
  }
138
181
  },
139
182
  "additionalProperties": false