Kyro Sprint Forge — Runtime Contract (v4)
One scope = one sprint.json. Agents read project state + its lean pack, then route on nextAction. No agent-facing files.
Step 0 — Startup (MANDATORY, before anything else)
Run this before reading any other section and before writing any Kyro artifact. It is the same
handshake the orchestrator performs; it is repeated here in full because this skill is invocable on
its own (kyro-ai:sprint-forge), and on that path the orchestrator is never loaded.
- Resolve
{{KYRO_CLI}}, once per session, before anything else below. This token is normally
substituted at install time by npx kyro-ai install/sync. If you are reading this from a channel
that never ran that substitution (for example, installed as a Claude Code plugin from the
marketplace), the literal 12 characters {{KYRO_CLI}} are still sitting in this file — resolve
them yourself:
- Run
kyro --version. If it exits 0, {{KYRO_CLI}} means bare kyro for the rest of this session.
- Else, check whether
~/.agents/kyro/current/dist/cli.js exists. If it does, {{KYRO_CLI}} means
node ~/.agents/kyro/current/dist/cli.js.
- Else, Kyro's runtime is not installed on this machine. STOP — tell the user to run
npx kyro-ai@latest install --scope workspace --init-workspace --yes once, then retry. This is
not a license to hand-edit sprint.json or improvise; same rule as a missing verb in Step 4.
Substitute the resolved value mentally everywhere {{KYRO_CLI}} appears in this or any other loaded
skill asset for the rest of the session — never run the literal 12 characters {{KYRO_CLI}}.
- Read
.agents/kyro/project.json + .agents/kyro/local.json. Unreadable/corrupt → stop here.
- Resolve the scope from user input,
local.json.activeScope, or the only directory under
.agents/kyro/scopes/. Ambiguous or none → ask the user before continuing.
- A scope that does not exist yet — neither in
project.json nor on disk — is creation,
not corruption: skip repair and context-pack, load modes/INIT.md, and never route it
to recovery.
- Only for an existing scope, silently run
{{KYRO_CLI}} repair integrity prepare --kyro-scope <scope> --json before context-pack. Never omit --kyro-scope here — it isolates this
scope from unrelated drift. Findings/blockers → load modes/recover.md and stop. None → continue.
- Capability handshake: run
{{KYRO_CLI}} capabilities --json. Unknown command, handshake
failure, or a missing tool-owned verb (record-evidence included) means the runtime is unusable: ABORT without mutating Kyro
state. Report the observed output of {{KYRO_CLI}} --version (or not installed) and the exact
remedy npx kyro-ai@latest sync --scope workspace --yes. Never work around it by hand.
- Resolve routing with
{{KYRO_CLI}} context-pack --kyro-scope <scope> --json (lean pack:
nextAction, nextTaskId, reviewPending, conventions, budget). Do not open the full
sprint.json to route. No sprint.json → INIT.
- Load the single mode named by the pack's
nextAction (see Routing below).
If Step 0 did not complete, no Kyro artifact gets written. A CLI you could not resolve, a failed
handshake, or a missing runtime are all STOP conditions — never a reason to hand-author sprint.json,
project.json, or local.json. Claude Code may add a PreToolUse defense, but that host-specific hook
is reinforcement only; the portable guarantee is this fail-closed CLI contract.
Core Invariants
sprint.json is the single source of truth; one file to update per action (see Read Path Contract).
- Route on the pack's
nextAction (mirrors handoff.nextAction); never infer from file presence.
- Generate one sprint; never pre-generate.
- Tasks are self-contained: every task carries
description, files_to_touch, context, acceptance_criteria.
- Debt never disappears; it only changes
status (open → in_progress → resolved | deferred).
- Closing a sprint is owned by
{{KYRO_CLI}} close-sprint — never null activeSprint by hand; it becomes one ledger[] entry.
- Findings/archives are write-only evidence; never re-read to route.
- Admit unknowns, never guess. Write
[NEEDS CLARIFICATION: <gap>] and route to clarify. {{KYRO_CLI}} doctor/analyze FAIL while any marker remains.
- Tool-owned verbs require a CLI that exposes them (Startup handshake). A missing verb means the runtime is too old — abort; never fall back by hand.
Read Path Contract (context-pack first) — MANDATORY
The full sprint.json is ~10–20k tokens. Never open it to route/execute/review or brief status — read the lean pack ({{KYRO_CLI}} context-pack --kyro-scope <scope> --json; --task[ <id>] for execute/review). Open the full file only when plan_sprint/close_sprint/status-full needs its planning or reporting context; agents never open it in order to write it.
Artifact Write Contract (MANDATORY)
Every mutation of sprint.json, project state, checkpoints, or archive/ MUST be owned by a CLI verb.
The CLI validates, locks, writes, and re-verifies the affected state internally. Agents must not
substitute an editor, patch, or ad-hoc script. If a required state-changing verb is absent, stop and
report the observed runtime version plus npx kyro-ai@latest sync --scope workspace --yes.
Tool-owned operations (use the CLI, do not hand-roll)
Irreversible or schema-critical operations are CLI-owned, never hand-rolled:
| Command |
What it owns |
{{KYRO_CLI}} close-sprint --kyro-scope <scope> --outcome <...> |
Lossless close: publishes the checkpoint, snapshots into ledger[], reconciles state. |
{{KYRO_CLI}} doctor --artifacts --kyro-scope <scope> |
Validates shape drift, checkpoint state/digests/artifacts, legacy snapshots, and unresolved [NEEDS CLARIFICATION]. |
{{KYRO_CLI}} analyze --kyro-scope <scope> |
Semantic cross-check (clarity, coverage, deps, debt, principles); non-zero on CRITICAL/HIGH. Gate before close. |
{{KYRO_CLI}} repair --kyro-scope <scope> |
Normalizes sprint.json formatting. |
{{KYRO_CLI}} clarify --from <file> --kyro-scope <scope> |
Records one or more accepted clarification decisions and safely advances routing when clear. |
{{KYRO_CLI}} rule add ... [--global] |
Adds a scope rule; --global also writes project.json after approval. |
{{KYRO_CLI}} scope complete --kyro-scope <scope> |
Explicit finished-scope completion (Forge overlay). Not retirement. |
Claude Code's PreToolUse hook adds host-specific defense against manual managed-state writes. Other
hosts may not expose an equivalent hook, so correctness never depends on it.
Routing (handoff.nextAction → mode)
User intent to complete/close a finished scope is {{KYRO_CLI}} scope complete (Forge overlay), not a nextAction and not retirement. done means already terminal.
| nextAction |
Load |
init (no sprint.json) |
modes/INIT.md + one helpers/analysis/{workType}.md |
clarify |
modes/clarify.md |
plan_sprint |
modes/SPRINT.md, modes/plan-sprint.md, then helpers/sprint-generator.md |
await_scope_completion |
Ask: complete the finished scope, or explicitly expand it. Complete → scope complete; expand → then route as plan_sprint. |
execute_task |
modes/SPRINT.md, modes/execute-task.md |
review_task |
modes/SPRINT.md, modes/review-task.md, helpers/reviewer.md |
close_sprint |
modes/SPRINT.md, modes/close-sprint.md, helpers/debt-tracker.md + helpers/learner.md as needed |
done |
Stop — already complete or retired. No work mode. |
| status report |
modes/STATUS.md |
| inconsistent |
modes/recover.md |
Templates are loaded only immediately before writing their artifact.
Principles, conventions, ADRs
principles[] in project.json: authored gates; non-negotiable blocks.
conventions[]: scope rules live in sprint.json; approved globals also live in project.json. Use {{KYRO_CLI}} rule add [--global].
adrs[] in sprint.json: durable scope architecture decisions with tradeoffs.
Artifact Contract
| File |
Role |
.agents/kyro/project.json |
Shared registry: scopes[], optional principles[], optional global conventions[] |
.agents/kyro/local.json |
Personal state: activeScope, installed adapters, execution preferences |
.agents/kyro/scopes/{scope}/sprint.json |
Single source of truth (see template) |
.agents/kyro/scopes/{scope}/archive/sprint-NNN-slug.md |
Human narrative at close (write-only) |
.agents/kyro/scopes/{scope}/archive/sprint-NNN-slug.json |
Verbatim snapshot of the closed sprint (write-only) |
.agents/kyro/scopes/{scope}/archive/sprint-NNN-slug.checkpoint.json |
Versioned lossless checkpoint (before/after state, write-only) |
.agents/kyro/scopes/{scope}/findings/NN-slug.md |
INIT analysis evidence (write-only) |
Boundaries
- INIT is read-only against source code until it writes Kyro artifacts.
- Execution may modify code/docs but must validate touched areas before marking a task done.
- STATUS is read-only unless explicitly mutating debt status.
- Recover preserves user archives and rebuilds
sprint.json from the best evidence.
1---2name: sprint-forge3description: Adaptive sprint workflow with a single source of truth per scope (sprint.json), lean context loading, formal debt tracking, and lossless sprint-close checkpoints.4license: Apache-2.05---67# Kyro Sprint Forge — Runtime Contract (v4)89One scope = one `sprint.json`. Agents read project state + its lean pack, then route on `nextAction`. No agent-facing files.1011## Step 0 — Startup (MANDATORY, before anything else)1213Run this before reading any other section and before writing any Kyro artifact. It is the same14handshake the orchestrator performs; it is repeated here in full because this skill is invocable on15its own (`kyro-ai:sprint-forge`), and on that path the orchestrator is never loaded.16171. **Resolve `{{KYRO_CLI}}`, once per session, before anything else below.** This token is normally18 substituted at install time by `npx kyro-ai install`/`sync`. If you are reading this from a channel19 that never ran that substitution (for example, installed as a Claude Code plugin from the20 marketplace), the literal 12 characters `{{KYRO_CLI}}` are still sitting in this file — resolve21 them yourself:22 - Run `kyro --version`. If it exits 0, `{{KYRO_CLI}}` means bare `kyro` for the rest of this session.23 - Else, check whether `~/.agents/kyro/current/dist/cli.js` exists. If it does, `{{KYRO_CLI}}` means24 `node ~/.agents/kyro/current/dist/cli.js`.25 - Else, Kyro's runtime is not installed on this machine. STOP — tell the user to run26 `npx kyro-ai@latest install --scope workspace --init-workspace --yes` once, then retry. This is27 not a license to hand-edit `sprint.json` or improvise; same rule as a missing verb in Step 4.28 Substitute the resolved value mentally everywhere `{{KYRO_CLI}}` appears in this or any other loaded29 skill asset for the rest of the session — never run the literal 12 characters `{{KYRO_CLI}}`.302. Read `.agents/kyro/project.json` + `.agents/kyro/local.json`. Unreadable/corrupt → stop here.313. Resolve the scope from user input, `local.json.activeScope`, or the only directory under32 `.agents/kyro/scopes/`. Ambiguous or none → ask the user before continuing.334. A scope that does not exist yet — neither in `project.json` nor on disk — is creation,34 not corruption: skip `repair` and `context-pack`, load `modes/INIT.md`, and never route it35 to recovery.365. Only for an existing scope, silently run `{{KYRO_CLI}} repair integrity prepare --kyro-scope37 <scope> --json` before `context-pack`. Never omit `--kyro-scope` here — it isolates this38 scope from unrelated drift. Findings/blockers → load `modes/recover.md` and stop. None → continue.396. **Capability handshake:** run `{{KYRO_CLI}} capabilities --json`. Unknown command, handshake40 failure, or a missing tool-owned verb (`record-evidence` included) means the runtime is unusable: ABORT without mutating Kyro41 state. Report the observed output of `{{KYRO_CLI}} --version` (or `not installed`) and the exact42 remedy `npx kyro-ai@latest sync --scope workspace --yes`. Never work around it by hand.437. Resolve routing with `{{KYRO_CLI}} context-pack --kyro-scope <scope> --json` (lean pack:44 `nextAction`, `nextTaskId`, `reviewPending`, `conventions`, budget). Do not open the full45 `sprint.json` to route. No `sprint.json` → INIT.468. Load the single mode named by the pack's `nextAction` (see Routing below).4748**If Step 0 did not complete, no Kyro artifact gets written.** A CLI you could not resolve, a failed49handshake, or a missing runtime are all STOP conditions — never a reason to hand-author `sprint.json`,50`project.json`, or `local.json`. Claude Code may add a `PreToolUse` defense, but that host-specific hook51is reinforcement only; the portable guarantee is this fail-closed CLI contract.5253## Core Invariants54551. `sprint.json` is the single source of truth; one file to update per action (see Read Path Contract).562. Route on the pack's `nextAction` (mirrors `handoff.nextAction`); never infer from file presence.573. Generate one sprint; never pre-generate.584. Tasks are self-contained: every task carries `description`, `files_to_touch`, `context`, `acceptance_criteria`.595. Debt never disappears; it only changes `status` (`open → in_progress → resolved | deferred`).606. Closing a sprint is owned by `{{KYRO_CLI}} close-sprint` — never null `activeSprint` by hand; it becomes one `ledger[]` entry.617. Findings/archives are write-only evidence; never re-read to route.628. **Admit unknowns, never guess.** Write `[NEEDS CLARIFICATION: <gap>]` and route to `clarify`. `{{KYRO_CLI}} doctor`/`analyze` FAIL while any marker remains.639. **Tool-owned verbs require a CLI that exposes them** (Startup handshake). A missing verb means the runtime is too old — abort; never fall back by hand.6465## Read Path Contract (context-pack first) — MANDATORY6667The full `sprint.json` is ~10–20k tokens. Never open it to route/execute/review or brief status — read the lean pack (`{{KYRO_CLI}} context-pack --kyro-scope <scope> --json`; `--task[ <id>]` for execute/review). Open the full file only when `plan_sprint`/`close_sprint`/status-full needs its planning or reporting context; agents never open it in order to write it.6869## Artifact Write Contract (MANDATORY)7071Every mutation of `sprint.json`, project state, checkpoints, or `archive/` MUST be owned by a CLI verb.72The CLI validates, locks, writes, and re-verifies the affected state internally. Agents must not73substitute an editor, patch, or ad-hoc script. If a required state-changing verb is absent, stop and74report the observed runtime version plus `npx kyro-ai@latest sync --scope workspace --yes`.7576## Tool-owned operations (use the CLI, do not hand-roll)7778Irreversible or schema-critical operations are CLI-owned, never hand-rolled:7980| Command | What it owns |81|---------|--------------|82| `{{KYRO_CLI}} close-sprint --kyro-scope <scope> --outcome <...>` | Lossless close: publishes the checkpoint, snapshots into `ledger[]`, reconciles state. |83| `{{KYRO_CLI}} doctor --artifacts --kyro-scope <scope>` | Validates shape drift, checkpoint state/digests/artifacts, legacy snapshots, and unresolved `[NEEDS CLARIFICATION]`. |84| `{{KYRO_CLI}} analyze --kyro-scope <scope>` | Semantic cross-check (clarity, coverage, deps, debt, principles); non-zero on CRITICAL/HIGH. Gate before close. |85| `{{KYRO_CLI}} repair --kyro-scope <scope>` | Normalizes `sprint.json` formatting. |86| `{{KYRO_CLI}} clarify --from <file> --kyro-scope <scope>` | Records one or more accepted clarification decisions and safely advances routing when clear. |87| `{{KYRO_CLI}} rule add ... [--global]` | Adds a scope rule; `--global` also writes `project.json` after approval. |88| `{{KYRO_CLI}} scope complete --kyro-scope <scope>` | Explicit finished-scope completion (Forge overlay). Not retirement. |8990Claude Code's `PreToolUse` hook adds host-specific defense against manual managed-state writes. Other91hosts may not expose an equivalent hook, so correctness never depends on it.9293## Routing (handoff.nextAction → mode)9495User intent to complete/close a finished scope is `{{KYRO_CLI}} scope complete` (Forge overlay), not a `nextAction` and not retirement. `done` means already terminal.9697| nextAction | Load |98|------------|------|99| `init` (no sprint.json) | `modes/INIT.md` + one `helpers/analysis/{workType}.md` |100| `clarify` | `modes/clarify.md` |101| `plan_sprint` | `modes/SPRINT.md`, `modes/plan-sprint.md`, then `helpers/sprint-generator.md` |102| `await_scope_completion` | Ask: complete the finished scope, or explicitly expand it. Complete → `scope complete`; expand → then route as `plan_sprint`. |103| `execute_task` | `modes/SPRINT.md`, `modes/execute-task.md` |104| `review_task` | `modes/SPRINT.md`, `modes/review-task.md`, `helpers/reviewer.md` |105| `close_sprint` | `modes/SPRINT.md`, `modes/close-sprint.md`, `helpers/debt-tracker.md` + `helpers/learner.md` as needed |106| `done` | Stop — already complete or retired. No work mode. |107| status report | `modes/STATUS.md` |108| inconsistent | `modes/recover.md` |109110Templates are loaded only immediately before writing their artifact.111112## Principles, conventions, ADRs113114- `principles[]` in `project.json`: authored gates; `non-negotiable` blocks.115- `conventions[]`: scope rules live in `sprint.json`; approved globals also live in `project.json`. Use `{{KYRO_CLI}} rule add [--global]`.116- `adrs[]` in `sprint.json`: durable scope architecture decisions with tradeoffs.117118## Artifact Contract119120| File | Role |121|------|------|122| `.agents/kyro/project.json` | Shared registry: `scopes[]`, optional `principles[]`, optional global `conventions[]` |123| `.agents/kyro/local.json` | Personal state: `activeScope`, installed adapters, execution preferences |124| `.agents/kyro/scopes/{scope}/sprint.json` | Single source of truth (see template) |125| `.agents/kyro/scopes/{scope}/archive/sprint-NNN-slug.md` | Human narrative at close (write-only) |126| `.agents/kyro/scopes/{scope}/archive/sprint-NNN-slug.json` | Verbatim snapshot of the closed sprint (write-only) |127| `.agents/kyro/scopes/{scope}/archive/sprint-NNN-slug.checkpoint.json` | Versioned lossless checkpoint (before/after state, write-only) |128| `.agents/kyro/scopes/{scope}/findings/NN-slug.md` | INIT analysis evidence (write-only) |129130## Boundaries131132- INIT is read-only against source code until it writes Kyro artifacts.133- Execution may modify code/docs but must validate touched areas before marking a task done.134- STATUS is read-only unless explicitly mutating debt status.135- Recover preserves user archives and rebuilds `sprint.json` from the best evidence.