What this console proves
The neutral core, built first: proprietary scan files enter through pluggable adapters, so the engine isn't locked to one scanner. The resulting twins and property facts live in open, exportable formats. Nothing is deleted, only versioned, and the property facts registry is append-only.
On top of that core sits the client's 17-step controlled lifecycle. A version gets a spatial map (building, floor, unit, space, zone) and a systems map (system, sub-system, component). An anchor pins a point to both maps at once. An observation and its measurements get recorded against that anchor. Evidence gets captured and cited. A hypothesis and a materiality rule turn that evidence into a finding, and the finding has to be reviewed before anyone can recommend a fix. The fix gets costed and authorized before a work order can exist. The work gets executed and verified, and a verified completion fact publishes a new twin version on its own. Every one of those transitions writes an entry to the append-only registry, so the whole chain stays auditable.
Two of the steps below try to skip a gate on purpose. The API is expected to refuse them with an HTTP 409, and that refusal is styled green because it's the correct outcome, not a failure of the demo.
The data model
Static reference: the shape every record below gets created against.
Foundation
Spatial map, per version
Systems map, per twin (persists across versions)
Anchors, observations and evidence
Reasoning
Finding, reviewed before it can move forward
Cost, authorization and work
Execution and verification
Completion, feeding back into a new version
A Property has many Twins. A Twin holds a chain of immutable Versions, a systems map that persists across versions, and a pointer to the current version. Each Version carries its own spatial map, its own anchors, and everything reasoned from them. A completion fact is the only thing that can trigger a new Version, and only after a verification actually passed. Every gate transition writes to the append-only registry event log, whether it succeeds or gets refused.
Live demonstration
Every button below calls the live, same-origin JSON API and shows the response beneath it. A "blocked" outcome on a gate or immutability step is the correct result, and it's styled green.
Reset walks the whole lifecycle graph for the demo property (spatial and systems maps, anchors, evidence, findings, work orders, the registry log, everything) and removes it. Rule and materiality threshold definitions are left in place on purpose: they're reusable reference data, not per-run demo state, the way a real inspector would reuse the same rule across properties.
Automated test evidence
Static reference to the test suite. Run it with php artisan test.
- VersioningTest: version numbers increment sequentially; publishing moves the current-version pointer while keeping the old version; a published version throws on update and on delete; a draft version can still be edited.
- PropertyFactsRegistryTest: append() writes a checksummed fact; update and delete on a fact both throw; the registry service exposes no update/delete method at all.
- AdapterRegistryTest: the reference adapter is discoverable by format; the ingestion path drives validate() → ingest() and produces a job plus a draft version; an unsupported format resolves no adapter.
- TwinStorageTest: stored models are content-addressed and checksummed; export() writes an open-format manifest proving the twin and registry are exportable.
- PropertyTwinApiTest: the full create-property → twin → version → publish happy path over the live API; validation rejects a nameless property; spaces/findings/facts flow end to end.
- LifecycleHappyPathTest: drives the full 17-step chain through the service layer, from spatial and systems maps through the triggered publish.
- LifecycleApiTest: the same chain over live HTTP, including the two gate refusals as 409 responses.
- LifecycleGatesTest: exercises the review, recommendation, work-order, verification and triggered-publish gates directly, confirming each is refused out of order and allowed in order.
- DualAnchoringTest: a spatial anchor holding both a spatial reference and a system reference at once.
- CitationTest: an evidence item cites an observation and records its stance.
- EffectiveDateTest: findings and observations carry their own effective date, separate from when the row was created.