feat(threats): author-controlled manual ids, Critical priority, and register origin/status - #74
Merged
Merged
Conversation
…fintion of manual.
5 tasks
This was referenced Jul 25, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
feat(threats): author-controlled manual ids, Critical priority, and register origin/status
Implements THR-002. The threat register now has a stable public contract: authors own
manual ids and priority, and every surface distinguishes manual, current-generated,
persisted-generated, and stale entries.
What changed
Stable manual identity.
ManualThreatId(Core) is the single definition of thereserved
manual:namespace.threats --add --id,AuthoringService.AddThreat, and theMCP
add_threattool accept an author-supplied id, canonicalize it (prefix optional,[A-Za-z0-9._-], 1–128 chars), and refuse a duplicate rather than overwriting theexisting threat's triage.
Criticalpriority, tmforge-wide.ThreatPriorityis the one vocabulary andThreatPrioritiescanonicalizes it for every surface. Severity→priority defaults areunchanged, so no existing threat moved. The embedded knowledge base now declares the whole
vocabulary with
IsPriorityUsed; at a foreign KB the two vocabularies are unioned, soneither side's values become unselectable.
Register origin/status.
ThreatRegisterClassifiersplits the register against onegeneration run. Staleness is only claimed when the rule was present and enabled and still
did not fire; a rule absent or disabled is reported as
indeterminatewith the rule named,never assumed stale.
Stale entries are inspectable and removable.
list threatsshows a STANDING column;threats --remove-staleclears leftovers. A stale entry carrying triage is kept and named—
--forceis the explicit way to discard it — and pruning refuses outright when anyentry's rule was not part of the run.
Surfaces:
open --json+ human output,list threats, HTML report (stale badge),POST /v1/model/threat-register, WASMThreatRegister, MCPthreat_register. The engineprojection rides the existing single-evaluation seam (
AnalysisProjection.Register), so itcosts no extra rule run.
Behavior changes
.tm7bytes change: the embedded KB now declaresIsPriorityUsedand thepriority value list.
convert --knowledge-baseoutput changes (it is now prepared like every other tm7 write).threats --remove <id>accepts a stale entry; a threat the rules still produce is stillrefused.
openapi/v1.jsonand Studioschema.d.tsregenerated.