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
285 lines
12 KiB
Markdown
285 lines
12 KiB
Markdown
---
|
||
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 A–D,
|
||
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 A–D.
|
||
`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
|