feat(curator): vendor the application backend as the scenario's tracked source

The curator Python backend (package, tests, systemd units, config templates, scripts) now lives under scenarios/curator/backend and is the single source of truth; the live checkout at the workspace path is a runtime copy. Exported from the app repo's tracked tree via git archive (no history, .pi/venv/caches excluded). 149 unit tests pass from the new location.

profile.toml backend is now repo-relative (scenarios/curator/backend); verify-generated.sh resolves a relative backend against REPO_ROOT. verify-no-secrets ASSIGN heuristic now requires value entropy so vendored kwargs like token=extraction_token no longer false-positive. README documents the backend/ layout and the operator-owned app rollout step.
This commit is contained in:
Kai
2026-08-30 18:49:10 -07:00
parent 14c97d88cf
commit 88b06d782f
57 changed files with 14236 additions and 9 deletions
+23 -3
View File
@@ -14,10 +14,23 @@ Verified against **pi 0.84.3**. Re-run the probes after every `pi update`.
| Scenario | Purpose | Service | Status |
|---|---|---|---|
| [`curator`](scenarios/curator/) | Book / film / TV / music curation agent | `curator.service` | target config written, **not yet deployed** |
| [`curator`](scenarios/curator/) | Book / film / TV / music curation agent | `curator.service` | **deployed**; agent config and application backend both tracked here |
| [`memo-inbox`](scenarios/memo-inbox/) | Routes Telegram/WeChat messages to Calendar, Obsidian todo or journal | `pi-memo-telegram.service` | **mirror** of live config, zero behaviour change |
| [`pi-grok`](scenarios/pi-grok/) | Interactive Grok 4.6 coding agent | none (manual) | registered only |
## Application code
A scenario that runs its own service keeps that service's source under
`scenarios/<name>/backend/` — for `curator`, the Python package, tests, systemd
units and config templates. It is the single source of truth; the live checkout
at the scenario's `workspace` path is a runtime copy.
`deploy-scenario.sh` installs only `workspace/` (the `.pi` config) and renders the
launch contract; it does not touch `backend/`, build a venv or restart a service.
Rolling application code out to the live checkout and restarting the unit stays an
operator step, deliberately: restarting decides when to interrupt a live
conversation.
## Start here
| Document | Contents |
@@ -79,6 +92,7 @@ scenarios/<name>/
profile.toml single source of truth for the launch contract
workspace/ what gets installed into the live workspace
eval/ recorded golden transcripts
backend/ application/service code, when the scenario runs its own service
scripts/ diff, deploy, backup, restore, secret guard
secrets/ host-local, untracked
```
@@ -111,8 +125,14 @@ Nothing real ever enters this repository. `models.json`, `auth.json`,
`trust.json` and every `*.env` are ignored; `secrets/` accepts only `.gitkeep`,
`README.md`, `*.example` and `*.template`.
`scripts/verify-no-secrets.sh` enforces this as a pre-commit hook. Install it in
a fresh clone:
`scripts/verify-no-secrets.sh` enforces this as a pre-commit hook.
Because a scenario's `backend/` now holds real source, the credential-assignment
heuristic requires the value to carry entropy (a digit or uppercase letter):
snake_case identifiers such as `token=extraction_token` are source, not secrets,
while base64/hex/random keys still trip it.
Install it in a fresh clone:
```bash
ln -sf ../../scripts/verify-no-secrets.sh .git/hooks/pre-commit