Merge origin/main into ethie/pm-clean

Conflict resolutions and semantic fixups:

- utils.py / hermes_yaml.py: main widened ruamel's round-trip emitter so a long
  double-quoted scalar is never folded after an escaped backslash. pm-clean builds
  every rt emitter through hermes_yaml.roundtrip_yaml(), so the width lives there
  (ROUNDTRIP_YAML_WIDTH moves with it); xai_retirement imports it from hermes_yaml.
- hermes_cli/banner.py: keep pm-clean's removal of the banner update check. Main's
  GIT_NO_LAZY_FETCH fix for it applies to its replacement, source_check: every
  read-only probe (source_git_env) now refuses promisor lazy fetches, and the
  partial-clone test targets that probe (red without the flag).
- .github/workflows/tests.yml: keep setup-pm; main's uv pin bump does not apply.
  Main's WAL-capable SQLite gates are kept, run against $HERMES_PYTHON (the
  PM-pinned interpreter, SQLite 3.53.1). The e2e step takes main's
  --include-integration invocation.
- apps/desktop: package.json has no build block here, so main's macOS locale-marker
  restore joins the darwin branch of the existing after-pack.mjs, and its test
  loads the hook from electron-builder.config.cjs and imports PlatformPackager
  from app-builder-lib's root (electron-builder 27 exports no ./out paths). The
  win32 row is dropped: this hook sanitizes and signs PE trees on win32 by design.
- reconciliation.ts: main's rowId hydration (#119326) was merged into the first of
  pm-clean's split helpers only; the resolver is now one helper both halves use.
- en.ts: both sides' keys kept. tests/tools/test_lazy_deps.py stays deleted.
- Tests main added with `import yaml` use hermes_yaml, like the rest of the tree.
This commit is contained in:
ethernet
2026-09-23 19:51:34 -04:00
242 changed files with 19169 additions and 1063 deletions

View File

@@ -48,6 +48,15 @@ jobs:
test-environment: 'true'
prune-python-cache: true
- name: Check SQLite runs WAL
# Hermes picks DELETE journal mode on a SQLite with the WAL-reset
# bug. If the PM-pinned interpreter links one, every WAL test silently
# runs DELETE (or skips), so fail loudly instead. Tests that need DELETE
# select it explicitly (journal_mode config, a pinned vulnerable
# version), so they run on any interpreter.
run: |
"$HERMES_PYTHON" -c "import sqlite3, sys, hermes_state_wal as w; v = w.is_sqlite_wal_reset_vulnerable(); print(f'Python {sys.version.split()[0]}, SQLite {sqlite3.sqlite_version}, WAL-reset vulnerable: {v}'); sys.exit(1 if v else 0)"
- name: Restore per-file duration cache
# scripts/run_tests_parallel.py raises a file's timeout to
# 3x its last healthy duration (_effective_file_timeout) so a
@@ -115,12 +124,21 @@ jobs:
key: test-durations-${{ github.run_id }}
e2e:
runs-on: ubuntu-latest
timeout-minutes: 15
# The core suites spawn real serve / gateway / tui_gateway / MCP / SQLite
# writer processes per test; a 4-vCPU runner serialises them into timeouts.
runs-on: ubuntu-latest-32-core
timeout-minutes: 30
steps:
- name: Checkout code
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
- name: Set up Node
# The boot-contract suite feeds serve's stdout through Desktop's own
# backend-ready.ts (native TS stripping needs Node >= 22.18).
uses: actions/setup-node@49933ea5288caeca8642d1e84afbd3f7d6820020 # v4
with:
node-version: 26
- name: Install ripgrep (prebuilt binary)
run: |
set -euo pipefail
@@ -142,10 +160,27 @@ jobs:
test-environment: 'true'
prune-python-cache: true
- name: Run e2e tests
- name: Require a WAL-capable SQLite
# The state.db suites skip on a WAL-reset-vulnerable SQLite; fail
# instead of reporting green over zero coverage.
run: |
scripts/run_tests.sh tests/e2e/ -v --tb=short
"$HERMES_PYTHON" -c "import sqlite3, hermes_state_wal as w; print('sqlite', sqlite3.sqlite_version); assert not w.is_sqlite_wal_reset_vulnerable()"
- name: Run e2e tests
# One subprocess per file, in parallel: the core suites spawn real
# processes (serve, gateway, tui_gateway, MCP servers, SQLite writers)
# and must not share interpreter state.
run: |
scripts/run_tests.sh --include-integration tests/e2e
env:
# Multi-process episodes (torture chamber, compaction kill -9,
# gateway liveness, delivery exactly-once through a real gateway,
# the cron virtual-clock soak) legitimately run past the 300 s default.
HERMES_TEST_FILE_TIMEOUT: "900"
# No automatic re-run of a failed file: the torture chamber and the
# exactly-once/compaction suites are race detectors, and a rare
# corruption that passes on retry is still a corruption.
HERMES_TEST_FILE_RETRIES: "0"
OPENROUTER_API_KEY: ""
OPENAI_API_KEY: ""
NOUS_API_KEY: ""