• v5.10.0 692a4a526c

    v5.10.0 Stable

    ktg released this 2026-08-18 14:49:21 +00:00 | 11 commits to main since this release

    No known key found for this signature in database

    v5.10.0 — 2026-08-18 — STORM bounded research loop (default-off) + the Agent-tool name spawn defect

    Additive. Every new research mechanism ships inert: VOYAGE_STORM_ENABLED is
    unset by default, and with it unset both new /trekresearch phases are no-ops.
    The one change that affects consumers regardless of flags is the spawn rule under
    Fixed — it changes how any repo should call the Agent tool.

    STORM bounded loop — shipped, default-off, behind a pre-registered adoption gate

    • /trekresearch Phase 4.5 (dimension discovery, under the existing
      maxDimensions: 8 ceiling) and Phase 5 (bounded multi-turn follow-up,
      replacing the single follow-up pass) run only at effort: high and only
      when VOYAGE_STORM_ENABLED=1. Unset, Phase 5 is inert because
      lib/util/research-loop-cap.mjs grants a budget of 0, and Phase 4.5 is inert
      because its skip-guard reads the flag directly (it never calls the cap) — two
      independent off-switches, so a bug in one does not silently activate the other.
    • TREKRESEARCH_MAX_CONV_TURNS (default 3; invalid values fall back to 3)
      sets turns per dimension. The total budget is that value × maxDimensions.
    • New lib/util/research-loop-cap.mjs: an append-only ledger the cap counts its
      own turns from. Each turn slot is claimed with O_EXCL, so the bound survives
      concurrent turns; an unreadable ledger fails closed in both modules; and
      the enforcement boundary is a denial tombstone rather than the turn count, so
      a crash mid-turn cannot hand back a free turn.
    • New hooks/scripts/pre-agent-cap.mjs, registered as a PreToolUse hook on
      WebSearch|WebFetch|Task: the budget is enforced by the harness, not by prose
      in a command file. VOYAGE_DISABLE_CAP_HOOK=1 switches it off.
      docs/spike-pretooluse-subagent-reach.md records the measured reach of
      PreToolUse into sub-agent tool calls — including where the gap is.
    • Five measurement fields (unique_sources, dimensions_baseline, conv_turns,
      empty_turns, dimensions_baseline_preserved) are emitted to
      trekresearch-stats.jsonl and allowlisted in lib/exporters/field-allowlist.mjs.
      All five are counters or booleans — none carry prose or paths.
    • scripts/storm-measure.mjs + docs/storm-measurement.md: the adoption gate,
      with thresholds registered before the first measurement by design.
      ≥ 30 % improvement on either metric → adopt; < 15 % → decline; an empty arm is
      insufficient-data, not a decline. Decline is a no-op — the mechanism simply
      stays default-off; adopt is one constant. No measurement has been run yet.

    Added — outbound query privacy gate

    • lib/validators/query-privacy-gate.mjs inspects a research query before it
      leaves the machine, in the same two-tier shape as the existing SSRF gate: a
      WARN tier (absolute filesystem paths, repo-internal identifiers) that
      --soft / VOYAGE_QUERY_PRIVACY_ALLOW=1 can override, and a HARD-BLOCK tier
      (secret-shaped tokens) that nothing overrides. Called only from the two new
      high-effort steps; the existing single-pass path is unchanged.

    Fixed — the Agent tool's name parameter silently breaks a subagent's return channel

    • Consumers of this pipeline should read docs/agent-return-channel-defect.md.
      Passing name to the Agent tool does not label a subagent — it changes what is
      spawned: taskKind: "in_process_teammate" / spawnDepth: 0 instead of a real
      subagent (spawnDepth: 1). A teammate's final text is not a return value; it
      reaches the parent only if the teammate itself calls SendMessage(to: "main").
      Voyage's reviewer agents carry tools: [Read, Glob, Grep] — no SendMessage
      so when named they are structurally unable to answer. No error, no warning.
      Measured numerators (66-line target): named without explicit SendMessage
      0/5 returned · named + explicit SendMessage 1/1 · unnamed 3/3 ·
      work actually performed while named 5/5 — only delivery fails, and the
      output is recoverable from
      ~/.claude/projects/<project>/<session>/subagents/agent-*.jsonl.
      Independently confirmed at 3730 lines / 277 KB by akashic-intelligence
      (4/4 correct final text on disk); the returning arm above 66 lines remains
      inferred rather than observed, and the doc says so.
    • The four spawning commands (trekbrief, trekplan, trekresearch,
      trekreview) now state the rule at their spawn sites and name the mechanism.
      trekexecute spawns nothing and is excluded. The doc-consistency test
      derives the spawning set from the command files, so the pin cannot go
      vacuous when a command starts or stops spawning.

    Fixed — hook and validator hardening

    • The destructive-command rule anchored on command position rather than any
      substring (a path containing a blocked word no longer trips it), and the
      bypasses that anchoring itself opened are closed.
    • The secret-detection validator hard-blocks token formats the run-length
      patterns missed.
    • The exporter allowlist covers /trekresearch's engine field, with the JSONL
      schema fixture pinned to agree — a new stats field is otherwise dropped
      silently at export.

    Docs

    • README: first screen aligned with the org repo standard, complete AI
      disclosure, and the Gemini MCP tool contract described inline instead of via a
      dead cookbook link. Governance keeps one canonical file, not a local copy.
    • /trekresearch: STORM mechanisms documented across four surfaces; the
      Independence crossing's two risks split, each naming its own control.
    • docs/*.pdf is gitignored — origin is a public mirror and must never carry
      operator PDFs.

    Tests

    • Suite baseline 832 (830 pass / 0 fail / 2 skip) → 1013 (1011 / 0 / 2).
      New coverage: research-loop-cap (including the concurrency and fail-closed
      paths), the cap hook's crash-time marker branches, the query privacy gate, the
      measurement harness's decision rule, and the spawn-rule doc pin.
    Downloads
  • v5.9.1 8d39e1d4a5

    v5.9.1 Stable

    ktg released this 2026-07-02 23:11:25 +00:00 | 50 commits to main since this release

    Patch, no functional additions.

    Fixed

    • /trekendsession was unusable in every invocation: two of its three !`...` eager-exec blocks (Phase 3 atomic-write, Phase 4 validator call) contained unresolved runtime placeholders (<project-dir> etc.). The harness executes eager-exec blocks at command LOAD time, so zsh parsed <project-dir> as input redirection and the command aborted before the model saw a single instruction. Both blocks are now plain runtime Bash fences with the {curly} placeholder convention (shell-inert), matching trekplan.md/trekresearch.md. The Phase 1 discovery block (self-contained) keeps its legitimate eager-exec prefix; trekcontinue.md's discovery block was runtime-verified unaffected.
    • Latent secondary bug in the same blocks: cwd-relative plugin paths (lib/validators/..., ./lib/util/atomic-write.mjs) would have failed with ERR_MODULE_NOT_FOUND even after substitution, since the Bash cwd is the user's repo. Both now use absolute ${CLAUDE_PLUGIN_ROOT} paths per the existing command convention (Node ESM accepts absolute-path import specifiers — verified on Node 18+).

    Added

    • Regression guard tests/commands/trekendsession.test.mjs: scans every !`-block in commands/*.md for unresolved <angle>/{curly} placeholders (this bug class is silent until first invocation), plus structure tests pinning Phase 3/4 as runtime Bash with ${CLAUDE_PLUGIN_ROOT} paths and exactly one surviving eager block. Suite baseline 828 → 832 (830 pass / 0 fail / 2 skip).
    Downloads