mirror of
https://github.com/Twigpine/zero.git
synced 2026-11-10 05:01:28 -10:00
fix/opencode-session-header
12
Commits
| Author | SHA1 | Message | Date | |
|---|---|---|---|---|
|
|
1fde941803 |
perf: reduce startup and turn overhead (#932)
* perf(tui): disable duplicate composer cursor blink * perf(tui): stop composer wakeups after idle * refactor(tools): publish immutable registry snapshots * perf(startup): defer optional tool discovery * perf(provider): reuse compatible response sessions * feat(provider): add native patch tool input * fix(provider): recognize saved chat sessions * perf(tui): render only on screen changes * fix(runtime): address performance review findings * fix(usage): expose cache efficiency details * perf(agent): reduce redundant bounded-task turns * fix: harden runtime review edge cases * fix: address runtime review findings * build: restore official Bubble Tea dependency * fix(cli): redact MCP registration errors * fix: harden turn session regressions * fix: keep run tools and patch roots consistent * fix: bind freeform patch writes to scoped roots * test: keep patch fixtures out of worktree * fix(tools): reject mixed-root freeform patches |
||
|
|
97ef90d27a |
chore: remove code unreachable on every supported platform (#706)
* chore: remove code unreachable on every supported platform The Security and code health job's advisory deadcode step reports 152 unreachable functions on main. Running the same check under GOOS=linux, windows, and darwin shows 13 of those are false positives whose callers live in windows build-tagged files, so only functions unreachable on all three platforms are touched. Functions with no references anywhere are deleted, including the internal/reasoning package, which nothing imports. Functions that only tests reference move into per-package export_test.go files so tests keep their seams while the production binary sheds the code. Test call sites of deleted convenience wrappers are ported to the live APIs (scoped tool constructors, tools.DeferredSource, FinishReason checks). Kept despite the report: cron.Store.Runs (only reader of runs.jsonl, which production writes), and agenteval.TraceEventKeys and MissingTraceEvents (used across packages by the trace contract test). * docs(config): correct ValidateFile's errors.As claim Message is a flattened string (.Error() already called on the parse error), not a wrapped error, so callers can't recover the concrete json error type via errors.As. Fix the comment to match. Co-Authored-By: Claude Sonnet 5 <[email protected]> * chore(trace,skills): drop obsolete Sink adapters and fix stale doc references The dead-code pass removed the Emit methods but left Sink, NDJSONSink, and TextSink exported with a contract nothing implements; remove the types with their contract. Also remove the stray blank line at EOF of trace.go flagged by gofmt, and update skills package docs and HOW_ZERO_WORKS.md to stop directing callers to DiscoveryRoots/Duplicates, which are now test seams. Co-Authored-By: Claude Fable 5 <[email protected]> * chore: clean up remaining review nits on dead code removal Replace a pointless fmt.Errorf(...%w...).Error() with fmt.Sprintf using %v, since the wrapped error was discarded immediately anyway. Remove a comment block that was duplicated verbatim. * docs(skills): drop remaining references to test-only List/Get Load and MergedSkills comments still named List/Get as production entry points after they moved to export_test.go. Point callers at Load and ListFromRoots instead. * chore: remove now-unreferenced export_test.go seams execSessionManager.len() and likelySandboxDenied/sandboxDenialKind had no remaining callers after the sandbox unify-command-execution rebase; the production code they wrapped for tests no longer exists. --------- Co-authored-by: Claude Sonnet 5 <[email protected]> |
||
|
|
f6c060631e |
fix(openai): handle Ollama reasoning stream deltas (#486)
* fix(openai): handle reasoning alias in stream deltas * test(cli): assert reasoning event order --------- Co-authored-by: Ashwin <[email protected]> |
||
|
|
f7ee189ba5 |
fix: resolve 15 findings from the 2026-06-20 deep audit (#281)
* docs(audit): 2026-06-20 deep adversarial audit report
Audit-only deliverable (no source changed). Fresh origin/main (
|
||
|
|
ac6addaa83 |
Align sandbox permission blocks and backend states (#253)
* Prompt for shell network permissions Route network-risk shell calls through the existing permission prompt instead of hard-denying them at sandbox preflight. Approved network prompts apply the current turn/session request-permissions overlay so the effective sandbox policy is widened only after user approval. Move network command detection into the shell AST analyzer for package installers, gh/git network subcommands, and python http.server so quoted process patterns such as pkill -f "python3 -m http.server 8000" are not misclassified as network activity. Tested: GOCACHE=/tmp/zero-go-cache go test ./internal/sandbox -run 'TestAnalyzeCommand|TestClassifyDoesNotFlagQuotedHttpServerPattern|TestEvaluateExemptsNetworkToolsFromDenyByDefault|TestEngineClassifiesNetworkAndDestructiveShellCommands|TestGrantRequestPermissionsNetworkOverlaysPolicyForTurn' Tested: GOCACHE=/tmp/zero-go-cache go test ./internal/agent -run 'TestRunPersistentCommandPrefixStillPromptsForNetwork|TestRunApprovedNetworkBashPromptAppliesTurnNetworkGrant' Tested: GOCACHE=/tmp/zero-go-cache go test ./internal/tools -run 'TestBash|TestRegistryRunsBashThroughSandboxEngine' Tested: GOCACHE=/tmp/zero-go-cache go test ./... * Auto-allow native-sandboxed shell commands Remove the old hidden bash auto-allow environment/config path. Ordinary shell commands now use the active native sandbox as the permission boundary by default, while network, destructive, and workspace policy checks still run first. Policy-only and disabled sandbox backends continue to require approval for shell commands, so unsandboxed execution is not silently allowed. Tested: GOCACHE=/tmp/zero-go-cache go test ./internal/sandbox -run 'TestSandboxedBash|TestShellSandboxActive|TestEvaluateExemptsNetworkToolsFromDenyByDefault|TestGrantRequestPermissionsNetworkOverlaysPolicyForTurn|TestAnalyzeCommand|TestClassifyDoesNotFlagQuotedHttpServerPattern' Tested: GOCACHE=/tmp/zero-go-cache go test ./internal/tools -run 'TestBashAuto|TestBashStillPromptsWithoutActiveSandbox|TestRegistryRunsBashThroughSandboxEngine' Tested: GOCACHE=/tmp/zero-go-cache go test ./internal/cli -run 'TestApplyConfiguredSandboxPolicy|TestApplyConfiguredAutonomyCeiling' Tested: GOCACHE=/tmp/zero-go-cache go test ./internal/agent -run 'TestRunPersistentCommandPrefixStillPromptsForNetwork|TestRunApprovedNetworkBashPromptAppliesTurnNetworkGrant' Tested: GOCACHE=/tmp/zero-go-cache go test ./internal/daemon -run 'TestScrubWorkerEnvRemovesReentrancyMarkers' Tested: GOCACHE=/tmp/zero-go-cache go test ./... * Prompt for destructive shell approval Remove the separate DenyDestructiveShell policy layer from active sandbox decisions. Destructive shell classification now produces an approval prompt in ask/auto flows instead of a sandbox hard-deny, while no-approval paths remain blocked. Drop the removed destructive-shell policy field from sandbox policy output, backend capabilities, snapshots, and Windows golden data. Tested: GOCACHE=/tmp/zero-go-cache go test ./internal/agent -run 'TestRunPromptsForDestructiveShellInsteadOfSandboxDeny|TestRunPersistentCommandPrefixStillPromptsForNetwork|TestRunApprovedNetworkBashPromptAppliesTurnNetworkGrant' Tested: GOCACHE=/tmp/zero-go-cache go test ./internal/sandbox -run 'TestEngineClassifiesNetworkAndDestructiveShellCommands|TestBackendCapabilitiesReflectDisabledPolicy' Tested: GOCACHE=/tmp/zero-go-cache go test ./internal/cli -run 'TestRunSandboxPolicy|TestEffectiveSandboxPolicy' Tested: GOCACHE=/tmp/zero-go-cache go test ./internal/zerocommands -run 'TestSandboxPolicySnapshotFromPolicyFillsEffectiveMode' Tested: GOCACHE=/tmp/zero-go-cache go test ./... * Remove web-tool network policy switch Remove the old EnforceToolNetwork policy option and the NetworkHostAllowed per-tool gate so sandbox network policy only controls sandboxed shell egress. Keep web_search and web_fetch on their own tool permission and URL safety paths, with tests proving deny/scoped shell network policy no longer blocks in-process web tools. Tested: GOCACHE=/tmp/zero-go-cache go test ./internal/sandbox -run 'TestEvaluateExemptsNetworkToolsFromShellNetworkPolicy|TestEngineAllowsNetworkSideEffectWhenShellPolicyBlocksNetwork|TestGrantRequestPermissionsNetworkOverlaysPolicyForTurn|TestScopedNetworkGateInEvaluate' Tested: GOCACHE=/tmp/zero-go-cache go test ./internal/tools -run 'TestWebSearchRunWithSandbox|TestWebFetchRunWithSandbox|TestRegistryRoutesWebFetchThroughSandboxPath' Tested: GOCACHE=/tmp/zero-go-cache go test ./internal/agent -run 'TestRunPersistentCommandPrefixStillPromptsForNetwork|TestRunApprovedNetworkBashPromptAppliesTurnNetworkGrant' Tested: GOCACHE=/tmp/zero-go-cache go test ./... Tested: git diff --check * Prompt for outside-workspace file access Convert recoverable outside-workspace file path violations into permission prompts instead of hard-denying in ask/auto modes. Approved prompts now grant the requested filesystem scope through the existing request_permissions overlay for the current turn or session, so the follow-up sandbox evaluation and scoped file tools use the same policy path. Keep unsafe mode, apply_patch escapes, symlink traversal, and non-recoverable path cases hard-denied. Tested: GOCACHE=/tmp/zero-go-cache go test ./internal/sandbox -run 'TestEngineAutoAllowsWorkspaceFileMutationTools|TestEngineDeniesOutOfWorkspacePaths|TestGrantRequestPermissionsReadDoesNotGrantWrite|TestGrantRequestPermissionsSessionPersists' Tested: GOCACHE=/tmp/zero-go-cache go test ./internal/agent -run 'TestRunPromptsAndAllowsOutsideWorkspaceWrite|TestRunSessionAllowsLaterOutsideWorkspaceWrite|TestRunAppliesSandboxEvenInUnsafeMode' Tested: GOCACHE=/tmp/zero-go-cache go test ./internal/tools -run 'TestRegistryAppliesSandboxBeforeToolExecution|TestRegistrySandboxGatesPathAliasKeys|TestRegistryAllowsPromptToolWithPersistentSandboxGrant' Tested: GOCACHE=/tmp/zero-go-cache go test ./internal/cli -run 'TestRunSandboxCheckJSONDeniesOutOfWorkspaceWrite' Tested: GOCACHE=/tmp/zero-go-cache go test ./... Tested: git diff --check * Fix Windows network prompt test fixture Use a Windows curl.cmd shim and cmd.exe PATH syntax for TestRunApprovedNetworkBashPromptAppliesTurnNetworkGrant while keeping the POSIX fake curl fixture for Linux and macOS. This keeps the test focused on network prompt approval and turn network grants instead of relying on a POSIX shell script being executable on Windows. Tested: GOCACHE=/tmp/zero-go-cache go test ./internal/agent -run 'TestRunApprovedNetworkBashPromptAppliesTurnNetworkGrant|TestRunPersistentCommandPrefixStillPromptsForNetwork' Tested: GOCACHE=/tmp/zero-go-cache go test ./internal/sandbox -run 'TestClassifyASTCatchesNetworkProgramsRegexMisses|TestClassifyFlagsPipedInstallerVariants' Tested: GOCACHE=/tmp/zero-go-cache go test ./... Tested: git diff --check * Remove sandbox autonomy ceilings Sandbox permission decisions now match grants by tool and scope only, without MaxAutonomy or request autonomy checks. Persistent/session grants, permission approvals, workspace-write auto-allow, and native-sandbox shell auto-allow no longer route through an autonomy ceiling. Remove the sandbox.maxAutonomy config and CLI surfaces, including grant --auto, policy output, sandbox check autonomy input, and sandbox grant snapshots. MCP permission autonomy is intentionally unchanged because it is a separate MCP permission model. Tested: GOCACHE=/tmp/zero-go-cache go test ./internal/sandbox ./internal/agent ./internal/tools ./internal/zerocommands ./internal/config ./internal/cli ./internal/tui Tested: GOCACHE=/tmp/zero-go-cache go test ./... * Fail closed without native sandbox Remove AllowPolicyOnlyRunner from sandbox policy and snapshots. A restricted/managed command plan now errors when native sandbox support is unavailable instead of running through a policy-only direct runner. Policy-only backend data remains as diagnostics for capability/reporting paths, but it no longer authorizes command execution when a platform sandbox is required. Tested: GOCACHE=/tmp/zero-go-cache go test ./internal/sandbox ./internal/zerocommands ./internal/cli ./internal/tui Tested: GOCACHE=/tmp/zero-go-cache go test ./internal/agent ./internal/tools Tested: GOCACHE=/tmp/zero-go-cache go test ./... * Remove scoped shell network policy Drop the domain-scoped shell network mode and the local scoped-egress proxy path from the active sandbox model. Shell network policy now serializes and evaluates only deny or allow. Request-permissions network grants widen to allow without domain lists, and platform profiles consume the binary mode directly. The Linux helper no longer accepts proxy-route flags, Windows network hashes only the binary mode, and web tool tests assert they remain separate from shell network policy. Tested: GOCACHE=/tmp/zero-go-cache go test ./internal/sandbox ./internal/tools ./internal/notify Tested: GOCACHE=/tmp/zero-go-cache go test ./... * Align permission grant ordering and prompt text Move persistent and session grant matching ahead of recoverable sandbox prompts while keeping explicit denies and non-recoverable path violations fail-closed. Clean TUI permission transcript/card text so normal prompts show action, reason, scope, and readable block details instead of raw permission/risk/violation key-value metadata. Tested: GOCACHE=/tmp/zero-go-cache go test ./internal/sandbox ./internal/tui ./internal/agent ./internal/tools Tested: GOCACHE=/tmp/zero-go-cache go test ./... * Remove policy-only sandbox terminology Replace the unavailable native-backend diagnostic path with explicit unavailable support/backend states, and stop presenting missing native isolation as a policy-only fallback. Rename structured sandbox denial metadata from violation to block across permission events, stream-json, snapshots, TUI rendering, and sandbox-check output so user-facing flow matches blocked action language. Update README, work split docs, smoke test selectors, and Windows sandbox policy golden output for the new backend/support names and block payloads. Tested: GOCACHE=/tmp/zero-go-cache go test ./internal/sandbox ./internal/agent ./internal/tools ./internal/tui ./internal/cli ./internal/doctor ./internal/zerocommands ./internal/streamjson Tested: GOCACHE=/tmp/zero-go-cache go test ./... Tested: scripts/sandbox-smoke.sh Tested: git diff --check * Fix sandbox review follow-ups Fail closed for unknown network modes, keep network prompts ahead of bash allow grants, preserve v1 grant-file reads, and classify unparseable commands with obvious network programs as network-risk. Bump stream-json schema to v2 and document the block metadata field after the violation-to-block rename. Tests: GOCACHE=/tmp/zero-go-cache go test ./internal/sandbox ./internal/streamjson ./internal/specialist ./internal/cli -run 'TestExec.*Stream|TestStreamJSON|TestExecProtocol|TestExecReadsStreamJSONImages|TestExecAcceptsImageOnlyStreamJSONMessage|TestExecInputFormatStreamJSON' Tests: GOCACHE=/tmp/zero-go-cache go test ./... Tests: scripts/sandbox-smoke.sh Tests: git diff --check |
||
|
|
a3f62f093b |
streamjson: stop over-redacting prose in secret scrubbing
The sk- and bearer patterns were unanchored, so "sk-" inside "task-list" and the word after a bare "bearer" were replaced with [REDACTED], corrupting legitimate output. Anchor sk- on a word boundary and require a credential-length body for both sk- and bearer tokens; real keys/tokens are still redacted. |
||
|
|
68facda077 |
Image (multimodal) input: exec --image, stream-json images, TUI /image across all 3 providers (#143)
* zeroruntime: add ImageBlock type and NormalizeImageMediaType * zeroruntime: add optional Images field to Message * zeroruntime: add SeedMessagesWithImages, delegate SeedMessages with nil * Emit Anthropic image source blocks for user image turns * Add inlineData part type to Gemini request schema * Serialize user image attachments as Gemini inlineData parts * test(openai): pin text-only chat request serialization before content refactor * feat(openai): allow structured multimodal content parts in chat request * feat(openai): map image attachments to image_url content parts * test(openai): assert image content parts serialize over the request body * modelregistry: add SupportsVision capability gate * Add shared image-file loader package * cli: parse repeatable exec --image flag into imagePaths * cli: resolve exec image attachments via shared loader with sniff and size cap * agent: thread image attachments through Options into the seeded user turn * cli: resolve and vision-gate exec image attachments into the agent run * cli: document exec --image flag in help output * streamjson: add InputImage type and InputEvent.Images field * streamjson: whitelist images field on message events only * streamjson: allow empty content on message events that carry images * streamjson: add ResolveImages to decode, normalize and cap input images * streamjson: cover image parse-and-resolve round-trip and text-only invariance * Add /image command definition to TUI * Add synchronous vision check for TUI model * Implement /image attach, clear, and non-vision refusal in TUI * Render pending image chips above the input in both skins * Thread pending images into the agent turn and clear on submit * Wire stream-json images through to the agent run Stream-json message images were parsed and validated but never reached agent.Options.Images: streamjson.ResolveImages had no production caller, so images sent over stream-json input were silently dropped. resolveExecPrompt now also returns the resolved stream-json images (nil for text input and for image-free stream-json input). The exec runner merges them with --image attachments before the vision gate, so both input sources flow through the same drop+warn and the same agent.Options.Images wiring. Adds an exec-level end-to-end test that feeds a base64 image on a stream-json message event via stdin on a vision model and asserts the image reaches the agent run (the provider request's user turn). * Re-check TUI vision support at submit, not only at /image attach A user could attach an image on a vision model and then switch to a non-vision model via /model before submitting; the images were threaded unconditionally into the agent turn, reaching a model that rejects them. The commandPrompt submit path now re-runs the vision check against the current effective model. When the active model can't accept images, the pending images are dropped (not threaded) and an inline notice mirroring the headless drop+warn wording is appended. Pending image state is still cleared after submit either way. Adds a test that attaches on a vision model, switches the model id to a non-vision one, submits, and asserts the run received no images, an inline notice was appended, and pending state was cleared. * Bound memory with an os.Stat size pre-check in imageinput.LoadFile LoadFile read the whole file into memory before checking the size cap, so a multi-gigabyte file allocated a huge buffer only to be discarded. Add an os.Stat size pre-check before os.ReadFile: a file whose size exceeds MaxImageBytes is rejected with the same 10 MiB-limit error before any read; a missing file surfaces the same not-found error. The existing post-read len(data) check is kept as a TOCTOU backstop in case the file grows between Stat and ReadFile. * OpenAI: only the user role emits image content-parts The Anthropic and Gemini providers only attach images in their user branches, but OpenAI funnels every role through a single mapMessage, which would emit image content-parts for any role carrying Images. Guard the content-parts path to the user role: a non-user message that happens to carry Images keeps the plain string/nil content path. Pins the invariant with TestMapMessageNonUserRolesNeverCarryImages, asserting assistant/tool/system messages with Images set still serialize plain content (no content-parts array). * Deep-copy image buffers so attachments are never aliased Add a shared CloneImageBlocks helper in zeroruntime that deep-copies a slice of ImageBlock including each Data byte slice (returning nil for nil/empty input). Use it in SeedMessagesWithImages so a seeded user turn owns an independent copy of the caller's image bytes, and in the agent loop's copyMessages so image bytes are deep-copied alongside ToolCalls instead of staying aliased across history/request/result copies. Tests assert that mutating the caller's original Data bytes after seeding leaves the seeded message unchanged, and that copyMessages produces independent image bytes. * Accept image-only stream-json turns and bound base64 image size Resolve stream-json images before the prompt in the exec input path and tolerate an empty prompt when images are present, so an image-only message event (empty content + one image) proceeds with prompt="" and the image reaches the agent run instead of being rejected. A turn carrying neither text nor images still errors. In ResolveImages, reject an oversized payload from its ENCODED length (DecodedLen) BEFORE the base64 decode so a huge blob never allocates a decode buffer just to be capped afterward; the post-decode length check stays as a backstop. Tests cover the image-only exec turn reaching the agent and the pre-decode oversize rejection (asserting the size gate fires before any decode). * Bound the image read in imageinput.LoadFile with a LimitReader Replace os.ReadFile with os.Open + io.ReadAll over an io.LimitReader(f, MaxImageBytes+1). The os.Stat pre-check is only a fast-path hint (a non-regular file reports a misleading size and the file can grow between stat and read); the LimitReader is the real bound, so at most one byte past the cap is ever buffered and an oversized or unbounded source can never allocate a multi-gigabyte buffer. The file is closed via defer and the existing size message is reused. * Fix RenderChat frame-height off-by-one with image chips cmdRegion emits TWO rows when ImageChips is set (a chip row above the input line), but the body/overlay height accounting assumed a one-row command region, overflowing the fixed frame by one line. Compute the fixed-row count from the actual command-region height (1 or 2 rows) so the composed frame stays exactly Height rows in both cases. A RenderChat test asserts the rendered frame line-count equals the requested height both with and without ImageChips set. * Reject an empty inline --image= value Route the inline --image= form through requiredInlineFlagValue, the same empty-rejection the other inline flags use, so --image= errors with "--image requires a value" instead of appending an empty image path. A parse test covers the empty inline value. * imageinput: reject non-regular files (FIFO/dir) before opening --------- Co-authored-by: KRATOS <[email protected]> Co-authored-by: Gnanam <[email protected]> |
||
|
|
07d8ffc524 |
CLI wiring: skills/zeroline commands, --mode presets, exec checkpoints, sandbox --effective, sessions rewind (#128)
* CLI wiring: skills/zeroline commands, --mode presets, exec checkpoints, sandbox --effective, sessions rewind Final module of the runtime-core split. Wires the new runtime features into the cli, PRESERVING main's merged specialist cli (the source branch predates specialist and drops it; this keeps it via a 3-way merge from the common base, adding the reskin features as ours/theirs-only changes). - skills command (internal/cli/skills.go) listing internal/skills; zeroline-skin TUI launcher (internal/cli/zeroline.go) via runInteractiveTUIWithSkin. - exec: --mode presets (smart/deep/fast/large/precise) via applyExecMode; model-registry alias resolution + deprecation/effort notices; ContextWindow sizing (modelContextWindow); before-mutation checkpoint recording in OnToolCall; enhanced tool-result output (ChangedFiles/Redacted/Display); permission-mode validation fix. - sandbox policy --effective (resolved guards); sessions rewind (executes the rewind plan); interactive TUI defaults to Ask mode (advertises write/edit/bash + gates via prompts). - internal/streamjson: EventCheckpoint/EventRestore + CheckpointInfo for structured checkpoint output. Specialist cli preserved (specialist.go + flags + runtime + tests all intact). build/vet/-race/full-suite + GOOS=windows build green; no new deps. * Address #128 review: make sessions rewind reachable + honor --exclude-target, mode/notice/redaction fixes - sessions: add "rewind" to the parser whitelist (isSessionsCommand) — it was wired in dispatch + help but parseSessionsArgs rejected it as 'unknown sessions command', so it was unreachable. Regression test TestRunSessionsRewindIsReachableAndHonorsExcludeTarget. - sessions rewind: honor --exclude-target — ApplyRewind keeps THROUGH a sequence, so when KeepTarget is false apply through TargetSequence-1, matching rewind-plan (previously rewind always applied TO the target, disagreeing with the plan). The test asserts --exclude-target keeps fewer events than the default. - sessions rewind: redact the session id in the success + not-found messages (consistent with every other human-readable path). - exec_parse: reject empty inline --mode= via requiredInlineFlagValue (was a silent no-op running defaults). - exec: notice writes (model-deprecation + reasoning-effort advisories) now treat write failures as exitCrash, consistent with the rest of the command. build/vet/-race/full-suite + GOOS=windows build green. --------- Co-authored-by: KRATOS <[email protected]> |
||
|
|
52fbb6d9e7 | feat: add runtime permission decisions (#95) | ||
|
|
34ad21a551 |
Add runtime permission and verification event contracts (#82)
* feat: add runtime permission event contract * feat: stream permission events from exec * feat: add runtime command snapshots * feat: add session rewind compaction plans * feat: add verification event contracts * fix: harden runtime contract review gaps * test: assert approved exec stderr contract * fix: address CodeRabbit CHANGES_REQUESTED items for #82 - Make OnSandboxDecision callback async + panic-safe (non-blocking, recovered) in tools/registry.go per CR. - Add explicit regression test for ConfigSnapshot when ResolveRuntimeMetadata errors (no secret leak in Message/BaseURL). - (Many prior items like shapedPayloadPreview for permission/tool events, dual-target conflict test, stderr empty on approved path, Kind/Framework preservation, redactCommand empty slice, etc. were already landed on this branch.) All relevant tests now pass. * fix(agent): make sandbox decision available synchronously on Result for permission events The recent change to invoke OnSandboxDecision asynchronously (to satisfy non-blocking requirement) broke the agent's immediate capture of the decision for building PermissionEvent after registry.RunWithOptions. - Add SandboxDecision *sandbox.Decision to tools.Result (not serialized). - Populate it on all sandbox-involved return paths in registry.RunWithOptions (sync, before/while firing async callback for observers). - In agent executeToolCall, use result.SandboxDecision for buildPermissionEvent (reliable ordering) instead of side-effect capture via the callback. - The async callback is still supported for any external OnSandboxDecision consumers. This fixes the two failing agent tests that were causing the cross-platform 'Smoke' CI jobs to fail on this PR: - TestRunEmitsPermissionEventForPersistentSandboxGrant - TestRunAppliesSandboxEvenInUnsafeMode All go tests now pass. --------- Co-authored-by: KRATOS <[email protected]> |
||
|
|
623c53e324 |
feat: harden sandbox command execution (#79)
* feat: add sandbox command runner * feat: route shell tools through sandbox engine * test: cover sandboxed shell execution |
||
|
|
a710b0e5f5 |
feat: add Go headless protocol sessions (#60)
* feat: add Go headless protocol sessions * test: harden stream-json tool list filtering * fix: resolve stream-json review followups * chore: enable coderabbit review verdicts |