architecture-lifecycle
The lifecycle of an architecture — where it stands, whether it can be released, what changed since the last release, and the release itself. Invoke first, without planning, for any request to release,
SKILL.mdskills/architecture-lifecycle/SKILL.md
GitHubArchitecture Lifecycle
intake ─► create ─► v1.0.0 Draft ─► release ─► Released vN ─► edits / ADRs / TDRs ─► release ─► vN+1 … ─► deprecate
One script runs it: scripts/lifecycle.js. The state is derived, never stored — the version in ARCHITECTURE.md
is the last released one, its baseline is the annotated tag architecture-v{version}, and the change list is the
facts ledger of the tag's tree against the working tree. Edits write no marker.
| State | Meaning | Next |
|---|---|---|
draft |
no release yet | first release keeps v1.0.0 |
changed |
the docs differ from the tag, or [Unreleased] has lines |
release |
released |
the docs match the tag | refresh stale downstream artifacts |
untagged |
Released in the document, tag missing — a merged release PR, or a lost tag |
tag |
deprecated |
ARCHITECTURE_STATUS: Deprecated |
— |
no-git |
not a git repository | nothing can be released |
Resolve plugin_dir
plugin_dir=$(bun ~/.claude/plugins/marketplaces/shadowx4fox-solution-architect-marketplace/scripts/plugin-root.ts) —
show its stderr warning when a newer version is on the machine. L below is
bun [plugin_dir]/skills/architecture-lifecycle/scripts/lifecycle.js.
Status — "architecture status", "what is stale"
L status <project_root>. Quote the receipt: state, version, tag, the change list with its recommended bump, the
downstream artifacts (PO Spec, handoff kit, traceability, analysis reports, command center, Word export) each with the
version it was built from and the prompt that refreshes it. Compliance contracts are never read — the receipt reminds
to re-run them after a release.
Delivered in pieces — "release increment 2", "what does increment 2 need"
One target design; docs/01 § Delivery Increments (<!-- LABEL: Delivery Increments -->, Increment | Use Cases | Target) assigns its use cases to increments. bun [plugin_dir]/scripts/shared/increments.js <project_root> [--increment <id>] derives each slice — flows, phases, containers and integrations, cumulative, with what is new —
and names the gaps (a use case no flow serves, a flow without phases). Status lists the increments with the release
that carried each. Never assign a container to an increment by hand: move a use case.
A temporary element (one a later increment replaces) carries its window and TDR — **Delivery Increments:** 1–2 · TDR-NNN in a descriptor, the Increments column in docs/05. Releasing the increment after its window blocks
(retire-pending) until it is retired: strike the docs/05 row, remove the container (architecture-component-guardian),
resolve the TDR (technical-debt-records). Guide: ARCHITECTURE_DOCUMENTATION_GUIDE.md § Delivery Increments.
Check — "is my architecture ready"
L check <project_root> [--no-render] runs every gate the architecture already has, once: principles (Layer 1), the
Layer 2 review stamp, prose at release scope, explorer headers, components, derived sequences, flows, Mermaid,
connection labels, integrations, shape budgets, TDRs, ADR index. Exit 1 names the blocking gates, each with its fix. A
gate that stops on a judge worksheet (judge worksheet pending) — dispatch worksheet-judge, one per worksheet, then
re-run. In CI, where no one answers a worksheet, --undecided warn turns a finding that stands only because the judge
has not answered it (a principle finding not re-read, a phase-absent whose every name is undecided) into a warning; a
finding code decides still blocks. Never in a session: answer the worksheet.
The Layer 2 stamp: docs/02 ends with <!-- PRINCIPLE_REVIEW: PASS|WARNING <date> sha256:<hash> -->, written by
principle-check.js --stamp-review after the Section 3 Enforcement Gate (architecture-docs EDIT_WORKFLOW.md). Any
edit of the principles voids it; a missing or stale stamp blocks the release — run the gate, never hand-write the stamp.
Release — "release my architecture", /release-architecture
L plan <project_root> [--increment <id>] [--resolves ESC-NNN[,…]]— refuses onno-git,untagged,deprecated, or nothing changed. Otherwise: the gates, the change list (each line with its bump), the recommended bump, and.cache/sa-skills/lifecycle/entry.md— the changelog entry: the[Unreleased]lines written by hand first, then the change list by code (a first release keeps its Draft entry). With--increment(asked when the project declares increments and the user did not name one): theincrementgate, and the entry opens on the delivery scope line, which the tag carries too. Escalations (escalations/, RUN teams): the entry lists those closed since the tag — closed now and open in the tag's tree. One this release answers is named with--resolves ESC-NNN[,…](ask when open escalations are reported and the change answers them): the entry says "resolved by this release" andapplycloses it by the new tag in the release commit; in PR mode, putCloses #Nfor each issue the receipt names in the PR body. The other gates block on what the increment ships: a prose, header, component, flow, integration or budget finding located in a component, a docs/05 row or a docs/04 flow or phase outside the slice is printed and does not block (N in increment … (M outside it, not blocking), orwarnwhen none is inside). Section files, principles, ADRs and TDRs are the whole design's and block every increment.- A blocking gate → show it with its fix and stop. The user fixes it, or waives it explicitly with a reason
(
--waive <gate>:<reason>, written into the entry). Never waive on your own. - Show the change list and ask one question: the bump — recommended first (
MAJORsomething was removed or the structure changed ·MINORsomething added or a decision moved ·PATCHtext only). A first release asks nothing. - Optional: polish
entry.md— one short description per line where the code wrote only "content", duplicates of a hand-written line removed; one line per change, Keep a Changelog keywords English, prose indoc_language. Edit it at the lines, never rewrite it. L apply <project_root> [--bump major|minor|patch] [--direct] [--waive <gate>:<reason>]— refuses if the architecture changed after the plan. Writes theARCHITECTURE.mdmetadata,**Architecture Version:**in every component file, the changelog entry (rotated past five), closes the--resolvesescalations, refreshes the command center when a scene exists (optional: architecture-command-center), commits onlyARCHITECTURE.md,docs/,adr/,tdr/and those escalation records. PR (default):release/architecture-v{version}branch pushed, compare link printed, no tag — the tag comes after the merge (L tag, step 7).--direct: commit, tag and push on the current branch. Noorigin→ direct, local.- Quote the receipt: version, commit, branch, tag and push state, waivers, the downstream now stale. A failed push is reported with the command to retry — never as success.
- PR mode, once the PR is merged:
L tag <project_root>on the base branch — CI runs it on the push to the base branch (ci/architecture-release.yml). It tags the commit of the base branch's first-parent history where the version became Released (the merge or squash commit), never a laterHEAD, and pushes it; an existing tag is pushed or left alone. Why not tag the release branch: the index publishes on the tag, so it would publish a release nobody merged, and a squash merge would leave the tag off the base branch.
CI — ci/
Two GitHub Actions examples to copy into the architecture's repository: ci/architecture-gates.yml — every pull
request touching the architecture runs check --undecided warn and gets one comment with the gates and the status;
ci/architecture-release.yml — on the merge of a release PR: tag, the index's phase 1 on a runner that reaches the
server, and a dispatch of ci/architecture-handoff.yml, where Claude (claude-code-action, which refuses a push
event) regenerates the handoff kit into a pull request — also runnable by hand for any tag; the PR carries the
version's evidence, the command center regenerated from the documents and its photo-mode picture (snapshot.js)
embedded in the body, best effort. ci/architecture-tier0.yml (RUN teams, 10.7.0): a Tier 0 request an IDE filed
([T0-?] issue, scripts/shared/tier0.js) is written once someone who can triage labels it architecture-tier0 —
the policy re-read by tier0.js prepare, a doc fix by code and the rest by Claude, tier0.js verify and the gates, a
pull request merged at once with SA_TIER0_AUTOMERGE=true; a refusal is commented with its reasons. Each file's header lists
the variables, secrets and repository settings it needs.
Recover — a lost tag
L tag first: it finds the release commit. L recover <project_root> is for a tag lost outside that history — the
tag exists locally but not on origin: push it; on origin only: fetch it; nowhere:
confirm with the user, then tag HEAD with the version's changelog entry and push (refused while the architecture has
uncommitted changes).
Deprecate
L deprecate <project_root> --by "<note>" — ARCHITECTURE_STATUS: Deprecated and a **Deprecation Note**. No tag.
Rules
- Every write is the script's: never edit the version markers, the changelog entry heading or a tag by hand.
- Run git only through the script; it never force-pushes, amends or skips hooks. A failing hook stops the release with the files written and nothing tagged.
- A released version is the tag; a correction is a new PATCH release.