### Mode: upgrade

<!-- opt-in-capability: family-freshness -->

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 · ${CLAUDE_SKILL_DIR}/references/shared/command-shapes.md

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.
2. **Never-downgrade gate — FIRST, before any write.** Compare the stamp to the **deployment-lineage head** (`3.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".
3. **The step-3 run-list — stamp-independent reconciles, BEFORE the equal-head short-circuit.** Reached only when the stamp **≤ head**. Run the **seven operations below in order, on every upgrade** (equal-head too) — no lineage-head bump, no migration file. Each backticked id anchors its rationale block below the checklist; a consent marker is a CONDITIONAL gate — an explicit yes is required exactly where the row's clause states one:

   1. `pointers` — `node ${CLAUDE_SKILL_DIR}/tools/inject-methodology.mjs reconcile <project>/AGENTS.md` → per pointer: added · already present · skipped (reported) · a hard STOP.
   2. `footprint` — `node ${CLAUDE_SKILL_DIR}/tools/hide-footprint.mjs --dir <project> --reconcile --dry-run` → visibility: visible · ambiguous · hidden — consent (conditional): ambiguous → ask which it is BEFORE anything; hidden → the conditional re-run without `--dry-run` (its surfaced paths ask per bootstrap step 9).
   3. `configs` — `node ${CLAUDE_SKILL_DIR}/tools/ensure-configs.mjs --reconcile --cwd <project>` → one line per ensure: `seeded` / `note-refreshed` / `refreshed` / `regenerated` / `already-current` / `customized-preserved` / `malformed-preserved` / `already-present` / `skipped-no-node` / `old-adr-layout-migration-instructed` / `failed`.
   4. `gates-migration` — `node ${CLAUDE_SKILL_DIR}/references/scripts/migrate-gates.mjs --kit-tools ${CLAUDE_SKILL_DIR}/tools --cwd <project>` → the preview plan · INERT checker · CUSTOMIZED entries, each named — consent: apply only on an explicit yes, re-run with `--apply`.
   5. `bridges` — `node ${CLAUDE_SKILL_DIR}/tools/setup-backends.mjs --refresh-placed` → per-bridge lines: refreshed · already current · skipped — with its stated reason (not placed / newer than the bundle / unsupported host) · `skipped-readonly` · could not refresh.
   6. `lens` — `node ${CLAUDE_SKILL_DIR}/tools/lens-region.mjs reconcile <project>/docs/ai/agent_rules.md` → per section: refreshed · already current · custom edit preserved · file absent / engine too old — skipped · over the line cap — refused · section absent — noted · a fully absent/invalid engine → hard STOP.
   7. `bridge-settings` — `node ${CLAUDE_SKILL_DIR}/tools/bridge-settings.mjs --reconcile` → outcome line(s), pasted verbatim: ok · absent · flagged · duplicates · unusable.

   **`pointers` — the bounded pointers.** 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 or current equal-head deployment gains them **without a lineage-head bump or a migration** (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).

   **Classify the exit — there are THREE non-zero exits + one soft in-band skip; handle each differently:**

   (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.)

   (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.)

   (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.

   **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).

   **`footprint` — hidden-mode footprint reconcile (D9 / AD-014).** A deployment does not record whether it chose `hidden`, so first **infer visibility** — the dry-run writes **zero bytes** and 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.

   **`configs` — the project-configuration ensures, ONE run.** The ONE command performs **all six** ensures described below — orchestration config · gate declaration · autonomy declaration · enforcement scripts · spec layer · navigator index — in a fixed order, and prints **one outcome line per ensure**: paste those lines into the step 4 / step 8 success report. Every SEED is **create-only** (an existing file is preserved byte-for-byte); the three refresh-class ops are named apart — the orchestration onboarding note (refreshed only while it still matches a canonical this kit shipped), the spec-layer reader and checker pairs (below) and the **navigator index**, a GENERATED artifact regenerated whenever it is missing or stale (never authored content, so there is nothing to preserve). One ensure failing **never** skips the others: each reports its own outcome and the run exits non-zero when any of them `failed`. The outcome tokens, by ensure: orchestration → `seeded` / `note-refreshed` / `already-current` / `customized-preserved` / `malformed-preserved`; gates and autonomy → `seeded` / `already-present`; scripts → `seeded` / `already-present` / `old-adr-layout-migration-instructed` / `skipped-no-node`; specs → `seeded` / `refreshed` / `already-present` / `customized-preserved` / `skipped-no-node`; index → `regenerated` / `already-current`; and any ensure may report `failed`, whose line OPENS with the cause (relay it with that cause — never soften it into a skip; an op that copies file by file also states when it stopped partway). The cause vocabulary is CLOSED — one of `race-unresolved`, `template-unreadable`, `bundle-unreadable`, `adr-layout-unverifiable`, `wrong-node-kind`, `write-refused`, `unexpected-error`, `generator-unlaunchable`, `generator-failed`, `index-probe-failed`, `index-stale-after-write` — and every cause that can only arise AFTER the generator ran (`generator-failed`, and `index-probe-failed` / `index-stale-after-write` when they follow a reported regeneration) DISCLOSES in its own line that a write may already have landed. **A non-zero exit STOPs this upgrade** — report the failed line and stop there, before the equal-head exit, the migrations and the re-stamp. Add `--dry-run` to preview without writing a byte. Like the pointer slots + the footprint reconcile, all six reach an equal-head deployment **without a lineage-head bump or a migration file** (they are `.json` / `scripts/` / a generated artifact / a seeded store root, inherently outside the docs cap-validator).

   **What the orchestration-config ensure does.** `docs/ai/orchestration.json` must exist **and its onboarding note must be current**: created from the canonical seed if missing; if it already exists, **every activity/slot the user set is preserved** and ONLY the `_README` note is refreshed, and only 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 (it normalizes CRLF/whitespace before comparing; a *customized* `_README` is preserved verbatim → `customized-preserved`; a *malformed* existing config is **preserved untouched + LOUD** → `malformed-preserved`, never clobbered and never silently skipped). The current note points at `/agent-workflow-kit set-recipe`. **Kit-owned:** in the **delegated** path memory only seeds/preserves the file (memory upgrade step 2) and this ensure applies the `_README` refresh; in the **fallback** path it does both. (Memory stays standalone.)

   **What the gate-declaration ensure does.** `docs/ai/gates.json` must exist: created from `${CLAUDE_SKILL_DIR}/references/templates/gates.json` if missing — the kit's OWN template twin, so a memory substrate predating the gates feature never silently loses it; **an existing file is preserved byte-for-byte** (a project's declared gate matrix is authored content; unlike the orchestration `_README` there is no note-refresh here).

   **What the autonomy-declaration ensure does.** `docs/ai/autonomy.json` must exist: created from `${CLAUDE_SKILL_DIR}/references/templates/autonomy.json` if missing (the kit's own template twin — a stale memory never silently loses the seed); **an existing file is preserved byte-for-byte** (a declared policy is authored content). 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).

   **What the enforcement-script ensure does.** A deployment older than the ADR-cascade feature has no `scripts/archive-decisions.mjs`, and an equal-head exit would otherwise never deliver it. The pairs must exist in the project's `scripts/`: `archive-decisions.mjs` + `archive-decisions.test.mjs` and `markdown-blocks.mjs` + `markdown-blocks.test.mjs`, copied from `${CLAUDE_SKILL_DIR}/references/scripts/` if missing; **an existing file is preserved, never overwritten** (drift repair belongs to a lineage migration). Nothing else is seeded — the other tokenizer-era tests red beside OLD archivers. **OLD ADR-store layout — DETECTED FIRST, never auto-migrated (AD-051, Decision 13):** on a `docs/ai/history/decisions-archive*.md` monolith (`old`), or no monolith but a deployed rotator predating the store (`old-unrotated`), the project is on the RETIRED 3-tier cascade, so the ensure writes NOTHING and reports `old-adr-layout-migration-instructed` (the new `archive-decisions.mjs` beside un-migrated monoliths would red their ADR gate). Relay it as the LOUD instruct it is: the fix is the opt-in **`/agent-workflow-kit migrate-adr-store`** (consent-gated; previews first, never commits), and the seed lands on the next upgrade. A layout the ensure cannot READ is `failed`, not a seed — it never writes on an unverifiable tree. The seed applies ONLY to a clean layout (neither signal), and a project with no `package.json` at its root reports `skipped-no-node` (these are Node enforcement scripts) while the three config ensures still run. 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.

   **What the navigator ensure does.** `docs/ai/index.md` is the always-loaded navigator the entry point declares, and it is GENERATED — no template ships it, so a deployment that never ran the generator boots from a broken entry point (and, on a Node project, carries a pre-commit hook that fails its own index check). The ensure runs the bundled generator's finalizer and reports `regenerated` (it was missing or stale — it was written) or `already-current` (nothing written). It never skips a No-Node project: the generator runs from `${CLAUDE_SKILL_DIR}/references/scripts/` on the agent host, not from the project's `scripts/`. **Its position in the run-list is EARLY and therefore NOT authoritative** — `lens` (and, on the migrated path, steps 6–7) still change `docs/ai` afterwards — so the authoritative run is the LATE `--only index` rung documented at both exits; the early one is idempotent and costs at most an `already-current` line.

   **What the spec-layer ensure does.** A deployment older than the feature-spec layer lacks `scripts/spec-schema.mjs` and `docs/ai/specs/index.md`, and its deployed `check-docs-size.mjs` predates the store collapse. In ONE order: the reader pair, then the checker pair — each seeded when absent and REFRESHED only while a file's bytes are a body a release shipped (an append-only digest catalog → `refreshed`; an edited body is preserved verbatim and withholds the writes that depend on it, the checker lane waiting on a byte-current reader pair); the store root is seeded from the bundled template, date rendered, ONLY behind a checker pair current after the run — an older or edited checker renders the store row by row and reds the hook's `--check-index`, so behind a custom checker the store root is NOT seeded and the line names the remedy (copy the pair from `${CLAUDE_SKILL_DIR}/references/scripts/` by hand, re-run). One token by precedence: `seeded` > `refreshed` > `customized-preserved` (an edited pair, and this run wrote nothing) > `already-present`; `skipped-no-node` without a `package.json`; every line states what this run did, and a write that stops partway names what landed. The legacy-ADR instruct never withholds it.

   **`gates-migration` — legacy gates.json migration (consented preview — D8).** An EXISTING declaration may still carry the retired review-ledger / fold-completeness checks. Run the preview (dry-run — writes NOTHING), show the user the exact plan, and only on an explicit yes re-run it with `--apply`: canonical legacy entries (matched by their documented single-invocation cmd forms) are REMOVED, the canonical `unit-tests` cmd gains the built-in lcov reporters, and the coverage-check gate is ADDED last — atomic and COMPLETE, so the migrated declaration satisfies `run-gates --final`. **The checker rides a PRODUCER or is not declared at all** (`${CLAUDE_SKILL_DIR}/references/modes/gates.md`): with no gate producing the lcov it reads, the migration does NOT add it, an already-declared one is reported INERT, the result is not called final-run-capable, and the preview prints the paste-ready suite cmd to declare by hand — nothing is ever removed for you. CUSTOMIZED entries are NEVER auto-touched: the preview names each with a paste-ready recovery, and the commit guard must NOT be installed until they are resolved. This is the ONLY gates.json writer at upgrade (the consented FILL preview runs at init).

   **`bridges` — placed-bridge refresh — stamp-independent, same gate, BEFORE the equal-head short-circuit.** Run
   `node ${CLAUDE_SKILL_DIR}/tools/setup-backends.mjs --refresh-placed` and **paste its per-bridge
   output lines verbatim** — every outcome line is composed by the tool (*refreshed* / *already
   current* / *skipped — not placed* / `skipped-readonly` / *could not refresh* + its recovery). It
   is **refresh-only**: it refreshes a bridge **`setup` already placed** from this kit's bundled copies
   and re-links its wrappers; an **absent** bridge is a stated skip, **never a first placement**
   (placement stays the opt-in `${CLAUDE_SKILL_DIR}/references/modes/setup.md` — AD-009/AD-011 honesty intact), a placed bridge
   **newer** than the bundle is a stated skip naming the kit update (**never a downgrade**), and
   `skipped-readonly` is an equal-version re-sync a **read-only** skills dir blocked this session (a
   stated skip, exit 0 — not a failure). That line never guesses at the tree: it carries one **proven**
   verdict from a read-only re-scan of the bundle-owned files **and** the wrapper links —
   `clean-parity` (nothing the refresh manages differs), `drifted` (every item **named** with the
   recovery that applies: a rerun REPAIRS what it can converge, and REFUSES *what it cannot converge
   under the refresh's no-follow and ownership policy* — **non-exhaustively**: a symlink where it must
   write, an incompatible node kind, a foreign wrapper target; those are named apart as
   resolve-by-hand-then-rerun), or `unverifiable` (every uncomparable item **named**, the remaining
   need for repair unknown). The line carries the exact cause per item — relay it as worded, never
   soften `unverifiable` into "already fine", never relay a resolve-by-hand item as rerun-fixable.
   Runs on **every** upgrade
   (equal-head too), no lineage-head bump; a *could not refresh* line is non-fatal — relay it plainly
   with its recovery.

   **`lens` — agent-rules lens refresh.** Relay the outcome in plain
   language: the planning/review lens section was **refreshed** to
   the current canon · was **already current** · carries a **custom edit — preserved verbatim** (+
   its one-line note) · the **file is absent — skipped** · the **engine is too old — skipped**
   (refresh it with `npx @sabaiway/agent-workflow-engine@latest init`, then re-run) · **over the
   file's line cap — refused** (trim the file, re-run). The section is found by its heading — no
   markers; a renamed heading is preserved + noted. A fully absent/invalid engine is the same hard
   STOP as (c). Exit 0 covers every soft outcome; only the STOP is non-zero. The same invocation
   also reconciles the **Communication (user-facing messages)** section from the kit's own bundled
   template canon (no engine involved) — relay its line too: *refreshed* / *already current* /
   *custom edit preserved + note* / *section absent — noted (never an insert)* / *over the line
   cap — refused*; an unreadable bundled template canon is its own loud STOP naming the kit
   reinstall command.

   **`bridge-settings` — bridge settings reconcile.** **Paste its outcome line(s)
   verbatim**: it validates the deployed host settings file's keys against the bundled manifests and
   **NEVER writes** it (the file lives outside every kit tree — D2), so an unknown/retired key is
   flagged + preserved, never edited. Runs on **every** upgrade; exit 0 covers every outcome.
   **The LATE navigator finalizer — the AUTHORITATIVE run, after the last `docs/ai` mutation.** `lens` above rewrites `docs/ai/agent_rules.md`, so the step-3 index ensure is already behind by the time the run-list ends. Re-run that ONE op here, before the step-4 report: `node ${CLAUDE_SKILL_DIR}/tools/ensure-configs.mjs --reconcile --only index --cwd <project>`. Relay **this** line in the report (it supersedes the early one; an untouched tree reports `already-current`, a failure STOPs the upgrade like any other ensure). On the migrated path the same rung runs again at the END of step 7 — after the migrations, before the step-8 re-stamp.
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:
   - **Report step 3's outcome in plain language** — for **each** `pointers` slot (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); the **six project-configuration ensure** (`configs`) lines exactly as the one ensure run composed them (orchestration config, gate declaration, autonomy declaration, enforcement scripts, spec layer, navigator index — their outcome tokens are enumerated in step 3), each rendered in plain language: what was created, what was left exactly as the user wrote it, and — for a `failed` line — what stopped it; for the navigator, relay the **late** `--only index` line, not the early one; the **`gates-migration`** result — *nothing to migrate*, the shown plan *applied* on your explicit yes, or the plan *left unapplied* (consent not given), with any INERT checker or CUSTOMIZED entries named; the **placed-bridge refresh** (`bridges`) outcome — paste the tool's per-bridge lines verbatim (they are already plain: *refreshed* / *already current* / *skipped — not placed* / `skipped-readonly` with its re-scan verdict / *could not refresh* + recovery); the **agent-rules lens** (`lens`) outcome (*refreshed* / *already current* / *custom edit preserved + note* / *file absent* / *engine too old* / *over the line cap*) and the **Communication-section** outcome (its own set: refreshed / already current / custom preserved + note / section absent — noted / over the cap — refused); the **bridge-settings reconcile** (`bridge-settings`) outcome (paste the tool's line(s) verbatim); and, for a hidden deployment, whether the hidden-mode footprint (`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`).
   - **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*.
   - **Render the mandatory Recommendations section — on this exit too, BEFORE the footer.** Run `node ${CLAUDE_SKILL_DIR}/tools/recommendations.mjs --cwd <project-root>` and PRESENT its output — from the `## Recommendations (agent-workflow)` header — in the user's conversational language: every fact, count and item from the tool, nothing added or dropped; commands, paths, hosts and rule strings byte-exact; show the raw tool block on request. The section is present-even-when-empty (with everything optimal the body is exactly `no recommendations — flow optimal.`) and VERDICT-FIRST — the composed verdict line renders from the frozen templates `{K} item(s) need attention` / `nothing is broken` / `{N} optional recommendation(s), apply any you want` / `optimality NOT attested — {M} probe check(s) skipped`. Then OFFER the consent-gated applies: the user picks items in plain language; surface each picked item's posture note, get the explicit confirm, then 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).
   - **Live host/session facts are tool-composed only.** Any claim this report makes about the current host or session state — prompts fired, sandbox scope, whether a bypass was needed, network reachability, approval counts — must trace to **live tool output** from **this session** (the lines you just composed, or a probe you ran this run); a memory/handover snapshot is **context, never report facts**, and a claim with no live signal is **omitted or explicitly marked unverified** — never asserted from recollection. Full clause: *Live host/session facts* in `${CLAUDE_SKILL_DIR}/references/shared/report-footer.md`.
   - **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`).
   - **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).
5. Show the relevant `${CLAUDE_SKILL_DIR}/CHANGELOG.md` diff (entries newer than the project's stamp).
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.
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.) **Then, before the stamp, re-run the LATE navigator finalizer:** the migrations of steps 6–7 may have added or changed `docs/ai` files, so run the one op again — `node ${CLAUDE_SKILL_DIR}/tools/ensure-configs.mjs --reconcile --only index --cwd <project>` — and relay THAT line in the step-8 report (idempotent: an untouched tree reports `already-current`; a failure STOPs this upgrade like any other ensure).
8. Re-stamp `docs/ai/.workflow-version` to the **deployment-lineage head** (`3.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 run-list outcomes, each as step 4 words it: the `pointers` slots, the `footprint` visibility verdict (and what a consented re-run migrated), the **six project-configuration ensure** (`configs`) lines — the navigator one being the late `--only index` run at the end of step 7, the **`gates-migration`** result, the **placed-bridge refresh** (`bridges`) lines (pasted verbatim), the **agent-rules lens** (`lens`) + **Communication-section** outcomes (same outcome sets as step 4), and the **bridge-settings reconcile** (`bridge-settings`) outcome (line(s) 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 **render the mandatory Recommendations section**: run `node ${CLAUDE_SKILL_DIR}/tools/recommendations.mjs --cwd <project-root>` and PRESENT its output — from the `## Recommendations (agent-workflow)` header — in the user's conversational language (every fact, count and item, nothing added or dropped; commands, paths, hosts and rule strings byte-exact; raw tool block on request; present-even-when-empty: `no recommendations — flow optimal.`), then OFFER the consent-gated applies (per picked item: posture note → explicit confirm → run EXACTLY the rendered one-liner; a HAND-APPLY item is never run by you — `${CLAUDE_SKILL_DIR}/references/modes/recommendations.md`). **Every current host/session claim in this report is tool-composed only** — prompts fired, sandbox scope, whether a bypass was needed, network reachability and approval counts must trace to **live tool output** from **this session**, a memory/handover snapshot is **context, never report facts**, and an unbacked claim is **omitted or explicitly marked unverified** (full clause: *Live host/session facts* in `${CLAUDE_SKILL_DIR}/references/shared/report-footer.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.
