test(channels): complete delivery variant evidence - #6885
Conversation
|
Caution The consumer version of Gemini Code Assist on GitHub has been sunset. All code review activity has officially ceased. |
📝 WalkthroughSummary by CodeRabbit
WalkthroughSlack and Telegram E2E coverage now models exact delivery addresses, validates structured provider payloads and pairing state, and enforces source-citable evidence for outbound channel surfaces. Scheduled Slack tests separately verify default and override targets exactly once. ChangesExternal delivery evidence
Estimated code review effort: 4 (Complex) | ~45 minutes Sequence Diagram(s)sequenceDiagram
participant SlackWebhook
participant ExtensionDelivery
participant SlackProvider
SlackWebhook->>ExtensionDelivery: threaded app_mention event
ExtensionDelivery->>SlackProvider: postMessage with channel and thread_ts
SlackProvider-->>ExtensionDelivery: structured delivery payload
sequenceDiagram
participant TelegramWebhook
participant ExtensionDelivery
participant TelegramProvider
participant PairingRouter
TelegramWebhook->>ExtensionDelivery: forum-topic or chat message
ExtensionDelivery->>TelegramProvider: sendMessage with chat and topic identifiers
TelegramProvider-->>ExtensionDelivery: structured delivery payload
PairingRouter->>PairingRouter: report pairing status before and after unpair
Possibly related issues
Possibly related PRs
🚥 Pre-merge checks | ✅ 4✅ Passed checks (4 passed)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
|
🚅 Deployed to the ironclaw-pr-6885 environment in ironclaw-ci-preview
|
🔎 Review · PR #6885
1 actionable findings →Reviewed the complete trusted comparison. The added delivery journeys exercise the intended Slack and Telegram paths, but the new mechanical evidence inventory does not verify that its declared addresses match the cited Rust assertions. Automatic · PR opened · attempt 1 of 3 · completed in 1m 58s Run details
|
There was a problem hiding this comment.
🔍 Review complete · PR #6885
💬 1 finding
Reviewed the complete trusted comparison. The added delivery journeys exercise the intended Slack and Telegram paths, but the new mechanical evidence inventory does not verify that its declared addresses match the cited Rust assertions.
Findings
- 🟡 Low · Delivery metadata is not tied to the cited assertion —
tests/e2e/scenarios/test_journey_coverage.py:366-383
Details are attached to the relevant diff.
Validation and technical details
- Inspected the full trusted base/head PR delta via the merge-base comparison: 5 files, 438 insertions, 49 deletions.
- Reviewed all changed files and surrounding journey inventory, Rust delivery helpers, pairing flow, provider request capture, and composition test guidance.
git diff --check refs/ironloop/base...refs/ironloop/headpassed.- Focused tests could not be executed in this checkout: the bundled pytest environment is absent, system Python has no pytest module, and
cargois unavailable. - Base:
main - Head:
codex/ws8-delivery-evidenceat23eb40b - Run:
19c8f12a-6811-4085-897d-694c84a4f8b5
Coverage ratchetReborn integration-tier coverageLine coverage (Reborn crates): 85.5% — 316868 / 370600 lines Per-crate breakdown (60 crates, lowest-covered first)
This table itself is informational and never gates the PR on its own — not the percentage, not the per-crate holes, not the 0-coverage callout. A separate coverage ratchet (dry-run until enforce=true; see tests/integration/coverage-floor.toml) can fail the build on specific configured floors. Exemptions (3 entry/entries excluded from the accounting above)
|
23eb40b to
9f81e64
Compare
|
Caution The consumer version of Gemini Code Assist on GitHub has been sunset. All code review activity has officially ceased. |
🔎 Review · PR #6885
The target changed before this Run could finish. Automatic · PR opened · attempt 0 of 3 · cancelled after <1s Run details
|
There was a problem hiding this comment.
Actionable comments posted: 2
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@tests/e2e/journey_cases.py`:
- Around line 347-352: Remove ObservableAssertion.CREDENTIAL_INJECTION from the
assertions for the row citing
unbound_telegram_actor_pairs_via_web_minted_code_then_turns_attribute_to_the_paired_user_impl,
unless that integration test is updated to explicitly verify host-side token
substitution; keep the row’s assertions limited to behaviors covered by the
cited test.
In `@tests/e2e/scenarios/test_journey_coverage.py`:
- Around line 686-695: Update the threaded-evidence check in the journey
coverage test to inspect each adapter’s declared manifest or trait capability
rather than searching channel.rs text for “thread_anchor”. Resolve adapter
metadata through the existing surface/manifest discovery mechanism so valid
channels are not rejected due to hardcoded crate/file naming, and require
address.thread_anchor evidence only when that declared capability indicates
threaded delivery.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Path: .coderabbit.yaml
Review profile: ASSERTIVE
Plan: Pro Plus
Run ID: 45732a8b-5b71-4f55-9d31-eb824e9cf6bd
📒 Files selected for processing (5)
crates/ironclaw_reborn_composition/tests/trigger_poller_e2e.rstests/e2e/journey_cases.pytests/e2e/journey_types.pytests/e2e/scenarios/test_journey_coverage.pytests/integration/extension_delivery.rs
9f81e64 to
b762361
Compare
There was a problem hiding this comment.
Actionable comments posted: 2
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@tests/e2e/scenarios/test_journey_coverage.py`:
- Around line 399-447: Update _rust_function_body extraction in the assertion
validation path to mask Rust comments while preserving string literals before
applying the binding and gating regex checks. Ensure commented-out declarations
or comparisons cannot satisfy checks for expected_conversation_id,
expected_thread_anchor, or expected_count, while literals remain available for
value validation.
In `@tests/integration/extension_delivery.rs`:
- Around line 691-710: Update assert_telegram_chat_delivery_evidence so the
unthreaded predicate distinguishes a missing message_thread_id from a present
non-integer value. Replace the current get(...).and_then(Value::as_i64)
comparison with a direct absence check while retaining the
expected_thread_anchor declaration and comparison required by the coverage gate.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Path: .coderabbit.yaml
Review profile: ASSERTIVE
Plan: Pro Plus
Run ID: 5e7ef519-e66c-4fd6-b489-92714afa307f
📒 Files selected for processing (5)
crates/ironclaw_reborn_composition/tests/trigger_poller_e2e.rstests/e2e/journey_cases.pytests/e2e/journey_types.pytests/e2e/scenarios/test_journey_coverage.pytests/integration/extension_delivery.rs
b762361 to
9944ea6
Compare
There was a problem hiding this comment.
Actionable comments posted: 1
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@tests/e2e/scenarios/test_journey_coverage.py`:
- Around line 709-717: Update the outbound capability assertion in the test loop
over _production_channel_capabilities so supports_threads must be explicitly
declared for every surface, rather than using
capabilities.get("supports_threads") and failing open when absent or misspelled.
Preserve the threaded evidence check for declared true values, and add or update
regression coverage that executes this enforcing test command and verifies
missing declarations fail.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Path: .coderabbit.yaml
Review profile: ASSERTIVE
Plan: Pro Plus
Run ID: f1dac8d5-5951-4091-96b7-8d86e13eaa3e
📒 Files selected for processing (5)
crates/ironclaw_reborn_composition/tests/trigger_poller_e2e.rstests/e2e/journey_cases.pytests/e2e/journey_types.pytests/e2e/scenarios/test_journey_coverage.pytests/integration/extension_delivery.rs
9944ea6 to
a52dd3c
Compare
There was a problem hiding this comment.
Actionable comments posted: 2
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (1)
tests/e2e/scenarios/test_journey_coverage.py (1)
179-242: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low valueRuff flags this scanner over the branch/statement budget.
PLR0912 (19 > 12) and PLR0915 (56 > 50) both point at Line 179 after the
preserve_stringsadditions. Splitting the raw-string and quoted-string scanning into a small position-returning helper brings it back under budget without changing the masking contract.🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@tests/e2e/scenarios/test_journey_coverage.py` around lines 179 - 242, Refactor _rust_code_without_comments_or_strings to extract raw-string and quoted-string scanning into a small helper that returns the next position and, when masking is required, updates the result while preserving newlines. Replace the corresponding string branches with the helper call, retaining the existing preserve_strings behavior and masking contract while reducing PLR0912 and PLR0915 counts.Source: Linters/SAST tools
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@tests/e2e/journey_cases.py`:
- Around line 412-424: The _production_channel_capabilities function indexes
manifest["id"] without validating that the manifest declares an id, causing an
opaque KeyError. Add a named assertion or equivalent explicit validation before
indexing manifest["id"], with a diagnostic message identifying the missing
top-level id and manifest_path, while preserving the existing capability mapping
behavior.
In `@tests/e2e/scenarios/test_journey_coverage.py`:
- Around line 464-470: Replace the try/except AssertionError/pass around
_rust_function_body in the delegate loop with
contextlib.suppress(AssertionError), and add the contextlib import. Preserve the
existing behavior of appending reachable delegate bodies while ignoring lookup
failures.
---
Outside diff comments:
In `@tests/e2e/scenarios/test_journey_coverage.py`:
- Around line 179-242: Refactor _rust_code_without_comments_or_strings to
extract raw-string and quoted-string scanning into a small helper that returns
the next position and, when masking is required, updates the result while
preserving newlines. Replace the corresponding string branches with the helper
call, retaining the existing preserve_strings behavior and masking contract
while reducing PLR0912 and PLR0915 counts.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Path: .coderabbit.yaml
Review profile: ASSERTIVE
Plan: Pro Plus
Run ID: 99c55db7-d26d-4fc1-847a-32a7acba026c
📒 Files selected for processing (5)
crates/ironclaw_reborn_composition/tests/trigger_poller_e2e.rstests/e2e/journey_cases.pytests/e2e/journey_types.pytests/e2e/scenarios/test_journey_coverage.pytests/integration/extension_delivery.rs
|
Caution The consumer version of Gemini Code Assist on GitHub has been sunset. All code review activity has officially ceased. |
🔎 Review · PR #6885
GitHub request failed IronLoop could not complete a required GitHub request. Automatic · PR opened · attempt 1 of 3 · failed after 1m 55s Failure details
|
There was a problem hiding this comment.
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (1)
tests/e2e/scenarios/test_journey_coverage.py (1)
410-411: 📐 Maintainability & Code Quality | 🟡 Minor | ⚡ Quick winAdd failure messages to these two asserts.
Every other assert in
_assert_delivery_address_is_citablecarries anf"{case.case_id}: ..."diagnostic; these two bare asserts will surface as an opaqueAssertionErrorwith no indication of which requiredObservableAssertionis missing or for which case.🩺 Add diagnostics
- assert ObservableAssertion.EXACT_DESTINATION in case.assertions - assert ObservableAssertion.EXACT_MUTATION_COUNT in case.assertions + assert ObservableAssertion.EXACT_DESTINATION in case.assertions, ( + f"{case.case_id}: delivery address evidence requires EXACT_DESTINATION" + ) + assert ObservableAssertion.EXACT_MUTATION_COUNT in case.assertions, ( + f"{case.case_id}: delivery address evidence requires EXACT_MUTATION_COUNT" + )🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@tests/e2e/scenarios/test_journey_coverage.py` around lines 410 - 411, The two assertions in _assert_delivery_address_is_citable must include case-specific diagnostic failure messages. Add f"{case.case_id}: ..." messages identifying the missing EXACT_DESTINATION and EXACT_MUTATION_COUNT ObservableAssertion respectively, matching the diagnostics used by the surrounding assertions.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Outside diff comments:
In `@tests/e2e/scenarios/test_journey_coverage.py`:
- Around line 410-411: The two assertions in _assert_delivery_address_is_citable
must include case-specific diagnostic failure messages. Add f"{case.case_id}:
..." messages identifying the missing EXACT_DESTINATION and EXACT_MUTATION_COUNT
ObservableAssertion respectively, matching the diagnostics used by the
surrounding assertions.
ℹ️ Review info
⚙️ Run configuration
Configuration used: Path: .coderabbit.yaml
Review profile: ASSERTIVE
Plan: Pro Plus
Run ID: 1009d890-759b-41ad-bea2-d6cefa973baa
📒 Files selected for processing (2)
tests/e2e/journey_cases.pytests/e2e/scenarios/test_journey_coverage.py
…idence # Conflicts: # tests/e2e/journey_types.py # tests/e2e/scenarios/test_journey_coverage.py
There was a problem hiding this comment.
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (1)
tests/e2e/scenarios/test_journey_coverage.py (1)
180-239: 🎯 Functional Correctness | 🟠 Major | 🏗️ Heavy liftDo not treat preserved string contents as executable Rust evidence.
With
preserve_literals=True,_assert_rust_assignmentand the subsequent regexes scan raw string payloads as well as code. A raw/error string containinglet expected_conversation_id = ..., the expected anchor comparison, andmatching.count()can therefore satisfy the gate without executable delivery assertions. Use token/AST-aware matching, or keep code masked and extract literal RHS values separately; add a regression containing code-looking strings.As per path instructions, delivery coverage must be backed by executable, cited journey evidence.
Also applies to: 394-460, 479-492
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@tests/e2e/scenarios/test_journey_coverage.py` around lines 180 - 239, Update _assert_rust_assignment and the subsequent delivery-coverage regex checks so preserved string contents cannot satisfy executable Rust evidence; keep code masked for token matching and extract literal RHS values separately when needed. Apply the same protection to the related checks and add a regression fixture containing code-looking raw/error strings, while requiring delivery coverage to come from executable, cited journey assertions.Source: Path instructions
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Outside diff comments:
In `@tests/e2e/scenarios/test_journey_coverage.py`:
- Around line 180-239: Update _assert_rust_assignment and the subsequent
delivery-coverage regex checks so preserved string contents cannot satisfy
executable Rust evidence; keep code masked for token matching and extract
literal RHS values separately when needed. Apply the same protection to the
related checks and add a regression fixture containing code-looking raw/error
strings, while requiring delivery coverage to come from executable, cited
journey assertions.
ℹ️ Review info
⚙️ Run configuration
Configuration used: Path: .coderabbit.yaml
Review profile: ASSERTIVE
Plan: Pro Plus
Run ID: 90ba0400-6968-41a8-92dd-e3a3f72b53ef
📒 Files selected for processing (3)
tests/e2e/journey_cases.pytests/e2e/journey_types.pytests/e2e/scenarios/test_journey_coverage.py
* test(channels): complete delivery variant evidence * test(channels): bind inventory to provider assertions * test(channels): align inventory with declared evidence * test(channels): harden exact evidence parsing * test(channels): fail closed on manifest metadata
Summary
message_thread_idsurvives normalization through coordinated provider delivery.Change Type
Linked Issue
Related #6524. Webhook ingress remains covered by #6828. Reconciled against open #6831, #6776, and #6364; none implements this caller-seam delivery evidence.
Validation
cargo fmt --all -- --checkcargo clippy --all --benches --tests --examples --all-features -- -D warnings— both touched targets are clean locally with-D warnings; GitHub's freshClippy (all-features)gate also passed.cargo build— not applicable: test-only change; both touched test targets compiled under Clippy and focused test execution.cargo test --features integrationif database-backed or integration behavior changed — test-only coverage change; focused libSQL integration cases pass. PostgreSQL provisioning was attempted and failed before scenario execution because no Docker daemon is reachable.review-prorpr-shepherd --fixwas run before requesting review —pr-shepherdreadiness pass completed; the full final diff was reviewed across correctness, security, architecture, test quality, and repository conventions.Test Strategy
User behavior: Replies from Slack threads and Telegram forum topics return to the exact originating channel/thread/topic once; Telegram unthreaded chat pairing status and unpair are durably observable; scheduled Slack DM/channel delivery stays exact.
Risk areas:
Tests added or updated:
tests/e2e/scenarios/test_journey_coverage.pymechanically validates production-supported outbound surfaces, opaque conversation IDs, optional thread anchors, exact count, and reachable named caller assertions.reborn_integration_extension_delivery.What the tests prove:
-1008675309, topic77, important content, provider-issued cleanup message ID, and exactly one final reply.C777, thread1710000200.000050, important content, injected credential, and exactly one final reply.D-TRIGGER-DEFAULTandC-TRIGGER-OVERRIDE.515151, authenticated statusconnected=true, durable unpair, statusconnected=false, and fresh thread after re-pair.thread_anchorsupport mechanically requires both threaded and unthreaded evidence.Commands run:
bash scripts/codebase-graph.sh status→ graph missing; immediately used targeted live-code/contracts per guidance.tests/e2e/.venv/bin/pytest -q tests/e2e/scenarios/test_journey_coverage.py→ 44 passed.cargo test -q -p ironclaw_reborn_integration_tests --test reborn_integration_extension_delivery 'slack_final_reply_flows_through_the_real_delivery_coordinator::case_1_libsql' -- --exact --nocapture→ 1 passed.cargo test -q -p ironclaw_reborn_integration_tests --test reborn_integration_extension_delivery 'telegram_update_becomes_a_turn_and_a_coordinated_reply::case_1_libsql' -- --exact --nocapture→ 1 passed.cargo test -q -p ironclaw_reborn_integration_tests --test reborn_integration_extension_delivery 'unbound_telegram_actor_pairs_via_web_minted_code_then_turns_attribute_to_the_paired_user::case_1_libsql' -- --exact --nocapture→ 1 passed.cargo test -q -p ironclaw_reborn_composition --test trigger_poller_e2e scheduled_trigger_results_reach_exact_slack_targets_once_across_restart -- --exact --nocapture→ 1 passed.cargo clippy -p ironclaw_reborn_integration_tests --test reborn_integration_extension_delivery -- -D warnings→ clean.cargo clippy -p ironclaw_reborn_composition --test trigger_poller_e2e -- -D warnings→ clean.cargo fmt --all -- --checkandgit diff --check→ clean.git merge origin/main→ conflicts injourney_types.pyandtest_journey_coverage.pyresolved by preserving both WS12 live/browser evidence and WS8 exact delivery-address evidence; merge commit09fb55723.git merge origin/mainat6535edc96→ WS9 state-machine and IronHub changes merged without additional file conflicts; merge commit7aeb1aa27.tests/e2e/.venv/bin/pytest -q tests/e2e/scenarios/test_journey_coverage.py tests/e2e/scenarios/test_product_surface_coverage.py→ 51 passed on the merged head.tests/e2e/.venv/bin/pytest -q tests/e2e/scenarios/test_state_machine_coverage.py→ 12 passed on the merged head.tests/e2e/.venv/bin/pytest -q scripts/ci/test_ws12_suite_shards.py scripts/ci/test_ws12_workflow_contracts.py scripts/ci/test_reborn_changed_coverage.py→ 19 passed, 36 subtests passed on the merged head.origin/main...HEADdiff → eight valid automated review findings fixed; no remaining known correctness, security, architecture, or test-quality findings.09fb55723→ 56 passed, 0 failed, 0 pending, 6 policy-selected skips. Fresh CI on current merge head7aeb1aa27is in progress.StorageMode::Postgres requires a reachable Docker daemon/ container connection failure.Railway follow-through:
Deployment failedon two consecutive heads, including a clean current-main rebase. Its third deployment on the final head succeeded, so no readiness blocker remains. If the failure recurs, the linked logs require an authenticated Railway account with membership in project76f27460-1806-4eed-b168-e9b150113141(service3d19f4f3-6060-4143-8faf-ef546ed6fb97, environmentfdfae749-b48a-43b0-a8b1-89b2f9aab672).Sabotage baseline:
threaded delivery is implemented but lacks exact evidence.message_thread_idpropagation failed the whole-path topic assertion.thread_tspropagation failed exact threaded delivery evidence.C-FAKE-STRUCTURED-PROBEfailed because it was not bound toexpected_conversation_id.expected_countfrom1to2failed because it no longer matched the inventory.Security Impact
None. Test-only changes preserve authenticated pairing routes, host-side credential injection, typed actor/subject identity assertions, and provider mediation.
Reborn Trust-Boundary Checklist
N/A: no production policy/evidence/trust-bearing types, prompt ingress, hashes, variants, serde fields, queues, errors, or runtime boundary names changed. Tests explicitly assert the existing authenticated pairing caller, normalized actor/account, credential injection, durable state, and mediated provider evidence.
Database Impact
None. No migrations or schema changes. libSQL integration evidence passes; PostgreSQL execution is blocked by unavailable Docker on this host and remains visible above.
Blast Radius
Test inventory metadata and the Slack/Telegram delivery integration fixtures. The fail-loud inventory parser intentionally permits a cited test or its direct
_impldelegate; a source-layout rename without updated evidence will fail the contract test.Rollback Plan
Revert commits
0d469e935,a52dd3ce1,d34f29c75,89427d61c, and88724e031; production runtime behavior and persistent schemas are unchanged.Review Follow-Through
Checkbox-to-test/PR map:
telegram_update_becomes_a_turn_and_a_coordinated_replyin this PR.slack_final_reply_flows_through_the_real_delivery_coordinatorin this PR.scheduled_trigger_results_reach_exact_slack_targets_once_across_restart, now exposed through named assertions in this PR.test_reborn_v2_text_turn_persists_thread_and_transcript_without_trace_filesremains inventory evidence; no new variant exists.Reviewer judgment requested on the intentionally narrow mechanical rule: delivery assertions must be called by the cited Rust test or its direct
_impldelegate.Automated review follow-through:
89427d61c. Each named Rust helper now bindsexpected_conversation_id,expected_thread_anchor, andexpected_count; the inventory verifies those exact bindings gate the provider evidence and mutation count.CREDENTIAL_INJECTIONlooks unsupported by the cited pairing test” — fixed ind34f29c75; the pairing row now claims only evidence asserted by its cited journey.thread_anchorwill over-trigger the threaded-evidence requirement” — fixed ind34f29c75; requirements now derive fromchannel.presentation.supports_threadsin production manifests.a52dd3ce1; comments are masked even when string literals are preserved, with a regression test.a52dd3ce1; Telegram chat, Slack DM, and Slack channel evidence now asserts direct absence of the provider thread/topic field.supports_threadsis absent” — fixed in0d469e935; missing, misspelled, and non-boolean declarations each fail a sabotage regression.idis indexed unguarded” — fixed in0d469e935; a malformed-manifest regression requires a non-empty string ID and path-specific diagnostic.contextlib.suppressfor delegate-body lookup” — fixed in0d469e935; behavior remains covered by the complete inventory suite.Review track: A (tests/chore)