Repository navigation
Conversation
The Compose backend wrote every resolved (decrypted) env value into
.hack/.internal/compose.env.override.yml and left it there after up, down,
failed or interrupted runs.
The override now holds only ${HACK_ENV_<digest>_<KEY>} references and the
values reach docker compose through its process environment, so no Compose
command writes a value to disk. The file keeps its path (Compose records it
in each container's config_files label), is written atomically with mode
0600 and refuses a symlink or literal text. Files left by earlier versions
are replaced by the next Compose command, removed by down or by a command
that renders no override, and reported by a new "compose env at rest"
doctor check with an authorized --fix removal. Legacy adoption accepts the
reference form as well as the earlier literal bytes.
Refs HACK-1273
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Update the env guide, architecture notes and env/secrets threat model for the reference-only Compose env override, its doctor check and the remaining client-environment gap. Align run, up and adoption tests with values arriving through the Compose process environment. Refs HACK-1273 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The env override now holds only ${HACK_ENV_*} references, while each
container's config-hash label was computed by Compose with the resolved
values. The adoption config-hash probe ran without them, so every stack
with managed env that this version started was refused.
Preview and preparation now pass the reference values (already resolved
by the projection) to the probe's Compose environment only. A saved
recheck has no key or values: it binds each container's label to the
hash proven at preparation, with the Compose copy, generated override
bytes and env revision still pinned.
The docker e2e adoption harness now starts the original stack with the
same Compose process env that Hack supplies.
Refs HACK-1273
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
- Removal moves the file aside atomically and classifies what it moved; a value-free file a concurrent command wrote is linked back. - hack down removes a literal override before hooks, remote dispatch or Compose, so a failed down-before hook no longer keeps it. - Tests for the doctor --fix step, the no-override scrubs and the down-hook path; the CLI tests no longer search the host PATH. - Docs: direct docker compose use gets blank values; Linux 128 KiB per-string limit; services x keys growth. Refs HACK-1273 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The test runs doctor --fix twice and timed out at the 5 s default on the hosted runner. Refs HACK-1273 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Resolves the overlap with #349, which made the literal Compose env override private (0600, atomic). This branch removes the values from that file instead, so its reference writer is kept, the unused writePrivateEnvFileIfChanged import is dropped, the threat-model row for the private literal file is folded into the HACK-1273 row, and open gap 4 now covers .hack/.env plus the Compose client environment. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…scan The sentinel scan from #349 still allowed plaintext in .hack/.internal/compose.env.override.yml. That file now holds only ${HACK_ENV_...} references (HACK-1273), so it loses its exception: any value in it fails the scan. The scan now requires the override to exist with references, to be private and git-ignored, and requires the values to reach the docker compose client environment. Running the scan with next's src/commands/project.ts fails it. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Two removal paths had no test: the scrub in the legacy hack.env.json path when no service gets an override, and the sweep of an aside left by a removal that crashed between its move and its unlink. Each now has a test that fails when that path is removed. The sweep takes an injectable clock so the one-minute stale rule can be tested. The docs now say what the move-aside removal does not guarantee: the path is absent for a moment while a concurrently written value-free file is put back, and a crash leaves an aside that hack doctor does not report. hack down is described by what it runs before (hooks, remote target, Compose down) instead of 'before anything else'. Refs HACK-1273 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…ence values A legacy adoption pins the generated env override's bytes and inode, and adopted commands dispatch before the down scrub. Removing an earlier version's literal override therefore broke the adoption, and a new adoption could still bind a literal file for its whole life. - `hack config adopt` and its preview refuse a literal override and say to run `hack up` first, which rewrites it with references. - Removal (doctor --fix, down and the no-override scrubs) keeps an override while a prepared, active or pending adoption exists. Doctor reports it with the supported next step: rollback, `hack up`, adopt. The doctor check and its fix step now reach an adopted project, whose inputs ordinary discovery refuses. - Doctor reports leftover removal asides by count; --fix and a rendering Compose command delete stale ones. - `HACK_ENV_*` values reach only the `docker compose` invocations that read the override; dependency progress and cache reuse `docker` children get the env without them. - The exec readiness `compose ps` gets the Compose env, so Compose no longer warns about unset references. - docs/env.md gains an upgrade note for managed values that contain `$`. Refs HACK-1273 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Resolves the compose-managed-env import conflict in src/commands/project.ts (keep the reference renderer, add resolveComposeProjectName from next). Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…erride Preview now refuses a literal env override, so the fresh-adoption fixture binds the reference form that current writers produce. Refs HACK-1273 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Integration gate for merge batch b22: origin/next ace57ee + #357 (HACK-1273). Tree 24aa8363. Closed after the batch squashes.
🤖 Generated with Claude Code
Need help on this PR? Tag
@codesmith-botwith what you need.