Agent Skills › modu-ai/moai-adk › moai-ref-cross-model-audit

moai-ref-cross-model-audit

GitHub

该技能为审计代理提供跨模型审核收敛参考,指导调用audit_multi MCP工具并行分发代码审查至Claude、Codex和GLM后端,合并独立裁决并处理分歧。

.claude/skills/moai-ref-cross-model-audit/SKILL.md modu-ai/moai-adk

Trigger Scenarios

需要执行跨多个AI模型(如Claude, Codex, GLM)的代码审核 需要聚合不同后端模型的审查结果并生成统一审计报告

Install

npx skills add modu-ai/moai-adk --skill moai-ref-cross-model-audit -g -y
More Options

Non-standard path

npx skills add https://github.com/modu-ai/moai-adk/tree/main/.claude/skills/moai-ref-cross-model-audit -g -y

Use without installing

npx skills use modu-ai/moai-adk@moai-ref-cross-model-audit

指定 Agent (Claude Code)

npx skills add modu-ai/moai-adk --skill moai-ref-cross-model-audit -a claude-code -g -y

安装 repo 全部 skill

npx skills add modu-ai/moai-adk --all -g -y

预览 repo 内 skill

npx skills add modu-ai/moai-adk --list

SKILL.md

Frontmatter
{
    "name": "moai-ref-cross-model-audit",
    "metadata": {
        "status": "active",
        "version": "1.1.0",
        "category": "domain"
    },
    "description": "Cross-model audit convergence reference for the plan-auditor and sync-auditor agents. Documents how to invoke the `audit_multi` MCP tool to fan a code review out across the Claude subscription, codex, and GLM (z.ai) backends, converge their independent verdicts, and fold the resulting per-backend verdicts + disagreement flag into the audit output. The single skill both audit entry points load — no duplication.\n",
    "when_to_use": "Use when the audit plan (`moai verify audit-plan`) reports a cross-model backend AND the auditor needs a cross-backend second opinion before reaching a verdict. Also use when the auditor runs under a GPT or GLM main session and needs an independent Claude subscription verdict through `claude_audit`, or when it must explain why the convergence result is a pass, fail, or advisory-only disagreement.\n",
    "user-invocable": false
}

Cross-Model Audit Convergence

This skill is the single load-point both plan-auditor and sync-auditor use when the audit plan reports a cross-model backend. It documents the one MCP tool the auditor calls, the independence rule that tool enforces, how to check the result against the plan, and how to fold the returned convergence result into the auditor's verdict.

When to use convergence vs single-model

The auditor does not choose a backend by interpreting the audit_model value. It runs moai verify audit-plan --project-root <own toplevel> first (the full flow is in each agent's MCP Audit Tools section; pass the toplevel yourself, because CLAUDE_PROJECT_DIR names the primary checkout in a worktree session) and follows the plan:

Outcome of the verb Path This skill
config_status ok or absent, cross_model_active: false (the distributed default, an explicit claude token) Claude main: in-session review; GPT/GLM main: claude_audit for external-main sessions
cross_model_active: true audit_multi without a gates argument: the plan's backends, converged this skill
The output is the verify group's help text (it contains Shared diagnostic snapshot contract and neither config_status nor an audit-plan: line) The legacy path below, with "plan surface unreachable, legacy path used" named as a Gap only as the legacy path says
config_status: unreadable, an audit-plan: error, or any other failure to run the verb (refused, crashed, timed out, malformed output) Not the legacy path: a PASS-blocking Gap; a configured required backend that does not answer stays fail-closed no PASS on this audit

Legacy path (a binary that predates the verb). Behave as before the plan verb existed: read the project's audit_model from workflow.yaml — multi converges Claude, codex and GLM via audit_multi, claude keeps the single-model path, glm and codex call that one backend directly. Wherever audit_multi is called, pass it without a gates argument, and call it whenever the tree's workflow.yaml sets an audit model other than claude or any audit.gates key, so a plan-aware server applies the configured plan.

Single-model paths do NOT load this skill. Convergence is only the cross-model concern.

The audit_multi MCP tool

The single tool surface is:

mcp__moai__audit_multi

It is exposed by the moai mcp-server stdio server (the self-hosted MCP server shipped with the binary). The tool is a thin wrapper over the convergence engine: it does NOT re-implement the codex or GLM backends — it fans out by calling the existing single-backend handlers in parallel and synthesizes their results.

Input parameters

Parameter Type Required Notes
claude_verdict object conditional Claude main sessions pass their in-session verdict. GPT/GLM/unknown-origin sessions may omit it; audit_multi ignores any supplied value and performs a fresh Claude subscription audit.
target string no What the secondary backends review (uncommittedChanges, baseBranch). The string reaches both backends unchanged; for codex, baseBranch's branch name is then resolved server-side from the reviewed tree (remote default head, then main) — it cannot be supplied here.
focus string no Optional focus area forwarded to the secondary backends (e.g. concurrency, auth).
gates object no Per-auditor gate map (claude/codex/glm ∈ off/advisory/required). Auditors do not pass it: omitted, the tree's own plan applies (the configured audit model and gates); with no configuration the distributed defaults apply — claude required, codex required, glm advisory — and an unconfigured gate stays fail-open.
session_id string no When set, the result is persisted to .moai/state/audit-multi/<session>.json so the multi-review-gate Stop hook reads the most recent result rather than re-invoking convergence.
project_root string no (REQUIRED in a worktree) The tree the backends should read — this session's own git rev-parse --show-toplevel. Omitted from a worktree, the fan-out reads the PRIMARY checkout instead, so the backends review a diff that is not the one under audit and nothing in the result says so. Omit it only in the primary checkout. An unusable path is rejected with an error naming it, never silently replaced.

Contract-mode second review (card-bound). When the reviewed card runs under a contract-based autonomy workflow, invoke the tool with the card argument so this fan-out is recorded as the card's second review:

  • pass card_id set to the card identifier from the reviewed card's contract;
  • keep target: "baseBranch" — the review must cover the reviewed scope, never uncommitted changes;
  • run the review AFTER the last commit that changes the card's governed paths (the contract's ownership write globs, excluding the SPEC's own directory), so the recorded scope is current for the commit that will be judged; a review recorded before that commit is stale for the closure push.

The tool appends one second-review record into the card evidence directory. Without card_id no record is written and the tool behaves byte-identically to the pre-argument surface.

Output shape

The tool returns a ConvergenceResult:

{
  "per_backend_verdicts": [
    {"backend": "claude", "source": "mcp_claude_audit", "gate": "required", "verdict": "pass", "summary": "...", "findings": [], "next_steps": [], "provenance": {"transport": "claude-code-cli", "auth_mode": "subscription", "requested_model": "sonnet", "resolved_model": "claude-sonnet-...", "requested_effort": "high", "session_persisted": false}},
    {"backend": "codex",  "gate": "required", "verdict": "fail", "summary": "...", "findings": [...], "next_steps": []},
    {"backend": "glm",    "gate": "advisory", "verdict": "pass", "summary": "...", "findings": [], "next_steps": []}
  ],
  "overall_verdict": "fail",
  "disagreement_flag": true,
  "participant_count": 3,
  "residual_risk_note": "required-backend FAIL: codex; cross-model disagreement: pass=[claude(required), glm(advisory)] fail=[codex(required)]",
  "fail_open_backends": []
}
  • overall_verdict ∈ {pass, fail} — the existing review-output values. No new enum (disagreement is a flag, not a verdict value).
  • next_steps is populated ONLY where the backend itself produced it. A backend that returns a structured review carries its model's own list; a backend that answers in prose carries none, so its entry shows [] even on a fail with findings. An empty next_steps beside a non-empty findings is therefore the expected shape, not a truncated result — do not read the finding text as steps.
  • participant_count is how many backends contributed a comparable verdict: every entry whose gate is not off and whose verdict is pass or fail. inconclusive entries (missing, unauthenticated, erroring) are evidence-of-absence, not participants, and do not count. The field is always present, 0 included — it reports the count; no minimum-participant policy acts on it.
  • disagreement_flag is three-valued. true = a divergence was observed: a required split, an advisory-only conflict, or a single participant's intra-backend synthesis divergence (directly observed divergences are never discarded, even below 2 participants). false = 2+ participants were compared and none diverged. null = undetermined: fewer than 2 participants were compared and no divergence was observed, so neither "they agreed" nor "they disagreed" is a grounded claim. The null is explicit — the member is always present in the JSON, never an absent key.
  • residual_risk_note describes the convergence outcome in prose (which backend(s) failed, or the shape of the split). Surface this in the audit report's residual-risk section.
  • fail_open_backends lists the backends that returned inconclusive (missing, unauthenticated, or erroring) — surfaced so the report can name them.
  • plan_source is config when any backend's gate came from the tree's configuration, and absent otherwise. A result without it from a tree whose plan has configured gates comes from a server that predates the plan: the check below reports an unmet gate.
  • source distinguishes an in-session Claude anchor from a real mcp_claude_audit call. provenance identifies transport, subscription auth, requested/resolved model, effort, tool surface, persistence, usage source, and sanitized error code. Token counts are null when the CLI does not report them; they are never guessed.

How to invoke

In a Claude main session, call the tool with the in-session analysis folded into the claude_verdict object. Do NOT pass the full analysis text as prompt context for the other backends — see the Independence rule below.

result = mcp__moai__audit_multi({
  claude_verdict: { verdict: <your verdict>, summary: <one-line>, findings: [...], next_steps: [...] },
  target: "uncommittedChanges",
  focus: "concurrency",
  project_root: <git rev-parse --show-toplevel>,
  session_id: <current session id>
})

In a GPT or GLM main session, omit claude_verdict (or treat it as ignored):

result = mcp__moai__audit_multi({
  target: "uncommittedChanges",
  focus: "concurrency",
  project_root: <git rev-parse --show-toplevel>,
  session_id: <current session id>
})

The launch provider decides the path; prompt text cannot impersonate a Claude main session. Direct single-backend use is mcp__moai__claude_audit with the same target/focus/project-root scope and optional model/effort override.

The orchestrator-side question channel is preserved: the tool returns a structured result, never prompts the user. When a required backend is inconclusive, surface the structured overall_verdict: fail plus residual_risk_note in the audit report and let the orchestrator translate.

Independence rule (load-bearing)

Pass only the synthesized claude_verdict object to the MCP tool — NEVER the full Claude analysis text as prompt context for the secondary backends.

The external backends (Claude subscription, codex, GLM) are SUPER-REVIEWS: uncorrelated second opinions. Their value collapses to a re-sample of another model's reasoning the moment they see Claude's analysis. The convergence engine enforces this structurally — the claude_verdict is consumed ONLY as a Claude-main anchor. For GPT/GLM origins it is ignored, and the backends receive (target, focus, project_root) — a scope, an area name, and a directory, carrying no analysis between them. The auditor must not undermine the invariant by pasting another backend's reasoning into the focus field either.

Concretely:

  • focus carries a short AREA name (concurrency, auth, secret handling), not a paragraph of analysis.
  • claude_verdict.summary is a one-line verdict rationale, not the full review.
  • The findings you surface in the audit report come from per_backend_verdicts[].findings (each backend's own findings), NOT from echoing Claude's findings back.

Convergence policy (how overall_verdict is derived)

The engine derives overall_verdict per a 4-case table:

Case Condition overall_verdict disagreement_flag
1 All required backends PASS pass false
2 Any required FAIL (no required PASS to split against) fail false
3 Required split (≥1 required PASS + ≥1 required FAIL) fail (conservative) true
4 Advisory-only conflict (all required PASS, ≥1 advisory FAIL) pass true

Two invariants follow:

  • Disagreement is advisory, NOT a block. A disagreement_flag: true result is surfaced as residual-risk + advisory in the audit report; it never hard-blocks the flow on its own. The required-gate contract holds per backend, so the only block-shaped outcome is a required FAIL (cases 2/3 → overall_verdict: fail).
  • Advisory backends never flip overall to fail. Case 4 records the advisory conflict but keeps overall_verdict: pass. This is the fixed user-policy term: an advisory FAIL is reported, not enforced.
  • An explicitly configured required gate left unmet fails overall. A gate the project sets to required in workflow.audit.gates must actually hold: when that backend returns inconclusive (missing binary, auth failure, error), the engine fails overall_verdict and names the unmet backend in residual_risk_note. A gate the project never configured keeps the fail-open behavior — the distributed default is NOT an opt-in. In both cases the backend's own per_backend_verdicts entry stays inconclusive and its fail_open_backends listing stays, so the audit trail keeps saying the backend never ran.
  • Below 2 participants the flag is null, not false — unless a divergence was observed. The case table presumes a comparable field of 2+; when participant_count is 0 or 1 (for example the only required backend to produce a verdict is claude), "no disagreement detected" is not a grounded claim and the flag reports null. The carve-out: an intra-backend synthesis divergence observed by even a single participant keeps the flag true — observed information is never discarded.

Fail-open identity

Claude subscription, Codex, and GLM audit transports are fail-open. A missing, unauthenticated, erroring, or malformed backend yields verdict: inconclusive in its per_backend_verdicts slot and convergence continues over the remaining active backends. The autonomous flow is NEVER hard-blocked on a missing optional dependency — evidence-of-absence ≠ evidence-of-failure.

In a Claude main session, when all external backends are inconclusive, the overall verdict can fall back to the in-session Claude anchor — EXCEPT for a gate the project explicitly configured required in workflow.audit.gates: that gate left unmet fails overall_verdict instead (see the convergence policy above).

Checking the result against the plan

After an audit_multi call on a tree whose plan lists enforced_required backends, the result is checked before a verdict is reached:

  1. Write the digest of the result just obtained to <toplevel>/.moai/state/audit-plan-result.json with a Write tool — fresh, immediately before the check: overwrite any earlier file at that name and never reuse a file from an earlier audit. The digest holds overall_verdict, gate_unmet, plan_source and, per per_backend_verdicts entry, backend, gate and verdict — digest members only, never summary or finding text.
  2. Run moai verify audit-plan --project-root <toplevel> --result-file <that path> and pass only the path — never the JSON on the command line (the worktree guard refuses braces and quotes).
  3. Read convergence_check: ok: false is an unmet gate named by backend, no PASS, reported as an unmet gate and not as a reviewed defect.

plan-auditor carries Write and does steps 1-3 itself. In the sync phase the orchestrator does them: a cold sync-auditor is read-only, so it returns the digest members in its report, says its verdict is not final until the orchestrator's check passes, and the orchestrator writes the file and runs the check.

Folding the result into the audit verdict

The auditor's verdict and the convergence result relate as follows:

overall_verdict disagreement_flag Auditor action
pass false Standard PASS. No residual-risk row needed.
pass null Standard PASS. The flag is undetermined (participant_count below 2, no observed divergence) — not an agreement claim. No residual-risk row needed.
pass true PASS with a residual-risk row naming the advisory disagreement.
fail (any) FAIL. Name the failing required backend(s) from per_backend_verdicts. The block is conservative (cases 2/3).

In all cases, surface residual_risk_note verbatim in the audit report's residual-risk section so a human reader sees which backend disagreed with which.

Cross-references

  • mcp__moai__claude_audit, mcp__moai__codex_audit, mcp__moai__glm_audit — the single-backend tools. The convergence engine calls the same backends through its own fan-out and does NOT route through these handlers, so a behavior read from one surface must be confirmed on the other rather than assumed shared.

  • workflow.audit.gates.* — the per-auditor gate map (off/advisory/required). An explicit required is enforced on BOTH surfaces: on the convergence result an unmet required gate (its backend inconclusive) fails overall_verdict, and the single-backend codex_audit tool likewise returns verdict: fail with a non-empty gate_unmet and isError: false when an explicitly required codex gate is left without a verdict. Absent keys fall back to the distributed defaults WITHOUT that enforcement — write the key to opt in.

  • Audit receipts. Where the codex gate is explicitly required, the server records a receipt for every codex audit it performs and returns its id on the result as audit_receipt. Cite the ids you received in the verdict line that ends your report:

    AUDIT-VERDICT: <PASS|PASS-WITH-DEBT|FAIL> spec=<SPEC-ID> receipts=<receipt-id>[,<receipt-id>...]
    

    The line is the LAST non-empty line of the final message; receipts=none says no receipt was issued. A PASS the receipt store cannot corroborate is refused at subagent stop, and the phase-entry spawns stay denied until a PASS citing a valid receipt is recorded. The check reads the store, never the report text — quoting an id the store does not carry proves nothing.

  • workflow.multi.review_gate.enabled — opt-in toggle for the multi-review-gate Stop hook (the Path C fully-autonomous gate). Default OFF; opt in via local config.

Version History

  • 6dde1c1 Current 2026-10-19 18:21

    引入基于计划动词的验证路径,增强对配置状态和计划一致性的检查;支持在计划不可达时回退至遗留路径但阻断通过;增加文档表面测试。

  • 48239c7 2026-08-28 20:11

    新增 project_root 参数以支持 Worktree 环境下的正确目录定位,防止审计错误仓库;更新独立性规则说明。

  • 4100d87 2026-08-20 09:09

Same Skill Collection

.claude/skills/hns-lsel-curator/SKILL.md
.claude/skills/hns-moaiadk-dev-reference/SKILL.md
.claude/skills/hns-oss-docs-i18n-rules/SKILL.md
.claude/skills/hns-oss-docs-readme-sync/SKILL.md
.claude/skills/hns-oss-docs-structure-map/SKILL.md
.claude/skills/hns-oss-docs-verify/SKILL.md
.claude/skills/hns-workflow-ci-loop/SKILL.md
.claude/skills/moai-domain-backend/SKILL.md
.claude/skills/moai-domain-database/SKILL.md
.claude/skills/moai-domain-frontend/SKILL.md
.claude/skills/moai-domain-humanize/SKILL.md
.claude/skills/moai-domain-svg-infographic/SKILL.md
.claude/skills/moai-factory-foreman/SKILL.md
.claude/skills/moai-foundation-cc/SKILL.md
.claude/skills/moai-foundation-core/SKILL.md
.claude/skills/moai-foundation-quality/SKILL.md
.claude/skills/moai-foundation-thinking/SKILL.md
.claude/skills/moai-harness-learner/SKILL.md
.claude/skills/moai-jev-skill-suggestion/SKILL.md
.claude/skills/moai-kanban-foreman/SKILL.md
.claude/skills/moai-lane-watchdog/SKILL.md
.claude/skills/moai-meta-harness/SKILL.md
.claude/skills/moai-ref-api-patterns/SKILL.md
.claude/skills/moai-ref-aside-browser/SKILL.md
.claude/skills/moai-ref-git-workflow/SKILL.md
.claude/skills/moai-ref-jev-question-design/SKILL.md
.claude/skills/moai-ref-owasp-checklist/SKILL.md
.claude/skills/moai-ref-react-patterns/SKILL.md
.claude/skills/moai-ref-testing-pyramid/SKILL.md
.claude/skills/moai-ref-ui-polish/SKILL.md
.claude/skills/moai-workflow-ddd/SKILL.md
.claude/skills/moai-workflow-docs-claim-check/SKILL.md
.claude/skills/moai-workflow-loop/SKILL.md
.claude/skills/moai-workflow-project/SKILL.md
.claude/skills/moai-workflow-spec/SKILL.md
.claude/skills/moai-workflow-tdd/SKILL.md
.claude/skills/moai-workflow-testing/SKILL.md
.claude/skills/moai-workflow-worktree/SKILL.md
.claude/skills/moai/SKILL.md
.claude/skills/verify/SKILL.md
.moai/archive/skills/v2.16/moai-framework-electron/SKILL.md
.moai/archive/skills/v2.16/moai-platform-auth/SKILL.md
.moai/archive/skills/v2.16/moai-platform-chrome-extension/SKILL.md
.moai/archive/skills/v2.16/moai-platform-deployment/SKILL.md
.moai/archive/skills/v3.0/moai-design-craft/SKILL.md
.moai/archive/skills/v3.0/moai-design-tools/SKILL.md
.moai/archive/skills/v3.0/moai-docs-generation/SKILL.md
.moai/archive/skills/v3.0/moai-domain-uiux/SKILL.md
.moai/archive/skills/v3.0/moai-foundation-context/SKILL.md

Metadata

Files
0
Version
6dde1c1
Hash
b4ed96e2
Indexed
2026-08-20 09:09

inicio - Wiki
Copyright © 2011-2026 iteam. Current version is 2.155.2. UTC+08:00, 2026-10-19 20:21
浙ICP备14020137号-1