security: THREAT_MODEL.md states enforcement per boundary in 688 lines and names zero tests, so a claim can drift from the code that proves it without anything noticing
Nobody has claimed this yet.
- Dominant language
- Go
- Stars
- 9
- Forks
- 0
- Avg merge
- 3h 3m
- Merged PRs (30d)
- 509
Description
Observed behavior
At eb8172f, THREAT_MODEL.md is a serious document: boundaries, assets, adversaries, and a per-boundary section of "enforcement, limits, planned hardening" for author-to-deployment, caller-to-server, webhook-sender, server-to-worker, worker-to-plugin, plugin-to-network, tenant-to-tenant, run-to-history, and editor-and-agent tooling, plus prompt injection, the governance recursion, and the issuer as a single point of failure. It records what is not landed by issue number (#347, #146, #353), which is honest.
It names no test. grep -cE '_test\.go|Test[A-Z]\w+' THREAT_MODEL.md is 0; "verified by", "proved by", "pinned by" appear 0 times. Every enforcement sentence ("the identity egress boundary denies loopback and private ranges", "a plugin receives no reverse channel", "cross-tenant reads return NotFound") is true today because a test somewhere makes it true, and the document does not say which, so a refactor that deletes or weakens that test leaves the document asserting a property the tree no longer holds. The examples corpus has a charter test that fails on drift; the agent configuration has one; the threat model, which is the document a security reviewer reads first, has none.
The same document is where #1721 (fuzzers per boundary parser), #1703 (RFC checklist tests), #1725 (fail-open walker), and #1722 (global test seams on security paths) would each have been caught earlier if a row had said "verified by …" and the row had been empty.
Desired outcome
- Each enforcement claim in section 4 gains a
Verified by:line naming the test functions (package-qualified) that pin it, and each "planned hardening" line keeps its issue number. tools/threatmodel(a repository test besidetools/vacuity): parses those lines, resolves each named test to afunc Test…/Fuzz…in the tree, fails on a name that does not exist, and fails on an enforcement paragraph with noVerified by:line. The initial pass may mark a claimVerified by: none (#NNNN)with an issue, which is the ledger of what is asserted and unproven.docs/ARCHITECTURE.md's invariant 6 (fail closed at trust boundaries) links the threat model section as its evidence, the same way #1745 asks durability to.
Acceptance criteria
- Every enforcement paragraph in section 4 has a
Verified by:line and the test runs green. - Renaming one named test in a scratch branch makes the check fail with the paragraph and the missing name.
- The count of
Verified by: nonerows is in the job summary and only goes down.
Constraints and dependencies
- Adjacent: #1721, #1703, #1725, #1722, #1745 (durability evidence),
THREAT_MODEL.mdsection 8 "Non-goals and honest gaps".
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start with section 4 of THREAT_MODEL.md and inspect the repository-test patterns in tools/vacuity; the planned entry point is tools/threatmodel. Check the Go tree for package-qualified Test… and Fuzz… functions, then review docs/ARCHITECTURE.md invariant 6. Done means every enforcement paragraph has a resolvable Verified by line, the check catches renamed tests, and its summary reports unverified rows.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- go
- Domain
- documentation, security, testing-qa, tooling
- Issue type
- Feature
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Active
- Clarity
- Clearly specified
- Newbie friendliness
- 68/100