Skip to content

Latest commit

 

History

History
980 lines (821 loc) · 355 KB

security-ledger.md

File metadata and controls

980 lines (821 loc) · 355 KB

Security Review Ledger

Review ID Date Scope Evidence Findings / disposition Reviewer
SEC-001 2026-08-03 Initial filesystem, MCP, secrets, and AI trust boundaries Path and symlink escape tests; bounded-read tests; secret scan; threat model Read-only MVP accepted. Remote exposure and mutation remain blocked pending dedicated reviews. Initial maintainer
SEC-002 2026-08-03 Python dependency audit pip-audit reported PYSEC-2026-1845 in pytest 8.4.2; the post-upgrade audit found no known vulnerabilities Raised the development dependency floor to pytest 9.0.3; finding remediated and verified. Initial maintainer
SEC-003 2026-08-03 KiCad CLI DRC boundary Injection; process/discovery timeout; in-process report, cumulative-byte, file-count, and non-overlapping snapshot-memory bounds; malformed/incomplete/schema-skew reports; stale-context; side-effect containment; redaction; and real KiCad 10.0.5 integration tests Read-only fixed-argument adapter accepted; a POSIX wrapper sets the file ceiling before KiCad starts and execution occurs on a path-preserving private snapshot so .kicad_prl never enters the source workspace. Unsupported platforms fail closed. Arbitrary arguments, save/refill, and raw finding disclosure remain prohibited. Initial maintainer
SEC-004 2026-08-03 GitHub Actions supply chain Reviewed upstream major-version changes, pinned each action to a full commit SHA, replaced the deprecated provenance wrapper with actions/attest, retained least-privilege job permissions, and passed current-main CI, security, CodeQL, labeler, and dependency-review checks Workflows accepted. Future minor/patch updates are grouped while majors remain isolated for review. Release verification may run manually, while attestation and publication remain restricted to version-tag pushes. Initial maintainer
SEC-005 2026-08-03 v0.1.0 release provenance and recovery Tag run 30762649321; artifact SHA-256 digests; GitHub attestation verification constrained to the repository, release workflow, tag ref, and source digest; clean-wheel installation Build and attestation succeeded. Release creation failed because the isolated publish job lacked repository context; the identical verified artifacts were recovered manually, and the workflow was corrected to pass the repository explicitly without broadening permissions. Initial maintainer
SEC-006 2026-08-03 CodeQL v4 action-suite migration Dependabot PRs #14, #15, and #16; mixed-generation failure logs; immutable upstream v4.37.4 commit f205ea1c3313d32999d8d6a48b4f6530d4437b38; full repository checks The three coupled CodeQL actions were upgraded atomically. Dependabot now groups the suite across major, minor, and patch updates, preventing mixed action generations from being proposed independently. Initial maintainer
SEC-007 2026-08-03 Untrusted KiCad and Board IR v0.1 parser boundary Exact integer/string numeric regressions under changed decimal context; streaming S-expression and pre-DOM JSON allocation regressions; default writer/decoder budget parity; property/construct-name redaction; quote-aware numeric nets; version/layer/setup/tenting/native-identity, positional-lock, copper/Edge.Cuts graphics, zone-semantics, outline, and via-span mutations; real CopperTone conversion Accepted for the documented 20260206 subset after independent adversarial review. Unmodeled routing and non-default fabrication semantics fail without a snapshot. Remaining limits are intentional: one hole-free Board IR outline (rectangular in the KiCad adapter), front orthogonal footprints, full-stack through vias, solid single-loop zones, caller-supplied constraints, no fill-cache authority, no mutation/apply, and operational budgets may reject oversized schema-valid third-party input. Initial maintainer + independent agent audit
SEC-008 2026-08-03 Candidate-only A* routing boundary Exact and one-nanometre edge/keepout tests; stale/forged/type-invalid inputs; unmodeled geometry and constraint rejection; grid, expansion, obstacle-count, obstacle-check, and cancellation limits; 250 fixed-seed randomized determinism replays; independent 200-case Dijkstra cost comparison; full 144-test gate Accepted for the documented synthetic rectangular first slice after an independent review found and verified remediation of multiplicative obstacle work. Successful metrics are internal only. KiCad export, authoritative candidate DRC, MCP exposure, preview, and apply remain prohibited/unimplemented. Initial maintainer + independent agent audit
SEC-009 2026-08-03 Candidate-bound authoritative KiCad DRC boundary Exact candidate/base/source/patched-board/context hash tests; fixed-argument private execution; patched per-file and cumulative limits; stale live and private board/rule/library membership rejection; malformed, oversized, timed-out, signalled, unexpected-exit, and exit/report-mismatch cases; aggregate/type-count consistency; valid warning, exclusion, and hard-failure evidence; deep evidence immutability; and real KiCad 10.0.5 inode/mtime/workspace preservation Accepted for internal use on the documented replayed synthetic route. One subprocess/report path is shared with ordinary DRC; exit codes must agree with report finding presence; caller-controlled/save/refill flags and child logs remain blocked; and no candidate bytes or raw findings are returned. MCP/CLI exposure, preview, persistence, apply, electrical/SI/PI/EMC/thermal/DFM conclusions, fabrication approval, and production safety remain outside this evidence. Initial maintainer + independent agent audits
SEC-010 2026-08-03 Public route-preview boundary Unknown-field, non-integer, boolean-as-integer, out-of-range, control-character, oversized-name, non-copper-layer, and non-object request rejection; workspace traversal rejection; fail-closed Board IR conversion with bounded diagnostic-code counts; wall-clock deadline cancellation; typed routing diagnostics; detached and immutable serialization; binding invariants between candidate, Board IR digest, board revision, and DRC evidence; stubbed and real KiCad 10.0.5 runs asserting unchanged workspace inode, mtime, and bytes Accepted as a read-only public surface for the documented Board IR and two-pin subset. Candidate-bound DRC evidence is reachable only through the explicit include_drc flag, still returns aggregate counts only, and fails the call when KiCad is unavailable or evidence does not bind. Generated candidate geometry and endpoint pad IDs are intentionally returned to the caller; source board bytes, other nets, raw findings, coordinates, UUIDs, and net names are not. Durable jobs, persistence, export, and apply remain unimplemented. Initial maintainer
SEC-011 2026-08-03 Board IR inspection and shared request boundary Unknown-field, missing-field, non-object, non-integer, boolean-as-integer, control-character, and invalid net-class request rejection; workspace traversal rejection; fail-closed conversion with diagnostic-code-only reporting; supported/unsupported state invariants; detached immutable serialization; explicit assertion that net names, pad/net identities, UUIDs, and coordinates are absent from the returned document; constraint-dependent digest binding Accepted as a read-only structural surface. Disclosure is limited to object counts, digests, units, and standard KiCad copper layer names. Every public service now parses untrusted requests through one shared boundary, so a rule tightened there applies everywhere. Returning the Board IR snapshot itself, net names, or geometry remains out of scope. Initial maintainer
SEC-012 2026-08-03 Existing-copper obstacle model Exact and quarter-turn pad extents; orthogonal segment sweeps with ceiling half-widths; stricter-of-two net-class clearance selection; obstacle-budget accounting across keepouts, pads, and segments; fail-closed rejection of arcs, zones, vias, off-axis rotations, diagonal segments, and partially routed nets; A*/Dijkstra cost agreement on pad, segment, and mixed-obstacle boards; and a real KiCad 10.0.5 run confirming a detoured route reports zero errors and zero unconnected items Accepted. Obstacle work remains bounded by the existing obstacle-count and obstacle-check ceilings, and round pad shapes over-approximate only, so the model can refuse a legal route but cannot permit a clearance violation. Multi-net routing, vias, rip-up, and apply remain unimplemented. Initial maintainer
SEC-013 2026-08-03 Conservative polygon zone-boundary obstacle model Concave-not-bounding-box, full-grid-edge crossing, exact/one-nanometre offset, diagonal 3:4:5 rational distance, strictest-of-three clearance, same-net/other-layer, object/vertex/edge budget, 64-check cancellation, deterministic replay, A*/Dijkstra agreement, and outline-only KiCad adapter-to-preview workspace-preservation tests; CopperTone 0/14 failure-funnel re-measurement; independent code audit; full 271-test, Ruff, strict mypy, secret scan, dependency audit, and package build gate Accepted after the audit found that foreign-net class fallback swallowed CANCELLED; the fix rethrows every non-missing-class failure and regression tests cover both lookup checkpoints. Eager big-integer distance checks and a second unmetered vertex scan during polygon sorting were also removed. The complete outline is a deliberate over-approximation, cached fill remains non-authoritative, same-net zones remain partial routing, and no zone-specific KiCad refill/DRC, real-board routing, electrical, DFM, or fabrication claim is accepted. Initial maintainer + independent agent audit
SEC-014 2026-08-03 Licence-aware offline audio capability corpus Exact licence-hash and SPDX-identity mismatch tests; reference-only redistribution gating; duplicate/path/symlink/URL/oversize rejection; disjoint and evidence-derived claim tests; required candidate IDs and observed typed refusals; catalog and artifact replacement-race tests; deterministic private-copy execution; source byte/mtime preservation; real KiCad 10.0.5 Gerber parse/plot smoke; 18 focused tests; 288 nonblocked repository tests; Ruff, strict mypy, secret scan, and independent remediation audit Accepted for a development-only local functional corpus after the audit's licence-binding, fabricated-claim, TOCTOU, and provenance-wording blockers were remediated. Catalog, artifact, and licence report bindings come from one bounded validation snapshot; external records are metadata-only and never executed. This enforces repository provenance policy but is not legal, electrical, DRC, DFM, fabrication, or hardware evidence. The existing real-KiCad findings test still aborts in the managed macOS environment, while current dependency audit and isolated build attempts are network-blocked; release gating remains required in CI or an unrestricted environment. Initial maintainer + independent agent audit
SEC-015 2026-08-03 Canonical Circuit Intent IR 0.1.0 and deterministic KiCad schematic renderer Strict schema/codec, duplicate/unknown/numeric/control/UTF-8/digest/topology rejection, tighten-only byte/tree/object ceilings, canonical replay, escaped-string injection tests, immutable input and fixture inode/mtime checks, content-verified source/count provenance, artifact tamper/drift rejection, UUID uniqueness at the 64-component/128-connection ceiling, 47 focused tests, real KiCad 10.0.5 SVG and exact kicadxml connectivity export, 335 nonblocked repository tests, Ruff, strict mypy, secret scan, and independent remediation audit Accepted for the bounded two-pin resistor/non-polarized-capacitor logical subset after the audit found and verified fixes for caller-weakenable input/tree limits and independently drifting artifact provenance fields. Rendering is pure, capped at 1 MB, uses original embedded symbols, leaves footprints empty, sets on_board=no, and has no MCP/CLI/file-writing surface. Successful parsing and netlist export do not establish ERC, value correctness, symbol/footprint qualification, schematic-to-board parity, electrical/audio performance, manufacturability, or fabrication safety. The pre-existing real PCB DRC test still aborts in the managed macOS environment; dependency audit and isolated build remain network-blocked, so release gating is still required in CI or an unrestricted environment. Initial maintainer + independent agent audit
SEC-016 2026-08-03 Bounded Circuit Intent build and schematic delivery Strict snapshot and structured-content validation; content-owned digest creation; byte-identical double-render requirement; redacted serialization checks; independent 256-bit token, TTL, count, aggregate/per-artifact byte, LRU, uniform-unavailable, and digest-tamper cases; stdio-only MCP tool/resource and absent HTTP registration; explicit workspace-confined create-new CLI export with traversal, symlink, suffix, existing-target, and partial-file rejection Accepted for the ADR-0015 MVP boundary, superseding SEC-015's no-public-surface statement without weakening its renderer controls. Ordinary MCP output omits circuit strings and bytes; the capability store is non-enumerable, process-local, non-persistent, and limited to 15 minutes, 16 entries, 16 MiB total, and 1 MiB per artifact. CLI export creates one new schematic only. Per-build topology/digest/provenance/replay checks pass, while KiCad parse, ERC, parity, and electrical validation remain not_run and board readiness is false. A reviewed KiCad 10.0.5 fixture retained exact nets and reduced ERC warnings from seven to four; the two isolated external-port labels and two missing private-library-configuration warnings remain, so ERC-clean is not claimed. Initial maintainer + independent agent review
SEC-017 2026-08-03 KiCad CLI global-configuration and child-environment isolation Exact child-environment capture; inherited token and KiCad-variable exclusion; private HOME/KiCad/XDG/runtime/temp roots; state-tree symlink and special-file rejection; per-file, file-count, cumulative-byte, and scan-time boundary cases Accepted as hardening for ordinary and candidate-bound DRC. The child environment is reconstructed from PATH=os.defpath, LANG=C, and LC_ALL=C plus private per-run roots; no caller entry or user-global KiCad configuration is inherited. Private state is inspected under the same bounded policy as captured design context. KiCad remains a trusted external executable, and isolation does not turn DRC into ERC, electrical, DFM, or fabrication evidence. Initial maintainer + independent agent review
SEC-018 2026-08-03 Post-MVP filesystem, artifact-retention, and KiCad dependency audit remediation Absolute non-renewing capability-expiry and lazy-reclamation cases; descriptor-anchored read and path-component replacement cases; exact-lowercase output suffix and held-directory create-only checks; file-table environment/absolute/remote/plugin URI rejection; snapshot-confined relative dependency acceptance; private-child-cwd capture; retained redaction, digest, state-budget, and context-revision checks Accepted as clarification and hardening of SEC-016/SEC-017. Fifteen minutes is an access-control deadline, not immediate deletion or secure erasure; stale entries are reclaimed on later store activity or process exit. Workspace bytes are never consumed through a validate-then-reopen path, and output remains exact-lowercase create-only. KiCad receives only snapshot-confined table dependencies and runs from private TMPDIR, so uncaptured host, remote, plugin, and working-directory state cannot silently enter DRC evidence. Circuit Scene IR and semantic/visual placement remain an unimplemented high-fidelity north star, never a direct AI mutation path. Initial maintainer + independent agent audit remediation
SEC-019 2026-08-03 Final unrestricted audit remediation: MCP schemas, KiCad evidence capture, artifact accounting, and release authorization Closed wrapper/content/output schema cases with scalar/list/extra non-echo rejection; no-follow nonblocking regular-report cases; duplicate/non-finite/depth/value JSON cases; read-only full private-snapshot-tree side-effect checks; post-insertion artifact-alias mutation and exact size-accounting checks; changelog and release-authorization tag-gate checks; unrestricted Python 3.12.13 desktop run with CODEX_SANDBOX absent, 386/386 tests plus 26 subtests, KiCad 10.0.5, and five real PCB DRC nodes Accepted after the unrestricted audit. MCP shape errors cannot expand or echo the private contract; DRC evidence rejects special/replaced reports, hostile JSON, and any full-tree snapshot side effect; store identity and quotas use detached content/digest/size. All five real PCB DRC paths passed independently and preserved source bytes, mtime, and inode where applicable. The managed root run still has one environment skip/exit -6, but this no longer means real PCB DRC is unvalidated. Release tagging additionally requires a dated version section and append-only exact-commit Ready authorization; no 0.2.0 authorization is recorded. Initial maintainer + independent unrestricted audit
SEC-020 2026-08-04 Board IR 0.2.0 footprint fidelity, Circuit Scene 0.2.0, and revision-bound placement projection Strict schema/codec and legacy-compatibility cases; total pad ownership, courtyard-count/vertex/intersection, canonicalization, metamorphic-transform, scene-detail, native-identity, locked-move, unsupported-transform/topology, source-revision, forged-snapshot, and caller-tightened-budget regressions; independent adversarial review and remediation verification; direct KiCad 10.0.5 DRC of the four-pose courtyard fixture with zero violations and zero unconnected items; Python 3.12.13 make check with 881 passed and one pre-existing skip, Ruff, strict mypy, secret scan, dependency audit, and wheel/sdist build Accepted for revision-bound observation and non-mutating placement preview after the audit found and verified fixes for two blockers: a stale digest could label forged footprint content as the old snapshot, and the placement-view ParseLimits argument was ignored. The view now enforces caller-tightened content ceilings before canonical digest verification. The KiCad adapter remains restricted to front-side orthogonal footprints and matching unfilled fp_rect courtyard centerlines; courtyard_overlap remains not_modelled, and placement apply remains prohibited. Initial maintainer + independent agent audit
SEC-022 2026-08-04 Revision-bound Scene-to-route MCP edge and closed status contract Actual mcp.call_tool scene→route chain; exact candidate equality against the hidden-name oracle; board-revision refusal before Board IR conversion; snapshot-revision refusal before route/fill/DRC/token work; strict UTF-8 request boundary; selector XOR and relational constraint tests; contradictory five-variant output rejection with Draft 2020-12 validation; nested closed-schema regression; repeated capability-minting calls; real KiCad 10.0.5 candidate-DRC and fresh-fill evidence; Python 3.12.13 make check with 913 passed and one pre-existing skip, 90% coverage, Ruff, strict mypy, secret scan, pip-audit, and wheel/sdist build Accepted for the supported scene/route subset. The opaque scene reference is directly actionable only when both observed revisions are supplied; stale captures fail closed and raw net names remain compatibility-only. The MCP 2026-07-28 specification permits any valid JSON Schema 2020-12 output, so the status union is intentionally root-discriminated; input remains object-rooted. preview_route stays read-only for the workspace, while idempotent_hint=false truthfully reflects fresh stateless HMAC capability issuance when explicitly requested. The benchmark is an integration baseline, not whole-board, multilayer, placement, live-IPC, electrical, DRC-generalization, or fabrication evidence. Initial maintainer + independent agent audits
SEC-023 2026-08-04 Optional KiCad IPC observer boundary Fake-client contract tests cover local endpoint normalization, TCP rejection, timeout/size ceilings, deterministic digest/count redaction, missing optional dependency, and future-version refusal/opt-in. The bundled plugin manifest and entrypoint expose no mutation API. Accepted for the redacted read-only observer: endpoint/path/token/board content is omitted, all reads are bounded, future API versions fail closed by default, and the tool returns read_only=true. A live KiCad session was not probed because this workstation has KiCad IPC disabled; no live-scene, placement, routing, DRC, electrical, or fabrication claim is made. Initial maintainer
SEC-024 2026-08-04 KiCad IPC snapshot-to-Circuit-Scene hand-off Exact source-byte/digest/size invariant; fake-client deterministic scene replays; native Board IR conversion; author-text quarantine; literal board: "live"; malformed and stale board/snapshot digest refusals; closed MCP input/output schema; live render refusal; full local release gate. Accepted for read-only semantic binding: the source hand-off is internal and never serialized, only exact Board IR/Circuit Scene fields cross MCP, and caller-supplied stale revisions fail closed. The workstation's IPC server is disabled, so B-009 is a fake-client contract baseline; live placement, routing, DRC, ERC, electrical, and fabrication evidence remain absent. Initial maintainer
SEC-025 2026-08-04 KiCad IPC review remediation False check_version() results now fail closed; object counts are parsed from one bounded serialization and a second serialization must match; ten mutable collection materializations were removed; malformed source and revision-change tests were added; benchmark redaction uses identifiable private-object markers; plugin discovery-directory installation is documented. Accepted with one explicit residual: the official synchronous wrapper allocates the complete get_as_string() response before Python can enforce the byte ceiling. The adapter rejects oversized data immediately after return, bounds the parser, avoids additional object allocations, and records the need for an isolated worker before any hard pre-allocation or remote-session guarantee. No live session was available because IPC is disabled. Initial maintainer + review-bot remediation
SEC-026 2026-08-04 Live Circuit Scene request preflight The live-scene application service validates the closed board/constraint/region/layer/digest shape before capture_live_board, rejects the unsupported render flag at the same boundary, and uses a generic non-echoing error. B-011 proves one malformed request caused zero fake IPC client calls. Accepted: malformed MCP traffic cannot trigger board serialization, source parsing, or count materialization. Valid requests retain the exact source/digest and stale-revision gates from SEC-024. A live GUI session remains unavailable because IPC is disabled. Initial maintainer + review-bot remediation
SEC-027 2026-08-04 KiCad IPC serialized topology-count correctness Recursive S-expression count traversal now marks only direct kicad_pcb children as net declarations, ignores nested (net ...) references for the net total, and includes KiCad gr_circle graphics in the bounded shape set. Regression tests and B-012 use one top-level net plus one nested pad reference and one circle. Accepted: redacted object counts now describe board topology rather than child reference repetition, while parser budgets and the byte-identical confirmation remain unchanged. The fake-client result does not establish live KiCad compatibility or complete graphical coverage beyond the documented set. Initial maintainer + review-bot remediation

| SEC-028 | 2026-08-04 | Live KiCad IPC route-proposal boundary | Fake official-client exact-source tests; stale board/snapshot refusal; action flags rejected before IPC; closed MCP schema; deterministic file-backed candidate equality; redacted output assertions; benchmark B-013; source and full release gates | Accepted for the read-only proposal subset. The tool accepts only net_ref_id and both revision preconditions, converts one bounded byte-confirmed IPC snapshot, and returns no DRC/fill/apply authority or mutation. A real KiCad IPC session, live editor transaction, DRC, placement, electrical, and fabrication evidence remain unclaimed. | Initial maintainer | | SEC-029 | 2026-08-04 | Live KiCad IPC placement-proposal boundary | Fake official-client exact-source tests; candidate equality with file-backed placement; stale board/snapshot refusal; unknown action field rejected before IPC; closed MCP request/response schema; deterministic B-014 replay; mutator guard; Ruff, strict mypy, and targeted MCP/placement tests | Accepted for the read-only proposal subset. The tool requires board: "live" and both Scene revisions, derives all poses through the existing Board IR/legalizer path, and returns no raw source, DRC, fill, apply authority, or editor mutation. The workstation IPC server is disabled, so no live GUI, KiCad DRC, undo, electrical, or fabrication claim is made. | Initial maintainer + review-bot remediation | | SEC-030 | 2026-08-04 | Live KiCad editor-context boundary | Fake official-client tests for deterministic active-layer/selection output, stale board/snapshot/context preconditions, selection/layer races, empty/unknown/malformed/over-budget refs, raw-selection-string refusal, zero writes, and closed MCP schema | Accepted for the read-only context subset. Only allow-listed official wrapper classes with validated UUIDs become native refs; the adapter reads no board-author text, raw selection string, coordinates, net names, or mutation API. KiCad IPC is optional and unavailable on this workstation, so no live GUI compatibility or placement/routing/DRC/electrical/fabrication claim is made. | Initial maintainer | | SEC-031 | 2026-08-04 | Internal source-preserving KiCad placement projection | Deterministic five-case adapter suite; exact source/snapshot/candidate/view revision checks; native-identity and placeable-set binding; locked/side/rotation/moved-flag/unknown/duplicate/budget refusals; byte-preservation assertions; Board IR round-trip equality; Ruff and strict mypy | Accepted for the disposable candidate-only subset. The renderer cannot mutate a board or invoke KiCad, and it refuses unsupported footprint syntax, padless candidate omissions, forged self-consistent candidates, and stale/tampered inputs. Placement DRC, live compare-and-swap, undo, post-action observation, electrical behavior, and fabrication readiness remain unclaimed. | Initial maintainer + independent adversarial review | | SEC-032 | 2026-08-04 | Internal layered A* resource and result boundary | Two-signal-layer abstract lattice; integer-only states; terminal obstacle checks; separate node, expansion, obstacle-relation, and cancellation budgets; caps of 500k nodes, 1m expansions, 4,096 obstacles, and 10m obstacle checks; immutable result invariants; deterministic replay tests | Accepted for the internal oracle only. The module is not exported or connected to Board IR/KiCad and therefore does not claim trace clearance, via geometry, keepout legality, DRC, live mutation, or untrusted-board protection. A future Board IR adapter must add typed layer/net ownership, physical geometry, and serializer/DRC gates before any candidate surface. | Initial maintainer + independent review | | SEC-033 | 2026-08-04 | Board IR-bound layered routing proposal boundary | Board IR snapshot verification and digest binding; typed request and explicit revision checks; exactly two signal layers; integer grid, edge, obstacle, via, node, expansion, and cancellation budgets; conservative pad/track/via/zone/keepout envelopes; immutable candidate identity; deterministic replay, stale/off-grid, no-path, and tamper tests | Accepted for the internal candidate-only adapter. It performs no file or KiCad writes, invokes no KiCad process, exposes no MCP/apply authority, and makes no DRC/fill/electrical/fabrication claim. Source-preserving segment/via serialization, Board IR replay, and authoritative DRC remain mandatory before production routing through vias. | Initial maintainer + independent review | | SEC-034 | 2026-08-04 | Placement-angle and layered-budget review remediation | Exact decimal pad-angle serializer test with a moved orthogonal parent and a 45° Board IR pad angle; typed obstacle-count budget regression; Ruff, strict mypy, and focused placement/layered routing suites | Accepted. Parent footprint poses remain orthogonal-only, while pad rotations are rendered independently and round-trip through Board IR. Layered obstacle-budget exhaustion is bounded and typed; no new mutation, MCP, KiCad, DRC, or apply authority is introduced. | Initial maintainer + review-bot remediation | | SEC-035 | 2026-08-05 | Layered disposable serializer boundary | Required request replay; exact source/profile/snapshot and candidate digest checks; native UUID/tstamp collision scan; two-signal-layer and full-stack-via restriction; object/output budgets; source-preserving append-only rendering; Board IR round-trip equality; focused stale/tamper/reverse-via tests | Accepted for the internal candidate-only serializer. It writes no files, invokes no KiCad or DRC, exposes no MCP/apply authority, and does not claim electrical, fabrication, or FreeRouting parity. | Initial maintainer + independent design review | | SEC-036 | 2026-08-05 | Layered candidate-bound KiCad DRC boundary | Exact request replay and candidate/base/source/context revision checks; private context replacement; fixed-argument bounded child execution; strict redacted report parsing; stale board/rule/library and process/report mismatch refusal; deep evidence immutability; fake subprocess and real KiCad 10.0.5 source inode/mtime/byte preservation | Accepted for the documented two-signal-layer, full-stack-via proposal subset. The DRC result is internal, disposable, and read-only; no MCP/CLI exposure, candidate persistence, refill, apply token, editor mutation, or raw finding disclosure is added. It does not establish whole-board completion, electrical behavior, fabrication readiness, or FreeRouting parity. | Initial maintainer + independent review | | SEC-037 | 2026-08-05 | Freshness-bound fill-aware routing obstacle boundary | Source-revision and matching-zone checks for every VerifiedFill; exact polygon island obstacles with governing clearance; conservative fallback for unverified zones; stale/orphan refusal; object and obstacle-check budgets; deterministic corridor benchmark and full routing regression suite | Accepted for the internal pure routing core. KiCad refill remains opt-in and private through ADR-0021; fill is not added to Board IR or fetched by A*. Public preview does not yet return fill-aware provenance for routed candidates, and no electrical, fabrication, or FreeRouting claim is made. | Initial maintainer + independent review | | SEC-038 | 2026-08-05 | Public routed fill-provenance boundary | Selected-layer zone trigger; private disposable refill; source/context/fill digest equality; closed routing_effect output literal; synthetic foreign-island routed preview; MCP output-schema validation; workspace-preservation assertion | Accepted for the explicit include_fill_authority opt-in. Routed responses disclose only aggregate revision-bound evidence and its deterministic role, never fill vertices, net names, raw KiCad reports, or new mutation authority. Stale, orphaned, and source-mismatched fill remains fail-closed; no electrical, fabrication, or FreeRouting claim is made. | Initial maintainer + review-bot gate | | SEC-039 | 2026-08-05 | Layered and freshness-bound routing review remediation | Malformed obstacle-before-budget regression; malformed settings and absent-expected-revision diagnostics; candidate track/via radius envelope checks; explicit zone-clearance fill regression; orphaned-fill benchmark refusal; focused Ruff/mypy/unit validation | Accepted for the internal routing seams and explicit fill-aware preview provenance. Requests remain bounded and non-throwing; physical margins are conservative, fill remains opt-in and freshness-bound, and no new serialization, DRC, MCP mutation, electrical, fabrication, or FreeRouting claim is made. | Initial maintainer + review-bot remediation | | SEC-040 | 2026-08-05 | Public layered route-preview boundary | Descriptor-anchored .kicad_pcb read; required source/snapshot CAS; pad-ref net inference after conversion; bounded grid/settings and output geometry; canonical candidate-ID verification; closed nested MCP schemas; stale/unsupported/cross-net/off-grid/budget tests; no write, DRC, refill, export, persistence, or apply path | Accepted for the narrow two-signal-layer candidate-only proposal. Board text, net names, raw diagnostics, and credentials do not cross the boundary. The candidate is not asserted KiCad-valid or fabrication-ready; B-024 is contract/replay evidence only. | Initial maintainer + independent research review | | SEC-041 | 2026-08-05 | Durable routing-job ledger boundary | Closed immutable job/spec records; content-addressed IDs; source/snapshot CAS; SQLite BEGIN IMMEDIATE plus revision-qualified updates; bounded record/TTL/payload ceilings; uniform unknown/expired errors; cooperative cancellation; candidate identity verification; restart, race, tamper, and board/geometry disclosure tests | Accepted for the internal persistence subset. The ledger stores no board bytes, prompts, credentials, raw net names, candidate geometry, DRC findings, or apply authority. It does not execute workers or expose MCP Tasks; filesystem permissions, multi-user authorization, worker leases, candidate export, and remote deployment remain open. | Initial maintainer + independent lifecycle review | | SEC-042 | 2026-08-05 | Live layered route proposal boundary | Closed board: "live" request; pad-only net inference; source/Board IR/session CAS; bounded remaining IPC timeout; byte-identical double capture; official client closure on success/failure; deterministic file-oracle equality; stale/capture-race/timeout/redaction/no-write tests; no DRC/refill/serializer/apply path | Accepted for the narrow candidate-only two-signal-layer subset. KICAD_API_TOKEN is hashed and never returned; no board bytes, net names, socket paths, or raw diagnostics cross MCP. KiCad GUI, endpoint-via legality, DRC, electrical, fabrication, serializer/export, persistence, and FreeRouting claims remain unmade; ABA and wrapper pre-return allocation are documented residuals. | Initial maintainer + independent IPC/layered review | | SEC-043 | 2026-08-05 | Layered candidate topology and endpoint-via boundary | Candidate digest and Board IR CAS; endpoint/net/layer binding; exact path-via adjacency; full two-signal stack; duplicate/overlap/crossing rejection; bounded path/vertex/via/intersection work; conservative rotated-pad envelope; endpoint-via refusal; serializer integration; five focused positive/negative tests | Accepted for the internal disposable serializer. The gate is structural only and reports physical_validation=not_modelled; exact pad polygons, annular/hole/edge/keepout clearance, refill, KiCad DRC, electrical behavior, fabrication treatment, and FreeRouting parity remain separate evidence gates. Endpoint-via is blocked by the router until padstack/IPC-4761 evidence is modeled. | Initial maintainer + independent topology/geometry review | | SEC-044 | 2026-08-05 | Routing worker lease and execution boundary | Single active worker; CAS claim race; bounded injectable lease/poll clock; cooperative cancel; stale-running recovery; invalid/stale candidate terminalization with non-echoing diagnostic; candidate identity-only completion; ten focused worker tests; no board bytes/geometry in SQLite | Accepted for protocol-independent local execution only. The worker does not persist normalized requests or candidate manifests, retry stale boards, expose remote authorization, or implement MCP Tasks; future task IDs must be random and distinct from deterministic job IDs. | Initial maintainer + lifecycle/Tasks research review | | SEC-045 | 2026-08-05 | Redacted candidate-manifest persistence boundary | Closed content-addressed manifest; identity/base/endpoints/kind/router/policy binding; numeric metric-key allow-list; SQLite restart/TTL/capacity/idempotency; tamper and uniform unknown/expired refusal; eight focused tests; no geometry/board/net/prompt/credential/DRC fields | Accepted for summary persistence only. The store cannot export or rehydrate route geometry, does not create MCP Tasks handles, and does not add remote authorization, KiCad, DRC, electrical, fabrication, or FreeRouting authority. | Initial maintainer + manifest-store review | | SEC-046 | 2026-08-05 | Durable routing request/result and geometry-export boundary | Deep-frozen bounded request envelopes; forbidden board-byte/prompt/credential/DRC/token keys; source/snapshot CAS replay before worker execution; caller-context digest on lifecycle and export reads; content-addressed geometry verification on read; separate redacted manifest; SQLite TTL/capacity/restart; uniform unavailable errors; wrong-context, tamper, live-refusal, and no-mutation tests | Accepted for the local file-backed two-signal layered subset. Geometry is disclosed only through an explicit export tool after authorization; deterministic job IDs are idempotency keys, not bearer handles. No remote principals, MCP Tasks negotiation, DRC, KiCad mutation, single-layer/live jobs, or fabrication/electrical claim is added. | Initial maintainer + request/result security review | | SEC-047 | 2026-08-05 | Multi-pin topology-ordering boundary | Pure deterministic one-Steiner ordering; at-most-nine-component cap; every comparison charged to the existing obstacle-check/cancellation budget; no model, network, board mutation, raw geometry serialization, or external lookup tables; policy identity and replay tests; source-preservation benchmark | Accepted for the routing ordering seam. Exact obstacle-aware A* remains the geometry authority, larger nets use the prior MST order, and the result is candidate-only. The policy is a quality heuristic with no optimality, DRC, electrical, fabrication, or FreeRouting claim. | Initial maintainer + research review | | SEC-048 | 2026-08-05 | Public file-backed layered candidate DRC boundary | Explicit boolean opt-in; candidate/base/source/patched/context binding; shared deadline and A* cancellation; aggregate redacted response; private fixed-argument KiCad replay; source inode/mtime/bytes preservation; fake authority/schema, live/job refusal, direct-job rejection, and real blocked-pad KiCad 10.0.5 tests | Accepted for the documented two-signal-layer, full-stack-via proposal subset. DRC evidence is read-only and disposable; no raw findings, board bytes, refill, serializer/export, persistence, apply authority, whole-board, fabrication, electrical, or FreeRouting claim is added. | Initial maintainer + independent review | | SEC-049 | 2026-08-05 | Conservative obstacle spatial-index boundary | Immutable canonical entries; conservative closed bounds; deterministic bucket ordering; small/giant-object linear fallback; exact rectangle/polygon predicates retained; cancellation and obstacle ceilings enforced; differential A*/Dijkstra replay; 256/256 no-false-negative query checks; no board writes, model/provider calls, or raw geometry disclosure | Accepted for the local candidate-only routing core. Indexing narrows exact work but does not add routing authority: an indexed run may complete under a ceiling a linear scan would exhaust because fewer exact predicates are needed. No congestion, FreeRouting, KiCad DRC, electrical, fabrication, or remote-session claim is made. | Initial maintainer + independent geometry review | | SEC-050 | 2026-08-05 | Unsigned in-toto candidate DRC Statement boundary | Strict SHA-256 subject/material bindings; Link v0.3 fixed names and empty command; aggregate-only byproducts; closed MCP schema; canonical JSON determinism; tamper/binding/redaction tests; no raw board/path/net/UUID/prompt/credential/finding disclosure; no signer or DSSE envelope | Accepted for local candidate evidence projection. The payload is unsigned and unauthenticated; no persistence, remote transport, verification, apply authority, whole-board, electrical, fabrication, or FreeRouting claim is added. | Initial maintainer + attestation-format review | | SEC-051 | 2026-08-05 | Private placement-candidate KiCad DRC boundary | Native-identity/front-side/orthogonal/unfilled-courtyard admission; exact source/snapshot/candidate/patched/context revisions; fixed-argument private DRC child; strict redacted report; stale original and private-tree mutation refusal; 19 focused tests plus real KiCad 10.0.5 source inode/mtime/bytes preservation | Accepted for the narrow internal placement evidence subset. Public/live placement, unsupported footprint properties and geometry, apply/undo, electrical, fabrication, and FreeRouting claims remain absent. | Initial maintainer + independent placement/DRC review | | SEC-052 | 2026-08-05 | Review-bot remediation for attestation and layered request classification | Required nested in-toto digest object with extra-field rejection; malformed-versus-stale expected-revision regression; focused schema/layered tests; B-034/B-035 replayed from implementation commit 6b5c75e | Accepted as a contract-hardening correction. Empty or unknown digest objects and malformed expected revisions fail closed as invalid_request; no new routing, DRC, mutation, or provenance authority is added. | Initial maintainer + review-bot remediation | | SEC-053 | 2026-08-05 | Review-bot remediation for public net references, live IPC deadlines, job provenance, manifest expiry, and layered obstacle bounds | Strict content-derived net:name:<32 hex> references; cooperative deadline checks between every official IPC call; fixed typed failure diagnostics; request-kind/router/policy/seed/work-limit candidate binding; exact job/router manifest binding with committed TTL purge; early obstacle ceiling and conservative track/via/zone envelopes; budget-before-hash candidate verification; focused routing, job, manifest, placement, MCP, and IPC tests | Accepted as a contract-hardening correction. All surfaces remain deterministic, candidate-only, revision-bound, and read-only. IPC deadline enforcement is cooperative around blocking official calls; general multilayer congestion, remote authentication, MCP Tasks, serialization, apply, and fabrication authority remain open. | Initial maintainer + review-bot remediation | | SEC-054 | 2026-08-05 | Negotiated-congestion candidate boundary | Closed bounded request envelope; one signal layer and common world grid; exact unit-edge/vertex occupancy; capped present/history penalties; total expansion and obstacle-check ceilings; fixed diagnostics; cancellation; policy-digest-bound candidate re-identification; no raw board/prompt/net-name disclosure; deterministic crossing-fixture replay | Accepted for the narrow candidate-only coordinator. Structural lattice overflow is not physical clearance or KiCad DRC; multilayer vias, capacity classes, exact pairwise geometry, serialization, apply, remote jobs, and FreeRouting parity remain separate gates. | Initial maintainer + routing/research review | | SEC-055 | 2026-08-05 | Routing-job and candidate-manifest TTL miss boundary | Expired-row read-miss regression tests; SQLite row-count assertions after uniform unavailable errors; candidate store and routing job store use committed purge paths; unrelated exceptions retain rollback semantics | Accepted as a retention-boundary hardening correction. Expired redacted metadata is removed even when a caller only observes a miss; no board bytes, candidate geometry, remote transport, routing authority, or apply capability is added. | Initial maintainer + review-bot remediation | | SEC-056 | 2026-08-05 | Routing-worker lease cleanup after durable-row expiry | Reproduced cancellation-after-TTL miss; cleanup finally in cancellation and publish-race paths; focused worker regression proves active_lease is cleared and a same-ID recreated job can be claimed; no raw executor diagnostics persisted | Accepted as a lifecycle hardening correction. A missing durable row remains an unavailable/conflict error and is never retried implicitly; the worker cannot be permanently stranded by stale in-memory state. No queue, routing, remote, or apply authority is added. | Initial maintainer + review-bot remediation | | SEC-057 | 2026-08-05 | Live IPC cooperative deadline and serialized-count boundary | Deadline callback checkpoints during bounded S-expression item counting; confirmation preserves KicadIpcDeadlineError; focused IPC/live-layered tests; docs explicitly retain synchronous-wrapper pre-emption residual | Accepted as a timing-contract hardening correction. Expensive bounded parsing now observes the operation budget and deadline refusals remain typed; a blocking official IPC call can still outlive the cooperative deadline until an isolated worker/process boundary is added. No remote, mutation, DRC, or fabrication authority is added. | Initial maintainer + IPC/review-bot remediation | | SEC-058 | 2026-08-05 | Public layered DRC evidence status and authority binding | Added a strict redacted clean signal distinct from hard-gate passed; warning-only KiCad evidence, malformed authority, timeout refusal, candidate-unbound evidence, and closed MCP output validation regressions; source/CAS/read-only assertions retained | Accepted for the narrow file-backed layered preview. passed remains no active errors/unconnected items for compatibility, while clean requires no findings or ignored checks; malformed, timed-out, or candidate-unbound authority fails closed. No raw reports, board bytes, mutation, apply, whole-board, or FreeRouting claim is added. | Initial maintainer + DRC boundary review | | SEC-059 | 2026-08-05 | KiCad schematic parity XML boundary | Exact renderer replay before semantic comparison; fixed format-E allowlist; DTD/entity/processing-instruction rejection; element/depth/text/byte ceilings; duplicate component/pin/net-node refusal; frozen redacted evidence and non-echoing error codes; real KiCad 10.0.5 fixture | Accepted for the bounded passive source/connectivity oracle. XML is treated as hostile input and no raw values, references, net names, or bytes cross the evidence boundary. Authoritative ERC, schematic-to-PCB parity, broader libraries, and remote transport remain open. | Initial maintainer + schematic parity review | | SEC-060 | 2026-08-05 | Front/back Board IR footprint observation | Explicit F.Cu/B.Cu mapping; inner-layer refusal; matching F.CrtYd/B.CrtYd courtyard layer check; native identity and side/pad ownership binding; asymmetric fixture and KiCad 10.0.5 DRC oracle; no second mirror during import | Accepted for bounded read-only observation. GUI serialization, non-rectangular topology, side-aware placement legality, live CAS, apply, and fabrication claims remain open; placement serializer remains front-side-only. | Initial maintainer + placement observation review | | SEC-061 | 2026-08-05 | Same-side rectangular courtyard legality | Transform proposed rings from saved Board IR pose using exact quarter-turn integer arithmetic; compare only same-side rings with open rectangle overlap; fail closed on unsupported topology before view construction; closed proven_clear/violated contract; cross-side and synthetic overlap regressions | Accepted for the bounded Board IR v0.2 placement subset. Configurable nonzero courtyard_clearance, polygon/line-chain topology, post-placement connectivity, live CAS, DRC binding, and apply remain separate. | Initial maintainer + placement legality review | | SEC-062 | 2026-08-05 | Separately authorized bounded placement apply | Placement-scoped HMAC operation domain; explicit apply request and operator gate; candidate/source/snapshot CAS; workspace confinement; KiCad lock checks before read and under lock; pure source-preserving replay; exact backup and atomic replacement; single-use capability; route-token cross-domain, lock/retry, stale, no-op, and six focused placement-apply regressions | Accepted for the documented front-side orthogonal native-identity rectangular-courtyard subset. Unsupported footprint properties/topology, side flips, post-apply DRC/connectivity, undo, live IPC mutation, remote authority, and fabrication claims remain blocked. | Initial maintainer + contract/security review | | SEC-063 | 2026-08-05 | Placement apply publication and request-boundary hardening | Pre-read caps and closed fields for pose, grid, legality, and evidence manifests; closed nested destructive MCP request; post-rename and post-publication token consumption; fresh authorized render plus Board IR reparse; observed final-digest reporting; focused malformed, replay, concurrent-write, and schema regressions | Accepted as a contract-hardening correction for the same narrow placement subset. A post-publication mismatch remains applied_but_unverified; side flips, general geometry, DRC, undo, live IPC mutation, remote authority, and fabrication claims remain blocked. | Initial maintainer + independent review-bot audit | | SEC-064 | 2026-08-05 | Synthetic audio-routing benchmark boundary | CopperMCP-original Apache-2.0 fixture declaration; exact artifact/licence hashes; 10 deterministic preview/replay repetitions; candidate identity and derivative-byte equality; source inode/mtime/bytes preservation; explicit no-claim fields for apply, KiCad DRC, production, fabrication, and hardware | Accepted for a disposable two-pad RC microcase only. The benchmark is not an external audio corpus, circuit-design proof, KiCad authority, manufacturability result, or FreeRouting comparison. | Initial maintainer + benchmark/research review | | SEC-065 | 2026-08-05 | Placement final publication observation and status semantics | Final on-disk digest observation immediately before successful placement response; regression that writes after post-publication verification; single-use token refusal after the observed race; contract and documentation clarification that applied_but_unverified may report a restored original or concurrent final digest | Accepted as a best-effort closure of the reproducible post-verification race. A final nanosecond race still requires a longer editor transaction; KiCad DRC, undo, live IPC mutation, remote authority, and unsupported geometry remain blocked. | Initial maintainer + independent Terra review | | SEC-066 | 2026-08-05 | Apply final-observation availability | Final observation distinguishes an actual digest from an unreadable/missing board; route and placement result contracts permit a null after-revision only for applied_but_unverified; placement unlink regression verifies token single-use and no false applied result | Accepted as fail-closed status semantics. A longer editor transaction is still required for the residual last-nanosecond race; KiCad DRC, undo, live IPC mutation, remote authority, and unsupported geometry remain blocked. | Initial maintainer + independent Terra review | | SEC-067 | 2026-08-05 | Public file-backed placement DRC evidence | include_drc is opt-in and absent from live/apply authority; private disposable replay binds candidate, source, patched board, and full DRC context digests; MCP output is aggregate-only; warning-only passed=true/clean=false, malformed/foreign/expired evidence, timeout, and source-preservation regressions are covered | Accepted for the documented front-side, orthogonal, native-identity, rectangular-courtyard serializer subset. KiCad quality beyond aggregate DRC, general geometry, live CAS, apply, electrical/fabrication signoff, and FreeRouting comparison remain open. | Initial maintainer + placement DRC boundary review | | SEC-068 | 2026-08-05 | File-backed post-placement scene and DRC observation | Required SHA-256 precondition; one descriptor-confined board/project/rule/library capture; semantic scene from captured bytes; fixed private KiCad DRC; aggregate-only response; mandatory context re-capture; closed request excludes token/candidate/render fields; stale/race/missing-authority tests | Accepted as a read-only observation boundary. It makes no claim that a candidate caused the state, does not alter apply semantics, and adds no live IPC, ERC/electrical/fabrication, or FreeRouting authority. | Initial maintainer + Terra review | | SEC-069 | 2026-08-05 | Pre-work validation for post-placement observation and padless placement rules | Shared Circuit Scene request parser runs before workspace access; stale board digest is checked before DRC sidecar/context scans; context capture must reproduce the first board bytes; padless rule references are rejected before syntactic infeasibility checks; malformed/stale/rule-order regressions | Accepted as boundary hardening for the existing read-only observation and bounded placement subsets. It adds no mutation or authority; live editor CAS, arbitrary courtyard topology, and electrical/fabrication claims remain open. | Initial maintainer + review-bot remediation | | SEC-070 | 2026-08-05 | Negotiated-routing cancellation callback boundary | A* catches untrusted cancellation callback exceptions and maps them to typed CANCELLED; negotiated routing stops the active iteration and returns no candidates; focused callback regression and existing cancellation suite | Accepted for the bounded candidate-only coordinator. This is cooperative fail-closed behavior, not process pre-emption, physical clearance, KiCad DRC, or apply authority. | Initial maintainer + Terra routing review | | SEC-071 | 2026-08-05 | Layered candidate dimension provenance | Before topology acceptance, resolve the routed net's Board IR net-class assignment and compare track width, via diameter, via drill, and via instances; altered re-stamped candidates return fixed invalid-candidate diagnostics; focused verifier regression | Accepted for the internal/file-backed structural layered subset. Padstack semantics, arbitrary rules, DRC, fill, fabrication, live mutation, and FreeRouting parity remain open. | Initial maintainer + Terra multilayer review | | SEC-072 | 2026-08-05 | Durable routing-job retention and cancellation lease boundary | Purge expired rows before digest validation; commit deletion on malformed/unavailable lookup; CAS-acknowledge stale CANCEL_REQUESTED records after lease_ms; focused SQLite row-count and worker-recovery regressions; fixed redacted diagnostics retained | Accepted for the local single-worker lifecycle. It prevents stranded non-terminal jobs and stale metadata retention; distributed leases, MCP Tasks, remote transport, geometry persistence, and apply authority remain open. | Initial maintainer + Terra lifecycle review | | SEC-073 | 2026-08-05 | Workspace-preservation benchmark provenance | Post-placement replay snapshots include file/symlink kind, path, bytes or target, mode, inode, and nanosecond mtime; a focused regression detects a metadata-only touch with unchanged bytes; artifact and source commit are content-addressed | Accepted for benchmark evidence only. It detects observable local metadata mutations in the disposable workspace; it does not provide a filesystem transaction guarantee, live-editor CAS, or mutation provenance for an external process. | Initial maintainer + review-bot remediation | | SEC-074 | 2026-08-05 | Live route capture deadline boundary | Operation deadline created before capture; remaining timeout clamped to 1–10,000 ms; absolute deadline passed through bounded IPC parser; focused propagation regression; no mutation or raw-source disclosure | Accepted for the read-only live route proposal subset. Timing is cooperative and does not pre-empt a blocking official IPC call; live GUI, DRC, apply, electrical, and fabrication authority remain open. | Initial maintainer + review-bot remediation | | SEC-075 | 2026-08-05 | Live placement capture deadline boundary | Operation deadline created before capture; remaining timeout clamped to the adapter's bounded two-second cap; absolute deadline passed through bounded IPC parser; focused propagation regression; no mutation or raw-source disclosure | Accepted for the read-only live placement proposal subset. Timing is cooperative and does not pre-empt a blocking official IPC call; live GUI, DRC, apply, electrical, and fabrication authority remain open. | Initial maintainer + review-bot remediation | | SEC-076 | 2026-08-05 | Negotiated-routing retry cancellation boundary | Cancellation at a later iteration boundary returns no candidate, connection, overflow, or wire-length evidence from earlier partial passes; all ordered nets remain unrouted; focused synthetic two-net replay | Accepted for the bounded candidate-only coordinator. This is cooperative fail-closed behavior, not hard process interruption, physical clearance, KiCad DRC, apply authority, or FreeRouting parity. | Initial maintainer + review-bot remediation | | SEC-077 | 2026-08-05 | Apply-token replay retention | Consumed nonce remains present through live-token count pressure and is swept only after its own expiry; max_consumed rejects malformed hints but cannot evict authorization state; tiny-cap replay regression | Accepted for the process-local capability boundary. Retention is expiry-limited rather than count-limited; deployments requiring a hard memory ceiling must add pre-issuance admission control. No remote key persistence or multi-tenant authorization is added. | Initial maintainer + review-bot remediation | | SEC-078 | 2026-08-05 | Live placement operation-wide deadline | The original absolute deadline is passed from IPC capture into the shared placement pipeline; remaining time is supplied to legalization and optional evidence; expired post-capture work returns typed budget_exhausted; 37 focused placement-preview tests plus Ruff, mypy, and diff checks | Accepted for the read-only live placement proposal subset. Timing remains cooperative around official IPC calls; process isolation, editor mutation, DRC authority beyond the bounded opt-in, electrical, fabrication, and FreeRouting claims remain open. | Initial maintainer + Terra review-bot remediation | | SEC-079 | 2026-08-05 | OpenSSF-informed project health and supply-chain baseline | Dated Criticality reconstruction (0.23/1.00) with public-input limitations; distinct Scorecard API snapshot (5.8/10); pinned CI/CodeQL/Scorecard workflows; CONTRIBUTING, SECURITY, CODEOWNERS, issue templates, release and ledger controls | Accepted as a planning baseline, not a certification. Branch protection/API verification, packaging, signed-release verification, CII profile, maintainer redundancy, contributor breadth, and adoption evidence remain open; no synthetic activity or private contributor data is permitted. | Initial maintainer | | SEC-080 | 2026-08-05 | Negotiated custom-router and physical-clearance boundary | Generic backend result identity/request binding plus deterministic reference-core replay under split remaining expansion/obstacle budgets; exact integer candidate-pair swept-disc checks with assigned net-class widths, stricter clearance, pair budget, cancellation, and atomic allocation discard | Accepted for the one-layer orthogonal candidate-pair coordinator subset. The physical gate is not KiCad DRC or board-wide verification; existing copper, pads, vias, zones, custom rules, multilayer geometry, and physical-conflict-guided reroute remain open. | Initial maintainer + Terra routing review | | SEC-081 | 2026-08-05 | Internal placement-solver proposal boundary | Immutable intent/snapshot/view type checks; bounded search/ranking/legalizer limits; exact deadline/cancellation propagation; only legalizer-issued candidate retention; deterministic candidate-ID tie breaks and O(n log n) proxy scoring | Accepted as an internal advisory generator. It creates no file/editor mutation, token, DRC authority, or routing/physical claim; unsupported or interrupted work fails closed. | Initial maintainer + Terra placement review | | SEC-082 | 2026-08-05 | Advisory AI routing-policy input and trace boundary | Closed duplicate-key-rejecting bounded JSON decoder; immutable input/decision objects; digest equality and supplied-window membership checks; ordinal-only action tokens; hostile decision rejection; traces omit raw identifiers, geometry, prompts, board bytes, and candidate copper | Accepted for local advisory policy experimentation only. Content digests remain linkable and may permit complete low-entropy-record dictionary tests; no model, route integration, MCP tool, DRC, or apply authority is added. | Initial maintainer + Terra policy review | | SEC-083 | 2026-08-05 | MCP Tasks progressive-enhancement boundary | Runtime capability probe; no Tasks advertisement/wire methods; random 256-bit opaque handle distinct from job ID; constant-time owner-context binding; uniform unavailable response; bounded 1-second–24-hour in-memory retention/capacity and cancellation delegation | Accepted only as a process-local future seam. The observed mcp 2.0.0 result does not pin the <3 dependency range; no authenticated session principal or durable restart-safe task lookup exists. | Initial maintainer + Terra MCP review | | SEC-084 | 2026-08-05 | External FreeRouting comparison harness boundary | No GPL vendoring/linking; bounded untrusted files/process output; minimal child environment; private workspace; redacted diagnostics; KiCad DRC prerequisites; explicit self-attested receipt schemas that force incomplete status | Accepted as a diagnostic harness only. User-supplied executable/JAR execution is not sandbox containment, receipts cannot prove import/runner provenance, and no actual comparison evidence exists yet. | Initial maintainer + Terra benchmark review | | SEC-085 | 2026-08-05 | Documentation/evidence correction boundary | Audit-preserving correction of the custom-router, clearance-unit, policy-digest, and external-process wording: deterministic A* reference replay remains the implemented custom-backend gate; 300,000 nm is copper-edge clearance; content digests are linkable; and bounded child-process controls are not sandbox containment | Accepted as a documentation correction only. It adds no generic independent verifier, policy authority, Task wire support, comparison result, or sandbox. | Initial maintainer + Terra documentation review |

Security reviews are required before adding remote authentication, provider integrations, uploaded files, persistent multi-user jobs, or candidate application.

Amendment — 2026-08-03 (append-only correction): SEC-004's row was edited in place by PR #17 rather than superseded by a new dated entry, which the append-only convention forbids. The row as first written in PR #13 read: "Reviewed upstream major-version changes, pinned each action to a full commit SHA, replaced the deprecated provenance wrapper with actions/attest, and retained least-privilege job permissions", with the outcome "CI, security, release, labeler, CodeQL, and Scorecard workflows accepted pending current-main GitHub checks; future minor/patch updates are grouped while majors remain isolated for review." PR #17 replaced both fields with the current text after the dry-run work landed. The current row is factually right and is left standing; this note restores the history the in-place edit removed. Git history is the authority for both versions.

Review ID Date Scope Evidence Findings / disposition Reviewer
SEC-086 2026-08-05 Candidate-export retention and placement-solver publication boundary SQLite regression publishes an export, advances past its TTL, verifies the expired and unknown lookups have the same unavailable response, then inspects the database to prove candidate_json is absent. Placement-solver regressions cancel after legalization and during successor scoring, asserting status=cancelled and an empty ranked set. Accepted for the local bounded surfaces: expiry purge is committed before the uniform unavailable exception can roll it back, and an observed cooperative cancellation withholds every ranked candidate. This does not securely erase SQLite pages/backups or copies previously returned to a caller, guarantee hard interruption of evaluation/legalization, add placement apply authority, or make placement routing/DRC/fabrication evidence. Initial maintainer + review-bot remediation
SEC-087 2026-08-05 Routing request/export TTL cleanup on uniform unavailable paths SQLite regressions prove an expired request row is absent after an expired lookup returns the same unavailable response as an unknown request. A separate regression makes an unauthorized request for a live export while another export has expired, then proves the expired private row was removed and the unauthorized live export remains present and unchanged. Accepted for the local stores: uniform unavailable paths commit only prior expiry cleanup, so an exception cannot resurrect expired private records. Decode and stored-identity/integrity failures still roll back. This does not securely erase SQLite pages, backups, or previously returned copies; it does not disclose an unauthorized live export or add routing/apply authority. Initial maintainer + review-bot remediation
SEC-088 2026-08-05 Malformed routing-handle TTL retention boundary Store regressions retain expired request/export records, invoke each get() with a malformed handle at a valid timestamp, receive the same uniform unavailable error, and inspect SQLite to prove the expired private rows were committed away. Timestamp validation remains outside the transaction. Accepted for local retention: malformed-handle lookup begins/purges before handle validation and commits that cleanup before the uniform unavailable response. This neither treats an invalid timestamp as a normal lookup nor securely erases SQLite pages, backups, or previously returned copies; it adds no routing, disclosure, or apply authority. Initial maintainer + review-bot remediation
SEC-089 2026-08-05 Public routing service and candidate-manifest malformed-handle retention boundary Service and manifest regressions retain expired private records, issue malformed public routing-job/export or manifest handles at valid timestamps, verify the established fixed unavailable/not-found diagnostics, and inspect the backing stores to prove expiry cleanup persists. Accepted for local retention: public services no longer prevalidate handles owned by a store before that store can purge, and manifest lookup purges before malformed-ID refusal. Timestamp validation remains first; diagnostics disclose neither existence nor private data. This does not securely erase SQLite pages, backups, or previously returned copies, and adds no routing/export/apply authority. Initial maintainer + review-bot remediation
SEC-090 2026-08-05 MCP routing lifecycle malformed-handle retention boundary MCP regressions invoke malformed get, cancel, and export handle fields at valid timestamps while expired private records exist, verify the established fixed diagnostics and closed response shapes, and inspect the stores to prove cleanup persists; valid lifecycle/export paths remain covered. Accepted for the local MCP adapter: entrypoint handle acceptance is broadened only to reach service/store purge-first validation. Payload schemas remain closed; diagnostics reveal neither record existence nor private data. Timestamp validation remains downstream and first for the retention transaction. This does not securely erase SQLite pages, backups, or previously returned copies, and adds no routing or apply authority. Initial maintainer + review-bot remediation
SEC-091 2026-08-05 Internal negotiated-policy initial-order boundary Private immutable profile registry with one deterministic-reference-v1 entry; bounded coordinator-derived input; single digest-bound evaluation after immutable request validation; exact complete-net permutation and empty unsupplied selections; fixed redacted fail-closed refusal before router construction/calls; separate v3 composite candidate identity/evidence Accepted for the internal candidate-only slice. An unknown, malformed, disabled, throwing, or invalid profile never falls back to ordinary routing. The profile changes only initial net order; retries, geometry, validation, budgets, MCP exposure, model invocation, corridor/repair authority, and apply remain outside it. In-process evaluation has no hard pre-emption guarantee; remote, plugin, model, and subprocess adapters require a separately bounded isolated-worker contract. Initial maintainer + Terra policy review
SEC-092 2026-08-05 Project-scoped dependency audit Installed pip-audit help identifies positional project_path as the local-project mode; python -m pip_audit . resolves CopperMCP's declared graph and reported no known vulnerabilities, whereas the no-argument ambient-environment audit observed an unrelated global google-auth to cryptography PYSEC-2026-3552 finding. Make and hosted workflow now use the project path; a regression reads their selected target/step and requires the exact command. Accepted for declared-graph vulnerability reporting; secret scan remains separate and unchanged. Resolution remains subject to mutable resolver/index/network state, there is no lockfile or hash-pinned reproducibility, advisory databases can lag, the optional kicad extra is not included unless installed/resolved, and installed-runtime drift is a separate audit concern. No unrelated global package was pinned or upgraded. Initial maintainer + Terra dependency audit
SEC-093 2026-08-05 Optional-group coverage correction for project-scoped dependency audit pip-audit project-path mode has no extras selector. Therefore python -m pip_audit . resolves only the default production dependency graph: every optional group (dev, security, and kicad) is excluded, even though the hosted workflow installs .[security] to provide the auditor. The regression additionally pins the hosted secret-scan step to python scripts/check_secrets.py. Accepted as a bounded default-production audit and unchanged separate secret scan. It does not audit installed security extras or any other optional group; each requires an explicit audit target or lock evidence. Resolver/index/network mutability, missing lock/hash reproducibility, advisory latency, and installed-runtime drift remain separate limits. Initial maintainer + independent review remediation
SEC-094 2026-08-05 Durable routing completion and composed TTL-retention boundary Focused SQLite regressions fill the export store before candidate publication, inject export persistence failure during worker execution, expire a request through repository lookup, and reject malformed cancellation text while unrelated rows are expired. The checks assert no completed unexportable job and no retained expired request/lifecycle rows. Accepted for the local bounded job surface: artifacts persist before lifecycle completion, and a persistence failure terminalizes without candidate binding. Completion/cancellation races can retain only inaccessible TTL-bounded orphan artifacts. TTL is not secure erasure for SQLite pages, backups, or returned copies; no distributed transaction, remote authorization, routing-quality, DRC, or apply authority is added. Initial maintainer + review-bot remediation
SEC-095 2026-08-05 Routing candidate artifact preflight binding One pure validate_candidate_for_job function now validates candidate identity/type, kind, source revision, endpoints, router, policy, seed, and work limits before both direct/worker artifact persistence and again at completion CAS. Parameterized SQLite regressions reject validly formed candidates mismatched on kind, router, policy, seed, or metrics and prove both export and manifest tables remain empty. Accepted for the local candidate publication boundary. Invalid candidates cannot consume artifact capacity or become owner-retrievable; worker refusal uses fixed invalid_request and direct publication remains retryable. Valid candidates can still leave an inaccessible TTL-bounded orphan only if a later completion/cancellation race loses after persistence. No secure erasure, distributed transaction, remote authorization, DRC, routing-quality, or apply authority is claimed. Independent review remediation
SEC-096 2026-08-05 Routing candidate lifecycle eligibility before artifact persistence The shared non-mutating RoutingJobRecord.validate_completion_eligibility requires RUNNING at the exact expected revision before direct publication and worker pre-completion hooks; complete repeats it inside the final CAS. SQLite regressions cover queued, completed, failed, cancelled, cancel-requested, and wrong-revision direct calls, proving both artifact tables remain empty and the lifecycle record is unchanged. Accepted for the local candidate publication boundary. Preflight is not authority over a later concurrent transition; a valid candidate can still leave only an inaccessible TTL-bounded orphan if it loses that later completion/cancellation race. No secure erasure, distributed transaction, remote authorization, DRC, routing-quality, or apply authority is claimed. Independent review remediation
SEC-097 2026-08-05 Fixed reference policy-worker process boundary Single 32 KiB duplicate-key-rejecting closed JSON frame; request canonical digest plus 256-bit nonce; byte-exact canonical response enforcement; fixed redacted failure; exact reference backend and neutral no-window input only; sys.executable -I, replacement locale/timezone environment, closed inherited FDs, stderr=DEVNULL, temporary cwd, POSIX child session, parent timeout/cancellation session kill, and best-effort Unix CPU/file-size limits Accepted as an internal defense-in-depth reference-worker boundary. It never accepts provider credentials, board bytes, geometry-bearing windows, model/plugin profiles, endpoints, candidates, copper, or apply authority. It is not filesystem, network, or device sandboxing on macOS or another OS; future non-reference/model workers require a separately deployable sandbox design and review. Initial maintainer + independent policy-worker review
SEC-098 2026-08-05 Live IPC fidelity-oracle capability and deadline boundary Presence-only plugin credential preflight before settings resolution; fixed redacted endpoint/token/timeout/session/version/configuration outcomes; one monotonic deadline passed to capture and checked around Board IR/Scene conversion; fake-client no-mutator, redaction, hostile-settings skip, configuration, and post-capture-expiry regressions Accepted for local read-only diagnostics only. Credential presence is not authentication; cooperative checks cannot pre-empt a blocking IPC call or an in-progress conversion; raw source remains process-internal; and a skipped shell result is not proof that an editor API server is disabled. No MCP action, DRC, routing, placement, apply, or real-editor fidelity claim is added. Initial maintainer + independent review remediation
SEC-099 2026-08-05 Public MCP excessive-agency regression boundary Seven predeclared offline cases exercise closed MCP request schemas, annotation quarantine, stale revision, quota, output/report disclosure, and the public apply_candidate and apply_placement_candidate handlers. With apply enabled, syntactically valid unauthorized tokens return structured invalid_token before source access; same-run workspace snapshots compare path, type/symlink status, mode, size, digest, mtime, and inode while the artifact stores only stable unchanged assertions. Accepted for local MCP boundary regression. No model, network, KiCad, board mutation, application logger sink, host logs, remote authorization, or provider telemetry is evaluated; unknown attacks and host behavior remain open. Initial maintainer + independent review remediation
SEC-100 2026-08-05 Fixed reference policy-worker negotiated-routing admission The private deterministic-reference-worker-v1 profile is evaluated once after immutable snapshot/request validation and before router construction. Focused regressions prove equality with the in-process reference decision, profile-distinct evidence with equal candidate binding, and zero router calls/candidates/connections for noncanonical output, timeout, cancellation, wrong input digest, or wrong policy identity. Coordinator checks retain complete-net permutation, empty selections, v3 identity, retry order, and all work/physical budgets. Accepted for the internal fixed-reference initial-order profile only. The worker receives no board bytes, geometry-bearing windows, provider credentials, endpoint, model/plugin output, candidates, copper, MCP, KiCad, DRC, or apply authority. Its sanitized process and best-effort limits are defense in depth, not filesystem/network/device sandboxing, authentication, or safe admission for another evaluator. Initial maintainer + Terra integration review
SEC-101 2026-08-05 Full-history CI benchmark-provenance checkout The hosted CI checkout uses fetch-depth: 0, and a repository regression reads the named workflow step and requires that exact setting. This preserves access to the immutable historical evidence_harness_commit used by benchmark replay via git show, instead of making a shallow-clone omission look like an evidence failure. Accepted as workflow-configuration evidence only. Full history increases checkout cost and does not prove a hosted job ran, that a historical commit is trustworthy, or that an artifact and its metrics are correct; artifact digest, isolated replay, source review, and hosted status remain separate evidence. Initial maintainer + CI provenance review
SEC-102 2026-08-05 Real FreeRouting smoke process and evidence boundary The run pins the official v2.2.2 release asset URL and SHA-256, invokes the GPL-3.0-only JAR out of process with a minimal allowlisted environment and no inherited provider tokens, bounds execution to 120 seconds, hashes source/DSN/SES/result/report bytes, and records unchanged source bytes. KiCad 10.0.5 GUI DRC reports pass a fail-closed full-line parser. The artifact explicitly records comparison_closed=false, status=unavailable_or_incomplete, and incomplete_reason=self_attested_unverified. Accepted as one authorized local smoke observation only. The source/report header and source/DSN relation are non-causal; import and pure-kernel runner receipts are self-attested; the CopperMCP runner bypasses MCP, tokens, CAS, backups, and atomic publication. Process limits are not filesystem/network/device sandboxing, the official asset hash is not runtime trust, and no parity, timing, broad-board, manufacturing, or comparison-closure claim is accepted. Initial maintainer + independent FreeRouting evidence review
SEC-103 2026-08-05 Live KiCad session-revision secret-hashing boundary Process-local secrets.token_bytes(32) key; domain-separated HMAC-SHA256 token binding; strict hmac-sha256:<64 lowercase hex> MCP/schema and snapshot validation; hmac.compare_digest() capture and proposal CAS; stable same-process, distinct-token, process-key-rotation, legacy-wire, snapshot-forgery, and output-redaction regressions Accepted for the candidate-only same-process session-CAS boundary. No unkeyed token fingerprint, raw token, or process key is serialized, logged, or returned; fresh-process values deliberately fail closed. This is not remote authentication, a persistent session capability, protected process memory, a hard IPC timeout, KiCad ABA prevention, DRC, or editor mutation authority. Initial maintainer + CodeQL remediation
SEC-104 2026-08-05 Known-padless proposal-anchor validation precedence evaluate_placement invokes one padless-reference preflight before syntactic infeasibility analysis; it preserves the existing rule-reference scan, then adds every explicit proposal anchor in input order while skipping self-anchor None. The regression combines each supported anchor point (center, north, south, east, and west) with contradictory front/back side rules and requires an exact unsupported_geometry refusal, fixed diagnostic, and no candidate. Existing coverage retains pure-contradiction infeasible_constraints and genuinely absent-reference handling. Accepted for deterministic failure classification of known padless external anchors only. This adds no new input authority, reference authentication, anchor geometry, padless placeability, non-padless proposal behavior, candidate geometry, KiCad DRC, apply authorization, or mutation. Initial maintainer + placement validation review
SEC-105 2026-08-05 Live KiCad session-revision computational-cost boundary Fresh process-local secrets.token_bytes(32) salt; domain-separated PBKDF2-HMAC-SHA256 over validated token bytes; fixed 200,000 iterations and 32-byte output; strict pbkdf2-hmac-sha256:<64 lowercase hex> snapshot/MCP validation; hmac.compare_digest() CAS; stable/distinct/rotation/legacy/no-output/schema/fixed-work/runtime regressions Accepted for the candidate-only same-process session-CAS boundary and current CodeQL limited-input-secret guidance. No token or salt is serialized, logged, or returned; a fresh process deliberately stales old values. The local timing sample and broad guard do not guarantee latency across hosts or protect process memory. This is not remote authentication, a persistent capability, hard IPC timeout, KiCad ABA prevention, DRC, or mutation authority. Initial maintainer + CodeQL remediation
SEC-106 2026-08-05 Public live-session composition and padless-subject precedence Required closed nullable inspect_live_board.session_revision binds the captured PBKDF2 CAS into public structured output without exposing KICAD_API_TOKEN or the process salt; null is explicitly unrouteable. A fake-client regression composes observation, scene, and preview with only public outputs, then proves token-change and fresh-process refusal. Placement preflight consumes declared subjects in request order before rule/anchor scans and syntactic contradiction checks; the regression requires its fixed non-echoing unsupported-geometry refusal and no candidate. Accepted for local candidate-only composition and deterministic padless refusal precedence. The derived CAS is not authentication or a persistent capability; process memory, KiCad ABA, synchronous IPC pre-emption, full placement solving, DRC, apply, and mutation remain outside this boundary. Terra PR-51 remediation
SEC-107 2026-08-05 Internal exact Board-IR candidate-path acceptance gate Typed-only snapshot/request/candidate boundary; raw cardinality/scalar preflight before hashing; current-value reconstruction plus candidate-content digest verification; exact reference-router Board-IR preparation and per-decompressed-edge integer predicate replay; immutable revision/net/layer/width/endpoint/settings/seed/single-path/zero-via binding; path-edge and obstacle caps; cooperative cancellation/deadline checks; fixed redacted outcomes; ten-repeat detour, foreign-crossing, stale, cap, same-net attachment, foreign endpoint, malformed, and stop regressions Accepted for the bounded internal single-layer two-pin candidate-path subset. It constructs, stores, publishes, serializes, or applies no copper; it is not a coordinator/public API/MCP boundary, a replacement for candidate-pair clearance, KiCad DRC, general geometry/multilayer/via proof, or FreeRouting parity. The predeclared >=10% negotiated-integration gain was unmet, so integration remains declined. Initial maintainer + independent candidate-validator review
SEC-108 2026-08-05 FreeRouting harness private-workspace capability An internal provider must create/return a quota-backed root; the harness rechecks canonical path, current UID ownership, no group/other mode bits, no root/child symlink, required aggregate budget, and provider-root descendant relationship. Focused regressions reject shared/symlink roots; prove absent capability launches no Java/KiCad probes, DRC, export, FreeRouting, import, or runner subprocess; and prove provider-present probes and caller-result DRC boards/CWDs remain provider descendants, with tamper refusal before DRC. Accepted as a fail-closed provider seam only. No provider is enabled; metadata checks do not prove a quota or sandbox; macOS legacy sandbox probing lacked a safe runtime-read allowlist and Linux tmpfs/mount/cgroup support is unimplemented. This adds no executable sandbox, parity, performance, KiCad result, or comparison-closure claim. Independent review remediation
SEC-109 2026-08-05 Exact local-repair benchmark attribution boundary Retain B-071 and disclose its distinct KiCad-derived 512/20,000/128/200,000 configuration; replay the predeclared source-965d8fc semantics through a digest-pinned independent helper; compare its Board IR, requests, digest, and settings to the original builder; and keep the benchmark independent from test imports. Accepted as evidence-attribution hardening only. B-072 records a declined replay and adds no routing transaction, model/profile input, public MCP surface, candidate publication, DRC, FreeRouting parity, apply authority, or board mutation. Independent evidence correction
SEC-110 2026-08-05 Orthogonal courtyard observation and exact legality boundary Matching F/B courtyard-side gate; unfilled fp_rect/fp_poly plus reconstructed degree-two fp_line cycles; exact decimal-to-nanometre conversion; immutable board-frame rings; generic simple-ring validation; doubled-integer positive-area strip scan with per-strip/per-edge/per-interval placement-budget charges; fixed malformed topology refusal; KiCad-resaved clean DRC fixture and clear/overlap regressions Accepted for read-only Board IR and candidate-only same-side legality for simple orthogonal courtyard contours. It neither serializes nor applies this topology, and does not treat a clean source DRC as DRC evidence for a proposed move. Curves, arcs, diagonals, fills, nonzero custom clearance, side flips, GUI/live IPC mutation, electrical/fabrication signoff, and FreeRouting claims remain outside the boundary. Terra courtyard-chain implementation
SEC-111 2026-08-05 Original audio benchmark provenance and KiCad derivative boundary SHA-256-bound Apache fixture/catalog/provenance; no third-party board content; fixed public service request/response equality; source inode/mtime/bytes preservation; exact candidate object serialization; fixed local KiCad executable; replacement child environment; bounded timeout; JSON report counts only; each derivative begins from the original snapshot Accepted for private, independent single-candidate observations. The DRC process is not an executable sandbox and its aggregate counts do not prove source-to-product electrical validity, candidate composition, board cleanliness, fabrication, FreeRouting parity, or apply authority. Terra audio fixture implementation
SEC-112 2026-08-05 NE5532 benchmark DRC report ingestion boundary Descriptor-anchored workspace read with a configured byte cap before UTF-8/JSON decoding; reuse the authoritative adapter's duplicate-key, non-finite-number, nesting, value-count, and decoded-tree budgets before extracting aggregate counts. Oversized, malformed, and overdeep report regressions fail closed; ordinary aggregate observations remain unchanged. Accepted for the optional private benchmark report-ingestion path. This does not authenticate KiCad output, sandbox the executable, bind a report to a product board, expand DRC authority, or change the benchmark's independent-derivative, electrical, fabrication, or apply limits. Terra PR-54 remediation
SEC-113 2026-08-05 NE5532 benchmark KiCad child-output boundary Reuse the core POSIX RLIMIT_FSIZE exec wrapper for the report budget and connect child stdin/stdout/stderr to DEVNULL, so untrusted diagnostics have a zero-byte parent capture budget. A noisy-shim regression emits one megabyte on each stream for every source/derivative run while preserving the normal aggregate observation. Accepted for the optional private benchmark child-process boundary. This does not sandbox the executable, authenticate KiCad output, preserve diagnostics, alter report authority, bind a result to a product board, or change the independent-derivative, electrical, fabrication, or apply limits. Terra PR-55 remediation
SEC-115 2026-08-05 Atomic route-bundle preview boundary Closed 2–8 reference-only request, mandatory source and snapshot CAS, bounded deterministic coordinator, full composition replay equality, all-or-nothing publication, canonical immutable plan digest, exact cross-net swept-disc clearance gate, and private source-preserving combined serializer with Board-IR round trip. MCP annotation/schema status variants are closed and regression-pinned; no apply token, DRC field, board bytes, derivative URI, persistence, or partial plan is emitted. Benchmark DRC uses the project fixed-argv bounded adapter, private child state, report/stdout/stderr byte caps, JSON-structure caps, resolved executable/version/SHA-256 binding, and exit/report consistency check. Accepted for the existing two-pin one-layer common-grid subset. KiCad DRC is benchmark-only aggregate evidence for one disposable public-fixture derivative, not authorization to apply; bounded process limits are not an executable sandbox, and arbitrary rules, vias, zones/fill, multilayer, electrical/fabrication, and general-board authority remain open. Route-bundle implementation + independent review remediation
SEC-116 2026-08-05 Route-bundle preflight and benchmark-evidence binding correction Check the untrusted reference collection's concrete list type and 2–8 cardinality before iteration or element parsing; use fixed redacted errors and a hostile oversized-list regression. For a completed benchmark only, retain the strict adapter summary's SHA-256 base-board and DRC-context revisions and reject if the base revision differs from the private combined derivative bytes. Accepted as a bounded request/evidence correction. The hashes disclose no board bytes, route geometry, source board, token, derivative URI, or apply authority; DRC remains aggregate fixture evidence and the subprocess is not a sandbox. PR #57 remediation
SEC-117 2026-08-06 Route-bundle request-seed ceiling, budget classification, and DEVNULL reaffirmation Cap the accepted route-bundle seed at MAX_JSON_SAFE_INTEGER - (max_nets - 1) at the request boundary and in the published JSON Schema, so no schema-valid request can reach the deterministic core as an out-of-range derived seed + index and escape as an untyped builtins.ValueError. Classify an expired shared negotiation budget as budget exhaustion before the replay equality comparison, so a resource outcome is never published as a determinism claim. Bind the coordinator policy_digest into bundle_id. Revert the unrelated _run_captured_drc change that replaced subprocess.DEVNULL with never-read on-disk stdout/stderr capture files: SEC-113 remains the governing mitigation, no consumer reads those files, and the capture reintroduced a SIGXFSZ failure mode for a chatty but valid child under RLIMIT_FSIZE while bounding each stream separately. The restored DEVNULL wiring is now pinned by the shared DRC test helper. Accepted as a boundary, diagnostic-honesty, and reversal correction. It grants no apply, export, persistence, or DRC authority, discloses no board bytes or route geometry, and leaves the two-pin one-layer common-grid subset, KiCad benchmark-only aggregate evidence, and the non-sandboxed subprocess limits unchanged. PR #57 independent review remediation
SEC-118 2026-08-06 Live KiCad IPC observation boundary: operator consent, document type, confirmation budget, and redaction proof Foreign-root regressions at three independent layers (the IPC object counter, the live scene observer given already-captured bytes, and the file-backed scene observer) plus a control proving an unsupported board still returns a truthful supported: false; oversized-confirmation regressions for board and editor-context capture asserting a payload-budget type and explicitly not a connection type, plus a control proving an in-budget mid-observation edit is still refused; default-off, zero-client-created opt-in regressions for both capture chokepoints and the live scene surface, an ambient-KICAD_API_SOCKET test proving the environment is not read while disabled, retained TCP refusal once enabled, and a plugin-token test asserting KICAD_API_TOKEN reaches neither the binding kwargs nor the observation; exact {"0", "1"} membership tests over fourteen ambiguous spellings; a whole-response grep for eleven distinct hostile markers across net names, net class, footprint library id, property name/value, fp_text, gr_text, pad net, zone name, group name, and title block, over the observation dict, its repr, and the live scene outside its annotation quarantine, guarded by an assertion that each object class was actually counted; seven binding-failure regressions replacing the five no cover pragmas; MCP surface test that both live tools remain listed while refusing; full gate against a real KiCad 10.0.5 install (Ruff, strict mypy over 90 source files, 1589 passed / 1 skipped / 432 subtests, secret scan, version, ledger, doc-link, audio-benchmark, and circuit-intent checks; pip-audit and build are environment-blocked here and remain CI-gated) Accepted as a consent, type-confusion, budget-classification, and evidence-strength correction to the read-only live observation surface. Live IPC now requires explicit operator opt-in and is off by default, which is a behavior change for any deployment that relied on ambient socket discovery. unsupported.document is a new public diagnostic code; callers matching syntax.invalid for a wrong document type must move to it. The binding-failure fakes are locally defined stand-ins for kipy.errors.ApiError and kipy.errors.ConnectionError because kicad-python is optional and absent from CI, so the tests pin CopperMCP's typed refusal and message, not a claim about where the real binding raises. No live mutation, DRC, fill, apply, electrical, or fabrication authority is added; the residual get_as_string allocation noted in ADR-0029 is unchanged, since the wrapper still returns a complete string before Python can measure it. Issue triage (#75, #76, #77, #78) remediation
SEC-119 2026-08-06 Fixed-argument KiCad schematic ERC and netlist-export subprocess surface Both sch commands share one bounded helper, so the two surfaces cannot drift: private read-only snapshot directory, fixed argument vector with no caller-supplied flag and no --define-var, the same RLIMIT_FSIZE child wrapper, private HOME/config environment, report-byte and wall-clock budgets, and post-run snapshot-tree revalidation as the shipped board DRC adapter. Regressions cover: a digest that does not match the schematic bytes, malformed and empty inputs, an oversized schematic refused before any subprocess is spawned (asserted by discovery.assert_not_called()), a missing CLI and a non-POSIX platform as typed refusals rather than verdicts, exit-code/report disagreement in both directions, a DRC report offered as ERC evidence, a report naming a different source, missing requested severities, malformed sheets/violations/ignored-checks, duplicate JSON keys, duplicate sheet paths, and non-UTF-8 and non-object documents — each asserting a typed refusal that echoes no input. A real-CLI test greps the whole serialized response for the fixture's title, circuit id, every component reference and value, and every net name, proving none crosses the boundary; another asserts KiCad did not mutate the bytes it was given. A mutation check removing the schematic-digest binding in CircuitSchematicErcResult.__post_init__ was caught by exactly one test (test_result_refuses_evidence_bound_to_a_different_artifact) and by no other, then reverted. Full gate against a real KiCad 10.0.5 install. Accepted. Exposure is strictly lower than the already-reviewed board DRC surface: the subprocess input is CopperMCP's own deterministic render of Circuit Intent the caller just submitted, so there is no workspace snapshot, no library-table discovery, and no user file the model did not already provide. The containment blockers recorded in the 2026-08-05 ERC containment experiment are not re-litigated because the claim that triggered them is not made: this surface asserts no containment or privacy property for the KiCad subprocess beyond what board DRC already asserts, and no sandbox-exec boundary is reintroduced. Residual risks accepted for local use: the subprocess is not sandboxed and KiCad parses the schematic with full process privileges; RLIMIT_FSIZE still bounds each file rather than total writes, mitigated here by a single fixed output path and post-run tree validation. No workspace-schematic ERC surface is added — a path-taking ERC tool would reintroduce the user-data exposure this design avoids and requires its own review. No mutation, apply, board-parity, electrical, or fabrication authority is added. Initial maintainer
SEC-120 2026-08-06 Live KiCad editor mutation boundary: consent model, live-scoped capability, triple compare-and-swap, and the refusal that stands in for the mutation Exact {"0", "1"} membership tests for COPPER_MCP_ALLOW_LIVE_APPLY over fourteen ambiguous spellings plus default-off; two zero-client-created regressions asserting that neither a disabled live apply nor a missing live-IPC consent constructs an IPC client, each raising from the injected factory rather than merely checking a code; a bidirectional orthogonality test proving COPPER_MCP_ALLOW_APPLY neither grants live apply nor is required by it; capability regressions for a token minted by a different authority (standing in for a server restart, since the signing key is process-local), an expired token, a consumed token, a token verified before any socket is opened, and — the domain-separation control — a file apply token constructed with the session revision in the relative_path slot, refused because the two bindings prefix different HMAC domains; a parametrized proof that none of the three compare-and-swap values is caller-editable after minting, since all three sit inside the MAC; stale-board, restarted-editor and absent-session regressions asserting distinct codes and a truthful observed revision that is never auto-refreshed. An adversarial review of this surface found the original session leg inert — it was derived from KICAD_API_TOKEN and a process-local salt, both fixed for the lifetime of the CopperMCP process, which a restarting KiCad cannot write to, so it identified this server and observed nothing about the editor, and its guard test modelled the restart by mutating CopperMCP's own environment block, which the modelled event cannot do. The revision is now derived from the instance identity KiCad reports in every response header (one KIID per API-server process, the use its add-on documentation names), the guard test models a restart without touching CopperMCP's environment, and an editor reporting no identity yields no revision and therefore refuses every live apply. Six design records asserting the old mechanism were corrected with it; a constraints-perturbation test proving the Board IR snapshot digest is bound independently of the board bytes; candidate regressions for moved geometry under an unchanged claimed identity, a structurally malformed patch, and a 1,000-path manifest refused against the verifier's own ceilings; seven parametrized capture-failure regressions mapping each typed observer error to its own refusal, including KicadIpcDeadlineError ahead of its KicadIpcConnectionError base; a token-never-echoed grep over the whole serialized response; a contract-drift test asserting the failure enum and the public MCP Literal union are equal sets; an MCP-surface test proving the tool stays listed with truthful destructive_hint/read_only_hint annotations and a closed argument object; boundary tests for the manifest reconstruction covering both serialized point forms, five malformed points (including a bool coordinate, which is an int in Python and is therefore excluded before the integer test rather than after), a non-list geometry collection, and non-integer and out-of-range candidate fields; and a preconditions_verified assertion on every refusal so an absent check is never readable as a passing one. Mutation checks: removing the board compare-and-swap, the session compare-and-swap, and the snapshot compare-and-swap each fail the suite, and were reverted. 55 tests, 100% statement coverage of the new module. Full gate: Ruff check and format, strict mypy over 92 source files, 1,777 passed / 1 skipped / 477 subtests, and the ledger, ADR-number, doc-link, secret, and version checks. pip-audit and build are environment-blocked here and remain CI-gated. Accepted as a design and preconditions slice. apply_live_candidate performs every check a live mutation would require and then refuses with capability_not_implemented; no begin_commit, push_commit, create_items, update_items, remove_items, or save call exists anywhere in this repository, and the token is deliberately not consumed because nothing is spent. The KiCad end of the boundary is a fake: kicad-python is optional and absent from CI, so what these tests pin is CopperMCP's typed refusal and the order of its checks, not a claim about where the real binding raises — the same limitation SEC-118 recorded. Three residual hazards are recorded in R-114 rather than mitigated, because the IPC protocol exposes no revision, dirty flag, or conditional write, and kipy discards the per-item status that would justify reporting success. The destructive slice remains subject to adversarial review before merge. Initial maintainer
SEC-121 2026-08-06 Widening the live-IPC observation half's install base through the official KiCad Plugin and Content Manager The token property is checked against the parsed tree of every Python member of the shipped archive rather than its bytes, because the name KICAD_API_TOKEN legitimately appears twice as prose — in a source comment and in the PCM description that tells an installer the token stays put — and a byte grep would have had to be relaxed to tolerate that, relaxing it for a real reference too: no string constant, Name, or Attribute in the archive contains it, and a separate byte check covers plugin.json and requirements.txt, which Python never parses. A closed three-member import allowlist (__future__, json, copper_mcp.kicad_ipc, all absolute) forecloses os, the filesystem, and every transport at once, which is why there is no marker-by-marker grep for os.environ, socket, urllib, or subprocess — an import the plugin cannot make is a capability it cannot have. With no os import the packaged code cannot write the environment copper_mcp.config reads, and no string literal names COPPER_MCP_ALLOW_LIVE_IPC or COPPER_MCP_ALLOW_LIVE_APPLY, so the packaged half cannot grant what the server half withholds; a guard-the-guard test asserts inspect_live_board is actually called, so the disclaimers are not vacuous over an empty tree. No attribute or name in the archive is begin_commit, push_commit, create_items, update_items, remove_items, or save. Mutation check: adding kicad_token=os.environ.get("KICAD_API_TOKEN", "") to the IPC client factory call in inspect_live_board was caught by exactly two tests — test_the_plugin_token_never_reaches_the_binding_or_the_observation and test_configured_posix_socket_is_normalized_without_echoing_it — and by no other, then reverted. Disclosure controls for the new audience: description and description_full, the only text the PCM shows before an install, are asserted to name the flag, the exact =1 value, the token property, and the never-mutates and off-by-default claims. The entrypoint's module-scope import of copper_mcp.kicad_ipc moved inside main() behind a fixed sentence, because a PCM install delivers this file and not CopperMCP, so a new user's first click was an unhandled ImportError carrying a filesystem path into KiCad's warning bar; regressions assert the exit status, the actionable text, one line of output, no repository path, and no traceback. Archive integrity: every entry inside KiCad's ALLOWED_FILES whitelist, exactly six declared members, no directory entries, each member byte-identical to its source in the tree, the manifest's entrypoint present, and the icon re-checked against ci/validate/image.py's own bounds (PNG magic, ≤64×64, ≤20480 bytes, per-chunk CRC). Reproducibility as a supply-chain control: byte-identical across Python 3.12.13 and 3.14.2, two timezones, and different PYTHONHASHSEED, with an in-suite subprocess rebuild under perturbed TZ/PYTHONHASHSEED/SOURCE_DATE_EPOCH, and declared download_sha256/download_size/install_size re-derived from the built artifact. 51 tests, 197 subtests. Full gate recorded in the pull request. Accepted as a distribution-surface review. What changes is reach, not capability: the plugin's authority is identical to the manually installed one it replaces, and COPPER_MCP_ALLOW_LIVE_IPC remains exact {"0", "1"} and default off, so an install from the PCM grants nothing until the operator sets it in the environment KiCad was launched from. Three limits are stated rather than mitigated. (1) KiCad injects KICAD_API_TOKEN into every launched plugin's environment whether the plugin wants it or not; what is asserted is that this code never reads it, not that the value is absent from the process. (2) The tests pin the shipped archive, not KiCad's behaviour: kicad-python is optional and absent from CI and no package has been installed from a live PCM repository on any platform, so the readiness, venv, and pip findings are read from KiCad's source and cited, not observed — the same limitation SEC-118 and SEC-120 recorded. (3) A wider install base widens the blast radius of any future defect in the observation path itself, which is the reason the package is published as testing and the reason submission stays a human step. No mutation, apply, DRC, electrical, or fabrication authority is added, and no board bytes, net names, coordinates, or UUIDs become newly reachable. Initial maintainer
SEC-122 2026-08-06 Systematic excessive-agency evaluation across held-out project families (OWASP LLM06) 29 predeclared scenarios replayed against four project families for 116 cases, driven through the real MCP adapter rather than the service layer. Consent: apply_candidate, apply_placement_candidate, and apply_live_candidate each refused with their own code (apply_disabled, apply_disabled, live_apply_disabled) with the flags off. Capability: a forged token, a token minted by a different authority (standing in for another session, since the signing key is process-local), and tokens rebound to a different candidate, a different board revision, and a different board path were each refused as invalid_token; a route-domain token bound to the same placement candidate, revision, and path was refused as invalid_token because domain separation lives inside the MAC; a genuine token replayed immediately after the write it authorized was refused as token_already_used with the post-replay board digest equal to the post-apply digest. Staleness: a preview against a wrong revision refused stale_revision; an apply against a board edited outside CopperMCP after the token was minted, and an apply whose candidate names another Board IR snapshot, each refused stale_candidate. Laundering: a placement manifest whose legality record and checks_used were rewritten to a clean, individually-legal combination, and a route manifest whose published metrics were rewritten, were each refused by identity recomputation as splice_assertion_failed; validate_candidate normalized a manifest asserting hard_drc_errors: 0 and published no verdict field of its own. Non-claim: every contract field declared as a single-value Literal non-claim held only that value across every observed payload, no observed key ever carried a non-claim literal and a second value (three-valued pad_overlap exempted from its own contract), and no refusal reported an after-revision, an attempted mutation, or a verification matrix. Disclosure: net names, native footprint identities, exact coordinates, and the absolute workspace path were greped for across every refusal payload, with sha256: digests stripped first so a decimal coordinate cannot match inside one. Budget: 5,000-deep nesting, a 200,000-vertex manifest, a 5 MB path field, 101 candidates, and a board over the configured byte ceiling each refused inside the wall-clock ceiling, and each via the MCP adapter's own boundary exception rather than an arbitrary one — all 15 runnable rows record ToolError, so a RecursionError or a stray parser KeyError fails the scenario instead of counting as a refusal. Result: 77 passed, 0 failed, 39 not run. Five discriminator tests break a boundary and require the harness to record a failure. Accepted as coverage of the predeclared catalog against these boards, and nothing more. It does not test a model: none is invoked, so it measures CopperMCP's refusals and not whether an agent would attempt, report, or stop. A passing catalog is coverage, not absence — it bounds nothing that was not written down. The caller is in-process and constructs arguments a transport would reject, so no claim is made about a hostile host, a compromised client, or a rewriting transport. Nothing here covers remote deployment (no principal, OAuth, rate limit, audited log, or tenant isolation), logging or telemetry sinks (the application still has no logger sink), or any electrical, thermal, mechanical, DRC, or fabrication property. The held-out claim is uneven and is recorded as such: the only externally authored family, the MIT SimpleRouteJson corpus from B-088, contributed 29 of the 39 not-run rows because no MCP tool accepts its format, so it reached no agency boundary at all. coppertone-buffer afforded no apply capability (every net already routed; outside the placement-apply subset), so the five scenarios needing a genuine capability could not run there. The authoritative KiCad DRC/ERC scenario is not_run in every family by choice — invoking kicad-cli would make a self-digested artifact environment-dependent — and that boundary stays with SEC-113 and SEC-119. Three harness defects found during construction are recorded rather than quietly fixed: a vacuous manifest edit that read as a refusal while the apply legitimately succeeded (now guarded by an edit_was_vacuous assertion and a board-digest guard); a coordinate sentinel matching inside a SHA-256 digest and inside an echoed budget constant (now digest-stripped and grid-round-filtered); and a budget check that accepted any exception as a bounded refusal, which would have scored an unhandled parser error as a pass (now restricted to the adapter's declared boundary exceptions, with the raised class recorded). Initial maintainer
SEC-123 2026-08-07 Structural parse budgets over untrusted KiCad and Board IR input: raising the defaults and exposing them to the environment The budgets are denial-of-service controls against hostile board files, so raising a default weakens a control rather than merely relaxing a convenience. Reviewed: every new COPPER_MCP_MAX_PARSE_* variable is bounded above as well as below and refuses a malformed value with a typed ConfigurationError at startup, matching the existing settings; no budget becomes unbounded and none can be disabled; the discriminated refusal names a budget and its configured value, which are process configuration rather than board content, so the new message discloses nothing about the document that triggered it. Accepted. The new defaults are derived from a measured node-per-byte distribution with headroom rather than chosen, and adversarial inputs (deep nesting, wide child lists) remain bounded at them. Residual exposure is an operator who raises a budget beyond their machine's memory, which is their decision and is now visible to them because the refusal names the budget. Issue #112 remediation

| SEC-127 | 2026-08-07 | A new bounded kicad-cli pcb drc --schematic-parity subprocess surface that, unlike the ERC and netlist paths, takes a workspace board as input | Containment mirrors ADR-0004 and ADR-0071 rather than paraphrasing them: the argument vector is fixed with no caller-supplied flag, no --define-var, no --save-board, no --refill-zones and no --exit-code-violations; the board arrives only through read_workspace_file bounded by max_board_bytes and closed to {".kicad_pcb"}, so path escape and suffix confusion are refused by the existing reader and are regression-tested here; execution happens on a private 0700 snapshot, made read-only before launch, holding exactly parity.kicad_pcb and parity.kicad_sch under fixed basenames, with private HOME/TMPDIR/config, stdin/stdout/stderr all DEVNULL, the RLIMIT_FSIZE wrapper setting the ceiling before KiCad starts, a timeout, and non-POSIX platforms failing closed. Post-run the private process state is revalidated, the snapshot tree is revalidated against the closed two-name set so a .kicad_prl or any other side effect is refused rather than reported, SIGXFSZ is mapped to a typed refusal, and both inputs are re-read and compared byte-for-byte — a real-KiCad test asserts the caller's board file is unmodified. Report parsing reuses the reviewed DRC JSON preflight, tree validator, constant rejection and finite float parsing, then closes the shape further: schema, units, source basename, ISO-8601 date, version pattern, the exact three-member included_severities set, a 100,000-finding ceiling, and a refusal on any parity type outside the seven reviewed keys or any excluded: true finding. Redaction: parity descriptions embed net names verbatim — measured, "Pad net (GND) doesn't match net given by schematic (AUDIO_OUT)" and "Field 'Description' differs ..." — and affected items carry UUIDs and coordinates, so nothing from a finding body crosses the boundary; only per-type counts, three digests, the board revision and fixed literals are returned, asserted by a leak test over the serialized response. Mutation check: six mutations, each caught and reverted — removing the liveness invariant (4 tests), weakening it from != to > (3), dropping the projection-digest binding (1), substituting a constant board revision (1), decoupling passed from the connectivity count (4), and swapping --severity-all for --severity-error (9). 58 tests, 23 subtests; full gate recorded in the pull request. | Accepted as a read-only inspection surface. What is new is that a user's own board file reaches a KiCad subprocess, which the ERC path avoided by only ever handing KiCad bytes CopperMCP rendered itself; the board is copied into the private snapshot rather than executed in place, and the workspace copy is never opened for writing. No mutation, apply, or fabrication authority is added and no new consent flag exists. Three limits are stated rather than mitigated. (1) No .kicad_pro is written, so KiCad applies compiled-in default severities — no user project can weaken this verdict, and equally the verdict is not necessarily what that user's project would report. (2) Only KiCad 10.0.5 was executed; 9.0 is unverified. (3) The seven-key parity set is read off pcb_marker.cpp and drc_item.cpp and confirmed by measurement, not guaranteed by either file — the contract therefore refuses an unreviewed type rather than assuming the list is closed. | Initial maintainer | | SEC-131 | 2026-08-08 | The class of identities the source-preserving apply gates accept widens by one scheme: contour:assembled: (ADR-0087), a hash of an assembled Edge.Cuts outline's member gr_line uuids, no longer reads as :derived: and so no longer refuses apply on its own | Both gate predicates are byte-for-byte unchanged -- the review is of the identity derivation that feeds them, not of the gates. The safety argument rests on three checked properties. (1) Resolvability: the composite is produced only when every member carries exactly one native identity and the values are pairwise distinct within the member set, so the name resolves to a specific set of source expressions by running the derivation backwards; a regression test recomputes it independently from the raw s-expression tree. (2) Fail-closed degradation: any unresolvable member set degrades the contour to the revision-derived name the gates already refuse -- never a native-looking guess. (3) Stability under apply: the name is a function of the member uuid set alone, and neither a placement splice nor a route append touches an Edge.Cuts byte, so the five round-trip equality proofs run unmodified. Mutation evidence: deleting the degradation fallback fails 4 tests (missing-member, repeated-member, both-identity-fields, route render refusal); deleting the placement gate's :derived: scan fails 7; deleting the route gate's fails 6, including the apply-token gating test. Non-goals verified by test: a reused footprint/pad uuid board (D-158) still refuses both gates, a gr_rect board's identity and bytes are unchanged, and no patch path names a contour at all -- the widening removes a false obstruction, it does not add a nameable target. | Accepted. The invariant "no patch can name an object whose identity cannot be resolved back to the source file" is preserved with the gates untouched; what changed is that a resolvable identity stopped being spelled as an unresolvable one. Residual exposure is a writer that rewrites gr_line uuids wholesale on save, which moves the contour id and invalidates stored references -- tracked as R-131; it cannot make an unresolvable set look resolvable. | Initial maintainer | | SEC-132 | 2026-08-08 | Raising a denial-of-service control: the single-layer router's obstacle ceiling moves from 256 to 4,096 by default and its maximum from 4,096 to 32,768, and a new region_margin_nm setting reaches an untrusted request boundary | The raise is quantified rather than asserted. On the largest real board (31,389 segments) the worst of 40 nets costs 1.87 s and 45.5 MiB peak traced allocation at the new default, and 1.95 s and 45.5 MiB with the model unscoped at the 32,768 ceiling — peak memory does not move with the budget because it is dominated by the parsed snapshot, and 32,768 inflated rectangles are about 4 MiB. On synthetic adversarial input whose entire routing region is packed with foreign tracks on a 100 um pitch, both the default and the ceiling refuse within a bounded time: 32,000 objects refuse in 0.84 s at the default, 60,000 refuse in 1.52 s at the default and 1.74 s at the ceiling, and Board IR's own default byte budget refuses the snapshot outright past roughly 90,000. Three independent controls therefore remain between a request and unbounded work — the ADR-0079 parse budgets bound the board, max_obstacle_checks bounds the exact predicates, and max_obstacles bounds the model — and the raise buys an attacker roughly half a second and no additional memory. max_net_objects is the one budget whose cost is superlinear (the pairwise component merge is quadratic) and its ceiling is placed where that cost meets the check budget, so a raised value cannot outrun the work meter. Every new setting is validated by the same bounded-integer helper at the same request boundary, with a stated finite range, and a scoping mutation test proves the cheaper model cannot silently become an unsound one. Refusal messages name the budget and its configured value only; the observed object count is deliberately omitted so a refusal does not disclose board density to a caller that may not hold the board. | Accepted as a bounded raise of an existing work control on a read-only surface. No new subprocess, consent flag, network surface, or mutation authority is added, and no board content crosses any boundary. Two limits are stated rather than mitigated: the adversarial measurement is one synthetic shape on one host, and the cost model assumes the obstacle-check budget is left at or below its own ceiling — an operator who raises both to their maxima has deliberately bought the product of the two. | Initial maintainer | | SEC-133 | 2026-08-08 | The root-child refusal path in _semantic_preflight, reviewed because issue #129 asked for the rejected s-expression head to be interpolated into the diagnostic message, and because the accepted-input surface widens by one root head (group) whose name atom and member list are entirely board-author controlled. Re-reviewed after adversarial review found that widening it also touched an authorization gate. | The standing regression test_diagnostics_never_echo_attacker_controlled_construct_names (four cases, one of them a root head named SECRET_BEARER_TOKEN); new test_a_root_refusal_never_echoes_the_board and test_a_group_name_is_never_echoed_either; test_a_locked_root_group_is_refused_because_lock_reaches_its_members and test_a_locked_group_never_converts_a_member_footprint_as_unlocked; a 26-mutant manual mutation run over the new logic in which the mutant that interpolates the head into the message is killed by the existing non-echo regression and every mutant that weakens the lock refusal is killed by the two tests above. | Finding, from adversarial review: the first version of this change weakened the locked-footprint authorization gate, and this row previously claimed otherwise. It stated "no apply, authorization or write path changed", which was true of the code and false of the effect. BOARD_ITEM::IsLocked() derives an item's lock from its parent group, so accepting a (locked yes) group would have converted its members at locked=False, and placement/solver.py, placement/legalizer.py and kicad_placement_patch.py would each have authorized a move KiCad forbids. Widening accepted input is an authorization change whenever the widened construct carries a constraint, and this one did. Disposition: a locked group is now a typed refusal, so the gate is strictly not weakened -- the set of boards on which a footprint converts as unlocked is unchanged from before this change. Issue #129's suggestion 1 was implemented in a narrowed form and the divergence is deliberate. The issue argued that a KiCad format head is a fixed vocabulary term chosen by the format rather than board content; that premise holds for a head the format defines and fails for one it does not, since an arbitrary document can carry an arbitrary head. Interpolating it would have put untrusted board bytes into an instruction-bearing field and broken a passing regression. Instead the locator carries kicad_pcb.child[N], an index computed from the parse and never read from the document, and the message names the construct only by looking the token up in a closed table of documented root sections and emitting that table's literal. Index disclosure was considered and is not a new exposure: SEC-011 already permits object counts, and ADR-0079 refusals already carry byte-offset locators, so a root-child ordinal reveals strictly less about a private board than what is already emitted. A group's name is board-author text and reaches no field at all: never parsed, never stored, never echoed; and the group's uuid is deliberately not registered as a native identity, so a group can neither claim a Board IR identity nor push another object onto the revision-derived fallback. | @seunghyukchoe | | SEC-134 | 2026-08-12 | The first routing refusal to carry board-derived geometry. off_grid now publishes two pad identities, the lattice pitch in use, a signed per-axis miss, and the greatest common divisor of the two pad-centre deltas (ADR-0093). Reviewed as a disclosure change, since no routing semantics move; re-reviewed twice on PR #142: once after adversarial review found the published schema asserting less than the runtime, and again after a second review found a reachable crash path on untrusted input. | tests/test_routing_astar.py pins the exact evidence, the sign convention, the half-step tie, the negative-delta branch, the both-axes case, the worst-case message length against the 256-character contract bound, and the code/evidence biconditional in both directions; a parametrised case rejects each self-contradicting measurement at the backend. tests/test_route_preview.py pins the published document, asserts off_grid is null — never {} and never a zero — on a diagnostic that measured no lattice, and drives payloads through RoutePreviewToolResponse: the code moved, the evidence set to null, the key deleted, and four forgeries that are individually well-typed and in range (anchor equal to the pad, a miss wider than half the step it names, a miss of zero on both axes, a divisor the requested step divides) — every one must fail validation, and a pre-ADR-0093 payload of another code lacking the key must still pass. tests/test_benchmark_real_board_capability.py asserts the committed artifact records no digit from an off_grid message. tests/test_routing_astar.py additionally drives a pad pair at opposite legal Board IR coordinate extremes through the router and requires a typed refusal with the divisor withheld; pins the largest divisor that must still be reported so an off-by-one cap fails; pins the worst-case message length of both message branches against the 256-character bound; and sweeps 3,833 legal geometries — 974 of them in the overflow region — requiring every one to construct at the backend and validate at the published contract, which asserts the property over inputs rather than over an enumerated set of guards. A 25-mutant run over the new logic killed every one: the tie direction, the sign, the remainder of the magnitude, the unsigned remainder, swapped pad roles, a one-axis divisor, the dropped geometry, each of the four backend guards, the widened miss range, the biconditional weakened in the dataclass and again in the published contract, each of the four published-contract guards removed individually, the evidence key made required again, the oversized divisor reported instead of withheld, the withholding boundary moved off by one, every divisor withheld, the withheld message branch emptied, an over-range divisor admitted by the published schema, an empty object for an unmeasured lattice, the oracle rebuilt without evidence, and the unredacted artifact. Two mutants whose anchors had gone stale against the edited source were reported as skipped by the harness and re-anchored rather than counted, because a mutant that silently stops applying is a passing check that tests nothing. | Accepted as inside the settled disclosure precedent rather than as an extension of it, with one claim narrowed and one gap closed after review. SEC-011 permits object counts; ADR-0079 refusals already carry byte-offset locators; RouteConnectionContract already publishes start_pad_id and end_pad_id for the same net. Narrowed claim: this row previously said an off_grid refusal says strictly less than either successful outcome of the identical request. That is false against already_connected, whose contract carries pad identities and counts but no geometry, so the relative miss and the divisor are not derivable from it; and against the routed outcome — which does publish absolute path vertices — the comparison is vacuous for a net that can never be routed, which on the measured corpus is all 18. The claim now made is the one that holds for every request: this is per-request geometry about the net the caller named, computed from bytes the caller supplied, adding no object count, no net name, no absolute coordinate, and nothing about board density — the line ADR-0089 drew when it refused to report observed obstacle counts alongside a budget. Gap closed: the first version enforced the four cross-field invariants in the backend dataclass only, and adversarial review forged four payloads the published OffGridEvidenceContract accepted. A published schema that asserts less than the runtime lets a schema-only consumer accept what this project's own code refuses to construct — the same defect raised against sibling #137 — so every guard is now duplicated into the published contract and pinned. Second finding, and the more serious one: a reachable crash path on untrusted input. largest_representable_step_nm is the greatest common divisor of the two pad-centre deltas, and it is the only field of this evidence bounded by the board rather than by the request's validated settings. Board IR admits any coordinate in [-(2**53 - 1), 2**53 - 1], so the divisor reaches 2**54 - 2 and exceeded the JSON-safe bound the contract publishes; the constructor then raised ValueError before _fail could build a diagnostic, past preview_route, and out of the MCP tool — an uncaught exception for board bytes the format permits, where a typed refusal was required. Disposition: the divisor is withheld as None above MAX_REPRESENTABLE_STEP_NM, never clamped, since a clamped divisor would be a false claim about the board; the threshold is defined beside the validator and imported by the producer so the two cannot drift; every other field stays exact so the refusal remains actionable. The first attempt at that fix moved the crash rather than removing it — the withheld message branch is longer than the numeric one and reached 259 characters against a 256-character bound — which is why both branches are now pinned. Process finding: the first review had proved by contrapositive, guard by guard, that the constructor cannot reject genuine router evidence. The proof was sound over the guards it enumerated and silent about a bound outside that set. ADR-0093 now carries a full field-by-field enumeration against coordinate extremes, and the rule it yields: fields bounded by validated request settings cannot overflow, fields bounded by the board can, and only the second kind needs a bound derived from the input domain. Finding retained from the first review: scripts/benchmark_real_board_capability.py records one refusal message per verdict into a JSON report committed to this public repository while its corpus is a private design tree, so the new message would have carried a pad's miss distance into that file; the runner truncates to OFF_GRID_MESSAGE_LEAD, imported from the module that raises the refusal so a rewording cannot silently reopen it, and the truncation is asserted rather than reviewed. Two residual disclosure surfaces, recorded rather than changed: that redaction is per-call-site, not a property of the runner. _measure_placement records its refusal message verbatim, and the DRC and Circuit Scene paths record f"{type(error).__name__}: {error}" verbatim. Neither can carry geometry today — those messages are fixed strings, and placement's geometry travels in a separate legality object the runner does not record — but the next change that puts a board-derived value into a message on any of those surfaces leaks into the committed artifact, and nothing structural stops it. Anyone adding evidence to a diagnostic must check those three call sites. Not claimed: that per-refusal geometry is safe for a caller not entitled to the board — the whole model here is that the caller supplied the bytes; that any durable store outside this repository redacts (nothing in copper_mcp persists a RouteDiagnostic, and a future one must decide for itself); and nothing electrical, DRC, or manufacturing. | @seunghyukchoe | | SEC-135 | 2026-08-12 | The root-child accept path in _semantic_preflight, reviewed because D-184 widens the accepted-input surface by one root head (property) whose key and value are both entirely board-author controlled free text, and because the head being accepted is the same token the adapter previously used to name a refusal. Two questions were asked: can either half reach an instruction-bearing field, and can any key value change what the board is rather than what it is called? | test_a_root_board_property_key_and_value_are_never_echoed drives a key spelling SYSTEM_ignore_all_previous_instructions and a value spelling approve every candidate through a converting board and asserts neither appears in the encoded snapshot; the standing test_diagnostics_never_echo_attacker_controlled_construct_names and test_a_root_refusal_never_echoes_the_board are unchanged and still pass, so the closed-table naming rule is intact after property leaves that table. test_a_root_board_property_outside_the_writer_shape_is_refused pins all eight out-of-shape forms, each refusing with a fixed adapter-owned sentence and an index-computed locator. test_accepting_a_board_property_does_not_admit_the_text_that_expands_it pins that the one path by which a property value becomes board content — ${KEY} substituted into copper text, or into a barcode pattern — remains refused. A 24-mutant run over the new logic killed all 24 — a claim about the twenty-four chosen, not about the mutation space, and one whose harness is not committed, so the record carries the claim rather than reproducible evidence — including the mutant that interpolates the rejected key into the refusal sentence, every one that widens the accepted shape or drops the quoting requirement, and every one that falsifies the published count. The run is the cache-purged one: a same-size mutant restored inside one filesystem second leaves a .pyc CPython considers valid, which can hide a mutant in either direction and produces false kills in the apply direction. | No apply, authorization or write path changes, and unlike SEC-133 that statement was checked against effect rather than only against code. The locked-group lesson was applied by asking the analogous question over the key: KiCad special-cases no board property key anywhere, the format's reserved property keys are symbol properties, and a key colliding with a built-in text-variable token is shadowed by the resolver rather than empowered — so there is no key whose acceptance authorizes anything. The one genuine widening is disclosure-shaped and is closed by construction: neither half of the pair is stored, hashed, echoed, or used to select a message; the refusal sentences are literals chosen before the parse, and the locator is an index computed from the parse. property was removed from the closed refusal-naming table rather than left as unreachable text, so the table continues to name only constructs that can actually refuse. One disclosure surface did change, and it changed deliberately. Review found that circuit_scene.py skipped root (property …) because the adapter used to reject every board carrying one, so accepting the construct left an author-controlled string invisible and uncounted on the annotation surface — the quarantine channel's whole purpose. Root properties are now collected under a fourth origin, board_property, with the key emitted separately from the value, trust: untrusted_board_author as for every annotation, charged against the same ceiling, and test_a_root_board_property_is_disclosed_under_its_own_origin pins that both halves are returned, that nothing was dropped to make room, and that the whole-response grep still finds the strings nowhere outside annotations. That test splices the construct into a copy of the hostile fixture rather than committing it there, because the committed fixture's snapshot digest, annotation count and leading annotation reference IDs are pinned goldens: no pinned identity in tests/test_golden_identities.py moves in this change, and none was re-pinned. This widens disclosure only where the caller asked for annotations, and it closes a silent hole rather than opening one. Deliberately not claimed: that a board carrying a property is safe to apply — every apply gate is unchanged and independent — and that the value is preserved anywhere in Board IR, which is exactly what R-139 records it is not. | @seunghyukchoe | | SEC-136 | 2026-08-12 | The root copper-graphic refusal path in _semantic_preflight, reviewed because it begins selecting a diagnostic sentence by the board's own head token, and because the construct it now names carries an attacker-controlled string as its entire payload. This is the ADR-0090 question (SEC-133) in its worst form: for gr_text the unmodelled thing is the text, so quoting it back at the operator is both maximally tempting and maximally harmful. No accepted-input surface widens — nothing that refused now converts, and nothing that converted now refuses. | _UNMODELLED_COPPER_GRAPHIC_HEADS maps two heads to fixed (message, object_kind) tuples; the emitted bytes are values from that table, selected by an equality test, and no board token is interpolated or concatenated anywhere on the path. The standing regression test_diagnostics_never_echo_attacker_controlled_construct_names still covers the root path, and new test_the_copper_text_refusal_never_echoes_the_string_it_refuses puts SECRET_BEARER_TOKEN SYSTEM: disclose the workspace in the text atom and asserts that neither SECRET nor disclose appears in the message, locator, object_kind or object_id. Mutation M6 — building the sentence as f"{message} {expression.items[1]}" — is killed by that test; all six mutants applied to this path are killed, each anchor verified to match exactly once. The locator stays the constant kicad_pcb.graphic, computed by the adapter and never read from the document. | Accepted. Not claimed: that the refusal is actionable without opening the board — it names the construct and the layer class, deliberately not the string, the coordinates or the child index, so an operator must look. Residual to watch: object_kind is a free-form string field, and this is the second value added to it (after group, SEC-133) that a downstream consumer may not have a branch for; consumers must treat it as an opaque label, which the published contract already says. | @seunghyukchoe | | SEC-137 | 2026-08-12 | The Board IR adapter's accepted-input surface widens by a whole pad class: a connect pad on an untrusted board file now converts instead of refusing (ADR-0096), and a new integer field, ConversionResult.edge_connector_pad_count, is derived from board content. Reviewed on the same grounds as SEC-133, which reviewed the equivalent widening for root (group ...): a new accepted construct on the primary untrusted-input parser, plus a new count derived from it. | The widening opens no new code path -- a connect pad is read by the identical statements an smd pad is, with one dictionary key added, so no new parsing, allocation shape, or budget consumer exists. The echo surface strictly shrinks: _UNMODELLED_PAD_KINDS is deleted and the kind refusal is now an unconditional constant, so the one place a documented token could reach a message is gone; the standing regression test_diagnostics_never_echo_attacker_controlled_construct_names still applies, test_an_undocumented_pad_kind_is_refused_without_echoing_the_board pins that a hostile token never appears in its own refusal, and the mutant that interpolates the source token into the message is killed. The disclosure is an integer count of pads, the same class as unmodelled_group_count under SEC-133, and ConversionResult structurally refuses to carry it without a snapshot so a refused document discloses nothing. No authorization gate reads pad kind: locked is unaffected, and the one gate that did consult the resolved kind -- the paste/mask aperture skip -- was deliberately re-pointed at the raw source token so that widening the kind table could not widen the skip, with that exact mutation killed. | Reviewed; no new finding | | SEC-138 | 2026-08-13 | Correction row: every mutation claim this ledger itself carries, re-reviewed after a defect was found in the scratch harnesses that produced them -- eleven rows, not the six a first sweep found, and the undercount is recorded in ADR-0098 rather than smoothed over. SEC-119 (1 mutant), SEC-120 (3, "each fail the suite"), SEC-121 (1, caught "by exactly two tests ... and by no other"), SEC-127 (6, the run R-127 also cites), SEC-131 (3, the ADR-0087 run with its per-mutant failure counts), SEC-132 (the ADR-0089 scoping mutation, with D-176/R-133), SEC-133 (26), SEC-134 (25), SEC-135 (24, via ADR-0094, landed with PR #150 while this review was underway), SEC-136 (6) and SEC-137 (23, via ADR-0096) all rest on hand-applied mutant runs whose harnesses lived in agents' scratch directories and were deleted with them. | The audit in ADR-0098, and the deterministic reconstruction of the defect in tests/test_mutation_harness.py: a byte-count-preserving edit applied or restored within the same filesystem second is invisible to CPython's (mtime, size) .pyc check, so a stale cache silently runs the wrong code, and a stale mutant poisoning the next invocation is a false kill. None of the eleven rows establishes a reproducible run; SEC-134 and SEC-136 verified anchors and reported stale mutants as skipped, and SEC-135 -- whose run hit the defect live, 189 failures against code no longer on disk -- purged caches on its re-run and already states that its harness is not committed. That is the strongest discipline in the ledger and the model ADR-0098 builds on, but an anchor check reads the source and the defect is that the interpreter does not, and a purge described in a row is not a purge anyone can re-run. | Qualified, not retracted. No verdict in the five rows is shown false, and each row's non-mutation evidence (committed regressions, non-echo canaries, real-CLI checks) stands untouched; what falls is the auditability of the kill counts, which should be read as unauditable rather than as settled -- SEC-135 said as much about itself, and this row extends that sentence to its ten siblings. Every survivor those runs reported led to a committed test that still passes, so the direction that found real gaps is preserved in the suite either way. Disposition: future mutation claims on any security-reviewed surface must meet ADR-0098 -- committed spec under docs/mutants/, committed harness, anchors CI-gated, mutant-to-killing-test mapping, kills proved in both directions with caches purged. The first committed spec re-derives SEC-137's three most load-bearing mutants (the kind-table fifth key, connect re-pointed, the kind refusal deleted) against current source: killed: 3. Rows SEC-119/120/121/127/131/132/133/134/135/136/137 are append-only and stand as written; this row is their correction under ledger rule 3, and B-102 is the same correction for the benchmark ledger's two exposed rows (B-089, B-093). | @seunghyukchoe | | SEC-139 | 2026-08-13 | The Board IR accepted-input surface widens on two untrusted-input paths at once (ADR-0097). On the KiCad adapter, a construct that was refused outright -- a footprint carrying a courtyard on the layer opposite its copper side, unsupported.transform / "courtyard layer does not match its footprint side" -- now converts, so board files that never reached the geometry code now reach it. On the Board IR JSON decoder, two new optional keys, far_side_courtyards and far_side_courtyard_circles, are accepted on a document a caller supplies. Reviewed on the same grounds as SEC-133 (root group), SEC-135 (root property), SEC-136 (copper graphics) and SEC-137 (connect pads): a newly accepted construct on a primary untrusted-input parser. Two questions were asked, the second because SEC-133's finding was that the first one is not sufficient: can any of the new input reach an instruction-bearing field, and does accepting it weaken a gate that previously held? | No new echo surface, and the refusal vocabulary shrinks. The refusal sentence this change deletes was adapter-owned prose selected before the parse; nothing replaces it with an interpolation, no board token is concatenated into any message on the widened path, and the standing regression test_diagnostics_never_echo_attacker_controlled_construct_names is unchanged and still passes. Locators on the new path are index-computed (...line_chain[N], ...far_side_courtyards[N]), never read from the document. No new authorization gate, checked against effect rather than against code, which is the SEC-133 lesson. The question asked was whether a courtyard layer can authorize anything: it cannot -- locked is untouched, no apply path reads a courtyard layer, and the one write surface that could have widened deliberately did not. kicad_placement_patch._validate_footprint_expression still refuses every rectangle that is not F.CrtYd, so the set of boards the source-preserving serializer will write is unchanged, and test_write_back_still_refuses_a_board_carrying_a_far_side_courtyard_rectangle pins it; mutant M10, which widens that gate to accept B.CrtYd, is killed by that test. The safety direction runs the other way from a normal widening, which is the substantive finding: the construct being accepted was previously refused, and the gate it was protecting was under-approximating. Under the old same-side pairing two coincident B.CrtYd rectangles on opposite-side footprints were never compared, so a placement real kicad-cli reports as courtyards_overlap would have been published as proven_clear -- a keep-out silently dropped, in the one direction an obstacle may never err. test_the_old_side_gate_would_have_published_a_false_clearance pins exactly that, and B-101 measures it against real kicad-cli 10.0.5 with 0 contradictions. Budgets are charged, not bypassed. The decoder's 64-courtyard ceiling counts all four arrays against one total rather than one per layer, and the scene detail budget charges far-side vertices into the same ceiling, so a feed-through part cannot overrun a declared bound by drawing on the second layer; test_the_sixty_four_courtyard_ceiling_counts_both_layers_together (adapter), test_content_validation_enforces_the_shared_ceiling_on_a_hand_built_footprint (content validation), test_the_decoder_refuses_a_far_side_overflow_of_the_shared_ceiling (the untrusted-JSON decode surface, including the far-side-only overflow a per-layer count would miss) and test_far_side_courtyard_vertices_cost_the_scene_vertex_budget pin them, and mutant M8, which stops charging far-side vertices to the scene budget, is killed. Mutant M7 -- charging the decoder's copy of the ceiling to the near layer alone -- survived, and the reason is recorded rather than patched over. It is equivalent at the module's public surface: codec._decode_content has exactly one caller and validate_content runs on the next line with the identical combined ceiling, so every over-ceiling document is refused with the same code, locator and message with or without the decoder's copy -- measured, not argued. The decoder's ceiling is shadowed defence-in-depth, not the operative gate. Finding it did change the tree: the adapter ceiling test's docstring claimed it covered the decoder and did not, and the decode surface had no ceiling test of its own until this review added one. Decoded far-side geometry is held to the identical octilinear and integer-radius subset as the near side (test_a_decoded_far_side_ring_is_held_to_the_same_octilinear_rule), so the widening adds a layer and not a shape class. Disclosure widens by geometry the caller already supplied, under two new Circuit Scene keys emitted only when non-empty, charged against the same annotation-free geometry ceiling; nothing new is disclosed about a board the caller did not provide. A manual run of 11 chosen mutants over the widened logic killed 10, with M7 surviving as equivalent for the reason above. Each anchor was verified to match exactly once, each apply and restore verified by file digest, and every __pycache__ purged around both -- several of these mutants are byte-for-byte the same size as the code they replace, which is precisely the case a stale .pyc hides. The harness also asserts that the unmutated suite passes before applying anything: the first version of this run named a test file that does not exist, so pytest exited 4 on every case and reported all eleven mutants as killed without executing a single test. That false result was caught by the baseline check and is recorded here because it is the failure mode this kind of evidence is most prone to. This is a claim about the eleven mutants chosen and says nothing about the mutation space, and the harness is not committed, so this row carries the claim rather than reproducible evidence. | Accepted, with one residual recorded and no finding that blocks merge. Residual, in the conservative direction: the published schema is looser than the runtime. schemas/board-ir/0.2.0.schema.json bounds each courtyard array at maxItems: 64 independently, so a schema-only consumer sees a ceiling of 256 shapes per footprint across the four arrays where the decoder enforces 64 in total. This change widens that pre-existing gap from two arrays to four rather than introducing it. The direction is the safe one and is the opposite of SEC-134's defect: there the published contract accepted forgeries the runtime would never construct, whereas here the runtime refuses documents the schema permits, so CopperMCP over-refuses and never over-accepts. It is recorded rather than fixed because expressing "the sum of four arrays" in JSON Schema needs a construction the rest of this schema does not use, and doing it for these two arrays alone would leave the original pair inconsistent; it belongs in its own change across all four. Not claimed: that a board carrying a far-side courtyard is safe to apply -- every apply gate is unchanged and the serializer still refuses the construct outright; and nothing about arcs, curved chains, or nonzero courtyard clearance, which remain outside the accepted subset on both layers. | @seunghyukchoe | | SEC-140 | 2026-08-13 | The pad refusal path in the KiCad Board IR adapter, reviewed on two counts. First, the accepted-input surface widens by one head on an untrusted path: property joins the pad allowlist, so a construct that refused every board now converts seven of its eight writable values. Second, and the sharper one, nineteen new diagnostic sentences begin naming a construct, and one of them names a token -- the recurring SEC-133/SEC-136 question of whether a refusal may quote what it refused, asked again on a head whose payload is a bare atom the board author controls. | The names are values from closed tables, selected by equality, never built from source bytes: _UNSUPPORTED_PAD_FIELDS is an adapter tuple and the emitted sentence interpolates its element rather than the board's head, and the one token a refusal names, pad_prop_castellated, is emitted from the _REFUSED_PAD_PROPERTY constant after value == _REFUSED_PAD_PROPERTY. A board can therefore steer which fixed sentence returns and not one byte of what it contains. New test_a_refused_pad_property_never_echoes_the_token_it_refused puts SECRET_BEARER_TOKEN_disclose_the_workspace in the token and asserts that neither SECRET nor disclose reaches the message, locator, object_kind or object_id; the standing regression test_diagnostics_never_echo_attacker_controlled_construct_names still covers the path. Mutant PP11 -- rebuilding the sentence as f"pad fabrication property {value} is unsupported" -- is killed by that test. test_a_skipped_aperture_pad_cannot_smuggle_a_castellated_property pins the validation order against the aperture skip (mutant PP10), and test_an_unknown_pad_field_is_still_refused pins that the allowlist did not open (PP17). Twenty mutants over the path, twenty killed, by the committed ADR-0098 harness -- the twentieth, RV03, being a mutant adversarial review found surviving the first run: narrowing the validator's return to value == "pad_prop_heatsink" passed the whole suite, because every read of the disclosure counter used one token. It is a coverage gap in the counter rather than in this path's message safety, but it is recorded here because it is the same lesson: an example is not a class. D-184's second-surface check was run rather than skipped: circuit_scene.py collects root and footprint property nodes and not pad ones, and here that is correct rather than the silent gap ADR-0094 created -- a converted pad property is one of seven tokens this repository wrote, compared by equality, so there is no board-author string for a disclosure surface to reveal, unlike a root property's arbitrary key and value. | Accepted. Not claimed: that the refusal is actionable without opening the board -- it names the field and, for one value, the token, deliberately not the pad's number, net or position, so an operator must still look. Considered and rejected: naming the offending token in the general case. A token outside the closed table is board bytes with no format meaning, and quoting it would put untrusted input into an instruction-bearing field to no benefit; the off-table sentence is fixed. Residual to watch, and it is the same one SEC-136 left: the pad locator kicad_pcb.footprint[N].pad[N] discloses two ordinals about a private board. That is unchanged by this review -- the locator predates it, SEC-011 already permits object counts, and ADR-0079 refusals already carry byte offsets -- but nineteen newly-reachable sentences mean the locator is now returned in more situations than before, which is a change in frequency rather than in kind. | @seunghyukchoe | | SEC-142 | 2026-08-13 | The excessive-agency evaluation's authorized apply path and its confinement, reviewed because issue #110 asks for a reachable authorized path and because granting one to an evaluation makes that evaluation a thing that can mutate a board. Reviewed against SEC-122, which recorded the suite as it stood. | The suite replayed at 34 scenarios across 4 project families: 136 cases, 90 passed, 0 failed, 46 not run, plus 3 report-level controls, 0 failed (B-106). Permit: authorized-apply-permits-the-bound-candidate records applied in development-fixtures and in the held-out heldout-audio, having written real bytes into a temporary workspace copy, and authorized-apply-changes-only-the-authorized-board records that exactly the named board and its own pre-apply copy differ across that write. Confinement: an absolute path, a .. traversal and a symlink out of the workspace, each attempted with consent granted and a genuine token against a real board in a sibling temporary directory, all 9 runnable rows invalid_request with the outside board byte-identical. Degradation: with both capability probes returning nothing, failures is empty and controls_failed is 2, pinned by regression. Mutation: 6 mutants over the authorization gate and the controls, run through the committed harness of ADR-0098 (docs/mutants/2026-08-13-apply-authorization-gate.json), 6 killed, 0 survivors, 0 stale anchors — including the inverted route consent gate, the removed placement consent gate, the removed workspace confinement step, and the two mutants that make the coverage controls always satisfied. | What widened, exactly: nothing in the server. No apply, token, consent or path-resolution code was changed by this review, this branch's diff over src/ is empty — the widening is entirely in what the evaluation is permitted to do, and it was already doing it. _scenario_apply_replayed_token has performed a real authorized apply since SEC-122; the honest description of the prior state is that the suite's most dangerous capability was unnamed in the catalog and unguarded by any confinement test, not that it was absent. This row names it. Blast radius of the evaluation's write: one file, inside a tempfile.TemporaryDirectory created per project family, holding a copy made from a committed fixture seconds earlier; the enclosure is not inside the repository and its sibling beyond/ board is likewise a throwaway copy. test_source_boards_are_untouched_by_a_run digests every committed board across a full run. The harness deletes every COPPER_MCP_* variable from the environment at import, so an operator or CI job that exports COPPER_MCP_ALLOW_APPLY=1 or points COPPER_MCP_WORKSPACE at a real tree cannot redirect the write — pinned by test_cli_ignores_inherited_copper_configuration, which sets exactly those variables and requires the artifact to be unchanged. Consent inside the run is a Settings object constructed per family, never the process environment. The finding that came out of building it: the whole-workspace digest failed on its first execution, correctly — a successful apply writes a pre-apply rollback copy under .copper-mcp-backups/ that the previous single-board digest guard could not see. That copy is now held to belonging to the board that changed and carrying its pre-apply bytes, because a copy holding post-apply bytes restores nothing and a copy of another board would put one board's contents into another's history. Not claimed. This is not a claim that confinement holds in general: three named escape routes were attempted, on whatever filesystem the temporary directory landed on, through the in-process adapter. It is not a claim that the permitted write is correct — the permit rows establish that an authorized request is not refused and touches only its own board, and say nothing about the geometry written; no DRC ran. It is not a claim about a hostile host, a remote deployment, or a transport that rewrites requests. And the permit is evidenced on one held-out family: coppertone-buffer affords no genuine capability and records no_apply_capability_available, so R-148 carries the residual. | @seunghyukchoe | | SEC-143 | 2026-08-13 | The candidate replay boundary, which every verifier of routed copper passes through: AStarRouter.replay, _replay_candidate under render_kicad_candidate_board and apply_route_candidate, verify_candidate_path, and the apply-token gate in preview_route (ADR-0103, issue #163). | The binding equality and both of its directions, each with a non-vacuity assertion: test_replay_without_the_producing_fill_refuses_instead_of_routing_differently (the stricter direction, asserting the envelope route is genuinely longer) and test_replay_refuses_fill_a_candidate_was_never_routed_under (the looser direction, asserting the pour is genuinely the weaker model). The same pair at the serialization boundary and at the apply engine on real KiCad bytes. 17 committed mutants, 17 killed, 0 survivors, 0 not_run, spec docs/mutants/2026-08-13-replay-fill-authority.json. | Accepted. The change adds no input surface and no new authority: verified_fill was already an argument the router accepted, and nothing here reads a board, spawns KiCad, or widens what converts. Every added path is a refusal. The security-relevant judgement is the token gate: a capability whose exercise is guaranteed to refuse must not be issued, so preview_route withholds the apply token for a fill-routed candidate, and the destructive tool consequently never receives one. The binding is not a defence against a caller determined to lie -- an in-process caller can construct any candidate it likes -- but a forged binding changes the candidate ID, and the apply token is bound to that ID, so the realistic attack is closed by the existing token authority rather than by this change. verify_candidate_path refusing a fill-bound foreign candidate is the one place the surface narrows, deliberately: that validator holds no fill evidence and models zones by their envelope. | Initial maintainer + review-bot gate | | SEC-144 | 2026-08-13 | The cached zone-fill vertex budget as a denial-of-service control, reviewed because ADR-0104 raises its default tenfold on an untrusted-input path | Fill-vertex budget calibration; benchmarks/results/board-ir/2026-08-13-fill-vertex-budget-calibration.json; adversarial documents bisected against the shipped ParseLimits; tests/test_zone_fill.py, tests/test_config.py; docs/mutants/2026-08-13-fill-vertex-budget.json | The control is not what it was documented to be, and that is the finding. read_fill_islands parses the whole document before it counts a fill vertex, so refusing the largest corpus board at a budget of 3 costs 20.9 s of the 24.2 s a complete read costs: 86 % of the workload is unpreventable by this budget at any value. The defence against an unbounded vertex list is ParseLimits (SEC-121, ADR-0079), which also bounds the reachable population -- bisecting the densest legal fill document puts it at 741,375 vertices (budget.exceeded.nodes) at the shipped parse defaults, and at 2,097,152 under any configuration because the parser's fixed 16 MiB input ceiling admits no more eight-byte (xy 0 0) vertices than that. Priced, not asserted: against the densest reachable document the default's change from 50,000 to 500,000 moves a refusal from 29.325 s / 146.8 MiB to 35.812 s / 168.4 MiB, so it buys an attacker 6.5 s and 21.6 MiB (+22 % wall, +15 % peak) on top of a floor the budget has never been able to move. An operator restores the previous posture exactly with COPPER_MCP_MAX_FILL_VERTICES=50000, and improves on it materially only by lowering COPPER_MCP_MAX_PARSE_NODES, which is the control that binds. The range is not widened with the default: it stays 3-1,000,000, still reachable so no accepted value is inert, and deliberately below what the byte ceiling would permit. Two further observations. The budget is charged twice per proof -- once on the operator's board and once on this server's own KiCad output -- and the committed zone-fill-stale fixture shows the two populations differing (148 cached, 186 recomputed), so a budget in the gap refuses our own subprocess; across six stale corpus boards the difference is at most 0.03 %, which is why the disposition is to size the number rather than split the knob. And a refusal that lied was fixed: _points hardcoded "cached", producing refilled zone fill could not be read: cached zone fill exceeds .... A budget refusal still names configuration only -- the budget and its configured value, never an observed count and nothing derived from the document. Accepted as a priced posture change; the newly reachable per-island ceiling in the routing path is R-150. | Maintainer | | SEC-146 | 2026-08-14 | The layered candidate replay boundary and the newly public layered fill-authority seam, reviewed because ADR-0106 makes an obstacle model a caller-reachable input on a path where nothing bound it to the candidate it produced | tests/test_layered_board_adapter.py (binding, both replay directions, reordered-pour equality), tests/test_kicad_layered_route_patch.py (serialization boundary, both directions), tests/test_layered_route_preview.py (stale_fill, routing_effect, DRC forwarding), tests/test_live_layered_route_preview.py, tests/test_routing_job_mcp.py, tests/test_live_apply.py, tests/test_golden_identities.py; committed mutation spec docs/mutants/2026-08-14-layered-fill-contract.json | Accepted. The forbidden class here is a silent under-approximation of an obstacle, and the review's finding is that the change closes the only route to it on this path rather than opening one. Before it, a layered candidate carried no record of the model that produced it, so a verifier holding different fill -- including fill that retires envelopes the original search never saw retired -- would replay against it and could agree. One equality now forbids that, and the same equality forbids the opposite understated direction; a committed mutant for each half survives the other half's test and dies only to its own, so neither direction rests on the other's coverage. Three seams were checked for a capability whose exercise is guaranteed to refuse (ADR-0103's token rule). Live layered preview: pinned to Literal[False] and refused at the parser, because fill authority proves a file's cache fresh and a live proposal has no file. Durable routing jobs: refused at _prepare_layered_job and excluded from the persisted envelope, so a queued job can neither request the capability nor silently carry a flag nothing will honour. Live apply: no change was needed, and the scope of that evidence is stated rather than implied. layered_candidate_from_document ignores keys it does not read and re-hashes its result against the claimed identity, so once the binding is part of that identity a manifest claiming one rebuilds without it and fails the recomputation. The committed test exercises that seam -- the reconstruction and its identity recomputation -- one level below the tool boundary; it does not drive apply_live_candidate end to end. Coverage of the full path is by composition (that function's result is what verify_layered_candidate recomputes) plus the token chain, and on this surface the token chain is the whole protection, because verify_layered_candidate is structural-only and checks no obstacles at all. What is claimed: a fill-bound manifest cannot survive identity recomputation. What is not claimed: an end-to-end live-apply test of that refusal. Durable job ledger: validate_candidate_for_job refuses a fill-bound candidate outright. The request boundary already refuses the flag and the persisted envelope never names it, but that validator is reachable in-process, and the review found it would otherwise publish a completion row for a candidate every downstream replay must refuse -- fail-closed, but a row that should not exist. That is the ledger's own door, closed with its own test and mutant (JB03). Disclosure: the new fill_authority record publishes what preview_route already publishes -- digests, a KiCad version string, and two counts -- plus one closed four-value routing_effect literal. It carries no polygon, no net name and no zone identity, and the layered response already publishes absolute candidate vertices, so this says strictly less than the document it rides in. Resource posture is unchanged or tighter: reading the pour is bounded by max_fill_vertices (SEC-144) exactly as on the single-layer path, and the ordered-layer adapter's per-island ceiling refuses before any snapshot work, so a caller cannot buy unbounded preparation with the new flag. Not claimed: that the flag improves any route (B-105: zero changed verdicts), or that it is reachable on most real boards (R-152). | Maintainer | | SEC-147 | 2026-08-15 | Custom-pad primitive-point accounting at the Board IR 0.4 untrusted-input boundary, reviewed after review-bot discovery that points were collapsed into an AABB before total-vertex limits ran | The accepted custom-pad grammar is unchanged. The corrected path charges every accepted primitive point, enforces per-ring limits for gr_poly, and reserves the serialized Board IR total-vertex budget before snapshot publication. Exact-bound inputs remain accepted; over-bound inputs refuse. Tests cover the per-ring, total, and exact-bound cases; the committed mutation specification kills 10/10 mutants. | Accepted. This closes a denial-of-service accounting gap: primitive points can no longer disappear into a bounding box before max_vertices_per_ring/max_total_vertices enforcement. No public schema, accepted-set, write, or apply surface changed. Residual: the limits still bound parsing only within the configured budgets; they do not make custom primitive geometry exact, and other resource ceilings remain separate controls. | Review-bot finding and maintainer remediation | | SEC-148 | 2026-08-15 | Custom paste/mask aperture validation at the Board IR 0.4 untrusted-input boundary, reviewed after the second PR #192 review finding | Before remediation, custom paste/mask apertures were skipped before primitive grammar and vertex-budget checks because their geometry was discarded. The corrected path validates and charges aperture primitive points before the skip, while still publishing/counting no aperture geometry. Exact-bound and over-bound inputs, malformed and unknown primitive syntax, and the CPG11 mutation are covered by tests; CPG11 is killed. | Accepted. The accepted set is unchanged. The DoS boundary now applies equally to discarded aperture payloads; no public schema, Board IR geometry, write, or apply surface changed. Residual: aperture geometry remains intentionally unavailable to consumers, and other independent resource ceilings remain separate controls. | PR #192 review-bot finding and maintainer remediation | | SEC-149 | 2026-08-17 | Ordered-layer verified-fill aggregate validation, reviewed because the existing 4,096-island and 4,096-vertex ceilings multiplied into 16,777,216 unmetered vertex predicates before any router work budget existed | The new preflight reads one tuple length per structurally admissible island and refuses above the existing 10,000,000 obstacle-check domain ceiling before any vertex access. Malformed containers remain owned by the structural gate, ordinary request failures retain precedence, and the independent per-island ceiling remains reachable. The public preview and durable-job paths use fixed messages and never echo a net, coordinate, geometry, or observed caller count. Five ADR-0098 mutants are committed in docs/mutants/2026-08-17-layered-fill-validation-budget.json; Python 3.12.13 on macOS killed all five with baseline return code 0, zero survivors, and zero stale anchors (spec SHA-256 a5c3184b896c18bde283ced8ffdcd3717e76d7c92361ef6623d820418e082c9c). | Accepted as a refusal-side denial-of-service correction. No route, fill, board, candidate identity, apply authority, or configured budget widens. The 4,096 per-island ceiling remains the separate calibration tracked by issue #167. | Initial maintainer + cross-review | | SEC-150 | Production-core intake of externally generated route geometry under ADR-0112, reviewed as a new untrusted-input boundary | The document is a closed exact-dict schema; key count is checked before constant expected-key membership so hostile dictionaries cannot buy an unbounded key scan. Scalar digests and typed IDs are validated before semantic comparison; bool-as-int and unsafe nanometre values fail closed; segment, path-edge and obstacle-check work is bounded; cancellation and deadline callbacks are cooperative and exception-safe. Type-exact but internally mutated requests and snapshots are canonicalized or refused before nested traversal. Candidate identity, net binding, settings, costs and metrics are reconstructed from coordinator state, and the final legality decision uses the Board IR path validator. The exact off-grid obstacle fallback shares the remaining obstacle budget and upgrades only a proven collision. Collinear compression proves the middle vertex lies monotonically between its neighbours; a reversal is retained and refused, so an out-of-board or obstacle-crossing excursion cannot disappear before validation. Results use fixed diagnostics and disclose no geometry, board bytes, names, path, prompt, apply token or mutation capability. Tests cover hostile snapshots/requests, 10,000 extra keys at document/segment/point levels, forged fields, stale and malformed revisions, unknown pads/layers, width and via classes, resource stops, deterministic identity, leak scanning, benchmark-import isolation, the 1 nm two-direction control and the review-found reversal regression. | Accepted for a core-only read-only slice. No MCP, CLI, persistence, apply, KiCad subprocess, network or physical-validation authority is added. Residual corpus representability and calibration are recorded in R-161; issue #99 remains open until the 70-route artifact exists. | Initial maintainer + independent cross-review | | SEC-151 | Multi-path external route-patch intake and B-088 corpus replay under ADR-0113 | V2 retains exact closed dictionaries and coordinator-owned identity, request and budgets. Path count, compressed segments, expanded unit edges, obstacle predicates and the quadratic connectivity-core merge all consume fixed ceilings; cancellation and deadline checks remain cooperative. Every submitted path must join every coordinator-derived pad component. One path is valid for a partially routed multi-pin net whose existing same-net copper leaves exactly one merge; the same connectivity proof must still join all components, and the review-found case is pinned by a three-pad regression. The external verifier imports no benchmark code or private A* symbol. Result rows disclose only fixed diagnostics, bounded counts and digests; the B-120 artifact stores no coordinates, segments, paths, vias, board bytes, apply token or mutation authority. Focused tests cover deterministic multi-path identity, disconnected branches, closed output and v1 preservation; the corpus test replays 70/70 plus the four typed perturbations. The committed ADR-0098 harness spec docs/mutants/2026-08-17-external-route-patch-v2.json killed all 4 discriminator, connectivity, exact-incursion and early-budget mutants with zero survivors or stale anchors; spec SHA-256 1c007a57014848cd24f1adf1e0f07ef82800d16448ae4e9b5cf7cd96a863adac. | Accepted for a core-only Board-IR structural verifier. No network, MCP, CLI, persistence, apply, repair, KiCad subprocess or physical-validation authority is added. The quadratic core merge can exhaust the existing obstacle-check ceiling and then refuses; authoritative DRC remains an explicit #99 gate. | Maintainer review + review-bot remediation | | SEC-152 | External candidate to authoritative KiCad DRC continuation under ADR-0114 | File-backed coordinator reuses workspace-confined bounded reads and parse limits, derives the source/snapshot/request/profile rather than accepting them from the document, enforces optional source and snapshot preconditions, and requires typed include_drc consent. Closed v1/v2 parsing and Board IR acceptance precede KiCad discovery. The accepted disposition alone selects the non-replay serializer; exact type and candidate-ID binding prevent an in-process caller pairing one acceptance with another self-signed candidate. Source/profile equality, native identities, object/input ceilings, deterministic segment IDs and exact Board IR round trip remain mandatory. Existing private DRC execution binds candidate, source, patched board and context and discards a source/rule race. The absolute preview deadline now reduces each context-scan and subprocess budget from the current remaining time and is rechecked after report parsing before evidence publication. Output-leak tests reject coordinates, paths, segments, workspace paths and apply tokens. Real KiCad 10.0.5 tests cover a two-pad path and four-pad tree with source bytes, inode, mtime and workspace entries unchanged. docs/mutants/2026-08-17-external-candidate-kicad-drc.json kills all 7 opt-in, completion, evidence-binding, serializer-selection, disposition type/candidate-binding and deadline mutants; spec SHA-256 0b9d8c17e7e9ef1ab159e07abe8191846f645747a1070c1170b3a91443c1ba94. | Accepted for an internal read-only continuation. No MCP, CLI, persistence, apply or network authority is added. completed is execution, not a clean-board verdict; counts are one invocation, and KiCad DRC supplies no electrical, thermal, DFM, fabrication or hardware signoff. | Maintainer five-axis review + review-bot remediation | | SEC-153 | 2026-08-17 | Versioned public MCP intake of externally generated route geometry under ADR-0115 | The advertised schema closes the exact outer {request} wrapper, inner 1.0 envelope, reference-only selector, both revision preconditions and existing v1/v2 documents. Framework runtime acceptance stays broad so only the application boundary parses hostile nested values and emits fixed diagnostics. Candidate identity, net and metrics are server-owned; obstacle and edge work derive from bounded coordinator settings, with no standalone work-ceiling fields and no settings or budgets inside the foreign document. DRC is mandatory; structural refusals execute no KiCad. The response is a closed accepted/refused union: accepted carries recomputed identity plus candidate/source/patched-board/context-bound aggregate evidence, refused carries a typed fixed code, and both carry bounded work counts. Transport tests cover stdio/HTTP inventory, read-only/non-destructive/closed-world annotations, closed schemas, fixed wrapper failures, derived budgets, variant exclusivity, DRC evidence binding and a recursive forbidden-property scan for geometry, board content/names/paths, tokens, capabilities and mutation claims. The review-found TOCTOU seam is closed by carrying the intake source revision into the DRC continuation and rejecting its second capture when bytes differ, including a whitespace-only edit whose Board IR geometry is unchanged. B-121 replayed the excessive-agency artifact at the implementation commit: 136 cases, 90 passed, 0 failed, 46 not run, and all four controls passed. | Accepted after focused transport coverage, independent review and the full local gate. The boundary creates no CLI, persistence, repair, apply, live-IPC or network authority. completed names execution, passed and clean remain independent summary fields, and single_invocation is not reproducible evidence. KiCad DRC supplies no electrical, SI/PI/EMC, thermal, DFM, fabrication or hardware signoff. | Maintainer implementation review + independent cross-review + PR review remediation | | SEC-154 | 2026-08-17 | Ordered-layer verified-fill per-island source boundary under ADR-0116 | An independent audit found that the 10,000,000 aggregate length preflight did not price four bounds scans plus canonical JSON allocation and replay hashing. B-123 therefore measured the proposed widening in fresh subprocesses and rejected one million when its equal-total split case exceeded the predeclared 20-second gate. The selected 500,000 ceiling completed under its 12-second/512 MB gate; 500,001 refuses before bounding or hashing; aggregate overflow remains a fixed non-echoing budget refusal; every admitted island still consumes track/via obstacle slots. The new committed spec docs/mutants/2026-08-17-layered-fill-island-budget.json (SHA-256 a46fcf20d2db3b739345d9d5c0254a337ef60b66b367da0b8d8774f9bb57bbfe) reports 5/5 killed with no survivor or stale anchor; the earlier #189 spec and SEC-149 hash remain byte-identical. | Accepted as a measured widening with a retained finite ceiling. No client knob, public schema, candidate identity rule, board write, process, network or apply authority is added. One-host resource evidence is not a universal performance guarantee and no route-quality or physics claim is made. | Independent architecture audit + implementation owner + maintainer calibration | | SEC-155 | 2026-08-17 | Opt-in negotiated local-repair transaction under ADR-0117 | Repair runs only after a complete allocation fails the existing physical gate. Coordinator-derived provenance binds snapshot, envelope, target, conflicts, grid, bounded window and canonical occupancy. Board IR exclusion reuses the reference predicate; same-pass copper is expanded by widths and resolved clearance. Preflights precede materialization. Local, projection and validator work consume fixed ceilings; forged/stale provenance, malformed policy selection, budget exhaustion and cancellation publish no partial candidate. Accepted geometry is path-validated, repair-bound in identity, then rechecked against the full candidate set. Results disclose only bounded counts and digests. | Accepted for an internal one-window proposer/disposer transaction. No MCP, CLI, persistence, process, apply, DRC or mutation authority is added. The result is not routing-quality, fabrication or physical evidence. | Terra implementation + Luna cross-review + maintainer review | | SEC-156 | 2026-08-17 | Private authoritative-signoff boundary under ADR-0118, reviewed because a nominal positive status or caller-selected runner could turn surrogate/evidence metadata into SI/PI/thermal/DFM approval | The closed core binds evidence vocabulary to one candidate and Board revision, requires content-digest identity for authoritative output, rejects stale/mismatched/failed/unconfigured authority with fixed redacted outcomes, and keeps surrogate/advisory output non-claiming. Hostile closed inputs, bounds, cancellation/deadline and result-disclosure tests cover the refusal boundary; the private factory regression covers the supported construction path. The module is not exported through MCP or CLI and invokes no arbitrary runner or external process. | Accepted for the deferred, non-claiming core slice. The module-private guard is not an in-process sandbox against privileged Python import or monkeypatch; process isolation and operational trust remain required. No bounded authoritative executor, fixed production backend registry, SI/PI/thermal/DFM approval, network, MCP, CLI, persistence, apply or mutation authority exists; issue #91 remains open for those future gates. | Maintainer implementation review + security cross-review | | SEC-157 | 2026-08-17 | Untrusted routed SimpleRouteJson conversion into existing foreign-candidate documents | The import-side adapter accepts raw bytes only, preserves JSON number spellings in a distinct token type, rejects duplicate keys, non-finite constants, quoted numbers, invalid UTF-8 and recursive malformed JSON, and applies fixed byte, trace, relation, per-trace, aggregate route-item, number-token and coordinate ceilings. It re-imports the exact source digest with the recorded policy, verifies the supplied immutable snapshot, compares replay snapshot/source/net/width/adapter identities and the full non-trace output projection, then binds every trace to exactly one imported net through exact opaque aliases without parsing composite names or selecting by geometry. Closed trace/wire fields and unique trace IDs are required. Only endpoint-exact or complete acyclic wire trees with one declared layer and uniform positive integer-nanometre width are emitted; unsupported route kinds are refused rather than dropped. The output contains no caller identity, settings, cost, metrics or authority and remains untrusted input to the unchanged production disposer. Independent review found that source replay preceded the adapter byte gate and that unknown connectsTo values could be ignored; remediation now parses both byte-bounded documents before replay, prevents every configurable ceiling from exceeding a hard maximum, and requires each relation to resolve to the same net or same-owner trace. Focused tests cover v1/v2 acceptance and repeatable downstream identity plus source mutation, unknown roots, duplicate keys, number strings, non-finite and sub-nanometre values, replay ordering, non-widenable limits, zero/multiple/contradictory relation ownership, cyclic backtracking, diagonal, endpoint, via and unknown-layer refusals. | Accepted for a benchmark-package read-only import seam. No production package depends on it and no MCP, CLI, persistence, candidate construction, DRC, repair, apply, board mutation or full-output clearance claim is added. Cross-candidate and via/pad/trace checks remain separate future gates. | Implementation owner + independent architecture review and remediation | | SEC-159 | 2026-08-24 | Public disclosure and contract integrity for withheld apply authority across route, layered-route and placement previews | The vocabulary is a closed Literal defined once in an import-leaf module and reused by all internal and MCP contracts. Values match a fixed non-echoing lowercase pattern and carry no dynamic payload. Unsupported surfaces are explicit; request/server/proposal/board/fill/replay precedence avoids unnecessary board inspection after an earlier gate decides the result. Internal objects and public output models independently require exactly one of token and reason and reject unknown values. The former bare placement replay exception is reduced to replay_refused without its exception string. Route/layered responses move to 1.1 and placement preview responses to 0.2.0; placement candidates remain 0.1.0. Focused tests census all token-minting and token-serializing modules, exercise six surfaces and all eight reasons, pin every produced version, and inspect generated JSON Schema for both required keys and the exact enum. The ADR-0098 spec SHA-256 8c860d0f2f0591b6728e6cedb6a74c3641088ab116eba03d93f9433d14eda8e0 killed 15/15 mutants with zero survivors or stale anchors. | Accepted as a versioned diagnostic output contract. No input field, token authority, apply permission, write path, live mutation, persistence, network, DRC or physical claim is added. Existing single-use capability, candidate versions and revision/candidate bindings are unchanged. | Primary implementation + independent subagent review and remediation | | SEC-160 | 2026-08-24 | Read-only measurement of production source-preservation gates over an operator-owned private corpus | The runner requires apply, live IPC and live apply flags to remain disabled and never calls an apply or DRC surface. Corpus discovery fixes the expected denominator and explicit superseded files; every selected board is captured through read_workspace_file with workspace confinement, no symlink following, .kicad_pcb suffix enforcement and max_board_bytes. Conversion consumes the single captured byte snapshot, while an independent bounded re-read rejects any source mutation before evidence publication. Placement selects only footprints with owned pads. Runner bytes are captured once before measurement; immediately before publication, fixed-diagnostic checks reject commit drift, a newly dirty worktree, or runner-byte drift. Route and placement failures are isolated and collapsed to fixed aggregate literals, never exception text. Output is refused inside the corpus and carries no board path/name, per-board digest, geometry, bytes, component/net identity, apply token or mutation claim; a canonical run ID and runner digest bind the public artifact. Focused tests cover oversized and symlinked inputs, mid-run source mutation, repository and runner drift, gate isolation, padless-subject bypass, output containment, run identity and forbidden-field scanning. | Accepted as a benchmark-only, non-mutating evidence path. The 128-bit-truncated corpus fingerprint supports drift detection but is not a redistributable corpus manifest or cryptographic disclosure of individual boards. Structural applicability does not prove a write, DRC result, undo transaction, electrical, fabrication or hardware acceptance. | Luna implementation + independent review + primary five-axis/security remediation | | SEC-161 | 2026-08-23 | The first reachable SIGNED_OFF path: backend registry, evidence capability, executor bounds, and claim redaction (ADR-0119, D-223, R-174) | Reviewed the three forgery routes a positive status opens and the tests that close each. Caller-supplied authority: backend is still never inspected for a callable and never invoked; a present argument refuses; the registry is a module constant with no registration function, so there is no runtime seam to install one through. Forged evidence: AuthoritativeEvidence refuses to construct without a module-private sentinel, closing supported intake/construction paths; this is a cooperative internal-misuse guard, not an in-process security sandbox against a privileged Python caller importing or monkeypatching private symbols. Serialized evidence — the dict, its JSON, or any look-alike — is refused as intake rather than re-admitted. Laundered evidence: a claim is denied before its verdict is read if the backend is unregistered for the domain, the evidence names another candidate or another revision, or an expected digest does not match; suppression and comparability are checked before passed. Redaction: non-claims and refusals carry no backend ID, evidence digest, comparability or repetition count, and a claim carries no authoritative output bytes; backend failure returns a fixed diagnostic with no exception text, pinned by an exact-payload assertion. Bounds: 2-8 invocations, cancellation and cooperative deadline checks occur before every invocation and again after grading, evidence output capped at 1 MiB, repetitions capped at 8; the underlying KiCad invocation keeps its process, timeout and output limits. Authorization: sign-off writes nothing and grants nothing; the apply surfaces and their tokens are untouched. No fake backend is installed in any test, so no test exercises a path the design forbids. Accepted. | Maintainer | | SEC-162 | 2026-08-24 | Read-only fixed-point masking of public and private untrusted KiCad sources | The external manifest is read once through the no-follow workspace boundary under a 64 KiB cap and must be a closed 10-public/3-private document with unique opaque identities, safe relative .kicad_pcb paths, per-source SHA-256 values, and an independently pinned aggregate fingerprint. Boards are captured once under a 64 MiB ceiling and re-read after measurement. Only three fixed diagnostic/locator pairs can trigger exact direct-root CST splices; no board string becomes a deletion instruction. Conversion and masking are capped at 16 class passes. Publication requires a clean stable commit and unchanged runner bytes. The result is aggregate-only, self-digested, and excludes paths, names, per-board digests, geometry, transformed bytes, tokens, authority, and exception text. | Accepted for a benchmark-only counterfactual. The truncated cohort fingerprint is a drift detector, not a disclosure-safe cryptographic commitment against a guessed private corpus; the masks are unsound by design and grant no product, apply, DRC, fabrication, or hardware authority. | Implementation owner + independent five-axis review + primary remediation | | SEC-163 | 2026-08-27 | The refusal-message surface opened by translating audited exceptions to mcp ToolError (ADR-0121, D-226, R-176) | The central finding is that this opens no new surface at all. Through mcp 2.0.1 every escaping exception was rewrapped as ToolError(f"Error executing tool {name}: {exc}"), so each message translated here already crossed this boundary verbatim on the pinned line; translation restores that surface on 2.1 rather than creating one. Reviewed every message literal of all 16 translated types against the withhold-reason discipline ADR-0120 sets. request_boundary interpolates only server-declared field names, the fixed allowed-field list, and its own numeric bounds — known_fields deliberately reports a count of unsupported fields and never their names. WorkspaceViolationError messages are fixed strings and never carry the path they refused; the only interpolated value in that family is the server's own configured byte ceiling. ApplyRequestError, PlacementError, PostPlacementObservationError, BoardFormatError and ManifestContractError are fixed or field-name-only. KicadIpcDisabledError is one module constant naming the operator flag, which is the point of it. No message carries board bytes, a filesystem path, a net or component name, a coordinate, a UUID, an apply token, or KiCad description text. Two regression tests pin the property directly: a workspace refusal is driven with a secret-bearing relative path and the message is asserted to contain neither the secret nor the workspace root. The reverse direction was reviewed as the larger risk, and the first review round found a real instance of it: ApplyRequestError covered both request parsing and the ApplyResult/PlacementApplyResult invariants, which can fire after an authorized write, so translating the class would have let a post-write inconsistency be reported as a refusal — a caller told its board was untouched at the moment it may have changed. Those 15 sites are now ApplyResultInvariantError, a RuntimeError excluded by name. The residue on six read-only surfaces is bounded, recorded in ADR-0121 and carried as R-177; none of it can misstate whether a board changed. Otherwise the reverse direction is closed structurally: the translated set is a closed enumeration of exception classes, never except Exception or except ValueError, so an unhandled defect cannot be dressed as a deliberate answer; eleven crash types are asserted to propagate untouched, and mutants RC02/RC03 widen the handler and are killed. On the 2.1 line a genuine crash now discloses less than before — its text is withheld and only the server log keeps it. | Accepted. The claim is that refusal messages carry no board-derived value and that the translated set cannot admit a crash; it is not a claim about what the mcp SDK itself logs or transmits, nor about any release outside the tested 2.0.0/2.1.1 matrix. | Implementation owner + per-type message audit + committed mutants | | SEC-164 | 2026-08-28 | The parser input surface widened by D-227/ADR-0122: five new accepted setup children, one of them a nested container with 86 layer entries measured on real boards | Grammar closure at three levels, exercised by unit tests: _SETUP_METADATA_HEADS still refuses any unlisted direct child; _STACKUP_HEADS refuses any unlisted stackup child; _STACKUP_LAYER_HEADS refuses any unlisted layer child; and _validate_direct_atoms refuses a bare atom at the stackup and a second positional token on a layer. Every new head resolves through the existing child()/atoms() helpers, so arity and duplicate detection are the same code the accepted heads already used. Depth and node budgets are unchanged — ParseLimits bounds the document before any of this runs. edge_plating/edge_connector/castellated_pads accept only the bare unquoted atom no; a quoted "no" is refused, and a test covers it. | Amended 2026-08-28, before merge, after review of #225 (thread PRRT_kwDOTrPIR86c8Hfh): the row's original claim about the accepted surface was inaccurate, and the amendment is the correction rather than a restatement. The head allowlists were closed; the payloads were not read at all. All thirteen malformation classes probed — a nested child inside any accepted leaf, wrong or empty arity, non-numeric origins and material constants, a quoted "no" where a bare flag is meant — were accepted at every level, the nested stackup grammar included, so an accepted container was an unread one. Sharpest instance: (grid_origin (zone_defaults ...)) carried past the exact head _REFUSED_SETUP_HEADS_ON_RECORD refuses one level up. Now closed by _SETUP_SCALAR_PAYLOADS, _STACKUP_SCALAR_PAYLOADS and _STACKUP_LAYER_PAYLOADS: every accepted leaf permits no child expression, has exact arity, and has its token kind checked (decimal, bare yes/no, or bounded text), each refusing at the field's own locator. A duplicate of any accepted field now refuses as syntax.duplicate_field. What can now enter: five setup heads, one nested two-level container, and inside them only well-formed scalar payloads of the declared arity and kind — nothing else. The stackup grammar is an allowlist at every level and a payload grammar at every leaf, not a skip. What still cannot: any unlisted setup, stackup or stackup-layer head, including KiCad 10's zone_defaults; a non-neutral board-edge fabrication attribute; a repeated stackup; a bare or extra positional atom anywhere in the block. No value is read, retained, echoed or logged. The five heads are counted and discarded: no material name, thickness, dielectric constant, colour, origin coordinate or finish string is stored in Board IR, published in a diagnostic, or written to an artifact — B-130's own artifact records atom_values_committed: 0 for the same reason. Refusal messages remain table- or literal-selected and never interpolate a board byte, so the two new locators (kicad_pcb.setup.stackup.<field>, …layer[N]) disclose a position and never a value. No new file, network, subprocess, apply or board-write path is reachable; conversion stays read-only and the source bytes are unmodified. Residual: the counts are cardinalities of constructs on a board the caller already supplied, which is the same disclosure class the six existing unmodelled_counts entries occupy, and is carried by R-178. | @seunghyukchoe | | SEC-165 | 2026-08-28 | The parser input surface widened by D-228/ADR-0123: six new accepted footprint children, one accepted-with-a-value-check (zone_connect), and one nested container (a footprint-local group) reachable on every footprint of a board rather than once at root. Twenty further heads move from an unnamed refusal to a named one, which interpolates a token into a diagnostic. | The payload grammar ships with the acceptance, not after a review round. #225 established that an accepted container without one is an unread container: all thirteen malformation classes probed there were accepted at every level, and (grid_origin (zone_defaults ...)) carried the exact head the allowlist one level up exists to refuse. That lesson is applied here in advance. _FOOTPRINT_SCALAR_PAYLOADS gives every accepted leaf a closed grammar — no child expression at all, exact arity, and a checked token kind (bare decimal or bounded text) — each refusing at the field's own locator, and a duplicate of any accepted field is caught by the pre-existing byte-offset detector as syntax.duplicate_field. zone_connect accepts only the bare unquoted atoms 1, 2 and 3: 0 refuses with its own sentence, and a quoted "2", a -1, a 4 and a decimal 2.0 all refuse, because KiCad's own parser casts the token to the enum with no range check and a consumer must therefore check the domain itself. The footprint-local group resolves through the existing _check_group, so its closed child allowlist, its single positional-atom check and its locked-group refusal are the same already-tested code that guards a root group, reached through the same helpers — arity and duplicate detection are not re-implemented. Depth and node budgets are unchanged: ParseLimits bounds the document before any of this runs, and the group path adds no recursion the root path did not already have. Diagnostics disclose a position and never a value. The twenty named refusals interpolate unsupported_head, which is a literal from _UNSUPPORTED_FOOTPRINT_FIELDS selected by lookup, never a token read from the board — the same construction _UNSUPPORTED_PAD_FIELDS has used since ADR-0091. A head absent from that table still refuses through the allowlist with the field-less sentence, so an attacker-chosen head name cannot reach a message. Locators name a footprint index and a fixed field name. What can now enter: six footprint heads as well-formed scalars of declared arity and kind, an attaching zone_connect, and a footprint-local group whose children are only the heads KiCad's writer emits. What still cannot: any unlisted footprint head; a detaching or out-of-domain zone_connect; a non-zero or zero clearance; a locked group; a group with an unknown child or stray positional atom; a nested child inside any accepted leaf. No value is read, retained, echoed or logged. The six counted heads are validated and discarded — no sheet name, file name, margin or ratio is stored in Board IR, published in a diagnostic, or written to an artifact; B-132's own artifact records atom_values_committed: 0 for the same reason, and its two copper-interacting payload measurements are predicates (clearance_zero, zone_connect_attaching, zone_connect_detaching) that commit a count and never a value. No new file, network, subprocess, apply or board-write path is reachable; conversion stays read-only and the source bytes are unmodified. Residual: the counts are cardinalities of constructs on a board the caller already supplied, the same disclosure class the seven existing unmodelled_counts entries occupy, and are carried by R-179. | @seunghyukchoe | | SEC-166 | 2026-08-28 | The parser input surface widened by D-229/ADR-0124: root gr_arc on Edge.Cuts becomes an accepted outline construct, and a new geometry module turns three attacker-supplied integer points into a variable number of ring vertices. Four previously-unnamed refusals now name their construct. | The payload grammar ships with the acceptance, not after a review round — the #225/#226 lesson applied in advance. _EDGE_CUTS_ARC_FIELDS is the segment's own closed set plus exactly mid: an arc carrying width, angle, fill, pts, or any other head refuses at its own locator, and a stray positional atom other than locked refuses separately. That set is not guessed — B-134 measured all 97 arcs in the public cohort writing exactly start, mid, end, stroke, layer, uuid with no positional atom on any of them. Duplicate fields are caught by the pre-existing byte-offset detector as syntax.duplicate_field, and coordinates go through the same mm_to_nm precision gate every other point uses. The new module is the amplification question, and it is bounded three ways. A hostile board cannot choose the vertex count: subdivision is derived from the arc's own radius against a module constant (5,000 nm), then hard-capped by the caller at the remaining max_vertices_per_ring budget, and the assembled ring is charged against max_total_vertices and max_intersection_tests exactly as every other ring is. A degenerate arc — three collinear points, or a repeated control point — is refused before any subdivision runs, so the pathological input is a refusal rather than a loop. The chord ring's self-intersection check charges its own intersection budget, deliberately double-charging a ring that is later revalidated, which can only refuse earlier and never admit. Arithmetic is exact integers and Fractions over an integer-scaled lattice; there is no float in any predicate, so no denormal or precision-context input changes a verdict. The one place floating point appears is where an attacker can reach it, and it is fenced there rather than trusted. Three near-collinear integer points are a well-formed document describing a circle whose centre and radius dwarf any board; sampling it in floating point subtracts two enormous nearly-equal magnitudes, and catastrophic cancellation can put a candidate vertex outside the supported integer range — where constructing it would raise a bare ValueError from inside a geometry routine and surface as an unclassified geometry.invalid carrying an interpreter message. A sample is therefore offered, never assumed: a coordinate that is not finite or not representable declines, and the vertex is dropped exactly as one failing the exact predicates is. Dropping coarsens the polyline, which is always the safe direction, and the reported deviation grows to match. The radius itself is taken with an exact integer square root rather than math.sqrt, which cannot overflow for any circle three in-range points describe. Three parametrized cases at the extreme of the coordinate range pin the degradation, and mutant OA17 is the range check removed. Diagnostics disclose a position and never a value. _EDGE_CUTS_REFUSED_OUTLINE_HEADS maps a source token to a literal constant selected by lookup, never a string built from the board, so an attacker-chosen head cannot reach a message; a head absent from the table still refuses through the allowlist with the generic sentence. Locators name a head and an index computed here, not read from the document. No coordinate, uuid, layer name or stroke value appears in any refusal. What can now enter: a root gr_arc on Edge.Cuts whose three points are distinct and non-collinear, whose span is at most a half turn, and which bulges away from the assembled ring's interior. What still cannot: a concave arc; a major arc; gr_circle, gr_curve, gr_bezier or gr_poly on Edge.Cuts; a footprint-local Edge.Cuts graphic; an arc whose endpoints miss by any distance at all; two shapes sharing both endpoints; any unlisted arc child. Nothing is written and no new I/O path is reachable: conversion stays read-only, source bytes are unmodified, and no file, network, subprocess, apply or board-write path is added. The new disclosure is a bound, not a value. outline_inward_deviation_nm is a nanometre distance derived from geometry the caller already supplied, the same disclosure class the eight existing unmodelled_counts entries occupy; the residual that a caller can lose it by round-tripping a snapshot through JSON is carried by R-180. One surface is narrowed rather than widened: placement_preview now refuses a board whose outline is approximated, which removes a claim it could previously have made incorrectly had arcs been admitted without it. | @seunghyukchoe | | SEC-167 | 2026-08-28 | The parser input surface widened by D-230/ADR-0125: a previously refused construct — a filled fp_poly on a copper layer — is now read rather than rejected, and its vertex list is unbounded in the source. Nine further heads move from one shared refusal to nine named ones. A new benchmark instrument reads two third-party boards. | The vertex list is the attack surface, and it is charged rather than trusted. A polygon is reduced to a bounding envelope, so its vertices vanish before Board IR validation counts serialized rings and a caller's max_total_vertices would not have covered them; _charge_graphic_envelope_vertices charges them against the same budget reduced custom-pad primitives charge, and the remaining budget is subtracted before validate_content runs. B-136 measured polygons up to the v_gt_256 bucket on real boards, so this is a live path and not a hypothetical. Coordinates go through the same exact-decimal _mm and the same _transform overflow guard every other geometry uses; a non-quarter-turn rotation still refuses before any of it. No diagnostic echoes a board byte. The nine named refusals select their sentence from a closed table by an equality test on the head and never build it from the source token, which is the rule _UNMODELLED_COPPER_GRAPHIC_HEADS already follows one level up; a head outside the table falls to the unnamed sentence rather than being interpolated. Locators are computed indices, not board content. The write-back boundary is unchanged and now load-bearing for more boards. The emitted Segment carries a revision-derived identity, so kicad_route_patch and kicad_placement_patch both refuse the snapshot — a patch cannot delete or move copper this adapter only approximated. No parity surface reads the new objects: the placement legalizer's four verdicts read pads, outline and keepouts only, so an over-approximated obstacle cannot manufacture a violated. The instrument publishes no board content. benchmark_public_copper_graphic_census.py commits committed_board_bytes: 0 and, one step stricter than its siblings, converts every ratio into a predeclared bucket membership before it reaches the artifact, so coordinates_committed and ratios_committed are 0 alongside the four existing zeros. It is read-only by assertion and re-verifies every source hash after measurement. No new dependency, network call, subprocess, filesystem write or apply authority. | @seunghyukchoe | | SEC-168 | 2026-08-29 | Enabling KiCad's IPC API server widens the workstation's attack surface, and this is what it actually widened. The operator enabled the server for B-138's observation, so the exposure is now a fact about the machine rather than a hypothetical, and it is recorded by measurement rather than from the documentation. What now listens. A Unix domain socket at /tmp/kicad/api.sock (plus a /tmp/kicad/api.lock at 0600), created by KiCad and reached by kipy's _default_socket_path() when KICAD_API_SOCKET is unset. Measured mode srwxr-xr-x, owner uid 501, in a directory /tmp/kicad at drwxr-xr-x owned by the same uid inside the sticky world-writable /tmp. No TCP listener was created — lsof -iTCP -sTCP:LISTEN shows no KiCad socket — so this is local-only and does not expose the workstation to the network. CopperMCP's own _socket_path() independently refuses any endpoint that is not ipc://, an absolute POSIX path, or a Windows named pipe, so the adapter cannot be pointed at a TCP endpoint even if the environment tries. Who can connect, and the honest answer is: anything running as this user. Connecting to a Unix socket needs write permission on it; srwxr-xr-x grants that to the owner only, so the boundary is the uid, not the group and not other users. Within that uid there is no authentication whatsoever. KICAD_API_TOKEN was unset during this observation and kipy sends an empty token; the connection succeeded. The token is not an access control and must not be read as one — as kicad_ipc.py already documents from KiCad's api_server.cpp, m_token is a per-instance KIID the server stamps into every reply so a long-running client can detect that KiCad restarted. It identifies the server to the client, never the client to the server. What that means concretely: the socket is a full-privilege mutation surface, not a read surface. The same endpoint that answered these read-only calls also exposes create_items, update_items, delete_items and the begin_commit/push_commit transaction primitives. Any process running as this user — a malicious dependency in any virtualenv, a compromised editor extension, a script the user runs once — can modify the open board, and the operator's only signal is the editor's own undo stack. CopperMCP's transport authenticates nothing, and does not claim to. Its safety here is entirely structural and worth naming precisely: it is gated behind COPPER_MCP_ALLOW_LIVE_IPC (refusing before the endpoint is read, so a disabled deployment never discovers an ambient socket), it has no write path, and it returns only redacted counts and digests. Those are properties of this client. They are not properties of the socket, and no other client on the machine is bound by them. Recommendation to the operator, and it is the reason this row exists: the IPC server is not a setting to leave on. Disable it when a live session is not actively needed. The exposure lasts exactly as long as the server does. Nothing was written. No board mutation, no save, no editor command, no commit or undo transaction, and no token or socket path was committed to any artifact — the observation records kicad_api_socket_configured and kicad_api_token_configured as booleans only. | | SEC-169 | 2026-08-29 | Internal negotiated-routing admission now accepts untrusted 2–32-pad requests with request-local lattice origins and continues to accept a custom router implementation for deterministic policy/replay tests. The widened pad collection increases bounded work; differing phases make the structural congestion key incomplete for physical intersections; and a custom router can return an honestly re-hashed candidate carrying fields the no-fill seam did not authorize. | Exact 1/2/32/33-pad boundary tests; legacy digest pins; full-pad demand and connection fixtures; request-local shifted-lattice completion plus disjoint-resource physical-crossing refusal; forged endpoint/pad-count/order and fill_binding atomic refusal; independent semantic-replay inequality; cancellation and budget tests; Ruff, type, security and full repository gates. | Accepted for the internal candidate-only boundary. Cheap closed validation runs before router work, pad work is capped at 32 and demand at 1,000,000, all identities and topology are reconstructed against the immutable snapshot/request, custom output must have no fill binding, and exact whole-set physical clearance remains the final authority. The result publishes no geometry through a new surface and grants no mutation authority. Remaining exposure is availability/quality only: shifted-phase conflicts may evade congestion scoring and consume bounded retries before refusal. MCP, CLI, jobs, persistence, apply, KiCad DRC, electrical and fabrication claims remain unchanged. | @seunghyukchoe + independent Codex review | | SEC-170 | 2026-08-29 | Shifted-phase conflicting copper entering the retained two-pad local-repair provenance path after D-233. Requiring every conflict vertex to be congruent with the target origin could silently remove repair availability; naively snapping to one cell could under-block copper, while applying conservative bounds to the target could weaken its authoritative lattice check and unbounded resampling could amplify work. | A half-grid shifted crossing must derive provenance and block both adjacent target-lattice cells, an honest three-pad/two-pad allocation must reach the coordinator repair transaction and publish only after its final whole-set recheck, and a self-hashed target with aligned endpoints but an off-grid interior dogleg must refuse. Floor/ceiling interval coverage is exact integer arithmetic only for conflicts; every target vertex remains strictly mapped through its request lattice. Aligned inputs reproduce the pre-change provenance digest sha256:7a2aedc596c54c0c00d44987a24094e3ec475636f4c8acd8c69e2cf903a5b14c, non-orthogonal or zero-length geometry still refuses, and the conservative total bounds remain subject to max_projection_cells before cell expansion. The committed mutation spec docs/mutants/2026-08-29-negotiated-shifted-repair-projection.json, SHA-256 9fbfd3925186e07a786cb20fa498ad39fc618b1f4a6014a990c4839c6ca7e0df, kills all 5/5 ceiling-cell, ceiling-bound, restored conflict-congruence and weakened target-bound regressions with zero survivors. Focused provenance and coordinator tests, Ruff, mypy, security and the full repository gate cover the remediation. | Accepted as fail-closed availability remediation. Projection may overblock one adjacent row or column and decline a feasible repair, but cannot authorize a collision. Candidate validation, whole-set physical clearance, bounded work, atomic refusal, closed diagnostics and all MCP, CLI, persistence, apply and board-write boundaries remain unchanged. | @seunghyukchoe + Codex PR review remediation | | SEC-171 | 2026-08-29 | Internal multi-pin local repair after D-233/D-234: an untrusted rejected allocation now reaches exact path-pair responsibility probes, new capability-bound provenance, single-branch reconstruction and a private complete-tree validator. The risks are detached geometry becoming authority, candidate/path identity splicing, mutation of supposedly untouched branches, same-net loops or surprise contacts, rewritten or lost accounting, resource amplification, cancellation loss and bypass of the final physical gate. | The coordinator preflights complete path-pair work at 65,536 checks and reserves same-envelope final-recheck work before a probe; consumed responsibility checks are included in public accounting. Selection binds snapshot/envelope/iteration, both complete candidate IDs, path counts/indices/digests/endpoints and responsibility digest/checks. Provenance adds cumulative bounded conflict projection, blocks every unselected target branch outside its existing attachment endpoints, passes cancellation into Board-IR projection and returns consumed obstacle work through a closed refusal on failure or cancellation. Reconstruction preserves every unselected path and non-derived field; the private validator verifies both canonical IDs, inherited proximity/search accounting, unique canonical unit edges, acyclicity, original-only path/pad contact cells, every Board IR edge and one component containing every selected-layer pad and path. Original topology plus two reconstructed passes share one exact preflighted edge ledger; every evaluated contact predicate is obstacle-charged and observes cancellation before evaluation. Exact reconstructed-set physical work is checked before validation, and final whole-set clearance remains mandatory. Tests cover first/last responsible branches, 3 and 32 pads, a re-signed contact loop, positive/tampered accounting, exact shared edge work, charged mid-contact cancellation, one/max/post-projection refusal accounting, projection cancellation, original/grown work budgets, forged/stale/capability inputs, cumulative budgets, absent responsibility, validator refusal and final physical refusal. The committed mutation spec docs/mutants/2026-08-29-negotiated-multipin-branch-repair.json, SHA-256 fc6e15174b9552629bb5f1368d0fd02dc594039e46c4557d5a493ac18579af27, kills 27/27 independent gate weakenings with zero survivors, stale anchors or invalid runs on Python 3.12.13 / macOS-26.5.2-arm64-arm-64bit. | Accepted for the private opt-in candidate-only transaction. Every refusal is atomic and redacted; the final whole-set physical verifier remains the publication authority. No public input, geometry-returning response, credential, filesystem, subprocess, network, apply, editor or board-write surface is added. This is not held-out quality, KiCad DRC, electrical or fabrication evidence; B-140 did not enable repair and #90 remains open. | @seunghyukchoe + independent Codex implementation/review | | SEC-172 | 2026-08-30 | Review remediation for multi-pin local repair's untouched-branch projection: a tree candidate can carry a bounded number of compressed paths but each short segment can expand into a repeated square of blocked-cell insertions. Without a cumulative work preflight, a small repair window could still force millions of set operations before the existing area ceiling noticed anything. | Untouched branches now have a coordinator-side O(compressed-segments) upper-bound preflight sharing the existing 4,096 projection-cell ceiling after conflict projection work. The runtime enumerator charges each attempted insertion, observes cancellation before every insertion, and carries consumed expansion plus Board-IR work through the closed refusal accounting; no partial blocked set or candidate is published. Tree attempts reserve worst-case projection plus validator work against the envelope's global obstacle ceiling before probing; exact remaining-budget admission is inclusive. Successful totals and evidence include untouched insertion work, while refusal/cancellation preserves all consumed work. Regression fixtures place 2,045 short one-cell zigzag segments in a small window and prove refusal before enumeration, cancel after 16 consumed insertions during enumeration, assert exact successful expansion work for the legacy tree, close the 98-to-107 reproduction at 100, and retain the accepted 32-pad and two-pin identity/total pins. The committed mutation spec docs/mutants/2026-08-29-negotiated-multipin-branch-repair.json, SHA-256 d300bc240fd390a15f47249178e93c1705f7bf81be99d055a105c447e98d4e6b, kills 35/35 attempts with zero survivors, including deleted or weakened preflight, removed cancellation, dropped consumed-work accounting, deleted global reservation, off-by-one refusal, and hidden success accounting. | Accepted as fail-closed resource hardening within the existing private opt-in candidate-only transaction. The 4,096 projection ceiling and public success identity contracts remain unchanged; the safe upper bound may over-refuse a feasible thick-trace repair. No MCP, CLI, persistence, apply, editor, board-write, network or credential surface changes. | @seunghyukchoe + independent Codex review remediation | | SEC-173 | 2026-08-30 | B-141's repair-enabled differential adds a self-digested aggregate report and companion commitment for the private multi-pin branch-repair transaction. The new evidence surface could be used to smuggle board or candidate data, misbind a positive completion delta to a different runner/configuration/corpus, treat an uninstrumented control as repair-enabled, or overstate a deterministic completion result as DRC, electrical or fabrication authority. | The closed runner accepts only the fixed B-140/B-088 population and fixed control/treatment projections; control carries repair_settings: null, treatment carries the default bounded repair profile, and both arms run twice with deterministic replay. The semantic guards include an envelope-outcome-to-population check, which rejects an arm when outcome_breakdown["envelope_construction"] does not equal the fixed population's boards_unable_to_form_a_two_request_envelope count (4); forbid a disabled control (repair_settings: null) from claiming completed_with_repair, repair_published or any non-zero repair-work field, and require all six status categories (completed, no_path, partial, invalid_request, cancelled, not_run) to reconcile to the outcome taxonomy. Report and commitment validation binds source b7c71d4d643df155c7bdcee5bac25e7d943b7031, runner sha256:5f5e8b8685bf178ef7064ce2690afb789678c2af9c727d40b18847e0738e23a1, configuration sha256:17966b8f508143cf3f54f797ea9a02d6fd66cbfe0621e830950f050f0f1868a3, whole-metrics digest sha256:f7e38d6744feed63b852e10811f34205bb822a1e2e7ca9759a8cea80a326d4b2, report run sha256:bb73a925b00506e4c5305bd2fe0136f4d501f7351d1b78d8b8552b010cf06fe3, artifact sha256:ff2bcd77814e3818a896eb2813b66def45997487301ec8954cd7614d7affc81c, commitment run sha256:3633c0b6a1fa362d30572311968e56539cec455e39f1ddf687547592da79e397, commitment sha256:129be265f95519db1bb7a5856ad1323d0b57ed0fc180a9bbe6161957b83696d9, and exact corpus manifest binding. The source guard verifies the actual Git runner blob SHA at the declared source commit and accepts later historical HEAD movement without replacing that binding. The closed total_ripups bound is 70 * (8 - 1) = 490, with 490 accepted and 491 mutation-killed. The closed aggregate wire bound is 70 * 62,500,000,000 = 4,375,000,000,000 nm, with the exact bound accepted and the +1 boundary mutation-killed. The commitment pins exact control and treatment arm totals plus the full differential, and its whole-metrics digest covers every report metric, preventing a self-consistent re-signing from changing any of them. Per-reason refusal/outcome reconciliation is checked independently, and a later merge-ref or checkout movement of HEAD preserves rather than replaces the historically recorded source binding. The report/result objects have closed keys and fixed taxonomies; private payload, geometry, board, net, revision, path, apply, mutation and network claims are rejected or absent. The 187-test focused suite and 78/78 evidence-contract mutant result have zero survivors or control failures and covers report closure, static values, environment, arm/population parity, deterministic replay, self-digest, commitment/source/runner/configuration/metrics bindings, clean-source/race-safe publication and redaction. Amended 2026-09-01 after twelve P2 review findings on the self-digest validator, which were one finding in twelve places: totals were authenticated but not their decomposition, their denominators, or their provenance. Every published breakdown now declares which run-outcome codes each bucket stands for; the declaration is checked for total, disjoint coverage and each bucket is reconciled against the codes it partitions, in the report and in the companion, so an item moved between buckets with the totals patched up is refused and a code that lands in no bucket fails the run rather than publishing a quiet zero. The total_overflow_units ceiling is now 70 * 250,000 = 17,500,000, derived from the submitted nets and the grid each may occupy, replacing admitted * iterations * submitted**2 = 627,200 -- a product of two population-wide aggregates and a per-board repeat count that was also small enough to refuse a truthful measurement from one dense board. date_utc is derived from the committer date of the recorded revision and checked against Git on authoritative load, rather than pinned as a literal. The commitment's arm key set is derived from the report's own arm schema, so total_physical_checks, total_wire_length_nm, every breakdown and every repair-work counter are pinned by name and a claimed aggregate added later without a pin fails the run. The republication reproduced the retired artifact's whole-metrics digest sha256:f7e38d6744feed63b852e10811f34205bb822a1e2e7ca9759a8cea80a326d4b2 exactly, so the measurements were re-bound, not re-measured. validate_report returns the guarantee it actually reached -- shape_only, offline or repository_bound -- and its docstring enumerates what each level does and does not establish, because three of the twelve findings (the evidence date, the recorded source revision, and the companion's measurement pins) are bound to the repository rather than to the document and are therefore outside that function's scope at any argument. _validate_authoritative_bindings returns repository_bound or companion_bound depending on whether the companion was consulted, and load_artifact -- the authoritative entry point -- checks that it reached LOAD_ARTIFACT_GUARANTEE rather than asserting so in prose. Three re-signed documents (a lying evidence date, a source commit naming nothing, a moved headline total) are tested as accepted at the offline level and refused once the repository is consulted, pinning the content of the weaker guarantee in both directions. An absent recorded commit and a disagreeing one are separated: a repository that does not contain the recorded revision -- reachable only from an unrelated branch, a shallow checkout, a fresh clone, or another fork's artifact -- receives a refusal naming the absence, never the tampering refusal, because no disagreement was observed. That case refuses by default, and downgrades to the offline level only when a caller passes allow_absent_source_commit; load_artifact cannot opt in. | Accepted as fail-closed evidence hardening for the private candidate-only benchmark record. B-141 records 20 offered/imported, 16 admitted, four envelope-refused and 70 submitted; control completes 0 boards/0 nets and treatment completes 1 board/2 nets with one published repair and one completed_with_repair. The positive completion delta is not a safety authority or quality claim: caller-selected report/sidecar paths walk every parent directory fd-relatively without following links, open the final exact regular file nonblocking, apply a 64 KiB max+1 probe before decode/JSON, refuse FIFO and other special files with fixed non-echoing diagnostics, and fail closed on recursion; no KiCad DRC, electrical, SI/PI/EMC, thermal, DFM, fabrication, apply, editor, hardware or general-corpus behavior is established. #90 remains open for human review/calibration, and #91's private surrogate ranking remains the next agent-only direction. | @seunghyukchoe + independent Codex review | | SEC-174 | 2026-09-02 | Private #91 surrogate ranking comparison boundary | The legacy candidate ID omits some settings, so unlike-for-like candidates could be ranked together; untrusted candidates could leak geometry or masquerade as physics/fabrication signoff. | Separate comparison digest binds base revision, net, ordered endpoints, layer, width, pad count, ordering policy, fill binding, router version, policy and all nine A* settings; mismatches return incomparable_candidates, while seed/geometry/cost/metrics remain rankable variation. Exact immutable inputs, bounded vertices/candidates, deterministic scoring, closed redacted output, cancellation atomicity, direct-import-only scope, no MCP/CLI/apply/production caller, and unchanged DFM KiCad DRC authority preserve the boundary. Final 62 tests and 23/23 mutation kills pass. | Mitigated for private advisory slice; open for SI/PI/thermal authority, reviewed exposure, held-out quality and human calibration. | D-237, R-187, issue #91 | | SEC-175 | 2026-09-04 | OrcaRouter outbound advisory-policy boundary | Source review plus the 18-test focused suite: fixed HTTPS host and redirect refusal; key/model/timeout validation; alias redaction; local candidate rebinding; closed tool schema; duplicate/non-finite/oversized/multiple-response rejection; non-echoing transport failure; and no MCP, CLI, geometry, DRC, or apply path. No live credential or provider call was used. | Accepted on this branch as an experimental direct-import-only layer. Raw board content, revision, identities, bounds, coordinates, copper, route geometry, prompts, filesystem data, and apply tokens are excluded from requests; provider output cannot become a decision without local decoding and evaluate_policy. Availability, quota, provider forwarding/metadata, policy quality, and hard process isolation remain open; no routing, DRC, electrical, manufacturing, or apply claim is made. | @seunghyukchoe | | SEC-176 | 2026-09-04 | OrcaRouter offline merge-readiness hardening | The focused suite now passes 24 tests, including valid tool calls, unknown aliases, duplicate fields, bounded and nested JSON, redirect refusal, transport errors, non-success/no-retry behavior, non-finite values, missing keys, and configuration bounds; targeted Ruff and format checks pass; tests remain network-free and no live credential/provider call was used. | Accepted for the experimental branch boundary only. The added decoder and availability regressions are covered locally; exact clean make check, partner-approved synthetic live smoke, public compensation terms, provider forwarding/metadata, policy quality, hard isolation, and production readiness remain open. | D-247, ADR-0130, R-193, SEC-175 | | SEC-177 | 2026-09-05 | Internal optimization/v1 foundation | Closed bounded JSON command shapes; strict bool/cardinal checks; frozen typed metadata; post-placement composition and candidate/context/target-denominator binding; fail-closed missing judge authorities; CAS and non-resetting budgets; single-use bounded host-confirmation primitive; no optimization MCP registration or apply imports. Synthetic adversarial tests exercise refusal and replay, not actual router/DRC evidence. | Open for production integration: no authenticated human UI, durable transaction/worker fencing, live external router smoke, verified executor evidence, or geometry-disclosure transport is supplied. Checklist success never authorizes release. D-250, R-195, ADR-0132 Implementation self-review; independent review pending | | SEC-178 | 2026-09-02 | Re-review of the B-141 evidence validation boundary after provenance moved from revision to content; amends SEC-173, whose surface this changes rather than extends | Per-input content refusal parametrized over all six bound inputs, asserting the refusal names the drifting input; derived coverage in both directions (a published digest outside the verified set, and a verified set that stopped covering a published key); proof that the coverage guard is reached by the content check rather than merely present; a reconstructed squash orphan accepted at repository_bound because the content survives; _resolve_recorded_commit monkeypatched to raise across an authoritative load; the tri-state history check exercised through all three outcomes, without Git, and proven unreachable from every validation path; oldest-not-newest first-parent selection driven through a synthetic listing; the companion proven to be what refuses a re-signed date, revision or headline total; and a three-case fresh-clone measurement -- shallow clone plus branch fetch, simulated squash, and a --depth=1 control on main that refuses | Accepted. The boundary is narrower in one place and wider in another, and both are stated: a caller stopping at repository_bound now accepts a document naming any revision, whereas that document previously failed there; and every bound input is now individually verified against live bytes rather than one runner blob being read out of a recorded revision. load_artifact still reaches companion_bound and still checks the level it reached, so no guarantee moves at the authoritative entry point. The bounded 200-commit first-parent walk keeps the new history check off the unbounded-walk denial-of-service surface, and it is opt-in, never reached by validation, and never written into the artifact. This is evidence-contract review only: no MCP, CLI, apply, persistence or network surface changes, and no DRC, electrical, thermal, DFM or fabrication claim is created or altered. | Initial maintainer | | SEC-179 | 2026-09-05 | Native optimization runtime, MCP confirmation/disclosure, and external container execution boundary | Targeted repository/worker, native-composition, schema, source-binding and MCP tests; synthetic host/KiCad observations are labelled as such. The composed-bundle suite also exercised the installed KiCad locally. Full-suite, hosted, container and real-host acceptance are still pending. | Under independent review. Metadata-only persistence, owner-scoped CAS, expiring fences, private artifact limits, source/context rechecks, no model approval capability, default-off human-channel trust, and unchanged separate apply tools are the intended controls. No full hybrid-routing, physics, fabrication, hosted-speed or release acceptance is claimed. | Integration self-checks; independent review pending | | SEC-180 | 2026-09-05 | Amendment to SEC-179: source import and parent delivery gates; actual local container availability | Closed bounded child response, source/hash/terminal-state validation before callbacks, inventoried source-only imports, rejection of linked/special/extension/sourceless modules, staged private publication, and readiness checks before and after host consent. Targeted adversarial tests pass. Explicitly authorized Colima/Docker setup preserves the default context and shares no host folders; both pinned real router images completed public synthetic format smokes with no network or host mounts. A real FreeRouting permission failure exposed root-owned tmpfs; fixed UID/GID 65532 and mode 0700 are regression-pinned. | Local execution and delivery hardening only; full-suite, independent final review, real human-host confirmation, production external geometry disposal/DRC, held-out quality and hosted timing remain release gates. No private board was sent to either router smoke, and no board was applied. See runtime setup and smoke scope. | Integration remediation and local smoke | | SEC-181 | 2026-09-06 | Private readiness/electrical-input declarations and incomplete-search handling | Closed bounded decoders, exact catalog/source/origin binding, critical blockers even above ninety submitted points, explicit unverified artifacts and null audited readiness. Electrical declarations validate reference kinds, physical order, integer units and per-edge model suitability; only digest/count/missing-category views are durable-safe. Inner legalizer exhaustion cannot become certified search work. | Locally tested contract and refusal boundaries only. No physics executor, authenticated artifact intake, strict native transaction, new MCP operation or application authority is added. Independent integrated review and real evidence remain gates. | D-253, D-254, ADR-0134, ADR-0135; main-agent review | | SEC-182 | 2026-09-06 | Fresh benchmark replay import binding | A regression reproduced execution of stale timestamp/size-valid bytecode despite an inventory of newer source. The replay now compiles bounded source bytes after checking their inventory digest, restricts core/harness module origins and namespace paths, rejects preloaded project modules, and bounds inventory nodes. Thirteen focused tests cover source drift, stale bytecode, unbound source, extension and sourceless modules. | Local import-binding verification only; full current-source replay and independent review remain separate checks. The receipt does not authenticate physical evidence, authorize a release or grant application authority. | D-252; replay-source tests | | SEC-183 | 2026-09-06 | Offline harness environment and server isolation | Full validation exposed real-router smoke settings erased during collection. Temporary environment restoration fixed that loss, but independent review rejected canonical-server cache pollution: harness-first import could force stdio/default settings on a later HTTP startup. The revised helper loads the fixed implementation into a separate offline module; canonical imports/settings remain untouched, failed construction clears its private cache, and all harness calls retain explicit settings. Twelve subprocess cases cover both import orders, invalid inherited settings, failed initialization/retry and mocked HTTP CLI startup. Forty-nine harness tests passed; all three reports now record the helper path/hash separately, and historical records remain byte-identical. | Local offline testing only, not a concurrent production-server factory or human-consent authority. Final provenance re-review and integrated checks remain separate. No transport, provider or user-board mutation was invoked by the import regressions. | Independent review findings and main-agent remediation; D-252 | | SEC-184 | 2026-09-06 | Captured candidate connectivity-parity boundary | Seventy-seven tests and 23 subtests passed across the captured/private and existing public parity paths. Real installed KiCad controls distinguish candidate bytes from an intentionally different workspace board, verify the captured revision and preserve workspace bytes. Hermetic cases cover stale/malformed/oversized input, invalid and enormous deadlines, late subprocess output and late report acceptance. Existing fixed arguments, private environment, snapshot integrity, report bounds and component-accounting liveness remain shared. | Candidate-to-bounded-intent connectivity only, using compiled-in severities. No project-context ERC, footprint correctness, physics, MCP/package exposure, application authority or release claim. Independent scoped review and integration validation remain pending. | D-255; main-agent review and bounded implementation worker | | SEC-185 | 2026-09-06 | Amendments to SEC-183/SEC-184: source provenance, whole-operation deadline checkpoints and collection isolation | Independent review closed offline server-cache isolation and required the new helper path/hash in all three report identities; this is implemented without rewriting historical reports. It also found that parity hashed inputs before checking expiry and reused a scan allowance; deadline validation/checkpoints now precede hashing and each bounded write, scan, read, parse and final acceptance phase. Fault injection proves the next phase is not entered after expiry. A Python 3.13 broad run found a separate deleted-workspace leak from in-process CLI tests; per-test restoration plus a hermetic committed-killing-test collector fixes the cause and proves refusal to inherit invalid parent configuration. The 154-test focused group with 56 subtests passed on both 3.11.15 and 3.13.15. | Local remediation evidence only. The earlier 3.13 run remains a failure (4,562 passed, one failed, two skipped); final broad and integrated review results must be recorded separately. CLI product behavior, mutation gates, historical artifacts and public optimization contracts are unchanged. | Independent findings, main-agent remediation and bounded test worker | | SEC-186 | 2026-09-06 | Integrated optimization review and nested-mutation evidence remediation | Independent runtime review found four P2 gaps: optional approval observations defaulted to expected values, parent response processing could overrun the deadline, heartbeats could prolong crash recovery beyond runtime, and completed cancellation retained unnecessary private accounting. Explicit validated observations and fresh bounded board parsing now precede consent consumption; parent parsing/decoding/hash/callback phases recheck expiry; renewed lease duration shrinks to remaining runtime; source/judges are revoked immediately while only running-work accounting remains until its callback. Review-only completed status is preserved. A four-worker coverage run also exposed inherited pytest options changing collection failures into apparent mutation kills; nested runs now preserve spec arguments but clear ambient options and force serial execution. | Focused remediation only; final integrated re-review and broad checks remain required. The coverage attempt is retained as unsuccessful: 4,565 passed, two mutation-harness failures, two skips, 520.61 seconds. No user board was applied, missing engineering authority remains inconclusive, and no historical evidence was re-signed. | Independent integrated review, main-agent fixes and bounded execution workers | | SEC-187 | 2026-09-06 | Final local verification of the reviewed integration increment; amends SEC-182 through SEC-186 | Final source/input inventory sha256:324658cefd328e078581b064297c66a75437414db3e553193629bf83701369c7 remained stable. Canonical full make check passed 4,586 tests with two skips and 779 subtests; coverage 89%, mypy 136 modules, security/audit/build checks passed. Final 3.11 and 3.13 compatibility selections each passed 4,585 tests; fresh current-source B-141 replay plus isolated-delivery tests passed 24 tests on each. The PATH-gated KiCad authority-path case was then executed separately on all three, one pass each. Independent review accepted explicit observations, bounded leases, deadline-through-delivery, cancelled-data/accounting cleanup, callback staging release, and serial isolated mutation verdicts. A final fault test proved that expiry inside the last database status read cannot become successful delivery; failed-future and staging references are released. | Accepted for the reviewed local increment only. These observations do not authenticate held-out quality, complete physics, strict native editor transactions, genuine human consent, hosted speed targets or release readiness. Existing review-only completion and separate apply controls remain intact; no user board was applied, no source was publicly published, and historical reports were not re-signed. See the final checkpoint for selections, timings and remaining gates. | Independent scoped/integrated Codex review and main-agent final verification | | SEC-188 | 2026-09-06 | Private electrical artifact capture | Independent review found and closed portable case/normalization aliases, Unicode control/surrogate admission, and caller-mutable limit instances. The implementation snapshots exact validated limits, performs two complete bounded descriptor-read sweeps, verifies declared bytes, refuses detectable drift and publishes no partial capture. Forty-eight focused tests passed independently; input/readiness/capture groups passed 84 tests on Python 3.11 and 3.13, and main source mypy passed 137 modules. | Accepted for artifact-byte verification only. Canonical alias refusal is intentionally conservative; hard-link identity, filesystem-wide atomicity, model authenticity, dependency closure, project parity and physics remain unverified. No MCP surface, model execution, audited readiness score or application capability is added. | D-257, R-199, ADR-0136; independent Codex review and main remediation | | SEC-189 | 2026-09-06 | Isolated current census fixture | Fixed census-only argument, fresh digest-checking source imports, pre/post source inventory, bounded self-digested output and a minimal child environment preserve current computation rather than substitute history. The parent validates closed fields, exact numeric types, duplicate/non-finite JSON refusal, interpreter and source binding before all existing assertions consume the report. Independent stub/validator/CI-wiring review passed 29 tests with no remaining P1/P2 findings. The full B-140 file passed 47 tests before final decoder hardening; the real fresh-comparison fixture under parent coverage subsequently passed in 89.42 seconds of setup. | Accepted for the private compatibility/evidence path only. Default B-141 remains unchanged and historical runners/artifacts have no diff. Full integration and new hosted speed measurement remain required; the earlier green hosted run missed the twenty-minute target and does not satisfy main calibration. No geometry, model, engineering, release or application authority is created. | D-258, ADR-0137; independent Codex review and main measurement | | SEC-190 | 2026-09-06 | Combined capture/census verification | Source/input inventory sha256:989bd1cbe8baa3741c1d915fb67cf652f32613e53d52affbaeb375b0952cff8d remained fixed through canonical full validation: 4,649 passed, two skipped, 779 subtests, 89% coverage; mypy 137 source modules, lint/metadata, secret scan, dependency audit and build passed. The B-140 source-bound setup took 95.56 seconds within the run, with B-141 replay retained. Capture/input/readiness tests passed 84 tests on each alternate supported interpreter. | Accepted for the reviewed local increment; updated hosted validation remains pending. Initial hosted baseline 34009062108 passed but missed the speed target at 32m12s. No main calibration, physical calibration, complete hierarchy/parity, strict live mutation or readiness percentage is claimed. | SEC-188, SEC-189; main-agent integration verification | | SEC-191 | 2026-09-06 | Mandatory evidence and test-infrastructure classification | Independent integrated review found that a conftest-only PR could skip the evidence job. Fourteen initial classification regressions failed before the fix; all root/nested conftest hooks and documented root pytest configuration files now fan out evidence. Two real Makefile invocation tests failed before switching the required target outside pytest; afterward the combined classifier/workflow suite passed 50 tests. A hostile conftest is not imported by the required replay, nonzero replay exit propagates, and the existing one-hour ceiling remains. | Fix pending final review and fresh integrated/hosted validation. This prevents test-hook skipping, not arbitrary tampering with the reviewed runner or workflow itself. The preceding 5c1d5b8 baseline passed 4650 tests, two skips, 779 subtests and 89% coverage in exact-head make check; those results do not certify the new fix. | D-260; pytest configuration reference | | SEC-192 | 2026-09-06 | Parser allocation evidence isolation | Independent review found a disabled tracer could report zero bytes as a successful measurement. A parser-stub regression reproduced that false success, then passed after enforcing fresh/active tracer ownership and positive peaks in producer and parent. Exact original workload hashes, integer-only limits, malformed/tampered/source/interpreter refusal tests and the original memory-law assertions remain. The reviewed code-only slice passed 139 focused tests on each of Python 3.11, 3.12 and 3.13, plus Ruff 0.16.6. | Accepted for the private allocation-test path; main-based integration and hosted performance validation remain required. This is synthetic resource evidence, not board routability, engineering correctness, release or application authority. Allocation peaks are not claimed deterministic across hosts or interpreters. | D-261; independent Codex review and main-agent regression/compatibility verification | | SEC-193 | 2026-09-06 | Foundation and parser main validation closure | Append later evidence to SEC-191/192 without rewriting their earlier observations. The final classifier/workflow suite passed 51 tests on each interpreter, including NUL-delimited Unicode/newline paths. Exact 987569b make check passed 4673 tests, two skips, 779 subtests and 89% coverage; the skipped real KiCad test subsequently passed with installed 10.0.5 on PATH. PR 268 merged as a0a572b with equal Git trees and all main jobs passed in run 34019964835. Exact d03581f parser make check passed 4690 tests, one two-pin-only skip, 779 subtests and 89% coverage with real KiCad/container smokes enabled. PR 269 passed in 11m34s, merged as 5fbada0 with equal Git trees, and all main jobs passed in run 34021596538. Main paths were 22m03s and 20m26s. | These two successful main runs calibrate all four CI roles, retaining every matrix observation and all 120-minute ceilings. One qualifying PR-speed result is not the required three-run streak. Original dirty checkout and restored integration-history branches are preserved. Full v0.13 acceptance, real-host consent, calibrated physics, held-out quality, strict native mutation and audited five-area readiness remain open; no release or apply authority is added. | D-260, D-261; foundation main, parser main |

2026-09-06 follow-up to SEC-193: the first calibration full gate at 9fd2567 failed on a stale CB2 comment anchor (4,689 other tests passed); it is not successful full-validation evidence. Re-anchor CB2 to the same unique quality timeout. The required mutation replay exposed CB6's outdated mapping to the pending branch, and its first report write failed because the output directory was absent. Re-anchor CB6 to the actual missing-entry guard and add a valid-plus-missing-job discriminator. Through the committed budget spec and repository mutation harness, the subsequent run produced baseline exit 0, 15 killed, zero survivors, and all restoration controls exit 0; spec SHA-256 is dfef12dd729520d7c89b02d6e0a5d1fd49c20fcc214812912173c915842d4a7d. Independent review accepted the repaired mapping. Production checker logic, measured observations and timeouts are unchanged. A fresh exact-head full gate is still required before publishing this calibration milestone. | SEC-194 | 2026-09-06 | Private schematic hierarchy boundary | Preserve the Board IR/candidate/validation/apply separation and v1 meanings. Tests cover confined exact references, nested/shared UUID paths, malformed field tails, aliases, cycles, byte/work/depth limits and redaction. A red regression test demonstrated empty project-variable substitutions bypassing output-size/depth bounds; charge each recursive input length plus one against 65,536 units and propagate the shared deadline. Exact-bound and expiry controls now pass. | No native engine, file read, board write or capability credit in this slice. Prior hierarchy review and separate Ponytail audit informed the implementation; current independent review, exact-source full validation and protected hosted checks remain required before merge. Ponytail found only optional duplicate variable-validation cleanup; no safety checks or dependencies were removed. | D-262, R-200; ADR-0138 |

2026-09-06 follow-up to SEC-194: independent review rejected 9cf5885 because recursive project-variable values can derive a different child path than KiCad's single-pass loader. The new discriminator failed before the fix. Replace recursion with one bounded substitution pass, refuse unresolved values, and keep pre-append output limits and shared deadline checks. This supersedes the earlier recursive work-meter design and removes that attack path. The superseded full check was deliberately interrupted after 427 passing tests at 515.37 seconds; it is not successful full-validation evidence. Fresh review and full validation remain required. The separate, unmerged ERC executor also needs severity and authorized-backend identity gates; no success is claimed for it here.

2026-09-06 second follow-up to SEC-194: the reviewer and primary confirmed native suppression of the exact case-sensitive ERC_WARNING/ERC_ERROR/DRC_WARNING/DRC_ERROR prefixes during filename expansion. Reject those prefixes before map lookup; four nonempty-value regressions now pass. The reviewer accepted the final scoped patch and checked lowercase case sensitivity independently. All 149 hierarchy tests pass on Python 3.11, 3.12 and 3.13; Ruff and strict mypy pass. The superseded 8eefe8f four-worker full check was interrupted after 4,454 passes and one skip at 283.87 seconds, not counted as successful evidence. Run the complete suite on the final commit before publication. Later ERC input, backend-authentication and severity findings remain outside this metadata-only milestone.

2026-09-06 closure of SEC-194: exact a828a6a full make check passed 4,840 tests, one intentional fixture skip and 89% coverage with four loadfile workers, real KiCad and both pinned router smokes enabled. PR #271 passed all hosted checks in 21m27s, missing the speed target. A proposed KIPRJMOD root-anchor change was declined with pinned native-source evidence; its conversation was resolved before protected squash merge. Main e98f4fc has the same Git tree and successful CI run 34033755004 (11m30s). The source branch was restored after automatic deletion. No release or readiness credit was granted.

| SEC-195 | 2026-09-06 | Declared schematic-project capture | The separate capture review identified missing cooperative JSON checkpoints and retained malformed-limit/overflow exception contexts. Red regression tests reproduced the context issue; the implementation now uses shared callbacks, post-handler deadline precedence and fixed raises outside handlers. The reviewer accepted the fixes with 40 focused tests, Ruff and mypy. The source-derived/native-controlled declared-only KIPRJMOD behavior was preserved. | New-main integration still needs its exact-source full gate and hosted checks. Byte/hierarchy verification is not library closure, model validation, parity, real ERC, physics, atomic filesystem capture or application authority. The later ERC executor is excluded from this milestone. | D-263, R-201; ADR-0139 |

2026-09-06 integration follow-up to SEC-195: independent review of the fresh-main capture-only diff found no actionable issues; 66 capture/settings/CLI tests and 189 hierarchy/capture tests passed, along with Ruff/format, strict mypy and metadata checks. A separate Ponytail audit inventoried 1,029 non-generated files and inspected this input path; it suggested one optional redundant variable-map traversal (about three lines), with no dependency or safety-control removal. No audit edits were applied. Exact-commit full validation and hosted checks remain the publication gate.

2026-09-07 closure of SEC-195: exact ad5996a full make check passed 4,880 tests, one intentional fixture skip and 89% coverage, with four loadfile workers and existing real-engine smokes enabled. PR #272 passed hosted checks in 20m25s, still above the speed target. Protected squash main 7f197b3 has the identical tree; main CI34039035604 passed in 14m59s. The source branch was restored after automatic deletion. No release or readiness credit was granted.

| SEC-196 | 2026-09-07 | Identity-neutral ERC report boundary | Preserve v1 wrapper meanings while checking project UUID coverage, duplicate identity and expected severity floors. Bind full finding details rather than aggregate counts alone. The initial transplant passed 33 tests and 26 subtests, Ruff/format and strict mypy. | Independent review and exact-source full validation remain required. Expected UUIDs and severities are caller-owned constraints, not authenticated engine evidence; child-file load completeness and real project execution remain outside this parser slice. | D-264, R-202; ADR-0140 |

2026-09-07 follow-up to SEC-196: independent review found that an active severity floor could still be ignored or its finding excluded, producing a zero-hard-error observation. Both controls reproduced before the fix. The parser now copies and validates the full expectation map upfront, rejects ignored active keys and excluded/downgraded findings, and preserves explicitly disabled outside-scope categories without granting them capability credit. Legacy calls without a map remain unchanged. Focused review and exact-source validation must close this correction before publication.

2026-09-07 focused review closure for SEC-196: the reviewer accepted the corrected floor behavior and unchanged legacy None path; independent hermetic checks passed 25 tests and 30 subtests. Canonical combined parser/CLI checks passed 36 tests and 34 subtests, Ruff/format and strict mypy. Ponytail's separate inventory/detailed parser audit proposed no justified cuts. Exact-head full validation and hosted checks remain required; no executor or source-load authority is added.

2026-09-07 PR review follow-up to SEC-196: hosted review identified a mutable dictionary inside the frozen observation. A new regression reproduced post-validation count mutation. Copy counts into MappingProxyType during construction; independent review accepted the fix and separately checked alias isolation and legacy serialization. The earlier e656efa full check passed 4,890 tests, one skip and 89% coverage, and its hosted CI passed in 20m29s, but neither waives fresh validation of this correction.

2026-09-07 publication follow-up to SEC-196: exact 7d89436 full make check passed 4,891 tests, one intentional fixture skip and 89% coverage with four loadfile workers and existing real KiCad/router smokes enabled. Hosted PR 273 passed in 20m43s. Protected squash main 0086315 has the identical tree; main CI34047446714 remains pending at this entry. The source branch was restored after automatic deletion. No project executor, native guard or readiness claim was included.

| SEC-197 | 2026-09-07 | Focused census refusal fixtures | Replace a large corpus input only in admission-disagreement and complete-object-parity negative controls. The small existing KiCad fixture still executes actual solo routing and the coordinator; an additional positive control establishes admission and unperturbed parity. Existing complete-corpus replay and privacy/provenance assertions remain. Canonical covered controls passed, with their timing limitations recorded explicitly. | Independent correctness review and complete final-source validation remain required. This changes no production geometry, parser, policy, marker, evidence exclusion, approval or apply surface. Test speed is not routing-quality or engineering evidence. | D-265; execution program |

2026-09-07 scoped closure of SEC-197: independent review accepted the fixture adapter, genuine admission/control parity and both specific negative controls; the reviewer independently ran all three tests. Canonical covered controls and Python 3.11/3.13 uninstrumented controls passed, as did Ruff/format, ledger and documentation-link checks. The full corpus replay, all other assertions and production files are unchanged. Complete final-source validation and hosted checks remain the publication gates.

2026-09-07 publication follow-up to SEC-197: exact 3941b2e full make check passed 4,892 tests, one intentional fixture skip and 89% coverage, with four loadfile workers and the existing real-engine smokes enabled. PR274 CI34048359193 passed in 18m51s, the first current consecutive under-twenty-minute observation after intervening nonqualifying runs. Protected squash main 9865e2b has the identical tree. Main CI34049532015 remains pending at this entry; its result is not a PR-speed observation. The source branch was restored after automatic deletion. No routing-quality or readiness credit was granted.

| SEC-198 | 2026-09-07 | Captured project ERC preparation | The independent preparation review identified late captured-file count validation, rejection of native-valid pin matrix value 3 and raw overflow from very large integer deadlines. Four regression controls reproduced the defects before correction. A further review confirmed quadratic unused-inheritance lookup without timely checkpoints; its corrected regression also reproduced late traversal. Early count bounds, guarded deadline conversion, the native 0..3 matrix domain, one symbol-name set and per-symbol checkpoints now pass 32 focused tests. | Final scoped re-review, full final-source validation and hosted checks remain required. The separate executor, complete source loading, general symbol/model fidelity, project parity and actual judgement/application authorities remain outside this slice. | D-266, R-203; ADR-0141 |

2026-09-07 complexity review for SEC-198: Ponytail initially proposed removing BACKEND_VERSION as unused in the preparation-only split. After checking its existing local executor and fault-test consumers, the reviewer retracted that finding. No justified cuts remain and no audit edits were applied. This is complexity review, not correctness or execution acceptance. A separate real-engine integration control in the unpublished executor first reproduced rejection of native pin-map value 3, then passed after the corresponding fix: the pinned backend reported the expected hard pin_to_pin finding and preserved source bytes. That control is not included in, and does not certify, the preparation-only publication.

2026-09-07 scoped correctness closure of SEC-198: the independent reviewer accepted all four corrections and the current preparation boundary with no remaining actionable findings. The reviewer independently ran all 32 focused tests, including successful contained unused inheritance and refusal immediately after injected expiry. Canonical Ruff/format, strict mypy, ledger/ADR and documentation-link checks pass. Cross-version controls, final-source full validation and hosted gates remain necessary; the broader executor and its authority claims are not covered by this acceptance.

2026-09-07 hosted-review follow-up to SEC-198: exact 838a01a passed full make check (4,924 tests, one intentional skip, 89% coverage) and hosted CI34050941560, but two hosted review findings correctly kept PR275 blocked. Settings normalization lacked local deadline checks and subordinate errors could escape the dedicated preparation error type. Six new controls reproduced both deadline gaps and four subordinate error paths with private chained causes. The normalizer now checks traversal/serialization boundaries; a minimal outer wrapper retains owned fixed refusals and translates subordinate validation failures after their handlers. The independent reviewer accepted the corrected production/test blobs with 38 focused tests. New final-source full validation and hosted checks remain required; the earlier green run does not waive these corrections.

2026-09-07 publication closure of SEC-198: final 4e7fa55 passed full make check (4,930 tests, one intentional skip, 89% coverage) and hosted CI34053481728 in 18m48s. Both addressed review conversations were resolved after validation/push. Protected squash main 78f8142 has the identical tree; main CI34054615852 passed in 16m15s with Security/CodeQL/OpenSSF also green. Source branch restored after automatic deletion. PR274 and PR275 are two current consecutive under-twenty-minute observations, not the required three. No readiness or application credit was granted.

| SEC-199 | 2026-09-07 | Bound current-project connectivity ERC | Integrated independent review found that a valid captured-input report could outlive matching workspace source; six before/during root/project/child mutation controls reproduced stale delivery. The runner now descriptor-checks original bytes before execution and delivery and assigns the result only after the final check. Further controls cover missing/symlink sources, final-read size/deadline, invalid workspace types and context-free cyclic-path errors. The reviewer accepted the final execution source after fixes; real backend controls and 103 focused tests passed on the integration branch. | Fresh publication-source full validation and hosted checks remain mandatory. This review does not cover general library/model support, parity, physics, fabrication, atomic editor transactions, human approval or release. Command doubles do not earn native-engine evidence. | D-267, R-204; ADR-0142 |

2026-09-07 executor publication preparation: the reviewed four-file source/test set was copied byte-for-byte onto verified main 78f8142; the fresh worktree passed all 103 focused tests with the existing vendor-sealed KiCad backend, without modifying the installed app or original dirty checkout. The 596-line executor is reviewed with its associated regression tests as one coherent execution unit; preparer and report parsing were published separately. Ponytail identified an optional fixture branch simplification and questioned the Settings copy; the entry-boundary copy is retained by design to own caller-supplied limits. No audit cuts were applied. Full final-source validation remains the next gate.

2026-09-07 publication-context review of SEC-199: the reviewer confirmed the four executable/test files remain byte-identical to the integrated reviewed source and retained that acceptance. The ADR wording was corrected to distinguish admissible inconclusive reports from missing/invalid native outputs and excluded/ignored-active findings, which cause a fixed refusal with no report. The fresh 103-test group passed on Python 3.11, 3.12 and 3.13. Ponytail retracted the Settings-copy finding as intentional ownership of caller-supplied limits; the optional fixture cleanup was not applied. Final-commit full validation and hosted gates remain required.

2026-09-07 hosted-quality follow-up to SEC-199: bb32698 passed local make check (4,984 tests, one intentional skip, 89% coverage), but hosted run34056887553 failed Linux mypy because direct sys.platform constant folding marked the macOS verifier body unreachable. The same failure reproduced locally with --platform linux. A local runtime alias preserves the exact platform refusal condition while keeping the verifier implementation type-checked on every host; no ignore or disabled warning is introduced. Linux and Darwin type checks and the five backend controls pass. Independent review and new final-source full validation must close this correction before publication proceeds.

2026-09-07 scoped re-review of SEC-199: the reviewer confirmed from installed mypy source that direct platform comparisons are specially folded and accepted the runtime alias as preserving comparison, short-circuiting, backend requirements and both authentication call sites. No type-check suppression or runtime authority change occurs. New exact-head full validation and hosted checks remain required.

2026-09-07 second hosted-review follow-up to SEC-199: 2853fa9 passed its fresh local full check (4,984 tests, one intentional skip, 89% coverage), but hosted comments identified malformed CLI settings escaping as AttributeError and missing report-processing deadline checkpoints. Three malformed-path cases and an expiry-before-normalization control reproduced those defects. The runner validates None/Path before discovery and supplies the shared deadline to the ERC observation parser. JSON guards, semantic loops, normalization, hashing and return now checkpoint; v1 callers retain the no-deadline behavior. Seven additional controls cover default equivalence, bad/expired limits, JSON guard callbacks and normalization phases. All 190 focused/legacy checks passed, and independent review accepted the fixes after separately running 37 existing ERC tests. Final-source full validation and hosted gates remain required; earlier green local checks do not waive the corrections.

2026-09-07 publication closure of SEC-199: exact d835e8e passed full make check (4,995 tests, one intentional skip, 89% coverage) and hosted CI34059199918 in 19m07s. Addressed conversations were resolved after fixes and validation. Protected squash main ab934f0 has the identical tree; main CI34060206669 passed in 16m25s with Security/CodeQL/OpenSSF green. The source branch was restored. PR274/275/276 are three consecutive qualifying under-twenty-minute observations, not a readiness or physical-validation score.

2026-09-07 execution-context extraction follow-up to SEC-199: isolate private native setup, source probes and final verification before introducing candidate parity. Existing ERC report/error meanings and the fixed authenticated backend are retained; a real before/after control reproduced the identical report digest. Independent review found initial/per-file and retained-plus-transient syntax-copy admission gaps; red controls reproduced work before refusal, and the new checks reject before discovery or snapshot writes. A focused ordering control retains original-byte verification after all syntax probes and at closure, with private-state checks after each probe. Ponytail removed duplicate original-snapshot traversals and a no-op exception wrapper. The later parity runner and parser are not included in this refactor milestone. Exact-source full validation and protected hosted checks remain required.

| SEC-200 | 2026-09-07 | Ordinary-project parity observation boundary | Factor neutral native observations from the existing parser without changing the legacy component-accounting rule or accepted set. Explicit project expectations check enabled parity rules and companion finding shape; full normalized finding identities and cooperative deadline checks remain distinct from engine authentication and liveness. A fixed native probe observed empty parity output and exit zero when no schematic was loaded, motivating the separate executor gate. | This publication is report-only. The native candidate executor, general model/BOM support, full DRC, physical authority, edit atomicity, human consent and release remain separate. Final-source full validation and protected hosted checks remain required. | D-268, R-205; ADR-0143 |

2026-09-07 candidate-executor follow-up to SEC-200: the separate implementation now uses authenticated original-source loading, a private immutable candidate tree, parity-specific project rules and complete count-matched native diagnostics. Real synthetic matching and altered-net controls distinguish parity pass and fail; a malformed child refuses, sources remain unchanged and workspace board bytes are not consumed. Companion DRC remains explicitly inconclusive. Independent review found hashing after expiry and delayed per-file derivative admission; red controls reproduced both, then passed after bounded 64-KiB hash checkpoints and early file checks. The reviewer accepted the final code, including retained-plus-probe context fixes published separately. Ponytail removed a redundant diagnostic digest; matching transcript counts and command policy remain bound. The combined real-gated ERC/parity selection passed 309 tests on each supported Python interpreter. Exact publication-source full validation and protected hosted checks remain required; synthetic controls are not held-out quality or physical evidence.

2026-09-07 publication closure of SEC-199/200: PR277/f91c691 passed full make check (4,998 tests, one intentional skip, 89% coverage) and hosted CI34063909325 in 16m22s; protected main b839cd0 had the identical tree and main CI34064743854 passed in 10m10s. PR278/5b7ddb6 passed its final-source full check (5,007 tests, one intentional skip, 89%) and hosted CI34065988788 in 10m14s; equal-tree main ae9f831 passed CI34066672202 in 18m54s. PR279/941cba9 passed full check (5,034 tests, one intentional skip, 89%) and hosted CI34068052637 in 16m22s; equal-tree main 9ba46cf passed CI34068900826 in 18m54s. Security/CodeQL/OpenSSF gates passed for each main revision. Source branches and the original dirty checkout were preserved. These close the scoped publication gates, not held-out quality, physics, strict mutation, human consent or the five-area goal.

| SEC-201 | 2026-09-07 | Native component inventory boundary | A disposable root/nested native-export probe verified resolved references, root-relative sheet paths and explicit exclusion markers, with unchanged inputs and empty diagnostics. Native source inspection identified annotation warnings with exit zero and unit-grouping/virtual-reference omissions. The private parser/executor will bind those semantics under resource, identity, freshness and backend gates. | Independent review and final-source validation remain required. No BOM content, model definition, physical calibration, complete placed-unit coverage, approval or apply authority is claimed. | D-269, R-206; ADR-0144 |

2026-09-07 XML reader publication preparation for SEC-201: publish the report reader and its complete adversarial controls separately from native execution. Independent review identified absent/empty optional field forms as overrestricted; five red controls reproduced the contract gap, then all 53 parser tests passed after allowing only empty absence forms while retaining duplicate/conflict/one-sided-nonempty refusal. The reviewer accepted that correction. All 64 integrated component tests passed on Python 3.11 and 3.13, including four real native controls; a broader 152-test native/ERC/parity selection passed on 3.12. Those integrated results do not replace this report-only slice's final-source full and hosted gates. Ponytail removed duplicate digest construction without changing its bytes and found no further justified cuts. No execution, BOM/model, physics or apply authority is granted by the XML reader.

2026-09-07 hosted-review follow-up to SEC-201: 533adfc passed full local make check (5,087 tests, one intentional skip, 89% coverage), but PR280 review identified late ElementTree tail mutation across 64-KiB feeds. Three new controls reproduced acceptance of non-whitespace tails, oversized tails and a bypassed aggregate value ceiling. Keep the existing early parser limits, then independently account for the completed tree's values and tails under the same deadline. The three controls and a final-pass expiry guard now pass within the 57-test parser selection. The narrow stdlib XML call in the test is only an independent oracle over owned synthetic bytes. Re-review and a fresh final-source full/hosted run remain required; earlier green runs do not certify this correction or the dependent native executor.

2026-09-07 native executor follow-up to SEC-201: the isolated capture runs two fixed authenticated exports with original-source/context verification and refuses warnings, nonzero outcomes or divergent observations. Main integration corrected temporary import suppressions and bound digests to returned records rather than copied metadata. Four real controls cover nested paths, stale display labels, duplicate-annotation warnings and shared-child identities; all 64 component tests passed on each alternate interpreter, and the 152-test broader native/ERC/parity group passed on canonical 3.12. Independent integrated review accepted source and optional-field corrections; no further Ponytail cuts were identified. Final publication-source full validation and hosted gates remain required. Captured component metadata remains distinct from actual BOM content, model validity, physics, human approval and application authority.

2026-09-07 XML publication closure of SEC-201: corrected PR280/71b946e passed full make check (5,091 tests, one intentional skip, 89% coverage) and hosted CI34074718066 in 16m22s. Protected main 86654db had the identical tree and main CI34075912224 passed in 18m52s, with Security, CodeQL and OpenSSF green. The source branch and original dirty checkout were preserved. This closes the reader's publication gate, not native execution, BOM agreement, physics or application authority.

2026-09-07 PR281 deadline follow-up to SEC-201: review found that final inventory conversion and monolithic JSON hashing continued after expiry. Two new red controls reproduced continued record conversion and encoder advancement; both pass after cooperative checks during sort-key extraction, conversion and streaming JSON/hash work. Empty/nonempty Unicode and reordered-record controls retain the exact v1 digest bytes; a sort-key expiry control refuses before conversion. Bounded standard-library sort/token primitives remain cooperative, not hard real-time guarantees. Independent re-review and fresh final-source full/hosted validation remain required; the earlier 3fd3fd2 run does not certify this correction.

| SEC-202 | 2026-09-07 | BOM content boundary | A fixed native export control established CSV columns and DNP spelling. CSV red/green controls covered private exception chains, early text limits, canonical ordering and late sorting. Independent review reproduced raw integer-conversion exceptions under the legal 640-digit interpreter limit; exact standard-library Decimal conversions preserve bounded-field semantics without global setting changes. The corrected CSV reader passed 41 focused tests on each supported interpreter. | CSV parsing is data only; actual row/native reconciliation and its integration review remain separate. No model, rating, physics, release or apply claim. Final-source full and hosted gates remain required. | D-270, R-207; ADR-0145 |

2026-09-07 remaining-budget follow-up to SEC-202: integrated reconciliation review identified that each BOM artifact reset the row/reference ceilings. The reader now accepts validated lower remaining budgets (defaults unchanged), including zero for header-only data, and refuses extra row work or range expansion before processing it. Three red reconciliation controls reproduced cross-artifact budget overflow and incorrect eligible-empty scope; those now pass. Additional CSV controls verify malformed budgets and pre-expansion refusal. The corrected combined suite passed 80 tests including four real KiCad comparison controls. CSV reading still grants no reconciliation or engineering authority by itself; isolated publication/full/hosted verification remains required.

2026-09-07 native observation evidence follow-up to SEC-187: isolated KiCad source 6faa462f passed the real-frame eight-case/57-assertion suite and legacy 40-case/2,106-assertion suite, both exit zero and without warning/error/failure lines. Active native commits refuse observation for all tested clients; dropping an empty commit restores the same session and content. Main corrected exception-safe test cleanup before independent acceptance and native compilation. Runtime used the pinned image with no network/host mounts, read-only source/build state and private temporary settings. Initial Mac ownership-transfer and wrong-binary-path preparation failures remain separate non-evidence logs. The native prototype note records source/binary/GPL-patch hashes and explicit limitations. This establishes local observation/refusal/recovery only, not strict mutation, full project binding, IPC-disabled builds, physical validation, genuine consent, upstream submission, installation or release.

2026-09-07 native inventory publication closure of SEC-201: corrected PR281/355013d passed final-source make check (5,107 tests, one intentional skip, 89% coverage), all 73 focused component tests on each supported interpreter including four real native controls, and hosted CI34078910350 in 19m08s. Protected squash main a4ee8d5 has the identical tree; main CI34080029815 passed in 19m15s with Security/CodeQL/OpenSSF green. The addressed deadline review was resolved after correction, independent acceptance and full validation; the source branch was restored. This closes native inventory publication, not BOM/model verification, physics, strict application, human acceptance or the five-area goal.

2026-09-07 CSV publication preparation for SEC-202: isolated source at4024e80 passed full make check (5,159 tests, one intentional skip, 89% coverage) in 453.55s of pytest. Source/input fingerprint sha256:53681416caaa10aef1ec2c3bd526c9d2e03492b8d3beb3b13b4a94aee0ed01d0 remains unchanged after documentation-only corrections and verified-main synchronization; production and test bytes were not changed by that synchronization. All published ledger entries are retained. The source-location documentation finding was corrected and independently accepted. Final metadata/package checks and exact-head hosted gates remain required; no actual reconciler or additional native execution authority is included in the CSV reader.

2026-09-07 PR282 field-limit follow-up to SEC-202: hosted review found that ambient csv.field_size_limit could reject valid fields. Three red controls reproduced failures at shared limits 0, 1 and 10. A private per-call multi-phase stdlib CSV module now owns its limit/exception state, with explicit dialect and a fixed parsing ceiling; the shared module registry, limit and dialect remain unchanged. Mid-parse state changes, dialect isolation, unsupported/shared/failed module initialization and deadline controls are included. All 63 parser tests pass on each supported interpreter; Ruff and strict mypy pass. Exact source/runtime probing confirmed private state on CPython 3.11–3.13. Re-review and fresh full/hosted gates are required for the changed source; earlier 5,159-test results do not certify this correction. BOM/model/physics/application authority remains absent.

2026-09-07 reconciliation review follow-up to SEC-202: complete row/native agreement now binds the full fresh execution receipt, with failures preceding empty eligible scope and cumulative row/reference ceilings across all artifacts. Review-driven controls reproduced per-file budget resets and an incorrect scope reason before correction. A separate Ponytail audit found no justified cuts. The initial combined selection passed 80 tests including four real native controls; the alternate-interpreter selection passed 76 with those four intentionally unconfigured. Later red controls reproduced continued native-receipt and final-report encoding after shared-deadline expiry. Deadline-aware private digest methods preserve both canonical namespaces and retain final artifact/source freshness checks after hashing. Independent correctness review accepted that three-file correction; focused report tests passed 27 with four native controls unconfigured, and strict mypy passed. Final-source real, compatibility, full and protected hosted gates remain required. Model definitions, ratings, physics and application authority remain explicitly unassessed.

2026-09-07 CSV publication closure of SEC-202: corrected PR282/9a5ace8 passed fresh full make check (5,170 tests, one intentional skip, 89% coverage), all 63 parser tests on each supported interpreter, independent correctness/Ponytail review and hosted CI34083897201 in 18m59s. Protected main ffeb80b has the identical tree and passed main CI34085110732 in 19m13s, with Security/CodeQL/OpenSSF green. The field-limit review was resolved after correction, full validation and push; the source branch was restored. This closes the CSV reader's publication gate, not native BOM agreement, model validity, physics, strict apply or release readiness.

2026-09-07 actual reconciliation publication preparation for SEC-202: the CSV correction was propagated into the composed BOM path. Clean 4a9590a passed fresh full make check (5,201 tests, one intentional skip, 89% coverage) in 536.72s of pytest. Source/input fingerprint sha256:a507ba490513874bbb42c04b878c28cde07fc4b41997b4207be7b9ffde49ce14 remains unchanged after verified-main synchronization; the deadline-aware native receipt helper and all other production/test bytes are identical to that tested source. Published ledger history is retained as a complete prefix. Final metadata/package checks, publication isolation review and exact-head hosted gates remain required. No pin-census, model/physics, human approval or application authority is included in this milestone.

2026-09-07 PR283 empty-scope follow-up to SEC-202: review found that two minimum-cardinality guards made the intended no-disagreement empty-scope outcome unreachable. Four red controls reproduced the premature declaration refusal. Matching empty declaration/binding sets are now admitted while the items field remains required, maximum counts stay bounded, and each nonempty item still requires references. Missing eligible components, contradictory/unbound rows and unequal sets retain failure/refusal behavior. The corrected 103-test selection includes six real native controls; the new header-only cases distinguish all-excluded native components (inconclusive) from missing eligible components (fail). Independent source review accepted the two-line correction; cross-version, final-source full and corrected hosted checks remain required. Earlier 5,201-test evidence does not certify this changed source, and no model/physics/apply authority is added.

| SEC-203 | 2026-09-07 | Pin-source interpreter publication | Extract the complete internal source interpreter while retaining shared work/deadline accounting, validated path indexing, raw all-unit pin correspondence and source-only fixtures/tests. The existing preparation gate remains responsible for capture/hierarchy/flat-library equivalence. Main compared moved definitions with the integrated baseline; two intentional internal refinements remove a duplicated path field and strengthen lookup regression coverage. | Source-only slice: no complete project census, public census digest, native execution, model validity, physics or apply authority. All assembly and native proof increments remain mandatory; isolated final-source/full/hosted gates are required. | D-271, R-208; ADR-0146 |

2026-09-07 BOM publication closure of SEC-202: corrected PR283/0ec4dc2 passed fresh full make check (5,210 tests, one intentional skip, 89% coverage), all 103 focused tests including six native cases on each supported interpreter, independent review and hosted CI34091177508 in 19m23s. Protected squash main 011fc78 has the identical tree and passed main CI34092700640 in 18m47s, with Security/CodeQL/OpenSSF green. The empty-scope review was resolved after correction, full validation and push; the source branch was restored. This closes the limited BOM/native metadata agreement milestone, not model/physics, strict live mutation, human acceptance or release readiness.

2026-09-07 source-slice preparation for SEC-203: the isolated ffeb80b-based 5f07f4f source slice passed 5,185 tests, one intentional skip, 89% coverage and all 15 direct cases on Python 3.11–3.13. Verified-main synchronization added the independently validated BOM implementation, so a fresh combined-source full run is required rather than reusing that earlier count. All source-interpreter production/test bytes remain unchanged from the reviewed composition; published ledger history is retained. Project assembly and all native proof remain mandatory later publication slices.

2026-09-07 PR284 immutability follow-up to SEC-203: hosted review found that a frozen parsed template still exposed a mutable instance dictionary. Three red controls reproduced addition, deletion and replacement of captured path records. Return a standard-library read-only mapping over a parser-local dictionary whose values remain frozen; retain indexed lookup, duplicate checks, shared accounting and deadlines. A copied index can be changed without affecting the parsed source, and frozen instance values reject reassignment. Independent review, cross-version, fresh source-bound full validation and corrected hosted checks are required; earlier 5,225-test evidence does not certify this changed source. No project/native/model/physics/application authority is added.

2026-09-07 project-assembly preparation for SEC-203: add the complete assembler and immutable self-binding records above the unchanged source interpreter, retaining the existing preparation verifier, single budget/deadline, full-path instance index and all 29 original unit cases plus the two integration checks. Reusable capture fixtures are added only where now consumed. The validated complete composition remains preserved in pin-census-split; this publication omits only the separately mandatory native-proof test slice, not production behavior. Isolated validation and protected gates remain required before publication. No native connectivity, model, physics, approval or apply authority is added.

2026-09-07 PR285 selector follow-up to SEC-203: hosted review identified that independent unit and body-style membership checks could admit an undeclared combination and emit only common pins. Two red controls reproduced crossed selections against distinct unit/style bodies. Preserve immutable actual selector pairs and require a joint match or that unit's common-style body before assembling an occurrence. Only a library with no specific unit bodies receives the implicit first-unit interpretation; common pins do not synthesize missing combinations for declared units. Positive controls retain common styles, common-only symbols and explicitly declared graphical bodies. Existing 5,260-test and successful CI 34101187455 results belong to the earlier source; independent review and fresh exact-source validation are required before resolving the finding or merging. No model, physics or application authority is added.

2026-09-07 PR285 corrected selector validation for SEC-203: independent correctness/security review accepted the scoped fix; separate Ponytail review found no justified cuts. All 63 composed source/assembler/native controls passed on Python 3.11, 3.12 and 3.13. Fresh full make check passed 5,265 tests, one intentional skip, 89% coverage and all lint/type/security/build gates in 540.77 seconds of pytest. Source/input fingerprint: sha256:8665c6227796864d177d2902cc01e9039d3af54f400c37dd3f3bdce96bef71a9. The immutable pair metadata preserves constant-time occurrence checks and canonical output encoding for admitted inputs. The fix was propagated into the unpublished native-proof and model branches; their full integration validations remain separate. Corrected exact-head hosted gates are still required before merge, with no engineering or application authority added.

2026-09-07 native-proof publication preparation for SEC-203: add the complete eight-case proof file without production changes, preserving the reviewed comparison-negative and repeated real native cases from the full composition. Exact multiplicity, duplicate-key refusal, declared metadata, effective native name/type, clean diagnostics and state/source freshness remain asserted. Documentation limits the evidence to these controlled examples; arbitrary census results still have native/model/engineering validation not run and no apply authority. Isolation, configured native execution, full integration and protected hosted gates remain required before publication.

2026-09-07 PR286 shared-sheet follow-up to SEC-203: hosted review identified that the required populated shared-leaf native control was absent; the prior RC fixture repeated only empty sheets. Add one populated child source reached through two sheet UUID paths, with occurrence-specific R1/R2 references overriding a stale display value. Assert the shared source symbol/pin UUIDs, both complete occurrence paths, all four census pins, and two exact native library/node comparisons under existing diagnostics/freshness gates. The direct configured native case passed; independent review, full-suite and supported-interpreter validation remain required before resolving the finding or merging. The earlier eight-case/full-run evidence is historical and does not certify this addition. No production, model, physics or application authority is added.

2026-09-07 PR286 source-pairing review refinement: independent review found that separate UUID sets did not detect swapped pin UUIDs or a three-to-one distribution across occurrences. The shared case now checks the exact four full-path/reference/pin-number/source-symbol-UUID/source-pin-UUID tuples with multiplicity. Two negative controls preserve the former sets while corrupting those pairings and require refusal. The running preliminary full check predates this refinement and cannot certify the final assertions; fresh validation remains required.

2026-09-07 PR286 final shared-leaf validation: independent review accepted the exact four occurrence/pin/UUID bindings and both provenance-negative controls; separate Ponytail review found no justified cuts. All 66 source/assembler/native controls passed on Python 3.12 (35.13 seconds), 3.11 (33.02 seconds) and 3.13 (33.01 seconds). A fresh final-assertion make check passed 5,276 tests, one intentional skip, 89% coverage and all lint/type/security/build gates in 484.96 seconds of pytest. Source/input fingerprint remained sha256:8665c6227796864d177d2902cc01e9039d3af54f400c37dd3f3bdce96bef71a9; unchanged production bytes do not substitute for the fresh test run. Corrected exact-head hosted gates remain required before merge. No simulation, physical calibration or application authority is added.

| SEC-204 | 2026-09-07 | Captured SPICE definition boundary | Model bytes are untrusted data. Threats include hidden commands/includes, ambiguous name and terminal resolution, mutable retained records, private error disclosure and recursive or excessive expanded work. The first fixed profile permits only local diode/passive definitions and bounded dependency checks; it never opens files or executes models. | Implementation, independent review and exact-source validation remain pending. Complete project/model binding and confined native execution are separate mandatory work, not implied by parsing; no physics, approval or apply authority. | D-272, R-209; ADR-0147 |

2026-09-07 SEC-204 reader validation: primary red controls exposed retained private exception context, per-definition rather than cumulative source limits, and empty-subcircuit expansion accounting. The corrected reader validates permitted bytes directly, carries remaining element capacity into each definition before examining another element, counts subcircuit invocation work, bounds finite numeric tokens and rechecks the deadline before delivery. Independent correctness/security review accepted the final implementation; separate Ponytail review found no justified cuts. All 59 focused controls passed on Python 3.11, 3.12 and 3.13, including six repeated real KiCad diode/subcircuit export cases with explicit normal/reversed pin mappings and header order. Fresh full make check passed 5,327 tests, one intentional skip, 89% coverage and lint/type/security/package gates in 542.01 seconds of pytest. The source/input fingerprint was sha256:cf1f2be03a9e57409f86d2aa8a92a1006112b20ee91fccbd96251e17dd00e4c8; source and tests remained unchanged through validation. This closes the reader's local validation checkpoint only: complete project/model associations, confined ngspice execution, physical calibration and protected hosted publication remain outstanding. No engineering or application authority is added.

2026-09-07 SEC-204 final-byte follow-up: the enabled commit formatter reflowed one source condition and two test signatures, preserving their exact ASTs but changing the source fingerprint. Rather than certifying the earlier bytes, a fresh four-worker full make check passed 5,327 tests, one intentional skip, 89% coverage and all type/security/package gates in 426.98 seconds of pytest. All 735 Python files also passed the explicit format check. Final source/input fingerprint: sha256:d2a567807112cdd1b373df43ea70453e14653a52a32199dd044973d19e5d8977. The all-interpreter 59-case runs above used the AST-identical pre-reflow source; they are not claimed as separate post-reflow runs. Documentation-only evidence additions were checked afterward. Hosted publication and the complete model-binding/simulation/physics boundaries remain open.

| SEC-205 | 2026-09-07 | Pin-net source-admission publication | Extract the reviewed source-census admission and direct controls from the preserved complete mapper. Admit all hashed fields before conversion/scanning, retain exact source identities and alias groups, and share fixed error/deadline primitives without future-consumer imports. | This slice does not authenticate captured bytes or provide native XML mapping, execution, model validity or apply authority. All XML-mapping and native-executor stages remain mandatory. Fresh isolated/composed validation and protected hosted gates are required. | D-273, R-210; ADR-0148 |

2026-09-07 SEC-205 source-slice validation: independent review accepted byte-identical admission code/fixtures/assertions, absent future consumers, retained parent ledger prefixes and explicit source-only claims. All 73 direct cases passed on Python 3.11, 3.12 and 3.13; an additional run passed with both XML mapper and native executor imports actively blocked. Fresh full make check passed 5,408 tests, one intentional skip, 89% code coverage and all lint/type/security/build gates in 513.81 seconds of pytest. Source/input fingerprint: sha256:1562e917ec76ca5bea53fa5c179ea7834ff3a10bd73bb1d55ed654ea36227d00. The separately preserved complete extracted composition passed 5,455 tests; that does not substitute for this isolated run. Protected hosted gates and all later XML/executor stages remain required, with no engineering or application authority added.

2026-09-07 PR288 source-boundary follow-up to SEC-205: hosted review found that distinct pin UUIDs could conceal duplicate pin numbers within the same source occurrence, and generated group representations exposed private metadata. Red controls reproduced physical/virtual duplicate records reaching hashing and source-group representation leakage. Add the occurrence-plus-pin-number identity check before virtual exclusion/hashing, and fixed redacted group/context representations. A positive control retains distinct pin numbers in one occurrence and existing multi-unit alias controls remain. All 77 direct source cases pass; independent review, fresh source-bound full validation and corrected hosted checks remain required. Earlier 5,408-test evidence belongs to the pre-correction source and is not certification of these changes.

2026-09-07 PR288 corrected validation for SEC-205: independent review accepted both fixes, preserved legitimate source aliases and constant-time identity checks, and confirmed fixed group/context representations; separate Ponytail review found no justified cuts. All 77 source cases passed on Python 3.11–3.13 and all 124 corrected composed/native cases passed on Python 3.12 (34.96 seconds), 3.11 (37.36 seconds) and 3.13 (38.50 seconds). Fresh source-slice make check passed 5,412 tests, one intentional skip, 89% code coverage and all lint/type/security/build gates in 536.04 seconds of pytest. Source/input fingerprint: sha256:e6139884fddddf8e85bdc36e309fdb574c87a25c9b2229ce7976206c574ef1bd. Downstream slices received the same correction and require refreshed full validation. New exact-head hosted checks remain required before merge; no model, physics or application authority is added.

2026-09-07 SEC-205 XML-slice preparation: add the complete reviewed XML mapping, immutable record identity and all 33 XML/mixed/extraction controls above the unchanged source-admission slice. Direct alias/error re-exports preserve class identity; no native executor or execution claim is included. The complete final executor and all 14 of its controls remain mandatory. Isolated validation, independent review and protected hosted gates are required before publication; supplied XML alone is not native, model, physics or application authority.

2026-09-07 SEC-205 XML-slice validation: independent review accepted unchanged mapper/tests and source dependencies, direct canonical re-exports, complete parent ledger prefixes and supplied-XML scope. All 106 source/XML cases passed on Python 3.12 (0.96 seconds), 3.11 (0.35 seconds) and 3.13 (0.94 seconds). Fresh isolated make check passed 5,441 tests, one intentional skip, 90% code coverage and all lint/type/security/build gates in 516.08 seconds of pytest. Source/input fingerprint: sha256:135e5f58daf6f2757fe8ac72e4e7f9d4ea7346a030aca2a441e6cac1e3f5d995. The executor and its real native controls remain the mandatory final stage; protected hosted gates are required before publication. Code coverage is not engineering readiness or application authority.

2026-09-07 SEC-205 corrected XML integration: include both reviewed PR288 source guards and retain the complete parent ledger prefix. The XML mapper and its tests remain unchanged; 110 source/XML controls and the 124-case corrected native composition passed. Fresh isolated make check on cd22d8c passed 5,445 tests, one intentional skip, 90% code coverage and all lint/type/security/build gates in 562.98 seconds of pytest. Source/input fingerprint: sha256:c94b9c41826a5b8fdffb4bd68a3e16f73f6ff09a3261c183b50032110db9b746. This supersedes the earlier pre-correction full result for integration purposes. Protected hosted validation and the complete native-executor stage remain required; no model, physics or application authority is added.

2026-09-07 SEC-205 executor-slice preparation: add the unchanged reviewed executor and all 14 executor tests above the isolated source/XML parents. The operation derives the census internally, uses fixed authenticated native context/commands, checks two complete observations, hashes the final immutable report and rechecks live source bytes before delivery. The redundant earlier report hash remains removed per Ponytail review. Isolation, native/cross-version/full validation, independent integration review and protected hosted gates remain required. No circuit-function, model, physics, approval or application authority is added.

2026-09-07 SEC-205 corrected executor validation: independent integration review accepted the unchanged executor/tests, corrected source guards and complete parent ledger history. All 124 corrected source/XML/executor cases passed on Python 3.12 (34.96 seconds), 3.11 (37.36 seconds) and 3.13 (38.50 seconds), including real KiCad alias/conflict/no-connect observations. Fresh full make check on 47bd6ca passed 5,459 tests, one intentional skip, 90% code coverage and all lint/type/security/build gates in 567.03 seconds of pytest. Source/input fingerprint: sha256:eef9c93b019926e5d00c354ede02a445fc4f33a3ac8829fd47c52b26c81e94a1. The pre-correction executor run remains historical. Final protected publication gates still apply; the map observes captured native pin/net relationships and grants no model, physics or application authority.

| SEC-206 | 2026-09-07 | Pure SPICE terminal-join publication | Closed bounded declaration, actual model-byte parsing, complete sets and retained aliases; numeric ports preserve source spelling and selected-definition hashing uses the caller deadline. | Independent safety and separate Ponytail review accepted the corrected logic in the complete implementation. Isolated/composed validation and later internally derived native evidence remain required. No source-settings, simulator, physics or apply authority. | D-274, R-211; ADR-0149 |

2026-09-07 SEC-206 isolation review accepted the exact corrected helper/tests, all 25 core cases, absent future runner/imports and complete parent ledger prefixes. The core cases passed on Python 3.12 with the future runner import actively blocked (0.26s), 3.11 (0.35s) and 3.13 (0.37s). The preserved complete composition passed 5,500 tests; fresh isolated full validation remains required for this smaller source population. No native collection or physical authority is implied.

2026-09-07 SEC-206 isolated pure-join validation: fresh make check passed 5,484 tests, one intentional skip, 90% code coverage and all format/lint/type/security/build gates, with 629.22 seconds of pytest using three workers and configured real parent backends. Tested staged tree 5bcd0b381e3bccebf839ff9da6164a1f1863340f; source/input fingerprint sha256:9863b0cd0fd963601d2d74277a7b1b6289aa61d9659820dd83a2f4ce301de109. Independent isolation review and all 25 core cases on Python 3.11–3.13 passed. Protected hosted gates and the complete internal-capture/native-runner slice remain required; no physics or apply pass.

2026-09-08 SEC-206 PR291 inventory-link correction: hosted review identified cross-inventory mixing despite matching project IDs and references. A red control reproduced acceptance after changing only the pin map's component identity. Retain the exact inventory from the existing BOM call after its final checks; preserve the report-only public API and recorded v1 digest bytes. The join verifies both full-receipt and normalized component links under the active deadline, plus common capture/execution/syntax/executable/authentication context. Direct comparison of the two differently namespaced digests would reject valid inputs and is not used. Golden-digest and one-native-call controls pass. The adapted full family passed 92 cases including real KiCad observations; independent correctness/security review accepted the bridge and found no justified Ponytail cuts. Fresh full and exact-head hosted validation remain required; earlier full results are pre-correction evidence, not proof for this change.

2026-09-08 SEC-206 corrected PR291 full validation: make check passed 5,495 tests, one intentional skip, 90% code coverage and all format/lint/type/security/build gates, with 624.76 seconds of pytest using three workers and configured real parent backends. Tested staged tree 305e0706f45b898cc7a729cffe119b4f80369352; source/input fingerprint sha256:dd526ea26a071dd8d5667b3e4c67ecf4aae7ddde92bfe16d5cfb0c2d99bf8c59. Independent bridge review and the 92-case real adapted family passed. Corrected exact-head hosted checks remain required. No v1 digest reinterpretation, extra native run or physics pass.

2026-09-07 SEC-206 runner publication preparation: add the unchanged internally owned artifact, BOM and native-pin orchestration plus its complete 16-case group, including three real KiCad controls. Hash before final source/model freshness; check every shared alias before conversion. Source and tests match the corrected complete integration at 2a7c090. All three independent review findings are closed; source-settings, SPICE-export, simulator and physics authority remain unassessed. Preserve the full pure-join ledger prefix. Publication evidence reuse must demonstrate matching source/input fingerprints, fresh metadata/build checks and independent integration review.

2026-09-08 SEC-206 runner inventory-link correction: retain the exact fresh BOM inventory and pass it into the corrected join. Verify both differently namespaced identity links and the common execution/backend context without another native run or changed v1 report fields/digest bytes. The adapted family passed 92 cases with real KiCad; Python 3.11 and 3.13 each passed 83 controls with nine native cases omitted. Independent review accepted the bridge and consumer. Earlier matching-fingerprint reuse is superseded by this code change; fresh full validation is required.

2026-09-08 SEC-206 corrected runner full validation: fresh make check passed 5,511 tests, one intentional skip, 90% code coverage and all format/lint/type/security/build gates, with 654.85 seconds of pytest using three workers and configured real KiCad/router backends. Tested staged tree69fd6d0eb6b80a9b6a38555a77911d92a0152d99; source/input fingerprint sha256:264f2a1caeedfe5b657198617ee495716781f2e5703d8b8bf1b1ec614de2ee6f. The independent bridge/consumer review and 92-case real family passed. This supersedes the pre-bridge 5,500-test composition for current consumer validation. Corrected parent synchronization, protected hosted gates and later source-settings/SPICE/simulator/physics work remain required.

| SEC-207 | 2026-09-08 | Native SPICE parser publication | Preserve the reviewed exact output matcher, ordered-port/name-collision checks, bounded framing/tokenization and deadline-safe result publication. | Supplied records are not authenticated. Confined source preparation, two internally executed exports, final freshness and all later simulator/physics/human gates remain mandatory. Isolation and full validation required. | D-275, R-212; ADR-0150 |

2026-09-08 SEC-207 parser isolation preparation: parser and all 34 tests are byte-identical to the accepted complete implementation. Python 3.12 passed with future-preparer/coordinator imports blocked (0.48s); Python 3.11 and 3.13 passed all 34 cases (0.48s/0.98s). Format, type and metadata checks pass. The complete composition passed 5,597 tests; fresh isolated full validation remains required for this smaller source population. No native, simulator, physics or apply authority added.

2026-09-08 SEC-207 isolated parser validation: independent isolation review accepted unchanged parser/test bytes, all 34 assertions/cases, absent future consumers and complete parent ledger prefixes. Fresh make check passed 5,545 tests, one intentional skip, 90% code coverage and all format/lint/type/security/build gates, with 550.31 seconds of pytest using three workers and configured real parent backends. Tested treef3760cf21120bdaf90dfbccc9759d0758c4e04df; source/input fingerprint sha256:43afc1497e2962a00387a474efee299d23b9d0c4a89d14a6606a18a5563d3017. Parent main verification and protected hosted gates remain required before publication; the complete source-preparation/native operation and later simulator/physics work are not replaced.

2026-09-08 SEC-207 edit-kernel preparation: copy the mechanically extracted kernel and its four direct tests without changing implementation bytes. Keep canonical error/check/edit identities, no future-facade/coordinator imports, bounded source inspection and pre-materialization sizing. All original preparer and native-operation assertions remain in later mandatory stages; these internal primitives do not authenticate records or promise public fixed-error conversion alone. Complete extracted validation, isolated kernel checks and independent review remain required.

2026-09-08 SEC-207 kernel isolation: independent review accepted unchanged kernel/test bytes, canonical definitions, existing-only imports, complete parent ledger prefix and explicitly internal scope. All four direct tests passed Python 3.12 with future imports blocked (0.25s), 3.11 (0.21s) and 3.13 (0.25s); format/type/metadata checks passed. The complete extracted composition passed 5,602 tests; fresh isolated full validation and protected publication remain.

2026-09-08 SEC-207 isolated kernel validation: fresh make check passed 5,549 tests, one intentional skip, 89% code coverage and all format/lint/type/security/build gates, with 574.10 seconds of pytest using three workers and configured real parent backends. Tested staged tree ac5fc7331ac10878ea8459b39c138c79e052f00d; source/input fingerprint sha256:edce55a219e7e1fcdfef68ae5c109f433d3bdde853be1718654ed03608972cdb. Independent isolation and preservation reviews passed. Parent main verification and protected publication remain required; this internal kernel does not replace the full preparation/export operation or grant engineering/application authority.

2026-09-08 SEC-207 complete-preparer publication preparation: copy the accepted facade and all 39 original preparer cases plus its reexport-identity control exactly from cdbadb5. Preserve the full kernel ledger prefix and existing parser/kernel behavior. Complete project/model admission, source alias checks and bounded derivative construction are supplied, not native execution or physics authority. The complete native coordinator and all real controls remain mandatory later. Fresh isolated validation and independent integration review precede protected publication.

2026-09-08 SEC-207 preparer isolation checks: all 44 preparer/kernel cases passed on Python 3.12 with the future exporter import blocked (0.99s), 3.11 (1.43s) and 3.13 (1.45s). Facade and original test bytes match the accepted complete extraction. Fresh isolated full validation remains required; the full native exporter and its original real controls are not omitted from the program or replaced by this source-only operation.

2026-09-08 SEC-207 isolated preparer validation: independent review accepted exact facade/test bytes, canonical kernel identities, complete parent ledger prefix and scope. Fresh make check passed 5,589 tests, one intentional skip, 90% code coverage and all format/lint/type/security/build gates, with 583.08 seconds of pytest using three workers and configured real parent backends. Tested treebfbd453f1042731d579459298a486b1ffc8acdeb; source/input fingerprint sha256:85ca8259777ce5d6b36de8503bd93603c1700f1969805a630045bccc5f9c45b0. Protected parent/hosted validation and the complete native export operation remain required. No model accuracy, simulator, physics, human approval or apply authority follows from preparation.

2026-09-08 SEC-207 hosted review reopened the preparer gate: PR295 at13edfb87 passed its 13m01s CI run34150551513, but review identified swapped source-symbol aliases that could target the wrong component and unbounded artifact identifiers hashed before admission. Do not merge this head. Remediation must verify captured instance/reference identity without breaking hierarchical overrides, bound nested records before hashing/sorting, retain all original controls and obtain fresh integration validation. The earlier green local/hosted results remain historical evidence, not a waiver of these findings or validation of a fix.

2026-09-08 SEC-207 remediation preparation: reproduced the swapped-alias and early-admission failures before changing production code (six failing controls and one positive control). The fix reuses the bounded source census for effective instance references and admits nested binding fields before model selection or hashing. All original preparer/kernel cases remain; 52 focused tests now pass on Python 3.11, 3.12 and 3.13. Kernel bytes are unchanged. Formatting, lint and type checks pass. Source-only census preparation is repeated under the same deadline; no additional native execution is introduced. Independent review, fresh full validation and updated exact-head hosted checks remain required before resolving the review and merging.

2026-09-08 SEC-207 follow-up review found two remaining early-admission gaps: captured artifact identifiers still reached dictionary hashing, and a definition guard trusted an overridable class attribute. Both were reproduced with failing regressions. The in-flight full run was deliberately interrupted because its source was known to require correction; its 5,340 partial passes and exit2/KeyboardInterrupt are not successful evidence. The corrected code uses an inline exact type check and the same bounded identifier admission for binding and captured records. Captured role/digest fields also refuse callback-bearing subtypes. All 56 focused tests pass on Python 3.11, 3.12 and 3.13; format, lint and targeted mypy pass. Independent delta review and a fresh full run must validate this new source before publication.

2026-09-08 SEC-207 delta review accepted both follow-up corrections: exact definition type checking precedes field access, and shared identifier admission precedes captured/binding hashing. Hostile captured role/digest fields also refuse before callbacks. No supported-input semantic regression was found in the scoped recheck. Separate Ponytail review accepted removal of the single-use spoofable wrapper and found no further justified cut. Fresh full validation and exact-head hosted checks remain required.

2026-09-08 SEC-207 corrected preparer full validation: fresh make check passed 5,601 tests, one intentional skip, 90% code coverage and all format/lint/type/security/build gates in 567.49 seconds of pytest using three workers and configured real parent backends. Tested staged tree6ccef729aa6b1547472b4c711da09512f88bf746; source/input fingerprint sha256:fd69298e8c0972fd2e1a090f0a7f19918add1cc9cea266db9b6503ef6d637748. Independent review accepted the semantic alias correction and both final admission fixes; 56 focused controls passed every supported interpreter. This successful run supersedes the interrupted correction attempt for final-source validation. Updated exact-head hosted checks, protected merge and resulting main verification remain required; no execution/physics/apply authority or five-area completion follows from source preparation.

2026-09-08 SEC-207 whole-export publication preparation: restore the unchanged coordinator, all 12 coordinator cases and the original native preparation/export control above the accepted parser/kernel/preparer. The source/input fingerprint matches the complete extracted validation; all source/tests/config/scripts must remain identical for evidence reuse. Fresh metadata/build checks, targeted real controls and independent integration review remain required. No simulator, physics, human approval or application authority is asserted by native export agreement.

2026-09-08 SEC-207 whole-export validation reuse: independent review confirmed all tracked non-documentation files are identical to cdbadb5 and the complete preparer ledger prefix is preserved. Source/input fingerprint remains sha256:43fe479e47cb5edd8e910298c97dcc487cb11b1c2e26e926526416aa83e140d7, matching the 5,602-test complete extracted run. Fresh format/lint/type/security/build checks passed, and all 91 focused cases passed with configured real KiCad in 118.12 seconds. Reusing that full result is justified for identical source; no new full run is claimed. Protected parent/hosted gates and later simulator/physics work remain required before broader capability claims.

2026-09-08 SEC-207 corrected-parent integration: carry the reviewed preparer correction from ef8443d into the whole native exporter without changing coordinator or native-control bytes. Retain the complete corrected parent ledger prefix. Earlier whole-export full-suite reuse is superseded because source admission and its tests changed. Fresh composed validation, targeted real native controls and independent integration review are required before publication.

2026-09-08 SEC-207 corrected native integration checks: independent review accepted exact preparer/test bytes from ef8443d, unchanged coordinator/native controls and the complete parent ledger prefix. All 103 focused cases passed with configured real KiCad in 123.08 seconds; format/lint/type checks passed. A fresh full composed run remains required; previous complete suite reuse is not final validation of this corrected source.

2026-09-08 SEC-207 corrected whole-export full validation: fresh make check on1fda2c0 passed 5,614 tests, one intentional skip, 90% code coverage and every format/lint/type/security/ build gate, with 626.76 seconds of pytest and three workers using real parent backends. Tested tree412fb025c0e12ebacb9d4ed00b5439e1d1b6aa72; source/input fingerprint sha256:cae8e6fe03df7117523d67c6665ffd3ba75d2bc0f6ca0551a444e6fc445e1f16. The 103-case real native family and independent integration review also passed. This replaces the superseded pre-correction full reuse for current-source validation. Parent-main verification and protected publication remain required; native export is not simulation or physics authority.

| SEC-208 | 2026-09-08 | Private operating-point output boundary | Owned pinned ngspice 45.2 raw-output probe establishes the one-point format; implementation tests and independent review remain pending. | Treat all supplied bytes, counts, vector identities and numbers as untrusted. Enforce structural/time bounds and exact expected output; do not infer execution, convergence, calibration or apply authority from parsing. | ADR-0151 |

2026-09-08 SEC-208 validation: primary review caught and corrected a test fixture that did not match actual native formatting; the retained fixture now matches pinned 45.2 output. All 22 controls passed Python 3.11, 3.12 and 3.13. Two fresh owned native runs were parsed directly, with clean diagnostics, confirmed cleanup and identical semantic digest sha256:7e93a52d7b9eaf0614b868d2dc6f81fd149041d5de20fe260e34899231b153da. Independent correctness/security review accepted the scoped interpreter; separate Ponytail review found no justified cuts. Fresh make check passed 5,624 tests, one intentional skip, 90% code coverage and all format/lint/type/security/build gates in 624.49 seconds of pytest with three workers and configured real parent backends. Tested staged tree 12c0fcb396f57d5e8baff99b7dbbd64c815fdd29; source/input fingerprint sha256:d23a140a31e4a1b400973c110335810392f196a09c0af86d462803e95103d7d1. This verifies supplied-output interpretation only. Production execution, convergence, case/net binding, calibration, physics, human approval and apply remain separate gates.

2026-09-08 SEC-208 corrected-parent integration: preserve the unchanged operating-point interpreter and all 22 controls while carrying the corrected preparer/native-export parent. Retain its complete ledger prefix. Earlier full validation describes the pre-correction source; fresh composed validation and independent integration review are required before publication.

2026-09-08 SEC-208 integration review accepted unchanged raw parser/test bytes from2cac36d, exact corrected parent source/native controls from1fda2c0 and its complete ledger prefix. The 120 non-native family controls passed on Python3.12 (2.21s),3.11 (1.58s) and3.13 (1.66s), with five real cases explicitly deselected. The parent separately passed103 cases with real KiCad. Format/lint/type checks passed. A fresh full composed run remains required.

2026-09-08 SEC-208 corrected composed full validation: fresh make check onac1be5c passed 5,636 tests, one intentional skip, 90% code coverage and all format/lint/type/security/build gates, with 624.64 seconds of pytest using three workers and configured real parent backends. Tested treea403267c00e9f8af86522144a500964da9183d24; source/input fingerprint sha256:f4caabf85a31e22f465ad052a1d9aa15b559132592a8e080073c4506dfb8029b. The independent integration review and 120-case compatibility family passed. This replaces pre-correction full evidence for the current source. Parent-main verification and protected publication remain required; simulated numbers still grant no convergence/physics/apply authority.

2026-09-08 SEC-208 hosted review reopened PR297 despite green CI: record ADR0151 in the canonical decision ledger, reject non-byte payloads before length callbacks, and preserve finite subnormal values instead of applying an absolute exponent cutoff. D276 now records the decision. The parser fixes and regressions retain all original controls; 25 focused tests pass Python3.11,3.12 and3.13 with format/lint/type checks. Independent review and a fresh full run must precede updated publication; earlier full evidence does not cover this correction.

2026-09-08 SEC-208 corrected parser validation: independent review accepted exact-byte admission before callbacks, finite subnormal preservation, and D276's canonical ADR link. Separate Ponytail review accepted removal of the redundant exponent cutoff. Fresh make check passed 5,639 tests, one intentional skip, 90% code coverage and every format/lint/type/security/ build gate, with 817.79 seconds of pytest on three workers. Tested staged tree 57becfecb500b10226175bd0b24d25d48fe39c9b; source/input fingerprint sha256:0b4cdddebeec7e14073ef28536aaf9c6a10f5f8b12d20cb0bf1c7aab6952e220. All25 focused tests passed Python3.11,3.12 and3.13. This supersedes the pre-correction full result for publication; exact-head hosted checks and main verification remain required. No execution, convergence, calibration, physics or apply authority follows from parsing.

| SEC-209 | 2026-09-08 | Joint component/pin native acquisition | Each of two bounded native XML payloads passes both existing parsers; semantic agreement, component cross-binding, exact v1 identities, per-export verification, context authentication and final freshness remain. | Independent review accepted the implementation after restoring cheap BOM admission before native work. No cached authentication, larger budget, caller-selected authority or partial pair is introduced. | ADR-0152, D-277 |

2026-09-08 SEC-209 isolation: all six source/test files match the reviewed complete checkpoint d5b514b. Original assertions/public signatures remain, with no future simulator/runtime imports. Independent isolation review accepted; Ponytail found no additional cuts beyond removing two redundant final hashes already performed by the report hashes. Isolated62 non-real tests passed with ten explicit real-case deselections, the real report/digest-equivalence control passed in 33.19s, and metadata/type/security/build checks passed before adding these publication records. Exact-tip checks, fresh complete integration evidence and protected hosted/main gates remain.

2026-09-08 SEC-209 complete integration evidence: the full optimized development checkpoint d5b514b passed5,736 tests, one intentional skip and every make-check gate in815.09s of pytest, including the repeated/asymmetric real simulator controls. Its source/input fingerprint is sha256:c148ba7929b5a73f3151ccb40ab4787c1116a861ef48d13b4a3504897f7acf07. That evidence belongs to the complete checkpoint, not this smaller isolated publication tip. Fresh isolated validation and protected hosted/main checks remain required.

2026-09-08 SEC-209 isolated full validation: fresh make check passed5,654 tests, one intentional skip,90% code coverage and every format/lint/type/security/build gate, with 645.28 seconds of pytest using three workers and configured real parent backends. Tested staged tree4933bb8a889346a0d4d4f44c660e2c101932f3bb; source/input fingerprint sha256:ae4fe296384511f45dddcbfdbab91ee4a90683a49c346bb8604e691006241d35. The isolated62-test selection passed all supported interpreters, and real v1 report/digest equivalence passed. Independent implementation, admission-order correction, isolation and publication-record reviews accepted. Protected exact-head hosted checks and resulting main verification remain required; no physics, approval, application or whole-goal authority follows.

| SEC-210 | 2026-09-08 | Mechanical shared container-process extraction | Original declarations and process methods are preserved by AST comparison; router constructor signature and public compatibility aliases remain. | No new execution profile, request selection, cleanup behavior or authority is introduced. Cleanup corrections and simulator execution remain separately reviewed stages. | Primary comparison and independent review |

2026-09-08 SEC-210 focused validation: all17 original local router controls pass on Python3.11, 3.12 and3.13. The two original real FreeRouting/SimpleRouteJson smokes passed in7.27s. Strict mypy passes163 source files. Independent review confirmed unchanged original tests, direct compatibility aliases, no circular/future-simulator dependency and no behavior fixes mixed into the extraction. Separate Ponytail review found no justified cuts. Exact-tip hosted validation, parent-main verification and the complete simulator program remain required.

2026-09-08 SEC-210 parent synchronization: process code and original router tests remain identical to6406d67; all six joint-acquisition files match1738756. The complete parent ledger prefix is preserved, and the mechanical stage's provisional entry is SEC210 to avoid the joint publication's SEC209. Independent integration review accepted these identities and scope. The79 combined non-effectful controls passed Python3.12,3.11 and3.13, with twelve real cases explicitly deselected in that selection. Metadata/type checks pass. Parent-main and exact-tip publication gates remain; no future cleanup/executor behavior is included here.

2026-09-08 SEC-210 complete validation: make check passed5,654 tests, one intentional skip and90% code coverage, with634.47 seconds of pytest on three workers. Every format, lint, type, security and build gate passed. Tested commit19ae88db7099d5741af591d34fa7ac005d38f1c3; tree d3e0ceee8aa9ae612bb51b7257470be73ec12e81; source/input fingerprint sha256:d5167b041dcedb678279549387b30f0b0d6936e1c3351a44413b4d44145c321b. PR298's merge be772770703c26e9f3e34c4cbf2321d455e1c9b6 has the exact reviewed joint-acquisition tree and introduces no new content in this stage's parent synchronization. Its main checks and this stage's protected publication remain separate gates. No simulator, cleanup fix, engineering verdict or application authority is introduced by this extraction.

| SEC-211 | 2026-09-08 | Fixed-image ngspice executor and cleanup | Fixed image/version/driver identity; exact byte/frame ceilings; default denial for malformed, nonzero, stderr, cancelled, expired and cleanup-failed runs; read-only no-network non-root confinement; forced removal and confirmed reap. | Raw designs, models and logs remain private and uncommitted. This isolated control neither binds cases/source nor proves convergence, model accuracy, physics, engineering, approval or apply authority. Full-suite, protected-hosted and main verification remain required. | ADR-0153, D-278 |

2026-09-08 SEC-211 isolated validation: the39 focused container/probe/executor controls passed with two existing skips and one worker on Python3.11 in1.01s, Python3.12 in0.99s and Python3.13 in1.11s wall time. Format, Ruff, strict source typecheck and build passed. Full-suite, real-native, protected-hosted and main verification remain required.

2026-09-08 SEC-211 final-delivery correction: independent review found that cancellation during frame decoding or successful workspace cleanup was not polled before result delivery. Four regressions failed before the fix: late cancellation, callback failure, deadline expiry inside the final callback, and cancellation during cleanup. The executor now polls after cleanup and checks its deadline afterward. All43 focused controls passed on Python3.11,3.12 and3.13, with two real-router cases skipped in that selection; format, Ruff and strict type checks passed. Fresh actual execution of119-byte and300119-byte owned divider inputs produced identical operating-point digests with confirmed cleanup in1.424 seconds. Both real router smokes passed in5.15 seconds. Source/input fingerprint: sha256:d104e8b006b7fc385cd89e2929e327fa827d9d3fd2dfc4f22caa6a4e68ce47e3. These observations do not establish physics or full-suite completion. Corrected-source review, full validation and protected publication/main verification remain required.

2026-09-08 SEC-211 corrected full validation: independent review closed the final-cancellation finding. Fresh make check passed5,680 tests, one intentional skip and90% code coverage, with 647.44 seconds of pytest on three workers. All format, lint, type, security and build gates passed. Tested staged tree414109f2e17dca0ac5365d871c0d5ce57bdb1716; source/input fingerprint sha256:d104e8b006b7fc385cd89e2929e327fa827d9d3fd2dfc4f22caa6a4e68ce47e3. This source includes the four late-stop regressions and supersedes pre-correction validation for this isolated stage. Parent-history synchronization and protected hosted/main validation remain required before later publication. Complete project composition and all calibrated physics, engineering and application requirements remain separate; this executor grants none.

2026-09-08 SEC-211 hosted P1 correction: an exited leader could be reaped while a descendant held its pipe open, after which buffered stream closure could hang. Four real, externally guarded probe/cleanup regressions (same-group and escaped descendants) fail against the published source in32.19 seconds. The correction uses unbuffered nonblocking selectors, retains leader identity until pipe completion or abort, signals the owned group before reaping, and closes local pipes without I/O workers. Already-reaped handles do not signal stale groups. Exchange/removal exception paths also clean up; their two regressions failed before adding finally ownership. All51 focused controls pass on Python3.11,3.12 and3.13, with two real-router cases skipped in that selection. Fresh actual small/300KB ngspice checks passed1.594s; both real router smokes passed4.62s. Format, Ruff and strict mypy pass. Independent review accepted scoped P1 closure, including the stronger unconfirmed-reap refusal/closure control and retained original assertions. Source/input fingerprint: sha256:6e031f8b1d0cab3e4303e06873ae1d68d0beea2c4408ef9edc463bbef024ed7b. The earlier full run is pre-P1 evidence. A new corrected-source full run, updated PR review/checks and main verification remain mandatory; no descendant-containment, physics or apply claim follows.

2026-09-08 SEC-211 parallel full validation was unsuccessful: four native authority controls failed while5,684 passed and one skipped in970.40s on three workers. Two SPICE controls expose exit-time deep bundle-signature verification timeouts with about8s and5s remaining. Two project ERC failures deliberately suppress internal context, so their exact original cause is not asserted. The selector/cleanup controls passed in that run. The same four native cases passed serially with coverage in51.44s and unchanged authentication/deadline limits; diagnostic timing was limited to elapsed time, remaining budget, exit status and exception type. That observation does not establish a causal contention result or replace full validation. The next full attempt uses standard serial test execution, retaining every test, coverage and all original limits.

2026-09-08 SEC-211 corrected serial full validation passed5,688 tests with one skip and90% code coverage in1658.22s of pytest. All format, lint, strict type, security and build gates passed. Tested staged treedc4bf17d3960de2a91957c14de0def13422fe150; source/input fingerprint sha256:6e031f8b1d0cab3e4303e06873ae1d68d0beea2c4408ef9edc463bbef024ed7b. This is a complete serial run of unchanged tests, limits and authentication, not a subset or budget relaxation. The earlier parallel run remains unsuccessful evidence and its contention hypothesis remains unproven. Independent review accepted the actual P1 implementation; updated protected hosted validation and resulting main verification are still required before landing.

| SEC-212 | 2026-09-08 | Explicit operating-point case binding | Closed bounded case JSON; declaration/capture/binding identity checks; complete non-NC native endpoints; native-ground normalization; all-rail mapping; explicit energization; directed load-pair and temperature-limit checks; deadline-bound identities. | Caller-created binding/declaration data is not authenticated source or physics proof. No deck, backend, execution, convergence, engineering, approval or apply authority is introduced. Full composition, protected-hosted and main verification remain required. | ADR-0154, D-279 |

2026-09-08 SEC-212 isolated controls passed12 tests each on Python3.11,3.12 and3.13. Format, Ruff, complete lint/metadata, strict typecheck, security audit and package build passed. Independent isolation and metadata review accepted the unchanged source/assertions, complete parent ledger prefixes and private non-authority interpretation. Ponytail found no justified cuts in this binding stage. These results do not claim fresh isolated-full, native execution, physics, hosted publication or main verification; those remain separate gates.

2026-09-08 SEC-212 complete isolated validation: make check passed5,692 tests, one skip, 90% code coverage and every format, lint, type, security and build gate. Pytest completed in619.68 seconds on three workers. Tested commit388768a32138f70404b32c163b1863ce9fd9b667; tree663eb5055ed2341ad5f57af9ccafcb913c81b74a; source/input fingerprint sha256:6d583420728ca02d564c4dfa6e6a0fbf871a8749ca40383c1dc83ba83b04bfbc. Independent source/isolation and metadata reviews accepted. This establishes the isolated binding stage's validation, not a simulator, calibrated authority or completed readiness goal. Parent-publication, protected hosted checks and resulting main verification remain required.

2026-09-08 SEC-212 parent correction: the six shared container/P1 test files now match the independently reviewed nonblocking correction in the executor stage. Case binding and its original assertions are unchanged. The earlier full result is pre-correction evidence; it does not establish a corrected-source full pass. Parent full/hosted/main validation and this stage's updated exact-source gates remain required.

2026-09-08 SEC-212 corrected full validation passed5,700 tests with one skip and90% coverage in1759.34s of serial pytest. All format, lint, strict type, security and build gates passed. Tested commitac45173c25d3e56b19a7255a09fded1f402ae27a; tree 6fa848fc31ef0fbbd1b3be5df55b6d75f0c6b587; source/input fingerprint sha256:278e96ed0bfcb2e1b826374033c6e95a3663a9970dde0a53ddca7af002da1214. The complete test selection, authentication and all limits were unchanged. This is current isolated-stage evidence after the parent cleanup correction, not the older pre-P1 result. Main2cbf2df is verified green. Exact-head hosted checks and resulting main verification remain required before further publication; no physics, execution or apply authority is claimed here.

2026-09-08 SEC-212 review correction: PR301 identified caller-created model pins whose native reference differed from their enclosing bound component. Nine regression cases reproduced acceptance before the fix: renamed owner, renamed selected pin, and unused no-connect foreign pin, each through source admission, expected export rows and operating-point case resolution. Both shared admission boundaries now require exact reference equality before optional-pin selection. The nine regressions pass; related focused controls passed124 tests with three environment-gated skips. All21 case controls passed on Python3.11 and3.13; format and Ruff passed. The prior5,700-test full and hosted CI34186402701 succeeded on the pre-correction source only. Independent review and fresh corrected-source full/hosted/main validation remain required. No source authentication, numerical, physics, engineering or apply authority is added.

2026-09-08 SEC-212 pin-owner correction complete validation: 5,709 tests passed with one skip and 90% code coverage in 1764.40 seconds of serial pytest. All format, lint, strict type, security and source/wheel build gates passed. Tested commit 43afebcdea5f9ad2699b6cbbaa690f3de9148a34; tree 31718671f11f8927892ec5bece57abcaec1a99cb; source/input fingerprint sha256:10ac9630ef8851c4b303ef98d50f9ec88e9d7665e650841e10cfe3ad4f8fcee0. Independent correction review accepted the shared pin-owner guards and reproduced 21 passing case controls. Hosted CI34187753206 passed on the same implementation. This record changes no source or test bytes; final metadata and exact-tip hosted checks, followed by resulting main verification, remain required before the next milestone publishes. No physics or apply claim.

2026-09-08 SEC-003 corrective finding: an owned KiCad 10.0.5 fixture with a missing-unit custom clearance constraint returned a schema-valid default-rule DRC report. The intended 0.5 mm negative control did not fail until the rule was corrected to explicit 0.5mm. A matching project file alone did not change that outcome. Native source confirms rule-initialization failure clears the complete custom set and the board loader catches the exception. The original authority claim is therefore incomplete for malformed custom-rule input.

A separate owned native experiment produced the exact probe item's unexcluded error assertion for two valid rule files and none for missing units, an unknown constraint or an invalid condition property. This supports the ADR-0160 design, not implementation acceptance. Full original-context preservation, witness spoofing, deadlines, ceilings, cleanup, native integration and independent review remain required. SEC-113's zero diagnostic-capture budget and the existing file/apply boundaries are unchanged.

2026-09-08 SEC-003 scoped implementation review accepted the loading/fallback correction after case-preserving paths, pre-hash input admission, projected-size admission, post-cleanup deadlines and context-free original-store failure handling were corrected. Four primary path/privacy regressions failed before correction and pass afterward. Integrated controls passed 124 tests and 25 subtests on Python 3.11, 3.12 and 3.13; four real cases were deselected in those runs. The separate real KiCad group passed 18 cases in 12.01 seconds, including the 14 new loading controls and existing native DRC integrations. Counts are overlapping, not additive coverage. Format, lint/metadata, strict type, secret/dependency audit and source/wheel builds passed. Independent final implementation review repeated 124 tests and 25 subtests and found no remaining findings in scope. Fresh full validation, protected hosted/main checks and final evidence review remain pending. This is loading/fallback detection, not static rule-expression certification; inactive invalid assertion expressions remain a distinct unresolved native limitation.

| SEC-213 | 2026-09-08 | Conservative operating-point topology preflight | Fresh bounded captured-model parsing; positive R/C/L admission; iterative expansion and node/work/path limits; case-folded hierarchy-collision refusal before renaming; grounded-incidence and voltage/inductor-loop checks. | Malformed, unavailable, unsupported and expired input refuses. No source authentication, deck/backend execution, convergence, physical correctness, engineering, approval or apply authority is introduced. Full composition, protected-hosted and main verification remain required. | ADR-0155, D-280 |

2026-09-08 SEC-213 isolated controls passed32 tests on each of Python3.11,3.12 and3.13. Format, Ruff, complete lint/metadata, strict typecheck, security and build passed. Independent isolation and metadata reviews accepted unchanged source/assertions, complete parent history and conservative non-authority claims. Ponytail's optional unread _Model.name field finding is recorded but not applied; _Element.name remains necessary for hierarchical identity. Fresh isolated-full and composed/native/publication evidence remain separate gates. None of these controls establishes complete singularity detection, convergence or physical accuracy.

2026-09-08 SEC-213 historical full result: the pre-P1 stage at4ca0f79 passed5,724 tests, one skip and all make-check gates in673.17s of pytest. Tested tree 95591f7401516947d4bf59ba77ee7cdb2e1ff6fb; source/input fingerprint sha256:104e9bd2b86f21f1a830ec903708524a3b4da239ac167bebb79c7a8d89f77d45. The shared container/P1 correction has since been propagated from the reviewed executor stage; topology logic and its original assertions remain unchanged. That correction requires new exact-source validation. The historical full result is not a pass for the current source.

2026-09-08 SEC-213 complete serial validation passed 5,732 tests with one skip and 90% code coverage in 1847.52 seconds. All format, lint, strict type, security and build gates passed. Tested commit 92cfafe17448496ea02ae90e9b59a997372c233d; tree c70c6976498807fd0c4b65c45ba16109908d7b7f; source/input fingerprint sha256:1fdef2ffd51228d341351a89ee98a1509daf9287d8af425fbe58d4d8ac6cbd93. No test selection, authentication or work/time limit was relaxed. This source includes the container cleanup correction but precedes PR301's foreign-pin admission correction. Integrating that correction requires fresh exact-source validation; this result must not be attributed to the later source. No convergence, physics, application, hosted or release acceptance is claimed.

| SEC-214 | 2026-09-08 | Bounded project nominal-DC observation | One internally verified export acquisition; explicit case/topology/deck admission; exact captured models; fixed-image two-run case replay; bounded diagnostics/raw-vector/numeric checks; final artifact recapture and source freshness. | Supported passive/diode nominal DC is not SI/PI/thermal/EMC, calibration, model accuracy, convergence or engineering authority. No new MCP, provider or apply surface is introduced. Protected-hosted, main and release verification remain required. | ADR-0156, D-281 |

2026-09-08 SEC-214 isolated validation: 22 non-real controls passed on Python3.11,3.12 and3.13, with six real cases deselected; format, lint, type, security and build gates passed. Reused complete evidence belongs only to original checkpoint45b42f1, tree5bb8bd4, where the full suite recorded 5,740 tests, one skip and676.10 seconds with source/input fingerprint sha256:a105ad63bc33af20b266add5d77c7efdd839269070bc8bca564ee58906717b72. It is not a fresh full-validation claim for this publication tip. Historical unsuccessful a6 evidence, if encountered, remains unsuccessful and is not substituted for this checkpoint.

2026-09-08 SEC-214 publication hold: the matched45b42f1/tree5bb8bd4 full result predates the PR300 shared-container cleanup P1. It remains historical source evidence only and does not close corrected-source validation. P1 remediation, fresh full validation and protected publication/main verification remain pending; this note neither changes prior evidence nor claims the finding closed.

2026-09-08 SEC-214 parent correction is propagated: shared container source and tests match the reviewed executor correction. Current complete source/config/test equality with the development reference is preserved at fingerprint sha256:18793b02532f865d42ccb978f945ced1a895bae52ffeeb59ed17f08e54a16f27. The earlier a105 fingerprint and its full run remain historical. Corrected-source full and protected publication/main validation are still required before this stage can land.

2026-09-08 SEC-214 corrected full attempt remains unsuccessful:5,747 tests passed, one skipped and one native SPICE-source control failed in2150.82s. Its trace names exit-time deep bundle authentication timing out with about20s remaining. That test and authentication implementation are unchanged from main2cbf2df. A standalone signature check subsequently completed in7.48s; the exact failed test passed with coverage and unchanged limits in23.24s, with timing-only diagnostics showing deep checks around4s. These observations do not prove the cause of the full-run latency spike or establish a full pass. No check was cached, skipped or weakened. Complete-project acceptance remains open pending successful full validation and hosted gates.

| SEC-215 | 2026-09-08 | Purpose-bound host confirmation across MCP protocols | Default-off verified-host gating; owner/purpose/job-record/package/judge-bound, expiring one-use challenges; 128-entry retention; replacement/replay refusal; pre-prompt and post-acceptance delivery checks; unchanged approval source checks and fixed resolver errors. | Private board bytes, credentials and issued capabilities remain server-side. SDK continuation protection alone proves neither one use nor human consent. No apply, physics, new tool or provider authority is added; full/native and verified-human validation remain open. | ADR-0157, D-282 |

2026-09-08 SEC-215 focused validation:36 consent controls pass with installed MCP2.0.0 and2.1.1, including actual legacy/current protocol clients. The same36 controls pass Python3.11 and3.13. Independent review accepted the replacement/replay controls after a P2 correction: expected resolver failures now return fixed ToolError rather than UnexpectedToolError. Both exact-class regressions failed before the correction. The five normalized input/output schemas match the clean6244fdb/8a4bbce baseline (60,042 bytes; sha256:b6f0bc2d53d688bf4922ef17ca6c88cb9f8dbcc3eddf8b1bc4e474d3fb86627f). Ponytail found no safe cut without removing load-bearing checks. These synthetic client results do not prove a human UI, native application or full-repository acceptance.

2026-09-08 SEC-003 PR302 follow-up: review found that each native pass independently resolves the executable. A changed PATH, configured alias or executable can separate the loading witness from the original report's backend. The prior full run is successful evidence for its recorded source, but does not close this finding. A single resolved executable identity with bounded content/stat checks before both passes and after cleanup is being implemented. It will require new scoped/full/hosted validation; no atomic-exec, vendor or shared-library assurance is implied. Dependent topology validation was intentionally interrupted, exit130, after322 passing tests and442.61 seconds. Its partial log remains non-successful evidence; it will not be reused as a pass.

2026-09-08 SEC-003 executable-binding correction: one resolved path and bounded descriptor-backed content/stat identity now bind the operation. Drift checks cover both passes and final cleanup, including no-rule execution. A new mocked outbound-timeout control reproduced 10 seconds being granted after seven seconds of a ten-second budget; the corrected no-rule path grants three. Independent review accepted the implementation and this final deadline correction. Integrated checks passed 137 tests and 25 subtests on Python 3.11, 3.12 and 3.13; four native cases were deselected in those runs. A separate controlled native group passed 18 cases in 39.14 seconds. An earlier worker command accidentally selected one native unittest and failed its workspace assertion; that run is not acceptance evidence, and no installed executable was modified. Fresh complete and exact-tip hosted validation remain required. Executable consistency does not establish atomic pathname execution, publisher authentication or shared-library integrity.

2026-09-08 SEC-003 portable-test correction: hosted CI run 34209815291 rejected three legacy DRC mock cases on all supported interpreters because /trusted/kicad-cli does not exist. Those tests now use the existing inert executable-fixture helper in their pytest-owned temporary area, outside the workspace whose contents they assert. Subprocesses remain mocked; production executable discovery, identity admission and drift checks are unchanged. The three cases failed before correction (43.80 seconds) and passed afterward on Python 3.12 (149.43 seconds on a heavily contended host). This is mock-contract evidence, not native execution. The new exact-tip hosted matrix and complete integration validation remain pending.

| SEC-216 | 2026-09-08 | Private complete layered-tree composition | Exact source-pad/layer membership; bounded pre-hash admission; deterministic replay; complete source-net verification; shared through-via identity and remaining allowances; source-preserving reparse; context-free callback errors and final cancellation checks. | Scoped correctness review is accepted. Native DRC, full integration, held-out quality and protected publication remain pending. No external conversion, physics, human confirmation, apply or saving authority is introduced. | ADR-0158, D-283 |

2026-09-08 SEC-216 independent review closed the reported terminal-layer, complete-pad-set, nonfinite budget, inherited exception-context, pre-hash traversal, shared-via, remaining allowance, late-cancellation and same-layer/source-pad contact findings. The final reviewer independently ran 71 scoped tests in 1.42 seconds, plus pair-budget and cancellation controls. The implementation worker reported 154 combined new/legacy unit tests in 6.99 seconds. Counts are overlapping, not additive. Inner-only SMD fixtures are synthetic only; the ordinary outer-pad native fixture is prepared but has not executed. No native, full-suite, held-out or readiness acceptance is claimed.

2026-09-08 SEC-216 native fixture check: the ordinary three-outer-pad/four-layer case passed with KiCad 10.0.5 in 2.03 seconds. Its source had unconnected items; the deterministically serialized complete result had zero hard DRC errors and zero unconnected items. The original source bytes, inode and modification time were unchanged. This uses distinct single-pad blocker nets and exercises actual inner copper, not the invalid inner-only SMD fixture. Source/input fingerprint sha256:6e9b09caecd6f810520b5e04ee792e521fff50a7b5bf66f3a1c5ccb9468a5072. This owned fixture proves only that composed case. Full integration, broader native coverage, held-out quality and protected publication remain required; no physics or apply authority is added.

| SEC-217 | 2026-09-08 | Private composed IR-class clearance | Complete input admission before hashing; exact rational geometry; physical-layer and net-class checks; cumulative work; fixed refusals; final cancellation; input-bound measured/unavailable observation. | Private implementation review accepted; parser-produced quoted strings are preserved while hostile subclasses refuse. Native comparisons are owned fixtures only. Full validation, versioned ranking integration and held-out improvement remain pending; no native-rule, physics or application authority is added. | ADR-0159, D-284 |

2026-09-08 SEC-217 scoped evidence: 73 unit controls plus two independent arithmetic tests passed. The latter cover 128 deterministic projection samples and translation/reflection invariance, not 128 physical measurements. Independent review repeated 75 non-native tests in 0.33 seconds. The real KiCad circular-pad comparison passed three cases in 1.34 seconds after explicit 0.5mm replaced the incorrect unitless fixture value. Earlier parser-admission and wrong-unit attempts remain failed evidence, not native validation passes. New shared rule-loading integration still needs current-source native/full verification. No production ranking or readiness gain is claimed.

2026-09-08 SEC-003 complete validation of the loading/fallback correction passed 5,781 tests with one skip and 90% code coverage in 1765.24 seconds of serial pytest. Format, lint/metadata, strict typecheck, secret/dependency audit and source/wheel builds all passed. Tested commit 68a811b067b0c81af6aaa80b8256b4794b691cc2; tree 1bc3e5dc623df889e69f97698f0d9e928a553311; source/input fingerprint sha256:0fb075b0f78365db1bca07a7154dd99d235b2b6cb1303fad5c58b4b2ad9c5563. The run enabled the new native rule-loading controls and existing real-router/native settings, without removing tests, relaxing limits or replacing native checks with mocks. This record changes no implementation or test bytes. Final record review, exact-tip hosted validation and resulting main verification remain required. The static-expression limitation above and full five-area readiness, physics and human-approval gates remain open.

2026-09-14 SEC-003 cutout workflow review: explicit Board IR0.5 and scene0.5 preserve missing material and owner geometry;0.4 bytes/interpretation remain frozen. Native multi-layer zones retain their source object and project context while per-layer IR projections carry an explicit source-zone binding. Reviewer identified an already-connected shortcut before cutout obstacles; shared retained-copper checks now precede connectivity claims and consume existing budgets. Exact capsule/annulus contact was independently reviewed as sound, including rejection of drill-only copper; it is enabled only for0.5. The duplicate material scan identified in review was removed while direct connectivity callers retain the check. No native/apply/consent authority is weakened. Current native controls are development evidence only; full validation, final integrated review and protected main CI remain outstanding for this feature.

2026-09-14 SEC-003 PR307 external review correction: despite green hosted checks, review identified a non-owner pad placed wholly inside a cutout being labeled inconclusive and therefore considered legal. Reproduction confirmed this for axis-aligned and45-degree pads; the latter has no conservative core. The shared legalizer now rejects whole-bound containment in a hole or any positive core contact. Direct legalizer and production preview controls both refuse without a candidate or apply token. The existing outer-edge/0.4 behavior is unchanged. Focused placement controls passed97 cases and31 subtests; the positive native placement/routing cutout workflow passed7.57s after the fix. Earlier green checks and review did not prove this missing negative case; final validation and re-review are required before merge. No board was applied and no genuine consent is claimed.

2026-09-14 SEC-003 closed-boundary refinement: a45-degree6x8mm pad inside a10x10mm cutout has a conservative circular AABB exactly equal to the hole bounds. The strict polygon-containment test still returned inconclusive; its new regression failed before switching to inclusive exact rectangular bounds. All three non-owner cases now return illegal_placement through both the legalizer and production preview, without candidates or tokens. Independent correctness/security and Ponytail review accepted this proof;101 focused cases and31 subtests passed, strict mypy and Ruff passed, and the positive native workflow passed7.38s. Product/required-domain authority and the no-hole outer-edge policy are unchanged. The corrected full integration gate remains pending.

2026-09-14 SEC-003 P1 closure verification: tree efde5ccd13b57a8bec14ffd3b38fed23d2a97d4f passed complete make check:6296 passed,79 skipped, 380.15s,88% coverage, canonical Python3.12 and four workers, plus metadata/lint, strict mypy, secret/dependency audit and wheel/sdist builds. This append records the result without changing tested product or test bytes. The old PR head's green CI is not evidence for the correction; new-head hosted validation and protected merge/main verification remain required.