audit(0089): cycle close — record acyclicity lockstep + C24 ledger refresh; rm ephemeral spec/plan

Cycle-close audit for the /boss run that followed up the cycle-0088 construction
fieldtest (#161 cycle-reject + #162 diagnostics-by-identifier). Regression gate:
full workspace suite green (0 failed).

Architect drift review (range 86841b0..HEAD): drift_found, two items, both
documentation-side — the code is correct and green.
- What holds: invariant 5 / C9 acyclicity (closes_cycle is a correct eager
  reachability gate, no false positive on a valid DAG); C24 no-second-validator
  (blueprint.rs untouched, finish() only translates the gates' returned
  CompileError); fieldtest corpus handled per convention.
- Resolved (fix path, ledger): the C24 Status now enumerates the #161 eager
  acyclicity gate and captures the LOCKSTEP the architect flagged — closes_cycle
  (construction-time) and the bootstrap Kahn sort (harness.rs, BootstrapError::Cycle)
  are now two homes of invariant-5 that must co-evolve when the explicit
  delay/register node lands; plus a note that the holistic finalize faults now read
  by-identifier (#162) while still calling the unchanged gates.

Ephemeral 0089 spec + plan git-rm'd per the active-cycle artefact lifecycle; the
durable rationale is lifted to the ledger above. No code change in this commit.
This commit is contained in:
2026-06-30 11:57:25 +02:00
parent f1ab81d1b8
commit 7ad7f58798
3 changed files with 16 additions and 498 deletions
+16 -2
View File
@@ -1797,7 +1797,8 @@ introspectable construction service**: a declarative, replayable by-identifier
op-script (`aura graph build` / `introspect` over a JSON op-list, the engine
`GraphSession` / `replay`) builds a runnable blueprint through validated ops — the
engine's construction gates split into *eager* per-op checks (name resolution, edge
kind-match, the double-wire arm, param bind) and *holistic* finalize checks (wiring
kind-match, the double-wire arm, param bind, and acyclicity — a `connect` that would close a
cycle is rejected eagerly, #161) and *holistic* finalize checks (wiring
totality, param-namespace injectivity, root-role boundness), **both cadences calling
the same extracted predicates** (`edge_kind_check`, the shared resolution helpers,
`check_root_roles_bound` — no second validator) — plus build-free introspection over
@@ -1806,7 +1807,20 @@ slots). It **emits** the #155 blueprint; acceptance met: a graph built purely th
the ops compiles identical (C1) to its Rust-built twin, an invalid op is rejected at
the op naming the cause, introspection answers without a build. The engine `Op` stays
serde-free (the wire DTO is CLI-side); the vocabulary's enumerable companion
(`std_vocabulary_types`) lives in `aura-std` (no registry, invariant 9). **Remaining**
(`std_vocabulary_types`) lives in `aura-std` (no registry, invariant 9). **Cycle
0089 follow-up (#161 / #162, after the cycle-0088 fieldtest).** The eager acyclicity
gate above (`GraphSession::closes_cycle`, a reachability check at the closing
`connect`) closed a fieldtest-found hole where `graph build` accepted a non-DAG
op-list (invariant 5 / C9). **Lockstep:** it is a *second* home of invariant-5
alongside the bootstrap Kahn sort (`harness.rs`, `BootstrapError::Cycle`); the two
must co-evolve when the explicit delay/register node — invariant-5's sole legal
feedback — lands, or a valid delay-feedback graph the bootstrap accepts would be
rejected at construction. The holistic *finalize* faults now also read
**by-identifier** (#162): `finish()` translates the index-carrying `CompileError`s
(`UnconnectedPort` / `RoleKindMismatch` / `UnboundRootRole`) into by-identifier
`OpError` variants — still *calling* the unchanged holistic gates (the
no-second-validator lockstep preserved), only translating their result.
**Remaining**
(each its own milestone issue): the forward-compat *must-understand* gate (#156);
content-addressed topology identity in the manifest (#158, C18); retiring the pre-C24
hard-wired `aura-cli` harnesses (`HarnessKind`, `run_stage1_r`, `*_sweep_family`) once