Skip to content

Cat A fork-prep fixes: console hardcode, vault dir, vault secret#10

Merged
jdevera merged 3 commits into
mainfrom
cat-a-fixes
May 18, 2026
Merged

Cat A fork-prep fixes: console hardcode, vault dir, vault secret#10
jdevera merged 3 commits into
mainfrom
cat-a-fixes

Conversation

@jdevera
Copy link
Copy Markdown
Owner

@jdevera jdevera commented May 18, 2026

Summary

Three independent Category-A fork-prep fixes, each its own commit. Closes the bulk of the structural-correctness cleanup left over from the cdt → cola rename.

Commit What
8354677 internal/console/console.go: Windows parent-process detection compared parent.Executable() against the literal "cdt"/"cdt.exe". After the rename the comparison silently fails and the ANSI heuristic breaks for any launcher invoked via itself (hooks, package commands) under PowerShell. Derive the name from filepath.Base(os.Executable()) so it tracks whatever the binary is called at runtime. Runs at package-init time, before InitContext(), so context isn't an option here.
445afaf internal/gvault/file-vault.go: the vault directory was hardcoded to ~/.file-vault/, shared across every binary built from this codebase. Two launchers with different names collide on every vault entry — silent data corruption. Scope under <AppDir>/file-vault/ (mirrors the existing config / dropins / logs layout). One-release migration: at init, if no entry exists at the new path but one exists at the legacy path, copy it in place; new writes always go to the new path. AppDir resolution is inlined to avoid config → helper → gvault circular import.
6132319 internal/gvault/file-vault.go readSecret(): dropped the silent fallback to hashing ~/.ssh/id_rsa as the vault key. That coupling was load-bearing — vault recoverability was tied to an SSH key the user might rotate, and CI runners with no ~/.ssh saw cascading failures (this exact issue surfaced during PR #9). Now requires an explicit <APPNAME>_VAULT_SECRET (literal) or <APPNAME>_VAULT_SECRET_FILE (path); error message names both env vars when neither is set. Existing users on the SSH default need to either set <APPNAME>_VAULT_SECRET_FILE=~/.ssh/id_rsa to preserve current behaviour or pick a new secret.

Behaviour change

The third commit is a breaking change for any user who was implicitly relying on the SSH-key default to encrypt their file vault. They'll see an explicit error pointing at the two env vars they can set. Worth a release note when this lands.

Test plan

Verified locally before push:

  • ./build.sh clean
  • go build ./... && go vet ./... clean
  • go test ./... all packages pass
  • ./test/integration.sh 19/19 suites pass
  • Fork CI green across the matrix (Linux / macOS / Windows × amd64 / arm64)

jdevera added 3 commits May 18, 2026 22:04
The Windows PowerShell parent-process check compared parent.Executable()
against the literal "cdt"/"cdt.exe". After the binary rename the
comparison silently fails, breaking the ANSI-detection heuristic for any
launcher invoked via itself (hooks, package commands) under PowerShell —
ANSI sequences get emitted as raw text.

filepath.Base(os.Executable()) returns the same shape parent.Executable()
already returns ("cola"/"cola.exe", or whatever the binary is named at
runtime), with no context dependency — important since this runs at
package-init time before InitContext().
The hardcoded ~/.file-vault/ directory was shared across every binary
built from this codebase, so two launchers with different names
(e.g. cola and mydt) collided on every vault entry — silent data
corruption between binaries.

Move the vault under the per-launcher tree (mirrors the existing
config / dropins / logs layout). Inline AppDir resolution rather
than importing config to avoid a circular import (config → helper →
gvault).

Migration: at init time, if no entry exists at the new path but one
exists at the legacy ~/.file-vault/<name> path, copy the legacy file
in place. Single-binary users keep their data; multi-binary users
need to re-login on the second binary, which was already the implicit
contract. The legacy-path fallback is intended to be removed one
release after this lands.
readSecret() previously fell through to hashing ~/.ssh/id_rsa when
neither <APPNAME>_VAULT_SECRET nor <APPNAME>_VAULT_SECRET_FILE was
set. That coupling was implicit and load-bearing: users who never
asked for it had their vault recoverability tied to an SSH key they
might rotate, and CI runners with no ~/.ssh saw silent failures
that only surfaced as cascading test errors much higher up the stack.

Drop the SSH default. If neither env var is set, return an error
that names both env vars so the caller knows exactly what to set.
Existing users on a non-default vault secret are unaffected;
existing users on the SSH default need to either set
<APPNAME>_VAULT_SECRET_FILE=~/.ssh/id_rsa explicitly to keep current
behaviour, or pick a new secret and re-store credentials.

Surfaced during the env-var split PR (#9) where four integration
suites failed on CI for this exact reason and passed locally
because dev machines have an ~/.ssh.
@jdevera jdevera merged commit 7b0a985 into main May 18, 2026
16 checks passed
@jdevera jdevera deleted the cat-a-fixes branch May 18, 2026 21:52
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.

1 participant