# Copilot Instructions — [PROJECT NAME] > **Generated by the doc-and-modernize skill (Modernization mode) as an editable starting point.** > Save this at **`.github/copilot-instructions.md`** (the path GitHub Copilot > auto-loads). It encodes the *canonical commands* and the *phase-gating rules* > an agent (or human) must follow while executing `MODERNIZATION_PLAN.md`. Tune > the gates, commands, and branch rules to your project — the placeholders below > are intentionally generic. Delete this note once customized. [PROJECT NAME] is being **modernized**. The safety strategy is **adaptive**: the legacy stack may be partly or wholly dead, so we do **not** assume a fully-green legacy CI gate exists up front. Each component is on the **highest achievable rung of the safety ladder** (L0–L4), has a named **Testability Milestone** (the phase where it first builds, runs, and passes ≥1 test on a supported toolchain), and is labeled **pre-testability ("dark")** or **post-testability ("lit")**. CI is stood up at a named **CI Milestone** (the first lit phase); enforcing it as a required check is a manual human step. See `MODERNIZATION_PLAN.md` for the phase roadmap, per-component testability/rung, the CI Milestone, and the residual-risk register; `ARCHITECTURE.md` for the audited current state. Work one phase at a time; do not advance until the current phase's exit criteria are demonstrably met. ## Commands > Fill from the architecture doc's **Commands & Verification Inventory**. Use > your ecosystem's real runner (npm/yarn/pnpm, `make`, `just`, `cargo`, `go`, > `poetry`/`tox`/`nox`, `gradle`/`mvn`, …). Delete rows that don't apply. | Action | Command | |--------|---------| | Install / restore deps | `` | | Build | `` | | Run / serve locally | `` | | Unit tests (all) | `` | | Single test file | `` | | Single test by name | `` | | Lint | `` | | Format / check | `` / `` | | Typecheck (if applicable) | `` | | End-to-end / smoke (if applicable) | `` | | Contract / characterization tests | `` | CI (``) runs `` on `` for every push and PR. CI was stood up in **phase ``** (the first *lit* phase). **Enforcement is a separate manual step:** until a human turns this workflow into a **required status check / branch-protection rule** (``), CI *runs* on PRs but does **not** *block* merges. > **Keep this table current.** If a phase introduces a new long-term command, > update this table (and confirm it with the user during planning) — don't leave > the canonical command list stale. ## Phase gating (regime-aware; applies to every phase) A phase is **not complete** until its **Verification & Exit Criteria** in `MODERNIZATION_PLAN.md` pass. Those criteria must be: 1. **Objectively verifiable** — runnable commands / captured evidence, not a subjective judgement. 2. **Actually executed and recorded** — run them and note the result in the plan before starting the next phase. 3. **Gated** — do **not** advance to phase N+1 until phase N's criteria are demonstrably met. **Which criteria are valid depends on the component's regime:** - **Post-testability ("lit") phases:** exit on runnable commands / **green CI on the phase's branch/PR — the authoritative signal.** Shared baseline: `` and `` must pass; if the change touched the client / transport / protocol / any public interface, the relevant end-to-end and contract/characterization tests must also stay green. - **Pre-testability ("dark") phases:** the component isn't alive yet, so a green CI test gate is a **category error**. Exit on the phase's achievable **safety-ladder rung** instead — captured seam/oracle snapshots, reversibility scaffolding proven present, a passed smoke checklist, recorded review. **Do not block a dark phase on a test suite that can't run yet.** A blessed **downgrade** to a lower rung (with residual risk named) is a valid exit, not a failure. **Never require a component's automated test gate before it crosses its own Testability Milestone.** Report to the user any phase whose pass/fail is unknown rather than assuming it passed. ## Decisions - When a phase is planned, **all sub-decisions must be resolved and documented** in the plan so implementation needs no further user input. - State **"dropped" vs "deferred"** explicitly for anything cut — don't leave it ambiguous. - Update `MODERNIZATION_PLAN.md` status markers (✅ complete / ⏭️ descoped / 🗑️ dropped) as each phase's exit criteria are met, and **update the safety-ladder rung / residual-risk register** as components cross their Testability Milestone. ## Branching & PRs Each phase is developed on its **own branch** — never commit phase work directly to the default branch (``). Create a new branch at the start of a phase (e.g. `phase-N-`). Once the phase's exit criteria are met and recorded, push the branch and open a PR to the default branch. For **post-testability ("lit")** phases, let CI on the PR be the authoritative green signal before merging. For **pre-testability ("dark")** phases, the PR instead carries the achievable safety-ladder rung's evidence (captured contracts, smoke results, reversibility scaffolding) with residual risk named. **Merge to trunk before the next phase; never stack.** Cut each phase branch **from the trunk (``)**, and **merge its PR to trunk before starting the next phase.** Never base a phase branch or its PR on a *sibling* `phase-N` branch — stacked phase PRs get merged into each other, the trunk silently stalls several phases behind, and later phases are forced into a bind. Before starting a phase, verify the previous phase is merged and `git log origin/..HEAD` is empty at branch creation. **Controlled stacking is allowed only if genuinely unavoidable — and only with a reconciliation PR that lands the stack onto trunk plus an explicit residual-risk note.** > **Confirm the trunk name; retire legacy defaults.** Pin the real trunk > (``). If a second default-ish branch exists (e.g. a legacy > `master` alongside `main`), mark it "history only — do not target" so phase > work never lands on the wrong branch. **Keep the executable docs alive with the code.** Any phase that changes **topology** — module/reactor membership, removed services, renamed branches, changed commands, new/removed endpoints — must update **this file**, the `README`, and any module/topology list **in the same PR**. A stale module list or a hard-coded old-branch link actively misleads the next agent/human. **Register transitional-insecure states.** If a phase intentionally introduces a temporary weak state to stay runnable (permit-all shim, CSRF disabled, an open endpoint, a placeholder secret), record it with the phase that **closes** it and a by-design-until-phase-N note, and scope it as tightly as possible — this preempts recurring scanner/reviewer churn. > **CI enforcement is a manual, human-only step.** An agent can author and run > the CI workflow, but making it a **required status check / branch-protection > rule** so it actually *blocks* merges is a platform-UI/admin action > (``) the agent > cannot perform. Until you configure it, treat "green CI is authoritative" as a > convention you enforce by hand. Do this once, at/after the CI Milestone phase.