Repository navigation
v1: register service ops node-locally (fix Filesystem dropped by name-collision poison at closure scale) - #5670
Merged
Merged
Conversation
briansrls
marked this pull request as ready for review
June 23, 2026 20:38
gunbai-bot Bot
pushed a commit
that referenced
this pull request
Jun 23, 2026
…required data name extdeps/ctrl/jobserver.dag declared its anchor as `ctrl_jobserver_authority`, but the extdeps_external_authority_gate projector (read_external_authority_anchor_from_items) matches the data def by the EXACT name `extdeps_external_authority_anchor`. So jobserver projected as Absent -> a "missing:extdeps.ctrl.jobserver" violation, turning extdeps_external_authority_live_clean_tree_holds() false on main (landed via #5663/#5670). That is the batch-2 failure my PR inherited through the merge (corpus_live_clean_tree_holds / corpus_live_anchored_modules_clean_holds + extdeps_external_authority_gate_passes all RED). Rename the data def to the required name (no other ref to ctrl_jobserver_authority exists in dsl/ or src/v2/). Verified: both authority witnesses flip GREEN, my oomd witness stays green. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
briansrls
added a commit
that referenced
this pull request
Jun 24, 2026
…tdeps/systemd unit-management interface plus oomd config surface, apt install-as-effect, and a gunbc install Realization that grounds OomdEnforced from a verify/show-effective read (#5677) * WIP: Model systemd-oomd as a dependency (pure .dag, no live execution): extde * WIP: Model systemd-oomd as a dependency (pure .dag, no live execution): extde * Model systemd-oomd as a dependency (pure .dag): reconcile carrier + systemd/oomd interface + apt install-effect + grounded OomdEnforced Shared std carrier (std/realization_reconcile.dag), first instance = oomd: - reconcile(apply_effect, show_read, grounding) -> Converged{evidence} | NotConverged{reason}. Substrate deviation from the pre-signed fn(R)->Grounding<E> param (v1 seed cannot type a fn-typed param returning a generic-applied enum); closest faithful form takes the grounding value and enforces the read-presence gate. Section-5 invariants kept: ReadAbsent => NotConverged (evidence impossible without an observed read); the verdict never depends on apply_effect (threaded as provenance only). extdeps systemd interface (consolidated under the existing extdeps.os.systemd home, reusing SystemdUnitActiveState from #5635 rather than minting a parallel enum): - extdeps/os/systemctl.dag: enable / start / set-property / daemon-reload / is-active / show-effective-property operation shapes + UnitFileState; unit is always a parameter. - extdeps/os/oomd.dag: oomd config surface (ManagedOOMMemoryPressure/Swap, pressure limit/duration, oomd.conf globals) + oomctl dump read; real names from oomd.conf(5) and systemd.resource-control(5). apt install-as-effect: - extdeps/apt.dag: Install operation (package is a parameter, no business literal) + systemd-oomd-defaults package, reusing the existing package-name concept. gunbc install Realization (sibling to os_install.dag), instance #1 of the carrier: - gunbc/oomd_install.dag: compose apt-install + runner-slice ManagedOOM drop-in + enable/start + a show-effective VERIFY that GROUNDS OomdEnforced. Pure .dag, no live execution: committed read is ReadAbsent, so the carrier derives OomdUnverified (fail-closed). OomdEnforced is derivable ONLY from a ReadObserved carrying an active unit AND effective ManagedOOMMemoryPressure=kill. Witness (claim_batch-discoverable), discriminating by execution: - managed read (active + kill) grounds OomdEnforced; unmanaged (auto), inactive, and absent reads stay OomdUnverified. Fail-open perturbation (auto also grounds) flips the witness RED, proving the grounding is real, not a constant. Does not touch committed gunbc_fleet_oomd_evidence (stays OomdUnverified until a real live verify runs through the carrier). Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * WIP: Model systemd-oomd as a dependency (pure .dag, no live execution): extde * Fix main-red: name jobserver's external-authority anchor to the gate-required data name extdeps/ctrl/jobserver.dag declared its anchor as `ctrl_jobserver_authority`, but the extdeps_external_authority_gate projector (read_external_authority_anchor_from_items) matches the data def by the EXACT name `extdeps_external_authority_anchor`. So jobserver projected as Absent -> a "missing:extdeps.ctrl.jobserver" violation, turning extdeps_external_authority_live_clean_tree_holds() false on main (landed via #5663/#5670). That is the batch-2 failure my PR inherited through the merge (corpus_live_clean_tree_holds / corpus_live_anchored_modules_clean_holds + extdeps_external_authority_gate_passes all RED). Rename the data def to the required name (no other ref to ctrl_jobserver_authority exists in dsl/ or src/v2/). Verified: both authority witnesses flip GREEN, my oomd witness stays green. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * Fix tree-wide main-red: regenerate ROADMAP.md from authority (dedup merge-artifact CI-humming line) ROADMAP.md is a generated projection of gunbc.roadmap_authority (the GeneratedArtifactDriftGate enforces committed == expected_roadmap_md()). A textual git-merge of origin/main duplicated the '→ [CI humming]' line; the authority emits it once, so the committed file drifted and the floor drift gate returned Bool(false) (main has carried this red since the bad merge). Regenerated via main_wet on dsl/tools/generated_artifact_gate.dag; no hand-edit. Drift gate now green by execution. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * WIP: Model systemd-oomd as a dependency (pure .dag, no live execution): extde * Strengthen OomdEnforced grounding to a full conjunction; retarget to the SESSIONS slice (close the oomd-active-alone fail-open) Per the CI-humming critical path (bright-stag-194 / sharp-heron-321 / fierce-carp-462): OomdEnforced must NOT be satisfiable by systemd-oomd being active alone — an active oomd with no managed session cgroup has nothing to evict-within under aggregate pressure (zero protection), a §5 fail-open. ground_oomd_from_read now requires the full conjunction over the effective read: (a) the managed sessions slice EXISTS (b) effective ManagedOOMMemoryPressure == kill on the slice (c) per-session memory.max == C (the eviction ceiling) AND parent sessions.slice MemoryMax == the measured aggregate reservation — both BYTE ceilings, reusing the §3 single authority RunnerSliceCapEffectiveness (CapUnbounded => fail-closed) (d) ManagedOOMMemoryPressureLimit == intended PSI percent — a SEPARATE Percent fact, never conflated with the byte caps (systemd's MemoryPressureLimit takes a PSI percentage, not bytes) (e) systemd-oomd active AND enabled (UnitFileState == UnitEnabled) (f) oomctl confirms the slice is in oomd's managed set Thresholds (C, aggregate, PSI%) are PARAMETERS resolved from their single authorities (REGIME-2 oomd_eviction_ceiling / aggregate_reservation; policy PSI default 60), not minted here. Retarget: the ManagedOOM policy + drop-in now target the (held, not-final) sessions.slice — the oomd subject — not gunbc-runner.slice, which was both the wrong subject (the runner slice is hard-capped, never evicted) and a §3 nickname for the live system-actions-runner.slice. The slice literal is parameterized pending the operator-blessed docker cgroup-parent change. Committed model stays ReadAbsent => OomdUnverified (pure .dag, fail-closed). Witness green by execution: the all-facts-hold read grounds Enforced, and each single missing/wrong fact (slice absent, inactive, disabled, auto, wrong/unbounded per-session cap, wrong parent cap, wrong PSI %, oomctl unmanaged, unmeasured aggregate) fails closed — a discriminating red against the old fail-open. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * WIP: Model systemd-oomd as a dependency (pure .dag, no live execution): extde * Address review: ground oomd durations on std.measure Second; enumerate UnitFileState arms Two findings from claude-opus-4-7 review of #5677: 1. unit-modeling hard-block (extdeps/os/oomd.dag): the duration fields default_memory_pressure_duration / managed_oom_memory_pressure_duration were typed Seconds (a bare branded Int in std/types.dag), a flat scalar for a time quantity. std.measure already has the Time dimension + One scale + the Nanosecond/Microsecond precedent, and Seconds was used ONLY in oomd.dag — so this lands on the carrier (M9 DFS-attach, not a 🟡 defer): add Second = Measure<Time, One, Nat> (one row beside Nanosecond/ Microsecond) and type both fields Second / Second?, values second(30) / second(20). No flat scalar propagates into the policy authority. 2. §5 fail-open (gunbc/oomd_install.dag): unit_is_enabled matched UnitEnabled => true; _ => false over the closed 10-variant UnitFileState, hiding every future arm behind one false. Now enumerates all ten arms explicitly (like the sibling unit_is_active). UnitEnabledRuntime => false is deliberate: runtime-only enablement does not survive a reboot, which the grounding requires. Witness still green by execution; measure carrier tests green. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * Address review nits: String? grounding sentinel; promote Percent to std.types Non-blocking findings from claude-opus-4-7's approving review of #5677: 2. first_grounding_failure overloaded "" as the no-failure sentinel (a second representation of absence). Now returns String? — Absent = all checks pass, Present{reason} = first failure — and ground_oomd_from_read matches on it. No empty-as-absent straddle. 3. Percent was declared in the extdeps.os.oomd leaf, but a percentage is a universal (not oomd-specific) concept; the next caller would re-mint or import-up awkwardly. Promoted to std.types beside the other branded-Int scalars (Duration/Milliseconds/Seconds) that are collectively pending the value-Measure migration; oomd.dag and oomd_install.dag now import it from std. No fork (no std.Percent existed before). Finding 1 (the coproduct->Bool enforcement predicates) is left as-is — the reviewer called it defensible: they encode a domain semantic (only Active/UnitEnabled constitute enforcement; Activating/Reloading deliberately fail closed), not mechanical variant-equality, and the per-check failure_reason carries the located cause. Witness green by execution. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * Add gunbc_oomd_fleet_evidence seam for the fleet capacity gate (CI-humming PR2) sharp-heron-321's CI-humming PR2 needs to bind fleet_host_budget's gunbc_fleet_oomd_evidence (today a literal OomdUnverified, consumed by ci_runner_placement REGIME-2) to this PR's grounded result rather than hardcoding = OomdEnforced. Expose a single binding seam: gunbc_oomd_fleet_evidence(req: OomdGroundingThresholds) -> OomdEnforcementEvidence It grounds over the committed gunbc_oomd_show_effective_read, so it stays OomdUnverified (fail-closed) until a real live ReadObserved on the managed sessions slice grounds the full conjunction — §5 verify-the-realization, no test-greening literal flip. It returns OomdEnforcementEvidence directly so std.realization_reconcile.Reconciliation never leaks into fleet_host_budget (which carries product.budget_tree.Reconciliation) — sidestepping the documented flat-namespace collision. The read shape is internal, so the seam is stable across future grounding-conjunct additions (e.g. a session-membership check coordinated with fierce-carp's cgroup-parent PR). Witness exercises it green (fail-closed on the committed ReadAbsent). Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * WIP: Model systemd-oomd as a dependency (pure .dag, no live execution): extde * Address RC: ground Percent as a Measure in std.measure (not a std.types brand) The prior std.types Percent (branded Int) forked the unit-modeling authority — exactly what the in-tree dissolve_on (container_stats.dag:115: 'Ratio or PercentagePoint typed alias lands in std/measure') was authored against. It satisfied the trigger in name without grounding it in the Measure carrier, so container_stats.cpu_percent could not reuse it and the oomd percent fields consumed a forked unit (DESIGN §3 single authority + unit-modeling hard-block). Fix: add a Dimensionless quantity to std.measure and land type Percent = Measure<Dimensionless, One, Nat> (+ percent / percent_count) beside the other Measure aliases (Second/ByteSize/Hertz). Quantity is a phantom type param (never matched), so the new variant is additive. Removed Percent from std.types. extdeps/os/oomd.dag and gunbc/oomd_install.dag import it from std.measure; percent literals are percent(N); the PSI% grounding check compares via percent_count (no record == straddle). This gives percent ONE home in the Measure framework — container_stats's cpu_percent can now dissolve onto the same Dimensionless quantity (a future Ratio sibling) instead of a parallel brand. Predicate-dissolution finding is non-blocking (workflow-local, domain semantic) — left as-is, addressed in prior replies. Witness green by execution; measure carrier tests green. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * WIP: Model systemd-oomd as a dependency (pure .dag, no live execution): extde --------- Co-authored-by: Brian Searls <briansearls1@gmail.com> Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Problem
In a large import closure the v1 interpreter dropped the
Filesystemservice's operations, soFilesystem.Writeraisedunknown service operation: Filesystem.Writeat runtime (other services — gcp/redfish/shell/Urandom — registered fine). Same class as the a1 type-name-collision poison.Root cause (reproduced)
InterpContext::with_runtime_optionsbuilt the runtimeservice_opstable by gating on a name-keyed lookup:graph.item_registry.get(&authored_name).kind == ServiceItem.item_registryis keyed by authored name and merged across the whole closure (overlay wins,rc_map_merge). Two top-level items share the nameFilesystem:std.resourcesresource Filesystem→item_kind=OtherItemextdeps.filesystem.filesystem_ioservice Filesystem→ServiceItemOnce both are reachable, the resource wins the merge and poisons the lookup, so the genuine service node's ops are never registered. The "~35 sources" framing is incidental — reproduced at an 18-module closure (
import filesystem_io+import std.resources { ResourceHandle }). Small fs witnesses (filesystem_io only, 7 modules) never pullstd.resources, which masked the bug.Fix
Detect service-ness node-locally:
if item_kind(item.clone()) == ItemKind::ServiceItem. The service node carries thetransportthat defines it as a service — it is the single authority. This removes the second, poisonable representation (fail-closed by construction, DESIGN §5).v1_interpreter.rsis a hand-maintained stage0 seed, so the direct edit is correct.Verification (by execution)
unknown service operation) → green post-fix (wet write/read round-trip).interp_recorded_fixturenarrow-gate suite: 23 passed, 0 failed.dsl/test/claim/filesystem_write_closure_scale_witness.dag+filesystem_write_closure_scale_record_then_hermetic_replay_holdsininterp_recorded_fixture_test.rs. Deliberately NOT enrolled inclaim_witness_corpus_ci_runner.dag(that module has no consumer — would be coverage-by-illusion).🤖 Generated with Claude Code