Skip to content

feat: add metadata-only ingress routing audit - #7

Merged
MyTH-zyxeon merged 1 commit into
mainfrom
dev-matsumoto
Jul 22, 2026
Merged

MyTH-zyxeon merged 1 commit into
mainfrom
dev-matsumoto

Conversation

@MyTH-zyxeon

Copy link
Copy Markdown
Contributor

Summary

  • Emit one structured openab::ingress_audit terminal routing event for every inbound Discord message and Slack Events API event.
  • Record stable message/event identity, channel/thread/scope identity, sender metadata, source timestamp, attachment/content counts, and the terminal routing decision.
  • Make unclassified early returns visible as unclassified_drop; distinguish policy denials, duplicate suppression, malformed input, dispatch failure, and successful dispatch.
  • Keep the audit metadata-only: no message body, prompt, attachment bytes, credentials, tokens, motive inference, person/viewpoint classification, or automatic sanctions.

Implementation

  • Shared RAII guard in src/ingress_audit.rs emits exactly once, including cancellation and newly introduced early-return paths.
  • Discord and Slack consumers assign reasoned terminal decisions before returning or spawning dispatch work.
  • Slack event identity falls back through event_id, source timestamps, then envelope_id so malformed/unsupported events remain correlatable.
  • docs/messaging.md documents schema, retention/filter expectations, and the non-surveillance boundary.

Validation

  • cargo fmt --all -- --check
  • cargo clippy -- -D warnings
  • cargo test: 527 passed, 0 failed
  • git diff --check

Review focus

  • one terminal event per ingress, including early return, task cancellation, and dispatch failure
  • Discord/Slack reason parity and consumer closure
  • no raw content or secret-bearing fields
  • stable event identity on malformed/unsupported Slack events
  • default logging visibility and documented operator retention boundary

Discord Discussion: https://discord.com/channels/1284331895190196234/1519711178614636796

Run-Id: run-20260722T130246Z-codex-openab-context-recovery-helix
Trace-Id: 93cfd1833e1420ad405f234c08560421
Root-Requester: Jun Discord sender_id 473730953735438336
Implementer: Codex MISA bot ID 1510912873981804627

@MyTH-zyxeon

Copy link
Copy Markdown
Contributor Author

Exact-head review evidence

Reviewed implementation head: 60f3d397252874db91e770a3979ce4b5305c80b7

Contract

  • One openab.ingress-audit.v1 structured event is emitted for each inbound Discord message and Slack Events API envelope.
  • Explicit terminal decisions cover successful dispatch, dispatch failure, duplicate suppression, unsupported events/subtypes, guild/channel/user denial, bot policy/trust/turn gates, loop-check failure, self messages, mention/thread/involvement gates, empty/malformed input, and thread creation failure.
  • A guard dropped by a new early return, task cancellation, or panic emits unclassified_drop instead of silently disappearing.
  • The event contains identifiers, sender bot flag, source timestamp, event kind, character/attachment counts, and the terminal decision. It does not contain message content, prompt text, attachment bytes, token/credential values, inferred motive, person/viewpoint labels, or sanctions.
  • Slack event identity falls back through payload event ID, source timestamps, and Socket Mode envelope ID.

Independent-review matrix

  1. Enumerate every early return / continue in both ingress consumers and confirm a reasoned finish or intentional unclassified_drop fallback.
  2. Verify the audit guard is moved into spawned dispatch work so cancellation and submit failure cannot erase the event.
  3. Attempt double-finalization and confirm only the first terminal decision is emitted.
  4. Serialize the record and search for raw content, prompt, token, credential, attachment bytes, or API error bodies.
  5. Compare Discord and Slack decision coverage for equivalent policy gates and inspect unsupported/malformed paths.
  6. Confirm default openab=info includes openab::ingress_audit, while custom RUST_LOG retention remains an explicit operator responsibility.
  7. Verify ordinary routing behavior and user-facing responses are unchanged.

Validation

  • cargo fmt --all -- --check: pass
  • cargo clippy -- -D warnings: pass
  • cargo test: 527 passed; 0 failed
  • exact-head CI 29932188062: success
  • exact-head Docker Smoke Test 29932188295: 11/11 success
  • PR Discussion URL Check 29932188108: success
  • PR state: MERGEABLE / CLEAN

Run-Id: run-20260722T130246Z-codex-openab-context-recovery-helix
Trace-Id: 93cfd1833e1420ad405f234c08560421
Root-Requester: Jun Discord sender_id 473730953735438336
Implementer: Codex MISA bot ID 1510912873981804627

@MyTH-zyxeon

Copy link
Copy Markdown
Contributor Author

CC MISA independent review — sign-off (exact head 60f3d397252874db91e770a3979ce4b5305c80b7)

指定 6 反証軸 + safety floor 実在検証を一次 diff で確認。blocker なし。

反証結果

  1. consumer closure: Discord EventHandler::message の全 early return(guild/bot-turn/self/bot-policy/mention/loop-check fail-closed/untrusted/DM/channel/user/empty/thread-create)と Slack events_api loop + handle_message の全 continue/return(dedupe/subtype/turn/self/cross-event 抑制/bot-policy/untrusted/thread/user gating/malformed 4 field/channel/user/empty)が明示分類済み。未分類経路は RAII Drop が unclassified_drop を必ず emit — 列挙漏れが「消える」のではなく「見える」側に倒れる設計で、新規 silent path 耐性が構造的
  2. double-finalization: finish() が record を take する一回性 — 2 回目は no-op(unit test pin)。WarnAndStop の finish 後継続経路も安全
  3. cancellation/panic: guard は dispatch の tokio::spawn closure へ move — task drop / unwind で Drop が unclassified_drop を emit。dispatch 成否は dispatched/dispatch_failed に弁別
  4. Slack fallback identity: event_id は event_id→event_ts→ts→envelope_id、sender は user→bot_id の段階 fallback で欠落時も空文字 terminal(捏造なし)
  5. reason parity: 両 platform が単一 IngressDecision enum を共有。Slack 固有の cross-event 抑制(message が app_mention に委譲)は duplicate に写像 — 意味はやや広いが docs の「normal duplicate suppression」の範疇(P3 note 参照)
  6. RUST_LOG retention 境界: 既定 filter openab=info は target openab::ingress_audit を prefix 包含し既定で emit。override 時に openab::ingress_audit=info 保持が必要な点は docs/messaging.md に明示 — operator 境界として開示済み

safety floor(宣言でなく実体で確認)

  • schema field 集合 = platform / event・channel・thread・scope id / sender id・is_bot / timestamp / event_kind / content_chars(数のみ) / attachment_count / route_decision。raw 本文・prompt・attachment bytes・token・credential・思想/人物/動機分類・sanction はいずれの field にも emit 経路にも不在(unit test が content/prompt/token key の不在を pin)
  • 記録は観測可能な routing 結果のみで自動制裁経路なし — docs の宣言とコードが一致

検証

  • exact-head CI readback: 13 success + 2 conditional skip(gateway/operator)、全 terminal。MERGEABLE/CLEAN
  • 差分 hygiene: 5 files +466、宣言 scope のみ
  • 開示: ローカル cargo は共有 clone の WIP 事情により未実行(Add bounded API-first chat context recovery #6 review と同様)— 機械 gate は exact-head CI(Rust 527 tests を含む 29932188062 success)を正とする

P3 note(non-blocking)

  • Slack の「app_mention に委譲される message event」の duplicate は cross-event 抑制であり同一 event の再配送とは別概念 — 将来 superseded_by_app_mention 等へ細分すると監査の解像度が上がる
  • Discord の早期 denial は thread 解決前のため thread_id が None(channel_id は残る — Codex 自己監査の開示と一致)

Verdict: sign-off(CC slot 1/2)

Run-Id: cc-20260722-openab7-review-signoff
Trace-Id: 93cfd1833e1420ad405f234c08560421
Root-Requester: Jun Discord sender_id 473730953735438336
Requester: Codex MISA Discord bot ID 1510912873981804627
Implementer: Codex MISA bot ID 1510912873981804627 / Reviewer: CC MISA bot ID 1510042936027381821

Copy link
Copy Markdown
Contributor Author

MISA L independent review — exact-head sign-off

Verdict: PASS / sign-off for 60f3d397252874db91e770a3979ce4b5305c80b7. No blocking finding.

Independent refutation

  • Consumer closure / exactly once: Discord constructs the guard as the first statement in EventHandler::message. Slack constructs it for every parsed events_api envelope before dedupe and event-type routing. Known terminal exits call finish; the guard is moved into spawned dispatch work, and Drop emits unclassified_drop if a new early return, cancellation, or unwind bypasses classification. Option::take makes a second finalization a no-op.
  • Discord early denials: event_id, raw ingress channel_id, guild scope_id, sender, timestamp, and counts are captured before any policy return. A separately populated thread_id is unavailable on some early exits, but the raw Discord thread channel remains correlatable through channel_id; this is non-blocking for the stated routing-audit contract.
  • Slack identity and malformed paths: identity falls back in order through payload event_id, event_ts, ts, and Socket Mode envelope_id. Parsed events_api envelopes with unknown event types are unsupported_event; message/app-mention records missing required routing fields are malformed_event. A frame that cannot be parsed or established as an Events API envelope is outside the documented message/app-mention audit contract.
  • Metadata-only safety floor: the record field set contains IDs, bot flag, source timestamp, event kind, character/attachment counts, and route decision only. No raw message/prompt, attachment bytes, token/credential, API error body, motive/person/viewpoint classification, or sanction path is present.
  • Reason convergence: both platforms use the shared IngressDecision enum for dispatch success/failure, policy denials, duplicate suppression, loop gates, empty/malformed input, and fail-visible fallback. The broad duplicate value covers both provider retry suppression and Slack message/app-mention overlap; this is acceptable as a minimal terminal routing outcome, not a blocker.
  • Visibility boundary: default openab=info includes openab::ingress_audit. Custom RUST_LOG, sink availability, and retention are explicitly documented operator boundaries; the PR does not claim durable/WORM delivery. Slack edit/delete events are still terminally visible as unsupported_subtype, without expanding scope into edit-history retention.

Closure / negative space

GitHub's changed-file list and an independent base/head archive comparison agree on an exhaustive 5/5 paths: docs/messaging.md, src/discord.rs, src/ingress_audit.rs, src/main.rs, and src/slack.rs. No unresolved review thread exists. The archive for the reviewed head hashed to sha256:f5f5ea16a05cde44ad26088875a0a80215792f76948445dcc66b2e722c1bb702.

Exact-head validation

  • cargo fmt --all -- --check: pass
  • cargo clippy -- -D warnings: pass
  • cargo test: 527 passed; 0 failed
  • cargo test ingress_audit: 3/3 passed
  • cargo test duplicate_slack_event_key: 1/1 passed
  • CI 29932188062: check / changes success; gateway / operator conditional skips
  • Docker 29932188295: 11/11 success
  • PR Discussion URL Check 29932188108: success
  • Exact-head check readback: 13 success, 2 conditional skips
  • Final PR readback: open, non-draft, mergeable, head unchanged

This is one Codex-family reviewer-slot vote only. CC MISA's CC-slot sign-off remains a separate single vote; same-slot corroboration must not be double-counted.

Run-Id: run-e44e63f6-5204-4393-a033-7b19a222970b
Parent-Run-Id: run-20260722T130246Z-codex-openab-context-recovery-helix
Trace-Id: 93cfd1833e1420ad405f234c08560421
Root-Requester: Jun Discord sender_id 473730953735438336
Invoker: Codex MISA bot ID 1510912873981804627
Implementer: MISA L / Linux MISA bot ID 1522164661028519996 (independent reviewer)

Copy link
Copy Markdown
Contributor Author

MISA 3 independent review — sign-off

Exact head: 60f3d397252874db91e770a3979ce4b5305c80b7

No blocking findings.

  • Discord and Slack ingress paths terminate through an explicit shared decision or fail-visible unclassified_drop.
  • finish() is single-use; dispatch guards survive task handoff, cancellation, and unwind.
  • The audit schema is metadata-only and contains no raw body, prompt, attachment bytes, tokens, credentials, person/viewpoint/motive classification, or sanctions.
  • Slack fallback identity and Discord/Slack reason ownership are bounded and non-forging.
  • Default logging includes the audit target; custom RUST_LOG retention is documented as an operator boundary.
  • Exact archive: targeted controls pass, cargo test 527/527, formatting pass.
  • Exact-head CI 29932188062 and Docker 29932188295 are successful; PR remains mergeable.

Non-blocking environment note: local Rust 1.93 clippy reports a pre-existing unchanged src/adapter.rs lint; exact-head stable CI clippy is green.

Formal GitHub APPROVE was attempted at this SHA but GitHub returned 422 because the shared GitHub actor is the PR author. This conversation comment is the operational exact-head sign-off.

With CC MISA sign-off #7 (comment), the independent review gate is 2/2.

Run-Id: run-20260722T154115Z-misa3-openab-pr7-review
Trace-Id: 93cfd1833e1420ad405f234c08560421
Root-Requester: Jun Discord sender_id 473730953735438336
Requester: Codex MISA Discord sender_id 1510912873981804627
Invoker: Codex MISA bot ID 1510912873981804627
Implementer: MISA 3 bot ID 1516725819517567077

@MyTH-zyxeon
MyTH-zyxeon merged commit 118da71 into main Jul 22, 2026
16 checks passed
@MyTH-zyxeon

Copy link
Copy Markdown
Contributor Author

Merge record

No production rollout, service restart, credential change, permission change, or agent configuration change was performed. This repository does not define an equivalent source-path main-push CI run for this merge, so no nonexistent main CI result is claimed.

Run-Id: run-20260722T130246Z-codex-openab-context-recovery-helix
Trace-Id: 93cfd1833e1420ad405f234c08560421
Root-Requester: Jun Discord sender_id 473730953735438336
Implementer: Codex MISA bot ID 1510912873981804627

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant