Skip to content

Changelog

Hand-maintained, newest first. Versions track solutions/ontological/.claude-plugin/plugin.json.

2026-07-14 — Compiled-binary distribution (D-2APS)

Section titled “2026-07-14 — Compiled-binary distribution (D-2APS)”

The distribution model changed again: instead of shipping a plain-Node build artifact, @sksizer/sdlc now ships as a compiled, self-contained bun binary — one per platform, selected via optionalDependencies behind a plain-Node shim (the esbuild/biome/turbo pattern). A consumer needs neither Bun nor a build step. This supersedes the plain-Node artifact described in the 2026-07-12 entry below.

  • Binary build + npm wrapper. solutions/ontological/scripts/build-binary.ts compiles the CLI (embedding the runtime-asset + harness surface, with the .claude-plugin manifest versions stamped to package.json); build-npm-wrapper.ts assembles the per-platform packages + the main shim package. release.yml cross-compiles, packs, smoke-tests the shipped artifact, and publishes (gated on NPM_TOKEN).
  • Retired the plain-Node path. The plugin build-artifact op (and its vendored-dep bundling), the runtime-agnostic gate, the git-pinned sdlc-dist channel, and the esbuild / tsc-alias / tsconfig.build.json build tax are all removed — the binary bundles the source and its deps via Bun, so shipped code no longer needs to be plain-Node-compatible.

2026-07-12 — Runtime-agnostic distribution migration (M-UWPO / D-0014, superseded above)

Section titled “2026-07-12 — Runtime-agnostic distribution migration (M-UWPO / D-0014, superseded above)”

The deterministic core stopped being a Bun-only, symlink-installed plugin and became a JS-runtime-agnostic artifact you install through the CLI. A consumer with Node and no Bun can now run npx sdlc. This is the landed portion of an active milestone — release CI ([[T-75UD]]) and the pilot-consumer verdict ([[T-521G]]) are still open.

  • Runtime-agnostic shipped code. Bun.* and import.meta.dir/main are gone from every shipped tree; a sdlc gate runtime-agnostic gate keeps Bun-only constructs from creeping back. Plain-Node execution is proven end to end (T-WGV4, #697/#692).
  • @sksizer/sdlc npm artifact. sdlc plugin build-artifact stages a publishable package; an npm-pack install runs npx sdlc on plain Node with Bun absent (T-XTGT, #700).
  • sdlc harness install claude — wire the harness into a consumer project, idempotently: --mode copy | node-modules | link, auto-detecting source → link and installed → copy, with an idempotent settings merge. project doctor gained a same-install check (T-ZF8U, #699).
  • Dev-link mode. sdlc harness install claude --dev (sugar for --mode link) registers the live source checkout, routing link config to .claude/settings.local.json; mode-switches are idempotent and mutually exclusive, and project doctor reports dev/linked (T-ZEPK, #707).
  • sdlc dev runtime selector. The launcher resolves its source as SDLC_HOME env → XDG sdlc/home config → local (config suppressed when CLAUDE_PLUGIN_ROOT is set). sdlc dev use <path> / off / status / link points a PATH-installed sdlc at a live checkout for cross-project work (T-F9TG, #708).
  • Skill corpus normalized onto the ${CLAUDE_PLUGIN_ROOT}cli/sdlc launcher for runtime/entry resolution, with a sdlc gate corpus-invocation gate forbidding raw cli/sdlc.ts invocations in skills (T-ITMN, #698).
  • No code-root path assumptions. Self-location walks up to the project root for sdlc.yaml; the three self-location hops are annotated and pinned (T-T0O9, #701).
  • sdlc site build — one op runs generate → package-manager detect → astro build and reports the dist path, so a consumer builds the docs site without Bun; build:doc-site routes through it. Also fixed a latent --no-* CLI flag no-op (T-0PIB, #705).

2026-06-07 — Deterministic site assembly (M-0005 / D-0010)

Section titled “2026-06-07 — Deterministic site assembly (M-0005 / D-0010)”

The docs site became a pure build artifact: one sdlc docs generate site pass owns every file under sites/df-docs/src/content/docs/ and the generated sidebar.

  • The whole content root is generated. The reference pages, the planning-corpus rosters + per-entity child pages, the glossary/references appendix, the data-model page, and the roadmap are all generated. A file the pass did not place is deleted if it carries the AUTO-GENERATED banner (stale page) or a hard error if unbannered (foreign hand-written content).
  • The supplemental model. Hand-written pages now live OUTSIDE the content root under sites/df-docs/supplemental/ and are declared in a manifest, sites/df-docs/site.yaml (a landing: slot + an ordered nav: list). The pass mirrors each into the content root with an injected banner.
  • The sidebar is generated from site.yaml’s slot order (sites/df-docs/src/generated/sidebar.mjs); astro.config.mjs is a thin shell.
  • Every planning entity type projects onto the site — a generic roster + child-page projection, with per-type overrides; a new entity type ships on the site with zero wiring. The roadmap is generated from milestone entities.
  • Pages render through Eta templates, retiring site.ts’s string concatenation.
  • sdlc docs generate site --check — a drift gate that regenerates without writing and exits non-zero (naming the drifted pages) when the committed site is stale. Wired into quality_checks, so a PR that changes an entity without regenerating the site fails CI. Coupling between regen and per-task PRs dissolves: a per-task PR’s regen diff is exactly its own change.

2026-06-06 — Reference entities and the docs Appendix (D-0009)

Section titled “2026-06-06 — Reference entities and the docs Appendix (D-0009)”
  • reference entity type (RF prefix, docs/planning/references/) — external documentation, research, and artifacts become first-class entities with an optional url in frontmatter and a body that can summarize, copy, or transclude the source material. sdlc reference create <slug> --title <name> [--url <url>].
  • docs/references.md — fourth generated artifact (sdlc docs generate references): Reference | Summary | Link | Cited by, host-labelled links, same bucketing as the glossary.
  • Appendixdocs/index.md’s Appendix now carries the generated Glossary and References tables, and the site sidebar gains a trailing Appendix group holding Glossary and References.
  • Per-entity pages — every term and reference gets a full generated page (/glossary/<slug>/, /references/<slug>/); roster entries link through to them, the Appendix sidebar lists per-entity children that jump to each entry’s row anchor on the roster page, and the rosters’ On this page nav lists every entry (route-middleware TOC injection).

2026-06-06 — Term entities, site glossary, and docs generate surface (D-B4CA)

Section titled “2026-06-06 — Term entities, site glossary, and docs generate surface (D-B4CA)”
  • term entity type (TM prefix, docs/planning/terms/) — each glossary entry is now a first-class entity with schema, lifecycle, and audit coverage. 13 initial instances (TM-0001TM-0013) minted from the previous hand-written glossary.
  • docs/glossary.md is now a build artifact, generated from term entities by sdlc docs generate glossary. The file moves out of docs/planning/ to sit beside docs/index.md.
  • sdlc docs generate [<artifact>…] supersedes sdlc index generate: one op, one deterministic pass over the full generated-docs family — index, glossary, and site. Positional artifact selection for scoped runs.
  • Site generation ported onto the substratesites/df-docs/scripts/regen.mjs is replaced by solutions/ontological/lib/services/docs/site.ts (TypeScript, tested, registered as the site artifact). Invoked via sdlc docs generate site. The .mjs script is deleted.
  • Glossary — new site page generated from term entities; definitions inlined from each entity’s ^summary block (no Obsidian transclusions on the site).

v0.2.0 — 2026-06-06 — Op-substrate full sweep (M-0003)

Section titled “v0.2.0 — 2026-06-06 — Op-substrate full sweep (M-0003)”

The deterministic core became a single op registry. Every capability that lived in plugin/scripts/ or plugin/validators/ moved into solutions/ontological/lib/ as a registry op or service, and the sdlc CLI is now the sole entry — a thin door generated from the registry, with no contract restated anywhere (D-0007-deterministic-op-substrate, D-H7FS-op-substrate-surface).

A command is a 2–3 segment kebab path (OpDescriptor.path: string[], hard cap 3), not a flat {noun, verb}. The surface lands at 11 visible nouns and 4 hidden:

Nouns
Visibletask · backlog · milestone · standard · entities · commit · report · index · quality · project · dashboard
Hidden (--advanced)plugin · pr · gate · lease

Depth-3 nesting appears only where a group genuinely nests with ≥2 members: quality baseline {capture,diff,prune}, project scan {todos,candidates}, and the two-axis lease (lease task {claim, acquire, reacquire, transition, archive}, lease op claim). Run sdlc --help --advanced for the full tree.

  • path[] registrydefineOp keys every op by path.join(" "); the legacy {noun, verb} shape is accepted and normalized, so existing descriptors and positional callers compiled unedited.
  • defineService — a registry sibling for long-running capabilities (the dashboard, the lease heartbeat loop): a lifecycle (start/stop?/list?) instead of request/response, dispatched outside invokeOp’s output-parse pipeline.
  • --output text|json|jsonl — one projection parameter over the op’s canonical Zod output (--json kept as an alias). Defaults are op-declared: a cli.render(output, io) hook makes text the default (line-oriented parity), otherwise json.
  • Render hooks — the text projection; a hook’s numeric return shapes the CLI exit code so a “FAIL” shape exits non-zero without throwing.
  • SERVICE_ERROR — a new exit tier in the OpError taxonomy for lifecycle failures (already-running, stale pidfile, port-in-use).
  • plugin/scripts/ and plugin/validators/ are deleted, along with plugin/cli/lease_cli — the entire pre-migration deterministic surface (chore!: delete plugin/scripts + plugin/validators + cli/lease_cli, T-YBKU). git log --follow resolves history for every relocated file.
  • The sdlc CLI is the sole entry. Skills no longer shell out to ${CLAUDE_PLUGIN_ROOT}scripts/X.ts; every caller flips to sdlc <path…>. LEGACY_NOUNS has shrunk to a single forwarder, backlog.
  • Guards added so the old paths can’t come back: a no-legacy-script-paths check, project-check-op-modules (a malformed op module fails loudly rather than silently dropping a command), and the gate skill-prose / gate worktree-scope lefthook gates now invoke the CLI directly.

The Ops reference is regenerated from the registry — one page per registered path. The hand-written pages (this changelog, the architecture set, the roadmap, the landing page) were rewritten against the migrated substrate. See the Architecture overview.

Historical snapshot of the v0.1.1 release. Several paths below were later relocated or deleted in the M-0003 sweep above — this section records the state as it shipped, not the current layout.

The repo restructure moved every distributable plugin artifact under plugin/. Peer projects (this docs site, future front ends) sit as siblings. ~/.claude/plugins/sdlc is a symlink to plugin/ so edits land in version control automatically.

Entity contracts moved from a flat schemas/ directory into a per-entity-type layout: each type came to own its schema, its new-instance template, and its reference docs in one place. The frontmatter validator was updated to resolve the right schema for an instance automatically — no per-skill schema plumbing.

A one-tick reconcile-and-dispatch loop. Each tick: sync main, classify every open PR via /sdlc:pr-check, act on the verdicts (close-out MERGED, attempt resolution on NEEDS-RESPONSE / CONFLICTS / CI-FAILED), then dispatch up to two concurrent /sdlc:task-work runs against tasks in status: open/ready. Appends one line per tick to .sdlc/orchestrator-log.md (the digest moved here from .claude/ in the 2026-05 runtime-state migration). Wrap with /loop /sdlc:orchestrate for hands-off operation.

backlog joined task and milestone as a schematized entity, with /sdlc:backlog-triage walking each item to decide promote-to-task, promote-to-milestone, defer, or skip. The triage skill commits each decision atomically.

A container entity above milestones was added, with immutable ids on the same pattern as milestones so the filename survives renaming. (The entity set was reworked in later releases — see Data model for the current nine types.)

Each task type defines an implementation-ready.md contract — what a task spec needs before it’s pickable. /sdlc:task-ensure-ready checks the contract and stamps readiness_verified_at: on pass; /sdlc:task-define walks the user through filling gaps when it fails.

/sdlc:entities-audit reports schema-version drift, frontmatter validation errors, and prose-section drift across every entity instance — read-only. /sdlc:entities-migrate applies the mechanical, auto-fixable subset (stamping schema_version: on entities that pre-dated SDLC management).

/sdlc:task-work now requires a post-mortem section appended to the task file before the PR opens. The friction list is converted into follow-up task files automatically via a sub-agent (procedure co-located with the task entity). This is the mechanism that keeps “the LLM needed a human here” loops feeding back into the backlog.

The site you’re reading. Astro Starlight scaffold under sites/df-docs/, hand-written architecture / roadmap / changelog content, and the auto-generated Reference section. The reference pages are sourced from the plugin’s skills, entity schemas, and — since the M-0003 sweep — the op registry, by sites/df-docs/scripts/regen.mjs. The project-local /dev-update-docs skill (under .claude/skills/, not part of the distributed plugin) runs the regen, semantically verifies the hand-written pages against the live source, and reports drift.

Pre-v0.1.1 history isn’t reconstructed here. The docs/planning/tasks/ directory in the repo is the durable record — each closed task carries a completion_note: pointing at its merged PR.