@sabaiway/agent-workflow-kit 1.30.0 → 1.32.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/CHANGELOG.md +75 -0
- package/README.md +5 -2
- package/SKILL.md +31 -551
- package/capability.json +1 -1
- package/launchers/windsurf-workflow.md +4 -2
- package/package.json +1 -1
- package/references/hooks/gate-approve.mjs +13 -0
- package/references/modes/agents.md +11 -0
- package/references/modes/backends.md +9 -0
- package/references/modes/bootstrap.md +49 -0
- package/references/modes/gates.md +17 -0
- package/references/modes/grounding.md +12 -0
- package/references/modes/help.md +7 -0
- package/references/modes/hook.md +24 -0
- package/references/modes/procedures.md +18 -0
- package/references/modes/recipes.md +18 -0
- package/references/modes/review-state.md +13 -0
- package/references/modes/set-recipe.md +24 -0
- package/references/modes/setup.md +30 -0
- package/references/modes/status.md +22 -0
- package/references/modes/uninstall.md +18 -0
- package/references/modes/upgrade.md +46 -0
- package/references/modes/velocity.md +33 -0
- package/references/shared/composition-handoff.md +39 -0
- package/references/shared/deploy-tail.md +61 -0
- package/references/shared/report-footer.md +116 -0
- package/tools/engine-source.mjs +2 -1
- package/tools/velocity-profile.mjs +253 -32
package/capability.json
CHANGED
|
@@ -14,8 +14,10 @@ reinvent any of it here; the kit's `SKILL.md` is the single source of truth.
|
|
|
14
14
|
|
|
15
15
|
## Steps
|
|
16
16
|
|
|
17
|
-
1. Read the kit instructions in full: `<KIT_DIR>/SKILL.md
|
|
18
|
-
|
|
17
|
+
1. Read the kit instructions in full: `<KIT_DIR>/SKILL.md` (the thin router), plus the
|
|
18
|
+
`references/` files it points to — the chosen mode's `<KIT_DIR>/references/modes/<mode>.md`
|
|
19
|
+
and any `references/shared/` files that mode's `Requires:` line names. Wherever it says
|
|
20
|
+
`${CLAUDE_SKILL_DIR}`, read that as `<KIT_DIR>`.
|
|
19
21
|
2. Pick the mode:
|
|
20
22
|
- No `docs/ai/` in this project → **bootstrap**.
|
|
21
23
|
- `docs/ai/` already exists → ask the user whether to run **upgrade** instead.
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@sabaiway/agent-workflow-kit",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.32.0",
|
|
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",
|
|
@@ -71,6 +71,13 @@ export const SEEDED_READONLY_CORE = Object.freeze([
|
|
|
71
71
|
'Bash(git ls-files:*)',
|
|
72
72
|
'Bash(git check-ignore:*)',
|
|
73
73
|
'Bash(git branch --list:*)',
|
|
74
|
+
'Bash(git rev-parse:*)',
|
|
75
|
+
'Bash(git blame:*)',
|
|
76
|
+
'Bash(git shortlog:*)',
|
|
77
|
+
'Bash(git describe:*)',
|
|
78
|
+
'Bash(git tag --list:*)',
|
|
79
|
+
'Bash(git stash list:*)',
|
|
80
|
+
'Bash(git worktree list:*)',
|
|
74
81
|
'Bash(npm view:*)',
|
|
75
82
|
'Bash(npm ls:*)',
|
|
76
83
|
'Bash(npm outdated:*)',
|
|
@@ -82,6 +89,12 @@ export const SEEDED_READONLY_CORE = Object.freeze([
|
|
|
82
89
|
'Bash(readlink:*)',
|
|
83
90
|
'Bash(which:*)',
|
|
84
91
|
'Bash(grep:*)',
|
|
92
|
+
'Bash(diff:*)',
|
|
93
|
+
'Bash(stat:*)',
|
|
94
|
+
'Bash(du:*)',
|
|
95
|
+
'Bash(basename:*)',
|
|
96
|
+
'Bash(dirname:*)',
|
|
97
|
+
'Bash(realpath:*)',
|
|
85
98
|
]);
|
|
86
99
|
|
|
87
100
|
// Baked frozen copy of velocity-profile.mjs RUNTIME_RESIDUAL_FORMS (the documented residual a
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
### Mode: agents
|
|
2
|
+
|
|
3
|
+
The opt-in **cheap-lane subagent writer** — the family's second `.claude/` writer, on the velocity discipline. It places the bundled cheap-lane subagent definitions (`references/agents/*.md`) into the project's `.claude/agents/` so mechanical work — extraction sweeps, changelog fact-skeletons, gate-failure triage — runs on a **cheap model** (`model: haiku`, `effort: low`, bounded read-only tools) instead of the frontier main lane. **Claude-Code-specific** (like velocity): other agent hosts ignore `.claude/agents/`. Judgment, review, real code, and user-facing copy never move to these vehicles — they are extraction/drafting only, and the orchestrator verifies their output.
|
|
4
|
+
|
|
5
|
+
Run `node ${CLAUDE_SKILL_DIR}/tools/cheap-agents.mjs [--dry-run | --apply] [--cwd <dir>]`:
|
|
6
|
+
|
|
7
|
+
1. **`--dry-run` first, always** (the default — changes nothing). It previews, per bundled vehicle, whether it **would place** the file, finds it **already current**, or finds a **customized** file (different content) that will be **preserved, never overwritten** (delete the file to reseed it from the bundle).
|
|
8
|
+
2. **Only on an explicit yes**, re-run with `--apply`. It writes **only** under `.claude/agents/` — never `settings.json` / `settings.local.json`, never a commit. `--apply` is deployment-gated (the stamp must be at the lineage head) and symlink-safe (a symlinked `.claude` / `.claude/agents` / target file is a STOP).
|
|
9
|
+
3. **Hidden-mode deployments:** after apply, run the hide-footprint reconcile (`node ${CLAUDE_SKILL_DIR}/tools/hide-footprint.mjs --dir <project> --reconcile`) so the placed files stay invisible to `git status` — `/.claude/agents/` is in the known-footprint registry; the apply report reminds you.
|
|
10
|
+
|
|
11
|
+
**Invariants:** writer (writes only `.claude/agents/`) · preview by default · a diverged existing file is reported and preserved, never clobbered · never touches settings · never commits · vehicles are pinned to `model: haiku` + `effort: low` + read-only tools (content-tested).
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
### Mode: backends
|
|
2
|
+
|
|
3
|
+
Read-only. Answers *"which optional execution-backends are set up vs missing, and what's the next step?"* — for the family's subscription-CLI bridges (`codex-cli-bridge` → `codex`, `antigravity-cli-bridge` → `agy`). It **never writes, never commits, and never runs a subscription CLI**.
|
|
4
|
+
|
|
5
|
+
1. Run `node ${CLAUDE_SKILL_DIR}/tools/detect-backends.mjs` and present its table verbatim. Each row reports two **decoupled** axes: `manifestState` (health of the bridge *skill* — `not-installed | unsupported-schema | invalid-manifest | foreign | stub | ok`) and the readiness signals `cli` / `credentials` / `wrappers`, probed independently — so a CLI that is installed and signed in but whose bridge *skill* is absent reads `needs-skill`, not "missing".
|
|
6
|
+
2. For any backend that is not `ready`, point to its setup: the local `setup/README.md` when the bridge is installed, otherwise the backend's setup URL (both are in the report).
|
|
7
|
+
3. State plainly to the user that this is **detection only**:
|
|
8
|
+
- **"credentials present"** means the credential-marker **file** exists — it is **not** a live login check. The detector never runs `codex login status` / `agy` (that would spawn a paid, slow, networked subscription CLI).
|
|
9
|
+
- The bridges' wrappers are **POSIX `.sh`** scripts. On Windows the detector still works, but the bridges themselves are **not promised to run** — say so rather than implying they will.
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
### Mode: bootstrap
|
|
2
|
+
|
|
3
|
+
Requires: ${CLAUDE_SKILL_DIR}/references/shared/report-footer.md · ${CLAUDE_SKILL_DIR}/references/shared/composition-handoff.md · ${CLAUDE_SKILL_DIR}/references/shared/deploy-tail.md
|
|
4
|
+
|
|
5
|
+
> Bundled sources below (templates, scripts) live in **this skill's own directory** — `${CLAUDE_SKILL_DIR}/` in Claude Code, or the folder containing this `SKILL.md` in Codex / other agents. Use that as the copy/read source; the working directory is the **target project**, not the skill.
|
|
6
|
+
|
|
7
|
+
> The three setup questions (steps 2–4) are decisions only the user can make and are hard to reverse after a commit. Ask each as a **structured multiple-choice prompt where your agent supports it** (`AskUserQuestion` in Claude Code — one option per choice, recommended one first), otherwise in prose — and **wait for the answer before writing anything**.
|
|
8
|
+
|
|
9
|
+
1. **Recon (read-only).** Before writing anything:
|
|
10
|
+
- `package.json` / `pyproject.toml` / `go.mod` / `Cargo.toml` → stack, package manager, scripts.
|
|
11
|
+
- `ls -la` root → `README`, existing `AGENTS.md`/`CLAUDE.md`, CI configs, linter/formatter configs.
|
|
12
|
+
- `git log --oneline -30` + `git status` → recent activity, branch, uncommitted changes.
|
|
13
|
+
- `src/` (or equivalent) 2–3 levels deep → modules, routes/pages, components, services, types.
|
|
14
|
+
- Tests (framework, location, E2E?) and linter rules.
|
|
15
|
+
- Record: stack, package manager, daily commands (`dev`/`test`/`lint`/`type-check`), routes/pages, architecture layers.
|
|
16
|
+
- **First-contact orientation — say this before the first question (read-only).** In 1–2 plain lines, tell the user what this is — a portable memory & workflow system for this repo, so future sessions boot from a small structured memory instead of re-reading everything — and that they can run **`/agent-workflow-kit help`** any time to see every command. This is the "start here"; keep it to a sentence or two, then ask the visibility question.
|
|
17
|
+
2. **Choose visibility — ASK the user explicitly and wait for the answer, before writing anything.** This decides what gets tracked and is hard to reverse after a commit, so never assume the default silently: `visible` (committed — canonical, recommended) or `hidden` (in-tree, git-ignored via the **project-local** `.git/info/exclude` — one managed block covering the full AI/agent footprint, never the machine-global excludes). See [Visibility contract](${CLAUDE_SKILL_DIR}/references/contracts.md#visibility-contract).
|
|
18
|
+
3. **Choose conversational language — ASK the user explicitly and wait for the answer.** 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
|
+
4. **Choose agent attribution — ASK the user explicitly and wait for the answer.** 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
|
+
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/` from `${CLAUDE_SKILL_DIR}/references/templates/` (the template loop deploys each non-`AGENTS.md` template — the `.md` docs **and** the two seeded, user-editable strict-JSON configs: **`docs/ai/orchestration.json`** (the per-project recipe defaults the `procedures` advisor reads) and **`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`)). 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
|
+
7. **Fill templates** per the table below.
|
|
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
|
+
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.
|
|
25
|
+
- **visible** — wire the `package.json` scripts + add the minimal `.gitignore`. **Do not run the hide tool.**
|
|
26
|
+
- **hidden** — run the kit's hide writer (one managed block in the **project-local** `.git/info/exclude`, covering the kit's own artifacts **and** every known AI/agent tool's footprint — never the machine-global excludes): `node ${CLAUDE_SKILL_DIR}/tools/hide-footprint.mjs --dir <project> --dry-run` **first** (changes nothing, prints the plan), then the same without `--dry-run`. Handle what it surfaces, in plain language (never the tool's internal terms):
|
|
27
|
+
- A path it reports as **already committed** can't be hidden by ignoring it and is **never un-tracked silently** — show the user the printed `git rm --cached <path>`, let them decide, then opt it in with `--include=<path>`.
|
|
28
|
+
- A **present file with a generic name** it flags (e.g. `GEMINI.md`) → ask before `--include=<path>`.
|
|
29
|
+
- If it reports a **leftover machine-wide ignore block** from an older deployment, **ask before removing it** — it could affect another of the user's repos that relies on the same machine-wide rules; on a yes, re-run with `--remove-global` (prints a restorable backup). Otherwise it is kept (harmless — the project-local rules win).
|
|
30
|
+
- Report the result plainly (what is now hidden). **No Node on the agent host** → write the one managed block into `.git/info/exclude` by hand from the contract's path list, and report the manual step. **Windows is supported.**
|
|
31
|
+
- **Do not edit `package.json`** in hidden mode — a tracked change leaks the whole system.
|
|
32
|
+
10. **Stamp the deployment lineage.** Write the **deployment-lineage head** into
|
|
33
|
+
`docs/ai/.workflow-version` (one semver line). The lineage head is **`1.3.0`** — the shared
|
|
34
|
+
`agent-workflow` deployment lineage, **NOT** this kit's npm package version (see
|
|
35
|
+
`package.json` / `CHANGELOG.md`). The two are
|
|
36
|
+
independent axes: a packaging-only release bumps the package but leaves the lineage head until a
|
|
37
|
+
migration actually changes the deployed `docs/ai` structure. A stamp greater than the head →
|
|
38
|
+
STOP (never downgrade).
|
|
39
|
+
11. **Report & ask.** Show `tree docs/ai/`, 2–3 lines on what was filled with real data vs left as TODO, 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 ends on **one** recommended next step — including the optional, opt-in `/agent-workflow-kit velocity` (a read-only allowlist so routine read-only commands stop prompting; `${CLAUDE_SKILL_DIR}/references/modes/velocity.md`) or, once gates are declared, `/agent-workflow-kit hook` (auto-approve your own declared gate commands; `${CLAUDE_SKILL_DIR}/references/modes/hook.md`) when nothing more pressing applies, never run without a yes. Then **ask before committing** — never auto-commit.
|
|
40
|
+
|
|
41
|
+
Fill strategy:
|
|
42
|
+
|
|
43
|
+
| File | Strategy |
|
|
44
|
+
|------|----------|
|
|
45
|
+
| `current_state.md`, `architecture.md`, `env_commands.md`, `technical_specification.md`, `pages/index.md` | Fill with **real** recon data (stack, scripts, layers, routes). |
|
|
46
|
+
| `tech_reference.md` | Carry over real configs/patterns found in deps. |
|
|
47
|
+
| `active_plan.md`, `handover.md` | TODO seed (e.g. "Bootstrap session — fill domain sections after first real work"). |
|
|
48
|
+
| `decisions.md` | Seed `AD-001` (adopting this memory system). |
|
|
49
|
+
| `known_issues.md`, `changelog.md`, `pages/shared-patterns.md` | Empty template / first bootstrap entry. |
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
### Mode: gates
|
|
2
|
+
|
|
3
|
+
The **generic project gate runner** — it batches the project's OWN declared verification commands into one run. The runner itself **writes nothing, never commits, and never runs a subscription CLI**; what it EXECUTES is the project's own declaration, with the caller's privileges (trust posture: a batching convenience over commands the project already runs by hand — **not a sandbox**).
|
|
4
|
+
|
|
5
|
+
Run `node ${CLAUDE_SKILL_DIR}/tools/run-gates.mjs [--cwd <project>] [--only <id>]…`:
|
|
6
|
+
|
|
7
|
+
1. **Reads `docs/ai/gates.json`** (strict JSON, hand-editable; seeded from `references/templates/gates.json`). Each gate is `{ id, title, cmd }` — `id` a unique kebab handle, `cmd` **ONE bash command line** (brace/glob expansion works; a host without bash gets a loud preflight error, exit 6 — never a silent reinterpretation under another shell). The declaration names **WHAT to check, never who executes it** — the schema has no lane/model/routing fields and rejects unknown keys loudly.
|
|
8
|
+
2. **Runs each gate from the project root** and prints a per-gate **PASS/FAIL table** plus **one machine-readable summary line** as the last line (`[run-gates] status=… gates=… passed=… failed=… failed_ids=…`). A failing gate's own output is preserved **verbatim** (triage without re-running); a green gate's output is not echoed; gates after a failure still run. **Exit 0 iff all selected gates are green.**
|
|
9
|
+
3. **Honest outcomes, each distinct — never a silent green:** a **missing** declaration (exit 3 — the report names the recovery: create `docs/ai/gates.json` from the template; `upgrade` re-seeds a missing one), an **empty** `gates` list (exit 4), a **malformed/invalid** declaration (exit 5, loud `path: reason`). Repeatable **`--only <id>`** re-runs a subset; an unknown id is a loud usage error (exit 2).
|
|
10
|
+
|
|
11
|
+
The declaration is **seeded at bootstrap** (the template loop, `${CLAUDE_SKILL_DIR}/references/modes/bootstrap.md` step 6) and **ensured-if-missing on upgrade** from THIS kit's own template twin (`${CLAUDE_SKILL_DIR}/references/modes/upgrade.md` step 3) — independent of the installed memory substrate's age; an existing file is always **preserved byte-for-byte**. It is deliberately **not** a delegation-required memory asset: gates are optional, and absence is an honest runner outcome, not a deployment failure.
|
|
12
|
+
|
|
13
|
+
Declared gates can also be **auto-approved** (no permission prompt on a byte-exact invocation from the project root) via the opt-in PreToolUse hook — `${CLAUDE_SKILL_DIR}/references/modes/hook.md`: the SAME declaration, a second consumer; editing gates.json needs no re-wiring.
|
|
14
|
+
|
|
15
|
+
**Candidate line — the review-receipt gate (opt-in, never auto-seeded; AD-021).** Projects that configure a reviewed/council `plan-execution.review` recipe can declare the AD-038 review-state check as one more gate — the exact candidate `{ id, title, cmd }` line and its contract live under `${CLAUDE_SKILL_DIR}/references/modes/review-state.md` (step 3). The template `gates.json` stays EMPTY; adding the line is the maintainer's explicit consent, by hand.
|
|
16
|
+
|
|
17
|
+
**Invariants:** the runner writes nothing · never commits · never runs a subscription CLI · executes only the project's OWN declared commands (never a kit-invented one) · the bash contract fails loud, never reinterprets.
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
### Mode: grounding
|
|
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 two **mechanical** halves of a facts payload; the orchestrator still owns any judgment-bearing additions. **Catalogued honestly as a WRITER** — `--out <path>` writes one file — with the invariant: `--out` accepts **only gitignored / out-of-repo scratch destinations** and REFUSES a tracked path AND an in-repo not-ignored path (a new untracked file would itself move the review fingerprint the facts are about to ground); **stdout is the default**. It never commits and never runs a subscription CLI.
|
|
4
|
+
|
|
5
|
+
Run `node ${CLAUDE_SKILL_DIR}/tools/grounding.mjs [--constraints] [--plan <path>] [--reserve-bytes <n>] [--out <path>]`:
|
|
6
|
+
|
|
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. **`--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.
|
|
9
|
+
3. **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.
|
|
10
|
+
4. 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.
|
|
11
|
+
|
|
12
|
+
**Invariants:** writer (writes at most the ONE `--out` scratch file — gitignored / out-of-repo only) · never commits · never runs a subscription CLI · verbatim slices only (assembly is mechanical; facts judgment stays with the orchestrator).
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
### Mode: help
|
|
2
|
+
|
|
3
|
+
Read-only. The single discoverable **command index** — it answers *"what can `/agent-workflow-kit` do, and which commands change things?"* It **never writes, never commits, and never runs a subscription CLI**.
|
|
4
|
+
|
|
5
|
+
Run `node ${CLAUDE_SKILL_DIR}/tools/commands.mjs` (add `--json` for the machine-readable catalog) and present its grouped index — **Inspect / Configure / Orchestrate / Lifecycle**, each command tagged **read-only / writer / guarded / runs-project-commands** (the last: the kit writes nothing, but the mode executes the project's OWN declared commands — the `gates` runner) — in the user's conversational language. That catalog is the **single source of truth** for the command surface (the same one the bootstrap / upgrade report footers point at); `routeInvocation(token)` in the same file is the executable contract for which invocation maps to which mode.
|
|
6
|
+
|
|
7
|
+
`help` is also the landing spot for any **unrecognized or ambiguous** invocation — and that path is **always read-only** (the safe-routing rule under *Version status & the two axes*). When you arrive here that way, render the index and, in plain language, note that the invocation wasn't recognized so nothing was changed.
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
### Mode: hook
|
|
2
|
+
|
|
3
|
+
The opt-in **gate-approval PreToolUse hook** — the family's third `.claude/` writer (velocity discipline), and the shipped closure of the velocity trust-posture residual (**AD-021 scope C, probe-proven in AD-037**). It places a **self-contained** hook runtime at `.claude/hooks/agent-workflow-gates.mjs` (no kit imports — it keeps working if the kit is uninstalled) and wires ONE `PreToolUse` `"Bash"` entry into `.claude/settings.json`. Per Bash call the hook then walks a decision ladder, first match wins:
|
|
4
|
+
|
|
5
|
+
- **Auto-approve** a command **byte-identical** (leading/trailing trim only — no whitespace collapsing, no quote/glob/variable interpretation, no prefix or pattern matching, ever: patterns are what made AD-021 auto-seeding rejected) to a gate `cmd` declared in `docs/ai/gates.json` — read **LIVE on every call** (editing gates.json never needs re-wiring; one declaration, two consumers with `${CLAUDE_SKILL_DIR}/references/modes/gates.md`) — invoked **from the project root** (gates run from the root by contract; the same bytes from a subdirectory are NOT approved) and under `default`/`acceptEdits` permission mode (an approval never loosens `plan`/`bypassPermissions`).
|
|
6
|
+
- **Ask** on a command whose leading tokens match the velocity **seeded read-only core** when it carries the documented runtime residual — output redirection, command substitution, or the bounded `--output` write-flag family — surfacing a human prompt even where a seeded allow rule would have silently approved (**hook `ask` overrides an allow rule — proven live**: on Claude Code 2.1.185 a seeded `Bash(git log:*)` silently wrote a file via `git log --output=…`; with the hook wired the same call prompts). Detection is string-level and conservative: a quoted metacharacter may over-ask, never under-allow.
|
|
7
|
+
- **Stay silent otherwise** — the normal permission flow proceeds unchanged. The hook **never emits `deny`**; nothing is hard-blocked.
|
|
8
|
+
|
|
9
|
+
**Honest residual status (AD-037):** current engine builds already intercept `>` redirection and `$()` substitution upstream (observed headless on 2.1.185); the **`--output` family was proven open** and is the seam this hook demonstrably closes. The guard still covers all three documented classes (defense-in-depth — engine behavior may vary across surfaces/versions). **Fail-safe, decoupled:** a missing/broken/invalid `gates.json` disables ONLY gate auto-approval — the residual guard keeps running; every anomaly path exits 0 (the hook is never the blocker or the noise — the `gates` runner reports a broken declaration at its own point of use). **Not a sandbox:** it closes the named residual for the seeded core and auto-approves declared gates; it does not police arbitrary commands or user-added rules.
|
|
10
|
+
|
|
11
|
+
**Trust posture (state it plainly when asking consent):** the hook removes the PROMPT only for commands the human already declared in `docs/ai/gates.json` — the same trust boundary as the `gates` runner, which executes them with the caller's privileges. **gates.json thereby becomes a privileged file**: whoever can edit it can get its commands auto-approved. An invalid declaration approves NOTHING (strict parse, exact validation parity with the runner).
|
|
12
|
+
|
|
13
|
+
**Version-status routing** like the other writer modes (stamp head `1.3.0`; `--apply` enforces it in code).
|
|
14
|
+
|
|
15
|
+
Run `node ${CLAUDE_SKILL_DIR}/tools/gate-hook.mjs [--dry-run | --apply] [--cwd <dir>]`:
|
|
16
|
+
|
|
17
|
+
1. **`--dry-run` first, always** (the default — changes nothing): previews the placement and the exact settings entry it would merge. It STOPs (zero writes) on: a symlinked `.claude` / `.claude/hooks` / target file / non-regular `settings.json`; malformed settings JSON; a **malformed existing `hooks` shape** (never a merge-through-clobber); an unsafe `permissions.defaultMode` in **either** settings file; or a target hook file with **different** content while our entry is not wired (**it refuses to wire an unknown script as a PreToolUse hook** — the recovery is named: delete the file to reseed from the bundle).
|
|
18
|
+
2. **Ask consent** via **`AskUserQuestion` where supported**, the no-change option first: keep prompting for gate commands, or place + wire the hook — presenting the trust posture above in plain language.
|
|
19
|
+
3. **Only on an explicit yes**, re-run with `--apply`. It places the file FIRST, then wires settings (a wired-but-missing entry would error on every Bash call); merge-don't-clobber (foreign hooks/matchers/keys and existing permissions preserved; re-apply never duplicates); **settings hot-reload — the hook is active for new Bash calls, no session restart needed**. An identical existing file is *already current*; a diverged-but-already-wired file is reported, never clobbered or unwired.
|
|
20
|
+
4. **Hidden-mode deployments:** after apply, run the hide-footprint reconcile (`node ${CLAUDE_SKILL_DIR}/tools/hide-footprint.mjs --dir <project> --reconcile`) — `/.claude/hooks/` is in the known-footprint registry; the apply report reminds you.
|
|
21
|
+
|
|
22
|
+
**Invariants:** writes ONLY `.claude/hooks/agent-workflow-gates.mjs` + `.claude/settings.json` · never `settings.local.json` · never commits · exact-match approval only (no patterns) · never `deny` · never auto-wired by `init`/`upgrade` (placement stays opt-in — the AD-011/AD-034 boundary: init/upgrade may refresh placed things, never place new ones).
|
|
23
|
+
|
|
24
|
+
**Exit codes:** `0` done / dry-run (incl. the reported diverged-but-wired state); `1` a precondition STOP; `2` bad arguments.
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
### Mode: procedures
|
|
2
|
+
|
|
3
|
+
Read-only **activity-procedures advisor**. Answers *"what are the steps of this named activity, and which recipe applies at each slot here?"* It composes the orchestration recipes (`${CLAUDE_SKILL_DIR}/references/modes/recipes.md`) into **named activities** with **typed recipe slots**. It **never writes, never commits, never runs a subscription CLI** — the deterministic resolution lives in the kit; the orchestrator runs the resolved recipe via the bridge skills and **owns any commit when the activity has a commit boundary** (a backend never commits). Not every activity commits: `plan-authoring` ends at approval and produces no commit (plans are ephemeral, never committed); `plan-execution` commits per Step.
|
|
4
|
+
|
|
5
|
+
The two v1 activities (canon in the **installed engine**, `references/procedures.md`):
|
|
6
|
+
|
|
7
|
+
- **`plan-authoring`** (slot: `review`) — research → draft → self-review → **review {recipe}** → fold/loop → present for approval; enforce the mandatory Cleanup.
|
|
8
|
+
- **`plan-execution`** (slots: `execute`, `review`) — per Step: resolve the recipe → if Delegated, dispatch execution first → implement → self-review → **review {recipe}** → gates → commit boundary.
|
|
9
|
+
|
|
10
|
+
Run **`node ${CLAUDE_SKILL_DIR}/tools/procedures.mjs <activity> [--override <slot>=<recipe>]… [--json]`**. It reads the activity's steps live from the engine and prints them **verbatim**, then the **resolved effective recipe per slot** from the per-project config + the read-only backend detector:
|
|
11
|
+
|
|
12
|
+
1. **Config = `docs/ai/orchestration.json`** — strict JSON, **agent-writable via `/agent-workflow-kit set-recipe` (`${CLAUDE_SKILL_DIR}/references/modes/set-recipe.md`) OR hand-edited** (the kit reads + validates it; `procedures`/`recipes` stay read-only — the writer is `set-recipe`). Shape: `{ "<activity>": { "<slot>": "<recipe>" } }`; all slots optional (an absent slot → its computed default, stated); an optional `"_README"` string is allowed + ignored. `review` accepts `solo|reviewed|council`; `execute` accepts `solo|delegated`. Seeded by `init` (a user-editable template) — see `${CLAUDE_SKILL_DIR}/references/modes/bootstrap.md`.
|
|
13
|
+
2. **Default resolution (config silent):** `review` → Reviewed if any review-capable backend is `ready`, else Solo (never Council by default); `execute` → Solo (Delegated is opt-in). **Degradation:** a config/computed default degrades **gracefully with a stated reason** (Council → Reviewed → Solo; Delegated → Solo); a per-run **`--override <slot>=<recipe>`** that can't be satisfied degrades **loudly** (a flagged warning, so you tell the user) — but is **still exit 0** (a valid request that gracefully degraded).
|
|
14
|
+
3. **Exit codes:** `0` success; `2` usage (unknown `<activity>` / bad `--override` — a bare `--override <recipe>`, an unknown slot, an invalid recipe-for-slot, or a duplicate slot); `1` config error (malformed / schema-invalid / unreadable `orchestration.json`) **or** engine error (the installed engine is absent / invalid / **too old** to ship `references/procedures.md` — upgrade it with `npx @sabaiway/agent-workflow-engine@latest init`). A `1`/`2` failure is loud (`path: reason`), never a silent fallback.
|
|
15
|
+
|
|
16
|
+
**Cap-soft-skip degradation (the feature's only AUTO route).** The activity procedures are auto-discoverable only through the one-line **`workflow:methodology`** pointer (this kit + the engine carry `disable-model-invocation:true`, so NL like "write a plan" does **not** auto-load this skill). On a deployment whose methodology pointer was cap-soft-skipped — or whose pre-existing customized pointer lacks the procedures clause — the procedures are still reachable by **explicitly** invoking `/agent-workflow-kit procedures`; surface that plainly rather than treating it as a gap.
|
|
17
|
+
|
|
18
|
+
**Invariants:** read-only · never writes · never commits · never runs a subscription CLI · the deterministic resolution is the kit's, the recipe execution is the orchestrator's.
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
### Mode: recipes
|
|
2
|
+
|
|
3
|
+
Read-only **orchestration advisor**. Answers *"how should I compose the optional execution-backends into plan → execute → review here, and which recipe fits?"* It **never writes, never commits, never runs a subscription CLI, and never executes a recipe** — the orchestrator (you) runs the chosen recipe through the bridge skills and makes the single commit; a backend is advisory or delegated, never autonomous.
|
|
4
|
+
|
|
5
|
+
The four recipes (defined over each bridge's `provides` roles — `codex`: execute + review; `agy`: review + probe), canonical narrative in the **installed engine** (`references/orchestration.md`):
|
|
6
|
+
|
|
7
|
+
- **Solo** — you plan, execute, and self-review; no backend (always available; the floor).
|
|
8
|
+
- **Reviewed** — you execute; **one** backend reviews the result (advisory). Prefers `codex` when both are ready (`agy` carries a standing health caveat).
|
|
9
|
+
- **Council** — **both** backends review independently; you synthesize the two opinions.
|
|
10
|
+
- **Delegated** — you hand a **bounded** execution sub-task to a backend (`codex exec`), then review the returned diff and commit.
|
|
11
|
+
|
|
12
|
+
1. Run **`node ${CLAUDE_SKILL_DIR}/tools/recipes.mjs`** (the read-only planner; `--json` for the structured form). It runs the backend detector, lists the four recipes, and prints — for the current environment — a **per-recipe dispatch plan that degrades with a stated reason** when a backend isn't `ready` (Council → Reviewed → Solo; Delegated → Solo), plus advisory **quota/health notes** (prefer the cheapest model; Council spends two backends' quota; `agy` may stall on substantive prompts — Issue-001, prefer `codex`).
|
|
13
|
+
2. **Offer the choice** via **`AskUserQuestion` where your agent supports it** (`AskUserQuestion` in Claude Code) — one option per recipe, the `recommendRecipe` choice listed **first** — otherwise in prose. Then print `planRecipe(chosen, detection)` (the per-stage dispatch + degradation reasons + quota/health notes) so the user sees exactly what running it entails.
|
|
14
|
+
3. **Availability = `readiness === ready`, full stop.** Every other readiness supplies the human reason (needs-skill → "not installed — `/agent-workflow-kit setup`"; needs-cli → "install the CLI"; needs-credentials → "log in"; degraded → "wrapper not on PATH — `/agent-workflow-kit setup`"). This is set-up state only — **never** a claim that a backend's service is responsive (the detector cannot observe a runtime stall; `agy`'s Issue-001 is a *standing advisory*, not a readiness signal).
|
|
15
|
+
|
|
16
|
+
**The configured-recipe line (`--active-line`, read-only).** `node ${CLAUDE_SKILL_DIR}/tools/recipes.mjs --active-line` prints exactly **one** machine-composed line: the **CONFIGURED** recipe of every activity/slot, resolved from the target project's `docs/ai/orchestration.json` (read from the current directory) + live readiness — each slot with its source (configured vs computed default), its degradation stated, and its dispatched wrapper set — explicitly contrasted with the readiness **recommendation** (which is informational; the configured recipes are what runs). Paste it verbatim: it fills the session-start discovery step (the deployed `agent_rules.md` §1.1) and the handover "Active recipes:" slot; `set-recipe` echoes the same line after every successful write. A malformed config fails loud (exit 1), never a silent fallback.
|
|
17
|
+
|
|
18
|
+
**Invariants:** read-only · never runs a subscription CLI · never commits · the orchestrator executes the recipe via the bridge skills, not the kit.
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
### Mode: review-state
|
|
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).
|
|
4
|
+
|
|
5
|
+
Run `node ${CLAUDE_SKILL_DIR}/tools/review-state.mjs [--check] [--json]`:
|
|
6
|
+
|
|
7
|
+
1. Plain run → the human report: resolved recipe + source, plan-in-flight, tree fingerprint, per-backend receipt state (current / stale / ungrounded / missing) with verdict + grounding + timestamp.
|
|
8
|
+
2. **`--check`** → the gate exit code. The **normative exit contract lives in the tool header** (the single home — do not re-enumerate it elsewhere): exit 0 for a solo-resolved recipe (configured, or degraded there — no ready reviewer), no plan in flight (the `docs/plans` naming convention: `queue.md` and `EXECUTE-`/`FEEDBACK-`-prefixed or `PROMPT`/`prompt`/`handoff`-carrying names are scratch), a clean tree, a non-git cwd, or every recipe-named backend receipted **current + grounded**; exit 1 when a backend is missing, **stale** (ANY edit after its review moves the fingerprint), or grounded:false under reviewed/council. **Presence, not unanimity:** verdict adjudication (ship/revise, the divergence crossover) stays orchestrator judgment — the gate only proves the configured backends really reviewed THIS tree. Plan/diff receipts and continuations (`agy-review --continue`) are **informational-only**: after a fold, only a **fresh grounded re-run** (`codex-review code`; `agy-review code --facts @f`) restores green.
|
|
9
|
+
3. **Wire it as a gate by hand — never auto-seeded (AD-021).** The candidate line for your own `docs/ai/gates.json`: `{ "id": "review-state", "title": "Review receipts current for the uncommitted tree", "cmd": "node <path-to-this-skill>/tools/review-state.mjs --check" }` — with the path your project actually reaches the kit by. Once declared, the opt-in `${CLAUDE_SKILL_DIR}/references/modes/hook.md` auto-approves it like any other declared gate.
|
|
10
|
+
|
|
11
|
+
**Human residual (stated, accepted):** `git commit --no-verify` and receipt-file deletion/forgery remain possible — this is a self-discipline mechanism against silent process drift, not a security boundary.
|
|
12
|
+
|
|
13
|
+
**Invariants:** read-only · never writes · never commits · never runs a subscription CLI · spawns read-only `git` queries only · the receipt writers are the bridge review wrappers, never the kit.
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
### Mode: set-recipe
|
|
2
|
+
|
|
3
|
+
The **config writer** for `docs/ai/orchestration.json` — the answer to *"set my standing recipe preference without hand-editing JSON."* **Division of labor (AD-025):** YOU turn the user's plain language into explicit ops; the KIT does the deterministic validate → merge → preview → write. It **previews by default** (writes nothing); `--write` applies. It **never runs a backend and never commits**. Hand-editing `docs/ai/orchestration.json` stays fully supported — this is an offered convenience, never a lock.
|
|
4
|
+
|
|
5
|
+
**Map the user's plain language → explicit ops** (the kit ships no NL parser; it performs no `all`-magic, so you expand scope explicitly, asking when unclear):
|
|
6
|
+
|
|
7
|
+
| user says (RU/EN) | op | scope |
|
|
8
|
+
|---|---|---|
|
|
9
|
+
| "оба ревьюят" / "both review" | `--set <activity>.review=council` | **disambiguate**: which activity? If both, pass `--set plan-authoring.review=council --set plan-execution.review=council`. |
|
|
10
|
+
| "один ревьюер" / "one reviewer" | `--set <activity>.review=reviewed` | per the named activity, else ask |
|
|
11
|
+
| "делегируй исполнение" / "delegate execution" | `--set plan-execution.execute=delegated` | execution only |
|
|
12
|
+
| "верни как было / сам" / "revert / do it myself" | `--unset <activity>.<slot>` | the named slot → its computed default |
|
|
13
|
+
|
|
14
|
+
Run **`node ${CLAUDE_SKILL_DIR}/tools/set-recipe.mjs [--set <activity>.<slot>=<recipe>]… [--unset <activity>.<slot>]… [--write] [--json]`**:
|
|
15
|
+
|
|
16
|
+
1. **Grammar — always fully-qualified `<activity>.<slot>`** (the kit never guesses the activity; a bare `review=council` is rejected). `review` accepts `solo|reviewed|council`; `execute` accepts `solo|delegated`. Activities/slots: `plan-authoring.review`, `plan-execution.execute`, `plan-execution.review`.
|
|
17
|
+
2. **Preview by default** — prints `current → proposed` for the **changed** slots only, plus the **effective recipe resolved against live backend readiness** (degradation stated honestly, e.g. *council requested, 1 ready reviewer → runs reviewed until a 2nd backend is ready*). It writes **nothing**. Re-run with **`--write`** to apply (same effective/degradation note — a direct `--write` is never quieter than the preview). `--unset` returns a slot to its computed default (reverting needs no hand-edit either). A no-op `--set` (slot already equals) writes nothing and never re-seeds the onboarding note.
|
|
18
|
+
3. **`--write`** applies via a hardened, atomic write (deployment-gated — refuses to scatter a config into a repo with no `docs/ai`; exclusive-create temp + rename; symlink/TOCTOU-safe; last-writer-wins). It preserves the onboarding note + every untouched slot, normalizing to canonical 2-space JSON.
|
|
19
|
+
**Standing-consent advisory (after a successful `--write` only, and only when the written config names a `reviewed`/`council` recipe — a solo recipe gets NO advisory):** advise the ONE-TIME **hand-adds** to the maintainer's `.claude/settings.local.json` — `Bash(codex-review:*)` + `Bash(agy-review:*)` + `Bash(node <skill-dir>/tools/grounding.mjs:*)`, with the path your project actually reaches the kit by. State plainly: (a) auto-approving a review wrapper **spends subscription quota without a per-run prompt** — that is exactly what standing consent means here, so it is the maintainer's call; (b) the kit **never writes that file** — these stay hand-adds; (c) `grounding.mjs --out` writes ONE scratch facts file — that write is what the standing consent covers; (d) the entry must match the invocation **byte-form your project actually uses, INCLUDING quoting** — the procedures advisor renders a QUOTED skill path, and a hand-add covering it must use the same spelling (a mismatched spelling is a dead rule that simply prompts).
|
|
20
|
+
4. **Exit codes:** `0` success (an explicit recipe that gracefully degrades is still `0`); `2` usage (a bare/duplicate op, or `--write` with no ops); `1` config error (malformed/unreadable config — the file is left **untouched**, never clobbered) or a write STOP (no deployment / a symlinked config). A `1`/`2` failure is loud; on a malformed config, offer to show the parse error so you can help the user fix the JSON.
|
|
21
|
+
|
|
22
|
+
Output is **English/structured** — **localize it to the user's conversational language** when you narrate. Surface the effective-recipe/degradation note plainly.
|
|
23
|
+
|
|
24
|
+
**Invariants:** writer (writes only `docs/ai/orchestration.json`) · never commits · never runs a subscription CLI · previews by default · degradation honesty on preview AND `--write` · hand-edit stays first-class.
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
### Mode: setup
|
|
2
|
+
|
|
3
|
+
The **only writer** among the backend modes, and **opt-in / in-agent only** — **placement** is **never** part of `init`. The npx installer deploys the *kit* and bundles the bridge skills in its tarball, but **does not place** them (that honesty claim is load-bearing — see `decisions.md` AD-009 / AD-011); **once placed** by `setup`, `init` and `${CLAUDE_SKILL_DIR}/references/modes/upgrade.md` keep the placed copy fresh via the refresh-only `--refresh-placed` (below) — **never a first placement, never a downgrade**. `setup` owns exactly the two deterministic, secret-free steps and **guides** the rest. It **never commits and never runs a subscription CLI**.
|
|
4
|
+
|
|
5
|
+
Run `node ${CLAUDE_SKILL_DIR}/tools/setup-backends.mjs [<backend>] [--bindir <path>] [--dry-run]`:
|
|
6
|
+
|
|
7
|
+
- `<backend>` — `codex` | `agy` | `antigravity` | `codex-cli-bridge` | `antigravity-cli-bridge`; omit for **all**.
|
|
8
|
+
- `--bindir <path>` — where to link the wrappers (default `~/.local/bin`).
|
|
9
|
+
- `--dry-run` — print the per-backend plan and change **nothing** (run this first).
|
|
10
|
+
- `--refresh-placed` — the **refresh-only** mode (what `init` runs automatically and `${CLAUDE_SKILL_DIR}/references/modes/upgrade.md`
|
|
11
|
+
runs as its fourth stamp-independent reconcile): refresh every bridge `setup` **already placed**
|
|
12
|
+
from the kit's bundled copies + re-link its wrappers; an absent bridge is a stated skip (**never**
|
|
13
|
+
placed), a placed bridge newer than the bundle is a stated skip naming the kit update (**never**
|
|
14
|
+
downgraded), and every outcome line is composed by the tool — paste verbatim. Does not combine
|
|
15
|
+
with `--dry-run`.
|
|
16
|
+
- `--help`, `-h` — usage.
|
|
17
|
+
|
|
18
|
+
For each backend it:
|
|
19
|
+
1. **Places / refreshes the bundled bridge skill** (from the kit's `bridges/<name>/` mirror) into its canonical dir — but only when that dir is **absent / empty / proven-managed** (valid manifest, matching `name`+`kind`). A `stub` / `foreign` / `invalid` / `unsupported` dir, a marker fs-error, or a symlinked dir → **STOP**, never overwritten. Refresh re-runs on a proven-managed dir so re-running `setup` delivers bundled fixes.
|
|
20
|
+
2. **Links its wrappers** (`codex-exec` / `codex-review`; `agy-review` / `agy-run`) onto `--bindir` via **managed symlinks** — replacing only a symlink that already points at our source. A non-symlink or a foreign symlink → **STOP**; it **preflights every target first**, so a conflict on one wrapper makes **zero** changes. If `--bindir` is not on `PATH`, it prints the one-line `export PATH=…` to add — it never edits a shell rc.
|
|
21
|
+
3. **Guides the manual, secret-bearing steps it will NOT automate** — the binary install (each bridge's `setup/README.md` §1) and the one-time interactive subscription login (`codex login` / `agy`) — printing the exact command for whichever axis is still missing (axis-aware: it can ask for both the CLI and the login at once).
|
|
22
|
+
|
|
23
|
+
**Close-the-loop output (surface both, localized).** The tool prints, after the per-backend report:
|
|
24
|
+
- a **bridge version** on each skill line — `(vX)` for a fresh place / equal refresh, `(vOld → vNew)` when a refresh bumps the bridge (never `vnull → …`);
|
|
25
|
+
- a **status pointer** — the full family + deployment version view lives in `/agent-workflow-kit status`;
|
|
26
|
+
- a **proactive recipe offer** when a setup just made a review backend ready (re-detected AFTER apply, so it reflects the real new state): it prints `/agent-workflow-kit set-recipe --set plan-authoring.review=<depth>` **and** `…plan-execution.review=<depth>` (Council when both are ready, else Reviewed). Relay it in plain language: offer to set the review recipe for **both** planning and execution review (preview first; you'll write it via `${CLAUDE_SKILL_DIR}/references/modes/set-recipe.md`, or they can hand-edit) — never offer only `plan-execution`. Ask if the scope is unclear.
|
|
27
|
+
|
|
28
|
+
**Windows:** the wrappers are POSIX `.sh`; on `win32` it reports *unsupported — use WSL* and mutates nothing.
|
|
29
|
+
|
|
30
|
+
**Exit codes:** `0` = done / already set up / only manual steps remain (guidance is never a failure); **non-zero** = a STOP (a dir/symlink it refuses to clobber), a bad argument, a missing bundle, or a native fs error (the underlying reason is preserved in the message).
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
### Mode: status
|
|
2
|
+
|
|
3
|
+
Requires: ${CLAUDE_SKILL_DIR}/references/shared/report-footer.md
|
|
4
|
+
|
|
5
|
+
Read-only. The **single answer to "versions + deployment + settings + bridges"** across the whole family — `tools/family-registry.mjs` aggregates every member's `capability.json` and surveys the project. It **never writes, never commits, and never runs a subscription CLI**.
|
|
6
|
+
|
|
7
|
+
Run `node ${CLAUDE_SKILL_DIR}/tools/family-registry.mjs --json [--dir <project>]` and render it **compact**, in the user's conversational language — **never paste the JSON or any internal field name** (no-leak rule). Map the **`installed[].state`** token via the value→plain-language map under *The version block + welcome mat* in `${CLAUDE_SKILL_DIR}/references/shared/report-footer.md` (the `visibility` and wrapper states have their own phrasings, below). Present, each area on its own line(s), routing detail to its domain mode:
|
|
8
|
+
|
|
9
|
+
1. **Versions — a status-only render from `installed[]` + `deploymentHead`** (this is **NOT** the shared notes-based version block — see the separation note below): the **`docs/ai` structure version** (named as such, never "lineage head"), then each member by its `display` showing its `version` (or, when there is no version, the plain phrase for its `state`, mapped above), plus the two-axes disambiguation. **Freshness comes from `installed[].refresh`, not from `notes`:** for each member whose **`refresh.behind`** is `true`, show a **localized "needs refresh"** label and the **verbatim `refresh.recommend`** command **exactly once** (the command/package name stays source-language; **do not also paste the English `notes` caveats** — `refresh.recommend` is the single source of the recovery step, so the command is never duplicated on this surface). A member whose **`refresh.freshness`** is **`unknown`** is surfaced too — a localized *"couldn't be checked"* label; it is **never counted as current and never as behind** (its `notes` caveat carries the detail on the notes-based surfaces; here the label is enough). Lead with a one-line **headline count** derived from `installed[].state` + `refresh.behind` + `refresh.freshness` (e.g. *"5 members installed · 1 needs a refresh · 1 couldn't be checked"* — omit a zero count).
|
|
10
|
+
|
|
11
|
+
> **Status reads `refresh`; the shared version block + the bootstrap/upgrade footers stay `notes`-based (unchanged this release).** `${CLAUDE_SKILL_DIR}/references/modes/status.md` has its OWN status-only render (above), keyed on `installed[].refresh.behind` / `refresh.recommend`. The shared **version block** (under *The version block + welcome mat* in `${CLAUDE_SKILL_DIR}/references/shared/report-footer.md`) and the bootstrap (step 11) + every upgrade (steps 4 / 8) report footer still consume `installed[].notes` verbatim — that wiring is deliberately **untouched** here (their migration onto `refresh` is deferred). Do not rewrite those footers onto `refresh`.
|
|
12
|
+
2. **Deployment (`--dir`)** (from `project`): whether `docs/ai/` is deployed + the deploy stamps by `display`; and **visibility** — render `project.visibility.state` in **user-safe words only**: *visible (tracked)* / *hidden (git-ignored, local-only)* / *unclear (uncommitted or partially set up)* — **never** the words "hidden fence" or any marker term. A `visibility.error` → surface it plainly.
|
|
13
|
+
3. **Settings (`--dir`, one line each)** (from `project.settings`):
|
|
14
|
+
- **recipes** — the effective recipe per slot (detail → `/agent-workflow-kit procedures` / `recipes`); a `recipes.detectError` → say the backends couldn't be checked, so recipes floored at solo.
|
|
15
|
+
- **attribution** — `includeCoAuthoredBy` effective; call out a **local override** only when `local` is non-null **and** differs from `project` (a `null` `local` means the key is absent there, so the project value stands — that is not an override).
|
|
16
|
+
- **velocity** — the effective `permissions.defaultMode` + whether an allowlist is seeded (detail → `/agent-workflow-kit velocity`).
|
|
17
|
+
- Any area's **`error`** field → surface it **loudly** in plain language; the rest of `status` still renders (never a crash).
|
|
18
|
+
4. **Bridges (host, one line)** (from `bridges[]`): per bridge — readiness + wrapper PATH-presence; render each wrapper's `state` as *on PATH* (`present`) / *not on PATH* (`missing`) / *couldn't check* (`unknown`) (detail → `/agent-workflow-kit backends` / `setup`). **No default-model claim.** "credentials present" means a marker file exists, not a live login.
|
|
19
|
+
|
|
20
|
+
Restate the **two-axes honesty** — an installed *package* version is not the project's **`docs/ai` structure version** (see *Version disclosure* in `${CLAUDE_SKILL_DIR}/references/shared/report-footer.md`); the installed version is whatever is on disk under `~/.claude/skills/…`, so a stale install shows its real (older) version, honestly. A host that can't run the helper → **skip with the concrete reason** (the helper-failure contract), never silently.
|
|
21
|
+
|
|
22
|
+
**Invariants:** read-only · never writes · never commits · never runs a subscription CLI · plain language only, no leaked internal terms.
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
### Mode: uninstall
|
|
2
|
+
|
|
3
|
+
The **guarded teardown** — the inverse of `init` (the kit + engine skills) + `setup` (the bridges) + a hidden deploy. **In-agent, opt-in**, and built around one hard rule: **it never deletes user-authored content.** Run **`--dry-run` first, always**, show the user the classified plan in plain language, get explicit consent, then re-run with `--yes`. It **never commits**.
|
|
4
|
+
|
|
5
|
+
Run `node ${CLAUDE_SKILL_DIR}/tools/uninstall.mjs [<member>] [--dir <project>] [--bindir <path>] [--dry-run | --yes]`:
|
|
6
|
+
|
|
7
|
+
- `<member>` — limit the skill axis to one member (`agent-workflow-kit` / `-memory` / `-engine` / a bridge); omit for the **whole family**.
|
|
8
|
+
- `--dir <project>` — also reverse the **project-deployment** surfaces in `<project>`.
|
|
9
|
+
- `--bindir <path>` — where the bridge wrappers were linked (default `~/.local/bin`, mirrors `setup`).
|
|
10
|
+
- `--dry-run` — print the plan and change **nothing** (run this first). `--yes` — apply the **auto-removable** set.
|
|
11
|
+
|
|
12
|
+
It classifies every surface into four classes and acts accordingly:
|
|
13
|
+
|
|
14
|
+
- **remove** (safe) — an installed skill dir that is **provably ours** (valid manifest, `name`+`kind` match). A dir present but **not provably ours** (`foreign`/`stub`/`invalid`/unreadable) → **STOP**: left untouched **and reported**, while the teardown still removes the members that ARE ours (a not-ours surface is never clobbered, and never blocks removing the rest — the per-item `setup` posture). **Preflight-then-mutate:** if a mutable surface **changed since the dry-run** (a skill no longer ours, a wrapper turned foreign, a hook that lost our marker, a malformed fence), the run **aborts with zero changes**.
|
|
15
|
+
- **reverse** (managed-marker) — a bridge **wrapper symlink that points at our source** (a foreign/non-symlink one → STOP); the hidden-mode **managed fence** (via the existing `--unhide` path — only the fenced lines); a **pre-commit hook carrying our marker** (an unmarked / user hook → left + reported).
|
|
16
|
+
- **KEEP — never deleted** (report-only) — `docs/ai`, `AGENTS.md`, `CLAUDE.md`, `docs/plans`, and `.claude/settings.json` (the `includeCoAuthoredBy` edit **and** any `permissions.defaultMode`/`permissions.allow` the velocity profile may have seeded). The tool **prints the exact `rm` / `git rm --cached`** for the docs/entry files and an **edit** instruction for `settings.json` (never an `rm` — it may hold your own settings); the **user** runs them. Surface this in plain language; never delete on their behalf.
|
|
17
|
+
|
|
18
|
+
**Shared globals:** removing `agent-workflow-memory` / `agent-workflow-engine` / a bridge removes a **global** skill that another project on the machine may use — say so before applying. **Windows:** the wrappers are POSIX; the skill-dir + project arms still work, the wrapper arm reports *use WSL*.
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
### Mode: upgrade
|
|
2
|
+
|
|
3
|
+
Requires: ${CLAUDE_SKILL_DIR}/references/shared/report-footer.md · ${CLAUDE_SKILL_DIR}/references/shared/composition-handoff.md · ${CLAUDE_SKILL_DIR}/references/shared/deploy-tail.md
|
|
4
|
+
|
|
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
|
+
2. **Never-downgrade gate — FIRST, before any write.** Compare the stamp to the **deployment-lineage head** (`1.3.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 **two** pointers — the **workflow-methodology** pointer and, right below it, the **orchestration-recipes** pointer (Solo / Reviewed / Council / Delegated, routing to `/agent-workflow-kit recipes`) — and is filled on **every** upgrade, idempotently (zero-diff when both are already present + filled), so even a legacy / current **`1.3.0`** deployment gains them **without a lineage-head bump or a migration** (the deployment-lineage head stays `1.3.0`; the `agent-workflow-memory` **package** template did get a docs-only headroom trim for the second pointer, 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** (both fragments are read live from it — see the distinct outcomes below).
|
|
8
|
+
|
|
9
|
+
**Classify the exit — there are THREE non-zero exits + one soft in-band skip; handle each differently:**
|
|
10
|
+
|
|
11
|
+
(a) **Soft, reported skip of the orchestration pointer (CONTINUE the upgrade).** The orchestration pointer is the less-critical second pointer; when it can't be added right now `reconcile` exits **zero**, keeps the methodology pointer, and **reports the skip on stdout** (the `… skipped …` line) — never silent (Hard Constraint). Two reasons: **(i)** the methodology pointer fits but adding the orchestration pointer would push the file past the `AGENTS.md` 100-line cap; or **(ii)** the installed `agent-workflow-engine` is **present but too old** to ship the recipes fragment (`<1.2.0`) — it can still supply the methodology pointer, so only the recipes pointer is withheld. Report it in the successful-exit report (**step 4** equal-head, else **step 8**) in plain language, e.g. *"The orchestration-recipes pointer wasn't added — the entry point is at its 100-line limit / your methodology engine is older than the recipes feature. The recipes are still available any time via `/agent-workflow-kit recipes`; 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 either pointer, same plain-language framing.)
|
|
12
|
+
|
|
13
|
+
(b) **Malformed pair / missing-or-duplicate anchor (either pointer) — a hard STOP (do NOT continue).** A non-zero exit whose message names a marker/anchor problem; never soft-skip it.
|
|
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 **neither** fragment (distinct from (a)(ii), where the engine is valid but merely too old for the recipes 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 the methodology pointer (a no-silent-failures violation). (b) and (c) STOP the upgrade; only (a) continues.
|
|
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; the orchestration pair sits right under the methodology end marker). Fill each empty pair from its engine fragment (`methodology-slot.md` / `orchestration-slot.md`) — never inline a copy (that would re-create the retired mirror).
|
|
18
|
+
|
|
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
|
+
|
|
21
|
+
**Orchestration config ensure (seed-or-refresh) — stamp-independent, same gate, BEFORE the equal-head short-circuit.** Ensure `docs/ai/orchestration.json` exists **and its onboarding note is current**: **create it from the template if missing**; **if it already exists, preserve every activity/slot the user set, and refresh ONLY the `_README` note when the existing one still matches a known prior canonical** — the tested `refreshIfCanonical` / `refreshReadme` in `tools/orchestration-config.mjs` is the source of truth for that decision (normalize CRLF/whitespace before comparing; a *customized* `_README` is preserved verbatim; a *malformed* existing config is **preserved + a loud warning**, never clobbered or silently skipped). The current note points at `/agent-workflow-kit set-recipe` (the config is now agent-writable — no more "never written for you"). **The refresh helper is kit-owned** — in the **delegated** path memory only seeds/preserves the file (memory upgrade step 2) and the **kit** then applies the `_README` refresh; in the **fallback** path the kit seeds-or-refreshes directly from `${CLAUDE_SKILL_DIR}/references/templates/orchestration.json`. (Memory stays standalone — it never depends on this helper.) Like the pointer slots + the footprint reconcile, this reaches an equal-head (`1.3.0`) deployment **without a lineage-head bump or a migration file** (it is a `.json`, inherently outside the docs cap-validator). Report it in the step 4 / step 8 success report (config *seeded* / *note refreshed* / *already current* / *customized — preserved*).
|
|
22
|
+
|
|
23
|
+
**Gate-declaration ensure (seed-if-missing) — stamp-independent, same gate, BEFORE the equal-head short-circuit.** Ensure `docs/ai/gates.json` exists: **create it from `${CLAUDE_SKILL_DIR}/references/templates/gates.json` if missing** — the kit's OWN template twin, so this works even when the installed memory substrate predates the gates feature (a stale memory never silently loses it); **an existing file is preserved byte-for-byte** (a project's declared gate matrix is authored content — never clobbered, never refreshed in place; unlike the orchestration `_README` there is no note-refresh here). Report it in the step 4 / step 8 success report (*seeded* / *already present*). Like the config ensure, this reaches an equal-head deployment without a lineage-head bump or a migration file (a `.json`, inherently outside the docs cap-validator).
|
|
24
|
+
|
|
25
|
+
**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). 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*).
|
|
26
|
+
|
|
27
|
+
**Placed-bridge refresh — stamp-independent, same gate, BEFORE the equal-head short-circuit.** Run
|
|
28
|
+
`node ${CLAUDE_SKILL_DIR}/tools/setup-backends.mjs --refresh-placed` and **paste its per-bridge
|
|
29
|
+
output lines verbatim** — every outcome line is composed by the tool (*refreshed* / *already
|
|
30
|
+
current* / *skipped — not placed* / *could not refresh* + its recovery); you compose nothing
|
|
31
|
+
factual. It is **refresh-only**: it refreshes a bridge **`setup` already placed** from this kit's
|
|
32
|
+
bundled copies and re-links its wrappers; an **absent** bridge is a stated skip, **never a first
|
|
33
|
+
placement** (placement stays the opt-in `${CLAUDE_SKILL_DIR}/references/modes/setup.md` — AD-009/AD-011 honesty intact), and a
|
|
34
|
+
placed bridge **newer** than the bundled copy is a stated skip naming the kit update (**never a
|
|
35
|
+
downgrade**). Like the other three reconciles it runs on **every** upgrade — including an
|
|
36
|
+
equal-head one — with no lineage-head bump. A *could not refresh* line is non-fatal: relay it
|
|
37
|
+
plainly with its recovery and continue the upgrade.
|
|
38
|
+
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 methodology-slot **and** hidden-mode footprint reconciles) ran first and may have changed things, so this is a proper exit report, not a no-op:
|
|
39
|
+
- **Report step 3's outcome in plain language** — for **each** pointer (workflow-methodology and orchestration-recipes) whether it was *added*, was *already present* (nothing changed), or was *skipped because the entry point is over its line limit* (the cap-refusal soft-skip from step 3, with its reason); 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 enforcement-script ensure *added* the `archive-decisions` pair to `scripts/` or found it *already present*; 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); 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`).
|
|
40
|
+
- **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*.
|
|
41
|
+
- **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`).
|
|
42
|
+
- **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).
|
|
43
|
+
5. Show the relevant `${CLAUDE_SKILL_DIR}/CHANGELOG.md` diff (entries newer than the project's stamp).
|
|
44
|
+
6. 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.
|
|
45
|
+
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`.
|
|
46
|
+
8. Re-stamp `docs/ai/.workflow-version` to the **deployment-lineage head** (`1.3.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) — 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 **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**.
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
### Mode: velocity
|
|
2
|
+
|
|
3
|
+
The opt-in onboarding **velocity profile** — it seeds a fixed, audited **read-only** Claude Code allowlist into `.claude/settings.json` so an agent stops idling on approval prompts for routine read-only commands while the maintainer is away. It is the family's **first programmatic `.claude/settings.json` writer** (attribution stayed an agent-driven prose merge). **In-agent, opt-in, writes only `.claude/settings.json`**, on one hard rule: **it never allowlists `commit`/`push`/`publish`** — so a direct commit/push/publish still ASKs; the only caveat is the trust-posture residual (below) — its closure is **shipped, opt-in: `${CLAUDE_SKILL_DIR}/references/modes/hook.md`**.
|
|
4
|
+
|
|
5
|
+
**Version-status routing (like the other writer modes):** read `docs/ai/.workflow-version` first — not-deployed → bootstrap; stamp < `1.3.0` → `upgrade`; stamp > head / unparseable → STOP. The tool enforces this in code too (`--apply` STOPs unless the stamp is the lineage head).
|
|
6
|
+
|
|
7
|
+
Run `node ${CLAUDE_SKILL_DIR}/tools/velocity-profile.mjs [--dry-run | --apply] [--kit-tools] [--accept-edits] [--cwd <dir>]`:
|
|
8
|
+
|
|
9
|
+
1. **`--dry-run` first, always** (the default — changes nothing). It prints: the fixed read-only core it would add; a **read-only advisory** that lists your `package.json` `scripts` as **unaudited candidates you may add BY HAND** (inspect each first) to `.claude/settings.json` / `settings.local.json` — the tool **never** writes them and flags obviously-mutating names as "do not add"; any **pre-existing non-read-only `Bash(...)` entries** to consider removing by hand; and the honest residual notice (below). It STOPs (zero writes) on a symlinked `.claude` / non-regular `settings.json`, malformed settings JSON, or an unsafe `permissions.defaultMode` — `bypassPermissions` or anything outside `default`/`acceptEdits`/`plan`, present in **either** `settings.json` or `settings.local.json`.
|
|
10
|
+
2. **Ask the opt-ins** via **`AskUserQuestion` where supported** — two separate choices, the safe option FIRST in each. First the **`--kit-tools` tier** (separate from `acceptEdits`; **"core only" remains the default answer** — seed the tier only on an explicit yes, then add `--kit-tools` to the `--apply` re-run). Then the `acceptEdits` opt-in:
|
|
11
|
+
- **"Keep per-edit approval prompts (recommended)"** — seed only the read-only allowlist; file edits still prompt.
|
|
12
|
+
- **"Auto-accept file edits (`defaultMode: acceptEdits`)"** — present the honest FULL posture: it auto-applies Edit/Write AND auto-runs `mkdir`/`touch`/`mv`/`cp` in the working dir, is paired with the read-only allowlist, and — stated plainly — a settings-level allow rule is a **trust posture, not a sandbox**: a read-only entry can still write a file via output redirection, and (Claude Code's allow rules do not inspect command substitution) could in principle run another command via `cmd $(…)`. velocity **never adds `commit`/`push`/`publish` as allow rules** — so a direct `git push` still ASKs — and the residual guard for the seeded core ships as the opt-in PreToolUse hook (`${CLAUDE_SKILL_DIR}/references/modes/hook.md`; probe-proven on the `--output` family — current engine builds already intercept redirection/substitution upstream). The approval **floor** (never auto-approved, with or without the tier): every writer `--apply`/`--write`/`--yes` still prompts; clobber-protection STOPs still stop; the three release asks (commit/push/publish) stay maintainer-owned. Note also that a `defaultMode` in `settings.local.json` would override this project-level write (local > project), since velocity writes only `.claude/settings.json`.
|
|
13
|
+
3. **Only on an explicit yes**, re-run with `--apply` (add `--accept-edits` only if they chose the second option). It merges-don't-clobber (preserves `includeCoAuthoredBy`, every key, and existing allow entries) and writes **only** `.claude/settings.json`.
|
|
14
|
+
4. **Surface delegation-readiness, read-only.** If they want a step run Delegated, set it with `/agent-workflow-kit set-recipe --set plan-execution.execute=delegated` (`${CLAUDE_SKILL_DIR}/references/modes/set-recipe.md`) or by hand-editing `docs/ai/orchestration.json`; **velocity itself never writes the orchestration config.**
|
|
15
|
+
|
|
16
|
+
**The `--kit-tools` tier (opt-in).** On top of the read-only core, `--kit-tools` seeds an audited kit-tool tier — every path **resolved absolute from the running skill at seed time**, so the posture is **fail-safe**: a moved or reinstalled skill leaves a stale rule that simply **prompts again** (re-run velocity to reseed; nothing widens silently). A seeded entry equals its covered dispatch line below with `${CLAUDE_SKILL_DIR}` replaced by the resolved skill dir and `${PROJECT_ROOT}` by this project's resolved root, **UNQUOTED** — a quoted path is a different byte string and will still prompt (a dead rule, not a hole). The covered dispatch lines (this list IS the documented-invocation source):
|
|
17
|
+
|
|
18
|
+
- `node ${CLAUDE_SKILL_DIR}/tools/recipes.mjs --active-line` — and any other args (wildcard)
|
|
19
|
+
- `node ${CLAUDE_SKILL_DIR}/tools/procedures.mjs <activity>` (wildcard)
|
|
20
|
+
- `node ${CLAUDE_SKILL_DIR}/tools/family-registry.mjs --json` (wildcard)
|
|
21
|
+
- `node ${CLAUDE_SKILL_DIR}/tools/detect-backends.mjs` (wildcard)
|
|
22
|
+
- `node ${CLAUDE_SKILL_DIR}/tools/commands.mjs` (wildcard)
|
|
23
|
+
- `node ${CLAUDE_SKILL_DIR}/tools/review-state.mjs --check` (wildcard)
|
|
24
|
+
- `node ${CLAUDE_SKILL_DIR}/tools/manifest/validate.mjs --strict <skill-dir>` (wildcard)
|
|
25
|
+
- `node ${CLAUDE_SKILL_DIR}/tools/release-scan.mjs <path>` (wildcard)
|
|
26
|
+
- `node ${CLAUDE_SKILL_DIR}/tools/run-gates.mjs --cwd ${PROJECT_ROOT}` — **EXACT byte-string only**, and honestly **project-exec, not read-only**: it runs YOUR declared `docs/ai/gates.json` commands — the same trust boundary the opt-in hook grants byte-exact per-cmd. A wildcard would be BROADER than that boundary (`--cwd <dir>` executes another project's declared gates), so the bare cwd-defaulting form, any other `--cwd`, and `--only` forms all still prompt.
|
|
27
|
+
- Writer previews, **exact arg-free dry-run byte-strings only** (for these three writers the arg-free default IS the preview): `node ${CLAUDE_SKILL_DIR}/tools/velocity-profile.mjs` · `node ${CLAUDE_SKILL_DIR}/tools/cheap-agents.mjs` · `node ${CLAUDE_SKILL_DIR}/tools/gate-hook.mjs` — every `--apply`/`--write`/`--yes` still prompts, always.
|
|
28
|
+
|
|
29
|
+
Honesty notes: tier entries get **NO PreToolUse-hook residual coverage** — the opt-in hook's residual ask-net guards only the seeded read-only CORE prefixes, so the tier rides the same settings-level residual posture as the core (redirection / command substitution are not inspectable at the settings layer; see the residual notice). A skill or project path that cannot survive UNQUOTED in a byte-exact rule (spaces, metacharacters, non-POSIX) **STOPs the tier up front with a clear error** — nothing is seeded. Anything you want covered beyond the tier — such paths, this repo's own relative-path spellings, other tools — stays a **BY-HAND add** to your settings, with the path your project actually reaches the kit by. Pre-existing `node …` allow entries that do NOT match the seeded tier byte-forms stay flagged by the advisory for hand review.
|
|
30
|
+
|
|
31
|
+
**Invariants:** creates `.claude/` if absent and writes **only** `.claude/settings.json` (no other file); **never** allowlists commit/push/publish; **never** writes `settings.local.json`; never commits; opt-in `acceptEdits`, never silent.
|
|
32
|
+
|
|
33
|
+
**Exit codes:** `0` done / dry-run; `1` a precondition STOP (stamp not current, unsafe mode, malformed settings, symlinked `.claude` / non-regular target); `2` bad arguments.
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
## Hand-off contract & bounded pointer reconciliation (composition root)
|
|
2
|
+
|
|
3
|
+
**Hand-off contract (explicit; tested independent of agent interpretation).**
|
|
4
|
+
- **Delegated** (memory valid): the kit passes the **target project dir** + the **three setup
|
|
5
|
+
answers** (visibility / language / attribution) to `agent-workflow-memory`, which writes
|
|
6
|
+
`docs/ai/` + `AGENTS.md` (carrying the **two empty pointer pairs** — `workflow:methodology` and
|
|
7
|
+
`workflow:orchestration`) + **`.memory-version`**. The kit then **reconciles both bounded pointers**
|
|
8
|
+
(below) and writes the kit-fallback **`.workflow-version`**. → **both stamps** present. In **hidden** mode the kit is the **single
|
|
9
|
+
hide authority**: after the hand-off it runs `tools/hide-footprint.mjs` (bootstrap step 9 — `${CLAUDE_SKILL_DIR}/references/modes/bootstrap.md`), which **absorbs
|
|
10
|
+
memory's project-local footprint lines** into the one canonical `.git/info/exclude` block and adds
|
|
11
|
+
the external footprint — so there is **no machine-global write** at any step (a stale memory's
|
|
12
|
+
residual global block is cleaned via the upgrade reconcile, below).
|
|
13
|
+
- **Fallback** (memory absent/invalid): the kit runs the bootstrap procedure (`${CLAUDE_SKILL_DIR}/references/modes/bootstrap.md`) from its own
|
|
14
|
+
bundled assets — whose entry-point template now ships **two empty pointer pairs** (`workflow:methodology`
|
|
15
|
+
+ `workflow:orchestration`) the kit reconciles + fills — and writes **`.workflow-version`** only.
|
|
16
|
+
Softly suggest installing `agent-workflow-memory` — never a prerequisite.
|
|
17
|
+
|
|
18
|
+
**Bounded pointer reconciliation (the kit is the ONLY writer of these slots).** After `AGENTS.md`
|
|
19
|
+
exists, run ONE command — `node ${CLAUDE_SKILL_DIR}/tools/inject-methodology.mjs reconcile
|
|
20
|
+
<project>/AGENTS.md` — which reconciles **two** bounded pointers in a single atomic write: the
|
|
21
|
+
**workflow-methodology** pointer (the plan → execute → review summary) **and**, right below it, the
|
|
22
|
+
**orchestration-recipes** pointer (the Solo / Reviewed / Council / Delegated vocabulary, routing to
|
|
23
|
+
`/agent-workflow-kit recipes`). Each is **one atomic operation per slot**: **ensure the slot exists**
|
|
24
|
+
(insert an empty marker pair at its anchor when a legacy entry point lacks one) → **inject the bounded
|
|
25
|
+
fragment ONLY IF the slot is empty** (a filled / user-customized slot is preserved verbatim) →
|
|
26
|
+
**cap-check** (the second pointer's check runs on the file *after* the first, so it guards the
|
|
27
|
+
**combined** ≤100-line budget). Both fragments are short summary + pointer, read **live from the
|
|
28
|
+
installed `agent-workflow-engine`** (`references/methodology-slot.md` + `references/orchestration-slot.md`,
|
|
29
|
+
the family's one source of truth) — **not** a bundled mirror, and **not** the full references. The
|
|
30
|
+
live read is **lazy + fail-loud**: the engine is consulted **only when a slot actually needs filling**,
|
|
31
|
+
so a deployment whose pointers are already filled reconciles to a zero-diff no-op even on a host
|
|
32
|
+
without the engine; but when a fill **is** needed and the engine is **absent/invalid**, reconcile
|
|
33
|
+
**STOPs** — report it in plain language with the one-line install command
|
|
34
|
+
`npx @sabaiway/agent-workflow-engine@latest init` (`npx @sabaiway/agent-workflow-kit@latest init`
|
|
35
|
+
installs the engine for you; translate, never leak tool internals). Contract per slot: exactly one
|
|
36
|
+
ordered `start → end` pair; a malformed slot (single, reversed, nested, duplicate) or a missing /
|
|
37
|
+
duplicate anchor → **STOP with an error**, never edit (the file is left byte-for-byte unchanged). The
|
|
38
|
+
**orchestration pointer is soft-skipped** (reported, never silent) when — and only when — adding it
|
|
39
|
+
would exceed the 100-line cap: the methodology pointer still lands and the upgrade continues.
|