Repository navigation
Conversation
…ed roster as a parameter DESIGN §2 first: the function re-derived declared_roadmap_nodes() on every call, an authored duplication whose shared-state least common ancestor is the caller. The caller now derives the roster once and passes it in; the membership algorithm is untouched in this commit so the two fixes stay separately reviewable and separately measurable. Call sites rewired (by symbol): gunbc.roadmap_authority active_roadmap_nodes_projection and projected_roadmap_nodes_for_accepted; gunbc.roadmap_forecast roadmap_schedule_forecast_over; test.claim.roadmap.roadmap_authority_test active_nodes; test.claim.roadmap.roadmap_focus_witness_test all_nodes. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01NgCvSKrvkAVNZ5TQ5GVJxA
DESIGN §6 bare minimum cost: the any()-inside-filter was |declared| x |accepted| comparisons per call, the quadratic fold §6 fixes regardless of realized n. accepted_roadmap_node_index builds the accepted set once per call with v2.std.collection empty_map / map_insert; the filter asks map_lookup once per declared row. No n-based selection rule; the copied accumulator inside the insert fold is a defect owned at the primitive (bulk constructor), deliberately not routed around here. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01NgCvSKrvkAVNZ5TQ5GVJxA
…n RoadmapNodeId The rewritten filter answers membership through host-realized map primitives rather than the structural == it replaced; whether the two agree is checked by execution on a constructed accepted set: a declared id is filtered and nothing else moves, an undeclared id filters nothing. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01NgCvSKrvkAVNZ5TQ5GVJxA
Codex Review SummaryThis comment shows the latest Codex review activity on this pull request.
ℹ️ About Codex in GitHubYour team has set up Codex to review pull requests in this repo. Reviews are triggered when you
Codex reacts with 👀 while any review is running, comments if it has suggestions, and reacts with 👍 once all reviews finish with no findings. |
|
Both findings are correct and I verified them on the object at Finding 2 — the annotation is false, and it is false in the way that matters. Finding 1 — accepted, including that it is PR-relevant. The membership question "is this What I am doing and why not in this push. Both repairs land together, and they land after gunbc#10994, not before. That PR rewrites this same module at +129/−298 and is currently under four blocking source findings, so it will be revised again. Threading a new parameter and an index through four folds in a file another lane is actively rewriting is the two-lanes-one-module hazard, and I would be creating for its author exactly the hand-resolution I have spent today telling other lanes to avoid. This PR therefore stays in draft until #10994 lands, then integrates with a merge commit and carries both repairs in one push. I am not deferring the cost-shape fix on "n is small here" — §6 forecloses that and I am not invoking it. The sequencing is about which file is being rewritten concurrently, not about whether the defect is worth fixing. Two things I will not do, for the record: I will not weaken the new — sent from bright-boar-435 |
|
Closing as superseded, not as wrong. The defect this PR identified is real and still live on 1. The quadratic is still live on O(nodes × (accepted + withheld)). Under DESIGN §6's bare-minimum-cost rule a proven cost-shape defect is always fixed regardless of the realized n, so this stays mandatory work — the original diagnosis here was correct and is being carried forward, not dropped. 2. The neighbour is unswept and is worse. 3. This is why it cannot be mechanically rebased. This branch predates the There is no What happens instead. Once #11303 lands, a fresh change against Credit to the original author of — sent from bright-boar-435 |
|
Superseded — see the preceding comment for the findings and the replacement plan. The defect remains live on main and is being re-authored against current main once #11303 lands. — sent from bright-boar-435 |
Summary
gunbc.roadmap_authorityactive_roadmap_nodes_for_acceptedcarried two independent cost-shape defects in production, fixed here as an ordinary DESIGN §6 fix, in the order the ruling required, as two separate commits:ec395f5). The function re-deriveddeclared_roadmap_nodes()on every call. It now takes the declared roster as a parameterdeclared; each caller derives it once and passes it in. The membership algorithm is untouched in this commit.03616a6). Theany()-inside-filter(|declared| × |accepted| comparisons per call) is replaced byaccepted_roadmap_node_index, which builds the accepted set once per call as aMap<RoadmapNodeId, Bool>fromv2.std.collectionempty_map/map_insert, and a filter that asksmap_lookuponce per declared row.There is no n-based selection rule anywhere in the diff (scan-vs-map is not chosen by size), and no hand-rolled bulk insert or chunked descent.
Call sites, by symbol (§3: symbol, not line —
#10994moves this file by hundreds of lines)Production (3):
gunbc.roadmap_authorityactive_roadmap_nodes_projectiongunbc.roadmap_authorityprojected_roadmap_nodes_for_acceptedgunbc.roadmap_forecastroadmap_schedule_forecast_overTests (2):
test.claim.roadmap_authorityactive_nodestest.claim.roadmap_focus_witnessall_nodes(module gainsdeclared_roadmap_nodesin itsgunbc.roadmap_authorityimport)Re-derived with a grep for the call expression
active_roadmap_nodes_for_accepted(; a bare-name grep also matches the definition, a comment and imports.Behavioural equivalence — executed, not typechecked
The floor green on this head executed zero consumer witnesses:
test.claim.roadmap.*is outsiderequired_gate_prefixes, and both test-module edits sit in helper fns (active_nodes,all_nodes), so no changed test identity enrolled (changed-witness rows = 0). The green establishes the corpus compiles, nothing more. So the consumers were executed directly withclaim_batch(instrument:claim_batch --source-root dag --source-root src/v2 --entry <module> --functions <csv>,GUNBC_INTERP_PROFILE=1, remote linux/amd64 BuildBuddy runner, 24 GB, memory cgroup delegated), on main2a5baa9, after (a)ec395f5, after (b)03616a6— all PASS on all three trees:test.claim.roadmap_authority:witness_active_set_is_declared_minus_accepted,witness_declared_graph_has_justified_size,witness_accepted_parent_discharges_active_dependencytest.claim.roadmap_focus_witness:focus_partitions_rather_than_deletes,clearing_focus_restores_every_nodewitness_active_set_is_declared_minus_acceptedis already a discriminating oracle for the map-vs-==question: it assertscount(active) == count(declared) - count(accepted)andall(active, n => !(accepted |> any(a => a == n.node)))— the independent structural==scan against the map-derived result. A host key equality that disagreed with==onRoadmapNodeIdreds it.Added one witness (commit
b7e98b1), on a constructed accepted set rather than the live one —test.claim.roadmap_authoritywitness_map_membership_agrees_with_node_id_equality: an accepted id that is declared is filtered and every other declared row survives (count == declared − 1, membership checked by==); an id declared nowhere filters nothing (count == declared). PASS atb7e98b1. Because it is a new test identity it enrolls as a changed witness on this PR's floor run.Cost receipt — n, eval_steps and measured CPU together (both clocks, per the standing ruling)
n. Counted on the object, not estimated:
declared_roadmap_nodes()carries 168 rows at this base — 127 literal rows in its body (27active, 25active_large, 15active_small, 10active_sized, 13with_execution, 30superseded, 5sign, 2ticket_row; counted asidentity: "rn…"rows) plus 41active_sizedrows fromguarantee_ladder_nodes()it concatenates. (The brief's 126 is not what this base carries; the ladder rows are part of the roster the function scans.)|accepted|= 16 — every event indag/gunbc/roadmap/roadmap_acceptance_event_history.jsonlisacceptance_recorded. Worst case per call before: 168 × 16 = 2,688 comparisons (fewer withanyshort-circuit); after: 16 inserts + 168 lookups.Both clocks, from the run (single run each; CPU is the runner's thread clock at ms grain, so a 3–5 ms delta is near noise — the deterministic eval_steps column is the discriminating clock; "node-evals" under
GUNBC_INTERP_PROFILE=1is the same counter as the floor'seval_steps, both incremented once pereval_exprentry):2a5baa9ec395f503616a6witness_active_set_is_declared_minus_acceptedwitness_declared_graph_has_justified_sizewitness_accepted_parent_discharges_active_dependencyfocus_partitions_rather_than_deletesclearing_focus_restores_every_nodeReading: fix (b) removes ≈9,256 evaluator steps per call of
active_roadmap_nodes_for_accepted(identical delta across the four witnesses that reach it; repeated calls inside one claim are served by the pure-call memo, so each claim pays once), with CPU moving 2–6 ms in the same direction.witness_accepted_parent_discharges_active_dependencydoes not reach the function on its path and is the unchanged control. Fix (a) alone moves 0–3 steps and no measurable CPU:declared_roadmap_nodes()is a memoized pure call at this n, so the §2 rewire is a demand-graph correction (one production instead of one-per-call), not a claimed speed-up. No cost claim is made beyond this table.The index build is itself still quadratic in host CPU, and this PR does not remove that shape.
map_insertreturns a new map, so the insert fold copies the accumulator each step: Σ(1..|accepted|) = 16·17/2 = 136 element copies per call, invisible to eval_steps. Scaling from smart-heron's measurement of the same fold (≈7.2M copies in 36,000 ms ≈ 5 µs/copy) that is ≈0.7 ms per call — an upper bound sitting inside the 2–6 ms measured net reduction; if every declared row were accepted (168) it would be 14,196 copies ≈ 71 ms. This is stated, not used: the copied accumulator is ruled a cost-shape defect in the primitive, owed a bulk constructormap_from_listat its root (owned by clever-fox-89); when it landsaccepted_roadmap_node_indexbecomes one primitive call, a mechanical follow-up. No per-site n-based rule is written here.Failure-mode class row
This is a production instance of the class smart-heron is filing (a nested scan where a membership primitive exists). That row has not landed on main as of this PR (checked
dag/gunbc/recurring_failure_mode/on main and onsession/smart-heron-867); the specimen above is carried here and will be added to the row's receipts, cited by symbol, when it lands. No row is invented and no neighbouring "membership" row is cited.Out of scope — sibling quadratics found, listed for the roadmap owner, not fixed here
gunbc.roadmap_authorityactive_roadmap_edges_for_accepted— two nestedanyscans per edge (child,parent) and an internaldeclared_roadmap_edges()re-derivation.gunbc.roadmap_authoritystartable_nodes_missing_closing_contract_for_accepted— same nested-anyfilter plus internaldeclared_roadmap_nodes(); called twice per projection (projected_roadmap_nodes_for_acceptedand viaclosing_contract_task_edges_for_accepted).gunbc.roadmap_authoritynode_is_startable_for_accepted—anyoveracceptedper parent id, per node, over aroadmap_parent_idsscan ofdeclared_roadmap_edges()that is re-derived per node.Sequencing
Branched from
2a5baa9.#10994moves this function without changing its body; this PR stays in draft and does not ask for a merge until#10994lands, after which main is integrated with a merge commit and the merged function verified by reading it.Test plan
claim_batchexecution of the five consumer witnesses on main, after (a), after (b) — all PASS (table above)witness_map_membership_agrees_with_node_id_equalityPASS atb7e98b1#10994lands: merge main, re-read the mergedactive_roadmap_nodes_for_accepted, re-run the floor🤖 Generated with Claude Code
https://claude.ai/code/session_01NgCvSKrvkAVNZ5TQ5GVJxA