Write a SLICE''s quality lens as a grounding doc (quality.md) — a short statement of what "good" means for the slice plus a table of checkable gates (dimension / bar / how checked), drawn from the profile''s NFR gates that apply and the slice''s functionalities'' rules, never invented. The MIDDLE of the NON-FUNCTIONAL realize pipe (architecture → quality → run), run on a shaped slice. Reads the hub from the spine (functionality grounding + profile), never another lens. Writes the slice''s qua...
Scanned 9/10/2026
Install to Claude Code
npx -y skills add kapilvirenahuja/garura --skill quality --agent claude-codeInstalls into .claude/skills of the current project.
Are you the author of Quality?
Add the live security badge to your README — it updates automatically with every re-scan.
[](https://www.skillsdirectory.com/skills/kapilvirenahuja-quality)More formats (shields.io, HTML) on the badges page.
---
name: quality
position: none
description: 'Write a SLICE''s quality lens as a grounding doc (quality.md) — a short statement of what "good" means for the slice plus a table of checkable gates (dimension / bar / how checked), drawn from the profile''s NFR gates that apply and the slice''s functionalities'' rules, never invented. The MIDDLE of the NON-FUNCTIONAL realize pipe (architecture → quality → run), run on a shaped slice. Reads the hub from the spine (functionality grounding + profile), never another lens. Writes the slice''s quality lens directly, in place on the live model.'
user-invocable: true
---
# quality
Write a shaped slice's **quality lens** as the grounding doc `quality.md`: what "good" means for
this slice, and the checkable gates it must clear. The gates are drawn from the product profile's
NFR gates that apply to the slice and from the slice's functionalities' own rules, made checkable —
never invented. /quality reads the slice's **hub** — its functionalities' grounding docs plus the
profile (both from the spine) — and never another realize lens.
**Pipeline position: none.** /quality is the MIDDLE of the non-functional realize pipe (architecture
→ quality → run): it runs on the branch /arch already started, injects no `start-change` head and no
close sequence, stops when its work is done, and leaves the branch for /run. The close belongs to
/run. It writes the persistent product model **directly, in place** on the already-started branch
(the slice's quality lens) — there is no draft copy and no apply/promote step; review is the branch
git diff and the pipeline's end PR. (#437, #500, ADR 026)
**Write discipline (ADR 026, `standards/rules/direct-model-write.md`).** The LLM authoring skill
writes ONLY the per-node lens docs (`quality.md` and its machine sibling `quality-gates.yaml`)
straight to the live model; every shared-file mutation (the slice's decision records) is done by the
deterministic keyed persist script, in place, keyed to the target slice so it cannot touch another
slice's decisions. The model tree is asserted clean at entry (F13) and the play commits its own model
delta at close (C12), so the working-tree diff vs HEAD is exactly this run's delta. Containment is a
post-write scoped guard (`scoped_write_guard.py`), not a draft.
## Compiled From
This play was compiled from the quality ICE (`reference/ice.md`) by play-editor (#466 Batch C;
#467 Batch B — the checkpoint upgraded to a conditional learned gate, see
`standards/rules/gate-config.md`; #500 — migrated to direct-model-write per ADR 026 and
`standards/rules/direct-model-write.md`). Intent defines constraints (C1–C12) and failure conditions
(F1–F13); the expectation defines success scenarios (S1–S6), a Done means (D1–D4, baked to
`stop-condition.yaml`), and one recovery entry per failure condition. To modify this play, update
`reference/ice.md` and recompile with play-editor. Do NOT edit this file manually.
## Role
You are the orchestrator. You own the workflow and step order. You delegate the domain work —
authoring the quality lens grounding doc — to the `product-os-keeper` agent via a JSON contract over
files on disk, and you run the mechanical checks (readiness/hub resolution, the shape linter, the
content-quality eval, grounding + coverage, the keyed in-place persist, and the post-write scoped
guard) through bundled scripts and an isolated judge. You never write the lens yourself, and you
never COMMIT before the single checkpoint's gate resolves (C10) — a typed approval, a recorded config
skip, or a recorded policy auto-pass.
**Forbidden:** hand-writing the lens or a decision; writing anything other than this slice's
`quality.md`, its machine sibling `quality-gates.yaml`, and a decision (C2); reading or grounding on
another realize lens (C7); inventing a gate with no profile gate or functionality rule behind it
(C5); writing a decision by any route other than `scripts/persist_quality.py`; committing before the
checkpoint gate resolves; running against a dirty product-os tree (C12/F13); closing COMPLETED
without the stop-condition verdict held (C11).
**Agent boundaries:**
| Agent | Domain | Skill it invokes | Phases |
|-------|--------|------------------|--------|
| `product-os-keeper` | Author the slice's quality lens (intent + gates) from the hub — the profile's NFR gates that apply + the functionalities' rules — writing the lens docs in place on the live model | `author-quality-lens` | Author |
`product-os-keeper` is the single domain agent this play uses (1 of the ≤5 budget). The
content-quality judge always runs as an isolated, clean-context sub-agent (optionally on a configured
different model) — never the orchestrator's own context.
## Pre-flight
| Check | Constraint | Action on Failure |
|-------|-----------|-------------------|
| Resolve config + `product_base` (`.garura/core/config.yaml`) | — | Hard halt |
| Resolve `grounding-eval.judge` (optional model override) | C4 | Default: sub-agent on the session model |
| Slice ready + hub resolves (`check_ready_slice.py`) | C1 | Hard halt (REC1) |
| **Clean model tree** — `git status --porcelain -- <product_base>product-os` is empty | C12/F13 | Hard halt (REC13) |
**Clean-tree assertion (C12/F13, ADR 026).** Before any work, assert the product-os tree carries no
uncommitted edits — `HEAD` is only a correct base for the scoped guard and the change-shape if the
tree is clean at entry:
```
test -z "$(git status --porcelain -- <product_base>product-os)" || { echo "HALT: dirty product-os tree (REC13)"; exit 1; }
```
If dirty, halt at pre-flight and ask for a clean model tree (commit or revert the pending model
edits, or run the prior pipeline play /arch to its close) before /quality proceeds.
Resolve the pre-flight facts mechanically with the bundled resolver:
```
python3 scripts/preflight.py --play quality --config .garura/core/config.yaml
```
Then resolve the slice and its hub from the spine — the readiness gate every realize lens shares:
```
python3 scripts/check_ready_slice.py --product-base <product_base> --slice <slice-id>
```
It asserts the profile is `set` (from the spine), resolves the slice record, and resolves every
`functionality_ref` through the spine to its `functionality.md` grounding doc — the hub. If the slice
is absent, a functionality does not resolve, or the profile is not firmed, hard halt (C1/REC1).
The run's working root is `<working>` = `{stm_base}_realize/quality/` — the manifest
(`quality-manifest.yaml`), the change-shape, the persist record (`persist-manifest.json`), the
captured scoped-guard report (`guard-report.json`), and status markers all live under it. These are
STM, non-model artifacts (ADR 008/017) — the model itself is written IN PLACE under
`<product_base>product-os/`, never into `<working>`. The stop-condition gate evaluates against
`<working>`.
Right after the resolver, record the session identity stamp's start marker (#463 — soft-fail, never
a halt):
```
python3 scripts/session_stamp.py --phase start \
--marker "{stm_base}_realize/quality/status/session-stamp-quality.json" \
--cwd "$(pwd)" --branch "$(git branch --show-current)"
```
**Resume check:** if `{stm_base}_realize/quality/status/<slice-id>.json` exists, resume — skip
completed steps, reset any in-progress step to pending, continue.
## Task DAG
Create ALL tasks immediately after resolving config — before any domain work.
Write-then-review (ADR 026): the FULL model delta — the LLM lens docs AND the keyed persist's
decision writes — is written to the live model BEFORE the checkpoint, so the guard, the change-shape,
and the human all see the real delta. Nothing is COMMITTED before the gate resolves; cancel reverts
the uncommitted writes.
```
[T1] Author the lens (docs to live) blockedBy: []
[T2] Validate the live docs blockedBy: [T1]
[T3] Persist (keyed, in place — decisions) blockedBy: [T2]
[T4] Guard the full delta + classify the shape blockedBy: [T3]
[T5] Checkpoint (approval over the full git diff) blockedBy: [T4]
[T6] Commit the model delta blockedBy: [T5]
[T7] Scenario Validation blockedBy: [T6]
[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: Author
**Step 1 — Author the lens (docs to live)** · Owner: `product-os-keeper` · Depends on: pre-flight
The agent invokes `author-quality-lens` to write the slice's `quality.md` (the intent + the gates,
per the Quality lens template) AND its machine sibling `lens/quality-gates.yaml` (#462 — one binding
card per Gates-table row) **straight to the live model** from the hub (the functionality grounding
docs + the profile's NFR gates), and to emit a `quality-manifest.yaml` (the grounding map + any
material choice as structured data). Per ADR 026 the skill writes the per-node lens docs in place and
emits any decision as manifest data (it never writes `_spine.yaml`, `profile.yaml`, or a decision):
{
"task": "author the slice's quality lens (intent + checkable gates) from its hub, writing quality.md + quality-gates.yaml in place on the live model; ground every gate in a profile NFR gate that applies or a functionality rule; emit the grounding map + any material choice into the manifest",
"inputs": { "slice_ref": "<domain>/<slice>",
"slice_file": "<slice record>",
"functionality_groundings": "<from check_ready_slice>",
"profile": "<spine profile>", "product_base": "<product_base>",
"lens_rel": "product-os/<domain>/slices/<slice>/lens/quality.md" },
"outputs": { "manifest": "<working>/quality-manifest.yaml" }
}
The skill reads the hub read-only and writes the two lens docs IN PLACE under
`<product_base>product-os/`, plus `quality-manifest.yaml` under `<working>` (STM). It writes NO shared
model file.
**SE-1 (F1/C1):** `check_ready_slice.py` passed at pre-flight — the slice is ready and its hub
resolves; an unready slice halted (REC1).
**SE-12 (F13/C12):** the product-os tree was clean at entry — the pre-flight assertion
(`git status --porcelain -- <product_base>product-os` empty) passed on a fresh start; a dirty model
tree halted at pre-flight (REC13), so the change-shape and the scoped guard reflect only this run's
delta.
### Phase: Validate
**Step 2 — Validate the live docs** · Owner: play · Depends on: Step 1
Run the guards over the LIVE lens before the checkpoint — shape first, then content, then grounding.
Under direct-model-write the docs are already written in place, so the linter and the content eval run
over the live paths:
```
python3 scripts/lint_grounding.py --doc <product_base>/product-os/<domain>/slices/<slice>/lens/quality.md
python3 scripts/validate_quality.py --manifest <working>/quality-manifest.yaml --slice-file <product_base>/<slice_file>
```
Then run the **content-quality eval** over `quality.md`: spawn an isolated, clean-context sub-agent
handed the judge prompt (`standards/rules/grounding-eval.md`), the live doc, and the Quality lens
per-section guidance, on the model from `grounding-eval.judge.model`. Gate the verdict:
```
python3 scripts/grounding_gate.py --verdict <verdict.json>
```
**SE-2 (F3/C3):** `lint_grounding.py` exits 0 — `quality.md` conforms to the Quality lens template
(Intent, Gates), no missing/extra/empty section.
**SE-3 (F4/C4):** the content-quality eval gate (`grounding_gate.py`) passes — `quality.md` is
self-explaining and clears the stranger test.
**SE-4 (F5/C5):** `validate_quality.py` — every gate grounds in a profile NFR gate that applies or a
functionality rule; any material choice names a decision (a manifest choice) that resolves.
**SE-5 (F6/C6):** `validate_quality.py` — the gates consider every functionality the slice bundles
(coverage).
**SE-6 (F7/C7):** `validate_quality.py` — the gates ground on no other realize lens.
**SE-7 (F8/C8):** every gate is a checkable bar — the Gates table carries a bar and a check; a bare
adjective with no value/standard/check fails the content eval and the linter's substance floor.
On any GAP, apply the matching recovery (REC3–REC8) and re-run before the persist/checkpoint.
### Phase: Persist (write the full delta first, ADR 026 write-then-review)
**Step 3 — Persist (keyed, in place)** · Owner: play · Depends on: Step 2
Write-then-review (ADR 026): the FULL model delta is written to the live model BEFORE the checkpoint,
so the guard, the change-shape, and the human all see the real delta. The lens docs are already on the
live model (Step 1). `persist_quality.py` now writes the SHARED files in place, keyed to
`--slice-ref`: it reads the manifest and writes one decision record per material choice, skip-if-exists
(an accepted decision is never edited in place), and it REFUSES any choice whose `slice_ref` is not the
target slice (the node-level containment the file-level guard cannot provide). It also stamps the
machine applied fields the close reads — `lens_applied`/`gates_machine_applied` — by checking the live
lens the author wrote is present under the slice. No draft, no doc copy. Nothing is COMMITTED yet —
the commit (Step 6) happens only after the gate approves; on cancel the whole delta is reverted
(Step 5):
```
python3 scripts/persist_quality.py --manifest <working>/quality-manifest.yaml \
--product-base <product_base> --slice-ref <domain>/<slice> \
--lens-rel product-os/<domain>/slices/<slice>/lens/quality.md \
--decided-by /quality --date "$(date -u +%Y-%m-%d)" \
--out-manifest <working>/persist-manifest.json
```
The persist manifest carries `ok`, the decisions written, and the machine applied fields the close's
stop-condition gate reads (#464): `lens_applied: true` (quality.md landed) and
`gates_machine_applied: true` (the machine sibling landed).
### Phase: Guard + Classify (over the full delta)
**Step 4 — Guard the full delta + classify the shape** · Owner: play · Depends on: Step 3
**The run's write scope (the per-play guard policy, ADR 026).** The old `apply_quality.py` fixed
allowlist encoded quality's write scope by construction; under direct-model-write that same scope is
the `scoped_write_guard.py` policy — resolve `<slice-dir>` as the target slice's directory
(`<domain>/slices/<slice>`):
--allow 'product-os/<slice-dir>/lens/quality.md' # the re-derived lens doc (overwrite)
--allow 'product-os/<slice-dir>/lens/quality-gates.yaml' # the re-derived machine sibling (overwrite)
--add-only 'product-os/<slice-dir>/decisions/*.yaml' # new decisions (added, never modified — superseded not edited)
**Guard ONCE over the full delta (C9/C10).** After ALL writes (the LLM lens docs from Step 1 and the
keyed persist's decision writes from Step 3), run the scoped guard a single time over the whole delta.
Capture its report — its `ok` field is the stop condition's D4 input:
```
python3 scripts/scoped_write_guard.py --product-base <product_base> --base-ref HEAD \
--allow 'product-os/<slice-dir>/lens/quality.md' \
--allow 'product-os/<slice-dir>/lens/quality-gates.yaml' \
--add-only 'product-os/<slice-dir>/decisions/*.yaml' \
--out <working>/guard-report.json
```
If the guard exits non-zero, re-run with `--restore` to revert the offending paths, apply REC9 (a
non-lens/non-decision file changed, or an accepted decision edited in place), and re-run before the
checkpoint.
**Classify the full working-tree delta (C10).** Classify the model tree's diff vs HEAD — now the FULL
delta (lens docs + machine sibling + any decision), per ADR 026 write-then-review (no draft dir), so a
material re-derive yields a materially different shape key from a prose edit:
```
python3 scripts/classify_change.py --play quality \
--product-base <product_base> --base-ref HEAD --out <working>/shape.json
```
**SE-8 (F2/F9/C2/C9):** the scoped-write guard report reads `ok: true` — the only model paths changed
are this slice's `lens/quality.md` and `lens/quality-gates.yaml` (re-derive) and any new decision
(added, never edited in place); the spine, the profile, the slice record, and the other lenses are
byte-identical. Nothing outside the allowlist was written.
### Phase: Checkpoint (conditional gate, C10)
**Step 5 — Human review (class: standard, conditional)** · Owner: play · Depends on: Step 4
**This is the single checkpoint (C10) — the agent never skips it on its own judgment.** It is a
**conditional gate** per `standards/rules/gate-config.md` (#467 — /quality is one of the eleven
conditional document plays). Resolve, first match wins: pinned (n/a here) → `gates.plays.quality` →
the learned policy → `gates.classes.standard` → `gates.default` (absent ⇒ on). For the policy lookup,
use the shape key classified in Step 4.
Look the shape key up in the config-resolved learned policy (`gates.conditional.policy` →
`gate-policy.yaml`). **Shape in `auto:` AND not in `never_auto:` AND no blocking finding (a Step 2
lint gap or content-eval fail, or a Step 4 guard violation) → auto-pass:** record `gate auto-passed by
learned policy (shape: <shape-key>, policy v<version>)` as a Checkpoint Decisions row plus the
working-tree diff summary (the axis counts from `shape.json`), append the ledger line, and proceed to
Step 6 (commit) — no wait:
```
python3 scripts/gate_eval.py append --ledger <gates.conditional.ledger> --play quality \
--issue <issue> --shape <shape-key> --predicted auto --human auto_pass \
--ts <run ts> --policy-version <policy version>
```
Anything else resolves the gate on (an explicit `gates.plays.quality: off` instead records
`gate skipped by config (<resolution path>)` as a Checkpoint Decisions row and proceeds on the
validated delta). When on, present the proposed intent and the gates **inline over the real model git
diff**, plus any decision, and wait for the typed response. Approve → continue to Step 6 (commit).
**Cancel → revert the working tree (ADR 026 step 6):** the full delta is already on disk, so run the
guard with `--restore` and an EMPTY allow set to `git restore` the modified model paths and
`git clean`/remove the new ones (byte-clean back to HEAD), then halt — nothing was committed, and
cancel means "revert what was written":
```
python3 scripts/scoped_write_guard.py --product-base <product_base> --base-ref HEAD \
--restore --out <working>/guard-report.json # empty --allow ⇒ every model path reverted
```
Then append the crossing's live-eval ledger line with the human's real action:
```
python3 scripts/gate_eval.py append --ledger <gates.conditional.ledger> --play quality \
--issue <issue> --shape <shape-key> --predicted gate \
--human approved_clean|approved_edited|rejected --ts <run ts>
```
`<issue>` is the slice-realize issue the run's branch carries (opened by /arch's start-change).
`<gates.conditional.ledger>` / `<gates.conditional.policy>` resolve from config `gates.conditional`;
`<policy version>` is the policy file's `version:` field. `<run ts>` is the run's own UTC timestamp,
derived the same way the close derives `ts` (`date -u`), passed by the orchestrator — the script never
reads the wall clock. EVERY crossing appends exactly one live-eval ledger line, gated or auto.
**SE-9 (F10/C10):** the lens is COMMITTED only after this gate resolves — a typed approval, a recorded
config skip, or a recorded policy auto-pass; Step 6 is the sole committer and depends on this step. On
cancel the whole delta is reverted before any commit, so nothing becomes durable without the gate.
**SE-11 (F12/C10):** every conditional-gate crossing appended exactly one live-eval ledger line
(`gate_eval.py append`), and an auto-pass fired only for a shape the policy lists in `auto:` (and not
in `never_auto:`) with no blocking finding.
### Phase: Commit (make the delta durable, ADR 026 step 7)
**Step 6 — Commit the model delta** · Owner: play · Depends on: Step 5
The gate approved (or auto-passed / was skipped by config). Commit the full model delta on the branch
(C12, ADR 026 step 7) — a lightweight persist step that makes the writes durable and advances HEAD; it
is NOT the pipeline start/end sequence (quality is a middle play). A cancelled checkpoint never reaches
this step — its tree was already restored in Step 5:
```
git add -- <product_base>product-os
git commit -m "feat(model): quality lens for <slice> (#<issue>)"
```
**SE-10 (F11/C11):** the close is stop-condition gated — `check_stop_condition.py` over the baked
`stop-condition.yaml` (D1 the persist record `persist-manifest.json` exists; D2 it stamps
`lens_applied: true`; D3 it stamps `gates_machine_applied: true`; D4 the captured `guard-report.json`
reads `ok: true`) must read **held** before any COMPLETED close, and the model delta is committed
(C12); a run whose persist or guard did not land closes HALTED, never COMPLETED (REC11).
### Phase: Scenario Validation
**Step 7 — Scenario evals** · Owner: play · Depends on: Step 6
- **SCE-1 (S1 — quality engineer):** `quality.md` is a valid Quality Lens doc clearing the linter +
the content eval, the spine/slice/profile/other lenses are byte-identical (guard `ok`), and the
stop-condition verdict reads held.
- **SCE-2 (S2 — product owner, grounded gates):** every gate traces to a profile NFR gate that
applies or a functionality rule; material choices name a decision that resolves.
- **SCE-3 (S3 — reviewer, concrete):** every gate is a checkable bar — a value or named standard plus
a check — never a bare adjective.
- **SCE-4 (S4 — architect, hub-only):** no other realize lens was read or written.
- **SCE-5 (S5 — product owner, re-run):** a re-run re-derives only `quality.md`; everything else
byte-identical (guard `ok`); no accepted decision edited in place.
- **SCE-6 (S6 — reviewer):** the checkpoint showed the intent and the gates inline over the real model
git diff, and no product-model change was COMMITTED before approval — the full delta written in place
shows as the branch diff and is reverted byte-clean on cancel (ADR 026 step 6) — or, on the auto-pass
path, the shape was policy-listed and the recorded auto-pass, the ledger line, and the diff summary
stood in for the wait (nothing committed before the gate resolved).
### Phase: Evidence & Close
**Step 8 — Close** · Owner: play · Depends on: Step 7
Run the Standard Play Close. /quality is a slice-realize play — record evidence per the D1 rule.
```bash
# --- Standard Play Close (canonical; see standards/rules/play-close.md) ---
# Path tokens resolved at pre-flight (resolve here if not already):
# ltm_project_target = yq '.ltm.project-target' .garura/core/config.yaml
# evidence_base, slug:
# project-scoped play : evidence_base="${stm_base}${issue}/evidence/quality/" ; slug="#${issue}"
# product-scoped play : evidence_base="${product_base}_evidence/quality/" ; slug="${slice_slug}"
evidence_template=$(cat "${ltm_project_target}standards/templates/evidence-file.md")
delivery_template=$(cat "${ltm_project_target}standards/templates/delivery-report.md")
ts=$(date -u +%Y%m%d-%H%M%S)
evidence_dest="${evidence_base}${ts}.md"
mkdir -p "$(dirname "$evidence_dest")"
# Session identity stamp (#463) — close phase; start phase ran at pre-flight
session_stamp=$(python3 scripts/session_stamp.py --phase close \
--marker "${stm_base}_realize/quality/status/session-stamp-quality.json")
# Stop-condition gate (#464) — Step C0: this play carries a baked manifest, so the
# gate is LIVE. Evaluate the Done means against the run's working root as the
# close's authoritative input.
python3 scripts/check_stop_condition.py \
--manifest "<play-dir>/stop-condition.yaml" \
--base "${stm_base}_realize/quality/" \
--out "${stm_base}_realize/quality/status/stop-condition-quality.yaml"
sc_exit=$? # 0 held · 1 unmet · 2 error
# Conditional-gate policy refresh (#467) — soft: a distill failure never blocks the close.
# gates_ledger / gates_policy / gates_streak = yq '.gates.conditional.ledger|.policy|.streak'
# project_name = yq '.project.name' .garura/core/config.yaml
python3 scripts/distill_gate_policy.py --ledger "${gates_ledger}" --policy "${gates_policy}" \
--streak "${gates_streak}" --project "${project_name}" || true
```
**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 — fix the state per REC11 (re-run the keyed persist,
re-capture the scoped-write guard report, or make the model-delta commit) and re-evaluate; the close
stays HALTED until the verdict reads held. An unevaluable verdict is never a pass.
`/quality` runs on the slice-realize issue /arch opened, so it is project-scoped:
`evidence_base="${stm_base}${issue}/evidence/quality/"` and `slug="#${issue}"`.
**Step C1 — Write evidence file.** Gated by the resolved `evidence.record` flag. When false, skip and
record `evidence skipped (record=false)`. Otherwise fill the `evidence-file.md` slots (play `quality`,
run_id `quality-${ts}`, slice slug, started/completed, status per C0, exit_reason; artifacts: the
slice's `quality.md`, its machine sibling `quality-gates.yaml`, the manifest, any decision, the persist
manifest (`persist-manifest.json`), the captured `guard-report.json`, the model-delta commit sha, the
stop-condition verdict; the content-eval verdict; step + scenario evals SE-1…SE-12 / SCE-1…SCE-6;
checkpoint decision (incl. any `gate skipped by config` or `gate auto-passed by learned policy` row,
with the diff summary and the ledger line); 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 with the Stop Condition section
filled) 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 `standards/rules/pipeline-next.md` and emit `**Next:** /<command> — <why>. Or run /next to see all recommended actions.` (only /next pointer, or omit, when the mapped command is null), per `play-close.md`. Fill the `delivery-report.md` slots: `## quality Delivered —
${slug}`, the Run Summary table (incl. the stop-condition verdict), the Pipeline Steps table, the
Artifacts Produced table (the quality lens + its machine sibling `quality-gates.yaml` + any
decision + the model-delta commit sha), Next Steps (run /run to close the non-functional pipe), and a
pointer to `$evidence_dest`. Always emitted.
```bash
# --- end Standard Play Close ---
```
## Scenario Validation
| Scenario | Persona | Eval |
|----------|---------|------|
| S1 — first run | quality engineer | SCE-1 |
| S2 — grounded gates | product owner | SCE-2 |
| S3 — concrete | reviewer | SCE-3 |
| S4 — hub-only | architect | SCE-4 |
| S5 — re-run | product owner | SCE-5 |
| S6 — the checkpoint | reviewer | SCE-6 |
## Recovery
| For | Trigger | Direction | Handoff |
|-----|---------|-----------|---------|
| F1 | the slice is absent, a functionality does not resolve, or the profile is not firmed | halt and route to /shape or /understand before /quality runs | human |
| F2 | a write touched something beyond this slice's quality.md, its machine sibling quality-gates.yaml, or a decision (scoped-guard violation) | the guard's `--restore` reverts the out-of-scope paths; re-run writing only the slice's lens and any decision | autonomous |
| F3 | quality.md fails the template/shape or carries out-of-scope content | re-emit to the Quality lens template (intent and gates only) | autonomous |
| F4 | quality.md fails the content-quality eval | rewrite the failing section to the judge's cited fixes and re-judge until the gate passes | autonomous |
| F5 | an invented gate, or a material choice with no decision | re-tie each gate to a profile gate or a functionality rule, and record the material decision | autonomous |
| F6 | a functionality was not considered | extend the gates to cover the missing functionality's quality-relevant rules | autonomous |
| F7 | /quality read or depended on another lens | remove the dependency; /quality derives only from the slice's hub | autonomous |
| F8 | a gate is not checkable — a vague adjective with no value, standard, or check | re-draft the gate as a value or named standard plus how it is checked | autonomous |
| F9 | a non-lens/non-decision file changed, or an accepted decision was edited in place (scoped-guard violation) | the guard's `--restore` already reverted the offending paths; re-run writing only quality.md + quality-gates.yaml and the new decision, after a human confirms the restore | human |
| F10 | the lens was committed before the checkpoint gate resolved | this cannot happen in write-then-review order (commit is Step 6, after the gate); if reached, revert the commit and re-present the checkpoint; commit only after the gate resolves | human |
| F11 | the run is about to close COMPLETED with the Done means unmet | close HALTED (`stop_condition_unmet`) with the unmet clauses named; fix the state — re-run the keyed persist, re-capture the scoped-write guard report, or make the model-delta commit — then re-evaluate; the close stays HALTED until the verdict reads held | autonomous |
| F12 | a conditional-gate crossing left no live-eval ledger line, or an auto-pass fired for a shape the policy does not list as auto (or that carried a blocking finding) | re-append the missing ledger line from the recorded crossing; when the auto-pass was unearned, re-run the gate as a live wait (render the prompt, take the typed verdict) and append the corrected line | autonomous |
| F13 | the product-os tree is dirty at entry (uncommitted model edits present) | halt at pre-flight and ask for a clean model tree — commit or revert the pending model edits (or run /arch to its close) — before /quality proceeds | human |
## Pause and Resume
Steps run top to bottom. On entry, resolve config, resolve the target slice, check the status marker,
skip completed steps, reset any in-progress step to pending, and continue. A fresh start with no
marker runs everything and creates the marker at Step 1. Resuming a run that already wrote model docs
enters a dirty tree; the pre-flight clean-tree assertion (F13) is scoped to a FRESH start — a resume
continues its own in-progress delta.
## Compilation Metadata
| Field | Value |
|-------|-------|
| fingerprint | sha256:387b35863215da93b3e57ade968d6368071a0399fb8ceb297f253d28e6b90dcb (of `reference/ice.md`) |
| compiled_by | play-editor (#500 direct-model-write, ADR 026); prior: play-editor (#466 Batch C; #467 Batch B — conditional learned gate) |
| pipeline_position | none |
| position_exception | middle of the non-functional realize pipe — runs on the branch /arch started; the close belongs to /run |
| workflow_structure | A (single checkpoint — conditional learned gate, class: standard, per gate-config.md #467; direct-model-write WRITE-THEN-REVIEW per ADR 026 — persist + guard + classify before the gate, commit after; gated close) |
| stop_condition | stop-condition.yaml (D1–D4), gate live at Step C0 |
| domain_agents | 1 (product-os-keeper) |
| utility_agents | 0 |
| skills_used | author-quality-lens |
| scripts | 11 (preflight, check_ready_slice, lint_grounding, grounding_gate, validate_quality, persist_quality — keyed in-place persist, scoped_write_guard — post-write containment, check_stop_condition — Done-means gate, session_stamp — #463 identity stamp, classify_change + gate_eval + distill_gate_policy — #467 conditional gate) |
| step_evals | 12 (SE-1…SE-12) |
| scenario_evals | 6 (SCE-1…SCE-6) |
| recovery_entries | 13 (one per failure condition; 10 autonomous / 3 human) |
**Recompiled note (#500, direct-model-write / ADR 026):** migrated from draft-then-apply to
direct-model-write. The old draft model tree and the `apply_quality.py`/`check_quality.py` promotion +
verify scripts are removed; the authoring skill writes the per-node lens docs (`quality.md` +
`quality-gates.yaml`) straight to the live model; the new keyed `persist_quality.py` writes the shared
files (decisions) in place, keyed to the slice, and stamps `lens_applied`/`gates_machine_applied` from
the live lens; containment is the post-write `scoped_write_guard.py` (its `guard-report.json` is D4);
`classify_change.py` reads the working-tree git diff (`--product-base`/`--base-ref HEAD`); checkpoint
cancel reverts the working tree via the guard `--restore`; the play asserts a clean product-os tree at
entry (F13) and commits its own `feat(model)` delta after approval (C12). Order is **write-then-review**
(ADR 026 "Order of operations"): the full delta — LLM lens docs AND the keyed persist's decision
writes — is written to the live model FIRST (Steps 1+3), then guarded ONCE and classified over the full
delta (Step 4), then the gate resolves over the real git diff (Step 5), and only an approved gate
COMMITS (Step 6). Nothing is COMMITTED before approval; cancel reverts the uncommitted writes. The
per-play Standard Play Close (evidence + delivery report) is retained (required by `lint-components`
and the play-creator G12 emit on every play); the `feat(model)` commit is the separate lightweight
persist step, so both coexist as C12 describes. See `standards/rules/direct-model-write.md`.
**Recompiled note (#467 Batch B):** checkpoint upgraded to a conditional learned gate; see
`gate-config.md`.
**Direct-edit deviation note (#500) — INTENT CHANGE, HAND-COMPILED, CONVERGENCE UNVERIFIED:**
This SKILL was updated to the direct-model-write write-then-review shape (ADR 026) by a
**hand-compile from `reference/ice.md`**, NOT by a live `/play-editor` run. This is an intent change
(it alters the write path, the containment guarantee, the checkpoint cancel semantics, and the step
order), so the sanctioned path is recompile-via-`/play-editor`; play-editor is interactive-only (fully
gated, human-checkpoint) and cannot run headless in this environment, so the compiled output was
produced by hand to match what play-editor would emit from the current `reference/ice.md` (fingerprint
above, the real sha256 of the file). **The `compiled_by` line names play-editor for provenance intent,
but no play-editor run actually occurred and convergence is UNVERIFIED.** An interactive `/play-editor`
convergence run against `reference/ice.md` is REQUIRED — confirming the emitted SKILL matches this
hand-compiled body and refreshing the fingerprint — before this play is relied on in a pipeline run.
This mirrors the /understand reference migration (#498) whose ICE C12 distinguishes the model-delta
commit from the Standard Play Close; both coexist here as C12 describes.
Is this your skill, or is something wrong with this listing? Request removal or report an issue. Author removals are honored within 72 hours.
No comments yet. Be the first to comment!