Skip to content

Zero-regression hardening: close 2 RCEs + 70 correctness/robustness findings (ZRCS Steps 0-10)#12

Merged
aksOps merged 18 commits into
mainfrom
worktree-zero-regression
May 29, 2026
Merged

Zero-regression hardening: close 2 RCEs + 70 correctness/robustness findings (ZRCS Steps 0-10)#12
aksOps merged 18 commits into
mainfrom
worktree-zero-regression

Conversation

@aksOps

@aksOps aksOps commented May 29, 2026

Copy link
Copy Markdown
Contributor

Summary

Implements the full Zero-Regression Change Sequence (ZRCS) — the prioritized output of a multi-agent review of the codebase. Closes 2 confirmed RCEs and 70 additional correctness / robustness / build findings across 11 ordered steps, each landed TDD-first and gated by the full -race suite.

Baseline was 106 tests; this PR ships 315 tests (+209), all green under -race, with zero regressions (suite is additive-green; the original behaviors still pass).

Why

A senior-architect review surfaced one CRITICAL command-execution path plus a cluster of correctness defects in the store read-modify-write path, resume/reconciliation logic, tmux protocol parsing, and the TUI. Each finding was adversarially verified (false positives discarded) and given a tests-needed-first gate so the fixes could land without breaking existing behavior.

Highlights

  • CRITICAL — two RCEs closed & proven inert (commit 5a24535):
    • shellQuote used strconv.Quote (double quotes) → $(...)/backtick/$VAR reached /bin/sh -c via tmux new-session. Now POSIX single-quote escaping; proven inert by a sh -c sentinel test.
    • tmux session name flowed unvalidated into the run-shell session-closed hook (#{hook_session_name}, re-expanded by tmux); CreateSession now allow-lists ^uam-[a-z0-9]+-[0-9a-f]{1,16}$.
    • Plus sessions.json is now validated on load (drop+log), and gh pr view passes the URL after --.
  • Store integrity: atomic LoadSessions read-modify-write under one lock (fixes a lost-update vs TogglePin), landed behind a new store-concurrency test; schema-downgrade guard; quarantine-safe corrupt-config load; collision-guarded insert.
  • Resume safety: Claude/Codex now resume via --continue / resume --last instead of re-running the original prompt in full-access mode.
  • tmux robustness: one malformed list-sessions line (e.g. a cwd containing |) no longer drops the whole batch; tmux 3.4 empty-server detection; multiline-prompt handling.
  • TUI: rename-target panic/retarget guards, multibyte/paste input, width-aware rendering, PR/state glyphs, peek-follows-cursor, message TTL.
  • Build/distribution: reproducible static build (CGO_ENABLED=0 -trimpath), vendored deps for offline/air-gapped builds, secret-independent CI gate, pinned security tools, Dependabot/CODEOWNERS.

Verification

  • go build ./..., go vet ./..., gofmt -l . — clean
  • go test -race ./...315 pass
  • go mod verify — all modules verified
  • govulncheck ./...0 reachable vulnerabilities
  • Offline build: GOPROXY=off go build -mod=vendor ./cmd/uam ✓ → statically-linked, stripped binary

Commit map (15 atomic commits, one per step/cluster)

Commit Step Findings
5a24535 0-1 security + safety-net F05, F06, F08, F09, F46, F50
41d1329 2 LoadSessions/RMW F01, C1-1, F18
0667151 3 partial-failure/orphan F03, F04, F19, C1-2, F32
64b80ad 4 resume C1-5, C2-5, F42
2b33c9e 5 tmux protocol F10, F11, F12, F25, F56, F13
297a773 6a TUI input F27, C2-1, F29, C2-3
132ecc3 6b TUI render F28, F26, F30, F58, C2-2, F53, F55
80099ee 7a migration F07, F33, F44
a7343b5 7b store integrity F22, F43, F45, C2-7
d63c6c3 8a lifecycle F20, F24, F02, F17
28463ea 8b cadence/perf F16, F60, C2-11, F59, F34
144caa9 9a wiring F14, F21, F36, C2-9, C2-8
0eacef6 9b deadcode/cli F40, F41, C1-3, C1-6, C2-4, F54
b7f113a 9c hygiene F51, F52, F57
cd01601 10 build/dist F48, F47, F49

Review guidance

  • The diff is dominated by vendor/ (F48 added the vendored module tree for offline builds). The real change is 72 non-vendor files / 46 test files — review those. If vendoring is not wanted in this repo, the cd01601 commit can be dropped/adjusted independently.
  • Worth a closer human eye: the TUI render cluster (132ecc3) and the refresh-cadence rework (28463ea).

Known limitations

  • gosec was not run locally (not installed in the dev env) — CI security.yml runs it (now version-pinned per F47). The RCE fixes are proven by behavioral sh -c tests.
  • sonar.yml's secret-gated skip still reports a green check when SONAR_TOKEN is absent; the new ci.yml gate is fully secret-independent, so this is cosmetic. Flagged as a follow-up.

aksOps and others added 15 commits May 29, 2026 09:37
…ety-net

Wave 1 of the Zero-Regression Change Sequence (TDD, full -race gate):

- F05 (CRITICAL): shellQuote used strconv.Quote (double quotes) so $(...)/
  backtick/$VAR reached /bin/sh -c via tmux new-session. Now POSIX
  single-quote escaping. Proven inert via sh -c sentinel test.
- F06: tmux session name flowed unvalidated into the run-shell hook
  (#{hook_session_name}); CreateSession now allow-lists ^uam-[a-z0-9]+-[0-9a-f]{1,16}$.
- F08: sessions.json records validated on load (drop+log) — defense-in-depth
  metachar deny-list, runs in loadNoLock before migrate/re-persist.
- F09: gh pr view now passes the URL after `--`; PR URL validated against
  the anchored GitHub shape.
- F50: TestStoreUpdateIsAtomicUnderConcurrency — store concurrency safety net.
- F46: secret-independent ci.yml (build/vet/gofmt/-race/lint).

Gate: build+vet+gofmt clean, 129 tests pass under -race (106 baseline).
Checkpoint commit on worktree branch only.
…han guards (ZRCS F03,F04,F19,C1-2,F32)

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
…tempfile, PR owner/repo rehydrate (ZRCS F22,F43,F45,C2-7)
…hrottle, reorder debounce (ZRCS F16,F60,C2-11,F59,F34)
…ation, wizard parity (ZRCS F14,F21,F36,C2-9,C2-8)
Comment thread .github/workflows/ci.yml Fixed
Comment thread .github/workflows/release.yml Fixed
Comment thread .github/workflows/release.yml Fixed
Comment thread .github/workflows/release.yml Fixed
…target Go skew)

golangci-lint v1.62.2 is built with go1.23 and refuses a go1.24 target;
the repo already ships a version:"2" .golangci.yml. Switch to
golangci-lint-action@v7 + v2.1.6 with install-mode goinstall so the linter
is compiled with the repo's own toolchain. Verified locally: 0 issues.
Comment thread .github/workflows/ci.yml Fixed
@aksOps aksOps enabled auto-merge (squash) May 29, 2026 14:23
aksOps added 2 commits May 29, 2026 14:28
The offline/air-gap requirement applies to the *runtime* (the production
binary makes no public-internet calls — it is static and the only network
call, gh pr view, is timeout-bounded), not the build environment, which has
proxy access. Vendoring added ~274k lines of dependency source for no benefit
here. Removed vendor/; go.sum + the module proxy provide reproducibility.
Static -trimpath build, pinned CI tools, and dependabot/CODEOWNERS retained.
Resolves the CodeQL "unpinned tag for a non-immutable Action" supply-chain
findings on the new workflows by pinning to immutable commit SHAs (tag kept
as a trailing comment). Consistent with ZRCS F47 (pin CI tooling).

- golangci/golangci-lint-action v7
- anchore/sbom-action/download-syft v0.17.9
- sigstore/cosign-installer v3.7.0
- goreleaser/goreleaser-action v6
@sonarqubecloud

Copy link
Copy Markdown

@aksOps aksOps merged commit 784767a into main May 29, 2026
13 checks passed
@aksOps aksOps deleted the worktree-zero-regression branch May 29, 2026 14:43
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.

2 participants