name: stpa-audit
description: This skill should be used when conducting or AUDITING an STPA (System-Theoretic Process Analysis) or STPA-Sec (its security extension) hazard analysis on a PulseEngine project — including "do an STPA", "audit the hazard analysis", "are our losses/hazards/UCAs complete", "STPA-Sec review", "security hazard analysis", "check the safety/ artifacts", or before a release whose V-model gate depends on the hazard analysis being sound. Fires whenever the front-end of the safety case (losses → hazards → constraints → UCAs → loss scenarios) needs to be built or verified. rivet already provides the typed schema, link semantics, and rivet check topology validation — this skill operationalizes the method and the audit on top of it.
metadata:
author: pulseengine.eu
version: "0.1.0"
STPA / STPA-Sec audit
STPA is the hazard-analysis front-end of the V-model: it derives, top-down, what must never happen (losses), the system states that lead there (hazards), the constraints that prevent them, and how control actions go wrong (UCAs → loss scenarios). STPA-Sec is the same machinery turned on an adversary: security losses, security hazards, and unsafe control actions an attacker can cause. In PulseEngine this is not prose — it is a typed graph in rivet, which makes completeness a mechanical oracle and soundness a reasoning review. This skill covers both building it and, especially, auditing it.
The rivet vocabulary (ground truth)
STPA artifacts: loss, hazard (and sub-hazard), system-constraint,
controller / controlled-process (the control structure),
controller-constraint, uca, loss-scenario.
STPA-Sec artifacts (the security inversion): sec-loss (with cia-impact,
stakeholders), sec-hazard (cia-impact, severity,
leads-to-sec-loss), sec-constraint (prevents-sec-hazard), sec-uca
(uca-type, context, adversarial-causation — inject / spoof / tamper
/ intercept — and attacker-type), sec-scenario (attack-vector,
attacker-type).
The schema lives in rivet (schemas/stpa-sec.yaml); rivet itself dogfoods it
under safety/stpa/ and safety/stpa-sec/. Read those as the worked
example before auditing another project's analysis.
The audit — two halves, both required
Half 1 — Completeness (mechanical; this is the oracle)
Run rivet and treat a failing link-topology as a hard finding, per
[oracle-gate-a-change]:
rivet validate # schema + types well-formed
rivet check # link topology — the STPA closure rules below
rivet coverage # is the hazard analysis traced into the rest of the V?
The closure rules rivet check should enforce (flag any gap as a blocker):
- every
lossis led to by ≥1hazard; no orphan losses, no hazard without a loss; - every
hazardis prevented by ≥1system-constraint/controller-constraint; - the control structure is complete — every
controllerhas itscontrolled-processand the relevant control/feedback actions; - every
ucatraces to ahazardand has ≥1loss-scenarioexplaining its causation; - STPA-Sec: every
sec-hazardhas asec-constraint; everysec-ucahas non-emptyadversarial-causationandattacker-type; everysec-scenarionames anattack-vector;cia-impactis set on sec-losses and sec-hazards and the triad (C, I, A) is consciously covered, not partial.
If rivet check can't express one of these rules, that's a tooling gap →
[report-tool-friction] against rivet, then audit it by hand for now.
Half 2 — Soundness (reasoning; clean-room)
A green rivet check proves the graph is closed, not that the analysis is
right. Per [clean-room-verification], spawn a cold reviewer and have them
re-derive a sample, not infer from the existing labels:
- Are the losses the actual stakeholder losses, or a convenient subset?
- Is each hazard a genuine worst-case system state, not a failure mode or a cause? (STPA hazards are states, not events.)
- Is each UCA genuinely unsafe in its context (provided/not-provided/ wrong-timing/wrong-duration)? Context is where bogus UCAs hide.
- Do loss scenarios give a plausible causal chain, or just restate the UCA?
- STPA-Sec: is the attacker model explicit and adequate (capability,
position, goal)? Does
adversarial-causationanswer how (inject/spoof/ tamper/intercept), not just that? Is security co-developed with safety, or bolted on after (a smell — STPA and STPA-Sec share the control structure)?
Conducting it (when there's no analysis yet)
Work the four STPA steps top-down, writing rivet artifacts at each:
- Losses & hazards — stakeholder losses; system-level hazards that lead
to them (+
cia-impactfor the STPA-Sec pass). - Control structure — controllers, controlled processes, control + feedback actions.
- UCAs — for each control action, the four ways it's unsafe in context.
- Loss scenarios — causal chains that produce each UCA; for STPA-Sec, the
adversarial scenarios (attack-vector, attacker-type).
Each artifact links via rivet's typed predicates so
rivet checkcan later audit closure. Then run the audit above on your own output.
Where this composes
- [
pulseengine-feature-loop] — STPA/STPA-Sec is the loop's true front-end: losses/hazards/constraints precede the AADL architecture in spar and the typed requirements in rivet. A feature that changes hazardous behavior re-opens the analysis. - [
oracle-gate-a-change] —rivet checkover the STPA closure rules is the mechanical oracle; the diff that closes a gap is the one that counts. - [
clean-room-verification] — Half 2; audit the reasoning cold. - [
release-execution] — the STPA/STPA-Sec analysis being complete and sound is a precondition of the V-model traceability gate: every safety/ security constraint must trace forward to a requirement, architecture, implementation, and verification evidence.
Anti-patterns
- Treating STPA as a document instead of rivet's typed graph — you lose the mechanical completeness oracle and traceability into the V.
- Auditing completeness without soundness —
rivet checkgreen is necessary, not sufficient; a closed graph of wrong hazards still passes. - Security as an afterthought — STPA-Sec shares the control structure with
STPA; co-develop them. A sec-analysis with empty
adversarial-causationor no explicit attacker model is theatre. - Hazards written as events or causes rather than states; UCAs without context; loss scenarios that restate the UCA instead of explaining it.
- Partial CIA coverage in STPA-Sec passed off as complete.