Skip to content

[Feature] /threat-model: inline DFD as point-in-time snapshot at audit time #270

@atlas-apex

Description

@atlas-apex

User Story

As a security engineer reviewing a historical threat model, I want the DFD that the threats were enumerated against to be inlined as a point-in-time snapshot in the threat-model output (with a "DFD as of YYYY-MM-DD" marker), so that the threat model remains internally consistent and auditable even after the live DFD evolves.

Context

Today (per AgDR-0026) /threat-model consumes projects/<name>/architecture/dfd.md as the source of truth — it reads the DFD, enumerates STRIDE threats per trust-boundary crossing, and writes its output to projects/<name>/audits/threat-model/<ts>.md (per AgDR-0019 + #218).

The threat-model output links to the live DFD but doesn't copy it. So when the architecture evolves and /dfd is re-run, the historical threat models reference a DFD that no longer matches what they analysed. That's silent rot — last quarter's threats are now indexed against this quarter's DFD.

Audit-class outputs are by design point-in-time snapshots (per AgDR-0019). The DFD that an audit consumed is part of that snapshot.

Acceptance Criteria

  • /threat-model reads projects/<name>/architecture/dfd.md at audit time and inlines:
    • The full ```mermaid flowchart block (verbatim)
    • The ## Trust boundaries table (verbatim)
    • The ## Data classifications table (verbatim)
  • The inlined section is clearly marked: ## DFD (snapshot as of YYYY-MM-DD) with a callout: "This is a point-in-time capture of the DFD that this threat model was enumerated against. Live DFD: projects/<name>/architecture/dfd.md."
  • The ## Discovery provenance block from dfd.md is not inlined (too noisy for a threat-model output; readers click through to the live DFD for that)
  • If dfd.md doesn't exist when /threat-model runs, the skill stops and prompts the operator to run /dfd <project> first
  • The threat-model output passes the new Mermaid lint (closes the loop with [Feature] Mermaid lint.sh per emitting skill (/c4, /dfd, /tech-vision) #266)
  • Audit-artefact persistence is preserved — the threat-model output still lands at projects/<name>/audits/threat-model/<ts>.md + runs/<ts>.json per AgDR-0019
  • SKILL.md updated to describe the new snapshot step; AgDR-0026 (DFD as source-of-truth) updated with a forward-link to this snapshot pattern
  • Glossary in PR body covers "snapshot", "live DFD", "audit-artefact persistence"

Design Notes

  • Inline by copy, not by transclusion. A snapshot pattern ({{include: dfd.md}} style) would couple the rendering of historical threat models to whatever the live DFD says today — same root cause as today's problem. The whole point is the file is self-contained.
  • /compliance-check consumes the same DFD (also per AgDR-0026). Same snapshot pattern should apply there. Out of scope for this ticket — file a sibling ticket if accepted.
  • Same pattern applies to other DFD-consumers (/security-review, potentially /launch-check if it summarises threats). Out of scope for v1; design here so it's reusable.
  • Drift detection (out of scope, v1). A future enhancement: when /threat-model runs again, compare the snapshot from the previous run to the current live DFD; flag deltas so the operator knows what's new. v1 just inlines the snapshot — diff/drift is a v2 concern.

Risks

  • Snapshot can rot if the operator never re-runs /threat-model. Mitigation: print a "last run was N days ago" warning in /launch-check / portfolio status output. Out of scope for this ticket.
  • File-size growth — each threat-model now carries the DFD's Mermaid block (~30-100 lines) + tables. Acceptable given audit-history is dated subdirs (per AgDR-0019); doesn't bloat the live tree.

Out of scope

  • Inlining DFD into /compliance-check output (separate ticket if accepted)
  • DFD drift detection between threat-model runs (v2)
  • Inlining DFD into /security-review or /launch-check (separate analysis)

Glossary

Term Definition
Snapshot A point-in-time copy of an artefact, captured at audit time so the audit remains internally consistent later
Live DFD The continuously-refreshed projects/<name>/architecture/dfd.md produced by /dfd
Audit-artefact persistence The dated-subdir convention shipped via AgDR-0019 / #218projects/<name>/audits/<dim>/<ts>.md

Metadata

Metadata

Assignees

No one assigned

    Labels

    P2Medium — plan-worthy, not urgentenhancementNew feature or request

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions