glas-harness answered both open questions from ACTIVITY-WP-0032, so T01 is resolved as option A: the ops_run pull queue stays and carries the versioned harness_profile_ref plus attribution refs. The claiming executor passes the request into Glas, which resolves or refuses before sandbox creation. This changes the execution contract without also changing scheduling topology. Two answers shaped the plan: - harness_profile_ref and approach_hint coexist with distinct semantics. approach_hint must never override, synthesize, or fall back from an absent or invalid profile ref on governed execution — T02 must enforce that in code. - The glas-harness catalog is authoritative and must not be mirrored. Glas has no network validation service today, so emit-time remote validation is not available. T03 is corrected accordingly: validate locally and structurally, rely on the execution-side Glas resolver as the mandatory fail-closed check, and record the residual gap rather than papering over it with a mirrored catalogue. Hub decision 147beec6-7fe7-4837-8e3a-4264a240379d. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
15 KiB
| domain | repo | updated |
|---|---|---|
| capabilities | activity-core | 2026-08-18 |
SCOPE
This file helps you quickly understand what this repository is about, when it is relevant, and when it is not.
One-liner
activity-core is the org-wide Event Bridge for the Coulomb organization — a rule-governed event loop that receives time-based and domain events, evaluates declarative rules and LLM instructions against current org context, and emits structured task, report, and evidence outputs without owning downstream task lifecycle.
Core Idea
An ActivityDefinition (a markdown file checked into a repo) declares a trigger
(cron, one-off scheduled datetime, or named event type), context sources to
resolve before evaluation, and a set of rules and instructions that determine
what work or evidence to produce. When triggered, a durable Temporal workflow
loads the definition, resolves context, evaluates the rule/instruction set, and
emits outputs via configured sinks:
- Tasks — via
IssueSink(rest→ issue-core,state-hubprogress, ornulldry-run). - Reports — instruction reports to working memory and/or State Hub progress.
- Evidence — compact non-secret summaries from selected resolvers (ops inventory, package prune, legacy-meter, etc.).
Everything is auditable: activity_runs records the activation; task_spawn_log
records emissions; report sinks leave progress/working-memory artifacts.
The two evaluation modes:
- Rule — deterministic condition (sandboxed Python-like DSL) → fixed task templates. Fast, testable, no LLM cost.
- Instruction — optional pre-filter → LLM or deterministic report path
(
model: deterministic/none/unused) → structured tasks and/or reports. LLM reserved for genuine judgement; deterministic for pure context summaries.
In Scope
- ActivityDefinition model: trigger config (cron / scheduled / event), context sources, rules (condition + action), instructions (trusted-field prompt + model + output schema + report sinks).
- Event type registry: publisher-declared markdown definitions with attribute schemas, example payloads, and intent documentation. Curator-gating configurable per runtime environment.
- Trigger types: 5-field cron with timezone and misfire policy; one-off scheduled datetime; event-type subscription via NATS; manual one-shot API trigger; one-shot schedule smoke tests for recurring definitions.
- Schedule reconcile: Temporal Schedule upsert/pause with per-row error
isolation (
sync_schedulescontinues afterScheduleAlreadyRunningError). - Context resolution adapters: repo-scoping, State Hub (domain/workplan state, SBOM status, daily triage digest, coding retro, Binky rhythm status, consistency sweep, RecentlyOnScope hourly), shell queries (e.g. Forgejo package prune), and ops inventory probes. Registry is extensible.
- Rule evaluator: sandboxed AST walker;
for_eachbinding; noexec(). - Instruction executor: trusted-field rendering, llm-connect, structured validation, item-granular recovery, deterministic report path, report sinks.
- Task emission adapter:
IssueCoreRestSink,StateHubProgressSink,NullSinkselected byISSUE_SINK_TYPE. Production railiance01 currently usesstate-hubas the safe default for internal findings (see ACTIVITY-WP-0021/0022); restorerestonly when issue-core→Forgejo is healthy and policy allows external issues. - Report / evidence sinks: working memory, State Hub progress
(
daily_triage,sbom_staleness,forgejo_package_prune,ops_inventory_probe,activity_task_spawn, etc.). - Spawn audit log:
task_spawn_logwith rule/instruction id and sink ref. - Webhook receiver: Gitea/GitHub → EventEnvelope → NATS.
- Worker and workflow infrastructure: Temporal
RunActivityWorkflow(load → resolve → evaluate → report → log_run → emit). Emit failures no longer skipactivity_runsrows. - REST admin API (FastAPI): CRUD, manual trigger, admin sync, metrics.
- Operator automation console (ACTIVITY-WP-0024):
/opsinventory, status window, run history, Run now / enable / disable / pause with operator-token auth (fail-closed), plus thin HTML UI at/ops/ui. - Automation status surface:
make automation-statusandmake prod-automation-status/scripts/prod_automation_status.shfor railiance01 evidence without LLM authority (same contract as/ops/automations/status). - Operational runbook:
docs/runbook.md, emission boundary docs.
Out of Scope
- Task lifecycle — create/assign/track/close remains issue-core (or fleet work-record connectors). activity-core holds a spawn audit trail only.
- Project and initiative management — project-core (future).
- General execution workers — scans, patches, privileged API writes that are not explicitly declared as bounded ActivityDefinition side-effects (e.g. retention prune with dry-run/apply gates) belong to per-repo workers or platform tools.
- General ops control plane — Kubernetes, SSH, tunnels, secret custody, OpenBao policy administration.
- Event broker / Temporal server hosting — consume, do not own lifecycle.
- End-user task UI — tracking human work items. The operator automation
console (
/ops) is in scope; it manages ActivityDefinitions and schedules, not task lifecycle. - Coding assistant schedulers as production authority.
Boundary note (side-effect resolvers): A small set of shell/context resolvers intentionally invoke platform tools (e.g. Forgejo package prune). That is allowed only when the side-effect is the declared purpose of the ActivityDefinition, is credential-routed, evidence-posted, and not general task execution. It must not expand into an unbounded ops executor.
Relevant When
- Org-wide recurring maintenance (SBOM, package prune, legacy-meter, Binky rhythm, consistency sweeps) without bespoke per-service cron.
- Reactive task/report generation from org events and context.
- One-off future scheduling.
- Auditable activation history (runs, spawn log, progress).
- Answering “how did automations go since Sunday?” from deterministic repo-native / prod evidence.
Not Relevant When
- Tracking task completion/reassignment → issue-core / work records.
- Multi-phase project orchestration → project-core.
- Simple host cron with no durability or evidence needs.
Current State (2026-08-18)
Status
Production on railiance01 (activity-core namespace). Product work through
ACTIVITY-WP-0028 is finished. G2 (executor gap) is closed in-repo by
ACT-ADR-005 + ACTIVITY-WP-0026 (ops_run claim queue).
Open work (SBOM catch-up parked — CUST-WP-0062 / ACTIVITY-WP-0030):
| WP | Status | Role |
|---|---|---|
| ACTIVITY-WP-0029 | active | S5 of State Hub retirement: retarget sweeps/sinks/execution to repo-manager and hub-core |
| ACTIVITY-WP-0030 | active (all tasks wait) | Daily SBOM catch-up; do not start — waits on CUST-WP-0062 |
Live posture (railiance01)
- Image:
activity-core:railiance01-prod(locally imported). ISSUE_SINK_TYPE=state-hub(internal findings → State Hub progress, not Forgejo issues).- Edge relay:
actcore-statehub-edge-relay→ in-clusterstate-hub. - Weekly prune: worker has
FORGEJO_TOKEN+ hostPath/opt/railiance-platformlive_images_file(kubectl absent in pod).
- Proven one-shots (2026-07-21): Binky daily/mail COMPLETED with tasks_spawned=1; SBOM deterministic report; daily triage progress; prune apply.
Definitions (repo files + prod DB)
| Definition | Role |
|---|---|
weekly-sbom-staleness |
Deterministic SBOM report; task emit gated off |
weekly-forgejo-package-prune |
Sunday 03:30 UTC apply prune + evidence |
weekly-legacy-meter-review / legacy-meter-8h-capture |
Meter evidence |
weekly-coding-retro |
Present; enablement depends on coding_retro feed |
| Binky daily / mail / review-prep | Rhythm tasks via IssueSink |
| Railiance ConfigMap bundle | Daily triage, ROS hourly, consistency sweep, etc. |
Task emission posture
- Canonical REST sink to issue-core remains implemented and documented.
- Production default is
state-hubafter Forgejo PAT/backend failures and fleet policy against silent Forgejo issues (WP-0021 path B, WP-0022). - Restoring
restrequires healthy issue-core→Forgejo and explicit policy opt-in per definition.
Assessment Against Intent
Alignment
| INTENT promise | Status |
|---|---|
| Answers when / what / where | Met — Temporal schedules, rules/instructions, sinks |
| Markdown definitions | Met — activity-definitions/, event-types, external ConfigMaps |
| Rules before instructions | Met — SBOM/prune/Binky rules; triage uses LLM when needed |
| Durable recurring automation | Met — railiance01 schedules fire; status surface exists |
| Audit trail | Met — activity_runs, spawn log, progress/working-memory |
| Does not own task lifecycle | Met — no completion tracking |
| Does not own project phases | Met |
Gaps and tensions (INTENT ↔ practice)
| Gap | Severity | Notes |
|---|---|---|
| G1. Sink default vs INTENT “emit to issue-core” | High (policy) | INTENT names issue-core as the task landing zone. Practice and work-record canon push State Hub / repo work records for internal findings. WP-0022 owns policy; code already supports state-hub / null / rest. |
| G2. Executor gap | Closed (in-repo) | ACT-ADR-005 + ACTIVITY-WP-0026 (ops_run claim queue). Claim loop remains REIN-A-0002. Do not use issue-core/Forgejo as default ops queue (WP-0022). |
| G3. Side-effect resolvers | Medium | Forgejo prune apply: true runs platform deletes inside a context resolver. Allowed only as declared, gated side-effect; needs clearer SCOPE language (above) and operator refresh of live-images protection. |
| G4. Review queue | Medium | review_required remains metadata-only; no downstream review queue. |
| G5. TaskExecutorWorkflow stub | Low | Disabled unless ACTIVITY_CORE_ENABLE_TASK_EXECUTOR_STUB (WP-0023-T08). |
| G6. ROS digest completeness | Medium (ops, external) | Templates mounted; state-hub image still lacks markitect_tool / MarkiTect CLI (main-d8808bf checked 2026-07-21). Owner: state-hub (WP-0023-T07). |
| G7. Credential delivery | Low (residual) | FORGEJO_TOKEN via ESO actcore-forgejo-admin (WP-0023-T05, Ready). issue-core GITEA_BACKEND_TOKEN still 503 forgejo-inbox for path A rest — issue-core owner (WP-0023-T06). |
| G8. Live-images hygiene | Medium (ops) | Multi-cluster live-images-all.txt must be refreshed after deploys or prune can delete live tags (incident 2026-07-21, restored). scripts/refresh_live_images.sh (T04). |
| G9. Evidence federation | Low | Progress often lands on railiance01 edge/hub; workstation primary hub may not show the same feed without tunnel/outbox health. |
| G10. API external access | Done | WP-0025 finished: Traefik + Authelia SSO for ops + Temporal UI; LLDAP activity-core-operators (NK-WP-0021); port-forward break-glass only. |
| G11. State Hub as permanent target | Medium (T03 open) | Sweep is dual-run/repo-manager-retargetable; /execution/semantics is local. Progress/evidence sinks still wait on HUB-WP-0004 (ACTIVITY-WP-0029-T03). |
Drift risks
- Convenience execution — growing shell resolvers into a general ops runner.
- Silent sink restore — flipping
ISSUE_SINK_TYPE=restwithout policy + healthy Forgejo backend reintroduces issue spam / 503s. - Protection file staleness — weekly prune with
apply: truedepends on fresh live-image lists. - Stub workflow attraction —
TaskExecutorWorkflowlooks like an execution home.
How It Fits
[NATS JetStream / Temporal Schedules / manual trigger]
↓
[activity-core] Event type registry · rules · instructions · context resolvers
↓
[IssueSink: rest | state-hub | null] → issue-core or hub-core progress (State Hub until cutover)
[report/evidence sinks] → hub-core / working memory
[ops_run claim queue] → rein-aharness / per-repo executors
[bounded shell side-effects] → platform tools (e.g. package prune)
- Upstream: NATS, Temporal, PostgreSQL, repo-manager / hub-core (State Hub until retirement), repo-scoping, llm-connect.
- Downstream: issue-core (optional), hub-core progress, platform tools, rein-aharness / per-repo executors claiming ops_runs.
- Orientation (not runtime): info-tech-canon (task/org/governance vocabulary), policy-nexus (publication of ADRs/canon — not authored here).
- Ops: railiance01 k3s; workstation status via SSH helper.
Terminology
- ActivityDefinition — markdown policy unit (trigger + context + rules/instructions).
- EventEnvelope — canonical inbound event shape.
- Rule / Instruction — deterministic vs judgement (or deterministic report) paths.
- IssueSink — task emission adapter (
rest/state-hub/null). - Report sink / Evidence sink — non-task activation outputs.
- Spawn audit trail — local emission record; not authoritative task state.
- Activity (Temporal) vs ActivityDefinition (app policy) — different concepts.
Related / Overlapping
info-tech-canon— task / organization / governance vocabulary; repository layout.policy-nexus— publishes ADRs/canon; does not author them.repo-manager— repo registry, consistency engine, work-record index.hub-core— messages, progress projections, extension ports (core-hub absorbed later).state-hub— compatibility read model until STATE-WP-0079 retirement.issue-core— task connector / external tracker mapping (not fleet work-record origin).repo-scoping,llm-connect,rein-aharness.railiance-platform— Forgejo package prune tool and credential lanes.ops-warden— credential routing (not secret vending for non-SSH).ops-bridgetunnels.
Architecture Decisions
docs/adr/adr-001-event-bridge-architecture.mddocs/adr/adr-002-definition-format.mddocs/adr/adr-003-rule-instruction-model.mddocs/adr/adr-004-producer-trust-boundary.mddocs/adr/adr-005-ops-runs-vs-dev-work-records.mddocs/adr/adr-006-glas-profile-execution.md
Getting Oriented
- Start:
INTENT.md, this file,docs/adr/,docs/runbook.md. - Key code:
workflows.py,activities.py,issue_sink.py,report_sinks.py,context_resolvers/,automation_status.py,sync_schedules.py. - Definitions:
activity-definitions/,event-types/, Railiance ConfigMaps. - Status:
make automation-status SINCE=sunday·make prod-automation-status SINCE=sunday.
Provided Capabilities
type: data
title: Durable event-triggered task factory
description: >
Org-wide Event Bridge that receives time-based and domain events, evaluates
declarative rules and LLM instructions against current org context, and emits
structured task, report, and evidence outputs with a full spawn/report audit
trail while leaving task lifecycle ownership downstream.
keywords: [temporal, workflow, event-bridge, task, report, evidence, cron, event, rule, instruction, org-automation]