Skip to main content

2026-06-11 — RFC-006 Required Operating Decisions

Resolves the ten owner decisions listed in RFC-006 §16 before Phase 0 implementation begins. All defaults are calibrated for a solo operator with AI agents; revisit at first hire or when throughput doubles.

Decision 1 — Telemetry store

Question: which existing store replaces daily Git snapshot PRs? Decision: existing stores only — no new system. A new dedicated metrics store (Grafana Cloud, Datadog, etc.) is not justified until monthly recurring revenue exceeds $10k or team size exceeds three engineers. Decision revisits when either threshold is crossed.

Decision 2 — Lifecycle representation

Question: labels vs. a state service for the first implementation. Decision: GitHub issue labels are the canonical lifecycle state representation for Phase 0–2. A state service requires a separate RFC and migration only if label-based implementation proves insufficient at scale. Label namespace: status:<value> — one per issue at all times. Canonical label set (must exist in all monitored repos): status:wip and status:abandoned are retired aliases; label-sync will map existing uses to status:in_progress and status:cancelled respectively.

Decision 3 — Duplicate survivor policy

Question: oldest actionable issue vs. highest-quality issue? Decision: oldest actionable issue is the default survivor. Rationale: predictable, requires no quality judgment, and protects existing assignees and references. Override: an explicit survivor: #NNN comment by @adrper79-dot selects a different canonical issue and is recorded by the dedup controller before closure. A “non-actionable” oldest issue (locked, transferred, missing body) yields to the next oldest actionable issue, not to a quality score.

Decision 4 — Verification classes

Question: which work types require production verification vs. merge verification? Default for unclassified work: code:pr (merge verification). Work class is set by the supervisor template’s workClass: field. Issues without a matched template default to code:pr unless @adrper79-dot sets work-class: <value> in the issue body.

Decision 5 — Initial lease TTLs

Question: how long before a stale claim is released? The TTL clock starts at claimed_at stored in the supervisor claim comment. It does not use issue.updated_at (which is bumped by any label/comment activity and cannot be used as a claim-start signal). Phase 2 will move TTL enforcement to LockDO for atomic expiry. For Phase 0–1, the releaseStaleClaimedIssues sweep reads claimed_at from the claim comment and uses the values above instead of the prior 7-day issue.updated_at heuristic.

Decision 6 — Automation escape-rate threshold

Question: what escape rate triggers a trust-tier demotion? A “severe escape” (production outage, data loss, security exposure) demotes immediately to L0 Observe for the affected action class regardless of rate. Baseline escape rate will be measured during the 14-day Phase 0 observation window before any demotion rules are enforced.

Decision 7 — Lease and transition authority

Question: confirm LockDO for atomic lease/fencing and D1 for receipts. Decision: confirmed.
  • LockDO (supervisor Worker Durable Object) is the sole authority for atomic lease acquisition, fencing token issuance, and lease expiry decisions. Worker-local clocks are never used to decide ownership.
  • D1 (factory-supervisor database) is the append-only store for transition receipts, run history, lease audit log, and template stats.
  • Phase 0–1 exception: until the LockDO lease API is built (Phase 2), the claimed_at timestamp in the supervisor comment is the interim claim record. It is not atomic but is sufficient for a single-agent system.

Decision 8 — Manual override policy

Question: who can override, under what conditions, and how long does it last? Authorized actors: @adrper79-dot only until the team grows to ≥ 3 engineers, at which point a second CODEOWNER may be nominated by ADR amendment. Override types: All override comments are recorded by the lifecycle controller as transition receipts. Automation reconciliation gives precedence to a manual override that has not yet expired.

Decision 9 — Incident recurrence policy

Question: grouping and reopen windows by source. Severity escalation on recurrence:
  • First recurrence within window: add recurrence:1 label; bump priority one level.
  • Second recurrence within window: add recurrence:2; notify @adrper79-dot; escalate to P1 minimum.
  • Third+ recurrence: P0; require postmortem before closure.
A closed Sentry issue reopened by a new occurrence is not “Done” — the lifecycle controller sets it to In Progress (with active assignee) or Intake (unassigned), not Done.

Decision 10 — Work-class profiles (Definition of Ready / Done per class)

Question: proportional Ready and Done evidence for each work class.

Definition of Ready (DoR) — per class

Definition of Done (DoD) — per class

All classes: acceptance criteria from the issue body must be explicitly checked before transitioning to Done. “CI green” alone is never sufficient for code:deploy or incident.

Consequences

  • label-sync.yml must create the eight status:* labels across all monitored repos.
  • project-sync.mjs issue.closed handler must read lifecycle labels before deciding Done vs. Cancelled.
  • supervisor-core.mjs claim comment must embed claimed_at: <ISO> and work-class: <class> so releaseStaleClaimedIssues can apply TTLs from Decision 5 rather than the prior 7-day heuristic.
  • The Project board needs the eight Status options (Intake, Ready, In Progress, In Review, Blocked, Verifying, Done, Cancelled). Todo may remain during migration as an alias for Intake.
  • RFC-006 §16 is now fully resolved. Phase 0 implementation is unblocked.