axstack 0.49.1 → 0.50.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +5 -7
- package/docs/concepts.md +11 -51
- package/docs/host-operations.md +24 -99
- package/docs/installation.md +27 -52
- package/docs/workflows.md +48 -35
- package/package.json +1 -1
- package/profiles/presets/claude-only.json +0 -37
- package/profiles/presets/codex-only.json +0 -36
- package/profiles/presets/mixed.json +4 -41
- package/skills/axstack/references/automations.md +33 -5
- package/skills/axstack/references/autopilot.md +7 -5
- package/skills/axstack/references/candidate-publication.md +1 -0
- package/skills/axstack/references/contracts.md +55 -7
- package/skills/axstack/references/lifecycle.md +20 -5
- package/skills/axstack/references/pr-shape.md +15 -0
- package/skills/axstack/references/pr-triage-nightly.md +14 -2
- package/skills/axstack/references/review-manager-prompt.md +18 -11
- package/skills/axstack/references/role-roster.md +4 -9
- package/skills/axstack/references/routing.md +3 -7
- package/skills/axstack/references/t3-runtime.md +122 -103
- package/skills/axstack/references/test-audit-weekly.md +14 -2
- package/skills/axstack/references/workspace-hygiene.md +14 -2
- package/skills/axstack/scripts/dispatch-plan.js +10 -27
- package/skills/axstack/scripts/resolve-models.js +9 -18
- package/skills/axstack-brainstorm/references/arena.md +2 -2
- package/skills/axstack-cleanup/SKILL.md +6 -3
- package/skills/axstack-implement/SKILL.md +5 -4
- package/skills/axstack-research/SKILL.md +3 -5
- package/skills/axstack-review/SKILL.md +7 -3
- package/skills/axstack-scout/SKILL.md +2 -12
- package/skills/axstack-watch/SKILL.md +43 -8
- package/skills/axstack-watch/references/escalation.md +1 -1
- package/skills/axstack-watch/references/proven-verification.md +1 -1
- package/skills/axstack-watch/references/repair-publication.md +1 -1
- package/skills/axstack-watch/references/watch-runtime.md +46 -33
- package/src/instructions.js +4 -3
- package/src/roles.js +3 -6
- package/skills/axstack/scripts/account-usage.js +0 -79
- package/skills/axstack/scripts/pick-instance.js +0 -57
- package/skills/axstack/scripts/sync-default.js +0 -191
- package/skills/axstack/systemd/axstack-default-sync.service +0 -8
- package/skills/axstack/systemd/axstack-default-sync.timer +0 -11
|
@@ -12,8 +12,7 @@ or use an explicit user selection in the run record. The legacy manifest
|
|
|
12
12
|
manifest value does not create a contradiction. Missing or contradictory installed
|
|
13
13
|
preset / explicit user selection: setup gap, hold. Never infer from live profiles, harness,
|
|
14
14
|
tools, credentials, quota, subscription, or default to `mixed`.
|
|
15
|
-
|
|
16
|
-
may use headroom under [Provider bindings](t3-runtime.md#preflight-and-binding);
|
|
15
|
+
Follow [Provider bindings](t3-runtime.md#preflight-and-binding);
|
|
17
16
|
provider/model substitution still requires the user's decision.
|
|
18
17
|
|
|
19
18
|
At start, snapshot all role IDs from installed `skills/axstack/roles.json`,
|
|
@@ -30,9 +29,6 @@ using saved T3 capabilities JSON; missing or malformed capabilities holds.
|
|
|
30
29
|
Claude exact IDs come from capabilities, replacing transcript read-back.
|
|
31
30
|
Use an explicit model as given; for `model:null` without a class, grok uses the
|
|
32
31
|
provider's first listed model from saved capabilities and records its exact ID.
|
|
33
|
-
For `model:null` without a class, Antigravity must select the first listed model
|
|
34
|
-
whose ID ends with `-<effort>` from saved capabilities and record its exact ID.
|
|
35
|
-
Missing effort-suffix matches hold resolution for Antigravity.
|
|
36
32
|
A Codex or Claude role with neither model nor class is an intentional absence
|
|
37
33
|
and holds.
|
|
38
34
|
Resume must reuse the saved capabilities and role snapshot with no re-resolution; changes require the user’s explicit decision.
|
|
@@ -40,8 +36,7 @@ An unavailable provider, model, role, mode or effort holds that role with no sub
|
|
|
40
36
|
Preset changes apply to new runs only; an active run keeps its snapshot.
|
|
41
37
|
Replacing a session needs an explicit user decision and revalidation.
|
|
42
38
|
Timeout, quota, auth and rejection hold affected work.
|
|
43
|
-
|
|
44
|
-
Follow [Provider bindings](t3-runtime.md#preflight-and-binding) for driver account re-selection at turn boundaries.
|
|
39
|
+
Follow [Provider bindings](t3-runtime.md#preflight-and-binding).
|
|
45
40
|
[Model discipline](contracts.md#model-discipline) governs optional seats,
|
|
46
41
|
auditor preflight, and required holds; [Role roster](role-roster.md) governs
|
|
47
42
|
single-provider absence, mixed research with at least two different providers,
|
|
@@ -148,4 +143,5 @@ not alone a formal spec trigger. Hold affected unsafe work while reassessing.
|
|
|
148
143
|
author provenance — then use `axstack-review` and `axstack-watch` without
|
|
149
144
|
repeated approval or new spec ceremony. Never infer the author from the
|
|
150
145
|
orchestrator or assume an imported own PR's author.
|
|
146
|
+
Before pushing a stale or external PR, follow [adoption dispositions](../../axstack-watch/SKILL.md#stale-or-external-prs).
|
|
151
147
|
- Direct later phase: start there and pass that phase's identity check.
|
|
@@ -29,73 +29,14 @@ preset and stable role IDs, requested provider/model/class/mode/effort, resolved
|
|
|
29
29
|
ID, source and time once. Resume preserves that snapshot with no re-resolution;
|
|
30
30
|
changes require the user's explicit decision. Bundled presets are setup inputs.
|
|
31
31
|
|
|
32
|
-
Provider bindings must map
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
by `scripts/pick-instance.js --provider <provider>`.
|
|
36
|
-
For dispatched roles, only error exit 1 permits fallback to the canonical instance after validating availability.
|
|
37
|
-
Exit 2 (no eligible provider instances) must hold the work without fallback.
|
|
38
|
-
Record the chosen instanceId and a pointer to saved `--json` output in the dispatch record.
|
|
39
|
-
Only same-provider, same-model account selection among instances of one driver
|
|
40
|
-
is permitted, with provider, model, class and effort rules required to remain unchanged.
|
|
41
|
-
An exhausted account with no eligible sibling must hold.
|
|
42
|
-
Dispatched roles never fail over mid-thread.
|
|
43
|
-
|
|
44
|
-
When the driver starts or resumes a run and at the start of every run-watch wake,
|
|
45
|
-
it runs `scripts/pick-instance.js --provider <its own provider> --json`.
|
|
46
|
-
Read its current binding with `t3_thread_configuration` and save picker JSON in private run evidence.
|
|
47
|
-
If the driver's own current instance is `excluded` for a usage limit and an eligible
|
|
48
|
-
same-provider sibling exists, it must switch itself via `t3_thread_configure` to the
|
|
49
|
-
chosen sibling instance, keeping the same provider, model and effort/options, then continue.
|
|
50
|
-
The driver must record from/to instance, a pointer to saved picker JSON and UTC time in `progress.md`.
|
|
51
|
-
If the driver's own current instance is eligible, it must stay despite headroom differences.
|
|
52
|
-
On exit 2 (no eligible sibling), the driver must hold under the existing rule.
|
|
53
|
-
On error exit 1, the driver must keep its current instance.
|
|
54
|
-
Driver account re-selection must configure only the calling thread and only at a turn boundary.
|
|
55
|
-
A turn already paused by a usage limit cannot self-recover.
|
|
56
|
-
The next wake or user message runs this check.
|
|
57
|
-
|
|
58
|
-
Driver self-switching is required from v0.25.1.
|
|
59
|
-
T3 scheduled tasks retain the creation-time instanceId for wakes and fresh-thread
|
|
60
|
-
passes regardless of the calling thread's current binding.
|
|
61
|
-
The driver must arm a run watch only after picking its account: `pick-instance.js` before `schedule_task`.
|
|
62
|
-
On a driver self-switch, delete and recreate its armed bound run watch with the
|
|
63
|
-
same prompt, cadence and binding on the new instance.
|
|
64
|
-
|
|
65
|
-
Every scheduled automation pass runs `scripts/pick-instance.js --provider <its own provider> --json`
|
|
66
|
-
at pass start, including fresh-thread review-manager passes.
|
|
67
|
-
Scheduled passes follow the driver's eligibility and stay rules: an eligible own instance stays,
|
|
68
|
-
exit 1 keeps the current instance and exit 2 holds.
|
|
69
|
-
If a scheduled pass's own current instance is `excluded` and an eligible same-provider sibling exists,
|
|
70
|
-
it must switch itself via `t3_thread_configure` to the chosen sibling instance,
|
|
71
|
-
keeping the same provider, model and effort/options.
|
|
72
|
-
On a scheduled pass self-switch in a review-manager lane, only the owner-of-record, after lane reconciliation
|
|
73
|
-
and the duplicate check, must delete and recreate its own schedule with the same
|
|
74
|
-
prompt, cadence and binding on the chosen instance.
|
|
75
|
-
On any other scheduled pass self-switch, delete and recreate its own schedule with
|
|
76
|
-
the same prompt, cadence and binding on the chosen instance only after `list_scheduled_tasks`
|
|
77
|
-
confirms no replacement for that schedule on the chosen instance already exists.
|
|
78
|
-
If a replacement for that schedule on the chosen instance already exists, any other scheduled pass must skip recreation.
|
|
79
|
-
For a review-manager self-switch, only the owner-of-record must update the recorded
|
|
80
|
-
`axstack-owner` binding's instanceId to the chosen instance after verifying unchanged
|
|
81
|
-
provider/model/effort/options with `t3_thread_configuration` and attaching the picker
|
|
82
|
-
switch receipt, before the admission binding comparison.
|
|
83
|
-
For each schedule replacement, read back old absence and new presence using `list_scheduled_tasks`.
|
|
84
|
-
For each schedule replacement, record old/new scheduledTaskId, from/to instance,
|
|
85
|
-
picker JSON pointer and UTC time in the `progress.md` or durable activation/continuity record.
|
|
86
|
-
Retain the recorded schedule's title and enabled state and use a fresh stable creation `clientRequestId`.
|
|
87
|
-
An uncertain replacement holds affected work: preserve its native receipts for reconciliation.
|
|
88
|
-
A scheduled pass already running on an exhausted account cannot recover.
|
|
89
|
-
Account switches must happen before exhaustion at the picker's near-limit cutoff.
|
|
32
|
+
Provider bindings must map codex→`codex`, claude→`claudeAgent` and grok→`grok`.
|
|
33
|
+
For every dispatch or launch, claude must bind to `claudeAgent` and codex must bind to `codex`.
|
|
34
|
+
A usage-limited instance must hold the work without failover.
|
|
90
35
|
|
|
91
36
|
For plan generation, run
|
|
92
|
-
`scripts/dispatch-plan.js --role <id> --roles <roles.json> --capabilities <saved.json> --
|
|
37
|
+
`scripts/dispatch-plan.js --role <id> --roles <roles.json> --capabilities <saved.json> --kind task|launch`
|
|
93
38
|
using the recorded role snapshot and saved capabilities.
|
|
94
|
-
Plan JSON carries `inputs`, which callers omit when copying `target`/`modelSelection` and `runtimeMode` into `delegate_task`/`t3_thread_launch`; large plan output requires `--out`.
|
|
95
|
-
For claude/codex, the `--picker` JSON must come from saved
|
|
96
|
-
`scripts/pick-instance.js --provider <role provider> --json` output.
|
|
97
|
-
For grok/antigravity, or after a claude/codex picker exit-1 canonical fallback,
|
|
98
|
-
pass `{"chosenInstanceId":"<canonical instance>"}`.
|
|
39
|
+
Plan JSON carries `inputs`, which callers omit when copying `target`/`modelSelection` and `runtimeMode` plus `isolation` when present into `delegate_task`/`t3_thread_launch`; large plan output requires `--out`.
|
|
99
40
|
For configuration verification, run `scripts/dispatch-plan.js --verify <configuration.json>`
|
|
100
41
|
with the same plan inputs and saved `t3_thread_configuration` read-back.
|
|
101
42
|
|
|
@@ -105,17 +46,13 @@ A preset model must be used as given.
|
|
|
105
46
|
|
|
106
47
|
A missing or malformed catalog holds resolution.
|
|
107
48
|
|
|
108
|
-
For a null-model grok
|
|
49
|
+
For a null-model grok role, record the exact model ID from the plan,
|
|
109
50
|
rather than an unresolved provider default.
|
|
110
|
-
Antigravity must hold when saved capabilities advertise zero models.
|
|
111
|
-
No matching effort suffix holds resolution for Antigravity.
|
|
112
51
|
For codex or claude, a role lacking both model and class is an intentional
|
|
113
52
|
absence and must hold; never use a provider default for that role.
|
|
114
53
|
|
|
115
54
|
An unavailable provider, model, role, mode or effort must hold that role with
|
|
116
55
|
no substitution. Auth, quota, timeout and rejection do not select an alternative.
|
|
117
|
-
Here alternative means a provider or model substitution, excluding the bounded
|
|
118
|
-
same-provider, same-model account selection above.
|
|
119
56
|
Intentional absent seats remain recorded absences; availability is runtime proof.
|
|
120
57
|
|
|
121
58
|
Grok's CLI requires ≥1.0.13.
|
|
@@ -138,9 +75,9 @@ configuration; unrelated configurations remain eligible.
|
|
|
138
75
|
|
|
139
76
|
| Roles | Mechanism and permitted workspace | Completion |
|
|
140
77
|
|---|---|---|
|
|
141
|
-
| Advisers, research, read-only explorers, explainers, diligence, checker, auditor,
|
|
78
|
+
| Advisers, research, read-only explorers, explainers, diligence, checker, auditor, arena prose candidates and judges, escalation | Must use async `delegate_task` in the driver worktree, title = dispatch key; tracked and untracked files stay untouched; writes only `<run>/evidence/<key>/` | Native notification followed by persisted `task_status` |
|
|
142
79
|
| Reviewers (peer/authored), release checks, debug investigators, execution investigators (`axstack-explore-execution`), UI verifier candidate checks (`axstack-ui-verifier`) | Must use async `delegate_task`, title = dispatch key; driver makes a disposable detached checkout of candidate SHA and pinned base with `git worktree add --detach <run>/checkouts/<key> <sha>` (plus pinned debug patch); brief requires `cd` into it; only disposable probes write there, outputs go to `<run>/evidence/<key>/` | Same delegated terminal checks |
|
|
143
|
-
| Author and repairs |
|
|
80
|
+
| Author and repairs | Fresh authors must use async `delegate_task` with `isolation:"worktree"`, title = dispatch key, stable `clientRequestId` in their own worktree, kept until PR merges or closes; repairs use `t3_thread_send` to the same child | Delegated terminal checks plus verified candidate |
|
|
144
81
|
| Owner | Driver thread in Driver worktree; never writes tracked candidate source or tests; planning artifacts allowed only for repository Markdown; scope, integration, forge mutations and record | No worker launch |
|
|
145
82
|
|
|
146
83
|
The UI verifier checkout row applies to candidate checks, while a page without
|
|
@@ -152,6 +89,13 @@ The driver may write planning artifacts (spec, ticket map) in its own worktree w
|
|
|
152
89
|
Repairs return to that author. Missing or idle sessions grant no ownership transfer.
|
|
153
90
|
The current chat/driver has no role row in any preset.
|
|
154
91
|
|
|
92
|
+
At launch and rename, visible driver thread titles express a plain outcome of
|
|
93
|
+
at most 30 characters.
|
|
94
|
+
Visible driver thread titles use no repo, issue or size prefix.
|
|
95
|
+
Hidden children keep dispatch-key titles.
|
|
96
|
+
D9 applies to driver threads only, while flagged unbound pass threads retain the
|
|
97
|
+
`Needs you: <kind> <repo>#<n>` (or `<lane>`) rename under Automations.
|
|
98
|
+
|
|
155
99
|
The dispatch key must be `<run>:<role>:<task>:a<n>`, recorded before launch and
|
|
156
100
|
used as the exact whole T3 title. Substring matches do not establish identity.
|
|
157
101
|
Each dispatch binds the approved spec or small-change intent, brief, authority, role snapshot, base and candidate to its dispatch key.
|
|
@@ -162,12 +106,37 @@ The branch must be `axstack/<run>/<role>/<task>-a<n>`; lowercase each segment
|
|
|
162
106
|
and replace every `[^a-z0-9-]` character with `-`. Keep the dispatch key in its
|
|
163
107
|
original form and record both; normalization is never an identity substitute.
|
|
164
108
|
|
|
109
|
+
Before dispatch, the driver must name its resolved worktree absolute path in the author brief.
|
|
110
|
+
Before `git switch -c`, the delegated fresh author must verify `git rev-parse --show-toplevel` differs from the driver worktree named in the brief.
|
|
111
|
+
The isolation proof also requires `git rev-parse --git-dir` differs from `git rev-parse --git-common-dir` (a linked worktree) and `git status --porcelain` is empty.
|
|
112
|
+
The isolation proof must never depend on the starting branch name.
|
|
113
|
+
T3 can rename the starting branch after start.
|
|
114
|
+
On failed isolation proof, stop with `AXSTACK-FAILED` and change nothing.
|
|
115
|
+
After dispatch, the driver must read back the child's `worktreePath` and hold if it is missing or equals the driver worktree.
|
|
116
|
+
The delegated fresh author brief step 1 must verify the branch is absent before
|
|
117
|
+
`git switch -c <encoded branch> <pinned base SHA>`, then verify HEAD equals the pinned base SHA.
|
|
118
|
+
Immediately before `git switch -c`, record the current starting branch with `git symbolic-ref --short HEAD` and starting HEAD with `git rev-parse HEAD`.
|
|
119
|
+
Never use `git switch -C`.
|
|
120
|
+
Delete the T3-created starting branch under its current name only after the switch succeeds and HEAD is verified.
|
|
121
|
+
If T3 renamed the recorded name between capture and switch, follow the worktree reflog rename to the final name.
|
|
122
|
+
Delete only if no worktree has it checked out and its tip equals the recorded starting HEAD.
|
|
123
|
+
If it cannot be identified safely, leave it and name it in the receipt for driver cleanup.
|
|
124
|
+
At dispatch, record taskId, childThreadId, worktreePath and encoded branch.
|
|
125
|
+
T3 worktree isolation starts from the parent HEAD and ignores workspaceStrategy,
|
|
126
|
+
so the delegated fresh child must perform step 1 in its own checkout before writing.
|
|
127
|
+
|
|
128
|
+
Keep `t3_thread_launch` for top-level drivers; use `t3_thread_launch` as a rare
|
|
129
|
+
author fallback only when worktree isolation is unavailable and record each use in the run record.
|
|
130
|
+
For a recorded author launch, use `{type:worktree, baseRef:<SHA>, branch:<encoded branch>, startFromOrigin:false}`.
|
|
131
|
+
A launched fallback author starts on its encoded branch and skips step 1 and the isolation proof.
|
|
132
|
+
The launch-only recovery and completion rules below cover that fallback.
|
|
133
|
+
|
|
165
134
|
`baseRef` must always be a commit SHA, never a branch name; T3 renames its
|
|
166
135
|
`t3code/*` branches. Pin base and candidate before dispatch.
|
|
167
|
-
Fetch the pinned base commit into the
|
|
168
|
-
Before
|
|
136
|
+
Fetch the pinned base commit into the dispatch repository before an author dispatch.
|
|
137
|
+
Before an author dispatch, verify locally that the pinned base SHA resolves to a
|
|
169
138
|
commit with that exact SHA.
|
|
170
|
-
If fetch or verification fails, hold that
|
|
139
|
+
If fetch or verification fails, hold that dispatch.
|
|
171
140
|
|
|
172
141
|
Workers must finish with exactly one final marker: `AXSTACK-DONE key=… head=…
|
|
173
142
|
report=…`, `AXSTACK-FAILED key=… head=… report=…`, or `AXSTACK-QUESTION key=… q=…`.
|
|
@@ -185,6 +154,9 @@ Delegated completion must require terminal `completed`, `result_available`,
|
|
|
185
154
|
`hasPendingChildRuns:false`, and final `AXSTACK-DONE`; a question stays
|
|
186
155
|
incomplete even when native status says completed.
|
|
187
156
|
|
|
157
|
+
Delegated author completion requires delegated terminal checks plus candidate checks:
|
|
158
|
+
non-empty diff, clean tree and named red/green logs.
|
|
159
|
+
|
|
188
160
|
Launched writer completion must require terminal `t3_thread_wait` on that run,
|
|
189
161
|
then candidate checks: non-empty diff, clean tree and named red/green logs.
|
|
190
162
|
A receipt message alone counts only as progress; it can precede terminal state.
|
|
@@ -207,7 +179,10 @@ including untracked entries. Any change is a hold before advancing that work.
|
|
|
207
179
|
|
|
208
180
|
## Launch recovery, repairs and questions
|
|
209
181
|
|
|
210
|
-
For a lost
|
|
182
|
+
For a lost delegated dispatch or repair response, retry with the same stable
|
|
183
|
+
`clientRequestId` to recover task identity. Never start a second writer while the outcome is unknown.
|
|
184
|
+
|
|
185
|
+
For a lost launch response on the recorded fallback route the driver must use fully paginated `t3_thread_list`
|
|
211
186
|
with `titleContains=<key>`, filtered to exact whole-title equality, plus
|
|
212
187
|
`git worktree list`. Keep the reserved branch through recovery. A branch or
|
|
213
188
|
worktree without a reconciled thread prevents proof of absence.
|
|
@@ -222,16 +197,31 @@ failed is launch failure; timed-out with `t3_thread_read` showing both
|
|
|
222
197
|
`activeRunId` and `worktreePath` is started; still preparing is a hold and
|
|
223
198
|
re-read at the next wake. An unresolved state preserves the attempt.
|
|
224
199
|
|
|
225
|
-
For
|
|
226
|
-
|
|
200
|
+
For a delegated child, detect questions with `t3_pending_request_list(childThreadId)`.
|
|
201
|
+
Never rely on `hasPendingQuestion` alone.
|
|
202
|
+
Codex `request_user_input_async` does not set it.
|
|
203
|
+
Use `t3_pending_request_read`, then confirm the request is still pending with
|
|
204
|
+
`t3_pending_request_list(childThreadId)`, then answer once within existing authority
|
|
205
|
+
using `t3_pending_request_respond`; a second ask holds.
|
|
206
|
+
Independent review rounds require fresh `delegate_task` calls.
|
|
207
|
+
Only author continuation and an answer to a child's own question use the same child.
|
|
208
|
+
Providers without a question tool (grok) and launched writers keep
|
|
209
|
+
the `AXSTACK-QUESTION` marker route.
|
|
210
|
+
|
|
211
|
+
For a delegated marker question, answer once with `t3_thread_send(childThreadId, mode:queue)`,
|
|
212
|
+
record the returned `taskId`, and consume the follow-up under delegated terminal checks.
|
|
213
|
+
For a launched-writer `AXSTACK-QUESTION` marker the driver must answer once using
|
|
214
|
+
`t3_thread_send` to the `childThreadId`, record the returned resumed runId, then
|
|
227
215
|
`t3_thread_wait(childThreadId, runId, timeoutMs:600000)`, re-armed by the run
|
|
228
216
|
watch. Persist status again and accept only `latestTerminal*` with
|
|
229
217
|
`latestTerminalRunId` newer than the question run (recorded run ordering, not
|
|
230
218
|
lexical ID order), terminal success and matching receipt key/SHA. The original
|
|
231
|
-
summary stays stable; no notification is assumed for a resumed result.
|
|
219
|
+
summary stays stable; no notification is assumed for a launched-writer resumed result.
|
|
232
220
|
|
|
233
|
-
A repair must use `t3_thread_send(
|
|
234
|
-
|
|
221
|
+
A delegated repair must use a stable clientRequestId with `t3_thread_send(childThreadId, mode:queue, clientRequestId)` to the same author
|
|
222
|
+
in the same attempt, worktree and branch, record the returned taskId and verify the existing candidate head.
|
|
223
|
+
Repairs never repeat fresh checkout step 1. Pin the new candidate revision.
|
|
224
|
+
For a launched fallback, retain the same author thread and use launched-run completion checks.
|
|
235
225
|
|
|
236
226
|
A replacement after terminal failure must use `a<n+1>`, a new branch and title;
|
|
237
227
|
the failed attempt's branch is kept until salvage. Unknown liveness holds
|
|
@@ -239,7 +229,7 @@ replacement; reconcile the old writer before admitting another.
|
|
|
239
229
|
|
|
240
230
|
With an unsettled launched thread, the driver turn must end only while a bound
|
|
241
231
|
`schedule_task` with `bindToCurrentThread:true` is armed at the default
|
|
242
|
-
`everyMs:
|
|
232
|
+
`everyMs:3600000` or for its 5-minute recovery cases in
|
|
243
233
|
[Chat-run watch runtime](../../axstack-watch/references/watch-runtime.md#chat-run-watch),
|
|
244
234
|
with its ID recorded. Each wake must reconcile all unsettled runs, including a
|
|
245
235
|
writer that died without sending; failed runs hold incomplete work. The watch
|
|
@@ -269,17 +259,19 @@ Before finishing PR work, including watch end or Close-out, the driver calls
|
|
|
269
259
|
`list_thread_pull_requests` and links every missing run PR.
|
|
270
260
|
Never link unrelated PRs.
|
|
271
261
|
|
|
272
|
-
|
|
273
|
-
the driver
|
|
274
|
-
`
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
only that PR's merge-ready and requires retrying the link.
|
|
262
|
+
Authors are never PR-linked: the driver alone links and watches the PR.
|
|
263
|
+
For delegated authors after accepted completion, in the same driver turn settle with
|
|
264
|
+
`t3_thread_organize` using `action: settle`, read back `settled: true` with `t3_thread_read`
|
|
265
|
+
and record `settle: manual` under the [Settlement](workspace-hygiene.md#settlement) guards.
|
|
266
|
+
For delegated authors, archive and guarded manual worktree removal wait for PR merge or close.
|
|
267
|
+
Never rely on automatic child cleanup.
|
|
279
268
|
|
|
280
269
|
When the forge confirms a run PR merged or closed, in the same driver turn the
|
|
281
|
-
driver
|
|
282
|
-
|
|
270
|
+
driver first reads its author thread with `t3_thread_read`.
|
|
271
|
+
If the readback already shows `settled: true`, record `settle: native` only when
|
|
272
|
+
no driver settle was issued for that thread; otherwise retain `settle: manual`.
|
|
273
|
+
Otherwise settle with `t3_thread_organize` using `action: settle`, then read back
|
|
274
|
+
`settled: true` with `t3_thread_read` before recording `settle: manual`.
|
|
283
275
|
Apply the existing [Settlement](workspace-hygiene.md#settlement) guards:
|
|
284
276
|
terminal run evidence is required and user-taken-over threads stay untouched.
|
|
285
277
|
A missing or failed settle readback holds watch end and Close-out only for
|
|
@@ -288,22 +280,44 @@ that author thread until resolved.
|
|
|
288
280
|
For every watched own PR in chat-run or standalone adopted maintenance, when
|
|
289
281
|
available the driver calls `watch_pull_request` for T3 wakes on check completion,
|
|
290
282
|
new comments from others, or branch conflicts, then ends the turn.
|
|
283
|
+
Only the PR-owning driver calls `watch_pull_request`.
|
|
284
|
+
Delegated children never call `watch_pull_request`.
|
|
285
|
+
Before arming, handle existing checks and comments because only later comments wake the thread.
|
|
291
286
|
Never poll or keep a model active between native PR wake events.
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
287
|
+
Native watch ends after 8 failed reads, or on settle, archive, user Stop, or PR merge/close.
|
|
288
|
+
For parked holds, follow [Parked user-reply holds](contracts.md#parked-user-reply-holds).
|
|
289
|
+
A parking unwatch never triggers native re-arm or the 5-minute recovery cadence.
|
|
290
|
+
A non-user T3 "stopped watching" notice is itself a driver wake: in that same turn,
|
|
291
|
+
re-check the PR.
|
|
292
|
+
After a non-user stop while the PR stays open, the driver must re-arm in that
|
|
293
|
+
same turn when GraphQL quota permits, using the recovery steps below.
|
|
294
|
+
Record the stop reason T3 gives.
|
|
295
|
+
Re-arm only after a stop not caused by the user.
|
|
296
|
+
For a "could not read" stop, run `gh api rate_limit --jq .resources.graphql` as a diagnostic only.
|
|
297
|
+
When GraphQL remaining is near 0, defer re-arming until reset: set the bound
|
|
298
|
+
schedule to 5 minutes and re-arm on the next wake after reset.
|
|
299
|
+
Record the GraphQL reset time in the run record.
|
|
300
|
+
Never wait for a GraphQL reset inside a turn.
|
|
301
|
+
Before re-arming, first unsettle the driver thread with `t3_thread_organize`
|
|
302
|
+
using `action: unsettle`, then call `watch_pull_request` again.
|
|
303
|
+
Never re-arm in a loop.
|
|
295
304
|
Route native PR wake events through watch §4 and the unchanged §5 readiness predicate.
|
|
296
305
|
|
|
297
306
|
If `watch_pull_request` is unavailable, fall back to the bound 5-minute schedule
|
|
298
307
|
and `scripts/pr-digest.js` without a hold.
|
|
299
308
|
If re-arming fails, restore the bound 5-minute schedule.
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
When work restarts,
|
|
304
|
-
|
|
309
|
+
For forge-resolved human waits, including user merge, npm stage approval and
|
|
310
|
+
human review, with no unsettled worker and no PR needing watch events, set the run watch cadence to 60 minutes
|
|
311
|
+
at once.
|
|
312
|
+
When work restarts, re-evaluate cadence against the recovery conditions in
|
|
313
|
+
[Chat-run watch runtime](../../axstack-watch/references/watch-runtime.md#chat-run-watch).
|
|
314
|
+
Keep native PR watches for forge-resolved waits.
|
|
305
315
|
For chat-run cadence changes, follow [Chat-run watch runtime](../../axstack-watch/references/watch-runtime.md#chat-run-watch)
|
|
306
|
-
for the
|
|
316
|
+
for the 60-minute backstop, 5-minute recovery, and schedule update read-back.
|
|
317
|
+
An open PR left unwatched by a user Stop never triggers the 5-minute recovery cadence.
|
|
318
|
+
After T3 auto-settles a multi-PR driver on one PR merge, it re-arms remaining
|
|
319
|
+
open members through the recovery steps before ending the turn.
|
|
320
|
+
If rate-limited, use the 5-minute schedule and next-wake recovery above.
|
|
307
321
|
The schedule still reconciles author and review tasks, readiness, and release.
|
|
308
322
|
When a PR merges or closes, or its watch is torn down, call `unwatch_pull_request`
|
|
309
323
|
and keep its link.
|
|
@@ -358,13 +372,18 @@ The driver must retain a user-taken-over T3 thread; never send cleanup commands
|
|
|
358
372
|
to it, including `t3_thread_organize` settle or archive.
|
|
359
373
|
Require T3 terminal run evidence before `t3_thread_organize` settle or archive;
|
|
360
374
|
these metadata actions are not worktree removal.
|
|
375
|
+
Self-settle is the one exception to terminal-before-settle: T3 returns
|
|
376
|
+
`settlesWhenTurnEnds:true` and the next pass verifies `settled: true`.
|
|
377
|
+
Apply the guarded unbound pass-end action in
|
|
378
|
+
[Finite-session teardown](automations.md#finite-session-teardown).
|
|
361
379
|
|
|
362
380
|
## Project preflight and run record
|
|
363
381
|
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
382
|
+
Hosts can delete author worktrees at merge through `storageCleanup.worktreeOnMerge`.
|
|
383
|
+
`t3_project_read` cannot read `storageCleanup.worktreeOnMerge`.
|
|
384
|
+
Evidence never lives in a worktree and belongs in private `<run>/evidence/<key>/`.
|
|
385
|
+
A missing merged or closed author worktree is expected, not a hold.
|
|
386
|
+
Automatic worktree deletion cannot replace evidence readback and salvage.
|
|
368
387
|
|
|
369
388
|
The run record must contain driver threadId, projectId, host, T3 version,
|
|
370
389
|
installed Axstack SHA, capabilities JSON path and scheduledTaskIds for every
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# Weekly test-audit prompt
|
|
2
2
|
|
|
3
|
-
At pass start, follow [Provider bindings](t3-runtime.md#preflight-and-binding) for
|
|
3
|
+
At pass start, follow [Provider bindings](t3-runtime.md#preflight-and-binding) for provider binding.
|
|
4
4
|
|
|
5
5
|
You are a fresh finite weekly test-audit session in this repository's dedicated
|
|
6
6
|
T3 project worktree. Before admission, read the activation record: repository,
|
|
@@ -65,5 +65,17 @@ The recorded owning watch thread merges under the same watch predicate.
|
|
|
65
65
|
Workers never merge.
|
|
66
66
|
|
|
67
67
|
Raise decision and serious-risk holds in the T3 driver thread; end the turn
|
|
68
|
-
|
|
68
|
+
waiting on the decision. Keep routine reports there, including skipped or empty passes.
|
|
69
69
|
Settle owned workers and preserve evidence under the shared lifecycle.
|
|
70
|
+
|
|
71
|
+
At pass start, read the recorded prior pass thread with `t3_thread_read` and
|
|
72
|
+
apply [Finite-session teardown](automations.md#finite-session-teardown)'s guarded
|
|
73
|
+
verification or hold/report before replacing its identity.
|
|
74
|
+
Record own pass threadId in the existing activation record and read back the save.
|
|
75
|
+
|
|
76
|
+
At pass end, an unbound pass calls `t3_thread_organize` with `action: settle` on its
|
|
77
|
+
own thread only, only when it owns no PR watch, has zero unsettled descendants,
|
|
78
|
+
has no pending receipt and is not held, wedged or a stalled owner.
|
|
79
|
+
Follow [Finite-session teardown](automations.md#finite-session-teardown) for
|
|
80
|
+
deferred self-settle and next-pass verification; this applies to quiet, skipped
|
|
81
|
+
and empty passes too.
|
|
@@ -24,8 +24,10 @@ still appears is a hold; agents do not answer it.
|
|
|
24
24
|
|
|
25
25
|
## Project preflight
|
|
26
26
|
|
|
27
|
-
|
|
28
|
-
|
|
27
|
+
Hosts can delete author worktrees at merge through `storageCleanup.worktreeOnMerge`.
|
|
28
|
+
`t3_project_read` cannot read `storageCleanup.worktreeOnMerge`.
|
|
29
|
+
Evidence never lives in a worktree and belongs in private `<run>/evidence/<key>/`.
|
|
30
|
+
A missing merged or closed author worktree is expected, not a hold.
|
|
29
31
|
Automatic deletion cannot replace evidence readback or salvage. Do not change
|
|
30
32
|
project settings without recorded host-mutation authority.
|
|
31
33
|
|
|
@@ -33,10 +35,20 @@ project settings without recorded host-mutation authority.
|
|
|
33
35
|
|
|
34
36
|
Cleanup order is: settled descendants -> evidence readback -> salvage dirty or ignored non-cache content -> t3_thread_organize archive -> exact git worktree remove without force -> git branch -d for local-only branches.
|
|
35
37
|
Require terminal run evidence before `t3_thread_organize` settle or archive.
|
|
38
|
+
Self-settle is the one exception to terminal-before-settle: T3 returns
|
|
39
|
+
`settlesWhenTurnEnds:true` and the next pass verifies `settled: true`.
|
|
40
|
+
Apply the guarded unbound pass-end action in
|
|
41
|
+
[Finite-session teardown](automations.md#finite-session-teardown).
|
|
42
|
+
Record `settle: native` only when no driver settle was issued for that thread;
|
|
43
|
+
otherwise retain `settle: manual` even when a later read already shows settled.
|
|
36
44
|
These metadata actions do not remove worktrees. Accept matching delegated task
|
|
37
45
|
or launched run completion under the runtime contract before settlement.
|
|
38
46
|
After the driver accepts a launched writer's (author or repair) or delegated task's completion from terminal run evidence plus a verified receipt or candidate check, in the same driver turn it settles the matching thread with `t3_thread_organize` using `action: settle` as metadata only.
|
|
39
47
|
The driver reads back `settled: true` with `t3_thread_read` on the writer thread for launched writers and on the `childThreadId` for delegated tasks.
|
|
48
|
+
For delegated authors after accepted completion, in the same driver turn settle with `t3_thread_organize` using `action: settle`, read back `settled: true` with `t3_thread_read` and record `settle: manual`.
|
|
49
|
+
For delegated authors, archive and guarded manual worktree removal wait for PR merge or close.
|
|
50
|
+
Never rely on automatic child cleanup.
|
|
51
|
+
Delegated author threads stay hidden in the sidebar regardless of settlement; visibility statements below apply to launched writers.
|
|
40
52
|
This extends the existing same-turn settle rule: a pinned run-owned child is still settled.
|
|
41
53
|
T3's settle clears the pin, including one inherited from the parent at creation. There is no separate unpin step.
|
|
42
54
|
Native T3 tools do not show pins, so the read-back stays `settled: true`.
|
|
@@ -1,17 +1,16 @@
|
|
|
1
1
|
import { readFileSync, writeFileSync } from 'node:fs';
|
|
2
2
|
|
|
3
|
-
const flags = ['--role', '--roles', '--capabilities', '--
|
|
3
|
+
const flags = ['--role', '--roles', '--capabilities', '--kind', '--verify', '--out'];
|
|
4
4
|
const nonempty = (value) => typeof value === 'string' && value.trim().length > 0;
|
|
5
5
|
const help = `Usage: bun dispatch-plan.js --role <id> --roles <roles.json>
|
|
6
|
-
--capabilities <saved.json> --
|
|
6
|
+
--capabilities <saved.json> --kind task|launch
|
|
7
7
|
[--verify <configuration.json>] [--out <report.json>]
|
|
8
|
-
Example: bun dispatch-plan.js --role axstack-author --roles roles.json --capabilities capabilities.json --
|
|
8
|
+
Example: bun dispatch-plan.js --role axstack-author --roles roles.json --capabilities capabilities.json --kind task
|
|
9
9
|
|
|
10
10
|
--role Role ID from the supplied snapshot
|
|
11
11
|
--roles Installed-style roles.json (version 1, roles array)
|
|
12
12
|
--capabilities Saved orchestrator_capabilities JSON; reuse the run's saved snapshot
|
|
13
|
-
--
|
|
14
|
-
--kind task emits target; launch emits modelSelection
|
|
13
|
+
--kind task emits target and, for axstack-author, isolation:"worktree"; launch emits modelSelection
|
|
15
14
|
--verify Compare t3_thread_configuration JSON; print evidence then MATCH or each mismatch
|
|
16
15
|
--out Save the payload as full JSON here; stdout is an input/path/omitted-count summary
|
|
17
16
|
--help Show all flags and exit codes
|
|
@@ -61,7 +60,7 @@ function normalizedOptions(options) {
|
|
|
61
60
|
return JSON.stringify(entries.sort(([left], [right]) => left.localeCompare(right)));
|
|
62
61
|
}
|
|
63
62
|
|
|
64
|
-
function verify(configuration,
|
|
63
|
+
function verify(configuration, provider, model, options) {
|
|
65
64
|
const mismatches = [];
|
|
66
65
|
const selection = configuration?.modelSelection;
|
|
67
66
|
const compare = (field, expected, observed, equal = expected === observed) => {
|
|
@@ -73,7 +72,7 @@ function verify(configuration, instanceId, provider, model, options) {
|
|
|
73
72
|
compare('provider', provider, selection.provider,
|
|
74
73
|
(selection.provider === 'claude' ? 'claudeAgent' : selection.provider) === provider);
|
|
75
74
|
}
|
|
76
|
-
compare('instanceId',
|
|
75
|
+
compare('instanceId', provider, selection?.instanceId);
|
|
77
76
|
compare('model', model, selection?.model);
|
|
78
77
|
compare('options', options, selection?.options,
|
|
79
78
|
normalizedOptions(options) === normalizedOptions(selection?.options));
|
|
@@ -130,8 +129,6 @@ function plan(argv, io) {
|
|
|
130
129
|
if (!nonempty(role.model) && !nonempty(role.modelClass) && role.model !== null) {
|
|
131
130
|
hold(`model unavailable for role ${role.id}`);
|
|
132
131
|
}
|
|
133
|
-
const picker = readJSON(args['--picker']);
|
|
134
|
-
if (!nonempty(picker?.chosenInstanceId)) hold('picker chosen instance unavailable');
|
|
135
132
|
const modelArgs = typeof role.model === 'string' ? ['--model', role.model]
|
|
136
133
|
: role.modelClass ? ['--class', role.modelClass] : ['--model', String(role.model)];
|
|
137
134
|
const resolved = Bun.spawnSync([process.execPath, `${import.meta.dir}/resolve-models.js`,
|
|
@@ -140,30 +137,16 @@ function plan(argv, io) {
|
|
|
140
137
|
if (resolved.stderr.length) io.stderr(resolved.stderr.toString());
|
|
141
138
|
if (resolved.exitCode !== 0) return resolved.exitCode === 1 ? 2 : 1;
|
|
142
139
|
const { model, effortOption, providerInstanceId } = JSON.parse(resolved.stdout.toString());
|
|
143
|
-
const chosen = readJSON(args['--capabilities']).providers
|
|
144
|
-
.filter((provider) => provider.providerInstanceId === picker.chosenInstanceId);
|
|
145
|
-
if (chosen.length !== 1 || chosen[0].driverKind !== providerInstanceId
|
|
146
|
-
|| (['grok', 'antigravity'].includes(role.provider) && picker.chosenInstanceId !== providerInstanceId)) {
|
|
147
|
-
hold(`picker instance ${picker.chosenInstanceId} does not bind provider ${role.provider}`);
|
|
148
|
-
}
|
|
149
|
-
if (!Array.isArray(chosen[0].models)) {
|
|
150
|
-
hold(`malformed models on instance ${picker.chosenInstanceId}; expected an array; observed ${JSON.stringify(chosen[0].models) ?? 'missing'}`);
|
|
151
|
-
}
|
|
152
|
-
const selectedModel = chosen[0].models.find((entry) => entry.id === model);
|
|
153
|
-
if (!selectedModel) hold(`model ${model} unavailable on instance ${picker.chosenInstanceId}`);
|
|
154
|
-
if (effortOption && !selectedModel.options?.some((option) => option.id === effortOption.id
|
|
155
|
-
&& option.options?.some((value) => value.id === effortOption.value))) {
|
|
156
|
-
hold(`effort ${effortOption.value} unavailable on instance ${picker.chosenInstanceId}`);
|
|
157
|
-
}
|
|
158
140
|
const options = effortOption ? [effortOption] : [];
|
|
159
141
|
if (args['--verify']) {
|
|
160
|
-
const verification = verify(readJSON(args['--verify']),
|
|
142
|
+
const verification = verify(readJSON(args['--verify']), providerInstanceId, model, options);
|
|
161
143
|
emit(verification);
|
|
162
144
|
return verification.mismatches.length ? 2 : 0;
|
|
163
145
|
}
|
|
164
|
-
const selection = { [args['--kind'] === 'launch' ? 'instanceId' : 'providerInstanceId']:
|
|
146
|
+
const selection = { [args['--kind'] === 'launch' ? 'instanceId' : 'providerInstanceId']: providerInstanceId,
|
|
165
147
|
model, options };
|
|
166
|
-
emit({ [args['--kind'] === 'launch' ? 'modelSelection' : 'target']: selection, runtimeMode: 'full-access'
|
|
148
|
+
emit({ [args['--kind'] === 'launch' ? 'modelSelection' : 'target']: selection, runtimeMode: 'full-access',
|
|
149
|
+
...(args['--kind'] === 'task' && role.id === 'axstack-author' ? { isolation: 'worktree' } : {}) });
|
|
167
150
|
return 0;
|
|
168
151
|
}
|
|
169
152
|
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { readFileSync } from 'node:fs';
|
|
2
2
|
|
|
3
|
-
const bindings = { codex: 'codex', claude: 'claudeAgent', grok: 'grok'
|
|
3
|
+
const bindings = { codex: 'codex', claude: 'claudeAgent', grok: 'grok' };
|
|
4
4
|
const effortIds = { codex: 'reasoningEffort', claude: 'effort', grok: 'reasoningEffort' };
|
|
5
5
|
const nonempty = (value) => typeof value === 'string' && value.trim().length > 0;
|
|
6
6
|
|
|
@@ -21,7 +21,7 @@ function argumentsFrom(args) {
|
|
|
21
21
|
}
|
|
22
22
|
}
|
|
23
23
|
if (!options.provider || !options.capabilities || !options.effort) {
|
|
24
|
-
throw new Error('expected --provider codex|claude|grok
|
|
24
|
+
throw new Error('expected --provider codex|claude|grok --capabilities path --effort level');
|
|
25
25
|
}
|
|
26
26
|
return options;
|
|
27
27
|
}
|
|
@@ -45,7 +45,7 @@ function providerFrom(catalog, provider) {
|
|
|
45
45
|
return instance;
|
|
46
46
|
}
|
|
47
47
|
|
|
48
|
-
function modelFrom(models, { provider, model: pin, class: modelClass, excluded
|
|
48
|
+
function modelFrom(models, { provider, model: pin, class: modelClass, excluded }) {
|
|
49
49
|
if (pin && pin !== 'null') {
|
|
50
50
|
const model = models.find((model) => model.id === pin && !excluded.includes(model.id));
|
|
51
51
|
if (!model) throw new Error(`missing requested model ${pin}`);
|
|
@@ -56,9 +56,7 @@ function modelFrom(models, { provider, model: pin, class: modelClass, excluded,
|
|
|
56
56
|
if (['codex', 'claude'].includes(provider)) {
|
|
57
57
|
throw new Error(`intentional absence for ${provider}: missing model and class`);
|
|
58
58
|
}
|
|
59
|
-
|
|
60
|
-
const model = provider === 'antigravity'
|
|
61
|
-
? models.find((model) => model.id.endsWith(`-${effort}`)) : models[0];
|
|
59
|
+
const model = models[0];
|
|
62
60
|
if (!model || excluded.includes(model.id)) throw new Error('missing first listed model');
|
|
63
61
|
return model;
|
|
64
62
|
}
|
|
@@ -89,19 +87,12 @@ try {
|
|
|
89
87
|
const catalog = JSON.parse(readFileSync(path, 'utf8'));
|
|
90
88
|
const instance = providerFrom(catalog, provider);
|
|
91
89
|
const model = modelFrom(instance.models, options);
|
|
92
|
-
|
|
93
|
-
if (
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
}
|
|
97
|
-
} else {
|
|
98
|
-
const effortOptions = model.options.filter((option) => option.id === effortIds[provider]);
|
|
99
|
-
if (effortOptions.length !== 1 || !effortOptions[0].options?.some((value) => value.id === effort)
|
|
100
|
-
|| (provider === 'grok' && effort === 'max')) {
|
|
101
|
-
throw new Error(`unsupported effort ${effort} for ${provider}/${model.id}`);
|
|
102
|
-
}
|
|
103
|
-
effortOption = { id: effortOptions[0].id, value: effort };
|
|
90
|
+
const effortOptions = model.options.filter((option) => option.id === effortIds[provider]);
|
|
91
|
+
if (effortOptions.length !== 1 || !effortOptions[0].options?.some((value) => value.id === effort)
|
|
92
|
+
|| (provider === 'grok' && effort === 'max')) {
|
|
93
|
+
throw new Error(`unsupported effort ${effort} for ${provider}/${model.id}`);
|
|
104
94
|
}
|
|
95
|
+
const effortOption = { id: effortOptions[0].id, value: effort };
|
|
105
96
|
console.log(JSON.stringify({ provider, providerInstanceId: instance.providerInstanceId,
|
|
106
97
|
model: model.id, effortOption, source: 'capabilities', path }));
|
|
107
98
|
} catch (error) {
|
|
@@ -12,7 +12,7 @@ hard-to-reverse choices; they replace the critique round for that question.
|
|
|
12
12
|
example, taking the shortest path that compiles. Treat them as prompts, not defects. Candidates receive only the brief; the rubric is for judging.
|
|
13
13
|
2. **Fan out.** Produce one candidate per configured family independently from the same brief,
|
|
14
14
|
without cross-reading: `axstack-advisor-astra`, `axstack-advisor-opus`,
|
|
15
|
-
|
|
15
|
+
and `axstack-arena-candidate-grok`.
|
|
16
16
|
Each gives a design, rationale, and rejected alternatives. The driver authors no candidate.
|
|
17
17
|
The driver drafts no recommendation until every candidate returns.
|
|
18
18
|
3. **Cross-judge (Rung 2 only).** After every candidate completes, give round 1 judge
|
|
@@ -45,7 +45,7 @@ verdicts per round) as `Decisions` rows in the
|
|
|
45
45
|
[caller's run record](../../axstack/references/run-record.md) when one exists,
|
|
46
46
|
otherwise include it in the returned verdict. Load
|
|
47
47
|
[T3 runtime](../../axstack/references/t3-runtime.md) immediately before the
|
|
48
|
-
first candidate or judge dispatch. If an optional Grok
|
|
48
|
+
first candidate or judge dispatch. If an optional Grok candidate
|
|
49
49
|
malfunctions (launch failure, trust/login prompt, or prompt block), fence it,
|
|
50
50
|
record `absent (<reason>)`, name it once in the next
|
|
51
51
|
read-back, and continue with available candidates without relay or substitution.
|
|
@@ -20,9 +20,12 @@ Before any runtime action, load and follow:
|
|
|
20
20
|
evidence is the last removable-worktree blocker
|
|
21
21
|
|
|
22
22
|
Use project-scoped T3 thread inventory, `git worktree list --porcelain` and run
|
|
23
|
-
records.
|
|
24
|
-
|
|
25
|
-
|
|
23
|
+
records.
|
|
24
|
+
Hosts can delete author worktrees at merge through `storageCleanup.worktreeOnMerge`.
|
|
25
|
+
`t3_project_read` cannot read `storageCleanup.worktreeOnMerge`.
|
|
26
|
+
Evidence never lives in a worktree and belongs in private `<run>/evidence/<key>/`.
|
|
27
|
+
A missing merged or closed author worktree is expected, not a hold.
|
|
28
|
+
Follow the runtime schema, never invent an alternate command protocol.
|
|
26
29
|
|
|
27
30
|
## Authority and scope
|
|
28
31
|
|