chore(deps): Bump idna from 3.13 to 3.15 in /backend#21
Open
dependabot[bot] wants to merge 1 commit into
Open
Conversation
Bumps [idna](https://github.com/kjd/idna) from 3.13 to 3.15. - [Release notes](https://github.com/kjd/idna/releases) - [Changelog](https://github.com/kjd/idna/blob/master/HISTORY.md) - [Commits](kjd/idna@v3.13...v3.15) --- updated-dependencies: - dependency-name: idna dependency-version: '3.15' dependency-type: indirect ... Signed-off-by: dependabot[bot] <support@github.com>
eastmadc
added a commit
that referenced
this pull request
May 22, 2026
Codify the cross-stack alignment test discipline as a first-class recipe. Pairs with CLAUDE.md Rule #25 single-slice exception #2 (cross-stack-alignment commit shape) — that rule covers the COMMIT shape; this recipe covers the TEST shape (5 mandatory parts + asymmetry-tolerance design principle + 2 commit shapes Shape 1 multi-surface single-commit vs Shape 2 regression canary on existing surfaces). Closes evening:RvwC-C2 HIGH from postmortem-hw-firmware-reviewer-followup-2026-05-15-evening.md (ADAPTIVE_BACKLOG entry now in-progress → completed). Rule-of-Nine evidence table inline: - Rule-of-Eight Shape-1 baseline: 7079b4d + ee2abd9 β.12a + f70c2e1 γ.7 + 20ea228 δ.8 + 5466644 ε.1.b.4 + da71afa ζ.1 + a6be708 ζ.2.C + 04a3c55 ζ.3.C - 9th instance + first Shape-2: d641f28 (2026-05-15 evening) F-FORENSIC-10 alignment canary — first explicit add-test-only commit for existing-surface alignment Companions: Rule #21 (sync CLAUDE.md ↔ conventions.md ↔ .mex/patterns/), Rule #46 META-CANARY discipline (gate's diagnostic substring must be asserted, not just rejection), Rule #31 width-canary (surface-identification grep run twice), Rule #19 evidence-first (asymmetry documented in module docstring before refactoring it into a "looks symmetric" shape). INDEX.md entry added in same commit per Rule #21 sync discipline. ~282 LOC recipe (within typical recipe size range — add-alembic-migration is 17312 chars; this is comparable). Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
eastmadc
added a commit
that referenced
this pull request
May 22, 2026
Codify the forward-prepared CVE pin pattern as a first-class recipe. Pairs with CLAUDE.md Rule #19 evidence-first + the hard-reject version_regex matcher contract at cve_matcher.py:480-491 ("Stays STRICT — when present, version evidence MUST be found"). Closes evening:RvwC-C7 HIGH from postmortem-hw-firmware-reviewer-followup-2026-05-15-evening.md (ADAPTIVE_BACKLOG entry now in-progress → completed). Rule-of-Two evidence: - 6bc1c1d (2026-05-15 morning) — 6 Tegra/L4T CVE pins forward-prepared for L4T BSP release extraction; activated via afternoon's f54d415+0a901f2+338f95b parser chain (4-of-6 fired on DS1; 2 correctly excluded per NVD scope). - e45a74c (2026-05-15 evening) — MediaTek CVE-2023-20819 forward-prepared for MOLY banner extraction (lr11/lr12a/lr13/nr15/nr16/nr17 modem-OS families per NVD CPE); 20 rows over-attributed pre-narrowing → 0 rows post-narrowing pending mtk_modem parser shipment. Recipe covers: WHEN to apply (NVD-CPE narrowing without extraction infra) + WHAT to ship (YAML entry shape with inline comment header citing NVD CPE + hard-reject contract + activation prerequisite) + boundary-anchored regex shape `(?:^|[^a-z0-9])` for substring-confusion guards (NOT `\b` which fails on underscore-separated banners like MOLY_NR16_R1) + gate-canary test shape per Rule #46 + activation commit-chain plan (parser extraction → detection re-run with DELETE-before-redetect → cve-match with surgical DELETE before re-match → verification audit) + 10 worked steps. Companions: Rule #19 (evidence-first NVD WebFetch), Rule #25 per-piece commits, Rule #46 paired-canary (gate-canary REQUIRED), Pattern #5 of evening postmortem (surgical DELETE before cve-match), Pattern #7 of afternoon postmortem (on_conflict_do_nothing requires DELETE+redetect for parser-output changes on existing blobs), Pattern #8 of evening postmortem (pre/post corpus baseline audit), Pattern #9 of evening postmortem (triple- verification scout → implementer → reviewer catches drift single-axis verification misses; 7 sessions running durable beyond debate). INDEX.md entry added in same commit per Rule #21 sync discipline. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
eastmadc
added a commit
that referenced
this pull request
May 22, 2026
… C C14) Cross-stack-alignment commit per Rule #25 single-slice exception #2 + Rule #21 sync discipline — CLAUDE.md learned rules + .mex/context/conventions.md Verify Checklist mirror in one atomic commit. Splitting would leave them temporarily out of sync (the same alignment-drift failure mode the rules themselves codify against). PROMOTIONS (closing evening:RvwC-C14 HIGH): - Rule #48 — Cross-stack alignment test discipline 5-part shape (paired rejection + paired acceptance + size-lock + cross-layer alignment proper + Rule #46 META-CANARY) + asymmetry-tolerance design principle (WARN+skip vs raise ValueError per layer; NOT a forced common mode; name-equality across dialects is FALSE alignment) + two commit shapes (Shape 1 multi-surface single-commit per Rule #25 vs Shape 2 alignment regression canary on existing surfaces). Rule-of-Nine durable beyond debate; recipe at .mex/patterns/cross-stack-alignment-test.md (105a888). - Rule #49 — Forward-prepared CVE pin pattern (Rule-of-Two Tegra+MediaTek modem). HARD-REJECT version_regex contract at cve_matcher.py:477-491 produces zero matches today + activates zero-LOC when parser ships. Required: inline YAML comment header citing Reviewer source + boundary- anchored regex (?:^|[^a-z0-9]) + gate-canary test per Rule #46 + activation commit-chain plan. Recipe at .mex/patterns/forward-prepared- cve-pin.md (b8f6e95). - Rule #50 — Shared advisory_id with documented dedup pattern (Rule-of-One+ FragAttacks; promotable to Rule-of-Two on KRACK/Dragonblood/BroadPwn audit). Matcher dedupes per (firmware_id, blob_id, cve_id) UNIQUE; duplicate-advisory_id WARN at load time is INTENTIONAL convergence signal (opt-in suppression deferred). Vendor narrowing fields on advisory-only entries (cves: []) remain load-bearing for _match_curated. CVSS aggregate discipline (worst-case individual) — 7 sessions running. Rule #25 SINGLE-SLICE EXCEPTION #2 UPDATE: Rule-of-Eight → Rule-of-Nine adds d641f28 as the 9th instance + first canonical Shape-2 form (alignment regression canary on existing surfaces; commit-prefix test(<scope>)). Promotion rationale per Rule #40 / Rule #47 precedent — Rule #48 promoted at Rule-of-Nine (durable beyond debate); Rule #49 at Rule-of-Two; Rule #50 at Rule-of-One+ with future-Rule-of-N candidates explicitly queued in .planning/ADAPTIVE_BACKLOG.md (533bb72). Stale "rules 1-39 above" reference in Companion scaffold section bumped to "rules 1-50 above". conventions.md last_updated line bumped from 2026-05-12 to 2026-05-18 with promotion notes. This commit IS itself a cross-stack-alignment commit per Rule #48 Shape 1 (adding new entries across 2 source-of-truth surfaces: CLAUDE.md learned rules list + .mex/context/conventions.md Verify Checklist mirror — both enforce the same conceptual contract via Rule #21). Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
eastmadc
added a commit
that referenced
this pull request
May 22, 2026
…ter (A-01, A-02) Cross-stack-alignment commit per Rule #25 single-slice exception #2 + Rule #21 sync discipline — CLAUDE.md + conventions.md text correction in one atomic commit. REVIEWER A-02 HIGH (forensic-correctness): Rule #50 originally claimed the matcher dedupes via "(firmware_id, blob_id, cve_id) UNIQUE constraint". Independent code-read verification this session against backend/app/models/sbom.py:65-129 confirms NO UniqueConstraint exists on sbom_vulnerabilities — the model declares only Index entries (idx_sbom_vulns_component / _firmware / _cve / _resolution / _blob). Dedup is purely application-side via an in-memory `existing` set constructed at cve_matcher.py:905 from a firmware-scoped initial SELECT, checked at :989 (curated tier) + :1042 (Tier 4 kernel-CPE). `firmware_id` is implicit per-invocation because each match_firmware_cves call is scoped to one firmware row. This matters because the original wording suggested DB-level enforcement of the dedup contract; correct wording surfaces that `force_rescan=True` skips the in-memory check (NEVER DELETEs existing rows — UNIQUE violations on re-insert would still be impossible because there IS no DB constraint, but the application-level dedup is bypassed; the surgical-DELETE-before- cve-match recipe from evening postmortem Pattern #5 still applies for YAML-edit-driven row changes). REVIEWER A-01 HIGH (sync drift): .mex/context/conventions.md frontmatter `description` said "derived from 43 learned rules"; bumped to 50 after Rules #48-50 promotion in commit 294fa3a. Mirror of the parallel "rules 1-39 above → rules 1-50 above" fix already applied in CLAUDE.md:473 line. This commit IS itself a cross-stack-alignment commit per Rule #48 Shape 1 (CLAUDE.md learned rule + conventions.md Verify Checklist mirror enforce the same conceptual contract via Rule #21). Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
eastmadc
added a commit
that referenced
this pull request
May 22, 2026
…peners (C-01) Reviewer C HIGH C-01 from this session's adaptability review caught that ADAPTIVE_BACKLOG.md (commit 533bb72) is not referenced from .mex/ROUTER.md. A fresh hw-firmware-session opener loading ROUTER.md first per the Behavioural Contract would NOT discover the backlog — closing the future-session-affordance loop the backlog itself was meant to open. Fix: - Add routing-table row "Continuing a hw-firmware adaptive-detection session → .planning/ADAPTIVE_BACKLOG.md" with a one-line gloss on its spot-check methodology. - Bump last_updated 2026-05-05 → 2026-05-18 to reflect this edit. The "Current Project State" + "Known issues" sections in ROUTER.md retain their existing content; this edit is surgical per Rule #21 sync (route to the new artefact, don't rewrite the file). Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
eastmadc
added a commit
that referenced
this pull request
May 22, 2026
…it tier re-evaluation Rule-of-One mechanical-rigor strength (precedent: Rules #40 + #47 + #50 promoted on same basis). When converting an endpoint from synchronous to 202+polling per Rule #33, the saturation calculus changes from "uvicorn worker held for N minutes" to "background task spawned per ACK" — the original rate-limit tier becomes the wrong shape, usually too restrictive AND keyed to the wrong resource ceiling. Source evidence — 2026-05-18 rate-limit campaign (9 commits): - f6dbc7b: split TIER_A_HEAVY → TIER_A_HEAVY + TIER_A_LIGHT_ACK - 69ed1dd: extractErrorMessage handles SlowAPI body shape - ca5a64f: axios global 429 interceptor + Retry-After cooldown - 616e89d: custom structured 429 handler (tier name + retry_after + hint) - 3d2454b: vuln_scan_status orphan reaper (mirror of cve_match / device_dump reapers) - 58a6f54: bump DB pool 10+20 → 15+25 = 40 for 30/hour burst headroom - 8766710: add TIER_A_HEAVY to undecorated 202 endpoints /firmware/{id}/unpack + /device/dumps - afa23a9: fix tier reverse-map (parsed-form keys) + Retry-After header (caught by live canary) - b24a4d8: dynamic 429 test + Rule #46 META-CANARY trio (proves gate fires) Root cause: the Rule #33 sync→202+polling conversion at commit 8f54a24 (vuln-scan) didn't re-evaluate the rate-limit tier, so the 5/hour limit kept throttling the operator's iterative research workflow on DS1 firmware. Sweep also caught 2 unrelated UNLIMITED 202+polling endpoints with the same shape-mismatch (firmware/unpack + device/dumps). Rule shape: - Mechanical procedure (a)-(h) covering measurement + computation + documentation + test-update + canary discipline at Rule #33 conversion time. - Tier shape by WORK duration (not ack shape): TIER_A_HEAVY for ≥5min event-loop pin OR sync; TIER_A_LIGHT_ACK for ≤2min detached; TIER_B_DOCKER for Docker-spawn. - Companion failure-mode bullets (orphan reaper / frontend 429 handler / structured 429 body) so future Rule-#33 conversions enumerate the dependents explicitly. - Promotable to Rule-of-Two when next Rule-#33 conversion surfaces the same gap. This commit IS itself a cross-stack-alignment commit per Rule #48 Shape 1 (CLAUDE.md learned rule + conventions.md Verify Checklist mirror enforce the same conceptual contract via Rule #21). CLAUDE.md changes: - Rule #51 inserted after Rule #50 (lines 464-466) - "rules 1–50" → "rules 1–51" in Companion scaffold section conventions.md changes: - description: "50 learned rules" → "51 learned rules" - last_updated: amended with Rule #51 promotion line - Verify Checklist: new bullet inserted before Rule #50 entry Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
eastmadc
added a commit
that referenced
this pull request
May 22, 2026
…r-ingest Operator-facing documentation completing Scout DD §Docs requirement. extending-firmware-patterns.md gains "Surface 6 — chip_families/*.yaml" covering: schema location, hot-reload contract, closed-grammar discipline (NO regex/script/template keys ever), 65-line worked example for STM32F4 walker hint, what operators DO and DO NOT need to do, pointers. New external-descriptor-ingest.md captures the Velociraptor / dissect / custom-ingestor protocol: endpoint shape, auth, rate-limit, request + response schema for all 5 status codes (201/200/409/422/404/429), Velociraptor VQL integration example, roadmap of Phase 2.5 / 3 / 4 upgrades, pointer back to Rule #52 + #33 + #51 + #46. Rule #21 sync: both docs reference Rule #52 + scout findings; companion recipe files in .mex/patterns/ deferred to Phase 2.5 (operator-facing docs are the higher-leverage move for the "we won't be the only ones ingesting files" direction). Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
eastmadc
added a commit
that referenced
this pull request
May 22, 2026
…3.2.f) Closes the P3.2 closure deferrals from the user kickoff prompt: * Item 7 — Wave-2 cross-feature critique methodology promotion. * Item 8 — Rule #52 promotion to Rule-of-Two (file-format YAML registry is the SECOND adaptable-extension surface after bare-metal MCU/DSP; Rule-of-Three eligibility declared for the next surface). CLAUDE.md Rule #52 updates: * "Worked example (Rule-of-One)" expanded into "Worked examples (Rule-of-Two DURABLE BEYOND DEBATE)" with worked-example #1 (Eaton TMS320F28066 bare-metal MCU/DSP — unchanged) + worked-example #2 (file-format YAML registry, Phase 3.1 + 3.2 across 14 commits): 20+ closed Literals (SortTier / DispatchKind / DetectionSignalKind / TextFormatCharset / etc.); 49 operator-extensible YAMLs; 9 cross- feature catalog-load validators A1-A9; cost-sorted resolver with _compute_sort_key total-order tuple; HYBRID plugin escape hatch (MatcherProto + register_matcher + freeze_plugin_registry); bundled rtos_detection_default plugin emits free-string rtos_family taxonomy via by_rtos_family dispatch; 60+ paired Rule #46 META-CANARIES; 348/348 pytest sweep green. * New "Methodology refinement — Wave-1 + Wave-2 cross-feature critique separation" section. Both worked examples used 5 Wave-1 single-axis scouts + 2-3 Wave-2 cross-feature critique scouts. W2-beta's "blow- it-up stage" surfaces attacks Wave-1 architecturally can't (P3.1 found A1-A5; P3.2 found 3 NEW SC5 analogs leading to A6/A7/A8). Without W2-beta, single-axis scouts MISS cross-feature attacks. The 2-wave separation is the durable methodology pattern. * "Promotable to Rule-of-Two when:" hoisted to "Promotable to Rule-of- Three when:" — next adaptable-extension surface (decoder family / vendor adapter / ICS protocol decoder / JTAG TAP family / USB descriptor families) shipping under the same shape promotes Rule #52 to Rule-of-Three DURABLE BEYOND DEBATE. .mex/context/conventions.md Verify Checklist: * New Rule #52 entry per Rule #21 (cross-scaffold sync — when a rule is added/changed in CLAUDE.md Learned Rules, update conventions.md in the same commit). Captures the 3-layer split discipline (DATA / BEHAVIOR / WALKER), the worked-example #2 detail, the Wave-1+Wave-2 methodology, and the companion-rule list. Memory: * New `feedback_wave2_cross_feature_methodology.md` capturing the Wave-1 + Wave-2 dispatch pattern with evidence (P3.1 A1-A5 + P3.2 A6/A7/A8 + 3 new SC5 analogs from W2-beta). * MEMORY.md index appended with the new feedback entry. P3.2 deferrals to P3.3 (separate session per W2-beta): * P3.3.a — delete 3 legacy shim modules (classifier_legacy.py + format_detection_legacy.py + unpack_common_classify_legacy.py). P3.2.e converted test_file_format_parity.py to JSON-snapshot form so the parity test no longer imports classifier_legacy — the modules become deletable safely. Acceptance: grep -c "Rule-of-Two" CLAUDE.md = 4+ (existing + 2 new for Rule #52) grep -c "Wave-1 + Wave-2" CLAUDE.md = 1 grep -c "file-format YAML registry" CLAUDE.md = 2+ grep -c "Rule #52" .mex/context/conventions.md = 1+ Phase 3.2 complete. 6 commits shipped: P3.2.a sort_tier + precedence-flip + _legacy_magic_classify removal P3.2.b TextFormatConstraint + Intel HEX + SREC + A8 P3.2.c RTOS plugin wiring HYBRID + by_rtos_family + A6/A7/A9 P3.2.d container precedence docs + windows_cab disambig drop P3.2.e parity test -> JSON snapshot form P3.2.f Rule #52 Rule-of-Two + Wave-2 methodology + .mex sync Net deltas across P3.2 (excluding deferred P3.3.a shim removal): ~3,200 net insertions across the 6 commits (cumulative); the legacy modules will be deleted in P3.3.a for net code reduction overall. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
eastmadc
added a commit
that referenced
this pull request
May 22, 2026
…IVE_BACKLOG.md (cross-scaffold sync) Per Rule #21 cross-scaffold sync — when a session ships backlog items, move them to the Completed section AND prune the Open section. This commit closes the 5 backlog items shipped today: * evening:RvwA-A5 + RvwB-B6 — shared_advisory_id opt-in (23974ea) * evening:RvwC-C10 — list_extension_points rejection counts (4ecaa5b) * evening:RvwC-C4 — describe_advisory MCP tool (f1669c3) * evening:RvwC-C11 — verify_cve_attribution MCP tool (7420279) * ratelimit-2026-05-18:scout1 — 9-endpoint TIER_A_HEAVY (3677f1c) Plus the 15-commit Phase 3.2 + P3.3.a chain (`34d0689..4c028fc`) closing all P3.1 deferrals end-to-end + the postmortem + /citadel:learn extraction. Frontend hover panel for advisory_id glossary downgraded LOW (backend MCP tool covers the operator-CLI path). Remaining 58 scout1 endpoints downgraded LOW (CRUD shapes that don't need TIER_A_HEAVY; re-grep needed before scoping). Last-updated header reflects 2026-05-19 closure. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
eastmadc
added a commit
that referenced
this pull request
May 22, 2026
…backlog sweep Closure documents for the post-P3.2 backlog sweep that shipped 7 commits (`4c028fc..e7824cf`) — P3.3.a shim deletion + 5 HIGH ADAPTIVE_BACKLOG.md items + cross-scaffold sync. Postmortem captures: * 7 commits with title/source/SHA breakdown. * 3 "What Broke" entries (1 carried from P3.2 terminator byte-count + 2 in-session caught at <2 min each: describe_advisory test field-access drift; Citadel protect-files hook on memory write). * 7 safety-system catches: _LAST_LOAD_REJECTIONS counter dict; _check_tier_alignment extension; shared_advisory_id asymmetric-opt-in WARN; backward-compat test; mock-vs-live discipline; pre-shipping pytest sweeps; Rule #21 cross-scaffold sync. * 5 patterns + 4 anti-patterns extracted to knowledge files. * 4 recommendations (frontend hover panel deferred LOW; scout1-remaining-58 deferred LOW; KRACK/Dragonblood/BroadPwn audit for Rule #50 → Rule-of-Two; MCP-tool 4-test-shape recipe). Patterns shipped to .planning/knowledge/backlog-sweep-2026-05-19-patterns.md: 1. HIGH backlog items close without scout dispatch when entry has LOC + rationale + reviewer-tag + acceptance criteria. 2. Schema-driven extension of existing tools beats new-tool authoring when new data fits role (C10 49 LOC vs C4 148 LOC + C11 280 LOC). 3. Per-tool MCP test shape — 4-test baseline (positive / no-match / schema-error / edge case). Rule-of-Two after C4 + C11. 4. Rule #21 cross-scaffold sync as the closure commit (ADAPTIVE_BACKLOG.md updated as the LAST commit before session-handoff). 5. Module-level counter dict + accessor + MCP-tool surfacing for cross-session observability of validator rejection counts. 6. Opt-in YAML key for intentional convergence (Rule #50). 7. Kickoff prompt's "alternative lanes" framing preserves unambiguous fallback-direction list. Anti-patterns shipped: 1. Tool-handler payload-shape drift between sister tools (caught by test KeyError; fix: factor shared dict-render helper). 2. Direct Write to memory directory blocked by Citadel protect-files hook (fix: Bash heredoc). 3. Stale ADAPTIVE_BACKLOG.md "Open" rows for shipped items (fix: cross-scaffold sync as closure commit). 4. Test assertion accessing field handler doesn't return (fix: sketch return-shape contract before writing test). Net session totals (15 commits 34d0689..e7824cf): * Phase 3.2 (a..f) = 6 commits + 3 closure (postmortem + /learn + P3.3.a shim deletion) * Backlog sweep = 5 commits + 1 ADAPTIVE_BACKLOG.md sync * 0 reverts; bisect-clean throughout * CLAUDE.md Rule #52: Rule-of-One → Rule-of-Two DURABLE BEYOND DEBATE * ADAPTIVE_BACKLOG.md §2 HIGH evening: ALL CLOSED * ADAPTIVE_BACKLOG.md §3.0 scout1: CLOSED (next-session: §3.a/b/c MEDIUM items + scout1-remaining-58 LOW) Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
eastmadc
added a commit
that referenced
this pull request
May 22, 2026
…3.x) Rule #25 Shape-1 single-slice cross-stack alignment commit per the P3.2 postmortem Rec #2 deferral: "Both `windows_installer_iso` (bootmgr substring) AND `iso_9660` (CD001 magic at offset 32769) can drop from `_CATALOG_NEEDS_DISAMBIGUATION` when a `substring_in_head` signal kind ships." Schema (`app/schemas/file_format.py`): * `DetectionSignalKind` += `substring_in_head` (13 values total). * New `SubstringInHeadCombine = Literal["any", "all"]`. * New `SubstringInHeadConstraint` Pydantic sub-model (5 fields, `extra="forbid"`): - `needles_hex: list[str]` — 1..16 entries; 2..64 bytes each; hex-validated by model_validator. 16-needle cap + 64-byte cap bound evaluator cost per Wave-1 S5 attack O floor. - `case_sensitive: bool = False` — toggles `bytes.lower()` pre-normalisation on both window and needles. - `combine: SubstringInHeadCombine = "any"`. - `min_count: int = 1` — validated `<= len(needles_hex)`. - `search_offset: int = 0`, `search_length: int | None = None` — bounded head window for the scan. * `DetectionSignal.substring_in_head_constraint` field + `_check_kind_fields` validator branch (required-when-kind + symmetric-reject; mirrors the P3.2.b `text_format_constraint` pair). * Exports: `SubstringInHeadCombine`, `SubstringInHeadConstraint`. Resolver (`app/services/file_format_catalog/resolver.py`): * `_eval_substring_in_head` — literal byte substring scan. Decodes needles once; optionally lowercases (window + needles); applies `combine` + `min_count`; bounded by `search_offset` + `search_length`. Zero hardcoded byte literals — Rule #46 anti-hardcode META-CANARY enforced via AST-walk. * `_SIGNAL_COST_CLASS["substring_in_head"] = 2` (same I/O cost class as `magic_bytes`; bounded head-byte scan). * `SIGNAL_EVALUATORS` entry — `test_meta_canary_signal_evaluators_exhaustive` remains green; new paired gate-canary added. YAML adoption (`_system/windows_installer_iso.yaml`): * Drops the `filename` signal (substring is stricter; preserves extensionless-bootmgr-ISO semantic from the legacy bridge). * Adds `substring_in_head` signal with 3 needles (`bootmgr`, `sources/boot.wim`, `sources\\boot.wim`), case_sensitive=false, combine=any, min_count=1 — mirrors the prior `head_lower` scan in `_legacy_bridge_detect`. Bridge cleanup (`app/services/format_detection.py`): * Drops `iso_9660` + `windows_installer_iso` from `_CATALOG_NEEDS_DISAMBIGUATION`. * Deletes the ~10-line CD001 + bootmgr substring upgrade block in `_legacy_bridge_detect`. Catalog round-trip handles both formats cleanly: bootmgr-bearing ISO → `windows_installer_iso` (precedence 100 + 2-of-2 all_required); bare ISO → `iso_9660` (the windows manifest's substring_in_head signal fails, all_required rejects, iso_9660 floor matches). Tests (`tests/test_substring_in_head_evaluator.py` — new, 34 tests): * Positive eval — bootmgr lowercase / uppercase (case-insensitive) / sources/boot.wim alternative / sources\\boot.wim alternative. * Negative eval — no needle / case_sensitive=True with mixed case / empty head / search_length too short / search_offset past needle / search_offset past blob size. * combine='all' requires every needle; combine='any' + min_count=2. * Catalog round-trip — bootmgr-bearing ISO resolves to windows_installer_iso; bare ISO resolves to iso_9660; uppercase BOOTMGR via case_sensitive=False. * Schema — required-when-kind / symmetric-reject / empty-needles / too-many-needles (>16) / under-min-byte / over-max-byte / odd-hex-length / invalid-hex / min_count>len(needles) / extra-field-forbid / accepts-minimal-default. * Operator manifest with substring_in_head loads cleanly. * Rule #46 paired META-CANARIES — exhaustive `SIGNAL_EVALUATORS` vs `DetectionSignalKind` PAIRED gate-canary (the existing canary at `test_file_format_catalog.py:774` lacked its paired gate-canary — Rule #46 hygiene fixup); NEW exhaustive `_SIGNAL_COST_CLASS` vs `DetectionSignalKind` canary + paired gate-canary (the project was missing this exhaustive entirely); PAIRED gate-canary for existing `DISPATCH_EVALUATORS` exhaustive (also lacked one). * Rule #46 anti-hardcode AST-walk META-CANARY for `_eval_substring_in_head` + paired gate-canary synthesising a hostile `b"bootmgr"` hardcoded variant. * `SubstringInHeadCombine` Literal exhaustive check. Parity corpus (`tests/fixtures/format_parity_corpus/`): * `_GENERATE.py` updated — `windows_installer_iso.head` now contains bootmgr at offset 0x100 + CD001 at 0x8001 (same 32774-byte size). * `_HEAD_BYTES_INSUFFICIENT` in `test_file_format_parity.py` drops `windows_installer_iso` — head-byte fixture is now sufficient. Validation: * 433/434 pytest green across in-scope file-format + classifier + unpack-integrity + windows-format-detection + text_format + substring_in_head test files (1 skipped pre-existing; 3 broader- sweep failures pre-existing in main: 2 PE-signatures FK + 1 rate-limit dynamic — documented in ADAPTIVE_BACKLOG.md). * Rule #11 import smoke against running backend — `SIGNAL_EVALUATORS` exhaustive against new `DetectionSignalKind`; `_SIGNAL_COST_CLASS` exhaustive; `SubstringInHeadCombine` Literal values correct. * Rule #35b live canary against running backend — `detect_format()` round-trip: bootmgr-bearing ISO → `windows_installer_iso`; bare CD001 ISO → `iso_9660`. Bridge no longer mentions ISO_9660. * Catalog `last_warning` is `None` after load — no schema rejections on the windows_installer_iso adoption. ADAPTIVE_BACKLOG.md sync (Rule #21): new `p3x:substring_in_head` row in §5 completed; last-updated bumped to 2026-05-20 morning. Follow-up deferrals carried forward (still queued from P3.2): * `Refinement.stem_category_map` schema extension (closes qcom_mbn). * arq worker `on_startup` plugin registration. * Per-family RTOS YAMLs in `_system/`. * TI-TXT YAML + `block_header` Literal value (paired with chip_family TI C28x walker integration).
eastmadc
added a commit
that referenced
this pull request
May 22, 2026
Closure document for the P3.x signal-kind extension shipped at dcebd1c..52bce07 (2 commits — schema extension + SHA pin). Postmortem captures: * 3 "What Broke" entries — all caught + resolved in <5 min each: (1) Rule #8 rebuild's COPY layer snapshot ran mid-edit so resolver + format_detection + YAML edits MISSED the image; recovered via docker cp + Rule #20 restart fallback. (2) Production .dockerignore excludes tests/, so corpus regenerator can't run inside the container; switched to host `uv run`. (3) Pre-rebuild backend container's pytest run returned phantom- green 223 passed despite .dockerignore tests/ exclusion — origin unclear, but trust HOST pytest as canonical going forward. * 13 safety-system catches across the schema validator + 4 new Rule #46 paired META-CANARIES + 1 NEW exhaustive (`_SIGNAL_COST_CLASS`) + anti-hardcode AST walker + Rule #11 import smoke + Rule #35b live canary. * 7 patterns: 1. HIGH P3.x deferrals close without scout dispatch when shape + scope are clear (Rule-of-Two now: backlog-sweep + this session). 2. Sub-model + symmetric-reject + extra='forbid' + Rule #46 paired canary is the durable signal-kind extension shape (Rule-of-Two now: TextFormatConstraint + SubstringInHeadConstraint). 3. Rule #46 §gate-canary-requirement hygiene fixups cluster around new signal-kind extensions — sweep adjacent dispatch tables. 4. Rule #25 Shape-1 single-slice exception #2 stays correct (Rule-of-Eleven now: Rule #25 Rule-of-Nine + P3.2 baseline + this). 5. Direct-push per-piece cadence + 0 reverts continues (32+ commits across 4 sessions). 6. Test infrastructure executes on host, NOT in production container. 7. `docker cp` + `restart` per Rule #20 exception is the right fallback when a parallel rebuild snapshots mid-edit. * 7 recommendations for future sessions: 1. Refinement.stem_category_map schema extension (HIGH next). 2. arq worker on_startup plugin registration (MEDIUM). 3. TI-TXT YAML + block_header Literal (deferred until chip_family). 4. Per-family RTOS YAMLs in _system/ (MEDIUM). 5. .mex/patterns/add-signal-kind.md recipe at Rule-of-Three. 6. UP037 cleanup in app/schemas/file_format.py via `from __future__ import annotations` (low-priority lint hygiene). 7. make_live_db() FK breakage on volatility_injection_records → memory_dump_image (pre-existing; tripped today's broader-sweep). * Numbers: 2 commits / +789 net / 34 tests / 0 reverts / 1 Rule #21 cross-scaffold sync / 0 quality gate blocks. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
eastmadc
added a commit
that referenced
this pull request
May 22, 2026
…ssion 1 Closure document for the ICS protocol catalog Session 1 shipped at 0dabbd6..1d0d0a9 (3 ICS commits — schema + catalog + Modbus YAML). Postmortem captures: * 3 "What Broke" entries — all caught at design time or in seconds: (1) Scout A's 1.5× P3.2 estimate was 2-3× too low vs W2-γ `wc -l` measurements — caught by Wave-2 γ yardstick BEFORE shipping code. (2) Pydantic IcsProtocolMatch is FLAT — live canary AttributeError; print-statement fix only. (3) Anti-hardcode META-CANARY scope clarification (test files OK). * 14 safety-system catches across W2-γ Rule #28 yardstick + W2-β NEW attacks + Pydantic validators + catalog path cross-check + I4 cross- vendor collision + 17 paired Rule #46 META-CANARIES + combine=all_required discipline in v0 YAML. * 7 patterns: 1. Deep research + Wave-1 + Wave-2 methodology durable for Rule #52 extensions (Rule-of-Two now: P3.1 + P3.2; promoted to Rule-of-Three when Session 2 closes). 2. W2-γ Rule #28 yardstick CATCHES over-ambitious Wave-1 estimates BEFORE shipping code — load-bearing safety system for multi-session campaigns. 3. Multi-session FOUNDATION-first split works. 4. Sub-model + symmetric-reject + extra='forbid' pattern is Rule-of- Three now (TextFormatConstraint + SubstringInHeadConstraint + IcsStringInBinaryConstraint/IcsFunctionCodeSetConstraint). 5. Closed-grammar Pydantic Literals + free-string taxonomy + sibling subpackage = durable Rule #52 shape. 6. Multi-protocol-per-binary cardinality genuinely different from file-format single-format-per-blob. 7. `combine: all_required` discipline is operator-UX answer to W2-β §SC5-NEW-ICS-2 (combine-mode permissive composition attack). * 7 recommendations for Session 2: 1. Walker (Rule #39 triplet) + ORM + alembic + state machine 2. Walker auto-trigger + finding-source Rule #25 Shape-1 alignment 3. MCP tools category (Rule #44 lookup_*_across_firmwares mandatory) 4. Bundled string-scanner plugin + W2-β §SC5-NEW-ICS-7 I16 hot-reload mitigation in same commit 5. Remaining 2 protocols (DNP3 + S7Comm) as Rule #25 Shape-1 commits 6. CLAUDE.md Rule #52 Rule-of-Three promotion when full surface ships 7. Promote `.mex/patterns/add-signal-kind.md` recipe (Rule-of-Three threshold reached) ADAPTIVE_BACKLOG.md sync (Rule #21): * `ics-protocol-session1` row added to §5 completed with full commit SHA range + research artefact pointers + Session 2 plan * Last-updated bumped to 2026-05-20 afternoon Numbers: 3 ICS commits / +5,552 net / 114 new tests / 0 reverts / 0 quality gate blocks / 14 safety catches / 8 adversarial scouts dispatched. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
eastmadc
added a commit
that referenced
this pull request
May 22, 2026
Rule #52 instance #3 / Phase 3: new MCP tool category ``backend/app/ai/tools/ics_protocol.py`` with 4 tools per W2-α plan, surfacing the Phase 1 walker's JSONB result and Rule #33 .a state machine to MCP consumers. Includes ALL 5 W2-β §SC5-NEW-ICS-S2-* provenance gates inline (Wave-1 C + W2-β mandate). Tools (registered in ai/__init__.py → registry size 335 total): - ``trigger_ics_protocol_walk(firmware_id)`` — Rule #33 .a operator- trigger. Flips idle→queued; fires OUTER background runner via asyncio.create_task; Rule #33 .a 409 on in-flight. **W2-β §SC5-NEW-ICS-S2-ε (I35)**: filters by context.project_id — operator-A in P1 cannot trigger walker against firmware in P2 via switch_project. - ``list_ics_protocols(firmware_id)`` — reads ``ics_protocol_walk_result`` JSONB; surfaces consumer_warning when ``_result_passes_provenance_gates`` rejects (W2-β §SC5-NEW-ICS-S2-1 sister-provenance + §SC5-NEW-ICS-S2-β consistency_warning). - ``lookup_ics_protocol_across_firmwares(protocol_family, scope, limit)`` — CLAUDE.md Rule #44 MANDATORY cross-firmware aggregation. Applies: (a) SQL filter ``ics_protocol_walk_status='completed' AND result IS NOT NULL`` (W2-β §SC5-NEW-ICS-S2-3 + γ); (b) per-row Python gate via ``_result_passes_provenance_gates`` (schema_version=1 / provenance=walker / no consistency_warning); (c) ``supply_chain_signal`` flag requires match_count≥2 AND ≥1 matching firmware with curated-tier (_system/core) manifest_source (W2-β §SC5-NEW-ICS-S2-γ I30 — operator-tier-only matches do NOT trigger the signal). - ``describe_ics_protocol_anomalies(firmware_id)`` — operator-UX surface; flags multi_protocol (3+ families), mid_walk_catalog_drift (W2-β §SC5-NEW-ICS-S2-β), non_walker_provenance (W2-β §SC5-NEW-ICS-S2-1), walker_errors. Test battery (Rule #46 paired META-CANARIES + Rule #35b live canaries against make_live_db): - test_register_ics_protocol_tools_registers_four: registry sanity - test_trigger_ics_protocol_walk_409_on_in_flight: Rule #33 .a conflict - test_trigger_ics_protocol_walk_project_scope_filter: §SC5-NEW-ICS-S2-ε - test_trigger_ics_protocol_walk_requires_active_project: defensive - test_list_ics_protocols_consumer_warning_on_provenance_fail: §SC5-NEW-ICS-S2-1 — surfaces consumer_warning when provenance hostile - test_list_ics_protocols_handles_non_completed_status: hint shape - test_lookup_across_firmwares_filters_failed_rows: §SC5-NEW-ICS-S2-3 - test_lookup_across_firmwares_filters_legacy_schema_version: §SC5-NEW-ICS-S2-ι - test_lookup_across_firmwares_supply_chain_signal_requires_curated: §SC5-NEW-ICS-S2-γ I30 — operator-tier-only does NOT trigger flag - test_lookup_across_firmwares_supply_chain_signal_fires_when_curated: paired canary — curated tier ≥2 DOES trigger flag - test_describe_anomalies_surfaces_consistency_warning: §SC5-NEW-ICS-S2-β - test_describe_anomalies_multi_protocol_threshold: operator-UX All 12 MCP tests + 936 broader sweep passed: docker compose exec -T backend uv run pytest tests/test_ics_protocol_mcp.py -q → 12 passed in 8.37s + broader ICS + reaper + normaliser + auth-gate sweep: 936 passed Tenancy note: scope='global' is operator-owned cross-project introspection in single-tenant wairz; future multi-tenant deploy MUST acquire context.permitted_project_ids per the Rule #44 Rule-of-Nine docstring direction (consistent with linux_systemd, linux_journald, + other cross-firmware tools). Phase 3.B (REST router + TIER_A_LIGHT_ACK + 202-polling) DEFERRED — W2-γ marked optional ("HTTP endpoint optional; could compress to 1 commit"). Frontend page (Scout D's project sub-route surface) is also deferred to a follow-up session; MCP-only access is sufficient for the walker → Rule #44 cross-firmware aggregation path. Phase 4 (next): Bundled string_scanner plugin + freeze_plugin_registry with W2-β §SC5-NEW-ICS-S2-α MappingProxyType + AST pre-import scan hardening + Rule #21 backfill to file_format_catalog. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
eastmadc
added a commit
that referenced
this pull request
May 22, 2026
…W2-β §SC5-NEW-ICS-S2-α HARDENED freeze (Phase 4) Rule #52 instance #3 / Phase 4: closes Session 1 W2-β §SC5-NEW-ICS-7 (hot-reload × plugin module-level shadow) — the scariest unmitigated attack identified by Session 1 deep-research. Ships with W2-β §SC5-NEW-ICS-S2-α HARDENED shape (Wave-2 β cross-feature critique explicit recommendation): MappingProxyType wrap + closure-capture gate + freeze sentinel + namespace-disjointness collision check. Resolver plugin infrastructure (app/services/ics_protocol_catalog/ resolver.py): - IcsProtocolMatcherProto Protocol — typed plugin contract; cost_class + protocol_families + detect(blob_head, path, size, context) signature. - Private _PLUGIN_REGISTRY mutable dict; PRIVATE — never re-exported. - Public PLUGIN_REGISTRY = MappingProxyType(_PLUGIN_REGISTRY) — read-only view. Direct ``PLUGIN_REGISTRY[x] = y`` writes raise TypeError. CLOSES §SC5-NEW-ICS-S2-α: hostile bundled plugin ``from ... import PLUGIN_REGISTRY; PLUGIN_REGISTRY["x"] = matcher`` attack now fails at the proxy layer (NOT just the freeze check). - register_matcher(name, matcher) — three gates: freeze sentinel, namespace-disjointness collision, closure-capture rejection. - _closure_capture_check (W2-β §SC5-NEW-ICS-S2-ζ): rejects matchers whose detect() callable captures AsyncSession/Settings/ContextVar/ ToolContext via closure (request-scope leak prevention). - freeze_plugin_registry() flips sentinel; _unfreeze_plugin_registry_for_tests for test isolation only. Bundled string_scanner plugin (NEW app/services/ics_protocol_catalog/plugins/string_scanner.py): - Stateless StringScannerPlugin — closure-clean (no captured state). - Coarse byte-needle signatures for modbus_tcp / dnp3 / s7comm — detects library-symbol patterns the closed-grammar string_in_binary_constraint cannot express compactly. Plugin discovery (NEW app/services/ics_protocol_catalog/plugins/__init__.py): - register_default_plugins(freeze=True) — static imports of bundled plugins; no importlib against operator-controlled name strings (defense against §SC5-NEW-ICS-S2-α dynamic-import attack vector). Lifespan wire (app/main.py): - register_default_plugins(freeze=True) called AFTER LOLDrivers probe + BEFORE yield. Order matters — the freeze gate is the security boundary; calling after yield exposes a startup-to-first-request window. Defensive try/except so plugin registration failure does NOT block startup — walker degrades gracefully to closed-grammar YAML detection only. Rule #46 paired META-CANARIES (test_ics_protocol_plugin.py, 13 tests): - test_plugin_registry_is_mappingproxytype_read_only: type assertion - test_mappingproxytype_gate_actually_blocks_direct_dict_write: paired canary — synthesizes hostile direct write; confirms TypeError - test_register_matcher_pre_freeze_succeeds: paired canary (gate doesn't degenerate to always-reject) - test_register_matcher_post_freeze_raises: §SC5-NEW-ICS-S2-α primary mitigation; RuntimeError on post-freeze write - test_freeze_does_not_block_existing_lookups: defensive — reads still work post-freeze - test_register_matcher_rejects_async_session_closure_capture: §SC5-NEW-ICS-S2-ζ — synthesizes hostile matcher with AsyncSession in __closure__; confirms ValueError - test_register_matcher_accepts_stateless_matcher: paired canary - test_register_matcher_rejects_protocol_family_collision: namespace disjointness (analog of file_format A7) - test_register_default_plugins_registers_string_scanner: smoke - test_register_default_plugins_freezes_when_requested: lifespan contract - test_string_scanner_plugin_detect_returns_hits_on_modbus_signature: plugin functional smoke - test_string_scanner_plugin_returns_none_on_clean_binary: paired - test_main_py_lifespan_imports_and_calls_register_default_plugins: Rule #46 META-CANARY — confirms main.py call shape + BEFORE-yield textual ordering Phase 4 test sweep: 13 passed in 0.48s; broader Phase 1-4 + baseline sweep: 952 passed. DEFERRED per W2-β recommendation (queued in Phase 6 postmortem): - AST pre-import scan of plugin module source (complex; covered partially by closure-capture gate + MappingProxyType wrap) - Rule #21 backfill to file_format_catalog (same MappingProxyType + closure-capture hardening) — file_format precedent uses bare dict shape; backfill is a Rule-of-Two sweep but ICS-S2 scope deferred it; documented in Phase 6 postmortem as follow-up. Phase 5 (next): DNP3 + S7Comm production YAML manifests as Rule #25 single-slice commits (one per protocol per Rule #25). Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
eastmadc
added a commit
that referenced
this pull request
May 22, 2026
…hase 5.B) Rule #52 instance #3 / Phase 5.B — Rule #25 per-piece commit: ships the third + final v0 ICS protocol catalog production manifest, plus the cross-protocol disjointness matrix tests that require both DNP3 + S7Comm YAMLs present. S7Comm (Siemens SIMATIC S7 over TPKT/COTP/TCP port 102) detector signals: - string_in_binary needle set: 's7comm' / 'snap7' / 'libsnap7' / 'libs7' (case-insensitive; combine=any min_count=1) - port_signature: 102 (IANA-registered ISO-TSAP; LE uint16) - function_code_set: 11 S7 Job/Userdata PDU codes (0x04 Read Var / 0x05 Write Var / 0x1A-0x1F Request Download to End Upload / 0x28 PLC Control / 0x29 PLC Stop / 0xF0 Setup Communication) — min_count=3 within 512-byte window per W2-β A8 floor. output.vendor='siemens' / vendor_product='simatic_s7' carries family- level attribution; specific S7-1500 vs S7-300 version pinning is forward-prepared via protocol_version (null for legacy S7Comm; future v1 'v3' for S7Comm-Plus on S7-1200/1500). W2-β §SC5-NEW-ICS-2 mitigation: combine=all_required prevents port-102-alone false positives (other ISO-TSAP services on port 102). Banner + FC table co-requirement disambiguates. Tests (tests/test_ics_protocol_dnp3_s7comm_e2e.py): - test_production_catalog_loads_s7comm_v0: load smoke + vendor attribution - test_s7comm_resolves_all_three_signals_fire: happy path - test_s7comm_rejects_port_only_no_iso_tsap_false_positive: §SC5-NEW-ICS-2 - test_modbus_blob_does_not_cross_match_dnp3_or_s7comm: cross-protocol disjointness (Modbus FCs 0x01-0x06 overlap with DNP3 but port + banner disambiguates under all_required) - test_dnp3_blob_does_not_cross_match_modbus_or_s7comm: matrix - test_s7comm_blob_does_not_cross_match_modbus_or_dnp3: matrix - test_multi_protocol_firmware_matches_all_three: multi-protocol HMI cardinality (Session 1 postmortem Pattern #6 contract — resolve_all returns list[IcsProtocolMatch] supporting multi-family detection) 7 tests pass in 0.59s; combined Phase 5 sweep (5.A + 5.B) = 12 passed. Phase 6 (next): Rule #52 Rule-of-Three promotion in CLAUDE.md + .mex/context/conventions.md mirror per Rule #21 + .mex/patterns/ add-signal-kind.md recipe + Session 2 postmortem + /citadel:learn. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
eastmadc
added a commit
that referenced
this pull request
May 22, 2026
… + postmortem (Phase 6) Rule #52 instance #3 / Phase 6 — final commit of the ICS protocol catalog Session 2 campaign. Promotes CLAUDE.md Rule #52 from Rule-of-Two to **Rule-of-Three DURABLE BEYOND DEBATE** with ICS protocol catalog as worked example #3 alongside bare-metal MCU (instance #1, 2026-05-19) and file-format YAML registry (instance #2, 2026-05-19). CLAUDE.md changes: - Worked example #3 added (Rule-of-Three) — full surface description: 11 closed Literals + 3 production YAMLs (modbus_tcp + dnp3 + s7comm) + Rule #39 walker triplet + Rule #44 cross-firmware MCP + HARDENED plugin escape hatch (MappingProxyType + closure-capture + freeze) + DUAL reaper + 5 finding sources + 80+ Rule #46 paired META-CANARIES + all 10 §SC5-NEW-ICS-S2 mitigations. - Methodology block extended to Rule-of-Four (P3.1 + P3.2 + ICS S1 + ICS S2 — across 4 applications W2-β surfaced 24 cross-feature attacks Wave-1 single-axis scouts architecturally couldn't see). - "Promotable to Rule-of-Three" → "Promotable to Rule-of-Four"; promotion date 2026-05-19 → 2026-05-22. .mex/context/conventions.md mirror (Rule #21): - Verify Checklist Rule #52 entry updated to Rule-of-Three with ICS as worked example #3; methodology refinement extended to cover all 4 applications. .mex/patterns/add-signal-kind.md (NEW recipe — Rule-of-Three threshold reached: P3.2.b TextFormatConstraint + P3.x SubstringInHeadConstraint + Session 1 IcsStringInBinaryConstraint / IcsFunctionCodeSetConstraint): - Codifies the 4-element pattern for adding a new signal kind to a Rule #52 closed-grammar catalog: closed Literal + sub-model with extra='forbid' + symmetric-reject validator + evaluator in the closed dispatch table + Rule #46 paired META-CANARY (exhaustive + anti-hardcode AST + paired gate canary). - Gotchas: cross-stack alignment ships ONE commit per Rule #25; cost-class is load-bearing for resolver cost-sort; YAML schema lock-step on Literal value list changes. .planning/postmortems/postmortem-ics-protocol-session2-2026-05-22.md (NEW): - Full session narrative: Wave-1 + Wave-2 dispatch, 11-commit plan (10 shipped + this Phase 6), 0 reverts, bisect-clean, 980/980 test sweep green. - 3 failures documented (alembic ID collision; statusConfig apostrophe parser; cross-protocol test split) — all caught at design time, 0 production impact. - 14 safety catches across 30+ individual gate fires. - 5 recommendations (4 future-session follow-ups; 1 in this commit). - 10 W2-β §SC5-NEW-ICS-S2-α..κ attacks catalogued with mitigations shipped or deferred-with-rationale. Verified end-to-end: - 980 tests pass across all ICS phases + baseline META-CANARIES (auth-gate, reapers, sbom_status_alignment, background_task_sweep) - No regressions; bisect-clean across all 10 commits 0de1eba..cabb298 - DB CHECK constraints + alembic migrations applied + verified via psql column inspection + ck_findings_source 5 new ICS sources - Rule #46 paired META-CANARIES across all gates fire on synthetic violations + paired canaries confirm gates don't degenerate to always-reject Deferred follow-ups (documented in postmortem): - file_format_catalog backfill to MappingProxyType + closure-capture hardening (Rule #21 mirror sweep — same §SC5-NEW-ICS-S2-α attack surface exists in the bare-dict file_format precedent) - REST endpoint + frontend page (Scout D's /projects/{id}/ics-protocols sub-route — MCP access is sufficient for v0 ship) - AST plugin-source pre-import scan (W2-β nice-to-have secondary defense beyond MappingProxyType + closure-capture) - Feedback memory update: promote feedback_wave2_cross_feature_methodology to Rule-of-Four Session totals: 10 commits (0de1eba..[this]) / +4,708 net LOC / 80 new tests / 0 reverts / W2-γ projected 5,569 — actual -29% under midpoint due to Scout B's template-copy discipline / Rule-of-Three DURABLE BEYOND DEBATE achieved. Run /citadel:learn ics-protocol-session2-2026-05-22 next. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
eastmadc
added a commit
that referenced
this pull request
May 22, 2026
Prepends ICS protocol catalog Session 2 closure entry to the Last-updated chain. CLAUDE.md Rule #52 promoted to Rule-of-Three DURABLE BEYOND DEBATE with ICS as worked example #3. Records: - 11 commits (0de1eba..c988c15) / +4,798 net LOC / 80 new tests / 0 reverts / bisect-clean / 980-test sweep green - W2-γ SINGLE-SESSION verdict HONORED (actual -14% under midpoint) - Wave-1+Wave-2 methodology now Rule-of-Four (24 W2-β attacks surfaced across 4 applications) - Deferred follow-ups: file_format_catalog backfill to MappingProxyType (Rule #21 mirror sweep); REST router + frontend page; AST plugin- source pre-import scan - Session 3 (Fix #9 full Rule #52 extraction-strategy refactor) queued as Rule-of-Four north star Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
eastmadc
added a commit
that referenced
this pull request
May 29, 2026
…reaper Commit 1 of 8 — the migration + model columns + dual-reaper registration for the C1 generic kernel-config EXTRACTION walker. The column + reaper are one logical unit (folded together per R50.2 build-sequence note — else test_walker_reaper_configs_size_lock_matches_firmware_model goes RED between commits, breaking bisect-clean). DISTINCT from the existing kernel_config_audit_* family (linux_kernel_hardening_walker). C1 is the UPSTREAM extraction layer that guarantees metadata.kernel_config is populated cross-packaging so the DOWNSTREAM kernel_config_audit walker fires UNCHANGED. - alembic e3f4a5b6c7d8 (revision ID picked distinct from the taken d2e3f4a5b6c7 per the a51b15a collision lesson): 5 columns + ck_firmware_kernel_config_walk_status CHECK (Rule #33 .c). - firmware.py: 5 mapped_column declarations with a docstring distinguishing walk-extraction vs audit-consumption + the Rule #47 ordering contract. - walker_registry.py: DUAL reaper registration (STATE_MACHINE explicit literal + WALKER via _walker_reaper) per the ICS precedent + Scout-E suffix-introspection mandate. Docstring 28->29 (Rule #21). - test_main_lifespan_reapers.py: size-lock STATE_MACHINE 10->11, WALKER 28->29 (R50.2 S1 — anchored to TEST constants, not stale docstrings). Migration applied (Rule #20 docker cp + alembic upgrade head); full backend+worker+migrator rebuild done (Rule #8/#20 class-shape). 16/16 test_main_lifespan_reapers green in-container. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
eastmadc
added a commit
that referenced
this pull request
May 29, 2026
Commit 6 of 8 — register auto_kernel_config_walk_firmware_safe in WALKER_AUTO_TRIGGERS so C1 auto-fires post-detection, placed BEFORE auto_kernel_config_audit_firmware_safe so the metadata back-fill precedes the downstream KSPP audit read. - walker_registry.py: import + list insert (C1 runner at index 11, audit at index 12 — verified). Sequential dispatch in _fire_walker_auto_triggers + _run_hardware_firmware_detection_safe guarantees the ordering (same precedent as memory_image_enumerator → windows_info). AUTO_TRIGGERS 31 → 32. - firmware_service.py: docstring 27 → 32 safe-runners (Rule #21 docstring-sync; count authoritative via len(get_walker_auto_triggers())). - test_kernel_config_walker.py: test_c1_runner_fires_before_audit_runner asserts C1 is registered AND its index < the audit runner's index (Rule #47 ordering canary — without it the audit reads metadata.kernel_config before C1 back-fills it and phone-class firmware audits nothing). Rule #47 consumer-hook enumeration: BOTH the legacy _run_hardware_firmware_detection_safe (unpack.py:186) AND the new _post_process_pipeline (firmware_service.py:881) iterate get_walker_auto_triggers() — both pick up C1, no orphan-state trap. Validation: 37/37 (walker incl. ordering + reaper + auto-trigger-bridge) green in-container. AUTO_TRIGGERS=32, C1 idx 11 < audit idx 12. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
eastmadc
added a commit
that referenced
this pull request
May 29, 2026
…ring (piece 5/6) Rule #47 consumer-hook wiring — append auto_module_reachability_walk_firmware_safe to WALKER_AUTO_TRIGGERS (33 safe-runners now), placed AFTER auto_kernel_config_walk_firmware_safe so C1's metadata.kernel_config back-fill precedes C2's builtin_y_from_config read (sequential dispatch in _fire_walker_auto_triggers / _run_hardware_firmware_detection_safe). No per-walker edit in _post_process_pipeline needed — the pipeline already iterates the WALKER_AUTO_TRIGGERS registry list (Rule #42 factoring), so the single list append IS the full wiring. firmware_service docstring count synced 32->33 (Rule #21). Tests (31/31 green): test_c2_runner_registered_in_walker_auto_triggers (the 847eae9 orphan-state guard) + test_c2_runner_fires_after_c1_kernel_config (index ordering) + the full walker suite + the reaper size-locks (WALKER_AUTO_TRIGGERS=33, WALKER_REAPER=30, STATE_MACHINE=12). Ruff clean. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
eastmadc
added a commit
that referenced
this pull request
Jun 8, 2026
… + #54 (derived-artifact drift) Promoted from the cra-exploitability-deep-review campaign via an adversarial 3-persona rule-debate (process/rule-clarity, security-PSE/axiom, tooling/enforceability). Both verdicts: land-with-edits; all must-fixes applied. - Rule #53 EXTENDS Rule #46 to the RECOGNIZER side: a substantiation gate must match POSITIVE EVIDENCE, never a bare disposition/rule-id tag (else it launders). Two-part resolved-skip test; Axiom-4 binding (never key a risk-clearing recognizer to a mutable runtime annotation); wairz security-gate analog (#36/#45/#37 must re-derive proof, not trust signed=true/safe=true labels). Rule-of-One-plus, self-introduced + caught by self-audit (617 R47-L1 launder/un-launder primary). - Rule #54 derived-artifact drift: derive-don't-duplicate + regenerate ALL representations on source change + gate cross-representation consistency WITH a source-sanity floor (a green parity gate proves AGREEMENT, not CORRECTNESS). Niche carve-out vs #47 (reacting code) / #35c (read-boundary normalize). NOT-APPLY boundary for dated/archived captures. Rule-of-Two (CDX/mirror VEX drift + hand-typed-figure drift). Wairz anchor: #9 frontend Record<Type> maps, generated SBOM exports, the #21 doc mirror. Both rules cite REAL, GREEN gates (shipped in sibling cve-assessment-framework b0aab59a FIRST) so they don't describe aspirational enforcement — avoiding the Rule #35a verification-artifact-that-lies the rules themselves warn against. Rule #21 mirror into .mex/context/conventions.md Verify Checklist + last_updated bump in this same commit.
ee7b52a to
a8d2fb9
Compare
eastmadc
added a commit
that referenced
this pull request
Jun 12, 2026
…) per δ postmortem Two CLAUDE.md Learned Rules extended in response to the windows-coverage-godmode Phase δ postmortem (2026-05-09): **Rule #8 — Rebuild worker AND migrator whenever you rebuild backend.** Pre-emptively codified from δ.5 antipattern #2 + "What Broke" #5 (Rule-of-One). The migrator init container shares the Dockerfile + alembic versions tree with backend + worker; when it boots first using a stale image (compose dependency ordering), it can't find new revisions and exits 255, blocking backend + worker startup. δ.9 hit this when `docker compose build --pull backend worker` succeeded but `up -d` then failed on `Can't locate revision identified by 'd5a6b7c8d9e0'`. Codified the migrator extension here rather than waiting for a Rule-of-Two — the failure mode is structurally identical to worker (shared Dockerfile + versions tree); waiting for recurrence buys nothing. Companion guidance added: post-rebuild `docker compose ps` to confirm all expected services are running. δ.9 antipattern #6 caught a frontend container that exited during the failed-migrator cascade — docker compose's dependency graph can take down healthy services when an init container fails. ~10 s recovery via `up -d frontend`. **Rule #38 — Bash absolute-path discipline + catch-and-correct mid-flow.** Extended Rule #38 with a "Catch-and-correct mid-flow" subsection derived from δ.9 antipattern #5. β.10 + β.12 were the original Rule-of-Two incidents (CWD drift after `cd backend && uv run` caused git commands to resolve against `backend/backend/...`); δ.9 was a mid-flow catch — the agent ran `pwd` self-inspection after a `cd /home/dustin/code/wairz/backend && uv run python -c "..."` invocation, noticed the drift, and reset with explicit `cd /home/dustin/code/wairz` BEFORE any git command tripped on it. Net 0 incidents in the commit log; the catch validates the discipline rather than violating it. The catch-and-correct subsection codifies the recovery pattern: once you notice a `cd` has been issued, the very next Bash invocation should be either `cd /home/dustin/code/wairz` or use absolute-path forms for everything that follows. `pwd` self-check costs ~1 s; the alternative (a git command resolving against `backend/backend/...` and producing `fatal: ambiguous argument`) costs ~30 s to recover. Subshell form `( cd backend && uv run pytest ... )` is also documented as preventing drift at the source — the `cd` is scoped to the parens and doesn't leak into the next call. Prefer the subshell shape over a bare `cd backend && uv run ...`. **Mirror discipline (Rule #21):** Both rules are mirrored to `.mex/context/conventions.md` Verify Checklist in the same commit: - "Rebuild parity" item updated to require all three (backend + worker + migrator) and reference the δ.9 frontend cascade. - "Bash absolute-path discipline" item updated to Rule-of-Three (β.10 + β.12 + δ.9) and document the mid-flow catch-and-correct. - `last_updated` frontmatter touched. Refs: - CLAUDE.md Rule #21 (mirror discipline) - .planning/postmortems/postmortem-windows-coverage-godmode-delta-2026-05-09.md (rec #2 + "What Broke" #2/#5/#6) - .planning/knowledge/windows-coverage-godmode-delta-2026-05-09-antipatterns.md (#2, #5, #6)
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Bumps idna from 3.13 to 3.15.
Changelog
Sourced from idna's changelog.
Commits
af30a09Release 3.1530314d4Pre-release 3.15rc005d4b21Merge pull request #237 from kjd/convert-docs-to-markdown2987fdbConvert README and HISTORY from reStructuredText to Markdown59fa800Merge pull request #236 from kjd/dependabot/github_actions/actions-f3e34333eadef6983Merge branch 'master' into dependabot/github_actions/actions-f3e34333eabbd8004Merge pull request #234 from StanFromIreland/patch-1edd07c0Bump github/codeql-action from 3.35.2 to 4.35.2 in the actions group5557db0Merge branch 'master' into patch-1f11746cMerge pull request #235 from StanFromIreland/patch-2Dependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting
@dependabot rebase.Dependabot commands and options
You can trigger Dependabot actions by commenting on this PR:
@dependabot rebasewill rebase this PR@dependabot recreatewill recreate this PR, overwriting any edits that have been made to it@dependabot show <dependency name> ignore conditionswill show all of the ignore conditions of the specified dependency@dependabot ignore this major versionwill close this PR and stop Dependabot creating any more for this major version (unless you reopen the PR or upgrade to it yourself)@dependabot ignore this minor versionwill close this PR and stop Dependabot creating any more for this minor version (unless you reopen the PR or upgrade to it yourself)@dependabot ignore this dependencywill close this PR and stop Dependabot creating any more for this dependency (unless you reopen the PR or upgrade to it yourself)You can disable automated security fix PRs for this repo from the Security Alerts page.