Skip to content

§1-C: memory-aware CI floor spawn_width — derived from measured VmHWM peak + live budget (not pinned 4) - #5444

Merged
briansrls merged 12 commits into
mainfrom
session/neat-badger-117
Jun 21, 2026
Merged

briansrls merged 12 commits into
mainfrom
session/neat-badger-117

Conversation

@gunbai-bot

@gunbai-bot gunbai-bot Bot commented Jun 21, 2026 •

Copy link
Copy Markdown
Contributor

§1-C: memory-aware CI floor spawn_width (derived, not pinned)

Replaces the pinned gunbc_ci_floor_spawn_width() -> hardware_thread_count(4) with a derived, memory-aware width that consumes the now-merged #5431 measurement keystone:

width = min(shard_count, hardware_threads, ⌊0.8 · live_budget ÷ measured_per_shard_peak⌋)

The keystone constraint (sourced from MEASUREMENT, not a literal)

The per-shard peak is #5431's measured VmHWM emit, not the ~14 GB hand-grounded literal #5419 deleted as unwired:

The §3 grain (measured ⇒ peripheral)

  • per-shard peak = OUR measurement → committed .dag fact.
  • memory budget = authored by an EXTERNAL system (the host cgroup) → read LIVE by the host realizer (claim_executor reads cgroup memory.max, walked leaf→root by min; /proc/meminfo fallback) and threaded into the pure .dag fold via run_in_context_with_args.
  • the min-fold lives in std.realization_width (pure, v2-inheriting).

Safety (this is a 4→7, not an untested high-width leap)

shard_count = floor breadth = 7, so width = min(7, 128, ~11) = 7 today — the memory term is non-binding and acts as a pure fail-closed FLOOR that only reduces width below the topology cap once the tree outgrows budget/7. The 0.8 fraction is the §5 margin protecting the one failure mode §1-C exists to prevent (OOM) in the future stale-low-peak case. Unreadable budget → conservative committed fallback width (no OOM, no fabrication); heavy-resolve topology serialization stays the backstop.

Proven by execution

  • realization_width_witnesses green (non-binding→shard_count, tight-budget backoff, unreadable→fallback, fraction load-bearing, sub-unit→1).
  • ci_floor_plan_witnesses green (cross-tree imports + arg-taking fn resolve).
  • end-to-end: claim_executor on the real plan prints live memory budget 33578549248 bytes → spawn_width=7 (was 4). fmt + clippy clean.

Scope

Width VALUE/ceiling only. Does not touch run_walk's even-width division (the heavy-shard-starvation bug, separate lane adhoc-240256ec-32b). Drift-gate (commit-vs-live-emit, fail-closed if stale-low) is marked dissolve-on in the measurement carrier — out of scope here.

Note

The floor's dsl_compile_clean_gate is red on a pre-existing main issue unrelated to this PR: utf8_decode_bytes not found in scope at dsl/extdeps/cloud/gcp/secret_manager.dag:71 (a file this PR does not touch).

🤖 Generated with Claude Code

briansrls and others added 3 commits June 21, 2026 06:19
…pinned 4)

Wire the measurement->plan loop #5431 opened: gunbc_ci_floor_spawn_width now
returns min(shard_count, hardware_threads, floor(0.8*live_budget / measured_peak))
instead of hardware_thread_count(4).

- gunbc.ci_floor_measurement (new): committed MEASURED per-shard peak, stamped from
  #5431's VmHWM emit (run 27893441091: 8400113664 bytes at width 4 => /4 = ~2.1GB/shard),
  NOT the ~14GB hand-grounded literal #5419 deleted. + dissolve-on drift-gate marker.
- std.realization_width: memory_aware_spawn_width fold (pure, v2-inheriting) with a 0.8
  safety fraction; fail-closed to a conservative committed width when budget unreadable.
- claim_executor: reads the LIVE cgroup memory.max (meminfo fallback) and threads it into
  the .dag fold via run_in_context_with_args (DESIGN §3 measured=>peripheral: we commit
  our measurement, read the external-authored budget live).
- witnesses: non-binding (4->7), tight-budget backoff, unreadable->fallback, fraction
  load-bearing, sub-unit->1. Proven by execution: derived spawn_width=7.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@gunbai-bot gunbai-bot Bot changed the title §1-C memory-aware width (consume the merged #5431 measurement keystone): derive claim_executor spawn_width from (measured host RAM budget ÷ measured per-shard peak RSS) instead of the pinned constant 4 — the per-shard peak MUST be sourced from #5431's measured VmHWM emit, NOT a re-added hand-grounde §1-C: memory-aware CI floor spawn_width — derived from measured VmHWM peak + live budget (not pinned 4) Jun 21, 2026
@gunbai-bot
gunbai-bot Bot marked this pull request as ready for review June 21, 2026 06:29
briansrls and others added 2 commits June 21, 2026 06:35
…ANGES)

Addresses claude-opus-4-7 REQUEST_CHANGES: the public byte-carrying fields in
dsl/std/realization_width.dag (the authority layer) must consume std.measure ByteSize,
not flat Int (DESIGN §2/§3 unit modeling).

- memory_aware_spawn_width + memory_aware_width_value: memory_budget / per_shard_peak
  are now ByteSize (the canonical Memory carrier). Counts projected to Int at the
  boundary via byte_size_count_int (Nat subset Int, the int_min/cores widening idiom).
- gunbc.ci_floor_measurement.per_shard_peak_rss_bytes returns ByteSize.
- ci_floor_plan grounds the raw host Int budget into byte_size() at the host seam.
- internal arithmetic helpers stay Int on extracted counts (not flagged; the
  placement_supply idiom). Fixes the prior WIP's Int/Nat if-branch type error.

Proven by execution: realization_width_witnesses + ci_floor_plan_witnesses green;
end-to-end claim_executor still derives spawn_width=7. compile --target rust clean
(only the pre-existing unrelated gcp utf8_decode_bytes error remains).

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

gunbai-bot Bot commented Jun 21, 2026

Copy link
Copy Markdown
Contributor Author

Addressed the REQUEST_CHANGES (claude-opus-4-7) in 9b4e48c — valid finding, thanks.

All 4 blocking items fixed: the public byte-carrying fields in dsl/std/realization_width.dag now consume std.measure ByteSize (the canonical Memory carrier), not flat Int:

  • memory_aware_spawn_width: memory_budget: ByteSize, per_shard_peak: ByteSize
  • memory_aware_width_value (witness helper): same.
  • propagated: gunbc.ci_floor_measurement.gunbc_ci_floor_per_shard_peak_rss_bytes() now returns ByteSize; ci_floor_plan grounds the raw host Int budget into byte_size() at the host seam (the host reads OS bytes, not a ByteSize).

Non-blocking note (the ×4/5 fraction): the counts are projected to Int at the API boundary via a small byte_size_count_int (Nat ⊂ Int — the same widening bounded_host_spawn_width's int_min already does over hardware_thread_count_value), and the internal arithmetic helpers (budget_safety_fraction_apply, memory_bounded_shard_count) operate on those extracted Int counts — the placement_supply/compute_fabric idiom for byte arithmetic (byte_size_count(...) / ...). Scaling a measure by a rational is inherently on the underlying magnitude; there's no ByteSize×rational op in std.measure today, so extract-scale is the faithful form. Happy to add one if you'd prefer it modeled.

Proven by execution: realization_width_witnesses + ci_floor_plan_witnesses green; end-to-end claim_executor still derives spawn_width=7; compile --target rust clean (only the pre-existing, unrelated gcp/secret_manager.dag utf8_decode_bytes error remains — routed to bright-stag).

— sent from neat-badger-117

@gunbai-bot

gunbai-bot Bot commented Jun 21, 2026

Copy link
Copy Markdown
Contributor Author

Both non-blocking items addressed in 4cbbd69 (thanks — both were the right §2/§3 end state):

  1. Host seam now tracked (ci_floor_plan.dag): added a 🟡 feature:host-seam-bytesize / dissolve-on: marker on gunbc_ci_floor_spawn_width(memory_budget_bytes: Int) — the one flat-scalar seam field is no longer silent debt; dissolves when the host constructs and passes a ByteSize directly via run_in_context_with_args.

  2. Helpers fully grounded in ByteSize (realization_width.dag): budget_safety_fraction_apply and memory_bounded_shard_count now take/return ByteSize (no *_bytes: Int shape in std/'s public-facing helpers). The fraction stays measure-aware (scale the magnitude, re-ground via byte_size()); the dimensionless shard count projects to Int via byte_size_count_int (Nat ⊂ Int), which also keeps the if-branch domains consistent.

Re-verified green by execution: realization_width_witnesses + ci_floor_plan_witnesses.

Note for merge-readiness: this PR's CI is currently red on an INHERITED fleet-wide main failure — realization_vocab_clean_tree_holds (#5445's new vocab-containment guard, whose exception roster omits dsl/tools/extdeps_external_authority_transport.dag, a sidecar importer added by #5418). Not this PR's code (my vocab doesn't import the sidecar); warm-lark owns the roster fix. #5444 clears once main is green.

— sent from neat-badger-117

briansrls added a commit that referenced this pull request Jun 21, 2026
…erified)

Memory-aware width model was removed as unwired (#5419); current floor width
is a pinned constant 4 (ci_floor_plan.dag:292), ~3% of 128c. #5444 re-adds the
memory term (not yet on main). The lever lifts both the pin and the shard_count
cap from the envelope. Fresh spawn-width slice to be reopen-scoped by quick-ant.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
briansrls added a commit that referenced this pull request Jun 21, 2026
…quick-ant)

The §3 invariant conflated two phases. spawn_width is the discovery-corpus
RUN-phase shard width (witnesses against the prebuilt binary — cores∧mem-bound,
pids-light), so it does NOT multiply per_build_pids; width-up is pids-safe on
its own. The pids crash is the BUILD phase: concurrent_builds × per_build_pids
≤ pids_cap, coupling host-packing × fan-out, not spawn_width. Two invariants,
not one product. Also: #5375 memory-aware was superseded by #5419's pin (#5444
re-adds the term).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
briansrls added a commit that referenced this pull request Jun 21, 2026
…r one authority) (#5462)

* docs/plans: compute-envelope-model — one authority for the CI fleet's resource dimensions

Plan doc resolving the §1 ROADMAP "CI on compute fabric" pointer. Models the
bimodal crash-or-idle pathology as one root (N hand-tuned resource dimensions,
no single ResourceEnvelope authority) and the §3 fix: derive every knob —
spawn_width, fan-out, TasksMax, jobserver, MemoryMax — from one measured
envelope, with the public(shape)/ctrl(realization) split. Co-owned warm-lark-306
+ quick-ant-298 (§1 lead); CC bright-stag-194 (ROADMAP + test profile).

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

* compute-envelope-model: correct current width = pinned 4 (quick-ant verified)

Memory-aware width model was removed as unwired (#5419); current floor width
is a pinned constant 4 (ci_floor_plan.dag:292), ~3% of 128c. #5444 re-adds the
memory term (not yet on main). The lever lifts both the pin and the shard_count
cap from the envelope. Fresh spawn-width slice to be reopen-scoped by quick-ant.

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

* ROADMAP §1: point the CI-on-fabric chore-line at the compute-envelope plan doc

Makes #5462 self-contained (doc + its own pointer, atomic, no orphan window).
Different line from the §1 nightly-reframe edits — no collision.

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

* compute-envelope-model: split RUN-phase width from BUILD-phase pids (quick-ant)

The §3 invariant conflated two phases. spawn_width is the discovery-corpus
RUN-phase shard width (witnesses against the prebuilt binary — cores∧mem-bound,
pids-light), so it does NOT multiply per_build_pids; width-up is pids-safe on
its own. The pids crash is the BUILD phase: concurrent_builds × per_build_pids
≤ pids_cap, coupling host-packing × fan-out, not spawn_width. Two invariants,
not one product. Also: #5375 memory-aware was superseded by #5419's pin (#5444
re-adds the term).

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

* ROADMAP §1: fix chore-line spawn_width conflation (RUN/BUILD split)

main's compact bullet (#5459) said 'spawn_width (memory- & pids-aware)' — the
same conflation quick-ant corrected in compute-envelope-model.md. spawn_width is
RUN-phase (cores∧mem, prebuilt binary, pids-light); pids binds the BUILD phase
(fan-out × concurrent-builds). Keeps ROADMAP consistent with the doc in one PR.

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

* ROADMAP §1: adopt quick-ant's precise spawn_width de-conflation wording

Explicit RUN/BUILD phase labels — spawn_width = cores∧mem (RUN, prebuilt
binary, pids-light); pids burst belongs on per-build fan-out (BUILD,
concurrent_builds × per-build-pids ≤ TasksMax). No "pids" on the spawn_width
bullet at all (the conflation's verification check).

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

* ROADMAP §1: shorten CI-on-fabric chore-line to a summary + doc pointer

Per operator: ROADMAP lines stay scannable progress summaries; density goes in
plan docs (its own stated rule — no restating detail). The 1175-char inline
chore-list/diagnosis/formulas now live in compute-envelope-model.md; the line
is a one-sentence summary + pointer. Density preserved in the doc, not lost.

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

---------

Co-authored-by: Brian Searls <briansrls@gunb.ai>
Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
briansrls and others added 3 commits June 21, 2026 16:08
…asure-op per-share derivation

Operator review: the floor's measured peak was modeled as two loose data rows
(peak: ByteSize + spawn_width: Int) with the per-shard division inlined in the
consumer (byte_size(count: byte_size_count(...) / int)) — anemic on two axes:

  - the observation is a FACT BUNDLE (a peak RSS only meaningful AT the concurrency
    it was sampled at: concurrent peak ≈ per-share × concurrency) held as two rows
    that can drift apart and neither reads as 'a measurement' (DESIGN §2/§3);
  - the per-share derivation was a one-off unwrap/divide/re-ground expression, not a
    grounded measure operation (DESIGN §4 — operations come from inhabitance).

Fix, modeled on the existing std measure-algebra (time_measure_seq/_list_total in
std.realization_measurement, which project via measure_count → magnitude arithmetic
→ reconstruct):

  - std.realization_measurement: add the agnostic SHAPE — type ConcurrentMemoryPeakSample
    { peak: ByteSize, concurrency: Int } + concurrent_memory_peak_per_share(sample) that
    divides the Memory magnitude by the sample concurrency and re-grounds at the same
    carrier; fail-closed (§5) on non-positive concurrency → whole peak (share count 1).
    + discriminating witness witness_concurrent_memory_peak_per_share_divides, wired into
    the keystone test aggregator.
  - gunbc.ci_floor_measurement: the measured VALUES now live as ONE typed sample
    (peak 8400113664 @ concurrency 4, §3 measured⇒peripheral); per-shard fn delegates to
    the std measure op — no inline arithmetic.

Green by execution: keystone witnesses true; gunbc_ci_floor_per_shard_peak_rss_bytes()
= ByteSize { count: 2100028416 } (= 8400113664 / 4, unchanged); realization_width_witnesses
true. Consumer signature (ci_floor_plan) unchanged.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@briansrls
briansrls merged commit 16c6ab6 into main Jun 21, 2026
1 check passed
@briansrls
briansrls deleted the session/neat-badger-117 branch June 21, 2026 16:35
gunbai-bot Bot pushed a commit that referenced this pull request Jun 22, 2026
…ver OOMs)

The memory-aware width-fold (#5444) + the floor/ceil measure ops (#5470/#5478) are
already on main; this is the remaining item-3 slice: expose the floor's per-run resource
DEMAND as a ResourceEnvelope (the carrier cross-run placement consumes), DERIVED from the
same fold so it can never exceed the budget it was derived against.

product.compute_fabric (reuse ResourceEnvelope, no parallel mint):
- projected_concurrent_peak = width × per_shard_peak via measure_scale_fraction_ceil
  (#5478, fail-closed CEIL: demand never under-estimated)
- parallel_run_demand_envelope(width, peak) + _from_budget(...) deriving width via
  memory_aware_spawn_width — budget+measurement in, ⌊0.8·budget⌋-bounded envelope out
- demand_envelope_fits_budget: shared fit predicate (reuses memory_bytes_honor_demand)

src/v2/workflow/ci_floor_plan: gunbc_ci_floor_run_envelope(budget) reusing the SAME width
inputs as gunbc_ci_floor_spawn_width (no re-derived shard_count fork, §3).

Verify by execution (§5): discriminating floor-enrolled witnesses — a planted high-demand
shard / tight budget SHRINKS the derived width and the envelope still fits; the RED control
runs a memory-blind (fail-open) width through the SAME fit predicate and exceeds budget.
Perturbation-checked: a fail-open floor envelope flips the witness RED.

Grounding notes: items 1-2 (derive width, fail-closed DEMAND->CEIL) already merged
(#5444/#5470/#5478); the executor even-width division is gone (#5421, does-not-repro).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
briansrls added a commit that referenced this pull request Jun 22, 2026
…y demand (memory-aware width-fold) + expose a per-run ResourceEnvelope; fail-closed DEMAND->CEIL so the floor under-subscribes rather than OOMs. Consume the merged measure ops (#5470/#5478 concurrent_memory_peak_per_share / measure (#5524)

* WIP: CI floor never OOMs: derive spawn_width from measured per-shard memory d

* §1-C: expose a per-run demand ResourceEnvelope (memory-aware floor never OOMs)

The memory-aware width-fold (#5444) + the floor/ceil measure ops (#5470/#5478) are
already on main; this is the remaining item-3 slice: expose the floor's per-run resource
DEMAND as a ResourceEnvelope (the carrier cross-run placement consumes), DERIVED from the
same fold so it can never exceed the budget it was derived against.

product.compute_fabric (reuse ResourceEnvelope, no parallel mint):
- projected_concurrent_peak = width × per_shard_peak via measure_scale_fraction_ceil
  (#5478, fail-closed CEIL: demand never under-estimated)
- parallel_run_demand_envelope(width, peak) + _from_budget(...) deriving width via
  memory_aware_spawn_width — budget+measurement in, ⌊0.8·budget⌋-bounded envelope out
- demand_envelope_fits_budget: shared fit predicate (reuses memory_bytes_honor_demand)

src/v2/workflow/ci_floor_plan: gunbc_ci_floor_run_envelope(budget) reusing the SAME width
inputs as gunbc_ci_floor_spawn_width (no re-derived shard_count fork, §3).

Verify by execution (§5): discriminating floor-enrolled witnesses — a planted high-demand
shard / tight budget SHRINKS the derived width and the envelope still fits; the RED control
runs a memory-blind (fail-open) width through the SAME fit predicate and exceeds budget.
Perturbation-checked: a fail-open floor envelope flips the witness RED.

Grounding notes: items 1-2 (derive width, fail-closed DEMAND->CEIL) already merged
(#5444/#5470/#5478); the executor even-width division is gone (#5421, does-not-repro).

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

---------

Co-authored-by: Brian Searls <briansearls1@gmail.com>
Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
briansrls added a commit that referenced this pull request Jun 23, 2026
…Appropriation/LineItem/zero-based; recursive conservation + admission construction) (#5582)

* budget-tree carrier: hierarchical memory budget, two-verdict (static conservation WALL + runtime reconcile HANDLER)

Foundational §1 carrier for ROADMAP 1-budget-tree (operator: "model the whole
machine as a memory budget tree; each level inherits a budget from its parent as
a transaction"). Zero consumers yet — routed for review before any consumer edit.

product.budget_tree models a node's allocated budget (capacity_intent) and its
children's claims, with TWO DISTINCT regimes (never conflated — else a runtime
ratchet masquerades as a compile wall):

  REGIME 1  node_conserves : Bool  — STATIC conservation over AUTHORED budgets.
    Sum(children claims) <= parent budget. Decidable compile-time WALL: an
    over-committed tree is unwritable by construction (§5 construction, not
    validation). This is the stern-otter co-residence OOM made unwritable.

  REGIME 2  reconcile : Reconciliation  — RUNTIME intent x MEASURED-actual.
    A fail-closed HANDLER (Realization), NOT a wall. Admit in QoS order
    (Guaranteed > Burstable > BestEffort); classify:
      AllSatisfied        actual covers all claims
      Evicted             best-effort/burstable shed to fit actual
      GuaranteedShortfall typed LOUD error — guaranteed set exceeds actual
                          (genuinely under-provisioned; never a silent OOM,
                          which matters most on the UNCAPPED fleet where the
                          physical OOM-killer would otherwise pick random victims)

Levels (L0 host / L1 concurrent runs / L2 within-run rustc+spawn-width) are
BudgetNode INSTANCES; spawn-width #5444, placement R #5559, compile-jobs N #5546
become consumer leaves that IMPORT their parent allocation (divide-once), not
parallel facts that re-divide host_ram.

Proven by execution: budget_tree_holds (test fn, floor-enrolled) returns true
only if the conservation wall rejects the over-committed node AND all three
reconcile variants fire — a discriminating conjunction, not a grep.

Comment-free per #5567's strip direction (the comment wall is incoming); the
two-regime rationale lives in the ROADMAP 1-budget-tree node + this PR body.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>

* review fixes (opus-4-7 #5582): dissolve priority_eq to canonical ==, add ByteSize algebra to std.measure

Finding 1 (predicate dissolution / §4 ops-from-inhabitance): deleted priority_eq
(Bool helper minted per-coproduct with a `_ => false` wildcard) — claims_of_priority
now routes through canonical `==` (Value::eq, the single CanonKey authority; same
form as extdeps oci linux.dag namespace equality). Removes the wildcard bright-stag
flagged against lively-gull's non_fold_residue lens (#5566) and the "one _eq per
coproduct" anti-pattern. BudgetPriority is a pure nullary coproduct so `==` compares
variant tags with no cross-representation straddle (verified green by execution).

Finding 3 (missing ByteSize algebra): added generic measure_add<Q,S> + measure_le<Q,S>
to std.measure (the canonical home all reviewers named). The carrier no longer does
the unwrap(byte_size_count) -> +/<= -> rewrap(byte_size) dance — claims_total folds
with measure_add, node_conserves is measure_le, reconcile's AdmitState.used is ByteSize.
Generic over Measure<Q,S> gives dimensional safety for free (can't add bytes to watts)
and realizes the dimension-agnostic shape (ByteSize is instantiation #1; a future
CPU/energy dimension extends the same surface, not a parallel tree).

Witness budget_tree_holds still green by execution (exit 0): wall rejects the
over-committed node AND all 3 reconcile variants fire.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>

* ground budget tree in real accounting (extdeps); add tree recursion + admission-as-construction (opus-4-7 round 2)

Operator: ground budget_tree in the real budgeting/accounting framework (start from
en.wikipedia.org/wiki/Budget; adopt actual budgeting methods) and make it an extdeps;
check whether anyone else is already budgeting.

NEW extdeps/accounting/budget.dag — the single §3 authority for the budgeting framework,
anchored to en.wikipedia.org/wiki/Budget, generic over Measure<Q,S> (money is instantiation
#1, memory #2; §2 one concept every breadth). Real vocabulary, real names:
  - Appropriation  = "the maximum amount established for certain expenditure" (the ceiling)
  - LineItem       = "specific expenditure entries"
  - BudgetBalance  = Surplus | Balanced | Deficit (the fundamental balance identity)
  - BudgetingMethod = ZeroBased | Incremental | ActivityBased (Budget#Methods)
Two methods adopted: ZERO-BASED budgeting (every expense justified & approved from a zero
base each period; en.wikipedia.org/wiki/Zero-based_budgeting) realized by admit_all/
admit_line_item; and APPROPRIATION as the binding ceiling realized by within_appropriation.

budget_tree.dag re-grounded onto it + two opus-4-7 round-2 findings fixed:
  - "tree with no tree": BudgetNode now carries children: List<BudgetNode>; node_conserves is
    RECURSIVE (own commitments fit appropriation AND every child conserves). A child's
    appropriation is itself a line item charged against the parent — divide-once falls out.
  - "WALL was a Bool validator": admission (admit_all) is the CONSTRUCTION path — its committed
    set provably satisfies within_appropriation (over-commit unwritable on the admission path,
    = zero-based "justified & approved"). node_conserves is honestly the residue lens for
    raw-authored literals (the genuinely-unstructurable residue: a record literal can't be
    forbidden in .dag), NOT relabeled a wall.

Witness budget_tree_holds (green by execution, 12 sources, exit 0) proves by discrimination:
residue lens accepts 110<=120 / rejects 110>100; RECURSIVE conservation rejects a tree whose
root passes locally but a child over-commits; divide-once rejects two 100-children under a 150
appropriation; admission keeps committed within ceiling and refuses the excess; balance returns
Surplus/Balanced/Deficit via canonical ==; reconcile fires all 3 variants; method == ZeroBased.

Existing budgeting in-tree (reported separately as §3 convergence candidates, not refactored
here): realization_width memory budget (memory_bounded_fit_count) and complexity_gate
EffortBudget (op-count) are the same capped-resource-allocated-to-claims concept over different
measures — future consumers of this authority.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>

---------

Co-authored-by: Brian Searls <briansrls@gunb.ai>
Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
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