# Design choices

The decisions that shaped open-scaffold and why. Every entry here is a fork in the road we explicitly chose, not a default we stumbled into. Read this if you want to understand what the scaffold *is*, not just what it does.

## The decisions

**Why CLAUDE.md and AGENTS.md are hand-duplicated instead of generated.** Because a build script that breaks in six months is worse than two files that might drift in six months. Drift you notice on the next read; a broken generator rots silently. The paired-view header in each file tells you to mirror edits, and if drift happens three times in the first year, we revisit.

**Why orchestration is adapter-mediated, not embedded in the core.** The plan's `Execution strategy` section is a portable contract. Generic open-scaffold stores and parses that contract under `.osc/`; runtime adapters translate it into runtime-native handoffs or spawning. This keeps the core portable across OMC, OMX, Cursor, plain Claude/Codex, or a human in a terminal. Open Scaffold should expose runtime selection in run packets, but core should not depend on old adapter repositories or claim they are first-class packages.

**Why executable Open Scaffold starts with an agentic runtime package, not hidden core spawning.** The owner accepted that Open Scaffold should become executable, but the product strength is still source-of-truth-first evidence and auditability. The first executable boundary is an in-repo GitHub source package, `packages/runtime-omx/`, targeting OMX / oh-my-codex with `$ralplan` first. It is not part of the root `open-scaffold` npm payload today. Core continues to create run packets and evidence expectations; the package proves dry-run/receipt behavior first and may only launch real runtime work behind explicit opt-in gates. (The layer doc was archived 2026-06-10; see git history.)

**Translation policy: translated agent entry points are best-effort and English-canonical.** `AGENTS.md` and `CLAUDE.md` are translated into `zh`, `ja`, `ko`, `es`, and `pt` as machine-assisted entry points for non-English-speaking developers and coding agents. The English files remain canonical. Translations preserve the same `##` heading structure and factual claims, but discrepancies are documentation bugs to report and fix, not alternate policy.

**Why `osc work` should own the control loop, not a native runtime.** Adoption needs one coherent work command, not manual choreography across plan/run/dispatch/evidence/verify/close. The decision is yes to a safe run-lifecycle controller and no to native core runtime ownership now: core owns plan/package/run/receipt/evidence/verification/human gates; adapters own worker execution, provider auth, spawning, sandbox translation, and runtime sessions. See [`2026-05-28-runtime-control-loop-not-native-runtime.md`](2026-05-28-runtime-control-loop-not-native-runtime.md).

**Why MCP stays an optional integration facet until contracts and gates mature.** `osc mcp serve` is useful as a local read interface over repo truth, but it should not become the execution controller or a write-authority shortcut. Keep it optional/read-oriented now, add versioned schema/conformance work before promising stability, and route any future write-capable MCP surface through the `119` controller gate model. See [`2026-05-29-mcp-integration-surface-posture.md`](2026-05-29-mcp-integration-surface-posture.md).

**Why `osc evolve` v2 starts with analysis, not more execution.** A local 2000m v1 two-lane run tied on raw score and exposed that current `osc evolve` records attempts but does not yet detect plateau, impossible/probe-only criteria, or no-score-moving retries. The next Open Scaffold direction is read-only analysis, benchmark-neutral external scorer import, and compact evidence before controller claims; benchmark design stays owned by the benchmark repo. See [`2026-05-31-osc-evolve-v2-after-2000m.md`](2026-05-31-osc-evolve-v2-after-2000m.md).

**Why Codex uses a `codex` preset backed by the `runtime-omx` adapter.** The user-facing target is `osc work ... --runtime codex`, but the tested adapter path today is OMX / oh-my-codex `$ralplan`. Open Scaffold therefore exposes `codex` as the broad preset, keeps `omx` as the explicit harness-name preset, and defers a separate direct `runtime-codex` package until evidence justifies it. See [`2026-05-26-codex-adapter-naming.md`](2026-05-26-codex-adapter-naming.md).

**Why runtime strategy research is evidence-first.** Open Scaffold core does not own autonomous spawning today, but Milestone 16 treats thin adapter invocation or a sibling runtime as explicit strategic options. The research brief was archived 2026-06-10; see git history. Use [`docs/SPAWNING_BOUNDARY.md`](../SPAWNING_BOUNDARY.md) for the current adapter/runtime boundary and dispatch-receipt direction.

**Why old plan questions are reconciled in new notes instead of edited in place.** Completed plans keep their historical `## Open questions` because those questions show what was unknown at the time. When later PRs answer them, the answer belongs in a new reconciliation note, release/evidence note, roadmap update, or follow-up plan — not in a rewritten done plan. See [`2026-05-18-open-question-reconciliation.md`](2026-05-18-open-question-reconciliation.md).

**Why plans are immutable once committed.** Because edits silently rewrite history. Six weeks from now, you won't remember whether the plan said X all along or whether you quietly switched last Tuesday. The amendment protocol is the trade: when the world changes, write `<plan>-amendment-1.md` next to the plan, add a one-line entry to MISSION.md's changelog, and the original plan stays frozen. Slower in the moment, honest forever after.

**Why mission-first gating is the first thing `verify.sh` checks.** Because everything downstream is meaningless without it. A plan with no mission is a plan for nothing. The check exists so the very first failure mode is impossible to ignore — and so progressive disclosure can hide everything else until the mission is real.
