Repository navigation
feat: run more than one vault-cortex install on a machine with INSTANCE_NAME - #686
Conversation
|
umm-actually re-reviewed at No new findings (53 tracked finding(s) across all runs). Review phase The review deadline expired; results from completed phases are shown. Context notes
umm-actually · z-ai/glm-5.3-flash |
cdc50ef to
6c9c857
Compare
|
Update DEPLOY.md's stale two-service compose description
Pre-existing: DEPLOY.md still says docker-compose runs two services in order and credits the forked sync image, describing the architecture that commit dd2489f replaced with the single Failure scenario: A user reading DEPLOY.md to deploy the remote stack expects two services (obsidian-sync plus the MCP server) and searches ARCHITECTURE.md for a 'Docker Compose Startup' section that no longer exists, then cannot map the documented topology onto the single-service compose file they downloaded. Suggested fixRewrite the passage to describe the single-container stack ('docker compose runs one vault-cortex service; the s6 init chain performs login and sync-setup inside the container') and point to the current ARCHITECTURE.md s6 startup section by its actual heading.umm-actually · z-ai/glm-5.3-flash |
|
Re the umm-actually PR-level finding "Update DEPLOY.md's stale two-service compose description" (comment 6305929440): false positive. DEPLOY.md line 100 already says Compose runs one 🔍 ship-check · pr-monitor · claude-opus-5-5 |
|
Drop configure.test.ts's local createRecordingDocker in favor of the shared stub
This PR adds createRecordingDocker to command-stubs.ts and switches init, lifecycle and upgrade tests to it, but configure.test.ts still defines its own local copy with a narrower shape (no calls/runParams recording beyond dockerRun). The duplicate can drift from the shared one, as it already has (it lacks the inspect/rm/logs recording the shared version now provides). Failure scenario: A future change to DockerRunner or the recording shape updates command-stubs' helper but not configure.test.ts's local copy, so configure tests silently assert against a stale stub shape or fail to record operations the shared helper would capture. Suggested fixImport createRecordingDocker from ./command-stubs.js in configure.test.ts and delete the local definition.umm-actually · z-ai/glm-5.3-flash |
|
Init's success message references .env settings for a kept legacy file it never validated
runRemoteInit's start offer runs after the optional-settings and write steps, and for a kept legacy .env (one whose PUBLIC_URL line is empty or absent) offerDockerRun proceeds straight to docker run — resolveDeployment's PUBLIC_URL validation lives only in restart/upgrade/configure paths. A remote .env kept by init with PUBLIC_URL= empty boots a container whose OAuth issuer is unset, which the server rejects at startup; init's gate ladder doesn't check it the way the other start paths do, so the failure surfaces as docker's health timeout instead of the clear PUBLIC_URL message. Failure scenario: A user re-runs init --mode remote over a compose-era directory whose kept .env has an empty PUBLIC_URL= line, accepts the overwrite=false keep, and answers yes to 'Start the server now?': the container starts, OAuth binding fails at boot, and after 4 minutes init prints only the generic health-timeout message with no pointer to the missing PUBLIC_URL, while restart for the same directory would have named it. Suggested fixIn runRemoteInit, before offering the start, apply the same PUBLIC_URL presence check resolveDeployment uses (or reuse resolveDeployment's validation) so a kept legacy .env gets the explicit 'PUBLIC_URL not found in <dir>/.env' error instead of a health timeout.umm-actually · z-ai/glm-5.3-flash |
|
Re the umm-actually PR-level finding "Drop configure.test.ts's local createRecordingDocker in favor of the shared stub" (comment 6306297657): fixed in be40c0e. configure.test.ts now imports createRecordingDocker from command-stubs.ts and asserts on its runParams record; the local copy is gone. 🔍 ship-check · pr-monitor · claude-opus-5-5 |
|
Re the umm-actually PR-level finding "Init's success message references .env settings for a kept legacy file it never validated" (comment 6306372327): false positive. The finding says restart would have named the missing PUBLIC_URL, but 🔍 ship-check · pr-monitor · claude-opus-5-5 |
|
Fix the stale start-offer test that passes only because Docker is down
The remote-flow test named 'skips the start offer when the sync token was left blank' no longer verifies any token-dependent behavior: runRemoteInit now offers the start regardless of token state (setup mode handles a blank one), and the offer is skipped only because the test's dockerDown stub short-circuits offerDockerRun at its daemon check, before the confirm is ever reached. The sibling test in the same describe asserts the offer IS asked with a blank token, so this test cannot fail for the behavior its name claims. Failure scenario: With Docker actually running, the same blank-token remote init asks 'Start the server now?' — the sibling 'leaves OBSIDIAN_AUTH_TOKEN blank when auto-capture is declined' test (dockerDaemonOnly) asserts exactly that. Mutating or removing any token-related logic cannot make this test fail, because dockerDown returns 'not-started' from offerDockerRun's daemon gate before the confirm; a reader trusting the test name concludes init refuses to start token-less installs, the opposite of the PR's stated 'Remote init offers to start without a Sync token' behavior. Suggested fixRename the test to what it actually pins (e.g. "does not offer to start when Docker is down, even with a blank token") or fold it into the daemon-down coverage without the token framing; if the blank-token start behavior is what should be pinned, drive it with a running-daemon stub (dockerDaemonOnly/dockerReadyEmptyHost) and assert the offer is asked, matching the sibling test.umm-actually · z-ai/glm-5.3-flash |
|
Fix the remote-init test whose blank-token skip no longer exists
Remote init now offers the start step even when OBSIDIAN_AUTH_TOKEN is blank (the container serves its sign-in page), so the behavior this test's name claims no longer exists. The assertion still holds only because the fixture runs with the Docker daemon down, which suppresses the start question for any token state. Failure scenario: A maintainer editing the remote init flow reads the test name, concludes a blank Sync token still suppresses the start offer, and relies on that contract; the suite stays green through any rewrite of the offer gating because dockerDown's daemon check — not token logic — is what keeps 'Start the server now?' out of the asked prompts. Suggested fixRename the test to the gate it actually pins (the not-running daemon suppresses the start question), or run it against a ready daemon and assert the offer now appears for a blank token, matching the new sign-in-page flow.umm-actually · z-ai/glm-5.3-flash |
|
Re the umm-actually PR-level findings "Fix the stale start-offer test that passes only because Docker is down" (comment 6321777433) and "Fix the remote-init test whose blank-token skip no longer exists" (comment 6321777720): both point at the same test, and both are valid. Fixed in 65e03ba. The test "skips the start offer when the sync token was left blank" described behaviour this PR removed. Remote init now offers to start without a Sync token, and two other tests pin that: "leaves OBSIDIAN_AUTH_TOKEN blank when auto-capture is declined" asks "Start the server now?" with a blank token, and "starts the server without a Sync token and points at its sign-in page" runs it. The test is now "warns and skips the start offer when the Docker daemon is down". It asserts the remote flow's exact warnings (the skipped name check, then the daemon-not-running message with the start command), mirroring the local flow's daemon-down test. No other test name claims the old blank-token skip. 🔍 ship-check · pr-monitor · claude-opus-5-5 |
…rect the no-token start comment readEnvPublicUrl now trims inside the quotes, so `PUBLIC_URL=" "` stops start with the empty-or-missing error instead of passing the gate and timing out on a server that refuses the blank value. Ship-Check: bug-check · claude-opus-5-5 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…init start without a Sync token - readEnvPort reports a PORT that isn't a whole number from 1 to 65535 instead of using 8000; start, restart, upgrade and init stop on it, and an init re-run stops on a kept invalid PORT unless --port replaces it. Before, the CLI mapped 8000 while a derived PUBLIC_URL could carry the bad value. - start, restart and upgrade refuse an empty or missing PUBLIC_URL for a remote install too, suggesting the server's public address. - Remote init offers to start the server without a Sync token: the container keeps a login saved on its volume, or serves its sign-in page, and the closing message says how to sign in there (over HTTPS). The generated .env comment no longer says the token must be filled in before starting. Ship-Check: pr-monitor · claude-opus-5-5 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…nd show sign-in steps for a kept .env without a Sync token - A PORT that isn't a port no longer strands a default-port localhost PUBLIC_URL when init --port or configure replaces it, and configure no longer pre-fills that value in the port prompt. - Remote init decides whether to print the sign-in steps from the .env on disk, so a token captured this run but not saved to a kept .env no longer hides them. - Comments listing the start checks now include PORT and every command that runs them. Ship-Check: bug-check · claude-opus-5-5 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…dropped Sync token, and warn when --port strands PUBLIC_URL - After writing .env, init runs start's own checks on the file on disk: a kept .env with no PUBLIC_URL, VAULT_PATH, or a valid PORT or INSTANCE_NAME stops init with start's error instead of starting a server that can't boot, and a local start mounts the kept file's vault folder, as start does. - Remote init warns when it kept an existing .env and so dropped the Sync token captured in this run, and prints the command that adds it. - A re-run whose --port leaves a custom PUBLIC_URL on the old port gets the same warning a port picked in the settings menu gives. Ship-Check: pr-monitor · claude-opus-5-5 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…e --port PUBLIC_URL warning fires - resolveDeployment's docstring lists init, which now runs start's .env checks. - describeStrandedCarriedPublicUrl's docstring states that any carried PUBLIC_URL that doesn't follow the new port warns, not only one that names a port. Ship-Check: bug-check · claude-opus-5-5 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
… already names the new port Ship-Check: pr-monitor · claude-opus-5-5 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…rs publish init already refuses a name another install uses; it now does the same for the port. Docker lists every container's published host ports, stopped ones included: - the own-name prompt offers the first free port above 8000 and asks again for one that's taken, so a third install no longer gets 8001 - a taken --port or default port stops --yes and is asked again interactively - a reuse doesn't count the reused install's own container Ship-Check: pr-monitor · claude-opus-5-5 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
… CLI init notes The Compose steps in the local and remote guides now name the settings a second install needs and link where each is described, instead of listing example values. The CLI README's init notes are split by subject: remote setups, re-running init, and running a second vault as numbered steps. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…guides Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Each install syncs a different vault, so their changes never share a sync history and a shared device name has nothing to tell apart. The settings table row goes back to describing what the name labels. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…nto .env The optional settings text in each deploy .env.example is copied into the .env the CLI writes, where Compose wording points CLI users at a tool they never use. The shared text now names no setup method: settings apply when the container is re-created, and renaming an install starts with stopping its container. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…iew findings - init stops before asking anything when the folder's .env belongs to an install of the other mode, pointing at start or another --dir, so a re-run never writes or starts the other mode over it. - After a taken port is entered, the port prompt suggests the first free port, and a reuse whose default port another container holds suggests a free one instead of the taken default. - The sign-in lines name the page first, then say it asks for the auth token below, so the URL no longer reads as the token. - The boot warning about other vaults' Sync setups lists only setups stored for this vault folder, the only ones ob can pick. - The PTY tests' fake docker answers `container ls -aq` with the present names instead of failing. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
… blank-token skip Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…nd in the settings list - A re-run's --port gets the same check as a new install's port, with the install's own container left out, so --yes stops and an interactive run asks again before .env is written. - The port picked in the optional-settings list, in init and configure, is refused when another container publishes it; the install's own port is accepted. The port-collision helpers move beside the port prompt they build on. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
start, restart, upgrade, configure's restart, down, and init's start offer now read the image of the container that holds the install's name. When it is not a Vault Cortex image they stop with a message naming the container and its image, instead of removing it. Also: - suggestFreePort starts at the default port, so init suggests 8000 when it is free, as the guides say. - init passes the deployment's vault path straight through; the fallback for a kept remote .env could not be reached once init refuses a mode mismatch. - derivePublicUrlOverride is now withPublicUrlOverride and takes named inputs. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Installs the CLI started before v0.27.0 still run ghcr.io/aliasunder/vault-mcp, so the foreign-container check now accepts that image too, and start, restart, upgrade and down keep managing those installs. The fake docker in the PTY tests now answers `container inspect` for every name it is given, as docker does. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The port check read Docker's published ports into a map keyed by host port, so when the install's own container and another container both declared a port, whichever was inspected last won. If that was the install's own container, the other container's claim disappeared and the port read as free. The ports now stay one entry per container, and the install's own container is left out before the map is built. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The --yes error for a taken port told a user who had passed --port to re-run with --port. It now names the first free port instead, which fits whether the taken port came from --port or the default. configure also reuses the instance name requireInitializedDir has already checked, instead of reading INSTANCE_NAME a second time. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
logs streamed whatever container held the install's name, so it could show another app's output while down and restart refused that same container. It now refuses it with the same message. Every command now finds the install's container through containerImage, so containerExists is removed, along with its stale comment about guarding removals. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Bug-check findings:
- init no longer offers to reuse the data of another app's container that
holds the requested name: --yes and --instance-name stop, and the prompt
asks for a new name straight away.
- upgrade refuses another app's container before downloading the image.
- configure asks Docker again before offering the restart, since it may
have stopped or started while the prompts were open.
- A host-port range ("8000-8010") counts every port in it as taken.
- The mode-mismatch refusal applies only to a .env init wrote (one with
MCP_AUTH_TOKEN); another app's .env gets the usual re-run question.
- The refusal names both remedies: rename the other container, which keeps
the install's data, or change INSTANCE_NAME, which starts on new volumes.
- The pre-rename vault-mcp image is no longer accepted: the CLI named those
containers vault-mcp, so the INSTANCE_NAME lookup never reaches them.
Code-quality findings:
- One checkInstanceContainer helper replaces four copies of the image check.
- askPort folds into askFreePort; portInUseMessage takes named inputs;
askOptionalSettings requires portsInUse.
- Stale comments and docs corrected (start's replace rule, init's re-run
bullets, the second-vault step, the dormant-setup comment, re-created).
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
730e6fe to
c9518b8
Compare
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…ting one Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
## Summary The CLI release notes list every commit that touches `cli/`, so they include changes no CLI user gets: the release's own version bump, test-only commits, and commits that only reword comments (including the comment text of the `.env` templates in `cli/src/env.ts`). A commit is now listed only when its changes under `cli/` add or remove a line that none of these rules skips: - blank lines - lines in files under `cli/src/__tests__/` - the `"version"` line of `cli/package.json` (the release bump) - in `.ts` files, lines that start, after any indent, with `#`, `//`, `/*` or `*`: comments, and the `.env` templates' comment text. A `#` line shaped like a setting (`# KEY=value`) still counts, because the templates ship optional settings commented out for the user to uncomment In other files, `cli/README.md` included, every non-blank line counts. Dependency changes in `cli/package.json` stay listed, and the "Published to npm" footer is unchanged. With no earlier CLI tag, the range is still the whole history, and the same rules decide which of its commits are listed. - `.github/scripts/generate-cli-notes.sh`: new script that prints the listed commits since the previous CLI tag, one `- <subject>` line each, newest first. - `.github/workflows/cli_release.yml`: the "Create GitHub release" step runs the script with `bash` instead of `git log -- cli/`. - `src/__tests__/generate-cli-notes.test.ts`: runs the real script under `bash` against a temporary git repository. - `scripts/__tests__/lint-shell.test.ts`: lists the new script among the shell scripts ShellCheck checks. - `CONTRIBUTING.md`: the release-notes section states the CLI rule. - `AGENTS.md`: the script-test conventions list the new test. ## Test plan - [x] The script for every `cli-v*` tag (55): cli-v0.16.0 lists exactly #686, #682 and #677 and leaves out its own bump, #665 and #642, whose `cli/` changes are comment text only. Counting setting lines changed the result for five commits in the whole history (#225, #314, #468, #484, #617), each adding or renaming a commented-out `.env` setting; without it, cli-v0.10.6 and cli-v0.12.0 would have had no listed commits. - [x] `npx vitest run src/__tests__/generate-cli-notes.test.ts scripts/__tests__/lint-shell.test.ts`: 30 tests pass; each rule was mutated once and fails the test that covers it. - [x] The same output under BSD awk (macOS) and mawk (the Ubuntu runners' awk), and under macOS `/bin/bash` 3.2. - [x] `npm run lint:shell`, markdownlint and prettier pass. 🤖 Generated with [Claude Code](https://claude.com/claude-code) --------- Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
What does this PR do?
Closes #681.
Two vault-cortex installs can now run side by side on one machine. Before this change, every install used the same container name and the same volumes, so a second Compose project or
npx vault-cortex initeither failed on the taken container name or attached to the first install's volumes. On the:remoteimage, a second vault on the first vault's volumes is synced into the same folder, merging the two vaults through Obsidian Sync.A new
INSTANCE_NAMEsetting names an install's Compose project, container and volumes. Unset, or set tovault-cortex, every name stays exactly as it is today, so existing installs keep their volumes.The
:remoteimage also stops a boot whose volumes hold the Obsidian Sync setup for a different vault thanVAULT_NAME, beforeob sync-setupwrites anything.Who is affected
name:andcontainer_name:followINSTANCE_NAME. With it unset orvault-cortex,docker compose configrenders byte-identical to main.-pandCOMPOSE_PROJECT_NAMEnow rename the container along with the project.INSTANCE_NAMEfrom the install's.envand acts only on that name's container and volumes.initasks for a new name and port when the default name's container or volumes already exist, and new--instance-nameand--portflags cover scripted installs. A re-run ofinitkeeps an install's name, port and URL.init --yesinto a new folder now exits when the default name is taken, until--instance-nameis given.init's start question says so ("This stops and replaces the existing … container. Its data volumes are kept."), and a yes replaces it the waystartdoes. Before,docker runfailed on the taken name.2025,cafe) could have matched, and removed, an unrelated container.start,restart,upgrade,configure's restart,down,logs, andinit's start offer), it checks that container's image. When the image isn't Vault Cortex, the command leaves the container alone, names the container and its image, and offers two fixes: rename that container, which keeps the install's data, or changeINSTANCE_NAME, which starts on new, empty volumes.upgradechecks before it downloads the image.initdoesn't offer to reuse its data: it asks for a new name, and--yesor--instance-namestops instead.initchecks a new install's port, a re-run's--port, and thePORTpicked from the settings list (initandconfigure) against the host ports other containers publish, stopped ones included; a published range counts every port in it. A taken port is asked again with the first free port suggested, counting up from 8000;--yesstops instead and names a free port.initrefuses a folder whose.envit wrote for an install of the other mode (local or remote), as soon as it knows the folder, and points atstartor another--dir. Another app's.envgets the usual re-run question.start,restart,upgradeandinitrefuse a.envwhosePORTisn't a whole number from 1 to 65535 (it was read as 8000) and, for remote installs too, an empty or missingPUBLIC_URL. After writing,initchecks the.envon disk the waystartdoes, so a kept file decides what starts.initoffers to start without a Sync token. The container then uses a login saved on its volume, or shows its sign-in page atPUBLIC_URL, and the closing message says how to sign in there.:remotedeployment (Compose, CLI,docker run, Render, Railway, the Lightsail workflow): a boot stops with an error when the Sync client would sync a vault other thanVAULT_NAME. That state syncs the wrong vault today, so it is not a supported setup, and this is not flagged as a breaking change. A setup file the Sync client would silently ignore (unreadable, unparseable, or not a setup object) also stops the boot, and so does an answer from the Sync client that names no vault (each with its own error and the client's reason). An install that already uses the right vault but also holds another vault's dormant setup for the same vault folder boots with a warning.Changes
rootfs/etc/s6-overlay/scripts/check-sync-vault(new, read-only): resolvesVAULT_NAMEto a vault ID the wayob sync-setupdoes, validates every stored setup file, and compares the vault the Sync client would use for the vault folder with that ID. It prints the ID for the second check and its decision on stderr, and can be run by hand inside a running container.init-setup-vaultruns the check beforeob sync-setup, then confirms aftersync-setupthat the client usesVAULT_NAME's vault before anysync-configcall writes to the setup..env.examplefiles, with the CLI's.envblocks resynced.templates.test.tscounts active optional lines too and skipsCOMPOSE_PROJECT_NAME, which Compose sets itself.docker.ts,lifecycle.ts,messages.ts,scaffold.ts,init.ts,program.ts,optional-settings.tsand a newinstance-identity.ts. Printed commands and connector names use the install's name.INSTANCE_NAMEsettings row and an "Another vault's Sync setup" section in the remote guide, troubleshooting entries in the Render and Railway guides, and notes incli/README.md,llms-install.md,DEPLOY.md,ARCHITECTURE.mdandAGENTS.md(the Sync client outputs the check relies on).check-sync-vault.test.tsthat replays outputs captured from the pinned Sync client;init-setup-vault.test.tsruns the real script beside a stub check; a remote-boot scenario seeds another vault's setup on the config volume and asserts the boot stops beforesync-setupwith the setup unchanged; CLI unit and PTY tests for the name-in-use prompt, the flags, re-init, custom-name commands, and the image and port checks. The PTY fakedockermodels containers and volumes by name and reports each container's image.Decisions
sync-setupand removing new ones was ruled out, because a setupsync-setuprewrote could be removed with real state in it.configuredoes not offerINSTANCE_NAME: renaming an existing install moves it to empty volumes.Type of change
Checklist
npm testpasses at the head,c9518b81, after rebasing onto main (5,740 passed, 2 skipped)npm run buildsucceeds;npm run lint(0 errors) andknippassnpm run test:remote-bootpassed 57/57 andnpm run test:cli-pty18/18 locally at730e6fec, the last commit before the rebase, which brought in only main's release-script and dependency changes; the CLI PTY workflow passed at8176a2a2Live Test Results
Real Obsidian Sync refusal (this Mac, disposable volumes, image built from
4420b49b,sha256:d20552b3; the container, volumes and image were removed afterwards). A fresh config volume held a hand-written setup for a made-up vault ID withvaultPath/vault, which the real Sync client picked. The boot usedVAULT_NAMEfor the real vault,SYNC_MODE=pull-only, a throwawayDEVICE_NAMEand noVAULT_PASSWORD, so a missed check would have stopped atob sync-setup's password check.4420b49b)ob sync-setup: "This install is set up to sync a different vault than VAULT_NAME", naming both vaults, the made-up one as "no longer in your account"config.jsonunchangedob sync-setupnever ranContainer name matching (real Docker on this Mac):
docker container inspect --format '{{.Name}}' 62f6ea, a 6-character prefix of the ID of a container namedmitest-hexprobe, exited 0 and printed/mitest-hexprobe. On main, an install named62f6eawould have treated that container as its own. The CLI now compares the printed name.Image and port checks (real Docker 29.8.2 on this Mac, the branch CLI at
730e6fec, throwaway containers created but never started, all removed afterwards):730e6fec)docker container inspect --format '{{.Name}} {{.Config.Image}}'on two containers/probe-foreign-686 umm-actually-test:latest,/probe-own-686 ghcr.io/aliasunder/vault-cortex:latest, the shapecontainerImageparses-p 18686:8000lists18686logsanddownon an install whose name a non-Vault Cortex container holdsdownremoves any container namedvault-cortex, whatever its image)INSTANCE_NAMEfixes; the container is still theredownon an install whose container runsghcr.io/aliasunder/vault-cortex:latestINSTANCE_NAME)init --yes --port 18686re-run while a stopped container publishes 18686init --yes --instance-name probe-foreign-686for a new install.envwritteninit --yes --port 18691re-run while a stopped container publishes the range18690-18692Podman and nerdctl were not run. Their source shows both report
.Config.Imageincontainer inspect: Podman'sInspectContainerConfig.Image, and nerdctl's Docker-compatibleConfig.Image, set from the reference the container was created with.Production boot at
cdc50ef7. Since then the boot scripts gained fail-closed checks for an unreadable vault list and for a Sync client answer without a vault ID, their own error messages, and a warning when the setup listing fails; the dormant-setup warning now lists only setups for this vault folder. The normal path, where the Sync client already usesVAULT_NAME's vault, is unchanged; the script tests and the remote-boot suite cover it at730e6fec. On a single-vault install like this one, the warning printed nothing before the narrowing and prints nothing after it, so the boot wasn't redeployed for it. Test Deploy run 39356144477 built and pushed:testfromcdc50ef7. The container was recreated fromghcr.io/aliasunder/vault-cortex:testwithorg.opencontainers.image.revision=cdc50ef7fea73b2d7059510b894899d9f68904f0and is healthy. "Before" is the previous:testbuild (revision5c145387), with this branch'scheck-sync-vaultrun by hand inside it.5c145387)cdc50ef7)Vault check: continue — set up for '<vault>', no warningVault check: continue — set up for '<vault>', no warningFirst sync complete., continuous sync service up/healthz(host and public URL){"ok":true}{"ok":true}vault_recent_notesanswersSide by side on one machine at
cdc50ef7(macOS, Docker Desktop, the branch CLI against real Docker, throwaway vaults; everything removed afterwards):init --yes --instance-name … --port 8010, thenstart --dirinitwith the default name already in usehttp://localhost:8011/down --dir Bdeploy/localwith differentINSTANCE_NAME<name>_mcp_datavolumes named per projectinit --mode remotethenstart --dir🤖 Generated with Claude Code