Skip to content

fix(build): a dlopen-surface pass that does not apply publishes a reason, and never over an answer (2026.9.10.2) - #600

Merged
Sunrisepeak merged 3 commits into
mainfrom
fix/a-non-answer-is-published-not-omitted
Sep 9, 2026
Merged

fix(build): a dlopen-surface pass that does not apply publishes a reason, and never over an answer (2026.9.10.2)#600
Sunrisepeak merged 3 commits into
mainfrom
fix/a-non-answer-is-published-not-omitted

Conversation

@Sunrisepeak

Copy link
Copy Markdown
Member

check_dlopen_surface returned without writing in four cases: not Linux, a non-hermetic binding or allow_host_libs, a plan producing no program, a plan producing no linked artifact. Omitting the record makes "the check did not apply" and "the check was never run" the same reading.

It does more than omit a sentence, because the two copies of the record have opposite lifetimes. The sidecar survives an invocation; resolution.json is regenerated from an empty object at the start of one. The backend runs once per drive and a single invocation can drive it more than once — mcpp test builds the library and then links the test binary — so a drive that links only a dependency's shared library has no program, has nothing to answer, and yet decides what the documented place to look finally contains.

The repair has two halves

Every early return now publishes a record carrying its reason. And a non-answer republishes a reading already on file under the same key rather than replacing it with a blank: the key covers the contract hash, the SubOS stamp and the host-libs policy, not the link units, so a reading taken under it is still about this farm and this policy, and a key that moved has already cleared the record. Publishing the reason alone would have turned a silent absence into a loud wrong answer.

What was measured, and what was not

Against the released 2026.9.10.1 in a sandbox, .agents/docs/2026-09-10-596-verify.sh passed sections A to C and section D reported resolution.json has no runtime.dlopen_surface. That run was also the run that installed the dependency into the sandbox registry.

Run again against the same binary in the same sandbox with the registry warm, section D passes: dlopen_surface examined 15 of 15 members.

The ordering of backend drives on the cold run was not captured and has not been reproduced. What is repaired here is the code path that can produce that reading; the unexplained observation is recorded in section 7 of the design record as open, not written up as a diagnosis of that run.

Criterion

DlopenSurfaceRecord.ANonAnswerRepublishesTheAnswerAlreadyOnFile — a unit test rather than an end-to-end case, because reaching it needs two drives over one output directory where the second is the one that does not apply, and no project shape names that.

Both halves were refuted with the repair removed:

  • without the republish branch: after.value("members", 0) is 0, expected 7
  • without the publish at all: stored.is_object() is false, the sidecar was not written

The verification script gained the matching criterion — a published non-answer counts as a failure — because without it the next such overwrite would read as a pass.

Design record: .agents/docs/2026-09-09-dlopen-surface-and-two-unwinders.md §7, §8.6. Follows #596.

…son, and never over an answer (2026.9.10.2)

`check_dlopen_surface` returned without writing in four cases: not Linux, a
non-hermetic binding or `allow_host_libs`, a plan producing no program, a plan
producing no linked artifact. Omitting the record makes "the check did not
apply" and "the check was never run" the same reading.

It does more than omit a sentence, because the two copies of the record have
opposite lifetimes. The sidecar survives an invocation; `resolution.json` is
regenerated from an empty object at the start of one. The backend runs once per
drive and a single invocation can drive it more than once -- `mcpp test` builds
the library and then links the test binary -- so a drive that links only a
dependency's shared library has no program, has nothing to answer, and yet
decides what the documented place to look finally contains.

Every early return now publishes a record carrying its `reason`. A non-answer
republishes a reading already on file under the same key rather than replacing
it with a blank: the key covers the contract hash, the SubOS stamp and the
host-libs policy, not the link units, so a reading taken under it is still
about this farm and this policy, and a key that moved has already cleared the
record. Publishing the reason alone would have turned a silent absence into a
loud wrong answer.

WHAT WAS MEASURED, AND WHAT WAS NOT. Against the released 2026.9.10.1 in a
sandbox, `.agents/docs/2026-09-10-596-verify.sh` passed sections A to C and
section D reported `resolution.json has no runtime.dlopen_surface`; that run
was also the run that installed the dependency. Run again against the same
binary in the same sandbox with the registry warm, section D passes with
`dlopen_surface examined 15 of 15 members`. The ordering of drives on the cold
run was not captured and has not been reproduced, so what is repaired here is
the code path that can produce that reading, recorded as such in section 7 and
section 8.6 of the design record rather than as a diagnosis of that run.

The invariant is a unit test rather than an end-to-end case: reaching it needs
two drives over one output directory where the second is the one that does not
apply, and no project shape names that. Both halves were refuted with the
repair removed -- without the republish branch the reading becomes 0 members,
without the publish the sidecar is not written at all. The verification script
gained the matching criterion: a published non-answer counts as a failure.
A reader who finds `{"members": 0, "walked": 0, "findings": [], "reason": ...}`
has to be told what it means, and told to treat it as "not measured" rather
than as a clean result. Four reasons are published; a target that is not Linux
publishes no record at all, because the record is ELF-shaped and an empty
answer about a format the build never produces is its own confusion.
The object was whatever `find` reached first. A run that also builds a
dependency can leave more than one resolution.json under the work tree, and
traversal order is not a property of the record being tested. The probe builds
one project, so the count is the assertion and the file that was read is
printed beside the result.
@Sunrisepeak
Sunrisepeak merged commit 940d9f2 into main Sep 9, 2026
37 checks passed
@Sunrisepeak
Sunrisepeak deleted the fix/a-non-answer-is-published-not-omitted branch September 9, 2026 19:30
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.

2 participants