Skip to content

fix(runtime): surface local runtime failures#141

Closed
michiosw wants to merge 2 commits into
mainfrom
feat/runtime-surface-errors
Closed

fix(runtime): surface local runtime failures#141
michiosw wants to merge 2 commits into
mainfrom
feat/runtime-surface-errors

Conversation

@michiosw
Copy link
Copy Markdown
Contributor

@michiosw michiosw commented May 16, 2026

Summary
This cleans up kontext start local runtime handling by surfacing real failures instead of silently ignoring them.

Before this, kontext start and local runtime startup/cleanup ignored several errors (host/cwd/executable lookup, socket removal/close, session end/close). ResultFromEvaluateResult also fell back to allowed when decision was invalid, which is a fail-open bug.

Now there is one stricter path:

  • internal/run/run.go surfaces and logs lifecycle failures.
  • internal/localruntime/service.go fail-fast on unexpected socket cleanup failures.
  • internal/localruntime/conversions.go denies on invalid decision or decision/allowed mismatch (explicit reason).
  • internal/guard/judge/llama_server_test.go makes the early-exit timing assertion stable under -race.

Why
This gives kontext-cli a cleaner maintenance path for local runtime correctness:

kontext start
-> localruntime service (socket)
-> runtimecore session lifecycle
-> hook decision conversion
-> explicit failure surfaced

This PR does not broaden behavior beyond the cleanup scope.

What changed
Removed silent fallbacks in local runtime conversions
Surfaced ignored errors in kontext start runtime lifecycle
Made local runtime socket cleanup strict
Stabilized judge early-exit timing under race

Verification
go test ./...
go vet ./...
go test -race ./...

Copy link
Copy Markdown
Contributor Author

This stack of pull requests is managed by Graphite. Learn more about stacking.

@greptile-apps
Copy link
Copy Markdown

greptile-apps Bot commented May 16, 2026

Greptile Summary

This PR surfaces more local runtime and session cleanup failures. The main changes are:

  • Stricter local runtime result validation for invalid or mismatched decisions.
  • Logged cleanup failures for sockets, session directories, runtime sessions, and signal forwarding.
  • Fatal handling for unresolved kontext executable paths before settings generation.
  • User-facing reporting when managed session teardown fails.

Confidence Score: 3/5

This should be fixed before merging.

  • Legacy local runtime responses that omit decision can now be denied.
  • Managed session teardown failures can print unredacted error text to stderr.
  • The remaining cleanup and diagnostic changes are mostly contained.

Focus on internal/localruntime/conversions.go and internal/run/run.go.

Security Review

  • Credential exposure: internal/run/run.go prints raw EndSession errors to stderr without redaction, which can expose token-shaped transport or backend error details.

Important Files Changed

Filename Overview
internal/localruntime/conversions.go Tightens local runtime result conversion, but breaks legacy allowed-only responses.
internal/run/run.go Surfaces more runtime and cleanup errors, including one unredacted user-facing teardown error.

Reviews (1): Last reviewed commit: "fix(runtime): surface local runtime fail..." | Re-trigger Greptile

Comment on lines 103 to +108
decision, ok := hook.NormalizeDecision(result.Decision)
if !ok {
decision = resultFromBool(result.Allowed).Decision
return hook.Result{
Decision: hook.DecisionDeny,
Reason: fmt.Sprintf("invalid local runtime decision %q", result.Decision),
}
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P1 Preserve legacy allowed fallback

EvaluateResult.Decision is still omitempty on the wire, and both the CLI hook path and local runtime client pass socket responses through this converter. When an older or hand-written local runtime sends a valid legacy response like {"allowed":true} without decision, this branch now returns a deny instead of preserving the previous allow behavior. That can block operations after only the client side is upgraded.

Comment thread internal/run/run.go
Comment on lines +311 to +314
if err := client.EndSession(endCtx, sessionID); err != nil {
fmt.Fprintf(out, "\n! Failed to end session (%s): %v\n", truncateID(sessionID), err)
return
}
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P1 security Redact teardown errors

This prints the raw EndSession error directly to stderr, while diagnostic logging goes through the redactor. If the backend or transport error includes a request URL, authorization detail, cookie, or token-shaped parameter, teardown failures can leak that value into terminal or CI logs even when verbose diagnostics are off.

Suggested change
if err := client.EndSession(endCtx, sessionID); err != nil {
fmt.Fprintf(out, "\n! Failed to end session (%s): %v\n", truncateID(sessionID), err)
return
}
if err := client.EndSession(endCtx, sessionID); err != nil {
fmt.Fprintf(out, "\n! Failed to end session (%s): %s\n", truncateID(sessionID), diagnostic.Redact(err.Error()))
return
}

@michiosw michiosw closed this May 17, 2026
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