activity-core/SCOPE.md
tegwick 1c4b3c592c
All checks were successful
CI Smoke / host-smoke (push) Successful in 0s
CI Smoke / container-smoke (push) Successful in 1s
docs: accept ACT-ADR-006, profile-driven execution over the pull queue
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>
2026-08-21 13:57:48 +02:00

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-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-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-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 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

  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  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.

  • 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-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
  • docs/adr/adr-005-ops-runs-vs-dev-work-records.md
  • docs/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]