Workstream Profile Guide
Workstream profiles let a project describe the shape of a track without making Fairway project-specific. Use them when a repo has recurring coordination needs such as release readiness, platform foundation work, frontend migration, service extraction, SDK readiness, or security hardening.
Profiles are operational in readiness checks and dashboard visibility. Fairway
validates the config, uses route_samples in fairway adoption artifact,
evaluates named profile gates against recorded evidence rows, applies blocking
profile gates in fairway merge-ready, and groups dashboard tasks by
profile/kind when metadata is present. The dashboard can also filter by
profile, kind, owning domain, risk, and review domain; it also evaluates
profile gates in the main view and bounds task/activity tables for larger
tracks. Tasks can carry profile-aware metadata such as owning domain/layer,
source/target paths, review domains, risk level, and migration type.
Template-rendered packets are
available through fairway packet template; guard reports are recorded through
fairway record guard-report.
When To Add One
Add a profile when agents or reviewers keep asking the same coordination questions:
- Which task kinds belong to this workstream?
- Which paths should prove review routing is configured?
- Which evidence or approvals are expected before readiness?
- Which review domains should be considered for merge or release decisions?
- Which packet fields should agents fill out for this track?
Do not add a profile for one-off task instructions. Put those in the task notes or a context packet instead.
Minimal Example
[[workstream_profiles]]
name = "release-readiness"
task_kinds = ["release-risk", "uat-evidence", "approval"]
dashboard_groups = ["release risks", "uat evidence", "approvals"]
review_domains = ["security", "ops", "governance"]
route_samples = ["scripts/release/check.sh", "doc/release/runbook.md"]
[[workstream_profiles.gates]]
name = "security-review"
group = "security gates"
mode = "advisory"
task_kinds = ["release-risk"]
evidence_type = "security-review"
required_evidence_count = 1
accepted_results = ["pass", "partial"]
artifact_required = true
expires_after = "720h"
description = "Security review evidence should be attached before release readiness."
[[workstream_profiles.gates]]
name = "release-owner-approval"
mode = "blocking"
evidence_type = "approval"
required_evidence_count = 1
owner_signoff_required = true
[[packet_templates]]
profiles = ["release-readiness"]
name = "release-risk"
required_fields = ["risk", "owner", "severity", "mitigation", "residual_risk"]
optional_fields = ["expiry", "accepted_by"]
Gate Modes
Use advisory for expectations that should appear in reports and
merge-ready warnings but should not block readiness yet. Use blocking for
gates that must pass before merge-ready succeeds. Use report_only for early
guard rails where findings are still being measured.
Evidence Requirements
Profile gates can describe the evidence a workstream expects:
groupclusters related gates in dashboard and report surfaces. Use stable nouns such asboundary guards,release evidence,security gates, orSDK readinessso large tracks show readiness posture first instead of a flat list of every check.task_kindsnarrows a gate to specific task kinds inside the profile. Omit it when every task kind in the profile needs the same evidence.required_evidence_countsays how many matching evidence records should exist.accepted_resultslists acceptable evidence results. Use values fromfairway record evidence:pass,fail,partial,skipped, orblocked.artifact_requiredsays the evidence should include a durable path or URL.owner_signoff_requiredsays a named owner approval is expected.expires_afterrecords how long the evidence remains fresh.
These fields are validated, evaluated in adoption artifacts, and enforced by
merge-ready when the gate mode is blocking.
Gate evaluation first matches profile gates to tasks by the profile's
task_kinds, then narrows again by the gate's optional task_kinds. It then
counts evidence rows that satisfy every configured requirement:
evidence_typematchesfairway record evidence --artifact-type.accepted_resultsmatches--result.artifact_requiredrequires the counted row to include--artifact.expires_afterrequires the counted row'screated_attimestamp to be within the configured duration.owner_signoff_requiredrequires the counted row's notes to containsignofforsign-off.
For required_evidence_count > 1, every counted row must satisfy all of the
gate's configured evidence requirements. Stale rows or rows missing required
artifacts/signoff do not contribute to the count.
Adoption Artifact
After adding or changing a profile:
fairway config validate
fairway adoption artifact
fairway --json adoption artifact > .fairway/adoption.json
The artifact should show the profile gates, route samples, and gate evaluation
summary you configured. If route samples do not resolve to the expected
reviewers, update [[review_routes]] before asking agents to rely on the
profile. If a gate reports missing tasks, record the required evidence or adjust
the gate before treating the workstream as ready.
The dashboard shows the same profile gates as a live readiness panel. Use it
while agents are working so missing evidence is visible before merge-ready or
readiness report becomes the first place the team sees the gap.
For large tracks, group gates by evidence family and make the default dashboard exception-first: missing blocking gates should be visible immediately, passed gates should be rollups, and detailed gate rows should be used for drill-down. This is the pattern that kept the GPUaaS platform-foundation track readable: maps first, guard visibility second, facade implementation third.
Task Metadata
Use task metadata when the workstream needs architecture context that should survive handoffs and exports:
fairway add PF-003 \
--title "Introduce platform evidence facade" \
--role backend \
--kind facade \
--profile platform-foundation \
--owning-domain platform \
--owning-layer service \
--source-paths cmd/api/evidence.go,packages/services \
--target-paths packages/services/platform/evidence \
--review-domains architecture,security \
--risk-level high \
--migration-type facade
The same fields are accepted in YAML/JSON imports. See
examples/platform-foundation-queue.yaml
for a generic platform-foundation queue.
For platform-foundation reshuffles, keep the queue dependency order explicit:
ownership maps first, report-only boundary guards second, facade or
vertical-slice implementation third. In practice, facade tasks should depend on
both the relevant architecture-map task and a boundary-guard task unless the
orchestrator records an explicit residual-risk exception. This makes the
discipline visible to agents and reviewers before work starts.
For planning-heavy or documentation-heavy tracks, make the task owner an
orchestrator role and keep architecture, security, frontend, ops, and governance
as review domains. This avoids accidental self-review when a path such as
doc/architecture/** routes to the architecture reviewer. Implementation tasks
can still be owned by the lane doing the work, such as backend or ui.
Agent Guidance
Agents should treat profile config as the local contract for that workstream.
For example, if a task kind is architecture-map, the agent should use the
matching packet command or configured packet template fields and record evidence
against the named gates. If the profile is missing a gate or field, update the
config or docs rather than inventing a private checklist in chat.
fairway packet template architecture-map T-010 \
--field scope="route ownership" \
--field current_owner=mixed \
--field target_owner=D-arch \
--field migration_risk="route moves can hide auth regressions" \
--field acceptance="owners and review routes are explicit"
Guard reports should be recorded as evidence rather than pasted into chat:
fairway record guard-report T-011 \
--guard import-boundary \
--mode report_only \
--finding "cmd/api imports billing internals" \
--false-positive "generated client code" \
--allowed-debt "legacy route package" \
--graduation-criteria "zero critical findings for two releases" \
--artifact dist/import-boundary.json
Use readiness reports when a workstream or release needs a gate summary:
fairway readiness report --profile release-readiness
fairway --json readiness report --profile platform-foundation
Tasks with review_domains require one approved review per domain before
merge-ready succeeds. Use domain names that match the reviewer identities your
repo records, such as architecture, security, frontend, ops, or
governance. If the repo uses lane IDs as reviewers, such as D-arch or
E-governance, use those exact lane IDs in review_domains; otherwise the
queue can import successfully but merge-ready cannot be satisfied by recorded
reviews.