# Risk Register: Borrowing from `earthtojake/text-to-cad`

Risks identified while considering which mechanisms to import. Each row is concrete: a specific failure mode, how it could enter `.aieng`, and the mitigation that must be in place *before* the borrowing lands.

Severity: H = identity-changing if it slips; M = damages trust but recoverable; L = ergonomics only.

| # | Risk | Severity | Trigger | Mitigation | Owner gate |
|---|---|---|---|---|---|
| R1 | `.aieng` drifts into text-to-CAD generation | H | An "aieng generate" or "aieng synthesise" verb is added; a skill bundle ships in default install; agent-side authoring becomes recommended | (a) Codify in `docs/core_position.md`: "`.aieng` does not generate CAD geometry. CAD authoring is external." (b) Reject any CLI verb whose name implies geometry synthesis. (c) Const guard in schema: forbid `producer_kind: "aieng_core"` on geometry artifacts. | PR-review checklist |
| R2 | Viewer becomes authoritative state | H | Users edit through viewer UI; viewer caches override JSON; "approve claim" button added | Viewer is read-only by construction. No Python writer modules imported. Lint rule rejects writer imports in viewer module. Footer banner on every page. No "approve / advance / accept" controls. | Phase 18B acceptance |
| R3 | Generated topology mistaken for CAD truth | H | `aag.json`, `topology_map.json`, or `interface_graph.json` are quoted as engineering truth without acknowledging `extraction_mode` | (a) Each derived resource carries explicit `generated_index: true` / `not_source_of_truth: true` / `extraction_mode` provenance. (b) AI summaries surface `extraction_mode` next to feature/topology mentions. (c) Benchmark questions explicitly test the distinction. | Existing (G5+G11); reinforce in 18C |
| R4 | Visual snapshots mistaken for validation evidence | H | Viewer ships PNG export; user attaches snapshot to a claim; evidence ledger accepts it | Schema const guard: `evidence_index` rejects `producer_kind: "aieng_viewer"`. `aieng record-evidence` rejects viewer-source artifacts. Sidecar JSON on every snapshot carries `not_validation_evidence: true`. | Phase 18B; tested by negative test |
| R5 | Claims auto-advance without evidence | H | A CLI helper or viewer button advances `unsupported` → `pass` because heuristics look good; new code path forgets to enforce `auto_advance: false` | (a) `auto_advance: false` is a required field on every claim's `decision_criteria` (G9). (b) `update-claim` requires explicit evidence ref. (c) Validator fails if a claim is `pass` with empty `supported_by`. (d) Benchmark negative test catches auto-advance regressions. | Existing (G9); add benchmark negative test |
| R6 | Heavy dependencies enter default install | M | text-to-cad-style viewer ships Node/Vite/three.js as required; CadQuery becomes required; OCP becomes required | (a) Default install stays pure Python. (b) `[geometry]`, `[mcp]`, `[viewer]` remain optional extras. (c) Viewer MVP uses stdlib HTTP + static HTML/JS, no Node. (d) `pip install aieng` produces a working `aieng validate`. | Phase 18B; CI test on minimal install |
| R7 | Markdown summaries replace structured facts | M | `README_FOR_AI.md` or `ai/summary.md` is quoted by an AI as source-of-truth without consulting the JSON; a future tool only reads the summaries | (a) Summaries explicitly disclaim "derived from `<resource>`; consult that resource for authoritative values." (b) `aieng validate` warns if summary numerics diverge from the source. (c) MCP tools return structured records, not summary text, for tool calls. | Existing discipline; reinforce in docs |
| R8 | Semantic patches confused with executable CAD regeneration | H | An AI assumes a `modify_parameter` patch on a `parameter_source: mock` feature has changed the STEP geometry; `apply-patch` execution record is misread | (a) `editability` and `writeback_strategy` are required fields on every feature. (b) `apply-patch` writes `no_geometry_modified: true` for non-regeneration sources. (c) Validator forbids the patch from changing STEP path. (d) Benchmark question explicitly tests this distinction. | Existing (G7); add benchmark test |
| R9 | Reference notation becomes a query/edit interface | M | `@aieng[...]` grows wildcards, write semantics, or path traversal | Grammar fixes the form. `ref-inspect` is read-only. No write-path through references. Schema does not parse references as queries. | Phase 18A acceptance |
| R10 | Per-agent skill installers proliferate | M | Following text-to-cad's pattern, someone adds `aieng-claude-install.sh`, `aieng-codex-install.sh`, etc. | `.aieng` does not ship per-agent installers. MCP is the only optional access surface. Documented in `core_position.md`. | PR-review checklist |
| R11 | Benchmark inputs become heavy via Git LFS | L | text-to-cad's LFS approach copied; STEP fixtures grow large | All `.aieng` benchmark fixtures are small or generator-script-produced. No LFS. Documented in benchmark scaffold. | Phase 18C acceptance |
| R12 | Cross-resource references silently rot | M | A resource is overwritten with new IDs while another still points at old ones | `ref-check` (Phase 18A) catches dangling refs. `aieng validate` runs `ref-check`. CI fails on dangling refs. | Phase 18A; CI |
| R13 | Adapter capability claims drift from reality | M | A CAD/CAE adapter declares L4 but only achieves L2; downstream AI trusts the declaration | G11 adapter capability declarations are part of the data; benchmark family-specific tests can validate declared vs observed capability. Mismatch surfaces as a validator warning. | Existing (G11); benchmark cross-check |
| R14 | Viewer renders 3D STEP and leaks into authority | H | A contributor adds `cadquery`/`build123d` viewer rendering "just for debugging" | Lint rule in viewer module forbids geometry-kernel imports. Code review checklist. Viewer pages explicitly list "no 3D rendering" as a property. | Phase 18B acceptance |
| R15 | Network/telemetry sneaks into viewer or MCP | M | Analytics, error reporting, or remote help added | Local-first invariant in `core_position.md`. Viewer binds only to 127.0.0.1. No telemetry libraries in dependencies. Tested by `pip install aieng --offline`. | Phase 18B acceptance |
| R16 | Summaries become bilingual / verbose / "agent prompts" | L | An effort to please specific LLMs adds prompt-engineering text to `ai/summary.md` | Summary content is deterministic from structured resources. No model-specific prompt text. Reviewed at PR time. | PR-review checklist |
| R17 | Benchmark questions evolve to favour a specific AI | M | Questions are tuned per model run, biasing the rubric | Questions are versioned with the benchmark scaffold. Rubric changes require a versioned scoring sheet revision. Comparisons across models always use the same version. | Phase 18C acceptance |
| R18 | "Apply patch" inadvertently advances claims | H | `apply-patch` execution record is interpreted by validator as evidence | `auto_advance: false` everywhere. `apply-patch` writes a `patch_execution` record, not an `evidence` record. Schema separates the two record types. Tested. | Existing (G8); reinforce in tests |

## Top three to gate Phase 18 against

- **R1** (text-to-CAD drift) — biggest identity risk.
- **R4** (viewer snapshots as evidence) — biggest viewer risk; must be closed before any viewer extra ships.
- **R5** (auto-advance) — biggest claim-integrity risk; already guarded by G9, must stay guarded as new surfaces appear.

If any of R1, R4, R5 cannot be conclusively closed for a proposed feature, that feature does not ship.
