v1.81.0

EvoMap/evolverv1.81.0May 16, 2026by autogame-17

AI Summary

Structural hardening includes establishing a single source of truth for prompt enums, adding cooperative yield locks, and implementing strict failure checks in the deployment pipeline.

Key Highlights

  • Created `src/gep/schemas/protocol.js` as the single source of truth for enums.
  • Daemon honors `.evolver.lock` file for cooperative cycle yielding.
  • Added release-window quiet period to prevent daemon interference during deployments.
  • Deploy script now fails fast before irreversible npm publish.
  • Startup diagnostics for Hub mirror status.

New Features

  • Single source of truth for prompt schemas.
  • Cooperative yield mechanisms.
  • Deployment pipeline hardening.

Full Release Notes

## [1.81.0] - 2026-05-16

This minor bump bundles two structural-hardening PRs that grew out of the
v1.80.7 → v1.80.9 development cycle. No new user-facing features —
everything here makes the existing protocol and release pipeline more
robust against the failure modes those releases revealed.

### Added — single source of truth for prompt-vs-code enums (#45)

`src/gep/schemas/protocol.js` is now the canonical home for every string
literal enum that lives both in JS validation code AND in the LLM-facing
prompt schema: `VALID_CATEGORIES` (re-exported from `gene.js`),
`VALID_OUTCOME_STATUSES` (from `capsule.js`), `VALID_RISK_LEVELS`,
`VALID_TRACE_STAGES`. Plus `renderEnum()` / `renderEnumList()` helpers.

`prompt.js`'s `SCHEMA_DEFINITIONS` is no longer a const string with the
enum literals baked in — `buildSchemaDefinitions()` interpolates from
`protocol.js` at load. `mutation.js`'s `isValidMutation` and
`normalizeMutation` import the enums instead of inlining them. The
stale "keep this in sync with schemas/gene.js" warning comment in
`solidify.js` is removed because the rule is now structural.

A new `test/schemaPromptConsistency.test.js` adds 4 cases that fail loudly
if any future contributor reintroduces a hardcoded enum literal in
`prompt.js`, drifts `protocol.js` from the underlying schema files, or
removes a category from the canonical whitelist without auditing
`strategy.js` presets. Fundamentally closes the bug class that produced
the v1.80.7 → v1.80.8 explore-mode-drift incident.

### Added — cooperative yield via `.evolver.lock` (#46, P1-1)

The `evolver --loop` daemon now honors a cooperative file lock at
`<repo>/.evolver.lock`. Whoever creates the file (the user, a release
script, an IDE refactor task) owns the cycle for as long as it lives. The
daemon yields the entire cycle without touching the working tree. Stale
locks older than `EVOLVE_USER_LOCK_TTL_MS` (default 1h) are auto-ignored
so a forgotten file does not permanently dormant the daemon. NaN /
non-positive / suspiciously-small (`< 1000ms`) TTL values are rejected
with a clear console diagnostic, so users who write
`EVOLVE_USER_LOCK_TTL_MS=5m` (which `parseInt` quietly turns into 5)
see why the lock is being ignored.

### Added — release-window quiet period (#46, P2-5)

If the most recent commit on the current branch matches
`/^chore\(release\)/i` AND was committed less than
`EVOLVE_RELEASE_WINDOW_MS` ago (default 5min), the daemon yields the
cycle on its own — no manual lock needed. Stops the daemon from
auto-creating `fix/*` branches or modifying `solidify.js` mid-deploy
when `publish_public.js`'s `ensureClean()` is about to assert a clean
working tree. Same NaN / parseInt-prefix / clock-skew protection as
the user lock above.

### Added — Hub mirror startup diagnostic (#46, P1-2)

Daemon startup now emits one explicit `[HubMirror]` line saying whether
outcome / attempt / solidify / skill_emit events will be mirrored to
`<hub>/a2a/memory/event` (default ON via `MEMORY_GRAPH_SYNC_HUB`). For
the inactive case the line names which credential is missing (hub URL,
node_id, or node_secret). No behavior change — the mirror was already
on by default — but the state is now observable.

### Hardened — `scripts/deploy.sh` fails fast before npm publish (#45)

Step 5 (`publish_public.js`) and step 7 (npm publish) used
`|| echo "WARN"` to swallow failures, which let a failed GitHub Release
step be followed by a successful `npm publish` — leaving the registry
pointing at a version with no GitHub release. `npm publish` cannot be
undone, so this was a real one-way state. v1.80.8 actually hit this when
`publish_public.js` failed with a missing-git-identity error in the
temp publish repo, but deploy continued and shipped npm@1.80.8 anyway.

Two layered defenses now apply: (1) step 5 exits 1 with an actionable
error if `publish_public.js` returns non-zero, instead of WARN-and-continue;
(2) step 7 runs `gh release view v$VERSION` as a precondition before
invoking `npm publish` and refuses to ship if the GitHub Release is
missing or in draft state. Step 7 itself also fails fast if `npm publish`
errors. Step 6 (binary upload) intentionally keeps WARN-and-continue
because it is recoverable via `gh release upload --clobber`.

### Why minor not patch

This release introduces two new env-var contracts (`EVOLVE_USER_LOCK_TTL_MS`,
`EVOLVE_RELEASE_WINDOW_MS`), one new operational primitive (`.evolver.lock`),
and a new public schema module (`src/gep/schemas/protocol.js`). All are
backwards-compatible additions, but operators may want to know the contract
surface grew. patch would have understated the change.