activity-core/docs/repo-automation-review-cli.md
tegwick 192942244e
All checks were successful
CI Smoke / host-smoke (push) Successful in 0s
CI Smoke / container-smoke (push) Successful in 1s
Build and Publish Container Image / build-and-push (push) Successful in 21s
feat(activity): multi-service config, make help default, install-cli
Bare make lists targets. make install-cli installs the activity tool via uv.
Named activity-core backends live in ~/.config/activity/services.json with
list/add/use/default/which; -s/--service selects one call without changing
the default; --activity-url is a one-shot override.
2026-08-06 17:25:54 +02:00

315 lines
12 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# Repo-scoped automation review CLI (`activity`)
**Status:** implemented (ACTIVITY-WP-0028) — v1 shipped 2026-08-06
**CLI name:** `activity`
**Related:** [runbook.md](runbook.md), [ops-run-queue.md](ops-run-queue.md),
[recurring-automations-playbook.md](recurring-automations-playbook.md),
[edge-relay-resilience.md](edge-relay-resilience.md),
[llm-connect-host-access.md](llm-connect-host-access.md)
**Origin:** Freedom Intelligence operator need (2026-08-06) — review scheduled
deliverables from the consumer repo without AI tooling.
---
## Rigorous review of the original concept
### What is strong (keep)
| Strength | Why it matters |
| -------- | -------------- |
| **Repo-first lens** | Operators live in consumer repos; org-wide `automation-status` is the wrong default UX for “did FI run?” |
| **Multi-source truth** | Git vs hub vs ops_run disagreement is real (FI 2026-08-06: brief on origin, hub event lag). Single-source answers mislead. |
| **Local checkpoint / ack** | “Since I last looked” is personal; belongs in XDG state, not State Hub or actcore DB |
| **Non-goals** | Not a scheduler, not an agent, not a workplan writer — keeps scope bounded |
| **Reuse stack** | Ops API + artefacts (WP-0027) + git + hub progress — no new backend product |
| **Exit codes for scripting** | Fits morning automation and CI-ish operator habits |
### What was weak or ambiguous (fix)
| Issue | Optimization |
| ----- | ------------ |
| Name `actcore-review` | Prefer **`activity`** — short, repo-native, pairs with domain “activity definitions”. Document collision with unrelated packages; ship as console script of `activity-core`. |
| Five overlapping verbs | Collapse to a **stable verb set** with clear precedence: `status` = compose; `list` / `runs` / `deliverables` / `inbox` = slices; `ack` / `checkpoint` = local state only |
| “~100200 lines wrapper” | Underestimates definition parsing, multi-source merge, and tests. Target a small **module package** under `activity_core/review_cli/` (~500800 LOC + tests), not a one-file hack |
| Deliverable globs unspecified | Require a **convention** in definition frontmatter or docs table; v1 ships FI + Binky built-ins + optional `review:` block |
| Collection candidates first-class | **Defer** to v2 — regex mining briefs is fragile; path-level inbox first |
| Exit code 3 always | **Opt-in** `--strict-review` only — default 0/1/2 keeps “green morning” scripts usable |
| Live API always assumed | **Offline-first ladder**: local defs + git always work; API/hub enrich when reachable |
| Checkpoint stores both commits and paths | Prefer **path + ops_run_id** as primary ack keys; commits are optional hints only (paths move less than SHAs across rebase) |
| Prod SSH helper as first path | Prefer **ops API** (`ACTIVITY_CORE_URL` / SSO-reachable host); SSH prod script is break-glass only |
### Verdict
**Concept is good.** Implement it as the **`activity` CLI**, activity-core owned,
consumer-cwd friendly, offline-capable, multi-source honest.
---
## Problem (restated)
From a **consumer repo** (e.g. `freedom-intelligence`), answer without AI:
1. Are regular automations declared / scheduled for this repo?
2. What is the list?
3. What ran or failed in a time window (today / week / since last review)?
4. What deliverables were produced?
5. What is still open for human review?
Evidence is split today: activity-core definitions/runs/ops_runs, State Hub
progress, git artefacts, ops UI. Existing tools are **activity-core-centric**,
not **repo-first**, and lack a personal review cursor.
## Non-goals
- New scheduler or claim worker
- LLM / coding-agent workflow
- Replacement for ops UI
- Hub writes for workplans/tasks (checkpoint is local only)
- Authoring definitions from the CLI
- First-class “collection candidate” inbox items (v2)
## Name and entrypoint
```bash
# Install (activity-core package)
uv tool install -e ~/activity-core # or pip install -e .
# → console script: activity
cd ~/freedom-intelligence
activity status
activity inbox
activity ack briefs/2026/08/2026-08-06.md
```
| Rule | Choice |
| ---- | ------ |
| Binary name | `activity` |
| Package | `activity-core` (`[project.scripts] activity = activity_core.review_cli:main`) |
| Default cwd | Consumer repo root (or any descendant) |
| Repo slug | `--repo` > git remote path > `.repo-classification.yaml` > directory name |
| Config | Named services in `~/.config/activity/services.json`; env still works |
| Collision | If another `activity` is on PATH, use `python -m activity_core.review_cli` |
### Multi-service endpoints
Operators may talk to more than one activity-core deployment (local stack,
railiance, …). Configure named services once; pick a default; override per call.
```bash
# userspace install
make install-cli
# register backends
activity service add railiance \
--url https://activity.coulomb.social \
--hub-url http://127.0.0.1:18000 \
--description "Railiance prod (SSO)" \
--make-default
activity service add local \
--url http://127.0.0.1:8010 \
--hub-url http://127.0.0.1:8000
activity service list
activity service use local # switch default
activity service which # what this shell would use
# one-shot without changing default (flags after the verb)
activity runs -s railiance --since today
activity status --activity-url http://10.43.x.x:8010
```
| Precedence (highest first) | Source |
| -------------------------- | ------ |
| 1 | `--activity-url` / `--hub-url` |
| 2 | `--service NAME` / `-s NAME` |
| 3 | `ACTIVITY_CORE_URL` / `STATE_HUB_URL` env |
| 4 | config file default service |
| 5 | unset (offline-only) |
Config path: `${XDG_CONFIG_HOME:-~/.config}/activity/services.json`
(or `ACTIVITY_CONFIG_DIR`).
Working name `actcore-review` is **retired** in favour of `activity`.
## Commands
| Command | Operator question | Evidence order |
| ------- | ----------------- | -------------- |
| `list` | What automations bind to this repo? | Local `activity-definitions/*.md` → ops API filter `target_repo` |
| `runs [--since …]` | What ran / failed? | Ops API runs+ops_runs → hub `executor_run` → degraded label |
| `deliverables [--since …]` | What was produced? | ops_run artefacts git globs hub completion paths |
| `inbox` | Open for review? | Deliverables since checkpoint ack set |
| `status` | One-screen dashboard | Compose list + runs + inbox counts + source health |
| `checkpoint show\|set\|clear` | Review cursor | Local state file only |
| `ack <path\|ops-run-id\|--all>` | Mark reviewed | Updates local state; no remote writes |
### Defaults
| Flag | Default |
| ---- | ------- |
| `--since` for `runs` / `deliverables` | `checkpoint` if set, else `today` (Europe/Berlin calendar day) |
| `--since` shortcuts | `today`, `yesterday`, `week`, `sunday`, `checkpoint`, ISO date/time |
| `--format` | `text` \| `json` |
| `--strict-review` | off — when on, exit `3` if inbox non-empty |
| `--repo` | auto-detect |
### Example session
```bash
cd ~/freedom-intelligence && git pull --ff-only
activity status
# Repo: freedom-intelligence
# Automations: 1 enabled (FI Daily Research Brief 30 7 * * 1-5 Europe/Berlin)
# Since checkpoint 2026-08-05T16:00+02:00
# runs: 1 ok, 0 failed deliverables: 1 new inbox: 1
# Sources: defs=ok git=ok api=ok hub=degraded
activity runs --since today
# 2026-08-06 07:30 ok ops_run=… path=briefs/2026/08/2026-08-06.md hub=missing
activity inbox
# [ ] briefs/2026/08/2026-08-06.md (partial: git ok, hub fi_daily_brief missing)
activity ack briefs/2026/08/2026-08-06.md
activity checkpoint show
```
### Exit codes
| Code | Meaning |
| ---- | ------- |
| `0` | No automation failures in window; sources not hard-failed |
| `1` | ≥1 failed run / failed ops_run in window |
| `2` | Evidence degraded (API/hub unreachable; partial answer printed) |
| `3` | Open inbox items remain (**only** with `--strict-review`) |
## Checkpoint model
**Local, operator-owned** — XDG state, not hub/DB.
```text
${ACTIVITY_REVIEW_STATE_DIR:-$XDG_STATE_HOME/activity}/<repo-slug>/checkpoint.json
# default XDG_STATE_HOME=~/.local/state
```
```json
{
"repo": "freedom-intelligence",
"schema": 1,
"reviewed_at": "2026-08-05T16:00:00+02:00",
"reviewed_paths": ["briefs/2026/08/2026-08-05.md"],
"reviewed_ops_run_ids": ["eeccd98a-bd2b-4247-9289-2bf17aa22301"],
"notes": ""
}
```
- Primary ack keys: **`reviewed_paths`**, **`reviewed_ops_run_ids`**
- `reviewed_at` advances on `ack` / `checkpoint set`
- No multi-host sync (v1)
## Resolving “for this repo”
1. **Declared (offline):** parse consumer `activity-definitions/*.md`
Match when `target_repo` == slug, or labels contain slug, or file lives in
that repos definitions tree.
2. **Live schedule:** `GET /ops/automations?target_repo=<slug>` (add filter if
missing).
3. **Runs:** `GET /ops/automations/{id}/runs?since=…` (artefacts from WP-0027);
optional `GET /ops-runs?target_repo=&since=`.
4. **Deliverables:** union of artefact paths, git globs, hub completion
`detail.path` for configured event types.
### Trust matrix (do not simplify away)
| Git artefact | Hub completion | Interpretation |
| ------------ | -------------- | -------------- |
| present | present | **ok** |
| present | missing | **partial** — produced; bookkeeping gap (warn, not “did not run”) |
| missing | present | **lag/mismatch** — pull remote / wrong clone / path drift |
| missing | missing | **missing** — did not run or failed before write |
Never answer “did not run” from hub-only absence when git has the artefact.
## Definition convention (v1)
Prefer optional frontmatter (when present):
```yaml
review:
deliverable_globs:
- "briefs/**/*.md"
completion_event_type: fi_daily_brief
path_in_event: detail.path # default
```
**Built-in fallbacks** (no frontmatter required day one):
| Repo / automation id | Globs | Completion event |
| -------------------- | ----- | ---------------- |
| `freedom-intelligence` / `fi-daily-research-brief` | `briefs/**/*.md` | `fi_daily_brief` |
| `binky-control` / binky daily rhythm | `briefs/**/*daily*` | `binky_daily_brief` (if used) |
Unknown automations: still list + show runs; deliverables only from
`ops_run.result.path` when present.
## Placement
| Layer | Role |
| ----- | ---- |
| `activity_core/review_cli/` | CLI + merge logic + checkpoint |
| Ops API | `target_repo` filters; runs already carry artefacts |
| `make activity-review …` | Thin Makefile pass-through (optional) |
| Does **not** replace | `automation-list`, `automation-status`, `prod_automation_status.sh` |
## Architecture
```text
activity status|list|runs|…
├─ resolve_repo(cwd, --repo)
├─ load_local_definitions()
├─ load_checkpoint(state_dir)
├─ try ops API (ACTIVITY_CORE_URL)
├─ try State Hub (STATE_HUB_URL)
├─ git log / path exists
└─ merge → trust matrix → text|json + exit code
```
### Minimal phases (implementation)
| Phase | Deliverable | Offline? |
| ----- | ----------- | -------- |
| **P0** | `list` + `status` (defs only) + `--json` | yes |
| **P1** | `deliverables` + `checkpoint` + `ack` + `inbox` (git + checkpoint) | yes |
| **P2** | `runs` + hub completion join + trust matrix | partial |
| **P3** | Live API `target_repo` filter + full green/partial rows | needs URL |
| **P4** | Docs, Makefile, install path, FI morning ritual in playbook | — |
## Open decisions — locked for WP-0028
| # | Decision | Lock |
| - | -------- | ---- |
| 1 | Package location | **activity-core** console script `activity` |
| 2 | Exit code 3 | **Opt-in** `--strict-review` |
| 3 | Deliverable declaration | Optional `review:` frontmatter + built-in table |
| 4 | Collection candidates | **Out of v1** |
| 5 | Default evidence | Offline-first; API enriches |
| 6 | Ack keys | paths + ops_run ids (not commits alone) |
## Relationship to existing tools
| Tool | Role after `activity` ships |
| ---- | --------------------------- |
| `make automation-status` | Org/cluster window (unchanged) |
| `prod_automation_status.sh` | Prod SSH fire counts (break-glass) |
| ops UI | Browser review + trigger/pause |
| **`activity`** | Consumer-repo morning review + personal checkpoint |
## Pin log
| Date | Change |
| ---- | ------ |
| 2026-08-06 | Concept captured (actcore-review working name) |
| 2026-08-06 | Rigorous review; rename to `activity`; optimize scope; WP-0028 |