Commit Graph

2 Commits

Author SHA1 Message Date
kami be08938f1f Thread context through Provider.Execute and stop reporting read failures as unknown
Finding 6 of REVIEW-2026-07-30.md. runWithTimeout could not cancel anything,
because Provider.Execute took no context: the goroutine ran on to the HTTP
client's 60s timeout, outliving the 30s capability timeout. Provider.Execute
now takes a context carrying that timeout, and the workspace provider issues
its tool call with http.NewRequestWithContext, so a timed-out execution
actually tears the request down.

A read-only capability whose provider call times out now resolves to failed
rather than unknown. Spec §4.3 reserves unknown for executions whose side
effect may or may not have landed, and never retries them — which made read
failures both unretryable and indistinguishable from genuinely ambiguous
mutations, for calls that by definition have no side effect. Mutating
capabilities still resolve to unknown.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Uea55zaiWuEByEDC4UBSdd
2026-07-30 23:39:50 +04:00
kami 89d8433d17 Implement Hexis confirmations, disabled-by-default risk, and timeout=>unknown
Closes the biggest gap between the running execution engine and
ECOSYSTEM-SPEC.md §4.3: confirmations were entirely unmodeled, so any
capability could execute unconfirmed regardless of requires_confirmation.

- New confirmations table + Confirmation domain type; POST
  /api/v1/confirmations mints a TTL-bound (120s) confirmation binding
  capability id+version, target entity, and a sorted-key args hash.
- Execute() now requires a valid pending confirmation when the
  capability demands one: rejects missing, expired, consumed, or
  args/version-mismatched confirmations; consumes on success.
- Capabilities gain enabled (destructive risk defaults to disabled,
  matching "must be turned on explicitly") and timeout_seconds.
- One in-flight execution per (capability_id, target_entity_id); a
  second concurrent attempt is rejected (surfaced as 409 over HTTP).
- Wall-clock timeout per capability now wraps the provider call; on
  timeout the outcome is "unknown" (new ExecutionStatus), never
  "failed", and the run is never auto-retried.
- 9 new engine tests cover each guard from the spec's Phase 6 gate.

Vikunja #274.
2026-07-20 00:58:42 +04:00