Commit graph

59 commits

Author SHA1 Message Date
5dd04dcb3d retire identifier registrar guard
All checks were successful
CI Smoke / host-smoke (push) Successful in 0s
CI Smoke / container-smoke (push) Successful in 1s
Build and Publish Multi-Context Image / build-and-push (push) Successful in 26s
Assistant: codex
Assistant-Model: gpt-5.6-sol
Assistant-Session: 01a053ff-1d6f-7fe2-ac1c-a6eb40a42a0c
2026-08-31 19:34:11 +02:00
34f5cb3fc3 feat: add fast forge work-record reconciliation
All checks were successful
CI Smoke / host-smoke (push) Successful in 0s
CI Smoke / container-smoke (push) Successful in 1s
Build and Publish Multi-Context Image / build-and-push (push) Successful in 24s
Assistant: codex
Assistant-Model: gpt-5.6-sol
Assistant-Session: 01a053ff-1d6f-7fe2-ac1c-a6eb40a42a0c
2026-08-30 22:38:54 +02:00
037c8360e2 Refresh WORK-RECORDS.md after every live record is archived.
All checks were successful
CI Smoke / host-smoke (push) Successful in 0s
CI Smoke / container-smoke (push) Successful in 1s
Build and Publish Multi-Context Image / build-and-push (push) Successful in 35s
C-33 returned early when the generator produced no rows, so a leftover
index kept listing archived workplans as active. Rewrite that file to an
empty table instead of leaving the stale rows in place.

Assistant: grok
Assistant-Session: 01a04d7c-846d-77e3-af8d-020019e4eb61
2026-08-29 14:39:42 +02:00
2e2ae1e5d0 feat: make repository reads alias-aware
All checks were successful
CI Smoke / host-smoke (push) Successful in 0s
CI Smoke / container-smoke (push) Successful in 1s
Build and Publish Multi-Context Image / build-and-push (push) Successful in 25s
Assistant: codex
Assistant-Model: gpt-5.6-sol
Assistant-Session: 01a049a4-ee9f-78e1-9d66-2cb0f9bea3e3
2026-08-29 10:47:51 +02:00
fae2816199 fix(consistency): preserve repository domain in briefs
All checks were successful
CI Smoke / host-smoke (push) Successful in 0s
CI Smoke / container-smoke (push) Successful in 1s
Assistant: codex
Assistant-Model: gpt-5.6-sol
Assistant-Session: 01a02b22-9638-76d2-bbff-b7ea1770b118
2026-08-23 13:57:22 +02:00
70a708ff11 fix(consistency): preserve checker call compatibility
All checks were successful
CI Smoke / host-smoke (push) Successful in 0s
CI Smoke / container-smoke (push) Successful in 1s
Assistant: codex
Assistant-Model: gpt-5.6-sol
Assistant-Session: 01a023c0-a0a3-7c03-b395-5a0d2757214d
2026-08-22 12:41:46 +02:00
059de9358e feat(consistency): rebuild authoritative intake IDs
All checks were successful
CI Smoke / host-smoke (push) Successful in 0s
CI Smoke / container-smoke (push) Successful in 1s
Build and Publish Multi-Context Image / build-and-push (push) Successful in 23s
Assistant: codex
Assistant-Model: gpt-5.6-sol
Assistant-Session: 01a023c0-a0a3-7c03-b395-5a0d2757214d
2026-08-22 12:23:43 +02:00
03c7924b7f feat(consistency): bootstrap empty repo projections
All checks were successful
CI Smoke / host-smoke (push) Successful in 0s
CI Smoke / container-smoke (push) Successful in 1s
Assistant: codex
Assistant-Model: gpt-5.6-sol
Assistant-Session: 01a023c0-a0a3-7c03-b395-5a0d2757214d
2026-08-22 12:07:08 +02:00
697dd49390 feat(consistency): rebuild deterministic projection IDs
All checks were successful
CI Smoke / host-smoke (push) Successful in 0s
CI Smoke / container-smoke (push) Successful in 1s
Build and Publish Multi-Context Image / build-and-push (push) Successful in 26s
Assistant: codex
Assistant-Model: gpt-5.6-sol
Assistant-Session: 01a023c0-a0a3-7c03-b395-5a0d2757214d
2026-08-22 09:43:55 +02:00
b9d9ffed5f feat(consistency): consume repo-manager conformance
All checks were successful
CI Smoke / host-smoke (push) Successful in 1s
CI Smoke / container-smoke (push) Successful in 1s
Assistant: codex
Assistant-Model: gpt-5.6-sol
Assistant-Session: 01a023c0-a0a3-7c03-b395-5a0d2757214d
2026-08-21 22:34:24 +02:00
433e104909 fix: route registrar skips through repo-manager
All checks were successful
CI Smoke / host-smoke (push) Successful in 0s
CI Smoke / container-smoke (push) Successful in 1s
2026-08-21 21:41:15 +02:00
d8e0eddb22 feat: delegate project register; registrar-only ID minting
All checks were successful
CI Smoke / host-smoke (push) Successful in 0s
CI Smoke / container-smoke (push) Successful in 1s
Build and Publish Multi-Context Image / build-and-push (push) Successful in 39s
STATE-WP-0080-T02: statehub register routes project-flavor scaffolding
through rmgr scaffold and keeps only repo + host-path registration.
T01 refuse remains when GOAL.md is missing and --wp-prefix is not set.

RMGR-WP-0005-T01: C-06/C-11/C-32 skip mint+writeback unless this
instance is the identifier registrar (STATEHUB_REGISTRAR or railiance
hostname).
2026-08-18 21:51:30 +02:00
6d038fd050 fix: stop C-23 promoting proposed and C-15 overwriting files
All checks were successful
CI Smoke / host-smoke (push) Successful in 0s
CI Smoke / container-smoke (push) Successful in 1s
ADR-007 / RMGR-WP-0005-T06: proposed stays a human gate. Task status
follows the file (ADR-001); wait is not "ahead" of progress or todo.
2026-08-18 13:37:26 +02:00
bfaff50b4e feat: dual-run facade to repo-manager for task writeback
Some checks failed
CI Smoke / host-smoke (push) Successful in 0s
CI Smoke / container-smoke (push) Successful in 1s
Build and Publish Multi-Context Image / build-and-push (push) Failing after 57s
RMGR-WP-0002 Stage B: when RM_WRITEBACK/RM_RECONCILE flags are set, PATCH
/tasks and C-15 writeback call rmgr; fix_repo runs rmgr reconcile for pilots.
2026-08-09 23:19:56 +02:00
fe4cfe22c9 feat: DoX assessment recording and soft visibility (STATE-WP-0077)
All checks were successful
CI Smoke / host-smoke (push) Successful in 1s
CI Smoke / container-smoke (push) Successful in 2s
Add quality_doc/dor/dod recording convention, quality-debt CLI, promote-intake
and C-34 soft warnings, agent protocol notes, and DoD policy badge language.
Mark STATE-WP-0077 finished.
2026-07-22 21:18:40 +02:00
b564ac7046 C-33: generated per-repo work-record index (CUST-WP-0061-T04)
All checks were successful
CI Smoke / host-smoke (push) Successful in 1s
CI Smoke / container-smoke (push) Successful in 4s
First cut of the transclusion-style index named in the stage-3 seed: a
WORK-RECORDS.md at repo root listing kind/id/status/lane/source for
every workplan, task, intake, decision, and engagement found in the
repo -- derived purely from files (no hub query), matching the ADR-001
rebuild principle. Full markitect transclusion rendering is a
follow-on, not this first cut.

- _generate_work_record_index(): reuses iter_workplan_files/
  parse_frontmatter/get_tasks_from_workplan for workplan+task rows,
  and the repo-wide yaml-block scan already proven by C-31/C-32 for
  intake/decision/engagement rows. Archived workplans excluded (index
  is for current orientation, not history); closed decisions/intakes/
  engagements stay listed. Returns None (no file written) for repos
  with zero work records, to avoid clutter.
- _check_work_record_index_freshness(): C-33, WARN+fixable when
  WORK-RECORDS.md is missing or its content differs from a fresh
  regeneration.
- fix_repo C-33 dispatch: overwrites the file with the regenerated
  content.

13 new tests (generation across all kinds, sort order, archived
exclusion, self-scan exclusion, freshness detection incl. idempotence).
No regressions: full repo suite green (561 tests).

Live-verified at two scales: binky-control (5 workplans, 31 tasks, 3
intake, 4 decisions, 5 engagements) and the-custodian (52 workplans,
332 tasks) -- both generated correctly on first run, confirmed
idempotent (identical second run produces no C-33 fix), and the larger
repo's scan added no material overhead to the existing ~1.5min
fix-consistency run.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-21 01:25:26 +02:00
aade470f4a C-32: fix-consistency registration for intake/decision work records (CUST-WP-0061-T02)
All checks were successful
CI Smoke / host-smoke (push) Successful in 1s
CI Smoke / container-smoke (push) Successful in 2s
Extends fix-consistency to scan any file for kind: intake / kind: decision
YAML blocks (not just workplans/, per canon: any file is a potential
work-record source), create the corresponding hub entity when missing a
state_hub_intake_id / state_hub_decision_id, and write the id back into
the source block -- same write-back pattern as C-06 for workplans.
kind: engagement is reported INFO (deferred, not fixable): no hub entity
exists for it yet, a separate stage-3 follow-on.

- _load_work_record_kind_registry(): kind-aware registry loader, factored
  out so C-31's existing flat _load_work_record_patterns() builds on it
  without duplication (verified: C-31's 16 tests still pass unmodified)
- _check_work_record_registration(): detection, wired into check_repo
  right after C-31
- _inject_yaml_block_field(): write-back helper for  fenced
  blocks, mirroring _inject_task_id_into_block's pattern for
  blocks
- fix_repo C-32 dispatch: creates the intake (scoped to repo_id) or
  decision (scoped to resolved topic_id, reusing C-06's domain->topic
  resolution) via the REST API, then writes the id back
- tests/test_work_record_registration.py: 15 tests (classification,
  detection incl. engagement-deferred and workplan-kind-exclusion,
  injection incl. idempotence and non-interference with sibling blocks)

Live-verified end to end against a real registered repo (binky-control,
not just synthetic fixtures): a real fix-consistency run found and
registered 3 genuinely open, previously-unlinked intake items
(AWQ-002/003/006) sitting in AutopilotWorkQueue.md, and correctly
deferred 5 real OH- engagement items as INFO. No regressions: full
consistency_check + consistency_sweep suite (128 tests) and C-31's own
suite (16 tests) still green.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-21 00:48:10 +02:00
59770145fd C-31 work-record sidetrack detector (CUST-WP-0060-T05)
All checks were successful
CI Smoke / host-smoke (push) Successful in 0s
CI Smoke / container-smoke (push) Successful in 2s
Warn on YAML-block ids matching no kind in the canon work-record type
registry (~/the-custodian/canon/standards/work-record-types.yaml, override
via WORK_RECORD_REGISTRY). Detection only; registration of non-workplan
kinds is a later stage. Skips template placeholders and repos without the
registry available.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-20 02:07:17 +02:00
b2640a1591 feat(legacy-meter): meter MCP aliases and fix brief workstream_id label (STATE-WP-0070 T03/T04)
T03: MCP alias retirement gate was unstartable — deprecation notices existed
but no mcp:* interfaces were ever registered or metered. Add
_meter_legacy_mcp() posting /legacy-meter/usage (kind mcp_tool, component
state-hub.mcp) from create_workstream, list_workstreams, update_workstream,
update_workstream_status, and state://workstreams/{topic_slug}; register all
five phase-3 backlog keys so zero-window streaks accrue from today.

T04: trace residual POST /progress/ workstream_id (3 calls/8h, unknown) to
.custodian-brief.md labelling workplans "workstream_id:"; brief generator now
prints "workplan_id:". Briefs refresh on each repo's next fix-consistency run.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-10 15:21:49 +02:00
bb6bec9f10 STATE-WP-0070: identity headers, archive 0069, phase-2 workplan
Some checks failed
CI Smoke / host-smoke (push) Successful in 0s
CI Smoke / container-smoke (push) Has been cancelled
Add X-StateHub-Component to fix-consistency and other State Hub REST callers for
legacy-meter attribution. Archive STATE-WP-0069; open STATE-WP-0070 for
meter-gated phase-2 retirement. Task POST bodies use workplan_id only.
2026-07-09 00:39:09 +02:00
b05ca2ca8c Migrate remaining in-repo workstream REST callers to /workplans
All checks were successful
CI Smoke / host-smoke (push) Successful in 0s
CI Smoke / container-smoke (push) Successful in 6s
Point cleanup_stale_tasks, validate_repo_adr, custodian_cli, dashboard data
loaders, extensions poll, MCP legacy resource, and consistency_check task
queries at preferred /workplans routes. Add caller inventory evidence doc.
2026-07-09 00:25:54 +02:00
e0c954d098 Finish STATE-WP-0069: retire legacy completion event and DELETE /workstreams
All checks were successful
CI Smoke / host-smoke (push) Successful in 0s
CI Smoke / container-smoke (push) Successful in 2s
Stop dual-publishing org.statehub.workstream.completed; return 410 Gone for
legacy DELETE /workstreams/{id}. Migrate fix-consistency, MCP adhoc bootstrap,
and dashboard token summary to /workplans/. Add legacy-meter evidence capture
script and pytest snapshot; update docs and close out the workplan.
2026-07-08 23:37:46 +02:00
931ebfb652 fix(consistency): skip terminal orphan DB tasks in C-12 check
All checks were successful
CI Smoke / host-smoke (push) Successful in 0s
CI Smoke / container-smoke (push) Successful in 5s
Cancelled or done DB tasks without file backing are historical duplicates
after workplan linkage. Do not warn on active workstreams when the orphan
is already terminal.
2026-07-08 11:42:44 +02:00
9693946755 feat(consistency): coordination hygiene checks and MCP workplan_id aliases
All checks were successful
CI Smoke / host-smoke (push) Successful in 0s
CI Smoke / container-smoke (push) Successful in 2s
Add C-25..C-30 fix-consistency checks for blocked-workplan inbox sweeps,
stale unread triage, workplan ID prefix/collision lint, and SCOPE freshness.
Extend brief generation and get_domain_summary with inbox hygiene warnings.
Complete workplan_id aliases on remaining MCP tools and retry transient
_api_get failures to reduce false stale-reference errors under load.
2026-07-08 00:56:21 +02:00
5289ba02ae feat(consistency): commit the-custodian daily-triage working-memory notes
All checks were successful
CI Smoke / host-smoke (push) Successful in 1s
CI Smoke / container-smoke (push) Successful in 4s
Sweep writeback stages memory/working/daily-triage-*.md on the-custodian
so activity-core hostPath sink notes reach git without a separate sync job.
2026-07-07 01:05:10 +02:00
16201ac918 feat(deploy): railiance01 consistency sweep host mount and hostname override
All checks were successful
CI Smoke / host-smoke (push) Successful in 0s
CI Smoke / container-smoke (push) Successful in 2s
Build and Publish Multi-Context Image / build-and-push (push) Successful in 2m3s
Add git/ssh to the runtime image, mount /home/tegwick into the state-hub pod,
resolve host_paths via STATE_HUB_SWEEP_HOSTNAME, and fall back to the
railiance01 the-custodian canon path for classification validation.
2026-07-06 19:24:28 +02:00
dbe917ceae Workplan consistency optimization 2026-07-04 00:42:56 +02:00
a361ce8731 chore: add local consistency sync cli 2026-07-02 00:15:16 +02:00
b536741539 feat(statehub): add offline write buffer relay 2026-06-25 13:44:27 +02:00
0949d4c0d8 feat(classification-spine): implement STATE-WP-0065 repo-anchored model
Replace the ad-hoc coordination-domain spine with the Repo Classification
Standard: 14 market domains, classification columns on managed_repos, and
workplans anchored by repo_id (topic_id optional).

- Add Alembic migration d8e9f0a1b2c3 with data backfill and workstream→workplan rename
- Add api/classification.py validation and register-from-classification tooling
- Expose workplan-first REST/MCP surface with legacy workstream aliases
- Add C-24 consistency rule and legacy domain frontmatter mapping
- Update dashboard repos page with category/capability/stake filters
- Update orientation docs; mark STATE-WP-0065 finished
2026-06-22 13:52:13 +02:00
39ed5459b9 finish(STATE-WP-0064): cut over scheduler and split sweep errors from failures
STATE-WP-0064 cutover (state-hub only):
- Retire local custodian-sync.timer; archive units under infra/systemd/archived/
- Mark workplan finished; update infra/README, cron-migration, runbook, AGENTS.md
- Point activity-core-delegation at the consistency-sweep runbook

Consistency engine — automation error vs assessment failure:
- C-00 is an automation error; C-01..C-23 assessment failures are recorded
  for follow-up but no longer fail --remote --all scheduled sweeps (exit 0)
- Skip workplans/README.md in the workplan glob (human index, not a workplan)
- Progress events and compare script expose automation_error and
  assessment_failures separately from exit_code
2026-06-22 01:20:59 +02:00
e9e9168921 fix: stabilize consistency make wrappers 2026-06-07 19:49:17 +02:00
b3f8ed63c2 fix: distinguish consistency API lookup failures 2026-06-07 13:53:34 +02:00
38835e9e79 feat(tasks): adopt canonical task statuses 2026-05-26 01:32:50 +02:00
d4a195d0b5 Add renormalization rule guide 2026-05-23 17:01:41 +02:00
0aa02d9117 Add lifecycle renormalization consistency repair 2026-05-23 16:54:38 +02:00
c12091c2eb Fixed and improved token tracking 2026-05-23 13:59:05 +02:00
c7150bae5f Improve dashboard loading and task sync 2026-05-19 02:32:22 +02:00
d6522a9a40 Complete workplan state model cleanup 2026-05-18 01:31:36 +02:00
2484ed2815 Load limiting safeguards 2026-05-06 04:04:53 +02:00
5429340f21 Improved workplan dependency management facilities 2026-05-04 11:45:24 +02:00
c9695d51b1 Implemented Ad-Hoc Task handling 2026-05-01 21:27:52 +02:00
45fb6e141d chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-05-01:
  - update .custodian-brief.md for the-custodian
2026-05-01 00:55:53 +02:00
768a8ba9c7 fix(api): normalize trailing slashes — no slash on param routes
Rule: trailing slash only on collection roots (/). Any route containing
a path parameter {…} uses no trailing slash. Applies across all routers,
scripts, Makefile, and tests. Fixes 307-redirect fragility on POST/PATCH
from naive clients (curl, Codex HTTP calls).

Also adds POST /repos/{slug}/sync — runs ADR-001 consistency check with
--fix via HTTP, so non-MCP agents (Codex) can self-service DB sync without
operator intervention.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-26 15:13:01 +02:00
6cbf2d2c56 feat(consistency): T04 push seal — closed-loop writeback for automated commits
Root cause of the 501-commit pile-up in inter-hub: fix_repo() created
git commits (brief updates, T03 writebacks) but never pushed them, so
the 15-minute timer accumulated local commits indefinitely. Once real
development landed on remote the repos diverged with no self-healing path.

Changes
-------
repo_sync.py (new module)
  Extracts all git lifecycle primitives: pull_ff, push_ff,
  count_remote_ahead (C-16 input), count_local_ahead (C-17/T04 input).
  Module docstring documents the push-seal invariant and stable state.

consistency_check.py
  - Imports primitives from repo_sync; thin _detect_behind_remote wrapper
    preserves backward compat for existing callers and tests.
  - C-17 backlog guard: if local has unpushed commits from a prior failed
    push, retry before making more; skip all writes if push still fails.
  - T04 push seal: unconditional push_ff() at end of every fix_repo() run.
  - _report_needs_action: ahead_of_remote param so repos with unpushed
    backlogs are not silently skipped as "clean" by fix_all_remote().
  - Domain-slug fallback: brief no longer degrades to "(unknown)" when all
    workplans are completed — falls back to any workstream for domain context.
  - Service switched from --all --fix to --remote --all (pulls before
    fixing, skips already-clean repos).

push-seal.md (new)
  Capability documentation: the problem, the invariant, all three checks
  (C-16/C-17/T04), stable-state description, API reference, and test map.

test_repo_sync.py (new, 32 tests)
  Full coverage of all four primitives via real git repos (tmp_path).
  Includes C-17 scenario, push-seal invariant, and four end-to-end
  loop-stability tests.

test_consistency_check.py
  Four new _report_needs_action cases for the ahead_of_remote parameter.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-21 01:43:40 +02:00
a486c63603 fix(consistency): prevent post-commit hook re-entrancy loop
The post-commit hook re-invokes fix-consistency, which commits writeback
changes, which re-triggers the hook — causing exponential process spawning.

Fix: pass GIT_CUSTODIAN_SYNC=1 in the env for all writeback git commits.
Update the post-commit hook (not tracked by git) to exit early when this
variable is set.

Also remove the --no-verify flag that was added as a failed attempt (it
only skips pre-commit/commit-msg, not post-commit hooks).

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-28 23:55:07 +01:00
1f8ef7f88b feat(repos): git-fingerprint-based machine-independent repo identity
Add git_fingerprint (root commit SHA-1) to managed_repos as a stable,
machine-independent identifier — identical across every clone regardless
of checkout path, remote URL, or SSH alias.

- Migration n1i2j3k4l5m6: adds git_fingerprint column + non-unique index
  (non-unique to support repos that share ancestry via forks/splits)
- GET /repos/by-fingerprint?hash=<sha>[&remote_url=<url>]: lookup by
  fingerprint; optional remote_url disambiguates shared-ancestry repos
- GET /repos/by-remote?url=<url>: fallback lookup by remote URL
- consistency_check.py --here [PATH]: auto-detects repo slug from any
  local checkout via fingerprint (falls back to remote URL), then auto-
  registers host_paths[hostname] so subsequent runs need no override
- --all now includes repos with host_paths[current_hostname], not just
  those with local_path
- fix-consistency-here / check-consistency-here Makefile targets
- Fixed _api_get bug: httpx strips query strings when params={} is passed
- Backfilled fingerprints for 14 repos on this host

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-28 23:55:06 +01:00
df2d14bae0 feat(brief): generate .custodian-brief.md per repo for offline worker orientation
Adds _write_custodian_brief() to consistency_check.py. After every fix_repo()
run, a .custodian-brief.md is written to the repo root with: domain, last-synced
timestamp, current repo goal, active workstreams with progress (done/total), and
the first 7 open tasks per workstream (blocked → in_progress → todo order) with
task IDs. The file is git-committed when content changes so remote workers (e.g.
CoulombCore) can pull it and orient without a live MCP connection.

Session protocol template and CLAUDE.md updated: read .custodian-brief.md first,
then call get_domain_summary() as an enhancement (skip if MCP unreachable).
This eliminates false "State hub is offline" alarms in subagents and remote workers.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-26 17:48:36 +01:00
075b34945f feat(consistency): fix-consistency-remote works without REPO for all repos
Adds --remote CLI flag and fix_all_remote() function. When run without a
REPO argument, the target checks all registered repos and:
- Skips repos whose local path does not exist on this machine
- Skips repos that are already clean (no fixable issues, no FAILs, not
  behind remote, only C-08 background noise allowed)
- For repos that need work: git pull --ff-only then fix_repo()

Prints a summary of CLEAN (skipped) and NOT ON THIS HOST (skipped) repos
before the detailed fix reports.

Simplifies the Makefile target from shell-level curl+git to a single
uv run call using --remote. Same flag handles both single-repo and all-repos.

Also adds _git_pull() helper and 13 new tests (71 total in consistency suite).

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-26 14:38:30 +01:00
e8bac88ba2 fix(consistency): correct behind-remote detection to not trigger on local-ahead
_detect_behind_remote was comparing HEAD != @{u} which incorrectly
triggered C-16 when the local repo had unpushed commits. Fixed to use
git rev-list --count HEAD..@{u} which only counts commits the remote
has that local lacks. Adds test_returns_false_when_local_ahead.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-26 13:31:28 +01:00