{"server":"io.github.ajc3xc/meridian","count":100,"tools":[{"name":"accept_handoff","title":"Accept Handoff","description":"[SUPPORT] Read-only: (1bd5e810) Canonical receiver-side acceptance check for a handoff envelope — composes token verification, capability/tool availability, tool-manifest drift, and board-revision divergence into ONE structured verdict, so MCP/HTTP/stdio all produce identical results for identical input (same underlying meridian.handoff.accept_handoff_envelope every transport calls). Every input is optional and independently gated — supply whatever you have; an omitted check is skipped, never failed. Returns {accepted: bool, result: 'ok'|'STALE_HANDOFF'|'FOREIGN_PROJECT_CONFIG'|'BOARD_DIVERGENCE'|'TOOL_MANIFEST_DRIFT'|'BODY_HASH_MISMATCH'|'CAPABILITY_UNAVAILABLE', reasons: [str], token_check, identity_check, capability_check, tool_manifest_check, board_check, is_trusted_channel: false, delivery_source: str}. Checks run in this order, short-circuiting on first failure: (1) token — token/presented_body via the same verify_handoff_token check; a body_mismatch reason maps to BODY_HASH_MISMATCH, every other invalid reason (not_found/wrong_project/already_consumed/expired) maps to STALE_HANDOFF — the raw token_check.reason sub-field always preserves which one, since AGENTS.md treats not_found/wrong_project as real spoofing signals and already_consumed/expired as usually just a sibling session having already acted. (2) identity binding (22f2604d) — presented_body's own <project_start_config> tag vs THIS call's project_id/expected_repo_path, via meridian.handoff.check_project_start_config_identity; runs whenever step (1) did not already reject the envelope on its own basis — i.e. token verification passed or no token was presented — so a body whose embedded identity disagrees with project_id is FOREIGN_PROJECT_CONFIG even when the token itself verified ok. This catches a genuine token paired with a foreign project's start-config, which step (1)'s wrong_project check alone cannot (that only catches a token minted for a DIFFERENT project_id, not a body whose own tag disagrees with a token that legitimately matches project_id). It does NOT re-run after step (1) already failed (STALE_HANDOFF/BODY_HASH_MISMATCH) — that failure is independently sufficient to reject the envelope. (3) capability — required_tools vs available_tools: any required name missing from available_tools is CAPABILITY_UNAVAILABLE. (4) tool-manifest drift — expected_required_tools_hash vs a hash computed live from live_items' own tool_requirements fields (see meridian.handoff.compute_required_tools_hash): mismatch is TOOL_MANIFEST_DRIFT. (5) board revision — expected_board_revision (acf6f51a's manifest <handoff_manifest board_revision=...>) vs a hash computed live from live_items via meridian.handoff.compute_board_revision: mismatch is BOARD_DIVERGENCE. live_items is YOUR OWN get_sprint_items(...) result — this tool never queries the board itself, so you control exactly which project/version/status filter \"live\" means; pass the same filter used when the compared handoff/manifest was generated. is_trusted_channel is always false here (calling this tool at all means verifying something other than the trusted pending_goal/load_handoff channel — see those tools' own docs). Scope note: this is a validation/report tool, not a hard gate — it is not wired into claim_sprint_item in this pass. Persistent-state disclosure: on hosted Meridian, supplied text and project/session metadata -- including task log entries, pinned decisions, sprint items, notes, handoff/goal state, and HITL queue items -- are sent to and stored in Meridian's service, in an isolated per-tenant Postgres database (Neon); self-hosted deployments keep the same categories in the configured local SQLite/Postgres database. This data is visible in the dashboard and API, and may resurface in later project context or handoffs. Notes and pinned decisions can be deleted individually; task log entries and sprint items can be deleted via the dashboard/API (not exposed as an agent-facing tool); HITL queue items and handoff state have no per-record delete. Full removal of any of this data is available via project or account deletion, using the documented controls. Do not include secrets.","input_schema":{"type":"object","required":[],"properties":{"goal_token":{"type":"string","description":"Optional: the token value from the <goal_token>…</goal_token> line in the /goal block being accepted."},"live_items":{"type":"array","items":{"type":"object"},"description":"Optional: your own get_sprint_items(...) result (the exact items/filter the compared handoff/manifest was generated from) — required for the tool-manifest-drift and board-revision checks; omit to skip both."},"project_id":{"type":"string"},"session_id":{"type":"string","description":"Optional (1b7eb437): your own claiming session's id, used ONLY to attribute a durable handoff-provenance receipt to this call when accepted=true (action_audit_log, event_type='handoff_provenance_receipt'). Purely additive — omitting it changes nothing about this tool's behavior or return shape. See verify_handoff_token's session_id for the same contract."},"project_name":{"type":"string","description":"Project name — an alternative to project_id; resolved to the id internally. project_id wins if both are given."},"presented_body":{"type":"string","description":"Optional: the full pasted /goal block (token + SECURITY banner included), checked against the token's stored body_hash AND against project_id/expected_repo_path via its own <project_start_config> tag — same contract as verify_handoff_token's presented_body, plus the 22f2604d identity-binding check."},"required_tools":{"type":"array","items":{"type":"string"},"description":"Optional: tool names the handoff declared as required. Paired with available_tools to detect CAPABILITY_UNAVAILABLE."},"available_tools":{"type":"array","items":{"type":"string"},"description":"Optional: tool names actually available to you right now (e.g. from a live tools/list). Paired with required_tools."},"delivery_source":{"type":"string","description":"Optional (22f2604d): a label for how you received this content (default 'chat_paste'). Echoed back verbatim; purely informational bookkeeping alongside the always-false is_trusted_channel."},"expected_repo_path":{"type":"string","description":"Optional (22f2604d): YOUR OWN independently-known repo root (e.g. from your own meridian.toml/cwd) — never a value read out of presented_body itself. Compared against presented_body's <project_start_config repo_path=...>; a disagreement is FOREIGN_PROJECT_CONFIG."},"expected_board_revision":{"type":"string","description":"Optional: the board_revision value from a manifest's <handoff_manifest board_revision=\"...\"> attribute, or any prior meridian.handoff.compute_board_revision(...) result to compare live_items against."},"expected_required_tools_hash":{"type":"string","description":"Optional: a prior meridian.handoff.compute_required_tools_hash(...) result to compare against live_items' current tool_requirements."}}},"output_schema":null,"annotations":{"title":"Accept Handoff","readOnlyHint":false,"openWorldHint":false,"idempotentHint":false,"destructiveHint":false},"source":"probe","observed_at":"2026-09-29T06:40:02.225Z"},{"name":"acquire_docx_document_lease","title":"Acquire Docx Document Lease","description":"[MAINTENANCE] 6507e83a — Whole-document cross-process lease for .docx files, the counterpart claim_docx_region never provided (that tool hard-requires a specific element_id). Use this when a session needs to rewrite an ENTIRE document (a bulk restructure, a canonical-merge promotion) and must block out every other writer, not just one element. Blocked by another live session's whole-file lock (claim_file) OR ANY other live session's claim on the file (lease or scoped element) — a whole-document lease requires the document be free of every other session's claims first. Once held, blocks every other session's writes (via check_docx_region_write_conflict, the same gate update_paragraph and the meridian-docs tunnel relay already enforce) and new claim_docx_region attempts on this file until released or expired (same TTL as every other claim in this module). Returns {leased: true, file_path, session_id} on success or {leased: false, reason, message, ...} on conflict — never raises. Persistent-state disclosure: on hosted Meridian, supplied text and project/session metadata -- including task log entries, pinned decisions, sprint items, notes, handoff/goal state, and HITL queue items -- are sent to and stored in Meridian's service, in an isolated per-tenant Postgres database (Neon); self-hosted deployments keep the same categories in the configured local SQLite/Postgres database. This data is visible in the dashboard and API, and may resurface in later project context or handoffs. Notes and pinned decisions can be deleted individually; task log entries and sprint items can be deleted via the dashboard/API (not exposed as an agent-facing tool); HITL queue items and handoff state have no per-record delete. Full removal of any of this data is available via project or account deletion, using the documented controls. Do not include secrets.","input_schema":{"type":"object","required":["session_id","file_path"],"properties":{"file_path":{"type":"string","description":"The .docx source path."},"session_id":{"type":"string","description":"The calling session."}}},"output_schema":null,"annotations":{"title":"Acquire Docx Document Lease","readOnlyHint":false,"openWorldHint":false,"idempotentHint":false,"destructiveHint":false},"source":"probe","observed_at":"2026-09-29T06:40:02.225Z"},{"name":"activate_profile_layer","title":"Activate Profile Layer","description":"[SUPPORT] 0bec79a7 (PROFILE-5) — Advance a hosted_default layer's lifecycle to 'active' — the single 'publish' operation for the hosted_default floor (fae6e882 pinned decision collapsed 'publish' and 'activate' into this one tool: a hosted_default layer becomes authoritative the moment it reaches 'active', so there is no separate publish step to expose). Only a draft -> active or deprecated -> active transition is valid; any other current state (e.g. retired, which is terminal) rejects with {error}. Idempotent: calling on an already-active scope is a no-op success (same revision, no new audit row). See reset_profile_layer for the non-audited 'clear the row entirely' path, or save_profile_layer followed by this tool for the audited draft-then-publish flow. Persistent-state disclosure: on hosted Meridian, supplied text and project/session metadata -- including task log entries, pinned decisions, sprint items, notes, handoff/goal state, and HITL queue items -- are sent to and stored in Meridian's service, in an isolated per-tenant Postgres database (Neon); self-hosted deployments keep the same categories in the configured local SQLite/Postgres database. This data is visible in the dashboard and API, and may resurface in later project context or handoffs. Notes and pinned decisions can be deleted individually; task log entries and sprint items can be deleted via the dashboard/API (not exposed as an agent-facing tool); HITL queue items and handoff state have no per-record delete. Full removal of any of this data is available via project or account deletion, using the documented controls. Do not include secrets.","input_schema":{"type":"object","required":["scope_id"],"properties":{"actor":{"type":"string","description":"Optional human/session identity recorded on the audit ledger for this transition."},"scope_id":{"type":"string","description":"The hosted_default scope id to activate (typically 'global')."}}},"output_schema":null,"annotations":{"title":"Activate Profile Layer","readOnlyHint":false,"openWorldHint":false,"idempotentHint":false,"destructiveHint":false},"source":"probe","observed_at":"2026-09-29T06:40:02.225Z"},{"name":"add_custom_hook","title":"Add Custom Hook","description":"[MAINTENANCE] 273287cb — define a user-creatable Claude Code hook (PreToolUse | PostToolUse | Stop), generalizing past sprint_guard.sh/.ps1 (the only hook Meridian auto-writes today). Written into the repo's .claude/hooks/<slug>.sh / .ps1 on the next generate_handoff — the same auto-inject mechanism sprint_guard already uses. script_sh (POSIX shell body) is required; script_ps1 (PowerShell body) is optional — omit it to only ever write the .sh file. matcher is a Claude Code tool-name regex (e.g. \"Edit|Write\"), ignored for Stop hooks. blocking (default true) controls determinism vs. suggestion power: true writes the script byte-for-byte so its own exit code drives REAL Claude Code exit-code-blocking semantics (exit 2 blocks a PreToolUse call / a Stop / feeds PostToolUse output back to the model); false wraps it so an exit 2 is downgraded to 1 before it's written — the hook still runs and its output still surfaces, but it can never hard-block ('strong suggestion power' without determinism). name must not be 'sprint_guard' (reserved for Meridian's own hook) or collide with an existing hook's derived slug on this project — both raise a clear {error}. Persistent-state disclosure: on hosted Meridian, supplied text and project/session metadata -- including task log entries, pinned decisions, sprint items, notes, handoff/goal state, and HITL queue items -- are sent to and stored in Meridian's service, in an isolated per-tenant Postgres database (Neon); self-hosted deployments keep the same categories in the configured local SQLite/Postgres database. This data is visible in the dashboard and API, and may resurface in later project context or handoffs. Notes and pinned decisions can be deleted individually; task log entries and sprint items can be deleted via the dashboard/API (not exposed as an agent-facing tool); HITL queue items and handoff state have no per-record delete. Full removal of any of this data is available via project or account deletion, using the documented controls. Do not include secrets.","input_schema":{"type":"object","required":["name","event","script_sh"],"properties":{"name":{"type":"string","description":"Human-readable hook name; sanitized to a filesystem-safe slug used for the written filename(s). Must not be 'sprint_guard'."},"event":{"enum":["PreToolUse","PostToolUse","Stop"],"type":"string","description":"Which Claude Code hook event this fires on."},"enabled":{"type":"boolean","description":"Default true. Disabled hooks are skipped on the next generate_handoff write (their files aren't touched, but also aren't refreshed)."},"matcher":{"type":"string","description":"Optional Claude Code tool-name matcher regex (e.g. \"Edit|Write\"); ignored for Stop hooks."},"blocking":{"type":"boolean","description":"Default true. true = real exit-code-blocking semantics (script written verbatim). false = advisory/non-blocking (an exit 2 is downgraded to 1 before writing)."},"script_sh":{"type":"string","description":"POSIX shell script body (required). Receives the same stdin JSON payload Claude Code passes to any hook."},"project_id":{"type":"string"},"script_ps1":{"type":"string","description":"Optional PowerShell script body. Omit to only write the .sh file."},"project_name":{"type":"string","description":"Project name — an alternative to project_id; resolved to the id internally. project_id wins if both are given."}}},"output_schema":null,"annotations":{"title":"Add Custom Hook","readOnlyHint":false,"openWorldHint":false,"idempotentHint":false,"destructiveHint":false},"source":"probe","observed_at":"2026-09-29T06:40:02.225Z"},{"name":"add_insight","title":"Add Insight","description":"[SUPPORT] Record a durable STRATEGIC INSIGHT — accumulated understanding that generates future decisions. A first-class knowledge type SEPARATE from decisions (choices with a lifecycle) and notes (reference). horizon sets its shelf-life: 'permanent' insights ALWAYS surface in get_planning_brief; 'year'/'quarter' are time-boxed. Returns the stored insight. Persistent-state disclosure: on hosted Meridian, supplied text and project/session metadata -- including task log entries, pinned decisions, sprint items, notes, handoff/goal state, and HITL queue items -- are sent to and stored in Meridian's service, in an isolated per-tenant Postgres database (Neon); self-hosted deployments keep the same categories in the configured local SQLite/Postgres database. This data is visible in the dashboard and API, and may resurface in later project context or handoffs. Notes and pinned decisions can be deleted individually; task log entries and sprint items can be deleted via the dashboard/API (not exposed as an agent-facing tool); HITL queue items and handoff state have no per-record delete. Full removal of any of this data is available via project or account deletion, using the documented controls. Do not include secrets.","input_schema":{"type":"object","required":["title"],"properties":{"body":{"type":"string","description":"The insight (markdown)."},"tags":{"type":"array","items":{"type":"string"},"description":"Optional tags."},"title":{"type":"string"},"horizon":{"enum":["permanent","year","quarter"],"type":"string","description":"Shelf-life. 'permanent' always appears in the planning brief. Default 'quarter'."},"project_id":{"type":"string"},"project_name":{"type":"string","description":"Project name — an alternative to project_id; resolved to the id internally. project_id wins if both are given."}}},"output_schema":null,"annotations":{"title":"Add Insight","readOnlyHint":false,"openWorldHint":false,"idempotentHint":false,"destructiveHint":false},"source":"probe","observed_at":"2026-09-29T06:40:02.225Z"},{"name":"add_note","title":"Add Note","description":"[SUPPORT] Add a per-project wiki note (setup, gotcha, howto, env, ...). Free-form title/body; comma-separated tags optional. Optional kind (wiki=gotcha/rule/howto, insight=strategic/product analysis, reference=external/one-off docs, code=warning/context anchored to a file, document=ingested report/spec/thesis) controls how the dashboard renders it. For a code anchor pass kind='code' plus file_path (and optional symbol): the note is then surfaced automatically when a session calls claim_file/get_file_claims for that path, so the executor sees the warning before editing. Pass source (a URL or file path) to record where the note came from — set automatically by ingest_document. Tag a note 'roadmap' AND pass a committable category (TECHNICAL/ARCHITECTURAL/PRODUCT) to also append it to ROADMAP.md's roadmap-notes anchor. Persistent-state disclosure: on hosted Meridian, supplied text and project/session metadata -- including task log entries, pinned decisions, sprint items, notes, handoff/goal state, and HITL queue items -- are sent to and stored in Meridian's service, in an isolated per-tenant Postgres database (Neon); self-hosted deployments keep the same categories in the configured local SQLite/Postgres database. This data is visible in the dashboard and API, and may resurface in later project context or handoffs. Notes and pinned decisions can be deleted individually; task log entries and sprint items can be deleted via the dashboard/API (not exposed as an agent-facing tool); HITL queue items and handoff state have no per-record delete. Full removal of any of this data is available via project or account deletion, using the documented controls. Do not include secrets.","input_schema":{"type":"object","required":["title","body"],"properties":{"body":{"type":"string"},"kind":{"enum":["wiki","insight","reference","code","document"],"type":"string"},"tags":{"type":"string"},"title":{"type":"string"},"source":{"type":"string","description":"Provenance: a URL or file path this note was ingested from. Stored on the note (used by kind='document')."},"symbol":{"type":"string","description":"Optional symbol (class/function/method) to scope the code anchor to. File-level anchors (no symbol) surface for any symbol in the file."},"category":{"type":"string"},"priority":{"enum":["high","normal","low"],"type":"string","description":"high-priority notes surface first in generate_handoff and planner context."},"file_path":{"type":"string","description":"Code anchor (kind='code'): repo-relative or absolute path this note warns about. Surfaced at claim_file/get_file_claims for the same path."},"project_id":{"type":"string"},"project_name":{"type":"string","description":"Project name — an alternative to project_id; resolved to the id internally. project_id wins if both are given."}}},"output_schema":null,"annotations":{"title":"Add Note","readOnlyHint":false,"openWorldHint":false,"idempotentHint":false,"destructiveHint":false},"source":"probe","observed_at":"2026-09-29T06:40:02.225Z"},{"name":"add_proposal","title":"Add Proposal","description":"Capture an idea into a proposal — PROJECT-SCOPED BY DEFAULT (a8afd8f9). This is the preferred entry point going forward; add_workspace_proposal remains available as the explicit workspace-global opt-in for cross-project ideas. Pass project_id (or project_name) to scope the proposal to that project, XOR pass scope='workspace' to explicitly opt into a workspace-global proposal instead — an ambiguous call (neither, or both) is rejected with an error rather than guessed. Like add_workspace_proposal, these are NOT executor-claimable; a human reviews and promotes them via promote_proposal. Proposals start at status='raw' and progress through an enforced lifecycle: raw → investigating → promoted|rejected. A project-scoped proposal's project_id is enforced at promote_proposal time: promoting it into a DIFFERENT project is rejected unless allow_project_transfer=True (+ transfer_reason) is passed there. Persistent-state disclosure: on hosted Meridian, supplied text and project/session metadata -- including task log entries, pinned decisions, sprint items, notes, handoff/goal state, and HITL queue items -- are sent to and stored in Meridian's service, in an isolated per-tenant Postgres database (Neon); self-hosted deployments keep the same categories in the configured local SQLite/Postgres database. This data is visible in the dashboard and API, and may resurface in later project context or handoffs. Notes and pinned decisions can be deleted individually; task log entries and sprint items can be deleted via the dashboard/API (not exposed as an agent-facing tool); HITL queue items and handoff state have no per-record delete. Full removal of any of this data is available via project or account deletion, using the documented controls. Do not include secrets.","input_schema":{"type":"object","required":["title","body"],"properties":{"body":{"type":"string","description":"Full description of the insight or idea."},"tags":{"type":"string","description":"Optional comma-separated tags."},"scope":{"enum":["project","workspace"],"type":"string","description":"Pass 'workspace' to explicitly opt into a workspace-global proposal instead of project-scoping it. Defaults to project-scoped when project_id/project_name is given; omitting both project_id/project_name AND scope is an error (never inferred)."},"title":{"type":"string","description":"Short idea title."},"family_id":{"type":"string","description":"Optional family/grouping id shared by related proposals."},"project_id":{"type":"string","description":"Project to scope this proposal to. Required unless scope='workspace' is passed instead."},"project_name":{"type":"string","description":"Project name — alternative to project_id; resolved to the id internally."},"idempotency_key":{"type":"string","description":"Optional caller-supplied key; a retried call with the same key returns the original proposal instead of creating a duplicate."}}},"output_schema":null,"annotations":{"title":"Add Proposal","readOnlyHint":false,"openWorldHint":false,"idempotentHint":false,"destructiveHint":false},"source":"probe","observed_at":"2026-09-29T06:40:02.225Z"},{"name":"add_proposal_gate","title":"Add Proposal Gate","description":"[SUPPORT] Raise a typed, lane-blocking HITL gate for a materially ambiguous decision — legal/IP, product scope, destructive operations, production deployment, human acceptance of a contradiction, or other materially ambiguous decisions (category must be one of: legal_ip, product_scope, destructive_ops, production_deploy, contradiction_acceptance, other_ambiguous). Always starts state='blocked' (fail-safe) with no decision yet — routine read-only decomposition and bounded fallback work never needs a gate. affected is a non-empty list of sprint_item_id strings and/or generic pointer objects ({source_type, targets:[...]})  naming exactly what this gate blocks. Resolve with resolve_proposal_gate once a human decides. Persistent-state disclosure: on hosted Meridian, supplied text and project/session metadata -- including task log entries, pinned decisions, sprint items, notes, handoff/goal state, and HITL queue items -- are sent to and stored in Meridian's service, in an isolated per-tenant Postgres database (Neon); self-hosted deployments keep the same categories in the configured local SQLite/Postgres database. This data is visible in the dashboard and API, and may resurface in later project context or handoffs. Notes and pinned decisions can be deleted individually; task log entries and sprint items can be deleted via the dashboard/API (not exposed as an agent-facing tool); HITL queue items and handoff state have no per-record delete. Full removal of any of this data is available via project or account deletion, using the documented controls. Do not include secrets.","input_schema":{"type":"object","required":["category","question","affected","evidence"],"properties":{"affected":{"type":"array","items":{},"description":"Non-empty list of sprint_item_id strings and/or generic pointer objects naming what this gate blocks."},"category":{"enum":["legal_ip","product_scope","destructive_ops","production_deploy","contradiction_acceptance","other_ambiguous"],"type":"string"},"evidence":{"type":"string","description":"Why this is ambiguous — the evidence that triggered raising the gate."},"question":{"type":"string","description":"The materially ambiguous question this gate raises for human judgment."},"created_by":{"type":"string","description":"Who/what raised this gate. Defaults to session_id when omitted."},"expires_at":{"type":"string","description":"Optional ISO timestamp after which the decision lapses (see reopen_policy)."},"project_id":{"type":"string"},"session_id":{"type":"string"},"project_name":{"type":"string","description":"Project name — an alternative to project_id; resolved to the id internally. project_id wins if both are given."},"reopen_policy":{"enum":["manual","auto_on_expiry","on_new_evidence"],"type":"string","description":"manual (default): a decided gate stays decided until reopen_proposal_gate is called explicitly. auto_on_expiry: once expires_at passes, the gate reports 'blocked' again regardless of the last decision. on_new_evidence: same as manual, just a policy label for UIs."}}},"output_schema":null,"annotations":{"title":"Add Proposal Gate","readOnlyHint":false,"openWorldHint":false,"idempotentHint":false,"destructiveHint":false},"source":"probe","observed_at":"2026-09-29T06:40:02.225Z"},{"name":"add_sprint_item","title":"Add Sprint Item","description":"ALWAYS call get_sprint_items first to check for existing pending items before adding. Append a todo item to the project's sprint checklist. Use when starting work on a new version so the next session sees what's in flight. Optional: group items under a named objective with 'group'; attribute to a person with 'human_id'. Use 'depends_on' to block until another item finishes. Blocks near-duplicate titles (>=60% word overlap with an open pending/in_progress item) and returns the conflict; also warns (drift_warning) when the title looks already-shipped — 3+ keyword overlap with a migrations.py/_migrate_X or a recent commit; pass force=true to add anyway. Persistent-state disclosure: on hosted Meridian, supplied text and project/session metadata -- including task log entries, pinned decisions, sprint items, notes, handoff/goal state, and HITL queue items -- are sent to and stored in Meridian's service, in an isolated per-tenant Postgres database (Neon); self-hosted deployments keep the same categories in the configured local SQLite/Postgres database. This data is visible in the dashboard and API, and may resurface in later project context or handoffs. Notes and pinned decisions can be deleted individually; task log entries and sprint items can be deleted via the dashboard/API (not exposed as an agent-facing tool); HITL queue items and handoff state have no per-record delete. Full removal of any of this data is available via project or account deletion, using the documented controls. Do not include secrets.","input_schema":{"type":"object","required":["version","title"],"properties":{"wave":{"type":"string","description":"58a45b92 — stored, deterministic wave/batch label (e.g. 'wave-1') for enforced wave-a/wave-b grouping. Usually auto-filled by assign_sprint_waves from the conflict-free parallel groups; set it here only to pin an item to a specific wave up front. Omit to leave unassigned."},"force":{"type":"boolean","description":"Override the duplicate guard AND the codebase drift check (7e212375) and add the item even if its title matches an existing open item or looks already-shipped. Default false."},"group":{"type":"string","description":"Optional objective name for grouping."},"notes":{"type":"string","description":"Optional free-form context stored on the item at creation time."},"title":{"type":"string"},"track":{"type":"string","description":"dec69708 — named lane for the item (e.g. 'paper'). Buckets items so a whole track can be deferred/skipped."},"policy":{"type":"object","properties":{"artifact_pointer_check":{"enum":["off","warn","strict"],"type":"string","description":"off = no enforcement; warn = surface but don't block (default); strict = block completion without a valid planned_output pointer."},"allow_document_only_override":{"type":"boolean","description":"When true, a document_only-kind item may override/bypass the pointer check (default false)."},"require_exact_table_output_pointer":{"type":"boolean","description":"When true, a table-kind item must declare an exact planned_output pointer (default false)."},"require_exact_figure_output_pointer":{"type":"boolean","description":"When true, a figure-kind item must declare an exact planned_output pointer (default false)."}},"description":"2f9cb288 — per-item override of how strictly a missing/wrong artifact output pointer is enforced. Absent (omit, or on update_sprint_item pass null to clear) falls back to the project default: artifact_pointer_check='warn', every guard flag false — never a silent 'off', never a silent 'strict'. See meridian.artifact_declaration.effective_artifact_policy."},"version":{"type":"string"},"human_id":{"type":"string","description":"Optional: person this item is assigned to."},"priority":{"enum":["urgent","high","normal","low"],"type":"string","description":"e08fee30 — item priority (default 'normal'). Higher-priority PENDING items are surfaced, claimed, and grouped FIRST: get_sprint_items and get_parallelizable_groups order urgent-first within their existing ordering, so an executor picks up higher-priority work before lower. Ordering-only for now; a running-session preemption/interrupt mechanism is deferred."},"depends_on":{"type":"string","description":"Sprint item id that must complete first."},"project_id":{"type":"string"},"blocker_kind":{"enum":["manual","superseded"],"type":"string","description":"2282a636 — omit for an ordinary item; 'manual' marks the item as blocked on a REAL-WORLD action OUTSIDE Meridian (publish something, obtain an API key, talk to an advisor). DISTINCT from milestone_type='human' (which is about WHO executes): a manual-blocker item is surfaced distinctly and is EXCLUDED from executor 'just claim the next pending' scoping, so an executor never treats it as claimable work. f89d440f — 'superseded' marks the item's premise as replaced by other work (e.g. a workspace proposal); UNLIKE 'manual' this is a HARD gate — claim_sprint_item refuses it outright even on a direct claim by item_id, not just a listing exclusion."},"failure_mode":{"enum":["continue","stop"],"type":"string","description":"'stop' blocks this item if the parent fails."},"project_name":{"type":"string","description":"Project name — an alternative to project_id; resolved to the id internally. project_id wins if both are given."},"artifact_kind":{"enum":["document_only","figure","table"],"type":"string","description":"2f9cb288 — the kind of artifact this item produces. Omit when unknown (never guessed/inferred) — an absent value is distinct from any listed kind. Pass an empty string on update_sprint_item to CLEAR it."},"required_tool":{"type":"string","description":"4d1fb28f — pin the specific MCP tool/plugin the executor MUST use for this item (e.g. 'Serena: replace_symbol_body', 'meridian__patch_file', a named tunnel plugin) instead of leaving tool choice to executor habit. Rendered as a hard directive in the /goal block (not a soft hint) — see build_item_briefing / the batch /goal's <required_tool> clause. Omit for ordinary executor discretion."},"deferred_until":{"type":"string","description":"dec69708 — ISO timestamp before which the item CANNOT be claimed. claim_sprint_item hard-refuses it until this time passes (enforced deferral, e.g. 'defer the paper-track until 2026-09-01'). Omit for an immediately-claimable item."},"milestone_type":{"enum":["task","milestone","human"],"type":"string","description":"'milestone' renders as a timeline marker; 'human' marks a task for a human (hidden from executor sessions)."},"planned_output":{"type":"object","required":["source_type","targets"],"properties":{"label":{"type":"string","description":"Optional human-readable label for this output."},"targets":{"type":"array","items":{"type":"object"},"description":"Non-empty array of {uri, selector, target_kind?, subSelector?, freshness?} — see add_sprint_item_pointer for the full selector shape (range/symbol/node_id/zotero_key/text_quote/finding_id/directory/git/remote_fs/artifact, 62640241)."},"source_type":{"type":"string","description":"e.g. 'code', 'docs', 'experiment' — what kind of source the target lives in."},"provenance_required":{"type":"boolean","description":"Whether the executor must record_provenance for this output before it counts as satisfied. Default false."}},"description":"2f9cb288 — a TYPED POINTER declaring where this item's output is expected to land — NOT a free-form path. Validated via meridian.pointers.validate_pointer: source_type + a non-empty targets array of {uri, selector, target_kind?, subSelector?}, plus an optional label. Do not infer this from a directory or a generic 'mcp_tool:' resource id — only an explicit pointer counts. No secrets or machine-local absolute paths (same check as set_capability_manifest / tool_requirements). Pass null on update_sprint_item to clear."},"tool_requirements":{"type":"array","items":{"type":"object","required":["name","server_or_namespace","required_or_preferred","purpose"],"properties":{"name":{"type":"string","description":"The tool's name, e.g. 'find_symbol'."},"purpose":{"type":"string","description":"Why this item needs it."},"fallback":{"anyOf":[{"type":"string"},{"type":"array","items":{"type":"string"}}],"description":"Optional alternate tool id(s) to try, in order, if this one is unavailable."},"verification":{"type":"string","description":"Optional: how to confirm the call actually worked."},"call_template":{"type":"string","description":"Optional example invocation/signature."},"availability_check":{"type":"string","description":"Optional: how to confirm the tool is present (e.g. a tools/list name match)."},"server_or_namespace":{"type":"string","description":"Which server/namespace it lives under, e.g. 'Serena', 'meridian', 'Filesystem'."},"required_or_preferred":{"enum":["required","preferred"],"type":"string","description":"'required' = hard requirement; 'preferred' = soft preference, never blocking."}}},"description":"76dde31f — typed per-item MCP tool-requirement contract, distinct from touches_resources (scheduling metadata) and the legacy free-form required_tool pin (a single string). Each entry: name, server_or_namespace, required_or_preferred ('required'|'preferred'), purpose (all required); call_template, fallback (a string or list of alternate tool ids), availability_check, verification (all optional). Once set, this structured field is the CANONICAL source build_item_briefing / the batch /goal's <tool_requirements> clause / the machine-readable capability contract render — required_tool keeps working and is used as a read-time compatibility fallback only when this is empty. No secrets or machine-local absolute paths (validated, same check as set_capability_manifest). Pass [] to clear."},"touches_resources":{"type":"array","items":{"type":"string"},"description":"Typed resource identifiers this item touches, for parallel conflict detection: 'file:path.py', 'db:migrations', 'mcp_tool:name', 'route:METHOD:/path', 'pypi:publish', 'github:tag'. Used by get_parallelizable_groups to cluster non-overlapping items. SYMBOL-LEVEL: use 'symbol:path.py::function_name' (double colon) so two items editing DIFFERENT symbols in the SAME file are treated as non-overlapping and co-batched in parallel (line ranges resolve via real AST/tree-sitter parsing when claim_sprint_item gets the file's content in resource_contents). A single-colon 'file:path.py:function_name' suffix is treated as the WHOLE file (it locks and conflicts like 'file:path.py') and does not co-batch. Prefer symbol-level ids when two items touch the same file but different functions/classes."}}},"output_schema":null,"annotations":{"title":"Add Sprint Item","readOnlyHint":false,"openWorldHint":false,"idempotentHint":false,"destructiveHint":false},"source":"probe","observed_at":"2026-09-29T06:40:02.225Z"},{"name":"add_sprint_item_pointer","title":"Add Sprint Item Pointer","description":"[SUPPORT] 2976e168 — attach a GENERIC POINTER to a sprint item: a portable, composable reference to a thing-in-a-source, grounded in LSP Location + W3C Web Annotation Selector composition. targets is an ARRAY of {uri, selector, subSelector?} objects (native multi-file, the LSP WorkspaceEdit pattern); the whole composite shape is stored as JSON, not per-domain columns. Every selector is an object with an explicit \"type\" PLUS that type's own field(s):\n• range — {\"type\":\"range\", \"start_line\":int, \"end_line\":int, \"start_char\"?:int, \"end_char\"?:int} (an LSP Range); the pointer IS the location.\n• symbol — {\"type\":\"symbol\", \"qualified_name\":\"pkg.mod.func\"} resolved against the cached code graph to a file+line.\n• node_id — {\"type\":\"node_id\", \"id\":\"<element-id>\"} of a doc_store element (an ingested-document structure node). NOTE: the field is \"id\", NOT \"value\".\n• zotero_key — {\"type\":\"zotero_key\", \"key\":\"<zotero-key>\"} of a Zotero library item.\n• text_quote — {\"type\":\"text_quote\", \"exact\":str, \"prefix\"?:str, \"suffix\"?:str, \"archived_url\"?:str, \"archived_at\"?:str, \"canonical_url\"?:str, \"retrieval_hash\"?:str} (W3C TextQuoteSelector; source_type \"web\" — a URL — OR a local .docx path, resolving via a docx paragraph-text match instead of an HTTP GET). Resolving re-fetches live and flags content drift (the cited passage silently changed/vanished).\n• finding_id — {\"type\":\"finding_id\", \"id\":\"<finding-note-id>\"} (source_type \"experiment\") addresses a save_finding artifact.\n• directory — {\"type\":\"directory\", \"root\":str, \"include\"?:[str,...], \"exclude\"?:[str,...], \"manifest_id\"?:str, \"snapshot_id\"?:str} (62640241) — a directory ROOT + glob include/exclude selector + optional snapshot/manifest identity. Resolving it (local paths only by default) walks the tree and returns a deterministic manifest + manifest_hash.\n• git — {\"type\":\"git\", \"repository\":str, \"ref\"?:str, \"commit\"?:str, \"path\"?:str} (62640241) — a Git repository identity; at least one of \"ref\"/\"commit\" is required. A line range within \"path\" is expressed via subSelector (a nested range), NOT a new field. Resolving it (local clones only by default) checks reachability against the repo's current HEAD via `git rev-parse`.\n• remote_fs — {\"type\":\"remote_fs\", \"host_id\":str, \"filesystem_slot\":str, \"path\":str, \"lease_id\"?:str, \"session_id\"?:str, \"snapshot_id\"?:str} (62640241) — an opaque tunnel-connector host + filesystem slot + remote path, optionally bound to the lease/session that captured it. No core-local default resolver exists (requires an injected, tunnel-backed resolver) — reported explicitly unresolved without one, never silently dropped.\n• artifact — {\"type\":\"artifact\", \"manifest_uri\":str, \"fingerprint\"?:str, \"run_id\"?:str, \"item_id\"?:str, \"provenance_id\"?:str} (62640241) — a build/output artifact's manifest URI plus an optional fingerprint and a link to the producing run/sprint-item/provenance record. Resolving it (local files only by default) hashes the manifest file to report its current fingerprint.\nAn optional selector.subSelector nests finer granularity (W3C hasSubSelector) — e.g. {\"type\":\"symbol\", \"qualified_name\":\"a.b.f\", \"subSelector\": {\"type\":\"range\", \"start_line\":3, \"end_line\":4}} = 'these lines, within this function'. A subSelector is itself a FULL selector and MUST carry its OWN explicit \"type\" (it does not inherit the parent's). source_type names the domain (code | docs | citation | web | experiment | …). Each target may also carry target_kind: \"existing\" | \"planned_new\" (300a063d) — set \"existing\" ONLY when the file/symbol already exists (this is checked against the real filesystem and REJECTED if the path isn't there); set \"planned_new\" for a file this sprint item will CREATE, which is explicitly exempt from that check. Omitting target_kind keeps the pre-existing, unchecked behavior (defaults to \"existing\" in the stored shape but is never filesystem-verified) — set it explicitly to get real verification. 62640241 — a target may ALSO carry an optional freshness proof: {\"content_hash\"?:str, \"source_revision\"?:str, \"resolver_version\"?:str, \"captured_at\"?:str, \"state\"?: \"current\"|\"stale\"|\"unknown\"|\"unavailable\"|\"ambiguous\"}. Purely additive/opt-in; resolve_sprint_item_pointers recomputes a LIVE freshness_state for directory/git/remote_fs/artifact/text_quote targets by comparing this declared proof against what resolution finds right now. A target may ALSO carry an optional repo_root (W1-J) naming WHICH repo a relative uri is anchored to, for a companion-repo pointer whose uri lives in a different checkout than the one hosting this Meridian project (e.g. a paper repo alongside the code repo). Never send a raw absolute path here — pass the actual local path (or any stable label) you want the uri anchored to; it is converted to a portable, one-way identity fingerprint (basename + a content hash, never reversible back to the input) before being stored, the same scheme projects.repo_identity already uses for this project's OWN repo binding. Omitting repo_root means the pre-existing default: the uri is anchored to this same Meridian project's repo. A repo_root-bearing target's target_kind=\"existing\" filesystem check is SKIPPED (never falsely run against the wrong repo's cwd) rather than checked or silently assumed verified. Malformed pointers are rejected with a clear error: a bad/missing selector.type, a missing required selector field (e.g. node_id without \"id\", git without ref or commit, a subSelector with no \"type\", an invalid target_kind or freshness.state, or target_kind=\"existing\" at a path that doesn't exist). Returns the stored pointer. Persistent-state disclosure: on hosted Meridian, supplied text and project/session metadata -- including task log entries, pinned decisions, sprint items, notes, handoff/goal state, and HITL queue items -- are sent to and stored in Meridian's service, in an isolated per-tenant Postgres database (Neon); self-hosted deployments keep the same categories in the configured local SQLite/Postgres database. This data is visible in the dashboard and API, and may resurface in later project context or handoffs. Notes and pinned decisions can be deleted individually; task log entries and sprint items can be deleted via the dashboard/API (not exposed as an agent-facing tool); HITL queue items and handoff state have no per-record delete. Full removal of any of this data is available via project or account deletion, using the documented controls. Do not include secrets.","input_schema":{"type":"object","required":["sprint_item_id","source_type","targets"],"properties":{"label":{"type":"string","description":"Optional human-readable label for the pointer."},"targets":{"type":"array","items":{"type":"object"},"description":"Non-empty array of {uri, selector, subSelector?, target_kind?, freshness?, repo_root?} targets. Each selector is an object carrying an explicit \"type\" plus that type's field(s): range {\"type\":\"range\", start_line, end_line, start_char?, end_char?}; symbol {\"type\":\"symbol\", qualified_name}; node_id {\"type\":\"node_id\", id} (field is \"id\", NOT \"value\"); zotero_key {\"type\":\"zotero_key\", key}; text_quote {\"type\":\"text_quote\", exact, prefix?, suffix?, archived_url?, archived_at?, canonical_url?, retrieval_hash?}; finding_id {\"type\":\"finding_id\", id}; directory {\"type\":\"directory\", root, include?, exclude?, manifest_id?, snapshot_id?}; git {\"type\":\"git\", repository, ref?, commit? (>=1 required), path?}; remote_fs {\"type\":\"remote_fs\", host_id, filesystem_slot, path, lease_id?, session_id?, snapshot_id?}; artifact {\"type\":\"artifact\", manifest_uri, fingerprint?, run_id?, item_id?, provenance_id?} (62640241 for the last five). An optional subSelector is itself a full selector and MUST carry its own \"type\". target_kind is \"existing\" (default; explicit \"existing\" is verified against the real filesystem) or \"planned_new\" (a file not created yet — exempt from that check). freshness (62640241) is an optional {content_hash?, source_revision?, resolver_version?, captured_at?, state?} proof of what the source looked like at capture time. repo_root (W1-J) is an optional string naming which COMPANION repo a relative uri is anchored to (a different checkout than this Meridian project's own repo); never send a raw absolute path — it is converted to a one-way identity fingerprint before storage, and disables the target_kind='existing' filesystem check for that target (checking it against this process's cwd would check the wrong repo)."},"project_id":{"type":"string"},"source_type":{"type":"string","description":"Domain of the pointer: code | docs | citation | web | experiment | … (free text)."},"project_name":{"type":"string","description":"Project name — an alternative to project_id; resolved to the id internally. project_id wins if both are given."},"sprint_item_id":{"type":"string","description":"The sprint item to attach the pointer to."}}},"output_schema":null,"annotations":{"title":"Add Sprint Item Pointer","readOnlyHint":false,"openWorldHint":false,"idempotentHint":false,"destructiveHint":false},"source":"probe","observed_at":"2026-09-29T06:40:02.225Z"},{"name":"add_sprint_note","title":"Add Sprint Note","description":"[SUPPORT] Add an ephemeral note to the current session's scratch pad. Use for constraints, blockers, working assumptions valid only this session. Notes are auto-deleted when the session closes. Pass note_kind='thinking' for a thinking_sync (HOOKS_DEBUG_STATE) note: a structured snapshot of the reasoning state (what was tried, what failed, current confirmed state) that the dashboard renders with a distinct icon. Intended for Claude's client-side thinking_sync post-tool-call hook, which extracts the extended-thinking scratchpad and persists it here so debugging state survives across turns and into the next session brief. Persistent-state disclosure: on hosted Meridian, supplied text and project/session metadata -- including task log entries, pinned decisions, sprint items, notes, handoff/goal state, and HITL queue items -- are sent to and stored in Meridian's service, in an isolated per-tenant Postgres database (Neon); self-hosted deployments keep the same categories in the configured local SQLite/Postgres database. This data is visible in the dashboard and API, and may resurface in later project context or handoffs. Notes and pinned decisions can be deleted individually; task log entries and sprint items can be deleted via the dashboard/API (not exposed as an agent-facing tool); HITL queue items and handoff state have no per-record delete. Full removal of any of this data is available via project or account deletion, using the documented controls. Do not include secrets.","input_schema":{"type":"object","required":["session_id","title","body"],"properties":{"body":{"type":"string"},"title":{"type":"string"},"note_kind":{"enum":["note","thinking"],"type":"string","description":"'note' (default) or 'thinking' for a thinking_sync scratchpad note."},"session_id":{"type":"string"}}},"output_schema":null,"annotations":{"title":"Add Sprint Note","readOnlyHint":false,"openWorldHint":false,"idempotentHint":false,"destructiveHint":false},"source":"probe","observed_at":"2026-09-29T06:40:02.225Z"},{"name":"add_subtask","title":"Add Subtask","description":"[SUPPORT] Add a child sprint item under an existing parent item. Inherits the parent's version. Status starts as pending. Rejects if the parent is already done, failed, or skipped. Pass owner='human' or owner='ai' to build a mixed-ownership task chain: owned subtasks added in sequence become a strict chain (each depends on the previous owned sibling), and completing one auto-advances ownership — an AI→human step files a HITL handoff, a human→AI step un-blocks the next AI subtask. The parent stays in_progress until all subtasks are terminal. Persistent-state disclosure: on hosted Meridian, supplied text and project/session metadata -- including task log entries, pinned decisions, sprint items, notes, handoff/goal state, and HITL queue items -- are sent to and stored in Meridian's service, in an isolated per-tenant Postgres database (Neon); self-hosted deployments keep the same categories in the configured local SQLite/Postgres database. This data is visible in the dashboard and API, and may resurface in later project context or handoffs. Notes and pinned decisions can be deleted individually; task log entries and sprint items can be deleted via the dashboard/API (not exposed as an agent-facing tool); HITL queue items and handoff state have no per-record delete. Full removal of any of this data is available via project or account deletion, using the documented controls. Do not include secrets.","input_schema":{"type":"object","required":["parent_id","title"],"properties":{"owner":{"enum":["human","ai"],"type":"string","description":"Optional owner for mixed-ownership task chains: 'human' or 'ai'. Omit for a legacy unchained subtask."},"title":{"type":"string","description":"Title of the new subtask."},"parent_id":{"type":"string","description":"ID of the parent sprint item."},"project_id":{"type":"string"},"project_name":{"type":"string","description":"Project name — an alternative to project_id; resolved to the id internally. project_id wins if both are given."}}},"output_schema":null,"annotations":{"title":"Add Subtask","readOnlyHint":false,"openWorldHint":false,"idempotentHint":false,"destructiveHint":false},"source":"probe","observed_at":"2026-09-29T06:40:02.225Z"},{"name":"add_workspace_note","title":"Add Workspace Note","description":"[MAINTENANCE] Add a workspace-level wiki note that applies across ALL projects in this workspace (onboarding, cross-cutting conventions, shared infra). Unlike add_note, it is not tied to a project and is injected at the top of every project's context block + handoff. Comma-separated tags optional. Persistent-state disclosure: on hosted Meridian, supplied text and project/session metadata -- including task log entries, pinned decisions, sprint items, notes, handoff/goal state, and HITL queue items -- are sent to and stored in Meridian's service, in an isolated per-tenant Postgres database (Neon); self-hosted deployments keep the same categories in the configured local SQLite/Postgres database. This data is visible in the dashboard and API, and may resurface in later project context or handoffs. Notes and pinned decisions can be deleted individually; task log entries and sprint items can be deleted via the dashboard/API (not exposed as an agent-facing tool); HITL queue items and handoff state have no per-record delete. Full removal of any of this data is available via project or account deletion, using the documented controls. Do not include secrets.","input_schema":{"type":"object","required":["title","body"],"properties":{"body":{"type":"string"},"tags":{"type":"string"},"title":{"type":"string"}}},"output_schema":null,"annotations":{"title":"Add Workspace Note","readOnlyHint":false,"openWorldHint":false,"idempotentHint":false,"destructiveHint":false},"source":"probe","observed_at":"2026-09-29T06:40:02.225Z"},{"name":"add_workspace_proposal","title":"Add Workspace Proposal","description":"Capture a workspace-level flash of insight into the 'drawer of inspiration' — cross-project ideas that don't belong to any one project yet. Unlike sprint items these are NOT executor-claimable; they require a human to review and promote them. Proposals start at status='raw' and progress through an enforced lifecycle: raw → investigating → promoted|rejected. Use advance_proposal_status to move through the lifecycle; use promote_proposal to convert one into a real sprint item. Persistent-state disclosure: on hosted Meridian, supplied text and project/session metadata -- including task log entries, pinned decisions, sprint items, notes, handoff/goal state, and HITL queue items -- are sent to and stored in Meridian's service, in an isolated per-tenant Postgres database (Neon); self-hosted deployments keep the same categories in the configured local SQLite/Postgres database. This data is visible in the dashboard and API, and may resurface in later project context or handoffs. Notes and pinned decisions can be deleted individually; task log entries and sprint items can be deleted via the dashboard/API (not exposed as an agent-facing tool); HITL queue items and handoff state have no per-record delete. Full removal of any of this data is available via project or account deletion, using the documented controls. Do not include secrets.","input_schema":{"type":"object","required":["title","body"],"properties":{"body":{"type":"string","description":"Full description of the insight or idea."},"tags":{"type":"string","description":"Optional comma-separated tags."},"title":{"type":"string","description":"Short idea title."}}},"output_schema":null,"annotations":{"title":"Add Workspace Proposal","readOnlyHint":false,"openWorldHint":false,"idempotentHint":false,"destructiveHint":false},"source":"probe","observed_at":"2026-09-29T06:40:02.225Z"},{"name":"add_workspace_sprint_item","title":"Add Workspace Sprint Item","description":"[MAINTENANCE] Add an item to the workspace-level personal backlog — a cross-project board NOT tied to any single project (track thesis + Meridian + personal goals in one view). Use the per-project add_sprint_item for project work instead. 'group' is the cross-project bucket the item lives under (e.g. 'thesis', 'meridian', 'personal'); 'human_id' assigns it to a person. New items start as 'todo'. Persistent-state disclosure: on hosted Meridian, supplied text and project/session metadata -- including task log entries, pinned decisions, sprint items, notes, handoff/goal state, and HITL queue items -- are sent to and stored in Meridian's service, in an isolated per-tenant Postgres database (Neon); self-hosted deployments keep the same categories in the configured local SQLite/Postgres database. This data is visible in the dashboard and API, and may resurface in later project context or handoffs. Notes and pinned decisions can be deleted individually; task log entries and sprint items can be deleted via the dashboard/API (not exposed as an agent-facing tool); HITL queue items and handoff state have no per-record delete. Full removal of any of this data is available via project or account deletion, using the documented controls. Do not include secrets.","input_schema":{"type":"object","required":["title"],"properties":{"group":{"type":"string","description":"Cross-project bucket, e.g. 'thesis'/'meridian'/'personal'."},"title":{"type":"string"},"human_id":{"type":"string","description":"Optional: person this item is assigned to."}}},"output_schema":null,"annotations":{"title":"Add Workspace Sprint Item","readOnlyHint":false,"openWorldHint":false,"idempotentHint":false,"destructiveHint":false},"source":"probe","observed_at":"2026-09-29T06:40:02.225Z"},{"name":"advance_proposal_status","title":"Advance Proposal Status","description":"[SUPPORT] Transition a workspace proposal through its lifecycle. Enforced transitions: raw → investigating|rejected; investigating → promoted|rejected|raw; rejected → raw. 'promoted' is a terminal status reachable only via promote_proposal (which also creates the sprint item). Returns the updated proposal. Persistent-state disclosure: on hosted Meridian, supplied text and project/session metadata -- including task log entries, pinned decisions, sprint items, notes, handoff/goal state, and HITL queue items -- are sent to and stored in Meridian's service, in an isolated per-tenant Postgres database (Neon); self-hosted deployments keep the same categories in the configured local SQLite/Postgres database. This data is visible in the dashboard and API, and may resurface in later project context or handoffs. Notes and pinned decisions can be deleted individually; task log entries and sprint items can be deleted via the dashboard/API (not exposed as an agent-facing tool); HITL queue items and handoff state have no per-record delete. Full removal of any of this data is available via project or account deletion, using the documented controls. Do not include secrets.","input_schema":{"type":"object","required":["proposal_id","status"],"properties":{"status":{"enum":["raw","investigating","rejected"],"type":"string","description":"Target status. 'promoted' is not allowed here — use promote_proposal instead."},"proposal_id":{"type":"string"}}},"output_schema":null,"annotations":{"title":"Advance Proposal Status","readOnlyHint":false,"openWorldHint":false,"idempotentHint":false,"destructiveHint":false},"source":"probe","observed_at":"2026-09-29T06:40:02.225Z"},{"name":"analyze_model_efficiency","title":"Analyze Model Efficiency","description":"[MAINTENANCE] 0fba4cb6 — MECHANICAL (zero-token) model-tier suggestion for a task or sprint item. Deterministic, rule/heuristic classifier: NO model call, NO DB, NO network — it mirrors how the ultracode orchestration script spends zero model tokens on routing. Pass a task descriptor (any of title, description, file_count, files, touches_resources, size) and it returns a suggested tier: {tier: 'haiku'|'sonnet'|'opus', score, signals:[{signal, detail, weight}...], rationale, mode:'mechanical'}. Cheap-leaning signals (title keywords like 'typo'/'docstring'/'lint', 1 file, size 'xs'/'s') pull toward 'haiku'; expensive-leaning signals ('refactor'/'migration'/'auth', many files, touched resources, size 'l'/'xl') pull toward 'opus'. Use it to route a task to the cheapest sufficient model before spawning an executor. FOLLOW-UP (out of scope this pass): a second LLM-backed 'semantic' mode that reads the full item for a nuanced second opinion.","input_schema":{"type":"object","required":[],"properties":{"size":{"enum":["xs","s","m","l","xl"],"type":"string","description":"Optional explicit sprint-item size estimate (case-insensitive). Larger -> more expensive."},"files":{"type":"array","items":{"type":"string"},"description":"Alternative to file_count: the list of files touched; its length is used when file_count is omitted."},"title":{"type":"string","description":"Task / sprint-item title. Scanned for cheap/expensive keyword signals."},"file_count":{"type":"integer","description":"Number of files the task touches. Fewer files -> cheaper tier."},"description":{"type":"string","description":"Optional longer description; also scanned for keyword signals."},"touches_resources":{"type":"array","items":{"type":"string"},"description":"Resources (DB/schema/infra/services) the task touches. May also be an integer count. More/any resources -> more expensive."}}},"output_schema":null,"annotations":{"title":"Analyze Model Efficiency","readOnlyHint":true,"openWorldHint":false,"idempotentHint":true,"destructiveHint":false},"source":"probe","observed_at":"2026-09-29T06:40:02.225Z"},{"name":"analyze_sprint","title":"Analyze Sprint","description":"[MAINTENANCE] PLANNING: Read-only synthesis of the current sprint into one structured brief — parallelizability (conflict-free groups + max fan-out), dependency chains (depends_on walked to the root), resource/file conflicts (items sharing touches_resources), and stalls (stall_count>0). Returns {summary, recommended_strategy, parallelism, dependency_chains, longest_chain, file_conflicts, stalls, blocked, running}. Call in planning sessions instead of stitching together get_parallelizable_groups + manual dependency/conflict analysis. Persistent-state disclosure: on hosted Meridian, supplied text and project/session metadata -- including task log entries, pinned decisions, sprint items, notes, handoff/goal state, and HITL queue items -- are sent to and stored in Meridian's service, in an isolated per-tenant Postgres database (Neon); self-hosted deployments keep the same categories in the configured local SQLite/Postgres database. This data is visible in the dashboard and API, and may resurface in later project context or handoffs. Notes and pinned decisions can be deleted individually; task log entries and sprint items can be deleted via the dashboard/API (not exposed as an agent-facing tool); HITL queue items and handoff state have no per-record delete. Full removal of any of this data is available via project or account deletion, using the documented controls. Do not include secrets.","input_schema":{"type":"object","required":[],"properties":{"version":{"type":"string","description":"Optional: only analyze items in this sprint-version bucket."},"project_id":{"type":"string"},"project_name":{"type":"string","description":"Project name — an alternative to project_id; resolved to the id internally. project_id wins if both are given."}}},"output_schema":null,"annotations":{"title":"Analyze Sprint","readOnlyHint":false,"openWorldHint":false,"idempotentHint":false,"destructiveHint":false},"source":"probe","observed_at":"2026-09-29T06:40:02.225Z"},{"name":"annotate_outputs","title":"Annotate Outputs","description":"[SUPPORT] 9e02e448 — capture a human annotation for a path inside an outputs tree WITHOUT touching the filesystem. Upserts a row into the annotations layer of the local DuckDB outputs index for outputs_dir. Two tiers, same mechanism: Tier 1 = pass outputs_dir as path to annotate the whole tree ('what this experiment tree is about'); Tier 2 = pass any sub-path (file or directory) to annotate a specific run, file, or subdirectory ('PCA on, BFS off, overwritten 5x'). run_params is an optional free-form dict of parameters logged alongside the note (e.g. {\"lr\": 0.001, \"batch_size\": 32}). Annotations are automatically surfaced in search_outputs results — any hit's path (or its nearest ancestor directory) that has an annotation will have it included in the hit's 'annotations' field without a second tool call. A MERIDIAN_NOTES.md file placed anywhere in the tree is also auto-ingested into the same table on every rebuild, keyed to its containing directory. Returns the stored annotation as a dict. Persistent-state disclosure: on hosted Meridian, supplied text and project/session metadata -- including task log entries, pinned decisions, sprint items, notes, handoff/goal state, and HITL queue items -- are sent to and stored in Meridian's service, in an isolated per-tenant Postgres database (Neon); self-hosted deployments keep the same categories in the configured local SQLite/Postgres database. This data is visible in the dashboard and API, and may resurface in later project context or handoffs. Notes and pinned decisions can be deleted individually; task log entries and sprint items can be deleted via the dashboard/API (not exposed as an agent-facing tool); HITL queue items and handoff state have no per-record delete. Full removal of any of this data is available via project or account deletion, using the documented controls. Do not include secrets.","input_schema":{"type":"object","required":["outputs_dir","path","note"],"properties":{"note":{"type":"string","description":"The annotation text (e.g. 'PCA on, BFS off — results from run on 2026-07-12 with lr=0.001')."},"path":{"type":"string","description":"The path to annotate — either the outputs_dir root (Tier 1, tree-level annotation) or any file/subdirectory path within the tree (Tier 2, per-run or per-file annotation)."},"run_params":{"type":"object","description":"Optional free-form key-value dict of run parameters to log alongside the note (e.g. {\"lr\": 0.001, \"epochs\": 100})."},"outputs_dir":{"type":"string","description":"Absolute path to the outputs directory tree root (same value you pass to search_outputs)."}}},"output_schema":null,"annotations":{"title":"Annotate Outputs","readOnlyHint":false,"openWorldHint":false,"idempotentHint":false,"destructiveHint":false},"source":"probe","observed_at":"2026-09-29T06:40:02.225Z"},{"name":"answer_hitl","title":"Answer HITL","description":"[SUPPORT] Answer a pending HITL request programmatically. Marks it answered so the waiting session can resume. Use list_hitl_requests to find request IDs. Persistent-state disclosure: on hosted Meridian, supplied text and project/session metadata -- including task log entries, pinned decisions, sprint items, notes, handoff/goal state, and HITL queue items -- are sent to and stored in Meridian's service, in an isolated per-tenant Postgres database (Neon); self-hosted deployments keep the same categories in the configured local SQLite/Postgres database. This data is visible in the dashboard and API, and may resurface in later project context or handoffs. Notes and pinned decisions can be deleted individually; task log entries and sprint items can be deleted via the dashboard/API (not exposed as an agent-facing tool); HITL queue items and handoff state have no per-record delete. Full removal of any of this data is available via project or account deletion, using the documented controls. Do not include secrets.","input_schema":{"type":"object","required":["request_id","answer"],"properties":{"answer":{"type":"string"},"request_id":{"type":"string"},"answered_by":{"type":"string","description":"Optional human_id of the answerer."}}},"output_schema":null,"annotations":{"title":"Answer HITL","readOnlyHint":false,"openWorldHint":false,"idempotentHint":false,"destructiveHint":false},"source":"probe","observed_at":"2026-09-29T06:40:02.225Z"},{"name":"archive_decision","title":"Archive Decision","description":"[SUPPORT] Archive a pinned decision by id. Soft-deletes to preserve the audit trail. Use when something was filed by mistake or is a duplicate. For retiring a valid but superseded decision, prefer update_decision(status=superseded). Persistent-state disclosure: on hosted Meridian, supplied text and project/session metadata -- including task log entries, pinned decisions, sprint items, notes, handoff/goal state, and HITL queue items -- are sent to and stored in Meridian's service, in an isolated per-tenant Postgres database (Neon); self-hosted deployments keep the same categories in the configured local SQLite/Postgres database. This data is visible in the dashboard and API, and may resurface in later project context or handoffs. Notes and pinned decisions can be deleted individually; task log entries and sprint items can be deleted via the dashboard/API (not exposed as an agent-facing tool); HITL queue items and handoff state have no per-record delete. Full removal of any of this data is available via project or account deletion, using the documented controls. Do not include secrets.","input_schema":{"type":"object","required":["decision_id"],"properties":{"decision_id":{"type":"string"}}},"output_schema":null,"annotations":{"title":"Archive Decision","readOnlyHint":false,"openWorldHint":false,"idempotentHint":false,"destructiveHint":true},"source":"probe","observed_at":"2026-09-29T06:40:02.225Z"},{"name":"assign_sprint_waves","title":"Assign Sprint Waves","description":"[MAINTENANCE] 58a45b92 — PERSIST the parallel grouping: writes the conflict-free batches get_parallelizable_groups computes onto each eligible item's stored `wave` field (group i -> 'wave-{i+1}'), so parallelism becomes deterministic and inspectable (get_sprint_items surfaces `wave`) instead of recomputed every call. Only currently-eligible items (pending/todo, dependency-satisfied, unclaimed, non-manual-blocker) are labelled; blocked/in-flight/done items are left untouched (re-run once they clear). Idempotent — recomputes from the live board each call. Hand-override any item afterwards with update_sprint_item(wave=...). Returns {version, wave_count, assigned, waves: {'wave-1': [ids...], ...}, blocked_count, undeclared_count}. 605ca2c4 — if active executor sessions are detected, the response also includes active_session_warning: re-labeling wave numbers while a session is mid-flight can desync it from a /goal string that already references specific wave labels. Persistent-state disclosure: on hosted Meridian, supplied text and project/session metadata -- including task log entries, pinned decisions, sprint items, notes, handoff/goal state, and HITL queue items -- are sent to and stored in Meridian's service, in an isolated per-tenant Postgres database (Neon); self-hosted deployments keep the same categories in the configured local SQLite/Postgres database. This data is visible in the dashboard and API, and may resurface in later project context or handoffs. Notes and pinned decisions can be deleted individually; task log entries and sprint items can be deleted via the dashboard/API (not exposed as an agent-facing tool); HITL queue items and handoff state have no per-record delete. Full removal of any of this data is available via project or account deletion, using the documented controls. Do not include secrets.","input_schema":{"type":"object","required":[],"properties":{"version":{"type":"string","description":"Optional: only assign waves to items in this sprint-version bucket."},"project_id":{"type":"string"},"project_name":{"type":"string","description":"Project name — an alternative to project_id; resolved to the id internally. project_id wins if both are given."}}},"output_schema":null,"annotations":{"title":"Assign Sprint Waves","readOnlyHint":false,"openWorldHint":false,"idempotentHint":false,"destructiveHint":false},"source":"probe","observed_at":"2026-09-29T06:40:02.225Z"},{"name":"batch_mutate","title":"Batch Mutate","description":"[SUPPORT] 133bfff6 — run a batch of TRANSACTIONAL mutation entries in ONE call, mixing entry kinds selected per-entry via 'kind': 'sprint_item_pointer' (attach a pointer — same shape as add_sprint_item_pointer: sprint_item_id, source_type, targets, optional label), 'sprint_item_update' (patch an EXISTING sprint item — same shape as update_sprint_item: item_id + at least one patchable field; sprint-item CREATION is not supported here, use execute_batch(operation='sprint_items', ...) or add_sprint_item for that), and (PROFILE-7) 'profile_layer' (upsert one scope_type+scope_id profile layer — same shape as set_profile_layer: scope_type, scope_id, optional fields/reset_fields/provenance/expected_revision; a stale expected_revision surfaces error_code='CONFLICT' with expected_revision/actual_revision in the outcome payload). Reuses the exact same validated apply/compensate logic execute_batch and the single-item tools already use — no separate/duplicated mutation path. mode is REQUIRED: 'all_or_nothing' validates every entry BEFORE mutating anything — any validation failure writes NOTHING (status 'rejected'); a mutation failure partway through rolls back every entry this call already wrote via a compensating delete/revert (status 'failed', per-entry status 'rolled_back'). 'best_effort' processes each entry independently (status 'ok' | 'partial' | 'failed'). idempotency_key is REQUIRED (pass null or \"\" to explicitly opt out) — a retried call with the identical (project_id, idempotency_key) tuple returns the FIRST call's stored result verbatim (idempotent_replay:true) instead of re-executing. PROJECT ISOLATION: an entry MAY carry its own 'project_id' field, but it MUST match this call's own project_id or the entry is rejected outright — a mutation entry can never target a different project. Returns {status, mode, project_id, idempotency_key, idempotent_replay, created_count, error_count, results:[{index, correlation_key, status, id, outcome, error_code, error_message, retryable}], request_id, committed_count, failures:[...failed results...], rollback_status: 'none'|'rolled_back'|'rejected'} — results is ALWAYS in input order. Persistent-state disclosure: on hosted Meridian, supplied text and project/session metadata -- including task log entries, pinned decisions, sprint items, notes, handoff/goal state, and HITL queue items -- are sent to and stored in Meridian's service, in an isolated per-tenant Postgres database (Neon); self-hosted deployments keep the same categories in the configured local SQLite/Postgres database. This data is visible in the dashboard and API, and may resurface in later project context or handoffs. Notes and pinned decisions can be deleted individually; task log entries and sprint items can be deleted via the dashboard/API (not exposed as an agent-facing tool); HITL queue items and handoff state have no per-record delete. Full removal of any of this data is available via project or account deletion, using the documented controls. Do not include secrets.","input_schema":{"type":"object","required":["entries","mode","idempotency_key"],"properties":{"mode":{"enum":["all_or_nothing","best_effort"],"type":"string","description":"REQUIRED — no default."},"entries":{"type":"array","items":{"type":"object"},"description":"Non-empty list of entries, each carrying its own 'kind' ('sprint_item_pointer', 'sprint_item_update', or 'profile_layer'). Each entry may carry an optional 'correlation_key' string echoed back on its result."},"project_id":{"type":"string"},"session_id":{"type":"string","description":"Optional attribution for the idempotency receipt."},"max_entries":{"type":"integer","description":"Optional cap on len(entries) for this call (default 100)."},"project_name":{"type":"string","description":"Project name — an alternative to project_id; resolved to the id internally. project_id wins if both are given."},"idempotency_key":{"type":"string","description":"REQUIRED key (value may be null or \"\" to explicitly opt out)."}}},"output_schema":null,"annotations":{"title":"Batch Mutate","readOnlyHint":false,"openWorldHint":false,"idempotentHint":false,"destructiveHint":false},"source":"probe","observed_at":"2026-09-29T06:40:02.225Z"},{"name":"batch_read","title":"Batch Read","description":"[SUPPORT] 133bfff6 — run a batch of DOMAIN-AWARE, CONCURRENT read requests in ONE call. Each request names an 'adapter' + 'operation' + 'args'; independent requests (no depends_on) execute concurrently via asyncio.gather — this is pure in-process dispatch, no subagents/worktrees involved. A request with 'depends_on' (a list of other requests' 'request_id's in this SAME batch) waits only for its own declared prerequisites, not the whole batch; if a prerequisite fails, the dependent resolves immediately with error_code='DEPENDENCY_FAILED' and is never executed. Two requests with the identical adapter+operation+normalized-args+depends_on-set COALESCE to one execution — duplicates come back with cache_hit=true and coalesced_with=<the request_id that actually ran>; pass a non-default cache_policy to opt a specific request out of coalescing. Adapters currently registered: 'sprint_board' with operations 'get_sprint_items' (args: status, show_blocked, include_human, version, include_manual_blocker, include_deferred — same meaning as the get_sprint_items tool) and 'get_sprint_item_pointers' (args: sprint_item_id — 404s if that item belongs to a different project); and 'profile' (PROFILE-7) with operations 'get_profile_layer' (args: scope_type, scope_id), 'list_profile_layers' (args: optional scope_type filter), 'get_effective_profile' (args: optional session_id, user_scope_id, workspace_scope_id — returns the merged, generation-keyed effective profile across all 5 layers), and 'get_profile_layer_revisions' (args: scope_id, optional limit); and 'tunnel_research' (d17a437a, bounded cross-MCP research fan-out) with operations 'diagnostics' (args: optional refresh bool — reports which of the code/docs/outputs tunnel slots are connected right now and which specific tool names are routable on them; never fails on a missing tunnel context) and 'call' (args: tool, optional arguments object — dispatches ONE READ-ONLY tool call through whichever connected tunnel slot serves it; 'tool' must be on this adapter's own fixed read-only allowlist for the code-intel/meridian-docs/meridian-outputs MCP surfaces or it is rejected as VALIDATION_ERROR before any dispatch is attempted; NOT_FOUND when no tunnel is active or the tool isn't exposed on any connected slot — never dispatched blind). Returns {results: [{request_id, status, adapter, operation, result, error_code, error_message, elapsed_ms, cache_hit, coalesced_with}], elapsed_ms} — results is ALWAYS in input order. error_code is one of VALIDATION_ERROR, ADAPTER_NOT_FOUND, OPERATION_NOT_FOUND, DEPENDENCY_NOT_FOUND, DEPENDENCY_CYCLE, DEPENDENCY_FAILED, NOT_FOUND, TIMEOUT, INTERNAL_ERROR. This tool is READ-ONLY — for mutations use batch_mutate or execute_batch.","input_schema":{"type":"object","required":["requests"],"properties":{"requests":{"type":"array","items":{"type":"object","required":["request_id","adapter","operation"],"properties":{"args":{"type":"object","description":"Operation-specific arguments. Defaults to {}."},"adapter":{"type":"string","description":"Registered adapter name, e.g. 'sprint_board'."},"operation":{"type":"string","description":"Operation the adapter exposes, e.g. 'get_sprint_items'."},"depends_on":{"type":"array","items":{"type":"string"},"description":"Optional list of this batch's own request_ids that must resolve first."},"request_id":{"type":"string","description":"Required, unique within this batch."},"timeout_ms":{"type":"integer","description":"Optional per-request timeout in milliseconds (default 10000)."},"cache_policy":{"type":"string","description":"Optional. Any value other than omitted/\"\"/\"default\" opts this request OUT of duplicate-coalescing."}}},"description":"Non-empty list of typed read requests."},"project_id":{"type":"string"},"max_requests":{"type":"integer","description":"Optional cap on len(requests) for this call (default 100)."},"project_name":{"type":"string","description":"Project name — an alternative to project_id; resolved to the id internally. project_id wins if both are given."}}},"output_schema":null,"annotations":{"title":"Batch Read","readOnlyHint":true,"openWorldHint":false,"idempotentHint":true,"destructiveHint":false},"source":"probe","observed_at":"2026-09-29T06:40:02.225Z"},{"name":"capture_research_finding","title":"Capture Research Finding","description":"[SUPPORT] Inline capture for web/paper research during planning: save a finding from a URL as an addressable note with the source link, optionally linked to a decision. A research-shaped wrapper over save_finding — arXiv URLs are tagged source_type=arxiv automatically, everything else as web. Turns web-search results into durable Meridian artifacts instead of evaporating. Persistent-state disclosure: on hosted Meridian, supplied text and project/session metadata -- including task log entries, pinned decisions, sprint items, notes, handoff/goal state, and HITL queue items -- are sent to and stored in Meridian's service, in an isolated per-tenant Postgres database (Neon); self-hosted deployments keep the same categories in the configured local SQLite/Postgres database. This data is visible in the dashboard and API, and may resurface in later project context or handoffs. Notes and pinned decisions can be deleted individually; task log entries and sprint items can be deleted via the dashboard/API (not exposed as an agent-facing tool); HITL queue items and handoff state have no per-record delete. Full removal of any of this data is available via project or account deletion, using the documented controls. Do not include secrets.","input_schema":{"type":"object","required":["url","summary"],"properties":{"url":{"type":"string","description":"Source URL of the web page or paper."},"summary":{"type":"string","description":"Your summary of the finding (markdown)."},"project_id":{"type":"string"},"project_name":{"type":"string","description":"Project name — an alternative to project_id; resolved to the id internally. project_id wins if both are given."},"related_decision_id":{"type":"string","description":"Optional pinned-decision id to link the finding to."}}},"output_schema":null,"annotations":{"title":"Capture Research Finding","readOnlyHint":false,"openWorldHint":false,"idempotentHint":false,"destructiveHint":false},"source":"probe","observed_at":"2026-09-29T06:40:02.225Z"},{"name":"checkpoint","title":"Checkpoint","description":"[SUPPORT] Save progress mid-session. Runs auto_capture (buckets done tasks into a note), generates a delta handoff, and returns a compact summary with what was done, what's pending, and the suggested next /goal string (now the same canonical, token-embedded continuation block generate_handoff renders — verify it with verify_handoff_token exactly like any other /goal block). Call before context fills up or before ending a session. Persistent-state disclosure: on hosted Meridian, supplied text and project/session metadata -- including task log entries, pinned decisions, sprint items, notes, handoff/goal state, and HITL queue items -- are sent to and stored in Meridian's service, in an isolated per-tenant Postgres database (Neon); self-hosted deployments keep the same categories in the configured local SQLite/Postgres database. This data is visible in the dashboard and API, and may resurface in later project context or handoffs. Notes and pinned decisions can be deleted individually; task log entries and sprint items can be deleted via the dashboard/API (not exposed as an agent-facing tool); HITL queue items and handoff state have no per-record delete. Full removal of any of this data is available via project or account deletion, using the documented controls. Do not include secrets.","input_schema":{"type":"object","required":["session_id"],"properties":{"version":{"type":"string","description":"(455cfc36) Optional explicit sprint-version bucket (e.g. 'v0.2.6') to scope this checkpoint to — wins over the calling session's own stored sprint_version, exactly like generate_handoff's own version kwarg. Omit to fall back to the session's resolved scope (unchanged default behavior)."},"project_id":{"type":"string"},"session_id":{"type":"string"},"project_name":{"type":"string","description":"Project name — an alternative to project_id; resolved to the id internally. project_id wins if both are given."}}},"output_schema":null,"annotations":{"title":"Checkpoint","readOnlyHint":false,"openWorldHint":false,"idempotentHint":false,"destructiveHint":false},"source":"probe","observed_at":"2026-09-29T06:40:02.225Z"},{"name":"claim_docx_region","title":"Claim Docx Region","description":"[MAINTENANCE] f7ee1ba7 — Model B scoped-region claiming for .docx files. Claim a specific paragraph/element by its durable `element_id` (the w14:paraId surfaced by get_document_structure / update_paragraph) so another session cannot overwrite it concurrently. Two sessions can hold NON-OVERLAPPING element claims on the SAME file — the real precision benefit vs. a whole-file lock. An edit to a claimed element_id by another session is REJECTED structurally (not just advisory) at the update_paragraph level. A whole-file lock by another session blocks this claim. Returns {claimed: true, file_path, session_id, element_id} on success or {claimed: false, reason, message, conflicts} on conflict. Persistent-state disclosure: on hosted Meridian, supplied text and project/session metadata -- including task log entries, pinned decisions, sprint items, notes, handoff/goal state, and HITL queue items -- are sent to and stored in Meridian's service, in an isolated per-tenant Postgres database (Neon); self-hosted deployments keep the same categories in the configured local SQLite/Postgres database. This data is visible in the dashboard and API, and may resurface in later project context or handoffs. Notes and pinned decisions can be deleted individually; task log entries and sprint items can be deleted via the dashboard/API (not exposed as an agent-facing tool); HITL queue items and handoff state have no per-record delete. Full removal of any of this data is available via project or account deletion, using the documented controls. Do not include secrets.","input_schema":{"type":"object","required":["session_id","file_path","element_id"],"properties":{"file_path":{"type":"string","description":"The .docx source path (the same value as the `doc` arg to update_paragraph / ingest_document)."},"element_id":{"type":"string","description":"The target element's durable id (w14:paraId or p{index} fallback) as surfaced by get_document_structure."},"session_id":{"type":"string","description":"The calling session."}}},"output_schema":null,"annotations":{"title":"Claim Docx Region","readOnlyHint":false,"openWorldHint":false,"idempotentHint":false,"destructiveHint":false},"source":"probe","observed_at":"2026-09-29T06:40:02.225Z"},{"name":"claim_file","title":"Claim File","description":"[SUPPORT] Claim edit rights on a file for this session. Whole-file by default (auto-expires after 2 hours). For symbol-level claims — so two sessions can edit the same file if they own different classes/functions — also pass `symbol` (e.g. 'AuthRouter' or 'AuthRouter.login') AND `content` (the file's full source). Meridian parses the source (stdlib ast for Python, tree-sitter for JS/TS/C/C++/Go/Rust/Java/C#), and hard-blocks if another live session already owns an overlapping line range — the block lists which symbols are still safe to claim. Unparseable content falls back to a whole-file lock. The response includes a `code_notes` list of code-anchored project notes (kind='code') for this file/symbol — read them before editing. Pass `item_id` (the sprint item you're claiming this file/symbol for) whenever you know it — it disambiguates the touches_resources amendment side-effect (c027922d) when your session holds more than one sprint item in_progress at once. Persistent-state disclosure: on hosted Meridian, supplied text and project/session metadata -- including task log entries, pinned decisions, sprint items, notes, handoff/goal state, and HITL queue items -- are sent to and stored in Meridian's service, in an isolated per-tenant Postgres database (Neon); self-hosted deployments keep the same categories in the configured local SQLite/Postgres database. This data is visible in the dashboard and API, and may resurface in later project context or handoffs. Notes and pinned decisions can be deleted individually; task log entries and sprint items can be deleted via the dashboard/API (not exposed as an agent-facing tool); HITL queue items and handoff state have no per-record delete. Full removal of any of this data is available via project or account deletion, using the documented controls. Do not include secrets.","input_schema":{"type":"object","required":["session_id","file_path"],"properties":{"mode":{"enum":["read","write"],"type":"string","description":"Claim grain (ffa03655). 'write' (default) = EXCLUSIVE: blocks other writers and is blocked by any other session's read claim. 'read' = SHARED: many sessions can read-claim the same file at once (no false contention for parallel reader agents), blocked only by another session's write lock."},"symbol":{"type":"string","description":"Optional symbol to claim (class/function/method name, e.g. 'AuthRouter' or 'AuthRouter.login'). Requires `content`."},"content":{"type":"string","description":"Full source of the file, required when `symbol` is given so the server can resolve the symbol's line range."},"item_id":{"type":"string","description":"Optional sprint item id this claim is being made for (c027922d). When your session holds 2+ sprint items in_progress concurrently, pass this so the touches_resources amendment side-effect is attributed to the right item instead of guessed."},"file_path":{"type":"string"},"session_id":{"type":"string"}}},"output_schema":null,"annotations":{"title":"Claim File","readOnlyHint":false,"openWorldHint":false,"idempotentHint":false,"destructiveHint":false},"source":"probe","observed_at":"2026-09-29T06:40:02.225Z"},{"name":"claim_sprint_item","title":"Claim Sprint Item","description":"Claim a pending sprint item: sets status to in_progress and records claimed_at + actor. Read-only: false. Rejects if the item is already in_progress, done, failed, skipped, its touches_files overlap active file claims from another live session, or (18c488b6) a touches_resources file:/symbol: entry is locked by another live session — this last check ACQUIRES the resource lock (via claim_file/claim_symbol) as part of claiming, is a hard block regardless of worktree isolation, and rolls back cleanly if the claim itself doesn't land. 54c488b6/54d2c2af: every symbol:/file: resource this acquires also gets a durable lock-granularity receipt (achieved symbol vs. coarse-fallback grain, and why), auditable after the fact independent of this call's response payload. 1b7eb437: on a project that has opted into the 'handoff_provenance_verification' capability (set_capability_manifest), the claimed item's response also carries handoff_provenance_warning (no matching verify_handoff_token/accept_handoff receipt attributable to this session_id was found) or handoff_provenance_receipt (a matching receipt) — informational only, never blocks the claim in this pass. Reuses this tool's existing session_id argument for attribution; no new argument is needed. Persistent-state disclosure: on hosted Meridian, supplied text and project/session metadata -- including task log entries, pinned decisions, sprint items, notes, handoff/goal state, and HITL queue items -- are sent to and stored in Meridian's service, in an isolated per-tenant Postgres database (Neon); self-hosted deployments keep the same categories in the configured local SQLite/Postgres database. This data is visible in the dashboard and API, and may resurface in later project context or handoffs. Notes and pinned decisions can be deleted individually; task log entries and sprint items can be deleted via the dashboard/API (not exposed as an agent-facing tool); HITL queue items and handoff state have no per-record delete. Full removal of any of this data is available via project or account deletion, using the documented controls. Do not include secrets.","input_schema":{"type":"object","required":["item_id"],"properties":{"actor":{"type":"string","description":"Executor id/name recorded as having claimed the item (5823db0b; defaults to session_id)."},"item_id":{"type":"string"},"project_id":{"type":"string"},"session_id":{"type":"string","description":"Optional caller session id; its own file claims are ignored for conflict checks, and it is the identity any touches_resources symbol/file locks are acquired under (18c488b6). Omitting it skips resource-lock acquisition entirely (fail-open — no behavior change from before 18c488b6) UNLESS strict_resource_locking=true, in which case a missing session_id on an item that declares resources is refused outright (MISSING_EXECUTION_IDENTITY)."},"project_name":{"type":"string","description":"Project name — an alternative to project_id; resolved to the id internally. project_id wins if both are given."},"resource_contents":{"type":"object","description":"18c488b6 — optional map of {file_path: file_content} for any symbol: entries in the item's touches_resources. The server has no direct filesystem access to your repo, so supplying a file's current content here is what lets a symbol: resource get a REAL AST-resolved line-range lock (via claim_symbol) instead of falling back to a whole-file lock. Omit a file's content (or omit this arg entirely) and its symbol: resources fall back to a whole-file lock with an explicit fallback_reason in the response's resource_lock_scope — never a silent downgrade, UNLESS strict_resource_locking=true (see below), in which case that same fallback is REJECTED instead."},"allow_file_fallback":{"type":"boolean","description":"54d2c2af — explicit, audited approval for the whole-file-lock fallback that strict_resource_locking=true would otherwise reject for an unresolved symbol: resource. Ignored when strict_resource_locking is not set (the pre-54d2c2af default already allows this fallback implicitly). Pass true to say 'yes, lock the whole file for this resource' instead of supplying real resource_contents."},"strict_resource_locking":{"type":"boolean","description":"54d2c2af — default false (zero behavior change). Set true to opt this call into the HARDENED, fail-closed contract: a symbol: resource that cannot get a real symbol-range lock (missing resource_contents for its file, or claim_symbol itself couldn't resolve the symbol — unparseable / not found / ambiguous) is REJECTED (ok=false, error=SYMBOL_LOCK_NOT_APPROVED, all-or-nothing rollback) instead of silently widening to a whole-file lock, unless allow_file_fallback=true is ALSO passed. Also promotes a missing session_id (on an item that declares resources) from the default fail-open skip to a hard MISSING_EXECUTION_IDENTITY block."}}},"output_schema":null,"annotations":{"title":"Claim Sprint Item","readOnlyHint":false,"openWorldHint":false,"idempotentHint":false,"destructiveHint":false},"source":"probe","observed_at":"2026-09-29T06:40:02.225Z"},{"name":"clear_capability_profile","title":"Clear Capability Profile","description":"[SUPPORT] 02038afe — Delete a scope's ENTIRE capability profile row (both its capabilities and its disabled_capability_ids) so it reverts to purely inheriting from less specific layers. Distinct from disabling individual capability ids via set_capability_profile's disabled_capability_ids — this clears the whole layer. Idempotent: clearing an already-empty or never-set scope is a no-op, not an error. Persistent-state disclosure: on hosted Meridian, supplied text and project/session metadata -- including task log entries, pinned decisions, sprint items, notes, handoff/goal state, and HITL queue items -- are sent to and stored in Meridian's service, in an isolated per-tenant Postgres database (Neon); self-hosted deployments keep the same categories in the configured local SQLite/Postgres database. This data is visible in the dashboard and API, and may resurface in later project context or handoffs. Notes and pinned decisions can be deleted individually; task log entries and sprint items can be deleted via the dashboard/API (not exposed as an agent-facing tool); HITL queue items and handoff state have no per-record delete. Full removal of any of this data is available via project or account deletion, using the documented controls. Do not include secrets.","input_schema":{"type":"object","required":["scope_type","scope_id"],"properties":{"scope_id":{"type":"string"},"scope_type":{"enum":["workspace","user","project","sprint_version","item"],"type":"string"}}},"output_schema":null,"annotations":{"title":"Clear Capability Profile","readOnlyHint":false,"openWorldHint":false,"idempotentHint":false,"destructiveHint":false},"source":"probe","observed_at":"2026-09-29T06:40:02.225Z"},{"name":"clone_profile_layer","title":"Clone Profile Layer","description":"[SUPPORT] 0bec79a7 (PROFILE-5) — Copy one layer's fields/reset_fields/provenance onto another scope, going through the exact same validation/hashing path as save_profile_layer (not a raw copy) — the target scope's allowed_layers may differ from the source's, so a field the source layer legally carries can still be rejected at the target. Rejects with {error} when the source layer does not exist (revision=0 — cloning nothing is a caller error, not a silent no-op). Cloning INTO a hosted_default target never carries over the source's lifecycle_state — a fresh clone always lands in 'draft', exactly like any other first-ever write on a hosted_default scope; use activate_profile_layer afterward to publish it. Persistent-state disclosure: on hosted Meridian, supplied text and project/session metadata -- including task log entries, pinned decisions, sprint items, notes, handoff/goal state, and HITL queue items -- are sent to and stored in Meridian's service, in an isolated per-tenant Postgres database (Neon); self-hosted deployments keep the same categories in the configured local SQLite/Postgres database. This data is visible in the dashboard and API, and may resurface in later project context or handoffs. Notes and pinned decisions can be deleted individually; task log entries and sprint items can be deleted via the dashboard/API (not exposed as an agent-facing tool); HITL queue items and handoff state have no per-record delete. Full removal of any of this data is available via project or account deletion, using the documented controls. Do not include secrets.","input_schema":{"type":"object","required":["source_scope_type","source_scope_id","target_scope_type","target_scope_id"],"properties":{"actor":{"type":"string","description":"Optional human/session identity recorded on the target's hosted_default audit ledger, if the target is hosted_default."},"source_scope_id":{"type":"string"},"target_scope_id":{"type":"string"},"source_scope_type":{"enum":["hosted_default","workspace","user","project","session"],"type":"string"},"target_scope_type":{"enum":["hosted_default","workspace","user","project","session"],"type":"string"}}},"output_schema":null,"annotations":{"title":"Clone Profile Layer","readOnlyHint":false,"openWorldHint":false,"idempotentHint":false,"destructiveHint":false},"source":"probe","observed_at":"2026-09-29T06:40:02.225Z"},{"name":"commit_proposal_promotion","title":"Commit Proposal Promotion","description":"[SUPPORT] Commit a proposal's promotion through 'depth' (ce4883f3), cumulative over every shallower depth. Requires 'preview_hash' from a just-called preview_proposal_promotion with the SAME arguments — a mismatch (proposal or target project's board changed since) is rejected rather than silently committed against stale information, and nothing is written. Committing an already-satisfied depth is an idempotent no-op success (matches the preview's already_satisfied=true case). A genuine lost race against a concurrent caller (caught by the underlying race-safe functions) is reported honestly as a failure with a 'deviation_auto_resolved' audit trail — never silently retried or swallowed. When the promoted sprint item's resources or the proposal's own text match one of 3 narrow deviation heuristics (production_deployment / tenant_security_boundary / destructive_behavior), this files a durable HITL via request_hitl and returns hitl_pending=true WITHOUT completing remaining steps — pass a non-empty 'override_reason' to acknowledge and proceed anyway (audited). 'investigation_findings' and 'pointers' are recorded via append_proposal_update at the matching depth; 'pointers' entries are validated via meridian.pointers.validate_pointer (each needs source_type + a non-empty targets array of {uri, selector, target_kind?}). depth='executable_handoff' calls generate_handoff(selected_item_ids=[the new/reused sprint item id]) — scoped to exactly that item's dependency closure, with project/version/session identity. Returns {proposal_id, project_id, depth, already_satisfied, committed, deviation, hitl_pending, hitl_request_id}. Persistent-state disclosure: on hosted Meridian, supplied text and project/session metadata -- including task log entries, pinned decisions, sprint items, notes, handoff/goal state, and HITL queue items -- are sent to and stored in Meridian's service, in an isolated per-tenant Postgres database (Neon); self-hosted deployments keep the same categories in the configured local SQLite/Postgres database. This data is visible in the dashboard and API, and may resurface in later project context or handoffs. Notes and pinned decisions can be deleted individually; task log entries and sprint items can be deleted via the dashboard/API (not exposed as an agent-facing tool); HITL queue items and handoff state have no per-record delete. Full removal of any of this data is available via project or account deletion, using the documented controls. Do not include secrets.","input_schema":{"type":"object","required":["proposal_id","depth","preview_hash"],"properties":{"actor":{"type":"string","description":"Optional actor identity recorded on proposal events."},"depth":{"enum":["proposal","investigation","pointers","sprint_items","executable_handoff"],"type":"string","description":"How far to commit promoting, cumulative over every shallower depth."},"pointers":{"type":"array","items":{"type":"object"},"description":"Pointer declarations to record (depth>='pointers'); each validated via meridian.pointers.validate_pointer ({source_type, targets: [{uri, selector, target_kind?}], label?})."},"project_id":{"type":"string","description":"Target project — where the sprint item lands."},"session_id":{"type":"string","description":"Caller session id; threaded into recorded events and into the depth='executable_handoff' handoff."},"proposal_id":{"type":"string"},"preview_hash":{"type":"string","description":"The 'preview_hash' from a fresh preview_proposal_promotion call with the SAME arguments."},"project_name":{"type":"string","description":"Project name — alternative to project_id; resolved to the id internally."},"override_reason":{"type":"string","description":"Non-empty reason to acknowledge and proceed past a triggered HITL deviation instead of stopping (audited)."},"sprint_item_title":{"type":"string","description":"Override title for the sprint item; defaults to the proposal title."},"touches_resources":{"type":"array","items":{"type":"string"},"description":"Explicit resource ids for the sprint item; overrides inference."},"sprint_item_version":{"type":"string","description":"Sprint version for the new item; defaults to 'current'."},"investigation_findings":{"type":"string","description":"Investigation findings to record (depth>='investigation'); recorded via append_proposal_update."},"infer_touches_resources":{"type":"boolean","description":"Infer touches_resources from the proposal's title/body via recent git history when touches_resources is omitted. Default true."}}},"output_schema":null,"annotations":{"title":"Commit Proposal Promotion","readOnlyHint":false,"openWorldHint":false,"idempotentHint":false,"destructiveHint":false},"source":"probe","observed_at":"2026-09-29T06:40:02.225Z"},{"name":"compare_proposal_versions","title":"Compare Proposal Versions","description":"[SUPPORT] Read-only: structural diff between two proposals — most commonly two adjacent versions in a lineage chain, but works for any two existing proposal ids. Reports per-field before/after/changed for title/body/tags/status/scope_type/project_id/family_id, plus a difflib similarity ratio and a unified diff for body specifically, plus whether the two are directly linked in the lineage graph ('adjacent') and the connecting edge(s) if so. Returns {from, to, direct_relations, adjacent, diff}.","input_schema":{"type":"object","required":["from_proposal_id","to_proposal_id"],"properties":{"to_proposal_id":{"type":"string","description":"Second proposal to compare (the 'b' side of each diff entry)."},"from_proposal_id":{"type":"string","description":"First proposal to compare (the 'a' side of each diff entry)."}}},"output_schema":null,"annotations":{"title":"Compare Proposal Versions","readOnlyHint":true,"openWorldHint":false,"idempotentHint":true,"destructiveHint":false},"source":"probe","observed_at":"2026-09-29T06:40:02.225Z"},{"name":"complete_experiment_run","title":"Complete Experiment Run","description":"[SUPPORT] 3f6b8715 — finalize a run as status='completed' (default) or status='abandoned'. outcome_summary and disposition (keep|discard|promote) are explicit and REQUIRED — rejected with {error} when missing/empty, even on a retry against an already-terminal run. result_receipt is bounded to 32KB; past that cap it is spilled to durable object storage (local content-addressed storage today, transparently upgrading to Tigris when configured) and replaced with a small pointer — never truncated, and rejected outright only if the spill itself fails. HARD INVARIANT: this call always writes an experiment_events row when the run newly reaches a terminal state here — status='abandoned' or an outcome_summary containing 'dead end'/'failed' (case-insensitive) auto-writes {event_type:'dead_end'}. Persistent-state disclosure: on hosted Meridian, supplied text and project/session metadata -- including task log entries, pinned decisions, sprint items, notes, handoff/goal state, and HITL queue items -- are sent to and stored in Meridian's service, in an isolated per-tenant Postgres database (Neon); self-hosted deployments keep the same categories in the configured local SQLite/Postgres database. This data is visible in the dashboard and API, and may resurface in later project context or handoffs. Notes and pinned decisions can be deleted individually; task log entries and sprint items can be deleted via the dashboard/API (not exposed as an agent-facing tool); HITL queue items and handoff state have no per-record delete. Full removal of any of this data is available via project or account deletion, using the documented controls. Do not include secrets.","input_schema":{"type":"object","required":["session_id","run_id","outcome_summary","disposition"],"properties":{"run_id":{"type":"string"},"status":{"enum":["completed","abandoned"],"type":"string","description":"Terminal status this call produces (default 'completed'). 'expired' is expire_stale_runs' exclusive path, not settable here."},"project_id":{"type":"string"},"session_id":{"type":"string"},"disposition":{"enum":["keep","discard","promote"],"type":"string","description":"Explicit, never inferred. 'promote' makes this run eligible for promote_experiment_run."},"project_name":{"type":"string","description":"Project name — an alternative to project_id; resolved to the id internally. project_id wins if both are given."},"result_receipt":{"type":"object","description":"Bounded (32KB) JSON-serializable receipt — rejected, never truncated, past the cap."},"outcome_summary":{"type":"string","description":"Required, non-empty. Bounded to 4000 characters."}}},"output_schema":null,"annotations":{"title":"Complete Experiment Run","readOnlyHint":false,"openWorldHint":false,"idempotentHint":false,"destructiveHint":false},"source":"probe","observed_at":"2026-09-29T06:40:02.225Z"},{"name":"complete_external_job","title":"Complete External Job","description":"[SUPPORT] Finalize an external job with an explicit terminal outcome. This never infers success from output files and never reopens a terminal record. It appends a final task-log event and refreshes the local snapshot. Persistent-state disclosure: on hosted Meridian, supplied text and project/session metadata -- including task log entries, pinned decisions, sprint items, notes, handoff/goal state, and HITL queue items -- are sent to and stored in Meridian's service, in an isolated per-tenant Postgres database (Neon); self-hosted deployments keep the same categories in the configured local SQLite/Postgres database. This data is visible in the dashboard and API, and may resurface in later project context or handoffs. Notes and pinned decisions can be deleted individually; task log entries and sprint items can be deleted via the dashboard/API (not exposed as an agent-facing tool); HITL queue items and handoff state have no per-record delete. Full removal of any of this data is available via project or account deletion, using the documented controls. Do not include secrets.","input_schema":{"type":"object","required":["session_id"],"properties":{"detail":{"type":"string"},"job_id":{"type":"string"},"status":{"enum":["succeeded","failed","canceled"],"type":"string"},"job_key":{"type":"string"},"metadata":{"type":"object"},"project_id":{"type":"string"},"session_id":{"type":"string"},"project_name":{"type":"string","description":"Project name — an alternative to project_id; resolved to the id internally. project_id wins if both are given."}}},"output_schema":null,"annotations":{"title":"Complete External Job","readOnlyHint":false,"openWorldHint":false,"idempotentHint":false,"destructiveHint":false},"source":"probe","observed_at":"2026-09-29T06:40:02.225Z"},{"name":"complete_research_run","title":"Complete Research Run","description":"[SUPPORT] a5343387 — finalize a research run with a compact, byte-bounded receipt (16KB cap; exceeding it is REJECTED, never silently truncated). disposition is explicit and REQUIRED (keep|discard|promote) — never inferred from the run's outcome. Idempotent on an already-terminal run (completed/failed/abandoned/expired): a duplicate call returns the existing terminal state unchanged, never an error. Only disposition='promote' runs are eligible for promote_research_run, and only disposition in (keep, promote) runs are ever embedded into a handoff's research_run_receipts (see generate_handoff/build_continuation_manifest) — discard means exactly that. Persistent-state disclosure: on hosted Meridian, supplied text and project/session metadata -- including task log entries, pinned decisions, sprint items, notes, handoff/goal state, and HITL queue items -- are sent to and stored in Meridian's service, in an isolated per-tenant Postgres database (Neon); self-hosted deployments keep the same categories in the configured local SQLite/Postgres database. This data is visible in the dashboard and API, and may resurface in later project context or handoffs. Notes and pinned decisions can be deleted individually; task log entries and sprint items can be deleted via the dashboard/API (not exposed as an agent-facing tool); HITL queue items and handoff state have no per-record delete. Full removal of any of this data is available via project or account deletion, using the documented controls. Do not include secrets.","input_schema":{"type":"object","required":["session_id","run_id","disposition"],"properties":{"run_id":{"type":"string"},"receipt":{"type":"object","properties":{"commands_run":{"type":"array","items":{"type":"string"}},"files_touched":{"type":"array","items":{"type":"string"}},"failure_reason":{"type":"string"},"result_summary":{"type":"string"},"artifact_references":{"type":"array","items":{"type":"string"}}},"description":"Compact receipt (16KB total cap): files_touched (list of project-relative paths), commands_run (list, truncated if long), result_summary (bounded string), artifact_references (list of pointer ids), failure_reason (string or null)."},"project_id":{"type":"string"},"session_id":{"type":"string"},"disposition":{"enum":["keep","discard","promote"],"type":"string","description":"Explicit, never inferred. 'promote' makes this run eligible for promote_research_run."},"project_name":{"type":"string","description":"Project name — an alternative to project_id; resolved to the id internally. project_id wins if both are given."}}},"output_schema":null,"annotations":{"title":"Complete Research Run","readOnlyHint":false,"openWorldHint":false,"idempotentHint":false,"destructiveHint":false},"source":"probe","observed_at":"2026-09-29T06:40:02.225Z"},{"name":"complete_sprint_item","title":"Complete Sprint Item","description":"Mark a sprint item done. Pass task_id to link the task that shipped it. Pass session_id to get a board_change field (items injected mid-run) and an active-worktree merge reminder in the response. If the item is flagged required_notes, you MUST pass notes= (evidence: what shipped / how verified) or a task_id, or completion is refused (EVIDENCE_REQUIRED). If the item is flagged require_verification (e2e1b682), completion is refused (VERIFICATION_REQUIRED) unless an independent PASS is on file: pass verifier_session_id (a DIFFERENT session id from actor — a fresh, no-memory subsession that inspected the change with read-only tools) and verification_verdict='pass' to file and check the verdict in this same call. fdaa5b55 — if the item has a linked GitHub issue, the response carries a github_issue_action field: issues Meridian itself created (github_issue_source='meridian_auto') are commented on and auto-closed; any other issue (manual/legacy) only gets a proposed-closure comment plus a non-blocking HITL for human review — never auto-closed. 8693b6a8 — claim-ownership gate: if the item is claimed by a DIFFERENT actor than the one completing it, completion is refused (CLAIM_MISMATCH) UNLESS that claim is stale (claimed 2h+ ago, or the claiming session is dead/closed) — the exact stale-cleanup pattern of closing items left behind by a dead session keeps working automatically. For a live, non-stale foreign claim, pass force_foreign_claim=true to explicitly acknowledge and complete anyway. 5fe3502e — pass strict_evidence=true (or flag the item require_strict_evidence=true via update_sprint_item) for STRICT, fail-closed evidence verification: completion is refused (STRICT_EVIDENCE_BLOCKED, with typed evidence_errors codes — EVIDENCE_ABSENT/EVIDENCE_INVALID/EVIDENCE_STALE/WRONG_WORKTREE/UNCLAIMED_EDIT) unless evidence is present, verifiable, fresh, from the right worktree, and every modified file was claimed. Default (no strict_evidence, no require_strict_evidence) behavior is exactly the pre-existing advisory-only evidence checks — nothing changes unless you opt in. a8c0f3b7 — CODE-INTEL PROSPECTING RECEIPT gate: opt in at the PROJECT level via set_capability_manifest(capabilities=[{id:'code_intel_prospecting', ...}]) — no per-call flag needed, and a no-op for projects that never declared it. When declared, completion of an item that has touches_resources and no prospect_bypass is refused (CODE_INTEL_RECEIPT_MISSING) unless a durable receipt shows a real search_graph/find_symbol/prospect_symbol call happened since the item was claimed (see meridian.code_intel_receipt) — or refused (CODE_INTEL_UNAVAILABLE) when the capability is availability_policy='required' and code-intel itself is unavailable. Pass override_code_intel_receipt=true with a non-empty override_reason to acknowledge and complete anyway (audited). 'optional'/'degraded_ok' policies never block — they degrade with a code_intel_receipt_warning on the returned item instead. Persistent-state disclosure: on hosted Meridian, supplied text and project/session metadata -- including task log entries, pinned decisions, sprint items, notes, handoff/goal state, and HITL queue items -- are sent to and stored in Meridian's service, in an isolated per-tenant Postgres database (Neon); self-hosted deployments keep the same categories in the configured local SQLite/Postgres database. This data is visible in the dashboard and API, and may resurface in later project context or handoffs. Notes and pinned decisions can be deleted individually; task log entries and sprint items can be deleted via the dashboard/API (not exposed as an agent-facing tool); HITL queue items and handoff state have no per-record delete. Full removal of any of this data is available via project or account deletion, using the documented controls. Do not include secrets.","input_schema":{"type":"object","required":["item_id"],"properties":{"actor":{"type":"string","description":"Executor id/name recorded as having completed the item (defaults to session_id). Checked against the item's claim owner (8693b6a8) — a mismatch on a live, non-stale claim is refused unless force_foreign_claim=true."},"notes":{"type":"string","description":"Evidence for the completion (what shipped / how it was verified). Persisted on the item; satisfies the required_notes gate."},"item_id":{"type":"string"},"task_id":{"type":"string"},"project_id":{"type":"string"},"session_id":{"type":"string","description":"Optional: include board_change + worktree merge reminder."},"project_name":{"type":"string","description":"Project name — an alternative to project_id; resolved to the id internally. project_id wins if both are given."},"override_reason":{"type":"string","description":"5fe3502e — REQUIRED alongside override_strict_evidence=true (or a8c0f3b7's override_code_intel_receipt=true): why the rejection is being overridden. Recorded to action_audit_log (who/when/why) — an override with no reason is refused, not silently accepted."},"strict_evidence":{"type":"boolean","description":"5fe3502e — opt in to the STRICT, fail-closed evidence gate for THIS call only (see meridian.sprint_evidence_guard). Omit/false preserves the exact pre-existing advisory-only behavior. Equivalent, persistent alternative: update_sprint_item(require_strict_evidence=true)."},"verification_notes":{"type":"string","description":"e2e1b682 — optional free-text explanation from the verifier (especially useful on a fail verdict)."},"force_foreign_claim":{"type":"boolean","description":"8693b6a8 — set true to complete an item claimed by a DIFFERENT, still-live (non-stale) actor. An explicit override, never inferred; omit/false for normal completion. Not needed to close items left behind by a stale/dead claiming session — that is detected automatically."},"verifier_session_id":{"type":"string","description":"e2e1b682 — session id of the fresh, independent, read-only-tools verifier subsession that PASSED/FAILED this item. Must differ from actor/session_id or the require_verification gate rejects it as non-independent. Ignored on items without require_verification set."},"verification_verdict":{"enum":["pass","fail"],"type":"string","description":"e2e1b682 — the fresh verifier subsession's independent PASS/FAIL determination. Required (with verifier_session_id) to satisfy require_verification in the same call as completion."},"override_strict_evidence":{"type":"boolean","description":"5fe3502e — explicit, audited override of a STRICT_EVIDENCE_BLOCKED rejection. Must be paired with a non-empty override_reason in the SAME call, or it is ignored and the block stands. Never inferred; omit/false for normal strict behavior."},"override_code_intel_receipt":{"type":"boolean","description":"a8c0f3b7 — explicit, audited override of a CODE_INTEL_RECEIPT_MISSING / CODE_INTEL_UNAVAILABLE rejection. Must be paired with a non-empty override_reason in the SAME call, or it is ignored and the block stands. Only relevant for a project that declared the 'code_intel_prospecting' capability."}}},"output_schema":null,"annotations":{"title":"Complete Sprint Item","readOnlyHint":false,"openWorldHint":false,"idempotentHint":false,"destructiveHint":false},"source":"probe","observed_at":"2026-09-29T06:40:02.225Z"},{"name":"complete_wave_gate","title":"Complete Wave Gate","description":"[SUPPORT] d2430713 — EXECUTOR GATE: call this AFTER you have actually run a wave's gate action list (push, deploy, wait, run_verification) to unblock the next wave's sprint items. You MUST pass the REAL structured result from run_verification as verification_payload — the server validates it (status=='ok', exit_code==0). A self-report ('I think it passed') or a fabricated payload is rejected with a clear error. On success, writes a wave_gate_results row and returns {gate_completed, wave_label, next_wave_label, next_wave_item_count, next_wave_item_ids, gate_id}. Each wave gate may only be completed once (duplicate calls return an error). Security note: this is a deploy-adjacent gate — only actual run_verification output satisfies it. ed8e4524 — SCOPED TO SPRINT VERSION: pass version (or session_id to auto-resolve the calling session's scope) so two different sprint versions that happen to share the SAME wave_label (e.g. both have a 'wave-2') never satisfy or unblock each other's gate — omit both to keep the exact prior project-wide behavior for a single-version project. Persistent-state disclosure: on hosted Meridian, supplied text and project/session metadata -- including task log entries, pinned decisions, sprint items, notes, handoff/goal state, and HITL queue items -- are sent to and stored in Meridian's service, in an isolated per-tenant Postgres database (Neon); self-hosted deployments keep the same categories in the configured local SQLite/Postgres database. This data is visible in the dashboard and API, and may resurface in later project context or handoffs. Notes and pinned decisions can be deleted individually; task log entries and sprint items can be deleted via the dashboard/API (not exposed as an agent-facing tool); HITL queue items and handoff state have no per-record delete. Full removal of any of this data is available via project or account deletion, using the documented controls. Do not include secrets.","input_schema":{"type":"object","required":["wave_label","verification_payload"],"properties":{"actor":{"type":"string","description":"Optional session_id or actor name to record who completed the gate."},"version":{"type":"string","description":"ed8e4524 — Optional sprint-version bucket this gate belongs to (e.g. 'v0.2.6'). Wins over session_id's resolved scope. Omit (and omit session_id) for the legacy project-wide gate behavior."},"project_id":{"type":"string"},"session_id":{"type":"string","description":"ed8e4524 — Optional: resolve the version scope from this session's own sprint_version (same helper handoff._resolve_session_sprint_version uses for checkpoint) when version is not given explicitly."},"wave_label":{"type":"string","description":"The wave whose gate is being completed, e.g. 'wave-1'. Must match the wave field on sprint_items that were just executed."},"project_name":{"type":"string","description":"Project name — an alternative to project_id; resolved to the id internally. project_id wins if both are given."},"verification_payload":{"type":"object","description":"The FULL dict returned by run_verification. Must have status='ok' and exit_code=0. Any other value (non-zero exit, error, not_configured, not_connected) is rejected. Do NOT fabricate or self-report — the server validates the payload."}}},"output_schema":null,"annotations":{"title":"Complete Wave Gate","readOnlyHint":false,"openWorldHint":false,"idempotentHint":false,"destructiveHint":false},"source":"probe","observed_at":"2026-09-29T06:40:02.225Z"},{"name":"complete_workspace_sprint_item","title":"Complete Workspace Sprint Item","description":"[MAINTENANCE] Mark a workspace personal-backlog item done (stamps completed_at). Returns the updated item. Persistent-state disclosure: on hosted Meridian, supplied text and project/session metadata -- including task log entries, pinned decisions, sprint items, notes, handoff/goal state, and HITL queue items -- are sent to and stored in Meridian's service, in an isolated per-tenant Postgres database (Neon); self-hosted deployments keep the same categories in the configured local SQLite/Postgres database. This data is visible in the dashboard and API, and may resurface in later project context or handoffs. Notes and pinned decisions can be deleted individually; task log entries and sprint items can be deleted via the dashboard/API (not exposed as an agent-facing tool); HITL queue items and handoff state have no per-record delete. Full removal of any of this data is available via project or account deletion, using the documented controls. Do not include secrets.","input_schema":{"type":"object","required":["item_id"],"properties":{"item_id":{"type":"string"}}},"output_schema":null,"annotations":{"title":"Complete Workspace Sprint Item","readOnlyHint":false,"openWorldHint":false,"idempotentHint":false,"destructiveHint":false},"source":"probe","observed_at":"2026-09-29T06:40:02.225Z"},{"name":"configure_wave_gate","title":"Configure Wave Gate","description":"[SUPPORT] 74a8f420 — PLANNING: configure (or on-the-fly reconfigure) a deterministic action pipeline attached to a wave or wave-range, ENFORCED STRUCTURALLY — not just advisory /goal prose. Once set, claim_sprint_item refuses (WAVE_GATE_PENDING) to claim any item whose wave sorts beyond wave_end until complete_wave_gate records real run_verification evidence for that boundary. actions is an ordered, non-empty list of {\"type\": ...} dicts — type must be one of push_dev | push_main | deploy | wait | run_verification (push_dev/push_main/deploy are run by the executor via trigger_workflow; run_verification maps onto the run_verification tool whose output complete_wave_gate requires as evidence; wait is a plain pause step; extra keys per action, e.g. {\"type\": \"wait\", \"seconds\": 30}, are preserved verbatim). wave_start (defaults to wave_end) documents a multi-wave range covered by one gate checkpoint. Re-configuring an un-passed wave_end is an upsert — the pipeline can be revised right up until an executor completes it; once passed the config is immutable (returns {\"error\": ...}). Returns {configured, gate_config_id, project_id, wave_start, wave_end, actions} on success. ed8e4524 — SCOPED TO SPRINT VERSION: pass version (or session_id to auto-resolve the calling session's scope) so two different sprint versions that happen to share the SAME wave_end label never reconfigure or immutably block each other's gate — omit both to keep the exact prior project-wide behavior for a single-version project. Persistent-state disclosure: on hosted Meridian, supplied text and project/session metadata -- including task log entries, pinned decisions, sprint items, notes, handoff/goal state, and HITL queue items -- are sent to and stored in Meridian's service, in an isolated per-tenant Postgres database (Neon); self-hosted deployments keep the same categories in the configured local SQLite/Postgres database. This data is visible in the dashboard and API, and may resurface in later project context or handoffs. Notes and pinned decisions can be deleted individually; task log entries and sprint items can be deleted via the dashboard/API (not exposed as an agent-facing tool); HITL queue items and handoff state have no per-record delete. Full removal of any of this data is available via project or account deletion, using the documented controls. Do not include secrets.","input_schema":{"type":"object","required":["wave_end","actions"],"properties":{"actor":{"type":"string","description":"Optional session_id or actor name to record who configured the gate."},"actions":{"type":"array","items":{"type":"object"},"description":"Non-empty ordered list of {\"type\": push_dev|push_main|deploy|wait|run_verification, ...params} action dicts — the deterministic pipeline that must run before the next wave unlocks."},"version":{"type":"string","description":"ed8e4524 — Optional sprint-version bucket this gate belongs to (e.g. 'v0.2.6'). Wins over session_id's resolved scope. Omit (and omit session_id) for the legacy project-wide gate behavior."},"wave_end":{"type":"string","description":"The boundary wave, e.g. 'wave-3'. Any item in a later wave (same 'prefix-N' family) is structurally blocked from claim_sprint_item until this gate completes."},"project_id":{"type":"string"},"session_id":{"type":"string","description":"ed8e4524 — Optional: resolve the version scope from this session's own sprint_version (same helper handoff._resolve_session_sprint_version uses for checkpoint) when version is not given explicitly."},"wave_start":{"type":"string","description":"Optional: first wave covered by this gate (documentation only, defaults to wave_end) — e.g. wave_start='wave-1' with wave_end='wave-3' covers waves 1-3 under one checkpoint."},"project_name":{"type":"string","description":"Project name — an alternative to project_id; resolved to the id internally. project_id wins if both are given."}}},"output_schema":null,"annotations":{"title":"Configure Wave Gate","readOnlyHint":false,"openWorldHint":false,"idempotentHint":false,"destructiveHint":false},"source":"probe","observed_at":"2026-09-29T06:40:02.225Z"},{"name":"create_experiment","title":"Create Experiment","description":"[SUPPORT] 3f6b8715 — W1-M Experiment Registry: create a named experiment (a research question; many runs belong to one). Reuses the pre-existing experiments table (4376e655) additively — config_template/created_by (an unrelated ML-style tracking interface's own columns) are left untouched. Persistent-state disclosure: on hosted Meridian, supplied text and project/session metadata -- including task log entries, pinned decisions, sprint items, notes, handoff/goal state, and HITL queue items -- are sent to and stored in Meridian's service, in an isolated per-tenant Postgres database (Neon); self-hosted deployments keep the same categories in the configured local SQLite/Postgres database. This data is visible in the dashboard and API, and may resurface in later project context or handoffs. Notes and pinned decisions can be deleted individually; task log entries and sprint items can be deleted via the dashboard/API (not exposed as an agent-facing tool); HITL queue items and handoff state have no per-record delete. Full removal of any of this data is available via project or account deletion, using the documented controls. Do not include secrets.","input_schema":{"type":"object","required":["name"],"properties":{"name":{"type":"string","description":"Bounded, non-empty experiment name."},"hypothesis":{"type":"string","description":"What this experiment is testing."},"project_id":{"type":"string"},"session_id":{"type":"string"},"project_name":{"type":"string","description":"Project name — an alternative to project_id; resolved to the id internally. project_id wins if both are given."}}},"output_schema":null,"annotations":{"title":"Create Experiment","readOnlyHint":false,"openWorldHint":false,"idempotentHint":false,"destructiveHint":false},"source":"probe","observed_at":"2026-09-29T06:40:02.225Z"},{"name":"create_project","title":"Create Project","description":"[MAINTENANCE] Create a new Meridian project. Persistent-state disclosure: on hosted Meridian, supplied text and project/session metadata -- including task log entries, pinned decisions, sprint items, notes, handoff/goal state, and HITL queue items -- are sent to and stored in Meridian's service, in an isolated per-tenant Postgres database (Neon); self-hosted deployments keep the same categories in the configured local SQLite/Postgres database. This data is visible in the dashboard and API, and may resurface in later project context or handoffs. Notes and pinned decisions can be deleted individually; task log entries and sprint items can be deleted via the dashboard/API (not exposed as an agent-facing tool); HITL queue items and handoff state have no per-record delete. Full removal of any of this data is available via project or account deletion, using the documented controls. Do not include secrets.","input_schema":{"type":"object","required":["name"],"properties":{"name":{"type":"string"},"execution_mode":{"enum":["autonomous","interactive"],"type":"string","description":"Executor posture for sessions on this project. 'autonomous' (default) claims and runs sprint items immediately without asking; 'interactive' asks for direction first. Editable later in dashboard Settings."},"parent_project_id":{"type":"string","description":"Optional parent project id — makes this a subproject that inherits the parent's north_star when it has none of its own. Subprojects are one level deep: the parent must exist and must not itself be a subproject."}}},"output_schema":null,"annotations":{"title":"Create Project","readOnlyHint":false,"openWorldHint":false,"idempotentHint":false,"destructiveHint":false},"source":"probe","observed_at":"2026-09-29T06:40:02.225Z"},{"name":"create_proposal_successor","title":"Create Proposal Successor","description":"[SUPPORT] Create a NEW, distinct proposal that is a version/successor of an existing one, linked to it by an explicit typed relation (supersedes/refines/forks/continues/duplicates/responds_to) — never by mutating the predecessor or overloading family_id/proposal_events (pinned decision 6aef812e). Inherits the predecessor's project scope (project-scoped stays project-scoped, workspace-global stays workspace-global) and family_id automatically. Idempotent: pass the same idempotency_key on a retry to get back the SAME successor rather than a second one — the underlying proposal creation AND the lineage edge are both independently idempotent. Returns {proposal, lineage, predecessor_id}. Persistent-state disclosure: on hosted Meridian, supplied text and project/session metadata -- including task log entries, pinned decisions, sprint items, notes, handoff/goal state, and HITL queue items -- are sent to and stored in Meridian's service, in an isolated per-tenant Postgres database (Neon); self-hosted deployments keep the same categories in the configured local SQLite/Postgres database. This data is visible in the dashboard and API, and may resurface in later project context or handoffs. Notes and pinned decisions can be deleted individually; task log entries and sprint items can be deleted via the dashboard/API (not exposed as an agent-facing tool); HITL queue items and handoff state have no per-record delete. Full removal of any of this data is available via project or account deletion, using the documented controls. Do not include secrets.","input_schema":{"type":"object","required":["proposal_id","title","body","relation_type"],"properties":{"body":{"type":"string","description":"Full description for the new successor proposal."},"tags":{"type":"string","description":"Optional comma-separated tags for the new proposal."},"actor":{"type":"string","description":"Optional actor identity recorded on the new proposal's events and on the lineage edge."},"label":{"type":"string","description":"Optional human-readable label stored on the lineage edge itself (not on either proposal)."},"title":{"type":"string","description":"Title for the new successor proposal."},"session_id":{"type":"string","description":"Optional caller session id, recorded on the new proposal's 'created' event."},"proposal_id":{"type":"string","description":"The PREDECESSOR proposal's id — the new proposal's relation_type points at this one."},"relation_type":{"enum":["supersedes","refines","forks","continues","duplicates","responds_to"],"type":"string","description":"How the new proposal relates to its predecessor."},"idempotency_key":{"type":"string","description":"Optional caller-supplied key; a retried call with the same key returns the original successor instead of creating a duplicate."}}},"output_schema":null,"annotations":{"title":"Create Proposal Successor","readOnlyHint":false,"openWorldHint":false,"idempotentHint":false,"destructiveHint":false},"source":"probe","observed_at":"2026-09-29T06:40:02.225Z"},{"name":"delete_custom_hook","title":"Delete Custom Hook","description":"[MAINTENANCE] 273287cb — delete a user-defined hook by id (the id returned by add_custom_hook / get_custom_hooks). Idempotent: deleting an already-gone hook returns {deleted:false} rather than erroring, matching delete_sprint_item_pointer's convention. Does NOT remove any already-written .claude/hooks/<slug>.* files — those are simply no longer refreshed on the next generate_handoff. Persistent-state disclosure: on hosted Meridian, supplied text and project/session metadata -- including task log entries, pinned decisions, sprint items, notes, handoff/goal state, and HITL queue items -- are sent to and stored in Meridian's service, in an isolated per-tenant Postgres database (Neon); self-hosted deployments keep the same categories in the configured local SQLite/Postgres database. This data is visible in the dashboard and API, and may resurface in later project context or handoffs. Notes and pinned decisions can be deleted individually; task log entries and sprint items can be deleted via the dashboard/API (not exposed as an agent-facing tool); HITL queue items and handoff state have no per-record delete. Full removal of any of this data is available via project or account deletion, using the documented controls. Do not include secrets.","input_schema":{"type":"object","required":["hook_id"],"properties":{"hook_id":{"type":"string","description":"The hook id to delete."},"project_id":{"type":"string"},"project_name":{"type":"string","description":"Project name — an alternative to project_id; resolved to the id internally. project_id wins if both are given."}}},"output_schema":null,"annotations":{"title":"Delete Custom Hook","readOnlyHint":false,"openWorldHint":false,"idempotentHint":false,"destructiveHint":true},"source":"probe","observed_at":"2026-09-29T06:40:02.225Z"},{"name":"delete_note","title":"Delete Note","description":"[MAINTENANCE] Hard-delete a project note by id. Persistent-state disclosure: on hosted Meridian, supplied text and project/session metadata -- including task log entries, pinned decisions, sprint items, notes, handoff/goal state, and HITL queue items -- are sent to and stored in Meridian's service, in an isolated per-tenant Postgres database (Neon); self-hosted deployments keep the same categories in the configured local SQLite/Postgres database. This data is visible in the dashboard and API, and may resurface in later project context or handoffs. Notes and pinned decisions can be deleted individually; task log entries and sprint items can be deleted via the dashboard/API (not exposed as an agent-facing tool); HITL queue items and handoff state have no per-record delete. Full removal of any of this data is available via project or account deletion, using the documented controls. Do not include secrets.","input_schema":{"type":"object","required":["note_id"],"properties":{"note_id":{"type":"string"}}},"output_schema":null,"annotations":{"title":"Delete Note","readOnlyHint":false,"openWorldHint":false,"idempotentHint":false,"destructiveHint":true},"source":"probe","observed_at":"2026-09-29T06:40:02.225Z"},{"name":"delete_sprint_item_pointer","title":"Delete Sprint Item Pointer","description":"[MAINTENANCE] 2976e168 — delete ONE generic pointer from a sprint item by its pointer id (the id returned by add_sprint_item_pointer / get_sprint_item_pointers). Idempotent: returns {pointer_id, deleted:false} when no pointer had that id, rather than erroring. To CHANGE a pointer's targets/source_type/label in place instead — preserving its id/created_at, and without the data-loss/visibility window a delete-then-re-add pair has — use relocate_sprint_item_pointer (W1-J); reserve this tool for when you actually want the pointer gone. Persistent-state disclosure: on hosted Meridian, supplied text and project/session metadata -- including task log entries, pinned decisions, sprint items, notes, handoff/goal state, and HITL queue items -- are sent to and stored in Meridian's service, in an isolated per-tenant Postgres database (Neon); self-hosted deployments keep the same categories in the configured local SQLite/Postgres database. This data is visible in the dashboard and API, and may resurface in later project context or handoffs. Notes and pinned decisions can be deleted individually; task log entries and sprint items can be deleted via the dashboard/API (not exposed as an agent-facing tool); HITL queue items and handoff state have no per-record delete. Full removal of any of this data is available via project or account deletion, using the documented controls. Do not include secrets.","input_schema":{"type":"object","required":["pointer_id"],"properties":{"pointer_id":{"type":"string","description":"The id of the pointer to delete."}}},"output_schema":null,"annotations":{"title":"Delete Sprint Item Pointer","readOnlyHint":false,"openWorldHint":false,"idempotentHint":false,"destructiveHint":true},"source":"probe","observed_at":"2026-09-29T06:40:02.225Z"},{"name":"delete_watchlist_query","title":"Delete Watchlist Query","description":"[SUPPORT] Delete a saved research watchlist query. Scoped to project_id + the watchlist tag, so it never deletes an unrelated note. Persistent-state disclosure: on hosted Meridian, supplied text and project/session metadata -- including task log entries, pinned decisions, sprint items, notes, handoff/goal state, and HITL queue items -- are sent to and stored in Meridian's service, in an isolated per-tenant Postgres database (Neon); self-hosted deployments keep the same categories in the configured local SQLite/Postgres database. This data is visible in the dashboard and API, and may resurface in later project context or handoffs. Notes and pinned decisions can be deleted individually; task log entries and sprint items can be deleted via the dashboard/API (not exposed as an agent-facing tool); HITL queue items and handoff state have no per-record delete. Full removal of any of this data is available via project or account deletion, using the documented controls. Do not include secrets.","input_schema":{"type":"object","required":["watchlist_id"],"properties":{"project_id":{"type":"string"},"project_name":{"type":"string","description":"Project name — an alternative to project_id; resolved to the id internally. project_id wins if both are given."},"watchlist_id":{"type":"string","description":"id returned by save_watchlist_query / list_watchlist_queries."}}},"output_schema":null,"annotations":{"title":"Delete Watchlist Query","readOnlyHint":false,"openWorldHint":false,"idempotentHint":false,"destructiveHint":false},"source":"probe","observed_at":"2026-09-29T06:40:02.225Z"},{"name":"dismiss_hitl","title":"Dismiss HITL","description":"[SUPPORT] Dismiss a HITL request (won't-answer / no longer relevant). Stays in audit trail. Use list_hitl_requests to find request IDs. Persistent-state disclosure: on hosted Meridian, supplied text and project/session metadata -- including task log entries, pinned decisions, sprint items, notes, handoff/goal state, and HITL queue items -- are sent to and stored in Meridian's service, in an isolated per-tenant Postgres database (Neon); self-hosted deployments keep the same categories in the configured local SQLite/Postgres database. This data is visible in the dashboard and API, and may resurface in later project context or handoffs. Notes and pinned decisions can be deleted individually; task log entries and sprint items can be deleted via the dashboard/API (not exposed as an agent-facing tool); HITL queue items and handoff state have no per-record delete. Full removal of any of this data is available via project or account deletion, using the documented controls. Do not include secrets.","input_schema":{"type":"object","required":["request_id"],"properties":{"request_id":{"type":"string"}}},"output_schema":null,"annotations":{"title":"Dismiss HITL","readOnlyHint":false,"openWorldHint":false,"idempotentHint":false,"destructiveHint":true},"source":"probe","observed_at":"2026-09-29T06:40:02.225Z"},{"name":"execute_batch","title":"Execute Batch","description":"[SUPPORT] 627187b8 — run a HOMOGENEOUS batch of management writes (all entries the SAME operation) with real atomic-or-independent semantics. Every entry in ``entries`` is validated and reported individually — no guessing whether a partial write happened. operation selects the entry shape:\n• sprint_items — create new sprint items. Each entry needs a non-empty 'title' plus any add_sprint_item kwarg (version, group, human_id, depends_on, priority, touches_resources, ...). Every entry's own 'action' (if present) must be 'create'.\n• item_updates — patch existing sprint items. Each entry needs a non-empty 'item_id' plus at least one patch_sprint_item field to change (title, status, notes, priority, ...). Every entry's own 'action' (if present) must be 'update'.\n• pointers — attach generic pointers (see add_sprint_item_pointer). Each entry needs 'sprint_item_id', 'source_type', 'targets' (+ optional 'label').\n• notes — file sprint notes (see add_sprint_note). Each entry needs 'title' and 'body' (+ optional 'session_id' — falls back to this call's own top-level session_id when omitted — and 'note_kind').\nAny entry MAY carry a 'correlation_key' (any non-empty string) echoed back on its result for reconciliation; every result also carries its 0-based input 'index' regardless.\nmode is REQUIRED and controls failure semantics: 'all_or_nothing' validates every entry BEFORE mutating anything — if any entry fails validation, NOTHING is written (status 'rejected'); if a mutation fails partway through, every entry this call already wrote is rolled back via a compensating delete/revert (status 'failed'). 'best_effort' processes each entry independently — one entry's failure never blocks the others (status 'ok' | 'partial' | 'failed' depending on how many succeeded).\nidempotency_key is REQUIRED (pass null or \"\" to explicitly opt out of idempotency protection for this call) — a retried call with the identical (project_id, operation, idempotency_key) tuple returns the FIRST call's stored result verbatim (idempotent_replay:true) instead of re-executing, making retries safe even for all_or_nothing batches that already wrote and rolled back once.\nReturns {status, mode, entry_kind, operation, project_id, idempotency_key, idempotent_replay, created_count, error_count, results:[{index, correlation_key, status, id, outcome, error_code, error_message, retryable}]} — results is ALWAYS in input order regardless of processing order. Each result status is 'ok' (mutated), 'error' (validation or mutation failure — see error_code/error_message/retryable), 'rolled_back' (succeeded, then undone by a later all_or_nothing failure), or 'not_attempted' (never reached because an earlier entry aborted the batch). max_entries caps this call (default 100); exceeding it is rejected before anything is attempted. Persistent-state disclosure: on hosted Meridian, supplied text and project/session metadata -- including task log entries, pinned decisions, sprint items, notes, handoff/goal state, and HITL queue items -- are sent to and stored in Meridian's service, in an isolated per-tenant Postgres database (Neon); self-hosted deployments keep the same categories in the configured local SQLite/Postgres database. This data is visible in the dashboard and API, and may resurface in later project context or handoffs. Notes and pinned decisions can be deleted individually; task log entries and sprint items can be deleted via the dashboard/API (not exposed as an agent-facing tool); HITL queue items and handoff state have no per-record delete. Full removal of any of this data is available via project or account deletion, using the documented controls. Do not include secrets.","input_schema":{"type":"object","required":["operation","entries","mode","idempotency_key"],"properties":{"mode":{"enum":["all_or_nothing","best_effort"],"type":"string","description":"REQUIRED — no default. 'all_or_nothing': validate-then-mutate with compensating rollback on any mutation failure. 'best_effort': every entry processed independently."},"entries":{"type":"array","items":{"type":"object"},"description":"Non-empty list of entry objects, ALL matching the chosen operation's shape. Each entry may carry an optional 'correlation_key' string echoed back on its result."},"operation":{"enum":["sprint_items","item_updates","pointers","notes"],"type":"string","description":"Stable operation name selecting the entry shape and forced per-entry action (sprint_items=create, item_updates=update). See the tool description for each shape."},"project_id":{"type":"string"},"session_id":{"type":"string","description":"Batch-level default session_id used by 'notes' entries that omit their own session_id."},"max_entries":{"type":"integer","description":"Optional cap on len(entries) for this call (default 100). Exceeding it rejects the whole call before anything is attempted."},"project_name":{"type":"string","description":"Project name — an alternative to project_id; resolved to the id internally. project_id wins if both are given."},"idempotency_key":{"type":"string","description":"REQUIRED key (value may be null or \"\" to explicitly opt out). A retried call with the same (project_id, operation, idempotency_key) replays the first call's stored result instead of re-executing."}}},"output_schema":null,"annotations":{"title":"Execute Batch","readOnlyHint":false,"openWorldHint":false,"idempotentHint":false,"destructiveHint":false},"source":"probe","observed_at":"2026-09-29T06:40:02.225Z"},{"name":"export_ai_log","title":"Export AI Log","description":"[MAINTENANCE] c0168425 — Read-only: project-scoped, receipted export of ai_log_events (meridian.db.ai_log — the append-only ExecutionEvent log). Nothing captures events into this table automatically yet (see meridian.ai_log's module docstring); this exports whatever has been recorded via append_event so far. Filter with session_id/event_type/correlation_id/parent_event_id exactly like list_events. limit defaults to 5000 and is capped at 5000 — the response's truncated field is true when more matching rows exist than were returned. Returns {project_id, exported_at, filters, event_count, truncated, events, export_hash} — export_hash is a sha256 over the exported events so a caller can independently verify nothing was altered in transit.","input_schema":{"type":"object","required":[],"properties":{"limit":{"type":"integer","description":"Default/max 5000."},"event_type":{"type":"string"},"project_id":{"type":"string"},"session_id":{"type":"string"},"project_name":{"type":"string","description":"Project name — an alternative to project_id; resolved to the id internally. project_id wins if both are given."},"correlation_id":{"type":"string"},"parent_event_id":{"type":"string"}}},"output_schema":null,"annotations":{"title":"Export AI Log","readOnlyHint":true,"openWorldHint":false,"idempotentHint":true,"destructiveHint":false},"source":"probe","observed_at":"2026-09-29T06:40:02.225Z"},{"name":"export_ai_log_artifacts","title":"Export AI Log Artifacts","description":"[MAINTENANCE] c0168425 — Read-only: project-scoped, receipted export of stored ai_log artifacts (meridian.artifact_store — the local-first, content-addressed blob store an ExecutionEvent payload can point to via artifact_ref instead of inlining large content). Pass content_hashes to export an explicit subset (sha256:... values) — every requested hash must exist for this project, or the call errors rather than silently returning a shorter list; omit it to export every artifact currently stored for the project. Returns {project_id, exported_at, artifact_count, total_size, artifacts, export_hash} — each artifact entry includes its metadata plus base64-encoded content. export_hash covers the metadata only (not the base64 payloads) so it stays cheap to verify.","input_schema":{"type":"object","required":[],"properties":{"project_id":{"type":"string"},"project_name":{"type":"string","description":"Project name — an alternative to project_id; resolved to the id internally. project_id wins if both are given."},"content_hashes":{"type":"array","items":{"type":"string"},"description":"Explicit subset of 'sha256:...' hashes to export. Omit to export every artifact stored for the project."}}},"output_schema":null,"annotations":{"title":"Export AI Log Artifacts","readOnlyHint":true,"openWorldHint":false,"idempotentHint":true,"destructiveHint":false},"source":"probe","observed_at":"2026-09-29T06:40:02.225Z"},{"name":"export_ai_log_otel","title":"Export AI Log to OTel","description":"[MAINTENANCE] R2-G — Run ONE bounded export pass of new ai_log_events to the configured OTel/Langfuse-compatible OTLP endpoint for a project, resuming from the durable watermark left by the previous pass. Always safe to call: returns {\"status\": \"disabled\"} immediately if MERIDIAN_AI_LOG_OTEL_ENABLED (or this project's own override) is off, {\"status\": \"unavailable\"} if the optional opentelemetry client library isn't installed or no endpoint is configured, {\"status\": \"idle\"} if there is nothing new to export, {\"status\": \"sent\"} on full success, {\"status\": \"degraded\"} if part of the batch sent before a chunk exhausted its bounded retries (the watermark still advanced past every chunk that DID send — no silent gaps), or {\"status\": \"sync_failed\"}/{\"status\": \"error\"} if nothing sent this pass. NEVER raises, never blocks the caller longer than a bounded overall deadline, and never mutates or deletes any ai_log_events row — Meridian's own DB stays authoritative regardless of outcome. Returns {project_id, status, sent_count, batch_size, reason}. Persistent-state disclosure: on hosted Meridian, supplied text and project/session metadata -- including task log entries, pinned decisions, sprint items, notes, handoff/goal state, and HITL queue items -- are sent to and stored in Meridian's service, in an isolated per-tenant Postgres database (Neon); self-hosted deployments keep the same categories in the configured local SQLite/Postgres database. This data is visible in the dashboard and API, and may resurface in later project context or handoffs. Notes and pinned decisions can be deleted individually; task log entries and sprint items can be deleted via the dashboard/API (not exposed as an agent-facing tool); HITL queue items and handoff state have no per-record delete. Full removal of any of this data is available via project or account deletion, using the documented controls. Do not include secrets.","input_schema":{"type":"object","required":[],"properties":{"batch_size":{"type":"integer","description":"Max events to fetch this pass. Default from MERIDIAN_AI_LOG_OTEL_BATCH_SIZE (200), hard-capped at 1000."},"project_id":{"type":"string"},"project_name":{"type":"string","description":"Project name — an alternative to project_id; resolved to the id internally. project_id wins if both are given."}}},"output_schema":null,"annotations":{"title":"Export AI Log to OTel","readOnlyHint":false,"openWorldHint":true,"idempotentHint":false,"destructiveHint":false},"source":"probe","observed_at":"2026-09-29T06:40:02.225Z"},{"name":"fan_out_sprint_items","title":"Fan Out Sprint Items","description":"[SUPPORT] Bulk-insert sprint items from a single orchestrator call — decompose a goal into parallel work items without N sequential add_sprint_item calls. Pass a list of {title, description?, group?, version?} dicts; returns the list of new item_ids in insertion order. By DEFAULT (strict omitted/false) no duplicate guard is applied (the caller is assumed to have deduped) and titles that resolve to an empty string are silently skipped — unchanged, original behavior, kept for compatibility.\n468ab67d — pass strict=true to opt into the SAME shared engine execute_batch uses (meridian.db.batch_management, add_sprint_item-backed): the 60%-word-overlap duplicate guard applies (per-item force:true still overrides it), idempotency_key makes a retried call with the same key replay the first call's result instead of re-inserting, and mode picks all_or_nothing (validate-then-insert with compensating rollback on failure, default) or best_effort (each item processed independently). In strict mode the response is the execute_batch response shape ({status, mode, entry_kind, project_id, idempotency_key, idempotent_replay, created_count, error_count, results:[{index, correlation_key, status, id, outcome, error_code, error_message, retryable}]}) PLUS the usual item_ids/count keys — a different, richer shape than the legacy bare item_ids/count, by design (a new opt-in contract, not a silent change to the old one). Each item may carry its own correlation_key (echoed back on its strict-mode result) and force (per-item duplicate-guard override, strict mode only). Persistent-state disclosure: on hosted Meridian, supplied text and project/session metadata -- including task log entries, pinned decisions, sprint items, notes, handoff/goal state, and HITL queue items -- are sent to and stored in Meridian's service, in an isolated per-tenant Postgres database (Neon); self-hosted deployments keep the same categories in the configured local SQLite/Postgres database. This data is visible in the dashboard and API, and may resurface in later project context or handoffs. Notes and pinned decisions can be deleted individually; task log entries and sprint items can be deleted via the dashboard/API (not exposed as an agent-facing tool); HITL queue items and handoff state have no per-record delete. Full removal of any of this data is available via project or account deletion, using the documented controls. Do not include secrets.","input_schema":{"type":"object","required":["items"],"properties":{"mode":{"enum":["all_or_nothing","best_effort"],"type":"string","description":"strict mode only — default 'all_or_nothing'. Ignored unless strict=true."},"items":{"type":"array","items":{"type":"object","required":["title"],"properties":{"force":{"type":"boolean","description":"strict mode only — override the duplicate-title guard for this item (same meaning as add_sprint_item's own force). Ignored in legacy (non-strict) mode, which never applies the guard at all."},"group":{"type":"string","description":"Optional objective group name."},"title":{"type":"string","description":"Sprint item title (required)."},"version":{"type":"string","description":"Optional sprint-version bucket; defaults to empty string."},"description":{"type":"string","description":"Optional notes / detail for the item."},"correlation_key":{"type":"string","description":"strict mode only — an arbitrary caller-chosen id echoed back on this item's result for reconciliation. Ignored in legacy mode."},"touches_resources":{"type":"array","items":{"type":"string"},"description":"Optional typed resource identifiers (file:/symbol:/db:/mcp_tool:/route:/pypi:/github:) for parallel conflict detection. For SYMBOL-LEVEL granularity use 'symbol:path.py::func' (double colon) so items editing different symbols in the same file co-batch in parallel; a single-colon 'file:path.py:func' suffix is treated as the whole file."}}},"description":"List of sprint item specs. Each must have at least a 'title'."},"strict":{"type":"boolean","description":"468ab67d — default false (legacy: no duplicate guard, bare item_ids/count response). Pass true to opt into the shared batch_management engine's duplicate guard + idempotency-key replay + mode semantics — see the tool description."},"project_id":{"type":"string"},"project_name":{"type":"string","description":"Project name — an alternative to project_id; resolved to the id internally. project_id wins if both are given."},"idempotency_key":{"type":"string","description":"strict mode only — a retried call with the same (project_id, idempotency_key) replays the first call's stored result instead of re-inserting. Ignored unless strict=true."}}},"output_schema":null,"annotations":{"title":"Fan Out Sprint Items","readOnlyHint":false,"openWorldHint":false,"idempotentHint":false,"destructiveHint":false},"source":"probe","observed_at":"2026-09-29T06:40:02.225Z"},{"name":"finalize_wave_run","title":"Finalize Wave Run","description":"[SUPPORT] 2a654cb0 — IDEMPOTENT FINALIZATION: close a wave run opened by start_wave_run. Safe to retry: if the run is already merged this returns the ORIGINAL result with already_finalized=true, writes no row and appends no event (event_count is identical across the retry — that is the observable proof). Fails CLOSED in three cases: (1) a failure_mode='stop' child has failed — returns {finalized: false, blocked_by: [...]} naming the items; (2) expected_revision_hash does not match the board the run was planned against — you are holding a stale manifest, re-read the board first; (3) evidence is not a genuine run_verification result (status='ok', exit_code=0) — the SAME evidence contract complete_wave_gate enforces; a self-report is rejected. Returns {finalized, already_finalized, wave_run_id, status, finalized_at, finalizer_evidence, children_summary, event_count}. Persistent-state disclosure: on hosted Meridian, supplied text and project/session metadata -- including task log entries, pinned decisions, sprint items, notes, handoff/goal state, and HITL queue items -- are sent to and stored in Meridian's service, in an isolated per-tenant Postgres database (Neon); self-hosted deployments keep the same categories in the configured local SQLite/Postgres database. This data is visible in the dashboard and API, and may resurface in later project context or handoffs. Notes and pinned decisions can be deleted individually; task log entries and sprint items can be deleted via the dashboard/API (not exposed as an agent-facing tool); HITL queue items and handoff state have no per-record delete. Full removal of any of this data is available via project or account deletion, using the documented controls. Do not include secrets.","input_schema":{"type":"object","required":["wave_run_id"],"properties":{"actor":{"type":"string","description":"Optional session_id or actor name recorded as finalizing the run."},"evidence":{"type":"object","description":"The FULL dict returned by run_verification. Must have status='ok' and exit_code=0. Not required when replaying an already-finalized run."},"wave_run_id":{"type":"string","description":"The immutable id returned by start_wave_run."},"expected_revision_hash":{"type":"string","description":"Optional staleness gate: the board revision_hash you believe this run was planned against. A mismatch refuses the finalization instead of merging against unseen state."}}},"output_schema":null,"annotations":{"title":"Finalize Wave Run","readOnlyHint":false,"openWorldHint":false,"idempotentHint":false,"destructiveHint":false},"source":"probe","observed_at":"2026-09-29T06:40:02.225Z"},{"name":"find_orphaned_docx_staged_files","title":"Find Orphaned Docx Staged Files","description":"[MAINTENANCE] 6507e83a — Maintenance diagnostic: detect staged-DOCX temp files (.meridian-docx-stage-*.tmp) left behind by a process that crashed between STAGE and PROMOTE inside meridian.doc_store's write transaction. Purely a detection utility — never deletes or touches anything it finds. Returns a list of {path, size_bytes, age_seconds, likely_orphan}, oldest first. A file younger than max_age_seconds is reported but not flagged likely_orphan (it may be an active, in-flight promotion). Persistent-state disclosure: on hosted Meridian, supplied text and project/session metadata -- including task log entries, pinned decisions, sprint items, notes, handoff/goal state, and HITL queue items -- are sent to and stored in Meridian's service, in an isolated per-tenant Postgres database (Neon); self-hosted deployments keep the same categories in the configured local SQLite/Postgres database. This data is visible in the dashboard and API, and may resurface in later project context or handoffs. Notes and pinned decisions can be deleted individually; task log entries and sprint items can be deleted via the dashboard/API (not exposed as an agent-facing tool); HITL queue items and handoff state have no per-record delete. Full removal of any of this data is available via project or account deletion, using the documented controls. Do not include secrets.","input_schema":{"type":"object","required":["directory"],"properties":{"directory":{"type":"string","description":"Directory to scan (typically a .docx's own parent directory)."},"max_age_seconds":{"type":"number","description":"Age threshold in seconds for likely_orphan=true. Default 3600 (1 hour)."}}},"output_schema":null,"annotations":{"title":"Find Orphaned Docx Staged Files","readOnlyHint":false,"openWorldHint":false,"idempotentHint":false,"destructiveHint":false},"source":"probe","observed_at":"2026-09-29T06:40:02.225Z"},{"name":"find_outputs_by_source","title":"Find Outputs By Source","description":"[SUPPORT] 2ae25966 — READ-ONLY reverse provenance lookup over a run's OUTPUTS tree: the mirror image of resolve_figure_output's forward direction (figure -> source). Given a script or data file's source_path, scans the same local DuckDB outputs index search_outputs/annotate_outputs use for every indexed output whose recorded generating_script traces back to it — an exact (case/slash-insensitive) string match OR a basename match, so 'analysis/run.py' also matches an output recorded with generating_script='run.py'. This is the direction plain exact-path resolution can never answer, because that always starts from the output side: 'what did this script/data file produce?' — useful for auditing a stale Outputs_*_BACKUP folder mess by walking a source file's outputs forward, newest first, and comparing against what a document actually cites. Returns {outputs_dir, source_path, outputs:[{path, generating_script, is_archival, canonical_path, sha256, kind, size, mtime, csv_columns, json_keys}], total} sorted newest-first by mtime; total is the full match count before limit truncation. outputs is empty (not an error) when nothing in the tree cites this source, or when outputs_dir doesn't exist.","input_schema":{"type":"object","required":["outputs_dir","source_path"],"properties":{"limit":{"type":"integer","description":"Max matched outputs to return, newest-first by mtime (default 25)."},"outputs_dir":{"type":"string","description":"Absolute path to the outputs directory tree to index and search (same value you pass to search_outputs)."},"source_path":{"type":"string","description":"The generating script or data file to trace forward from (e.g. 'analysis/run.py') — matched against each indexed output's recorded generating_script."}}},"output_schema":null,"annotations":{"title":"Find Outputs By Source","readOnlyHint":true,"openWorldHint":false,"idempotentHint":true,"destructiveHint":false},"source":"probe","observed_at":"2026-09-29T06:40:02.225Z"},{"name":"find_similar_equation","title":"Find Similar Equation","description":"[MAINTENANCE] 06df6ab3 — fuzzy-match a LaTeX string against every equation already indexed (via index_equation) for one stored document, best match first. Each result carries the stored equation row PLUS a difflib similarity score (0..1) against its latex_normalized. Useful before index_equation to check whether an equation is already present under a slightly different LaTeX spelling. Returns {document_id, matches:[...]} — an empty list (never an error) when the document has no stored equations, or doc doesn't resolve to a stored document.","input_schema":{"type":"object","required":["doc","latex"],"properties":{"doc":{"type":"string","description":"The stored document's source (the path/URL you ingested it under via ingest_document, which registers a docx/latex document in the doc-structure store)."},"latex":{"type":"string","description":"LaTeX source to fuzzy-match against this document's stored equations."},"limit":{"type":"integer","description":"Max matches to return (default 5)."},"project_id":{"type":"string"},"project_name":{"type":"string","description":"Project name — an alternative to project_id; resolved to the id internally. project_id wins if both are given."}}},"output_schema":null,"annotations":{"title":"Find Similar Equation","readOnlyHint":true,"openWorldHint":false,"idempotentHint":true,"destructiveHint":false},"source":"probe","observed_at":"2026-09-29T06:40:02.225Z"},{"name":"find_similar_figure","title":"Find Similar Figure","description":"[MAINTENANCE] c623e648 — fuzzy-match a free-text description OR a file path against every figure already indexed (index_figure) for one stored document, best match first. Each result carries the stored figure row PLUS a difflib similarity score (0..1) — the better of the match against its normalized_caption and against its file_path. Useful before index_figure to check whether a figure is already present under a slightly different caption or path. Returns {document_id, matches:[...]} — an empty list (never an error) when the document has no indexed figures, or doc doesn't resolve to a stored document. d2a3537a — pass outputs_dir to RESOLVE THROUGH to the outputs index: every matched figure with a file_path that names an already-indexed run output gains a linked_output field (the output's path, generating_script, canonical/archival flag, fingerprint), so 'does this plot already exist as a run output?' and 'where is it referenced in my thesis?' are one lookup (linked_output is null when the figure names no indexed output).","input_schema":{"type":"object","required":["doc","description_or_path"],"properties":{"doc":{"type":"string","description":"The stored document's source (the path/URL you ingested it under via ingest_document, which registers a docx/latex document in the doc-structure store)."},"limit":{"type":"integer","description":"Max matches to return (default 5)."},"project_id":{"type":"string"},"outputs_dir":{"type":"string","description":"d2a3537a — optional outputs tree root. When given, each matched figure resolves THROUGH to its outputs_index row (linked_output) by file_path. Omit for a pure fuzzy match."},"project_name":{"type":"string","description":"Project name — an alternative to project_id; resolved to the id internally. project_id wins if both are given."},"description_or_path":{"type":"string","description":"A free-text description OR a file path to fuzzy-match against this document's indexed figures."}}},"output_schema":null,"annotations":{"title":"Find Similar Figure","readOnlyHint":true,"openWorldHint":false,"idempotentHint":true,"destructiveHint":false},"source":"probe","observed_at":"2026-09-29T06:40:02.225Z"},{"name":"find_similar_table","title":"Find Similar Table","description":"[MAINTENANCE] 2622182d — fuzzy-match a free-text description against every table already indexed (index_table) for one stored document, best match first. Each result carries the stored table row PLUS a difflib similarity score (0..1) against its normalized_caption. Useful before index_table to check whether a table is already present under a slightly different caption. Returns {document_id, matches:[...]} — an empty list (never an error) when the document has no indexed tables, or doc doesn't resolve to a stored document.","input_schema":{"type":"object","required":["doc","description"],"properties":{"doc":{"type":"string","description":"The stored document's source (the path/URL you ingested it under via ingest_document, which registers a docx/latex document in the doc-structure store)."},"limit":{"type":"integer","description":"Max matches to return (default 5)."},"project_id":{"type":"string"},"description":{"type":"string","description":"A free-text description to fuzzy-match against this document's indexed tables."},"project_name":{"type":"string","description":"Project name — an alternative to project_id; resolved to the id internally. project_id wins if both are given."}}},"output_schema":null,"annotations":{"title":"Find Similar Table","readOnlyHint":true,"openWorldHint":false,"idempotentHint":true,"destructiveHint":false},"source":"probe","observed_at":"2026-09-29T06:40:02.225Z"},{"name":"find_symbol_usages","title":"Find Symbol Usages","description":"[MAINTENANCE] 9605edb0 — READ-ONLY cross-reference tracking: given a document and EITHER a doc_equations row id OR a symbol / normalized-LaTeX string, resolve it to ONE target normalized-LaTeX (an equation id uses that row's stored latex_normalized as-is; a raw string is normalized with the SAME normalize_latex that produced every stored latex_normalized) and return every place that target reappears in the document — matching equations (exact normalized-latex equality) AND paragraphs whose text textually contains the symbol. Each hit carries element_id, document_id, ordinal, matched_text, context (equation|paragraph) and an is_definition/is_reuse flag: the EARLIEST occurrence by ordinal is the definition, later ones are reuse — so a later mention can be checked to point back to the definition instead of assuming the reader remembers it. Hits are ordered by ordinal (definition first). Returns {document_id, target, resolved_from, hits:[...]} — an empty hits list (never an error) when nothing matches, or doc doesn't resolve to a stored document.","input_schema":{"type":"object","required":["doc","symbol_or_equation_id"],"properties":{"doc":{"type":"string","description":"The stored document's source (the path/URL you ingested it under via ingest_document, which registers a docx/latex document in the doc-structure store)."},"project_id":{"type":"string"},"project_name":{"type":"string","description":"Project name — an alternative to project_id; resolved to the id internally. project_id wins if both are given."},"symbol_or_equation_id":{"type":"string","description":"A doc_equations row id, OR a raw symbol / normalized-LaTeX string to track (e.g. 'E=mc^2' or '\\\\sigma')."}}},"output_schema":null,"annotations":{"title":"Find Symbol Usages","readOnlyHint":true,"openWorldHint":false,"idempotentHint":true,"destructiveHint":false},"source":"probe","observed_at":"2026-09-29T06:40:02.225Z"},{"name":"generate_handoff","title":"Generate Handoff","description":"EXECUTOR SESSIONS: MANDATORY - call at end of every session before disconnect. Never write markdown manually. Read-only: Generate a context handoff. mode='full' writes the complete L0/L1/L2 handoff; mode='delta' returns a compact session update (completed + pending + /goal); mode='starter' returns a <=20-line block for paste-after-/compact or cold start - project_id, start_session command, last 5 completed titles, top 3 pending IDs, /goal; mode='planner' returns strategic context for a claude.ai planning chat; mode='goal' (682005f4) returns ONLY the bare /goal block itself - no readiness header, no workspace decisions/notes, no L0/L1/L2 context - with each pending item's resolved code pointer(s), if any, rendered inline in <sprint_items>. FORWARD THE RETURNED content FIELD VERBATIM to the user (a5e8aa74) - the server delivers content as the EXACT raw handoff text, with NO Markdown code fence, header, or blockquote added around it (earlier versions wrapped it in a 4-backtick fence under 5234877f; that wrapping was removed because it broke copy-paste fidelity for the /goal trust protocol - see format_handoff_mcp_content in meridian/handoff.py). Output the field value as-is, as the sole plain-text bubble - do NOT add your own fence, header, blockquote, or any other wrapping on the calling side either. Do NOT just narrate that the handoff succeeded; paste the actual text. Also returns capability_contract (98aaccf4) on every mode: a machine-readable {requested, effective, availability, manifest_hash, executable, executable_reasons, generated_at} object describing the project's declared capabilities and whether an executor can run right now — null if contract-building failed. It also carries per-pending-item enrichment sections (item_tool_requirements, item_sprint_item_pointers, item_artifact_pointer_findings, item_executor_contracts, item_routing_summary) — each capped (537a7cef) to the first 15 items by id, with a sibling item_<section>_truncated {truncated, total_candidates, included} marker reporting the real count when a board exceeds that; the requested/effective capability lists are separately capped past 50 entries the same way. A capped section never drops data silently — the full detail for an omitted item is still reachable via a follow-up generate_handoff(mode='full') call. Every executor-facing /goal payload also includes an explicit <executor_item_ids> manifest containing every claimable item ID in deterministic order; receivers must use that manifest rather than parsing presentation prose or a truncated starter preview. Also returns scope (b8f89491) on every mode: {requested_version, effective_version, session_id} — which sprint-version bucket the handoff actually resolved to (explicit version arg wins over the session's own stored sprint_version; both null means genuinely unscoped, every version). Every mode's /goal text (full/delta/starter/goal, embedded in content or returned bare) also carries a structured <execution_policy execution_mode=... max_planning_turns=... required_first_action=... no_confirmation=... permitted_parallel_wave=... claim_before_edit=...> tag (75ac1c8e) right after <executor_directive> — the SAME canonical policy start_session's execution_policy field returns, so a receiver can identify the required first action from the tag attributes without interpreting prose. Also returns handoff_evidence_status (8a883f60) on every mode: an explicit {code_pointer_enrichment, resolved_pointer_annotation, freshness_requery, wave_gate_exclusion, graph_search_availability} object — each a {status: verified|skipped|failed|degraded, reason, fallback} entry for that best-effort step, so a silently-degraded handoff is never indistinguishable from a fully-verified one. Pass strict_evidence=true to fail CLOSED instead: if any capability comes back failed/degraded, nothing is rendered or persisted and the call returns {error: HANDOFF_EVIDENCE_BLOCKED, evidence_status, evidence_errors, message} — default (strict_evidence omitted/false) behavior is completely unchanged. Also returns continuation_status (ecc8b280) for full/delta modes: a {continuation_required, terminal_ready, execution_mode, actionable_count, actionable_pending_count, actionable_in_progress_count, actionable_item_ids, blocked_count, blocked_item_ids, reason} object reporting whether actionable pending/in_progress work remains on the live, version-scoped board with no recorded blocker_kind, while execution_mode=autonomous — the machine-readable signal that an autonomous session may NOT yet treat itself as finished. Pass checkpoint=true when THIS call is a mid-run progress report, not a final session-ending handoff — a checkpoint is never blocked by the gate below. Pass strict_continuation=true to fail CLOSED instead of just reporting: if continuation_required is true and checkpoint is not set, nothing is rendered or persisted and the call returns {error: HANDOFF_CONTINUATION_BLOCKED, continuation_status, message} — resolve/claim the remaining item(s), record a genuine blocker_kind on them, or call again with checkpoint=true. Default (strict_continuation omitted/false) behavior never blocks — continuation_status is still always returned so a caller can act on it voluntarily. Also supports selected_item_ids (cffb9323) — an explicit INCLUDE-ONLY item scope for safe parallel-follow-up handoffs. force_include_ids only ever WIDENS the pending list (re-adds specific deferred ids); selected_item_ids NARROWS it: when given, generate_handoff resolves a dependency-closed scope (the requested ids plus any transitively-required depends_on ancestor still todo/pending) and applies it identically across every executable mode (full/delta/starter/goal), so an isolated two-item follow-up handoff never emits the rest of the eligible version backlog or overlaps an active wave/batch a sibling session already owns. The rendered /goal carries a <selected_item_scope requested=... closure=... closure_hash=...> tag stating the exact selected ids and the wave plan — embedded in the body BEFORE the provenance token is minted, so the selection is bound into the SAME body-hash/token-integrity mechanism (efaa918a) as the rest of the /goal block. Fails CLOSED, not silently widened: a missing/foreign/wrong-version/already-in_progress/otherwise-non-pending requested id raises a structured refusal (error=HANDOFF_SELECTION_BLOCKED, selection_rejected) — nothing is rendered or persisted for that call. (7a373f41) A selection that validates cleanly but collapses to zero executable items once the manual/backburner/unprospected/wave-gate exclusion filters run instead refuses with error=HANDOFF_SCOPE_NON_EXECUTABLE, requested_ids, and an excluded_requested reason list — this same contract is identical across every connector surface (hosted HTTP MCP, stdio, and the REST /handoff route). Persistent-state disclosure: on hosted Meridian, supplied text and project/session metadata -- including task log entries, pinned decisions, sprint items, notes, handoff/goal state, and HITL queue items -- are sent to and stored in Meridian's service, in an isolated per-tenant Postgres database (Neon); self-hosted deployments keep the same categories in the configured local SQLite/Postgres database. This data is visible in the dashboard and API, and may resurface in later project context or handoffs. Notes and pinned decisions can be deleted individually; task log entries and sprint items can be deleted via the dashboard/API (not exposed as an agent-facing tool); HITL queue items and handoff state have no per-record delete. Full removal of any of this data is available via project or account deletion, using the documented controls. Do not include secrets.","input_schema":{"type":"object","required":[],"properties":{"mode":{"enum":["full","delta","planner","starter","goal"],"type":"string","description":"(aec043cb) Optional — omitting mode is now INTENT-BASED, never a silent 'full'. Omission resolves to: 'delta' if session_id already produced a handoff this session (resumed/continuation); else 'goal' if session_id was started with role='executor'; else 'planner' if role='planner'; else 'goal' (the safe, bounded default — no workspace decisions/notes, no other project's state) when intent can't otherwise be determined. 'full' — the unbounded, whole-workspace archival/diagnostic dump, including cross-project workspace decisions/notes — is now returned ONLY for an explicit mode='full' request, never for an omitted one. (d2fc7465) Persistence differs by mode too, and is now explicit on the response: only 'full'/'delta'/'goal' write to the `handoffs` history table and the trusted pending_goal channel load_handoff() reads back — 'planner'/'starter'/'compact' are call-and-forget renders meant to be pasted directly, never the canonical stored handoff. The response's `retrievable_via_load_handoff` field states this per-call rather than requiring a caller to infer it from mode name."},"version":{"type":"string","description":"(b8f89491) Optional explicit sprint-version bucket (e.g. 'v0.2.6') to scope this handoff to — applies to every mode (full/delta/starter/compact/goal), not just starter. Wins over the calling session's own stored sprint_version. Omit to fall back to session_id's scope, or to the whole project's cross-version backlog when neither is set."},"root_dir":{"type":"string","description":"Optional request-local absolute source-tree root used by live pointer resolution's local semantic fallback when no code tunnel is available. Never persisted."},"checkpoint":{"type":"boolean","description":"(ecc8b280) Mark THIS call as a mid-run progress report rather than a final, session-ending handoff. Applies to full/delta modes only. A checkpoint=true call is never refused by strict_continuation below, regardless of how much actionable work remains — it changes nothing about what gets rendered, only whether the continuation gate can engage."},"project_id":{"type":"string"},"session_id":{"type":"string","description":"Optional session id for auto-delta on repeated calls in the same session."},"project_name":{"type":"string","description":"Project name — an alternative to project_id; resolved to the id internally. project_id wins if both are given."},"emit_manifest":{"type":"boolean","description":"(acf6f51a) Opt-in, off by default. mode='goal' only (for now): when true, embeds a canonical <handoff_manifest> XML block — schema_version, board_revision (a deterministic digest of every item's id/status/depends_on), project/tenant origin identity, generated_at, the selected/closure item ids, the full item id/status/depends_on/resources list, and the wave plan — into the rendered /goal text BEFORE the goal token is minted, so verify_handoff_token's existing body_hash check also covers the manifest; no separate verification path. A receiver re-fetches the live board and compares against board_revision (see handoff.verify_board_revision) to detect drift before acting. Other modes are unaffected by this flag for now."},"skip_ai_summary":{"type":"boolean","description":"65c8b426 — skip the optional AI (Haiku) narrative calls (session summaries, ai_summary blurb, sprint retrospective). Default true on the MCP path for fast, reliable handoffs. Pass false to include AI-generated narrative sugar when you have budget and time."},"strict_evidence":{"type":"boolean","description":"(8a883f60) Opt-in, off by default — mirrors complete_sprint_item's strict_evidence shape exactly. When true, a failed/degraded pointer-enrichment/freshness/wave-gate/graph-search capability makes this call refuse to render or persist a handoff at all, returning {error: HANDOFF_EVIDENCE_BLOCKED, evidence_status, evidence_errors, message} instead. Leave false/omitted for today's graceful-degrade behavior (handoff_evidence_status is still returned either way)."},"force_include_ids":{"type":"array","items":{"type":"string"},"description":"(45f519a0, validated by 3cab355a) Optional list of sprint-item ids to force-include in the pending list even when their deferred_until is in the future. This is a one-off visibility override for this handoff call only — deferred_until is NOT cleared, so claim_sprint_item's own deferral gate is unaffected. Use when a human wants a backburnered item back in scope for one planning run without permanently re-enabling claiming. Every id is validated: it must belong to this project, match the effective version scope (when one applies), and be genuinely todo/pending — an unknown/cross-project/cross-version/not-pending id is rejected (reported in the response's force_include_rejected list, never silently dropped) rather than honoured. Accepted ids are also exempt from the code-pointer enrichment cap, so a requested item always gets prospected regardless of how large the pending board is."},"selected_item_ids":{"type":"array","items":{"type":"string"},"description":"(cffb9323) Optional explicit INCLUDE-ONLY item scope for a safe, isolated parallel-follow-up handoff — the opposite direction from force_include_ids (which WIDENS the pending list). When given, the pending batch on EVERY mode (full/delta/starter/compact/goal) is narrowed to exactly these ids plus their dependency closure (any depends_on ancestor still todo/pending in this project/version) — nothing else from the eligible backlog is included. Every requested id is validated (must exist, belong to this project, match the effective version scope when one applies, and be genuinely todo/pending — not already in_progress under another session, not done/failed/skipped): if ANY id fails validation, generate_handoff raises rather than silently falling back to the unfiltered backlog. The dependency-closure ids and a stable hash of that closure are rendered in a <selected_item_scope> tag inside the /goal block, bound into the same token body-hash as the rest of the content. (d2fc7465) The SAME closure ids/hash, plus which of the requested ids survived every downstream claimability filter (unprospected/backburner/manual/wave_gate_pending, each with a reason) and why, are ALSO returned as a structured `selected_scope` field on the response — the parse-free counterpart to the embedded tag, and the only place to learn about a PARTIAL exclusion (some, not all, requested ids dropped); a TOTAL exclusion instead raises HANDOFF_SCOPE_NON_EXECUTABLE. `selected_scope` is null when selected_item_ids was never passed."},"strict_continuation":{"type":"boolean","description":"(ecc8b280) Opt-in, off by default — mirrors strict_evidence's shape. When true and checkpoint is not set, refuses to render/persist this handoff (full/delta modes only) if actionable pending/in_progress items remain on the live board with no recorded blocker_kind while execution_mode=autonomous, returning {error: HANDOFF_CONTINUATION_BLOCKED, continuation_status, message} instead. Leave false/omitted for today's behavior (continuation_status is still always returned either way)."},"strict_pointer_evidence":{"type":"boolean","description":"(eb8b6894) Opt-in, off by default, separate from strict_evidence above. When true, the claimable/goal batch's UNPROSPECTED exclusion requires a pending item's durable pointer(s) to have actually RESOLVED (resolve_pointer succeeded), not merely be PRESENT as a row — a structurally-valid-but-unresolved pointer no longer silently satisfies the gate. Never raises/blocks the whole handoff (unlike strict_evidence): an affected item is simply excluded from the claimable batch, the same way today's presence-only UNPROSPECTED gate already excludes items. Every pending item's pointer_resolution_status (structural_valid/target_resolved/provenance_verified/resolution_source/strict_satisfied) is always returned regardless of this flag — it only changes which items make the claimable cut."}}},"output_schema":null,"annotations":{"title":"Generate Handoff","readOnlyHint":true,"openWorldHint":false,"idempotentHint":true,"destructiveHint":false},"source":"probe","observed_at":"2026-09-29T06:40:02.225Z"},{"name":"get_agent_instructions","title":"Get Agent Instructions","description":"[MAINTENANCE] Read-only: Return the custom agent_instructions for a project. These are injected automatically by start_session so every session picks them up. Use this when you need to read or display the current instructions.","input_schema":{"type":"object","required":[],"properties":{"project_id":{"type":"string"},"project_name":{"type":"string","description":"Project name — an alternative to project_id; resolved to the id internally. project_id wins if both are given."}}},"output_schema":null,"annotations":{"title":"Get Agent Instructions","readOnlyHint":true,"openWorldHint":false,"idempotentHint":true,"destructiveHint":false},"source":"probe","observed_at":"2026-09-29T06:40:02.225Z"},{"name":"get_ai_log_export_status","title":"Get AI Log Export Status","description":"[MAINTENANCE] R2-G — Read-only: status/diagnostics for the OPTIONAL AI-log -> OTel/self-hosted-Langfuse export adapter (meridian.ai_log_otel_export). Attempts NO network call — only reports whether the feature is globally enabled (MERIDIAN_AI_LOG_OTEL_ENABLED), the effective per-project enabled state, whether the optional opentelemetry client library is installed, the resolved endpoint/protocol/service_name, and the stored config/watermark row (last export status, last error, retry_count) if one exists. Meridian's own ai_log_events table stays authoritative regardless of this feature's state — see meridian.ai_log_otel_export's module docstring for the binding architectural decision (this is an export adapter, never a second source of truth). Returns {project_id, global_feature_enabled, effective_enabled, dependency_available, endpoint_configured, protocol, langfuse_compat, service_name, config}.","input_schema":{"type":"object","required":[],"properties":{"project_id":{"type":"string"},"project_name":{"type":"string","description":"Project name — an alternative to project_id; resolved to the id internally. project_id wins if both are given."}}},"output_schema":null,"annotations":{"title":"Get AI Log Export Status","readOnlyHint":true,"openWorldHint":false,"idempotentHint":true,"destructiveHint":false},"source":"probe","observed_at":"2026-09-29T06:40:02.225Z"},{"name":"get_blog_posts","title":"Get Blog Posts","description":"[MAINTENANCE] Read-only: List workspace-scoped blog posts, newest first. Optional 'status' filter (draft|published|archived). Each post includes a 'url' (/blog/<slug>).","input_schema":{"type":"object","required":[],"properties":{"status":{"enum":["draft","published","archived"],"type":"string"}}},"output_schema":null,"annotations":{"title":"Get Blog Posts","readOnlyHint":true,"openWorldHint":false,"idempotentHint":true,"destructiveHint":false},"source":"probe","observed_at":"2026-09-29T06:40:02.225Z"},{"name":"get_capability_manifest","title":"Get Capability Manifest","description":"[SUPPORT] 649e095f — Read-only: return a project's structured capability manifest (id/purpose/required_tools/fallback_chain/provenance/availability_policy/verification_command per capability), plus its schema version and a stable content hash for change detection. A project that has never set one gets an empty manifest back, never an error — old projects continue unaffected. Foundation-only: this is the raw declared manifest, not yet resolved against live tool/tunnel availability or profile inheritance. Persistent-state disclosure: on hosted Meridian, supplied text and project/session metadata -- including task log entries, pinned decisions, sprint items, notes, handoff/goal state, and HITL queue items -- are sent to and stored in Meridian's service, in an isolated per-tenant Postgres database (Neon); self-hosted deployments keep the same categories in the configured local SQLite/Postgres database. This data is visible in the dashboard and API, and may resurface in later project context or handoffs. Notes and pinned decisions can be deleted individually; task log entries and sprint items can be deleted via the dashboard/API (not exposed as an agent-facing tool); HITL queue items and handoff state have no per-record delete. Full removal of any of this data is available via project or account deletion, using the documented controls. Do not include secrets.","input_schema":{"type":"object","required":[],"properties":{"project_id":{"type":"string"},"project_name":{"type":"string","description":"Project name — an alternative to project_id; resolved to the id internally. project_id wins if both are given."}}},"output_schema":null,"annotations":{"title":"Get Capability Manifest","readOnlyHint":false,"openWorldHint":false,"idempotentHint":false,"destructiveHint":false},"source":"probe","observed_at":"2026-09-29T06:40:02.225Z"},{"name":"get_citation_edges","title":"Get Citation Edges","description":"[MAINTENANCE] fefb596a — read the CITATION GRAPH of a project's ingested documents. Returns every in-text citation marker (a kind='citation' element parsed from an ingested .tex/.docx) together with its resolved edges:\n• bibentry edges — the intra-document link from a \\cite{key} marker to a matching \\bibitem/bibliography entry in the SAME document (materialised automatically on ingest).\n• zotero_item edges — the cross-document link from a marker to a canonical Zotero library item, keyed on DOI (materialised by the opt-in resolve_citations pass); target_document_id is set when the cited paper is itself ingested in this project.\nEach marker carries {element_id, document_id, ordinal, ref, text, edges:[{edge_kind, target_kind, target_ref, target_element_id, target_document_id, resolved_at}]}. Scope to one document with source (a stored source path/URL) or document_id; omit both for the whole project. Returns an empty markers list (never an error) when no document structure has been persisted yet.","input_schema":{"type":"object","required":[],"properties":{"source":{"type":"string","description":"Restrict to the document stored under this source (path/URL). Empty graph if the source is unknown."},"project_id":{"type":"string"},"document_id":{"type":"string","description":"Restrict to one stored document by its doc_store id."},"project_name":{"type":"string","description":"Project name — an alternative to project_id; resolved to the id internally."}}},"output_schema":null,"annotations":{"title":"Get Citation Edges","readOnlyHint":true,"openWorldHint":false,"idempotentHint":true,"destructiveHint":false},"source":"probe","observed_at":"2026-09-29T06:40:02.225Z"},{"name":"get_connection_log","title":"Get Connection Log","description":"[MAINTENANCE] Read-only: Return the recent /mcp connection-event log for this tenant (newest first, up to 200 entries). Every HTTP /mcp request Meridian receives is recorded: timestamp, MCP method (initialize/tools/list/tools/call/...), auth_result (success/oauth/no_token/invalid_token/expired), tools_returned (tool count for tools/list responses), client_user_agent, and HTTP response_status. Use this to diagnose client-side outages (zero tools returned, auth failures, unexpected User-Agents) in real time or after the fact without needing raw Fly.io log access.","input_schema":{"type":"object","required":[],"properties":{"limit":{"type":"integer","description":"Max entries to return (default 100, max 200)."},"since":{"type":"string","description":"ISO timestamp (UTC). Only return events at or after this time. Example: '2026-07-15 03:00:00'"}}},"output_schema":null,"annotations":{"title":"Get Connection Log","readOnlyHint":true,"openWorldHint":false,"idempotentHint":true,"destructiveHint":false},"source":"probe","observed_at":"2026-09-29T06:40:02.225Z"},{"name":"get_context_block","title":"Get Context Block","description":"[SUPPORT] Read-only: Return a compact project context block (north star, sprint, pending sprint items, recent tasks, recent decisions, active sessions) wrapped in a <meridian_context project_id=\"...\" mode=\"...\"> XML envelope for structured parsing by AI clients (v2.5+). The 'text' field in the response contains the XML-wrapped content. mode='full' (default) for Code Handoff into a fresh Claude Code session; mode='chat' for a shorter paste into a new claude.ai conversation. The HTTP route /projects/{id}/context-block returns the same content as unwrapped plain text.","input_schema":{"type":"object","required":[],"properties":{"mode":{"enum":["full","chat"],"type":"string"},"project_id":{"type":"string"},"project_name":{"type":"string","description":"Project name — an alternative to project_id; resolved to the id internally. project_id wins if both are given."}}},"output_schema":null,"annotations":{"title":"Get Context Block","readOnlyHint":true,"openWorldHint":false,"idempotentHint":true,"destructiveHint":false},"source":"probe","observed_at":"2026-09-29T06:40:02.225Z"},{"name":"get_custom_hooks","title":"Get Custom Hooks","description":"[MAINTENANCE] 273287cb — list a project's user-defined hooks (newest first). Optional event filter and enabled_only flag. Each entry includes the derived slug (the filename stem used when written to .claude/hooks/) alongside the stored fields.","input_schema":{"type":"object","required":[],"properties":{"event":{"enum":["PreToolUse","PostToolUse","Stop"],"type":"string","description":"Optional filter to only this event's hooks."},"project_id":{"type":"string"},"enabled_only":{"type":"boolean","description":"When true, only return hooks with enabled=true."},"project_name":{"type":"string","description":"Project name — an alternative to project_id; resolved to the id internally. project_id wins if both are given."}}},"output_schema":null,"annotations":{"title":"Get Custom Hooks","readOnlyHint":true,"openWorldHint":false,"idempotentHint":true,"destructiveHint":false},"source":"probe","observed_at":"2026-09-29T06:40:02.225Z"},{"name":"get_document_structure","title":"Get Document Structure","description":"[SUPPORT] 13462df2 — return the heading outline of a Word .docx WITHOUT ingesting it as a note. Meridian parses the .docx server-side (stdlib only, no python-docx, no persistent index) and returns paragraph_count, heading_count, and an ordered list of headings (level, text, para_id) — a fast structural map of a thesis chapter / spec before deciding what to read or ingest. Pass file_path to a server-accessible .docx. Persistent-state disclosure: on hosted Meridian, supplied text and project/session metadata -- including task log entries, pinned decisions, sprint items, notes, handoff/goal state, and HITL queue items -- are sent to and stored in Meridian's service, in an isolated per-tenant Postgres database (Neon); self-hosted deployments keep the same categories in the configured local SQLite/Postgres database. This data is visible in the dashboard and API, and may resurface in later project context or handoffs. Notes and pinned decisions can be deleted individually; task log entries and sprint items can be deleted via the dashboard/API (not exposed as an agent-facing tool); HITL queue items and handoff state have no per-record delete. Full removal of any of this data is available via project or account deletion, using the documented controls. Do not include secrets.","input_schema":{"type":"object","required":["file_path"],"properties":{"file_path":{"type":"string","description":"Path to a server-accessible .docx file."}}},"output_schema":null,"annotations":{"title":"Get Document Structure","readOnlyHint":false,"openWorldHint":false,"idempotentHint":false,"destructiveHint":false},"source":"probe","observed_at":"2026-09-29T06:40:02.225Z"},{"name":"get_docx_document_lease","title":"Get Docx Document Lease","description":"[MAINTENANCE] 6507e83a — Read-only: the live whole-document lease on a .docx file, if any (who holds it). Use before acquire_docx_document_lease or a bulk rewrite to see whether the document is already leased by someone else. Persistent-state disclosure: on hosted Meridian, supplied text and project/session metadata -- including task log entries, pinned decisions, sprint items, notes, handoff/goal state, and HITL queue items -- are sent to and stored in Meridian's service, in an isolated per-tenant Postgres database (Neon); self-hosted deployments keep the same categories in the configured local SQLite/Postgres database. This data is visible in the dashboard and API, and may resurface in later project context or handoffs. Notes and pinned decisions can be deleted individually; task log entries and sprint items can be deleted via the dashboard/API (not exposed as an agent-facing tool); HITL queue items and handoff state have no per-record delete. Full removal of any of this data is available via project or account deletion, using the documented controls. Do not include secrets.","input_schema":{"type":"object","required":["file_path"],"properties":{"file_path":{"type":"string","description":"The .docx source path."}}},"output_schema":null,"annotations":{"title":"Get Docx Document Lease","readOnlyHint":false,"openWorldHint":false,"idempotentHint":false,"destructiveHint":false},"source":"probe","observed_at":"2026-09-29T06:40:02.225Z"},{"name":"get_docx_region_claims","title":"Get Docx Region Claims","description":"[MAINTENANCE] f7ee1ba7 — Read-only: list active scoped docx-region claims on a file (who owns which element_ids). Use before update_paragraph to see whether the target element is claimed. Persistent-state disclosure: on hosted Meridian, supplied text and project/session metadata -- including task log entries, pinned decisions, sprint items, notes, handoff/goal state, and HITL queue items -- are sent to and stored in Meridian's service, in an isolated per-tenant Postgres database (Neon); self-hosted deployments keep the same categories in the configured local SQLite/Postgres database. This data is visible in the dashboard and API, and may resurface in later project context or handoffs. Notes and pinned decisions can be deleted individually; task log entries and sprint items can be deleted via the dashboard/API (not exposed as an agent-facing tool); HITL queue items and handoff state have no per-record delete. Full removal of any of this data is available via project or account deletion, using the documented controls. Do not include secrets.","input_schema":{"type":"object","required":["file_path"],"properties":{"file_path":{"type":"string","description":"The .docx source path."}}},"output_schema":null,"annotations":{"title":"Get Docx Region Claims","readOnlyHint":false,"openWorldHint":false,"idempotentHint":false,"destructiveHint":false},"source":"probe","observed_at":"2026-09-29T06:40:02.225Z"},{"name":"get_effective_capability_profile","title":"Get Effective Capability Profile","description":"[SUPPORT] 02038afe — Read-only: resolve and return the MERGED capability profile for a project (optionally narrowed to one sprint item) across every applicable layer — workspace -> user -> project -> sprint_version -> item, least to most specific. A capability id declared at more than one layer resolves to the most specific layer's declaration; the response's capability_sources maps each effective capability id to the layer that won. overrides lists every capability id declared by more than one layer (each entry flagged conflict=true when the two declarations disagree on required_tools or availability_policy — the fields that change what an executor can actually rely on). disabled lists every disable that actually retracted an inherited capability. Pass sprint_item_id to also resolve that item's sprint_version and item layers; omit it to get just workspace/user/project. Never resolves against live tool/tunnel availability — this is the declared, merged profile only. Persistent-state disclosure: on hosted Meridian, supplied text and project/session metadata -- including task log entries, pinned decisions, sprint items, notes, handoff/goal state, and HITL queue items -- are sent to and stored in Meridian's service, in an isolated per-tenant Postgres database (Neon); self-hosted deployments keep the same categories in the configured local SQLite/Postgres database. This data is visible in the dashboard and API, and may resurface in later project context or handoffs. Notes and pinned decisions can be deleted individually; task log entries and sprint items can be deleted via the dashboard/API (not exposed as an agent-facing tool); HITL queue items and handoff state have no per-record delete. Full removal of any of this data is available via project or account deletion, using the documented controls. Do not include secrets.","input_schema":{"type":"object","required":[],"properties":{"project_id":{"type":"string"},"project_name":{"type":"string","description":"Project name — an alternative to project_id; resolved to the id internally. project_id wins if both are given."},"user_scope_id":{"type":"string","description":"Optional — a user/human id whose 'user' layer should be included in the merge."},"sprint_item_id":{"type":"string","description":"Optional — also resolve this item's sprint_version and item-scoped layers."},"workspace_scope_id":{"type":"string","description":"Optional — defaults to 'singleton' (the self-host default workspace key)."}}},"output_schema":null,"annotations":{"title":"Get Effective Capability Profile","readOnlyHint":false,"openWorldHint":false,"idempotentHint":false,"destructiveHint":false},"source":"probe","observed_at":"2026-09-29T06:40:02.225Z"},{"name":"get_effective_profile","title":"Get Effective Profile","description":"[SUPPORT] 0bec79a7 (PROFILE-5) — Read-only: resolve and return the MERGED profile for a project across every applicable layer — hosted_default -> workspace -> user -> project -> session, least to most specific (see meridian.db.profile_layers.get_effective_profile). The 'project' layer is synthetic: its 7 legacy ProjectSettings/executor_config fields come from the existing get_project_settings authority (zero duplication), and its 3 new fields (tool_priority_map, capability_manifest_ref, claim_verification_mode) come from the real profile_layers row. A hosted_default layer only applies when its lifecycle_state is 'active' or 'deprecated' — 'draft' and 'retired' never contribute fields but still mark the result degraded/not-executable via the returned executable/degraded/*_reasons fields. Pass session_id/user_scope_id to also fold in those layers; workspace_scope_id/hosted_default_scope_id default to 'singleton'/'global'. Returns {error} for an unknown project_id.","input_schema":{"type":"object","required":[],"properties":{"project_id":{"type":"string"},"session_id":{"type":"string","description":"Optional — also resolve this session's session-scoped layer."},"project_name":{"type":"string","description":"Project name — an alternative to project_id; resolved to the id internally. project_id wins if both are given."},"user_scope_id":{"type":"string","description":"Optional — a user/human id whose 'user' layer should be included in the merge."},"workspace_scope_id":{"type":"string","description":"Optional — defaults to 'singleton' (the self-host default workspace key)."},"hosted_default_scope_id":{"type":"string","description":"Optional — defaults to 'global' (the self-host default hosted_default key)."}}},"output_schema":null,"annotations":{"title":"Get Effective Profile","readOnlyHint":true,"openWorldHint":false,"idempotentHint":true,"destructiveHint":false},"source":"probe","observed_at":"2026-09-29T06:40:02.225Z"},{"name":"get_experiment","title":"Get Experiment","description":"[SUPPORT] 3f6b8715 — read one project-scoped experiment by id.","input_schema":{"type":"object","required":["experiment_id"],"properties":{"project_id":{"type":"string"},"project_name":{"type":"string","description":"Project name — an alternative to project_id; resolved to the id internally. project_id wins if both are given."},"experiment_id":{"type":"string"}}},"output_schema":null,"annotations":{"title":"Get Experiment","readOnlyHint":true,"openWorldHint":false,"idempotentHint":true,"destructiveHint":false},"source":"probe","observed_at":"2026-09-29T06:40:02.225Z"},{"name":"get_experiment_events","title":"Get Experiment Events","description":"[SUPPORT] 3f6b8715 — list an experiment's events, oldest first. Optionally scoped to one run_id. Includes BOTH auto-skeleton writes (dead_end/pivot/breakthrough) and manually recorded ones.","input_schema":{"type":"object","required":["experiment_id"],"properties":{"limit":{"type":"integer","maximum":1000,"minimum":1},"run_id":{"type":"string"},"project_id":{"type":"string"},"project_name":{"type":"string","description":"Project name — an alternative to project_id; resolved to the id internally. project_id wins if both are given."},"experiment_id":{"type":"string"}}},"output_schema":null,"annotations":{"title":"Get Experiment Events","readOnlyHint":true,"openWorldHint":false,"idempotentHint":true,"destructiveHint":false},"source":"probe","observed_at":"2026-09-29T06:40:02.225Z"},{"name":"get_experiment_run","title":"Get Experiment Run","description":"[SUPPORT] 3f6b8715 — read one project-scoped experiment run by id.","input_schema":{"type":"object","required":["run_id"],"properties":{"run_id":{"type":"string"},"project_id":{"type":"string"},"project_name":{"type":"string","description":"Project name — an alternative to project_id; resolved to the id internally. project_id wins if both are given."}}},"output_schema":null,"annotations":{"title":"Get Experiment Run","readOnlyHint":true,"openWorldHint":false,"idempotentHint":true,"destructiveHint":false},"source":"probe","observed_at":"2026-09-29T06:40:02.225Z"},{"name":"get_external_job","title":"Get External Job","description":"[SUPPORT] Read one project-scoped external job and its durable observation history. Use this from a fresh session before taking any action on a live job.","input_schema":{"type":"object","required":[],"properties":{"job_id":{"type":"string"},"job_key":{"type":"string"},"project_id":{"type":"string"},"project_name":{"type":"string","description":"Project name — an alternative to project_id; resolved to the id internally. project_id wins if both are given."},"include_history":{"type":"boolean"}}},"output_schema":null,"annotations":{"title":"Get External Job","readOnlyHint":true,"openWorldHint":false,"idempotentHint":true,"destructiveHint":false},"source":"probe","observed_at":"2026-09-29T06:40:02.225Z"},{"name":"get_file_claims","title":"Get File Claims","description":"[SUPPORT] Read-only: show active claims on a file — the whole-file lock (with the holder's session name, if any) plus any symbol-level claims. Use to check who owns a file before editing it. Pass project_id (and optional symbol) to also get a `code_notes` list of code-anchored notes (kind='code') for that path.","input_schema":{"type":"object","required":["file_path"],"properties":{"symbol":{"type":"string","description":"Optional symbol to scope code-anchored notes to (requires project_id)."},"file_path":{"type":"string"},"project_id":{"type":"string","description":"Include code-anchored notes (kind='code') for this project/path in the response."},"project_name":{"type":"string","description":"Project name — an alternative to project_id; resolved to the id internally. project_id wins if both are given."}}},"output_schema":null,"annotations":{"title":"Get File Claims","readOnlyHint":true,"openWorldHint":false,"idempotentHint":true,"destructiveHint":false},"source":"probe","observed_at":"2026-09-29T06:40:02.225Z"},{"name":"get_findings","title":"Get Findings","description":"[MAINTENANCE] Read-only (c35370cc): read stored session_findings for a project (newest first), optionally scoped by key and/or session_id. The read side of store_finding. Persistent-state disclosure: on hosted Meridian, supplied text and project/session metadata -- including task log entries, pinned decisions, sprint items, notes, handoff/goal state, and HITL queue items -- are sent to and stored in Meridian's service, in an isolated per-tenant Postgres database (Neon); self-hosted deployments keep the same categories in the configured local SQLite/Postgres database. This data is visible in the dashboard and API, and may resurface in later project context or handoffs. Notes and pinned decisions can be deleted individually; task log entries and sprint items can be deleted via the dashboard/API (not exposed as an agent-facing tool); HITL queue items and handoff state have no per-record delete. Full removal of any of this data is available via project or account deletion, using the documented controls. Do not include secrets.","input_schema":{"type":"object","required":[],"properties":{"key":{"type":"string","description":"Only findings in this bucket."},"limit":{"type":"integer","description":"Max rows (default 50)."},"project_id":{"type":"string"},"session_id":{"type":"string","description":"Only findings from this session."},"project_name":{"type":"string","description":"Project name — an alternative to project_id."}}},"output_schema":null,"annotations":{"title":"Get Findings","readOnlyHint":false,"openWorldHint":false,"idempotentHint":false,"destructiveHint":false},"source":"probe","observed_at":"2026-09-29T06:40:02.225Z"},{"name":"get_flag_drift","title":"Get Flag Drift","description":"[MAINTENANCE] 8ca89e8f — read side of link_flag_to_section: for every recorded flag link (optionally scoped to one doc / element_id / flag_name — pass flag_name alone with no doc for the REVERSE query 'flag X changed, which sections does it touch'), re-scan the CURRENT codebase (same AST scan as get_flag_registry) and diff each link's recorded default against what the flag defaults to NOW. Only the most recently recorded link per (element, flag) pair is diffed — a re-verified section's older links are history, not live claims. Each result carries status: 'removed' (the flag, or this exact call site, no longer exists — the strongest staleness signal), 'drifted' (the flag still exists but its default changed since this section was computed — the section is possibly stale, needs re-verification), or 'ok' (no evidence of drift found). Returns {project_id, root_dir, links:[{...link fields, current_default, current_call_sites, status}], summary:{ok, drifted, removed}}. No recorded links returns an empty list, never an error — this is advisory, not a hard gate.","input_schema":{"type":"object","required":[],"properties":{"doc":{"type":"string","description":"Optional: scope to links recorded against one stored document (the doc source you ingested it under)."},"root_dir":{"type":"string","description":"Absolute path to the source-tree root to re-scan for current flag defaults (same as get_flag_registry's root_dir). Defaults to the server's current working directory when omitted."},"flag_name":{"type":"string","description":"Optional: scope to links recorded for one flag name — the reverse query, omit 'doc' to search project-wide."},"element_id":{"type":"string","description":"Optional: scope to links recorded against one specific doc_elements id."},"project_id":{"type":"string"},"project_name":{"type":"string","description":"Project name — an alternative to project_id; resolved to the id internally. project_id wins if both are given."}}},"output_schema":null,"annotations":{"title":"Get Flag Drift","readOnlyHint":true,"openWorldHint":false,"idempotentHint":true,"destructiveHint":false},"source":"probe","observed_at":"2026-09-29T06:40:02.225Z"},{"name":"get_flag_registry","title":"Get Flag Registry","description":"[SUPPORT] 45802b67 — scan a source tree for `os.environ.get(...)` / `os.getenv(...)` call sites (AST-based, not regex) and return a flat inventory of every config flag the codebase reads: {flag_name, file, line, default}. Only call sites where the flag name is a STRING LITERAL first argument are included — dynamic names (a variable, f-string, etc.) are skipped gracefully rather than erroring. The default is best-effort literal-eval'd from the second positional arg (or a `default=` keyword); a non-literal default evaluates to null. Useful for auditing config drift — 'what env flags exist, where are they read, what do they default to' — without grepping by hand. Returns {repo_root, flags:[...], count, unique_flag_names:[...], unique_count}. A missing/empty tree returns an empty flags list, never an error.","input_schema":{"type":"object","required":[],"properties":{"root_dir":{"type":"string","description":"Absolute path to the source-tree root to scan recursively (vendored/build/cache dirs like node_modules/.git/dist/__pycache__ are pruned). Defaults to the server's current working directory (the current project's repo root) when omitted."}}},"output_schema":null,"annotations":{"title":"Get Flag Registry","readOnlyHint":true,"openWorldHint":false,"idempotentHint":true,"destructiveHint":false},"source":"probe","observed_at":"2026-09-29T06:40:02.225Z"},{"name":"get_goal","title":"Get Goal","description":"[SUPPORT] Read-only: Fine-grained — return just the goal fields (north_star, sprint, version_goal) in isolation. Use start_session or get_session_brief for full context including tasks and decisions. Use get_goal when you only need the raw goal fields.","input_schema":{"type":"object","required":[],"properties":{"project_id":{"type":"string"},"project_name":{"type":"string","description":"Project name — an alternative to project_id; resolved to the id internally. project_id wins if both are given."}}},"output_schema":null,"annotations":{"title":"Get Goal","readOnlyHint":true,"openWorldHint":false,"idempotentHint":true,"destructiveHint":false},"source":"probe","observed_at":"2026-09-29T06:40:02.225Z"},{"name":"get_graph_diff","title":"Get Graph Diff","description":"[MAINTENANCE] Read-only: compare the latest code-graph snapshots of two sessions — returns delta in node_count, hotspot_count, and file_churn. Use snapshot_graph_metrics first to record each session's current state.","input_schema":{"type":"object","required":["session_a","session_b"],"properties":{"session_a":{"type":"string","description":"First session ID."},"session_b":{"type":"string","description":"Second session ID to compare against session_a."}}},"output_schema":null,"annotations":{"title":"Get Graph Diff","readOnlyHint":true,"openWorldHint":false,"idempotentHint":true,"destructiveHint":false},"source":"probe","observed_at":"2026-09-29T06:40:02.225Z"},{"name":"get_hitl_request","title":"Get HITL Request","description":"[SUPPORT] Read-only: Poll a HITL request for the human's answer. Returns the row including status ('pending'|'answered'|'dismissed') and answer text.","input_schema":{"type":"object","required":["request_id"],"properties":{"request_id":{"type":"string"}}},"output_schema":null,"annotations":{"title":"Get HITL Request","readOnlyHint":true,"openWorldHint":false,"idempotentHint":true,"destructiveHint":false},"source":"probe","observed_at":"2026-09-29T06:40:02.225Z"},{"name":"get_insights","title":"Get Insights","description":"[SUPPORT] Read-only: List a project's strategic insights (newest first), optionally filtered by horizon (permanent|year|quarter). Review accumulated understanding before planning. permanent insights also appear automatically in get_planning_brief.","input_schema":{"type":"object","required":[],"properties":{"horizon":{"enum":["permanent","year","quarter"],"type":"string","description":"Optional horizon filter."},"project_id":{"type":"string"},"project_name":{"type":"string","description":"Project name — an alternative to project_id; resolved to the id internally. project_id wins if both are given."}}},"output_schema":null,"annotations":{"title":"Get Insights","readOnlyHint":true,"openWorldHint":false,"idempotentHint":true,"destructiveHint":false},"source":"probe","observed_at":"2026-09-29T06:40:02.225Z"},{"name":"get_latex_structure","title":"Get Latex Structure","description":"[SUPPORT] 106118cd — parse a LaTeX (.tex) source's structure WITHOUT a PDF intermediary. Meridian parses the .tex server-side with pylatexenc (pure-Python, no LaTeX install) and returns heading_count, an ordered headings outline and a nested tree of \\part/\\chapter/\\section/\\subsection/\\subsubsection/\\paragraph (level, kind, text, children), plus unexpanded_inputs (\\input/\\include filenames, not expanded) and a bibliography list (thebibliography \\bibitem entries, and \\bibliography{...} + a sibling .bib when a path is given). Pass file_path to a server-accessible .tex, OR pass source with the raw LaTeX inline. Malformed LaTeX returns a partial/empty result, never an error crash. Persistent-state disclosure: on hosted Meridian, supplied text and project/session metadata -- including task log entries, pinned decisions, sprint items, notes, handoff/goal state, and HITL queue items -- are sent to and stored in Meridian's service, in an isolated per-tenant Postgres database (Neon); self-hosted deployments keep the same categories in the configured local SQLite/Postgres database. This data is visible in the dashboard and API, and may resurface in later project context or handoffs. Notes and pinned decisions can be deleted individually; task log entries and sprint items can be deleted via the dashboard/API (not exposed as an agent-facing tool); HITL queue items and handoff state have no per-record delete. Full removal of any of this data is available via project or account deletion, using the documented controls. Do not include secrets.","input_schema":{"type":"object","required":[],"properties":{"source":{"type":"string","description":"Raw LaTeX source, as an alternative to file_path. Ignored when file_path is given."},"file_path":{"type":"string","description":"Path to a server-accessible .tex file. A sibling .bib referenced by \\bibliography is resolved relative to it."}}},"output_schema":null,"annotations":{"title":"Get Latex Structure","readOnlyHint":false,"openWorldHint":false,"idempotentHint":false,"destructiveHint":false},"source":"probe","observed_at":"2026-09-29T06:40:02.225Z"},{"name":"get_notes","title":"Get Notes","description":"[SUPPORT] Read-only: List project notes (newest first), LIGHTWEIGHT by default — each item is id/slug/title/tags/kind/priority/timestamps with NO body, so the list never overflows context. This is the pull model: scan the list, then call read_note(project_id, slug) to fetch one note's full body on demand. Optional ?tag substring filter and ?query full-text search (matches title+body even though bodies aren't returned). Pass bodies=true only when you truly need every body inline. Pagination: pass limit (default 100, max 500) and/or cursor to get a {notes, has_more, next_cursor} envelope, then re-call with cursor=next_cursor for the next page; omit both for the full list.","input_schema":{"type":"object","required":[],"properties":{"tag":{"type":"string"},"sort":{"enum":["recency","relevance"],"type":"string","description":"98890df1 — 'relevance' ranks notes by reference_count/recency/decision-link (heavily cross-referenced notes surface, stale ones sink) and returns a bare list with a per-note 'relevance' score; default 'recency'."},"limit":{"type":"integer","description":"Page size (default 100, clamped 1..500). Passing limit or cursor switches the result to the {notes, has_more, next_cursor} pagination envelope."},"query":{"type":"string","description":"Text search across note title and body (case-insensitive)."},"bodies":{"type":"boolean","description":"Default false. true returns full note bodies inline (legacy behavior) — usually unnecessary; prefer read_note(slug)."},"cursor":{"type":"integer","description":"Offset cursor from a prior page's next_cursor. Passing it switches the result to the {notes, has_more, next_cursor} envelope."},"project_id":{"type":"string"},"project_name":{"type":"string","description":"Project name — an alternative to project_id; resolved to the id internally. project_id wins if both are given."}}},"output_schema":null,"annotations":{"title":"Get Notes","readOnlyHint":true,"openWorldHint":false,"idempotentHint":true,"destructiveHint":false},"source":"probe","observed_at":"2026-09-29T06:40:02.225Z"},{"name":"get_parallelizable_groups","title":"Get Parallelizable Groups","description":"[MAINTENANCE] Read-only: Return clusters of pending sprint items that are safe to run simultaneously. Filters pending/todo items (optionally by version) whose depends_on is satisfied, then greedily partitions them into groups where no two items in a group share a touches_resources identifier. The orchestrator fans out each group as a parallel subagent batch and runs the groups in sequence. Returns {version, groups: [[item,...],...], group_count, eligible_count, undeclared_count, blocked: [...]}. Items still waiting on an unfinished dependency are listed under 'blocked', not in any group. Makes parallel sprints system-enforced rather than LLM-guessed. Persistent-state disclosure: on hosted Meridian, supplied text and project/session metadata -- including task log entries, pinned decisions, sprint items, notes, handoff/goal state, and HITL queue items -- are sent to and stored in Meridian's service, in an isolated per-tenant Postgres database (Neon); self-hosted deployments keep the same categories in the configured local SQLite/Postgres database. This data is visible in the dashboard and API, and may resurface in later project context or handoffs. Notes and pinned decisions can be deleted individually; task log entries and sprint items can be deleted via the dashboard/API (not exposed as an agent-facing tool); HITL queue items and handoff state have no per-record delete. Full removal of any of this data is available via project or account deletion, using the documented controls. Do not include secrets.","input_schema":{"type":"object","required":[],"properties":{"version":{"type":"string","description":"Optional: only consider items in this sprint-version bucket."},"project_id":{"type":"string"},"project_name":{"type":"string","description":"Project name — an alternative to project_id; resolved to the id internally. project_id wins if both are given."}}},"output_schema":null,"annotations":{"title":"Get Parallelizable Groups","readOnlyHint":false,"openWorldHint":false,"idempotentHint":false,"destructiveHint":false},"source":"probe","observed_at":"2026-09-29T06:40:02.225Z"},{"name":"get_pinned_decisions","title":"Get Pinned Decisions","description":"[SUPPORT] Read-only: List pinned decisions, highest priority first (urgent → normal → low, then newest-first). Active only by default. Each row includes its priority and a parsed edit_log array of prior bodies ({body, ts}) recorded on every in-place body edit. Pass query to filter to decisions whose title or body matches (every whitespace-separated term must appear in the title or the body, same multiword-AND convention as search_tasks/search_all) — omit or pass a blank string for no filter (W1-A).","input_schema":{"type":"object","required":[],"properties":{"query":{"type":"string","description":"Optional free-text filter over title + body. Every whitespace-separated term must appear in the title or the body (AND across terms, OR across columns). Blank/omitted means no filter."},"project_id":{"type":"string"},"project_name":{"type":"string","description":"Project name — an alternative to project_id; resolved to the id internally. project_id wins if both are given."},"include_superseded":{"type":"boolean"}}},"output_schema":null,"annotations":{"title":"Get Pinned Decisions","readOnlyHint":true,"openWorldHint":false,"idempotentHint":true,"destructiveHint":false},"source":"probe","observed_at":"2026-09-29T06:40:02.225Z"},{"name":"get_planning_brief","title":"Get Planning Brief","description":"PLANNING SESSIONS: CALL THIS FIRST before anything else. Read-only: Return a compact planning context — sprint, north star, pending items, in-progress items, recent tasks, active sessions, recent decisions, unvalidated assumptions, the last session's output (last_session), and a new-handoff signal. No session registration needed. Designed for planning chat sessions that need to see project state without side effects. Pass `since` (a prior call's generated_at) to flag only handoffs filed since you last checked. pending_items/in_progress default-collapse any parent_id/item_group cluster (2+ items) into one summary row — pass expand=true for the full ungrouped list.","input_schema":{"type":"object","required":[],"properties":{"since":{"type":"string","description":"Optional ISO timestamp (a prior brief's generated_at). When given, new_handoff_available flags only handoffs filed after it."},"expand":{"type":"boolean","description":"Default false: collapse parent_id/item_group clusters in pending_items/in_progress into one summary row each. Pass true for the full ungrouped list."},"project_id":{"type":"string"},"project_name":{"type":"string","description":"Project name — an alternative to project_id; resolved to the id internally. project_id wins if both are given."}}},"output_schema":null,"annotations":{"title":"Get Planning Brief","readOnlyHint":true,"openWorldHint":false,"idempotentHint":true,"destructiveHint":false},"source":"probe","observed_at":"2026-09-29T06:40:02.225Z"},{"name":"get_plugin_details","title":"Get Plugin Details","description":"[MAINTENANCE] Read-only: Full schema for one named plugin (all tool definitions, description overrides, and stored skill guide if available). Use list_plugins first to see which plugins are active, then call get_plugin_details(name) to load the schema for a specific plugin on demand.","input_schema":{"type":"object","required":["name"],"properties":{"name":{"type":"string","description":"Plugin name as returned by list_plugins (e.g. 'filesystem', 'code-intel', 'code-extractor')."}}},"output_schema":null,"annotations":{"title":"Get Plugin Details","readOnlyHint":true,"openWorldHint":false,"idempotentHint":true,"destructiveHint":false},"source":"probe","observed_at":"2026-09-29T06:40:02.225Z"},{"name":"get_profile_layer","title":"Get Profile Layer","description":"[SUPPORT] 0bec79a7 (PROFILE-5) — Read-only: return the raw, single-layer profile for one (scope_type, scope_id) — one row of the hosted_default -> workspace -> user -> project -> session contract, with no merging against any other layer. A scope with no persisted row gets an empty profile back (revision=0, fields={}), never an error — mirrors get_capability_manifest's 'never a read error' contract. Use get_effective_profile instead when you want the MERGED, multi-layer view for a project.","input_schema":{"type":"object","required":["scope_type","scope_id"],"properties":{"scope_id":{"type":"string","description":"The key for this layer — a hosted_default policy id (typically 'global'), a tenant/workspace id, a user/human id, the project_id, or the session_id, depending on scope_type."},"scope_type":{"enum":["hosted_default","workspace","user","project","session"],"type":"string"}}},"output_schema":null,"annotations":{"title":"Get Profile Layer","readOnlyHint":true,"openWorldHint":false,"idempotentHint":true,"destructiveHint":false},"source":"probe","observed_at":"2026-09-29T06:40:02.225Z"},{"name":"get_profile_layer_revisions","title":"Get Profile Layer Revisions","description":"[SUPPORT] 0bec79a7 (PROFILE-5) — Read-only: the hosted_default revision/audit history for one scope_id, newest first — the rollback/audit trail the profile contract requires for the one layer that is 'immutable once published'. Only hosted_default writes are ledgered; a non-hosted_default scope_id always returns []. Each entry carries revision, content_hash, lifecycle_state, fields, reset_fields, actor, and created_at.","input_schema":{"type":"object","required":["scope_id"],"properties":{"limit":{"type":"integer","description":"Maximum rows to return, newest first. Defaults to 50."},"scope_id":{"type":"string"}}},"output_schema":null,"annotations":{"title":"Get Profile Layer Revisions","readOnlyHint":true,"openWorldHint":false,"idempotentHint":true,"destructiveHint":false},"source":"probe","observed_at":"2026-09-29T06:40:02.225Z"},{"name":"get_project_by_name","title":"Get Project By Name","description":"[MAINTENANCE] Read-only: Find a project by name — look up, search, or resolve a project's project_id from its name (case-insensitive substring match). Use when the user names a project but you need its id. Returns the first hit with id, name, and sprint.","input_schema":{"type":"object","required":["name"],"properties":{"name":{"type":"string"}}},"output_schema":null,"annotations":{"title":"Get Project By Name","readOnlyHint":true,"openWorldHint":false,"idempotentHint":true,"destructiveHint":false},"source":"probe","observed_at":"2026-09-29T06:40:02.225Z"},{"name":"get_proposal_gates","title":"Get Proposal Gates","description":"[SUPPORT] Read-only: list proposal HITL gates for a project, optionally filtered by category and/or (raw, stored) state. Pass sprint_item_id to instead list only the gates currently blocking/quarantining that one item (an effective-state-aware view — an expired auto_on_expiry gate is included even if its stored state says 'allowed').","input_schema":{"type":"object","required":[],"properties":{"state":{"enum":["blocked","quarantined","allowed"],"type":"string"},"category":{"enum":["legal_ip","product_scope","destructive_ops","production_deploy","contradiction_acceptance","other_ambiguous"],"type":"string"},"project_id":{"type":"string"},"project_name":{"type":"string","description":"Project name — an alternative to project_id; resolved to the id internally. project_id wins if both are given."},"sprint_item_id":{"type":"string","description":"When given, returns only gates currently blocking/quarantining this sprint item (ignores category/state filters)."}}},"output_schema":null,"annotations":{"title":"Get Proposal Gates","readOnlyHint":true,"openWorldHint":false,"idempotentHint":true,"destructiveHint":false},"source":"probe","observed_at":"2026-09-29T06:40:02.225Z"},{"name":"get_proposal_lineage","title":"Get Proposal Lineage","description":"[SUPPORT] Read-only: everything known about one proposal's place in its lineage graph in one call — raw relation edges touching it (either direction), its ancestor chain (walking predecessor-ward, nearest first), its direct successors (proposals that relate TO it, sequence-ordered), and its full descendant set (every proposal that transitively relates to it, breadth-first, nearest first). Descendants are capped at max_items edges with a non-silent 'descendants_truncated' marker reporting the true total when exceeded — ancestors/successors/links are not capped (a lineage chain/fan-out this large would itself be pathological). Returns {proposal_id, links, ancestors, successors, descendants, descendants_truncated}.","input_schema":{"type":"object","required":["proposal_id"],"properties":{"max_items":{"type":"integer","maximum":1000,"minimum":1,"description":"Cap on how many descendant edges to return (default 200)."},"proposal_id":{"type":"string"}}},"output_schema":null,"annotations":{"title":"Get Proposal Lineage","readOnlyHint":true,"openWorldHint":false,"idempotentHint":true,"destructiveHint":false},"source":"probe","observed_at":"2026-09-29T06:40:02.225Z"},{"name":"get_remote_task_status","title":"Get Remote Task Status","description":"[SUPPORT] 32d3d5de — Open a FRESH SSH connection (never the launching one) and determine a remote task's real status: completed (with the real exit code), still running (PID alive), terminated-unexpectedly (PID gone, no exit code — often OOM-kill or a host reset), connection-lost-but-possibly-still-running (the SSH connection itself could not be established, explicitly distinct from a failure), or unknown. Includes a bounded log tail and elapsed time. Persistent-state disclosure: on hosted Meridian, supplied text and project/session metadata -- including task log entries, pinned decisions, sprint items, notes, handoff/goal state, and HITL queue items -- are sent to and stored in Meridian's service, in an isolated per-tenant Postgres database (Neon); self-hosted deployments keep the same categories in the configured local SQLite/Postgres database. This data is visible in the dashboard and API, and may resurface in later project context or handoffs. Notes and pinned decisions can be deleted individually; task log entries and sprint items can be deleted via the dashboard/API (not exposed as an agent-facing tool); HITL queue items and handoff state have no per-record delete. Full removal of any of this data is available via project or account deletion, using the documented controls. Do not include secrets.","input_schema":{"type":"object","required":["job_id"],"properties":{"job_id":{"type":"string"},"project_id":{"type":"string"},"project_name":{"type":"string","description":"Project name — an alternative to project_id; resolved to the id internally. project_id wins if both are given."}}},"output_schema":null,"annotations":{"title":"Get Remote Task Status","readOnlyHint":false,"openWorldHint":false,"idempotentHint":false,"destructiveHint":false},"source":"probe","observed_at":"2026-09-29T06:40:02.225Z"},{"name":"get_research_run","title":"Get Research Run","description":"[SUPPORT] a5343387 — read one project-scoped research run by id.","input_schema":{"type":"object","required":["run_id"],"properties":{"run_id":{"type":"string"},"project_id":{"type":"string"},"project_name":{"type":"string","description":"Project name — an alternative to project_id; resolved to the id internally. project_id wins if both are given."}}},"output_schema":null,"annotations":{"title":"Get Research Run","readOnlyHint":true,"openWorldHint":false,"idempotentHint":true,"destructiveHint":false},"source":"probe","observed_at":"2026-09-29T06:40:02.225Z"},{"name":"get_server_log_checkpoint","title":"Get Server Log Checkpoint","description":"[MAINTENANCE] b241a437 -- Read-only: Return the positional/checkpoint index for the server_logs ring-buffer. The checkpoint is a lightweight 'table of contents' mapping minute-level timestamp buckets to the first/last row id and row count in that bucket. Use this for fast navigation through large log windows: find the bucket just before your target timestamp, then use its min_recorded_at as the since= argument to get_server_logs to skip all older rows without scanning. Complementary to search_server_logs (BM25 text search): this is positional navigation (WHERE in the log?) not semantic ranking (WHAT text?). The optional seek_to= argument returns the best since= hint directly. The index is rebuilt from the in-memory snapshot on every get_server_logs / search_server_logs call, so it is always current. Returns {total_rows, bucket_granularity_label, min_recorded_at, max_recorded_at, bucket_count, buckets:[{bucket, count, min_recorded_at, max_recorded_at, first_id, last_id}], seek_hint (when seek_to= given)}.","input_schema":{"type":"object","required":[],"properties":{"seek_to":{"type":"string","description":"Optional ISO timestamp (UTC). When provided, returns a seek_hint field with the best since= value to pass to get_server_logs to start near this timestamp. Example: '2026-07-17 03:00:00'"}}},"output_schema":null,"annotations":{"title":"Get Server Log Checkpoint","readOnlyHint":true,"openWorldHint":false,"idempotentHint":true,"destructiveHint":false},"source":"probe","observed_at":"2026-09-29T06:40:02.225Z"}],"next_cursor":"get_server_log_checkpoint","next_actions":[{"action":"list_tools","description":"Next page","href":"/v1/servers/io.github.ajc3xc%2Fmeridian/tools?cursor=get_server_log_checkpoint&limit=100","arguments":{"name":"io.github.ajc3xc/meridian","cursor":"get_server_log_checkpoint","limit":100}},{"action":"get_connection","description":"Connection block to call these tools","href":"/v1/servers/io.github.ajc3xc%2Fmeridian/connection?target=mcpServers","arguments":{"name":"io.github.ajc3xc/meridian","target":"mcpServers"}},{"action":"get_server","description":"Full descriptor with trust and connectability","href":"/v1/servers/io.github.ajc3xc%2Fmeridian","arguments":{"name":"io.github.ajc3xc/meridian"}}]}