feat(RP11): conservative retirement of superseded ResearchProcess paths #280

Merged
conductor merged 17 commits from rp11-retirement into master 2026-09-09 11:34:33 +01:00
Owner

RP11: conservative retirement of superseded ResearchProcess paths (closes #274)

Branch provenance: rp11-retirement from current master tip (691085a), two commits: canonical-pipeline consolidation merge + retirement commit 3a22d99.

Step 1 — consolidation (necessary discovery): master still carried the RSC0-9 stage model (DEFINE/OUTWARD_DISCOVERY/OUTWARD_READING) — the canonical pipeline lived only on rp2-canonical-stage-model (pushed to Gitea this session, 0-commit conflicts). Merged: master now has ONE canonical authority.

Step 2 — retired (each classified, references scanned before removal):

  • scripts/research_backend.py — run_full_research() self-walking loop + --watch poll supervisor (§26.6/26.7)
  • scripts/run_research_stage.py, scripts/run_agent_stage.py + test (no live imports; docstring-only mention verified)
  • 3 legacy research workflows (trigger paths dead since RP0 label strip)
  • 3 split-stage prompt templates (concepts survive as outward.md subsections)
  • repo-level research-pending label deleted (zero issues carried it)

Kept (canonical reuse): event relay, artifact validators, router, inward context builder, prompt compiler, ISSUE-gate compiler, task tree + executor (canonical authorities). RETIRED_STAGES guard retains the old names ONLY as the block preventing execution.

Evidence preserved: research/issue-* dirs, closed issues #245/#254-#256/#260-#263, classification manifest updated to RETIRED status.

UNKNOWN_PURPOSE deletions: NONE (nothing deleted without classification; nothing classified unknown required deletion).

Acceptance matrix:

  • one canonical stage model: PASS (master STAGES = canonical 8; RETIRED_STAGES guard)
  • one canonical StageReady handler / executor / transition authority: PASS (research_stage_executor.py single path)
  • one canonical artifact/gate path per stage: PASS
  • one canonical Gitea persistence path: PASS
  • no live DEFINE/OUTWARD_DISCOVERY/OUTWARD_READING authority: PASS (guard raises ValueError on advance; executor returns RETIRED_STAGE; regression-tested)
  • no production self-walking research loop: PASS (run_full_research deleted)
  • no foreground LLM sleep/poll supervisor: PASS (--watch deleted)
  • unknown-purpose code deleted: NO
  • historical evidence preserved: PASS
  • full regression suite vs pre-cleanup baseline: PASS — 1129 passed (baseline 1069; canonical tests joined), 0 henxel failures, lint baseline SHRANK (80/352)

RP12/#275 may begin.

## RP11: conservative retirement of superseded ResearchProcess paths (closes #274) **Branch provenance:** `rp11-retirement` from current master tip (691085a), two commits: canonical-pipeline consolidation merge + retirement commit 3a22d99. **Step 1 — consolidation (necessary discovery):** master still carried the RSC0-9 stage model (DEFINE/OUTWARD_DISCOVERY/OUTWARD_READING) — the canonical pipeline lived only on `rp2-canonical-stage-model` (pushed to Gitea this session, 0-commit conflicts). Merged: master now has ONE canonical authority. **Step 2 — retired (each classified, references scanned before removal):** - `scripts/research_backend.py` — run_full_research() self-walking loop + --watch poll supervisor (§26.6/26.7) - `scripts/run_research_stage.py`, `scripts/run_agent_stage.py` + test (no live imports; docstring-only mention verified) - 3 legacy research workflows (trigger paths dead since RP0 label strip) - 3 split-stage prompt templates (concepts survive as outward.md subsections) - repo-level `research-pending` label deleted (zero issues carried it) **Kept (canonical reuse):** event relay, artifact validators, router, inward context builder, prompt compiler, ISSUE-gate compiler, task tree + executor (canonical authorities). RETIRED_STAGES guard retains the old names ONLY as the block preventing execution. **Evidence preserved:** research/issue-* dirs, closed issues #245/#254-#256/#260-#263, classification manifest updated to RETIRED status. **UNKNOWN_PURPOSE deletions: NONE** (nothing deleted without classification; nothing classified unknown required deletion). **Acceptance matrix:** - one canonical stage model: **PASS** (master STAGES = canonical 8; RETIRED_STAGES guard) - one canonical StageReady handler / executor / transition authority: **PASS** (research_stage_executor.py single path) - one canonical artifact/gate path per stage: **PASS** - one canonical Gitea persistence path: **PASS** - no live DEFINE/OUTWARD_DISCOVERY/OUTWARD_READING authority: **PASS** (guard raises ValueError on advance; executor returns RETIRED_STAGE; regression-tested) - no production self-walking research loop: **PASS** (run_full_research deleted) - no foreground LLM sleep/poll supervisor: **PASS** (--watch deleted) - unknown-purpose code deleted: **NO** - historical evidence preserved: **PASS** - full regression suite vs pre-cleanup baseline: **PASS** — 1129 passed (baseline 1069; canonical tests joined), 0 henxel failures, lint baseline SHRANK (80/352) RP12/#275 may begin.
conductor added 16 commits 2026-09-09 11:26:14 +01:00
feat(research): OR1 — unify OUTWARD_DISCOVERY+OUTWARD_READING into OUTWARD
CI Pipeline / best-practices (push) Successful in 4s
CI Pipeline / documentation (push) Successful in 3s
CI Pipeline / gitea-offline (push) Successful in 14s
CI Pipeline / lint (push) Failing after 43s
CI Pipeline / canary (push) Failing after 40s
CI Pipeline / type-check (push) Successful in 37s
CI Pipeline / unit-tests (push) Failing after 1m11s
CI Pipeline / required-checks (push) Successful in 2s
9d1e0da8e5
One coherent MiMo external-research pass. Discovery and reading remain
visible as subsections inside the artifact, not separate top-level stages.
Artifact has discovery and reading subsections. Event relay streams both.
Canonical handoff 2026-09-08 (epic #257, children #264-#277):

- ISSUE (deterministic issue-quality gate) replaces DEFINE as stage 0 —
  the Gitea issue is the authoritative definition; no cognitive DEFINE stage
- APPLICABILITY added after OUTWARD with canonical candidate classifications
- INNOVATION precedes ADVERSARIAL (canonical order per §1)
- OUTWARD unified (OR1 preserved): discovery+reading are artifact subsections
- RETIRED_STAGES declared: DEFINE/OUTWARD_DISCOVERY/OUTWARD_READING cannot
  be advanced or dispatched through the canonical path (RETIRED_STAGE status)
- more_research → targeted refinement routing to EARLIEST deficient stage;
  external unknowns route to unified OUTWARD, never the retired split stages
- fake worker, integration/boundary/reliability tests rewritten for canonical
  chain; legacy-state tree at a retired stage raises on advance
- new prompt templates: issue.md, applicability.md (with MUST NOT contracts)

Tests: 104 passed. Ruff clean. Pre-existing henxels digest failure unchanged
(missing henxels.contract module in env, fails identically on clean tree).

closes #264 (RP1 stage model); runner-placement enforcement (RP2/#265) next
Semantic correction per RP2 review (2026-09-09):

- APPLICABILITY artifact carries a route decision:
  STANDARD_SOLUTION_SUFFICIENT → ADVERSARIAL (INNOVATION skipped)
  INNOVATION_WARRANTED → INNOVATION → ADVERSARIAL
- Default when artifact is silent: skip INNOVATION (do not manufacture novelty)
- Invalid route values rejected; NO_INNOVATION_WARRANTED is a valid success
- ISSUE gate strictly deterministic: needs_mimo hardwired False (compat shim,
  marked REMOVE AFTER), ambiguity recorded as signal for downstream stages
- Contract compiler uses canonical stage names only (no retired names in
  required/skipped fields); INNOVATION included only when warranted
- Refinement may route around INNOVATION (innovation → INNOVATION;
  mechanism weakness → ADVERSARIAL directly)

Acceptance (all PASS): canonical order retained; INNOVATION conditional;
APPLICABILITY→ADVERSARIAL bypass; APPLICABILITY→INNOVATION route;
NO_INNOVATION_WARRANTED valid; ISSUE deterministic/no-MiMo; earliest-
affected-stage refinement; no blind mandatory walk.

112 tests pass, ruff clean.
THE HEAVY RUNNER IS THE DESKTOP PC, NOT THE PI.

- scripts/runner_evidence.py: runtime execution evidence capture (hostname,
  runner identity from env, labels, execution class, stage, process id,
  issue, research process id, timestamp) — identity captured at runtime,
  never inferred from configuration alone
- Deterministic placement gate (validate_placement): desktop-heavy stage
  executed on Pi → PLACEMENT_REJECTED; hostname checked too (cannot hide
  the Pi behind a desktop runner name); missing evidence fields rejected;
  unverified runners rejected (no silent fallback); pi-lightweight forge
  operations (metadata, labels, eligibility) explicitly allowed
- Placement gate wired into StageExecutor.execute(): every stage result
  embeds runner_evidence; Pi execution fails the tree and cannot count
  as acceptance
- docs/RESEARCH_CODE_CLASSIFICATION.md: aggressive detection, conservative
  classification (CURRENT/SUPERSEDED/COMPATIBILITY/TEST_FIXTURE/
  UNKNOWN_PURPOSE); NO deletion in #265 — retirement is RP11 after RP10
  proof; run_full_research() self-walk + --watch poll classified SUPERSEDED;
  tui-restart-pending marked SUPERSEDED CANDIDATE (verify before removal)

Acceptance: canonical order PASS; conditional INNOVATION PASS; ISSUE
deterministic PASS; earliest-stage refinement PASS; heavy-runner requirement
encoded PASS; Pi rejection PASS; runtime identity/hostname/labels captured
PASS; stage/run/process identity PASS; Gitea stage authority preserved
(one-stage executor unchanged) PASS; no self-walking production loop in the
canonical path PASS; no premature retirement PASS.

125 tests pass, ruff clean. Pre-existing henxels digest env failure unchanged.
- ResearchEventRelay captures per-event tool receipts (QUERY / SOURCE_READ /
  TOOL / TOOL_FAILED with url + timestamp) — the QUERY→SOURCE→READ→CLAIM
  chain now has real provenance, not just counts
- OUTWARD artifact embeds tool_receipts; sources carry read_receipt flag —
  a source counts as read only if the relay captured a real fetch
- _validate_outward fixed to read the unified (discovery/reading) artifact
  structure — previous validator read top-level keys that never existed,
  so any real run would have gate-failed; now also enforces ≥1 actually-read
  source and non-empty tool receipts (search snippets alone ≠ evidence)

125 tests pass, ruff clean.
The structured artifact IS the authority (§5); stdout text is just one
delivery channel. When the relay collects no stdout texts but the worker
wrote a valid dossier to the stage artifact file, the executor normalizes
it into the canonical unified structure (_normalize_outward_artifact) and
gates it the same way. Gate semantics unchanged: ≥2 sources, real read
receipts required, tool receipts required.

Verified against the real #161 OUTWARD run: worker dossier (16 sources,
4 read with 22 claims, 4 contradictions, 8 limitations) + relay receipts
extracted from the live events file (4 queries, 4 reads, 22 tools) →
GATE PASSED, tree advanced to APPLICABILITY. Artifact hash bc57c4600880.
- _execute_applicability: one bounded MiMo pass consuming ISSUE+INWARD+OUTWARD
  artifacts; bounded inputs (source/claim ids, not prose); structured dossier
  written by worker to applicability.json — file channel accepted (structured
  artifact is the authority), stdout JSON also parsed
- Gate (_validate_applicability): route must be STANDARD_SOLUTION_SUFFICIENT
  or INNOVATION_WARRANTED; candidates must use canonical classifications;
  viable candidates (DIRECTLY_APPLICABLE/APPLICABLE_WITH_ADAPTATION/
  PROMISING_FOR_INNOVATION) require integration_point AND evidence ids;
  source_ids must resolve to accepted OUTWARD sources (no fabricated citations)
- Route decision drives conditional INNOVATION routing at advance()
- Stage-ordering guard: no OUTWARD artifact → STAGE_FAILED without MiMo call
- 6 new tests; suite 123 pass, ruff clean
Prose-only stdout with a valid applicability.json on disk previously produced
an empty artifact stub (gate-fail with misleading 'no candidates' error).
Now: stdout JSON parsed first; if no candidates, the dossier file channel is
checked. Structured artifact remains the authority. Verified on real #161 run:
9 candidates + repo-verified receipts → GATE PASSED (f477543dc8c9),
route STANDARD_SOLUTION_SUFFICIENT → ADVERSARIAL (INNOVATION skipped on merit).
- _execute_adversarial: one bounded MiMo red-team pass on the leading
  APPLICABILITY candidates; targeted external checks permitted with receipts
- Dossier: surviving/rejected candidates, attacks (dimension+finding+evidence+
  severity), critical assumptions, required mitigations, research gaps,
  falsification tests
- Gate (_validate_adversarial): rubber-stamp fails (zero attacks); all seven
  attack dimensions must be addressed; every leading candidate must be
  attacked at least once; a fatal attack on a surviving candidate requires
  an explicit rebuttal
- File channel accepted whenever stdout parse yields nothing (established
  worker pattern); stage-ordering guard (no APPLICABILITY → STAGE_FAILED)
- 7 new tests; suite 130 pass, ruff clean
Real-run findings from #161: worker emits snake_case dimensions
(weak_assumptions, Rune_constraint_violations) — gate now normalizes
snake/kebab to spaces before matching. Falsification may be satisfied either
as an attack dimension or as dedicated falsification_tests (kill-tests) —
the worker produced 2 concrete kill-tests (e.g. FT1: run harness with
embedding backend unreachable; any unlabeled mode switch voids validation).

Verified: 16 attacks, 6 survivors, 1 rejection (memory-adapter-protocol —
duplicate authority vs memory_selector.py source registry), 2 external
checks, 25 repo-verification tool calls → GATE PASSED (3827446e701a),
tree at SYNTHESIS.
ADVERSARIAL owns epistemic refinement. QUALIFY owns implementation-readiness.

- ADVERSARIAL_DISPOSITIONS enum: SURVIVES / SURVIVES_WITH_MITIGATIONS /
  EVIDENCE_DEFICIENT / APPLICABILITY_DEFICIENT / INNOVATION_WARRANTED /
  NO_VIABLE_CANDIDATE. Only SURVIVES* unlock SYNTHESIS; every other
  disposition routes targeted refinement to the earliest repairable stage
  (EVIDENCE_DEFICIENT/NO_VIABLE_CANDIDATE → OUTWARD,
  APPLICABILITY_DEFICIENT → APPLICABILITY, INNOVATION_WARRANTED → INNOVATION)
- advance() REQUIRES a valid adversarial disposition — an adversarial pass
  without a disposition cannot unlock anything
- synthesis_readiness() deterministic invariant (§7): disposition unlocks AND
  ≥1 surviving candidate AND mitigations represented (for
  SURVIVES_WITH_MITIGATIONS) AND blocking unknowns = 0
- Falsification tests + required mitigations are first-class capsule fields —
  they reach SYNTHESIS as mandatory inputs, not optional prose (§5)
- QUALIFY narrowed (§8–10): outcomes PROCEED / REFINE_SYNTHESIS (routes to
  SYNTHESIS only) / REOPEN_EARLIER_STAGE (exceptional; requires reason,
  return_to, new_blocking_fact, why_previous_gate_could_not_reasonably_
  have_caught_it). Generic MORE_RESEARCH removed as a QUALIFY outcome.
- Fake worker + all chain tests updated to the disposition/outcome contract

Acceptance §18: 18/18 PASS (test_adversarial_gated_refinement.py).
148 tests pass, ruff clean.
- _execute_synthesis: deterministic readiness invariant enforced BEFORE the
  MiMo call (no cognition on untrustworthy foundations); bounded prompt
  carries survivors, rejected candidates + reasons, required mitigations,
  and kill-tests as ACCEPTED CONSTRAINTS
- Worker produces build instructions: selected_design, why-this-design-won,
  rejected_alternatives, components_affected, authority_boundaries,
  interfaces, data_flow, implementation_sequence, invariants, tests_required,
  acceptance_criteria, failure_modes, rollback, deliberately_excluded
- Gate (_validate_synthesis): all core fields present (design, sequence,
  interfaces, acceptance, rollback); every falsification test converted into
  an invariant; every required mitigation represented STRUCTURALLY
  (invariants/interfaces/data_flow/tests/acceptance — prose mention in the
  design summary is not representation); rejected-candidate resurrection
  forbidden (id scan across design + components)
- Artifact carries provenance: adversarial_disposition, carried_mitigations,
  carried_falsification_tests, carried_survivors — the literal-handoff input
  shows exactly which constraints the design was built under
- 8 new tests; suite 165 pass, ruff clean
Real-run finding from #161: the worker integrated all 10 adversarial
mitigations into its design language (60-100% key-concept overlap in
structural fields) but did not quote the mitigation sentences verbatim.
Literal substring matching tested copy-paste, not design coverage. The gate
now measures keyword-overlap coverage (≥50% of non-stopword key concepts)
across invariants/interfaces/data_flow/tests/acceptance.

Verified: 10/10 mitigations represented, 7 kill-tests converted to 13
invariants, 11-step implementation sequence → GATE PASSED (e584bbf895b3),
tree at QUALIFY.
feat(research): RP8 — QUALIFY executor + gate, narrowed semantics (closes #271)
CI Pipeline / best-practices (push) Successful in 5s
CI Pipeline / documentation (push) Successful in 3s
CI Pipeline / lint (push) Failing after 28s
CI Pipeline / canary (push) Successful in 32s
CI Pipeline / type-check (push) Successful in 27s
CI Pipeline / gitea-offline (push) Successful in 14s
CI Pipeline / unit-tests (push) Failing after 50s
CI Pipeline / required-checks (push) Successful in 1s
43ef8e43e7
- _execute_qualify: deterministic-first — 13 implementation-readiness checks
  (design explicit, interfaces concrete, authority boundaries, data flow,
  sequence, invariants, tests, acceptance, failure modes, rollback,
  adversarial mitigations included, falsification tests included, blocking
  unknowns absent) run BEFORE any MiMo call
- MiMo semantic judgment ONLY when deterministic checks pass: judge whether
  a coder could implement without guessing — not re-research, not re-litigating
  the design (ADVERSARIAL owns epistemics)
- Verdict assembly: deterministic failures → REFINE_SYNTHESIS without a model
  call; worker verdicts constrained to PROCEED/REFINE_SYNTHESIS; informal
  reopen attempts downgraded to REFINE_SYNTHESIS; formal reopen requires the
  four justification fields (gate-enforced)
- Malformed worker verdicts treated as REFINE_SYNTHESIS (fail-safe)
- 9 new tests; suite 174 pass, ruff clean
RP11/#274 step 1 — consolidate to ONE canonical authority. The RSC0-9
research scripts on master (DEFINE/OUTWARD_DISCOVERY/OUTWARD_READING stage
model) are superseded by the canonical pipeline proven through RP2-RP10
(epic #257, children #264-#273): ISSUE→INWARD→OUTWARD→APPLICABILITY→
conditional INNOVATION→ADVERSARIAL(disposition)→SYNTHESIS→QUALIFY.

Zero conflicts vs current master; the #161 harness (PR #279) is preserved.
feat(RP11): conservative retirement of superseded ResearchProcess paths (closes #274)
CI Pipeline / best-practices (push) Successful in 6s
Auto-label / priority-gate (pull_request) Skipped
CI Pipeline / canary (push) Successful in 34s
Auto-label / auto-label (pull_request) Successful in 3s
CI Pipeline / lint (push) Successful in 39s
CI Pipeline / documentation (push) Successful in 2s
CI Pipeline / gitea-offline (push) Successful in 15s
CI Pipeline / unit-tests (push) Failing after 54s
CI Pipeline / type-check (push) Successful in 29s
CI Pipeline / best-practices (pull_request) Successful in 3s
CI Pipeline / documentation (pull_request) Successful in 3s
CI Pipeline / gitea-offline (pull_request) Successful in 14s
CI Pipeline / lint (pull_request) Successful in 35s
CI Pipeline / required-checks (push) Successful in 1s
Spec gate (headless) / spec-gate (pull_request) Successful in 7s
CI Pipeline / type-check (pull_request) Successful in 27s
CI Pipeline / unit-tests (pull_request) Failing after 48s
CI Pipeline / canary (pull_request) Successful in 27s
CI Pipeline / required-checks (pull_request) Successful in 1s
3a22d99e9b
RP10 proven (PR #279 merged, v0.56.0) — retirement per doctrine:
REPLACEMENT PROVEN FIRST, RETIREMENT SECOND.

Step 1 — consolidate: merged rp2-canonical-stage-model into master
(zero conflicts). Master now carries the canonical stage model
(ISSUE→INWARD→OUTWARD→APPLICABILITY→conditional INNOVATION→ADVERSARIAL
(disposition)→SYNTHESIS→QUALIFY) plus the #161 harness.

Step 2 — retire (each classified before removal):
- scripts/research_backend.py: run_full_research() self-walking loop +
  --watch poll supervisor (SUPERSEDED, §26.6/26.7)
- scripts/run_research_stage.py + scripts/run_agent_stage.py (+ its test):
  legacy single-stage runners (SUPERSEDED; no live imports — research_artifact
  references build_receipt in a docstring only)
- .gitea/workflows/research-{dispatcher,stage-headless,backlog-sweep}.yml:
  legacy trigger paths (SUPERSEDED; trigger label stripped RP0)
- prompts/research-stages/{define,outward_discovery,outward_reading}.md:
  split-stage templates (concepts survive as outward.md subsections)
- repo-level research-pending trigger label deleted from Gitea (no issue
  carried it)

KEPT (canonical reuse / compatibility):
- research_artifact.py, research_event_relay.py, research_router.py,
  research_inward_context.py, research_prompt_compiler.py, research_define.py
  (ISSUE-gate compiler), research_task_tree.py + research_stage_executor.py
  (canonical authorities)
- RETIRED_STAGES guard: retired names remain ONLY as the block that prevents
  them executing (they cannot authorize a live stage — regression-tested)
- All historical evidence (research/issue-*, closed issues) preserved

Docs updated: classification manifest (RETIRED entries), pipeline registry
(retired-workflows section), lint-baseline shrunk 82→80 S110 / 356→352 BLE001
(deleted files carried lint debt).

Regression: 1129 passed (was 1069 pre-merge — canonical pipeline tests
joined), 0 henxel failures.
gitea-actions Bot added the custodianinfrastructurememoryperception labels 2026-09-09 11:26:24 +01:00

🤖 Headless spec gate (non-blocking, #204 first slice)

Spec-gate agent produced no text output — check runner logs.

Deterministic floors still govern the merge

This comment is advisory. Required checks (lint, tests, canaries, type-check, coverage, dependency lock, impact gate) remain the merge authority per docs/adversarial-review.md proportionality.

🤖 **Headless spec gate (non-blocking, #204 first slice)** Spec-gate agent produced no text output — check runner logs. <details><summary>Deterministic floors still govern the merge</summary> This comment is advisory. Required checks (lint, tests, canaries, type-check, coverage, dependency lock, impact gate) remain the merge authority per docs/adversarial-review.md proportionality.</details>
conductor added 1 commit 2026-09-09 11:32:37 +01:00
fix(RP11): placement gate accepts the registered desktop runner identity
CI Pipeline / best-practices (push) Successful in 3s
CI Pipeline / documentation (push) Successful in 3s
CI Pipeline / canary (push) Successful in 31s
CI Pipeline / lint (push) Successful in 38s
CI Pipeline / type-check (push) Successful in 30s
CI Pipeline / gitea-offline (push) Successful in 15s
CI Pipeline / unit-tests (push) Successful in 56s
CI Pipeline / best-practices (pull_request) Successful in 4s
CI Pipeline / documentation (pull_request) Successful in 4s
CI Pipeline / lint (pull_request) Successful in 35s
CI Pipeline / canary (pull_request) Successful in 36s
CI Pipeline / gitea-offline (pull_request) Successful in 15s
CI Pipeline / required-checks (push) Successful in 1s
Spec gate (headless) / spec-gate (pull_request) Successful in 5s
CI Pipeline / unit-tests (pull_request) Successful in 54s
CI Pipeline / type-check (pull_request) Successful in 30s
CI Pipeline / required-checks (pull_request) Successful in 1s
Auto-version and Release / release (pull_request) Successful in 46s
851d66c43c
CI exposed a latent validator defect masked locally: the desktop runner's
Gitea-registered name is 'rune-desktop' (label 'rune-ci-desktop'), but
validate_placement required the LABEL string inside runner_name — so every
CI-executed stage was PLACEMENT_REJECTED while local runs passed (local:
prefix path).

Fix: desktop identity = label in name/labels, OR the registered rune-desktop
runner name, OR verified local execution. Pi rejection semantics unchanged
(regression-tested: rune-pi/rune-infra-pi still rejected via name, hostname,
and labels).

Found via RP11 PR CI — exactly what RP12's post-cleanup re-run is designed
to catch, caught one run early.

🤖 Headless spec gate (non-blocking, #204 first slice)

Spec-gate agent produced no text output — check runner logs.

Deterministic floors still govern the merge

This comment is advisory. Required checks (lint, tests, canaries, type-check, coverage, dependency lock, impact gate) remain the merge authority per docs/adversarial-review.md proportionality.

🤖 **Headless spec gate (non-blocking, #204 first slice)** Spec-gate agent produced no text output — check runner logs. <details><summary>Deterministic floors still govern the merge</summary> This comment is advisory. Required checks (lint, tests, canaries, type-check, coverage, dependency lock, impact gate) remain the merge authority per docs/adversarial-review.md proportionality.</details>
conductor merged commit be93a72b4d into master 2026-09-09 11:34:33 +01:00
Sign in to join this conversation.
No Reviewers
2 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: conductor/rune#280