axstack 0.56.1 → 0.58.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (31) hide show
  1. package/package.json +1 -1
  2. package/profiles/presets/claude-only.json +1 -1
  3. package/profiles/presets/codex-only.json +1 -1
  4. package/profiles/presets/mixed.json +1 -1
  5. package/skills/axstack/references/contracts.md +5 -0
  6. package/skills/axstack/references/diligence.md +3 -1
  7. package/skills/axstack/references/fleet-dispatch.md +23 -6
  8. package/skills/axstack/references/fleet-route-schema.md +15 -1
  9. package/skills/axstack/references/lifecycle.md +12 -0
  10. package/skills/axstack/references/local-artifacts.md +202 -0
  11. package/skills/axstack/references/role-roster.md +5 -0
  12. package/skills/axstack/references/t3-runtime.md +7 -0
  13. package/skills/axstack/references/ui-verification.md +4 -1
  14. package/skills/axstack/scripts/dispatch-plan.js +11 -1
  15. package/skills/axstack/scripts/fleet-config.js +3 -1
  16. package/skills/axstack/scripts/fleet-destination.js +12 -3
  17. package/skills/axstack/scripts/fleet-dispatch.js +10 -2
  18. package/skills/axstack/scripts/fleet-facts.js +6 -1
  19. package/skills/axstack/scripts/fleet-receipt.js +45 -8
  20. package/skills/axstack/scripts/fleet-scope.js +37 -0
  21. package/skills/axstack-align/SKILL.md +5 -0
  22. package/skills/axstack-audit/SKILL.md +7 -1
  23. package/skills/axstack-audit/references/record.md +1 -1
  24. package/skills/axstack-brainstorm/SKILL.md +5 -0
  25. package/skills/axstack-brainstorm/references/arena.md +8 -0
  26. package/skills/axstack-explain/SKILL.md +4 -0
  27. package/skills/axstack-explain/references/visual-qa.md +6 -1
  28. package/skills/axstack-improve/SKILL.md +6 -0
  29. package/skills/axstack-publish/SKILL.md +4 -0
  30. package/skills/axstack-research/SKILL.md +4 -0
  31. package/skills/axstack-review/SKILL.md +5 -0
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "axstack",
3
- "version": "0.56.1",
3
+ "version": "0.58.0",
4
4
  "description": "Axstack installer and setup CLI: installs owned chat skills and role data, configures supported harness settings, and checks T3 Code capabilities.",
5
5
  "keywords": [
6
6
  "claude-code",
@@ -297,7 +297,7 @@
297
297
  "model": null,
298
298
  "modeId": "bypassPermissions",
299
299
  "thinkingOptionId": "high",
300
- "notes": "Intentional single-provider absence in the claude-only preset; Grok candidate unavailable. Arena holds without substitution."
300
+ "notes": "Record the intentional single-provider absence of optional Grok in claude-only. Never substitute another model. Required candidate and judge absences still hold their applicable question or round."
301
301
  }
302
302
  ]
303
303
  }
@@ -296,7 +296,7 @@
296
296
  "model": null,
297
297
  "modeId": "full-access",
298
298
  "thinkingOptionId": "high",
299
- "notes": "Intentional single-provider absence in the codex-only preset; Grok candidate unavailable. Arena holds without substitution."
299
+ "notes": "Record the intentional single-provider absence of optional Grok in codex-only. Never substitute another model. Required candidate and judge absences still hold their applicable question or round."
300
300
  }
301
301
  ]
302
302
  }
@@ -299,7 +299,7 @@
299
299
  "model": null,
300
300
  "modeId": "full-access",
301
301
  "thinkingOptionId": "high",
302
- "notes": "Independent Grok Rung 2 design candidate. Use the T3 Grok provider and resolve the model from saved capabilities. Receives the same brief without cross-reading; returns design, rationale, and rejected alternatives."
302
+ "notes": "Independent optional Grok design candidate for every light arena. Use the T3 Grok provider and resolve the model from saved capabilities. Receives the same brief without cross-reading; returns design, rationale, and rejected alternatives."
303
303
  }
304
304
  ]
305
305
  }
@@ -98,6 +98,11 @@ to the user with no reconciliation and no Fable.
98
98
 
99
99
  ## Advised holds
100
100
 
101
+ For an eligible local nonrepo report-only consultation, follow the explicit
102
+ advice workflow in [Local artifacts](local-artifacts.md). Bind its actual parent
103
+ phase and trigger in the brief; this changes no parent prerequisite, the
104
+ never-advised exclusions below, configured seats or escalation conditions.
105
+
101
106
  Advise when a hold reaches the user and the reply picks between two or more
102
107
  paths an agent can then carry out.
103
108
  The criterion governs and the examples are illustrative.
@@ -5,7 +5,9 @@ and bounded follow-ups are defined in [Peer mode](../../axstack-review/SKILL.md#
5
5
 
6
6
  Read the [T3 runtime boundary](t3-runtime.md) before dispatch.
7
7
  Dispatch `axstack-diligence` with async `delegate_task` in the driver worktree,
8
- using a pinned brief and private evidence paths.
8
+ using a pinned brief and private evidence paths. Explicit non-repository
9
+ research/article diligence uses [Local artifacts](local-artifacts.md) with
10
+ local shared isolation and independently reopened sources, without a fake Git repo.
9
11
  It is read-only, never authors or edits, and returns `PASS`, `FINDINGS`, or `UNKNOWN`
10
12
  with locations, observed evidence, and limits. A stale or missing receipt is
11
13
  not a pass. Keep its first pass independent of other reviewers and workers.
@@ -7,6 +7,12 @@ records and forge actions. Helpers validate explicit saved inputs only: no
7
7
  network, clock, dispatch, retry, merge, retained state or aggregate permission grant.
8
8
  Synthetic evidence can pass binding checks; helpers cannot authenticate it.
9
9
 
10
+ For supported local non-repository report-only work, apply
11
+ [Local artifacts](local-artifacts.md): its discriminated scope, native read/list
12
+ null-identity proof and owned folders replace only the repository/checkout terms.
13
+ All native execution authority and independent exact-byte review remain required.
14
+ Engineering/code review and remote routes retain their existing rules.
15
+
10
16
  ## Observe before selecting
11
17
 
12
18
  1. Record installed Axstack and both T3 versions, directed origin/target link,
@@ -70,7 +76,7 @@ read envelope is `{tool,environmentId,args,observedAt,evidence,value}` where arg
70
76
  excludes the forwarding environmentId, and evidence points to the preserved raw
71
77
  native call/result. environment/project/capabilities are read on the selected
72
78
  host; links are read on origin. The capabilities envelope uses `valueText` for
73
- exact raw catalog bytes instead of value. Project repositoryIdentity.canonicalKey
79
+ exact raw catalog bytes instead of value. For repository scope, project repositoryIdentity.canonicalKey
74
80
  must match the requested repositoryId. If project-read identity is null/omitted,
75
81
  `projectList` may carry an ordered array of `t3_project_list` read envelopes on
76
82
  that same environment. Collect from cursor 0 through native nextCursor:null,
@@ -78,7 +84,9 @@ recording actual cursor/limit arguments (native defaults: 0/20, limit at most 10
78
84
  Every page must join without gaps, extra arguments or duplicate project IDs.
79
85
  The selected project's ID and workspaceRoot must equal project-read; every
80
86
  available canonicalKey must equal repositoryId, including when both reads have
81
- identity. Missing identity in both, incomplete pagination and any conflict hold.
87
+ identity. In repository scope, missing identity in both holds; local-artifact
88
+ scope instead requires explicit null in both reads. Incomplete pagination and
89
+ any conflict hold for either scope.
82
90
 
83
91
  For observed T3 0.1.5 native Codex/Claude drivers, omitted provider runtimeModes
84
92
  means no provider restriction: native resolveRuntimeMode and RuntimePolicy
@@ -98,9 +106,11 @@ recommendation, explicit evaluation time and config pin. Compare its target to t
98
106
  independently selected host/environment/project/model/options/runtimeMode. Copy only
99
107
  native supported fields, never inputs or fleetBinding. Call `delegate_task` with
100
108
  that exact target, full-access, a role-labelled title, stable clientRequestId and
101
- scope. Reviewers require native isolation:"worktree" and pinned candidate/base;
102
- no shell-created child checkout. Other nonwriters write only their named private
103
- evidence directory on that host. Preserve requested arguments and native response.
109
+ scope. Code reviewers require native isolation:"worktree" and pinned candidate/base;
110
+ no shell-created child checkout. Explicit local artifact reviewers instead use
111
+ shared isolation and SHA-256 snapshots under [Local artifacts](local-artifacts.md);
112
+ artifact writers use only their owned artifact/evidence folders. Other nonwriters
113
+ write only their named private evidence directory on that host. Preserve requested arguments and native response.
104
114
 
105
115
  Record taskId on the origin plus remoteChild.environmentId/threadId. The native
106
116
  remoteChild schema need not return runId: normalize it from observed task/thread
@@ -117,7 +127,11 @@ recommendation at the same model/permission pins; record the exclusion evidence.
117
127
 
118
128
  Preserve schemaVersion:1, recommendationJSON (exact bytes), configDigest,
119
129
  attempt (key, exact title, clientRequestId, origin environmentId/threadId/taskId,
120
- candidate/base SHAs), requested target/runtimeMode/isolation and native submission.
130
+ candidate/base SHAs for repositories, artifact SHA-256/null base for local artifacts),
131
+ requested target/runtimeMode/isolation and native submission. Artifact ownership
132
+ and byte readbacks follow [Local artifacts](local-artifacts.md#receipts).
133
+ That reference also defines the local-only T3 0.1.5 child-title projection;
134
+ the attempt always retains the full exact requested title.
121
135
  The driver's independent fleetAttempt is the expected run-record identity;
122
136
  never copy it from an arriving receipt to make a comparison pass.
123
137
 
@@ -137,6 +151,9 @@ submission.childRunId; never use lexical ordering of IDs or the original summary
137
151
  Require completed/result_available/no pending children/no unanswered questions or
138
152
  approval. Require exactly one AXSTACK-DONE key/candidate/report marker on both origin's
139
153
  latestTerminalSummary and the destination's final current-run agent message.
154
+ For local artifacts only, T3 0.1.5's deduplicated summary uses the exact
155
+ run/byte-bound exception in [Local artifacts](local-artifacts.md#receipts);
156
+ never rewrite raw native fields or extend it to remote/engineering receipts.
140
157
  A completion marker may be followed by the T3
141
158
  `PR <url>, head <sha>, checks and reviews <state>` trailer. Other trailing text
142
159
  or additional AXSTACK markers keep the receipt held.
@@ -112,6 +112,17 @@ for serial emulator use, desktop safety and declared thermal prechecks.
112
112
  | `pendingAssignments` | Array of `{clientRequestId, environmentId, taskId?}` |
113
113
  | `exclusions` | `{hosts: {hostId: reason}, routes: {routeId: reason}}`; nonempty reason strings |
114
114
 
115
+ `request.scope` may be `{kind:"repository"}` with a nonempty repositoryId;
116
+ legacy omitted scope retains that repository requirement. The explicit
117
+ `{kind:"local-artifact", ...}` alternative requires repositoryId:null and the
118
+ workflow, role, native project and ownership fields in [Local artifacts](local-artifacts.md).
119
+ The local-artifact matrix separates direct and inherited roles for research, explain,
120
+ publish, brainstorm, align, improve, audit and conditional advice.
121
+ Brainstorm candidate/judge roles never leak into source/article authority.
122
+ Applicable rung/round duties remain report-only procedural checks, not route authority.
123
+ Artifact destination project also carries workspaceRoot; only the bound local
124
+ environment/project/workspace is eligible. Null alone never selects a route.
125
+
115
126
  `role` is `reader` (all nonwriter roles) or `author`. `requiredCapabilities`
116
127
  is an array of strings. An authentication requirement names the actual session
117
128
  capability; only the host proving that session is eligible. No credential
@@ -311,7 +322,10 @@ unavailable destination model/options, or role/settings/config disagreement.
311
322
  It never reinterprets a requested model pin as a different available model.
312
323
 
313
324
  Task plans add `environmentId`/`projectId` to `target`; launch plans add them
314
- beside `modelSelection`. All requested options survive as T3 option entries.
325
+ beside `modelSelection`. All requested options survive as T3 option entries. Explicit local-artifact
326
+ plans require nativeDestination, the exact scope role and task kind; they emit
327
+ isolation:"shared" and artifactScope evidence. The latter is never a native
328
+ argument. Artifact readback compares scope and shared isolation as well.
315
329
  Both include `fleetBinding: {configDigest, destinationSnapshotId,
316
330
  destinationCapabilitiesDigest}`. This is preserved evidence, not a T3 launch
317
331
  parameter. Copy only tool-supported launch fields. Coordinator author routes
@@ -29,6 +29,14 @@ Prefer parallel independent bounded work; no redundant workers. Fanout is depend
29
29
  capacity-driven within host/spending limits. [PR shape](pr-shape.md) covers
30
30
  theme/size; queue dependencies under [PR chains](pr-chain.md).
31
31
 
32
+ For supported non-repository report-only workflows, use
33
+ [Local artifacts](local-artifacts.md) for owned shared delegates and SHA-256
34
+ receipts. The reviewer checkout row above applies to code candidates; article
35
+ review retains independent source/fact and exact-byte UI/design checks.
36
+ Brainstorm candidates and applicable judges retain independent report-only
37
+ arena duties and conditional rounds; this grants no engineering authority.
38
+ Null identity does not waive engineering isolation or authorize remote artifacts.
39
+
32
40
  ## Ownership
33
41
 
34
42
  The PR owner is accountable for candidate, fixes, evidence, monitoring.
@@ -176,6 +184,10 @@ Build no custom scheduler, state engine or legacy fallback. See
176
184
  Audit measurement is enabled by default for every substantive run; dispatch
177
185
  follows [Close-out](#close-out) or a material-deviation/repeated-repair
178
186
  checkpoint. An `axstack-audit` run is excluded; it launches no children.
187
+ For supported nonrepo report runs, keep the originating workflow and inherited
188
+ auditor roles in [Local artifacts](local-artifacts.md); standalone audit uses
189
+ workflow audit and never audits itself. Conditional advice uses that matrix
190
+ and the standing advised-hold/escalation rules, without waiving parent prerequisites.
179
191
  Load [axstack-audit](../../axstack-audit/SKILL.md). Accepted proposals
180
192
  require a regression scenario and unchanged holdout checks; they change
181
193
  nothing without tested independent review.
@@ -0,0 +1,202 @@
1
+ # Local non-repository artifacts
2
+
3
+ The report-only modes in the matrix below may use an explicitly bound
4
+ non-repository artifact scope. Null repository identity alone never authorizes
5
+ a route.
6
+ Engineering authors and code reviewers still require a repository and native
7
+ Git worktree isolation. Remote artifacts and remote author/coordinator work
8
+ remain outside this scope.
9
+
10
+ ## Scope and ownership
11
+
12
+ Use `request.scope` below with `repositoryId:null` and `role:reader`.
13
+ Here reader means no product-code authority. Writers may write only their owned
14
+ artifacts or reports under the selected phase contract.
15
+ `task` remains a load preference, not role authority.
16
+ The scope is evidence for the helpers and brief, never a native T3 argument.
17
+
18
+ ```json
19
+ {
20
+ "kind": "local-artifact",
21
+ "workflow": "explain",
22
+ "roleId": "axstack-explainer",
23
+ "environmentId": "<current environment>",
24
+ "projectId": "<actual parent project>",
25
+ "workspaceRoot": "/scratch",
26
+ "artifactRoot": "/scratch/run/artifacts/author-a1",
27
+ "evidenceRoot": "/scratch/run/evidence/author-a1",
28
+ "reservedRoots": ["/scratch/run/artifacts/other-attempt"]
29
+ }
30
+ ```
31
+
32
+ The research, explain and publish workflows permit the configured research
33
+ requirements/code/code-sol/web/web-sol/X and explore-execution/
34
+ explore-execution-sol source roles plus diligence. Explain and Publish also
35
+ permit explainer, explainer-review and the configured UI verifier roles.
36
+ Use their full `axstack-` role IDs; this list does not make an absent seat
37
+ available or change provider/model/effort/options/runtime authority.
38
+ The selected role ID must equal scope.roleId in dispatch-plan.
39
+ No engineering author, code reviewer, owner or arbitrary role can use this scope.
40
+
41
+ Brainstorm permits only candidate seats Astra (`axstack-advisor-astra`),
42
+ Opus (`axstack-advisor-opus`), Grok (`axstack-arena-candidate-grok`) and judge
43
+ seats Opus (`axstack-arena-judge-opus`), Fable (`axstack-escalation-fable`), Astra
44
+ (`axstack-arena-judge-astra`). All outputs are report-only; never grant
45
+ implementation or spec approval. These seats are excluded from Research,
46
+ Explain and Publish artifact scopes; source/article roles are excluded from
47
+ Brainstorm. These are direct roles; inherited audit is listed below.
48
+ This is arena authority, never arbitrary adviser authority.
49
+
50
+ Candidates must remain independent with the same bounded brief and no
51
+ cross-reading; judges never author candidates or cross-read other judges.
52
+ Rung 1 has no judge round; Rung 2 uses round 1, with round 2 only on the
53
+ existing disagreement or caller's user-rejection trigger in
54
+ [the arena procedure](../../axstack-brainstorm/references/arena.md).
55
+ The driver verifies rung, round, independence and configured seat availability
56
+ before dispatch; helpers validate role scope, not those procedural facts.
57
+
58
+ Use the selected preset's exact provider/model/effort/full-access bindings.
59
+ Configured optional Grok follows the arena's fenced absence rule; an uncertain
60
+ dispatch requires reconciliation. Fable is a required round-2 judge when that
61
+ round applies, not an optional candidate. A missing required model or an
62
+ intentional null-model absence holds the applicable round without substitution.
63
+ An allowlisted role never makes an unavailable seat executable.
64
+
65
+ ## Workflow and inherited-role matrix
66
+
67
+ Substantive parent runs in each supported workflow retain `axstack-auditor` and
68
+ `axstack-auditor-sol` under the lifecycle hook. Their passes must remain
69
+ independent on the same bounded evidence, with configured optional-seat and
70
+ mixed-provider rules unchanged. Audit never audits itself; its auditor workers
71
+ launch no children. The unlaunchable-base UNKNOWN archive exception remains
72
+ a degraded receipt, not evidence of a completed audit.
73
+
74
+ | Workflow | Direct roles | Inherited audit | Boundary |
75
+ | --- | --- | --- | --- |
76
+ | research | Source roles listed above | Both auditors | Cited, bounded research; no engineering |
77
+ | explain, publish | Source and article roles listed above | Both auditors | Exact-byte review; publication still needs authority |
78
+ | brainstorm | Six candidate/judge seats listed above | Both auditors | Independent report-only arena and applicable rounds |
79
+ | align | `axstack-advisor-astra`, `axstack-advisor-opus` | Both auditors | Pre-repository scope advice; stop before execution |
80
+ | improve | `axstack-research-code`, `axstack-research-code-sol`, `axstack-ui-verifier`, `axstack-ui-verifier-sonnet` | Both auditors | Named nonversioned code/UI discovery only; second UI seat only under its dual-run trigger |
81
+ | audit | `axstack-auditor`, `axstack-auditor-sol` | None; terminal audit | Standalone audit of explicit nonrepo evidence; only assigned `audit.md` is writable |
82
+ | advice | `axstack-advisor-astra`, `axstack-advisor-opus`, `axstack-escalation-fable` | None; audit retains the supported parent's workflow | Only eligible existing shared advice; Fable retains its trigger |
83
+
84
+ The advice workflow permits only existing advised-hold, high-stakes or bounded
85
+ escalation consultations under [Standing contracts](contracts.md). It never
86
+ waives the parent phase's repository, store or tracker prerequisites. Record
87
+ the actual parent phase, qualifying trigger, evidence and question in the brief.
88
+ Ordinary advised holds use Astra/Opus; high-stakes use Astra/Fable; other Fable
89
+ uses require the existing bounded escalation trigger and a fresh session.
90
+ Never relabel arbitrary work as advice. Required seats and missing models hold
91
+ without substitution. The helper checks the role matrix; the driver must verify
92
+ these conditional duties, as with arena rounds.
93
+
94
+ Nested phase calls use their own explicit scope: Align research uses research,
95
+ unresolved design uses brainstorm, and Improve visuals use explain. This is not
96
+ a workflow alias for the caller or a waiver of its prerequisites.
97
+
98
+ Improve already accepts nonversioned files, screenshots and exported snippets.
99
+ Its previous artifact routing was ambiguous, not a proven runtime failure.
100
+ The improve mapping now covers that existing report-only discovery: copy owned
101
+ source snapshots, bind stable source identity and SHA-256, and name missing
102
+ history. UI discovery retains exact build/URL, source identity, real Playwright
103
+ capture and applicable dual-run requirements. A supplied screenshot alone is
104
+ not proof of a live render. Repository readiness, whole-repo Scout, executable
105
+ probes and implementation do not acquire artifact authority.
106
+
107
+ | Skill or mode | Nonrepo boundary |
108
+ | --- | --- |
109
+ | Anatomy | Uses Explain's workflow and exact-byte review; no new workflow |
110
+ | Perf | Router only; Improve discovery may use improve, Debug/Implement still require repository isolation |
111
+ | Spec | Unsupported as a standalone artifact workflow; chosen authoritative store, repository counterpart and approval remain required |
112
+ | Tickets | Unsupported; approved engineering scope, repository/store and tracker access remain required |
113
+ | Scout | Unsupported; whole-repository pinned-tree evidence is required |
114
+ | Debug, Implement | Unsupported; native repository/worktree probes and writers remain required |
115
+ | Review | Article/source review uses explain/publish; PR/code/codebase review retains repository and checkout requirements |
116
+ | Verify | Unsupported; repository verification-skill authoring routes through Implement |
117
+ | Watch | Unsupported; PR/repository ownership and forge rules remain required |
118
+ | Correct, Cleanup, VOA | Inline only; no worker workflow added; existing identity, ownership and read-only/status limits remain |
119
+
120
+ This matrix plus the supported rows covers the twenty skills inspected for this
121
+ repair. It describes contract/validator support, not completed native execution.
122
+ No live provider, browser, tracker, publication or installed-host support follows
123
+ from static checks or fixture receipts. Missing prerequisites remain unresolved;
124
+ record the exact gap rather than fabricate a repository, alias or approval.
125
+
126
+ The driver binds the native parent project and its real workspaceRoot. Require
127
+ explicit null repositoryIdentity in both project-read and complete project-list
128
+ reads; omitted, conflicting or incomplete observations hold. Native environment,
129
+ project, catalog, provider restrictions, options, runtime and access checks still
130
+ apply. Use only a local route in that environment/project/workspace. Do not
131
+ fabricate a repository ID, initialize Git or attach an unrelated repository.
132
+
133
+ Give every attempt separate owned artifact and evidence directories, strict
134
+ children of the observed workspaceRoot. They must be canonical absolute paths,
135
+ with no traversal, shared-root writes or ancestor/equal overlap. `reservedRoots`
136
+ is the driver's current list of other attempts' owned artifact/evidence roots;
137
+ include pending and retained attempts, never guess an empty inventory.
138
+ The helper checks lexical paths and overlaps; the driver must independently
139
+ verify real paths, no symlink escapes, ownership and exclusive writers on disk.
140
+ Unknown ownership holds. This is supplied evidence, not an authenticated lock.
141
+
142
+ ## Native dispatch and review
143
+
144
+ Use async native `delegate_task` with `isolation:"shared"`, exact local target,
145
+ role-labelled title and stable clientRequestId. Native local projectId must equal
146
+ the parent's project; moving to another local project is unsupported. Preserve
147
+ requested arguments and native effective settings separately. Dispatch-plan
148
+ requires nativeDestination and `--kind task`; it returns artifactScope as evidence
149
+ and shared isolation. Copy only supported native arguments into delegate_task.
150
+ No top-level launch, shell checkout, live policy edit or per-run bypass is needed.
151
+
152
+ Research branches keep independent first passes and cited-source reopening.
153
+ Diligence reopens answer-changing claims; it never becomes the article author.
154
+ The explainer remains sole source writer. Reviewers/verifiers get their own
155
+ byte-identical snapshot in their owned artifact directory; their reports/probes
156
+ stay in their separate evidence directory and never edit the author's original.
157
+ Independent explainer review checks the exact SHA-256 bytes. Before public
158
+ publication require Playwright layout/interaction evidence and independent
159
+ source/fact and design review of those same bytes under Explain/Publish rules.
160
+ Changed bytes invalidate affected reviews and renders; unknown proof holds.
161
+ Shared filesystem access does not permit cross-reading independent first passes.
162
+ Publication remains the explicitly authorized driver's action.
163
+
164
+ ## Receipts
165
+
166
+ Retain the normal native task/thread/run, pending-question and settings checks.
167
+ For audits, the driver supplies an owned read-only input snapshot or evidence
168
+ manifest under artifactRoot. Bind its SHA-256 as the candidate; the auditor
169
+ writes only evidenceRoot/audit.md and marker report points there. Missing Git
170
+ history is a named limitation, never a fabricated revision. Paired auditors get
171
+ independent owned snapshots and never cross-read reports.
172
+
173
+ For artifact receipts, `attempt.candidate` and marker `head` are the exact
174
+ 64-hex artifact SHA-256; `attempt.base` is null. They are not Git revisions.
175
+ Bind `artifactScope` to the requested scope and report to evidenceRoot.
176
+ Supply `artifact:{path,sha256,readback:{path,sha256,evidence}}` for the independently
177
+ hashed owned snapshot. Requested isolation must be shared. Native child worktreePath may be null;
178
+ on T3 0.1.5 it may also inherit the parent's non-Git scratch path. For the latter,
179
+ include `parent` as a saved `t3_thread_read` observation (tool, environmentId,
180
+ args.threadId, observedAt, evidence, value.thread). Bind it to the attempt's
181
+ origin thread, selected project, child parentThreadId/subagent relationship and
182
+ identical canonical path inside workspaceRoot. Verify the actual filesystem;
183
+ this is shared access, not a Git checkout or OS isolation. Checkout metadata
184
+ remains forbidden. Unknown or different parent/path evidence holds.
185
+
186
+ T3 0.1.5 deduplicates local task results: latestTerminalSummary can be null when
187
+ summary contains the same result. For local artifact receipts only, use that
188
+ summary when childRunId and latestTerminalRunId both equal the current completed
189
+ run and its bytes equal the destination final message. An explicit conflicting
190
+ terminal summary, stale run, other version or remote result does not use this
191
+ fallback. Preserve the raw native fields; do not rewrite them. Never synthesize an effective field from requested settings.
192
+ The driver checks actual bytes and readbacks; helpers validate saved data only.
193
+ For local artifact receipts on observed T3 0.1.5 only, a trimmed requested title
194
+ longer than 72 UTF-16 code units may appear on the child as its first 69 units
195
+ plus three ASCII periods (`...`). Compare that exact native projection, never
196
+ an arbitrary prefix or Unicode ellipsis. Keep the full requested title in the
197
+ independent attempt; do not rewrite either native or expected evidence. Task,
198
+ child, run, parent, marker and artifact bindings still apply: clipped titles are
199
+ not unique identity. Other versions, remote and engineering receipts retain
200
+ exact title equality. Saved replay proves compatibility, not a fresh dispatch.
201
+
202
+ Keep artifact receipts separate from Git candidate publication/PR/merge receipts.
@@ -6,6 +6,11 @@ native destination. Remote reviewers require T3 worktree isolation; no shell chi
6
6
  checkout. Host names confer no role or permission. Remote authors/coordinator stay
7
7
  disabled; local isolated authors remain supported even overloaded.
8
8
 
9
+ Supported non-repository report-only workflows use the bounded role matrix
10
+ and local shared-artifact isolation in [Local artifacts](local-artifacts.md).
11
+ This changes no configured seat, source independence or exact-byte review duty.
12
+ Engineering authors and code reviewers cannot acquire this artifact authority.
13
+
9
14
  - Chat drives (no role ID); `axstack-owner` owns one PR and
10
15
  `axstack-author` its sole writer.
11
16
  For own PRs, automatic merge is the default under the
@@ -204,6 +204,13 @@ a candidate follows [UI verification](ui-verification.md).
204
204
 
205
205
  The driver must be the sole run-record writer and enforce one writer per
206
206
  candidate; it never writes tracked candidate source or tests or repairs an author's source.
207
+ For supported non-repository report-only workflows only,
208
+ [Local artifacts](local-artifacts.md) supplies the artifact branch of this table:
209
+ Only the matrix's direct and inherited roles use local shared native delegates
210
+ with separate owned folders and exact SHA-256 snapshots.
211
+ Its role allowlist excludes engineering authors and code reviewers; their native
212
+ Git worktree rules above remain mandatory. Null repository alone grants nothing.
213
+
207
214
  The driver may write planning artifacts (spec, ticket map) in its own worktree when the selected store is repository Markdown.
208
215
  Repairs return to that author. Missing or idle sessions grant no ownership transfer.
209
216
  The current chat/driver has no role row in any preset.
@@ -24,8 +24,11 @@ All other browser checks outside the two named exceptions remain delegated to co
24
24
 
25
25
  Read the [T3 runtime boundary](t3-runtime.md) before dispatch; for candidate
26
26
  checks use its driver-made disposable detached checkout at the pinned candidate SHA.
27
+ For explicit non-repository article or Improve discovery checks, use the local shared delegate and
28
+ owned SHA-256 snapshot in [Local artifacts](local-artifacts.md); no Git candidate
29
+ is fabricated. Engineering candidate checks retain the checkout requirement.
27
30
  Use the configured verifier browser and honor the user browser-tool policy.
28
- Candidate browser and visual checks must run in a delegated UI verifier role in its own detached checkout; outputs go to its private evidence folder, never the driver worktree.
31
+ Engineering candidate browser and visual checks must run in a delegated UI verifier role in its own detached checkout; outputs go to its private evidence folder, never the driver worktree.
29
32
 
30
33
  For every interactive page, require a real-browser `axstack-ui-verifier` interaction pass.
31
34
  Give the evidence path and SHA-256 of the exact bytes in the verifier brief.
@@ -1,6 +1,7 @@
1
1
  import { readFileSync, writeFileSync } from 'node:fs';
2
2
  import { inspectFleetReceipt } from './fleet-receipt.js';
3
3
  import { bindFleet } from './fleet-dispatch.js';
4
+ import { canonical } from './fleet-config.js';
4
5
 
5
6
  const fleetFlags = ['--recommendation', '--fleet-input', '--now', '--config-digest'];
6
7
  const flags = ['--role', '--roles', '--capabilities', '--kind', '--verify', '--out', ...fleetFlags];
@@ -34,6 +35,9 @@ by its destination facts. It is never the origin catalog by default.
34
35
  Fleet verification requires environmentId/projectId and fleetBinding alongside
35
36
  the effective T3 configuration. C3 collects that host-qualified evidence envelope.
36
37
  Optional input.nativeDestination validates saved native forwarded reads.
38
+ Explicit local-artifact scope requires those reads and kind task; emits isolation:"shared".
39
+ artifactScope is preserved evidence only, never a native tool argument.
40
+ Artifact verification also requires artifactScope and independently checked isolation.
37
41
  Optional --verify fleetAttempt/fleetReceipt validates host-qualified terminal facts;
38
42
  --out retains per-term receipt evidence. Synthetic bindings cannot authenticate reads.
39
43
  Coordinator routes remain unsupported here. A plan grants no launch authority.
@@ -98,6 +102,11 @@ function verify(configuration, provider, model, options, fleet) {
98
102
  if (fleet) {
99
103
  for (const [field, expected] of Object.entries(fleet.destination)) compare(field, expected, configuration?.[field]);
100
104
  for (const [field, expected] of Object.entries(fleet.fleetBinding)) compare(field, expected, configuration?.fleetBinding?.[field]);
105
+ if (fleet.artifactScope) {
106
+ compare('artifactScope', fleet.artifactScope, configuration?.artifactScope,
107
+ canonical(fleet.artifactScope) === canonical(configuration?.artifactScope));
108
+ compare('isolation', 'shared', configuration?.isolation);
109
+ }
101
110
  }
102
111
  let receiptTerms;
103
112
  if (fleet && configuration?.fleetReceipt !== undefined) {
@@ -175,7 +184,7 @@ function plan(argv, io) {
175
184
  const recommendation = JSON.parse(recommendationJSON);
176
185
  fleet = bindFleet(readJSON(args['--fleet-input']), recommendation,
177
186
  args['--config-digest'], Number(args['--now']), readFileSync(args['--capabilities'], 'utf8'),
178
- resolution, role.id === 'axstack-author');
187
+ resolution, role.id === 'axstack-author', role.id, args['--kind']);
179
188
  fleet.recommendation = recommendation;
180
189
  fleet.recommendationJSON = recommendationJSON;
181
190
  fleet.now = Number(args['--now']);
@@ -189,6 +198,7 @@ function plan(argv, io) {
189
198
  const selection = { [args['--kind'] === 'launch' ? 'instanceId' : 'providerInstanceId']: providerInstanceId,
190
199
  model, options, ...(args['--kind'] === 'task' ? fleet?.destination : {}) };
191
200
  emit({ [args['--kind'] === 'launch' ? 'modelSelection' : 'target']: selection, runtimeMode: 'full-access',
201
+ ...(fleet?.artifactScope ? { artifactScope: fleet.artifactScope, isolation: fleet.isolation } : {}),
192
202
  ...(fleet ? { fleetBinding: fleet.fleetBinding, ...(args['--kind'] === 'launch' ? fleet.destination : {}) } : {}),
193
203
  ...(args['--kind'] === 'task' && role.id === 'axstack-author' ? { isolation: 'worktree' } : {}) });
194
204
  return 0;
@@ -1,3 +1,5 @@
1
+ import { validScope } from './fleet-scope.js';
2
+
1
3
  // Configuration is reviewed data. This module does not read account-local files.
2
4
  export function fail(code) { throw new Error(code); }
3
5
  export const record = (value) => value !== null && typeof value === 'object' && !Array.isArray(value);
@@ -58,7 +60,7 @@ export function validateInput(input, now) {
58
60
  const r = input.request;
59
61
  if (!record(r) || !text(r.task) || !['reader', 'author'].includes(r.role)
60
62
  || !Array.isArray(r.requiredCapabilities) || !r.requiredCapabilities.every(text)
61
- || !text(r.repositoryId) || !text(r.providerInstanceId) || !text(r.model)
63
+ || !validScope(r) || !text(r.providerInstanceId) || !text(r.model)
62
64
  || !record(r.options) || !text(r.runtimeMode)) fail('request-schema');
63
65
  for (const key of ['destinations', 'routeFacts', 'telemetry', 'assignments', 'pendingAssignments']) {
64
66
  if (!Array.isArray(input[key])) fail(`${key}-schema`);
@@ -1,4 +1,5 @@
1
1
  // Validate explicit saved native reads. These bindings do not authenticate input.
2
+ import { isArtifact } from './fleet-scope.js';
2
3
  import { canonical, text, time } from './fleet-config.js';
3
4
 
4
5
  export function inspectDestination(observation, recommendation, capabilitiesText, now) {
@@ -51,9 +52,17 @@ export function inspectDestination(observation, recommendation, capabilitiesText
51
52
  }
52
53
  // ProjectService.listPage resolves the cold identity cache; getById need not.
53
54
  const identities = [project?.repositoryIdentity, listed?.repositoryIdentity].filter((v) => v != null);
54
- term('destination-repository', identities.length > 0
55
- && identities.every((v) => v.canonicalKey === s.repositoryId), identities,
56
- identities.length === 0);
55
+ if (isArtifact(recommendation.request)) {
56
+ const scope = recommendation.request.scope;
57
+ term('destination-artifact-project', project?.repositoryIdentity === null
58
+ && listed?.repositoryIdentity === null && project?.workspaceRoot === scope.workspaceRoot
59
+ && s.environmentId === scope.environmentId && s.projectId === scope.projectId,
60
+ { project, listed });
61
+ } else {
62
+ term('destination-repository', identities.length > 0
63
+ && identities.every((v) => v.canonicalKey === s.repositoryId), identities,
64
+ identities.length === 0);
65
+ }
57
66
  term('destination-catalog', o.capabilities?.valueText === capabilitiesText, o.capabilities?.valueText);
58
67
  const catalog = JSON.parse(capabilitiesText);
59
68
  const providers = catalog.providers?.filter((v) => v.providerInstanceId === recommendation.request.providerInstanceId);
@@ -1,15 +1,22 @@
1
1
  // Bind supplied placement facts to a plan. No reads, dispatch or authority grant.
2
+ import { isArtifact } from './fleet-scope.js';
2
3
  import { inspectDestination } from './fleet-destination.js';
3
4
  import { canonical, record, text } from './fleet-config.js';
4
5
  import { recommend } from './fleet-route.js';
5
6
 
6
- export function bindFleet(input, saved, configDigest, now, capabilitiesText, resolved, author) {
7
+ export function bindFleet(input, saved, configDigest, now, capabilitiesText, resolved, author, roleId, kind) {
7
8
  const hold = (code) => { throw Object.assign(new Error(code), { exitCode: 2 }); };
8
9
  if (saved?.schemaVersion !== 1) hold('schema-version: recommendation');
9
10
  if (configDigest !== input?.configDigest) hold('config-digest-mismatch');
10
11
  let current;
11
12
  try { current = recommend(input, now); } catch (error) { hold(error.message); }
12
13
  if (canonical(saved) !== canonical(current)) hold('recommendation-mismatch');
14
+ const artifact = isArtifact(current.request);
15
+ if (artifact) {
16
+ if (roleId !== current.request.scope.roleId) hold('artifact-role-mismatch');
17
+ if (kind !== 'task') hold('artifact-task-only');
18
+ if (input.nativeDestination === undefined) hold('artifact-native-destination-required');
19
+ }
13
20
  const selected = current.selected;
14
21
  if (!selected) hold('no-executable-route');
15
22
  // Coordinator enablement/lifecycle is a later capability, never inferred here.
@@ -40,7 +47,8 @@ export function bindFleet(input, saved, configDigest, now, capabilitiesText, res
40
47
  return { id, value };
41
48
  });
42
49
  return {
43
- options, destination: { environmentId: selected.environmentId, projectId: selected.projectId },
50
+ options, ...(artifact ? { artifactScope: current.request.scope, isolation: 'shared' } : {}),
51
+ destination: { environmentId: selected.environmentId, projectId: selected.projectId },
44
52
  fleetBinding: { configDigest, destinationSnapshotId: selected.destinationSnapshotId,
45
53
  destinationCapabilitiesDigest: digest },
46
54
  };
@@ -1,3 +1,4 @@
1
+ import { isArtifact } from './fleet-scope.js';
1
2
  import { nativeAssignments } from './fleet-inventory.js';
2
3
  import { canonical, evidence, fail, record, text, time } from './fleet-config.js';
3
4
 
@@ -116,6 +117,8 @@ export function routeReasons(route, host, destination, facts, input, now) {
116
117
  const add = (code) => { if (!reasons.includes(code)) reasons.push(code); };
117
118
  const remote = route.environmentId !== input.origin.environmentId;
118
119
  const r = input.request;
120
+ const artifact = isArtifact(r);
121
+ if (artifact && (remote || route.kind !== 'local' || r.scope.environmentId !== input.origin.environmentId)) add('artifact-local-only');
119
122
  if (Object.hasOwn(input.exclusions.hosts, host.id)) add('excluded-host');
120
123
  if (Object.hasOwn(input.exclusions.routes, route.id)) add('excluded-route');
121
124
  if (!route.enabled) add('route-disabled');
@@ -134,7 +137,9 @@ export function routeReasons(route, host, destination, facts, input, now) {
134
137
  || !evidence(destination.evidence, host.environmentId, now)) add('evidence-unproven');
135
138
  if (!text(destination.snapshotId) || facts?.destinationSnapshotId !== destination.snapshotId) add('target-snapshot-mismatch');
136
139
  if (!record(destination.project) || !text(destination.project.id)) add('project-missing');
137
- else if (destination.project.repositoryId !== r.repositoryId) add('project-mismatch');
140
+ else if (destination.project.repositoryId !== r.repositoryId
141
+ || (artifact && (destination.project.id !== r.scope.projectId
142
+ || destination.project.workspaceRoot !== r.scope.workspaceRoot))) add('project-mismatch');
138
143
  const e = destination.execution;
139
144
  if (!record(e) || e.available !== true) add('execution-unproven');
140
145
  else if (e.providerInstanceId !== r.providerInstanceId || e.model !== r.model
@@ -1,5 +1,6 @@
1
1
  // Saved evidence validator. A pass binds supplied facts; it cannot authenticate them.
2
2
  import { canonical, record, text, time } from './fleet-config.js';
3
+ import { inside, isArtifact } from './fleet-scope.js';
3
4
  import { inspectNativeFamily } from './fleet-native-receipt.js';
4
5
 
5
6
  function options(value) {
@@ -21,6 +22,7 @@ export function inspectFleetReceipt(receipt, expected) {
21
22
  const a = expected.attempt;
22
23
  const s = expected.recommendation.selected;
23
24
  const request = expected.recommendation.request;
25
+ const artifact = isArtifact(request);
24
26
  term('receipt-origin', text(a?.origin?.threadId) && a?.origin?.environmentId === expected.recommendation.originEnvironmentId
25
27
  && same(r.attempt?.origin, a?.origin), r.attempt?.origin,
26
28
  !text(a?.origin?.threadId) || r.attempt?.origin == null);
@@ -39,7 +41,12 @@ export function inspectFleetReceipt(receipt, expected) {
39
41
  && r.thread?.environmentId === s.environmentId && thread?.threadId === child(status),
40
42
  { submitted: submitted?.remoteChild ?? submitted?.childThreadId,
41
43
  status: status?.remoteChild ?? status?.childThreadId, thread: r.thread?.environmentId });
42
- term('receipt-title', text(a?.title) && thread?.title === a.title, thread?.title);
44
+ // T3 0.1.5 persists subagentThreadTitle's exact projection on local children.
45
+ // Full attempt/task/run/marker identity remains independently mandatory.
46
+ const projectedTitle = artifact && !remote && s.versions?.t3 === '0.1.5'
47
+ && text(a?.title) && a.title === a.title.trim() && a.title.length > 72
48
+ && thread?.title === a.title.slice(0, 69) + '...';
49
+ term('receipt-title', text(a?.title) && (thread?.title === a.title || projectedTitle), thread?.title);
43
50
  term('receipt-project', thread?.projectId === s.projectId, thread?.projectId);
44
51
  for (const [name, tool, environmentId, args] of [
45
52
  ['status', 'task_status', a?.origin?.environmentId, { taskId: a?.origin?.taskId }],
@@ -127,16 +134,46 @@ export function inspectFleetReceipt(receipt, expected) {
127
134
  };
128
135
  const items = r.thread?.value?.items;
129
136
  const final = Array.isArray(items) ? items.filter((v) => v.runId === current && v.createdBy === 'agent').at(-1) : null;
130
- term('receipt-marker', /^[a-f0-9]{40}$/.test(a?.candidate ?? '')
131
- && finalMarker(status?.latestTerminalSummary) === marker && finalMarker(final?.text) === marker
132
- && (!initial || status?.latestTerminalSummary === final?.text),
133
- { origin: status?.latestTerminalSummary, destination: final?.text });
137
+ // T3 0.1.5 suppresses latestTerminalSummary when it equals summary.
138
+ // Only the same local result run may use that deduplicated value.
139
+ const localSummary = artifact && !remote && s.versions?.t3 === '0.1.5'
140
+ && status?.latestTerminalSummary === null && text(current)
141
+ && status?.childRunId === current && status?.latestTerminalRunId === current
142
+ && status?.status === 'completed' && status?.summary === final?.text;
143
+ const resultSummary = localSummary ? status.summary : status?.latestTerminalSummary;
144
+ term('receipt-marker', (artifact ? /^[a-f0-9]{64}$/ : /^[a-f0-9]{40}$/).test(a?.candidate ?? '')
145
+ && finalMarker(resultSummary) === marker && finalMarker(final?.text) === marker
146
+ && (!initial || resultSummary === final?.text),
147
+ { origin: resultSummary, destination: final?.text });
134
148
  term('receipt-host-path', r.evidence?.hostId === s.hostId && r.evidence?.environmentId === s.environmentId
135
- && absolute(r.evidence?.path) && finalMarker(status?.latestTerminalSummary)?.endsWith(` report=${r.evidence.path}`), r.evidence);
136
- if (a?.title?.startsWith('Reviewer: ')) {
149
+ && absolute(r.evidence?.path) && finalMarker(resultSummary)?.endsWith(` report=${r.evidence.path}`), r.evidence);
150
+ if (artifact) {
151
+ const scope = request.scope;
152
+ const bytes = r.artifact;
153
+ term('receipt-artifact-scope', a?.base === null && same(r.artifactScope, scope)
154
+ && inside(r.evidence?.path, scope.evidenceRoot), r.artifactScope);
155
+ term('receipt-artifact-bytes', bytes?.sha256 === a?.candidate && inside(bytes?.path, scope.artifactRoot)
156
+ && bytes?.readback?.path === bytes.path && bytes?.readback?.sha256 === bytes.sha256
157
+ && text(bytes?.readback?.evidence), bytes);
158
+ // Shared native children can inherit a parent's non-Git scratch directory.
159
+ // Bind that value to an actual parent read; a path alone proves nothing.
160
+ const parent = r.parent;
161
+ const parentThread = parent?.value?.thread;
162
+ const inherited = !remote && s.versions?.t3 === '0.1.5'
163
+ && parent?.tool === 't3_thread_read' && parent.environmentId === a?.origin?.environmentId
164
+ && same(parent.args, { threadId: a?.origin?.threadId })
165
+ && time(parent.observedAt) && parent.observedAt <= expected.now && text(parent.evidence)
166
+ && parentThread?.threadId === a?.origin?.threadId && parentThread?.projectId === s.projectId
167
+ && thread?.parentThreadId === parentThread?.threadId && thread?.relationshipToParent === 'subagent'
168
+ && absolute(parentThread?.worktreePath) && inside(parentThread.worktreePath, scope.workspaceRoot)
169
+ && thread?.worktreePath === parentThread.worktreePath;
170
+ term('receipt-isolation', r.requested?.isolation === 'shared'
171
+ && (thread?.worktreePath === null || inherited) && r.checkout == null,
172
+ { isolation: r.requested?.isolation, worktreePath: thread?.worktreePath, parent });
173
+ } else if (a?.title?.startsWith('Reviewer: ')) {
137
174
  term('receipt-isolation', r.requested?.isolation === 'worktree', r.requested?.isolation);
138
175
  }
139
- if (a?.title?.startsWith('Reviewer: ') || r.checkout != null || thread?.worktreePath != null || r.requested?.isolation === 'worktree') {
176
+ if (!artifact && (a?.title?.startsWith('Reviewer: ') || r.checkout != null || thread?.worktreePath != null || r.requested?.isolation === 'worktree')) {
140
177
  const c = r.checkout;
141
178
  term('receipt-checkout', c?.hostId === s.hostId && c?.environmentId === s.environmentId
142
179
  && absolute(c?.path) && c.path === thread?.worktreePath
@@ -0,0 +1,37 @@
1
+ // Explicit artifact authority, separate from repository engineering authority.
2
+ const sourceRoles = ['axstack-research-requirements', 'axstack-research-code', 'axstack-research-code-sol',
3
+ 'axstack-explore-execution', 'axstack-explore-execution-sol',
4
+ 'axstack-research-web', 'axstack-research-web-sol', 'axstack-research-x', 'axstack-diligence'];
5
+ const articleRoles = ['axstack-explainer', 'axstack-explainer-review', 'axstack-ui-verifier', 'axstack-ui-verifier-sonnet'];
6
+ const brainstormRoles = ['axstack-advisor-astra', 'axstack-advisor-opus', 'axstack-arena-candidate-grok',
7
+ 'axstack-arena-judge-opus', 'axstack-escalation-fable', 'axstack-arena-judge-astra'];
8
+ const auditRoles = ['axstack-auditor', 'axstack-auditor-sol'];
9
+ const workflowRoles = {
10
+ research: [...sourceRoles, ...auditRoles],
11
+ explain: [...sourceRoles, ...articleRoles, ...auditRoles],
12
+ publish: [...sourceRoles, ...articleRoles, ...auditRoles],
13
+ brainstorm: [...brainstormRoles, ...auditRoles],
14
+ align: ['axstack-advisor-astra', 'axstack-advisor-opus', ...auditRoles],
15
+ improve: ['axstack-research-code', 'axstack-research-code-sol', 'axstack-ui-verifier',
16
+ 'axstack-ui-verifier-sonnet', ...auditRoles],
17
+ audit: auditRoles,
18
+ advice: ['axstack-advisor-astra', 'axstack-advisor-opus', 'axstack-escalation-fable'],
19
+ };
20
+ export const isArtifact = (request) => request?.scope?.kind === 'local-artifact';
21
+ const path = (value) => typeof value === 'string' && value.startsWith('/') && value !== '/'
22
+ && !/[\s\x00-\x1f\x7f]/.test(value) && !value.slice(1).split('/').some((v) => ['', '.', '..'].includes(v));
23
+ export const inside = (value, root) => path(value) && path(root) && value.startsWith(`${root}/`);
24
+ const overlaps = (a, b) => a === b || inside(a, b) || inside(b, a);
25
+
26
+ export function validScope(request) {
27
+ const s = request.scope;
28
+ if (s === undefined) return typeof request.repositoryId === 'string' && request.repositoryId.trim().length > 0;
29
+ if (s?.kind === 'repository') return typeof request.repositoryId === 'string' && request.repositoryId.trim().length > 0;
30
+ if (!isArtifact(request) || request.repositoryId !== null || request.role !== 'reader'
31
+ || typeof s.workflow !== 'string' || !Object.hasOwn(workflowRoles, s.workflow) || !workflowRoles[s.workflow].includes(s.roleId)
32
+ || ![s.environmentId, s.projectId].every((v) => typeof v === 'string' && v.trim().length > 0)
33
+ || !inside(s.artifactRoot, s.workspaceRoot) || !inside(s.evidenceRoot, s.workspaceRoot)
34
+ || overlaps(s.artifactRoot, s.evidenceRoot) || !Array.isArray(s.reservedRoots)
35
+ || s.reservedRoots.some((root) => !path(root) || overlaps(root, s.artifactRoot) || overlaps(root, s.evidenceRoot))) return false;
36
+ return true;
37
+ }
@@ -8,6 +8,11 @@ description: When exploring or planning engineering work, use axstack-align to s
8
8
  For authorized delivery runs, follow [Autopilot](../axstack/references/autopilot.md)
9
9
  for phase continuation and holds.
10
10
 
11
+ Before repository binding, report-only Align advice uses workflow align in
12
+ [Local artifacts](../axstack/references/local-artifacts.md). Research and
13
+ Brainstorm retain their own scopes; inherited audit and eligible shared advice
14
+ follow the same matrix. This grants no Spec/store, tracker or execution authority.
15
+
11
16
  On driver entry, sweep under [Workspace hygiene](../axstack/references/workspace-hygiene.md); dispatched workers do not sweep.
12
17
  For every dispatch brief, name its private `<run dir>/evidence/<dispatch>/` folder.
13
18
 
@@ -5,6 +5,12 @@ description: When a substantive run needs evidence review, use axstack-audit to
5
5
 
6
6
  # Audit
7
7
 
8
+ For explicit nonrepo evidence, follow
9
+ [Local artifacts](../axstack/references/local-artifacts.md): standalone audit uses
10
+ workflow audit; inherited audits retain the supported parent's workflow. The
11
+ driver binds owned input snapshots and SHA-256; only the assigned audit.md is
12
+ writable. Missing Git history stays a limitation, never a fabricated revision.
13
+
8
14
  On driver entry, sweep under [Workspace hygiene](../axstack/references/workspace-hygiene.md); dispatched workers do not sweep.
9
15
  For every dispatch brief, name its private `<run dir>/evidence/<dispatch>/` folder.
10
16
 
@@ -64,7 +70,7 @@ Use actual records, never memory:
64
70
  - the decision log and configured `axstack-advisor-astra` and
65
71
  `axstack-advisor-opus` receipts and fresh `axstack-escalation-fable`
66
72
  receipts when triggered;
67
- - exact git revisions;
73
+ - exact git revisions where applicable; owned SHA-256 snapshots for nonrepo evidence;
68
74
  - test and review evidence; and
69
75
  - the run execution record at its recorded `progress.md` path.
70
76
 
@@ -6,7 +6,7 @@ reason when evidence is missing; missing evidence is never a pass.
6
6
 
7
7
  ```text
8
8
  Run: <run identity + scope/authority + audit mode (end-of-run | checkpoint)>
9
- Baseline: <approved spec rev | peer mode | research mode | maintenance scope>
9
+ Baseline: <approved spec rev | peer mode | research mode | maintenance scope | nonrepo report scope + source SHA-256>
10
10
  Acceptance: <passed / failed / unverified + test + SHA traces>
11
11
  Steps: <completed / deviated + why + approval per deviation>
12
12
  Advisers: <Astra/Opus configured coverage / eligible uses + same-question receipts; Astra/Fable high-stakes AGREE coverage / eligible uses>
@@ -10,6 +10,11 @@ Run inline in the current T3 driver thread. Never delegate a coordinator.
10
10
  This procedure is report-only. Do not implement, prototype, or grant execution
11
11
  or spec approval. Never interview the user or invoke Align.
12
12
 
13
+ For an explicit No-project local report scope, follow
14
+ [Local artifacts](../axstack/references/local-artifacts.md) for bounded candidate/judge
15
+ roles, separate owned folders and SHA-256 receipts. Native null-identity proof,
16
+ exact configured models/settings and arena round conditions remain required.
17
+
13
18
  Load [Standing contracts](../axstack/references/contracts.md) before acting.
14
19
  Set the rung from researched facts under the
15
20
  [design lens](../axstack/references/design-lens.md); Rung 2 meets its ADR test.
@@ -40,6 +40,14 @@ hard-to-reverse choices; they replace the critique round for that question.
40
40
  For candidate and judge threads, follow the [same-turn settle rule](../../axstack/references/workspace-hygiene.md#settlement).
41
41
  The user still decides; spec approval remains the one human checkpoint.
42
42
 
43
+ For a No-project arena, use the explicit `workflow:brainstorm` scope in
44
+ [Local artifacts](../../axstack/references/local-artifacts.md). Each candidate
45
+ owns separate artifact/evidence roots; judges receive independently owned
46
+ byte-identical anonymized snapshots after candidates finish and write only
47
+ reports. Preserve exact SHA-256 readbacks and independent sessions, including
48
+ fresh round-2 judges. Shared isolation grants no cross-reading or remote
49
+ artifact permission. The scope allowlist does not waive rung/round triggers.
50
+
43
51
  Record the synthesis note (base, graft sources, rejections, dropouts, judge
44
52
  verdicts per round) as `Decisions` rows in the
45
53
  [caller's run record](../../axstack/references/run-record.md) when one exists,
@@ -20,6 +20,10 @@ scope baseline. Ordinary work in the current chat needs no launch preflight;
20
20
  load the [T3 runtime boundary](../axstack/references/t3-runtime.md) only
21
21
  immediately before an actual profile dispatch.
22
22
 
23
+ For explicit local non-repository work, apply
24
+ [Local artifacts](../axstack/references/local-artifacts.md) before native dispatch.
25
+ Preserve this phase's independent source/fact and exact-byte review requirements.
26
+
23
27
  ## 1. Bound the question and evidence
24
28
 
25
29
  1. Identify the audience, question, requested format, theme, and publication
@@ -24,7 +24,12 @@ Interaction checks remain with `axstack-ui-verifier`; source-fidelity review is
24
24
  Use this checklist for every HTML explanation and other visual artifacts where
25
25
  rendering matters.
26
26
 
27
- Browser and visual checks must run in the delegated `axstack-ui-verifier` in its own detached checkout; outputs go to its private evidence folder, never the driver worktree.
27
+ Browser and visual checks use delegated `axstack-ui-verifier`: engineering
28
+ candidates require its own detached checkout; explicit non-repository articles
29
+ use the local shared delegate with an owned exact-byte snapshot under
30
+ [Local artifacts](../../axstack/references/local-artifacts.md). Outputs stay in
31
+ its private evidence folder. Playwright checks and source/design review remain
32
+ bound to the exact final SHA-256 before public publication.
28
33
 
29
34
  1. Identify the final artifact bytes and theme. The explicit user theme wins;
30
35
  otherwise use `prefers-color-scheme`.
@@ -5,6 +5,12 @@ description: When assessing codebase quality, improving a named screen or flow,
5
5
 
6
6
  # Improve
7
7
 
8
+ For named nonversioned code/UI discovery, use workflow improve under
9
+ [Local artifacts](../axstack/references/local-artifacts.md). Its bounded code
10
+ research/UI roles and inherited audit have separate owned snapshots and SHA-256
11
+ receipts. This resolves the former routing ambiguity; it grants no repository
12
+ readiness, whole-repository Scout, implementation or tracker authority.
13
+
8
14
  On driver entry, sweep under [Workspace hygiene](../axstack/references/workspace-hygiene.md); dispatched workers do not sweep.
9
15
  For every dispatch brief, name its private `<run dir>/evidence/<dispatch>/` folder.
10
16
 
@@ -10,6 +10,10 @@ The current T3 driver owns publication; workers return checked artifacts.
10
10
  Load [Standing contracts](../axstack/references/contracts.md) and follow its
11
11
  lifecycle pointers. Keep page bytes, checks and receipts in private run evidence.
12
12
 
13
+ For explicit local non-repository work, apply
14
+ [Local artifacts](../axstack/references/local-artifacts.md) before native dispatch.
15
+ Preserve this phase's independent source/fact and exact-byte review requirements.
16
+
13
17
  ## 1. Bind the request
14
18
 
15
19
  Read host-managed `~/.config/axstack/publish.json` containing string fields
@@ -20,6 +20,10 @@ baseline, ticket map, or author pipeline. Keep it read-only unless requested
20
20
  and separately authorized to change product code or publish; otherwise, neither
21
21
  is part of research.
22
22
 
23
+ For explicit local non-repository work, apply
24
+ [Local artifacts](../axstack/references/local-artifacts.md) before native dispatch.
25
+ Preserve this phase's independent source/fact and exact-byte review requirements.
26
+
23
27
  ## Procedure
24
28
 
25
29
  1. **Frame the question.** Restate the question, what is in scope, what is
@@ -11,6 +11,11 @@ Include [Safe deletion](../axstack/references/workspace-hygiene.md#safe-deletion
11
11
 
12
12
  Manual review keeps the user’s chat and workspace open.
13
13
 
14
+ For non-repository article/source review, follow
15
+ [Local artifacts](../axstack/references/local-artifacts.md); Explain/Publish own
16
+ the independent artifact review. PR/code-review modes below retain repository
17
+ and native worktree requirements; null identity never selects those modes.
18
+
14
19
  Produce evidence-bound findings for an exact revision using the review count
15
20
  and model routing required by its mode. Report within the requested authority;
16
21
  for own PRs, automatic merge is the default under the