Commit Graph

5407 Commits

Author SHA1 Message Date
Vincent Koc ae2705dafb fix(release): harden FRV checkpoint finalization 2026-08-22 17:18:56 +09:00
Vincent Koc 75bfd70ce1 fix(release): commit validation state before checkpoints 2026-08-22 16:46:40 +09:00
Vincent Koc 21705ac547 fix(release): harden checkpoint finalization 2026-08-22 16:31:56 +09:00
Vincent Koc 8bb779b231 fix(release): finalize validation state atomically 2026-08-22 16:31:56 +09:00
Vincent Koc bb243bcffd fix(release): isolate checkpoint journal failures 2026-08-22 16:31:56 +09:00
Vincent Koc 16f6839fb6 fix(release): preserve job log compatibility 2026-08-22 16:31:56 +09:00
Vincent Koc 513ce128e0 test(release): align rerun artifact assertions 2026-08-22 16:31:56 +09:00
Vincent Koc 69ac65272b fix(release): recover validation state across reruns 2026-08-22 16:31:47 +09:00
Ayaan Zaidi 0933263f76 fix(mantis): publish proof comments on auto-triggered runs (#127787)
## What Problem This Solves

Auto-triggered Mantis proof runs (label/`clawsweeper_label` and other non-comment request sources) end with no PR comment at all. The durable evidence publisher runs with `--create-missing false` and only edits an existing marker comment, but the inline status comment carrying that marker was only created when `request_source == 'issue_comment'`. Label-triggered runs therefore published nothing and logged the misleading "Skipped stale Mantis QA evidence comment because its status is no longer active" — observed on PR #127735. This is the silent-failure class: a Mantis run completes and the PR shows no visible outcome.

## Why This Change Was Made

- `.github/workflows/mantis-telegram-desktop-proof.yml`: the status ack comment (👀 + active-job link + run-scoped marker) is now created for every request source that resolves to a PR (`pr_number != ''`), not only `issue_comment`. The 👀 *reaction* stays `issue_comment`-only (it lives in `mantis-resolve-request.yml`, untouched — there is no triggering comment to react to on label runs).
- The start-failure fallback comment and the existing-artifact republish path now use the same run-scoped marker `<!-- mantis-telegram-desktop-proof:${GITHUB_RUN_ID}-${GITHUB_RUN_ATTEMPT} -->` as the status comment and the main publisher, so every publisher edits the single run-owned comment (ack → progress → final proof; no comment spam). The republish path gets an explicit `--create-missing false` to match. The design invariant that makes `false` safe: the fallback status-comment step is not `continue-on-error`, so a run in which no marker comment could be created fails `resolve_request` and never reaches publish.
- `scripts/mantis/publish-pr-evidence.mjs`: the two skip cases now log honestly — "no existing comment found" vs "could not update existing comment" — instead of one misleading stale-status message.

## User Impact

Operators triggering Mantis via labels (ClawSweeper flows) now get the same single evolving PR comment as comment-triggered runs: an immediate 👀 ack with the running job link, edited in place into the final proof evidence. No more runs that finish invisibly.

## Evidence

- Focused suite: `node scripts/run-vitest.mjs test/scripts/mantis-telegram-desktop-proof-workflow.test.ts` — 28/28, including new assertions that the status/failure comment gates use `pr_number != ''` (and not `request_source`) and that both publishers pass the run-scoped marker with `--create-missing false`.
- `node scripts/check-changed.mjs -- <touched files>` green; `git diff --check` clean.
- Marker alignment verified across all five sites in the workflow (status comment, prior-attempt cleanup regex, fallback comment, failure report, both publisher invocations): all use `mantis-telegram-desktop-proof:${GITHUB_RUN_ID}-${GITHUB_RUN_ATTEMPT}`.
- Live-run proof of the label-triggered path requires a merged workflow (GitHub runs the workflow from the default branch for these triggers), so the first post-merge label-triggered Mantis run is the live verification; stated here as the known evidence gap.

Production LOC delta: −4 (workflow/tooling); tests +13.
2026-08-22 11:10:11 +05:30
Ayaan Zaidi 10e0e690df feat(mantis): programmable proof boundaries with recipe library (#127782)
Makes the Mantis Telegram Desktop proof agent programmable at its trust boundaries: declarative Bot API fault rules (drop/status per method), per-request scripted mock-provider responses, observe-until predicates (post-cursor events/text, cumulative provider count), and bounded proxy-side recording of outbound Bot API requests as trusted lane facts. Adds a reusable recipe library under .github/codex/prompts/mantis-recipes/ and raises the proof agent's reasoning effort to high.

Security: the SUT container shadows proxy-control with an inaccessible tmpfs so candidate PR code sharing the mantis-sut uid cannot read or rewrite the proxy's recorded evidence; unmount is blocked by cap-drop/no-new-privileges. Proof doctrine now treats proxy-recorded Bot API facts as trusted comparison evidence and provider request logs as diagnostics.

Follow-up named in PR: move the mock OpenAI server out of the SUT container so provider request facts also become candidate-tamper-proof.
2026-08-22 11:06:06 +05:30
Dallin Romney e1256421d3 fix(e2e): skip package postinstall in git fixture (#127768) 2026-08-21 20:45:19 -07:00
Dallin Romney 53fbe2eb33 fix(release): preserve validation plan across reruns (#127343)
* fix(release): preserve validation plan across reruns

* test(release): align rerun plan assertions

* refactor(release): use canonical plan cache action

* style(test): format release plan cache assertion
2026-08-21 19:08:32 -07:00
Dallin Romney fc5cb9e304 fix(ci): preserve current Kova gate failures (#126034) 2026-08-21 18:18:26 -07:00
Peter Steinberger 89bb601b91 fix(qa): replace Linux-only /proc probes in the Telegram proof harness (#127718)
The Mantis lane and the Telegram user driver reached for /proc to enforce
media containment and to prove a pid was still alive. Off Linux those paths
do not exist, so the containment check compared a literal "/proc/self/fd/N"
string against the output root and refused every file, while both liveness
probes silently reported "gone": the lane stole a held harness lock and the
driver deleted the observer pid file without ever signalling the process.

Containment now uses each runtime's strongest portable construct. Python
descends the media path one component at a time from an open directory
descriptor (O_DIRECTORY|O_NOFOLLOW, dir_fd), which is race-free and also
covers the intermediate directories the old leaf-only O_NOFOLLOW did not.
Node has no openat(2), so publicRelativePath re-walks the resolved
components after the descriptor is open and refuses any that became a
symlink. Liveness moves to process.kill(pid, 0) and to ps state/args, which
keeps the pid-reuse and zombie handling the /proc reads provided.

The compound-command approval binding test asserted an operand count that
only held where the host interpreters live in a root-owned prefix; a
Homebrew python3 is writable, so it correctly binds as a third executable
operand. Assert the script operands by path instead.
2026-08-21 17:45:12 -07:00
Vincent Koc 7dfe406d20 perf(ci): parallelize installer smoke validation (#127138)
* fix(ci): parallelize installer smoke groups

* fix(ci): bind installer smoke artifacts

* fix(ci): isolate installer smoke candidate payload

* fix(ci): restore trusted install harness

* fix(ci): run Bun smoke from trusted harness
2026-08-21 17:02:11 -07:00
Peter Steinberger 74c1900e63 refactor(tooling): unify managed child process cleanup (#127480) 2026-08-21 15:43:39 -07:00
Peter Steinberger 14cebc477a fix(recovery): keep queued replies alive during session watchdog repair (#127510)
* fix(recovery): preserve queued turns during session watchdog repair

* test(plugins): make stalled response timeout deterministic
2026-08-21 14:14:26 -07:00
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 8dd21b0f34 fix(browser): load Playwright runtime on demand (#127049)
* fix(browser): load Playwright runtime on demand

* test(browser): use lazy Playwright accessor

* fix(worker): bind bundled Playwright runtime

* style(worker): format build regression

* style(worker): apply repository formatter
2026-08-21 10:45:18 -07:00
Ayaan Zaidi 10a3df4fb6 feat(mantis): let proof agents extend desktop control (#127271)
* feat(mantis): let proof agents extend desktop control

* fix(mantis): constrain desktop extensions

* docs(mantis): document desktop action authority

* fix(mantis): bind actions to recorded window
2026-08-21 23:09:17 +05:30
Eden 830196c628 fix(scripts): keep Windows lint runs from failing before any file is checked (#126274)
* fix(scripts): keep Windows lint runs from failing before any file is checked

`pnpm lint:extensions` aborts on Windows whenever the plugin SDK boundary
cache is cold: the boundary prep spawns `node_modules/.bin/tsgo` directly,
and Windows cannot execute the extensionless pnpm shim, so the run dies with
ENOENT before oxlint checks a single file. The stylelint runner reached by
`check-changed` fails the same way for the same reason.

Both now build their child process with `createManagedCommandInvocation`,
the launcher every other repo tool runner already uses, which routes the shim
through cmd.exe on Windows and returns the command unchanged everywhere else.

Off Windows the spawned command, arguments, and options are byte-identical to
before, so only the broken platform changes behavior.

* fix(scripts): stop the lint pipeline from spawning a tool shim directly

`pnpm lint` reaches stylelint through the same raw shim spawn that broke the
boundary prep, so the pipeline dies on Windows after oxlint succeeds. Route it
through the managed launcher like every other tool runner.

The remaining hazard is structural: the resolver hands out a path that only
some callers know to normalize, and the three sites that forgot were spread
across two spawn shapes. Add a static guard so a shim can only flow into a
launcher that understands the platform, and so the next occurrence fails on
Linux CI instead of on a contributor's Windows machine.

* test(scripts): trim Windows shim regression coverage

Punchcard-Session: cobalt-orchard-willow-2q

---------

Co-authored-by: Vincent Koc <vincentkoc@ieee.org>
2026-08-21 09:31:50 -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
ClawSweeper f94f945314 improve(ui): declutter Automations across desktop and mobile (#127198)
* improve(ui): declutter automations list

* test: align automation UI and process cleanup

Co-authored-by: Tak Hoffman <781889+Takhoffman@users.noreply.github.com>

---------

Co-authored-by: RoboClaw <309084314+roboclaw-bot@users.noreply.github.com>
Co-authored-by: Tak Hoffman <781889+Takhoffman@users.noreply.github.com>
2026-08-21 06:56:43 -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
Dallin Romney be891d2ac0 fix(e2e): follow shared auth ownership in onboarding proof (#126958) 2026-08-20 20:01:25 -07:00
Dallin Romney 1c40eee82e fix(ci): route recurring validation through SHA helper (#126766) 2026-08-20 19:11:27 -07:00
Peter Steinberger ab2bbd42df test: trim UI and tooling test seams (#126937) 2026-08-20 19:04:18 -07:00
Peter Steinberger e22774127a test: remove core test scaffolding (#126926) 2026-08-20 18:34:15 -07:00
Josh Avant a042125170 fix(memory): preserve provenance across dreaming (#126489)
* fix(memory): preserve provenance across dreaming

* fix(build): preserve bundled hook metadata

* refactor(build): remove obsolete directory helper

* test(memory): align provenance fixtures

* test(memory): type consolidation run options

* test(memory): register write provenance siblings

* fix(memory): preserve legacy provenance registration

* fix(memory): make provenance provider-independent

* fix(memory): canonicalize provenance workspace keys

* fix(memory): keep provenance mutation host-private

* fix(build): track runtime postbuild implementations

* fix(build): verify bundled hook metadata outputs
2026-08-20 17:58:31 -07:00
Peter Steinberger df2cc8f259 fix(onboard): honor secret-input-mode ref for the generated gateway token (#126877)
* fix(onboard): honor secret-input-mode ref for the generated gateway token

`openclaw onboard --secret-input-mode ref` was silently ignored for
`gateway.auth.token`: onboarding generated the token and wrote it into
`openclaw.json` as a plaintext string, so `openclaw doctor` warned about
`gateway.auth.token` on the install it had just created. The flag was
honored for provider credentials, so an operator who explicitly opted into
references still ended up with a plaintext secret and a remediation
(`openclaw secrets configure`) that cannot migrate a self-generated value,
because it validates a ref by resolving one that already exists.

Setup mints this token itself, so reference mode now provisions it:

- an ambient OPENCLAW_GATEWAY_TOKEN keeps an `env` ref to that variable, so a
  later rotation stays authoritative instead of being pinned by a stale copy
- anything else (freshly generated, or an existing plaintext token being
  migrated) goes into the shared SQLite secret store as a write-only `secret`
  entry, with config holding only `{source:"store",...}`

An existing store entry wins over a freshly generated one, so reruns never
rotate a token already paired with clients. The store write precedes the
config write: a ref persisted without its value would leave the gateway
unauthenticatable, while an orphaned entry is reused by the next run.

The interactive wizard had the same dead end and is fixed the same way.
Default (plaintext) onboarding is unchanged.

User impact: `--secret-input-mode ref` now keeps the gateway token out of
openclaw.json, and a fresh install no longer self-reports a plaintext-secret
warning.

* test(onboard): split gateway onboarding suite under the max-lines gate

The added gateway auth-token tests pushed
onboard-non-interactive.gateway.test.ts to 1014 lines, over the max-lines
limit (check-lint-core-3). Repo policy is to split, never suppress.

Extract the shared vi.mock/harness preamble into
onboard-non-interactive.gateway.test-mocks.ts, following the existing
agent-command.test-mocks.ts pattern, and move the four gateway auth-token
storage tests into their own suite. The reachability mock becomes a holder
object so both suites can swap it across the module boundary, and hoisted
mocks are re-exported in a separate export clause because Vitest rejects
exporting a vi.hoisted binding at its declaration.

Test set is unchanged: the it-declaration multiset matches the pre-split
file exactly, with no duplication across the two suites.

* test(onboard): give the shared gateway onboarding mocks unique export names

check-export-name-collisions flagged `runtime` and `readConfigFileSnapshotMock`
as colliding with program.test-mocks.ts and plugins-cli-test-helpers.ts once the
gateway onboarding preamble became a shared module. Rename the exports to
gatewayOnboardRuntime / gatewayOnboardConfigSnapshotMock per the repo's
unique-export-name rule; suites alias them locally so the assertions read the
same as before.

* test(tooling): route the new gateway auth-token suite from its test helper

test-projects asserts which suites a change to
onboard-non-interactive.test-helpers.ts should run. The new
onboard-non-interactive.gateway-auth-token.test.ts imports that helper, so it
belongs in the expected routing plan.
2026-08-20 17:46:59 -07:00
Peter Steinberger e78b9d3ce4 fix(install): defer success until verification (#126871) 2026-08-20 15:57:11 -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
joshavant b52d2f08f5 fix(ci): trust maintainer-authored dependency changes 2026-08-20 15:09:22 -05:00
Peter Steinberger 4249df34b4 improve(code-mode): call tools as global functions (#126262)
* feat(code-mode): expose tools as global functions

* fix(code-mode): harden callable tool composition

* fix(code-mode): reserve private guest globals

* fix(cron): migrate legacy code-mode triggers

* fix(code-mode): align final tool result contracts
2026-08-20 12:18:23 -07:00
Vincent Koc 701b576cc1 fix(ci): default Telegram advisory input to false (#126794) 2026-08-21 03:03:52 +08:00
Peter Steinberger ee7146a282 fix(ui): make startup gzip runtime-independent (#126795)
Host zlib versions compress identical startup assets into different bytes, causing false Linux budget failures. Emit canonical shipped pako gzip sidecars, restore the 512 B ratchet tolerance, and lower the startup baseline from 348351 B to 344531 B.
2026-08-20 12:00:01 -07:00
Dallin Romney 2f602fd382 fix(plugin-sdk): deduplicate API diff declarations (#126725) 2026-08-20 11:31:48 -07:00
Patrick Erichsen 7e4eeb90d7 fix(pr): batch ignored transition checks (#126759)
* fix(pr): batch ignored transition checks

* fix(pr): ignore absent ignored transition paths
2026-08-20 11:08:28 -07:00
Vincent Koc 2f0f65e790 fix(ci): add Telegram-only package acceptance profile (#126769) 2026-08-20 11:01:59 -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