freedom-intelligence/workplans/FI-WP-0005-profiled-brief-execution.md
tegwick de285be742 Record recovery of stranded 2026-09-15..22 briefs and the rein push fix.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>

Assistant: claude-code
Assistant-Model: opus
Assistant-Process: 51320@bnt-lap001
Assistant-Session: 9d40b4c7-8e3c-42ee-b755-d658d4640d6c
2026-09-22 16:26:43 +02:00

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

---
id: FI-WP-0005
type: workplan
title: "Move the daily brief to a profiled, granted execution on activity-core infrastructure"
domain: agents
repo: freedom-intelligence
status: active
flavor: implementation
owner: claude
topic_slug: freedom-intelligence
priority: high
created: "2026-09-22"
updated: "2026-09-22"
depends_on:
- FI-WP-0004
related:
- REINAH-WP-0003
- ACT-ADR-006
- ACT-ADR-007
- ACTIVITY-WP-0032
- ACTIVITY-WP-0038
state_hub_workstream_id: "00f3ba5e-270d-559d-afb6-8b382507c902"
---
# FI-WP-0005 — Profiled brief execution
## Origin
rein-aharness message `d0b45acb` (2026-09-04, REINAH-WP-0003-T04): profile-absent
routing now depends on `AGENT_HARNESS_LEGACY_APPROACHES_UNTIL` (example expiry
**2026-12-31**). FI must supply an owner-approved replacement for
`fi-daily-research-brief`: a versioned profile, input schema, allowed paths,
completion evidence, model route, rollback pin and a separate publication
decision. FI replied 2026-09-22 (`74afc283`): FI-WP-0004-T04 already removed
the swallowed push failure; the declaration follows this workplan.
## Decisions (operator, 2026-09-22)
1. **Publication is generic infrastructure.** Request a repository-grant v2
in activity-core with a typed publication field. Do not keep the push as an
FI-specific rein capability.
2. **Execution shape B.** The brief runs as an agent under a versioned Glas
profile. Its sandbox can reach only the model route and the FI source
hosts. The current single llm-connect call writes from model memory, and
that caused the V4-Flash mis-sizing.
3. **Generic due check now.** Propose to activity-core replacing the
FI-specific `fi_brief_status` resolver with a parameterised
published-artifact resolver. FI is the first user.
4. **Break-glass host timer:** retire it (T06, rationale below).
## Responsibilities
| Layer | Owns for this job | Does not own |
|---|---|---|
| freedom-intelligence | Definition, inputs, allowed paths, quality rules, source host list, publication decision, durability verifier, canary acceptance | Scheduling code, profile catalog, sandboxes |
| activity-core | Schedule, due resolution, `ops_run` emission carrying `harness_profile_ref` + `repository_grant`, grant validation, close reconciliation and evidence | Executing anything (ADR-006 §4); the profile catalog |
| glas-harness | Profile `harness.fi-research-brief`: rein, sandbox, tool profile, model route, limits, rollback pin | What the brief says; when it runs |
| sand-boxer | Isolation and the per-host HTTPS egress allowlist (`docs/bwrap-egress.md`) | Which hosts FI needs |
| rein-aharness | Inner loop; grant enforcement (paths, commits, publication); drops label routing and Binky model env fallbacks | Publication policy |
Reused as-is: `harness_profile_ref` (WP-0032), grant v1 path and commit
validation plus close reconciliation (WP-0038), profile version pinning as
rollback. Gaps: grant v1 rejects `publish: true`; `fi_brief_status` is
tenant-specific code in shared infrastructure; no Glas profile allows
network egress beyond a model provider.
## Tasks
### T01 — Owner declaration v1
```task
id: FI-WP-0005-T01
status: done
priority: high
state_hub_task_id: "bf8c1870-bdca-51d6-beaf-c5f000037205"
```
Write `activity-definitions/fi-daily-research-brief.declaration.yaml` (or an
equivalent section in the definition) stating: input set (files and prior
brief window), output path `briefs/YYYY/MM/YYYY-MM-DD.md`, allowed paths,
commit count (exactly 1), completion evidence (`fi_daily_brief` with
`pushed=true`, `origin_sha`, path, date), required model class and tool use,
quality rules (catalog is the authority, no invented sizes, no re-announce),
publication policy (reference T02), and rollback. No Binky-named env vars.
**Done when:** the declaration is committed, and every field rein listed in
`d0b45acb` maps to a concrete value or to a named follow-up task here.
**2026-09-22:** Done. `activity-definitions/fi-daily-research-brief.declaration.yaml`
(status `proposed`). It covers profile ref (pending T05), inputs, outputs, grant
(its v1 fields validate against activity-core `RepositoryGrant`; publication pending
T04), quality rules, model requirements without env selection, completion
evidence and rollback pins. `scripts/test_declaration.py` checks it. Open
operator question: whether a pinned agent executable inside the Glas sandbox
satisfies the playbook's "no Claude Code / Codex on railiance01" rule.
### T02 — Publication decision record
```task
id: FI-WP-0005-T02
status: done
priority: high
state_hub_task_id: "25475ede-ebd9-5c31-8c22-718e30acf8ac"
```
`docs/decisions/2026-09-22-brief-origin-publication.md`: FI grants
fast-forward-only publication of `briefs/**` to `origin/main`; no force, no
other refs; publication failure fails the run and leaves the day due. Supersedes
the implicit grant wording in FI-WP-0004-T04.
**Done when:** the decision is committed and cited by T01 and T04.
**2026-09-22:** Done. Adds a single rebase-and-retry on non-fast-forward;
it never merges or forces. Cited by the declaration and the activity-core
proposal `8ee9a6ab`.
### T03 — Machine-readable source host list
```task
id: FI-WP-0005-T03
status: done
priority: high
state_hub_task_id: "9b92d7f4-f4c8-5ce5-9367-462653515e90"
```
`docs/sources-allowlist.md` is prose with no hostnames. Derive an exact
`host:443` list (lowercase, no wildcards, per sand-boxer rules) for axes AD,
kept beside the prose list and checked by a small test so the two do not
drift. Keep it minimal. Egress is enforced by destination only, not by
path, so every host is a trust decision.
**Done when:** the list is committed with a test, and the host count and the
rationale for each host are recorded.
**2026-09-22:** Done. `docs/sources-egress.yaml` has 17 hosts covering axes AD.
`scripts/test_sources_egress.py` checks sand-boxer format, the 24-host cap and
that each channel is named in the prose allowlist. A live check replaced
redirecting hosts (docs.anthropic.com → platform.claude.com, lmarena.ai →
arena.ai). openai.com and x.ai return 403 to plain clients, which is noted.
### T04 — activity-core handoff: grant v2 publication + generic due resolver
```task
id: FI-WP-0005-T04
status: progress
priority: high
state_hub_task_id: "d679352f-8b0d-5ca5-9e42-4173ed87f48a"
```
Request (hub message to activity-core, not tasks registered here):
- **Repository grant v2.** v1 fields plus `publication: {remote, ref,
mode: fast-forward-only}`. Validated at definition sync and emission
preflight. Close reconciliation requires matching `origin_sha` evidence
when publication is granted; publication failure is a failed close, not
a success. Needs an ADR amendment and agreement with rein-aharness
(ADR-002).
- **Published-artifact due resolver.** Parameters: repo, path template, ref,
timezone, completion event type. Due is true unless the artifact exists on
the remote ref *and* a matching event reports `pushed=true`.
`fi_brief_status` becomes a thin alias, then is retired.
**Done when:** activity-core acknowledges with its workplan id(s), and the
agreed grant v2 schema revision is recorded here.
**2026-09-22:** Proposal sent to activity-core (`8ee9a6ab`). Awaiting reply.
### T05 — glas-harness handoff: `harness.fi-research-brief@1.0.0`
```task
id: FI-WP-0005-T05
status: progress
priority: high
state_hub_task_id: "e1d0bacd-b93d-50d5-b07d-e950e96443dc"
```
Request a profile: rein `rein-aharness`, unattended; bwrap sandbox with
`network.egress` = model route + the T03 hosts, `default: deny`; a tool profile
that can write only the granted paths and may publish only under a grant;
model route and limits per T01; `operational_readiness` evidence; documented
rollback pin. Blockers are the sand-boxer and Glas owner-auth items
(SAND-WP-0015-T04, GLAS-WP-0012-T02). Track them, do not work around them.
**Done when:** the profile exists at a pinned version with a positive
readiness proof in a sandbox run.
**2026-09-22:** Request sent to glas-harness (`c7f2df46`), including the
host-install question. Awaiting reply.
### T06 — Retire the break-glass host timer
```task
id: FI-WP-0005-T06
status: done
priority: medium
state_hub_task_id: "69abf6cf-95af-51b2-8874-120f30cb4b0a"
```
Delete `scripts/railiance-rhythm/systemd/*`, `install-on-railiance.sh` and
`run-daily.sh` (keep `run-common.sh` only if it is still referenced). Replace
`docs/recurrence-ops.md` and playbook references with a manual one-shot
recovery command, valid until the legacy expiry, and the post-cutover
rollback (T08). Remove the timer from railiance01.
Rationale: the timer is a second scheduler outside activity-core. It runs
the profile-absent legacy command with no grant, and its installer runs
`enable --now`. After cutover it would bypass the profile and grant, and
after the legacy expiry the command it calls stops working. A missed day
costs little: due stays true, the verifier records the gap, and a catch-up
brief closes it (FI-WP-0004-T05 precedent).
**Done when:** the files are removed, the docs name the one-shot command and
the profile-pin rollback, and the host has no FI timer.
**2026-09-22:** Done. The earlier "not-found" check used the wrong unit names.
`fi-research-brief-daily.{timer,service}` were installed but disabled and had
never fired (`LastTriggerUSec` empty). They are now removed from
`~/.config/systemd/user` and systemd has been reloaded; no FI brief unit remains. The whole
`scripts/railiance-rhythm/` directory is deleted (`run-common.sh` had no other
caller). `docs/recurrence-ops.md` documents the manual one-shot
(`~/bin/rein-aharness-claim fi-research-brief --target-repo ... --date ...`)
and the post-cutover rollback.
### T07 — Disabled canary definition
```task
id: FI-WP-0005-T07
status: todo
priority: high
state_hub_task_id: "fd22b96d-39f0-53fd-9cdf-7bd29e758c54"
```
After T04 and T05: add a disabled, operator-triggered canary definition
(pattern: activity-core `glas-profile-pilot`) carrying `harness_profile_ref`,
grant v2 and the generic resolver, targeting a controlled date. Compare the
output with the compatibility executor on the same inputs. Run
`scripts/verify_brief_durability.py --require-date` on the canary day.
**Done when:** one canary brief is on `origin/main` with grant, acceptance
and `origin_sha` evidence reconciled by activity-core, and the comparison is
recorded in `docs/evidence/`.
### T08 — Cutover, rollback proof, reply to rein
```task
id: FI-WP-0005-T08
status: todo
priority: high
state_hub_task_id: "3bd365ad-7e9c-54cc-ad2b-e1cbbf525636"
```
Move `fi-daily-research-brief` to the profiled definition; ask rein-aharness
to remove the FI label route and `fi_research_brief` compatibility path.
Exercise rollback once: pin the previous profile version or revert the
definition revision, and show that the due and evidence behaviour holds.
Reply on thread `d0b45acb` with the definition revision, profile version,
grant schema revision, and canary and rollback evidence.
**Done when:** at least five consecutive weekday briefs have run on the
profiled path, and rein confirms that FI no longer needs
`AGENT_HARNESS_LEGACY_APPROACHES_UNTIL`. Target: before 2026-12-01.
## Incident found during T06 (2026-09-22)
Briefs for 2026-09-15 to 2026-09-22 were stranded on railiance01 because
every push was rejected non-fast-forward. They are recovered, and the root cause
is fixed in rein-aharness `294201a` (the T02 rebase-once rule, now also on the
compatibility path). Details: `docs/brief-durability-audit.md`.
## Risks
- **Owner-auth blockers in sand-boxer and Glas** may not clear before
December. Decision point on 2026-11-15: ask rein for a dated FI-only
legacy extension. Do not fall back to shape A silently.
- **Egress is enforced by host, not path.** A broad source host is a broad
channel, so keep T03 minimal.
- **Cross-repo contract change.** Grant v2 touches activity-core,
rein-aharness and ADR-002; schedule slips there move T07.
## Out of scope
- Changing brief content, template or axes
- Reserve collection (FI-WP-0004 residuals: restore readback, scoped IAM key)
- Other tenants' migrations (Binky etc.), except as consumers of the generic
grant and resolver