Commit Graph

7965 Commits

Author SHA1 Message Date
Peter Steinberger d77cc3dd30 chore(release): prepare 2026.8.1-beta.3 2026-08-17 14:50:33 -07:00
Peter Steinberger de9b367214 fix(ui): generic mock chat sends show a visible outcome (#125347)
* fix(ui): make generic mock chat sends observable

* test(ui): stabilize control UI e2e timing
2026-08-17 11:40:56 -07:00
Peter Steinberger 7170a6231a feat(agents): unify agent status into a durable progress_card (#125125)
* feat(agents): unify agent status into a durable progress_card

Replace the write-only update_plan to-do tool and the fragmented plan
rendering with one durable status artifact per session: progress_card
({plan?, markdown?}, replace-on-write, 8 KiB markdown / 50-step caps).
Cards persist in a lazy-additive session_progress_cards table in the
per-agent DB (no schema-version bump), broadcast progressCard.changed,
and render from the store with exactly one live placement per view
(session rail when visible, else the composer-adjacent bar); transcripts
collapse to one-line receipts, and the sidebar hovercard shows other
sessions' cards inline (markdown + <progress>, DOMPurify allowlist, no
iframes). The three stream-derived plan renderers and their dedup
heuristics are deleted.

Codex runs disable the native plan tool per thread
(tools.update_plan.enabled=false) and receive progress_card via the
dynamic-tool bridge; compaction restore now reinjects the card (steps +
bounded markdown). Card writes still emit the legacy plan stream event so
native apps and channels keep working until their per-platform
migrations. Policy names map update_plan -> progress_card; the shipped
tools.updatePlan=false kill switch is honored.

Net -277 production LOC; -480 test LOC.

* test(agents): regenerate Codex prompt snapshots for update_plan thread-config disable

* chore(protocol): allowlist progressCard.changed for native apps pending card migration

* fix(ci): repair progress card integration checks

* fix(codex): canonicalize native progress cards

* test(gateway): reconcile progress card method order

* test(codex): stabilize native approval fixture
2026-08-17 09:44:04 -07:00
Peter Steinberger 70ce8ea6f7 fix(pr): verify hosted commit membership locally (#125335)
One-time maintainer-authorized bootstrap landing for the exact reviewed head. This direct merge replaces the broken self-hosted verifier so subsequent pull requests can return to the native review, prepare, and merge workflow.
2026-08-17 09:41:13 -07:00
Peter Steinberger 49af98c12b fix(macos): avoid codesign metadata SIGPIPE (#125281) 2026-08-17 09:17:47 -07:00
Ayaan Zaidi d90dcc2111 feat(plugin-sdk): export saveMediaSource from media-store (#125278)
Plugins holding a remote URL had no non-deprecated Plugin SDK path to turn it into managed media; saveMediaSource was only reachable through the deprecated media-runtime barrel while docs pointed at media-store. Re-export it from the focused subpath and move the bundled qa-channel plugin off the deprecated barrel. Maintainer decision: full saveMediaSource (local path + HTTP(S)) is the supported media-store contract.

Fixes #125259
2026-08-17 12:54:52 +00:00
Peter Steinberger d919637303 fix(test): prepare standalone survivor plugin registry (#125251)
Amp-Thread-ID: https://ampcode.com/threads/T-01a00f54-65a0-7286-898f-bb550f6485ed

Co-authored-by: Amp <amp@ampcode.com>
2026-08-17 04:39:44 -07:00
Peter Steinberger 076a8cc616 fix(install): avoid unusable checkout directories after failed clones (#124872)
* fix(install): publish fresh git clones transactionally

Amp-Thread-ID: https://ampcode.com/threads/T-01a00ae0-190d-718b-8a76-b75f3e8d1fae

* fix(installer): preserve empty clone destinations transactionally

Amp-Thread-ID: https://ampcode.com/threads/T-01a00ae0-190d-718b-8a76-b75f3e8d1fae

* fix(update): satisfy transactional clone lint

Amp-Thread-ID: https://ampcode.com/threads/T-01a00ae0-190d-718b-8a76-b75f3e8d1fae

* test(update): type recovery directory assertion

* fix(installer): retain canonical clone checkout

Amp-Thread-ID: https://ampcode.com/threads/T-01a00ae0-190d-718b-8a76-b75f3e8d1fae

* fix(update): retain published checkout root

Amp-Thread-ID: https://ampcode.com/threads/T-01a00ae0-190d-718b-8a76-b75f3e8d1fae

* test(update): cover package preflight before clone

Amp-Thread-ID: https://ampcode.com/threads/T-01a00ae0-190d-718b-8a76-b75f3e8d1fae

---------

Co-authored-by: Amp <amp@ampcode.com>
2026-08-17 02:40:07 -07:00
Peter Steinberger 55ce95fac8 feat(sessions): three-layer session ownership — agent attribution, assignable owner, participants (#125057)
* feat(sessions): stamp agent identity on spawned sessions and return spawn receipts

Agent-spawned sessions recorded the requesting session key as createdActor.id,
so the Control UI creator chip rendered an opaque key. Spawn producers now stamp
the canonical requester agent id; parent-authority validation moves to a new
trusted requesterSessionKey field. projectSessionActor enriches agent actors
with configured identity name/avatar at read time, and visible sessions_spawn
returns a sessionUrl + owner receipt with URL-first acknowledgement guidance.

* feat(sessions): assignable session ownership with owner facet and menus

GitHub-assignee-style ownership: sessions get a mutable owner (defaulting to
the immutable createdActor) stored in additive bare-nullable SQLite columns
with first-use lazy ensure. New operator.write sessions.assignOwner validates
targets, requires an identified caller, authorizes by session visibility, and
records assignedBy/assignedAt inside the write transaction. The sessions agent
tool gains assign_owner; the Control UI adds Assign-to-me/Assign-to menus in
sidebar rows and chat headers, renders the effective owner chip, and the
creator facet/filter now keys on effective owner. Sharing authority stays
anchored on createdActor.

* feat(sessions): record session participants and stack them in the owner chip

Records every distinct external prompter (human profile/channel sender, or a
requesting agent) per session in an additive session_participants table at the
turn-admission boundary — best-effort, deferred, never blocking the turn; the
session's own agent and viewers are never recorded, capped at 32 per session.
The session row projects a bounded participants list (owner excluded) plus a
total count with the same actor enrichment as owner/createdActor. The sidebar
chip becomes a pair-stack when others have prompted (owner front, one peeking
participant or +N behind), the chat header shows the full facepile, and an
authenticated involvingMe list filter adds an Involving-me sidebar predicate.
Participant projection is excluded from logical-session CAS equality so display
history never invalidates session writes.

* fix(sessions): identify built-in agent tool callers for owner assignment

The sessions tool's assign_owner dispatched through the in-process synthetic
client, which carries neither a signed agent-runtime identity nor a human
profile, so agent-initiated reassignment always failed with FORBIDDEN. The
tool now captures its trusted requester agent identity and carries it across
in-process dispatch as internal client state (never wire params); the handler
derives assignedBy as signed runtime identity, then trusted agent-tool caller,
then authenticated human. Live-verified end-to-end on a dev gateway.

* fix(ci): split oversized session modules and refresh prompt snapshots

Split the max-lines offenders at concept boundaries for session equality, tool overrides, and protocol owner schemas. Remove the redundant Number conversion from the node:sqlite participant count. Refresh prompt snapshots after drift from the sessions and sessions_spawn tool description updates.

* fix(ci): restore solo-mode chip suppression and conform new method descriptors

Solo-mode root cause: owner-assignment submenu options reused the permanent owner-chip custom element, so hidden menu avatars were counted as attribution chrome. Menus now use viewer avatars while gateway-gated owner chips remain exclusive to collaborative sessions.

Conform sessions.assignOwner to the 2026.8 descriptor and append-only advertised-method inventories, and regenerate the Swift and Kotlin protocol surfaces.

Keep historical v15/v14 fixtures frozen by stripping the new owner columns; the existing range already excludes the participant table. Replace the new raw SQLite schema probes with synchronous Kysely queries.

Clear max-lines by splitting the organizer host contract, pure agent-navigation projections, and ownership/filtering sidebar cases at their concept boundaries.

* fix(ci): integrate ownership series with latest main surfaces

Wire the sessions-page assign-owner action, merge capability imports, narrow the navigation export scope, and apply sessions-create formatting.

The owner-presence regression came from hidden assign-owner menu avatars emitting data-viewer-id, so owner and menu chrome now opt out of presence markers while real facepiles retain them.

* fix(sessions): scope the involving-me filter to profile-backed participants

Session participant history mixed channel-native sender ids with authenticated Gateway profile ids, so involving-me missed real sessions and could accept numeric collisions.

Record the actor_source namespace at each producer, carry it through the internal SQLite projection, and match authenticated viewers only against profile-backed human participants. Legacy NULL sources fail closed for filtering, while channel ids remain available for display.

* build(ui): raise startup budget baseline for session ownership surfaces

Ownership chips, assignment menus, and the participant stack add ~0.7 KiB
gzip to the startup path; CI compression landed just over the previous
baseline+tolerance. Hard cap (350 KiB) unchanged.

* refactor(sessions): drop raw NULL projection for the lazy actor_source column

The Kysely guardrail rejects typed raw sql snippets outside allowlisted
boundaries; select the lazily-ensured column only when present and let the
row projection treat its absence as unknown/legacy.

* build(ui): refresh combined startup baseline
2026-08-17 02:35:20 -07:00
Peter Steinberger fbd910d417 fix(ci): enforce env budget before merge (#125189) 2026-08-17 02:32:57 -07:00
Peter Steinberger b77671ced2 feat(mac): harden Peekaboo elevation cutovers (#124564)
* feat(mac): harden elevation cutovers

* fix(mac): make elevation recovery transactional

* fix(mac): revalidate elevation owner shutdown

* fix(mac): quiesce elevation recovery owners

* fix(mac): close elevation artifact and recovery races

* fix(mac): use signed exclusive app renames

* fix(mac): defer elevation hangup signals

* fix(mac): restore receipts during elevation rollback

* fix(mac): bind elevation receipts to both architectures

* fix(mac): close elevation attestation races

* fix(mac): bind elevation proof to final objects

* fix(mac): keep elevation rollback independently trusted

* fix(mac): validate every rollback generation

* fix(mac): authenticate legacy elevation recovery

* fix(mac): attest recursive Peekaboo sources

* fix(mac): recover when elevation app is unavailable

* fix(mac): preserve raced recovery custody

* test(mac): preserve missing-tool coverage

* test(mac): register recursive gitlink fixture

* fix(mac): authenticate all elevation custody

* fix(mac): bind elevation build and recovery inputs

* fix(mac): persist elevation recovery transactions

* fix(mac): durably publish elevation custody

* fix(mac): complete elevation transaction durability
2026-08-17 02:20:55 -07:00
Ayaan Zaidi 8c6976e1fc fix(agents): report recovered tool retries (#125078)
Preserve attempt-local recovery state so successful mutation retries emit a redacted terminal receipt without stale failure warnings.

Co-authored-by: Ayaan Zaidi <hi@obviy.us>
2026-08-17 14:35:00 +05:30
Peter Steinberger e3d553b734 fix(channels): surface Discord voice failures and preserve Telegram controls (#125152)
* fix(channels): surface degraded Discord and Telegram sends

* fix(telegram): preserve legacy slash callbacks

* fix(ci): correct env-var count after version define removal
2026-08-17 01:56:38 -07:00
Peter Steinberger 5ebfbbf8d7 fix(plugins): honor per-agent runtime config (#124978)
* fix(plugins): resolve per-agent config through SDK

* test(codex): preserve agent runtime exports

* test(telegram): make default owner explicit

* refactor(plugins): use lightweight agent scope runtime

* fix(codex): preserve multi-agent execution ownership

* chore(plugin-sdk): record approved agent scope exports

* fix(codex): keep scoped sandbox ownership authoritative

* fix(codex): preserve agent scope in native side actions

* fix(ci): avoid counting node check as environment variable
2026-08-17 01:53:08 -07:00
Peter Steinberger 23ea04a375 refactor(media): remove orphan runtime facades (#125121) 2026-08-17 00:42:33 -07:00
Peter Steinberger a917c99e92 fix(runtime): classify Node releases consistently across install and launch (#124812)
* fix(runtime): align Node release version guards

Amp-Thread-ID: https://ampcode.com/threads/T-01a00ae0-190d-718b-8a76-b75f3e8d1fae

* test(runtime): include Node version helper in source fixture

* fix(install): align Node release checks across boundaries

Amp-Thread-ID: https://ampcode.com/threads/T-01a00ae0-190d-718b-8a76-b75f3e8d1fae

* fix: keep node version guard legacy-compatible

Amp-Thread-ID: https://ampcode.com/threads/T-01a00ae0-190d-718b-8a76-b75f3e8d1fae

* test(runtime): exercise legacy launcher preflight

* fix(installer): validate installed Node release versions

Amp-Thread-ID: https://ampcode.com/threads/T-01a00ae0-190d-718b-8a76-b75f3e8d1fae

* fix(installer): compare Node version parts numerically

Amp-Thread-ID: https://ampcode.com/threads/T-01a00ae0-190d-718b-8a76-b75f3e8d1fae

* test(installer): cover 17-digit Node major

---------

Co-authored-by: Amp <amp@ampcode.com>
2026-08-17 00:42:23 -07:00
Peter Steinberger f59e945013 feat(gateway): move sessions between Gateway and runners (#125036)
* chore: preserve session placement move work

* feat(gateway): move sessions between runners

* test(gateway): align recovery fixture with move barriers

* fix(protocol): format literal-only Swift initializers

* test(ui): prove session move terminal state

* refactor(gateway): narrow session move target fence

* fix(gateway): preserve pending result recovery ownership

* test(workers): migrate reclaim lifecycle fixtures

* refactor(gateway): keep move internals private

* test(gateway): align split bootstrap fixture with moves

* fix(gateway): recover session moves through exact intent

* refactor(gateway): derive move placement subtypes locally
2026-08-17 00:23:13 -07:00
Peter Steinberger 2a556234c2 fix(install): persist OpenClaw PATH in Unix shells (#124779)
* fix(installer): persist user bin across fresh shells

Amp-Thread-ID: https://ampcode.com/threads/T-01a00ae0-190d-718b-8a76-b75f3e8d1fae

* fix(installer): stop when profile copy fails

Amp-Thread-ID: https://ampcode.com/threads/T-01a00ae0-190d-718b-8a76-b75f3e8d1fae

* fix(install): follow Bash profile precedence

* fix(install): safely update read-only shell profiles

Amp-Thread-ID: https://ampcode.com/threads/T-01a00ae0-190d-718b-8a76-b75f3e8d1fae

* test(installer): isolate login profile proof

Amp-Thread-ID: https://ampcode.com/threads/T-01a00ae0-190d-718b-8a76-b75f3e8d1fae

---------

Co-authored-by: Amp <amp@ampcode.com>
2026-08-17 00:21:11 -07:00
Peter Steinberger 2b2c11e748 fix(install): keep stable channel when npm install retries (#124778)
* fix(installer): keep npm channel target immutable

Amp-Thread-ID: https://ampcode.com/threads/T-01a00ae0-190d-718b-8a76-b75f3e8d1fae

* fix(install): fail after repeated CLI package install errors

Amp-Thread-ID: https://ampcode.com/threads/T-01a00ae0-190d-718b-8a76-b75f3e8d1fae

* fix(installer): verify npm package publication

Amp-Thread-ID: https://ampcode.com/threads/T-01a00ae0-190d-718b-8a76-b75f3e8d1fae

* fix(install): satisfy shellcheck for entry validation

* fix(installer): link the packaged OpenClaw launcher

Amp-Thread-ID: https://ampcode.com/threads/T-01a00ae0-190d-718b-8a76-b75f3e8d1fae

* test(installer): keep retry fixture version-valid

Amp-Thread-ID: https://ampcode.com/threads/T-01a00ae0-190d-718b-8a76-b75f3e8d1fae

---------

Co-authored-by: Amp <amp@ampcode.com>
2026-08-17 00:17:26 -07:00
ClawSweeper 1d65e7b449 test: default trusted checks to local execution (#125120)
Co-authored-by: RoboClaw <309084314+roboclaw-bot@users.noreply.github.com>
2026-08-16 23:45:50 -07:00
Peter Steinberger 4e1f26dc18 refactor(gateway,ui): one bounded display projection; delete marker strip sites (#124997)
* refactor(gateway,ui): one bounded display projection; delete marker strip sites

Persisted transcripts are marker-free since the write-boundary projection
(#124793), the historical migration (#124888), and TTS facts (#124913), so
display surfaces stop compensating. sessions.list.lastMessagePreview and its
siblings (sessions.preview/describe, TUI picker, sessions_list tool, MCP) now
share one bounded role-aware projection (240 chars, tool/system/thinking and
suppressed control replies excluded, directive-only rows fall through). The
web reply chip reads the typed openclawDelivery fact instead of parsing text;
chat.history preserves the field to the UI. Post-hoc display strips are
deleted across web/TUI/MCP/sessions-list; live streaming cleaners stay.
Stale gateway-protocol preview comments corrected; no schema change.
Assertion-safety baseline pruned for shrunk files (sanctioned direction).

Production net -173, tests net -137. Fixes the sidebar [[reply_to_current]]
preview leak and the empty-code-pill overstrip of quoted markers.

* fix(agents): preserve restart recovery transcript reads

* refactor(gateway): remove obsolete transcript exports

* fix(gateway): normalize injected delivery directives

* fix(ci): scope projection and recovery checks

* chore(ci): shrink plugin SDK surface budgets

* test: deflake loaded side question and worker checks

* test: align display projection CI fixtures

* style: format display projection fixture
2026-08-16 23:44:29 -07:00
Peter Steinberger 3010318ba3 fix(android): isolate debug app installs (#125099) 2026-08-16 23:36:57 -07:00
Peter Steinberger 1204225303 chore(scripts): enforce erasable TypeScript syntax (#125104) 2026-08-16 23:31:27 -07:00
Peter Steinberger 2915e563d6 feat(workboard): show full boards on session dashboards (#125094)
* feat(workboard): full-board dashboard widget

Adds a third trusted plugin widget kind, workboard:board, rendering the
complete Kanban board (all columns, live plugin.workboard.changed
refresh) inside a session dashboard. Props {boardId} scope it to one
board; without it the widget shows every board, matching workboard:mini
semantics. Card rendering reuses the workboard page renderColumn with an
explicit surface option so page and widget cannot drift; the shared
board filter moved to ui/src/lib/workboard/board-filter.ts. Mutations
follow the connection's canMutate; read-only connections get a
view-only board.

Proof: pnpm test ui/src/lib/board ui/src/pages/workboard
ui/src/lib/workboard extensions/workboard (9,494 passed), i18n baseline
green, autoreview clean (codex/gpt-5.6-sol). tsgo core/ui/extensions
green locally; remote check:changed blocked by Daytona capacity and the
tsgo:core Daytona exit reproduced locally as a heavy-check lock race,
passing on retry.

* test(ui): seed workboard fixtures in the mocked dev server

* fix(ci): register workboard proof capture script
2026-08-16 23:19:30 -07:00
Patrick Erichsen 9e4ba15f4c improve: detect Claude CLI prompt cache regressions (#124988)
* test(gateway): cover Claude CLI prompt cache reuse

* test(gateway): validate Claude CLI cache across processes

* test(gateway): perturb Claude native cache context

* test(gateway): calibrate Claude CLI cache threshold

* docs(testing): align Claude cache threshold

* test(gateway): preserve config literal types

* test(gateway): split node admission coverage
2026-08-16 21:48:23 -07:00
Peter Steinberger 0d78854415 fix(install): reject invalid PowerShell installer options (#124882)
* fix(install): reject invalid PowerShell installer options

Bind installer parameters strictly so unknown switches and positional arguments cannot enter the mutating installer body. Validate environment options before initialization, add explicit help, and gate website publication on Windows PowerShell 5.1 and pwsh probes.

Amp-Thread-ID: https://ampcode.com/threads/T-01a00ae0-190d-718b-8a76-b75f3e8d1fae

* test(installer): validate strict PowerShell options

Amp-Thread-ID: https://ampcode.com/threads/T-01a00ae0-190d-718b-8a76-b75f3e8d1fae

---------

Co-authored-by: Amp <amp@ampcode.com>
2026-08-16 21:16:40 -07:00
Pavan Kumar Gondhi 6e026c2fe3 fix(gateway): reject unattributable loopback proxy traffic [AI] (#119950)
* fix(gateway): bind auth limits to ingress attribution

* fix(gateway): close remaining ingress auth gaps

* fix(gateway): carry attribution into new ingress paths

* fix(gateway): close ingress ownership gaps

* fix(gateway): complete proxy ingress hardening

* fix(gateway): stabilize managed Tailscale ingress

* fix(gateway): make Tailscale cleanup ownership-safe

Refuse reset-on-exit publication until Tailscale exposes an atomic owner-bound cleanup operation, and migrate legacy configs with Doctor.

* fix(gateway): finish ingress ownership repair

* fix(gateway): own managed Tailscale route lifetime

Run managed Serve and Funnel routes as foreground claims tied to the Gateway lifecycle. Retire named Service config through Doctor because Tailscale Services cannot run in foreground mode.

Co-authored-by: Pavan Kumar Gondhi <pavangondhi@gmail.com>

* fix(gateway): align Tailscale consumers and build guards

Remove the retired named-service config from Telegram Mini App URL resolution and register the lifecycle worker as an explicit production entry.

Co-authored-by: Pavan Kumar Gondhi <pavangondhi@gmail.com>

* fix(gateway): preserve retired Tailscale inputs

Keep Funnel enabled when removing an ignored named-Service setting and accept the legacy positive reset flag as a no-op now that managed routes always follow Gateway lifetime.

Co-authored-by: Pavan Kumar Gondhi <pavangondhi@gmail.com>

* fix(gateway): preserve Tailscale route diagnostics

Prefer the actionable foreground CLI failure captured during timeout cleanup, and cover the original delayed-failure ordering.

Co-authored-by: Pavan Kumar Gondhi <pavangondhi@gmail.com>

* fix(gateway): reconcile Tailscale ingress with main

Preserve current ingress ownership contracts after the rebase, retire the obsolete device-auth migration check, validate route-owner IPC, and move Tailscale auth coverage onto the managed listener.

Co-authored-by: Pavan Kumar Gondhi <pavangondhi@gmail.com>

* fix(gateway): finish ingress rebase coverage

Unify the rebased net imports and let module-reset WebSocket tests prepare attribution through the same fresh module instance as the handler.

Co-authored-by: Pavan Kumar Gondhi <pavangondhi@gmail.com>

* test(gateway): align run-loop server fixture

---------

Co-authored-by: joshavant <830519+joshavant@users.noreply.github.com>
2026-08-16 21:01:20 -07:00
Peter Steinberger bf9b25ab7e fix(gateway): prevent control-plane polling stalls (#124891)
* fix(gateway): avoid repeated control-plane scans

* fix(tooling): allow concurrent worktree validation

* fix(ci): refresh protocol and runner inputs

* perf(ui): defer hidden session refreshes

* fix(ui): resolve session refresh lint failure

* fix(update): preserve pre-cache update channel

* fix(update): normalize cached update channel

* fix(gateway): lifecycle-cache update install identity

* fix(ui): preserve manual history retry after layout scroll

* test(codex): repair side-question tool schema fixture
2026-08-16 20:58:27 -07:00
Peter Steinberger 0c01534426 fix(installer): finalize deferred PATH installs successfully (#124678)
Amp-Thread-ID: https://ampcode.com/threads/T-01a00ae0-190d-718b-8a76-b75f3e8d1fae

Co-authored-by: Amp <amp@ampcode.com>
2026-08-16 19:59:23 -07:00
Peter Steinberger 85baeecb57 refactor: consolidate record guards (#124970) 2026-08-16 19:34:57 -07:00
Peter Steinberger 78beccf053 feat: add cloud worker profiles and machine selection (#124864)
* feat(workers): add per-dispatch machine classes

* feat(ui): add cloud worker machine picker
2026-08-16 18:37:00 -07:00
Peter Steinberger 759e9cafec fix(ci): derive plugin SDK boundary cache inputs (#124897) 2026-08-16 18:35:58 -07:00
Peter Steinberger fa642a305e fix(ui): drop duplicate plan card summary (#124895) 2026-08-16 16:45:23 -07:00
Peter Steinberger 1d2d44c8ff perf(ci): price agents-core-models from its measured hybrid wall
`agentic-agents-core-models` carried the 36s scaled estimate while measuring
56.3s (n=6, p90 58.6s) across 260 compact jobs on 2026-08-16. Packed beside
`agentic-agents-core-runtime-hosted-1` (60.4s) it built the only bin running
>=1.25x its prediction: compact-large-19 ran 122s of work priced at 88s, which
made it the most frequent slowest job in the workflow.

Add the measured value to the hybrid hint map, which already exists for exactly
these Blacksmith-specific observations. The packer then separates the two, and
the tallest actual compact bin drops 122s -> 109s with no bin above 1.25x and
no change to row counts (48 push / 56 pull-request), so this costs no extra
runner registrations.

Two things deliberately left alone. The `agentic-gateway-core-3` 140s pin looks
like a 2x over-prediction against its 68.5s median, but run 31938297538 really
did take 138.0s (109.03s + 28.98s across its two configs) on a run whose fleet
slowdown factor was 0.98 -- a genuine tail on a healthy run, so unpinning it
would rebuild a >200s bin whenever the tail lands. Every other bin already sits
within 1.24x of its prediction.

The replaced guard pinned one bin arrangement (`runtime-hosted-1` not sharing a
job with `agents-core-tools`) with no stated failure mode, so any honest refit
broke it. It now asserts the property that comment was reaching for -- both
weight sources survive rebalancing under the body ceiling -- plus the specific
regression this fixes. Mutation-checked: dropping the hint fails the new guard.

Measurement note for the next refit: sum a shard's per-config Duration lines
before taking a median. Pooling them reads as a large over-prediction that is
not there.
2026-08-16 16:34:12 -07:00
Peter Steinberger ed339f9ba3 fix: remove delivery markers from historical sessions (#124888)
* fix(sessions): migrate historical transcript directives

* fix(infra): complete directive migration on pre-archives-schema databases

session_transcript_archives is a lazy additive v17 surface; valid databases
may omit it. The archives phase now treats the missing table as empty and
completes the cursor instead of warning-skipping the whole database forever.
Verified against a real long-lived agent DB: previously stuck cursor
completes with zero warnings in ~100ms.

* chore(ci): allow directive migration SQLite access
2026-08-16 16:24:46 -07:00
Peter Steinberger 0b5bb09510 fix(test): propagate parent heavy-check ownership (#124859)
Amp-Thread-ID: https://ampcode.com/threads/T-01a00b7c-b9f0-73d5-8fb7-e619e8e458e1

Co-authored-by: Amp <amp@ampcode.com>
2026-08-16 15:09:30 -07:00
Peter Steinberger 33f3b72a19 refactor(plugin-sdk): extract stream and SecretRef primitives (#124835) 2026-08-16 14:30:11 -07:00
Peter Steinberger 68762ad22c fix(ui): give queued-outbox badges their own outbox icon (#124842)
The sidebar queued-message badge and the composer queue reused the clock
glyph that also marks attached automations, so a session with both showed
two identical clocks distinguishable only by tooltip. Add an outbox tray
icon (Lucide inbox with the roof swapped for a rising arrow) and use it
for queued-to-send surfaces; the clock stays automation/cron-only. The
mock dev fixture now flags one session with hasAutomation so the badge
renders in mocked-dashboard proofs.
2026-08-16 14:29:41 -07:00
Peter Steinberger 4d4ee7bc86 refactor(plugin-sdk): consolidate session catalog families (#124801) 2026-08-16 13:25:11 -07:00
Peter Steinberger df5b5baf83 fix(ci): invalidate extension boundary cache for attempt types (#124800) 2026-08-16 13:16:32 -07:00
Peter Steinberger 7e92751d9a test(upgrade): drop retired agent context assertion (#124765)
Amp-Thread-ID: https://ampcode.com/threads/T-01a00a6a-b64e-74a5-8b15-2d3b966a468d

Co-authored-by: Amp <amp@ampcode.com>
2026-08-16 12:12:54 -07:00
Peter Steinberger 6540028c79 fix(ci): snapshot synced Testbox candidates (#124743)
Co-authored-by: Amp <amp@ampcode.com>
2026-08-16 11:56:02 -07:00
Peter Steinberger 568b920b21 feat(lint): enforce import ordering and deduplication (#124730)
* refactor(imports): dedupe and hoist imports

* feat(lint): enforce import/no-duplicates and import/first
2026-08-16 11:44:52 -07:00
Peter Steinberger b7fb951a94 fix(ci): let Crabbox own doctor readiness deadlines (#124725) 2026-08-16 11:30:24 -07:00
Peter Steinberger 569835e8b0 fix(ci): align baseline ratchets across local and CI (#124720) 2026-08-16 11:07:31 -07:00
Peter Steinberger cae9ecaba4 fix(pr): substitute anchor-matching canonical wrapper for stale worktrees (#124710)
A linked worktree whose base predates (or carries) wrapper changes relative
to origin/main previously hit a hard refusal, even though the canonical
checkout held exactly the trusted origin/main wrapper the refusal message
told the operator to go run by hand. When the canonical checkout is clean
and byte-identical to fetched refs/remotes/origin/main, exec it with a loud
stderr notice instead; advisory dev-wrapper opt-in keeps precedence, and
the refusal remains when no anchor-matching wrapper exists on disk.

Also records the squash-merged stacked-branch rebase gotcha
(git rebase --onto origin/main <landed-branch>) in the PR maintainer skill.
2026-08-16 10:48:26 -07:00
Peter Steinberger aeff737da9 fix(agents): prevent invalid names from targeting the default agent (#124670)
* fix(agents): reject unrepresentable agent ids

* refactor(system-agent): split model selection setup

* chore: shrink assertion safety baseline

* docs: record strict agent id validation proof

* style: format strict agent id report

* chore: drop stray unrelated report artifact

* chore: restore REPORT.md to main state
2026-08-16 10:37:06 -07:00
Peter Steinberger 337933509d fix(android): stop wrapper subprocess trees on cancellation (#124686)
* fix(android): reap Gradle wrapper subprocesses

* fix(android): preserve wrapper spawn errors
2026-08-16 09:43:12 -07:00
Peter Steinberger eb63cb1481 fix: keep dirty changed checks scoped to local edits (#124685)
* fix(crabbox): preserve dirty changed-gate state

Amp-Thread-ID: https://ampcode.com/threads/T-01a00a6a-b64e-74a5-8b15-2d3b966a468d

* fix(ci): cover WSL2 dirty changed gates

Amp-Thread-ID: https://ampcode.com/threads/T-01a00a6a-b64e-74a5-8b15-2d3b966a468d

---------

Co-authored-by: Amp <amp@ampcode.com>
2026-08-16 09:40:48 -07:00
Peter Steinberger 9eb68f37cf fix(pr): support authenticated GitHub CLI wrappers (#124674)
Amp-Thread-ID: https://ampcode.com/threads/T-01a00adc-59a7-727f-8708-6623320ec2b2

Co-authored-by: Amp <amp@ampcode.com>
2026-08-16 09:24:36 -07:00