Skip to content

fan_tach_health binds to std.goal_assessment, discharging the frontier that named it - #10926

Merged
briansrls merged 6 commits into
mainfrom
session/sleek-newt-698-observed-collision
Sep 10, 2026
Merged

briansrls merged 6 commits into
mainfrom
session/sleek-newt-698-observed-collision

Conversation

@gunbai-bot

@gunbai-bot gunbai-bot Bot commented Sep 10, 2026 •

Copy link
Copy Markdown
Contributor

Finishes the convergence consolidation: product.fan_tach_health was the last
module computing an observe/assess judgement with its own hand-rolled vocabulary
instead of std.goal_assessment.

Why this module, and why now

This is not a migration I picked the shape of. std.goal_assessment already
declared GoalAssessmentRefused a §3c declared frontier and named its
trigger as a consumer rather than a date:

the trigger is a NAMED CONSUMER rather than a date: product.fan_tach_health
already computes exactly this fact -- FanTachRefused over
DuplicateExpectedHeader, DuplicateObservedHeader and HostIdentityMismatch,
each of them an ill-formed question set rather than an unhealthy fan -- and the
arm is discharged when that module is bound to this algebra.

This is that binding. The frontier is now discharged, and discharged by
execution
: three witnesses reach GoalAssessmentRefused on real fleet inputs,
and disabling the host-identity check turns one of them red.

The type split is not cosmetic

GoalDiverged carries FreeSemigroup<Deviation>. Handing that parameter the
undivided seven-arm FanTachVerdict would let a divergence list hold
RotationObserved -- a healthy reading filed as a mismatch, which is exactly the
edit that algebra's own annotation says nothing in the type would stop. So the
verdict splits into FanTachHealthy / FanTachDeviation / FanTachUnknown,
with one FanTachJudgement fold keeping the per-header classification a single
authority and three projections off it (§4b: construction over validation).

One arm changes the answer, not the label

An expected header the collector never answered for used to be a verdict beside
the others, so a host carrying one still read as assessed. Nothing about that
fan was established, so it is now an unknown and the host is indeterminate --
which assess_by_deviations_and_unknowns ranks above any proved deviation, for
the reason that algebra states: remediating a subject whose state is partly unread
is licensed by an answer nobody has.

This is the only behavioural change in the PR, and it is the one the witnesses
work hardest on.

A witness that had never run

While verifying, gunbc.fleet_fan_tach_health_witness turned out to be
referenced by nothing -- absent from local_repo_wet_schedule (46
identities, none of them fan_tach), named by no lane, roster or CI step, with a
corpus grep returning only its own two self-references. Its claims had never
executed on any merge path.

What nearly went wrong: on finding it could not be emitted, I was about to
write a §4b(3) declared rung drop for the lost wet evidence. That would have
declared a regression against a baseline that never existed. Checking enrolment
before writing the drop is what caught it.

Deleting it outright would have discarded five claims the new witness did not
cover -- among them "an intermittent zero is not a fault", the conjunct that makes
the rotation rate load-bearing rather than decorative. So the claims moved to
where they execute first, and only then did the inert module die (§3 delete-first,
and its rule that the minimum Y preserves every required refusal).

Evidence

13 witnesses in dag/test/claim/fan_tach_assessment_witness_test.dag, five of
which exist to keep the others honest: a satisfied host so the divergence is not
vacuous, a fully-read host so the indeterminate arm is not universal, a
well-formed question so the three refusals are not an assessment that refuses
everything, and a roster-identity claim untouched by rate logic.

Three mutation cycles, each predicted-red with green controls:

Mutation Red Controls
missing observation reclassified as a deviation an_omitted_window_is_an_unknown_not_an_assessed_host green
host-identity check disabled one_host_expectation_against_another_hosts_windows_refuses green
judgement keys on any zero instead of the rate floor both rate-dependent claims roster-identity claim green

42 pre-existing witnesses (fabric switch 12, cable plant 6, goal assessment 6,
realization selection 18) unchanged. Namespace wave ADMITTED, 2 deltas, both
auto-admitted, no admission rows required.

Stated plainly, because it bears on how this PR was scoped

I opened this branch to fix a four-way Observed naming fork, having claimed it
broke the repo_ruleset closure and blocked its verification. That claim was
false.
repo_ruleset type-checks clean -- frontend, normalize, reconcile and
analyses all pass, with zero occurrences of Observed in the output, and it does
not import any of the colliding modules. It refuses at emit, for an unrelated
modelled reason (shell transport has no rust realization for
gunbc.WitnessBin.Run). I have retracted the claim and briefed the cleanup lane
not to repeat it; the Observed de-fork landed separately on its §3 merits in
#10915.

fleet_fan_tach_expectation likewise refuses at emit (filter in branch
condition, unprojectable). Verified pre-existing: byte-identical diagnostic on
clean main with this change stashed. That is why the executing evidence here is
a claim witness (interpreted) rather than the wet path.

Follow-up worth its own lane

If one witness module could sit unenrolled and unnoticed since it was written,
the open question is how many others do -- an unrun witness is indistinguishable
from a passing one from the outside. A census of witness modules against the
schedules that actually run them is a lens-shaped question, and it is the
difference between "we found one" and "we know the number."

🤖 Generated with Claude Code

https://claude.ai/code/session_01PUtSkZTNvpWQv58Lk9cGzg

gunbc-ci-auto-heal and others added 2 commits September 10, 2026 03:14
…rontier

std.goal_assessment declared GoalAssessmentRefused a section 3c frontier whose
trigger was a NAMED CONSUMER rather than a date: "product.fan_tach_health
already computes exactly this fact -- FanTachRefused over
DuplicateExpectedHeader, DuplicateObservedHeader and HostIdentityMismatch, each
of them an ill-formed question set rather than an unhealthy fan -- and the arm
is discharged when that module is bound to this algebra." This is that binding.

The seven-arm FanTachVerdict splits into FanTachHealthy, FanTachDeviation and
FanTachUnknown. That is not cosmetic: GoalDiverged carries
FreeSemigroup<Deviation>, so handing it the undivided verdict would let a
divergence list hold RotationObserved -- a healthy reading filed as a mismatch,
which is the edit that algebra's own annotation says nothing in the type would
stop. One FanTachJudgement fold keeps the per-header classification a single
authority; the three extractors are projections of it, not second folds.

ONE ARM CHANGES ANSWER RATHER THAN LABEL. An expected header the collector never
answered for was a verdict beside the others, so a host carrying one still read
as assessed. Nothing about that fan was established, so it is now an unknown and
the host is indeterminate -- which assess_by_deviations_and_unknowns ranks above
any proved deviation, for the reason that algebra states: remediating a subject
whose state is partly unread is licensed by an answer nobody has.

EVIDENCE, AND IT IS EXECUTED. dag/test/claim/fan_tach_assessment_witness_test.dag
carries 8 witnesses, 4 of them controls that exist to keep the other 4 honest --
a satisfied host so the divergence is not vacuous, a fully-read host so the
indeterminate arm is not universal, a well-formed question so the three refusals
are not an assessment that refuses everything. Two mutations were run: missing
observation reclassified as a deviation turns the omitted-window witness red with
both controls green, and disabling the host-identity check turns the cross-host
refusal red with both controls green. The refusal arm is therefore reachable on a
real input, so the frontier is discharged by execution and not by assertion.

The wet witness gains no new evidence here: fleet_fan_tach_expectation cannot be
emitted (filter in branch condition, unprojectable), which reproduces byte-identical
on clean main with this change stashed. The claim witness is the executing path.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01PUtSkZTNvpWQv58Lk9cGzg
… module goes

gunbc.fleet_fan_tach_health_witness was referenced by NOTHING -- absent from
v2.workflow.local_repo_wet_terminal local_repo_wet_schedule (46 identities, none
of them fan_tach), named by no lane, no roster and no CI step. A corpus grep
returned only the file's own two self-references. Its claims had therefore never
run on any merge path, which makes it the section 5 case that is worse than an
absent witness: a file that reads as coverage while being permanently inert.

WHAT NEARLY WENT WRONG. Discovering it could not be emitted, I was about to write
a section 4b(3) declared rung drop for the lost wet evidence. That would have
declared a regression against a baseline that never existed. Checking enrolment
before writing the drop is what caught it -- no rung was held, so none was lost,
and the real finding is older and worse than the one I set out to record.

Deleting it outright would have discarded five claims the new claim witness did
not cover: an intermittent zero is not a fault (the conjunct that makes the RATE
load-bearing rather than decorative), an unwired endpoint is nominal rather than
a missing rotation, a header outside the roster is an authority gap, srv3 and
srv4 differ by identity rather than arity, and srv1's three healthy endpoints
beside its two degraded ones. So this is the second half of a replacement
migration: the claims move to where they execute, and only then does the inert
module die -- rather than surviving as an attractor a later reader mistakes for
a safety net (DESIGN section 3, delete-first, and its rule that the minimum Y
must preserve every required refusal).

They fold the judgements rather than the assessment, because "two degraded
endpoints AND three healthy ones" is a statement about five headers and the
algebra carries evidence on the satisfied arm alone.

EXECUTED, NOT ASSERTED. 13 witnesses green. Mutating the judgement to key on any
zero instead of the rate floor -- the exact defect the dropout control exists to
prevent -- turns both rate-dependent claims red while the roster-identity claim
stays green, so the mutation isolates rather than flattens.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01PUtSkZTNvpWQv58Lk9cGzg
@gunbai-bot gunbai-bot Bot changed the title convergence consolidation fan_tach_health binds to std.goal_assessment, discharging the frontier that named it Sep 10, 2026
@gunbai-bot
gunbai-bot Bot marked this pull request as ready for review September 10, 2026 04:18
…alse

Review 63076, three findings, all confirmed against the code.

GoalAssessmentRefused was constructed at three sites and absent from the import
list. Both sibling bindings import it explicitly, so this was also a section 3
inconsistency. One correction to the finding's severity, which does not change
the fix: it is an `unlisted import use` ADVISORY rather than an unresolved
symbol, which is why 13 witnesses and the whole closure compiled over it.

THE FRONTIER ROW IS RETIRED, and this is the finding worth the diff. The note in
std.goal_assessment still read "AND IT HAS NO CONSTRUCTOR TODAY", still described
the discharge as pending, and still cited FanTachRefused -- a symbol this PR
deletes. So the PR body claimed the frontier was discharged while the carrier
mark said otherwise and pointed at a dead name (section 4b(4): a climb retires
the machinery it obsoletes; section 3: cite a symbol that resolves).

Two things the old note had right are kept rather than lost with it: that
repo_ruleset and the realization-selection witness reach the arm never, which is
a property of THEIR SUBJECTS and not of the arm -- a parameter instantiated at
Never is a binding declaring the arm unreachable for itself, which is the honest
use of it -- and the section 5 reason the arm would deserve to exist with no
consumer at all, because "the world differs" and "the question was malformed"
have different owners.

The rotating_floor annotation cited the wet witness as its reason for existing,
in the same PR that deletes that witness. It now grounds the literal instead:
srv2's healthy endpoints sit at 16-20 and srv1's bad ones at 4 and 9, so 12 is
chosen inside the separating gap rather than measured off the current tree, and
it lives with the caller because fan_tach_health takes the floor as a goal
parameter -- a shared constant would be the fork that parameter prevents.

BOTH OF THE LAST TWO ARE THE SAME DEFECT: an annotation asserting a state this
same diff invalidated. It is the class this session briefed another lane about,
found twice here, and did not catch by re-reading.

13 witnesses green; the four pre-existing suites unchanged at 12/6/6/18.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01PUtSkZTNvpWQv58Lk9cGzg
@gunbai-bot

gunbai-bot Bot commented Sep 10, 2026

Copy link
Copy Markdown
Contributor Author

Addressed review 63076 in 4d47412d388. All three findings verified against the code and fixed.

1. GoalAssessmentRefused not imported — fixed. One correction to the finding's severity that doesn't change the fix: this is an unlisted import use advisory, not an unresolved symbol. That's why the 13 witnesses and the whole closure compiled over it. The finding is still right that it's inconsistent with both sibling bindings, so it's imported now.

2. The frontier row must be retired in the same diff — fixed, and this was the one worth the diff. The note still read "AND IT HAS NO CONSTRUCTOR TODAY", still described the discharge as pending, and still cited FanTachRefused, a symbol this PR deletes. My own PR body claimed the frontier was discharged while the carrier mark said it wasn't and pointed at a dead name.

Two things the old note had right are kept rather than deleted along with it: that repo_ruleset and the realization-selection witness reach the arm never — a property of their subjects, not of the arm, since a parameter instantiated at Never is a binding honestly declaring the arm unreachable for itself — and the §5 reason the arm deserves to exist even with no consumer, because "the world differs" and "the question was malformed" have different owners.

3. rotating_floor — fixed. The annotation cited the wet witness as its reason for existing, in the same PR that deletes that witness. It now grounds the literal properly: srv2's healthy endpoints sit at 16–20 and srv1's bad ones at 4 and 9, so 12 is chosen inside the separating gap rather than measured off the current tree; and it lives with the caller because fan_tach_health takes the floor as a goal parameter, where a shared constant would be the fork that parameter exists to prevent.

Findings 2 and 3 are the same defect — an annotation asserting a state this same diff invalidated — which is the class I briefed another lane about this session and then committed twice here.

CI is red for a reason outside this PR. The 17 parse errors are all in dag/gunbc/machine_intake/megarac_media_attach.dag, which is not in this diff (three files, all fan-tach). It landed on main in #10630 with 17 in-body // annotations that the §4c parser refuses, and main's own run 3fc663339 concluded failure. Every PR inherits it. I've escalated rather than rewriting another lane's module: the blocks sit mid-body inside functions and §4c models module-item grain only, so hoisting means deciding which declaration each attaches to, and the prose is substantive — one block explains a real session-leak defect.

13 witnesses green; four pre-existing suites unchanged at 12/6/6/18.

— sent from sleek-newt-698

…ever read zero

Review 63089, two findings. They turned out to be one defect, and fixing it one
way fixes both.

rotation_anomaly_count and expectation_drift_count were left dangling: their only
consumer was the wet witness this PR deletes, and the replacement imported three
of the five counters. Section 3c red, and pointedly so in a PR whose framing is
that it retires inert code -- leaving two newly-inert functions behind is the same
defect one level down.

Separately the witness projected the closed FanTachJudgement sum onto ad-hoc
string tags and counted them by equality. That re-minted counting the module
already owns as typed folds (section 2), and -- the part that matters -- it made
three assertions unfalsifiable: "no-rotation" was ONLY EVER asserted at zero, so
any drift in the literal, or a rename of the arm behind it, left them permanently
green. That is section 4b's decoration rather than a wall, and it is the same
class this PR's own controls were written to avoid.

So the tags are deleted and every count goes through the module's folds, which
makes a renamed arm a compile error rather than a silent pass. The two orphans
are consumed rather than deleted, because they were exactly the tools the string
comparisons were standing in for. All seven judgement arms now have one typed
counter in one authority; the two healthy arms gained theirs here.

FOUR NEW CONJUNCTS PIN WHAT ONLY READ ZERO. A rotor read twenty times that never
turned, an expected header whose sensor published nothing -- the same verdict arm
reached by the other absence, so a migration collapsing the two causes is visible
here rather than in a postmortem -- a not-expected header spinning anyway, and the
matching zero on the unmodified fleet so the drift control proves more than that
the counter can reach one. The live fleet exhibits none of these, which is
precisely why the old assertions could not be falsified; the fixtures REPLACE a
window rather than adding one, so the roster and denominator stay as declared and
only the reading is under test.

17 witnesses green. Two further mutations, each predicted-red with green controls:
collapsing an unpublished expected header into correctly-absent reds the
publishing-nothing conjunct while the stopped-rotor one stays green, so the two
absences are independently pinned; disabling UnexpectedRotation reds the drift
conjunct alone. Five mutation cycles now stand behind this PR.

No counter is dangling: consumers 6/6/3/3/3/2/2 across the seven.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01PUtSkZTNvpWQv58Lk9cGzg
@gunbai-bot

gunbai-bot Bot commented Sep 10, 2026

Copy link
Copy Markdown
Contributor Author

Addressed review 63089 in 0a5ac86aad3. Both findings verified and fixed — and they turned out to be one defect, so fixing it one way resolves both.

Finding 1 — two counters left dangling. Confirmed: rotation_anomaly_count and expectation_drift_count had only the deleted wet witness as a consumer. Fair point that a PR framed around retiring inert code should not leave two newly-inert functions behind.

Finding 2 — string tags over a closed sum. Also confirmed, and this is the one that mattered. "no-rotation" was only ever asserted at zero in three conjuncts and never pinned positively, so a drift in the literal or a rename of the arm would have left them permanently green. That is the decoration §4b describes, and it is the same class of defect the rest of this PR's controls were written to avoid — I shipped it while mutation-testing against it elsewhere in the same diff.

The fix is one change. All string tags are deleted; every count now goes through the module's typed folds, so a renamed arm is a compile error rather than a silent pass. The two orphans are consumed rather than deleted, because they were exactly the tools the string comparisons were standing in for. All seven judgement arms now have one typed counter in one authority (the two healthy arms gained theirs here).

Four new conjuncts pin what previously only read zero: a rotor read twenty times that never turned; an expected header whose sensor published nothing — the same verdict arm reached by the other absence, so a migration collapsing the two causes shows up here rather than in a postmortem; a not-expected header spinning anyway; and the matching zero on the unmodified fleet, so the drift control proves more than that the counter can reach one.

The live fleet exhibits none of these conditions, which is exactly why the old assertions couldn't be falsified. The fixtures replace a window rather than adding one, so the roster and denominator stay as the fleet declares them and only the reading is under test.

Evidence: 17 witnesses green. Two further mutations, each predicted-red with green controls — collapsing an unpublished expected header into correctly-absent reds the publishing-nothing conjunct while the stopped-rotor one stays green (so the two absences are independently pinned); disabling UnexpectedRotation reds the drift conjunct alone. Five mutation cycles now stand behind this PR. No counter is dangling: consumers 6/6/3/3/3/2/2.

CI remains red for a cause outside this PR. All 17 parse errors are in dag/gunbc/machine_intake/megarac_media_attach.dag, which is not in this diff. It landed on main in #10630 with 17 in-body // annotations the §4c parser refuses; main's own run 3fc663339 concluded failure, so every PR inherits it. Escalated rather than rewritten, because the blocks sit mid-body inside functions and §4c models module-item grain only — hoisting means deciding which declaration each attaches to, and one of those blocks documents a real session-leak defect.

— sent from sleek-newt-698

… its own evidence

Review 63108, two findings, both confirmed.

FanTachSubject packed a `host` beside expectation.host with nothing constraining
them to agree, while the note on that very declaration claimed invalid assembly
was unwritable. It was not: a mismatched pair was constructible, inspect_fan_tach
labelled the receipt from the subject's copy and assess_fan_tach joined windows
against the expectation's, so an inspection could be filed under a host that was
never assessed. The field is deleted and the inspection subject derived from
expectation.host -- one fact in one place (section 3), by construction rather than
an equality check bolted on afterwards (section 4b).

The fail-open control dropped FAN4 and asserted one degradation survived. FAN4 is
one of srv1's TWO degraded endpoints -- 9 rotations in 20 beside FAN5's 4 -- so the
arithmetic was right and established nothing the annotation claimed: it could not
tell "the deviations survive the unknown" from "one of them was the header I
removed". It now omits FAN1, which is healthy at 20 of 20, and asserts both
degradations survive.

THE PATTERN IS THE FINDING. This is the third annotation in this PR to assert a
state the code does not hold -- after one citing FanTachRefused past its deletion
and one citing the wet witness past its deletion. All three are prose written to
describe an intention and never re-read against what the code ended up doing.
Review is catching them; the author is not.

Seven mutation cycles now stand behind this PR, and the seventh exists because the
sixth was wrong. Emptying deviations at the call site reds the omitted-window
conjunct AND the divergence conjunct, because with no deviations and no unknowns
srv1 falls through to GoalSatisfied -- too broad to isolate the claim, and reported
as a confirmation it would have been the same overclaim as the three above.
Emptying known_deviations inside GoalIndeterminate alone reds the target with both
controls green, which is the evidence the annotation actually needs.

59 witnesses green: 17 fan-tach, and 12/6/6/18 across the pre-existing suites,
re-run because the narrow mutation touched std.goal_assessment, an authority five
bindings share. Both mutated files restored byte-identical.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01PUtSkZTNvpWQv58Lk9cGzg
@gunbai-bot

gunbai-bot Bot commented Sep 10, 2026

Copy link
Copy Markdown
Contributor Author

Addressed review 63108 in 62fa70a6230. Both findings verified against the code and correct.

Finding 2 — FanTachSubject.host forks expectation.host. Right, and the annotation on that declaration made it worse: it claimed invalid assembly was unwritable while a mismatched pair was plainly constructible, with inspect_fan_tach labelling the receipt from the subject's copy and assess_fan_tach joining on the expectation's. An inspection could be filed under a host that was never assessed. The field is deleted and the subject derived from expectation.host — one fact in one place, by construction rather than an equality check added afterwards.

Finding 1 — the fail-open control overclaims. Also right. srv1/FAN4 is rotating_count: 9 and FAN5 is 4, so FAN4 is one of the two degraded endpoints. Dropping it and asserting == 1 was correct arithmetic that established nothing the note claimed — it could not distinguish "the deviations survive the unknown" from "one of them was the header I removed". It now omits FAN1 (healthy, 20 of 20) and asserts both degradations survive.

The pattern is worth naming. This is the third annotation in this PR to assert a state the code doesn't hold, after one citing FanTachRefused past its deletion and one citing the wet witness past its deletion. All three are prose written to describe an intention and never re-read against what the code ended up doing. Review is catching these; I am not.

On the evidence, including a correction. Seven mutation cycles now stand behind this PR, and the seventh exists because the sixth was wrong. Emptying deviations at the call site reds the omitted-window conjunct and the divergence conjunct — with no deviations and no unknowns srv1 falls through to GoalSatisfied — so it was too broad to isolate the claim. I predicted it would leave the divergence conjunct green and it did not. Reporting that as a confirmation would have been the same overclaim as the three findings above. Emptying known_deviations inside GoalIndeterminate alone reds the target with both controls green, which is the evidence the annotation actually needs.

59 witnesses green: 17 fan-tach plus 12/6/6/18 across the pre-existing suites, re-run because the narrow mutation touched std.goal_assessment, an authority five bindings share. Both mutated files restored byte-identical.

CI is red for a cause outside this PR, and I have verified it by filename rather than by inference. Extracting the parse failures from run 34442441847 gives 17 errors, all in dag/gunbc/machine_intake/megarac_media_attach.dag, and zero in this diff's three files. #10932 is open to fix it; until that lands every PR in the repo inherits the failure.

— sent from sleek-newt-698

@briansrls
briansrls merged commit 9ccd06e into main Sep 10, 2026
4 checks passed
@briansrls
briansrls deleted the session/sleek-newt-698-observed-collision branch September 10, 2026 14:56
@briansrls
briansrls restored the session/sleek-newt-698-observed-collision branch September 10, 2026 14:58
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