Skip to content
Back to skills

Record Decision

ASecurity

Record a decision as an ADR, written from the one ADR template (standards/templates/adr.md) — a Markdown ADR for Garura''s own decisions (docs/adr/) or a decision.yaml record for a product decision — with what it overrides and what it changes in plain view: every older ADR it supersedes or amends (with the part), the files, rules, schemas, plays and agents it affects, its effect on agent intent (ICE), and whether it would change a person''s business intent (it never does: such a decision is s...

  • 3 stars
  • 0 votes
  • 0 copies
  • 0 views
  • Added November 7, 2026
researchpythongobashnodegit

Security analysis

A100/100

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

Scanned November 7, 2026

npx -y skills add intent-driven-ai/garura --skill record-decision --agent claude-code

Installs into .claude/skills of the current project.

Are you the author of Record Decision?

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

Security grade badge for Record Decision
[![Security: A — Skills Directory](https://www.skillsdirectory.com/api/skills/intent-driven-ai-record-decision/badge)](https://www.skillsdirectory.com/skills/intent-driven-ai-record-decision)

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: record-decision
position: both
description: 'Record a decision as an ADR, written from the one ADR template (standards/templates/adr.md) — a Markdown ADR for Garura''s own decisions (docs/adr/) or a decision.yaml record for a product decision — with what it overrides and what it changes in plain view: every older ADR it supersedes or amends (with the part), the files, rules, schemas, plays and agents it affects, its effect on agent intent (ICE), and whether it would change a person''s business intent (it never does: such a decision is shown to the person and not applied). Accepted only on a person''s word: run by hand, a pinned approval before anything is written as accepted; inside a loop, saved as proposed and accepted at the loop''s final review. Older ADRs gain only a forward pointer, written after acceptance; the ADR index is rebuilt. Also completes a proposed ADR later (/record-decision accept <file>). Run by hand it opens and lands its own change; handed a loop''s JSON contract it opens nothing of its own.'
user-invocable: true
---

# adr

Record a decision as an **ADR** — a decision record — from the one template in core memory,
`standards/templates/adr.md`. One set of core fields, two shapes:

- **Markdown** — Garura's own ADRs, `docs/adr/NNN-<slug>.md`.
- **YAML** — a product decision, a `decision.yaml` record (with the #632 fields) beside its node.

The play makes what a decision overrides and what it changes visible before anyone accepts it,
keeps every older ADR pointing forward, and never lets a decision change a person's business
intent. Only a person accepts an ADR.

**Pipeline position: both.** Run by hand, the D2 rule prepends `start-change` and appends
`commit-change → propose-change → check-change → merge-change`. **Inside a loop** the loop
hands it a JSON contract (`--contract`): it opens no issue or branch, skips the end sequence,
does not stop for approval, and saves the ADR as proposed for the loop's final review
(ADR 031).

**Two entry modes.** `/record-decision <brief>` records a new decision. `/record-decision accept <file>` completes a
proposed ADR later — the person accepts it, and its forward pointers and the index are written.

## Compiled From

This play was compiled from the adr ICE (`reference/ice.md`) by create-play (#632). Intent
defines constraints (C1–C11) and failure conditions (F1–F11); the expectation defines success
scenarios (S1–S6), a Done means (D1–D5, baked to `stop-condition.yaml`), and one recovery entry
per failure condition. To modify this play, update `reference/ice.md` and recompile with
edit-play.
Do NOT edit this file manually — it is a compiled artifact.

## Role

You are the orchestrator. You own the step order and the one human checkpoint. You hand the
judgment — what the decision supersedes or amends, what it affects, its ICE impact, its
business-intent check, and the draft — to the `adr-keeper` agent, which invokes the `author-decision`
skill, through a JSON contract over files on disk. You run the mechanical work through bundled
scripts: applying the person's word (`apply_adr.py`, over `adr.py`), the scope check and the
stop condition. You never accept an ADR yourself, and you never edit an older ADR except
through `apply_adr.py`'s forward pointer.

**Forbidden:** writing a record without a complete brief (C1); writing off the template (C2);
leaving an overridden ADR unnamed or without its part (C3); recording affects or ICE impact that
names nothing real (C4); applying a decision that would change a person's business intent (C5);
marking an ADR accepted without a person, writing a rejected one, or stopping for approval
inside a loop (C6); editing an older ADR beyond its pointer, or pointing before acceptance
(C7); leaving the index stale (C8); writing anything but the record, the pointers and the index
(C9); opening an issue or branch inside a loop (C10); closing COMPLETED with the done checks
unmet (C11).

**Agent boundaries:**

| Agent | Domain | Skill it invokes | Phases |
|-------|--------|------------------|--------|
| `adr-keeper` | Gather the context a decision needs (overlap candidates judged by reading them, affects, ICE impact, business-intent check), have the record drafted, check it (lint, guard) | `author-decision` | Draft |

`adr-keeper` is the single **domain agent**. The start and end sequence are injected sub-plays.
Everything else is a script.

## Pre-flight

| Check | Constraint | Action on Failure |
|-------|-----------|-------------------|
| Resolve config + `stm_base` (`.garura/core/config.yaml`) | — | Hard halt |
| A decision brief was given: what is decided, why now, the options, who decides, where (or, for `accept`, a proposed ADR file) | C1 | Ask for what is missing (gather, not a halt) |
| Loop contract: when `--contract <file>` is passed, it is valid JSON naming `loop_run_id` and `branch`, and the current branch equals that branch | C10 | Hard halt (REC10) |
| `template-manager` loads the ADR template (`standards/templates/adr.md`) into `<working>/context/templates/` | C2 | Hard halt on `template_missing` |
| **Clean record tree** — run by hand, checked at the end of Step 0 (the branch must exist first): `git status --porcelain -- docs/adr <product_base>product-os` is empty | C9 | Hard halt (REC9) |

Resolve the facts with the bundled resolver — not by inference:

```
git branch --show-current
git -c core.quotepath=off status --porcelain -uall > <working>/porcelain-before.txt
python3 scripts/preflight.py --play record-decision --config .garura/core/config.yaml \
    --branch "<current branch>" --porcelain-file <working>/porcelain-before.txt
python3 scripts/session_stamp.py --phase start \
    --marker "<working>/status/session-stamp-adr.json" \
    --cwd "$(pwd)" --branch "$(git branch --show-current)"
```

`in_loop` is true exactly when a valid `--contract` was passed; record it in
`<working>/run.json` with the contract's `loop_run_id` and `branch`. The working folder
`<working>` is `{stm_base}_adr/<run-ts>/` — fixed, not keyed on the issue, because run by hand
pre-flight runs before start-change has created it (as `/discover-intent` does).
`porcelain-before.txt` is captured again after Step 0 when run by hand, so the scope check sees
only this run's changes. Then snapshot the files already changed (inside a loop there will be
some), so a second change to one of them is caught:

```
python3 scripts/check_adr_scope.py --snapshot --before <working>/porcelain-before.txt \
    --out <working>/hashes-before.json
```

Then ask `template-manager` for the ADR template. The play hands its copy to `adr-keeper` in
the Step 2 contract (C2); `adr-keeper` does not fetch the template itself:

    { "task":    "load these templates into the run's short-term memory",
      "inputs":  { "issue": null, "templates": ["standards/templates/adr.md"] },
      "outputs": { "out_dir": "<working>/context/templates/",
                   "manifest": "<working>/context/templates/manifest-record-decision.json" },
      "task_id": "load-adr-template" }

`template_missing` is a hard halt: no record is written off the template.

## Task DAG

Create ALL tasks immediately after pre-flight, before any domain work. Inside a loop, T0 and
E1–E4 are created and marked skipped (`in_loop`), and T3 is skipped (no approval stop). In
`accept` mode, T1 and T2 are skipped.

```
[T0] start-change (injected — start; skipped in a loop)   blockedBy: []
[T1] Capture the brief                                    blockedBy: [T0]
[T2] Draft the ADR (adr-keeper → author-decision)              blockedBy: [T1]
[T3] Accept or reject (pinned by hand; none in a loop)   blockedBy: [T2]
[T4] Apply: write, accept, point forward, index           blockedBy: [T3]
[T5] Scope check                                          blockedBy: [T4]
[T6] Commit the record                                    blockedBy: [T5]
[E1] commit-change (injected — end; skipped in a loop)   blockedBy: [T6]
[E2] propose-change (injected — end; skipped in a loop)  blockedBy: [E1]
[E3] check-change (injected — end; skipped in a loop)   blockedBy: [E2]
[E4] merge-change (injected — end; skipped in a loop)    blockedBy: [E3]
[T7] Scenario Validation                                  blockedBy: [E4]
[T8] Close                                                blockedBy: [T7]
```

Mark each task in progress before its step and completed right after its eval passes. No
runtime reordering. On resume, skip completed and reset in-progress to pending.

## Workflow

### Phase: Start (injected — D2 position: start)

**Step 0 — start-change** · Owner: `start-change` (sub-play) · Depends on: pre-flight
*Skipped when `in_loop`.* Run the start-of-pipeline member as a sub-play with `parent_run_id`:
it resolves or creates the issue, cuts the branch off fresh main, and inits STM. Then check the
record tree is clean and capture the starting state on the new branch:

```
test -z "$(git status --porcelain -- docs/adr <product_base>product-os)"   # else hard halt (REC9)
git -c core.quotepath=off status --porcelain -uall > <working>/porcelain-before.txt
```

    { "play": "start-change", "parent_run_id": "<this run id>",
      "inputs": { "title": "adr: <the decision in a few words>" },
      "outputs": { "result": "{stm_base}_adr/<run-ts>/start-change.json" } }

### Phase: Brief

**Step 1 — Capture the brief** · Owner: play · Depends on: Step 0 · *skipped in `accept` mode*
Write the decision brief to `<working>/brief.md` with these headings, in the person's (or the
calling play's) words: `## Decision`, `## Why now`, `## Options considered` (each with why it
lost), `## Decided by`, `## Decided in`, and the shape (`markdown` for a framework decision,
`yaml` for a product decision, with its node). Ask the person for any heading that is empty —
plainly, one at a time; never fill one in.
**SE-1 (F1/C1):** `brief.md` has a non-empty Decision, Why now and Options considered; the
agent's contract (Step 2) does not read `failed` with `brief_incomplete`.

### Phase: Draft

**Step 2 — Draft the ADR** · Owner: `adr-keeper` · Depends on: Step 1

    { "task":    "gather the context for this decision and have it drafted as an ADR",
      "inputs":  { "brief": "<working>/brief.md", "shape": "markdown | yaml",
                   "adr_dir": "docs/adr (markdown) | <the node's decisions folder> (yaml)",
                   "intents_dir": "<product_base>product-os/intents | null",
                   "template": "<working>/context/templates/standards/templates/adr.md",
                   "script": "<skill-dir>/scripts/adr.py" },
      "outputs": { "context": "<working>/adr-context.yaml",
                   "draft": "<working>/adr-draft.md | <working>/adr-draft.yaml",
                   "check_report": "<working>/adr-check.json" },
      "task_id": "draft-adr" }

The agent finds the next number (or id), lists the overlap candidates and reads each to judge
superseded / amended (with the part) / not affected, names what the decision affects and its
ICE impact with real paths, sets the business-intent check (`none`, `kind` or `instance`), has
`author-decision` draft the record as proposed, and checks it (lint and guard). It returns only its
contract. `blocked` with `needs_person` means the decision would change a person's business
intent, or the brief is incomplete — go to the person. **This stop applies in both modes:** run
by hand, Step 3 shows the person; inside a loop, it is a new question, and a new question
stops the loop (ADR 029 §2) — the ADR is never applied to the intent either way.
**SE-2 (F2/C2):** `adr-check.json` reports the lint clean for the draft, and the contract's
`template` is the copy `template-manager` wrote (its manifest names the source).
**SE-3 (F3/C3):** `adr-context.yaml` lists every older ADR it supersedes or amends, each with a
part; every ADR named in the draft's Supersedes/Amends is in that list and vice versa.
**SE-4 (F4/C4):** the draft's Affects and ICE impact are non-empty, and every path in Affects
exists in the repository.

### Phase: Accept (pinned human checkpoint, run by hand)

**Step 3 — Accept or reject** · Owner: play · Depends on: Step 2 · Checkpoint (class:
one-way-door, pinned) · **run by hand: never skipped by config or policy. Inside a loop:
skipped — no approval stop.**
*Inside a loop (`in_loop`), skip this step: the ADR is saved as proposed (Step 4 with
`--proposed`), and the person accepts it at the loop's final review with `/record-decision accept <file>`.*
If the business-intent check is `instance` (or the guard exits 4), stop here — run by hand or
inside a loop: show the person
which business intent the decision would change and why, and close HALTED with
`exit_reason: business_intent` — the person changes the brief or ends it (S2).
Otherwise show the draft exactly as it will read, the older ADRs it supersedes or amends (with
the part), what it affects, its ICE impact and its business-intent check, and ask the person to
type one of: **accept**, **reject**, or **change: <what>**.
- **accept** → write `<working>/decision.yaml`:
  `decision: { verdict: accept, by: person, accepted_by: <git user>, reply: <their exact words> }`.
- **reject** → write the same with `verdict: reject`; Step 4 writes nothing; close HALTED with
  `exit_reason: rejected` (S5).
- **change** → add the change to the brief and go back to Step 2.
**SE-5 (F5/C5):** no record was applied while the business-intent check read `instance` or the
guard exited 4.
**SE-6 (F6/C6):** run by hand, `decision.yaml` reads `by: person` with the person's own
non-empty reply, written only after the draft was shown; inside a loop, no `decision.yaml`
exists and the play did not wait.

### Phase: Apply

**Step 4 — Apply: write, accept, point forward, index** · Owner: play (script) · Depends on:
Step 3

```
python3 scripts/apply_adr.py --draft <working>/adr-draft.<md|yaml> \
    --context <working>/adr-context.yaml --target <docs/adr/NNN-slug.md | <node>/decisions/<id>.yaml> \
    ( --decision <working>/decision.yaml | --proposed ) \
    --adr-dir <docs/adr | the node's decisions folder> [--index docs/adr/_index.md] \
    [--intents-dir <product_base>product-os/intents] --date <date> --working <working>
```

In `accept` mode: `python3 scripts/apply_adr.py --accept-existing <file> --by "<git user>"
--date <date> [--adr-dir docs/adr] [--index docs/adr/_index.md] --working <working>`, after the
person typed **accept** on the proposed ADR shown to them.

Every check runs before the first write, so a stop writes nothing: the draft must still be
Proposed, its number must match its file name and be unused, and (when accepting now) every
older ADR it names must exist. It lints, runs the business-intent guard (exit 4 stops before
writing), writes nothing on a reject (exit 5), writes the record at the target (never over an existing file), and — only on
accept — marks it accepted with the person's name, writes each forward pointer on the older
ADRs (the only edit they get), and rebuilds the index. Inside a loop it saves the record as
proposed and leaves the pointers for acceptance. It writes `adr-manifest.json`.
**SE-7 (F7/C7):** every older ADR changed in this run differs from its base only on its Status
line (Markdown) or its `superseded_by` / `amended_by` / `status` fields (YAML); no pointer was
written while the record was proposed (`pointers_deferred: true`).
**SE-8 (F8/C8):** for an accepted Markdown ADR, `adr-manifest.json` reads `index_ok: true`, and
the index has a row for every ADR file in the folder.

**Step 5 — Scope check** · Owner: play (script) · Depends on: Step 4

```
git -c core.quotepath=off status --porcelain -uall > <working>/porcelain-after.txt
python3 scripts/check_adr_scope.py --before <working>/porcelain-before.txt \
    --before-hashes <working>/hashes-before.json \
    --after <working>/porcelain-after.txt --allow <the target> \
    --allow <each older ADR file it pointed> [--allow docs/adr/_index.md] \
    --out <working>/guard-report.json
```

**SE-9 (F9/C9):** `guard-report.json` reads `ok: true` — only the record, its pointers, the
index and the run's own records changed.

**Step 6 — Commit the record** · Owner: play · Depends on: Step 5

```
git add -- <the target> <each older ADR file it pointed> [docs/adr/_index.md] <working>
git commit -m "docs(adr): ADR <NNN or id> — <title> (#<issue>)"
```

### Phase: End sequence (injected — D2 position: end)

*Skipped when `in_loop` — the loop lands its own change.* After the commit, the D2 rule
injects the close sequence, each a sub-play with `parent_run_id`:

**Step E1 — commit-change** · blockedBy: Step 6

    { "play": "commit-change", "parent_run_id": "<this run id>", "inputs": {}, "outputs": { "result": "{stm_base}_adr/<run-ts>/commit-change.json" } }

**Step E2 — propose-change** · blockedBy: E1

    { "play": "propose-change", "parent_run_id": "<this run id>", "inputs": {}, "outputs": { "result": "{stm_base}_adr/<run-ts>/propose-change.json" } }

**Step E3 — check-change** · blockedBy: E2

    { "play": "check-change", "parent_run_id": "<this run id>", "inputs": {}, "outputs": { "result": "{stm_base}_adr/<run-ts>/check-change.json" } }

**Step E4 — merge-change** · blockedBy: E3

    { "play": "merge-change", "parent_run_id": "<this run id>", "inputs": {}, "outputs": { "result": "{stm_base}_adr/<run-ts>/merge-change.json" } }

Each end member owns its own evals; a review reject stops the chain before merge; the land on
main keeps its pinned human approval.
**SE-10 (F10/C10):** by hand, `start-change` ran at the head and `merge-change.json` reports the
PR merged; inside a loop, `run.json` reads `in_loop: true`, neither `start-change` nor any end
member ran, and the commit is on the contract's branch.

### Phase: Scenario Validation

**Step 7 — Scenario evals** · Owner: play · Depends on: the end sequence (or Step 6 in a loop)
- **SCE-1 (S1 — framework author, amends older ADRs):** `adr-manifest.json` reads
  `decided: true`, `status: accepted`, `lint_ok: true`, `linked: true`; each older ADR named in
  the new one's Supersedes/Amends line carries a pointer to it on its Status line and is
  otherwise unchanged.
- **SCE-2 (S2 — framework author, would change a business intent):** the guard exited 4; no new
  ADR file exists in the ADR folder; the run closed HALTED with `exit_reason: business_intent`.
- **SCE-3 (S3 — product owner, product decision):** the record passes the lint, reads
  `status: accepted` with `metadata.accepted_by`, and names its node.
- **SCE-4 (S4 — Discovery loop):** `run.json` reads `in_loop: true`; `adr-manifest.json` reads
  `status: proposed` and `pointers_deferred: true`; no older ADR changed; no `decision.yaml`.
- **SCE-5 (S5 — framework author, rejects):** `adr-manifest.json` reads `rejected: true`; no new
  ADR file, no older ADR changed, the index unchanged; the run closed HALTED with
  `exit_reason: rejected`.
- **SCE-6 (S6 — framework author, the index):** the index has a row for the new number reading
  Accepted, and a row for every ADR file in the folder.

### Phase: Evidence & Close

**Step 8 — Close** · Owner: play · Depends on: Step 7
Run the Standard Play Close.
**SE-11 (F11/C11):** the close is stop-condition gated — `check_stop_condition.py` over the
baked `stop-condition.yaml` (D1 record saved; D2 decided — accepted by a person, or proposed in
a loop; D3 lint clean; D4 linked or pointers deferred; D5 scope ok) reads **held** before any
COMPLETED close.

```bash
# --- Standard Play Close (shared; see ../_shared/play-close.md) ---
# Run the close in ../_shared/play-close.md. Its Step L loads the templates through
# template-manager and sets ts and evidence_dest; then run this play's own lines below;
# then Steps C0-C2.
#   evidence_base, slug (project-scoped play):
#     evidence_base="${stm_base}${issue}/evidence/adr/"   ; slug="#${issue}"
# Session identity stamp (#463) — close phase; start phase ran at pre-flight
session_stamp=$(python3 scripts/session_stamp.py --phase close \
    --marker "<working>/status/session-stamp-adr.json")
# Stop-condition gate (#464) — Step C0: this play carries a baked manifest, so the
# gate is LIVE. Evaluate the Done means here as the close's authoritative input.
python3 scripts/check_stop_condition.py \
    --manifest "<play-dir>/stop-condition.yaml" \
    --base "<working>/" \
    --out "<working>/status/stop-condition-adr.yaml"
sc_exit=$?   # 0 held · 1 unmet · 2 error
```

**Step C0 — bind the verdict.** `sc_exit == 0` (held) permits `status: COMPLETED`. Anything
else closes `HALTED` with `exit_reason: stop_condition_unmet` and the evidence's Stop Condition
section names every unmet clause. A run the guard stopped closes HALTED with
`exit_reason: business_intent`; a run the person rejected closes HALTED with
`exit_reason: rejected`. An unevaluable verdict is never a pass.

**Step C1 — Write evidence file.** Gated by the resolved `evidence.record` flag (global +
per-play `evidence.plays.adr`; first match wins, absent ⇒ record). When false, skip the write
and record `evidence skipped (record=false)` in the report's pointer line. Otherwise fill the
`evidence-file.md` slots (play `adr`, run_id `adr-${ts}`, issue, started_at/completed_at,
status per C0, exit_reason; artifacts produced: the record, the older ADRs pointed,
the index, `brief.md`, `adr-context.yaml`, `adr-check.json`, `decision.yaml`,
`adr-manifest.json`, `guard-report.json`, the commit sha; `in_loop`; step and scenario eval
results SE-1…SE-11 / SCE-1…SCE-6; the checkpoint decision from Step 3 with the person's exact
reply; the session identity stamp fields from $session_stamp (#463): session_id, ledger_file,
ledger_start_offset, ledger_end_offset (null when unresolved — never blocks the close); and
stop_condition per C0) and write to `$evidence_dest`. Do NOT hand-author the body.

**Step C2 — Render delivery report.** Also render the **Next** line: resolve this play in
the Next-line map (`$next_map`, from `template-manager`) and emit `**Next:** /<command> — <why>.` (omitted when the mapped command is null), per
`play-close.md`. Fill the `delivery-report.md` slots and output the report:
`## adr Delivered — ADR <NNN or id>`, the Run Summary table, the Pipeline Steps table from the
task DAG, the Artifacts Produced table (the record, the pointers, the index), Next Steps (for a
proposed ADR: accept it at the loop's final review with `/record-decision accept <file>`), and a pointer
to `$evidence_dest`. Always emitted; never gated.

```bash
# --- end Standard Play Close ---
```

## Scenario Validation

| Scenario | Persona | Eval |
|----------|---------|------|
| S1 — a new Garura ADR amending older ones | framework author | SCE-1 |
| S2 — would change a business intent | framework author | SCE-2 |
| S3 — a product decision | product owner | SCE-3 |
| S4 — inside a loop | Discovery loop | SCE-4 |
| S5 — rejected | framework author | SCE-5 |
| S6 — the index | framework author | SCE-6 |

## Recovery

| For | Trigger | Direction | Handoff |
|-----|---------|-----------|---------|
| F1 | no brief, or it lacks the decision, the reason or the options | ask the person (or the calling play) for what is missing; never fill it in | human |
| F2 | the record fails the template's structural check, or the template did not come through the play's contract | load the template through `template-manager`, hand its copy to `adr-keeper`, and re-draft against it with the check's report | autonomous |
| F3 | an overridden ADR is unnamed or has no part | re-read the overlap candidates, name each with the part, re-draft | autonomous |
| F4 | affects or ICE impact missing or naming things that do not exist | search the repository for the real names and re-draft | autonomous |
| F5 | the decision would change a person's business intent | stop before writing; show the person which intent and why; the person changes the brief or ends the run | human |
| F6 | accepted without a person, a rejected ADR written, or a loop waited | reset to proposed (or remove the rejected file); by hand, present and record only the person's word; in a loop, save as proposed and move on | human |
| F7 | an older ADR edited beyond its pointer, or a pointer written early | restore the older ADR from git and re-write only the pointer, after acceptance | autonomous |
| F8 | the index is stale | rebuild it from the ADR folder (`adr.py index`) | autonomous |
| F9 | a path outside the record, the pointers and the index changed | restore the offending paths from git, after a person confirms | human |
| F10 | by hand without opening or landing the change, or an issue or branch opened inside a loop | by hand, run the missing opening or end step; in a loop, close the stray issue and branch and continue on the loop's branch | human |
| F11 | the close would read COMPLETED with the done checks unmet | close HALTED with the unmet checks named; fix and re-evaluate | autonomous |

## Pause and Resume

Steps run top to bottom. On entry, resolve config and the in-progress run from the status
marker, skip completed steps, reset any in-progress step to pending, and continue. A resume
after Step 2 reuses the draft and its context; a resume never re-asks the person once
`decision.yaml` exists. Inside a loop, a resume keeps `in_loop` from `run.json`.

## Compilation Metadata

| Field | Value |
|-------|-------|
| fingerprint | sha256:cd7ff7c1e9e7c56d850fc7d371d339c1a67fbfb72d75a8218fdba2239ec7f5e3 (of `reference/ice.md`) |
| compiled_by | create-play (#632) |
| pipeline_position | both (start-change head; commit → propose → review → merge close; both skipped inside a loop) |
| position_exception | record-writing both play — writes the ADR on its started branch (or the loop's) and commits it (Step 6) BEFORE the injected end sequence lands it |
| workflow_structure | B with one human checkpoint — pinned when run by hand (the person accepts or rejects), none inside a loop (saved proposed for the loop's final review); stop-condition gated close |
| stop_condition | stop-condition.yaml (D1–D5), gate live at Step C0 |
| domain_agents | 1 (adr-keeper) |
| utility_agents | 1 (template-manager — the ADR template at pre-flight, and the close's templates) |
| skills_used | author-decision |
| scripts | 6 (preflight.py, session_stamp.py, check_stop_condition.py, adr.py — copied from the author-decision skill, apply_adr.py, check_adr_scope.py) + test_apply_adr.py |
| step_evals | 11 (SE-1…SE-11) |
| scenario_evals | 6 (SCE-1…SCE-6) |
| recovery_entries | 11 (one per failure condition; 6 autonomous / 5 human) |

Files in this skill

  • SKILL.md26.2 KB
  • reference/ice.md10.4 KB
  • scripts/adr.py21.9 KB
  • scripts/apply_adr.py14.9 KB
  • scripts/check_adr_scope.py4 KB
  • scripts/check_stop_condition.py5 KB
  • scripts/preflight.py7 KB
  • scripts/session_stamp.py4.8 KB
  • scripts/test_apply_adr.py18.6 KB
  • stop-condition.yaml1.2 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.