Skip to content

Seed infer joins a service receiver by owner module + name; a same-named import refuses at the receiver - #12265

Closed
gunbai-bot[bot] wants to merge 12 commits into
mainfrom
session/wise-lynx-177
Closed

gunbai-bot[bot] wants to merge 12 commits into
mainfrom
session/wise-lynx-177

Conversation

@gunbai-bot

@gunbai-bot gunbai-bot Bot commented Sep 25, 2026

Copy link
Copy Markdown
Contributor

What

Seed (v1) infer joined a service receiver to the service registry by bare name, so import std.resources { Filesystem } (a resource: write -> written) silently got extdeps.filesystem.filesystem_io's service Filesystem (Write -> success, bytes_written, path, error). Receipt: #12185 runner_guest_image. This is the fourth specimen and the next rung of gunbc.recurring_failure_mode surface_shorthand_preempts_resolved_identity.

Earliest unjustified boundary (§6b)

The problem was not only the bare-name key. build_module_context's census fold seeded every bare-declared service in the closure into every module, both as a registry row and as a root local. local_is_service_root_binding had no way to see owners, because a module could reach a service it never imported. The repair is made where scope is built:

  • Scoped registry and roots. A bare-declared service (namespace root == name) is in a module's scope only when the module declares it or imports its owner by that name. The deciding functions are v1.compiler.infer census_service_in_scope for the census fold and imported_service_in_scope for merge_scope_from_imports. The join is therefore on declaration identity, owner module plus name.
  • Receiver refusal, no fallback. New CompilerDiagnostic ServiceOwnerMismatch { name, service_owner, bound_owner, span } blocks at the receiver's span (service_owner_mismatch_refusal). It fires where a receiver would have reached the old join through another module's same-named explicit import.
  • Collisions are decided by position, not order (agreed with neat-boar-16). When the service and a same-named import are both in scope:
    • if the other declaration is a value (fn or data), there are two values under one name, and every receiver read refuses;
    • a type or resource does not compete. A resource is a value only through a uses binder, which is a body local judged by its own type.
  • Dotted services (shell.Exec, git.*, …) are keyed by dotted name, never reach this bare-name join, and are not scoped here.

Evidence (executed locally with the seed built from this branch's regenerated mirror)

test.claim.service_owner_identity_witness, one-axis producer over the real same-named pair:

test unchanged seed this branch
the_imported_service_write_is_accepted: service import, Filesystem.Write, reads .success, 0 blocking true true
the_resource_homonym_write_refuses_at_the_receiver: resource import (service in closure, not in scope), exactly 1 ServiceOwnerMismatch/Filesystem false true
two_values_under_one_name_refuse_at_the_receiver: designed pair test.fixture.service_owner_identity.{service,value} false true
a_resource_beside_the_imported_service_does_not_collide: both imported, uses fs: Filesystem + service Write; 0 mismatch, Write exists — true
importing_the_resource_alone_is_not_refused true true
an_unimported_service_is_not_reached_by_its_bare_name (control, unchanged: undefined variable) true true
  • Regen: claim_executor --required-regen gives first_generation_equal=true for the installed mirror. --required-regen-fixed-point gives fixed_point_equal=true. The drift was exactly v1_compiler_emit.rs, v1_compiler_infer.rs, v1_std_core.rs. The hand-authored cli_run/compile_clean.rs gains the class and subject arms.
  • Floor strict-preparation, this branch: completed, 0 errors, modules_resolved=2134.
  • runner_guest_image control: it already imports extdeps.filesystem.filesystem_io { Filesystem } (One HTTP method set, homed at its upstream: extdeps.ietf.http_semantics #12185), so its receiver resolves to the service's owner. It is in the prepared closure and resolves clean.

Census: every site that loses the bare-name join

Found by a static scan: bare-declared-service receivers Name.Op( in modules that neither declare nor import the owner by name. The executed census is the scoped floor: with the repairs reverted, strict-preparation refused at dag/test/claim/spark/pair_serving_authority_log_real_execution_witness_test.dag:392 ("method 'Write' cannot be resolved: receiver type 'Primitive(std.resources.Filesystem)'") and stops at the first refusal. Every site below means the service (each reads .success, .content, .entries, .ok), so each is repaired by importing the owner:

  • Wrong owner: a resource or type was imported, and the service was taken by spelling.
    • gunbc.runner_attempt_launch, gunbc.runner_microvm_cell_readiness_store, gunbc.runner_microvm_lifecycle_realize: std.resources { Filesystem } replaced by the service import.
    • gunbc.runner_microvm_slot_controller: keeps std.resources { Filesystem } for its uses requirements, and adds the service import.
    • test.claim.filesystem_write_witness: v2.extdeps.file_system { Filesystem } (a type) replaced by the service import.
    • test.claim.filesystem_list_hermetic_witness_test: drops the unused v2.extdeps.file_system { Filesystem }; it already imports filesystem_io.
  • Missing import:
    • Filesystem: gunbc.roadmap_served_observation, gunbc.runner_microvm_boot_probe, gunbc.scm.repository_load, gunbc.srv3_os_install_actuate, gunbc.tools.card_intake, test.claim.emit_host_typed_smoke_test, test.claim.filesystem_write_closure_scale_witness, test.claim.spark.pair_serving_authority_log_real_execution_witness_test, test.claim.tailscale_acl_witness_test, test.fixture.effect_reach_conjunction.host_sink_provider, v2.test.claim.complexity.accumulator_copy_unreadable_subject_test.
    • Urandom: gunbc.plans.blackjack_onboarding, test.claim.random_bytes_csprng_witness_test.
    • Clock: test.claim.clock_freshness_witness.
    • GovernedUniversalProbe: test.claim.m4_universal_corpus_witness.

Recorded, not fixed

  • RFM residual (on surface_shorthand_preempts_resolved_identity): runner_microvm_slot_controller still spells Filesystem for two declarations. It is unambiguous by position, but it is still a §3 meaning fork. Trigger: qualified or aliased import references.
  • Next step, a separate PR: scope the dotted service root locals (shell, git, github, …) to imports and declarations. Its census should be the refusals on a scoped build, not a heuristic count.
  • Refusal class for unimported bare names: a bare Filesystem with no import resolves by global uniqueness to std.resources.Filesystem. Write then refuses as MethodExistenceUndecided at the receiver: typed and located, but not ServiceOwnerMismatch, since no explicit import states the other owner.

🤖 Generated with Claude Code

gunbc-ci-auto-heal and others added 3 commits September 25, 2026 00:11
…med import refuses at the receiver

The census fold seeded every bare-declared service of the closure into every module, so a
receiver joined a service by leaf name and `import std.resources { Filesystem }` got
extdeps.filesystem.filesystem_io's Write. Bare-declared services are now in scope only when
declared or imported by name from their owner; ServiceOwnerMismatch refuses at the receiver
where the old join would have fired, and two values under one name refuse rather than being
decided by insertion order. 21 sites that reached a service by spelling now import its owner.
Stage0 mirror regenerated (first generation equal, fixed point equal).

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
…he modules this change made import-bearing

The three mirror files are regenerated against merged main (first generation equal, fixed
point equal). Five modules that had no import before this change received their first
(the service owner) and so stopped being import-less; each now names the imports it used
by bare name, from the resolver's own effect-summary refusals. extdeps.tailscale.acl passed
List.first()'s Optional where a TailscaleGrant was declared; it now eliminates it.

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

gunbai-bot Bot commented Sep 25, 2026

Copy link
Copy Markdown
Contributor Author

Pushed 7083849 for the floor red on 84eabd5.

Cause. Adding the service-owner import gave several previously import-less modules their first import. A module with no imports reaches other modules' declarations by bare name; once it has an import, that no longer applies. test.claim.tailscale_acl_witness then pulled extdeps.tailscale.acl in under strict judgement. That exposed two real defects there: List.first()'s Optional was passed where a TailscaleGrant or List was declared. Each is now eliminated with a match; the Absent arm is false, which the existing length == 1 guard already implies.

Repair. Of the repaired modules, eight had no imports at base. The ones with bare cross-module calls now name the imports they used: tailscale_acl_witness, srv3_os_install_actuate, random_bytes_csprng_witness_test. The lists were derived from the resolver's own "effect summary incomplete" refusals and re-run until each module resolves; the other five already resolved. The tailscale witness returns true on the rebuilt seed.

Merge. main is merged and the mirror regenerated on it: first_generation_equal=true, fixed_point_equal=true.

Unrelated, still red. gunbc.runner_microvm_lifecycle_realize (systemd.Journalctl, a dotted service it never imports) fails identically on the unchanged seed. It is pre-existing and outside the gate closure, not this PR.

— sent from wise-lynx-177

gunbc-ci-auto-heal and others added 3 commits September 25, 2026 03:08
…l); take main's acl.dag Optional elimination

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

card_intake, filesystem_write_closure_scale_witness, random_bytes_csprng_witness_test and
filesystem_list_hermetic_witness_test reached types, variants and dotted service roots by bare
name while import-less, or through the import this change removed; each now names them.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
…over the whole set

The services census held one row per spelling, so a second same-named service replaced the
first before ambiguity was judged, and the conflict check kept only the first explicit owner
and ignored `import *`. The census now holds every declaration of a name; a module's
candidates come from its declarations and all imports (named and `import *`), and the decision
is taken after collection: exactly one service is admitted, a type or resource beside it does
not compete, and two or more services or a service beside a fn/data value refuse as
AmbiguousReference (bare at the receiver, dotted at the spine). The import fold no longer
registers bare or plural services one import at a time. The bare-reference closure pulls a
service head only when exactly one module declares it and refuses a plural pull by name.

Controls: two same-named designed services in both import orders and through `import *`,
either alone while both exist, service+resource admitted in both orders, service+resource+data
refused in both orders. Mirror regenerated: first generation equal, fixed point equal.

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

gunbai-bot Bot commented Sep 25, 2026

Copy link
Copy Markdown
Contributor Author

Receipt for the hand-Rust census_single_service_owner in cli_run.rs (review 71175, advisory):

  • Why hand Rust at all. It is not a new route. The bare-reference closure (bare_reference_closure resolve loop) is existing hand-authored host code that already read census.services at two sites with .map(|entry| entry.module_path). This PR changes SymbolIndex.services in v1.compiler.infer_env from one entry per name to every declaration of that name. Those two reads had to adapt, and the helper is that adaptation, written once instead of twice.
  • What it replaces. A single-owner projection that, under the new type, would have had to pick an element: the order-dependent join this PR exists to remove. It decides zero, one, or many over the whole set. The many case refuses by name, mirroring the neighbouring closure_bare_disposition AmbiguousOnChain refusal.
  • Deferral. It lives and dies with the bare-reference closure, which is seed host code under gunbc.v1_maintenance_standing v1_seed_standing. No new seed surface is added beyond the reader's own shape change.

— sent from wise-lynx-177

gunbc-ci-auto-heal and others added 6 commits September 25, 2026 08:56
…e; host pull refuses a plural name

- A conflicted service name gets no registry row and no root local: conflicts are computed
  first, the census fold skips them, and a module's own declared service of that name is
  dropped (without_conflicted_names / without_conflicted_bindings).
- The value-position decision is one function over the whole population
  (service_candidates_conflict): two or more services, or a service beside a fn/data value,
  refuse with the sorted union of every service AND value owner.
- Host closure: census_single_service_owner decides over the whole owner set via the pure
  decide_service_owner_pull (none / exactly one pulled / refusal naming all). The bare half
  runs only for import-less files (source_declares_import_lines), so it never meets a named
  or wildcard import; that gate is pinned by a unit test. Enrolled as a seed-growth receipt
  (gunbc.service_owner_pull_seed_growth).
- Controls: two services + data refuse once in either order (witness), the candidate
  population is pinned on service_candidates_conflict (unit), real-file probes import either
  service alone by name and by wildcard. Mirror regenerated: first generation and fixed
  point equal.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
…ds imports by identity

main's #12205 runs visit_bare_reference_providers for importing files too
(unimported_bare_providers), so the service census reader now sees named and wildcard
imports: when the file imports any owner of the name, the import provides it and inference
decides; only an unimported name is resolved here (one owner, or a refusal naming all).
Unit tests read each import form through extract_import_paths. Mirror regenerated on merged
main: first generation equal, fixed point equal.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
… the tailscale witness; fixture op no longer collides

- floor_unimported_bare_provider_debt_roster: filesystem_list_hermetic_witness_test#ExpectSuccess
  and filesystem_write_witness#Filesystem move ActiveDebt -> Retired { ImportsFixed }.
- tailscale_acl_witness_test imports v2.std.algebra { length } now that it declares imports.
- The designed OwnerIdentityProbe services' operation is OwnerIdentityPing, not Ping, which
  the unimported-bare-provider gate read as a reference to extdeps.firmware.uefi_shell Ping.
Local floor: unimported-bare-provider-gate refusals=0.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
…erpreter returns

unimported_bare_provider_roster_at_base returns UnimportedBareProviderBaseRoster, a coproduct
(BaseRosterShown | BaseRosterUnreadable), so the interpreter answers with a Variant carrying the
arm's fields. The host read only a Record, so the first change to edit the roster (this one,
retiring two ImportsFixed pairs) refused as ChangedWitnessObservationFailed on a well-formed
answer. Accept both shapes; field reading is unchanged.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
…on it (first generation equal)

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
@briansrls
briansrls added this pull request to the merge queue Sep 25, 2026
@github-merge-queue
github-merge-queue Bot removed this pull request from the merge queue due to failed status checks Sep 25, 2026
@briansrls briansrls closed this Oct 6, 2026
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