--- 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 --- # 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: todo priority: high ``` 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. ### T02 — Publication decision record ```task id: FI-WP-0005-T02 status: todo priority: high ``` `docs/decisions/2026-09-XX-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. ### T03 — Machine-readable source host list ```task id: FI-WP-0005-T03 status: todo priority: high ``` `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. ### T04 — activity-core handoff: grant v2 publication + generic due resolver ```task id: FI-WP-0005-T04 status: todo priority: high ``` 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. ### T05 — glas-harness handoff: `harness.fi-research-brief@1.0.0` ```task id: FI-WP-0005-T05 status: todo priority: high ``` 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. ### T06 — Retire the break-glass host timer ```task id: FI-WP-0005-T06 status: todo priority: medium ``` 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). Confirm the timer is absent on railiance01 (`not-found` on 2026-09-22). 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. ### T07 — Disabled canary definition ```task id: FI-WP-0005-T07 status: todo priority: high ``` 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 ``` 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. ## 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