diff --git a/CONTEXT.md b/CONTEXT.md index 2458daa..88eb532 100644 --- a/CONTEXT.md +++ b/CONTEXT.md @@ -33,7 +33,7 @@ A free-text takeaway captured against a Feature once it is delivered — what th _Avoid_: retro note, lesson, postmortem **Status**: -A Feature's *current* delivery confidence (a snapshot, overwritten each review): **green** (all good), **orange** (in trouble but we have a plan), **red** (in trouble and we have no plan). May carry a comment. Applies only while in-flight; once delivered, the **Learning** takes over and the Status is dropped. An overdue Feature (past its latest estimate, not delivered) is expressed through an orange/red Status, not a dedicated symbol. +A Feature's *current* delivery confidence (a snapshot, overwritten each review): **on-track** (all good), **at-risk** (in trouble but we have a plan), **off-track** (in trouble and we have no plan). May carry a comment. Applies only while in-flight; once delivered, the **Learning** takes over and the Status is dropped. An overdue Feature (past its latest estimate, not delivered) is expressed through an at-risk/off-track Status, not a dedicated symbol. _Avoid_: health, RAG, risk **Week**: diff --git a/src/components/MacroplanGrid.vue b/src/components/MacroplanGrid.vue index 875bc19..818a273 100644 --- a/src/components/MacroplanGrid.vue +++ b/src/components/MacroplanGrid.vue @@ -58,20 +58,14 @@ const gridStyle = computed(() => ({ function tone(row: FeatureRow): Tone { if (row.delivered) return row.onTime ? 'success' : 'error' - if (row.status === 'green') return 'success' - if (row.status === 'orange') return 'warning' - if (row.status === 'red') return 'error' + if (row.status === 'on-track') return 'success' + if (row.status === 'at-risk') return 'warning' + if (row.status === 'off-track') return 'error' return 'neutral' } function statusWord(row: FeatureRow): string { - return row.status === 'green' - ? 'on track' - : row.status === 'orange' - ? 'at risk' - : row.status === 'red' - ? 'blocked' - : 'in flight' + return row.status ? row.status.replace('-', ' ') : 'in flight' } function markerAt(row: FeatureRow, w: WeekId): MarkerKind | null { diff --git a/src/data/sample.ts b/src/data/sample.ts index d1203e0..0d51aa3 100644 --- a/src/data/sample.ts +++ b/src/data/sample.ts @@ -1,5 +1,5 @@ // Default Macroplan shown on first load — exercises every state: -// on-time delivery, late delivery with slips, in-flight (green/orange/red), +// on-time delivery, late delivery with slips, in-flight (on-track/at-risk/off-track), // an overdue Feature, and a Milestone with unmet required Features. export const SAMPLE_PLAN = `title = "Q3 — Checkout revamp" @@ -32,7 +32,7 @@ learning = "Vendor lead time was the real constraint — derisk vendors up front name = "Dashboard" start = 2026-06-01 original = 2026-06-08 # already past 'now' and undelivered → overdue -status = "red" +status = "off-track" note = "No recovery plan yet — needs an owner." [[feature]] @@ -40,14 +40,14 @@ name = "Search" start = 2026-06-08 original = 2026-06-22 reestimates = [2026-07-06] # re-estimated once, still in flight → △ -status = "orange" +status = "at-risk" note = "Third-party search API is flaky; spike a fallback." [[feature]] name = "Notifications" start = 2026-06-22 original = 2026-07-06 -status = "green" +status = "on-track" [[milestone]] name = "Code freeze" diff --git a/src/model/parse.ts b/src/model/parse.ts index 1d564dd..4db5f85 100644 --- a/src/model/parse.ts +++ b/src/model/parse.ts @@ -11,7 +11,7 @@ export class PlanParseError extends Error { } } -const STATUSES = ['green', 'orange', 'red'] as const satisfies readonly StatusLevel[] +const STATUSES = ['on-track', 'at-risk', 'off-track'] as const satisfies readonly StatusLevel[] // ── Field schemas ────────────────────────────────────────────────────────── // A TOML date (smol-toml returns a Date subclass) or a yyyy-mm-dd string, diff --git a/src/model/plan.test.ts b/src/model/plan.test.ts index 57255d1..4cf506a 100644 --- a/src/model/plan.test.ts +++ b/src/model/plan.test.ts @@ -76,10 +76,10 @@ describe('F2 — on-time / late classification (ADR-0001)', () => { }) it('in-flight (undelivered) → ◯ only, onTime null, bar ends at the furthest estimate', () => { - const r = rowOf(base('reestimates = [2026-06-29]\nstatus = "red"'), 'X') + const r = rowOf(base('reestimates = [2026-06-29]\nstatus = "off-track"'), 'X') expect(r.onTime).toBeNull() expect(r.delivered).toBe(false) - expect(r.status).toBe('red') + expect(r.status).toBe('off-track') expect(r.barEndWeek).toBe('2026-06-29') // furthest open estimate expect(r.markers.some((m) => m.kind === 'original')).toBe(true) }) @@ -91,7 +91,7 @@ describe('bar extent relative to now', () => { it('extends an overdue undelivered bar to the now week, keeping ◯ at the estimate', () => { // original 2026-06-08 is before now (week of 2026-06-15) and undelivered → overdue - const r = rowOf(feat('status = "red"'), 'X') + const r = rowOf(feat('status = "off-track"'), 'X') expect(r.delivered).toBe(false) expect(r.barEndWeek).toBe('2026-06-15') // runs up to now, past the 06-08 estimate expect(r.markers.find((m) => m.kind === 'original')?.week).toBe('2026-06-08') diff --git a/src/model/types.ts b/src/model/types.ts index 68d90be..63a1da6 100644 --- a/src/model/types.ts +++ b/src/model/types.ts @@ -1,6 +1,6 @@ import type { WeekId } from './week' -export type StatusLevel = 'green' | 'orange' | 'red' +export type StatusLevel = 'on-track' | 'at-risk' | 'off-track' // ── Raw model: as authored, after TOML parse + validation, before derivation ──