mirror of
https://github.com/mvschwarz/openrig.git
synced 2026-11-09 03:39:51 -10:00
docs(guidance): teach the conventions SSOT in both repo and installed contexts
The conventions doc reaches readers by three paths, and the shipped teaching surfaces only ever named one of them: repo source docs/reference/sdlc-conventions.md packed internal daemon/docs/reference/sdlc-conventions.md installed stable $OPENRIG_HOME/reference/sdlc-conventions.md Every pointer named the repo path. That is correct for someone reading the repo and wrong for an agent on an installed package, where the file lives where the daemon materializes it at startup -- it copies the bundled docs to $OPENRIG_HOME/reference/ precisely "so agents can find them at a stable path" (packages/daemon/src/startup.ts). So the guidance sent installed agents to a path that does not exist on their machine. Fixed by teaching both contexts rather than by moving files. The packed path stays internal assembly input and is never taught: it is the resolver's input, not a user path, and scripts/build-package.sh stages it there for exactly that reason. The default ~/.openrig is shown only parenthetically -- naming $OPENRIG_HOME is what stays correct for operators running a custom home. Repo-only surfaces (source comments, the scaffold test's SSOT_POINTER constant, filesystem reads of the repo file) keep the repo path, because they are correct there. Also trims the mission-slice-sop description from 701 to 392 UTF-8 bytes. A skill description is a retrieval surface competing for budget with every other skill; this one was the outlier. The trim is guarded by a test pinning both the budget and the named trigger terms, since a shorter description that drops "proof-lock" is a skill that silently stops being retrieved for proof-lock work. What was cut lives on in the skill body. Tests: check-packing now pins the staging contract hermetically -- it asserts build-package.sh's staging and the files allowlist from git-tracked inputs only, because reading packages/cli/daemon (gitignored build output) would pass on a developer machine and fail a clean checkout. Byte-equality against a real artifact is a separate opportunistic check that skips when absent. Plugin byte-parity is extended to openrig-user, which carried the pointer in both canonical and bundled copies but had no drift guard. Slice: release-0.4.7 guidance completeness Gate: qitem-20260720102526-5e585698 (Guard) / qitem-20260720101929-aa922842 Co-Authored-By: Claude Opus 4.8 (1M context) <[email protected]>
This commit is contained in:
1 parent
42e7b19857
commit
6c7b9240c3
31 files changed
+260
-48
No files matched your search
@@ -535,7 +535,7 @@ ${slice.objective}
|
||||
- [ ] Queue items include enough body or tag context to link back to \`${slice.id}\`.
|
||||
- [ ] Proof artifacts are referenced from the slice before closure (drop via \`rig proof add\`).
|
||||
|
||||
> Conventions SSOT: \`docs/reference/sdlc-conventions.md\` — section names, proof-contract format, the two locks, C1 headers. For a small slice the mini-requirements may BE the whole PRD.
|
||||
> Conventions SSOT: \`docs/reference/sdlc-conventions.md (installed: $OPENRIG_HOME/reference/sdlc-conventions.md)\` — section names, proof-contract format, the two locks, C1 headers. For a small slice the mini-requirements may BE the whole PRD.
|
||||
`;
|
||||
}
|
||||
|
||||
|
||||
@@ -93,7 +93,7 @@ function isVideoFile(filePath: string): boolean {
|
||||
|
||||
export function proofCommand(): Command {
|
||||
const cmd = new Command("proof").description(
|
||||
"Proof artifacts — drop gate/proof evidence into a slice's proof/ dir with the machine-readable C1 header, validated at the natural moment (OPR.0.4.4.19 FR-8). The drop is the SDLC's proof leg: --evidences joins it to the slice's ## Proof contract items (what the Living Notes DELIVERED section pairs + renders); proof-lock afterwards via rig scope slice approve --scope delivery. Conventions SSOT: docs/reference/sdlc-conventions.md."
|
||||
"Proof artifacts — drop gate/proof evidence into a slice's proof/ dir with the machine-readable C1 header, validated at the natural moment (OPR.0.4.4.19 FR-8). The drop is the SDLC's proof leg: --evidences joins it to the slice's ## Proof contract items (what the Living Notes DELIVERED section pairs + renders); proof-lock afterwards via rig scope slice approve --scope delivery. Conventions SSOT: docs/reference/sdlc-conventions.md (installed: $OPENRIG_HOME/reference/sdlc-conventions.md)."
|
||||
);
|
||||
cmd.option("--workspace <path>", "Override workspace root (else cwd walk or $OPENRIG_WORK_ROOT)");
|
||||
|
||||
|
||||
@@ -259,7 +259,7 @@ function buildSliceShowCommand(): Command {
|
||||
|
||||
function buildSliceCreateCommand(): Command {
|
||||
return new Command("create")
|
||||
.description("Create a new slice in a mission. Scaffolds the SDLC convention sections (## Intent / ## Mini-requirements / ## Proof contract) + proof/ + PROOF.md + IMPLEMENTATION-PRD.md for EVERY template kind — the shapes the Living Notes UI projects. Conventions SSOT: docs/reference/sdlc-conventions.md.")
|
||||
.description("Create a new slice in a mission. Scaffolds the SDLC convention sections (## Intent / ## Mini-requirements / ## Proof contract) + proof/ + PROOF.md + IMPLEMENTATION-PRD.md for EVERY template kind — the shapes the Living Notes UI projects. Conventions SSOT: docs/reference/sdlc-conventions.md (installed: $OPENRIG_HOME/reference/sdlc-conventions.md).")
|
||||
.argument("<mission>", "Mission name")
|
||||
.argument("<slug>", "Short slug (becomes the folder name's suffix)")
|
||||
.option("--template <kind>", `Template: ${SLICE_TEMPLATE_KINDS.join(" | ")}`, "placeholder")
|
||||
@@ -1596,7 +1596,7 @@ function buildApproveCommand(tier: "slice" | "mission"): Command {
|
||||
return new Command("approve")
|
||||
.description(
|
||||
tier === "slice"
|
||||
? "Approve a slice: writes the frontmatter stamp + an append-only audit row (daemon-side, one operation). --scope spec = the PLAN-LOCK (PRD-matches-intent; this artifact set gets built); delivery (default) = the PROOF-LOCK (terminal sign-off). Approval is freeze/sign-off, never proven-green. Conventions SSOT: docs/reference/sdlc-conventions.md."
|
||||
? "Approve a slice: writes the frontmatter stamp + an append-only audit row (daemon-side, one operation). --scope spec = the PLAN-LOCK (PRD-matches-intent; this artifact set gets built); delivery (default) = the PROOF-LOCK (terminal sign-off). Approval is freeze/sign-off, never proven-green. Conventions SSOT: docs/reference/sdlc-conventions.md (installed: $OPENRIG_HOME/reference/sdlc-conventions.md)."
|
||||
: "Approve a mission: same staged/delegated semantics as slice approve, at mission tier."
|
||||
)
|
||||
.argument(tier === "slice" ? "<slice-path>" : "<mission>", tier === "slice" ? "Slice path (absolute, relative, or NN-slug)" : "Mission name")
|
||||
|
||||
@@ -40,4 +40,4 @@ created: {{created_date}}
|
||||
|
||||
---
|
||||
|
||||
> **How you work this slice (SOP):** conventions SSOT: `docs/reference/sdlc-conventions.md`; full flow: the `mission-slice-sop` skill. Author intent → mini-requirements + proof contract (→ mockups for UI slices) → plan-lock (`rig scope slice approve --scope spec`) → build the locked set → QA visual compare → `rig proof add … --evidences --media` drops into `proof/` (never hand-place evidence without the drop) → proof-lock (`--scope delivery`). Track on PROGRESS.md; a slice is **not done** until every proof-contract item has evidence. Verify with `rig scope audit`.
|
||||
> **How you work this slice (SOP):** conventions SSOT: `docs/reference/sdlc-conventions.md` (installed: `$OPENRIG_HOME/reference/sdlc-conventions.md`); full flow: the `mission-slice-sop` skill. Author intent → mini-requirements + proof contract (→ mockups for UI slices) → plan-lock (`rig scope slice approve --scope spec`) → build the locked set → QA visual compare → `rig proof add … --evidences --media` drops into `proof/` (never hand-place evidence without the drop) → proof-lock (`--scope delivery`). Track on PROGRESS.md; a slice is **not done** until every proof-contract item has evidence. Verify with `rig scope audit`.
|
||||
@@ -36,4 +36,4 @@ created: {{created_date}}
|
||||
|
||||
---
|
||||
|
||||
> **How you work this slice (SOP):** conventions SSOT: `docs/reference/sdlc-conventions.md`; full flow: the `mission-slice-sop` skill. Author intent → mini-requirements + proof contract (→ mockups for UI slices) → plan-lock (`rig scope slice approve --scope spec`) → build the locked set → QA visual compare → `rig proof add … --evidences --media` drops into `proof/` (never hand-place evidence without the drop) → proof-lock (`--scope delivery`). Track on PROGRESS.md; a slice is **not done** until every proof-contract item has evidence. Verify with `rig scope audit`.
|
||||
> **How you work this slice (SOP):** conventions SSOT: `docs/reference/sdlc-conventions.md` (installed: `$OPENRIG_HOME/reference/sdlc-conventions.md`); full flow: the `mission-slice-sop` skill. Author intent → mini-requirements + proof contract (→ mockups for UI slices) → plan-lock (`rig scope slice approve --scope spec`) → build the locked set → QA visual compare → `rig proof add … --evidences --media` drops into `proof/` (never hand-place evidence without the drop) → proof-lock (`--scope delivery`). Track on PROGRESS.md; a slice is **not done** until every proof-contract item has evidence. Verify with `rig scope audit`.
|
||||
@@ -44,4 +44,4 @@ created: {{created_date}}
|
||||
|
||||
---
|
||||
|
||||
> **How you work this slice (SOP):** conventions SSOT: `docs/reference/sdlc-conventions.md`; full flow: the `mission-slice-sop` skill. Author intent → mini-requirements + proof contract (→ mockups for UI slices) → plan-lock (`rig scope slice approve --scope spec`) → build the locked set → QA visual compare → `rig proof add … --evidences --media` drops into `proof/` (never hand-place evidence without the drop) → proof-lock (`--scope delivery`). Track on PROGRESS.md; a slice is **not done** until every proof-contract item has evidence. Verify with `rig scope audit`.
|
||||
> **How you work this slice (SOP):** conventions SSOT: `docs/reference/sdlc-conventions.md` (installed: `$OPENRIG_HOME/reference/sdlc-conventions.md`); full flow: the `mission-slice-sop` skill. Author intent → mini-requirements + proof contract (→ mockups for UI slices) → plan-lock (`rig scope slice approve --scope spec`) → build the locked set → QA visual compare → `rig proof add … --evidences --media` drops into `proof/` (never hand-place evidence without the drop) → proof-lock (`--scope delivery`). Track on PROGRESS.md; a slice is **not done** until every proof-contract item has evidence. Verify with `rig scope audit`.
|
||||
@@ -12,7 +12,7 @@ created: {{created_date}}
|
||||
proof. Everything between is ELASTIC. For a small slice the
|
||||
mini-requirements below may BE the whole PRD; add depth only where the
|
||||
work demands it. The scaffold must not mint ceremony.
|
||||
Conventions SSOT: docs/reference/sdlc-conventions.md -->
|
||||
Conventions SSOT: docs/reference/sdlc-conventions.md (installed: $OPENRIG_HOME/reference/sdlc-conventions.md) -->
|
||||
|
||||
# Slice {{slice_number}} — {{title}}
|
||||
|
||||
|
||||
@@ -24,7 +24,7 @@ created: {{created_date}}
|
||||
|
||||
## Mission/Slice SOP — how you work this mission & slice
|
||||
|
||||
> The canonical files below are the **operating surface of the work** — you track on them, prove on them, hand off through them, and survive compaction on them. They are NOT side-artifacts to "maintain"; keeping them current *is* the work. Load the `mission-slice-sop` skill for the full operating procedure. **Conventions SSOT: `docs/reference/sdlc-conventions.md`** — the slice section names (`## Intent` / `## Mini-requirements` / `## Proof contract`), the proof-contract format, the two locks (`rig scope slice approve --scope spec|delivery`), and the C1 proof headers all live there.
|
||||
> The canonical files below are the **operating surface of the work** — you track on them, prove on them, hand off through them, and survive compaction on them. They are NOT side-artifacts to "maintain"; keeping them current *is* the work. Load the `mission-slice-sop` skill for the full operating procedure. **Conventions SSOT: `docs/reference/sdlc-conventions.md`** (installed: `$OPENRIG_HOME/reference/sdlc-conventions.md`) — the slice section names (`## Intent` / `## Mini-requirements` / `## Proof contract`), the proof-contract format, the two locks (`rig scope slice approve --scope spec|delivery`), and the C1 proof headers all live there.
|
||||
|
||||
### The canonical files (the operating surface)
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
# Progress — {{missionName}}
|
||||
|
||||
> **WHO/WHEN:** the orchestrator owns the current-state summary; every agent logs its own outcomes here after every slice-done AND every commit. One line per outcome, link down for detail. See the `mission-slice-sop` skill + the conventions SSOT (`docs/reference/sdlc-conventions.md`).
|
||||
> **WHO/WHEN:** the orchestrator owns the current-state summary; every agent logs its own outcomes here after every slice-done AND every commit. One line per outcome, link down for detail. See the `mission-slice-sop` skill + the conventions SSOT (`docs/reference/sdlc-conventions.md` in the repo, `$OPENRIG_HOME/reference/sdlc-conventions.md` on an installed package).
|
||||
|
||||
## Milestones
|
||||
|
||||
|
||||
@@ -29,7 +29,7 @@ created: {{created_date}}
|
||||
|
||||
## Mission/Slice SOP — how you work this mission & slice
|
||||
|
||||
> The canonical files below are the **operating surface of the work** — you track on them, prove on them, hand off through them, and survive compaction on them. They are NOT side-artifacts to "maintain"; keeping them current *is* the work. Load the `mission-slice-sop` skill for the full operating procedure. **Conventions SSOT: `docs/reference/sdlc-conventions.md`** — the slice section names (`## Intent` / `## Mini-requirements` / `## Proof contract`), the proof-contract format, the two locks (`rig scope slice approve --scope spec|delivery`), and the C1 proof headers all live there.
|
||||
> The canonical files below are the **operating surface of the work** — you track on them, prove on them, hand off through them, and survive compaction on them. They are NOT side-artifacts to "maintain"; keeping them current *is* the work. Load the `mission-slice-sop` skill for the full operating procedure. **Conventions SSOT: `docs/reference/sdlc-conventions.md`** (installed: `$OPENRIG_HOME/reference/sdlc-conventions.md`) — the slice section names (`## Intent` / `## Mini-requirements` / `## Proof contract`), the proof-contract format, the two locks (`rig scope slice approve --scope spec|delivery`), and the C1 proof headers all live there.
|
||||
|
||||
### The canonical files (the operating surface)
|
||||
|
||||
|
||||
@@ -44,4 +44,4 @@ Non-visual slices: mark this section N/A.
|
||||
|
||||
---
|
||||
|
||||
> **How you work this slice (SOP):** conventions SSOT: `docs/reference/sdlc-conventions.md`; full flow: the `mission-slice-sop` skill. Author intent → mini-requirements + proof contract (→ mockups for UI slices) → plan-lock (`rig scope slice approve --scope spec`) → build the locked set → QA visual compare → `rig proof add … --evidences --media` drops into `proof/` (never hand-place evidence without the drop) → proof-lock (`--scope delivery`). Track on PROGRESS.md; a slice is **not done** until every proof-contract item has evidence. Verify with `rig scope audit`.
|
||||
> **How you work this slice (SOP):** conventions SSOT: `docs/reference/sdlc-conventions.md` (installed: `$OPENRIG_HOME/reference/sdlc-conventions.md`); full flow: the `mission-slice-sop` skill. Author intent → mini-requirements + proof contract (→ mockups for UI slices) → plan-lock (`rig scope slice approve --scope spec`) → build the locked set → QA visual compare → `rig proof add … --evidences --media` drops into `proof/` (never hand-place evidence without the drop) → proof-lock (`--scope delivery`). Track on PROGRESS.md; a slice is **not done** until every proof-contract item has evidence. Verify with `rig scope audit`.
|
||||
@@ -1,6 +1,6 @@
|
||||
# PROOF — {{id}} {{title}}
|
||||
|
||||
> **WHO/WHEN:** the impl/QA pair that worked the slice, at slice-close — a slice is NOT done until this file exists and every proof-contract item has evidence (mapped 1:1, artifacts under `proof/`). See the `mission-slice-sop` skill + the conventions SSOT (`docs/reference/sdlc-conventions.md`).
|
||||
> **WHO/WHEN:** the impl/QA pair that worked the slice, at slice-close — a slice is NOT done until this file exists and every proof-contract item has evidence (mapped 1:1, artifacts under `proof/`). See the `mission-slice-sop` skill + the conventions SSOT (`docs/reference/sdlc-conventions.md` in the repo, `$OPENRIG_HOME/reference/sdlc-conventions.md` on an installed package).
|
||||
>
|
||||
> **HOW (the drop verb, not hand-placement):** put media files under `proof/`, then ATTACH them with `rig proof add {{id}} --artifact-type qa --verdict PASS --candidate-sha <tip> --money-evidence "<one line>" --evidences "1" --media "screenshot-01.png"` — the drop writes the C1 header the Living Notes DELIVERED pairing joins on. Hand-placing files without a drop leaves the deliverable unpaired and `unverified`.
|
||||
|
||||
|
||||
@@ -32,4 +32,4 @@ created: {{created_date}}
|
||||
|
||||
---
|
||||
|
||||
> **How you work this slice (SOP):** conventions SSOT: `docs/reference/sdlc-conventions.md`; full flow: the `mission-slice-sop` skill. Author intent → mini-requirements + proof contract (→ mockups for UI slices) → plan-lock (`rig scope slice approve --scope spec`) → build the locked set → QA visual compare → `rig proof add … --evidences --media` drops into `proof/` (never hand-place evidence without the drop) → proof-lock (`--scope delivery`). Track on PROGRESS.md; a slice is **not done** until every proof-contract item has evidence. Verify with `rig scope audit`.
|
||||
> **How you work this slice (SOP):** conventions SSOT: `docs/reference/sdlc-conventions.md` (installed: `$OPENRIG_HOME/reference/sdlc-conventions.md`); full flow: the `mission-slice-sop` skill. Author intent → mini-requirements + proof contract (→ mockups for UI slices) → plan-lock (`rig scope slice approve --scope spec`) → build the locked set → QA visual compare → `rig proof add … --evidences --media` drops into `proof/` (never hand-place evidence without the drop) → proof-lock (`--scope delivery`). Track on PROGRESS.md; a slice is **not done** until every proof-contract item has evidence. Verify with `rig scope audit`.
|
||||
@@ -36,4 +36,4 @@ created: {{created_date}}
|
||||
|
||||
---
|
||||
|
||||
> **How you work this slice (SOP):** conventions SSOT: `docs/reference/sdlc-conventions.md`; full flow: the `mission-slice-sop` skill. Author intent → mini-requirements + proof contract (→ mockups for UI slices) → plan-lock (`rig scope slice approve --scope spec`) → build the locked set → QA visual compare → `rig proof add … --evidences --media` drops into `proof/` (never hand-place evidence without the drop) → proof-lock (`--scope delivery`). Track on PROGRESS.md; a slice is **not done** until every proof-contract item has evidence. Verify with `rig scope audit`.
|
||||
> **How you work this slice (SOP):** conventions SSOT: `docs/reference/sdlc-conventions.md` (installed: `$OPENRIG_HOME/reference/sdlc-conventions.md`); full flow: the `mission-slice-sop` skill. Author intent → mini-requirements + proof contract (→ mockups for UI slices) → plan-lock (`rig scope slice approve --scope spec`) → build the locked set → QA visual compare → `rig proof add … --evidences --media` drops into `proof/` (never hand-place evidence without the drop) → proof-lock (`--scope delivery`). Track on PROGRESS.md; a slice is **not done** until every proof-contract item has evidence. Verify with `rig scope audit`.
|
||||
@@ -1,6 +1,6 @@
|
||||
# Progress — {{sliceName}}
|
||||
|
||||
> **WHO/WHEN:** every agent working this slice logs its own outcomes here after every slice-done AND every commit. One line per outcome, link down for detail. See the `mission-slice-sop` skill + the conventions SSOT (`docs/reference/sdlc-conventions.md`).
|
||||
> **WHO/WHEN:** every agent working this slice logs its own outcomes here after every slice-done AND every commit. One line per outcome, link down for detail. See the `mission-slice-sop` skill + the conventions SSOT (`docs/reference/sdlc-conventions.md` in the repo, `$OPENRIG_HOME/reference/sdlc-conventions.md` on an installed package).
|
||||
|
||||
## Acceptance
|
||||
|
||||
|
||||
@@ -403,7 +403,7 @@ export function classifyScopeItem(input: ScopeAuditInput): ScopeAuditResult {
|
||||
severity: "low",
|
||||
path: childPath(input.path, "README.md"),
|
||||
message: "Slice README has no `## Intent` section, so the Living Notes UI cannot project its INTENT section.",
|
||||
remediation: "Add `## Intent` carrying the recorded intent verbatim (conventions SSOT: docs/reference/sdlc-conventions.md; `rig scope slice create` scaffolds it).",
|
||||
remediation: "Add `## Intent` carrying the recorded intent verbatim (conventions SSOT: docs/reference/sdlc-conventions.md (installed: $OPENRIG_HOME/reference/sdlc-conventions.md); `rig scope slice create` scaffolds it).",
|
||||
});
|
||||
}
|
||||
|
||||
@@ -456,7 +456,7 @@ export function classifyScopeItem(input: ScopeAuditInput): ScopeAuditResult {
|
||||
message: miniBody === null
|
||||
? "No `## Mini-requirements` section — the Living Notes PLAN section has no concise requirements tier to project."
|
||||
: "`## Mini-requirements` carries no numbered items (`1. …`) — the one-glance requirement tier is where approval starts.",
|
||||
remediation: "Add `## Mini-requirements` with a numbered list of observable outcomes (conventions SSOT: docs/reference/sdlc-conventions.md; for a small slice this may BE the whole PRD).",
|
||||
remediation: "Add `## Mini-requirements` with a numbered list of observable outcomes (conventions SSOT: docs/reference/sdlc-conventions.md (installed: $OPENRIG_HOME/reference/sdlc-conventions.md); for a small slice this may BE the whole PRD).",
|
||||
});
|
||||
}
|
||||
}
|
||||
@@ -482,7 +482,7 @@ export function classifyScopeItem(input: ScopeAuditInput): ScopeAuditResult {
|
||||
message: contractBody === null
|
||||
? "No `## Proof contract` section — the DELIVERED pairing has no promised-deliverables source to join proof against."
|
||||
: "`## Proof contract` carries no checkbox deliverables (`- [ ] …`) — the DELIVERED pairing joins proof against those items.",
|
||||
remediation: "Add `## Proof contract` with one checkbox line per promised deliverable, written as an observable outcome (conventions SSOT: docs/reference/sdlc-conventions.md).",
|
||||
remediation: "Add `## Proof contract` with one checkbox line per promised deliverable, written as an observable outcome (conventions SSOT: docs/reference/sdlc-conventions.md (installed: $OPENRIG_HOME/reference/sdlc-conventions.md)).",
|
||||
});
|
||||
}
|
||||
|
||||
@@ -503,7 +503,7 @@ export function classifyScopeItem(input: ScopeAuditInput): ScopeAuditResult {
|
||||
severity: "info",
|
||||
path: childPath(input.path, "README.md"),
|
||||
message: "Slice declares an Intent visual (UI slice) but no mockup reference is present — a UI slice with no mockup in its locked set is an incomplete plan.",
|
||||
remediation: "Attach the planned mockup: an image ref in `## Intent visual` or a plannedRef on the proof-contract deliverable (conventions SSOT: docs/reference/sdlc-conventions.md §3).",
|
||||
remediation: "Attach the planned mockup: an image ref in `## Intent visual` or a plannedRef on the proof-contract deliverable (conventions SSOT: docs/reference/sdlc-conventions.md §3 (installed: $OPENRIG_HOME/reference/sdlc-conventions.md §3)).",
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@@ -21,6 +21,25 @@ import { renderMissionTemplate } from "../src/lib/scope/templates.js";
|
||||
const CONVENTION_SECTIONS = ["## Intent", "## Mini-requirements", "## Proof contract"] as const;
|
||||
const SSOT_POINTER = "docs/reference/sdlc-conventions.md";
|
||||
|
||||
// aa922842 — the dual-context pointer contract.
|
||||
//
|
||||
// Scaffolded output lands in a USER's workspace, so it is installed-facing: the reader may
|
||||
// have no repo at all. The same doc reaches them by three different paths and only two may
|
||||
// ever be taught:
|
||||
// repo source docs/reference/sdlc-conventions.md — correct for repo readers
|
||||
// installed stable $OPENRIG_HOME/reference/sdlc-conventions.md — correct for installed agents
|
||||
// (default ~/.openrig/…)
|
||||
// packed internal daemon/docs/reference/… — assembly input, NEVER taught
|
||||
//
|
||||
// Two failure modes this guards, both of which look fine in a repo checkout:
|
||||
// 1. teaching ONLY the repo path — an installed agent looks somewhere that does not exist;
|
||||
// 2. teaching the DEFAULT home as the only path — wrong for any operator with a custom
|
||||
// OPENRIG_HOME (this rig runs one). Naming `$OPENRIG_HOME/...` is MANDATORY; mentioning
|
||||
// `~/.openrig/...` alongside it as the default is honest and explicitly allowed, so this
|
||||
// does NOT ban the default — requiring the env-aware pointer already covers the risk.
|
||||
const INSTALLED_POINTER_ENV = "$OPENRIG_HOME/reference/sdlc-conventions.md";
|
||||
const INTERNAL_PACKED_PATH = "daemon/docs/reference/";
|
||||
|
||||
const RENDER_OPTS = {
|
||||
id: "OPR.0.4.4.99",
|
||||
slice_number: "99",
|
||||
@@ -83,6 +102,31 @@ describe("OPR.0.4.4.23 convention scaffold — exhaustive over SliceTemplateKind
|
||||
}
|
||||
});
|
||||
|
||||
// aa922842 — dual-context pointer discriminator. Scaffolded output is installed-facing.
|
||||
it("every slice template teaches BOTH contexts: the repo path AND the OPENRIG_HOME-aware installed path", () => {
|
||||
for (const kind of SLICE_TEMPLATE_KINDS) {
|
||||
const rendered = renderSliceTemplate(kind, RENDER_OPTS);
|
||||
// Repo context retained — a repo reader must not be sent to an installed-only path.
|
||||
expect(rendered, `template kind "${kind}" dropped the repo-source pointer`).toContain(SSOT_POINTER);
|
||||
// Installed context added — without this an agent on an installed package is told to
|
||||
// read a path that does not exist on their machine.
|
||||
expect(
|
||||
rendered,
|
||||
`template kind "${kind}" never names the installed stable path; an installed agent cannot find the conventions doc from this scaffold`,
|
||||
).toContain(INSTALLED_POINTER_ENV);
|
||||
}
|
||||
});
|
||||
|
||||
it("no template leaks the internal packed path as if it were a user path", () => {
|
||||
for (const kind of SLICE_TEMPLATE_KINDS) {
|
||||
const rendered = renderSliceTemplate(kind, RENDER_OPTS);
|
||||
expect(
|
||||
rendered.includes(INTERNAL_PACKED_PATH),
|
||||
`template kind "${kind}" teaches the internal assembly path ${INTERNAL_PACKED_PATH} as if it were a user path`,
|
||||
).toBe(false);
|
||||
}
|
||||
});
|
||||
|
||||
it("the convention sections come FIRST — kind-specific body sits below them", () => {
|
||||
for (const kind of SLICE_TEMPLATE_KINDS) {
|
||||
const rendered = renderSliceTemplate(kind, RENDER_OPTS);
|
||||
|
||||
@@ -21,7 +21,7 @@ Load those too. This shared overlay is only the common bootstrap floor, not the
|
||||
|
||||
If your seat works missions or slices, load the packaged `mission-slice-sop` skill BEFORE authoring or building — it teaches the flow the Living Notes UI projects: intent → mini-requirements + proof contract (→ mockups for UI slices) → plan-lock (`rig scope slice approve --scope spec`) → build the locked set → QA visual compare → `rig proof add … --media` drops (the C1 drop verb — never hand-place proof files) → proof-lock (`--scope delivery`).
|
||||
|
||||
The conventions themselves (section names, proof-contract format, the two locks, C1 proof headers) live in ONE shipped document: `docs/reference/sdlc-conventions.md` (in the CLI package). `rig scope slice create` scaffolds the convention sections for every template kind; `rig scope audit` is the advisory backstop — it records and advises, it never blocks your work.
|
||||
The conventions themselves (section names, proof-contract format, the two locks, C1 proof headers) live in ONE shipped document: `docs/reference/sdlc-conventions.md` in the repo, materialized at `$OPENRIG_HOME/reference/sdlc-conventions.md` (default `~/.openrig/reference/sdlc-conventions.md`) on an installed package. `rig scope slice create` scaffolds the convention sections for every template kind; `rig scope audit` is the advisory backstop — it records and advises, it never blocks your work.
|
||||
|
||||
## Identity
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
---
|
||||
name: mission-slice-sop
|
||||
description: Use when working a mission or slice — the full SDLC flow (intent → mini-requirements + proof contract → mockups → plan-lock → build → QA visual compare → `rig proof` drops → proof-lock) plus how to track, prove, hand off, and carry state across agents and compaction via the canonical files (PROGRESS.md / PROOF.md / MISSION_NOTES.md / MISSION_BRIEF.md / README.md / IMPLEMENTATION-PRD.md). Covers the convention sections the Living Notes UI projects, the two locks, the three role contracts, per-file WHO/WHEN/HOW rules, the four-legs lifecycle, hot-potato queue handoffs, the moment-of-truth checklist, the deterministic `rig scope audit` backstop, and the ghost-text capture gotcha.
|
||||
description: "Use when working a mission or slice: the SDLC flow (intent -> mini-requirements + proof contract -> mockups -> plan-lock -> build -> QA -> `rig proof` drops -> proof-lock), and how to track, prove, and hand off state across agents and compaction via PROGRESS.md / PROOF.md / MISSION_NOTES.md. Covers the two locks, role contracts, hot-potato queue handoff, and the `rig scope audit` backstop."
|
||||
metadata:
|
||||
openrig:
|
||||
stage: shipped
|
||||
@@ -11,8 +11,10 @@ metadata:
|
||||
Living Notes UI projects — the convention sections, the proof-contract
|
||||
pairing, the two staged-approval locks, C1 proof drops, and the three
|
||||
role contracts. Conventions SSOT: docs/reference/sdlc-conventions.md
|
||||
(shipped with the CLI package). The deterministic backstop is the
|
||||
`rig scope audit` classifier.
|
||||
in the repo; on an installed package the daemon materializes the same
|
||||
document at $OPENRIG_HOME/reference/sdlc-conventions.md (default
|
||||
~/.openrig/reference/sdlc-conventions.md). The deterministic backstop
|
||||
is the `rig scope audit` classifier.
|
||||
sibling_skills:
|
||||
- queue-handoff
|
||||
- seat-continuity-and-handover
|
||||
@@ -21,7 +23,7 @@ metadata:
|
||||
|
||||
# Mission/Slice SOP — how you work a mission & slice
|
||||
|
||||
Use this skill to actually **do** mission/slice work the way OpenRig expects: author the convention sections, track on the canonical files, prove on them, hand off through them, and survive compaction on them. **Do the work described here; do not merely explain the protocol.** The deterministic backstop is `rig scope audit` — the audit classifier is the source of truth for adherence. The conventions themselves live in ONE place: **`docs/reference/sdlc-conventions.md`** (shipped with the CLI package) — this skill teaches the flow; the SSOT defines the formats.
|
||||
Use this skill to actually **do** mission/slice work the way OpenRig expects: author the convention sections, track on the canonical files, prove on them, hand off through them, and survive compaction on them. **Do the work described here; do not merely explain the protocol.** The deterministic backstop is `rig scope audit` — the audit classifier is the source of truth for adherence. The conventions themselves live in ONE document: **`docs/reference/sdlc-conventions.md`** in the repo, materialized by the daemon at **`$OPENRIG_HOME/reference/sdlc-conventions.md`** (default `~/.openrig/reference/sdlc-conventions.md`) on an installed package — this skill teaches the flow; the SSOT defines the formats.
|
||||
|
||||
## The SDLC flow (intent → proof)
|
||||
|
||||
@@ -110,4 +112,4 @@ When you `rig capture` a pane, **greyed / ghost autocomplete suggestions are NOT
|
||||
- **Finishing a slice?** → every proof-contract item has curated evidence via `rig proof add … --evidences --media` (C1 drops — never only hand-placed files)? PROGRESS updated? MISSION_NOTES `§1` refreshed? proof locked (`--scope delivery`)? Handed off via queue?
|
||||
- **Committing?** → PROGRESS updated?
|
||||
- **Compacting?** → filed your state in MISSION_NOTES?
|
||||
- **Starting on a mission?** → read the mission README (incl. this SOP) + MISSION_NOTES + `docs/reference/sdlc-conventions.md`?
|
||||
- **Starting on a mission?** → read the mission README (incl. this SOP) + MISSION_NOTES + the conventions SSOT (`docs/reference/sdlc-conventions.md` in the repo, `$OPENRIG_HOME/reference/sdlc-conventions.md` on an installed package)?
|
||||
@@ -565,7 +565,7 @@ Composes with slice 33's `progress` + scaffolding to make `rig scope` the **dete
|
||||
|
||||
### The SDLC control plane — convention sections, the two locks, `rig proof` (v0.4.4)
|
||||
|
||||
The Living Notes UI is a plain projection of well-formed on-disk markdown. The conventions live in ONE shipped document — **`docs/reference/sdlc-conventions.md`** (in the CLI package) — and the operating procedure is the **`mission-slice-sop`** skill. The command surface:
|
||||
The Living Notes UI is a plain projection of well-formed on-disk markdown. The conventions live in ONE shipped document — **`docs/reference/sdlc-conventions.md`** in the repo, materialized by the daemon at **`$OPENRIG_HOME/reference/sdlc-conventions.md`** (default `~/.openrig/reference/sdlc-conventions.md`) on an installed package — and the operating procedure is the **`mission-slice-sop`** skill. The command surface:
|
||||
|
||||
```bash
|
||||
rig scope slice create <mission> <slug> [--template <kind>] # scaffolds ## Intent / ## Mini-requirements / ## Proof contract
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
---
|
||||
name: mission-slice-sop
|
||||
description: Use when working a mission or slice — the full SDLC flow (intent → mini-requirements + proof contract → mockups → plan-lock → build → QA visual compare → `rig proof` drops → proof-lock) plus how to track, prove, hand off, and carry state across agents and compaction via the canonical files (PROGRESS.md / PROOF.md / MISSION_NOTES.md / MISSION_BRIEF.md / README.md / IMPLEMENTATION-PRD.md). Covers the convention sections the Living Notes UI projects, the two locks, the three role contracts, per-file WHO/WHEN/HOW rules, the four-legs lifecycle, hot-potato queue handoffs, the moment-of-truth checklist, the deterministic `rig scope audit` backstop, and the ghost-text capture gotcha.
|
||||
description: "Use when working a mission or slice: the SDLC flow (intent -> mini-requirements + proof contract -> mockups -> plan-lock -> build -> QA -> `rig proof` drops -> proof-lock), and how to track, prove, and hand off state across agents and compaction via PROGRESS.md / PROOF.md / MISSION_NOTES.md. Covers the two locks, role contracts, hot-potato queue handoff, and the `rig scope audit` backstop."
|
||||
metadata:
|
||||
openrig:
|
||||
stage: shipped
|
||||
@@ -11,8 +11,10 @@ metadata:
|
||||
Living Notes UI projects — the convention sections, the proof-contract
|
||||
pairing, the two staged-approval locks, C1 proof drops, and the three
|
||||
role contracts. Conventions SSOT: docs/reference/sdlc-conventions.md
|
||||
(shipped with the CLI package). The deterministic backstop is the
|
||||
`rig scope audit` classifier.
|
||||
in the repo; on an installed package the daemon materializes the same
|
||||
document at $OPENRIG_HOME/reference/sdlc-conventions.md (default
|
||||
~/.openrig/reference/sdlc-conventions.md). The deterministic backstop
|
||||
is the `rig scope audit` classifier.
|
||||
sibling_skills:
|
||||
- queue-handoff
|
||||
- seat-continuity-and-handover
|
||||
@@ -21,7 +23,7 @@ metadata:
|
||||
|
||||
# Mission/Slice SOP — how you work a mission & slice
|
||||
|
||||
Use this skill to actually **do** mission/slice work the way OpenRig expects: author the convention sections, track on the canonical files, prove on them, hand off through them, and survive compaction on them. **Do the work described here; do not merely explain the protocol.** The deterministic backstop is `rig scope audit` — the audit classifier is the source of truth for adherence. The conventions themselves live in ONE place: **`docs/reference/sdlc-conventions.md`** (shipped with the CLI package) — this skill teaches the flow; the SSOT defines the formats.
|
||||
Use this skill to actually **do** mission/slice work the way OpenRig expects: author the convention sections, track on the canonical files, prove on them, hand off through them, and survive compaction on them. **Do the work described here; do not merely explain the protocol.** The deterministic backstop is `rig scope audit` — the audit classifier is the source of truth for adherence. The conventions themselves live in ONE document: **`docs/reference/sdlc-conventions.md`** in the repo, materialized by the daemon at **`$OPENRIG_HOME/reference/sdlc-conventions.md`** (default `~/.openrig/reference/sdlc-conventions.md`) on an installed package — this skill teaches the flow; the SSOT defines the formats.
|
||||
|
||||
## The SDLC flow (intent → proof)
|
||||
|
||||
@@ -110,4 +112,4 @@ When you `rig capture` a pane, **greyed / ghost autocomplete suggestions are NOT
|
||||
- **Finishing a slice?** → every proof-contract item has curated evidence via `rig proof add … --evidences --media` (C1 drops — never only hand-placed files)? PROGRESS updated? MISSION_NOTES `§1` refreshed? proof locked (`--scope delivery`)? Handed off via queue?
|
||||
- **Committing?** → PROGRESS updated?
|
||||
- **Compacting?** → filed your state in MISSION_NOTES?
|
||||
- **Starting on a mission?** → read the mission README (incl. this SOP) + MISSION_NOTES + `docs/reference/sdlc-conventions.md`?
|
||||
- **Starting on a mission?** → read the mission README (incl. this SOP) + MISSION_NOTES + the conventions SSOT (`docs/reference/sdlc-conventions.md` in the repo, `$OPENRIG_HOME/reference/sdlc-conventions.md` on an installed package)?
|
||||
@@ -565,7 +565,7 @@ Composes with slice 33's `progress` + scaffolding to make `rig scope` the **dete
|
||||
|
||||
### The SDLC control plane — convention sections, the two locks, `rig proof` (v0.4.4)
|
||||
|
||||
The Living Notes UI is a plain projection of well-formed on-disk markdown. The conventions live in ONE shipped document — **`docs/reference/sdlc-conventions.md`** (in the CLI package) — and the operating procedure is the **`mission-slice-sop`** skill. The command surface:
|
||||
The Living Notes UI is a plain projection of well-formed on-disk markdown. The conventions live in ONE shipped document — **`docs/reference/sdlc-conventions.md`** in the repo, materialized by the daemon at **`$OPENRIG_HOME/reference/sdlc-conventions.md`** (default `~/.openrig/reference/sdlc-conventions.md`) on an installed package — and the operating procedure is the **`mission-slice-sop`** skill. The command surface:
|
||||
|
||||
```bash
|
||||
rig scope slice create <mission> <slug> [--template <kind>] # scaffolds ## Intent / ## Mini-requirements / ## Proof contract
|
||||
|
||||
@@ -18,4 +18,4 @@ Ship features that solve real customer problems with evidence-backed requirement
|
||||
|
||||
## Mission/slice tracking (the SDLC)
|
||||
|
||||
Requirements and delivery are tracked as missions and slices — on-disk markdown the Living Notes UI projects. Load the packaged `mission-slice-sop` skill; the conventions live in `docs/reference/sdlc-conventions.md` (shipped with the CLI package). PM's leg of the flow: record intent verbatim, author the mini-requirements (the one-glance tier where approval starts) + the proof contract (promised deliverables as observable outcomes; UI deliverables name their planned mockup), then plan-lock with `rig scope slice approve --scope spec`. Proof-lock (`--scope delivery`) is the terminal sign-off after QA's visual compare and `rig proof add … --media` drops (the C1 drop verb).
|
||||
Requirements and delivery are tracked as missions and slices — on-disk markdown the Living Notes UI projects. Load the packaged `mission-slice-sop` skill; the conventions live in `docs/reference/sdlc-conventions.md` (installed: `$OPENRIG_HOME/reference/sdlc-conventions.md`; shipped with the CLI package). PM's leg of the flow: record intent verbatim, author the mini-requirements (the one-glance tier where approval starts) + the proof contract (promised deliverables as observable outcomes; UI deliverables name their planned mockup), then plan-lock with `rig scope slice approve --scope spec`. Proof-lock (`--scope delivery`) is the terminal sign-off after QA's visual compare and `rig proof add … --media` drops (the C1 drop verb).
|
||||
@@ -138,4 +138,4 @@ This is the advanced product-team lane. Use it when the work needs richer coordi
|
||||
|
||||
## Mission/slice tracking (the SDLC)
|
||||
|
||||
Work is tracked as missions and slices — on-disk markdown the Living Notes UI projects. Load the packaged `mission-slice-sop` skill before authoring or building a slice; the conventions (section names, proof contract, the two locks, C1 proof headers) live in `docs/reference/sdlc-conventions.md` (shipped with the CLI package). The short form: record intent → author mini-requirements + a proof contract (→ mockups for UI slices) → plan-lock (`rig scope slice approve --scope spec`) → build the locked set → QA visually compares planned vs delivered → `rig proof add … --evidences --media` drops (the C1 drop verb — never hand-place evidence) → proof-lock (`--scope delivery`). `rig scope audit` is the advisory backstop — fix the flag, don't suppress it.
|
||||
Work is tracked as missions and slices — on-disk markdown the Living Notes UI projects. Load the packaged `mission-slice-sop` skill before authoring or building a slice; the conventions (section names, proof contract, the two locks, C1 proof headers) live in `docs/reference/sdlc-conventions.md` (installed: `$OPENRIG_HOME/reference/sdlc-conventions.md`; shipped with the CLI package). The short form: record intent → author mini-requirements + a proof contract (→ mockups for UI slices) → plan-lock (`rig scope slice approve --scope spec`) → build the locked set → QA visually compares planned vs delivered → `rig proof add … --evidences --media` drops (the C1 drop verb — never hand-place evidence) → proof-lock (`--scope delivery`). `rig scope audit` is the advisory backstop — fix the flag, don't suppress it.
|
||||
@@ -403,7 +403,7 @@ export function classifyScopeItem(input: ScopeAuditInput): ScopeAuditResult {
|
||||
severity: "low",
|
||||
path: childPath(input.path, "README.md"),
|
||||
message: "Slice README has no `## Intent` section, so the Living Notes UI cannot project its INTENT section.",
|
||||
remediation: "Add `## Intent` carrying the recorded intent verbatim (conventions SSOT: docs/reference/sdlc-conventions.md; `rig scope slice create` scaffolds it).",
|
||||
remediation: "Add `## Intent` carrying the recorded intent verbatim (conventions SSOT: docs/reference/sdlc-conventions.md (installed: $OPENRIG_HOME/reference/sdlc-conventions.md); `rig scope slice create` scaffolds it).",
|
||||
});
|
||||
}
|
||||
|
||||
@@ -456,7 +456,7 @@ export function classifyScopeItem(input: ScopeAuditInput): ScopeAuditResult {
|
||||
message: miniBody === null
|
||||
? "No `## Mini-requirements` section — the Living Notes PLAN section has no concise requirements tier to project."
|
||||
: "`## Mini-requirements` carries no numbered items (`1. …`) — the one-glance requirement tier is where approval starts.",
|
||||
remediation: "Add `## Mini-requirements` with a numbered list of observable outcomes (conventions SSOT: docs/reference/sdlc-conventions.md; for a small slice this may BE the whole PRD).",
|
||||
remediation: "Add `## Mini-requirements` with a numbered list of observable outcomes (conventions SSOT: docs/reference/sdlc-conventions.md (installed: $OPENRIG_HOME/reference/sdlc-conventions.md); for a small slice this may BE the whole PRD).",
|
||||
});
|
||||
}
|
||||
}
|
||||
@@ -482,7 +482,7 @@ export function classifyScopeItem(input: ScopeAuditInput): ScopeAuditResult {
|
||||
message: contractBody === null
|
||||
? "No `## Proof contract` section — the DELIVERED pairing has no promised-deliverables source to join proof against."
|
||||
: "`## Proof contract` carries no checkbox deliverables (`- [ ] …`) — the DELIVERED pairing joins proof against those items.",
|
||||
remediation: "Add `## Proof contract` with one checkbox line per promised deliverable, written as an observable outcome (conventions SSOT: docs/reference/sdlc-conventions.md).",
|
||||
remediation: "Add `## Proof contract` with one checkbox line per promised deliverable, written as an observable outcome (conventions SSOT: docs/reference/sdlc-conventions.md (installed: $OPENRIG_HOME/reference/sdlc-conventions.md)).",
|
||||
});
|
||||
}
|
||||
|
||||
@@ -503,7 +503,7 @@ export function classifyScopeItem(input: ScopeAuditInput): ScopeAuditResult {
|
||||
severity: "info",
|
||||
path: childPath(input.path, "README.md"),
|
||||
message: "Slice declares an Intent visual (UI slice) but no mockup reference is present — a UI slice with no mockup in its locked set is an incomplete plan.",
|
||||
remediation: "Attach the planned mockup: an image ref in `## Intent visual` or a plannedRef on the proof-contract deliverable (conventions SSOT: docs/reference/sdlc-conventions.md §3).",
|
||||
remediation: "Attach the planned mockup: an image ref in `## Intent visual` or a plannedRef on the proof-contract deliverable (conventions SSOT: docs/reference/sdlc-conventions.md §3 (installed: $OPENRIG_HOME/reference/sdlc-conventions.md §3)).",
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@@ -257,7 +257,7 @@ slice: ${slice.id}
|
||||
function sliceProof(slice: DefaultSlice): string {
|
||||
return `# PROOF — ${slice.dotId} ${slice.title}
|
||||
|
||||
> **WHO/WHEN:** the impl/QA pair that worked the slice, at slice-close — a slice is NOT done until this file exists and every proof-contract item has evidence (mapped 1:1, artifacts under \`proof/\`). See the \`mission-slice-sop\` skill + the conventions SSOT (\`docs/reference/sdlc-conventions.md\`).
|
||||
> **WHO/WHEN:** the impl/QA pair that worked the slice, at slice-close — a slice is NOT done until this file exists and every proof-contract item has evidence (mapped 1:1, artifacts under \`proof/\`). See the \`mission-slice-sop\` skill + the conventions SSOT (\`docs/reference/sdlc-conventions.md (installed: $OPENRIG_HOME/reference/sdlc-conventions.md)\`).
|
||||
>
|
||||
> **HOW (the drop verb, not hand-placement):** put media files under \`proof/\`, then ATTACH them with \`rig proof add ${slice.dotId} --artifact-type qa --verdict PASS --candidate-sha <tip> --money-evidence "<one line>" --evidences "1" --media "screenshot-01.png"\` — the drop writes the C1 header the Living Notes DELIVERED pairing joins on. Hand-placing files without a drop leaves the deliverable unpaired and \`unverified\`.
|
||||
|
||||
@@ -306,7 +306,7 @@ ${slice.objective}
|
||||
- [ ] Queue items include enough body or tag context to link back to \`${slice.id}\`.
|
||||
- [ ] Proof artifacts are referenced from the slice before closure (drop via \`rig proof add\`).
|
||||
|
||||
> Conventions SSOT: \`docs/reference/sdlc-conventions.md\` — section names, proof-contract format, the two locks, C1 headers. For a small slice the mini-requirements may BE the whole PRD.
|
||||
> Conventions SSOT: \`docs/reference/sdlc-conventions.md (installed: $OPENRIG_HOME/reference/sdlc-conventions.md)\` — section names, proof-contract format, the two locks, C1 headers. For a small slice the mini-requirements may BE the whole PRD.
|
||||
`;
|
||||
}
|
||||
|
||||
|
||||
@@ -535,7 +535,7 @@ export function checkSdlcConventionSections(opts: CheckSliceDocsInput): DoctorCh
|
||||
status: "warn",
|
||||
message: `${offenders.length} slice README${offenders.length === 1 ? " is" : "s are"} missing SDLC convention sections (Intent / Mini-requirements / Proof contract) and will not fully project in the Living Notes UI`,
|
||||
fixHint:
|
||||
"add the missing sections per docs/reference/sdlc-conventions.md (rig scope slice create scaffolds them); run rig scope audit <mission> for per-slice findings — advisory only, nothing is blocked",
|
||||
"add the missing sections per docs/reference/sdlc-conventions.md (installed: $OPENRIG_HOME/reference/sdlc-conventions.md) (rig scope slice create scaffolds them); run rig scope audit <mission> for per-slice findings — advisory only, nothing is blocked",
|
||||
evidence: { missionsRoot, slicesChecked, offenders },
|
||||
};
|
||||
}
|
||||
|
||||
@@ -23,6 +23,22 @@ const PLUGIN_COPY = path.join(
|
||||
"packages/daemon/assets/plugins/openrig-core/skills/mission-slice-sop/SKILL.md",
|
||||
);
|
||||
|
||||
// aa922842 — openrig-user is the SECOND skill whose canonical and bundled-plugin copies both
|
||||
// carry the conventions pointer, so the dual-context rewrite edits both. Unlike
|
||||
// mission-slice-sop it had NO byte-parity guard: mirror-skills covers specs → _canonical, and
|
||||
// the S2 test above covered specs → plugin for exactly one skill. Verified by negative search
|
||||
// over packages/*/test (openrig-core-plugin.test.ts asserts tree existence, not byte parity;
|
||||
// skill-audit.test.ts has no equality assertion). Editing an unguarded pair is how the repo
|
||||
// ends up correct while the shipped plugin ships stale — pin it before touching it.
|
||||
const PARITY_PINNED_SKILLS = ["mission-slice-sop", "openrig-user"] as const;
|
||||
|
||||
function canonicalPath(skill: string): string {
|
||||
return path.join(repoRoot, `packages/daemon/specs/agents/shared/skills/core/${skill}/SKILL.md`);
|
||||
}
|
||||
function pluginPath(skill: string): string {
|
||||
return path.join(repoRoot, `packages/daemon/assets/plugins/openrig-core/skills/${skill}/SKILL.md`);
|
||||
}
|
||||
|
||||
describe("OPR.0.4.4.23 mission-slice-sop plugin byte-parity (S2 drift guard)", () => {
|
||||
it("both copies exist", () => {
|
||||
expect(fs.existsSync(CANONICAL_SOURCE), `missing ${CANONICAL_SOURCE}`).toBe(true);
|
||||
@@ -38,3 +54,79 @@ describe("OPR.0.4.4.23 mission-slice-sop plugin byte-parity (S2 drift guard)", (
|
||||
).toBe(true);
|
||||
});
|
||||
});
|
||||
|
||||
describe("aa922842 canonical→plugin byte-parity, extended to every conventions-carrying skill", () => {
|
||||
for (const skill of PARITY_PINNED_SKILLS) {
|
||||
it(`${skill}: canonical and bundled plugin copies both exist`, () => {
|
||||
expect(fs.existsSync(canonicalPath(skill)), `missing ${canonicalPath(skill)}`).toBe(true);
|
||||
expect(fs.existsSync(pluginPath(skill)), `missing ${pluginPath(skill)}`).toBe(true);
|
||||
});
|
||||
|
||||
it(`${skill}: bundled plugin copy is byte-identical to canonical`, () => {
|
||||
const source = fs.readFileSync(canonicalPath(skill));
|
||||
const plugin = fs.readFileSync(pluginPath(skill));
|
||||
expect(
|
||||
source.equals(plugin),
|
||||
`${skill} drifted between the canonical skill source and the bundled plugin — refresh the plugin copy byte-for-byte (cp source → plugin). mirror-skills does NOT cover this pair; hand-edited divergence is banned.`,
|
||||
).toBe(true);
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
// aa922842 — the skill description is a RETRIEVAL surface: a runtime reads it to decide
|
||||
// whether to load the skill, so it competes for a byte budget with every other skill's
|
||||
// description. At 701 UTF-8 bytes this one was the outlier. Trimming it is only safe if the
|
||||
// terms that make it findable survive — a shorter description that drops "proof-lock" is a
|
||||
// skill that silently stops being retrieved for proof-lock work. Budget and trigger set are
|
||||
// pinned together for that reason: neither is safe alone.
|
||||
const DESCRIPTION_BUDGET_BYTES = 500;
|
||||
|
||||
// Guard-named trigger set (aa922842 ruling). Extend deliberately, never trim to make a
|
||||
// draft fit — a term removed here is retrieval coverage removed from the product.
|
||||
const REQUIRED_TRIGGERS = [
|
||||
"mission",
|
||||
"slice",
|
||||
"proof contract",
|
||||
"plan-lock",
|
||||
"proof-lock",
|
||||
"rig proof",
|
||||
"PROGRESS.md",
|
||||
"PROOF.md",
|
||||
"MISSION_NOTES.md",
|
||||
"handoff",
|
||||
"compaction",
|
||||
];
|
||||
|
||||
/** Extract the frontmatter `description:` value, folding continuation lines. */
|
||||
function readDescription(file: string): string {
|
||||
const text = fs.readFileSync(file, "utf-8");
|
||||
const match = /^description:\s*([\s\S]*?)(?=\n[A-Za-z_-]+:|\n---)/m.exec(text);
|
||||
expect(match, `no frontmatter description: found in ${file}`).not.toBeNull();
|
||||
return match![1].split(/\s+/).filter(Boolean).join(" ");
|
||||
}
|
||||
|
||||
describe("aa922842 mission-slice-sop description budget + trigger preservation", () => {
|
||||
it(`the canonical description fits the ${DESCRIPTION_BUDGET_BYTES}-byte retrieval budget`, () => {
|
||||
const description = readDescription(CANONICAL_SOURCE);
|
||||
const bytes = Buffer.byteLength(description, "utf-8");
|
||||
expect(
|
||||
bytes,
|
||||
`mission-slice-sop description is ${bytes} UTF-8 bytes (${description.length} chars), over the ${DESCRIPTION_BUDGET_BYTES}-byte budget. Trim prose, never a trigger term from REQUIRED_TRIGGERS.`,
|
||||
).toBeLessThanOrEqual(DESCRIPTION_BUDGET_BYTES);
|
||||
});
|
||||
|
||||
it("every named trigger term survives the trim", () => {
|
||||
const description = readDescription(CANONICAL_SOURCE).toLowerCase();
|
||||
const missing = REQUIRED_TRIGGERS.filter((t) => !description.includes(t.toLowerCase()));
|
||||
expect(
|
||||
missing,
|
||||
`mission-slice-sop description lost trigger term(s): ${missing.join(", ")}. The skill will stop being retrieved for that work; restore the term and trim prose instead.`,
|
||||
).toEqual([]);
|
||||
});
|
||||
|
||||
it("the bundled plugin copy carries the same description (budget survives the byte-copy)", () => {
|
||||
// Byte-parity above already implies this, but asserting it directly means a future
|
||||
// refactor that relaxes parity cannot silently ship an over-budget installed skill.
|
||||
expect(readDescription(PLUGIN_COPY)).toBe(readDescription(CANONICAL_SOURCE));
|
||||
});
|
||||
});
|
||||
@@ -1,4 +1,5 @@
|
||||
import { execSync } from "node:child_process";
|
||||
import { existsSync, readFileSync } from "node:fs";
|
||||
import { test } from "node:test";
|
||||
import assert from "node:assert/strict";
|
||||
|
||||
@@ -15,3 +16,72 @@ test("npm pack of @openrig/cli includes scripts/check-abi.mjs in tarball", () =>
|
||||
`scripts/check-abi.mjs missing from npm pack output. Published tarball will fail postinstall.\nFiles found: ${files.filter((f) => f.includes("scripts")).join(", ") || "(none under scripts/)"}`
|
||||
);
|
||||
});
|
||||
|
||||
// aa922842 — the conventions doc reaches agents through a THREE-path model:
|
||||
// repo source docs/reference/sdlc-conventions.md (what repo readers cite)
|
||||
// packed INTERNAL daemon/docs/reference/sdlc-conventions.md (assembly input only —
|
||||
// NEVER taught as a user path)
|
||||
// installed stable $OPENRIG_HOME/reference/sdlc-conventions.md (default ~/.openrig/…)
|
||||
// The daemon materializes the stable path at startup by reading `../docs/reference`
|
||||
// relative to its dist dir (packages/daemon/src/startup.ts), which is exactly why
|
||||
// scripts/build-package.sh stages the docs at daemon/docs/reference/. That internal input
|
||||
// is therefore load-bearing and completely unguarded today: if the copy step regressed, the
|
||||
// stable path would silently stop materializing and every teaching pointer would go stale
|
||||
// with no failing test. This pins it.
|
||||
// HERMETIC BY CONSTRUCTION: packages/cli/daemon is gitignored build output, so any assertion
|
||||
// that reads it (or runs `npm pack` against it) passes on a developer machine with a stale
|
||||
// assembled package and FAILS in a clean checkout before anything is built. This test therefore
|
||||
// asserts the three contracts that make the stable path work, using only git-tracked inputs,
|
||||
// and never runs or mutates the real package build.
|
||||
test("build-package stages the conventions doc as the daemon's stable-path input, and the package allowlist ships it", () => {
|
||||
const buildScript = readFileSync("scripts/build-package.sh", "utf-8");
|
||||
|
||||
// (a) STAGING CONTRACT — build-package must stage the repo's docs/reference into
|
||||
// daemon/docs/reference. The daemon resolves `../docs/reference` from its dist dir at
|
||||
// startup to materialize $OPENRIG_HOME/reference/; if this staging is dropped or
|
||||
// retargeted, the stable agent-facing path silently stops existing.
|
||||
assert.match(
|
||||
buildScript,
|
||||
/mkdir -p "\$CLI_DIR\/daemon\/docs\/reference"/,
|
||||
"scripts/build-package.sh no longer creates daemon/docs/reference — the daemon's startup resolver (../docs/reference) would find nothing and $OPENRIG_HOME/reference/ would never materialize."
|
||||
);
|
||||
assert.match(
|
||||
buildScript,
|
||||
/cp -r "\$REPO_ROOT\/docs\/reference\/"\* "\$CLI_DIR\/daemon\/docs\/reference\/"/,
|
||||
"scripts/build-package.sh no longer copies docs/reference verbatim into the staged package. Byte preservation is what makes the shipped conventions doc trustworthy — a transforming copy (sed/awk/envsubst) would let installed agents read something the repo never said."
|
||||
);
|
||||
|
||||
// (b) INCLUSION CONTRACT — npm only publishes what the files allowlist names. Staging into
|
||||
// daemon/ is useless if "daemon" is not published.
|
||||
const pkg = JSON.parse(readFileSync("packages/cli/package.json", "utf-8"));
|
||||
assert.ok(
|
||||
Array.isArray(pkg.files) && pkg.files.includes("daemon"),
|
||||
`packages/cli package.json "files" must include "daemon" or nothing staged there is published. Found: ${JSON.stringify(pkg.files)}`
|
||||
);
|
||||
|
||||
// (c) SOURCE CONTRACT — the doc being staged must actually exist in the repo and be
|
||||
// non-trivial. This is the git-tracked input; everything above is plumbing around it.
|
||||
const repoDoc = readFileSync("docs/reference/sdlc-conventions.md");
|
||||
assert.ok(
|
||||
repoDoc.length > 1000,
|
||||
`docs/reference/sdlc-conventions.md is ${repoDoc.length}B — implausibly small for the conventions SSOT; staging would ship a truncated doc.`
|
||||
);
|
||||
});
|
||||
|
||||
// OPPORTUNISTIC, never required: when an assembled package happens to be present, verify the
|
||||
// staged copy really is byte-identical. Skipped (not failed) in a clean checkout, so this
|
||||
// cannot make `npm run test:repo` depend on build state — the contracts above are the
|
||||
// hermetic guarantee; this is the belt-and-braces check on an actual artifact.
|
||||
test("staged conventions doc is byte-identical to the repo source (skipped when no assembled package present)", (t) => {
|
||||
const staged = "packages/cli/daemon/docs/reference/sdlc-conventions.md";
|
||||
if (!existsSync(staged)) {
|
||||
t.skip("no assembled package at packages/cli/daemon — run scripts/build-package.sh to exercise this check");
|
||||
return;
|
||||
}
|
||||
const repoDoc = readFileSync("docs/reference/sdlc-conventions.md");
|
||||
const stagedDoc = readFileSync(staged);
|
||||
assert.ok(
|
||||
repoDoc.equals(stagedDoc),
|
||||
`${staged} is not byte-identical to docs/reference/sdlc-conventions.md (repo ${repoDoc.length}B vs staged ${stagedDoc.length}B). Re-run scripts/build-package.sh; a drifted staged copy teaches installed agents stale conventions.`
|
||||
);
|
||||
});
|
||||
@@ -1,6 +1,6 @@
|
||||
---
|
||||
name: mission-slice-sop
|
||||
description: Use when working a mission or slice — the full SDLC flow (intent → mini-requirements + proof contract → mockups → plan-lock → build → QA visual compare → `rig proof` drops → proof-lock) plus how to track, prove, hand off, and carry state across agents and compaction via the canonical files (PROGRESS.md / PROOF.md / MISSION_NOTES.md / MISSION_BRIEF.md / README.md / IMPLEMENTATION-PRD.md). Covers the convention sections the Living Notes UI projects, the two locks, the three role contracts, per-file WHO/WHEN/HOW rules, the four-legs lifecycle, hot-potato queue handoffs, the moment-of-truth checklist, the deterministic `rig scope audit` backstop, and the ghost-text capture gotcha.
|
||||
description: "Use when working a mission or slice: the SDLC flow (intent -> mini-requirements + proof contract -> mockups -> plan-lock -> build -> QA -> `rig proof` drops -> proof-lock), and how to track, prove, and hand off state across agents and compaction via PROGRESS.md / PROOF.md / MISSION_NOTES.md. Covers the two locks, role contracts, hot-potato queue handoff, and the `rig scope audit` backstop."
|
||||
metadata:
|
||||
openrig:
|
||||
stage: shipped
|
||||
@@ -11,8 +11,10 @@ metadata:
|
||||
Living Notes UI projects — the convention sections, the proof-contract
|
||||
pairing, the two staged-approval locks, C1 proof drops, and the three
|
||||
role contracts. Conventions SSOT: docs/reference/sdlc-conventions.md
|
||||
(shipped with the CLI package). The deterministic backstop is the
|
||||
`rig scope audit` classifier.
|
||||
in the repo; on an installed package the daemon materializes the same
|
||||
document at $OPENRIG_HOME/reference/sdlc-conventions.md (default
|
||||
~/.openrig/reference/sdlc-conventions.md). The deterministic backstop
|
||||
is the `rig scope audit` classifier.
|
||||
sibling_skills:
|
||||
- queue-handoff
|
||||
- seat-continuity-and-handover
|
||||
@@ -21,7 +23,7 @@ metadata:
|
||||
|
||||
# Mission/Slice SOP — how you work a mission & slice
|
||||
|
||||
Use this skill to actually **do** mission/slice work the way OpenRig expects: author the convention sections, track on the canonical files, prove on them, hand off through them, and survive compaction on them. **Do the work described here; do not merely explain the protocol.** The deterministic backstop is `rig scope audit` — the audit classifier is the source of truth for adherence. The conventions themselves live in ONE place: **`docs/reference/sdlc-conventions.md`** (shipped with the CLI package) — this skill teaches the flow; the SSOT defines the formats.
|
||||
Use this skill to actually **do** mission/slice work the way OpenRig expects: author the convention sections, track on the canonical files, prove on them, hand off through them, and survive compaction on them. **Do the work described here; do not merely explain the protocol.** The deterministic backstop is `rig scope audit` — the audit classifier is the source of truth for adherence. The conventions themselves live in ONE document: **`docs/reference/sdlc-conventions.md`** in the repo, materialized by the daemon at **`$OPENRIG_HOME/reference/sdlc-conventions.md`** (default `~/.openrig/reference/sdlc-conventions.md`) on an installed package — this skill teaches the flow; the SSOT defines the formats.
|
||||
|
||||
## The SDLC flow (intent → proof)
|
||||
|
||||
@@ -110,4 +112,4 @@ When you `rig capture` a pane, **greyed / ghost autocomplete suggestions are NOT
|
||||
- **Finishing a slice?** → every proof-contract item has curated evidence via `rig proof add … --evidences --media` (C1 drops — never only hand-placed files)? PROGRESS updated? MISSION_NOTES `§1` refreshed? proof locked (`--scope delivery`)? Handed off via queue?
|
||||
- **Committing?** → PROGRESS updated?
|
||||
- **Compacting?** → filed your state in MISSION_NOTES?
|
||||
- **Starting on a mission?** → read the mission README (incl. this SOP) + MISSION_NOTES + `docs/reference/sdlc-conventions.md`?
|
||||
- **Starting on a mission?** → read the mission README (incl. this SOP) + MISSION_NOTES + the conventions SSOT (`docs/reference/sdlc-conventions.md` in the repo, `$OPENRIG_HOME/reference/sdlc-conventions.md` on an installed package)?
|
||||
@@ -565,7 +565,7 @@ Composes with slice 33's `progress` + scaffolding to make `rig scope` the **dete
|
||||
|
||||
### The SDLC control plane — convention sections, the two locks, `rig proof` (v0.4.4)
|
||||
|
||||
The Living Notes UI is a plain projection of well-formed on-disk markdown. The conventions live in ONE shipped document — **`docs/reference/sdlc-conventions.md`** (in the CLI package) — and the operating procedure is the **`mission-slice-sop`** skill. The command surface:
|
||||
The Living Notes UI is a plain projection of well-formed on-disk markdown. The conventions live in ONE shipped document — **`docs/reference/sdlc-conventions.md`** in the repo, materialized by the daemon at **`$OPENRIG_HOME/reference/sdlc-conventions.md`** (default `~/.openrig/reference/sdlc-conventions.md`) on an installed package — and the operating procedure is the **`mission-slice-sop`** skill. The command surface:
|
||||
|
||||
```bash
|
||||
rig scope slice create <mission> <slug> [--template <kind>] # scaffolds ## Intent / ## Mini-requirements / ## Proof contract
|
||||
|
||||
Reference in new issue
Block a user