Repository navigation
Folder: the bitwarden tool line follows the Environment's vault state (no vault, waiting, connected, locked) (#470) - #492
Conversation
…aiming a signed-in vault (#470) The catalog entry bitwarden told agents in AGENTS.md that the Bitwarden CLI is signed in to the Environment's own vault, on every Environment where the tool is on. On a work Environment whose handover names no vault, lazurio vault status answers that there is none and lazurio vault env refuses, so the generated instructions contradicted the one source of truth. The purpose now claims no state: only lazurio vault status says whether there is a vault and in which state; connected is the vault its agents use on their own; unsupported is none here (no-vault: the handover names none yet; no-tailnet: a public Organization's Environment, which has none on purpose); any other state waits for a person or does not work now; until the vault is connected, secrets go where the Operator says. The usage starts work with lazurio vault env only with a connected vault and runs it again when bw reports the vault locked. The Folder records no vault state: it changes only by an explicit change (F14), and the handover's vault member stays out of its binding. The generated bytes change on every Remote Environment where bitwarden is on: the template revision moves to base-instructions-57 with its pinned digest; the snapshots change only in their revision line. F53 gains an addendum and docs/environment-tools.md describes the texts. Test: tests/folder-vault-line.test.ts pairs the generated line with the real lazurio vault status for no-vault, no-tailnet, needs-connection, not-set-up, not-allowed, connected and locked, in both languages. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…ened (2026-10-16) The addendum said the issue asked for the change on 2026-10-18, the day of the fix; the issue was opened on 2026-10-16. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
agentrozjedemeai
left a comment
There was a problem hiding this comment.
@immakermatty CHANGES_REQUESTED on exact head 1bed0ca.
Blocker — src/tools/catalog.ts:393-394 says that any unsupported status means “there is no vault here” (and lists only no-vault / no-tailnet). But the status core returns unsupported for folder-unreadable, handover-unreadable, not-operator, and connection-unreadable too (src/vault/host.ts, src/vault/context.ts). I exercised statusText(unsupportedStatus(...)) on the exact head: for connection-unreadable it reports that the record of an already connected personal vault cannot be read, while the generated AGENTS.md categorically says there is no vault. An unreadable handover cannot establish absence either. This recreates an untrue generated instruction in the precise status-driven contract being fixed. Please limit the “no vault” claim to unsupported with no-vault or no-tailnet, and tell agents to follow the CLI reason for other unsupported results; align the F53 addendum/environment-tools prose and add a negative test for e.g. connection-unreadable / handover-unreadable. Do not add vault state to the Folder binding: that design choice is sound.
Verified locally in a detached clean checkout: 145 passed, 0 failed across the ten specified files; revision 57 digest and revision-only snapshots pass, diff --check clean. GitHub checks completed successfully (non-applicable checks skipped); no unresolved threads at preflight. Last commit changes only the issue date in docs, consistent with #470 opened 2026-10-16. No merge performed.
…n line; any other reason follows the status (#470) Review of #492: the line said that any unsupported answer of lazurio vault status means there is no vault here. The status core also answers unsupported for an unreadable Folder or handover, another operator and a personal Environment whose record of the Bitwarden its person connected cannot be read. An unreadable handover cannot establish absence, and that personal Environment has a vault. The purpose now says there is no vault only for unsupported with the reason no-vault (not yet: the handover names none) or no-tailnet (on purpose: a public Organization's Environment). From any other answer, unsupported with another reason too, an agent does not conclude that there is no vault and follows what the status says, its reason included. The usage is unchanged: anything but connected uses neither bw nor lazurio vault env, and a secret goes where the Operator says. base-instructions-57 is not released, so the revision stays and its pinned digest changes; the snapshots do not move. F53's addendum and docs/environment-tools.md say the same. Test: tests/folder-vault-line.test.ts adds handover-unreadable and connection-unreadable over the production composition on real files: neither answer says no vault, and the line names unsupported only in the absence tied to no-vault and no-tailnet and in the rule for any other reason. Against the text before, all four tests fail. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
agentrozjedemeai
left a comment
There was a problem hiding this comment.
@immakermatty APPROVED on exact head 20f9c0d. The round-1 blocker is resolved: the generated Czech and English bitwarden line asserts vault absence only for unsupported/no-vault or unsupported/no-tailnet; all other answers, including unreadable handover/connection, direct the agent to the live lazurio vault status reason without inferring absence. The unchanged usage refuses bw and vault env unless connected. F53 and environment-tools agree. I traced the status composition and exercised the negative file-backed fixtures plus all 11 related test files locally: 185 passed, 0 failed; check:static passed, revision digest/snapshots passed, diff --check clean. GitHub checks green on this SHA; no unresolved review threads at preflight. No merge performed; Publication remains with Matěj.
Status: ready for review. Head
20f9c0dafixes the review blocker raised on1bed0ca2(CHANGES_REQUESTED): onlyunsupportedwithno-vaultorno-tailnetnow reads as "no vault"; any other answer,unsupportedfor another reason too, sends the agent to the status's reason. Verified on20f9c0da:bun run check:staticexit 0; 11 related test files 185 pass, 0 fail; the contract test (now 4 tests) fails on both1bed0ca2's and main's text and passes here; CI green (static checks, tests 1/2 and 2/2, check ubuntu-24.04, scope).Why
Issue #470: on an Organization's work Environment whose Machine handover names no vault (its network has no Lazurio Vaultwarden yet),
lazurio vault statusanswers "Not available: this Environment has no vault yet: its Machine handover names none.",lazurio vault envrefuses andbwis not on PATH. The generatedAGENTS.mdstill said:The catalog's
purposeclaimed the vault as signed in on every Environment where the person's switch "Používají agenti" is on, whatever the vault's real state. So the main instruction file contradicted the one source of truth, which the manual itself tells agents to read first.What changes
The
bitwardenline no longer claims a state. Instead it says what each answer oflazurio vault statusmeans, using the codes the status reports. This is the same state machine the CLI uses (vault core, #481), not a second one.AGENTS.md(the tool'spurpose), in English (Czech is equivalent):manual/this-machine.md(theusage) changes how it begins:connected, agents use neitherbwnorlazurio vault env. When they need a secret, they tell the Operator what the status says and ask where the secret belongs.eval "$(lazurio vault env)". Whenbwreports the vault locked (connectedwithlocked), they run that command again.The rest of the usage is unchanged: the paths a, b and c, and the Publication rule.
How this maps to the issue's states:
lazurio vault statusanswersunsupported/no-vault(the issue's Environment)bworvault env.unsupported/no-tailnet(#481's public Organization case)unsupportedwith any other reason:handover-unreadable,folder-unreadable,not-operator,connection-unreadable(review of1bed0ca2)bworvault env, and secrets go where the Operator says.needs-connection,not-allowed,not-set-upand the restconnectedvault env.connectedwithlockedvault envagain, which unlocks it.The generated bytes change on every Remote Environment where
bitwardenis on. The template revision therefore moves tobase-instructions-57with its pinned digest; the snapshots change only in their revision line. Existing Folders get the new text at their next refresh, which Machines runs after every apply. The decision is recorded as F53's addendum of 2026-10-18 (docs/decisions.md), anddocs/environment-tools.mddescribes the texts.What intentionally does not change
No vault state is recorded in the Folder. The handover's
vaultmember stays out of the Folder's binding, as the handover contract says. I considered recording "the handover names a vault" in the binding so the line could say "there is none" unconditionally, and rejected it:unchanged). On an Environment with the switch off, a fact recorded before its network got a Vaultwarden would stay stale. The setup that turns the switch on once the vault is ready would then render "none" at exactly the wrong moment;The line therefore follows the CLI: it names its answers and leaves the live one to
lazurio vault status. The alternatives are in the addendum's table.The vault core,
lazurio vault status/env/setup, the Tools row, Nastavení → Trezor, the manual's Secrets section (already conditional onconnected) and the setup prompt (lazurio tools prompt bitwarden) are unchanged.Verified
On head
20f9c0da:bun run check:static: exit 0. Biome checked 754 files,tsc --noEmitpasses, check:public PASS over 929 files, build:proof and smoke:proof PASS.folder-vault-line,folder-template-revision,folder-tools,folder-render,folder-manual,tools,vault-cli,launchpad-tools,vault-host,vault-context,environment-wording).119c00c0, the author's full localbun test: 3929 pass, 9 skip, 1 fail. The failure was the known load flake intests/launchpad-prompts.test.ts(Flaky: launchpad-prompts expects no GitHub call before admission, but the Launchpad's start peeks the Personalspace holder in the background #413, Flaky under a loaded full run: launchpad-prompts "hosted personal: new-personal-module …" sees a GitHub viewer call before the first request #425, Flaky test: hosted personal new-personal-module records an unexpected viewer call #490), which passes 11/11 alone, three times in a row.Contract test
tests/folder-vault-line.test.ts(4 tests) runs on the real consumer: the generatedAGENTS.mdandmanual/this-machine.mdof the same handover, compared with the reallazurio vault status, in Czech and English.No vault. The production composition of
lazurio vaultruns on real files: a root-issued handover, an adopted hosted Folder and the declared operator. It answers:unsupported/no-vaultfor the issue's Environment;unsupported/no-tailnetfor a public Organization's Environment;needs-connectionfor a personal Environment waiting for its person.lazurio vault envrefuses each one (exit 2), and the line says what that answer means.Another reason (new, review of
1bed0ca2). On the same real composition:unsupported/handover-unreadable, "Not available: the Machine handover cannot be read.";unsupported/connection-unreadable.Neither answer says "no vault" and
vault envrefuses both. The line namesunsupportedexactly twice: in the absence tied tono-vault(andno-tailnet), and in the rule that sends any other reason to the status, with "its reason included" / "včetně důvodu". It holds no absence clause for the reported reason.Vault in the handover (fake vault and fake bw). The line follows
not-set-up, thennot-allowed, thenconnected(vault envhands out the session), thenconnectedwithlocked(runningvault envagain unlocks it).Every fixture binding in both languages: no claim of a signed-in vault,
lazurio vault statusnamed as the source, andunsupportedonly in those two clauses.Against
1bed0ca2's text and against main's text, all four tests fail. The new test 2 fails on1bed0ca2at the structural check: one genericunsupportedmention, no reason-tied absence and no follow-the-reason clause, after the CLI had already answeredhandover-unreadableandconnection-unreadable.Risks and open points
purposeinAGENTS.mdgrows from 289 to 794 characters in Czech and from 282 to 888 in English. An agent learns which case applies only by runninglazurio vault status, which the text tells it to do. The 32 KBAGENTS.mdbudget test passes.base-instructions-57. No other open PR claims it; only the stale Agents: deliver account protection to every Folder preset #440 bumps to 54. A PR merged first with its own bump needs this one rebased onto the next number and re-pinned.installationofbitwarden) namesno-vaultbut not Trezor: an Environment without a vault explains the vault; the public Organization has none on purpose (DEV-6631) #481'sno-tailnet. It is not part of the Folder, so I left it for a separate small change if wanted.Work context
HumanAndMachine-ai_GEN3/.worktrees/productionspace/LazurioPlatform/DEV-6631-folder-vault-line, branchagent/DEV-6631-folder-vault-linefrommain7443bd43(with Trezor: an Environment without a vault explains the vault; the public Organization has none on purpose (DEV-6631) #481).HumanAndMachine-ai/mission-control-data:v3,data/mission-control/plans/2026/09/DEV-6631-environment-agent-vault.yaml), root decision 0203.docs/decisions.md.Fixes #470
🤖 Generated with Claude Code
Note
Make Bitwarden tool line follow the Environment's vault state instead of claiming signed-in
lazurio vault status: connected, unsupported (no-vault, no-tailnet), waiting, or locked.bwnorlazurio vault envunless status is connected, and to rerunlazurio vault envwhen a connected vault is locked. Purpose and usage text updated in both Czech and English in catalog.ts, with guidance rules documented in environment-tools.md and an F53 addendum decision record in decisions.md.folder.instructionTemplateRevisionfrombase-instructions-56tobase-instructions-57, with snapshot and digest updates in the render and template-revision tests.base-instructions-57snapshots in folder-render.test.ts.snap and folder-manual.test.ts.snap if downstream content depends on the old signed-in claim.Macroscope summarized 119c00c.