Commit Graph

35 Commits

Author SHA1 Message Date
Peter Steinberger 341551937e fix(agents): preserve empty CLI subagent completions (#126379)
* fix(agents): preserve empty CLI subagent completions

* chore(qa): remove retired Matrix coverage leaf

* refactor: consolidate shared runtime ownership

* fix(scripts): keep runtime build coercion dependency-light

* chore: remove release-owned changelog entry
2026-08-19 11:30:43 -07:00
Peter Steinberger c2b61a40be perf(test): fake audit contention retry clock (#126213) 2026-08-19 00:51:59 -07:00
Peter Steinberger 5564671c4f fix(gateway): bound audit and Codex backlogs (#126154)
* fix(gateway): bound audit and Codex backlogs

Live Gateway SQLite lock failures and process heap pressure exposed two
independent queue owners. Route best-effort audit persistence through the
canonical shared-state connection with bounded contention retries, and remove
the per-notification Codex yield so the keyed turn queue can drain directly.

Follow-up to #126033 and #126073.

* fix(gateway): annotate raw SQLite cold-open probe

* test(codex): register notification burst shard
2026-08-18 21:44:09 -07:00
Josh Lehman 9204ab8dc4 fix(skills): restrict workshop mutations to workshop-owned skills and record reconcile outcomes (#125666)
Skill Workshop could autonomously rewrite or delete handwritten skills and discarded its own drop rationale. Workshop mutations are now gated on ledger-derived ownership (applied create proposals; unknown provenance fails closed to user-owned read-only), ownership claims end at drop and return on restore with failure-safe ordering, legacy backups stay restorable, every reconcile outcome persists with drop reasons in an additive table, and a bounded skill_workshop history action exposes them. Adopt/disown opt-in: #125711.

Co-authored with @jalehman (original ownership design).

Fixes #125652
2026-08-18 15:10:41 +05:30
Peter Steinberger 475d20a034 fix(ui): stop the model picker from nagging about refresh failures (#125661)
* fix(ui): stop the model picker from nagging about refresh failures

A failed background catalog refresh rendered a "Couldn't refresh models"
banner plus a Retry button on top of a complete, working model list, and
replaced the composer trigger's model name with that error text. The
picker already keeps the last-known catalog and re-requests it on every
open, so the operator was being asked to press a button for something the
UI does by itself.

The error stays recorded on the host — it is what drops the stale
availability gate so the composer remains usable — but it is no longer
surfaced while there are models to show. Only a genuinely empty catalog
still says "Models unavailable". The new-session picker gains the chat
picker's open-triggers-revalidate behavior so re-opening it is the retry
there too, instead of dead-ending until a page reload.

Two adjacent simplifications in the same surface:

- Model rows reserve their provider-icon slot as an invisible stem, so
  names line up with the provider heading label (same 34px stem grouped
  and filtered, nothing shifts while typing).
- The "Using agent default" footer is gone: the default row already
  carries a DEFAULT badge and the checkmark. Typing "default" in the
  picker search now matches the default model instead.

Proof: scripts/capture-model-picker-proof.mts captures the open picker
against a mocked gateway; alignment delta 0px (was -24px), search
"default" matches the default row (was nothing), and a failed models.list
leaves no catalog-state element with all rows intact.

* fix(ci): register the model-picker proof script and await its picker revalidation

The unused-file scan needs every scripts/ entry point referenced, like the
sibling ui:proof:* recipes. The catalog-reconnect assertion also has to wait
for the picker's own metadata request instead of reading the log the moment
the rows render.

* test(ui): split model-catalog scenarios out of the new-session e2e file

The catalog-reconnect file hit the 1000-line cap. Its model-catalog metadata
failure/recovery pair is a separate surface from CLI-agent targets, terminal
start, and draft reconnect, so it moves to its own file rather than earning a
max-lines suppression.

* test(audit): give the pinned-reader contract test a realistic timeout

It adds a pinned-SHA git worktree and cold-compiles the audit and state
modules under tsx, which takes minutes on a contended runner. The 120s
default made it fail by construction; it timed out on an unrelated PR shard
while passing locally at ~55s.
2026-08-18 00:58:19 -07:00
Josh Avant 916aca13f3 feat: record subagent execution lineage (#122015)
* feat(audit): record subagent execution lineage

* fix(audit): type-check spawn lineage validation

* docs: preserve spawned-run lineage invariants

* fix(audit): preserve lineage for worker spawns

* fix(audit): bind worker lineage to live authority

* fix(audit): keep lineage carrier private

* fix(sessions): preserve ACP participant recording

* fix(audit): keep lineage out of runtime bearer

* fix(audit): keep lineage type private

* test(audit): match current worker claim shape

* test(audit): preserve readonly lineage result

* fix(audit): redeem spawn lineage privately

* fix(audit): preserve lineage redemption on copy

* test(audit): prove nested worker spawn lineage

* fix(audit): restore execution identity CI gates
2026-08-17 21:41:30 -07:00
Josh Avant f7a8638282 feat(audit): explain outbound message delivery (#123709)
* feat(audit): explain outbound message delivery

* fix(audit): record early message policy denials

* refactor(audit): split message delivery readers

* test(outbound): cover delivery audit lifecycle

* fix(audit): preserve message progress across downgrade

* fix(audit): keep progress out of activity protocol

* docs(audit): keep activity outcomes terminal-only

* fix(audit): bound merged delivery paging

* fix(audit): trust decision channel references

* fix(audit): keep retention constant private

* fix(audit): record broadcast target denials

* fix(audit): distinguish broadcast denial receipts

* test(qa): enforce message delivery receipt proof

* fix(audit): integrate C04 with schema v9 owners

* chore(audit): satisfy assertion safety gate

* refactor(agents): split explicit message target guard

* test(audit): materialize pinned reader in shallow CI

* test(qa): poll terminal audit persistence

* fix(delivery): defer audit terminal to recovery

* test(qa): isolate message delivery restart proof

* test(qa): keep gateway restart config canonical

* test(qa): exclude unrelated restart plugins

* test(qa): remove unused restart plugins

* test(qa): disable automatic memory plugin

* test(qa): converge replacement gateway startup

* fix(plugins): stabilize registry fingerprints

* fix(plugins): use public normalization export

* test(plugins): keep fingerprint fixture immutable

* fix(audit): bind delivery receipts to exact executions

* chore(audit): keep terminal binding helper private

* test(reply): cover unbound admission callbacks

* docs(agents): preserve durable delivery ownership
2026-08-16 21:26:27 -07:00
Peter Steinberger 46f5951d53 fix(audit): reject filter combinations that cannot match (#124513) 2026-08-16 02:09:23 -07:00
Jesse Merhi ed447135bd Prevent auxiliary owners from resetting shared WAL (#123777) 2026-08-15 12:34:24 +10:00
Josh Avant 97a53a9b35 feat: audit admitted channel participant identity (#122863)
* feat: audit admitted channel participant identity

* fix: preserve Telegram identity through thread recovery

* fix: signal held gateway process groups

* fix: keep audit evidence passive in collect routing

* fix: validate copied channel participant evidence

* fix: bind channel participant evidence to host ingress

* fix: honor Telegram proof credential roles

* fix: restart held Telegram proof through gateway

* fix: repair channel identity CI regressions

* test(matrix): bind thread routing owner

* fix: preserve direct DM SDK compatibility

* fix: bind channel provenance at host runtime

* test(feishu): provide channel context builder

* fix: defer record-bound channel runtime resolution

* fix: keep channel admission evidence core-private

* fix(audit): bind channel admission to plugin lifecycle

* fix(audit): bind ingress provenance to final context

* refactor(audit): split admission scope keys

* test(queue): cover combined metadata carriers

* refactor(audit): keep lifecycle helpers private

* fix(queue): preserve combined turn authority

* test(channels): provide ingress context builders

* test(channels): align integrated CI fixtures

* test(clickclack): resolve model-loop ingress

* docs: preserve channel participant evidence invariant
2026-08-14 08:57:01 -05:00
Peter Steinberger 44dd983c0c feat(mac): add canonical elevation host workflow (#123569)
* feat(mac): add canonical elevation host workflow

* fix(mac): clarify elevation host deployment

* test(ui): stabilize cloud startup effort flow

* fix(mac): fail closed on unknown TCC status

* test: synchronize async CI boundaries

* test: remove remaining CI timing races
2026-08-14 05:39:24 -07:00
Josh Avant 1b36f42653 fix(audit): preserve numeric decision cursors (#122619) 2026-08-12 13:08:25 -05:00
Josh Avant 562391b9af feat(audit): explain denied operator approvals (#119815)
* Audit: add durable decision receipts

* Audit: route generic decision facts through writer

* Audit: satisfy strict decision count typing

* Test: align decision writer type coverage

* Refactor: isolate decision receipt projection

* Fix: preserve ambiguous approval correlation

* Fix decision coverage across pages

* Fix approval coverage across corrupt pages

* Fix decision summaries across retention and paging

* Remove superseded decision fact count path

* Keep session-derived approval links conservative

* Test decision paging at owner boundary

* Audit: bind approval receipts to exact execution

* Test: keep decision receipt coverage focused

* docs(agents): preserve decision receipt ownership

* Docs: refresh Plugin SDK split baselines

* Docs: require opt-in for future decision facts

* Fix: bound decision receipt inspection
2026-08-12 05:23:29 -05:00
Josh Avant 35d764076e fix(audit): ignore inherited execution identity evidence (#122418)
* fix(audit): require owned admission data

* docs(agents): preserve owned admission invariant
2026-08-11 23:19:17 -05:00
joshavant 4ccf7d0dfa fix(audit): validate raw invoker evidence 2026-08-11 21:52:21 -05:00
joshavant 2d9f64f872 fix(audit): preserve unknown invoker evidence 2026-08-11 21:52:21 -05:00
Peter Steinberger b529217878 test(audit): consolidate worker lifecycle coverage (#122369)
Co-authored-by: Amp <amp@ampcode.com>
2026-08-11 18:51:12 -07:00
Peter Steinberger cad77fb39c refactor: consolidate remaining coercion helpers (#122020) 2026-08-11 10:22:01 -07:00
Peter Steinberger fa9626c4e1 refactor(steering): make active-run admission exact and atomic (#120285)
* refactor(steering): make admission exact and atomic

* fix(steering): bind targets by run identity

* fix(steering): inject before reply dispatch

* fix(steering): preserve backend injection modes

* fix(steering): target session suggestions

* fix(steering): preserve sibling delivery contracts

* style(steering): satisfy exact-head lint

* fix(steering): preserve targetless protocol compatibility

* fix(steering): preserve exact targets through replies
2026-08-07 16:58:04 -07:00
joshavant 621efa4f5f fix(audit): require explicit activity provenance 2026-08-07 18:40:17 -05:00
joshavant d4c9a4d8f1 Revert "feat(audit): preserve exact agent execution provenance"
This reverts commit 79b8775bc9.
2026-08-07 18:40:17 -05:00
joshavant 9dc4a358d3 Revert "fix(audit): keep source adoption schema first-use"
This reverts commit 4244630ccf.
2026-08-07 18:40:17 -05:00
Vincent Koc 4244630ccf fix(audit): keep source adoption schema first-use 2026-08-07 15:27:14 +08:00
Vincent Koc 79b8775bc9 feat(audit): preserve exact agent execution provenance 2026-08-07 15:27:14 +08:00
Josh Avant 618fba92bf feat(audit): add execution identity inspection (#117034)
* feat(audit): add opt-in execution identity inspection

* fix(audit): gate recovery identity retention

* fix(audit): keep recovery identity type private

* test(audit): type internal recovery fixture

* test(audit): split recovery identity coverage

* docs(audit): define operator read trust boundary

* test(qa): register identity scenario child

* fix(audit): enforce shared identity retention bounds

* fix(audit): seal public ingress identity boundary

* fix(audit): keep ingress guard lint-clean

* fix(gateway): preserve advertised method order

* chore(protocol): sync advertised method order

* fix(protocol): encode audit selector invariants

* test(audit): prove exact execution guard

* fix(audit): keep identity storage lazy
2026-08-04 20:05:15 -05:00
Peter Steinberger d347cd1097 refactor: canonicalize cache mechanics (#118262)
* refactor: adopt shared map pruning

* refactor: share config-scoped ttl cache

* refactor: share backup link cache

* refactor: centralize native relay retention cap

* chore: remove obsolete bundled channel lint suppression

* chore: shrink max-lines baseline

* refactor: remove cache pruning wrappers
2026-08-02 19:33:13 -07:00
Peter Steinberger 3a555d5956 refactor(agents): centralize terminal lifecycle outcomes (#118254)
* refactor(agents): centralize terminal lifecycle outcomes

* fix(agents): preserve terminal projection contracts

* refactor(agents): split terminal error boundary

* test(gateway): align stale lifecycle projection
2026-08-02 19:17:30 -07:00
Peter Steinberger 357087b9c7 refactor(gateway): lifecycle-owned ambient state via factory-registered drains (#118271)
* refactor(runtime): own ambient state lifecycle cleanup

* chore(plugin-sdk): refresh additive API baseline

* fix(runtime): restore agent wait listener lifecycle

Keep agent-job data process-shared while preserving module-local event subscription ownership. Ratchet the public wildcard budget down after replacing text-runtime's wildcard singleton export with named exports.
2026-08-02 18:06:46 -07:00
Peter Steinberger edecdbd05e refactor(config): config-surface reduction tranche 3 — product consolidations (review request) (#111527)
* refactor(config): consolidate media model lists

* refactor(config): unify memory configuration

* refactor(config): consolidate TTS ownership

* refactor(config): move typing policy to agents

* refactor(config): retire product-level config surfaces

* refactor(config): share scoped tool policy type

* chore(config): refresh generated baselines

* fix(config): honor agent typing overrides

* fix(config): migrate sibling config consumers

* refactor(infra): keep base64url decoder private

* fix(config): strip invalid legacy TTS values

* chore(config): refresh rebased baseline hash

* fix(doctor): route legacy messages.tts.realtime voice to talk during tts move

* refactor(config): polish final layout names

* refactor(config): freeze retired tuning defaults

* feat(config): add fast mode default symmetry

* refactor(config): key agent entries by id

* docs(config): update final layout reference

* test(config): cover final layout migrations

* chore(config): refresh final layout baselines

* fix(config): align final layout runtime readers

* fix(config): align remaining readers

* fix(config): stabilize final layout migrations

* fix(config): finalize config projection proof

* fix(config): address final layout review

* docs(release): preserve historical config names

* fix(config): complete keyed agent migration

* fix(config): close final migration gaps

* fix(config): finish full-branch review

* fix(config): complete runtime secret detection

* fix(config): close final review findings

* fix(config): finish canonical docs and heartbeat migration

* fix(config): integrate latest main after rebase

* refactor(env): isolate test-only controls

* refactor(env): isolate build and development controls

* refactor(env): collapse process identity indirection

* refactor(env): remove duplicate config and temp aliases

* docs(env): define the operator-facing allowlist

* ci(env): ratchet production variable count

* fix(env): remove stale provider helper import

* fix(env): make ratchet sorting explicit

* test(env): keep test seam in dead-code audit

* test(env): cover ratchet growth and boundary; document surface budgets

* docs(config): document tier-eval consolidations

* docs(config): clarify speech preference ownership

* test(memory): align retired tuning fixtures

* refactor(memory): freeze engine heuristics

* refactor(config): apply tier-eval tranche

* refactor(tts): move persona shaping to providers

* refactor(compaction): move prompt policy to providers

* test(config): align hookified prompt fixtures

* chore(deadcode): classify test-only exports

* chore(github): remove unused spawn helper

* chore(deadcode): classify queue diagnostics

* chore(deadcode): remove unused lane snapshot export

* chore(plugin-sdk): ratchet consolidated surface

* fix(config): integrate latest main after rebase
2026-07-21 20:28:43 -07:00
Peter Steinberger 658fdaea5b refactor(audit): remove internal test exports (#108111)
* refactor(audit): remove internal test exports

* chore(deadcode): refresh export baseline
2026-07-15 00:30:16 -07:00
Peter Steinberger 26fe6e8ea3 refactor(audit): trim internal input types (#107390) 2026-07-14 03:43:49 -07:00
Peter Steinberger e2ec8283c4 refactor(deadcode): trim mid-size src exports (#105888)
* refactor(deadcode): trim auto-reply and CLI exports

* refactor(deadcode): trim cron and task exports

* refactor(deadcode): trim fleet and process exports

* test(deadcode): exercise live task and process seams

* test(fleet): cover stream redaction through owner module

* refactor(security): trim dead internal exports

* refactor(secrets): trim dead internal exports

* refactor(deadcode): trim remaining src exports

* refactor(deadcode): remove test-only runtime exports

* refactor(deadcode): trim pairing test exports

* refactor(deadcode): reconcile refreshed baseline

* test(auto-reply): deduplicate queue state imports
2026-07-13 00:42:56 -07:00
Vincent Koc baa9eb4d7b refactor(audit): remove unused recorder reset (#105446) 2026-07-12 16:16:59 +02:00
Peter Steinberger 7a466b33f3 feat: add metadata-only message audit events (#103903)
* feat: add metadata-only message audit events

* chore(protocol): restore generated swift models and config baseline after rebase

* fix(state): gate agent-db ownership check before schema version

* fix(cli): sync audit command description into the root-help catalog

* fix(audit): require destination proof before classifying outbound messages as direct

* refactor(audit): drop dead migration guard and add contract comments

* docs(gateway): add dedicated audit history page and cross-links

* test(e2e): enable direct-mode message audit in the telegram proof SUT config

* test(channels): expect declared conversationKind in durable delivery session context

* fix(audit): record the routing channel id for inbound rows from plugin channels

* fix(audit): match channel-prefixed delivery targets in the destination route gate

* fix(audit): validate explicit target kind against the destination route kind

* fix(audit): use the canonical target-prefix grammar in the destination route gate and fail closed on foreign migration tables

* fix(audit): normalize nested provider and kind target prefixes in the destination gate

* fix(audit): strip registered provider aliases and the direct kind prefix in the destination gate

* chore(docs): refresh config baseline after rebase
2026-07-11 13:14:08 -07:00
Peter Steinberger f53346944d feat: correlate native search outcomes in audit history (#98704)
* feat: correlate native search outcomes in audit history

Metadata-only audit ledger for agent runs and tool actions in the shared
state DB: stable event identity, closed action/status/error vocabularies,
one-way-hashed tool-call ids, never-inferred terminal outcomes for native
web-search (explicit completed/failed only; otherwise unknown), bounded
retention, audit.list gateway RPC and openclaw audit CLI. Squashed from
the 82-commit audit stack for replay onto current main.

* feat(audit): add audit.enabled config gate (default on)

The metadata-only audit ledger records by default: an audit trail enabled
only after an incident cannot explain the incident, and the rows are
strictly less sensitive than the transcripts every install already
stores. audit.enabled=false stops new writes at the gateway subscription
seam; audit.list and openclaw audit keep serving existing records until
they expire. Documented in the configuration reference, protocol page,
and CLI reference.

* fix: repair full-matrix CI findings after rebase

- break the dynamic-tools/dynamic-tool-execution import cycle by
  extracting resolveCodexToolAbortTerminalReason into a leaf module
- restore main's session-worktree protocol exports lost in the
  index.ts auto-merge
- register the audit event writer worker as a knip entry point
- docs table formatting; subagent wait-cancellation test scoped to its
  audit intent (outcome + timing) and advanced past main's new
  lifecycle-timeout retry grace
2026-07-06 12:30:12 +01:00