@kylecheng3146/agent-ops 0.9.0 → 0.10.2

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 (73) hide show
  1. package/README.md +3 -2
  2. package/dist/packages/cli/src/args.js +58 -14
  3. package/dist/packages/cli/src/bin.js +10 -3
  4. package/dist/packages/cli/src/cli.js +30 -6
  5. package/dist/packages/cli/src/commands/advance.js +2 -1
  6. package/dist/packages/cli/src/commands/escapes.js +109 -0
  7. package/dist/packages/cli/src/commands/parallel.js +1 -1
  8. package/dist/packages/cli/src/commands/review-show.js +1 -1
  9. package/dist/packages/cli/src/commands/review.js +63 -11
  10. package/dist/packages/cli/src/commands/run.js +10 -3
  11. package/dist/packages/cli/src/commands/task.js +41 -3
  12. package/dist/packages/cli/src/commands/update.js +16 -4
  13. package/dist/packages/cli/src/commands/verify.js +4 -1
  14. package/dist/packages/cli/src/context.js +22 -4
  15. package/dist/packages/cli/src/debug-intake.js +1 -1
  16. package/dist/packages/cli/src/office-entry.js +8 -4
  17. package/dist/packages/cli/src/owned-run-step.js +4 -4
  18. package/dist/packages/cli/src/parallel-deps.js +0 -2
  19. package/dist/packages/cli/src/run-deps.js +12 -9
  20. package/dist/packages/cli/src/run-entry.js +76 -17
  21. package/dist/packages/cli/src/run-setup-entry.js +2 -2
  22. package/dist/runtime/src/escape/link.js +317 -0
  23. package/dist/runtime/src/escape/origin.js +20 -0
  24. package/dist/runtime/src/escape/rules.js +252 -0
  25. package/dist/runtime/src/fs/temporary.js +10 -0
  26. package/dist/runtime/src/install/harness.js +7 -4
  27. package/dist/runtime/src/logging/local-log.js +44 -1
  28. package/dist/runtime/src/office/scene.js +1 -1
  29. package/dist/runtime/src/office/server.js +43 -16
  30. package/dist/runtime/src/office/snapshot.js +1 -1
  31. package/dist/runtime/src/parallel/finish.js +139 -65
  32. package/dist/runtime/src/parallel/manage.js +51 -1
  33. package/dist/runtime/src/parallel/receipt.js +3 -1
  34. package/dist/runtime/src/parallel/service.js +5 -1
  35. package/dist/runtime/src/review/execute.js +20 -12
  36. package/dist/runtime/src/review/packet.js +20 -7
  37. package/dist/runtime/src/review/probe.js +3 -2
  38. package/dist/runtime/src/review/runner.js +26 -3
  39. package/dist/runtime/src/review/slots.js +1 -1
  40. package/dist/runtime/src/run/controls.js +99 -1
  41. package/dist/runtime/src/run/hosts/codex.js +28 -1
  42. package/dist/runtime/src/run/hosts/protocol.js +5 -2
  43. package/dist/runtime/src/run/integration.js +35 -13
  44. package/dist/runtime/src/run/policy.js +65 -10
  45. package/dist/runtime/src/run/scheduler.js +10 -5
  46. package/dist/runtime/src/run/service.js +68 -21
  47. package/dist/runtime/src/run/supervisor.js +11 -2
  48. package/dist/runtime/src/run/transport.js +1 -0
  49. package/dist/runtime/src/schema/validate.js +6 -1
  50. package/dist/runtime/src/security/permissions.js +85 -0
  51. package/dist/runtime/src/surface/discovery.js +79 -2
  52. package/dist/runtime/src/surface/schema.js +43 -2
  53. package/dist/runtime/src/task/completion.js +20 -0
  54. package/dist/runtime/src/task/contract.js +3 -1
  55. package/dist/runtime/src/task/debug-state.js +9 -3
  56. package/dist/runtime/src/task/debug-user-event.js +82 -17
  57. package/dist/runtime/src/task/debug.js +59 -16
  58. package/dist/runtime/src/task/service.js +58 -6
  59. package/dist/runtime/src/verify/acceptance-replay.js +24 -11
  60. package/docs/en/guides/configuration.md +24 -5
  61. package/docs/en/guides/task-debug.md +26 -2
  62. package/docs/en/spec/acceptance-and-evidence.md +104 -2
  63. package/docs/en/spec/harness-adapters.md +26 -1
  64. package/docs/en/spec/loop-engineering.md +34 -6
  65. package/docs/en/spec/review.md +6 -0
  66. package/docs/zh-TW/guides/configuration.md +20 -4
  67. package/docs/zh-TW/guides/task-debug.md +19 -2
  68. package/docs/zh-TW/spec/acceptance-and-evidence.md +84 -4
  69. package/docs/zh-TW/spec/harness-adapters.md +21 -1
  70. package/docs/zh-TW/spec/loop-engineering.md +9 -3
  71. package/docs/zh-TW/spec/review.md +5 -0
  72. package/package.json +1 -1
  73. package/schemas/task.schema.json +8 -1
@@ -57,12 +57,25 @@ Use `task debug --task <id> --debug-action <action>`:
57
57
  new reference and `reason`.
58
58
  - `strategy --payload-file <json>` records a different `from`/`to` method,
59
59
  substantive `reason` and discriminating `reference`. Only one switch is allowed.
60
+ - `origin --payload-file <json>` declares where the bug came from once a
61
+ hypothesis is confirmed: `{"kind": "escape-of", "commit": "<commit>", "label":
62
+ "<earliest gate>"}` (optional `"receipt"`) or `{"kind": "pre-existing" |
63
+ "external", "reason": "..."}`. It revises the contract, so re-verify and
64
+ re-record the confirmed hypothesis before review; finish refuses
65
+ `ESCAPE_ORIGIN_MISSING` without it. `escape-of` prints the link state and
66
+ `git blame` hints and writes `.agent-ops-escapes/<task-id>.json`, which is
67
+ committed with the fix (see `EVIDENCE-ESCAPE-001`). A surface label also
68
+ needs a tracked `.agent-ops-escapes/rules/<rule-id>.json` rule that replays
69
+ at the escaped commit, and a criteria/verify label needs `"promote":
70
+ "<runnerId:checkId>"`; finish refuses `ESCAPE_RULE_UNPROVEN` otherwise (see
71
+ `EVIDENCE-ESCAPE-002`).
60
72
  - `checkpoint --session <id>` saves the current bound source/policy/stop cause.
61
73
  - `resume --session <id>` recovers a matching owned worktree checkpoint. Mismatches
62
74
  require human confirmation and remain preserved; this command cannot waive them.
63
75
  - `extend --session <native-id> --event-id latest` reads the current native human
64
- continue event. It grants exactly twenty additional minutes once, only after
65
- time exhaustion and without waiving any other blocker. No actor/text flag can
76
+ continue or resume-repair event. After time exhaustion it grants a full twenty
77
+ minutes from that event, retaining consumed time and overrun in the grant snapshot
78
+ without waiving any other blocker. No actor/text flag can
66
79
  authorize a grant. Missing native transcripts fail closed as unsupported.
67
80
 
68
81
  Limits belong to the original root across revisions, children and sessions.
@@ -85,6 +98,11 @@ rounds. Test/fixture edits do not. New paired original-regression outcomes or
85
98
  new discriminating hypothesis outcomes count as progress; renaming a task or
86
99
  hypothesis does not. Two stagnant rounds require the strategy switch; two more
87
100
  stop, subject to the global round/time ceilings.
101
+ The switch may cite this issue's own sealed regression evidence from an earlier
102
+ contract revision, because a scope revision stales current evidence while
103
+ verification stays stopped; hypotheses and delivery still need fresh evidence.
104
+ At the round limit an unchanged candidate may still be reviewed, and re-verified
105
+ when its last verification passed; a failing or changed candidate stays stopped.
88
106
 
89
107
  Success requires baseline assertion red and candidate green for the original
90
108
  regression, required related checks, a supported confirmed hypothesis, and two
@@ -109,3 +127,9 @@ persists foreground progress, and does not promise
109
127
  execution after the native conversation closes. Native transcripts are trusted
110
128
  host evidence, not protection against an attacker with the same filesystem
111
129
  authority.
130
+
131
+ An explicit native human `no time limit` / `取消時間限制` instruction removes the
132
+ original issue time cap via the same native-only `extend --event-id latest`
133
+ authority. The grant records `grantedMs: null` and the spent snapshot; original
134
+ budget, consumption, prior grants, iteration limits and evidence gates remain.
135
+ Ordinary command and review stall timeouts remain in force.
@@ -18,6 +18,10 @@ Executable acceptance MUST bind the current contract to immutable replay evidenc
18
18
  build and test build. Tasks provide stable check IDs and explicit committed
19
19
  test/fixture/helper materials. Each checkout installs and builds its own version
20
20
  before candidate materials are overlaid. Tasks cannot override runner commands.
21
+ - A generic runner must emit exactly the union of `checkIds` requested by criteria
22
+ sharing its runner, baseline and materials; unexpected rows are UNKNOWN. If a
23
+ runner always emits its full suite, bind the full emitted set while keeping
24
+ `redCheckIds` limited to the actual regression assertions.
21
25
  - Fixture, collection, build, timeout, cancellation, truncated output, missing or
22
26
  duplicate IDs, retries and skips MUST NOT establish red or green. Complete raw
23
27
  execution artifacts are digest-bound to the contract, materials and commits.
@@ -104,13 +108,22 @@ Every new task MUST record a surface audit of where else its change lands before
104
108
  such as `order:`, `user_`, `menu.`); compound identifiers (snake_case,
105
109
  camelCase or containing digits, so prose words are not queries) and string
106
110
  literals from added and removed lines (at least 6 characters; skipped as too
107
- generic above 30 file hits). Every hit outside the diff and the surface lists stops review.
111
+ generic above 10 file hits, changed files included). Every hit outside the diff and the surface lists stops review.
112
+ - A derived query (diff token, template fragment or hunk-header name) whose hits
113
+ are incidental may be dismissed once in the surface's optional `dismissed`
114
+ list (`{query, reason}`, reason at most 256 characters, "out of scope" is
115
+ not a reason) instead of one exclusion per file. Recorded axis queries and
116
+ escape-rule hits cannot be dismissed, nor can a query reaching fewer than 4
117
+ files outside the diff (the likeliest sibling signal); at most 128
118
+ dismissals. Reviewers see each dismissal with its hit count, flagged when it
119
+ hid a file an earlier `SURFACE_UNCLASSIFIED` block named.
108
120
  Results are cached by HEAD, base, diff, query set and config hash.
109
121
  - Review returns NOT_RUN with: `SURFACE_MISSING` (no or unparseable surface;
110
122
  also refused at create for non-DEBUG tasks), `SURFACE_UNCLASSIFIED`,
111
123
  `SURFACE_QUERY_TOO_BROAD` (one recorded query over 200 files),
112
124
  `SURFACE_EXCLUSION_TOO_BROAD` (one glob over 10 files, or any file in the
113
- diff), `SCENARIO_MISSING`, `SURFACE_BUDGET_EXCEEDED` (120 s total, never
125
+ diff), `SURFACE_DISMISSAL_TOO_BROAD` (over 128 dismissals),
126
+ `SURFACE_DISMISSAL_INVALID` (a recorded or rare query), `SCENARIO_MISSING`, `SURFACE_BUDGET_EXCEEDED` (120 s total, never
114
127
  silently skipped) or `SURFACE_UNASSIGNED` (children's covers differ from the
115
128
  parent's included list; checked by every review, including advance and batch).
116
129
  - A surface revision is a contract revision: fresh evidence and two fresh
@@ -122,6 +135,95 @@ Every new task MUST record a surface audit of where else its change lands before
122
135
  both rounds' residual risks and non-blocking findings, references it in the
123
136
  git note and prints the residual risks.
124
137
 
138
+ ## EVIDENCE-ESCAPE-001
139
+
140
+ Every DEBUG fix MUST declare where its bug came from before review, and a declared escape MUST be linked, labelled and recorded mechanically.
141
+
142
+ - Trigger: A DEBUG hypothesis is confirmed, or a normal task fixes a bug that passed earlier gates.
143
+ - Action: Declare `origin` with `task debug --debug-action origin --payload-file <json>`: `{"kind": "escape-of", "commit": "<commit>", "label": "<label>"}` (optional `"receipt"`), or `{"kind": "pre-existing" | "external", "reason": "..."}`. A normal task may opt in with `task create|revise --escape-of <commit> --escape-label <label> [--escape-receipt <id>]`. Commit the `.agent-ops-escapes/<task-id>.json` record with the fix.
144
+ - Evidence: `origin` is bound into the task contract hash; finish, `task complete` and the completion gate refuse a DEBUG task created after this rule without it as `ESCAPE_ORIGIN_MISSING`; both reviewers receive the link state, labels, facts and residual risks under the `escape-label` criterion.
145
+ - Positive: `Hypothesis confirmed; origin escape-of 864dbbe2 label surface; replay marks the missed page surface-unseen; the record is committed with the fix.`
146
+ - Negative: `Finish a DEBUG fix without an origin, or relabel a surface-excluded miss as review because the reviewer "should have noticed".`
147
+
148
+ - The declaration comes after a confirmed hypothesis (`ESCAPE_ORIGIN_EARLY`
149
+ otherwise), inside the DEBUG budget. It is a contract revision: re-verify,
150
+ re-record the confirmed hypothesis with the new evidence, then review.
151
+ Re-declaring replaces the record. The output lists `git blame` hint commits
152
+ for lines the fix changed or removed; blame is a hint only, because an
153
+ omission bug lives in lines nobody wrote.
154
+ - Finish receipts stay local in the Git common directory. Schema 2 records
155
+ every commit in target..candidate and a per-file diff fingerprint (blob ids
156
+ and hunk positions dropped, so a squash merge keeps it); schema 1 receipts
157
+ still load and link by exact head only.
158
+ - Link states are counted separately: `gated` (a receipt matched),
159
+ `unresolved` with a reason (`receipt-not-local` when a Git note or
160
+ `--escape-receipt` names a receipt this machine lacks, `ambiguous-receipt`,
161
+ `link-unavailable`) and `ungated` (no receipt and no note). Resolution
162
+ order: `--escape-receipt` override, the commit inside a receipt's recorded
163
+ range (schema 1: exact head), per-file fingerprint match, then unresolved or
164
+ ungated.
165
+ - Label: one primary label, the earliest gate that could have caught the
166
+ escape — `requirement`, `surface`, `scenario`, `criteria`, `verify`,
167
+ `review` — or `flagged` (a residual risk or finding already said it) or
168
+ `out-of-model`. The agent proposes it; `git grep -F` replay of the linked
169
+ receipt's recorded surface queries at its candidate marks each file the fix
170
+ touched as included, excluded, hit, unseen or absent, and `surface-excluded`
171
+ or `surface-unseen` overrides any later label. The two reviewers adjudicate.
172
+ - The ledger is git-tracked and data only (commits, paths, labels, reasons,
173
+ counts; never file contents or transcripts), one file per task so parallel
174
+ worktrees never conflict. Gate catches (`SURFACE_*` and `SCENARIO_MISSING`
175
+ review blocks, review FAIL, verify red to green) append advisory local-log
176
+ `gate-catch` events with only the code and task id; logging fails open,
177
+ while the origin requirement fails closed.
178
+ - Scope R1 records. Rules learned from escapes, replay proof, backtests,
179
+ `--escape-fix` and an `agent-ops escapes` report are R2
180
+ ([EVIDENCE-ESCAPE-002](#evidence-escape-002)).
181
+
182
+ ## EVIDENCE-ESCAPE-002
183
+
184
+ A surface escape MUST become a proven, tracked rule before its fix finishes, and learned rules MUST only tighten the surface gate.
185
+
186
+ - Trigger: A declared escape-of origin (EVIDENCE-ESCAPE-001), or a past escape backfilled with `task create --escape-of <commit> --escape-label <label> --escape-fix <fix-commit>`.
187
+ - Action: For a `surface`, `surface-unseen` or `surface-excluded` label, commit a rule `.agent-ops-escapes/rules/<rule-id>.json` shaped `{"id", "escape", "label", "trigger": {"paths", "tokens"}, "expand": {"paths", "queries"}, "noExclude"}` and re-declare the origin. For `criteria` or `verify`, name the fixing task's red-to-green check with `--escape-promote <runnerId:checkId>` (DEBUG payload `"promote"`). Other labels record a lesson.
188
+ - Evidence: Finish, `task complete` and the completion gate re-run the proof and refuse `ESCAPE_RULE_UNPROVEN`, `ESCAPE_RULE_TOO_BROAD` or `SURFACE_BUDGET_EXCEEDED`; the ledger record stores the proving rule, its content hash and its backtest fires, commits and rate.
189
+ - Positive: `Escape surface-unseen; rule image-size-siblings fires on the escaped commit, its query hits both missed sibling pages there, and fires on 2 of the last 200 commits.`
190
+ - Negative: `Finish a surface escape whose rule never fires on the escaped commit, or add a rule field that excludes paths.`
191
+
192
+ - Rules are data only and need no trust: triggers and expands become argv
193
+ `git grep -F` queries and path globs, never shell or regex. The strict schema
194
+ has no field that removes a query, adds an exclusion or relaxes any gate.
195
+ An invalid rule fails closed as review NOT_RUN `ESCAPE_RULE_INVALID`; a
196
+ symlinked or non-regular rules directory or file as `ESCAPE_RULE_UNSAFE`.
197
+ - Surface gate: a rule fires only when the task diff matches a trigger path
198
+ glob or a changed line contains a trigger token. Every expand hit of a fired
199
+ rule must be in the diff, included, UNKNOWN or excluded, else
200
+ `SURFACE_UNCLASSIFIED`; with `noExclude` an excluded hit is
201
+ `ESCAPE_RULE_NO_EXCLUDE`. Fires and included/excluded counts per rule go to
202
+ local-log `escape-rule` events (fail-open).
203
+ - Proof: the rule must name the escaped commit, fire on that commit's own diff
204
+ and, replayed at that commit, hit every missed path that existed there.
205
+ Missed paths come from the fix commit with `--escape-fix`, otherwise from
206
+ the task diff. A `criteria`/`verify` escape needs its promoted check to be a
207
+ `redCheckIds` entry of a proven behavioral criterion of the fixing task
208
+ (red baseline, green candidate); the output prints a config proposal for a
209
+ new required verifier, and agent-ops never writes `.agent-ops/config.json`.
210
+ `scenario`, `review`, `requirement`, `flagged` and `out-of-model` record an
211
+ unproven lesson with a reason and do not block. No review or test ever runs
212
+ at the escaped commit.
213
+ - Backtest: the trigger is matched against the diffs of the last 200
214
+ first-parent commits in one argv `git log`; a fire rate above 30% is
215
+ `ESCAPE_RULE_TOO_BROAD`. It is time-budgeted (over budget is
216
+ `SURFACE_BUDGET_EXCEEDED`, never a silent pass) and cached by HEAD and rule
217
+ hash. Editing a proving rule makes the ledger record stale until re-declared.
218
+ - `agent-ops escapes [--json]` is a read-only, fail-open report: misses per
219
+ label from the ledger, `gate-catch` codes from the local log, origin mix,
220
+ link-state mix with unresolved reasons, and per-rule fire/included/excluded
221
+ counts with time windows, as raw counts with n and `insufficient-data`
222
+ when n < 10. Rules with at least 10 fires and no included hit are listed as
223
+ retirement candidates; removal is always a reviewed commit, never automatic.
224
+ - R2 supersedes the phase-2 `surface.aliases` config (now tracked rules) and
225
+ `surface stats` (now `agent-ops escapes`).
226
+
125
227
  ## EVIDENCE-AGGREGATE-001
126
228
 
127
229
  The verifier MUST return FAIL when a criterion is missing, duplicated, unknown, or has empty evidence.
@@ -109,7 +109,7 @@ The current registration matrix is intentionally asymmetric:
109
109
  | office-presence (Preview) | degraded | degraded | supported | degraded |
110
110
  | lifecycle-summary | degraded | supported | supported | degraded |
111
111
  | command-policy | supported | unknown | supported | supported |
112
- | completion-gate | supported | unsupported | unsupported | unsupported |
112
+ | completion-gate | supported | unsupported | supported | unsupported |
113
113
  | optional-stop-verify | degraded | unsupported | supported | degraded |
114
114
 
115
115
  For runtime-failure handling, only `command-policy` is fail-closed. Claude
@@ -191,6 +191,31 @@ removes only `run` and keeps `loop`.
191
191
  - Positive: `A Claude Code session with the run profile writes .agent-ops/state/run-goal.md in the main checkout and starts agent-ops run --host claude --wait in the background.`
192
192
  - Negative: `Split an eight-criteria change into subtasks while the run profile is active, add auto-run text to GEMINI.md, or resume a blocked run without the user.`
193
193
 
194
+ `run status` includes `recovery` in JSON and the same guidance in text: phase
195
+ (unknown for legacy records), original bounded redacted diagnostic, sealed proof
196
+ (`recorded-unchecked` is an observation, not validation), cleanup state,
197
+ resumability and concrete remediation. An unchanged cleanup failure retains its
198
+ original cause. Trust, native identity, generation and denial failures remain
199
+ fail-closed; a sealed proof never erases a native or organization denial.
200
+
201
+ Manual resume of a receipt-bound integration validates the exact sealed proof,
202
+ receipt digest and transaction, owner/generation, candidate/target ancestry and
203
+ Git note before cleanup. It executes only missing note, gate, trust and checkout
204
+ cleanup steps; it preserves existing receipt bytes and completed task/proof work.
205
+ A missing unrecorded note may be bound to the sealed receipt; a missing or changed
206
+ recorded note blocks. Completed cleanup requires the owned checkouts to be gone.
207
+ The target is never moved again. A changed target is accepted only as a descendant
208
+ of the receipt-bound candidate with recorded integration history.
209
+
210
+ Cleanup records a bounded redacted original failure and a retry-input digest of
211
+ the transaction boundary, checkout status, untracked file metadata and heartbeat
212
+ liveness. Identical inputs return `RUN_CLEANUP_UNCHANGED` before repeating cleanup;
213
+ a remediation delta permits a fresh attempt after all safety checks. This digest
214
+ is a retry guard, not verification reuse or new authority. Finalization failure
215
+ does not immediately replay the failed integration: it preserves the original
216
+ cause for manual recovery. Live/unknown/forged/symlink heartbeats and unrelated
217
+ user files retain the existing non-force removal protections.
218
+
194
219
  ## HARNESS-ADAPTER-008
195
220
 
196
221
  `agent-ops office` (Preview) MUST show progress read-only from agent-ops state alone. The
@@ -14,8 +14,12 @@
14
14
  goals. Same-host writers use isolated worktrees and current generation leases;
15
15
  the coordinator counts toward the maximum two writers. Dependencies become
16
16
  available only through frozen deliveries; child baselines follow those commits.
17
- - The default 60-minute budget counts the union of active intervals, including
18
- setup, proof, review and integration. Resume keeps elapsed time and usage epochs.
17
+ - New runs have no total time cap (`budget.limitMs: null`). Active interval unions
18
+ still measure setup, proof, review and integration. Legacy finite runs upgrade
19
+ only on manual resume, retaining the old limit, intervals, elapsed time, usage
20
+ epochs and blocker history. Reads and installation never upgrade or awaken runs.
21
+ Command/review timeouts, provider quotas, DEBUG budgets and no-progress/stop
22
+ controls remain independent and effective. Explicit --time-budget is rejected.
19
23
  Missing counters remain UNKNOWN; partial usage is not a complete cost estimate.
20
24
  - Questions pause work and require an explicit answer. Repair preserves the goal
21
25
  and records failures; two identical rounds without progress stop that worker
@@ -38,17 +42,41 @@
38
42
  setup requires explicit resume and retains its checkout and failure artifact.
39
43
  - A coordinator may assess additional fixed non-dangerous capabilities only under
40
44
  a run-scoped policy bound to the original repository trust, executable runtime
41
- and remaining budget. Explicit native or organization denial cannot be bypassed.
45
+ and a finite one-hour authorization window. Explicit native or organization denial cannot be bypassed.
42
46
  Policy changes fence all writers, preserve frozen deliveries and journal contract
43
47
  synchronization before new generations acquire leases. This never grants global
44
48
  repository trust. Native decisions retain redacted command scope and rationale;
45
49
  absent provider evidence remains UNKNOWN.
46
- Explicit resume renews expired authorization from the remaining budget and
47
- reconciles immutable renewal lineage before policy synchronization. An answer
48
- uses the same recovery checks; neither action can revive an explicit denial.
50
+ Active execution automatically renews an expired grant only when the original
51
+ repository trust, config, executable runtime and operation scope still match.
52
+ Renewal is digest-bound to its predecessor, preserves assessments, rejects
53
+ invalid/backward clocks, and loses to concurrent stop, denial or scope changes.
54
+ Changed/revoked authority requires genuine authorization through the existing
55
+ trust/resume process; renewal never grants permanent trust or clears denial.
56
+ Explicit resume reconciles immutable renewal lineage before policy synchronization.
57
+ An answer uses the same recovery checks; neither action can revive an explicit denial.
58
+ `run resume <id> --retry-approval <auth-event-id>` MAY explicitly retry a
59
+ Codex automatic approval review that failed with its usage-limit wrapper.
60
+ Each selected failure MUST retain its original private artifact, digest,
61
+ worker identity and policy lineage; unrelated or genuine denials still block.
62
+ Repeat the flag for multiple failures. Successful acknowledgements are audited
63
+ and revalidated on later resumes. This grants no command permission: native
64
+ approval runs again. Existing writer-death, checkout, trust and budget checks apply.
65
+ Initial recovery after a current manual resume MAY ignore an owned Codex limit
66
+ snapshot received before activation whose native update second strictly predates
67
+ that resume. Automatic restarts, unknown/equal/future timestamps, clock rollback,
68
+ and every limit received after activation starts remain authoritative. Native
69
+ activation MUST acknowledge an active goal before starting or steering a turn.
70
+ Manual resume releases derivative `RUN_POLICY_DISABLED` task blocks while
71
+ preserving IDs, accounting, history and unrelated product failures.
49
72
  - Convergence compares actual per-check statuses and outstanding finding pins.
50
73
  Source fingerprints, timing and diagnostics alone cannot establish progress.
51
74
 
75
+ With `jobs=1`, child execution MUST wait for confirmed coordinator process death.
76
+ The coordinator retains its task and native session identity, and resumes under a
77
+ new generation after child deliveries. Native registration, recovery and start
78
+ MUST enforce at most one active agent; changing task slot accounting alone is insufficient.
79
+
52
80
  This module defines the bounded loop used to plan, implement, verify, and hand off work.
53
81
 
54
82
  ## LOOP-START-001
@@ -10,6 +10,8 @@ An independent reviewer MUST receive a minimal packet containing the request, cr
10
10
  - Positive: `Packet contains recorded task intent, criteria, files, and evidence requirements.`
11
11
  - Negative: `Forward the complete session transcript and environment.`
12
12
 
13
+ Large surface audits, including complete revision history, discovery and post-block exclusions, may use a digest-bound reference to an exact normalized match in the validated snapshot contract manifest. Both review rounds must read the complete manifest surface. The 64 KiB inline packet and 512 KiB manifest bounds remain enforced; small and legacy packets retain inline data.
14
+
13
15
  ## REVIEW-RESULT-001
14
16
 
15
17
  A review result MUST preserve PASS, FAIL, or NOT_RUN and MUST NOT convert NOT_RUN into PASS.
@@ -57,6 +59,10 @@ Raw reviewer output remains bounded and unstreamed. SIGINT or SIGTERM aborts
57
59
  the active process tree without fallback or attestation; timeout remains a
58
60
  distinct NOT_RUN reason rather than being flattened to `missing-cli`.
59
61
 
62
+ agy may remain silent throughout a generation. Its review and resumed answer
63
+ MUST NOT be cancelled solely for missing output; the configured round timeout
64
+ and caller cancellation remain effective.
65
+
60
66
  ## REVIEW-CHAIN-001
61
67
 
62
68
  The two planned sessions MUST be ordered as a necessary review followed by an
@@ -99,7 +99,13 @@ diagnostic。
99
99
  Capability check 與模型啟動進度都寫到 stderr,包括 `--json` 模式;stdout
100
100
  仍只有最終 JSON envelope,且不會串流 reviewer 原始輸出。SIGINT 或 SIGTERM
101
101
  會終止目前 reviewer 的完整 process tree、不進入 fallback,也不寫入
102
- attestation。整條 chain 逾時時回報 `timeout`,不會誤報 `missing-cli`。
102
+ attestation。整條 chain 逾時時回報 `timeout`,不會誤報 `missing-cli`。每輪
103
+ reviewer 預設最多 30 分鐘(可用 `reviewRoles[].timeoutMs` 覆寫);在 stall 視窗內
104
+ 完全沒有輸出的 reviewer 仍會提早停止。
105
+
106
+ Acceptance runner 的步驟若未設定自己的 `timeoutMs`,`setup` 為 10 分鐘,
107
+ `build`、`testBuild` 與 runner 本身各 5 分鐘,git checkout 為 1 分鐘。逾時的步驟
108
+ 回報為 `UNKNOWN`,並指出是哪個步驟、上限多少,以及要調整哪個 `timeoutMs` 欄位。
103
109
 
104
110
  task ID 必須明確指定,且永遠使用該 task 的原始 criteria;不能用 session fallback
105
111
  或 criterion filter 取代需求。review 會在 adversarial session 前、以及寫入證據前
@@ -174,6 +180,13 @@ fingerprint,因此兩個對話修改同一個 checkout 會互相作廢對方
174
180
  `.worktreeinclude`(gitignore 語法,例如 `.env` 或 `local.properties`)比對到
175
181
  的檔案;Git 已 checkout 的檔案一律不覆寫。只有主 checkout 已 trusted 且
176
182
  worktree 的 effective config 完全相同時才繼承 trust。
183
+ - 在主 checkout 核准的 `agent-ops update` 會把新 config 複製到副本仍是先前已
184
+ 信任版本的每個 session worktree,並以相同指令信任它;確認前 plan 會列出這些
185
+ session worktree。手動修改過的 worktree config 不會被覆寫,run 的 worktree 也
186
+ 保留自己的授權。舊 config 下建立的 task 不會自動重新綁定:
187
+ review 會列出可重新綁定的
188
+ `agent-ops task revise --task <id> --expected-contract <hash> --reason <text>`
189
+ (criteria 與 surface 不變),之後再重新 verify。
177
190
  - `setup` 指令在新 worktree 中執行(預設 timeout 十分鐘),處理 Git 不會帶過去
178
191
  的東西,例如已安裝的相依套件。它屬於 trusted config 的一部分,不需另外核准;
179
192
  任一步驟失敗會移除該 worktree。
@@ -223,7 +236,7 @@ fingerprint,因此兩個對話修改同一個 checkout 會互相作廢對方
223
236
  詢問一次。
224
237
  - 在 worktree 裡對每個 task 執行 verify 與 review,但不要執行 `task complete`
225
238
  (Claude Code 在隔離的 worktree session 中會拒絕它)。`agent-ops worktree finish
226
- <name>` 會在任何 rebase 之前 complete worktree 內每個未封存的 task,先 subtask
239
+ <name>` 會在合併之前 complete worktree 內每個未封存的 task,先 subtask
227
240
  後 parent,各自使用其 PASS review 記錄的 base(沒有記錄時使用 worktree 的 base)。
228
241
  任一 task 無法完成時不會合併,錯誤訊息會指出是哪個 task。建立 subtask 時 session
229
242
  維持附著在 task 樹最上層,且每個 task 各自保留 review 紀錄,所以在同一份原始碼上
@@ -241,8 +254,11 @@ fingerprint,因此兩個對話修改同一個 checkout 會互相作廢對方
241
254
  finish。主 checkout 就在 target branch 上時,合併會更新它的檔案,所以那裡有未
242
255
  commit 的變更會擋住合併;主 checkout 在其他 branch 或 detached 時,只移動
243
256
  target 的 ref,checkout、檔案與未 commit 的變更都不會被動到。Target 若被其他
244
- worktree checkout 則拒絕,並指出該路徑。Target 若已前進會先 rebase;沒有衝突且自身 patch 不變的 rebase 會先
245
- 重新驗證再合併;衝突則連同先合併那份工作在 `refs/notes/agent-ops` 的意圖一起
257
+ worktree checkout 則拒絕,並指出該路徑。Target 若已前進,會 rebase worktree 後以
258
+ `WORKTREE_REBASED` 停下,不 complete 任何 task:先前的證據涵蓋的是舊 base,
259
+ 不是即將合併的組合。以印出的 `--base` 重新 verify 與 review,再執行一次 finish;
260
+ 已 complete 的 task 不能再記錄證據,需以 follow-up task 涵蓋 rebase 後的變更。
261
+ 衝突則重設並連同先合併那份工作在 `refs/notes/agent-ops` 的意圖一起
246
262
  回報。Note 會記錄 worktree 的每個 task,subtask 縮排在其 parent 之下,並附上
247
263
  一行 `session: <id>`,標明完成這次 finish 的 session。Finish 也會把該 session
248
264
  的 gate baseline 重設為合併後的原始碼,所以即使 task 現在只存在於 note 裡,
@@ -48,11 +48,23 @@ Claude、Codex 與 agy 都使用可信 native session lifecycle,在 `UserPromp
48
48
  中斷且沒有封存結果的操作,必須等持久化 process identity 證實程序已死亡後,
49
49
  才封存 UNKNOWN environment receipt;這段經過時間仍會保留,不會退還不明時間。
50
50
  測試材料修改不算修復輪;兩輪停滯需要一次實質策略切換,再兩輪停滯停止。
51
+ 範圍改版會讓現有證據失效、而驗證在登記策略切換前仍停止,因此策略切換可引用同一原始任務已封存的歷史回歸證據;假設確認與最終交付仍需新版契約的新證據。
52
+ 達到回合上限後,未變更的候選仍可審查;上次驗證通過時也可重新驗證(例如只更新 escape ledger),不計為新回合。驗證失敗或產品內容變更的候選仍維持停止。
53
+
54
+ 假設確認後以 `origin --payload-file <json>` 宣告 bug 來源:`{"kind": "escape-of",
55
+ "commit": "<commit>", "label": "<最早關卡>"}`(可選 `"receipt"`),或 `{"kind":
56
+ "pre-existing" | "external", "reason": "..."}`。它會修訂 contract,因此 review 前要重新
57
+ verify 並重新記錄已確認的假設;沒有它時 finish 以 `ESCAPE_ORIGIN_MISSING` 拒絕。
58
+ `escape-of` 會印出連結狀態與 `git blame` 提示,並寫入 `.agent-ops-escapes/<task-id>.json`,
59
+ 與修復一起 commit(見 `EVIDENCE-ESCAPE-001`)。surface 標記還需要一條在被逃逸 commit
60
+ 重放成立、受追蹤的 `.agent-ops-escapes/rules/<rule-id>.json` 規則;criteria/verify 標記需要
61
+ `"promote": "<runnerId:checkId>"`;否則 finish 以 `ESCAPE_RULE_UNPROVEN` 拒絕(見
62
+ `EVIDENCE-ESCAPE-002`)。
51
63
 
52
64
  checkpoint 保存 task/session/source/contract/config/cause;resume 只接受同一
53
65
  擁有者 worktree 的匹配 checkpoint,保留 dirty 內容及預算。失配需要人類確認。
54
- 時間耗盡後明確「繼續」可透過 `extend --event-id latest` 讀取原生人類事件,
55
- 一次增加 20 分鐘;沒有可信事件来源則回報 unsupported,其他阻礙不被解除。
66
+ 時間耗盡後明確「繼續」或「繼續修復」可透過 `extend --event-id latest` 讀取原生人類事件,
67
+ 從該事件取得完整 20 分鐘,並以 grant 快照保留既有消耗與超時;沒有可信事件來源則回報 unsupported,其他阻礙不被解除。
56
68
 
57
69
  Claude / agy / 原生 Codex 的 Stop 都會檢查無 Git 差異的 active DEBUG task,不論是否安裝 completion gate。
58
70
  DEBUG gate 故障先針對 task/config 重新載入一次;仍失敗則明確回報 `UNKNOWN/未完成`
@@ -64,3 +76,8 @@ Codex 的一般 completion gate 仍 unsupported;DEBUG 專用 Stop 以原生
64
76
  只承諾前景對話與持久化進度,不承諾對話關閉後繼續,也不宣稱抵擋同檔案權限攻擊。
65
77
 
66
78
  完整命令及細節見英文 [Task DEBUG](../../en/guides/task-debug.md)。
79
+
80
+ 原生人類明確要求「取消時間限制」或 `no time limit` 時,可透過同一個
81
+ `extend --event-id latest` 原生授權入口取消原任務總時限。grant 記錄
82
+ `grantedMs: null` 與已用時間快照;原預算、消耗、舊 grant、回合限制及
83
+ 驗證與 review 關卡均保留。個別命令與 review 的防卡死逾時仍有效。
@@ -12,6 +12,7 @@
12
12
 
13
13
  - `behavioral`:指定 red checks 在 baseline 都因斷言失敗,candidate 的必要 checks 全部通過。`invariant`:candidate 的必要 checks 通過,baseline 原本 PASS 有效。`review-only`:兩輪 fresh review 對照原始目標驗收,不宣稱機械證明。
14
14
  - repo 授權的 `verification.acceptanceRunners` 定義 argv、setup、產品與 test build。task 提供穩定 check IDs 與明列且已 commit 的 test/fixture/helper;兩側各自安裝並 build 其版本,再覆蓋 candidate 材料。task 不能改 runner 命令。
15
+ - generic runner 輸出的 check IDs 必須恰好等於共用相同 runner、baseline 與材料之 criteria 所要求的 `checkIds` 聯集;多出的列為 UNKNOWN。若 runner 固定輸出整套 checks,就綁定完整輸出集合,並將 `redCheckIds` 限於實際回歸斷言。
15
16
  - fixture、collection、build、timeout、取消、輸出截斷、缺少或重複 ID、retry、skip MUST NOT 算 red 或 green。完整 execution artifacts 以摘要綁定契約、材料與 commits。
16
17
  - 原生 Jest JSON 與 Vitest task errors 無法完整區分 test-call 斷言與 hook/fixture cleanup。除非已 review 的 repo collector 提供明確斷言分類,失敗列 MUST 保持 UNKNOWN;AssertionError 名稱、matcher 資料與 pass 的 hook 狀態都不足。green 需要明確的單次 attempt 證據:attempts、Jest invocations,或 Vitest retryCount 與 repeatCount 兩者。原生 Vitest JSON 省略這些 counters,不能單獨提供機械證明。pytest 每個 nodeid 必須有一組依序的 setup/call/teardown;Rust protocol 必須提供 attempts。缺 metadata MUST NOT 預設為一次成功。
17
18
  - baseline 固定為建立 commit;finding pin 使用被 FAIL 的 candidate。revise/replan 保留原始目標、全部映射要求與先前契約/證據。新契約必須重新取證並取得兩輪 fresh review。
@@ -20,7 +21,7 @@
20
21
 
21
22
  task state 寫入 version 2、讀取 version 1;evidence version 4 讀取舊證據,attestation version 3 綁定契約與 coverage。legacy criteria 維持下列 verifier 規則;typed/revised 契約不能沿用舊 review。coverage 分列機械證明、review-only、legacy;runner 綁定本身不算證明。明確 no-change proof 列出固定 candidate 上已 commit 的 regular source files;整合時重新解析支持路徑。一般 empty-diff review 與 empty-branch direct finish 仍拒絕。
22
23
 
23
- English source version: 2026-10-06. Revalidate: when the English specification changes.
24
+ English source version: 2026-10-20. Revalidate: when the English specification changes.
24
25
 
25
26
  ## EVIDENCE-CRITERION-001
26
27
 
@@ -73,13 +74,20 @@ English source version: 2026-10-06. Revalidate: when the English specification c
73
74
  不以 task 文字組 regex),由便宜的來源先跑:記錄的查詢;diff hunk header 的外層
74
75
  函式名;template literal 固定片段(至少 4 字元且以分隔符界定,例如 `order:`、
75
76
  `user_`、`menu.`);新增與刪除行的複合識別字(snake_case、camelCase 或含數字,
76
- 因此一般文字單字不會成為查詢)與字串常值(至少 6 字元;命中超過 30 個檔案視為
77
- 太通用而略過)。diff 與 surface 清單之外的任何命中都會擋下 review。
77
+ 因此一般文字單字不會成為查詢)與字串常值(至少 6 字元;命中超過 10 個檔案〈含
78
+ 變更檔案〉視為太通用而略過)。diff 與 surface 清單之外的任何命中都會擋下 review。
79
+ - 衍生查詢(diff 字詞、template 片段或 hunk header 函式名)的命中若只是巧合,可在
80
+ surface 選用的 `dismissed` 清單中以一筆 `{query, reason}` 排除(理由至多 256
81
+ 字元,「out of scope」不是理由),不必逐檔排除。記錄的軸查詢與 escape rule 命中
82
+ 不能排除;diff 以外命中少於 4 個檔案的查詢(最可能是兄弟頁面線索)也不能排除;
83
+ 至多 128 筆。Reviewer 會看到每筆排除與其命中數,若它隱藏了先前
84
+ `SURFACE_UNCLASSIFIED` 阻擋所列的檔案則會標示出來。
78
85
  結果以 HEAD、base、diff、查詢集合與 config hash 快取。
79
86
  - Review 以 NOT_RUN 回報:`SURFACE_MISSING`(沒有或無法解析的 surface;非 DEBUG
80
87
  task 建立時也會拒絕)、`SURFACE_UNCLASSIFIED`、`SURFACE_QUERY_TOO_BROAD`(單一
81
88
  記錄查詢超過 200 個檔案)、`SURFACE_EXCLUSION_TOO_BROAD`(單一 glob 超過 10 個
82
- 檔案,或包含 diff 內的檔案)、`SCENARIO_MISSING`、`SURFACE_BUDGET_EXCEEDED`
89
+ 檔案,或包含 diff 內的檔案)、`SURFACE_DISMISSAL_TOO_BROAD`(超過 128 筆排除)、
90
+ `SURFACE_DISMISSAL_INVALID`(記錄的查詢或稀有查詢)、`SCENARIO_MISSING`、`SURFACE_BUDGET_EXCEEDED`
83
91
  (總計 120 秒,絕不默默略過)或 `SURFACE_UNASSIGNED`(子 task covers 與父 task
84
92
  included 不一致;每次 review 都檢查,包含 advance 與 batch)。
85
93
  - 修訂 surface 等同修訂 contract:需要新的證據與兩次新的 review。在
@@ -90,6 +98,78 @@ English source version: 2026-10-06. Revalidate: when the English specification c
90
98
  - 一般 `worktree finish` 也會寫入與 advance 相同的本機 receipt,包含兩輪的 residual
91
99
  risks 與 non-blocking findings,在 git note 引用它並印出 residual risks。
92
100
 
101
+ ## EVIDENCE-ESCAPE-001
102
+
103
+ 每個 DEBUG 修復 MUST 在 review 前宣告 bug 的來源;宣告的逃逸 MUST 以機械方式連結、標記並記錄。
104
+
105
+ - Trigger: DEBUG 假設已確認,或一般 task 修復一個通過了先前關卡的 bug。
106
+ - Action: 以 `task debug --debug-action origin --payload-file <json>` 宣告 `origin`:`{"kind": "escape-of", "commit": "<commit>", "label": "<label>"}`(可選 `"receipt"`),或 `{"kind": "pre-existing" | "external", "reason": "..."}`。一般 task 可用 `task create|revise --escape-of <commit> --escape-label <label> [--escape-receipt <id>]` 選擇加入。把 `.agent-ops-escapes/<task-id>.json` 記錄與修復一起 commit。
107
+ - Evidence: `origin` 綁進 task contract hash;本規則上線後建立的 DEBUG task 沒有它時,finish、`task complete` 與 completion gate 以 `ESCAPE_ORIGIN_MISSING` 拒絕;兩位 reviewer 在 `escape-label` 條件下收到連結狀態、標記、事實與 residual risks。
108
+ - Positive: `假設已確認;origin escape-of 864dbbe2 label surface;重放把漏掉的頁面標為 surface-unseen;記錄與修復一起 commit。`
109
+ - Negative: `DEBUG 修復沒有 origin 就 finish,或把 surface-excluded 的漏網改標成 review,理由是 reviewer「應該注意到」。`
110
+
111
+ - 宣告必須在假設確認之後(否則 `ESCAPE_ORIGIN_EARLY`),並計入 DEBUG 預算。它是一次
112
+ contract revision:重新 verify、以新證據重新記錄已確認的假設,然後 review。重新宣告會
113
+ 取代記錄。輸出會列出修復所改或刪行的 `git blame` 提示 commit;blame 只是提示,因為遺漏
114
+ 型 bug 存在於沒人寫過的行。
115
+ - finish receipt 留在本機 Git common directory。Schema 2 記錄 target..candidate 的每個
116
+ commit 與逐檔 diff fingerprint(去掉 blob id 與 hunk 位置,squash merge 後仍相同);
117
+ schema 1 receipt 仍可載入,但只以 exact head 連結。
118
+ - 連結狀態分開計數:`gated`(找到 receipt)、帶理由的 `unresolved`(Git note 或
119
+ `--escape-receipt` 指向本機沒有的 receipt 時為 `receipt-not-local`,另有
120
+ `ambiguous-receipt`、`link-unavailable`)與 `ungated`(沒有 receipt 也沒有 note)。
121
+ 解析順序:`--escape-receipt` 覆寫、commit 位於某 receipt 記錄的範圍內(schema 1:exact
122
+ head)、逐檔 fingerprint 相符,最後才是 unresolved 或 ungated。
123
+ - 標記:單一主要標記,取最早能抓到此逃逸的關卡 —— `requirement`、`surface`、
124
+ `scenario`、`criteria`、`verify`、`review` —— 或 `flagged`(residual risk 或 finding 已
125
+ 提過)或 `out-of-model`。由 agent 提議;以 `git grep -F` 在被連結 receipt 的 candidate
126
+ 上重放其記錄的 surface 查詢,把修復碰到的每個檔標為 included、excluded、hit、unseen 或
127
+ absent,`surface-excluded` 或 `surface-unseen` 會覆寫任何較晚的標記。兩位 reviewer 裁決。
128
+ - ledger 受 git 追蹤且只含資料(commit、路徑、標記、理由、計數;絕不含檔案內容或對話紀錄),
129
+ 每個 task 一個檔案,平行 worktree 不會衝突。關卡攔截(`SURFACE_*` 與 `SCENARIO_MISSING`
130
+ review 阻擋、review FAIL、verify 由紅轉綠)會附加僅含 code 與 task id 的參考性 local-log
131
+ `gate-catch` 事件;記錄失敗時 fail-open,origin 要求則 fail-closed。
132
+ - 範圍 R1 只負責記錄。由逃逸學到的規則、重放證明、回測、`--escape-fix` 與
133
+ `agent-ops escapes` 報表屬於 R2([EVIDENCE-ESCAPE-002](#evidence-escape-002))。
134
+
135
+ ## EVIDENCE-ESCAPE-002
136
+
137
+ surface 逃逸 MUST 在修復 finish 前變成已證明、受追蹤的規則;學到的規則 MUST 只能收緊 surface gate。
138
+
139
+ - Trigger: 已宣告的 escape-of origin(EVIDENCE-ESCAPE-001),或以 `task create --escape-of <commit> --escape-label <label> --escape-fix <fix-commit>` 回填的過去逃逸。
140
+ - Action: 標記為 `surface`、`surface-unseen` 或 `surface-excluded` 時,commit 一條規則 `.agent-ops-escapes/rules/<rule-id>.json`,形狀為 `{"id", "escape", "label", "trigger": {"paths", "tokens"}, "expand": {"paths", "queries"}, "noExclude"}`,並重新宣告 origin。`criteria` 或 `verify` 以 `--escape-promote <runnerId:checkId>`(DEBUG payload `"promote"`)指名修復 task 由紅轉綠的 check。其他標記記錄為 lesson。
141
+ - Evidence: finish、`task complete` 與 completion gate 會重跑證明,並以 `ESCAPE_RULE_UNPROVEN`、`ESCAPE_RULE_TOO_BROAD` 或 `SURFACE_BUDGET_EXCEEDED` 拒絕;ledger 記錄保存證明用規則、其內容 hash 與回測的 fires、commits 與比率。
142
+ - Positive: `逃逸 surface-unseen;規則 image-size-siblings 在被逃逸 commit 上觸發,其查詢在該 commit 命中兩個漏掉的兄弟頁面,且在最近 200 個 commit 中只觸發 2 次。`
143
+ - Negative: `規則從未在被逃逸 commit 上觸發就 finish surface 逃逸,或新增可排除路徑的規則欄位。`
144
+
145
+ - 規則只含資料且不需要 trust:trigger 與 expand 變成 argv `git grep -F` 查詢與路徑
146
+ glob,絕不經過 shell 或 regex。嚴格 schema 沒有任何能移除查詢、新增排除或放寬關卡的
147
+ 欄位。無效規則以 review NOT_RUN `ESCAPE_RULE_INVALID` fail-closed;symlink 或非一般
148
+ 檔案的規則目錄或檔案則為 `ESCAPE_RULE_UNSAFE`。
149
+ - Surface gate:只有 task diff 符合 trigger 路徑 glob,或某個變更行包含 trigger token
150
+ 時,規則才會觸發。已觸發規則的每個 expand 命中都必須位於 diff、included、UNKNOWN 或
151
+ excluded,否則為 `SURFACE_UNCLASSIFIED`;有 `noExclude` 時,被排除的命中為
152
+ `ESCAPE_RULE_NO_EXCLUDE`。每條規則的觸發與 included/excluded 計數寫入 local-log
153
+ `escape-rule` 事件(fail-open)。
154
+ - 證明:規則必須指名被逃逸 commit、在該 commit 自身的 diff 上觸發,並在該 commit 重放時
155
+ 命中當時已存在的每個漏掉路徑。有 `--escape-fix` 時漏掉路徑取自 fix commit,否則取自
156
+ task diff。`criteria`/`verify` 逃逸需要其 promoted check 是修復 task 某個已證明
157
+ behavioral 條件的 `redCheckIds` 項目(baseline 紅、candidate 綠);輸出會印出新增
158
+ required verifier 的 config 提案,agent-ops 絕不寫入 `.agent-ops/config.json`。
159
+ `scenario`、`review`、`requirement`、`flagged` 與 `out-of-model` 記錄帶理由的未證明
160
+ lesson,不阻擋。絕不在被逃逸 commit 上執行 review 或測試。
161
+ - 回測:以一次 argv `git log` 把 trigger 比對最近 200 個 first-parent commit 的 diff;
162
+ 觸發比率超過 30% 為 `ESCAPE_RULE_TOO_BROAD`。回測有時間預算(超出為
163
+ `SURFACE_BUDGET_EXCEEDED`,絕不默默通過),並以 HEAD 與規則 hash 快取。編輯證明用規則
164
+ 會讓 ledger 記錄過期,直到重新宣告。
165
+ - `agent-ops escapes [--json]` 是唯讀、fail-open 的報表:來自 ledger 的各標記漏網數、
166
+ 來自 local log 的 `gate-catch` code、origin 組成、帶 unresolved 理由的連結狀態組成,
167
+ 以及每條規則的觸發/included/excluded 計數與時間窗,皆為附 n 的原始計數,n < 10 時標為
168
+ `insufficient-data`。至少觸發 10 次且從無 included 命中的規則列為退役候選;移除一律
169
+ 經過審查的 commit,絕不自動。
170
+ - R2 取代 phase-2 的 `surface.aliases` 設定(改為受追蹤規則)與 `surface stats`
171
+ (改為 `agent-ops escapes`)。
172
+
93
173
  ## EVIDENCE-AGGREGATE-001
94
174
 
95
175
  驗證器 MUST 在條件缺少、重複、未知或證據為空時回傳 FAIL。
@@ -93,7 +93,7 @@ script,也不得改變一般 permission request。
93
93
  | office-presence (Preview) | degraded | degraded | supported | degraded |
94
94
  | lifecycle-summary | degraded | supported | supported | degraded |
95
95
  | command-policy | supported | unknown | supported | supported |
96
- | completion-gate | supported | unsupported | unsupported | unsupported |
96
+ | completion-gate | supported | unsupported | supported | unsupported |
97
97
  | optional-stop-verify | degraded | unsupported | supported | degraded |
98
98
 
99
99
  Runtime-failure 處理中,只有 `command-policy` 為 fail-closed。當已安裝的 config
@@ -164,6 +164,26 @@ byte-identical。Update MUST 保留此 profile,除非提供 `--auto-run on|off
164
164
  - Positive: `啟用 run profile 的 Claude Code session 在 main checkout 寫入 .agent-ops/state/run-goal.md,並在 background 啟動 agent-ops run --host claude --wait。`
165
165
  - Negative: `run profile 啟用時仍將八項 criteria 的變更拆成 subtask、在 GEMINI.md 加入 auto-run 文字,或未經使用者即 resume blocked run。`
166
166
 
167
+ `run status` 的 JSON 提供 `recovery`,文字輸出也呈現相同資訊:phase(舊紀錄為
168
+ unknown)、有界且遮蔽敏感資料的原始診斷、sealed proof(`recorded-unchecked`
169
+ 僅表示紀錄存在,不代表驗證通過)、cleanup 狀態、能否 resume 與具體修復方式。
170
+ 相同 cleanup blocker 保留原始 cause。Trust、native identity、generation 與 denial
171
+ 仍 fail-closed;sealed proof 不得抹除 native 或組織的明確拒絕。
172
+
173
+ 人工 resume 已寫入 receipt 的 integration,必須先驗證原 sealed proof、receipt
174
+ digest 與 transaction、owner/generation、candidate/target ancestry 及 Git note。
175
+ 只執行尚缺的 note、gate、trust 與 checkout cleanup,保留原 receipt bytes 與已完成的
176
+ task/proof。尚未記錄完成且缺失的 note 可補寫;已記錄完成的 note 缺失或變更則阻擋。
177
+ 確認所屬 checkout 已移除後才可標記 cleaned,不再次移動 target。Target 若已前進,
178
+ 僅在它是 receipt-bound candidate 的後代且有原整合歷史時接受。
179
+
180
+ Cleanup 保存有界且遮蔽敏感資料的原始錯誤,以及 transaction boundary、checkout
181
+ status、untracked file metadata 與 heartbeat liveness 的 retry-input digest。
182
+ 相同輸入回 `RUN_CLEANUP_UNCHANGED`,不重複 cleanup;修復條件改變後仍須重新通過所有
183
+ 安全檢查,才可嘗試一次。此 digest 僅防止盲重試,不是 proof reuse 或新授權。
184
+ Finalization 失敗不立即重跑同一 integration,保留原 cause 供人工恢復。
185
+ Live/unknown/偽造/symlink heartbeat 與無關使用者檔案仍受既有 non-force removal 保護。
186
+
167
187
  ## HARNESS-ADAPTER-008
168
188
 
169
189
  `agent-ops office`(Preview)MUST 只依據 agent-ops state 以 read-only 方式呈現進度。
@@ -11,17 +11,23 @@
11
11
  - Negative: 只因 native goal completion 就把 run 標為 complete。
12
12
 
13
13
  - macOS supervisor 在啟動 goal 前保存 Claude/Codex native 身份。同 host writers 使用獨立 worktrees 與目前 generation lease;coordinator 計入最多兩個 writer。依賴以固定交付提供,child baseline 在依賴 commits 進入 checkout 後建立。
14
- - 預設 60 分鐘預算計算 active intervals 聯集,包含 setup、verify、review、整合。resume 保留時間與 usage epochs;缺少計數維持 UNKNOWN,partial usage 不算完整成本。
14
+ - 新 run 不設總時間上限(`budget.limitMs: null`),仍以 active intervals 聯集記錄 setup、verify、review、整合的消耗。舊有限 run 僅在下次人工 resume 升級,保留舊上限、intervals、消耗、usage epochs 與 blocker 歷史;讀取或安裝不會升級或喚醒舊 run。單次命令/review timeout、provider quota、DEBUG 預算、無進度與 pause/stop 控制保持獨立有效。明確指定 --time-budget 會被拒絕。缺少計數維持 UNKNOWN,partial usage 不算完整成本。
15
15
  - 實質疑問暫停並要求明確回答。修復保留目標與失敗紀錄;連續兩次相同失敗且無進展停止該 worker 及其依賴,獨立 task 仍可執行。review findings 在下次 final gate 前必須有回歸 pin 或記錄 review-only fallback。
16
16
  - native completion 僅是觀察。完成必須有必要驗證、兩輪 fresh review、完成的 task state、綁定 target 的 receipt。整合在移動 target 前封存 candidate,記錄 task、receipt、note、cleanup 進度;恢復驗證封存證據,不重做成功的 target mutation。不一致的 target 維持 blocked。
17
17
  - Stop 先保存禁止續跑,再確認受管 process group 死亡。crash recovery 不得取代仍存活或身份不明的 writer。dirty checkout、版本漂移、restart storm 保留現場。重開機/login 改變必須明確 resume;不修改全域 host policy。
18
18
  - Native handshake 前先保存啟動程序身份;尚未開啟的 Codex session 必須證明程序死亡,才可在新 lease 重新初始化。
19
19
 
20
20
  - Setup 與 native agent 發起的 local proof MUST 先登記 dormant process group 再執行;Stop 也要取消子程序。中斷的 setup 必須明確 resume,保留 checkout 與失敗 artifact。
21
- - Coordinator 只能在綁定原始 repository trust、可執行 runtime、剩餘預算的 run-scoped policy 下,評估新增固定且非危險的能力。不得繞過 native 或組織的明確拒絕。Policy 變更先停止所有 writer,保留固定交付,以 journal 記錄 contract 同步,再啟動新 generation;不授予永久 repository trust。Native decision 保存遮罩後的命令範圍與理由,provider 未提供的證據維持 UNKNOWN。
22
- - 明確 resume 從剩餘預算續期過期授權,並先核對不可變 renewal lineage,再同步 policy。回答問題也沿用相同恢復檢查;兩者皆不得復活已被明確拒絕的工作。
21
+ - Coordinator 只能在綁定原始 repository trust、可執行 runtime、一小時有限授權期限的 run-scoped policy 下,評估新增固定且非危險的能力。不得繞過 native 或組織的明確拒絕。Policy 變更先停止所有 writer,保留固定交付,以 journal 記錄 contract 同步,再啟動新 generation;不授予永久 repository trust。Native decision 保存遮罩後的命令範圍與理由,provider 未提供的證據維持 UNKNOWN。
22
+ - 執行中的 run 僅在原始 repository trust、config、可執行 runtime 與操作範圍完全相同時,自動續期過期的有限授權。續期以 digest 綁定前一版本並保留既有評估,拒絕無效/倒退時鐘;並行 stop、denial 或 scope 變更使續期失敗。權限已變更或撤銷時須沿既有 trust/resume 流程取得真正授權;續期不授予永久 trust,也不消除 denial。明確 resume 先核對不可變 renewal lineage,再同步 policy。回答問題也沿用相同恢復檢查;兩者皆不得復活已被明確拒絕的工作。
23
+ - `run resume <id> --retry-approval <auth-event-id>` MAY 明確重試以額度不足 wrapper 失敗的 Codex 自動審批。每筆指定失敗 MUST 保有原始 private artifact、digest、worker identity 與 policy lineage;真正或未指定的拒絕仍阻擋。多筆失敗可重複旗標。成功確認會留存並在後續 resume 重新驗證;此操作不授予命令權限,原生審批必須重跑,既有 writer 死亡、checkout、trust 與預算檢查仍適用。
24
+ - 當次人工 resume 的初始恢復 MAY 忽略啟用前收到、且 native 更新秒數嚴格早於該次 resume 的本執行緒 Codex 額度快照。自動重啟、未知/同秒/未來時間、時鐘倒退,以及啟用開始後收到的所有額度事件仍有效。Native 啟用 MUST 確認 goal 為 active,才能啟動或轉向 turn。人工 resume 可解除衍生的 `RUN_POLICY_DISABLED` task 阻擋,但保留 ID、耗用、歷史及其他產品失敗。
23
25
  - 收斂判斷比較實際 per-check 狀態及未解除的 finding pins;source fingerprint、時間或診斷文字本身不能算進展。
24
26
 
27
+ `jobs=1` 時,child MUST 等 coordinator 程序確認死亡後才執行。coordinator 保留
28
+ task 與 native session identity,在 child 交付後以新 generation 接續。native
29
+ 註冊、恢復與啟動 MUST 都限制最多一個 active agent;僅扣除 task slot 不足以符合。
30
+
25
31
  English source version: 2026-07-23. Revalidate: when the English specification changes.
26
32
 
27
33
  ## LOOP-START-001
@@ -12,6 +12,8 @@ English source version: 2026-09-30. Revalidate: when the English specification c
12
12
  - Positive: `Packet 包含已記錄的 task 意圖、條件、檔案與證據要求。`
13
13
  - Negative: `轉送完整 session transcript 與環境。`
14
14
 
15
+ 大型 surface audit(含完整修訂歷史、discovery 與 post-block exclusions)可使用 digest-bound reference,指向已驗證 snapshot 契約 manifest 中正規化後完全相符的資料。兩輪審查都必須讀取完整 manifest surface。64 KiB inline packet 與 512 KiB manifest 上限仍有效;小型及舊版 packet 保留 inline 資料。
16
+
15
17
  ## REVIEW-RESULT-001
16
18
 
17
19
  審查結果 MUST 保留 PASS、FAIL 或 NOT_RUN,且 MUST NOT 把 NOT_RUN 轉成 PASS。
@@ -58,6 +60,9 @@ tree,不 fallback、不寫 attestation;timeout 保留獨立 NOT_RUN reason
58
60
 
59
61
  ## REVIEW-CHAIN-001
60
62
 
63
+ agy 在生成期間可能完全沒有輸出。review 與接續回答 MUST NOT 僅因沒有輸出而
64
+ 被取消;設定的單輪 timeout 與呼叫者取消仍然有效。
65
+
61
66
  兩個規劃的 session MUST 依序為必要 reviewer 與 adversarial 複審。第一個
62
67
  session 遇到 FAIL 或 NOT_RUN MUST 立即停止;不會在該結果後 fallback。
63
68