@sabaiway/agent-workflow-kit 1.44.0 → 1.45.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/CHANGELOG.md +63 -0
- package/README.md +6 -3
- package/SKILL.md +9 -1
- package/bridges/antigravity-cli-bridge/SKILL.md +1 -1
- package/bridges/antigravity-cli-bridge/bin/agy-review.sh +87 -16
- package/bridges/antigravity-cli-bridge/bin/agy-review.test.mjs +3 -0
- package/bridges/antigravity-cli-bridge/bin/agy.test.mjs +4 -2
- package/bridges/antigravity-cli-bridge/capability.json +3 -2
- package/bridges/codex-cli-bridge/SKILL.md +7 -7
- package/bridges/codex-cli-bridge/bin/codex-exec.sh +3 -3
- package/bridges/codex-cli-bridge/bin/codex-exec.test.mjs +4 -1
- package/bridges/codex-cli-bridge/bin/codex-review.sh +93 -22
- package/bridges/codex-cli-bridge/bin/codex-review.test.mjs +4 -0
- package/bridges/codex-cli-bridge/capability.json +4 -3
- package/bridges/codex-cli-bridge/references/driving-codex.md +5 -4
- package/bridges/codex-cli-bridge/references/sandbox-and-flags.md +5 -4
- package/capability.json +1 -1
- package/package.json +1 -1
- package/references/modes/bootstrap.md +1 -1
- package/references/modes/bridge-settings.md +1 -1
- package/references/modes/grounding.md +8 -7
- package/references/modes/recommendations.md +14 -0
- package/references/modes/review-state.md +1 -1
- package/references/modes/sandbox-masks.md +15 -0
- package/references/modes/upgrade.md +10 -7
- package/references/modes/velocity.md +13 -2
- package/references/shared/composition-handoff.md +21 -16
- package/references/shared/report-footer.md +5 -1
- package/references/templates/AGENTS.md +2 -1
- package/references/templates/autonomy.json +3 -0
- package/tools/autonomy-config.mjs +13 -3
- package/tools/commands.mjs +15 -1
- package/tools/delegation.mjs +9 -5
- package/tools/detect-backends.mjs +2 -2
- package/tools/doc-parity.mjs +8 -0
- package/tools/engine-source.mjs +6 -0
- package/tools/family-registry.mjs +21 -7
- package/tools/fold-completeness-run.mjs +5 -0
- package/tools/grounding.mjs +139 -22
- package/tools/inject-methodology.mjs +117 -28
- package/tools/manifest/schema.md +20 -0
- package/tools/manifest/validate.mjs +26 -0
- package/tools/procedures.mjs +61 -8
- package/tools/recipes.mjs +94 -15
- package/tools/recommendations.mjs +469 -0
- package/tools/review-ledger-write.mjs +14 -0
- package/tools/review-ledger.mjs +3 -2
- package/tools/review-state.mjs +101 -24
- package/tools/run-gates.mjs +3 -0
- package/tools/sandbox-masks.mjs +370 -0
- package/tools/set-recipe.mjs +13 -1
- package/tools/velocity-profile.mjs +228 -22
|
@@ -13,8 +13,9 @@
|
|
|
13
13
|
#
|
|
14
14
|
# For `code`, the wrapper PRECOMPUTES the full change set (repo map, git status,
|
|
15
15
|
# staged + unstaged diffs, untracked file CONTENTS — binaries skipped, symlinks
|
|
16
|
-
# shown as targets,
|
|
17
|
-
#
|
|
16
|
+
# shown as targets, directories/vanished paths noted; never-committable untracked
|
|
17
|
+
# paths (devices/FIFOs/sockets) are excluded from the review domain entirely) and
|
|
18
|
+
# feeds it in, so codex does not burn a run rediscovering it. A clean tree exits 0
|
|
18
19
|
# BEFORE a run is spent; an oversized payload goes via a git-dir-local temp file
|
|
19
20
|
# (never silently truncated). Optionally (CODEX_REVIEW_SCHEMA=1) the findings come
|
|
20
21
|
# back as a validated JSON object, with a raw-text fallback.
|
|
@@ -56,14 +57,16 @@ Receipt:
|
|
|
56
57
|
side effect — a successful review appends one JSON receipt line to
|
|
57
58
|
<git dir>/agent-workflow-review-receipts.jsonl (AW_REVIEW_RECEIPTS overrides): fingerprint =
|
|
58
59
|
sha256 over the canonical uncommitted-state payload (staged diff + unstaged diff +
|
|
59
|
-
untracked-not-ignored contents — the review-payload domain
|
|
60
|
+
untracked-not-ignored contents — the review-payload domain; never-committable untracked paths —
|
|
61
|
+
character/block devices, FIFOs, sockets — are excluded from the domain entirely, untracked
|
|
62
|
+
symlinks/directories ride as name-only notes) in code mode, the artifact-file
|
|
60
63
|
sha256 in plan mode; verdict parsed from the mandated literal verdict line (schema mode: the
|
|
61
64
|
verdict field); always fresh:true (one-shot) + grounded:true (native AGENTS.md auto-merge,
|
|
62
65
|
factsHash null); a write failure warns, never fails the review
|
|
63
66
|
|
|
64
67
|
Settings file (KEY=VALUE, parsed never sourced; env wins over file, file wins over built-in default):
|
|
65
68
|
${XDG_CONFIG_HOME:-~/.config}/agent-workflow/bridge-settings.conf
|
|
66
|
-
CODEX_SERVICE_TIER — service tier: 'priority' (Fast — ~1.5x speed at a 2.5x credit rate on gpt-5.
|
|
69
|
+
CODEX_SERVICE_TIER — service tier: 'priority' (Fast — ~1.5x speed at a 2.5x credit rate on gpt-5.6-sol); a consented SPEND knob, default off (standard tier)
|
|
67
70
|
CODEX_HARD_TIMEOUT — hard wall-clock cap, integer seconds 1..86400 (built-in default 1800)
|
|
68
71
|
CODEX_REVIEW_MAX_TOTAL_BYTES — inline-payload cap, integer bytes 1..100000000 (default 1500000); above it the diff rides via a git-dir temp file
|
|
69
72
|
|
|
@@ -164,12 +167,12 @@ aw_apply_settings() {
|
|
|
164
167
|
}
|
|
165
168
|
aw_apply_settings
|
|
166
169
|
|
|
167
|
-
DEFAULT_CODEX_MODEL="gpt-5.
|
|
170
|
+
DEFAULT_CODEX_MODEL="gpt-5.6-sol"
|
|
168
171
|
DEFAULT_CODEX_EFFORT="xhigh"
|
|
169
172
|
# Review-receipt identity (AD-038). AW_BRIDGE_VERSION mirrors this bridge's SKILL.md/capability.json
|
|
170
173
|
# version (drift-guarded by codex-review.test.mjs against capability.json).
|
|
171
174
|
AW_RECEIPT_BACKEND="codex"
|
|
172
|
-
AW_BRIDGE_VERSION="2.
|
|
175
|
+
AW_BRIDGE_VERSION="2.5.0"
|
|
173
176
|
CODEX_MODEL="${CODEX_MODEL:-$DEFAULT_CODEX_MODEL}"
|
|
174
177
|
CODEX_EFFORT="${CODEX_EFFORT:-$DEFAULT_CODEX_EFFORT}"
|
|
175
178
|
# Generous hard cap for a slow xhigh review (subscription latency varies).
|
|
@@ -180,7 +183,7 @@ CODEX_REVIEW_MAX_TOTAL_BYTES="${CODEX_REVIEW_MAX_TOTAL_BYTES:-1500000}"
|
|
|
180
183
|
# Codex service tier (quality-neutral speed knob; live-probed 2026-07-05): default EMPTY ⇒ no
|
|
181
184
|
# service_tier flag (standard tier) — enabling Fast is a consented per-host SPEND act, never a
|
|
182
185
|
# silent default. The only server-catalog tier id on this subscription is 'priority' (catalog
|
|
183
|
-
# display name "Fast": ~1.5x token speed at a 2.5x credit rate on gpt-5.
|
|
186
|
+
# display name "Fast": ~1.5x token speed at a 2.5x credit rate on gpt-5.6-sol; quality-neutral —
|
|
184
187
|
# same model). codex itself accepts ANY -c service_tier string silently (probe-verified), so
|
|
185
188
|
# the wrapper validates the effective value: an unsupported one warns and runs on the standard
|
|
186
189
|
# tier — a typo can never silently masquerade as Fast.
|
|
@@ -292,11 +295,76 @@ sha256_stdin() {
|
|
|
292
295
|
fi
|
|
293
296
|
}
|
|
294
297
|
|
|
298
|
+
# Never-committable untracked stat class (Decision 1, AD-044 Plan 4): character/block devices,
|
|
299
|
+
# FIFOs, sockets — git content can never carry them, so they are excluded from the ENTIRE review
|
|
300
|
+
# domain (fingerprint payload, assembled change set, status section, no-diff preflight). Symlinks
|
|
301
|
+
# (checked first, never followed) and directories (an embedded repo lists as `dir/` — a committable
|
|
302
|
+
# gitlink) STAY in the domain. The class surfaces where a sandbox injects device masks whose dirent
|
|
303
|
+
# LIES to git's walk; the stat here sees the truth.
|
|
304
|
+
is_never_committable_untracked() {
|
|
305
|
+
[[ ! -L "$1" && ( -p "$1" || -S "$1" || -c "$1" || -b "$1" ) ]]
|
|
306
|
+
}
|
|
307
|
+
|
|
308
|
+
# The ONE untracked-not-ignored walk every review-domain surface iterates (fingerprint payload,
|
|
309
|
+
# assembled change set, no-diff preflight): NUL-delimited paths with the never-committable classes
|
|
310
|
+
# filtered out.
|
|
311
|
+
emit_untracked_paths_z() {
|
|
312
|
+
local path
|
|
313
|
+
while IFS= read -r -d '' path; do
|
|
314
|
+
if is_never_committable_untracked "$path"; then continue; fi
|
|
315
|
+
printf '%s\0' "$path"
|
|
316
|
+
done < <(git ls-files --others --exclude-standard -z)
|
|
317
|
+
}
|
|
318
|
+
|
|
319
|
+
# True when at least one untracked-not-ignored path survives the never-committable filter — the
|
|
320
|
+
# no-diff preflight twin of the fingerprint walk (a tree whose ONLY untracked paths are
|
|
321
|
+
# device/FIFO/socket masks reads clean).
|
|
322
|
+
has_reviewable_untracked() {
|
|
323
|
+
[[ "$(emit_untracked_paths_z | wc -c)" -gt 0 ]]
|
|
324
|
+
}
|
|
325
|
+
|
|
326
|
+
# `git status --porcelain=v1` with never-committable untracked records dropped, so the assembled
|
|
327
|
+
# review payload is byte-identical with and without a device mask (the fingerprint==payload domain
|
|
328
|
+
# identity). Quote/space-safe: each filtered path's DISPLAYED line comes from git itself (never a
|
|
329
|
+
# re-implemented C-quoting), then exact whole-line removal — only untracked (??) records can match
|
|
330
|
+
# by construction. A mask nested in an otherwise-empty untracked directory leaves the collapsed
|
|
331
|
+
# `?? dir/` record (a directory is not in the filtered class); the real sandbox masks land beside
|
|
332
|
+
# tracked content, where status lists them individually.
|
|
333
|
+
emit_status_porcelain_filtered() {
|
|
334
|
+
local path line drop=""
|
|
335
|
+
while IFS= read -r -d '' path; do
|
|
336
|
+
if is_never_committable_untracked "$path"; then
|
|
337
|
+
line="$(git status --porcelain=v1 -- ":(literal)$path")"
|
|
338
|
+
if [[ -n "$line" ]]; then drop+="$line"$'\n'; fi
|
|
339
|
+
fi
|
|
340
|
+
done < <(git ls-files --others --exclude-standard -z)
|
|
341
|
+
if [[ -z "$drop" ]]; then
|
|
342
|
+
git status --porcelain=v1
|
|
343
|
+
else
|
|
344
|
+
git status --porcelain=v1 | grep -Fvxf <(printf '%s' "$drop") || true
|
|
345
|
+
fi
|
|
346
|
+
}
|
|
347
|
+
|
|
348
|
+
# ONE non-failing advisory when the walk observes never-committable untracked paths: they are
|
|
349
|
+
# ignored by the review domain BY CONSTRUCTION; the kit's sandbox-masks lane can hide them from
|
|
350
|
+
# `git status` too. Never an error, never a detector.
|
|
351
|
+
warn_never_committable_untracked() {
|
|
352
|
+
local path n=0
|
|
353
|
+
while IFS= read -r -d '' path; do
|
|
354
|
+
if is_never_committable_untracked "$path"; then n=$((n + 1)); fi
|
|
355
|
+
done < <(git ls-files --others --exclude-standard -z)
|
|
356
|
+
if (( n > 0 )); then
|
|
357
|
+
echo "notice: $n never-committable untracked path(s) (device/FIFO/socket) ignored by the review domain — for a clean 'git status' see the kit's sandbox-masks lane (/agent-workflow-kit sandbox-masks)." >&2
|
|
358
|
+
fi
|
|
359
|
+
}
|
|
360
|
+
|
|
295
361
|
# The canonical uncommitted-state fingerprint payload (code mode). Domain == the review payload:
|
|
296
|
-
# tracked staged + unstaged changes + untracked-not-ignored file contents (binary
|
|
297
|
-
#
|
|
298
|
-
#
|
|
299
|
-
#
|
|
362
|
+
# tracked staged + unstaged changes + untracked-not-ignored file contents (binary untracked files,
|
|
363
|
+
# symlinks, and directories/gitlinks ride as name-only notes, mirroring the assembled change set;
|
|
364
|
+
# never-committable untracked paths — devices/FIFOs/sockets — are EXCLUDED entirely, see
|
|
365
|
+
# emit_untracked_paths_z). The prose definition lives in capability.json
|
|
366
|
+
# roles.review.contract.receipt (both bridges, lockstep); the kit checker (tools/review-state.mjs)
|
|
367
|
+
# implements the SAME serialization in node — cross-checked by the kit's
|
|
300
368
|
# review-fingerprint-parity.test.mjs.
|
|
301
369
|
emit_fingerprint_payload() {
|
|
302
370
|
git diff --cached --no-ext-diff
|
|
@@ -313,7 +381,7 @@ emit_fingerprint_payload() {
|
|
|
313
381
|
printf 'untracked:%s\n' "$path"
|
|
314
382
|
cat -- "$path"
|
|
315
383
|
fi
|
|
316
|
-
done < <(
|
|
384
|
+
done < <(emit_untracked_paths_z)
|
|
317
385
|
}
|
|
318
386
|
|
|
319
387
|
# sha256 of the canonical payload, emitted from the work-tree ROOT (a subdir invocation hashes the
|
|
@@ -355,17 +423,18 @@ write_review_receipt() {
|
|
|
355
423
|
fi
|
|
356
424
|
}
|
|
357
425
|
|
|
358
|
-
# Emit the full review surface to stdout: repo map, status
|
|
359
|
-
# diffs, and the CONTENTS of every untracked REGULAR file (NUL-safe
|
|
360
|
-
#
|
|
361
|
-
#
|
|
362
|
-
#
|
|
426
|
+
# Emit the full review surface to stdout: repo map, status (never-committable untracked records
|
|
427
|
+
# filtered), staged + unstaged diffs, and the CONTENTS of every untracked REGULAR file (NUL-safe
|
|
428
|
+
# iteration over the SAME filtered walk as the fingerprint — the payload is byte-identical with
|
|
429
|
+
# and without a device mask). Symlinks are shown as their target (never followed — no out-of-repo
|
|
430
|
+
# leak); directories/vanished paths are noted, never read (a `cat` on a FIFO would hang BEFORE the
|
|
431
|
+
# hard timeout applies — that class never reaches this loop).
|
|
363
432
|
assemble_code_diff() {
|
|
364
433
|
echo "=== repo file map (git ls-files) ==="
|
|
365
434
|
git ls-files
|
|
366
435
|
echo
|
|
367
436
|
echo "=== git status (porcelain) ==="
|
|
368
|
-
|
|
437
|
+
emit_status_porcelain_filtered
|
|
369
438
|
echo
|
|
370
439
|
echo "=== staged diff (git diff --cached) ==="
|
|
371
440
|
git diff --cached --no-ext-diff
|
|
@@ -387,7 +456,7 @@ assemble_code_diff() {
|
|
|
387
456
|
cat -- "$path"
|
|
388
457
|
printf '\n'
|
|
389
458
|
fi
|
|
390
|
-
done < <(
|
|
459
|
+
done < <(emit_untracked_paths_z)
|
|
391
460
|
}
|
|
392
461
|
|
|
393
462
|
mode="${1:-}"
|
|
@@ -416,12 +485,14 @@ case "$mode" in
|
|
|
416
485
|
prompt="${directive}"$'\n\nPLAN:\n'"$(cat -- "$target")"
|
|
417
486
|
;;
|
|
418
487
|
code)
|
|
419
|
-
# No-diff preflight — never spend a subscription run on a clean tree.
|
|
420
|
-
|
|
421
|
-
|
|
488
|
+
# No-diff preflight — never spend a subscription run on a clean tree. Never-committable
|
|
489
|
+
# untracked masks do not count: the FILTERED domain is the review surface.
|
|
490
|
+
if git diff --quiet && git diff --cached --quiet && ! has_reviewable_untracked; then
|
|
422
491
|
echo "codex-review: no uncommitted changes to review — the working tree is clean." >&2
|
|
492
|
+
warn_never_committable_untracked
|
|
423
493
|
exit 0
|
|
424
494
|
fi
|
|
495
|
+
warn_never_committable_untracked
|
|
425
496
|
# The canonical fingerprint of the tree codex is about to review — computed at assembly time
|
|
426
497
|
# (BEFORE the EXIT trap can fire), so the receipt attests exactly the reviewed state.
|
|
427
498
|
REVIEW_ARTIFACT="code"
|
|
@@ -106,6 +106,10 @@ const run = ({ repo, bin }, { args = ['code'], env = {}, path, cwd } = {}) => {
|
|
|
106
106
|
env: {
|
|
107
107
|
PATH: path || `${bin}:${process.env.PATH}`,
|
|
108
108
|
HOME: repo,
|
|
109
|
+
// The wrapper's mktemp must keep working when the suite itself runs inside an OS sandbox
|
|
110
|
+
// whose /tmp is read-only (only $TMPDIR is writable there) — the built-from-scratch env
|
|
111
|
+
// would otherwise drop it and fail every spawn.
|
|
112
|
+
TMPDIR: process.env.TMPDIR ?? '/tmp',
|
|
109
113
|
CODEX_HOME: codexHome,
|
|
110
114
|
CODEX_FAKE_ARGV: argvFile,
|
|
111
115
|
CODEX_FAKE_ENV: envFile,
|
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
"schema": 1,
|
|
4
4
|
"name": "codex-cli-bridge",
|
|
5
5
|
"kind": "execution-backend",
|
|
6
|
-
"version": "2.
|
|
6
|
+
"version": "2.5.0",
|
|
7
7
|
"provides": ["execute", "review"],
|
|
8
8
|
"roles": {
|
|
9
9
|
"execute": {
|
|
@@ -39,7 +39,7 @@
|
|
|
39
39
|
],
|
|
40
40
|
"grounding": "automatic — the wrapper precomputes the full working-tree change set (repo map, status, diffs, untracked contents) and codex auto-merges the root AGENTS.md; no grounding flags",
|
|
41
41
|
"continue": [],
|
|
42
|
-
"receipt": "side effect — a successful review appends one JSON receipt line to <git dir>/agent-workflow-review-receipts.jsonl (AW_REVIEW_RECEIPTS overrides): fingerprint = sha256 over the canonical uncommitted-state payload (staged diff + unstaged diff + untracked-not-ignored contents — the review-payload domain) in code mode, the artifact-file sha256 in plan mode; verdict parsed from the mandated literal verdict line (schema mode: the verdict field); always fresh:true (one-shot) + grounded:true (native AGENTS.md auto-merge, factsHash null); a write failure warns, never fails the review"
|
|
42
|
+
"receipt": "side effect — a successful review appends one JSON receipt line to <git dir>/agent-workflow-review-receipts.jsonl (AW_REVIEW_RECEIPTS overrides): fingerprint = sha256 over the canonical uncommitted-state payload (staged diff + unstaged diff + untracked-not-ignored contents — the review-payload domain; never-committable untracked paths — character/block devices, FIFOs, sockets — are excluded from the domain entirely, untracked symlinks/directories ride as name-only notes) in code mode, the artifact-file sha256 in plan mode; verdict parsed from the mandated literal verdict line (schema mode: the verdict field); always fresh:true (one-shot) + grounded:true (native AGENTS.md auto-merge, factsHash null); a write failure warns, never fails the review"
|
|
43
43
|
}
|
|
44
44
|
}
|
|
45
45
|
},
|
|
@@ -50,7 +50,7 @@
|
|
|
50
50
|
"values": ["priority"],
|
|
51
51
|
"default": null,
|
|
52
52
|
"appliesTo": ["codex-exec", "codex-review"],
|
|
53
|
-
"effect": "codex service tier; 'priority' (catalog display name Fast) = ~1.5x token speed at a 2.5x credit rate on gpt-5.
|
|
53
|
+
"effect": "codex service tier; 'priority' (catalog display name Fast) = ~1.5x token speed at a 2.5x credit rate on gpt-5.6-sol — quality-neutral (same model), live-probed 2026-07-05. Unset/empty ⇒ no service_tier flag (standard tier). SPEND KNOB: enabling it is a consented per-host act, never a default. codex itself accepts any -c service_tier string silently, so the wrapper validates the value."
|
|
54
54
|
},
|
|
55
55
|
{
|
|
56
56
|
"key": "CODEX_HARD_TIMEOUT",
|
|
@@ -71,6 +71,7 @@
|
|
|
71
71
|
"effect": "codex-review code: above this assembled-payload size (bytes) the diff rides via a git-dir temp file instead of inline — never truncated."
|
|
72
72
|
}
|
|
73
73
|
],
|
|
74
|
+
"networkHosts": ["chatgpt.com", "*.chatgpt.com"],
|
|
74
75
|
"detect": {
|
|
75
76
|
"installed": {
|
|
76
77
|
"env": "CODEX_CLI_BRIDGE_DIR",
|
|
@@ -20,7 +20,7 @@ judgment.
|
|
|
20
20
|
|
|
21
21
|
## Quality-first: model & effort are pinned
|
|
22
22
|
|
|
23
|
-
Delegated codex work ALWAYS runs on the frontier model at max effort: `gpt-5.
|
|
23
|
+
Delegated codex work ALWAYS runs on the frontier model at max effort: `gpt-5.6-sol` / `xhigh` are **pinned**
|
|
24
24
|
and a non-default `CODEX_MODEL`/`CODEX_EFFORT` is **refused** (exit 2). Do not try to "tune down" the
|
|
25
25
|
model or effort for a real run — the wrapper will stop you. Quota is metered in **messages** (rolling
|
|
26
26
|
5h + weekly), so economy comes from removing waste (clean capture, the precomputed review diff, resume),
|
|
@@ -38,8 +38,9 @@ mis-ordered steps, scope creep, missing gates).
|
|
|
38
38
|
|
|
39
39
|
Use **`codex-review code`** for advisory, severity-tagged findings on uncommitted changes. The wrapper
|
|
40
40
|
**precomputes the whole change set** — repo map, `git status`, staged + unstaged diff, and the
|
|
41
|
-
**contents of untracked files** (binaries noted but skipped, symlinks shown as targets
|
|
42
|
-
|
|
41
|
+
**contents of untracked files** (binaries noted but skipped, symlinks shown as targets;
|
|
42
|
+
never-committable untracked paths — devices/FIFOs/sockets — excluded from the review domain
|
|
43
|
+
entirely) — and feeds it in, so codex does not burn a run roaming the filesystem to
|
|
43
44
|
rediscover it. A clean tree exits 0 *before* a run is spent. An oversized payload (over
|
|
44
45
|
`CODEX_REVIEW_MAX_TOTAL_BYTES`, default 1.5 MB) is written to a git-dir temp file and referenced by
|
|
45
46
|
path — never silently truncated. Set `CODEX_REVIEW_SCHEMA=1` to get findings back as a validated JSON
|
|
@@ -76,7 +77,7 @@ codex-exec --resume <session-id> <file|-> # explicit session id
|
|
|
76
77
|
|
|
77
78
|
Resume continues the SAME codex session, so you avoid re-sending the original context. It runs through
|
|
78
79
|
the wrapper, which **re-establishes every invariant** (subscription-only `*_API_KEY` scrub,
|
|
79
|
-
`--ignore-user-config`, the pinned `gpt-5.
|
|
80
|
+
`--ignore-user-config`, the pinned `gpt-5.6-sol`/`xhigh`) and **restates the full posture via `-c`** —
|
|
80
81
|
because `codex exec resume` resets the sandbox/approval/network posture and rejects `-s`/`--add-dir`/`-C`,
|
|
81
82
|
the wrapper passes `-c sandbox_mode=workspace-write -c approval_policy=never -c
|
|
82
83
|
sandbox_workspace_write.network_access=false` explicitly. A resume takes no passthrough flags and an
|
|
@@ -50,7 +50,7 @@ echoes `session: <id>` to stderr. On a missing/empty final-message file it falls
|
|
|
50
50
|
|
|
51
51
|
## Quality-first guard (pinned model & effort)
|
|
52
52
|
|
|
53
|
-
The wrappers default `CODEX_MODEL=gpt-5.
|
|
53
|
+
The wrappers default `CODEX_MODEL=gpt-5.6-sol` and `CODEX_EFFORT=xhigh` and **refuse** (exit 2, loud) any
|
|
54
54
|
non-default — delegated work always uses the frontier model at max effort; quality is never traded for
|
|
55
55
|
quota. `CODEX_PROBE=1` relaxes this for a throwaway, effort-independent probe only (echoed loudly), and
|
|
56
56
|
a probe still runs on the subscription, in the sandbox, with clean capture.
|
|
@@ -108,8 +108,9 @@ This is defence-in-depth beside the prompt contract; the orchestrator still revi
|
|
|
108
108
|
|
|
109
109
|
`code` mode does NOT make codex discover the diff. The wrapper assembles the full surface — repo file
|
|
110
110
|
map (`git ls-files`), `git status`, staged + unstaged diff, and the **contents** of every untracked
|
|
111
|
-
regular file (NUL-safe; binaries noted but skipped, symlinks shown as targets
|
|
112
|
-
|
|
111
|
+
regular file (NUL-safe; binaries noted but skipped, symlinks shown as targets; never-committable
|
|
112
|
+
untracked paths — devices/FIFOs/sockets — excluded from the review domain entirely) — into a
|
|
113
|
+
git-dir-local temp file (600 perms), then feeds it in. A **clean tree exits 0** before
|
|
113
114
|
a run is spent. If the assembled payload exceeds `CODEX_REVIEW_MAX_TOTAL_BYTES` (default `1500000`) it is
|
|
114
115
|
passed **by path** (read-fence carve-out) instead of inline — **never truncated**. `-s read-only` is
|
|
115
116
|
kept so codex may still read surrounding in-repo files for context.
|
|
@@ -185,7 +186,7 @@ exec` over the precomputed diff instead, keeping every invariant intact.
|
|
|
185
186
|
| `-o, --output-last-message <f>` | write ONLY the final message (clean capture) |
|
|
186
187
|
| `--json` | structured event stream (`thread.started` ⇒ session id) |
|
|
187
188
|
| `--output-schema <f>` | constrain output to a JSON schema (`CODEX_REVIEW_SCHEMA=1`) |
|
|
188
|
-
| `-m <model>` | model (wrapper default `gpt-5.
|
|
189
|
+
| `-m <model>` | model (wrapper default `gpt-5.6-sol`, pinned via `CODEX_MODEL`) |
|
|
189
190
|
| `-c model_reasoning_effort=<effort>` | reasoning effort (wrapper default `xhigh`, pinned via `CODEX_EFFORT`) |
|
|
190
191
|
| `--ignore-user-config` | do NOT load `$CODEX_HOME/config.toml`; auth still uses `CODEX_HOME` |
|
|
191
192
|
| `--color never` | disable ANSI colour in output |
|
package/capability.json
CHANGED
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@sabaiway/agent-workflow-kit",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.45.1",
|
|
4
4
|
"description": "Portable, cross-agent memory & workflow for AI coding agents — Claude Code, Codex, Cursor, Devin Desktop. One command deploys an AGENTS.md entry point + docs/ai context with cap/archive/index enforcement into any repo.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"ai-agents",
|
|
@@ -18,7 +18,7 @@ Requires: ${CLAUDE_SKILL_DIR}/references/shared/report-footer.md · ${CLAUDE_SKI
|
|
|
18
18
|
3. **Choose conversational language — answered in the step-2 batch.** Which language should the agent *talk to them* in — questions, explanations, summaries, status updates? Offer the language they're already writing in as the default. Carry the answer into the `{{COMM_LANGUAGE}}` slot of the *Communication language* block when `AGENTS.md` is created (step 5). See [Communication contract](${CLAUDE_SKILL_DIR}/references/contracts.md#communication-contract). This sets the **dialogue** language only — never the files.
|
|
19
19
|
4. **Choose agent attribution — answered in the step-2 batch.** May the agent attribute work to itself / to AI — `Co-Authored-By` trailers, "Generated with …" footers, "AI"/agent/model mentions in code, comments, commit messages, PR titles/bodies, or docs? **Default to `off`** (no agent/AI mention anywhere) unless they opt in — people are routinely surprised to find an AI listed as a repo contributor. Carry the answer into the `{{AGENT_ATTRIBUTION}}` slot of the *Attribution* block when `AGENTS.md` is created (step 5). **If `off` and the project uses Claude Code**, also set `"includeCoAuthoredBy": false` in the project's `.claude/settings.json` (create it if absent) — the trailer is added by the harness, so a doc directive alone won't stop it. See [Attribution contract](${CLAUDE_SKILL_DIR}/references/contracts.md#attribution-contract).
|
|
20
20
|
5. **Entry-point doc.** If `AGENTS.md` / `CLAUDE.md` already exist (step-1 recon), do **not** overwrite — show the user and ask whether to merge or replace. Otherwise create `AGENTS.md` (the cross-agent standard — Codex / Cursor / Devin Desktop / Copilot read it natively) from `${CLAUDE_SKILL_DIR}/references/templates/AGENTS.md`, and symlink `CLAUDE.md -> AGENTS.md` (`ln -s AGENTS.md CLAUDE.md`) for Claude Code — single source, no duplication. For nested context, add a subdir `AGENTS.md` (+ a `CLAUDE.md` symlink beside it for Claude Code).
|
|
21
|
-
6. **Deploy `docs/ai/`.** Create every `docs/ai/` file + `pages/` + the seed `adr/` store from `${CLAUDE_SKILL_DIR}/references/templates/` (the template loop deploys each non-`AGENTS.md`, non-`adr-record.md` template — `adr-record.md` is a skill-home ADR authoring reference, never deployed). This deploys the HOT ADR window **`docs/ai/decisions.md`** and the seed navigator **`docs/ai/adr/log.md`** (its `adr/` subdir copies in wholesale), the `.md` docs, **and** the
|
|
21
|
+
6. **Deploy `docs/ai/`.** Create every `docs/ai/` file + `pages/` + the seed `adr/` store from `${CLAUDE_SKILL_DIR}/references/templates/` (the template loop deploys each non-`AGENTS.md`, non-`adr-record.md` template — `adr-record.md` is a skill-home ADR authoring reference, never deployed). This deploys the HOT ADR window **`docs/ai/decisions.md`** and the seed navigator **`docs/ai/adr/log.md`** (its `adr/` subdir copies in wholesale), the `.md` docs, **and** the four seeded, user-editable strict-JSON configs: **`docs/ai/orchestration.json`** (the per-project recipe defaults the `procedures` advisor reads), **`docs/ai/gates.json`** (the project's gate declaration — an empty list to fill with its own verification commands, consumed by `${CLAUDE_SKILL_DIR}/references/modes/gates.md`), **`docs/ai/verification-profile.json`** (the OPTIONAL fold-completeness verification profile — its seeded default reproduces the composition root's V8 + node:test behaviour, so a project deletes it to fall back to exactly that, or edits it for another language/runner), and **`docs/ai/autonomy.json`** (the per-project autonomy policy — seeded SPARSE with the onboarding note only, so it is exactly the computed defaults until the user declares levels via `/agent-workflow-kit set-autonomy` or by hand). Keep each `.md` file's frontmatter (`type / lastUpdated / scope / staleAfter / owner / maxLines`); the `.json` seeds carry no frontmatter (the docs cap-validator globs `*.md` only, so they are inherently skipped).
|
|
22
22
|
7. **Fill templates** per the table below.
|
|
23
23
|
8. **Install enforcement (Node projects).** Copy `${CLAUDE_SKILL_DIR}/references/scripts/*.mjs` (+ `*.test.mjs`) into the project's `scripts/`. They self-configure (project name from `package.json`, hierarchical/on-demand sections auto-discovered). **If the project has no Node runtime** (step-1 recon), skip this step and the hook in step 9 — follow the cap/archive/index policy manually, or port the scripts to the project's language.
|
|
24
24
|
9. **Wire / hide** per visibility (see [Visibility contract](${CLAUDE_SKILL_DIR}/references/contracts.md#visibility-contract)). Install the pre-commit hook (Node projects): `node scripts/install-git-hooks.mjs`. If the installer reports a pre-existing non-marker hook, stop and ask the user to merge it manually rather than overwriting.
|
|
@@ -6,7 +6,7 @@ The reader + consent-gated **writer** for the **host-level** bridge settings fil
|
|
|
6
6
|
|
|
7
7
|
| key | bridge | values | note |
|
|
8
8
|
|---|---|---|---|
|
|
9
|
-
| `CODEX_SERVICE_TIER` | codex | `priority` | **SPEND KNOB** — the "Fast" tier: ~1.5× token speed at a **2.5× credit rate** on gpt-5.
|
|
9
|
+
| `CODEX_SERVICE_TIER` | codex | `priority` | **SPEND KNOB** — the "Fast" tier: ~1.5× token speed at a **2.5× credit rate** on gpt-5.6-sol, quality-neutral (same model). Default unset ⇒ standard tier. |
|
|
10
10
|
| `CODEX_HARD_TIMEOUT` | codex | integer `1..86400` | hard wall-clock cap (seconds) via `timeout(1)`. |
|
|
11
11
|
| `CODEX_REVIEW_MAX_TOTAL_BYTES` | codex | integer `1..100000000` | codex-review payload size above which the diff rides a temp file (never truncated). |
|
|
12
12
|
| `AGY_HARD_TIMEOUT` | agy | duration `5m`/`30m`/`90s` (unit required, nonzero) | hard wall-clock cap via `timeout(1)`. |
|
|
@@ -1,13 +1,14 @@
|
|
|
1
1
|
### Mode: grounding
|
|
2
2
|
|
|
3
|
-
The **grounded-review facts assembler** (AD-038) — an ungrounded `agy` review GUESSES, and while the grounding contract is mechanized (`agy-review code --facts @f`), populating the facts file was a manual chore. This mode emits the
|
|
3
|
+
The **grounded-review facts assembler** (AD-038) — an ungrounded `agy` review GUESSES, and while the grounding contract is mechanized (`agy-review code --facts @f`), populating the facts file was a manual chore. This mode emits the **mechanical** facts sources of a payload (constraints / autonomy / plan / ledger digest); the orchestrator still owns any judgment-bearing additions. **Catalogued honestly as a WRITER** — `--out <path>` writes one file — with the invariant: `--out` accepts **only system-temp destinations outside the repo ($TMPDIR / /tmp — rewritable scratch) or a FRESH gitignored in-repo path (create-only, exclusive write)** and REFUSES everything else: a tracked path, an in-repo not-ignored path (a new untracked file would itself move the review fingerprint the facts are about to ground), an EXISTING in-repo file even when gitignored (the `.env` clobber class — this writer is bridge-tier auto-allowable), any other outside-repo destination, and symlink/non-regular leaves; **stdout is the default**. It never commits and never runs a subscription CLI.
|
|
4
4
|
|
|
5
|
-
Run `node ${CLAUDE_SKILL_DIR}/tools/grounding.mjs [--constraints] [--plan <path>] [--ledger-summary] [--reserve-bytes <n>] [--out <path>]`:
|
|
5
|
+
Run `node ${CLAUDE_SKILL_DIR}/tools/grounding.mjs [--constraints] [--autonomy] [--plan <path>] [--ledger-summary] [--reserve-bytes <n>] [--out <path>]`:
|
|
6
6
|
|
|
7
7
|
1. **`--constraints`** — slice the root `AGENTS.md` **Hard Constraints** section, verbatim and whole (exactly ONE matching heading; zero or several is a loud STOP, never a guess — the marker-slot discipline).
|
|
8
|
-
2. **`--
|
|
9
|
-
3. **`--
|
|
10
|
-
4.
|
|
11
|
-
5.
|
|
8
|
+
2. **`--autonomy`** (AD-044 Plan 3) — append the COMPUTED effective autonomy policy: the shared resolver (`resolveAutonomy`) over the **git-top** `docs/ai/autonomy.json` renders every red-line + per-activity level with a stated source line. An ABSENT file is exit 0 — the computed defaults ARE the effective policy (unlike `velocity-profile --autonomy`, which writes settings and refuses an undeclared policy); a malformed/unreadable policy fails CLOSED (exit 1). Informational for the reviewing backend — enforcement stays the OS sandbox + the orchestrator. Rides between the constraints and the plan sections.
|
|
9
|
+
3. **`--plan <path>`** — extract the plan's decision-bearing canonical sections, verbatim + whole: `## Approach` (REQUIRED — its "What we are NOT doing" text rides inside; it is not a heading in canon) and `## Verification` (REQUIRED — STOP if missing), plus `## Decisions (locked)` when present (the optional engine §7 heading); a DUPLICATE heading is always a STOP.
|
|
10
|
+
4. **`--ledger-summary`** (BUGFREE-3 / AD-049) — append a COMPUTED review-ledger digest for the SINGLE in-flight `plan-execution` segment: the round/origin/classification/verdict/override counts (filtered to that loop + base — unrelated loops excluded) plus a terse per-round render. "Computed, not remembered" facts — the reviewer sees the loop's own history without the orchestrator hand-copying it. A loud STOP unless exactly one plan is in flight; read-only (the ledger is never written here).
|
|
11
|
+
5. **Byte budget** — the output honors the same `AGY_MAX_PROMPT_BYTES` contract the agy wrapper enforces (override may only tighten; the OS argv ceiling is rejected), MINUS **`--reserve-bytes <n>`** — the artifact share the caller expects `agy-review` to add around these facts. Overflow is trimmed tail-first with a loud in-band marker + stderr report — never a silent cut.
|
|
12
|
+
6. Feed the result to the wrapper: `agy-review code --facts @<out>`. The `procedures` advisor renders this invocation as a concrete pre-step whenever the resolved review dispatch includes agy — populated with the in-flight plan path when exactly one plan is in flight.
|
|
12
13
|
|
|
13
|
-
**Invariants:** writer (writes at most the ONE `--out` scratch file — gitignored
|
|
14
|
+
**Invariants:** writer (writes at most the ONE `--out` scratch file — system-temp, or a fresh gitignored in-repo path, exclusive-create) · never commits · never runs a subscription CLI · verbatim slices only (assembly is mechanical; facts judgment stays with the orchestrator).
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
### Mode: recommendations
|
|
2
|
+
|
|
3
|
+
The **read-only deployment advisor** — the deterministic section every `upgrade` run ends with, also invocable on its own. It computes what in THIS deployment is configured sub-optimally (allowlist not seeded, autonomy render drifted, sandbox unavailable, gates undeclared, bridge friction, sandbox-mask clutter) and renders each item as **{what is sub-optimal · the benefit in ONE plain line · the exact consent-gated apply one-liner}**. The tool computes; **you paste the section VERBATIM** (the `composeStatusLine` precedent) — you compose nothing factual.
|
|
4
|
+
|
|
5
|
+
Run `node ${CLAUDE_SKILL_DIR}/tools/recommendations.mjs --cwd <project-root> [--json]`:
|
|
6
|
+
|
|
7
|
+
1. **`--cwd` is REQUIRED** — the target project is explicit, never inferred from the shell's current directory (a subdirectory invocation still advises on the named root).
|
|
8
|
+
2. **Paste the whole rendered section verbatim**, starting at its `## Recommendations (agent-workflow)` header. It renders **present-even-when-empty**: with everything optimal the body is exactly `no recommendations — flow optimal.` A failed probe renders as a stated `⚠ skipped item …` line — never a crash, never a fabricated item.
|
|
9
|
+
3. **The apply-through-agent lane (consent-first):** after pasting, OFFER to apply; the user picks items in plain language; you run **EXACTLY the rendered one-liners — no improvisation** (each writer keeps its own consent semantics: previews, `--apply` flags, refusals). An item marked **HAND-APPLY** (the network-allowlist item) is **never run by you and never written by the kit** — the user pastes it by hand if they accept the stated risk; the hosts come from each bridge's `capability.json` `networkHosts` (the single documentation source).
|
|
10
|
+
4. Benefit lines are frozen tool data, fact-true: the dual velocity+security wording (`safer — blast radius bounded by the OS sandbox, not human attention`) rides ONLY the items with a real security delta (the autonomy render, the sandbox provisioning); the bridge-wrappers item claims **velocity only**, and risk-bearing items state their risk in the same line.
|
|
11
|
+
|
|
12
|
+
**Invariants:** read-only (never writes, never commits, never runs a subscription CLI) · `--cwd` required · present-even-when-empty · probe failures degrade to stated skip lines · apply one-liners are cwd-independent (absolute tool paths + a pinned `--cwd`; the sandbox-provision item pins via a `cd <root> &&` prefix — the doctor reads its cwd; the ONE exception is the `set-autonomy` item, a conversational skill invocation explicitly labeled *run IN the target project*) · the kit never seeds `sandbox.network.allowedDomains` / `sandbox.filesystem.allowWrite` (hand-apply territory, risk stated).
|
|
13
|
+
|
|
14
|
+
**Exit codes:** `0` report rendered (items or the empty state); `1` error (e.g. `--cwd` is not a directory); `2` usage.
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
### Mode: review-state
|
|
2
2
|
|
|
3
|
-
Read-only **review-receipt checker** (AD-038) — it makes *"reviewed ≠ shipped"* mechanically detectable. The bridge review wrappers (`codex-review` / `agy-review`, from bridge version 2.2.0) append one receipt line per **successful** review to a file **inside the git dir** (`<git dir>/agent-workflow-review-receipts.jsonl` — never committable by construction; `AW_REVIEW_RECEIPTS` overrides). This mode resolves the effective `plan-execution.review` recipe (the SAME config + read-only detector the `procedures` advisor reads), recomputes the canonical **uncommitted-state fingerprint** (staged + unstaged + untracked-not-ignored contents — exactly the review-payload domain; the prose definition lives in each bridge's `capability.json` review contract, implementations cross-checked by the kit's fingerprint-parity test), and reports, per recipe-named backend, whether a **fresh, grounded, current-fingerprint** receipt exists. It **never writes, never commits, never runs a subscription CLI**; it does spawn **read-only `git` queries** to compute the fingerprint — stated honestly (that is still read-only, but it is a subprocess).
|
|
3
|
+
Read-only **review-receipt checker** (AD-038) — it makes *"reviewed ≠ shipped"* mechanically detectable. The bridge review wrappers (`codex-review` / `agy-review`, from bridge version 2.2.0) append one receipt line per **successful** review to a file **inside the git dir** (`<git dir>/agent-workflow-review-receipts.jsonl` — never committable by construction; `AW_REVIEW_RECEIPTS` overrides). This mode resolves the effective `plan-execution.review` recipe (the SAME config + read-only detector the `procedures` advisor reads), recomputes the canonical **uncommitted-state fingerprint** (staged + unstaged + untracked-not-ignored contents — exactly the review-payload domain; never-committable untracked paths — character/block devices, FIFOs, sockets — are excluded from the domain entirely, so sandbox-injected device masks can never move the fingerprint; the prose definition lives in each bridge's `capability.json` review contract, implementations cross-checked by the kit's fingerprint-parity test), and reports, per recipe-named backend, whether a **fresh, grounded, current-fingerprint** receipt exists. It **never writes, never commits, never runs a subscription CLI**; it does spawn **read-only `git` queries** to compute the fingerprint — stated honestly (that is still read-only, but it is a subprocess).
|
|
4
4
|
|
|
5
5
|
Run `node ${CLAUDE_SKILL_DIR}/tools/review-state.mjs [--check] [--json]`:
|
|
6
6
|
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
### Mode: sandbox-masks
|
|
2
|
+
|
|
3
|
+
**Cosmetic exclude lane for sandbox-injected device masks** (AD-044). An OS sandbox (Claude Code) injects character-device masks into the work tree (`.bashrc`, `.gitconfig`, `.vscode`, …); git lists them as untracked noise. The **review domain already ignores them by construction** — never-committable untracked classes (character/block devices, FIFOs, sockets) are excluded from the fingerprint, the assembled review payload, and the clean checks in both bridge wrappers and the kit checker. This mode is the optional **cosmetic** half: it hides the masks from `git status` (and every other `--exclude-standard` untracked walk) via **one managed fenced block** in the file `git rev-parse --git-path info/exclude` names.
|
|
4
|
+
|
|
5
|
+
Run `node ${CLAUDE_SKILL_DIR}/tools/sandbox-masks.mjs [--cwd <project-root>]`:
|
|
6
|
+
|
|
7
|
+
1. **Flagless → READ-ONLY probe/preview.** Derives the CURRENT mask set from the **unfiltered** untracked walk (`git ls-files --others -z`, without standard excludes — an already-hidden mask stays visible to a rerun) plus lstat classification. Only the never-committable classes are ever candidates; tracked / regular / directory / symlink / gitlink / missing paths can never enter the block **by construction**. The probe also **revalidates** the existing fenced entries and loudly flags any that became a REAL path. It prints the exact apply one-liner.
|
|
8
|
+
2. **`--apply` → consent-gated FULL-BLOCK REPLACE** from a fresh derivation — stale masks drop by construction, never append-only. Run it **inside the sandbox** (masks are visible only there). An apply whose derivation is EMPTY while a non-empty block exists refuses loudly (you are probably outside the sandbox) unless `--clear` is also given; an empty derivation with no block is a stated no-op. `--clear` always means **remove the managed block** — it takes precedence over the derivation, even while masks are visible.
|
|
9
|
+
3. **Writes ONLY its own fenced block** — never `.gitignore`, never a global excludesFile, never outside the fence. A malformed fence (start without end, duplicated markers) **fails closed**: loud report, file untouched. The fence is separate from the hidden-mode reconcile's block.
|
|
10
|
+
|
|
11
|
+
**Where the need surfaces on its own (no standing detector):** `review-state --check` prints one non-failing notice with this mode's apply one-liner whenever it observes filtered-class untracked paths, and the upgrade **Recommendations** section carries the same item (the probe is exported to the advisor — `${CLAUDE_SKILL_DIR}/references/modes/recommendations.md`) — a NEW mask appearing after a sandbox update surfaces its own fix at the next check or upgrade.
|
|
12
|
+
|
|
13
|
+
**Watch note (D5):** an exclude rule hides a path from `git status` **AND from bulk staging** — a real file at an excluded path is silently skipped by `git add -A`/`git add .` (an explicit `git add <path>` refuses without `-f`), so it would stay out of your commits; `.git/info/exclude` never warns. Before creating a REAL file at a masked path (e.g. a real `.vscode/`), delete the matching line from the managed block first — the probe flags exactly this case.
|
|
14
|
+
|
|
15
|
+
**Invariants:** flagless run is read-only · `--apply` writes only the managed block in the repo-local exclude file · probe-derived membership, never a hardcoded list · fail-closed on a malformed fence · never commits, never touches `.gitignore` or any global git config.
|
|
@@ -4,17 +4,17 @@ Requires: ${CLAUDE_SKILL_DIR}/references/shared/report-footer.md · ${CLAUDE_SKI
|
|
|
4
4
|
|
|
5
5
|
1. Read `docs/ai/.workflow-version` (the project's stamped lineage). If missing, treat as a pre-versioned deployment and offer to re-bootstrap conservatively.
|
|
6
6
|
2. **Never-downgrade gate — FIRST, before any write.** Compare the stamp to the **deployment-lineage head** (`2.0.0` — NOT this kit's package version). If the stamp is **greater than the head** or unparseable → **STOP and report**; do not touch a newer / unknown deployment at all (not even the methodology slot). This STOP is one of the few places the number is actionable (*Version disclosure* in `${CLAUDE_SKILL_DIR}/references/shared/report-footer.md`): show the user **the `docs/ai` structure version** their deployment carries versus the one this kit expects, plus the plain one-line two-axes note — naming it the structure version, **never** "lineage head".
|
|
7
|
-
3. **Reconcile the bounded pointers — stamp-independent, BEFORE the equal-head short-circuit.** Reached only when the stamp **≤ head**. Run `node ${CLAUDE_SKILL_DIR}/tools/inject-methodology.mjs reconcile <project>/AGENTS.md`. ONE call reconciles **
|
|
7
|
+
3. **Reconcile the bounded pointers — stamp-independent, BEFORE the equal-head short-circuit.** Reached only when the stamp **≤ head**. Run `node ${CLAUDE_SKILL_DIR}/tools/inject-methodology.mjs reconcile <project>/AGENTS.md`. ONE call reconciles **three** pointers — the **workflow-methodology** pointer, the **orchestration-recipes** pointer (Solo / Reviewed / Council / Delegated, routing to `/agent-workflow-kit recipes`) right below it, and the **autonomy-policy** pointer (the `docs/ai/autonomy.json` read contract, routing to `/agent-workflow-kit set-autonomy`) below that — and is filled on **every** upgrade, idempotently (zero-diff when all are already present + filled), so even a legacy / current **`2.0.0`** deployment gains them **without a lineage-head bump or a migration** (the deployment-lineage head stays `2.0.0`; the `agent-workflow-memory` **package** template did get docs-only headroom trims for the chained pointers, but no deployed-`docs/ai` structure changed). Per slot it inserts an empty pair at its anchor if absent, preserves a customized pair verbatim, and STOPs (never edits) on a malformed pair, a missing / duplicate anchor, or **when a fill is needed but the installed `agent-workflow-engine` is absent/invalid** (the fragments are read live from it — see the distinct outcomes below).
|
|
8
8
|
|
|
9
9
|
**Classify the exit — there are THREE non-zero exits + one soft in-band skip; handle each differently:**
|
|
10
10
|
|
|
11
|
-
(a) **Soft, reported skip of
|
|
11
|
+
(a) **Soft, reported skip of a CHAINED pointer — orchestration and/or autonomy (CONTINUE the upgrade).** The chained pointers are the less-critical ones; when one can't be added right now `reconcile` exits **zero**, keeps every prior fill, and **reports each skip on stdout** (the `… skipped …` line) — never silent (Hard Constraint). Three reasons: **(i)** the prior pointers fit but adding this one would push the file past the `AGENTS.md` 100-line cap; **(ii)** the installed `agent-workflow-engine` is **present but too old** to ship that fragment (`<1.2.0` lacks the recipes one; every engine before the autonomy release lacks the autonomy one) — it can still supply the earlier pointers, so only that pointer is withheld; or **(iii)** — autonomy only — its **anchor is absent** because the orchestration pair is itself absent or was skipped, so the autonomy pointer has nowhere to chain (add the orchestration pointer first, then re-run). Report it in the successful-exit report (**step 4** equal-head, else **step 8**) in plain language, e.g. *"The orchestration-recipes / autonomy pointer wasn't added — the entry point is at its 100-line limit / your methodology engine is older than that feature. The recipes stay available via `/agent-workflow-kit recipes` and the autonomy policy via `/agent-workflow-kit set-autonomy`; to add the pointer, trim the entry point and/or refresh the engine with `npx @sabaiway/agent-workflow-engine@latest init`, then re-run upgrade."* (The separate case where the **methodology** pointer ITSELF can't fit the cap is a non-zero exit that changes nothing — continue without the pointers, same plain-language framing.)
|
|
12
12
|
|
|
13
|
-
(b) **Malformed pair / missing-or-duplicate anchor (
|
|
13
|
+
(b) **Malformed pair / missing-or-duplicate anchor (any pointer) — a hard STOP (do NOT continue).** A non-zero exit whose message names a marker/anchor problem; never soft-skip it. (The one deliberate exception is (a)(iii): the autonomy pointer's ABSENT anchor is the chained soft skip, exit zero — a reported skip, not this STOP.)
|
|
14
14
|
|
|
15
|
-
(c) **`methodology engine not found/invalid …` — a hard STOP (do NOT continue).** A fill was needed but the installed `agent-workflow-engine` is **fully absent/invalid** — it can supply **
|
|
15
|
+
(c) **`methodology engine not found/invalid …` — a hard STOP (do NOT continue).** A fill was needed but the installed `agent-workflow-engine` is **fully absent/invalid** — it can supply **no** fragment (distinct from (a)(ii), where the engine is valid but merely too old for a chained one). Report it in plain language with the one-line install command `npx @sabaiway/agent-workflow-engine@latest init` (or note that `npx @sabaiway/agent-workflow-kit@latest init` installs the engine for you), then re-run upgrade once it is present. **Never** treat (c) as a soft-skip (a) — mis-handling it would silently drop a pointer (a no-silent-failures violation). (b) and (c) STOP the upgrade; only (a) continues.
|
|
16
16
|
|
|
17
|
-
**No-Node project:** the fragments live only in the **installed `agent-workflow-engine`** (`references/methodology-slot.md` + `references/orchestration-slot.md`, under `~/.claude/skills/agent-workflow-engine` or `$AGENT_WORKFLOW_ENGINE_DIR`) — there is no bundled copy, and a No-Node host cannot run the `npx` engine install. Open `AGENTS.md` and classify **each** pointer by hand: a **filled / customized** pair → leave it verbatim (no engine needed); a **malformed** pair (not exactly one ordered `start → end`) → STOP, do not edit. A pair that needs filling — **absent markers OR a present-but-empty pair** — needs the engine's fragment, so: if the engine is **not installed**, that pointer **cannot be added** — report it plainly (the methodology is already in `docs/ai/agent_rules.md`; the recipes are available via `/agent-workflow-kit recipes`; install the engine to add the pointers). If the engine **is** present, **count the lines first** — if adding/filling would take the file over 100 lines, **skip that pointer and report the skip** (methodology first, then orchestration;
|
|
17
|
+
**No-Node project:** the fragments live only in the **installed `agent-workflow-engine`** (`references/methodology-slot.md` + `references/orchestration-slot.md` + `references/autonomy-slot.md`, under `~/.claude/skills/agent-workflow-engine` or `$AGENT_WORKFLOW_ENGINE_DIR`) — there is no bundled copy, and a No-Node host cannot run the `npx` engine install. Open `AGENTS.md` and classify **each** pointer by hand: a **filled / customized** pair → leave it verbatim (no engine needed); a **malformed** pair (not exactly one ordered `start → end`) → STOP, do not edit. A pair that needs filling — **absent markers OR a present-but-empty pair** — needs the engine's fragment, so: if the engine is **not installed**, that pointer **cannot be added** — report it plainly (the methodology is already in `docs/ai/agent_rules.md`; the recipes are available via `/agent-workflow-kit recipes`; the autonomy policy via `/agent-workflow-kit set-autonomy`; install the engine to add the pointers). If the engine **is** present, **count the lines first** — if adding/filling would take the file over 100 lines, **skip that pointer and report the skip** (methodology first, then orchestration, then autonomy; each chained pair sits right under the previous pair's end marker). Fill each empty pair from its engine fragment (`methodology-slot.md` / `orchestration-slot.md` / `autonomy-slot.md`) — never inline a copy (that would re-create the retired mirror).
|
|
18
18
|
|
|
19
19
|
**Hidden-mode footprint reconcile — stamp-independent, same gate, BEFORE the equal-head short-circuit (D9 / AD-014).** A deployment does not record whether it chose `hidden`, so first **infer visibility**: `node ${CLAUDE_SKILL_DIR}/tools/hide-footprint.mjs --dir <project> --reconcile --dry-run` (writes **zero bytes**). It reports one of — **visible** (the entry point is tracked) → nothing to do; **ambiguous** (untracked but not ignored — could be a fresh uncommitted repo, or a hide that broke) → **ASK** the user which it is, never guess; **hidden** → re-run without `--dry-run` to migrate any older **machine-global** hide to the **project-local** `.git/info/exclude` (one managed block; folds in the legacy `.claude/skills/` line), idempotently (a clean re-run is zero-diff). Handle its surfaced paths exactly as bootstrap step 9 (`${CLAUDE_SKILL_DIR}/references/modes/bootstrap.md`) (already-committed → show `git rm --cached`, ask before `--include`; generic-name present file → ask; **leftover machine-wide ignore block → ASK before `--remove-global`**, default keep + report). No Node on the agent host / Windows → as bootstrap step 9 (`${CLAUDE_SKILL_DIR}/references/modes/bootstrap.md`). This runs on **every** hidden upgrade, like the methodology slot — no lineage-head bump, no migration file.
|
|
20
20
|
|
|
@@ -24,6 +24,8 @@ Requires: ${CLAUDE_SKILL_DIR}/references/shared/report-footer.md · ${CLAUDE_SKI
|
|
|
24
24
|
|
|
25
25
|
**Verification-profile ensure (seed-if-missing) — stamp-independent, same gate, BEFORE the equal-head short-circuit.** Ensure `docs/ai/verification-profile.json` exists: **create it from `${CLAUDE_SKILL_DIR}/references/templates/verification-profile.json` if missing** (the kit's OWN template twin, so the fallback/stale-memory path still gains the OPTIONAL fold-completeness profile); **an existing file is preserved byte-for-byte** (a project may have edited it for its language/runner). An ABSENT profile reproduces the default V8 + node:test behaviour, so this ensure only ADDS the opt-in default. Report it in the step 4 / step 8 report (*seeded* / *already present*). Like the config + gate ensures, no lineage-head bump or migration file (a `.json`, outside the docs cap-validator).
|
|
26
26
|
|
|
27
|
+
**Autonomy-declaration ensure (seed-if-missing) — stamp-independent, same gate, BEFORE the equal-head short-circuit.** Ensure `docs/ai/autonomy.json` exists: **create it from `${CLAUDE_SKILL_DIR}/references/templates/autonomy.json` if missing** (the kit's OWN template twin, mirrored from memory — so a stale memory never silently loses the seed); **an existing file is preserved byte-for-byte** (a declared policy is authored content — never clobbered, never refreshed in place). The seed is SPARSE (the onboarding note only) and **defaults-equivalent** — deploying it never changes behavior (the computed defaults stay the policy until the user declares levels with `/agent-workflow-kit set-autonomy` or by hand). Report it in the step 4 / step 8 success report (*seeded* / *already present, preserved*). Like the other config ensures, no lineage-head bump or migration file (a `.json`, outside the docs cap-validator).
|
|
28
|
+
|
|
27
29
|
**Enforcement-script ensure (seed-if-missing) — stamp-independent, same gate, BEFORE the equal-head short-circuit.** A deployment older than the ADR-cascade feature has no `scripts/archive-decisions.mjs`, and an equal-head exit would otherwise never deliver it. Ensure the pair exists in the project's `scripts/`: **copy `archive-decisions.mjs` + `archive-decisions.test.mjs` from `${CLAUDE_SKILL_DIR}/references/scripts/` if missing** (the kit's own fallback copies — byte-identical to the memory canon by the mirror guard); **an existing file is preserved, never overwritten** (drift repair belongs to a lineage migration, not this ensure). **OLD ADR-store layout — DETECT FIRST, never auto-migrate (AD-051, Decision 13):** if the project still carries a `docs/ai/history/decisions-archive*.md` monolith (the `adrLayout: "old"` signal `status` surfaces), it is on the RETIRED 3-tier cascade — **do NOT seed or refresh the now one-file-per-ADR rotator here** (the new `archive-decisions.mjs` beside un-migrated monoliths would red their ADR gate). Instead surface a LOUD instruct: run the opt-in **`/agent-workflow-kit migrate-adr-store`** (it snapshots, refreshes the scripts, and migrates in one consent-gated step; previews first, never commits). The seed-if-missing above applies ONLY to a clean layout (no monolith). The deployed pre-commit hook gains the `archive-decisions.mjs --check` line only when the hook itself is next refreshed (re-run `node scripts/install-git-hooks.mjs` after the ensure and it will refuse a non-marker hook as always); an OLD hook without the line stays consistent-safe — the decisions gate is simply not enforced yet, never a broken hook. Skip this ensure on a No-Node project (the scripts are Node enforcement). Report it in the step 4 / step 8 success report (*added* / *already present* / *old ADR layout — migration instructed*).
|
|
28
30
|
|
|
29
31
|
**Placed-bridge refresh — stamp-independent, same gate, BEFORE the equal-head short-circuit.** Run
|
|
@@ -54,11 +56,12 @@ Requires: ${CLAUDE_SKILL_DIR}/references/shared/report-footer.md · ${CLAUDE_SKI
|
|
|
54
56
|
**NEVER writes** it (the file lives outside every kit tree — D2), so an unknown/retired key is
|
|
55
57
|
flagged + preserved, never edited. Runs on **every** upgrade; exit 0 covers every outcome.
|
|
56
58
|
4. **Equal-head exit — a real successful-exit report, not a bare stop.** If the stamp **equals** the head, the lineage is up to date — but step 3 (the stamp-independent reconciles) ran first and may have changed things, so this is a proper exit report, not a no-op:
|
|
57
|
-
- **Report step 3's outcome in plain language** — for **each** pointer (workflow-methodology and
|
|
59
|
+
- **Report step 3's outcome in plain language** — for **each** pointer (workflow-methodology, orchestration-recipes and autonomy-policy) whether it was *added*, was *already present* (nothing changed), or was *skipped* (the soft-skip from step 3, with its reason — over the line limit / engine too old / the autonomy pointer's anchor absent); whether the `docs/ai/orchestration.json` config was *seeded* (created from the template), had its onboarding note *refreshed*, was *already current*, or carried a *customized note that was preserved* (a user edit is never clobbered); whether the `docs/ai/gates.json` gate declaration was *seeded* or was *already present* (preserved byte-for-byte); whether the `docs/ai/verification-profile.json` profile was *seeded* or was *already present* (preserved byte-for-byte); whether the `docs/ai/autonomy.json` declaration was *seeded* (the sparse defaults-equivalent note) or was *already present* (preserved byte-for-byte); whether the enforcement-script ensure *added* the `archive-decisions` pair to `scripts/`, found it *already present*, or found an *old ADR layout — migration instructed*; the **placed-bridge refresh** outcome — paste the tool's per-bridge lines verbatim (they are already plain: *refreshed* / *already current* / *skipped — not placed* / *could not refresh* + recovery); the **agent-rules lens** outcome (*refreshed* / *already current* / *custom edit preserved + note* / *file absent* / *engine too old* / *over the line cap*); the **bridge-settings reconcile** outcome (paste the tool's line verbatim); and, for a hidden deployment, whether the hidden-mode footprint was *moved to project-local*, was *already project-local* (nothing changed), or needed a question (ambiguous visibility / a leftover machine-wide block). Plain wording only — never the reconcile/slot/anchor/marker terms (the never-leak-kit-internals Gotcha — `${CLAUDE_SKILL_DIR}/references/shared/deploy-tail.md`).
|
|
58
60
|
- **Never surface the structure number on this exit.** Whatever step 3 did, do **not** recite the `docs/ai` structure version, the internal versioning vocabulary, or the two-axes note here — the number is inert on an equal-head exit; it belongs to *Version disclosure* in `${CLAUDE_SKILL_DIR}/references/shared/report-footer.md` (shown at the never-downgrade STOP, the explicit status view, or on an explicit ask). Frame the success itself per the final bullet: if step 3 changed anything, say **what changed** in plain human terms; only a pure zero-diff no-op is *settings already current — no update needed*.
|
|
61
|
+
- **Render the mandatory Recommendations section — on this exit too, BEFORE the footer.** Run `node ${CLAUDE_SKILL_DIR}/tools/recommendations.mjs --cwd <project-root>` and paste its output VERBATIM from the `## Recommendations (agent-workflow)` header (present-even-when-empty — with everything optimal the body is exactly `no recommendations — flow optimal.`). Then OFFER the consent-gated applies: the user picks items in plain language and you run EXACTLY the rendered one-liners (a HAND-APPLY item is never run by you) — the full lane in `${CLAUDE_SKILL_DIR}/references/modes/recommendations.md`. Pinned order on this exit: Recommendations block → optional applies → report footer → the commit ask (the advisor/apply lane never lands after the commit ask).
|
|
59
62
|
- **Print the report footer** in the canonical order (version block → one-line backend-status line → welcome mat — the shared contracts in `${CLAUDE_SKILL_DIR}/references/shared/report-footer.md`; rendered from the helpers, same host-can't-run skip-with-reason). The welcome mat closes on **one** caveat-aware next step (a behind member first, else `setup` / `recipes` / `velocity` / `agents` / `hook`).
|
|
60
63
|
- **Then ask before committing — never auto-commit.** If step 3 added the slot (or anything else changed), report it and ask. If step 3 was a pure zero-diff no-op and nothing else changed, give the plain **settings already current — no update needed** message (the *Success state* contract in `${CLAUDE_SKILL_DIR}/references/shared/report-footer.md`) and still print the read-only version block (installed package versions) + backend line — but **no `docs/ai` structure version and no two-axes note** (nothing changed, so the number is inert here).
|
|
61
64
|
5. Show the relevant `${CLAUDE_SKILL_DIR}/CHANGELOG.md` diff (entries newer than the project's stamp).
|
|
62
65
|
6. **Collect the migration answers FIRST, then apply.** If `AGENTS.md` is missing BOTH the *Communication language* and *Attribution* blocks — i.e. both blocks are missing (a pre-1.1.0 deployment) — ask the two questions as ONE structured multi-question prompt; record each answer individually, write nothing until ALL are answered, and carry the answers into the migrations below: a migration whose answer was already collected never re-asks (its own "Ask the user" step is the standalone fallback); a single missing block keeps its single ask (step 7). Then apply `${CLAUDE_SKILL_DIR}/migrations/<version>-<slug>.md` in **semver order**, only those newer than the project's stamp. Migrations are **idempotent** — safe to re-run.
|
|
63
66
|
7. Reconcile drift: add any kernel files/scripts the project is missing; never clobber project-authored content (their `decisions.md`, `known_issues.md`, page specs stay). Any user question a migration raises follows the same rule as bootstrap — **structured multiple-choice where supported** (`AskUserQuestion` in Claude Code), otherwise prose. If `AGENTS.md` has no *Communication language* block (pre-1.1.0 deployment), **ask the user their conversational language** and insert the block — see `migrations/1.1.0-communication-language.md`. If it has no *Attribution* block (pre-1.2.0 deployment), **ask whether the agent may attribute work to itself / AI** and insert the block (defaulting to `off`) — see `migrations/1.2.0-agent-attribution.md`. (An answer already collected by the step-6 batched prompt is carried in — never re-asked here.)
|
|
64
|
-
8. Re-stamp `docs/ai/.workflow-version` to the **deployment-lineage head** (`2.0.0`, not the package version — mechanics unchanged: the atomic write to the stamp file). In the report, **describe what the upgrade changed in plain human terms** — which parts of their `docs/ai` are now different (the migrations that ran), plus the step-3 **placed-bridge refresh** lines (pasted verbatim), the step-3 **agent-rules lens** outcome (same outcome set as step 4),
|
|
67
|
+
8. Re-stamp `docs/ai/.workflow-version` to the **deployment-lineage head** (`2.0.0`, not the package version — mechanics unchanged: the atomic write to the stamp file). In the report, **describe what the upgrade changed in plain human terms** — which parts of their `docs/ai` are now different (the migrations that ran), plus the step-3 **placed-bridge refresh** lines (pasted verbatim), the step-3 **agent-rules lens** outcome (same outcome set as step 4), the step-3 **bridge-settings reconcile** outcome, and the step-3 **autonomy-declaration ensure** outcome (*seeded* / *already present, preserved*) — rather than reciting a version number; **omit the raw structure number**, and do **not** print the two-axes note here (it belongs to *Version disclosure* in `${CLAUDE_SKILL_DIR}/references/shared/report-footer.md`, on demand only). Then **render the mandatory Recommendations section**: run `node ${CLAUDE_SKILL_DIR}/tools/recommendations.mjs --cwd <project-root>`, paste its output VERBATIM from the `## Recommendations (agent-workflow)` header (present-even-when-empty: `no recommendations — flow optimal.`), and OFFER the consent-gated applies (run EXACTLY the rendered one-liners; a HAND-APPLY item is never run by you — `${CLAUDE_SKILL_DIR}/references/modes/recommendations.md`). Then **print the report footer** in the canonical order (version block → one-line backend-status line → welcome mat — the shared contracts in `${CLAUDE_SKILL_DIR}/references/shared/report-footer.md`; rendered from the helpers, same host-can't-run skip-with-reason; the welcome mat closes on one caveat-aware next step). Then **ask before committing** — the pinned order on this exit is: Recommendations block → optional applies → report footer → the commit ask.
|