Skip to content

Folder: the bitwarden tool line follows the Environment's vault state (no vault, waiting, connected, locked) (#470) - #492

Merged
immakermatty merged 3 commits into
mainfrom
agent/DEV-6631-folder-vault-line
Oct 18, 2026
Merged

immakermatty merged 3 commits into
mainfrom
agent/DEV-6631-folder-vault-line

Conversation

@immakermatty

@immakermatty immakermatty commented Oct 18, 2026 •

Copy link
Copy Markdown
Contributor

Status: ready for review. Head 20f9c0da fixes the review blocker raised on 1bed0ca2 (CHANGES_REQUESTED): only unsupported with no-vault or no-tailnet now reads as "no vault"; any other answer, unsupported for another reason too, sends the agent to the status's reason. Verified on 20f9c0da: bun run check:static exit 0; 11 related test files 185 pass, 0 fail; the contract test (now 4 tests) fails on both 1bed0ca2'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 status answers "Not available: this Environment has no vault yet: its Machine handover names none.", lazurio vault env refuses and bw is not on PATH. The generated AGENTS.md still said:

  • bitwarden (zapnutý): Bitwarden CLI (bw) přihlášené k vlastnímu trezoru tohoto Prostředí … Trezor patří Prostředí a jeho agenti ho používají sami.

The catalog's purpose claimed 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 bitwarden line no longer claims a state. Instead it says what each answer of lazurio vault status means, 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's purpose), in English (Czech is equivalent):

Bitwarden CLI (bw) for this Environment's own vault: in its network's Lazurio Vaultwarden, or on a personal Environment in its person's own Bitwarden. Only lazurio vault status says whether there is a vault here and in which state. When it reports connected, the vault belongs to the Environment and its agents use it on their own: what you find in it you may use without asking. When it reports unsupported with the reason no-vault, there is no vault here yet, because this Environment's handover names none; with no-tailnet there is none on purpose, because this is a public Organization's Environment. From any other answer, unsupported with another reason too, do not conclude that there is no vault: it may wait for a person or not work now; follow what lazurio vault status says, its reason included. Until the vault is connected, secrets go where the Operator says.

manual/this-machine.md (the usage) changes how it begins:

  • With any answer but connected, agents use neither bw nor lazurio vault env. When they need a secret, they tell the Operator what the status says and ask where the secret belongs.
  • With a connected vault, agents start with eval "$(lazurio vault env)". When bw reports the vault locked (connected with locked), 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 status answers What the line tells the agent
unsupported / no-vault (the issue's Environment) No vault here yet: the handover names none. Secrets go where the Operator says. Don't use bw or vault env.
unsupported / no-tailnet (#481's public Organization case) No vault here on purpose: this is a public Organization's Environment. Same steps.
unsupported with any other reason: handover-unreadable, folder-unreadable, not-operator, connection-unreadable (review of 1bed0ca2) Not "no vault": don't conclude absence, follow what the status says, its reason included. An unreadable handover says nothing about a vault either way, and an unreadable connection record belongs to a personal Environment that has a vault. Meanwhile, no bw or vault env, and secrets go where the Operator says.
Waiting for a person: needs-connection, not-allowed, not-set-up and the rest The vault waits for a person or does not work now. Same steps.
connected The Environment's vault, used by its agents on their own. Start with vault env.
connected with locked Run vault env again, which unlocks it.

The generated bytes change on every Remote Environment where bitwarden is on. The template revision therefore moves to base-instructions-57 with 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), and docs/environment-tools.md describes the texts.

What intentionally does not change

  • No vault state is recorded in the Folder. The handover's vault member 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:

    • a refresh that renders the same bytes records nothing (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;
    • a 0197 pilot whose handover names no vault is connected;
    • waiting, connected and locked are live states. The Folder changes only by an explicit change (F14), so it could never track them.

    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 on connected) and the setup prompt (lazurio tools prompt bitwarden) are unchanged.

Verified

On head 20f9c0da:

Contract test tests/folder-vault-line.test.ts (4 tests) runs on the real consumer: the generated AGENTS.md and manual/this-machine.md of the same handover, compared with the real lazurio vault status, in Czech and English.

  1. No vault. The production composition of lazurio vault runs on real files: a root-issued handover, an adopted hosted Folder and the declared operator. It answers:

    • unsupported/no-vault for the issue's Environment;
    • unsupported/no-tailnet for a public Organization's Environment;
    • needs-connection for a personal Environment waiting for its person.

    lazurio vault env refuses each one (exit 2), and the line says what that answer means.

  2. Another reason (new, review of 1bed0ca2). On the same real composition:

    • the handover is made unreadable after adoption: the answer is unsupported/handover-unreadable, "Not available: the Machine handover cannot be read.";
    • a personal Environment's connection record is made unreadable: the answer is unsupported/connection-unreadable.

    Neither answer says "no vault" and vault env refuses both. The line names unsupported exactly twice: in the absence tied to no-vault (and no-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.

  3. Vault in the handover (fake vault and fake bw). The line follows not-set-up, then not-allowed, then connected (vault env hands out the session), then connected with locked (running vault env again unlocks it).

  4. Every fixture binding in both languages: no claim of a signed-in vault, lazurio vault status named as the source, and unsupported only in those two clauses.

Against 1bed0ca2's text and against main's text, all four tests fail. The new test 2 fails on 1bed0ca2 at the structural check: one generic unsupported mention, no reason-tied absence and no follow-the-reason clause, after the CLI had already answered handover-unreadable and connection-unreadable.

Risks and open points

  • The line is now the same, state-neutral text on every Remote Environment, and longer: the purpose in AGENTS.md grows from 289 to 794 characters in Czech and from 282 to 888 in English. An agent learns which case applies only by running lazurio vault status, which the text tells it to do. The 32 KB AGENTS.md budget test passes.
  • Merge order: this takes 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.
  • Observed, not changed: the setup prompt's target state (installation of bitwarden) names no-vault but not Trezor: an Environment without a vault explains the vault; the public Organization has none on purpose (DEV-6631) #481's no-tailnet. It is not part of the Folder, so I left it for a separate small change if wanted.

Work context

Fixes #470

🤖 Generated with Claude Code

Note

Make Bitwarden tool line follow the Environment's vault state instead of claiming signed-in

  • The generated Bitwarden instructions no longer assert the agent is signed in. They now branch on lazurio vault status: connected, unsupported (no-vault, no-tailnet), waiting, or locked.
  • Agents are told to use neither bw nor lazurio vault env unless status is connected, and to rerun lazurio vault env when 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.
  • Bumps folder.instructionTemplateRevision from base-instructions-56 to base-instructions-57, with snapshot and digest updates in the render and template-revision tests.
  • Adds folder-vault-line.test.ts covering the full vault lifecycle via the fake vault, plus real Remote Environment files for no-vault, no-tailnet, and waiting states in both locales.
  • Behavioral Change: all generated AGENTS.md and manual/this-machine.md outputs now use status-driven wording; check the base-instructions-57 snapshots 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.

…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>
@immakermatty
immakermatty marked this pull request as ready for review October 18, 2026 10:37
…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 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 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 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 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.

@immakermatty
immakermatty merged commit 82e9519 into main Oct 18, 2026
7 checks passed
@immakermatty
immakermatty deleted the agent/DEV-6631-folder-vault-line branch October 18, 2026 11:25
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.

Folder instructions call the bitwarden tool on and signed in where the handover names no vault

2 participants