Skip to content

Reconcile the unknown-exception inventory with the shipped webhook, ProposalTools, and CLI boundaries - #2483

Merged
Chris0Jeky merged 2 commits into
mainfrom
issue-2351/inventory-reconcile
Sep 4, 2026
Merged

Reconcile the unknown-exception inventory with the shipped webhook, ProposalTools, and CLI boundaries#2483
Chris0Jeky merged 2 commits into
mainfrom
issue-2351/inventory-reconcile

Conversation

@Chris0Jeky

Copy link
Copy Markdown
Owner

Summary

docs/security/UNKNOWN_EXCEPTION_SURFACE_INVENTORY.md (merged in #2470) was written against
a1ed795a7 and still described R1, R2 and R7 as open. All three have since shipped. This PR
reconciles the inventory with the tree and extends the guard to cover the newly-hardened surface.

Docs plus one list entry and one test — no production code changes.

  • R1 — CLOSED by Generalize webhook persisted failures and align ProposalTools redaction #2474 (merge 8dbeb81cf). OutboundWebhookDeliveryWorker.cs:253-255 persists
    SensitiveDataRedactor.GenericUnexpectedFailureMessage instead of
    Redact($"...{ex.Message}"), and logs the exception exactly once against the delivery id via
    SummarizeException (:248-252). Row and residual rewritten with those lines and the three
    pinning cases in OutboundWebhookDeliveryWorkerTests (generalization-during-processing, HTTP 500,
    timeout).
  • R2 — CLOSED by Generalize webhook persisted failures and align ProposalTools redaction #2474. ProposalTools.Error(Result) (ProposalTools.cs:191-193) now routes
    through SanitizeLlmFailureMessage, matching ReadTools/WriteTools. Cites
    ProposalToolsErrorSafetyTests.GetProposalStatus_KnownDomainFailureWithRedactablePattern_IsRedacted.
  • R7 — CLOSED by Sanitize standalone CLI unexpected failures #2466 (merge 57df469e2). Program.cs:20,125-127 plus
    Commands/CliUnexpectedFailure.cs:27,46, pinned by CliUnexpectedErrorSafetyTests (11 cases). A
    one-line note under the closure records that [CLI][Security] Give the standalone CLI a bounded always-on diagnostic sink for unexpected failures #2468 tracks the always-on diagnostic sink; the
    companion failure file shipped harness-only.
  • HTTP rows now cite UnknownExceptionBoundaryProofTests (Prove the correlated unknown-exception boundary end to end #2471) as the end-to-end pin for both
    the unhandled-exception boundary and the Result mapper.
  • Pinned-at statement moved from a1ed795a7 to 5b2a3c742, and states honestly that only the
    rows touched by these fixes plus the HTTP rows were re-read at that commit.
  • R3-R6 left open, unchanged. Nothing is renumbered — closed entries keep their slots.
  • Guard: backend/src/Taskdeck.Api/Workers/OutboundWebhookDeliveryWorker.cs added to
    PERSISTED_STATE_FILES in scripts/check-unknown-exception-boundary.mjs, with no new allowlist
    entry
    — the fixed arm assigns the generic constant directly and references only
    ex.GetType().Name / SummarizeException(ex) on the log path, neither of which rule 2 matches.
    One new test asserts the file is in the list. The inventory's guard section is updated for the new
    list membership and for the fact that the reviewed guarded-ternary allowance in rule 1 is now
    generic and no longer exercised by any shipped file.

Part of #2351. This PR intentionally does not close the umbrella issue.

Verification

Run at head in an isolated worktree detached from origin/main 5b2a3c742:

  • node --test scripts/check-unknown-exception-boundary.test.mjs25 tests, 25 pass, 0 fail
    (24 before, plus the new persisted-state membership test).
  • node scripts/check-unknown-exception-boundary.mjs"Unknown-exception boundary check passed.",
    exit 0, 0 findings on the real tree with the worker in PERSISTED_STATE_FILES.
  • node scripts/check-docs-governance.mjs"Docs governance check passed.", exit 0.
  • git diff --check — exit 0, no whitespace errors.
  • Every file:line and test name written into the doc was read out of the tree at 5b2a3c742, not
    taken from the PR descriptions: the webhook catch arm, ProposalTools.Error(Result),
    Program.cs's top-level catch, CliUnexpectedFailure.cs, and the four test files' member names.
    The three merges cited (8dbeb81cf, 57df469e2, ca3f3e6b4) were confirmed ancestors of HEAD
    with git merge-base --is-ancestor.
  • The HTTP rows' pre-existing line numbers (UnhandledExceptionMiddleware.cs:60-63,65-69,
    ResultExtensions.cs:34-56,41-48,49-54, PipelineConfiguration.cs:116) were re-read and still
    resolve correctly at 5b2a3c742.

Not verified

  • No backend test run. No production code changed, so the .NET suites were not executed; the
    test names cited in the doc were verified to exist by reading the test sources, not by running
    them.
  • Rows outside this slice were not re-read. R3-R6 and every unchanged row keep their
    a1ed795a7 line numbers, which may have drifted; the doc now says so explicitly rather than
    implying a whole-file re-pin.
  • No claim is made about surfaces outside the inventory's stated scope, and the guard's coverage is
    unchanged apart from the one added file.

OutboundWebhookDeliveryWorker.cs now persists the generic constant for
unknown exceptions (#2474), so it joins PERSISTED_STATE_FILES. The real-tree
scan stays at zero findings with no new allowlist entry.
R1, R2 and R7 are closed by #2474 and #2466; re-read at 5b2a3c7 with the
shipped file:line evidence and the pinning test names. The HTTP rows cite
UnknownExceptionBoundaryProofTests (#2471) as the end-to-end pin. R3-R6 stay
open. #2468 tracks the CLI's always-on diagnostic sink.
@chatgpt-codex-connector

Copy link
Copy Markdown

You have reached your Codex usage limits for code reviews. You can see your limits in the Codex usage dashboard.
To continue using code reviews, add credits to your account and enable them for code reviews in your settings.

@Chris0Jeky

Copy link
Copy Markdown
Owner Author

Fresh-context independent review at exact head 425ec9d.

Verdict: no CRITICAL or HIGH finding. Merge-blocking: none.

Checked at the checkout: every rewritten R1, R2, and R7 row states a property that is true in the tree (the webhook unknown-exception arm persists the generic constant and logs the redacted summary once; ProposalTools routes every code through SanitizeLlmFailureMessage; the CLI top-level catch delegates to CliUnexpectedFailure with only PreMigrationBackupException keeping redacted authored text); every cited test name exists at the cited line in UnknownExceptionBoundaryProofTests, OutboundWebhookDeliveryWorkerTests, ProposalToolsErrorSafetyTests, and CliUnexpectedErrorSafetyTests; adding the webhook worker to PERSISTED_STATE_FILES creates no finding because no catch in that file touches .Message, .StackTrace, or .ToString() on the exception. Worker-run proof: guard tests 25/25, real tree 0 findings, docs governance and diff check clean.

LOW, declined: the doc now carries two pin coordinate systems (some rows keep a1ed795 line numbers); stated honestly in the header, no false claim.

Remaining gate: exact-head hosted ci-required green and the three-minute aging floor, then a merge commit. Part of #2351; the umbrella stays open.

@Chris0Jeky

Copy link
Copy Markdown
Owner Author

Session checkpoint: reviewed clean, no fix pending; merge under the normal gate once the Windows API Integration job at head 425ec9d is green and the aging floor has passed. Merge-tree against main is clean.

@Chris0Jeky

Copy link
Copy Markdown
Owner Author

Review gate (Codex credits exhausted, SC-9): one fresh-context reviewer audited every file:line and test-name citation in the changed inventory rows against the head — all MATCH except one cosmetic off-by-one (webhook catch is at OutboundWebhookDeliveryWorker.cs:233, not :232); the guard change is additive (adds the worker file to PERSISTED_STATE_FILES, no allowlist or rule relaxation). Verdict SHIP. LOWs declined as non-blocking: the :232/:233 nit; the new list-membership test cannot detect a rule-2 regression (the tree-clean test carries that); the CLI row wording attributes DomainException/usage message preservation to the boundary rather than the command layer. Merging once main's in-progress run completes.

@Chris0Jeky
Chris0Jeky merged commit 41c9d92 into main Sep 4, 2026
35 checks passed
@github-project-automation github-project-automation Bot moved this from Pending to Done in Taskdeck Execution Sep 4, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

Status: Done

Development

Successfully merging this pull request may close these issues.

1 participant