Purpose: Operational procedures for Surface package versioning, state transitions, and lifecycle events
Status: Phase 7 implementation; depth-1 scope
Last updated: 2026-09-22
Every Surface execution package has a lifecycle state and a version record. This document defines:
Draft
↓
Validation-Ready (with lock for governance review)
↓
Approved (signed off for production use)
↓
Archived (superseded by newer version)
| State | Meaning | Governance | Use | Promotion path |
|---|---|---|---|---|
| Draft | Being authored or regenerated; not yet validated | None required | Internal development only | Promotion by: manual validation step |
| Validation-Ready | Regeneration complete; awaiting governance review | Review requested | CI/staging environments | Promotion by: maintainer sign-off |
| Approved | Governance approved; ready for production | Board signed-off or equivalent | Production consumption | Promotion by: release pipeline |
| Archived | Superseded by a newer version | Automatic on new promotion | Historical reference only | Demotion only (no promotion) |
Draft → Validation-Ready
- Regeneration complete
- All release gates pass
- No manual action required (automatic on gate success)
Validation-Ready → Approved
- Maintainer reviews governance state
- No outstanding exceptions
- Maintainer signs off
Approved → Archived
- Newer version promoted to Approved
- Automatic (old version archived on new release)
Archived → (terminal state)
- Remain queryable for provenance tracing
- May not be promoted back to active use
These transitions are forbidden:
Draft → Approved (must validate first)Validation-Ready → Archived (must be Approved first)Archived → Approved (no revival; create new version instead)Example: 0.2.1-sha256.a7c9d2e.srf-canon/2
| Part | Meaning | When incremented | Example |
|---|---|---|---|
| MAJOR | Incompatible interface change; requires client rewrite | Rarely; architecture decision required | 1.0.0 (from 0.x.x) |
| MINOR | New features; backward compatible | When adding new index forms, promotion types, or policy fields | 0.2.0 (added Projection subsystem) |
| PATCH | Bug fixes; no new features | When fixing compiler bugs or defects without spec change | 0.2.1 |
| METADATA | Content identifier + canonicalisation version | Every regeneration | sha256.a7c9d2e.srf-canon/2 |
MAJOR (rare):
MINOR (common during active development):
PATCH (common):
METADATA (every regeneration):
srf-canon/1, srf-canon/2, etc.)sha256.a7c9d2e.srf-canon/2Each Surface package tracks its own version independently. The ecosystem has no global version number.
However, all packages must use the same canonicalisation version in production to ensure hash portability.
Trigger: Source, mapping, or profile change detected
Procedure:
sha256.<new-hash>.srf-canon/<current-version>Validation-ReadyAutomatic on success; manual on failure:
# Success path
python -m surface lower --contracts ontology/surface/examples/my-contract.ttl
# Regeneration + gate verification → Auto-promotion to Validation-Ready
# Failure path
# Review logs, fix issues, retry manually
python -m surface lower --contracts ontology/surface/examples/my-contract.ttl --force-draft
# Stays in Draft; requires manual repair
State recorded:
ex:SurfacePackage_MyConcern_v0.2.1_a7c9d2e
rdf:type srf:GeneratedSurface ;
srf:packageState <ValidationReady> ;
srf:packageVersion "0.2.1-sha256.a7c9d2e.srf-canon/2" ;
srf:lastRegeneratedAt "2026-09-22T15:30:00Z"^^xsd:dateTime ;
srf:regeneratedReason "Coverage-type scheme rebound to 2026Q4 edition" ;
srf:reviewRequestedAt "2026-09-22T15:31:00Z"^^xsd:dateTime .
Trigger: Maintainer reviews and approves the package
Procedure:
ApprovedGate review checklist:
State recorded:
ex:SurfacePackage_MyConcern_v0.2.1_a7c9d2e
rdf:type srf:GeneratedSurface ;
srf:packageState <Approved> ;
srf:packageVersion "0.2.1-sha256.a7c9d2e.srf-canon/2" ;
srf:reviewRequestedAt "2026-09-22T15:31:00Z"^^xsd:dateTime ;
srf:reviewApprovedAt "2026-09-22T16:15:00Z"^^xsd:dateTime ;
srf:reviewApprovedBy <person/maintainer-1> ;
srf:reviewNotes "Approved for production; no outstanding issues" .
Trigger: Release pipeline deploys the package
Procedure:
Approved# Blue-green or staged rollout
cp -r ontology/surface/execution/my-contract/v0.2.1-a7c9d2e \
ontology/surface/execution/my-contract/current
git add ontology/surface/execution/my-contract/current
git commit -m "Release: my-contract v0.2.1-a7c9d2e to production"
State recorded:
ex:SurfacePackage_MyConcern_v0.2.1_a7c9d2e
rdf:type srf:GeneratedSurface ;
srf:packageState <Active> ;
srf:packageVersion "0.2.1-sha256.a7c9d2e.srf-canon/2" ;
srf:deployedToProductionAt "2026-09-22T17:00:00Z"^^xsd:dateTime ;
srf:canonicalisationVersion "srf-canon/2" ;
srf:productionSupersedes <v0.2.0-sha256.c4e1f3a.srf-canon/2> .
Trigger: A newer version is promoted to Active
Procedure:
Archivedsrf:productionSupersedes for provenance tracingDo NOT delete archived packages. Keep them queryable for:
State recorded:
ex:SurfacePackage_MyConcern_v0.2.0_c4e1f3a
rdf:type srf:GeneratedSurface ;
srf:packageState <Archived> ;
srf:packageVersion "0.2.0-sha256.c4e1f3a.srf-canon/2" ;
srf:deployedToProductionAt "2026-09-10T08:00:00Z"^^xsd:dateTime ;
srf:archivedAt "2026-09-22T17:00:00Z"^^xsd:dateTime ;
srf:supersededBy <v0.2.1-sha256.a7c9d2e.srf-canon/2> .
ex:SurfacePackage_MyConcern_v0.2.1_a7c9d2e
rdf:type srf:GeneratedSurface ;
srf:packageState <Active> ;
srf:productionSupersedes <v0.2.0-sha256.c4e1f3a.srf-canon/2> .
A canonicalisation cutover (e.g., srf-canon/1 → srf-canon/2) is a rare, high-impact event that invalidates all recorded hashes across the entire package estate.
See surface-invalidation-runbook.md § Scenario 4 for the technical procedure.
Old estate (srf-canon/1):
all packages @ Active or Archived states
all hashes based on srf-canon/1 algorithm
↓↓↓ Cutover decision & authorization ↓↓↓
Transition period:
new packages regenerated with srf-canon/2
both versions running (carefully isolated)
comparison tests running to verify equivalence
↓↓↓ Verification complete ↓↓↓
Staged rollout:
domain-1: v0.2.0-sha256.c4e1f3a.srf-canon/1 → Archived
v0.2.1-sha256.a7c9d2e.srf-canon/2 → Active
[wait 24 hours, monitoring]
domain-2: (same)
domain-3: (same)
↓↓↓ All domains transitioned ↓↓↓
New estate (srf-canon/2):
all packages @ Active or Archived
all hashes based on srf-canon/2 algorithm
backward-compatibility monitoring complete
Before cutover:
v0.2.0-sha256.c4e1f3a.srf-canon/1
After cutover (same MAJOR.MINOR.PATCH, new canonicalisation):
v0.2.0-sha256.a1b2c3d.srf-canon/2
Note: The PATCH version does not change because the functionality is unchanged; only the canonicalisation algorithm did. This ensures version consistency across the cutover.
If cutover verification fails:
New (srf-canon/2) packages fail comparison tests
→ Rollback: Revert to old (srf-canon/1) packages
→ Investigate failure (compiler bug? canonicalisation mismatch?)
→ Delay cutover by N weeks
→ Fix root cause and retry
Record the incident in the operational log with:
Symptoms:
Active but contains old hashesDiagnosis:
python tools/surface/invalidation.py --check-production-state \
ontology/surface/execution/my-contract/current
# Output:
# ❌ MISMATCH: Package metadata says v0.2.1-a7c9d2e
# but filesystem contains v0.2.0-c4e1f3a
# ❌ Hashes are stale (created 2026-09-10, now 2026-09-22)
Recovery:
python -m surface lower --contracts ontology/surface/examples/my-contract.ttl --regenerate-all
Symptoms:
srf-canon/1, others use srf-canon/2Prevention (preferred):
Recovery (if mixing occurred):
srf-canon/1 or all srf-canon/2)A real deployment would track this state in a dashboard:
Surface Package Lifecycle Status
═══════════════════════════════════════════════════════════════
Package Version State Updated
─────────────────────────────────────────────────────────────────
coverage-index 0.2.1-a7c9d2e Active 2 hours ago
peril-dimension 0.1.5-c4e1f3a Active 1 week ago
scope-closure 0.3.0-b2d8e9f Validation-Rdy 30 mins ago
sic-category 0.2.0-d9e1a3b Archived 1 month ago
Canonicalisation Version: srf-canon/2
Last estate-wide cutover: 2026-08-15
Next planned review: 2026-10-15
Release Gates Summary:
✅ All Surface tests: 61/61
✅ All MORK tests: 15/15
✅ All parity checks: 99.5%
⚠️ SWRL verification: Pending (Phase 8 item 7)
tools/surface/invalidation.py — API referenceLast updated: 2026-09-22
Related ADR: ADR-A12 (Identity and Derivation Model), ADR-A27 (Invalidation and Minimal-Scope Regeneration Policy)