activity-core/SCOPE.md
tegwick 91353df7d0
All checks were successful
CI Smoke / host-smoke (push) Successful in 0s
CI Smoke / container-smoke (push) Successful in 2s
Build and Publish Container Image / build-and-push (push) Successful in 29s
Finish WP-0025 SSO cutover except group allowlist residual.
Mark T03–T05 and T07–T08 done after live Authelia/TLS verification,
prefer SSO principal in ops UI copy and audits, and document break-glass
port-forward. Leave T06 waiting on net-kingdom LLDAP/Authelia group rules.
2026-07-22 10:23:36 +02:00

14 KiB

domain repo updated
capabilities activity-core 2026-07-21

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-hub progress, or null dry-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_schedules continues after ScheduleAlreadyRunningError).
  • 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_each binding; no exec().
  • Instruction executor: trusted-field rendering, llm-connect, structured validation, item-granular recovery, deterministic report path, report sinks.
  • Task emission adapter: IssueCoreRestSink, StateHubProgressSink, NullSink selected by ISSUE_SINK_TYPE. Production railiance01 currently uses state-hub as the safe default for internal findings (see ACTIVITY-WP-0021/0022); restore rest only 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_log with 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 skip activity_runs rows.
  • REST admin API (FastAPI): CRUD, manual trigger, admin sync, metrics.
  • Operator automation console (ACTIVITY-WP-0024): /ops inventory, 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-status and make prod-automation-status / scripts/prod_automation_status.sh for 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-07-21)

Status

Production on railiance01 (activity-core namespace). Recent finished workplans:

WP Outcome
ACTIVITY-WP-0018 Own-infra automation status CLI
ACTIVITY-WP-0019 Automation inventory targets
ACTIVITY-WP-0020 Weekly Forgejo package prune enabled; first apply 38 deletes
ACTIVITY-WP-0021 Prod reliability: state-hub sink, log_run-before-emit, schedule harden, DB probes, prod status path
ACTIVITY-WP-0006/0008 Marked finished historically; enablement evidence has moved

Open product/policy workplan: ACTIVITY-WP-0022 (IssueSink no-default-Forgejo).

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-cluster state-hub.
  • Weekly prune: worker has FORGEJO_TOKEN + hostPath /opt/railiance-platform
    • live_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-hub after Forgejo PAT/backend failures and fleet policy against silent Forgejo issues (WP-0021 path B, WP-0022).
  • Restoring rest requires 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 High (value) Tasks are emitted (progress refs or issue-core), but no per-repo executor reliably consumes them (Binky briefs still need harness/agent pickup). INTENT assigns execution to per-repo Temporal workers — that substrate is thin.
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 Medium (mostly done) WP-0025: Traefik + Authelia SSO live for activity.coulomb.social + temporal.coulomb.social; port-forward break-glass; residual T06 group allowlist.

Drift risks

  1. Convenience execution — growing shell resolvers into a general ops runner.
  2. Silent sink restore — flipping ISSUE_SINK_TYPE=rest without policy + healthy Forgejo backend reintroduces issue spam / 503s.
  3. Protection file staleness — weekly prune with apply: true depends on fresh live-image lists.
  4. Stub workflow attractionTaskExecutorWorkflow looks 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  State Hub progress
[report/evidence sinks]               →  State Hub / working memory
[bounded shell side-effects]          →  platform tools (e.g. package prune)
  • Upstream: NATS, Temporal, PostgreSQL, State Hub, repo-scoping, llm-connect.
  • Downstream: issue-core (optional), State Hub, platform tools, future per-repo executors / agent-harness.
  • 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.

  • issue-core — task connector / external tracker mapping (not fleet work-record origin).
  • repo-scoping, State Hub / the-custodian, llm-connect, agent-harness.
  • railiance-platform — Forgejo package prune tool and credential lanes.
  • ops-warden — credential routing (not secret vending for non-SSH).
  • project-core (future), ops-bridge tunnels.

Architecture Decisions

  • docs/adr/adr-001-event-bridge-architecture.md
  • docs/adr/adr-002-definition-format.md
  • docs/adr/adr-003-rule-instruction-model.md
  • docs/adr/adr-004-producer-trust-boundary.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]