Login
Check-in [c63c8afd39]
Login

Many hyperlinks are disabled.
Use anonymous login to enable hyperlinks.

Overview
Comment:Merge: backfill the mobile-skin opt-in row on the boot sweep (ticket 9bb34ea1e4 redo)

The original fix gated RepoBootstrap#ensure_skin on a new ollama-codex-mobile-skin config row, set only by RepoBootstrap.onboard. Review found the real regression: none of the 24 currently-served repos (including ollama itself) carry that row, since onboard is the only writer of it and the boot sweep never backfilled it -- merging as submitted would have silently stopped the mobile-skin invariant from being enforced/repaired anywhere except future onboard calls.

Adds RepoBootstrap.backfill_mobile_skin_opt_in, called from ensure() (so every ensure_all/ensure_served boot sweep runs it) exactly once per repo, only when the opt-in row is entirely unset: - a repo named stone (basename match) backfills to row=0 and has any forced css/header/footer/details rows deleted in the same SQL transaction, so Fossil's default skin returns there; - any other repo whose current css already equals SKIN_CSS (the pre-fix sweep already skinned it) backfills to row=1, so ensure_skin keeps enforcing the invariant on it going forward; - anything else is left with no row -- opts in only via a real onboard.

Verified independently: all three backfill criteria confirmed directly in source and covered by the branch's own new specs. Checked the live, just-recovered stone.fossil directly before this merge: it carried the forced css (11750 bytes)/header/footer/details rows with no opt-in row at all -- exactly the state this backfill targets. Also checked the branch's own redundancy claim (that onboard's enable_mobile_skin call becomes redundant) and found it does NOT hold in general: a brand-new peer has no css row yet, so the non-stone backfill branch never fires for it -- onboard's explicit call is still load-bearing for every genuinely-new peer.

Suite via gate_run: ci.cr passed outright, 1981 examples, 0 failures, 0 errors, 36 pending, 645.0s.

Maintainer approved via delegation on this thread; merge word posted by fable: "merge 3803c725e3cd".

Co-Authored-By: Claude Sonnet 5, noreply@anthropic.com

Downloads: Tarball | ZIP archive
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA3-256: c63c8afd39f56acdc77782f4c71354383f64d0db286bc33d5c142ec40eb85ad4
User & Date: agent-trunk-ops 2026-09-20 23:50:16.027
Context
2026-09-21
01:40
Merge: gate-branch/gate-run gate the branch merged with trunk, not the bare tip (ticket 752e76f61b)

A branch created before ci.cr landed on trunk (or before any trunk-side CI-relevant change) was gated from a clone of the bare branch tip, found no ci.cr, and held forever with "no CI flow declared" even after trunk had one -- seen three times today (badge-launcher, interactor, gp-crystal). Every ordinary CI system tests the merge result, not the branch tip.

New TaskWorker#merge_trunk_for_gate runs `fossil merge trunk` in the gate's clone (uncommitted) before looking for ci.cr, for both gate-branch's fresh clone and gate-run's caller-owned clone. A real merge conflict is now its own RED gate (mark_merge_gate_red, step "merge trunk", the CONFLICT-line list from `fossil status` as the reason) -- never silently skipped, never mistaken for "no ci.cr". "No ci.cr" now only fires once trunk ITSELF (post-merge) has none, routed as a plain OCX-HOLD (new TaskQueue.mark_held_plain -- same marker, no design_input=confirm) so it lands in the coordinator queue rather than a false Needs-you decision card. mark_merge_gate gains trunk_hash, recorded in the stamp's new "trunk" field and the GREEN forum notice, so trunk-ops can confirm it merges the exact pair the gate verified.

Also fixes ServedPeerDeploy.trunk_tip, which queried a nonexistent blob.mtime column -- silently swallowed by its own rescue nil, always returning nil, never actually exercised against a real repository. Rewritten to the same leaf/tagxref(tagtype=2) pattern TaskQueue.commit_landed_on_trunk? already uses and has proven correct.

Verified independently: reviewed as tooling I depend on constantly. Confirmed all three required behaviors against their fixtures, not just the spec names -- a branch forked before trunk's ci.cr gates GREEN via the merge-then-look order; a genuine merge conflict (both branch and trunk edit the same file) yields a red gate naming the conflicting file, design_input never stamped confirm; the stamp records the merged trunk check-in. Cross-checked the trunk_tip rewrite against TaskQueue.commit_landed_on_trunk?'s already-proven query rather than taking the diff's own comment at face value.

Suite via gate_run: ci.cr passed outright, 1985 examples, 0 failures, 0 errors, 36 pending, 587.0s.

Maintainer approved via delegation on this thread; merge word posted by fable: "merge 09c6ddddba7b".

Co-Authored-By: Claude Sonnet 5, noreply@anthropic.com check-in: 454ed92973 user: agent-trunk-ops tags: trunk

01:29
Fix needs_you sync writing 'none' onto never-touched tickets (ticket 46bfce9fce)

Cause: NeedsYou.sync! compared the evaluated value against the stored needs_you field, but an empty (never-stamped) field and a stored "none" compared unequal, so the first sync after the needs_you column existed wrote "none" onto every eligible ticket in every served repo -- 2897 field-only artifacts across 12 repos in one pass (fossil-scm.org 1126, ollama 1253, stone 161, and others), including closed tickets and an imported reference archive with no daemon role. Those 2897 artifacts are already synced to every clone (including Stone) and cannot be retracted.

Fix, src/needs_you.cr: 1. Empty and "none" are now the same state for writing purposes: sync! never writes "none" onto a ticket whose field is empty, only to clear a previously non-none value. 2. sync! now requires RepoBootstrap.daemon_managed?(repository) -- the same onboarding flag ticket 9bb34ea1e4 introduced to keep the mobile-skin sweep off stone.fossil and other repos this daemon doesn't own -- so an imported archive or foreign client's repo is never swept at all. The ticket query also drops Closed/Deferred outright (defense in depth; evaluate already returns "none" for both). Fixed/Tested stay in the query -- they are the try-this domain's own active statuses and must keep being evaluated. 3. A write-budget invariant guard (Accountability: every daemon write is deliberate and bounded): a pass that would write more than 25 ticket artifacts on one repo writes none of them and logs a refusal naming the count and the repo; set needs-you-migrate=1 in that repo's config to run it once, and the pass that consumes the override deletes the row again.

spec/needs_you_spec.cr: a 100-unstamped-ticket fixture now gets zero writes (was 100 before this fix); a 3-real-card fixture gets exactly 3; a previously-stamped 'merge' that no longer applies still gets exactly one 'none' to clear it; a non-daemon-managed fixture with a real gate gets zero; the write-budget spec confirms 26 pending writes are refused, then land (and the override is consumed) once needs-you-migrate=1 is set. Reworked the existing "clears human_verify... once a merge-authority login replies" spec, which relied on the old bug's write-onto-empty behavior; added a case proving a reply landing before any sync ever ran leaves needs_you empty rather than stamping an unearned "none".

crystal spec spec/needs_you_spec.cr spec/repo_bootstrap_spec.cr: 84 examples, 0 failures. Full suite not run (targeted specs only, per instructions).

Co-Authored-By: Claude Sonnet 5, noreply@anthropic.com Leaf check-in: 307136f7df user: agent-claude tags: agent/20260921T011402Z-needs-you-sync-wrote-none-onto-2897-tick

2026-09-20
23:50
Merge: backfill the mobile-skin opt-in row on the boot sweep (ticket 9bb34ea1e4 redo)

The original fix gated RepoBootstrap#ensure_skin on a new ollama-codex-mobile-skin config row, set only by RepoBootstrap.onboard. Review found the real regression: none of the 24 currently-served repos (including ollama itself) carry that row, since onboard is the only writer of it and the boot sweep never backfilled it -- merging as submitted would have silently stopped the mobile-skin invariant from being enforced/repaired anywhere except future onboard calls.

Adds RepoBootstrap.backfill_mobile_skin_opt_in, called from ensure() (so every ensure_all/ensure_served boot sweep runs it) exactly once per repo, only when the opt-in row is entirely unset: - a repo named stone (basename match) backfills to row=0 and has any forced css/header/footer/details rows deleted in the same SQL transaction, so Fossil's default skin returns there; - any other repo whose current css already equals SKIN_CSS (the pre-fix sweep already skinned it) backfills to row=1, so ensure_skin keeps enforcing the invariant on it going forward; - anything else is left with no row -- opts in only via a real onboard.

Verified independently: all three backfill criteria confirmed directly in source and covered by the branch's own new specs. Checked the live, just-recovered stone.fossil directly before this merge: it carried the forced css (11750 bytes)/header/footer/details rows with no opt-in row at all -- exactly the state this backfill targets. Also checked the branch's own redundancy claim (that onboard's enable_mobile_skin call becomes redundant) and found it does NOT hold in general: a brand-new peer has no css row yet, so the non-stone backfill branch never fires for it -- onboard's explicit call is still load-bearing for every genuinely-new peer.

Suite via gate_run: ci.cr passed outright, 1981 examples, 0 failures, 0 errors, 36 pending, 645.0s.

Maintainer approved via delegation on this thread; merge word posted by fable: "merge 3803c725e3cd".

Co-Authored-By: Claude Sonnet 5, noreply@anthropic.com check-in: c63c8afd39 user: agent-trunk-ops tags: trunk

22:57
Merge: fix O(tickets x ticketchng) queries behind the 12s Agent Console / 5s sessions render (ticket c6cf7d0651)

Permanent Time.monotonic phase timers (fossil_forum.cr, activity_report.cr, needs_you.cr, ui.cr) disproved the initial hypothesis (forum-thread decoding, ~56ms total) and found the real cause: five read paths (ActivityReport#schema_field_gates/#owned_confirm_ticket/#query_plan_tickets, NeedsYou#fetch_rows, TaskQueue#task_select) each ran a per-ticket correlated subquery/EXISTS against ticketchng (Fossil's stock schema, no index on tkt_id) -- O(tickets x ticketchng) instead of O(tickets + ticketchng). Rewrote each into a single-pass CTE that scans ticketchng once. Adds spec/render_budget_spec.cr, a fixture of comparable row-count shape pinning /chat under 1s and /chat?sessions=1 under 0.5s.

Measured against the real served ollama.fossil (1096 tickets, 6023 ticketchng rows, 2971 forum posts): /chat: 11.05s -> 0.86-0.89s /chat?sessions=1: 4.94s -> 0.40-0.41s

Verified independently: checked each rewrite's semantic equivalence directly against source, not just the diff -- the window-function CTEs' ORDER/LIMIT match the old scalar subqueries exactly; the group_concat CTEs preserve the old empty-case COALESCE semantics. Checked one subtle point by hand: task_select's rewrite changes a per-row json_group_array subquery (returns the literal string '[]' for a ticket with zero matching comments, confirmed live) to a LEFT JOIN returning SQL NULL for the same case -- a real raw-SQL difference, but parse_comments' early-return guard already collapses both to the identical `[] of String`, so no observable behavior change. One minor, non-blocking note: owned_confirm_ticket_query's WHERE clause changed from a per-row EXISTS to a concatenated-string LIKE, theoretically susceptible to a concatenation-boundary false positive (never a missed match) -- the author already diff-verified full result sets against the real 1096-ticket repo with no discrepancies.

Suite via gate_run: ci.cr passed outright, 1976 examples, 0 failures, 0 errors, 36 pending, 723.0s.

Maintainer approved via delegation on this thread; merge word posted by fable: "merge e6e27a7aebe8".

Co-Authored-By: Claude Sonnet 5, noreply@anthropic.com check-in: b8da3f3fa4 user: agent-trunk-ops tags: trunk

22:32
Redo of ticket 9bb34ea1e4: backfill the mobile-skin opt-in row on the boot sweep

Merges agent/20260920T205343Z-stone-app-shows-a-forced-bad-skin-the-da (the original fix, which gated ensure_skin on a new MOBILE_SKIN_OPT_IN_KEY config row set only by RepoBootstrap.onboard). trunk-ops's review found the real regression: none of the 24 currently-served repos (including `ollama` itself) carry that row, since onboard is the only writer of it and the boot sweep never backfilled it -- merging as-is would have silently stopped the mobile-skin invariant from being enforced/repaired anywhere except future onboard calls.

Adds RepoBootstrap.backfill_mobile_skin_opt_in, called from `ensure` (so every ensure_all/ensure_served sweep runs it) exactly once per repo -- only when the opt-in row is entirely unset, so a later manual choice always sticks: * a repo named `stone` (matched by basename) backfills to row=0 and has any forced css/header/footer/details rows deleted in the same SQL transaction, so Fossil's default skin returns there even though the pre-fix sweep already wrote the ollama-codex skin into it. * any other repo whose current `css` already equals SKIN_CSS (i.e. the pre-fix sweep already skinned it) backfills to row=1, so ensure_skin keeps enforcing the invariant on it going forward. * anything else (never touched by the pre-fix sweep) is left with no row -- not a backfill target, opts in only via a real `onboard`.

ensure()'s top-level rescue already skips a repo it can't open, so this naturally leaves the corrupt live stone.fossil untouched until its own recovery ticket lands -- no special-casing needed for that.

This makes RepoBootstrap.onboard's own `enable_mobile_skin(target)` call (for a brand-new peer) redundant with the backfill for any peer that also happens to already carry SKIN_CSS at onboard time, but onboard's call stays since a genuinely new repo has no css row yet for the backfill to match on.

Specs (spec/repo_bootstrap_spec.cr, new ".ensure (mobile skin opt-in backfill)" describe block): a scratch repo pre-skinned with no row backfills to 1 and keeps getting re-skinned on drift; a scratch repo named `stone` pre-skinned with no row backfills to 0 and loses the forced rows; a repo whose row is already 0 is never re-decided. Full suite: 1981 examples, 0 failures, 0 errors, 36 pending (7:39).

Co-Authored-By: Claude Sonnet 5, noreply@anthropic.com Leaf check-in: 3803c725e3 user: agent-claude tags: agent/20260920T221745Z-stone-app-shows-a-forced-bad-skin-the-da

Changes
Unified Diff Side-by-Side Diff Patch
Changes to spec/repo_bootstrap_spec.cr.
Changes to spec/skin_render_spec.cr.
Changes to src/repo_bootstrap.cr.