Context
While pruning knip-flagged dead code we removed packages/prx/src/pr-state/personal_sprintx.ts — a complete, never-wired feature (no verb, no surface, zero importers). It's a real idea worth keeping on the backlog, so capturing it here before it's only recoverable from git archaeology.
The full implementation is recoverable from git history at the commit just before the pruning commit (branch claude/prune-dead-machine-shims). Path: packages/prx/src/pr-state/personal_sprintx.ts.
The idea
A personal sprint layered over the unit-of-work surface: tie a set of UoWs to a single weekly outcome and a measurable metric, then derive live progress from board state.
Config (zod personalSprintxSchema, .strict()):
sprintId, owner
weeklyGoal: { outcome, metric, targetDelta, assignedUowIds: CanonicalId[] }
sprintGoal: { outcome, metric }
metric: { baseline, current } (nullable)
bindings: Record<CanonicalId, { metric, expectedDelta? }> — which UoW moves which metric
velocity: { pointsCompleted? }
Derivation (derivePersonalSprintx(surface, config) → PersonalSprintxDerived):
- Assigned rollup from board state:
total / contributing / merged / blocked / running, where
- merged-like =
merged | cleaned | merge_ready
- blocked-like =
changes_requested | no_worktree | worktree_created
- running =
row.agent.state === "running"
- contributing = the row's binding metric matches the weekly-goal metric (vs. "non-goal")
- Metric status (
metricStatus): deltaPercent = (current-baseline)/baseline*100; metTarget honors sign of targetDelta (improvement can be negative-is-better); progressPercent clamped 0–100; status ∈ met_target | on_track | at_risk | failed_target (with a "moved wrong direction" → failed_target rule). Null-safe (missing baseline/current ⇒ at_risk).
goalRows: per-UoW { id, board, prNumber, contribution }.
- ID normalization throughout (
trim().toUpperCase(), canonical ^[A-Z][A-Z0-9]+-\d+$).
Why it's interesting (and why it was parked)
It connects the work-unit surface to an outcome layer — "did this week's PRs move the number I said they would?" — rather than just counting throughput. That's aligned with the value-props/forcing-function framing.
It was never given a CLI verb or a surface projection, so it sat as dead code. To revive for real:
- Add a
prx sprintx (or surface-axis) verb that loads the config (loadPersonalSprintxConfig(path)) and renders derivePersonalSprintx.
- Decide where
metric.current comes from (manual config vs. a metrics source).
- Tests + a changeset + docs/cli.md entry.
Also removed (no capture needed)
The machine/{index,events,state,derive-phase,invariants}.ts files were pure re-export shims (a convenience barrel aliasing @bounded-systems/machine-schema + machines/pr.ts) with zero importers — no design to preserve. If a single machine/ facade import path is wanted later, it's a one-line barrel to recreate.
https://claude.ai/code/session_01LPzb9h4TgS7zCB4vWtNiS4
Context
While pruning knip-flagged dead code we removed
packages/prx/src/pr-state/personal_sprintx.ts— a complete, never-wired feature (no verb, no surface, zero importers). It's a real idea worth keeping on the backlog, so capturing it here before it's only recoverable from git archaeology.The full implementation is recoverable from git history at the commit just before the pruning commit (branch
claude/prune-dead-machine-shims). Path:packages/prx/src/pr-state/personal_sprintx.ts.The idea
A personal sprint layered over the unit-of-work surface: tie a set of UoWs to a single weekly outcome and a measurable metric, then derive live progress from board state.
Config (zod
personalSprintxSchema,.strict()):sprintId,ownerweeklyGoal:{ outcome, metric, targetDelta, assignedUowIds: CanonicalId[] }sprintGoal:{ outcome, metric }metric:{ baseline, current }(nullable)bindings:Record<CanonicalId, { metric, expectedDelta? }>— which UoW moves which metricvelocity:{ pointsCompleted? }Derivation (
derivePersonalSprintx(surface, config) → PersonalSprintxDerived):total / contributing / merged / blocked / running, wheremerged | cleaned | merge_readychanges_requested | no_worktree | worktree_createdrow.agent.state === "running"metricStatus):deltaPercent = (current-baseline)/baseline*100;metTargethonors sign oftargetDelta(improvement can be negative-is-better);progressPercentclamped 0–100; status ∈met_target | on_track | at_risk | failed_target(with a "moved wrong direction" →failed_targetrule). Null-safe (missing baseline/current ⇒at_risk).goalRows: per-UoW{ id, board, prNumber, contribution }.trim().toUpperCase(), canonical^[A-Z][A-Z0-9]+-\d+$).Why it's interesting (and why it was parked)
It connects the work-unit surface to an outcome layer — "did this week's PRs move the number I said they would?" — rather than just counting throughput. That's aligned with the value-props/forcing-function framing.
It was never given a CLI verb or a surface projection, so it sat as dead code. To revive for real:
prx sprintx(or surface-axis) verb that loads the config (loadPersonalSprintxConfig(path)) and rendersderivePersonalSprintx.metric.currentcomes from (manual config vs. a metrics source).Also removed (no capture needed)
The
machine/{index,events,state,derive-phase,invariants}.tsfiles were pure re-export shims (a convenience barrel aliasing@bounded-systems/machine-schema+machines/pr.ts) with zero importers — no design to preserve. If a singlemachine/facade import path is wanted later, it's a one-line barrel to recreate.https://claude.ai/code/session_01LPzb9h4TgS7zCB4vWtNiS4