Configuration control — spec tree, Substrate query fix, QC loop resolution, ISO 15289 reports

Summary

Four changes: spec tree for per-subsystem completeness tracking, fix for SubstrateStateStore returning wrong fact values, resolution of the QC loop that ran 22 consecutive sessions, and ISO 15289 document split with GSN safety case export.

Changes

1. Spec tree — structural manifest for decomposition

A spec tree defines the expected artifacts for each subsystem. Created during scaffold, checked by decompose sessions and guards. Solves three persistent problems:

Duplicate diagrams: Each subsystem has a canonical diagram name in the spec tree. Decompose checks by exact name match — no more substring matching that created duplicates across sessions.

Homeless requirements: Document section IDs are locked into the spec tree during scaffold. Every reqs create call uses section IDs from the spec tree — no per-session lookups, no wrong-section errors. The fusion reactor project accumulated 118 floating requirements (39% of total); this prevents recurrence.

Per-subsystem completeness: The isFirstPassComplete guard now checks the spec tree — all subsystems must have status:complete. Replaces aggregate count thresholds (≥80 SUB) that allowed individual subsystems to be skipped.

The decompose flow now selects the next subsystem from the spec tree (prioritising in-progress, then highest-SIL pending) rather than Claude’s ad-hoc choice.

2. SubstrateStateStore.get() query fix

Root cause of the 22-session QC loop (sessions 403–424).

SubstrateStateStore.get() queried facts by predicate only, without filtering by subject. When both Claude (subject: se-fusion-reactor-control-system, value: 393) and the harness (subject: autonomous-loop, value: 424) stored LAST_QC_SESSION, the store returned whichever the API listed first. Claude’s stale value (393) made interimQCDue see 31 sessions since QC instead of 0, firing QC every session.

Fix: get() now queries with the defaultSubject (autonomous-loop) first, falling back to no-subject query for backwards compatibility.

Impact: 22 wasted QC sessions (~$40), unassignedDoc grew from 57 to 118 because the QC flow lacked the mandatory --document/--section instruction. Both fixed.

3. ISO 15289 document split

Reports split from one monolithic page into five ISO/IEC/IEEE 15289-aligned documents alongside the preserved legacy report:

DocumentISO TypeStandards
ConOpsDescriptionISO 15289, IEEE 29148 §6.1
System Requirements (SyRS)SpecificationISO 15289, IEEE 29148 §6.2–6.4
System Design (SyDD)DescriptionISO 15289, IEEE 29148 §6.5
Verification Plan (SVP)PlanISO 15289, IEEE 29148 §6.6
Hazard Analysis (HRA)ReportISO 15289, IEC 61508 Phase 3

IEEE 29148 requirement categorisation on the SyRS page: system requirements auto-classified into functional, performance, interface, safety, security, environmental, reliability, and compliance categories.

GSN safety case on the HRA page: visual Mermaid diagram of goal structure plus downloadable YAML export for GSN tools.

Build-time caching added to shared data module — 822s → 287s (3× faster, 529 pages).

4. Additional fixes

  • airgen verify run removed from validate flow (checks unused verification activities, not VER requirements)
  • Harness now automatically sets LAST_QC_SESSION after every QC flow (no longer relies on Claude)
  • Mandatory --document/--section instruction added to QC flow
  • Trait name fix: 6 case variants corrected across all journal posts

Version manifest

ComponentBeforeAfter
Subsystem trackingAggregate counts (≥80 SUB)Per-subsystem spec tree (all must be complete)
Diagram dedupSubstring name matchCanonical name from spec tree (exact match)
Requirement sectionsPer-session lookupLocked in spec tree at scaffold
Substrate queriesPredicate onlySubject + predicate (prevents cross-subject collisions)
QC trackingClaude-dependentHarness-managed LAST_QC_SESSION
Reports1 monolithic page1 legacy + 5 ISO 15289 documents + GSN
Build time822s287s (cached)
Git commits1720
← all entries