From 131bf0811864e20f74c65896aa32472520fe02ff Mon Sep 17 00:00:00 2001 From: "@permadeath.com" Date: Thu, 13 Aug 2026 16:03:49 -0400 Subject: [PATCH] docs(plan)!: remove the order field and the numbered column MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit A total order over twenty epics was a lie that cost something to maintain. Inserting one at the front renumbered every file beneath it and every row in the register, so two branches each adding an epic conflicted by construction, over a number neither of them cared about — which is exactly what happened between this branch and the camo/invite stack. The Open table still reads roughly top to bottom and that is now the whole of the ordering. What actually constrains the work is dependsOn and status, both of which are per epic and true independently of what anybody else is doing. Moving an epic is moving one line. Breaking for anything already reading the frontmatter: `order` is gone, not optional. Change-Id: Ica1bf689a9d7f10dd930fdc8034f09346d2f0407 --- plan/README.md | 76 ++++++++++++++++++++++------------------ plan/achievements.md | 1 - plan/after-action.md | 1 - plan/appview.md | 1 - plan/campaign.md | 1 - plan/cost-model.md | 1 - plan/daily-challenge.md | 1 - plan/forces.md | 1 - plan/invitations.md | 1 - plan/leaderboard.md | 1 - plan/managed-store.md | 1 - plan/match-lifecycle.md | 1 - plan/match-records.md | 1 - plan/onboarding.md | 1 - plan/player-profile.md | 1 - plan/proxy-split.md | 1 - plan/scenarios.md | 1 - plan/security-review.md | 1 - plan/session-security.md | 1 - plan/user-safety.md | 1 - 20 files changed, 42 insertions(+), 53 deletions(-) diff --git a/plan/README.md b/plan/README.md index d0b52e2..a8d3f49 100644 --- a/plan/README.md +++ b/plan/README.md @@ -24,18 +24,26 @@ Compose before anything runs on AWS. Each epic's filename is its id, and that id never changes. `plan/complete/camo.md` is `camo`, so its commits read `feat(camo): …` and `fix(camo): …`. That is the -whole reason the ids have no number prefix: an epic's order changes, and a -filename that has to be renamed is not an identifier. Archiving moves the file +whole reason the ids have no number prefix, and the reason there is no order +field either: a filename or a field that has to be rewritten when something +else moves is not an identifier. Archiving moves the file between directories and never renames it, for the same reason. `plan` is a valid scope too, for changes to this register. -## Order is advisory +## Order is advisory, and unnumbered -The `order` in an epic's frontmatter says roughly when it is expected to -happen. It is not a queue. Epics get finished out of order, blocked epics get -overtaken, and a number moving is not an event. What matters is `dependsOn`, -which says what genuinely cannot start first. +The Open table below reads roughly top to bottom, and that is the whole of the +ordering. There is no `order` field and no numbered column, because a total +order over twenty epics is a lie that costs something to maintain: inserting +one at the front used to renumber every file beneath it and every row here, so +two branches each adding an epic conflicted by construction, over a number +neither of them cared about. + +What actually constrains the work is `dependsOn`, which says what genuinely +cannot start first, and `status`, which says what is blocked. Those are per +epic, they are true independently of what anybody else is doing, and moving an +epic is moving one line. ## Status @@ -79,33 +87,33 @@ The exit criterion is met and something is still open in the file. ## Open -| # | id | title | status | -|---|---|---|---| -| 1 | [match-records](match-records.md) | A finished match is player-owned, checkable data | blocked | -| 2 | [match-lifecycle](match-lifecycle.md) | A match starts, survives, and ends properly | open | -| 3 | [session-security](session-security.md) | A session is only as alive as the grant behind it | open | -| 4 | [managed-store](managed-store.md) | Losing the box does not lose login grants | open | -| 5 | [proxy-split](proxy-split.md) | Deploying the API does not drop every live match | open | -| 6 | [security-review](security-review.md) | The boundaries have been looked at deliberately | open | -| 7 | [scenarios](scenarios.md) | The scenario catalog is generated and validated, not curated | open | -| 8 | [user-safety](user-safety.md) | A player has somewhere to go when another player is the problem | open | -| 9 | [invitations](invitations.md) | Nobody is put in a match without being asked | open | -| 10 | [player-profile](player-profile.md) | A player has a page that is about them | blocked | -| 11 | [onboarding](onboarding.md) | Somebody who has never played MegaMek can finish a match | open | -| 12 | [daily-challenge](daily-challenge.md) | One fight a day, the same for everyone, scored | blocked | -| 13 | [cost-model](cost-model.md) | What a match costs is measured | open | -| 14 | [forces](forces.md) | A player brings their own units | open | -| 15 | [achievements](achievements.md) | A player is awarded something and chooses to show it | open | -| 16 | [appview](appview.md) | lance.blue shows a match it never hosted | open | -| 17 | [leaderboard](leaderboard.md) | A rating anybody can recompute | open | -| 18 | [after-action](after-action.md) | A finished match is worth reading, not just counting | open | -| 19 | [campaign](campaign.md) | Pilots and forces persist between matches | open | - -Six through nine are where the project stops being played only by people who -know each other. They are ordered ahead of the things that bring strangers in -— onboarding and the daily challenge — rather than behind them, because a -consent gap or a missing block is much cheaper to fix before it has been -exercised than after. +| id | title | status | +|---|---|---| +| [match-records](match-records.md) | A finished match is player-owned, checkable data | blocked | +| [match-lifecycle](match-lifecycle.md) | A match starts, survives, and ends properly | open | +| [session-security](session-security.md) | A session is only as alive as the grant behind it | open | +| [managed-store](managed-store.md) | Losing the box does not lose login grants | open | +| [proxy-split](proxy-split.md) | Deploying the API does not drop every live match | open | +| [security-review](security-review.md) | The boundaries have been looked at deliberately | open | +| [scenarios](scenarios.md) | The scenario catalog is generated and validated, not curated | open | +| [user-safety](user-safety.md) | A player has somewhere to go when another player is the problem | open | +| [invitations](invitations.md) | Nobody is put in a match without being asked | open | +| [player-profile](player-profile.md) | A player has a page that is about them | blocked | +| [onboarding](onboarding.md) | Somebody who has never played MegaMek can finish a match | open | +| [daily-challenge](daily-challenge.md) | One fight a day, the same for everyone, scored | blocked | +| [cost-model](cost-model.md) | What a match costs is measured | open | +| [forces](forces.md) | A player brings their own units | open | +| [achievements](achievements.md) | A player is awarded something and chooses to show it | open | +| [appview](appview.md) | lance.blue shows a match it never hosted | open | +| [leaderboard](leaderboard.md) | A rating anybody can recompute | open | +| [after-action](after-action.md) | A finished match is worth reading, not just counting | open | +| [campaign](campaign.md) | Pilots and forces persist between matches | open | + +The middle of that list — security-review through invitations — is where the +project stops being played only by people who know each other. It sits ahead of +the things that bring strangers in, onboarding and the daily challenge, rather +than behind them, because a consent gap or a missing block is much cheaper to +fix before it has been exercised than after. ## Continuous diff --git a/plan/achievements.md b/plan/achievements.md index 91af2f9..fcf4261 100644 --- a/plan/achievements.md +++ b/plan/achievements.md @@ -2,7 +2,6 @@ id: achievements title: A player is awarded something and chooses to show it status: open -order: 15 repos: [headquarters, lexicons] dependsOn: [] exitCriterion: > diff --git a/plan/after-action.md b/plan/after-action.md index 072ba9d..d66ea82 100644 --- a/plan/after-action.md +++ b/plan/after-action.md @@ -2,7 +2,6 @@ id: after-action title: A finished match is worth reading, not just counting status: open -order: 18 repos: [headquarters, arena, lexicons] dependsOn: [match-records] exitCriterion: > diff --git a/plan/appview.md b/plan/appview.md index 36ae2d7..110a936 100644 --- a/plan/appview.md +++ b/plan/appview.md @@ -2,7 +2,6 @@ id: appview title: lance.blue shows a match it never hosted status: open -order: 16 repos: [headquarters, infra] dependsOn: [match-records, managed-store] exitCriterion: > diff --git a/plan/campaign.md b/plan/campaign.md index 061f750..e6c4104 100644 --- a/plan/campaign.md +++ b/plan/campaign.md @@ -2,7 +2,6 @@ id: campaign title: Pilots and forces persist between matches status: open -order: 19 repos: [headquarters, arena, lexicons] dependsOn: [forces, after-action] exitCriterion: > diff --git a/plan/cost-model.md b/plan/cost-model.md index 0bf11bf..0a861a3 100644 --- a/plan/cost-model.md +++ b/plan/cost-model.md @@ -2,7 +2,6 @@ id: cost-model title: What a match costs is measured, and what a busy day costs is known status: open -order: 13 repos: [headquarters, arena, infra] dependsOn: [] exitCriterion: > diff --git a/plan/daily-challenge.md b/plan/daily-challenge.md index a83cc6d..c01125f 100644 --- a/plan/daily-challenge.md +++ b/plan/daily-challenge.md @@ -2,7 +2,6 @@ id: daily-challenge title: One fight a day, the same for everyone, scored status: blocked -order: 12 repos: [headquarters, arena] dependsOn: [match-records, scenarios, player-profile] exitCriterion: > diff --git a/plan/forces.md b/plan/forces.md index 8eba4de..9356de0 100644 --- a/plan/forces.md +++ b/plan/forces.md @@ -2,7 +2,6 @@ id: forces title: A player brings their own units status: open -order: 14 repos: [headquarters, arena, lexicons] dependsOn: [scenarios] exitCriterion: > diff --git a/plan/invitations.md b/plan/invitations.md index 4263b34..14de154 100644 --- a/plan/invitations.md +++ b/plan/invitations.md @@ -2,7 +2,6 @@ id: invitations title: Nobody is put in a match without being asked status: open -order: 9 repos: [headquarters, lexicons] dependsOn: [lobby] exitCriterion: > diff --git a/plan/leaderboard.md b/plan/leaderboard.md index e3535bb..dce8004 100644 --- a/plan/leaderboard.md +++ b/plan/leaderboard.md @@ -2,7 +2,6 @@ id: leaderboard title: A rating anybody can recompute status: open -order: 17 repos: [headquarters, lexicons] dependsOn: [match-records, appview] exitCriterion: > diff --git a/plan/managed-store.md b/plan/managed-store.md index 0fd400f..99b3ec0 100644 --- a/plan/managed-store.md +++ b/plan/managed-store.md @@ -2,7 +2,6 @@ id: managed-store title: Losing the box does not lose login grants status: open -order: 4 repos: [headquarters, infra] dependsOn: [] exitCriterion: > diff --git a/plan/match-lifecycle.md b/plan/match-lifecycle.md index cc02d2f..6ca806b 100644 --- a/plan/match-lifecycle.md +++ b/plan/match-lifecycle.md @@ -2,7 +2,6 @@ id: match-lifecycle title: A match starts, survives, and ends properly status: open -order: 2 repos: [headquarters, arena, infra] dependsOn: [] exitCriterion: > diff --git a/plan/match-records.md b/plan/match-records.md index 634cc94..837dd13 100644 --- a/plan/match-records.md +++ b/plan/match-records.md @@ -2,7 +2,6 @@ id: match-records title: A finished match is player-owned, checkable data status: blocked -order: 1 repos: [headquarters, arena, lexicons] dependsOn: [] exitCriterion: > diff --git a/plan/onboarding.md b/plan/onboarding.md index e0e3e66..1d6f014 100644 --- a/plan/onboarding.md +++ b/plan/onboarding.md @@ -2,7 +2,6 @@ id: onboarding title: Somebody who has never played MegaMek can finish a match status: open -order: 11 repos: [headquarters, arena] dependsOn: [scenarios] exitCriterion: > diff --git a/plan/player-profile.md b/plan/player-profile.md index ee071f2..249d861 100644 --- a/plan/player-profile.md +++ b/plan/player-profile.md @@ -2,7 +2,6 @@ id: player-profile title: A player has a page that is about them status: blocked -order: 10 repos: [headquarters] dependsOn: [match-records] exitCriterion: > diff --git a/plan/proxy-split.md b/plan/proxy-split.md index 345a988..91edec8 100644 --- a/plan/proxy-split.md +++ b/plan/proxy-split.md @@ -2,7 +2,6 @@ id: proxy-split title: Deploying the API does not drop every live match status: open -order: 5 repos: [headquarters, infra] dependsOn: [] exitCriterion: > diff --git a/plan/scenarios.md b/plan/scenarios.md index 5f20257..d0a5ac1 100644 --- a/plan/scenarios.md +++ b/plan/scenarios.md @@ -2,7 +2,6 @@ id: scenarios title: The scenario catalog is generated and validated, not curated status: open -order: 7 repos: [headquarters, arena] dependsOn: [] exitCriterion: > diff --git a/plan/security-review.md b/plan/security-review.md index f1165e8..60dcf63 100644 --- a/plan/security-review.md +++ b/plan/security-review.md @@ -2,7 +2,6 @@ id: security-review title: The boundaries have been looked at deliberately, not incidentally status: open -order: 6 repos: [headquarters, arena, infra] dependsOn: [] exitCriterion: > diff --git a/plan/session-security.md b/plan/session-security.md index efb26a3..568bb93 100644 --- a/plan/session-security.md +++ b/plan/session-security.md @@ -2,7 +2,6 @@ id: session-security title: A session is only as alive as the grant behind it status: open -order: 3 repos: [headquarters] dependsOn: [sign-in] exitCriterion: > diff --git a/plan/user-safety.md b/plan/user-safety.md index 9eca058..e8a73b9 100644 --- a/plan/user-safety.md +++ b/plan/user-safety.md @@ -2,7 +2,6 @@ id: user-safety title: A player has somewhere to go when another player is the problem status: open -order: 8 repos: [headquarters, arena, lexicons] dependsOn: [] exitCriterion: > -- 2.51.2