Skip to content

Apps → Trezor only where a vault is: the entry follows the vault core's answer (F36/F53 addendum, DEV-6612) - #500

Merged
immakermatty merged 3 commits into
mainfrom
agent/DEV-6612-trezor-where-vault
Oct 18, 2026
Merged

immakermatty merged 3 commits into
mainfrom
agent/DEV-6612-trezor-where-vault

Conversation

@immakermatty

@immakermatty immakermatty commented Oct 18, 2026 •

Copy link
Copy Markdown
Contributor

Why

Matěj (Organization Admin) decided on 2026-10-18 that the Trezor entry of the Apps column appears only in an Environment that has a vault (root decision 0185's addendum, HumanAndMachines/Lazurio#577, open):

  • the Personal Environment, whether its person has connected their own Bitwarden or not (the page is also where they connect it, root 0203 point 7);
  • an Organization's Work or Team Environment whose handover names a vault.

It does not appear in an Organization's Environment without a vault (a public Organization's among them, which has none on purpose), nor on your computer. #495 listed it everywhere except your computer.

The predicate

Visibility is the vault core's own answer, the one lazurio vault status starts from: VaultHost.context() (in production readVaultContext in src/vault/host.ts → vaultContextOf / VaultUnsupportedReason). There is no second rule, no new handover parsing, and nothing is keyed on an Organization's name or slug (#499).

  • vaultListed(answer) in src/launchpad/vault-page-view.ts: the pure rule over the core's answer.
  • vaultAnswer(host) in src/vault/flow.ts: the vault core's one resolution, read by both vaultStatus (lazurio vault status) and the Apps column. It is host.context() with a 0197 pilot that was never connected answered as no-vault (see below). vaultInAppsOf(host) in src/launchpad/boot-document.ts is vaultListed(await vaultAnswer(host)), and it falls back to listed if anything throws.
The core's answer Trezor in the Apps column
own (the handover's vault; a personal Environment's own Bitwarden, connected) listed
needs-connection (a personal Environment whose person has not connected it yet) listed
pilot, account connected the 0197 way listed
pilot, never connected hidden (its status is no-vault)
unsupported: no-vault, no-tailnet, workstation hidden
unsupported: folder-unreadable, handover-missing, handover-unreadable, not-operator, connection-unreadable listed (the page shows the fault)
reading the core throws listed

Where I followed the code instead of the brief (pilot). The brief says to show a pilot context. But readVaultContext returns a pilot context for every Organization's Environment whose handover names no vault, as long as it sits on a network whose control server is https://headscale.<zone>. For those it does not check whether a pilot was ever connected; only personal Environments get that check. Their status, however, is no-vault (pilotStatus → pilotOf null → unsupportedStatus("no-vault")), and their page is the no-vault explanation from #481. So with the context alone, nearly every Organization's Environment without a vault would still list Trezor, which is the exact case the decision is about. The core therefore resolves a pilot once in vaultAnswer with its own pilotConnected (the same check readVaultContext already makes for personal Environments and the same first step pilotStatus takes; it reads only the pilot's account file, never bw). vaultStatus and the Apps column both read that one answer, so they never disagree. After the DEV-6631 vault lead's review, the Launchpad imports nothing from legacy-0197. The fault reasons stay listed as the brief says; nothing in the code or the F-records says otherwise.

First paint. The server decides, the way the boot document already carries the entry the audience is drawn from. pageBoot() reads vaultInAppsOf(vaultHostOf()) beside the Folder's state, inside the boot document's existing 500 ms budget. It uses only local files (the Folder, the handover, the vault's custody), with no bw and no network. The boot document (lazurio.launchpad-boot.v1) gets one additive member, vaultInApps: boolean | null. Where it is false, withBoot serves the page with hidden on #vault-nav. ui.ts draws the item from the same member at script start, before data-ready, and in firstRun. This extends #495's path (vaultInApps in vault-page-view.ts, now vaultInApps(carried, preset)) instead of adding a parallel one. A page that carries no answer falls back to the preset rule of #495: your computer's page has no boot document and hides Trezor by local, and a hosted page whose boot document came late lists it.

Deliberately unchanged

Records

  • docs/decisions.md: new F53 addendum of 2026-10-18 (3): Trezor only where the Environment has a vault. It replaces point 2 of F53's addendum (2), that addendum's rejected alternative "List Trezor only where there is a vault" and its wireframe deviation. Amendment notes are added on F36's addendum "the Apps column holds Trezor" and on the first-paint addendum's boot-document point.
  • docs/launchpad-development.md: the column, the Vault section and a short "Where the column lists Trezor".
  • src/vault/legacy-0197/README.md: its deletion condition now names the pilot branch of vaultAnswer in ../flow.ts.

Verification

  • bun run check:static: pass (biome, tsc, public guard, proof build and smoke).
  • tests/launchpad-apps-vault.test.ts (21 tests): vaultListed for every answer and every reason, with a new reason failing to compile. Also vaultInApps with and without a carried answer, and over HTTP a hosted Launchpad whose vault facts are read by the production composition (processVaultHost). Only the handover's place, the operator's record and the state root are the test's. It covers 11 Environments: personal waiting, personal connected, personal with an unreadable connection, work with a vault, Team with a vault, work without a vault as a never-connected pilot, work connected the 0197 way, work without a vault on a network no pilot derives from, public without a network, a hosted Folder read off Linux, and a missing handover. Each is served with the item listed or hidden, with the same answer in its boot document. Old and new vault addresses are served where it is hidden and stay 404 on the public one. The workstation's page has no boot document, and a core that throws leaves the entry listed. Against the code before, the four hiding cases and the never-connected pilot fail (mutation-checked).
  • tests/launchpad-boot.test.ts, tests/launchpad-first-paint.test.ts, tests/public-environment.test.ts, tests/vault-page-view.test.ts, tests/vault-host.test.ts, tests/launchpad-routes.test.ts, tests/launchpad-vault-page.test.ts, tests/launchpad-hosted.test.ts, tests/launchpad-vault.test.ts, tests/vault-requests.test.ts: pass.
  • Full suite bun test --timeout 30000: 3990 pass, 9 skip, 1 fail of 4000 tests across 276 files (915.8 s). The one failure is tests/application-environment.test.ts, "a declared sibling …": the module lifecycle answered port-occupied for a module start while preview Launchpads of the browser check were running on the same machine. Rerun alone, the file passes 9/9. It is unrelated to this change.
  • After the vault lead's review (head ffddf680): vaultAnswer refactor and a merge of main (Theme: one colour theme per Environment, chosen in Settings and followed by Chat, Apps and Automate (root 0208, F36 addendum) #493 theme; both boot members kept). check:static passes; all 24 vault and boot test files (234 tests) and the theme tests pass. The per-Environment HTTP test now also asserts that vaultStatus says workstation/no-vault/no-tailnet exactly where the column hides Trezor. The full suite on this head is reported in a comment below.
  • Headless Chrome (playwright-core with the installed Chrome, root decision 0178) against scripts/preview-launchpad.ts at 1440 × 900, in Czech. An init script recorded the item's hidden state and the page's data-ready on every animation frame from the start:
    • Personal (personal, waiting for its person): column Všechny moduly, Soubory, Integrace, Trezor; /vault opens it.
    • Work with a vault (hosted) and Team with a vault (hosted … team): Trezor listed.
    • Work without a vault (hosted … no-vault) and public without a network (hosted … no-tailnet): served with hidden, and hidden from the very first frame, with no flash. /vault and the old /settings/vault (the address is rewritten to /vault) open the page with its explanation, with the column still without Trezor.
    • Your computer (local): no boot document; the item is hidden while the page itself is still hidden (before data-ready), so nothing flashes; /vault still answers.
    • Public (hosted … public, whose preview vault answers own): F55's stylesheet still hides Trezor and Integrace; /vault answers 404 and shows the Apps home.
    • No page errors. The only failed requests are the preview's known gaps (/.lazurio/account/environments, /api/update/status, /api/content/jobs/latest). These are no rendered-page CI gates; screenshots are kept locally.

Risks

  • One more read on a hosted page's path. It takes the Folder read lock beside readShellInputs and reads a few small local files. If the Folder is held by another operation, the boot document is dropped as before. The page then shows Trezor until the next load (the fail-safe), even where there is no vault.
  • Read once per page load. An Environment that gains or loses its vault while its page is open shows the change at the next load.
  • A new consumer of the frozen 0197 pilot code. It is noted in its deletion list, and the compiler would flag it on deletion.
  • A connected 0197 pilot on a work Environment stays listed, as its status is connected. Whether any such pilot remains is the vault thread's inventory (DEV-6631 task 649).

Plan: DEV-6612 (HumanAndMachine-ai/mission-control-data:v3:data/mission-control/plans/2026/09/DEV-6612-produkt-jedna.yaml). Root record: HumanAndMachines/Lazurio#577.

🤖 Generated with Claude Code

Note

Show Trezor in Apps column only when the vault core lists it

  • The hosted page boot now computes a server-side vault-column decision via vaultInAppsOf and passes it into the boot document; the Trezor item is hidden in first-paint markup when the decision is false (boot-document.ts, server.ts)
  • The boot data contract gains a nullable vaultInApps member; parseBoot maps missing, null, and malformed values to null without invalidating the boot object (boot.ts)
  • Client rendering honors the carried server decision and falls back to the workstation preset only when no decision is present (ui.ts, vault-page-view.ts)
  • Adds a full decision matrix, served-HTTP integration harness, and fixtures for Environment kinds, pilot states, and unreadable vault cores (launchpad-apps-vault.test.ts)
  • Documents the rule in the F53 addendum and Launchpad behavior guide (decisions.md, launchpad-development.md)
  • Risk: Trezor visibility now changes for no-vault and no-tailnet hosted Environments (previously listed); the vaultInAppsOf resolver must be removed when the legacy 0197 pilot is deleted (README.md)

Macroscope summarized 9d164d5.

…vault core answers

Matěj decided on 2026-10-18 (root decision 0185's addendum,
HumanAndMachines/Lazurio#577) that the Apps column lists Trezor only in
an Environment that has a vault: a personal Environment, connected or
not, and an Organization's work or Team Environment whose handover names
one. Not an Organization's Environment without a vault, a public one
among them, nor this computer. #495 listed it everywhere but `local`.

The rule is the vault core's answer, the one `lazurio vault status`
starts from (`VaultHost.context()`, `readVaultContext`): `vaultListed`
hides it for `no-vault`, `no-tailnet` and `workstation`, and keeps it for
`own`, `needs-connection` and the faults the page says. A 0197 pilot is
resolved as its status resolves it: the context derives a pilot for
every Organization's Environment on a `headscale.<zone>` network, so one
never connected (`pilotConnected` false, status `no-vault`) is not
listed. No handover parsing of its own, nothing keyed on an
Organization's name (#499).

The server decides it for the first paint: `vaultInAppsOf` reads it
beside the Folder's state from local files only (never bw), the boot
document carries it as `vaultInApps`, and the page is served with
`hidden` on `#vault-nav` where it is false; ui.ts draws the item from
the same member. A page without a boot document follows its preset as
before. `/vault`, `/settings/vault` and their requests stay served
everywhere; the vault page and F55's public rule are unchanged.

Recorded as F53's addendum of 2026-10-18 (3), with notes on F36's and
F53's addenda of 2026-10-18 and on the first paint's boot document;
launchpad-development.md and the frozen pilot's deletion list follow.
Tested over HTTP with the production composition of the vault's facts
(11 Environments), the pure rule for every reason, the boot document's
member and a core that throws.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@immakermatty
immakermatty marked this pull request as ready for review October 18, 2026 15:18
immakermatty and others added 2 commits October 18, 2026 17:24
…r), so the Launchpad imports nothing from legacy-0197

The DEV-6631 vault lead's review of #500: the Launchpad resolved a 0197
pilot itself (`pilotConnected` in boot-document.ts), a second resolution
beside `pilotStatus` and a legacy-0197 import outside the vault core.

`vaultAnswer` (src/vault/flow.ts) is now the one place: the host's context
with a pilot never connected answered as `no-vault`. `vaultStatus`
(`lazurio vault status`) and `vaultInAppsOf` both read it, so the status and
the column never disagree. The test of every hosted Environment also checks
that the status says "no vault" exactly where the column hides Trezor.
The legacy README's deletion list names the pilot branch of `vaultAnswer`.

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

# Conflicts:
#	src/launchpad/boot-document.ts
#	src/launchpad/server.ts

@agentrozjedemeai agentrozjedemeai left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@immakermatty Exact-head review of ffddf68: approved. The predicate covers all declared unsupported reasons; the server and UI consume the same boot decision before the first visible paint, while exceptions leave the entry listed. The pilot resolution is shared with vault status, uses local vault facts rather than Organization names, and the served-HTTP tests exercise the production host composition. The F53/F36 amendments preserve the public-Environment F55 exception and disclose the future public-Team-with-vault follow-up. No public data or credential exposure found in the diff. Local isolated checkout: 64 focused tests passed, check:static passed, git diff --check clean. Live CI green; zero review threads.

@immakermatty

Copy link
Copy Markdown
Contributor Author

Full suite on head ffddf68 (bun test --timeout 30000): 4041 pass, 9 skip, 0 fail, 4050 tests across 281 files.

@immakermatty

Copy link
Copy Markdown
Contributor Author

Vault-core review by the DEV-6631 vault lead, at head ffddf680. This is a comment, not an approval: the PR is authored under the same account, and Pablo reviews Lazurio/* changes.

Result: OK for the vault boundary.

@immakermatty
immakermatty merged commit 7a607cf into main Oct 18, 2026
7 checks passed
immakermatty added a commit that referenced this pull request Oct 19, 2026
… in Apps, three kinds of words, the theme

Brings #467 up to date with main (dbee5f6) after the guide F56 (#501-#503,
#509), Apps → Trezor (#495, #500), three kinds of Environment (#497), one
colour theme per Environment (#493) and the tour's gear stop (#475).

One textual conflict, in scripts/preview-launchpad.ts: main's `team` flag
for a hosted Team Environment and this branch's `workspace-tabs` flag sit
side by side; each keeps its own option. The section head keeps main's
accent colour (`--lz-accent`, #493) for its flag and rule.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants