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.
302 lines
14 KiB
Markdown
302 lines
14 KiB
Markdown
---
|
|
domain: capabilities
|
|
repo: activity-core
|
|
updated: "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 attraction** — `TaskExecutorWorkflow` 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.
|
|
|
|
---
|
|
|
|
## Related / Overlapping
|
|
|
|
- `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
|
|
|
|
```capability
|
|
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]
|
|
```
|