-
Notifications
You must be signed in to change notification settings - Fork 2
Expand file tree
/
Copy pathforge-status-v3.schema.yml
More file actions
279 lines (256 loc) · 14 KB
/
Copy pathforge-status-v3.schema.yml
File metadata and controls
279 lines (256 loc) · 14 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
# ──────────────────────────────────────────────────────────────────────────────
# .forge-status.yml — SCHEMA v3
# ──────────────────────────────────────────────────────────────────────────────
# This file documents the shape of `.forge-status.yml` produced by Product Forge
# v1.5.0 and later. It is a reference document, not an executable JSON Schema.
#
# Design principles:
# - Additive over v2: every v2 field is preserved with identical semantics.
# - All new fields are OPTIONAL so v2 files remain valid v3 files.
# - Writers may omit fields they do not use; readers must tolerate absence.
# - `schema_version: 3` indicates new-writer output. Absence or `2` means
# the file was last written by pre-v1.5.0 code and should be treated as v2.
# ──────────────────────────────────────────────────────────────────────────────
# Version marker. Must be an integer. Presence of `3` means new-writer output.
schema_version: 3
# Feature slug. Immutable once set.
feature: "example-feature-slug"
# ISO-8601 date. Immutable once set.
created_at: "2026-04-19"
# ISO-8601 timestamp. Updated on every write.
last_updated: "2026-04-19T12:00:00Z"
# NEW in v3.
# Drives phase map selection. Valid values: "express" | "lite" | "standard" | "v-model".
# "express" (v1.6) is the lightest track — product_spec → plan → implement → verify.
# Default: "standard" if omitted.
feature_mode: "standard"
# NEW in v3.
# Set to `true` by the `backfill` command when this feature was reverse-engineered
# from existing code rather than authored through the full lifecycle.
backfilled: false
# NEW in v3.
# Marks a feature as v1.5.0-native (vs lazily-migrated v1.3/v1.4). Used by
# the digest-enforcement rule in docs/runtime.md §8.3 to decide whether
# missing digests are CRITICAL (v2-native) or WARNING + stub (grandfathered).
# Writers: new features created by v1.5.0+ orchestrator set this to true
# on the initial write.
# Absence is equivalent to `false` — i.e. grandfathered.
v2_native: true
# Legacy v2 field — preserved.
# Valid values: "classic" | "v-model" | "ask".
speckit_mode: "classic"
# Per-phase status map.
# v2 stored only a status string per phase. v3 expands each entry into an object
# while keeping the key set compatible. The orchestrator always reads `status`
# first; all other fields are optional instrumentation.
#
# Valid status values:
# pending — not started
# in_progress — currently running
# completed — finished and accepted
# skipped — user explicitly chose to skip an optional phase
# completed_with_known_issues — finished but with documented open issues (used
# by test_run / verify-gated phases; see runtime.md §4)
# not_applicable — phase was never in scope for this feature (e.g.
# phases outside a lite-mode map, or phases not run
# for a backfilled feature reverse-engineered from code)
# The `revalidation` phase additionally accepts the legacy literal `approved`
# (same meaning as `completed`) for v1/v2 backwards compatibility.
# The skip-reason policy in docs/policy.md §3 applies ONLY to `skipped`;
# `not_applicable` is exempt.
phases:
problem_discovery:
status: "completed" # see valid values above
started_at: "2026-04-18T09:00:00Z" # NEW
completed_at: "2026-04-18T09:45:00Z" # NEW
tokens_in: 12000 # NEW — tokens consumed by this phase
tokens_out: 3500 # NEW
tool_calls: 14 # NEW
digest_path: "problem-discovery/digest.md" # NEW — see A4 digest template
skipped: false # NEW — true if status == "skipped"
skip_reason: null # NEW — required when skipped=true (E2 policy)
produced_by: null # NEW — identity (email/handle) of the human who owned
# the artifact this phase produced. Optional; REQUIRED
# when role_approvals.solo_mode=false (powers the
# distinct-approver rule: approved_by != produced_by,
# policy.md §5.3).
research:
status: "completed"
product_spec:
status: "completed"
design_system_harvest: # NEW v1.6 — Phase 2 helper (UI features only)
status: "completed" # not_applicable for backend-only features
revalidation:
status: "approved" # keeps v2 "approved" literal for this phase
bridge:
status: "completed"
plan:
status: "completed"
tasks:
status: "completed"
pre_impl_review:
status: "completed"
implement:
status: "in_progress"
# NEW v1.6 — test-first "Red" gate audit record.
# Populated by `implement` after consuming the `Test-first: true` markers
# tasks.md attaches to each test task. Records whether the marked tests were
# confirmed failing before implementation, or the gate was skipped.
red_gate:
status: "confirmed_failing" # confirmed_failing | skipped
tests: ["TC-UNIT-021", "TC-E2E-003"] # the TC-* ids that were run red-first
skip_reason: null # required when status == "skipped"
code_review:
status: "pending"
verify:
status: "pending"
test_plan:
status: "pending"
test_run:
status: "pending"
release_readiness:
status: "pending"
spec_merge: # NEW v1.6 — living-spec merge into canonical specs/
status: "pending" # runs after release-readiness; not_applicable when no canonical specs/
retrospective:
status: "pending"
# Supporting / extension phase keys — written by the standalone supporting commands
# (api-docs, security-check, tracking-plan) and the optional extension phases run by
# the orchestrator (i18n-harvest, migration-plan, monitoring-setup, experiment-design).
# Each is recognized in the canonical phases map; `not_applicable` when the phase was
# never run for this feature.
api_docs: # written by the api-docs command (instrumentation in top-level api_docs_report below)
status: "not_applicable"
security_check: # written by the security-check command (instrumentation block lives in commands/security-check.md, not here)
status: "not_applicable"
tracking_plan: # written by the tracking-plan command (instrumentation block lives in commands/tracking-plan.md, not here)
status: "not_applicable"
i18n_harvest: # written by i18n-harvest; not_applicable for English-only projects
status: "not_applicable"
migration_plan: # written by migration-plan; not_applicable when no data/schema migration
status: "not_applicable"
monitoring_setup: # written by monitoring-setup; not_applicable when no observability scope
status: "not_applicable"
experiment_design: # written by experiment-design; not_applicable unless flag marked experiment: true
status: "not_applicable"
# Legacy v2 field — preserved.
testing:
final_pass_rate: ""
bugs_found: 0
bugs_fixed: 0
bugs_deferred: 0
test_runs_total: 0
# NEW in v3.
# Per-task instrumentation. Populated by the `implement` phase as work proceeds.
# Empty list if the feature has not yet produced tasks.md.
#
# Renamed from the initial v3 draft's top-level `tasks:` to `task_log:` to
# remove the name collision with `phases.tasks` (the Phase 5B: Tasks entry).
# Both keys coexist in v3 files and mean different things:
# phases.tasks.status — whether Phase 5B has been completed
# task_log[] — per-individual-task runtime log
task_log:
- id: "T001" # matches task id in tasks.md
size: "M" # XS | S | M | L | XL (D4 T-shirt sizing)
status: "completed" # pending | in_progress | completed | failed | skipped
paths: ["back/src/modules/users/users.service.ts"] # files the task touches
commit_sha: "abc1234" # short or full SHA of the commit that closed the task
started_at: "2026-04-19T10:00:00Z"
completed_at: "2026-04-19T11:15:00Z"
failure_log_path: null # optional path to failures/<id>.md if status == "failed"
# Gate audit trail. Extended from v2.
# Each entry records a human-in-the-loop decision at a phase boundary.
gates:
- phase: "plan"
decision: "approved" # approved | approved_with_conditions | revised | skipped | rolled_back | aborted
timestamp: "2026-04-19T10:00:00Z"
notes: ""
conditions: []
sync_result: "clean" # clean | N_critical | N_warning
rolled_back_to: null # NEW — required when decision == "rolled_back" (phase name to rewind to)
reviewed_sha: "abc1234" # NEW v1.6 (W5-A2) — git SHA / artifact stamp the gate was reviewed against.
# On a re-run, the gate shows only the diff since this sha (delta/incremental review).
risk: "low" # NEW v1.6 (W5-A4) — gate risk class from scripts/gate-risk.js: low | medium | high.
reviewed_by_model: null # NEW v1.7 (P1-B) — reviewer id when code-review ran with --cross-model; null otherwise.
cross_model_findings: 0 # NEW v1.7 (P1-B) — count of findings the cross-model reviewer added (0 if not run).
# NEW in v3 — role-based approvals.
# If `role_approvals.solo_mode` is true (see below), this block is omitted.
# Otherwise this records who approved, per role.
approvals:
pm:
approved_by: "alice@example.com"
at: "2026-04-19T10:00:00Z"
eng:
approved_by: "bob@example.com"
at: "2026-04-19T10:03:00Z"
qa: null # null == pending; object == approved
# NEW in v3 — skip_reason attached at the gate, not at the phase.
skip_reason: null # required when decision == "skipped"
# NEW v1.6 — action-item tally written by `release-readiness` on its gate entry.
# Counts of must/should/nice-to-have items and how many MUSTs are completed.
# Optional; present only on the release_readiness gate.
action_items:
must: 0
must_completed: 0
should: 0
nice_to_have: 0
# Legacy v2 field — preserved.
sync_runs:
last_run: "2026-04-19T10:00:00Z"
total_runs: 3
last_drift_count: 0
last_critical_count: 0
last_verdict: "clean"
# Legacy v2 field — preserved.
change_requests: []
# NEW v1.6. Top-level instrumentation block written by the `api-docs` command.
# Renamed from `api_docs:` to `api_docs_report:` to remove the sibling collision
# with the `phases.api_docs` status entry (mirrors the tasks→task_log fix).
# Phase completion is tracked under `phases.api_docs.status`; this block carries
# the per-run output summary. Omitted until api-docs has run.
api_docs_report:
endpoints: 12 # number of documented endpoints/operations
source: "contracts" # "contracts" (reconciled) | "scratch" (no contracts/*)
openapi_file: "api-docs/openapi.yml"
asyncapi_file: "api-docs/asyncapi.yml" # omitted when no contracts/asyncapi.yaml
postman_file: "api-docs/postman-collection.json"
drift_issues: 0 # count of contract↔implementation drift findings
# NEW v1.6. Top-level instrumentation block written by the `release-readiness`
# command. Phase completion is tracked under the release_readiness gate in gates[];
# this block carries supply-chain artifact paths. Omitted until release-readiness runs.
# NOTE: this top-level key shares its NAME with the `phases.release_readiness` status
# entry above — the same sibling-name collision D-APIDOCS-RENAME renamed away for
# api_docs (→ api_docs_report). The name `release_readiness.supply_chain_paths` is
# fixed by the writer (commands/release-readiness.md) and is kept verbatim here so its
# writes conform; the two keys live at different nesting levels and do not break the
# YAML parse. Flagged for maintainer reconciliation.
release_readiness:
supply_chain_paths:
sbom: "release/sbom.json"
sca: "release/sca-report.json"
licenses: "release/licenses.txt"
# NEW in v3. Cross-feature dependency graph used by `portfolio` (B1).
# Both lists contain feature slugs from sibling `features/<slug>/` directories.
# Managed manually for now; auto-detection deferred to a later wave.
dependencies:
depends_on: [] # features that must ship before this one
depended_on_by: [] # features blocked by this one
# NEW in v3. Monorepo scope — which workspaces this feature touches.
# Populated only when the project config has the `codebase.paths` block
# (monorepo mode). In single-root mode this field is omitted.
#
# Writers: bridge sets initial scope from product-spec; implement updates
# it from actual `task_log[].paths` workspace prefixes.
# Readers: portfolio (for per-workspace conflict matrix), test-plan
# (for test runner selection), verify-full (for scoped code scan).
scope:
paths: ["backend", "frontend"] # workspace names from codebase.paths
cross_workspace: true # true when len(paths) > 1
primary: "backend" # default workspace for ambiguous operations
# NEW in v3. Role approval configuration.
# In solo-dev projects, set solo_mode: true — gates require a single approval.
# In team projects, use required_roles per phase to demand multi-role sign-off.
role_approvals:
solo_mode: true
# When solo_mode: false, this block is consulted:
required_roles_per_phase: {} # e.g. { pre_impl_review: ["pm", "eng"], release_readiness: ["pm", "eng", "qa"] }