@open-agent-toolkit/cli 0.2.22 → 0.2.24

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.
@@ -1,5 +1,5 @@
1
1
  {
2
- "version": "2026-07-25.1",
2
+ "version": "2026-07-27.1",
3
3
  "providers": {
4
4
  "codex": {
5
5
  "economy": {
@@ -115,20 +115,18 @@
115
115
  },
116
116
  "high": {
117
117
  "candidates": [
118
- "gpt-5.6-sol-medium",
119
- "gpt-5.6-sol-high",
120
118
  "claude-opus-5-thinking-medium",
121
- "claude-opus-5-thinking-high"
119
+ "gpt-5.6-sol-medium",
120
+ "claude-opus-5-thinking-high",
121
+ "gpt-5.6-sol-high"
122
122
  ]
123
123
  },
124
124
  "frontier": {
125
125
  "candidates": [
126
- "claude-fable-5-thinking-high",
127
- "claude-fable-5-thinking-xhigh",
128
126
  "gpt-5.6-sol-xhigh",
129
- "gpt-5.6-sol-max",
130
127
  "claude-opus-5-thinking-xhigh",
131
- "claude-opus-5-thinking-max"
128
+ "gpt-5.6-sol-max",
129
+ "claude-fable-5-thinking-high"
132
130
  ]
133
131
  }
134
132
  }
@@ -717,8 +717,21 @@ Each liveness tick keeps stdout-idle time and also reports `processAlive` plus
717
717
  the latest metadata-only transcript activity as `lastActivityEvidence` when
718
718
  available. The probe performs bounded depth-two traversal and compares newest
719
719
  mtime plus total size with its spawn baseline. It never reads transcript
720
- contents, never extends a budget, and never changes pass/fail or receive
721
- eligibility.
720
+ contents and never changes pass/fail or receive eligibility.
721
+
722
+ When the hard timeout fires, OAT stops periodic liveness ticks, sends `SIGTERM`,
723
+ schedules the existing `SIGKILL` fallback, and then starts one final transcript
724
+ observation with the timeout timestamp. Once the child closes, result resolution
725
+ waits no longer than the one-second observation grace and does not delay either
726
+ signal. A final sample available before result resolution supersedes older
727
+ in-flight periodic work; otherwise OAT retains the latest valid periodic
728
+ evidence.
729
+
730
+ On a normal child close, OAT waits within the same one-second grace only when a
731
+ periodic transcript observation is already in flight. This preserves late
732
+ evidence but can add up to one second to an otherwise successful execution. The
733
+ one-second observation grace and five-second force-kill fallback are fixed
734
+ safety bounds, not environment-tunable settings.
722
735
 
723
736
  Claude and Cursor evidence has `scope: project-dir`. Codex's date-sharded
724
737
  sessions directory is shared across the runtime, so its evidence has
@@ -726,7 +739,18 @@ sessions directory is shared across the runtime, so its evidence has
726
739
  attributable to this gate child).” Probe errors fail soft to process and stdout
727
740
  telemetry.
728
741
 
729
- Timeout and child-failure envelopes include the latest `activityEvidence`.
742
+ Timeout and child-failure JSON envelopes include the latest `activityEvidence`.
743
+ For human timeout and non-refusal child-failure output, OAT prints a second line
744
+ with this shape:
745
+
746
+ ```text
747
+ Activity evidence: <runtime> <project|ambient> transcript metadata <changed|did not change> since baseline; observed <milliseconds>ms ago; latest transcript change was <milliseconds>ms before observation.
748
+ ```
749
+
750
+ When the evidence scope is ambient, the line ends with `This activity is not
751
+ attributable to this gate child.` Structured refusals omit the extra human
752
+ diagnostic because the refusal itself explains why execution stopped.
753
+
730
754
  Before spawn, the gate also writes a transient marker under the system temp
731
755
  directory at `oat-gate-runs/<runId>.json`; startup diagnostics print its path.
732
756
  The marker records target, runtime, project, review type/scope, start time,
@@ -76,10 +76,36 @@ To pick up a new version, compare your
76
76
  `workflow.dispatchCeiling.recommendationVersion` against the bundled version,
77
77
  then either edit the affected cells by hand or clear them and re-adopt.
78
78
 
79
- Version `2026-07-25.1` is a live example: it adds Opus 5 rungs to the Cursor
80
- `balanced`, `high`, and `frontier` tiers and drops `claude-sonnet-5-high` from
81
- `economy`. An adopter still on the prior version keeps their existing Cursor
82
- tiers untouched until they take one of those actions.
79
+ Version `2026-07-27.1` is a live example. It interleaves the Cursor `high` and
80
+ `frontier` tiers so each alternates a GPT rung with a Claude rung, ending `high`
81
+ at `gpt-5.6-sol-high` and `frontier` at `claude-fable-5-thinking-high`. It also
82
+ drops `claude-opus-5-thinking-max` and `claude-fable-5-thinking-xhigh` from
83
+ `frontier`. Dropping the Opus max rung follows the non-monotonic top-end Opus
84
+ evidence recorded in `subagent-orchestration/references/evidence-and-refresh.md`,
85
+ which treats max as a route requiring justification rather than a strictly
86
+ better rung. Dropping the Fable xhigh rung is a recommendation judgment rather
87
+ than a measured finding: `subagent-orchestration/references/provider-claude.md`
88
+ permits either Fable rung for a qualified specialist case, and this ladder takes
89
+ the cheaper one absent a comparison favoring xhigh. The evidence record above
90
+ does not compare the two rungs. Both models remain in the pin catalog and stay
91
+ available to a hand-edited ladder. An adopter still on the prior version keeps their existing
92
+ Cursor tiers untouched until they take one of the actions above.
93
+
94
+ The terminal entries in that version are chosen, not incidental. Because the
95
+ final candidate in a tier is the target its implementation-phase self-review
96
+ pins, reordering a tier changes who reviews it even when the membership is
97
+ untouched. Cross-family independence for the external phase gate and the
98
+ lifecycle gate comes from `gates.execTargets` instead, which is configured
99
+ separately and is not drawn from this ladder.
100
+
101
+ Curating a ladder down has a consequence in the other direction. The
102
+ `subagent-orchestration` guidance names a route per task class, and a route you
103
+ prune becomes unreachable: the guidance still recommends it while the resolver
104
+ rejects it as unconfigured. A ladder whose `economy` tier drops its mechanical
105
+ route leaves mechanical work with nowhere to go but a higher tier. Keep at least
106
+ one reachable rung for each task class the project uses, and prefer more than
107
+ one candidate per tier, since a tier holding a single entry cannot express a
108
+ choice.
83
109
 
84
110
  Before offering adoption, planning runs `oat config list --json` once and treats
85
111
  its output as the effective boundary across shared, repo-local, user, and
@@ -213,10 +239,10 @@ candidate in each tier:
213
239
  tiers.
214
240
  - **Cursor:** verified multi-family flat IDs across Composer, Claude (Sonnet,
215
241
  Opus, and Fable), GPT, and Grok. Two counts apply and they differ: the
216
- bundled recommendation carries 16 Cursor candidates across the four tiers,
217
- while the materialization catalogue carries 18 flat IDs. The extra entries
218
- are approved mappings deliberately kept out of the recommendation but still
219
- materializable. The catalogue maps each flat ladder ID to a separate
242
+ bundled recommendation carries 14 Cursor candidates across the four tiers,
243
+ while the materialization catalogue carries 18 flat IDs. The four extra
244
+ entries are approved mappings deliberately kept out of the recommendation but
245
+ still materializable. The catalogue maps each flat ladder ID to a separate
220
246
  bracket-form frontmatter model; OAT does not derive or normalize either
221
247
  value.
222
248
 
@@ -1,6 +1,6 @@
1
1
  {
2
- "cli": "0.2.22",
3
- "docs-config": "0.2.22",
4
- "docs-theme": "0.2.22",
5
- "docs-transforms": "0.2.22"
2
+ "cli": "0.2.24",
3
+ "docs-config": "0.2.24",
4
+ "docs-theme": "0.2.24",
5
+ "docs-transforms": "0.2.24"
6
6
  }
@@ -235,7 +235,7 @@ remains immutable baseline evidence for the original p01-t01 verification.
235
235
  | `oat-project-import-plan/SKILL.md` | `f7ca8635452f -> NG`; `c2e5fa410069 -> NG`; `655d61df0a8f -> NG`; `dceff5cc04b5 -> NG`; `1af4957a1af2 -> IMPORT-01`; `45b699c1c0b5 -> IMPORT-01`; `ba6d120791c1 -> IMPORT-01`; `070ebc5259af -> IMPORT-03`; `c11552696e2e -> IMPORT-03`; `cfe661966baf -> IMPORT-04`; `baa91c0a0bf8 -> NG`; `e364e84b2702 -> NG`; `39031985a945 -> IMPORT-06`; `f106aa29a217 -> IMPORT-07`; `65038450aee3 -> IMPORT-07`; `bee4c4aa34c6 -> NG`; `3f0b53056edd -> IMPORT-09` |
236
236
  | `oat-project-implement/SKILL.md` | `18980f6bc1a6 -> NG`; `ffb3af0ba8ef -> NG`; `e0355c7a05e9 -> IMPLEMENT-11+IMPLEMENT-13+IMPLEMENT-16`; `6296f41ae11c -> NG`; `a167d03559fa -> NG`; `cf317c17c586 -> IMPLEMENT-01`; `8ce8a09feca4 -> NG`; `bd0cb4988188 -> NG`; `28af4ee0055d -> NG` |
237
237
  | `oat-project-implement/references/completion-and-closeout.md` | `f7dab9c1f96c -> IMPLEMENT-12`; `c69c17a069a8 -> IMPLEMENT-14`; `a97fa5634a68 -> IMPLEMENT-14`; `3af58881811c -> IMPLEMENT-14`; `4203e1f49d0f -> IMPLEMENT-14`; `c3bd2458a3d3 -> IMPLEMENT-13`; `95b5eafc070d -> IMPLEMENT-13`; `25ecbe9c998b -> IMPLEMENT-13+IMPLEMENT-14+IMPLEMENT-15+IMPLEMENT-16`; `f6f24fd71da4 -> IMPLEMENT-13+IMPLEMENT-14+IMPLEMENT-15+IMPLEMENT-16`; `f18283bc1cf9 -> IMPLEMENT-13+IMPLEMENT-14+IMPLEMENT-15+IMPLEMENT-16`; `2c1ffc4a82dd -> IMPLEMENT-13+IMPLEMENT-14+IMPLEMENT-15+IMPLEMENT-16`; `3454a07aa843 -> IMPLEMENT-16`; `0d86e2098cfb -> IMPLEMENT-13+IMPLEMENT-14+IMPLEMENT-15+IMPLEMENT-16`; `d5fe597d266f -> IMPLEMENT-13+IMPLEMENT-14+IMPLEMENT-15+IMPLEMENT-16`; `55a152e944c1 -> IMPLEMENT-16`; `effac7cbd573 -> IMPLEMENT-13+IMPLEMENT-14+IMPLEMENT-15+IMPLEMENT-16`; `9d2a34d8b148 -> IMPLEMENT-13+IMPLEMENT-14+IMPLEMENT-15+IMPLEMENT-16`; `d27462aaed26 -> IMPLEMENT-13+IMPLEMENT-14+IMPLEMENT-15+IMPLEMENT-16`; `9d52ecb17268 -> IMPLEMENT-13+IMPLEMENT-14+IMPLEMENT-15+IMPLEMENT-16`; `5b91aabe3757 -> IMPLEMENT-13+IMPLEMENT-14+IMPLEMENT-15+IMPLEMENT-16`; `fd0ad919f702 -> IMPLEMENT-13+IMPLEMENT-14+IMPLEMENT-15+IMPLEMENT-16`; `63bf28df1474 -> IMPLEMENT-13+IMPLEMENT-14+IMPLEMENT-15+IMPLEMENT-16`; `a4ed471dbc78 -> IMPLEMENT-16`; `6b7a64cec6e5 -> IMPLEMENT-16`; `0a4fdba0ebc0 -> IMPLEMENT-13+IMPLEMENT-14+IMPLEMENT-15+IMPLEMENT-16`; `a5033c2aada5 -> IMPLEMENT-13+IMPLEMENT-14+IMPLEMENT-15+IMPLEMENT-16`; `e77609eddba0 -> IMPLEMENT-13+IMPLEMENT-14+IMPLEMENT-15+IMPLEMENT-16`; `351156e8dde4 -> IMPLEMENT-13+IMPLEMENT-14+IMPLEMENT-15+IMPLEMENT-16`; `51d45bd2bbd1 -> IMPLEMENT-16`; `f7796ffcc804 -> IMPLEMENT-16`; `990d730cb494 -> IMPLEMENT-16`; `6ed28bb7d384 -> IMPLEMENT-16`; `8b7d4b5bcf1b -> IMPLEMENT-16`; `88aad500e6e9 -> IMPLEMENT-16`; `877e3e3f9eda -> IMPLEMENT-16`; `fc03c97f834e -> IMPLEMENT-16`; `12939a3da5e0 -> IMPLEMENT-16`; `bdb418335a88 -> IMPLEMENT-16`; `fba97e596ebd -> IMPLEMENT-16`; `3d0b5e2f14f0 -> IMPLEMENT-17`; `87f1424a8692 -> NG`; `6b1ec05182f0 -> IMPLEMENT-11`; `e6d696a27c91 -> NG`; `c77f8ccb52ad -> NG`; `48de2614c0ba -> IMPLEMENT-11`; `32d53f5212e5 -> IMPLEMENT-11`; `7cdb4a9c57b7 -> IMPLEMENT-11`; `16ffc0aa099b -> IMPLEMENT-11`; `d6868ea10b3f -> IMPLEMENT-11`; `4f05ff5567be -> IMPLEMENT-11`; `c70b47ae7a6d -> IMPLEMENT-11`; `5fafd093b58e -> NG`; `567d43ab0c2e -> NG`; `21ceaf7e658a -> NG`; `249427a9f475 -> NG`; `8a7ec13a9b7c -> NG`; `9aeb7fce2012 -> IMPLEMENT-18`; `f11a7cdda220 -> IMPLEMENT-18`; `4523ac029152 -> NG`; `6e87b08c4046 -> NG`; `baa6052c7f0a -> IMPLEMENT-18`; `27d3fad116b1 -> IMPLEMENT-18`; `2cfbeb4388a5 -> IMPLEMENT-18`; `c56ea56a56db -> NG`; `43e2e3c1380d -> IMPLEMENT-17`; `b49690277fb5 -> NG`; `df12304d6a36 -> NG`; `52eacac11fef -> IMPLEMENT-17`; `60092df6b17b -> IMPLEMENT-17`; `361872c6b00e -> IMPLEMENT-17`; `d2bc711a75fb -> IMPLEMENT-17` |
238
- | `oat-project-implement/references/dispatch-and-dry-run.md` | `21b85f5e4daa -> IMPLEMENT-08`; `74c92b32bb2a -> IMPLEMENT-08`; `8efd2d0517ab -> IMPLEMENT-09`; `461ed9b3e495 -> IMPLEMENT-09`; `b5ad64fd744d -> NG`; `14ce436cfffa -> NG`; `043ca36da3e2 -> NG`; `a23e45c1dc8d -> NG`; `498143bb41a7 -> NG`; `4fe3eb179023 -> NG`; `7f75485e5a33 -> NG`; `8ec3a96df029 -> NG`; `16c3f96e758d -> NG`; `5915c41fe058 -> NG`; `f51e43eeac56 -> NG`; `fd41c25623cb -> NG`; `58a932ed6453 -> NG`; `4718bd3ce12d -> NG`; `58c444a2126b -> NG`; `2df3adae4120 -> NG`; `e75df892b55c -> NG` |
238
+ | `oat-project-implement/references/dispatch-and-dry-run.md` | `21b85f5e4daa -> IMPLEMENT-08`; `74c92b32bb2a -> IMPLEMENT-08`; `8efd2d0517ab -> IMPLEMENT-09`; `461ed9b3e495 -> IMPLEMENT-09`; `b5ad64fd744d -> NG`; `14ce436cfffa -> NG`; `043ca36da3e2 -> NG`; `a23e45c1dc8d -> NG`; `498143bb41a7 -> NG`; `4fe3eb179023 -> NG`; `7f75485e5a33 -> NG`; `8ec3a96df029 -> NG`; `16c3f96e758d -> NG`; `5915c41fe058 -> NG`; `f51e43eeac56 -> NG`; `fd41c25623cb -> NG`; `58a932ed6453 -> NG`; `4718bd3ce12d -> NG`; `58c444a2126b -> NG`; `2df3adae4120 -> NG`; `e75df892b55c -> NG`; `8ba5dbd2a0d8 -> NG` |
239
239
  | `oat-project-implement/references/docs/autonomy-contract.md` | `* -> NG` |
240
240
  | `oat-project-implement/references/phase-execution.md` | `27737e814790 -> NG`; `6dda2b8e62e2 -> IMPLEMENT-10`; `b3197086bb1e -> IMPLEMENT-10` |
241
241
  | `oat-project-implement/references/plan-and-resume.md` | `413829d31e32 -> IMPLEMENT-02`; `c7706cd8ad09 -> IMPLEMENT-03`; `a80a948df658 -> IMPLEMENT-03`; `b7ea139780ec -> IMPLEMENT-03+IMPLEMENT-04`; `8d438f2180ba -> IMPLEMENT-03`; `9e72e0518cda -> IMPLEMENT-03`; `3e177a1021e6 -> IMPLEMENT-03+IMPLEMENT-04`; `b59fc9eb9ce3 -> IMPLEMENT-03`; `a2b1d6855283 -> IMPLEMENT-03`; `44351a32e52a -> IMPLEMENT-03`; `b98b022f5523 -> IMPLEMENT-03`; `e9f5b949e214 -> IMPLEMENT-03`; `316fb6d9e980 -> IMPLEMENT-03`; `8b25a2c5c548 -> IMPLEMENT-03`; `1a59b1c0e705 -> IMPLEMENT-03`; `466cd562fc52 -> IMPLEMENT-03`; `083d896978d5 -> IMPLEMENT-03`; `f4ab11c13ae9 -> IMPLEMENT-03`; `7dc17ffcc1c4 -> IMPLEMENT-03`; `f731a90adabd -> IMPLEMENT-04`; `886ac01e7aa9 -> IMPLEMENT-04`; `b715db67df0c -> IMPLEMENT-04`; `2d9f26a539f3 -> IMPLEMENT-10`; `28384dee114f -> IMPLEMENT-05`; `f2591a4978b4 -> NG`; `8290823080b5 -> IMPLEMENT-06`; `f75789bf6c8e -> IMPLEMENT-07` |
@@ -235,7 +235,7 @@ remains immutable baseline evidence for the original p01-t01 verification.
235
235
  | `oat-project-import-plan/SKILL.md` | `f7ca8635452f -> NG`; `c2e5fa410069 -> NG`; `655d61df0a8f -> NG`; `dceff5cc04b5 -> NG`; `1af4957a1af2 -> IMPORT-01`; `45b699c1c0b5 -> IMPORT-01`; `ba6d120791c1 -> IMPORT-01`; `070ebc5259af -> IMPORT-03`; `c11552696e2e -> IMPORT-03`; `cfe661966baf -> IMPORT-04`; `baa91c0a0bf8 -> NG`; `e364e84b2702 -> NG`; `39031985a945 -> IMPORT-06`; `f106aa29a217 -> IMPORT-07`; `65038450aee3 -> IMPORT-07`; `bee4c4aa34c6 -> NG`; `3f0b53056edd -> IMPORT-09` |
236
236
  | `oat-project-implement/SKILL.md` | `18980f6bc1a6 -> NG`; `ffb3af0ba8ef -> NG`; `e0355c7a05e9 -> IMPLEMENT-11+IMPLEMENT-13+IMPLEMENT-16`; `6296f41ae11c -> NG`; `a167d03559fa -> NG`; `cf317c17c586 -> IMPLEMENT-01`; `8ce8a09feca4 -> NG`; `bd0cb4988188 -> NG`; `28af4ee0055d -> NG` |
237
237
  | `oat-project-implement/references/completion-and-closeout.md` | `f7dab9c1f96c -> IMPLEMENT-12`; `c69c17a069a8 -> IMPLEMENT-14`; `a97fa5634a68 -> IMPLEMENT-14`; `3af58881811c -> IMPLEMENT-14`; `4203e1f49d0f -> IMPLEMENT-14`; `c3bd2458a3d3 -> IMPLEMENT-13`; `95b5eafc070d -> IMPLEMENT-13`; `25ecbe9c998b -> IMPLEMENT-13+IMPLEMENT-14+IMPLEMENT-15+IMPLEMENT-16`; `f6f24fd71da4 -> IMPLEMENT-13+IMPLEMENT-14+IMPLEMENT-15+IMPLEMENT-16`; `f18283bc1cf9 -> IMPLEMENT-13+IMPLEMENT-14+IMPLEMENT-15+IMPLEMENT-16`; `2c1ffc4a82dd -> IMPLEMENT-13+IMPLEMENT-14+IMPLEMENT-15+IMPLEMENT-16`; `3454a07aa843 -> IMPLEMENT-16`; `0d86e2098cfb -> IMPLEMENT-13+IMPLEMENT-14+IMPLEMENT-15+IMPLEMENT-16`; `d5fe597d266f -> IMPLEMENT-13+IMPLEMENT-14+IMPLEMENT-15+IMPLEMENT-16`; `55a152e944c1 -> IMPLEMENT-16`; `effac7cbd573 -> IMPLEMENT-13+IMPLEMENT-14+IMPLEMENT-15+IMPLEMENT-16`; `9d2a34d8b148 -> IMPLEMENT-13+IMPLEMENT-14+IMPLEMENT-15+IMPLEMENT-16`; `d27462aaed26 -> IMPLEMENT-13+IMPLEMENT-14+IMPLEMENT-15+IMPLEMENT-16`; `9d52ecb17268 -> IMPLEMENT-13+IMPLEMENT-14+IMPLEMENT-15+IMPLEMENT-16`; `5b91aabe3757 -> IMPLEMENT-13+IMPLEMENT-14+IMPLEMENT-15+IMPLEMENT-16`; `fd0ad919f702 -> IMPLEMENT-13+IMPLEMENT-14+IMPLEMENT-15+IMPLEMENT-16`; `63bf28df1474 -> IMPLEMENT-13+IMPLEMENT-14+IMPLEMENT-15+IMPLEMENT-16`; `a4ed471dbc78 -> IMPLEMENT-16`; `6b7a64cec6e5 -> IMPLEMENT-16`; `0a4fdba0ebc0 -> IMPLEMENT-13+IMPLEMENT-14+IMPLEMENT-15+IMPLEMENT-16`; `a5033c2aada5 -> IMPLEMENT-13+IMPLEMENT-14+IMPLEMENT-15+IMPLEMENT-16`; `e77609eddba0 -> IMPLEMENT-13+IMPLEMENT-14+IMPLEMENT-15+IMPLEMENT-16`; `351156e8dde4 -> IMPLEMENT-13+IMPLEMENT-14+IMPLEMENT-15+IMPLEMENT-16`; `51d45bd2bbd1 -> IMPLEMENT-16`; `f7796ffcc804 -> IMPLEMENT-16`; `990d730cb494 -> IMPLEMENT-16`; `6ed28bb7d384 -> IMPLEMENT-16`; `8b7d4b5bcf1b -> IMPLEMENT-16`; `88aad500e6e9 -> IMPLEMENT-16`; `877e3e3f9eda -> IMPLEMENT-16`; `fc03c97f834e -> IMPLEMENT-16`; `12939a3da5e0 -> IMPLEMENT-16`; `bdb418335a88 -> IMPLEMENT-16`; `fba97e596ebd -> IMPLEMENT-16`; `3d0b5e2f14f0 -> IMPLEMENT-17`; `87f1424a8692 -> NG`; `6b1ec05182f0 -> IMPLEMENT-11`; `e6d696a27c91 -> NG`; `c77f8ccb52ad -> NG`; `48de2614c0ba -> IMPLEMENT-11`; `32d53f5212e5 -> IMPLEMENT-11`; `7cdb4a9c57b7 -> IMPLEMENT-11`; `16ffc0aa099b -> IMPLEMENT-11`; `d6868ea10b3f -> IMPLEMENT-11`; `4f05ff5567be -> IMPLEMENT-11`; `c70b47ae7a6d -> IMPLEMENT-11`; `5fafd093b58e -> NG`; `567d43ab0c2e -> NG`; `21ceaf7e658a -> NG`; `249427a9f475 -> NG`; `8a7ec13a9b7c -> NG`; `9aeb7fce2012 -> IMPLEMENT-18`; `f11a7cdda220 -> IMPLEMENT-18`; `4523ac029152 -> NG`; `6e87b08c4046 -> NG`; `baa6052c7f0a -> IMPLEMENT-18`; `27d3fad116b1 -> IMPLEMENT-18`; `2cfbeb4388a5 -> IMPLEMENT-18`; `c56ea56a56db -> NG`; `43e2e3c1380d -> IMPLEMENT-17`; `b49690277fb5 -> NG`; `df12304d6a36 -> NG`; `52eacac11fef -> IMPLEMENT-17`; `60092df6b17b -> IMPLEMENT-17`; `361872c6b00e -> IMPLEMENT-17`; `d2bc711a75fb -> IMPLEMENT-17` |
238
- | `oat-project-implement/references/dispatch-and-dry-run.md` | `21b85f5e4daa -> IMPLEMENT-08`; `74c92b32bb2a -> IMPLEMENT-08`; `8efd2d0517ab -> IMPLEMENT-09`; `461ed9b3e495 -> IMPLEMENT-09`; `b5ad64fd744d -> NG`; `14ce436cfffa -> NG`; `043ca36da3e2 -> NG`; `a23e45c1dc8d -> NG`; `498143bb41a7 -> NG`; `4fe3eb179023 -> NG`; `7f75485e5a33 -> NG`; `8ec3a96df029 -> NG`; `16c3f96e758d -> NG`; `5915c41fe058 -> NG`; `f51e43eeac56 -> NG`; `fd41c25623cb -> NG`; `58a932ed6453 -> NG`; `4718bd3ce12d -> NG`; `58c444a2126b -> NG`; `2df3adae4120 -> NG`; `e75df892b55c -> NG` |
238
+ | `oat-project-implement/references/dispatch-and-dry-run.md` | `21b85f5e4daa -> IMPLEMENT-08`; `74c92b32bb2a -> IMPLEMENT-08`; `8efd2d0517ab -> IMPLEMENT-09`; `461ed9b3e495 -> IMPLEMENT-09`; `b5ad64fd744d -> NG`; `14ce436cfffa -> NG`; `043ca36da3e2 -> NG`; `a23e45c1dc8d -> NG`; `498143bb41a7 -> NG`; `4fe3eb179023 -> NG`; `7f75485e5a33 -> NG`; `8ec3a96df029 -> NG`; `16c3f96e758d -> NG`; `5915c41fe058 -> NG`; `f51e43eeac56 -> NG`; `fd41c25623cb -> NG`; `58a932ed6453 -> NG`; `4718bd3ce12d -> NG`; `58c444a2126b -> NG`; `2df3adae4120 -> NG`; `e75df892b55c -> NG`; `8ba5dbd2a0d8 -> NG` |
239
239
  | `oat-project-implement/references/docs/autonomy-contract.md` | `* -> NG` |
240
240
  | `oat-project-implement/references/phase-execution.md` | `27737e814790 -> NG`; `6dda2b8e62e2 -> IMPLEMENT-10`; `b3197086bb1e -> IMPLEMENT-10` |
241
241
  | `oat-project-implement/references/plan-and-resume.md` | `413829d31e32 -> IMPLEMENT-02`; `c7706cd8ad09 -> IMPLEMENT-03`; `a80a948df658 -> IMPLEMENT-03`; `b7ea139780ec -> IMPLEMENT-03+IMPLEMENT-04`; `8d438f2180ba -> IMPLEMENT-03`; `9e72e0518cda -> IMPLEMENT-03`; `3e177a1021e6 -> IMPLEMENT-03+IMPLEMENT-04`; `b59fc9eb9ce3 -> IMPLEMENT-03`; `a2b1d6855283 -> IMPLEMENT-03`; `44351a32e52a -> IMPLEMENT-03`; `b98b022f5523 -> IMPLEMENT-03`; `e9f5b949e214 -> IMPLEMENT-03`; `316fb6d9e980 -> IMPLEMENT-03`; `8b25a2c5c548 -> IMPLEMENT-03`; `1a59b1c0e705 -> IMPLEMENT-03`; `466cd562fc52 -> IMPLEMENT-03`; `083d896978d5 -> IMPLEMENT-03`; `f4ab11c13ae9 -> IMPLEMENT-03`; `7dc17ffcc1c4 -> IMPLEMENT-03`; `f731a90adabd -> IMPLEMENT-04`; `886ac01e7aa9 -> IMPLEMENT-04`; `b715db67df0c -> IMPLEMENT-04`; `2d9f26a539f3 -> IMPLEMENT-10`; `28384dee114f -> IMPLEMENT-05`; `f2591a4978b4 -> NG`; `8290823080b5 -> IMPLEMENT-06`; `f75789bf6c8e -> IMPLEMENT-07` |
@@ -1,6 +1,6 @@
1
1
  ---
2
2
  name: oat-project-implement
3
- version: 2.2.0
3
+ version: 2.2.1
4
4
  description: Use when plan.md is ready for execution. Dispatches one phase implementer per phase, owns independent phase review and bounded fix routing, and supports plan-declared worktree-isolated parallel phases.
5
5
  oat_gateable: true
6
6
  argument-hint: '[--retry-limit <N>] [--dry-run]'
@@ -52,6 +52,9 @@ to be clean; each append is committed by the bookkeeping that owns it.
52
52
  dispatch record at `$PROJECT_PATH/implementation.md#<run-anchor>`;
53
53
  never mirror that record. Do not write the project log at acceptance; append
54
54
  it with the phase-outcome entry after the child's report returns.
55
+ - Implementing a phase in the root during a Tier 1 run is a deviation, never a
56
+ silent default: record the phase ID, reason, and root model under a sibling
57
+ `Root-inline phase` heading at that run anchor. Sanctioned Tier 2 needs none.
55
58
  - Before validating the review artifact or updating project bookkeeping, consume
56
59
  exactly one brief artifact-mode confirmation of reconnaissance:
57
60
  - `**Reconnaissance:** attempted`
@@ -105,6 +105,16 @@ Do not print `[0/N]` for this preflight step. The implementation denominator
105
105
  is not established by capability detection; use the literal `[preflight]`
106
106
  label above.
107
107
 
108
+ **Root-inline phases:** the preflight above records the tier reason once for the
109
+ run, so a sanctioned Tier 2 run needs no further per-phase record. Implementing
110
+ a phase in the root during a Tier 1 run is different: subagents were available
111
+ and approved, and the root took the work anyway. That is a deviation and must be
112
+ recorded, but no child was accepted, so the generic dispatch record cannot carry
113
+ it — that record is keyed on launch state the deviation does not have. Record it
114
+ instead under a `Root-inline phase` heading placed beside the generic record at
115
+ the same `$PROJECT_PATH/implementation.md#<run-anchor>`, giving the phase ID,
116
+ the reason the root did not dispatch, and the model the root was running.
117
+
108
118
  **Tier lock:** tier is locked for the remainder of the run only after the
109
119
  dispatch target is resolved. Subsequent phase-implementer, optional nested,
110
120
  fix-continuation, and review dispatches use the same tier. Tier controls
@@ -187,11 +197,21 @@ Print before phase work:
187
197
  ```text
188
198
  OAT Dispatch Tier: balanced (codex, managed capped — pinned-variant)
189
199
  Resolved cap: high
200
+ Classified task class: default-implementation
201
+ Preferred effort: medium
202
+ Selected effort: medium
190
203
  Source: project state
191
204
  Provider default effort: medium
192
205
  Note: OAT will use resolver-returned materialized Codex role names up to high. Base/unpinned roles resolve through the provider default only for explicit inherit/default behavior or the documented managed-uncapped reviewer exception.
193
206
  ```
194
207
 
208
+ The classification and the resolved cap are separate lines because they answer
209
+ separate questions: what the work needs, and what the policy permits. Here the
210
+ class resolved to `default-implementation` at `medium` effort while the cap
211
+ permitted `high`, so the selection sits below the ceiling. A stamp reporting
212
+ `not-classified` against a selected value equal to its cap is recording that the
213
+ first question went unasked.
214
+
195
215
  If no policy resolves and the session is interactive, present the dispatch
196
216
  policy prompt once before starting work. Print the unresolved-policy heading,
197
217
  then generate the choice text from canonical CLI metadata immediately before
@@ -400,6 +420,28 @@ Cursor rules:
400
420
  - Treat every configured Cursor candidate string as opaque. Do not normalize it
401
421
  or infer capability from its spelling. The materialized mapping and resolver
402
422
  alone translate it to a native variant.
423
+ - Select the concrete candidate before resolving, and select it through the
424
+ Task-Class Resolution contract in
425
+ `oat-dispatch-subagents/references/provider-cursor.md`, intersected with the
426
+ dated class guidance in the active `subagent-orchestration` selection
427
+ reference. That contract owns the decision; do not restate it here and do not
428
+ merge the two references. The Codex effort bands above are not a substitute:
429
+ they are defined on an effort axis Cursor does not expose, since Cursor
430
+ carries effort inside the candidate string and reports
431
+ `effort_axis=not-applicable`.
432
+ - Eligibility is wider than the ceiling tier. For implementation and fix work
433
+ every candidate from the lowest tier through the project's named maximum is
434
+ eligible, so a phase below the ceiling class has somewhere to land.
435
+ - The managed-capped route takes the exact-candidate branch above, so
436
+ `--candidate-model` is required. Omitting it does not ask the resolver to
437
+ choose; with no preferred value to compare against it takes the capped branch
438
+ and sets the selected value to the policy value, reporting
439
+ `selectionMode=capped` with the selected model equal to the cap. That pairing
440
+ is the signature of a skipped selection rather than evidence that the ceiling
441
+ was warranted, and it resolves without error, so nothing else will flag it.
442
+ - A ceiling is a maximum, not a target. Selecting the cap is correct only when
443
+ task-class resolution independently arrives there; reaching it because no
444
+ candidate was selected is a defect.
403
445
  - For managed capped phase-implementer/fix dispatch, call
404
446
  `oat project dispatch-ceiling resolve --provider cursor --role implementer --ceiling-tier <project-or-phase-tier> --candidate-model <opaque-model> --report-scope <phase-id> --report-action implementation --json`.
405
447
  For bounded fixes, reuse the exact phase target with a bounded fix scope.
@@ -463,12 +505,13 @@ Requested controls: {model=<value|none>, effort=<value|none>, target=<value|unkn
463
505
  Configured defaults: {provider default effort/model | unknown | not-applicable}
464
506
  Runtime confirmation: {observed:<slug> | declared:<slug> | not-observable | mismatch:<detail>}
465
507
  Preferred effort: {low | medium | high | xhigh | max | provider-default | not-applicable}
508
+ Classified task class: {mechanical-recon | intelligent-recon | default-implementation | hard-reasoning | consequential | not-classified}
466
509
  OAT Dispatch Tier: {economy | balanced | high | frontier | uncapped | inherit host defaults | legacy capped}
467
510
  Resolved cap: {resolved cap value | none}
468
511
  Selected effort: {low | medium | high | xhigh | max | provider-default | not-applicable}
469
512
  Policy source: {repo config | project state | preflight prompt}
470
513
  Provider default effort: {value | unknown | not-applicable}
471
- Selection mode: {capped | uncapped | review-target | no-review-target | inherit-default}
514
+ Selection mode: {candidate | capped | uncapped | review-target | no-review-target | inherit-default | unresolved}
472
515
  Route level: {0 | 1 | ... | none}
473
516
  Model axis: { selected:<value> | inherited | not-applicable | host-auto }
474
517
  Effort axis: { selected:<value> | provider-default | inherited | not-applicable | host-auto }
@@ -477,6 +520,26 @@ Dispatch stamp: Dispatch: scope=<phase-or-task> action=<implementation|fix|revie
477
520
  Rationale: {short rationale grounded in phase scope and any policy cap/uncapped/default behavior}
478
521
  ```
479
522
 
523
+ `Classified task class` carries the same value as the generic record's
524
+ `task_class` field in
525
+ `oat-dispatch-subagents/references/record-schema.md`, which is provider-neutral
526
+ across all five classes. Do not introduce a second vocabulary here. Where a
527
+ provider also classifies on an effort axis, that classification stays in
528
+ `Preferred effort`; Cursor reports `effort_axis=not-applicable` and carries the
529
+ class alone.
530
+
531
+ A managed-capped implementer or fix dispatch must carry a class. Because it
532
+ takes the exact-candidate branch, a correct one resolves to
533
+ `Selection mode: candidate`, or to `unresolved` when the requested candidate is
534
+ not selectable. `not-classified` is reserved for routes that make no selection,
535
+ and on a managed-capped route it pairs with `Selection mode: capped` to mark the
536
+ defect described under Cursor rules: the resolver reports `capped` precisely
537
+ because no candidate was supplied to select. That pairing is what distinguishes
538
+ a justified selection from a silent one.
539
+
540
+ Mirror the resolver's `selectionMode` values exactly. Omitting one forces a
541
+ correct dispatch to log a value that means something else.
542
+
480
543
  For an explicit inherit/default fallback (for example a base `oat-reviewer`
481
544
  under inherit policy), the log reads `Route: none; level=none`,
482
545
  `Runtime confirmation: not-observable`, `Selection mode: inherit-default`,
@@ -235,7 +235,7 @@ remains immutable baseline evidence for the original p01-t01 verification.
235
235
  | `oat-project-import-plan/SKILL.md` | `f7ca8635452f -> NG`; `c2e5fa410069 -> NG`; `655d61df0a8f -> NG`; `dceff5cc04b5 -> NG`; `1af4957a1af2 -> IMPORT-01`; `45b699c1c0b5 -> IMPORT-01`; `ba6d120791c1 -> IMPORT-01`; `070ebc5259af -> IMPORT-03`; `c11552696e2e -> IMPORT-03`; `cfe661966baf -> IMPORT-04`; `baa91c0a0bf8 -> NG`; `e364e84b2702 -> NG`; `39031985a945 -> IMPORT-06`; `f106aa29a217 -> IMPORT-07`; `65038450aee3 -> IMPORT-07`; `bee4c4aa34c6 -> NG`; `3f0b53056edd -> IMPORT-09` |
236
236
  | `oat-project-implement/SKILL.md` | `18980f6bc1a6 -> NG`; `ffb3af0ba8ef -> NG`; `e0355c7a05e9 -> IMPLEMENT-11+IMPLEMENT-13+IMPLEMENT-16`; `6296f41ae11c -> NG`; `a167d03559fa -> NG`; `cf317c17c586 -> IMPLEMENT-01`; `8ce8a09feca4 -> NG`; `bd0cb4988188 -> NG`; `28af4ee0055d -> NG` |
237
237
  | `oat-project-implement/references/completion-and-closeout.md` | `f7dab9c1f96c -> IMPLEMENT-12`; `c69c17a069a8 -> IMPLEMENT-14`; `a97fa5634a68 -> IMPLEMENT-14`; `3af58881811c -> IMPLEMENT-14`; `4203e1f49d0f -> IMPLEMENT-14`; `c3bd2458a3d3 -> IMPLEMENT-13`; `95b5eafc070d -> IMPLEMENT-13`; `25ecbe9c998b -> IMPLEMENT-13+IMPLEMENT-14+IMPLEMENT-15+IMPLEMENT-16`; `f6f24fd71da4 -> IMPLEMENT-13+IMPLEMENT-14+IMPLEMENT-15+IMPLEMENT-16`; `f18283bc1cf9 -> IMPLEMENT-13+IMPLEMENT-14+IMPLEMENT-15+IMPLEMENT-16`; `2c1ffc4a82dd -> IMPLEMENT-13+IMPLEMENT-14+IMPLEMENT-15+IMPLEMENT-16`; `3454a07aa843 -> IMPLEMENT-16`; `0d86e2098cfb -> IMPLEMENT-13+IMPLEMENT-14+IMPLEMENT-15+IMPLEMENT-16`; `d5fe597d266f -> IMPLEMENT-13+IMPLEMENT-14+IMPLEMENT-15+IMPLEMENT-16`; `55a152e944c1 -> IMPLEMENT-16`; `effac7cbd573 -> IMPLEMENT-13+IMPLEMENT-14+IMPLEMENT-15+IMPLEMENT-16`; `9d2a34d8b148 -> IMPLEMENT-13+IMPLEMENT-14+IMPLEMENT-15+IMPLEMENT-16`; `d27462aaed26 -> IMPLEMENT-13+IMPLEMENT-14+IMPLEMENT-15+IMPLEMENT-16`; `9d52ecb17268 -> IMPLEMENT-13+IMPLEMENT-14+IMPLEMENT-15+IMPLEMENT-16`; `5b91aabe3757 -> IMPLEMENT-13+IMPLEMENT-14+IMPLEMENT-15+IMPLEMENT-16`; `fd0ad919f702 -> IMPLEMENT-13+IMPLEMENT-14+IMPLEMENT-15+IMPLEMENT-16`; `63bf28df1474 -> IMPLEMENT-13+IMPLEMENT-14+IMPLEMENT-15+IMPLEMENT-16`; `a4ed471dbc78 -> IMPLEMENT-16`; `6b7a64cec6e5 -> IMPLEMENT-16`; `0a4fdba0ebc0 -> IMPLEMENT-13+IMPLEMENT-14+IMPLEMENT-15+IMPLEMENT-16`; `a5033c2aada5 -> IMPLEMENT-13+IMPLEMENT-14+IMPLEMENT-15+IMPLEMENT-16`; `e77609eddba0 -> IMPLEMENT-13+IMPLEMENT-14+IMPLEMENT-15+IMPLEMENT-16`; `351156e8dde4 -> IMPLEMENT-13+IMPLEMENT-14+IMPLEMENT-15+IMPLEMENT-16`; `51d45bd2bbd1 -> IMPLEMENT-16`; `f7796ffcc804 -> IMPLEMENT-16`; `990d730cb494 -> IMPLEMENT-16`; `6ed28bb7d384 -> IMPLEMENT-16`; `8b7d4b5bcf1b -> IMPLEMENT-16`; `88aad500e6e9 -> IMPLEMENT-16`; `877e3e3f9eda -> IMPLEMENT-16`; `fc03c97f834e -> IMPLEMENT-16`; `12939a3da5e0 -> IMPLEMENT-16`; `bdb418335a88 -> IMPLEMENT-16`; `fba97e596ebd -> IMPLEMENT-16`; `3d0b5e2f14f0 -> IMPLEMENT-17`; `87f1424a8692 -> NG`; `6b1ec05182f0 -> IMPLEMENT-11`; `e6d696a27c91 -> NG`; `c77f8ccb52ad -> NG`; `48de2614c0ba -> IMPLEMENT-11`; `32d53f5212e5 -> IMPLEMENT-11`; `7cdb4a9c57b7 -> IMPLEMENT-11`; `16ffc0aa099b -> IMPLEMENT-11`; `d6868ea10b3f -> IMPLEMENT-11`; `4f05ff5567be -> IMPLEMENT-11`; `c70b47ae7a6d -> IMPLEMENT-11`; `5fafd093b58e -> NG`; `567d43ab0c2e -> NG`; `21ceaf7e658a -> NG`; `249427a9f475 -> NG`; `8a7ec13a9b7c -> NG`; `9aeb7fce2012 -> IMPLEMENT-18`; `f11a7cdda220 -> IMPLEMENT-18`; `4523ac029152 -> NG`; `6e87b08c4046 -> NG`; `baa6052c7f0a -> IMPLEMENT-18`; `27d3fad116b1 -> IMPLEMENT-18`; `2cfbeb4388a5 -> IMPLEMENT-18`; `c56ea56a56db -> NG`; `43e2e3c1380d -> IMPLEMENT-17`; `b49690277fb5 -> NG`; `df12304d6a36 -> NG`; `52eacac11fef -> IMPLEMENT-17`; `60092df6b17b -> IMPLEMENT-17`; `361872c6b00e -> IMPLEMENT-17`; `d2bc711a75fb -> IMPLEMENT-17` |
238
- | `oat-project-implement/references/dispatch-and-dry-run.md` | `21b85f5e4daa -> IMPLEMENT-08`; `74c92b32bb2a -> IMPLEMENT-08`; `8efd2d0517ab -> IMPLEMENT-09`; `461ed9b3e495 -> IMPLEMENT-09`; `b5ad64fd744d -> NG`; `14ce436cfffa -> NG`; `043ca36da3e2 -> NG`; `a23e45c1dc8d -> NG`; `498143bb41a7 -> NG`; `4fe3eb179023 -> NG`; `7f75485e5a33 -> NG`; `8ec3a96df029 -> NG`; `16c3f96e758d -> NG`; `5915c41fe058 -> NG`; `f51e43eeac56 -> NG`; `fd41c25623cb -> NG`; `58a932ed6453 -> NG`; `4718bd3ce12d -> NG`; `58c444a2126b -> NG`; `2df3adae4120 -> NG`; `e75df892b55c -> NG` |
238
+ | `oat-project-implement/references/dispatch-and-dry-run.md` | `21b85f5e4daa -> IMPLEMENT-08`; `74c92b32bb2a -> IMPLEMENT-08`; `8efd2d0517ab -> IMPLEMENT-09`; `461ed9b3e495 -> IMPLEMENT-09`; `b5ad64fd744d -> NG`; `14ce436cfffa -> NG`; `043ca36da3e2 -> NG`; `a23e45c1dc8d -> NG`; `498143bb41a7 -> NG`; `4fe3eb179023 -> NG`; `7f75485e5a33 -> NG`; `8ec3a96df029 -> NG`; `16c3f96e758d -> NG`; `5915c41fe058 -> NG`; `f51e43eeac56 -> NG`; `fd41c25623cb -> NG`; `58a932ed6453 -> NG`; `4718bd3ce12d -> NG`; `58c444a2126b -> NG`; `2df3adae4120 -> NG`; `e75df892b55c -> NG`; `8ba5dbd2a0d8 -> NG` |
239
239
  | `oat-project-implement/references/docs/autonomy-contract.md` | `* -> NG` |
240
240
  | `oat-project-implement/references/phase-execution.md` | `27737e814790 -> NG`; `6dda2b8e62e2 -> IMPLEMENT-10`; `b3197086bb1e -> IMPLEMENT-10` |
241
241
  | `oat-project-implement/references/plan-and-resume.md` | `413829d31e32 -> IMPLEMENT-02`; `c7706cd8ad09 -> IMPLEMENT-03`; `a80a948df658 -> IMPLEMENT-03`; `b7ea139780ec -> IMPLEMENT-03+IMPLEMENT-04`; `8d438f2180ba -> IMPLEMENT-03`; `9e72e0518cda -> IMPLEMENT-03`; `3e177a1021e6 -> IMPLEMENT-03+IMPLEMENT-04`; `b59fc9eb9ce3 -> IMPLEMENT-03`; `a2b1d6855283 -> IMPLEMENT-03`; `44351a32e52a -> IMPLEMENT-03`; `b98b022f5523 -> IMPLEMENT-03`; `e9f5b949e214 -> IMPLEMENT-03`; `316fb6d9e980 -> IMPLEMENT-03`; `8b25a2c5c548 -> IMPLEMENT-03`; `1a59b1c0e705 -> IMPLEMENT-03`; `466cd562fc52 -> IMPLEMENT-03`; `083d896978d5 -> IMPLEMENT-03`; `f4ab11c13ae9 -> IMPLEMENT-03`; `7dc17ffcc1c4 -> IMPLEMENT-03`; `f731a90adabd -> IMPLEMENT-04`; `886ac01e7aa9 -> IMPLEMENT-04`; `b715db67df0c -> IMPLEMENT-04`; `2d9f26a539f3 -> IMPLEMENT-10`; `28384dee114f -> IMPLEMENT-05`; `f2591a4978b4 -> NG`; `8290823080b5 -> IMPLEMENT-06`; `f75789bf6c8e -> IMPLEMENT-07` |
@@ -235,7 +235,7 @@ remains immutable baseline evidence for the original p01-t01 verification.
235
235
  | `oat-project-import-plan/SKILL.md` | `f7ca8635452f -> NG`; `c2e5fa410069 -> NG`; `655d61df0a8f -> NG`; `dceff5cc04b5 -> NG`; `1af4957a1af2 -> IMPORT-01`; `45b699c1c0b5 -> IMPORT-01`; `ba6d120791c1 -> IMPORT-01`; `070ebc5259af -> IMPORT-03`; `c11552696e2e -> IMPORT-03`; `cfe661966baf -> IMPORT-04`; `baa91c0a0bf8 -> NG`; `e364e84b2702 -> NG`; `39031985a945 -> IMPORT-06`; `f106aa29a217 -> IMPORT-07`; `65038450aee3 -> IMPORT-07`; `bee4c4aa34c6 -> NG`; `3f0b53056edd -> IMPORT-09` |
236
236
  | `oat-project-implement/SKILL.md` | `18980f6bc1a6 -> NG`; `ffb3af0ba8ef -> NG`; `e0355c7a05e9 -> IMPLEMENT-11+IMPLEMENT-13+IMPLEMENT-16`; `6296f41ae11c -> NG`; `a167d03559fa -> NG`; `cf317c17c586 -> IMPLEMENT-01`; `8ce8a09feca4 -> NG`; `bd0cb4988188 -> NG`; `28af4ee0055d -> NG` |
237
237
  | `oat-project-implement/references/completion-and-closeout.md` | `f7dab9c1f96c -> IMPLEMENT-12`; `c69c17a069a8 -> IMPLEMENT-14`; `a97fa5634a68 -> IMPLEMENT-14`; `3af58881811c -> IMPLEMENT-14`; `4203e1f49d0f -> IMPLEMENT-14`; `c3bd2458a3d3 -> IMPLEMENT-13`; `95b5eafc070d -> IMPLEMENT-13`; `25ecbe9c998b -> IMPLEMENT-13+IMPLEMENT-14+IMPLEMENT-15+IMPLEMENT-16`; `f6f24fd71da4 -> IMPLEMENT-13+IMPLEMENT-14+IMPLEMENT-15+IMPLEMENT-16`; `f18283bc1cf9 -> IMPLEMENT-13+IMPLEMENT-14+IMPLEMENT-15+IMPLEMENT-16`; `2c1ffc4a82dd -> IMPLEMENT-13+IMPLEMENT-14+IMPLEMENT-15+IMPLEMENT-16`; `3454a07aa843 -> IMPLEMENT-16`; `0d86e2098cfb -> IMPLEMENT-13+IMPLEMENT-14+IMPLEMENT-15+IMPLEMENT-16`; `d5fe597d266f -> IMPLEMENT-13+IMPLEMENT-14+IMPLEMENT-15+IMPLEMENT-16`; `55a152e944c1 -> IMPLEMENT-16`; `effac7cbd573 -> IMPLEMENT-13+IMPLEMENT-14+IMPLEMENT-15+IMPLEMENT-16`; `9d2a34d8b148 -> IMPLEMENT-13+IMPLEMENT-14+IMPLEMENT-15+IMPLEMENT-16`; `d27462aaed26 -> IMPLEMENT-13+IMPLEMENT-14+IMPLEMENT-15+IMPLEMENT-16`; `9d52ecb17268 -> IMPLEMENT-13+IMPLEMENT-14+IMPLEMENT-15+IMPLEMENT-16`; `5b91aabe3757 -> IMPLEMENT-13+IMPLEMENT-14+IMPLEMENT-15+IMPLEMENT-16`; `fd0ad919f702 -> IMPLEMENT-13+IMPLEMENT-14+IMPLEMENT-15+IMPLEMENT-16`; `63bf28df1474 -> IMPLEMENT-13+IMPLEMENT-14+IMPLEMENT-15+IMPLEMENT-16`; `a4ed471dbc78 -> IMPLEMENT-16`; `6b7a64cec6e5 -> IMPLEMENT-16`; `0a4fdba0ebc0 -> IMPLEMENT-13+IMPLEMENT-14+IMPLEMENT-15+IMPLEMENT-16`; `a5033c2aada5 -> IMPLEMENT-13+IMPLEMENT-14+IMPLEMENT-15+IMPLEMENT-16`; `e77609eddba0 -> IMPLEMENT-13+IMPLEMENT-14+IMPLEMENT-15+IMPLEMENT-16`; `351156e8dde4 -> IMPLEMENT-13+IMPLEMENT-14+IMPLEMENT-15+IMPLEMENT-16`; `51d45bd2bbd1 -> IMPLEMENT-16`; `f7796ffcc804 -> IMPLEMENT-16`; `990d730cb494 -> IMPLEMENT-16`; `6ed28bb7d384 -> IMPLEMENT-16`; `8b7d4b5bcf1b -> IMPLEMENT-16`; `88aad500e6e9 -> IMPLEMENT-16`; `877e3e3f9eda -> IMPLEMENT-16`; `fc03c97f834e -> IMPLEMENT-16`; `12939a3da5e0 -> IMPLEMENT-16`; `bdb418335a88 -> IMPLEMENT-16`; `fba97e596ebd -> IMPLEMENT-16`; `3d0b5e2f14f0 -> IMPLEMENT-17`; `87f1424a8692 -> NG`; `6b1ec05182f0 -> IMPLEMENT-11`; `e6d696a27c91 -> NG`; `c77f8ccb52ad -> NG`; `48de2614c0ba -> IMPLEMENT-11`; `32d53f5212e5 -> IMPLEMENT-11`; `7cdb4a9c57b7 -> IMPLEMENT-11`; `16ffc0aa099b -> IMPLEMENT-11`; `d6868ea10b3f -> IMPLEMENT-11`; `4f05ff5567be -> IMPLEMENT-11`; `c70b47ae7a6d -> IMPLEMENT-11`; `5fafd093b58e -> NG`; `567d43ab0c2e -> NG`; `21ceaf7e658a -> NG`; `249427a9f475 -> NG`; `8a7ec13a9b7c -> NG`; `9aeb7fce2012 -> IMPLEMENT-18`; `f11a7cdda220 -> IMPLEMENT-18`; `4523ac029152 -> NG`; `6e87b08c4046 -> NG`; `baa6052c7f0a -> IMPLEMENT-18`; `27d3fad116b1 -> IMPLEMENT-18`; `2cfbeb4388a5 -> IMPLEMENT-18`; `c56ea56a56db -> NG`; `43e2e3c1380d -> IMPLEMENT-17`; `b49690277fb5 -> NG`; `df12304d6a36 -> NG`; `52eacac11fef -> IMPLEMENT-17`; `60092df6b17b -> IMPLEMENT-17`; `361872c6b00e -> IMPLEMENT-17`; `d2bc711a75fb -> IMPLEMENT-17` |
238
- | `oat-project-implement/references/dispatch-and-dry-run.md` | `21b85f5e4daa -> IMPLEMENT-08`; `74c92b32bb2a -> IMPLEMENT-08`; `8efd2d0517ab -> IMPLEMENT-09`; `461ed9b3e495 -> IMPLEMENT-09`; `b5ad64fd744d -> NG`; `14ce436cfffa -> NG`; `043ca36da3e2 -> NG`; `a23e45c1dc8d -> NG`; `498143bb41a7 -> NG`; `4fe3eb179023 -> NG`; `7f75485e5a33 -> NG`; `8ec3a96df029 -> NG`; `16c3f96e758d -> NG`; `5915c41fe058 -> NG`; `f51e43eeac56 -> NG`; `fd41c25623cb -> NG`; `58a932ed6453 -> NG`; `4718bd3ce12d -> NG`; `58c444a2126b -> NG`; `2df3adae4120 -> NG`; `e75df892b55c -> NG` |
238
+ | `oat-project-implement/references/dispatch-and-dry-run.md` | `21b85f5e4daa -> IMPLEMENT-08`; `74c92b32bb2a -> IMPLEMENT-08`; `8efd2d0517ab -> IMPLEMENT-09`; `461ed9b3e495 -> IMPLEMENT-09`; `b5ad64fd744d -> NG`; `14ce436cfffa -> NG`; `043ca36da3e2 -> NG`; `a23e45c1dc8d -> NG`; `498143bb41a7 -> NG`; `4fe3eb179023 -> NG`; `7f75485e5a33 -> NG`; `8ec3a96df029 -> NG`; `16c3f96e758d -> NG`; `5915c41fe058 -> NG`; `f51e43eeac56 -> NG`; `fd41c25623cb -> NG`; `58a932ed6453 -> NG`; `4718bd3ce12d -> NG`; `58c444a2126b -> NG`; `2df3adae4120 -> NG`; `e75df892b55c -> NG`; `8ba5dbd2a0d8 -> NG` |
239
239
  | `oat-project-implement/references/docs/autonomy-contract.md` | `* -> NG` |
240
240
  | `oat-project-implement/references/phase-execution.md` | `27737e814790 -> NG`; `6dda2b8e62e2 -> IMPLEMENT-10`; `b3197086bb1e -> IMPLEMENT-10` |
241
241
  | `oat-project-implement/references/plan-and-resume.md` | `413829d31e32 -> IMPLEMENT-02`; `c7706cd8ad09 -> IMPLEMENT-03`; `a80a948df658 -> IMPLEMENT-03`; `b7ea139780ec -> IMPLEMENT-03+IMPLEMENT-04`; `8d438f2180ba -> IMPLEMENT-03`; `9e72e0518cda -> IMPLEMENT-03`; `3e177a1021e6 -> IMPLEMENT-03+IMPLEMENT-04`; `b59fc9eb9ce3 -> IMPLEMENT-03`; `a2b1d6855283 -> IMPLEMENT-03`; `44351a32e52a -> IMPLEMENT-03`; `b98b022f5523 -> IMPLEMENT-03`; `e9f5b949e214 -> IMPLEMENT-03`; `316fb6d9e980 -> IMPLEMENT-03`; `8b25a2c5c548 -> IMPLEMENT-03`; `1a59b1c0e705 -> IMPLEMENT-03`; `466cd562fc52 -> IMPLEMENT-03`; `083d896978d5 -> IMPLEMENT-03`; `f4ab11c13ae9 -> IMPLEMENT-03`; `7dc17ffcc1c4 -> IMPLEMENT-03`; `f731a90adabd -> IMPLEMENT-04`; `886ac01e7aa9 -> IMPLEMENT-04`; `b715db67df0c -> IMPLEMENT-04`; `2d9f26a539f3 -> IMPLEMENT-10`; `28384dee114f -> IMPLEMENT-05`; `f2591a4978b4 -> NG`; `8290823080b5 -> IMPLEMENT-06`; `f75789bf6c8e -> IMPLEMENT-07` |
@@ -235,7 +235,7 @@ remains immutable baseline evidence for the original p01-t01 verification.
235
235
  | `oat-project-import-plan/SKILL.md` | `f7ca8635452f -> NG`; `c2e5fa410069 -> NG`; `655d61df0a8f -> NG`; `dceff5cc04b5 -> NG`; `1af4957a1af2 -> IMPORT-01`; `45b699c1c0b5 -> IMPORT-01`; `ba6d120791c1 -> IMPORT-01`; `070ebc5259af -> IMPORT-03`; `c11552696e2e -> IMPORT-03`; `cfe661966baf -> IMPORT-04`; `baa91c0a0bf8 -> NG`; `e364e84b2702 -> NG`; `39031985a945 -> IMPORT-06`; `f106aa29a217 -> IMPORT-07`; `65038450aee3 -> IMPORT-07`; `bee4c4aa34c6 -> NG`; `3f0b53056edd -> IMPORT-09` |
236
236
  | `oat-project-implement/SKILL.md` | `18980f6bc1a6 -> NG`; `ffb3af0ba8ef -> NG`; `e0355c7a05e9 -> IMPLEMENT-11+IMPLEMENT-13+IMPLEMENT-16`; `6296f41ae11c -> NG`; `a167d03559fa -> NG`; `cf317c17c586 -> IMPLEMENT-01`; `8ce8a09feca4 -> NG`; `bd0cb4988188 -> NG`; `28af4ee0055d -> NG` |
237
237
  | `oat-project-implement/references/completion-and-closeout.md` | `f7dab9c1f96c -> IMPLEMENT-12`; `c69c17a069a8 -> IMPLEMENT-14`; `a97fa5634a68 -> IMPLEMENT-14`; `3af58881811c -> IMPLEMENT-14`; `4203e1f49d0f -> IMPLEMENT-14`; `c3bd2458a3d3 -> IMPLEMENT-13`; `95b5eafc070d -> IMPLEMENT-13`; `25ecbe9c998b -> IMPLEMENT-13+IMPLEMENT-14+IMPLEMENT-15+IMPLEMENT-16`; `f6f24fd71da4 -> IMPLEMENT-13+IMPLEMENT-14+IMPLEMENT-15+IMPLEMENT-16`; `f18283bc1cf9 -> IMPLEMENT-13+IMPLEMENT-14+IMPLEMENT-15+IMPLEMENT-16`; `2c1ffc4a82dd -> IMPLEMENT-13+IMPLEMENT-14+IMPLEMENT-15+IMPLEMENT-16`; `3454a07aa843 -> IMPLEMENT-16`; `0d86e2098cfb -> IMPLEMENT-13+IMPLEMENT-14+IMPLEMENT-15+IMPLEMENT-16`; `d5fe597d266f -> IMPLEMENT-13+IMPLEMENT-14+IMPLEMENT-15+IMPLEMENT-16`; `55a152e944c1 -> IMPLEMENT-16`; `effac7cbd573 -> IMPLEMENT-13+IMPLEMENT-14+IMPLEMENT-15+IMPLEMENT-16`; `9d2a34d8b148 -> IMPLEMENT-13+IMPLEMENT-14+IMPLEMENT-15+IMPLEMENT-16`; `d27462aaed26 -> IMPLEMENT-13+IMPLEMENT-14+IMPLEMENT-15+IMPLEMENT-16`; `9d52ecb17268 -> IMPLEMENT-13+IMPLEMENT-14+IMPLEMENT-15+IMPLEMENT-16`; `5b91aabe3757 -> IMPLEMENT-13+IMPLEMENT-14+IMPLEMENT-15+IMPLEMENT-16`; `fd0ad919f702 -> IMPLEMENT-13+IMPLEMENT-14+IMPLEMENT-15+IMPLEMENT-16`; `63bf28df1474 -> IMPLEMENT-13+IMPLEMENT-14+IMPLEMENT-15+IMPLEMENT-16`; `a4ed471dbc78 -> IMPLEMENT-16`; `6b7a64cec6e5 -> IMPLEMENT-16`; `0a4fdba0ebc0 -> IMPLEMENT-13+IMPLEMENT-14+IMPLEMENT-15+IMPLEMENT-16`; `a5033c2aada5 -> IMPLEMENT-13+IMPLEMENT-14+IMPLEMENT-15+IMPLEMENT-16`; `e77609eddba0 -> IMPLEMENT-13+IMPLEMENT-14+IMPLEMENT-15+IMPLEMENT-16`; `351156e8dde4 -> IMPLEMENT-13+IMPLEMENT-14+IMPLEMENT-15+IMPLEMENT-16`; `51d45bd2bbd1 -> IMPLEMENT-16`; `f7796ffcc804 -> IMPLEMENT-16`; `990d730cb494 -> IMPLEMENT-16`; `6ed28bb7d384 -> IMPLEMENT-16`; `8b7d4b5bcf1b -> IMPLEMENT-16`; `88aad500e6e9 -> IMPLEMENT-16`; `877e3e3f9eda -> IMPLEMENT-16`; `fc03c97f834e -> IMPLEMENT-16`; `12939a3da5e0 -> IMPLEMENT-16`; `bdb418335a88 -> IMPLEMENT-16`; `fba97e596ebd -> IMPLEMENT-16`; `3d0b5e2f14f0 -> IMPLEMENT-17`; `87f1424a8692 -> NG`; `6b1ec05182f0 -> IMPLEMENT-11`; `e6d696a27c91 -> NG`; `c77f8ccb52ad -> NG`; `48de2614c0ba -> IMPLEMENT-11`; `32d53f5212e5 -> IMPLEMENT-11`; `7cdb4a9c57b7 -> IMPLEMENT-11`; `16ffc0aa099b -> IMPLEMENT-11`; `d6868ea10b3f -> IMPLEMENT-11`; `4f05ff5567be -> IMPLEMENT-11`; `c70b47ae7a6d -> IMPLEMENT-11`; `5fafd093b58e -> NG`; `567d43ab0c2e -> NG`; `21ceaf7e658a -> NG`; `249427a9f475 -> NG`; `8a7ec13a9b7c -> NG`; `9aeb7fce2012 -> IMPLEMENT-18`; `f11a7cdda220 -> IMPLEMENT-18`; `4523ac029152 -> NG`; `6e87b08c4046 -> NG`; `baa6052c7f0a -> IMPLEMENT-18`; `27d3fad116b1 -> IMPLEMENT-18`; `2cfbeb4388a5 -> IMPLEMENT-18`; `c56ea56a56db -> NG`; `43e2e3c1380d -> IMPLEMENT-17`; `b49690277fb5 -> NG`; `df12304d6a36 -> NG`; `52eacac11fef -> IMPLEMENT-17`; `60092df6b17b -> IMPLEMENT-17`; `361872c6b00e -> IMPLEMENT-17`; `d2bc711a75fb -> IMPLEMENT-17` |
238
- | `oat-project-implement/references/dispatch-and-dry-run.md` | `21b85f5e4daa -> IMPLEMENT-08`; `74c92b32bb2a -> IMPLEMENT-08`; `8efd2d0517ab -> IMPLEMENT-09`; `461ed9b3e495 -> IMPLEMENT-09`; `b5ad64fd744d -> NG`; `14ce436cfffa -> NG`; `043ca36da3e2 -> NG`; `a23e45c1dc8d -> NG`; `498143bb41a7 -> NG`; `4fe3eb179023 -> NG`; `7f75485e5a33 -> NG`; `8ec3a96df029 -> NG`; `16c3f96e758d -> NG`; `5915c41fe058 -> NG`; `f51e43eeac56 -> NG`; `fd41c25623cb -> NG`; `58a932ed6453 -> NG`; `4718bd3ce12d -> NG`; `58c444a2126b -> NG`; `2df3adae4120 -> NG`; `e75df892b55c -> NG` |
238
+ | `oat-project-implement/references/dispatch-and-dry-run.md` | `21b85f5e4daa -> IMPLEMENT-08`; `74c92b32bb2a -> IMPLEMENT-08`; `8efd2d0517ab -> IMPLEMENT-09`; `461ed9b3e495 -> IMPLEMENT-09`; `b5ad64fd744d -> NG`; `14ce436cfffa -> NG`; `043ca36da3e2 -> NG`; `a23e45c1dc8d -> NG`; `498143bb41a7 -> NG`; `4fe3eb179023 -> NG`; `7f75485e5a33 -> NG`; `8ec3a96df029 -> NG`; `16c3f96e758d -> NG`; `5915c41fe058 -> NG`; `f51e43eeac56 -> NG`; `fd41c25623cb -> NG`; `58a932ed6453 -> NG`; `4718bd3ce12d -> NG`; `58c444a2126b -> NG`; `2df3adae4120 -> NG`; `e75df892b55c -> NG`; `8ba5dbd2a0d8 -> NG` |
239
239
  | `oat-project-implement/references/docs/autonomy-contract.md` | `* -> NG` |
240
240
  | `oat-project-implement/references/phase-execution.md` | `27737e814790 -> NG`; `6dda2b8e62e2 -> IMPLEMENT-10`; `b3197086bb1e -> IMPLEMENT-10` |
241
241
  | `oat-project-implement/references/plan-and-resume.md` | `413829d31e32 -> IMPLEMENT-02`; `c7706cd8ad09 -> IMPLEMENT-03`; `a80a948df658 -> IMPLEMENT-03`; `b7ea139780ec -> IMPLEMENT-03+IMPLEMENT-04`; `8d438f2180ba -> IMPLEMENT-03`; `9e72e0518cda -> IMPLEMENT-03`; `3e177a1021e6 -> IMPLEMENT-03+IMPLEMENT-04`; `b59fc9eb9ce3 -> IMPLEMENT-03`; `a2b1d6855283 -> IMPLEMENT-03`; `44351a32e52a -> IMPLEMENT-03`; `b98b022f5523 -> IMPLEMENT-03`; `e9f5b949e214 -> IMPLEMENT-03`; `316fb6d9e980 -> IMPLEMENT-03`; `8b25a2c5c548 -> IMPLEMENT-03`; `1a59b1c0e705 -> IMPLEMENT-03`; `466cd562fc52 -> IMPLEMENT-03`; `083d896978d5 -> IMPLEMENT-03`; `f4ab11c13ae9 -> IMPLEMENT-03`; `7dc17ffcc1c4 -> IMPLEMENT-03`; `f731a90adabd -> IMPLEMENT-04`; `886ac01e7aa9 -> IMPLEMENT-04`; `b715db67df0c -> IMPLEMENT-04`; `2d9f26a539f3 -> IMPLEMENT-10`; `28384dee114f -> IMPLEMENT-05`; `f2591a4978b4 -> NG`; `8290823080b5 -> IMPLEMENT-06`; `f75789bf6c8e -> IMPLEMENT-07` |
@@ -1,6 +1,6 @@
1
1
  ---
2
2
  name: subagent-orchestration
3
- version: 1.0.1
3
+ version: 1.0.2
4
4
  description: Use when delegating work to subagents or choosing a model for a task — routing by task class, selecting provider-specific models and effort, and verifying subagent claims. Covers OpenAI/Codex, Anthropic/Claude, and Cursor.
5
5
  compatibility: Self-contained; no OAT installation required.
6
6
  user-invocable: true
@@ -60,6 +60,15 @@ still require enough capability to use tools, follow scope, and return complete
60
60
  evidence. Prefer scripts over models when a deterministic program fully solves
61
61
  the task.
62
62
 
63
+ A named route is only usable where the harness can actually select it. The
64
+ models named per task class in these references are dated examples, and a
65
+ harness will often expose a different set. When a named route is unavailable,
66
+ substitute one meeting the same class floor, or move one class up; never fall
67
+ through to the strongest model on offer merely because the named one was
68
+ missing. Where a harness restricts selection to a configured set, keep enough
69
+ distinct entries that a classification has somewhere to land — a set holding a
70
+ single entry cannot express a choice, only a default.
71
+
63
72
  ## Escalation Boundaries
64
73
 
65
74
  - Mechanical to intelligent recon when judgment is required to identify a
@@ -170,6 +179,15 @@ instantiations in provider guidance are dated and provisional unless a relevant
170
179
  evaluation qualifies them. Reviewer independence never transfers authorization
171
180
  away from the root.
172
181
 
182
+ One exception to effort following reasoning depth is worth stating so it does
183
+ not read as a contradiction. A quality gate may hold its reviewer at a fixed
184
+ configured rung regardless of the phase under review, because a gate that
185
+ varies its reviewer stops being comparable across runs and a regression becomes
186
+ indistinguishable from a change of reviewer. That is a determinism argument
187
+ rather than a depth argument, and it applies to the gate's own reviewer, not to
188
+ review generally: it neither raises the authoring route nor licenses treating
189
+ consequence as a reason for top effort elsewhere.
190
+
173
191
  ## Staleness
174
192
 
175
193
  Read `evidence-and-refresh.md` when provider guidance is review-required or
@@ -0,0 +1,32 @@
1
+ import type { GateActivityEvidence, GateActivityProbe, GateActivityProbeStatus } from './activity-probes.js';
2
+ export interface ProcessRunOptions {
3
+ activityProbe?: GateActivityProbe;
4
+ cwd: string;
5
+ env: NodeJS.ProcessEnv;
6
+ livenessIntervalMs?: number;
7
+ onLiveness?: (snapshot: GateLivenessSnapshot) => void;
8
+ purpose: 'host-detection' | 'availability' | 'execute';
9
+ stdin: 'ignore' | 'inherit';
10
+ stdio: 'ignore' | 'inherit' | 'pipe';
11
+ stdoutDestination?: 'stdout' | 'stderr';
12
+ timeoutMs: number;
13
+ }
14
+ export interface ProcessRunResult {
15
+ activityEvidence?: GateActivityEvidence;
16
+ exitCode: number;
17
+ refusal?: string;
18
+ stderrBytes: number;
19
+ stdoutBytes: number;
20
+ timedOut?: boolean;
21
+ }
22
+ export interface GateLivenessSnapshot {
23
+ elapsedMs: number;
24
+ hardBudgetMs: number;
25
+ idleMs: number;
26
+ processAlive: boolean;
27
+ activityProbeStatus?: GateActivityProbeStatus;
28
+ lastActivityEvidence?: GateActivityEvidence;
29
+ }
30
+ export declare function runChildProcess(command: string, args: string[], options: ProcessRunOptions): Promise<ProcessRunResult>;
31
+ export declare function extractStructuredRefusal(output: string): string | undefined;
32
+ //# sourceMappingURL=child-process.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"child-process.d.ts","sourceRoot":"","sources":["../../../src/commands/gate/child-process.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EACV,oBAAoB,EACpB,iBAAiB,EACjB,uBAAuB,EACxB,MAAM,mBAAmB,CAAC;AAS3B,MAAM,WAAW,iBAAiB;IAChC,aAAa,CAAC,EAAE,iBAAiB,CAAC;IAClC,GAAG,EAAE,MAAM,CAAC;IACZ,GAAG,EAAE,MAAM,CAAC,UAAU,CAAC;IACvB,kBAAkB,CAAC,EAAE,MAAM,CAAC;IAC5B,UAAU,CAAC,EAAE,CAAC,QAAQ,EAAE,oBAAoB,KAAK,IAAI,CAAC;IACtD,OAAO,EAAE,gBAAgB,GAAG,cAAc,GAAG,SAAS,CAAC;IACvD,KAAK,EAAE,QAAQ,GAAG,SAAS,CAAC;IAC5B,KAAK,EAAE,QAAQ,GAAG,SAAS,GAAG,MAAM,CAAC;IACrC,iBAAiB,CAAC,EAAE,QAAQ,GAAG,QAAQ,CAAC;IACxC,SAAS,EAAE,MAAM,CAAC;CACnB;AAED,MAAM,WAAW,gBAAgB;IAC/B,gBAAgB,CAAC,EAAE,oBAAoB,CAAC;IACxC,QAAQ,EAAE,MAAM,CAAC;IACjB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,WAAW,EAAE,MAAM,CAAC;IACpB,WAAW,EAAE,MAAM,CAAC;IACpB,QAAQ,CAAC,EAAE,OAAO,CAAC;CACpB;AAED,MAAM,WAAW,oBAAoB;IACnC,SAAS,EAAE,MAAM,CAAC;IAClB,YAAY,EAAE,MAAM,CAAC;IACrB,MAAM,EAAE,MAAM,CAAC;IACf,YAAY,EAAE,OAAO,CAAC;IACtB,mBAAmB,CAAC,EAAE,uBAAuB,CAAC;IAC9C,oBAAoB,CAAC,EAAE,oBAAoB,CAAC;CAC7C;AAED,wBAAsB,eAAe,CACnC,OAAO,EAAE,MAAM,EACf,IAAI,EAAE,MAAM,EAAE,EACd,OAAO,EAAE,iBAAiB,GACzB,OAAO,CAAC,gBAAgB,CAAC,CAgN3B;AAED,wBAAgB,wBAAwB,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS,CAG3E"}
@@ -0,0 +1,210 @@
1
+ import { spawn } from 'node:child_process';
2
+ // Keep these safety bounds fixed rather than environment-tunable. In particular,
3
+ // changing the force-kill fallback would alter the hard-timeout contract.
4
+ // Revisit the observation grace only if field evidence shows large transcript
5
+ // directories routinely exceed it.
6
+ const FORCE_KILL_GRACE_MS = 5_000;
7
+ const ACTIVITY_OBSERVATION_GRACE_MS = 1_000;
8
+ export async function runChildProcess(command, args, options) {
9
+ return new Promise((resolve, reject) => {
10
+ let timedOut = false;
11
+ let suppressLiveness = false;
12
+ let killTimeout = null;
13
+ let stderrBytes = 0;
14
+ let stdoutBytes = 0;
15
+ let refusal;
16
+ let stdoutLineBuffer = '';
17
+ let stderrLineBuffer = '';
18
+ let latestActivityEvidence;
19
+ let latestActivityProbeStatus;
20
+ let activityObservationSequence = 0;
21
+ let latestActivityEvidenceSequence = 0;
22
+ let livenessProbePending = false;
23
+ let pendingPeriodicObservation;
24
+ let finalActivityObservation;
25
+ const startedAt = Date.now();
26
+ let lastActivityAt = startedAt;
27
+ const child = spawn(command, args, {
28
+ cwd: options.cwd,
29
+ env: options.env,
30
+ stdio: options.stdio === 'pipe'
31
+ ? [options.stdin, 'pipe', 'pipe']
32
+ : options.stdio,
33
+ });
34
+ const recordActivity = () => {
35
+ lastActivityAt = Date.now();
36
+ };
37
+ const scanChunk = (buffer, chunk) => {
38
+ const combined = buffer + chunk.toString('utf8');
39
+ const lines = combined.split('\n');
40
+ const remainder = lines.pop() ?? '';
41
+ if (!refusal) {
42
+ for (const line of lines) {
43
+ refusal = extractStructuredRefusal(line.replace(/\r$/, ''));
44
+ if (refusal) {
45
+ break;
46
+ }
47
+ }
48
+ }
49
+ return remainder;
50
+ };
51
+ child.stdout?.on('data', (chunk) => {
52
+ stdoutBytes += chunk.byteLength;
53
+ stdoutLineBuffer = scanChunk(stdoutLineBuffer, chunk);
54
+ recordActivity();
55
+ const destination = options.stdoutDestination === 'stderr'
56
+ ? process.stderr
57
+ : process.stdout;
58
+ destination.write(chunk);
59
+ });
60
+ child.stderr?.on('data', (chunk) => {
61
+ stderrBytes += chunk.byteLength;
62
+ stderrLineBuffer = scanChunk(stderrLineBuffer, chunk);
63
+ recordActivity();
64
+ process.stderr.write(chunk);
65
+ });
66
+ const processAlive = () => {
67
+ if (child.pid === undefined)
68
+ return false;
69
+ try {
70
+ process.kill(child.pid, 0);
71
+ return true;
72
+ }
73
+ catch {
74
+ return false;
75
+ }
76
+ };
77
+ const observeActivity = async (observedAt) => {
78
+ if (!options.activityProbe)
79
+ return undefined;
80
+ const sequence = ++activityObservationSequence;
81
+ try {
82
+ const activityProbeStatus = await options.activityProbe.observe(observedAt);
83
+ const evidence = activityProbeStatus.evidence;
84
+ if (evidence && sequence > latestActivityEvidenceSequence) {
85
+ latestActivityEvidence = evidence;
86
+ latestActivityEvidenceSequence = sequence;
87
+ }
88
+ return activityProbeStatus;
89
+ }
90
+ catch {
91
+ // Activity evidence is diagnostic only. Preserve the last valid sample.
92
+ return undefined;
93
+ }
94
+ };
95
+ const settleWithinActivityGrace = (observation) => new Promise((resolveObservation) => {
96
+ // Keep this timer referenced so a closed child cannot end the process
97
+ // before the bounded diagnostic observation settles.
98
+ const graceTimeout = setTimeout(resolveObservation, ACTIVITY_OBSERVATION_GRACE_MS);
99
+ const settle = () => {
100
+ clearTimeout(graceTimeout);
101
+ resolveObservation();
102
+ };
103
+ void observation.then(settle, settle);
104
+ });
105
+ const livenessInterval = options.onLiveness && options.livenessIntervalMs
106
+ ? setInterval(() => {
107
+ if (livenessProbePending)
108
+ return;
109
+ livenessProbePending = true;
110
+ const now = Date.now();
111
+ const observation = (async () => {
112
+ const activityProbeStatus = await observeActivity(now);
113
+ if (activityProbeStatus) {
114
+ latestActivityProbeStatus = activityProbeStatus;
115
+ }
116
+ if (suppressLiveness)
117
+ return;
118
+ options.onLiveness?.({
119
+ elapsedMs: now - startedAt,
120
+ hardBudgetMs: options.timeoutMs,
121
+ idleMs: now - lastActivityAt,
122
+ processAlive: processAlive(),
123
+ ...(latestActivityProbeStatus
124
+ ? { activityProbeStatus: latestActivityProbeStatus }
125
+ : {}),
126
+ ...(latestActivityEvidence
127
+ ? { lastActivityEvidence: latestActivityEvidence }
128
+ : {}),
129
+ });
130
+ })();
131
+ pendingPeriodicObservation = observation;
132
+ const clearPending = () => {
133
+ if (pendingPeriodicObservation === observation) {
134
+ pendingPeriodicObservation = undefined;
135
+ }
136
+ livenessProbePending = false;
137
+ };
138
+ void observation.then(clearPending, clearPending);
139
+ }, options.livenessIntervalMs)
140
+ : null;
141
+ livenessInterval?.unref();
142
+ const timeout = setTimeout(() => {
143
+ timedOut = true;
144
+ suppressLiveness = true;
145
+ if (livenessInterval) {
146
+ clearInterval(livenessInterval);
147
+ }
148
+ child.kill('SIGTERM');
149
+ killTimeout = setTimeout(() => {
150
+ child.kill('SIGKILL');
151
+ }, FORCE_KILL_GRACE_MS);
152
+ killTimeout.unref();
153
+ finalActivityObservation = observeActivity(Date.now());
154
+ }, options.timeoutMs);
155
+ timeout.unref();
156
+ child.on('error', (error) => {
157
+ clearTimeout(timeout);
158
+ if (livenessInterval) {
159
+ clearInterval(livenessInterval);
160
+ }
161
+ if (killTimeout) {
162
+ clearTimeout(killTimeout);
163
+ }
164
+ reject(error);
165
+ });
166
+ child.on('close', (code) => {
167
+ suppressLiveness = true;
168
+ clearTimeout(timeout);
169
+ if (livenessInterval) {
170
+ clearInterval(livenessInterval);
171
+ }
172
+ if (killTimeout) {
173
+ clearTimeout(killTimeout);
174
+ }
175
+ void (async () => {
176
+ if (finalActivityObservation) {
177
+ const periodicObservation = pendingPeriodicObservation;
178
+ const finalThenFallback = finalActivityObservation.then(async (activityProbeStatus) => {
179
+ if (!activityProbeStatus?.evidence && periodicObservation) {
180
+ await periodicObservation;
181
+ }
182
+ });
183
+ await settleWithinActivityGrace(finalThenFallback);
184
+ }
185
+ else if (pendingPeriodicObservation) {
186
+ // Preserve evidence already in flight on a normal close. This can add
187
+ // up to the bounded grace to an otherwise successful execution.
188
+ await settleWithinActivityGrace(pendingPeriodicObservation);
189
+ }
190
+ refusal ??=
191
+ extractStructuredRefusal(stdoutLineBuffer.replace(/\r$/, '')) ??
192
+ extractStructuredRefusal(stderrLineBuffer.replace(/\r$/, ''));
193
+ resolve({
194
+ ...(latestActivityEvidence
195
+ ? { activityEvidence: latestActivityEvidence }
196
+ : {}),
197
+ exitCode: timedOut ? 124 : (code ?? 1),
198
+ ...(refusal ? { refusal } : {}),
199
+ stderrBytes,
200
+ stdoutBytes,
201
+ ...(timedOut ? { timedOut: true } : {}),
202
+ });
203
+ })();
204
+ });
205
+ });
206
+ }
207
+ export function extractStructuredRefusal(output) {
208
+ const match = output.match(/^OAT_GATE_REFUSAL: (.*)$/m);
209
+ return match?.[1]?.replace(/\r$/, '');
210
+ }
@@ -5,8 +5,9 @@ import { type ResolvedConfig } from '../../config/resolve.js';
5
5
  import { type ModelFamily } from '../../providers/identity/family.js';
6
6
  import { type IdentityConfidence, type IdentityProvenance } from '../../providers/identity/provenance.js';
7
7
  import { Command } from 'commander';
8
- import { createGateActivityProbe, type GateActivityEvidence, type GateActivityProbe, type GateActivityProbeStatus } from './activity-probes.js';
8
+ import { createGateActivityProbe } from './activity-probes.js';
9
9
  import { createBranchLocalGateCli, currentGateCliLaunch, readGateRouteReceipt, removeBranchLocalGateCli } from './branch-local-cli.js';
10
+ import { type ProcessRunOptions, type ProcessRunResult } from './child-process.js';
10
11
  import { parseReviewGateVerdict } from './review-verdict.js';
11
12
  interface GateCommandDependencies {
12
13
  buildCommandContext: (options: GlobalOptions) => CommandContext;
@@ -31,36 +32,6 @@ interface GateCommandDependencies {
31
32
  removeGateRunMarker: (path: string, warn: (message: string) => void) => Promise<void>;
32
33
  writeDiagnostic: (message: string) => void;
33
34
  }
34
- interface ProcessRunOptions {
35
- activityProbe?: GateActivityProbe;
36
- cwd: string;
37
- env: NodeJS.ProcessEnv;
38
- livenessIntervalMs?: number;
39
- onLiveness?: (snapshot: GateLivenessSnapshot) => void;
40
- purpose: 'host-detection' | 'availability' | 'execute';
41
- stdin: 'ignore' | 'inherit';
42
- stdio: 'ignore' | 'inherit' | 'pipe';
43
- stdoutDestination?: 'stdout' | 'stderr';
44
- timeoutMs: number;
45
- }
46
- interface ProcessRunResult {
47
- activityEvidence?: GateActivityEvidence;
48
- activityProbeStatus?: GateActivityProbeStatus;
49
- capturedOutput?: string;
50
- exitCode: number;
51
- refusal?: string;
52
- stderrBytes: number;
53
- stdoutBytes: number;
54
- timedOut?: boolean;
55
- }
56
- interface GateLivenessSnapshot {
57
- elapsedMs: number;
58
- hardBudgetMs: number;
59
- idleMs: number;
60
- processAlive: boolean;
61
- activityProbeStatus?: GateActivityProbeStatus;
62
- lastActivityEvidence?: GateActivityEvidence;
63
- }
64
35
  type GateTimeoutSource = 'cli' | 'target' | 'config' | 'env' | 'scope-default' | 'default';
65
36
  interface GateRunMarker {
66
37
  runId: string;
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/commands/gate/index.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/commands/gate/index.ts"],"names":[],"mappings":"AAMA,OAAO,EAEL,KAAK,cAAc,EACnB,KAAK,aAAa,EACnB,MAAM,sBAAsB,CAAC;AAC9B,OAAO,EAAE,gBAAgB,EAAE,MAAM,8BAA8B,CAAC;AAShE,OAAO,EAWL,KAAK,UAAU,EAIf,KAAK,SAAS,EACd,KAAK,cAAc,EACnB,KAAK,UAAU,EAEhB,MAAM,oBAAoB,CAAC;AAC5B,OAAO,EAKL,KAAK,cAAc,EACpB,MAAM,iBAAiB,CAAC;AAWzB,OAAO,EAEL,KAAK,WAAW,EACjB,MAAM,4BAA4B,CAAC;AACpC,OAAO,EAEL,KAAK,kBAAkB,EACvB,KAAK,kBAAkB,EAExB,MAAM,gCAAgC,CAAC;AAExC,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAGpC,OAAO,EACL,uBAAuB,EAExB,MAAM,mBAAmB,CAAC;AAC3B,OAAO,EACL,wBAAwB,EACxB,oBAAoB,EACpB,oBAAoB,EACpB,wBAAwB,EAEzB,MAAM,oBAAoB,CAAC;AAC5B,OAAO,EAEL,KAAK,iBAAiB,EACtB,KAAK,gBAAgB,EACtB,MAAM,iBAAiB,CAAC;AACzB,OAAO,EACL,sBAAsB,EAIvB,MAAM,kBAAkB,CAAC;AAG1B,UAAU,uBAAuB;IAC/B,mBAAmB,EAAE,CAAC,OAAO,EAAE,aAAa,KAAK,cAAc,CAAC;IAChE,kBAAkB,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,OAAO,CAAC,MAAM,CAAC,CAAC;IACrD,aAAa,EAAE,CAAC,QAAQ,EAAE,MAAM,KAAK,OAAO,CAAC,SAAS,CAAC,CAAC;IACxD,cAAc,EAAE,CAAC,QAAQ,EAAE,MAAM,EAAE,MAAM,EAAE,SAAS,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;IACvE,kBAAkB,EAAE,CAAC,QAAQ,EAAE,MAAM,KAAK,OAAO,CAAC,cAAc,CAAC,CAAC;IAClE,mBAAmB,EAAE,CACnB,QAAQ,EAAE,MAAM,EAChB,MAAM,EAAE,cAAc,KACnB,OAAO,CAAC,IAAI,CAAC,CAAC;IACnB,cAAc,EAAE,CAAC,aAAa,EAAE,MAAM,KAAK,OAAO,CAAC,UAAU,CAAC,CAAC;IAC/D,eAAe,EAAE,CAAC,aAAa,EAAE,MAAM,EAAE,MAAM,EAAE,UAAU,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;IAC9E,sBAAsB,EAAE,CACtB,QAAQ,EAAE,MAAM,EAChB,aAAa,EAAE,MAAM,EACrB,GAAG,EAAE,MAAM,CAAC,UAAU,KACnB,OAAO,CAAC,cAAc,CAAC,CAAC;IAC7B,uBAAuB,EAAE,OAAO,uBAAuB,CAAC;IACxD,wBAAwB,EAAE,OAAO,wBAAwB,CAAC;IAC1D,oBAAoB,EAAE,OAAO,oBAAoB,CAAC;IAClD,wBAAwB,EAAE,OAAO,wBAAwB,CAAC;IAC1D,oBAAoB,EAAE,OAAO,oBAAoB,CAAC;IAClD,UAAU,EAAE,CACV,OAAO,EAAE,MAAM,EACf,IAAI,EAAE,MAAM,EAAE,EACd,OAAO,EAAE,iBAAiB,KACvB,OAAO,CAAC,gBAAgB,CAAC,CAAC;IAC/B,sBAAsB,EAAE,OAAO,sBAAsB,CAAC;IACtD,gBAAgB,EAAE,OAAO,gBAAgB,CAAC;IAC1C,UAAU,EAAE,MAAM,CAAC,UAAU,CAAC;IAC9B,kBAAkB,EAAE,CAClB,IAAI,EAAE,MAAM,EACZ,MAAM,EAAE,aAAa,EACrB,IAAI,EAAE,CAAC,OAAO,EAAE,MAAM,KAAK,IAAI,KAC5B,OAAO,CAAC,OAAO,CAAC,CAAC;IACtB,mBAAmB,EAAE,CACnB,IAAI,EAAE,MAAM,EACZ,IAAI,EAAE,CAAC,OAAO,EAAE,MAAM,KAAK,IAAI,KAC5B,OAAO,CAAC,IAAI,CAAC,CAAC;IACnB,eAAe,EAAE,CAAC,OAAO,EAAE,MAAM,KAAK,IAAI,CAAC;CAC5C;AA+CD,KAAK,iBAAiB,GAClB,KAAK,GACL,QAAQ,GACR,QAAQ,GACR,KAAK,GACL,eAAe,GACf,SAAS,CAAC;AAOd,UAAU,aAAa;IACrB,KAAK,EAAE,MAAM,CAAC;IACd,QAAQ,EAAE,MAAM,CAAC;IACjB,OAAO,EAAE,MAAM,CAAC;IAChB,UAAU,EAAE,MAAM,GAAG,IAAI,CAAC;IAC1B,WAAW,EAAE,MAAM,GAAG,IAAI,CAAC;IAC3B,OAAO,EAAE,MAAM,CAAC;IAChB,SAAS,EAAE,MAAM,CAAC;IAClB,QAAQ,EAAE,MAAM,CAAC;IACjB,YAAY,EAAE,iBAAiB,CAAC;CACjC;AAcD,KAAK,kBAAkB,GAAG,aAAa,GAAG,cAAc,GAAG,MAAM,CAAC;AAClE,KAAK,qBAAqB,GACtB,kBAAkB,GAClB,4BAA4B,GAC5B,2CAA2C,GAC3C,kBAAkB,CAAC;AA4BvB,MAAM,WAAW,kBAAkB;IACjC,EAAE,EAAE,MAAM,CAAC;IACX,MAAM,EAAE,UAAU,CAAC;IACnB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,MAAM,EAAE,WAAW,CAAC;IACpB,SAAS,CAAC,EAAE,qBAAqB,CAAC;IAClC,uBAAuB,CAAC,EAAE,OAAO,CAAC;CACnC;AAED,UAAU,oBAAoB;IAC5B,KAAK,EAAE,MAAM,CAAC;IACd,UAAU,EAAE,kBAAkB,CAAC;IAC/B,UAAU,EAAE,kBAAkB,CAAC;IAC/B,MAAM,EAAE,WAAW,CAAC;IACpB,aAAa,EAAE,WAAW,EAAE,CAAC;IAC7B,kBAAkB,CAAC,EAAE,MAAM,EAAE,CAAC;IAC9B,sBAAsB,CAAC,EAAE,MAAM,CAAC;IAChC,kBAAkB,EAAE,OAAO,CAAC;IAC5B,MAAM,EAAE,MAAM,GAAG,OAAO,GAAG,mBAAmB,GAAG,aAAa,GAAG,SAAS,CAAC;CAC5E;AAED,UAAU,qBAAqB;IAC7B,KAAK,EAAE,kBAAkB,CAAC;IAC1B,QAAQ,EAAE,qBAAqB,CAAC;IAChC,QAAQ,EAAE;QACR,KAAK,EAAE,MAAM,CAAC;QACd,UAAU,EAAE,kBAAkB,CAAC;QAC/B,UAAU,EAAE,kBAAkB,CAAC;QAC/B,MAAM,EAAE,WAAW,CAAC;QACpB,MAAM,EAAE,oBAAoB,CAAC,QAAQ,CAAC,CAAC;QACvC,aAAa,EAAE,WAAW,EAAE,CAAC;QAC7B,kBAAkB,CAAC,EAAE,MAAM,EAAE,CAAC;QAC9B,sBAAsB,CAAC,EAAE,MAAM,CAAC;KACjC,CAAC;IACF,QAAQ,EAAE;QACR,MAAM,EAAE,MAAM,CAAC;QACf,OAAO,EAAE,MAAM,CAAC;QAChB,MAAM,EAAE,WAAW,CAAC;QACpB,KAAK,CAAC,EAAE,MAAM,CAAC;KAChB,CAAC;IACF,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AA+xCD,wBAAgB,gBAAgB,CAC9B,QAAQ,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,UAAU,CAAC,CAAC,EAC9C,cAAc,EAAE,MAAM,EACtB,KAAK,EAAE,kBAAkB,EACzB,gBAAgB,CAAC,EAAE,oBAAoB,GACtC,kBAAkB,GAAG,IAAI,CAS3B;AAy/DD,wBAAgB,iBAAiB,CAC/B,SAAS,GAAE,OAAO,CAAC,uBAAuB,CAAM,GAC/C,OAAO,CA4NT"}
@@ -1,4 +1,4 @@
1
- import { execFileSync, spawn } from 'node:child_process';
1
+ import { execFileSync } from 'node:child_process';
2
2
  import { createHash, randomUUID } from 'node:crypto';
3
3
  import { mkdir, readdir, readFile, rm, writeFile } from 'node:fs/promises';
4
4
  import { tmpdir } from 'node:os';
@@ -20,6 +20,7 @@ import { Command } from 'commander';
20
20
  import YAML from 'yaml';
21
21
  import { createGateActivityProbe, } from './activity-probes.js';
22
22
  import { createBranchLocalGateCli, currentGateCliLaunch, readGateRouteReceipt, removeBranchLocalGateCli, } from './branch-local-cli.js';
23
+ import { runChildProcess, } from './child-process.js';
23
24
  import { parseReviewGateVerdict, severityDisplayName, } from './review-verdict.js';
24
25
  import { createGateRouteCommand } from './route.js';
25
26
  const DEFAULT_DEPENDENCIES = {
@@ -75,6 +76,7 @@ const REVIEW_GATE_CONTEXT_NOTE = [
75
76
  const GATE_CHECK_TIMEOUT_MS = 5_000;
76
77
  const GATE_EXEC_TIMEOUT_MS = 15 * 60 * 1_000;
77
78
  const GATE_LIVENESS_INTERVAL_MS = 30_000;
79
+ const AMBIENT_ACTIVITY_ATTRIBUTION = 'not attributable to this gate child';
78
80
  async function writeGateRunMarker(path, marker, warn) {
79
81
  try {
80
82
  await mkdir(join(tmpdir(), 'oat-gate-runs'), { recursive: true });
@@ -239,152 +241,6 @@ function corroborateGateInvocation(expected, actual, targetCorroboration) {
239
241
  },
240
242
  };
241
243
  }
242
- async function runChildProcess(command, args, options) {
243
- return new Promise((resolve, reject) => {
244
- let timedOut = false;
245
- let killTimeout = null;
246
- let stderrBytes = 0;
247
- let stdoutBytes = 0;
248
- let refusal;
249
- let stdoutLineBuffer = '';
250
- let stderrLineBuffer = '';
251
- let latestActivityEvidence;
252
- let latestActivityProbeStatus;
253
- let livenessProbePending = false;
254
- const startedAt = Date.now();
255
- let lastActivityAt = startedAt;
256
- const child = spawn(command, args, {
257
- cwd: options.cwd,
258
- env: options.env,
259
- stdio: options.stdio === 'pipe'
260
- ? [options.stdin, 'pipe', 'pipe']
261
- : options.stdio,
262
- });
263
- const recordActivity = () => {
264
- lastActivityAt = Date.now();
265
- };
266
- const scanChunk = (buffer, chunk) => {
267
- const combined = buffer + chunk.toString('utf8');
268
- const lines = combined.split('\n');
269
- const remainder = lines.pop() ?? '';
270
- if (!refusal) {
271
- for (const line of lines) {
272
- refusal = extractStructuredRefusal(line.replace(/\r$/, ''));
273
- if (refusal) {
274
- break;
275
- }
276
- }
277
- }
278
- return remainder;
279
- };
280
- child.stdout?.on('data', (chunk) => {
281
- stdoutBytes += chunk.byteLength;
282
- stdoutLineBuffer = scanChunk(stdoutLineBuffer, chunk);
283
- recordActivity();
284
- const destination = options.stdoutDestination === 'stderr'
285
- ? process.stderr
286
- : process.stdout;
287
- destination.write(chunk);
288
- });
289
- child.stderr?.on('data', (chunk) => {
290
- stderrBytes += chunk.byteLength;
291
- stderrLineBuffer = scanChunk(stderrLineBuffer, chunk);
292
- recordActivity();
293
- process.stderr.write(chunk);
294
- });
295
- const processAlive = () => {
296
- if (child.pid === undefined)
297
- return false;
298
- try {
299
- process.kill(child.pid, 0);
300
- return true;
301
- }
302
- catch {
303
- return false;
304
- }
305
- };
306
- const livenessInterval = options.onLiveness && options.livenessIntervalMs
307
- ? setInterval(() => {
308
- if (livenessProbePending)
309
- return;
310
- livenessProbePending = true;
311
- const now = Date.now();
312
- void (async () => {
313
- const activityProbeStatus = await options.activityProbe?.observe(now);
314
- const evidence = activityProbeStatus?.evidence;
315
- if (activityProbeStatus) {
316
- latestActivityProbeStatus = activityProbeStatus;
317
- }
318
- if (evidence)
319
- latestActivityEvidence = evidence;
320
- options.onLiveness?.({
321
- elapsedMs: now - startedAt,
322
- hardBudgetMs: options.timeoutMs,
323
- idleMs: now - lastActivityAt,
324
- processAlive: processAlive(),
325
- ...(latestActivityProbeStatus
326
- ? { activityProbeStatus: latestActivityProbeStatus }
327
- : {}),
328
- ...(latestActivityEvidence
329
- ? { lastActivityEvidence: latestActivityEvidence }
330
- : {}),
331
- });
332
- })().finally(() => {
333
- livenessProbePending = false;
334
- });
335
- }, options.livenessIntervalMs)
336
- : null;
337
- livenessInterval?.unref();
338
- const timeout = setTimeout(() => {
339
- timedOut = true;
340
- child.kill('SIGTERM');
341
- killTimeout = setTimeout(() => {
342
- child.kill('SIGKILL');
343
- }, 5_000);
344
- killTimeout.unref();
345
- }, options.timeoutMs);
346
- timeout.unref();
347
- child.on('error', (error) => {
348
- clearTimeout(timeout);
349
- if (livenessInterval) {
350
- clearInterval(livenessInterval);
351
- }
352
- if (killTimeout) {
353
- clearTimeout(killTimeout);
354
- }
355
- reject(error);
356
- });
357
- child.on('close', (code) => {
358
- clearTimeout(timeout);
359
- if (livenessInterval) {
360
- clearInterval(livenessInterval);
361
- }
362
- if (killTimeout) {
363
- clearTimeout(killTimeout);
364
- }
365
- refusal ??=
366
- extractStructuredRefusal(stdoutLineBuffer.replace(/\r$/, '')) ??
367
- extractStructuredRefusal(stderrLineBuffer.replace(/\r$/, ''));
368
- resolve({
369
- ...(latestActivityEvidence
370
- ? { activityEvidence: latestActivityEvidence }
371
- : {}),
372
- ...(latestActivityProbeStatus
373
- ? { activityProbeStatus: latestActivityProbeStatus }
374
- : {}),
375
- exitCode: timedOut ? 124 : (code ?? 1),
376
- ...(refusal ? { refusal } : {}),
377
- stderrBytes,
378
- stdoutBytes,
379
- ...(timedOut ? { timedOut: true } : {}),
380
- });
381
- });
382
- });
383
- }
384
- function extractStructuredRefusal(output) {
385
- const match = output.match(/^OAT_GATE_REFUSAL: (.*)$/m);
386
- return match?.[1]?.replace(/\r$/, '');
387
- }
388
244
  function isGateWriteLayer(value) {
389
245
  return VALID_WRITE_LAYERS.includes(value);
390
246
  }
@@ -1184,7 +1040,7 @@ async function executeTarget(selected, prompt, context, dependencies, timeout) {
1184
1040
  else {
1185
1041
  const activityDescription = lastActivityEvidence
1186
1042
  ? lastActivityEvidence.scope === 'ambient-runtime'
1187
- ? 'ambient runtime activity (not attributable to this gate child)'
1043
+ ? `ambient runtime activity (${AMBIENT_ACTIVITY_ATTRIBUTION})`
1188
1044
  : 'project-directory activity'
1189
1045
  : `${activityProbeStatus?.status ?? 'unavailable'} (${activityProbeStatus?.attemptedPath ?? 'no path'})`;
1190
1046
  context.logger.info(`Gate liveness: target=${selected.id} elapsed_ms=${elapsedMs} idle_ms=${idleMs} hard_budget_ms=${hardBudgetMs} process_alive=${processAlive} activity_evidence=${activityDescription}.`);
@@ -1606,6 +1462,25 @@ function writeReviewGateExecutionFailure(context, payload) {
1606
1462
  return;
1607
1463
  }
1608
1464
  context.logger.error(message);
1465
+ if (payload.activityEvidence && !payload.refusal) {
1466
+ context.logger.error(formatGateActivityEvidenceDiagnostic(payload.activityEvidence));
1467
+ }
1468
+ }
1469
+ function formatGateActivityEvidenceDiagnostic(evidence, now = Date.now()) {
1470
+ const transcriptScope = evidence.scope === 'ambient-runtime'
1471
+ ? `${evidence.runtime} ambient transcript`
1472
+ : `${evidence.runtime} project transcript`;
1473
+ const baselineState = evidence.changedSinceBaseline
1474
+ ? 'changed since baseline'
1475
+ : 'did not change since baseline';
1476
+ const observedAgoMs = Math.max(0, now - evidence.observedAt);
1477
+ const lastChangeTiming = evidence.lastChangeAt === null
1478
+ ? 'latest transcript change time unavailable'
1479
+ : `latest transcript change was ${Math.max(0, evidence.observedAt - evidence.lastChangeAt)}ms before observation`;
1480
+ const attributionWarning = evidence.scope === 'ambient-runtime'
1481
+ ? ` This activity is ${AMBIENT_ACTIVITY_ATTRIBUTION}.`
1482
+ : '';
1483
+ return `Activity evidence: ${transcriptScope} metadata ${baselineState}; observed ${observedAgoMs}ms ago; ${lastChangeTiming}.${attributionWarning}`;
1609
1484
  }
1610
1485
  function writeReviewGateUnexpectedFailure(context, payload) {
1611
1486
  const message = payload.error instanceof Error
@@ -2085,8 +1960,7 @@ async function runReviewGate(prompt, options, context, dependencies) {
2085
1960
  ...routeReceipt,
2086
1961
  })}\n`);
2087
1962
  const childExitCode = childResult.exitCode;
2088
- const refusal = childResult.refusal ??
2089
- extractStructuredRefusal(childResult.capturedOutput ?? '');
1963
+ const refusal = childResult.refusal;
2090
1964
  const writeRefusalFailure = () => {
2091
1965
  if (!refusal) {
2092
1966
  return false;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@open-agent-toolkit/cli",
3
- "version": "0.2.22",
3
+ "version": "0.2.24",
4
4
  "private": false,
5
5
  "description": "Open Agent Toolkit CLI",
6
6
  "homepage": "https://github.com/voxmedia/open-agent-toolkit/tree/main/packages/cli",
@@ -34,7 +34,7 @@
34
34
  "ora": "^9.0.0",
35
35
  "yaml": "2.8.2",
36
36
  "zod": "^3.25.76",
37
- "@open-agent-toolkit/control-plane": "0.2.22"
37
+ "@open-agent-toolkit/control-plane": "0.2.24"
38
38
  },
39
39
  "devDependencies": {
40
40
  "@types/node": "^22.10.0",