@awak-app/simy-cli 0.5.12 → 0.5.14

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.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@awak-app/simy-cli",
3
- "version": "0.5.12",
3
+ "version": "0.5.14",
4
4
  "description": "Local SIMY executor for non-coding Local Tasks and Agentic Loop runs.",
5
5
  "type": "module",
6
6
  "bin": {
@@ -13,7 +13,7 @@ import {
13
13
  } from "./durable-local-task-steps-contract.js";
14
14
  import { buildExecutionCapabilityContract } from "./execution-capability-contract.js";
15
15
 
16
- export const CLI_VERSION = "0.5.12";
16
+ export const CLI_VERSION = "0.5.14";
17
17
  export const CLI_API_CONTRACT_VERSION = 10;
18
18
 
19
19
  export function withCliContract(
@@ -53,6 +53,11 @@ Before material action, record:
53
53
  the exact user journey;
54
54
  - required evidence, applicable change boundaries, risk tier, and the few
55
55
  critical invariants that must block integration;
56
+ - for every production-relevant experience ID, outcome and guardrail measures
57
+ with signal, independent source, observation window, threshold, decision and
58
+ owner; if no production outcome is in scope, record that once with a reason;
59
+ - when release is in scope, staged exposure and deterministic promote, hold,
60
+ abort and rollback criteria, rollback mechanism, kill switch and owner;
56
61
  - requested and effective delivery levels, the risk-based safety ceiling, and
57
62
  the chat confirmation receipt;
58
63
  - exclusions and authority boundaries, especially commit, push, Draft PR
@@ -77,19 +82,20 @@ shared source, not twelve new task-local copies. Unaffected views retain their
77
82
  version; unknown As-Is facts remain unknown. Review changes through the team's
78
83
  normal version control and preserve concurrent work.
79
84
 
80
- Use independent agents for design review (including consistency across diagram
81
- kinds), implementation-to-To-Be review, and final PR/evidence review at **every**
82
- level. Reviewers inspect the full affected path and unchanged linked views. Fix
83
- findings and obtain independent re-review. A changed requirement or baseline
85
+ Freeze and follow the risk-proportionate review plan from the selected delivery
86
+ level. Level 3 may consolidate design, implementation-to-To-Be, affected-view and
87
+ final evidence review into one independent final-candidate review. Inspect changed
88
+ views and their dependency links; retain unrelated views by exact revision. Fix
89
+ findings and independently re-review the affected behavior. A changed bound input
84
90
  invalidates affected approval; do not rewrite To-Be to disguise a failed result.
85
91
 
86
- PR creation and post-creation verification include the SQM loop described in the
87
- reference. Announce this requirement when starting Delivery Loop. Running SQM
88
- still follows its explicit opt-in/authority rules; if opt-in or access is absent,
89
- retain the unmet SQM gate and continue independent work. Ordinary PR work outside
90
- Delivery Loop does not activate this workflow. Record known incident coverage and
91
- unknown coverage separately; a green proof with no applicable rules does not prove
92
- that historical failures cannot recur.
92
+ When SQM is explicitly opted in, apply the identity-aware SQM plan described in
93
+ the reference. Announce its applicability when starting Delivery Loop. Reuse a
94
+ verifiable proof only for exactly unchanged bound inputs; rerun for changed identity
95
+ or newly applicable PR-only checks. If required access is absent, retain the unmet
96
+ gate and continue independent work. Ordinary PR work outside Delivery Loop does
97
+ not activate SQM. Record known and unknown incident coverage separately; zero
98
+ applicable rules do not prove that historical failures cannot recur.
93
99
 
94
100
  ## Maintain the acceptance checklist outside the conversation
95
101
 
@@ -223,6 +229,63 @@ Reuse this record in implementation and review. Recheck only affected entries
223
229
  when rules, scope, revisions, execution paths, or authority change; patch the
224
230
  charter and invalidate affected evidence under the existing receipt contract.
225
231
 
232
+ ## Check equivalent-purpose consistency
233
+
234
+ Before changing behavior, contracts, validation, policy, or trust-boundary rules
235
+ that affect users, API consumers, data integrity, or security, identify every
236
+ relevant surface and execution path that serves the same user purpose. Group
237
+ those paths by semantic intent, then record for each path its persona, current
238
+ source of truth, precedence, fallback, enforcement location, and observed
239
+ behavior. Include client and server paths, platform variants, account, tenant,
240
+ app, device, or system preferences, caches, and legacy defaults when they can
241
+ affect the result. Use code, configuration, schemas, tests, documentation, and
242
+ runtime evidence; matching labels alone are not proof that the same rule is
243
+ enforced.
244
+
245
+ For each equivalent-purpose group, verify whether all paths consume one
246
+ canonical rule with the same precedence and fallback semantics. When they do
247
+ not, determine whether the divergence is intentional and supported by an
248
+ authoritative product decision. Also check that tests cover the shared contract
249
+ at every affected boundary. A language choice that follows the device or OS on
250
+ one surface and an in-app preference on another is one instance of this class,
251
+ not a language-specific exception. Input validation split between frontend and
252
+ backend is another: identify the canonical validation contract separately from
253
+ where it is enforced. Multiple enforcement points may be correct when the
254
+ frontend provides timely feedback and the backend protects the trust boundary,
255
+ but equivalent rules must not drift.
256
+
257
+ If competing sources or behaviors exist and no authoritative choice resolves
258
+ them, do not silently select the most common implementation or whichever path
259
+ is easiest to change. Produce a human-decision packet containing:
260
+
261
+ - the shared purpose, affected personas, surfaces, and current divergence;
262
+ - each viable unification option, including preserving an intentional
263
+ divergence when that is genuinely valid;
264
+ - for each option, user benefit, user and operational risk, compatibility and
265
+ migration effects, fallback behavior, reversibility, support and maintenance
266
+ cost, security and trust-boundary constraints, validation plan, and material
267
+ evidence gaps;
268
+ - a recommendation and rationale when the evidence supports one, clearly
269
+ separated from the decision itself.
270
+
271
+ Require an explicit human selection even when one option is recommended. Mark
272
+ the affected decision `needs_hil` and the dependent implementation
273
+ `partially_blocked`; continue independent authorized work, but do not implement
274
+ the behavior choice, define its test oracle, migrate data, or advance the
275
+ affected scope to Ready or merge. A timeout or missing response is not approval.
276
+ Human choice does not override mandatory security, privacy, data-integrity, or
277
+ external-contract constraints; exclude unsafe or non-compliant options from the
278
+ viable set and explain why. For example, client-only validation is not viable
279
+ when untrusted input reaches a server-side trust boundary.
280
+
281
+ Record the selected option as a revision-bound `HumanDecisionReceipt` and patch
282
+ the charter with the canonical source, precedence, fallback, affected consumers,
283
+ migration and rollout constraints, enforcement locations, verification plan,
284
+ and rollback condition. Then implement every affected path against that decision
285
+ and add boundary tests that fail if the paths drift again. A later change to the
286
+ decision or its canonical rule invalidates dependent evidence and requires a new
287
+ decision when the trade-off materially changes.
288
+
226
289
  ## Keep delivery states distinct
227
290
 
228
291
  Track and report the highest state actually proven:
@@ -290,10 +353,11 @@ Run focused regression tests first, then formatting, lint, type checking, unit
290
353
  tests, and the actual affected runtime. Apply only the relevant lanes from
291
354
  [the change-boundary matrix](references/change-boundary-matrix.md).
292
355
 
293
- After local verification at every level, have an independent agent compare the
294
- implementation and observed user outcomes to the frozen To-Be and original request.
295
- Include cross-view consistency, omissions and applicable historical regressions.
296
- Fix findings narrowly and independently re-review the affected behavior.
356
+ After local verification, execute the frozen review plan for the effective level
357
+ and governing repository. The independent reviewer compares the implementation
358
+ and observed outcomes to the frozen To-Be and original request, including affected
359
+ cross-view links, omissions and applicable historical regressions. Fix findings
360
+ narrowly and independently re-review the affected behavior.
297
361
 
298
362
  Give the independent verifier the acceptance sources and raw evidence, not just
299
363
  the implementer's summary. Use a separate session/agent for every review; another model can help but model count is not quality evidence.
@@ -308,11 +372,14 @@ production configuration, and CI or security-policy changes.
308
372
 
309
373
  ### 4. Coordinate through Draft PR and integration state
310
374
 
311
- Before creating a PR, pass the independent To-Be review and pre-PR SQM loop.
312
375
  After authority for the required remote changes exists, record reproduction,
313
376
  tests, evidence, companion revisions, skipped checks, and remaining gates in the
314
- Draft PR. After creation, run a fresh SQM loop bound to the actual PR head/base
315
- and have an independent agent review the PR diff, proofs and incident coverage.
377
+ Draft PR so the exact remote candidate can be inspected. Before Ready or merge,
378
+ pass the reviews and explicitly opted-in SQM gates required by the frozen plan.
379
+ Rerun a review or SQM gate only when its bound head,
380
+ base, diff, specification, policy, evidence, environment or SQM bundle changed,
381
+ or when a PR-only check became applicable. Otherwise retain the verified receipt
382
+ and record its exact identity instead of duplicating ceremony.
316
383
  Before Ready or merge, combine the latest base with required companion
317
384
  and parallel changes, rerun the affected path, and confirm current CI and
318
385
  mergeability. Without combined-state proof, report `pr_only_verified`, not
@@ -342,6 +409,13 @@ remote merge result. Wait until the target environment reports the exact merge
342
409
  revision or a verifiably derived image digest. Confirm health and runtime
343
410
  identity before live verification.
344
411
 
412
+ For a production-impacting change, release through the frozen stages. At each
413
+ stage observe the named outcome and guardrail signals for the frozen window, then
414
+ apply the deterministic decision: promote only when all promotion thresholds pass;
415
+ hold when evidence is incomplete; abort or rollback when a halt threshold fires.
416
+ Verify the rollback mechanism and kill switch before exposure. Record the owner
417
+ and a receipt for every decision. A release plan is not evidence that a stage ran.
418
+
345
419
  ### 7. Verify the deployed user journey
346
420
 
347
421
  Repeat the relevant Chrome journey against the deployed environment. Include
@@ -354,6 +428,10 @@ history or claim `done`. Save the exact revision, environment, input, Run ID,
354
428
  timestamps, visible state, network evidence, and logs, then add a boundary
355
429
  regression before re-entering implementation.
356
430
 
431
+ After the frozen observation window, evaluate the production outcome and guardrail
432
+ measures for the same experience IDs. A functioning deployment is not successful
433
+ delivery when the intended outcome misses its threshold or a guardrail is breached.
434
+
357
435
  ### Feed repaired delivery failures back into SQM
358
436
 
359
437
  When an observed failure was repaired, prepare one bounded `delivery.json` record
@@ -374,10 +452,11 @@ and validation ordering still require Delivery Loop execution controls.
374
452
 
375
453
  Remove scoped fixtures and prove the residual count is zero. Deliver a compact
376
454
  completion receipt containing shared-spec baseline/To-Be revisions and status,
377
- cross-view and implementation review results, pre/post-PR SQM proofs and historical
378
- coverage gaps, repository revisions, PR and CI, independent
455
+ the frozen review plan and identity-bound review results, applicable SQM proofs
456
+ and their reuse/rerun decision, historical coverage gaps, repository revisions, PR and CI, independent
379
457
  review, container/runtime results, local Chrome evidence, merge and deployment
380
- identity, deployed Chrome evidence, artifacts, cleanup, skipped gates, and
458
+ identity, rollout-stage and outcome/guardrail results, deployed Chrome evidence,
459
+ artifacts, cleanup, skipped gates, and
381
460
  residual risk. Convert recurring findings into the smallest maintainable rule,
382
461
  test, static check, or source-of-truth update selected by the five-response
383
462
  comparison. Bound debt cleanup by scope, change size, and completion criteria;
@@ -24,6 +24,13 @@ together for the beneficiary to succeed, include an end-to-end criterion in
24
24
  addition to narrower diagnostic criteria. Independent coverage review compares
25
25
  the experience contract and original request to the frozen rows before coding.
26
26
 
27
+ For production-relevant experience IDs, extend the same charter with outcome and
28
+ guardrail measures. Each measure names the signal, independent source,
29
+ observation window, threshold, resulting decision and owner. A rollout policy
30
+ references those measure IDs for promotion and halt decisions. These fields are
31
+ part of the same acceptance source and readable results view, not a second
32
+ success checklist.
33
+
27
34
  Each criterion has two layers:
28
35
 
29
36
  - `user`: a goal-driven user journey with visible interactions and evidence of the
@@ -64,6 +71,11 @@ After every evaluated action (test, repair, review or changed inputs):
64
71
  All rows, including pending/failed ones, stay visible. A green matrix cannot advance
65
72
  an unrelated gate or prove merge/deployment. Validate again for the final environment.
66
73
 
74
+ During staged release, append the stage, exposure, observed window, measure
75
+ results and deterministic `promote`, `hold`, `abort` or `rollback` decision to
76
+ the current results and receipt. Planned thresholds are not observations. A
77
+ healthy deployment cannot replace a missed outcome or breached guardrail.
78
+
67
79
  After the exact candidate is built in a production-like local environment, run
68
80
  the complete experience and regenerate `checklist.md` for that same revision,
69
81
  environment, fixture, and input. Read the user and system rows together as a
@@ -37,11 +37,11 @@ messages.
37
37
 
38
38
  | Level | Name | Intended work | Verification and review policy |
39
39
  | --- | --- | --- | --- |
40
- | 1 | Maximum assurance | Authentication, payments, destructive or irreversible changes, production security/configuration, sensitive data, and risky migrations | Exercise all affected and adjacent invariants, failure/recovery and rollback paths; require the broadest applicable independent review and repository gates. |
41
- | 2 | Protected | Persistence, permissions, shared contracts, external side effects, cross-repository changes, and medium-risk migrations | Verify both evidence layers for every affected outcome, shared boundaries, retry/idempotency and recovery; require independent review of the change and affected integrations. |
42
- | 3 | Balanced (default) | Normal features and bug fixes with bounded, reversible impact | Run focused regressions, applicable static checks, the real affected runtime and main user journey; require independent design/To-Be/PR review, scoped to the affected path. |
43
- | 4 | Fast | Small, isolated, reversible UI or implementation changes | Run the direct regression and real affected path; add broader checks only for touched shared boundaries; keep mandatory review and evidence gates. |
44
- | 5 | Fastest | Copy, documentation, comments, metadata, or similarly trivial changes with no runtime/data/security effect | Verify the changed artifact, final diff, packaging/link integrity where applicable, and every repository-mandated check; do not claim untested runtime behavior. |
40
+ | 1 | Maximum assurance | Authentication, payments, destructive or irreversible changes, production security/configuration, sensitive data, and risky migrations | Exercise all affected and adjacent invariants, failure/recovery and rollback paths. Use separate independent design, implementation-boundary, and final PR/evidence reviews plus every repository gate. |
41
+ | 2 | Protected | Persistence, permissions, shared contracts, external side effects, cross-repository changes, and medium-risk migrations | Verify both evidence layers, shared boundaries, retry/idempotency, staged rollout and recovery. Require independent boundary/design and final candidate/integration review; combine them only when the reviewed inputs are exactly identical. |
42
+ | 3 | Balanced (default) | Normal features and bug fixes with bounded, reversible impact | Run focused regressions, applicable static checks, the real affected runtime and main user journey. One independent final-candidate review may cover design, implementation, affected views and evidence; repeat only when its bound identity changes. |
43
+ | 4 | Fast | Small, isolated, reversible UI or implementation changes | Run the direct regression and real affected path, adding shared-boundary checks only when touched. Use a scoped independent diff/actual-path review when repository policy or material ambiguity requires it. |
44
+ | 5 | Fastest | Copy, documentation, comments, metadata, or similarly trivial changes with no runtime/data/security effect | Verify the artifact, final diff, packaging/link integrity and repository-mandated checks. Independent review is needed only when governing policy requires it or material ambiguity remains. |
45
45
 
46
46
  Level 3 is the recommendation when no task-specific signal favors another level.
47
47
  Faster levels reduce work only by declaring genuinely unaffected lanes not
@@ -69,8 +69,9 @@ always choose a lower numbered, safer level.
69
69
  Every level preserves:
70
70
 
71
71
  - frozen success criteria and independent acceptance sources;
72
- - shared system As-Is/To-Be, cross-view consistency and independent agent reviews;
73
- - pre/post-PR SQM gates under explicit opt-in, with historical coverage reported;
72
+ - shared system As-Is/To-Be and consistency of affected cross-view links;
73
+ - the frozen risk-proportionate review plan and every governing repository review;
74
+ - SQM only under explicit opt-in, with identity-bound proof and historical coverage reported;
74
75
  - honest state transitions and current revision/context binding;
75
76
  - required user/system evidence for applicable outcomes;
76
77
  - protection of user work, secrets, data integrity, and tenant boundaries;
@@ -78,3 +79,16 @@ Every level preserves:
78
79
  - repository-required tests, reviews, CI, and approval/authority boundaries.
79
80
 
80
81
  All levels retain the [minimum functional floor](minimum-completion.md): requirement mapping, actual operation/result, and independent postcondition/integration observations. Persistence requires reload and stored-state checks. Non-runtime work verifies its real consumer/artifact; no imaginary DB or API checks are added. The minimum checker has no level-based bypass.
82
+
83
+ ## Reuse instead of duplicate ceremony
84
+
85
+ Freeze the review and SQM plan in the charter. Reuse a passing review or SQM
86
+ proof only when its repository, head, base, working-tree/diff, specification,
87
+ policy, knowledge bundle, evidence and relevant environment identities are exactly
88
+ unchanged and the proof remains verifiable. A PR URL alone is not a changed input.
89
+ Rerun the affected review or SQM phase when any bound identity changes or when a
90
+ PR-only scanner, policy or integration check first becomes applicable.
91
+
92
+ Do not reopen or re-attest every shared view. Inspect the changed views and their
93
+ declared dependency links; retain unchanged views by exact revision. Do not turn a
94
+ failed, unavailable or applicable gate into `not_applicable` to save time.
@@ -139,8 +139,8 @@ external provider calls are introduced.
139
139
 
140
140
  The floor's stable criterion rows trace back to requirement IDs in the team's shared
141
141
  As-Is/To-Be specification. Follow [shared system specifications](shared-system-specifications.md)
142
- for purpose, user experience, cross-view consistency, independent reviews and
143
- pre/post-PR SQM. These are controller workflow obligations, not fields magically
142
+ for purpose, user experience, cross-view consistency, risk-proportionate independent
143
+ reviews and explicitly opted-in, identity-aware SQM. These are controller workflow obligations, not fields magically
144
144
  validated by the minimum checker. The CLI gate verifies minimum structured evidence;
145
145
  it does not launch every design review or SQM phase on its own. Standalone hosts
146
146
  remain responsible for executing this skill and cannot claim an enforced host hook.
@@ -34,9 +34,11 @@ At the start of each run:
34
34
  5. Link each experience ID to workflow, screen/control, state/sequence, API/event,
35
35
  data/relationship, permission and runtime boundaries as applicable. Map these
36
36
  stable system IDs to the run's criterion rows and implementation/evidence locations.
37
- 6. Obtain independent design review before implementation. Supply the original
38
- request, shared baseline, To-Be and linked unchanged views. Missing evidence or
39
- contradictory views remains pending/failed, never silently accepted.
37
+ 6. Freeze the delivery-level review plan. At levels that require a separate
38
+ design review, obtain it before implementation; at level 3 the independent
39
+ final-candidate review may cover design, implementation and evidence together.
40
+ Supply the original request, shared baseline, To-Be and affected links. Missing
41
+ evidence or contradictory views remains pending/failed, never silently accepted.
40
42
 
41
43
  After the exact local candidate is built, update the existing acceptance matrix
42
44
  and its readable table for those same experience IDs. Compare expected experience,
@@ -68,13 +70,15 @@ interface views; do not invent application screens, APIs, tables or infrastructu
68
70
 
69
71
  ## Review evidence and neutral agents
70
72
 
71
- All reviews use independent agents/sessions, including design, cross-view
72
- consistency, implementation-versus-To-Be, verification changes and PR review.
73
- An agent must not approve work it authored. A reviewer can re-review fixes to its
74
- findings if it did not implement the fixes. Supply raw sources, not desired answers;
75
- require inspected references, discrepancies, uncertainty and a reasoned verdict.
76
- Use the repository-required model (gpt-5.5 / xhigh where mandated and available).
77
- If independent review is unavailable, report that gate as blocked.
73
+ Required reviews use independent agents/sessions; an agent must not approve work
74
+ it authored. Follow the risk-proportionate plan in `delivery-levels.md` instead of
75
+ creating design, cross-view, implementation and PR reviews by default. A reviewer
76
+ may cover several review kinds in one receipt when the candidate inputs are the
77
+ same, and can re-review fixes it did not implement. Supply raw sources, not desired
78
+ answers; require inspected references, discrepancies, uncertainty and a reasoned
79
+ verdict. Use the repository-required model (gpt-5.5 / xhigh where mandated and
80
+ available). If a required independent review is unavailable, report that gate as
81
+ blocked.
78
82
 
79
83
  Persist a compact review receipt: reviewer/session identity, review kind, original
80
84
  request and shared baseline/To-Be references, candidate revisions, inspected views
@@ -122,17 +126,22 @@ Use concrete regressions for relevant uncovered incidents and have an independen
122
126
  reviewer assess coverage; keep missing incident history or untested boundaries
123
127
  visible. No finite test promises absence of all future bugs.
124
128
 
125
- Pre-PR: implementation-to-To-Be review and relevant regressions pass, then run SQM;
126
- repair findings within the bounded loop, re-review changed work, and rerun against
127
- the final candidate before creation. On unavailable/failed proof, withhold creation
128
- and report the exact blocker while continuing independent authorized preparation.
129
-
130
- Post-PR: fetch the actual PR head/base and check out/verify that combination, run
131
- both SQM phases again into new paths, inspect proof and current CI, and obtain
132
- independent PR/evidence review. The pre-PR proof cannot stand in for this run.
133
- If it fails, retain the PR as draft/not-ready with unmet gates recorded, repair and
134
- rerun affected independent reviews and SQM. A changed head/base/spec or relevant
135
- bundle invalidates affected approvals and proofs; preserve old receipts as history.
129
+ Draft creation: after authority and local regressions, publish a Draft so the exact
130
+ remote candidate can be inspected. Draft existence is not gate approval.
131
+
132
+ Before Ready or merge, pass the frozen review plan. When the explicitly opted-in
133
+ plan requires SQM, run it against the final candidate; repair findings within the
134
+ bounded loop and rerun affected gates. On an unavailable/failed required proof,
135
+ retain Draft/not-ready and report the exact blocker while continuing independent
136
+ authorized preparation.
137
+
138
+ Post-PR: fetch and verify the actual PR head/base and current CI. Reuse the pre-PR
139
+ SQM proof only when repository, head, base, working-tree/diff, specification,
140
+ policy, knowledge bundle, evidence and relevant environment identities are exactly
141
+ unchanged and the signed proof verifies. Rerun into a new path when any identity
142
+ changed or a PR-only scanner/policy becomes applicable. Apply the same rule to
143
+ independent review. If a required gate fails, retain the PR as draft/not-ready,
144
+ repair and rerun affected gates. Preserve superseded receipts as history.
136
145
  Promote Ready only with current required gates, including applicable combined-state
137
146
  verification. Merge and deployment still require their own authority and evidence.
138
147
 
@@ -12,8 +12,9 @@ Persist one controller-owned snapshot with at least:
12
12
  - frozen experience-contract identities, their mapping to acceptance rows, and
13
13
  the current readable local-experience table path and digest;
14
14
  - acceptance-source identities and digests, architecture boundaries, applicable
15
- rule decisions, risk tier, requested/effective delivery levels, the safety
16
- ceiling reason, and chat-confirmation receipt;
15
+ rule decisions, human-decision receipt IDs, approved canonical sources and
16
+ their precedence and fallback semantics, risk tier, requested/effective
17
+ delivery levels, the safety ceiling reason, and chat-confirmation receipt;
17
18
  - repository, base SHA, head SHA, companion SHAs, merge SHA, image digests, and
18
19
  deployed revision;
19
20
  - target environments, user journey, user/tenant fixture identities, and
@@ -22,7 +23,8 @@ Persist one controller-owned snapshot with at least:
22
23
  - frozen acceptance charter digest, current matrix/table paths and digests,
23
24
  superseded matrix snapshots, and the acceptance validator result for each gate;
24
25
  - verification-boundary changes, deferred-debt references, and applicable
25
- outcome and guardrail measures;
26
+ outcome and guardrail measures, rollout policy, current rollout stage and
27
+ latest deterministic release decision;
26
28
  - attempt number, retry/time/cost budgets, and failure fingerprints;
27
29
  - append-only receipt IDs, evidence references, timestamps, and cleanup state.
28
30
 
@@ -35,6 +37,7 @@ an integrity failure.
35
37
  Use the smallest applicable receipts rather than free-form completion claims:
36
38
 
37
39
  - `CharterReceipt`
40
+ - `HumanDecisionReceipt`
38
41
  - `FailureReproductionReceipt`
39
42
  - `ImplementationReceipt`
40
43
  - `LocalVerificationReceipt`
@@ -46,6 +49,8 @@ Use the smallest applicable receipts rather than free-form completion claims:
46
49
  - `ChromeUserJourneyReceipt`
47
50
  - `MergeReceipt`
48
51
  - `DeploymentIdentityReceipt`
52
+ - `RolloutStageReceipt`
53
+ - `OutcomeEvaluationReceipt`
49
54
  - `HealthReceipt`
50
55
  - `LiveEvidenceReceipt`
51
56
  - `CleanupReceipt`
@@ -63,6 +68,29 @@ Each receipt should contain:
63
68
  network traces, DB rows, artifact hashes, CI/deploy URLs, and timestamps;
64
69
  - a typed error category and retryability when unsuccessful.
65
70
 
71
+ A `HumanDecisionReceipt` additionally stores or immutably references the exact
72
+ decision packet presented to the human. Preserve the question and scope; every
73
+ option's user benefit, user and operational risk, compatibility and migration
74
+ effects, fallback behavior, reversibility, support and maintenance cost,
75
+ security and trust-boundary constraints, validation plan, and material evidence
76
+ gaps; any excluded unsafe or non-compliant option and its reason; and any
77
+ recommendation separately from the decision. Record the selected option's exact
78
+ text and stable ID or digest, conditions attached to the selection, decision
79
+ maker, timestamp, and a stable approval reference such as a message or turn ID
80
+ or an immutable transcript or artifact digest, with its channel and context when
81
+ applicable. The selection may reference a viable presented option or an explicit
82
+ user-authored modification or combination. When the user's decision is clear,
83
+ executable, and introduces no undisclosed material trade-off, update the packet
84
+ and record that same message as approval without requesting confirmation again.
85
+ If the decision is ambiguous or introduces a material trade-off not yet explained,
86
+ clarify only the unresolved point before proceeding with dependent work. Mandatory
87
+ security, privacy, data-integrity, and external-contract constraints still apply.
88
+
89
+ A successful `HumanDecisionReceipt` requires an explicit selection. Until then,
90
+ store the pending decision packet in the snapshot and publish the monitor verdict
91
+ `needs_hil` with action `request_hil`; never synthesize or infer approval from a
92
+ recommendation, silence, or an implementation pattern.
93
+
66
94
  ## Monitor verdict and policy action
67
95
 
68
96
  The semantic monitor may emit:
@@ -101,6 +129,7 @@ Evidence is revision-bound:
101
129
  | Change | Invalidate |
102
130
  |---|---|
103
131
  | Charter or explicit success conditions | All affected downstream gates |
132
+ | Human decision, canonical source, precedence, or fallback | All dependent implementation and verification evidence |
104
133
  | Acceptance source, test oracle, assertion, or CI/security gate changes | The affected gate and all dependent downstream evidence |
105
134
  | Head SHA or generated source changes | Local, CI, integration, container, and live evidence |
106
135
  | Base SHA or companion revision changes | Integration and later evidence |
@@ -108,6 +137,8 @@ Evidence is revision-bound:
108
137
  | Merge SHA changes | Deployment identity and live evidence |
109
138
  | Deployed revision changes | Health and live evidence |
110
139
  | Browser profile, tenant, or fixture changes | Affected user-journey evidence |
140
+ | Outcome/guardrail signal, source, window, threshold, decision, or owner changes | Affected release and outcome evidence |
141
+ | Rollout stage, exposure, recovery control, or kill switch changes | Affected rollout and later live evidence |
111
142
 
112
143
  Do not discard historical receipts; mark them superseded for the current gate.
113
144
 
@@ -146,11 +177,13 @@ done =
146
177
  && deployed_exact_revision
147
178
  && health_verified
148
179
  && live_verified
180
+ && production_outcome_evaluated
149
181
  && cleanup_verified
150
182
  && completion_receipt_created
151
183
  ```
152
184
 
153
- Remove only genuinely non-applicable terms and record why. If merge or deploy
185
+ Remove only genuinely non-applicable terms and record why; production outcome
186
+ evaluation is non-applicable when no production-impacting release is in scope. If merge or deploy
154
187
  is outside current authority, stop at the highest proven pre-authority state.
155
188
 
156
189
  Acceptance evidence must cover every applicable criterion for the target gate,
@@ -4,6 +4,7 @@ import { lstat, readFile, realpath } from "node:fs/promises";
4
4
  import path from "node:path";
5
5
  import { fileURLToPath } from "node:url";
6
6
  import { isDeepStrictEqual } from "node:util";
7
+ import { normalizeProductionContract } from "./production-contract.mjs";
7
8
  import {
8
9
  checkAcceptance,
9
10
  contextDigest,
@@ -49,6 +50,7 @@ export function minimumCharter(charter) {
49
50
  run_id: charter.id,
50
51
  source,
51
52
  experience,
53
+ ...normalizeProductionContract(charter.completion_contract, ids),
52
54
  criteria: charter.acceptance_criteria.map((outcome, index) => ({
53
55
  id: ids[index],
54
56
  outcome,
@@ -0,0 +1,158 @@
1
+ // Shared by the CLI and the independently installed skill. Keep this module
2
+ // self-contained so validation never depends on the repository checkout.
3
+ const cleanString = value => typeof value === "string" ? value.trim() : "";
4
+ const record = value => value && typeof value === "object" && !Array.isArray(value) ? value : {};
5
+ const uniqueStrings = value => [...new Set(Array.isArray(value) ? value.map(cleanString).filter(Boolean) : [])];
6
+ const criterionIdPattern = /^[A-Za-z][A-Za-z0-9]*(?:[-_.][A-Za-z0-9]+)*$/;
7
+
8
+ export function normalizeProductionContract(source, ids) {
9
+ const outcome_contract = normalizeOutcomeContract(source.outcome_contract, ids);
10
+ return { outcome_contract, rollout_policy: normalizeRolloutPolicy(source.rollout_policy, outcome_contract) };
11
+ }
12
+
13
+ function normalizeOutcomeContract(value, criterionIds) {
14
+ const source = record(value);
15
+ const criteria = new Set(criterionIds);
16
+ const outcomeMeasures = normalizeMeasures(
17
+ source.outcome_measures,
18
+ criteria,
19
+ new Set(["promote", "hold"]),
20
+ "outcome",
21
+ );
22
+ const guardrailMeasures = normalizeMeasures(
23
+ source.guardrail_measures,
24
+ criteria,
25
+ new Set(["hold", "abort", "rollback"]),
26
+ "guardrail",
27
+ );
28
+ const allIds = [
29
+ ...outcomeMeasures.map((measure) => measure.id),
30
+ ...guardrailMeasures.map((measure) => measure.id),
31
+ ];
32
+ if (new Set(allIds).size !== allIds.length) {
33
+ throw new Error("Duplicate outcome or guardrail measure IDs");
34
+ }
35
+ return {
36
+ outcome_measures: outcomeMeasures,
37
+ guardrail_measures: guardrailMeasures,
38
+ };
39
+ }
40
+
41
+ function normalizeMeasures(value, criterionIds, allowedDecisions, kind) {
42
+ if (value === undefined || value === null) return [];
43
+ if (!Array.isArray(value)) throw new Error(`Invalid ${kind} measures`);
44
+ const measures = value.map((item) => {
45
+ const source = record(item);
46
+ const measure = {
47
+ id: cleanString(source.id),
48
+ criterion_id: cleanString(source.criterion_id),
49
+ signal: cleanString(source.signal),
50
+ source: cleanString(source.source),
51
+ window: cleanString(source.window),
52
+ threshold: cleanString(source.threshold),
53
+ decision: cleanString(source.decision).toLowerCase(),
54
+ owner: cleanString(source.owner),
55
+ };
56
+ if (
57
+ !criterionIdPattern.test(measure.id) ||
58
+ !criterionIds.has(measure.criterion_id) ||
59
+ !measure.signal ||
60
+ !measure.source ||
61
+ !measure.window ||
62
+ !measure.threshold ||
63
+ !allowedDecisions.has(measure.decision) ||
64
+ !measure.owner
65
+ ) {
66
+ throw new Error(`Invalid ${kind} measure`);
67
+ }
68
+ return measure;
69
+ });
70
+ if (new Set(measures.map((measure) => measure.id)).size !== measures.length) {
71
+ throw new Error(`Duplicate ${kind} measure IDs`);
72
+ }
73
+ return measures;
74
+ }
75
+
76
+ function normalizeRolloutPolicy(value, outcomeContract) {
77
+ const source = record(value);
78
+ const required = source.required === true;
79
+ if (!required) {
80
+ return {
81
+ required: false,
82
+ reason: cleanString(source.reason) || "No production rollout is in scope",
83
+ stages: [],
84
+ promotion_requires: [],
85
+ halt_on: [],
86
+ rollback: null,
87
+ kill_switch: null,
88
+ };
89
+ }
90
+ const stages = normalizeRolloutStages(source.stages);
91
+ const outcomeIds = new Set(
92
+ outcomeContract.outcome_measures.map((measure) => measure.id),
93
+ );
94
+ const guardrailIds = new Set(
95
+ outcomeContract.guardrail_measures.map((measure) => measure.id),
96
+ );
97
+ const promotionRequires = uniqueStrings(source.promotion_requires);
98
+ const haltOn = uniqueStrings(source.halt_on);
99
+ const rollback = normalizeRecoveryControl(source.rollback, "rollback");
100
+ const killSwitch = normalizeRecoveryControl(source.kill_switch, "kill switch");
101
+ if (
102
+ stages.length < 2 ||
103
+ outcomeIds.size === 0 ||
104
+ promotionRequires.length !== outcomeIds.size ||
105
+ promotionRequires.some((id) => !outcomeIds.has(id)) ||
106
+ guardrailIds.size === 0 ||
107
+ haltOn.length !== guardrailIds.size ||
108
+ haltOn.some((id) => !guardrailIds.has(id))
109
+ ) {
110
+ throw new Error("Invalid progressive rollout policy");
111
+ }
112
+ return {
113
+ required: true,
114
+ reason: cleanString(source.reason) || "Production impact requires progressive exposure",
115
+ stages,
116
+ promotion_requires: promotionRequires,
117
+ halt_on: haltOn,
118
+ rollback,
119
+ kill_switch: killSwitch,
120
+ };
121
+ }
122
+
123
+ function normalizeRolloutStages(value) {
124
+ if (!Array.isArray(value)) throw new Error("Invalid rollout stages");
125
+ const stages = value.map((item) => {
126
+ const source = record(item);
127
+ const stage = {
128
+ id: cleanString(source.id),
129
+ exposure: cleanString(source.exposure),
130
+ observation_window: cleanString(source.observation_window),
131
+ };
132
+ if (
133
+ !criterionIdPattern.test(stage.id) ||
134
+ !stage.exposure ||
135
+ !stage.observation_window
136
+ ) {
137
+ throw new Error("Invalid rollout stage");
138
+ }
139
+ return stage;
140
+ });
141
+ if (new Set(stages.map((stage) => stage.id)).size !== stages.length) {
142
+ throw new Error("Duplicate rollout stage IDs");
143
+ }
144
+ return stages;
145
+ }
146
+
147
+ function normalizeRecoveryControl(value, label) {
148
+ const source = record(value);
149
+ const control = {
150
+ mechanism: cleanString(source.mechanism),
151
+ owner: cleanString(source.owner),
152
+ };
153
+ if (!control.mechanism || !control.owner) {
154
+ throw new Error(`Invalid ${label} control`);
155
+ }
156
+ return control;
157
+ }
158
+
@@ -1,3 +1,4 @@
1
+ import { normalizeProductionContract } from "../codex-plugins/simy/skills/agentic-delivery-loop/scripts/production-contract.mjs";
1
2
  import { cleanString, stringArray } from "./shared.js";
2
3
 
3
4
  export const COMPLETION_CONTRACT_VERSION = 2;
@@ -15,13 +16,16 @@ export function buildCompletionContract({
15
16
  const proofRequired = stringArray(source.proof_required);
16
17
  const criteria = stringArray(acceptanceCriteria);
17
18
  const userOutcome = cleanString(source.user_outcome) || cleanString(requirement);
19
+ const ids = criterionIds(source.criterion_ids, criteria.length);
20
+ const productionContract = normalizeProductionContract(source, ids);
18
21
  return {
19
22
  version: COMPLETION_CONTRACT_VERSION,
20
23
  user_outcome: userOutcome,
21
24
  minimum_scope:
22
25
  minimumScope.length > 0 ? minimumScope : criteria,
23
- criterion_ids: criterionIds(source.criterion_ids, criteria.length),
26
+ criterion_ids: ids,
24
27
  experience: normalizeExperience(source.experience, userOutcome),
28
+ ...productionContract,
25
29
  non_goals: stringArray(nonGoals),
26
30
  proof_required: uniqueStrings([
27
31
  "criterion_evidence",
@@ -65,6 +65,9 @@ export function buildIndependentAuditInstruction(charter, attempt) {
65
65
  "Treat executor claims as untrusted until supported by repository evidence.",
66
66
  "Compare the original request and frozen experience to the complete stable criterion-ID list and implementation mapping. Report forgotten features, dead controls, unsaved results and broken integration. Open the raw minimum evidence, verify its oracle and actual runtime observations; matching expected/actual JSON and hashes alone do not prove truth. Check reload/session return and persisted values/ownership when saving is required.",
67
67
  "For every stable criterion ID, return a criterion_results entry only after directly checking its cited proof and observed outcome.",
68
+ "For production-relevant criteria, verify that each outcome and guardrail measure names its signal, independent source, observation window, threshold, decision, owner, and criterion ID.",
69
+ "When rollout_policy.required=true, verify that staged exposure and deterministic promote, hold, abort, rollback, and kill-switch controls are frozen before release. Do not treat a rollout plan as deployed evidence.",
70
+ "Apply the frozen delivery-level review plan: reuse a prior review only when its exact head, base, specification, policy, evidence, and environment identities are unchanged; otherwise review the affected boundary again.",
68
71
  charter.evidence_policy?.browser_required
69
72
  ? "Open and inspect the actual local screenshots or videos. Return visual_review.inspected=true only after checking their visible content against the acceptance criteria."
70
73
  : "Do not require visual evidence when the Charter does not require browser evidence.",
@@ -43,6 +43,9 @@ export function buildCodingInstruction(
43
43
  `Usable outcome: ${charter.completion_contract?.experience?.usable_outcome || "not recorded"}`,
44
44
  `Recovery experience: ${charter.completion_contract?.experience?.recovery || "not recorded"}`,
45
45
  `Forbidden experiences:\n${bullets(charter.completion_contract?.experience?.forbidden_experiences || [])}`,
46
+ `Outcome measures: ${JSON.stringify(charter.completion_contract?.outcome_contract?.outcome_measures || [])}`,
47
+ `Guardrail measures: ${JSON.stringify(charter.completion_contract?.outcome_contract?.guardrail_measures || [])}`,
48
+ `Progressive rollout policy: ${JSON.stringify(charter.completion_contract?.rollout_policy || { required: false })}`,
46
49
  `Minimum scope:\n${bullets(charter.completion_contract?.minimum_scope || charter.acceptance_criteria)}`,
47
50
  `Non-goals:\n${bullets(charter.completion_contract?.non_goals || charter.thread_state.non_goals)}`,
48
51
  `Proof required:\n${bullets(charter.completion_contract?.proof_required || [])}`,