Skip to content
Back to skills

Align

ASecurity

Single interactive entry point to the persistent layer — an interview-driven session that records or revises a `strategy-*` intention node. Frames the input as a new strategy or an edit to an existing one, runs a Socratic dialectic to fix intent/placement/benefit/signal/conditions, advises on delegation capture, retains tactical byproducts as draft tactic nodes, and lands the record via `graph-commit`. With no prompt, runs an onboarding funnel — orient, validate the deployment, walk to a craf...

  • 3 stars
  • 0 votes
  • 0 copies
  • 0 views
  • Added September 3, 2026
ai-agentsrustgoshellbashnodegitdocumentation

Works with

  • terminal
  • cli

Security analysis

A100/100

Pro scans all 2 files and shows the line behind each finding

Scanned September 3, 2026

npx -y skills add natb1/commons.systems --skill align --agent claude-code

Installs into .claude/skills of the current project.

Are you the author of Align?

Add the live security badge to your README. It updates with every re-scan.

Security grade badge for Align
[![Security: A — Skills Directory](https://www.skillsdirectory.com/api/skills/natb1-align/badge)](https://www.skillsdirectory.com/skills/natb1-align)

More formats (shields.io, HTML) on the badges page. Keep it an A: scan every change in CI with Pro.

Download with Pro
SKILL.md
---
name: align
description: Single interactive entry point to the persistent layer — an interview-driven session that records or revises a `strategy-*` intention node. Frames the input as a new strategy or an edit to an existing one, runs a Socratic dialectic to fix intent/placement/benefit/signal/conditions, advises on delegation capture, retains tactical byproducts as draft tactic nodes, and lands the record via `graph-commit`. With no prompt, runs an onboarding funnel — orient, validate the deployment, walk to a crafted prompt — that falls through into the same interview. On-demand only; never files a GitHub issue.
user-invocable: true
model: opus
---

# Align

**On the `model` field's enforcement (strategy-token-economy clarification 10,
2026-07-16):** `/align` is `user-invocable: true` — it runs on the
interactive main loop, not via a `context: fork` subagent launch. A `model:`
field in frontmatter is confirmed honored for `context: fork` skills; for
`user-invocable` main-loop skills like this one, honoring is unconfirmed. This
skill stays whole-session Opus because its interview dialectic is
non-delegable and it has no dispatch launch path to carry an explicit
`model: opus` argument the way `/align-tactics`' Step 3 subagent launch does.
If the harness does not honor this field on the interactive path, the default
here is intended-not-guaranteed — backed by the token audit's by-node/by-phase
attribution (`strategy-token-economy`'s sensor) reading after the fact whether
the session actually ran on Opus.

`/align [optional requirement text]` records or revises a
`strategy-*` intention node under interview. It supersedes `/file-issue`'s
requirements-definition role for the graph-native dispatch model
(`intentions/strategy-graph-native-dispatch.md`): a strategy enters
execution by being recorded here, not by becoming a GitHub issue. Full
spec and coverage matrix: `intentions/tactic-graph-native-dispatch.md`
§2.2 and §4.

This skill never files, edits, or closes anything on GitHub. Its only
artifact is one or more `intentions/strategy-*.md` (and, incidentally,
`intentions/tactic-*.md` draft) nodes landed on `origin/main`.

**Record-completeness contract** (strategy clarification 31 / condition 7):
the graph record is the **sole carrier** from this skill to `/align-tactics` —
the target router queues re-evaluation as a fresh session with only the
graph, no memory of this interview. Every decision, edge-case resolution,
and tactical byproduct this round produces must land in the node
(`clarifications`/`attributes.conditions`/`success_signal`, plus draft-tactic
bodies) at record time (step 5); running `/align-tactics` in the same
session afterward is a bootstrap safety net, not a substitute for a
complete record. Step 6's clause-coverage walk is the check that discharges
this condition.

The interview **is** the audit (clarification 2 on
`strategy-graph-native-dispatch`): unlike `/file-issue`, there is no
downstream PR review step that checks the requirement was captured
correctly. Take the dialectic seriously — a rushed interview is a
permanent gap in the record, not a draft someone else will catch.

## Trigger and input

On-demand only, human-invoked. The two branches are fixed by
prompt-presence:

- **With a prompt** — treat the text following `/align` as the
  **requirement text** and run step 1's "With requirement text" branch
  (the interview).
- **With no prompt** — run step 1's **onboarding funnel** branch, which
  ends by falling through into the interview with a crafted prompt.

Never `AskUserQuestion`-free for the interview itself (step 2) — this
skill's whole value is the dialectic. Reserve `AskUserQuestion` for
bounded choices with a recommended option listed first, per the
2026-07-03 prototype run's convention; open-ended elicitation is a normal
conversational turn, prose reply captured as-is — never `AskUserQuestion`.
That split is this skill's standing elicitation convention, and it binds
the onboarding funnel's Socratic walk as much as the interview proper.

## Step 0 — Claim and isolate

Before the first write, claim the target node id and author in its
worktree — the same uniform node-id reservation discipline the router's
fan-out workers follow (`strategy-graph-native-dispatch`'s 2026-07-06
concurrency-safety clarification). Never author strategy edits in the
shared `main` checkout: a second concurrent session's dirty tracked file
blocks your `graph-commit` rebase, and a stale read races live phase state
(both happened live the day that clarification landed).

1. **Resolve the target node id.** For an edit or a doctrine round, it is
   the primary `strategy-*` being edited — claimed
   before the first write. A brand-new strategy has no id until step 5
   constructs it; author it in the worktree and claim its id as soon as the
   id is fixed.
2. **Enter the worktree — on a verified-fresh checkout.** Otherwise create
   or re-enter it, and do all authoring and the step-5 `graph-commit` from
   there. The worktree **is** the claim: the same live-session ⇔ worktree
   liveness rule the router uses, so no separate lock is needed. **Prefer
   `provision-node-worktree`**
   (`.claude/skills/dispatch-propagate/scripts/provision-node-worktree`): it
   fetches `origin/main` and cuts the worktree fresh from it, so no separate
   freshness check is needed after it. If instead you use native
   `EnterWorktree`, **or** re-enter an **already-existing** worktree by any
   means **other than `provision-node-worktree`**, running
   `.claude/skills/dispatch-propagate/scripts/assert-worktree-fresh` is
   **mandatory** as the very first action in that worktree — **before any
   graph read** (before Step 1's overlap grep / `readNode`, etc.). A non-zero
   exit means the checkout is stale **or** the `git fetch` itself failed;
   either way, **STOP** and freshen (`git fetch origin main && git merge
   origin/main`) before proceeding. Never treat a failed fetch as license to
   proceed on unverified state.
4. **Load the ancestry projection.** After entering the worktree, load the
   ancestry projection for the claimed node: read `.claude/ancestry-context.md`
   if `provision-node-worktree` wrote it, otherwise run `node --import tsx/esm
   packages/intentionsutil/scripts/node-ancestry.ts <node-id> --dir
   "$(pwd)/intentions"` and hold its output.

   This projection is read-only decision context for in-scope, plan-under-determined
   judgment calls; the node body remains the sole work contract (a plan that assumes
   the projection exists is still an incomplete record), and a perceived plan-vs-ancestry
   conflict parks to `office_hours` with a recommendation — never self-expanded or
   self-reduced scope.

**Doctrine-recording rounds pin the pace curve.** A round that records
governing dispatch doctrine (a concurrency-safety or
dispatch-discipline clarification) pins
`dispatch.config/target-workers.json` to floor 0 / terminal 1 for its
audit window so the fleet quiesces while the doctrine settles, then
restores the standing 50 / 100 curve after — the practice the 2026-07-06
clarification records.

## Step 1 — Frame

**With requirement text:**

1. **Multi-topic separation.** If the text bundles independent concerns —
   each would need its own `success_signal` and could be pursued to
   completion without the other — treat it as N separate strategies. Run
   steps 2–6 once per concern, each producing its own node and its own
   `graph-commit` call in step 5. Do not force unrelated concerns into one
   node to avoid re-running the interview.
2. **Duplicate / overlap detection.** Run
   `node --import tsx/esm packages/intentionsutil/scripts/align-strategy-census.ts intentions`
   and grep its per-strategy statement dump for keyword overlap with the
   requirement (statement, rationale, and clarification text) — one flat
   dump to scan instead of grepping N separate `intentions/strategy-*.md`
   files. A strong match means this is an **edit**, not a new strategy —
   read the matched node in full via `readNode(intentionsDir, id)` (or just
   read the file: only the frontmatter is authoritative) before the
   interview, and use it as the dialectic's starting point.
3. **New vs. edit.** No strong overlap → new strategy: identify which
   `virtue-*.md` node(s) it serves (a strategy's `serves` must resolve to
   `kind: virtue` — `validateGraph` rule 8). Overlap found → edit: confirm
   with the author (`AskUserQuestion`, recommended: "edit
   `strategy-<id>`") before proceeding.

**With no requirement text — onboarding funnel:**

This is the fork/consuming-repo entry path, folded in from the retired
`/align-init` skill: orient the practitioner, verify the deployment
actually works, then walk them to a prompt and run the interview on it.

1. **Orient.** Give the practitioner a one-screen description of what they
   have deployed: a harness for long-horizon autonomous workflows built
   around the **intention graph** — the versioned store under `intentions/`
   whose node kinds are defined by the `intentions/kind-*.md` nodes:
   - **Virtues** (`virtue-*`) — permanent dispositions; the roots of the
     graph. They never complete; everything else justifies itself against
     them.
   - **Strategies** (`strategy-*`) — persistent, condition-bearing,
     signal-carrying goals. A strategy records the author's intent, the
     circumstances it is contingent on (`attributes.conditions`), and the
     `success_signal` that would validate it.
   - **Tactics** (`tactic-*`) — transient, completable, delegable work.
     Each claude-eligible tactic carries a full clean-session plan in its
     node body and is walked through execution phases by the dispatch
     router.
   - **Delegations** — attachment records: which work is handed to whom
     (human → AI → procedure), with the divergence/irreversibility axes
     that bound capture risk.

   The router reads the graph at `origin/main` and schedules eligible
   tactics autonomously; the two align skills (`/align` and
   `/align-tactics`) are the human interface that populates it. Keep the
   orientation to one screen — the schema reference is
   `intentions/kind-kind.md` for anyone who wants depth.

2. **Validate deployment.** Confirm the tooling actually works in this
   checkout before interviewing anyone. Run
   `.claude/skills/align/scripts/validate-deployment.sh`, which performs the
   three local checks (no `gh`, no network) and reports each result with its
   own remediation diagnostic:
   - **Workspace installed** — `npm test --prefix packages/intentionsutil`.
     On failure (tests fail, or `node --import tsx/esm` cannot resolve) the workspace is
     not installed: the script says to run `npm ci` at the repo root and
     rerun.
   - **Graph clean** — `node --import tsx/esm packages/intentionsutil/scripts/validate-graph.ts
     intentions` (dangling refs, cycles, schema). The store directory is a
     REQUIRED argument with no default (strategy-graph-native-dispatch
     clarification 194/242) — that is what makes a missing or unreadable
     `intentions/` a loud failure rather than an empty node list reported as a
     clean graph. On failure — a missing or unreadable `intentions/` directory,
     or a schema violation — the script reports the exact error. Do **not** proceed to the funnel's remaining steps over a
     broken store.
   - **Router heartbeat** — `systemctl --user is-active
     dispatch-claude-daemon.service` (Linux deployments; the daemon hosts
     the dispatch tick). An inactive daemon is non-fatal: the script points
     at the home-manager module (`nix/home/claude-code.nix`, instance
     template `examples/office-hours-nate/flake.nix`) and the funnel
     continues — the interview itself does not need the daemon — but say
     clearly that nothing dispatches until the heartbeat is wired.

   Keeping these rote checks in a script rather than inline prose is the
   mechanical-floor doctrine: scripts carry what is mechanical, skill prose
   carries only what needs judgment.

3. **Walk to a prompt.** Elicit, Socratically, what the practitioner wants
   recorded or changed — one open question at a time, as a normal
   conversational turn with the prose reply captured as-is. This is
   open-ended capture, never `AskUserQuestion` (the "Trigger and input"
   convention above; `AskUserQuestion` stays reserved for bounded gates).
   Converge on a single crafted prompt stating the requirement in the
   practitioner's own terms, and confirm it reads right to them.

   Then **fall through directly into this same step's "With requirement
   text" branch** using that crafted prompt as the requirement text,
   continuing in-session. Do **not** re-invoke `/align` through the Skill
   tool on itself — this is a continuation, not a new invocation.

**Note — no virtue-review step.** This funnel deliberately omits
`/align-init`'s old "Review virtues" step (its rung-0 virtue-review flow);
that flow retires with `/align-init` rather than folding in. Virtue
recording now happens as a natural consequence of running `/align <prompt>`
normally — the "New vs. edit" logic above already identifies which
`virtue-*` node a new strategy serves, and surfaces the gap when none fits.

**Mechanics.** Keyword grep (step 3's delegation sweep) only **shortlists**
candidates; it never disposes of one — disposition requires reading each
shortlisted node in full. Such sweeps may fan out to `Explore` subagents
returning compact `path:line`-anchored findings — the interview dialectic
itself (step 2 onward) is never delegated.

## Step 2 — Interview dialectic

Run this once per strategy target selected in step 1 (new or edit).

### Interview type — classify first, and state it

Every interview is one of two types, fixed by where the authoritative model of
the subject currently lives (2026-07-09 interview-types doctrine,
`strategy-explicit-intent` clarification "What interview types do align
sessions run, and which rules bind each?"). State which type each interview is
before the dialectic proper begins.

- **Type b — the record is authoritative and the author has drifted from it or
  not yet internalized it** (author education). Full periagoge rules bind:
  probes cite the record **at `origin/main`** as the fixed object — never the
  working tree (a stale checkout presents already-amended doctrine as current),
  never session memory; the author articulates their own account before
  Claude's account appears; compulsion is argument only — press until resolved,
  never impose. Three exits stay open to the author at all times: amend the
  record (the dialectic wins), defer (held on trust under a deferred decision stamp — see
  "Deferral mechanics" below), or claim authority over Claude's account or a
  referenced tradition (an intentional divergence, recorded). Claude never
  blocks and never withholds recording.
- **Type a — the model lives in the author, unrecorded or not yet formed**
  (Claude elicitation and education). Visible-refusable-draft rules bind:
  propose viable seams and explore their consequences to author feedback. Joint
  inquiry where nothing is settled anywhere is type a's elicitation limb, not a
  third type — it resolves by the same visible-draft machinery, and parsimony
  declines the extra seam.

**Run type b before type a when required author knowledge is unrecorded.**
Type b's object is the topic's **ground** — the knowledge needed to decide,
across the record at `origin/main` and the relevant traditions, recorded and
Claude-internal alike — not merely the pending decision surface. A type b
confined to ratifying decision mechanics is the named deviation; explore the
ground first, then take the formed decision into type a.

In either type, always surface graph-internal inconsistencies, inconsistencies
between the graph and Claude's internal knowledge (a good the author may not
yet have seen), and parsimony findings (redundant seams).

### Question mechanics — every round, both types

Every `AskUserQuestion` round in this step — the step-2.1 intent confirmation,
the step-2.9 design-canvas question, and any other — carries three things (the
standing feedback loop of both types, not a type-a convenience):

1. a **recommendation** — your best answer, listed first — carrying **in the
   same option** the authority under which it is accepted: **ratified**,
   **delegated**, or **deferred** (the authority-in-option rule,
   `strategy-discovered-requirements` 2026-08-31 clarification, superseding
   the earlier separate accept-as-deferral option);
2. an honest **boldness assessment** on that recommendation — how much of it
   rests on the graph and this session's context versus Claude-internal
   knowledge the author has not verified;
3. **other options presenting alternatives with their trade-offs** — never
   authority re-spellings of option 1. The author accepts a disposition at a
   *different* authority via the free-text "Other" reply, which every
   question already carries.

Propose the authority by these ratified rules (same clarification): **ratify**
for authority and vocabulary boundaries, charters and principles that bind
future judgment, amendments touching ratified content, and transcriptions of
the author's stated position; **delegate** for implementation detail under a
ratified principle — mechanically validatable, cheaply reversible, reviewable
through the normal queues; **defer** for Claude-authored substance the author
has not examined and cannot cheaply examine in-interview, and for the first
concrete instance of a newly delegated pattern; escalate one level toward
ratify when being wrong is expensive, irreversible, or capture-shaped. An
accepted deferral still follows "Deferral mechanics" below.

**Deliver a question's motivating context — including each recommendation's
boldness — where the author will actually read it:** inside the
`AskUserQuestion` tool itself (question text, option descriptions, preview
panes) or in a prior turn the author has already read and responded to. The
author reads neither Claude's thinking nor same-turn preamble emitted before
the question call, so context living only there has not been provided — a
boldness assessment stated only in preamble is undelivered. A question must
never reference material the author has not seen.

### Deferral mechanics

(Amended 2026-09-01 under `strategy-graph-review-curriculum`'s 2026-08-30
record-time-enrollment amendment: record-time enrollment mints **nothing** —
/align records decision stamps, and the review queue derives from them. The
former born-parked review-item typology this section carried is retired; the
2026-09-01 errata round pruned the one item minted under it.)

A deferral is always defer-until-later-review — a conscious, temporary choice
to hold a recommendation on trust, never a quiet drop. When the author accepts
one:

- **Record it.** Land a dated clarification on the affected node naming exactly
  what is held on trust, stamped `(decision: deferred — ...)` (the ordinary
  step-2.8 clarification mechanics). The deferred stamp **is** the enrollment:
  the review queue is derived from deferred/delegated stamps per the curriculum
  amendment, so no review-item node, reading-chunk node, or side list is
  created. When a grounding text exists, name it inside the stamped
  clarification so the derived queue can route the sitting to it.
- **Extend delegated scope when it defers to Claude's articulation.** When the
  held content is Claude-drafted reasoning, the same round extends
  `delegation-philosophical-articulation`'s delegated scope — reconcile that
  node in this round's commit.

### Dialectic steps

1. **Intent.** Elicit the one-line `statement` a plain conversational turn
   first; once you have enough to draft one, confirm it via
   `AskUserQuestion` with your best draft as the recommended option.
2. **Placement.** For a new strategy: propose the `serves` virtue id(s) and,
   if it is naturally a sub-strategy of an existing one, a `parent`
   strategy id (same-kind only — `validateGraph` rule 6). For an edit:
   confirm placement is still correct given the revision. Recommend your
   best guess first.
3. **Doctrinal-consistency gate.** Test the drafted strategy for internal
   consistency with the recorded model of the good before it enters that
   model — the function doctrine (`strategy-explicit-intent`, 2026-07-08
   clarifications) requires every strategy be tested against the model it
   joins, and `validateGraph` rule 8 (checked at step 2.2) covers only
   referential integrity, not consistency of intent. Read the relevant
   doctrine **at `origin/main`, never the working tree** — a stale checkout
   presents already-amended doctrine as current, the live failure mode the
   2026-07-08 round caught (e.g. `git show
   origin/main:intentions/<id>.md`). Read: the `serves` virtues' rationales
   and `tension_with` pairs; overlapping strategies' `clarifications` and
   `attributes.conditions`; and the tradition records those virtues cite.
   Surface every contradiction between the drafted `statement`/`rationale`
   and that doctrine as an interview question, following the "Question
   mechanics" subsection above (recommendation with authority-in-option +
   boldness, context delivered inside the `AskUserQuestion` tool).
   Each resolution lands as a dated `clarifications` entry in the step-2.8
   provenance convention. On the **edit** path (step 1.2 classified the
   target as an edit of an existing strategy), run the gate against the
   revised `statement`/`rationale` as well.
4. **Benefit.** Talk through why this strategy is worth running now versus
   later or not at all — this is conversational, not a gated question,
   but its conclusion should be visible in the eventual `rationale`.
5. **Steelman-alternative challenge.** Test the strategy against the
   strongest rival conception of its intent before recording it — the
   alternatives test otherwise lives only in
   `strategy-philosophical-grounding`'s periodic rounds, so a strategy
   recorded between rounds would enter untested. Articulate the strongest
   rival framing of the strategy's intent — a different end it could be
   serving, a different shape the same end could take — sourced from the
   tradition records the `serves` virtues cite (their `adopted` /
   `diverged` / `chosen_over` entries) or a named candidate tradition you
   can defend. Put that rival framing to the author via `AskUserQuestion`,
   following the "Question mechanics" subsection above (recommendation with
   authority-in-option + boldness, context delivered inside the tool). Record
   the resolution as a dated `clarifications` entry in the adopt/diverge
   shape — either the strategy adopts the rival framing, or it diverges
   from it with the reason stated — carrying a dated provenance clause per
   the step-2.8 convention.
6. **Signal.** Draft a `success_signal` — `{observable, sensor, threshold,
   is_proxy}` — and confirm it names something a sensor can actually read.
   A strategy with no plausible sensor is a sign the intent is still too
   abstract; push back before recording one.
7. **Conditions.** Ask the author to state the circumstances this strategy
   is contingent on (`attributes.conditions`) — author availability,
   architectural assumptions, another strategy holding, etc.
8. **Edge cases and consequences.** For each of the above, surface at
   least one edge case or downstream consequence and resolve it with the
   author. Every resolution becomes a dated `clarifications` entry —
   `{question, answer}` where `answer` carries a dated provenance clause:
   an event verb (Recorded / Amended / Reviewed / clarified / adopted,
   etc.) plus an ISO date, placed wherever it reads best in the sentence —
   a front-loaded parenthetical is preferred, e.g.
   `"(Recorded 2026-07-05 interview.) ..."`, but any placement is accepted.
   The newest ISO date anywhere in the answer is its effective date — the
   `readingDate()` contract (`packages/intentionsutil/src/router.ts`)
   extracts it verb-agnostically, and `coverage.ts`'s `lastReviewedOf`
   depends on it. An amendment adds a new dated clause rather than rewriting
   the old one, so the history of resolutions stays legible. Get the date
   via `date -u +%Y-%m-%d`, never hand-guessed. `validateGraph` rule 17
   mechanically enforces the date-presence half of this convention; the
   event verb is documented style, not linted.
9. **Design-canvas support (UI-design requirements only).** When a
   decision is about UI shape and text underspecifies it, supplement
   `AskUserQuestion` with visual aids: build mockup/variant artifacts on
   `@commons-systems/ds` and sync them to the claude.ai/design canvas via
   `DesignSync`, so the author disambiguates by pointing at a variant.
   For a chart, dashboard, or data-viz requirement, first load the
   `/dataviz` built-in skill — its procedure governs the recorded design:
   form chosen by the data's job (including its "is it even a chart" test),
   color assigned by role (categorical/sequential/diverging/status) never by
   rank, the categorical palette run through `/dataviz`'s validator script
   (never eyeballed), mark specs and spacers, a default hover layer, and an
   accessibility pass (legend for ≥2 series, table view, a selected — not
   auto-flipped — dark mode). `/dataviz` and the design canvas compose, not
   compete: `/dataviz` supplies the design method and its computable checks;
   the canvas still supplies the mockup/variant artifacts for author
   disambiguation, now built to follow `/dataviz`.
   Canvas artifacts are interview aids, not deliverables — the resolution
   they produce is recorded as an ordinary dated clarification like any
   other. Caveat: a freshly synced component is absent from the canvas
   until the project is opened/refreshed — warn the author if this is
   their first look at a same-session sync.
10. **Persistent-layer ownership gate.** Whenever this interview is about to
    record standing structure — a node that owns a `success_signal` that is
    read on an ongoing basis, a node carrying a standing `attention`
    boost/override,
    or any node that other machinery permanently references — the recorded
    owner must be `kind: strategy` (or `virtue`), never a tactic. Tactics are
    transient by definition: they complete and leave the selectable graph.
    If a tactic is proposed as a standing owner, surface it as an interview
    question, never record-and-fix-later: recommend the owning strategy, and
    propose creating one if none exists (`strategy-main-health` is the worked
    precedent, created 2026-07-13 for exactly this reason). Resolution lands
    as a dated `clarifications` entry per the step-2.8 provenance convention.
11. **Layer-placement gate.** Before recording any interview outcome, classify
    its content against kind-tactic's authoring test (`intentions/kind-tactic.md`,
    2026-07-21 clarification, "Where does an interview outcome land — strategy
    layer or tactic layer?"): a standing requirement — one that must still hold
    after every tactic currently serving the strategy completes and is pruned —
    lands as a strategy or kind clarification; a completable change lands as a
    draft tactic (Step 4); a split outcome lands as both, the invariant as a
    clarification and its implementing fix as a tactic. Open-children
    orthogonality and freeze/re-stamp cost are **never** placement inputs — they
    govern only the materiality classification's blast radius (see
    "Documentation completeness over commit size" and "Materiality-scoped
    freeze", below), a separate, later decision. Cite kind-tactic's test; do
    not restate its rationale here.

**The `/file-issue` 8-category evaluation, folded into the steps above**
(so nothing from the coverage matrix silently drops):

| Category | Where it lands here |
|---|---|
| Duplicates | Step 1.2 overlap detection |
| Compliance | Step 2.2 — does intent trace to a real virtue |
| Clarity | Step 2.1 — a muddled composite statement is a step-1.1 multi-topic split, not a vague one-liner accepted as-is |
| Correctness | Step 2.6 — does the signal actually measure the stated intent |
| Relevance | Retired with the improvement pass — no longer covered by this skill |
| Decomposition | Deliberately **not** this skill's job — a strategy is never broken into PR leaves here; that is `/align-tactics` |
| Recommendations | The interview's own resolutions, recorded live as clarifications — there is no separate recommendations pass |
| Open-issue alignment | Retired with the improvement pass — the corpus-wide condition/signal staleness sweep is no longer covered by this skill |

## Step 3 — Delegation advice

Run
`node --import tsx/esm packages/intentionsutil/scripts/align-strategy-census.ts intentions`
and read its "Delegations" section — it already dumps id, statement,
`attributes.delegated`, `attributes.divergence.level`, and
`attributes.irreversibility.{gated,recovery_cost}` for every delegation
node — for entries whose `statement` or `attributes.delegated` overlaps the
strategy's domain. For each match:

1. Propose (`AskUserQuestion`) whether the strategy should carry a
   `recovers: [<delegation-id>]` edge (`recovers` is valid only on
   `kind: strategy`, and every entry must resolve to `kind: delegation` —
   `validateGraph` rule 9). A strategy that unwinds or reduces reliance on
   a delegation should record the edge even if unwinding is only partial.
2. Read the delegation's `attributes.divergence.level` and
   `attributes.irreversibility.{gated,recovery_cost}`. Surface capture risk
   explicitly in the proposal: high divergence or a gated, costly
   irreversibility means the author should weigh this before committing —
   state it in the `AskUserQuestion` description, not just in your own
   head.

## Step 4 — Retain draft tactics

Tactical or implementation content that surfaces naturally during the
interview is **retained, never refined and never dropped** — this skill
has no plan schema or quality bar to hold it to; that is `/align-tactics`'s
job.

**Artifact-owner placement** (strategy clarification 27): a draft's `serves`
names the strategy that owns the artifact the byproduct touches — never the
nearest-fit strategy just because it is the one under interview. A
genuinely cross-cutting byproduct uses an honest multi-entry `serves`
naming every owning strategy. When no strategy owns the artifact, do not
force-fit one: surface the gap to the author (a candidate for a brand-new
strategy, per Step 1's "New vs. edit" logic) rather than parking the
draft under a strategy that does not actually own it.

For each such byproduct, write a draft tactic node:

```bash
cat > "$TMPDIR/tactic-draft.json" <<'JSON'
{"id":"tactic-<slug>","kind":"tactic","statement":"<one-line>","owner":"ai","status":"raw","parent":null,"serves":["<strategy-id>"],"rationale":"<why this surfaced, from the interview>"}
JSON
node --import tsx/esm packages/intentionsutil/scripts/write-node.ts --dir intentions \
  --file "$TMPDIR/tactic-draft.json"
```

No `phase` field (equivalently `phase: draft`) marks it as **undecomposed
work whose next step is an `/align-tactics` session** — not executable phase
work, but not inert either. The router **does** select a draft tactic,
emitting it at the `align-tactics` directive rung
(`packages/intentionsutil/src/router.ts`'s frozen-tactic candidate loop),
subject to three gates: `office_hours` must be null (so a born-parked review
item from Step 2's deferral mechanics is skipped), its blockers must all be
`done`, and it must not be named as another tactic's `parent` (a permanent
subtree container is skipped rather than surfaced as an undecomposed draft).
A draft does **not** count as a child for the strategy's `/align-tactics`
eligibility — a strategy with only draft children still emits its own
fresh-round candidate, and the two compete by rank. If the byproduct is more than a one-line statement, follow
with a direct `Edit` of the node body (everything after the closing `---`
fence) to carry the fuller context — `writeNode` preserves an existing
tactic body verbatim across later frontmatter-only rewrites, so this
survives untouched until `/align-tactics` consumes it.

Never write this content to an ad-hoc design doc outside `intentions/` —
the graph is the only home for tactical context, however provisional.

**Graph as sole tracker** (strategy clarification 28): the `intentions/`
graph is the source-of-truth issue tracker, bug tracker included — every
defect worth fixing is a tactic (or a unit of one), never a side channel
(an ad-hoc doc, a code comment thread, a chat aside). A byproduct that is a
bug report is retained here exactly like any other tactical byproduct. Code
`TODO`s stay pointer-only — `TODO(tactic-<id>)` — never carrying the
substance itself; a substantive TODO with no backing node is a
review-phase finding, not something this skill should ever produce.

## Step 5 — Record

Before constructing the JSON to land, re-confirm that no node about to be
recorded this round — as a `success_signal` owner or a standing `attention`
boost/override carrier — is `kind: tactic`. This is the same gate as dialectic
step 10, restated here as the final pre-write check so a resolution made earlier
in a long interview is not silently dropped by the time the JSON is constructed.

Write the full node through `write-node.ts` — never hand-edit the YAML
frontmatter:

- **New strategy:** construct the full JSON from the interview (required
  core plus `serves`, `rationale`, `clarifications`, `success_signal`,
  `attributes.conditions`, `recovers` from step 3) and pipe or `--file` it
  into `write-node.ts`.
- **Edit:** read the existing node's frontmatter in full by **dumping it
  through `dump-node.ts`**, which captures both the JSON to reconcile and a
  base manifest recording the blob you read — the compare-and-swap token
  step 5's `graph-commit --base` checks (never a bare `readNode` one-liner,
  which records no base):

  ```bash
  BASE=$(node --import tsx/esm packages/intentionsutil/scripts/dump-node.ts --dir intentions \
    --out-dir "$TMPDIR/dump" <strategy-id>)
  # reconcile from "$TMPDIR/dump/<strategy-id>.json"; pass "$BASE" to graph-commit below
  ```

  Only the frontmatter is authoritative. **Amendment completeness**
  (strategy clarification 38,
  widening clarification 32's tactic-amendment bar to any node amendment in
  any align skill): an edit round is a **whole-node reconciliation**, never
  a patch applied in isolation. Reconcile the edited strategy's `statement`,
  `rationale`, `attributes.conditions`, `success_signal`, and every
  `clarifications` entry the edit touches or contradicts against the
  interview's full outcome before constructing the JSON to land — landing
  one new clarification while a sibling field (an older clarification, a
  stale condition, an unrevised rationale sentence) still contradicts it is
  an incomplete amendment, the same defect class as an incomplete record
  (condition 7). The author's live presence in this interview reduces but
  does not remove the risk: the record, not the session, is the carrier.
  Construct the fully-reconciled JSON (not a `jq` delta patch) and pass it
  to `write-node.ts`. Never transcribe frontmatter by hand.

```bash
node --import tsx/esm packages/intentionsutil/scripts/write-node.ts --dir intentions \
  --file "$TMPDIR/strategy.json"
```

Then land it — `graph-commit` is the **only** write path, never a
hand-rolled `git commit`/`git push`. For an **edit**, pass the base
manifest from `dump-node.ts` via `--base` so a stale read is refused
mechanically (before any commit) rather than left to rebase luck:

```bash
packages/intentionsutil/scripts/graph-commit --base "$BASE" \
  <strategy-id> [<draft-tactic-id> ...]
```

A brand-new strategy has no origin/main blob to compare, so it takes no
`--base` entry — omit the flag (or the id) for nodes this round creates;
`--base` covers only the pre-existing nodes you dumped.

Bundle any draft tactic nodes authored in the same pass into the same
`graph-commit` call as their serving strategy — one call, one commit,
covering everything this interview produced. A multi-topic round
(step 1.1) instead runs step 5 **once per independent strategy**, each its
own `graph-commit` call with its own draft-tactic bundle: the "single-node
commit" discipline (clarification 2) is about one node id per file inside
a commit that stays small and reviewable, not a hard cap of one file per
push.

If `graph-commit` exits 1 having printed a parking message, the node
landed with `office_hours` set instead of the intended content (a
concurrent-edit conflict) — tell the author and stop; do not retry
automatically.

**Scope-inert re-stamp — protect a tactic's own scope custody.** If this
round's edit touched the **body** (not just frontmatter) of an in-flight
tactic — a node with a phase set, i.e. an open child (not `draft`, not
`done`), the same population the Materiality-scoped-freeze section below
discusses — then that body edit trips the tactic's own chain-of-custody
scope gate: the worktree-local `.claude/worktrees/<id>.scope-fingerprint`
stamp no longer matches the tactic's current body fingerprint, and the gate
demotes the tactic back to `implement`, discarding its qa/review custody.
That is correct for a real plan-substance change, but this interview
sometimes must edit an open tactic's body for a **scope-inert** reason — a
reconciliation note, a drift-review correction, a provenance annotation, or
any other body edit clarification 38's amendment-completeness bar produces —
where the plan substance is unchanged. For those, the demotion is spurious.

Classify this round's own edit, per tactic, as **scope-inert** (plan
substance unchanged — e.g. a provenance/reconciliation annotation) versus
**material or unsure**. The rule is fail-closed: **only** a confident
scope-inert verdict re-stamps; on **any** doubt — including a merely
plausible substance change — do nothing further here. Leave the stamp
untouched and let custody demote the tactic exactly as it does today. That
demotion-on-doubt is the existing correct behavior, not a failure mode to
work around.

For each tactic whose edit is confidently scope-inert, **after** the body
edit has landed via `graph-commit` in this **same** round (so it is on
origin/main), run:

```bash
node --import tsx/esm packages/intentionsutil/scripts/restamp-scope-fingerprint.ts <tactic-id>
```

It must run post-`graph-commit`: the script reads the tactic's current
on-disk body and the current `origin/main` sha to compute the stamp, so a
pre-landing run would stamp stale content. It re-writes **only** the
worktree-local `.scope-fingerprint` file — it is never a node write and
never a `graph-commit` of its own.

Record the classification in this round's own record/summary — the
scope-inert verdict and the tactic ids re-stamped — as the audit trail the
doctrine requires.

This is a **separate** stamp from the Materiality-scoped-freeze section that
follows, not an extension of it. That section's `execution.strategy_fingerprint`
freeze protects open children broadly against **strategy**-substance drift;
this step's worktree-local `.scope-fingerprint` re-stamp protects a single
**tactic**'s own scope-custody gate from being tripped by a scope-inert edit
to that tactic's own body. Two unrelated stamps, two unrelated mechanisms —
do not conflate them.

**Documentation completeness over commit size.** When an interview outcome is
materially a property of the strategy under edit (an invariant of its
contract, a resolved edge case, a doctrine correction), record it as a
strategy clarification on that strategy — never relocate it to a draft tactic,
or omit it, to keep the commit small or to avoid a re-stamp. Commit size is
never a reason to put documentation in the wrong place; the materiality-scoped
freeze below is what keeps a warranted clarification's *blast radius* small —
it is not a reason to avoid recording the clarification itself. Whether the
outcome belongs in the persistent layer at all is decided upstream, by
dialectic step 11 (Layer-placement gate); this section governs only the blast
radius of a placement already made there.

**Measure freeze/re-stamp cost via the authoritative predicate, never a
grep.** If a recording or materiality decision turns on how many open children
a clarification would freeze, compute the actual set with `readNode`
(`packages/intentionsutil/src/store.ts`, re-exported via the package index
barrel) + `isFingerprintStale`
(`packages/intentionsutil/src/transitions.ts`) — or
`strategyFingerprint` (`packages/intentionsutil/src/router.ts`) plus the same
per-child stamp read the router's selector uses — never a text `grep` over
`strategy_fingerprint`. A `grep -c` (or similar) over that field counts the
key line itself, so a null-valued stamp (`strategy_fingerprint: null` — not
stale, per `isFingerprintStale`) is indistinguishable from a real one in the
grep count and inflates the estimate. A cost estimate that drives a recording
or materiality decision must come from the same predicate the router uses, not
a text search.

**Materiality-scoped freeze — classify each open child.** If this is an edit
to a strategy that has open (non-draft, non-`done`) child tactics with an
existing stamped `execution.strategy_fingerprint` entry for this strategy, the
session must classify **each** such stamped open child against the actual edit
delta — **before** running `graph-commit` — into exactly one of three buckets.
The classification is materiality-scoped, not indiscriminate: an edit no longer
queues a blanket freeze of the whole open subtree; only the children the edit
actually affects freeze.

There is **no rank gate** — rank is not a proxy for materiality. A low-rank
child can still be materially affected, and a high-rank child can still be
orthogonal; classify every stamped open child on the substance of the delta,
never on its rank.

- **Orthogonal** — the edit does not affect this child's plan at all.
  Re-stamp its `execution.strategy_fingerprint` entry for this strategy to
  `{hash: strategyFingerprint(strategy), sha: <origin/main sha at edit time>}`
  in the **same** `graph-commit` as this strategy edit, so no freeze fires for
  this child.
- **Materially affected** — the edit changes something this child's plan
  depends on. Leave its stamp untouched/stale: the freeze fires and it
  re-evaluates later at its own rank via the existing re-evaluation mechanism
  (unchanged — `tactic-graph-router-selector` /
  `tactic-graph-router-transitions` when live; the inline `/align-tactics` pass
  in this same session in the bootstrap interim, as every round recorded on
  `strategy-graph-native-dispatch` so far has done by hand).
- **Must-land-first migration** — this child must not proceed until some
  carrier work lands. In addition to leaving its stamp stale (as materially
  affected), add `blocked_by += [<carrier-id>]` so the router cannot select it
  until the carrier lands.

`hash` is always `strategyFingerprint(strategy)` from
`packages/intentionsutil/src/router.ts` — always that helper, never a
hand-computed hash. In the bootstrap-interim hand-stamp path (no live router
yet), get `sha` with `git rev-parse origin/main`. The live-router path instead
passes it through `apply-node-transition.ts --strategy-sha <sha>` rather than
shelling git itself.

Dropping the legacy bare-string form entirely, and making `validate-graph`
**reject** bare strings, is sequenced future work (migration step 4), **not**
this change: bare strings remain valid deprecated-legacy, and only the
classification-touched (re-stamped) keys convert to the `{hash, sha}` object
form — opportunistic conversion, not a bulk migration of the extant legacy
bare-hash stamps.

**Curriculum enrollment (record time).** Maintaining the ever-expanding
review curriculum is one of /align's roles
(`strategy-graph-review-curriculum` clarification 5): every recorded node
enrolls when it lands, and enrollment happens here, not in a later pass.
Which mode a node enrolls in is derivable from its own record —
held-on-trust/delegated content is mode A, author-owned content is mode B.

- **Mode A — content held on trust.** Enrollment is the decision stamp
  itself: a deferral or delegated recording lands as a dated clarification
  stamped `(decision: deferred — ...)` / `(decision: delegated — ...)` on the
  node, in the same `graph-commit` as the record it covers, and the review
  queue is derived from those stamps (`strategy-graph-review-curriculum`,
  AMENDED 2026-08-30: record-time enrollment mints nothing). No born-parked
  review item, reading-chunk node, or roster entry is created; the stamp
  lives on the enrolled node, so the linkage is intrinsic.
- **Mode B — author-owned content.** Enrollment is implicit: being recorded
  in the graph *is* enrollment, and the curriculum frontier's recursive scope
  expansion is the recurrence mechanism that reaches the node — no action is
  owed at record time. Never create a per-node review schedule, a standing
  review item, or a side list for author-owned doctrine. Review items are
  born-parked nodes derived from node status
  (`strategy-graph-review-curriculum` condition: the curriculum stays
  graph-encoded, never a hand-maintained side list); /align never maintains a
  separate roster.

## Step 6 — Requirements coverage check

Before finishing (requirement-text mode only): walk the author's original
text clause by clause and confirm each maps to a recorded element — a
`clarifications` entry, a `rationale` sentence, a `tooling_goals` entry, an
`attributes.conditions` entry, or a draft-tactic bullet. An unmapped clause
never drops silently: either return to the interview for it, or land it in
a draft tactic body. State in your final summary to the author which
clause mapped where — this is the one behavior a rushed pass is most
likely to skip, and skipping it is exactly the failure mode this step
exists to catch (found live in the 2026-07-03 `strategy-attention-surface`
round: a requirement anchor that survived only in session context until
this check restored it).

This walk is what discharges the record-completeness contract (strategy
clarification 31 / condition 7, see the preamble above): `/align-tactics`
re-evaluates from a fresh session with only the graph, so a clause that
maps to nothing recorded is a gap this skill — not the next session — is
responsible for closing.

## Out of scope

- `/align-tactics` (breaking a recorded strategy into PR-sized tactics —
  `tactic-align-tactics-skill`): a sibling skill, not this one's job.
- Deleting `/file-issue` itself: that is `tactic-legacy-router-removal`,
  gated on the legacy gh queue draining. `/file-issue` carried gh-issue work
  through this skill's rollout; it is now retired ("RETIRED — do not invoke",
  `.claude/skills/file-issue/SKILL.md`) and GitHub Issues are disabled
  repo-wide.

## Verification

Prose only — this is an interactive-dialectic skill with no automated
test surface, so no ```verify block:

- Dry-run on a toy requirement in an interactive session. Confirm:
  - the written node passes `node --import tsx/esm packages/intentionsutil/scripts/validate-graph.ts intentions`;
  - it landed via `graph-commit` (visible on `origin/main`, not just
    locally committed);
  - any draft tactics from step 4 landed in the same commit and read back
    with `phase` absent;
  - no `gh issue`/`gh pr` command ran anywhere in the flow.

- Invoke `/align` with **no prompt** in an interactive session to exercise
  the onboarding branch. Confirm:
  - step 1 orients — the practitioner gets the one-screen description of the
    graph's node kinds before anything else runs;
  - `.claude/skills/align/scripts/validate-deployment.sh` actually runs, and
    reports all three checks (workspace installed, graph clean, router
    heartbeat) each with its own remediation diagnostic — including on the
    failure paths, and with an inactive daemon reported as non-fatal;
  - the walk-to-a-prompt step converges on a crafted prompt and then
    **falls through in-session** into step 1's "With requirement text"
    branch — it must not re-invoke `/align` through the Skill tool.

Files in this skill

  • SKILL.md47.7 KB
  • scripts/validate-deployment.sh4.9 KB

Attribution

Is this your skill, or is something wrong with this listing? Request removal or report an issue. Author removals are honored within 72 hours.

Comments

Loading comments…

Newsletter

Get the weekly list of safe new skills, and the ones we pulled.