Commit 56bf14e
feat(ics-protocol): 4 MCP tools incl. Rule #44 cross-firmware (Phase 3)
Rule #52 instance digitalandrew#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 digitalandrew#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 digitalandrew#33 .a operator-
trigger. Flips idle→queued; fires OUTER background runner via
asyncio.create_task; Rule digitalandrew#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 digitalandrew#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 digitalandrew#21 backfill to file_format_catalog.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>1 parent cf6db33 commit 56bf14e
3 files changed
Lines changed: 1124 additions & 0 deletions
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
13 | 13 | | |
14 | 14 | | |
15 | 15 | | |
| 16 | + | |
16 | 17 | | |
17 | 18 | | |
18 | 19 | | |
| |||
110 | 111 | | |
111 | 112 | | |
112 | 113 | | |
| 114 | + | |
| 115 | + | |
| 116 | + | |
| 117 | + | |
113 | 118 | | |
0 commit comments