Skip to content

feat: embed git-aware version in binary output#14

Merged
donbeave merged 1 commit into
mainfrom
feature/version-from-git
Apr 7, 2026
Merged

feat: embed git-aware version in binary output#14
donbeave merged 1 commit into
mainfrom
feature/version-from-git

Conversation

@donbeave

@donbeave donbeave commented Apr 7, 2026

Copy link
Copy Markdown
Member

Summary

  • Adds build.rs that computes version at compile time from Cargo.toml + git SHA
  • jackin --version now outputs Ghostty-style versions: jackin 0.5.0-dev+a31e949
  • Preview formula sets JACKIN_VERSION_OVERRIDE so brew install jackin@preview reports 0.5.0-preview+a31e949
  • Release workflow sets JACKIN_VERSION_OVERRIDE for clean release versions

Version formats by channel

Channel Example
Local dev 0.5.0-dev+a31e949
Preview (brew install jackin@preview) 0.5.0-preview+a31e949
Stable (brew install jackin) 0.5.0

Test plan

  • cargo fmt -- --check passes
  • cargo clippy passes with zero warnings
  • cargo nextest run — 204 tests pass
  • cargo run -- --version outputs jackin 0.5.0-dev+<sha>
  • JACKIN_VERSION_OVERRIDE=0.5.0-preview+abc1234 cargo run -- --version outputs override
  • After merge: verify preview workflow publishes updated formula
  • After merge: brew upgrade jackin@preview reports new version

Note

The stable homebrew formula (jackin.rb) in jackin-project/homebrew-tap also needs the JACKIN_VERSION_OVERRIDE update in its install block — already applied locally at /Users/donbeave/Projects/jackin-project/homebrew-tap/Formula/jackin.rb, needs to be committed to that repo separately.

🤖 Generated with Claude Code

Add build.rs that computes the version string at compile time:
- Local dev builds: 0.5.0-dev+<sha> (Cargo.toml version + git SHA)
- Preview builds: 0.5.0-preview+<sha> (set via JACKIN_VERSION_OVERRIDE)
- Release builds: 0.5.0 (set via JACKIN_VERSION_OVERRIDE)

Update preview and release workflows to set JACKIN_VERSION_OVERRIDE so
homebrew-installed binaries report the correct version.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
@donbeave donbeave merged commit 5f2593c into main Apr 7, 2026
1 check passed
@donbeave donbeave deleted the feature/version-from-git branch April 7, 2026 10:21
donbeave added a commit that referenced this pull request Apr 20, 2026
feat: embed git-aware version in binary output
donbeave added a commit that referenced this pull request Apr 21, 2026
feat: embed git-aware version in binary output
donbeave added a commit that referenced this pull request Apr 21, 2026
feat: embed git-aware version in binary output
donbeave added a commit that referenced this pull request Apr 21, 2026
feat: embed git-aware version in binary output
donbeave added a commit that referenced this pull request Apr 21, 2026
feat: embed git-aware version in binary output
donbeave added a commit that referenced this pull request May 7, 2026
feat: embed git-aware version in binary output
Signed-off-by: Alexey Zhokhov <alexey@zhokhov.com>
Co-authored-by: Codex <codex@openai.com>
donbeave added a commit that referenced this pull request May 7, 2026
feat: embed git-aware version in binary output

Signed-off-by: Alexey Zhokhov <alexey@zhokhov.com>
Co-authored-by: Codex <codex@openai.com>
donbeave added a commit that referenced this pull request May 7, 2026
Add build.rs that computes the version string at compile time:
- Local dev builds: 0.5.0-dev+<sha> (Cargo.toml version + git SHA)
- Preview builds: 0.5.0-preview+<sha> (set via JACKIN_VERSION_OVERRIDE)
- Release builds: 0.5.0 (set via JACKIN_VERSION_OVERRIDE)

Update preview and release workflows to set JACKIN_VERSION_OVERRIDE so
homebrew-installed binaries report the correct version.

Signed-off-by: Alexey Zhokhov <alexey@zhokhov.com>
Co-authored-by: Claude <noreply@anthropic.com>
donbeave added a commit that referenced this pull request May 7, 2026
feat: embed git-aware version in binary output

Signed-off-by: Alexey Zhokhov <alexey@zhokhov.com>
Co-authored-by: Codex <codex@openai.com>
donbeave added a commit that referenced this pull request May 9, 2026
… env-var leaks (#273)

Tier 3 follow-up to the post-#266 hardening. Add a PR-time `publish-manifest-rehearsal` job to `construct.yml` that runs the same docker buildx CLI plumbing `publish-manifest` depends on, without the side-effect steps (Docker Hub login, `imagetools create`, `imagetools inspect`).

The previous hardening rounds were process- (#267 docs rules) and gate-side (#14 / #15 terraform branch protection). This is the workflow-side companion. The #266 break (`ERROR: no builder "jackin-construct" found`) was caused by hoisting `BUILDX_BUILDER` into workflow-level env, which docker buildx reads as the default-builder selection — surfacing only post-merge on main because `publish-manifest` is push-only and never runs on a `pull_request` event. `docker buildx ls` evaluates `BUILDX_BUILDER` at startup and exits non-zero on a missing-builder reference, regardless of whether the rest of the command would have hit the network. Running it on PR + feature-branch dispatch reproduces the failure shape without registry credentials.

Two checks: `docker buildx ls` (catches workflow-level env-var leaks for any current or future buildx-controlling env var) and `docker buildx imagetools --help >/dev/null` (smoke-test that the buildx CLI plugin is bundled and loadable on the runner). The `construct-required` aggregator now lists `publish-manifest-rehearsal` in `needs:` so the rehearsal's result is rolled up into the same single check name branch protection requires.

Equivalent rehearsals for `build-validator`, `deploy`, and `publish-preview` are deferred — those side-effect surfaces don't have the same network-free reproducibility shape `buildx ls` provides for docker, so the fidelity-vs-cost trade is worse. Reopen if a #266-class break surfaces in any of them.

Signed-off-by: Alexey Zhokhov <alexey@zhokhov.com>
Co-authored-by: Claude <noreply@anthropic.com>
donbeave added a commit that referenced this pull request May 17, 2026
…hase 1 (#366)

## Summary

Re-bakes the codebase-readability program's May 2026 baseline against
today's tree (LOC, file counts, mega-function sizes, `//!` coverage,
duplication counts) and adds a trend caution showing every metric except
`"Dockerfile"` literals regressed since the original audit — making the
gap between "audit happened" and "extraction work scheduled" visible to
anyone landing on the page. Cargo workspace split's LOC reference is
updated to match. Separately, resolves the standing contradiction
between the deferred Bollard migration and two still-Medium open review
findings (#13 cleanup string-matching, #14
inspect-collapse-to-not-found) by carving out a concrete Phase 1 scope
(lifecycle, cleanup, inspect via Bollard) with named files, out-of-scope
items, and acceptance criteria; the open findings catalog now back-links
both items to that Phase 1 so the two pages agree on ownership.

## What's deferred (follow-up PRs)

- `jackin-daemon` phase-order section so the four reactive-daemon leaves
(daemon, live-auth-sync, attention-prompts, host-bridge, desktop hub)
have one canonical sequencing reference.
- `reproducibility-pinning` operator-review pass (the page has been
"agent brainstorm, not yet reviewed" for a long time).
- `multi-runtime-support` "Remaining Work" bullets — split into
acceptance-criteria-bearing leaves or annotate each bullet with a
definition of done.
- Bollard Phase 2 (`docker build`, interactive `docker run -it` via
Bollard) — kept deferred per the original "incremental is pragmatic"
rationale.

## Verify locally

### Checkout

Paste this first to bypass the `tirith` paste scanner for the rest of
the session:

```sh
export TIRITH=0
```

Then paste the checkout block:

```sh
mkdir -p "$HOME/Projects/jackin-project/test"
cd "$HOME/Projects/jackin-project/test"

if [ ! -d jackin/.git ]; then
  git clone https://github.com/jackin-project/jackin.git
fi

cd jackin
mise trust
git fetch -f origin docs/roadmap-rebake-audit-and-bollard-phase1:refs/remotes/origin/docs/roadmap-rebake-audit-and-bollard-phase1
git checkout -B docs/roadmap-rebake-audit-and-bollard-phase1 refs/remotes/origin/docs/roadmap-rebake-audit-and-bollard-phase1
```

### Documentation

```sh
cd docs
bun install --frozen-lockfile
bunx astro sync
bunx tsc --noEmit
bun run build
bun run check:repo-links
bun run dev
```

Astro serves at `http://localhost:4321/`. Pages to walk:

**http://localhost:4321/reference/roadmap/codebase-readability/**  
UPDATED roadmap page in the *Internals → Roadmap → Codebase health*
sidebar group. New "Trend since the original May 2026 audit" caution
Aside at the top should render under the five numbered goals, and the
per-module health table plus Tier A/B/C tables should show the refreshed
LOC numbers (largest file 7593L, `fn run` 1186L). The "Current metrics"
table near the bottom now has three columns (today / original May 2026
audit / pre-audit) instead of two.

**http://localhost:4321/reference/roadmap/bollard-migration/**  
UPDATED roadmap page in the *Internals → Roadmap → Infrastructure*
sidebar group. Status now reads "Partially scoped"; new "Open Review
Findings This Resolves" and "Phased Plan" sections should render with
the in-scope files, out-of-scope deferrals, and acceptance criteria for
Phase 1.

**http://localhost:4321/reference/roadmap/open-review-findings/**  
UPDATED roadmap page in the same Infrastructure sidebar group. Findings
#13 and #14 should each end with "Scoped for the Bollard migration Phase
1." and the link should resolve.

**http://localhost:4321/reference/roadmap/cargo-workspace-split/**  
UPDATED roadmap page in the *Codebase health* sidebar group. The "When
to do this" paragraph should read "~93K lines of production Rust (119
files in src/, re-baked 2026-05-17) … 88% growth".

**http://localhost:4321/reference/roadmap/**  
UPDATED overview. The Infrastructure improvements section's "Docker API
migration" bullet should now describe Phase 1 as the next concrete PR
with the open-findings link, and end with "(status: partially scoped)".

Signed-off-by: Alexey Zhokhov <alexey@zhokhov.com>
Co-authored-by: Amp <amp@ampcode.com>
donbeave added a commit that referenced this pull request May 17, 2026
…hase 1 (#366)

## Summary

Re-bakes the codebase-readability program's May 2026 baseline against
today's tree (LOC, file counts, mega-function sizes, `//!` coverage,
duplication counts) and adds a trend caution showing every metric except
`"Dockerfile"` literals regressed since the original audit — making the
gap between "audit happened" and "extraction work scheduled" visible to
anyone landing on the page. Cargo workspace split's LOC reference is
updated to match. Separately, resolves the standing contradiction
between the deferred Bollard migration and two still-Medium open review
findings (#13 cleanup string-matching, #14
inspect-collapse-to-not-found) by carving out a concrete Phase 1 scope
(lifecycle, cleanup, inspect via Bollard) with named files, out-of-scope
items, and acceptance criteria; the open findings catalog now back-links
both items to that Phase 1 so the two pages agree on ownership.

## What's deferred (follow-up PRs)

- `jackin-daemon` phase-order section so the four reactive-daemon leaves
(daemon, live-auth-sync, attention-prompts, host-bridge, desktop hub)
have one canonical sequencing reference.
- `reproducibility-pinning` operator-review pass (the page has been
"agent brainstorm, not yet reviewed" for a long time).
- `multi-runtime-support` "Remaining Work" bullets — split into
acceptance-criteria-bearing leaves or annotate each bullet with a
definition of done.
- Bollard Phase 2 (`docker build`, interactive `docker run -it` via
Bollard) — kept deferred per the original "incremental is pragmatic"
rationale.

## Verify locally

### Checkout

Paste this first to bypass the `tirith` paste scanner for the rest of
the session:

```sh
export TIRITH=0
```

Then paste the checkout block:

```sh
mkdir -p "$HOME/Projects/jackin-project/test"
cd "$HOME/Projects/jackin-project/test"

if [ ! -d jackin/.git ]; then
  git clone https://github.com/jackin-project/jackin.git
fi

cd jackin
mise trust
git fetch -f origin docs/roadmap-rebake-audit-and-bollard-phase1:refs/remotes/origin/docs/roadmap-rebake-audit-and-bollard-phase1
git checkout -B docs/roadmap-rebake-audit-and-bollard-phase1 refs/remotes/origin/docs/roadmap-rebake-audit-and-bollard-phase1
```

### Documentation

```sh
cd docs
bun install --frozen-lockfile
bunx astro sync
bunx tsc --noEmit
bun run build
bun run check:repo-links
bun run dev
```

Astro serves at `http://localhost:4321/`. Pages to walk:

**http://localhost:4321/reference/roadmap/codebase-readability/**  
UPDATED roadmap page in the *Internals → Roadmap → Codebase health*
sidebar group. New "Trend since the original May 2026 audit" caution
Aside at the top should render under the five numbered goals, and the
per-module health table plus Tier A/B/C tables should show the refreshed
LOC numbers (largest file 7593L, `fn run` 1186L). The "Current metrics"
table near the bottom now has three columns (today / original May 2026
audit / pre-audit) instead of two.

**http://localhost:4321/reference/roadmap/bollard-migration/**  
UPDATED roadmap page in the *Internals → Roadmap → Infrastructure*
sidebar group. Status now reads "Partially scoped"; new "Open Review
Findings This Resolves" and "Phased Plan" sections should render with
the in-scope files, out-of-scope deferrals, and acceptance criteria for
Phase 1.

**http://localhost:4321/reference/roadmap/open-review-findings/**  
UPDATED roadmap page in the same Infrastructure sidebar group. Findings
#13 and #14 should each end with "Scoped for the Bollard migration Phase
1." and the link should resolve.

**http://localhost:4321/reference/roadmap/cargo-workspace-split/**  
UPDATED roadmap page in the *Codebase health* sidebar group. The "When
to do this" paragraph should read "~93K lines of production Rust (119
files in src/, re-baked 2026-05-17) … 88% growth".

**http://localhost:4321/reference/roadmap/**  
UPDATED overview. The Infrastructure improvements section's "Docker API
migration" bullet should now describe Phase 1 as the next concrete PR
with the open-findings link, and end with "(status: partially scoped)".

Signed-off-by: Alexey Zhokhov <alexey@zhokhov.com>
Co-authored-by: Amp <amp@ampcode.com>
donbeave added a commit that referenced this pull request May 18, 2026
… env-var leaks (#273)

Tier 3 follow-up to the post-#266 hardening. Add a PR-time `publish-manifest-rehearsal` job to `construct.yml` that runs the same docker buildx CLI plumbing `publish-manifest` depends on, without the side-effect steps (Docker Hub login, `imagetools create`, `imagetools inspect`).

The previous hardening rounds were process- (#267 docs rules) and gate-side (#14 / #15 terraform branch protection). This is the workflow-side companion. The #266 break (`ERROR: no builder "jackin-construct" found`) was caused by hoisting `BUILDX_BUILDER` into workflow-level env, which docker buildx reads as the default-builder selection — surfacing only post-merge on main because `publish-manifest` is push-only and never runs on a `pull_request` event. `docker buildx ls` evaluates `BUILDX_BUILDER` at startup and exits non-zero on a missing-builder reference, regardless of whether the rest of the command would have hit the network. Running it on PR + feature-branch dispatch reproduces the failure shape without registry credentials.

Two checks: `docker buildx ls` (catches workflow-level env-var leaks for any current or future buildx-controlling env var) and `docker buildx imagetools --help >/dev/null` (smoke-test that the buildx CLI plugin is bundled and loadable on the runner). The `construct-required` aggregator now lists `publish-manifest-rehearsal` in `needs:` so the rehearsal's result is rolled up into the same single check name branch protection requires.

Equivalent rehearsals for `build-validator`, `deploy`, and `publish-preview` are deferred — those side-effect surfaces don't have the same network-free reproducibility shape `buildx ls` provides for docker, so the fidelity-vs-cost trade is worse. Reopen if a #266-class break surfaces in any of them.

Signed-off-by: Alexey Zhokhov <alexey@zhokhov.com>
Co-authored-by: Claude <noreply@anthropic.com>
donbeave added a commit that referenced this pull request May 18, 2026
…hase 1 (#366)

## Summary

Re-bakes the codebase-readability program's May 2026 baseline against
today's tree (LOC, file counts, mega-function sizes, `//!` coverage,
duplication counts) and adds a trend caution showing every metric except
`"Dockerfile"` literals regressed since the original audit — making the
gap between "audit happened" and "extraction work scheduled" visible to
anyone landing on the page. Cargo workspace split's LOC reference is
updated to match. Separately, resolves the standing contradiction
between the deferred Bollard migration and two still-Medium open review
findings (#13 cleanup string-matching, #14
inspect-collapse-to-not-found) by carving out a concrete Phase 1 scope
(lifecycle, cleanup, inspect via Bollard) with named files, out-of-scope
items, and acceptance criteria; the open findings catalog now back-links
both items to that Phase 1 so the two pages agree on ownership.

## What's deferred (follow-up PRs)

- `jackin-daemon` phase-order section so the four reactive-daemon leaves
(daemon, live-auth-sync, attention-prompts, host-bridge, desktop hub)
have one canonical sequencing reference.
- `reproducibility-pinning` operator-review pass (the page has been
"agent brainstorm, not yet reviewed" for a long time).
- `multi-runtime-support` "Remaining Work" bullets — split into
acceptance-criteria-bearing leaves or annotate each bullet with a
definition of done.
- Bollard Phase 2 (`docker build`, interactive `docker run -it` via
Bollard) — kept deferred per the original "incremental is pragmatic"
rationale.

## Verify locally

### Checkout

Paste this first to bypass the `tirith` paste scanner for the rest of
the session:

```sh
export TIRITH=0
```

Then paste the checkout block:

```sh
mkdir -p "$HOME/Projects/jackin-project/test"
cd "$HOME/Projects/jackin-project/test"

if [ ! -d jackin/.git ]; then
  git clone https://github.com/jackin-project/jackin.git
fi

cd jackin
mise trust
git fetch -f origin docs/roadmap-rebake-audit-and-bollard-phase1:refs/remotes/origin/docs/roadmap-rebake-audit-and-bollard-phase1
git checkout -B docs/roadmap-rebake-audit-and-bollard-phase1 refs/remotes/origin/docs/roadmap-rebake-audit-and-bollard-phase1
```

### Documentation

```sh
cd docs
bun install --frozen-lockfile
bunx astro sync
bunx tsc --noEmit
bun run build
bun run check:repo-links
bun run dev
```

Astro serves at `http://localhost:4321/`. Pages to walk:

**http://localhost:4321/reference/roadmap/codebase-readability/**  
UPDATED roadmap page in the *Internals → Roadmap → Codebase health*
sidebar group. New "Trend since the original May 2026 audit" caution
Aside at the top should render under the five numbered goals, and the
per-module health table plus Tier A/B/C tables should show the refreshed
LOC numbers (largest file 7593L, `fn run` 1186L). The "Current metrics"
table near the bottom now has three columns (today / original May 2026
audit / pre-audit) instead of two.

**http://localhost:4321/reference/roadmap/bollard-migration/**  
UPDATED roadmap page in the *Internals → Roadmap → Infrastructure*
sidebar group. Status now reads "Partially scoped"; new "Open Review
Findings This Resolves" and "Phased Plan" sections should render with
the in-scope files, out-of-scope deferrals, and acceptance criteria for
Phase 1.

**http://localhost:4321/reference/roadmap/open-review-findings/**  
UPDATED roadmap page in the same Infrastructure sidebar group. Findings
#13 and #14 should each end with "Scoped for the Bollard migration Phase
1." and the link should resolve.

**http://localhost:4321/reference/roadmap/cargo-workspace-split/**  
UPDATED roadmap page in the *Codebase health* sidebar group. The "When
to do this" paragraph should read "~93K lines of production Rust (119
files in src/, re-baked 2026-05-17) … 88% growth".

**http://localhost:4321/reference/roadmap/**  
UPDATED overview. The Infrastructure improvements section's "Docker API
migration" bullet should now describe Phase 1 as the next concrete PR
with the open-findings link, and end with "(status: partially scoped)".

Signed-off-by: Alexey Zhokhov <alexey@zhokhov.com>
Co-authored-by: Amp <amp@ampcode.com>
donbeave added a commit that referenced this pull request May 19, 2026
…e findings #13/#14

- bollard-migration.mdx: rewrite to describe what shipped in Phase 1 and
  what remains deferred (docker build, interactive exec) in Phase 2
- roadmap.mdx: move bollard-migration from Planned to Partially implemented
- open-review-findings.mdx: remove #13 (string-match cleanup) and #14
  (inspect collapses to not-found), renumber #15-17 to #13-15
- codebase-map.mdx: add src/docker_client.rs entry describing DockerApi
  trait, BollardDockerClient, FakeDockerClient, and ContainerState

Signed-off-by: Alexey Zhokhov <alexey@zhokhov.com>
Co-authored-by: Claude <noreply@anthropic.com>
donbeave added a commit that referenced this pull request May 19, 2026
…e findings #13/#14

- bollard-migration.mdx: rewrite to describe what shipped in Phase 1 and
  what remains deferred (docker build, interactive exec) in Phase 2
- roadmap.mdx: move bollard-migration from Planned to Partially implemented
- open-review-findings.mdx: remove #13 (string-match cleanup) and #14
  (inspect collapses to not-found), renumber #15-17 to #13-15
- codebase-map.mdx: add src/docker_client.rs entry describing DockerApi
  trait, BollardDockerClient, FakeDockerClient, and ContainerState

Signed-off-by: Alexey Zhokhov <alexey@zhokhov.com>
Co-authored-by: Claude <noreply@anthropic.com>
donbeave added a commit that referenced this pull request May 23, 2026
Trust-but-verify pass on the 15-item /code-review max-effort report
that followed the parallel-agent capture commit. Splits cleanly from
the in-flight env-config refactor by touching only the host-side
session-inventory and snapshot-fanout paths plus the capsule socket
layer; parallel-agent territory (main.rs, daemon.rs, session.rs,
launch.rs, env_model.rs, derived_image.rs, entrypoint.sh) stays
untouched.

Findings addressed:

* `src/console/manager/state.rs` — fan-out worker panics now surface
  through the existing `debug_log` path: `h.join()` failures are
  downcast to a string and re-routed as `Err(anyhow!)` so the slot
  is no longer dropped by `filter_map(|h| h.join().ok())`. Snapshot
  fan-out is also bounded by `SNAPSHOT_FANOUT_CHUNK = 8` so a host
  with dozens of active containers does not spawn dozens of OS
  threads per 500 ms refresh tick; each chunk's wall-clock cost is
  still bounded by the slowest fetch in that chunk. The fan-out
  body moves into a free `fetch_snapshots_parallel` helper so
  `refresh_instances` stays under the clippy line-count gate.

* `src/runtime/attach.rs` — `JACKIN_STATUS_CMD` now gates on
  `test -S /jackin/run/jackin.sock` so the early-bring-up window
  (between container start and the daemon binding its socket, plus
  any pre-`setup-once` time) does not leak operator-visible stderr
  from a binary that exists but cannot serve yet. `test -S` exits
  silently with status 1 if the socket is absent; `||` short-
  circuits at the first failure only — no `|| true` masking the
  second command's errors once the socket exists. `parse_jackin_sessions`
  drops the strict `len() != expected` equality in favour of
  `take(expected)` so trailing footer lines or labels that
  `Display`-emit a non-`[` continuation line no longer flip the
  parse to Unavailable; the count check is now a lower-bound
  (`< expected`), which still catches real format drift but
  tolerates harmless decoration. The header search lifts a shared
  `parse_session_count` helper used by both `inspect_agent_sessions`
  here and `isolation::finalize::has_jackin_sessions`, replacing
  the duplicate parser that was warned about in finding #3.

* `src/isolation/finalize.rs` — `parse_session_count` is now
  `runtime::attach::parse_session_count`; the local copy is gone.
  One header parser, one definition of malformed, no silent
  divergence on edge cases.

* `crates/jackin-capsule/src/socket.rs` — accept-loop cap-rejection
  log now fires exactly once on the saturation transition + once on
  the recovery transition, with per-drop messages demoted to
  `cdebug!` so a flood attacker (the exact threat
  `MAX_CONCURRENT_CLIENTS` defends against) cannot drown the
  compact-tier log. Per-backoff line also demoted to `cdebug!` —
  the accept-error clog above already names the failure, so the
  1-line-per-failure compact-log invariant holds. `start_listener_at`
  splits behind a new `start_listener_at_with_limiter` test-only
  helper that returns the inner `Arc<Semaphore>`. The cap regression
  test now reads `limiter.available_permits()` directly instead of
  racing `rx.recv()` against a 300 ms wall-clock deadline —
  cap-sensitive, not timing-sensitive. Wall-clock `timeout()`
  windows widen to 2 s for the remaining positive assertions so a
  slow CI runner does not produce spurious failures.

* `crates/jackin-capsule/src/protocol/attach.rs` — new
  `hello_env_count_over_cap_is_rejected_by_decoder_with_full_payload`
  variant supplies a fully-populated payload of `MAX_HELLO_ENV + 1`
  real entries so the per-entry boundary is verified after the read
  loop, not just at the count declaration. The earlier test only
  exercised the front-of-loop guard; a regression that moved the
  cap check below the per-entry loop would slip past it silently.

Deferred (parallel-agent territory or out-of-scope for this pass):

* `crates/jackin-capsule/src/session.rs` kitty single-pop vs N-push
  asymmetry (finding #6) and `focus_swap_reset_*` test-name
  overpromises (finding #12) — `session.rs` is mid-rebase by the
  parallel agent.
* `crates/jackin-capsule/src/main.rs` `--focus` eprintln eaten by
  alt-screen swap (finding #8) — `main.rs` mid-rebase.
* `src/runtime/launch.rs` `fake_docker_for_clean_attached_exit`
  fixture ordering (finding #14) — `launch.rs` mid-rebase under
  the env-config migration.

Setup-once gating left untouched: `docker/runtime/entrypoint.sh`
already gates on `/jackin/state/hooks/setup-once.done` (line 78,
runs only if marker absent; line 88 writes the marker on success).
The new `test -S` socket gate on the host-side status query is the
orthogonal half of the "don't query during early bring-up" rule.

Co-authored-by: Claude <noreply@anthropic.com>
Signed-off-by: Alexey Zhokhov <alexey@zhokhov.com>
donbeave added a commit that referenced this pull request May 23, 2026
Trust-but-verify pass on the 15-item /code-review max-effort report
that followed the parallel-agent capture commit. Splits cleanly from
the in-flight env-config refactor by touching only the host-side
session-inventory and snapshot-fanout paths plus the capsule socket
layer; parallel-agent territory (main.rs, daemon.rs, session.rs,
launch.rs, env_model.rs, derived_image.rs, entrypoint.sh) stays
untouched.

Findings addressed:

* `src/console/manager/state.rs` — fan-out worker panics now surface
  through the existing `debug_log` path: `h.join()` failures are
  downcast to a string and re-routed as `Err(anyhow!)` so the slot
  is no longer dropped by `filter_map(|h| h.join().ok())`. Snapshot
  fan-out is also bounded by `SNAPSHOT_FANOUT_CHUNK = 8` so a host
  with dozens of active containers does not spawn dozens of OS
  threads per 500 ms refresh tick; each chunk's wall-clock cost is
  still bounded by the slowest fetch in that chunk. The fan-out
  body moves into a free `fetch_snapshots_parallel` helper so
  `refresh_instances` stays under the clippy line-count gate.

* `src/runtime/attach.rs` — `JACKIN_STATUS_CMD` now gates on
  `test -S /jackin/run/jackin.sock` so the early-bring-up window
  (between container start and the daemon binding its socket, plus
  any pre-`setup-once` time) does not leak operator-visible stderr
  from a binary that exists but cannot serve yet. `test -S` exits
  silently with status 1 if the socket is absent; `||` short-
  circuits at the first failure only — no `|| true` masking the
  second command's errors once the socket exists. `parse_jackin_sessions`
  drops the strict `len() != expected` equality in favour of
  `take(expected)` so trailing footer lines or labels that
  `Display`-emit a non-`[` continuation line no longer flip the
  parse to Unavailable; the count check is now a lower-bound
  (`< expected`), which still catches real format drift but
  tolerates harmless decoration. The header search lifts a shared
  `parse_session_count` helper used by both `inspect_agent_sessions`
  here and `isolation::finalize::has_jackin_sessions`, replacing
  the duplicate parser that was warned about in finding #3.

* `src/isolation/finalize.rs` — `parse_session_count` is now
  `runtime::attach::parse_session_count`; the local copy is gone.
  One header parser, one definition of malformed, no silent
  divergence on edge cases.

* `crates/jackin-capsule/src/socket.rs` — accept-loop cap-rejection
  log now fires exactly once on the saturation transition + once on
  the recovery transition, with per-drop messages demoted to
  `cdebug!` so a flood attacker (the exact threat
  `MAX_CONCURRENT_CLIENTS` defends against) cannot drown the
  compact-tier log. Per-backoff line also demoted to `cdebug!` —
  the accept-error clog above already names the failure, so the
  1-line-per-failure compact-log invariant holds. `start_listener_at`
  splits behind a new `start_listener_at_with_limiter` test-only
  helper that returns the inner `Arc<Semaphore>`. The cap regression
  test now reads `limiter.available_permits()` directly instead of
  racing `rx.recv()` against a 300 ms wall-clock deadline —
  cap-sensitive, not timing-sensitive. Wall-clock `timeout()`
  windows widen to 2 s for the remaining positive assertions so a
  slow CI runner does not produce spurious failures.

* `crates/jackin-capsule/src/protocol/attach.rs` — new
  `hello_env_count_over_cap_is_rejected_by_decoder_with_full_payload`
  variant supplies a fully-populated payload of `MAX_HELLO_ENV + 1`
  real entries so the per-entry boundary is verified after the read
  loop, not just at the count declaration. The earlier test only
  exercised the front-of-loop guard; a regression that moved the
  cap check below the per-entry loop would slip past it silently.

Deferred (parallel-agent territory or out-of-scope for this pass):

* `crates/jackin-capsule/src/session.rs` kitty single-pop vs N-push
  asymmetry (finding #6) and `focus_swap_reset_*` test-name
  overpromises (finding #12) — `session.rs` is mid-rebase by the
  parallel agent.
* `crates/jackin-capsule/src/main.rs` `--focus` eprintln eaten by
  alt-screen swap (finding #8) — `main.rs` mid-rebase.
* `src/runtime/launch.rs` `fake_docker_for_clean_attached_exit`
  fixture ordering (finding #14) — `launch.rs` mid-rebase under
  the env-config migration.

Setup-once gating left untouched: `docker/runtime/entrypoint.sh`
already gates on `/jackin/state/hooks/setup-once.done` (line 78,
runs only if marker absent; line 88 writes the marker on success).
The new `test -S` socket gate on the host-side status query is the
orthogonal half of the "don't query during early bring-up" rule.

Co-authored-by: Codex <codex@openai.com>
Signed-off-by: Alexey Zhokhov <alexey@zhokhov.com>
donbeave added a commit that referenced this pull request May 23, 2026
Trust-but-verify pass on the 15-item /code-review max-effort report
that followed the parallel-agent capture commit. Splits cleanly from
the in-flight env-config refactor by touching only the host-side
session-inventory and snapshot-fanout paths plus the capsule socket
layer; parallel-agent territory (main.rs, daemon.rs, session.rs,
launch.rs, env_model.rs, derived_image.rs, entrypoint.sh) stays
untouched.

Findings addressed:

* `src/console/manager/state.rs` — fan-out worker panics now surface
  through the existing `debug_log` path: `h.join()` failures are
  downcast to a string and re-routed as `Err(anyhow!)` so the slot
  is no longer dropped by `filter_map(|h| h.join().ok())`. Snapshot
  fan-out is also bounded by `SNAPSHOT_FANOUT_CHUNK = 8` so a host
  with dozens of active containers does not spawn dozens of OS
  threads per 500 ms refresh tick; each chunk's wall-clock cost is
  still bounded by the slowest fetch in that chunk. The fan-out
  body moves into a free `fetch_snapshots_parallel` helper so
  `refresh_instances` stays under the clippy line-count gate.

* `src/runtime/attach.rs` — `JACKIN_STATUS_CMD` now gates on
  `test -S /jackin/run/jackin.sock` so the early-bring-up window
  (between container start and the daemon binding its socket, plus
  any pre-`setup-once` time) does not leak operator-visible stderr
  from a binary that exists but cannot serve yet. `test -S` exits
  silently with status 1 if the socket is absent; `||` short-
  circuits at the first failure only — no `|| true` masking the
  second command's errors once the socket exists. `parse_jackin_sessions`
  drops the strict `len() != expected` equality in favour of
  `take(expected)` so trailing footer lines or labels that
  `Display`-emit a non-`[` continuation line no longer flip the
  parse to Unavailable; the count check is now a lower-bound
  (`< expected`), which still catches real format drift but
  tolerates harmless decoration. The header search lifts a shared
  `parse_session_count` helper used by both `inspect_agent_sessions`
  here and `isolation::finalize::has_jackin_sessions`, replacing
  the duplicate parser that was warned about in finding #3.

* `src/isolation/finalize.rs` — `parse_session_count` is now
  `runtime::attach::parse_session_count`; the local copy is gone.
  One header parser, one definition of malformed, no silent
  divergence on edge cases.

* `crates/jackin-capsule/src/socket.rs` — accept-loop cap-rejection
  log now fires exactly once on the saturation transition + once on
  the recovery transition, with per-drop messages demoted to
  `cdebug!` so a flood attacker (the exact threat
  `MAX_CONCURRENT_CLIENTS` defends against) cannot drown the
  compact-tier log. Per-backoff line also demoted to `cdebug!` —
  the accept-error clog above already names the failure, so the
  1-line-per-failure compact-log invariant holds. `start_listener_at`
  splits behind a new `start_listener_at_with_limiter` test-only
  helper that returns the inner `Arc<Semaphore>`. The cap regression
  test now reads `limiter.available_permits()` directly instead of
  racing `rx.recv()` against a 300 ms wall-clock deadline —
  cap-sensitive, not timing-sensitive. Wall-clock `timeout()`
  windows widen to 2 s for the remaining positive assertions so a
  slow CI runner does not produce spurious failures.

* `crates/jackin-capsule/src/protocol/attach.rs` — new
  `hello_env_count_over_cap_is_rejected_by_decoder_with_full_payload`
  variant supplies a fully-populated payload of `MAX_HELLO_ENV + 1`
  real entries so the per-entry boundary is verified after the read
  loop, not just at the count declaration. The earlier test only
  exercised the front-of-loop guard; a regression that moved the
  cap check below the per-entry loop would slip past it silently.

Deferred (parallel-agent territory or out-of-scope for this pass):

* `crates/jackin-capsule/src/session.rs` kitty single-pop vs N-push
  asymmetry (finding #6) and `focus_swap_reset_*` test-name
  overpromises (finding #12) — `session.rs` is mid-rebase by the
  parallel agent.
* `crates/jackin-capsule/src/main.rs` `--focus` eprintln eaten by
  alt-screen swap (finding #8) — `main.rs` mid-rebase.
* `src/runtime/launch.rs` `fake_docker_for_clean_attached_exit`
  fixture ordering (finding #14) — `launch.rs` mid-rebase under
  the env-config migration.

Setup-once gating left untouched: `docker/runtime/entrypoint.sh`
already gates on `/jackin/state/hooks/setup-once.done` (line 78,
runs only if marker absent; line 88 writes the marker on success).
The new `test -S` socket gate on the host-side status query is the
orthogonal half of the "don't query during early bring-up" rule.

Co-authored-by: Codex <codex@openai.com>
Signed-off-by: Alexey Zhokhov <alexey@zhokhov.com>
donbeave added a commit that referenced this pull request May 23, 2026
Trust-but-verify pass on the 15-item /code-review max-effort report
that followed the parallel-agent capture commit. Splits cleanly from
the in-flight env-config refactor by touching only the host-side
session-inventory and snapshot-fanout paths plus the capsule socket
layer; parallel-agent territory (main.rs, daemon.rs, session.rs,
launch.rs, env_model.rs, derived_image.rs, entrypoint.sh) stays
untouched.

Findings addressed:

* `src/console/manager/state.rs` — fan-out worker panics now surface
  through the existing `debug_log` path: `h.join()` failures are
  downcast to a string and re-routed as `Err(anyhow!)` so the slot
  is no longer dropped by `filter_map(|h| h.join().ok())`. Snapshot
  fan-out is also bounded by `SNAPSHOT_FANOUT_CHUNK = 8` so a host
  with dozens of active containers does not spawn dozens of OS
  threads per 500 ms refresh tick; each chunk's wall-clock cost is
  still bounded by the slowest fetch in that chunk. The fan-out
  body moves into a free `fetch_snapshots_parallel` helper so
  `refresh_instances` stays under the clippy line-count gate.

* `src/runtime/attach.rs` — `JACKIN_STATUS_CMD` now gates on
  `test -S /jackin/run/jackin.sock` so the early-bring-up window
  (between container start and the daemon binding its socket, plus
  any pre-`setup-once` time) does not leak operator-visible stderr
  from a binary that exists but cannot serve yet. `test -S` exits
  silently with status 1 if the socket is absent; `||` short-
  circuits at the first failure only — no `|| true` masking the
  second command's errors once the socket exists. `parse_jackin_sessions`
  drops the strict `len() != expected` equality in favour of
  `take(expected)` so trailing footer lines or labels that
  `Display`-emit a non-`[` continuation line no longer flip the
  parse to Unavailable; the count check is now a lower-bound
  (`< expected`), which still catches real format drift but
  tolerates harmless decoration. The header search lifts a shared
  `parse_session_count` helper used by both `inspect_agent_sessions`
  here and `isolation::finalize::has_jackin_sessions`, replacing
  the duplicate parser that was warned about in finding #3.

* `src/isolation/finalize.rs` — `parse_session_count` is now
  `runtime::attach::parse_session_count`; the local copy is gone.
  One header parser, one definition of malformed, no silent
  divergence on edge cases.

* `crates/jackin-capsule/src/socket.rs` — accept-loop cap-rejection
  log now fires exactly once on the saturation transition + once on
  the recovery transition, with per-drop messages demoted to
  `cdebug!` so a flood attacker (the exact threat
  `MAX_CONCURRENT_CLIENTS` defends against) cannot drown the
  compact-tier log. Per-backoff line also demoted to `cdebug!` —
  the accept-error clog above already names the failure, so the
  1-line-per-failure compact-log invariant holds. `start_listener_at`
  splits behind a new `start_listener_at_with_limiter` test-only
  helper that returns the inner `Arc<Semaphore>`. The cap regression
  test now reads `limiter.available_permits()` directly instead of
  racing `rx.recv()` against a 300 ms wall-clock deadline —
  cap-sensitive, not timing-sensitive. Wall-clock `timeout()`
  windows widen to 2 s for the remaining positive assertions so a
  slow CI runner does not produce spurious failures.

* `crates/jackin-capsule/src/protocol/attach.rs` — new
  `hello_env_count_over_cap_is_rejected_by_decoder_with_full_payload`
  variant supplies a fully-populated payload of `MAX_HELLO_ENV + 1`
  real entries so the per-entry boundary is verified after the read
  loop, not just at the count declaration. The earlier test only
  exercised the front-of-loop guard; a regression that moved the
  cap check below the per-entry loop would slip past it silently.

Deferred (parallel-agent territory or out-of-scope for this pass):

* `crates/jackin-capsule/src/session.rs` kitty single-pop vs N-push
  asymmetry (finding #6) and `focus_swap_reset_*` test-name
  overpromises (finding #12) — `session.rs` is mid-rebase by the
  parallel agent.
* `crates/jackin-capsule/src/main.rs` `--focus` eprintln eaten by
  alt-screen swap (finding #8) — `main.rs` mid-rebase.
* `src/runtime/launch.rs` `fake_docker_for_clean_attached_exit`
  fixture ordering (finding #14) — `launch.rs` mid-rebase under
  the env-config migration.

Setup-once gating left untouched: `docker/runtime/entrypoint.sh`
already gates on `/jackin/state/hooks/setup-once.done` (line 78,
runs only if marker absent; line 88 writes the marker on success).
The new `test -S` socket gate on the host-side status query is the
orthogonal half of the "don't query during early bring-up" rule.

Signed-off-by: Alexey Zhokhov <alexey@zhokhov.com>
Co-authored-by: Codex <codex@openai.com>
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