Skip to content

merge-queue batch q-1785817081 - #778

Closed
matt82198 wants to merge 14 commits into
mainfrom
integrate/q-1785817081
Closed

matt82198 wants to merge 14 commits into
mainfrom
integrate/q-1785817081

Conversation

@matt82198

Copy link
Copy Markdown
Owner

Merge-queue batch built by tools/merge_queue.py.

Members: #693, #703, #754

Members are closed only after git merge-base --is-ancestor proves their content landed on main.

matt82198 and others added 14 commits August 2, 2026 20:48
…+ landed-content close guard (debottleneck B1)

B1.1: --integration becomes DEFAULT with auto-generated batch-<YYYYMMDD-HHMM> names;
      --serial escape hatch for legacy mode; add --dry-run trial merge in scratch worktree.
B1.2: Stacked PRs chain graph building (baseRefName reads); drop entire chain on conflict;
      independent chains ordered by dependency depth.
B1.3: TDD-FIRST: ancestor check (git merge-base --is-ancestor) blocks close of unlanded content;
      correctness bug fix prevents closing PRs whose content never merged to main.
B1.4: enforce_admins runtime assert at train start (gh api check); abort if not enabled.
B1.5: Integration mode never calls update_branch (FLAG 1 APPROVED: strict:false verified live);
      serial mode only updates BEHIND/UNKNOWN with --rebase-behind flag (default OFF).
B1.6: Regeneration hook stub (A1/A2/A3 generators plug in here); commits if files changed.

Test suite: 43 passing (1 new TDD-first test for B1.3 ancestor check).
Gates: secret_scan --staged exit 0.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Three verified P1s in the merged cost drawer (#676) and its browser proof.

a1 — CostSummaryDrawer showed stale spend forever after backend death.
`isError` was gated on `!cost`, but useSSE's EventSource error handler spreads
`prev` and retains the last cost payload. After ANY first payload both isLoading
and isError were unreachable, so a dead backend rendered the healthy loaded
branch with arbitrarily stale Total/Rate/Model-mix on every view, with zero
indication. `isError` is now `connectionStatus.status !== 'live'` ALONE —
connection status wins over cached data. A retained payload renders under an
explicit `cost-summary-stale` label inside the error state, never as current.

a2 — Model-mix percentages were dimensionally wrong. The share divided a model's
ALL-TIME tokens by (LATEST-DAY tokens x model count): a share of nothing,
unbounded above, then clamped by `width: min(pct * 2, 100)%` so a true 50% share
rendered full and a long history with a quiet latest day rendered every model at
100%. Shares are now each model's fraction of the all-time token total, both
sides from `summary.models` (the only per-model breakdown the contract carries).
Same window on both sides, so shares sum to 100%; the window is labelled in the
UI and the numeric share is rendered beside each bar. Rounding to 0.1% happens
once, so label and bar width cannot disagree.

a3 — verify_cost_summary_drawer.py asserted materially less than its docstring
claimed. Console-clean (a/h/l) and the "No data yet" message (k) were print-only:
a page throwing on every render printed [WARN] and exited 0. Every enumerated
claim is now an assert. Also: the console filter dropped any message containing
"warning"/"deprecated" as a substring (swallowing "Uncaught TypeError: warning
banner is undefined") and is now an explicit full-match allowlist; 4xx/5xx
responses and uncaught pageerrors are captured and asserted; the empty phase's
vacuous `has_pricing is False or len(models) == 0` is now two real assertions and
the phase sets AESOP_CONFIG_ROOT so it is hermetic; non-auto-waiting
`is_visible()` checks became `wait_for(state=...)`; `wait_for_server` fails fast
if the server process exits; stderr is always surfaced.

TDD: the 8 new vitest cases were written first and all 8 fail against the
pre-fix component (23/31 pass) and all pass after (31/31). Falsifiability of the
proof was demonstrated by breaking the console-clean and empty-message
assertions locally — both turn the run red (exit 1) — then restoring.

Gates: vitest 532/532 (42 files), tsc --noEmit clean, vite build + dist
committed, verify_cost_summary_drawer.py exit 0, stateapi_lint 0 new (40 =
baseline), claudemd contract/sync/domain-map green, secret_scan --staged CLEAN.

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

# Conflicts:
#	tools/CLAUDE.md
The origin/main merge added the merge_queue.py entry alongside this branch's
own entries, taking the file to 151 lines and failing the "CLAUDE.md linter
gate (scope invariant)" step in ci (0).

Folds alert_bridge.py and dep_graph.py onto one row -- the same pairing this
file already uses for launch_tui.py / orchestrator_status.py. No entry is lost.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…rd test, make epoch fencing real

Deep-scan findings B1/B2/B3 in the multibox coordination layer.

B1 (split-brain): LeaseStore derived claim keys with case_policy="platform",
which case-folds when os.name == 'nt' and preserves case otherwise. Two
instances sharing one coordination db therefore derived DIFFERENT keys for the
same file ('tools/Runner.py' -> 'tools/runner.py' on Windows, 'tools/Runner.py'
on Linux), so _check_conflicts (exact match) missed and BOTH were granted the
claim. Case policy is now configuration, not a property of the host OS, resolved
explicit-arg > multibox.case_policy > $AESOP_CLAIM_CASE_POLICY > "insensitive".
An unrecognized policy raises ValueError (fail-closed).

B2 (vacuous guard): the heterogeneity guard called canonical_claim_path directly
with case_policy="insensitive" -- a value production never passed -- and never
touched _normalize_path, so it stayed green while B1 was live and survived
mutating _normalize_path to the identity function. Rewritten to exercise the real
production entry point, plus an end-to-end LeaseStore split-brain reproducer.

B3 (inert epoch): nothing in the repo ever incremented the persisted epoch, so
get_identity_with_epoch returned 1 forever and could not distinguish a pre- from
a post-crash instance, while the module documented it as a monotonic boot
counter. Acquisition now increments and durably persists the epoch (temp file +
fsync + os.replace), fail-closed on persist failure (EpochPersistError, a
subclass of IdentityCorruptionError) and on a non-integer epoch. Existing
corrupt-file fail-closed hardening and fresh-box epoch=1 are preserved.
release_own_stale() now raises NotImplementedError instead of returning an
unconditional True while doing nothing.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…gration-default

# Conflicts:
#	tests/CLAUDE.md
#	tools/CLAUDE.md
#	tools/merge_train.py
@matt82198 matt82198 added the merge-queue-batch Integration batch PR opened by the merge-queue advancer label Aug 4, 2026
@matt82198

Copy link
Copy Markdown
Owner Author

Dissolving merge-queue batch: required check(s) absent from rollup: windows

@matt82198 matt82198 closed this Aug 4, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

merge-queue-batch Integration batch PR opened by the merge-queue advancer

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant