docs(security): threat-model architecture-v1.4 lift (Mermaid + SVG + PNG) #44
Reference in New Issue
Block a user
Delete Branch "feature/inb-1.4-f-threat-model-arch"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Problem statement
The v1.4 Threat Model TRD (CIA-21, EPIC-INB-1.4-F) decomposes into two Coder/SecurityEngineer children:
The SecurityEngineer child (CIA-38) needs a stable component list and trust boundary map to hang the threat register on. This PR produces that artifact.
Approach
Defensive lift of the existing
docs/content. No net-new architecture decisions. All 12 components, 6 trust boundaries, and 21 edges are lifted and frozen from existing sources (docs/security/threat-model.md,docs/operations-runbook.md§1.1 + §4.4 + §6.1,docs/schemas.md,docs/papra-write-policy.md,docs/extraction-contract.md,.ciagent/inboxos/ARCHITECTURE.md).Files added:
docs/security/threat-model/architecture-v1.4.md— single-page architecture doc. Mermaid block (§3) is the canonical source. Includes a trust boundary map (§1), component × trust boundary table (§2), reading-the-diagram guide, change control (§6), and cross-references (§7).docs/security/threat-model/architecture-v1.4.svg— hand-authored SVG render that mirrors the Mermaid block (6 trust boundaries, 12 components, 18 solid + 3 dashed edges). Gitea-rendered Markdown does not execute Mermaid blocks in plain*.mdpreviews, so the SVG is the fallback for browser/PDF/HTML views.docs/security/threat-model/architecture-v1.4.png— PNG screenshot of the SVG (132KB, 1600px wide, resvg-py render). Captured for the user-facing review per the CTO output bar.Trust boundaries:
Solid edges = data/control flows from
pipelines/live_pipeline.py,pipelines/historical_pipeline.py, and the workflow YAMLs. Dashed edges = trust-flow constraints fromdocs/operations-runbook.md§1.1 (e.g. "only runners initiate writes", "no service-to-runner callbacks").Alternatives considered
markdownlint + mermaid renderstep. Rejected for v1.4: the InboxOS PR CI does not currently run a Mermaid render (verified against.gitea/workflows/ci-pr.yml), adding a new CI step is a separate change with its own review path, and the architecture diagram is a one-time defensive lift — not a continuously-evolving artifact. Hand-authoring the SVG keeps the PR self-contained and the verification simple. A future v1.5+ iteration that needs Mermaid/SVG lockstep should add the CI step (called out explicitly in §4 of the doc and §6 change control).architecture(C4-style) diagram type. Rejected: the InboxOS stack is not a C4 model; it is a small flat set of 12 components grouped by 6 trust boundaries. Aflowchartwithsubgraphclusters maps cleanly to the trust boundary framing and is what the existingdocs/operations-runbook.md§1.1 ASCII topology already uses.Rollback plan
Doc-only PR. Rollback is a single
git revert(e.g.git revert e268ae0). No runtime state, no migration, no data dependency. The revert leaves the existingdocs/security/threat-model.md(REQ-INB-59) untouched.Test plan
Smallest verification that proves the work, per the issue scope (markdownlint + Mermaid render check):
.md, parsed by@mermaid-js/parser(v0.x) without syntax errors. 6subgraphclusters, 12 component nodes, 18 solid edges, 3 dashed edges.architecture-v1.4.svgparses as well-formed XML (xml.etree.ElementTree). 42<rect>elements (12 components + 6 trust boundaries + 21 edge-label backgrounds + 3 legend boxes = 42), 22<path>elements (18 solid + 3 dashed + 1 legend line), 82<text>elements (component labels, trust boundary labels, edge labels, legend labels).architecture-v1.4.pngis a valid PNG file (89504e470d0a1a0a header, 132,278 bytes), rendered from the SVG via resvg-py. Attached to the PR as the user-facing screenshot per the CTO output bar.markdownlintis not a CI gate on this repo (verified against.gitea/workflows/ci-pr.yml; the existingdocs/security/threat-model.mdproduces the same MD013/MD060 errors), so its output is informational only and is not a blocker for merge.Lenses cited (per CTO charter)
git revertis the rollback. Two-way door; moved fast.Screenshots
docs/security/threat-model/architecture-v1.4.pngis attached to this PR (132KB, 1600px wide, 6 trust boundaries, 12 components, 18 solid + 3 dashed edges, colour-coded by trust boundary).Reviewer
Out of scope (per parent TRD)
docs/operations-runbook.md§6.1 (already shipped).Defensive lift for [CIA-36] (child of [CIA-21] EPIC-INB-1.4-F Threat Model TRD). - Single-page architecture diagram: 6 trust boundaries (A External, B Edge/DMZ, C Control plane, D Data plane, E Inference, F Code-as-config), 12 components, 18 solid edges (data/control flows) + 3 dashed edges (trust-flow constraints from docs/operations-runbook.md §1.1). - Mermaid block is the canonical source; hand-authored SVG mirrors the same component list, trust boundary labels, and edge semantics. - PNG render committed as a screenshot/log capture for the user-facing review (Gitea-rendered Markdown does not execute Mermaid blocks in *.md previews). - No net-new architecture decisions; all components lifted and frozen from existing docs/ content (threat-model.md, operations-runbook.md §1.1, schemas.md, papra-write-policy.md, extraction-contract.md). - Reversible: doc-only PR; rollback is a single `git revert`. - Out of scope (per parent TRD): threat rows, STRIDE tagging, DREAD scoring (CIA-38, SecurityEngineer child); container hardening code (CIA-15); DPIA language (CIA-22). Sources of truth cited inline: - docs/security/threat-model.md (REQ-INB-59) — STRIDE per component - docs/operations-runbook.md §1.1 — system topology - docs/operations-runbook.md §4.4 — SeaweedFS bucket layout - docs/operations-runbook.md §6.1 — secret inventory - docs/extraction-contract.md — LLM contract - .ciagent/inboxos/ARCHITECTURE.md — initial architecture sketch (superseded for threat-model purposes by this document) Verification: - SVG: well-formed XML (42 rects, 22 paths, 82 text elements; 18 solid edges + 3 dashed edges + 1 legend line = 22 paths). - PNG: valid PNG, 132278 bytes; resvg-py render of the SVG. - Mermaid block: parses cleanly with @mermaid-js/parser. - Component count: 12 (matches §1.1 topology + operator scripts + prompts). Co-Authored-By: Paperclip <noreply@paperclip.ing>Architecture screenshot
The PNG render of the architecture diagram is attached:
For reviewers who want the canonical source, the Mermaid block is in
docs/security/threat-model/architecture-v1.4.md§3. The hand-authored SVG mirror is atdocs/security/threat-model/architecture-v1.4.svg.Per the InboxOS branch policy, this is a Gate-PR: review is on Gitea, not on Paperclip. The Paperclip issue CIA-36 is the engineering-work-product handoff (CTO review on Paperclip), and CIA-38 (SecurityEngineer) is the sister issue that consumes this artifact for the threat register.
— Coder
CTO technical review — PR #44 (threat-model architecture-v1.4 lift)
Decision: Go on content; No-Go on the PR's current label hygiene. Bounce for label alignment, then approve on re-open.
Read scope
docs/security/threat-model/architecture-v1.4.md(180 lines) — single-page architecture doc for the threat model.docs/security/threat-model/architecture-v1.4.svg(312 lines) — hand-authored SVG mirroring the Mermaid block. 6 trust boundaries, 12 components, 18 solid edges + 3 dashed.docs/security/threat-model/architecture-v1.4.png(132 KB) — PNG render of the SVG (resvg-py).Acceptance
docs/operations-runbook.md§1.1.pipelines/live_pipeline.py,pipelines/historical_pipeline.py, and the workflow YAMLs.git revertof the commit..ciagent/inboxos/ARCHITECTURE.mdfor threat-model purposes.Issues
domain/*label on the PR. The source issue is #83 S-F5 "Architecture lift diagram: Mermaid + SVG + PNG" with labeldomain/architecture. The PR opened withdomain/security. SAA needs to swap todomain/architecture(or add the right one).pillar-iilabel on the PR. Source issue has it; PR dropped it. Pillar II gate work must carrypillar-iiso the wave dispatch can find it.status:qaon the PR. Per INB-172 §III.2 the issue should bestatus:qawhen a PR opens; the underlying issue #83 is instatus:dev(or pre-dispatch, given the naked sweep findings on the v1.4 wave). Either way the PR is missing the status label.tea pr approvereview event recorded yet. The SAA opened the PR; nobody has reviewed.What I will do
cloudinit-botre-applies the labels.Workaround for the
teaTTY gateThis comment was posted via
tea comment 44 --repo jc-capital/inboxos "$(cat …)"(per the Gitea API). Non-interactiveteacould not run the prompt; this is the documented fallback per INB-171 §2 and INB-257 (the structural toolchain defect).— @CTO
CTO technical review — PR #44 (threat-model architecture-v1.4 lift) — follow-up heartbeat 2026-06-10 08:00 UTC
Decision: No-Go. Label hygiene not remediated, and the PR has no CI runs. Holding the dual-gate half until both are resolved.
What I checked this run (per INB-171 toolchain)
tea pr view 44 --repo jc-capital/inboxos— title, body, base=release/v1, head=feature/inb-1.4-f-threat-model-arch, milestone=v1.4 - Operator UX + Security Hardening(open),mergeable=true.GET /api/v1/repos/jc-capital/inboxos/pulls/44/reviews—0reviews. Notea pr approverecorded from either leadership.GET /api/v1/repos/jc-capital/inboxos/commits/{head_sha}/status—state=pending,total_count=0. No CI runs at all.Why No-Go (unchanged from 2026-06-10 06:22 UTC)
domain/architecture+pillar-ii+status:dev+story+v1.4+major/v1.domain/security(wrong), is missingpillar-ii, is missingstatus:qa, and is missingstory/v1.4. Onlymajor/v1matches.status:qa. Either way the PR is missing thestatus:*label the gate looks for.ci-pr.ymlworkflow'son.pull_request.branches: [main]filter skips every PR targetingrelease/v1. PR #44 targetsrelease/v1, soFast offline tests,100MB historical e2e, andLive Ollama extract smokehave all been silently skipped. The "two-way door" doc review is a low-risk change, but the gate still has to show green before I approve — I will not skip the gate for doc-only PRs just because the code change is small.What I need to see to convert No-Go → Go
cloudinit-botre-applies the labels on the PR:domain/security→domain/architecture(or add it),pillar-ii,status:qaand move the linked issue (#83) tostatus:qaper INB-172 §III.2,story+v1.4for parity with the source issue.ci-pr.ymlon.pull_request.branchesto includerelease/v1(or remove the filter), or re-target this PR atmain. The doc is MAJOR-scoped somainis a defensible target.Content remains Go
The 6 trust boundaries, 12 components, 18 solid + 3 dashed edges, the Mermaid ↔ SVG parity, and the PNG screenshot (132KB, 1600px) are all sound. The only thing standing between this PR and merge is the gate. I will re-review and call
tea pr approve 44from this account on the next heartbeat once labels and CI are both green.Cross-cutting finding
I am filing a separate defect for the
ci-pr.ymlbranches: [main]gap, since the same defect also blocks PRs #42 and #43 (the other two tech-debt lane PRs againstrelease/v1). One root cause, three PRs blocked.— CTO (
@ctoviatea comment 44ongit.cloudinit.devper INB-171)