Addresses the review findings on #371, plus several the bots did not catch.
All fixes have regression coverage that fails on the prior code.
Source corruption:
- Vue accept dropped valueless root attrs (disabled, v-cloak) and, worse,
rewrote @click="x" as a literal click="x" DOM attribute, because the attr
parser was name-anchored and skipped the sigil. Tokenize the whole Vue attr
grammar and normalize shorthands so accept round-trips directives.
- --variant was interpolated unescaped into a RegExp, so --variant '.*' matched
the original block first and reported a successful accept while silently
restoring the original. Validate against the digits pattern the browser and
the /events schema already enforce.
- --id reached path.join unvalidated, so --id ../../../../etc/evil wrote and
read receipts outside the project. Hoist the existing safeSessionId check
into impeccable-paths and apply it at every id-to-path sink.
Accept/lock correctness:
- Plain HTML/JSX accept and discard did not catch SOURCE_LOCKED, so contention
exited non-zero with empty stdout and the agent got no JSON to retry on.
- Lock staleness was mtime-only and never read the pid it records: a holder
whose critical section outran 60s had its live lock swept, admitting a second
writer to the same file, while a crashed holder blocked accepts for a full
60s. Decide staleness by owner liveness, and release only our own lock.
Detector:
- isNeutralColor only parses computed color forms, so routing authored CSS
through it reported inset 4px 0 0 #000 / black / #e5e7eb as chromatic
side-tab stripes. Add an authored-color neutrality test covering hex and
named neutrals; the fixture had no literal-color cases at all.
- Rule line numbers were off by one for every rule after the first, and
commented-out CSS was scanned as live rules.
Server:
- An error reply carries no sourceEventType, and inferSourceEventType returned
undefined, which acknowledgePendingEvent treats as a wildcard: a stale
generate worker's failure consumed the user's queued Accept, which then
reached no agent and left the browser in SAVING forever.
- The generate preflight spawned live-wrap.mjs synchronously inside the request
handler, freezing the single-threaded server for the whole scaffold (~7.6s
measured on this repo, 15s ceiling) and stalling Accept/Discard/SSE. Make it
async, claiming the lease before the first await so no event double-delivers.
- Every browser checkpoint was echoed back as variant_progress, so a Tune
slider drag remounted the preview under the user's cursor and latched the
*_reviewable phases from the wrong trigger. Gate on the reason.
Cleanup:
- Collapse four divergent benchmark argv parsers into scripts/lib/cli-args.mjs.
Three silently misread flags: --iterations 20 benchmarked 5, --agent llm ran
the fake agent, --median-target=0.4 used the default threshold.
- Drop a snapshot cache this branch made write-only (it grew per session for
the server's lifetime and was never read), a dead exported reconcile helper,
and the unused deferReply branch.
Prepared with AI assistance under maintainer direction.
Co-Authored-By: Claude <noreply@anthropic.com>
* Add OpenAI plugin submission bundle
Build a Codex-native OpenAI plugin with bundled hooks, public listing metadata, submission guidance, privacy coverage, and regression tests.
AI assistance: OpenAI Codex prepared and validated these changes under maintainer direction.
* Fix provider script command rendering
Replace heuristic rewrites across executable scripts with one explicit provider marker, render pinned shortcuts per target harness, and remove the personal email from the public publisher manifest.
Addresses automated review feedback on PR #363.
AI assistance: OpenAI Codex prepared and validated these changes under maintainer direction.
Context files (PRODUCT.md / DESIGN.md) resolve child-first then fall back to the repo root, and /impeccable live lets the user pick a child app in a monorepo. Single-app behavior is unchanged. Closes#202. Co-Authored-By: abdulwahabone