Redline experiment plan
- Status: active plan, 2026-10-10; amended 2026-10-10 (Stage 1 standalone, B6; YYZ deferred to Stage 2)
- Owner: Fridai Engineering
- Executor: an automated coding agent working task by task (see protocol.md)
- Verifier: a senior reviewer checks the destination gate when STATUS.md shows every task done
This is the entry point. Read it top to bottom once, then follow the protocol.
The bet
Readers of an evolving knowledge base will review changes in short bites on the rendered page, and will not go to GitLab to do it. Git stays the geological record: every action a person takes on the page ends as a commit or a GitLab note, attributed to that person’s GitLab identity. GitLab’s discussion layer is the comment store for this experiment because it is free; nothing in this plan may harden around that choice.
GitLab’s discussion layer is the first comment store because it is free. If its model blocks a capability, the executor may hold comments in an interim schema inside the service, as long as a task propagates them down to GitLab or git before the experiment reads its results. The same freedom applies to the identity layer: GitLab OAuth is the first choice, not a constraint. See the protocol’s “Freedom to refactor”.
The thesis is tested by three capabilities on a rendered page:
- Inline redline. One open merge request shown as Word-style tracked changes inside the rendered text, not as a side list of operations.
- Changed since. Which blocks of this page changed since a revision the reader picks, or since their last visit.
- Anchored comments. Select text, leave a comment, see it attributed to your GitLab user, reply and resolve without leaving the page.
Everything else in the service (drafts, approvals, merge) stays off.
Stages
The experiment runs in two stages, modelled on how the Markdown Renderer
(fio-design-markdown-renderer) proved itself at lcy.fio.sh before YYZ
adoption counted as done. See design/standalone.md.
- Standalone (this plan’s destination). Redline serves its own dashboard
and knowledge base beside its API on one origin, on the tailnet, in a QA
and a production environment, and is proven there against real GitLab with
this repository’s
kb/as content (batch B6). - Adoption in YYZ (deferred). YYZ’s pages now come from kb-packages, which carry neither build-time history nor block ids, so B5 waits until that compatibility work is planned (tech debt TD-002 to TD-004).
Destination
The plan is complete when every check in batches/G-destination.md passes. The gate is deterministic: named unit tests, named Playwright specs, a benchmark bound on git invocations, a contract validation, a green pipeline, and the standalone service deployed on the private network in QA and production with recorded evidence, including one real merge request shown inline and one real comment attributed in GitLab. Each check lists the exact command and the exact expected output.
The business outcome (do people actually use it) belongs to Stage 2: it is
measured thirty days after YYZ adoption by scripts/experiment-report.js.
That is the kill criterion, not a build gate.
The task graph
Tasks are grouped in batches by subject. Dependencies cross batches, so execute by wave, not by batch. A wave contains tasks whose dependencies are all done. Tasks inside a wave are independent and may be done in any order.
| Wave | Tasks |
|---|---|
| 1 | T0.1 mock GitLab · T0.2 fixture site · T0.4 identity mode · T0.5 health and reachability · T0.6 verify rulesets · T1.1 benchmark harness · T2.1 share semantic module |
| 2 | T0.3 Playwright harness and CI job · T1.2 build-time index · T2.2 remark block ids · T2.3 block history · T2.4 failure classification · T2.6 word diff |
| 3 | T1.3 warm index cache · T1.4 enrichment from the index · T2.5 contract tests · T3.0 shared store · T3.2 remove browser dialogs · T4.1 experiment deployment config |
| 4 | T3.1 reachability states · T4.2 smoke script · T4.5 experiment report |
| 5 | T3.3 OAuth connect · T3.5 inline redline · T3.6 changed since · T4.3 operator setup (human) |
| 6 | T3.4 anchored comments |
| 7 | T6.1 dashboard site · T6.3 QA environment · T6.6 lifecycle records |
| 8 | T6.2 service serves the dashboard |
| 9 | T6.4 dashboard end to end · T6.5 live smoke spec |
| 10 | T6.7 QA and production deployment and evidence (human) · T6.8 timeline scrubber · T6.9 comments in the text |
| 11 | G destination gate |
Deferred to Stage 2: T4.4 (replaced by T6.7), T5.1, T5.2.
Batch files:
- B0 Foundations: mock GitLab, fixture site, Playwright, identity mode, reachability.
- B1 Build-time index: one git pass per build instead of one per page.
- B2 Semantic and schema: shared block model, rendered block ids, block history, contract.
- B3 UX: the three thesis capabilities and the network states, proven with Playwright.
- B4 Network: Tailscale-only deployment, smoke, measurement.
- B5 YYZ: the consuming site (deferred to Stage 2).
- B6 Standalone: dashboard and API on one origin, QA and production, live evidence.
- G Destination: the gate.
Design specs the tasks cite:
- design/network.md: topology, cookie and CORS constraints, the three failure states.
- design/state-machine.md: data schema additions and the client state machine with exact message strings.
- design/build-index.md: the single-pass history index algorithm.
- design/fixture-data.md: the canonical mock repository every test asserts against.
- design/standalone.md: Stage 1, the standalone dashboard, its artifact and environments.
Progress is recorded in STATUS.md. Blockers go in BLOCKERS.md
beside it (create on first use).
What this plan deliberately leaves out
- Cloudflare Access and Tunnel. The experiment runs on the Tailscale network. The existing Access code path stays and stays tested; it is not deployed.
- Drafts, approvals and merge. The code stays;
features.editing,features.approvalsandfeatures.mergingare false for the experiment site. - Release-channel mechanics, badge, runbook and kb-package polish. No task
changes them; B6 only consumes the existing
verifiedandreleasedchannels (QA tracks one, production the other).
Nothing else is out of bounds. Code shape, module layout, the Dockerfile, the identity mechanism and the comment schema may all change if the experiment needs it.