Commit Graph

2198 Commits

Author SHA1 Message Date
Vincent Koc 1da74794b6 fix(release): establish immutable release plan contract (#127008)
* fix(release): define immutable release plan contract

* fix(release): harden immutable plan authority

* fix(release): tighten release plan authority

* fix(release): share plugin publication authority

* fix(release): verify plan authority remotely

* fix(release): track ClawHub publication authorities

* fix(release): trust remote tooling tag identity

* fix(release): close plugin publication authority

* fix(release): align npm authority selection

* fix(release): bind plans to validation intent

* fix(release): require qualification cadence

* fix(release): reject lossy canonical values

* fix(release): narrow qualification cadence

* fix(release): bind plan parser dependency

* fix(release): add tagless diagnostic plans

* fix(release): attest release plan parser tree

* fix(release): isolate verified plan parser snapshot

* fix(release): verify plan tooling before execution
2026-08-21 11:24:22 -07:00
Dallin Romney c4d07b398b fix(release): allow unreleased changelog in SHA preflight (#127019) 2026-08-21 09:28:36 -07:00
Vincent Koc a2f0b84e8a fix(release): report blockers before diagnostics finish (#127014)
* fix(release): separate decisions from diagnostic drain

* test(release): align decision drain fixtures

* fix(release): pin artifact downloads to valid v8 SHA

* fix(release): default empty evidence paths in plans

* fix(release): bind complete evidence reuse selection

* fix(release): harden retry artifact integrity

* fix(release): canonicalize reused validation evidence

* fix(release): bind manifest children to execution plan

* test(release): fix validation fixture types

* fix(release): retry transient decision artifact reads
2026-08-21 09:14:39 -07:00
Vincent Koc 7833e242cb fix(ci): isolate performance candidate trust (#127160) 2026-08-21 07:54:56 -07:00
Ayaan Zaidi e8d2b8cb18 fix(mantis): keep Telegram proof running and honest (#127108)
Make long, free-form Telegram proof runs truthful and resilient. Keep the trusted mock harness current across historical SUTs, preserve intentional silence and blocked outcomes, remove fixed attempt/lifetime caps, and export cropped motion proof without the prior memory spike.

Co-authored-by: Ayaan Zaidi <hi@obviy.us>
2026-08-21 17:53:54 +05:30
Vincent Koc 67630f6854 fix(ci): isolate candidate cache authority (#127149) 2026-08-21 03:47:41 -07:00
Vincent Koc 225aa5a178 fix(ci): isolate Actions cache writes (#127107) 2026-08-21 02:45:06 -07:00
Vincent Koc fa86caf94f fix(release): keep protected tooling trusted after main moves (#126881)
* fix(release): keep protected tooling trusted after main moves

* fix(release): cover protected tooling recovery paths

* fix(release): honor live tooling contracts

* fix(release): revalidate tooling at npm publish

* fix(release): bind npm publishers to live tooling

* fix(release): preserve trusted dispatch identity

* fix(release): revalidate parent authorization

* fix(release): bind ClawHub to release parent

* docs(release): define frozen tooling identity

* test(release): align ClawHub protected dispatch ref

* fix(release): trust protected plugin npm preflight tooling

* docs(release): scope protected writer guarantees

* fix(release): keep protected tooling foundation npm-only

* test(release): cover trusted npm preflight tooling
2026-08-21 07:24:31 +00:00
Ayaan Zaidi 190f2edd7f fix(qa): stop Mantis skipping visible Telegram changes (#127032)
Remove the premature visibility classifier and let one proof agent configure and exercise the disposable Telegram gateway. Align mock response timing with the 15-minute lane budget while preserving credential isolation through the alias-token proxy.
2026-08-21 12:33:38 +05:30
Vincent Koc 750f2f3762 fix(release): require concrete validation retry groups (#127012)
* fix(release): require concrete validation retry groups

* fix(release): reject mismatched retry filters

* fix(release): align retry controller vocabulary

* fix(release): preserve historical validation evidence

* fix(release): validate retry filters before scheduling

* test(release): follow shared filter validator

* docs(testing): clarify release QA retry groups
2026-08-20 23:35:16 -07:00
Ayaan Zaidi 1aa211be4a fix(qa): make Mantis backfills reliable (#126980)
Preserve honest blocked proof outcomes and publish visible stop-reports without marking them passed. Serialize burst runs through the authoritative Telegram-user lease while reserving time for proof and cleanup.
2026-08-21 10:01:58 +05:30
Peter Steinberger 0f2facaf14 test: remove Docker seed source guards (#126949)
* test: remove Docker seed source guards

* ci: route Docker seed edits to owner lanes
2026-08-20 20:36:38 -07:00
Dallin Romney 59e9765e77 fix(ci): accept extended-stable patch successors (#126936)
* fix(ci): accept extended-stable patch successors

* fix(ci): align Telegram extended-stable successors
2026-08-20 20:13:26 -07:00
Vincent Koc fa71a6f27b fix(qa): isolate packaged mock auth bootstrap (#126247)
* fix(qa): isolate packaged mock auth config

Punchcard-Session: frost-orchard-lantern-ze
(cherry picked from commit 648bd40a4f)

* fix(qa): scrub inherited shell startup env

* fix(qa): block exported Bash functions
2026-08-21 06:51:34 +08:00
Vincent Koc 701b576cc1 fix(ci): default Telegram advisory input to false (#126794) 2026-08-21 03:03:52 +08:00
Vincent Koc 2f0f65e790 fix(ci): add Telegram-only package acceptance profile (#126769) 2026-08-20 11:01:59 -07:00
Hiroshi Tanaka 55f1738d50 fix(control-ui): config form save corrupts 64-bit id strings in string|number fields (#126402)
* fix(control-ui): stop config form save from corrupting 64-bit id strings

Saving the schema-driven config form coerced every numeric-looking string
to a JS number before submission. For union-typed fields such as
tools.elevated.allowFrom.* (anyOf: string | number), string entries
holding 64-bit ids (Discord/Telegram snowflakes) were rewritten through
Number(), which rounds past 2^53:
"1048113311314608148" -> 1048113311314608100. The corruption also hit
untouched fields, because serialization coerces the whole form, so merely
saving an unrelated setting silently broke elevated-approval allowlists
(fail-closed: the real user id no longer matched).

Two guards fix this:
- coerceFormValues keeps a string that already satisfies a string variant
  of an anyOf/oneOf union instead of parsing it into another variant's
  number.
- coerceConfigFormNumberString refuses lossy integer parses: plain
  integer text beyond Number.MAX_SAFE_INTEGER that does not round-trip
  through BigInt stays a string, so pure number/integer fields fail
  validation loudly instead of storing a corrupted id.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

* fix(control-ui): harden 64-bit config id preservation

* fix(control-ui): validate mixed-union scalar branches

* test(control-ui): prove real gateway id preservation

* test(control-ui): use communications route for config proof

* test(control-ui): grant config proof admin scope

* test(control-ui): reopen raw config for proof

* fix(control-ui): preserve explicit union input types

* test(control-ui): exercise union collection draft

* ci: retry flaky control ui e2e

* fix(control-ui): preserve mixed scalar branch types

* ci: retry service worker e2e

* fix(control-ui): preserve typeless string union branches

* fix(control-ui): reject lossy decimal coercion

* fix(control-ui): reject lossy pure numeric input

* fix(control-ui): preserve exact numeric branch semantics

* ci: retry checkout rate limit

* ci(control-ui): capture real gateway proof

* test(control-ui): frame config proof values

* ci: retry checkout download

* test(control-ui): prove Gateway-served production bundle

* fix(control-ui): preserve exact incremental union edits

* refactor(control-ui): isolate scalar edit session state

* fix(control-ui): keep scalar edit branch type internal

* fix(control-ui): avoid detached focus selector

* fix(control-ui): round-trip exact numeric branches

* refactor(control-ui): share exact scalar formatting

---------

Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
2026-08-20 08:50:24 -07:00
Ayaan Zaidi 4768ac53c5 feat(qa): acknowledge Mantis PR requests (#126702)
Give maintainers immediate visibility when Mantis is requested. Bare mentions now react, link the active run, and keep one run-owned status comment through proof, short-circuit, or failure.

Co-authored-by: Ayaan Zaidi <hi@obviy.us>
2026-08-20 21:19:40 +05:30
Ayaan Zaidi 8458777e6a feat(qa): trigger Mantis proof from pull requests (#126658)
Add trusted ClawSweeper-label and maintainer-comment dispatch for Mantis Telegram proof. Short-circuit non-visible PRs before desktop setup while preserving exact-head, fork, credential, and comment-ownership boundaries.
2026-08-20 20:05:51 +05:30
Vincent Koc c28c279afa fix(release): keep frozen validation independent of main (#126622)
* fix(release): freeze validation tooling identity

* fix(release): enforce frozen validation contract

* fix(release): validate candidate identity in parent

* fix(ci): close release isolation gate findings
2026-08-20 04:32:38 -07:00
Ayaan Zaidi b7b7eec5ee feat(qa): run Mantis Telegram proof on local desktop (#126220)
Move Mantis Telegram Desktop proof from the remote AWS/Crabbox lane to a recorder-driven local Docker desktop. Keep proof scenarios agent-authored, cache trusted build outputs, and publish exact visible Telegram evidence without writing the QA bot token to artifacts.

Co-authored-by: Ayaan Zaidi <hi@obviy.us>
2026-08-20 11:12:51 +00:00
Peter Steinberger ab7fc490d6 fix(package): clean dist before root packaging (#126577) 2026-08-20 01:13:06 -07:00
Vincent Koc bd77ee1031 fix(ci): retain pending QA workflow calls (#126254) 2026-08-20 00:34:26 +08:00
Peter Steinberger b514fca522 refactor(update): simplify lifecycle transactions (#126240)
* refactor(update): simplify lifecycle transactions

* ci: use runner-provided ShellCheck

* test(infra): stabilize port-release probe
2026-08-19 01:50:35 -07:00
Peter Steinberger 7bc994aee8 fix(install): avoid success after incomplete lifecycle changes (#125992)
* fix(install): make lifecycle mutations transactional

Standalone installers now apply npm-version-aware lifecycle approval. Updates verify and repair the installation before reporting success and preserve the prior install owner during method switches. Uninstall now exits nonzero when requested cleanup is only partially completed. Plugin update behavior is unchanged.

Closes #125925

* test(uninstall): assert aggregated live-owner failure

* fix(install): satisfy standalone shell checks

* fix(update): scan PATH for prior Git wrapper

* test(hooks): await Gmail watcher descendant exit

* fix(install): verify Windows npm candidate

* fix(ci): normalize package acceptance version

* fix(update): preserve staged local package links

* test(update): fold staged symlink coverage

* fix(update): retire every legacy Git wrapper

* test(docs): align consolidated ownership checks
2026-08-18 20:50:15 -07:00
Dallin Romney 5169760bde fix(ci): provide isolated Telegram runtime tmp (#125625)
* fix(ci): provide isolated Telegram runtime tmp

* style(test): format Telegram QA regression
2026-08-18 07:17:37 -07:00
Dallin Romney 33a8645dcf fix(ci): resolve performance targets from checkout (#125575) 2026-08-18 07:03:16 -07:00
PollyBot13 e83a9b583d fix(ci): parse Telegram QA launcher on macOS Bash (#125294)
The Telegram release-QA workflow embeds a SUT launcher that the repository
test suite extracts and syntax-checks with the local bash. Four `[[ -v ... ]]`
probes require Bash 4.2+, so the check failed under stock macOS Bash 3.2.

Replace them with `declare -p` and `${keep_env[$key]+x}`, which parse on
Bash 3.2 and are runtime-equivalent on the Ubuntu runners. Environment
preservation and boundary-mode behavior are unchanged.

Closes #125293
2026-08-18 12:47:39 +05:30
Peter Steinberger b3248bf8f1 fix(release): authenticate performance health probes (#125453) 2026-08-17 16:54:21 -07:00
Víctor Gurbani Carballo daf7cae8c0 fix(android): new chats receive generated titles (#123670)
* fix(android): allow generated session titles

* fix(android): keep unnamed chat titles local

Co-authored-by: victor-gurbani <89997914+victor-gurbani@users.noreply.github.com>

* chore(android): refresh native i18n inventory

Co-authored-by: victor-gurbani <89997914+victor-gurbani@users.noreply.github.com>

* fix(ci): keep fork lint within hosted limits

Co-authored-by: victor-gurbani <89997914+victor-gurbani@users.noreply.github.com>

* test(ci): align prerelease manifest fixture

Co-authored-by: victor-gurbani <89997914+victor-gurbani@users.noreply.github.com>

* fix(android): align chat switcher session titles

Co-authored-by: victor-gurbani <89997914+victor-gurbani@users.noreply.github.com>

---------

Co-authored-by: Peter Steinberger <steipete@gmail.com>
2026-08-17 03:35:34 -07:00
Peter Steinberger a3578c7790 test(qa): cover Discord progress draft lifecycle (#125089)
* test(qa): cover Discord progress draft lifecycle

* test(qa): allow live Discord draft proof

* ci(qa): select Discord provider mode
2026-08-16 23:17:53 -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
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
Patrick Erichsen 305e38f5d9 fix(release): allow beta Docker backfills (#124999) 2026-08-16 20:16:40 -07:00
Peter Steinberger 759e9cafec fix(ci): derive plugin SDK boundary cache inputs (#124897) 2026-08-16 18:35:58 -07:00
Peter Steinberger 1f1aa88f14 perf(ci): split Windows CI two ways instead of one serial lane
`checks-windows-node-test` ran the whole 222-266s Windows body in a single
Blacksmith lane, so every run that scheduled it finished at 287-334s against a
~180s plateau. Measured across 45 canonical main runs it was the wall in all
seven runs that triggered it (324-519s vs a 210s median elsewhere).

Blacksmith's Windows class admits exactly 2 concurrent jobs (run 31865243804),
which is why the earlier 3-part split failed: its tail queued 211s behind a
finished part. Pin the split width to that measured capacity instead. The two
parts are balanced by measured per-project wall time -- part 1 keeps the old
list 1 plus list 2's non-infra projects (~108s), part 2 takes list 2's infra
project plus the old list 3 (~112s) -- so both land near 113s and the lane
stops setting the wall.

One canonical partition now serves every backend; the github-mode/dispatch
3-part variant and its separate file inventory are gone, along with the
single-lane `task: test` case and the per-row `matrix.runner` the collapsed
lane needed. The complete 65-file Windows inventory is preserved exactly, and
the guards pin the width on both sides (mutation-checked: restoring 3 parts
fails the matrix guard).
2026-08-16 16:02:24 -07:00
Peter Steinberger bf67e079a9 fix(ci): render only aggregate QA evidence (#124823) 2026-08-16 13:49:39 -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 de52a6c314 fix(ci): select aggregate QA evidence by manifest (#124802) 2026-08-16 13:14:49 -07:00
Peter Steinberger 6a0c9f43d2 fix(ci): keep QA evidence output repo-relative (#124760) 2026-08-16 12:08:48 -07:00
Peter Steinberger edf4c74601 fix(ci): prevent QA maturity scorecard timeouts (#124612)
* fix(ci): prevent QA maturity scorecard timeouts

* fix(ci): register QA evidence shard entrypoint

* fix(ci): isolate QA evidence jobs from shared caches

* fix(ci): separate QA selected revision from trusted harness

* fix(ci): protect every QA selected-code job

* fix(ci): bind QA workflow callers before checkout

* fix(ci): authenticate QA evidence caller chain

* fix(ci): remove dynamic QA checkout actions
2026-08-16 11:17:21 -07:00
Peter Steinberger 4fb27369ee perf(ci): keep the real-Gateway UI E2E lane on Blacksmith in hybrid mode
`checks-ui-e2e-real-gateway` folded `hybrid` into the `github` breaker clause
instead of taking the attempt-gated route its sibling `checks-ui-e2e` uses, so
it was the only Chromium lane pinned to hosted capacity on attempt 1. Measured
across 46 canonical main runs it averaged 205s (max 225s) against a 150-190s
plateau, making it the run's slowest job whenever the compact Node matrix
behaved.

Route it like `checks-ui-e2e`: Blacksmith 16-vCPU on attempt 1, hosted on rerun,
manual dispatch, fork, and same-repo PR retry. Cache inputs stay on the shared
pnpm store for both backends, matching the sibling lane.

The guard now derives both Chromium lanes' `runs-on` from one pinned template so
a hosted-only divergence cannot return unnoticed; mutation-checked by reverting
the workflow clause (2 failures).
2026-08-16 11:15:47 -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 8d86fe79a6 perf(ci): route runners by contributor trust instead of fork status
Fork pull requests were pinned to GitHub-hosted runners while maintainer
PRs rode Blacksmith. That split arrived with ci.yml's first commit
(f4f990a) and was never a reasoned posture -- no rationale in docs,
commit bodies, or the ci-limits skill -- and this week's Blacksmith
tranches widened the gap: maintainer walls are ~3:36 while the last fork
PR I measured (#124633) took 13m0s. We already paid for it once in
#118530, which raised the cross-repo artifact budget to 35 minutes
because contributor PR #117992 timed out twice on hosted capacity.

Runner choice now follows author_association: OWNER, MEMBER, COLLABORATOR,
and CONTRIBUTOR get Blacksmith; FIRST_TIME_CONTRIBUTOR, FIRST_TIMER, NONE,
and MANNEQUIN stay on hosted runners, which are free for public repos, so
an unreviewed author cannot spend Blacksmith capacity. Earning the fast
path requires a landed commit, which requires a maintainer merge.

Note for anyone tempted to trim that list: maintainers report CONTRIBUTOR
here, not OWNER/MEMBER, because org membership is concealed -- steipete's
74 sampled PRs are all CONTRIBUTOR. Dropping CONTRIBUTOR would move
maintainer PRs to hosted.

Scope is deliberately runner-only: 27 runs-on clauses. The 34
dependency-cache/use-actions-cache conditions and 6 job ifs stay
fork-gated, because cache poisoning is a different risk from runner
choice -- a fork run still never writes an archive a trusted run restores.

Verified by evaluating all 25 configurable runs-on expressions: maintainer
PR 12/25 Blacksmith, returning-contributor fork 12/25 (identical), unknown
author 0/25, FIRST_TIME_CONTRIBUTOR 0/25, push to main 12/25 unchanged.
Guard tests gained trusted/untrusted fork cases; 119 pass.
2026-08-16 07:43:07 -07:00
Peter Steinberger 81d44365ae chore(ci): drop the artifact-check step outputs left behind by the job outputs
Removing build-artifacts' unread job outputs left the step still writing
four `*-result` step outputs and carrying an `id` that nothing
references. The wave already reports failures through ::error
annotations and its exit code, so these were pure leftovers.

Re-simulated the step body with stubbed pnpm/node: normal run exits 0, a
failing verifier still exits 1.
2026-08-16 06:37:01 -07:00
Peter Steinberger d8697d5956 chore(ci): drop the disabled timing-summary job and unread build outputs
Two pieces of dead workflow surface, found auditing where CI time goes:

- ci-timings-summary was hard-disabled (`if: ${{ false && ... }}`) with a
  TODO to re-enable or delete it after the next timing-optimization
  review. That review happened; the local `pnpm ci:timings` helper is what
  we actually use, and docs already pointed there. The job carried a
  25-entry needs list that had to be kept in sync to stay lintable.
- build-artifacts exported four `*-result` outputs that no job or workflow
  reads.

Removing the job lets the gate guard assert the stronger invariant it
wanted all along: ci-gate needs *every* job in the file, so a new lane
cannot slip in ungated (28 jobs, 27 gated, zero exceptions).

No runtime behavior changes: the job could never run and the outputs had
no consumers. Also audited every `pnpm <script>` and `node scripts/...`
reference in ci.yml for rot -- all resolve.
2026-08-16 06:27:11 -07:00
Peter Steinberger bba57301d9 perf(ci): fold built-runtime verifiers into the artifact-check wave
build-artifacts is the wall's pole in 4 of the last 5 main runs (171-186s,
~15-20s ahead of the next lane), so its serial steps are the wall. The
Doctor plugin-index proof, singleton smoke, and startup-memory check ran
as their own 13s step even though they are independent dist readers that
the 47s artifact-check wave could absorb.

They now run inside that wave: on Blacksmith all seven start together, so
the verifiers cost the wave's max instead of 13s of serial time; hosted
runners still serialize the three through run_verifier so the RSS ceiling
measures an unloaded process. The step drops its selection gate because
the verifiers always run -- each artifact check already self-gates on its
own RUN_* flag, so a run with no checks selected still verifies.

Proof: extracted the step body and ran it with stubbed pnpm/node. Both
modes behave (Blacksmith 7 checks started, hosted-with-nothing-selected
still runs the 3 verifiers), and a failing verifier exits 1 with its
::error annotation in both -- the wave cannot swallow it.
2026-08-16 04:52:56 -07:00
Peter Steinberger d5f41f734b fix(ci): trust QA tooling for frozen targets (#124509)
* fix(ci): trust QA tooling for frozen targets

* fix(ci): validate frozen QA tooling context

* fix(ci): verify frozen context without checkout

* fix(ci): pin QA tooling to workflow revision
2026-08-16 02:41:24 -07:00
Peter Steinberger 255ca8d96b fix(ci): trust frozen plugin prerelease fixtures (#124446)
* fix(ci): trust frozen plugin prerelease fixtures

* fix(ci): apply scoped plugin test omissions
2026-08-15 23:47:25 -07:00