Skip to content

api: expose evidence_verify as an additive op (unblocks dsh-sessionflow#9 / C1) #22

Open

Description

@HarryHeYu

Problem

voyager evidence verify <session_id> <seq> [digest] --json is fully implemented
and correct (voyager/evidence.py, voyager/cli.py:141-158), but it is
CLI-only. voyager/api.py:522-532 _OPS has 9 ops and none for evidence;
MCP has none. docs/MAINTENANCE.md known-issue #6 and
docs/audits/2026-11-next-phase-baseline.md:65 record this as "CLI only; no
API/MCP wrapper… deferred until something consumes it". That consumer now
exists: dsh-sessionflow#9
(C1 sessionflow_evidence_verify), where the maintainer has confirmed
Option A in
this decision.

The technical reason an op is required (not optional): the plugin's
runJson() throws CLI_FAILED on any non-zero exit code, while
voyager/evidence.py:39-45 uses exit codes 1–4 for the normal verdicts
MISMATCH, NOT_FOUND, UNVERIFIABLE, INVALID_REFERENCE. A direct CLI call
would discard four of the five states. callOp() reads a single JSON line from
voyager api and returns payload.result, so the verdict lives in
result.status, decoupled from the process exit code.

Scope (thin wrapper ONLY)

  • Add one additive op (e.g. evidence_verify) to _OPS that calls the existing
    evidence.verify() and returns its dict verbatim — at minimum status,
    exit_code, session_id, seq, digest, found_digest,
    source_available, message.
  • No changes to verify(), EXIT_CODES, the five-state semantics, the CLI,
    the help text, fingerprint serialisation or event_digest.
    FINGERPRINT_ALGORITHM is sha256-8hex-json-v1 (canonical JSON,
    voyager/util.py:171); any future change to it is a breaking change with a
    release-note obligation. Verification logic stays in Core, once.
  • BRIDGE_SCHEMA_VERSION = 1 (api.py:216) stays 1. This is an additive
    op, following the existing precedent in api.py; no version sniffing.
  • integration_info() (api.py:501-515) derives ops/capabilities from
    _OPS, so the new op becomes discoverable automatically.
  • Do not add an MCP tool, do not touch resolveVoyager(),
    REQUIRED_CORE_REF, the continuity engine, Store, or the bridge protocol.
  • Out of scope: Evidence claim-vs-observation research, DSH provenance
    classifier (MAINTENANCE.md Codex SessionStart relay hardcodes C:\Python314\python.exe, so the hook silently does nothing on any other machine #13), audit-state naming (Continuation Bundle keeps only each session's last assistant message #14, tracked in
    dsh-sessionflow#2),
    OpenCode Phase 3, native resume, and any widening of CI matrices.

Old-Core behaviour (must not be confused with a verdict)

handle_request() returns unknown op: 'evidence_verify' (ops: …)
(api.py:541) when the op is absent. The plugin must surface that as
"this Core does not support evidence_verify" — never as evidence
NOT_FOUND (which means the referenced session/event is gone) and never as
MATCH. callOp converts payload.error into OP_ERROR, so this path is
testable.

Acceptance tests

  1. All five states round-trip through the op by name, including:
    • no digest → UNVERIFIABLE;
    • malformed seq / non-8-hex digest → INVALID_REFERENCE;
    • unknown session / seq → NOT_FOUND;
    • a rewritten transcript → MISMATCH;
    • a consistent reference → MATCH.
  2. Every state returns {id, result} with result.status; the verdict is
    not carried by the process exit code.
  3. integration_info()["ops"] contains the new op name.
  4. unknown op degradation is asserted against a Core without the op.
  5. MATCH stays "this reference is consistent", never "the claim is true"
    (existing tests/test_evidence_help.py pins the wording — unchanged).
  6. Full Core suite green; scripts/check_consistency.py --strict OK; any new
    docs/*.md must be registered in docs/INDEX.md or test_docs.py fails.
  7. Verification level: UNIT_TESTED here; INTEGRATION_TESTED with the plugin
    over the bridge in the linked plugin PR. No LIVE_VERIFIED claim.

Dependencies / merge order

  1. Prerequisite: maintainer resolves the workflow OAuth scope so Core
    a41324c (release.yml scratch-segment fix) can be pushed and Core CI is
    fully green. Do not work around the permission or force-push.
  2. This op lands, is tested and merged first, and only after an installable
    Core version exists may the plugin PR be formally accepted.
  3. No new release/tag in this issue; the existing v1.3.1 tag is untouched.
  4. Cross-repo rule (CONTRIBUTING.md): two linked issues/PRs, core first,
    then plugin
    . Keep dsh-sessionflow#9
    as the design record.

Claiming

Open for @SunnyRad, who raised and scoped the design in
dsh-sessionflow#9 and
expressed the intent to submit the minimal Core PR. The maintainer will not
pre-empt this implementation. Please comment here to claim it; no fixed
deadline. A plugin-side contract-test draft PR may be prepared in parallel but
should be marked blocked on an installable Core version.

Verification level of this issue: design/scope only, NOT_VERIFIED.

Activity

  1. HarryHeYu commented on Nov 12, 2026

    @HarryHeYu
    OwnerAuthor

    感谢你之前对 Evidence Verification 做的详细设计分析!

    我这边已经确定采用 Option A:Core 新增 additive evidence_verify API op,Plugin 通过现有 callOp() 调用。

    这一方向欢迎你继续主导推进,Core #22 和 Plugin #9 的实现都可以由你认领。我会负责接口与架构 Review,以及真实 Core 集成验收。

    目前我这边正在推进 OpenCode Adapter Phase 3 的真实 Schema 兼容修复,这部分由我负责,不需要你重复投入。

    Evidence 这边建议按以下顺序:

    1. 先完成 Core api: expose evidence_verify as an additive op (unblocks dsh-sessionflow#9 / C1) #22 的最小实现,只包装现有 evidence.verify(),不修改五态语义、指纹算法和 CLI。
    2. 补齐五态 API 回归,确认 MATCH、MISMATCH、NOT_FOUND、UNVERIFIABLE、INVALID_REFERENCE 都能正常返回。
    3. 保持 schema_version = 1,通过 integration_info().ops 暴露新增能力。
    4. 提交 Core PR,等 Review 和 CI 通过后合并。
    5. 再完成 Plugin sessionflow_evidence_verify,通过 callOp() 接入,旧 Core 不支持时明确提示。
    6. Plugin 侧补充真实 Core 集成测试,确认五态没有被 Bridge 转换成调用失败。

    Plugin 的 Draft PR 和 Stub 测试可以提前准备,但正式合并仍遵守 Core 先行原则。

    我这边 Core 的 Release Workflow 还存在一个权限授权问题,不过这是发布工程问题,不需要因此停止你在功能分支上开发和提交 Draft PR。正式发布前会完成处理。

    这项工作不设固定期限,你有时间就推进;如果遇到 Core 接口设计方面的问题,可以直接在 Issue 或 PR 中讨论。

    感谢你此前连续几个 PR 的高质量贡献,也感谢你在跨仓修改前先明确设计边界。

  2. SunnyRad commented on Nov 12, 2026

    @SunnyRad
    Contributor

    Claiming this as invited by @HarryHeYu (see #22 and the division-of-labor note on dsh-sessionflow#9). I'll keep the change strictly additive: one thin pass-through op over evidence.verify(), five states unchanged, schema_version = 1, new test + no other file touched. Core PR first; the plugin PR follows after an installable Core version exists. No fixed deadline.

    — SunnyRad

  3. HarryHeYu commented on Nov 12, 2026

    @HarryHeYu
    OwnerAuthor

    Acceptance on PR #24 passed at 856a09e (unchanged): thin wrapper only, all five verdicts returned via the API with exit_code as a field, schema_version stays 1, integration_info().ops includes evidence_verify, and an older Core returns unknown op (an error, never evidence NOT_FOUND). I ran the op directly for each state: MATCH 0 / MISMATCH 1 / NOT_FOUND 2 / UNVERIFIABLE 3 / INVALID_REFERENCE 4.

    PR is still Draft and stays that way until @SunnyRad marks it Ready — I am not changing its status. Merge order remains Core-first; the plugin tool (#9) should not be accepted before an installable Core containing this op exists. No release in this round.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementNew feature or requesthelp wantedExtra attention is needed

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions