axstack 0.24.1 → 0.25.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 +48 -9
- package/docs/installation.md +9 -6
- package/docs/workflows.md +142 -27
- package/package.json +1 -1
- package/profiles/presets/claude-only.json +10 -1
- package/profiles/presets/codex-only.json +10 -1
- package/profiles/presets/mixed.json +16 -7
- package/skills/axstack/references/automations.md +41 -3
- package/skills/axstack/references/autopilot.md +37 -21
- package/skills/axstack/references/candidate-publication.md +10 -0
- package/skills/axstack/references/contracts.md +20 -17
- package/skills/axstack/references/diligence.md +6 -1
- package/skills/axstack/references/lifecycle.md +4 -4
- package/skills/axstack/references/pr-shape.md +5 -0
- package/skills/axstack/references/pr-triage-nightly.md +22 -0
- package/skills/axstack/references/preview.md +53 -0
- package/skills/axstack/references/review-manager-prompt.md +6 -3
- package/skills/axstack/references/role-roster.md +5 -1
- package/skills/axstack/references/routing.md +7 -2
- package/skills/axstack/references/run-record.md +4 -1
- package/skills/axstack/references/t3-runtime.md +68 -3
- package/skills/axstack/references/test-audit-weekly.md +4 -1
- package/skills/axstack/references/ui-verification.md +2 -0
- package/skills/axstack/scripts/pick-instance.js +110 -0
- package/skills/axstack-audit/SKILL.md +5 -3
- package/skills/axstack-implement/SKILL.md +25 -10
- package/skills/axstack-relay/SKILL.md +37 -11
- package/skills/axstack-review/SKILL.md +42 -11
- package/skills/axstack-watch/SKILL.md +125 -42
- package/skills/axstack-watch/references/repair-publication.md +3 -0
- package/skills/axstack-watch/references/watch-runtime.md +34 -12
|
@@ -45,6 +45,16 @@ remote confirmation. Reviewers inspect a detached immutable checkout of the
|
|
|
45
45
|
confirmed candidate SHA and pinned base, never only the movable branch name.
|
|
46
46
|
Any author repair creates a new revision and repeats this boundary.
|
|
47
47
|
|
|
48
|
+
## Revert line
|
|
49
|
+
|
|
50
|
+
Every own PR description must contain exactly one `Revert` line:
|
|
51
|
+
`Revert: clean` | `Revert: steps: <manual steps>` | `Revert: irreversible: <why>`.
|
|
52
|
+
Use `clean` only when a single `git revert` of the merge commit restores the
|
|
53
|
+
previous behaviour with CI green.
|
|
54
|
+
A `clean` revert leaves no data, schema, config, external, or published effect behind.
|
|
55
|
+
Otherwise use `steps` or `irreversible`.
|
|
56
|
+
Classify every release PR as `irreversible`.
|
|
57
|
+
|
|
48
58
|
## Immutable checkout shape
|
|
49
59
|
|
|
50
60
|
The driver creates the immutable review checkout with `git worktree add --detach <run>/checkouts/<key> <sha>` at the confirmed candidate SHA and pinned base.
|
|
@@ -40,9 +40,14 @@ the revised scope and plan.
|
|
|
40
40
|
|
|
41
41
|
Validate the configured provider and model at actual launch. If it is
|
|
42
42
|
unavailable or exhausted, pause affected work, record the gap, and ask the
|
|
43
|
-
user.
|
|
43
|
+
user. Only same-provider, same-model account selection among instances of one
|
|
44
|
+
driver may use headroom under [Provider bindings](t3-runtime.md#preflight-and-binding).
|
|
45
|
+
An exhausted account with no eligible sibling still holds; dispatched roles never fail over mid-thread.
|
|
46
|
+
Follow [Provider bindings](t3-runtime.md#preflight-and-binding) for driver account re-selection at turn boundaries.
|
|
47
|
+
Never infer any other route from quota state or subscription entitlement. Every
|
|
44
48
|
substitution requires the user's decision: configured alternatives are not
|
|
45
49
|
defaults. Rejection, timeout, quota and auth failures hold affected work.
|
|
50
|
+
Substitution here means changing provider or model, excluding that account selection.
|
|
46
51
|
Read the [T3 runtime boundary](t3-runtime.md) before dispatch, receipt consumption
|
|
47
52
|
or recovery; resolve models from the saved capabilities snapshot and verify
|
|
48
53
|
requested and effective settings separately.
|
|
@@ -103,19 +108,17 @@ gate.
|
|
|
103
108
|
|
|
104
109
|
## Authority
|
|
105
110
|
|
|
106
|
-
- The driver owns
|
|
107
|
-
|
|
108
|
-
- One T3 host/server owns a run.
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
- The human merges by default, bottom-up for a stack. Review approval and
|
|
121
|
-
reviewer votes never grant mutation or merge authority.
|
|
111
|
+
- The driver owns scope, cross-PR coordination, integration, and every selected
|
|
112
|
+
external-tracker mutation. Checker reports discrepancies only.
|
|
113
|
+
- One T3 host/server owns a run. No fixed active-PR count; fanout is dependency-
|
|
114
|
+
and capacity-driven within host resource and spending limits. Reduce fanout for
|
|
115
|
+
recorded rework, review backlog, or resource pressure. Queue conflicts and
|
|
116
|
+
dependencies; use `gh stack` for dependent PRs. Routine shape, split, fanout, and
|
|
117
|
+
exception choices within approved scope are autonomous driver decisions; size alone never
|
|
118
|
+
requires user approval.
|
|
119
|
+
- Exactly one writer per candidate; one persistent accountable PR owner. Each PR has one theme and measured size under [PR shape](pr-shape.md). Report unknown capacity
|
|
120
|
+
metrics; never a telemetry prerequisite or blocker. Parent changes invalidate
|
|
121
|
+
affected child evidence; refresh it against the new parent.
|
|
122
|
+
- Own PRs default to automatic merge under [watch §5](../../axstack-watch/SKILL.md).
|
|
123
|
+
Review approval and reviewer votes alone never grant mutation or merge authority.
|
|
124
|
+
User merges are bottom-up for a stack.
|
|
@@ -7,6 +7,11 @@ It is read-only, never authors or edits, and returns `PASS`, `FINDINGS`, or `UNK
|
|
|
7
7
|
with locations, observed evidence, and limits. A stale or missing receipt is
|
|
8
8
|
not a pass. Keep its first pass independent of other reviewers and workers.
|
|
9
9
|
|
|
10
|
+
Load [Finding severity](../../axstack-review/SKILL.md#finding-severity) for the shared rubric.
|
|
11
|
+
Diligence returns `FINDINGS` for any `medium` or `high` mismatch.
|
|
12
|
+
Diligence returns `PASS` with the low items listed when only low mismatches remain.
|
|
13
|
+
Keep diligence `UNKNOWN` unchanged.
|
|
14
|
+
|
|
10
15
|
For a PR, compare every changed line with the accepted intent and exclusions:
|
|
11
16
|
is it intended and in scope? Check that no contract, rule, or obligation was
|
|
12
17
|
silently weakened or dropped by rewording. Compare the PR body, commit messages,
|
|
@@ -30,5 +35,5 @@ Report an attributed failure with its retained output normally.
|
|
|
30
35
|
An observed full-suite failure still fails the suite, including when attributed or reported `UNKNOWN`.
|
|
31
36
|
No reruns are required.
|
|
32
37
|
|
|
33
|
-
`FINDINGS` identifies a mismatch for the driver to resolve at the owning phase;
|
|
38
|
+
`FINDINGS` identifies a medium or high mismatch for the driver to resolve at the owning phase;
|
|
34
39
|
it does not edit the artifact or create another review round by itself.
|
|
@@ -9,9 +9,9 @@ binding state and receipts to exact revisions.
|
|
|
9
9
|
|
|
10
10
|
- Driver: current chat; owns scope, decisions, cross-PR dependencies,
|
|
11
11
|
external-tracker mutations, integration.
|
|
12
|
-
- Owner: driver
|
|
13
|
-
|
|
14
|
-
merge
|
|
12
|
+
- Owner: driver for loop PRs; `axstack-owner` for standalone watch/review without
|
|
13
|
+
a live driver. PR-scoped publication is within user authority.
|
|
14
|
+
Own PRs default to automatic merge under watch §5's predicate.
|
|
15
15
|
- Author: exactly one writer per candidate; accepted fixes return there.
|
|
16
16
|
Workers launch no recursive teams.
|
|
17
17
|
- Reviewers: peer = two configured roles with the same brief and isolated first
|
|
@@ -121,7 +121,7 @@ The default 24-hour deadline covers standalone task-owned timers. Stop them at
|
|
|
121
121
|
deadline and preserve remaining work; the review automation has no task-owned
|
|
122
122
|
deadline. Merge-ready requires applicable review receipt(s) and current diligence
|
|
123
123
|
`PASS` at the exact head; CI/tests alone are insufficient. Merge-ready
|
|
124
|
-
differs from merged
|
|
124
|
+
differs from merged.
|
|
125
125
|
|
|
126
126
|
## Review automation health
|
|
127
127
|
|
|
@@ -24,6 +24,11 @@ migrations that must change together to stay green and reviewable.
|
|
|
24
24
|
This is not a folder restriction. Unrelated themes split even under the target.
|
|
25
25
|
Smaller cohesive PRs are encouraged; no padding.
|
|
26
26
|
|
|
27
|
+
## PR body
|
|
28
|
+
|
|
29
|
+
Every own PR description must contain exactly one `Revert` line.
|
|
30
|
+
Follow [Revert line](candidate-publication.md#revert-line) for its format and classification.
|
|
31
|
+
|
|
27
32
|
## Exception band
|
|
28
33
|
The driver attempts a reasonable split first. If each tried split materially
|
|
29
34
|
compromises atomicity, green state, or independent reviewability, or inseparable
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
# Nightly PR-triage prompt
|
|
2
|
+
|
|
3
|
+
You are a fresh read-only nightly PR-triage pass in your own T3 thread.
|
|
4
|
+
Read-only applies to the forge, and own schedule replacement follows [Provider bindings](t3-runtime.md#preflight-and-binding).
|
|
5
|
+
At pass start, follow [Provider bindings](t3-runtime.md#preflight-and-binding) for your own account and schedule binding.
|
|
6
|
+
Use [Nightly PR-triage setup](automations.md#nightly-pr-triage-setup) for activation.
|
|
7
|
+
Read the durable activation record for the repository set.
|
|
8
|
+
Resolve the user with `gh api user --jq .login`.
|
|
9
|
+
Read all open PRs authored by the user in every repository in the recorded set,
|
|
10
|
+
including all pages.
|
|
11
|
+
|
|
12
|
+
Report each PR's CI, reviews, mergeable state, and unresolved threads in your
|
|
13
|
+
own T3 thread.
|
|
14
|
+
For each unavailable, failed, or incomplete forge field, report `UNKNOWN`.
|
|
15
|
+
Report incomplete repository or pagination coverage explicitly.
|
|
16
|
+
Flag stale PRs after 7 days of inactivity.
|
|
17
|
+
Report the top three PRs to act on with reasons drawn from the observed state.
|
|
18
|
+
If fewer than three PRs exist, report those available.
|
|
19
|
+
Never declare a PR merge-ready.
|
|
20
|
+
|
|
21
|
+
Never merge, post comments, change labels, push, send relay messages, dispatch
|
|
22
|
+
work, or launch threads.
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
# PR previews
|
|
2
|
+
|
|
3
|
+
Only the PR owner runs this procedure for private previews over the tailnet.
|
|
4
|
+
The tailnet is the user's private Tailscale network.
|
|
5
|
+
Preview authority covers only the preview unit and its `tailscale serve` route on the VPS.
|
|
6
|
+
This procedure grants no release, npm publish, or host install authority.
|
|
7
|
+
A later release run under `AGENTS.md` needs its own recorded authority.
|
|
8
|
+
|
|
9
|
+
## Decide
|
|
10
|
+
|
|
11
|
+
Start a preview only when the run's T3 host is the VPS.
|
|
12
|
+
On any other host, record "no preview: run host is not the VPS" and continue.
|
|
13
|
+
For each own PR, the owner decides whether a preview makes sense.
|
|
14
|
+
Require both a runnable dev-server command documented in the base branch's `AGENTS.md` or README and a user-visible change in the PR.
|
|
15
|
+
Read the command only from the base.
|
|
16
|
+
Never read the command from the PR head.
|
|
17
|
+
If either requirement is missing, record "no preview".
|
|
18
|
+
|
|
19
|
+
Report missing systemd user lingering or Tailscale operator rights as "no preview".
|
|
20
|
+
Never change systemd user lingering or Tailscale operator rights.
|
|
21
|
+
Never change unrelated host services or configuration.
|
|
22
|
+
Run at most two previews per host.
|
|
23
|
+
A third preview waits until a slot frees.
|
|
24
|
+
|
|
25
|
+
## Start and record
|
|
26
|
+
|
|
27
|
+
The owner starts the preview from an isolated checkout of the PR head as a systemd user unit.
|
|
28
|
+
Set `RuntimeMaxSec=4h`, `MemoryMax=2G`, and `CPUQuota=200%`.
|
|
29
|
+
Use only repository-documented dev or test environment sources.
|
|
30
|
+
Never use production secrets for a preview in any repository.
|
|
31
|
+
After start, confirm the process listens only on loopback.
|
|
32
|
+
After start, confirm the `tailscale serve` target is `127.0.0.1:<port>`.
|
|
33
|
+
If either loopback check fails, tear down and record "no preview: not loopback-only".
|
|
34
|
+
Never use Tailscale Funnel.
|
|
35
|
+
|
|
36
|
+
Record `Preview: <url> @ <served-sha>` in the run record and the driver thread.
|
|
37
|
+
Label it as the served revision, distinct from the PR head SHA.
|
|
38
|
+
Put the Preview line and any "preview queued" note in the PR description only for private repositories.
|
|
39
|
+
After each restart or teardown, update or remove the Preview line and any "preview queued" note in the private PR description.
|
|
40
|
+
Update or remove the run-record and driver-thread preview records after each restart or teardown.
|
|
41
|
+
|
|
42
|
+
The `axstack-ui-verifier` can use the preview URL.
|
|
43
|
+
A preview never replaces UI verification.
|
|
44
|
+
Follow [UI verification](ui-verification.md) for the independent rendered pass.
|
|
45
|
+
|
|
46
|
+
## Restart and teardown
|
|
47
|
+
|
|
48
|
+
When the PR head changes, restart the preview on the new head.
|
|
49
|
+
Run teardown when the PR merges or closes, the watch ends, or the time limit stops the unit.
|
|
50
|
+
Use `ExecStopPost` to remove the route when the time limit stops the unit.
|
|
51
|
+
At teardown, remove both the unit and its `tailscale serve` route.
|
|
52
|
+
Read back the absence of both the unit and its `tailscale serve` route.
|
|
53
|
+
If teardown fails, hold and record a receipt.
|
|
@@ -1,12 +1,15 @@
|
|
|
1
1
|
# Review manager prompt
|
|
2
2
|
|
|
3
|
+
At pass start, follow [Provider bindings](t3-runtime.md#preflight-and-binding) for own account selection.
|
|
4
|
+
|
|
3
5
|
You are a fresh finite T3 review-manager pass in project `axstack-review-lane`
|
|
4
6
|
on the VPS's existing `axatbhardwaj/axstack` clone. Fetch first; this unbound
|
|
5
7
|
pass worktree starts from `origin/main`. Enter through installed `axstack-review`,
|
|
6
8
|
which loads `../axstack/references/automations.md` relatively. Read that contract
|
|
7
|
-
and [T3 runtime](t3-runtime.md).
|
|
8
|
-
|
|
9
|
-
|
|
9
|
+
and [T3 runtime](t3-runtime.md). Reconcile lane ownership and duplicate status,
|
|
10
|
+
then follow [Provider bindings](t3-runtime.md#preflight-and-binding) for shared schedule
|
|
11
|
+
recreation and recorded instance update before verifying the recorded `axstack-owner`
|
|
12
|
+
binding before admission. Discover all eligible peer-review events and admit within measured host capacity.
|
|
10
13
|
Use host-clone detached per-PR checkouts; preserve exact ownership and receipts.
|
|
11
14
|
Retire settled predecessors, report retained worktree count, and disable the
|
|
12
15
|
schedule and hold past its authorized limit. Save and read back continuity at
|
|
@@ -2,7 +2,11 @@
|
|
|
2
2
|
|
|
3
3
|
- Chat drives (no role ID); `axstack-owner` owns one PR and
|
|
4
4
|
`axstack-author` its sole writer.
|
|
5
|
-
|
|
5
|
+
For own PRs, automatic merge is the default under the
|
|
6
|
+
[watch predicate](../../axstack-watch/SKILL.md#5-state-readiness-precisely).
|
|
7
|
+
Only the recorded owning watch thread merges, including `axstack-owner`
|
|
8
|
+
for authorized standalone maintenance. Other roles never acquire merge authority.
|
|
9
|
+
- `axstack-reviewer-primary` and `axstack-reviewer-peer` are the ordered
|
|
6
10
|
peer pair. Peer review uses both; authored review uses this table:
|
|
7
11
|
|
|
8
12
|
| Preset | Author class | Reviewer (class/effort) |
|
|
@@ -10,6 +10,9 @@ Presets: `mixed`, `codex-only`, `claude-only`. For new runs, use
|
|
|
10
10
|
skills root, or an explicit user selection in the run record. Missing or contradictory sources are
|
|
11
11
|
a setup gap: hold. Never infer from live profiles, harness,
|
|
12
12
|
tools, credentials, quota, subscription, or default to `mixed`.
|
|
13
|
+
Only same-provider, same-model account selection among instances of one driver
|
|
14
|
+
may use headroom under [Provider bindings](t3-runtime.md#preflight-and-binding);
|
|
15
|
+
provider/model substitution still requires the user's decision.
|
|
13
16
|
|
|
14
17
|
At start, snapshot all role IDs from installed `skills/axstack/roles.json`,
|
|
15
18
|
including provider/modelClass/model/mode/effort and intentional absences.
|
|
@@ -35,6 +38,8 @@ An unavailable provider, model, role, mode or effort holds that role with no sub
|
|
|
35
38
|
Preset changes apply to new runs only; an active run keeps its snapshot.
|
|
36
39
|
Replacing a session needs an explicit user decision and revalidation.
|
|
37
40
|
Timeout, quota, auth and rejection hold affected work.
|
|
41
|
+
An exhausted account with no eligible sibling still holds; dispatched roles never fail over mid-thread.
|
|
42
|
+
Follow [Provider bindings](t3-runtime.md#preflight-and-binding) for driver account re-selection at turn boundaries.
|
|
38
43
|
[Model discipline](contracts.md#model-discipline) governs optional seats,
|
|
39
44
|
auditor preflight, and required holds; [Role roster](role-roster.md) governs
|
|
40
45
|
single-provider absence and mixed Codex+Claude fan-out.
|
|
@@ -102,8 +107,8 @@ reason in the run record, or in the brief for tiny direct work.
|
|
|
102
107
|
issue plus explicit acceptance checks and exclusions, snapshots it once, and
|
|
103
108
|
proceeds. No prior snapshot, spec, tickets, or second approval is required; do not route
|
|
104
109
|
to `axstack-align` solely because the snapshot is not yet written. Strict TDD,
|
|
105
|
-
mode-specific review, model, risk, and
|
|
106
|
-
|
|
110
|
+
mode-specific review, model, risk, and merge-authority contracts still apply.
|
|
111
|
+
Own PRs default to automatic merge under watch §5 predicate.
|
|
107
112
|
- **Unclear:** clarify via `axstack-align` or a bounded question, then
|
|
108
113
|
classify small or substantial; it does not force substantial-work paperwork.
|
|
109
114
|
[Design lens](design-lens.md) Rung 1 is Unclear; use `axstack-align`.
|
|
@@ -97,7 +97,9 @@ send, or watch can be looked up before any retry.
|
|
|
97
97
|
Resume from compact pointers to commands or evidence, not copied transcripts.
|
|
98
98
|
For chat-run watch, record the bound T3 schedule and scheduledTaskId,
|
|
99
99
|
member PR publication/adoption receipts, exact driver threadId/runId, observation/report
|
|
100
|
-
IDs, disposition, wake and stop receipts in this same record.
|
|
100
|
+
IDs, disposition, wake and stop receipts in this same record.
|
|
101
|
+
Record the chat-run watch cadence, last PR event, native schedule lifetime, and re-arm receipts.
|
|
102
|
+
The driver alone writes it; a later same-Run publication joins the membership only after remote readback. Reconcile named threads/runs, revisions, PR state, watches, and deliveries before
|
|
101
103
|
creating or redelivering anything. Outside the bounded driver-start orphan
|
|
102
104
|
sweep, touch only this run; no unscoped global sweep, runtime database, or
|
|
103
105
|
scheduler follows from the record.
|
|
@@ -185,6 +187,7 @@ Source base: <exact revision or source identity>
|
|
|
185
187
|
IDs: <projectId + driver threadId/runId + dispatch identity receipt pointers>
|
|
186
188
|
Runtime: <host + T3 version + installed Axstack SHA + capabilities JSON path>
|
|
187
189
|
Schedules: <scheduledTaskIds of every watch and manager schedule>
|
|
190
|
+
Watch: <member publication/adoption receipts + cadence + last PR event + native lifetime + update/re-arm/stop receipts>
|
|
188
191
|
Worktrees in other repositories: <per-run repository and worktree IDs or none>
|
|
189
192
|
Evidence: <check/review/submission/audit receipt pointers>
|
|
190
193
|
Pending: <launch/acceptance/external receipts + scheduledTaskIds + runIds + deadline>
|
|
@@ -16,8 +16,66 @@ preset and stable role IDs, requested provider/model/class/mode/effort, resolved
|
|
|
16
16
|
ID, source and time once. Resume preserves that snapshot with no re-resolution;
|
|
17
17
|
changes require the user's explicit decision. Bundled presets are setup inputs.
|
|
18
18
|
|
|
19
|
-
Provider bindings must map
|
|
20
|
-
|
|
19
|
+
Provider bindings must map grok→`grok` and antigravity→`antigravity`, with
|
|
20
|
+
canonical error-exit fallbacks codex→`codex` and claude→`claudeAgent`.
|
|
21
|
+
At each dispatch or launch, claude and codex must bind to the instanceId printed
|
|
22
|
+
by `scripts/pick-instance.js --provider <provider>`.
|
|
23
|
+
For dispatched roles, only error exit 1 permits fallback to the canonical instance after validating availability.
|
|
24
|
+
Exit 2 (no eligible provider instances) must hold the work without fallback.
|
|
25
|
+
Record the chosen instanceId and a pointer to saved `--json` output in the dispatch record.
|
|
26
|
+
Only same-provider, same-model account selection among instances of one driver
|
|
27
|
+
is permitted, with provider, model, class and effort rules required to remain unchanged.
|
|
28
|
+
An exhausted account with no eligible sibling must hold.
|
|
29
|
+
Dispatched roles never fail over mid-thread.
|
|
30
|
+
|
|
31
|
+
When the driver starts or resumes a run and at the start of every run-watch wake,
|
|
32
|
+
it runs `scripts/pick-instance.js --provider <its own provider> --json`.
|
|
33
|
+
Read its current binding with `t3_thread_configuration` and save picker JSON in private run evidence.
|
|
34
|
+
If the driver's own current instance is `excluded` for a usage limit and an eligible
|
|
35
|
+
same-provider sibling exists, it must switch itself via `t3_thread_configure` to the
|
|
36
|
+
chosen sibling instance, keeping the same provider, model and effort/options, then continue.
|
|
37
|
+
The driver must record from/to instance, a pointer to saved picker JSON and UTC time in `progress.md`.
|
|
38
|
+
If the driver's own current instance is eligible, it must stay despite headroom differences.
|
|
39
|
+
On exit 2 (no eligible sibling), the driver must hold under the existing rule.
|
|
40
|
+
On error exit 1, the driver must keep its current instance.
|
|
41
|
+
Driver account re-selection must configure only the calling thread and only at a turn boundary.
|
|
42
|
+
A turn already paused by a usage limit cannot self-recover.
|
|
43
|
+
The next wake or user message runs this check.
|
|
44
|
+
|
|
45
|
+
Driver self-switching is required from v0.25.1.
|
|
46
|
+
T3 scheduled tasks retain the creation-time instanceId for wakes and fresh-thread
|
|
47
|
+
passes regardless of the calling thread's current binding.
|
|
48
|
+
The driver must arm a run watch only after picking its account: `pick-instance.js` before `schedule_task`.
|
|
49
|
+
On a driver self-switch, delete and recreate its armed bound run watch with the
|
|
50
|
+
same prompt, cadence and binding on the new instance.
|
|
51
|
+
|
|
52
|
+
Every scheduled automation pass runs `scripts/pick-instance.js --provider <its own provider> --json`
|
|
53
|
+
at pass start, including fresh-thread review-manager passes.
|
|
54
|
+
Scheduled passes follow the driver's eligibility and stay rules: an eligible own instance stays,
|
|
55
|
+
exit 1 keeps the current instance and exit 2 holds.
|
|
56
|
+
If a scheduled pass's own current instance is `excluded` and an eligible same-provider sibling exists,
|
|
57
|
+
it must switch itself via `t3_thread_configure` to the chosen sibling instance,
|
|
58
|
+
keeping the same provider, model and effort/options.
|
|
59
|
+
On a scheduled pass self-switch in a review-manager lane, only the owner-of-record, after lane reconciliation
|
|
60
|
+
and the duplicate check, must delete and recreate its own schedule with the same
|
|
61
|
+
prompt, cadence and binding on the chosen instance.
|
|
62
|
+
On any other scheduled pass self-switch, delete and recreate its own schedule with
|
|
63
|
+
the same prompt, cadence and binding on the chosen instance only after `list_scheduled_tasks`
|
|
64
|
+
confirms no replacement for that schedule on the chosen instance already exists.
|
|
65
|
+
If a replacement for that schedule on the chosen instance already exists, any other scheduled pass must skip recreation.
|
|
66
|
+
For a review-manager self-switch, only the owner-of-record must update the recorded
|
|
67
|
+
`axstack-owner` binding's instanceId to the chosen instance after verifying unchanged
|
|
68
|
+
provider/model/effort/options with `t3_thread_configuration` and attaching the picker
|
|
69
|
+
switch receipt, before the admission binding comparison.
|
|
70
|
+
For each schedule replacement, read back old absence and new presence using `list_scheduled_tasks`.
|
|
71
|
+
For each schedule replacement, record old/new scheduledTaskId, from/to instance,
|
|
72
|
+
picker JSON pointer and UTC time in the `progress.md` or durable activation/continuity record.
|
|
73
|
+
Retain the recorded schedule's title and enabled state and use a fresh stable creation `clientRequestId`.
|
|
74
|
+
An uncertain replacement holds affected work: preserve its native receipts for reconciliation.
|
|
75
|
+
A scheduled pass already running on an exhausted account cannot recover.
|
|
76
|
+
Account switches must happen before exhaustion at the picker's near-limit cutoff.
|
|
77
|
+
|
|
78
|
+
Map `modeId` to `runtimeMode:full-access` and effort
|
|
21
79
|
to `options:[{id,value}]`. Stored permission intent is neither effective parity
|
|
22
80
|
nor a security boundary.
|
|
23
81
|
|
|
@@ -27,6 +85,7 @@ A preset model must be used as given.
|
|
|
27
85
|
codex `gpt-<N>-<class>`, claude `claude-<class>-<N>-<N>`. Use
|
|
28
86
|
`scripts/resolve-models.js --provider` with the saved capabilities JSON path;
|
|
29
87
|
a missing or malformed catalog holds resolution.
|
|
88
|
+
Model catalog resolution retains the canonical instance IDs above.
|
|
30
89
|
|
|
31
90
|
A `model:null` role lacking a class must use the first model listed for its
|
|
32
91
|
provider in saved capabilities only for grok and antigravity (launch-by-agent-id
|
|
@@ -40,6 +99,8 @@ absence and must hold; never use a provider default for that role.
|
|
|
40
99
|
|
|
41
100
|
An unavailable provider, model, role, mode or effort must hold that role with
|
|
42
101
|
no substitution. Auth, quota, timeout and rejection do not select an alternative.
|
|
102
|
+
Here alternative means a provider or model substitution, excluding the bounded
|
|
103
|
+
same-provider, same-model account selection above.
|
|
43
104
|
Intentional absent seats remain recorded absences; availability is runtime proof.
|
|
44
105
|
|
|
45
106
|
Codex effort must use option ID `reasoningEffort`.
|
|
@@ -234,4 +295,8 @@ The boundary must provide no Axstack daemon, DB, lock or scheduler. Native T3
|
|
|
234
295
|
schedules supply wakes; Axstack maintains prose records, not a runtime state
|
|
235
296
|
engine. Private evidence requires explicit publication authority before sharing;
|
|
236
297
|
receipts confer no merge, release, publication, model-substitution, host-mutation
|
|
237
|
-
or expanded scope authority.
|
|
298
|
+
or expanded scope authority.
|
|
299
|
+
For own PRs, automatic merge is the default under the
|
|
300
|
+
[watch predicate](../../axstack-watch/SKILL.md#5-state-readiness-precisely).
|
|
301
|
+
The recorded owning watch thread merges; a missing or idle owner requires
|
|
302
|
+
lifecycle reconciliation and explicit transfer first.
|
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
# Weekly test-audit prompt
|
|
2
2
|
|
|
3
|
+
At pass start, follow [Provider bindings](t3-runtime.md#preflight-and-binding) for account selection and schedule recreation.
|
|
4
|
+
|
|
3
5
|
You are a fresh finite weekly test-audit session in this repository's dedicated
|
|
4
6
|
T3 project worktree. Before admission, read the activation record: repository,
|
|
5
7
|
test-path allowlist, finite budget, and standing edit and PR-open authority.
|
|
@@ -54,7 +56,8 @@ Keep one writer and private revision-bound receipts; workers never push.
|
|
|
54
56
|
Obtain independent review using Implement's configured authored-review roles and
|
|
55
57
|
verify the exact candidate's checks before publication. The driver uses
|
|
56
58
|
`gh stack` and opens at most one test-audit PR per week after independent review;
|
|
57
|
-
the
|
|
59
|
+
for own PRs, automatic merge is the default under the
|
|
60
|
+
[watch predicate](../../axstack-watch/SKILL.md#5-state-readiness-precisely).
|
|
58
61
|
|
|
59
62
|
Notify only under the run's Notification policy: a decision park, merge-ready
|
|
60
63
|
(within the run's milestone cap), or serious-risk hold; never progress or
|
|
@@ -6,6 +6,8 @@ run's role snapshot. Give it the exact build, URL, or artifact and the private
|
|
|
6
6
|
dispatch's evidence folder. The verifier is read-only: it never edits source.
|
|
7
7
|
The PR writer remains the sole writer.
|
|
8
8
|
|
|
9
|
+
Before using a PR preview URL, the UI verifier must read [PR previews](preview.md).
|
|
10
|
+
|
|
9
11
|
The sole author browser exception is archify `finalize` as a headless build gate.
|
|
10
12
|
Keep finalize outputs only in the private evidence folder.
|
|
11
13
|
Never replace the verifier's rendered pass with finalize.
|
|
@@ -0,0 +1,110 @@
|
|
|
1
|
+
import { mkdirSync, readFileSync, writeFileSync } from 'node:fs';
|
|
2
|
+
|
|
3
|
+
const weights = {
|
|
4
|
+
claude: { default_claude_max_20x: 4, default_claude_max_5x: 1 }, codex: { pro: 4, prolite: 1 },
|
|
5
|
+
};
|
|
6
|
+
const drivers = { claude: 'claudeAgent', codex: 'codex' };
|
|
7
|
+
const home = process.env.HOME;
|
|
8
|
+
const expandHome = (path) => path === '~' ? home : path.startsWith('~/') ? `${home}/${path.slice(2)}` : path;
|
|
9
|
+
const readJson = (path) => JSON.parse(readFileSync(path, 'utf8'));
|
|
10
|
+
const cacheDir = `${process.env.XDG_CACHE_HOME || `${home}/.cache`}/axstack`;
|
|
11
|
+
const cachePath = `${cacheDir}/usage.json`;
|
|
12
|
+
let cache;
|
|
13
|
+
try { cache = readJson(cachePath); } catch { cache = {}; }
|
|
14
|
+
if (!cache || typeof cache !== 'object' || Array.isArray(cache)) cache = {};
|
|
15
|
+
|
|
16
|
+
function argumentsFrom(args) {
|
|
17
|
+
const options = {};
|
|
18
|
+
for (let i = 0; i < args.length; i++) {
|
|
19
|
+
const flag = args[i];
|
|
20
|
+
if (flag === '--json' && !options.json) { options.json = true; continue; }
|
|
21
|
+
if (!['--provider', '--settings'].includes(flag) || flag.slice(2) in options) {
|
|
22
|
+
throw new Error('expected --provider claude|codex [--settings path] [--json]');
|
|
23
|
+
}
|
|
24
|
+
const value = args[++i];
|
|
25
|
+
if (!value || value.startsWith('--')) throw new Error('missing argument value');
|
|
26
|
+
options[flag.slice(2)] = value;
|
|
27
|
+
}
|
|
28
|
+
if (!Object.hasOwn(drivers, options.provider)) throw new Error('expected --provider claude|codex');
|
|
29
|
+
return options;
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
async function account(instanceId, instance, provider) {
|
|
33
|
+
const config = instance.config ?? {};
|
|
34
|
+
const dir = expandHome((provider === 'claude' ? config.homePath : config.shadowHomePath || config.homePath)
|
|
35
|
+
|| `${home}/.${provider}`);
|
|
36
|
+
let credentials;
|
|
37
|
+
try {
|
|
38
|
+
credentials = readJson(`${dir}/${provider === 'claude' ? '.credentials.json' : 'auth.json'}`);
|
|
39
|
+
const valid = provider === 'claude' ? credentials.claudeAiOauth?.accessToken
|
|
40
|
+
: credentials.tokens?.access_token && credentials.tokens?.account_id;
|
|
41
|
+
if (!valid) throw new Error();
|
|
42
|
+
} catch {
|
|
43
|
+
return { instanceId, score: null, state: 'skipped', reason: 'missing credentials' };
|
|
44
|
+
}
|
|
45
|
+
const headers = provider === 'claude'
|
|
46
|
+
? { authorization: `Bearer ${credentials.claudeAiOauth.accessToken}`,
|
|
47
|
+
'anthropic-beta': 'oauth-2025-04-20', 'user-agent': 'claude-cli/2.1.0 (external, cli)' }
|
|
48
|
+
: { authorization: `Bearer ${credentials.tokens.access_token}`,
|
|
49
|
+
'chatgpt-account-id': credentials.tokens.account_id };
|
|
50
|
+
const url = provider === 'claude'
|
|
51
|
+
? process.env.AXSTACK_CLAUDE_USAGE_URL || 'https://api.anthropic.com/api/oauth/usage'
|
|
52
|
+
: process.env.AXSTACK_CODEX_USAGE_URL || 'https://chatgpt.com/backend-api/wham/usage';
|
|
53
|
+
const key = JSON.stringify([provider, dir]);
|
|
54
|
+
let value = cache[key];
|
|
55
|
+
if (!Number.isFinite(value?.updatedAt) || !(value.utilization === null || Number.isFinite(value.utilization))
|
|
56
|
+
|| typeof value.limitReached !== 'boolean') value = undefined;
|
|
57
|
+
let state = 'cached';
|
|
58
|
+
if (!value || Date.now() - value.updatedAt >= 5 * 60 * 1000) {
|
|
59
|
+
try {
|
|
60
|
+
const response = await fetch(url, { headers, signal: AbortSignal.timeout(5000) });
|
|
61
|
+
if (!response.ok) throw new Error();
|
|
62
|
+
const usage = await response.json();
|
|
63
|
+
const windows = provider === 'claude'
|
|
64
|
+
? [usage.five_hour?.utilization, usage.seven_day?.utilization]
|
|
65
|
+
: [usage.rate_limit?.primary_window?.used_percent, usage.rate_limit?.secondary_window?.used_percent];
|
|
66
|
+
const known = windows.filter((value) => typeof value === 'number' && Number.isFinite(value));
|
|
67
|
+
value = { updatedAt: Date.now(),
|
|
68
|
+
tier: provider === 'claude' ? credentials.claudeAiOauth.rateLimitTier : usage.plan_type,
|
|
69
|
+
utilization: known.length ? Math.max(...known) : null, limitReached: usage.rate_limit?.limit_reached === true };
|
|
70
|
+
cache[key] = value;
|
|
71
|
+
state = 'fresh';
|
|
72
|
+
try {
|
|
73
|
+
mkdirSync(cacheDir, { recursive: true, mode: 0o700 });
|
|
74
|
+
writeFileSync(cachePath, JSON.stringify(cache), { mode: 0o600 });
|
|
75
|
+
} catch { /* Cache availability must not prevent account selection. */ }
|
|
76
|
+
} catch {
|
|
77
|
+
state = value ? 'stale' : 'unknown';
|
|
78
|
+
value ??= { tier: credentials.claudeAiOauth?.rateLimitTier, utilization: null };
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
const stale = state === 'stale';
|
|
82
|
+
if (value.utilization >= 95 || value.limitReached) {
|
|
83
|
+
return { instanceId, score: null, state: 'excluded', stale, reason: 'usage limit' };
|
|
84
|
+
}
|
|
85
|
+
const weight = Object.hasOwn(weights[provider], value.tier) ? weights[provider][value.tier] : 1;
|
|
86
|
+
return { instanceId, score: value.utilization === null ? weight : (100 - value.utilization) * weight,
|
|
87
|
+
state: value.utilization === null ? 'unknown' : state, stale };
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
try {
|
|
91
|
+
const options = argumentsFrom(process.argv.slice(2));
|
|
92
|
+
const settings = readJson(expandHome(options.settings || `${home}/.t3/userdata/settings.json`));
|
|
93
|
+
if (!settings?.providerInstances || typeof settings.providerInstances !== 'object'
|
|
94
|
+
|| Array.isArray(settings.providerInstances)) throw new Error();
|
|
95
|
+
const instances = [];
|
|
96
|
+
for (const [instanceId, instance] of Object.entries(settings.providerInstances).filter(([, instance]) =>
|
|
97
|
+
instance.enabled && instance.driver === drivers[options.provider])) {
|
|
98
|
+
instances.push(await account(instanceId, instance, options.provider));
|
|
99
|
+
}
|
|
100
|
+
const chosen = instances.filter((instance) => instance.score !== null).sort((a, b) => b.score - a.score)[0];
|
|
101
|
+
if (!chosen) {
|
|
102
|
+
console.error('account selection hold: no eligible provider instances');
|
|
103
|
+
process.exitCode = 2;
|
|
104
|
+
} else {
|
|
105
|
+
console.log(options.json ? JSON.stringify({ chosenInstanceId: chosen.instanceId, instances }) : chosen.instanceId);
|
|
106
|
+
}
|
|
107
|
+
} catch {
|
|
108
|
+
console.error('account selection failed: invalid input/settings or unexpected error');
|
|
109
|
+
process.exitCode = 1;
|
|
110
|
+
}
|
|
@@ -42,8 +42,10 @@ If the base auditor is unlaunchable (preflight rejection, no Dispatch started),
|
|
|
42
42
|
record `auditor: UNKNOWN (unlaunchable)` with the attempted route and error as
|
|
43
43
|
the archive receipt; archive the run. A launched auditor Dispatch must settle
|
|
44
44
|
normally. There is no substitution for the base auditor.
|
|
45
|
-
The user-chosen improvement mode is a tested, independently reviewed PR
|
|
46
|
-
|
|
45
|
+
The user-chosen improvement mode is a tested, independently reviewed PR.
|
|
46
|
+
For own PRs, automatic merge is the default under the
|
|
47
|
+
[watch predicate](../axstack-watch/SKILL.md#5-state-readiness-precisely).
|
|
48
|
+
The auditor never merges.
|
|
47
49
|
|
|
48
50
|
Act as a non-author, read-only reader of the run. The assigned audit artifact is
|
|
49
51
|
`audit.md`, the only writable output. Make no edits to product, skills,
|
|
@@ -151,7 +153,7 @@ Each proposal names:
|
|
|
151
153
|
4. a regression scenario first, followed by an unchanged holdout evaluation;
|
|
152
154
|
5. a cost and quality comparison when those values were measured; and
|
|
153
155
|
6. the authorized delivery path: the auditor suggests, the driver arranges an
|
|
154
|
-
author and independent review, a reviewed PR is proposed, and
|
|
156
|
+
author and independent review, a reviewed PR is proposed, and the owning watch thread applies watch §5, including its user-merge exclusions.
|
|
155
157
|
|
|
156
158
|
Keep evaluation data, candidate changes, and validation separate. This is an
|
|
157
159
|
original Axstack workflow with no outside dependency or extra framework to
|
|
@@ -189,6 +189,10 @@ The author stops at that receipt and does not push. The driver reconciles it,
|
|
|
189
189
|
uses `gh stack` to publish, confirms remote readback, and continues the loop
|
|
190
190
|
without editing the candidate. No step grants merge authority.
|
|
191
191
|
|
|
192
|
+
Every own PR description must contain exactly one `Revert` line.
|
|
193
|
+
Follow [Revert line](../axstack/references/candidate-publication.md#revert-line)
|
|
194
|
+
for its format and classification.
|
|
195
|
+
|
|
192
196
|
## 6. Loop until merge-ready
|
|
193
197
|
|
|
194
198
|
Inputs are one snapshotted small-change intent or an approved spec and ticket
|
|
@@ -202,6 +206,8 @@ For each PR:
|
|
|
202
206
|
|
|
203
207
|
1. Dispatch `axstack-author` under §§3-5 and consume its strict-TDD receipt.
|
|
204
208
|
2. Publish through candidate-publication and read back the exact SHA.
|
|
209
|
+
For each own PR, the owner must follow [PR previews](../axstack/references/preview.md)
|
|
210
|
+
to decide whether a preview makes sense.
|
|
205
211
|
3. Dispatch and consume the authored-mode `axstack-review` selected from actual
|
|
206
212
|
author provenance. State the author's actual provider and model from the
|
|
207
213
|
T3 launch receipt in the review dispatch brief; a `Claude-Session`
|
|
@@ -239,9 +245,10 @@ For each PR:
|
|
|
239
245
|
`repairs` once and counts once toward the third-round hold.
|
|
240
246
|
|
|
241
247
|
The T3 run watch reconciles every unsettled dispatch attempt; the bounded
|
|
242
|
-
forge check wait is the only other implementation wait.
|
|
243
|
-
|
|
244
|
-
|
|
248
|
+
forge check wait is the only other implementation wait.
|
|
249
|
+
After verified readback of every own PR publication, the driver arms or joins
|
|
250
|
+
its maintain-mode chat-run watch under [Autopilot](../axstack/references/autopilot.md).
|
|
251
|
+
That watch owns the bound T3 schedule wake; its runtime sets the cadence.
|
|
245
252
|
A turn with unsettled launched threads must end only under the bound-watch rule in the T3 runtime contract.
|
|
246
253
|
With settled threads, end a turn only when every required PR is `merge-ready` or `held`. Under the recorded Notification policy,
|
|
247
254
|
`axstack-relay` sends only a serious risk immediately, a genuine blocked
|
|
@@ -253,13 +260,21 @@ Only the bounded categories—user-decision holds (including spec approval),
|
|
|
253
260
|
serious-risk holds, and at most two merge-ready/merged milestones per run—may
|
|
254
261
|
be relayed under the recorded Notification policy.
|
|
255
262
|
|
|
256
|
-
Merge-ready opens the merge boundary.
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
+
Merge-ready opens the merge boundary.
|
|
264
|
+
For own PRs, automatic merge is the default under the
|
|
265
|
+
[watch predicate](../axstack-watch/SKILL.md#5-state-readiness-precisely).
|
|
266
|
+
The merge actor is the recorded owning watch thread (`axstack-owner` for
|
|
267
|
+
standalone authorized maintenance), including small and adopted work.
|
|
268
|
+
Missing or idle ownership follows lifecycle reconciliation and explicit transfer first.
|
|
269
|
+
Apply `axstack-watch` §5's merge card and full predicate; an approval alone
|
|
270
|
+
never grants merge authority.
|
|
271
|
+
A peer PR or `deploying` base waits for the user to merge, in either approval mode.
|
|
272
|
+
User merges are bottom-up for a stack.
|
|
273
|
+
A manager, worker, reviewer, monitor, or nightly triage must never merge.
|
|
274
|
+
Observation-only and peer watches never merge.
|
|
275
|
+
Watch §5 owns provider provenance, approval carryover, eligible bases, every
|
|
276
|
+
planned stack member's publication, exclusions, and card-reply exceptions.
|
|
277
|
+
This policy grants no release, npm publish, or host install authority.
|
|
263
278
|
Re-read every predicate term under watch §5 before merging. Confirm merge
|
|
264
279
|
commits are allowed, `delete_branch_on_merge` is false, and the base has no
|
|
265
280
|
merge queue; otherwise hold for the user. For a singleton, use
|