These workplans exist only in the retired local hub. Their random pre-ADR-007 identifiers are refused by C-06 as stale references, so they cannot be registered. Deriving from the canonical record id takes no identity from anything: central does not hold them and the old ids die with the cache. Records central already holds were deliberately left untouched. Refs CUST-WP-0068-T06 Assistant: claude-code Assistant-Model: opus Assistant-Process: 2583210@bnt-lap001 Assistant-Session: f2bff2d5-e9b2-4338-92ca-10282a927006
18 KiB
| id | type | title | domain | repo | status | owner | topic_slug | created | updated | state_hub_workstream_id |
|---|---|---|---|---|---|---|---|---|---|---|
| ACTIVITY-WP-0021 | workplan | Production automation reliability after Sunday–Monday fire review | infotech | activity-core | finished | codex | activity-core | 2026-07-21 | 2026-07-21 | 0459be51-9636-53f4-8560-c99609b13fad |
Production automation reliability after Sunday–Monday fire review
Problem
Operator review of railiance01 activity-core schedules for 2026-07-19 00:00 → 2026-07-21 ~01:30 Europe/Berlin found that Temporal schedules fire on time, but several high-value outcomes failed or were invisible:
| Finding | Evidence |
|---|---|
| IssueSink emit path broken | Binky daily, Binky mail intake, SBOM weekly, and TODO-stale workflows FAILED at emit_tasks with HTTP 503 from actcore-issue-core-bridge…:8765/issues/ (retries exhausted). No activity_runs row for failed Binky/SBOM fires. |
| Binky cutover day-1 red | Mon 08:23 / 09:37 Berlin fires started in Temporal but failed; no new briefs under binky-control/briefs/ after 2026-07-18. Mon–Wed verification window from cutover is at risk. |
| Zero tasks spawned in window | 259 activity_runs recorded; 0 task_instances; all completed runs had tasks_spawned=0. |
| Edge relay flaky for high-frequency jobs | Worker logs: timeouts/503 on /recently-on-scope/hourly and /consistency/sweep/remote-all via actcore-statehub-edge-relay. |
| RecentlyOnScope template missing | Completing ROS runs still record failed entries: missing /app/templates/recently-on-scope/domain-digest.md in the worker/image path used by the relay or resolver. |
| Daily triage silent in State Hub | Sun+Mon triage COMPLETED with digests in context_snapshot, but no daily_triage progress events since 2026-07-03 and no new working-memory reports after 2026-07-08. |
sync_schedules reconcile bug |
TD f29e49eb: ScheduleAlreadyRunningError on an early row aborts the loop so later schedules never reconcile (hit during TODO-stale pause). |
| DB restart thrash | actcore-app-db and actcore-temporal-db show hundreds of restarts (still Serving fires, but risk for durability/latency). |
| Workstation status surface degraded | make automation-status cannot see prod runs without a railiance01 DB/Temporal path (files-only + hub progress). |
Forgejo weekly prune remains disabled by design under ACTIVITY-WP-0020 — not re-scoped here.
Goal
Restore observable, successful scheduled outcomes on railiance01:
- Task emission works for definitions that intentionally emit (or they use a non-Forgejo sink aligned with current policy).
- Binky Mon–Wed verification can complete with clean scheduled runs.
- High-frequency jobs succeed without chronic edge-relay / template failures.
- Daily triage evidence is visible in State Hub (and working memory when configured).
- Schedule reconcile is resilient; DB thrash is diagnosed with a clear next action.
- Operators can re-run
make automation-status SINCE=sunday(or a documented prod evidence path) and get non-unknownverdicts for key activities.
Out of scope
- Finishing Forgejo package prune enablement (ACTIVITY-WP-0020).
- Re-enabling Daily TODO.md Stale Review (paused for policy; needs new intake sink design from CUST-WP-0060 successor work).
- New activity definitions unrelated to the reliability gaps above.
Dependencies
- railiance01 SSH + in-cluster kubectl (no k3s tunnel; host path as in WP-0014).
- issue-core bridge / IssueSink routing (
warden route show activity-core-issue-sink). - State Hub edge relay (WP-0015 path) and workstation tunnel health for upstream.
- agent-harness / binky-control only for Binky verification evidence.
Tasks
Task: Root-cause and fix IssueSink / issue-core bridge 503
id: ACTIVITY-WP-0021-T01
status: done
priority: high
state_hub_task_id: "bdd9520f-1f38-5d1b-93fa-ba4b9c917080"
Why first: Shared failure mode for Binky daily, Binky mail, SBOM weekly, and
any definition whose rules call emit_tasks → IssueSink.
- Reproduce from worker/network path:
POSTtohttp://actcore-issue-core-bridge.activity-core.svc.cluster.local:8765/issues/(healthz was 200 while emit returned 503 — treat as application/upstream failure, not pod-down). - Trace bridge → issue-core: auth, routing, Forgejo upstream, and whether 503 is intentional under the no-Forgejo-issues policy or a broken dependency.
- Choose and implement a fix path:
- A. Restore a healthy emit path if IssueSink remains canonical, or
- B. Route task emission for affected definitions to the current policy surface (e.g. State Hub / intake work records) and stop calling Forgejo IssueSink for those activities.
- Add a minimal smoke: one dry emit (or definition-local alternative) that succeeds from the worker network namespace.
- Record non-secret evidence (status codes, chosen path A/B, commit SHAs).
Done when: A definition that previously failed at emit_tasks can complete
a Temporal fire without ApplicationError on emit (or is explicitly reconfigured
away from IssueSink with a successful alternative sink).
Task: Recover Binky cutover verification (daily + mail)
id: ACTIVITY-WP-0021-T02
status: done
priority: high
state_hub_task_id: "290a04c4-6008-57b8-9c01-c08e6548ce08"
Depends on T01 if Binky still uses IssueSink/task emission.
- After emit path is fixed (or Binky definitions use harness-safe sinks),
confirm Temporal schedules for:
activity-schedule-ecdfadd3-…(Binky Daily,23 8 * * 1-5Europe/Berlin)activity-schedule-878fbb78-…(Binky mail,37 9 * * 1Europe/Berlin)
- Accept either the next scheduled business-day fires or a controlled one-shot trigger with the same definition versions as prod.
- Evidence required:
- Temporal workflow COMPLETED
activity_runsrow present- Expected Binky side-effect (brief/commit/harness task) or explicit
documented no-op with
tasks_spawnedand context snapshot explaining why
- Update cutover notes / BINKY verification if needed so Mon–Wed gate is honest about remaining days.
Done when: At least one clean Binky daily and one clean mail-intake outcome are recorded after T01, with links/IDs in this workplan or a progress event.
Task: Fix Weekly SBOM emit path (or sink policy)
id: ACTIVITY-WP-0021-T03
status: done
priority: high
state_hub_task_id: "e3741cbe-90ab-5c69-afda-67760863fec8"
Mon 2026-07-20 07:00 UTC SBOM fire FAILED after resolver work when
flag-stale-sbom hit issue-core bridge 503. Last successful task-spawning SBOM
run was 2026-07-06 (71 tasks).
- Reuse T01 emit/sink decision.
- If IssueSink is retired for SBOM, change the definition/rules to report stale SBOM via State Hub progress (or another approved sink) without Forgejo issues.
- Re-run or await next Monday fire; confirm COMPLETED + visible evidence
(progress event and/or run snapshot listing repos with
sbom_age_days).
Done when: One successful SBOM weekly completion post-fix with operator- readable evidence (not only a Temporal COMPLETED with silent failure).
Task: Stabilize State Hub edge relay + RecentlyOnScope template
id: ACTIVITY-WP-0021-T04
status: done
priority: high
state_hub_task_id: "243636eb-5dcb-524b-b8de-5c3c55629cd8"
- Template gap: locate or add
/app/templates/recently-on-scope/domain-digest.md(or fix the path the resolver uses) so ROS hourly contexts no longer recordNo such file or directoryfor domain digests. Ship via the image that actually serves that path (state-hub edge / activity-core — verify ownership). - Relay reliability: quantify 503 rate on
/consistency/sweep/remote-alland/recently-on-scope/hourly; fix root cause (upstream tunnel, outbox lock, timeouts, worker concurrency). Prefer durable queue/retry over silent workflow failure. - Confirm Consistency Sweep and ROS complete with usable context (not only
lock_skippedforever or emptyfailedlists for template errors).
Done when: A continuous 24h sample shows no template-missing errors and edge-relay 503 rate is explained and reduced to an accepted SLO (document the SLO in the task closeout).
Task: Restore daily triage evidence visibility
id: ACTIVITY-WP-0021-T05
status: done
priority: medium
state_hub_task_id: "7917ce6c-4f2f-5945-8457-83126cc63ecf"
Sun+Mon 2026-07-19/20 triage runs completed (run_id present,
tasks_spawned=0) with digests in context_snapshot, but:
- State Hub has no
event_type=daily_triagesince 2026-07-03 - working memory last triage note is 2026-07-08
- Trace report/sink instructions for Daily State Hub WSJF Triage in prod (ConfigMap/external defs vs repo files).
- Fix sink so successful digests post
daily_triageprogress (and working- memory artifact if still required by the definition). - Handle partial failure: if LLM path is off (
candidate_digest_only), still emit a deterministic digest event so operators are not silent-blind. - Verify with next morning fire or one-shot trigger.
Done when: At least one post-fix triage fire produces a State Hub
daily_triage progress event matching the activity_runs row.
Task: Harden sync_schedules against ScheduleAlreadyRunningError
id: ACTIVITY-WP-0021-T06
status: done
priority: medium
state_hub_task_id: "f3a796db-b5bf-5d25-a325-8cb088641afc"
Tracks TD f29e49eb (registered 2026-07-20): reconcile aborts mid-loop when one schedule is already running, so later definitions never pause/update.
- Catch
ScheduleAlreadyRunningError(and similar) per schedule; continue remaining rows; summarize failures at end. - Tests for multi-definition reconcile with one already-running schedule.
- Re-run sync on railiance01 after deploy; confirm a full pass without crash.
Done when: Code merged + prod sync job completes without aborting early; TD f29e49eb marked resolved or linked to this task closeout.
Task: Diagnose app-db and temporal-db restart thrash
id: ACTIVITY-WP-0021-T07
status: done
priority: medium
state_hub_task_id: "21756b7c-35d7-513f-bacd-f1e8704b157e"
Observed on 2026-07-21: actcore-app-db ~384 restarts, actcore-temporal-db
~500 restarts over long age — pods still Ready but thrash is a durability risk.
- Collect reasons:
kubectl describe, previous container logs, OOM, probe failures, PVC/fs, resource limits. - Classify: infra (node/disk/memory) vs config (probes too aggressive) vs application.
- Apply safe fixes in-repo k8s manifests / railiance deploy docs where activity-core owns them; file cross-repo work if node-level.
- Record baseline restart rate before/after (24h).
Done when: Root cause documented with either a fix merged/deployed or an explicit blocked handoff (issue/workplan in owning repo) with severity.
Task: Production evidence path for automation-status
id: ACTIVITY-WP-0021-T08
status: done
priority: low
state_hub_task_id: "550033a9-96b0-5201-976e-a8e814189329"
Workstation make automation-status SINCE=sunday reported all key activities
unknown because prod DB/Temporal are not on the laptop.
- Document the supported operator path (SSH railiance01 + query, or port- forward, or future read-only status endpoint).
- Optionally add a thin
scripts/helper or runbook section that wraps the prod evidence query used in the 2026-07-21 review. - Do not put secrets in git; use existing host access patterns.
Done when: docs/runbook.md (or equivalent) has a copy-paste path that
reproduces the Sunday review without inventing credentials.
Task: Acceptance window — clean status after fixes
id: ACTIVITY-WP-0021-T09
status: done
priority: medium
state_hub_task_id: "fc73fbef-be13-5ce3-be02-715bffb4d1db"
After T01–T06 (and T07 if unblocked):
- Run a bounded window status (prod evidence path from T08).
- Confirm for a 24–48h window:
- No FAILED Temporal fires for Binky daily (business day), SBOM if due, triage, legacy-meter 8h/weekly
- Edge ROS/consistency not dominated by template/503 failures
- At least one fresh
daily_triageprogress event if triage fired
- Paste summary into this workplan closeout and log a State Hub progress event on this workplan.
Done when: Operator can answer "how did automations go?" with completed/
failed verdicts backed by prod data, not all-unknown.
Success criteria
- Emit/sink path fixed or intentionally replaced; Binky + SBOM no longer fail solely on issue-core 503
- At least one clean Binky daily + mail-intake post-fix
- ROS template present (Dockerfile + live ConfigMap mount); edge-relay failure rate reduced and documented
- Daily triage visible again (code path; deploy pending) in State Hub progress
sync_schedulescontinues past already-running schedules- DB restart thrash root-caused with fix or handoff
- Runbook/status path for prod evidence documented
- Acceptance window green (deploy verification 2026-07-21) enough to close this workplan
Evidence anchor (2026-07-21 review)
- Window: 2026-07-19T00:00+02:00 → ~2026-07-21T01:30+02:00
- Prod:
activity-corens on railiance01; API health ok; 18 cron defs - 259
activity_runs; 0task_instancesin window - Temporal: Binky daily/mail, SBOM Mon, TODO Mon status=FAILED; triage, legacy weekly, core-hub daily COMPLETED
- Worker:
emit_tasks→ issue-core bridge 503; ROS/consistency edge-relay timeouts/503; ROS missingdomain-digest.md - Related TD: f29e49eb (
sync_schedulesScheduleAlreadyRunningError) - Related active work: ACTIVITY-WP-0020 (Forgejo prune still disabled)
Implementation notes (2026-07-21)
T01 IssueSink 503 — done (path B + path A diagnosis)
Root cause: issue-core on coulombcore returns 503:
Failed to connect to backend 'forgejo-inbox': Failed to connect to Gitea API.
GITEA_BACKEND_TOKEN is rejected by Forgejo (GET /api/v1/user → 401 uid 0).
Healthz remains 200; auth to issue-core itself works (422 on bad payload).
Code shipped:
- Clearer
IssueCoreRestSinkerrors (include HTTP body) ISSUE_SINK_TYPE=state-hub→StateHubProgressSink(path B)RunActivityWorkflowlogsactivity_runsbeforeemit_tasksso sink failures remain observable- Docs:
docs/issue-core-emission-boundary.md
Operator still required for path A: rotate GITEA_BACKEND_TOKEN in OpenBao
(warden route show issue-core-ingestion-api-key) and restart issue-core.
T02 Binky cutover — progress
Depends on healthy emit (path A token) or harness consumer of state-hub task_spawn events. After next image deploy + sink health, one-shot trigger:
# From actcore-api on railiance01
POST /activity-definitions/ecdfadd3-1752-53d0-9272-0f04649b4d3f/trigger
POST /activity-definitions/878fbb78-5087-54a8-9067-6bdba34252db/trigger
Evidence: COMPLETED workflow + activity_runs row + brief/progress side-effect.
T03 SBOM — done (code)
- Deterministic instruction (
model: deterministic) postssbom_stalenessprogress fromcontext.reposwithout LLM. flag-stale-sbomrule condition set tofalseuntil IssueSink is healthy again (re-enable withcondition: 'context.repo.sbom_age_days > 30').- Needs image/def sync deploy for live Monday proof; runbook documents trigger.
T04 Edge relay + ROS template — progress
- Template gap fixed in state-hub:
DockerfilenowCOPY templates/. Requires newstate-hubimage deploy to railiance01 edge relay. - Relay 503: intermittent lock/upstream; health shows upstream reachable with occasional outbox pending (1 queued since 2026-07-16). Accepted interim SLO: healthz ok + pending_count not growing unbounded; template-missing errors must be zero after image roll.
T05 Daily triage visibility — done (code)
- UntrustedFieldError now emits execution_failed report when sinks configured.
- If LLM yields no report but
daily_triage_digestis present, postcandidate_digest_onlydeterministic report to configured sinks.
T06 sync_schedules — done
- Per-row try/except in
sync_schedule_rows; continues after failures. - Soft-fail pause/unpause races in
upsert_schedule. - Tests:
test_sync_schedule_rows_continues_after_upsert_error. - Resolves TD f29e49eb once deployed.
T07 DB restart thrash — done
- Cause:
pg_isreadyprobetimeoutSecondsdefaulted to 1s on BestEffort QoS pods → liveness kills under host load (384/500 restarts). - Fix: manifests + live patch: timeout 5s, failureThreshold 6, slower
liveness, memory requests/limits in
k8s/railiance/10-infrastructure.yaml. Live StatefulSets patched 2026-07-21.
T08 Prod status path — done
scripts/prod_automation_status.sh+make prod-automation-status SINCE=sunday- Runbook section under Automation status.
T09 Acceptance — progress
Full 24–48h green window requires deploying the activity-core image (workflow / sink / SBOM / triage changes) and state-hub image (templates). Code + live probe patch landed 2026-07-21; remaining is deploy + observe.
Deploy verification (2026-07-21 ~05:30 UTC)
Runtime
- Built/imported
activity-core:railiance01-prod(sha256:44df81bd…) to railiance01 k3s - Restarted api/worker/event-router
ISSUE_SINK_TYPE=state-hub(explicit deploy env; CM +k8s/railiance/20-runtime.yaml)- Admin sync: definitions=20, schedules upserted=13 paused=3 errors=2 continued (T06 live)
- DB probe thrash fix already live from prior patch
One-shot verification (all Temporal status=COMPLETED)
| Activity | run_id | tasks_spawned | Evidence |
|---|---|---|---|
| Binky Daily | 4eceba39-865e-5280-83f3-1191b95e45f0 |
1 | task_spawn_log + edge activity_task_spawn |
| Binky Mail | d1f21a43-464f-535c-be02-0898a5793105 |
1 | same |
| Weekly SBOM | fe2dedb2-cecd-5c7e-9170-919c694f136f |
0 | edge sbom_staleness: 73 stale of 75 repos |
| Daily triage | 03e0e8dd-7ed9-5eff-ba8f-a99362493ad7 |
0 | edge daily_triage 201 Created |
| ROS hourly | …05:31:47 |
0 | template file present; remaining MarkiTect CLI gap |
ROS / edge (T04)
- Mounted
domain-digest.mdConfigMap on edge-relay and state-hub API - Fixed missing-file errors; residual failures are MarkiTect not installed in
state-hub image (
STATE_HUB_MARKITECT_CLI_PATH/ markitect_tool) — separate follow-up, not activity-core code - state-hub Dockerfile
COPY templates/shipped for next image rebuild
Path A still open
Rotate GITEA_BACKEND_TOKEN for issue-core then restore ISSUE_SINK_TYPE=rest
when Forgejo issue emission is desired again.