Skip to content

Let the design documents catch up with the code (#194, #195) - #203

Merged
icebergai-review-bot[bot] merged 1 commit into
mainfrom
claude/codebase-review-cleanup-ovlli4
Aug 20, 2026
Merged

Let the design documents catch up with the code (#194, #195)#203
icebergai-review-bot[bot] merged 1 commit into
mainfrom
claude/codebase-review-cleanup-ovlli4

Conversation

@richardmhope

Copy link
Copy Markdown
Contributor

Closes #194. Closes #195.

Two issues in one PR because they are one change: #195 wants ARCHITECTURE.md's decision table to run through the hand-over ADR, and its §8 points at the threat model that #194 fixes. Shipping them apart would mean landing an architecture doc that references a security doc only correct in another open branch.

#194 — the threat model did not know hand-over existed

docs/security.md § Outbound requests opened with "Two features deliberately send traffic out of the deployment". Hand-over targets are a third, and they carry more than an announcement does — the owning team, the due date, up to ten remediation actions — because the person picking up the ticket is not looking at this console.

POST /handoff/callback was worse: no session, no CSRF token, authenticated only by the target's own signing secret, and absent from the numbered trust-boundary list entirely. It is the only inbound boundary that is neither a browser session nor an engine token.

Added:

  • Trust boundary 9 — the callback: same-secret HMAC, five-minute replay window, rate-limited per address on the failed-login bucket charged before the body is read, 64 KiB cap, one indistinguishable 401 for every failure mode. And the part that bounds the damage: a verified receiver writes its own work item's state, id and URL, and nothing else. It cannot move a finding; where the two disagree the console shows the disagreement. The worst a compromised receiver achieves is a wrong claim about its own ticket.
  • A third bullet under § Outbound requests, with the three ways hand-over differs from a webhook channel (it carries more, its reply is read, requesting it is analyst+ rather than admin).
  • "External ticket creation" comes off the out-of-scope list, whose own instruction was that adding any of those must revisit this threat model. That was overdue, not optional.

ADR 0014 records the decisions that until now lived only as prose in docs/handoff.md and migration docstrings: one target type and why vendor clients were rejected, the notification wire format reused deliberately, dedup by both a unique constraint and a never-regenerated idempotency key, admins-decide-where/analysts-decide-which, and §6 — the reply is recorded beside the finding, never applied to it, because a receiver is not a person and applying it would mean inventing an actor for the audit trail or bypassing the evidence policy.

Two docstrings in iceberg_api/handoff/ that pointed at "§ Notification egress" now point at the ADR and the right section.

#195 — ARCHITECTURE.md was ~six milestones behind

  • §5 stopped at ADR 0009; it now runs through 0014 (liveness validation, correlation, remediation, incremental, hand-over). The Python row dropped its "3.13 fallback if the M0 compat spike finds blockers" — M0 shipped.
  • §4 drew the pre-Support incremental and resumable source scanning #143 flow: a fetch that reports only when it ends. It now covers batched progress submission and why a checkpoint may not outrun its findings, where a batch is cut, per-scope cursors, coverage manifests with HMAC gap references, and both gates on auto-resolution (not-completed, and not-full-mode) with the note that notifications sit outside them.
  • §9 listed M0–M4 and named SMB connectors, incremental scanning and external ticket creation as MVP non-goals — all three ship. M5/M6 added, the shipped non-goals pruned, and a pointer at docs/backlog.md as the live list.
  • §1 still called file shares post-MVP. §2's diagram box gained the subsystems it was missing and labels the engine→API arrow as progress and results. §8 names the nine boundaries and the three-out/one-in egress shape.

Validation

Documentation only — no behaviour change. make check green: ruff, mypy, scripts/check_docs.py (43 documents, link and make-target checks), 1956 passed / 2 skipped. tests/test_docs_invariants.py covers the new ADR being indexed and linked.


Generated by Claude Code

Two documents that describe themselves as authoritative had fallen behind
what shipped, in ways that matter differently.

**The threat model did not know hand-over existed (#194).** security.md
§ Outbound requests opened with "two features deliberately send traffic out of
the deployment"; hand-over targets were a third, carrying more than an
announcement does — the owning team, the due date, up to ten remediation
actions. And POST /handoff/callback, which takes no session and no CSRF token
and is authenticated only by the target's own signing secret, was a trust
boundary the numbered list did not contain at all: the only inbound one that
is neither a browser nor an engine. Both are written up, including what a
verified receiver may drive (its own work item's state, id and URL) and what
it may not (the finding). "External ticket creation" comes off the
out-of-scope list whose own instruction was that adding it must revisit this
document.

ADR 0014 records the decisions that until now lived only as prose: one target
type and why vendor clients were rejected, the notification wire format reused
deliberately, dedup by both a unique constraint and a never-regenerated
idempotency key, admins-decide-where/analysts-decide-which, and the reply
recorded beside the finding rather than written onto it.

**ARCHITECTURE.md was roughly six milestones behind (#195).** The §5 table
stopped at ADR 0009 and now runs through 0014. §4's scan flow predated
checkpoints, so it drew a fetch that reports only when it ends; it now covers
batched progress submission, per-scope cursors, coverage manifests, and the two
gates on auto-resolution. §9 listed M0-M4 and named SMB connectors, incremental
scanning and external ticket creation as non-goals, all three of which ship.
§1 still called file shares post-MVP.

Refs ADR 0013, ADR 0014.

Claude-Session: https://claude.ai/code/session_012sohE85sRDt6t2w3936rGJ

Co-authored-by: Claude <noreply@anthropic.com>

@icebergai-review-bot icebergai-review-bot Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Verdict

APPROVE

Completed bounded review across 1 immutable scope(s). No actionable findings in the supplied change.

Scope health

Convergence: healthy. Review mode: initial.
Recommended action: CONTINUE_INCREMENTAL.

  • No escalation signals.

Prior findings

Finding Status
No prior finding state

New findings

No new findings.

Fix-induced regressions

  • None evidenced.

Uncertainty

  • No material uncertainty recorded.

Validation

  • Reviewed the supplied immutable diff only; no prior findings were provided for recheck.

Residual risks

  • None identified.

@icebergai-review-bot
icebergai-review-bot Bot merged commit 9b517a7 into main Aug 20, 2026
6 checks passed
@icebergai-review-bot
icebergai-review-bot Bot deleted the claude/codebase-review-cleanup-ovlli4 branch August 20, 2026 00:55
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

ARCHITECTURE.md is roughly six milestones behind the code The hand-over feature shipped without threat-model coverage or an ADR

2 participants