ds-update-agentic-engineering · git:20260914.89e2ce1 · 2026-09-14 · sha256 f1f9e68ac75e49be

ds-update-agentic-engineering git:20260914.89e2ce1A

Immutable. This exact content never changes and is served at /api/v1/blob/f1f9e68ac75e49be.

---
name: ds-update-agentic-engineering
description: "Handles the full edit-sync-build-commit-push cycle for methodology and tooling files under your dinostack install (resolved at runtime from `~/.agentic/agentic-engineering-config.json` `repo_dir`, def"
user-invocable: true
---
# /ds-update-agentic-engineering

> Run the Activation preflight from `METHODOLOGY.md` before proceeding. If inactive, no-op and exit.

Handles the full edit-sync-build-commit-push cycle for methodology and tooling files under your dinostack install (resolved at runtime from `~/.agentic/agentic-engineering-config.json` `repo_dir`, default `~/DinoStack`).

**Distinct from `/ds-update`** (opposite direction): this pushes methodology edits *up* to upstream; `/ds-update` pulls the methodology *down* and reinstalls.

**In-repo only.** This command edits files inside the dinostack/DinoStack repo and spawns Workers that run in isolation worktrees. Isolation worktrees are created from the current session's git repo, not from `AE_REPO_DIR` - so running this from a different project corrupts both repos' worktree state and cleanup. Step 0a enforces that the session is rooted in the AE repo; otherwise it writes a handoff doc and stops without editing.

**When to use - use whenever ANY of these hold:**
- (a) The user asks to edit, add, or remove a rule, convention, agent definition, command, reference, or protocol doc under your dinostack install.
- (b) The user says "update the methodology", "change the protocol", "edit the wrap skill", "add an agent", "rename a command", or anything similar that implies changing a file in the dinostack repo.
- (c) You are about to use Edit or Write on any file whose absolute path is within one of the in-scope directories listed in Scope below (e.g. `<AE_REPO_DIR>/content/**`, the Codex native-skill generator inputs or outputs, the build scripts, `<AE_REPO_DIR>/hooks/**`, or `<AE_REPO_DIR>/.codex/hooks/**`). Files outside those directories (docs, README, unrelated build artifacts, top-level config) may be edited directly.

**Why it matters:** Without this command's Step 0 git sync, concurrent edits from multiple machines produce push conflicts and messy rebases; without Step 4 commit+push, edits pile up uncommitted locally.

**Do NOT bypass:** The main agent must NOT edit files in the in-scope directories listed in Scope with direct Edit/Write calls. The only exception is the permission-blocked path documented below: if a spawned Worker has returned a BLOCKED status citing Edit permission denial by the permission system, the main session may apply the edit directly per the permission-blocked path in this command. That is the sole carve-out. If you find yourself about to Edit or Write a file in one of the in-scope directories without that specific trigger, stop and invoke `/ds-update-agentic-engineering` instead. Files outside the in-scope list (docs, README, build artifacts, top-level config) may be edited directly and are governed by the normal Trivial/Elevated risk tiers.

**Scope:**

In scope (must route through `/ds-update-agentic-engineering`):
- `content/**` - the single source of truth for all rules, commands, references, and agent definitions
- `.codex/skill-frontmatter/**`, `.codex/skill-compatibility.yml`, `scripts/codex-skills.py`, and `.codex/skills/**` - Codex native-skill generation inputs, reviewed compatibility inventory, generator, and generated outputs
- `.claude/build.sh`, `.codex/build.sh`, `.cursor/build.sh` - build scripts that generate the adapter artifacts
- `hooks/**` and `.codex/hooks/**` - git hooks (pre-commit, etc.) and Codex session hooks (risk-reminder, stop-context)

Out of scope (direct Edit/Write is fine; normal Trivial/Elevated tiers apply):
- `docs/**` - the docs site (including `docs/index.html`, `docs/slides/**`, etc.)
- `README.md`, `CONTRIBUTING.md`, `LICENSE`, top-level config files (`vercel.json`, `.gitignore`, etc.)
- Build artifacts regenerated by the build scripts: `.claude/commands/**`, `.claude/agents/**`, `.codex/commands/**`, `.codex/agents/**`, `.codex/AGENTS.md`, `.codex/README.md`, `.cursor/commands/**`, `.cursor/rules/**`, `.cursor/README.md`
- `.vercel/`, `.agentic/compression-state.json`, and other machine-local state files

Note: `.claude/skills/dinostack/**` files are symlinks into `content/` - editing them is functionally editing `content/`, so they remain IN scope via the `content/**` rule above. This is a clarification, not a separate scope.

**Command authoring:** when a Step 1 edit adds or rewrites a command file (`content/commands/*.md`), follow `content/references/command-authoring.md` - trigger-keyword "When to use" descriptions, bad/good example-pair seeding, and the module-manifest header. New commands must be registered in `bin/ds-help` (the full command inventory); `content/SKILL.md`'s Commands section is a curated subset, so list a command there only when it warrants prominent placement.

## Step 0a - Directory gate (run before Step 0)

This is the first action of the command, before any git sync or edit. It guarantees the session repo IS the AE repo so that Worker isolation worktrees are created in the correct repo.

**Resolve `AE_REPO_DIR` once at the start of the command - it persists for all subsequent steps in this invocation:**

```bash
AE_REPO_DIR=""
AE_CONFIG="$HOME/.agentic/agentic-engineering-config.json"
if [[ -f "$AE_CONFIG" ]]; then
  AE_REPO_DIR="$(python3 -c "
import json, sys
try:
    with open(sys.argv[1]) as f:
        print(json.load(f).get('repo_dir', ''))
except Exception:
    print('')
" "$AE_CONFIG" 2>/dev/null)"
fi
if [[ -z "$AE_REPO_DIR" ]] || ! git -C "$AE_REPO_DIR" rev-parse --git-dir >/dev/null 2>&1; then
  AE_REPO_DIR="$HOME/DinoStack"
fi
```

Fallback behavior: if `~/.agentic/agentic-engineering-config.json` does not exist, has no `repo_dir` key, or `repo_dir` is not a git repository, `AE_REPO_DIR` defaults to `~/DinoStack` exactly as before.

**Canonical resolver:** the inline block above is the reference implementation. The same logic is extracted into `scripts/lib/repo-dir.sh` (`resolve_repo_dir` function), which is what hooks and the installer use at runtime. If you need to understand or audit the resolution behavior, `scripts/lib/repo-dir.sh` is the single source to read - the command spec above and the shell lib must stay in sync.

**Compare the session repo against `AE_REPO_DIR` by canonical path:**

```bash
SESSION_REPO="$(git rev-parse --show-toplevel 2>/dev/null || true)"
AE_REAL="$(cd "$AE_REPO_DIR" 2>/dev/null && pwd -P || true)"
SESSION_REAL="$(cd "$SESSION_REPO" 2>/dev/null && pwd -P || true)"
```

Decision:

- **In-repo (`SESSION_REAL` is non-empty AND equals `AE_REAL`):** proceed to Step 0. Worker isolation worktrees will be created in the AE repo, which is correct.
- **Cross-directory (no git repo, or `SESSION_REAL` does not equal `AE_REAL`):** the gate triggers. Do NOT spawn any Worker, do NOT edit any file, do NOT `cd` into `AE_REPO_DIR` to edit it. Instead:
  1. Capture the intended change from the user's request: a one-line title, the rationale, the target file(s) under `content/`, and any decisions already made in this session.
  2. Choose the handoff destination:
     - If `AE_REAL` is non-empty (the AE repo exists): write to `$AE_REPO_DIR/docs/planning/handoff-<YYYYMMDD-HHMMSS>-<slug>.md`. Create `docs/planning/` with `mkdir -p` if absent; it is local and gitignored per convention, so it never lands in a commit.
     - If `AE_REAL` is empty (`AE_REPO_DIR` is unreachable or not a git repo - a broken install): do NOT create a phantom directory there. Write the handoff to `$HOME/.agentic/handoff-<YYYYMMDD-HHMMSS>-<slug>.md` instead (`mkdir -p "$HOME/.agentic"`), and include the warning line from step 3 in the redirect message.
     Derive `<slug>` from the change title (lowercase, hyphenated); derive the timestamp from `date -u +%Y%m%d-%H%M%S`.
  3. When `AE_REAL` is empty, also include the broken-install warning line shown below. Print the redirect message below and STOP. Do not continue to Step 0.

Note: a git worktree derived from the AE repo (e.g. a path under `AE_REPO_DIR/.agentic/worktrees/`) resolves to its own toplevel, not `AE_REAL`, so it also trips this gate. That is intended: `/ds-update-agentic-engineering` runs from the main checkout at `AE_REPO_DIR`, never from a worktree derived from it.

Handoff doc template:

```markdown
# Methodology change handoff

- Created: <ISO8601 from `date -u +%Y-%m-%dT%H:%M:%SZ`>
- From session in: <SESSION_REAL, or "(no git repo)" if empty>
- Target repo: <AE_REPO_DIR>

## Intended change
<one-line title>

## Rationale
<why this change>

## Target files
- content/...

## Decisions already made
- <bullets, or "none yet">

## Next step
Open a Claude Code session rooted in <AE_REPO_DIR> and run `/ds-update-agentic-engineering`, referencing this handoff.
```

Redirect message template (print verbatim, substituting the resolved paths). When `AE_REAL` is empty, also include the broken-install warning line shown below (omit it when `AE_REAL` is non-empty):

```
/ds-update-agentic-engineering was invoked from outside the AE repo.
  Session repo: <SESSION_REAL, or "(no git repo)">
  AE repo:      <AE_REPO_DIR>
  (Warning: AE repo path does not exist or is not a git repo - check your installation.)
Editing the methodology from here would create isolation worktrees in the wrong repo, so I have NOT made any edits.
Handoff written to: <handoff path>
Next: open a new Claude Code session rooted in <AE_REPO_DIR> and run /ds-update-agentic-engineering (reference the handoff above).
```

## Step 0 - Pre-flight git sync

Before making any edits, the main agent (not a subagent - git state decisions require main-agent judgment) resolves the repo location and runs the following checks.

`AE_REPO_DIR` is already resolved in Step 0a and persists for this invocation.

1. `cd "$AE_REPO_DIR" && git fetch origin`
2. Run `git status --porcelain` to check for uncommitted changes.
3. Run `git rev-list --left-right --count HEAD...origin/main` to measure divergence.

Decision matrix:

- **Clean tree AND local == origin/main:** proceed to Step 1.
- **Clean tree AND origin is ahead (local behind):** capture `OLD_HEAD="$(git -C "$AE_REPO_DIR" rev-parse HEAD)"`, fast-forward pull (`git pull --ff-only origin main`), capture `NEW_HEAD="$(git -C "$AE_REPO_DIR" rev-parse HEAD)"`, then run the hook-change note check below, then proceed to Step 1.
- **Clean tree AND local is ahead (origin behind):** note this in the user-facing summary but proceed - the push in Step 4 will include the prior commits too.
- **Clean tree AND both are ahead (divergence):** STOP. Tell the user: "Local and origin have diverged (N local commits, M origin commits). Resolve the divergence manually before running /ds-update-agentic-engineering again." Do not attempt auto-merge or rebase.
- **Dirty tree (any uncommitted changes):** STOP. Show the user `git status` output and tell them to commit, stash, or discard before running /ds-update-agentic-engineering. Do not auto-stash - the WIP may be important and this command is not authorized to touch it.

**Hook-change note (after any pull in this step):**
```bash
HOOK_CHANGES="$(git -C "$AE_REPO_DIR" diff --name-only "$OLD_HEAD" "$NEW_HEAD" -- hooks/)"
```
If `HOOK_CHANGES` is non-empty, print the following informational note (substituting `HOOK_CHANGES` as a comma-joined list into `Changed:`), then continue. Never stop the flow for this - it is informational only, not an actionable warning. Step 4.5 below auto-refreshes this machine's local hook snapshot once this command's own edit is pushed, independent of the pull handled here.

> note: this update changed files under hooks/. A bare git pull no longer changes a running session's hooks (they load from a session-stable snapshot, not the checkout) - but this flow also runs the install step, which refreshes this checkout's SHARED hook snapshot in place. So any OTHER Claude Code session already open against this checkout will pick up the changed hooks on its next tool call. If that matters, have those sessions /exit and restart once this update finishes. Changed: `<comma-joined HOOK_CHANGES>`

If `HOOK_CHANGES` is empty, skip silently.

## Step 1 - Spawn a Worker

Spawn a Worker subagent with instructions (every section of this spawn prompt that the conductor composes is a slot per `content/references/subagent-protocol.md` §11 Output Expectations, "**Brief section form**"):
1. Read the current file(s) to be changed.
2. Apply the edit using the Edit tool.
3. If editing `content/rules/`, `content/references/`, or `content/agents/`: edit only the `content/` path. The corresponding `.claude/skills/dinostack/` and `.claude/agents/` paths are symlinks pointing into `content/` - but because the Worker runs in an isolation worktree, the edit lives in the worktree branch and is NOT live in the conductor's checkout until Step 2.5 cherry-picks it in. (On the permission-blocked in-place path where the conductor edits directly, the symlinks do make the change live immediately - but that is the exception, not the rule.) The other ten adapters are built artifacts, so the Step 3 build is still required before commit - the `adapter-sync` CI gate fails otherwise.
4. If editing `content/commands/`: edit only the `content/commands/` path. The `.claude/commands/*.md` copies are build artifacts - `build.sh` prepends the `/dinostack` prerequisite blockquote and writes the result to `.claude/commands/`. The build must be run after approval for the change to take effect.
5. Commit the edit to the isolation worktree branch with `git commit -s` and a short message describing the change.
6. Return the full diff, the commit SHA (full 40-character), and the worktree branch name.
7. If the Edit cannot be applied for any reason other than a Claude Code permission denial (file not found, ambiguous anchor, etc.), return a clear error description instead of a diff - do not attempt workarounds.

## Permission-blocked path

If the Worker in Step 1 returns a BLOCKED status explicitly citing an Edit permission denial by the Claude Code permission system (exact form observed in practice: "BLOCKED - Edit permission was denied by the permission system"), the main session may apply the edit directly, then present the diff to the user in Step 2 as normal. The user approval gate in Step 2 is preserved without exception - the main session never applies an edit and proceeds without human review. Step 3 proceeds only after approval.

## Step 1.5 - Vision-alignment check

Every invocation of this command edits methodology-core files by definition (see Scope above) -
this check runs unconditionally, with no separate proportionality gate.

Before presenting the diff in Step 2, read `docs/overview/vision.md` if it exists (it is the
operator-owned North Star for this repo) and apply its "How to use this for PR alignment" rubric
to the diff produced in Step 1: does the change advance at least one of the file's own listed
pillars without regressing another? Take the pillar set from the file itself, not from memory or
an inline list here - it changes over time and this step must never hardcode a stale copy.

Write a short alignment note (2-4 sentences - this is a check, not a report):
- Which pillar(s) the change advances, in one line each.
- Any pillar it plausibly regresses or trades off, named plainly - do not omit a real trade-off
  to make the note look cleaner.
- If `docs/overview/vision.md` does not exist, state that plainly and skip the rest of this step.

This is a **surface, not a gate**: a misalignment you notice does not stop the flow. State it in
the note and let the human approval in Step 2 be the decision point - per vision.md's own rubric,
misalignment is "a direction signal for the operator... not necessarily a request-changes
verdict." Do not skip this step because the diff looks small; a one-line rule change can still
shift the methodology's direction.

Carry the alignment note into Step 2.

## Step 2 - Present to the user

Show the diff, state what the change does, and include the vision-alignment note from Step 1.5. Remind the user that the per-adapter copies are build artifacts that Step 3 regenerates. Wait for explicit approval.

## Step 2.5 - Integrate the Worker's commit

**Skip this step on the permission-blocked in-place path.** On that path the conductor already edited the checkout directly (no isolation worktree), so there is nothing to cherry-pick - proceed straight to Step 3.

Otherwise (normal isolation-worktree path), after the user approves in Step 2:

1. Make sure the conductor's main checkout is current. Run from `$AE_REPO_DIR`:

   ```bash
   cd "$AE_REPO_DIR" && git fetch origin
   ```

2. Check whether local main has diverged from origin/main using the same decision matrix as Step 0:
   - **Local behind, fast-forwardable:** capture `OLD_HEAD="$(git -C "$AE_REPO_DIR" rev-parse HEAD)"`, `git pull --ff-only origin main`, capture `NEW_HEAD="$(git -C "$AE_REPO_DIR" rev-parse HEAD)"`, run the same hook-change note check as Step 0 (`git -C "$AE_REPO_DIR" diff --name-only "$OLD_HEAD" "$NEW_HEAD" -- hooks/`; print the shared note when non-empty, never block), then continue.
   - **Diverged (both sides ahead):** STOP. Tell the user: "Local and origin have diverged since Step 0. Resolve the divergence manually before continuing." Do not force or auto-merge.
   - **Local ahead or equal:** proceed.

   This closes the window where the Worker's worktree was based on a now-stale main tip - the cherry-pick lands on the current HEAD after this sync.

3. Cherry-pick the Worker's commit into the conductor's checkout - use the full 40-character SHA returned in Step 1, NOT the worktree branch name:

   ```bash
   git cherry-pick --no-commit <worker-sha>
   ```

   **Do NOT use `git merge <worktree-branch>`.** The worktree branch is based on the main tip at Worker spawn time. If main has advanced since then, merging the branch can resurrect files that were deleted on the current main - the "worktrees do not replay deletions on re-base" hazard. Cherry-pick applies only the delta the Worker introduced, which is safe regardless of base drift.

4. Verify the cherry-pick applied cleanly - two checks in order:

   - **Conflict check (first):** Run `git ls-files -u` and inspect `git status --porcelain`. If `git ls-files -u` produces any output, or the status shows any line with a leading `UU`, `AA`, or other unmerged-path state code, or `.git/CHERRY_PICK_HEAD` still exists, the cherry-pick conflicted. Run `git cherry-pick --abort` immediately and STOP - report the conflicting path(s) to the user. This is the same-file base-drift collision that a concurrent PR to the same `content/` path produces during the Worker run. Do NOT proceed to Step 3.

   - **Scope check (second):** If no conflicts, run `git status --porcelain` and verify the working tree shows ONLY the intended `content/` source path(s). If any other file appears as modified or added, STOP and show the user - a wider delta means the worktree base drifted further than expected or the Worker touched something outside its scope.

## Step 3 - Run the build

After approval, if the diff touches ANY file under `content/`, rebuild every adapter so the committed adapter artifacts stay in sync. The `adapter-sync` CI gate rebuilds all of them and fails on any drift, so a partial build - or skipping the build for a rules/references/agents edit - makes the push fail. Run from `$AE_REPO_DIR`:

```bash
cd "$AE_REPO_DIR" && \
bash .claude/build.sh && bash .cursor/build.sh && bash .codex/build.sh && \
bash .gemini/build.sh && bash .kimi/build.sh && bash .opencode/build.sh && \
bash .omp/build.sh && bash .pi/build.sh && bash .hermes/build.sh && bash .openclaw/build.sh && \
bash .copilot/build.sh
```

Then run `git status --porcelain` and confirm the only changes are the `content/` source file(s) plus their regenerated adapter copies. If any unrelated source file shows as modified, STOP and show the user - a build script can silently revert an out-of-date source file (the adapter-rebuild revert hazard).

If the diff touches `content/sections/`, also regenerate the methodology baseline in the same commit: `scripts/.methodology-baseline.sha256` is a per-file SHA256 manifest of content/sections/ and must be updated in the same commit as any section change (see `scripts/check-methodology-drift.sh`). This is a separate CI gate from `adapter-sync`. Regenerate it with:

```bash
bash scripts/check-methodology-drift.sh --regenerate
```

Note: `.claude/skills/dinostack/` and `.claude/agents/` are symlinks into `content/`, so `content/rules/`, `content/references/`, and `content/agents/` edits are immediately live in your own Claude session with no build. The build above is still required so the other ten adapters' committed artifacts match `content/`.

## Step 3.5 - Docs update check

After the build, evaluate whether the content change affects concepts covered in `docs/index.html` or `docs/slides/`. This step runs before the commit so any doc updates land in the same commit.

**Significant changes** (require action): new or removed protocol behavior, changed table values (e.g. tier table, risk table), added/removed/renamed rules, agents, or commands, or anything a reader of the published docs would now encounter as incorrect.

**Minor changes** (skip silently): phrasing adjustments with no behavioral or structural effect.

**If the change is significant:**

1. Check which docs reference the affected concept. The main reference is `docs/index.html`; slides live in `docs/slides/`. Use grep to locate the relevant sections quickly.
2. For simple value changes (a table cell, a model name, a step number): apply the update directly to the doc file(s) and include them in the commit.
3. For structural changes (new rule, new agent, new command, removed section): surface a specific note to the user - name the exact doc file(s) and section(s) that are now stale, and what needs updating. Do not just say "consider updating docs". Then wait for the user to decide whether to update now or track it separately before proceeding to Step 4.
4. If any `docs/slides/*-slides.md` deck content changed as part of this update, run `bash scripts/build-slides.sh` and stage the regenerated `docs/slides/*.html` into the same commit. Never hand-edit the `.html` - it is build output enforced by the `slides-sync` CI gate. Upgrading marp is an intentional same-PR action: bump `scripts/package.json`, regenerate `scripts/package-lock.json`, and rebuild all decks in the same commit.

## Step 4 - Commit and push

Only runs if Steps 1-3 actually made changes.

1. Run `git status --porcelain` to list what changed. Expect exactly: the `content/` source path(s) applied by the Step 2.5 cherry-pick (or, on the permission-blocked in-place path, edited directly by the conductor) plus the adapter artifacts regenerated by Step 3. There is no separate "files edited in Step 1" set in the conductor checkout - the Worker's edit reaches this checkout only via the Step 2.5 cherry-pick.
2. Verify the staged/unstaged file list matches what was intended. If unfamiliar files appear (WIP that somehow materialized), STOP and show the user.
3. Stage the edited files by explicit path - never `git add -A` or `git add .`. Explicitly name each file path on the `git add` command line. This includes both the `content/` source file and all adapter artifacts regenerated by Step 3.
4. Capture `PRE_PUSH_HEAD="$(git -C "$AE_REPO_DIR" rev-parse HEAD)"` - the pre-commit HEAD, before the commit below is created. Step 4.5 diffs from this point to detect whether the commit this step is about to push touches hook paths.
5. Commit with `git commit -s` and a message summarizing what rule/command changed. Format: `docs(protocol): <short summary>` or the natural commit type for the file being edited. No Claude footer. No em dashes. The `-s` adds a `Signed-off-by:` trailer from the repo's configured git identity (which must match the commit author email); the dinostack repo enforces a DCO Signed-off-by check, so the `-s` is mandatory here or CI fails.
6. Push with `git push origin main`.
7. If push is rejected because origin is ahead (race condition - someone pushed between the Step 2.5 sync and the Step 4 push): run `git pull --rebase origin main`. If the rebase is clean, retry the push. If the rebase has conflicts, STOP and escalate to the user with `git status` output showing the conflict files. Do NOT force-push, do NOT `git rebase --abort`, do NOT `git reset`. The user resolves the conflict manually.
8. Report the final commit SHA and push result to the user.

## Step 4.5 - Refresh local hook snapshot

Only runs if Step 4 actually pushed a commit. Best-effort and non-blocking - a failed refresh warns but does not fail the flow.

**Why this step exists:** Step 3 runs `build.sh`, never `install.sh`. `hooks/**` and `.codex/hooks/**` are in scope for this command (see Scope above), so a maintainer who edits a hook file and runs `/ds-update-agentic-engineering` would otherwise push the change but keep running their own pre-edit local hook snapshot on this machine - the dogfooding gap. This step closes it automatically.

**4.5a - Detect whether the pushed commit touched hook paths**, using the commit range from Step 4 (`PRE_PUSH_HEAD` captured before the commit, to the current HEAD after the push - and after any Step 4 item 7 rebase - succeeded):

```bash
POST_PUSH_HEAD="$(git -C "$AE_REPO_DIR" rev-parse HEAD)"
HOOK_PATHS_CHANGED="$(git -C "$AE_REPO_DIR" diff --name-only "$PRE_PUSH_HEAD" "$POST_PUSH_HEAD" -- hooks/ .codex/hooks/ .codex/config/hooks.json .gemini/hooks/ .kimi/hooks/)"
```

If `HOOK_PATHS_CHANGED` is empty, skip the rest of this step silently.

**4.5b - Auto-run the refresh (no separate confirmation):** Step 2's user approval already covered this diff, including any hook-path edits within it, and `install.sh` is idempotent and scoped to this machine's adapter config directories (`~/.claude`, etc.) - re-running it is not a novel side effect requiring its own gate.

Refresh `.claude` (always, locked) plus every other adapter marked `true` in `~/.agentic/agentic-engineering-config.json`'s `adapters` map. If that config file or its `adapters` map is absent or unreadable, fall back to `.claude` only:

```bash
AE_CONFIG="$HOME/.agentic/agentic-engineering-config.json"
REFRESH_ADAPTERS="$(python3 -c "
import json, sys
try:
    with open(sys.argv[1]) as f:
        cfg = json.load(f)
    adapters = sorted(k for k, v in cfg.get('adapters', {}).items() if v)
except Exception:
    adapters = []
if '.claude' not in adapters:
    adapters.append('.claude')
print(' '.join(adapters))
" "$AE_CONFIG" 2>/dev/null || echo ".claude")"

for adapter in $REFRESH_ADAPTERS; do
  if [[ -x "$AE_REPO_DIR/$adapter/install.sh" ]]; then
    bash "$AE_REPO_DIR/$adapter/install.sh" || echo "warning: $adapter/install.sh refresh failed - this machine's $adapter hook snapshot may still be stale. Re-run manually: bash $AE_REPO_DIR/$adapter/install.sh"
  fi
done
```

**4.5c - Report:** include the refreshed adapter(s) and their snapshot path(s) in the final summary shown to the user alongside the Step 4 commit SHA and push result. On a refresh failure, surface the warning line verbatim rather than silently swallowing it.

Note: This command governs edits to its own source file - the recursion is intentional. Use `/ds-update-agentic-engineering` when modifying this file. Because of Step 0a, that editing session must itself be rooted in the AE repo - if you are elsewhere, the gate produces a handoff and you continue in a session opened in `$AE_REPO_DIR`.