Skip to content

srv3/srv4 are representable now: split alignment from adoption - #9575

Merged
briansrls merged 4 commits into
mainfrom
session/wise-eagle-112-alignment
Aug 28, 2026
Merged

briansrls merged 4 commits into
mainfrom
session/wise-eagle-112-alignment

Conversation

@gunbai-bot

@gunbai-bot gunbai-bot Bot commented Aug 28, 2026

Copy link
Copy Markdown
Contributor

What this closes

gunbc.bmc_fan_alignment_standing held srv3 and srv4 at ObservedProgramNotRepresentableByIntent, and its payload named the exact gap:

per-actuator-group duty offsets and slew limits: the host runs two fan controller entries and BmcFanCurve models one

That gap is closed. extdeps.bmc.pid_control_program ProgramZone carries thermal_demand_controllers and actuator_controllers as separate lists, each ActuatorController with its own feed_forward, output_limits and slew — one thermal demand feeding several actuators, which is the shape that was missing.

Established two independent ways

Not by reading the type:

  1. The representability gate passes on both captured hosts by execution (Lane S: read the deployed fan programs exactly, conserve every occurrence, and gate representability #9491).
  2. The captures themselves carry exactly one stepwise TEMP_SOC controller driving two fan entries — FAN1 and CHASSIS.

The captures are dated 2026-08-27, after the 2026-08-26 hand reconfiguration, so they are the running programs and not their predecessors. I checked this specifically: representability proven against a superseded capture would have produced the same green while being a false claim.

Why a fourth arm and not a reclassification

Neither existing arm is true, and the closest one is dangerous:

arm true? admits apply?
IntentMatchesObservedProgram no — projection is still the old single-actuator curve yes
ObservedProgramNotRepresentableByIntent no longer — the shape exists no
ObservedProgramNotAdopted no — somebody looked, and it decoded whole no

Relabelling into the first would hand the actuator permission to overwrite the quieter hand-split program with the worse curve — the precise outcome this carrier exists to prevent, reached by relabelling with no code change. The true state is representable, read, and divergent from the intent, whose remedy is an operator adoption decision rather than a modelling task or a host visit, so it may not share a reason symbol with either. BmcFanProjectionApplyRefusalCause gains the matching cause for the same reason.

Alignment flipped; actuation did not. Apply stays refused for every host.

The vacated arm keeps its evidence

srv3/srv4 left ObservedProgramNotRepresentableByIntent, but the arm is still live and a future host may occupy it. Deleting its coverage along with the rows that happened to use it would leave a live refusal path with nothing asserting it still refuses — so the witness now constructs that standing instead of borrowing it from the fleet roster, and srv3_srv4_expected_missing survives as that construction's payload rather than becoming dead data.

Verified by execution

  • all twelve witness conjuncts pass
  • discriminating RED: marking srv3 IntentMatchesObservedProgram turns the witness red; restoring returns it green
  • five neighbouring fan witnesses green
  • the new arm surfaced its one real dependent as a non-exhaustive-match refusal in bmc_fan_projection, which is the fail-closed census working

Scope

No actuation change, no adoption, no acoustic claim. Adoption is the next operator decision and is deliberately not taken here.

gunbc-ci-auto-heal and others added 3 commits August 28, 2026 04:56
gunbc.bmc_fan_alignment_standing held srv3 and srv4 at
ObservedProgramNotRepresentableByIntent, whose payload named the exact
gap: "the host runs two fan controller entries and BmcFanCurve models
one". That gap is closed. extdeps.bmc.pid_control_program ProgramZone
carries thermal_demand_controllers and actuator_controllers as separate
lists, each ActuatorController with its own feed_forward, output_limits
and slew -- one thermal demand feeding several actuators, which is the
shape that was missing.

ESTABLISHED TWO INDEPENDENT WAYS, not by reading the type. The
representability gate passes on both captured hosts by execution (#9491);
and the captures themselves carry exactly one `stepwise` TEMP_SOC
controller driving two `fan` entries, FAN1 and CHASSIS. The captures are
dated 2026-08-27, AFTER the 2026-08-26 hand reconfiguration, so they are
the running programs rather than their predecessors -- checked, because
representability proven against a superseded capture would have been a
false claim with the same green.

A FOURTH ARM RATHER THAN A RECLASSIFICATION INTO AN EXISTING ONE.
IntentMatchesObservedProgram is false AND admits apply, so relabelling
into it would hand the actuator permission to overwrite the quieter
hand-split program with the old single-actuator curve -- the exact
outcome this carrier exists to prevent, reached with no code change.
ObservedProgramNotAdopted is false too; somebody looked. The true state
is representable, read, and DIVERGENT from the intent, and its remedy is
an operator adoption decision rather than a modelling task or a host
visit, so it may not share a reason symbol with either.
BmcFanProjectionApplyRefusalCause gains the matching cause for the same
reason.

Alignment flipped; actuation did not. Apply stays refused for every host.

THE VACATED ARM KEEPS ITS EVIDENCE. srv3/srv4 left
ObservedProgramNotRepresentableByIntent but the arm is still live and a
future host may occupy it, so the witness now CONSTRUCTS that standing
rather than borrowing it from the fleet roster, and
srv3_srv4_expected_missing survives as that construction's payload
instead of becoming dead data.

Verified by execution: all twelve witness conjuncts pass; the
discriminating RED holds -- marking srv3 IntentMatchesObservedProgram
turns the witness red and restoring returns it green; five neighbouring
fan witnesses green.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
…iew 57145)

`srv4_maps_to_unrepresentable` held the representable-but-not-adopted
verdict. Cosmetic anywhere else; here it undercuts the change's own
thesis, since the whole point is that "no shape for it" and "shape
exists, nobody adopted it" are different states with different remedies,
and a reader trusting the binding name would take the conjunct as
evidence for the arm it is not testing.

Swept the file for the class rather than fixing the cited line alone: the
other `unrepresentable` names are the constructed vacated-arm conjunct
and its payload, where the word is correct and stays.

Witness re-run green.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
…austive match)

The split added BmcFanProjectionObservedProgramRepresentableNotAdopted to
BmcFanProjectionApplyRefusalCause; bmc_converge's refusal-reason renderer
still matched only the three it replaced. Total at the level examined,
blind to the distinction this PR exists to draw.

Caught by the required floor's strict preparation over the whole corpus,
not by either entry compile or either review.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
@gunbai-bot

gunbai-bot Bot commented Aug 28, 2026

Copy link
Copy Markdown
Contributor Author

CI status on 5044794, with the evidence, because the failing check is not this PR's.

required-witnesses-build: PASS. required-witnesses-floor: FAIL — identically to main.

The floor's previous red on 690e48b was mine and is fixed: strict preparation refused with bmc_converge.dag:192:7: non-exhaustive match: missing variant(s) BmcFanProjectionObservedProgramRepresentableNotAdopted — this PR's fourth arm, with one refusal-reason renderer still matching the three it replaced. That is gone; preparation now completes and the fold runs all 12949 witnesses.

What fails now is main's own 47. Set comparison, not count comparison:

failures
main 33145062452 (3a8344b5c38) 47
this PR 33147617760 (5044794) 47
symmetric difference 0

Both report verdict=FloorRefused unexpected_failures=47. This branch introduces no new failing identity and removes none.

This is the exposure #9106 (c9043b967c7) was predicted to produce: deleting the floor's DeclinedLiveTree arm moved ~900 discovered-and-declined sites into execution, and planned went 11997 → 12944. Main has been red on every run since fe1c389b2 (2026-08-28T03:57Z); the ten underlying facts behind fifteen of those identities are routed as work items already. The remaining ~32 are the unreduced remainder and are not routed.

So there is nothing to fix here, and I am not pushing a change. Merge readiness on this PR turns on main's floor going green, not on this branch.

Local receipt for the fix that was mine, run both ways on one machine with --dependency-pool-index primary-precedence: arm removed → 1 blocking error(s), 492 advisory (the floor's error, same file and line); arm present → 0 blocking error(s), 492 advisory. Identical advisory counts, so the difference is the planted fault rather than drift.

— sent from wise-eagle-112

@briansrls
briansrls merged commit c9f5968 into main Aug 28, 2026
1 of 2 checks passed
@briansrls
briansrls deleted the session/wise-eagle-112-alignment branch August 28, 2026 18:27
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant