ADR-125 — Four product-surface substrates: Heed, Brief, Ramp, Vie
Status: Proposed (2026-05-02) Decider: Operator Supersedes: none — extends ADR-079 (operational-approval substrate), ADR-092 (host/project separation), ADR-094 (bundle-compose-in-GHCR), ADR-107/108/109 (gates as playbook primitives)
Context
The factory has accumulated rich SIGNAL — the agent-reports journal (warp#246), structural-check verdicts, persona-review outcomes, the curator's blocking findings, deploy-events, probe-status, validate-projects results — but the consumption surfaces are passive. /operate aggregates if the operator looks. /infra renders if the operator clicks. There is no PUSH, no SCOPED ROUTING, no ESCALATION, no DAILY DIGEST, no STAGED DEPLOY, no VARIANT-COMPARISON DECISION SUPPORT.
For the 50-product fleet target (project_factory_principle_50_products.md), four distinct PRODUCT-SURFACE concerns surfaced in operator vision-setting on 2026-05-02:
- Push events with guidance — alerts that escalate, link to playbooks, and respect role/scope (warp#944 Heed)
- Calm daily insight — area-scoped digest with future delegation (warp#945 Brief)
- Staged deploys with monitoring — canary→stable with auto-promote/rollback (warp#946 Ramp)
- Variant comparison with decision — A/B testing with statistical significance gating (warp#947 Vie)
These are NOT four independent products. They share substrate, they share the operator's vocabulary, and they sit on top of the existing factory primitives (warp queue, playbook runtime, deploy substrate, signal collection). This ADR captures the shared design contract so the four epics can be implemented in a coordinated way.
Decision
Build all four as first-class product surfaces of the factory, sharing four substrates:
Substrate 1 — User / role / area (Heed Phase 1; reused by Brief, Vie scope filtering)
- Postgres tables:
users,roles,subscriptions(user_id × area_pattern) - Roles:
operator(sees all),area_owner(sees their areas),on_call(rotation) - Area patterns: regex against warp item
repo+tags - Bare-minimum schema; expand only when 3rd consumer demands richer
Substrate 2 — Channel-out abstraction (Heed Phase 3; reused by Brief)
- Per-user
channel_prefstable:user_id × channel_type × address × severity_threshold - Initial channel: email (Resend or SMTP)
- Future channels: Slack, SMS, push — added as needed
- Delivery log table for audit + retry
Substrate 3 — Inference / guidance engine (Heed Phase 5; reused by Brief)
- Service location: a new internal package (e.g. internal/insight/) — Heed Phase 5 selects the exact path
- Inputs: any factory-state slice (alert payload, daily window, experiment data)
- Outputs: ranked structured suggestions, drawn from:
- Playbook tag-matching (Jaccard score)
- Finding journal grep (recency-weighted)
- ADR tag-map (curated)
- Persona-review history (gh search)
- 5-minute TTL cache
Substrate 4 — Real-time signal collection (Ramp Phase 3; reused by Vie)
- Per-host metrics endpoint:
GET /api/v1/infra/host/<name>/signals?since=<ts> - Per-experiment metrics endpoint:
GET /api/v1/vie/<exp>/metrics?since=<ts> - Time-series of error-rate / p99 / e2e / variant-event-counts
- 5s polling during canary + experiment runs; 60s otherwise
Naming
All four are single-syllable native verbs in the operator's tone register:
| Subsystem | Verb meaning | URL | CLI shape |
|---|---|---|---|
| Heed | heed the alert | /heed | heed --ack <id> |
| Brief | brief / be briefed | /brief | brief --area <name> |
| Ramp | ramp up / ramp down | /ramp | ramp deploy <project> |
| Vie | variants vie for the win | /vie | vie start <experiment> |
Operator-call on each name; the alternatives are listed in each epic ticket.
Dependency graph
┌─────────────┐
│ Substrate 1 │ user/role/area
│ (Heed P1) │
└──────┬───────┘
│
┌────────────┼────────────┐
│ │ │
┌─────▼─────┐ ┌───▼────┐ ┌────▼────┐
│ Heed │ │ Brief │ │ Vie │
│ P2-P7 │ │ all │ │ scope │
└─────┬─────┘ └────┬───┘ └────┬────┘
│ │ │
└─────────────┴───────────┘
│
┌─────────▼─────────┐
│ Substrate 4 │ signal collection
│ (Ramp P3) │
└─────────┬──────────┘
│
┌─────────▼──────────┐
│ Vie metrics + │
│ Ramp soak monitor │
└────────────────────┘
Heed Phase 1 is the substrate gate. Once it lands, Brief / Ramp / Vie can phase in parallel.
Consequences
Positive
- Four product surfaces ship with shared foundations (no per-subsystem rebuild of user model, channel abstraction, inference, signal collection)
- Operator vocabulary stays consistent (single-syllable verbs across CLI + URL + dashboards)
- The factory becomes RESPONSIVE (push, escalate, decide) instead of merely OBSERVABLE
- 50-product fleet target gets the substrate (per-area scope, per-product variant testing, per-host canary)
- Off-the-shelf integration cost (PagerDuty + Statsig + Argo Rollouts + custom digest) ≈ 70% of build cost AND fragments the operator's vocabulary
Negative
- Significant scope expansion. ~10000-15000 LoC across the four epics. Multi-week serial; weeks-parallel
- Naming conventions are operator-call; if operator changes mind on names mid-build, rename cost is moderate (mostly URL + CLI surface)
- Substrate decisions (Phase 1 user model, channel abstraction) bake in early; later subsystems must conform
Mitigations
- ADR (this doc) captures the substrate decisions before any phase ships, reducing rework
- Each subsystem's Phase 7 is a smoke test gating MVP — incremental validation
- Naming is reviewed as part of each epic's Phase 0 ADR, not bolted in mid-build
- Substrate Phase 1 (user/role/area) ships with a "minimum-viable" 3-role model; expansion is additive
Sequencing recommendation
- Heed Phase 0 + 1 + 2 (substrate 1 + alert kind) — foundational, ~3-5 days
- Heed Phase 3 (channel-out) parallel with Ramp Phase 0 + 1 (signal-source schema) — ~3 days
- Heed Phase 4-7 (escalation + guidance + UI + first-fire) parallel with Ramp Phase 2-3 (playbook + signal collection) — ~5-7 days
- Brief Phase 0 + 1-3 (digest data + render + email — depends on Heed P1+P3) — ~3 days
- Vie Phase 0 + 1-2 (variant runtime + metrics — depends on Substrate 4) — ~5 days
- Ramp Phase 4-7 (UI + auto-rollback + first-fire) — ~3-5 days
- Brief Phase 4-6 (UI + auto-actions + first-fire) — ~3-5 days
- Vie Phase 3-7 (significance + dashboard + Heed/Brief/Ramp wiring + first-fire) — ~5-7 days
Total: ~4-6 weeks serial; ~2-3 weeks parallel-swarmed.
Cross-references
- warp#944 Heed
- warp#945 Brief
- warp#946 Ramp
- warp#947 Vie
- ADR-079 (operational-approval substrate)
- ADR-092 (host/project separation)
- ADR-094 (bundle-compose-in-GHCR)
- ADR-107 (gates as playbook primitives)
- ADR-108 (sub-agent fires as first-class)
- ADR-109 (type:claude vs observer:)
- ADR-115 (principle-aware reviewers)
- ADR-116 (RAG)
project_factory_principle_50_products.mdfeedback_pipelines_over_ai.mdfeedback_name_before_you_love_it.md