# mgf-fed-web — build kickoff brief

**From:** Bassam · **To:** the implementer (Claude Code, local) · **Status:** handoff — last design round closed
**Read with:** `mgf-fed-web_spec_v0_1.md` (the authoritative contract) and `mgf-fed-web_dashboard_wireframe.html` (the reference prototype — open it; the behaviour is real, the data is mock).

---

## 0. TL;DR

The ecosystem keeps growing — Soothfast, Soothsmith, sooth-standard, the sites — and I need **one reliable, accurate, clear place where a human and an AI can stay in sync about it.** That's what mgf-fed-web is: a federated, read-mostly web view where, **per project**, I can see real status, the end-to-end roadmap, what's in progress, what's stalled and why, what's most valuable to do next, and what's waiting on a decision — and where feedback flows in rounds between me and you.

The one rule that makes it trustworthy: **the web is not a new source of truth.** Each project *generates* a schema-governed set of resources from its own real artifacts; the web only *composes and displays* them, and labels anything it computes itself as `derived`. No room for either of us to assume.

This is the build handoff. The spec is the contract; this brief is the why and the shape. Where I haven't decided something, it's a numbered confirm-line in spec §7 — raise concerns through the same feedback loop and commit to the answer.

---

## 1. Vision & scope

- **Is:** a federated dashboard that renders an accurate, printable, end-to-end picture per project and across all of them; a rounds-based feedback channel between human and AI; and a real-time view of what a project is doing right now.
- **Is not:** a place where project state is authored. The web never invents project facts. It reads what each project reports and tags what it derives.
- **Read/write split:** **read-only for project state.** The only output beyond display is **non-operative feedback** — actionable text delivered into a project's `feedback/` inbox. It changes nothing on its own; acting on it happens in the project, with that project's agent.
- **For both of us:** this is explicitly a human↔AI communication surface. You report through `generated/`; I respond through `feedback/`; we both watch `live/`. The clarity of that loop is the product.

---

## 2. Three channels, separated by nature

Every project carries a `fed-resources/` directory. It has **three** subtrees governed by **different** rules — keeping them separate is what keeps the whole thing honest.

```
<project>/fed-resources/
  manifest.json          # anchor: source commit + per-file hashes; covers generated/** ONLY
  generated/             # DURABLE state · schema-versioned · committed · freshness-GATED · project→web
    status.json roadmap.json architecture.json focus.json suggestions.json
    runs/<id>.json       # run-records: the verifiable "what happened" from a traced op
  feedback/              # AUTHORED · rounds-keyed · the generator NEVER writes here
    rounds/v<N>/feedback.json   # inbound:  my direction & questions
    rounds/v<N>/response.json   # return:   your answer + concerns (closes the loop)
  live/                  # EPHEMERAL activity · gitignored · NEVER gated   ← real-time
    CURRENT  sessions/<id>.ndjson
```

- **`generated/` — generated, not asserted (non-negotiable).** Produced by a per-project generator from real artifacts; never hand-edited. Each project ships a **freshness gate**: `regenerate → assert byte-identical to what's committed`. If it would differ, the gate **fails** — staleness is never a silent pass. This is what makes "never out of sync" real instead of aspirational.
- **`feedback/` — authored, two-way, non-operative.** My feedback and your responses, in numbered rounds. The generator is forbidden from touching it.
- **`live/` — ephemeral telemetry.** Append-only event logs from traced operations. Gitignored, never gated, never confused with provenance. Detail in §5.

---

## 3. The lenses — how it answers my actual questions

I don't think in "data files," I think in questions. So the UI is **lenses**, and each lens is a question that runs **at either scope** — one project (a tab) or all projects combined (the federation overview) — with the same render code. These map 1:1 to what I asked for:

1. **Roadmap** — the whole arc: where we started, what's done, where we are now ("you are here"), what's left — as a chain **plus a table** carrying **risk · effort · eta · dependency · owner** per stage. ("Cost" = two fields: `effort` as T-shirt size, `eta` as calendar — keep them separate.)
2. **In progress** — what's in flight now, with age and owner. **Plus a live mode** (§5).
3. **Stalled** — what's started but not finished, **with the reason and how long it's been stuck.** A stalled item missing a reason is itself flagged.
4. **Next best** — the most valuable thing to do next, **with the why shown**: impact, how much it unblocks, readiness, effort. It's a `derived` ranking over reported facts, and it must stay honestly *actionable* — a high-priority item that's blocked by dependencies is shown separately as "clear this blocker," not as "do this now."
5. **Decisions** — what's waiting on me: founder-owned items, anything you marked needs-clarification, open rounds. Combined across projects, this is my one worklist.
6. **Changed** — catch me up: the delta since the last snapshot, plus run-records from finished traced ops.
7. **Coupling** — what each project consumes from a sibling (e.g. Soothsmith imports the kernel's `canonical_json`) and when an upstream change should trigger a downstream check. Declared in `federation.json` — fact, not inference.
8. **Architecture** — the project's *own* diagram, projected, never redrawn. Overview also gets a **Risk register** and **Critical path**.

---

## 4. "In sync" has one definition

In sync = regenerating `generated/` from current source yields **byte-identical** output. The manifest anchors it (source commit + per-file hashes). Two checks: **shallow** (hashes + `source_commit == HEAD`, instant) and **deep** (`regenerate → assert no diff`, authoritative, non-mutating). States are first-class and never blank: `IN_SYNC · STALE · TAMPERED · UNKNOWN · UNREADABLE · CHECKING · SYNCING · ERROR`. Global sync is the aggregate. The project exposes this through a small CLI — `fedres status` / `check` / `generate` (+ the traced `run`, §5) — or make-targets; that's the only contract surface between web and project (spec §2). Topology is local-disk now, PyPI packages later, behind a `SourceProvider` seam so the web code doesn't change when that flips.

---

## 5. Live activity (real-time) — follow, don't command

I want to watch progress and actions on a project in real time, browse them, and see the active session's history. The design (spec §4A):

- **A traced op emits an event stream** (`session_start · step · progress · log · gate · artifact · session_end`) as append-only NDJSON into `live/`. The web **tails** it. The file *is* the record, so a dropped poll loses nothing; push is a later latency optimization, not the foundation.
- **The web follows; it never commands.** It's read-only on state and, in package mode, can't reach into a project at all — so it can't *make* a project go live. It **discovers** an active session and lights a `● live` marker; the button is **"Follow live."** A session starts when the project runs `fedres run <task> --trace`. (A local-dev-only "web triggers a run via a watch daemon" path is optional — confirm D-LIVE-1; it can't survive package mode.)
- **Live ≠ provenance.** The stream is ephemeral telemetry, gitignored, **never gated**, and wears a distinct `telemetry` tag. Its durable shadow is a committed, gated **run-record** in `generated/runs/` — *that's* the verifiable "what happened," and it feeds Changed. If the live tail breaks, the sync surface stays untouched. This separation is deliberate: real-time makes this part-monitor, and a monitor's flakiness must never erode trust in the provenance part.
- **In the UI** it's a **mode on the In-progress lens**, not a separate firehose: current step, live progress, last-event age, latest log, an expandable session timeline, Play/Pause, and honest idle/ended states. The prototype simulates a full session end-to-end — open it and hit "Start traced run (sim)" on Soothfast.

---

## 6. On the horizon (not v1 — noted so it shapes v1)

- **Mobile app (later).** A simpler companion, not a port: **one project per request** (no federation grid — pick a project, page through its lenses), and **device notifications** for the things that matter — sync drift, a stalled item missing a reason, a round answered, a live session ending ok/fail, an upstream-coupling trigger. Those map directly onto the live event kinds + sync states, so a small push relay watching `generated/` + `live/` is all it needs — which is *why* I want the event kinds kept stable now. Don't design it yet; just don't paint us into a corner.
- **Live push (later).** Swap poll/tail for SSE/`watch` so events arrive sub-second. Layered on §4A, never underneath it.

---

## 7. Non-negotiables

Generated-not-asserted + freshness-gated; one versioned symmetric schema with a version-aware reader; **honest-absence** everywhere (no blanks, no stale-shown-as-current, no guesses — `UNKNOWN`/`UNREADABLE`/"stream idle" are real values); **no second source of truth** (the architecture view projects the project's existing visual model, never redraws it); **read-only for project state**, feedback is non-operative and produced-then-delivered (no auto-commit into a governed repo); the live channel is **never** gated and **never** styled as provenance; everything printable; anything the web computes is tagged `derived`.

---

## 8. What I need you to confirm before/while building

All in spec §7 — the ones most likely to bite: the CLI surface (`fedres` binary vs make-targets, **D-SYNC-1**); force-sync on a governed repo (regenerate-only vs allow `--commit`, **D-SYNC-2**); working-tree vs committed read in local mode (**D-SYNC-3**); the `effort` convention — T-shirt vs points (**D-COST-1**); and whether to build the local-only "web triggers a traced run" daemon at all (**D-LIVE-1**). Build the milestones in order (spec §6: M0 schemas+validator → M6 live activity → M7 package mode); each has an acceptance bar. Raise concerns through `agent_raised` and commit to the resolution. Dogfood it on mgf-fed-web itself first.
