Repository navigation
fix: reconcile headless managed settings without prompting - #1008
Merged
Merged
Conversation
tt-le
force-pushed
the
tt-le/ug-headless-reconciliation-stacked
branch
from
October 6, 2026 20:22
93803fd to
3f45f81
Compare
sunishsheth2009
pushed a commit
to sunishsheth2009/ucode
that referenced
this pull request
Oct 6, 2026
## Stack 1. **This PR:** keep headless Claude/Codex stdout clean; targets `main`, merges independently. 2. Follow-up: databricks#1008 — non-prompting managed-settings reconciliation. ## Problem `isaac --claude -p --output-format json … > out.json` produces invalid JSON because UG prints status lines to stdout before the agent's output. Reported with Isaac `2.0.0-20261005192727-d3c9edb` / UG `0.1.0+0857d42` ([Slack](https://databricks.slack.com/archives/C0AH87SNGNT/p1790166359916159)). The thread also contains a second, separate failure: when the OS-managed settings differ on a UG-owned key (e.g. Isaac's `jq … model-serving-token.json` `apiKeyHelper`), headless launches stop with `cannot be applied non-interactively`. That is databricks#1008, not this PR. ## Changes - For Claude `-p`/`--print` and Codex `exec`/`e`/`app-server`, send UG status and bootstrap/install output to stderr. The agent's own stdout is untouched. - Detect headless mode by argument membership before the agent's `--` (no Codex option parser). Matching an option value only moves UG diagnostics to stderr. - Unit/component regressions for streams, errors, forwarding, and bootstrap subprocesses; live headless journeys now parse raw JSON/JSONL. ## Validation - Unit/component suites, Ruff, ty pass; CI green. - confirmed with local isaac build that `--p --output-format json` and `exec --json` produce valid jsons. | Case | `main` @ `4c1b866` | this PR @ `39f2d12` | |---|---|---| | `ug claude -- -p --output-format json` | ❌ | ✅ | | `ug claude -- --print --output-format json` | ❌ | ✅ | | `ug claude -- -p --output-format stream-json --verbose` | ❌ | ✅ | | `ug claude -- -p` (text) | ❌ | ✅ | | `ug claude -- --output-format json --model sonnet -p` | ❌ | ✅ | | `ug claude -- -p … \| python3 -m json.tool` | ❌ | ✅ | | `ug codex exec --json` | ❌ | ✅ | | `ug codex e --json` | ❌ | ✅ | | `ug codex -c … exec --json` | ❌ | ✅ | | `ug codex exec` (text) | ❌ | ✅ | | `ug codex exec --output-schema …` (stdout) | ❌ | ✅ | | `ug codex exec --output-schema … -o file` (file) | ✅ | ✅ | ## Scope No managed-settings, sudo, or Isaac changes (e.g. Isaac exit-code propagation, Isaac replacing `apiKeyHelper`). This pull request and its description were written by Isaac.
tt-le
force-pushed
the
tt-le/ug-headless-reconciliation-stacked
branch
from
October 7, 2026 13:20
3f45f81 to
be771e4
Compare
tt-le
force-pushed
the
tt-le/ug-headless-reconciliation-stacked
branch
from
October 7, 2026 13:40
be771e4 to
1520d3f
Compare
`managed_writes_allowed()` was doing double duty: with `repair_existing` it is the write-authorization gate, but its no-arg form was borrowed as an "is a terminal attached?" check at the sudo-mode sites, so `non_interactive = not managed_writes_allowed()` read backwards. Extract `_sudo_may_prompt()` for the TTY/prompt-mode check and build `managed_writes_allowed()` on top of it; the three prompt-mode sites now call `_sudo_may_prompt()` while the authorization-gate sites keep `managed_writes_allowed`. Behavior is unchanged (`_sudo_may_prompt()` equals the former no-arg form). Co-authored-by: Isaac <no-reply@databricks.com>
UG reviewReviewed headless Claude/Codex managed-file reconciliation and the shared privileged writer, focusing on non-prompting sudo, configuration ownership, backup preservation, and interactive compatibility. No actionable findings. Automated advisory review of |
david-siqi-liu
approved these changes
Oct 8, 2026
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.
Summary
Headless Claude/Codex launches fail when an existing OS-managed file overrides UG's gateway settings. Allow those conflicting files to be repaired using one-shot
sudo -nwith stdin disconnected. Authorization failures still block launch; there is no password-prompt fallback.Reuse the existing backup, policy-preserving composition, atomic write, and verification. Leave absent/compatible files unchanged. Headless creation, revert, and managed MCP writes remain out of scope.
This PR targets
main; the separate stdout/JSON fix (#1007) is already merged. Preventing Isaac from replacing UG'sapiKeyHelperand propagating harness exit codes remain separate Isaac work.Validation
isaac -p ... --output-format json). The headless launch — which fails onmain— succeeded and returned JSON, confirming the fix.git diff --checkpassed./etcwrites run there; those paths were exercised by the local Isaac repro above.This pull request description was written with AI assistance.