axstack 0.38.0 → 0.40.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.
package/README.md
CHANGED
|
@@ -66,7 +66,7 @@ You make decisions at holds and substantial-spec approval.
|
|
|
66
66
|
Follow [getting started](docs/getting-started.md) for the full first-task journey
|
|
67
67
|
and [guides](docs/guides.md) for features, reviews, watches, debugging and releases.
|
|
68
68
|
|
|
69
|
-
## What you can do (
|
|
69
|
+
## What you can do (20 skills)
|
|
70
70
|
|
|
71
71
|
| Layer | Skill | What it does |
|
|
72
72
|
| --- | --- | --- |
|
|
@@ -85,6 +85,7 @@ and [guides](docs/guides.md) for features, reviews, watches, debugging and relea
|
|
|
85
85
|
| Operate | [axstack-watch](skills/axstack-watch/SKILL.md) | Observe or maintain an existing PR within its authority. |
|
|
86
86
|
| Operate | [axstack-cleanup](skills/axstack-cleanup/SKILL.md) | Retire eligible completed agent resources. |
|
|
87
87
|
| Operate | [axstack-relay](skills/axstack-relay/SKILL.md) | Send an explicit message or authorized notification. |
|
|
88
|
+
| Operate | [axstack-publish](skills/axstack-publish/SKILL.md) | Publish one checked Explain article in the explicitly authorized private or public mode. |
|
|
88
89
|
| Understand | [axstack-research](skills/axstack-research/SKILL.md) | Answer one bounded question with sources. |
|
|
89
90
|
| Understand | [axstack-scout](skills/axstack-scout/SKILL.md) | Gather codebase evidence for an agent across several areas. |
|
|
90
91
|
| Understand | [axstack-explain](skills/axstack-explain/SKILL.md) | Explain a system and separate known behavior from gaps. |
|
package/docs/host-operations.md
CHANGED
|
@@ -235,15 +235,24 @@ This opt-in script changes only root `defaultModelSelection` in
|
|
|
235
235
|
`~/.t3/userdata/settings.json`. Without a pool it changes only the instance
|
|
236
236
|
among enabled accounts of the current Claude/Codex driver.
|
|
237
237
|
`AXSTACK_SYNC_POOL` compares drivers by weekly clocks (>=604800s), without
|
|
238
|
-
plan weights.
|
|
239
|
-
|
|
240
|
-
|
|
238
|
+
plan weights. Weekly remaining quota is `R = 100 - used` for the selected
|
|
239
|
+
weekly window. Prefer the highest band: `R >= 15`, `10 <= R < 15`, then `R < 10`.
|
|
240
|
+
A higher band switches without a pace margin; within the same band, rotation
|
|
241
|
+
needs a ten-point elapsed-minus-used pace lead and the current account wins ties.
|
|
242
|
+
This also applies when every eligible account is below 10% remaining: known
|
|
243
|
+
usable quota stays usable, ranked by pace. Without a pool, only pace applies.
|
|
244
|
+
This is a best-effort weekly reserve preference, not a guaranteed budget for
|
|
245
|
+
future work. The current hard guard still excludes any window at 95% used
|
|
246
|
+
or a reached limit. Excluded/unauthorized/skipped current accounts can escape
|
|
247
|
+
to known candidates before the unknown hold; otherwise any unknown holds,
|
|
248
|
+
even below 10% remaining. No eligible candidate leaves the default untouched.
|
|
249
|
+
Non-current absent credentials
|
|
241
250
|
exclude; malformed/unreadable credentials and unknown/stale usage hold.
|
|
242
251
|
Cache expires after five minutes. Missing defaults stay untouched; OAuth tokens
|
|
243
252
|
are never refreshed. Each host's pool uses only enabled, credentialed drivers:
|
|
244
253
|
|
|
245
254
|
```sh
|
|
246
|
-
AXSTACK_SYNC_POOL=claudeAgent=claude-opus-5-5,codex=gpt-6
|
|
255
|
+
AXSTACK_SYNC_POOL=claudeAgent=claude-opus-5-5,codex=gpt-6-astra:medium \
|
|
247
256
|
bun ~/.agents/skills/axstack/scripts/sync-default.js --dry-run
|
|
248
257
|
```
|
|
249
258
|
|
|
@@ -258,6 +267,15 @@ A fsynced sibling preserves mode; original bytes are checked before rename and
|
|
|
258
267
|
read back afterward. The accepted sub-ms T3 write race can lose an edit;
|
|
259
268
|
read-back mismatch is an error.
|
|
260
269
|
|
|
270
|
+
Validate pool models and efforts against each host's catalog before activation.
|
|
271
|
+
Preserve that host's current Opus effort by including it explicitly when set;
|
|
272
|
+
the illustrative Claude entry above omits effort. If the current Codex default
|
|
273
|
+
still uses Sol, the driver performs a one-time same-account selection migration
|
|
274
|
+
to `gpt-6-astra:medium` during authorized host activation, saving rollback bytes
|
|
275
|
+
and verifying the write/readback. The helper does not enforce models when the
|
|
276
|
+
account stays selected. Only new chats use the changed default; running threads,
|
|
277
|
+
role routing, schedules and `roles.json` stay outside this policy.
|
|
278
|
+
|
|
261
279
|
Under host-mutation authority, install and enable:
|
|
262
280
|
|
|
263
281
|
```sh
|
|
@@ -277,7 +295,7 @@ Override Bun/skills paths via `ExecStart`/`Environment` in
|
|
|
277
295
|
|
|
278
296
|
```ini
|
|
279
297
|
[Service]
|
|
280
|
-
Environment=AXSTACK_SYNC_POOL=claudeAgent=claude-opus-5-5,codex=gpt-6
|
|
298
|
+
Environment=AXSTACK_SYNC_POOL=claudeAgent=claude-opus-5-5,codex=gpt-6-astra:medium
|
|
281
299
|
```
|
|
282
300
|
|
|
283
301
|
Reload after edits. Logout needs authorized linger; installation never activates units.
|
package/docs/workflows.md
CHANGED
|
@@ -22,6 +22,9 @@ immediately before dispatch or account re-selection.
|
|
|
22
22
|
|
|
23
23
|
Direct routes need no spec ceremony:
|
|
24
24
|
|
|
25
|
+
- [axstack-publish](../skills/axstack-publish/SKILL.md) publishes one Explain
|
|
26
|
+
HTML article in one explicitly authorized private or public mode through the
|
|
27
|
+
driver, after final-byte checks, independent review and live verification.
|
|
25
28
|
- [axstack-verify](../skills/axstack-verify/SKILL.md) routes verification-skill
|
|
26
29
|
creation and maintenance through Implement.
|
|
27
30
|
A single-behavior check uses an existing `verify-<app>` skill or UI verification
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "axstack",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.40.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",
|
|
@@ -39,17 +39,21 @@ export function decide(settings, usage, now, pool = null) {
|
|
|
39
39
|
&& Number.isFinite(window?.used) && Number.isFinite(window?.seconds) && window.seconds > 0
|
|
40
40
|
&& Number.isFinite(window?.resetAt) && window.resetAt > now
|
|
41
41
|
&& (!pooled || window.seconds >= 604800);
|
|
42
|
+
const remaining = known ? 100 - window.used : null;
|
|
42
43
|
return { instanceId, state: excluded ? 'excluded' : known ? 'eligible' : 'unknown',
|
|
44
|
+
...(pooled && { band: known ? remaining >= 15 ? 2 : remaining >= 10 ? 1 : 0 : null }),
|
|
43
45
|
pace: known ? 100 * (1 - (window.resetAt - now) / (window.seconds * 1000)) - window.used : null };
|
|
44
46
|
});
|
|
45
47
|
const current = result.instances.find((entry) => entry.instanceId === from);
|
|
46
|
-
const best = result.instances.filter((entry) => entry.state === 'eligible')
|
|
48
|
+
const best = result.instances.filter((entry) => entry.state === 'eligible')
|
|
49
|
+
.sort((a, b) => (pooled ? b.band - a.band : 0) || b.pace - a.pace)[0];
|
|
47
50
|
const excluded = !current || current.state === 'excluded';
|
|
48
51
|
if (excluded && best) return updated(best, 'current-excluded');
|
|
49
52
|
if (result.instances.some((entry) => entry.state === 'unknown')) return { ...result, reason: 'unknown' };
|
|
50
53
|
if (!best) return { ...result, reason: 'no-eligible' };
|
|
51
|
-
|
|
52
|
-
|
|
54
|
+
const higherBand = pooled && best.band > current.band;
|
|
55
|
+
if (best.instanceId !== from && (higherBand || best.pace - current.pace >= 10)) {
|
|
56
|
+
return updated(best, higherBand ? 'reserve' : 'pace');
|
|
53
57
|
}
|
|
54
58
|
return { ...result, reason: 'margin' };
|
|
55
59
|
}
|
|
@@ -0,0 +1,95 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: axstack-publish
|
|
3
|
+
description: When the user requests publication of an Explain HTML article, use axstack-publish to verify and publish that article in the explicitly authorized mode.
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# Publish
|
|
7
|
+
|
|
8
|
+
Publish an existing Explain HTML article through the notes CLI on the configured publish host.
|
|
9
|
+
The current T3 driver owns publication; workers return checked artifacts.
|
|
10
|
+
Load [Standing contracts](../axstack/references/contracts.md) and follow its
|
|
11
|
+
lifecycle pointers. Keep page bytes, checks and receipts in private run evidence.
|
|
12
|
+
|
|
13
|
+
## 1. Bind the request
|
|
14
|
+
|
|
15
|
+
Read host-managed `~/.config/axstack/publish.json` containing string fields
|
|
16
|
+
`sshHost`, `publicOrigin` and `docsOrigin`.
|
|
17
|
+
|
|
18
|
+
```json
|
|
19
|
+
{"sshHost":"<publish host>","publicOrigin":"<public HTTPS origin>","docsOrigin":"<docs HTTPS origin>"}
|
|
20
|
+
```
|
|
21
|
+
|
|
22
|
+
Validate `sshHost` as `^[A-Za-z0-9][A-Za-z0-9.-]*$` and both origins as HTTPS
|
|
23
|
+
URL origins with no credentials, path, query or fragment.
|
|
24
|
+
Hold publication if the config is missing or invalid.
|
|
25
|
+
Never guess a publish host or either origin.
|
|
26
|
+
Keep these routing values host-managed; this config grants no publication authority.
|
|
27
|
+
Identify the Explain page by its exact bytes, byte count and SHA-256.
|
|
28
|
+
State the article, slug, mode (`private` or `public`) and target URL.
|
|
29
|
+
Public targets `<publicOrigin>/<slug>/`; private targets the
|
|
30
|
+
SlashDocs document URL at `docsOrigin` returned by the CLI.
|
|
31
|
+
For a new private document, state that origin and slug before publication and
|
|
32
|
+
record the allocated URL afterwards.
|
|
33
|
+
Require explicit authority for exactly one article and one mode per request.
|
|
34
|
+
Promotion, unpublish, reader changes and grant changes each need their own request.
|
|
35
|
+
Local creation or an earlier publication supplies no new publication authority.
|
|
36
|
+
If the request leaves the article or mode unclear, hold publication for clarification.
|
|
37
|
+
|
|
38
|
+
## 2. Prepare the final artifact
|
|
39
|
+
|
|
40
|
+
For public mode, run the [Explain redaction check](../axstack-explain/SKILL.md#3-verify-and-deliver)
|
|
41
|
+
to remove private paths, IDs, credentials, prompts, messages and internal records.
|
|
42
|
+
For public mode, run Explain's [self-contained asset check](../axstack-explain/references/inline-pages.md#check-the-exact-bytes).
|
|
43
|
+
Reuse Explain's [page rules](../axstack-explain/references/inline-pages.md#page-rules)
|
|
44
|
+
and [Visual QA](../axstack-explain/references/visual-qa.md) for checks and verifier routing.
|
|
45
|
+
|
|
46
|
+
Add a standalone light/dark theme with inline defaults and `prefers-color-scheme`
|
|
47
|
+
so the article works outside T3; honor an explicit user theme request.
|
|
48
|
+
Theme adaptation changes bytes: save `final.html`, its byte count and SHA-256,
|
|
49
|
+
then rerun the referenced Explain page checks on these final bytes.
|
|
50
|
+
Require a fresh independent `axstack-explainer-review` on the final bytes.
|
|
51
|
+
Preview these exact bytes with Playwright MCP at 728px dark and 360px light;
|
|
52
|
+
record both screenshots and the Explain QA results.
|
|
53
|
+
Any subsequent byte change invalidates checks and review: repeat this step.
|
|
54
|
+
Hold publication while any required check or review is missing or failed.
|
|
55
|
+
|
|
56
|
+
## 3. Publish from the driver
|
|
57
|
+
|
|
58
|
+
Publish only from the driver thread.
|
|
59
|
+
Use stdin only with no TTY and at most
|
|
60
|
+
5,000,000 bytes (5 MB) of final HTML:
|
|
61
|
+
|
|
62
|
+
```bash
|
|
63
|
+
ssh <publish host> notes publish --mode <mode> --slug <slug> < final.html
|
|
64
|
+
```
|
|
65
|
+
|
|
66
|
+
Use the validated `sshHost`, validate the slug as `^[a-z0-9][a-z0-9-]{0,63}$`
|
|
67
|
+
and select one literal mode (`private` or `public`).
|
|
68
|
+
Use safely quoted arguments, never interpolate unchecked input into a shell.
|
|
69
|
+
Require exit zero and one JSON line containing `url`, `doc`, `version`, `sha256`.
|
|
70
|
+
Compare its SHA with the final artifact; a mismatch or ambiguous result holds
|
|
71
|
+
success reporting until reconciled with `ssh <publish host> notes status --slug <slug>`.
|
|
72
|
+
Require the returned URL's origin to match the configured origin for that mode.
|
|
73
|
+
Retain phase errors and pending state as unresolved evidence.
|
|
74
|
+
|
|
75
|
+
## 4. Prove the live result and return
|
|
76
|
+
|
|
77
|
+
Verify the live URL in a real browser using Playwright MCP against the final SHA-256.
|
|
78
|
+
For public mode, verify an anonymous browser reads exact response bytes at
|
|
79
|
+
`<publicOrigin>/<slug>/` whose SHA-256 matches the final artifact.
|
|
80
|
+
Hash the response body bytes, rather than DOM serialization or rendered text.
|
|
81
|
+
For private mode, verify anonymous navigation reaches the SlashDocs sign-in page
|
|
82
|
+
leading to Dex and `notes status --slug <slug>` reports `published: true`, the
|
|
83
|
+
live version and SHA-256 that matches the final bytes.
|
|
84
|
+
Compare status's private version with the publish result; null live metadata
|
|
85
|
+
or a pending operation leaves verification unproven.
|
|
86
|
+
Reader-side reads are proven only by the separately authorized AC23 end-to-end
|
|
87
|
+
run; an anonymous redirect and CLI metadata do not prove a reader grant.
|
|
88
|
+
Return URL, version and SHA-256 with the live verification evidence or its hold.
|
|
89
|
+
Tell the user when `overwrote_external_edit` is true: publication replaced an
|
|
90
|
+
external edit, retained as an earlier SlashDocs version.
|
|
91
|
+
|
|
92
|
+
Agents never handle reader passwords.
|
|
93
|
+
Agents never run `notes reader show` or allocate a TTY (`-t` or `-tt` on SSH).
|
|
94
|
+
Reader and grant commands require their own request and secret-free non-TTY output.
|
|
95
|
+
The owner shares reader credentials separately from the article link.
|