Skip to content

open_decision

Open a new dated decision doc in the target repo’s docs/decisions/. Creates a PR adding a single file conforming to the repo’s decision-doc template. The doc is opened in ‘open’ status with sign-off block awaiting human countersign.

Upholds: MR-4 · MR-7 Side effects: Creates a branch petrova/open-decision/ in target_repo, adds docs/decisions/-.md, opens a PR.

  • REPO_IN_REGISTRY — target_repo must appear in registry.yaml.
  • SLUG_KEBAB_LOWERCASE_LE6_WORDS — slug must match ^[a-z0-9]+(-[a-z0-9]+){0,5}$ — kebab-case, lowercase, ≤6 hyphen-delimited segments.
  • DATE_MATCHES_TODAY — date must be the current UTC date at execution time. Backdating decision docs is forbidden by MR-4 / MR-7.
  • ALTERNATIVES_GE_2 — alternatives_considered array must contain ≥2 entries (decision-doc convention).
  • FILE_DOES_NOT_EXIST — target path docs/decisions/-.md must not already exist in target_repo’s default_branch.
  • SUPERSEDES_RESOLVES — If supersedes is non-empty, every path listed must exist in target_repo and reference a closed or superseded decision doc.
  • title string (required)
  • slug string (required)
  • dateIsoDate (required)
  • supersedes array
  • context string (required)
  • decision string (required)
  • alternatives_considered array (required)
    • items:
      • name string (required)
      • rejection_reason string (required)
  • consequences object
    • code array
    • docs array
    • phases array
    • invariants array
  • references array
  • status string enum: open, closed — Almost always ‘open’ at creation time. ‘closed’ only allowed when caller has the human countersign already and includes it in sign_off.
  • sign_off object
    • subagent string
    • human string
  • decision_doc_path string
  • prPRRef
  • diff_previewDiffPreview

Input:

{
"envelope": {
"verb": "open_decision",
"target_repo": "kahn-hq",
"idempotency_key": "a3f29c4b1e8d76024b5a8c7f1e2d3a4b5c6d7e8f9a0b1c2d3e4f5a6b7c8d9e0f",
"dry_run": true,
"actor": "human:alex@devarno.com",
"triggered_by": {
"kind": "phase_close",
"ref": "Phase-7"
}
},
"params": {
"title": "Phase 7 close-out",
"slug": "phase-7-close",
"date": "2026-04-29",
"context": "Phase 7 (SPA consumer-readiness) implementation closed 2026-04-28; this doc records the close-out classification of friction surfaced in M7.8.1.",
"decision": "Phase 7 closes with M7.8.2 (operator-driven re-probe) deferred to Phase 8. Five hot gaps delivered; cold/n-a gaps stay candidate.",
"alternatives_considered": [
{
"name": "Extend Phase 7 to absorb M7.8.2 friction",
"rejection_reason": "Violates MR-2 — friction surfaced in a phase becomes the next phase's input, not a retrofit."
},
{
"name": "Close Phase 7 without verification round",
"rejection_reason": "Violates MR-10 — verification round is mandatory at phase close."
}
],
"consequences": {
"phases": [
"Phase 7 closed",
"Phase 8 opens with M7.8.2 input"
],
"invariants": []
}
}
}

Output (output_dry_run):

{
"envelope": {
"verb": "open_decision",
"status": "dry_run",
"idempotency_key": "a3f29c4b1e8d76024b5a8c7f1e2d3a4b5c6d7e8f9a0b1c2d3e4f5a6b7c8d9e0f",
"mr_citations": [
"MR-4",
"MR-7"
]
},
"result": {
"decision_doc_path": "docs/decisions/2026-04-29-phase-7-close.md",
"diff_preview": {
"files": [
{
"path": "docs/decisions/2026-04-29-phase-7-close.md",
"operation": "create",
"size_bytes": 1842
}
],
"branch": "petrova/open-decision/phase-7-close",
"commit_message": "decision: phase-7-close (idempotency: a3f29c4b1e8d7602)"
}
}
}

Schema: spec/verbs/open_decision.schema.json Upholds: MR-4 (ISO dates), MR-7 (append-only). Emits: PR adding docs/decisions/<today>-<slug>.md to target repo.

  • Recording any architectural call, scope change, supersession, or phase transition’s decision portion (paired with start_phase / close_phase for those).
  • Any change that needs a paper trail beyond a commit message.
{
"title": "<Imperative phrasing of the decision>",
"slug": "<kebab-case-le-6-words>",
"context": "<What surfaced the decision. Cite the trigger.>",
"decision": "<What was decided. One paragraph.>",
"alternatives_considered": [
{"name": "<alt-1>", "rejection_reason": "<one sentence>"},
{"name": "<alt-2>", "rejection_reason": "<one sentence>"}
]
}

Optional:

  • consequences: { code: [], docs: [], phases: [], invariants: [] }
  • references: [ "<doc path or external URL>" ]
  • supersedes: [ "<docs/decisions/YYYY-MM-DD-old-slug.md>" ]
  • sign_off: { subagent, human } — usually defer; doc opens in open status.
  • slug must match ^[a-z0-9]+(-[a-z0-9]+){0,5}$.
  • alternatives_considered length ≥ 2.
  • date (auto-derived) must be today’s UTC date.
  • docs/decisions/<date>-<slug>.md must not exist on default branch (live check on apply).
Terminal window
cat > /tmp/petrova-input.json <<'JSON'
{
"title": "Switch RLS enforcement to Postgres policies",
"slug": "rls-via-postgres-policies",
"context": "RLS via app-layer middleware drifts from auth tables; 2026-04-29 finding 20260429-1100-rls-drift.md surfaced 3 missed checks.",
"decision": "Move RLS enforcement to Postgres policies on a per-tenant basis. Middleware retains read-only audit trail.",
"alternatives_considered": [
{"name": "Status quo (middleware-only RLS)", "rejection_reason": "Drift incidents already in production."},
{"name": "Reverse: drop middleware, policies-only", "rejection_reason": "Loses audit trail useful for incident review."}
],
"consequences": {
"code": ["backend/auth/middleware.ts simplifies to read-only", "migrations 0042-0045 add policies"],
"docs": ["docs/decisions/2026-04-29-rls-via-postgres-policies.md (this doc)"]
}
}
JSON
petrova open_decision kahn-hq --input /tmp/petrova-input.json

The doc opens in open status with <<pending>> sign-off. Closing the decision requires the human to countersign — either by editing the file (creates a follow-up commit on the PR) or by re-invoking open_decision with status: "closed" + sign_off.human populated.