Skip to content

Changeset: launch plan reconciliation, 2026-08-24 โ€‹

APPLIED 2026-08-24 in commit bbf5def3. All eight rows landed, none skipped: every Current block matched its file exactly once, and afterwards exactly eight lines differed and no others. The section below describing the apply step as blocked is kept as the record of why this was written as a document. See README.md for what was applied and what was not.

Every edit below is written out in full so applying it is mechanical. Line numbers are against the files as they stood on feat/admin-and-merchant-portals at commit time; match on the row's first cell, not the line number, because tasks 9 and 10 edit ALPHA.md after this and will shift them.

Why is this a document instead of an edit? โ€‹

The PM lane guard refused both target files, and the refusal was left standing. โ€‹

  • .claude/hooks/guard-pm-lane.sh blocked a write to docs/business/launches/ALPHA.md and a write to docs/business/launches/PROTOTYPE.md. Both sit outside docs/projects/**.
  • The documented door is CLAUDE_ALLOW_PM_BUILD=1. It was not used. It opens only on the operator's direct, present-tense word for the specific object, and she is away.
  • Applying this: eight single-line replacements across two files, five in ALPHA.md and three in PROTOTYPE.md. Nothing else in either file changes.
  • Verified applyable: a dry run matched every Current block against its file, replaced it, and confirmed exactly eight lines differ afterwards and no others.

What changes in ALPHA.md? โ€‹

  • Current:
    | Attribution, no-POS path | Analytics, Business | ๐Ÿ”ด P0 | Lit lantern redeems in-app with an animated confirmation shown at the counter | Pilot venues can test this with no merchant systems integration | ๐Ÿšง In progress | [#704](https://github.com/cattreedev/lantern_app/issues/704), [#697](https://github.com/cattreedev/lantern_app/issues/697) |
  • Corrected:
    | Attribution, no-POS path | Analytics, Business | ๐Ÿ”ด P0 | Lit lantern redeems in-app with an animated confirmation shown at the counter | Pilot venues can test this with no merchant systems integration | โ“ Needs operator input | [#704](https://github.com/cattreedev/lantern_app/issues/704) |
  • Evidence: #704 closed, #697 closed. #697 is "feat(merchant): real delivery data on the merchant dashboard (replace mock numbers)", a different subject, and it is the link this row should never have carried.
  • Why not just relink it: the row is one of the two that needs her words. See the questions section below.
  • Independent line item: dropping #697 can be applied or skipped on its own. The status change is the part that stops the row lying.

Row "Android and iOS device testing" (line 62): the last empty P0 Issues cell gets #963. โ€‹

  • Current:
    | Android and iOS device testing | Eng | ๐Ÿ”ด P0 | Install, push and offline behavior across real devices | The PWA is the product | โฌœ Not started | |
  • Corrected:
    | Android and iOS device testing | Eng | ๐Ÿ”ด P0 | Install, push and offline behavior across real devices | The PWA is the product | โฌœ Not started | [#963](https://github.com/cattreedev/lantern_app/issues/963) |
  • Scope note: this row is not one of the four named stale rows. It is here because the goal line reads "no alpha P0 row has an empty Issues cell", and after #896 is linked this was the only one left. Drop this line item if tasks 9 or 10 collide with it; nothing else depends on it.
  • Overlap surfaced: #722 already covers iOS push and is cited by the separate P1 row on line 63. #963 is the P0 superset (Android too, install and offline too) and says so in its body. Collapsing the two rows is her call, and #963 names that.

Row "Untested API functions on alpha paths" (line 64): cite the live successor, and fix a breakdown that does not add up. โ€‹

  • Current:
    | Untested API functions on alpha paths | Eng | ๐Ÿ”ด P0 | **109** exported functions across the six API services are imported by no test in their own service (auth 52, venues 18, lanterns 13, analytics 13, merchants 6, assistant 12). Ranked subset is DONE except the half on another lane's territory. Run `npm run count:untested-api` | Tracked on IMPORTED-by-a-test, not mentioned: the mention floor counted a guard as covered on the strength of a prose comment. It reads 76, and the 33 in between are reached by nothing | ๐Ÿšง In progress | [#942](https://github.com/cattreedev/lantern_app/issues/942) |
  • Corrected:
    | Untested API functions on alpha paths | Eng | ๐Ÿ”ด P0 | **109** exported functions across the six API services are imported by no test in their own service (auth 49, venues 18, lanterns 11, analytics 13, merchants 6, assistant 12). Ranked subset is DONE except the half on another lane's territory. Run `npm run count:untested-api` | Tracked on IMPORTED-by-a-test, not mentioned: the mention floor counted a guard as covered on the strength of a prose comment. It reads 76, and the 33 in between are reached by nothing | ๐Ÿšง In progress | [#962](https://github.com/cattreedev/lantern_app/issues/962), [#942](https://github.com/cattreedev/lantern_app/issues/942) |
  • Two changes, both evidenced by one fresh run of npm run count:untested-api on this branch, 2026-08-24:
    • #942 closed COMPLETED on 2026-08-21 via PR #946, which was scoped to the ranked subset plus the metric fix, never to the row. #962 is the successor filed today for the remaining 109.
    • The parenthetical breakdown was stale and internally inconsistent: 52 + 18 + 13 + 13 + 6 + 12 = 114, not the 109 the same cell claims. The fresh per-service no-IMPORT figures are auth 49, venues 18, lanterns 11, analytics 13, merchants 6, assistant 12, which do sum to 109.
  • Status stays In progress, and that is now true rather than accidental: the work is real, and #962 is open behind it.

Row "ToS and Privacy Policy" (line 73): status becomes Needs operator input, and a stale clause in the Why cell goes. โ€‹

  • Current:
    | ToS and Privacy Policy | Legal | ๐Ÿ”ด P0 | Final, counsel-reviewed, published, and reachable from the app | Public signup without them is not an option, and the footer links currently go nowhere | ๐Ÿšง In progress | [#141](https://github.com/cattreedev/lantern_app/issues/141), [#837](https://github.com/cattreedev/lantern_app/issues/837) |
  • Corrected:
    | ToS and Privacy Policy | Legal | ๐Ÿ”ด P0 | Final, counsel-reviewed, published, and reachable from the app | Public signup without them is not an option. The pages exist and the app footer now reaches them; the counsel-review and publishing half is undecided | โ“ Needs operator input | [#141](https://github.com/cattreedev/lantern_app/issues/141), [#837](https://github.com/cattreedev/lantern_app/issues/837) |
  • Evidence for the Why-cell correction: #837 is closed, and apps/web/src/screens/landing/LandingPage.jsx lines 208 to 215 now point at #/privacy, #/terms and #/safety, with apps/web/src/screens/legal/PrivacyPage.jsx, TermsPage.jsx and LegalPageShell.jsx behind them. "The footer links currently go nowhere" has been false since that merge.
  • Both issue links stay. #141 is open and #837 is the closed record that the pages shipped.

Row "Business legalities and governance" (line 75): the unlinked #896 gets linked. โ€‹

  • Current:
    | Business legalities and governance | Legal, Business | ๐Ÿ”ด P0 | Entity, Employee Rights Charter, governance docs signed off | Founding paperwork gets harder with users attached | โ“ Needs operator input | |
  • Corrected:
    | Business legalities and governance | Legal, Business | ๐Ÿ”ด P0 | Entity, Employee Rights Charter, governance docs signed off | Founding paperwork gets harder with users attached | โ“ Needs operator input | [#896](https://github.com/cattreedev/lantern_app/issues/896) |
  • Evidence: #896 is open, milestone Alpha, and its body names this exact row as its source. It was filed for this cell and never linked back.
  • Status is already correct and does not change.

What changes in PROTOTYPE.md? โ€‹

Row "Doctor learns more" (line 16): Not started becomes Built. โ€‹

  • Current:
    | Doctor learns more | Eng | ๐ŸŸ  P1 | Worktree health, port status, the stale-server hint | The single best diagnostic should cover the things that actually break | โฌœ Not started | [#857](https://github.com/cattreedev/lantern_app/issues/857) |
  • Corrected:
    | Doctor learns more | Eng | ๐ŸŸ  P1 | Worktree health, port status, the stale-server hint | The single best diagnostic should cover the things that actually break | โœ… Built | [#857](https://github.com/cattreedev/lantern_app/issues/857) |
  • Evidence, PROVEN by running it: ./lantern doctor on 2026-08-24 printed a Worktrees section (5 total, one flagged dirty), a Ports section naming every listener against PORT_MAP including the 8080 Firestore-versus-Venues warning, and seven stale-watch hints of the form "source changed after this server started". All three sections #857 proposed are live.
  • Where the code is: tooling/scripts/doctor-env.mjs, whose file header cites #857 by number, plus the surveyWorktrees and surveyPorts calls in lantern.

Row "Offer review layout" (line 30): Not started becomes Built. This is a FIFTH stale row, found during verification and not named in the brief. โ€‹

  • Current:
    | Offer review layout | Design | ๐ŸŸ  P1 | The last screen before publishing reads as broken | Reviewers use it every day of Alpha | โฌœ Not started | [#818](https://github.com/cattreedev/lantern_app/issues/818) |
  • Corrected:
    | Offer review layout | Design | ๐ŸŸ  P1 | The last screen before publishing reads as broken | Reviewers use it every day of Alpha | โœ… Built | [#818](https://github.com/cattreedev/lantern_app/issues/818) |
  • How it was found: a sweep for rows whose every cited issue is CLOSED, run over both files against live GitHub state. The brief named four rows; this sweep found five.
  • Evidence, PROVEN from git: #818 closed COMPLETED 2026-08-14. Commit d791173b (PR #877) carries the commit "fix(merchant): Review step cards wrap instead of forcing two columns (#818)" and the line Closes #818.
  • The judgment in this one, stated so she can overrule it: #818 is narrower than the row. The issue is specifically "summary card text wraps one character per line at desktop width"; the row says "the last screen before publishing reads as broken". Built is correct if the wrap was the whole of what read as broken. If she meant the row more broadly, it needs a new issue rather than a status change.

Row "Contrast enforced for real" (line 38): cite the open successor #895 ahead of the closed #878. โ€‹

  • Current:
    | Contrast enforced for real | Eng, Design | ๐Ÿ”ด P0 | axe is blind three ways (unparseable colour, exactly 1:1, layered backgrounds); the palette converges so it can see | A user's own lantern name shipped invisible behind a green 347/347 suite | ๐Ÿšง In progress | [#878](https://github.com/cattreedev/lantern_app/issues/878) |
  • Corrected:
    | Contrast enforced for real | Eng, Design | ๐Ÿ”ด P0 | axe is blind three ways (unparseable colour, exactly 1:1, layered backgrounds); the palette converges so it can see | A user's own lantern name shipped invisible behind a green 347/347 suite | ๐Ÿšง In progress | [#895](https://github.com/cattreedev/lantern_app/issues/895), [#878](https://github.com/cattreedev/lantern_app/issues/878) |
  • Status stays In progress, and it is correct. #878 closed COMPLETED on 2026-08-14 (the diagnosis and the palette convergence). #895 is open and is the remaining half: nothing enforces the ban.
  • Evidence that #895 is genuinely unbuilt: no contrast or neutral lint script exists (ls tooling/scripts/ has no match for contrast, neutral or palette, and no package.json script matches either). A grep for live neutral-* utilities across apps/ and packages/, excluding dist/, returns exactly one hit, and it is inside a code comment at apps/web/src/components/UserProfile.stories.jsx:131. So the codebase is still clean and still unguarded, exactly as #895 describes.

What questions does the operator have to answer? โ€‹

Question 1, the "Attribution, no-POS path" row: what does redeeming an offer at the counter actually mean? โ€‹

  • The question, as it needs asking: when a user with a lit lantern redeems an offer at a pilot venue, what does the staff member on the other side of the counter actually see and do? Is the animated in-app confirmation the whole mechanism (the user shows their phone, staff eyeball it, nothing is recorded on the venue side), or does staff have to acknowledge it somewhere, and does anything need to stop the same confirmation being shown twice?
  • Why an agent cannot answer it: it decides what the row's P0 scope is, and therefore what "done" means for the only attribution path pilot venues will have. #704 shipped a server-side claim and redeem flow; whether that IS this row or only the back half of it is a product call.
  • What it unblocks: filing the row's own issue, which the backlog has been holding for the same reason.
  • The question, as it needs asking: the row's Description says "final, counsel-reviewed, published, and reachable from the app". Reachable is done. Which of the other three are in scope for December? Specifically: does a lawyer read these before Alpha, or is that a Beta gate; does "published" mean the marketing site carries them too or only the app; and does the privacy policy have to be final, or is a dated draft acceptable for an invite-only cohort?
  • Why an agent cannot answer it: it is a legal-exposure judgment with a cost attached, in the same family as the trademark spend on the row below it.
  • What it unblocks: whether #141 is a December blocker or gets deferred, and whether counsel needs booking now.

How was this verified? โ€‹

The changeset was applied in memory and the result checked against live GitHub state, on 2026-08-24. โ€‹

  • Dry run: each Current block matched its target file exactly once; after replacing all eight, exactly eight lines differed (ALPHA.md 38, 62, 64, 73, 75 and PROTOTYPE.md 16, 30, 38) and no others.
  • Issue states came from one gh api graphql call over every issue number cited anywhere in either file, not from reading the numbers and assuming.

Three sweeps over the post-apply text, all clean. โ€‹

CheckBeforeAfter
Alpha P0 rows with an empty Issues cell2 (Android and iOS device testing, Business legalities and governance)0
Rows reading In progress whose cited issues are ALL closed3 (Attribution no-POS path, Untested API functions, Contrast enforced for real)0
Rows reading Not started whose cited issues are ALL closed2 (Doctor learns more, Offer review layout)0
  • The third sweep is the one that was not asked for, and it is the one that found the fifth stale row.

What did NOT change, and why? โ€‹

Nothing else in either file was touched. โ€‹

  • Tasks 9 and 10 edit ALPHA.md after this one. Every line item above is a single-row replacement so a conflict is resolvable by hand in seconds.

docs/business/launches/README.md is stale and was deliberately left alone. โ€‹

  • Its "Needs review" section still says nine rows have no issue behind them, naming penetration testing, Google Places, safety-comfort measurement, pilot venue agreements, repeatable pitch, sales and onboarding process, target launch events, Google Workspace and Slack, and hire a second engineer. All nine now carry issues (#865, #866, #867, #868, #869, #870, #871, #872, #873), verified against the rows in ALPHA.md.
  • It is outside both the four named rows and the two markers, so it is recorded here rather than edited.

Built with VitePress