Skip to content
This repository was archived by the owner on Sep 27, 2026. It is now read-only.

deck 1.1.0: the boot sweep serves the bundle catalog - #154

Merged
m4ttheweric merged 14 commits into
mainfrom
apps-2-13-b-deck-sweep
Sep 25, 2026
Merged

m4ttheweric merged 14 commits into
mainfrom
apps-2-13-b-deck-sweep

Conversation

@m4ttheweric

@m4ttheweric m4ttheweric commented Sep 25, 2026 •

Copy link
Copy Markdown
Contributor

Deck 1.1.0: the boot sweep serves the bundle catalog

Prod's deck now serves exactly the apps its bundle ships, and dev serves whatever is registered, so switching flavors no longer leaves chat on a missing working dir or gitq's CLI looping as a web app. Part of the 2.13.0 prod-readiness release (RT-279..284; this unit serves RT-280, RT-281 and RT-284).

What changed

Catalog (src/registry/bundle-catalog.ts)

  • Reads Contents/Resources/deps.lock rows that carry serve into a name to port and args map.
  • A bundle with no served rows (or no readable lock) keeps today's rules.
  • Parity fixture deps-lock-serve.fixture.json is byte-identical to repo-tools' twin from deps.lock: serve field for bundled apps mattstack#442 (sha256 pinned in both tests, prettier-ignored).

Sweep (reresolveManagedApps)

  • Both flavors create an rt row for each catalog app that has no row under any owner; prod also adopts a same-named user row, keeping its dev link.
  • A catalog app the sweep cannot create gets no row, and deck's own board row names it on every machine until it resolves: no binary in the bundle, its port held by a record, route or service, a route-only row of its name, or a legacy mrs row awaiting deck adopt mrs --as board.
  • Catalog apps serve Helpers/<name> <serve.args> from ~/.mattstack/<name>, which deck now creates.
  • rt rows outside the prod catalog are not-served: plist removed, row and dev link kept, hidden from /api/apps.
  • A plist that already matches but lost its data dir is healed and kickstarted.
  • Catalog args override stored bundle-path commands without a legacy badge.

Also

  • The spec builder refuses a missing working dir deck does not own, as a launchd issue.
  • deck restart --managed and deck setup skip not-served rows.
  • deck remove --managed <name> removes only that app through POST /api/v1/apps/managed/remove/<name> (404 unknown app, 409 <name> is not managed). A 1.0.x deck 404s that path instead of removing every app, and the bulk route refuses a name in its body.
  • /api/apps waits up to 10s for the first boot sweep, then answers 503, so the launcher never takes a half-built catalog as final.
  • An edit that would leave a user row on a missing working dir is refused before the old plist is torn down.
  • The managed-row refusal names deck remove <name> --force, not rt uninstall.
  • AGENTS.md no longer points at convert.ts; deck is 1.1.0.

Ruling applied

Dev creates missing catalog rows too (option A, ruled 2026-09-25 with three conditions): "missing" means no row of that name under any owner, so dev never adopts or duplicates; dev creates a row only when the bundle ships Helpers/<name>, otherwise it writes a board issue and creates nothing; a created row stores no bundle-absolute command. Each condition is pinned by a test.

Verification

  • New tests: catalog parser and parity fixture, catalog serve shapes, the dev to prod to dev flip on a lived-in registry, not-served, data-dir heal, catalog collisions, missing helper, named remove.
  • 16 targeted deck test files green locally (279 tests), plus 17 more files that exercise register, setup and remote flows; the full deck suite runs in the deck-macos job.
  • Review round: 12 touched test files green (263 tests) plus 6 neighbors (31), including a CLI test against a 1.0.x-shaped deck.
  • bun run format:check clean; tsc -p apps/deck adds no errors (162 before and after the review round).

Follow-up

  • Deck 1.1.0 reaches a bundle through the 2.13.0 bundle-apps dispatch and its deps.lock PR; until then the bundle ships deck 1.0.7.
  • Deploy this deck to the dev app together with or after unit E: rt main's uninstall still runs deck remove --managed board and ... gitq, which a 1.1.0 CLI treats as named removes, so chat, console and boxscore would stay installed after rt uninstall.
  • Not-served rows still read as down on deck's board in prod; a served: false status marker and board styling are a separate UI change.

🤖 Generated with Claude Code

m4ttheweric and others added 10 commits September 25, 2026 01:14
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…per by name

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…ing directory

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…nd heals missing data dirs

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…n prod

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…s deck remove --force

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…rt.ts

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@coderabbitai

coderabbitai Bot commented Sep 25, 2026 •

Copy link
Copy Markdown

Warning

Review limit reached

Next included review available in 39 minutes.

Check out review usage here.

View limit details

Limit details: You’ve used the included review currently available. Your 83 included PR review attempts over the past 7 days set your current allowance at 1 review per hour.

Your organization has reached its usage spending cap. Adjust your spending cap in the billing tab.

Learn how review limits work.

Review configuration:

⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Advanced

Run ID: fad0ffba-4b22-4c2d-b70f-27df6d45ad86

📥 Commits

Reviewing files that changed from the base of the PR and between 35a59cd and 025fd33.

⛔ Files ignored due to path filters (1)
  • bun.lock is excluded by !**/*.lock
📒 Files selected for processing (29)
  • .prettierignore
  • apps/deck/AGENTS.md
  • apps/deck/README.md
  • apps/deck/core/board/useBoardState.ts
  • apps/deck/package.json
  • apps/deck/src/api/discovery.test.ts
  • apps/deck/src/api/discovery.ts
  • apps/deck/src/api/register.test.ts
  • apps/deck/src/api/register.ts
  • apps/deck/src/api/server.test.ts
  • apps/deck/src/api/server.ts
  • apps/deck/src/api/status.test.ts
  • apps/deck/src/api/status.ts
  • apps/deck/src/boot-reresolve.test.ts
  • apps/deck/src/boot-reresolve.ts
  • apps/deck/src/cli/commands.test.ts
  • apps/deck/src/cli/commands.ts
  • apps/deck/src/main.ts
  • apps/deck/src/registry/__fixtures__/deps-lock-serve.fixture.json
  • apps/deck/src/registry/bootstrap.test.ts
  • apps/deck/src/registry/bundle-catalog.test.ts
  • apps/deck/src/registry/bundle-catalog.ts
  • apps/deck/src/registry/catalog-report.ts
  • apps/deck/src/registry/lifecycle.test.ts
  • apps/deck/src/registry/lifecycle.ts
  • apps/deck/src/registry/serve-shape.test.ts
  • apps/deck/src/registry/serve-shape.ts
  • apps/deck/src/services/bundle-layout.test.ts
  • apps/deck/src/services/bundle-layout.ts

Comment @coderabbitai help to get the list of available commands.

m4ttheweric and others added 4 commits September 25, 2026 03:43
…r deck 404s it instead of removing every app

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
… still creating catalog rows

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…alog port held by a route or service, or a legacy mrs row, stops creation

The sweep's refusals live in memory and join deck's own status row, since a helper-run deck has no platform record. editApp refuses a missing working dir before any teardown, reinstallSupervised's not-served skip is pinned, and the sweep tests never rm outside their temp dir.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…s during the boot sweep

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@m4ttheweric

Copy link
Copy Markdown
Contributor Author

CodeRabbit is rate limited on this PR (org allowance and spending cap), so an Opus review stood in. Where its findings landed, as of 025fd33:

Fixed

  • Named managed remove now uses POST /api/v1/apps/managed/remove/<name>. A 1.0.x deck 404s that path instead of removing every app, and the bulk route refuses a name in its body. There's a CLI test against a 1.0.x-shaped deck.
  • /api/apps waits up to 10s for the first boot sweep, then answers 503 with no apps key. The gate opens after 60s regardless, so a stuck sweep can't hide the catalog for the whole session.
  • Catalog refusals are kept in memory and shown on deck's own status row, so they appear on machines with no platform record. They join an existing launchd issue rather than replacing it.
  • The catalog port check now covers routes and launchd services (the app's own leftover plist is ignored) and names the holder.
  • The sweep doesn't create board while a legacy mrs row is still waiting for deck adopt mrs --as board.
  • reinstallSupervised's not-served skip is now pinned by a test.
  • editApp refuses a missing working dir before tearing down the old plist.
  • Sweep tests won't rm -rf anything outside their temp dir.
  • AGENTS.md says a catalog app removed with --force comes back on the next deck start.

Not changed here

  • The not-served status marker: the board has no rendering for it, so it's a separate UI change. It's listed under Follow-up.
  • Release ordering with unit E: this is a deploy-order note for the runbook, not a code change. It's also listed under Follow-up.

@m4ttheweric
m4ttheweric merged commit a38d976 into main Sep 25, 2026
5 checks passed
@m4ttheweric
m4ttheweric deleted the apps-2-13-b-deck-sweep branch September 25, 2026 08:58
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant