@gotlibr/aisdlc
v2.0.2
Published
Generic workflow builder and offline execution engine
Readme
aisdlc
aisdlc turns declarative Workflow, Step, Template, Skill, Artifact, Validation, and Gate
descriptors into authenticated, resumable Runs. The engine executes the delivery protocol. It
does not choose work, manage people, call a model, or require a server.
Why AISDLC
AI coding agents can generate changes. They do not, by themselves, create a durable protocol for authority, evidence, recovery, or documentation. AISDLC supplies that protocol inside the repository:
| Complete handoffs | Explicit authority | Durable evidence | | --- | --- | --- | | Every active Step carries its exact contract, authenticated Skills, output Templates, submission set, and any explicitly declared context budget. | The human chooses the Subject, Workflow, mode, delivery task, and every declared Gate decision. The engine and agent cannot silently take that authority. | Workflow and Template pins, Artifact digests, Gate records, Run state, Knowledge, and drift scopes remain reviewable through Git. |
Use AISDLC for greenfield definition and delivery, retrospective adoption in an existing codebase, custom repository-specific delivery protocols, and fresh-agent handoffs that must survive process or context loss. Do not use it as a backlog, scheduler, campaign manager, autonomous task selector, AI provider, cross-repository control plane, or background worker.
Capability map
| Area | Supported product surface |
| --- | --- |
| Workflow declaration | Immutable TypeScript builders for Workflows, Steps, Outcomes, Artifacts, references, Validations, Gates, follow-ups, and Hooks. Built descriptors are deeply frozen, JSON-compatible, validated, hashed, and pinned. |
| Catalogs and policy | Four packaged flagship Workflows by default; one Git-root asdlc.workflows.ts may replace or explicitly extend the catalog and select compact or full terminal history. Invalid sources fail closed without fallback. |
| Forward execution | Start, resume, submit, gate, finish, abandon, and archive independent Runs. Active state is append-only and cold-resumable across processes. Parallel occurrences remain explicit. |
| Retrospective execution | Run the same Workflow over an existing system. Compiler-derived skips, observations, attestations, and retained artifacts produce an explicit historical record rather than a reduced second process. |
| Agent orchestration | agent-next returns bounded, digest-authenticated Step batches. agent-submit computes the exact submission envelope and returns next work, a human-gate wait, or the selected terminal close protocol. |
| Native agent integration | Package installation manages one canonical top-level AISDLC Skill for Codex and exposes that same body to Claude Code through a repository-relative symlink. Hand edits and conflicting entries are refused without overwrite. |
| Structural artifacts | Typed Markdown Templates support required and human-owned sections, typed lists, declared references, deterministic serialization, exact section outlines, and selector-based extraction. |
| Validation and Gates | Closed deterministic validations cover content, relations, approvals, paths, and structural capabilities. Gate approval is bound to one submitted digest and becomes stale when those bytes change. |
| Authenticated handoffs | Workflow, Step, and close Skills are verified by SHA-256. Output Templates, active Workflow descriptors, submitted Artifacts, and terminal Knowledge sources have separate authenticated identities. |
| Context control | Fresh agents receive the complete active contract but only bounded Artifact catalogs. outline and extract expose exact CommonMark subtrees without silently loading whole documents. |
| Live evolution | Describe, compile, diff, and validate catalogs. Active Runs never silently rebind; explicit dry-run plans and atomic apply migrate compatible descriptor and Template pins. |
| Lifecycle Hooks | Immutable Hooks run literal, shell-free commands after six committed lifecycle events, in declared order, with stable invocation IDs and exact Run context. |
| Knowledge and drift | Successful terminal work can cross once into Subject-scoped Knowledge. Code pins and exact repository paths make later drift mechanical and explicit. |
| Stable documentation | Flagship flows publish per-Subject FeatureDocs and a repository-global, MADR-formatted ADR catalog. Supersession is reciprocal; accepted and rejected decision bodies remain immutable. |
| State and recovery | Git-visible Run and Knowledge ledgers are repository-local. Journal recovery repairs interrupted writes; compact retention packs terminal evidence, while full retention preserves transition history. |
| Confinement and integrity | Repository paths are confined without following hostile links; mutation failures are atomic; tampered journals, forged metadata, stale digests, and invalid Git tracking rules fail closed. |
| CLI and automation | Closed, machine-readable JSON commands cover discovery, execution, agent batches, migration, Knowledge, drift, integrity checks, Skills, and provider integration. No interactive parser or hidden command aliases. |
| Runtime and packaging | Node.js on macOS or Linux, arm64 or x64. Verified native prebuilds are selected by target and checksum; a C++17 local build is the offline fallback when no match exists. |
Every capability is detailed below with its supported commands, contracts, examples, and failure boundaries.
Install
Requirements
- Node.js 22.10 or newer
- Git repository with
user.nameanduser.emailconfigured - macOS or Linux on arm64 or x64
pnpm10 when building from source- Local Node.js development headers and a C++17 compiler when no matching native prebuild is present
The supported targets are macOS arm64/x64 and Linux arm64/x64. Installation verifies the current target and compiles the native module locally when its prebuild is absent.
Build and install
Install the public package in the target repository:
npm install @gotlibr/aisdlcThe executable is ./node_modules/.bin/aisdlc and the Workflow API is
@gotlibr/aisdlc/workflows.
To build a package from source, use Codex or Claude Code from this checkout:
Build, verify, and install AISDLC into <target-repository>.pnpm install --frozen-lockfile
pnpm build
pnpm verify:native
pnpm release:pack --destination ./dist-pack/fresh
# or omit --destination to receive a unique temporary output directory
pnpm release:packnpm install --offline --no-audit --no-fund /path/to/gotlibr-aisdlc-<version>.tgzPublish from a clean tracked checkout with one version argument:
pnpm release:publish patch
# also accepted: minor, major, or an exact greater stable version such as 2.1.0The package postinstall verifies the matching native prebuild and compiles it locally when the
prebuild is absent. For a project-local install inside a Git repository, it also installs the
current top-level AISDLC Skill for Codex and Claude Code. Package-manager script suppression
disables both the native fallback and automatic Skill installation.
release:pack creates gotlibr-aisdlc-<version>.tgz. With no destination it creates a unique
temporary directory and returns the absolute path. An explicit destination refuses with RELEASE_EXISTS instead of overwriting an existing gotlibr-aisdlc-<version>.tgz.
release:publish persists the requested version bump, rebuilds, typechecks, verifies the complete
native matrix, runs the complete test suite, creates the canonical tarball, and publishes that exact
tarball to npm as latest. A failure before npm publication restores the original package version.
Once npm publication starts, a failure retains the bumped version because registry state may be uncertain.
Pushing a v<version> tag runs .github/workflows/publish.yml with Node.js 22.14.0 and
npm 11.5.1. It calls pnpm release:publish --tag <tag>, requiring the tag to match the committed
package version, and runs the same verification and packing pipeline before publishing through
npm trusted publishing (OIDC). npm accepts provenance only from public repositories, so this
private repository publishes without it. Configure the npm package's trusted publisher for GitHub repository
gotlibr/aisdlc and workflow publish.yml; no npm token or OTP is required.
The executable is ./node_modules/.bin/aisdlc. For source development, tell Codex or Claude Code:
Use this checkout's AISDLC build. The CLI equivalent is pnpm build, followed by
node dist/bin/aisdlc.js. The examples below use aisdlc as shorthand for whichever executable
path applies.
Quickstart
Normal operation uses one user-invocable, top-level AISDLC Skill.
| Agent | Native invocation |
| --- | --- |
| Claude Code | /aisdlc <brief intent> |
| Codex | $aisdlc <brief intent> or select AISDLC through /skills |
Claude Code derives /aisdlc from the managed .claude/skills/aisdlc entry. Codex discovers the
same canonical Skill at .agents/skills/aisdlc but does not register repository Skills as direct
custom slash commands. The text after either native invocation is brief intent, not CLI flags.
Every conversational example below uses Claude Code's /aisdlc form. In Codex, replace only the
leading /aisdlc with $aisdlc; the brief intent stays unchanged. The Skill inspects the repository
and catalog, resolves the executable, Workflow, Subject, Run, occurrence, outcome, selectors, IDs,
and flags, then asks one plain-language question only when a human decision is genuinely missing.
The CLI equivalents remain below for automation, debugging, and audit. Gate approval is the one
deliberate exception: the Skill presents the pending Gate but never invokes approve for the
human.
Work from inside the target Git repository. When Git-root
asdlc.workflows.tsis absent, the embedded flagship Workflow catalog is active.
1. Install AISDLC and its top-level Skill
Codex or Claude Code
Install AISDLC from /absolute/path/to/gotlibr-aisdlc-<version>.tgz.npm install --offline --no-audit --no-fund /absolute/path/to/gotlibr-aisdlc-<version>.tgz
git add package.json package-lock.json
git add .agents/skills/aisdlc .claude/skills/aisdlc
git commit -m 'chore: install aisdlc skill'
./node_modules/.bin/aisdlc catalogThe package lifecycle installs .agents/skills/aisdlc as the one canonical managed Skill and
creates .claude/skills/aisdlc as a symlink to it. A later package update refreshes authenticated
managed content in place. A conflicting or hand-edited file, directory, or link is refused without
overwrite. For explicit repair or an installation performed with lifecycle scripts disabled, use
/aisdlc repair the Codex and Claude Code integrations in Claude Code or $aisdlc repair the Codex
and Claude Code integrations in Codex. The CLI equivalents are aisdlc skill-sync and
aisdlc provider-install --provider claude-code.
Other provider integrations may install and commit an explicit control pointer:
Claude Code /aisdlc
/aisdlc set up provider <stable-slug>./node_modules/.bin/aisdlc provider-install --provider <stable-slug>2. Start one Run
Name the job and its scope. The Skill resolves the catalog identifier and mode:
Claude Code /aisdlc
/aisdlc define checkout./node_modules/.bin/aisdlc start --subject checkout --workflow definition --mode forwardThe Skill retains the returned Run ID and uses it for every subsequent command.
3. Hand the Run to the agent
/aisdlc continue| Owner | Responsibility |
| --- | --- |
| Human | States the job and scope; answers unresolved product questions; reviews bytes; runs approve; decides next work |
| Agent | Resolves CLI identities and flags; prepares authenticated batches; performs Steps; submits; commits permanent state; runs doctor |
| Engine | Resolves descriptors; validates transitions; records committed facts; remains actor-agnostic |
Keeping agents away from approve is an integration-layer responsibility represented by the
top-level Skill and provider control pointer, not hidden actor detection in the engine.
4. Execute the active Step
Claude Code /aisdlc
/aisdlc continueThe top-level Skill handles this internal loop:
./node_modules/.bin/aisdlc agent-next --subject checkout --run <run-id>agent-next returns one bounded batch per selected active occurrence. Each batch contains:
- the complete Step contract, prompt, Artifact catalog, and any explicitly declared context budget;
- ordered, digest-authenticated Workflow and Step
agentSkills; - outcome-keyed close instructions in
outcomeAgentSkills; - authenticated
outputTemplates; and - exact
submissionArtifactIds.
The agent reads each authenticated instruction body in order, uses each step.produces entry
as the exact instantiate spec, writes against the matching output Template, and selects one
declared outcome. agent-submit computes the exact current digest envelope and returns the next
authenticated batches, a human-gate waiting state, or the selected terminal close instruction.
./node_modules/.bin/aisdlc instantiate \
--subject checkout \
--run <run-id> \
--spec '<entry-from-value.step.produces>' \
--sections '<object-mapping-template-sections-to-accepted-content>' \
--summary 'Completed the current step'
./node_modules/.bin/aisdlc agent-submit \
--subject checkout \
--run <run-id> \
--outcome <success-outcome-id> \
--occurrence <batch-occurrence-id>Skill digests authenticate immutable instructions. Artifact digests attest mutable outputs. They are not interchangeable.
Each Skill reference contains only role, id, version, an absolute readable ref, and the
SHA-256 digest of the exact file. Workflow guidance precedes Step guidance. A close instruction
is returned only for its declared terminal outcome. A fully read Skill may be reused when its
exact digest repeats in the same task, after verifying that the referenced file still matches.
The agent never maps declaration IDs to instruction files.
Each output Template carries its canonical digest and complete section rules: required,
non-empty, human-owned, and typed-list constraints. At start, the Run persists every declared
Template digest. At resume and instantiate, the engine resolves the current Template by ID,
recomputes the digest, and compares it with the Run's templatePins. Missing content, forgery,
or drift is refused.
Durable paths bind {subject} and {run} from the current handoff. The flagship preset uses
both, so concurrent Runs never target the same durable Artifact path. After every state-changing
command and external approval, include Git-visible permanent .aisdlc state in the next commit.
--sections is a JSON object keyed by Template section. A normal section accepts a string. A section
with listFields accepts either compatible multiline text or an array of objects. Every array
item must contain all declared fields, no undeclared fields, and single-line string values;
enumerated fields accept only declared options.
Programmatic callers may use ordinary or null-prototype records. Every section and item field
must be an enumerable own string-named data property. Inherited fields, accessors, symbols,
non-enumerable fields, and exotic prototypes are refused without property execution. The engine
serializes fields in declared listFields order, independent of input key order.
{
"Purpose": "Define checkout behavior",
"Requirements": [
{
"acceptance": "Cart total is exact",
"statement": "Calculate the cart total",
"id": "REQ-001"
}
],
"Constraints": "- id: CON-001\n statement: Keep calculations deterministic\n source: owner",
"Owner Decisions": "Approved",
"Change Log": "Created"
}If Requirements.listFields declares id, statement, then acceptance, the serialized body
uses that order. extract --sections Requirements returns those exact canonical bytes. Invalid
shapes are refused before repository mutation with the section, item, and field identified.
5. Pass a human Gate
When the selected outcome has a Gate, commit every durable submitted Artifact first. That commit is the baseline proving that human-owned sections survive later automated updates.
Claude Code /aisdlc
/aisdlc show me what needs approvalThe Skill cannot approve on the human's behalf. After reviewing the presented bytes, the human runs the returned command with explicit answers:
./node_modules/.bin/aisdlc present --subject checkout --run <run-id> --outcome <outcome-id>
./node_modules/.bin/aisdlc approve \
--subject checkout \
--run <run-id> \
--outcome <outcome-id> \
--answers '{"<question-id>":"approved"}'Missing baseline content returns HUMAN_BASELINE_ABSENT. Changed submitted bytes make approval
stale and require resubmission. Failed validation never creates a Gate record.
After approval, run /aisdlc continue in Claude Code or $aisdlc continue in Codex. Repeat until
the Run records a terminal ending.
6. Close the Run and derive Knowledge
For a terminal outcome, the agent reads that outcome's exact outcomeAgentSkills reference and
performs only its close protocol. A declared follow-up appears in terminalFollowUps and the
successful ending record.
Claude Code /aisdlc
/aisdlc finish this run./node_modules/.bin/aisdlc derive-template --subject <subject> --run <run-id> --file knowledge.jsonderive-template exports only authenticated, visited, descriptor-declared durable Artifacts. It
does not mutate Knowledge; it returns the exact subsequent derive command. Repeating it with
identical source bytes is idempotent. Existing different files, symlinks, traversal, and absolute
paths are refused without overwrite. Only derive performs the one-way crossing into Knowledge.
A later successful Run may derive the same Knowledge IDs again. Current nonhistorical documents are atomically replaced and advance to that Run; Run-owned source Artifacts remain immutable. Exact replay is byte-idempotent. Content correction remains a separate gated update that preserves human-owned sections.
After external approval of a terminal outcome, confirm the ending with status; do not resume
the ended Run. An ending never implies a successor Workflow. Control returns to explicit human
orchestration.
./node_modules/.bin/aisdlc status --subject checkout --run <run-id>
./node_modules/.bin/aisdlc inventory --subject checkout
./node_modules/.bin/aisdlc doctor --subject checkoutTo terminate an unfinished Run instead, run
/aisdlc abandon this run because <reason> in Claude Code or the $aisdlc equivalent in Codex.
./node_modules/.bin/aisdlc abandon --subject checkout --run <run-id> --reason <reason>How it works
flowchart TD
H["Human states a job and scope"] --> O["Top-level Skill resolves catalog and Run identities"]
O --> S["start pins the Workflow and Templates"]
S --> N["agent-next returns one authenticated Step batch"]
N --> A["Agent creates or updates declared Artifacts"]
A --> U["agent-submit authenticates the exact submission set"]
U --> V{"Validations pass?"}
V -->|"No"| R["Refusal without transition"]
V -->|"Yes"| G{"Outcome has a Gate?"}
G -->|"Yes"| W["Committed submitted digest; wait for human"]
W --> P["present + approve against those exact bytes"]
G -->|"No"| T["Commit the declared Outcome"]
P --> T
T --> E{"Run ended?"}
E -->|"No"| N
E -->|"Yes"| K["Derive authenticated Knowledge"]
K --> D["Stable FeatureDocs or ADRs; code-pin drift for product Knowledge"]Every state-changing command produces repository-local permanent state for the next Git checkpoint. A process can disappear after any committed fact; the next process resumes from the pinned Run rather than reconstructing intent from chat history.
Definition and delivery are independent pipelines:
flowchart LR
A["Conversation or existing system"] --> B["Definition Run"]
B --> C["Approved requirements and design"]
C -->|"Human selects and hands off a task"| D["Independent delivery Run"]
D --> E["Code, tests, and documentation"]
E --> F["Derived Knowledge"]
F --> G["Drift detection"]The human decides which approved task to deliver. AISDLC records completed facts and enforces declared contracts; it never reports priority, progress, readiness, a frontier, or the next task.
Included workflows
The embedded flagship preset is usable without scaffolding or configuration.
| Workflow ID | Version | Steps | Success-path approvals | Use it for |
| --- | ---: | ---: | ---: | --- |
| definition | 3.0.0 | 8 | 5 | Conversation, mandatory requirements, justified research, design, neutral task decomposition, and integrated FeatureDocs |
| delivery-bug-fix | 3.0.0 | 6 | 2 | Bug-fix planning, proof tests, implementation, delivery evidence, documentation, and integrated Knowledge handling |
| delivery-external-item | 3.0.0 | 7 | 3 | External-request attestation, delivery and proof planning, tests, implementation, evidence, documentation, and integrated Knowledge handling |
| architecture-decision | 1.0.0 | 1 | 1 | One MADR-formatted decision and an atomic repository-global ADR catalog refresh |
Approval counts describe the packaged primary success path before optional investigation or
correction loops. Alternate declared Outcomes remain visible through describe and compile.
Start any Workflow in forward mode for new work or retrospective mode for a system that
already exists:
Claude Code /aisdlc
/aisdlc document the existing checkout system retrospectivelyaisdlc start --subject existing-checkout --workflow definition --mode retrospectiveArchitecture Decision Subjects use adr-NNNN-kebab-title; title identity is validated before
the source Artifact or Run state can be written.
Retrospective mode compiles the same success path into an explicit plan. Steps without useful durable output are skipped with recorded facts; durable facts are observed or attested. It is not a separate reduced workflow.
Core model
| Noun | Meaning | | --- | --- | | Template | Typed Markdown structure for an Artifact | | Artifact | Content produced, consumed, read, or updated by a Step | | Validation | Deterministic check applied before a transition | | Gate | Human approval over submitted content and declared questions | | Skill | Top-level user orchestration plus digest-authenticated Workflow, Step, and terminal Outcome instructions | | Step | Typed work contract with inputs, outputs, outcomes, and optional Gate | | Workflow | Declarative graph of Steps and transitions | | Subject | Exact scope shared by its Runs and Knowledge | | Run | Append-only execution history of one Workflow for one Subject | | Knowledge | Durable, code-pinned projection derived from completed work |
A preset is inert packaged data containing these descriptors. It is not another domain noun and cannot add behavior to the generic engine.
Agent handoff and structural Markdown
Every handoff is designed for a fresh, zero-context agent. It contains the complete active Step contract, exact submission digest membership, authenticated output Template descriptors, ordered Workflow and Step Skill references, outcome-keyed close Skill references, prompt material, a catalog of relevant Artifacts, and a byte budget. Catalog entries expose section selectors rather than silently loading entire files.
Section access
outline returns a CommonMark section tree with heading, depth, exact UTF-8 body size,
children, and stable JSON-Pointer-style selectors such as /Architecture/Ports. In selectors,
~ becomes ~0 and / becomes ~1. extract returns the exact selected subtree. A bare
heading is accepted only when it identifies one top-level section unambiguously.
Claude Code /aisdlc
/aisdlc show the architecture ports and decisions in the current Artifactaisdlc outline --subject checkout --run <run-id> --artifact <artifact-id>
aisdlc extract --subject checkout --run <run-id> --artifact <artifact-id> \
--sections /Architecture/Ports,/DecisionsOmitting --sections, passing --sections '', or passing only whitespace means the complete
Artifact, including all descendants. A comma-separated value containing an empty member is
invalid. Literal [] and /[] remain legal selectors when those headings exist. Inlining a
parent includes its descendants; selecting only a child preserves the child's original heading
and depth.
Knowledge
Product Knowledge is scoped to one Subject and derived from completed work. Architecture Decision
Records use the same derivation crossing but publish into one repository-global catalog under
docs/architecture/decisions; each ADR remains a separate decision file, with accepted or rejected
bodies immutable except for the reciprocal supersession metadata and Change Log update. Every flagship
product-Knowledge source template—hub, topic, and API reference—requires one typed Code Scope
section with the exact fields pin, then paths. Drift reports whether those paths changed after
the pin; it does not search across Subjects or continuously watch the repository.
Common operations
Claude Code /aisdlc
/aisdlc derive checkout Knowledge, show its FeatureDocs, check drift, and rebuild its projectionaisdlc derive-template --subject checkout --run <run-id> --file knowledge.json
aisdlc derive --subject checkout --run <run-id> --file knowledge.json
aisdlc knowledge-read --subject checkout --ids feature-index,feature-overview,feature-api
aisdlc drift --subject checkout
aisdlc knowledge-recompute --subject checkoutDerivation contract
knowledge.json is a closed JSON array conforming to
schemas/knowledge-input.schema.json (also staged at
dist/schemas/knowledge-input.schema.json). derive-template maps each declared source Artifact
to exactly one document: Artifact id, templateId, repository path, and content are copied;
subject is the named Subject; noun is Knowledge; historical is false; Subject references
come from the source Template's declared reference syntaxes. A Template section whose exact typed
fields are pin, then paths, defines mechanical drift: use one list item per repository-relative
path and repeat one 7–64 character lowercase hexadecimal Git commit pin across all items. The pin
must resolve to a commit object in the current repository; export canonicalizes an abbreviated pin
to its full commit ID. Missing objects, blobs, trees, tags, different pins, an empty scope,
absolute/traversing/backslash paths, unknown fields, missing fields, duplicate IDs, wrong Subjects,
and an empty document array are refused before export or Knowledge mutation with
KNOWLEDGE_CODE_PIN_INVALID for every non-commit pin.
Example generated entry:
{
"noun": "Knowledge",
"id": "feature-overview",
"subject": "checkout",
"templateId": "knowledge-topic",
"path": "docs/features/checkout/topics/overview.md",
"content": "# Summary\nCurrent behavior...",
"references": [],
"codeScope": { "pin": "0123456789abcdef0123456789abcdef01234567", "paths": ["src/checkout.ts"] },
"historical": false
}Before derive, those Artifacts remain Run evidence and inventory/knowledge-read return no
new Knowledge. A successful derive commits the documents, inventory, and projection atomically.
The engine authorizes the complete batch against the exact pinned successful terminal Outcome,
follow-up, submitted Artifact digests, resolved durable specs, Template pins, and stored source
bytes. Missing, additional, forged, historical, or mismatched documents write nothing.
knowledge-recompute rebuilds the per-Subject projection from committed Knowledge records; it
does not invent new content.
TypeScript Workflow authoring
Workflow authoring has one optional source: asdlc.workflows.ts at the target Git root. When
the file is absent, every nested working directory uses the packaged flagship catalog. When the
file is present, its synchronous default export is the complete catalog; nothing from the
flagship is merged implicitly. Any source read, compile, evaluation, export, or descriptor
validation failure is terminal. Invalid source never falls back to the packaged catalog.
The declaration imports only the public @gotlibr/aisdlc/workflows package entry. Do not import
dist/**, src/**, or packaged preset assets. The file is trusted repository code executed
with the CLI user's filesystem, process, and environment privileges. The loader is not a
sandbox. Review the file with the same rigor as any build script.
Every command accepts --config <dir> to resolve asdlc.workflows.ts,
aisdlc.config.json, and skills/ from that directory. Relative directories resolve from the
invocation directory. Run state stays in the repository's .aisdlc/; the config directory
receives no engine state. Without this flag, configuration resolves from the Git root.
Public package surface
@gotlibr/aisdlc/workflows is the only public TypeScript module boundary. Execution is CLI-backed; normal
repository operation is conversational through the installed AISDLC Skill.
| Export group | Public surface |
| --- | --- |
| Declaration factories | artifact, reference, validation, gate, followUp, hook, outcome, step, workflow, defineWorkflows |
| Packaged content | flagshipWorkflows, createFlagshipWorkflows |
| Repository behavior | repositoryPolicy, DEFAULT_REPOSITORY_POLICY |
| Identity and pins | ids, digest, descriptorVersion |
| Builder implementations | Artifact, reference, Validation, Gate, follow-up, Hook, Outcome, Step, Workflow, Template, and catalog builders |
| Contracts | Descriptor, builder, identifier, JSON Result, Run, Gate, Knowledge, handoff, inventory, migration, and lifecycle Hook TypeScript types |
The shipped schemas/*.json files describe closed runtime and data contracts. In particular,
workflow.schema.json describes the immutable descriptor emitted by TypeScript builders; it is
not a handwritten Workflow authoring format.
Catalog composition
defineWorkflows() starts an empty replacement catalog. Seed it with
flagshipWorkflows only when the repository explicitly extends the packaged catalog.
Catalog operations are immutable and preserve order: add appends, replace and edit
stay in place, remove deletes by ID, and build returns the deeply frozen complete catalog.
import { defineWorkflows, flagshipWorkflows } from "@gotlibr/aisdlc/workflows";
export default defineWorkflows(flagshipWorkflows)
.remove("definition")
.add(customWorkflow)
.replace("delivery-bug-fix", replacementWorkflow)
.edit("delivery-external-item", current => ({ ...current, version: "4.0.0" }))
.build();Duplicate IDs and missing edit, replace, or remove targets fail while evaluating
asdlc.workflows.ts. Nothing is partially applied.
The same root source may export one closed repository policy. Compact terminal history is the
default. Select full only when every Run transition must remain in the working tree for external
audit or debugging.
import { defineWorkflows, flagshipWorkflows, repositoryPolicy } from "@gotlibr/aisdlc/workflows";
export const repository = repositoryPolicy({ terminalRunHistory: "compact" });
export default defineWorkflows(flagshipWorkflows).build();Unknown named exports, policy keys, and policy values fail configuration loading. The policy never changes a live Run's workflow descriptor or its declared public documentation destinations.
Lifecycle Hooks are authored in this same TypeScript surface. A Hook declares one supported lifecycle event and one shell-free executable invocation. Catalog Hook operations apply identically to packaged and custom Workflows.
import { defineWorkflows, flagshipWorkflows, hook, ids } from "@gotlibr/aisdlc/workflows";
const finalize = hook()
.identify(ids.hook("commit-and-push"))
.on("run.ended")
.command("scripts/commit-and-push", ["--all"])
.build();
export default defineWorkflows(flagshipWorkflows)
.addHook("delivery-bug-fix", finalize)
.build();The identical operation applies to a custom catalog:
export default defineWorkflows([customWorkflow])
.addHook("custom-delivery", finalize)
.build();Commands are launched directly without a shell. Executables and arguments must be nonblank and
contain no NUL byte. Supported events are run.started, step.entered, step.submitted,
outcome.taken, step.skipped, and run.ended.
Dispatch begins only after the corresponding Run fact is committed. A command failure returns
LIFECYCLE_HOOK_FAILED with transitionCommitted: true; it never rolls the fact back. Dispatch is
synchronous and has no durable retry queue, so Hook commands must be idempotent. The stable
AISDLC_HOOK_INVOCATION_ID supports wrapper-side deduplication.
Every command runs at the Git root and receives AISDLC_HOOK_ID, AISDLC_HOOK_EVENT,
AISDLC_HOOK_SUBJECT, AISDLC_HOOK_RUN_ID, AISDLC_HOOK_WORKFLOW_ID,
AISDLC_HOOK_WORKFLOW_VERSION, AISDLC_HOOK_DESCRIPTOR_PIN, and AISDLC_HOOK_MODE.
Step, occurrence, outcome, and ending facts additionally set the corresponding
AISDLC_HOOK_STEP_ID, AISDLC_HOOK_OCCURRENCE_ID, AISDLC_HOOK_OUTCOME_ID, and
AISDLC_HOOK_ENDING. run.ended includes succeeded, cancelled, and historicized; a
commit-and-push wrapper intended only for successful completion must require
AISDLC_HOOK_ENDING=succeeded.
Declare a custom Workflow
Every Workflow builder receives the complete Template and Skill ID sets that its descriptor may
reference. The sets validate references; they do not load assets. This complete declaration uses
the packaged task-record Template and delivery Skill:
import {
artifact, defineWorkflows, descriptorVersion, hook, ids, outcome, reference, step, workflow
} from "@gotlibr/aisdlc/workflows";
const references = {
templates: [ids.template("task-record")],
skills: [ids.skill("delivery")]
};
const record = artifact()
.identify(ids.artifact("delivery-record"))
.template(ids.template("task-record"))
.durable(".aisdlc/work/{subject}/{run}/record.md")
.build();
const intake = step()
.identify(ids.step("intake"))
.displayName("Capture delivery request")
.skill(ids.skill("delivery"))
.produce(record)
.outcome(outcome().identify(ids.outcome("intake.done"))
.success(ids.step("review")).build())
.outcome(outcome().identify(ids.outcome("intake.cancelled")).cancel().build())
.build();
const review = step()
.identify(ids.step("review"))
.displayName("Review delivery record")
.skill(ids.skill("delivery"))
.consume(reference().identify(record.id).inline(true).build())
.outcome(outcome().identify(ids.outcome("review.done")).success().build())
.outcome(outcome().identify(ids.outcome("review.cancelled")).cancel().build())
.build();
const finalize = hook()
.identify(ids.hook("finalize-custom-delivery"))
.on("run.ended")
.command("scripts/commit-and-push", ["--all"])
.build();
const customWorkflow = workflow(undefined, references)
.identify(ids.workflow("custom-delivery"))
.version(descriptorVersion("1.0.0"))
.skill(ids.skill("delivery"))
.entry(ids.step("intake"))
.hook(finalize)
.step(intake)
.step(review)
.descriptor();
export default defineWorkflows([customWorkflow]).build();Modify a declared Workflow
Every factory accepts an existing value as its seed. Catalog edit supplies a cloned current
descriptor, so nested edits can rebuild only the changed path. This edit inserts a replacement
Step, redirects the incoming edge, changes an Artifact path, removes the old Step, and increments
the descriptor version:
const approval = step(review)
.identify(ids.step("approval"))
.displayName("Approve delivery record")
.replaceOutcome("review.done",
outcome().identify(ids.outcome("approval.done")).success().build())
.replaceOutcome("review.cancelled",
outcome().identify(ids.outcome("approval.cancelled")).cancel().build())
.build();
export default defineWorkflows([customWorkflow])
.edit("custom-delivery", current => workflow(current, references)
.version(descriptorVersion("2.0.0"))
.editStep("intake", currentStep => step(currentStep)
.editProduce("delivery-record", currentArtifact => artifact(currentArtifact)
.repositoryPath(".aisdlc/work/{subject}/{run}/approved.md")
.build())
.editOutcome("intake.done", currentOutcome => outcome(currentOutcome)
.destination(ids.step("approval"))
.build())
.build())
.insertAfter("intake", approval)
.removeStep("review")
.descriptor())
.build();For any seed descriptor, pass reference sets containing every Template and Skill it already uses,
plus any new references. Catalog edit may also return a complete descriptor directly when a
nested builder is unnecessary.
Builder capability reference
All methods return new builder state. Every collection supports explicit add, remove, replace, and edit operations where listed.
| Factory or surface | Declaration and modification capabilities |
| --- | --- |
| defineWorkflows(seed) | add, remove, replace, edit; addHook/removeHook/replaceHook/editHook; build |
| workflow(seed, references) | identify, version, skill, removeSkill; hook/removeHook/replaceHook/editHook; context, removeContext, replaceContext, editContext, entry, step, insertBefore, insertAfter, removeStep, replaceStep, editStep, sequence, parallel, removeParallel, build, descriptor |
| step(seed) | identify, displayName, skill, budget, session, executor; produce/removeProduce/replaceProduce/editProduce; consume/removeConsume/replaceConsume/editConsume; read/removeRead/replaceRead/editRead; update/removeUpdate/replaceUpdate/editUpdate; outcome/removeOutcome/replaceOutcome/editOutcome; build |
| artifact(seed) | identify, template, durable, temporary, repositoryPath, build |
| reference(seed) | identify, noun, sections, inline, build |
| validation(seed) | identify, kind, parameter, removeParameter, replaceParameter, editParameter, build |
| gate(seed) | identify, question, removeQuestion, replaceQuestion, editQuestion, approval, removeApproval, editApproval, build |
| followUp(seed) | instruction, destination, removeDestination, replaceDestination, editDestination, build |
| hook(seed) | identify, on, command, build |
| outcome(seed) | identify, success, custom, cancel, destination; validation/removeValidation/replaceValidation/editValidation; gate/removeGate/replaceGate/editGate; closeSkill/removeCloseSkill/replaceCloseSkill/editCloseSkill; followUp/removeFollowUp/replaceFollowUp/editFollowUp; inject, removeInjection, build |
Steps may declare session("fresh" | "continue") and executor("agent" | "script").
These fields are returned in Step metadata, including agent-next handoffs, for the caller to
interpret. They do not change engine execution and are omitted when undeclared.
Step context is unbounded by default. Call budget(tokens) with a positive integer to opt into
engine enforcement for a custom Step. Packaged Workflows do not declare context budgets.
sequence(...stepIds) adds missing success edges between existing Steps. parallel(id,
branches, join) declares branches and adds their entry, member, and join edges.
removeParallel(id) restores only builder-generated edges and refuses if those edges were
edited afterward.
Final descriptor construction rejects incomplete or duplicate declarations, unknown Template or Skill references, dangling or unreachable Steps, success cycles, invalid parallel graphs, unavailable Artifact dependencies, updates to temporary Artifacts, invalid Outcome shapes, and repository paths that escape the Git root. Graph edits are never silently repaired: redirect or remove every entry, destination, parallel member, and Artifact dependency explicitly.
Catalog commands consume the evaluated descriptor catalog by ID:
Claude Code /aisdlc
/aisdlc validate edited-flow and compare it with path-flowaisdlc catalog
aisdlc validate --workflow edited-flow
aisdlc describe --workflow edited-flow
aisdlc compile --workflow edited-flow --mode forward
aisdlc diff --source-workflow edited-flow --target-workflow path-flowaisdlc.config.json remains the closed root surface for non-Workflow preset, templates, and
skills settings. It cannot author or locate Workflows. Every other field is invalid. Handwritten
Workflow JSON is not an authoring source. Packaged non-Workflow assets are composed with the
TypeScript Workflow catalog and metadata at runtime.
Live migration
Changing a descriptor never silently rebinds an active Run. Dry-run against the target Workflow ID, persist the returned exact plan, review it, then apply that plan:
Claude Code /aisdlc
/aisdlc plan migrating this run to edited-flowAfter reviewing the plan, give a separate instruction:
/aisdlc apply that planaisdlc migrate --dry-run --subject checkout --run <run-id> --target-workflow edited-flow
aisdlc migrate --apply --subject checkout --plan migration-plan.jsonApply atomically replaces the active descriptor pin and complete Template pin set. A refused or stale plan writes nothing. Starting a Run is always a real mutation and has no dry-run form.
Command reference
All output is newline-delimited JSON: successful records go to stdout and failures to stderr.
Flags are closed; undeclared or repeated flags are rejected.
Run aisdlc, aisdlc --help, aisdlc help <command>, or aisdlc <command> --help
for machine-readable discovery without requiring a repository.
Normal operation does not require memorizing this surface or supplying internal identities. Give the top-level Skill a brief task-level instruction; it discovers the command details and asks only for a missing human decision. For read-only discovery:
/aisdlc explain migration| Job | Commands |
| --- | --- |
| Discover and inspect | help, catalog, preset, validate, describe, compile, diff |
| Start and observe Runs | start, status, resume, inventory |
| Operate agent batches | agent-next, agent-submit |
| Create and read Artifacts | instantiate, outline, extract |
| Submit and approve | submit, present, approve |
| End and retain Runs | abandon, archive, historicize, purge |
| Evolve live Runs | migrate --dry-run, migrate --apply |
| Derive and inspect Knowledge | derive-template, derive, knowledge-read, knowledge-recompute, drift |
| Check boundaries and integrity | scope, doctor |
| Manage agent integration | skill-sync, provider-install |
Exact syntax:
help [<command>]
catalog
preset
validate --workflow <workflow-id>
describe --workflow <workflow-id>
compile --workflow <workflow-id> --mode forward|retrospective
diff --source-workflow <workflow-id> --target-workflow <workflow-id>
start --subject <subject> --workflow <workflow-id> --mode forward|retrospective
status [--subject <subject> [--run <run-id>]]
resume --subject <subject> --run <run-id> [--occurrence <occurrence-id>]
agent-next --subject <subject> --run <run-id> [--occurrence <occurrence-id>]
agent-submit --subject <subject> --run <run-id> --outcome <outcome-id> [--occurrence <occurrence-id>]
instantiate --subject <subject> --run <run-id> --spec <json> --sections <section-object-json> --summary <text>
outline --subject <subject> --run <run-id> --artifact <artifact-id>
extract --subject <subject> --run <run-id> --artifact <artifact-id> [--sections <selector,...>]
submit --subject <subject> --run <run-id> --outcome <outcome-id> --digests <json>
present --subject <subject> --run <run-id> --outcome <outcome-id>
approve --subject <subject> --run <run-id> --outcome <outcome-id> --answers <json>
abandon --subject <subject> --run <run-id> --reason <text>
archive --subject <subject> --run <run-id>
migrate --dry-run --subject <subject> --run <run-id> --target-workflow <workflow-id>
migrate --apply --subject <subject> --plan <plan.json>
inventory --subject <subject>
historicize --subject <subject>
purge --subject <subject>
doctor --subject <subject>
derive-template --subject <subject> --run <run-id> --file <knowledge.json>
derive --subject <subject> --run <run-id> --file <knowledge.json>
knowledge-read --subject <subject> --ids <knowledge-id,...>
knowledge-recompute --subject <subject>
drift --subject <subject> [--head <git-ref>]
scope --file <capability.json>
skill-sync
provider-install --provider <stable-slug>When called without arguments, status resolves a Run from the current directory's recorded
facts. If a Run has multiple active occurrences, resume requires the exact occurrence ID.
scope checks a proposed capability against the six-question product boundary. skill-sync
installs or upgrades the packaged top-level Skill at .agents/skills/aisdlc/SKILL.md, with a
content receipt that distinguishes an older managed version from a human edit; that Skill
contains only the generic prepare/execute/submit protocol. For claude-code, provider-install
syncs that canonical Skill and creates .claude/skills/aisdlc as a directory symlink to it. Other
providers receive a small marked integration pointer. Neither command copies presets, invokes
providers, or enables network access.
The package lifecycle invokes the same managed installation against the Git repository containing
INIT_CWD. It runs on project-local install and update, skips source-package and non-repository
installation contexts, and does not initialize .aisdlc engine state.
State, recovery, and deletion
Each Run owns one ledger at .aisdlc/runs/<subject>/<run>/state.aidb. While active, the ledger is
append-only. Under the default compact policy, ending the Run atomically replaces that history
with one authenticated checkpoint containing the terminal state and Artifact metadata. Durable
working Artifacts live under .aisdlc/work/<subject>/<run> while a gate may need Git-visible
source bytes, then their content is packed into that terminal checkpoint and the working files are
removed. terminalRunHistory: "full" retains the transition ledger and working files. Separate
Runs and Subjects still modify separate files and merge without a synthetic global conflict.
| Command | Effect |
| --- | --- |
| archive | Preserves one Run's history and removes its scratch |
| historicize | Preserves all Subject history, cleans scratch, and marks Knowledge historical |
| purge | Deletes the exact Subject inventory; Git history is the only undo |
The native Run ledger stores logical state.json, transitions/<version>.json, and
artifacts/<artifact-id>.json keys in one physical file while active. A compact terminal
checkpoint stores current state.json and Artifact metadata only. Its Run record includes the Workflow
descriptor pin, complete Template pin set, versioned positions, outcomes, Gate records, and
ending or migration facts. Embedded Workflow descriptors resolve by committed digest without
redundant repository copies; exceptional non-embedded Workflow versions remain
content-addressed. Templates resolve current content by TemplateId, then their canonical digest
is compared with the persisted templatePins. Same-ID drift or forgery refuses resume and
instantiation until an explicit migration changes those pins; Template bodies are not
historically retrievable by digest.
Run ledgers, archive ledgers, and Knowledge records are normal Git-tracked repository state.
Each Subject's Knowledge metadata, inventory, projection, and derived source content are virtual
paths backed by one .aisdlc/knowledge/<subject>/state.aidb; the independent revision ledger
retains transaction concurrency control. Existing file-tree Knowledge storage remains readable
without mutation and is migrated idempotently by the next Knowledge write. Public documentation is not stored there: FeatureDocs publish to
docs/features/<subject>/{index.md,topics/*,api.md} and ADRs publish to
docs/architecture/decisions.
Repository initialization atomically extends the common Git directory's untracked
info/exclude with exact rules for .aisdlc/.journal-key, .aisdlc/.transactions/, live
Run scratch, and conventional Hook telemetry under .aisdlc/hooks/. Existing .gitignore and info/exclude bytes are retained, and repeated
initialization is byte-idempotent. Before writing, the engine evaluates Git's effective rules
for every transient class and a permanent Run-ledger probe. A rule that exposes a transient or
hides permanent .aisdlc state is refused with STATE_TRACKING_IGNORED without modifying Git
metadata or engine state. Per-Run ledgers and Knowledge therefore remain visible to Git without
creating a shared branch-conflict file, including from linked worktrees.
The write root for info/exclude is derived from no-follow filesystem metadata, never from Git
command output. Direct checkouts require an owned .git directory. Linked worktrees require an
exact .git pointer, an admin directory owned by the common Git directory, exact commondir, and
a canonical gitdir back-reference to that worktree. Git's reported common directory only
corroborates the derived root; disagreement refuses before Git metadata or engine state changes.
Journaled mutations use .aisdlc/.transactions transiently. Recovery rolls incomplete
transactions backward and committed transactions forward, then removes the journal. There is
no daemon, server, network dependency, lock, lease, worker state, tracker, or second observer.
purge performs no inbound-reference scan.
Deliberate boundaries
The product does not provide task ordering, prioritization, delegation, scheduling, boards, campaigns, adoption tracking, cross-Subject search, inter-Workflow orchestration, mutable status, network calls, or background workers. It has no lexical refusal list or synonym filter; only commands in the actual command table exist. These omissions preserve a deterministic, actor-agnostic execution core.
Verification
Run the complete local verification suite before packing:
Claude Code /aisdlc
/aisdlc verify this packagepnpm typecheck
pnpm test
pnpm architecture:verify
pnpm test:cold-startThe suite covers architecture, conformance, fault recovery, CLI, native integration, and installed-package cold starts.
Authoritative documents
The binding product contract is:
