Skip to content

chore(hooks): make pre-push degrade gracefully in constrained environments - #13579

Open
maphew wants to merge 23 commits into
Kilo-Org:mainfrom
maphew:chore/hook-graceful-degradation
Open

maphew wants to merge 23 commits into
Kilo-Org:mainfrom
maphew:chore/hook-graceful-degradation

Conversation

@maphew

@maphew maphew commented Aug 29, 2026

Copy link
Copy Markdown
Contributor

What

Makes the pre-push hook and build tooling resilient in constrained/cloud dev environments that lack the full toolchain:

  • .husky/pre-push — honor KILO_SKIP_BUN_VERSION_CHECK=1 to bypass the hard bun version gate (for sandboxes whose bun can't be upgraded), and skip the JetBrains typecheck with a warning when no Java is present.
  • packages/script/src/index.ts — mirror the same KILO_SKIP_BUN_VERSION_CHECK=1 override (the hook and this script share the semver gate and are documented as "keep in sync").
  • script/setup-sandbox.sh — new idempotent bootstrap for constrained environments: installs Java 21, trusts the sandbox TLS intercept CA for git/JVM/gh, and runs bun install.
  • AGENTS.md — document the constraints and the escape hatches.

Why

Cloud agent sandboxes and CI-less containers often ship a bun below the pinned version and no JDK, so every push fails the pre-push hook before any code quality signal. These changes let the hook degrade gracefully: the hard gates become skippable with an explicit opt-in env var, and the JetBrains check is skipped (with a warning) when Java is missing. The setup script restores the full toolchain when it's available.

The overrides are opt-in — default behavior (hard gate, JetBrains check) is unchanged, and CI runs the same checks independently.

Verification

  • bun run script/check-opencode-annotations.ts --worktree — pass
  • tsgo --noEmit -p packages/script/tsconfig.json — pass
  • Hook logic tested both with and without KILO_SKIP_BUN_VERSION_CHECK=1 (bun 1.3.12 vs required ^1.3.14)
  • script/setup-sandbox.sh ran end-to-end in a sandbox (installed Java 21, configured git http.sslCAInfo + JVM cacerts, bun install)

Note: git push from a sandbox may still need --no-verify when gradle can't download dependencies (e.g. TLS intercept), which the hook cannot detect.

Draft: awaiting review.

@maphew
maphew marked this pull request as ready for review August 29, 2026 20:06

maphew commented Aug 29, 2026

Copy link
Copy Markdown
Contributor Author

Adversarial review complete (draft sweep). Findings addressed in e7a5203:

  • pre-push Java check: JAVA_HOME set but non-executable now counts as Java absent, so the JetBrains typecheck degrades gracefully (warning) instead of failing loudly — verified against dash (the hook's /bin/sh).
  • setup-sandbox.sh idempotency: stale chain-*.pem files are cleared before re-extraction; the keytool import no longer warns spuriously when the CA is already imported; replacing an existing global http.sslCAInfo is now called out.

Verification: tsgo --noEmit -p packages/script/tsconfig.json clean, annotation check passes, hook gate tested with/without KILO_SKIP_BUN_VERSION_CHECK=1 (bun 1.3.12 vs ^1.3.14), has_java21 version detection tested. Branch synced with main (0 behind).

@chatgpt-codex-connector

chatgpt-codex-connector Bot commented Aug 29, 2026 •

Copy link
Copy Markdown

Codex Review Summary

This comment shows the latest Codex review activity on this pull request.

Review Status Commit Review trigger
📝 Code Review ✅ Completed 2026-08-29T20:11:21.989649Z e7a5203 Draft marked ready
ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review" or "@codex security review".

Codex reacts with 👀 while any review is running, comments if it has suggestions, and reacts with 👍 once all reviews finish with no findings.

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: e7a5203cd5

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread script/setup-sandbox.sh Outdated
Comment thread script/setup-sandbox.sh Outdated
@kilo-code-bot

kilo-code-bot Bot commented Aug 29, 2026 •

Copy link
Copy Markdown
Contributor

Code Review Summary

Status: No Issues Found | Recommendation: Merge

The prior suggestion (missing intermediates during candidate-CA verification) is resolved in 8ebf467: extract_intercept_ca now passes every presented cert other than the candidate anchor and the leaf via repeated -untrusted, while trust stays anchored on the candidate through -CAfile plus -no-CAfile/-no-CApath/-no-CAstore. The added untrusted certs cannot become trust anchors, so the attacker-supplied-root guard is preserved.

Files Reviewed (4 files)
  • script/setup-sandbox.sh (incremental change, lines 95-108)
  • .husky/pre-push (unchanged since previous review)
  • AGENTS.md (unchanged since previous review)
  • packages/script/src/index.ts (unchanged since previous review)
Previous Review Summaries (8 snapshots, latest commit ef01e1b)

Current summary above is authoritative. Previous snapshots are kept for context only.

Previous review (commit ef01e1b)

Status: 1 Issue Found | Recommendation: Address before merge

Overview

Severity Count
CRITICAL 0
WARNING 0
SUGGESTION 1
Issue Details (click to expand)

SUGGESTION

File Line Issue
script/setup-sandbox.sh 98 Verification can reject a valid intercept chain that contains an intermediate: -CAfile "$f" supplies only the self-signed candidate as anchor and the other presented chain certs are not passed via -untrusted, so multi-level intercept chains fail path building and CA setup is skipped even though the chain was legitimate.
Files Reviewed (4 files)
  • .husky/pre-push
  • AGENTS.md
  • packages/script/src/index.ts
  • script/setup-sandbox.sh - 1 suggestion

Fix these issues in Kilo Cloud

Previous review (commit e75a060)

Status: 1 Issue Found | Recommendation: Address before merge

Overview

Severity Count
CRITICAL 0
WARNING 1
SUGGESTION 0
Issue Details (click to expand)

WARNING

File Line Issue
script/setup-sandbox.sh 90 The intercept-CA leaf check (openssl verify -no-CAfile -no-CApath -CAfile "$f" "$leaf") still consults OpenSSL's default certificate store, which on Debian/Ubuntu resolves to the system CA directory that holds the real intercept CA. Because that CA already signed the presented leaf (it passed -verify_return_error above), the leaf verifies against any self-signed candidate and the first one wins, so an attacker-supplied root can still be installed globally for git (http.sslCAInfo) and into the JVM cacerts. Add -no-CAstore (OpenSSL 3.0+) so trust is anchored solely on the candidate; guard it if the script must also run on 1.1.1.
Files Reviewed (4 files)
  • .husky/pre-push
  • AGENTS.md
  • packages/script/src/index.ts
  • script/setup-sandbox.sh - 1 issue

Fix these issues in Kilo Cloud

Previous review (commit d8db523)

Status: 1 Issue Found | Recommendation: Address before merge

Overview

Severity Count
CRITICAL 0
WARNING 1
SUGGESTION 0
Issue Details (click to expand)

WARNING

File Line Issue
script/setup-sandbox.sh 90 The intercept-CA leaf check (openssl verify -no-CAfile -no-CApath -CAfile "$f" "$leaf") still consults OpenSSL's default certificate store, which resolves to the system CA directory (/usr/lib/ssl/certs -> /etc/ssl/certs). Because that directory holds the real intercept CA, the leaf verifies against any self-signed candidate and the first one still wins, so an attacker root can still be installed globally for git and the JVM. Add -no-CAstore.
Files Reviewed (4 files)
  • .husky/pre-push
  • AGENTS.md
  • packages/script/src/index.ts
  • script/setup-sandbox.sh - 1 issue

Fix these issues in Kilo Cloud

Previous review (commit 43e104a)

Status: 1 Issue Found | Recommendation: Address before merge

Overview

Severity Count
CRITICAL 0
WARNING 1
SUGGESTION 0
Issue Details (click to expand)

WARNING

File Line Issue
script/setup-sandbox.sh 86 The new leaf check openssl verify -CAfile "$f" "$leaf" still consults the system's default trusted certificate directory, so it does not isolate trust to the candidate CA. Since the earlier -verify_return_error step only reaches this code when the presented chain already verifies against the system store, the leaf will verify against any self-signed candidate. A relay/proxy that prepends its own self-signed root ahead of the real intercept CA is therefore still selected (first self-signed match wins) and installed as git's global http.sslCAInfo and into the JVM cacerts. Pass -no-CApath (and -no-CAfile) so the check is anchored solely on $f.
Files Reviewed (4 files)
  • .husky/pre-push
  • AGENTS.md
  • packages/script/src/index.ts
  • script/setup-sandbox.sh - 1 issue

Fix these issues in Kilo Cloud

Previous review (commit 3a80191)

Status: 1 Issue Found | Recommendation: Address before merge

Overview

Severity Count
CRITICAL 0
WARNING 1
SUGGESTION 0
Issue Details (click to expand)

WARNING

File Line Issue
script/setup-sandbox.sh 78 extract_intercept_ca picks the first self-signed certificate from the raw -showcerts output instead of the CA that actually signed the verified github.com leaf, so a relay MITM can precede the intercept CA with its own root; setup_ca then installs that root as Git's global http.sslCAInfo and into the JVM cacerts. Verify the chosen CA against the leaf (e.g. openssl verify -CAfile "$f" chain-1.pem) before trusting it.
Files Reviewed (4 files)
  • .husky/pre-push
  • AGENTS.md
  • packages/script/src/index.ts
  • script/setup-sandbox.sh - 1 issue

Fix these issues in Kilo Cloud

Previous review (commit dca2524)

Status: No Issues Found | Recommendation: Merge

Files Reviewed (4 files)
  • .husky/pre-push
  • AGENTS.md
  • packages/script/src/index.ts
  • script/setup-sandbox.sh

Previous review (commit c6d2ce1)

Status: No Issues Found | Recommendation: Merge

Files Reviewed (2 files)
  • AGENTS.md
  • script/setup-sandbox.sh

Previous review (commit e7a5203)

Status: 2 Issues Found | Recommendation: Address before merge

Overview

Severity Count
CRITICAL 0
WARNING 2
SUGGESTION 0
Issue Details (click to expand)

WARNING

File Line Issue
script/setup-sandbox.sh 44 Java install failure aborts the rest of bootstrap
script/setup-sandbox.sh 63 Intercept CA detection treats the issuer DN as a regex
Files Reviewed (4 files)
  • .husky/pre-push
  • AGENTS.md
  • packages/script/src/index.ts
  • script/setup-sandbox.sh - 2 issues

Fix these issues in Kilo Cloud


Reviewed by deepseek-flash-latest · Input: 41.3K · Output: 8.8K · Cached: 253.6K

Review guidance: REVIEW.md from base branch main

maphew commented Aug 31, 2026

Copy link
Copy Markdown
Contributor Author

Addressed all four outstanding review findings in 94f9738:

  • Codex P1 (authenticate the CA before trusting): extract_intercept_ca now requires the github.com chain to verify against the system trust store (-verify_return_error -verify_hostname github.com). An unverifiable chain — e.g. an attacker-injected self-signed one — is rejected with a warning and nothing is installed globally for git or the JVM. Verified live in a proxy sandbox: Verify return code: 0 (ok) and the intercept CA is still detected.
  • Codex P2 (stale JVM alias): the kilocode-sandbox-intercept alias is deleted before import, so a changed proxy CA between runs replaces the obsolete certificate instead of silently leaving the old one trusted.
  • kilo WARNING (Java install abort): the apt-get install is guarded, so a failed install no longer aborts the rest of bootstrap (setup_ca/setup_install still run).
  • kilo WARNING (issuer DN as regex): the self-sign check uses grep -qF, matching the DN as a literal string rather than a regex.

Also verified end-to-end: with Java absent and bun below the gate range, the modified pre-push hook now skips the JetBrains typecheck with a warning and exits 0; packages/script typecheck is clean. Branch synced with main (0 behind).

maphew commented Aug 31, 2026

Copy link
Copy Markdown
Contributor Author

Added setup_bun to script/setup-sandbox.sh (c6d2ce1): the bootstrap now reads the packageManager range from package.json and upgrades a stale system bun in place (bun upgrade) instead of relying on KILO_SKIP_BUN_VERSION_CHECK=1. Falls back to the documented override warning when the upgrade isn't possible (e.g. a package-manager-managed bun). Also fixed the summary line so a missing java prints missing rather than shell noise.

Verified end-to-end in a sandbox with the old baked-in bun 1.3.12: ./script/setup-sandbox.sh upgrades to a range-satisfying bun, and the pre-push hook then passes without any override (Java gate skips gracefully). AGENTS.md guidance updated.

maphew commented Sep 3, 2026

Copy link
Copy Markdown
Contributor Author

Merge-readiness sweep complete: branch synced with current main (ffc0655, 0 behind), no merge conflicts, CI green on the latest head — including the previously flaky jetbrains WorktreeSessionEditorManagerTest (fixed upstream in main). Replies posted on both Codex threads. Ready for human review.

@maphew maphew closed this Sep 11, 2026
@maphew maphew reopened this Sep 11, 2026
@maphew
maphew force-pushed the chore/hook-graceful-degradation branch from edb8bd3 to 3a80191 Compare September 27, 2026 10:59
@github-actions github-actions Bot added community Opened by someone outside the Kilo team needs-triage Waiting for a maintainer to look labels Oct 8, 2026
@maphew
maphew force-pushed the chore/hook-graceful-degradation branch from 07468b3 to d8db523 Compare October 11, 2026 04:49
maphew and others added 6 commits October 13, 2026 13:14
…ments

Add escape hatches for sandboxes missing tooling:
- KILO_SKIP_BUN_VERSION_CHECK=1 skips the hard bun version gate (kept in sync in packages/script/src/index.ts)
- The JetBrains typecheck is skipped with a warning when no Java is present
- Add script/setup-sandbox.sh to bootstrap constrained/cloud environments: installs Java 21, trusts the sandbox TLS intercept CA for git/JVM/gh, and runs bun install
- Document the constraints in AGENTS.md
- pre-push: treat JAVA_HOME set but non-executable as Java absent so the
  JetBrains check degrades gracefully instead of failing loudly
- setup-sandbox: clear stale chain files, avoid spurious keytool warning
  on already-imported CA, and note when replacing an existing git
  http.sslCAInfo
Address review findings on the setup-sandbox bootstrap:

- Trust the intercept CA only after verifying the github.com chain against
  the system trust store (-verify_return_error -verify_hostname), so an
  attacker who can intercept DNS/TCP during bootstrap cannot inject a CA
  that then gets installed globally for git and the JVM.
- Replace a stale JVM alias before reimporting: a changed proxy CA between
  runs no longer silently leaves the obsolete certificate in cacerts.
- A failed apt-get Java install no longer aborts the rest of bootstrap
  (setup_ca/setup_install now still run).
- The issuer-DN self-sign check compares the DN as a literal string
  (grep -F) instead of a regex, so DNs containing '.', '+', '(' etc.
  are matched correctly.
Ephemeral sandbox images bake an older system bun, so the pre-push hook's
packageManager gate trips before anything else. setup_bun now reads the
required range from package.json and upgrades a stale bun in place
(`bun upgrade`), falling back to a KILO_SKIP_BUN_VERSION_CHECK warning
when the upgrade is not possible (e.g. package-manager-managed bun).
Also tidy the java summary line so a missing java prints "missing"
instead of shell noise.
@maphew
maphew force-pushed the chore/hook-graceful-degradation branch from d8db523 to e75a060 Compare October 13, 2026 20:16
@github-actions github-actions Bot added priority:p2 Medium: features and other work. Set from the title. Change by hand. and removed ci-failing labels Oct 15, 2026
@maphew

maphew commented Oct 22, 2026

Copy link
Copy Markdown
Contributor Author

Review finding addressed in ef01e1b: extract_intercept_ca now adds -no-CAstore to the candidate verification when OpenSSL supports it (3.0+), detected from openssl verify -help; on 1.1.1 the flag is omitted rather than failing the script. Trust for the candidate is now anchored solely on the candidate certificate, so the leaf cannot validate against an arbitrary self-signed root through the default CA store. bash -n script/setup-sandbox.sh and sh -n .husky/pre-push pass.

@maphew

maphew commented Oct 22, 2026

Copy link
Copy Markdown
Contributor Author

Finding addressed in 8ebf467: candidate verification now passes the presented certificates between the leaf and the self-signed anchor via repeated -untrusted flags (excluding the anchor and leaf), so multi-level intercept chains build a valid path. Verified with a generated local three-cert chain (root -> intermediate -> leaf): verification fails without -untrusted and returns OK with it. bash -n script/setup-sandbox.sh passes.

@maphew

maphew commented Oct 23, 2026

Copy link
Copy Markdown
Contributor Author

Sweep note: branch is current with main (0 behind) and the review findings are resolved, but the latest CI run has a failure unrelated to this diff — KiloBackendWorkspaceTest > wsl virtual directory transitions to Unsupported without fetching agents() in packages/kilo-jetbrains hit a TimeoutCancellationException (run 39967003721), which then failed test (linux). Main's equivalent run passed. I do not have permission to rerun failed jobs; a maintainer can rerun it.

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

community Opened by someone outside the Kilo team needs-triage Waiting for a maintainer to look priority:p2 Medium: features and other work. Set from the title. Change by hand.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant