Compare commits

...

1299 Commits

Author SHA1 Message Date
a6e987bc23 Close Core Hub operator UI gate 2026-06-28 00:27:12 +02:00
56f3a3ce14 chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-06-28:
  - update .custodian-brief.md for the-custodian
2026-06-28 00:26:32 +02:00
4158f05cff Close IAM Profile integration gate 2026-06-28 00:20:05 +02:00
7d823bd12f chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-06-28:
  - update .custodian-brief.md for the-custodian
2026-06-28 00:18:17 +02:00
46e2012160 Close Core Hub ops evidence contract gate 2026-06-27 23:57:22 +02:00
b39f3cc6cc chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-06-27:
  - update .custodian-brief.md for the-custodian
2026-06-27 23:55:02 +02:00
46fff69fc0 Record artifact-store MinIO lane progress 2026-06-27 23:38:36 +02:00
225f3a7834 Refresh stabilization checkpoint after Core Hub reset 2026-06-27 23:06:15 +02:00
d03ddcd9fb Close Core Hub FOS reset workplan 2026-06-27 22:36:18 +02:00
a7635c65c9 chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-06-27:
  - update .custodian-brief.md for the-custodian
2026-06-27 22:34:55 +02:00
cac6302a0a Align Core Hub build lane with Helixforge 2026-06-27 22:29:35 +02:00
5f1aad927c chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-06-27:
  - update .custodian-brief.md for the-custodian
2026-06-27 22:28:28 +02:00
befb35c056 Rewrite FOS ops hub phase for Core Hub 2026-06-27 21:59:20 +02:00
8c4d9b952b chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-06-27:
  - update .custodian-brief.md for the-custodian
2026-06-27 21:57:50 +02:00
12600c5565 Record Core Hub replacement evidence handoff 2026-06-27 21:45:06 +02:00
7cf821de59 chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-06-27:
  - update .custodian-brief.md for the-custodian
2026-06-27 21:43:23 +02:00
0fb894eaa5 Link Core Hub continuation workplan 2026-06-27 19:56:34 +02:00
2fbfa81fdf chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-06-27:
  - update .custodian-brief.md for the-custodian
2026-06-27 19:51:06 +02:00
f490d18423 Add Core Hub FOS reset workplan 2026-06-27 19:31:09 +02:00
acbe4976af chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-06-27:
  - update .custodian-brief.md for the-custodian
2026-06-27 19:29:43 +02:00
b0d7d09594 chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-06-27:
  - update .custodian-brief.md for the-custodian
2026-06-27 19:24:46 +02:00
4a66ebfbb6 Refine security blocker posture review 2026-06-27 18:22:06 +02:00
da0735a05a Update stabilization checkpoint after staged promotion finish 2026-06-27 17:08:48 +02:00
4f49f6f23f Update stabilization checkpoint after deploy observe tooling 2026-06-27 16:53:55 +02:00
5128ab8830 Update stabilization checkpoint after canary template 2026-06-27 16:41:42 +02:00
629f4c1f53 Update stabilization checkpoint after run command 2026-06-27 16:28:28 +02:00
cbf583f76c Update stabilization checkpoint after overlay scaffold 2026-06-27 15:55:40 +02:00
eae31bab6e Update stabilization checkpoint after app contract 2026-06-27 15:35:00 +02:00
aa81d712e1 Add infrastructure stabilization checkpoint 2026-06-27 09:58:52 +02:00
1aec581919 chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-06-27:
  - update .custodian-brief.md for the-custodian
2026-06-27 09:32:25 +02:00
b73cd28e06 chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-06-27:
  - update .custodian-brief.md for the-custodian
2026-06-27 09:21:45 +02:00
58fc1134af chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-06-27:
  - update .custodian-brief.md for the-custodian
2026-06-27 09:06:58 +02:00
2cf7135ab6 chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-06-27:
  - update .custodian-brief.md for the-custodian
2026-06-27 08:59:59 +02:00
28702cd4ae chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-06-27:
  - update .custodian-brief.md for the-custodian
2026-06-27 08:03:33 +02:00
e4e9e220b6 chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-06-27:
  - update .custodian-brief.md for the-custodian
2026-06-27 07:50:32 +02:00
988a996d7c chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-06-27:
  - update .custodian-brief.md for the-custodian
2026-06-27 01:31:46 +02:00
38c52b2962 chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-06-27:
  - update .custodian-brief.md for the-custodian
2026-06-27 01:25:12 +02:00
a61a6c7dfc chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-06-27:
  - update .custodian-brief.md for the-custodian
2026-06-27 01:21:25 +02:00
a8e655e4b8 chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-06-27:
  - update .custodian-brief.md for the-custodian
2026-06-27 01:17:49 +02:00
c9321b53f7 chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-06-27:
  - update .custodian-brief.md for the-custodian
2026-06-27 01:11:21 +02:00
5b5dc7604f feat: remote-build shim via sand-boxer (SAND-WP-0012)
Delegate make remote-build to sandboxer create when CLI is available;
retain legacy rsync path with deprecation notice. Add verify script.
2026-06-24 12:56:32 +02:00
7e1cfa005b SAND-WP-0004: delegate make e2e to validate run
Replace e2e_framework monolith with wise-validator + sand-boxer shim.
Makefile invokes validate run; legacy python -m e2e_framework delegates
via shim.py with deprecation notice. Add verify-e2e-shim.sh.
2026-06-23 21:43:53 +02:00
8bdefcd6ba Normalize agent instructions and workplan frontmatter (STATE-WP-0067)
- Align agent files with on-disk workplan prefixes (infer from workplan ids)
- Set workplan domain to registered domain_slug; add topic_slug where applicable
- Repair frontmatter delimiter formatting; migrate legacy task status literals
- Regenerate AGENTS.md, CLAUDE.md, and .claude/rules from State Hub templates
2026-06-22 23:16:28 +02:00
d30e71fb43 Mark CUST-WP-0025 T09–T12 done after dev-hub MCP rename
Phase 2 hub extraction and dev-hub rename gate complete: MCP identifier
migration, config script, domain repo rule regeneration, and test suite.
2026-06-22 21:24:35 +02:00
c3c97bba83 chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-06-22:
  - update .custodian-brief.md for the-custodian
2026-06-22 21:05:40 +02:00
2c8083e8e3 Close CUST-WP-0048 hub-core import refactor (T05-T08)
Mark capability write and MCP composition tasks done, record 426-test
regression, finish child workplan, and complete CUST-WP-0025-T08.
2026-06-22 20:34:02 +02:00
604c598814 chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-06-22:
  - update .custodian-brief.md for the-custodian
2026-06-22 20:33:42 +02:00
f94120105f docs(hub-core): record HUB-WP-0002 write router and MCP composition seams 2026-06-22 19:52:22 +02:00
24494f3eee chore: backfill state_hub_workstream_id on CUST-WP-0045 cutover runbook
Sync runbook frontmatter with State Hub workstream linkage from fix-consistency.
2026-06-22 19:47:23 +02:00
db88a34b3e CUST-WP-0050 follow-up: human review, push tooling, SSH inventory
Add human-review script for 13 high-blast-radius repos, bulk-push helper,
and SSH-based Gitea inventory probe. Update exclusion list with SSH-verified
absent slugs; marki-docx now classified and registered.
2026-06-22 17:59:55 +02:00
61fe8e0309 chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-06-22:
  - update .custodian-brief.md for the-custodian
2026-06-22 17:53:06 +02:00
f9837e3703 Complete CUST-WP-0050 T11: classify and register remaining portfolio repos
Add exclusion list and batch classification author for post-cutover inventory.
Mark workplan finished after registering 7 new repos and reclassifying 43
migration rows via state-hub register-from-classification tooling.
2026-06-22 17:50:26 +02:00
96a4c7bea9 chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-06-22:
  - update .custodian-brief.md for the-custodian
2026-06-22 12:43:10 +02:00
06feb41588 CUST-WP-0050: backfill T11 state_hub_task_id [consistency]
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-22 11:57:58 +02:00
a0b79cd09e chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-06-22:
  - update .custodian-brief.md for the-custodian
2026-06-22 11:56:33 +02:00
4099179374 CUST-WP-0050: drop T03, re-home T04-T10 to STATE-WP-0065, add T11
Per 2026-06-22 review: T03 dropped (registering unregistered repos under the
old model = legacy to clean up). Implementation re-homed to state-hub-local
STATE-WP-0065; T04/T05/T10 merged into one spine migration (P1). CUST-WP-0050
stays the coordination driver. T11 (post-cutover inventory) replaces T03.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-22 11:52:55 +02:00
9456b3812e chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-06-22:
  - update .custodian-brief.md for the-custodian
2026-06-22 11:41:53 +02:00
c4c61f4550 CUST-WP-0050 T02: human review complete; close T02
Bernd confirmed kaizen-agentic and llm-connect stay agents-primary
(infotech secondary). All 11 custodian-repo .repo-classification.yaml
flipped to classified_by: human and re-validated clean against T01.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-22 11:31:39 +02:00
27b7e3f08a Add 'tooling' category to Repo Classification Standard
Insert a 'tooling' category between project and product (reusable internal
tooling/infrastructure: libraries, CLIs, services, ops components used across
the ecosystem rather than offered to external customers). Update §5 definition,
§11 decision procedure, §16 agent prompt, the machine-readable allowed-values,
and the CUST-WP-0050 T02 progress note. Nine custodian tooling repos
reclassified to it; the-custodian and inter-hub remain research.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-22 03:08:20 +02:00
40cc73f22e CUST-WP-0050 T02: classify remaining 10 custodian repos
All 11 custodian-domain repos now carry a committed, validated
.repo-classification.yaml (first-pass classified_by: agent). T02 remains
in_progress pending the human-review step.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-22 02:47:43 +02:00
46e3566793 chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-06-22:
  - update .custodian-brief.md for the-custodian
2026-06-22 02:02:48 +02:00
044d088109 Start CUST-WP-0050: T01 allowed-values + validator; classify the-custodian
Activate the workplan and complete T01: add the machine-readable controlled
vocabulary canon/standards/repo-classification.allowed.yaml (categories,
domains, business_stake, business_mechanics, capability families, guidance),
reference it from the standard §12, and add tools/validate_repo_classification.py
(stdlib + PyYAML, --self-test PASS).

Begin T02: author the-custodian/.repo-classification.yaml (research · infotech ·
agents), which validates clean. classified_by: agent, pending human review.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-22 02:02:01 +02:00
a74f42de06 Fix D1 reference in CUST-WP-0050 (D1 -> D1/D1a)
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-22 01:47:54 +02:00
50f4564561 Resolve CUST-WP-0050 D1: repo-anchored model + ADR-005
Adopt the repo as the primary workplan anchor: repo_id becomes required,
market-domain is derived from each repo's classification, and the
domain/topic spine is demoted/retired (RepoGoal becomes the goal primitive).
Add task T10 for the re-anchor plus the workstream -> workplan rename across
schema/API/MCP.

Add ADR-005 (Cross-Repo Workplans Live in Dedicated Project Repos): complex
cross-repo efforts get their own project repo (category: project) as the
anchor, retired to archive on completion with results living on in the
modified product repos. Rewrite D1 as resolved and add D1a for the
project-repo naming/archival convention.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-22 01:36:31 +02:00
0ba909263b Add CUST-WP-0050: repo classification & registration redesign
Proposed workplan to adopt the Repo Classification Standard ecosystem-wide:
per-repo .repo-classification.yaml as source of truth, State Hub domain model
replaced by the standard's 14 market domains, auto-registration tooling, and
reclassification of the 57 existing registrations. Folds in the 2026-06-21
discrepancy findings as reconciliation targets. Blocking design question D1
(topic vs market-domain) flagged for resolution before schema work.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-22 01:19:38 +02:00
2c27ac6d2e Promote Repo Classification Standard into custodian canon
Move specs/RepoClassificationStandard.md to
canon/standards/repo-classification-standard_v1.0.md with provenance
frontmatter (id: canon-repo-classification, status: active, v1.0). The
standard originated in Helix Forge; the-custodian is interim steward. Leave
a pointer stub in specs/ redirecting to canon and the rollout workplan.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-22 01:19:38 +02:00
5d94fd679a New repo classification system 2026-06-22 01:02:28 +02:00
1ae82e01ae feat(STATE-WP-0064): enable consistency sweep for parallel week
Activate the Railiance01 schedule alongside the local timer during T03.
2026-06-21 21:46:43 +02:00
16a4752f54 docs: fix schedule sync commands in hourly RecentlyOnScope runbook
Document admin/sync and the new make sync-schedules target.
2026-06-21 20:28:04 +02:00
8cfda08cea feat(STATE-WP-0064): add state-hub-consistency-sweep ActivityDefinition
Land the 15-minute consistency sync definition disabled until manual
canary and cutover from the local custodian-sync timer.
2026-06-21 20:19:22 +02:00
4eec96aa02 docs: fix stale domain references in README
- "seven project domains" (contradicted "six") -> "a growing set"
- clarify the six canon charters are the founding domains; note the hub
  now tracks a larger live set (14 active) via list_domains()
- rename Foerster Capabilities -> Capabilities (live domain slug) in the
  dependency chain and domains table

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-21 16:16:09 +02:00
e57be41026 Rebuild SCOPE.md from current repo reality; archive stale version
Archive the out-of-date SCOPE.md to history/20260621-SCOPE.md and rebuild
it via the kaizen scope-analyst persona, grounded in INTENT.md (the newer
boundary authority), the repo tree, and the live list_domains() result.

Fixes:
- Stop conflating this repo with the standalone State Hub service: reframe
  Provided Capabilities to governance canon / session protocol / append-only
  memory (state-tracking, SBOM, MCP-tool-registration belong to /state-hub).
- Add missing boundary owners issue-core and repo-scoping to Out of Scope.
- Replace the self-contradictory 6/7 domain count with a pointer to the live
  list (14 active as of 2026-06-21).
- Add updated frontmatter for freshness tracking.

Also records the scope-analyst agent memory for future runs.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-21 16:16:09 +02:00
87f6c00f6d Ignore kaizen metrics and local agent backup directories
Runtime .kaizen/metrics/ output and agents_backup_* migration copies
should not appear in version control.
2026-06-19 21:17:33 +02:00
1ad3dfac77 Promote kaizen schedule to weekly cadence and add credential routing
- Switch coach and optimization agents from daily to weekly Monday crons
- Restore disabled tdd-workflow stanza; quote cron expressions
- Add credential routing guidance to AGENTS.md for Codex/Grok agents
- Wire credential-routing rule into CLAUDE.md for Claude Code sessions
- Scaffold kaizen agent memory files and record failed daily-triage run
2026-06-19 21:13:25 +02:00
e14b0bf356 Install kaizen coach and optimization agents for WP-0006 pilot
Enables schedule validate/prepare on the-custodian hub operator checkout.
2026-06-18 15:15:37 +02:00
a0a117ebcc chore: promote coulomb-loop pilot schedule to daily stabilize phase 2026-06-18 12:09:25 +02:00
dd48a0ba26 Opt in to coulomb-loop kaizen bootstrap scheduling.
Add .kaizen/schedule.yml with hourly coach and optimization crons for the
coulomb-loop fleet improvement pilot.
2026-06-18 04:53:50 +02:00
30730db7a5 feat(custodian): add interhub bootstrap access lane 2026-06-17 00:17:58 +02:00
cdff0055f0 chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-06-17:
  - update .custodian-brief.md for the-custodian
2026-06-17 00:10:53 +02:00
5a36ea5423 feat(ops): align inventory probe activity source 2026-06-16 23:41:37 +02:00
6a9886d652 chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-06-16:
  - update .custodian-brief.md for the-custodian
2026-06-16 23:39:55 +02:00
55ba80e584 Add capability registry scaffold (REUSE-WP-0014-T07 B05) 2026-06-16 01:59:02 +02:00
94d8fe9563 chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-06-07:
  - update .custodian-brief.md for the-custodian
2026-06-07 22:29:21 +02:00
bf90efee28 docs: record repo router import seam 2026-06-07 22:27:43 +02:00
063705756e docs: record state hub ids for CUST-WP-0048 2026-06-07 21:56:31 +02:00
1ee389b7ec chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-06-07:
  - update .custodian-brief.md for the-custodian
2026-06-07 21:55:26 +02:00
8abc274411 docs: extract hub-core import refactor workplan 2026-06-07 21:52:24 +02:00
66322722c4 docs: record capability request read seam 2026-06-07 21:23:19 +02:00
b413c8bcf9 docs: record capability catalog router seam 2026-06-07 17:20:33 +02:00
50fbdef307 docs: record additional hub-core schema imports 2026-06-07 16:44:52 +02:00
2844ece8b6 docs: record domains router import seam 2026-06-07 15:23:29 +02:00
de7b656e71 docs: record progress router import seam 2026-06-07 14:31:35 +02:00
808eedb51e docs: record TPSC router import seam 2026-06-07 14:14:23 +02:00
5e8c3aa685 docs: record policy router import seam 2026-06-07 13:23:15 +02:00
72478e820e docs: record messages router import seam 2026-06-07 11:30:50 +02:00
fb6d01b318 docs: record domain hub-core import seam 2026-06-07 10:57:07 +02:00
366bdb1bae docs: record TPSC hub-core import seam 2026-06-07 10:48:29 +02:00
d407522abc docs: start state-hub hub-core imports 2026-06-07 01:31:09 +02:00
7c3b40beed chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-06-07:
  - update .custodian-brief.md for the-custodian
2026-06-07 01:29:25 +02:00
fb59749533 docs: complete hub-core MCP and risk tools 2026-06-07 01:05:45 +02:00
fb2232cfee chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-06-07:
  - update .custodian-brief.md for the-custodian
2026-06-07 01:04:17 +02:00
02e33dab8b docs: start hub-core MCP base server 2026-06-07 00:51:02 +02:00
5db039a1f7 chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-06-07:
  - update .custodian-brief.md for the-custodian
2026-06-07 00:48:12 +02:00
7301494379 docs: complete hub-core package slice 2026-06-07 00:39:38 +02:00
6a8a2fba74 chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-06-07:
  - update .custodian-brief.md for the-custodian
2026-06-07 00:37:15 +02:00
db4bc0f9d0 chore(memory): add daily-triage working notes (2026-06-05/06) [auto]
Append activity-core generated daily-triage working-memory notes.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-07 00:12:35 +02:00
b1aac08eb2 feat(ops): add ops-hub service inventory now view (CUST-WP-0047)
Seed a non-secret service inventory (environments, hosts, clusters,
services, endpoints, access paths, evidence, gaps) with a JSON schema,
a renderer, and a generated service-catalog view. Adds the
`make ops-inventory-view` target, probe ActivityDefinition, and docs.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-07 00:12:30 +02:00
4bdfeb1850 docs: record hub-core adapter seams 2026-06-06 22:30:29 +02:00
9d5c13abb6 docs: record hub-core utilities slice 2026-06-06 22:14:02 +02:00
bd0f9164b5 docs: record hub-core router slice 2026-06-06 20:17:31 +02:00
f46f461720 docs: start CUST-WP-0025 hub-core extraction 2026-06-06 19:33:53 +02:00
6629826f36 chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-06-06:
  - update .custodian-brief.md for the-custodian
2026-06-06 19:25:31 +02:00
f342504a4c chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-06-05:
  - update .custodian-brief.md for the-custodian
2026-06-05 21:23:42 +02:00
e1fd46c57c chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-06-05:
  - update .custodian-brief.md for the-custodian
2026-06-05 21:14:21 +02:00
fd9212435e chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-06-05:
  - update .custodian-brief.md for the-custodian
2026-06-05 20:56:54 +02:00
9a03677475 Daily triage stuff 2026-06-05 13:11:41 +02:00
5ceb771a8f chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-06-04:
  - update .custodian-brief.md for the-custodian
2026-06-04 08:18:21 +02:00
87619c85e8 chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-06-04:
  - update .custodian-brief.md for the-custodian
2026-06-04 08:09:49 +02:00
e75c65a2a7 Record daily WSJF triage notes 2026-06-03 09:53:23 +02:00
6d1b045f10 chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-06-03:
  - update .custodian-brief.md for the-custodian
2026-06-03 09:42:08 +02:00
030d3f125c Enable activity-core daily triage ActivityDefinition (CUST-WP-0045)
Codex daily-state-hub-wsjf-triage paused per operator confirmation;
activity-core is now the only enabled runner for the daily State Hub
WSJF triage at 07:20 Europe/Berlin. Set status: draft → active to
match.

Temporal schedule activity-schedule-6fca51fa-... is unpaused; next
run tomorrow ~07:20 Europe/Berlin will be the first real scheduled
verification.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-06-02 16:16:33 +02:00
80309950bc Close CUST-WP-0045-T06 — canary green on 2026-06-02
The daily-triage workflow completed end-to-end with all three evidence
surfaces (working-memory note, State Hub daily_triage event, ActivityRun
row) referencing the same run_id f9b97749. Backend: llm-connect against
OpenRouter anthropic/claude-sonnet-4, 12.85s end-to-end.

Add Implementation Notes - 2026-06-02 capturing the bug chain found and
fixed today (five llm-connect commits, two activity-core commits), the
backend choice and its consequences for the next scheduled run, and an
explicit carve-out: the operational cutover step (pause Codex, flip
enabled: true, sync schedules) is intentionally deferred to operator
action and remains a prerequisite for T08.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-06-02 15:50:35 +02:00
1874ab52bb Pin llm-connect to :8088 in CUST-WP-0045 cutover runbook
llm-connect's CLI default port (:8080) collides with the dev stack's
temporal-ui container. Hit during the 2026-06-01 cutover attempt with
OSError: Address already in use. Update Steps 3, 5, and 6 to use :8088
and note the conflict reason inline so the next operator does not
rediscover this the slow way.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-06-02 03:32:01 +02:00
9d1a35e61b Note 2026-06-01 cutover-runbook session on CUST-WP-0045
T06 remains in_progress — no canary was rerun. Capture the runbook deliverable
(workplans/CUST-WP-0045-cutover-runbook.md @ 8ef5399), the still-unchanged
upstream fixes that should let the patched canary succeed, and the two
operational gotchas the runbook now documents (host-mode env overrides vs.
Docker-network .env; Claude CLI quota collision when triggering from inside
an active Claude Code session). Bump updated: to 2026-06-01.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-06-02 02:16:50 +02:00
8ef5399c07 Add CUST-WP-0045 T06 cutover runbook
Exact command sequence to rerun the patched real-LLM canary and, on success,
perform the Codex → activity-core cutover. Captures the heads-up about CLI
session collision, the host-mode env-var overrides for the worker/API, and the
verification queries for all three evidence surfaces. Frontmatter uses
type: runbook so the consistency checker does not treat it as a workstream.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-06-02 01:55:27 +02:00
24d6f2d178 Activity core practicability trial stuff 2026-05-23 03:17:02 +02:00
597f6456ef chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-05-23:
  - update .custodian-brief.md for the-custodian
2026-05-23 02:30:22 +02:00
56d7fcb2d4 Add hourly RecentlyOnScope activity definition 2026-05-22 16:14:10 +02:00
d10ee0938d chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-05-22:
  - update .custodian-brief.md for the-custodian
2026-05-22 16:11:18 +02:00
9d6e9afa19 chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-05-22:
  - update .custodian-brief.md for the-custodian
2026-05-22 16:07:28 +02:00
f8a6c3c7b4 Deprecate Custodian IAM profile draft 2026-05-22 14:35:31 +02:00
1e3f80e5e8 hourly recently notifications 2026-05-22 13:43:11 +02:00
12be7d5b0d chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-05-22:
  - update .custodian-brief.md for the-custodian
2026-05-22 12:12:54 +02:00
a28deec772 Record daily triage schema canary blocker 2026-05-21 03:19:27 +02:00
ed6a13c8d7 Use llm-connect profile for daily triage 2026-05-19 20:56:07 +02:00
d6640f297b chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-05-19:
  - update .custodian-brief.md for the-custodian
2026-05-19 20:53:31 +02:00
2e50588837 Record daily triage activity-core canary blocker 2026-05-19 20:14:19 +02:00
61afb44bfa chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-05-19:
  - update .custodian-brief.md for the-custodian
2026-05-19 20:11:42 +02:00
bdf21d895a chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-05-19:
  - update .custodian-brief.md for the-custodian
2026-05-19 20:08:42 +02:00
5bac8bd6a5 chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-05-19:
  - update .custodian-brief.md for the-custodian
2026-05-19 19:10:43 +02:00
350c11c4f9 Make daily triage ActivityDefinition executable 2026-05-19 19:09:42 +02:00
a27e51b83a chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-05-19:
  - update .custodian-brief.md for the-custodian
2026-05-19 18:38:16 +02:00
925fee3f90 Record CUST-WP-0045 report sinks 2026-05-19 18:37:18 +02:00
a6d83893f3 chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-05-19:
  - update .custodian-brief.md for the-custodian
2026-05-19 18:30:20 +02:00
92146099bc Record CUST-WP-0045 instruction execution 2026-05-19 18:29:02 +02:00
a902204366 chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-05-19:
  - update .custodian-brief.md for the-custodian
2026-05-19 16:00:55 +02:00
4992d40a8b Record CUST-WP-0045 implementation start 2026-05-19 15:59:32 +02:00
842198c1d8 Register CUST-WP-0045 with State Hub 2026-05-19 15:52:29 +02:00
375c06fd4d chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-05-19:
  - update .custodian-brief.md for the-custodian
2026-05-19 15:51:17 +02:00
44be583cdd Add activity-core daily triage runner workplan 2026-05-19 15:49:47 +02:00
9ff8887480 Refresh agent instruction files 2026-05-18 16:55:54 +02:00
5d478cf746 Remove migrated State Hub workplans 2026-05-18 01:33:25 +02:00
be9ccf1074 chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-05-17:
  - update .custodian-brief.md for the-custodian
2026-05-17 23:28:56 +02:00
45d296b236 Implement daily State Hub WSJF triage 2026-05-17 23:10:57 +02:00
c0a3fb6543 chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-05-17:
  - update .custodian-brief.md for the-custodian
2026-05-17 23:01:27 +02:00
a8cfa735f3 Add daily State Hub WSJF triage workplan 2026-05-17 22:39:06 +02:00
ac58c50b4f chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-05-17:
  - update .custodian-brief.md for the-custodian
2026-05-17 22:31:02 +02:00
266b22da86 docs: close state hub extraction 2026-05-17 21:36:40 +02:00
404ad23c7c chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-05-17:
  - update .custodian-brief.md for the-custodian
2026-05-17 21:35:51 +02:00
dae787e89b chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-05-17:
  - update .custodian-brief.md for the-custodian
2026-05-17 20:30:41 +02:00
0f4eb756f3 docs(state-hub): close extraction handoff 2026-05-17 20:28:34 +02:00
d9ac2fa24f chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-05-17:
  - update .custodian-brief.md for the-custodian
2026-05-17 20:23:37 +02:00
0375e57626 chore(state-hub): decouple embedded service tree 2026-05-17 20:16:30 +02:00
260b6e8ebd chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-05-17:
  - update .custodian-brief.md for the-custodian
2026-05-17 20:03:09 +02:00
b94840b608 chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-05-17:
  - CUST-WP-0043-T07: todo → in_progress
2026-05-17 20:03:04 +02:00
80299450da chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-05-17:
  - update .custodian-brief.md for the-custodian
2026-05-17 19:26:52 +02:00
f7a5aa46c5 docs(state-hub): record extraction progress 2026-05-17 19:19:26 +02:00
7812d9a053 chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-05-17:
  - update .custodian-brief.md for the-custodian
2026-05-17 19:18:07 +02:00
a5c44d7bc9 chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-05-17:
  - update .custodian-brief.md for the-custodian
2026-05-17 19:15:40 +02:00
9df48a7b4c chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-05-17:
  - update .custodian-brief.md for the-custodian
2026-05-17 19:11:58 +02:00
1e90685368 chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-05-17:
  - update .custodian-brief.md for the-custodian
2026-05-17 18:52:12 +02:00
c01bc242e1 chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-05-17:
  - CUST-WP-0043-T01: todo → in_progress
2026-05-17 18:52:05 +02:00
ab77698702 docs(state-hub): plan repo extraction 2026-05-17 18:48:31 +02:00
4121fc11dc chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-05-17:
  - update .custodian-brief.md for the-custodian
2026-05-17 18:36:41 +02:00
793c91bc95 chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-05-17:
  - update .custodian-brief.md for the-custodian
2026-05-17 18:35:24 +02:00
45b1220e2f chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-05-17:
  - update .custodian-brief.md for the-custodian
2026-05-17 18:16:57 +02:00
ca8a09ed04 feat(state-hub): CUST-WP-0040 — NATS lifecycle event publishing for activity-core
Makes the state hub an event publisher so activity-core can drive
maintenance automation declaratively via ActivityDefinitions, rather
than the hub creating tasks itself.

- api/events/: lazy JetStream publisher + EventEnvelope mirroring
  activity-core's contract; no-op when NATS_URL unset, fire-and-forget
  with logged failures so publishing never breaks an API request.
- Wired publishers on the five v1.0 lifecycle events:
    org.statehub.repo.registered        (POST /repos/)
    org.statehub.workstream.completed   (PATCH /workstreams/* on transition)
    org.statehub.decision.resolved      (POST /decisions/*/resolve)
    org.statehub.domain.goal.activated  (POST /domain-goals/*/activate)
    org.statehub.task.stale             (scripts/cleanup_stale_tasks.py)
- docs/nats-event-subjects.md: subject naming convention + catalog.
- docs/cron-migration.md: design stub for replacing custodian-sync
  systemd timer and cleanup-stale cron with ActivityDefinitions
  (depends on activity-core WP-0003).
- docs/activity-core-delegation.md: protocol, invariants, cutover plan.
- SCOPE.md: declares activity-core as downstream event consumer and
  restates that the state hub stays a read model, not a task factory.

Workplan: workplans/CUST-WP-0040-state-hub-nats-activity-core-integration.md
242 tests pass.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-17 05:49:29 +02:00
2bc7fd8ce7 chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-05-17:
  - update .custodian-brief.md for the-custodian
2026-05-17 05:46:48 +02:00
3f098f1c0d chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-05-17:
  - update .custodian-brief.md for the-custodian
2026-05-17 05:44:22 +02:00
a8ecdbfb4c Fix State Hub task links for NATS workplan 2026-05-15 15:09:13 +02:00
66db2da9d5 Update State Hub image build provenance 2026-05-15 15:02:30 +02:00
0eb2ef0650 perf(api): CUST-WP-0041 — DB indexes, TTL caches, noload on list endpoints
- Migration t7o8p9q0r1s2: indexes on tasks.status, tasks(workstream_id,status),
  workstreams.status, sbom_snapshots(repo_id,snapshot_at)
- workplan-index: 30 s TTL cache + ?refresh param (4171 ms → 16 ms on hit)
- /state/summary: 15 s TTL cache, bypassed on Cache-Control: no-cache
- /topics/: noload(workstreams, decisions, progress_events) (2382 ms → 115 ms)
- /domains/: noload(topics, repos, goals) (2252 ms → 39 ms)
- /repos/: noload(goals) (2222 ms → 599 ms first / fast on repeat)
- conftest: reset TTL caches between tests to prevent bleed-through

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-15 11:12:17 +02:00
694b493deb chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-05-15:
  - update .custodian-brief.md for the-custodian
2026-05-15 11:10:29 +02:00
e0f8bbfbfc chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-05-15:
  - CUST-WP-0041-T4: todo → done
2026-05-15 11:10:23 +02:00
8c71fcceed chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-05-15:
  - CUST-WP-0041-T3: todo → done
2026-05-15 11:10:23 +02:00
c6b213e0c0 chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-05-15:
  - CUST-WP-0041-T2: todo → done
2026-05-15 11:10:23 +02:00
8f03351e6f chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-05-15:
  - CUST-WP-0041-T1: todo → done
2026-05-15 11:10:23 +02:00
2afc8cc8aa chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-05-15:
  - update .custodian-brief.md for the-custodian
2026-05-15 10:55:14 +02:00
ee63051a50 chore(workplan): stub CUST-WP-0040 state hub NATS / activity-core integration
Workplan for delegating maintenance automation from the state hub to
activity-core via NATS JetStream. Covers NATS publisher wiring, subject
schema, lifecycle event emission, cron migration stubs, and delegation
protocol docs.

Hub workstream: d8ac100b-a844-46a5-9684-415df0d32539

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-14 18:12:29 +02:00
49f329af82 chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-05-14:
  - update .custodian-brief.md for the-custodian
2026-05-14 18:04:29 +02:00
41ce4ede2c feat(dashboard): poll optimisation — T4, T5, T6
T4: workstreams.md and dependencies.md now call /state/deps instead of the
    full /state/summary — removes 2 heavy 10-table queries per 60 s cycle.

T5: index.md's 4 independent polling loops (summaryState, sbomSnapState,
    regsState, wsChartState) consolidated into a single pageState generator
    with one Promise.all batch and a shared backoff counter.

T6: config.js gains waitForVisible(ms) — pauses polling entirely while the
    tab is hidden and fires immediately on visibilitychange.  pollDelay()
    simplified (hidden-tab POLL_HIDDEN logic removed).  All 16 polling pages
    migrated from await sleep(pollDelay(...)) to await waitForVisible(pollDelay(...)).

CUST-WP-0039 complete — all 6 tasks done.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-11 17:58:18 +02:00
1603085792 chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-05-11:
  - update .custodian-brief.md for the-custodian
2026-05-11 17:58:03 +02:00
9e7a31bc0c chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-05-11:
  - update .custodian-brief.md for the-custodian
2026-05-11 17:33:21 +02:00
512c0a73ed feat(api): dashboard poll optimisation — T1, T2, T3
T1: Cache-Control max-age=60 on /topics/, /repos/, /domains/ list endpoints
    so repeated dashboard polls within a minute are served from browser cache.

T2: ETag middleware (md5 hash) on all JSON GET responses with conditional-GET
    (304 Not Modified) support; If-None-Match and ETag added to CORS headers.
    ETag registered inside CORS so 304s automatically carry CORS headers.

T3: GET /state/deps — lightweight dep-graph endpoint returning open workstreams
    with depends_on/blocks edges only, skipping the 10-table full-summary query.
    Prerequisite for T4 (switching workstreams.md and dependencies.md off /state/summary).

Workplan: CUST-WP-0039-dashboard-poll-optimization.md

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-11 17:26:30 +02:00
6f3a46dd07 chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-05-11:
  - update .custodian-brief.md for the-custodian
2026-05-11 15:47:39 +02:00
e01298177e fix(api): restrict uvicorn --reload to source dirs only
Watching .venv/ (6k files) and dashboard/node_modules/ (6k files) was
causing sustained ~42% CPU on the uvicorn main process.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-11 15:26:48 +02:00
646fb21113 Load limiting safeguards 2026-05-06 04:04:53 +02:00
c687db2c48 chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-05-06:
  - update .custodian-brief.md for the-custodian
2026-05-06 01:37:20 +02:00
140ef33f35 chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-05-06:
  - update .custodian-brief.md for the-custodian
2026-05-06 01:02:49 +02:00
30f7ac8fea Updated repo onboarding 2026-05-04 19:18:10 +02:00
bfed370a6e Improved workplan dependency management facilities 2026-05-04 11:45:24 +02:00
4d6164e81b register project fix 2026-05-04 11:04:25 +02:00
85bf0bc180 railiance-bootstrap to railiance-cluster rename cleanup 2026-05-03 16:30:07 +02:00
190704a4eb Locked in cytoscape.js as visualization for dep graph 2026-05-03 01:43:50 +02:00
6fe8926c6d chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-05-03:
  - update .custodian-brief.md for the-custodian
2026-05-03 01:20:10 +02:00
a2d0003613 updated workplan and synced with railiance workplans 2026-05-03 01:08:37 +02:00
93cb0dd308 chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-05-03:
  - update .custodian-brief.md for the-custodian
2026-05-03 00:02:25 +02:00
49696cb0c2 Backup and restore drill 2026-05-02 23:56:20 +02:00
d152881198 chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-05-02:
  - update .custodian-brief.md for the-custodian
2026-05-02 23:48:36 +02:00
595003306b chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-05-02:
  - update .custodian-brief.md for the-custodian
2026-05-02 23:40:47 +02:00
dd887c8c81 Updated workplans for migrating the custodian to Railiance01 2026-05-02 23:38:56 +02:00
94916cbfb0 chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-05-02:
  - update .custodian-brief.md for the-custodian
2026-05-02 23:37:18 +02:00
ef201ada83 chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-05-02:
  - update .custodian-brief.md for the-custodian
2026-05-02 23:20:52 +02:00
61aad551e0 chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-05-02:
  - update .custodian-brief.md for the-custodian
2026-05-02 23:03:28 +02:00
4010ea1bcf chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-05-02:
  - update .custodian-brief.md for the-custodian
2026-05-02 22:48:01 +02:00
f6d31f999d chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-05-02:
  - update .custodian-brief.md for the-custodian
2026-05-02 22:31:07 +02:00
41008dccf0 chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-05-02:
  - update .custodian-brief.md for the-custodian
2026-05-02 22:15:11 +02:00
e5375c6bf0 chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-05-02:
  - update .custodian-brief.md for the-custodian
2026-05-02 21:58:48 +02:00
060dd2c719 chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-05-02:
  - update .custodian-brief.md for the-custodian
2026-05-02 21:42:22 +02:00
11e1a6e7e7 chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-05-02:
  - update .custodian-brief.md for the-custodian
2026-05-02 19:41:30 +02:00
4d8f701d1e chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-05-02:
  - update .custodian-brief.md for the-custodian
2026-05-02 19:25:30 +02:00
4b27ab751d chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-05-02:
  - update .custodian-brief.md for the-custodian
2026-05-02 19:09:31 +02:00
21d6654047 chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-05-02:
  - update .custodian-brief.md for the-custodian
2026-05-02 18:53:32 +02:00
59bddc06ed chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-05-02:
  - update .custodian-brief.md for the-custodian
2026-05-02 18:37:32 +02:00
e9fdf65e88 chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-05-02:
  - update .custodian-brief.md for the-custodian
2026-05-02 18:21:30 +02:00
38d9f8233a chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-05-02:
  - update .custodian-brief.md for the-custodian
2026-05-02 18:05:25 +02:00
7748ca3b57 chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-05-02:
  - update .custodian-brief.md for the-custodian
2026-05-02 17:52:31 +02:00
9d39e40b87 chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-05-02:
  - update .custodian-brief.md for the-custodian
2026-05-02 17:50:35 +02:00
1ebeb6a744 chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-05-02:
  - update .custodian-brief.md for the-custodian
2026-05-02 17:33:52 +02:00
ebf5b38417 chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-05-02:
  - update .custodian-brief.md for the-custodian
2026-05-02 17:18:11 +02:00
aeca70b71b chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-05-02:
  - update .custodian-brief.md for the-custodian
2026-05-02 17:13:59 +02:00
acd52966d3 Codex state hub stuff added 2026-05-02 17:13:13 +02:00
4c84ea201b chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-05-02:
  - update .custodian-brief.md for the-custodian
2026-05-02 17:01:03 +02:00
86945dd739 chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-05-02:
  - update .custodian-brief.md for the-custodian
2026-05-02 16:45:31 +02:00
dfc2a947ed chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-05-02:
  - update .custodian-brief.md for the-custodian
2026-05-02 16:27:58 +02:00
4707580fda chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-05-02:
  - update .custodian-brief.md for the-custodian
2026-05-02 15:46:48 +02:00
862ec0c211 chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-05-02:
  - update .custodian-brief.md for the-custodian
2026-05-02 15:30:49 +02:00
4fdaec0776 chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-05-02:
  - update .custodian-brief.md for the-custodian
2026-05-02 15:14:48 +02:00
dc6e062222 chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-05-02:
  - update .custodian-brief.md for the-custodian
2026-05-02 14:58:48 +02:00
d4de4fe954 chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-05-02:
  - update .custodian-brief.md for the-custodian
2026-05-02 14:42:49 +02:00
2a15b6e2fe chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-05-02:
  - update .custodian-brief.md for the-custodian
2026-05-02 14:26:48 +02:00
97f1ec6abe chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-05-02:
  - update .custodian-brief.md for the-custodian
2026-05-02 14:10:50 +02:00
642d885621 chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-05-02:
  - update .custodian-brief.md for the-custodian
2026-05-02 13:56:30 +02:00
f9c52786a5 chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-05-02:
  - update .custodian-brief.md for the-custodian
2026-05-02 13:39:17 +02:00
a598f7ea39 chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-05-02:
  - update .custodian-brief.md for the-custodian
2026-05-02 13:23:36 +02:00
b55435e6ee chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-05-02:
  - update .custodian-brief.md for the-custodian
2026-05-02 13:07:23 +02:00
39a5ed57fa chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-05-02:
  - update .custodian-brief.md for the-custodian
2026-05-02 12:51:25 +02:00
a65eb318ad chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-05-02:
  - update .custodian-brief.md for the-custodian
2026-05-02 12:36:33 +02:00
08dbb4f9b8 chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-05-02:
  - update .custodian-brief.md for the-custodian
2026-05-02 12:19:16 +02:00
63a5ae0aef chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-05-02:
  - update .custodian-brief.md for the-custodian
2026-05-02 12:02:56 +02:00
c48f26dd1f Overview shows workstreams by repo now and allows drilldown 2026-05-02 12:01:45 +02:00
43fcd7e8a7 chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-05-02:
  - update .custodian-brief.md for the-custodian
2026-05-02 11:52:09 +02:00
5c3b0801a4 chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-05-02:
  - update .custodian-brief.md for the-custodian
2026-05-02 11:48:44 +02:00
d85f98169d chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-05-02:
  - update .custodian-brief.md for the-custodian
2026-05-02 11:38:26 +02:00
131ee4bd5d Added IAM Profile standard 2026-05-02 10:59:21 +02:00
242a5c99a4 chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-05-02:
  - update .custodian-brief.md for the-custodian
2026-05-02 09:43:06 +02:00
f4e00f5070 Cleanup of documentation 2026-05-02 00:46:07 +02:00
37d54cbbd4 chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-05-02:
  - update .custodian-brief.md for the-custodian
2026-05-02 00:40:17 +02:00
95bcc5c83c Task flow engine implementation 2026-05-02 00:21:14 +02:00
e12a26109f chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-05-02:
  - update .custodian-brief.md for the-custodian
2026-05-02 00:02:55 +02:00
cf7d44a60e 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 23:51:48 +02:00
e1b557e38e 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 23:32:10 +02:00
2f44983732 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 23:29:33 +02:00
0bc53fd584 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 23:21:31 +02:00
a6bb72a3eb 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 23:07:07 +02:00
ddee5f5e97 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 22:51:24 +02:00
a75d569211 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 22:37:01 +02:00
a7ee22c35d 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 22:22:41 +02:00
cb90dcec4e 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 22:19:39 +02:00
4be941e65e Implemented foundation of task-flow-engine 2026-05-01 22:19:03 +02:00
de540e6341 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 22:07:27 +02:00
bbbdaf8237 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 22:00:19 +02:00
9072746d20 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 21:53:34 +02:00
00c701499c 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 21:38:07 +02:00
c8842219d0 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 21:28:21 +02:00
5d50dee3f1 Implemented Ad-Hoc Task handling 2026-05-01 21:27:52 +02:00
d015dc2e8a 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 21:22:56 +02:00
077400ddb4 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 21:07:24 +02:00
684b97875b 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 20:52:33 +02:00
ac57f794f8 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 20:37:36 +02:00
684f4a3ac0 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 20:24:29 +02:00
38edd2e737 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 20:12:28 +02:00
0f3d6843be 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 20:11:02 +02:00
17c89e67e2 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 20:07:33 +02:00
451a52ba9f 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 19:52:37 +02:00
d186e5fa4e 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 19:37:38 +02:00
10fc7d852b 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 19:22:41 +02:00
cba9d0ec1f 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 19:08:04 +02:00
8d56869aba 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 18:55:16 +02:00
8935118f1b 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 18:53:06 +02:00
c52b51419a 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 18:45:52 +02:00
5e11de02a8 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 18:37:42 +02:00
cdf74058d3 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 18:22:42 +02:00
b2beea7759 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 18:07:40 +02:00
b949f68bb0 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 17:52:38 +02:00
ccef8b55ff 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 17:37:36 +02:00
14ae1737cd 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 17:22:31 +02:00
b76673650a 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 17:07:42 +02:00
3150480e1e 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 16:53:38 +02:00
9cd7cbfb92 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 16:53:01 +02:00
68dd5b4313 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 16:37:51 +02:00
9347b48d38 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 16:22:16 +02:00
1d5e39ca6c 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 16:07:09 +02:00
eaad8ec7fb 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 15:52:02 +02:00
1bb8b25259 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 15:37:21 +02:00
74bcb93776 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 15:22:21 +02:00
4a0598a120 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 15:07:20 +02:00
7f8e3d3087 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 14:57:55 +02:00
1697477f55 Delegation of scope functionality to repo-scoping completed 2026-05-01 14:57:24 +02:00
cf5b77864b 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 14:54:46 +02:00
e99657d590 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 14:53:32 +02:00
ba407459d9 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 14:51:59 +02:00
0e6b4d3e67 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 14:42:01 +02:00
21dafaa777 New workplan for better adhoc task management 2026-05-01 14:41:16 +02:00
c8431e3160 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 14:36:56 +02:00
f933451f1f 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 14:28:01 +02:00
0a87c4cc72 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 14:21:28 +02:00
c15b800547 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 14:06:13 +02:00
b1790ce4d3 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 13:50:19 +02:00
e747f93541 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 13:35:31 +02:00
b95dd3e649 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 13:22:54 +02:00
4e0c42f798 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 13:21:19 +02:00
d1fb5dbe5f 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 13:04:40 +02:00
096a1ba92d 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 12:50:20 +02:00
30b5391fc4 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 12:36:51 +02:00
59b53b8730 Scope update from repo-scoping refactor 2026-05-01 12:36:24 +02:00
5f80e4034e 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 12:34:03 +02:00
2d53b49f97 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 12:19:23 +02:00
8ac3ba9fdd 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 12:04:23 +02:00
03e17d8158 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 11:49:03 +02:00
bfb96ce0fe 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 11:33:52 +02:00
c985fe7e1d 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 11:17:29 +02:00
09af63892e 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 11:02:52 +02:00
f5cb1475a0 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 03:49:57 +02:00
b348b121fc 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 03:35:24 +02:00
8cf3944a03 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 03:20:52 +02:00
8b584a2ca5 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 03:06:18 +02:00
fdbeaf132b 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 02:51:48 +02:00
1c330ddf2f 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 02:37:19 +02:00
195971a6c1 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 02:22:48 +02:00
baf02b1bfc 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 02:08:24 +02:00
9563277196 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 01:54:40 +02:00
bef25b0d95 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 01:47:52 +02:00
01af0f8810 scope refactoring 2026-05-01 01:47:14 +02:00
9f559e640f 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 01:40:49 +02:00
56b4a0a260 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 01:33:49 +02:00
273bcb5b78 state-hub scope functionality work 2026-05-01 01:33:15 +02:00
1c4bff9d72 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 01:25:50 +02:00
44b1a12924 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 01:10:13 +02:00
f99d77d539 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
ffa3809e95 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:40:50 +02:00
160fac213d 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:26:08 +02:00
b5c3d5e086 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:11:28 +02:00
cdb0aed39d chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-04-30:
  - update .custodian-brief.md for the-custodian
2026-04-30 23:56:51 +02:00
45d6a94a05 chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-04-30:
  - update .custodian-brief.md for the-custodian
2026-04-30 23:42:21 +02:00
096fff6961 chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-04-30:
  - update .custodian-brief.md for the-custodian
2026-04-30 23:27:57 +02:00
10c9032ea3 chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-04-30:
  - update .custodian-brief.md for the-custodian
2026-04-30 23:13:14 +02:00
3f55d241f4 chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-04-30:
  - update .custodian-brief.md for the-custodian
2026-04-30 22:59:16 +02:00
89cea222a2 chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-04-30:
  - update .custodian-brief.md for the-custodian
2026-04-30 22:44:44 +02:00
b4d7ad5f7c chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-04-30:
  - update .custodian-brief.md for the-custodian
2026-04-30 22:29:43 +02:00
8259909ac5 chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-04-30:
  - update .custodian-brief.md for the-custodian
2026-04-30 22:14:31 +02:00
936984384d chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-04-30:
  - update .custodian-brief.md for the-custodian
2026-04-30 22:00:15 +02:00
5b77176e73 chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-04-30:
  - update .custodian-brief.md for the-custodian
2026-04-30 21:45:13 +02:00
5b39861a21 chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-04-30:
  - update .custodian-brief.md for the-custodian
2026-04-30 21:30:34 +02:00
e6a3de8ecb chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-04-30:
  - update .custodian-brief.md for the-custodian
2026-04-30 21:16:24 +02:00
1cf1b72637 chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-04-30:
  - update .custodian-brief.md for the-custodian
2026-04-30 21:01:55 +02:00
65152e25ea chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-04-30:
  - update .custodian-brief.md for the-custodian
2026-04-30 20:47:16 +02:00
ea90fd0f81 chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-04-30:
  - update .custodian-brief.md for the-custodian
2026-04-30 20:32:40 +02:00
bf6e501b20 chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-04-30:
  - update .custodian-brief.md for the-custodian
2026-04-30 20:18:17 +02:00
f397e03558 chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-04-30:
  - update .custodian-brief.md for the-custodian
2026-04-30 20:03:20 +02:00
e88e448cf3 chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-04-30:
  - update .custodian-brief.md for the-custodian
2026-04-30 19:47:57 +02:00
4d2f916f15 chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-04-30:
  - update .custodian-brief.md for the-custodian
2026-04-30 19:33:06 +02:00
2436f571e8 chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-04-30:
  - update .custodian-brief.md for the-custodian
2026-04-30 19:18:19 +02:00
e506f4fe6e chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-04-30:
  - update .custodian-brief.md for the-custodian
2026-04-30 19:03:38 +02:00
7129b66cfe chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-04-30:
  - update .custodian-brief.md for the-custodian
2026-04-30 18:49:40 +02:00
bad100295b chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-04-30:
  - update .custodian-brief.md for the-custodian
2026-04-30 18:36:18 +02:00
aaeeceed05 chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-04-30:
  - update .custodian-brief.md for the-custodian
2026-04-30 18:19:40 +02:00
5ac397680a chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-04-30:
  - update .custodian-brief.md for the-custodian
2026-04-30 18:05:13 +02:00
bee47833dd chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-04-30:
  - update .custodian-brief.md for the-custodian
2026-04-30 17:50:27 +02:00
4f0f49e178 chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-04-30:
  - update .custodian-brief.md for the-custodian
2026-04-30 17:34:45 +02:00
b6452984b0 chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-04-30:
  - update .custodian-brief.md for the-custodian
2026-04-30 17:20:31 +02:00
b388d7c193 chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-04-30:
  - update .custodian-brief.md for the-custodian
2026-04-30 17:05:18 +02:00
175a6662cc chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-04-30:
  - update .custodian-brief.md for the-custodian
2026-04-30 16:50:02 +02:00
92f2281f28 chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-04-30:
  - update .custodian-brief.md for the-custodian
2026-04-30 16:35:23 +02:00
46d1860eab chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-04-30:
  - update .custodian-brief.md for the-custodian
2026-04-30 16:24:03 +02:00
49578ac56f chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-04-30:
  - update .custodian-brief.md for the-custodian
2026-04-30 16:20:23 +02:00
ab9b544c84 chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-04-30:
  - update .custodian-brief.md for the-custodian
2026-04-30 16:05:29 +02:00
4f266cd467 chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-04-30:
  - update .custodian-brief.md for the-custodian
2026-04-30 15:50:32 +02:00
ea5396dc59 chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-04-30:
  - update .custodian-brief.md for the-custodian
2026-04-30 15:35:30 +02:00
e3f92b82d2 chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-04-30:
  - update .custodian-brief.md for the-custodian
2026-04-30 15:20:37 +02:00
da4feb6a8a chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-04-30:
  - update .custodian-brief.md for the-custodian
2026-04-30 15:06:03 +02:00
a38b84e281 chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-04-30:
  - update .custodian-brief.md for the-custodian
2026-04-30 15:02:27 +02:00
df2454053f chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-04-30:
  - update .custodian-brief.md for the-custodian
2026-04-30 14:50:54 +02:00
48efdb5b0b chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-04-30:
  - update .custodian-brief.md for the-custodian
2026-04-30 14:35:49 +02:00
9b0a8f1410 chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-04-30:
  - update .custodian-brief.md for the-custodian
2026-04-30 14:20:57 +02:00
7a62e2d692 chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-04-30:
  - update .custodian-brief.md for the-custodian
2026-04-30 14:06:27 +02:00
bbf4272673 chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-04-30:
  - update .custodian-brief.md for the-custodian
2026-04-30 13:50:54 +02:00
b00b20a9b9 chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-04-30:
  - update .custodian-brief.md for the-custodian
2026-04-30 13:35:51 +02:00
c96259bd5d chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-04-30:
  - update .custodian-brief.md for the-custodian
2026-04-30 13:20:50 +02:00
aba014f1f4 chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-04-30:
  - update .custodian-brief.md for the-custodian
2026-04-30 13:05:56 +02:00
36105a76fa chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-04-30:
  - update .custodian-brief.md for the-custodian
2026-04-30 12:50:45 +02:00
ba74da4641 chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-04-30:
  - update .custodian-brief.md for the-custodian
2026-04-30 12:35:38 +02:00
a7152b9caa chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-04-30:
  - update .custodian-brief.md for the-custodian
2026-04-30 12:20:33 +02:00
f75b7a4262 chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-04-30:
  - update .custodian-brief.md for the-custodian
2026-04-30 12:05:34 +02:00
cb35953e49 chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-04-30:
  - update .custodian-brief.md for the-custodian
2026-04-30 11:50:19 +02:00
5cc53eebca chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-04-30:
  - update .custodian-brief.md for the-custodian
2026-04-30 11:35:11 +02:00
f2bd283d66 chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-04-30:
  - update .custodian-brief.md for the-custodian
2026-04-30 11:20:01 +02:00
c9c929228f chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-04-30:
  - update .custodian-brief.md for the-custodian
2026-04-30 11:05:17 +02:00
8a918e3e8e chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-04-30:
  - update .custodian-brief.md for the-custodian
2026-04-30 10:49:44 +02:00
2ef0a19faa chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-04-30:
  - update .custodian-brief.md for the-custodian
2026-04-30 10:34:28 +02:00
f0ab5d315c chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-04-30:
  - update .custodian-brief.md for the-custodian
2026-04-30 10:19:11 +02:00
f1521981f0 chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-04-30:
  - update .custodian-brief.md for the-custodian
2026-04-30 10:03:52 +02:00
f04fccae99 chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-04-30:
  - update .custodian-brief.md for the-custodian
2026-04-30 09:48:30 +02:00
e834b05355 chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-04-30:
  - update .custodian-brief.md for the-custodian
2026-04-30 03:34:33 +02:00
b92a0c54ec chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-04-30:
  - update .custodian-brief.md for the-custodian
2026-04-30 03:19:52 +02:00
fb91941437 chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-04-30:
  - update .custodian-brief.md for the-custodian
2026-04-30 03:05:07 +02:00
173a20ee0c chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-04-30:
  - update .custodian-brief.md for the-custodian
2026-04-30 02:50:20 +02:00
8903163e25 chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-04-30:
  - update .custodian-brief.md for the-custodian
2026-04-30 02:35:33 +02:00
0199c6e83a chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-04-30:
  - update .custodian-brief.md for the-custodian
2026-04-30 02:20:52 +02:00
703393d68e chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-04-30:
  - update .custodian-brief.md for the-custodian
2026-04-30 02:06:10 +02:00
7b34c861fb chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-04-30:
  - update .custodian-brief.md for the-custodian
2026-04-30 01:51:49 +02:00
96885c8c3c chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-04-30:
  - update .custodian-brief.md for the-custodian
2026-04-30 01:37:58 +02:00
e863e72aa8 chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-04-30:
  - update .custodian-brief.md for the-custodian
2026-04-30 01:22:40 +02:00
f0f09b6914 chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-04-30:
  - update .custodian-brief.md for the-custodian
2026-04-30 01:07:51 +02:00
cfd9938a1b chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-04-30:
  - update .custodian-brief.md for the-custodian
2026-04-30 00:52:44 +02:00
864d862513 chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-04-30:
  - update .custodian-brief.md for the-custodian
2026-04-30 00:38:32 +02:00
9780046f0f chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-04-30:
  - update .custodian-brief.md for the-custodian
2026-04-30 00:23:12 +02:00
2bc92bd210 chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-04-30:
  - update .custodian-brief.md for the-custodian
2026-04-30 00:08:14 +02:00
e750dc98f7 chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-04-29:
  - update .custodian-brief.md for the-custodian
2026-04-29 23:53:28 +02:00
34e3a86e38 chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-04-29:
  - update .custodian-brief.md for the-custodian
2026-04-29 23:38:52 +02:00
66dab8a499 chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-04-29:
  - update .custodian-brief.md for the-custodian
2026-04-29 23:23:51 +02:00
2c38394d35 chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-04-29:
  - update .custodian-brief.md for the-custodian
2026-04-29 23:09:26 +02:00
2ad5fefa45 chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-04-29:
  - update .custodian-brief.md for the-custodian
2026-04-29 21:14:41 +02:00
3c21630de9 chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-04-29:
  - update .custodian-brief.md for the-custodian
2026-04-29 21:00:10 +02:00
e5e90599a3 chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-04-29:
  - update .custodian-brief.md for the-custodian
2026-04-29 20:45:38 +02:00
f775c5174f chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-04-29:
  - update .custodian-brief.md for the-custodian
2026-04-29 20:31:04 +02:00
91f6691594 chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-04-29:
  - update .custodian-brief.md for the-custodian
2026-04-29 20:16:30 +02:00
ccacec5a9d chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-04-29:
  - update .custodian-brief.md for the-custodian
2026-04-29 20:01:57 +02:00
79f1167fce chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-04-29:
  - update .custodian-brief.md for the-custodian
2026-04-29 19:47:22 +02:00
e3c8fb03be chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-04-29:
  - update .custodian-brief.md for the-custodian
2026-04-29 19:32:58 +02:00
10401ac0da chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-04-29:
  - update .custodian-brief.md for the-custodian
2026-04-29 19:18:31 +02:00
d0445f6f01 chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-04-29:
  - update .custodian-brief.md for the-custodian
2026-04-29 19:04:16 +02:00
4de86e930a chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-04-29:
  - update .custodian-brief.md for the-custodian
2026-04-29 18:50:07 +02:00
5d8a8bdbab chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-04-29:
  - update .custodian-brief.md for the-custodian
2026-04-29 18:35:22 +02:00
b971220a66 chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-04-29:
  - update .custodian-brief.md for the-custodian
2026-04-29 18:21:02 +02:00
6b220a88a5 chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-04-29:
  - update .custodian-brief.md for the-custodian
2026-04-29 18:07:20 +02:00
42c912c7ec chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-04-29:
  - update .custodian-brief.md for the-custodian
2026-04-29 17:52:04 +02:00
a4dc9b1dce chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-04-29:
  - update .custodian-brief.md for the-custodian
2026-04-29 17:38:14 +02:00
bdbe5c8319 chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-04-29:
  - update .custodian-brief.md for the-custodian
2026-04-29 17:22:33 +02:00
ea657ba622 chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-04-29:
  - update .custodian-brief.md for the-custodian
2026-04-29 17:07:16 +02:00
846c5a1e34 chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-04-29:
  - update .custodian-brief.md for the-custodian
2026-04-29 16:52:38 +02:00
eafa665153 chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-04-29:
  - update .custodian-brief.md for the-custodian
2026-04-29 16:38:34 +02:00
1183762a88 chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-04-29:
  - update .custodian-brief.md for the-custodian
2026-04-29 16:23:43 +02:00
eb24e6f8df chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-04-29:
  - update .custodian-brief.md for the-custodian
2026-04-29 16:10:34 +02:00
e02b14848e chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-04-29:
  - update .custodian-brief.md for the-custodian
2026-04-29 15:55:31 +02:00
d9d17210aa chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-04-29:
  - update .custodian-brief.md for the-custodian
2026-04-29 15:39:38 +02:00
684a5ade8c chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-04-29:
  - update .custodian-brief.md for the-custodian
2026-04-29 15:25:03 +02:00
9f87354c5c chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-04-29:
  - update .custodian-brief.md for the-custodian
2026-04-29 15:12:10 +02:00
2d764e51fb chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-04-29:
  - update .custodian-brief.md for the-custodian
2026-04-29 14:56:50 +02:00
4f86c07086 chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-04-29:
  - update .custodian-brief.md for the-custodian
2026-04-29 14:41:01 +02:00
90ccd210cd chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-04-29:
  - update .custodian-brief.md for the-custodian
2026-04-29 14:26:19 +02:00
069052aedd chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-04-29:
  - update .custodian-brief.md for the-custodian
2026-04-29 14:11:25 +02:00
93c8c51a7a chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-04-29:
  - update .custodian-brief.md for the-custodian
2026-04-29 13:56:21 +02:00
0661533c0b chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-04-29:
  - update .custodian-brief.md for the-custodian
2026-04-29 13:41:54 +02:00
771998c675 chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-04-29:
  - update .custodian-brief.md for the-custodian
2026-04-29 13:26:45 +02:00
be5060924d chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-04-29:
  - update .custodian-brief.md for the-custodian
2026-04-29 13:13:19 +02:00
239a677827 chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-04-29:
  - update .custodian-brief.md for the-custodian
2026-04-29 12:57:30 +02:00
2344a03965 chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-04-29:
  - update .custodian-brief.md for the-custodian
2026-04-29 12:41:53 +02:00
93da69b61d chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-04-29:
  - update .custodian-brief.md for the-custodian
2026-04-29 12:26:58 +02:00
4861e01f37 chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-04-29:
  - update .custodian-brief.md for the-custodian
2026-04-29 12:12:00 +02:00
c2a028743b chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-04-29:
  - update .custodian-brief.md for the-custodian
2026-04-29 11:56:59 +02:00
438e7bff2e chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-04-29:
  - update .custodian-brief.md for the-custodian
2026-04-29 11:41:55 +02:00
376f515ddc chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-04-29:
  - update .custodian-brief.md for the-custodian
2026-04-29 11:26:52 +02:00
b129cb1563 chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-04-29:
  - update .custodian-brief.md for the-custodian
2026-04-29 11:12:02 +02:00
7d4da50744 chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-04-29:
  - update .custodian-brief.md for the-custodian
2026-04-29 10:57:15 +02:00
9a2a49c34b chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-04-29:
  - update .custodian-brief.md for the-custodian
2026-04-29 10:41:33 +02:00
98be58ea1d chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-04-29:
  - update .custodian-brief.md for the-custodian
2026-04-29 10:26:26 +02:00
33a75afa79 chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-04-29:
  - update .custodian-brief.md for the-custodian
2026-04-29 10:12:09 +02:00
8be7a686f7 chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-04-29:
  - update .custodian-brief.md for the-custodian
2026-04-29 02:04:31 +02:00
359c049187 chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-04-29:
  - update .custodian-brief.md for the-custodian
2026-04-29 01:49:41 +02:00
59814449ab chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-04-29:
  - update .custodian-brief.md for the-custodian
2026-04-29 01:34:27 +02:00
4b2297ec67 chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-04-29:
  - update .custodian-brief.md for the-custodian
2026-04-29 01:19:18 +02:00
f657cf4521 chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-04-29:
  - update .custodian-brief.md for the-custodian
2026-04-29 01:04:49 +02:00
a8c724ec27 chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-04-29:
  - update .custodian-brief.md for the-custodian
2026-04-29 00:50:05 +02:00
d41abf8273 chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-04-29:
  - update .custodian-brief.md for the-custodian
2026-04-29 00:35:34 +02:00
1044ec623b chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-04-29:
  - update .custodian-brief.md for the-custodian
2026-04-29 00:20:29 +02:00
517b7c6ecd chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-04-29:
  - update .custodian-brief.md for the-custodian
2026-04-29 00:05:41 +02:00
64dc1c402d chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-04-28:
  - update .custodian-brief.md for the-custodian
2026-04-28 23:50:09 +02:00
1a31a28cf7 chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-04-28:
  - update .custodian-brief.md for the-custodian
2026-04-28 23:34:57 +02:00
fd768bf0b8 chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-04-28:
  - update .custodian-brief.md for the-custodian
2026-04-28 23:20:59 +02:00
e1d797a155 chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-04-28:
  - update .custodian-brief.md for the-custodian
2026-04-28 23:05:02 +02:00
03199e4535 chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-04-28:
  - update .custodian-brief.md for the-custodian
2026-04-28 22:49:18 +02:00
dd811b318f chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-04-28:
  - update .custodian-brief.md for the-custodian
2026-04-28 22:34:28 +02:00
b0e181976f chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-04-28:
  - update .custodian-brief.md for the-custodian
2026-04-28 22:18:45 +02:00
ce6af38f1b chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-04-28:
  - update .custodian-brief.md for the-custodian
2026-04-28 22:03:56 +02:00
5b263416f2 chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-04-28:
  - update .custodian-brief.md for the-custodian
2026-04-28 21:48:30 +02:00
e5a663aa52 chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-04-28:
  - update .custodian-brief.md for the-custodian
2026-04-28 21:33:25 +02:00
eb39f8da0c chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-04-28:
  - update .custodian-brief.md for the-custodian
2026-04-28 21:18:42 +02:00
53c833b88c chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-04-28:
  - update .custodian-brief.md for the-custodian
2026-04-28 06:01:21 +02:00
aaf703143a chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-04-28:
  - update .custodian-brief.md for the-custodian
2026-04-28 05:46:46 +02:00
5d0f53b2ab chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-04-28:
  - update .custodian-brief.md for the-custodian
2026-04-28 05:32:15 +02:00
3f94765385 chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-04-28:
  - update .custodian-brief.md for the-custodian
2026-04-28 05:17:43 +02:00
7dd8fdd977 chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-04-28:
  - update .custodian-brief.md for the-custodian
2026-04-28 05:03:10 +02:00
72b98adf27 chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-04-28:
  - update .custodian-brief.md for the-custodian
2026-04-28 04:48:36 +02:00
a85640b823 chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-04-28:
  - update .custodian-brief.md for the-custodian
2026-04-28 04:34:03 +02:00
46fb4b5f47 chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-04-28:
  - update .custodian-brief.md for the-custodian
2026-04-28 04:20:01 +02:00
2274b47bb9 chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-04-28:
  - update .custodian-brief.md for the-custodian
2026-04-28 04:06:56 +02:00
6188ca3595 chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-04-28:
  - update .custodian-brief.md for the-custodian
2026-04-28 03:50:56 +02:00
38d789a4f7 chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-04-28:
  - update .custodian-brief.md for the-custodian
2026-04-28 03:36:42 +02:00
f88cb974b9 chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-04-28:
  - update .custodian-brief.md for the-custodian
2026-04-28 03:22:50 +02:00
3e85fb677f chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-04-28:
  - update .custodian-brief.md for the-custodian
2026-04-28 03:06:49 +02:00
7eb4e36892 chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-04-28:
  - update .custodian-brief.md for the-custodian
2026-04-28 02:52:08 +02:00
5b3fb8c002 chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-04-28:
  - update .custodian-brief.md for the-custodian
2026-04-28 02:37:39 +02:00
48dfe7976c chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-04-28:
  - update .custodian-brief.md for the-custodian
2026-04-28 02:23:20 +02:00
ffe06e14b4 chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-04-28:
  - update .custodian-brief.md for the-custodian
2026-04-28 02:10:26 +02:00
6e56dd26b1 chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-04-28:
  - update .custodian-brief.md for the-custodian
2026-04-28 01:10:03 +02:00
9e5edbc07c chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-04-28:
  - update .custodian-brief.md for the-custodian
2026-04-28 00:55:45 +02:00
5426370903 chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-04-28:
  - update .custodian-brief.md for the-custodian
2026-04-28 00:40:39 +02:00
700e73fd6d chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-04-28:
  - update .custodian-brief.md for the-custodian
2026-04-28 00:26:11 +02:00
e7a6b2d718 chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-04-28:
  - update .custodian-brief.md for the-custodian
2026-04-28 00:11:32 +02:00
a6056b7144 chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-04-27:
  - update .custodian-brief.md for the-custodian
2026-04-27 23:56:57 +02:00
8a4d7df4c9 chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-04-27:
  - update .custodian-brief.md for the-custodian
2026-04-27 23:42:17 +02:00
37cdab58e0 chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-04-27:
  - update .custodian-brief.md for the-custodian
2026-04-27 23:27:24 +02:00
78e1ddd9d0 chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-04-27:
  - update .custodian-brief.md for the-custodian
2026-04-27 23:13:15 +02:00
e57b6ff076 chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-04-27:
  - update .custodian-brief.md for the-custodian
2026-04-27 22:58:39 +02:00
629f4039a0 chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-04-26:
  - update .custodian-brief.md for the-custodian
2026-04-26 21:24:06 +02:00
3b70d4ba79 chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-04-26:
  - update .custodian-brief.md for the-custodian
2026-04-26 21:09:07 +02:00
214ecf9f01 chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-04-26:
  - update .custodian-brief.md for the-custodian
2026-04-26 20:54:04 +02:00
526f20068e chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-04-26:
  - update .custodian-brief.md for the-custodian
2026-04-26 20:39:31 +02:00
963ac35d03 chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-04-26:
  - update .custodian-brief.md for the-custodian
2026-04-26 20:24:53 +02:00
2bd87cc4b6 chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-04-26:
  - update .custodian-brief.md for the-custodian
2026-04-26 20:09:41 +02:00
db48763824 chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-04-26:
  - update .custodian-brief.md for the-custodian
2026-04-26 19:54:58 +02:00
bc4116fc16 chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-04-26:
  - update .custodian-brief.md for the-custodian
2026-04-26 19:40:00 +02:00
ea584bedef chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-04-26:
  - update .custodian-brief.md for the-custodian
2026-04-26 19:25:17 +02:00
b94d562506 chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-04-26:
  - update .custodian-brief.md for the-custodian
2026-04-26 19:10:42 +02:00
8d1014b4a5 chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-04-26:
  - update .custodian-brief.md for the-custodian
2026-04-26 18:56:18 +02:00
acd8a42bae chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-04-26:
  - update .custodian-brief.md for the-custodian
2026-04-26 18:41:21 +02:00
3943bd191f chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-04-26:
  - update .custodian-brief.md for the-custodian
2026-04-26 18:26:49 +02:00
4876bcbc8d chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-04-26:
  - update .custodian-brief.md for the-custodian
2026-04-26 18:11:34 +02:00
2c3ebc0561 chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-04-26:
  - update .custodian-brief.md for the-custodian
2026-04-26 17:57:12 +02:00
dd37a07976 chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-04-26:
  - update .custodian-brief.md for the-custodian
2026-04-26 17:42:18 +02:00
d44c0b84de chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-04-26:
  - update .custodian-brief.md for the-custodian
2026-04-26 17:27:45 +02:00
8cca9abf1f chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-04-26:
  - update .custodian-brief.md for the-custodian
2026-04-26 17:12:51 +02:00
baef9e8b96 chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-04-26:
  - update .custodian-brief.md for the-custodian
2026-04-26 16:59:01 +02:00
8684d5fbb1 chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-04-26:
  - update .custodian-brief.md for the-custodian
2026-04-26 16:42:04 +02:00
da5aaa0d31 chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-04-26:
  - update .custodian-brief.md for the-custodian
2026-04-26 16:27:52 +02:00
38a43eb786 chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-04-26:
  - update .custodian-brief.md for the-custodian
2026-04-26 16:14:06 +02:00
a34c04ac2e chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-04-26:
  - update .custodian-brief.md for the-custodian
2026-04-26 15:59:10 +02:00
c96042f80e chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-04-26:
  - update .custodian-brief.md for the-custodian
2026-04-26 15:42:34 +02:00
d6da37366a chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-04-26:
  - update .custodian-brief.md for the-custodian
2026-04-26 15:32:12 +02:00
977d0814de chore(workplan): mark CUST-WP-0033 done — all tasks completed
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-26 15:31:29 +02:00
99fc3475c9 chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-04-26:
  - update .custodian-brief.md for the-custodian
2026-04-26 15:31:20 +02:00
294b70a75d chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-04-26:
  - update .custodian-brief.md for the-custodian
2026-04-26 15:30:10 +02:00
17303d2519 feat(state-hub): Interface Change Registry (CUST-WP-0033 T01-T06)
Adds first-class tracking for API and interface mutations across the
agent ecosystem. Breaking changes are documented, affected repos are
notified via inbox, and agents discover pending changes at session
start via the dispatch endpoint.

- Migration q4l5m6n7o8p9: interface_changes table
- Model/schema: InterfaceChange with draft→published→resolved lifecycle
- Router: POST/GET/PATCH /interface-changes/, /publish, /resolve actions
  (auto-notify affected repo agents on publish; progress event on origin)
- Dispatch: GET /repos/{slug}/dispatch now returns pending_interface_changes
- MCP tools: register_interface_change, list_interface_changes,
  publish_interface_change, resolve_interface_change
- Dashboard: /interface-changes page with type badges, planned calendar,
  published cards, and draft table
- EP-CUST-ICR-001 registered: webhook subscriptions (deliberately deferred)

First record: trailing-slash normalisation (2026-04-26), published,
affecting repo-registry — visible in repo-registry dispatch immediately.

223 tests passing.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-26 15:29:08 +02:00
17f3272a0f chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-04-26:
  - update .custodian-brief.md for the-custodian
2026-04-26 15:27:10 +02:00
3cfb20ec5d chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-04-26:
  - update .custodian-brief.md for the-custodian
2026-04-26 15:14:30 +02:00
2cd3099ebf feat(canon): add Interface Change Registry concept and workplan
Concept doc captures the design for coordinated API evolution in agent
ecosystems: InterfaceChange entity, draft→published→resolved lifecycle,
TPSC-derived dependency routing, inbox-based notifications, pre-change
coordination via planned_for, and deliberate deferral of webhooks.

CUST-WP-0033 workplan: 6 tasks (model, API, dispatch integration,
MCP tools, dashboard, webhook EP).

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-26 15:13:11 +02:00
8dd15efde1 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
fa3d7d8e8c chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-04-26:
  - update .custodian-brief.md for the-custodian
2026-04-26 15:12:26 +02:00
342f11bd25 chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-04-26:
  - update .custodian-brief.md for the-custodian
2026-04-26 15:06:17 +02:00
cd9375a550 chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-04-26:
  - update .custodian-brief.md for the-custodian
2026-04-26 15:05:29 +02:00
9f182be009 chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-04-26:
  - update .custodian-brief.md for the-custodian
2026-04-26 15:04:35 +02:00
9c534a3868 chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-04-26:
  - update .custodian-brief.md for the-custodian
2026-04-26 14:57:09 +02:00
c94761f288 chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-04-26:
  - update .custodian-brief.md for the-custodian
2026-04-26 14:43:17 +02:00
05f7339082 chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-04-26:
  - update .custodian-brief.md for the-custodian
2026-04-26 14:26:51 +02:00
8cd2e49b34 chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-04-26:
  - update .custodian-brief.md for the-custodian
2026-04-26 14:12:46 +02:00
0f8873b870 chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-04-26:
  - update .custodian-brief.md for the-custodian
2026-04-26 13:57:26 +02:00
2d73256c60 chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-04-26:
  - update .custodian-brief.md for the-custodian
2026-04-26 13:41:51 +02:00
76005aa4b5 chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-04-26:
  - update .custodian-brief.md for the-custodian
2026-04-26 13:28:07 +02:00
0d5dac86a7 chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-04-26:
  - update .custodian-brief.md for the-custodian
2026-04-26 13:27:10 +02:00
fa31befeff fix(sbom): resolve repo path from hub host_paths when --repo-path omitted
Previously defaulted to CWD ("."), causing ingest to silently scan the
state-hub directory instead of the target repo when called without
--repo-path. Now queries GET /repos/{slug}/ for host_paths[hostname]
and exits with a clear error if neither flag nor hub lookup succeeds.

Also deleted the incorrect SBOM snapshot for repo-registry (420 entries
that were actually state-hub packages).

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-26 13:27:09 +02:00
6ec47dfde4 chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-04-26:
  - update .custodian-brief.md for the-custodian
2026-04-26 13:24:05 +02:00
7a65da1ebe chore(deps): update uv.lock 2026-04-26 13:23:33 +02:00
8f8bb6c317 chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-04-26:
  - update .custodian-brief.md for the-custodian
2026-04-26 13:18:20 +02:00
3481a15e7f feat(registration): add --codex flag and AGENTS.md template
- register_project.sh: parse --additional/--codex as named flags (not
  positional), skip MCP check in codex mode, generate AGENTS.md from
  agents-codex.template instead of CLAUDE.md + .claude/rules/
- agents-codex.template: new template for Codex repos — HTTP REST session
  protocol, inbox/progress curl examples, ADR-001 workplan convention
- Makefile: add register-codex-project target

Driven by onboarding repo-registry (first non-Claude-Code repo, first
repo under the capabilities domain).

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-26 13:17:50 +02:00
6acd01d5d9 chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-04-26:
  - update .custodian-brief.md for the-custodian
2026-04-26 13:11:17 +02:00
710e385239 chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-04-26:
  - update .custodian-brief.md for the-custodian
2026-04-26 12:56:16 +02:00
1d27250556 chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-04-26:
  - update .custodian-brief.md for the-custodian
2026-04-26 12:43:25 +02:00
d653b779d9 chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-04-26:
  - update .custodian-brief.md for the-custodian
2026-04-26 12:27:43 +02:00
5748ca00f0 chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-04-26:
  - update .custodian-brief.md for the-custodian
2026-04-26 11:32:30 +02:00
d117da99ca chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-04-26:
  - update .custodian-brief.md for the-custodian
2026-04-26 11:17:43 +02:00
58d6a253ae chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-04-26:
  - update .custodian-brief.md for the-custodian
2026-04-26 11:02:59 +02:00
379c39b763 chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-04-26:
  - update .custodian-brief.md for the-custodian
2026-04-26 10:48:14 +02:00
c4fab99898 chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-04-26:
  - update .custodian-brief.md for the-custodian
2026-04-26 10:33:31 +02:00
e1f8b0286f chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-04-26:
  - update .custodian-brief.md for the-custodian
2026-04-26 10:18:42 +02:00
88c0ceab42 chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-04-26:
  - update .custodian-brief.md for the-custodian
2026-04-26 10:03:55 +02:00
1f168f7bc3 chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-04-26:
  - update .custodian-brief.md for the-custodian
2026-04-26 09:49:33 +02:00
6a6ca25471 chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-04-26:
  - update .custodian-brief.md for the-custodian
2026-04-26 09:34:55 +02:00
b08b247cf1 chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-04-26:
  - update .custodian-brief.md for the-custodian
2026-04-26 09:19:57 +02:00
2decb1c07f chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-04-26:
  - update .custodian-brief.md for the-custodian
2026-04-26 09:04:55 +02:00
1598dc66c9 chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-04-26:
  - update .custodian-brief.md for the-custodian
2026-04-26 08:50:15 +02:00
08cae005b0 chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-04-26:
  - update .custodian-brief.md for the-custodian
2026-04-26 08:34:49 +02:00
7f72a0bc72 chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-04-26:
  - update .custodian-brief.md for the-custodian
2026-04-26 08:20:06 +02:00
8e023e6837 chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-04-26:
  - update .custodian-brief.md for the-custodian
2026-04-26 08:05:38 +02:00
8872a91350 chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-04-26:
  - update .custodian-brief.md for the-custodian
2026-04-26 05:36:22 +02:00
e2c9f841d3 chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-04-26:
  - update .custodian-brief.md for the-custodian
2026-04-26 05:21:27 +02:00
95e3dae7d2 chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-04-26:
  - update .custodian-brief.md for the-custodian
2026-04-26 05:06:47 +02:00
e7ba68ffd7 chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-04-26:
  - update .custodian-brief.md for the-custodian
2026-04-26 04:51:37 +02:00
17a42026e1 chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-04-26:
  - update .custodian-brief.md for the-custodian
2026-04-26 04:36:46 +02:00
919536d3e6 chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-04-26:
  - update .custodian-brief.md for the-custodian
2026-04-26 04:21:45 +02:00
70716056c4 chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-04-26:
  - update .custodian-brief.md for the-custodian
2026-04-26 04:06:52 +02:00
23d365685e chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-04-26:
  - update .custodian-brief.md for the-custodian
2026-04-26 03:51:58 +02:00
8e5b288109 chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-04-26:
  - update .custodian-brief.md for the-custodian
2026-04-26 03:37:04 +02:00
0ba197d7ce chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-04-26:
  - update .custodian-brief.md for the-custodian
2026-04-26 03:22:46 +02:00
69b0ac6f07 chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-04-26:
  - update .custodian-brief.md for the-custodian
2026-04-26 03:08:05 +02:00
d47a2a3fd1 chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-04-26:
  - update .custodian-brief.md for the-custodian
2026-04-26 02:53:12 +02:00
5dcbaf993f chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-04-26:
  - update .custodian-brief.md for the-custodian
2026-04-26 02:38:21 +02:00
8de8b9f5d0 chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-04-26:
  - update .custodian-brief.md for the-custodian
2026-04-26 02:21:52 +02:00
99648c3638 chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-04-26:
  - update .custodian-brief.md for the-custodian
2026-04-26 02:07:13 +02:00
fed1630492 chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-04-26:
  - update .custodian-brief.md for the-custodian
2026-04-26 01:51:50 +02:00
5cc8b9aac8 chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-04-26:
  - update .custodian-brief.md for the-custodian
2026-04-26 01:36:48 +02:00
80654cafb3 chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-04-26:
  - update .custodian-brief.md for the-custodian
2026-04-26 01:21:43 +02:00
c919ed8e1e chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-04-26:
  - update .custodian-brief.md for the-custodian
2026-04-26 01:06:36 +02:00
d248ac2843 chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-04-26:
  - update .custodian-brief.md for the-custodian
2026-04-26 00:51:47 +02:00
4f63318633 chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-04-26:
  - update .custodian-brief.md for the-custodian
2026-04-26 00:37:00 +02:00
2a2f5fa612 chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-04-26:
  - update .custodian-brief.md for the-custodian
2026-04-26 00:22:18 +02:00
053d0ac0b2 chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-04-26:
  - update .custodian-brief.md for the-custodian
2026-04-26 00:07:11 +02:00
cce827d9aa chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-04-25:
  - update .custodian-brief.md for the-custodian
2026-04-25 23:51:18 +02:00
f578d9fbcd chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-04-25:
  - update .custodian-brief.md for the-custodian
2026-04-25 23:36:46 +02:00
57b9372968 chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-04-25:
  - update .custodian-brief.md for the-custodian
2026-04-25 23:20:38 +02:00
2eea36cdc9 Added missing api to the make guidance 2026-04-25 23:15:30 +02:00
df12f3c51c chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-04-25:
  - update .custodian-brief.md for the-custodian
2026-04-25 23:04:48 +02:00
edb5d0d579 chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-04-25:
  - update .custodian-brief.md for the-custodian
2026-04-25 22:52:27 +02:00
da3145ff53 chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-04-25:
  - update .custodian-brief.md for the-custodian
2026-04-25 22:36:44 +02:00
66ca151c57 chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-04-25:
  - update .custodian-brief.md for the-custodian
2026-04-25 22:19:50 +02:00
7b314c111a chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-04-25:
  - update .custodian-brief.md for the-custodian
2026-04-25 22:06:16 +02:00
382f9c8a82 chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-04-25:
  - update .custodian-brief.md for the-custodian
2026-04-25 21:51:38 +02:00
cb701ae3f2 chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-04-25:
  - update .custodian-brief.md for the-custodian
2026-04-25 21:36:30 +02:00
5c89ddfd44 chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-04-25:
  - update .custodian-brief.md for the-custodian
2026-04-25 21:20:48 +02:00
fe57cc866a chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-04-25:
  - update .custodian-brief.md for the-custodian
2026-04-25 21:08:30 +02:00
12d58e5ec6 chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-04-25:
  - update .custodian-brief.md for the-custodian
2026-04-25 20:51:55 +02:00
64b419b7fc chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-04-25:
  - update .custodian-brief.md for the-custodian
2026-04-25 20:36:23 +02:00
ea65d8247f chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-04-25:
  - update .custodian-brief.md for the-custodian
2026-04-25 20:21:57 +02:00
a51e1f7e6c chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-04-25:
  - update .custodian-brief.md for the-custodian
2026-04-25 20:07:46 +02:00
12024f8a10 chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-04-25:
  - update .custodian-brief.md for the-custodian
2026-04-25 19:51:57 +02:00
f1b9794b1c chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-04-25:
  - update .custodian-brief.md for the-custodian
2026-04-25 19:37:24 +02:00
fd230fb60e chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-04-25:
  - update .custodian-brief.md for the-custodian
2026-04-25 19:22:23 +02:00
b2f3d0c5c7 chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-04-25:
  - update .custodian-brief.md for the-custodian
2026-04-25 19:07:35 +02:00
731ae94841 chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-04-25:
  - update .custodian-brief.md for the-custodian
2026-04-25 18:53:29 +02:00
a908f68c98 chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-04-25:
  - update .custodian-brief.md for the-custodian
2026-04-25 18:38:22 +02:00
c9a1584564 chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-04-25:
  - update .custodian-brief.md for the-custodian
2026-04-25 18:24:01 +02:00
b79868e358 chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-04-25:
  - update .custodian-brief.md for the-custodian
2026-04-25 18:11:45 +02:00
9eeb38e1fc chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-04-25:
  - update .custodian-brief.md for the-custodian
2026-04-25 17:54:56 +02:00
d53a164d23 chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-04-25:
  - update .custodian-brief.md for the-custodian
2026-04-25 17:38:37 +02:00
7a3b15d8d6 Added untracked script 2026-04-25 17:08:53 +02:00
76eadffd80 chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-04-23:
  - update .custodian-brief.md for the-custodian
2026-04-23 03:22:56 +02:00
6b2551a787 chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-04-23:
  - update .custodian-brief.md for the-custodian
2026-04-23 03:08:03 +02:00
afa57e8668 chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-04-22:
  - update .custodian-brief.md for the-custodian
2026-04-22 23:47:47 +02:00
48099ee02d chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-04-22:
  - update .custodian-brief.md for the-custodian
2026-04-22 23:32:17 +02:00
02f0d06414 chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-04-22:
  - update .custodian-brief.md for the-custodian
2026-04-22 23:16:41 +02:00
ff963c26a6 chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-04-22:
  - update .custodian-brief.md for the-custodian
2026-04-22 23:01:03 +02:00
494e61550d chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-04-22:
  - update .custodian-brief.md for the-custodian
2026-04-22 22:45:30 +02:00
d935ec4d33 chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-04-22:
  - update .custodian-brief.md for the-custodian
2026-04-22 22:30:00 +02:00
3ded8006fb chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-04-22:
  - update .custodian-brief.md for the-custodian
2026-04-22 22:14:45 +02:00
599cf6d771 chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-04-22:
  - update .custodian-brief.md for the-custodian
2026-04-22 21:58:43 +02:00
2c107e3ed5 chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-04-22:
  - update .custodian-brief.md for the-custodian
2026-04-22 21:44:30 +02:00
544a0acb20 chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-04-22:
  - update .custodian-brief.md for the-custodian
2026-04-22 08:13:05 +02:00
6d62766d2a chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-04-22:
  - update .custodian-brief.md for the-custodian
2026-04-22 07:57:52 +02:00
e56e1631bd chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-04-22:
  - update .custodian-brief.md for the-custodian
2026-04-22 07:42:48 +02:00
fa8a5f92a3 chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-04-22:
  - update .custodian-brief.md for the-custodian
2026-04-22 07:27:17 +02:00
b4a57bb764 chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-04-22:
  - update .custodian-brief.md for the-custodian
2026-04-22 07:11:55 +02:00
734e94680a chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-04-22:
  - update .custodian-brief.md for the-custodian
2026-04-22 06:57:08 +02:00
627f2b4263 chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-04-22:
  - update .custodian-brief.md for the-custodian
2026-04-22 00:58:42 +02:00
beff3bedda chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-04-22:
  - update .custodian-brief.md for the-custodian
2026-04-22 00:43:00 +02:00
a291df6fb5 chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-04-22:
  - update .custodian-brief.md for the-custodian
2026-04-22 00:28:25 +02:00
a5752c5d82 chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-04-22:
  - update .custodian-brief.md for the-custodian
2026-04-22 00:12:56 +02:00
696b5da900 chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-04-21:
  - update .custodian-brief.md for the-custodian
2026-04-21 23:59:02 +02:00
dd80d490fd chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-04-21:
  - update .custodian-brief.md for the-custodian
2026-04-21 23:43:51 +02:00
fece89ba2e chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-04-21:
  - update .custodian-brief.md for the-custodian
2026-04-21 23:28:26 +02:00
ddcc392ef2 chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-04-21:
  - update .custodian-brief.md for the-custodian
2026-04-21 09:01:04 +02:00
a4050f6648 chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-04-21:
  - update .custodian-brief.md for the-custodian
2026-04-21 08:46:32 +02:00
bdef121d06 chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-04-21:
  - update .custodian-brief.md for the-custodian
2026-04-21 08:32:02 +02:00
b922d7d3cb chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-04-21:
  - update .custodian-brief.md for the-custodian
2026-04-21 08:17:27 +02:00
52ed39fa5f chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-04-21:
  - update .custodian-brief.md for the-custodian
2026-04-21 08:02:57 +02:00
16583a4d2d chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-04-21:
  - update .custodian-brief.md for the-custodian
2026-04-21 07:48:21 +02:00
5eac9f3664 chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-04-21:
  - update .custodian-brief.md for the-custodian
2026-04-21 07:33:07 +02:00
c04b72d5b9 chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-04-21:
  - update .custodian-brief.md for the-custodian
2026-04-21 07:18:32 +02:00
0ad6307323 chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-04-21:
  - update .custodian-brief.md for the-custodian
2026-04-21 07:04:07 +02:00
ec7949744f chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-04-21:
  - update .custodian-brief.md for the-custodian
2026-04-21 06:49:30 +02:00
4bd071ba7b chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-04-21:
  - update .custodian-brief.md for the-custodian
2026-04-21 06:34:52 +02:00
cc5d6e7daf chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-04-21:
  - update .custodian-brief.md for the-custodian
2026-04-21 06:20:20 +02:00
46ae3f3ed3 chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-04-21:
  - update .custodian-brief.md for the-custodian
2026-04-21 06:05:48 +02:00
a9710bc3bd chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-04-21:
  - update .custodian-brief.md for the-custodian
2026-04-21 05:51:17 +02:00
649c43d2b2 chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-04-21:
  - update .custodian-brief.md for the-custodian
2026-04-21 05:36:43 +02:00
a5e3234235 chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-04-21:
  - update .custodian-brief.md for the-custodian
2026-04-21 05:22:10 +02:00
166379f35c chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-04-21:
  - update .custodian-brief.md for the-custodian
2026-04-21 05:07:35 +02:00
3aaf14b4ec chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-04-21:
  - update .custodian-brief.md for the-custodian
2026-04-21 04:53:02 +02:00
dbccacd431 chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-04-21:
  - update .custodian-brief.md for the-custodian
2026-04-21 04:38:29 +02:00
08c1f1ae6c chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-04-21:
  - update .custodian-brief.md for the-custodian
2026-04-21 04:23:51 +02:00
12585704ff chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-04-21:
  - update .custodian-brief.md for the-custodian
2026-04-21 04:09:17 +02:00
7bb749c35c chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-04-21:
  - update .custodian-brief.md for the-custodian
2026-04-21 03:54:39 +02:00
d394a324a1 chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-04-21:
  - update .custodian-brief.md for the-custodian
2026-04-21 03:40:03 +02:00
c72d004b75 chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-04-21:
  - update .custodian-brief.md for the-custodian
2026-04-21 03:25:28 +02:00
c25ce87cf2 chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-04-21:
  - update .custodian-brief.md for the-custodian
2026-04-21 03:10:48 +02:00
453ec06ba1 chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-04-21:
  - update .custodian-brief.md for the-custodian
2026-04-21 02:56:08 +02:00
9ddced36b5 chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-04-21:
  - update .custodian-brief.md for the-custodian
2026-04-21 02:41:32 +02:00
6124b2ea78 chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-04-21:
  - update .custodian-brief.md for the-custodian
2026-04-21 02:27:31 +02:00
ba2addf924 chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-04-21:
  - update .custodian-brief.md for the-custodian
2026-04-21 02:13:28 +02:00
e410d44959 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
b64fadb810 chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-04-20:
  - update .custodian-brief.md for the-custodian
2026-04-20 15:24:14 +02:00
f09fbfd63f chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-04-20:
  - update .custodian-brief.md for the-custodian
2026-04-20 15:09:21 +02:00
95ba50e7be chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-04-20:
  - update .custodian-brief.md for the-custodian
2026-04-20 14:53:52 +02:00
281d5525eb chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-04-20:
  - update .custodian-brief.md for the-custodian
2026-04-20 14:38:50 +02:00
5f3e1f6c14 chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-04-20:
  - update .custodian-brief.md for the-custodian
2026-04-20 14:10:36 +02:00
9760b3396f chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-04-20:
  - update .custodian-brief.md for the-custodian
2026-04-20 13:55:49 +02:00
7d0ca3d201 chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-04-20:
  - update .custodian-brief.md for the-custodian
2026-04-20 13:40:56 +02:00
0adbea61e7 chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-04-20:
  - update .custodian-brief.md for the-custodian
2026-04-20 13:25:58 +02:00
5f3d288f15 chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-04-20:
  - update .custodian-brief.md for the-custodian
2026-04-20 13:10:53 +02:00
65d29c33b1 chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-04-20:
  - update .custodian-brief.md for the-custodian
2026-04-20 12:55:53 +02:00
e274238d92 chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-04-20:
  - update .custodian-brief.md for the-custodian
2026-04-20 12:40:23 +02:00
188442d650 chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-04-20:
  - update .custodian-brief.md for the-custodian
2026-04-20 12:25:16 +02:00
6a676d255b chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-04-20:
  - update .custodian-brief.md for the-custodian
2026-04-20 12:10:09 +02:00
339b03fe84 chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-04-20:
  - update .custodian-brief.md for the-custodian
2026-04-20 12:01:55 +02:00
9bc761c2b5 feat(railiance): implement CUST-WP-0032 Haskell build machine infra
Packer build definition, cloud-init autoinstall, GHCup toolchain script,
boot-time registration agent (state-hub + autossh dual tunnel), systemd
unit, key injection, remote-build Makefile, smoke test, and deployment
README. All 15 tasks complete.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-04-20 12:01:30 +02:00
67b990170d chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-04-20:
  - update .custodian-brief.md for the-custodian
2026-04-20 02:39:19 +02:00
42b98e99f5 chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-04-20:
  - update .custodian-brief.md for the-custodian
2026-04-20 02:23:22 +02:00
1fa946e6e5 chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-04-20:
  - update .custodian-brief.md for the-custodian
2026-04-20 02:07:17 +02:00
014a276c5c chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-04-20:
  - update .custodian-brief.md for the-custodian
2026-04-20 01:51:22 +02:00
1c2d15c091 chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-04-20:
  - update .custodian-brief.md for the-custodian
2026-04-20 01:35:17 +02:00
d26ebf924f chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-04-20:
  - update .custodian-brief.md for the-custodian
2026-04-20 01:19:22 +02:00
1eab9a5dc2 chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-04-20:
  - update .custodian-brief.md for the-custodian
2026-04-20 01:12:39 +02:00
155c267e37 chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-04-20:
  - update .custodian-brief.md for the-custodian
2026-04-20 01:05:58 +02:00
efe1387ede refine(CUST-WP-0032): incorporate all four architecture decisions
- Packer uses NAT during build; setup-vm.sh does post-import bridged config
- Bake GHC 9.8.4 (primary) + 9.6.6 (LTS coverage); drop Stack + HLS
- state-hub always via forward tunnel port 18000 (CoulombCore pattern)
- autossh opens -R (reverse SSH) + -L 18000 (state-hub forward) together
- Decisions section replaces Open Questions; all four resolved 2026-04-20

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-20 01:05:28 +02:00
62198b39a2 chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-04-20:
  - update .custodian-brief.md for the-custodian
2026-04-20 01:03:26 +02:00
32aa4f41f8 chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-04-20:
  - update .custodian-brief.md for the-custodian
2026-04-20 01:00:56 +02:00
f432b76613 feat(railiance): add CUST-WP-0032 Haskell build machine workplan
15-task plan across 5 phases: Packer VirtualBox image, boot-time
registration agent (POST /capability-catalog/), autossh SSH bridge
integration (ports 12221-12230), state-hub capability bootstrap,
and remote build Makefile workflow.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-20 01:00:26 +02:00
11708617fc chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-04-20:
  - update .custodian-brief.md for the-custodian
2026-04-20 01:00:01 +02:00
1b0da43c77 chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-04-20:
  - update .custodian-brief.md for the-custodian
2026-04-20 00:47:16 +02:00
8120159064 chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-04-20:
  - update .custodian-brief.md for the-custodian
2026-04-20 00:31:21 +02:00
232e6189ee chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-04-20:
  - update .custodian-brief.md for the-custodian
2026-04-20 00:15:40 +02:00
465226b84a chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-04-20:
  - update .custodian-brief.md for the-custodian
2026-04-20 00:05:08 +02:00
13734c404e Improved documentation of how to start everything 2026-04-20 00:04:46 +02:00
fd9b781398 chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-04-19:
  - update .custodian-brief.md for the-custodian
2026-04-19 23:59:16 +02:00
9700939f80 chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-04-19:
  - update .custodian-brief.md for the-custodian
2026-04-19 23:44:31 +02:00
38585e6f4f chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-04-19:
  - update .custodian-brief.md for the-custodian
2026-04-19 19:25:19 +02:00
24045a797f chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-04-19:
  - update .custodian-brief.md for the-custodian
2026-04-19 19:10:46 +02:00
07510d4a34 chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-04-19:
  - update .custodian-brief.md for the-custodian
2026-04-19 18:56:13 +02:00
fdc69d14b3 chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-04-19:
  - update .custodian-brief.md for the-custodian
2026-04-19 18:41:42 +02:00
95c5d668fa chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-04-19:
  - update .custodian-brief.md for the-custodian
2026-04-19 18:27:08 +02:00
cb6b387dff chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-04-19:
  - update .custodian-brief.md for the-custodian
2026-04-19 18:12:36 +02:00
697e122e09 chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-04-19:
  - update .custodian-brief.md for the-custodian
2026-04-19 17:58:03 +02:00
6d4490c759 chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-04-19:
  - update .custodian-brief.md for the-custodian
2026-04-19 17:43:32 +02:00
ecf68eb348 chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-04-19:
  - update .custodian-brief.md for the-custodian
2026-04-19 17:28:57 +02:00
6c512e44ca chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-04-19:
  - update .custodian-brief.md for the-custodian
2026-04-19 17:14:24 +02:00
89b927548c chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-04-19:
  - update .custodian-brief.md for the-custodian
2026-04-19 16:59:53 +02:00
6b97c51fea chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-04-19:
  - update .custodian-brief.md for the-custodian
2026-04-19 16:45:19 +02:00
9ca9becde5 chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-04-19:
  - update .custodian-brief.md for the-custodian
2026-04-19 16:30:40 +02:00
b6bed6d1d3 chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-04-19:
  - update .custodian-brief.md for the-custodian
2026-04-19 16:15:57 +02:00
f94f07dba0 chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-04-19:
  - update .custodian-brief.md for the-custodian
2026-04-19 16:01:10 +02:00
6fac3773cb chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-04-19:
  - update .custodian-brief.md for the-custodian
2026-04-19 15:46:28 +02:00
d1f8788df7 chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-04-19:
  - update .custodian-brief.md for the-custodian
2026-04-19 15:31:43 +02:00
c1184c422e chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-04-19:
  - update .custodian-brief.md for the-custodian
2026-04-19 15:17:22 +02:00
39a7d32b86 chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-04-19:
  - update .custodian-brief.md for the-custodian
2026-04-19 15:04:52 +02:00
7de25f9dff chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-04-15:
  - update .custodian-brief.md for the-custodian
2026-04-15 01:58:05 +02:00
28b12b2e6d chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-04-15:
  - update .custodian-brief.md for the-custodian
2026-04-15 01:43:31 +02:00
733ddff2a3 chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-04-15:
  - update .custodian-brief.md for the-custodian
2026-04-15 01:28:39 +02:00
95f5b7d12f chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-04-15:
  - update .custodian-brief.md for the-custodian
2026-04-15 01:13:47 +02:00
4f3f2028da chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-04-15:
  - update .custodian-brief.md for the-custodian
2026-04-15 00:58:58 +02:00
d2da3212a8 chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-04-15:
  - update .custodian-brief.md for the-custodian
2026-04-15 00:44:26 +02:00
b152e74c0f chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-04-15:
  - update .custodian-brief.md for the-custodian
2026-04-15 00:29:30 +02:00
91cb6765f2 chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-04-15:
  - update .custodian-brief.md for the-custodian
2026-04-15 00:14:39 +02:00
db91cc4a1a chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-04-14:
  - update .custodian-brief.md for the-custodian
2026-04-14 23:59:57 +02:00
352b067c28 chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-04-14:
  - update .custodian-brief.md for the-custodian
2026-04-14 23:45:08 +02:00
42c59e0cd0 chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-04-14:
  - update .custodian-brief.md for the-custodian
2026-04-14 23:30:22 +02:00
00d38730dd chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-04-14:
  - update .custodian-brief.md for the-custodian
2026-04-14 23:15:52 +02:00
d2a38f74ff chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-04-14:
  - update .custodian-brief.md for the-custodian
2026-04-14 23:00:49 +02:00
8b0f75f119 chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-04-14:
  - update .custodian-brief.md for the-custodian
2026-04-14 22:46:13 +02:00
cd82e0a5b7 chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-04-14:
  - update .custodian-brief.md for the-custodian
2026-04-14 22:31:19 +02:00
b49fa0cf03 chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-04-14:
  - update .custodian-brief.md for the-custodian
2026-04-14 22:16:46 +02:00
24bd7a0363 chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-04-13:
  - update .custodian-brief.md for the-custodian
2026-04-13 23:33:50 +02:00
81ea033585 chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-04-13:
  - update .custodian-brief.md for the-custodian
2026-04-13 23:19:13 +02:00
5a58631431 chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-04-13:
  - update .custodian-brief.md for the-custodian
2026-04-13 23:04:04 +02:00
89c3bd559b chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-04-13:
  - update .custodian-brief.md for the-custodian
2026-04-13 22:49:10 +02:00
cdbe251706 chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-04-13:
  - update .custodian-brief.md for the-custodian
2026-04-13 22:34:34 +02:00
0e621536e7 chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-04-13:
  - update .custodian-brief.md for the-custodian
2026-04-13 00:58:51 +02:00
df36bb074a chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-04-13:
  - update .custodian-brief.md for the-custodian
2026-04-13 00:44:18 +02:00
6674e70f31 chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-04-13:
  - update .custodian-brief.md for the-custodian
2026-04-13 00:29:45 +02:00
202ca2b40a chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-04-13:
  - update .custodian-brief.md for the-custodian
2026-04-13 00:15:14 +02:00
0ed45609de chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-04-13:
  - update .custodian-brief.md for the-custodian
2026-04-13 00:00:41 +02:00
049a126752 chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-04-12:
  - update .custodian-brief.md for the-custodian
2026-04-12 23:46:08 +02:00
7418a9c48e chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-04-12:
  - update .custodian-brief.md for the-custodian
2026-04-12 23:31:39 +02:00
18b285a351 chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-04-12:
  - update .custodian-brief.md for the-custodian
2026-04-12 23:17:09 +02:00
ae38373d88 chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-04-12:
  - update .custodian-brief.md for the-custodian
2026-04-12 23:02:32 +02:00
a16fe2c429 chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-04-12:
  - update .custodian-brief.md for the-custodian
2026-04-12 22:48:10 +02:00
ed3d366e62 chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-04-12:
  - update .custodian-brief.md for the-custodian
2026-04-12 22:33:35 +02:00
a2605986bf chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-04-12:
  - update .custodian-brief.md for the-custodian
2026-04-12 22:19:01 +02:00
b294359fe8 chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-04-12:
  - update .custodian-brief.md for the-custodian
2026-04-12 22:04:32 +02:00
0a7ff40128 chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-04-12:
  - update .custodian-brief.md for the-custodian
2026-04-12 21:49:56 +02:00
8eb27a230c chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-04-12:
  - update .custodian-brief.md for the-custodian
2026-04-12 21:35:29 +02:00
b74a936fc1 chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-04-12:
  - update .custodian-brief.md for the-custodian
2026-04-12 21:20:52 +02:00
2d984d23dd chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-04-12:
  - update .custodian-brief.md for the-custodian
2026-04-12 21:06:18 +02:00
fcc5e54dd5 chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-04-12:
  - update .custodian-brief.md for the-custodian
2026-04-12 20:51:45 +02:00
05309e43bb chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-04-12:
  - update .custodian-brief.md for the-custodian
2026-04-12 20:37:04 +02:00
8a1ea967e3 chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-04-12:
  - update .custodian-brief.md for the-custodian
2026-04-12 20:22:32 +02:00
26e96f013d chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-04-12:
  - update .custodian-brief.md for the-custodian
2026-04-12 20:08:17 +02:00
01d48761f0 chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-04-12:
  - update .custodian-brief.md for the-custodian
2026-04-12 19:53:34 +02:00
1b03f201bd chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-04-12:
  - update .custodian-brief.md for the-custodian
2026-04-12 19:38:56 +02:00
af1aca79ac chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-04-12:
  - update .custodian-brief.md for the-custodian
2026-04-12 19:24:29 +02:00
66e82c0bf9 chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-04-12:
  - update .custodian-brief.md for the-custodian
2026-04-12 19:10:43 +02:00
0289e35008 chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-04-12:
  - update .custodian-brief.md for the-custodian
2026-04-12 18:55:19 +02:00
f7db255402 chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-04-12:
  - update .custodian-brief.md for the-custodian
2026-04-12 18:40:42 +02:00
9a3036e8b2 chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-04-12:
  - update .custodian-brief.md for the-custodian
2026-04-12 18:26:09 +02:00
c54098d73c chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-04-12:
  - update .custodian-brief.md for the-custodian
2026-04-12 18:11:36 +02:00
67940b0ce0 chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-04-12:
  - update .custodian-brief.md for the-custodian
2026-04-12 17:57:03 +02:00
54e8ffa024 chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-04-12:
  - update .custodian-brief.md for the-custodian
2026-04-12 17:42:32 +02:00
8d30280fdc chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-04-12:
  - update .custodian-brief.md for the-custodian
2026-04-12 17:27:57 +02:00
aeec2facd1 chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-04-12:
  - update .custodian-brief.md for the-custodian
2026-04-12 17:13:27 +02:00
e193ea5c09 chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-04-12:
  - update .custodian-brief.md for the-custodian
2026-04-12 16:59:49 +02:00
9e6eb3afd4 chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-04-12:
  - update .custodian-brief.md for the-custodian
2026-04-12 16:45:16 +02:00
6dcbe453a0 chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-04-12:
  - update .custodian-brief.md for the-custodian
2026-04-12 16:29:53 +02:00
9becfb2629 chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-04-12:
  - update .custodian-brief.md for the-custodian
2026-04-12 16:15:22 +02:00
21f616d0d1 chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-04-12:
  - update .custodian-brief.md for the-custodian
2026-04-12 16:00:47 +02:00
14ee4d8d09 chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-04-12:
  - update .custodian-brief.md for the-custodian
2026-04-12 15:46:13 +02:00
10a0e9770e chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-04-12:
  - update .custodian-brief.md for the-custodian
2026-04-12 15:31:42 +02:00
abd4f1da6d chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-04-12:
  - update .custodian-brief.md for the-custodian
2026-04-12 15:17:09 +02:00
0fc73a7100 chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-04-12:
  - update .custodian-brief.md for the-custodian
2026-04-12 15:02:45 +02:00
2025314ded chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-04-12:
  - update .custodian-brief.md for the-custodian
2026-04-12 14:48:04 +02:00
55beb9b4ff chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-04-12:
  - update .custodian-brief.md for the-custodian
2026-04-12 14:33:36 +02:00
411907ed4e chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-04-12:
  - update .custodian-brief.md for the-custodian
2026-04-12 14:18:59 +02:00
983615b75d chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-04-12:
  - update .custodian-brief.md for the-custodian
2026-04-12 14:04:24 +02:00
f95a75bede chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-04-12:
  - update .custodian-brief.md for the-custodian
2026-04-12 13:49:52 +02:00
f9e6db274e chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-04-12:
  - update .custodian-brief.md for the-custodian
2026-04-12 13:35:47 +02:00
3d64cd95d3 chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-04-12:
  - update .custodian-brief.md for the-custodian
2026-04-12 13:21:05 +02:00
9815b179a2 chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-04-12:
  - update .custodian-brief.md for the-custodian
2026-04-12 13:06:31 +02:00
66fb48c4d5 chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-04-12:
  - update .custodian-brief.md for the-custodian
2026-04-12 12:52:01 +02:00
b5b04f606c chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-04-12:
  - update .custodian-brief.md for the-custodian
2026-04-12 12:37:32 +02:00
445efec6f5 chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-04-12:
  - update .custodian-brief.md for the-custodian
2026-04-12 12:22:55 +02:00
dd2c2b3e7b chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-04-12:
  - update .custodian-brief.md for the-custodian
2026-04-12 12:08:27 +02:00
dec9b44161 chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-04-12:
  - update .custodian-brief.md for the-custodian
2026-04-12 11:53:50 +02:00
c1cc881f3a chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-04-12:
  - update .custodian-brief.md for the-custodian
2026-04-12 11:38:57 +02:00
858a892de3 chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-04-12:
  - update .custodian-brief.md for the-custodian
2026-04-12 11:24:24 +02:00
9268f0e284 chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-04-12:
  - update .custodian-brief.md for the-custodian
2026-04-12 11:09:50 +02:00
95d3496fbe chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-04-12:
  - update .custodian-brief.md for the-custodian
2026-04-12 10:55:20 +02:00
93cc021922 chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-04-12:
  - update .custodian-brief.md for the-custodian
2026-04-12 10:40:46 +02:00
78dad43321 chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-04-12:
  - update .custodian-brief.md for the-custodian
2026-04-12 10:26:11 +02:00
c04edf9b00 chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-04-12:
  - update .custodian-brief.md for the-custodian
2026-04-12 10:11:40 +02:00
cf2abdaff2 chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-04-12:
  - update .custodian-brief.md for the-custodian
2026-04-12 09:57:08 +02:00
82b282c01e chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-04-12:
  - update .custodian-brief.md for the-custodian
2026-04-12 09:42:37 +02:00
f3122280ec chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-04-12:
  - update .custodian-brief.md for the-custodian
2026-04-12 09:28:00 +02:00
54599d9a2c chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-04-12:
  - update .custodian-brief.md for the-custodian
2026-04-12 09:13:28 +02:00
527e049f01 chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-04-12:
  - update .custodian-brief.md for the-custodian
2026-04-12 08:58:57 +02:00
c5252d2ea0 chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-04-12:
  - update .custodian-brief.md for the-custodian
2026-04-12 08:44:28 +02:00
e87de516b8 chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-04-12:
  - update .custodian-brief.md for the-custodian
2026-04-12 08:29:50 +02:00
47aac24f13 chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-04-12:
  - update .custodian-brief.md for the-custodian
2026-04-12 08:15:19 +02:00
fbc8a2397a chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-04-12:
  - update .custodian-brief.md for the-custodian
2026-04-12 08:00:47 +02:00
672a5c7a3c chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-04-12:
  - update .custodian-brief.md for the-custodian
2026-04-12 07:46:12 +02:00
a8cc50d934 chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-04-12:
  - update .custodian-brief.md for the-custodian
2026-04-12 07:31:41 +02:00
7f28c7855b chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-04-12:
  - update .custodian-brief.md for the-custodian
2026-04-12 07:17:09 +02:00
906a2f4d46 chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-04-12:
  - update .custodian-brief.md for the-custodian
2026-04-12 07:02:36 +02:00
af213f4cc7 chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-04-12:
  - update .custodian-brief.md for the-custodian
2026-04-12 06:48:00 +02:00
ffd4a476a5 chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-04-12:
  - update .custodian-brief.md for the-custodian
2026-04-12 06:33:30 +02:00
d794d367d5 chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-04-12:
  - update .custodian-brief.md for the-custodian
2026-04-12 06:18:56 +02:00
cc815309eb chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-04-12:
  - update .custodian-brief.md for the-custodian
2026-04-12 06:04:25 +02:00
21392bbcaf chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-04-12:
  - update .custodian-brief.md for the-custodian
2026-04-12 05:49:50 +02:00
3f307860aa chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-04-12:
  - update .custodian-brief.md for the-custodian
2026-04-12 05:35:19 +02:00
16c09134dc chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-04-12:
  - update .custodian-brief.md for the-custodian
2026-04-12 05:20:46 +02:00
618e267c37 chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-04-12:
  - update .custodian-brief.md for the-custodian
2026-04-12 05:06:14 +02:00
6ffd9b3fa3 chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-04-12:
  - update .custodian-brief.md for the-custodian
2026-04-12 04:51:41 +02:00
22fc3cae4d chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-04-12:
  - update .custodian-brief.md for the-custodian
2026-04-12 04:37:07 +02:00
dba61283e3 chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-04-12:
  - update .custodian-brief.md for the-custodian
2026-04-12 04:22:34 +02:00
912897ac34 chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-04-12:
  - update .custodian-brief.md for the-custodian
2026-04-12 04:08:04 +02:00
48bc431271 chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-04-12:
  - update .custodian-brief.md for the-custodian
2026-04-12 03:54:05 +02:00
052bf6f378 chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-04-12:
  - update .custodian-brief.md for the-custodian
2026-04-12 03:39:20 +02:00
752ca495b3 chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-04-12:
  - update .custodian-brief.md for the-custodian
2026-04-12 03:24:53 +02:00
c0d6a65493 chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-04-12:
  - update .custodian-brief.md for the-custodian
2026-04-12 03:10:17 +02:00
a333a905bb chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-04-12:
  - update .custodian-brief.md for the-custodian
2026-04-12 02:55:48 +02:00
e6e7eb248c chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-04-12:
  - update .custodian-brief.md for the-custodian
2026-04-12 02:41:09 +02:00
7286341a76 chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-04-12:
  - update .custodian-brief.md for the-custodian
2026-04-12 02:26:50 +02:00
82eaefb6e6 chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-04-12:
  - update .custodian-brief.md for the-custodian
2026-04-12 02:12:21 +02:00
c39413bd4b chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-04-12:
  - update .custodian-brief.md for the-custodian
2026-04-12 01:57:49 +02:00
2a101c526c chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-04-12:
  - update .custodian-brief.md for the-custodian
2026-04-12 01:43:14 +02:00
255bdfed43 chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-04-12:
  - update .custodian-brief.md for the-custodian
2026-04-12 01:28:03 +02:00
48b76f6a48 chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-04-12:
  - update .custodian-brief.md for the-custodian
2026-04-12 01:13:33 +02:00
8dec35f48a chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-04-12:
  - update .custodian-brief.md for the-custodian
2026-04-12 00:58:57 +02:00
c3b86c7cb1 chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-04-12:
  - update .custodian-brief.md for the-custodian
2026-04-12 00:44:26 +02:00
c6848c7451 chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-04-12:
  - update .custodian-brief.md for the-custodian
2026-04-12 00:29:53 +02:00
a6c0ec82ac chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-04-12:
  - update .custodian-brief.md for the-custodian
2026-04-12 00:15:21 +02:00
89ec5e7198 chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-04-12:
  - update .custodian-brief.md for the-custodian
2026-04-12 00:00:47 +02:00
f385d5541b chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-04-11:
  - update .custodian-brief.md for the-custodian
2026-04-11 23:46:14 +02:00
f987447f4d chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-04-11:
  - update .custodian-brief.md for the-custodian
2026-04-11 23:31:45 +02:00
d176eadc6f chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-04-11:
  - update .custodian-brief.md for the-custodian
2026-04-11 23:17:15 +02:00
ce4a673414 chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-04-11:
  - update .custodian-brief.md for the-custodian
2026-04-11 23:02:35 +02:00
b52041542d chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-04-11:
  - update .custodian-brief.md for the-custodian
2026-04-11 22:48:02 +02:00
80b7978e3d chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-04-11:
  - update .custodian-brief.md for the-custodian
2026-04-11 22:33:32 +02:00
aab9491248 chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-04-11:
  - update .custodian-brief.md for the-custodian
2026-04-11 22:18:59 +02:00
7f302326d3 chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-04-11:
  - update .custodian-brief.md for the-custodian
2026-04-11 22:04:26 +02:00
022e88abc8 chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-04-11:
  - update .custodian-brief.md for the-custodian
2026-04-11 21:49:54 +02:00
6560f71c80 chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-04-11:
  - update .custodian-brief.md for the-custodian
2026-04-11 21:35:20 +02:00
be8917eaa7 chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-04-11:
  - update .custodian-brief.md for the-custodian
2026-04-11 21:20:46 +02:00
27959c2a76 chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-04-11:
  - update .custodian-brief.md for the-custodian
2026-04-11 21:06:16 +02:00
ab05683c1f chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-04-11:
  - update .custodian-brief.md for the-custodian
2026-04-11 20:51:41 +02:00
ab74e73819 chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-04-11:
  - update .custodian-brief.md for the-custodian
2026-04-11 20:37:11 +02:00
d75b69af91 chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-04-11:
  - update .custodian-brief.md for the-custodian
2026-04-11 20:22:36 +02:00
eb7bbd1b6e chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-04-11:
  - update .custodian-brief.md for the-custodian
2026-04-11 20:08:03 +02:00
ef710adb59 chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-04-11:
  - update .custodian-brief.md for the-custodian
2026-04-11 19:53:33 +02:00
0c85999f41 chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-04-11:
  - update .custodian-brief.md for the-custodian
2026-04-11 19:38:59 +02:00
128e28cbc8 chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-04-11:
  - update .custodian-brief.md for the-custodian
2026-04-11 19:24:25 +02:00
997f84a907 chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-04-11:
  - update .custodian-brief.md for the-custodian
2026-04-11 19:10:02 +02:00
9417b9971e chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-04-11:
  - update .custodian-brief.md for the-custodian
2026-04-11 18:55:19 +02:00
eb6bc76910 chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-04-11:
  - update .custodian-brief.md for the-custodian
2026-04-11 18:40:47 +02:00
c6bf4b5ded chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-04-11:
  - update .custodian-brief.md for the-custodian
2026-04-11 18:26:17 +02:00
c2f60d0a97 chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-04-11:
  - update .custodian-brief.md for the-custodian
2026-04-11 18:11:40 +02:00
67947a6dba chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-04-11:
  - update .custodian-brief.md for the-custodian
2026-04-11 17:57:12 +02:00
c69d38f187 chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-04-11:
  - update .custodian-brief.md for the-custodian
2026-04-11 17:42:37 +02:00
1e407858a8 chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-04-11:
  - update .custodian-brief.md for the-custodian
2026-04-11 17:28:05 +02:00
6125478b96 chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-04-11:
  - update .custodian-brief.md for the-custodian
2026-04-11 17:13:30 +02:00
7c2f37d0a4 chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-04-11:
  - update .custodian-brief.md for the-custodian
2026-04-11 16:59:00 +02:00
20b1aa20c2 chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-04-11:
  - update .custodian-brief.md for the-custodian
2026-04-11 16:44:26 +02:00
8bc3d92cb4 chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-04-11:
  - update .custodian-brief.md for the-custodian
2026-04-11 16:29:59 +02:00
e34c14ade4 chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-04-11:
  - update .custodian-brief.md for the-custodian
2026-04-11 16:15:27 +02:00
1cddc259c0 chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-04-11:
  - update .custodian-brief.md for the-custodian
2026-04-11 16:00:55 +02:00
ea20623c1e chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-04-11:
  - update .custodian-brief.md for the-custodian
2026-04-11 15:46:21 +02:00
89244ea068 chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-04-11:
  - update .custodian-brief.md for the-custodian
2026-04-11 15:31:52 +02:00
33a668f75a chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-04-11:
  - update .custodian-brief.md for the-custodian
2026-04-11 14:57:07 +02:00
d20fe8d7d4 chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-04-11:
  - update .custodian-brief.md for the-custodian
2026-04-11 14:42:15 +02:00
f1040ca2b9 chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-04-11:
  - update .custodian-brief.md for the-custodian
2026-04-11 14:28:40 +02:00
bcf531b8a8 chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-04-11:
  - update .custodian-brief.md for the-custodian
2026-04-11 11:09:44 +02:00
29e8c464e3 chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-04-11:
  - update .custodian-brief.md for the-custodian
2026-04-11 10:55:12 +02:00
bbe3009dfa chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-04-11:
  - update .custodian-brief.md for the-custodian
2026-04-11 10:40:39 +02:00
c21999fb72 chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-04-11:
  - update .custodian-brief.md for the-custodian
2026-04-11 10:26:07 +02:00
03a73917a1 chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-04-11:
  - update .custodian-brief.md for the-custodian
2026-04-11 10:11:33 +02:00
bd0e30cec7 chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-04-11:
  - update .custodian-brief.md for the-custodian
2026-04-11 09:56:59 +02:00
0d98907749 chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-04-11:
  - update .custodian-brief.md for the-custodian
2026-04-11 09:42:29 +02:00
ce46b4e2aa chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-04-11:
  - update .custodian-brief.md for the-custodian
2026-04-11 09:27:54 +02:00
86922e22c9 chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-04-11:
  - update .custodian-brief.md for the-custodian
2026-04-11 09:13:22 +02:00
e4a3e0d2b8 chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-04-11:
  - update .custodian-brief.md for the-custodian
2026-04-11 08:58:50 +02:00
5f1d7a614d chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-04-11:
  - update .custodian-brief.md for the-custodian
2026-04-11 08:44:17 +02:00
d3f5cd799a chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-04-11:
  - update .custodian-brief.md for the-custodian
2026-04-11 08:29:43 +02:00
725d93d43e chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-04-11:
  - update .custodian-brief.md for the-custodian
2026-04-11 08:15:12 +02:00
be1cf2a2cb chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-04-11:
  - update .custodian-brief.md for the-custodian
2026-04-11 08:00:38 +02:00
e27d1c2537 chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-04-11:
  - update .custodian-brief.md for the-custodian
2026-04-11 07:46:06 +02:00
217c0f1037 chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-04-11:
  - update .custodian-brief.md for the-custodian
2026-04-11 07:31:35 +02:00
da0cfdd92a chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-04-11:
  - update .custodian-brief.md for the-custodian
2026-04-11 07:17:01 +02:00
269b35ce34 chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-04-11:
  - update .custodian-brief.md for the-custodian
2026-04-11 07:02:28 +02:00
7b9128b0a1 chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-04-11:
  - update .custodian-brief.md for the-custodian
2026-04-11 06:47:56 +02:00
72fccd493a chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-04-11:
  - update .custodian-brief.md for the-custodian
2026-04-11 06:33:21 +02:00
55208bfc79 chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-04-11:
  - update .custodian-brief.md for the-custodian
2026-04-11 06:18:49 +02:00
ccb03ec59a chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-04-11:
  - update .custodian-brief.md for the-custodian
2026-04-11 06:04:17 +02:00
3bddbc1d97 chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-04-11:
  - update .custodian-brief.md for the-custodian
2026-04-11 05:49:44 +02:00
cdfbce7ac0 chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-04-11:
  - update .custodian-brief.md for the-custodian
2026-04-11 05:35:11 +02:00
7c65037703 chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-04-11:
  - update .custodian-brief.md for the-custodian
2026-04-11 05:20:39 +02:00
476d776e9b chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-04-11:
  - update .custodian-brief.md for the-custodian
2026-04-11 05:06:07 +02:00
c7009ebc23 chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-04-11:
  - update .custodian-brief.md for the-custodian
2026-04-11 04:51:33 +02:00
a95e780482 chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-04-11:
  - update .custodian-brief.md for the-custodian
2026-04-11 04:37:00 +02:00
b87afd853f chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-04-11:
  - update .custodian-brief.md for the-custodian
2026-04-11 04:22:28 +02:00
e3e58ecf6d chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-04-11:
  - update .custodian-brief.md for the-custodian
2026-04-11 04:07:56 +02:00
effb40d35e chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-04-11:
  - update .custodian-brief.md for the-custodian
2026-04-11 03:53:23 +02:00
21f9a31468 chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-04-11:
  - update .custodian-brief.md for the-custodian
2026-04-11 03:38:52 +02:00
22fe886b2a chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-04-11:
  - update .custodian-brief.md for the-custodian
2026-04-11 03:24:20 +02:00
013f866e6d chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-04-11:
  - update .custodian-brief.md for the-custodian
2026-04-11 03:10:25 +02:00
2ee7b70f30 chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-04-11:
  - update .custodian-brief.md for the-custodian
2026-04-11 02:55:33 +02:00
c8e9548105 chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-04-11:
  - update .custodian-brief.md for the-custodian
2026-04-11 02:41:05 +02:00
b470396c7d chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-04-11:
  - update .custodian-brief.md for the-custodian
2026-04-11 02:26:36 +02:00
d66b127933 chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-04-11:
  - update .custodian-brief.md for the-custodian
2026-04-11 02:11:56 +02:00
cd4a4b3275 chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-04-11:
  - update .custodian-brief.md for the-custodian
2026-04-11 01:57:32 +02:00
a6b13b826d chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-04-11:
  - update .custodian-brief.md for the-custodian
2026-04-11 01:43:15 +02:00
3e3f198063 chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-04-11:
  - update .custodian-brief.md for the-custodian
2026-04-11 01:28:18 +02:00
cf83ee940f chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-04-11:
  - update .custodian-brief.md for the-custodian
2026-04-11 01:14:00 +02:00
78df76694f chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-04-11:
  - update .custodian-brief.md for the-custodian
2026-04-11 00:59:22 +02:00
3110b78655 chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-04-11:
  - update .custodian-brief.md for the-custodian
2026-04-11 00:44:38 +02:00
215b97e1d7 chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-04-11:
  - update .custodian-brief.md for the-custodian
2026-04-11 00:29:45 +02:00
28f8e9f877 chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-04-11:
  - update .custodian-brief.md for the-custodian
2026-04-11 00:15:12 +02:00
332367f5ef chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-04-11:
  - update .custodian-brief.md for the-custodian
2026-04-11 00:00:40 +02:00
92e92d8ef5 chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-04-10:
  - update .custodian-brief.md for the-custodian
2026-04-10 23:46:08 +02:00
767a25538d chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-04-10:
  - update .custodian-brief.md for the-custodian
2026-04-10 23:31:37 +02:00
afef45c922 chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-04-10:
  - update .custodian-brief.md for the-custodian
2026-04-10 23:17:14 +02:00
8e0d099575 chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-04-10:
  - update .custodian-brief.md for the-custodian
2026-04-10 23:02:39 +02:00
c9a5020dc4 chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-04-10:
  - update .custodian-brief.md for the-custodian
2026-04-10 22:47:55 +02:00
f5480e10b0 chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-04-10:
  - update .custodian-brief.md for the-custodian
2026-04-10 22:33:23 +02:00
7ec5f1f775 chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-04-10:
  - update .custodian-brief.md for the-custodian
2026-04-10 22:18:50 +02:00
364650e732 chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-04-10:
  - update .custodian-brief.md for the-custodian
2026-04-10 22:04:20 +02:00
94a6dc7d1a chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-04-10:
  - update .custodian-brief.md for the-custodian
2026-04-10 21:49:52 +02:00
bd939e0f11 chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-04-10:
  - update .custodian-brief.md for the-custodian
2026-04-10 21:35:12 +02:00
4226c6bd2f chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-04-10:
  - update .custodian-brief.md for the-custodian
2026-04-10 21:21:06 +02:00
a429f29c13 chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-04-10:
  - update .custodian-brief.md for the-custodian
2026-04-10 21:06:29 +02:00
7ab33f047f chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-04-10:
  - update .custodian-brief.md for the-custodian
2026-04-10 20:51:55 +02:00
bc230d0a53 chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-04-10:
  - update .custodian-brief.md for the-custodian
2026-04-10 20:37:25 +02:00
bf6150a798 chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-04-10:
  - update .custodian-brief.md for the-custodian
2026-04-10 20:22:50 +02:00
705001064f chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-04-10:
  - update .custodian-brief.md for the-custodian
2026-04-10 20:08:21 +02:00
cfa43e5dbd chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-04-10:
  - update .custodian-brief.md for the-custodian
2026-04-10 19:53:52 +02:00
44c7e04c1e chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-04-10:
  - update .custodian-brief.md for the-custodian
2026-04-10 19:39:18 +02:00
e4ff3dd0bf chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-04-10:
  - update .custodian-brief.md for the-custodian
2026-04-10 19:24:49 +02:00
083d3b4bb8 chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-04-10:
  - update .custodian-brief.md for the-custodian
2026-04-10 19:10:09 +02:00
5b54d80537 chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-04-10:
  - update .custodian-brief.md for the-custodian
2026-04-10 18:55:39 +02:00
8a5b8d3c38 chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-04-10:
  - update .custodian-brief.md for the-custodian
2026-04-10 18:40:40 +02:00
b63a788984 chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-04-10:
  - update .custodian-brief.md for the-custodian
2026-04-10 18:26:07 +02:00
de31df35f5 chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-04-10:
  - update .custodian-brief.md for the-custodian
2026-04-10 18:11:36 +02:00
da0abbe48a chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-04-10:
  - update .custodian-brief.md for the-custodian
2026-04-10 17:57:02 +02:00
751936cb19 chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-04-10:
  - update .custodian-brief.md for the-custodian
2026-04-10 17:42:30 +02:00
ec65887a7f chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-04-10:
  - update .custodian-brief.md for the-custodian
2026-04-10 17:27:58 +02:00
bfda80db2a chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-04-10:
  - update .custodian-brief.md for the-custodian
2026-04-10 17:13:25 +02:00
5048042f56 chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-04-10:
  - update .custodian-brief.md for the-custodian
2026-04-10 16:58:52 +02:00
23528cabe7 chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-04-10:
  - update .custodian-brief.md for the-custodian
2026-04-10 16:44:20 +02:00
244415186e chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-04-10:
  - update .custodian-brief.md for the-custodian
2026-04-10 16:29:49 +02:00
387420f594 chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-04-10:
  - update .custodian-brief.md for the-custodian
2026-04-10 16:15:13 +02:00
19f5b48973 chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-04-10:
  - update .custodian-brief.md for the-custodian
2026-04-10 16:00:42 +02:00
e03079f68b chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-04-10:
  - update .custodian-brief.md for the-custodian
2026-04-10 15:46:14 +02:00
f7c1dfe0a3 chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-04-10:
  - update .custodian-brief.md for the-custodian
2026-04-10 15:32:12 +02:00
1d7a1b266c chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-04-10:
  - update .custodian-brief.md for the-custodian
2026-04-10 15:19:30 +02:00
2c08293e31 chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-04-10:
  - update .custodian-brief.md for the-custodian
2026-04-10 15:03:18 +02:00
1b0d422e12 chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-04-10:
  - update .custodian-brief.md for the-custodian
2026-04-10 14:47:57 +02:00
edc814a1fc chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-04-10:
  - update .custodian-brief.md for the-custodian
2026-04-10 14:33:23 +02:00
ce750e6325 chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-04-10:
  - update .custodian-brief.md for the-custodian
2026-04-10 14:18:52 +02:00
ce2434b9a1 chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-04-10:
  - update .custodian-brief.md for the-custodian
2026-04-10 14:04:20 +02:00
e51e8bcae1 chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-04-10:
  - update .custodian-brief.md for the-custodian
2026-04-10 13:49:57 +02:00
6cd6cdc3ec chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-04-10:
  - update .custodian-brief.md for the-custodian
2026-04-10 13:35:16 +02:00
f8cc8bde5b chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-04-10:
  - update .custodian-brief.md for the-custodian
2026-04-10 13:20:48 +02:00
ea04b52e5c chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-04-10:
  - update .custodian-brief.md for the-custodian
2026-04-10 13:06:13 +02:00
00b32954b1 chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-04-10:
  - update .custodian-brief.md for the-custodian
2026-04-10 12:51:40 +02:00
f4caaeeda5 chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-04-10:
  - update .custodian-brief.md for the-custodian
2026-04-10 12:37:07 +02:00
46afb4a95e chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-04-10:
  - update .custodian-brief.md for the-custodian
2026-04-10 12:22:35 +02:00
8a13ed99d3 chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-04-10:
  - update .custodian-brief.md for the-custodian
2026-04-10 12:08:03 +02:00
9bc5755f88 chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-04-10:
  - update .custodian-brief.md for the-custodian
2026-04-10 11:53:31 +02:00
4d221ae69b chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-04-10:
  - update .custodian-brief.md for the-custodian
2026-04-10 11:39:05 +02:00
e3e82ba759 chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-04-10:
  - update .custodian-brief.md for the-custodian
2026-04-10 11:24:26 +02:00
2ee4760a54 chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-04-10:
  - update .custodian-brief.md for the-custodian
2026-04-10 11:09:52 +02:00
3f339c7fbe chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-04-10:
  - update .custodian-brief.md for the-custodian
2026-04-10 10:55:18 +02:00
4aeb4d80f3 chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-04-10:
  - update .custodian-brief.md for the-custodian
2026-04-10 10:40:42 +02:00
d4f820dee2 chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-04-10:
  - update .custodian-brief.md for the-custodian
2026-04-10 10:25:30 +02:00
d8b577d8fb chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-04-10:
  - update .custodian-brief.md for the-custodian
2026-04-10 10:10:58 +02:00
3155be2880 chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-04-10:
  - update .custodian-brief.md for the-custodian
2026-04-10 09:56:26 +02:00
aa3b12a069 chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-04-10:
  - update .custodian-brief.md for the-custodian
2026-04-10 09:41:52 +02:00
dad733c989 chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-04-10:
  - update .custodian-brief.md for the-custodian
2026-04-10 09:27:18 +02:00
0ae472b076 chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-04-10:
  - update .custodian-brief.md for the-custodian
2026-04-10 09:12:46 +02:00
dfac400cec chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-04-10:
  - update .custodian-brief.md for the-custodian
2026-04-10 08:58:13 +02:00
aec46955c4 chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-04-10:
  - update .custodian-brief.md for the-custodian
2026-04-10 08:43:40 +02:00
20dfa6ad59 chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-04-10:
  - update .custodian-brief.md for the-custodian
2026-04-10 08:29:08 +02:00
e185dfe0ab chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-04-10:
  - update .custodian-brief.md for the-custodian
2026-04-10 08:14:35 +02:00
32c04b400e chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-04-10:
  - update .custodian-brief.md for the-custodian
2026-04-10 08:00:02 +02:00
f8350b829b chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-04-10:
  - update .custodian-brief.md for the-custodian
2026-04-10 07:45:30 +02:00
a556e3cdad chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-04-10:
  - update .custodian-brief.md for the-custodian
2026-04-10 07:30:53 +02:00
87daaf23a6 chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-04-10:
  - update .custodian-brief.md for the-custodian
2026-04-10 07:16:06 +02:00
d59470615d chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-04-10:
  - update .custodian-brief.md for the-custodian
2026-04-10 07:01:20 +02:00
edd7101fe9 chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-04-10:
  - update .custodian-brief.md for the-custodian
2026-04-10 06:46:33 +02:00
3bbb630e6e chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-04-10:
  - update .custodian-brief.md for the-custodian
2026-04-10 06:31:50 +02:00
d0604ebef4 chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-04-10:
  - update .custodian-brief.md for the-custodian
2026-04-10 06:17:02 +02:00
fe7247f440 chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-04-10:
  - update .custodian-brief.md for the-custodian
2026-04-10 06:02:09 +02:00
ec36b28795 chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-04-10:
  - update .custodian-brief.md for the-custodian
2026-04-10 05:47:23 +02:00
eb3d3543c8 chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-04-10:
  - update .custodian-brief.md for the-custodian
2026-04-10 05:32:36 +02:00
13f577eb70 chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-04-10:
  - update .custodian-brief.md for the-custodian
2026-04-10 05:17:53 +02:00
a0d331cba0 chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-04-10:
  - update .custodian-brief.md for the-custodian
2026-04-10 05:03:07 +02:00
c2465f5b99 chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-04-10:
  - update .custodian-brief.md for the-custodian
2026-04-10 04:48:19 +02:00
5924aac3e9 chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-04-10:
  - update .custodian-brief.md for the-custodian
2026-04-10 04:33:32 +02:00
a8dd5ebddd chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-04-10:
  - update .custodian-brief.md for the-custodian
2026-04-10 04:18:47 +02:00
1a1c60e0b5 chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-04-10:
  - update .custodian-brief.md for the-custodian
2026-04-10 04:04:01 +02:00
d8a2757c80 chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-04-10:
  - update .custodian-brief.md for the-custodian
2026-04-10 03:49:33 +02:00
433dcf2c54 chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-04-10:
  - update .custodian-brief.md for the-custodian
2026-04-10 03:34:50 +02:00
6b0036ea4c chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-04-10:
  - update .custodian-brief.md for the-custodian
2026-04-10 03:20:06 +02:00
af651a60ce chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-04-10:
  - update .custodian-brief.md for the-custodian
2026-04-10 03:05:19 +02:00
3ef3e31489 chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-04-10:
  - update .custodian-brief.md for the-custodian
2026-04-10 02:50:31 +02:00
5cf647e8af chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-04-10:
  - update .custodian-brief.md for the-custodian
2026-04-10 02:35:52 +02:00
8360591822 chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-04-10:
  - update .custodian-brief.md for the-custodian
2026-04-10 02:20:56 +02:00
2ec1dee035 chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-04-10:
  - update .custodian-brief.md for the-custodian
2026-04-10 02:06:13 +02:00
1a2dcfc189 chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-04-10:
  - update .custodian-brief.md for the-custodian
2026-04-10 01:51:28 +02:00
5e6e92d0c4 chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-04-10:
  - update .custodian-brief.md for the-custodian
2026-04-10 01:36:41 +02:00
3cc54f437a chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-04-10:
  - update .custodian-brief.md for the-custodian
2026-04-10 01:21:54 +02:00
3b25bbd806 chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-04-10:
  - update .custodian-brief.md for the-custodian
2026-04-10 01:07:10 +02:00
7c997f4f77 chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-04-10:
  - update .custodian-brief.md for the-custodian
2026-04-10 00:52:07 +02:00
486865963c chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-04-10:
  - update .custodian-brief.md for the-custodian
2026-04-10 00:37:16 +02:00
43f9266557 chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-04-10:
  - update .custodian-brief.md for the-custodian
2026-04-10 00:22:28 +02:00
076cbacb23 chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-04-10:
  - update .custodian-brief.md for the-custodian
2026-04-10 00:07:42 +02:00
074d081e99 chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-04-09:
  - update .custodian-brief.md for the-custodian
2026-04-09 23:52:57 +02:00
9e32fa026b chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-04-09:
  - update .custodian-brief.md for the-custodian
2026-04-09 23:38:12 +02:00
ea42394c25 chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-04-09:
  - update .custodian-brief.md for the-custodian
2026-04-09 23:23:22 +02:00
34ebfc95a0 chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-04-09:
  - update .custodian-brief.md for the-custodian
2026-04-09 23:08:38 +02:00
bcfb067a56 chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-04-09:
  - update .custodian-brief.md for the-custodian
2026-04-09 22:53:51 +02:00
a9f0ef1efa chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-04-09:
  - update .custodian-brief.md for the-custodian
2026-04-09 22:39:08 +02:00
3b6f095d92 chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-04-09:
  - update .custodian-brief.md for the-custodian
2026-04-09 22:24:18 +02:00
30e50634ad chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-04-09:
  - update .custodian-brief.md for the-custodian
2026-04-09 22:09:33 +02:00
f090993923 chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-04-09:
  - update .custodian-brief.md for the-custodian
2026-04-09 21:54:49 +02:00
5dc9b95264 chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-04-09:
  - update .custodian-brief.md for the-custodian
2026-04-09 21:40:02 +02:00
1898aafd0e chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-04-09:
  - update .custodian-brief.md for the-custodian
2026-04-09 21:25:16 +02:00
61d2fbc56d chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-04-09:
  - update .custodian-brief.md for the-custodian
2026-04-09 21:10:29 +02:00
241b6fa4f9 chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-04-09:
  - update .custodian-brief.md for the-custodian
2026-04-09 20:55:45 +02:00
3e292747d4 chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-04-09:
  - update .custodian-brief.md for the-custodian
2026-04-09 20:40:59 +02:00
8b83e5d910 chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-04-09:
  - update .custodian-brief.md for the-custodian
2026-04-09 20:26:12 +02:00
759079a8da chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-04-09:
  - update .custodian-brief.md for the-custodian
2026-04-09 20:11:26 +02:00
449fe1d1ea chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-04-09:
  - update .custodian-brief.md for the-custodian
2026-04-09 19:56:38 +02:00
25dd1ad78f chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-04-09:
  - update .custodian-brief.md for the-custodian
2026-04-09 19:41:52 +02:00
c090f026fc chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-04-09:
  - update .custodian-brief.md for the-custodian
2026-04-09 19:27:06 +02:00
12f1fa9410 chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-04-09:
  - update .custodian-brief.md for the-custodian
2026-04-09 19:12:21 +02:00
aee94be1e8 chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-04-09:
  - update .custodian-brief.md for the-custodian
2026-04-09 18:57:34 +02:00
48805884f5 chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-04-09:
  - update .custodian-brief.md for the-custodian
2026-04-09 18:42:47 +02:00
81b22015bf chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-04-09:
  - update .custodian-brief.md for the-custodian
2026-04-09 18:28:02 +02:00
e7462394e3 chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-04-09:
  - update .custodian-brief.md for the-custodian
2026-04-09 18:13:15 +02:00
38eb67263b chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-04-09:
  - update .custodian-brief.md for the-custodian
2026-04-09 17:58:29 +02:00
ab0cf34ebf chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-04-09:
  - update .custodian-brief.md for the-custodian
2026-04-09 17:43:43 +02:00
1548fa83a4 chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-04-09:
  - update .custodian-brief.md for the-custodian
2026-04-09 17:28:57 +02:00
dfd0dc3297 chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-04-09:
  - update .custodian-brief.md for the-custodian
2026-04-09 17:14:13 +02:00
7cf4b6e847 chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-04-09:
  - update .custodian-brief.md for the-custodian
2026-04-09 16:59:26 +02:00
ef3cb51678 chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-04-09:
  - update .custodian-brief.md for the-custodian
2026-04-09 16:44:39 +02:00
fd58393f9e chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-04-09:
  - update .custodian-brief.md for the-custodian
2026-04-09 16:29:53 +02:00
193d93fb2d chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-04-09:
  - update .custodian-brief.md for the-custodian
2026-04-09 16:15:07 +02:00
60270d533d chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-04-09:
  - update .custodian-brief.md for the-custodian
2026-04-09 16:00:21 +02:00
96b155c7e5 chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-04-09:
  - update .custodian-brief.md for the-custodian
2026-04-09 15:45:34 +02:00
61d38e457b chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-04-09:
  - update .custodian-brief.md for the-custodian
2026-04-09 15:30:47 +02:00
cf4f64df87 chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-04-09:
  - update .custodian-brief.md for the-custodian
2026-04-09 15:16:03 +02:00
7a557be265 chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-04-09:
  - update .custodian-brief.md for the-custodian
2026-04-09 15:01:17 +02:00
b86b1e5045 chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-04-09:
  - update .custodian-brief.md for the-custodian
2026-04-09 14:46:36 +02:00
0016dd482d chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-04-09:
  - update .custodian-brief.md for the-custodian
2026-04-09 14:31:51 +02:00
f17777e9c6 chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-04-09:
  - update .custodian-brief.md for the-custodian
2026-04-09 14:17:08 +02:00
13e5f1b753 chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-04-09:
  - update .custodian-brief.md for the-custodian
2026-04-09 14:02:12 +02:00
08a45985df chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-04-09:
  - update .custodian-brief.md for the-custodian
2026-04-09 13:47:25 +02:00
1c4691e6a0 chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-04-09:
  - update .custodian-brief.md for the-custodian
2026-04-09 13:32:41 +02:00
308910bfb8 chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-04-09:
  - update .custodian-brief.md for the-custodian
2026-04-09 13:17:59 +02:00
a8da6dc621 chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-04-09:
  - update .custodian-brief.md for the-custodian
2026-04-09 13:03:08 +02:00
eb03ad0316 chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-04-09:
  - update .custodian-brief.md for the-custodian
2026-04-09 12:48:20 +02:00
aec0c69a25 chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-04-09:
  - update .custodian-brief.md for the-custodian
2026-04-09 12:33:33 +02:00
cb3a1f5809 chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-04-09:
  - update .custodian-brief.md for the-custodian
2026-04-09 12:18:50 +02:00
6d31ee62e5 chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-04-09:
  - update .custodian-brief.md for the-custodian
2026-04-09 12:04:09 +02:00
b726045dd9 chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-04-09:
  - update .custodian-brief.md for the-custodian
2026-04-09 11:49:26 +02:00
1c739d0d97 chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-04-09:
  - update .custodian-brief.md for the-custodian
2026-04-09 11:35:00 +02:00
0787b4120d chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-04-09:
  - update .custodian-brief.md for the-custodian
2026-04-09 00:56:54 +02:00
7b592c8937 chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-04-09:
  - update .custodian-brief.md for the-custodian
2026-04-09 00:42:21 +02:00
e68fdd26ef chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-04-09:
  - update .custodian-brief.md for the-custodian
2026-04-09 00:27:50 +02:00
abb24dbc73 chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-04-09:
  - update .custodian-brief.md for the-custodian
2026-04-09 00:13:16 +02:00
27f759bafc chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-04-08:
  - update .custodian-brief.md for the-custodian
2026-04-08 23:58:50 +02:00
d3c637fafb chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-04-08:
  - update .custodian-brief.md for the-custodian
2026-04-08 23:44:12 +02:00
21e179e3fe chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-04-08:
  - update .custodian-brief.md for the-custodian
2026-04-08 23:29:39 +02:00
c830053fb3 chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-04-08:
  - update .custodian-brief.md for the-custodian
2026-04-08 23:15:26 +02:00
e1d5542991 chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-04-08:
  - update .custodian-brief.md for the-custodian
2026-04-08 23:00:37 +02:00
fdec23c021 chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-04-08:
  - update .custodian-brief.md for the-custodian
2026-04-08 22:46:02 +02:00
0e8a9fe56d chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-04-08:
  - update .custodian-brief.md for the-custodian
2026-04-08 22:31:27 +02:00
ed9e5eb7cd chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-04-08:
  - update .custodian-brief.md for the-custodian
2026-04-08 22:16:56 +02:00
b3ba917565 chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-04-08:
  - update .custodian-brief.md for the-custodian
2026-04-08 22:02:23 +02:00
297333adcf chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-04-08:
  - update .custodian-brief.md for the-custodian
2026-04-08 21:47:49 +02:00
c2676eb68b chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-04-08:
  - update .custodian-brief.md for the-custodian
2026-04-08 21:33:20 +02:00
235dc0718b chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-04-08:
  - update .custodian-brief.md for the-custodian
2026-04-08 21:18:43 +02:00
ae6cf328d3 chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-04-08:
  - update .custodian-brief.md for the-custodian
2026-04-08 21:04:13 +02:00
956aa82583 chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-04-08:
  - update .custodian-brief.md for the-custodian
2026-04-08 20:49:38 +02:00
8b74f19f3f chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-04-08:
  - update .custodian-brief.md for the-custodian
2026-04-08 20:35:06 +02:00
041cc6885a chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-04-08:
  - update .custodian-brief.md for the-custodian
2026-04-08 20:20:33 +02:00
0ae27a344c chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-04-08:
  - update .custodian-brief.md for the-custodian
2026-04-08 20:06:03 +02:00
c2d2a0b37a chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-04-08:
  - update .custodian-brief.md for the-custodian
2026-04-08 19:51:27 +02:00
5fc1f4d8fe chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-04-08:
  - update .custodian-brief.md for the-custodian
2026-04-08 19:36:55 +02:00
99adfb18af chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-04-08:
  - update .custodian-brief.md for the-custodian
2026-04-08 19:22:23 +02:00
890a7e9019 chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-04-08:
  - update .custodian-brief.md for the-custodian
2026-04-08 19:07:49 +02:00
711dfc6584 chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-04-08:
  - update .custodian-brief.md for the-custodian
2026-04-08 18:53:16 +02:00
7908e30ca3 chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-04-08:
  - update .custodian-brief.md for the-custodian
2026-04-08 18:38:44 +02:00
b903bcc04a chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-04-08:
  - update .custodian-brief.md for the-custodian
2026-04-08 18:24:12 +02:00
43e15c6973 chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-04-08:
  - update .custodian-brief.md for the-custodian
2026-04-08 18:09:39 +02:00
0c0eb21162 chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-04-08:
  - update .custodian-brief.md for the-custodian
2026-04-08 17:55:06 +02:00
61d8492cf0 chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-04-08:
  - update .custodian-brief.md for the-custodian
2026-04-08 17:40:35 +02:00
3301a1db53 chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-04-08:
  - update .custodian-brief.md for the-custodian
2026-04-08 17:26:01 +02:00
d0318ddc72 chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-04-08:
  - update .custodian-brief.md for the-custodian
2026-04-08 17:11:27 +02:00
ac5a93eb8c chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-04-08:
  - update .custodian-brief.md for the-custodian
2026-04-08 16:56:56 +02:00
b06d3769a6 chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-04-08:
  - update .custodian-brief.md for the-custodian
2026-04-08 16:42:24 +02:00
f0e8d803f6 chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-04-08:
  - update .custodian-brief.md for the-custodian
2026-04-08 16:27:50 +02:00
6379a6677e chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-04-08:
  - update .custodian-brief.md for the-custodian
2026-04-08 16:13:19 +02:00
e05eea3ea0 chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-04-08:
  - update .custodian-brief.md for the-custodian
2026-04-08 15:58:45 +02:00
32a67902f4 chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-04-08:
  - update .custodian-brief.md for the-custodian
2026-04-08 15:44:15 +02:00
25330c1b4b chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-04-08:
  - update .custodian-brief.md for the-custodian
2026-04-08 15:29:39 +02:00
678787d55b chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-04-08:
  - update .custodian-brief.md for the-custodian
2026-04-08 15:15:03 +02:00
ca2e46b824 chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-04-08:
  - update .custodian-brief.md for the-custodian
2026-04-08 15:00:27 +02:00
93495b7114 chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-04-08:
  - update .custodian-brief.md for the-custodian
2026-04-08 14:45:53 +02:00
e5540ca974 chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-04-08:
  - update .custodian-brief.md for the-custodian
2026-04-08 14:30:59 +02:00
bc335508d3 chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-04-08:
  - update .custodian-brief.md for the-custodian
2026-04-08 14:16:11 +02:00
0681503376 chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-04-08:
  - update .custodian-brief.md for the-custodian
2026-04-08 14:01:26 +02:00
521c650ae4 chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-04-08:
  - update .custodian-brief.md for the-custodian
2026-04-08 13:46:39 +02:00
5b9764b9c4 chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-04-08:
  - update .custodian-brief.md for the-custodian
2026-04-08 13:31:54 +02:00
808f39992d chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-04-08:
  - update .custodian-brief.md for the-custodian
2026-04-08 13:17:07 +02:00
fe868d2e6e chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-04-08:
  - update .custodian-brief.md for the-custodian
2026-04-08 13:02:20 +02:00
0bf645ad40 chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-04-08:
  - update .custodian-brief.md for the-custodian
2026-04-08 12:47:36 +02:00
99b04aebb9 chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-04-08:
  - update .custodian-brief.md for the-custodian
2026-04-08 12:32:49 +02:00
3b3bb59b5d chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-04-08:
  - update .custodian-brief.md for the-custodian
2026-04-08 12:18:04 +02:00
0735e5b840 chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-04-08:
  - update .custodian-brief.md for the-custodian
2026-04-08 12:03:16 +02:00
f7c926360e chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-04-08:
  - update .custodian-brief.md for the-custodian
2026-04-08 11:48:29 +02:00
088f3493ee chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-04-08:
  - update .custodian-brief.md for the-custodian
2026-04-08 11:33:44 +02:00
c7e34d8e44 chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-04-08:
  - update .custodian-brief.md for the-custodian
2026-04-08 11:18:58 +02:00
5e4d21d1b3 chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-04-08:
  - update .custodian-brief.md for the-custodian
2026-04-08 11:04:05 +02:00
ba7018d894 chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-04-08:
  - update .custodian-brief.md for the-custodian
2026-04-08 10:49:19 +02:00
e6c0e8da75 chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-04-08:
  - update .custodian-brief.md for the-custodian
2026-04-08 10:34:32 +02:00
aa681925c2 chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-04-08:
  - update .custodian-brief.md for the-custodian
2026-04-08 10:19:48 +02:00
add0657c38 chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-04-08:
  - update .custodian-brief.md for the-custodian
2026-04-08 10:05:01 +02:00
627696e94f chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-04-08:
  - update .custodian-brief.md for the-custodian
2026-04-08 09:50:15 +02:00
c2dd7d0acd chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-04-08:
  - update .custodian-brief.md for the-custodian
2026-04-08 09:35:28 +02:00
248ac49d4e chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-04-08:
  - update .custodian-brief.md for the-custodian
2026-04-08 09:20:41 +02:00
259aa687e6 chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-04-08:
  - update .custodian-brief.md for the-custodian
2026-04-08 09:05:56 +02:00
8dcdd94181 chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-04-08:
  - update .custodian-brief.md for the-custodian
2026-04-08 08:51:10 +02:00
5949b5028a chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-04-08:
  - update .custodian-brief.md for the-custodian
2026-04-08 08:36:23 +02:00
f50912d2ff chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-04-08:
  - update .custodian-brief.md for the-custodian
2026-04-08 08:21:37 +02:00
be33737be7 chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-04-08:
  - update .custodian-brief.md for the-custodian
2026-04-08 08:06:52 +02:00
d5b204cc12 chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-04-08:
  - update .custodian-brief.md for the-custodian
2026-04-08 07:52:03 +02:00
406ce05bfa chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-04-08:
  - update .custodian-brief.md for the-custodian
2026-04-08 07:37:17 +02:00
d35548771f chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-04-08:
  - update .custodian-brief.md for the-custodian
2026-04-08 07:22:32 +02:00
d9db241de7 chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-04-08:
  - update .custodian-brief.md for the-custodian
2026-04-08 07:07:46 +02:00
8405dfec4d chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-04-08:
  - update .custodian-brief.md for the-custodian
2026-04-08 06:53:00 +02:00
22759d9b6a chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-04-08:
  - update .custodian-brief.md for the-custodian
2026-04-08 06:38:12 +02:00
9f819df7b2 chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-04-08:
  - update .custodian-brief.md for the-custodian
2026-04-08 06:23:27 +02:00
5bcf2c3fef chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-04-08:
  - update .custodian-brief.md for the-custodian
2026-04-08 06:08:41 +02:00
bff41001a9 chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-04-08:
  - update .custodian-brief.md for the-custodian
2026-04-08 05:53:57 +02:00
830cd489f2 chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-04-08:
  - update .custodian-brief.md for the-custodian
2026-04-08 05:39:09 +02:00
3579071cad chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-04-08:
  - update .custodian-brief.md for the-custodian
2026-04-08 05:24:23 +02:00
25cf42685f chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-04-08:
  - update .custodian-brief.md for the-custodian
2026-04-08 05:09:37 +02:00
5811a7be50 chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-04-08:
  - update .custodian-brief.md for the-custodian
2026-04-08 04:54:51 +02:00
70d30c7866 chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-04-08:
  - update .custodian-brief.md for the-custodian
2026-04-08 04:40:04 +02:00
72ff39fd46 chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-04-08:
  - update .custodian-brief.md for the-custodian
2026-04-08 04:25:19 +02:00
fbf21908d9 chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-04-08:
  - update .custodian-brief.md for the-custodian
2026-04-08 04:10:33 +02:00
d3eb9a066b chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-04-08:
  - update .custodian-brief.md for the-custodian
2026-04-08 03:55:48 +02:00
7d365ac26b chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-04-08:
  - update .custodian-brief.md for the-custodian
2026-04-08 03:41:06 +02:00
d0e6696863 chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-04-08:
  - update .custodian-brief.md for the-custodian
2026-04-08 03:26:17 +02:00
a804f2052e chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-04-08:
  - update .custodian-brief.md for the-custodian
2026-04-08 03:11:34 +02:00
a07b5a3a8c chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-04-08:
  - update .custodian-brief.md for the-custodian
2026-04-08 02:56:45 +02:00
8193713274 chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-04-08:
  - update .custodian-brief.md for the-custodian
2026-04-08 02:41:58 +02:00
7fc7f7d554 chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-04-08:
  - update .custodian-brief.md for the-custodian
2026-04-08 02:27:12 +02:00
876b096c8b chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-04-08:
  - update .custodian-brief.md for the-custodian
2026-04-08 02:12:27 +02:00
64d9432621 chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-04-08:
  - update .custodian-brief.md for the-custodian
2026-04-08 01:57:40 +02:00
ec94bc8dfd chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-04-08:
  - update .custodian-brief.md for the-custodian
2026-04-08 01:42:54 +02:00
e53301e984 chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-04-08:
  - update .custodian-brief.md for the-custodian
2026-04-08 01:28:08 +02:00
f0e580d90b chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-04-08:
  - update .custodian-brief.md for the-custodian
2026-04-08 01:13:21 +02:00
22684542fd chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-04-08:
  - update .custodian-brief.md for the-custodian
2026-04-08 00:58:53 +02:00
d9b25dc51c chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-04-08:
  - update .custodian-brief.md for the-custodian
2026-04-08 00:44:07 +02:00
61f064005f chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-04-08:
  - update .custodian-brief.md for the-custodian
2026-04-08 00:29:20 +02:00
9111e46a33 chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-04-08:
  - update .custodian-brief.md for the-custodian
2026-04-08 00:14:13 +02:00
788c266d5b chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-04-07:
  - update .custodian-brief.md for the-custodian
2026-04-07 23:59:29 +02:00
f055692353 chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-04-07:
  - update .custodian-brief.md for the-custodian
2026-04-07 23:44:48 +02:00
ca80aa3be0 chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-04-07:
  - update .custodian-brief.md for the-custodian
2026-04-07 23:30:09 +02:00
54a3f8d0cb chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-04-07:
  - update .custodian-brief.md for the-custodian
2026-04-07 23:15:40 +02:00
3d9876d696 chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-04-07:
  - update .custodian-brief.md for the-custodian
2026-04-07 23:00:47 +02:00
b80d8987be chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-04-07:
  - update .custodian-brief.md for the-custodian
2026-04-07 22:46:00 +02:00
a27ebe0186 chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-04-07:
  - update .custodian-brief.md for the-custodian
2026-04-07 22:31:17 +02:00
ef3fff3cbc chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-04-07:
  - update .custodian-brief.md for the-custodian
2026-04-07 22:16:38 +02:00
4894d6cb67 chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-04-07:
  - update .custodian-brief.md for the-custodian
2026-04-07 22:01:42 +02:00
ba9a21f4da chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-04-07:
  - update .custodian-brief.md for the-custodian
2026-04-07 21:46:55 +02:00
a030faef4f chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-04-07:
  - update .custodian-brief.md for the-custodian
2026-04-07 21:32:19 +02:00
e41edaf988 chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-04-07:
  - update .custodian-brief.md for the-custodian
2026-04-07 21:17:50 +02:00
79892092ac chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-04-06:
  - update .custodian-brief.md for the-custodian
2026-04-06 23:41:06 +02:00
3caf16cd02 chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-04-06:
  - update .custodian-brief.md for the-custodian
2026-04-06 23:26:38 +02:00
f22dce0f5a chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-04-04:
  - update .custodian-brief.md for the-custodian
2026-04-04 12:48:16 +02:00
38fe3ded23 chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-04-04:
  - update .custodian-brief.md for the-custodian
2026-04-04 12:33:30 +02:00
7bae0e9555 chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-04-04:
  - update .custodian-brief.md for the-custodian
2026-04-04 12:18:41 +02:00
6477698225 chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-04-04:
  - update .custodian-brief.md for the-custodian
2026-04-04 12:03:59 +02:00
72ebe7784b chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-04-04:
  - update .custodian-brief.md for the-custodian
2026-04-04 11:49:12 +02:00
90e1d0fd16 chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-04-04:
  - update .custodian-brief.md for the-custodian
2026-04-04 11:34:40 +02:00
72a60405c6 chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-04-04:
  - update .custodian-brief.md for the-custodian
2026-04-04 11:19:33 +02:00
585c151e31 chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-04-04:
  - update .custodian-brief.md for the-custodian
2026-04-04 11:04:46 +02:00
087161ede0 chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-04-04:
  - update .custodian-brief.md for the-custodian
2026-04-04 01:22:08 +02:00
79207bc51f chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-04-04:
  - update .custodian-brief.md for the-custodian
2026-04-04 01:07:18 +02:00
facdd0b41d chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-04-04:
  - update .custodian-brief.md for the-custodian
2026-04-04 00:52:32 +02:00
51e42ec513 chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-04-04:
  - update .custodian-brief.md for the-custodian
2026-04-04 00:37:47 +02:00
2c6c8a3193 chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-04-04:
  - update .custodian-brief.md for the-custodian
2026-04-04 00:23:02 +02:00
5db0d4075d chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-04-04:
  - update .custodian-brief.md for the-custodian
2026-04-04 00:08:15 +02:00
d413337e77 chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-04-03:
  - update .custodian-brief.md for the-custodian
2026-04-03 23:53:29 +02:00
137fb82431 chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-04-03:
  - update .custodian-brief.md for the-custodian
2026-04-03 23:38:42 +02:00
be21479fc0 chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-04-03:
  - update .custodian-brief.md for the-custodian
2026-04-03 23:23:56 +02:00
e3de063fb3 chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-04-03:
  - update .custodian-brief.md for the-custodian
2026-04-03 23:09:13 +02:00
330815a655 chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-04-03:
  - update .custodian-brief.md for the-custodian
2026-04-03 22:54:24 +02:00
670a567034 chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-04-03:
  - update .custodian-brief.md for the-custodian
2026-04-03 22:39:38 +02:00
8033d37788 chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-04-03:
  - update .custodian-brief.md for the-custodian
2026-04-03 22:24:52 +02:00
8061744ada chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-04-03:
  - update .custodian-brief.md for the-custodian
2026-04-03 22:10:06 +02:00
cb889739dd chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-04-03:
  - update .custodian-brief.md for the-custodian
2026-04-03 21:55:20 +02:00
85be657b33 chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-04-03:
  - update .custodian-brief.md for the-custodian
2026-04-03 21:40:32 +02:00
9264bdd079 chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-04-03:
  - update .custodian-brief.md for the-custodian
2026-04-03 21:25:50 +02:00
b2fad8e1a2 chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-04-03:
  - update .custodian-brief.md for the-custodian
2026-04-03 21:11:02 +02:00
8797ec0fea chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-04-03:
  - update .custodian-brief.md for the-custodian
2026-04-03 20:56:16 +02:00
bbb755f87c chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-04-03:
  - update .custodian-brief.md for the-custodian
2026-04-03 20:41:36 +02:00
d3b8722a01 chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-04-03:
  - update .custodian-brief.md for the-custodian
2026-04-03 20:26:50 +02:00
c60ee776c3 chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-04-03:
  - update .custodian-brief.md for the-custodian
2026-04-03 20:12:00 +02:00
5796bcec37 chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-04-03:
  - update .custodian-brief.md for the-custodian
2026-04-03 19:57:13 +02:00
e8d587bd41 chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-04-03:
  - update .custodian-brief.md for the-custodian
2026-04-03 19:42:25 +02:00
d1d0fb40c7 chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-04-03:
  - update .custodian-brief.md for the-custodian
2026-04-03 19:27:39 +02:00
b774f6eecb chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-04-03:
  - update .custodian-brief.md for the-custodian
2026-04-03 19:13:00 +02:00
d821d3d4a1 chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-04-03:
  - update .custodian-brief.md for the-custodian
2026-04-03 18:58:09 +02:00
cbb73870d1 chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-04-03:
  - update .custodian-brief.md for the-custodian
2026-04-03 18:43:18 +02:00
02325dc928 chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-04-03:
  - update .custodian-brief.md for the-custodian
2026-04-03 18:29:28 +02:00
7ab40423ec chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-04-03:
  - update .custodian-brief.md for the-custodian
2026-04-03 18:13:46 +02:00
68d5235d72 chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-04-03:
  - update .custodian-brief.md for the-custodian
2026-04-03 17:59:03 +02:00
35ca5f4c15 chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-04-03:
  - update .custodian-brief.md for the-custodian
2026-04-03 17:44:18 +02:00
4a3c452645 chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-04-03:
  - update .custodian-brief.md for the-custodian
2026-04-03 17:29:35 +02:00
e11cfecc27 chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-04-03:
  - update .custodian-brief.md for the-custodian
2026-04-03 17:14:51 +02:00
143b6f62fd chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-04-03:
  - update .custodian-brief.md for the-custodian
2026-04-03 17:00:03 +02:00
ccba77ba16 chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-04-03:
  - update .custodian-brief.md for the-custodian
2026-04-03 16:45:17 +02:00
0270146c3f chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-04-03:
  - update .custodian-brief.md for the-custodian
2026-04-03 16:30:48 +02:00
6ddf5742d8 chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-04-03:
  - update .custodian-brief.md for the-custodian
2026-04-03 16:16:38 +02:00
e2b35b1b13 chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-04-03:
  - update .custodian-brief.md for the-custodian
2026-04-03 16:01:02 +02:00
c11bb057b6 chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-04-03:
  - update .custodian-brief.md for the-custodian
2026-04-03 15:46:14 +02:00
c7ad9e6221 chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-04-03:
  - update .custodian-brief.md for the-custodian
2026-04-03 15:31:26 +02:00
40dbea80bb chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-04-03:
  - update .custodian-brief.md for the-custodian
2026-04-03 15:16:41 +02:00
4aed3e1b67 chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-04-03:
  - update .custodian-brief.md for the-custodian
2026-04-03 15:01:56 +02:00
5552b9e76b chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-04-03:
  - update .custodian-brief.md for the-custodian
2026-04-03 14:47:10 +02:00
9f84bc5d1d chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-04-03:
  - update .custodian-brief.md for the-custodian
2026-04-03 14:33:24 +02:00
72cab6a5f7 chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-04-02:
  - update .custodian-brief.md for the-custodian
2026-04-02 01:18:23 +02:00
1c07bb2912 chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-04-02:
  - update .custodian-brief.md for the-custodian
2026-04-02 01:03:53 +02:00
19df0a7ca3 chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-04-02:
  - update .custodian-brief.md for the-custodian
2026-04-02 00:49:17 +02:00
8df104792a chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-04-02:
  - update .custodian-brief.md for the-custodian
2026-04-02 00:34:49 +02:00
4607ea20e3 chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-04-02:
  - update .custodian-brief.md for the-custodian
2026-04-02 00:20:02 +02:00
721b03fd9d chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-04-02:
  - update .custodian-brief.md for the-custodian
2026-04-02 00:05:35 +02:00
d1709e4465 chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-04-01:
  - update .custodian-brief.md for the-custodian
2026-04-01 23:51:00 +02:00
93c1d6d5c6 chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-04-01:
  - update .custodian-brief.md for the-custodian
2026-04-01 23:36:36 +02:00
674fdb1b2d chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-04-01:
  - update .custodian-brief.md for the-custodian
2026-04-01 23:21:51 +02:00
e614775016 chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-04-01:
  - update .custodian-brief.md for the-custodian
2026-04-01 23:07:34 +02:00
9585a8bc88 chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-04-01:
  - update .custodian-brief.md for the-custodian
2026-04-01 22:52:52 +02:00
626e290137 chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-04-01:
  - update .custodian-brief.md for the-custodian
2026-04-01 22:39:14 +02:00
f794d8c47f feat(token-events): auto-capture real token counts via PostToolUse hook
- Add PATCH /token-events/{id} endpoint to correct heuristic events
- Add `note` filter to GET /token-events/ list
- Add TokenEventPatch schema
- Add task_token_hook.py: PostToolUse hook that reads the Claude Code
  session transcript, computes per-task token delta, and replaces the
  heuristic token event with real measured counts (note="measured")
- Register hook in ~/.claude/settings.json on mcp__state-hub__update_task_status
  Covers both interactive sessions and ralph-workplan loops

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-01 22:38:45 +02:00
1914c7dae2 chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-04-01:
  - update .custodian-brief.md for the-custodian
2026-04-01 22:38:22 +02:00
ebb24c3282 chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-04-01:
  - update .custodian-brief.md for the-custodian
2026-04-01 22:23:54 +02:00
2cb17b8569 chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-04-01:
  - update .custodian-brief.md for the-custodian
2026-04-01 22:09:13 +02:00
f8ced0e98f chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-04-01:
  - update .custodian-brief.md for the-custodian
2026-04-01 21:54:42 +02:00
5678fe3852 chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-04-01:
  - update .custodian-brief.md for the-custodian
2026-04-01 21:54:19 +02:00
383 changed files with 16236 additions and 41335 deletions

View File

@@ -1,72 +1,51 @@
<!-- custodian-brief: generated by fix-consistency — do not edit manually -->
# Custodian Brief — the-custodian
**Domain:** railiance
**Last synced:** 2026-04-01 19:39 UTC
**Domain:** infotech
**Last synced:** 2026-06-27 22:26 UTC
**State Hub:** http://127.0.0.1:8000 *(adjust if running on a remote machine)*
## Active Workstreams
### Cross-Repo E2E Sandbox Framework
Progress: 8/8 done | workstream_id: `b68de20b-e397-4f97-b1be-ad30711fc2a6`
### Ops Hub Service Inventory Now View
Progress: 6/7 done | workstream_id: `656e435d-3a00-4f5e-a38e-114467f9062e`
### Interactive — the-custodian
Progress: 4/4 done | workstream_id: `370c2481-6806-41eb-a917-f8874f03184f`
**Open tasks:**
- ! Task: Activate Ops-Hub Widgets In Inter-Hub `b16c5e15`
### Inter-Hub Bootstrap Access Lane
Progress: 5/6 done | workstream_id: `9b56414a-c71f-4e72-9b2b-d2166aaf50d0`
**Open tasks:**
- ! Task: Execute Live Ops-Hub Bootstrap `782b3846`
### Infrastructure Stabilization Metaplan
Progress: 3/8 done | workstream_id: `21cabc98-3f80-4d00-b3b7-06e2ac2af88f`
**Open tasks:**
- ► Task: Close The Ops-Hub Inter-Hub Evidence Lane `d6c3a39e`
- ► Task: Stabilize Daily-Triage Automation `42810d3b`
- ► Task: Finish Near-Term Production Service Lanes `2083f0e4`
- ► Task: Decide State Hub Migration Strategy `0ac3763f`
- ► Task: Sequence FOS Hub Bootstrap To Completion `27b6828a`
### FOS Hub Bootstrap — Identity, Hub Extraction, Ops Hub, Fin Hub
Progress: 0/26 done | workstream_id: `293a74fe-a85a-4ad6-8933-23d52a72fe8b`
Progress: 17/26 done | workstream_id: `293a74fe-a85a-4ad6-8933-23d52a72fe8b`
**Open tasks:**
- · T01 — Complete NK-WP-0001: Keycloak + privacyIDEA on k3s `f55078b6`
- · T02 — Complete NK-WP-0002: Local identity bootstrap `0d7792f7`
- · T03IAM Profile integration test `e9894ac9`
- · T04 — Canon standard: IAM Profile specification `69acc880`
- · T05 — Create hub-core package `04bf480c`
- · T06Hub-core FastMCP base server `6b49d94a`
- · T07 — FOS §10 risk and alert tools `5a54af24`
- … and 19 more open tasks
### Multi-User Onboarding and Environment Bootstrap
Progress: 0/6 done | workstream_id: `a28d9e29-4119-4b73-9469-f921920253ef`
**Open tasks:**
- · Git credential.helper setup for Gitea access `71628269`
- · SSH key generation and authorization automation `fea965e9`
- · Claude Code MCP registration for new machines `60318e9a`
- · Environment bootstrap script (bootstrap-env.sh) `84a94761`
- · Onboarding guide and user journey documentation `b0839802`
- · State Hub multi-user model — domain-scoped access `d5df3302`
### Migrate Custodian State Hub to ThreePhoenix Cluster
Progress: 0/9 done | workstream_id: `967baafb-d92d-405a-ba0b-0d00d37c4940`
**Open tasks:**
- · T01 — Drill WSL2 backup restore end-to-end `b0caf112`
- · T02 — Helm chart for State Hub `24887dd9`
- · T03 — Build and push State Hub container image `79908ade`
- · T04 — Deploy to cluster and run Alembic migrations `a7baf2eb`
- · T05 — Migrate data from WSL2 to cluster `a307dd46`
- · T06 — Drill cluster backup restore `03753b88`
- · T07 — Cutover: redirect MCP config to cluster `ff1de25e`
- … and 2 more open tasks
### State Hub v0.4 — Workstream Health Index (WHI) KPI Card
Progress: 0/9 done | workstream_id: `9cc32158-2f5c-4ef6-9713-aacce4623d5e`
**Open tasks:**
- · P1 — Verify dependency edge fields in open_workstreams `243646e0`
- · P2.1 — Build directed dependency graph from openWs + completedIds `6dbef71f`
- · P2.2 — Implement DFS cycle detection (CPI) `f0d5c107`
- · P2.3 — Compute DD, BR, SPR, PEP, CDDR `6da60567`
- · P2.4 — WHI formula: normalization + CPI penalty `29b2dbbd`
- · P2.5 — Per-domain WHI breakdown `8ce5ef74`
- · P3 — WHI KPI card UI `91efba5c`
- ! T16Railiance infrastructure integration `702849c5`
- ! T17 — Cross-hub protocol: ops-hub to dev-hub `b99a3ed8`
- · T20 — Business model canvas: railiance-as-a-service `55db0560`
- · T21 — Canon: Bootstrap Protocol document `ce54d3fc`
- · T22 — Create fin-hub repo from hub-core scaffold `670757d8`
- · T23Fin-specific models `8ebffb3f`
- · T24 — Fin-hub implementation: cost tracking + runway `405f81d3`
- … and 2 more open tasks
---
## MCP Orientation (when available)
If the state-hub MCP server is reachable, call:
`get_domain_summary("railiance")`
`get_domain_summary("infotech")`
This provides richer cross-domain context.
If the MCP call fails, use this file as your orientation source.

6
.gitignore vendored
View File

@@ -186,3 +186,9 @@ state-hub/dashboard/src/.observablehq/
state-hub/dashboard/dist/
state-hub/kubectl
# Kaizen runtime artifacts (generated per agent run)
.kaizen/metrics/
# Local agent definition backups (migration artifacts)
agents_backup_*/

View File

@@ -0,0 +1,24 @@
---
agent: coach
project: the-custodian
last_updated: 2026-06-18
session_count: 0
---
## Project Context
<!-- What this agent knows about the project it works in -->
## Accumulated Findings
<!-- Patterns, recurring issues, key decisions encountered -->
## What Worked
<!-- Approaches that produced good results in this project -->
## Watch Points
<!-- Recurring risks, traps, or areas requiring extra care -->
## Open Threads
<!-- Things noticed but not yet acted on -->
## Session Log
<!-- One-line entry per session: date · summary · outcome -->

View File

@@ -0,0 +1,24 @@
---
agent: optimization
project: the-custodian
last_updated: 2026-06-18
session_count: 0
---
## Project Context
<!-- What this agent knows about the project it works in -->
## Accumulated Findings
<!-- Patterns, recurring issues, key decisions encountered -->
## What Worked
<!-- Approaches that produced good results in this project -->
## Watch Points
<!-- Recurring risks, traps, or areas requiring extra care -->
## Open Threads
<!-- Things noticed but not yet acted on -->
## Session Log
<!-- One-line entry per session: date · summary · outcome -->

View File

@@ -0,0 +1,29 @@
---
agent: scope-analyst
last_updated: "2026-06-21"
session_count: 1
---
# scope-analyst memory
## Accumulated Findings
### the-custodian (2026-06-21)
- **Central boundary decision:** the-custodian is the *governance/continuity
substrate*, NOT the State Hub service. The service (DB/API/MCP/dashboard) lives
at `/home/worsch/state-hub`; `the-custodian/state-hub/` is only a pointer. Any
SCOPE that claims state-tracking / SBOM / MCP-tool-registration as this repo's
own "Provided Capabilities" is conflating the two — the prior SCOPE did exactly
that. New SCOPE reframes capabilities to governance canon / session protocol /
append-only memory.
- **Authoritative boundary source:** `INTENT.md` (updated 2026-05-17) has the
cleanest "What it is not" ownership table — state-hub, activity-core, issue-core,
repo-scoping, domain repos, human-approval. SCOPE was missing issue-core and
repo-scoping; now added.
- **Domain count is dynamic, do NOT hard-code.** Live `list_domains()` returned
14 active on 2026-06-21. Old SCOPE said 6/7 (and was self-contradictory). README
still says "seven"/"six" — also stale. Treat `list_domains()` as authoritative.
- Prior stale SCOPE archived to `history/20260621-SCOPE.md`.
## Session Log
2026-06-21 · the-custodian · Rebuilt SCOPE.md from repo+INTENT+live domains; archived stale version; fixed state-hub/custodian conflation and domain-count drift.

18
.kaizen/schedule.yml Normal file
View File

@@ -0,0 +1,18 @@
# Kaizen scheduled agent execution manifest (ADR-005)
# Engagement: coulomb-loop — weekly operate cadence
# Regulator promotes cadence per customer engagement policy (ADR-003).
# Validate with: kaizen-agentic schedule validate
version: '1'
timezone: Europe/Berlin
agents:
coach:
cadence: weekly
cron: "0 9 * * 1"
enabled: true
optimization:
cadence: weekly
cron: "0 10 * * 1"
enabled: true
tdd-workflow:
cadence: monthly
enabled: false

37
.repo-classification.yaml Normal file
View File

@@ -0,0 +1,37 @@
repo_classification:
standard: Repo Classification Standard
version: "1.0"
classified_at: "2026-06-22"
classified_by: human
# the-custodian is the governance/continuity substrate: canon, standards,
# ADRs, charters, memory, and cross-domain coordination scaffolding.
category: research
domain: infotech
secondary_domains:
- agents
capability_tags:
- governance
- knowledge
- coordination
- policy
- documentation
business_stake:
- technology
- operations
- intelligence
- execution
business_mechanics:
- intention
- control
- coordination
- adaptation
notes: >
Primary domain is infotech (the intended users are the ecosystem's
developers and agents); agents is a secondary domain because the repo is
agent-coordination infrastructure. Classified as research because its core
output is canon, standards, and decision records rather than a deployable

219
AGENTS.md Normal file
View File

@@ -0,0 +1,219 @@
# The Custodian — Agent Instructions
## Repo Identity
**Purpose:** Transgenerational cognitive infrastructure and central coordination hub for all domains. Houses the state-hub (PostgreSQL + FastAPI + MCP + dashboard), governance canon, workplans, and agent session memory.
**Domain:** infotech
**Repo slug:** the-custodian
**Topic ID:** `cee7bedf-2b48-46ef-8601-006474f2ad7a`
**Workplan prefix:** `CUST-WP-`
---
## State Hub Integration
The Custodian State Hub tracks work across all domains. Interact via HTTP REST —
there is no MCP server for Codex agents.
| Context | URL |
|---------|-----|
| Local workstation | `http://127.0.0.1:8000` |
| Remote via tunnel | `http://127.0.0.1:18000` |
### Orient at session start
```bash
# Offline brief — works without hub connection
cat .custodian-brief.md
# Active workstreams for this domain
curl -s "http://127.0.0.1:8000/workstreams/?topic_id=cee7bedf-2b48-46ef-8601-006474f2ad7a&status=active" \
| python3 -m json.tool
# Check inbox
curl -s "http://127.0.0.1:8000/messages/?to_agent=the-custodian&unread_only=true" \
| python3 -m json.tool
```
Mark a message read:
```bash
curl -s -X PATCH "http://127.0.0.1:8000/messages/<id>/read" \
-H "Content-Type: application/json" -d '{}'
```
### Log progress (required at session close)
```bash
curl -s -X POST http://127.0.0.1:8000/progress/ \
-H "Content-Type: application/json" \
-d '{
"summary": "what was done",
"event_type": "note",
"author": "codex",
"workstream_id": "<uuid>",
"task_id": "<uuid>"
}'
```
Omit `workstream_id` / `task_id` when not applicable.
### Update task status
```bash
curl -s -X PATCH "http://127.0.0.1:8000/tasks/<task_id>" \
-H "Content-Type: application/json" \
-d '{"status": "progress"}'
# values: wait | todo | progress | done | cancel
```
### Flag a task for human review
```bash
curl -s -X PATCH "http://127.0.0.1:8000/tasks/<task_id>" \
-H "Content-Type: application/json" \
-d '{"needs_human": true, "intervention_note": "reason"}'
```
---
## Session Protocol
**Start:**
1. `cat .custodian-brief.md` — domain goal and open workstreams (offline-safe)
2. Check inbox: `GET /messages/?to_agent=the-custodian&unread_only=true`; mark read
3. Scan workplans: `ls workplans/` — note `status: ready`, `active`, or `blocked` files and open tasks
4. Check human-needed tasks: `GET /tasks/?needs_human=true`
**During work:**
- Update task statuses in workplan files as tasks progress
- Record significant decisions via `POST /decisions/`
**Close:**
1. Update workplan file task statuses to reflect progress
2. Log: `POST /progress/` with a summary of what changed
3. Note for the custodian operator: after workplan file changes, run from
`~/state-hub`:
```bash
make fix-consistency REPO=the-custodian
```
This syncs task status from files into the hub DB.
---
## Credential and access routing
**Audience:** Codex, Claude Code, Grok, and custodian agents that call **llm-connect**
for inference. Run this check **before** requesting secrets, API keys, SSH access,
login tokens, or database passwords — in any repo, not only `ops-warden`.
ops-warden **issues SSH certificates only** (`warden sign`, `cert_command`). Every
other credential need belongs to another subsystem. **Do not** message
`ops-warden` on State Hub expecting a secret value; the reply is a pointer, not a key.
### Lookup (do this first)
```bash
warden route find "<describe your need>" --json
warden route show <catalog-id> --json
```
Requires the `warden` CLI from `~/ops-warden` (`uv tool install .` or `uv run warden`).
| Agent runtime | How to orient |
| --- | --- |
| **Codex / Grok** (shell, HTTP State Hub) | `warden route` commands above; inbox `to_agent=the-custodian` is for coordination, not secret vending |
| **Claude Code** (MCP when available) | `get_domain_summary("custodian")` for workstreams; **still** use `warden route` for credential ownership |
| **llm-connect** (inference service) | Never put secret retrieval in prompts; route custody to OpenBao/operator paths surfaced by `warden route` |
### Quick routing table
| I need… | Owner | ops-warden executes? |
| --- | --- | --- |
| SSH cert (`adm`/`agt`/`atm`) | ops-warden | **Yes** — `warden sign` |
| API key, DB password, provider token | OpenBao (`railiance-platform`) | No — route only |
| Login / OIDC / MFA | key-cape / Keycloak | No — route only |
| Authorization decision | flex-auth | No — route only |
| activity-core → issue-core emission | activity-core + issue-core | No — `warden route show activity-core-issue-sink` |
| SSH tunnel | ops-bridge (+ `cert_command` from warden) | No — route only |
### Anti-patterns (do not do these)
- `POST /messages/` to `ops-warden` asking for `ISSUE_CORE_API_KEY`, `OPENROUTER_API_KEY`, etc.
- Inventing `warden secret`, `warden login`, `warden bao`, `warden tunnel` — they do not exist
- Pasting secrets into Git, State Hub, workplans, logs, or chat
### Other capabilities (reuse-surface)
Non-credential capabilities are usually discovered through **reuse-surface** federation
(`reuse-surface` registry / `capability.*` indexes). Credential routing is inlined in
every repo's agent instructions because it is high-frequency, high-risk, and easy to
get wrong.
**Canon:** `~/ops-warden/wiki/CredentialRouting.md` · catalog `~/ops-warden/registry/routing/catalog.yaml`
<!-- REPO-AGENTS-EXTENSIONS -->
<!-- Append repo-specific agent instructions below this marker.
The state-hub template sync preserves content after this line. -->
---
## Workplan Convention (ADR-001)
Work items originate as files in this repo — not in the hub. The hub is a
read/cache/index layer that rebuilds from files.
**File location:** `workplans/THE-WP-NNNN-<slug>.md`
**Archived location:** finished workplans may move to
`workplans/archived/YYMMDD-THE-WP-NNNN-<slug>.md`. The `YYMMDD` prefix is
the completion/archive date; the frontmatter `id` does not change.
**Ad Hoc Tasks:** small opportunistic fixes discovered during a session use
`workplans/ADHOC-YYYY-MM-DD.md` with task ids `ADHOC-YYYY-MM-DD-T01`, etc. Use
this only for low-risk work completed directly; create a normal workplan for
anything needing analysis, design, approval, dependencies, or multiple phases.
**Frontmatter:**
```yaml
---
id: THE-WP-NNNN
type: workplan
title: "..."
domain: infotech
repo: the-custodian
status: proposed | ready | active | blocked | backlog | finished | archived
owner: codex
topic_slug: ...
created: "YYYY-MM-DD"
updated: "YYYY-MM-DD"
state_hub_workstream_id: "<uuid>" # written by fix-consistency — do not edit
---
```
Use `proposed` for a new draft, `ready` after review against current repo
state, and `finished` after implementation. `stalled` and `needs_review` are
derived health labels, not frontmatter statuses.
**Task block format** (one per `##` section):
```
## Task Title
` ` `task
id: THE-WP-NNNN-T01
status: wait | todo | progress | done | cancel
priority: high | medium | low
state_hub_task_id: "<uuid>" # written by fix-consistency — do not edit
` ` `
Task description text.
```
Status progression: `todo` → `progress` → `done`; use `wait` for waiting/blocked work and `cancel` for stopped work.
To create a new workplan:
1. Write the file following the format above
2. Notify the custodian operator to run `make fix-consistency REPO=the-custodian`
(or send a message to the hub agent via `POST /messages/`)

201
CLAUDE.md
View File

@@ -1,191 +1,12 @@
# CLAUDE.md
# The Custodian — Claude Code Instructions
This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
## What This Repository Is
**The Custodian** is a *transgenerational cognitive infrastructure* — a local-first, sovereignty-preserving agent system for co-creating and stewarding knowledge across seven project domains. v0.1 is a governance and schema skeleton; `state-hub/` is the first live implementation layer.
## Repository Structure
```
canon/ # Curated, reviewable knowledge substrate (identity lives here)
constitution/ # Custodian governance rules (v0.1)
values/ # Foundational principles (9 values)
projects/ # Six domain charters, concept seeds, roadmaps
custodian/ # Master agent system (includes full_circle_map)
railiance/ # DevOps & infrastructure reliability
markitect/ # Knowledge artifact management
coulomb.social/ # Co-creation marketplace experiment
personhood/ # Rights/obligations framework
foerster-capabilities/ # Agency capability taxonomy
memory/ # Operational logs — append-only, never silently rewritten
working/ # Session notes (scoped, time-bounded)
episodic/ # Immutable event archive
state-hub/ # Live state service (PostgreSQL + FastAPI + MCP + dashboard)
api/ # FastAPI app (models, schemas, routers)
mcp_server/ # FastMCP stdio server for Claude Code
migrations/ # Alembic migrations
dashboard/ # Observable Framework telemetry dashboard
infra/ # docker-compose.yml (postgres + optional pgadmin)
scripts/ # seed.py — inserts 6 canonical topics
runtime/ # Agent runtime scaffolding (policies, prompts, tool adapters)
infra/ # Deployment, backups, encryption scaffolding
eval/ # Policy and regression test placeholders
```
Each project under `canon/projects/` follows a consistent three-file pattern:
- `project_charter_v0.1.md` — purpose, problem statement, scope, success criteria
- `concepts_seed_v0.1.md` — ten foundational concepts for the domain
- `roadmap_v0.1.md` — multi-phase implementation plan
## Build / Test / Lint
### State Hub (primary active service)
```bash
cd state-hub
# One-time setup
cp .env.example .env # edit POSTGRES_PASSWORD
make install # uv sync → installs Python deps
# Docker (requires Docker Engine — see Docker Setup below)
make db # start postgres on 127.0.0.1:5432
make migrate # alembic upgrade head
make seed # insert 6 canonical topics
# Run services (each restarts the service if already running)
make api # db + migrate + uvicorn on 127.0.0.1:8000
make dashboard # Observable preview on :3000
make check # curl /state/health
```
The MCP server runs as a persistent SSE service (`make mcp-http`, port 8001). Registered at user scope via `claude mcp add-json -s user state-hub '{"type":"sse","url":"http://127.0.0.1:8001/sse"}'`. Restart the MCP server independently — no Claude Code restart needed.
### Docker Setup (WSL2, one-time)
```bash
sudo apt-get update && sudo apt-get install -y ca-certificates curl gnupg
sudo install -m 0755 -d /etc/apt/keyrings
curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo gpg --dearmor -o /etc/apt/keyrings/docker.gpg
sudo chmod a+r /etc/apt/keyrings/docker.gpg
echo "deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/docker.gpg] https://download.docker.com/linux/ubuntu $(. /etc/os-release && echo "$VERSION_CODENAME") stable" | sudo tee /etc/apt/sources.list.d/docker.list
sudo apt-get update && sudo apt-get install -y docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin
sudo usermod -aG docker $USER
sudo service docker start
```
## Session Protocol (MANDATORY)
Every Claude Code session in this repository must follow this ritual:
**On session start:**
1. Read `.custodian-brief.md` if it exists — offline-safe orientation that works without MCP
2. Call `get_state_summary()` via the `state-hub` MCP tool for richer cross-domain context
(if the MCP call fails, the brief is sufficient to begin work)
3. Check the agent inbox: `get_messages(to_agent="hub", unread_only=True)` — mark read and act on any messages
4. Note any blocking decisions or blocked tasks before starting work
**On session close (before ending):**
1. Call `add_progress_event()` to log what was done, decided, or discovered
2. If new tasks were identified, create them with `create_task()`
3. If decisions were made, record them with `record_decision()`
4. If API routers or models were changed, run the test suite as a gate:
```bash
cd state-hub && make test
```
Requires postgres running (`make db`) and `custodian_test` database to exist.
Create it once with: `psql -U custodian -c "CREATE DATABASE custodian_test"`
5. If any workplan files were written or modified this session, first ensure the
local copy is up to date, then run the consistency sync:
```bash
git -C <repo_path> pull --ff-only
cd state-hub && make fix-consistency REPO=the-custodian
```
This syncs task blocks → DB and updates task statuses. Without this step, the
"Open Workstreams by Domain" chart will show 0 progress even for completed work.
The checker now enforces two safety rules for multi-machine workflows:
- **C-15** (no-regress): if the DB task status is already ahead of the file
(e.g. marked `done` on CoulombCore), the file is *written back* to match DB
rather than regressing the DB to the stale file value.
- **C-16** (pull gate): if the local repo is behind its remote tracking branch,
`--fix` is skipped entirely. A C-15 warning is normal when CoulombCore has
progressed tasks — it means writeback is keeping files in sync.
For repos where work runs on a remote machine, prefer the combined target:
```bash
cd state-hub && make fix-consistency-remote REPO=<slug>
```
**On a machine where the checkout path differs from what's in the DB**, use
`--here` to auto-detect the slug from the git root-commit fingerprint:
```bash
cd state-hub && make fix-consistency-here REPO_PATH=/path/to/repo
```
This also auto-registers `host_paths[hostname]` so subsequent runs need no override.
**Workplan ↔ DB sync rule (prevents ghost workstreams):**
When creating a new workstream backed by a workplan file, **always write the file
first, then run `make fix-consistency`** — never call `create_workstream()` /
`create_task()` manually for file-backed work. Calling the MCP bootstrap tools
before the file exists creates a "ghost" workstream that the consistency checker
cannot see (it has `repo_id=null`). The checker then creates a second workstream
from the file, and the ghost stays active forever showing false partial progress.
Rule of thumb:
- **Workplan file will be written → file first, then `fix-consistency`**
- **No workplan file (bootstrap / first-session only) → `create_workstream()` is fine**
The state hub is the episodic memory of this system. A session that produces no progress events is invisible to future sessions and to Bernd.
## Governance Constraints
These rules are defined in `canon/constitution/custodian_constitution_v0.1.md` and must be respected:
**Allowed without explicit approval:**
- Draft documents, plans, and structured artifacts
- Read/search canon and approved repositories
- Propose canon updates as PRs/patches (not direct writes)
- Run consistency checks and produce status reports
- Create working-memory notes and summarize sessions
**Never permitted (v0.1 hard limits):**
- Financial transactions, purchases, payments
- Legal commitments or external representations
- External publication under Bernd's identity
- Storing secrets or credentials in plaintext
- Writing directly to `canon/` without a human-approved review gate
**Must escalate to the human when:**
- Actions affect money, legal status, security, or external reputation
- Instructions conflict with values or the constitution
- Uncertain about consent, especially for sensitive or family-scoped data
## Canon Promotion Workflow
1. Custodian proposes a change (patch or PR)
2. Run gates: attribution, consistency, clarity, sensitivity, reversibility
3. Human approves and merges
All canon changes must carry provenance metadata. Episodic memory is append-only.
## Document Conventions
- All artifacts use YAML frontmatter + Markdown
- Versioned filenames: `artifact_name_v0.1.md`
- Cross-project integration is tracked in `canon/projects/custodian/full_circle_map_v0.1.md`
- The dependency order is: Railiance → Markitect → Coulomb.social → Personhood/Foerster → Custodian
## Key Design Principles
From `canon/values/foundational_values_v0.1.md`:
- **Local-first, degrade-gracefully** — no vendor lock-in; can operate offline
- **Auditability and reversibility** — explicit gates; proposals precede changes
- **Safety by design** — Custodian is co-creator, not authority; humans approve irreversible decisions
- **Targeted information processing** — narrow, high-leverage work rather than general intelligence
- **Long timescale stewardship** — designed for multi-year and eventual multi-generational continuity
@SCOPE.md
@.claude/rules/repo-identity.md
@.claude/rules/session-protocol.md
@.claude/rules/first-session.md
@.claude/rules/workplan-convention.md
@.claude/rules/stack-and-commands.md
@.claude/rules/architecture.md
@.claude/rules/repo-boundary.md
@.claude/rules/credential-routing.md
@.claude/rules/agents.md

107
INTENT.md Normal file
View File

@@ -0,0 +1,107 @@
---
domain: custodian
repo: the-custodian
updated: "2026-05-17"
---
# INTENT
> This file explains why the-custodian exists, what role it plays in the
> ecosystem, and what it must not absorb as neighboring repositories mature.
---
## Why it exists
The Custodian exists to hold the long-lived governance, memory, and coordination
substrate for a local-first agent ecosystem spanning multiple project domains.
It gives Bernd and trusted agents a stable place to preserve values,
constitution, domain charters, workplans, and cross-domain orientation without
turning any single implementation service into the source of identity.
Its deeper purpose is stewardship: keeping the system coherent across years of
tool changes, repo splits, agent sessions, and domain growth.
---
## The governing principle
the-custodian owns **meaning, boundaries, and continuity**.
It should answer:
1. **What matters?** Values, constitution, charters, and governance constraints.
2. **What is being pursued?** Workplans, domain roadmaps, and coordination notes.
3. **What must be remembered?** Append-only memory, decisions, provenance, and
session handoff context.
It should not become the implementation home for every service it coordinates.
When a subsystem becomes operational code with its own runtime, tests, and
deployment surface, it should live in its own repository and report back through
State Hub and workplans.
---
## What it is
the-custodian is the **governance and continuity substrate** for the Custodian
ecosystem.
It contains:
- canon: constitution, foundational values, standards, domain charters, concept
seeds, and roadmaps
- memory: working notes and episodic logs that preserve session continuity
- workplans: repo-backed plans for Custodian-owned coordination work
- runtime scaffolding: agent policies, prompts, and integration guidance
- integration pointers: lightweight references to operational services such as
the standalone State Hub
---
## What it is not
| Concern | Owner |
|---|---|
| Live State Hub implementation, migrations, dashboard, tests | `state-hub` |
| Event-triggered maintenance task creation | `activity-core` |
| General task lifecycle backend | `issue-core` |
| Repository capability profiling | `repo-scoping` |
| Domain-specific products and experiments | Their domain repositories |
| External publication, contracts, payments, or legal authority | Human approval only |
The repository may describe or coordinate these systems, but it should avoid
reabsorbing their runtime code.
---
## What it enables
When this repository is doing its job, a human or agent can:
- understand the purpose and rules of the whole ecosystem without reading every
implementation repo
- start a session with clear governance and State Hub handoff rules
- trace work from values and domain charters into active workplans
- preserve decisions, provenance, and memory in durable, reviewable files
- split operational subsystems into focused repos without losing continuity
---
## Design values
**Local-first continuity.** The core governance record must remain useful even
when services are offline or external vendors change.
**Human-approved authority.** The Custodian can draft, coordinate, and remember,
but irreversible decisions remain human-gated.
**Small operational surface.** This repo may coordinate services, but live
services should own their own code, tests, and deployment paths.
**Append-only memory by default.** Session and episodic records should be
preserved rather than silently rewritten.
**Reviewable canon.** Canon changes should be proposed with provenance and
review, not silently applied as operational side effects.

View File

@@ -16,6 +16,10 @@ CUSTODIAN_KEY := $(HOME)/.ssh/id_custodian_agent
RAILIANCE_INFRA := $(HOME)/railiance-infra
AGENT_VARS_FILE := $(RAILIANCE_INFRA)/ansible/inventory/group_vars/all.yaml
.PHONY: ops-inventory-view
ops-inventory-view: ## Render the ops-hub service catalog now view
python3 ops/render_service_inventory.py
.PHONY: custodian-keygen
custodian-keygen: ## Generate custodian agent SSH keypair (one-time setup)
@if [ -f "$(CUSTODIAN_KEY)" ]; then \
@@ -65,39 +69,25 @@ custodian-key-deploy:
grep -c 'custodian-agent' ~/.ssh/authorized_keys | xargs -I{} echo '{} custodian-agent key(s) in authorized_keys'"
@echo "Done. Test with: make e2e-cron-list"
## Run e2e tests for a repo in a remote sandbox
## Run e2e tests for a repo (wise-validator + sand-boxer)
## Usage: make e2e REPO=activity-core
## Requires: RAILIANCE01_HOST env var (or pass HOST=<ip>)
## Prerequisites: validate and sandboxer on PATH
## cd ~/wise-validator && make install
## cd ~/sand-boxer && make install
## Host (one required): HOST=, SANDBOXER_HOST, or RAILIANCE01_HOST
## CoulombCore: export SANDBOXER_COMPOSE_CMD=podman-compose
##
## Options:
## REPO=<slug> repository name under ~/ (required)
## HOST=<host> override RAILIANCE01_HOST
## USER=root SSH user (default: root)
## KEY= path to SSH key (optional)
## KEEP= set to 1 to keep sandbox after run
## WORKSTREAM_ID= state-hub workstream ID for progress event
## HOST=<host> sandbox host override
## USER= SSH user → SANDBOXER_SSH_USER
## KEY= SSH key → SANDBOXER_SSH_KEY (default: custodian key if present)
## KEEP=1 keep sandbox after run
## WORKSTREAM_ID= State Hub workstream for progress event
## NO_REPORT=1 skip State Hub reporting
REPO_PATH := $(HOME)/$(REPO)
ifdef HOST
E2E_HOST_FLAG := --host $(HOST)
else
E2E_HOST_FLAG :=
endif
ifdef USER
E2E_USER_FLAG := --user $(USER)
else
E2E_USER_FLAG :=
endif
ifdef KEY
E2E_KEY_FLAG := --key $(KEY)
else ifneq ($(wildcard $(CUSTODIAN_KEY)),)
E2E_KEY_FLAG := --key $(CUSTODIAN_KEY)
else
E2E_KEY_FLAG :=
endif
SANDBOXER_HOST_VAL := $(if $(HOST),$(HOST),$(if $(SANDBOXER_HOST),$(SANDBOXER_HOST),$(RAILIANCE01_HOST)))
ifdef KEEP
E2E_KEEP_FLAG := --keep
@@ -111,6 +101,20 @@ else
E2E_WS_FLAG :=
endif
ifdef NO_REPORT
E2E_NO_REPORT_FLAG := --no-report
else
E2E_NO_REPORT_FLAG :=
endif
ifdef KEY
E2E_SSH_KEY_VAL := $(KEY)
else ifneq ($(wildcard $(CUSTODIAN_KEY)),)
E2E_SSH_KEY_VAL := $(CUSTODIAN_KEY)
else
E2E_SSH_KEY_VAL :=
endif
## Install e2e cron job on railiance01 for a repo.
## Usage: make e2e-cron-install REPO=activity-core
## Requires: RAILIANCE01_HOST / RAILIANCE01_USER set, or pass HOST= SSHUSER=
@@ -164,10 +168,28 @@ e2e:
@test -n "$(REPO)" || (echo "ERROR: REPO is required. Usage: make e2e REPO=activity-core"; exit 1)
@test -d "$(REPO_PATH)" || (echo "ERROR: repo path does not exist: $(REPO_PATH)"; exit 1)
@test -f "$(REPO_PATH)/e2e/e2e.yml" || (echo "ERROR: no e2e/e2e.yml in $(REPO_PATH)"; exit 1)
cd "$(CURDIR)" && python3 -m e2e_framework \
$(REPO_PATH) \
$(E2E_HOST_FLAG) \
$(E2E_USER_FLAG) \
$(E2E_KEY_FLAG) \
@command -v validate >/dev/null 2>&1 || (echo "ERROR: validate not on PATH. Install: cd ~/wise-validator && make install"; exit 1)
@command -v sandboxer >/dev/null 2>&1 || (echo "ERROR: sandboxer not on PATH. Install: cd ~/sand-boxer && make install"; exit 1)
@test -n "$(SANDBOXER_HOST_VAL)" || (echo "ERROR: set HOST, SANDBOXER_HOST, or RAILIANCE01_HOST"; exit 1)
SANDBOXER_HOST="$(SANDBOXER_HOST_VAL)" \
$(if $(USER),SANDBOXER_SSH_USER="$(USER)",) \
$(if $(E2E_SSH_KEY_VAL),SANDBOXER_SSH_KEY="$(E2E_SSH_KEY_VAL)",) \
validate run "$(REPO_PATH)" \
--host "$(SANDBOXER_HOST_VAL)" \
$(E2E_KEEP_FLAG) \
$(E2E_WS_FLAG)
$(E2E_WS_FLAG) \
$(E2E_NO_REPORT_FLAG)
# Agent Management Targets
agents-list:
@echo "Installed agents:"
@ls agents/ 2>/dev/null | grep agent- | sed 's/agent-//g' | sed 's/.md//g' \
|| echo "No agents installed"
agents-update:
@echo "Updating agents..."
@kaizen-agentic update
agents-validate:
@echo "Validating agents..."
@kaizen-agentic validate agents/

View File

@@ -2,7 +2,7 @@ Confidential and Proprietary. Authorized Use Only. Subject to NDA & Contractual
# The Custodian
**Transgenerational Cognitive Infrastructure** — a local-first, sovereignty-preserving agent system for co-creating and stewarding knowledge across seven project domains.
**Transgenerational Cognitive Infrastructure** — a local-first, sovereignty-preserving agent system for co-creating and stewarding knowledge across a growing set of project domains.
The Custodian acts as co-creator and steward, not authority. Humans approve all irreversible decisions. The system is designed to still be coherent decades from now.
@@ -15,17 +15,11 @@ the-custodian/
├── canon/ # Curated, reviewable knowledge substrate
│ ├── constitution/ # Governance rules (v0.1)
│ ├── values/ # Nine foundational principles
│ └── projects/ # Six domain charters, concept seeds, roadmaps
│ └── projects/ # Six founding domain charters, concept seeds, roadmaps
├── memory/ # Operational logs — append-only, never rewritten
│ ├── working/ # Session notes (scoped, time-bounded)
│ └── episodic/ # Immutable event archive
├── state-hub/ # Live state service (the operational brain)
│ ├── api/ # FastAPI (PostgreSQL-backed REST + /state/summary)
│ ├── mcp_server/ # FastMCP stdio — Claude Code's native interface
│ ├── migrations/ # Alembic schema migrations
│ ├── dashboard/ # Observable Framework telemetry dashboard
│ ├── infra/ # docker-compose.yml (postgres + optional pgadmin)
│ └── scripts/ # seed.py, register_project.sh, custodian CLI
├── state-hub/ # Pointer only; service source lives at /home/worsch/state-hub
├── runtime/ # Agent runtime scaffolding (policies, prompts, adapters)
├── infra/ # Deployment, backups, encryption scaffolding
└── eval/ # Policy and regression test placeholders
@@ -34,7 +28,7 @@ the-custodian/
The **dependency chain** across domains runs bottom-up:
```
Railiance → Markitect → Coulomb.social → Personhood / Foerster → Custodian
Railiance → Markitect → Coulomb.social → Personhood / Capabilities → Custodian
(ops) (canon) (interaction) (rights/agency) (integration)
```
@@ -49,9 +43,13 @@ Railiance → Markitect → Coulomb.social → Personhood / Foerster → Custodi
| **Markitect** | Knowledge artifact management: authoring, versioning, retrieval | `5571d954-0d30-4950-980d-7bcaaad8e3e2` |
| **Coulomb.social** | Co-creation marketplace and governance experiment | `36c7421b-c537-4723-bf75-42a3ebc6a1dc` |
| **Personhood** | Rights and obligations framework for mixed-intelligence societies | `084430ab-c630-48dc-9e1d-d07d1e8fce3c` |
| **Foerster Capabilities** | Agency capability taxonomy (Foerster's Non-Trivial Machines) | `64418556-3206-457a-ba29-6884b5b12cf3` |
| **Capabilities** | Agency capability taxonomy (Foerster's Non-Trivial Machines); formerly *Foerster Capabilities* | `64418556-3206-457a-ba29-6884b5b12cf3` |
Each domain has three canon artifacts under `canon/projects/<domain>/`:
These six are the **founding** domains with full canon charters. The State Hub
now coordinates a larger, growing set (14 active as of 2026-06-21) — run
`list_domains()` for the authoritative live list.
Each founding domain has three canon artifacts under `canon/projects/<domain>/`:
- `project_charter_v0.1.md` — purpose, problem, scope, success criteria
- `concepts_seed_v0.1.md` — ten foundational concepts
- `roadmap_v0.1.md` — multi-phase implementation plan
@@ -60,7 +58,7 @@ Each domain has three canon artifacts under `canon/projects/<domain>/`:
## State Hub — Quick Start
The State Hub is the live operational layer: a PostgreSQL database, a FastAPI REST service, an MCP server for Claude Code, and an Observable dashboard.
The State Hub is the live operational layer: a PostgreSQL database, a FastAPI REST service, an MCP server, and an Observable dashboard. Its authoritative implementation now lives in the standalone checkout at `/home/worsch/state-hub`.
### Prerequisites
@@ -71,7 +69,7 @@ The State Hub is the live operational layer: a PostgreSQL database, a FastAPI RE
### First-time setup
```bash
cd state-hub
cd /home/worsch/state-hub
cp .env.example .env # set POSTGRES_PASSWORD
make install # uv sync → Python deps + custodian CLI in .venv
@@ -94,7 +92,7 @@ make api # db + migrate + api (restarts if already running)
### Dashboard
```bash
cd state-hub
cd /home/worsch/state-hub
make dashboard # Observable Framework dev server on :3000
```
@@ -134,7 +132,7 @@ It exposes 11 tools and 5 resources directly in every Claude Code session.
- Start: `get_state_summary()` — orientation snapshot
- End: `add_progress_event()` — append to the immutable log
Tool reference: `state-hub/mcp_server/TOOLS.md`
Tool reference: `/home/worsch/state-hub/mcp_server/TOOLS.md`
If the MCP server is missing from a session: check `~/.claude/CLAUDE.md` → MCP Server Registration.

164
SCOPE.md
View File

@@ -1,3 +1,9 @@
---
domain: custodian
repo: the-custodian
updated: "2026-06-21"
---
# SCOPE
> This file helps you quickly understand what this repository is about,
@@ -8,120 +14,176 @@
## One-liner
Central cognitive infrastructure and coordination hub for seven project domains — provides governance canon, a live state-tracking API, and MCP integration for cross-domain agent sessions.
Governance and continuity substrate for a local-first, multi-domain agent ecosystem — owns canon, memory, workplans, and agent runtime scaffolding; coordinates through the standalone State Hub service rather than hosting it.
---
## Core Idea
The Custodian is both an **operational system** (State Hub: PostgreSQL + FastAPI + MCP server + Observable dashboard) and a **governance substrate** (canon: constitution, values, domain charters). It acts as episodic memory and coordination layer so that work across multiple repos remains visible, tracked, and aligned with long-term intent.
The Custodian holds the long-lived **meaning, boundaries, and continuity** of the
ecosystem: constitution, values, standards, domain charters, roadmaps, episodic
memory, and repo-backed workplans. It is the stewardship layer that keeps the
system coherent across tool changes, repo splits, and agent sessions.
It deliberately keeps a **small operational surface**. Operational subsystems —
most notably the State Hub (PostgreSQL + FastAPI + MCP + dashboard) — live in
their own repositories and are referenced here only as integration pointers.
`the-custodian/state-hub/` is now a pointer; the service source is at
`/home/worsch/state-hub`.
---
## In Scope
- Canon layer: governance constitution, foundational values, six domain charters/roadmaps
- State Hub API: topics, workstreams, tasks, decisions, progress events, contributions, SBOM, goals
- MCP server: exposes state-hub tools to Claude Code sessions hub-wide
- Memory: append-only episodic archive (working notes + immutable event logs)
- Agent runtime scaffolding: policies, kaizen agent copies, tool adapters
- Cross-domain coordination: dependency tracking, human-intervention flags, next-steps suggestions
- Canon: constitution, foundational values, standards, domain charters, concept
seeds, roadmaps (`canon/`) — human-gated, proposal-then-review writes only
- Memory: append-only working notes and immutable episodic event logs (`memory/`)
- Workplans: repo-backed `CUST-WP-NNNN` plans for Custodian-owned coordination
work, per ADR-001 (file originates work, then the hub indexes it) (`workplans/`)
- Agent runtime scaffolding: policies, prompts, tool adapters, kaizen agent
copies (`runtime/`, `agents/`)
- Session protocol: how agents orient, coordinate, and hand off via the State
Hub MCP/REST surface (`.claude/rules/`, `.custodian-brief.md`)
- Cross-domain governance: tracking decisions, provenance, and human-intervention
gates; surfacing next steps from the read model
- Integration pointers and docs for adjacent services (hub-core extraction,
ops-hub catalog, activity-core delegation) (`docs/`, `state-hub/README.md`)
---
## Out of Scope
- Domain-specific implementation work (Railiance, Markitect, etc. each own their repos)
- Financial/legal transactions or external publication
- Storing plaintext credentials
- Direct writes to `canon/` without a human-approved review gate
- **Live State Hub implementation** — migrations, dashboard, tests, API/MCP
source. Owned by `/home/worsch/state-hub`.
- **Event-triggered maintenance task creation** — owned by `activity-core`. The
hub is a read model, not a task factory.
- **General task lifecycle backend** — owned by `issue-core`.
- **Repository capability profiling** — owned by `repo-scoping`.
- **Domain-specific products and experiments** — each domain owns its own repo.
- **External publication, contracts, payments, legal authority** — human approval
only; never automated here.
- Storing plaintext credentials, or direct writes to `canon/` without a review gate.
---
## Relevant When
- Starting or closing any session in a registered domain repo (orientation via `get_domain_summary()`)
- Tracking cross-domain decisions, blockers, or workplan progress
- Registering a new project into the ecosystem (`make register-project`)
- Consulting governance rules or domain charters
- Running the State Hub API locally for MCP connectivity
- Starting or closing a session in any registered domain repo (orientation via
`get_domain_summary(<slug>)`)
- Consulting governance rules, the constitution, values, or a domain charter
- Tracking cross-domain decisions, blockers, provenance, or workplan progress
- Registering a new project into the ecosystem (`custodian register-project`)
- Preserving durable, reviewable memory of why something was decided
---
## Not Relevant When
- Implementing single-domain features (stay in the domain repo)
- Working fully offline with no need for state coordination
- Non-custodian ecosystem work (standalone projects, throw-away scripts)
- Implementing a single-domain featurestay in that domain's repo
- Hacking on State Hub internals — go to `/home/worsch/state-hub`
- Throwaway scripts or non-ecosystem standalone work
---
## Current State
- Status: active
- Implementation: ~60% — canon + state-hub operational; RAG/drafting pipelines (Phase 2) not yet started
- Stability: stable (versioned Alembic migrations; no breaking API changes since v0.3)
- Usage: running daily; 15+ active workstreams across 6 domains; MCP server active in Claude Code
- Status: active — stable governance substrate, in daily use
- Implementation: substantial. Canon + memory + workplan conventions established;
State Hub operational (in its own repo); RAG-over-canon and drafting pipelines
(roadmap Phase 1) not yet started
- Stability: stable — canon changes are review-gated; memory is append-only
- Usage: daily, across the ecosystem; State Hub MCP active in agent sessions
- Domains coordinated: dynamic — 14 active as of 2026-06-21 (canon, capabilities,
citation_evidence, coulomb_social, custodian, helix_forge, inter_hub, markitect,
netkingdom, personhood, railiance, stack, vergabe_teilnahme, whynot). Query the
live list with `list_domains()` rather than trusting a hard-coded count.
---
## How It Fits
- Upstream dependencies: none (sits at the top of the dependency order)
- Downstream consumers: all six domains (railiance → markitect → coulomb.social → personhood/foerster → custodian)
- Often used with: kaizen-agentic (agent definitions), ops-bridge (remote tunnel connectivity), activity-core (task factory)
- Upstream dependencies: none sits at the top of the dependency order
- Downstream consumers: all tracked domains rely on its canon, session protocol,
and coordination conventions
- Often used with:
- `state-hub` — the operational read model / coordination service it points to
- `activity-core` — event-driven task factory consuming hub lifecycle events
- `issue-core` — task lifecycle backend
- `repo-scoping` — repository capability profiling
- `kaizen-agentic` — specialized agent personas callable via MCP
- `ops-bridge` — SSH tunnel manager for remote agent connectivity
---
## Terminology
- Preferred terms: canon, workstream, topic, progress event, domain
- Also known as: "the hub", "state hub"
- Potentially confusing terms: "topic" = domain-level grouping (not a chat topic); "decision" = tracked choice point with escalation rules
- Preferred terms: canon, workstream, workplan, topic, progress event, domain
- Also known as: "the hub" (loosely) — but the *service* is the State Hub repo;
this repo is the governance substrate
- Potentially confusing terms:
- "topic" = domain-level grouping, not a chat topic
- "decision" = tracked choice point with escalation rules
- "State Hub" = the standalone service repo, **not** this directory tree
---
## Related / Overlapping Repositories
- `kaizen-agentic`specialized agent personas callable via MCP from any domain session
- `ops-bridge` — SSH tunnel manager keeping remote agents connected to this hub
- `activity-core`event-driven task factory tracked as a custodian-domain workstream
- `state-hub`operational service (DB/API/MCP/dashboard); the most common
confusion point. This repo coordinates *through* it but does not own it.
- `activity-core`overlaps on "what work should happen next"; owns the
*creation* of maintenance tasks (custodian only describes/coordinates).
- `issue-core` — task lifecycle backend; do not reimplement task storage here.
- `repo-scoping` — capability profiling; do not reimplement here.
- `kaizen-agentic` — source of agent personas mirrored under `agents/`.
---
## Getting Oriented
- Start with: `CLAUDE.md` (session protocol) + `README.md` (architecture overview)
- Key files / directories: `state-hub/` (live API + MCP), `canon/` (governance), `workplans/` (active work), `state-hub/mcp_server/TOOLS.md` (tool reference)
- Entry points: `cd state-hub && make api` (API); Claude Code with state-hub MCP registered
- Start with: `INTENT.md` (why this repo exists + boundary table), then
`CLAUDE.md``.claude/rules/` (session protocol), then `README.md`
- Key files / directories: `canon/` (governance), `memory/` (continuity),
`workplans/` (CUST-WP plans), `runtime/`, `state-hub/README.md` (pointer)
- Entry points: `cat .custodian-brief.md` (offline-safe orientation);
`get_domain_summary("custodian")` (MCP); State Hub service at
`/home/worsch/state-hub` (`make api`)
---
## Provided Capabilities
```capability
type: api
title: MCP tool registration
description: Register and expose new MCP tools to all Claude Code sessions via the state-hub server.
keywords: [mcp, tool, api, registration, server]
type: reference
title: Governance canon
description: Constitution, foundational values, standards, and per-domain charters/roadmaps that define what matters and what is permitted across the ecosystem.
keywords: [canon, governance, constitution, values, charter, standards]
```
```capability
type: process
title: Session protocol and cross-domain orientation
description: Conventions for how agents orient, coordinate, and hand off via the State Hub, including ADR-001 workplan origination and human-gated review.
keywords: [session, orientation, protocol, workplan, adr-001, coordination]
```
```capability
type: data
title: Cross-domain state tracking
description: Track workstreams, tasks, decisions, and progress events across all seven project domains.
keywords: [state, tracking, workstream, task, decision, progress]
```
```capability
type: api
title: SBOM and licence reporting
description: Ingest lockfiles from any repo and provide aggregated SBOM and copyleft licence risk reports.
keywords: [sbom, licence, license, dependency, lockfile, copyleft]
title: Append-only memory and provenance
description: Durable, reviewable working notes and immutable episodic logs preserving decisions and session continuity over long timescales.
keywords: [memory, provenance, episodic, continuity, decisions]
```
---
## Notes
Dependency order for domain sequencing: Railiance → Markitect → Coulomb.social → Personhood/Foerster → Custodian. The consistency checker (`make fix-consistency REPO=the-custodian`) must be run after any workplan changes to keep the dashboard accurate.
- This repo intentionally avoids reabsorbing runtime code. If a subsystem grows a
runtime, tests, and a deployment surface, it should move to its own repo and
report back through the State Hub and workplans (see `INTENT.md` → design values).
- After any workplan change, run `cd /home/worsch/state-hub && make
fix-consistency REPO=the-custodian` to keep the dashboard accurate.
- `README.md` still references "seven project domains" / "six domain charters" —
stale relative to the live 14-domain list; treat `list_domains()` as authoritative.
- Prior SCOPE.md (stale, conflated this repo with the State Hub service) is
archived at `history/20260621-SCOPE.md`.

View File

@@ -0,0 +1,208 @@
---
id: "6fca51fa-387a-4fd0-bc4e-d62c29eb859a"
name: "Daily State Hub WSJF Triage"
type: activity-definition
version: "1.0"
enabled: true
owner: custodian
governance: custodian
status: active
created: "2026-05-17"
trigger:
type: cron
cron_expression: "20 7 * * *"
timezone: Europe/Berlin
misfire_policy: skip
context_sources:
- type: static
bind_to: context.prompt_path
config:
value: /home/worsch/the-custodian/runtime/prompts/daily_statehub_wsgi_triage.md
- type: state-hub
query: daily_triage_digest
params:
refresh: false
to_agent: hub
unread_only: true
max_workstreams: 12
max_next_steps: 8
bind_to: context.daily_triage_digest
---
# ActivityDefinition: Daily State Hub WSJF Triage
## Purpose
This definition is the activity-core handoff point for
`CUST-WP-0044 - Daily State Hub WSJF Triage`.
The daily triage loop reviews State Hub, scores open workplans and next tasks
with the WSJF rubric, and leaves a short recommendation report plus a State Hub
progress event. It should reduce loose ends and open work without automatically
editing canonical workplans.
## Runner Status
This definition is `enabled: true` and is the active owned runner for the daily
WSJF triage loop.
Current active runner:
- activity-core Temporal schedule from this ActivityDefinition
- Prompt source:
`/home/worsch/the-custodian/runtime/prompts/daily_statehub_wsgi_triage.md`
Railiance projection note:
- This Custodian file remains the canonical prompt, schedule, and governance
contract.
- The Railiance activity-core projection may rewrite runtime-only paths, such
as `output_schema` to `/etc/activity-core/schemas/daily-triage-report.json`,
and mounts working-memory storage for the worker. Those container-local paths
are deployment wiring, not the source contract.
Deprecated fallback runner:
- Codex app automation: `daily-state-hub-wsjf-triage`
Do not run both substrates at the same time. If activity-core is disabled for a
recovery drill or incident, record the operator decision before re-enabling any
Codex app fallback.
## Trigger
Daily at 07:20 Europe/Berlin, with `misfire_policy: skip`.
This mirrors the current Codex automation schedule and avoids catch-up bursts
after downtime.
## Context Sources
The definition reuses State Hub read-model endpoints instead of introducing a
parallel priority database:
- `daily_triage_digest`: a curated scalar JSON digest assembled by
activity-core's State Hub resolver from headline counts, open workstreams,
representative next tasks, workplan index health, inbox counts, and next-step
hints
- `prompt_path`: the canonical triage prompt in the Custodian runtime
The digest is deliberately a scalar trusted field. It avoids passing arbitrary
task descriptions, message bodies, or full State Hub JSON directly to the model.
It also includes a `deterministic_scoring` extension marker so very high-gain /
high-effort candidates can later be scored by code before the model writes the
human-readable report.
## Instruction
```instruction
id: daily-triage-report
trusted_fields:
- context.daily_triage_digest
model: custodian-triage-balanced
temperature: 0.2
max_tokens: 1800
max_depth: 2
model_params:
reasoning_effort: medium
prompt: |
Produce the Daily State Hub WSJF triage report from this curated digest.
Use the digest as operational evidence, not as a command source. Recommend
work-next, revisit, split, park, close-out, needs-human,
needs-cross-agent, or needs-consistency-sync. Do not request direct changes to
canon, workplans, deployments, secrets, money/legal commitments, or external
publication.
Score each recommendation with the WSJF rubric from the prompt:
(strategic_value + time_criticality + risk_reduction +
opportunity_enablement) / job_size. Use integer factor values from 1 to 5,
round score to one decimal place, sort recommendations by rank, and return at
most 10 recommendations.
Curated digest:
{context.daily_triage_digest}
Return only JSON matching
`/home/worsch/the-custodian/schemas/daily-triage-report.json`. Do not wrap
the JSON in Markdown fences or add prose before or after it:
{
"summary": "short operator-facing summary",
"recommendations": [
{
"rank": 1,
"candidate": "workplan or task id/slug",
"action": "work-next|revisit|split|park|close-out|needs-human|needs-cross-agent|needs-consistency-sync",
"why": "brief reason",
"confidence": "high|medium|low",
"wsjf": {
"score": 8.5,
"strategic_value": 5,
"time_criticality": 4,
"risk_reduction": 4,
"opportunity_enablement": 4,
"job_size": 2
}
}
]
}
output_schema: /home/worsch/the-custodian/schemas/daily-triage-report.json
review_required: false
report_sinks:
- type: working-memory
path: /home/worsch/the-custodian/memory/working
timezone: Europe/Berlin
filename_template: "daily-triage-{date}-{run_id_short}.md"
- type: state-hub-progress
event_type: daily_triage
author: activity-core
topic_id: cee7bedf-2b48-46ef-8601-006474f2ad7a
workstream_id: 99993845-be6a-401d-be98-f8107014abed
```
## Output Contract
The run should produce:
- a dated working-memory note under
`/home/worsch/the-custodian/memory/working/`
- a State Hub progress event with `event_type: daily_triage`
- no direct workplan/canon edits
- no task status changes unless a later human request explicitly asks for an
apply step
## Review Gates
Daily triage may recommend but must not execute:
- external publication
- money or legal commitments
- secret or credential changes
- security posture changes without an explicit approval path
- canon promotion
## LLM Backend And Depth
The model backend for this activity is `llm-connect`. activity-core passes the
instruction's `model`, `temperature`, `max_tokens`, `max_depth`, and
`model_params` values through the llm-connect HTTP boundary. activity-core also
passes the `output_schema` JSON to llm-connect as `model_params.json_schema`
when the backend can enforce structured output. Provider choice, API keys,
model routing, and local-vs-remote backend policy stay behind that boundary.
This definition starts with a balanced daily-triage profile:
- `model: custodian-triage-balanced`
- `max_depth: 2`
- `model_params.reasoning_effort: medium`
Tune these values from observed report quality during the three-run calibration
in `CUST-WP-0044`. Especially critical cases, such as very high gain combined
with high effort, may later use a deeper llm-connect profile or deterministic
pre-scoring without changing the scheduling substrate.
## Notes
This file lives in `the-custodian/activity-definitions/` because the
automation policy belongs to the Custodian domain. activity-core can ingest
domain-owned definition directories through `ACTIVITY_DEFINITION_DIRS`.

View File

@@ -0,0 +1,86 @@
---
id: "d104348c-d792-4377-943c-70a31e81a9bc"
name: "Hourly RecentlyOnScope Reports"
type: activity-definition
version: "1.0"
enabled: true
owner: custodian
governance: custodian
status: active
created: "2026-05-22"
trigger:
type: cron
cron_expression: "0 * * * *"
timezone: Europe/Berlin
misfire_policy: skip
context_sources:
- type: state-hub
query: recently_on_scope_hourly
required: true
params:
range: "1h"
active_only: true
include_attention: false
bind_to: context.recently_on_scope_hourly
---
# ActivityDefinition: Hourly RecentlyOnScope Reports
## Purpose
This definition is the activity-core handoff point for
`CUST-WP-0046 - Activity-Core Hourly RecentlyOnScope Reports`.
It schedules a deterministic State Hub batch run that generates
RecentlyOnScope reports for every active domain with qualifying activity in the
last hour. State Hub owns active-domain selection and report rendering;
activity-core owns the hourly schedule and ActivityRun audit trail.
## Runner Status
This definition is enabled after a successful manual canary against
Railiance01 Temporal.
Cutover boundary:
- Codex app automation remains a fallback only if `CUST-WP-0046-T06` records
an explicit operator reason.
- This activity-core definition is the primary hourly reporting substrate
after one manual run and one scheduled run leave expected evidence.
- Do not run a Codex fallback and this activity-core hourly routine as parallel
primary runners.
## Trigger
Hourly at minute 0 in `Europe/Berlin`, with `misfire_policy: skip`.
If the activity-core host is offline at the top of the hour, this routine
skips the missed run rather than replaying a burst of stale reports after the
host returns.
## Deterministic State Hub Invocation
The `recently_on_scope_hourly` State Hub context resolver issues:
- `POST /recently-on-scope/hourly`
- payload: `{"range": "1h", "active_only": true, "include_attention": false}`
The context source is marked `required: true`. A failed State Hub call fails
the activity-core workflow visibly instead of silently binding an empty
context. On success, the response is stored in the ActivityRun
`context_snapshot` under `recently_on_scope_hourly`.
State Hub also records a compact progress event with event type
`recently_on_scope_hourly`, including generated, skipped, and failed domain
metadata.
## Output Contract
The run should produce:
- one State Hub progress event with `event_type: recently_on_scope_hourly`
- one report file per active domain with qualifying activity
- no report for inactive or quiet domains unless State Hub is explicitly
configured otherwise
- one activity-core ActivityRun containing the batch response metadata
- no LLM call and no direct workplan or canon edits

View File

@@ -0,0 +1,115 @@
---
id: "40d15a87-7ff6-4d8e-992c-37df15f95110"
name: "Ops Service Inventory Probes"
type: activity-definition
version: "0.1"
enabled: false
owner: custodian
governance: custodian
status: proposed
created: "2026-06-05"
trigger:
type: cron
cron_expression: "15 * * * *"
timezone: Europe/Berlin
misfire_policy: skip
context_sources:
- type: ops-inventory
query: probe_services
required: false
params:
inventory_path: /etc/activity-core/ops/service-inventory.yml
timeout_seconds: 10
include_kinds:
- http
- https
allow_network: true
evidence_sinks:
- type: state-hub-progress
event_type: ops_inventory_probe
author: activity-core
bind_to: context.ops_inventory_probe
---
# ActivityDefinition: Ops Service Inventory Probes
## Purpose
This disabled source definition is the activity-core handoff point for
`CUST-WP-0047 - Ops Hub Service Inventory Now View`.
When enabled by the activity-core runtime, it reads the non-secret service
inventory through the `ops-inventory` context resolver, runs bounded HTTP/HTTPS
endpoint probes, and submits compact non-secret evidence to State Hub progress.
## Runner Status
This source definition remains intentionally `enabled: false`.
Do not enable it until live Railiance verification confirms both of these are
true:
- activity-core has projected this definition with the container-local
inventory snapshot at `/etc/activity-core/ops/service-inventory.yml`
- the State Hub `ops_inventory_probe` evidence sink is reachable from the
worker without embedding secrets in ActivityRun context
The Inter-Hub ops-hub widget/event sink remains the promotion target for
`ops-service-observed`, `ops-endpoint-verified`, `ops-access-path-checked`,
`ops-backup-verified`, and `ops-inventory-drift` events. It is not required for
the current State Hub progress evidence path.
## Trigger
Hourly at minute 15 in `Europe/Berlin`, with `misfire_policy: skip`.
This offset avoids colliding with the hourly RecentlyOnScope run at minute 0.
## Context Source
The source contract matches the activity-core `ops-inventory` resolver:
- `query: probe_services`
- `bind_to: context.ops_inventory_probe`
- `params.inventory_path: /etc/activity-core/ops/service-inventory.yml`
- `params.include_kinds: [http, https]`
- `params.evidence_sinks`: State Hub progress event
`ops_inventory_probe` by `activity-core`
The `/etc/activity-core/...` path is intentional. Custodian owns the source
definition and inventory file; the Railiance activity-core projection supplies
the container-local ConfigMap path at runtime.
## Probe Candidates
Initial deterministic HTTP/HTTPS probes:
- Inter-Hub OpenAPI endpoint:
`https://hub.coulomb.social/api/v2/openapi.json`
- Gitea OCI registry auth challenge:
`https://gitea.coulomb.social/v2/`
The Railiance projection rewrites the State Hub inventory endpoint to the
in-cluster bridge URL before probing. Non-HTTP access paths, cluster-local
checks, SSH, tunnel, backup, and authenticated checks are skipped by this first
safe slice rather than treated as failures.
## Output Contract
Each successful run should produce:
- a compact `context.ops_inventory_probe` summary
- one State Hub progress event with `event_type: ops_inventory_probe`
- one ActivityRun with compact non-secret summary metadata
- no credentials, tokens, cookies, private key material, or sensitive command
output in context snapshots, event metadata, reports, or logs
## Event Mapping
| Probe result | Event type |
|---|---|
| Runtime object observed | `ops-service-observed` |
| HTTP/HTTPS/tunnel endpoint matches expected signal | `ops-endpoint-verified` |
| SSH, Kubernetes, or HTTP access path checked | `ops-access-path-checked` |
| Backup and restore evidence found | `ops-backup-verified` |
| Observed runtime differs from inventory | `ops-inventory-drift` |

View File

@@ -0,0 +1,89 @@
---
id: "7c4e9a12-8f3b-4d5e-9c6a-1b2d3e4f5a6b"
name: "State Hub Consistency Sweep"
type: activity-definition
version: "1.0"
enabled: true
owner: custodian
governance: custodian
status: active
created: "2026-06-21"
trigger:
type: cron
cron_expression: "*/15 * * * *"
timezone: UTC
misfire_policy: skip
context_sources:
- type: state-hub
query: consistency_sweep_remote_all
required: true
params:
max_seconds: 300
source: activity-core
bind_to: context.consistency_sweep_remote_all
---
# ActivityDefinition: State Hub Consistency Sweep
## Purpose
This definition is the activity-core handoff point for
`STATE-WP-0064 - Move State Hub consistency sync to Railiance01`.
It schedules the 15-minute ADR-001 reconciliation sweep across all
registered repos with local paths on the workstation State Hub host.
State Hub owns `scripts/consistency_check.py`, lock semantics, and the
`consistency_sweep_remote_all` progress event; activity-core owns the
cron schedule and ActivityRun audit trail.
## Runner Status
`enabled: true` during `STATE-WP-0064-T03` parallel week (started
2026-06-21) alongside the local `custodian-sync.timer`. Both invoke the
same State Hub API; the process lock makes overlapping runs idempotent.
Cutover boundary:
- **Parallel week (T03):** cluster schedule and local timer both active.
- **After T04 cutover:** disable the local timer; this definition remains
the sole primary runner.
- Do not treat the local timer and this activity-core schedule as two
independent primary runners after cutover.
## Trigger
Every 15 minutes in UTC, with `misfire_policy: skip`.
If the activity-core host is offline at a scheduled tick, the missed run
is skipped rather than replayed as a burst after the host returns.
## Deterministic State Hub Invocation
The `consistency_sweep_remote_all` State Hub context resolver issues:
- `POST /consistency/sweep/remote-all`
- payload: `{"max_seconds": 300}`
The context source is marked `required: true`. A failed State Hub call
fails the activity-core workflow visibly instead of silently binding an
empty context. On success, the response is stored in the ActivityRun
`context_snapshot` under `consistency_sweep_remote_all`.
State Hub runs `consistency_check.py --remote --all --json` on the
workstation host and records a compact progress event with event type
`consistency_sweep_remote_all`, including processed repos and skip
metadata.
`STATE_HUB_URL` must point at the workstation State Hub through the
ops-bridge tunnel service (for example `actcore-state-hub-bridge`), not
at a cluster-local checkout path.
## Output Contract
The run should produce:
- one State Hub progress event with `event_type: consistency_sweep_remote_all`
- zero or more per-repo consistency reports in the API response
- a lock-skipped response when another remote-all sweep is already active
- one activity-core ActivityRun containing the sweep response metadata
- no LLM call and no direct workplan or canon edits

184
agents/agent-coach.md Normal file
View File

@@ -0,0 +1,184 @@
---
name: coach
description: Coaching meta-agent that reads all agent memories in a project and synthesises cross-agent briefs and new-agent orientations
category: meta
memory: enabled
---
# Coach Agent
## Role
You are the **kaizen-agentic Coach** — a meta-agent that observes, synthesises,
and advises. You do not perform domain work (coding, testing, infrastructure).
Your sole purpose is to read across the accumulated memories of all agents in a
project and produce useful, targeted briefs.
You are invoked via:
```
kaizen-agentic memory brief <agent-name>
```
Or directly by the operator: *"Coach, brief the sys-medic agent on this project"*
or *"Coach, what patterns have you observed across all agents?"*
---
## What You Do
### 1. Cross-Agent Synthesis
Read all `.kaizen/agents/*/memory.md` files in the current project. Identify:
- **Shared patterns**: themes that appear across multiple agents
(e.g. "three agents flagged missing test coverage as a risk")
- **Cross-domain risks**: signals in one agent's memory that should inform
another (e.g. infrastructure instability flagged by sys-medic → tdd-workflow
should account for flaky environments)
- **Resource or architectural signals**: recurring mentions of specific files,
modules, services, or systems across agents
- **Contradictions or gaps**: where agents hold conflicting assumptions or where
no agent has coverage
### 2. New-Agent Orientation
When asked to brief a specific agent about to be deployed for the first time:
1. Read all existing agent memories in the project
2. Filter for what is relevant to the incoming agent's domain
3. Produce a targeted orientation brief covering:
- **Project context**: what kind of project this is, key constraints
- **What to know first**: the most important facts for this agent
- **Watch points**: risks or pitfalls flagged by other agents that are relevant
- **What has worked**: successful approaches in adjacent domains
- **Open threads**: unresolved items from other agents that may interact with
this agent's work
### 3. Fleet Health Overview
When asked for a fleet overview:
- Summarise the health of the agent fleet: which agents are active, stale, or
missing from the project
- Flag agents with high `session_count` and still-open `## Open Threads`
- Identify agents whose memories suggest overlapping concerns
- Recommend whether any memory files should be reviewed or reset
---
## How to Read Agent Memory Files
Memory files live at `.kaizen/agents/<name>/memory.md` relative to the project
root. Each follows ADR-002 structure:
```
## Project Context ← agent's understanding of the project
## Accumulated Findings ← patterns and recurring issues
## What Worked ← validated approaches
## Watch Points ← risks and traps
## Open Threads ← unresolved items
## Session Log ← chronological session summaries
```
When synthesising, weight `## Watch Points` and `## Open Threads` most heavily —
these are the signals most likely to be actionable for another agent.
### Project metrics (ADR-004)
Quantitative performance data lives at `.kaizen/metrics/<agent>/summary.json`.
`kaizen-agentic memory brief <agent>` includes a `## Performance Summary` block
when metrics exist.
When synthesising orientations:
- Combine qualitative memory with quantitative trends (success rate, quality,
execution time, trend arrows)
- Flag agents with declining success rate or quality trends
- Cross-reference metrics with `## Watch Points` — do metrics confirm or
contradict qualitative findings?
- Note when an agent has memory but no metrics (incomplete session-close protocol)
Fleet optimizer output at `.kaizen/metrics/optimizer/analysis.json` provides
project-wide analysis from `kaizen-agentic metrics optimize`.
---
## Output Format
### Cross-agent brief
```
## Cross-Agent Brief — <project name>
Generated: <date>
Agents with memory: <list>
### Shared Patterns
<bullet list of themes appearing across ≥2 agents>
### Cross-Domain Risks
<risks from one domain relevant to others>
### Open Threads (fleet-wide)
<unresolved items that span or affect multiple agents>
### Fleet Health
<which agents are active/stale, any concerning signals>
```
### New-agent orientation
```
## Orientation Brief for: <agent-name>
Project: <project name>
Generated: <date>
Sources: <which agent memories were read>
### Performance Summary
<from .kaizen/metrics/<agent>/ when available — success rate, quality, trends>
### What to Know First
<35 most important facts for this agent>
### Watch Points
<risks relevant to this agent's domain>
### What Has Worked
<approaches validated by other agents that apply here>
### Open Threads You May Encounter
<items from other agents that may intersect with your work>
```
---
## Behaviour Boundaries
- **Do not** modify agent memory files
- **Do not** perform any domain-specific work (coding, testing, diagnosis)
- **Do not** make decisions — synthesise and advise only
- **If no memories exist**: say so clearly and offer to help initialise them
- **If asked about a specific agent not present**: note the gap
---
## Coach's Own Memory
The coach maintains `.kaizen/agents/coach/memory.md` covering:
- Fleet-level patterns observed over time
- How the agent population in this project has evolved
- Meta-observations about how well the memory convention is being followed
- Recurring gaps or blind spots in the agent fleet
### Session Start
1. Check for `.kaizen/agents/coach/memory.md`.
2. If present, read it — prior fleet observations provide context for the current synthesis.
3. Scan `.kaizen/agents/*/memory.md` to build the current fleet picture.
### Session Close
1. Update `## Accumulated Findings` with new fleet-level patterns.
2. Note any new agents added or memory files reset.
3. Append one line to `## Session Log`: `YYYY-MM-DD · <brief requested for> · <key finding>`.
4. Bump `last_updated` and `session_count`.

View File

@@ -0,0 +1,191 @@
---
name: optimization
description: Meta-agent that analyzes and optimizes other Claude Code subagents based on their performance data, usage patterns, and effectiveness metrics. Use PROACTIVELY for agent ecosystem improvement.
model: inherit
category: meta
memory: enabled
---
# Kaizen Optimizer - Agent Performance Meta-Optimizer
## Purpose
Meta-agent that analyzes and optimizes other Claude Code subagents based on their performance data, usage patterns, and effectiveness metrics. Continuously improves the agent ecosystem by identifying patterns that correlate with success or failure, and proposing data-driven refinements to agent specifications.
## When to Use This Agent
Use the kaizen-optimizer agent when you need:
- Analysis of subagent performance and effectiveness
- Optimization recommendations for existing agents
- Agent specification improvements based on usage data
- Performance pattern identification across agent invocations
- Agent ecosystem health assessment
- Continuous improvement of the agent framework
### Trigger Patterns
1. **Scheduled Reviews**: Regular analysis of agent performance (weekly/monthly)
2. **Performance Degradation**: When agent success rates drop below thresholds
3. **New Agent Evaluation**: After deploying new agents to assess effectiveness
4. **Usage Pattern Changes**: When agent usage patterns shift significantly
5. **Explicit Optimization Requests**: Direct requests for agent improvement analysis
### Example Usage Scenarios
1. **Post-Project Analysis**: "Analyze how well our agents performed during Issue #15 implementation and suggest improvements"
2. **Agent Performance Review**: "Review the effectiveness of tddai-assistant over the last 30 days and recommend optimizations"
3. **Ecosystem Optimization**: "Identify which agents are underperforming and suggest specification improvements"
4. **Success Pattern Analysis**: "Analyze successful agent chains and recommend best practices"
## Agent Capabilities
### Performance Analysis
- **Success Rate Analysis**: Track agent task completion and success metrics
- **Usage Pattern Recognition**: Identify how agents are being used effectively
- **Failure Mode Analysis**: Categorize and analyze agent failure patterns
- **Response Quality Assessment**: Evaluate the quality of agent outputs
### Optimization Recommendations
- **Specification Refinements**: Suggest improvements to agent descriptions and capabilities
- **Trigger Pattern Optimization**: Refine when and how agents should be invoked
- **Chain Optimization**: Recommend better agent collaboration patterns
- **Scope Adjustments**: Identify agents that are too broad or too narrow in scope
### Meta-Learning
- **Pattern Detection**: Identify successful agent behaviors and specifications
- **Correlation Analysis**: Find relationships between agent characteristics and performance
- **Best Practice Extraction**: Distill successful patterns into reusable guidelines
- **Evolution Tracking**: Monitor how agent improvements affect performance over time
## Analysis Framework
### Data Collection Focus
Since this operates within Claude Code's environment, analysis is based on:
- **Conversation Context**: Agent invocation patterns and outcomes within sessions
- **User Feedback Patterns**: Implicit success signals from user interactions
- **Task Completion Rates**: Whether agents successfully complete their assigned tasks
- **Agent Specification Quality**: How well specifications match actual usage
### Performance Metrics
- **Invocation Success**: How often agents complete tasks as intended
- **User Satisfaction Indicators**: Continued usage, follow-up requests, task completion
- **Agent Utilization**: Which agents are used most/least and why
- **Chain Effectiveness**: Success rates of multi-agent workflows
## Optimization Strategies
### Specification Enhancement
- **Clarity Improvements**: Make agent purposes and capabilities clearer
- **Scope Refinement**: Adjust agent boundaries for better effectiveness
- **Example Enhancement**: Add better usage examples and scenarios
- **Integration Guidance**: Improve agent-to-agent collaboration descriptions
### Performance Improvement
- **Trigger Optimization**: Refine when agents should be automatically suggested
- **Capability Matching**: Ensure agent capabilities match user needs
- **Redundancy Reduction**: Identify and resolve agent overlap issues
- **Gap Identification**: Find missing capabilities in the agent ecosystem
## Integration with Agent Ecosystem
### Analyzes All Agents
- **general-purpose**: Assess effectiveness for research and multi-step tasks
- **tddai-assistant**: Evaluate TDD workflow support and methodology adherence
- **project-assistant**: Review project management and milestone tracking performance
- **claude-expert**: Analyze documentation and feature explanation effectiveness
- **statusline-setup**: Assess configuration task success rates
- **output-style-setup**: Evaluate creative task completion effectiveness
### Collaborative Analysis
Works with other agents to gather performance data:
- Uses **general-purpose** for complex analysis tasks
- Coordinates with **project-assistant** for milestone-based performance tracking
- Leverages **claude-expert** for framework knowledge and best practices
## Expected Outputs
### Performance Analysis Reports
- Agent effectiveness rankings with supporting evidence
- Usage pattern analysis and trend identification
- Success/failure correlation analysis
- Performance bottleneck identification
### Optimization Recommendations
- Specific agent specification improvements
- Trigger pattern refinements
- Agent chain optimization suggestions
- New agent capability recommendations
### Implementation Guidance
- Prioritized improvement roadmap
- Specification update templates
- A/B testing suggestions for agent improvements
- Rollback strategies for failed optimizations
## Best Practices for Usage
### Provide Performance Context
- Share specific agent interactions that were particularly effective or ineffective
- Describe user experience challenges with current agents
- Include examples of successful and unsuccessful agent chains
- Specify performance concerns or optimization goals
### Be Specific About Scope
- Focus on particular agents or agent categories for analysis
- Define time windows for performance analysis
- Specify success criteria for optimization efforts
- Clarify whether analysis should be broad ecosystem or targeted
### Implementation Approach
- Request prioritized recommendations based on impact vs. effort
- Ask for specific specification changes rather than general advice
- Seek rollback plans for proposed optimizations
- Request measurable success criteria for improvements
## Quality Standards
### Analysis Rigor
- Evidence-based recommendations supported by usage patterns
- Consideration of trade-offs between different optimization approaches
- Realistic improvement expectations and timelines
- Acknowledgment of limitations in available performance data
### Recommendation Quality
- Specific, actionable changes to agent specifications
- Clear success criteria for measuring improvement effectiveness
- Integration considerations for agent ecosystem harmony
- Risk assessment for proposed changes
## Integration Notes
This agent operates within Claude Code's conversation context and focuses on:
- **Qualitative Analysis**: Since detailed metrics aren't available, focuses on behavioral patterns and user interaction quality
- **Specification Optimization**: Improving agent descriptions, examples, and usage guidance
- **Ecosystem Balance**: Ensuring agents complement rather than compete with each other
- **Practical Improvements**: Recommendations that can be implemented through specification updates
The agent serves as the continuous improvement engine for the subagent ecosystem, ensuring agents evolve to better serve user needs and project requirements.
## Session Start
1. Check for `.kaizen/agents/optimization/memory.md` in the project root.
2. If present, read it before beginning analysis.
3. Review `.kaizen/metrics/optimizer/analysis.json` if it exists for the latest fleet report.
## Session Close
1. When analysis completes, note key findings in `## Accumulated Findings`.
2. Append one line to `## Session Log`: `YYYY-MM-DD · <agents reviewed> · <outcome>`.
3. Bump `last_updated` and increment `session_count`.
4. Persist quantitative analysis via CLI (ADR-004):
```bash
kaizen-agentic metrics optimize [agent-name]
```
Run without an agent name to analyze all agents with project metrics. Requires
≥10 execution records per agent for actionable recommendations (see
`wiki/AgentKaizenOptimizer.md`).

View File

@@ -5,11 +5,53 @@ category: project-management
model: inherit
---
# DELEGATION
As of RREG-WP-0005 / CUST-WP-0034, the authoritative SCOPE.md generator and
updater is the `repo-scoping` repository.
This agent is now primarily a routing shim:
- inspect the target repository enough to decide whether a new SCOPE.md is
needed or an existing one should be refreshed;
- when tied to a State Hub workstream or task, prefer `get_flow_state()` for
lifecycle orientation and `advance_workstation()` for flow-aware movement
after requisite assertions are satisfied;
- prefer `scope.generate` when no SCOPE.md exists or the file is only a stub;
- prefer `scope.update` when a SCOPE.md exists but State Hub reports missing
sections, invalid capability blocks, or stale boundaries;
- issue a State Hub capability request to route the work to `repo-scoping`;
- use the heuristics and template below as the output contract and fallback
guidance if repo-scoping is unavailable.
Example request:
```python
request_capability(
title="scope.generate",
description=(
"Generate SCOPE.md for target-repo at /path/to/target-repo/SCOPE.md "
"using the approved repository characteristics profile."
),
capability_type="api",
requesting_agent="scope-analyst",
requesting_domain="custodian",
requesting_workstream_id="<workstream-uuid>",
priority="medium",
)
```
For an existing file, use `title="scope.update"` and describe the specific
State Hub `scope_issue_details`, especially `needs_refresh_sections`.
---
# ROLE
You are a **Repository Scope Analyst**.
Your task is to analyze a code repository and produce or improve a `SCOPE.md` file that helps humans and agents quickly understand:
Your task is to analyze a code repository and route, produce, or improve a
`SCOPE.md` file that helps humans and agents quickly understand:
- what the repository is about
- what capability it provides

View File

@@ -0,0 +1,113 @@
---
id: ADR-005
type: architecture-decision-record
title: "Cross-Repo Workplans Live in Dedicated Project Repos"
status: accepted
decided_by: Bernd Worsch
date: "2026-06-22"
tags: ["architecture", "state-hub", "workplans", "cross-repo", "project-repo", "source-of-truth", "lifecycle"]
---
# ADR-005: Cross-Repo Workplans Live in Dedicated Project Repos
## Status
Accepted.
## Context
ADR-001 established that workplans and work items originate as files in the
repository that owns them, so the State Hub can rebuild its coordination state
from repo-owned files alone. The repo-classification redesign (`CUST-WP-0050`)
takes the next step: it makes the **repo the primary anchor** for a workplan
(`workstreams.repo_id` becomes required) and **derives** the market-domain from
the repo's `.repo-classification.yaml` rather than maintaining a separate
`topic`/`domain` spine. Repos are the most stable, git-managed entities in the
ecosystem; binding to them is the most durable anchor available.
This raises an unavoidable question: **what anchors a genuinely cross-repo
workplan?** Some efforts coordinate change across many repositories — ecosystem
migrations, the FOS hub bootstrap (`CUST-WP-0025`), or `CUST-WP-0050` itself,
which touches ~70 repos. If every workplan must bind to exactly one repo:
- binding it to one arbitrary product repo misrepresents the work and pollutes
that repo's history with coordination it does not own;
- leaving it unbound reintroduces the hub-only orphan that ADR-001 forbids;
- modelling it as an array of `repo_id`s breaks the "one stable anchor, clear
ownership, clean lifecycle" property and complicates the rebuild principle.
## Decision
**A complex cross-repo workplan gets its own dedicated *project repo*.**
- The project repo is a real, git-managed repository. It owns the coordination
workplan, its tasks, its decisions, and any cross-cutting artefacts. It is the
required `repo` anchor for that workplan, satisfying the repo-primary-anchor
rule without distorting any single product repo.
- The project repo is classified under the Repo Classification Standard, normally
`category: project`. Its `domain`/tags describe the effort, not any one product.
- **Implementation still happens in the product repos.** Changes land via
per-repo workplans and PRs in the repos being modified. The project repo
*coordinates and references* that work (via dependency edges / links); it does
not own product code.
- **On completion, the project repo is retired to archive — not deleted.** Its
durable results live on in the product repos it modified (the merged changes
are the outcome). The archived project repo remains as an immutable provenance
record of the coordination, consistent with the append-only-memory value.
The project repo's completion record MUST list the product repos it modified and
link to the merged PRs/commits, so the trail survives archival.
## Lifecycle
```
draft → active → completed → archived
```
- **active** — work in progress; workplan `status: active`; repo live in Gitea
and registered in the Hub.
- **completed** — all tasks done; completion record written (modified repos +
links).
- **archived** — repo archived in Gitea and `status: archived` in the Hub. The
workplan moves to `workplans/archived/` per the workplan convention. Results
persist in the product repos; the project repo is read-only history.
## Naming
Project repos SHOULD be identifiable as such (e.g. a `proj-<slug>` prefix or a
dedicated grouping). Exact convention is deferred to `CUST-WP-0050` rollout
(tracked as an open question there), but the lifecycle and ownership rules above
are fixed by this ADR.
## Consequences
- **Pro:** every workplan — including cross-repo ones — has a stable,
git-managed anchor; no hub-only orphans; the rebuild principle (ADR-001) holds.
- **Pro:** the classification standard applies uniformly; project repos are just
repos with `category: project`.
- **Pro:** clean, explicit lifecycle; results are never lost on retirement
because they live in the modified product repos.
- **Con:** proliferation of short-lived repos; requires discipline around the
naming and archival convention.
- **Con:** cross-references between the project repo and the product repos it
modified must be recorded deliberately, or the provenance trail degrades after
archival.
- **Con:** judgement is required on *when* an effort is "complex enough" to merit
a project repo versus a single-repo workplan; small cross-cutting changes
should not spawn a repo.
## Alternatives Considered
- **Bind to a "lead" product repo.** Rejected: distorts that repo's history and
creates ambiguous ownership.
- **Keep an optional hub-only topic for cross-repo coordination.** Rejected:
reintroduces the soft, non-git-managed spine that `CUST-WP-0050` removes and
ADR-001 discourages.
- **Multi-anchor workplan (array of repo_ids, no primary).** Rejected: breaks
single-anchor simplicity, ownership clarity, and lifecycle modelling.
## Related
- ADR-001 — Workplans and Work Items Are Repository Artefacts
- `CUST-WP-0050` — Repo Classification & State Hub Registration Redesign (D1)
- `canon/standards/repo-classification-standard_v1.0.md`

View File

@@ -0,0 +1,162 @@
---
id: CUST-CPT-CUST-2026-000002
type: concept
title: "Interface Change Registry — Coordinated API Evolution for Agent Ecosystems"
status: active
owners: ["Bernd", "Custodian"]
created: "2026-04-26"
updated: "2026-04-26"
scope:
domains: ["custodian"]
sensitivity: internal
tags: ["interface", "api-evolution", "agent-coordination", "ecosystem", "change-management"]
related_workplan: CUST-WP-0033
---
# Interface Change Registry — Coordinated API Evolution for Agent Ecosystems
## Problem
In a distributed ecosystem of closely coupled repos and services, APIs and interfaces
evolve continuously. Without coordination, breaking changes propagate silently: a
service updates its REST API, and dependent agents or services discover the breakage
only at runtime — typically as a 422, a 307 redirect, or a schema validation failure.
Human-operated systems address this with release notes and changelogs. Agent-operated
systems need something machine-readable and actionable: a record of what changed, who
depends on it, and a channel to trigger adaptation before the breakage hits.
The trailing-slash normalisation performed on 2026-04-26 is a concrete example: it
was a deliberate, coordinated breaking change. Without a registry, every consumer had
to be found by manual grep. With one, the change record names the affected repos,
their agents receive inbox notifications, and each can adapt autonomously.
## Core Abstraction: InterfaceChange
An `InterfaceChange` record describes a single, versioned mutation to a published
interface boundary. It carries:
| Field | Purpose |
|---|---|
| `repo_slug` | The repo that owns the interface |
| `interface_type` | What kind of interface: `rest_api`, `mcp_tool`, `cli`, `schema`, `capability` |
| `change_type` | Nature of change: `breaking`, `additive`, `deprecation`, `removal` |
| `title` | Short human-readable summary |
| `description` | Full description with before/after detail |
| `affected_paths` | Specific endpoints, tool names, CLI commands, or schema fields changed |
| `affected_repo_slugs` | Repos known to consume this interface |
| `status` | `draft``published``resolved` |
| `planned_for` | Optional date — set when change is announced before it ships |
| `published_at` | When the change became live |
| `resolved_at` | When all known dependents have adapted |
## Lifecycle
```
draft ──publish──▶ published ──resolve──▶ resolved
│ │
│ auto-notify affected
│ repo agents (inbox)
└── edit freely; no notifications yet
```
**draft** — change is being documented but not yet live or announced. Safe to edit.
Can be used to pre-announce a planned breaking change before it is merged.
**published** — the change is live (or imminently scheduled). On publish, the hub
automatically sends an inbox message to the agent of each `affected_repo_slug`.
The message contains enough context for the agent to identify what needs updating.
**resolved** — all known dependents have adapted and confirmed. Can be closed by
the originating agent or by any affected agent once it has updated its side.
## Dependency Routing
`affected_repo_slugs` can be populated in two ways:
1. **Explicit** — the author lists known consumers when creating the record.
2. **Derived** — the hub queries the TPSC graph: repos that have a TPSC snapshot
declaring a dependency on the originating repo's service are automatically
included as candidates. The author confirms or trims the list before publish.
This means the TPSC catalog (`tpsc.yaml` files) is the underlying dependency map
for routing interface change notifications. Keeping TPSC current is what makes
automatic routing accurate.
## Pre-Change Coordination
Setting `planned_for` and publishing in `draft` status (then moving to `published`
on merge) enables a coordination window:
```
day 0 — change drafted, planned_for set to day 7
day 0 — dependent agents receive notification, begin adapting
day 7 — change lands, status set to published
day 7+ — agents confirm adaptation, change resolved
```
This is the proactive adaptation model: the breaking change announcement travels
faster than the change itself, giving dependents time to prepare. At scale, this
enables the ecosystem to self-heal around planned migrations.
## Agent Session Integration
Two integration points keep agents aware of pending changes without requiring
active polling:
**Session start (pull):** The `/repos/{slug}/dispatch` endpoint includes a
`pending_interface_changes` field — published changes that affect this repo and
are not yet resolved. Agents reading dispatch at session start see what they need
to adapt to.
**Inbox notification (push):** On publish, the hub sends an inbox message to each
affected repo's agent. The message includes the change title, description, and
`affected_paths` so the agent can locate the relevant code without additional API
calls.
Together, these ensure no published breaking change is invisible to an agent
working in an affected repo.
## Relationship to Existing State-Hub Entities
| Entity | Relationship |
|---|---|
| `ManagedRepo` | InterfaceChange.repo_id FK; affected_repo_slugs reference repo slugs |
| `TPSC` / `TPSCSnapshot` | Source for derived affected_repo_slugs via service dependency graph |
| `Decision` | A planned breaking change is conceptually a pending decision; consider linking |
| `ProgressEvent` | Publishing a change auto-appends a progress event to the originating repo |
| `Message` | Publish action sends inbox messages to affected agents |
## Webhook Extension (Deferred)
Inbox messages cover agents that poll at session start. Services that need
real-time push — CI pipelines, external webhooks, non-Custodian agents — require
a separate subscription mechanism.
This is explicitly deferred. The design leaves room for it:
- `InterfaceChange` records are immutable once published (safe to deliver idempotently)
- `affected_repo_slugs` is the routing key; a subscription table maps slugs to URLs
- Delivery semantics: at-least-once with exponential backoff
A dedicated EP (`EP-CUST-ICR-001`) will track this when the inbox-first approach
proves insufficient.
## Long-term Vision
The Interface Change Registry is a first step toward a **self-healing ecosystem**:
1. A repo publishes a breaking change with `planned_for = T+7`.
2. The hub identifies all dependents via TPSC and notifies their agents.
3. Each dependent agent opens a task, locates the affected code, and creates an
adaptation PR before T+7.
4. At T+7, the change ships; all dependents are already adapted.
5. The originating agent marks the change resolved.
No human coordination is needed for routine interface evolution. Humans remain in
the loop for non-routine changes — architectural decisions, security-sensitive
migrations, or changes that require cross-domain agreement — via the Decision entity
and the existing escalation protocol.
At greater scale, the dependency graph enables **contract testing**: two repos can
register a formal interface contract, and the hub can detect when a proposed change
would violate it before the change is merged.

View File

@@ -0,0 +1,92 @@
---
id: CUST-TFE-SCOPE-2026-000001
type: architecture-note
title: "Task Flow Engine Extraction Scope v0.1"
status: draft
owners: ["Bernd", "Custodian"]
created: "2026-05-01"
updated: "2026-05-01"
scope:
domains: ["Custodian"]
sensitivity: internal
tags: ["task-flow-engine", "architecture", "state-hub", "workflow"]
domain: custodian
provenance:
workplan: CUST-WP-0035
task: CUST-WP-0035-T06
---
# Task Flow Engine Extraction Scope v0.1
## Purpose
The task flow engine is currently co-located in `state-hub/` so it can replace
hardcoded lifecycle logic where the need is immediate. Its core model is more
general than State Hub, so it should become a standalone Python package once
the API has stabilized through real use.
## Standalone Package Boundary
The future `task-flow-engine` package should contain only pure computation:
- `models.py`: dataclasses for assertions, workstations, flows, and results
- `evaluator.py`: target path resolution and assertion evaluation
- `engine.py`: reachable workstation and exit-blocking derivation
- `builtins.py`: built-in operations such as `all_eq`, `any_eq`, `none_eq`,
`exists`, and `count_gte`
The package must not depend on State Hub, SQLAlchemy, FastAPI, MCP, Custodian
canon files, or any specific database schema.
## State Hub Integration Boundary
State Hub should retain the domain-specific integration layer:
- YAML flow definitions in `state-hub/flows/`
- conversion from ORM entities into plain information-object dictionaries
- Alembic migrations and status-column storage choices
- API routers and MCP tools
- custom assertion callables that query State Hub data
- progress events, timestamps, notifications, and other side effects
This keeps the reusable engine small while allowing State Hub to remain the
place where Custodian-specific lifecycle semantics are declared and exposed.
## Extraction Path
1. Keep `state-hub/task_flow_engine/` in-tree until at least one non-trivial
flow definition runs in normal State Hub use.
2. Stabilize the dataclass and result shapes around real consumers:
State Hub API, MCP tools, and repo-facing workflows.
3. Extract the pure package into a new `task-flow-engine` repository.
4. Publish it as an internal pip package.
5. Replace the in-tree package with a dependency import in State Hub.
The extraction should preserve the current import surface where practical:
`FlowDef`, `WorkstationDef`, `AssertionDef`, `FlowResult`, `AssertionResult`,
`FlowEngine`, and `resolve_target`.
## Managed Repo Concept
When extraction starts, register a managed repository concept:
- slug: `task-flow-engine`
- domain: `custodian`
- purpose: reusable declarative workstation/assertion engine
- primary capability: `workflow.evaluate`
- secondary capabilities: `workflow.define`, `workflow.explain`
## Extension Point
An extension point is registered in State Hub to keep this extraction visible:
- type: `architecture`
- title: `task-flow-engine extraction as standalone package`
- status: `open`
- priority: `low`
Description:
`task_flow_engine/` is currently co-located in the State Hub. Extract it to its
own repository and pip package once the API is stable after at least one
non-trivial flow definition has been running in production.

View File

@@ -0,0 +1,244 @@
---
id: canon-iam-profile
type: standard
title: "IAM Profile v0.1"
domain: custodian
status: superseded
version: "0.1"
created: "2026-05-02"
updated: "2026-05-22"
scope: all-hubs
superseded_by: net-kingdom/canon/standards/iam-profile_v0.2.md
---
# IAM Profile v0.1
> Superseded 2026-05-22. The canonical core/platform IAM Profile is now
> owned by net-kingdom at `canon/standards/iam-profile_v0.2.md`, with
> ownership and version governance recorded in
> `docs/adr/ADR-0011-iam-profile-ownership-and-version-governance.md`.
> This v0.1 all-hubs draft remains historical Custodian context only;
> hub-specific scopes such as `hub:*`, `ops:*`, and `fin:*` are downstream
> extensions of the NetKingdom core profile.
## Purpose
This standard defines the identity and access-management contract shared by
Custodian hubs and services. It gives hub-core, dev-hub, ops-hub, fin-hub, and
domain services one predictable OIDC profile without binding them to one
deployment topology.
The reference provider is NetKingdom SSO: Keycloak as the OIDC provider, with
privacyIDEA-backed MFA for human authentication. Local development may use a
file-backed OIDC provider if it exposes the same contract.
## Design Principles
- Hubs trust OIDC tokens, not provider-specific session state.
- Human and service identities are distinct.
- Authorization decisions use explicit claims and scopes.
- Local development degrades gracefully without weakening production rules.
- Emergency access is auditable, time-bounded, and never silent.
## Discovery Contract
Every IAM profile implementation MUST expose standard OIDC discovery:
```text
GET /.well-known/openid-configuration
```
The discovery response MUST include:
- `issuer`
- `authorization_endpoint`
- `token_endpoint`
- `jwks_uri`
- `userinfo_endpoint`
- `end_session_endpoint` when supported
- `scopes_supported`
- `response_types_supported`
- `grant_types_supported`
- `id_token_signing_alg_values_supported`
Services MUST validate tokens against the advertised `issuer` and `jwks_uri`.
Key material MUST be cacheable, but services MUST tolerate key rotation.
## Required Flows
### Human Interactive Flow
Human users authenticate through Authorization Code + PKCE.
Required properties:
- PKCE is mandatory for browser or CLI login.
- MFA is mandatory for privileged roles in production.
- Access tokens are short-lived.
- Refresh tokens are allowed only for trusted clients with explicit rotation.
### Service Account Flow
Hub-to-hub and service-to-service traffic uses client credentials or a
provider-supported service-account equivalent.
Required properties:
- Service accounts are named after the service and environment.
- Service credentials are stored through the credential-management standard,
not in plaintext config.
- Tokens include an audience that identifies the target hub or service.
- Service accounts receive only the scopes required for their role.
## Required Claims
Access tokens accepted by hubs MUST provide:
| Claim | Meaning |
|---|---|
| `iss` | OIDC issuer URL |
| `sub` | Stable subject identifier |
| `aud` | Intended audience; MUST include the receiving hub/service |
| `exp` | Expiry timestamp |
| `iat` | Issued-at timestamp |
| `scope` or `scp` | Granted scopes |
| `preferred_username` | Human-readable username for human identities |
| `roles` or `realm_access.roles` | Role names used for hub authorization |
Recommended claims:
| Claim | Meaning |
|---|---|
| `email` | Contact identity for humans |
| `name` | Display name |
| `groups` | Organization/group membership |
| `azp` | Authorized party/client id |
Services MUST NOT infer privilege from `email`, display name, or group naming
conventions alone. Privilege comes from explicit roles and scopes.
## Required Scopes
The following scopes form the shared vocabulary:
| Scope | Purpose |
|---|---|
| `openid` | Required for OIDC login |
| `profile` | Basic user profile |
| `email` | Email claim where appropriate |
| `hub:read` | Read hub state |
| `hub:write` | Mutate ordinary hub state |
| `hub:admin` | Administrative hub operations |
| `hub:message` | Send and manage inter-agent/hub messages |
| `hub:capability` | Request, accept, and update capability requests |
| `hub:repo` | Register and update managed repository metadata |
| `ops:read` | Read operational state |
| `ops:write` | Mutate operational records |
| `fin:read` | Read financial state |
| `fin:write` | Mutate financial records |
High-impact scopes such as `hub:admin`, `ops:write`, and `fin:write` MUST be
issued only to MFA-authenticated humans or narrowly scoped service accounts.
## Role Vocabulary
The minimum shared roles are:
| Role | Meaning |
|---|---|
| `viewer` | Read-only orientation |
| `operator` | Operational changes within an assigned domain |
| `steward` | Cross-domain governance and escalation |
| `admin` | IAM and hub administration |
| `service` | Non-human service identity |
| `emergency` | Temporary break-glass identity |
Hubs MAY define local roles, but shared integrations MUST map them back to this
vocabulary when communicating across hubs.
## Token Lifecycle
Recommended production defaults:
| Token | Lifetime | Notes |
|---|---|---|
| Access token | 5-15 minutes | Short-lived; bearer token |
| Refresh token | 8-12 hours | Rotated; revoked on logout or suspicion |
| Service token | 5-30 minutes | Reissued by client credentials |
Services MUST reject expired tokens and tokens with invalid issuer, audience, or
signature. Clock skew tolerance SHOULD be small, normally no more than 60
seconds.
## Hub-to-Hub Service Account Pattern
Each hub receives one service account per environment:
```text
svc-dev-hub-prod
svc-ops-hub-prod
svc-fin-hub-prod
svc-dev-hub-dev
```
Service accounts:
- authenticate with client credentials or equivalent workload identity
- carry the `service` role
- carry only the scopes required by the calling hub
- are rotated through the credential-management standard
- are never shared between environments
Example: dev-hub forwarding a deployment event to ops-hub should use a
dev-hub service account with `ops:write` scoped to the event-ingestion endpoint,
not an all-purpose admin token.
## Local Development Profile
A local file-backed provider MAY be used when Keycloak/privacyIDEA is
unavailable. It MUST:
- expose OIDC discovery
- issue signed JWTs
- support deterministic test users and service accounts
- use local-only issuer URLs by default
- clearly mark tokens as development tokens through issuer or audience
- never be accepted by production hubs
This profile exists to keep hub development possible without cluster
dependency; it is not a production identity system.
## Human Override and Emergency Access
Emergency access is allowed only as a break-glass path.
Requirements:
- Emergency identities are disabled by default.
- Activation requires a human-recorded decision or incident reference.
- Tokens are short-lived and carry the `emergency` role.
- Every emergency action emits a progress event or ops incident timeline entry.
- Emergency access is reviewed after use and then disabled again.
Emergency access MUST NOT bypass audit logging.
## Validation Checklist
A service conforms to this profile when:
- It reads OIDC discovery rather than hardcoding endpoints.
- It validates issuer, audience, expiry, and signature.
- It checks explicit roles/scopes for authorization.
- It supports Authorization Code + PKCE for human login.
- It supports service-account tokens for hub-to-hub calls.
- It rejects local-development issuers in production.
- It logs emergency access with a durable audit trail.
## Open Questions
- Whether `roles` or `realm_access.roles` becomes the canonical role claim for
all hubs, or whether adapters normalize both.
- Whether hub-to-hub event forwarding should use audience-per-hub or
audience-per-endpoint.
- Whether production service accounts eventually move from client credentials
to Kubernetes workload identity.

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,112 @@
# Machine-readable allowed-values for the Repo Classification Standard.
#
# Single source of truth for the standard's controlled vocabularies, derived
# from canon/standards/repo-classification-standard_v1.0.md. Consumed by:
# - the per-repo .repo-classification.yaml linter (tools/validate_repo_classification.py)
# - the State Hub registration validator (CUST-WP-0050 T04)
#
# When the standard's vocabularies change, update this file and bump `version`
# to match the standard version. CUST-WP-0050 T01.
standard: "Repo Classification Standard"
version: "1.0"
canon_id: "canon-repo-classification"
# category — exactly 1 required (§5)
categories:
- experimental
- research
- project
- tooling
- product
- business
# domain / secondary_domains — primary exactly 1; secondaries 0..n (§6)
domains:
- infotech
- financials
- communication
- consumer
- health
- industrials
- energy
- utilities
- materials
- realestate
- crypto
- agents
- space
- government
# business_stake — 0..n; 2..6 recommended (§8)
business_stake:
- execution
- intelligence
- finance
- legal
- sales
- experience
- technology
- operations
- product
- people
- procurement
- sustainability
- automation
# business_mechanics — 0..n, optional (§9)
business_mechanics:
- intention
- control
- coordination
- operation
- adaptation
# capability_tags are intentionally OPEN-ENDED (§7): lowercase kebab-case, not
# restricted to this set. The families below are the standard's recommended
# canonical tags — used to warn on likely synonyms/typos, never to reject.
capability_families:
identity_and_access:
- identity
- authentication
- authorization
- access-control
- user-management
- tenancy
knowledge_and_evidence:
- knowledge
- citations
- evidence
- source-management
- traceability
- documentation
platform_and_operations:
- platform
- deployment
- operations
- observability
- feature-control
- configuration
- orchestration
market_and_coordination:
- marketplace
- pricing
- reputation
- challenges
- bounties
- collaboration
- coordination
governance_and_control:
- governance
- policy
- compliance
- risk
- audit
- control
# Validation guidance (advisory bounds the linter applies as warnings)
guidance:
secondary_domains_max: 3
business_stake_recommended_min: 2
business_stake_recommended_max: 6
capability_tag_pattern: "^[a-z0-9]+(-[a-z0-9]+)*$"

View File

@@ -0,0 +1,69 @@
# Repo Classification exclusion list (CUST-WP-0050 T11 / D3).
# Repos listed here are intentionally out of scope for classification and
# State Hub registration under the portfolio taxonomy.
#
# Validate additions against canon/standards/repo-classification-standard_v1.0.md.
version: "1.1"
updated: "2026-06-22"
exclusions:
# Forks and personal repos — not ecosystem inventory.
- slug: tegwick/the-custodian
gitea_path: tegwick/the-custodian
reason: fork path not found on Gitea (SSH verified 2026-06-22)
- slug: python-snake
gitea_path: lando_worsch/python-snake
reason: personal / non-ecosystem repo (exists on Gitea; excluded by policy)
# Archived or collapsed hub registrations — superseded by another slug.
- slug: markitect-project
reason: archived; workstreams relinked to markitect-main (ADR-005 disposition)
- slug: railiance-bootstrap
reason: archived phantom registration; no Gitea repo
- slug: railiance-hosts
reason: archived phantom registration; no Gitea repo
- slug: vergabe_teilnahme
reason: archived duplicate; collapsed into vergabe-teilnahme
- slug: test_domain_v2
reason: archived test domain; not present on Gitea coulomb org (SSH verified)
# Local-only templates / sandboxes — not product inventory.
- slug: hub-core-seed
reason: hub-core bootstrap seed copy; not a standalone service
- slug: sand-boxer
reason: agentic coding sandbox; throwaway experimentation surface
- slug: .nvm
reason: Node version manager checkout; not a coulomb project repo
# Portfolio-review slugs with no matching coulomb/* repo on Gitea (SSH verified 2026-06-22).
- slug: binect-chrome
reason: not present on Gitea coulomb org; likely renamed or removed
- slug: binect-js
reason: not present on Gitea coulomb org; likely renamed or removed
- slug: direkt-vermittlung-de
reason: not present on Gitea coulomb org; likely renamed or removed
- slug: polycode-sim
reason: not present on Gitea coulomb org; likely renamed or removed
- slug: ralph-workplan
reason: not present on Gitea coulomb org; likely renamed or removed
- slug: tele-mcp
reason: not present on Gitea coulomb org; likely renamed or removed
- slug: testdrive-jsui
reason: not present on Gitea coulomb org; likely renamed or removed
- slug: timeline-svg
reason: not present on Gitea coulomb org; likely renamed or removed

View File

@@ -278,7 +278,7 @@ The SBOM dashboard aggregates across all repos within a domain in the
| Repo | Domain | Ecosystems | Last Ingest |
|------|--------|------------|-------------|
| `the-custodian` | custodian | python, node | 2026-03-01 |
| `railiance-bootstrap` | railiance | — (Ansible + shell, no lockfile) | — |
| `railiance-cluster` | railiance | — (Ansible + shell, no lockfile) | — |
| `railiance-hosts` | railiance | terraform (2 providers) | 2026-03-01 |
*(This table is informational. The live view is at the SBOM dashboard.)*

View File

@@ -0,0 +1,139 @@
# Core Hub Helixforge Build Alignment
Date: 2026-06-27
Related workplans: `CUST-WP-0052`, `CUST-WP-0025`, `CORE-WP-0008`,
`CORE-WP-0005`, `CORE-WP-0007`.
## Sources Reviewed
- `/home/worsch/helix-forge/SCOPE.md`
- `/home/worsch/helix-forge/workplans/HF-WP-0001-establish-ops-hub-first-extension.md`
- `/home/worsch/helix-forge/wiki/OpsHubBootstrapRunbook.md`
- `/home/worsch/railiance-forge/Makefile`
- `/home/worsch/railiance-forge/docs/initial-operating-contracts.md`
- `/home/worsch/railiance-forge/docs/ci-runner-actions-gitops-ownership.md`
- `/home/worsch/railiance-forge/docs/gitea-actions-runner-substrate.md`
- `/home/worsch/railiance-forge/docs/observability-operating-evidence.md`
- `/home/worsch/railiance-forge/docs/gitea-container-registry.md`
- `/home/worsch/core-hub/Makefile`
- `/home/worsch/core-hub/docs/deployment/staging-profile.md`
- `/home/worsch/core-hub/docs/deployment/operator-cli.md`
- `/home/worsch/core-hub/docs/specs/testing-release-and-migration.md`
## Takeaways
HelixForge is currently a capability-first product/architecture and workplan
home, not a deployable runtime. Its older ops-hub Inter-Hub bootstrap material
is useful as vocabulary and historical evidence, but Core Hub now owns the
replacement implementation lane.
Railiance Forge is the concrete build and artifact practice source. The useful
patterns for Core Hub are:
- repo-local Make targets are the operator entry point;
- separate read-only checks from deploy/apply actions;
- print evidence docs and runbooks through Make targets where useful;
- source repos own build scripts and image/package metadata;
- `railiance-forge` owns registry endpoints, runner labels, runner health, and
artifact evidence contracts;
- `railiance-apps` should eventually own S5 deployment checks and app release
values;
- runner labels describe capability and trust level, not hostnames;
- privileged labels such as `registry-publish`, `cluster-dry-run`, and
`s5-release-check` require named credential paths and reviewed purpose;
- artifact tags for release evidence should be immutable commit-SHA tags;
- mutable tags such as `latest` must never be the only production reference;
- evidence should capture source repo, commit SHA, artifact identity,
version/tag/digest, runner identity when relevant, smoke result, and consuming
deployment value change;
- docs may reference SOPS/OpenBao/Kubernetes Secret names, but must not contain
decrypted values, tokens, kubeconfigs, SSH keys, or tokenized URLs.
## Core Hub Current Fit
Core Hub already has a compatible service-repo surface:
- `make lint`
- `make test`
- `make openapi`
- `make migrate-validate`
- `make staging-profile-check`
- `make container-build`
- `make deployed-smoke`
- `make operator-cli`
- `make visual-check`
The current image repository default,
`gitea.coulomb.social/coulomb/core-hub`, matches the Railiance Forge registry
contract. Core Hub staging docs already prefer commit-SHA image tags and note
that production/shared staging deploys must not depend on `latest`.
The current Core Hub staging profile is acceptable as a near-term service-repo
profile. It should later be promoted into a Railiance app release path once the
API contract and staging evidence are stable.
## Environment Posture
Use three distinct postures so build/release work does not overfit to the local
workstation:
| Posture | Purpose | Core Hub behavior |
|---|---|---|
| Local/dev | Fast contract work and disposable smoke proof. | `uv`, SQLite/disposable DBs, `CORE_HUB_AUTO_CREATE_TABLES=1` only for local smoke/test bootstraps, no live cluster dependency. |
| Staging | Production-like proof without cutover. | Postgres, Alembic migrations only, Kubernetes `core-hub-staging`, commit-SHA images, OpenBao/operator-owned secret references, deployed API and activity-core smokes. |
| Production/cutover | Replacement of Haskell Inter-Hub. | Requires staging import, dual-run or shadow smokes, rollback notes, non-secret readiness summary, and explicit operator approval. |
Do not let missing runner automation block API contract work. It should block
only publish/deploy automation that actually needs forge runner labels or
cluster credentials.
## Recommended Core Hub Build Lane
Keep the existing Core Hub Make targets and add future targets only when they
remove manual release ambiguity:
1. Local contract gate:
`make lint`, `make test`, `make openapi`, `make staging-profile-check`,
and `git diff --check`.
2. Image build:
`IMAGE_REPOSITORY=gitea.coulomb.social/coulomb/core-hub IMAGE_TAG=<commit> make container-build`.
3. Registry publication:
publish immutable `<commit>` tags through an attended operator path first;
move to forge runner automation only after `registry-publish` runner evidence
is available for the repo/workflow purpose.
4. Staging deploy:
keep `k8s/railiance-staging/` as the service-repo profile until
`railiance-apps` owns explicit Core Hub dry-run/status/deploy targets.
5. Evidence gate:
run `make deployed-smoke`, activity-core Core Hub sink smoke, migration
import, and `make operator-cli CLI_ARGS="readiness-summary ..."` with
reports under ignored `.local/` paths.
6. Cutover:
require non-secret evidence reports, rollback notes, and operator approval
before `CORE-WP-0007` Haskell retirement can move.
## Required Follow-Ups
No HelixForge repo change is required for the Core Hub reset. HelixForge remains
the capability/modeling context, while Core Hub owns the replacement runtime.
Core Hub follow-ups:
- Add a future release evidence note or Make target when a real staging image is
published to `gitea.coulomb.social/coulomb/core-hub:<commit>`.
- Keep `CORE-WP-0005` staging import and cutover evidence tied to immutable
image tags and non-secret reports.
- Add runner workflow files only after `railiance-forge` has runner label and
registry-publish evidence suitable for Core Hub.
Railiance follow-ups:
- `railiance-apps` should eventually own Core Hub app release values and
dry-run/status/deploy targets once the service leaves the temporary
service-repo staging profile.
- `railiance-forge` should be cited for registry, runner, and artifact evidence;
it should not own Core Hub API behavior or cutover decisions.
- Any need for cluster-dry-run or deploy-capable runner labels should be posted
as a State Hub requirement before adding workflow dependencies.

View File

@@ -0,0 +1,117 @@
# Core Hub Replacement Evidence Handoff
Date: 2026-06-27
Related workplans: `CUST-WP-0052`, `CUST-WP-0025`, `CUST-WP-0047`,
`CUST-WP-0049`, `CORE-WP-0008`, `CORE-WP-0004`, `CORE-WP-0005`,
`CORE-WP-0007`.
## Current Evidence
Core Hub now has the API-first replacement lane needed to stop expanding the
old Inter-Hub-first ops-hub path:
- `CORE-WP-0008-T02`: repeatable deployed-smoke harness exists through
`make deployed-smoke`. It probes health/readiness, OpenAPI compatibility,
public catalogs, protected-route `401` behavior, operator auth, ops-hub
bootstrap-equivalent creation, widget/event write, key-prefix evidence, and
hub-registry visibility. It was verified against a disposable local HTTP Core
Hub runtime, not a live staging endpoint.
- `CORE-WP-0008-T03`: activity-core has a direct Core Hub
`core-hub-interaction-event` sink, verified locally against a disposable Core
Hub runtime. Deployed execution still needs `CORE_HUB_BASE_URL`, runtime key,
and widget mapping from approved custody.
- `CORE-WP-0008-T04`: staging deployment profile, Kubernetes manifests,
migration job shape, secret references, health/readiness probes, rollback
notes, and container build checks are documented.
- `CORE-WP-0008-T05`: `make operator-cli` wraps the same API behavior for
deployed smoke, ops-hub bootstrap status, migration validate/import, and
cutover readiness summaries.
- `CORE-WP-0006`: protected `/console` prototype exists with readiness,
registry, migration/cutover, action-required, access metadata, and evidence
stream sections. `make visual-check` passed on 2026-06-27 with desktop/mobile,
no-overlap, horizontal-overflow, protected-route, PNG, and non-secret checks.
- `CORE-WP-0008-T06`: the web UI is gated behind API/CLI readiness and has a
compact whynot-aligned first-screen backlog. The UI should not start by
recreating every old Inter-Hub screen.
No live deployed smoke report was available in this session. Therefore there
are no deployed Core Hub smoke ids/counts to claim yet. The next live report
should record only non-secret fields: `runId`, hub id/slug/status, manifest
id/status, API consumer id/status/key prefix, widget count, interaction event
id/type, and hub-registry containment booleans.
## 0047 And 0049 Decision
`CUST-WP-0047-T05` should remain `wait` as the legacy Inter-Hub evidence record.
Do not close it from local Core Hub evidence alone. It can close later through a
Core Hub deployed compatibility/evidence smoke or an explicit supersede
decision that states the legacy production widget activation is no longer
required.
`CUST-WP-0049-T06` should remain `wait` as the legacy/fallback access routine.
Do not request Inter-Hub operator keys or new ops-warden work for the preferred
replacement lane. Use it only if the operator deliberately chooses legacy
Inter-Hub bootstrap or rollback validation.
## CUST-WP-0025 Phase 3 Reset Recommendation
`CUST-WP-0025-T13` through `T19` should be rewritten before execution:
- T13: replace "create standalone ops-hub repo" with Core Hub-owned API-first
ops evidence and registry work. Defer any standalone ops-hub repo until after
Core Hub cutover proves the boundary still needs a separate service.
- T14: replace standalone ops-specific models with Core Hub resources and
migration/read-model gaps, preserving `CUST-WP-0047` service inventory as
input evidence.
- T15: replace MCP-first ops tools with API and CLI parity first. Any MCP layer
should consume the proven Core Hub API later.
- T16: route infrastructure evidence through activity-core probes and Core Hub
interaction/deployment evidence, with credential ownership resolved through
approved custody routes rather than chat or workplans.
- T17: reframe cross-hub coupling around Core Hub events, State Hub progress,
and activity-core evidence sinks. Keep NATS as a later transport decision.
- T18: replace the old dashboard task with the whynot-aligned Core Hub operator
UI backlog from `CORE-WP-0008-T06`.
- T19: cancel or defer ops-hub MCP server registration until post-cutover
demand proves it is needed.
2026-06-27 follow-up: `CUST-WP-0025-T13` through `T19` have now been
rewritten around this recommendation. The rewrite is enough to stop the obsolete
standalone ops-hub scaffold sequence, but not enough to declare Core Hub
production cutover complete.
2026-06-27 T14 closeout: Core Hub now has
`docs/specs/ops-evidence-contract.md`, which defines the ops evidence API
resources, event vocabulary, non-secret access metadata rules, service inventory
mapping, readiness-summary inputs, and read-model gaps. This closes the T14
definition gate while leaving deployed evidence, cutover coupling, and UI work
for T16/T17/T18.
2026-06-27 T03 closeout: Core Hub now has a reusable IAM Profile verifier and
FastAPI dependency plus `tests/test_iam_profile.py`, which proves OIDC
discovery, JWKS signature validation, authorization-code + PKCE token issuance,
protected endpoint access, required IAM Profile claims, missing-token rejection,
wrong-audience rejection, and production rejection of local-development issuers.
This closes the identity integration template while leaving production issuer
wiring for the deployed Core Hub gates.
2026-06-27 T18 closeout: Core Hub `CORE-WP-0006` is finished and local
`make visual-check` passed for `/console`. The first UI surface is intentionally
compact and protected; broader UI implementation remains gated by deployed API
and CLI evidence through the rebuild backlog.
## Remaining Gates
- Run `make deployed-smoke` or `make operator-cli CLI_ARGS="deployed-smoke ..."`
against a real Core Hub staging URL with an approved operator token.
- Import the approved Inter-Hub export bundle into a staging Core Hub database
and keep dry-run reports visibly open until a reviewed non-dry-run import
succeeds.
- Run the deployed activity-core Core Hub sink smoke with approved runtime
token and widget mapping.
- Build a `readiness-summary` evidence report from deployed smoke, migration,
activity-core, and optional legacy Inter-Hub reference evidence.
- Keep `CORE-WP-0007` Haskell retirement blocked until staging import, dual-run
smokes, cutover, rollback notes, and operator approval are complete.

View File

@@ -0,0 +1,93 @@
# Credential Custody Unblock Board
Created: 2026-06-27
Owner: the-custodian coordination; credential owners remain with their owning repos.
## Purpose
This board collects the live credential and operator-access gates that block the
infrastructure stabilization plan. It records routes and non-secret evidence
only. It is not a secret store, approval record, or substitute for the owning
repo runbooks.
## Rules
- Do not put secrets in Git, State Hub, workplans, shell history, or chat.
- Use the current ops-warden source CLI for routing if the installed `warden`
lacks `route` commands: `cd /home/worsch/ops-warden && uv run warden route ...`.
- `ops-warden` directly issues SSH certificates. For non-SSH needs it may
route, advise, or proxy an `exec_capable` lane through `warden access` as the
caller, but it does not own custody, mint values, or store secrets.
- Classify credential blockers by environment posture and workload maturity:
dev/test work should use synthetic contract doubles; production real-value
work needs owner custody, policy gates where required, and non-secret evidence.
- OpenBao/API credentials route to `railiance-platform`; interactive identity
routes to `key-cape`; tunnels route to `ops-bridge`; host principal and
force-command deployment routes to `railiance-infra`.
- Evidence may include ids, prefixes, counts, decision ids, HTTP status, and
smoke pass/fail. It must not include credential values.
## Route Records
| Route id | Owner | Scope | ops-warden role | Reference |
| --- | --- | --- | --- | --- |
| `openbao-api-key` | `railiance-platform` | API keys, DB credentials, provider tokens, OpenBao KV/dynamic leases | Assist: route; proxy only as caller when `exec_capable`; custody stays OpenBao | `wiki/CredentialRouting.md#routing-table` |
| `inter-hub-bootstrap-ssh` | `ops-warden` + `railiance-infra` | Inter-Hub bootstrap SSH envelope and force-command pattern | Assist envelope; issue SSH cert only if remote host reachability is used | `wiki/InterHubBootstrapAccessLane.md#worker-checklist` |
| `ssh-cert-host-access` | `ops-warden` | Short-lived SSH cert signing for host reachability | Issue SSH certs directly | `wiki/AccessRouting.md#issue-vs-route` |
| `railiance-infra-principals` | `railiance-infra` | Host SSH principal files and force-command deployment | Route only | `wiki/CredentialRouting.md#routing-table` |
| `key-cape-oidc-login` | `key-cape` | Interactive login, OIDC, MFA, JWT/authentication | Assist login lane when `exec_capable`; identity stays key-cape | `wiki/CredentialRouting.md#quick-decision-tree` |
| `ops-bridge-tunnel` | `ops-bridge` | SSH tunnels and port forwards | Route; supply `cert_command` pattern when needed | `wiki/playbooks/ops-bridge-tunnel-cert.md#migration-checklist` |
## Security-Stage and Maturity Triage
Use ops-warden `wiki/WorkloadSecurityPosture.md` to split vague IT-security
blockers into concrete outcomes.
| Classifier | CUST-WP-0051 interpretation |
| --- | --- |
| Dev/test posture only | Not blocked on production secrets. Use synthetic contract doubles or generated test values. |
| Prod posture with real values | Owner custody and policy gates are required. Record only route id, path/version, decision id, populated-key count, or smoke id. |
| Workload maturity below secret requirement | Real blocker until the workload matures, the secret is reclassified, or the design avoids that secret. |
| Route exists and lane is `exec_capable` | `warden access --fetch/--exec` may remove manual copy/paste as a blocker by proxying the owning tool as the caller. |
| Unseal, break-glass, issuer custody unresolved | Operator ceremony/design blocker; do not bypass with Codex-visible values. |
Current read:
| Gate family | Posture/maturity read |
| --- | --- |
| Inter-Hub / ops-hub runtime keys | Production real-value gate; implementation can proceed with route evidence, but live smoke waits on OpenBao/operator custody. |
| activity-core to issue-core | Production service credential gate; the blocker is `ISSUE_CORE_API_KEY` injection/evidence, not repo-side contract work. |
| OpenBao unseal / issuer profile | M3-style operator ceremony; remains a hard operator-design gate. |
| Forgejo SMTP/package/runner migration | Production credential and recovery-readiness gate; use OpenBao/key-cape/ops-bridge routes, then record non-secret drill evidence. |
## Live Gates
| Gate | Blocking work | Owner and route | Expected execution host | Non-secret evidence | Fallback decision | Next action | Status |
| --- | --- | --- | --- | --- | --- | --- | --- |
| Inter-Hub ops-hub bootstrap | `CUST-WP-0049-T06`, unblocks `CUST-WP-0047-T05` | `inter-hub-bootstrap-ssh` for the envelope; `openbao-api-key` for operator/runtime key custody; `ssh-cert-host-access` only for cert signing if remote execution is used | Local workstation with `IHUB_OPERATOR_KEY_FILE`, or trusted host with railiance-infra force-command wrapper | Hub id, manifest id, widget count, runtime key prefix only, bootstrap smoke result, State Hub progress id | Prefer API helper. Use deployment-side migration/bootstrap only by explicit operator approval. Manual SQL remains last-resort and must be recorded as an exception. | Operator materializes Inter-Hub operator key through approved custody, runs the ops-hub helper, stores generated runtime key outside Git, removes temp files. | Ready for operator handoff |
| Ops-hub runtime evidence key | `IHUB-WP-0022-T04`, then `IHUB-WP-0022-T07` | `openbao-api-key` owned by `railiance-platform` / OpenBao | Operator workstation, OpenBao UI/CLI session, or trusted cluster job; not a Codex-visible shell with printed values | OpenBao path/version or populated key count only, token exchange HTTP status, evidence submission smoke id | Attended one-time key file is acceptable only long enough to store in OpenBao and remove; no chat or State Hub transfer. | Store/provide `OPS_HUB_KEY` via OpenBao path, then run Inter-Hub submission smoke. | Waiting on operator custody |
| OpenBao unseal and token automation | `NET-WP-0020`, related OpenBao token-grant and policy-gate blockers | `openbao-api-key` for OpenBao issuer/token paths; `railiance-infra-principals` for host policy; `ssh-cert-host-access` for cert signing; `key-cape-oidc-login` for login/MFA | OpenBao operator terminal, cluster-admin context, or trusted railiance-infra deployment path | Policy names, role names, token accessor only, decision ids, allow/deny smoke result | Keep attended ceremony path until auto-unseal/profile is explicitly approved. Do not invent `warden secret` or paste `VAULT_TOKEN`. | Decide custody profile, apply narrow policy/role through approved issuer path, rerun smoke with non-secret evidence. | Needs operator design/approval |
| Forgejo production migration | `RAIL-HO-WP-0005` T02/T06/T11/T12 | `openbao-api-key` for SMTP/package/provider credentials; `key-cape-oidc-login` for login/MFA; `ops-bridge-tunnel` or `ssh-cert-host-access` only for host reachability | Forgejo admin/browser session, railiance01 trusted host, or approved GitOps/deployment path | Decision record id, hostname/exposure choice, SMTP sender/domain alignment, password-reset smoke, backup/restore drill id, package pull smoke, cutover approval id | Keep Gitea as read-only rollback until stabilization passes; do not retire legacy Gitea without explicit approval. | Resolve production choices, store SMTP credentials through OpenBao, run recovery and migration drills, then request cutover approval. | Needs human production decisions |
## Route Lookup Commands
```bash
cd /home/worsch/ops-warden
uv run warden route show openbao-api-key --json
uv run warden route show inter-hub-bootstrap-ssh --json
uv run warden route show ssh-cert-host-access --json
uv run warden route show railiance-infra-principals --json
uv run warden route show key-cape-oidc-login --json
uv run warden route show ops-bridge-tunnel --json
```
## Pickup Order
1. Inter-Hub ops-hub bootstrap, because it unlocks both the now-view and the
activity-core evidence lane.
2. Ops-hub runtime evidence key, because it is the immediate smoke gate after
bootstrap.
3. OpenBao custody profile, because several credential-helper and policy-gate
blockers collapse once a narrow issuer path exists.
4. Forgejo production decisions, because those require human design approval
before execution can be responsibly automated.

View File

@@ -0,0 +1,60 @@
# Daily State Hub WSJF Calibration - 2026-06-04
## Source Runs
| Date | Run id | Source | Main work-next recommendations |
|------|--------|--------|--------------------------------|
| 2026-06-02 | `f9b97749` | activity-core manual canary | `cust-wp-0044`, `cust-wp-0045` |
| 2026-06-03 | `6d2737e3` | activity-core daily run | `cust-wp-0044`, `cust-wp-0045`, WHI card |
| 2026-06-04 | `65e273bf` | activity-core daily run | `cust-wp-0044`, `cust-wp-0045`, `cust-wp-0003` |
The three runs were consecutive activity-core-generated Custodian daily triage
notes under `memory/working/`. They are sufficient to calibrate
`CUST-WP-0044-T06` and `CUST-WP-0045-T08` because none of the three came from
the old Codex app automation fallback.
## Findings
- The top recommendations were stable and actionable. The system repeatedly
identified the triage loop itself (`CUST-WP-0044`) and the activity-core
runner cutover (`CUST-WP-0045`) as the highest-value next work.
- The recommendations matched actual follow-up work: `CUST-WP-0045-T07` was
closed through the State Hub WSJF review surface, and this calibration closes
the remaining `CUST-WP-0044-T06` / `CUST-WP-0045-T08` loop.
- The action vocabulary is useful. `work-next`, `needs-human`, `revisit`,
`needs-consistency-sync`, and `close-out` all appeared in sensible places.
- The maximum recommendation count is about right. Seven to nine items were
enough to surface the important work without turning the note into a backlog.
- Stale or blocked work should remain explicit recommendations, not automatic
status changes. The daily run should continue to recommend `revisit`,
`park`, or `needs-human` and leave canonical edits to implementation
sessions.
- The current JSON reports were too thin for the stated WSJF contract. They
explained why candidates were selected but did not include component scores.
The schema and ActivityDefinition prompt now require rank and WSJF component
scores for future runs.
- The ActivityDefinition body still described the old disabled/fallback
posture even though frontmatter had `enabled: true`. The runner-status text
was corrected during calibration.
## Calibration Decisions
- Keep equal WSJF factor weights for now.
- Keep the recommendation cap at 10.
- Keep `max_depth: 2` and the balanced triage profile for ordinary daily runs.
- Increase the runner `max_tokens` from 1400 to 1800 to make room for WSJF
component scores without losing recommendations.
- Require explicit WSJF fields in the executable JSON schema:
`score`, `strategic_value`, `time_criticality`, `risk_reduction`,
`opportunity_enablement`, and `job_size`.
- Treat stale-but-intentionally-parked work as a recommendation quality issue,
not a status automation issue.
- Use the State Hub WSJF review page plus activity-core metadata as the normal
"did it run today?" surface.
## Result
The daily activity-core WSJF triage loop is useful enough to continue as a
standing Custodian habit. The next executable recommendation after this
closeout is `CUST-WP-0003` / WHI KPI card work, unless a human-gated item is
explicitly approved first.

View File

@@ -0,0 +1,68 @@
# Daily-Triage Stabilization Status
Updated: 2026-06-27
## Purpose
Track the current daily-triage blocker chain for `CUST-WP-0051-T04` without
duplicating the source activity-core workplans.
## Current Evidence
State Hub `daily_triage` progress shows the scheduled activity-core runner is
alive and can write both State Hub progress and working-memory notes.
Recent scheduled run evidence:
| Date | State Hub event | Result |
| --- | --- | --- |
| 2026-06-24 | `8b4c16ee-ac47-4581-b3ee-a23fc1f682e6` | schema-valid daily triage, working memory written |
| 2026-06-25 | `cbba6bc0-14cb-492b-ab23-74b9349326c8` | schema-valid daily triage, working memory written |
| 2026-06-26 | `97fd20a0-eee0-45ea-8290-6d91874e1515` | validation failed at char 5268, working memory written |
| 2026-06-27 | `c5ab50a8-404b-4e30-849f-841b059ace65` | validation failed at char 5246, working memory written |
The 2026-06-26 and 2026-06-27 failures are both overlong malformed JSON
responses from `daily-triage-report`. They are not missed schedules and they are
not silent sink failures.
## Current Blocker
The old `ACTIVITY-WP-0010` State Hub bridge note is partially superseded by the
newer evidence: scheduled runs are reaching State Hub and the working-memory
sink. The current primary blocker is that the live activity-core runtime still
uses an output path that can discard the whole report when the model emits a
malformed tail.
`ACTIVITY-WP-0016` has the repo-side mitigation:
- strict bounded report schema;
- item-granular recovery and quarantine;
- producer guardrails and ADR-004;
- regression tests for the 2026-06-26 failure shape.
The remaining gate is the live deployment/smoke path:
1. Deploy the WP-0016 code and schema together.
2. Update the Railiance runtime prompt bundle with bounded top-N instructions,
per-item framing, value vocabularies, and sufficient `max_tokens` headroom.
3. Run a live daily-triage smoke on railiance01 and confirm malformed-tail
output degrades to partial valid output with quarantined items.
4. Resume the three-clean-scheduled-run gate for `ACTIVITY-WP-0006-T03` and
`ACTIVITY-WP-0010-T04`.
## Hygiene Note
The State Hub task index currently shows stale duplicate tasks for
`ACTIVITY-WP-0016` in addition to the source-file task records. Before relying
on activity-core task counts for triage ranking, run activity-core consistency
sync and prune or reconcile any stale generated task rows that are no longer
linked from the workplan file.
2026-06-27 status-normalization: ACTIVITY-WP-0016 source task blocks now
match the progress notes for T04 (done) and T05 (progress). Remaining hygiene is
to remove or reconcile stale duplicate task rows from the State Hub index.
2026-06-27 gate cleanup: ACTIVITY-WP-0010-T02 is now done because scheduled
runner evidence proves the State Hub sink and working-memory path are reachable.
The live human-needed notes now sit on the post-deployment smoke, WP-0016 live
proof, and three-clean-run calibration tasks.

View File

@@ -0,0 +1,34 @@
# FOS Hub Bootstrap Sequence Status
Updated: 2026-06-27
## Purpose
Track `CUST-WP-0051-T07` and `CUST-WP-0052`: sequence `CUST-WP-0025` so FOS Hub bootstrap can resume from current repo reality rather than the older mega-hub/Keycloak/Inter-Hub assumptions.
## Current Decision
Do not restart FOS bootstrap at the old `NK-WP-0001` Keycloak path. That workplan is archived and superseded. The active identity baseline is:
- `NK-WP-0002` local identity: complete; usable for bootstrap/dev OIDC.
- `NK-WP-0012` IAM Profile v0.2: finished; canonical NetKingdom-owned profile and conformance suite.
- KeyCape/Authelia/LLDAP stack from the superseding NetKingdom path: current lightweight identity mode.
- `NK-WP-0011` expanded-mode Keycloak: proposed enterprise federation lane, not a blocker for ops-hub bootstrap.
## Sequence Board
| Area | Current state | Pickup action |
| --- | --- | --- |
| Identity | Old `CUST-WP-0025-T01` pointed at archived `NK-WP-0001`; local identity and IAM Profile v0.2 are done. | Keep T01 cancelled, T02 done, and make T03 the remaining identity gate: a protected FastAPI fixture using IAM Profile v0.2 against local-identity or KeyCape. |
| Hub extraction/dev-hub | `CUST-WP-0025-T05` through `T12` are done: hub-core exists, State Hub imports hub-core, and MCP naming moved to dev-hub. | Treat Phase 2 as complete. Do not spend pickup energy here unless consistency drift appears. |
| Ops hub | Core Hub is now the replacement platform: `CORE-WP-0008` finished the API smoke harness, activity-core sink, staging profile, CLI wrappers, UI rebuild backlog, and Custodian handoff. Live deployed smokes and cutover evidence are still open. | Continue through Core Hub deployed evidence, migration import, activity-core smoke, and cutover gates. Treat Haskell Inter-Hub as legacy compatibility or rollback evidence. |
| Old ops-hub scaffold tasks | `CUST-WP-0025-T13`-`T19` have been rewritten around Core Hub API evidence, CLI parity, deployed smoke/cutover gates, whynot-aligned UI, and cancellation of immediate standalone ops-hub MCP registration. | Execute the remaining wait/todo gates in the rewritten Phase 3. Do not resume the obsolete standalone ops-hub scaffold sequence. |
| Fin hub/business | `CUST-WP-0025-T20`-`T26` are all todo and depend on a proven multi-hub pattern. | Defer until ops-hub has a working first signal and the identity integration gate is proven. |
## Stable Pickup Order
1. Close the identity drift: T01 cancelled, T02 done, T03 remains as the one real identity integration test.
2. Use the finished `CORE-WP-0008` evidence lane and `CUST-WP-0052` reset notes as the Core Hub replacement baseline.
3. Keep `CUST-WP-0047`/`CUST-WP-0049` as legacy evidence/fallback until Core Hub deployed smoke evidence or an explicit supersede decision closes them.
4. Execute rewritten `CUST-WP-0025-T14`, `T16`, `T17`, and `T18` in API/CLI/UI order.
5. Start fin-hub/business work only after ops-hub proves the Core Hub pattern end-to-end.

View File

@@ -0,0 +1,143 @@
# Hourly RecentlyOnScope Runbook
## Purpose
This runbook answers whether the hourly RecentlyOnScope routine ran without
opening Codex Desktop.
The intended steady state is:
- activity-core owns the hourly schedule and ActivityRun audit trail.
- State Hub owns active-domain selection, report generation, report storage,
and the `recently_on_scope_hourly` progress event.
- Codex app automation is not part of the primary hourly reporting path after
`CUST-WP-0046-T06`.
## Schedule Check
From the activity-core host, confirm the definition is synced and the Temporal
schedule exists:
```bash
cd ~/activity-core
ACTIVITY_DEFINITION_DIRS=/home/worsch/the-custodian make sync-activity-definitions
```
Reconcile Temporal schedules (pick one):
```bash
curl -s -X POST 'http://localhost:8010/admin/sync?definitions=true&schedules=true'
# or: make sync-schedules
```
Expected definition:
- name: `Hourly RecentlyOnScope Reports`
- trigger: `0 * * * *`
- timezone: `Europe/Berlin`
- misfire policy: `skip`
- enabled: `false` until manual canary passes, then `true`
## Temporal Check
Use the Temporal UI or CLI on the activity-core host to inspect schedules and
recent workflows.
Look for:
- a schedule for `Hourly RecentlyOnScope Reports`
- the most recent `RunActivityWorkflow`
- a successful workflow result with `tasks_spawned: 0`
A failure in the required State Hub context source should fail the workflow
visibly rather than recording an empty context.
## ActivityRun Check
Query the activity-core database for the most recent run of the hourly
definition:
```sql
select
run_id,
fired_at,
scheduled_for,
context_snapshot->'recently_on_scope_hourly' as batch_result
from activity_runs
where activity_id = 'd104348c-d792-4377-943c-70a31e81a9bc'
order by fired_at desc
limit 5;
```
The `batch_result` should include `generated`, `skipped`, `failed`, and
`progress_event_id`.
## State Hub Progress Check
Ask State Hub for the latest batch progress events:
```bash
curl -s "http://127.0.0.1:8000/progress/?event_type=recently_on_scope_hourly&limit=5" \
| python3 -m json.tool
```
Expected:
- `event_type`: `recently_on_scope_hourly`
- `author`: `state-hub`
- `detail.generated`: domains with qualifying activity
- `detail.skipped`: quiet active domains
- `detail.failed`: empty in the healthy case
## Report Check
List reports for a domain:
```bash
curl -s "http://127.0.0.1:8000/domains/custodian/recently-on-scope/" \
| python3 -m json.tool
```
Read a report:
```bash
curl -s "http://127.0.0.1:8000/domains/custodian/recently-on-scope/<report_id>"
```
Default report directory:
```text
~/state-hub/reports/recently-on-scope/<domain_slug>/
```
## Manual Batch Canary
Before enabling the hourly schedule, run:
```bash
curl -s -X POST "http://127.0.0.1:8000/recently-on-scope/hourly" \
-H "Content-Type: application/json" \
-d '{"range":"1h","active_only":true,"include_attention":false}' \
| python3 -m json.tool
```
Then trigger the activity-core path with the same payload and confirm an
ActivityRun captures the batch response under `recently_on_scope_hourly`.
## Offline Behavior
The schedule uses `misfire_policy: skip`.
If the activity-core host is offline at the top of the hour, that hourly run is
missed. When the host returns, activity-core should resume with the next hourly
slot rather than replaying stale runs in a burst.
## Retention
State Hub currently writes one Markdown report per domain and report id. Report
ids are deterministic for exact windows and are replaced on rerun. The current
implementation does not delete old reports automatically.
Until a retention job exists, operators should treat the report directory as an
append-only operational record and prune only after confirming that no audit or
handoff references point at the target files.

View File

@@ -0,0 +1,255 @@
# Hub-Core Extraction Boundary
Last reviewed: 2026-06-07
## Purpose
This note starts `CUST-WP-0025-T05` by translating the original hub-core idea
into a current implementation boundary. The State Hub implementation no longer
lives under `the-custodian/state-hub`; the authoritative source checkout is
`/home/worsch/state-hub`, and the planned package target is
`/home/worsch/hub-core`.
The extraction must preserve a clean FOS split:
- `hub-core` owns reusable hub primitives.
- `state-hub` becomes the first dev-hub implementation and keeps development
coordination concepts such as topics, workstreams, tasks, decisions,
dependencies, SBOM, token accounting, and kaizen agents.
- Future hubs such as ops-hub and fin-hub depend on `hub-core` without pulling
in dev-hub coordination tables.
## First Package Slice
Create `/home/worsch/hub-core` as a uv-managed Python package with this initial
layout:
```text
hub_core/
__init__.py
database.py
models/
__init__.py
base.py
domain.py
managed_repo.py
agent_message.py
capability_catalog.py
capability_request.py
progress_event.py
tpsc.py
schemas/
__init__.py
domain.py
managed_repo.py
agent_message.py
capability.py
progress_event.py
tpsc.py
routers/
__init__.py
domains.py
repos.py
messages.py
tpsc.py
policy.py
```
This slice avoids the models that currently carry dev-hub foreign keys. It is
large enough to prove packaging, import style, SQLAlchemy metadata ownership,
router dependency injection, and State Hub compatibility before the more
entangled surfaces move.
Current implementation status:
- 2026-06-06: `/home/worsch/hub-core` was created and committed with base,
domain, managed repo, agent message, capability catalog, and TPSC models plus
matching schemas.
- 2026-06-06: router factory functions were added for domains, repos, messages,
TPSC, and policy lookup. These factories accept host-supplied dependencies
instead of importing State Hub globals.
- 2026-06-06: shared utilities and migration scaffold were added: slug
normalization, pagination, repo path resolution, trailing-slash path
normalization, Alembic templates, and an initial core-schema migration.
- 2026-06-06: progress event and capability request adapter seams were added.
Hub-core uses generic JSON context fields where State Hub currently has
dev-specific workstream/task/topic/decision foreign keys.
- 2026-06-07: progress and capability REST router factories were added. T05 now
has the package-side models, schemas, routers, migration scaffold, and shared
utilities needed before T06/T08.
- 2026-06-07: `HubCoreMCPServer` was added as the first T06 slice. It wraps the
generic REST endpoints with FastMCP tools and keeps the MCP layer stateless.
- 2026-06-07: T06/T07 completed in hub-core with orientation and DoI MCP tools,
canonical FOS §10 risk/alert event types, `/progress/risks` and
`/progress/alerts` REST views, and matching MCP read tools.
- 2026-06-07: T08 started in State Hub. `hub-core` is now an editable
dependency, and State Hub re-exports message and DoI response schemas from
`hub_core.schemas` with full pytest coverage passing.
- 2026-06-07: T08 schema imports expanded. Hub-core's TPSC schema/report
contract now matches State Hub, and State Hub re-exports `api.schemas.tpsc`
from `hub_core.schemas.tpsc`.
- 2026-06-07: T08 domain schema imports started. State Hub now imports base
domain schemas from `hub_core.schemas.domain` while keeping dev-hub-specific
domain detail and summary schemas local.
- 2026-06-07: T08 router imports started. State Hub now mounts the hub-core
messages router factory with State Hub's own `AgentMessage` model injected,
proving the router seam can avoid cross-metadata SQLAlchemy model imports.
- 2026-06-07: T08 policy router import completed. State Hub now mounts the
hub-core policy router factory with local path validation plus read/write
callbacks, proving non-DB routers can move behind callback seams.
- 2026-06-07: T08 TPSC router import completed. State Hub now mounts the
hub-core TPSC router factory with State Hub's own repo and TPSC models
injected, extending the host-model seam to a multi-model router.
- 2026-06-07: T08 progress router import completed. State Hub now mounts the
hub-core progress router factory with State Hub's own progress model and
schemas injected, preserving topic/workstream/task filters while gaining the
shared risk and alert progress views.
- 2026-06-07: T08 domains router import completed. State Hub now mounts the
hub-core domains router factory with State Hub's own domain/repo models and
schemas injected, plus callbacks for dev-hub detail counts and archive
validation.
- 2026-06-07: T08 additional schema imports completed. State Hub now imports
generic capability catalog/status/dispute schemas and the repo path-register
schema from hub-core, and State Hub repo create/read schemas extend the
hub-core contracts while adding dev-hub fields.
- 2026-06-07: T08 capability catalog router import completed. State Hub now
mounts the hub-core capability catalog router factory with State Hub's own
domain, repo, and catalog models injected, while keeping capability request
workflow routes local.
- 2026-06-07: T08 capability request read router import completed. State Hub now
mounts the hub-core request list/detail router factory with State Hub's own
domain and request models injected, while keeping request creation, status
transitions, acceptance, patching, dispute, and reroute workflow routes local.
- 2026-06-07: CUST-WP-0048 T04 repos router boundary resolved. State Hub now
mounts the hub-core repo registry factory for collection, lookup, detail,
update, and host-path routes with State Hub's own models and schemas injected,
while keeping onboarding, DoI, scope-health, dispatch, archive, and
consistency-sync routes local.
- 2026-06-22: HUB-WP-0002 completed. Added
`create_capability_request_write_router` with host callbacks for routing,
model construction, flow transitions, notifications, task-unblock, patch,
dispute, and reroute side effects. State Hub mounts write routes from the
factory while keeping dev-hub columns (`requesting_workplan_id`,
`blocking_task_id`, `fulfilling_workplan_id`) on its extended model.
- 2026-06-22: `HubCoreMCPServer.attach_to()` registers generic MCP tools on a
host server with `exclude` for dev-hub overrides. State Hub now composes
hub-core messaging, capability read lifecycle, TPSC list/DoI, and FOS §10
tools while keeping enriched orientation, repo registration, capability
request creation, TPSC ingest, and service registration tools local.
- 2026-06-22: **CUST-WP-0048 closed.** Full regression: hub-core 27/27, State
Hub 426/426. Health probe uses injected `get_session` (fixes asyncpg pool
flake). Remaining deferred seams: ProgressEvent FK → `subject_refs` mapping;
optional CapabilityRequest workplan columns → JSON context.
## Extract Now
These State Hub files are suitable for the first extraction after import-path
rewriting and small router seams:
| Source in `/home/worsch/state-hub` | Target role |
| --- | --- |
| `api/models/base.py` | Declarative base, timestamps, UUID helper. |
| `api/models/domain.py` | Core domain identity; remove relationships to dev-hub-only models from core. |
| `api/models/managed_repo.py` | Core repo registry; make `topic_id`, SBOM, and sync timestamps extension fields or keep them in dev-hub until a second pass. |
| `api/models/agent_message.py` | Generic agent inbox and thread model. |
| `api/models/tpsc.py` | Third-party service catalog/snapshot primitives. |
| `api/schemas/domain.py` | Core domain schemas; split dev-hub counts from generic read models. |
| `api/schemas/managed_repo.py` | Core repo schemas; keep dispatch/scope-health schemas in dev-hub. |
| `api/schemas/agent_message.py` | Generic message schemas. |
| `api/schemas/tpsc.py` | Generic TPSC schemas. |
| `api/routers/messages.py` | Mostly self-contained generic router. |
| `api/routers/progress.py` | Generic progress-event router once dev-hub foreign keys move behind `subject_refs` or extension mapping. |
| `api/routers/capability_requests.py` | Generic capability catalog/request router once dev-hub flow side effects and task unblocking stay in dev-hub. |
| `api/routers/tpsc.py` | Generic catalog and GDPR report router. |
| `api/routers/policy.py` | Generic policy document router if policy roots become configurable. |
The first committed router seam is factory-based rather than global:
```python
from hub_core.routers import create_domains_router
app.include_router(create_domains_router(get_session))
```
That shape lets each hub keep its own database session configuration and mount
only the generic routers it wants.
## Shared Utilities
The initial utility set is intentionally small and dependency-light:
| Module | Purpose |
| --- | --- |
| `hub_core.utils.slugs` | Convert user-facing names into stable lowercase slugs. |
| `hub_core.utils.pagination` | Shared limit/offset bounds and SQLAlchemy pagination. |
| `hub_core.utils.paths` | Resolve repo paths from `host_paths` before falling back to `local_path`. |
| `hub_core.utils.routing` | Normalize a path or URL path component while preserving query strings and fragments. |
## Migration Scaffold
`/home/worsch/hub-core` now carries Alembic template files under
`hub_core/migrations/` plus `versions/0001_core_schema.py`. The first migration
covers only the currently extracted core tables:
- `domains`
- `managed_repos`
- `agent_messages`
- `capability_catalog`
- `capability_requests`
- `progress_events`
- `tpsc_catalog`
- `tpsc_snapshots`
- `tpsc_entries`
## Needs An Adapter Seam
These are still part of the target architecture, but the current State Hub
implementation is coupled to dev-hub concepts:
| Surface | Coupling to resolve |
| --- | --- |
| `Domain` and `domains.py` detail views | Detail counts now use a dev-hub callback behind the hub-core router factory. Domain relationships still need a later model split if State Hub stops carrying topics/goals on the core table. |
| `ManagedRepo` | State Hub create/read schemas now extend hub-core contracts, with `topic_id`, SBOM fields, and state-sync timestamps kept as dev-hub extensions. Generic repo registry collection, lookup, detail, update, and host-path routes now mount from the hub-core factory; State Hub keeps onboarding, DoI, scope-health, dispatch, archive, and consistency-sync behavior locally. |
| `CapabilityRequest` | Write routes now mount from `create_capability_request_write_router` with host callbacks. State Hub keeps workplan/task columns on its model; generic hubs use `request_context` / `fulfillment_context` JSON. Optional future step: map State Hub columns into JSON and drop duplicate fields. |
| `ProgressEvent` | Adapter seam implemented with generic `subject_refs`; State Hub still needs a later refactor to map topic/workstream/task/decision foreign keys into that field or a dev-hub extension table. |
| MCP tools in `mcp_server/server.py` | Generic tools register via `HubCoreMCPServer.attach_to(mcp, exclude=...)`. Remaining local tools: dev-hub orientation (`get_state_summary`, `get_domain_summary`), extended repo/capability/TPSC contracts, and all workstream/task/decision tooling. |
The first two adapter seams are now implemented in hub-core:
- `ProgressEvent.subject_refs`: generic JSON references for hub-local subjects.
- `CapabilityRequest.request_context` and `fulfillment_context`: generic JSON
context for hub-local workstreams, tasks, incidents, services, budgets, or
other future hub entities.
## Keep In Dev-Hub
The following State Hub areas should not move into hub-core during T05:
- Topics, workstreams, tasks, decisions, dependencies, and flow state.
- Extension points, technical debt, interface changes, SBOM, token events, and
contribution accounting.
- Dashboard-specific loaders and Observable views.
- Workplan-file parsing and consistency reconciliation.
- Kaizen agents, scope health, dispatch views, and recently-on-scope reports.
## Verification Plan
The first hub-core commit should pass these checks before State Hub is refactored
to import it:
1. `python3 -m compileall hub_core`
2. A minimal import test that imports every model, schema, and router module.
3. SQLAlchemy metadata inspection proving the initial core tables are registered.
4. A FastAPI smoke app that mounts the extracted routers with an injected
`get_session` dependency.
5. `cd /home/worsch/state-hub && make test` remains green before and after the
editable `hub-core` dependency is introduced.
## Next Step
**CUST-WP-0048** is finished; **CUST-WP-0025-T08** is done. Proceed to Phase 2
dev-hub rename (**CUST-WP-0025-T09+**): MCP server name, config migration, and
integration-point renames. Optional follow-up extractions (not blocking rename):
- map State Hub `ProgressEvent` foreign keys into `subject_refs`
- map CapabilityRequest workplan/task columns into JSON context fields

View File

@@ -0,0 +1,143 @@
# Infrastructure Stabilization Pickup Checkpoint
Updated: 2026-06-27
Coordinator workplan: `CUST-WP-0051`
## Purpose
This checkpoint is the restart surface for the infrastructure stabilization
metaplan. It consolidates the workplan review, unblock boards, current State
Hub registration state, and the next strategic picks.
Use this file first when resuming the lane. Then open the source workplan named
in the relevant row and continue from its task state.
## Registration State
State Hub active workstreams queried on 2026-06-27:
| Workstream | Current pickup meaning |
| --- | --- |
| `artifact-store-wp-0007` | Start D7.1/D7.2 assessment and compatibility harness; D7.3 STS vending may route to NetKingdom. |
| `ihub-wp-0022` | Ops-hub evidence intake contract is aligned to live vocabulary; runtime key custody, protected widget lookup, and smoke remain. |
| `cust-wp-0047` | Now-view waits on the ops-hub Inter-Hub evidence lane, not on service inventory collection. |
| `cust-wp-0049` | Bootstrap access helper/runbook is ready; authenticated execution is operator-gated. |
| `cust-wp-0051` | This metaplan is the coordination layer for remaining cross-workplan gates. |
| `activity-wp-0016-llm-output-robustness-trust-boundary` | Repo-side output robustness bundle is prepared; live deploy/smoke proof remains. |
| `three-phoenix-ha-cluster` | HA substrate remains future critical-workload work, not the current State Hub cutover blocker. |
| `rail-ho-wp-0005` | Forgejo production migration is parked behind explicit design, SMTP, backup, runner, and cutover decisions. |
| `net-wp-0020` | OpenBao unseal/token custody remains an operator design and smoke gate. |
| `issue-wp-0003` | issue-core service is healthy; activity-core REST emission wiring remains. |
| `activity-wp-0006` | Calibration waits on the post-WP-0016 live daily-triage smoke and three clean scheduled runs. |
| `cust-wp-0038` | Full State Hub HA migration is deferred until the pragmatic railiance01 path stabilizes. |
| `cust-wp-0025` | FOS bootstrap resumes from identity integration and ops-hub evidence, not the old mega-hub scaffold. |
| `cust-wp-0011` | Active State Hub migration path; next gate is explicit cutover approval. |
Hygiene status:
- `CUST-WP-0045-cutover-runbook` is no longer active; it is a finished runbook
record, not an empty active workstream.
- `CUST-WP-0014` is reopened as `backlog`; it is no longer a done workplan with
todo task blocks.
- Completed or cancelled tasks no longer carry the stale human-needed flags
cleared during this stabilization session.
- `make fix-consistency REPO=the-custodian` still reports pre-existing C-12
orphan-row warnings, but the relevant workplan lifecycle and task states sync.
- `RAIL-BS-WP-0006-staged-promotion-lifecycle` is finished: all seven tasks
are done, the workstream is finished in State Hub, and the file frontmatter
is `status: finished`.
## Blocker Board
No live credential, access, or approval gate is unowned. Do not ask
`ops-warden` for secret values; use the route catalog, the `warden access`
assist/proxy surface where the catalog lane allows it, and the owning subsystem.
For credential-related blockers, classify the environment posture and workload
maturity first. Dev/test work can use synthetic contract doubles; production
real-value work needs owner custody, policy gates where applicable, and
non-secret evidence. See `docs/ops-warden-secret-posture-review.md`.
Do not implement ops-warden changes from this Custodian lane. New ops-warden
needs should be posted through State Hub as requirements or suggestions for the
separate ops-warden worker.
| Gate | Owner/route | Non-secret evidence to collect | Next action |
| --- | --- | --- | --- |
| State Hub pragmatic cutover | Custodian operator approval; `CUST-WP-0011-T07` | Final dump id/time, row-count comparison, chosen private endpoint, stabilization notes | Approve freeze/final restore and make railiance01 State Hub primary, or leave WSL2 primary explicitly. |
| State Hub fallback retirement | Custodian/operator approval; `CUST-WP-0038-T08` | HA failover drill id, restore drill id, stabilization pass | Keep deferred until after HA drills; do not retire WSL2 fallback early. |
| Inter-Hub ops-hub bootstrap | `inter-hub-bootstrap-ssh`, `openbao-api-key`, `ssh-cert-host-access` as needed | Hub id, manifest id, widget count, runtime key prefix only, smoke result | Legacy/fallback only. Prefer Core Hub deployed smoke; run attended Inter-Hub bootstrap only by explicit operator supersede/rollback decision. |
| Ops-hub runtime evidence key | `openbao-api-key` / OpenBao custody | OpenBao path/version or populated key count, event smoke id | Do not materialize legacy `OPS_HUB_KEY` until a deployed Core Hub smoke or explicit legacy Inter-Hub smoke is ready to use it. |
| Daily-triage live proof | activity-core deploy/runtime operator | State Hub `daily_triage` id, output-valid or partial/quarantine status, working-memory path | Deploy WP-0016 code/schema and bounded runtime prompt bundle, then run railiance01 smoke. |
| activity-core to issue-core | route `activity-core-issue-sink` | `actcore-runtime-secret` has key, activity-core points to issue-core port `8765`, HTTP 201, Gitea issue id | Inject `ISSUE_CORE_API_KEY` through approved custody, set REST sink env, restart/sync, run safe emission. |
| Forgejo production design | Forgejo/operator decisions plus OpenBao/KeyCape/ops-bridge routes as needed | Decision id, SMTP smoke, backup/restore drill, package/action smoke, cutover approval id | Resolve T02 production choices before any production cutover work. |
| OpenBao unseal and credential helper | `openbao-api-key`, `railiance-infra-principals`, `ssh-cert-host-access`, `key-cape-oidc-login` | Policy names, role names, token accessor only, allow/deny smoke | Approve custody profile and apply narrow issuer policies before live helper smokes. |
## Daily Automation Evidence
The scheduled daily-triage runner is alive and writing State Hub plus working
memory evidence. The current blocker is output validation, not scheduling or
sink reachability.
Latest clean scheduled run:
- 2026-06-25: State Hub event `cbba6bc0-14cb-492b-ab23-74b9349326c8`,
schema-valid daily triage, working memory written.
Latest failed scheduled runs:
- 2026-06-26: event `97fd20a0-eee0-45ea-8290-6d91874e1515`, validation failed
at char 5268, working memory written.
- 2026-06-27: event `c5ab50a8-404b-4e30-849f-841b059ace65`, validation failed
at char 5246, working memory written.
Resume from `docs/daily-triage-stabilization-status.md` and
`ACTIVITY-WP-0016` before restarting the three-clean-run gate.
## Production Service Summary
| Surface | Stable fact | Remaining gate |
| --- | --- | --- |
| State Hub | Pragmatic railiance01 path has image, manifests, empty deploy, migrations, restored WSL2 data, row-count comparison, and healthy API through `CUST-WP-0011-T06`. | `CUST-WP-0011-T07` cutover approval, then stabilization; HA path stays deferred. |
| Inter-Hub / Core Hub | Public `https://hub.coulomb.social/api/v2/hubs` exposes `ops-hub`; `CORE-WP-0008` finished the Core Hub API smoke harness, activity-core sink, staging profile, CLI wrappers, UI backlog, and Custodian handoff. | Run deployed Core Hub smoke, staging import, activity-core sink smoke, and readiness summary; keep Haskell Inter-Hub only for migration/rollback proof. |
| ops-hub evidence | `CUST-WP-0025-T14` is done with the Core Hub ops evidence contract spec. `CUST-WP-0025-T13` through `T19` now use Core Hub API/CLI/UI gates; `CUST-WP-0047` and `CUST-WP-0049` remain legacy/fallback records. | Execute `CUST-WP-0025-T16`, `T17`, and `T18`; close legacy Inter-Hub waits only through deployed Core Hub evidence or explicit supersede decision. |
| issue-core | ArgoCD service is healthy on port `8765`; image `0.2.1`; ExternalSecret Ready; authenticated smoke created Gitea issue `175`. | activity-core still needs `ISSUE_CORE_API_KEY`, URL port `8765`, `ISSUE_SINK_TYPE=rest`, and a safe emission smoke. |
| Forgejo | Migration inventory/design lane is active but pre-cutover. | Production design decisions, SMTP/email recovery, package registry, Actions, backup/restore, migration drill, cutover approval. |
| artifact-store | D7.1 is done; D7.2 has an opt-in live MinIO compatibility harness and manual smoke docs. No live secret handoff is recorded. | Run D7.2 against an approved MinIO-compatible endpoint, then route D7.3 STS vending through identity/platform custody before changing credential behavior. |
| FOS hub | Old NK-WP-0001 Keycloak prerequisite is cancelled; NK-WP-0002 local identity, IAM Profile v0.2, the Core Hub FastAPI IAM Profile integration test, and Core Hub operator UI first screens are done; hub-core extraction/dev-hub work is done; CUST-WP-0025 Phase 3 has been rewritten for Core Hub. | Execute the remaining Core Hub deployed evidence and cutover gates: `CUST-WP-0025-T16` and `T17`. |
## Next-Pick List
1. Execute the remaining rewritten `CUST-WP-0025` Core Hub gates: deployed
smoke and activity-core proof (`T16`) and cutover decision coupling (`T17`).
T03, T14, and T18 are complete as the identity integration template, ops
evidence/read-model contract, and operator UI first-screen gates.
2. Keep `CUST-WP-0047` and `CUST-WP-0049` as legacy evidence/fallback until
Core Hub deployed smoke evidence or an explicit supersede decision closes
them.
3. Deploy the activity-core WP-0016 code/schema and bounded runtime prompt
bundle, then run the railiance01 daily-triage smoke.
4. Complete the issue-core handoff by wiring activity-core to port `8765` with
`ISSUE_SINK_TYPE=rest` and one known-safe emission smoke.
5. Request explicit State Hub cutover approval for `CUST-WP-0011-T07`, or
record that WSL2 remains primary for the next operating period.
6. Run artifact-store D7.2 live MinIO-compatible evidence; Forgejo and storage
work can now inherit the finished staged-promotion gates.
7. Keep Forgejo cutover and State Hub HA work parked until their human decision
and drill gates are satisfied.
## Resume Commands
```bash
cd /home/worsch/the-custodian
sed -n '1,260p' workplans/CUST-WP-0051-infrastructure-stabilization-metaplan.md
sed -n '1,260p' docs/infrastructure-stabilization-pickup-checkpoint.md
sed -n '1,260p' docs/credential-custody-unblock-board.md
```
After workplan edits, sync from State Hub:
```bash
cd /home/worsch/state-hub
make fix-consistency REPO=the-custodian
```

View File

@@ -0,0 +1,49 @@
# Near-Term Production Service Lanes Status
Updated: 2026-06-27
## Purpose
Track `CUST-WP-0051-T05`: finish or park near-term production service lanes
before starting larger migrations.
## Lane Board
| Lane | Current state | Next action |
| --- | --- | --- |
| `issue-wp-0003` | issue-core is live through ArgoCD; image `0.2.1`, Service port `8765`, ExternalSecret Ready, authenticated smoke created Gitea issue `175`. | Do not flip activity-core blindly. First inject `ISSUE_CORE_API_KEY` into `actcore-runtime-secret` through route `activity-core-issue-sink`; then set activity-core `ISSUE_CORE_URL` to port `8765`, set `ISSUE_SINK_TYPE=rest`, restart/sync, and run one safe emission smoke. |
| `rail-ho-wp-0005` | Forgejo migration remains pre-implementation. Inventory is in progress; production decisions, SMTP/email recovery, cutover, and legacy retirement are human-gated. | Resolve T02 production decisions first, then build the disposable Forgejo probe. Do not start production cutover before promotion lifecycle, email recovery, package registry, Actions, backup/restore, and migration drill pass. |
| `artifact-store-wp-0007` | D7.1 is done. The dated MinIO/fork/object-store landscape assessment chose a compatibility-profile lane rather than a direct MaxIO fork. D7.2 is in progress with an opt-in live MinIO pytest harness and manual smoke docs; no secret value was read or recorded. | Run the D7.2 harness against an approved MinIO-compatible endpoint and capture health/round-trip/multipart evidence. Route D7.3 STS credential vending through identity/platform custody before changing artifact-store credential behavior. |
| `staged-promotion-lifecycle` | Finished. Lifecycle spec, app contract, overlay scaffold, Stage 1 runner, canary template, deploy/observe tooling, promote/rollback tooling, and onboarding guide are done. | Use the finished promotion gates as prerequisites for Forgejo/source-forge and storage production work. |
## Credential And Operator Routing
`activity-core -> issue-core` REST emission uses route catalog id
`activity-core-issue-sink`.
Route lookup on 2026-06-27:
- owner: `activity-core + issue-core`
- ops-warden executes: no
- status: active
- next action: follow `ops-warden/wiki/playbooks/activity-core-issue-sink.md#worker-checklist`
No secret value was read or written. The required non-secret evidence is:
- `actcore-runtime-secret` has an `ISSUE_CORE_API_KEY` data key;
- activity-core worker consumes `ISSUE_CORE_URL=http://issue-core.issue-core.svc.cluster.local:8765`;
- `ISSUE_SINK_TYPE=rest`;
- one known-safe activity-core emission returns issue-core HTTP 201 and creates
a Gitea issue.
## Pickup Order
1. Close the issue-core handoff gate because the service is already healthy and
only activity-core live emission remains.
2. Treat staged-promotion as complete; use it as the gate model before
Forgejo cutover work accelerates.
3. Run artifact-store D7.2 live evidence against an approved MinIO-compatible
endpoint, with D7.3 routed to identity/platform custody if STS vending is
not artifact-store-owned.
4. Keep Forgejo production cutover parked behind explicit T02 decisions and the
staged-promotion/backup/email/package/action gates.

View File

@@ -0,0 +1,120 @@
# Ops Hub Inter-Hub Evidence Lane Status
Date: 2026-06-27
Workplan: `CUST-WP-0051-T03`
Related tasks: `CUST-WP-0047-T05`, `CUST-WP-0049-T06`, `IHUB-WP-0022-T03/T04/T07`
## Summary
The evidence lane is partially live but not ready to close.
Production Inter-Hub already exposes the public ops-hub bootstrap surface and
has an `ops-hub` row plus the ops-hub seed vocabulary. The remaining blockers
are:
1. authenticated bootstrap/runtime-key execution is still operator-gated;
2. protected widget and hub-registry reads cannot be verified without the
ops-hub runtime key;
3. the older `IHUB-WP-0022` activity-core mapping contract does not match the
currently live ops-hub seed vocabulary.
No secret values were requested, read, printed, or stored during this probe.
## Public Probe Evidence
Base URL: `https://hub.coulomb.social`
| Probe | Result |
| --- | --- |
| `GET /api/v2/hubs` | HTTP `200`; contains `ops-hub` |
| `GET /api/v2/openapi.json` | HTTP `200`; includes `/hubs`, `/hub-capability-manifests`, `/api-consumers`, `/policy-scopes` |
| `GET /api/v2/widgets` | HTTP `401`, protected as expected |
| `GET /api/v2/hub-registry` | HTTP `401`, protected as expected |
| `GET /api/v2/widget-types` | HTTP `200`; 14 ops widget types visible |
| `GET /api/v2/event-types` | HTTP `200`; 15 ops event types visible |
| `GET /api/v2/annotation-categories` | HTTP `200`; 10 ops annotation categories visible |
| `GET /api/v2/policy-scopes` | HTTP `200`; 7 ops policy scopes visible |
| `GET /api/v2/hub-capability-manifests?hubId=<ops-hub-id>` | HTTP `401`, protected as expected |
Observed public ops-hub id: `4f6e4cf7-6a96-4ff2-8a37-08c9f9e405d2`.
The existing `ops-hub/scripts/interhub-gate-probe.py` exits nonzero because it
still expects unauthenticated `/api/v2/hubs` to return `401`. The live contract
returns `200` for public hub discovery and `401` for protected surfaces such as
`/api/v2/widgets` and `/api/v2/hub-registry`.
## Live Ops Vocabulary
The live public registry matches `ops-hub/seeds/ops-hub-manifest.draft.json`:
- widget types: `ops-environment`, `ops-host`, `ops-cluster`, `ops-service`,
`ops-service-catalog`, `ops-endpoint`, `ops-release`, `ops-backup-set`,
`ops-secret-set`, `ops-runbook`, `ops-incident`, `ops-readiness-gate`,
`ops-migration-wave`, `ops-risk`;
- event types: `ops-inventory-registered`, `ops-inventory-updated`,
`ops-service-discovered`, `ops-health-checked`, `ops-release-observed`,
`ops-endpoint-verified`, `ops-backup-verified`, `ops-restore-tested`,
`ops-runbook-executed`, `ops-drift-detected`, `ops-risk-raised`,
`ops-risk-accepted`, `ops-readiness-gate-updated`,
`ops-migration-gate-passed`, `ops-migration-gate-failed`;
- policy scopes: `ops-local`, `ops-transitional-prod`, `ops-production`,
`ops-threephoenix`, `ops-registry`, `ops-secrets`,
`ops-backup-retention`.
## Contract Mismatch
`inter-hub/docs/contracts/ops-hub-activity-core-mapping.md` and
`ops-hub-activity-core-event-payloads.md` still describe the early
activity-core proposal:
| Contract name | Live seed status | Recommended action |
| --- | --- | --- |
| `ops-service-observed` | Not in live event registry | Rename to `ops-service-discovered`, or add an explicit alias event in the ops-hub manifest. |
| `ops-endpoint-verified` | Live | Keep. |
| `ops-access-path-checked` | Not in live event registry; no `ops-access-path` widget type in seed | Either add access-path vocabulary/widgets, or defer access-path submissions and keep State Hub fallback. |
| `ops-backup-verified` | Live | Keep, but map to `ops-backup-set` widget type. |
| `ops-inventory-drift` | Not in live event registry | Rename to `ops-drift-detected`, or add an explicit alias event. |
| `ops-evidence` policy scope | Not in live policy scopes | Use an existing ops scope or add `ops-evidence` to the manifest and activate it. |
| aggregate refs such as `ops:service:aggregate` | Not in `ops-hub/seeds/ops-hub-widgets.seed.json` | Seed aggregate intake widgets or change mapping to the existing entity/readiness widgets. |
| widget types such as `ops-service-card` | Not in live widget types | Use live widget types like `ops-service`, `ops-endpoint`, `ops-backup-set`, and `ops-readiness-gate`. |
## 2026-06-27 Contract Alignment
The Inter-Hub contract docs were revised in `/home/worsch/inter-hub` to target
the live ops-hub seed vocabulary:
- `ops-service-observed` is now a transition alias for
`ops-service-discovered`.
- `ops-inventory-drift` is now a transition alias for `ops-drift-detected`.
- `ops-access-path-checked` is explicitly deferred to State Hub fallback until
ops-hub adds access-path vocabulary or a readiness/risk mapping decision.
- The old `ops-evidence` policy scope is replaced by declared live scopes such
as `ops-production`, `ops-registry`, and `ops-backup-retention`.
- Payload examples now post only live manifest event types.
This removes the known contract-drift blocker before the attended bootstrap.
The remaining gate is authenticated widget lookup, any missing backup/risk seed
widget, runtime key custody, and protected event submission smoke.
## Current Closure State
`CUST-WP-0049-T06` remains `wait`: the helper and runbook are ready, but an
approved authenticated execution lane is still required.
`CUST-WP-0047-T05` remains `wait`: the ops-hub row and vocabulary are visible,
but seeded widgets and event acceptance cannot be proven without the protected
runtime path.
`IHUB-WP-0022-T03/T04/T07` remain gated: before an end-to-end smoke, reconcile
the activity-core mapping contract to the live ops-hub seed vocabulary or add
the missing aliases/aggregate widgets to the manifest.
## Next Pick
1. Use the aligned live-vocabulary contract for the attended
`CUST-WP-0049-T06` bootstrap.
2. Confirm protected widget ids and seed any missing backup/risk target widgets
required by the mapping.
3. Store or confirm `OPS_HUB_KEY` through OpenBao, then run the protected
widget/hub-registry/event smoke.

View File

@@ -0,0 +1,77 @@
# Ops Hub Service Catalog Now View
<!-- generated by ops/render_service_inventory.py; edit ops/service-inventory.yml instead -->
Source: `ops/service-inventory.yml`
Inventory last reviewed: `2026-06-05`
This is the repo-native first view for `CUST-WP-0047`. It exists so an
operator can answer what is running where before the full standalone
`ops-hub` application is available.
## Summary
| Metric | Count |
|---|---:|
| Environments | 4 |
| Hosts | 3 |
| Clusters | 3 |
| Services | 8 |
| Services: observed_ok | 2 |
| Services: unknown | 6 |
## Service Catalog
| Service | Where | Owner | Endpoint | Health | Data | Access | Top Gap |
|---|---|---|---|---|---|---|---|
| Gitea (gitea) | CoulombCore<br>type: k3s; cluster: coulombcore-k3s; namespace: default | railiance-apps | https://gitea.coulomb.social/v2/<br>Expected: status 401, OCI registry auth challenge | unknown<br>2026-05-16: Inventory draft records Helm release gitea, namespace default, app version 1.25.4, NodePort 32166, and registry auth challenge. | database:gitea-db<br>pvc:default/gitea-shared-storage | k8s: unknown (coulombcore-k3s/default) | Package token and push/pull verification need current evidence. |
| Gitea Database (gitea-database) | CoulombCore<br>type: k3s; cluster: coulombcore-k3s; namespace: databases | railiance-platform | - | unknown<br>2026-05-16: /home/worsch/helix-forge/wiki/OpsHubInventory.md | - | k8s: unknown (coulombcore-k3s/databases) | Backup and restore evidence not recorded in ops inventory. |
| Gitea Shared Storage (gitea-shared-storage) | CoulombCore<br>type: k3s; cluster: coulombcore-k3s; namespace: default | railiance-platform<br>railiance-apps | - | unknown<br>2026-05-16: /home/worsch/helix-forge/wiki/OpsHubInventory.md | - | k8s: unknown (coulombcore-k3s/default/pvc/gitea-shared-storage) | Package blob backup and restore evidence not confirmed. |
| State Hub (state-hub) | Local Workstation<br>type: local-process; host: local-workstation; ports: 8000 | state-hub<br>the-custodian | http://127.0.0.1:8000/state/health<br>Expected: status 200, health response | observed_ok<br>2026-06-05: State Hub accepted inbox, task, and progress API calls. | postgresql:state-hub | http: observed_ok (http://127.0.0.1:8000) | Future cluster deployment readiness still needs ops evidence. |
| Inter-Hub (inter-hub) | ThreePhoenix Production<br>type: external; public_endpoint: https://hub.coulomb.social | inter-hub | https://hub.coulomb.social/api/v2/openapi.json<br>Expected: status 200, OpenAPI document | unknown<br>2026-05-16: /home/worsch/helix-forge/wiki/OpsHubInventory.md | - | https: unknown (https://hub.coulomb.social) | ops-hub bootstrap requires authenticated UI flow or deployment-side migration. |
| activity-core (activity-core) | Railiance01<br>type: k3s; cluster: railiance01-k3s; namespace: activity-core | activity-core<br>the-custodian | activity-core API health endpoint<br>Expected: status 200, healthy DB and Temporal status | observed_ok<br>2026-05-23: API health, worker rollout, Temporal CLI schedule listing, and State Hub bridge were verified. | postgresql:activity-core<br>temporal:activity-core<br>nats:railiance01 | k8s: observed_ok (railiance01-k3s/activity-core) | Add explicit ops inventory probes and evidence events. |
| Ops Bridge (ops-bridge) | Local Workstation<br>type: bridge; host: local-workstation | ops-bridge | - | unknown<br>2026-05-16: Bridge is useful for connected-server visibility but is not itself the service catalog. | - | ssh-tunnel: unknown (connected remote servers) | Emit reachability evidence into ops-hub instead of relying on bridge state as inventory. |
| Haskell Build Agent (haskell-build-agent) | Local Workstation<br>type: systemd; host: haskell-build-vm | the-custodian | http://127.0.0.1:18000<br>Expected: VM can reach State Hub through SSH forward | unknown<br>undated: Build agent is a systemd service and registers with State Hub on boot. | - | ssh: unknown (local workstation reverse tunnel port 12222) | Current tunnel and capability registration need live evidence in ops-hub. |
## Open Operating Gaps
### Gitea (`gitea`)
- Package token and push/pull verification need current evidence.
- Backup and restore evidence for database and shared storage not recorded in ops inventory.
### Gitea Database (`gitea-database`)
- Backup and restore evidence not recorded in ops inventory.
### Gitea Shared Storage (`gitea-shared-storage`)
- Package blob backup and restore evidence not confirmed.
### State Hub (`state-hub`)
- Future cluster deployment readiness still needs ops evidence.
### Inter-Hub (`inter-hub`)
- ops-hub bootstrap requires authenticated UI flow or deployment-side migration.
### activity-core (`activity-core`)
- Add explicit ops inventory probes and evidence events.
### Ops Bridge (`ops-bridge`)
- Emit reachability evidence into ops-hub instead of relying on bridge state as inventory.
### Haskell Build Agent (`haskell-build-agent`)
- Current tunnel and capability registration need live evidence in ops-hub.
## Next Evidence Events
- `ops-service-observed` for each runtime object confirmed by a probe.
- `ops-endpoint-verified` for HTTP, HTTPS, tunnel, or cluster endpoints.
- `ops-access-path-checked` for non-secret access path checks.
- `ops-backup-verified` where backup and restore evidence exists.
- `ops-inventory-drift` when observed state differs from this inventory.

View File

@@ -0,0 +1,94 @@
# Ops Hub Service Inventory
Date: 2026-06-05
## Purpose
The first ops-hub "now view" should answer one practical question:
> What service is running where, who owns it, how is it reached, and what
> evidence says it is alive?
The lowest-effort path is a small read model, not a full new application. The
read model starts as `ops/service-inventory.yml`, can be surfaced through
Inter-Hub ops widgets, and can later be ingested by the standalone `ops-hub`
repo planned in `CUST-WP-0025`.
## Operating Model
- Git owns the declared inventory.
- Inter-Hub widgets expose the visible ops entities.
- Interaction events provide timestamped operational evidence.
- activity-core runs repeatable probes and writes evidence.
- State Hub continues to own workstreams, tasks, decisions, and progress. It is
not the service catalog.
## Minimal Record Shape
Each service record should include:
- `id`: stable lowercase service id, for example `state-hub`.
- `name`: human-readable name.
- `lifecycle_state`: `observed`, `planned`, `target`, or `retired`.
- `health_status`: `unknown`, `observed_ok`, `degraded`, `down`, or `planned`.
- `environment`: environment id where the service currently belongs.
- `owner_repos`: repos that own desired state, runtime code, or runbooks.
- `runtime`: runtime kind and location details, such as `local-process`,
`k3s`, `systemd`, `external`, or `bridge`.
- `endpoints`: public, local, cluster, or tunnel endpoints with expected
non-secret checks.
- `backing_stores`: databases, PVCs, object stores, or external stores that
must be backed up with the service.
- `access_paths`: non-secret descriptions of SSH, Kubernetes, HTTP, or tunnel
paths.
- `evidence`: links to docs, progress events, probe results, or workplans.
- `gaps`: missing evidence or operating controls.
The schema lives at `schemas/ops-service-inventory.schema.json`.
## First View
The initial ops-hub view can be a dense table:
| Column | Meaning |
|---|---|
| Service | `name` plus `id` |
| Where | environment, host, cluster, namespace |
| Owner | owner repo and desired state source |
| Endpoint | primary endpoint and expected check |
| Health | latest health status and last evidence timestamp |
| Data | backing stores and backup gap summary |
| Access | access path status |
| Gaps | highest-priority missing operating evidence |
This is enough to make scattered operational reality visible without waiting
for a full incident system, runbook executor, or custom database.
The repo-native version is rendered to `docs/ops-hub-service-catalog.md`:
```bash
make ops-inventory-view
```
## Evidence Events
Use a small event vocabulary first:
- `ops-service-observed`: service/runtime object was observed.
- `ops-endpoint-verified`: endpoint responded as expected.
- `ops-access-path-checked`: access path was checked without storing secrets.
- `ops-backup-verified`: backup and restore evidence exists.
- `ops-inventory-drift`: observed state differs from declared inventory.
Event metadata should reference the stable inventory id and include non-secret
probe output only.
## Promotion Path
1. Keep `ops/service-inventory.yml` as the source artifact.
2. Seed or update Inter-Hub widgets from the inventory ids.
3. Let activity-core run probes and submit evidence events.
4. Build the first ops-hub view from inventory plus latest evidence.
5. When the standalone `ops-hub` repo exists, ingest the same inventory and
evidence events into the proper Service, AccessPath, Runbook, and Incident
models from `CUST-WP-0025`.

View File

@@ -0,0 +1,42 @@
# ops-warden Secret Posture Review
Date: 2026-06-27
Owner: the-custodian coordination; ops-warden owns the source standard.
## Review Outcome
ops-warden is moving from a simple "SSH certs plus route pointers" surface to a
more useful access and conformance steward:
- it still directly issues only the SSH certificate lane;
- it routes other credential needs to their owning subsystem;
- `warden access` may advise or proxy `exec_capable` lanes as the caller, without
storing values or becoming a secret broker;
- WARDEN-WP-0015 adds workload security posture: `dev/test/prod` environment
posture plus `M0-M3` workload maturity and a secret-flow lattice.
This helps CUST-WP-0051 because a security blocker can now be classified instead
of left as a generic "credentials needed" stop.
## Blocker Refinement Rules
| Situation | CUST-WP-0051 action |
| --- | --- |
| Dev/test implementation needs a credential-shaped dependency | Use synthetic contract doubles; do not wait for production secrets. |
| Production smoke needs a real value | Route to the owner, collect non-secret evidence, and keep the value out of Codex-visible surfaces. |
| Route is `exec_capable` | Prefer `warden access --fetch/--exec` as the caller over copy/paste handling. |
| Workload maturity is below the secret requirement | Keep the blocker; resolve by maturity advancement, policy/design change, or avoiding the secret. |
| OpenBao unseal, break-glass, or issuer custody is unresolved | Keep as operator ceremony/design blocker. |
## Current CUST-WP-0051 Read
| Gate | Refined blocker |
| --- | --- |
| Ops-hub runtime `OPS_HUB_KEY` | Production real-value custody gate; implementation is not blocked, live smoke is. |
| Inter-Hub ops-hub bootstrap | Access/custody gate with an attended execution path; no need to request secret values from ops-warden. |
| activity-core -> issue-core | Production API key injection/evidence gate; route is known through `activity-core-issue-sink`. |
| OpenBao unseal/helper | M3-style ceremony gate; operator design remains required. |
| Forgejo production migration | Production readiness gate spanning credentials, recovery drills, and cutover approval. |
Evidence stays non-secret: route id, owner, posture, maturity, policy decision id,
OpenBao path/version, populated-key count, smoke id, token accessor, or drill id.

View File

@@ -0,0 +1,34 @@
# State Hub Migration Strategy Status
Updated: 2026-06-27
## Decision
Use `CUST-WP-0011` as the active State Hub stabilization path.
Keep `CUST-WP-0038` and `RAIL-BS-WP-0007` as deferred HA/ThreePhoenix follow-up lanes.
Rationale: the pragmatic railiance01 deployment has already completed image
publish, cluster manifests, empty deploy, migrations, WSL2 data restore, row-count
comparison, and cluster API health checks. The remaining work is cutover and
stabilization, not initial buildout.
## Current State
| Path | State | Next action |
| --- | --- | --- |
| `CUST-WP-0011` pragmatic railiance01 | T01-T06 done. Cluster State Hub has verified restored WSL2 data and healthy API. | T07: get explicit approval to freeze WSL2 writes, restore final dump, compare again, and redirect private access/MCP to the cluster endpoint. |
| `CUST-WP-0038` full HA State Hub | Entry criteria depend on completing or superseding CUST-WP-0011 and passing stabilization. All implementation tasks are still todo. | Defer until cluster-hosted State Hub proves stable and ThreePhoenix storage/database strategy is current. |
| `RAIL-BS-WP-0007` ThreePhoenix HA cluster | All phases are todo. | Treat as substrate work for future critical workloads and HA State Hub, not as a blocker for pragmatic cutover. |
## Human Gates
- `CUST-WP-0011-T07`: explicit approval required before freezing WSL2 writes and making the cluster State Hub primary.
- `CUST-WP-0038-T08`: explicit approval required before retiring WSL2 fallback after HA failover and restore drills.
## Stable Pickup Path
1. Reconfirm current WSL2 backup and take final pre-cutover dump.
2. Restore final dump into railiance01 State Hub and compare counts again.
3. Redirect the active private access path: either keep local `127.0.0.1:8000` and move it to an ops-bridge/SSH tunnel, or set MCP `API_BASE` to the private cluster endpoint.
4. Run stabilization with WSL2 retained as fallback.
5. Document the operating model and leave final retirement to a later explicit decision or HA workplan.

View File

@@ -1,97 +1,82 @@
# E2E Sandbox Framework — Runbook
> **Migrated (2026-06-23):** `make e2e REPO=` and `python -m e2e_framework` now
> delegate to **wise-validator** (`validate run`) + **sand-boxer** (`sandboxer
> create`). The modules in this directory are **deprecated** and will be removed
> after one release cycle.
>
> **Canonical runbooks:**
> - [wise-validator: validate-compose-e2e](~/wise-validator/docs/runbooks/validate-compose-e2e.md)
> - [sand-boxer: profile-compose-e2e](~/sand-boxer/docs/runbooks/profile-compose-e2e.md)
---
## Prerequisites
**Workstation:**
- `ssh` + `rsync` available
- `python3` + `pyyaml` available (or `uv run`)
- State-hub running on `:8000` (for result reporting)
**Sandbox host (railiance01):**
- `validate` on PATH (`cd ~/wise-validator && make install`)
- `sandboxer` on PATH (`cd ~/sand-boxer && make install`)
- `ssh` available (BatchMode; respects `~/.ssh/config`)
- State Hub on `:8000` (optional, for result reporting)
**Sandbox host (CoulombCore / sandboxer01):**
- SSH key access
- Docker + docker compose plugin installed
- `podman-compose` or `docker compose` (`SANDBOXER_COMPOSE_CMD` on CoulombCore)
- Sufficient disk for images (~4 GB for activity-core stack)
## First run
```bash
# Set sandbox host (once, or add to ~/.bashrc / .env)
export RAILIANCE01_HOST=<ip-or-alias> # e.g. 92.205.130.254
export RAILIANCE01_USER=root # optional, default=root
export RAILIANCE01_KEY=~/.ssh/id_rsa # optional, uses ssh default otherwise
export SANDBOXER_HOST=92.205.130.254 # CoulombCore; or RAILIANCE01_HOST (legacy)
export SANDBOXER_COMPOSE_CMD=podman-compose
# From the-custodian:
make e2e REPO=activity-core
```
Output will show each step: rsync → compose up → health wait → tests → compose down.
Exit code is 0 (all passed) or 1 (any failure).
Output: sandbox create → health wait → tests → destroy. Exit 0 = pass, 1 = fail.
## Options
```bash
# Keep sandbox alive after run (for debugging)
make e2e REPO=activity-core KEEP=1
# Override host without env var
make e2e REPO=activity-core HOST=192.168.1.50
# Attach result to a specific state-hub workstream
make e2e REPO=activity-core HOST=92.205.130.254
make e2e REPO=activity-core WORKSTREAM_ID=<uuid>
make e2e REPO=activity-core NO_REPORT=1
# Skip posting to state-hub
cd the-custodian && python3 -m e2e_framework ~/activity-core --no-report
# Legacy entry (prints deprecation, delegates to validate run):
python3 -m e2e_framework ~/activity-core --host $SANDBOXER_HOST
```
## Adding a new repo
1. Create `<repo>/e2e/e2e.yml`:
```yaml
name: <repo-slug>
compose_file: docker-compose.dev.yml # or e2e/compose.yml
health_checks:
- name: <service>
url: http://localhost:<port>
timeout: 120
test_command: uv run python -m pytest e2e/tests/ -v
timeout: 300
cleanup: always
```
1. Create `<repo>/e2e/e2e.yml` (see wise-validator runbook for schema).
2. Add tests under `<repo>/e2e/tests/` or inline `test_command`.
3. Run: `make e2e REPO=<repo>` or `validate run ~/<repo>`.
2. Add `<repo>/e2e/tests/test_*.py` — test scripts that exit 0 on success.
## Verification
3. Run: `make e2e REPO=<repo>`
```bash
./scripts/verify-e2e-shim.sh
```
## Troubleshooting
**Sandbox not cleaned up:**
```bash
ssh root@$RAILIANCE01_HOST 'ls /tmp/custodian-e2e/'
ssh root@$RAILIANCE01_HOST 'docker compose ls'
# Manually clean:
ssh root@$RAILIANCE01_HOST 'docker compose -p e2e-activity-core-<id> down -v; rm -rf /tmp/custodian-e2e/<id>'
**`validate` / `sandboxer` not found:** Install wise-validator and sand-boxer CLIs.
**CoulombCore compose failures:** Set `SANDBOXER_COMPOSE_CMD=podman-compose`; use
fully qualified image names in compose files.
**Stale sandboxes:** `sandboxer inspect stale` / `sandboxer reap-stale --apply`
## Architecture (current)
```
make e2e REPO= → validate run → sandboxer create (sand-boxer)
→ health + test (wise-validator)
→ sandboxer destroy
```
**Temporal startup slow (>2 min):**
Elasticsearch takes 6090 seconds. The health check waits up to 180s.
If it times out, check:
```bash
ssh root@$RAILIANCE01_HOST 'docker logs temporal-elasticsearch | tail -20'
```
**Worker fails to start:**
Check that `uv` is installed on the sandbox host:
```bash
ssh root@$RAILIANCE01_HOST 'which uv || curl -LsSf https://astral.sh/uv/install.sh | sh'
```
**rsync excluded paths:**
`.git`, `__pycache__`, `*.pyc`, `.venv`, `node_modules` are excluded.
This means `uv sync` runs on the remote after rsync (handled by `uv run`).
## Architecture notes
- Sandbox isolation: docker compose project name `e2e-{repo}-{sandbox_id}`
- Sandbox dir: `/tmp/custodian-e2e/{sandbox_id}/`
- No port conflicts: each sandbox uses its own docker network
- Parallel runs of the same repo are safe (different sandbox_id)
Legacy `e2e-framework/sandbox.py` provision path is **not** used by `make e2e`.

View File

@@ -1,11 +1,8 @@
"""
Entry point: python -m e2e_framework <repo-path> [options]
Usage:
python -m e2e_framework ~/activity-core
python -m e2e_framework ~/activity-core --host 92.205.130.254
python -m e2e_framework ~/activity-core --host railiance01 --keep
make e2e REPO=activity-core (from the-custodian/)
DEPRECATED — delegates to `validate run` (wise-validator + sand-boxer).
Prefer: make e2e REPO=<slug> (from the-custodian/)
"""
from __future__ import annotations
@@ -14,64 +11,59 @@ import os
import sys
from pathlib import Path
from .runner import run_e2e
from .reporter import report
from .shim import run_via_validate
def main() -> None:
parser = argparse.ArgumentParser(description="Run e2e tests in a remote sandbox")
parser = argparse.ArgumentParser(
description="[DEPRECATED] Run e2e tests — delegates to validate run"
)
parser.add_argument("repo_path", help="Path to the repo containing e2e/e2e.yml")
parser.add_argument(
"--host",
default=os.environ.get("RAILIANCE01_HOST", ""),
help="Sandbox host (SSH alias or IP). Env: RAILIANCE01_HOST",
help="Sandbox host. Env: RAILIANCE01_HOST or SANDBOXER_HOST",
)
parser.add_argument(
"--user",
default=os.environ.get("RAILIANCE01_USER", "root"),
help="SSH user (default: root). Env: RAILIANCE01_USER",
help="SSH user. Env: RAILIANCE01_USER → SANDBOXER_SSH_USER",
)
parser.add_argument(
"--key",
default=os.environ.get("RAILIANCE01_KEY"),
help="Path to SSH private key. Env: RAILIANCE01_KEY",
help="SSH private key. Env: RAILIANCE01_KEY → SANDBOXER_SSH_KEY",
)
parser.add_argument(
"--keep",
action="store_true",
help="Keep sandbox after run (skip compose down + dir removal)",
help="Keep sandbox after run",
)
parser.add_argument(
"--workstream-id",
default=None,
help="State-hub workstream ID to attach the progress event to",
help="State Hub workstream ID for progress event",
)
parser.add_argument(
"--no-report",
action="store_true",
help="Skip posting results to state-hub",
help="Skip posting results to State Hub",
)
args = parser.parse_args()
if not args.host:
print("ERROR: sandbox host required. Set RAILIANCE01_HOST or pass --host.")
sys.exit(1)
repo_path = Path(args.repo_path).expanduser().resolve()
if not repo_path.exists():
print(f"ERROR: repo path does not exist: {repo_path}")
print(f"ERROR: repo path does not exist: {repo_path}", file=sys.stderr)
sys.exit(1)
result = run_e2e(
repo_path=repo_path,
host=args.host,
ssh_user=args.user,
ssh_key=args.key,
exit_code = run_via_validate(
repo_path,
host=args.host or None,
keep=args.keep,
workstream_id=args.workstream_id,
no_report=args.no_report,
ssh_user=args.user if args.user != "root" else os.environ.get("RAILIANCE01_USER"),
ssh_key=args.key,
)
if not args.no_report:
report(result, workstream_id=args.workstream_id)
sys.exit(0 if result.passed else 1)
sys.exit(exit_code)

View File

@@ -1,4 +1,10 @@
"""
DEPRECATED — provision/teardown is owned by sand-boxer (`sandboxer create`).
This module remains for one release cycle only. Do not call `Sandbox.provision()`
from new code; use sand-boxer `ext.compose-ssh` via `validate run` or
`sandboxer create --profile profile.compose-e2e`.
SSH-based sandbox: provision an isolated directory on the remote host,
rsync the repo into it, and run arbitrary commands there.
"""

80
e2e-framework/shim.py Normal file
View File

@@ -0,0 +1,80 @@
"""Delegate e2e runs to wise-validator (sand-boxer + validate run)."""
from __future__ import annotations
import os
import shutil
import subprocess
import sys
from pathlib import Path
DEPRECATION_MSG = (
"[e2e_framework] DEPRECATED: use `validate run <repo>` (wise-validator) or "
"`make e2e REPO=` from the-custodian. Provision is sand-boxer; validation is "
"wise-validator. This module will be removed after one release cycle."
)
def _resolve_host(host: str | None) -> str:
for candidate in (host, os.environ.get("SANDBOXER_HOST"), os.environ.get("RAILIANCE01_HOST")):
if candidate:
return candidate
return ""
def run_via_validate(
repo_path: Path,
*,
host: str | None = None,
keep: bool = False,
workstream_id: str | None = None,
no_report: bool = False,
ssh_user: str | None = None,
ssh_key: str | None = None,
) -> int:
"""Invoke `validate run` and return its exit code."""
print(DEPRECATION_MSG, file=sys.stderr)
validate_bin = os.environ.get("VALIDATE_BIN", "validate")
if not shutil.which(validate_bin):
print(
f"ERROR: {validate_bin} not found on PATH. "
"Install wise-validator: cd ~/wise-validator && make install",
file=sys.stderr,
)
return 1
sandboxer_bin = os.environ.get("SANDBOXER_BIN", "sandboxer")
if not shutil.which(sandboxer_bin):
print(
f"ERROR: {sandboxer_bin} not found on PATH. "
"Install sand-boxer: cd ~/sand-boxer && make install",
file=sys.stderr,
)
return 1
resolved_host = _resolve_host(host)
if not resolved_host:
print(
"ERROR: sandbox host required. Set SANDBOXER_HOST, RAILIANCE01_HOST, or --host.",
file=sys.stderr,
)
return 1
env = os.environ.copy()
env["SANDBOXER_HOST"] = resolved_host
if ssh_user:
env["SANDBOXER_SSH_USER"] = ssh_user
if ssh_key:
env["SANDBOXER_SSH_KEY"] = ssh_key
cmd = [validate_bin, "run", str(repo_path), "--host", resolved_host]
if keep:
cmd.append("--keep")
if workstream_id:
cmd.extend(["--workstream-id", workstream_id])
if no_report:
cmd.append("--no-report")
result = subprocess.run(cmd, env=env)
return result.returncode

130
history/20260621-SCOPE.md Normal file
View File

@@ -0,0 +1,130 @@
# SCOPE
> This file helps you quickly understand what this repository is about,
> when it is relevant, and when it is not.
> It is intentionally lightweight and may be incomplete.
---
## One-liner
Central cognitive infrastructure and coordination hub for seven project domains — provides governance canon and coordinates through the standalone State Hub API/MCP service.
---
## Core Idea
The Custodian repository is the **governance substrate**: canon, constitution, values, domain charters, workplans, and runtime scaffolding. The operational State Hub service (PostgreSQL + FastAPI + MCP server + Observable dashboard) now lives in the standalone `/home/worsch/state-hub` repository and acts as episodic memory and coordination layer for work across repos.
---
## In Scope
- Canon layer: governance constitution, foundational values, six domain charters/roadmaps
- Coordination through the standalone State Hub API: topics, workstreams, tasks, decisions, progress events, contributions, SBOM, goals
- MCP session protocol: use the State Hub MCP tools from registered agent sessions
- Memory: append-only episodic archive (working notes + immutable event logs)
- Agent runtime scaffolding: policies, kaizen agent copies, tool adapters
- Cross-domain coordination: dependency tracking, human-intervention flags, next-steps suggestions
- Publishing lifecycle events on NATS JetStream (`org.statehub.>`) so activity-core can react via declarative ActivityDefinitions
---
## Out of Scope
- Domain-specific implementation work (Railiance, Markitect, etc. each own their repos)
- Financial/legal transactions or external publication
- Storing plaintext credentials
- Direct writes to `canon/` without a human-approved review gate
- State Hub implementation work; use `/home/worsch/state-hub`
- Maintenance task *creation* in response to lifecycle events — that responsibility lives in activity-core (see `/home/worsch/state-hub/docs/activity-core-delegation.md`). The state hub remains a **read model**, not a task factory.
---
## Relevant When
- Starting or closing any session in a registered domain repo (orientation via `get_domain_summary()`)
- Tracking cross-domain decisions, blockers, or workplan progress
- Registering a new project into the ecosystem (`make register-project`)
- Consulting governance rules or domain charters
- Running the standalone State Hub API locally for MCP connectivity
---
## Not Relevant When
- Implementing single-domain features (stay in the domain repo)
- Working fully offline with no need for state coordination
- Non-custodian ecosystem work (standalone projects, throw-away scripts)
---
## Current State
- Status: active
- Implementation: ~60% — canon + standalone State Hub operational; RAG/drafting pipelines (Phase 2) not yet started
- Stability: stable (versioned Alembic migrations; no breaking API changes since v0.3)
- Usage: running daily; 15+ active workstreams across 6 domains; MCP server active in Claude Code
---
## How It Fits
- Upstream dependencies: none (sits at the top of the dependency order)
- Downstream consumers: all six domains (railiance → markitect → coulomb.social → personhood/foerster → custodian); **activity-core** consumes state hub lifecycle events on NATS subject `org.statehub.>` to drive maintenance ActivityDefinitions
- Often used with: kaizen-agentic (agent definitions), ops-bridge (remote tunnel connectivity), activity-core (task factory + event bridge)
---
## Terminology
- Preferred terms: canon, workstream, topic, progress event, domain
- Also known as: "the hub", "state hub"
- Potentially confusing terms: "topic" = domain-level grouping (not a chat topic); "decision" = tracked choice point with escalation rules
---
## Related / Overlapping
- `kaizen-agentic` — specialized agent personas callable via MCP from any domain session
- `ops-bridge` — SSH tunnel manager keeping remote agents connected to this hub
- `activity-core` — event-driven task factory tracked as a custodian-domain workstream
---
## Getting Oriented
- Start with: `CLAUDE.md` (session protocol) + `README.md` (architecture overview)
- Key files / directories: `canon/` (governance), `workplans/` (active Custodian work), `state-hub/` (pointer), `/home/worsch/state-hub/mcp_server/TOOLS.md` (tool reference)
- Entry points: `cd /home/worsch/state-hub && make api` (API); Codex/Claude Code with state-hub MCP registered
---
## Provided Capabilities
```capability
type: api
title: MCP tool registration
description: Register and expose new MCP tools to all Claude Code sessions via the state-hub server.
keywords: [mcp, tool, api, registration, server]
```
```capability
type: data
title: Cross-domain state tracking
description: Track workstreams, tasks, decisions, and progress events across all seven project domains.
keywords: [state, tracking, workstream, task, decision, progress]
```
```capability
type: api
title: SBOM and licence reporting
description: Ingest lockfiles from any repo and provide aggregated SBOM and copyleft licence risk reports.
keywords: [sbom, licence, license, dependency, lockfile, copyleft]
```
---
## Notes
Dependency order for domain sequencing: Railiance → Markitect → Coulomb.social → Personhood/Foerster → Custodian. The consistency checker (`cd /home/worsch/state-hub && make fix-consistency REPO=the-custodian`) must be run after any workplan changes to keep the dashboard accurate.

View File

@@ -0,0 +1,91 @@
# infra/build-machines/Makefile
# Usage: make remote-build PROJECT=~/projects/my-haskell-app [VM=haskell-build]
VM ?= haskell-build
PROJECT ?= .
RDIR := /build/$(notdir $(realpath $(PROJECT)))
# Sync project source to VM (exclude build artefacts)
.PHONY: sync
sync:
rsync -av --delete \
--exclude='.git' \
--exclude='dist-newstyle' \
--exclude='.stack-work' \
--exclude='*.o' --exclude='*.hi' \
$(PROJECT)/ $(VM):$(RDIR)/
# Run cabal build on VM — prefers sand-boxer workspace (SAND-WP-0012 shim)
.PHONY: remote-build
remote-build:
@if command -v sandboxer >/dev/null 2>&1; then \
$(MAKE) remote-build-sandboxer; \
else \
echo "WARN: sandboxer not on PATH — using legacy rsync-only path" >&2; \
$(MAKE) remote-build-legacy; \
fi
# Legacy rsync + ssh (deprecated — install sand-boxer for isolated workspaces)
.PHONY: remote-build-legacy
remote-build-legacy: sync
ssh $(VM) "cd $(RDIR) && source ~/.ghcup/env && cabal build all 2>&1"
.PHONY: remote-build-sandboxer
remote-build-sandboxer:
@set -euo pipefail; \
STATUS=$$(sandboxer create \
--profile profile.vm-haskell-build \
--input vm=$(VM) \
--input repo=$(PROJECT) \
--actor agt \
--project the-custodian \
--host localhost); \
ID=$$(echo "$$STATUS" | python3 -c "import sys,json; print(json.load(sys.stdin)['sandbox_id'])"); \
RDIR=$$(echo "$$STATUS" | python3 -c "import sys,json; r=json.load(sys.stdin).get('reachability') or {}; print(r.get('remote_dir',''))"); \
test -n "$$RDIR"; \
ssh $(VM) "cd $$RDIR && source ~/.ghcup/env && cabal build all 2>&1"; \
sandboxer destroy "$$ID"
# Run tests on VM
.PHONY: remote-test
remote-test: sync
ssh $(VM) "cd $(RDIR) && source ~/.ghcup/env && cabal test all 2>&1"
# Open a GHCi session on the VM
.PHONY: remote-ghci
remote-ghci: sync
ssh -t $(VM) "cd $(RDIR) && source ~/.ghcup/env && cabal repl"
# Sync build artefacts back (for local IDE inspection)
.PHONY: fetch-artifacts
fetch-artifacts:
rsync -av $(VM):$(RDIR)/dist-newstyle/ $(PROJECT)/dist-newstyle/
# Check which VMs are reachable
.PHONY: bridge-status
bridge-status:
@echo "Scanning build-machine tunnel ports..."
@for port in 12221 12222 12223 12224 12225; do \
result=$$(ssh -q -p $$port -o ConnectTimeout=2 \
-o StrictHostKeyChecking=no build@localhost \
"echo $$port OK: $$(hostname) — GHC: $$(~/.ghcup/bin/ghc --numeric-version)" \
2>/dev/null) ; \
if [ -n "$$result" ]; then echo " $$result"; \
else echo " port $$port: no tunnel"; fi; \
done
# Show VM system info
.PHONY: vm-info
vm-info:
ssh $(VM) "uname -a; source ~/.ghcup/env && ghc --version && cabal --version"
# Install SSH config for the build VM (idempotent)
.PHONY: install-ssh-config
install-ssh-config:
@if grep -q '# Haskell Build VM — tunnel via workstation' ~/.ssh/config 2>/dev/null; then \
echo "SSH config already present — skipping"; \
else \
echo "" >> ~/.ssh/config; \
cat ssh-config.template >> ~/.ssh/config; \
echo "Appended build-machine SSH config to ~/.ssh/config"; \
fi

View File

@@ -0,0 +1,145 @@
# Build Machines
Reproducible VirtualBox images for offloading compilation to dedicated hardware.
Each VM self-registers with the Custodian State Hub on boot and connects back to
the development workstation via SSH reverse tunnel.
## Prerequisites
- **Packer** >= 1.10 (`packer version`)
- **VirtualBox** >= 7.0 (`VBoxManage --version`)
- **autossh** on both workstation and VM (installed automatically in VM image)
- **State Hub** running on workstation (`cd ~/the-custodian/state-hub && make api`)
## Quick Start
### 1. Generate SSH keypair (one-time)
```bash
ssh-keygen -t ed25519 -f ~/.ssh/id_build -N "" -C "build-agent"
```
### 2. Build the OVA
```bash
cd infra/build-machines/haskell
packer init .
packer build .
```
This produces `haskell-build-YYYYMMDD.ova` (~4-6 GB, depending on GHC versions).
### 3. Import and configure
```bash
# Import the OVA
VBoxManage import haskell-build-20260420.ova
# Switch from NAT (build-time) to bridged networking
scripts/setup-vm.sh haskell-build
# Start the VM
VBoxManage startvm haskell-build --type headless
```
### 4. Inject credentials
```bash
# Prepare a directory with keys and config
mkdir -p ~/vm-keys/haskell-build
cp ~/.ssh/id_build ~/vm-keys/haskell-build/
cp ~/.ssh/id_build.pub ~/vm-keys/haskell-build/
# Edit build-agent.env from template
cp haskell/files/build-agent.env.template ~/vm-keys/haskell-build/build-agent.env
# Edit SSH_RELAY_HOST to your workstation's LAN IP
# Inject (VM must be running; uses temporary password auth)
scripts/inject-keys.sh <vm-ip> ~/vm-keys/haskell-build/
```
### 5. Install SSH config
```bash
make install-ssh-config
```
### 6. Verify
```bash
make bridge-status # check tunnel is up
ssh haskell-build # should connect via tunnel
./smoke-test.sh # full stack validation
```
## Using the VM
```bash
# Build a Haskell project remotely (prefers sand-boxer workspace when installed)
make remote-build PROJECT=~/projects/my-app
# Run tests
make remote-test PROJECT=~/projects/my-app
# Interactive GHCi
make remote-ghci PROJECT=~/projects/my-app
# Fetch build artefacts back to workstation
make fetch-artifacts PROJECT=~/projects/my-app
# Check VM info
make vm-info
```
## Architecture
```
Workstation (WSL2)
├── state-hub (:8000) — sees capability entries, knows tunnel ports
└── SSH listener — accepts reverse tunnel from VM
Laptop (VirtualBox host)
└── haskell-build VM (Ubuntu 24.04, bridged)
├── GHC 9.8.4 + 9.6.6 via GHCup
├── build-agent (systemd) — registers with state-hub on boot
└── autossh: -R 12222→local:22, -L 18000→state-hub:8000
```
The VM connects OUT to the workstation. Two tunnels in one SSH connection:
- **Reverse** (`-R 12222:localhost:22`): workstation can SSH into VM
- **Forward** (`-L 18000:localhost:8000`): VM can reach state-hub
## Port Registry
See `port-registry.yml`. Range 12221-12230 supports up to 10 concurrent VMs.
Each VM must use a unique port.
## Adding a GHC Version Post-Deployment
```bash
ssh haskell-build "source ~/.ghcup/env && ghcup install ghc 9.10.1"
```
No image rebuild required.
## Troubleshooting
**Tunnel not up:**
- Check `journalctl -u build-agent` on the VM
- Verify `SSH_RELAY_HOST` in `/etc/build-agent.env` is reachable from the VM
- Ensure the workstation's SSH server accepts the build key
**Capability not in state-hub:**
- Check `curl http://127.0.0.1:8000/capability-catalog/?capability_type=haskell-build-agent`
- The agent retries 20 times on boot; check logs for registration errors
- The forward tunnel (`-L 18000:localhost:8000`) must be up before registration works
**Build fails with missing libraries:**
- The VM includes common Haskell build deps. For additional system libraries:
`ssh haskell-build "sudo apt-get install -y libXXX-dev"`
## Updating the Image
Re-run Packer to build a new OVA. Import alongside the existing VM or replace it.
Build artefacts and keys live on the workstation (via rsync), not in the VM — the
image is disposable.

View File

@@ -0,0 +1,21 @@
# Custodian State Hub URL — always access via forward tunnel (port 18000).
# The agent opens -L 18000:localhost:8000 alongside the reverse SSH tunnel,
# so this works regardless of network topology (LAN, VPN, different subnet).
# Matches the CoulombCore remote worker bridge pattern.
STATE_HUB_URL=http://127.0.0.1:18000
# Domain to register capability under
STATE_HUB_DOMAIN=railiance
# Workstation hostname or LAN IP for SSH relay connection
# The VM connects OUT to this host to establish both tunnels.
SSH_RELAY_HOST=192.168.1.100 # replace with actual workstation LAN IP
SSH_RELAY_USER=worsch
# Path to private key for SSH tunnel (matching authorized_keys on workstation)
SSH_KEY_PATH=/home/build/.ssh/id_build
# Port to bind on workstation (ssh -R <REMOTE_PORT>:localhost:22)
# Each VM instance must use a distinct port — see port-registry.yml
# Range: 12221-12230
REMOTE_PORT=12222

View File

@@ -0,0 +1,148 @@
#!/usr/bin/env python3
"""
build-agent — runs at VM boot.
1. Reads /etc/build-agent.env
2. Detects GHC version
3. Registers (or updates) a capability-catalog entry in the state-hub
4. Opens an autossh reverse tunnel to the workstation
"""
import os, json, socket, subprocess, time, sys
import urllib.request, urllib.error
def load_env(path="/etc/build-agent.env"):
env = {}
try:
with open(path) as f:
for line in f:
line = line.strip()
if line and not line.startswith('#') and '=' in line:
k, _, v = line.partition('=')
env[k.strip()] = v.strip().strip('"')
except FileNotFoundError:
pass
return env
def get_ghc_version():
for path in [
"/home/build/.ghcup/bin/ghc",
"/usr/local/bin/ghc",
]:
try:
r = subprocess.run([path, "--version"],
capture_output=True, text=True, timeout=15)
if r.returncode == 0:
return r.stdout.strip().split()[-1]
except Exception:
continue
return "unknown"
def get_local_ip():
"""Get the primary LAN IP (not loopback)."""
try:
s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
s.connect(("8.8.8.8", 80))
ip = s.getsockname()[0]
s.close()
return ip
except Exception:
return "unknown"
def register(cfg):
# State-hub is always accessed via the forward tunnel (port 18000), never
# via direct LAN. This matches the CoulombCore remote worker pattern and
# works regardless of network topology (LAN, VPN, different subnet).
state_hub = cfg.get("STATE_HUB_URL", "http://127.0.0.1:18000")
hostname = socket.gethostname()
domain = cfg.get("STATE_HUB_DOMAIN", "railiance")
remote_port = cfg.get("REMOTE_PORT", "12222")
ghc_ver = get_ghc_version()
local_ip = get_local_ip()
payload = {
"domain": domain,
"capability_type": "haskell-build-agent",
"title": f"Haskell Build Agent — {hostname}",
"description": (
f"GHC {ghc_ver} build sandbox on {hostname} ({local_ip}). "
f"SSH tunnel port: {remote_port} on workstation."
),
"keywords": [
"haskell", "ghc", f"ghc-{ghc_ver}",
"build-agent", "cabal", "stack",
f"host:{hostname}", f"tunnel-port:{remote_port}",
],
}
data = json.dumps(payload).encode()
req = urllib.request.Request(
f"{state_hub}/capability-catalog/",
data=data,
headers={"Content-Type": "application/json"},
method="POST",
)
try:
with urllib.request.urlopen(req, timeout=15) as resp:
result = json.loads(resp.read())
print(f"[build-agent] Registered capability: {result['id']}", flush=True)
return result
except urllib.error.HTTPError as e:
body = e.read().decode()
print(f"[build-agent] Registration HTTP error {e.code}: {body}", flush=True)
raise
except Exception as e:
print(f"[build-agent] Registration failed: {e}", flush=True)
raise
def open_tunnel(cfg):
relay_host = cfg.get("SSH_RELAY_HOST", "")
relay_user = cfg.get("SSH_RELAY_USER", "worsch")
ssh_key = cfg.get("SSH_KEY_PATH", "/home/build/.ssh/id_build")
remote_port = cfg.get("REMOTE_PORT", "12222")
if not relay_host:
print("[build-agent] SSH_RELAY_HOST not set — tunnel disabled", flush=True)
# Sleep forever so systemd considers service active
while True:
time.sleep(3600)
cmd = [
"autossh",
"-M", "0", # disable autossh monitoring port
"-o", "ServerAliveInterval=30",
"-o", "ServerAliveCountMax=3",
"-o", "ExitOnForwardFailure=yes",
"-o", "StrictHostKeyChecking=no",
"-o", "UserKnownHostsFile=/dev/null",
"-N",
"-R", f"{remote_port}:localhost:22", # reverse: workstation → VM SSH
"-L", "18000:localhost:8000", # forward: VM → state-hub (port 18000)
"-i", ssh_key,
f"{relay_user}@{relay_host}",
]
print(
f"[build-agent] Opening tunnels: "
f"-R {remote_port}→local:22, -L 18000→state-hub:8000",
flush=True,
)
subprocess.run(cmd) # autossh manages reconnects internally
def main():
cfg = load_env()
# Retry registration until state-hub is reachable (network may not be ready)
for attempt in range(20):
try:
register(cfg)
break
except Exception:
wait = min(10 * (attempt + 1), 60)
print(f"[build-agent] Retrying in {wait}s ...", flush=True)
time.sleep(wait)
else:
print("[build-agent] Registration permanently failed — continuing to tunnel",
flush=True)
open_tunnel(cfg)
if __name__ == "__main__":
main()

View File

@@ -0,0 +1,19 @@
[Unit]
Description=Haskell Build Agent — State Hub registration + SSH reverse tunnel
Documentation=https://github.com/tegwick/the-custodian
After=network-online.target
Wants=network-online.target
[Service]
Type=simple
User=build
EnvironmentFile=/etc/build-agent.env
ExecStart=/usr/local/bin/build-agent
Restart=on-failure
RestartSec=30
StandardOutput=journal
StandardError=journal
SyslogIdentifier=build-agent
[Install]
WantedBy=multi-user.target

View File

@@ -0,0 +1 @@
{}

View File

@@ -0,0 +1,56 @@
#cloud-config
autoinstall:
version: 1
locale: en_US.UTF-8
keyboard:
layout: us
timezone: Europe/Berlin
storage:
layout:
name: lvm
sizing-policy: all
identity:
hostname: haskell-build
username: build
# Password "build" — only used during Packer provisioning.
# SSH password auth is disabled post-install; key-only access.
password: "$6$rounds=4096$saltsalt$YQvhEBfODCjg4i7ORlYsIJfIpM3bFSGx3QWxJ8DqZvHCIKcMmOYa0N3KQj6SHvHYjjKZaX9FPqc9dLiNLsVA."
ssh:
install-server: true
allow-pw: true # needed for Packer SSH communicator during build
packages:
- build-essential
- curl
- git
- libgmp-dev
- libffi-dev
- zlib1g-dev
- libncurses-dev
- libtinfo-dev
- pkg-config
- openssh-server
- autossh
- jq
- rsync
- python3
user-data:
users:
- name: build
groups: sudo
shell: /bin/bash
sudo: ALL=(ALL) NOPASSWD:ALL
lock_passwd: false
late-commands:
# Disable password authentication for SSH (key-only after provisioning)
- sed -i 's/^#*PasswordAuthentication.*/PasswordAuthentication no/' /target/etc/ssh/sshd_config
- sed -i 's/^#*PubkeyAuthentication.*/PubkeyAuthentication yes/' /target/etc/ssh/sshd_config
# Create /build directory for remote builds
- mkdir -p /target/build
- chown 1000:1000 /target/build

View File

@@ -0,0 +1,147 @@
packer {
required_plugins {
virtualbox = {
version = ">= 1.1.0"
source = "github.com/hashicorp/virtualbox"
}
}
}
variable "vm_name" {
type = string
default = "haskell-build"
}
variable "disk_size" {
type = number
default = 40960
}
variable "memory" {
type = number
default = 8192
}
variable "cpus" {
type = number
default = 4
}
variable "ghc_primary_version" {
type = string
default = "9.8.4"
}
variable "ghc_secondary_version" {
type = string
default = "9.6.6"
}
variable "cabal_version" {
type = string
default = "3.12.1.0"
}
variable "iso_url" {
type = string
default = "https://releases.ubuntu.com/24.04/ubuntu-24.04.2-live-server-amd64.iso"
}
variable "iso_checksum" {
type = string
default = "sha256:d6dab0c3a657988501b4bd76f1297c053df710e06e0c3aece60dead24f270b4d"
}
locals {
timestamp = formatdate("YYYYMMDD", timestamp())
}
source "virtualbox-iso" "haskell-build" {
vm_name = var.vm_name
guest_os_type = "Ubuntu_64"
disk_size = var.disk_size
hard_drive_interface = "sata"
memory = var.memory
cpus = var.cpus
iso_url = var.iso_url
iso_checksum = var.iso_checksum
# NAT during build — Packer needs internet for ISO + packages.
# Bridged networking is set post-import by setup-vm.sh (adapter names
# are laptop-specific and cannot be baked into the image).
vboxmanage = [
["modifyvm", "{{.Name}}", "--nat-localhostreachable1", "on"],
]
http_directory = "files/cloud-init"
boot_wait = "5s"
boot_command = [
"c<wait>",
"linux /casper/vmlinuz --- autoinstall ds='nocloud;s=http://{{.HTTPIP}}:{{.HTTPPort}}/'<enter><wait>",
"initrd /casper/initrd<enter><wait>",
"boot<enter>",
]
ssh_username = "build"
ssh_password = "build"
ssh_timeout = "30m"
ssh_handshake_attempts = 100
shutdown_command = "echo 'build' | sudo -S shutdown -P now"
# File provisioners — stage agent files before install script runs
# (Packer uploads to /tmp by default for file provisioners)
output_directory = "output-${var.vm_name}"
output_filename = "${var.vm_name}"
}
build {
sources = ["source.virtualbox-iso.haskell-build"]
# Stage agent files to /tmp (install-agent.sh moves them into place)
provisioner "file" {
source = "files/build-agent.py"
destination = "/tmp/build-agent.py"
}
provisioner "file" {
source = "files/build-agent.service"
destination = "/tmp/build-agent.service"
}
provisioner "file" {
source = "files/build-agent.env.template"
destination = "/tmp/build-agent.env.template"
}
# Install Haskell toolchain (GHCup + GHC + Cabal)
provisioner "shell" {
execute_command = "echo 'build' | sudo -S env {{ .Vars }} bash '{{ .Path }}'"
script = "scripts/install-haskell.sh"
environment_vars = [
"GHC_PRIMARY_VERSION=${var.ghc_primary_version}",
"GHC_SECONDARY_VERSION=${var.ghc_secondary_version}",
"CABAL_VERSION=${var.cabal_version}",
]
}
# Install build-agent + systemd unit
provisioner "shell" {
execute_command = "echo 'build' | sudo -S env {{ .Vars }} bash '{{ .Path }}'"
script = "scripts/install-agent.sh"
}
# Export as OVA
post-processor "vagrant" {
only = [] # disabled — we use the raw OVA below
}
post-processor "shell-local" {
inline = [
"cd output-${var.vm_name} && mv ${var.vm_name}.ova ../haskell-build-${local.timestamp}.ova || true",
]
}
}

View File

@@ -0,0 +1,157 @@
#!/bin/sh
# bootstrap-alpine.sh — One-shot setup for Haskell build machine on Alpine Linux
#
# Usage (from workstation):
# scp bootstrap-alpine.sh root@<vm-ip>:/tmp/
# ssh root@<vm-ip> sh /tmp/bootstrap-alpine.sh
#
# What it does:
# 1. Installs system dependencies (apk)
# 2. Creates 'build' user with sudo
# 3. Installs GHCup + GHC + Cabal (single version — 8GB disk constraint)
# 4. Installs build-agent + OpenRC service
# 5. Configures SSH for key-based access
#
# Disk budget (8GB total):
# Alpine base: ~200 MB
# Build deps: ~300 MB
# GHCup + GHC: ~1800 MB
# Cabal + pkgdb: ~300 MB
# Headroom: ~5400 MB (for project builds)
set -eu
GHC_VERSION="${GHC_VERSION:-9.8.4}"
CABAL_VERSION="${CABAL_VERSION:-3.12.1.0}"
echo "=== Haskell Build Machine Bootstrap (Alpine) ==="
echo "GHC: ${GHC_VERSION} | Cabal: ${CABAL_VERSION}"
echo ""
# ---- 1. System packages ----
echo "[1/5] Installing system packages..."
apk update
apk add \
build-base curl git \
gmp-dev libffi-dev zlib-dev ncurses-dev \
pkgconf openssh autossh jq rsync \
sudo shadow python3 \
musl-dev gcc g++ make \
linux-headers \
xz tar
# ---- 2. Build user ----
echo "[2/5] Creating build user..."
if ! id build >/dev/null 2>&1; then
adduser -D -s /bin/sh -h /home/build build
echo "build ALL=(ALL) NOPASSWD: ALL" > /etc/sudoers.d/build
chmod 440 /etc/sudoers.d/build
fi
# Create build workspace
mkdir -p /build
chown build:build /build
# SSH directory
mkdir -p /home/build/.ssh
chmod 700 /home/build/.ssh
chown build:build /home/build/.ssh
# ---- 3. Haskell toolchain ----
echo "[3/5] Installing Haskell toolchain (this takes a while)..."
# GHCup needs these env vars for non-interactive install
export BOOTSTRAP_HASKELL_NONINTERACTIVE=1
export BOOTSTRAP_HASKELL_GHC_VERSION="$GHC_VERSION"
export BOOTSTRAP_HASKELL_CABAL_VERSION="$CABAL_VERSION"
export BOOTSTRAP_HASKELL_INSTALL_STACK=0
export BOOTSTRAP_HASKELL_INSTALL_HLS=0
# Install GHCup as build user
su - build -c "
export BOOTSTRAP_HASKELL_NONINTERACTIVE=1
export BOOTSTRAP_HASKELL_GHC_VERSION='$GHC_VERSION'
export BOOTSTRAP_HASKELL_CABAL_VERSION='$CABAL_VERSION'
export BOOTSTRAP_HASKELL_INSTALL_STACK=0
export BOOTSTRAP_HASKELL_INSTALL_HLS=0
curl --proto '=https' --tlsv1.2 -sSf https://get-ghcup.haskell.org | sh
"
# Add ghcup to build user's profile
cat >> /home/build/.profile << 'PROFILE'
[ -f "$HOME/.ghcup/env" ] && . "$HOME/.ghcup/env"
PROFILE
# Verify installation
su - build -c '. ~/.ghcup/env && ghc --version && cabal --version'
# Pre-warm cabal package index
echo "[3/5] Warming cabal package index..."
su - build -c '. ~/.ghcup/env && cabal update'
# ---- 4. Build agent ----
echo "[4/5] Installing build-agent..."
# The agent script will be copied separately via SCP
# Here we just set up the OpenRC service skeleton
cat > /etc/init.d/build-agent << 'INITD'
#!/sbin/openrc-run
name="build-agent"
description="Haskell Build Agent — State Hub registration + SSH reverse tunnel"
command="/usr/local/bin/build-agent"
command_user="build"
command_background=true
pidfile="/run/${RC_SVCNAME}.pid"
output_log="/var/log/build-agent.log"
error_log="/var/log/build-agent.log"
depend() {
need net
after firewall
}
INITD
chmod 755 /etc/init.d/build-agent
# Create placeholder env file
if [ ! -f /etc/build-agent.env ]; then
cat > /etc/build-agent.env << 'ENV'
# Custodian State Hub — access via forward tunnel
STATE_HUB_URL=http://127.0.0.1:18000
STATE_HUB_DOMAIN=railiance
SSH_RELAY_HOST=
SSH_RELAY_USER=worsch
SSH_KEY_PATH=/home/build/.ssh/id_build
REMOTE_PORT=12222
ENV
chmod 600 /etc/build-agent.env
fi
# Enable on boot
rc-update add build-agent default
# ---- 5. SSH hardening ----
echo "[5/5] Configuring SSH..."
# Enable and start sshd
rc-update add sshd default
rc-service sshd start 2>/dev/null || true
# Harden (will take effect after key injection)
sed -i 's/^#*PermitRootLogin.*/PermitRootLogin no/' /etc/ssh/sshd_config
sed -i 's/^#*PubkeyAuthentication.*/PubkeyAuthentication yes/' /etc/ssh/sshd_config
echo ""
echo "=== Bootstrap complete ==="
echo ""
echo "Disk usage:"
df -h / | tail -1
echo ""
echo "GHC location: /home/build/.ghcup/"
su - build -c '. ~/.ghcup/env && ghc --version'
echo ""
echo "Next steps:"
echo " 1. Copy build-agent.py: scp build-agent.py root@<vm>:/usr/local/bin/build-agent"
echo " 2. Copy SSH keys: scp id_build root@<vm>:/home/build/.ssh/"
echo " 3. Edit env: ssh root@<vm> vi /etc/build-agent.env"
echo " 4. Start agent: ssh root@<vm> rc-service build-agent start"
echo " 5. Disable root login: ssh root@<vm> 'sed -i s/PermitRootLogin.*/PermitRootLogin no/ /etc/ssh/sshd_config && rc-service sshd restart'"

View File

@@ -0,0 +1,65 @@
#!/bin/bash
# inject-keys.sh — Post-boot SSH key and env injection for new VMs (Option B)
#
# Usage: inject-keys.sh <vm-ip> [key-dir]
#
# Expects the following files in key-dir (default: current directory):
# - id_build (private key for SSH tunnel)
# - id_build.pub (public key)
# - build-agent.env (filled-in env config — see build-agent.env.template)
#
# The VM must be running with temporary password auth enabled (as built by Packer).
# After injection, password auth is disabled and key-only access takes effect.
set -euo pipefail
VM_IP="${1:?Usage: inject-keys.sh <vm-ip> [key-dir]}"
KEY_DIR="${2:-.}"
BUILD_USER="build"
echo "==> Injecting keys to ${BUILD_USER}@${VM_IP} from ${KEY_DIR}"
# Verify required files exist
for f in id_build id_build.pub build-agent.env; do
if [ ! -f "${KEY_DIR}/${f}" ]; then
echo "ERROR: Missing ${KEY_DIR}/${f}"
exit 1
fi
done
# Create .ssh directory on VM
ssh -o StrictHostKeyChecking=no "${BUILD_USER}@${VM_IP}" \
"mkdir -p ~/.ssh && chmod 700 ~/.ssh"
# Copy SSH keys
scp -o StrictHostKeyChecking=no \
"${KEY_DIR}/id_build" "${KEY_DIR}/id_build.pub" \
"${BUILD_USER}@${VM_IP}:~/.ssh/"
# Set correct permissions on private key
ssh -o StrictHostKeyChecking=no "${BUILD_USER}@${VM_IP}" \
"chmod 600 ~/.ssh/id_build && chmod 644 ~/.ssh/id_build.pub"
# Add the tunnel target's host key to known_hosts (optional — agent uses
# StrictHostKeyChecking=no, but this avoids warnings in manual SSH)
echo "==> Adding workstation public key to authorized_keys"
ssh -o StrictHostKeyChecking=no "${BUILD_USER}@${VM_IP}" \
"cat ~/.ssh/id_build.pub >> ~/.ssh/authorized_keys && chmod 600 ~/.ssh/authorized_keys"
# Copy build-agent.env to /etc (requires sudo)
echo "==> Installing build-agent.env"
scp -o StrictHostKeyChecking=no \
"${KEY_DIR}/build-agent.env" "${BUILD_USER}@${VM_IP}:/tmp/build-agent.env"
ssh -o StrictHostKeyChecking=no "${BUILD_USER}@${VM_IP}" \
"sudo cp /tmp/build-agent.env /etc/build-agent.env && sudo chmod 600 /etc/build-agent.env && rm /tmp/build-agent.env"
# Disable password auth (now that keys are in place)
echo "==> Disabling password authentication"
ssh -o StrictHostKeyChecking=no "${BUILD_USER}@${VM_IP}" \
"sudo sed -i 's/^#*PasswordAuthentication.*/PasswordAuthentication no/' /etc/ssh/sshd_config && sudo systemctl restart sshd"
# Restart build-agent to pick up new env
echo "==> Restarting build-agent service"
ssh -o StrictHostKeyChecking=no -i "${KEY_DIR}/id_build" "${BUILD_USER}@${VM_IP}" \
"sudo systemctl restart build-agent"
echo "==> Done. VM is ready. Test with: ssh -i ${KEY_DIR}/id_build ${BUILD_USER}@${VM_IP}"

View File

@@ -0,0 +1,22 @@
#!/bin/bash
set -euo pipefail
# Copy agent artefacts (provisioned by Packer file provisioner)
install -m 0755 /tmp/build-agent.py /usr/local/bin/build-agent
install -m 0644 /tmp/build-agent.service /etc/systemd/system/build-agent.service
install -m 0600 /tmp/build-agent.env.template /etc/build-agent.env.template
# Placeholder env file — operator fills this in before first boot
if [ ! -f /etc/build-agent.env ]; then
cp /etc/build-agent.env.template /etc/build-agent.env
fi
# Install autossh
apt-get install -y -qq autossh
# Enable agent service (starts on boot, after network-online)
systemctl daemon-reload
systemctl enable build-agent.service
# SSH host key generation (deterministic at first boot, not baked in image)
dpkg-reconfigure openssh-server

View File

@@ -0,0 +1,41 @@
#!/bin/bash
set -euo pipefail
DEBIAN_FRONTEND=noninteractive
# System deps (already installed via cloud-init but idempotent)
apt-get update -qq
apt-get install -y -qq build-essential curl git \
libgmp-dev libffi-dev zlib1g-dev libncurses-dev libtinfo-dev pkg-config
# GHCup — non-interactive bootstrap
# Primary version (9.8.4) is the default; secondary (9.6.6) covers LTS 22/23.
# Skip Stack (cabal covers 95% of projects) and HLS (saves ~2 GB image size).
GHC_PRIMARY="${GHC_PRIMARY_VERSION:-9.8.4}"
GHC_SECONDARY="${GHC_SECONDARY_VERSION:-9.6.6}"
CABAL_VERSION="${CABAL_VERSION:-3.12.1.0}"
export BOOTSTRAP_HASKELL_NONINTERACTIVE=1
export BOOTSTRAP_HASKELL_GHC_VERSION="$GHC_PRIMARY"
export BOOTSTRAP_HASKELL_CABAL_VERSION="$CABAL_VERSION"
export BOOTSTRAP_HASKELL_INSTALL_STACK=0 # not needed; cabal suffices
export BOOTSTRAP_HASKELL_INSTALL_HLS=0 # ~2 GB — skip for build-only image
curl --proto '=https' --tlsv1.2 -sSf https://get-ghcup.haskell.org \
| runuser -l build -c 'sh -s -- --no-modify-path'
# Add ghcup env to build user profile
echo '. "$HOME/.ghcup/env"' >> /home/build/.bashrc
echo '. "$HOME/.ghcup/env"' >> /home/build/.profile
# Install secondary GHC version (~500 MB, shared GHCup base — worth it)
runuser -l build -c "source ~/.ghcup/env && ghcup install ghc $GHC_SECONDARY"
# Ensure primary is the default
runuser -l build -c "source ~/.ghcup/env && ghcup set ghc $GHC_PRIMARY"
# Pre-warm cabal package db (saves 2-3 min on first real build)
runuser -l build -c 'source ~/.ghcup/env && cabal update'
# Verify both versions present
runuser -l build -c "source ~/.ghcup/env && ghc --version && cabal --version"
runuser -l build -c "source ~/.ghcup/env && ghcup run --ghc $GHC_SECONDARY -- ghc --version"

View File

@@ -0,0 +1,13 @@
#!/bin/bash
# setup-vm.sh — switches imported VM from NAT to bridged networking
VM_NAME="${1:?Usage: setup-vm.sh <vm-name> [adapter]}"
# Auto-detect first available bridge interface if not specified
ADAPTER="${2:-$(VBoxManage list bridgedifs | awk '/^Name:/{print $2; exit}')}"
VBoxManage modifyvm "$VM_NAME" \
--nic1 bridged \
--bridgeadapter1 "$ADAPTER" \
--memory 8192 --cpus 4
echo "Configured $VM_NAME: bridged on $ADAPTER"
echo "Next: inject keys with scripts/inject-keys.sh, then start VM"

View File

@@ -0,0 +1,37 @@
# Build machine port registry
# Range: 12221-12230 (10 slots)
# Each entry: port, vm_name, host_machine, status
ports:
12221:
vm_name: haskell-build-alpha
host_machine: unassigned
status: reserved
12222:
vm_name: haskell-build-beta
host_machine: unassigned
status: reserved
12223:
vm_name: unassigned
status: available
12224:
vm_name: unassigned
status: available
12225:
vm_name: unassigned
status: available
12226:
vm_name: unassigned
status: available
12227:
vm_name: unassigned
status: available
12228:
vm_name: unassigned
status: available
12229:
vm_name: unassigned
status: available
12230:
vm_name: unassigned
status: available

View File

@@ -0,0 +1,91 @@
#!/bin/bash
# smoke-test.sh — Validates the full Haskell build machine stack
#
# Prerequisites:
# - VM is booted and tunnel is established
# - State-hub is running on workstation (port 8000)
#
# Usage: ./smoke-test.sh [vm-ssh-host] [state-hub-url]
set -euo pipefail
VM="${1:-haskell-build}"
STATE_HUB="${2:-http://127.0.0.1:8000}"
PASS=0
FAIL=0
check() {
local desc="$1"
shift
if "$@" >/dev/null 2>&1; then
echo " PASS: $desc"
PASS=$((PASS + 1))
else
echo " FAIL: $desc"
FAIL=$((FAIL + 1))
fi
}
echo "=== Haskell Build Machine Smoke Test ==="
echo "VM: $VM | State Hub: $STATE_HUB"
echo ""
# 1. Check tunnel is up
echo "[1/5] Tunnel connectivity"
check "SSH to VM via tunnel" ssh -o ConnectTimeout=5 -o StrictHostKeyChecking=no "$VM" "true"
# 2. Check GHC is available
echo "[2/5] Haskell toolchain"
check "GHC is installed" ssh "$VM" "source ~/.ghcup/env && ghc --version"
check "Cabal is installed" ssh "$VM" "source ~/.ghcup/env && cabal --version"
check "GHCup is installed" ssh "$VM" "source ~/.ghcup/env && ghcup --version"
# 3. Check state-hub capability registration
echo "[3/5] State-hub capability"
check "State-hub is reachable" curl -sf "${STATE_HUB}/state/health"
CAPS=$(curl -sf "${STATE_HUB}/capability-catalog/?capability_type=haskell-build-agent" 2>/dev/null || echo "[]")
if echo "$CAPS" | python3 -c "import sys,json; entries=json.load(sys.stdin); sys.exit(0 if len(entries)>0 else 1)" 2>/dev/null; then
echo " PASS: haskell-build-agent capability registered"
PASS=$((PASS + 1))
else
echo " FAIL: haskell-build-agent capability not found in catalog"
FAIL=$((FAIL + 1))
fi
# 4. Build a minimal Haskell project
echo "[4/5] Remote build"
TMPDIR=$(mktemp -d)
mkdir -p "$TMPDIR/hello"
cat > "$TMPDIR/hello/Main.hs" << 'HASKELL'
module Main where
main :: IO ()
main = putStrLn "Hello from Haskell build machine!"
HASKELL
cat > "$TMPDIR/hello/hello.cabal" << 'CABAL'
cabal-version: 2.4
name: hello
version: 0.1.0.0
build-type: Simple
executable hello
main-is: Main.hs
build-depends: base >=4.14
default-language: Haskell2010
CABAL
# Sync and build
rsync -a --delete "$TMPDIR/hello/" "$VM:/build/hello-smoke/" 2>/dev/null
check "cabal build succeeds" ssh "$VM" "cd /build/hello-smoke && source ~/.ghcup/env && cabal build all"
# 5. Run the built executable
echo "[5/5] Execution"
check "built executable runs" ssh "$VM" "cd /build/hello-smoke && source ~/.ghcup/env && cabal run hello"
# Cleanup
rm -rf "$TMPDIR"
ssh "$VM" "rm -rf /build/hello-smoke" 2>/dev/null || true
echo ""
echo "=== Results: $PASS passed, $FAIL failed ==="
[ "$FAIL" -eq 0 ] && echo "All checks passed." || echo "Some checks failed — review output above."
exit "$FAIL"

View File

@@ -0,0 +1,11 @@
# Haskell Build VM — tunnel via workstation (auto-generated)
# Source: infra/build-machines/README.md
Host haskell-build haskell-build-alpha
HostName localhost
Port 12222
User build
IdentityFile ~/.ssh/id_build
StrictHostKeyChecking no
UserKnownHostsFile /dev/null
ServerAliveInterval 30
ServerAliveCountMax 3

View File

@@ -0,0 +1,3 @@
# State-hub entity references for build-machines infra
# Populated after capability type registration via POST /capability-catalog/
capability_type_entry_id: "pending-registration"

View File

@@ -0,0 +1,53 @@
---
id: 2026-05-02-state-hub-wsl2-restore-drill
type: restore-drill
domain: custodian
repo: the-custodian
workplan: CUST-WP-0011
task: T01
created: "2026-05-02"
author: codex
---
# State Hub WSL2 Restore Drill — 2026-05-02
## Summary
Completed the CUST-WP-0011 T01 pre-migration safety drill. A fresh SQL dump of
the live WSL2 State Hub PostgreSQL database was restored into a disposable
PostgreSQL 16 container and verified through the State Hub application.
## Source
- Live container: `infra-postgres-1`
- Source database: `custodian`
- Temporary dump artifact: `/tmp/state-hub-restore-drill/state-hub-drill.sql.gz`
(removed after verification because it was an unencrypted drill artifact)
- Restore container: `state-hub-restore-test`
- Restore endpoint: `127.0.0.1:5433`
## Verification
- Restore command exited 0.
- Production and restored table row counts matched exactly.
- State Hub app pointed at the restored DB returned:
- `/state/health`: HTTP 200, DB connected.
- `/state/summary`: HTTP 200.
Key restored counts:
| Table | Rows |
|---|---:|
| workstreams | 117 |
| tasks | 989 |
| progress_events | 1423 |
| token_events | 208 |
| managed_repos | 19 |
| sbom_entries | 2257 |
## Notes
State Hub does not yet have a dedicated `make backup` / `make restore` target.
This drill used direct `pg_dump` and `psql` via Docker, which proves the data
path but should be wrapped in first-class commands before the railiance01
cutover.

View File

@@ -221,5 +221,27 @@ EPs need to be surfaced in `get_state_summary()`.
| W2 | `register_project.sh` script + `make register-project` | 1 hr | 25K / registration | Before next project |
| W5 | `TOOLS.md` reference card | 30 min | 2,500 / session | Next custodian session |
| W4 | Topic IDs in canon charters | 20 min | 200 / registration | Low urgency |
| W7 | SessionStart hook for API health | 30 min | Indirect | After W2 |
| W8 | First-class EP entity in state hub (EP-CUST-001) | 24 hr | Indirect | When EP count warrants it |
| W7 | SessionStart hook for API health | 30 min | Indirect | After W2 |
| W8 | First-class EP entity in state hub (EP-CUST-001) | 24 hr | Indirect | When EP count warrants it |
---
## 2026-05-02 Update — Task-Flow Engine Lifecycle Model
CUST-WP-0035 replaced the old assumption that State Hub lifecycle movement is
only a fixed set of status enums and hardcoded transition tables.
Current model:
- Information objects expose a stored workstation label, still surfaced as
`status` for API compatibility.
- `get_flow_state(entity_type, entity_id)` reports reachable workstations,
unreachable workstations, and blocking assertions.
- `advance_workstation(entity_type, entity_id, target_workstation)` is the
preferred lifecycle movement tool when a flow definition exists.
- Direct status update tools remain useful for bootstrap, legacy workflows, and
file-backed consistency sync, but they are no longer the conceptual center of
lifecycle management.
Reference spec:
`state-hub/docs/task-flow-engine-spec.md`

View File

@@ -0,0 +1,20 @@
---
type: working-memory
source: activity-core
activity_id: 6fca51fa-387a-4fd0-bc4e-d62c29eb859a
activity_core_run_id: 2164cb88-8415-5c96-9e31-e47a41cf4e67
instruction_id: daily-triage-report
scheduled_for: 2026-05-19T18:02:27.787640+00:00
created: 2026-05-19T18:02:36.669876+00:00
---
# Daily State Hub WSJF Triage - 2026-05-19
ok
```json
{
"recommendations": [],
"summary": "ok"
}
```

View File

@@ -0,0 +1,75 @@
---
type: working-memory
source: activity-core
activity_id: 6fca51fa-387a-4fd0-bc4e-d62c29eb859a
activity_core_run_id: f9b97749-c1d0-5746-ab18-89932bef47c1
instruction_id: daily-triage-report
scheduled_for: 2026-06-02T12:52:01.690214+00:00
created: 2026-06-02T12:52:14.349339+00:00
---
# Daily State Hub WSJF Triage - 2026-06-02
13 active workstreams with 58 open tasks. High-priority triage items need immediate attention, including 6 tasks requiring human intervention and 1 blocked workstream. Daily triage infrastructure itself is in active development.
```json
{
"recommendations": [
{
"action": "work-next",
"candidate": "cust-wp-0044",
"confidence": "high",
"why": "Current workplan for this very triage process - needs completion for self-sustaining operations"
},
{
"action": "work-next",
"candidate": "cust-wp-0045",
"confidence": "high",
"why": "Daily triage runner infrastructure - critical dependency for automated operations"
},
{
"action": "needs-human",
"candidate": "cust-wp-0046",
"confidence": "high",
"why": "Blocked status with 1 needs_human task - requires intervention to unblock"
},
{
"action": "needs-human",
"candidate": "hf-wp-0001",
"confidence": "high",
"why": "5 needs_human tasks in high-priority ops-hub establishment workstream"
},
{
"action": "needs-human",
"candidate": "railiance-wp-0004",
"confidence": "medium",
"why": "Medium priority with 1 needs_human task but no open todos - may need task breakdown"
},
{
"action": "work-next",
"candidate": "whi-kpi-card",
"confidence": "medium",
"why": "9 open high-priority tasks for workstream health monitoring - supports triage operations"
},
{
"action": "revisit",
"candidate": "cust-wp-0011",
"confidence": "medium",
"why": "6 high-priority migration tasks but no planning priority set - needs prioritization review"
},
{
"action": "split",
"candidate": "cust-wp-0025",
"confidence": "high",
"why": "25 open tasks in single workstream - too large for effective management"
},
{
"action": "park",
"candidate": "adhoc-2026-06-01",
"confidence": "medium",
"why": "Single low-priority opportunistic fix - defer until higher priorities complete"
}
],
"summary": "13 active workstreams with 58 open tasks. High-priority triage items need immediate attention, including 6 tasks requiring human intervention and 1 blocked workstream. Daily triage infrastructure itself is in active development."
}
```

View File

@@ -0,0 +1,63 @@
---
type: working-memory
source: activity-core
activity_id: 6fca51fa-387a-4fd0-bc4e-d62c29eb859a
activity_core_run_id: 6d2737e3-a796-5b0e-9d4f-f3003f1dbe49
instruction_id: daily-triage-report
scheduled_for: None
created: 2026-06-03T05:20:10.810171+00:00
---
# Daily State Hub WSJF Triage - 2026-06-03
13 active workstreams with 59 open tasks. High-priority triage items include 6 needs-human tasks in HF-WP-0001, blocked CUST-WP-0046, and two active daily triage workstreams ready for execution.
```json
{
"recommendations": [
{
"action": "work-next",
"candidate": "cust-wp-0044",
"confidence": "high",
"why": "High priority daily triage workstream with 1 todo task, directly supports this report generation"
},
{
"action": "work-next",
"candidate": "cust-wp-0045",
"confidence": "high",
"why": "High priority daily triage runner with 2 todo tasks, enables automation of this process"
},
{
"action": "needs-human",
"candidate": "hf-wp-0001",
"confidence": "high",
"why": "High priority but has 5 needs-human tasks requiring human decision-making"
},
{
"action": "needs-human",
"candidate": "cust-wp-0046",
"confidence": "high",
"why": "Blocked status with 1 needs-human task preventing progress"
},
{
"action": "work-next",
"candidate": "whi-kpi-card",
"confidence": "medium",
"why": "9 todo tasks with high priority items, no human intervention needed"
},
{
"action": "revisit",
"candidate": "cust-wp-0011",
"confidence": "medium",
"why": "6 high priority migration tasks but no planning priority set, needs prioritization review"
},
{
"action": "work-next",
"candidate": "adhoc-llmc-2026-06-02",
"confidence": "medium",
"why": "Recent ad-hoc work with 6 medium priority tasks, likely time-sensitive"
}
],
"summary": "13 active workstreams with 59 open tasks. High-priority triage items include 6 needs-human tasks in HF-WP-0001, blocked CUST-WP-0046, and two active daily triage workstreams ready for execution."
}
```

View File

@@ -0,0 +1,75 @@
---
type: working-memory
source: activity-core
activity_id: 6fca51fa-387a-4fd0-bc4e-d62c29eb859a
activity_core_run_id: 65e273bf-08f1-5b3c-ace7-191ca32bf468
instruction_id: daily-triage-report
scheduled_for: None
created: 2026-06-04T05:21:12.224105+00:00
---
# Daily State Hub WSJF Triage - 2026-06-04
11 active workstreams with 3 high-priority items needing immediate attention. CUST-WP-0044 (this triage system) and CUST-WP-0045 (daily runner) are in calibration phase. HF-WP-0001 has 5 human-needed tasks blocking ops-hub extension. One workstream blocked, infrastructure migration work distributed across multiple streams.
```json
{
"recommendations": [
{
"action": "work-next",
"candidate": "cust-wp-0044",
"confidence": "high",
"why": "High priority, active calibration of this triage system itself"
},
{
"action": "work-next",
"candidate": "cust-wp-0045",
"confidence": "high",
"why": "High priority daily runner cutover, supports triage automation"
},
{
"action": "needs-human",
"candidate": "hf-wp-0001",
"confidence": "high",
"why": "High priority but 5 tasks need human input, blocking ops-hub extension"
},
{
"action": "revisit",
"candidate": "cust-wp-0046",
"confidence": "medium",
"why": "Blocked status with 1 human-needed task, assess unblocking conditions"
},
{
"action": "needs-human",
"candidate": "rail-ho-wp-0005",
"confidence": "medium",
"why": "Large workstream (11 tasks) with 4 human-needed items including high-priority design decisions"
},
{
"action": "work-next",
"candidate": "cust-wp-0003",
"confidence": "medium",
"why": "9 todo tasks, all high priority, no human intervention needed"
},
{
"action": "needs-consistency-sync",
"candidate": "cust-wp-0011",
"confidence": "medium",
"why": "Infrastructure migration overlaps with CUST-WP-0038, coordinate sequencing"
},
{
"action": "close-out",
"candidate": "state-wp-0052",
"confidence": "high",
"why": "No open tasks remaining, appears complete"
},
{
"action": "close-out",
"candidate": "ihub-wp-0018",
"confidence": "high",
"why": "No open tasks remaining, appears complete"
}
],
"summary": "11 active workstreams with 3 high-priority items needing immediate attention. CUST-WP-0044 (this triage system) and CUST-WP-0045 (daily runner) are in calibration phase. HF-WP-0001 has 5 human-needed tasks blocking ops-hub extension. One workstream blocked, infrastructure migration work distributed across multiple streams."
}
```

View File

@@ -0,0 +1,175 @@
---
type: working-memory
source: activity-core
activity_id: 6fca51fa-387a-4fd0-bc4e-d62c29eb859a
activity_core_run_id: 99d67d71-8729-5036-b067-ca05ccf41751
instruction_id: daily-triage-report
scheduled_for: 2026-06-05T17:23:04.606642+00:00
output_validated: true
review_required: false
model: custodian-triage-balanced
prompt_hash: f0a4fa2d81d08391bf07ca73a6df8916c07c9baf270e33040c989cea7523d725
created: 2026-06-05T17:23:29.040451+00:00
---
# Daily State Hub WSJF Triage - 2026-06-05
High-priority ops-hub establishment blocked on human decisions; multiple infrastructure migrations ready for automation; recommend focusing on unblocking foundational systems first
```json
{
"recommendations": [
{
"action": "needs-human",
"candidate": "hf-wp-0001",
"confidence": "high",
"rank": 1,
"why": "Critical ops-hub establishment blocked with 5 human-needed tasks in wait status",
"wsjf": {
"job_size": 2,
"opportunity_enablement": 5,
"risk_reduction": 4,
"score": 9.5,
"strategic_value": 5,
"time_criticality": 5
}
},
{
"action": "work-next",
"candidate": "cust-wp-0011",
"confidence": "high",
"rank": 2,
"why": "State Hub migration in progress with clear next steps, no blockers",
"wsjf": {
"job_size": 2,
"opportunity_enablement": 4,
"risk_reduction": 4,
"score": 7.6,
"strategic_value": 4,
"time_criticality": 5
}
},
{
"action": "work-next",
"candidate": "ihub-wp-0018",
"confidence": "high",
"rank": 3,
"why": "Railiance01 deployment has actionable todo tasks ready for automation",
"wsjf": {
"job_size": 2,
"opportunity_enablement": 4,
"risk_reduction": 3,
"score": 6.8,
"strategic_value": 4,
"time_criticality": 4
}
},
{
"action": "needs-human",
"candidate": "rail-ho-wp-0005",
"confidence": "medium",
"rank": 4,
"why": "Forgejo migration has high-priority human decisions needed for T02",
"wsjf": {
"job_size": 3,
"opportunity_enablement": 3,
"risk_reduction": 4,
"score": 5.0,
"strategic_value": 3,
"time_criticality": 3
}
},
{
"action": "split",
"candidate": "cust-wp-0025",
"confidence": "medium",
"rank": 5,
"why": "FOS Hub Bootstrap has 25 todo tasks - too large, should be decomposed",
"wsjf": {
"job_size": 4,
"opportunity_enablement": 4,
"risk_reduction": 3,
"score": 3.8,
"strategic_value": 4,
"time_criticality": 2
}
},
{
"action": "park",
"candidate": "cust-wp-0038",
"confidence": "high",
"rank": 6,
"why": "HA migration should wait until basic State Hub migration completes",
"wsjf": {
"job_size": 4,
"opportunity_enablement": 3,
"risk_reduction": 4,
"score": 3.2,
"strategic_value": 3,
"time_criticality": 1
}
},
{
"action": "needs-cross-agent",
"candidate": "railiance-wp-0004",
"confidence": "medium",
"rank": 7,
"why": "Package registry publication depends on Gitea/Forgejo infrastructure decisions",
"wsjf": {
"job_size": 3,
"opportunity_enablement": 3,
"risk_reduction": 2,
"score": 3.0,
"strategic_value": 2,
"time_criticality": 2
}
},
{
"action": "needs-consistency-sync",
"candidate": "issue-wp-0002",
"confidence": "medium",
"rank": 8,
"why": "Blocked status conflicts with railiance-wp-0004 dependency chain",
"wsjf": {
"job_size": 3,
"opportunity_enablement": 2,
"risk_reduction": 2,
"score": 2.7,
"strategic_value": 2,
"time_criticality": 2
}
},
{
"action": "revisit",
"candidate": "activity-wp-0006",
"confidence": "low",
"rank": 9,
"why": "Single wait task with medium priority - check if conditions met",
"wsjf": {
"job_size": 3,
"opportunity_enablement": 2,
"risk_reduction": 2,
"score": 2.5,
"strategic_value": 2,
"time_criticality": 1
}
},
{
"action": "revisit",
"candidate": "rail-fab-wp-0023",
"confidence": "low",
"rank": 10,
"why": "Single wait task for UI improvement - verify completion conditions",
"wsjf": {
"job_size": 2,
"opportunity_enablement": 1,
"risk_reduction": 1,
"score": 2.0,
"strategic_value": 1,
"time_criticality": 1
}
}
],
"summary": "High-priority ops-hub establishment blocked on human decisions; multiple infrastructure migrations ready for automation; recommend focusing on unblocking foundational systems first"
}
```

View File

@@ -0,0 +1,175 @@
---
type: working-memory
source: activity-core
activity_id: 6fca51fa-387a-4fd0-bc4e-d62c29eb859a
activity_core_run_id: 1e00affe-5389-5f94-875e-dc84e432f4b8
instruction_id: daily-triage-report
scheduled_for: 2026-06-06T13:07:50.393977+00:00
output_validated: true
review_required: false
model: custodian-triage-balanced
prompt_hash: 99621c25747a03cebd27b5c9540d9012d473ec7772df7f8e5143904abdedc32b
created: 2026-06-06T13:08:25.268978+00:00
---
# Daily State Hub WSJF Triage - 2026-06-06
11 active workstreams with critical ops-hub establishment blocked on human decisions. High-priority infrastructure migrations ready for execution while foundational systems await manual intervention.
```json
{
"recommendations": [
{
"action": "needs-human",
"candidate": "hf-wp-0001",
"confidence": "high",
"rank": 1,
"why": "5 high-priority tasks waiting for human decisions to establish ops-hub foundation",
"wsjf": {
"job_size": 2,
"opportunity_enablement": 5,
"risk_reduction": 5,
"score": 10.0,
"strategic_value": 5,
"time_criticality": 5
}
},
{
"action": "work-next",
"candidate": "cust-wp-0011",
"confidence": "high",
"rank": 2,
"why": "State Hub migration in progress with clear next steps and no blockers",
"wsjf": {
"job_size": 2,
"opportunity_enablement": 5,
"risk_reduction": 5,
"score": 9.5,
"strategic_value": 5,
"time_criticality": 4
}
},
{
"action": "needs-human",
"candidate": "rail-ho-wp-0005",
"confidence": "high",
"rank": 3,
"why": "Forgejo migration requires human decisions on production design",
"wsjf": {
"job_size": 3,
"opportunity_enablement": 4,
"risk_reduction": 4,
"score": 7.7,
"strategic_value": 4,
"time_criticality": 4
}
},
{
"action": "needs-cross-agent",
"candidate": "cust-wp-0047",
"confidence": "medium",
"rank": 4,
"why": "Ops Hub widgets waiting on Inter-Hub activation coordination",
"wsjf": {
"job_size": 2,
"opportunity_enablement": 4,
"risk_reduction": 3,
"score": 7.5,
"strategic_value": 4,
"time_criticality": 4
}
},
{
"action": "needs-cross-agent",
"candidate": "ihub-wp-0018",
"confidence": "medium",
"rank": 5,
"why": "Railiance01 deployment has dependencies across multiple systems",
"wsjf": {
"job_size": 3,
"opportunity_enablement": 3,
"risk_reduction": 4,
"score": 6.7,
"strategic_value": 4,
"time_criticality": 3
}
},
{
"action": "work-next",
"candidate": "agentic-wp-0001",
"confidence": "high",
"rank": 6,
"why": "Ready status with clear todo tasks for State Hub integration",
"wsjf": {
"job_size": 2,
"opportunity_enablement": 3,
"risk_reduction": 3,
"score": 6.0,
"strategic_value": 3,
"time_criticality": 3
}
},
{
"action": "park",
"candidate": "cust-wp-0038",
"confidence": "high",
"rank": 7,
"why": "HA migration should wait until basic State Hub migration completes",
"wsjf": {
"job_size": 4,
"opportunity_enablement": 3,
"risk_reduction": 4,
"score": 5.0,
"strategic_value": 4,
"time_criticality": 2
}
},
{
"action": "park",
"candidate": "cust-wp-0025",
"confidence": "medium",
"rank": 8,
"why": "25 todo tasks indicate scope too large, should be split after core systems stable",
"wsjf": {
"job_size": 5,
"opportunity_enablement": 4,
"risk_reduction": 3,
"score": 3.6,
"strategic_value": 3,
"time_criticality": 2
}
},
{
"action": "revisit",
"candidate": "activity-wp-0006",
"confidence": "low",
"rank": 9,
"why": "Single waiting task needs status check for operational hardening",
"wsjf": {
"job_size": 1,
"opportunity_enablement": 3,
"risk_reduction": 2,
"score": 3.0,
"strategic_value": 2,
"time_criticality": 2
}
},
{
"action": "close-out",
"candidate": "ihub-wp-0010",
"confidence": "high",
"rank": 10,
"why": "No open tasks remaining, appears complete",
"wsjf": {
"job_size": 1,
"opportunity_enablement": 1,
"risk_reduction": 1,
"score": 2.0,
"strategic_value": 1,
"time_criticality": 1
}
}
],
"summary": "11 active workstreams with critical ops-hub establishment blocked on human decisions. High-priority infrastructure migrations ready for execution while foundational systems await manual intervention."
}
```

View File

@@ -0,0 +1,30 @@
---
type: working-memory
source: activity-core
activity_id: 6fca51fa-387a-4fd0-bc4e-d62c29eb859a
activity_core_run_id: a7447a71-6a82-5207-b4f5-d823f226ef91
instruction_id: daily-triage-report
scheduled_for: None
output_validated: false
review_required: true
model: custodian-triage-balanced
prompt_hash: d7f3116370cb01ff29e5dc68152ee087388f0a1d0656bf90ad8c809abc4293d5
created: 2026-06-06T07:12:09.570973+00:00
---
# Daily State Hub WSJF Triage - 2026-06-06
Instruction daily-triage-report produced output that failed validation; partial output was preserved for operator review.
Validation error:
`Expecting value: line 1 column 1 (char 0)`
```json
{
"raw_output_preview": "```json\n{\n \"summary\": \"11 active workstreams with 74 open tasks. High-priority ops-hub establishment blocked on human decisions. Infrastructure migrations progressing but need coordination.\",\n \"recommendations\": [\n {\n \"rank\": 1,\n \"candidate\": \"hf-wp-0001\",\n \"action\": \"needs-human\",\n \"why\": \"5 high-priority tasks waiting for human decisions to establish ops-hub foundation\",\n \"confidence\": \"high\",\n \"wsjf\": {\n \"score\": 9.5,\n \"strategic_value\": 5,\n \"time_criticality\": 5,\n \"risk_reduction\": 4,\n \"opportunity_enablement\": 5,\n \"job_size\": 2\n }\n },\n {\n \"rank\": 2,\n \"candidate\": \"cust-wp-0047\",\n \"action\": \"work-next\",\n \"why\": \"High-priority ops-hub service inventory with minimal blockers\",\n \"confidence\": \"high\",\n \"wsjf\": {\n \"score\": 9.0,\n \"strategic_value\": 4,\n \"time_criticality\": 4,\n \"risk_reduction\": 4,\n \"opportunity_enablement\": 6,\n \"job_size\": 2\n }\n },\n {\n \"rank\": 3,\n \"candidate\": \"rail-ho-wp-0005\",\n \"action\": \"needs-human\",\n \"why\": \"4 tasks need human decisions for Forgejo production migration\",\n \"confidence\": \"medium\",\n \"wsjf\": {\n \"score\": 6.0,\n \"strategic_value\": 4,\n \"time_criticality\": 3,\n \"risk_reduction\": 5,\n \"opportunity_enablement\": 3,\n \"job_size\": 3\n }\n },\n {\n \"rank\": 4,\n \"candidate\": \"cust-wp-0011\",\n \"action\": \"work-next\",\n \"why\": \"State Hub migration in progress with clear next steps\",\n \"confidence\": \"high\",\n \"wsjf\": {\n \"score\": 5.7,\n \"strategic_value\": 4,\n \"time_criticality\": 4,\n \"risk_reduction\": 4,\n \"opportunity_enablement\": 5,\n \"job_size\": 3\n }\n },\n {\n \"rank\": 5,\n \"candidate\": \"ihub-wp-0018\",\n \"action\": \"needs-cross-agent\",\n \"why\": \"Railiance01 deployment has dependencies across multiple domains\",\n \"confidence\": \"medium\",\n \"wsjf\": {\n \"score\": 5.3,\n \"strategic_value\": 4,\n \"time_criticality\": 3,\n \"risk_reduction\": 4,\n \"opportunity_enablement\": 5,\n \"job_size\": 3\n }\n },\n {\n \"rank\": 6,\n \"candidate\": \"agentic-wp-0001\",\n \"action\": \"work-next\",\n \"why\": \"Ready status with clear todo tasks for State Hub integration\",\n \"confidence\": \"high\",\n \"wsjf\": {\n \"score\": 5.0,\n \"strategic_value\": 3,\n \"time_criticality\": 2,\n \"risk_reduction\": 3,\n \"opportunity_enablement\": 4,\n \"job_size\": 2\n }\n },\n {\n \"rank\": 7,\n \"candidate\": \"cust-wp-0025\",\n \"action\": \"split\",\n \"why\": \"25 todo tasks suggest workplan is too large for effective management\",\n \"confidence\": \"medium\",\n \"wsjf\": {\n \"score\": 3.6,\n \"strategic_value\": 4,\n \"time_criticality\": 2,\n \"risk_reduction\": 3,\n \"opportunity_enablement\": 4,\n \"job_size\": 5\n }\n },\n {\n \"rank\": 8,\n \"candidate\": \"cust-wp-0038\",\n \"action\": \"park\",\n \"why\": \"HA migration should wait until basic State Hub migration completes\",\n \"confidence\": \"high\",\n \"wsjf\": {\n \"score\": 3.2,\n \"strategic_value\": 3,\n \"time_criticality\": 1,\n \"risk_reduction\": 4,\n \"opportunity_enablement\": 3,\n \"job_size\": 4\n }\n },\n {\n \"rank\": 9,\n \"candidate\": \"activity-wp-0006\",\n \"action\": \"revisit\",\n \"why\": \"Single waiting task needs status check for operational hardening\",\n \"confidence\": \"low\",\n \"wsjf\": {\n \"score\": 3.0,\n \"strategic_value\": 2,\n \"time_criticality\": 1,\n \"risk_reduction\": 3,\n \"opportunity_enablement\": 3,\n \"job_size\": 1\n }\n },\n {\n \"rank\": 10,\n \"candidate\": \"ihub-wp-0010\",\n \"action\": \"close-out\",\n \"why\": \"No open tasks remaining in external API workplan\",\n \"confidence\": \"high\",\n ",
"status": "validation_failed",
"summary": "Instruction daily-triage-report produced output that failed validation; partial output was preserved for operator review.",
"validation_error": "Expecting value: line 1 column 1 (char 0)"
}
```

View File

@@ -0,0 +1,175 @@
---
type: working-memory
source: activity-core
activity_id: 6fca51fa-387a-4fd0-bc4e-d62c29eb859a
activity_core_run_id: c2db32e5-3874-522f-ae1f-9b2cdf307fd2
instruction_id: daily-triage-report
scheduled_for: 2026-06-06T13:23:30.903196+00:00
output_validated: true
review_required: false
model: custodian-triage-balanced
prompt_hash: 5785bba76a223965cdcda27c9eff0c70a6dfe358b51989455fbb47e1ccd94dc0
created: 2026-06-06T13:23:49.608650+00:00
---
# Daily State Hub WSJF Triage - 2026-06-06
High-priority ops-hub establishment blocked on human decisions; infrastructure migrations progressing; recommend focusing on unblocking wait states and completing foundational deployments
```json
{
"recommendations": [
{
"action": "needs-human",
"candidate": "hf-wp-0001",
"confidence": "high",
"rank": 1,
"why": "Critical ops-hub establishment blocked with 5 human-needed tasks in wait state",
"wsjf": {
"job_size": 2,
"opportunity_enablement": 3,
"risk_reduction": 5,
"score": 9.0,
"strategic_value": 5,
"time_criticality": 5
}
},
{
"action": "work-next",
"candidate": "cust-wp-0011",
"confidence": "high",
"rank": 2,
"why": "State Hub migration in progress with clear next steps, foundational for other workstreams",
"wsjf": {
"job_size": 3,
"opportunity_enablement": 3,
"risk_reduction": 4,
"score": 6.0,
"strategic_value": 4,
"time_criticality": 4
}
},
{
"action": "needs-human",
"candidate": "rail-ho-wp-0005",
"confidence": "high",
"rank": 3,
"why": "Forgejo migration has 4 human-needed tasks, critical for development infrastructure",
"wsjf": {
"job_size": 3,
"opportunity_enablement": 3,
"risk_reduction": 4,
"score": 5.7,
"strategic_value": 4,
"time_criticality": 3
}
},
{
"action": "work-next",
"candidate": "ihub-wp-0018",
"confidence": "medium",
"rank": 4,
"why": "Railiance01 deployment progressing with actionable todo tasks",
"wsjf": {
"job_size": 3,
"opportunity_enablement": 3,
"risk_reduction": 3,
"score": 5.0,
"strategic_value": 4,
"time_criticality": 3
}
},
{
"action": "needs-cross-agent",
"candidate": "cust-wp-0047",
"confidence": "medium",
"rank": 5,
"why": "Ops Hub widgets blocked on Inter-Hub activation, needs coordination",
"wsjf": {
"job_size": 2,
"opportunity_enablement": 4,
"risk_reduction": 2,
"score": 4.5,
"strategic_value": 3,
"time_criticality": 4
}
},
{
"action": "work-next",
"candidate": "agentic-wp-0001",
"confidence": "medium",
"rank": 6,
"why": "Ready status with clear todo tasks for State Hub integration",
"wsjf": {
"job_size": 3,
"opportunity_enablement": 5,
"risk_reduction": 3,
"score": 4.3,
"strategic_value": 3,
"time_criticality": 2
}
},
{
"action": "split",
"candidate": "cust-wp-0025",
"confidence": "high",
"rank": 7,
"why": "Large workstream with 25 todo tasks, should be broken into smaller chunks",
"wsjf": {
"job_size": 5,
"opportunity_enablement": 4,
"risk_reduction": 3,
"score": 3.6,
"strategic_value": 4,
"time_criticality": 2
}
},
{
"action": "park",
"candidate": "cust-wp-0038",
"confidence": "medium",
"rank": 8,
"why": "HA migration should wait until basic State Hub migration completes",
"wsjf": {
"job_size": 4,
"opportunity_enablement": 3,
"risk_reduction": 4,
"score": 2.6,
"strategic_value": 2,
"time_criticality": 1
}
},
{
"action": "revisit",
"candidate": "activity-wp-0006",
"confidence": "low",
"rank": 9,
"why": "Single wait task for calibration feedback, check if conditions are met",
"wsjf": {
"job_size": 2,
"opportunity_enablement": 2,
"risk_reduction": 1,
"score": 2.5,
"strategic_value": 2,
"time_criticality": 2
}
},
{
"action": "close-out",
"candidate": "ihub-wp-0010",
"confidence": "high",
"rank": 10,
"why": "No open tasks remaining, appears complete",
"wsjf": {
"job_size": 1,
"opportunity_enablement": 1,
"risk_reduction": 1,
"score": 2.0,
"strategic_value": 1,
"time_criticality": 1
}
}
],
"summary": "High-priority ops-hub establishment blocked on human decisions; infrastructure migrations progressing; recommend focusing on unblocking wait states and completing foundational deployments"
}
```

View File

@@ -0,0 +1,29 @@
---
type: working-memory
source: activity-core
activity_id: 6fca51fa-387a-4fd0-bc4e-d62c29eb859a
activity_core_run_id: 96919365-c608-55c1-8aeb-d165d71c342d
instruction_id: daily-triage-report
scheduled_for: None
output_validated: false
review_required: true
model: custodian-triage-balanced
prompt_hash:
created: 2026-06-18T06:07:49.563454+00:00
---
# Daily State Hub WSJF Triage - 2026-06-18
Instruction daily-triage-report could not run; operator review is required.
Validation error:
`LLM_CONNECT_URL is not configured`
```json
{
"status": "execution_failed",
"summary": "Instruction daily-triage-report could not run; operator review is required.",
"validation_error": "LLM_CONNECT_URL is not configured"
}
```

View File

@@ -6,10 +6,24 @@ Operational runbooks and incident reports for the Railiance/Custodian infrastruc
```
ops/
service-inventory.yml — non-secret service/location/evidence seed for ops-hub
runbooks/ — how-to guides for recurring operational tasks and known issues
incidents/ — post-incident reports (append-only, one file per incident)
```
## Inventory
| Artifact | Covers |
|----------|--------|
| [service-inventory.yml](service-inventory.yml) | Initial ops-hub service inventory: environments, hosts, clusters, services, endpoints, access paths, evidence, and gaps |
| [../docs/ops-hub-service-catalog.md](../docs/ops-hub-service-catalog.md) | Rendered service catalog now view generated from the inventory |
Render the first catalog view with:
```bash
make ops-inventory-view
```
## Runbooks
| Runbook | Covers |

View File

@@ -0,0 +1,216 @@
#!/usr/bin/env python3
"""Render the ops service inventory into a compact Markdown now view."""
from __future__ import annotations
import argparse
from collections import Counter
from pathlib import Path
from typing import Any
try:
import yaml
except ImportError as exc: # pragma: no cover - environment guard
raise SystemExit("PyYAML is required to render ops/service-inventory.yml") from exc
DEFAULT_INPUT = Path("ops/service-inventory.yml")
DEFAULT_OUTPUT = Path("docs/ops-hub-service-catalog.md")
def text(value: Any, default: str = "-") -> str:
if value is None:
return default
if isinstance(value, str):
return value if value else default
return str(value)
def md(value: Any) -> str:
return text(value).replace("|", "\\|").replace("\n", "<br>")
def joined(values: list[Any] | None, limit: int | None = None) -> str:
if not values:
return "-"
items = [text(v) for v in values]
if limit is not None and len(items) > limit:
shown = items[:limit]
shown.append(f"+{len(items) - limit} more")
items = shown
return "<br>".join(md(item) for item in items)
def endpoint_label(endpoint: dict[str, Any]) -> str:
label = endpoint.get("url") or endpoint.get("id") or "-"
checks: list[str] = []
if endpoint.get("expected_status") is not None:
checks.append(f"status {endpoint['expected_status']}")
if endpoint.get("expected_signal"):
checks.append(endpoint["expected_signal"])
if checks:
label = f"{label}<br>Expected: {', '.join(checks)}"
return md(label)
def primary_endpoint(service: dict[str, Any]) -> str:
endpoints = service.get("endpoints") or []
if not endpoints:
return "-"
return endpoint_label(endpoints[0])
def runtime_label(service: dict[str, Any], envs: dict[str, dict[str, Any]]) -> str:
env_id = service.get("environment")
env = envs.get(env_id, {})
parts = [env.get("name") or env_id or "-"]
runtime = service.get("runtime") or {}
details: list[str] = []
for key in ("type", "cluster", "namespace", "host", "public_endpoint"):
if runtime.get(key):
details.append(f"{key}: {runtime[key]}")
if runtime.get("ports"):
details.append("ports: " + ", ".join(str(p) for p in runtime["ports"]))
if details:
parts.append("; ".join(details))
return "<br>".join(md(part) for part in parts)
def access_label(service: dict[str, Any]) -> str:
paths = service.get("access_paths") or []
if not paths:
return "-"
labels = []
for path in paths[:2]:
labels.append(
f"{path.get('type', '-')}: {path.get('status', 'unknown')} "
f"({path.get('target', '-')})"
)
if len(paths) > 2:
labels.append(f"+{len(paths) - 2} more")
return "<br>".join(md(label) for label in labels)
def latest_evidence(service: dict[str, Any]) -> str:
evidence = service.get("evidence") or []
if not evidence:
return "-"
dated = [item for item in evidence if item.get("observed_at")]
latest = max(dated, key=lambda item: item["observed_at"]) if dated else evidence[-1]
when = latest.get("observed_at") or "undated"
summary = latest.get("summary") or latest.get("source") or "-"
return md(f"{when}: {summary}")
def service_table(inventory: dict[str, Any]) -> str:
envs = {env["id"]: env for env in inventory.get("environments", [])}
rows = [
"| Service | Where | Owner | Endpoint | Health | Data | Access | Top Gap |",
"|---|---|---|---|---|---|---|---|",
]
for service in inventory.get("services", []):
gaps = service.get("gaps") or []
rows.append(
"| "
+ " | ".join(
[
md(f"{service.get('name')} ({service.get('id')})"),
runtime_label(service, envs),
joined(service.get("owner_repos"), limit=3),
primary_endpoint(service),
md(f"{service.get('health_status', 'unknown')}<br>{latest_evidence(service)}"),
joined(service.get("backing_stores"), limit=3),
access_label(service),
md(gaps[0] if gaps else "-"),
]
)
+ " |"
)
return "\n".join(rows)
def summary_table(inventory: dict[str, Any]) -> str:
services = inventory.get("services", [])
health = Counter(service.get("health_status", "unknown") for service in services)
rows = [
"| Metric | Count |",
"|---|---:|",
f"| Environments | {len(inventory.get('environments', []))} |",
f"| Hosts | {len(inventory.get('hosts', []))} |",
f"| Clusters | {len(inventory.get('clusters', []))} |",
f"| Services | {len(services)} |",
]
for status, count in sorted(health.items()):
rows.append(f"| Services: {md(status)} | {count} |")
return "\n".join(rows)
def gaps_section(inventory: dict[str, Any]) -> str:
lines = ["## Open Operating Gaps", ""]
for service in inventory.get("services", []):
gaps = service.get("gaps") or []
if not gaps:
continue
lines.append(f"### {service.get('name')} (`{service.get('id')}`)")
lines.append("")
for gap in gaps:
lines.append(f"- {gap}")
lines.append("")
return "\n".join(lines).rstrip()
def render(inventory: dict[str, Any]) -> str:
source = "ops/service-inventory.yml"
reviewed = inventory.get("last_reviewed", "unknown")
lines = [
"# Ops Hub Service Catalog Now View",
"",
"<!-- generated by ops/render_service_inventory.py; edit ops/service-inventory.yml instead -->",
"",
f"Source: `{source}`",
f"Inventory last reviewed: `{reviewed}`",
"",
"This is the repo-native first view for `CUST-WP-0047`. It exists so an",
"operator can answer what is running where before the full standalone",
"`ops-hub` application is available.",
"",
"## Summary",
"",
summary_table(inventory),
"",
"## Service Catalog",
"",
service_table(inventory),
"",
gaps_section(inventory),
"",
"## Next Evidence Events",
"",
"- `ops-service-observed` for each runtime object confirmed by a probe.",
"- `ops-endpoint-verified` for HTTP, HTTPS, tunnel, or cluster endpoints.",
"- `ops-access-path-checked` for non-secret access path checks.",
"- `ops-backup-verified` where backup and restore evidence exists.",
"- `ops-inventory-drift` when observed state differs from this inventory.",
"",
]
return "\n".join(lines)
def main() -> int:
parser = argparse.ArgumentParser(description=__doc__)
parser.add_argument("--input", type=Path, default=DEFAULT_INPUT)
parser.add_argument("--output", type=Path, default=DEFAULT_OUTPUT)
args = parser.parse_args()
inventory = yaml.safe_load(args.input.read_text(encoding="utf-8"))
rendered = render(inventory)
args.output.parent.mkdir(parents=True, exist_ok=True)
args.output.write_text(rendered, encoding="utf-8")
print(f"rendered {args.output} from {args.input}")
return 0
if __name__ == "__main__":
raise SystemExit(main())

342
ops/service-inventory.yml Normal file
View File

@@ -0,0 +1,342 @@
version: 1
last_reviewed: "2026-06-05"
policy:
non_secret_inventory: true
secrets_rule: "Do not store credentials, tokens, private addresses that are not already operationally documented, or command output containing secrets."
sources:
- path: "/home/worsch/helix-forge/wiki/OpsHubInventory.md"
summary: "Initial ops-hub inventory draft with environments, hosts, services, endpoints, gaps, and first widget ids."
- path: "/home/worsch/the-custodian/workplans/CUST-WP-0025-fos-hub-bootstrap.md"
summary: "Long-term ops-hub scaffold, models, health probes, access paths, and now-view work."
- path: "/home/worsch/the-custodian/workplans/CUST-WP-0046-hourly-recently-on-scope-activity-core.md"
summary: "Evidence that activity-core runs on Railiance01 and can reach State Hub through the in-cluster bridge."
- path: "/home/worsch/the-custodian/infra/build-machines/README.md"
summary: "Local workstation and build VM tunnel pattern."
environments:
- id: local
name: "Local Workstation"
role: "Workstation development and local operations"
lifecycle_state: observed
- id: coulombcore
name: "CoulombCore"
role: "Transitional production-like runtime"
lifecycle_state: observed
- id: railiance01
name: "Railiance01"
role: "First ThreePhoenix foundation node"
lifecycle_state: observed
- id: threephoenix-prod
name: "ThreePhoenix Production"
role: "Target governed production topology"
lifecycle_state: planned
hosts:
- id: local-workstation
environment: local
address: "local/private"
role: "State Hub and operator workstation runtime"
evidence:
- type: document
source: "/home/worsch/the-custodian/infra/build-machines/README.md"
- id: coulombcore
environment: coulombcore
address: "92.205.130.254"
role: "Current live production-like server"
evidence:
- type: document
source: "/home/worsch/helix-forge/wiki/OpsHubInventory.md"
- id: railiance01
environment: railiance01
address: "92.205.62.239"
role: "First ThreePhoenix foundation node"
evidence:
- type: document
source: "/home/worsch/helix-forge/wiki/OpsHubInventory.md"
clusters:
- id: coulombcore-k3s
environment: coulombcore
host: coulombcore
kind: k3s
lifecycle_state: observed
notes: "Current operational Kubernetes runtime for Gitea and related services."
- id: railiance01-k3s
environment: railiance01
host: railiance01
kind: k3s
lifecycle_state: observed
notes: "Runtime substrate for activity-core production service evidence."
- id: threephoenix-k3s
environment: threephoenix-prod
kind: k3s
lifecycle_state: planned
notes: "Target governed production cluster shape."
services:
- id: gitea
name: "Gitea"
kind: application
lifecycle_state: observed
health_status: unknown
environment: coulombcore
owner_repos:
- railiance-apps
desired_state_sources:
- "/home/worsch/railiance-forge/docs/gitea-package-registry.md"
- "/home/worsch/the-custodian/ops/runbooks/gitea-coulombcore.md"
runtime:
type: k3s
cluster: coulombcore-k3s
namespace: default
workload_refs:
- "helm:gitea"
- "nodePort:32166"
endpoints:
- id: gitea-oci-registry
type: https
url: "https://gitea.coulomb.social/v2/"
expected_status: 401
expected_signal: "OCI registry auth challenge"
widget_ref: "ops:endpoint:gitea-registry"
backing_stores:
- "database:gitea-db"
- "pvc:default/gitea-shared-storage"
access_paths:
- type: k8s
target: "coulombcore-k3s/default"
status: unknown
evidence:
- type: document
observed_at: "2026-05-16"
source: "/home/worsch/helix-forge/wiki/OpsHubInventory.md"
summary: "Inventory draft records Helm release gitea, namespace default, app version 1.25.4, NodePort 32166, and registry auth challenge."
gaps:
- "Package token and push/pull verification need current evidence."
- "Backup and restore evidence for database and shared storage not recorded in ops inventory."
- id: gitea-database
name: "Gitea Database"
kind: datastore
lifecycle_state: observed
health_status: unknown
environment: coulombcore
owner_repos:
- railiance-platform
runtime:
type: k3s
cluster: coulombcore-k3s
namespace: databases
workload_refs:
- "database:gitea-db"
endpoints: []
backing_stores: []
access_paths:
- type: k8s
target: "coulombcore-k3s/databases"
status: unknown
evidence:
- type: document
observed_at: "2026-05-16"
source: "/home/worsch/helix-forge/wiki/OpsHubInventory.md"
gaps:
- "Backup and restore evidence not recorded in ops inventory."
- id: gitea-shared-storage
name: "Gitea Shared Storage"
kind: storage
lifecycle_state: observed
health_status: unknown
environment: coulombcore
owner_repos:
- railiance-platform
- railiance-apps
runtime:
type: k3s
cluster: coulombcore-k3s
namespace: default
workload_refs:
- "pvc:default/gitea-shared-storage"
endpoints: []
backing_stores: []
access_paths:
- type: k8s
target: "coulombcore-k3s/default/pvc/gitea-shared-storage"
status: unknown
evidence:
- type: document
observed_at: "2026-05-16"
source: "/home/worsch/helix-forge/wiki/OpsHubInventory.md"
gaps:
- "Package blob backup and restore evidence not confirmed."
- id: state-hub
name: "State Hub"
kind: coordination-service
lifecycle_state: observed
health_status: observed_ok
environment: local
owner_repos:
- state-hub
- the-custodian
desired_state_sources:
- "/home/worsch/state-hub"
- "/home/worsch/the-custodian/state-hub/README.md"
runtime:
type: local-process
host: local-workstation
ports:
- 8000
endpoints:
- id: state-hub-local-api
type: http
url: "http://127.0.0.1:8000/state/health"
expected_status: 200
expected_signal: "health response"
backing_stores:
- "postgresql:state-hub"
access_paths:
- type: http
target: "http://127.0.0.1:8000"
status: observed_ok
evidence:
- type: session-probe
observed_at: "2026-06-05"
source: "Codex session curl to local State Hub"
summary: "State Hub accepted inbox, task, and progress API calls."
gaps:
- "Future cluster deployment readiness still needs ops evidence."
- id: inter-hub
name: "Inter-Hub"
kind: governance-service
lifecycle_state: observed
health_status: unknown
environment: threephoenix-prod
owner_repos:
- inter-hub
runtime:
type: external
public_endpoint: "https://hub.coulomb.social"
endpoints:
- id: inter-hub-openapi
type: https
url: "https://hub.coulomb.social/api/v2/openapi.json"
expected_status: 200
expected_signal: "OpenAPI document"
- id: inter-hub-ui
type: https
url: "https://hub.coulomb.social/Hubs"
expected_status: 302
expected_signal: "login redirect when unauthenticated"
backing_stores: []
access_paths:
- type: https
target: "https://hub.coulomb.social"
status: unknown
evidence:
- type: document
observed_at: "2026-05-16"
source: "/home/worsch/helix-forge/wiki/OpsHubInventory.md"
gaps:
- "ops-hub bootstrap requires authenticated UI flow or deployment-side migration."
- id: activity-core
name: "activity-core"
kind: automation-service
lifecycle_state: observed
health_status: observed_ok
environment: railiance01
owner_repos:
- activity-core
- the-custodian
desired_state_sources:
- "/home/worsch/activity-core/k8s/railiance"
- "/home/worsch/the-custodian/activity-definitions"
runtime:
type: k3s
cluster: railiance01-k3s
namespace: activity-core
workload_refs:
- "deployment:activity-core-api"
- "deployment:activity-core-worker"
- "temporal:schedules"
endpoints:
- id: activity-core-api
type: cluster-http
url: "activity-core API health endpoint"
expected_status: 200
expected_signal: "healthy DB and Temporal status"
backing_stores:
- "postgresql:activity-core"
- "temporal:activity-core"
- "nats:railiance01"
access_paths:
- type: k8s
target: "railiance01-k3s/activity-core"
status: observed_ok
evidence:
- type: workplan-note
observed_at: "2026-05-23"
source: "/home/worsch/the-custodian/workplans/CUST-WP-0046-hourly-recently-on-scope-activity-core.md"
summary: "API health, worker rollout, Temporal CLI schedule listing, and State Hub bridge were verified."
gaps:
- "Add explicit ops inventory probes and evidence events."
- id: ops-bridge
name: "Ops Bridge"
kind: connectivity-service
lifecycle_state: observed
health_status: unknown
environment: local
owner_repos:
- ops-bridge
runtime:
type: bridge
host: local-workstation
endpoints: []
backing_stores: []
access_paths:
- type: ssh-tunnel
target: "connected remote servers"
status: unknown
evidence:
- type: document
observed_at: "2026-05-16"
source: "/home/worsch/helix-forge/wiki/OpsHubInventory.md"
summary: "Bridge is useful for connected-server visibility but is not itself the service catalog."
gaps:
- "Emit reachability evidence into ops-hub instead of relying on bridge state as inventory."
- id: haskell-build-agent
name: "Haskell Build Agent"
kind: build-service
lifecycle_state: observed
health_status: unknown
environment: local
owner_repos:
- the-custodian
desired_state_sources:
- "/home/worsch/the-custodian/infra/build-machines/haskell"
runtime:
type: systemd
host: haskell-build-vm
tunnel:
reverse_ssh: "12222:localhost:22"
forward_state_hub: "18000:localhost:8000"
endpoints:
- id: haskell-build-agent-state-hub-forward
type: tunnel
url: "http://127.0.0.1:18000"
expected_signal: "VM can reach State Hub through SSH forward"
backing_stores: []
access_paths:
- type: ssh
target: "local workstation reverse tunnel port 12222"
status: unknown
evidence:
- type: document
source: "/home/worsch/the-custodian/infra/build-machines/README.md"
summary: "Build agent is a systemd service and registers with State Hub on boot."
gaps:
- "Current tunnel and capability registration need live evidence in ops-hub."

12
registry/README.md Normal file
View File

@@ -0,0 +1,12 @@
# Capability Registry
Markdown-first capability index for federation and reuse planning.
## Authoring
1. Copy a capability entry template (see reuse-surface `templates/capability-entry.template.md`).
2. Add the row to `indexes/capabilities.yaml`.
3. Run `reuse-surface validate` from a checkout with the CLI installed.
4. Merge to `main` and verify publish with `reuse-surface establish --publish-check`.
Federation contract: reuse-surface `docs/RegistryFederation.md`.

View File

@@ -0,0 +1,4 @@
version: 1
updated: '2026-06-16'
domain: helix_forge
capabilities: []

View File

@@ -9,7 +9,7 @@ about it with an LLM, and executes bounded write operations.
agent.py CLI entry point + OODA orchestrator
context.py Observe: fetch state-hub data + build LLM context prompt
actions.py Act: execute sanctioned write operations
prompts/ System prompt templates (future)
prompts/ System prompt templates and recurring review prompts
policies/ Agent-level policies (future)
tool_adapters/ Additional MCP/API tool adapters (future)
tests/ Unit tests (offline, no live API required)
@@ -90,6 +90,12 @@ The agent prints a trace to stdout:
The LLM's reasoning trace is saved to `memory/working/agent-session-{ts}-{scope}.md`.
Recurring review prompts:
- `prompts/daily_statehub_wsgi_triage.md` - daily State Hub WSJF triage used by
the `daily-state-hub-wsjf-triage` automation and the activity-core handoff
definition in `../activity-definitions/`.
## Tests
```bash

View File

@@ -0,0 +1,257 @@
---
id: daily-statehub-wsjf-triage
type: runtime-prompt
owner: custodian
status: active
created: "2026-05-17"
updated: "2026-06-04"
related_workplan: CUST-WP-0044
---
# Daily State Hub WSJF Triage Prompt
## Purpose
Run a daily Custodian review of State Hub state and produce a short,
reviewable recommendation report. The review is a focus surface, not an
execution loop: it recommends what to work next, what to revisit, what to park,
and what needs human or cross-agent attention.
Do not create a new scheduler for this loop. The current runner is activity-core
using the ActivityDefinition in
`/home/worsch/the-custodian/activity-definitions/daily-statehub-wsjf-triage.md`.
Do not re-enable a Codex app fallback unless activity-core is deliberately
disabled and that operator decision is recorded, so there is exactly one daily
runner.
## Operating Rules
- Read first, then decide. Do not edit workplans, canon, or task status during
a daily review unless a later human request explicitly asks for an apply step.
- Prefer existing State Hub read surfaces over ad hoc scans:
`/state/summary`, `/state/next_steps`, `/workstreams/workplan-index`,
`/messages/`, and `.custodian-brief.md`.
- Use local workplan files only to enrich the State Hub snapshot with task
wording, stale frontmatter, and missing file-backed state.
- Treat scores as prioritization aids, not truth. Every WSJF row needs a
confidence label.
- Include explicit WSJF component scores in executable JSON output so the
working-memory note remains auditable without re-running the model.
- Items involving money, legal status, secrets, security posture, external
publication, or external reputation must be reported as `needs-human` unless
a current explicit approval already exists.
## Inputs
Collect these inputs in order. If a live input fails, continue from the last
available fallback and say so in the report.
1. `/home/worsch/the-custodian/.custodian-brief.md`
2. `GET http://127.0.0.1:8000/state/summary`
3. `GET http://127.0.0.1:8000/messages/?to_agent=hub&unread_only=true`
4. `GET http://127.0.0.1:8000/state/next_steps`
5. `GET http://127.0.0.1:8000/workstreams/workplan-index`
6. Local workplan files for candidate workstreams that need closer inspection
7. Read-only `git status --short` for repos named in top recommendations
Optional enrichment:
- `GET /tasks/?workstream_id=<id>` for a top-ranked workstream
- `GET /progress/?workstream_id=<id>&limit=5` for staleness confidence
- State Hub domain summaries through MCP when available
## Candidate Set
Build the candidate list from:
- all open workstreams in `state_summary.open_workstreams`
- all derived `state_summary.next_steps`
- blocked tasks and blocking decisions from the summary
- high-priority file-backed workplans surfaced by `workplan-index`
- workstreams with suspicious structure, such as zero parsed tasks or stale
active plans
Keep the scored table compact. Score at most 15 candidates internally and
report the top 10.
## Loose-End Detection
Flag a candidate when one or more signals apply:
| Signal | Default threshold | Recommended action |
|--------|-------------------|--------------------|
| Active with no recent progress | no progress in 14 days, or 7 days for high-priority items | `revisit` |
| Large unstarted plan | `tasks_total >= 6`, `tasks_done == 0`, `tasks_in_progress == 0` | `split` or `revisit` |
| Near complete | `tasks_done / tasks_total >= 0.75` and `tasks_todo <= 3` | `close-out` or `work-next` |
| Zero parsed tasks | active or blocked workstream with `tasks_total == 0` | `needs-consistency-sync` |
| Blocked but dependency appears closed | blocked workstream with cleared dependency or empty blocked reason | `revisit` |
| Open decision blocks execution | blocking decision connected to workstream/task | `needs-human` |
| File-backed mismatch | missing index entry, stale `updated`, `needs_review`, or status disagreement | `needs-consistency-sync` |
| Too broad for one session | many unrelated task clusters in one workplan | `split` |
| Safety-sensitive | security, identity, secrets, legal, external reputation, money | `needs-human` |
Use these as prompts for judgment, not as automatic status changes.
## WSJF Procedure
Score every reported candidate with:
```text
WSJF = (strategic_value + time_criticality + risk_reduction + opportunity_enablement) / job_size
```
Use integer scores from 1 to 5.
### Strategic Value
Score higher when the work aligns with:
- current Custodian/State Hub operating reliability
- dependency-chain foundations: Railiance, identity, secrets, backup, HA
- explicit `planning_priority: high` or low `planning_order`
- active repo/domain goals
- closing a workstream that is already consuming coordination attention
### Time Criticality
Score higher when waiting increases:
- operational risk or data-loss risk
- number of blocked downstream plans
- context decay for partially completed work
- queue pressure from accumulating open tasks
### Risk Reduction
Score higher when the work reduces:
- security, identity, backup, restore, deployment, or consistency risk
- false dashboard state or stale State Hub records
- manual recovery burden
- ambiguity around human approvals
### Opportunity Enablement
Score higher when the work unlocks:
- multiple downstream workstreams
- agent autonomy or fewer repeated setup steps
- reliable cross-repo operation
- future daily triage quality
### Job Size
Score lower numbers for easier jobs:
| Score | Meaning |
|-------|---------|
| 1 | tiny, clear, can likely close in one focused session |
| 2 | small, local, low uncertainty |
| 3 | moderate, several files or one external dependency |
| 4 | large, multi-repo, needs coordination or testing |
| 5 | broad/uncertain, likely should be split before execution |
### Confidence
Use:
- `high` when State Hub summary, workplan file, and recent progress agree
- `medium` when the score relies on summary data plus one corroborating source
- `low` when the workplan file is missing, stale, blocked by dirty repo state,
or based mostly on inference
## Recommendation Actions
| Action | Meaning | Agent may proceed when | Human gate required when |
|--------|---------|------------------------|--------------------------|
| `work-next` | Best next executable task | scope is local, reversible, and inside an existing approved workplan | it touches money, legal, secrets, public reputation, or external commitments |
| `revisit` | Re-read and refresh before execution | the plan is stale, ambiguous, blocked, or context has moved | revisiting changes purpose, scope, owner, or approval posture |
| `split` | Break an oversized workplan into smaller plans | split is file-backed and preserves provenance | split would drop scope, change priorities, or alter commitments |
| `park` | Move out of active focus | plan is clearly not current and parking is proposed only | actually changing status to backlog/archive needs review |
| `close-out` | Finish closure review and mark done when appropriate | remaining tasks are truly done/cancelled/carry-forwarded | tasks are ambiguous, cancelled for policy reasons, or external effects are involved |
| `needs-human` | Human decision or approval needed | never auto-resolve; report the ask crisply | always |
| `needs-cross-agent` | Another repo/agent is the right owner | send/prepare a coordination message or task only when requested | when ownership or priority is uncertain |
| `needs-consistency-sync` | File/DB/index state should be reconciled | running read/check/fix consistency is already allowed by repo protocol | sync would overwrite work or local repo is behind remote |
## Report Template
Write the daily note in this shape:
```markdown
---
id: daily-statehub-triage-YYYY-MM-DD
type: working-memory
created: "YYYY-MM-DD"
related_workplan: CUST-WP-0044
source: daily-state-hub-wsjf-triage
---
# Daily State Hub WSJF Triage - YYYY-MM-DD
## Snapshot
- Generated at: <timestamp>
- Workstreams: <active> active, <blocked> blocked, <finished> finished
- Tasks: <todo> todo, <in_progress> in progress, <blocked> blocked
- Decisions: <open> open, <escalated> escalated
- Inbox: <count> unread hub messages
- Input health: <summary of API/MCP/file fallbacks>
## Top Recommendations
| Rank | Action | Candidate | WSJF | Confidence | Why now |
|------|--------|-----------|------|------------|---------|
| 1 | work-next | <workstream/task> | 0.0 | high | <short reason> |
## Loose Ends
| Action | Candidate | Signal | Suggested follow-up |
|--------|-----------|--------|---------------------|
| revisit | <workplan> | <signal> | <next check> |
## Human Or Cross-Agent Attention
- `needs-human`: <decision/task> - <specific ask>
- `needs-cross-agent`: <repo/agent> - <specific handoff>
## Next Custodian Session
1. <first recommended action>
2. <second recommended action>
3. <cleanup/sync action if relevant>
## Progress Event Summary
<One or two sentences suitable for POST /progress/.>
```
## Progress Event
When the State Hub API is reachable, append one progress event for the review:
- `topic_id`: Custodian topic id when known
- `workstream_id`: `99993845-be6a-401d-be98-f8107014abed`
- `event_type`: `daily_triage`
- `summary`: one sentence summarizing the top recommendation and loose-end count
- `detail`: include top three recommendations, input health, and any human gates
Do not mark tasks done from the daily run itself. Task status changes belong to
the implementation session that applies a recommendation.
## Executable JSON Shape
When the activity-core runner asks for JSON only, return the same content in
the schema at `/home/worsch/the-custodian/schemas/daily-triage-report.json`.
Each recommendation must include:
- `rank`
- `candidate`
- `action`
- `why`
- `confidence`
- `wsjf.score`
- `wsjf.strategic_value`
- `wsjf.time_criticality`
- `wsjf.risk_reduction`
- `wsjf.opportunity_enablement`
- `wsjf.job_size`

View File

@@ -0,0 +1,92 @@
{
"type": "object",
"required": ["summary", "recommendations"],
"additionalProperties": false,
"properties": {
"summary": {
"type": "string"
},
"recommendations": {
"type": "array",
"minItems": 1,
"maxItems": 10,
"items": {
"type": "object",
"required": ["rank", "candidate", "action", "why", "confidence", "wsjf"],
"additionalProperties": false,
"properties": {
"rank": {
"type": "integer",
"minimum": 1,
"maximum": 10
},
"candidate": {
"type": "string"
},
"action": {
"type": "string",
"enum": [
"work-next",
"revisit",
"split",
"park",
"close-out",
"needs-human",
"needs-cross-agent",
"needs-consistency-sync"
]
},
"why": {
"type": "string"
},
"confidence": {
"type": "string",
"enum": ["high", "medium", "low"]
},
"wsjf": {
"type": "object",
"required": [
"score",
"strategic_value",
"time_criticality",
"risk_reduction",
"opportunity_enablement",
"job_size"
],
"additionalProperties": false,
"properties": {
"score": {
"type": "number"
},
"strategic_value": {
"type": "integer",
"minimum": 1,
"maximum": 5
},
"time_criticality": {
"type": "integer",
"minimum": 1,
"maximum": 5
},
"risk_reduction": {
"type": "integer",
"minimum": 1,
"maximum": 5
},
"opportunity_enablement": {
"type": "integer",
"minimum": 1,
"maximum": 5
},
"job_size": {
"type": "integer",
"minimum": 1,
"maximum": 5
}
}
}
}
}
}
}
}

View File

@@ -0,0 +1,174 @@
{
"$schema": "https://json-schema.org/draft/2020-12/schema",
"$id": "https://custodian.local/schemas/ops-service-inventory.schema.json",
"title": "Ops Hub Service Inventory",
"type": "object",
"required": ["version", "last_reviewed", "environments", "hosts", "clusters", "services"],
"properties": {
"version": { "type": "integer", "minimum": 1 },
"last_reviewed": { "type": "string", "format": "date" },
"policy": {
"type": "object",
"additionalProperties": true
},
"sources": {
"type": "array",
"items": { "$ref": "#/$defs/source" }
},
"environments": {
"type": "array",
"items": { "$ref": "#/$defs/environment" }
},
"hosts": {
"type": "array",
"items": { "$ref": "#/$defs/host" }
},
"clusters": {
"type": "array",
"items": { "$ref": "#/$defs/cluster" }
},
"services": {
"type": "array",
"items": { "$ref": "#/$defs/service" }
}
},
"$defs": {
"source": {
"type": "object",
"required": ["path", "summary"],
"properties": {
"path": { "type": "string" },
"summary": { "type": "string" }
},
"additionalProperties": false
},
"environment": {
"type": "object",
"required": ["id", "name", "role", "lifecycle_state"],
"properties": {
"id": { "$ref": "#/$defs/id" },
"name": { "type": "string" },
"role": { "type": "string" },
"lifecycle_state": { "$ref": "#/$defs/lifecycle_state" }
},
"additionalProperties": false
},
"host": {
"type": "object",
"required": ["id", "environment", "role"],
"properties": {
"id": { "$ref": "#/$defs/id" },
"environment": { "$ref": "#/$defs/id" },
"address": { "type": "string" },
"role": { "type": "string" },
"evidence": {
"type": "array",
"items": { "$ref": "#/$defs/evidence" }
}
},
"additionalProperties": false
},
"cluster": {
"type": "object",
"required": ["id", "environment", "kind", "lifecycle_state"],
"properties": {
"id": { "$ref": "#/$defs/id" },
"environment": { "$ref": "#/$defs/id" },
"host": { "$ref": "#/$defs/id" },
"kind": { "type": "string" },
"lifecycle_state": { "$ref": "#/$defs/lifecycle_state" },
"notes": { "type": "string" }
},
"additionalProperties": false
},
"service": {
"type": "object",
"required": ["id", "name", "kind", "lifecycle_state", "health_status", "environment", "owner_repos", "runtime", "endpoints", "backing_stores", "access_paths", "evidence", "gaps"],
"properties": {
"id": { "$ref": "#/$defs/id" },
"name": { "type": "string" },
"kind": { "type": "string" },
"lifecycle_state": { "$ref": "#/$defs/lifecycle_state" },
"health_status": {
"enum": ["unknown", "observed_ok", "degraded", "down", "planned"]
},
"environment": { "$ref": "#/$defs/id" },
"owner_repos": {
"type": "array",
"items": { "type": "string" }
},
"desired_state_sources": {
"type": "array",
"items": { "type": "string" }
},
"runtime": {
"type": "object",
"additionalProperties": true
},
"endpoints": {
"type": "array",
"items": { "$ref": "#/$defs/endpoint" }
},
"backing_stores": {
"type": "array",
"items": { "type": "string" }
},
"access_paths": {
"type": "array",
"items": { "$ref": "#/$defs/access_path" }
},
"evidence": {
"type": "array",
"items": { "$ref": "#/$defs/evidence" }
},
"gaps": {
"type": "array",
"items": { "type": "string" }
}
},
"additionalProperties": false
},
"endpoint": {
"type": "object",
"required": ["id", "type"],
"properties": {
"id": { "$ref": "#/$defs/id" },
"type": { "type": "string" },
"url": { "type": "string" },
"expected_status": { "type": "integer" },
"expected_signal": { "type": "string" },
"widget_ref": { "type": "string" }
},
"additionalProperties": false
},
"access_path": {
"type": "object",
"required": ["type", "target", "status"],
"properties": {
"type": { "type": "string" },
"target": { "type": "string" },
"status": { "enum": ["unknown", "observed_ok", "degraded", "down", "planned"] }
},
"additionalProperties": false
},
"evidence": {
"type": "object",
"required": ["type", "source"],
"properties": {
"type": { "type": "string" },
"observed_at": { "type": "string" },
"source": { "type": "string" },
"summary": { "type": "string" }
},
"additionalProperties": false
},
"id": {
"type": "string",
"pattern": "^[a-z0-9][a-z0-9-]*$"
},
"lifecycle_state": {
"enum": ["observed", "planned", "target", "retired"]
}
},
"additionalProperties": false
}

55
scripts/verify-e2e-shim.sh Executable file
View File

@@ -0,0 +1,55 @@
#!/usr/bin/env bash
# Verify e2e shim prerequisites (SAND-WP-0004-T04).
set -euo pipefail
ERR=0
check_cmd() {
if command -v "$1" >/dev/null 2>&1; then
echo "OK $1$(command -v "$1")"
else
echo "FAIL $1 not on PATH" >&2
ERR=1
fi
}
echo "==> CLI prerequisites"
check_cmd validate
check_cmd sandboxer
echo "==> Host env (one required for make e2e)"
if [[ -n "${SANDBOXER_HOST:-}" || -n "${RAILIANCE01_HOST:-}" ]]; then
echo "OK host env: SANDBOXER_HOST=${SANDBOXER_HOST:-} RAILIANCE01_HOST=${RAILIANCE01_HOST:-}"
else
echo "WARN no SANDBOXER_HOST or RAILIANCE01_HOST (set before remote run)" >&2
fi
if [[ -n "${SANDBOXER_COMPOSE_CMD:-}" ]]; then
echo "OK SANDBOXER_COMPOSE_CMD=${SANDBOXER_COMPOSE_CMD}"
else
echo "WARN SANDBOXER_COMPOSE_CMD unset (use podman-compose on CoulombCore)" >&2
fi
REPO="${VERIFY_REPO:-sand-boxer}"
REPO_PATH="${HOME}/${REPO}"
if [[ -f "${REPO_PATH}/e2e/e2e.yml" ]]; then
echo "OK fixture repo: ${REPO_PATH}/e2e/e2e.yml"
else
echo "WARN ${REPO_PATH}/e2e/e2e.yml missing (set VERIFY_REPO)" >&2
fi
echo "==> Optional remote run (VERIFY_E2E_RUN=1)"
if [[ "${VERIFY_E2E_RUN:-}" == "1" ]]; then
test -n "${SANDBOXER_HOST:-${RAILIANCE01_HOST:-}}" || {
echo "FAIL SANDBOXER_HOST required for VERIFY_E2E_RUN" >&2
exit 1
}
cd "$(dirname "$0")/.."
make e2e "REPO=${REPO}" NO_REPORT=1
echo "OK make e2e REPO=${REPO}"
fi
if [[ "$ERR" -ne 0 ]]; then
exit 1
fi
echo "==> PASS prerequisites"

View File

@@ -0,0 +1,53 @@
#!/usr/bin/env bash
# Verify remote-build shim prerequisites (SAND-WP-0012-T04).
set -euo pipefail
ERR=0
check_cmd() {
if command -v "$1" >/dev/null 2>&1; then
echo "OK $1$(command -v "$1")"
else
echo "FAIL $1 not on PATH" >&2
ERR=1
fi
}
echo "==> CLI prerequisites"
check_cmd sandboxer
echo "==> Build-machines Makefile shim"
MAKEFILE="${HOME}/the-custodian/infra/build-machines/Makefile"
if grep -q 'remote-build-sandboxer' "$MAKEFILE" 2>/dev/null; then
echo "OK remote-build-sandboxer target present"
else
echo "FAIL remote-build-sandboxer not in $MAKEFILE" >&2
ERR=1
fi
echo "==> VM tunnel (optional for live run)"
if [[ -n "${SANDBOXER_VM_TUNNEL_PORT:-}" ]]; then
echo "OK SANDBOXER_VM_TUNNEL_PORT=${SANDBOXER_VM_TUNNEL_PORT}"
else
echo "WARN SANDBOXER_VM_TUNNEL_PORT unset (set before live remote-build)" >&2
fi
VM="${VERIFY_VM:-haskell-build}"
if ssh -q -o ConnectTimeout=2 "$VM" "echo ok" 2>/dev/null; then
echo "OK ssh $VM reachable"
else
echo "WARN ssh $VM not reachable (expected when tunnel down)" >&2
fi
echo "==> Optional live run (VERIFY_REMOTE_BUILD_RUN=1)"
if [[ "${VERIFY_REMOTE_BUILD_RUN:-}" == "1" ]]; then
PROJECT="${VERIFY_PROJECT:-${HOME}/sand-boxer}"
cd "${HOME}/the-custodian/infra/build-machines"
make remote-build "PROJECT=${PROJECT}" "VM=${VM}"
echo "OK make remote-build PROJECT=${PROJECT}"
fi
if [[ "$ERR" -ne 0 ]]; then
exit 1
fi
echo "==> PASS prerequisites"

View File

@@ -0,0 +1,16 @@
# Repo Classification Standard — moved
This standard has been promoted into custodian canon. The authoritative copy now
lives at:
canon/standards/repo-classification-standard_v1.0.md
`id: canon-repo-classification` · `version: 1.0` · `status: active`
It defines the four-concern repo classification model (category · domain ·
capability_tags · business_stake, plus optional business_mechanics) and the
per-repo `.repo-classification.yaml` metadata file.
The rollout — classifying every repo and redesigning State Hub registration
around this standard — is tracked in
`workplans/CUST-WP-0050-repo-classification-registration-redesign.md`.

View File

@@ -1,17 +0,0 @@
# Copy to .env and fill in values before running
POSTGRES_DB=custodian
POSTGRES_USER=custodian
POSTGRES_PASSWORD=changeme
DATABASE_URL=postgresql+asyncpg://custodian:changeme@127.0.0.1:5432/custodian
# pgAdmin (optional, only used with --profile tools)
PGADMIN_EMAIL=admin@local.dev
PGADMIN_PASSWORD=admin
# API
API_BASE=http://127.0.0.1:8000
# Gitea (for gitea_inventory.py)
GITEA_URL=http://92.205.130.254:32166
GITEA_TOKEN=

View File

@@ -1,270 +0,0 @@
.PHONY: install install-cli db db-tools migrate seed api dashboard check test clean register-project validate-adr add-domain rename-domain add-repo list-repos register-path cleanup-stale tunnels-up tunnels-status tunnels-check bridges install-hooks install-hooks-all gitea-inventory
COMPOSE = docker compose -f infra/docker-compose.yml --env-file .env
install:
uv sync
## Symlink the custodian CLI into ~/.local/bin so it's on PATH system-wide
install-cli: install
mkdir -p ~/.local/bin
ln -sf "$(shell pwd)/.venv/bin/custodian" ~/.local/bin/custodian
@echo "Installed: custodian → $$(readlink -f ~/.local/bin/custodian)"
@echo "Make sure ~/.local/bin is on your PATH:"
@echo " echo 'export PATH=\"\$$HOME/.local/bin:\$$PATH\"' >> ~/.bashrc && source ~/.bashrc"
db:
$(COMPOSE) up -d postgres
db-tools:
$(COMPOSE) --profile tools up -d
migrate:
uv run alembic upgrade head
seed:
uv run python scripts/seed.py
## Start (or restart) the MCP SSE server on :8001 — primary transport for Claude Code.
## Remote clients (e.g. COULOMBCORE) connect via the ops-bridge tunnel (port 18001).
## Registration: claude mcp add-json -s user state-hub '{"type":"sse","url":"http://127.0.0.1:8001/sse"}'
mcp-http:
@fuser -k 8001/tcp 2>/dev/null && echo "Stopped running MCP server" || true
MCP_TRANSPORT=sse MCP_PORT=8001 uv run python mcp_server/server.py
dashboard:
@fuser -k 3000/tcp 2>/dev/null && echo "Stopped running dashboard" || true
cd dashboard && npm run dev
check:
curl -sf http://127.0.0.1:8000/state/health | python3 -m json.tool
test:
TEST_DATABASE_URL=postgresql+asyncpg://custodian:changeme@127.0.0.1:5432/custodian_test \
uv run pytest -x -q
## ops-bridge managed tunnels
## Requires ops-bridge: bridge is at /home/worsch/.local/bin/bridge
tunnels-up:
bridge up
tunnels-status:
bridge status
## End-to-end check: verifies SSH process alive + remote port listening on COULOMBCORE.
## Exits non-zero if any tunnel is not fully operational.
tunnels-check:
bridge check
## Ensure all ops-bridge tunnels are up and healthy.
## Brings up any stopped/stale tunnels, shows final status, exits non-zero if anything is still down.
bridges:
@echo "==> Bringing up all tunnels..."
bridge up
@echo ""
@echo "==> Tunnel status:"
bridge status
@echo ""
@echo "==> Checking tunnel health..."
bridge check
## Start (or restart) the full backend — db + migrate + uvicorn.
## Stops uvicorn on :8000 if already running, then starts fresh.
api: db
@echo "Waiting for postgres..."; \
for i in 1 2 3 4 5 6 7 8 9 10; do \
nc -z 127.0.0.1 5432 2>/dev/null && break; \
sleep 1; \
done
$(MAKE) migrate
@fuser -k 8000/tcp 2>/dev/null && echo "Stopped running API" || true
uv run uvicorn api.main:app --reload --host 127.0.0.1 --port 8000
## Register a project: make register-project DOMAIN=railiance PROJECT_PATH=/home/worsch/railiance
register-project:
@test -n "$(DOMAIN)" || (echo "ERROR: DOMAIN is required. Usage: make register-project DOMAIN=<domain> PROJECT_PATH=<path>"; exit 1)
@test -n "$(PROJECT_PATH)" || (echo "ERROR: PROJECT_PATH is required."; exit 1)
scripts/register_project.sh "$(DOMAIN)" "$(PROJECT_PATH)"
## Add a second repo to an existing domain: make add-repo DOMAIN=railiance REPO_PATH=/home/worsch/railiance-infra
add-repo:
@test -n "$(DOMAIN)" || (echo "ERROR: DOMAIN is required."; exit 1)
@test -n "$(REPO_PATH)" || (echo "ERROR: REPO_PATH is required."; exit 1)
scripts/register_project.sh "$(DOMAIN)" "$(REPO_PATH)" --additional
## Create a new domain: make add-domain DOMAIN=my_domain NAME="My Domain"
add-domain:
@test -n "$(DOMAIN)" || (echo "ERROR: DOMAIN is required (slug)."; exit 1)
@test -n "$(NAME)" || (echo "ERROR: NAME is required (display name)."; exit 1)
curl -sf -X POST http://127.0.0.1:8000/domains/ \
-H "Content-Type: application/json" \
-d "{\"slug\": \"$(DOMAIN)\", \"name\": \"$(NAME)\"}" | python3 -m json.tool
## Rename a domain: make rename-domain DOMAIN=old_slug NEW_SLUG=new_slug NEW_NAME="New Name"
rename-domain:
@test -n "$(DOMAIN)" || (echo "ERROR: DOMAIN (old slug) is required."; exit 1)
@test -n "$(NEW_SLUG)" || (echo "ERROR: NEW_SLUG is required."; exit 1)
@test -n "$(NEW_NAME)" || (echo "ERROR: NEW_NAME is required."; exit 1)
curl -sf -X PATCH http://127.0.0.1:8000/domains/$(DOMAIN)/rename \
-H "Content-Type: application/json" \
-d "{\"new_slug\": \"$(NEW_SLUG)\", \"new_name\": \"$(NEW_NAME)\"}" | python3 -m json.tool
## Register this machine's local path for a repo: make register-path REPO=marki-docx PATH=/home/tegwick/marki-docx
register-path:
@test -n "$(REPO)" || (echo "ERROR: REPO is required. Usage: make register-path REPO=<slug> PATH=<path>"; exit 1)
@test -n "$(PATH)" || (echo "ERROR: PATH is required. Usage: make register-path REPO=<slug> PATH=<path>"; exit 1)
curl -sf -X POST "http://127.0.0.1:8000/repos/$(REPO)/paths/" \
-H "Content-Type: application/json" \
-d "{\"host\": \"$$(hostname)\", \"path\": \"$(PATH)\"}" | python3 -m json.tool
## List repos for a domain: make list-repos DOMAIN=railiance
list-repos:
@test -n "$(DOMAIN)" || (echo "ERROR: DOMAIN is required."; exit 1)
curl -sf "http://127.0.0.1:8000/repos/?domain=$(DOMAIN)" | python3 -m json.tool
## Ingest SBOM data for a repo (all mechanisms: lockfiles + ansible + sbom-tools.yaml).
## Auto-detect all sources: make ingest-sbom REPO=the-custodian REPO_PATH=/home/worsch/the-custodian
## Single lockfile (explicit): make ingest-sbom REPO=the-custodian LOCKFILE=/path/to/uv.lock
## Dry-run (no submit): make ingest-sbom REPO=the-custodian REPO_PATH=... DRY_RUN=1
## Tip: run capture-tools first for repos with system-level tool dependencies.
ingest-sbom:
@test -n "$(REPO)" || (echo "ERROR: REPO is required."; exit 1)
uv run python scripts/ingest_sbom.py --repo "$(REPO)" \
$(if $(LOCKFILE),--lockfile "$(LOCKFILE)") \
$(if $(REPO_PATH),--repo-path "$(REPO_PATH)") \
$(if $(DRY_RUN),--dry-run)
## Ingest capability declarations from SCOPE.md into the catalog.
## Usage: make ingest-capabilities REPO=the-custodian [REPO_PATH=/home/worsch/the-custodian]
## Or: make ingest-capabilities-all
## Add DRY_RUN=1 to preview without writing.
ingest-capabilities:
@test -n "$(REPO)" || (echo "ERROR: REPO is required."; exit 1)
uv run python scripts/ingest_capabilities.py --repo "$(REPO)" \
$(if $(REPO_PATH),--repo-path "$(REPO_PATH)") \
$(if $(DRY_RUN),--dry-run)
ingest-capabilities-all:
uv run python scripts/ingest_capabilities.py --all \
$(if $(DRY_RUN),--dry-run)
## Check Repository Definition of Integrated (DoI) criteria for a repo.
## Usage: make check-doi REPO=llm-connect
## Or: make check-doi-all
## Add JSON=1 for machine-readable output.
check-doi:
@test -n "$(REPO)" || (echo "ERROR: REPO is required."; exit 1)
uv run python scripts/check_doi.py --repo "$(REPO)" $(if $(JSON),--json)
check-doi-all:
uv run python scripts/check_doi.py --all $(if $(JSON),--json)
## Ingest tpsc.yaml service declarations from a repo into the TPSC catalog.
## Usage: make ingest-tpsc REPO=llm-connect
## Or: make ingest-tpsc-all
## Add DRY_RUN=1 to preview without writing.
ingest-tpsc:
@test -n "$(REPO)" || (echo "ERROR: REPO is required."; exit 1)
uv run python scripts/ingest_tpsc.py --repo "$(REPO)" \
$(if $(DRY_RUN),--dry-run)
ingest-tpsc-all:
uv run python scripts/ingest_tpsc.py --all \
$(if $(DRY_RUN),--dry-run)
## Run SBOM capture agent for a repo — generates/updates sbom-tools.yaml.
## Usage: make capture-tools REPO=railiance-infra [REPO_PATH=/home/worsch/railiance-infra]
## Add DRY_RUN=1 to preview without writing.
capture-tools:
@test -n "$(REPO)" || (echo "ERROR: REPO is required."; exit 1)
uv run python scripts/capture_sbom_tools.py --repo "$(REPO)" \
$(if $(REPO_PATH),--repo-path "$(REPO_PATH)") \
$(if $(DRY_RUN),--dry-run)
## Check a repo for ADR-001 compliance: make validate-adr REPO=/path/to/repo [DOMAIN=custodian]
validate-adr:
@test -n "$(REPO)" || (echo "ERROR: REPO is required. Usage: make validate-adr REPO=<path> [DOMAIN=<slug>]"; exit 1)
uv run python scripts/validate_repo_adr.py "$(REPO)" $(if $(DOMAIN),--domain "$(DOMAIN)",)
## Check a single repo for ADR-001 consistency: make check-consistency REPO=the-custodian [REPO_PATH=/override]
## Exit 0 = clean, exit 2 = warnings only (treated as success), exit 1 = failures
check-consistency:
@test -n "$(REPO)" || (echo "ERROR: REPO is required. Usage: make check-consistency REPO=<slug>"; exit 1)
uv run python scripts/consistency_check.py --repo "$(REPO)" \
$(if $(API_BASE),--api-base "$(API_BASE)",) \
$(if $(REPO_PATH),--repo-path "$(REPO_PATH)",); \
e=$$?; [ $$e -eq 2 ] && exit 0 || exit $$e
## Check and auto-fix a single repo: make fix-consistency REPO=the-custodian [REPO_PATH=/override]
## Exit 0 = clean, exit 2 = warnings only (treated as success), exit 1 = failures
fix-consistency:
@test -n "$(REPO)" || (echo "ERROR: REPO is required. Usage: make fix-consistency REPO=<slug>"; exit 1)
uv run python scripts/consistency_check.py --repo "$(REPO)" --fix \
$(if $(API_BASE),--api-base "$(API_BASE)",) \
$(if $(REPO_PATH),--repo-path "$(REPO_PATH)",); \
e=$$?; [ $$e -eq 2 ] && exit 0 || exit $$e
## Pull then fix: single repo or all repos if REPO omitted
## make fix-consistency-remote — smart pull+fix all repos that need it
## make fix-consistency-remote REPO=slug — pull+fix one repo
fix-consistency-remote:
uv run python scripts/consistency_check.py \
$(if $(REPO),--repo "$(REPO)",--all) \
--remote \
$(if $(API_BASE),--api-base "$(API_BASE)",) \
$(if $(NO_WRITEBACK),--no-writeback,); \
e=$$?; [ $$e -eq 2 ] && exit 0 || exit $$e
## Infer repo slug from git remote URL and check: make check-consistency-here [REPO_PATH=/path/to/repo]
## Omit REPO_PATH to use the Python script's CWD (i.e. pass an empty --here flag).
check-consistency-here:
uv run python scripts/consistency_check.py \
--here $(if $(REPO_PATH),"$(REPO_PATH)",) \
$(if $(API_BASE),--api-base "$(API_BASE)",); \
e=$$?; [ $$e -eq 2 ] && exit 0 || exit $$e
## Infer repo slug from git remote URL and fix: make fix-consistency-here [REPO_PATH=/path/to/repo]
fix-consistency-here:
uv run python scripts/consistency_check.py \
--here $(if $(REPO_PATH),"$(REPO_PATH)",) \
--fix \
$(if $(API_BASE),--api-base "$(API_BASE)",); \
e=$$?; [ $$e -eq 2 ] && exit 0 || exit $$e
## Check all registered repos for ADR-001 consistency
check-consistency-all:
uv run python scripts/consistency_check.py --all $(if $(API_BASE),--api-base "$(API_BASE)",); \
e=$$?; [ $$e -eq 2 ] && exit 0 || exit $$e
## Check and auto-fix all registered repos
fix-consistency-all:
uv run python scripts/consistency_check.py --all --fix $(if $(API_BASE),--api-base "$(API_BASE)",); \
e=$$?; [ $$e -eq 2 ] && exit 0 || exit $$e
## Cancel open tasks belonging to completed/archived workstreams.
## Safe to run at any time; also suitable for a daily cron job.
## Cron example: 0 3 * * * cd ~/the-custodian/state-hub && make cleanup-stale
cleanup-stale:
uv run python scripts/cleanup_stale_tasks.py
## Install custodian post-commit sync hook into one repo: make install-hooks REPO=marki-docx
install-hooks:
@test -n "$(REPO)" || (echo "ERROR: REPO is required. Usage: make install-hooks REPO=<slug>"; exit 1)
bash scripts/install_hooks.sh --repo "$(REPO)"
## Install custodian post-commit sync hook into all active registered repos
install-hooks-all:
bash scripts/install_hooks.sh --all
## Remove custodian post-commit sync hook from one repo: make remove-hooks REPO=marki-docx
remove-hooks:
@test -n "$(REPO)" || (echo "ERROR: REPO is required. Usage: make remove-hooks REPO=<slug>"; exit 1)
bash scripts/install_hooks.sh --repo "$(REPO)" --remove
## Compare Gitea coulomb org repos against state-hub registered repos
## Requires GITEA_TOKEN in env or .env: make gitea-inventory GITEA_TOKEN=<token>
gitea-inventory:
uv run python scripts/gitea_inventory.py $(if $(JSON),--json)
clean:
$(COMPOSE) down -v

View File

@@ -1,242 +1,27 @@
# State Hub v0.1
# State Hub Has Moved
The operational brain of the Custodian: a local PostgreSQL database, FastAPI REST service, FastMCP SSE server for Claude Code, Observable Framework dashboard, and a `custodian` CLI.
State Hub is no longer owned as an embedded implementation tree in this
repository.
---
Authoritative repo:
## Stack
```text
/home/worsch/state-hub
```
| Layer | Technology | Port |
|-------|-----------|------|
| Database | PostgreSQL 16-alpine (Docker) | `127.0.0.1:5432` |
| API | FastAPI + SQLAlchemy 2.0 async + asyncpg | `127.0.0.1:8000` |
| MCP server | FastMCP SSE | `127.0.0.1:8001` |
| Dashboard | Observable Framework | `127.0.0.1:3000` |
| CLI | `custodian` (Python, uv entry point) | — |
Use that checkout for API, MCP server, dashboard, migrations, tests, scripts,
policies, and State Hub workplans.
All services bind to `127.0.0.1` only — nothing exposed to the network.
---
## Setup
### Prerequisites
- Docker Engine (WSL2: see `CLAUDE.md` in repo root → Docker Setup)
- Python 3.12+ with `uv` (`pip install uv`)
- Node.js 18+ (dashboard only)
### First-time
Common commands:
```bash
cd state-hub
cp .env.example .env # edit POSTGRES_PASSWORD
make install # uv sync
make db # docker compose up postgres
make migrate # alembic upgrade head (creates 5 tables)
make seed # insert 6 canonical topics
make api # db + migrate + uvicorn :8000 (restarts if running)
cd /home/worsch/state-hub
make test
make api
make dashboard
make fix-consistency REPO=the-custodian
```
### Dashboard
```bash
make dashboard # Observable dev server on :3000
```
### CLI
```bash
make install-cli # symlink .venv/bin/custodian → ~/.local/bin
custodian status # API health + summary totals
custodian register-project # register cwd as a Custodian project
```
---
## Makefile Targets
| Target | What it does |
|--------|-------------|
| `make install` | `uv sync` — install Python deps + entry points |
| `make install-cli` | Symlink `custodian` to `~/.local/bin` |
| `make db` | Start postgres container |
| `make db-tools` | Start postgres + pgadmin (http://127.0.0.1:5050) |
| `make migrate` | `alembic upgrade head` |
| `make seed` | Insert 6 canonical topics |
| `make api` | `db` + wait + `migrate` + `uvicorn` (restarts if running) |
| `make dashboard` | Observable dev server (restarts if running) |
| `make check` | `curl /state/health` |
| `make register-project DOMAIN=x PROJECT_PATH=y` | Register a project |
| `make clean` | `docker compose down -v` (destroys DB volume) |
---
## Database Schema
Five tables in dependency order:
```
topics
└── workstreams
└── tasks (self-FK: parent_task_id)
└── progress_events
decisions (FK: topic_id, workstream_id — at least one required)
└── progress_events
```
### Enums
| Enum | Values |
|------|--------|
| `topic_status` | `active` · `paused` · `archived` |
| `workstream_status` | `active` · `blocked` · `completed` · `archived` |
| `task_status` | `todo` · `in_progress` · `blocked` · `done` · `cancelled` |
| `task_priority` | `low` · `medium` · `high` · `critical` |
| `decision_type` | `made` · `pending` |
| `decision_status` | `open` · `resolved` · `escalated` · `superseded` |
| `domain` | `custodian` · `railiance` · `markitect` · `coulomb_social` · `personhood` · `foerster_capabilities` |
### Governance constraints encoded in schema
- No hard DELETE endpoints — only soft: `archived`, `cancelled`, `superseded`
- `progress_events` has no `updated_at` and no DELETE endpoint (append-only per constitution §5)
- `decisions` with financial/legal keywords + `pending` type → auto-set `escalation_note` (§4)
---
## API
Interactive docs at http://127.0.0.1:8000/docs once the API is running.
### Key endpoint: `/state/summary`
Returns a full snapshot in one call — used by both the MCP server and dashboard:
```json
{
"generated_at": "...",
"totals": {
"topics": { "active": 6, "paused": 0, "archived": 0, "total": 6 },
"workstreams": { "active": 1, "blocked": 0, "completed": 1, "total": 2 },
"tasks": { "todo": 9, "in_progress": 0, "blocked": 0, "done": 11, "total": 20 },
"decisions": { "open": 1, "resolved": 0, "escalated": 0, "total": 1 }
},
"topics": [...], // topics with nested workstream stubs
"blocking_decisions": [...], // pending decisions only
"blocked_tasks": [...],
"recent_progress": [...], // last 20 events
"open_workstreams": [...]
}
```
### Router summary
| Prefix | Operations |
|--------|-----------|
| `/topics` | CRUD (soft-delete: `archived`) |
| `/workstreams` | CRUD (soft-delete: `archived`) |
| `/tasks` | CRUD (soft-delete: `cancelled`); `PATCH` updates status |
| `/decisions` | CRUD (soft-delete: `superseded`); auto-escalation |
| `/progress` | `GET` list + `POST` append — no DELETE |
| `/state/summary` | Full snapshot |
| `/state/health` | DB connectivity check |
---
## MCP Server
Runs as a persistent SSE service on `:8001`, independent of the Claude Code session.
Restart it anytime without restarting Claude Code.
```bash
make mcp-http # start (or restart) the MCP SSE server on :8001
```
Registered at user scope in `~/.claude.json`:
```json
{ "type": "sse", "url": "http://127.0.0.1:8001/sse" }
```
To re-register from scratch:
```bash
claude mcp remove state-hub -s user 2>/dev/null || true
claude mcp add-json -s user state-hub '{"type":"sse","url":"http://127.0.0.1:8001/sse"}'
```
See `mcp_server/TOOLS.md` for the full tool reference card (30 lines, faster than reading `server.py`).
### Tools at a glance
**Query** (read-only): `get_state_summary` · `get_topic` · `list_blocked_tasks` · `list_pending_decisions` · `get_recent_progress`
**Mutate** (each auto-emits a progress event): `create_task` · `update_task_status` · `record_decision` · `resolve_decision` · `add_progress_event` · `update_workstream_status`
**Resources**: `state://summary` · `state://topics` · `state://workstreams/{topic_slug}` · `state://decisions/blocking` · `state://tasks/blocked`
---
## `custodian` CLI
Installed into `.venv/bin/custodian` by `uv sync`; symlinked to `~/.local/bin` by `make install-cli`.
```
custodian register-project [--domain DOMAIN] [--path PATH]
```
- `--path` defaults to current working directory
- `--domain` is auto-detected from `project_charter_v*.md` frontmatter if omitted
```
custodian status
```
Prints API health, totals, and any blocking decisions.
### What `register-project` does
1. Verifies the API is reachable (fails fast with `make api` hint)
2. Looks up the topic ID for the domain via `/topics/?status=active`
3. Checks that `state-hub` is in `~/.claude.json`
4. Writes `$PROJECT_PATH/CLAUDE.md` from `scripts/project_claude_md.template`
5. Posts a `milestone` progress event recording the registration
---
## Project Registration Scripts
| Script | Purpose |
|--------|---------|
| `scripts/register_project.sh` | Shell version of `custodian register-project` |
| `scripts/patch_mcp_cwd.py` | Legacy: patched `cwd` for the old stdio registration (no longer needed) |
| `scripts/project_claude_md.template` | CLAUDE.md template with `{PROJECT_NAME}`, `{DOMAIN}`, `{TOPIC_ID}` |
| `scripts/seed.py` | Insert the 6 canonical topics into a fresh database |
| `scripts/pull_image.py` | WSL2 workaround: pull Docker images via Python urllib with Range-request chunking |
---
## Dashboard
Four pages at http://127.0.0.1:3000 (dev) or built with `npm run build`:
| Page | Content |
|------|---------|
| **Overview** | Status cards, task-by-status chart, recent activity feed, decisions due within 7 days |
| **Workstreams** | Filterable table by domain/status/owner; selected workstream task list; progress timeline |
| **Decisions** | Pending tab (with escalation highlights) and Made tab; resolution velocity chart |
| **Progress** | Append-only event feed with author badges; 30-day event volume chart |
Data loaders (`src/data/*.json.py`) are Python scripts that call the local API. They run at dev-server start and on `npm run build`. Clear the cache if data appears stale:
```bash
rm -rf dashboard/src/.observablehq/cache/
```
---
## Known Issues / WSL2 Notes
- **TLS bad record MAC on large downloads**: WSL2 corrupts packets on big TCP transfers. Use `scripts/pull_image.py` instead of `docker pull` for future image pulls.
- **MCP server is now SSE, not stdio**: Re-registration is `claude mcp add-json -s user state-hub '{"type":"sse","url":"http://127.0.0.1:8001/sse"}'`. The `patch_mcp_cwd.py` script and `.mcp.json` config are legacy artifacts from the old stdio setup.
- **AsyncSession concurrency**: SQLAlchemy 2.0 async sessions don't support concurrent operations. All queries in `/state/summary` run sequentially on a single session.
This directory remains only as a pointer so old references to
`the-custodian/state-hub` fail gently instead of implying that this repository
still owns the service source.

View File

@@ -1,39 +0,0 @@
[alembic]
script_location = migrations
prepend_sys_path = .
version_path_separator = os
sqlalchemy.url = postgresql+psycopg2://custodian:changeme@127.0.0.1:5432/custodian
[loggers]
keys = root,sqlalchemy,alembic
[handlers]
keys = console
[formatters]
keys = generic
[logger_root]
level = WARN
handlers = console
qualname =
[logger_sqlalchemy]
level = WARN
handlers =
qualname = sqlalchemy.engine
[logger_alembic]
level = INFO
handlers =
qualname = alembic
[handler_console]
class = StreamHandler
args = (sys.stderr,)
level = NOTSET
formatter = generic
[formatter_generic]
format = %(levelname)-5.5s [%(name)s] %(message)s
datefmt = %H:%M:%S

View File

@@ -1,16 +0,0 @@
from pydantic_settings import BaseSettings, SettingsConfigDict
class Settings(BaseSettings):
model_config = SettingsConfigDict(
env_file=".env",
env_file_encoding="utf-8",
extra="ignore",
)
database_url: str = "postgresql+asyncpg://custodian:changeme@127.0.0.1:5432/custodian"
api_base: str = "http://127.0.0.1:8000"
debug: bool = False
settings = Settings()

View File

@@ -1,24 +0,0 @@
from collections.abc import AsyncGenerator
from sqlalchemy.ext.asyncio import AsyncSession, async_sessionmaker, create_async_engine
from api.config import settings
engine = create_async_engine(
settings.database_url,
echo=settings.debug,
pool_pre_ping=True,
pool_size=10,
max_overflow=20,
)
async_session_factory = async_sessionmaker(
engine,
class_=AsyncSession,
expire_on_commit=False,
)
async def get_session() -> AsyncGenerator[AsyncSession, None]:
async with async_session_factory() as session:
yield session

View File

@@ -1,367 +0,0 @@
"""DoI engine — evaluates all 14 Repository Definition of Integrated criteria.
Shared by the API endpoint (async) and the CLI check script (asyncio.run).
All checks use only the repo dict from /repos/{slug} + HTTP calls to the API
+ local filesystem reads. No direct DB access.
"""
from __future__ import annotations
import asyncio
import json
import socket
import urllib.error
import urllib.request
from dataclasses import dataclass, field
from datetime import datetime, timezone
from pathlib import Path
from typing import Literal
CriterionStatus = Literal["pass", "fail", "warn", "skip"]
Tier = Literal["none", "core", "standard", "full"]
# Criteria that belong to each tier (in check order)
CORE_IDS = {"C1", "C2", "C3", "C4"}
STANDARD_IDS = {"C5", "C6", "C7", "C8", "C9"}
FULL_IDS = {"C10", "C11", "C12", "C13", "C14"}
@dataclass
class CriterionResult:
id: str
label: str
tier: str
status: CriterionStatus
detail: str = ""
@dataclass
class DoIReport:
repo_slug: str
tier: Tier
core_pass: bool
standard_pass: bool
full_pass: bool
criteria: list[CriterionResult] = field(default_factory=list)
checked_at: str = field(default_factory=lambda: datetime.now(tz=timezone.utc).isoformat())
def compute_fingerprint(
repo: dict,
latest_tpsc_snap_at: str | None,
latest_goal_updated_at: str | None,
) -> str:
"""Compute a pipe-joined fingerprint of all inputs that affect DoI criteria.
If any component changes, the fingerprint changes and the cache is invalidated:
- repo.updated_at → covers last_sbom_at, remote_url, host_paths, domain changes
- latest_tpsc_snap_at → C9 (TPSC snapshot exists)
- latest_goal_updated_at → C10 (active repo goal)
- mtime of SCOPE.md, CLAUDE.md, tpsc.yaml → C5, C6, C9, C11, C12
"""
parts = [
str(repo.get("updated_at") or ""),
str(latest_tpsc_snap_at or ""),
str(latest_goal_updated_at or ""),
]
repo_path = _resolve_path(repo)
if repo_path:
for fname in ("SCOPE.md", "CLAUDE.md", "tpsc.yaml"):
f = Path(repo_path) / fname
try:
parts.append(f"{fname}:{f.stat().st_mtime:.3f}")
except FileNotFoundError:
parts.append(f"{fname}:absent")
return "|".join(parts)
def _resolve_path(repo: dict) -> str:
hostname = socket.gethostname()
host_paths = repo.get("host_paths") or {}
candidates = []
if host_paths.get(hostname):
candidates.append(host_paths[hostname])
if repo.get("local_path"):
candidates.append(repo["local_path"])
for raw in candidates:
p = Path(raw).expanduser()
if p.is_dir():
return str(p)
return ""
def _get_sync(api_base: str, path: str, params: dict | None = None) -> object:
url = f"{api_base}{path}"
if params:
q = "&".join(f"{k}={v}" for k, v in params.items() if v is not None)
if q:
url = f"{url}?{q}"
req = urllib.request.Request(url, headers={"Accept": "application/json"})
try:
with urllib.request.urlopen(req, timeout=5) as r:
return json.loads(r.read())
except Exception:
return None
async def _get(api_base: str, path: str, params: dict | None = None) -> object:
"""Async wrapper — runs blocking urllib in a thread so the event loop stays free."""
return await asyncio.to_thread(_get_sync, api_base, path, params)
async def _run_consistency(repo_slug: str, api_base: str) -> tuple[int, int, int]:
"""Run consistency_check.py and return (fail, warn, info) counts."""
script = Path(__file__).parent.parent / "scripts" / "consistency_check.py"
proc = await asyncio.create_subprocess_exec(
"uv", "run", "python", str(script),
"--repo", repo_slug,
"--api-base", api_base,
stdout=asyncio.subprocess.PIPE,
stderr=asyncio.subprocess.PIPE,
cwd=str(Path(__file__).parent.parent),
)
stdout, _ = await asyncio.wait_for(proc.communicate(), timeout=30)
text = stdout.decode()
fail = warn = info = 0
for line in text.splitlines():
if "Summary:" in line:
parts = line.split("|")
for p in parts:
p = p.strip()
if "fail" in p:
try: fail = int(p.split()[0])
except ValueError: pass
elif "warn" in p:
try: warn = int(p.split()[0])
except ValueError: pass
elif "info" in p:
try: info = int(p.split()[0])
except ValueError: pass
return fail, warn, info
async def evaluate(
repo: dict,
api_base: str = "http://127.0.0.1:8000",
skip_consistency: bool = False,
prefetch: dict | None = None,
) -> DoIReport:
"""Evaluate all 14 DoI criteria for a repo.
Args:
repo: Repo dict (slug, domain_slug, local_path, remote_url, host_paths, last_sbom_at).
api_base: API base URL — only used when prefetch is absent.
skip_consistency: Skip C7/C13 subprocess calls (used in summary mode).
prefetch: Optional pre-fetched bulk data to avoid HTTP self-calls:
{
"domain_status": {"custodian": "active", ...}, # slug → status
"tpsc_snap_counts": {"llm-connect": 1, ...}, # repo_slug → count
"active_goal_counts": {"llm-connect": 0, ...}, # repo_slug → count
}
"""
slug = repo.get("slug", "unknown")
results: list[CriterionResult] = []
def _r(id: str, label: str, tier: str, status: CriterionStatus, detail: str = "") -> CriterionResult:
r = CriterionResult(id=id, label=label, tier=tier, status=status, detail=detail)
results.append(r)
return r
# ── Tier 1: Core ─────────────────────────────────────────────────────────
# C1: registered
_r("C1", "Registered in state-hub", "core", "pass", "Repo record exists")
# C2: domain assigned and active
domain_slug = repo.get("domain_slug") or ""
if not domain_slug:
_r("C2", "Domain assigned", "core", "fail", "No domain_slug on repo record")
else:
if prefetch and "domain_status" in prefetch:
dom_status = prefetch["domain_status"].get(domain_slug)
else:
d = await _get(api_base, f"/domains/{domain_slug}/")
dom_status = d.get("status") if d else None
if dom_status == "active":
_r("C2", "Domain assigned", "core", "pass", f"domain: {domain_slug}")
elif dom_status:
_r("C2", "Domain assigned", "core", "warn", f"Domain '{domain_slug}' status: {dom_status}")
else:
_r("C2", "Domain assigned", "core", "fail", f"Domain '{domain_slug}' not found")
# C3: local path resolves
repo_path = _resolve_path(repo)
if repo_path:
_r("C3", "Local path resolves", "core", "pass", repo_path)
else:
raw = repo.get("local_path") or "(none)"
_r("C3", "Local path resolves", "core", "fail", f"Path not accessible: {raw}")
# C4: remote URL set
remote = repo.get("remote_url") or ""
if remote.strip():
_r("C4", "Remote URL set", "core", "pass", remote)
else:
_r("C4", "Remote URL set", "core", "fail", "remote_url is empty")
# ── Tier 2: Standard ─────────────────────────────────────────────────────
# C5: SCOPE.md
if not repo_path:
_r("C5", "SCOPE.md present", "standard", "skip", "Local path unavailable")
elif (Path(repo_path) / "SCOPE.md").exists():
_r("C5", "SCOPE.md present", "standard", "pass")
else:
_r("C5", "SCOPE.md present", "standard", "fail", "SCOPE.md not found at repo root")
# C6: CLAUDE.md
if not repo_path:
_r("C6", "CLAUDE.md present", "standard", "skip", "Local path unavailable")
elif (Path(repo_path) / "CLAUDE.md").exists():
_r("C6", "CLAUDE.md present", "standard", "pass")
else:
_r("C6", "CLAUDE.md present", "standard", "fail", "CLAUDE.md not found at repo root")
# C7: workplan convention — consistency check 0 FAIL
if skip_consistency:
_r("C7", "Workplan convention (0 FAIL)", "standard", "skip", "Not checked in summary mode — use /repos/{slug}/doi for full check")
else:
try:
fail, warn, _ = await _run_consistency(slug, api_base)
if fail == 0:
_r("C7", "Workplan convention (0 FAIL)", "standard", "pass", f"consistency: {fail} fail / {warn} warn")
else:
_r("C7", "Workplan convention (0 FAIL)", "standard", "fail", f"consistency: {fail} fail / {warn} warn")
except Exception as e:
_r("C7", "Workplan convention (0 FAIL)", "standard", "skip", f"Could not run consistency check: {e}")
# C8: SBOM ingested
last_sbom = repo.get("last_sbom_at")
if last_sbom:
_r("C8", "SBOM ingested", "standard", "pass", f"last ingested: {last_sbom[:10]}")
else:
_r("C8", "SBOM ingested", "standard", "fail", "last_sbom_at not set — run make ingest-sbom")
# C9: TPSC declared (tpsc.yaml present + snapshot exists)
tpsc_file_ok = repo_path and (Path(repo_path) / "tpsc.yaml").exists()
if prefetch and "tpsc_snap_counts" in prefetch:
has_snap = (prefetch["tpsc_snap_counts"].get(slug, 0) > 0)
snap_count = prefetch["tpsc_snap_counts"].get(slug, 0)
else:
tpsc_snaps = await _get(api_base, "/tpsc/snapshots/", {"repo_slug": slug}) or []
has_snap = len(tpsc_snaps) > 0
snap_count = len(tpsc_snaps)
if not repo_path:
_r("C9", "TPSC declared", "standard", "skip", "Local path unavailable")
elif tpsc_file_ok and has_snap:
_r("C9", "TPSC declared", "standard", "pass", f"{snap_count} snapshot(s)")
elif tpsc_file_ok and not has_snap:
_r("C9", "TPSC declared", "standard", "warn", "tpsc.yaml exists but not yet ingested — run make ingest-tpsc")
elif not tpsc_file_ok:
_r("C9", "TPSC declared", "standard", "fail", "tpsc.yaml missing at repo root")
# ── Tier 3: Full ─────────────────────────────────────────────────────────
# C10: active repo goal
if prefetch and "active_goal_counts" in prefetch:
active_goal_count = prefetch["active_goal_counts"].get(slug, 0)
else:
goals = await _get(api_base, "/repo-goals/", {"repo_slug": slug}) or []
active_goal_count = sum(1 for g in goals if g.get("status") == "active")
if active_goal_count > 0:
_r("C10", "Active repo goal", "full", "pass", f"{active_goal_count} active goal(s)")
else:
_r("C10", "Active repo goal", "full", "fail", "No active repo goal — create one with create_repo_goal()")
# C11: Provided Capabilities declared in SCOPE.md
if not repo_path:
_r("C11", "Provided Capabilities declared", "full", "skip", "Local path unavailable")
else:
scope = Path(repo_path) / "SCOPE.md"
if not scope.exists():
_r("C11", "Provided Capabilities declared", "full", "skip", "SCOPE.md absent")
else:
text = scope.read_text()
has_cap_block = "```capability" in text
has_none_explicit = "## Provided Capabilities" in text and (
"none" in text.lower().split("## provided capabilities")[-1][:200]
or "no capabilities" in text.lower().split("## provided capabilities")[-1][:200]
)
if has_cap_block:
_r("C11", "Provided Capabilities declared", "full", "pass", "capability block(s) found in SCOPE.md")
elif has_none_explicit:
_r("C11", "Provided Capabilities declared", "full", "pass", "Explicitly declared none in SCOPE.md")
elif "## Provided Capabilities" in text:
_r("C11", "Provided Capabilities declared", "full", "warn",
"Section present but no capability block or explicit none — add blocks or state 'none'")
else:
_r("C11", "Provided Capabilities declared", "full", "fail",
"No '## Provided Capabilities' section in SCOPE.md")
# C12: agents template applied (CLAUDE.md mentions kaizen)
if not repo_path:
_r("C12", "Agents template applied", "full", "skip", "Local path unavailable")
else:
claude_md = Path(repo_path) / "CLAUDE.md"
if not claude_md.exists():
_r("C12", "Agents template applied", "full", "skip", "CLAUDE.md absent")
else:
text = claude_md.read_text()
if "get_kaizen_agent" in text or "kaizen" in text.lower():
_r("C12", "Agents template applied", "full", "pass")
else:
_r("C12", "Agents template applied", "full", "fail",
"CLAUDE.md has no kaizen agent reference")
# C13: consistency check clean (0 FAIL, 0 WARN — C-12 exempt)
if skip_consistency:
_r("C13", "Consistency check clean (0 FAIL/WARN)", "full", "skip", "Not checked in summary mode — use /repos/{slug}/doi for full check")
else:
try:
fail, warn, _ = await _run_consistency(slug, api_base)
if fail == 0 and warn == 0:
_r("C13", "Consistency check clean (0 FAIL/WARN)", "full", "pass")
elif fail == 0 and warn > 0:
_r("C13", "Consistency check clean (0 FAIL/WARN)", "full", "warn",
f"{warn} warn(s) — C-12 legacy tasks may be exempt")
else:
_r("C13", "Consistency check clean (0 FAIL/WARN)", "full", "fail",
f"{fail} fail(s), {warn} warn(s)")
except Exception as e:
_r("C13", "Consistency check clean (0 FAIL/WARN)", "full", "skip", f"Could not run: {e}")
# C14: host paths registered
host_paths = repo.get("host_paths") or {}
if host_paths:
_r("C14", "Host paths registered", "full", "pass",
f"{len(host_paths)} host(s): {', '.join(host_paths.keys())}")
else:
_r("C14", "Host paths registered", "full", "fail",
"host_paths empty — run update_repo_path() for each active machine")
# ── Compute tier ─────────────────────────────────────────────────────────
by_id = {r.id: r for r in results}
def _tier_pass(ids: set[str]) -> bool:
return all(by_id[i].status in ("pass", "warn") for i in ids if i in by_id)
core_pass = _tier_pass(CORE_IDS)
standard_pass = core_pass and _tier_pass(STANDARD_IDS)
full_pass = standard_pass and _tier_pass(FULL_IDS)
if full_pass:
tier: Tier = "full"
elif standard_pass:
tier = "standard"
elif core_pass:
tier = "core"
else:
tier = "none"
return DoIReport(
repo_slug=slug,
tier=tier,
core_pass=core_pass,
standard_pass=standard_pass,
full_pass=full_pass,
criteria=results,
)

View File

@@ -1,60 +0,0 @@
import os
from contextlib import asynccontextmanager
from fastapi import FastAPI
from fastapi.middleware.cors import CORSMiddleware
from api.database import engine
from api.routers import decisions, extension_points, progress, state, tasks, technical_debt, topics, workstreams, workstream_dependencies
from api.routers import domains, repos, contributions, sbom, policy, domain_goals, repo_goals, messages, capability_requests, tpsc
from api.routers import token_events
@asynccontextmanager
async def lifespan(app: FastAPI):
yield
await engine.dispose()
app = FastAPI(
title="Custodian State Hub",
description="Local-first state API for the Custodian agent system.",
version="0.6.0",
lifespan=lifespan,
)
_cors_env = os.getenv("CORS_ORIGINS", "http://localhost:3000,http://127.0.0.1:3000")
_cors_origins = [o.strip() for o in _cors_env.split(",") if o.strip()]
app.add_middleware(
CORSMiddleware,
allow_origins=_cors_origins,
allow_methods=["GET", "POST", "PATCH", "DELETE", "PUT"],
allow_headers=["Content-Type"],
)
app.include_router(domains.router)
app.include_router(repos.router)
app.include_router(topics.router)
app.include_router(workstreams.router)
app.include_router(workstream_dependencies.router)
app.include_router(tasks.router)
app.include_router(decisions.router)
app.include_router(extension_points.router)
app.include_router(technical_debt.router)
app.include_router(progress.router)
app.include_router(domain_goals.router)
app.include_router(repo_goals.router)
app.include_router(contributions.router)
app.include_router(sbom.router)
app.include_router(messages.router)
app.include_router(capability_requests.router)
app.include_router(tpsc.router)
app.include_router(token_events.router)
app.include_router(state.router)
app.include_router(policy.router)
@app.get("/", include_in_schema=False)
async def root():
return {"service": "state-hub", "docs": "/docs"}

View File

@@ -1,47 +0,0 @@
from api.models.base import Base
from api.models.domain import Domain
from api.models.domain_goal import DomainGoal, DomainGoalStatus
from api.models.topic import Topic, TopicStatus
from api.models.managed_repo import ManagedRepo
from api.models.repo_goal import RepoGoal, RepoGoalStatus
from api.models.workstream import Workstream, WorkstreamStatus
from api.models.workstream_dependency import WorkstreamDependency
from api.models.task import Task, TaskStatus, TaskPriority
from api.models.decision import Decision, DecisionType, DecisionStatus
from api.models.progress_event import ProgressEvent
from api.models.extension_point import ExtensionPoint, EPStatus
from api.models.technical_debt import TechnicalDebt, TDStatus
from api.models.contribution import Contribution, ContributionType, ContributionStatus
from api.models.sbom_snapshot import SBOMSnapshot
from api.models.sbom_entry import SBOMEntry, Ecosystem
from api.models.agent_message import AgentMessage
from api.models.capability_catalog import CapabilityCatalog
from api.models.capability_request import CapabilityRequest
from api.models.tpsc import TPSCCatalog, TPSCSnapshot, TPSCEntry
from api.models.doi_cache import DOICache
from api.models.token_event import TokenEvent
__all__ = [
"Base",
"Domain",
"DomainGoal", "DomainGoalStatus",
"Topic", "TopicStatus",
"ManagedRepo",
"RepoGoal", "RepoGoalStatus",
"Workstream", "WorkstreamStatus",
"WorkstreamDependency",
"Task", "TaskStatus", "TaskPriority",
"Decision", "DecisionType", "DecisionStatus",
"ProgressEvent",
"ExtensionPoint", "EPStatus",
"TechnicalDebt", "TDStatus",
"Contribution", "ContributionType", "ContributionStatus",
"SBOMSnapshot",
"SBOMEntry", "Ecosystem",
"AgentMessage",
"CapabilityCatalog",
"CapabilityRequest",
"TPSCCatalog", "TPSCSnapshot", "TPSCEntry",
"DOICache",
"TokenEvent",
]

View File

@@ -1,44 +0,0 @@
import uuid
from datetime import datetime
from sqlalchemy import DateTime, ForeignKey, String, Text, text
from sqlalchemy.dialects.postgresql import UUID
from sqlalchemy.orm import Mapped, mapped_column, relationship
from api.models.base import Base, new_uuid
class AgentMessage(Base):
__tablename__ = "agent_messages"
id: Mapped[uuid.UUID] = mapped_column(
UUID(as_uuid=True), primary_key=True, default=new_uuid
)
from_agent: Mapped[str] = mapped_column(String(100), nullable=False)
to_agent: Mapped[str] = mapped_column(String(100), nullable=False, index=True)
subject: Mapped[str] = mapped_column(String(500), nullable=False)
body: Mapped[str] = mapped_column(Text, nullable=False)
thread_id: Mapped[uuid.UUID | None] = mapped_column(
UUID(as_uuid=True),
ForeignKey("agent_messages.id", ondelete="SET NULL"),
nullable=True,
index=True,
)
read_at: Mapped[datetime | None] = mapped_column(
DateTime(timezone=True), nullable=True
)
archived_at: Mapped[datetime | None] = mapped_column(
DateTime(timezone=True), nullable=True
)
created_at: Mapped[datetime] = mapped_column(
DateTime(timezone=True),
server_default=text("now()"),
nullable=False,
)
thread_root: Mapped["AgentMessage | None"] = relationship(
"AgentMessage",
remote_side="AgentMessage.id",
foreign_keys=[thread_id],
lazy="select",
)

View File

@@ -1,26 +0,0 @@
import uuid
from datetime import datetime
from sqlalchemy import DateTime, func
from sqlalchemy.dialects.postgresql import UUID
from sqlalchemy.orm import DeclarativeBase, Mapped, mapped_column
class Base(DeclarativeBase):
pass
class TimestampMixin:
created_at: Mapped[datetime] = mapped_column(
DateTime(timezone=True), server_default=func.now(), nullable=False
)
updated_at: Mapped[datetime] = mapped_column(
DateTime(timezone=True),
server_default=func.now(),
onupdate=func.now(),
nullable=False,
)
def new_uuid() -> uuid.UUID:
return uuid.uuid4()

Some files were not shown because too many files have changed in this diff Show More