feat: add lineage-aware session search hits - #12
Merged
XelHaku merged 1 commit intoApr 25, 2026
Merged
Conversation
XelHaku
deleted the
autoloop/20260425T024216Z/w5/3-3.e.8-lineage-aware-source-filtered-search-hits
branch
April 25, 2026 07:48
XelHaku
added a commit
that referenced
this pull request
Apr 25, 2026
Implements items #4, #7, #14, #15 from docs/cmd-loops-improvements.md plus a partial #12 (parser errors map to exit code 2; richer codes for backend timeout / verify failure are deferred until internal packages emit semantic errors). #4 — Graceful shutdown: * main() wraps context.Background() with signal.NotifyContext for SIGINT/SIGTERM; the context is plumbed through run, runAutoloop, builderloop.RunOnce, plannerloop.RunOnce, and the service install paths. systemd's TimeoutStopSec now gives the backend a clean cancellation chance instead of jumping straight to SIGKILL. #7 — Keywords in planner summary: * printRunSummary echoes "keywords: <values>" when any are set so operators can confirm topical-focus mode actually engaged. #14 — --repo-root / REPO_ROOT: * Both binaries accept --repo-root <path> anywhere in argv (consumed before subcommand dispatch) and fall back to REPO_ROOT then os.Getwd. systemd units no longer have to rely on WorkingDirectory= alignment to operate. #15 — digest --output clobber guard: * Replaced os.WriteFile (silent overwrite) with O_CREATE|O_EXCL. --force opts back into truncate-and-overwrite. Default protects against fat-fingered paths like '--output README.md'. #12 (partial) — Parser errors → exit 2: * Introduced errParse sentinel in each binary. main() maps errors.Is(err, errParse) to os.Exit(2); everything else still exits 1. Future work: tag config errors / no-candidates / backend timeout / verify-failed once the internal packages surface them distinctly. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
XelHaku
added a commit
that referenced
this pull request
Apr 25, 2026
#12 — Structured exit codes (now full delivery): * New ErrPostPromotionVerifyFailed sentinel in internal/builderloop; runPostPromotionVerifyAndRepair joins it with the underlying error on terminal verify failure so cmd/ can errors.Is detect it. * classifyExit helper in both binaries maps: errParse → 2 (parse / config) builderloop.ErrPostPromotionVerifyFailed → 30 (builder-loop only) context.DeadlineExceeded / Canceled → 20 (backend timeout) anything else → 1 (internal) * "no-work=10" intentionally NOT emitted: a 0-candidates idle tick is normal, and systemd Restart=on-failure would flap. Documented in the improvements doc. #13 — --format json (now full delivery): * digest: builderloop.DigestLedgerCounts(path) added as the structured companion to DigestLedger; cmd emits the full event -> count map as JSON. * audit: cmd emits {"summary":"<text>"}; structured audit ledger already exists at <auditDir>/report.ndjson + report.csv, so the wrapper just gives scripts a stable JSON object. * status: cmd emits {"status":"<text>"}; structured planner state lives in planner_state.json. * digest gets a --format flag in addition to the existing --output/--force, with a JSON-also-respects-clobber-guard path. Tests cover classifyExit for all four cases per binary. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
XelHaku
added a commit
that referenced
this pull request
May 9, 2026
#12: `gormes gateway xyz --json` rejected `--json` as "unknown flag" because gateway parent has its own RunE (`runGateway`) so cobra parses flags BEFORE subcommand routing. The user's intent — "I asked for JSON output of an invocation containing --json" — must still produce JSON. Wrapper at executeRootCommand now also recognizes the cobra `unknown flag: --json` pattern and emits the same `{build, action: "unknown_subcommand", error}` document. #13: `sh install.sh --uninstall` (no flags) ran `gormes uninstall` which defaults to dry-run, leaving the operator looking at a preview and assuming cleanup happened. Asymmetric vs. install which actually installs by default. run_uninstall now scans the passthrough args for an explicit `--dry-run` opt-in and prepends `--yes --dry-run=false` when absent, preserving caller intent (`install.sh --uninstall --dry-run` still previews). RED → GREEN coverage: - TestFreshInstallE2E_InvalidInputJSONEmitsStructuredError gains a `gateway_unknown_subcommand_json` subtest. - TestInstallSh_UninstallDefaultsToApply runs install.sh against a recording shim and asserts the three contracts: bare apply, --dry-run preserved, passthrough flags survive. Found during v0.2.0 fresh-install e2e probe. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
XelHaku
added a commit
that referenced
this pull request
May 9, 2026
…sues (#178) * chore: bump hermes-agent submodule for hooks.py lifecycle parity Pulls upstream hermes-agent to faa13e49f for verified hook event dispatch line references used in agent lifecycle hooks contract validation. * flutter: Navivox key store providers and keys screen update Adds Riverpod-based key store providers (identityStoreProvider, serverStoreProvider) with stream-based watch pattern. Updates KeysScreen to ConsumerWidget showing imported servers and identities, with empty state for no keys. * feat(update): pre-update backup retention pruning (keep newest 5) After each successful pre-update backup write, the production adapter now prunes older backup zips so the directory doesn't grow forever. Default retention: 5 (matches Hermes' `updates.backup_keep` default). What's added: - internal/cli PruneBackups(backupDir, keep) (count, freed, err) helper: - Filters by `pre-update-*.zip` filename pattern (operator-owned files in the same directory survive untouched). - Sorts candidates by mtime, keeps newest `keep`, removes the rest. - keep <= 0 → no-op safety (operators who pass --backup-keep 0 by mistake should not lose data). - Missing directory → no-op (fresh installs with no prior backups). - Per-file remove errors are silently skipped — pruning is best-effort and must not block update completion. - internal/cli BackupResult extended with PrunedCount + PrunedBytes. - internal/cli emitPreUpdateBackupPolicy detail formatter appends `; pruned N older (M freed)` only when PrunedCount > 0; the no-prune common case (first --backup, recently-cleaned state) keeps the transcript short. - cmd/gormes defaultBackupWriterFor calls PruneBackups after a successful WriteBackupZip with keep=defaultBackupKeep (5). Tests: - internal/cli/backup_prune_test.go (5 unit tests): - KeepsNewestN: 5 fixtures with monotonic mtimes, keep=2 → 3 removed, newest 2 survive. - NoOpWhenAtOrUnderKeep: 1 file, keep=5 → no-op. - IgnoresNonBackupFiles: operator's NOTES.md + manifest.json + other-archive.tar.gz survive a prune that reduces 3 backup files to 1. - KeepZeroIsNoOpSafety: keep=0 and keep=-1 both no-op. - MissingDirReturnsNoOp: non-existent dir returns (0, 0, nil). - internal/cli/update_lifecycle_backup_writer_test.go (2 lifecycle tests): - BackupCompletedDetailIncludesPruneInfoWhenPositive: PrunedCount=3 surfaces "pruned 3 older" + "freed" in evidence detail. - BackupCompletedDetailOmitsPruneSuffixWhenZero: PrunedCount=0 emits no prune phrasing. End-to-end verification with a sandbox HOME seeded with 6 backup files: ⚕ Updating Gormes Agent... update branch: main ✓ update_pre_backup_completed /tmp/.gormes/backups/pre-update-20260508T014058Z.zip (329B, 2ms); pruned 2 older (240B freed) After run: 5 files in backups/ (newest 5 of the 6 seeds + 1 new write, 2 oldest removed) — matches the keep=5 contract exactly. Future-natural follow-up: wire `updates.backup_keep` from real config into a configurable retention budget (currently hardcoded to 5). Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> * feat: plugin lifecycle hook transform_llm_output with TDD fixtures * docs: mark transform_llm_output complete, unblock 7 parity rows, regenerate surfaces * feat: gateway allowed_chats whitelist config and update test coverage * fix(update): survive missing config.toml on fresh install * feat(signal): add signal-cli HTTP JSON-RPC + SSE bridge bootstrap layer Implement the fakeable Signal transport/bootstrap layer that bridges the existing signal.Bot seam to the signal-cli HTTP daemon. Five TDD acceptance tests cover config/health/lock lifecycle, SSE URL encoding, attachment fetch params, reconnect/recovery, and outbound send with typing-stop through a fake HTTP transport. Progress: Phase 7.A Signal subphase is now fully complete (4/4 rows). * fix(progress): update Phase 7.A test expectations for completed Signal bootstrap row * docs: close 6 inert umbrellas (5.O + 5.V), mark Matrix seam complete, regenerate surfaces * fix: add hermes gateway list to CLI parity manifest and tests * feat(matrix): add shared-chassis bot seam over threadtext contract * chore: pre-existing update lifecycle, backup writer, config writer changes * feat: add restore command, backup restore lifecycle, and update tests * chore: pre-existing status command changes * feat(restore): dry-run validates zip before printing would-extract Restore dry-run (without --yes) now validates the zip archive is openable and free of path-traversal entries BEFORE showing the "would extract" message. A corrupt or malicious zip will now surface the rejection immediately instead of misleading the operator. * feat(auth): add --json flag to auth status for machine-readable output gormes auth status <provider> --json now emits a parseable JSON document with the same redacted credential fields the human surface renders. Enables credential-health monitoring in CI/cron without scraping the human row. * fix(restore): add zip pre-validation to RestoreFromZip extract path Extends restore zip validation to the actual extract path (not just dry-run). Pre-validates the entire archive before extracting any files, so a malicious entry late in the zip cannot land earlier safe entries on disk. * refactor(doctor): route output through cobra writers, use newExitCodeError instead of os.Exit * feat(doctor): add JSON output mode and constructor command pattern - internal/doctor: add StatusSkip, MarshalJSON, and JSON struct tags - cmd/gormes/doctor: refactor doctorCmd to newDoctorCommand() constructor with doctorReporter for dual text/JSON output, eliminating shared var test contamination - cmd/gormes: wire newDoctorCommand() in root, update tests to use newRootCommand() with subcommand args - cmd/gormes/doctor_runE_test: add fleet-health JSON assertion test * test(doctor): add failed-field assertion for JSON monitoring contract * feat(doctor): track failed bool in JSON output for monitoring parity * feat(doctor): add drSeverity and pending incremental JSON refinements * feat(version): add git_commit field to --json output for fleet binary verification * feat: add git_commit field to --json version output and refactor versionCmd to constructor pattern - Refactor versionCmd from package-level var to newVersionCommand() constructor to prevent cross-test flag contamination (same anti-pattern that broke doctorCmd before its constructor refactor) - Add TestVersionCommand_ConstructorReturnsIndependentInstances test - Add git_commit field to versionReportJSON, populated via ldflag in CI/Makefile - Update deploy-gormes-www.yml, release.yml, Makefile build commands with -X main.GitCommit=${GIT_COMMIT} - Update release_workflow_test.go contract to expect GIT_COMMIT ldflag * refactor: convert memoryCmd to newMemoryCommand constructor pattern - Refactor memoryCmd from package-level var to newMemoryCommand() constructor to prevent cross-test flag contamination (same anti-pattern as versionCmd) - Convert memoryStatusCmd to newMemoryStatusCommand() constructor - Add TestMemoryCommand_ConstructorReturnsIndependentInstances test - Wire newMemoryCommand() into root command registration * refactor: remove resetGonchoDoctorFlags workaround, wire newGonchoCommand constructor - Remove resetGonchoDoctorFlags() call that the constructor pattern made obsolete - Wire newGonchoCommand() in place of gonchoCmd in root command registration - Add TestGonchoCommand_ConstructorReturnsIndependentInstances test * refactor: convert sessionCmd and remove old gonchoCmd package-level vars - Convert sessionCmd + subcommands to newSessionCommand() constructor tree (list, export, delete, prune, browse all get constructor functions) - Remove resetSessionsCommandFlagState() workaround now made obsolete - Add TestSessionCommand_ConstructorReturnsIndependentInstances test - Remove old gonchoCmd/gonchoDoctorCmd package-level vars now superseded by newGonchoCommand()/newGonchoDoctorCommand() - Wire newSessionCommand() into root command registration * refactor: convert gatewayCmd and telegramCmd to constructor pattern Replace gatewayCmd and telegramCmd package-level vars with newGatewayCommand() and newTelegramCommand() constructors. Move init()-based subcommand wiring and flag registration into the constructors so each newRootCommand() instance gets a fresh independent tree. Add a constructor-isolation test proving the gateway tree owns 10 distinct children per call (6 real + 4 mutating-unavailable placeholders). * feat: add Mattermost shared-chassis bot seam with dedup and mention gating New internal/channels/mattermost package adds a Seam over threadtext for Mattermost posted-event parsing before REST/WS transport. Handles double-encoded posted event JSON, drops self/system/duplicate posts, preserves root_id as canonical thread_id, models reply_mode=thread vs off, and uses pure-input mention gating (DM/free-channel/require-mention decisions). 15 fixture tests exercise the full event lifecycle including cancel hook suppression, allowed-channel whitelist enforcement, and @mention stripping. * feat: add git_dirty field to version --json, backup writer, and CLI test coverage - version --json: add git_dirty, go_version, os, arch fields - doctor: improve runE flow with additional diagnostics - restore: expand restore command with backup writer integration - status/update/auth/secrets: improve CLI command coverage - internal/cli: backup_writer, backup_restore, active_profile, busy_command, update_lifecycle enhancements with test coverage - CI: update release and deploy workflows - Makefile: build target updates * docs: sharpen 3 Phase 5 umbrella rows with 2026-05-07 parity source_refs, complete Mattermost seam Planner pass: add upstream source_refs to Skill registries (skills_tool.py, skill_commands.py, etc.), Dangerous action gating (approval.py, tirith/), and Atomic checkpoints (checkpoints.py, checkpoint_manager.py) umbrella rows. Builder pass: complete Mattermost shared-chassis bot seam row (7.7.C). Fifteen fixture tests prove posted-event parsing, dedup, self/system drops, mention gating, reply-mode thread/off, and hook cancellation. Regenerate all derived progress surfaces (agent queue, next slices, blocked slices, umbrella cleanup, landing data, contract readiness). * fix: harden builder-loop test runner cleanup with unconditional SIGKILL * fix: distinguish missing/corrupt zip in restore error messages ValidateRestoreZip, RestoreFromZip, and SummarizeRestoreZipImpact now surface 'zip not found: <path>' for missing files versus 'zip unreadable: ...' for corrupt archives. Previously both cases chained the os.Open wording behind a duplicate 'open' prefix, forcing operators to decode nested error chains to triage. * chore: add missing encoding/json import to auth command test * feat: add --json flag to auth list and profile show/list auth list --json emits {build, provider, credentials:[...]} with pre-redacted credential status. profile show --json emits {build, active, root} with redacted root path. profile list --json emits {build, active, profiles:[{name, active},...]} for fleet automation. * fix: fast-fail backup writer with operator-friendly missing source error * fix: bump discord e2e poll timeouts to eliminate flakes under parallel load * docs: add Checkpoints CLI parity row (P2, builder-ready) to progress.json * fix: add HTTP client timeout to logs command, refactor uninstall to use io.Writer * test: add goncho doctor test coverage * fix: goncho doctor production wiring * feat: add gormes checkpoints CLI (status/list/prune/clear/clear-legacy) * docs: mark Checkpoints CLI row complete with evidence * fix: parallel agent improvements (channels, gateway, usage, uninstall fixes) * feat: add provider client lazy-init pool for cold-start budget internal/provider/lazy_client.go: ClientPool with Register/Get/Reset that defers provider HTTP client construction until first access. Only the selected provider is constructed; unselected providers never invoke their factory. internal/provider/lazy_client_test.go: 6 tests covering does-not-construct-unselected, constructed-once, reset-for-testing, unknown-provider, factory-error, and concurrent-access. internal/runtime/coldstart_bench_test.go: BenchmarkGormesColdStart enforces a 5ms budget on 10-registered-provider cold start. cmd/gormes/provider_client.go: wires getOrCreateProviderClient into the oneshot path via newOneshotHTTPClient. hermes/client.go: adds ErrProviderUnavailable sentinel. Source: Hermes v0.12.0 PR #17046 (lazy OpenAI/Anthropic/Firecrawl) inside the ~57% TUI cold-start cut. * docs: mark Provider client lazy-init row complete, regenerate progress surfaces 5.Q row: contract validated, write_scope corrected, row implemented and marked complete with full evidence. Progress surfaces regenerated via go run ./cmd/progress write. * feat: setup reset breadcrumb, memory/restore/session enhancements setup.go: reset config preserves prior config as breadcrumb file, ResetConfig returns (string, error) to surface the backup path. setup_reset_breadcrumb_test.go: tests for breadcrumb output. memory/restore/session: operator-facing command enhancements. * feat: checkpoint manager enhancements with pruned-orphan threshold * feat: add --json flag to checkpoints prune, clear, and clear-legacy commands Emit machine-readable JSON for operator scripts performing GC, CI/CD jobs running destructive prunes, and dashboards auditing checkpoint state without scraping human-readable prose output. * feat: add video_analyze tool with vision provider routing seam Implements tool (P2, Phase 5.D) that accepts a video path or HTTPS URL plus prompt, checks provider vision capability, and returns analysis text or typed evidence. Fixture-proven against fakeVideoAnalyzeProvider with vision routing, unsupported provider rejection, workspace path sanitization, and URL scheme allowlist. Registered alongside image_generate in the default tool registry. No real Gemini transport — provider seam ready for downstream adapters. * feat: add --json flag to agent, config, curator, gateway, and uninstall commands Extends the machine-readable JSON output contract to agent reset, config show, curator status, gateway reload, and uninstall commands. Each emits a structured build-provenance-led envelope for operator scripts, fleet automation, and dashboards. * docs: mark video_analyze row complete, regenerate progress surfaces Updates progress.json: video_analyze tool contract_status→validated, status→complete. Regenerates all derived progress docs and site data via go run ./cmd/progress write. Parity sweep timestamp updated. * feat: complete curator --json output parity * feat: add --json flag to plugins list for fleet automation auditing * test: add JSON-structured-report test for skills sync --json * feat: add --json flags for skills sync, session delete, session prune * feat: add --json flags to auth logout/remove/reset, plus curator and gateway-stop improvements * feat: add --json machine output to curator and profile commands for fleet automation * chore: bump hermes-agent submodule reference * feat: add --json flags to auth, kanban, logs, mcp-login, navivox, plugins, setup, usage, and whatsapp commands * feat: add --json flag to onboard command for fleet automation * feat: add /kanban gateway slash command with store-backed subcommands * feat: add --json flags to acp, gateway-discover, and logout commands * docs: mark kanban slash row in_progress, regenerate progress surfaces * feat: add build provenance to migrate JSON output for fleet automation * feat: extend build provenance to migrate cleanup, security, and system JSON output * docs: parity sweep: sharpen 5.M kanban refs, add specify row, bump hermes-agent submodule * feat: add build provenance to session export --json output * feat: add build provenance to config show/edit --json output * feat: add --json flag to skills list command for fleet automation * feat: add build provenance to kanban CLI JSON output * feat: add kanban dashboard API routes with lane summary and task list * docs: parity sweep: clear stale Kanban blockers, add dashboard route evidence, regenerate progress surfaces * feat: add --json flag to navivox setup-host for fleet automation provisioning * feat: add build provenance to dashboard kanban and status API responses * chore: bump hermes-agent submodule (auth fix + cron routing intent) * feat: add LoadNousOAuthCredentials to round-trip persisted Nous OAuth device-code state * feat: extend build provenance to cron admin, plugin inventory, and model dashboard endpoints * docs: parity sweep sharpen Kanban evidence, add Nous OAuth row, regenerate progress surfaces * feat: expose BuildInfo on /health and /v1/capabilities responses * feat: add BuildInfo to /health/detailed response model and tests * feat: implement Nous OAuth device code login, refresh, and agent key minting * docs: parity sweep cleanup + Nous OAuth row complete + hermes-agent submodule refresh * feat: apiserver build provenance + CLI skills URL install + progressctl enhancements * feat: port Hermes i18n static-message system to Go - internal/i18n/: core package with T(), language resolution (explicit lang arg > GORMES_LANGUAGE env > SetConfigLanguage > en), YAML catalog loading with dotted-key flattening, 8-language support (en/zh/ja/de/es/fr/tr/uk) with full alias table - locales/: 8 YAML catalogs ported from hermes-agent/locales/ covering approval prompts and gateway slash replies - internal/config/config.go: add display.language to DisplayCfg - 15 tests: fallback chain, catalog parity, format substitution, env/config resolution, missing file, broken YAML * docs: parity sweep, i18n row, Kanban fixture fix, dashboard, bump hermes-agent - All-topic Hermes/Gormes parity sweep: i18n identified as source-backed missing feature (Hermes has agent/i18n.py with 8 languages; Gormes had zero i18n) - progress.json: added Phase 5.W i18n row (P2, builder-ready), fixed Kanban in_progress row phantom fixture paths (removed non-existent internal/gateway/kanban_command_test.go, internal/tui/kanban_slash_test.go, internal/dashboard/; pointed at real files) - 23 vague planned rows identified (no write_scope) for future sharpening - Kanban dashboard: capabilities endpoint tests, dashboard.go, dashboard_contract_test.go, runs.go from ongoing Kanban work - hermes-agent: submodule bumped to a3131862b (upstream parity sweep baseline) - Regenerated all progress-driven docs and site data (go run ./cmd/progress write) * fix: publish run.stopped SSE event before closing subscribers runRegistry.stop() now records a typed run.stopped lifecycle event into the SSE backlog before closing subscriber channels so SSE consumers see a terminal event symmetrical with run.completed and run.failed. Fleet automation surfacing run lifecycles depends on this typed terminus. * feat: include build provenance in legacy /api/jobs responses Legacy /api/jobs list and get endpoints now include build info at the top of their JSON envelopes so fleet automation can attribute responses to binary version. * feat: add run lifecycle counters to health endpoint (completed, failed, stopped) * feat: add run event lifecycle counters to detailed health API * feat: auto-populate run lifecycle counters from runRegistry in /health/detailed * feat: add strict-mode CWD and interpreter parity contract with TDD fixtures * feat: add request_total and enhanced run events tracking to health API * docs: regenerate progress surfaces after strict-mode parity sweep * feat: advertise runs_list filters in /v1/capabilities for SDK discovery * feat: add terminated_at to run status for dashboard duration computation * feat: fail closed with terminal_cwd_deleted when configured cwd is deleted * docs: parity sweep, terminal cwd guard complete, goal-loop row added * chore: bump hermes-agent submodule for parity sweep baseline * feat: support multi-value status filters in runs list endpoint * feat: expose session_id in run registry snapshots and API responses * chore: bump hermes-agent submodule for parity sweep baseline * feat: add session_id filter to runs list, advertise run lifecycle events in capabilities * feat: add Kanban multi-board registry with slug validation, board isolation, and CLI surface * feat: add oldest_active_age_seconds to health endpoint, refine session_id runs filter and lifecycle events * docs: parity sweep — mark skill registries row complete, convert to builder-ready evidence * feat: expose tool_calls_count in run status endpoint * feat: add SSE prelude snapshot to run event stream * feat: enrich run event streams * chore: rename builder loop scripts * feat: add google chat channel seam * fix: avoid dashboard flag shorthand collision * fix: align installer public surface tests * fix: include panic excerpt in crash stderr * fix: route Goncho sqlite opens through busy-timeout helper * feat: add Matrix sender filter parity * fix: clarify update check copy * feat: add Microsoft Graph helper parity * fix: show empty kanban list placeholder * fix: reject unknown active profiles * fix: fall back to build vcs metadata * feat: expand cron deliver all routing intent * feat: surface profile distribution metadata * fix: reject plugin subcommand typos * fix: reject parent command typos * feat: add config get command * fix: show unset config values * test: isolate tui save export fixtures * fix: treat missing turns table as empty * test: cover legacy xdg uninstall cleanup * fix: remove legacy xdg state on uninstall * fix: treat fresh install state as empty * test: isolate discord channel home state * feat: track msgraph webhook platform drift * fix: suggest parent command typos * fix: report empty goncho system status * feat: emit onboard wizard json plan * fix: avoid duplicate mcp login errors * chore: ignore whatsapp bridge node modules * fix: normalize cli json degraded states * docs: document native Windows installer * tools: refresh Hermes ea86714 parity manifest * fix: normalize gateway discovery json beacons * fix: normalize gateway status json empties * test: cover fresh install json inventory surfaces * feat: emit config get json * test: assert json surfaces carry build provenance * feat: track teams pipeline plugin metadata * test: refresh docs home install assertion * feat: add TUI websocket attach transport * fix: emit kanban not-found JSON * feat: add matrix bootstrap parity boundary * docs: refresh Hermes Teams docs mirror * feat: add mattermost bootstrap boundary * ci: add termux release artifact coverage * docs: lead README with methodology positioning * web: align landing with methodology positioning * feat: add project-mode execute code sandbox * feat: normalize cron approval mode * feat: bind native tui kanban slash command * test: make logs fallback test deterministic * docs: close Windows installer parity row * feat: add Windows gateway scheduled task lifecycle * fix: route gateway kanban through shared runner * feat: wire execute code mode config * test: stabilize kanban dispatcher shutdown checks * feat: add kanban dashboard dispatch quick path * fix: port shift-enter tui newline parity * docs: reconcile shift-enter parity row * fix: align TUI quit slash with Hermes * test: refresh Hermes patch tool parity manifest * feat: serialize Hermes fast-mode overrides * feat: add Kanban triage specify parity * test: stabilize Discord manager smoke * ci: enforce release archive size cap * docs: close release archive size gate row * ci: add release notes artifact sizes * feat: add slack manifest generator * release: prepare v0.2.0 (v2026.5.8) Minor bump 0.1 → 0.2 marks the move from case-by-case bug fixing to a CI-guarded contract for the --json arc. The autonomous engineering loop now ships its own conformance fence: - Six-battery fresh-install E2E suite (cmd/gormes/fresh_install_e2e_test.go) asserts no-null-arrays, typo-suggestions across 9 parents, fresh-install read-only exit-zero, build-provenance prepended on every captured-state --json document, parseable JSON on stdout, and structured {action: "not_found"} on lookup failures. - Native Windows installer (scripts/install.ps1) is first-class alongside install.sh. - gormes config get --json: structured {build, key, value, secret_redacted, set} with secret-key redaction. - Fresh-install UX uniform across legacy XDG migration, missing-DB read paths, and parent-command typo handling. Landing.js + Playwright reverted to v0.1.07 baseline. Methodology landing rewrite is a separate post-release slice; this release ships the fence, not the pitch. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> * fix: bound gateway startup disconnect cleanup * fix: route kanban commands through current board * feat: inject release build date provenance * fix: target install's managed checkout in gormes update, not cwd `gormes update` defaulted CheckoutDir to os.Getwd, walking up from whatever directory the operator invoked the command from. Run from inside the gormes-agent dev tree, it switched the tree's branch from `development` to `main` and ran a web build there — mutating the user's source instead of the install. resolveManagedCheckoutDir() mirrors install.sh's managed_checkout_dir(): GORMES_INSTALL_DIR override → $GORMES_INSTALL_HOME/gormes-agent → $HOME/.gormes/gormes-agent. Never falls back to cwd. The lifecycle's existing update_not_managed_checkout guard correctly fails the run when the resolved path isn't a git worktree (e.g., on a binary-fetch install with no managed clone). Two RED → GREEN tests pin the contract: - env-var override path (GORMES_INSTALL_DIR wins outright) - default fallback path (managed_home/gormes-agent, never cwd) Found during v0.2.0 fresh-install probe. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> * fix: remove dangling published-binary symlink during uninstall `gormes uninstall --yes` removed the managed binary at `<home>/bin/gormes` but left the install.sh-published PATH symlink at `~/.local/bin/gormes` dangling. After uninstall, `which gormes` returned empty, but the broken symlink persisted and confused reinstalls and shell completions. New `published-binary` artifact group enumerates the install.sh PATH-linked locations: - $GORMES_BIN_DIR (operator override; install.sh exports this) - $GORMES_PREFIX/bin (compatibility prefix) - $HOME/.local/bin (non-root default) - /usr/local/bin (root linux default) Surgical safety: only entries that are SYMLINKS whose target resolves into the gormes home are returned. A real binary at the same path (built from source, package-managed, manually placed) is never touched. Two RED → GREEN tests pin the contract: - TestUninstall_RemovesPublishedBinarySymlink — symlink → managed binary gets removed and listed in the JSON outcome. - TestUninstall_LeavesUnrelatedGormesBinaryAlone — non-symlink at the same path is preserved. Found during v0.2.0 fresh-install probe. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> * fix: bind Matrix E2EE bootstrap device id Complete the Matrix E2EE device-id crypto-store progress row with TDD coverage for resolved runtime device IDs, configured override behavior, missing-device degradation, and store-level put_device_id binding. Validated with go test ./... -count=1, go run ./cmd/progress validate, git diff --check, Matrix row tests, and docs/landing public-surface gates. * fix: publish install.sh and install.ps1 as release assets A curl following the natural GitHub release URL pattern https://github.com/.../releases/download/v0.2.0/install.sh returned 404 — install.sh and install.ps1 were not GitHub release assets, only landing-served at https://gormes.ai/install.sh. Users following the README's tagged-release URLs hit a wall and had to already know about the landing path to bootstrap. Publish step now stages install.sh + install.ps1 into dist/ before the softprops upload, and the release-notes block surfaces the canonical curl/irm one-liners so the install URLs are discoverable from the GitHub release page itself. RED → GREEN test in webpages/docs/install/release_workflow_test.go asserts both scripts appear in the upload glob and the release notes. Found during v0.2.0 fresh-install probe. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> * feat: add singularity command preflight contract * feat: add Camofox browser bridge * fix: pause interrupted gateway goals * fix(tui): trim soft-wrap markdown spaces * feat: add kanban run history command * feat: add kanban boards read model * docs: add nix flake packaging contract * feat: add kanban board override flag * fix: preserve kanban named board roots * fix: cap gateway shutdown disconnects * ci: attest release sboms * docs: close release sbom attestation row * feat: add kanban dashboard run history * feat: add kanban gc retention * fix: release signal lock before close returns * feat: prefer Windows release binary installs * feat: honor cron approval mode for terminal tools * ci: add OCI image smoke workflow * feat: add QQ Bot transport bootstrap seam * test: guard cron origin delivery identity * fix: normalize partial cron job records * web: add cron dashboard page * fix: preserve Telegram DM topic routing * ci: attest release build provenance * feat: support delegate task batches * fix: align kanban comment handoff policy * docs: close delegate task batch parity row * fix: preserve google chat relay sender type * feat: add gateway approval queue resolver * feat: add cron standalone sender fallback * feat: complete behavioral pattern extraction * feat: add profile clone-all create policy * web: add built-with Gormes proof page * fix: mirror telegram streaming edit safety * web: sync release date alias * feat: add Feishu update prompt cards * docs: sync release prep target matrix * feat: add curator archive prune commands * fix: coerce stringified tool-call arguments * feat: add kanban stats command * docs: close Kanban operator surface row * feat: add claw cleanup compatibility * fix: default top-level logout provider * docs: close logout fallback progress row * feat: add V4A patch mode to native patch tool * fix: deliver fast discord final frames * feat: classify minimax oauth provider * feat: restore fallback provider CLI * fix: align Telegram table row-label rendering * feat: add Google Chat standalone cron sender * feat: support V4A patch moves * chore: sync release benchmark metadata * feat: clear slash confirmations on reset * Emit JSON for invalid input errors * Add Kanban notify subscriptions * feat: add structured lint evidence to file tools * fix: surface home-tree wildcard under honest `gormes-home` group `gormes uninstall --json` preview classified the home-directory wildcard `<home>/` under the "logs" group (because config.CrashLogDir() returns GormesHome()). Fleet automation reading {"name": "logs", "paths": ["/home/xel/.gormes/"]} reasonably interpreted that as "removes log files," but `os.RemoveAll("<home>")` actually nukes the entire home tree: config, sessions, skills, subagents, kanban DB, the managed binary subdirectory — everything not enumerated by another group. Renamed split: - "logs" now lists only explicit log files (gormes.log) - new "gormes-home" group lists the home-tree wildcard with a truthful name; ordered last so per-feature groups appear first and the wholesale-removal scope is unambiguous. RED → GREEN test pins the contract: - TestUninstall_HomeDirWildcardIsNotMisclassifiedAsLogs Found during v0.2.0 fresh-install probe. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> * fix: emit JSON on cobra typo-with-suggestion under any parent `gormes config gat --json` and `gormes kanban shor --json` escaped the v0.2.0 conformance fence: cobra's built-in `findSuggestions` short-circuits in `Find()` and returns `unknown command "gat" for "gormes config"; did you mean "get"?` directly to Execute() — bypassing the parent's RunE guard installed by `installParentUnknownSubcommandGuards` (which only fires on the no-suggestion case). `executeRootCommand` now post-processes the Execute() error: when --json is in args AND the error matches cobra's `unknown command "X" for "Y"` pattern, it emits the same `{build, action: "unknown_subcommand", error}` document the parent guard would have produced. errors.As(exitCodeError) skip prevents double-emit when an inner RunE already handled it (mcp parent). Two RED → GREEN subtests in the existing conformance fence: - config_typo_with_suggestion (config gat → get) - kanban_typo_with_suggestion (kanban shor → show) Found during v0.2.0 fresh-install e2e probe. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> * fix: cover gateway --json edge + install.sh apply-by-default #12: `gormes gateway xyz --json` rejected `--json` as "unknown flag" because gateway parent has its own RunE (`runGateway`) so cobra parses flags BEFORE subcommand routing. The user's intent — "I asked for JSON output of an invocation containing --json" — must still produce JSON. Wrapper at executeRootCommand now also recognizes the cobra `unknown flag: --json` pattern and emits the same `{build, action: "unknown_subcommand", error}` document. #13: `sh install.sh --uninstall` (no flags) ran `gormes uninstall` which defaults to dry-run, leaving the operator looking at a preview and assuming cleanup happened. Asymmetric vs. install which actually installs by default. run_uninstall now scans the passthrough args for an explicit `--dry-run` opt-in and prepends `--yes --dry-run=false` when absent, preserving caller intent (`install.sh --uninstall --dry-run` still previews). RED → GREEN coverage: - TestFreshInstallE2E_InvalidInputJSONEmitsStructuredError gains a `gateway_unknown_subcommand_json` subtest. - TestInstallSh_UninstallDefaultsToApply runs install.sh against a recording shim and asserts the three contracts: bare apply, --dry-run preserved, passthrough flags survive. Found during v0.2.0 fresh-install e2e probe. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> * ci: sync Go toolchain floor with go.mod * chore: prepare v0.2.1 release metadata * chore: sync benchmark Go floor metadata --------- Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
XelHaku
added a commit
that referenced
this pull request
May 9, 2026
* docs: close 6 inert umbrellas (5.O + 5.V), mark Matrix seam complete, regenerate surfaces * fix: add hermes gateway list to CLI parity manifest and tests * feat(matrix): add shared-chassis bot seam over threadtext contract * chore: pre-existing update lifecycle, backup writer, config writer changes * feat: add restore command, backup restore lifecycle, and update tests * chore: pre-existing status command changes * feat(restore): dry-run validates zip before printing would-extract Restore dry-run (without --yes) now validates the zip archive is openable and free of path-traversal entries BEFORE showing the "would extract" message. A corrupt or malicious zip will now surface the rejection immediately instead of misleading the operator. * feat(auth): add --json flag to auth status for machine-readable output gormes auth status <provider> --json now emits a parseable JSON document with the same redacted credential fields the human surface renders. Enables credential-health monitoring in CI/cron without scraping the human row. * fix(restore): add zip pre-validation to RestoreFromZip extract path Extends restore zip validation to the actual extract path (not just dry-run). Pre-validates the entire archive before extracting any files, so a malicious entry late in the zip cannot land earlier safe entries on disk. * refactor(doctor): route output through cobra writers, use newExitCodeError instead of os.Exit * feat(doctor): add JSON output mode and constructor command pattern - internal/doctor: add StatusSkip, MarshalJSON, and JSON struct tags - cmd/gormes/doctor: refactor doctorCmd to newDoctorCommand() constructor with doctorReporter for dual text/JSON output, eliminating shared var test contamination - cmd/gormes: wire newDoctorCommand() in root, update tests to use newRootCommand() with subcommand args - cmd/gormes/doctor_runE_test: add fleet-health JSON assertion test * test(doctor): add failed-field assertion for JSON monitoring contract * feat(doctor): track failed bool in JSON output for monitoring parity * feat(doctor): add drSeverity and pending incremental JSON refinements * feat(version): add git_commit field to --json output for fleet binary verification * feat: add git_commit field to --json version output and refactor versionCmd to constructor pattern - Refactor versionCmd from package-level var to newVersionCommand() constructor to prevent cross-test flag contamination (same anti-pattern that broke doctorCmd before its constructor refactor) - Add TestVersionCommand_ConstructorReturnsIndependentInstances test - Add git_commit field to versionReportJSON, populated via ldflag in CI/Makefile - Update deploy-gormes-www.yml, release.yml, Makefile build commands with -X main.GitCommit=${GIT_COMMIT} - Update release_workflow_test.go contract to expect GIT_COMMIT ldflag * refactor: convert memoryCmd to newMemoryCommand constructor pattern - Refactor memoryCmd from package-level var to newMemoryCommand() constructor to prevent cross-test flag contamination (same anti-pattern as versionCmd) - Convert memoryStatusCmd to newMemoryStatusCommand() constructor - Add TestMemoryCommand_ConstructorReturnsIndependentInstances test - Wire newMemoryCommand() into root command registration * refactor: remove resetGonchoDoctorFlags workaround, wire newGonchoCommand constructor - Remove resetGonchoDoctorFlags() call that the constructor pattern made obsolete - Wire newGonchoCommand() in place of gonchoCmd in root command registration - Add TestGonchoCommand_ConstructorReturnsIndependentInstances test * refactor: convert sessionCmd and remove old gonchoCmd package-level vars - Convert sessionCmd + subcommands to newSessionCommand() constructor tree (list, export, delete, prune, browse all get constructor functions) - Remove resetSessionsCommandFlagState() workaround now made obsolete - Add TestSessionCommand_ConstructorReturnsIndependentInstances test - Remove old gonchoCmd/gonchoDoctorCmd package-level vars now superseded by newGonchoCommand()/newGonchoDoctorCommand() - Wire newSessionCommand() into root command registration * refactor: convert gatewayCmd and telegramCmd to constructor pattern Replace gatewayCmd and telegramCmd package-level vars with newGatewayCommand() and newTelegramCommand() constructors. Move init()-based subcommand wiring and flag registration into the constructors so each newRootCommand() instance gets a fresh independent tree. Add a constructor-isolation test proving the gateway tree owns 10 distinct children per call (6 real + 4 mutating-unavailable placeholders). * feat: add Mattermost shared-chassis bot seam with dedup and mention gating New internal/channels/mattermost package adds a Seam over threadtext for Mattermost posted-event parsing before REST/WS transport. Handles double-encoded posted event JSON, drops self/system/duplicate posts, preserves root_id as canonical thread_id, models reply_mode=thread vs off, and uses pure-input mention gating (DM/free-channel/require-mention decisions). 15 fixture tests exercise the full event lifecycle including cancel hook suppression, allowed-channel whitelist enforcement, and @mention stripping. * feat: add git_dirty field to version --json, backup writer, and CLI test coverage - version --json: add git_dirty, go_version, os, arch fields - doctor: improve runE flow with additional diagnostics - restore: expand restore command with backup writer integration - status/update/auth/secrets: improve CLI command coverage - internal/cli: backup_writer, backup_restore, active_profile, busy_command, update_lifecycle enhancements with test coverage - CI: update release and deploy workflows - Makefile: build target updates * docs: sharpen 3 Phase 5 umbrella rows with 2026-05-07 parity source_refs, complete Mattermost seam Planner pass: add upstream source_refs to Skill registries (skills_tool.py, skill_commands.py, etc.), Dangerous action gating (approval.py, tirith/), and Atomic checkpoints (checkpoints.py, checkpoint_manager.py) umbrella rows. Builder pass: complete Mattermost shared-chassis bot seam row (7.7.C). Fifteen fixture tests prove posted-event parsing, dedup, self/system drops, mention gating, reply-mode thread/off, and hook cancellation. Regenerate all derived progress surfaces (agent queue, next slices, blocked slices, umbrella cleanup, landing data, contract readiness). * fix: harden builder-loop test runner cleanup with unconditional SIGKILL * fix: distinguish missing/corrupt zip in restore error messages ValidateRestoreZip, RestoreFromZip, and SummarizeRestoreZipImpact now surface 'zip not found: <path>' for missing files versus 'zip unreadable: ...' for corrupt archives. Previously both cases chained the os.Open wording behind a duplicate 'open' prefix, forcing operators to decode nested error chains to triage. * chore: add missing encoding/json import to auth command test * feat: add --json flag to auth list and profile show/list auth list --json emits {build, provider, credentials:[...]} with pre-redacted credential status. profile show --json emits {build, active, root} with redacted root path. profile list --json emits {build, active, profiles:[{name, active},...]} for fleet automation. * fix: fast-fail backup writer with operator-friendly missing source error * fix: bump discord e2e poll timeouts to eliminate flakes under parallel load * docs: add Checkpoints CLI parity row (P2, builder-ready) to progress.json * fix: add HTTP client timeout to logs command, refactor uninstall to use io.Writer * test: add goncho doctor test coverage * fix: goncho doctor production wiring * feat: add gormes checkpoints CLI (status/list/prune/clear/clear-legacy) * docs: mark Checkpoints CLI row complete with evidence * fix: parallel agent improvements (channels, gateway, usage, uninstall fixes) * feat: add provider client lazy-init pool for cold-start budget internal/provider/lazy_client.go: ClientPool with Register/Get/Reset that defers provider HTTP client construction until first access. Only the selected provider is constructed; unselected providers never invoke their factory. internal/provider/lazy_client_test.go: 6 tests covering does-not-construct-unselected, constructed-once, reset-for-testing, unknown-provider, factory-error, and concurrent-access. internal/runtime/coldstart_bench_test.go: BenchmarkGormesColdStart enforces a 5ms budget on 10-registered-provider cold start. cmd/gormes/provider_client.go: wires getOrCreateProviderClient into the oneshot path via newOneshotHTTPClient. hermes/client.go: adds ErrProviderUnavailable sentinel. Source: Hermes v0.12.0 PR #17046 (lazy OpenAI/Anthropic/Firecrawl) inside the ~57% TUI cold-start cut. * docs: mark Provider client lazy-init row complete, regenerate progress surfaces 5.Q row: contract validated, write_scope corrected, row implemented and marked complete with full evidence. Progress surfaces regenerated via go run ./cmd/progress write. * feat: setup reset breadcrumb, memory/restore/session enhancements setup.go: reset config preserves prior config as breadcrumb file, ResetConfig returns (string, error) to surface the backup path. setup_reset_breadcrumb_test.go: tests for breadcrumb output. memory/restore/session: operator-facing command enhancements. * feat: checkpoint manager enhancements with pruned-orphan threshold * feat: add --json flag to checkpoints prune, clear, and clear-legacy commands Emit machine-readable JSON for operator scripts performing GC, CI/CD jobs running destructive prunes, and dashboards auditing checkpoint state without scraping human-readable prose output. * feat: add video_analyze tool with vision provider routing seam Implements tool (P2, Phase 5.D) that accepts a video path or HTTPS URL plus prompt, checks provider vision capability, and returns analysis text or typed evidence. Fixture-proven against fakeVideoAnalyzeProvider with vision routing, unsupported provider rejection, workspace path sanitization, and URL scheme allowlist. Registered alongside image_generate in the default tool registry. No real Gemini transport — provider seam ready for downstream adapters. * feat: add --json flag to agent, config, curator, gateway, and uninstall commands Extends the machine-readable JSON output contract to agent reset, config show, curator status, gateway reload, and uninstall commands. Each emits a structured build-provenance-led envelope for operator scripts, fleet automation, and dashboards. * docs: mark video_analyze row complete, regenerate progress surfaces Updates progress.json: video_analyze tool contract_status→validated, status→complete. Regenerates all derived progress docs and site data via go run ./cmd/progress write. Parity sweep timestamp updated. * feat: complete curator --json output parity * feat: add --json flag to plugins list for fleet automation auditing * test: add JSON-structured-report test for skills sync --json * feat: add --json flags for skills sync, session delete, session prune * feat: add --json flags to auth logout/remove/reset, plus curator and gateway-stop improvements * feat: add --json machine output to curator and profile commands for fleet automation * chore: bump hermes-agent submodule reference * feat: add --json flags to auth, kanban, logs, mcp-login, navivox, plugins, setup, usage, and whatsapp commands * feat: add --json flag to onboard command for fleet automation * feat: add /kanban gateway slash command with store-backed subcommands * feat: add --json flags to acp, gateway-discover, and logout commands * docs: mark kanban slash row in_progress, regenerate progress surfaces * feat: add build provenance to migrate JSON output for fleet automation * feat: extend build provenance to migrate cleanup, security, and system JSON output * docs: parity sweep: sharpen 5.M kanban refs, add specify row, bump hermes-agent submodule * feat: add build provenance to session export --json output * feat: add build provenance to config show/edit --json output * feat: add --json flag to skills list command for fleet automation * feat: add build provenance to kanban CLI JSON output * feat: add kanban dashboard API routes with lane summary and task list * docs: parity sweep: clear stale Kanban blockers, add dashboard route evidence, regenerate progress surfaces * feat: add --json flag to navivox setup-host for fleet automation provisioning * feat: add build provenance to dashboard kanban and status API responses * chore: bump hermes-agent submodule (auth fix + cron routing intent) * feat: add LoadNousOAuthCredentials to round-trip persisted Nous OAuth device-code state * feat: extend build provenance to cron admin, plugin inventory, and model dashboard endpoints * docs: parity sweep sharpen Kanban evidence, add Nous OAuth row, regenerate progress surfaces * feat: expose BuildInfo on /health and /v1/capabilities responses * feat: add BuildInfo to /health/detailed response model and tests * feat: implement Nous OAuth device code login, refresh, and agent key minting * docs: parity sweep cleanup + Nous OAuth row complete + hermes-agent submodule refresh * feat: apiserver build provenance + CLI skills URL install + progressctl enhancements * feat: port Hermes i18n static-message system to Go - internal/i18n/: core package with T(), language resolution (explicit lang arg > GORMES_LANGUAGE env > SetConfigLanguage > en), YAML catalog loading with dotted-key flattening, 8-language support (en/zh/ja/de/es/fr/tr/uk) with full alias table - locales/: 8 YAML catalogs ported from hermes-agent/locales/ covering approval prompts and gateway slash replies - internal/config/config.go: add display.language to DisplayCfg - 15 tests: fallback chain, catalog parity, format substitution, env/config resolution, missing file, broken YAML * docs: parity sweep, i18n row, Kanban fixture fix, dashboard, bump hermes-agent - All-topic Hermes/Gormes parity sweep: i18n identified as source-backed missing feature (Hermes has agent/i18n.py with 8 languages; Gormes had zero i18n) - progress.json: added Phase 5.W i18n row (P2, builder-ready), fixed Kanban in_progress row phantom fixture paths (removed non-existent internal/gateway/kanban_command_test.go, internal/tui/kanban_slash_test.go, internal/dashboard/; pointed at real files) - 23 vague planned rows identified (no write_scope) for future sharpening - Kanban dashboard: capabilities endpoint tests, dashboard.go, dashboard_contract_test.go, runs.go from ongoing Kanban work - hermes-agent: submodule bumped to a3131862b (upstream parity sweep baseline) - Regenerated all progress-driven docs and site data (go run ./cmd/progress write) * fix: publish run.stopped SSE event before closing subscribers runRegistry.stop() now records a typed run.stopped lifecycle event into the SSE backlog before closing subscriber channels so SSE consumers see a terminal event symmetrical with run.completed and run.failed. Fleet automation surfacing run lifecycles depends on this typed terminus. * feat: include build provenance in legacy /api/jobs responses Legacy /api/jobs list and get endpoints now include build info at the top of their JSON envelopes so fleet automation can attribute responses to binary version. * feat: add run lifecycle counters to health endpoint (completed, failed, stopped) * feat: add run event lifecycle counters to detailed health API * feat: auto-populate run lifecycle counters from runRegistry in /health/detailed * feat: add strict-mode CWD and interpreter parity contract with TDD fixtures * feat: add request_total and enhanced run events tracking to health API * docs: regenerate progress surfaces after strict-mode parity sweep * feat: advertise runs_list filters in /v1/capabilities for SDK discovery * feat: add terminated_at to run status for dashboard duration computation * feat: fail closed with terminal_cwd_deleted when configured cwd is deleted * docs: parity sweep, terminal cwd guard complete, goal-loop row added * chore: bump hermes-agent submodule for parity sweep baseline * feat: support multi-value status filters in runs list endpoint * feat: expose session_id in run registry snapshots and API responses * chore: bump hermes-agent submodule for parity sweep baseline * feat: add session_id filter to runs list, advertise run lifecycle events in capabilities * feat: add Kanban multi-board registry with slug validation, board isolation, and CLI surface * feat: add oldest_active_age_seconds to health endpoint, refine session_id runs filter and lifecycle events * docs: parity sweep — mark skill registries row complete, convert to builder-ready evidence * feat: expose tool_calls_count in run status endpoint * feat: add SSE prelude snapshot to run event stream * feat: enrich run event streams * chore: rename builder loop scripts * feat: add google chat channel seam * fix: avoid dashboard flag shorthand collision * fix: align installer public surface tests * fix: include panic excerpt in crash stderr * fix: route Goncho sqlite opens through busy-timeout helper * feat: add Matrix sender filter parity * fix: clarify update check copy * feat: add Microsoft Graph helper parity * fix: show empty kanban list placeholder * fix: reject unknown active profiles * fix: fall back to build vcs metadata * feat: expand cron deliver all routing intent * feat: surface profile distribution metadata * fix: reject plugin subcommand typos * fix: reject parent command typos * feat: add config get command * fix: show unset config values * test: isolate tui save export fixtures * fix: treat missing turns table as empty * test: cover legacy xdg uninstall cleanup * fix: remove legacy xdg state on uninstall * fix: treat fresh install state as empty * test: isolate discord channel home state * feat: track msgraph webhook platform drift * fix: suggest parent command typos * fix: report empty goncho system status * feat: emit onboard wizard json plan * fix: avoid duplicate mcp login errors * chore: ignore whatsapp bridge node modules * fix: normalize cli json degraded states * docs: document native Windows installer * tools: refresh Hermes ea86714 parity manifest * fix: normalize gateway discovery json beacons * fix: normalize gateway status json empties * test: cover fresh install json inventory surfaces * feat: emit config get json * test: assert json surfaces carry build provenance * feat: track teams pipeline plugin metadata * test: refresh docs home install assertion * feat: add TUI websocket attach transport * fix: emit kanban not-found JSON * feat: add matrix bootstrap parity boundary * docs: refresh Hermes Teams docs mirror * feat: add mattermost bootstrap boundary * ci: add termux release artifact coverage * docs: lead README with methodology positioning * web: align landing with methodology positioning * feat: add project-mode execute code sandbox * feat: normalize cron approval mode * feat: bind native tui kanban slash command * test: make logs fallback test deterministic * docs: close Windows installer parity row * feat: add Windows gateway scheduled task lifecycle * fix: route gateway kanban through shared runner * feat: wire execute code mode config * test: stabilize kanban dispatcher shutdown checks * feat: add kanban dashboard dispatch quick path * fix: port shift-enter tui newline parity * docs: reconcile shift-enter parity row * fix: align TUI quit slash with Hermes * test: refresh Hermes patch tool parity manifest * feat: serialize Hermes fast-mode overrides * feat: add Kanban triage specify parity * test: stabilize Discord manager smoke * ci: enforce release archive size cap * docs: close release archive size gate row * ci: add release notes artifact sizes * feat: add slack manifest generator * release: prepare v0.2.0 (v2026.5.8) Minor bump 0.1 → 0.2 marks the move from case-by-case bug fixing to a CI-guarded contract for the --json arc. The autonomous engineering loop now ships its own conformance fence: - Six-battery fresh-install E2E suite (cmd/gormes/fresh_install_e2e_test.go) asserts no-null-arrays, typo-suggestions across 9 parents, fresh-install read-only exit-zero, build-provenance prepended on every captured-state --json document, parseable JSON on stdout, and structured {action: "not_found"} on lookup failures. - Native Windows installer (scripts/install.ps1) is first-class alongside install.sh. - gormes config get --json: structured {build, key, value, secret_redacted, set} with secret-key redaction. - Fresh-install UX uniform across legacy XDG migration, missing-DB read paths, and parent-command typo handling. Landing.js + Playwright reverted to v0.1.07 baseline. Methodology landing rewrite is a separate post-release slice; this release ships the fence, not the pitch. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> * fix: bound gateway startup disconnect cleanup * fix: route kanban commands through current board * feat: inject release build date provenance * fix: target install's managed checkout in gormes update, not cwd `gormes update` defaulted CheckoutDir to os.Getwd, walking up from whatever directory the operator invoked the command from. Run from inside the gormes-agent dev tree, it switched the tree's branch from `development` to `main` and ran a web build there — mutating the user's source instead of the install. resolveManagedCheckoutDir() mirrors install.sh's managed_checkout_dir(): GORMES_INSTALL_DIR override → $GORMES_INSTALL_HOME/gormes-agent → $HOME/.gormes/gormes-agent. Never falls back to cwd. The lifecycle's existing update_not_managed_checkout guard correctly fails the run when the resolved path isn't a git worktree (e.g., on a binary-fetch install with no managed clone). Two RED → GREEN tests pin the contract: - env-var override path (GORMES_INSTALL_DIR wins outright) - default fallback path (managed_home/gormes-agent, never cwd) Found during v0.2.0 fresh-install probe. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> * fix: remove dangling published-binary symlink during uninstall `gormes uninstall --yes` removed the managed binary at `<home>/bin/gormes` but left the install.sh-published PATH symlink at `~/.local/bin/gormes` dangling. After uninstall, `which gormes` returned empty, but the broken symlink persisted and confused reinstalls and shell completions. New `published-binary` artifact group enumerates the install.sh PATH-linked locations: - $GORMES_BIN_DIR (operator override; install.sh exports this) - $GORMES_PREFIX/bin (compatibility prefix) - $HOME/.local/bin (non-root default) - /usr/local/bin (root linux default) Surgical safety: only entries that are SYMLINKS whose target resolves into the gormes home are returned. A real binary at the same path (built from source, package-managed, manually placed) is never touched. Two RED → GREEN tests pin the contract: - TestUninstall_RemovesPublishedBinarySymlink — symlink → managed binary gets removed and listed in the JSON outcome. - TestUninstall_LeavesUnrelatedGormesBinaryAlone — non-symlink at the same path is preserved. Found during v0.2.0 fresh-install probe. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> * fix: bind Matrix E2EE bootstrap device id Complete the Matrix E2EE device-id crypto-store progress row with TDD coverage for resolved runtime device IDs, configured override behavior, missing-device degradation, and store-level put_device_id binding. Validated with go test ./... -count=1, go run ./cmd/progress validate, git diff --check, Matrix row tests, and docs/landing public-surface gates. * fix: publish install.sh and install.ps1 as release assets A curl following the natural GitHub release URL pattern https://github.com/.../releases/download/v0.2.0/install.sh returned 404 — install.sh and install.ps1 were not GitHub release assets, only landing-served at https://gormes.ai/install.sh. Users following the README's tagged-release URLs hit a wall and had to already know about the landing path to bootstrap. Publish step now stages install.sh + install.ps1 into dist/ before the softprops upload, and the release-notes block surfaces the canonical curl/irm one-liners so the install URLs are discoverable from the GitHub release page itself. RED → GREEN test in webpages/docs/install/release_workflow_test.go asserts both scripts appear in the upload glob and the release notes. Found during v0.2.0 fresh-install probe. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> * feat: add singularity command preflight contract * feat: add Camofox browser bridge * fix: pause interrupted gateway goals * fix(tui): trim soft-wrap markdown spaces * feat: add kanban run history command * feat: add kanban boards read model * docs: add nix flake packaging contract * feat: add kanban board override flag * fix: preserve kanban named board roots * fix: cap gateway shutdown disconnects * ci: attest release sboms * docs: close release sbom attestation row * feat: add kanban dashboard run history * feat: add kanban gc retention * fix: release signal lock before close returns * feat: prefer Windows release binary installs * feat: honor cron approval mode for terminal tools * ci: add OCI image smoke workflow * feat: add QQ Bot transport bootstrap seam * test: guard cron origin delivery identity * fix: normalize partial cron job records * web: add cron dashboard page * fix: preserve Telegram DM topic routing * ci: attest release build provenance * feat: support delegate task batches * fix: align kanban comment handoff policy * docs: close delegate task batch parity row * fix: preserve google chat relay sender type * feat: add gateway approval queue resolver * feat: add cron standalone sender fallback * feat: complete behavioral pattern extraction * feat: add profile clone-all create policy * web: add built-with Gormes proof page * fix: mirror telegram streaming edit safety * web: sync release date alias * feat: add Feishu update prompt cards * docs: sync release prep target matrix * feat: add curator archive prune commands * fix: coerce stringified tool-call arguments * feat: add kanban stats command * docs: close Kanban operator surface row * feat: add claw cleanup compatibility * fix: default top-level logout provider * docs: close logout fallback progress row * feat: add V4A patch mode to native patch tool * fix: deliver fast discord final frames * feat: classify minimax oauth provider * feat: restore fallback provider CLI * fix: align Telegram table row-label rendering * feat: add Google Chat standalone cron sender * feat: support V4A patch moves * chore: sync release benchmark metadata * feat: clear slash confirmations on reset * Emit JSON for invalid input errors * Add Kanban notify subscriptions * feat: add structured lint evidence to file tools * fix: surface home-tree wildcard under honest `gormes-home` group `gormes uninstall --json` preview classified the home-directory wildcard `<home>/` under the "logs" group (because config.CrashLogDir() returns GormesHome()). Fleet automation reading {"name": "logs", "paths": ["/home/xel/.gormes/"]} reasonably interpreted that as "removes log files," but `os.RemoveAll("<home>")` actually nukes the entire home tree: config, sessions, skills, subagents, kanban DB, the managed binary subdirectory — everything not enumerated by another group. Renamed split: - "logs" now lists only explicit log files (gormes.log) - new "gormes-home" group lists the home-tree wildcard with a truthful name; ordered last so per-feature groups appear first and the wholesale-removal scope is unambiguous. RED → GREEN test pins the contract: - TestUninstall_HomeDirWildcardIsNotMisclassifiedAsLogs Found during v0.2.0 fresh-install probe. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> * fix: emit JSON on cobra typo-with-suggestion under any parent `gormes config gat --json` and `gormes kanban shor --json` escaped the v0.2.0 conformance fence: cobra's built-in `findSuggestions` short-circuits in `Find()` and returns `unknown command "gat" for "gormes config"; did you mean "get"?` directly to Execute() — bypassing the parent's RunE guard installed by `installParentUnknownSubcommandGuards` (which only fires on the no-suggestion case). `executeRootCommand` now post-processes the Execute() error: when --json is in args AND the error matches cobra's `unknown command "X" for "Y"` pattern, it emits the same `{build, action: "unknown_subcommand", error}` document the parent guard would have produced. errors.As(exitCodeError) skip prevents double-emit when an inner RunE already handled it (mcp parent). Two RED → GREEN subtests in the existing conformance fence: - config_typo_with_suggestion (config gat → get) - kanban_typo_with_suggestion (kanban shor → show) Found during v0.2.0 fresh-install e2e probe. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> * fix: cover gateway --json edge + install.sh apply-by-default #12: `gormes gateway xyz --json` rejected `--json` as "unknown flag" because gateway parent has its own RunE (`runGateway`) so cobra parses flags BEFORE subcommand routing. The user's intent — "I asked for JSON output of an invocation containing --json" — must still produce JSON. Wrapper at executeRootCommand now also recognizes the cobra `unknown flag: --json` pattern and emits the same `{build, action: "unknown_subcommand", error}` document. #13: `sh install.sh --uninstall` (no flags) ran `gormes uninstall` which defaults to dry-run, leaving the operator looking at a preview and assuming cleanup happened. Asymmetric vs. install which actually installs by default. run_uninstall now scans the passthrough args for an explicit `--dry-run` opt-in and prepends `--yes --dry-run=false` when absent, preserving caller intent (`install.sh --uninstall --dry-run` still previews). RED → GREEN coverage: - TestFreshInstallE2E_InvalidInputJSONEmitsStructuredError gains a `gateway_unknown_subcommand_json` subtest. - TestInstallSh_UninstallDefaultsToApply runs install.sh against a recording shim and asserts the three contracts: bare apply, --dry-run preserved, passthrough flags survive. Found during v0.2.0 fresh-install e2e probe. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> * ci: sync Go toolchain floor with go.mod * chore: prepare v0.2.1 release metadata * chore: sync benchmark Go floor metadata * fix: expand mixed platform toolset composites * fix: align cron auth-header scanner parity * docs: rebalance README runtime-first per feedback External feedback flagged the methodology-first hero as creating two competing identities (usable agent runtime vs. methodology demonstration), with the methodology framing burying what the product actually does. The 2026-05-07 strategy pivot stays intact for site/landing/blog copy; README walks back to runtime-first because that's where operators land. New hero leads with the runtime story; methodology lives in a dedicated "How It's Built" section near the bottom as supporting evidence. Section reorder follows the recommended flow: Hero → Quick Install → First Proof → What Works Today → Why People Switch → Daily Use → Migration → Build From Source → Docs → Security → How It's Built → Status. Other changes: - "Capability Map" → "What Works Today" with Supported/ Experimental/Roadmap labels (drops internal `runtime-ready`/ `fixture-backed`/`row-backed` jargon). - Strip the "Current development head after vX..." dev-branch changelog leak (belongs in CHANGELOG, not the README). - Consolidate Security & Trust from 5 bullets to 3. - Drop Operator Cheatsheet (redundant with Daily Use). - 271 → 194 lines. - Update install-script command to canonical landing URL (gormes.ai/install.sh). - Rename "First Run" → "First Proof" (operator-facing). - Bump latest release pointer from v0.2.0 to v0.2.1. Tests updated to encode the new contract: - TestREADMEStartsWithMethodology → TestREADMELeadsWithRuntime (asserts runtime anchor in the lead, methodology mentioned somewhere — just not first). - TestREADMEMentionsDifferentiator: relax window to 80 words and drop "single 30 MB Go binary" from the lead-block requirement (binary size now lives in Status). - TestREADMEPreservesOperatorSections: track new section names and the canonical install URL. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> * chore: refresh benchmark metadata * fix: emit subcommand_required JSON for parent --json (no subcommand) `gormes <parent> --json` (with no subcommand) printed Help text on stdout for 13 parents — silently violating the conformance contract that --json paths produce parseable JSON. Affects config, kanban, session, auth, mcp, memory, goncho, profile, curator, system, security, channels, agent. The recursive installParentUnknownSubcommandGuards helper now registers a hidden --json flag on every guarded parent and emits a structured `subcommand_required` document on stdout when the flag fires: {build, action: "subcommand_required", parent, available, error} `available` enumerates the parent's named subcommands so fleet automation can discover the surface programmatically without scraping Help text. Auth and mcp parents have their own RunE so the guard skips them; both now check --json explicitly and route through the same emitJSONSubcommandRequired helper for parity. Three new subtests in the existing conformance fence battery pin the contract for representative cases (config, kanban, agent), plus auth and mcp for the explicit-RunE path. Found during a deeper v0.2.1 e2e probe. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> * feat: support Telegram guest mention mode * release: prepare v0.2.2 (v2026.5.9) Same-day patch over v0.2.1 carrying #14 — 13 parent commands that printed Help text on stdout for `gormes <parent> --json` (no subcommand) now emit a structured `subcommand_required` document with the available subcommand list. Date alias shared with v0.2.1 follows the v0.1.06 / v0.1.07 precedent for back-to-back same-day releases. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> * feat: add python lint evidence to file tools --------- Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
XelHaku
added a commit
that referenced
this pull request
May 11, 2026
…ests (#184) * chore: rename builder loop scripts * feat: add google chat channel seam * fix: avoid dashboard flag shorthand collision * fix: align installer public surface tests * fix: include panic excerpt in crash stderr * fix: route Goncho sqlite opens through busy-timeout helper * feat: add Matrix sender filter parity * fix: clarify update check copy * feat: add Microsoft Graph helper parity * fix: show empty kanban list placeholder * fix: reject unknown active profiles * fix: fall back to build vcs metadata * feat: expand cron deliver all routing intent * feat: surface profile distribution metadata * fix: reject plugin subcommand typos * fix: reject parent command typos * feat: add config get command * fix: show unset config values * test: isolate tui save export fixtures * fix: treat missing turns table as empty * test: cover legacy xdg uninstall cleanup * fix: remove legacy xdg state on uninstall * fix: treat fresh install state as empty * test: isolate discord channel home state * feat: track msgraph webhook platform drift * fix: suggest parent command typos * fix: report empty goncho system status * feat: emit onboard wizard json plan * fix: avoid duplicate mcp login errors * chore: ignore whatsapp bridge node modules * fix: normalize cli json degraded states * docs: document native Windows installer * tools: refresh Hermes ea86714 parity manifest * fix: normalize gateway discovery json beacons * fix: normalize gateway status json empties * test: cover fresh install json inventory surfaces * feat: emit config get json * test: assert json surfaces carry build provenance * feat: track teams pipeline plugin metadata * test: refresh docs home install assertion * feat: add TUI websocket attach transport * fix: emit kanban not-found JSON * feat: add matrix bootstrap parity boundary * docs: refresh Hermes Teams docs mirror * feat: add mattermost bootstrap boundary * ci: add termux release artifact coverage * docs: lead README with methodology positioning * web: align landing with methodology positioning * feat: add project-mode execute code sandbox * feat: normalize cron approval mode * feat: bind native tui kanban slash command * test: make logs fallback test deterministic * docs: close Windows installer parity row * feat: add Windows gateway scheduled task lifecycle * fix: route gateway kanban through shared runner * feat: wire execute code mode config * test: stabilize kanban dispatcher shutdown checks * feat: add kanban dashboard dispatch quick path * fix: port shift-enter tui newline parity * docs: reconcile shift-enter parity row * fix: align TUI quit slash with Hermes * test: refresh Hermes patch tool parity manifest * feat: serialize Hermes fast-mode overrides * feat: add Kanban triage specify parity * test: stabilize Discord manager smoke * ci: enforce release archive size cap * docs: close release archive size gate row * ci: add release notes artifact sizes * feat: add slack manifest generator * release: prepare v0.2.0 (v2026.5.8) Minor bump 0.1 → 0.2 marks the move from case-by-case bug fixing to a CI-guarded contract for the --json arc. The autonomous engineering loop now ships its own conformance fence: - Six-battery fresh-install E2E suite (cmd/gormes/fresh_install_e2e_test.go) asserts no-null-arrays, typo-suggestions across 9 parents, fresh-install read-only exit-zero, build-provenance prepended on every captured-state --json document, parseable JSON on stdout, and structured {action: "not_found"} on lookup failures. - Native Windows installer (scripts/install.ps1) is first-class alongside install.sh. - gormes config get --json: structured {build, key, value, secret_redacted, set} with secret-key redaction. - Fresh-install UX uniform across legacy XDG migration, missing-DB read paths, and parent-command typo handling. Landing.js + Playwright reverted to v0.1.07 baseline. Methodology landing rewrite is a separate post-release slice; this release ships the fence, not the pitch. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> * fix: bound gateway startup disconnect cleanup * fix: route kanban commands through current board * feat: inject release build date provenance * fix: target install's managed checkout in gormes update, not cwd `gormes update` defaulted CheckoutDir to os.Getwd, walking up from whatever directory the operator invoked the command from. Run from inside the gormes-agent dev tree, it switched the tree's branch from `development` to `main` and ran a web build there — mutating the user's source instead of the install. resolveManagedCheckoutDir() mirrors install.sh's managed_checkout_dir(): GORMES_INSTALL_DIR override → $GORMES_INSTALL_HOME/gormes-agent → $HOME/.gormes/gormes-agent. Never falls back to cwd. The lifecycle's existing update_not_managed_checkout guard correctly fails the run when the resolved path isn't a git worktree (e.g., on a binary-fetch install with no managed clone). Two RED → GREEN tests pin the contract: - env-var override path (GORMES_INSTALL_DIR wins outright) - default fallback path (managed_home/gormes-agent, never cwd) Found during v0.2.0 fresh-install probe. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> * fix: remove dangling published-binary symlink during uninstall `gormes uninstall --yes` removed the managed binary at `<home>/bin/gormes` but left the install.sh-published PATH symlink at `~/.local/bin/gormes` dangling. After uninstall, `which gormes` returned empty, but the broken symlink persisted and confused reinstalls and shell completions. New `published-binary` artifact group enumerates the install.sh PATH-linked locations: - $GORMES_BIN_DIR (operator override; install.sh exports this) - $GORMES_PREFIX/bin (compatibility prefix) - $HOME/.local/bin (non-root default) - /usr/local/bin (root linux default) Surgical safety: only entries that are SYMLINKS whose target resolves into the gormes home are returned. A real binary at the same path (built from source, package-managed, manually placed) is never touched. Two RED → GREEN tests pin the contract: - TestUninstall_RemovesPublishedBinarySymlink — symlink → managed binary gets removed and listed in the JSON outcome. - TestUninstall_LeavesUnrelatedGormesBinaryAlone — non-symlink at the same path is preserved. Found during v0.2.0 fresh-install probe. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> * fix: bind Matrix E2EE bootstrap device id Complete the Matrix E2EE device-id crypto-store progress row with TDD coverage for resolved runtime device IDs, configured override behavior, missing-device degradation, and store-level put_device_id binding. Validated with go test ./... -count=1, go run ./cmd/progress validate, git diff --check, Matrix row tests, and docs/landing public-surface gates. * fix: publish install.sh and install.ps1 as release assets A curl following the natural GitHub release URL pattern https://github.com/.../releases/download/v0.2.0/install.sh returned 404 — install.sh and install.ps1 were not GitHub release assets, only landing-served at https://gormes.ai/install.sh. Users following the README's tagged-release URLs hit a wall and had to already know about the landing path to bootstrap. Publish step now stages install.sh + install.ps1 into dist/ before the softprops upload, and the release-notes block surfaces the canonical curl/irm one-liners so the install URLs are discoverable from the GitHub release page itself. RED → GREEN test in webpages/docs/install/release_workflow_test.go asserts both scripts appear in the upload glob and the release notes. Found during v0.2.0 fresh-install probe. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> * feat: add singularity command preflight contract * feat: add Camofox browser bridge * fix: pause interrupted gateway goals * fix(tui): trim soft-wrap markdown spaces * feat: add kanban run history command * feat: add kanban boards read model * docs: add nix flake packaging contract * feat: add kanban board override flag * fix: preserve kanban named board roots * fix: cap gateway shutdown disconnects * ci: attest release sboms * docs: close release sbom attestation row * feat: add kanban dashboard run history * feat: add kanban gc retention * fix: release signal lock before close returns * feat: prefer Windows release binary installs * feat: honor cron approval mode for terminal tools * ci: add OCI image smoke workflow * feat: add QQ Bot transport bootstrap seam * test: guard cron origin delivery identity * fix: normalize partial cron job records * web: add cron dashboard page * fix: preserve Telegram DM topic routing * ci: attest release build provenance * feat: support delegate task batches * fix: align kanban comment handoff policy * docs: close delegate task batch parity row * fix: preserve google chat relay sender type * feat: add gateway approval queue resolver * feat: add cron standalone sender fallback * feat: complete behavioral pattern extraction * feat: add profile clone-all create policy * web: add built-with Gormes proof page * fix: mirror telegram streaming edit safety * web: sync release date alias * feat: add Feishu update prompt cards * docs: sync release prep target matrix * feat: add curator archive prune commands * fix: coerce stringified tool-call arguments * feat: add kanban stats command * docs: close Kanban operator surface row * feat: add claw cleanup compatibility * fix: default top-level logout provider * docs: close logout fallback progress row * feat: add V4A patch mode to native patch tool * fix: deliver fast discord final frames * feat: classify minimax oauth provider * feat: restore fallback provider CLI * fix: align Telegram table row-label rendering * feat: add Google Chat standalone cron sender * feat: support V4A patch moves * chore: sync release benchmark metadata * feat: clear slash confirmations on reset * Emit JSON for invalid input errors * Add Kanban notify subscriptions * feat: add structured lint evidence to file tools * fix: surface home-tree wildcard under honest `gormes-home` group `gormes uninstall --json` preview classified the home-directory wildcard `<home>/` under the "logs" group (because config.CrashLogDir() returns GormesHome()). Fleet automation reading {"name": "logs", "paths": ["/home/xel/.gormes/"]} reasonably interpreted that as "removes log files," but `os.RemoveAll("<home>")` actually nukes the entire home tree: config, sessions, skills, subagents, kanban DB, the managed binary subdirectory — everything not enumerated by another group. Renamed split: - "logs" now lists only explicit log files (gormes.log) - new "gormes-home" group lists the home-tree wildcard with a truthful name; ordered last so per-feature groups appear first and the wholesale-removal scope is unambiguous. RED → GREEN test pins the contract: - TestUninstall_HomeDirWildcardIsNotMisclassifiedAsLogs Found during v0.2.0 fresh-install probe. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> * fix: emit JSON on cobra typo-with-suggestion under any parent `gormes config gat --json` and `gormes kanban shor --json` escaped the v0.2.0 conformance fence: cobra's built-in `findSuggestions` short-circuits in `Find()` and returns `unknown command "gat" for "gormes config"; did you mean "get"?` directly to Execute() — bypassing the parent's RunE guard installed by `installParentUnknownSubcommandGuards` (which only fires on the no-suggestion case). `executeRootCommand` now post-processes the Execute() error: when --json is in args AND the error matches cobra's `unknown command "X" for "Y"` pattern, it emits the same `{build, action: "unknown_subcommand", error}` document the parent guard would have produced. errors.As(exitCodeError) skip prevents double-emit when an inner RunE already handled it (mcp parent). Two RED → GREEN subtests in the existing conformance fence: - config_typo_with_suggestion (config gat → get) - kanban_typo_with_suggestion (kanban shor → show) Found during v0.2.0 fresh-install e2e probe. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> * fix: cover gateway --json edge + install.sh apply-by-default #12: `gormes gateway xyz --json` rejected `--json` as "unknown flag" because gateway parent has its own RunE (`runGateway`) so cobra parses flags BEFORE subcommand routing. The user's intent — "I asked for JSON output of an invocation containing --json" — must still produce JSON. Wrapper at executeRootCommand now also recognizes the cobra `unknown flag: --json` pattern and emits the same `{build, action: "unknown_subcommand", error}` document. #13: `sh install.sh --uninstall` (no flags) ran `gormes uninstall` which defaults to dry-run, leaving the operator looking at a preview and assuming cleanup happened. Asymmetric vs. install which actually installs by default. run_uninstall now scans the passthrough args for an explicit `--dry-run` opt-in and prepends `--yes --dry-run=false` when absent, preserving caller intent (`install.sh --uninstall --dry-run` still previews). RED → GREEN coverage: - TestFreshInstallE2E_InvalidInputJSONEmitsStructuredError gains a `gateway_unknown_subcommand_json` subtest. - TestInstallSh_UninstallDefaultsToApply runs install.sh against a recording shim and asserts the three contracts: bare apply, --dry-run preserved, passthrough flags survive. Found during v0.2.0 fresh-install e2e probe. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> * ci: sync Go toolchain floor with go.mod * chore: prepare v0.2.1 release metadata * chore: sync benchmark Go floor metadata * fix: expand mixed platform toolset composites * fix: align cron auth-header scanner parity * docs: rebalance README runtime-first per feedback External feedback flagged the methodology-first hero as creating two competing identities (usable agent runtime vs. methodology demonstration), with the methodology framing burying what the product actually does. The 2026-05-07 strategy pivot stays intact for site/landing/blog copy; README walks back to runtime-first because that's where operators land. New hero leads with the runtime story; methodology lives in a dedicated "How It's Built" section near the bottom as supporting evidence. Section reorder follows the recommended flow: Hero → Quick Install → First Proof → What Works Today → Why People Switch → Daily Use → Migration → Build From Source → Docs → Security → How It's Built → Status. Other changes: - "Capability Map" → "What Works Today" with Supported/ Experimental/Roadmap labels (drops internal `runtime-ready`/ `fixture-backed`/`row-backed` jargon). - Strip the "Current development head after vX..." dev-branch changelog leak (belongs in CHANGELOG, not the README). - Consolidate Security & Trust from 5 bullets to 3. - Drop Operator Cheatsheet (redundant with Daily Use). - 271 → 194 lines. - Update install-script command to canonical landing URL (gormes.ai/install.sh). - Rename "First Run" → "First Proof" (operator-facing). - Bump latest release pointer from v0.2.0 to v0.2.1. Tests updated to encode the new contract: - TestREADMEStartsWithMethodology → TestREADMELeadsWithRuntime (asserts runtime anchor in the lead, methodology mentioned somewhere — just not first). - TestREADMEMentionsDifferentiator: relax window to 80 words and drop "single 30 MB Go binary" from the lead-block requirement (binary size now lives in Status). - TestREADMEPreservesOperatorSections: track new section names and the canonical install URL. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> * chore: refresh benchmark metadata * fix: emit subcommand_required JSON for parent --json (no subcommand) `gormes <parent> --json` (with no subcommand) printed Help text on stdout for 13 parents — silently violating the conformance contract that --json paths produce parseable JSON. Affects config, kanban, session, auth, mcp, memory, goncho, profile, curator, system, security, channels, agent. The recursive installParentUnknownSubcommandGuards helper now registers a hidden --json flag on every guarded parent and emits a structured `subcommand_required` document on stdout when the flag fires: {build, action: "subcommand_required", parent, available, error} `available` enumerates the parent's named subcommands so fleet automation can discover the surface programmatically without scraping Help text. Auth and mcp parents have their own RunE so the guard skips them; both now check --json explicitly and route through the same emitJSONSubcommandRequired helper for parity. Three new subtests in the existing conformance fence battery pin the contract for representative cases (config, kanban, agent), plus auth and mcp for the explicit-RunE path. Found during a deeper v0.2.1 e2e probe. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> * feat: support Telegram guest mention mode * release: prepare v0.2.2 (v2026.5.9) Same-day patch over v0.2.1 carrying #14 — 13 parent commands that printed Help text on stdout for `gormes <parent> --json` (no subcommand) now emit a structured `subcommand_required` document with the available subcommand list. Date alias shared with v0.2.1 follows the v0.1.06 / v0.1.07 precedent for back-to-back same-day releases. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> * feat: add python lint evidence to file tools * fix: notify context engine on session reset * docs: add provider default model progress row * fix: refresh Hermes memory guidance * fix: resolve provider default models * docs: complete provider default model row * feat: add OpenRouter Grok affinity header * feat: add Telegram STT fallback resolver * fix: guard Kanban schema migration races * docs: update progress for STT and Kanban rows * fix: include Teams in channel capabilities * fix: preserve detached Windows gateway interrupts * fix: propagate ACP session cwd * fix: refresh Google Chat install hint * feat: add OpenRouter Pareto request plugin * feat: prefer Groq STT transcriber selection * docs: file pure-Go STT exploration row Track the architectural question of how Gormes should ship local STT given the Go ecosystem currently has no production-quality pure-Go (CGO_ENABLED=0) STT library. Research pass 2026-05-09 confirmed every actively-maintained Go STT library requires cgo: ggerganov/whisper.cpp/bindings/go (2026-05-02), kardianos fork, mutablelogic/go-whisper (2026-01-27), xPrimeTime/go-whisper-ct2 (2026-01-10, 0 stars, requires building CTranslate2 + libsndfile + libsamplerate + openblas from source), and k2-fsa/sherpa-onnx-go-linux (v1.13.1, the most production-grade cgo option). The only pure-Go path (agnivade/whisper-wasi via wazero+WASI) is a 2-star prototype with 5 commits, ~5x slower than native (90s vs 17s), no thread support in wazero, and explicitly disclaimed by its author. The new row in phase 5 / subphase 5.E captures the four mutually-exclusive architectural choices (status quo / cgo build-tag / WASI productionization / wait+monitor) with per-path tradeoffs and per-path acceptance bullets, so future planners do not re-research the same dead ends. Companion row "Telegram voice STT HTTP-provider fallback" already shipped today gives operators a no-install option (Groq free tier wired via GROQ_API_KEY env var) in the meantime — independent of which long-term architectural path is eventually chosen. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> * docs: refresh benchmark data * feat: add kanban worker log command * feat: silence Telegram placeholders by default * feat: add shell completion command * docs: plan WASI STT path * chore: refresh benchmark metadata * feat: add wazero WASI smoke harness * fix: preserve proxy replay metadata * ci: name sbom attestations in release notes * fix: add shell lint evidence to file tools * feat: bind FAL image generation queue API * feat: pass gateway photos as image parts * fix: preserve config comments on set * docs: record parity sweep progress * fix(provider): classify generic timeout messages * fix: preserve gateway image attachments * feat: add whisper wasi discovery fixture * docs: sync Hermes optional skill mirror * feat: surface curator rename summaries * chore: log gateway image attachment conversion * fix: admit image-only channel turns * feat: pin kanban board for chat tools * feat: add kanban notify delivery engine * web: refresh landing methodology copy * feat: add native image path hints * docs: correct image hint row scope * ci: align gormes.ai deploy guards with methodology hero The deploy-gormes-www.yml content guards still required the pre-rewrite hero copy ("AI agent runtime in one Go binary.", "An autonomous engineering loop ports Hermes to Go, every day.", "HOW IT IS BUILT") that 95864c2 removed. With those guards stale, the next push to main would fail at the "Verify homepage content" step before reaching the Cloudflare Pages deploy. Repoint positive grep assertions at the new methodology-first hero strings and add the old phrases to the negative-grep list so future drift back to parity-first copy fails the deploy instead of silently shipping. * chore: refresh benchmark snapshots * feat: retry text-only on vision rejection * fix: preserve fallback credential aliases * test: allow landing e2e port override * release: prepare v0.2.3 (v2026.5.9) Third same-day patch over v0.2.2; shared date alias follows the v0.1.06 / v0.1.07 and same-day v0.2.1 / v0.2.2 precedent for back-to-back releases. Cut to deploy the methodology-first landing rewrite to www.gormes.ai (deploy-gormes-www.yml only fires on push to main). Riding along: the multimodal photo passthrough + admission gate, native image input mode wiring, vision-unsupported retry, Telegram voice STT HTTP fallback, the first WASI STT exploration rows, provider/auth/runtime polish (config comments preserved on set, generic timeout classification, file-tool shell+python+structured lint evidence, fallback credential aliases, proxy replay metadata, FAL image gen binding, OpenRouter Pareto plugin, shell completion command, Telegram placeholder default, curator rename summaries), and the kanban suite (board pinning, notify delivery engine, worker log command). See CHANGELOG.md for the full annotated list. * Implement image input mode routing * feat: add native vision tool results * feat: add gateway restart notification opt-out * fix: add telegram audio transcription diagnostics * docs: mirror upstream Hermes user stories * fix: add stream drop retry diagnostics * fix: polish kanban slash help UX * fix: harden background review skill prompts * web: use local Astro binary for landing e2e * fix: mirror Codex Spark model metadata * Add Whisper tiny.en model cache helper * fix(stt): read Groq response as text, matches response_format=text request The Groq Whisper provider was sending response_format=text in the multipart form but then attempting json.NewDecoder(...).Decode(...) on the response body. Groq honored the requested format and returned the raw transcript starting with whatever character the user actually said. The JSON decoder choked on the first non-{ character with "invalid character 'T' looking for beginning of value" (or the same error with whatever the leading byte happened to be), the whole STT path failed silently behind the existing sanitizer, and Telegram voice messages came back as "audio transcription provider failed". Replace the JSON decode with io.ReadAll(resp.Body) so the read shape matches the response_format we asked for. Updated the existing Groq provider test to serve plain text (matches real Groq behavior under response_format=text) and to assert response_format=text is in the outgoing request, which doubles as a regression for the parse failure. Live evidence: gateway log line at 2026-05-10T01:24:22 captured diagnostic=stt_groq_parse_failure detail="Groq STT parse response: invalid character 'T' looking for beginning of value" — the diagnostic plumbing landed in 9c902de plus the iteration-2 expansion below pinpointed the exact failure site in one round trip. * feat(channels/telegram): expand STT failure diagnostics Builds on the diagnostic plumbing added in 9c902de: - telegramAudioErrorDiagnostic now distinguishes the seven Groq STT failure sites (network, file_open, request_build, parse, copy, writer_close, form). The previous version collapsed all of them to stt_groq_local_failure, which is what made the live "audio transcription provider failed" earlier today ambiguous between a network failure and a parse failure. The newly granular stt_groq_parse_failure is what pinpointed the response_format/JSON-decode mismatch (fixed in the parent commit). - New telegramAudioErrorRedactedDetail returns a 256-char-bounded, redacted substring of err.Error() suitable for the WARN log. Strips Telegram bot-token-shaped substrings and Telegram getFile direct URLs so log forwarders cannot leak credentials. Provider-side errors (Groq HTTP body, dial errors, TLS messages) pass through. - Both bot.go WARN call sites (voice + audio) now log diagnostic=<token> detail=<redacted-truncated-err> alongside the existing sanitized err= field. Operators can group by token or read the underlying error without rebuild cycles. * release: prepare v0.2.4 (v2026.5.10) Cuts to ship the Telegram voice STT fix to all install.sh users. Without v0.2.4, every operator with v0.2.3 installed gets "audio transcription provider failed" the moment they send a voice note — the Groq Whisper provider was sending response_format=text but JSON-decoding the response, and the JSON decoder choked on the first non-{ character of the real transcript. Also rolls forward today's diagnostic plumbing (codexu's 9c902de + this branch's iteration-2 expansion) so future STT regressions surface a granular diagnostic= token and a redacted detail= field in the WARN log instead of collapsing to "audio unavailable". See CHANGELOG.md for the full annotated list. * feat: add WASI Whisper transcriber * fix: parse OpenAI STT text responses * feat: wire WASI Whisper into Telegram STT * feat: add WASI Whisper audio preprocessing package * feat: bind WASI Whisper audio preprocessing * feat: record WASI Whisper benchmark evidence * fix: add patch no-match recovery hints * feat: add kanban tail event follower * feat: add fuzzy patch replace strategies * fix: normalize unicode fuzzy patch matches * feat(provider): add stream drop upstream diagnostics * test(landing): avoid e2e port collisions * fix: guard curator prompt against transient failures * feat: add block-anchor patch matching * fix: fuzzy match V4A patch hunks * fix: rollback failed v4a patch applies * ci: smoke release binary metadata * fix: bind release date alias to GitHub releases * feat: add context-aware patch replacement * feat: add Kanban orchestrator board tools * fix: verify patch replace persistence * fix: stabilize kanban tool list order * fix: cover Hermes bundled platform plugins * fix: harden kanban worker spawn resolution Mirror the refreshed Hermes dispatcher executable fallback in Gormes by resolving default Kanban worker spawns through PATH-first gormes lookup and current-executable fallback. Update progress evidence and mirror the new upstream plugin LLM docs page required by the refreshed Hermes submodule. * fix: harden kanban corrupt timestamp reads * fix: shape browser console CDP results * feat: expand Hermes i18n locale parity * fix(uninstall): scope to managed home + prefer recoverable trash over permanent delete Live regression 2026-05-10: a sandbox uninstall test (GORMES_INSTALL_HOME=/tmp/...) accidentally targeted the operator's REAL ~/.gormes and PERMANENTLY DELETED .env (provider keys), memory.db (Goncho conversation history), config.toml, ~/.gormes/bin/gormes, and ~/.local/bin/gormes. Two independent root causes lined up to make this maximally destructive: 1. install.sh's run_uninstall() did not export GORMES_HOME before invoking the gormes binary's `uninstall` subcommand. The gormes process inherited the operator's default $HOME-derived ~/.gormes path instead of the sandbox path the operator actually pointed at. 2. cmd/gormes/uninstall.go's executeUninstall used os.RemoveAll directly — permanent unrecoverable deletion. There was no fallback to a freedesktop trash, so even when the wrong scope was chosen, recovery was impossible. Fix #1 — install.sh run_uninstall pins scope: GORMES_HOME="$(managed_home_dir)" export GORMES_HOME managed_home_dir() returns $GORMES_INSTALL_HOME when set, else $HOME/.gormes. So sandbox uninstalls now stay in the sandbox; default uninstalls still target ~/.gormes as before. Fix #2 — cmd/gormes/uninstall.go pickArtifactMover(): - default: `gio trash <path>` when gio is on PATH (move to freedesktop trash, recoverable from any file manager's trash UI) - GORMES_UNINSTALL_FORCE_PURGE=1: opt-in permanent delete for CI cleanup, container teardown, secure wipe - fallback: permanent delete with an explicit label that names the missing dependency ("gio not available; install glib2-tools for recoverable trash") so operators understand why their uninstall isn't trash-aware Removal mode is now logged to stdout and surfaced in --json output as removal_mode: "...", so fleet automation can verify which mode fired. Recovery from this incident only worked because an earlier May-2 uninstall on the same operator's host had used a trash-aware path, leaving ~/.local/share/Trash/files/.gormes/ as a partial backup. The new default would have made that explicit instead of accidental. Tests: - TestPickArtifactMover_PrefersGioTrashWhenAvailable - TestPickArtifactMover_ForcePurgeOptsIntoPermanentDelete - TestPickArtifactMover_ForcePurgeAcceptsTrueAlias - TestPickArtifactMover_DefaultOnHostWithoutGio Existing uninstall tests (12) still pass — they all run with t.TempDir() paths that gio trash handles identically to os.RemoveAll for cleanup purposes. * fix(hermes): collapse double /v1 prefix in OpenAI-compatible URL builder Live regression 2026-05-10: an operator wired up OpenRouter using the documented base URL `https://openrouter.ai/api/v1` and got the cryptic "Not Found: provider returned HTML error body" error with no indication that openAICompatibleURL had joined the basePath /api/v1 with the chat-completions path /v1/chat/completions to produce `https://openrouter.ai/api/v1/v1/chat/completions` (double /v1, 404). Operators copy-pasting the documented base URL is the natural intuition across every OpenAI-compatible provider whose docs include /v1 in the advertised base URL — OpenAI itself, OpenRouter, Together, Groq chat, DeepInfra, etc. The defect class is silent: the request shape is structurally valid, the error body is HTML (the upstream service returned a generic 404 page), and the resulting Go error ("Not Found: provider returned HTML error body") doesn't surface the URL it tried. Fix: when basePath ends with "/v1" AND endpointPath starts with "/v1/", strip basePath's trailing "/v1" so both shapes (endpoint = "https://openrouter.ai/api" and endpoint = "https://openrouter.ai/api/v1") resolve to the same URL. Other prefix shapes are explicitly preserved: - baseURL ending in "/v1/proxy" (middle /v1, not trailing) — no collapse - endpointPath like "/responses" or "/messages" (non-/v1) — no collapse - baseURL without scheme (e.g. test stubs) — falls through to raw concat Eight-case TestOpenAICompatibleURL_CollapsesDoubleV1Prefix pins the contract: openrouter+/v1, openrouter+/v1/, openrouter without /v1, OpenAI with /v1 (same defect class), Anthropic /v1/messages (must still work), Azure /responses (basePath /v1 must be preserved), middle /v1 (no collapse), no-scheme fallthrough. Verified end-to-end: rebuilt + hot-swapped the gateway binary, set hermes.endpoint = "https://openrouter.ai/api/v1" (the previously-broken shape), ran `gormes --oneshot "Reply with exactly: openrouter url fix lives."` and got the exact reply through OpenRouter→DeepSeek v4 flash. * release: prepare v0.2.5 (v2026.5.10) Cuts to ship today's three follow-on fixes to install.sh users: 1. CRITICAL: install.sh --uninstall scope leak that wiped operators' real ~/.gormes when run from a sandbox (.env, memory.db, config.toml, binaries — unrecoverable on hosts without gio trash in the path the operator's environment used). 2. install.sh uninstall now defaults to recoverable trash via gio instead of permanent delete, with GORMES_UNINSTALL_FORCE_PURGE=1 for callers who legitimately need scrubbed disk. 3. OpenRouter (and other OpenAI-compatible) base URL with the documented /v1 suffix no longer 404s — the URL builder now collapses double-/v1 prefixes so endpoint = "https://openrouter.ai/api/v1" and endpoint = "https://openrouter.ai/api" both work. 4. OpenAI STT response_format=text + JSON-decode mismatch fixed (companion to the v0.2.4 Groq fix; same defect class, copy-paste bug in the OpenAI provider). Riding along: codexu's autonomous-loop work since v0.2.4 — pure-Go WASI Whisper transcriber wired into Telegram STT (no CGO, no Python, local fully-offline transcription path), V4A patch tool resilience hardening (block-anchor matching, fuzzy strategies, unicode normalization, rollback on failure), kanban orchestrator board tools + tail event follower, provider stream-drop upstream diagnostics, Hermes i18n locale parity expansion, and CI release-binary metadata smoke gate. See CHANGELOG.md for the full annotated list. * fix(tooltrace): show URL/query head, not tail, in tool-call previews `web_search`, `web_extract`, `web_crawl`, and `browser_navigate` were on the right-edge-truncate list, so Telegram showed previews like `web_search: "...et docs websocket WSS Quickstart CLOB"` and `web_extract: "...et.com/market-data/websocket/overview"` — hiding the search query's first words and the URL's domain behind a leading "...". Move them off the right-edge list. File-path tools (`read_file`, `write_file`, `patch`) keep tail-preview because the filename usually matters more than the directory chain. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> * chore(cron): add opencode-tuned prompt for the local-model builder lane The codex prompt assumes MCP-style skill calls (`gormes-skill-manager`, `gormes-git`) and a large-frontier model can hold the full parity-then- plan-then-build pipeline in head. opencode discovers SKILL.md files via its `skill` tool, has no MCP endpoint for these skills, and runs against a local ollama model (qwen3-coder:30b MoE on this rig) with much less cognitive headroom — the existing prompt sent the model into infinite `skill_mcp` retry loops. Add `opencode_prompt()`: tells the agent to use the `skill` tool (not `skill_mcp`), bias toward one tiny safe step per cycle, exit cleanly when confused, and never touch unfamiliar untracked files. Wire the backend dispatch to pick the right prompt for the active backend. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> * chore(cron): teach opencode prompt about strict tool-call schemas qwen3-coder:30b on opencode follows the structured-exit pattern but doesn't know the bash tool requires both `command` and `description` args, so it failed its first call with a SchemaError and bailed cleanly via "I am stopping because: ...". Add explicit reminders for the bash/read/edit/write tool shapes opencode enforces. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> * docs(progress): plan gateway /model interactive provider/model picker Author Phase 2.B.5 row "Gateway /model interactive provider/model picker" covering the Hermes _handle_model_command no-arg path: 2-step provider→model inline-keyboard picker on Telegram (mp:/mm:/mg:/mb:/mx: callback family), "Select a provider:" header parity, per-session model/provider override seam, and static-text fallback for non-inline channels. Distinct from the complete Cobra-CLI row at Phase 5.O — this slice writes a per-session override, not hermes.model/hermes.provider in TOML. Source-refs pinned at hermes-agent@d4b26df8 (current submodule sha) covering gateway/run.py:_handle_model_command, platforms/telegram.py:send_model_picker + _build_model_keyboard + _handle_model_picker_callback, and hermes_cli/model_switch.py:list_picker_providers. Relax internal/progress/progress_test.go:Phase2ExecutionQueue to allow 2.B.5 derived status of complete OR in_progress now that a newly discovered gateway-handler gap reopens the subphase. Per-row complete/validated asserts below remain locked. Regenerated docs/site progress mirrors via `go run ./cmd/progress write`. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> * fix(gateway): align tool-progress preview tests with head-edge truncation Commit b60a0e3 (fix(tooltrace): show URL/query head, not tail, in tool-call previews) moved web_search/web_extract/web_crawl/browser_navigate off the right-edge-truncate list in internal/tooltrace, but missed the gateway-level render tests still asserting the old tail-preview shape: - TestFormatToolProgressPlain_TruncatedWebPreviewsKeepRightEdge - TestFormatToolProgressPlain_MineruGatewayTranscriptShape Update those tests to match the shipped head-preview behavior (URL/query head visible, trailing "..." after truncation) and rename the first test to KeepLeftEdge so the name matches reality. Production code is unchanged. Unblocks PR-to-main CI gate; the failing tests passed on main only because main does not yet carry b60a0e3. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
No description provided.