Skip to content

feat(threats): author-controlled manual ids, Critical priority, and register origin/status - #74

Merged
Hacks4Snacks merged 6 commits into
mainfrom
hacks4snacks/tmregister
Jul 26, 2026
Merged

Hacks4Snacks merged 6 commits into
mainfrom
hacks4snacks/tmregister

Conversation

@Hacks4Snacks

Copy link
Copy Markdown
Owner

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 the
reserved manual: namespace. threats --add --id, AuthoringService.AddThreat, and the
MCP add_threat tool accept an author-supplied id, canonicalize it (prefix optional,
[A-Za-z0-9._-], 1–128 chars), and refuse a duplicate rather than overwriting the
existing threat's triage.

Critical priority, tmforge-wide. ThreatPriority is the one vocabulary and
ThreatPriorities canonicalizes it for every surface. Severity→priority defaults are
unchanged, 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, so
neither side's values become unselectable.

Register origin/status. ThreatRegisterClassifier splits the register against one
generation 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 indeterminate with the rule named,
never assumed stale.

Stale entries are inspectable and removable. list threats shows a STANDING column;
threats --remove-stale clears leftovers. A stale entry carrying triage is kept and named
— --force is the explicit way to discard it — and pruning refuses outright when any
entry's rule was not part of the run.

Surfaces: open --json + human output, list threats, HTML report (stale badge),
POST /v1/model/threat-register, WASM ThreatRegister, MCP threat_register. The engine
projection rides the existing single-evaluation seam (AnalysisProjection.Register), so it
costs no extra rule run.

Behavior changes

  • Exported .tm7 bytes change: the embedded KB now declares IsPriorityUsed and the
    priority value list.
  • convert --knowledge-base output changes (it is now prepared like every other tm7 write).
  • threats --remove <id> accepts a stale entry; a threat the rules still produce is still
    refused.
  • openapi/v1.json and Studio schema.d.ts regenerated.

@Hacks4Snacks Hacks4Snacks linked an issue Jul 26, 2026 that may be closed by this pull request
5 tasks
@Hacks4Snacks
Hacks4Snacks merged commit 97bc13b into main Jul 26, 2026
8 checks passed
@Hacks4Snacks
Hacks4Snacks deleted the hacks4snacks/tmregister branch July 26, 2026 20:09
This was referenced Jul 25, 2026
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.

[THR-002] Threat-register identity and status

1 participant