ShadowGraph
OfficialShadowGraph is an MCP server for capturing project decisions, attempts, facts, and memories, then evaluating and reusing them through search, context, reviews, and lifecycle controls.
Record decisions with chosen options, alternatives, assumptions, evidence, confidence, reopen rules, and idempotent retries.
Record attempts, outcomes, and supporting or contradicting confidence evidence; update decision status and supersession.
Record and reconcile scoped facts and memories, including batch ADD/UPDATE/DELETE/NOOP plans with provenance and validity windows.
Search, retrieve, recall, and expand records with filters, pagination, graph neighbors, ranked signals, and completeness declarations.
Read project working sets: active decisions, stale assumptions, failed attempts, fired conditions, low-confidence decisions, and persisted review signals.
Evaluate reopen rules, explain review verdicts, maintain stale/expired records, acknowledge review signals, and validate integrity.
Use project/origin scoping, access grants, audit revisions, read provenance, and explicit completeness metadata for controlled reads and writes.
Supports optional OpenAI-compatible embedding endpoints to generate semantic embeddings used for vector-based recall of scoped memory; remote endpoints are opt-in.
ShadowGraph
Carry useful development experience into the next agent session.
ShadowGraph records what worked, what failed, and why a decision was made—then supplies relevant experience when you continue working. The demonstrated automatic paths are the Windows Codex terminal wrapper and, in print mode, Claude Code CLI hooks on Windows, after one-time setup in projects you enroll.
Get started · Supported workflows · Release & downloads · Documentation
After setup, work normally. Memory processes in the background; reuse follows your project and sharing choices. Editable diagram.
From a failed check to useful experience
In a bounded Windows demonstration, an agent ran a parser check that failed because empty fields were missing. It removed a filtering step and reran the unchanged check successfully. Its explanation included the rejected alternative: reconstructing empty fields later would lose their original positions and add complexity.
The wrapper captured the actual command results and explanation. A fresh session working on a differently delimited reader received the relevant experience automatically, identified it as prior-session evidence before its first command, and preserved empty fields in its implementation. Its check passed.
This demonstrates one working path, not perfect recall. Extraction can be delayed: two ordinary tasks completed while earlier memory was still pending, then processing recovered automatically. No memory reminder or manual extraction command was needed.
Related MCP server: Memryzed
Quick start: Windows Codex
Prerequisites
Windows x64, PowerShell 7+, and Node.js 22.5+ with npm (Node 24 recommended).
Codex CLI 0.161.0, signed in through your existing ChatGPT subscription. The adapter explicitly selects
gpt-6.1-sol; other executor versions and API-key/provider overrides are not supported by this profile.A project you choose to enroll, and a private directory outside source control for memory and configuration.
The Codex executor is a separate prerequisite distributed as @openai/codex. ShadowGraph itself is not published to npm. Installing ShadowGraph alone does not enable automatic memory.
1. Install
Run in PowerShell 7+. The version is pinned; the release includes SHA256SUMS.txt for the tarball.
npm install --global https://github.com/LiLara-AI/shadowgraph/releases/download/v0.43.0/shadowgraph-unified-plugin-0.43.0.tgz
$executorDir = Join-Path $env:LOCALAPPDATA 'ShadowGraph-Codex-0.161.0'
npm install --prefix $executorDir @openai/codex@0.161.0
$codexExe = (Get-ChildItem (Join-Path $executorDir 'node_modules/@openai') -Filter codex.exe -Recurse | Select-Object -First 1).FullName
& $codexExe --version
& $codexExe login statusIf needed, use & $codexExe login and complete Codex's normal sign-in yourself. Select the native codex.exe, not an npm shim. Setup checks its version, binary identity and account route. Do not copy authentication files.
2. Enroll your project once
Run this from the project directory you want to enroll. Choose a descriptive project name; demo is an example.
$memoryHome = Join-Path $env:LOCALAPPDATA 'ShadowGraph-Codex-Memory'
$setupFile = Join-Path $env:LOCALAPPDATA 'shadowgraph-codex-setup.json'
@{
executable = $codexExe
hostMode = 'workspace'
projects = @(@{ project = 'demo'; cwd = (Get-Location).Path })
} | ConvertTo-Json -Depth 5 | Set-Content -Encoding utf8 $setupFile
shadowgraph-codex.cmd setup --config $setupFile --home $memoryHome
shadowgraph-codex.cmd status --home $memoryHomePersistent setup asks for genuine owner consent at your terminal. Review the project, executor and provider scope before confirming. Workspace permissions and managed execution rules still apply. PowerShell 7 writes this JSON as UTF-8 without a byte-order mark.
3. Work normally
From the enrolled project, launch:
$memoryHome = Join-Path $env:LOCALAPPDATA 'ShadowGraph-Codex-Memory'
shadowgraph-codex.cmd run --home $memoryHomeEnter ordinary task prompts, one line per turn. Launch the same command again for a fresh session. Relevant memory is supplied before each new turn; you do not need to say “remember” or “search memory.” Only work launched through this wrapper is observed.
Answers appear without waiting for extraction. Pending memory retries while the wrapper is open and on later launches. Closing it stops the bounded worker; there is no permanent background daemon. For configuration, pending-state troubleshooting and limits, see the Codex guide.
What survives a session
Experience | What stays attached |
Decisions | Chosen approach, alternatives, reasons and conditions for reconsideration |
Attempts and outcomes | What was tried and the observed result; inferred causes remain distinct |
Evidence | Source quotations, captured command results and provenance |
Current state | Corrections and supersession, while retaining history |
Uncertainty | Model-proposed interpretation, missing conditions and limits of the evidence |
Stored records are inspectable. A model interpretation is not independently verified truth, and a useful lesson is not automatically valid in every project.
Sharing and control
Memory starts project-only. You can explicitly share selected enrolled projects, select all currently permitted projects, exclude sources, revoke wider sharing, or pause the integration. Capture scope and read sharing are separate choices.
# From an enrolled project; use the same private home as setup.
shadowgraph-codex.cmd share --home $memoryHome --mode selected --projects demo,shared-library
shadowgraph-codex.cmd share --home $memoryHome --mode all-permitted --exclude confidential-project
shadowgraph-codex.cmd share --home $memoryHome --mode project
shadowgraph-codex.cmd pause --home $memoryHome
shadowgraph-codex.cmd resume --home $memoryHomeReplace names with your enrolled projects. Sharing is explicit and revocable, not an automatic permission detector. Corrections retain history; source dependencies prevent copied memory-informed answers from bypassing later revocation. Already displayed information cannot be erased from a transcript or a person's knowledge. Details and inspection commands.
Local-first, with a configured provider. Canonical memory stays in your private local store. Automatic extraction and host delivery send selected captured/context data through the configured model provider and require its account and network. Pattern redaction cannot guarantee every secret is removed. There is no hosted sync or telemetry. Data lifecycle, backup and deletion.
MCP interface profiles
Full remains the default (35 tools, or 36 with a configured verifier). Compact remains 16 tools. The new opt-in Workflow Profile offers 20 tools: Compact plus stored review signals, keyed confidence evidence, decision status transitions and explicit supersession, using the existing handlers and access controls.
Server environment | Inventory |
Profile unset; compact unset or | Full: 35 / 36 |
Profile unset; | Compact: 16 |
| Workflow: 20 |
Set the environment on the MCP server process, then restart/reconnect and refresh
tools/list. There is no agent-callable mode switch. Workflow does not expose
administrative repair or destructive cleanup. See the configuration and workflow
guide.
Supported workflows
Workflow | What this preview establishes |
Windows | Installed command-executing workflow; automatic capture, background extraction, fresh-session delivery and recovery after delay/failure |
MCP, CLI, HTTP and JavaScript API | Explicit record/read operations; MCP exposes 16 compact or 35 full tools. Tool calls alone do not observe all work |
Claude Code CLI hooks (Windows) | After one-time setup on Claude Code CLI 2.x (verified on 2.1.302 and 2.1.312, print mode): durable capture under contention, automatic extraction by an owner-selected model, delivery to fresh sessions, corrections of decisions (a decision kept verbatim is linked and marked as corrected, not closed) and revocable sharing. On Windows, use Claude Code 2.1.312 or later: up to 2.1.302, |
Codex Desktop UI or ordinary CLI launched elsewhere | Not observed by this wrapper |
Glama MCP container | Credential-free MCP surface; cannot capture a user's Windows Codex sessions by itself |
Preview limits
Each host turn has a 120-second process limit. Background extraction has bounded calls, retries and concurrency; a backlog can remain honestly pending. Native command events and user/assistant text are captured, but not every native tool-event type. Retrieval happens between turns, not inside a running turn.
For Claude Code CLI, delivered experience is not always applied: in one live run a fresh session received an earlier lesson and did not apply it. After extraction is deactivated and activated again, items left pending under the earlier setup are not extracted; status reports them as priorSetup. The Claude Code evidence is one Windows print-mode (claude -p) path, not every host.
This is Technical Preview, not stable/GA. There are no claims of perfect semantic classification, universal language support, cost or time savings, superiority over native memory, or a human third-party security audit. See release notes, security scope and benchmark status.
Upgrade and storage
Stop active work and back up your stores and private integration home before upgrading. v0.43.0 retains schema 7; changed source/executor/account identity requires setup again. Older pending work with different setup provenance is held, not silently reassigned. Upgrade and rollback guide.
Moving between 0.41.0 and 0.42.0
The historical schema-5/schema-7 migration and downgrade instructions remain in the migration guide. Preserve a backup made before upgrading.
Documentation
Need | Guide |
Automatic Windows setup, sharing, limits and troubleshooting | |
Manual installation, MCP configuration, CLI/HTTP/JavaScript and storage | |
Other clients and existing hooks | |
API and protocol details | |
A decision that reopens when conditions change | |
Privacy, backups and recovery | |
Development and feedback |
Please redact private paths, prompts, stores and credentials before reporting an issue. Report security vulnerabilities privately.
MIT license. No npm publication, paid hosting or standing extraction is implied by installing this preview.
Available Tools
20 toolsshadowgraph_ack_reviewADestructive
Acknowledge one persisted review signal by id, closing it as open work. Use reviewSignalId from shadowgraph_review or shadowgraph_review_context; shadowgraph_review_signals lists stored signals. Decision changes use shadowgraph_update_status or shadowgraph_supersede. Overwrites status and acknowledgedAt in place with no journal entry, so a rebuild cannot reconstruct it; a repeat restamps it.
| Name | Required | Description | Default |
|---|---|---|---|
| id | Yes | Persisted signal id: reviewSignalId from shadowgraph_review or shadowgraph_review_context, or id from shadowgraph_review_signals. A fresh context evaluation can be unpersisted and have no ID. This is not the decisionId. | |
| project | No | Owning project; required unless originId is set, else the write is refused. | |
| originId | No | Capture-origin id; with no project the record belongs to it alone. |
Output Schema
| Name | Required | Description |
|---|---|---|
| id | Yes | Signal identifier, used by shadowgraph_ack_review. |
| kind | Yes | Always "review". |
| title | No | Decision title, when the stored decision has one. |
| reason | Yes | Why it was raised. Identity is this plus decisionId and coverage. |
| status | Yes | open until acknowledged. |
| coverage | No | Exact conditions covered, and part of this identity. |
| createdAt | Yes | ISO 8601 time the signal was raised. |
| decisionId | Yes | The decision this signal is about. |
| acknowledgedAt | Yes | ISO 8601 time of the most recent acknowledgement. |
| alternativesToReconsider | Yes | Alternative labels to look at again. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Goes well beyond the annotations: overwrites status and acknowledgedAt in place, writes no journal entry so a rebuild cannot reconstruct the change, and a repeat call restamps rather than being a no-op — which correctly reinforces idempotentHint=false and destructiveHint=true.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Three sentences, each earning its place: effect, id sourcing plus alternatives, then the durability caveat. Front-loaded with the action before the cautions.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
An output schema exists and the annotations carry the safety profile, so the description only needs the action semantics and the irreversibility caveat — both present. Nothing an agent needs to invoke it correctly is missing.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100% and the schema already explains id provenance, the project/originId requirement, and that this is not decisionId. The description adds no syntax or format detail beyond the schema, so baseline 3 applies.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
Specific verb + resource + effect: 'Acknowledge one persisted review signal by id, closing it as open work'. It explicitly distinguishes itself from shadowgraph_update_status and shadowgraph_supersede, so an agent can route without opening schemas.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Names the upstream tools that produce the id (shadowgraph_review, shadowgraph_review_context) and the one that lists stored signals (shadowgraph_review_signals), then states the exclusion condition: decision changes go to shadowgraph_update_status or shadowgraph_supersede.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
shadowgraph_confidence_evidenceA
Apply one keyed piece of supporting or contradicting evidence to a decision's confidence. Use shadowgraph_record_outcome once the decision has played out, shadowgraph_record_fact for an observation that can reopen it. Reusing key cannot double-count, but restamps the decision and commits a revision; a new observation needs a new key.
| Name | Required | Description | Default |
|---|---|---|---|
| key | Yes | REQUIRED stable dedupe key. Reuse the same key for the same observation so retries cannot double-count; use a NEW key for a genuinely new observation. There is no default, because a generated one would only be stable within a millisecond. | |
| actor | No | Who performed this write, such as an agent or person name. Stored for audit; never used to grant trust. | |
| client | No | Which client software performed this write, such as the host application name. | |
| reason | Yes | Why this evidence matters. Required, non-empty, and kept in the audit history. | |
| project | No | Owning project; required unless originId is set, else the write is refused. | |
| originId | No | Capture-origin id; with no project the record belongs to it alone. | |
| supports | No | Defaults to true. false records contradicting evidence, moving confidence down instead of up. | |
| sessionId | No | Caller-owned identifier that groups related writes in the audit trail. | |
| decisionId | Yes | Identifier of an existing decision, as returned by shadowgraph_record_decision, shadowgraph_search, or shadowgraph_retrieve. | |
| observedAt | No | ISO 8601 time the evidence was observed. Defaults to now. | |
| sourceClass | No | Claimed origin, never proof: agent_claimed (the default), tool_observed, human_confirmed, or production_verified. It weights confidence only. An unrecognised label downgrades to agent_claimed, kept verbatim in sourceRaw. |
Output Schema
| Name | Required | Description |
|---|---|---|
| id | Yes | Stable entity identifier. |
| goal | No | What the decision was trying to achieve. |
| kind | Yes | Entity kind: decision, attempt, memory, fact, relation, review, or alternative. |
| actor | No | Who performed the write. |
| title | No | Short name of the decision. |
| chosen | No | The option that was chosen. |
| client | No | Which client performed the write. |
| status | No | Lifecycle state. Legacy records may carry a value this build does not recognise; shadowgraph_validate reports those. |
| outcome | No | The recorded outcome, or null until one is recorded. |
| project | No | Project namespace; null for an unattributed record or one imported from before projects. |
| evidence | No | Normalised evidence entries: source, type, sourceClass, confidence, observedAt, detail. |
| createdAt | No | ISO 8601 creation time. |
| migration | No | Present only on migrated records; records the legacy value a field was mapped from. |
| sessionId | No | Session identifier recorded with the write. |
| sourceRaw | No | The original origin label when it differed from sourceClass. Audit only; never evidence. |
| updatedAt | No | ISO 8601 time of the last change. |
| confidence | No | Auditable confidence: initial, current (0-1), policy, a history entry per move, and a basis summarising the contributions it was folded from. Legacy records may lack basis. |
| supersedes | No | Identifiers of decisions this one replaced. |
| assumptions | No | Assumptions the decision rests on. Searchable content. |
| reviewAfter | No | ISO 8601 instant after which shadowgraph_maintain marks this decision stale. |
| sourceClass | No | Claimed origin class recorded with the write. A claim, never proof. |
| alternatives | No | Rejected alternatives, each with id, label, reasonRejected, status, and the reopenWhen rules that make it reconsiderable. |
| supersededBy | No | Identifier of the decision that replaced this one. |
| schemaVersion | No | Storage schema version this entity was written under. A value above the build’s own version is preserved rather than downgraded. |
| failedAttempts | No | Attempt identifiers or notes attached to this decision. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare this is a non-read-only, non-idempotent, non-destructive write, so the bar is lower; the description still adds real context by explaining that a reused key cannot double-count but restamps the decision and commits a revision. That nuance reconciles with idempotentHint=false rather than contradicting it. It stops short of covering error conditions or the project/originId refusal rule, which live only in the schema.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Three sentences, each carrying distinct information: purpose, sibling routing, and key semantics. The purpose is front-loaded and there is no filler.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
With 11 parameters, full schema coverage, annotations, and an output schema, the description covers the essentials an agent needs to choose and call this tool correctly. It does not restate the project-unless-originId requirement or the sourceClass weighting, but those are fully documented in structured fields.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100%, so the baseline is 3, but the description adds consequence-level meaning for the key parameter beyond the schema's 'cannot double-count' — namely that reuse restamps the decision and commits a revision. The remaining 10 parameters (actor, client, sourceClass, project, etc.) are left entirely to the schema.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The first sentence gives a specific verb and resource — applying one keyed piece of supporting or contradicting evidence to a decision's confidence — and the scope ('one keyed piece') is stated up front. It names the two nearest siblings (record_outcome, record_fact) so an agent can disambiguate without opening any schema.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
It explicitly routes the agent: use shadowgraph_record_outcome once the decision has played out, and shadowgraph_record_fact for an observation that can reopen it. The final clause also states the rule for this tool's own keying (new observation needs a new key), leaving no inference required.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
shadowgraph_contextA
Read the project working set before planning: decisions, stale facts, failed attempts and fired conditions. shadowgraph_search matches every term; shadowgraph_retrieve adds neighbours; shadowgraph_recall ranks memory; shadowgraph_review_context persists signals. No decision or signal writes. Unmatched-query diagnostics stay in memory until a later save. No immediate revision without an access key; a key saves a revision and audit.
| Name | Required | Description | Default |
|---|---|---|---|
| asOf | No | ISO 8601 instant for relevant: facts and memories valid then, recency ordered from it, and lines derived as of it. | |
| facts | No | Temporary key/value overrides for object rules; unlisted keys use stored facts. Example: facts:{ready:true} tests {key:"ready",value:true}. This does not record a fact or fire a string rule; changedFacts supplies those changed-key signals. | |
| limit | No | Maximum items per collection, 1-1000, applied to each collection independently. Omit for the default of 50. | |
| query | No | Free text. With it or focalId, the response adds relevant: the records in scope that the lexical or graph signal ranks, ahead of the working set. No semantic signal is computed on this read. | |
| compact | No | With query or focalId, true delivers each relevant record as a shortened claim line (T1); false or omitted delivers full records. A line that would omit decisive meaning falls back to the full record. This controls record presentation, not the server tool mode. For example, query:"cache", compact:true adds relevant.items with expansion handles; compact:true alone does not add relevant. | |
| focalId | No | Entity id to rank graph neighbours from. An id outside the scope reaches nothing, like an unknown one. | |
| grantId | No | Alias for accessId; conflicting identifiers are refused. | |
| project | No | Project or confirmed workspace binding; otherwise origin-only. No identity returns an empty scoped view. | |
| accessId | No | Grant ID, rechecked at use. Widens reads only, never write authority. Presenting an access key commits a revision and bounded operational audit: at most one aggregate per grant, surface, outcome and UTC day. Conflicts with a different grantId are refused. | |
| originId | No | Capture-origin id; with no project the record belongs to it alone. | |
| changedFacts | No | Ephemeral changed-key signals for string-form reopenWhen rules; not stored facts. Example: changedFacts:["budget"] fires reopenWhen:["budget"]. Object rules instead read values from facts overrides or stored facts. |
Output Schema
| Name | Required | Description |
|---|---|---|
| notice | Yes | Declared interface metadata, not memory: context is a read, and reviewContext (shadowgraph_review_context) evaluates and persists. |
| project | Yes | The resolved project, or null when unresolved. |
| relevant | No | Present with query or focalId: records in scope ranked on the records themselves, head first. |
| completeness | Yes | Per-collection completeness. context returns several named collections, so one page object cannot describe it. |
| failedAttempts | Yes | Attempts that failed: resultClass failed or, with none and not captured, a result mentioning failure, regression, or error. |
| readProvenance | No | Original read bounds; reuse intersects these with currently valid authority. |
| activeDecisions | Yes | Decisions whose lifecycle status is current: proposed, planned, in_progress, executed, validated, or reconsidered. |
| firedConditions | Yes | Decisions whose recorded review conditions fired, with the conditions and the facts they were computed from. |
| reusableAttempts | No | Attempts whose reusableWhen conditions all hold now. The recorded failure still stands, and this is not authorisation to retry. |
| staleAssumptions | Yes | Facts that are no longer active, such as superseded or expired ones, which earlier decisions may still rest on. |
| conditionDiagnostics | No | Conditions that could not be settled, or that rest on facts which disagree. Neither a breach nor a confirmed-safe decision. |
| belowConfidenceThreshold | Yes | Decisions of any status whose recorded confidence is below the policy threshold. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations declare readOnlyHint=false and the description explains why: it is a read, but presenting an access key 'commits a revision and bounded operational audit', and unmatched-query diagnostics persist in memory until a later save. These are non-obvious side effects that the annotations alone would not convey. It stops short of describing pagination or output shape, but the output schema covers that.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The core purpose and scope are front-loaded in the first sentence, and every subsequent sentence maps to a sibling or a side effect. It is dense and somewhat telegraphic in places ('fired conditions', 'T1'), relying on jargon the agent must infer, which keeps it from a 5.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For an 11-parameter tool, the description supplies the selection logic, the write side effect of accessId, and the statefulness of diagnostics; annotations cover the safety profile and an output schema exists. The remaining gap is that optional fields like asOf, project and focalId are left entirely to the schema, which is acceptable given full coverage.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
With 100% schema coverage the baseline is 3, and the description still adds cross-parameter meaning: the access-key/audit tradeoff for accessId and the in-memory diagnostic retention tied to query. It does not re-explain facts, limit or changedFacts, which the schema already handles well.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
Opens with a specific verb and resource: 'Read the project working set', then enumerates what it returns (decisions, stale facts, failed attempts, fired conditions). It also names the four sibling tools and how each differs, so an agent can select it without opening any schema.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
'Read the project working set before planning' gives explicit timing, and the following clause routes the agent away from shadowgraph_search (exact term matching), shadowgraph_retrieve (neighbours), shadowgraph_recall (ranking) and shadowgraph_review_context (persists signals). This is exactly the when/when-not/alternatives structure the dimension rewards.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
shadowgraph_expandA
Fetch the full current record behind a context line, with its expansion handle as input. shadowgraph_context supplies the handle; flatten its scope into top-level inputs. Own-scope read saves nothing; an access key commits a revision and bounded audit. Returns record, revision status and bounded counterparts. A stale digest yields revision_changed; inaccessible records yield unavailable.
| Name | Required | Description | Default |
|---|---|---|---|
| asOf | No | The line's expansion.asOf, when it has one. | |
| digest | Yes | The line's expansion.digest: the revision the line was derived from. | |
| grantId | No | Alias for accessId; conflicting identifiers are refused. | |
| project | No | Project or confirmed workspace binding; otherwise origin-only. No identity returns an empty scoped view. | |
| accessId | No | Grant ID, rechecked at use. Widens reads only, never write authority. Presenting an access key commits a revision and bounded operational audit: at most one aggregate per grant, surface, outcome and UTC day. Conflicts with a different grantId are refused. | |
| originId | No | Capture-origin id; with no project the record belongs to it alone. | |
| recordId | Yes | The line's expansion.recordId. | |
| derivedAt | No | The line's expansion.derivedAt. A logical purge of the read's own project recorded after it answers purged. | |
| maxExpansions | No | How many structural counterparts to fetch in full, 0-50. Defaults to 5; the rest are marked uninvestigated, with their lines. | |
| derivationVersion | No | The line's expansion.derivationVersion. |
Output Schema
| Name | Required | Description |
|---|---|---|
| record | Yes | The current full record, or null. Never a summary and never the old revision. |
| status | Yes | current: the line came from this revision. revision_changed: the record changed since, and this is the current record. purged: the first purge of the read's own project after the line was logical. unavailable: no record with this id is served in the scope. |
| recordId | Yes | The record the line named. |
| completeness | Yes | Request coverage and any withheld detail. |
| boundRevision | Yes | The revision the line was derived from. |
| investigation | Yes | Counterparts investigated within the budget; null when no record is served. |
| readProvenance | No | Original read bounds; reuse intersects these with currently valid authority. |
| currentRevision | Yes | The live revision; null when no record is served. |
| revisionChanged | Yes | Whether the record changed after the line was derived; null when no record is served. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations declare readOnlyHint=false and idempotentHint=false without explaining why; the description fills that gap by disclosing that presenting an access key commits a revision and a bounded audit while an own-scope read has no side effects. It also enumerates failure modes (stale digest → revision_changed, inaccessible → unavailable), which is behavior an agent cannot infer from the schema.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Front-loaded with purpose, then prerequisite, side effect, return shape and error outcomes — each sentence carries distinct information with no filler. The density of domain jargon makes some clauses ('Own-scope read saves nothing') require a second read, costing a point.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
An output schema exists so return values needn't be spelled out, yet the description still flags the three things an agent must anticipate: record/revision status/counterparts, revision_changed on a stale digest, and unavailable on access failure. With 10 parameters at full schema coverage, nothing material is left undocumented.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100% and the schema itself is unusually descriptive, so the baseline is 3. The description still adds construction guidance ('with its expansion handle as input', 'flatten its scope into top-level inputs') that tells the agent how to derive the arguments rather than just what they are, pushing it to a 4.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb and resource ('Fetch the full current record behind a context line') and names the sibling that produces its input (shadowgraph_context), which lets an agent place it in the workflow. The jargon ('context line', 'expansion handle') is domain-specific and not self-explanatory, keeping it just short of a 5.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Gives an explicit prerequisite chain — shadowgraph_context supplies the handle, then flatten its scope into top-level inputs — and distinguishes the own-scope read from the access-key read by consequence ('saves nothing' vs 'commits a revision and bounded audit'). It stops short of naming a concrete when-not-to-use alternative among the many record_* siblings.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
shadowgraph_maintainA
Age due owned decisions to stale, expire due owned facts, then evaluate reopen rules. shadowgraph_review evaluates without aging; shadowgraph_validate diagnoses integrity. Maintenance does not repair or restore. Uses now or the clock; saves lifecycle changes and signals, even on repeats. Grants widen audited reads, not writes. Returns changed IDs, due items and stored signals, including acknowledged ones.
| Name | Required | Description | Default |
|---|---|---|---|
| now | No | ISO 8601 instant to treat as the current time. Defaults to the real clock; supplying it makes the run deterministic. | |
| facts | No | Temporary key/value overrides for object rules; unlisted keys use stored facts. Example: facts:{ready:true} tests {key:"ready",value:true}. This does not record a fact or fire a string rule; changedFacts supplies those changed-key signals. | |
| grantId | No | Alias for accessId; conflicting identifiers are refused. | |
| project | No | Project or confirmed workspace binding; otherwise origin-only. No identity returns an empty scoped view. | |
| accessId | No | Grant ID, rechecked at use. Widens reads only, never write authority. Presenting an access key commits a revision and bounded operational audit: at most one aggregate per grant, surface, outcome and UTC day. Conflicts with a different grantId are refused. | |
| originId | No | Capture-origin id; with no project the record belongs to it alone. | |
| changedFacts | No | Ephemeral changed-key signals for string-form reopenWhen rules; not stored facts. Example: changedFacts:["budget"] fires reopenWhen:["budget"]. Object rules instead read values from facts overrides or stored facts. |
Output Schema
| Name | Required | Description |
|---|---|---|
| at | Yes | The instant maintenance ran against. |
| due | Yes | Decisions due for reconsideration after the run. |
| diagnostics | No | Conditions that could not be settled, or that rest on facts which disagree. |
| reviewSignals | Yes | Every persisted review signal after the run, open and acknowledged alike. |
| readProvenance | No | Original read bounds; reuse intersects these with currently valid authority. |
| agedDecisionIds | Yes | Compatibility alias of staleDecisionIds for older callers. |
| staleDecisionIds | Yes | Decisions moved to stale because they passed reviewAfter. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Beyond annotations, it discloses that runs use a supplied 'now' or the real clock, that lifecycle changes and signals are persisted even on repeats (directly illuminating the non-idempotent hint), and that grants widen audited reads but never writes. It also scopes mutation: maintenance does not repair or restore, so the absence of destructiveHint is credible and explained.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Six short sentences, front-loaded with the action sequence, each carrying distinct information (scope, alternatives, exclusions, determinism, persistence, privileges, returns). Dense jargon makes it terse but no sentence is redundant.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a 7-parameter mutating tool, the description covers determinism, persistence/idempotency behaviour, authorization semantics, non-repair scope, and return contents. With an output schema present it need not enumerate return fields, and nothing an agent needs to invoke it safely is missing.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100%, so 3 is the floor; the description still adds conceptual meaning for 'now' (determinism), grantId/accessId (read-widening only, audited), and changedFacts (signals feeding reopen evaluation). It does not add format-level detail beyond the schema, so it earns a 4 rather than a 5.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The opening sentence gives a precise three-step verb sequence (age decisions to stale, expire facts, evaluate reopen rules) over named resources, which is far more specific than the tool name alone. It also explicitly distinguishes itself from shadowgraph_review and shadowgraph_validate, so an agent can route without opening schemas.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
It names two alternatives and states the differentiating condition ('review evaluates without aging', 'validate diagnoses integrity') plus an exclusion ('does not repair or restore'). It stops short of stating a positive trigger or addressing signal-oriented siblings like shadowgraph_ack_review, so it is clear but not exhaustive.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
shadowgraph_recallA
Rank scoped memory and records by lexical, vector, graph and temporal signals. shadowgraph_search requires every term; shadowgraph_retrieve adds neighbours; shadowgraph_context prepares a working set. Own-scope read saves nothing; an access key commits a revision and bounded audit. Returns scores and signal availability. No provider/vector means no semantic ranking. Omitted memory scope fields select null, not any user/run.
| Name | Required | Description | Default |
|---|---|---|---|
| asOf | No | ISO 8601 instant to select by valid time, returning what was true then rather than now. Also enables temporal ranking. | |
| limit | No | Maximum items to return, 1-1000; the default is 50 and completeness.limitSource reports which applied. Out of range is rejected, never silently clamped. | |
| query | No | Free text to rank against. An empty query still returns scope-matching records ranked by the remaining signals. | |
| scope | No | Scope selector. Omitted or partial fields mean explicit nulls, not "any": identity is the exact (project, userId, agentId, runId, memoryType, key) tuple, so a run-scoped memory never leaks into a user-only read. | |
| offset | No | Items to skip before this window. Ordering is total and deterministic, so paging cannot drop or duplicate an item. | |
| focalId | No | Entity id to measure graph distance from. Without it the graph signal reports available:false. | |
| grantId | No | Alias for accessId; conflicting identifiers are refused. | |
| project | No | Project or confirmed workspace binding; otherwise origin-only. No identity returns an empty scoped view. | |
| accessId | No | Grant ID, rechecked at use. Widens reads only, never write authority. Presenting an access key commits a revision and bounded operational audit: at most one aggregate per grant, surface, outcome and UTC day. Conflicts with a different grantId are refused. | |
| originId | No | Capture-origin id; with no project the record belongs to it alone. | |
| memoryType | No | Restrict memory candidates to this type. | |
| preferRecent | No | Enable temporal ranking against now. Ignored when asOf is supplied, which already selects a point in time. | |
| queryEmbedding | No | Caller-supplied query vector. Omit to use the configured provider; with neither, the semantic signal reports available:false and a reason. | |
| readProvenance | No | Original expansion bounds; cannot widen access. |
Output Schema
| Name | Required | Description |
|---|---|---|
| page | Yes | The window actually applied to the matching items. |
| items | Yes | The items in this window, in deterministic order. |
| completeness | Yes | Declares exactly what this response left out, so a truncated result can never look complete. |
| readProvenance | No | Original read bounds; reuse intersects these with currently valid authority. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint=false and idempotentHint=false, and the description explains why: an access key 'commits a revision and bounded audit,' while an own-scope read persists nothing. This adds valuable context beyond the annotations, including audit bounding language. It does not detail permission requirements or reversibility, but it meaningfully clarifies the side-effect profile.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is front-loaded with purpose, then alternatives, then behavioral caveats, packing substantial information into five sentences for a 14-parameter tool. Most sentences earn their place, though phrases like 'Own-scope read saves nothing' are telegraphic and slightly opaque. Overall it is efficient and well-structured.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given a complex 14-parameter tool with a full output schema, the description covers the major gotchas: null scope semantics, side effects from access keys, degraded ranking without a provider, and sibling alternatives. The output schema handles return-value details, so the description need not explain them. A few edge behaviors, such as paging or out-of-range limits, are delegated entirely to the schema, which is acceptable but leaves minor gaps.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, so the schema already documents parameters thoroughly; the baseline is 3. The description reinforces a few semantics, notably that omitted scope fields select explicit nulls rather than 'any' and that missing provider/vector disables semantic ranking, but these points largely restate schema content. It does not add syntax or format details beyond the schema.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description states a specific verb and resource: 'Rank scoped memory and records by lexical, vector, graph and temporal signals.' It also explicitly distinguishes this tool from three siblings by naming their contrasting behaviors: search requires every term, retrieve adds neighbours, and context prepares a working set. An agent can identify exactly what this tool does and how it differs from adjacent options.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description names shadowgraph_search, shadowgraph_retrieve, and shadowgraph_context with their distinguishing behaviors, giving the agent a clear basis for choosing among them. It also notes a key usage constraint: 'No provider/vector means no semantic ranking.' However, it stops short of an explicit 'use this when' statement or exclusions, leaving the selection slightly implicit.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
shadowgraph_reconsiderA
Explain review verdicts for one decision or a scoped set, with evidence and completeness. shadowgraph_review lists only due items; shadowgraph_ack_review closes a signal. No choice, confidence or lifecycle changes. Persists deduplicated owned signals and commits a revision. Grants widen audited evaluation, not writes. review_recommended means a trigger; manual_review means unresolved evidence; unchanged requires complete evaluation.
| Name | Required | Description | Default |
|---|---|---|---|
| facts | No | Temporary key/value overrides for object rules; unlisted keys use stored facts. Example: facts:{ready:true} tests {key:"ready",value:true}. This does not record a fact or fire a string rule; changedFacts supplies those changed-key signals. | |
| grantId | No | Alias for accessId; conflicting identifiers are refused. | |
| project | No | Project or confirmed workspace binding; otherwise origin-only. No identity returns an empty scoped view. | |
| accessId | No | Grant ID, rechecked at use. Widens reads only, never write authority. Presenting an access key commits a revision and bounded operational audit: at most one aggregate per grant, surface, outcome and UTC day. Conflicts with a different grantId are refused. | |
| originId | No | Capture-origin id; with no project the record belongs to it alone. | |
| decisionId | No | Limit the resolved project/origin to this decision; the ID does not supply scope. Unknown, out-of-scope, archived, abandoned or superseded decisions are rejected. Omit to explain all eligible decisions in scope. | |
| changedFacts | No | Ephemeral changed-key signals for string-form reopenWhen rules; not stored facts. Example: changedFacts:["budget"] fires reopenWhen:["budget"]. Object rules instead read values from facts overrides or stored facts. |
Output Schema
| Name | Required | Description |
|---|---|---|
| scope | Yes | What was reconsidered. |
| verdict | Yes | Aggregate over every decision in scope: a definite trigger outranks uncertainty, which outranks unchanged. |
| decisions | Yes | One entry per decision in scope, including decisions with nothing to report. |
| readProvenance | No | Original read bounds; reuse intersects these with currently valid authority. |
| evaluationCompleteness | Yes | partial when any decision in scope was partial. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already say the tool is not read-only, not destructive, and not idempotent; the description adds important context: it persists deduplicated owned signals and commits a revision, does not change choice/confidence/lifecycle, and grants only widen audited evaluation. It also defines verdict outcomes (review_recommended, manual_review, unchanged), which helps an agent interpret behavior. It leaves somewhat unclear exactly what the committed revision changes if lifecycle/choice/confidence are untouched.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is front-loaded with purpose, then sibling differentiation, then behavioral constraints. Most sentences earn their place, though the final three verdict definitions are terse and somewhat cryptic without more context.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
An output schema exists and the parameters are fully described, so the description does not need to explain return values or parameter details. Given the complexity, it covers purpose, sibling alternatives, mutation scope, grant semantics, and verdict meanings; the only gap is a clearer explanation of what 'reconsider' does operationally versus merely explaining.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, so the schema already documents all seven parameters in detail. The description adds no parameter-specific guidance beyond the broad mention of decisions, scoped sets, evidence, completeness, and grants; with full schema coverage this meets the baseline.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description states a specific action: explain review verdicts for a decision or scoped set, including evidence and completeness. It also differentiates itself from sibling tools by naming shadowgraph_review (lists due items) and shadowgraph_ack_review (closes a signal). The core verb is 'explain' rather than the tool name's 'reconsider,' which creates minor ambiguity about whether it also re-evaluates.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
It gives clear contrast with two siblings: use shadowgraph_review to list only due items and shadowgraph_ack_review to close a signal, implying this tool is for explaining verdicts. It also scopes grants to widening audited evaluation rather than writes, guiding access usage. It stops short of explicit when-not-to-use conditions beyond those sibling contrasts.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
shadowgraph_record_attemptA
Record one attempt with its result; returns the stored attempt. Use shadowgraph_record_decision for a choice; shadowgraph_record_outcome updates an existing decision and its confidence. An attempt is a separate record. Appends an attempt and journal entry and commits a revision; idempotencyKey prevents duplicate retries. resultClass overrides wording-based failure classification.
| Name | Required | Description | Default |
|---|---|---|---|
| actor | No | Who performed this write, such as an agent or person name. Stored for audit; never used to grant trust. | |
| client | No | Which client software performed this write, such as the host application name. | |
| reason | No | Why it turned out that way. Searchable content. | |
| result | Yes | What happened. Required, non-empty, and searchable content. With no resultClass, wording such as failed, error, or regression is what places the attempt in shadowgraph_context failedAttempts; a captured attempt's wording is never read. | |
| project | No | Owning project; required unless originId is set, else the write is refused. | |
| originId | No | Capture-origin id; with no project the record belongs to it alone. | |
| solution | Yes | What was tried. Required, non-empty, and searchable content. | |
| sessionId | No | Caller-owned identifier that groups related writes in the audit trail. | |
| environment | No | Where it was tried, such as a runtime, OS, or version. Searchable content, so a later attempt can be matched to the same environment. | |
| resultClass | No | Classify the result instead of leaving it to the wording heuristic. Set it when the result text does not say failed, error, or regression, or when it does but the attempt did not fail. | |
| sourceClass | No | Claimed origin, never proof: agent_claimed (the default), tool_observed, human_confirmed, or production_verified. It weights confidence only. An unrecognised label downgrades to agent_claimed, kept verbatim in sourceRaw. | |
| idempotencyKey | No | Retry identity within the project or origin and operation (also scope/type/key for memory). Reuse it to recover the original canonical ID; this key is never an entity ID. |
Output Schema
| Name | Required | Description |
|---|---|---|
| id | Yes | Stable entity identifier. |
| kind | Yes | Entity kind: decision, attempt, memory, fact, relation, review, or alternative. |
| actor | No | Who performed the write. |
| client | No | Which client performed the write. |
| reason | No | Why it turned out that way, verbatim as recorded. |
| result | No | What happened. |
| project | No | Project namespace; null for an unattributed record or one imported from before projects. |
| solution | No | What was tried. |
| createdAt | No | ISO 8601 creation time. |
| relatedTo | No | Identifiers of related entities. |
| sessionId | No | Session identifier recorded with the write. |
| sourceRaw | No | The original origin label when it differed from sourceClass. Audit only; never evidence. |
| updatedAt | No | ISO 8601 time of the last change. |
| causalClaim | No | The cause, attributed apart from the attempt: state recorded (the reason, agent_claimed), unknown, not_recorded, or legacy_freetext (a reason stored before causes were, never classed or evidenced). |
| environment | No | Where it was tried. |
| resultClass | No | Declared or observed: failed, succeeded, or inconclusive. If absent: not captured (no captureRef or outcomeEvidence), the wording heuristic classifies; captured, the outcome is undetermined. |
| sourceClass | No | Claimed origin class recorded with the write. A claim, never proof. |
| reusableWhen | No | Conditions recorded for reusing the attempt. All must hold, and none may be unresolved. |
| schemaVersion | No | Storage schema version this entity was written under. A value above the build’s own version is preserved rather than downgraded. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Goes well beyond the annotations by disclosing side effects ('Appends an attempt and journal entry and commits a revision'), retry semantics via idempotencyKey, and that resultClass overrides the wording-based failure classifier that feeds shadowgraph_context failedAttempts. It does not address permissions, ordering, or what happens if the commit fails, and there is mild tension between idempotentHint=false and the claim that idempotencyKey prevents duplicate retries (the key is opt-in, so not a true contradiction).
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Four front-loaded sentences: purpose+return, sibling routing, side effects, then parameter notes. Every sentence carries information, though the clipped phrasing ('An attempt is a separate record.') reads more telegraphic than explanatory.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
With 12 parameters, an output schema, full annotation coverage and 100% schema description coverage, the description supplies what structured fields cannot: sibling routing and commit side effects. Remaining gaps are minor given the rich schema, though the interaction between a non-idempotent annotation and an optional idempotency key could have been spelled out.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is already 100%, so the baseline is 3; the description still adds value by explaining that idempotencyKey guards duplicate retries and that resultClass bypasses the wording heuristic. It does not touch the required project/originId rule or sourceClass weighting, but those are documented in the schema.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb and resource ('Record one attempt with its result'), states the return ('returns the stored attempt'), and explicitly distinguishes itself from shadowgraph_record_decision and shadowgraph_record_outcome. An agent can pick this tool without opening any schema.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Names two alternative siblings and the condition that selects each ('for a choice' → record_decision; 'updates an existing decision and its confidence' → record_outcome), plus the clarifying rule 'An attempt is a separate record.' The routing decision is fully resolved in the description.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
shadowgraph_record_decisionA
Record one decision: chosen option, assumptions, evidence, and rejected alternatives with reopenWhen rules. Use shadowgraph_record_attempt for something tried, shadowgraph_record_fact for an observation, shadowgraph_remember for a note. Appends a decision and a journal entry; without idempotencyKey each call adds another and commits a revision.
| Name | Required | Description | Default |
|---|---|---|---|
| goal | No | What the decision is meant to achieve. Searchable content. | |
| actor | No | Who performed this write, such as an agent or person name. Stored for audit; never used to grant trust. | |
| title | Yes | Short name of the decision. Required, non-empty, and searchable content. | |
| chosen | Yes | The option actually chosen. Required, non-empty, and searchable content. | |
| client | No | Which client software performed this write, such as the host application name. | |
| project | No | Owning project; required unless originId is set, else the write is refused. | |
| evidence | No | Supporting evidence. Counted as declared evidence in the confidence basis, but never re-checked. | |
| originId | No | Capture-origin id; with no project the record belongs to it alone. | |
| sessionId | No | Caller-owned identifier that groups related writes in the audit trail. | |
| confidence | No | Starting confidence, 0-1. Defaults to 0.5. Later outcomes and evidence move it from this baseline; it is a degree of belief, never a verification status. | |
| assumptions | No | What the decision takes for granted. Record each as a fact too if it should be able to reopen the decision. | |
| sourceClass | No | Claimed origin, never proof: agent_claimed (the default), tool_observed, human_confirmed, or production_verified. It weights confidence only. An unrecognised label downgrades to agent_claimed, kept verbatim in sourceRaw. | |
| alternatives | No | Options considered and rejected. Alternatives belong to the decision and have no separate write API; they are what shadowgraph_review reconsiders. | |
| idempotencyKey | No | Retry identity within the project or origin and operation (also scope/type/key for memory). Reuse it to recover the original canonical ID; this key is never an entity ID. |
Output Schema
| Name | Required | Description |
|---|---|---|
| id | Yes | Stable entity identifier. |
| goal | No | What the decision was trying to achieve. |
| kind | Yes | Entity kind: decision, attempt, memory, fact, relation, review, or alternative. |
| actor | No | Who performed the write. |
| title | No | Short name of the decision. |
| chosen | No | The option that was chosen. |
| client | No | Which client performed the write. |
| status | No | Lifecycle state. Legacy records may carry a value this build does not recognise; shadowgraph_validate reports those. |
| outcome | No | The recorded outcome, or null until one is recorded. |
| project | No | Project namespace; null for an unattributed record or one imported from before projects. |
| evidence | No | Normalised evidence entries: source, type, sourceClass, confidence, observedAt, detail. |
| createdAt | No | ISO 8601 creation time. |
| migration | No | Present only on migrated records; records the legacy value a field was mapped from. |
| sessionId | No | Session identifier recorded with the write. |
| sourceRaw | No | The original origin label when it differed from sourceClass. Audit only; never evidence. |
| updatedAt | No | ISO 8601 time of the last change. |
| confidence | No | Auditable confidence: initial, current (0-1), policy, a history entry per move, and a basis summarising the contributions it was folded from. Legacy records may lack basis. |
| supersedes | No | Identifiers of decisions this one replaced. |
| assumptions | No | Assumptions the decision rests on. Searchable content. |
| reviewAfter | No | ISO 8601 instant after which shadowgraph_maintain marks this decision stale. |
| sourceClass | No | Claimed origin class recorded with the write. A claim, never proof. |
| alternatives | No | Rejected alternatives, each with id, label, reasonRejected, status, and the reopenWhen rules that make it reconsiderable. |
| supersededBy | No | Identifier of the decision that replaced this one. |
| schemaVersion | No | Storage schema version this entity was written under. A value above the build’s own version is preserved rather than downgraded. |
| failedAttempts | No | Attempt identifiers or notes attached to this decision. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Goes beyond the annotations by disclosing what a call actually produces — a decision plus a journal entry and a committed revision — and by warning that without idempotencyKey each call creates another record. That is real behavioral value not derivable from idempotentHint=false alone. It does not discuss permissions, refusals on missing project/originId, or error modes, which the schema covers but the description does not surface.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Three sentences: what it records, where to go instead, and what happens on the write. Front-loaded with the core action and no filler; the routing sentence is the exact length needed.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
With an output schema present, return values need no explanation; the description still contributes the creation/duplication semantics and sibling routing an agent needs to call this correctly. Nothing material is missing for a 14-parameter, 2-required record tool.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, so the schema already carries parameter meaning and the baseline of 3 applies. The description's mention of chosen/assumptions/evidence/alternatives/reopenWhen mirrors fields rather than adding format or constraint detail beyond them.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb and resource — 'Record one decision' — and immediately enumerates what a decision contains (chosen option, assumptions, evidence, rejected alternatives with reopenWhen rules), which separates it from a generic write. It also names three sibling tools it is not, so an agent can disambiguate without opening schemas.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Explicitly routes the agent: record_attempt for something tried, record_fact for an observation, remember for a note. The condition selecting this tool versus those alternatives is stated unambiguously.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
shadowgraph_record_factA
Record one observed fact as a project and key, with a claimed provenance class and optional validity window. Use for the fact keys reopenWhen rules name; shadowgraph_remember stores durable memory that is not an observation. Supersedes the previous active fact, keeping it as history. No input can make a fact verified. Each call commits a revision.
| Name | Required | Description | Default |
|---|---|---|---|
| key | Yes | Fact name, unique per project among active facts. Required and non-empty. Use the same key that a decision’s reopenWhen rules refer to. | |
| actor | No | Who performed this write, such as an agent or person name. Stored for audit; never used to grant trust. | |
| value | No | Any lossless JSON value: string, finite number, boolean, null, array, or object. | |
| client | No | Which client software performed this write, such as the host application name. | |
| source | No | Legacy alias for sourceClass. An unknown label downgrades to agent_claimed with the raw label kept in sourceRaw. | |
| project | No | Owning project; required unless originId is set, else the write is refused. | |
| originId | No | Capture-origin id; with no project the record belongs to it alone. | |
| expiresAt | No | ISO 8601 instant after which shadowgraph_maintain expires this fact. Combined with validTo, the earlier boundary wins. | |
| sessionId | No | Caller-owned identifier that groups related writes in the audit trail. | |
| confidence | No | How much the caller trusts this observation, 0-1. Defaults to 0.5. It does not verify anything. | |
| sourceClass | No | Claimed origin, never proof: agent_claimed (the default), tool_observed, human_confirmed, or production_verified. It weights confidence only. An unrecognised label downgrades to agent_claimed, kept verbatim in sourceRaw. | |
| idempotencyKey | No | Retry identity within the project or origin and operation (also scope/type/key for memory). Reuse it to recover the original canonical ID; this key is never an entity ID. | |
| verificationStatus | No | Only "contradicted" may be set by a caller, because it lowers trust. "verified" and "expired" are rejected: verification is not self-assertable and expiry is owned by shadowgraph_maintain. |
Output Schema
| Name | Required | Description |
|---|---|---|
| id | No | Stable entity identifier. |
| key | Yes | Fact name, unique per project among active facts. |
| kind | No | Entity kind: decision, attempt, memory, fact, relation, review, or alternative. |
| actor | No | Who performed the write. |
| value | No | The observed value, any lossless JSON value. |
| client | No | Which client performed the write. |
| source | No | Legacy alias of sourceClass, retained for compatibility. |
| status | No | active, superseded, or expired. |
| project | No | Project namespace; null for an unattributed record or one imported from before projects. |
| temporal | No | Bi-temporal window: validFrom, validTo, recordedAt, invalidatedAt. |
| createdAt | No | ISO 8601 creation time. |
| expiresAt | No | Caller-declared expiry instant, or null. |
| sessionId | No | Session identifier recorded with the write. |
| sourceRaw | No | The original origin label when it differed from sourceClass. Audit only; never evidence. |
| updatedAt | No | ISO 8601 time of the last change. |
| confidence | No | Caller-declared confidence in the observation, 0-1. |
| observedAt | No | ISO 8601 time the fact was observed. |
| sourceClass | No | Claimed origin class recorded with the write. A claim, never proof. |
| verification | No | Present only on a signed verification: the attestation this build checked. |
| schemaVersion | No | Storage schema version this entity was written under. A value above the build’s own version is preserved rather than downgraded. |
| validityPolicy | No | Declared expiry inputs and the effective expiration boundary derived from them. |
| verificationStatus | No | unverified, contradicted, expired, or verified. Only the separately configured signed-evidence verifier can produce verified. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare the write/non-idempotent/non-destructive profile, yet the description still adds real semantics: superseding keeps the prior fact as history, each call commits a revision, and no input can produce a verified fact. It stops short of describing response shape or failure modes, but the safety-relevant behavior is well covered.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Five short sentences, zero filler, with the core action front-loaded and the sibling disambiguation immediately after. Each remaining sentence contributes a distinct constraint (supersede, no self-verification, revision commit).
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
With 13 parameters, an output schema, and full annotation coverage, the description supplies exactly what structured fields cannot: supersede/history behavior, the trust ceiling, revision-per-call semantics, and sibling routing. Nothing an agent needs before calling is missing.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100% and the parameter descriptions already carry the subtle semantics (sourceClass downgrade, verificationStatus restrictions, idempotencyKey scope). The description only frames the required identity and the optional window at a high level, so it does not meaningfully exceed the schema.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb and resource ("Record one observed fact") plus the identity model (project + key) and the two payload dimensions (provenance class, validity window). It explicitly separates itself from shadowgraph_remember, so an agent can route without opening either schema.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Gives an affirmative trigger ("Use for the fact keys reopenWhen rules name") and a named alternative with the discriminating condition ("shadowgraph_remember stores durable memory that is not an observation"). This is explicit when-to-use and when-not-to-use in one sentence.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
shadowgraph_record_outcomeA
Record how a decision turned out and move its confidence by an evidence-weighted amount. shadowgraph_confidence_evidence records evidence short of an outcome, shadowgraph_update_status changes the lifecycle state. One outcome contribution per decision: re-recording replaces it, updates the decision timestamp and commits a revision; it does not change lifecycle status.
| Name | Required | Description | Default |
|---|---|---|---|
| outcome | Yes | The outcome to record. | |
| project | No | Owning project; required unless originId is set, else the write is refused. | |
| originId | No | Capture-origin id; with no project the record belongs to it alone. | |
| decisionId | Yes | Identifier of an existing decision, as returned by shadowgraph_record_decision, shadowgraph_search, or shadowgraph_retrieve. |
Output Schema
| Name | Required | Description |
|---|---|---|
| id | Yes | Stable entity identifier. |
| goal | No | What the decision was trying to achieve. |
| kind | Yes | Entity kind: decision, attempt, memory, fact, relation, review, or alternative. |
| actor | No | Who performed the write. |
| title | No | Short name of the decision. |
| chosen | No | The option that was chosen. |
| client | No | Which client performed the write. |
| status | No | Lifecycle state. Legacy records may carry a value this build does not recognise; shadowgraph_validate reports those. |
| outcome | No | The recorded outcome, or null until one is recorded. |
| project | No | Project namespace; null for an unattributed record or one imported from before projects. |
| evidence | No | Normalised evidence entries: source, type, sourceClass, confidence, observedAt, detail. |
| createdAt | No | ISO 8601 creation time. |
| migration | No | Present only on migrated records; records the legacy value a field was mapped from. |
| sessionId | No | Session identifier recorded with the write. |
| sourceRaw | No | The original origin label when it differed from sourceClass. Audit only; never evidence. |
| updatedAt | No | ISO 8601 time of the last change. |
| confidence | No | Auditable confidence: initial, current (0-1), policy, a history entry per move, and a basis summarising the contributions it was folded from. Legacy records may lack basis. |
| supersedes | No | Identifiers of decisions this one replaced. |
| assumptions | No | Assumptions the decision rests on. Searchable content. |
| reviewAfter | No | ISO 8601 instant after which shadowgraph_maintain marks this decision stale. |
| sourceClass | No | Claimed origin class recorded with the write. A claim, never proof. |
| alternatives | No | Rejected alternatives, each with id, label, reasonRejected, status, and the reopenWhen rules that make it reconsiderable. |
| supersededBy | No | Identifier of the decision that replaced this one. |
| schemaVersion | No | Storage schema version this entity was written under. A value above the build’s own version is preserved rather than downgraded. |
| failedAttempts | No | Attempt identifiers or notes attached to this decision. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations only say write, non-idempotent, non-destructive; the description goes further by disclosing that re-recording replaces the prior contribution, bumps the decision timestamp, and commits a revision without altering lifecycle status. That is real behavioral context beyond the annotations, though it says nothing about failure modes or what the revision commit implies for callers.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Three sentences, all load-bearing, with the core action front-loaded and sibling routing deferred to sentence two. It is dense but not padded; a shorter form would lose the replacement and lifecycle carve-outs.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
With a full output schema and complete parameter descriptions, the description only needs to carry differentiation and write semantics, which it does. The one gap is that the persistence/revision consequences of repeated calls are stated but not fully explained for an agent deciding whether replacement is safe.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is already 100%, including the enum semantics for status and the weighting role of sourceClass, so the description adds little parameter-level meaning. Only the 'evidence-weighted amount' phrasing gestures at how outcome.status and sourceClass combine, which the schema already explains.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb and resource ('Record how a decision turned out') plus the side effect ('move its confidence by an evidence-weighted amount'), which no sibling name implies. It then explicitly distinguishes itself from shadowgraph_confidence_evidence and shadowgraph_update_status.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Names two concrete alternatives with the condition that selects each: evidence short of an outcome goes to confidence_evidence, lifecycle changes go to update_status. It also states the one-outcome-per-decision rule that constrains repeated use.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
shadowgraph_rememberA
Add or reconcile one scoped memory, or apply an ADD/UPDATE/DELETE/NOOP plan, by identity tuple. Use shadowgraph_record_decision for a choice, shadowgraph_record_fact for an observation, shadowgraph_recall to read memory back. Identical content is a NOOP, new content supersedes and keeps history, DELETE invalidates; every call commits a revision.
| Name | Required | Description | Default |
|---|---|---|---|
| key | No | Stable caller-chosen name within this scope and type, such as hotel-style. Reusing it reconciles that memory rather than adding a second one. | |
| tags | No | Free-form labels stored with the memory. Part of the compared content, so changing them produces a new version. | |
| text | No | The memory content itself. Stored verbatim, searched as content, and compared to decide ADD, UPDATE, or NOOP. | |
| actor | No | Who performed this write, such as an agent or person name. Stored for audit; never used to grant trust. | |
| scope | No | Scope selector. Omitted or partial fields mean explicit nulls, not "any": identity is the exact (project, userId, agentId, runId, memoryType, key) tuple, so a run-scoped memory never leaks into a user-only read. | |
| client | No | Which client software performed this write, such as the host application name. | |
| project | No | Owning project; required unless originId is set, else the write is refused. | |
| validTo | No | ISO 8601 instant after which it stops being true, or null for open-ended. Must be later than validFrom. | |
| metadata | No | Caller-owned JSON object kept with the memory. Part of the compared content, so changing it produces a new version. | |
| originId | No | Capture-origin id; with no project the record belongs to it alone. | |
| embedding | No | Caller-supplied vector for this text. Omit to use the configured embedding provider; with no provider the record is still stored and recall reports semantic.available=false instead of renaming lexical overlap as semantic. | |
| sessionId | No | Caller-owned identifier that groups related writes in the audit trail. | |
| validFrom | No | ISO 8601 instant from which this memory is true in the modeled world. Defaults to the write time. Writes for one identity must arrive in non-decreasing validFrom order. | |
| memoryType | No | Which kind of memory this is, and part of its identity. preference and profile are durable user facts, goal a desired state, instruction an operating constraint, procedure reusable steps, episode a recallable event, note general knowledge. | |
| operations | No | A batch plan. Supply this instead of a single memory, typically from an extraction step. Every operation is validated before the first one is applied, so a malformed late operation cannot leave a half-applied batch. | |
| sourceClass | No | Claimed origin, never proof: agent_claimed (the default), tool_observed, human_confirmed, or production_verified. It weights confidence only. An unrecognised label downgrades to agent_claimed, kept verbatim in sourceRaw. | |
| idempotencyKey | No | Retry identity within the project or origin and operation (also scope/type/key for memory). Reuse it to recover the original canonical ID; this key is never an entity ID. |
Output Schema
| Name | Required | Description |
|---|---|---|
No output parameters | ||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Goes well beyond the annotations: identical content is a NOOP, new content supersedes while keeping history, DELETE invalidates rather than erases, and every call commits a revision — which also reconciles cleanly with idempotentHint=false. This is exactly the mutation/versioning context an agent needs before writing.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Four sentences, front-loaded with the capability, then routing, then versioning semantics. No filler and nothing repeated from the schema.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a 17-parameter, nested-schema write tool with an output schema, the description covers purpose, alternatives, and revision semantics adequately. It leaves edge cases like all-or-nothing batch validation and the project/originId requirement to the schema, which is acceptable but slightly under-advertised for such a complex tool.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100% and every parameter already carries a rich description (identity tuple semantics, validFrom ordering, embedding fallback, idempotencyKey reuse), so the baseline is 3. The description restates the identity-tuple concept but adds no parameter-level syntax or format detail beyond what the schema supplies.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb set (add/reconcile, apply a plan) on a specific resource (scoped memory) and names the identity tuple as the selector. It explicitly distinguishes itself from shadowgraph_record_decision and shadowgraph_record_fact, so an agent can tell which writer to pick without opening schemas.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Gives explicit routing rules: use record_decision for a choice, record_fact for an observation, recall to read back. That covers the main confusable siblings, but it doesn't mention when this tool is NOT appropriate versus the remaining writers (record_attempt, record_outcome, maintain) or when to prefer the batch plan over a single write.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
shadowgraph_retrieveA
Find content matches and their one-hop graph neighbours. shadowgraph_search returns matches only; shadowgraph_recall ranks relevance; shadowgraph_context prepares a working set. Own-scope read saves nothing; an access key commits a revision and bounded audit. Returns paginated records with match/relationship reasons. Every term must match a seed; neighbours need not match. Both stay in scope.
| Name | Required | Description | Default |
|---|---|---|---|
| kind | No | Restrict results to decisions or to attempts. A structured filter, never a content match. | |
| limit | No | Maximum items to return, 1-1000; the default is 50 and completeness.limitSource reports which applied. Out of range is rejected, never silently clamped. | |
| query | No | Whitespace-separated terms matched against the declared content fields (title, goal, chosen, assumption, evidence, alternative, attempt solution, attempt result, attempt reason, environment), exactly as in shadowgraph_search. Omit to retrieve by filters alone. | |
| offset | No | Items to skip before this window. Ordering is total and deterministic, so paging cannot drop or duplicate an item. | |
| status | No | Return only decisions in this lifecycle state. A structured filter, so matching it is never counted as a content match. | |
| grantId | No | Alias for accessId; conflicting identifiers are refused. | |
| project | No | Project or confirmed workspace binding; otherwise origin-only. No identity returns an empty scoped view. | |
| accessId | No | Grant ID, rechecked at use. Widens reads only, never write authority. Presenting an access key commits a revision and bounded operational audit: at most one aggregate per grant, surface, outcome and UTC day. Conflicts with a different grantId are refused. | |
| originId | No | Capture-origin id; with no project the record belongs to it alone. | |
| minConfidence | No | Return only decisions whose current confidence is at least this value, 0-1. A structured filter, never a content match. | |
| readProvenance | No | Original expansion bounds; cannot widen access. |
Output Schema
| Name | Required | Description |
|---|---|---|
| page | Yes | The window actually applied to the matching items. |
| items | Yes | The items in this window, in deterministic order. |
| completeness | Yes | Declares exactly what this response left out, so a truncated result can never look complete. |
| readProvenance | No | Original read bounds; reuse intersects these with currently valid authority. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Adds substantial non-obvious behavior beyond annotations: an access key commits a revision and a bounded audit (at most one aggregate per grant/surface/outcome/UTC day), which explains the readOnlyHint=false and idempotentHint=false flags rather than contradicting them. Also discloses total deterministic ordering, rejection-not-clamping on limit, and that results carry match/relationship reasons.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Front-loaded with the core purpose and alternatives, with no filler sentences. Some clauses are telegraphic to the point of opacity ('Own-scope read saves nothing'), which costs a bit of first-read clarity but keeps the payload dense.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For an 11-parameter, nested-object, output-schema-backed read tool, the description covers matching semantics, scope, paging behavior, audit side effects, and result shape — everything an agent needs before calling, without restating the return schema.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100%, so baseline is 3; the description nonetheless adds semantics the schema does not — 'every term must match a seed; neighbours need not match' clarifies query matching scope, and 'both stay in scope' constrains the result set. Structured filters (kind, status, minConfidence) being 'never a content match' is reinforced in the description.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb and resource — 'Find content matches and their one-hop graph neighbours' — and immediately contrasts with three named siblings (shadowgraph_search, shadowgraph_recall, shadowgraph_context). An agent can distinguish this from every sibling without opening a schema.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Explicitly positions the tool against alternatives: search returns matches only, recall ranks relevance, context prepares a working set — implying this is the one that adds neighbour expansion. Lacks an explicit 'do not use when' or a stated prerequisite, but the routing information is clear.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
shadowgraph_reviewA
Evaluate reopen rules and return due decisions as { items, completeness }, with signal IDs. shadowgraph_reconsider explains all verdicts; shadowgraph_review_context adds the working set; shadowgraph_ack_review closes a signal. Persists deduplicated owned signals; even repeats commit a revision. Grants widen audited evaluation, not signal writes. No choice or lifecycle changes.
| Name | Required | Description | Default |
|---|---|---|---|
| facts | No | Temporary key/value overrides for object rules; unlisted keys use stored facts. Example: facts:{ready:true} tests {key:"ready",value:true}. This does not record a fact or fire a string rule; changedFacts supplies those changed-key signals. | |
| grantId | No | Alias for accessId; conflicting identifiers are refused. | |
| project | No | Project or confirmed workspace binding; otherwise origin-only. No identity returns an empty scoped view. | |
| accessId | No | Grant ID, rechecked at use. Widens reads only, never write authority. Presenting an access key commits a revision and bounded operational audit: at most one aggregate per grant, surface, outcome and UTC day. Conflicts with a different grantId are refused. | |
| originId | No | Capture-origin id; with no project the record belongs to it alone. | |
| changedFacts | No | Ephemeral changed-key signals for string-form reopenWhen rules; not stored facts. Example: changedFacts:["budget"] fires reopenWhen:["budget"]. Object rules instead read values from facts overrides or stored facts. |
Output Schema
| Name | Required | Description |
|---|---|---|
| items | Yes | All known matching items inside this boundary. |
| completeness | Yes | Declares exactly what this response left out, so a truncated result can never look complete. |
| readProvenance | No | Original read bounds; reuse intersects these with currently valid authority. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations declare non-readonly, non-idempotent, non-destructive, but the description adds real behavioral context: it persists deduplicated owned signals, repeats still commit a revision, grants widen evaluation but not signal writes, and no lifecycle changes occur. That meaningfully extends the annotations, though the phrasing is dense.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Front-loaded with the purpose and output shape, then routing to siblings, then persistence semantics. Dense but each clause carries information (dedup, revision-on-repeat, grant scope). Minor cost: the jargon-heavy compression makes it harder to parse on first read.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Output schema exists, so the description needn't detail return values, and it still names the shape. For a 6-param, zero-required mutation with nested params, it covers persistence and audit behavior well. What's missing is a plain-language statement of what a 'signal' or 'reopen rule' is for an uninitiated agent.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, so the schema already documents facts, changedFacts, grantId, accessId, project, and originId thoroughly. The description adds no parameter-level detail beyond what the schema provides, so baseline 3 applies.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb+resource ('Evaluate reopen rules and return due decisions') and even names the return shape ({items, completeness}). It distinguishes itself from siblings by routing the reader to shadowgraph_reconsider, review_context, and ack_review. The only weakness is domain jargon ('reopen rules', 'due decisions') that isn't grounded for a newcomer.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Explicitly maps the nearby alternatives: reconsider explains verdicts, review_context adds the working set, ack_review closes a signal, so the agent can pick among them. It does not, however, contrast against shadowgraph_review_signals, a sibling that sounds closely related, nor state when NOT to use this tool.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
shadowgraph_review_contextA
Evaluate reopen rules, persist signals and return the project working set. shadowgraph_context does not save signals; shadowgraph_review also persists signals but returns only due items. shadowgraph_ack_review closes a returned signal. Deduplicates owned signals and commits a revision on every call. Grants widen audited evaluation, never writes. No choice or lifecycle changes.
| Name | Required | Description | Default |
|---|---|---|---|
| facts | No | Temporary key/value overrides for object rules; unlisted keys use stored facts. Example: facts:{ready:true} tests {key:"ready",value:true}. This does not record a fact or fire a string rule; changedFacts supplies those changed-key signals. | |
| limit | No | Maximum items per collection, 1-1000, applied to each collection independently. Omit for the default of 50. | |
| grantId | No | Alias for accessId; conflicting identifiers are refused. | |
| project | No | Project or confirmed workspace binding; otherwise origin-only. No identity returns an empty scoped view. | |
| accessId | No | Grant ID, rechecked at use. Widens reads only, never write authority. Presenting an access key commits a revision and bounded operational audit: at most one aggregate per grant, surface, outcome and UTC day. Conflicts with a different grantId are refused. | |
| originId | No | Capture-origin id; with no project the record belongs to it alone. | |
| changedFacts | No | Ephemeral changed-key signals for string-form reopenWhen rules; not stored facts. Example: changedFacts:["budget"] fires reopenWhen:["budget"]. Object rules instead read values from facts overrides or stored facts. |
Output Schema
| Name | Required | Description |
|---|---|---|
| project | Yes | The resolved project, or null when unresolved. |
| openReviews | Yes | Decisions currently due for reconsideration. |
| completeness | Yes | Per-collection completeness. context returns several named collections, so one page object cannot describe it. |
| readProvenance | No | Original read bounds; reuse intersects these with currently valid authority. |
| activeDecisions | Yes | Decisions in a current, actionable state: proposed, planned, in_progress, executed, validated, or reconsidered. |
| reusableAttempts | No | Attempts whose reusableWhen conditions all hold now. Worth reconsidering, not authorised to retry. |
| staleAssumptions | Yes | Facts that are no longer active, such as superseded or expired ones, which earlier decisions may still rest on. |
| suggestedQuestions | Yes | Questions for the low-confidence decisions in this project. |
| conditionDiagnostics | No | Conditions that could not be settled, or that rest on facts which disagree. Neither a breach nor a confirmed-safe decision. |
| failedAttemptsToAvoid | Yes | Attempts that failed: resultClass failed or, with none and not captured, a result mentioning failure, regression, or error. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Beyond the annotations, the description discloses important side effects: it deduplicates owned signals and commits a revision on every call. It also clarifies the grant boundary ('never writes') and scopes out choice or lifecycle changes, which is valuable behavioral context for a mutating review tool.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The definition is front-loaded with the core purpose and remains compact despite covering several sibling distinctions. Some phrases such as 'working set' and 'No choice or lifecycle changes' are dense or under-explained, but the overall structure is efficient and purpose-first.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given 100% schema coverage, existing annotations, and an output schema, the description does not need to explain every parameter or return value. It covers purpose, sibling routing, mutation side effects, and grant behavior, though 'project working set' remains somewhat vague and the scope of persisted signals could be clearer.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, so the baseline is 3. The description reinforces grant semantics with 'Grants widen audited evaluation, never writes,' but this largely restates what accessId/grantId already document and does not add meaning for facts, changedFacts, project, originId, or limit.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description names specific actions and outputs: evaluate reopen rules, persist signals, and return the project working set. It also distinguishes this tool from three siblings by explaining how shadowgraph_context, shadowgraph_review, and shadowgraph_ack_review differ.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description gives clear sibling-based routing: use shadowgraph_context when signals should not be saved, shadowgraph_review when only due items are needed, and shadowgraph_ack_review to close a returned signal. It does not state an explicit 'use this when...' rule or all when-not conditions, but the alternatives are well identified.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
shadowgraph_review_signalsA
List the review signals already persisted, optionally narrowed to a project or to open or acknowledged ones. shadowgraph_review re-evaluates reopen rules and can create signals, shadowgraph_ack_review closes one. Without an access key, this read saves nothing. An access key commits a revision and bounded audit. Returns { items, completeness }, unpaginated.
| Name | Required | Description | Default |
|---|---|---|---|
| status | No | Filter by state. Omit to return both. | |
| grantId | No | Alias for accessId; conflicting identifiers are refused. | |
| project | No | Project or confirmed workspace binding; otherwise origin-only. No identity returns an empty scoped view. | |
| accessId | No | Grant ID, rechecked at use. Widens reads only, never write authority. Presenting an access key commits a revision and bounded operational audit: at most one aggregate per grant, surface, outcome and UTC day. Conflicts with a different grantId are refused. | |
| originId | No | Capture-origin id; with no project the record belongs to it alone. |
Output Schema
| Name | Required | Description |
|---|---|---|
| items | Yes | All known matching items inside this boundary. |
| completeness | Yes | Declares exactly what this response left out, so a truncated result can never look complete. |
| readProvenance | No | Original read bounds; reuse intersects these with currently valid authority. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
This is the standout dimension: it explains the non-obvious side effect that justifies readOnlyHint=false and idempotentHint=false — an access key "commits a revision and bounded audit", bounded to at most one aggregate per grant, surface, outcome and UTC day, while no key means nothing is saved. It also discloses that results are unpaginated, which annotations cannot express.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Four tight sentences with the core action front-loaded and the sibling routing and side-effect caveat following. Every sentence carries information; the only minor redundancy is restating the return shape when an output schema already exists, though "unpaginated" is genuinely additive.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given an output schema and five documented parameters, the description covers the risky part (the audit/revision side effect of accessId) and scoping limits. It leaves the semantics of the returned `completeness` field unaddressed, which matters for a tool that claims to be unpaginated.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100% and the schema already documents status, project, originId and the accessId/grantId alias-conflict behavior in more detail than the description. The description adds only the consequence of omitting a key ("this read saves nothing"), so baseline 3 applies.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
"List the review signals already persisted, optionally narrowed to a project or to open or acknowledged ones" gives a specific verb, resource, and scope. It then explicitly contrasts with shadowgraph_review (re-evaluates rules, can create signals) and shadowgraph_ack_review (closes one), so an agent can pick it apart from siblings without opening a schema.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
It names the two adjacent siblings and what each does instead, which effectively routes the agent: use this to enumerate persisted signals, use shadowgraph_review to re-evaluate, shadowgraph_ack_review to close. It stops short of an explicit "use this when / do not use when" statement, so it is a strong 4 rather than a 5.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
shadowgraph_searchA
Find records containing every query term for a precise content lookup. shadowgraph_retrieve adds one-hop neighbours; shadowgraph_recall ranks matches; shadowgraph_context prepares a working set. Own-scope read saves nothing; an access key commits a revision and bounded audit. Returns paginated matches and completeness. "redis timeout" requires both terms, not an exact phrase; empty query applies filters only.
| Name | Required | Description | Default |
|---|---|---|---|
| kind | No | Restrict results to decisions or to attempts. A structured filter, never a content match. | |
| limit | No | Maximum items to return, 1-1000; the default is 50 and completeness.limitSource reports which applied. Out of range is rejected, never silently clamped. | |
| query | No | Whitespace-separated terms, matched case-insensitively as substrings against the declared content fields (title, goal, chosen, assumption, evidence, alternative, attempt solution, attempt result, attempt reason, environment). Every term must match something, so more terms narrow the result. Omit to filter without searching. | |
| offset | No | Items to skip before this window. Ordering is total and deterministic, so paging cannot drop or duplicate an item. | |
| status | No | Return only decisions in this lifecycle state. A structured filter, so matching it is never counted as a content match. | |
| grantId | No | Alias for accessId; conflicting identifiers are refused. | |
| project | No | Project or confirmed workspace binding; otherwise origin-only. No identity returns an empty scoped view. | |
| accessId | No | Grant ID, rechecked at use. Widens reads only, never write authority. Presenting an access key commits a revision and bounded operational audit: at most one aggregate per grant, surface, outcome and UTC day. Conflicts with a different grantId are refused. | |
| originId | No | Capture-origin id; with no project the record belongs to it alone. | |
| sourceClass | No | Return only records carrying this claimed origin class. A structured filter, never a content match. | |
| minConfidence | No | Return only decisions whose current confidence is at least this value, 0-1. A structured filter, never a content match. |
Output Schema
| Name | Required | Description |
|---|---|---|
| page | Yes | The window actually applied to the matching items. |
| items | Yes | The items in this window, in deterministic order. |
| completeness | Yes | Declares exactly what this response left out, so a truncated result can never look complete. |
| readProvenance | No | Original read bounds; reuse intersects these with currently valid authority. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Goes beyond the annotations by disclosing a non-obvious side effect: presenting an access key commits a revision and a bounded operational audit (at most one aggregate per grant/surface/outcome/UTC day). That is exactly the kind of hidden write behavior an agent needs, and it is consistent with readOnlyHint=false. It omits failure behavior for the scoped-view empty-result case and pagination mechanics, but annotations carry the safety fundamentals.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Front-loaded with the core verb and scope, then sibling routing, then the caveats. It is dense and somewhat telegraphic (clause-stacked with semicolons), but almost every clause carries real information; no filler sentences.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For an 11-parameter tool with 100% schema coverage, an output schema, and annotations, the description supplies the remaining pieces: return shape ('paginated matches and completeness'), matching semantics, filter-only mode, and the access-key write side effect. Nothing material is missing.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100%, so the baseline is 3; the description earns the extra point by clarifying query semantics beyond the schema text — '"redis timeout" requires both terms, not an exact phrase' and 'empty query applies filters only' disambiguate AND-matching vs phrase-matching, which the schema alone does not state as crisply.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb and resource: 'Find records containing every query term for a precise content lookup,' and immediately contrasts with shadowgraph_retrieve, shadowgraph_recall, and shadowgraph_context by role. An agent can pick this tool over its siblings without opening any schema.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Names the four nearest alternatives and what each does instead ('adds one-hop neighbours', 'ranks matches', 'prepares a working set'), which gives clear routing guidance. It stops short of explicit when-not-to-use conditions or precedence, so it falls just short of a 5.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
shadowgraph_supersedeA
Mark one decision superseded by a replacement in the same project. shadowgraph_record_decision creates the replacement; shadowgraph_update_status changes state without replacement. Returns previous, replacement and relation. Both IDs must be owned in the same project/origin. History stays searchable; even repeats commit a revision.
| Name | Required | Description | Default |
|---|---|---|---|
| project | No | Owning project; required unless originId is set, else the write is refused. | |
| originId | No | Capture-origin id; with no project the record belongs to it alone. | |
| decisionId | Yes | The decision being replaced. It becomes superseded and is excluded from current context. | |
| replacementId | Yes | The decision replacing it. Must be in the same project and must not be superseded, archived, abandoned, or stale. |
Output Schema
| Name | Required | Description |
|---|---|---|
| previous | Yes | A stored decision, including its alternatives and auditable confidence basis. |
| relation | Yes | The supersedes relationship, or null when a repeated supersession found none to report. |
| replacement | Yes | A stored decision, including its alternatives and auditable confidence basis. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations declare idempotentHint=false and destructiveHint=false, and the description earns credit by explaining why: 'History stays searchable; even repeats commit a revision' clarifies that repeated identical calls are not no-ops. It also signals the return shape (previous, replacement, relation) and the ownership precondition. It stops short of describing failure/refusal behaviour beyond the ownership rule, which is in the schema.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Four short sentences, front-loaded with the action, then alternatives, then return value, then constraints. Dense but nearly every clause carries information; 'Returns previous, replacement and relation' is slightly redundant given the output schema exists.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
With annotations covering the safety profile and an output schema covering return values, the description only needs to supply scope, sibling routing and the non-idempotence caveat — all present. Nothing an agent needs in order to call it correctly is missing.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, so decisionId, replacementId, project and originId are already fully documented in the input schema. The description adds only the shared-ownership constraint, which the schema already states for replacementId. Baseline 3 is appropriate.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a precise verb and resource ('Mark one decision superseded by a replacement in the same project') and immediately contrasts it with the two sibling tools that would otherwise be confusable. An agent can distinguish this from shadowgraph_record_decision and shadowgraph_update_status without opening either schema.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Explicitly routes between alternatives: record_decision creates the replacement, update_status changes state without a replacement, this tool links them. It also states the selection constraint ('Both IDs must be owned in the same project/origin'), leaving nothing to inference.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
shadowgraph_update_statusA
Move one decision to another lifecycle state. shadowgraph_supersede replaces a decision, shadowgraph_maintain alone produces stale, shadowgraph_record_outcome records the result. stale and superseded are system-owned and rejected. Setting the current state writes nothing but still commits a revision.
| Name | Required | Description | Default |
|---|---|---|---|
| status | Yes | Target state. Legal moves are proposed to planned/in_progress/abandoned/archived; planned to in_progress/abandoned/archived; in_progress to executed/failed/abandoned/archived; executed to validated/failed/reconsidered/archived; validated to reconsidered/archived; failed to reconsidered/abandoned/archived; reconsidered to planned/in_progress/abandoned/archived; stale to reconsidered/archived; abandoned to archived. stale and superseded cannot be set by a caller. | |
| project | No | Owning project; required unless originId is set, else the write is refused. | |
| originId | No | Capture-origin id; with no project the record belongs to it alone. | |
| decisionId | Yes | Identifier of an existing decision, as returned by shadowgraph_record_decision, shadowgraph_search, or shadowgraph_retrieve. |
Output Schema
| Name | Required | Description |
|---|---|---|
| id | Yes | Stable entity identifier. |
| goal | No | What the decision was trying to achieve. |
| kind | Yes | Entity kind: decision, attempt, memory, fact, relation, review, or alternative. |
| actor | No | Who performed the write. |
| title | No | Short name of the decision. |
| chosen | No | The option that was chosen. |
| client | No | Which client performed the write. |
| status | No | Lifecycle state. Legacy records may carry a value this build does not recognise; shadowgraph_validate reports those. |
| outcome | No | The recorded outcome, or null until one is recorded. |
| project | No | Project namespace; null for an unattributed record or one imported from before projects. |
| evidence | No | Normalised evidence entries: source, type, sourceClass, confidence, observedAt, detail. |
| createdAt | No | ISO 8601 creation time. |
| migration | No | Present only on migrated records; records the legacy value a field was mapped from. |
| sessionId | No | Session identifier recorded with the write. |
| sourceRaw | No | The original origin label when it differed from sourceClass. Audit only; never evidence. |
| updatedAt | No | ISO 8601 time of the last change. |
| confidence | No | Auditable confidence: initial, current (0-1), policy, a history entry per move, and a basis summarising the contributions it was folded from. Legacy records may lack basis. |
| supersedes | No | Identifiers of decisions this one replaced. |
| assumptions | No | Assumptions the decision rests on. Searchable content. |
| reviewAfter | No | ISO 8601 instant after which shadowgraph_maintain marks this decision stale. |
| sourceClass | No | Claimed origin class recorded with the write. A claim, never proof. |
| alternatives | No | Rejected alternatives, each with id, label, reasonRejected, status, and the reopenWhen rules that make it reconsiderable. |
| supersededBy | No | Identifier of the decision that replaced this one. |
| schemaVersion | No | Storage schema version this entity was written under. A value above the build’s own version is preserved rather than downgraded. |
| failedAttempts | No | Attempt identifiers or notes attached to this decision. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations declare a non-read-only, non-idempotent, non-destructive write, and the description adds real context beyond them: system-owned states are rejected, and re-setting the current state writes nothing yet still commits a revision (clarifying why the call is not idempotent). It stops short of covering permissions, failure modes for the project/originId constraint, or what the resulting revision looks like.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Lead sentence states purpose immediately, followed by sibling routing and then the revision nuance, with no filler. There is minor redundancy: the stale/superseded rejection is repeated from the status enum description.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
An output schema exists, so return values need not be explained, and the schema itself carries the full transition matrix. What the description must supply—when to use this versus its siblings, and the surprising revision-commit behavior—is present, leaving no gap an agent would hit when calling it.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100%, so the enum's legal-transition table, the stale/superseded restriction, and the project-unless-originId rule are already documented in the schema. The description's statements about system-owned states largely restate the schema rather than adding new parameter meaning, so the baseline 3 applies.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
Starts with a specific verb and resource: 'Move one decision to another lifecycle state.' It then explicitly separates itself from three siblings (supersede, maintain, record_outcome) by naming what each of those does instead, so an agent can choose correctly without opening any schema.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Gives explicit routing rules: use shadowgraph_supersede to replace, shadowgraph_maintain to let a decision go stale, shadowgraph_record_outcome to record a result, and this tool to change lifecycle state. It also states an exclusion (stale and superseded are rejected), which is exactly the when-not guidance an agent needs.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
shadowgraph_validateA
Diagnose record, graph and journal integrity without applying repairs. shadowgraph_maintain ages records; shadowgraph_review checks decision rules; shadowgraph_repair_plan (full mode only) proposes repairs; shadowgraph_rebuild (full mode only) checks journal replay. Own-scope read saves nothing; an access key commits a revision and bounded audit. For full-mode tools, ask the operator to unset SHADOWGRAPH_MCP_PROFILE and restart with SHADOWGRAPH_MCP_COMPACT=0.
| Name | Required | Description | Default |
|---|---|---|---|
| grantId | No | Alias for accessId; conflicting identifiers are refused. | |
| project | No | Project or confirmed workspace binding; otherwise origin-only. No identity returns an empty scoped view. | |
| accessId | No | Grant ID, rechecked at use. Widens reads only, never write authority. Presenting an access key commits a revision and bounded operational audit: at most one aggregate per grant, surface, outcome and UTC day. Conflicts with a different grantId are refused. | |
| originId | No | Capture-origin id; with no project the record belongs to it alone. |
Output Schema
| Name | Required | Description |
|---|---|---|
| valid | Yes | False when any error or unsupported issue is present. |
| counts | Yes | Issue counts per severity. |
| issues | Yes | Every diagnostic found, each with a stable code and severity. |
| readProvenance | No | Original read bounds; reuse intersects these with currently valid authority. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Goes beyond the annotations to explain the surprising non-readOnly profile: an own-scope read persists nothing, but presenting an access key commits a revision and a bounded audit capped at one aggregate per grant/surface/outcome/UTC day. That is exactly the side-effect disclosure an agent needs before calling a diagnostic tool that is not marked readOnly, and it is consistent with readOnlyHint=false.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Front-loaded and dense, with the core purpose in the first clause and alternatives enumerated compactly. Some phrasing is telegraphic ('Own-scope read saves nothing'), which trades clarity for brevity, but no sentence is filler.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
With an output schema present and full annotation coverage, the description supplies the missing pieces: how it differs from four siblings, the audit side effect, and the profile-gated availability. Only the concrete trigger condition for running a diagnostic versus reviewing is left implicit.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, including the grantId/accessId alias conflict rule and the 'widens reads only, never write authority' semantics, so the baseline is 3. The description reinforces the access-key commit behavior but adds no parameter detail the schema does not already carry.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
Opens with a specific verb and resource set: 'Diagnose record, graph and journal integrity without applying repairs.' The negative scope ('without applying repairs') immediately separates it from repair-oriented siblings, so an agent can identify it without opening a schema.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Explicitly maps four alternatives to their jobs: maintain ages records, review checks decision rules, repair_plan proposes repairs, rebuild checks journal replay. It also gives a prerequisite for the full-mode tools (unset SHADOWGRAPH_MCP_PROFILE, restart with SHADOWGRAPH_MCP_COMPACT=0). It stops short of stating the trigger condition for choosing this tool, but the routing coverage is strong.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
Tool Schema Changelog
Recent tool additions, removals, and schema changes observed during successful MCP inspections.
8 tool updates
v0.42.4- Changed
shadowgraph_context6 fields changed- changed
Output schema / properties / completeness / properties / capture / properties / gaps / items / properties / reason / enumPrevious value: -[ - "maxQueueDepth", - "maxStoreBytes", - "maxItemsPerSession", - "session_in_another_project", - "raw_expired", - "transcript_unrecognised", - "session_left_project", - "transcript_rewritten", - "transcript_reanchored", - "transcript_incomplete_at_end", - "transcript_line_oversized", - "tool_calls_not_captured" -]New value: +[ + "maxQueueDepth", + "maxStoreBytes", + "maxItemsPerSession", + "session_in_another_project", + "raw_expired", + "prior_setup", + "transcript_unrecognised", + "session_left_project", + "transcript_rewritten", + "transcript_reanchored", + "transcript_incomplete_at_end", + "transcript_line_oversized", + "tool_calls_not_captured" +] - added
Output schema / properties / completeness / properties / capture / properties / priorSetupAdded value: +{ + "description": "Unextracted items of no or an earlier setup; never extracted by the current one.", + "minimum": 0, + "type": "integer" +} - changed
Output schema / properties / relevant / properties / capture / properties / gaps / items / properties / reason / enumPrevious value: -[ - "maxQueueDepth", - "maxStoreBytes", - "maxItemsPerSession", - "session_in_another_project", - "raw_expired", - "transcript_unrecognised", - "session_left_project", - "transcript_rewritten", - "transcript_reanchored", - "transcript_incomplete_at_end", - "transcript_line_oversized", - "tool_calls_not_captured" -]New value: +[ + "maxQueueDepth", + "maxStoreBytes", + "maxItemsPerSession", + "session_in_another_project", + "raw_expired", + "prior_setup", + "transcript_unrecognised", + "session_left_project", + "transcript_rewritten", + "transcript_reanchored", + "transcript_incomplete_at_end", + "transcript_line_oversized", + "tool_calls_not_captured" +] - added
Output schema / properties / relevant / properties / capture / properties / priorSetupAdded value: +{ + "description": "Unextracted items of no or an earlier setup; never extracted by the current one.", + "minimum": 0, + "type": "integer" +} - changed
Output schema / properties / relevant / properties / processing / properties / gaps / items / properties / reason / enumPrevious value: -[ - "maxQueueDepth", - "maxStoreBytes", - "maxItemsPerSession", - "session_in_another_project", - "raw_expired", - "transcript_unrecognised", - "session_left_project", - "transcript_rewritten", - "transcript_reanchored", - "transcript_incomplete_at_end", - "transcript_line_oversized", - "tool_calls_not_captured" -]New value: +[ + "maxQueueDepth", + "maxStoreBytes", + "maxItemsPerSession", + "session_in_another_project", + "raw_expired", + "prior_setup", + "transcript_unrecognised", + "session_left_project", + "transcript_rewritten", + "transcript_reanchored", + "transcript_incomplete_at_end", + "transcript_line_oversized", + "tool_calls_not_captured" +] - added
Output schema / properties / relevant / properties / processing / properties / priorSetupAdded value: +{ + "description": "Unextracted items of no or an earlier setup; never extracted by the current one.", + "minimum": 0, + "type": "integer" +}
- Changed
shadowgraph_expand2 fields changed- changed
Output schema / properties / completeness / properties / capture / properties / gaps / items / properties / reason / enumPrevious value: -[ - "maxQueueDepth", - "maxStoreBytes", - "maxItemsPerSession", - "session_in_another_project", - "raw_expired", - "transcript_unrecognised", - "session_left_project", - "transcript_rewritten", - "transcript_reanchored", - "transcript_incomplete_at_end", - "transcript_line_oversized", - "tool_calls_not_captured" -]New value: +[ + "maxQueueDepth", + "maxStoreBytes", + "maxItemsPerSession", + "session_in_another_project", + "raw_expired", + "prior_setup", + "transcript_unrecognised", + "session_left_project", + "transcript_rewritten", + "transcript_reanchored", + "transcript_incomplete_at_end", + "transcript_line_oversized", + "tool_calls_not_captured" +] - added
Output schema / properties / completeness / properties / capture / properties / priorSetupAdded value: +{ + "description": "Unextracted items of no or an earlier setup; never extracted by the current one.", + "minimum": 0, + "type": "integer" +}
- Changed
shadowgraph_recall2 fields changed- changed
Output schema / properties / completeness / properties / capture / properties / gaps / items / properties / reason / enumPrevious value: -[ - "maxQueueDepth", - "maxStoreBytes", - "maxItemsPerSession", - "session_in_another_project", - "raw_expired", - "transcript_unrecognised", - "session_left_project", - "transcript_rewritten", - "transcript_reanchored", - "transcript_incomplete_at_end", - "transcript_line_oversized", - "tool_calls_not_captured" -]New value: +[ + "maxQueueDepth", + "maxStoreBytes", + "maxItemsPerSession", + "session_in_another_project", + "raw_expired", + "prior_setup", + "transcript_unrecognised", + "session_left_project", + "transcript_rewritten", + "transcript_reanchored", + "transcript_incomplete_at_end", + "transcript_line_oversized", + "tool_calls_not_captured" +] - added
Output schema / properties / completeness / properties / capture / properties / priorSetupAdded value: +{ + "description": "Unextracted items of no or an earlier setup; never extracted by the current one.", + "minimum": 0, + "type": "integer" +}
- Changed
shadowgraph_retrieve2 fields changed- changed
Output schema / properties / completeness / properties / capture / properties / gaps / items / properties / reason / enumPrevious value: -[ - "maxQueueDepth", - "maxStoreBytes", - "maxItemsPerSession", - "session_in_another_project", - "raw_expired", - "transcript_unrecognised", - "session_left_project", - "transcript_rewritten", - "transcript_reanchored", - "transcript_incomplete_at_end", - "transcript_line_oversized", - "tool_calls_not_captured" -]New value: +[ + "maxQueueDepth", + "maxStoreBytes", + "maxItemsPerSession", + "session_in_another_project", + "raw_expired", + "prior_setup", + "transcript_unrecognised", + "session_left_project", + "transcript_rewritten", + "transcript_reanchored", + "transcript_incomplete_at_end", + "transcript_line_oversized", + "tool_calls_not_captured" +] - added
Output schema / properties / completeness / properties / capture / properties / priorSetupAdded value: +{ + "description": "Unextracted items of no or an earlier setup; never extracted by the current one.", + "minimum": 0, + "type": "integer" +}
- Changed
shadowgraph_review2 fields changed- changed
Output schema / properties / completeness / properties / capture / properties / gaps / items / properties / reason / enumPrevious value: -[ - "maxQueueDepth", - "maxStoreBytes", - "maxItemsPerSession", - "session_in_another_project", - "raw_expired", - "transcript_unrecognised", - "session_left_project", - "transcript_rewritten", - "transcript_reanchored", - "transcript_incomplete_at_end", - "transcript_line_oversized", - "tool_calls_not_captured" -]New value: +[ + "maxQueueDepth", + "maxStoreBytes", + "maxItemsPerSession", + "session_in_another_project", + "raw_expired", + "prior_setup", + "transcript_unrecognised", + "session_left_project", + "transcript_rewritten", + "transcript_reanchored", + "transcript_incomplete_at_end", + "transcript_line_oversized", + "tool_calls_not_captured" +] - added
Output schema / properties / completeness / properties / capture / properties / priorSetupAdded value: +{ + "description": "Unextracted items of no or an earlier setup; never extracted by the current one.", + "minimum": 0, + "type": "integer" +}
- Changed
shadowgraph_review_context2 fields changed- changed
Output schema / properties / completeness / properties / capture / properties / gaps / items / properties / reason / enumPrevious value: -[ - "maxQueueDepth", - "maxStoreBytes", - "maxItemsPerSession", - "session_in_another_project", - "raw_expired", - "transcript_unrecognised", - "session_left_project", - "transcript_rewritten", - "transcript_reanchored", - "transcript_incomplete_at_end", - "transcript_line_oversized", - "tool_calls_not_captured" -]New value: +[ + "maxQueueDepth", + "maxStoreBytes", + "maxItemsPerSession", + "session_in_another_project", + "raw_expired", + "prior_setup", + "transcript_unrecognised", + "session_left_project", + "transcript_rewritten", + "transcript_reanchored", + "transcript_incomplete_at_end", + "transcript_line_oversized", + "tool_calls_not_captured" +] - added
Output schema / properties / completeness / properties / capture / properties / priorSetupAdded value: +{ + "description": "Unextracted items of no or an earlier setup; never extracted by the current one.", + "minimum": 0, + "type": "integer" +}
- Changed
shadowgraph_review_signals2 fields changed- changed
Output schema / properties / completeness / properties / capture / properties / gaps / items / properties / reason / enumPrevious value: -[ - "maxQueueDepth", - "maxStoreBytes", - "maxItemsPerSession", - "session_in_another_project", - "raw_expired", - "transcript_unrecognised", - "session_left_project", - "transcript_rewritten", - "transcript_reanchored", - "transcript_incomplete_at_end", - "transcript_line_oversized", - "tool_calls_not_captured" -]New value: +[ + "maxQueueDepth", + "maxStoreBytes", + "maxItemsPerSession", + "session_in_another_project", + "raw_expired", + "prior_setup", + "transcript_unrecognised", + "session_left_project", + "transcript_rewritten", + "transcript_reanchored", + "transcript_incomplete_at_end", + "transcript_line_oversized", + "tool_calls_not_captured" +] - added
Output schema / properties / completeness / properties / capture / properties / priorSetupAdded value: +{ + "description": "Unextracted items of no or an earlier setup; never extracted by the current one.", + "minimum": 0, + "type": "integer" +}
- Changed
shadowgraph_search2 fields changed- changed
Output schema / properties / completeness / properties / capture / properties / gaps / items / properties / reason / enumPrevious value: -[ - "maxQueueDepth", - "maxStoreBytes", - "maxItemsPerSession", - "session_in_another_project", - "raw_expired", - "transcript_unrecognised", - "session_left_project", - "transcript_rewritten", - "transcript_reanchored", - "transcript_incomplete_at_end", - "transcript_line_oversized", - "tool_calls_not_captured" -]New value: +[ + "maxQueueDepth", + "maxStoreBytes", + "maxItemsPerSession", + "session_in_another_project", + "raw_expired", + "prior_setup", + "transcript_unrecognised", + "session_left_project", + "transcript_rewritten", + "transcript_reanchored", + "transcript_incomplete_at_end", + "transcript_line_oversized", + "tool_calls_not_captured" +] - added
Output schema / properties / completeness / properties / capture / properties / priorSetupAdded value: +{ + "description": "Unextracted items of no or an earlier setup; never extracted by the current one.", + "minimum": 0, + "type": "integer" +}
10 tool updates
v0.42.3- Changed
shadowgraph_ack_review1 field changed- changed
Input schema / properties / id / descriptionPrevious value: -"Review signal id, as returned in reviewSignalId by shadowgraph_context, in the id field by shadowgraph_review_signals (full mode only), or in reviewSignals by shadowgraph_maintain. This is the signal id, not the decisionId it refers to."New value: +"Persisted signal id: reviewSignalId from shadowgraph_review or shadowgraph_review_context, or id from shadowgraph_review_signals. A fresh context evaluation can be unpersisted and have no ID. This is not the decisionId."
- Added
shadowgraph_confidence_evidence - Changed
shadowgraph_context3 fields changed- changed
Input schema / properties / changedFacts / descriptionPrevious value: -"Fact keys that just changed. Only string-form reopenWhen rules match this list; it is an ephemeral signal, not durable state."New value: +"Ephemeral changed-key signals for string-form reopenWhen rules; not stored facts. Example: changedFacts:[\"budget\"] fires reopenWhen:[\"budget\"]. Object rules instead read values from facts overrides or stored facts." - changed
Input schema / properties / compact / descriptionPrevious value: -"With query or focalId, true delivers each relevant record as a shortened claim line (T1); false or omitted delivers full records. A line that would omit decisive meaning falls back to the full record. This controls record presentation, not the server tool mode."New value: +"With query or focalId, true delivers each relevant record as a shortened claim line (T1); false or omitted delivers full records. A line that would omit decisive meaning falls back to the full record. This controls record presentation, not the server tool mode. For example, query:\"cache\", compact:true adds relevant.items with expansion handles; compact:true alone does not add relevant." - changed
Input schema / properties / facts / descriptionPrevious value: -"Fact key/value overrides evaluated instead of the stored facts of the same key. Stored facts are used for every key not listed here, so reopen rules still work after a restart."New value: +"Temporary key/value overrides for object rules; unlisted keys use stored facts. Example: facts:{ready:true} tests {key:\"ready\",value:true}. This does not record a fact or fire a string rule; changedFacts supplies those changed-key signals."
- Changed
shadowgraph_maintain2 fields changed- changed
Input schema / properties / changedFacts / descriptionPrevious value: -"Fact keys that just changed. Only string-form reopenWhen rules match this list; it is an ephemeral signal, not durable state."New value: +"Ephemeral changed-key signals for string-form reopenWhen rules; not stored facts. Example: changedFacts:[\"budget\"] fires reopenWhen:[\"budget\"]. Object rules instead read values from facts overrides or stored facts." - changed
Input schema / properties / facts / descriptionPrevious value: -"Fact key/value overrides evaluated instead of the stored facts of the same key. Stored facts are used for every key not listed here, so reopen rules still work after a restart."New value: +"Temporary key/value overrides for object rules; unlisted keys use stored facts. Example: facts:{ready:true} tests {key:\"ready\",value:true}. This does not record a fact or fire a string rule; changedFacts supplies those changed-key signals."
- Changed
shadowgraph_reconsider3 fields changed- changed
Input schema / properties / changedFacts / descriptionPrevious value: -"Fact keys that just changed. Only string-form reopenWhen rules match this list; it is an ephemeral signal, not durable state."New value: +"Ephemeral changed-key signals for string-form reopenWhen rules; not stored facts. Example: changedFacts:[\"budget\"] fires reopenWhen:[\"budget\"]. Object rules instead read values from facts overrides or stored facts." - changed
Input schema / properties / decisionId / descriptionPrevious value: -"Reconsider only this decision. An unknown id, or one belonging to another project, is an error rather than an empty result, so a mis-addressed request can never read as \"nothing changed\"."New value: +"Limit the resolved project/origin to this decision; the ID does not supply scope. Unknown, out-of-scope, archived, abandoned or superseded decisions are rejected. Omit to explain all eligible decisions in scope." - changed
Input schema / properties / facts / descriptionPrevious value: -"Fact key/value overrides evaluated instead of the stored facts of the same key. Stored facts are used for every key not listed here, so reopen rules still work after a restart."New value: +"Temporary key/value overrides for object rules; unlisted keys use stored facts. Example: facts:{ready:true} tests {key:\"ready\",value:true}. This does not record a fact or fire a string rule; changedFacts supplies those changed-key signals."
- Changed
shadowgraph_review2 fields changed- changed
Input schema / properties / changedFacts / descriptionPrevious value: -"Fact keys that just changed. Only string-form reopenWhen rules match this list; it is an ephemeral signal, not durable state."New value: +"Ephemeral changed-key signals for string-form reopenWhen rules; not stored facts. Example: changedFacts:[\"budget\"] fires reopenWhen:[\"budget\"]. Object rules instead read values from facts overrides or stored facts." - changed
Input schema / properties / facts / descriptionPrevious value: -"Fact key/value overrides evaluated instead of the stored facts of the same key. Stored facts are used for every key not listed here, so reopen rules still work after a restart."New value: +"Temporary key/value overrides for object rules; unlisted keys use stored facts. Example: facts:{ready:true} tests {key:\"ready\",value:true}. This does not record a fact or fire a string rule; changedFacts supplies those changed-key signals."
- Changed
shadowgraph_review_context2 fields changed- changed
Input schema / properties / changedFacts / descriptionPrevious value: -"Fact keys that just changed. Only string-form reopenWhen rules match this list; it is an ephemeral signal, not durable state."New value: +"Ephemeral changed-key signals for string-form reopenWhen rules; not stored facts. Example: changedFacts:[\"budget\"] fires reopenWhen:[\"budget\"]. Object rules instead read values from facts overrides or stored facts." - changed
Input schema / properties / facts / descriptionPrevious value: -"Fact key/value overrides evaluated instead of the stored facts of the same key. Stored facts are used for every key not listed here, so reopen rules still work after a restart."New value: +"Temporary key/value overrides for object rules; unlisted keys use stored facts. Example: facts:{ready:true} tests {key:\"ready\",value:true}. This does not record a fact or fire a string rule; changedFacts supplies those changed-key signals."
- Added
shadowgraph_review_signals - Added
shadowgraph_supersede - Added
shadowgraph_update_status
11 tool updates
v0.42.2- Changed
shadowgraph_ack_review1 field changed- changed
Input schema / properties / id / descriptionPrevious value: -"Review signal id, as returned in reviewSignalId by shadowgraph_context, in the id field by shadowgraph_review_signals, or in reviewSignals by shadowgraph_maintain. This is the signal id, not the decisionId it refers to."New value: +"Review signal id, as returned in reviewSignalId by shadowgraph_context, in the id field by shadowgraph_review_signals (full mode only), or in reviewSignals by shadowgraph_maintain. This is the signal id, not the decisionId it refers to."
- Changed
shadowgraph_context3 fields changed- changed
Input schema / properties / accessId / descriptionPrevious value: -"Grant ID, rechecked at use."New value: +"Grant ID, rechecked at use. Widens reads only, never write authority. Presenting an access key commits a revision and bounded operational audit: at most one aggregate per grant, surface, outcome and UTC day. Conflicts with a different grantId are refused." - changed
Input schema / properties / compact / descriptionPrevious value: -"Deliver each relevant record as a derived claim line (T1) instead of the full record. A line that cannot carry its decisive meaning is delivered as the full record."New value: +"With query or focalId, true delivers each relevant record as a shortened claim line (T1); false or omitted delivers full records. A line that would omit decisive meaning falls back to the full record. This controls record presentation, not the server tool mode." - changed
Output schema / properties / relevant / properties / processing / descriptionPrevious value: -"Scoped capture processing; extraction is inactive in this build."New value: +"Scoped capture processing and current extraction availability."
- Changed
shadowgraph_expand2 fields changed- added
Input schema / descriptionAdded value: +"Input recipe: copy the line.expansion fields, omit null optional values, and put its scope.project, scope.originId and scope.grantId at top level. Do not pass the operation name or nest a scope object. Keep the digest and original read bounds; no handle field grants wider authority." - changed
Input schema / properties / accessId / descriptionPrevious value: -"Grant ID, rechecked at use."New value: +"Grant ID, rechecked at use. Widens reads only, never write authority. Presenting an access key commits a revision and bounded operational audit: at most one aggregate per grant, surface, outcome and UTC day. Conflicts with a different grantId are refused."
- Changed
shadowgraph_maintain1 field changed- changed
Input schema / properties / accessId / descriptionPrevious value: -"Grant ID, rechecked at use."New value: +"Grant ID, rechecked at use. Widens reads only, never write authority. Presenting an access key commits a revision and bounded operational audit: at most one aggregate per grant, surface, outcome and UTC day. Conflicts with a different grantId are refused."
- Changed
shadowgraph_recall1 field changed- changed
Input schema / properties / accessId / descriptionPrevious value: -"Grant ID, rechecked at use."New value: +"Grant ID, rechecked at use. Widens reads only, never write authority. Presenting an access key commits a revision and bounded operational audit: at most one aggregate per grant, surface, outcome and UTC day. Conflicts with a different grantId are refused."
- Changed
shadowgraph_reconsider1 field changed- changed
Input schema / properties / accessId / descriptionPrevious value: -"Grant ID, rechecked at use."New value: +"Grant ID, rechecked at use. Widens reads only, never write authority. Presenting an access key commits a revision and bounded operational audit: at most one aggregate per grant, surface, outcome and UTC day. Conflicts with a different grantId are refused."
- Changed
shadowgraph_retrieve1 field changed- changed
Input schema / properties / accessId / descriptionPrevious value: -"Grant ID, rechecked at use."New value: +"Grant ID, rechecked at use. Widens reads only, never write authority. Presenting an access key commits a revision and bounded operational audit: at most one aggregate per grant, surface, outcome and UTC day. Conflicts with a different grantId are refused."
- Changed
shadowgraph_review1 field changed- changed
Input schema / properties / accessId / descriptionPrevious value: -"Grant ID, rechecked at use."New value: +"Grant ID, rechecked at use. Widens reads only, never write authority. Presenting an access key commits a revision and bounded operational audit: at most one aggregate per grant, surface, outcome and UTC day. Conflicts with a different grantId are refused."
- Changed
shadowgraph_review_context1 field changed- changed
Input schema / properties / accessId / descriptionPrevious value: -"Grant ID, rechecked at use."New value: +"Grant ID, rechecked at use. Widens reads only, never write authority. Presenting an access key commits a revision and bounded operational audit: at most one aggregate per grant, surface, outcome and UTC day. Conflicts with a different grantId are refused."
- Changed
shadowgraph_search1 field changed- changed
Input schema / properties / accessId / descriptionPrevious value: -"Grant ID, rechecked at use."New value: +"Grant ID, rechecked at use. Widens reads only, never write authority. Presenting an access key commits a revision and bounded operational audit: at most one aggregate per grant, surface, outcome and UTC day. Conflicts with a different grantId are refused."
- Changed
shadowgraph_validate1 field changed- changed
Input schema / properties / accessId / descriptionPrevious value: -"Grant ID, rechecked at use."New value: +"Grant ID, rechecked at use. Widens reads only, never write authority. Presenting an access key commits a revision and bounded operational audit: at most one aggregate per grant, surface, outcome and UTC day. Conflicts with a different grantId are refused."
30 tool updates
v0.42.1- Changed
shadowgraph_ack_review5 fields changed- changed
Input schema / properties / id / descriptionPrevious value: -"Review signal id, as returned in the id field by shadowgraph_review_signals or in reviewSignals by shadowgraph_maintain. This is the signal id, not the decisionId it refers to."New value: +"Review signal id, as returned in reviewSignalId by shadowgraph_context, in the id field by shadowgraph_review_signals, or in reviewSignals by shadowgraph_maintain. This is the signal id, not the decisionId it refers to." - added
Input schema / properties / originIdAdded value: +{ + "description": "Capture-origin id; with no project the record belongs to it alone.", + "type": "string" +} - added
Input schema / properties / projectAdded value: +{ + "description": "Owning project; required unless originId is set, else the write is refused.", + "type": "string" +} - added
Output schema / properties / coverageAdded value: +{ + "description": "Exact conditions covered, and part of this identity.", + "items": { + "type": "string" + }, + "type": "array" +} - changed
Output schema / properties / reason / descriptionPrevious value: -"Why the signal was raised. Together with decisionId this is the dedupe identity, so the same cause never raises a second signal."New value: +"Why it was raised. Identity is this plus decisionId and coverage."
- Removed
shadowgraph_backup - Removed
shadowgraph_confidence_evidence - Changed
shadowgraph_context44 fields changed- added
Input schema / properties / accessIdAdded value: +{ + "description": "Grant ID, rechecked at use.", + "type": "string" +} - added
Input schema / properties / asOfAdded value: +{ + "description": "ISO 8601 instant for relevant: facts and memories valid then, recency ordered from it, and lines derived as of it.", + "type": "string" +} - added
Input schema / properties / compactAdded value: +{ + "description": "Deliver each relevant record as a derived claim line (T1) instead of the full record. A line that cannot carry its decisive meaning is delivered as the full record.", + "type": "boolean" +} - added
Input schema / properties / focalIdAdded value: +{ + "description": "Entity id to rank graph neighbours from. An id outside the scope reaches nothing, like an unknown one.", + "type": "string" +} - added
Input schema / properties / grantIdAdded value: +{ + "description": "Alias for accessId; conflicting identifiers are refused.", + "type": "string" +} - added
Input schema / properties / originIdAdded value: +{ + "description": "Capture-origin id; with no project the record belongs to it alone.", + "type": "string" +} - changed
Input schema / properties / project / descriptionPrevious value: -"Project namespace. Defaults to \"default\"; an empty string is rejected."New value: +"Project or confirmed workspace binding; otherwise origin-only. No identity returns an empty scoped view." - added
Input schema / properties / queryAdded value: +{ + "description": "Free text. With it or focalId, the response adds relevant: the records in scope that the lexical or graph signal ranks, ahead of the working set. No semantic signal is computed on this read.", + "type": "string" +} - changed
Output schema / properties / activeDecisions / descriptionPrevious value: -"Decisions in a current, actionable state: proposed, planned, in_progress, executed, validated, or reconsidered."New value: +"Decisions whose lifecycle status is current: proposed, planned, in_progress, executed, validated, or reconsidered." - changed
Output schema / properties / activeDecisions / items / properties / project / descriptionPrevious value: -"Project namespace; records imported from a schema that predates projects may carry null."New value: +"Project namespace; null for an unattributed record or one imported from before projects." - added
Output schema / properties / belowConfidenceThresholdAdded value: +{ + "description": "Decisions of any status whose recorded confidence is below the policy threshold.", + "items": { + "description": "One decision whose recorded confidence is below the policy threshold.", + "properties": { + "confidence": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + }, + { + "type": "null" + }, + { + "type": "array" + }, + { + "type": "object" + } + ], + "description": "Recorded current confidence, normally 0-1; null when none is recorded, which counts as below." + }, + "decisionId": { + "description": "The decision.", + "type": "string" + }, + "status": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + }, + { + "type": "null" + }, + { + "type": "array" + }, + { + "type": "object" + } + ], + "description": "Its lifecycle status as recorded, whatever it is; null when none is recorded." + }, + "threshold": { + "description": "The policy threshold the confidence is below.", + "type": "number" + }, + "title": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "description": "Decision title, when the stored decision has one." + } + }, + "required": [ + "decisionId", + "status", + "confidence", + "threshold" + ], + "type": "object" + }, + "type": "array" +} - changed
Output schema / properties / completeness / descriptionPrevious value: -"Per-collection completeness. context returns five named collections, so one page object cannot describe it."New value: +"Per-collection completeness. context returns several named collections, so one page object cannot describe it." - added
Output schema / properties / completeness / properties / captureAdded value: +{ + "description": "Scoped unprocessed capture, when present.", + "properties": { + "blocked": { + "description": "Items blocked.", + "minimum": 0, + "type": "integer" + }, + "expired": { + "description": "Raw expired before extraction; a gap, not backlog.", + "minimum": 0, + "type": "integer" + }, + "extractionAvailable": { + "description": "Whether extraction runs.", + "type": "boolean" + }, + "failed": { + "description": "Items failed.", + "minimum": 0, + "type": "integer" + }, + "gaps": { + "description": "Capture refusal/unread gaps; no identities.", + "items": { + "properties": { + "from": { + "description": "Gap start time.", + "type": "string" + }, + "reason": { + "description": "Why capture has a gap.", + "enum": [ + "maxQueueDepth", + "maxStoreBytes", + "maxItemsPerSession", + "session_in_another_project", + "raw_expired", + "transcript_unrecognised", + "session_left_project", + "transcript_rewritten", + "transcript_reanchored", + "transcript_incomplete_at_end", + "transcript_line_oversized", + "tool_calls_not_captured" + ], + "type": "string" + }, + "sessions": { + "description": "Sessions covered by this gap.", + "minimum": 0, + "type": "integer" + }, + "to": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "description": "End time, if known." + } + }, + "required": [ + "reason", + "from", + "to" + ], + "type": "object" + }, + "type": "array" + }, + "limited": { + "description": "Admission limits; accepted items kept.", + "items": { + "properties": { + "ceiling": { + "description": "The limit value.", + "minimum": 0, + "type": "integer" + }, + "limit": { + "description": "The limit reached.", + "enum": [ + "maxQueueDepth", + "maxStoreBytes" + ], + "type": "string" + }, + "since": { + "description": "When refusal began.", + "type": "string" + } + }, + "required": [ + "limit", + "ceiling", + "since" + ], + "type": "object" + }, + "type": "array" + }, + "oldestPendingAt": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "description": "Oldest pending capture." + }, + "pending": { + "description": "Items waiting.", + "minimum": 0, + "type": "integer" + }, + "processing": { + "description": "Items claimed.", + "minimum": 0, + "type": "integer" + }, + "workerErrors": { + "description": "Scoped worker stops; fixed codes.", + "items": { + "properties": { + "at": { + "description": "Stop timestamp.", + "type": "string" + }, + "reason": { + "description": "Worker stop code.", + "type": "string" + } + }, + "required": [ + "reason", + "at" + ], + "type": "object" + }, + "type": "array" + } + }, + "required": [ + "pending", + "processing", + "failed", + "blocked", + "oldestPendingAt", + "extractionAvailable", + "limited", + "gaps" + ], + "type": "object" +} - added
Output schema / properties / completeness / properties / collections / properties / belowConfidenceThresholdAdded value: +{ + "description": "Counts for belowConfidenceThreshold.", + "properties": { + "hasMore": { + "description": "True when this collection was truncated.", + "type": "boolean" + }, + "omitted": { + "description": "total minus returned for this collection.", + "minimum": 0, + "type": "integer" + }, + "returned": { + "description": "Items returned for this collection.", + "minimum": 0, + "type": "integer" + }, + "total": { + "description": "Items that matched for this collection.", + "minimum": 0, + "type": "integer" + } + }, + "required": [ + "returned", + "total", + "hasMore", + "omitted" + ], + "type": "object" +} - added
Output schema / properties / completeness / properties / collections / properties / conditionDiagnosticsAdded value: +{ + "description": "Counts for conditionDiagnostics.", + "properties": { + "hasMore": { + "description": "True when this collection was truncated.", + "type": "boolean" + }, + "omitted": { + "description": "total minus returned for this collection.", + "minimum": 0, + "type": "integer" + }, + "returned": { + "description": "Items returned for this collection.", + "minimum": 0, + "type": "integer" + }, + "total": { + "description": "Items that matched for this collection.", + "minimum": 0, + "type": "integer" + } + }, + "required": [ + "returned", + "total", + "hasMore", + "omitted" + ], + "type": "object" +} - added
Output schema / properties / completeness / properties / collections / properties / failedAttemptsAdded value: +{ + "description": "Counts for failedAttempts.", + "properties": { + "hasMore": { + "description": "True when this collection was truncated.", + "type": "boolean" + }, + "omitted": { + "description": "total minus returned for this collection.", + "minimum": 0, + "type": "integer" + }, + "returned": { + "description": "Items returned for this collection.", + "minimum": 0, + "type": "integer" + }, + "total": { + "description": "Items that matched for this collection.", + "minimum": 0, + "type": "integer" + }, + "undetermined": { + "description": "Captured attempts with no resultClass: undetermined, in no collection.", + "minimum": 0, + "type": "integer" + } + }, + "required": [ + "returned", + "total", + "hasMore", + "omitted", + "undetermined" + ], + "type": "object" +} - removed
Output schema / properties / completeness / properties / collections / properties / failedAttemptsToAvoidRemoved value: -{ - "description": "Counts for failedAttemptsToAvoid.", - "properties": { - "hasMore": { - "description": "True when this collection was truncated.", - "type": "boolean" - }, - "omitted": { - "description": "total minus returned for this collection.", - "minimum": 0, - "type": "integer" - }, - "returned": { - "description": "Items returned for this collection.", - "minimum": 0, - "type": "integer" - }, - "total": { - "description": "Items that matched for this collection.", - "minimum": 0, - "type": "integer" - } - }, - "required": [ - "returned", - "total", - "hasMore", - "omitted" - ], - "type": "object" -} - added
Output schema / properties / completeness / properties / collections / properties / firedConditionsAdded value: +{ + "description": "Counts for firedConditions.", + "properties": { + "hasMore": { + "description": "True when this collection was truncated.", + "type": "boolean" + }, + "omitted": { + "description": "total minus returned for this collection.", + "minimum": 0, + "type": "integer" + }, + "returned": { + "description": "Items returned for this collection.", + "minimum": 0, + "type": "integer" + }, + "total": { + "description": "Items that matched for this collection.", + "minimum": 0, + "type": "integer" + } + }, + "required": [ + "returned", + "total", + "hasMore", + "omitted" + ], + "type": "object" +} - removed
Output schema / properties / completeness / properties / collections / properties / openReviewsRemoved value: -{ - "description": "Counts for openReviews.", - "properties": { - "hasMore": { - "description": "True when this collection was truncated.", - "type": "boolean" - }, - "omitted": { - "description": "total minus returned for this collection.", - "minimum": 0, - "type": "integer" - }, - "returned": { - "description": "Items returned for this collection.", - "minimum": 0, - "type": "integer" - }, - "total": { - "description": "Items that matched for this collection.", - "minimum": 0, - "type": "integer" - } - }, - "required": [ - "returned", - "total", - "hasMore", - "omitted" - ], - "type": "object" -} - added
Output schema / properties / completeness / properties / collections / properties / reusableAttemptsAdded value: +{ + "description": "Counts for reusableAttempts.", + "properties": { + "hasMore": { + "description": "True when this collection was truncated.", + "type": "boolean" + }, + "omitted": { + "description": "total minus returned for this collection.", + "minimum": 0, + "type": "integer" + }, + "returned": { + "description": "Items returned for this collection.", + "minimum": 0, + "type": "integer" + }, + "total": { + "description": "Items that matched for this collection.", + "minimum": 0, + "type": "integer" + } + }, + "required": [ + "returned", + "total", + "hasMore", + "omitted" + ], + "type": "object" +} - removed
Output schema / properties / completeness / properties / collections / properties / suggestedQuestionsRemoved value: -{ - "description": "Counts for suggestedQuestions.", - "properties": { - "hasMore": { - "description": "True when this collection was truncated.", - "type": "boolean" - }, - "omitted": { - "description": "total minus returned for this collection.", - "minimum": 0, - "type": "integer" - }, - "returned": { - "description": "Items returned for this collection.", - "minimum": 0, - "type": "integer" - }, - "total": { - "description": "Items that matched for this collection.", - "minimum": 0, - "type": "integer" - } - }, - "required": [ - "returned", - "total", - "hasMore", - "omitted" - ], - "type": "object" -} - changed
Output schema / properties / completeness / properties / collections / requiredPrevious value: -[ - "activeDecisions", - "staleAssumptions", - "failedAttemptsToAvoid", - "openReviews", - "suggestedQuestions" -]New value: +[ + "activeDecisions", + "staleAssumptions", + "failedAttempts", + "firedConditions", + "belowConfidenceThreshold" +] - changed
Output schema / properties / completeness / properties / complete / descriptionPrevious value: -"True only when no collection was truncated."New value: +"Known-candidate coverage; false for unresolved scope, withheld detail or pending capture; not recall." - added
Output schema / properties / completeness / properties / limitationAdded value: +{ + "description": "Limits of this view.", + "properties": { + "code": { + "description": "Stable limitation code.", + "type": "string" + }, + "detail": { + "description": "What this view cannot establish.", + "type": "string" + } + }, + "required": [ + "code", + "detail" + ], + "type": "object" +} - changed
Output schema / properties / completeness / properties / losslessItems / descriptionPrevious value: -"Always true: items are full records, never summaries."New value: +"False when returned items have withheld or transformed detail." - added
Output schema / properties / completeness / properties / quarantinedAdded value: +{ + "description": "Items withheld as possibly purged.", + "minimum": 0, + "type": "integer" +} - changed
Output schema / properties / completeness / properties / scope / descriptionPrevious value: -"The project this result covers."New value: +"The resolved read boundary." - added
Output schema / properties / completeness / properties / scope / propertiesAdded value: +{ + "grant": { + "anyOf": [ + { + "type": "null" + }, + { + "properties": { + "accessId": { + "description": "The currently rechecked grant identifier.", + "type": "string" + }, + "expiresAt": { + "description": "Earliest effective expiry of this read authority.", + "type": "string" + }, + "surface": { + "description": "Actual runtime surface of this read.", + "enum": [ + "cli", + "mcp", + "http" + ], + "type": "string" + } + }, + "required": [ + "accessId", + "expiresAt", + "surface" + ], + "type": "object" + } + ], + "description": "Effective rechecked grant, or null." + }, + "originPresented": { + "description": "Usable origin presented; not project selection.", + "type": "boolean" + }, + "project": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "description": "Resolved project, or null." + }, + "requestState": { + "description": "Whether a project was resolved.", + "enum": [ + "project_selected", + "project_unresolved" + ], + "type": "string" + } +} - added
Output schema / properties / completeness / properties / scope / requiredAdded value: +[ + "project", + "requestState", + "originPresented", + "grant" +] - added
Output schema / properties / conditionDiagnosticsAdded value: +{ + "description": "Conditions that could not be settled, or that rest on facts which disagree. Neither a breach nor a confirmed-safe decision.", + "items": { + "description": "Unresolved or contested conditions on one decision or attempt. Not a review signal: neither a breach nor a confirmed-safe decision.", + "properties": { + "attemptId": { + "description": "The attempt involved, for reusableWhen conditions.", + "type": "string" + }, + "conditions": { + "description": "The unresolved or contested conditions.", + "items": { + "description": "One evaluated reopen condition. Verdict \"unknown\" means it could not be evaluated from available evidence, which is not a pass.", + "properties": { + "alternativeId": { + "description": "Alternative carrying it.", + "type": "string" + }, + "alternativeLabel": { + "description": "Label of that alternative.", + "type": "string" + }, + "attemptId": { + "description": "Attempt the condition belongs to, for a reusableWhen rule.", + "type": "string" + }, + "conflictingEvidence": { + "description": "Equally applicable facts that disagree. The verdict rests on the deterministic winner.", + "items": { + "description": "A fact a verdict came from. Unrecorded fields are omitted, never filled in.", + "properties": { + "factId": { + "description": "The observed fact.", + "type": "string" + }, + "observedAt": { + "description": "When observed, if recorded.", + "type": "string" + }, + "sourceClass": { + "description": "Provenance class, if recorded.", + "type": "string" + }, + "validFrom": { + "description": "Validity start, if recorded.", + "type": "string" + }, + "value": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + }, + { + "type": "null" + }, + { + "type": "array" + }, + { + "type": "object" + } + ], + "description": "A stored value, any lossless JSON value." + }, + "verificationStatus": { + "description": "Verification status, if recorded.", + "type": "string" + } + }, + "required": [ + "factId", + "value" + ], + "type": "object" + }, + "type": "array" + }, + "decisionId": { + "description": "Decision the condition belongs to, for a reopenWhen rule.", + "type": "string" + }, + "evidence": { + "description": "Provenance of the value used.", + "type": "object" + }, + "expected": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + }, + { + "type": "null" + }, + { + "type": "array" + }, + { + "type": "object" + } + ], + "description": "A stored value, any lossless JSON value." + }, + "key": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "description": "Fact key read." + }, + "observed": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + }, + { + "type": "null" + }, + { + "type": "array" + }, + { + "type": "object" + } + ], + "description": "A stored value, any lossless JSON value." + }, + "operator": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "description": "Operator the rule declared." + }, + "reason": { + "description": "Why this verdict.", + "type": "string" + }, + "unit": { + "description": "Unit the rule declared, if any.", + "type": "string" + }, + "verdict": { + "description": "Evaluation result.", + "enum": [ + "true", + "false", + "unknown" + ], + "type": "string" + } + }, + "required": [ + "key", + "operator", + "verdict", + "reason" + ], + "type": "object" + }, + "type": "array" + }, + "decisionId": { + "description": "The decision involved, for reopenWhen conditions.", + "type": "string" + }, + "title": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "description": "Decision title, when stored." + } + }, + "required": [ + "conditions" + ], + "type": "object" + }, + "type": "array" +} - added
Output schema / properties / failedAttemptsAdded value: +{ + "description": "Attempts that failed: resultClass failed or, with none and not captured, a result mentioning failure, regression, or error.", + "items": { + "description": "A stored attempt and its result.", + "properties": { + "actor": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "description": "Who performed the write." + }, + "causalClaim": { + "description": "The cause, attributed apart from the attempt: state recorded (the reason, agent_claimed), unknown, not_recorded, or legacy_freetext (a reason stored before causes were, never classed or evidenced).", + "type": "object" + }, + "client": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "description": "Which client performed the write." + }, + "createdAt": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "description": "ISO 8601 creation time." + }, + "environment": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "description": "Where it was tried." + }, + "id": { + "description": "Stable entity identifier.", + "type": "string" + }, + "kind": { + "description": "Entity kind: decision, attempt, memory, fact, relation, review, or alternative.", + "type": "string" + }, + "project": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "description": "Project namespace; null for an unattributed record or one imported from before projects." + }, + "reason": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "description": "Why it turned out that way, verbatim as recorded." + }, + "relatedTo": { + "description": "Identifiers of related entities.", + "type": "array" + }, + "result": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "description": "What happened." + }, + "resultClass": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "description": "Declared or observed: failed, succeeded, or inconclusive. If absent: not captured (no captureRef or outcomeEvidence), the wording heuristic classifies; captured, the outcome is undetermined." + }, + "reusableWhen": { + "description": "Conditions recorded for reusing the attempt. All must hold, and none may be unresolved.", + "type": "array" + }, + "schemaVersion": { + "description": "Storage schema version this entity was written under. A value above the build’s own version is preserved rather than downgraded.", + "type": "integer" + }, + "sessionId": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "description": "Session identifier recorded with the write." + }, + "solution": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "description": "What was tried." + }, + "sourceClass": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "description": "Claimed origin class recorded with the write. A claim, never proof." + }, + "sourceRaw": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "description": "The original origin label when it differed from sourceClass. Audit only; never evidence." + }, + "updatedAt": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "description": "ISO 8601 time of the last change." + } + }, + "required": [ + "id", + "kind" + ], + "type": "object" + }, + "type": "array" +} - removed
Output schema / properties / failedAttemptsToAvoidRemoved value: -{ - "description": "Attempts whose result mentions failure, regression, or error.", - "items": { - "description": "A stored attempt and its result.", - "properties": { - "actor": { - "anyOf": [ - { - "type": "string" - }, - { - "type": "null" - } - ], - "description": "Who performed the write." - }, - "client": { - "anyOf": [ - { - "type": "string" - }, - { - "type": "null" - } - ], - "description": "Which client performed the write." - }, - "createdAt": { - "anyOf": [ - { - "type": "string" - }, - { - "type": "null" - } - ], - "description": "ISO 8601 creation time." - }, - "environment": { - "anyOf": [ - { - "type": "string" - }, - { - "type": "null" - } - ], - "description": "Where it was tried." - }, - "id": { - "description": "Stable entity identifier.", - "type": "string" - }, - "kind": { - "description": "Entity kind: decision, attempt, memory, fact, relation, review, or alternative.", - "type": "string" - }, - "project": { - "anyOf": [ - { - "type": "string" - }, - { - "type": "null" - } - ], - "description": "Project namespace; records imported from a schema that predates projects may carry null." - }, - "reason": { - "anyOf": [ - { - "type": "string" - }, - { - "type": "null" - } - ], - "description": "Why it turned out that way." - }, - "relatedTo": { - "description": "Identifiers of related entities.", - "type": "array" - }, - "result": { - "anyOf": [ - { - "type": "string" - }, - { - "type": "null" - } - ], - "description": "What happened." - }, - "reusableWhen": { - "description": "Conditions under which the attempt is worth repeating.", - "type": "array" - }, - "schemaVersion": { - "description": "Storage schema version this entity was written under. A value above the build’s own version is preserved rather than downgraded.", - "type": "integer" - }, - "sessionId": { - "anyOf": [ - { - "type": "string" - }, - { - "type": "null" - } - ], - "description": "Session identifier recorded with the write." - }, - "solution": { - "anyOf": [ - { - "type": "string" - }, - { - "type": "null" - } - ], - "description": "What was tried." - }, - "sourceClass": { - "anyOf": [ - { - "type": "string" - }, - { - "type": "null" - } - ], - "description": "Claimed origin class recorded with the write. A claim, never proof." - }, - "sourceRaw": { - "anyOf": [ - { - "type": "string" - }, - { - "type": "null" - } - ], - "description": "The original origin label when it differed from sourceClass. Audit only; never evidence." - }, - "updatedAt": { - "anyOf": [ - { - "type": "string" - }, - { - "type": "null" - } - ], - "description": "ISO 8601 time of the last change." - } - }, - "required": [ - "id", - "kind" - ], - "type": "object" - }, - "type": "array" -} - added
Output schema / properties / firedConditionsAdded value: +{ + "description": "Decisions whose recorded review conditions fired, with the conditions and the facts they were computed from.", + "items": { + "description": "One decision whose recorded reopen conditions, review date or failed outcome fired.", + "properties": { + "affectedAlternatives": { + "description": "Labels of the recorded alternatives the fired conditions belong to; all of them when the trigger was not alternative-specific.", + "items": { + "type": "string" + }, + "type": "array" + }, + "decisionId": { + "description": "The decision whose conditions fired.", + "type": "string" + }, + "reason": { + "description": "Comma-separated causes: the fact keys whose reopenWhen rules matched, \"review date reached\", or \"decision outcome failed\".", + "type": "string" + }, + "reviewSignalId": { + "description": "The stored review signal for this decision; shadowgraph_ack_review takes this id.", + "type": "string" + }, + "reviewSignalStatus": { + "description": "Whether this review is open or acknowledged, or unpersisted: no stored signal, because context is a read or the evaluation was wider. Entries are recomputed from current evidence; an acknowledged one still appears.", + "enum": [ + "open", + "acknowledged", + "unpersisted" + ], + "type": "string" + }, + "title": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "description": "Decision title, when the stored decision has one." + }, + "violatedConditions": { + "description": "The conditions that actually fired, each naming its operator, expected and observed value, and the fact it was computed from.", + "items": { + "description": "One evaluated reopen condition. Verdict \"unknown\" means it could not be evaluated from available evidence, which is not a pass.", + "properties": { + "alternativeId": { + "description": "Alternative carrying it.", + "type": "string" + }, + "alternativeLabel": { + "description": "Label of that alternative.", + "type": "string" + }, + "attemptId": { + "description": "Attempt the condition belongs to, for a reusableWhen rule.", + "type": "string" + }, + "conflictingEvidence": { + "description": "Equally applicable facts that disagree. The verdict rests on the deterministic winner.", + "items": { + "description": "A fact a verdict came from. Unrecorded fields are omitted, never filled in.", + "properties": { + "factId": { + "description": "The observed fact.", + "type": "string" + }, + "observedAt": { + "description": "When observed, if recorded.", + "type": "string" + }, + "sourceClass": { + "description": "Provenance class, if recorded.", + "type": "string" + }, + "validFrom": { + "description": "Validity start, if recorded.", + "type": "string" + }, + "value": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + }, + { + "type": "null" + }, + { + "type": "array" + }, + { + "type": "object" + } + ], + "description": "A stored value, any lossless JSON value." + }, + "verificationStatus": { + "description": "Verification status, if recorded.", + "type": "string" + } + }, + "required": [ + "factId", + "value" + ], + "type": "object" + }, + "type": "array" + }, + "decisionId": { + "description": "Decision the condition belongs to, for a reopenWhen rule.", + "type": "string" + }, + "evidence": { + "description": "Provenance of the value used.", + "type": "object" + }, + "expected": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + }, + { + "type": "null" + }, + { + "type": "array" + }, + { + "type": "object" + } + ], + "description": "A stored value, any lossless JSON value." + }, + "key": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "description": "Fact key read." + }, + "observed": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + }, + { + "type": "null" + }, + { + "type": "array" + }, + { + "type": "object" + } + ], + "description": "A stored value, any lossless JSON value." + }, + "operator": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "description": "Operator the rule declared." + }, + "reason": { + "description": "Why this verdict.", + "type": "string" + }, + "unit": { + "description": "Unit the rule declared, if any.", + "type": "string" + }, + "verdict": { + "description": "Evaluation result.", + "enum": [ + "true", + "false", + "unknown" + ], + "type": "string" + } + }, + "required": [ + "key", + "operator", + "verdict", + "reason" + ], + "type": "object" + }, + "type": "array" + } + }, + "required": [ + "decisionId", + "reason", + "affectedAlternatives" + ], + "type": "object" + }, + "type": "array" +} - added
Output schema / properties / noticeAdded value: +{ + "description": "Declared interface metadata, not memory: context is a read, and reviewContext (shadowgraph_review_context) evaluates and persists.", + "properties": { + "code": { + "description": "Stable notice code.", + "enum": [ + "context_does_not_persist" + ], + "type": "string" + }, + "detail": { + "description": "Where the old evaluate-and-persist behaviour moved.", + "type": "string" + }, + "replacement": { + "description": "The replacement operation on each surface.", + "properties": { + "cli": { + "description": "CLI verb to run.", + "type": "string" + }, + "http": { + "description": "HTTP route to call.", + "type": "string" + }, + "kernel": { + "description": "Kernel method to call.", + "type": "string" + }, + "mcp": { + "description": "MCP tool to call.", + "type": "string" + } + }, + "type": "object" + } + }, + "required": [ + "code", + "detail", + "replacement" + ], + "type": "object" +} - removed
Output schema / properties / openReviewsRemoved value: -{ - "description": "Decisions currently due for reconsideration.", - "items": { - "description": "One decision whose rejected alternatives are due for reconsideration.", - "properties": { - "alternativesToReconsider": { - "description": "Labels of the alternatives to look at again; all of them when the trigger was not alternative-specific.", - "items": { - "type": "string" - }, - "type": "array" - }, - "decisionId": { - "description": "The decision to reconsider.", - "type": "string" - }, - "reason": { - "description": "Comma-separated causes: the fact keys whose reopenWhen rules matched, \"review date reached\", or \"decision outcome failed\".", - "type": "string" - }, - "title": { - "anyOf": [ - { - "type": "string" - }, - { - "type": "null" - } - ], - "description": "Decision title, when the stored decision has one." - } - }, - "required": [ - "decisionId", - "reason", - "alternativesToReconsider" - ], - "type": "object" - }, - "type": "array" -} - added
Output schema / properties / project / anyOfAdded value: +[ + { + "type": "string" + }, + { + "type": "null" + } +] - changed
Output schema / properties / project / descriptionPrevious value: -"The project this context describes."New value: +"The resolved project, or null when unresolved." - removed
Output schema / properties / project / typeRemoved value: -"string" - added
Output schema / properties / readProvenanceAdded value: +{ + "description": "Original read bounds; reuse intersects these with currently valid authority.", + "properties": { + "accessId": { + "description": "Original grant, revalidated on every reuse.", + "type": "string" + }, + "expiresAt": { + "description": "Original effective expiry; reuse cannot extend it.", + "type": "string" + }, + "request": { + "description": "Original request ownership, preserved during expansion.", + "properties": { + "originId": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "description": "Original capture origin, or null when absent." + }, + "project": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "description": "Original resolved project, or null when unresolved." + } + }, + "required": [ + "project", + "originId" + ], + "type": "object" + }, + "scope": { + "description": "Finite explicit owner bounds; project names, origins and legacy attribution are disjoint.", + "properties": { + "legacyAttributions": { + "description": "Explicit legacy ownership classes; neither is a named project.", + "items": { + "enum": [ + "legacy_ambiguous", + "legacy_unattributed" + ], + "type": "string" + }, + "type": "array" + }, + "originIds": { + "description": "Exact nonempty origin identifiers for unattributed content.", + "items": { + "type": "string" + }, + "type": "array" + }, + "projects": { + "description": "Exact named projects, including a real project named default if requested.", + "items": { + "type": "string" + }, + "type": "array" + } + }, + "type": "object" + }, + "surfaces": { + "description": "Original permitted surfaces; reuse can only narrow them.", + "items": { + "enum": [ + "cli", + "mcp", + "http" + ], + "type": "string" + }, + "type": "array" + }, + "version": { + "const": 1, + "description": "Version of this bounded read provenance.", + "type": "integer" + } + }, + "required": [ + "version", + "request", + "accessId", + "scope", + "surfaces", + "expiresAt" + ], + "type": "object" +} - added
Output schema / properties / relevantAdded value: +{ + "description": "Present with query or focalId: records in scope ranked on the records themselves, head first.", + "properties": { + "byKind": { + "description": "Candidates by kind.", + "properties": { + "attempt": { + "description": "Candidate attempts.", + "minimum": 0, + "type": "integer" + }, + "decision": { + "description": "Candidate decisions.", + "minimum": 0, + "type": "integer" + }, + "fact": { + "description": "Candidate facts.", + "minimum": 0, + "type": "integer" + }, + "memory": { + "description": "Candidate memories.", + "minimum": 0, + "type": "integer" + } + }, + "required": [ + "decision", + "attempt", + "memory", + "fact" + ], + "type": "object" + }, + "capture": { + "description": "Scoped unprocessed capture, when present.", + "properties": { + "blocked": { + "description": "Items blocked.", + "minimum": 0, + "type": "integer" + }, + "expired": { + "description": "Raw expired before extraction; a gap, not backlog.", + "minimum": 0, + "type": "integer" + }, + "extractionAvailable": { + "description": "Whether extraction runs.", + "type": "boolean" + }, + "failed": { + "description": "Items failed.", + "minimum": 0, + "type": "integer" + }, + "gaps": { + "description": "Capture refusal/unread gaps; no identities.", + "items": { + "properties": { + "from": { + "description": "Gap start time.", + "type": "string" + }, + "reason": { + "description": "Why capture has a gap.", + "enum": [ + "maxQueueDepth", + "maxStoreBytes", + "maxItemsPerSession", + "session_in_another_project", + "raw_expired", + "transcript_unrecognised", + "session_left_project", + "transcript_rewritten", + "transcript_reanchored", + "transcript_incomplete_at_end", + "transcript_line_oversized", + "tool_calls_not_captured" + ], + "type": "string" + }, + "sessions": { + "description": "Sessions covered by this gap.", + "minimum": 0, + "type": "integer" + }, + "to": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "description": "End time, if known." + } + }, + "required": [ + "reason", + "from", + "to" + ], + "type": "object" + }, + "type": "array" + }, + "limited": { + "description": "Admission limits; accepted items kept.", + "items": { + "properties": { + "ceiling": { + "description": "The limit value.", + "minimum": 0, + "type": "integer" + }, + "limit": { + "description": "The limit reached.", + "enum": [ + "maxQueueDepth", + "maxStoreBytes" + ], + "type": "string" + }, + "since": { + "description": "When refusal began.", + "type": "string" + } + }, + "required": [ + "limit", + "ceiling", + "since" + ], + "type": "object" + }, + "type": "array" + }, + "oldestPendingAt": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "description": "Oldest pending capture." + }, + "pending": { + "description": "Items waiting.", + "minimum": 0, + "type": "integer" + }, + "processing": { + "description": "Items claimed.", + "minimum": 0, + "type": "integer" + }, + "workerErrors": { + "description": "Scoped worker stops; fixed codes.", + "items": { + "properties": { + "at": { + "description": "Stop timestamp.", + "type": "string" + }, + "reason": { + "description": "Worker stop code.", + "type": "string" + } + }, + "required": [ + "reason", + "at" + ], + "type": "object" + }, + "type": "array" + } + }, + "required": [ + "pending", + "processing", + "failed", + "blocked", + "oldestPendingAt", + "extractionAvailable", + "limited", + "gaps" + ], + "type": "object" + }, + "complete": { + "description": "All counted candidates returned, relevance established and the scope resolved; not semantic recall.", + "type": "boolean" + }, + "expansion": { + "description": "The operation a line handle names.", + "properties": { + "available": { + "description": "True: shadowgraph_expand serves the full record behind a line.", + "type": "boolean" + }, + "operation": { + "description": "Operation name.", + "type": "string" + } + }, + "required": [ + "operation", + "available" + ], + "type": "object" + }, + "fallback": { + "description": "Whether fuller delivery replaced relevance or a line.", + "properties": { + "reason": { + "anyOf": [ + { + "enum": [ + "relevance_not_established", + "decisive_meaning_omitted" + ], + "type": "string" + }, + { + "type": "null" + } + ], + "description": "relevance_not_established: no signal ranked a record, so the working set is delivered. decisive_meaning_omitted: a line could not carry its decisive meaning, so that record is delivered in full." + }, + "used": { + "description": "True when the working set or a full record was delivered instead.", + "type": "boolean" + } + }, + "required": [ + "used", + "reason" + ], + "type": "object" + }, + "hasMore": { + "description": "True when limit left candidates out.", + "type": "boolean" + }, + "items": { + "description": "Ranked records, best first; the working set when fallback reason is relevance_not_established.", + "items": { + "description": "One relevant record, as its line (T1) or in full (T2), with the ranks that selected it.", + "properties": { + "line": { + "description": "A derived claim line (T1): never canonical, bound to the revision it was derived from.", + "properties": { + "boundRevision": { + "description": "The record id and the SHA-256 digest of what the line was derived from.", + "type": "object" + }, + "claimClass": { + "description": "The weakest class among its claims and its cause: quoted, entailed, ambiguous, unsupported, legacy_freetext, or not_classified.", + "type": "string" + }, + "decisiveOmitted": { + "description": "Decisive parts the line could not carry; empty on a delivered line.", + "items": { + "type": "string" + }, + "type": "array" + }, + "derivationVersion": { + "description": "Version of the template.", + "type": "string" + }, + "derived": { + "description": "Always true: a line is never canonical.", + "type": "boolean" + }, + "expansion": { + "description": "Handle for the full record: operation, record id, digest, as-of, derivation version, scope and derivation time.", + "type": "object" + }, + "kind": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "description": "The kind of that record." + }, + "line": { + "description": "The record in one line, from a versioned template: stored values quoted, recorded conditions stated as recorded.", + "type": "string" + }, + "outcome": { + "description": "Attempts only: result class, outcome-evidence state and cause state.", + "type": "object" + }, + "polarity": { + "description": "Whether decisive text negates, with the negating text verbatim.", + "type": "object" + }, + "preconditions": { + "description": "Recorded reopen and reuse conditions and assumptions, verbatim.", + "type": "object" + }, + "provenance": { + "description": "Source class and capture reference.", + "type": "object" + }, + "recordId": { + "description": "The record the line was derived from.", + "type": "string" + }, + "requiresExpansion": { + "description": "True when a negation is not settled by a verified claim stating it.", + "type": "boolean" + }, + "scope": { + "description": "Project, memory scope, environment and applicability window.", + "type": "object" + }, + "status": { + "description": "Lifecycle, supersession and verification state.", + "type": "object" + } + }, + "required": [ + "recordId", + "kind", + "line", + "claimClass", + "polarity", + "scope", + "preconditions", + "status", + "provenance", + "boundRevision", + "derived", + "derivationVersion", + "decisiveOmitted", + "requiresExpansion", + "expansion" + ], + "type": "object" + }, + "ranks": { + "anyOf": [ + { + "description": "Position this item held in each signal list, counting from 1, or null where that signal did not rank it.", + "properties": { + "graph": { + "anyOf": [ + { + "type": "integer" + }, + { + "type": "null" + } + ], + "description": "Position in the graph-distance list; null when no focalId was supplied." + }, + "lexical": { + "anyOf": [ + { + "type": "integer" + }, + { + "type": "null" + } + ], + "description": "Position in the BM25-style lexical list." + }, + "semantic": { + "anyOf": [ + { + "type": "integer" + }, + { + "type": "null" + } + ], + "description": "Position in the vector list; null when no compatible query vector or provider existed." + }, + "temporal": { + "anyOf": [ + { + "type": "integer" + }, + { + "type": "null" + } + ], + "description": "Position in the recency list; null when neither asOf nor preferRecent was supplied." + } + }, + "required": [ + "lexical", + "semantic", + "graph", + "temporal" + ], + "type": "object" + }, + { + "type": "null" + } + ], + "description": "Position in each signal list; null for a working-set record delivered by the fallback." + }, + "record": { + "description": "One stored entity: a decision, attempt, memory, fact, or alternative. Fields vary by kind, and an entity imported from an older schema may carry fewer of them.", + "properties": { + "actor": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "description": "Who performed the write." + }, + "client": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "description": "Which client performed the write." + }, + "createdAt": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "description": "ISO 8601 creation time." + }, + "id": { + "description": "Stable entity identifier.", + "type": "string" + }, + "kind": { + "description": "Entity kind: decision, attempt, memory, fact, relation, review, or alternative.", + "type": "string" + }, + "project": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "description": "Project namespace; null for an unattributed record or one imported from before projects." + }, + "schemaVersion": { + "description": "Storage schema version this entity was written under. A value above the build’s own version is preserved rather than downgraded.", + "type": "integer" + }, + "sessionId": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "description": "Session identifier recorded with the write." + }, + "sourceClass": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "description": "Claimed origin class recorded with the write. A claim, never proof." + }, + "sourceRaw": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "description": "The original origin label when it differed from sourceClass. Audit only; never evidence." + }, + "updatedAt": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "description": "ISO 8601 time of the last change." + } + }, + "type": "object" + }, + "score": { + "anyOf": [ + { + "type": "number" + }, + { + "type": "null" + } + ], + "description": "Fused rank score; null for a working-set record delivered by the fallback." + }, + "temporalEvidence": { + "description": "What the stored times and supersession support: when it was recorded, when it held, whether it holds now.", + "properties": { + "currentState": { + "anyOf": [ + { + "description": "Whether it holds at the read instant, and on what basis.", + "properties": { + "basis": { + "anyOf": [ + { + "enum": [ + "explicit_supersession", + "validity_window", + "recording_order_only" + ], + "type": "string" + }, + { + "type": "null" + } + ], + "description": "What decides it; null when nothing temporal does." + }, + "evidence": { + "description": "The records that decide it, at most 10.", + "items": { + "type": "string" + }, + "type": "array" + }, + "evidenceOmitted": { + "description": "Deciding records not named.", + "minimum": 0, + "type": "integer" + }, + "state": { + "description": "unresolved: only the recording order sets it apart from another version. undetermined: no event time places it at the read instant.", + "enum": [ + "current", + "historical", + "not_yet_valid", + "unresolved", + "undetermined" + ], + "type": "string" + } + }, + "required": [ + "state", + "basis", + "evidence", + "evidenceOmitted" + ], + "type": "object" + }, + { + "type": "null" + } + ], + "description": "null for an attempt, an event." + }, + "eventTime": { + "description": "When it held, if stored apart from the recording time.", + "properties": { + "at": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "description": "The event time, when known." + }, + "state": { + "description": "unknown: no event time stored apart from the recording time.", + "enum": [ + "known", + "unknown" + ], + "type": "string" + } + }, + "required": [ + "at", + "state" + ], + "type": "object" + }, + "recordedAt": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "description": "When it was recorded." + } + }, + "required": [ + "recordedAt", + "eventTime", + "currentState" + ], + "type": "object" + }, + "tier": { + "description": "T1 carries line, T2 carries record.", + "enum": [ + "T1", + "T2" + ], + "type": "string" + } + }, + "required": [ + "tier", + "score", + "ranks", + "temporalEvidence" + ], + "type": "object" + }, + "type": "array" + }, + "limitSource": { + "description": "Whose choice bounded the items.", + "enum": [ + "caller", + "default" + ], + "type": "string" + }, + "limitation": { + "description": "Limits of this view.", + "properties": { + "code": { + "description": "Stable limitation code.", + "type": "string" + }, + "detail": { + "description": "What this view cannot establish.", + "type": "string" + } + }, + "required": [ + "code", + "detail" + ], + "type": "object" + }, + "lines": { + "description": "One entry per delivered line, in item order.", + "items": { + "description": "A delivered line.", + "properties": { + "claimClass": { + "description": "The claim class of that line.", + "type": "string" + }, + "recordId": { + "description": "The record the line was derived from.", + "type": "string" + }, + "requiresExpansion": { + "description": "Whether that line requires expansion.", + "type": "boolean" + } + }, + "required": [ + "recordId", + "claimClass", + "requiresExpansion" + ], + "type": "object" + }, + "type": "array" + }, + "omitted": { + "description": "total minus returned.", + "minimum": 0, + "type": "integer" + }, + "processing": { + "description": "Scoped capture processing; extraction is inactive in this build.", + "properties": { + "blocked": { + "description": "Items whose extraction is blocked.", + "minimum": 0, + "type": "integer" + }, + "extractionAvailable": { + "description": "Whether extraction runs.", + "type": "boolean" + }, + "failed": { + "description": "Items whose extraction failed.", + "minimum": 0, + "type": "integer" + }, + "gaps": { + "description": "Capture refusal/unread gaps; no identities.", + "items": { + "properties": { + "from": { + "description": "Gap start time.", + "type": "string" + }, + "reason": { + "description": "Why capture has a gap.", + "enum": [ + "maxQueueDepth", + "maxStoreBytes", + "maxItemsPerSession", + "session_in_another_project", + "raw_expired", + "transcript_unrecognised", + "session_left_project", + "transcript_rewritten", + "transcript_reanchored", + "transcript_incomplete_at_end", + "transcript_line_oversized", + "tool_calls_not_captured" + ], + "type": "string" + }, + "sessions": { + "description": "Sessions covered by this gap.", + "minimum": 0, + "type": "integer" + }, + "to": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "description": "End time, if known." + } + }, + "required": [ + "reason", + "from", + "to" + ], + "type": "object" + }, + "type": "array" + }, + "limited": { + "description": "Admission limits; accepted items kept.", + "items": { + "properties": { + "ceiling": { + "description": "The limit value.", + "minimum": 0, + "type": "integer" + }, + "limit": { + "description": "The limit reached.", + "enum": [ + "maxQueueDepth", + "maxStoreBytes" + ], + "type": "string" + }, + "since": { + "description": "When refusal began.", + "type": "string" + } + }, + "required": [ + "limit", + "ceiling", + "since" + ], + "type": "object" + }, + "type": "array" + }, + "oldestPendingAt": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "description": "When the oldest pending item arrived." + }, + "pending": { + "description": "Items awaiting extraction.", + "minimum": 0, + "type": "integer" + }, + "processing": { + "description": "Items an extraction has claimed; present when the store holds capture state.", + "minimum": 0, + "type": "integer" + }, + "workerErrors": { + "description": "Scoped worker stops; fixed codes.", + "items": { + "properties": { + "at": { + "description": "Stop timestamp.", + "type": "string" + }, + "reason": { + "description": "Worker stop code.", + "type": "string" + } + }, + "required": [ + "reason", + "at" + ], + "type": "object" + }, + "type": "array" + } + }, + "required": [ + "pending", + "failed", + "blocked", + "oldestPendingAt", + "extractionAvailable" + ], + "type": "object" + }, + "relevance": { + "description": "Whether any signal established relevance, and which signals ran.", + "properties": { + "established": { + "description": "True when the lexical, semantic or graph signal ranked a record. Recency orders records; it never selects one.", + "type": "boolean" + }, + "signals": { + "description": "Availability of each signal.", + "properties": { + "graph": { + "description": "Distance from focalId.", + "properties": { + "available": { + "description": "Whether the signal ran.", + "type": "boolean" + }, + "matched": { + "description": "Records it ranked.", + "minimum": 0, + "type": "integer" + } + }, + "required": [ + "available", + "matched" + ], + "type": "object" + }, + "lexical": { + "description": "Content-word matching: available when the query has a content word; matched counts records sharing one. Item ranks use every term.", + "properties": { + "available": { + "description": "Whether the signal ran.", + "type": "boolean" + }, + "matched": { + "description": "Records it ranked.", + "minimum": 0, + "type": "integer" + } + }, + "required": [ + "available", + "matched" + ], + "type": "object" + }, + "semantic": { + "description": "Meaning; never available on this read.", + "properties": { + "available": { + "description": "Whether the signal ran.", + "type": "boolean" + }, + "matched": { + "description": "Records it ranked.", + "minimum": 0, + "type": "integer" + } + }, + "required": [ + "available", + "matched" + ], + "type": "object" + }, + "temporal": { + "description": "Recency from asOf.", + "properties": { + "available": { + "description": "Whether the signal ran.", + "type": "boolean" + }, + "matched": { + "description": "Records it ranked.", + "minimum": 0, + "type": "integer" + } + }, + "required": [ + "available", + "matched" + ], + "type": "object" + } + }, + "required": [ + "lexical", + "semantic", + "graph", + "temporal" + ], + "type": "object" + } + }, + "required": [ + "established", + "signals" + ], + "type": "object" + }, + "returned": { + "description": "Items in this response.", + "minimum": 0, + "type": "integer" + }, + "scope": { + "description": "The resolved read boundary.", + "properties": { + "grant": { + "anyOf": [ + { + "type": "null" + }, + { + "properties": { + "accessId": { + "description": "The currently rechecked grant identifier.", + "type": "string" + }, + "expiresAt": { + "description": "Earliest effective expiry of this read authority.", + "type": "string" + }, + "surface": { + "description": "Actual runtime surface of this read.", + "enum": [ + "cli", + "mcp", + "http" + ], + "type": "string" + } + }, + "required": [ + "accessId", + "expiresAt", + "surface" + ], + "type": "object" + } + ], + "description": "Effective rechecked grant, or null." + }, + "originPresented": { + "description": "Usable origin presented; not project selection.", + "type": "boolean" + }, + "project": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "description": "Resolved project, or null." + }, + "requestState": { + "description": "Whether a project was resolved.", + "enum": [ + "project_selected", + "project_unresolved" + ], + "type": "string" + } + }, + "required": [ + "project", + "requestState", + "originPresented", + "grant" + ], + "type": "object" + }, + "temporal": { + "description": "The as-of instant, and how many items have no stored event time or rest on the recording order only.", + "properties": { + "asOf": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "description": "The asOf given, or null." + }, + "eventTimeUnknown": { + "description": "Items whose event time is unknown.", + "minimum": 0, + "type": "integer" + }, + "recordingOrderOnly": { + "description": "Items whose state rests on the recording order only.", + "minimum": 0, + "type": "integer" + } + }, + "required": [ + "asOf", + "eventTimeUnknown", + "recordingOrderOnly" + ], + "type": "object" + }, + "total": { + "description": "Candidates in total.", + "minimum": 0, + "type": "integer" + } + }, + "required": [ + "scope", + "relevance", + "fallback", + "byKind", + "total", + "returned", + "omitted", + "hasMore", + "complete", + "limitSource", + "limitation", + "temporal", + "lines", + "processing", + "expansion", + "items" + ], + "type": "object" +} - added
Output schema / properties / reusableAttemptsAdded value: +{ + "description": "Attempts whose reusableWhen conditions all hold now. The recorded failure still stands, and this is not authorisation to retry.", + "items": { + "description": "An attempt whose reusableWhen conditions ALL hold now, with none unresolved. The recorded failure still stands, and this is not authorisation to retry.", + "properties": { + "attemptId": { + "description": "The attempt.", + "type": "string" + }, + "resultClass": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "description": "Declared or observed result class, or null when the wording heuristic classified it." + }, + "satisfiedConditions": { + "description": "Every condition that had to hold, and the evidence for each.", + "items": { + "description": "One evaluated reopen condition. Verdict \"unknown\" means it could not be evaluated from available evidence, which is not a pass.", + "properties": { + "alternativeId": { + "description": "Alternative carrying it.", + "type": "string" + }, + "alternativeLabel": { + "description": "Label of that alternative.", + "type": "string" + }, + "attemptId": { + "description": "Attempt the condition belongs to, for a reusableWhen rule.", + "type": "string" + }, + "conflictingEvidence": { + "description": "Equally applicable facts that disagree. The verdict rests on the deterministic winner.", + "items": { + "description": "A fact a verdict came from. Unrecorded fields are omitted, never filled in.", + "properties": { + "factId": { + "description": "The observed fact.", + "type": "string" + }, + "observedAt": { + "description": "When observed, if recorded.", + "type": "string" + }, + "sourceClass": { + "description": "Provenance class, if recorded.", + "type": "string" + }, + "validFrom": { + "description": "Validity start, if recorded.", + "type": "string" + }, + "value": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + }, + { + "type": "null" + }, + { + "type": "array" + }, + { + "type": "object" + } + ], + "description": "A stored value, any lossless JSON value." + }, + "verificationStatus": { + "description": "Verification status, if recorded.", + "type": "string" + } + }, + "required": [ + "factId", + "value" + ], + "type": "object" + }, + "type": "array" + }, + "decisionId": { + "description": "Decision the condition belongs to, for a reopenWhen rule.", + "type": "string" + }, + "evidence": { + "description": "Provenance of the value used.", + "type": "object" + }, + "expected": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + }, + { + "type": "null" + }, + { + "type": "array" + }, + { + "type": "object" + } + ], + "description": "A stored value, any lossless JSON value." + }, + "key": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "description": "Fact key read." + }, + "observed": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + }, + { + "type": "null" + }, + { + "type": "array" + }, + { + "type": "object" + } + ], + "description": "A stored value, any lossless JSON value." + }, + "operator": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "description": "Operator the rule declared." + }, + "reason": { + "description": "Why this verdict.", + "type": "string" + }, + "unit": { + "description": "Unit the rule declared, if any.", + "type": "string" + }, + "verdict": { + "description": "Evaluation result.", + "enum": [ + "true", + "false", + "unknown" + ], + "type": "string" + } + }, + "required": [ + "key", + "operator", + "verdict", + "reason" + ], + "type": "object" + }, + "type": "array" + }, + "solution": { + "description": "What was tried.", + "type": "string" + } + }, + "required": [ + "attemptId", + "satisfiedConditions" + ], + "type": "object" + }, + "type": "array" +} - changed
Output schema / properties / staleAssumptions / items / properties / project / descriptionPrevious value: -"Project namespace; records imported from a schema that predates projects may carry null."New value: +"Project namespace; null for an unattributed record or one imported from before projects." - removed
Output schema / properties / suggestedQuestionsRemoved value: -{ - "description": "Questions for the low-confidence decisions in this project.", - "items": { - "type": "string" - }, - "type": "array" -} - changed
Output schema / requiredPrevious value: -[ - "project", - "activeDecisions", - "staleAssumptions", - "failedAttemptsToAvoid", - "openReviews", - "suggestedQuestions", - "completeness" -]New value: +[ + "project", + "activeDecisions", + "staleAssumptions", + "failedAttempts", + "firedConditions", + "belowConfidenceThreshold", + "completeness", + "notice" +]
- Added
shadowgraph_expand - Removed
shadowgraph_journal - Removed
shadowgraph_link - Changed
shadowgraph_maintain12 fields changed- added
Input schema / properties / accessIdAdded value: +{ + "description": "Grant ID, rechecked at use.", + "type": "string" +} - added
Input schema / properties / grantIdAdded value: +{ + "description": "Alias for accessId; conflicting identifiers are refused.", + "type": "string" +} - added
Input schema / properties / originIdAdded value: +{ + "description": "Capture-origin id; with no project the record belongs to it alone.", + "type": "string" +} - added
Input schema / properties / projectAdded value: +{ + "description": "Project or confirmed workspace binding; otherwise origin-only. No identity returns an empty scoped view.", + "type": "string" +} - added
Output schema / properties / diagnosticsAdded value: +{ + "description": "Conditions that could not be settled, or that rest on facts which disagree.", + "items": { + "description": "Unresolved or contested conditions on one decision or attempt. Not a review signal: neither a breach nor a confirmed-safe decision.", + "properties": { + "attemptId": { + "description": "The attempt involved, for reusableWhen conditions.", + "type": "string" + }, + "conditions": { + "description": "The unresolved or contested conditions.", + "items": { + "description": "One evaluated reopen condition. Verdict \"unknown\" means it could not be evaluated from available evidence, which is not a pass.", + "properties": { + "alternativeId": { + "description": "Alternative carrying it.", + "type": "string" + }, + "alternativeLabel": { + "description": "Label of that alternative.", + "type": "string" + }, + "attemptId": { + "description": "Attempt the condition belongs to, for a reusableWhen rule.", + "type": "string" + }, + "conflictingEvidence": { + "description": "Equally applicable facts that disagree. The verdict rests on the deterministic winner.", + "items": { + "description": "A fact a verdict came from. Unrecorded fields are omitted, never filled in.", + "properties": { + "factId": { + "description": "The observed fact.", + "type": "string" + }, + "observedAt": { + "description": "When observed, if recorded.", + "type": "string" + }, + "sourceClass": { + "description": "Provenance class, if recorded.", + "type": "string" + }, + "validFrom": { + "description": "Validity start, if recorded.", + "type": "string" + }, + "value": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + }, + { + "type": "null" + }, + { + "type": "array" + }, + { + "type": "object" + } + ], + "description": "A stored value, any lossless JSON value." + }, + "verificationStatus": { + "description": "Verification status, if recorded.", + "type": "string" + } + }, + "required": [ + "factId", + "value" + ], + "type": "object" + }, + "type": "array" + }, + "decisionId": { + "description": "Decision the condition belongs to, for a reopenWhen rule.", + "type": "string" + }, + "evidence": { + "description": "Provenance of the value used.", + "type": "object" + }, + "expected": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + }, + { + "type": "null" + }, + { + "type": "array" + }, + { + "type": "object" + } + ], + "description": "A stored value, any lossless JSON value." + }, + "key": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "description": "Fact key read." + }, + "observed": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + }, + { + "type": "null" + }, + { + "type": "array" + }, + { + "type": "object" + } + ], + "description": "A stored value, any lossless JSON value." + }, + "operator": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "description": "Operator the rule declared." + }, + "reason": { + "description": "Why this verdict.", + "type": "string" + }, + "unit": { + "description": "Unit the rule declared, if any.", + "type": "string" + }, + "verdict": { + "description": "Evaluation result.", + "enum": [ + "true", + "false", + "unknown" + ], + "type": "string" + } + }, + "required": [ + "key", + "operator", + "verdict", + "reason" + ], + "type": "object" + }, + "type": "array" + }, + "decisionId": { + "description": "The decision involved, for reopenWhen conditions.", + "type": "string" + }, + "title": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "description": "Decision title, when stored." + } + }, + "required": [ + "conditions" + ], + "type": "object" + }, + "type": "array" +} - added
Output schema / properties / due / items / properties / reviewSignalIdAdded value: +{ + "description": "Pass this to shadowgraph_ack_review to acknowledge this review.", + "type": "string" +} - added
Output schema / properties / due / items / properties / reviewSignalStatusAdded value: +{ + "description": "Whether this review is open or acknowledged, or unpersisted: no stored signal, because context is a read or the evaluation was wider. Entries are recomputed from current evidence; an acknowledged one still appears.", + "enum": [ + "open", + "acknowledged", + "unpersisted" + ], + "type": "string" +} - added
Output schema / properties / due / items / properties / violatedConditionsAdded value: +{ + "description": "The conditions that actually fired, each naming its operator, expected and observed value, and the fact it was computed from.", + "items": { + "description": "One evaluated reopen condition. Verdict \"unknown\" means it could not be evaluated from available evidence, which is not a pass.", + "properties": { + "alternativeId": { + "description": "Alternative carrying it.", + "type": "string" + }, + "alternativeLabel": { + "description": "Label of that alternative.", + "type": "string" + }, + "attemptId": { + "description": "Attempt the condition belongs to, for a reusableWhen rule.", + "type": "string" + }, + "conflictingEvidence": { + "description": "Equally applicable facts that disagree. The verdict rests on the deterministic winner.", + "items": { + "description": "A fact a verdict came from. Unrecorded fields are omitted, never filled in.", + "properties": { + "factId": { + "description": "The observed fact.", + "type": "string" + }, + "observedAt": { + "description": "When observed, if recorded.", + "type": "string" + }, + "sourceClass": { + "description": "Provenance class, if recorded.", + "type": "string" + }, + "validFrom": { + "description": "Validity start, if recorded.", + "type": "string" + }, + "value": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + }, + { + "type": "null" + }, + { + "type": "array" + }, + { + "type": "object" + } + ], + "description": "A stored value, any lossless JSON value." + }, + "verificationStatus": { + "description": "Verification status, if recorded.", + "type": "string" + } + }, + "required": [ + "factId", + "value" + ], + "type": "object" + }, + "type": "array" + }, + "decisionId": { + "description": "Decision the condition belongs to, for a reopenWhen rule.", + "type": "string" + }, + "evidence": { + "description": "Provenance of the value used.", + "type": "object" + }, + "expected": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + }, + { + "type": "null" + }, + { + "type": "array" + }, + { + "type": "object" + } + ], + "description": "A stored value, any lossless JSON value." + }, + "key": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "description": "Fact key read." + }, + "observed": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + }, + { + "type": "null" + }, + { + "type": "array" + }, + { + "type": "object" + } + ], + "description": "A stored value, any lossless JSON value." + }, + "operator": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "description": "Operator the rule declared." + }, + "reason": { + "description": "Why this verdict.", + "type": "string" + }, + "unit": { + "description": "Unit the rule declared, if any.", + "type": "string" + }, + "verdict": { + "description": "Evaluation result.", + "enum": [ + "true", + "false", + "unknown" + ], + "type": "string" + } + }, + "required": [ + "key", + "operator", + "verdict", + "reason" + ], + "type": "object" + }, + "type": "array" +} - added
Output schema / properties / readProvenanceAdded value: +{ + "description": "Original read bounds; reuse intersects these with currently valid authority.", + "properties": { + "accessId": { + "description": "Original grant, revalidated on every reuse.", + "type": "string" + }, + "expiresAt": { + "description": "Original effective expiry; reuse cannot extend it.", + "type": "string" + }, + "request": { + "description": "Original request ownership, preserved during expansion.", + "properties": { + "originId": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "description": "Original capture origin, or null when absent." + }, + "project": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "description": "Original resolved project, or null when unresolved." + } + }, + "required": [ + "project", + "originId" + ], + "type": "object" + }, + "scope": { + "description": "Finite explicit owner bounds; project names, origins and legacy attribution are disjoint.", + "properties": { + "legacyAttributions": { + "description": "Explicit legacy ownership classes; neither is a named project.", + "items": { + "enum": [ + "legacy_ambiguous", + "legacy_unattributed" + ], + "type": "string" + }, + "type": "array" + }, + "originIds": { + "description": "Exact nonempty origin identifiers for unattributed content.", + "items": { + "type": "string" + }, + "type": "array" + }, + "projects": { + "description": "Exact named projects, including a real project named default if requested.", + "items": { + "type": "string" + }, + "type": "array" + } + }, + "type": "object" + }, + "surfaces": { + "description": "Original permitted surfaces; reuse can only narrow them.", + "items": { + "enum": [ + "cli", + "mcp", + "http" + ], + "type": "string" + }, + "type": "array" + }, + "version": { + "const": 1, + "description": "Version of this bounded read provenance.", + "type": "integer" + } + }, + "required": [ + "version", + "request", + "accessId", + "scope", + "surfaces", + "expiresAt" + ], + "type": "object" +} - added
Output schema / properties / reviewSignals / items / properties / coverageAdded value: +{ + "description": "Exact conditions covered, and part of this identity.", + "items": { + "type": "string" + }, + "type": "array" +} - changed
Output schema / properties / reviewSignals / items / properties / reason / descriptionPrevious value: -"Why the signal was raised. Together with decisionId this is the dedupe identity, so the same cause never raises a second signal."New value: +"Why it was raised. Identity is this plus decisionId and coverage." - changed
Output schema / properties / reviewSignals / items / requiredPrevious value: -[ - "id", - "kind", - "decisionId", - "reason", - "alternativesToReconsider", - "status", - "createdAt" -]New value: +[ + "id", + "kind", + "decisionId", + "status", + "createdAt" +]
- Removed
shadowgraph_purge - Removed
shadowgraph_purge_preview - Removed
shadowgraph_rebuild - Changed
shadowgraph_recall17 fields changed- added
Input schema / properties / accessIdAdded value: +{ + "description": "Grant ID, rechecked at use.", + "type": "string" +} - added
Input schema / properties / grantIdAdded value: +{ + "description": "Alias for accessId; conflicting identifiers are refused.", + "type": "string" +} - added
Input schema / properties / originIdAdded value: +{ + "description": "Capture-origin id; with no project the record belongs to it alone.", + "type": "string" +} - changed
Input schema / properties / project / descriptionPrevious value: -"Project to recall from. Defaults to \"default\" for memory records rather than meaning all projects."New value: +"Project or confirmed workspace binding; otherwise origin-only. No identity returns an empty scoped view." - added
Input schema / properties / readProvenanceAdded value: +{ + "description": "Original expansion bounds; cannot widen access.", + "type": "object" +} - added
Output schema / properties / completeness / properties / captureAdded value: +{ + "description": "Scoped unprocessed capture, when present.", + "properties": { + "blocked": { + "description": "Items blocked.", + "minimum": 0, + "type": "integer" + }, + "expired": { + "description": "Raw expired before extraction; a gap, not backlog.", + "minimum": 0, + "type": "integer" + }, + "extractionAvailable": { + "description": "Whether extraction runs.", + "type": "boolean" + }, + "failed": { + "description": "Items failed.", + "minimum": 0, + "type": "integer" + }, + "gaps": { + "description": "Capture refusal/unread gaps; no identities.", + "items": { + "properties": { + "from": { + "description": "Gap start time.", + "type": "string" + }, + "reason": { + "description": "Why capture has a gap.", + "enum": [ + "maxQueueDepth", + "maxStoreBytes", + "maxItemsPerSession", + "session_in_another_project", + "raw_expired", + "transcript_unrecognised", + "session_left_project", + "transcript_rewritten", + "transcript_reanchored", + "transcript_incomplete_at_end", + "transcript_line_oversized", + "tool_calls_not_captured" + ], + "type": "string" + }, + "sessions": { + "description": "Sessions covered by this gap.", + "minimum": 0, + "type": "integer" + }, + "to": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "description": "End time, if known." + } + }, + "required": [ + "reason", + "from", + "to" + ], + "type": "object" + }, + "type": "array" + }, + "limited": { + "description": "Admission limits; accepted items kept.", + "items": { + "properties": { + "ceiling": { + "description": "The limit value.", + "minimum": 0, + "type": "integer" + }, + "limit": { + "description": "The limit reached.", + "enum": [ + "maxQueueDepth", + "maxStoreBytes" + ], + "type": "string" + }, + "since": { + "description": "When refusal began.", + "type": "string" + } + }, + "required": [ + "limit", + "ceiling", + "since" + ], + "type": "object" + }, + "type": "array" + }, + "oldestPendingAt": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "description": "Oldest pending capture." + }, + "pending": { + "description": "Items waiting.", + "minimum": 0, + "type": "integer" + }, + "processing": { + "description": "Items claimed.", + "minimum": 0, + "type": "integer" + }, + "workerErrors": { + "description": "Scoped worker stops; fixed codes.", + "items": { + "properties": { + "at": { + "description": "Stop timestamp.", + "type": "string" + }, + "reason": { + "description": "Worker stop code.", + "type": "string" + } + }, + "required": [ + "reason", + "at" + ], + "type": "object" + }, + "type": "array" + } + }, + "required": [ + "pending", + "processing", + "failed", + "blocked", + "oldestPendingAt", + "extractionAvailable", + "limited", + "gaps" + ], + "type": "object" +} - changed
Output schema / properties / completeness / properties / complete / descriptionPrevious value: -"True only when every matching item is present."New value: +"Known-candidate coverage; false for unresolved scope, withheld detail or pending capture; not recall." - added
Output schema / properties / completeness / properties / limitationAdded value: +{ + "description": "Limits of this view.", + "properties": { + "code": { + "description": "Stable limitation code.", + "type": "string" + }, + "detail": { + "description": "What this view cannot establish.", + "type": "string" + } + }, + "required": [ + "code", + "detail" + ], + "type": "object" +} - changed
Output schema / properties / completeness / properties / losslessItems / descriptionPrevious value: -"Always true: each returned item is a full-fidelity record, never a summary or a truncated field."New value: +"False when returned items have withheld or transformed detail." - added
Output schema / properties / completeness / properties / quarantinedAdded value: +{ + "description": "Items withheld as possibly purged.", + "minimum": 0, + "type": "integer" +} - changed
Output schema / properties / completeness / properties / scope / descriptionPrevious value: -"The project, query, and structured filters that produced this result, so it explains its own derivation."New value: +"The resolved read boundary." - added
Output schema / properties / completeness / properties / scope / propertiesAdded value: +{ + "grant": { + "anyOf": [ + { + "type": "null" + }, + { + "properties": { + "accessId": { + "description": "The currently rechecked grant identifier.", + "type": "string" + }, + "expiresAt": { + "description": "Earliest effective expiry of this read authority.", + "type": "string" + }, + "surface": { + "description": "Actual runtime surface of this read.", + "enum": [ + "cli", + "mcp", + "http" + ], + "type": "string" + } + }, + "required": [ + "accessId", + "expiresAt", + "surface" + ], + "type": "object" + } + ], + "description": "Effective rechecked grant, or null." + }, + "originPresented": { + "description": "Usable origin presented; not project selection.", + "type": "boolean" + }, + "project": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "description": "Resolved project, or null." + }, + "requestState": { + "description": "Whether a project was resolved.", + "enum": [ + "project_selected", + "project_unresolved" + ], + "type": "string" + } +} - added
Output schema / properties / completeness / properties / scope / requiredAdded value: +[ + "project", + "requestState", + "originPresented", + "grant" +] - added
Output schema / properties / completeness / properties / signals / properties / semantic / properties / indexedAdded value: +{ + "description": "Candidates carrying a stored vector, with or without a query vector.", + "minimum": 0, + "type": "integer" +} - changed
Output schema / properties / completeness / properties / signals / properties / semantic / requiredPrevious value: -[ - "available", - "matched", - "reason" -]New value: +[ + "available", + "matched", + "indexed", + "reason" +] - changed
Output schema / properties / items / items / properties / record / properties / project / descriptionPrevious value: -"Project namespace; records imported from a schema that predates projects may carry null."New value: +"Project namespace; null for an unattributed record or one imported from before projects." - added
Output schema / properties / readProvenanceAdded value: +{ + "description": "Original read bounds; reuse intersects these with currently valid authority.", + "properties": { + "accessId": { + "description": "Original grant, revalidated on every reuse.", + "type": "string" + }, + "expiresAt": { + "description": "Original effective expiry; reuse cannot extend it.", + "type": "string" + }, + "request": { + "description": "Original request ownership, preserved during expansion.", + "properties": { + "originId": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "description": "Original capture origin, or null when absent." + }, + "project": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "description": "Original resolved project, or null when unresolved." + } + }, + "required": [ + "project", + "originId" + ], + "type": "object" + }, + "scope": { + "description": "Finite explicit owner bounds; project names, origins and legacy attribution are disjoint.", + "properties": { + "legacyAttributions": { + "description": "Explicit legacy ownership classes; neither is a named project.", + "items": { + "enum": [ + "legacy_ambiguous", + "legacy_unattributed" + ], + "type": "string" + }, + "type": "array" + }, + "originIds": { + "description": "Exact nonempty origin identifiers for unattributed content.", + "items": { + "type": "string" + }, + "type": "array" + }, + "projects": { + "description": "Exact named projects, including a real project named default if requested.", + "items": { + "type": "string" + }, + "type": "array" + } + }, + "type": "object" + }, + "surfaces": { + "description": "Original permitted surfaces; reuse can only narrow them.", + "items": { + "enum": [ + "cli", + "mcp", + "http" + ], + "type": "string" + }, + "type": "array" + }, + "version": { + "const": 1, + "description": "Version of this bounded read provenance.", + "type": "integer" + } + }, + "required": [ + "version", + "request", + "accessId", + "scope", + "surfaces", + "expiresAt" + ], + "type": "object" +}
- Added
shadowgraph_reconsider - Changed
shadowgraph_record_attempt12 fields changed- added
Input schema / descriptionAdded value: +"ShadowGraph generates and returns canonical IDs. Supplying a creation id is refused before lookup or retry; keep returned IDs for later references." - added
Input schema / notAdded value: +{ + "required": [ + "id" + ] +} - changed
Input schema / properties / idempotencyKey / descriptionPrevious value: -"Retry key scoped by project and operation: reuse it so a retry returns the first result instead of writing a duplicate. Without it every call creates a new entity."New value: +"Retry identity within the project or origin and operation (also scope/type/key for memory). Reuse it to recover the original canonical ID; this key is never an entity ID." - added
Input schema / properties / originIdAdded value: +{ + "description": "Capture-origin id; with no project the record belongs to it alone.", + "type": "string" +} - changed
Input schema / properties / project / descriptionPrevious value: -"Project namespace. Defaults to \"default\"; an empty string is rejected."New value: +"Owning project; required unless originId is set, else the write is refused." - changed
Input schema / properties / result / descriptionPrevious value: -"What happened. Required, non-empty, and searchable content. Wording such as failed, error, or regression is what makes the attempt surface in shadowgraph_context as one to avoid."New value: +"What happened. Required, non-empty, and searchable content. With no resultClass, wording such as failed, error, or regression is what places the attempt in shadowgraph_context failedAttempts; a captured attempt's wording is never read." - added
Input schema / properties / resultClassAdded value: +{ + "description": "Classify the result instead of leaving it to the wording heuristic. Set it when the result text does not say failed, error, or regression, or when it does but the attempt did not fail.", + "enum": [ + "failed", + "succeeded", + "inconclusive" + ], + "type": "string" +} - added
Output schema / properties / causalClaimAdded value: +{ + "description": "The cause, attributed apart from the attempt: state recorded (the reason, agent_claimed), unknown, not_recorded, or legacy_freetext (a reason stored before causes were, never classed or evidenced).", + "type": "object" +} - changed
Output schema / properties / project / descriptionPrevious value: -"Project namespace; records imported from a schema that predates projects may carry null."New value: +"Project namespace; null for an unattributed record or one imported from before projects." - changed
Output schema / properties / reason / descriptionPrevious value: -"Why it turned out that way."New value: +"Why it turned out that way, verbatim as recorded." - added
Output schema / properties / resultClassAdded value: +{ + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "description": "Declared or observed: failed, succeeded, or inconclusive. If absent: not captured (no captureRef or outcomeEvidence), the wording heuristic classifies; captured, the outcome is undetermined." +} - changed
Output schema / properties / reusableWhen / descriptionPrevious value: -"Conditions under which the attempt is worth repeating."New value: +"Conditions recorded for reusing the attempt. All must hold, and none may be unresolved."
- Changed
shadowgraph_record_decision8 fields changed- added
Input schema / descriptionAdded value: +"ShadowGraph generates and returns canonical IDs. Supplying a creation id is refused before lookup or retry; keep returned IDs for later references." - added
Input schema / notAdded value: +{ + "required": [ + "id" + ] +} - added
Input schema / properties / alternatives / items / descriptionAdded value: +"ShadowGraph generates and returns canonical IDs. Supplying a creation id is refused before lookup or retry; keep returned IDs for later references." - added
Input schema / properties / alternatives / items / notAdded value: +{ + "required": [ + "id" + ] +} - changed
Input schema / properties / idempotencyKey / descriptionPrevious value: -"Retry key scoped by project and operation: reuse it so a retry returns the first result instead of writing a duplicate. Without it every call creates a new entity."New value: +"Retry identity within the project or origin and operation (also scope/type/key for memory). Reuse it to recover the original canonical ID; this key is never an entity ID." - added
Input schema / properties / originIdAdded value: +{ + "description": "Capture-origin id; with no project the record belongs to it alone.", + "type": "string" +} - changed
Input schema / properties / project / descriptionPrevious value: -"Project namespace. Defaults to \"default\"; an empty string is rejected."New value: +"Owning project; required unless originId is set, else the write is refused." - changed
Output schema / properties / project / descriptionPrevious value: -"Project namespace; records imported from a schema that predates projects may carry null."New value: +"Project namespace; null for an unattributed record or one imported from before projects."
- Changed
shadowgraph_record_fact6 fields changed- added
Input schema / descriptionAdded value: +"ShadowGraph generates and returns canonical IDs. Supplying a creation id is refused before lookup or retry; keep returned IDs for later references." - added
Input schema / notAdded value: +{ + "required": [ + "id" + ] +} - changed
Input schema / properties / idempotencyKey / descriptionPrevious value: -"Retry key scoped by project and operation: reuse it so a retry returns the first result instead of writing a duplicate. Without it every call creates a new entity."New value: +"Retry identity within the project or origin and operation (also scope/type/key for memory). Reuse it to recover the original canonical ID; this key is never an entity ID." - added
Input schema / properties / originIdAdded value: +{ + "description": "Capture-origin id; with no project the record belongs to it alone.", + "type": "string" +} - changed
Input schema / properties / project / descriptionPrevious value: -"Project namespace. Defaults to \"default\"; an empty string is rejected."New value: +"Owning project; required unless originId is set, else the write is refused." - changed
Output schema / properties / project / descriptionPrevious value: -"Project namespace; records imported from a schema that predates projects may carry null."New value: +"Project namespace; null for an unattributed record or one imported from before projects."
- Changed
shadowgraph_record_outcome3 fields changed- added
Input schema / properties / originIdAdded value: +{ + "description": "Capture-origin id; with no project the record belongs to it alone.", + "type": "string" +} - added
Input schema / properties / projectAdded value: +{ + "description": "Owning project; required unless originId is set, else the write is refused.", + "type": "string" +} - changed
Output schema / properties / project / descriptionPrevious value: -"Project namespace; records imported from a schema that predates projects may carry null."New value: +"Project namespace; null for an unattributed record or one imported from before projects."
- Removed
shadowgraph_redact - Changed
shadowgraph_remember7 fields changed- added
Input schema / descriptionAdded value: +"Every envelope and operation rejects a supplied id, including retries, DELETE and NOOP. Memory is selected by its scoped identity tuple; canonical IDs are generated and returned." - added
Input schema / notAdded value: +{ + "required": [ + "id" + ] +} - added
Input schema / properties / idempotencyKeyAdded value: +{ + "description": "Retry identity within the project or origin and operation (also scope/type/key for memory). Reuse it to recover the original canonical ID; this key is never an entity ID.", + "maxLength": 200, + "type": "string" +} - added
Input schema / properties / operations / items / notAdded value: +{ + "required": [ + "id" + ] +} - added
Input schema / properties / originIdAdded value: +{ + "description": "Capture-origin id; with no project the record belongs to it alone.", + "type": "string" +} - changed
Input schema / properties / project / descriptionPrevious value: -"Project namespace. Defaults to \"default\"; an empty string is rejected."New value: +"Owning project; required unless originId is set, else the write is refused." - changed
Output schema / anyOfPrevious value: -[ - { - "properties": { - "indexUpdated": { - "description": "Present when identical content arrived with a different embedding: the index was refreshed without minting a new version.", - "type": "boolean" - }, - "memory": { - "description": "A stored scoped memory version.", - "properties": { - "actor": { - "anyOf": [ - { - "type": "string" - }, - { - "type": "null" - } - ], - "description": "Who performed the write." - }, - "client": { - "anyOf": [ - { - "type": "string" - }, - { - "type": "null" - } - ], - "description": "Which client performed the write." - }, - "createdAt": { - "anyOf": [ - { - "type": "string" - }, - { - "type": "null" - } - ], - "description": "ISO 8601 creation time." - }, - "embedding": { - "anyOf": [ - { - "type": "array" - }, - { - "type": "object" - }, - { - "type": "null" - } - ], - "description": "The stored vector, or null when none was supplied and no provider was configured." - }, - "id": { - "description": "Stable entity identifier.", - "type": "string" - }, - "key": { - "anyOf": [ - { - "type": "string" - }, - { - "type": "null" - } - ], - "description": "Caller-chosen name within the scope and type." - }, - "kind": { - "description": "Entity kind: decision, attempt, memory, fact, relation, review, or alternative.", - "type": "string" - }, - "memoryType": { - "anyOf": [ - { - "type": "string" - }, - { - "type": "null" - } - ], - "description": "preference, profile, goal, instruction, procedure, episode, or note." - }, - "metadata": { - "description": "Caller-owned JSON stored with the memory.", - "type": "object" - }, - "project": { - "anyOf": [ - { - "type": "string" - }, - { - "type": "null" - } - ], - "description": "Project namespace; records imported from a schema that predates projects may carry null." - }, - "schemaVersion": { - "description": "Storage schema version this entity was written under. A value above the build’s own version is preserved rather than downgraded.", - "type": "integer" - }, - "scope": { - "description": "The userId, agentId, and runId this memory is scoped to; each is a string or null.", - "type": "object" - }, - "sessionId": { - "anyOf": [ - { - "type": "string" - }, - { - "type": "null" - } - ], - "description": "Session identifier recorded with the write." - }, - "sourceClass": { - "anyOf": [ - { - "type": "string" - }, - { - "type": "null" - } - ], - "description": "Claimed origin class recorded with the write. A claim, never proof." - }, - "sourceRaw": { - "anyOf": [ - { - "type": "string" - }, - { - "type": "null" - } - ], - "description": "The original origin label when it differed from sourceClass. Audit only; never evidence." - }, - "status": { - "anyOf": [ - { - "type": "string" - }, - { - "type": "null" - } - ], - "description": "active, superseded, or invalidated." - }, - "supersededBy": { - "anyOf": [ - { - "type": "string" - }, - { - "type": "null" - } - ], - "description": "Identifier of the version that replaced this one." - }, - "supersedes": { - "anyOf": [ - { - "type": "string" - }, - { - "type": "null" - } - ], - "description": "Identifier of the version this one replaced." - }, - "tags": { - "description": "Labels stored with the memory.", - "type": "array" - }, - "temporal": { - "description": "Bi-temporal window: validFrom, validTo, recordedAt, invalidatedAt.", - "type": "object" - }, - "text": { - "anyOf": [ - { - "type": "string" - }, - { - "type": "null" - } - ], - "description": "The memory content." - }, - "updatedAt": { - "anyOf": [ - { - "type": "string" - }, - { - "type": "null" - } - ], - "description": "ISO 8601 time of the last change." - }, - "verificationStatus": { - "anyOf": [ - { - "type": "string" - }, - { - "type": "null" - } - ], - "description": "Always unverified for memories." - }, - "version": { - "anyOf": [ - { - "type": "integer" - }, - { - "type": "null" - } - ], - "description": "Version number within this identity, incrementing on each superseding write." - } - }, - "required": [ - "id", - "kind" - ], - "type": "object" - }, - "operation": { - "description": "ADD when no active memory existed, UPDATE when one was superseded, NOOP when content was identical.", - "enum": [ - "ADD", - "UPDATE", - "NOOP" - ], - "type": "string" - }, - "previous": { - "description": "A stored scoped memory version.", - "properties": { - "actor": { - "anyOf": [ - { - "type": "string" - }, - { - "type": "null" - } - ], - "description": "Who performed the write." - }, - "client": { - "anyOf": [ - { - "type": "string" - }, - { - "type": "null" - } - ], - "description": "Which client performed the write." - }, - "createdAt": { - "anyOf": [ - { - "type": "string" - }, - { - "type": "null" - } - ], - "description": "ISO 8601 creation time." - }, - "embedding": { - "anyOf": [ - { - "type": "array" - }, - { - "type": "object" - }, - { - "type": "null" - } - ], - "description": "The stored vector, or null when none was supplied and no provider was configured." - }, - "id": { - "description": "Stable entity identifier.", - "type": "string" - }, - "key": { - "anyOf": [ - { - "type": "string" - }, - { - "type": "null" - } - ], - "description": "Caller-chosen name within the scope and type." - }, - "kind": { - "description": "Entity kind: decision, attempt, memory, fact, relation, review, or alternative.", - "type": "string" - }, - "memoryType": { - "anyOf": [ - { - "type": "string" - }, - { - "type": "null" - } - ], - "description": "preference, profile, goal, instruction, procedure, episode, or note." - }, - "metadata": { - "description": "Caller-owned JSON stored with the memory.", - "type": "object" - }, - "project": { - "anyOf": [ - { - "type": "string" - }, - { - "type": "null" - } - ], - "description": "Project namespace; records imported from a schema that predates projects may carry null." - }, - "schemaVersion": { - "description": "Storage schema version this entity was written under. A value above the build’s own version is preserved rather than downgraded.", - "type": "integer" - }, - "scope": { - "description": "The userId, agentId, and runId this memory is scoped to; each is a string or null.", - "type": "object" - }, - "sessionId": { - "anyOf": [ - { - "type": "string" - }, - { - "type": "null" - } - ], - "description": "Session identifier recorded with the write." - }, - "sourceClass": { - "anyOf": [ - { - "type": "string" - }, - { - "type": "null" - } - ], - "description": "Claimed origin class recorded with the write. A claim, never proof." - }, - "sourceRaw": { - "anyOf": [ - { - "type": "string" - }, - { - "type": "null" - } - ], - "description": "The original origin label when it differed from sourceClass. Audit only; never evidence." - }, - "status": { - "anyOf": [ - { - "type": "string" - }, - { - "type": "null" - } - ], - "description": "active, superseded, or invalidated." - }, - "supersededBy": { - "anyOf": [ - { - "type": "string" - }, - { - "type": "null" - } - ], - "description": "Identifier of the version that replaced this one." - }, - "supersedes": { - "anyOf": [ - { - "type": "string" - }, - { - "type": "null" - } - ], - "description": "Identifier of the version this one replaced." - }, - "tags": { - "description": "Labels stored with the memory.", - "type": "array" - }, - "temporal": { - "description": "Bi-temporal window: validFrom, validTo, recordedAt, invalidatedAt.", - "type": "object" - }, - "text": { - "anyOf": [ - { - "type": "string" - }, - { - "type": "null" - } - ], - "description": "The memory content." - }, - "updatedAt": { - "anyOf": [ - { - "type": "string" - }, - { - "type": "null" - } - ], - "description": "ISO 8601 time of the last change." - }, - "verificationStatus": { - "anyOf": [ - { - "type": "string" - }, - { - "type": "null" - } - ], - "description": "Always unverified for memories." - }, - "version": { - "anyOf": [ - { - "type": "integer" - }, - { - "type": "null" - } - ], - "description": "Version number within this identity, incrementing on each superseding write." - } - }, - "required": [ - "id", - "kind" - ], - "type": "object" - } - }, - "required": [ - "operation", - "memory" - ], - "type": "object" - }, - { - "properties": { - "completeness": { - "description": "Plan accounting. This is not the paginated completeness envelope.", - "properties": { - "applied": { - "description": "Results produced, one per submitted operation.", - "minimum": 0, - "type": "integer" - }, - "complete": { - "description": "Always true: a plan is applied in full or rejected in full.", - "type": "boolean" - }, - "requested": { - "description": "Operations submitted.", - "minimum": 0, - "type": "integer" - } - }, - "required": [ - "complete", - "requested", - "applied" - ], - "type": "object" - }, - "results": { - "description": "One result per submitted operation, in order.", - "items": { - "properties": { - "indexUpdated": { - "description": "Present when only the embedding was refreshed.", - "type": "boolean" - }, - "memory": { - "anyOf": [ - { - "description": "A stored scoped memory version.", - "properties": { - "actor": { - "anyOf": [ - { - "type": "string" - }, - { - "type": "null" - } - ], - "description": "Who performed the write." - }, - "client": { - "anyOf": [ - { - "type": "string" - }, - { - "type": "null" - } - ], - "description": "Which client performed the write." - }, - "createdAt": { - "anyOf": [ - { - "type": "string" - }, - { - "type": "null" - } - ], - "description": "ISO 8601 creation time." - }, - "embedding": { - "anyOf": [ - { - "type": "array" - }, - { - "type": "object" - }, - { - "type": "null" - } - ], - "description": "The stored vector, or null when none was supplied and no provider was configured." - }, - "id": { - "description": "Stable entity identifier.", - "type": "string" - }, - "key": { - "anyOf": [ - { - "type": "string" - }, - { - "type": "null" - } - ], - "description": "Caller-chosen name within the scope and type." - }, - "kind": { - "description": "Entity kind: decision, attempt, memory, fact, relation, review, or alternative.", - "type": "string" - }, - "memoryType": { - "anyOf": [ - { - "type": "string" - }, - { - "type": "null" - } - ], - "description": "preference, profile, goal, instruction, procedure, episode, or note." - }, - "metadata": { - "description": "Caller-owned JSON stored with the memory.", - "type": "object" - }, - "project": { - "anyOf": [ - { - "type": "string" - }, - { - "type": "null" - } - ], - "description": "Project namespace; records imported from a schema that predates projects may carry null." - }, - "schemaVersion": { - "description": "Storage schema version this entity was written under. A value above the build’s own version is preserved rather than downgraded.", - "type": "integer" - }, - "scope": { - "description": "The userId, agentId, and runId this memory is scoped to; each is a string or null.", - "type": "object" - }, - "sessionId": { - "anyOf": [ - { - "type": "string" - }, - { - "type": "null" - } - ], - "description": "Session identifier recorded with the write." - }, - "sourceClass": { - "anyOf": [ - { - "type": "string" - }, - { - "type": "null" - } - ], - "description": "Claimed origin class recorded with the write. A claim, never proof." - }, - "sourceRaw": { - "anyOf": [ - { - "type": "string" - }, - { - "type": "null" - } - ], - "description": "The original origin label when it differed from sourceClass. Audit only; never evidence." - }, - "status": { - "anyOf": [ - { - "type": "string" - }, - { - "type": "null" - } - ], - "description": "active, superseded, or invalidated." - }, - "supersededBy": { - "anyOf": [ - { - "type": "string" - }, - { - "type": "null" - } - ], - "description": "Identifier of the version that replaced this one." - }, - "supersedes": { - "anyOf": [ - { - "type": "string" - }, - { - "type": "null" - } - ], - "description": "Identifier of the version this one replaced." - }, - "tags": { - "description": "Labels stored with the memory.", - "type": "array" - }, - "temporal": { - "description": "Bi-temporal window: validFrom, validTo, recordedAt, invalidatedAt.", - "type": "object" - }, - "text": { - "anyOf": [ - { - "type": "string" - }, - { - "type": "null" - } - ], - "description": "The memory content." - }, - "updatedAt": { - "anyOf": [ - { - "type": "string" - }, - { - "type": "null" - } - ], - "description": "ISO 8601 time of the last change." - }, - "verificationStatus": { - "anyOf": [ - { - "type": "string" - }, - { - "type": "null" - } - ], - "description": "Always unverified for memories." - }, - "version": { - "anyOf": [ - { - "type": "integer" - }, - { - "type": "null" - } - ], - "description": "Version number within this identity, incrementing on each superseding write." - } - }, - "required": [ - "id", - "kind" - ], - "type": "object" - }, - { - "type": "null" - } - ], - "description": "The resulting memory, or null for a NOOP on an identity that has no memory." - }, - "operation": { - "description": "What was actually applied, which may differ from the requested action when content already matched.", - "enum": [ - "ADD", - "UPDATE", - "DELETE", - "NOOP" - ], - "type": "string" - }, - "previous": { - "description": "A stored scoped memory version.", - "properties": { - "actor": { - "anyOf": [ - { - "type": "string" - }, - { - "type": "null" - } - ], - "description": "Who performed the write." - }, - "client": { - "anyOf": [ - { - "type": "string" - }, - { - "type": "null" - } - ], - "description": "Which client performed the write." - }, - "createdAt": { - "anyOf": [ - { - "type": "string" - }, - { - "type": "null" - } - ], - "description": "ISO 8601 creation time." - }, - "embedding": { - "anyOf": [ - { - "type": "array" - }, - { - "type": "object" - }, - { - "type": "null" - } - ], - "description": "The stored vector, or null when none was supplied and no provider was configured." - }, - "id": { - "description": "Stable entity identifier.", - "type": "string" - }, - "key": { - "anyOf": [ - { - "type": "string" - }, - { - "type": "null" - } - ], - "description": "Caller-chosen name within the scope and type." - }, - "kind": { - "description": "Entity kind: decision, attempt, memory, fact, relation, review, or alternative.", - "type": "string" - }, - "memoryType": { - "anyOf": [ - { - "type": "string" - }, - { - "type": "null" - } - ], - "description": "preference, profile, goal, instruction, procedure, episode, or note." - }, - "metadata": { - "description": "Caller-owned JSON stored with the memory.", - "type": "object" - }, - "project": { - "anyOf": [ - { - "type": "string" - }, - { - "type": "null" - } - ], - "description": "Project namespace; records imported from a schema that predates projects may carry null." - }, - "schemaVersion": { - "description": "Storage schema version this entity was written under. A value above the build’s own version is preserved rather than downgraded.", - "type": "integer" - }, - "scope": { - "description": "The userId, agentId, and runId this memory is scoped to; each is a string or null.", - "type": "object" - }, - "sessionId": { - "anyOf": [ - { - "type": "string" - }, - { - "type": "null" - } - ], - "description": "Session identifier recorded with the write." - }, - "sourceClass": { - "anyOf": [ - { - "type": "string" - }, - { - "type": "null" - } - ], - "description": "Claimed origin class recorded with the write. A claim, never proof." - }, - "sourceRaw": { - "anyOf": [ - { - "type": "string" - }, - { - "type": "null" - } - ], - "description": "The original origin label when it differed from sourceClass. Audit only; never evidence." - }, - "status": { - "anyOf": [ - { - "type": "string" - }, - { - "type": "null" - } - ], - "description": "active, superseded, or invalidated." - }, - "supersededBy": { - "anyOf": [ - { - "type": "string" - }, - { - "type": "null" - } - ], - "description": "Identifier of the version that replaced this one." - }, - "supersedes": { - "anyOf": [ - { - "type": "string" - }, - { - "type": "null" - } - ], - "description": "Identifier of the version this one replaced." - }, - "tags": { - "description": "Labels stored with the memory.", - "type": "array" - }, - "temporal": { - "description": "Bi-temporal window: validFrom, validTo, recordedAt, invalidatedAt.", - "type": "object" - }, - "text": { - "anyOf": [ - { - "type": "string" - }, - { - "type": "null" - } - ], - "description": "The memory content." - }, - "updatedAt": { - "anyOf": [ - { - "type": "string" - }, - { - "type": "null" - } - ], - "description": "ISO 8601 time of the last change." - }, - "verificationStatus": { - "anyOf": [ - { - "type": "string" - }, - { - "type": "null" - } - ], - "description": "Always unverified for memories." - }, - "version": { - "anyOf": [ - { - "type": "integer" - }, - { - "type": "null" - } - ], - "description": "Version number within this identity, incrementing on each superseding write." - } - }, - "required": [ - "id", - "kind" - ], - "type": "object" - } - }, - "required": [ - "operation", - "memory" - ], - "type": "object" - }, - "type": "array" - } - }, - "required": [ - "results", - "completeness" - ], - "type": "object" - } -]New value: +[ + { + "properties": { + "indexUpdated": { + "description": "Present when identical content arrived with a different embedding: the index was refreshed without minting a new version.", + "type": "boolean" + }, + "memory": { + "description": "A stored scoped memory version.", + "properties": { + "actor": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "description": "Who performed the write." + }, + "client": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "description": "Which client performed the write." + }, + "createdAt": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "description": "ISO 8601 creation time." + }, + "embedding": { + "anyOf": [ + { + "type": "array" + }, + { + "type": "object" + }, + { + "type": "null" + } + ], + "description": "The stored vector, or null when none was supplied and no provider was configured." + }, + "id": { + "description": "Stable entity identifier.", + "type": "string" + }, + "key": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "description": "Caller-chosen name within the scope and type." + }, + "kind": { + "description": "Entity kind: decision, attempt, memory, fact, relation, review, or alternative.", + "type": "string" + }, + "memoryType": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "description": "preference, profile, goal, instruction, procedure, episode, or note." + }, + "metadata": { + "description": "Caller-owned JSON stored with the memory.", + "type": "object" + }, + "project": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "description": "Project namespace; null for an unattributed record or one imported from before projects." + }, + "schemaVersion": { + "description": "Storage schema version this entity was written under. A value above the build’s own version is preserved rather than downgraded.", + "type": "integer" + }, + "scope": { + "description": "The userId, agentId, and runId this memory is scoped to; each is a string or null.", + "type": "object" + }, + "sessionId": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "description": "Session identifier recorded with the write." + }, + "sourceClass": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "description": "Claimed origin class recorded with the write. A claim, never proof." + }, + "sourceRaw": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "description": "The original origin label when it differed from sourceClass. Audit only; never evidence." + }, + "status": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "description": "active, superseded, or invalidated." + }, + "supersededBy": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "description": "Identifier of the version that replaced this one." + }, + "supersedes": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "description": "Identifier of the version this one replaced." + }, + "tags": { + "description": "Labels stored with the memory.", + "type": "array" + }, + "temporal": { + "description": "Bi-temporal window: validFrom, validTo, recordedAt, invalidatedAt.", + "type": "object" + }, + "text": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "description": "The memory content." + }, + "updatedAt": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "description": "ISO 8601 time of the last change." + }, + "verificationStatus": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "description": "Always unverified for memories." + }, + "version": { + "anyOf": [ + { + "type": "integer" + }, + { + "type": "null" + } + ], + "description": "Version number within this identity, incrementing on each superseding write." + } + }, + "required": [ + "id", + "kind" + ], + "type": "object" + }, + "operation": { + "description": "ADD when no active memory existed, UPDATE when one was superseded, NOOP when content was identical.", + "enum": [ + "ADD", + "UPDATE", + "NOOP" + ], + "type": "string" + }, + "previous": { + "description": "A stored scoped memory version.", + "properties": { + "actor": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "description": "Who performed the write." + }, + "client": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "description": "Which client performed the write." + }, + "createdAt": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "description": "ISO 8601 creation time." + }, + "embedding": { + "anyOf": [ + { + "type": "array" + }, + { + "type": "object" + }, + { + "type": "null" + } + ], + "description": "The stored vector, or null when none was supplied and no provider was configured." + }, + "id": { + "description": "Stable entity identifier.", + "type": "string" + }, + "key": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "description": "Caller-chosen name within the scope and type." + }, + "kind": { + "description": "Entity kind: decision, attempt, memory, fact, relation, review, or alternative.", + "type": "string" + }, + "memoryType": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "description": "preference, profile, goal, instruction, procedure, episode, or note." + }, + "metadata": { + "description": "Caller-owned JSON stored with the memory.", + "type": "object" + }, + "project": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "description": "Project namespace; null for an unattributed record or one imported from before projects." + }, + "schemaVersion": { + "description": "Storage schema version this entity was written under. A value above the build’s own version is preserved rather than downgraded.", + "type": "integer" + }, + "scope": { + "description": "The userId, agentId, and runId this memory is scoped to; each is a string or null.", + "type": "object" + }, + "sessionId": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "description": "Session identifier recorded with the write." + }, + "sourceClass": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "description": "Claimed origin class recorded with the write. A claim, never proof." + }, + "sourceRaw": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "description": "The original origin label when it differed from sourceClass. Audit only; never evidence." + }, + "status": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "description": "active, superseded, or invalidated." + }, + "supersededBy": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "description": "Identifier of the version that replaced this one." + }, + "supersedes": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "description": "Identifier of the version this one replaced." + }, + "tags": { + "description": "Labels stored with the memory.", + "type": "array" + }, + "temporal": { + "description": "Bi-temporal window: validFrom, validTo, recordedAt, invalidatedAt.", + "type": "object" + }, + "text": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "description": "The memory content." + }, + "updatedAt": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "description": "ISO 8601 time of the last change." + }, + "verificationStatus": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "description": "Always unverified for memories." + }, + "version": { + "anyOf": [ + { + "type": "integer" + }, + { + "type": "null" + } + ], + "description": "Version number within this identity, incrementing on each superseding write." + } + }, + "required": [ + "id", + "kind" + ], + "type": "object" + } + }, + "required": [ + "operation", + "memory" + ], + "type": "object" + }, + { + "properties": { + "completeness": { + "description": "Plan accounting. This is not the paginated completeness envelope.", + "properties": { + "applied": { + "description": "Results produced, one per submitted operation.", + "minimum": 0, + "type": "integer" + }, + "complete": { + "description": "Always true: a plan is applied in full or rejected in full.", + "type": "boolean" + }, + "requested": { + "description": "Operations submitted.", + "minimum": 0, + "type": "integer" + } + }, + "required": [ + "complete", + "requested", + "applied" + ], + "type": "object" + }, + "results": { + "description": "One result per submitted operation, in order.", + "items": { + "properties": { + "indexUpdated": { + "description": "Present when only the embedding was refreshed.", + "type": "boolean" + }, + "memory": { + "anyOf": [ + { + "description": "A stored scoped memory version.", + "properties": { + "actor": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "description": "Who performed the write." + }, + "client": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "description": "Which client performed the write." + }, + "createdAt": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "description": "ISO 8601 creation time." + }, + "embedding": { + "anyOf": [ + { + "type": "array" + }, + { + "type": "object" + }, + { + "type": "null" + } + ], + "description": "The stored vector, or null when none was supplied and no provider was configured." + }, + "id": { + "description": "Stable entity identifier.", + "type": "string" + }, + "key": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "description": "Caller-chosen name within the scope and type." + }, + "kind": { + "description": "Entity kind: decision, attempt, memory, fact, relation, review, or alternative.", + "type": "string" + }, + "memoryType": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "description": "preference, profile, goal, instruction, procedure, episode, or note." + }, + "metadata": { + "description": "Caller-owned JSON stored with the memory.", + "type": "object" + }, + "project": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "description": "Project namespace; null for an unattributed record or one imported from before projects." + }, + "schemaVersion": { + "description": "Storage schema version this entity was written under. A value above the build’s own version is preserved rather than downgraded.", + "type": "integer" + }, + "scope": { + "description": "The userId, agentId, and runId this memory is scoped to; each is a string or null.", + "type": "object" + }, + "sessionId": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "description": "Session identifier recorded with the write." + }, + "sourceClass": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "description": "Claimed origin class recorded with the write. A claim, never proof." + }, + "sourceRaw": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "description": "The original origin label when it differed from sourceClass. Audit only; never evidence." + }, + "status": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "description": "active, superseded, or invalidated." + }, + "supersededBy": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "description": "Identifier of the version that replaced this one." + }, + "supersedes": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "description": "Identifier of the version this one replaced." + }, + "tags": { + "description": "Labels stored with the memory.", + "type": "array" + }, + "temporal": { + "description": "Bi-temporal window: validFrom, validTo, recordedAt, invalidatedAt.", + "type": "object" + }, + "text": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "description": "The memory content." + }, + "updatedAt": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "description": "ISO 8601 time of the last change." + }, + "verificationStatus": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "description": "Always unverified for memories." + }, + "version": { + "anyOf": [ + { + "type": "integer" + }, + { + "type": "null" + } + ], + "description": "Version number within this identity, incrementing on each superseding write." + } + }, + "required": [ + "id", + "kind" + ], + "type": "object" + }, + { + "type": "null" + } + ], + "description": "The resulting memory, or null for a NOOP on an identity that has no memory." + }, + "operation": { + "description": "What was actually applied, which may differ from the requested action when content already matched.", + "enum": [ + "ADD", + "UPDATE", + "DELETE", + "NOOP" + ], + "type": "string" + }, + "previous": { + "description": "A stored scoped memory version.", + "properties": { + "actor": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "description": "Who performed the write." + }, + "client": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "description": "Which client performed the write." + }, + "createdAt": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "description": "ISO 8601 creation time." + }, + "embedding": { + "anyOf": [ + { + "type": "array" + }, + { + "type": "object" + }, + { + "type": "null" + } + ], + "description": "The stored vector, or null when none was supplied and no provider was configured." + }, + "id": { + "description": "Stable entity identifier.", + "type": "string" + }, + "key": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "description": "Caller-chosen name within the scope and type." + }, + "kind": { + "description": "Entity kind: decision, attempt, memory, fact, relation, review, or alternative.", + "type": "string" + }, + "memoryType": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "description": "preference, profile, goal, instruction, procedure, episode, or note." + }, + "metadata": { + "description": "Caller-owned JSON stored with the memory.", + "type": "object" + }, + "project": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "description": "Project namespace; null for an unattributed record or one imported from before projects." + }, + "schemaVersion": { + "description": "Storage schema version this entity was written under. A value above the build’s own version is preserved rather than downgraded.", + "type": "integer" + }, + "scope": { + "description": "The userId, agentId, and runId this memory is scoped to; each is a string or null.", + "type": "object" + }, + "sessionId": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "description": "Session identifier recorded with the write." + }, + "sourceClass": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "description": "Claimed origin class recorded with the write. A claim, never proof." + }, + "sourceRaw": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "description": "The original origin label when it differed from sourceClass. Audit only; never evidence." + }, + "status": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "description": "active, superseded, or invalidated." + }, + "supersededBy": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "description": "Identifier of the version that replaced this one." + }, + "supersedes": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "description": "Identifier of the version this one replaced." + }, + "tags": { + "description": "Labels stored with the memory.", + "type": "array" + }, + "temporal": { + "description": "Bi-temporal window: validFrom, validTo, recordedAt, invalidatedAt.", + "type": "object" + }, + "text": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "description": "The memory content." + }, + "updatedAt": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "description": "ISO 8601 time of the last change." + }, + "verificationStatus": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "description": "Always unverified for memories." + }, + "version": { + "anyOf": [ + { + "type": "integer" + }, + { + "type": "null" + } + ], + "description": "Version number within this identity, incrementing on each superseding write." + } + }, + "required": [ + "id", + "kind" + ], + "type": "object" + } + }, + "required": [ + "operation", + "memory" + ], + "type": "object" + }, + "type": "array" + } + }, + "required": [ + "results", + "completeness" + ], + "type": "object" + } +]
- Removed
shadowgraph_repair_plan - Removed
shadowgraph_restore - Changed
shadowgraph_retrieve15 fields changed- added
Input schema / properties / accessIdAdded value: +{ + "description": "Grant ID, rechecked at use.", + "type": "string" +} - added
Input schema / properties / grantIdAdded value: +{ + "description": "Alias for accessId; conflicting identifiers are refused.", + "type": "string" +} - added
Input schema / properties / originIdAdded value: +{ + "description": "Capture-origin id; with no project the record belongs to it alone.", + "type": "string" +} - changed
Input schema / properties / project / descriptionPrevious value: -"Restrict to one project, including which neighbours may be pulled in."New value: +"Project or confirmed workspace binding; otherwise origin-only. No identity returns an empty scoped view." - added
Input schema / properties / readProvenanceAdded value: +{ + "description": "Original expansion bounds; cannot widen access.", + "type": "object" +} - added
Output schema / properties / completeness / properties / captureAdded value: +{ + "description": "Scoped unprocessed capture, when present.", + "properties": { + "blocked": { + "description": "Items blocked.", + "minimum": 0, + "type": "integer" + }, + "expired": { + "description": "Raw expired before extraction; a gap, not backlog.", + "minimum": 0, + "type": "integer" + }, + "extractionAvailable": { + "description": "Whether extraction runs.", + "type": "boolean" + }, + "failed": { + "description": "Items failed.", + "minimum": 0, + "type": "integer" + }, + "gaps": { + "description": "Capture refusal/unread gaps; no identities.", + "items": { + "properties": { + "from": { + "description": "Gap start time.", + "type": "string" + }, + "reason": { + "description": "Why capture has a gap.", + "enum": [ + "maxQueueDepth", + "maxStoreBytes", + "maxItemsPerSession", + "session_in_another_project", + "raw_expired", + "transcript_unrecognised", + "session_left_project", + "transcript_rewritten", + "transcript_reanchored", + "transcript_incomplete_at_end", + "transcript_line_oversized", + "tool_calls_not_captured" + ], + "type": "string" + }, + "sessions": { + "description": "Sessions covered by this gap.", + "minimum": 0, + "type": "integer" + }, + "to": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "description": "End time, if known." + } + }, + "required": [ + "reason", + "from", + "to" + ], + "type": "object" + }, + "type": "array" + }, + "limited": { + "description": "Admission limits; accepted items kept.", + "items": { + "properties": { + "ceiling": { + "description": "The limit value.", + "minimum": 0, + "type": "integer" + }, + "limit": { + "description": "The limit reached.", + "enum": [ + "maxQueueDepth", + "maxStoreBytes" + ], + "type": "string" + }, + "since": { + "description": "When refusal began.", + "type": "string" + } + }, + "required": [ + "limit", + "ceiling", + "since" + ], + "type": "object" + }, + "type": "array" + }, + "oldestPendingAt": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "description": "Oldest pending capture." + }, + "pending": { + "description": "Items waiting.", + "minimum": 0, + "type": "integer" + }, + "processing": { + "description": "Items claimed.", + "minimum": 0, + "type": "integer" + }, + "workerErrors": { + "description": "Scoped worker stops; fixed codes.", + "items": { + "properties": { + "at": { + "description": "Stop timestamp.", + "type": "string" + }, + "reason": { + "description": "Worker stop code.", + "type": "string" + } + }, + "required": [ + "reason", + "at" + ], + "type": "object" + }, + "type": "array" + } + }, + "required": [ + "pending", + "processing", + "failed", + "blocked", + "oldestPendingAt", + "extractionAvailable", + "limited", + "gaps" + ], + "type": "object" +} - changed
Output schema / properties / completeness / properties / complete / descriptionPrevious value: -"True only when every matching item is present."New value: +"Known-candidate coverage; false for unresolved scope, withheld detail or pending capture; not recall." - added
Output schema / properties / completeness / properties / limitationAdded value: +{ + "description": "Limits of this view.", + "properties": { + "code": { + "description": "Stable limitation code.", + "type": "string" + }, + "detail": { + "description": "What this view cannot establish.", + "type": "string" + } + }, + "required": [ + "code", + "detail" + ], + "type": "object" +} - changed
Output schema / properties / completeness / properties / losslessItems / descriptionPrevious value: -"Always true: each returned item is a full-fidelity record, never a summary or a truncated field."New value: +"False when returned items have withheld or transformed detail." - added
Output schema / properties / completeness / properties / quarantinedAdded value: +{ + "description": "Items withheld as possibly purged.", + "minimum": 0, + "type": "integer" +} - changed
Output schema / properties / completeness / properties / scope / descriptionPrevious value: -"The project, query, and structured filters that produced this result, so it explains its own derivation."New value: +"The resolved read boundary." - added
Output schema / properties / completeness / properties / scope / propertiesAdded value: +{ + "grant": { + "anyOf": [ + { + "type": "null" + }, + { + "properties": { + "accessId": { + "description": "The currently rechecked grant identifier.", + "type": "string" + }, + "expiresAt": { + "description": "Earliest effective expiry of this read authority.", + "type": "string" + }, + "surface": { + "description": "Actual runtime surface of this read.", + "enum": [ + "cli", + "mcp", + "http" + ], + "type": "string" + } + }, + "required": [ + "accessId", + "expiresAt", + "surface" + ], + "type": "object" + } + ], + "description": "Effective rechecked grant, or null." + }, + "originPresented": { + "description": "Usable origin presented; not project selection.", + "type": "boolean" + }, + "project": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "description": "Resolved project, or null." + }, + "requestState": { + "description": "Whether a project was resolved.", + "enum": [ + "project_selected", + "project_unresolved" + ], + "type": "string" + } +} - added
Output schema / properties / completeness / properties / scope / requiredAdded value: +[ + "project", + "requestState", + "originPresented", + "grant" +] - changed
Output schema / properties / items / items / properties / record / properties / project / descriptionPrevious value: -"Project namespace; records imported from a schema that predates projects may carry null."New value: +"Project namespace; null for an unattributed record or one imported from before projects." - added
Output schema / properties / readProvenanceAdded value: +{ + "description": "Original read bounds; reuse intersects these with currently valid authority.", + "properties": { + "accessId": { + "description": "Original grant, revalidated on every reuse.", + "type": "string" + }, + "expiresAt": { + "description": "Original effective expiry; reuse cannot extend it.", + "type": "string" + }, + "request": { + "description": "Original request ownership, preserved during expansion.", + "properties": { + "originId": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "description": "Original capture origin, or null when absent." + }, + "project": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "description": "Original resolved project, or null when unresolved." + } + }, + "required": [ + "project", + "originId" + ], + "type": "object" + }, + "scope": { + "description": "Finite explicit owner bounds; project names, origins and legacy attribution are disjoint.", + "properties": { + "legacyAttributions": { + "description": "Explicit legacy ownership classes; neither is a named project.", + "items": { + "enum": [ + "legacy_ambiguous", + "legacy_unattributed" + ], + "type": "string" + }, + "type": "array" + }, + "originIds": { + "description": "Exact nonempty origin identifiers for unattributed content.", + "items": { + "type": "string" + }, + "type": "array" + }, + "projects": { + "description": "Exact named projects, including a real project named default if requested.", + "items": { + "type": "string" + }, + "type": "array" + } + }, + "type": "object" + }, + "surfaces": { + "description": "Original permitted surfaces; reuse can only narrow them.", + "items": { + "enum": [ + "cli", + "mcp", + "http" + ], + "type": "string" + }, + "type": "array" + }, + "version": { + "const": 1, + "description": "Version of this bounded read provenance.", + "type": "integer" + } + }, + "required": [ + "version", + "request", + "accessId", + "scope", + "surfaces", + "expiresAt" + ], + "type": "object" +}
- Changed
shadowgraph_review5 fields changed- added
Input schema / properties / accessIdAdded value: +{ + "description": "Grant ID, rechecked at use.", + "type": "string" +} - added
Input schema / properties / grantIdAdded value: +{ + "description": "Alias for accessId; conflicting identifiers are refused.", + "type": "string" +} - added
Input schema / properties / originIdAdded value: +{ + "description": "Capture-origin id; with no project the record belongs to it alone.", + "type": "string" +} - changed
Input schema / properties / project / descriptionPrevious value: -"Review only this project. Omit to review every project."New value: +"Project or confirmed workspace binding; otherwise origin-only. No identity returns an empty scoped view." - changed
Output schema / (root)Previous value: -nullNew value: +{ + "properties": { + "completeness": { + "description": "Declares exactly what this response left out, so a truncated result can never look complete.", + "properties": { + "capture": { + "description": "Scoped unprocessed capture, when present.", + "properties": { + "blocked": { + "description": "Items blocked.", + "minimum": 0, + "type": "integer" + }, + "expired": { + "description": "Raw expired before extraction; a gap, not backlog.", + "minimum": 0, + "type": "integer" + }, + "extractionAvailable": { + "description": "Whether extraction runs.", + "type": "boolean" + }, + "failed": { + "description": "Items failed.", + "minimum": 0, + "type": "integer" + }, + "gaps": { + "description": "Capture refusal/unread gaps; no identities.", + "items": { + "properties": { + "from": { + "description": "Gap start time.", + "type": "string" + }, + "reason": { + "description": "Why capture has a gap.", + "enum": [ + "maxQueueDepth", + "maxStoreBytes", + "maxItemsPerSession", + "session_in_another_project", + "raw_expired", + "transcript_unrecognised", + "session_left_project", + "transcript_rewritten", + "transcript_reanchored", + "transcript_incomplete_at_end", + "transcript_line_oversized", + "tool_calls_not_captured" + ], + "type": "string" + }, + "sessions": { + "description": "Sessions covered by this gap.", + "minimum": 0, + "type": "integer" + }, + "to": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "description": "End time, if known." + } + }, + "required": [ + "reason", + "from", + "to" + ], + "type": "object" + }, + "type": "array" + }, + "limited": { + "description": "Admission limits; accepted items kept.", + "items": { + "properties": { + "ceiling": { + "description": "The limit value.", + "minimum": 0, + "type": "integer" + }, + "limit": { + "description": "The limit reached.", + "enum": [ + "maxQueueDepth", + "maxStoreBytes" + ], + "type": "string" + }, + "since": { + "description": "When refusal began.", + "type": "string" + } + }, + "required": [ + "limit", + "ceiling", + "since" + ], + "type": "object" + }, + "type": "array" + }, + "oldestPendingAt": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "description": "Oldest pending capture." + }, + "pending": { + "description": "Items waiting.", + "minimum": 0, + "type": "integer" + }, + "processing": { + "description": "Items claimed.", + "minimum": 0, + "type": "integer" + }, + "workerErrors": { + "description": "Scoped worker stops; fixed codes.", + "items": { + "properties": { + "at": { + "description": "Stop timestamp.", + "type": "string" + }, + "reason": { + "description": "Worker stop code.", + "type": "string" + } + }, + "required": [ + "reason", + "at" + ], + "type": "object" + }, + "type": "array" + } + }, + "required": [ + "pending", + "processing", + "failed", + "blocked", + "oldestPendingAt", + "extractionAvailable", + "limited", + "gaps" + ], + "type": "object" + }, + "complete": { + "description": "Known-candidate coverage; false for unresolved scope, withheld detail or pending capture; not recall.", + "type": "boolean" + }, + "limitSource": { + "description": "Whose choice bounded the result.", + "enum": [ + "caller", + "default" + ], + "type": "string" + }, + "limitation": { + "description": "Limits of this view.", + "properties": { + "code": { + "description": "Stable limitation code.", + "type": "string" + }, + "detail": { + "description": "What this view cannot establish.", + "type": "string" + } + }, + "required": [ + "code", + "detail" + ], + "type": "object" + }, + "losslessItems": { + "description": "False when returned items have withheld or transformed detail.", + "type": "boolean" + }, + "omitted": { + "description": "total minus returned.", + "minimum": 0, + "type": "integer" + }, + "quarantined": { + "description": "Items withheld as possibly purged.", + "minimum": 0, + "type": "integer" + }, + "returned": { + "description": "Items in this response.", + "minimum": 0, + "type": "integer" + }, + "scope": { + "description": "The resolved read boundary.", + "properties": { + "grant": { + "anyOf": [ + { + "type": "null" + }, + { + "properties": { + "accessId": { + "description": "The currently rechecked grant identifier.", + "type": "string" + }, + "expiresAt": { + "description": "Earliest effective expiry of this read authority.", + "type": "string" + }, + "surface": { + "description": "Actual runtime surface of this read.", + "enum": [ + "cli", + "mcp", + "http" + ], + "type": "string" + } + }, + "required": [ + "accessId", + "expiresAt", + "surface" + ], + "type": "object" + } + ], + "description": "Effective rechecked grant, or null." + }, + "originPresented": { + "description": "Usable origin presented; not project selection.", + "type": "boolean" + }, + "project": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "description": "Resolved project, or null." + }, + "requestState": { + "description": "Whether a project was resolved.", + "enum": [ + "project_selected", + "project_unresolved" + ], + "type": "string" + } + }, + "required": [ + "project", + "requestState", + "originPresented", + "grant" + ], + "type": "object" + }, + "total": { + "description": "Items that matched in total.", + "minimum": 0, + "type": "integer" + } + }, + "required": [ + "scope", + "returned", + "total", + "complete", + "omitted", + "losslessItems" + ], + "type": "object" + }, + "items": { + "description": "All known matching items inside this boundary.", + "items": { + "description": "One decision whose rejected alternatives are due for reconsideration.", + "properties": { + "alternativesToReconsider": { + "description": "Labels of the alternatives to look at again; all of them when the trigger was not alternative-specific.", + "items": { + "type": "string" + }, + "type": "array" + }, + "decisionId": { + "description": "The decision to reconsider.", + "type": "string" + }, + "reason": { + "description": "Comma-separated causes: the fact keys whose reopenWhen rules matched, \"review date reached\", or \"decision outcome failed\".", + "type": "string" + }, + "reviewSignalId": { + "description": "Pass this to shadowgraph_ack_review to acknowledge this review.", + "type": "string" + }, + "reviewSignalStatus": { + "description": "Whether this review is open or acknowledged, or unpersisted: no stored signal, because context is a read or the evaluation was wider. Entries are recomputed from current evidence; an acknowledged one still appears.", + "enum": [ + "open", + "acknowledged", + "unpersisted" + ], + "type": "string" + }, + "title": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "description": "Decision title, when the stored decision has one." + }, + "violatedConditions": { + "description": "The conditions that actually fired, each naming its operator, expected and observed value, and the fact it was computed from.", + "items": { + "description": "One evaluated reopen condition. Verdict \"unknown\" means it could not be evaluated from available evidence, which is not a pass.", + "properties": { + "alternativeId": { + "description": "Alternative carrying it.", + "type": "string" + }, + "alternativeLabel": { + "description": "Label of that alternative.", + "type": "string" + }, + "attemptId": { + "description": "Attempt the condition belongs to, for a reusableWhen rule.", + "type": "string" + }, + "conflictingEvidence": { + "description": "Equally applicable facts that disagree. The verdict rests on the deterministic winner.", + "items": { + "description": "A fact a verdict came from. Unrecorded fields are omitted, never filled in.", + "properties": { + "factId": { + "description": "The observed fact.", + "type": "string" + }, + "observedAt": { + "description": "When observed, if recorded.", + "type": "string" + }, + "sourceClass": { + "description": "Provenance class, if recorded.", + "type": "string" + }, + "validFrom": { + "description": "Validity start, if recorded.", + "type": "string" + }, + "value": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + }, + { + "type": "null" + }, + { + "type": "array" + }, + { + "type": "object" + } + ], + "description": "A stored value, any lossless JSON value." + }, + "verificationStatus": { + "description": "Verification status, if recorded.", + "type": "string" + } + }, + "required": [ + "factId", + "value" + ], + "type": "object" + }, + "type": "array" + }, + "decisionId": { + "description": "Decision the condition belongs to, for a reopenWhen rule.", + "type": "string" + }, + "evidence": { + "description": "Provenance of the value used.", + "type": "object" + }, + "expected": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + }, + { + "type": "null" + }, + { + "type": "array" + }, + { + "type": "object" + } + ], + "description": "A stored value, any lossless JSON value." + }, + "key": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "description": "Fact key read." + }, + "observed": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + }, + { + "type": "null" + }, + { + "type": "array" + }, + { + "type": "object" + } + ], + "description": "A stored value, any lossless JSON value." + }, + "operator": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "description": "Operator the rule declared." + }, + "reason": { + "description": "Why this verdict.", + "type": "string" + }, + "unit": { + "description": "Unit the rule declared, if any.", + "type": "string" + }, + "verdict": { + "description": "Evaluation result.", + "enum": [ + "true", + "false", + "unknown" + ], + "type": "string" + } + }, + "required": [ + "key", + "operator", + "verdict", + "reason" + ], + "type": "object" + }, + "type": "array" + } + }, + "required": [ + "decisionId", + "reason", + "alternativesToReconsider" + ], + "type": "object" + }, + "type": "array" + }, + "readProvenance": { + "description": "Original read bounds; reuse intersects these with currently valid authority.", + "properties": { + "accessId": { + "description": "Original grant, revalidated on every reuse.", + "type": "string" + }, + "expiresAt": { + "description": "Original effective expiry; reuse cannot extend it.", + "type": "string" + }, + "request": { + "description": "Original request ownership, preserved during expansion.", + "properties": { + "originId": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "description": "Original capture origin, or null when absent." + }, + "project": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "description": "Original resolved project, or null when unresolved." + } + }, + "required": [ + "project", + "originId" + ], + "type": "object" + }, + "scope": { + "description": "Finite explicit owner bounds; project names, origins and legacy attribution are disjoint.", + "properties": { + "legacyAttributions": { + "description": "Explicit legacy ownership classes; neither is a named project.", + "items": { + "enum": [ + "legacy_ambiguous", + "legacy_unattributed" + ], + "type": "string" + }, + "type": "array" + }, + "originIds": { + "description": "Exact nonempty origin identifiers for unattributed content.", + "items": { + "type": "string" + }, + "type": "array" + }, + "projects": { + "description": "Exact named projects, including a real project named default if requested.", + "items": { + "type": "string" + }, + "type": "array" + } + }, + "type": "object" + }, + "surfaces": { + "description": "Original permitted surfaces; reuse can only narrow them.", + "items": { + "enum": [ + "cli", + "mcp", + "http" + ], + "type": "string" + }, + "type": "array" + }, + "version": { + "const": 1, + "description": "Version of this bounded read provenance.", + "type": "integer" + } + }, + "required": [ + "version", + "request", + "accessId", + "scope", + "surfaces", + "expiresAt" + ], + "type": "object" + } + }, + "required": [ + "items", + "completeness" + ], + "type": "object" +}
- Added
shadowgraph_review_context - Removed
shadowgraph_review_signals - Changed
shadowgraph_search14 fields changed- added
Input schema / properties / accessIdAdded value: +{ + "description": "Grant ID, rechecked at use.", + "type": "string" +} - added
Input schema / properties / grantIdAdded value: +{ + "description": "Alias for accessId; conflicting identifiers are refused.", + "type": "string" +} - added
Input schema / properties / originIdAdded value: +{ + "description": "Capture-origin id; with no project the record belongs to it alone.", + "type": "string" +} - changed
Input schema / properties / project / descriptionPrevious value: -"Restrict to one project. Omitted, decisions and facts are searched across projects, while memories stay in the default project and all-null scope."New value: +"Project or confirmed workspace binding; otherwise origin-only. No identity returns an empty scoped view." - added
Output schema / properties / completeness / properties / captureAdded value: +{ + "description": "Scoped unprocessed capture, when present.", + "properties": { + "blocked": { + "description": "Items blocked.", + "minimum": 0, + "type": "integer" + }, + "expired": { + "description": "Raw expired before extraction; a gap, not backlog.", + "minimum": 0, + "type": "integer" + }, + "extractionAvailable": { + "description": "Whether extraction runs.", + "type": "boolean" + }, + "failed": { + "description": "Items failed.", + "minimum": 0, + "type": "integer" + }, + "gaps": { + "description": "Capture refusal/unread gaps; no identities.", + "items": { + "properties": { + "from": { + "description": "Gap start time.", + "type": "string" + }, + "reason": { + "description": "Why capture has a gap.", + "enum": [ + "maxQueueDepth", + "maxStoreBytes", + "maxItemsPerSession", + "session_in_another_project", + "raw_expired", + "transcript_unrecognised", + "session_left_project", + "transcript_rewritten", + "transcript_reanchored", + "transcript_incomplete_at_end", + "transcript_line_oversized", + "tool_calls_not_captured" + ], + "type": "string" + }, + "sessions": { + "description": "Sessions covered by this gap.", + "minimum": 0, + "type": "integer" + }, + "to": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "description": "End time, if known." + } + }, + "required": [ + "reason", + "from", + "to" + ], + "type": "object" + }, + "type": "array" + }, + "limited": { + "description": "Admission limits; accepted items kept.", + "items": { + "properties": { + "ceiling": { + "description": "The limit value.", + "minimum": 0, + "type": "integer" + }, + "limit": { + "description": "The limit reached.", + "enum": [ + "maxQueueDepth", + "maxStoreBytes" + ], + "type": "string" + }, + "since": { + "description": "When refusal began.", + "type": "string" + } + }, + "required": [ + "limit", + "ceiling", + "since" + ], + "type": "object" + }, + "type": "array" + }, + "oldestPendingAt": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "description": "Oldest pending capture." + }, + "pending": { + "description": "Items waiting.", + "minimum": 0, + "type": "integer" + }, + "processing": { + "description": "Items claimed.", + "minimum": 0, + "type": "integer" + }, + "workerErrors": { + "description": "Scoped worker stops; fixed codes.", + "items": { + "properties": { + "at": { + "description": "Stop timestamp.", + "type": "string" + }, + "reason": { + "description": "Worker stop code.", + "type": "string" + } + }, + "required": [ + "reason", + "at" + ], + "type": "object" + }, + "type": "array" + } + }, + "required": [ + "pending", + "processing", + "failed", + "blocked", + "oldestPendingAt", + "extractionAvailable", + "limited", + "gaps" + ], + "type": "object" +} - changed
Output schema / properties / completeness / properties / complete / descriptionPrevious value: -"True only when every matching item is present."New value: +"Known-candidate coverage; false for unresolved scope, withheld detail or pending capture; not recall." - added
Output schema / properties / completeness / properties / limitationAdded value: +{ + "description": "Limits of this view.", + "properties": { + "code": { + "description": "Stable limitation code.", + "type": "string" + }, + "detail": { + "description": "What this view cannot establish.", + "type": "string" + } + }, + "required": [ + "code", + "detail" + ], + "type": "object" +} - changed
Output schema / properties / completeness / properties / losslessItems / descriptionPrevious value: -"Always true: each returned item is a full-fidelity record, never a summary or a truncated field."New value: +"False when returned items have withheld or transformed detail." - added
Output schema / properties / completeness / properties / quarantinedAdded value: +{ + "description": "Items withheld as possibly purged.", + "minimum": 0, + "type": "integer" +} - changed
Output schema / properties / completeness / properties / scope / descriptionPrevious value: -"The project, query, and structured filters that produced this result, so it explains its own derivation."New value: +"The resolved read boundary." - added
Output schema / properties / completeness / properties / scope / propertiesAdded value: +{ + "grant": { + "anyOf": [ + { + "type": "null" + }, + { + "properties": { + "accessId": { + "description": "The currently rechecked grant identifier.", + "type": "string" + }, + "expiresAt": { + "description": "Earliest effective expiry of this read authority.", + "type": "string" + }, + "surface": { + "description": "Actual runtime surface of this read.", + "enum": [ + "cli", + "mcp", + "http" + ], + "type": "string" + } + }, + "required": [ + "accessId", + "expiresAt", + "surface" + ], + "type": "object" + } + ], + "description": "Effective rechecked grant, or null." + }, + "originPresented": { + "description": "Usable origin presented; not project selection.", + "type": "boolean" + }, + "project": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "description": "Resolved project, or null." + }, + "requestState": { + "description": "Whether a project was resolved.", + "enum": [ + "project_selected", + "project_unresolved" + ], + "type": "string" + } +} - added
Output schema / properties / completeness / properties / scope / requiredAdded value: +[ + "project", + "requestState", + "originPresented", + "grant" +] - changed
Output schema / properties / items / items / properties / record / properties / project / descriptionPrevious value: -"Project namespace; records imported from a schema that predates projects may carry null."New value: +"Project namespace; null for an unattributed record or one imported from before projects." - added
Output schema / properties / readProvenanceAdded value: +{ + "description": "Original read bounds; reuse intersects these with currently valid authority.", + "properties": { + "accessId": { + "description": "Original grant, revalidated on every reuse.", + "type": "string" + }, + "expiresAt": { + "description": "Original effective expiry; reuse cannot extend it.", + "type": "string" + }, + "request": { + "description": "Original request ownership, preserved during expansion.", + "properties": { + "originId": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "description": "Original capture origin, or null when absent." + }, + "project": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "description": "Original resolved project, or null when unresolved." + } + }, + "required": [ + "project", + "originId" + ], + "type": "object" + }, + "scope": { + "description": "Finite explicit owner bounds; project names, origins and legacy attribution are disjoint.", + "properties": { + "legacyAttributions": { + "description": "Explicit legacy ownership classes; neither is a named project.", + "items": { + "enum": [ + "legacy_ambiguous", + "legacy_unattributed" + ], + "type": "string" + }, + "type": "array" + }, + "originIds": { + "description": "Exact nonempty origin identifiers for unattributed content.", + "items": { + "type": "string" + }, + "type": "array" + }, + "projects": { + "description": "Exact named projects, including a real project named default if requested.", + "items": { + "type": "string" + }, + "type": "array" + } + }, + "type": "object" + }, + "surfaces": { + "description": "Original permitted surfaces; reuse can only narrow them.", + "items": { + "enum": [ + "cli", + "mcp", + "http" + ], + "type": "string" + }, + "type": "array" + }, + "version": { + "const": 1, + "description": "Version of this bounded read provenance.", + "type": "integer" + } + }, + "required": [ + "version", + "request", + "accessId", + "scope", + "surfaces", + "expiresAt" + ], + "type": "object" +}
- Removed
shadowgraph_supersede - Removed
shadowgraph_traverse - Removed
shadowgraph_update_status - Changed
shadowgraph_validate2 fields changed- added
Input schema / propertiesAdded value: +{ + "accessId": { + "description": "Grant ID, rechecked at use.", + "type": "string" + }, + "grantId": { + "description": "Alias for accessId; conflicting identifiers are refused.", + "type": "string" + }, + "originId": { + "description": "Capture-origin id; with no project the record belongs to it alone.", + "type": "string" + }, + "project": { + "description": "Project or confirmed workspace binding; otherwise origin-only. No identity returns an empty scoped view.", + "type": "string" + } +} - added
Output schema / properties / readProvenanceAdded value: +{ + "description": "Original read bounds; reuse intersects these with currently valid authority.", + "properties": { + "accessId": { + "description": "Original grant, revalidated on every reuse.", + "type": "string" + }, + "expiresAt": { + "description": "Original effective expiry; reuse cannot extend it.", + "type": "string" + }, + "request": { + "description": "Original request ownership, preserved during expansion.", + "properties": { + "originId": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "description": "Original capture origin, or null when absent." + }, + "project": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "description": "Original resolved project, or null when unresolved." + } + }, + "required": [ + "project", + "originId" + ], + "type": "object" + }, + "scope": { + "description": "Finite explicit owner bounds; project names, origins and legacy attribution are disjoint.", + "properties": { + "legacyAttributions": { + "description": "Explicit legacy ownership classes; neither is a named project.", + "items": { + "enum": [ + "legacy_ambiguous", + "legacy_unattributed" + ], + "type": "string" + }, + "type": "array" + }, + "originIds": { + "description": "Exact nonempty origin identifiers for unattributed content.", + "items": { + "type": "string" + }, + "type": "array" + }, + "projects": { + "description": "Exact named projects, including a real project named default if requested.", + "items": { + "type": "string" + }, + "type": "array" + } + }, + "type": "object" + }, + "surfaces": { + "description": "Original permitted surfaces; reuse can only narrow them.", + "items": { + "enum": [ + "cli", + "mcp", + "http" + ], + "type": "string" + }, + "type": "array" + }, + "version": { + "const": 1, + "description": "Version of this bounded read provenance.", + "type": "integer" + } + }, + "required": [ + "version", + "request", + "accessId", + "scope", + "surfaces", + "expiresAt" + ], + "type": "object" +}
27 tool updates
v0.40.1- Changed
shadowgraph_ack_review2 fields changed- added
Input schema / properties / id / descriptionAdded value: +"Review signal id, as returned in the id field by shadowgraph_review_signals or in reviewSignals by shadowgraph_maintain. This is the signal id, not the decisionId it refers to." - changed
Output schema / (root)Previous value: -nullNew value: +{ + "description": "The acknowledged review signal, retained rather than deleted.", + "properties": { + "acknowledgedAt": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "description": "ISO 8601 time of the most recent acknowledgement." + }, + "alternativesToReconsider": { + "description": "Alternative labels to look at again.", + "items": { + "type": "string" + }, + "type": "array" + }, + "createdAt": { + "description": "ISO 8601 time the signal was raised.", + "type": "string" + }, + "decisionId": { + "description": "The decision this signal is about.", + "type": "string" + }, + "id": { + "description": "Signal identifier, used by shadowgraph_ack_review.", + "type": "string" + }, + "kind": { + "const": "review", + "description": "Always \"review\".", + "type": "string" + }, + "reason": { + "description": "Why the signal was raised. Together with decisionId this is the dedupe identity, so the same cause never raises a second signal.", + "type": "string" + }, + "status": { + "description": "open until acknowledged.", + "enum": [ + "open", + "acknowledged" + ], + "type": "string" + }, + "title": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "description": "Decision title, when the stored decision has one." + } + }, + "required": [ + "id", + "kind", + "decisionId", + "reason", + "alternativesToReconsider", + "status", + "createdAt", + "acknowledgedAt" + ], + "type": "object" +}
- Changed
shadowgraph_backup2 fields changed- added
Input schema / properties / destination / descriptionAdded value: +"Server-side path to write the snapshot to. Required. An existing file there is overwritten; parent directories are created. Use the storage backend’s own extension, .json for JSON stores and .db for SQLite." - changed
Output schema / (root)Previous value: -nullNew value: +{ + "description": "Where the snapshot was taken from and written to.", + "properties": { + "destination": { + "description": "Path the snapshot was written to.", + "type": "string" + }, + "source": { + "description": "Path of the live store the snapshot was taken from.", + "type": "string" + } + }, + "required": [ + "source", + "destination" + ], + "type": "object" +}
- Changed
shadowgraph_confidence_evidence10 fields changed- changed
Input schema / properties / actor / descriptionPrevious value: -"Who performed this write, e.g. an agent name."New value: +"Who performed this write, such as an agent or person name. Stored for audit; never used to grant trust." - changed
Input schema / properties / client / descriptionPrevious value: -"Which client performed this write."New value: +"Which client software performed this write, such as the host application name." - added
Input schema / properties / decisionId / descriptionAdded value: +"Identifier of an existing decision, as returned by shadowgraph_record_decision, shadowgraph_search, or shadowgraph_retrieve." - changed
Input schema / properties / key / descriptionPrevious value: -"REQUIRED stable dedupe key. Reuse the same key for the same observation so retries do not double-count; use a NEW key for a genuinely new observation."New value: +"REQUIRED stable dedupe key. Reuse the same key for the same observation so retries cannot double-count; use a NEW key for a genuinely new observation. There is no default, because a generated one would only be stable within a millisecond." - added
Input schema / properties / observedAt / descriptionAdded value: +"ISO 8601 time the evidence was observed. Defaults to now." - added
Input schema / properties / reason / descriptionAdded value: +"Why this evidence matters. Required, non-empty, and kept in the audit history." - changed
Input schema / properties / sessionId / descriptionPrevious value: -"Session identifier for this write."New value: +"Caller-owned identifier that groups related writes in the audit trail." - changed
Input schema / properties / sourceClass / descriptionPrevious value: -"Claimed origin class. A claim, not proof: no value here can make a fact verified."New value: +"Claimed origin, never proof: agent_claimed (the default), tool_observed, human_confirmed, or production_verified. It weights confidence only. An unrecognised label downgrades to agent_claimed, kept verbatim in sourceRaw." - changed
Input schema / properties / supports / descriptionPrevious value: -"Defaults to true. false records contradicting evidence."New value: +"Defaults to true. false records contradicting evidence, moving confidence down instead of up." - changed
Output schema / (root)Previous value: -nullNew value: +{ + "description": "A stored decision, including its alternatives and auditable confidence basis.", + "properties": { + "actor": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "description": "Who performed the write." + }, + "alternatives": { + "description": "Rejected alternatives, each with id, label, reasonRejected, status, and the reopenWhen rules that make it reconsiderable.", + "type": "array" + }, + "assumptions": { + "description": "Assumptions the decision rests on. Searchable content.", + "items": { + "type": "string" + }, + "type": "array" + }, + "chosen": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "description": "The option that was chosen." + }, + "client": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "description": "Which client performed the write." + }, + "confidence": { + "description": "Auditable confidence: initial, current (0-1), policy, a history entry per move, and a basis summarising the contributions it was folded from. Legacy records may lack basis.", + "type": "object" + }, + "createdAt": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "description": "ISO 8601 creation time." + }, + "evidence": { + "description": "Normalised evidence entries: source, type, sourceClass, confidence, observedAt, detail.", + "type": "array" + }, + "failedAttempts": { + "description": "Attempt identifiers or notes attached to this decision.", + "type": "array" + }, + "goal": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "description": "What the decision was trying to achieve." + }, + "id": { + "description": "Stable entity identifier.", + "type": "string" + }, + "kind": { + "description": "Entity kind: decision, attempt, memory, fact, relation, review, or alternative.", + "type": "string" + }, + "migration": { + "description": "Present only on migrated records; records the legacy value a field was mapped from.", + "type": "object" + }, + "outcome": { + "anyOf": [ + { + "type": "object" + }, + { + "type": "null" + } + ], + "description": "The recorded outcome, or null until one is recorded." + }, + "project": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "description": "Project namespace; records imported from a schema that predates projects may carry null." + }, + "reviewAfter": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "description": "ISO 8601 instant after which shadowgraph_maintain marks this decision stale." + }, + "schemaVersion": { + "description": "Storage schema version this entity was written under. A value above the build’s own version is preserved rather than downgraded.", + "type": "integer" + }, + "sessionId": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "description": "Session identifier recorded with the write." + }, + "sourceClass": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "description": "Claimed origin class recorded with the write. A claim, never proof." + }, + "sourceRaw": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "description": "The original origin label when it differed from sourceClass. Audit only; never evidence." + }, + "status": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "description": "Lifecycle state. Legacy records may carry a value this build does not recognise; shadowgraph_validate reports those." + }, + "supersededBy": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "description": "Identifier of the decision that replaced this one." + }, + "supersedes": { + "description": "Identifiers of decisions this one replaced.", + "type": "array" + }, + "title": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "description": "Short name of the decision." + }, + "updatedAt": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "description": "ISO 8601 time of the last change." + } + }, + "required": [ + "id", + "kind" + ], + "type": "object" +}
- Changed
shadowgraph_context5 fields changed- added
Input schema / properties / changedFacts / descriptionAdded value: +"Fact keys that just changed. Only string-form reopenWhen rules match this list; it is an ephemeral signal, not durable state." - added
Input schema / properties / facts / descriptionAdded value: +"Fact key/value overrides evaluated instead of the stored facts of the same key. Stored facts are used for every key not listed here, so reopen rules still work after a restart." - added
Input schema / properties / limit / descriptionAdded value: +"Maximum items per collection, 1-1000, applied to each collection independently. Omit for the default of 50." - added
Input schema / properties / project / descriptionAdded value: +"Project namespace. Defaults to \"default\"; an empty string is rejected." - changed
Output schema / (root)Previous value: -nullNew value: +{ + "description": "The working set for one project.", + "properties": { + "activeDecisions": { + "description": "Decisions in a current, actionable state: proposed, planned, in_progress, executed, validated, or reconsidered.", + "items": { + "description": "A stored decision, including its alternatives and auditable confidence basis.", + "properties": { + "actor": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "description": "Who performed the write." + }, + "alternatives": { + "description": "Rejected alternatives, each with id, label, reasonRejected, status, and the reopenWhen rules that make it reconsiderable.", + "type": "array" + }, + "assumptions": { + "description": "Assumptions the decision rests on. Searchable content.", + "items": { + "type": "string" + }, + "type": "array" + }, + "chosen": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "description": "The option that was chosen." + }, + "client": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "description": "Which client performed the write." + }, + "confidence": { + "description": "Auditable confidence: initial, current (0-1), policy, a history entry per move, and a basis summarising the contributions it was folded from. Legacy records may lack basis.", + "type": "object" + }, + "createdAt": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "description": "ISO 8601 creation time." + }, + "evidence": { + "description": "Normalised evidence entries: source, type, sourceClass, confidence, observedAt, detail.", + "type": "array" + }, + "failedAttempts": { + "description": "Attempt identifiers or notes attached to this decision.", + "type": "array" + }, + "goal": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "description": "What the decision was trying to achieve." + }, + "id": { + "description": "Stable entity identifier.", + "type": "string" + }, + "kind": { + "description": "Entity kind: decision, attempt, memory, fact, relation, review, or alternative.", + "type": "string" + }, + "migration": { + "description": "Present only on migrated records; records the legacy value a field was mapped from.", + "type": "object" + }, + "outcome": { + "anyOf": [ + { + "type": "object" + }, + { + "type": "null" + } + ], + "description": "The recorded outcome, or null until one is recorded." + }, + "project": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "description": "Project namespace; records imported from a schema that predates projects may carry null." + }, + "reviewAfter": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "description": "ISO 8601 instant after which shadowgraph_maintain marks this decision stale." + }, + "schemaVersion": { + "description": "Storage schema version this entity was written under. A value above the build’s own version is preserved rather than downgraded.", + "type": "integer" + }, + "sessionId": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "description": "Session identifier recorded with the write." + }, + "sourceClass": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "description": "Claimed origin class recorded with the write. A claim, never proof." + }, + "sourceRaw": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "description": "The original origin label when it differed from sourceClass. Audit only; never evidence." + }, + "status": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "description": "Lifecycle state. Legacy records may carry a value this build does not recognise; shadowgraph_validate reports those." + }, + "supersededBy": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "description": "Identifier of the decision that replaced this one." + }, + "supersedes": { + "description": "Identifiers of decisions this one replaced.", + "type": "array" + }, + "title": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "description": "Short name of the decision." + }, + "updatedAt": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "description": "ISO 8601 time of the last change." + } + }, + "required": [ + "id", + "kind" + ], + "type": "object" + }, + "type": "array" + }, + "completeness": { + "description": "Per-collection completeness. context returns five named collections, so one page object cannot describe it.", + "properties": { + "collections": { + "description": "One entry per returned collection.", + "properties": { + "activeDecisions": { + "description": "Counts for activeDecisions.", + "properties": { + "hasMore": { + "description": "True when this collection was truncated.", + "type": "boolean" + }, + "omitted": { + "description": "total minus returned for this collection.", + "minimum": 0, + "type": "integer" + }, + "returned": { + "description": "Items returned for this collection.", + "minimum": 0, + "type": "integer" + }, + "total": { + "description": "Items that matched for this collection.", + "minimum": 0, + "type": "integer" + } + }, + "required": [ + "returned", + "total", + "hasMore", + "omitted" + ], + "type": "object" + }, + "failedAttemptsToAvoid": { + "description": "Counts for failedAttemptsToAvoid.", + "properties": { + "hasMore": { + "description": "True when this collection was truncated.", + "type": "boolean" + }, + "omitted": { + "description": "total minus returned for this collection.", + "minimum": 0, + "type": "integer" + }, + "returned": { + "description": "Items returned for this collection.", + "minimum": 0, + "type": "integer" + }, + "total": { + "description": "Items that matched for this collection.", + "minimum": 0, + "type": "integer" + } + }, + "required": [ + "returned", + "total", + "hasMore", + "omitted" + ], + "type": "object" + }, + "openReviews": { + "description": "Counts for openReviews.", + "properties": { + "hasMore": { + "description": "True when this collection was truncated.", + "type": "boolean" + }, + "omitted": { + "description": "total minus returned for this collection.", + "minimum": 0, + "type": "integer" + }, + "returned": { + "description": "Items returned for this collection.", + "minimum": 0, + "type": "integer" + }, + "total": { + "description": "Items that matched for this collection.", + "minimum": 0, + "type": "integer" + } + }, + "required": [ + "returned", + "total", + "hasMore", + "omitted" + ], + "type": "object" + }, + "staleAssumptions": { + "description": "Counts for staleAssumptions.", + "properties": { + "hasMore": { + "description": "True when this collection was truncated.", + "type": "boolean" + }, + "omitted": { + "description": "total minus returned for this collection.", + "minimum": 0, + "type": "integer" + }, + "returned": { + "description": "Items returned for this collection.", + "minimum": 0, + "type": "integer" + }, + "total": { + "description": "Items that matched for this collection.", + "minimum": 0, + "type": "integer" + } + }, + "required": [ + "returned", + "total", + "hasMore", + "omitted" + ], + "type": "object" + }, + "suggestedQuestions": { + "description": "Counts for suggestedQuestions.", + "properties": { + "hasMore": { + "description": "True when this collection was truncated.", + "type": "boolean" + }, + "omitted": { + "description": "total minus returned for this collection.", + "minimum": 0, + "type": "integer" + }, + "returned": { + "description": "Items returned for this collection.", + "minimum": 0, + "type": "integer" + }, + "total": { + "description": "Items that matched for this collection.", + "minimum": 0, + "type": "integer" + } + }, + "required": [ + "returned", + "total", + "hasMore", + "omitted" + ], + "type": "object" + } + }, + "required": [ + "activeDecisions", + "staleAssumptions", + "failedAttemptsToAvoid", + "openReviews", + "suggestedQuestions" + ], + "type": "object" + }, + "complete": { + "description": "True only when no collection was truncated.", + "type": "boolean" + }, + "limitSource": { + "description": "Whose choice bounded the collections.", + "enum": [ + "caller", + "default" + ], + "type": "string" + }, + "losslessItems": { + "description": "Always true: items are full records, never summaries.", + "type": "boolean" + }, + "scope": { + "description": "The project this result covers.", + "type": "object" + } + }, + "required": [ + "scope", + "complete", + "limitSource", + "losslessItems", + "collections" + ], + "type": "object" + }, + "failedAttemptsToAvoid": { + "description": "Attempts whose result mentions failure, regression, or error.", + "items": { + "description": "A stored attempt and its result.", + "properties": { + "actor": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "description": "Who performed the write." + }, + "client": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "description": "Which client performed the write." + }, + "createdAt": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "description": "ISO 8601 creation time." + }, + "environment": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "description": "Where it was tried." + }, + "id": { + "description": "Stable entity identifier.", + "type": "string" + }, + "kind": { + "description": "Entity kind: decision, attempt, memory, fact, relation, review, or alternative.", + "type": "string" + }, + "project": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "description": "Project namespace; records imported from a schema that predates projects may carry null." + }, + "reason": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "description": "Why it turned out that way." + }, + "relatedTo": { + "description": "Identifiers of related entities.", + "type": "array" + }, + "result": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "description": "What happened." + }, + "reusableWhen": { + "description": "Conditions under which the attempt is worth repeating.", + "type": "array" + }, + "schemaVersion": { + "description": "Storage schema version this entity was written under. A value above the build’s own version is preserved rather than downgraded.", + "type": "integer" + }, + "sessionId": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "description": "Session identifier recorded with the write." + }, + "solution": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "description": "What was tried." + }, + "sourceClass": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "description": "Claimed origin class recorded with the write. A claim, never proof." + }, + "sourceRaw": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "description": "The original origin label when it differed from sourceClass. Audit only; never evidence." + }, + "updatedAt": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "description": "ISO 8601 time of the last change." + } + }, + "required": [ + "id", + "kind" + ], + "type": "object" + }, + "type": "array" + }, + "openReviews": { + "description": "Decisions currently due for reconsideration.", + "items": { + "description": "One decision whose rejected alternatives are due for reconsideration.", + "properties": { + "alternativesToReconsider": { + "description": "Labels of the alternatives to look at again; all of them when the trigger was not alternative-specific.", + "items": { + "type": "string" + }, + "type": "array" + }, + "decisionId": { + "description": "The decision to reconsider.", + "type": "string" + }, + "reason": { + "description": "Comma-separated causes: the fact keys whose reopenWhen rules matched, \"review date reached\", or \"decision outcome failed\".", + "type": "string" + }, + "title": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "description": "Decision title, when the stored decision has one." + } + }, + "required": [ + "decisionId", + "reason", + "alternativesToReconsider" + ], + "type": "object" + }, + "type": "array" + }, + "project": { + "description": "The project this context describes.", + "type": "string" + }, + "staleAssumptions": { + "description": "Facts that are no longer active, such as superseded or expired ones, which earlier decisions may still rest on.", + "items": { + "description": "A stored fact with its provenance claim and validity window.", + "properties": { + "actor": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "description": "Who performed the write." + }, + "client": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "description": "Which client performed the write." + }, + "confidence": { + "anyOf": [ + { + "type": "number" + }, + { + "type": "null" + } + ], + "description": "Caller-declared confidence in the observation, 0-1." + }, + "createdAt": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "description": "ISO 8601 creation time." + }, + "expiresAt": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "description": "Caller-declared expiry instant, or null." + }, + "id": { + "description": "Stable entity identifier.", + "type": "string" + }, + "key": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "description": "Fact name, unique per project among active facts." + }, + "kind": { + "description": "Entity kind: decision, attempt, memory, fact, relation, review, or alternative.", + "type": "string" + }, + "observedAt": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "description": "ISO 8601 time the fact was observed." + }, + "project": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "description": "Project namespace; records imported from a schema that predates projects may carry null." + }, + "schemaVersion": { + "description": "Storage schema version this entity was written under. A value above the build’s own version is preserved rather than downgraded.", + "type": "integer" + }, + "sessionId": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "description": "Session identifier recorded with the write." + }, + "source": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "description": "Legacy alias of sourceClass, retained for compatibility." + }, + "sourceClass": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "description": "Claimed origin class recorded with the write. A claim, never proof." + }, + "sourceRaw": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "description": "The original origin label when it differed from sourceClass. Audit only; never evidence." + }, + "status": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "description": "active, superseded, or expired." + }, + "temporal": { + "description": "Bi-temporal window: validFrom, validTo, recordedAt, invalidatedAt.", + "type": "object" + }, + "updatedAt": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "description": "ISO 8601 time of the last change." + }, + "validityPolicy": { + "description": "Declared expiry inputs and the effective expiration boundary derived from them.", + "type": "object" + }, + "value": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + }, + { + "type": "null" + }, + { + "type": "array" + }, + { + "type": "object" + } + ], + "description": "The observed value, any lossless JSON value." + }, + "verification": { + "description": "Present only on a signed verification: the attestation this build checked.", + "type": "object" + }, + "verificationStatus": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "description": "unverified, contradicted, expired, or verified. Only the separately configured signed-evidence verifier can produce verified." + } + }, + "required": [ + "key" + ], + "type": "object" + }, + "type": "array" + }, + "suggestedQuestions": { + "description": "Questions for the low-confidence decisions in this project.", + "items": { + "type": "string" + }, + "type": "array" + } + }, + "required": [ + "project", + "activeDecisions", + "staleAssumptions", + "failedAttemptsToAvoid", + "openReviews", + "suggestedQuestions", + "completeness" + ], + "type": "object" +}
- Changed
shadowgraph_journal4 fields changed- changed
Input schema / properties / limit / descriptionPrevious value: -"Page size. Omitted means a declared default, never silent truncation."New value: +"Maximum items to return, 1-1000; the default is 50 and completeness.limitSource reports which applied. Out of range is rejected, never silently clamped." - changed
Input schema / properties / offset / descriptionPrevious value: -"Page offset."New value: +"Items to skip before this window. Ordering is total and deterministic, so paging cannot drop or duplicate an item." - added
Input schema / properties / project / descriptionAdded value: +"Return only entries recorded for this project. Omit for every project, including entries with no project." - changed
Output schema / (root)Previous value: -nullNew value: +{ + "description": "Journal entries with pagination, replay boundary, and declared gaps.", + "properties": { + "completeness": { + "description": "Declares exactly what this response left out, so a truncated result can never look complete.", + "properties": { + "complete": { + "description": "True only when every matching item is present.", + "type": "boolean" + }, + "gaps": { + "description": "Sequence ranges missing from the journal, each { from, to }. A hard purge legitimately creates one; it is declared, not hidden.", + "items": { + "properties": { + "from": { + "description": "First missing sequence.", + "type": "integer" + }, + "to": { + "description": "Last missing sequence.", + "type": "integer" + } + }, + "type": "object" + }, + "type": "array" + }, + "journalEpoch": { + "anyOf": [ + { + "type": "integer" + }, + { + "type": "null" + } + ], + "description": "First replayable sequence, or null when nothing is replayable." + }, + "journalSeq": { + "description": "Highest sequence issued so far.", + "type": "integer" + }, + "limitSource": { + "description": "Whose choice bounded the result.", + "enum": [ + "caller", + "default" + ], + "type": "string" + }, + "losslessItems": { + "description": "Always true: each returned item is a full-fidelity record, never a summary or a truncated field.", + "type": "boolean" + }, + "omitted": { + "description": "total minus returned.", + "minimum": 0, + "type": "integer" + }, + "returned": { + "description": "Items in this response.", + "minimum": 0, + "type": "integer" + }, + "scope": { + "description": "The project, query, and structured filters that produced this result, so it explains its own derivation.", + "type": "object" + }, + "total": { + "description": "Items that matched in total.", + "minimum": 0, + "type": "integer" + } + }, + "required": [ + "scope", + "returned", + "total", + "complete", + "omitted", + "losslessItems", + "limitSource", + "journalEpoch", + "journalSeq", + "gaps" + ], + "type": "object" + }, + "items": { + "description": "The items in this window, in deterministic order.", + "items": { + "description": "One journal entry: a complete post-operation snapshot. Entries imported from older schemas may lack seq or payload.", + "properties": { + "at": { + "description": "ISO 8601 time the entry was appended.", + "type": "string" + }, + "causationId": { + "description": "Present only when this entry was caused by another; carries that entry id.", + "type": "string" + }, + "entityId": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "description": "Identifier of that entity; null on a redacted skeleton." + }, + "entityKind": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "description": "Kind of the entity the entry is about." + }, + "id": { + "description": "Entry identifier.", + "type": "string" + }, + "idempotencyKey": { + "description": "Present only when the write carried a retry key.", + "type": "string" + }, + "payload": { + "anyOf": [ + { + "type": "object" + }, + { + "type": "null" + } + ], + "description": "The complete post-operation snapshot, or null once a logical purge reduced the entry to an audit skeleton." + }, + "project": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "description": "Project the entry belongs to." + }, + "provenance": { + "description": "actor, client, and sessionId recorded with the write; all null on purged skeletons.", + "type": "object" + }, + "redacted": { + "description": "Present only on entries reduced by a logical purge.", + "type": "boolean" + }, + "redactedReason": { + "description": "Why the entry was reduced.", + "type": "string" + }, + "schemaVersion": { + "description": "Schema version the entry was written under.", + "type": "integer" + }, + "seq": { + "description": "Monotonic sequence number. Absent on pre-journal metadata entries.", + "type": "integer" + }, + "transition": { + "description": "Present only on lifecycle changes; carries from, to, and the actor that made them.", + "type": "object" + }, + "type": { + "description": "Entry type, such as decision.recorded, fact.observed, memory.superseded, or project.purged.", + "type": "string" + } + }, + "type": "object" + }, + "type": "array" + }, + "page": { + "description": "The window actually applied to the matching items.", + "properties": { + "hasMore": { + "description": "True when matching items exist beyond this window.", + "type": "boolean" + }, + "limit": { + "description": "Window size applied, whether the caller set it or the default did.", + "minimum": 1, + "type": "integer" + }, + "offset": { + "description": "Index of the first item returned.", + "minimum": 0, + "type": "integer" + }, + "total": { + "description": "Matching items before the window was applied.", + "minimum": 0, + "type": "integer" + } + }, + "required": [ + "offset", + "limit", + "total", + "hasMore" + ], + "type": "object" + } + }, + "required": [ + "items", + "page", + "completeness" + ], + "type": "object" +}
- Changed
shadowgraph_link4 fields changed- added
Input schema / properties / from / descriptionAdded value: +"Source entity id. Must already exist: a decision, attempt, memory, fact, or alternative." - added
Input schema / properties / relation / descriptionAdded value: +"Relationship name, chosen by the caller and stored verbatim, such as depends_on, contradicts, or informs. It is what shadowgraph_traverse filters and explains hits by, so keep names consistent." - added
Input schema / properties / to / descriptionAdded value: +"Target entity id. Must already exist." - changed
Output schema / (root)Previous value: -nullNew value: +{ + "description": "The relationship that was created.", + "properties": { + "createdAt": { + "description": "ISO 8601 creation time.", + "type": "string" + }, + "from": { + "description": "Source entity identifier.", + "type": "string" + }, + "id": { + "description": "Identifier minted for this relationship. A new one on every call.", + "type": "string" + }, + "kind": { + "const": "relation", + "description": "Always \"relation\".", + "type": "string" + }, + "relation": { + "description": "Relationship name as supplied.", + "type": "string" + }, + "schemaVersion": { + "description": "Storage schema version.", + "type": "integer" + }, + "temporal": { + "description": "Bi-temporal window: validFrom, validTo, recordedAt, invalidatedAt.", + "type": "object" + }, + "to": { + "description": "Target entity identifier.", + "type": "string" + } + }, + "required": [ + "id", + "kind", + "schemaVersion", + "from", + "to", + "relation", + "createdAt", + "temporal" + ], + "type": "object" +}
- Changed
shadowgraph_maintain5 fields changed- added
Input schema / properties / changedFacts / descriptionAdded value: +"Fact keys that just changed. Only string-form reopenWhen rules match this list; it is an ephemeral signal, not durable state." - added
Input schema / properties / changedFacts / itemsAdded value: +{ + "type": "string" +} - added
Input schema / properties / facts / descriptionAdded value: +"Fact key/value overrides evaluated instead of the stored facts of the same key. Stored facts are used for every key not listed here, so reopen rules still work after a restart." - added
Input schema / properties / now / descriptionAdded value: +"ISO 8601 instant to treat as the current time. Defaults to the real clock; supplying it makes the run deterministic." - changed
Output schema / (root)Previous value: -nullNew value: +{ + "description": "What maintenance changed and what is now due.", + "properties": { + "agedDecisionIds": { + "description": "Compatibility alias of staleDecisionIds for older callers.", + "items": { + "type": "string" + }, + "type": "array" + }, + "at": { + "description": "The instant maintenance ran against.", + "type": "string" + }, + "due": { + "description": "Decisions due for reconsideration after the run.", + "items": { + "description": "One decision whose rejected alternatives are due for reconsideration.", + "properties": { + "alternativesToReconsider": { + "description": "Labels of the alternatives to look at again; all of them when the trigger was not alternative-specific.", + "items": { + "type": "string" + }, + "type": "array" + }, + "decisionId": { + "description": "The decision to reconsider.", + "type": "string" + }, + "reason": { + "description": "Comma-separated causes: the fact keys whose reopenWhen rules matched, \"review date reached\", or \"decision outcome failed\".", + "type": "string" + }, + "title": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "description": "Decision title, when the stored decision has one." + } + }, + "required": [ + "decisionId", + "reason", + "alternativesToReconsider" + ], + "type": "object" + }, + "type": "array" + }, + "reviewSignals": { + "description": "Every persisted review signal after the run, open and acknowledged alike.", + "items": { + "description": "A persisted review signal.", + "properties": { + "acknowledgedAt": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "description": "ISO 8601 time of the most recent acknowledgement." + }, + "alternativesToReconsider": { + "description": "Alternative labels to look at again.", + "items": { + "type": "string" + }, + "type": "array" + }, + "createdAt": { + "description": "ISO 8601 time the signal was raised.", + "type": "string" + }, + "decisionId": { + "description": "The decision this signal is about.", + "type": "string" + }, + "id": { + "description": "Signal identifier, used by shadowgraph_ack_review.", + "type": "string" + }, + "kind": { + "const": "review", + "description": "Always \"review\".", + "type": "string" + }, + "reason": { + "description": "Why the signal was raised. Together with decisionId this is the dedupe identity, so the same cause never raises a second signal.", + "type": "string" + }, + "status": { + "description": "open until acknowledged.", + "enum": [ + "open", + "acknowledged" + ], + "type": "string" + }, + "title": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "description": "Decision title, when the stored decision has one." + } + }, + "required": [ + "id", + "kind", + "decisionId", + "reason", + "alternativesToReconsider", + "status", + "createdAt" + ], + "type": "object" + }, + "type": "array" + }, + "staleDecisionIds": { + "description": "Decisions moved to stale because they passed reviewAfter.", + "items": { + "type": "string" + }, + "type": "array" + } + }, + "required": [ + "at", + "staleDecisionIds", + "agedDecisionIds", + "reviewSignals", + "due" + ], + "type": "object" +}
- Changed
shadowgraph_purge3 fields changed- changed
Input schema / properties / mode / descriptionPrevious value: -"Defaults to logical. `hard` is irreversible and removes audit history."New value: +"Defaults to logical, which keeps an auditable payload-free journal skeleton. \"hard\" is irreversible, physically removes journal entries, and leaves a sequence gap that validate() reports." - added
Input schema / properties / project / descriptionAdded value: +"Project to delete. Required and non-empty; there is no wildcard." - changed
Output schema / (root)Previous value: -nullNew value: +{ + "description": "What the purge removed.", + "properties": { + "events": { + "description": "Compatibility events that were present.", + "minimum": 0, + "type": "integer" + }, + "facts": { + "description": "Facts that were present.", + "minimum": 0, + "type": "integer" + }, + "idempotencyRemoved": { + "description": "Retry keys removed with the project.", + "minimum": 0, + "type": "integer" + }, + "journal": { + "description": "Journal entries that were present for the project.", + "minimum": 0, + "type": "integer" + }, + "journalEntriesRedacted": { + "description": "Entries reduced to an audit skeleton by a logical purge.", + "minimum": 0, + "type": "integer" + }, + "journalEntriesRemoved": { + "description": "Entries physically deleted by a hard purge.", + "minimum": 0, + "type": "integer" + }, + "journalEntryId": { + "description": "Id of the project.purged entry that records this purge.", + "type": "string" + }, + "mode": { + "description": "The mode that was applied.", + "enum": [ + "logical", + "hard" + ], + "type": "string" + }, + "project": { + "description": "The project that was purged.", + "type": "string" + }, + "records": { + "description": "Decisions, attempts, and memories that were present.", + "minimum": 0, + "type": "integer" + }, + "relations": { + "description": "Relationships that were present.", + "minimum": 0, + "type": "integer" + }, + "removed": { + "description": "Entities removed from live state, including alternatives.", + "minimum": 0, + "type": "integer" + }, + "removedJournalSequences": { + "description": "Sequence numbers a hard purge removed, declared so the resulting gap is explained rather than hidden.", + "items": { + "type": "integer" + }, + "type": "array" + } + }, + "required": [ + "project", + "records", + "facts", + "relations", + "events", + "journal", + "removed", + "mode", + "journalEntriesRedacted", + "journalEntriesRemoved", + "removedJournalSequences", + "idempotencyRemoved", + "journalEntryId" + ], + "type": "object" +}
- Changed
shadowgraph_purge_preview2 fields changed- added
Input schema / properties / project / descriptionAdded value: +"Project name to preview, matched exactly. Required and non-empty." - changed
Output schema / (root)Previous value: -nullNew value: +{ + "description": "What a purge of this project would remove.", + "properties": { + "events": { + "description": "Compatibility events for the project.", + "minimum": 0, + "type": "integer" + }, + "facts": { + "description": "Facts in the project.", + "minimum": 0, + "type": "integer" + }, + "journal": { + "description": "Journal entries recorded for the project.", + "minimum": 0, + "type": "integer" + }, + "project": { + "description": "The project that was previewed.", + "type": "string" + }, + "records": { + "description": "Decisions, attempts, and memories in the project.", + "minimum": 0, + "type": "integer" + }, + "relations": { + "description": "Relationships touching the project.", + "minimum": 0, + "type": "integer" + } + }, + "required": [ + "project", + "records", + "facts", + "relations", + "events", + "journal" + ], + "type": "object" +}
- Changed
shadowgraph_rebuild2 fields changed- changed
Input schema / properties / requireFullHistory / descriptionPrevious value: -"When true, refuse to rebuild if pre-journal metadata-only entries exist."New value: +"When true, refuse to rebuild if pre-journal metadata-only entries exist, returning rebuildable:false instead of a fold that silently starts later. Defaults to false." - changed
Output schema / (root)Previous value: -nullNew value: +{ + "description": "The rebuild report and the projection it produced.", + "properties": { + "applied": { + "description": "Entries folded into the projection.", + "minimum": 0, + "type": "integer" + }, + "duplicates": { + "description": "Sequence numbers appearing more than once, each { seq, count }. A repeated sequence cannot be totally ordered, so it makes the fold untrustworthy.", + "type": "array" + }, + "journalEpoch": { + "anyOf": [ + { + "type": "integer" + }, + { + "type": "null" + } + ], + "description": "First replayable sequence." + }, + "legacy": { + "description": "Entries recognised as pre-journal or non-replayable, each with a why.", + "type": "array" + }, + "ok": { + "description": "True when the fold ran; it does not by itself mean the projection is complete.", + "type": "boolean" + }, + "projection": { + "description": "The projection folded from the journal.", + "properties": { + "facts": { + "description": "Facts reconstructed by the fold.", + "items": { + "description": "A stored fact with its provenance claim and validity window.", + "properties": { + "actor": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "description": "Who performed the write." + }, + "client": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "description": "Which client performed the write." + }, + "confidence": { + "anyOf": [ + { + "type": "number" + }, + { + "type": "null" + } + ], + "description": "Caller-declared confidence in the observation, 0-1." + }, + "createdAt": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "description": "ISO 8601 creation time." + }, + "expiresAt": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "description": "Caller-declared expiry instant, or null." + }, + "id": { + "description": "Stable entity identifier.", + "type": "string" + }, + "key": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "description": "Fact name, unique per project among active facts." + }, + "kind": { + "description": "Entity kind: decision, attempt, memory, fact, relation, review, or alternative.", + "type": "string" + }, + "observedAt": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "description": "ISO 8601 time the fact was observed." + }, + "project": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "description": "Project namespace; records imported from a schema that predates projects may carry null." + }, + "schemaVersion": { + "description": "Storage schema version this entity was written under. A value above the build’s own version is preserved rather than downgraded.", + "type": "integer" + }, + "sessionId": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "description": "Session identifier recorded with the write." + }, + "source": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "description": "Legacy alias of sourceClass, retained for compatibility." + }, + "sourceClass": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "description": "Claimed origin class recorded with the write. A claim, never proof." + }, + "sourceRaw": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "description": "The original origin label when it differed from sourceClass. Audit only; never evidence." + }, + "status": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "description": "active, superseded, or expired." + }, + "temporal": { + "description": "Bi-temporal window: validFrom, validTo, recordedAt, invalidatedAt.", + "type": "object" + }, + "updatedAt": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "description": "ISO 8601 time of the last change." + }, + "validityPolicy": { + "description": "Declared expiry inputs and the effective expiration boundary derived from them.", + "type": "object" + }, + "value": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + }, + { + "type": "null" + }, + { + "type": "array" + }, + { + "type": "object" + } + ], + "description": "The observed value, any lossless JSON value." + }, + "verification": { + "description": "Present only on a signed verification: the attestation this build checked.", + "type": "object" + }, + "verificationStatus": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "description": "unverified, contradicted, expired, or verified. Only the separately configured signed-evidence verifier can produce verified." + } + }, + "required": [ + "key" + ], + "type": "object" + }, + "type": "array" + }, + "idempotency": { + "description": "Retry-key entries reconstructed by the fold.", + "type": "array" + }, + "records": { + "description": "Decisions, attempts, and memories reconstructed by the fold.", + "items": { + "description": "One stored entity: a decision, attempt, memory, fact, or alternative. Fields vary by kind, and an entity imported from an older schema may carry fewer of them.", + "properties": { + "actor": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "description": "Who performed the write." + }, + "client": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "description": "Which client performed the write." + }, + "createdAt": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "description": "ISO 8601 creation time." + }, + "id": { + "description": "Stable entity identifier.", + "type": "string" + }, + "kind": { + "description": "Entity kind: decision, attempt, memory, fact, relation, review, or alternative.", + "type": "string" + }, + "project": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "description": "Project namespace; records imported from a schema that predates projects may carry null." + }, + "schemaVersion": { + "description": "Storage schema version this entity was written under. A value above the build’s own version is preserved rather than downgraded.", + "type": "integer" + }, + "sessionId": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "description": "Session identifier recorded with the write." + }, + "sourceClass": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "description": "Claimed origin class recorded with the write. A claim, never proof." + }, + "sourceRaw": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "description": "The original origin label when it differed from sourceClass. Audit only; never evidence." + }, + "updatedAt": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "description": "ISO 8601 time of the last change." + } + }, + "type": "object" + }, + "type": "array" + }, + "relations": { + "description": "Relationships reconstructed by the fold.", + "items": { + "description": "A stored relationship between two entities.", + "properties": { + "actor": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "description": "Who performed the write." + }, + "client": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "description": "Which client performed the write." + }, + "createdAt": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "description": "ISO 8601 creation time." + }, + "from": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "description": "Source entity identifier." + }, + "id": { + "description": "Stable entity identifier.", + "type": "string" + }, + "kind": { + "description": "Entity kind: decision, attempt, memory, fact, relation, review, or alternative.", + "type": "string" + }, + "project": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "description": "Project namespace; records imported from a schema that predates projects may carry null." + }, + "relation": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "description": "Relationship name, such as depends_on or supersedes." + }, + "schemaVersion": { + "description": "Storage schema version this entity was written under. A value above the build’s own version is preserved rather than downgraded.", + "type": "integer" + }, + "sessionId": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "description": "Session identifier recorded with the write." + }, + "sourceClass": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "description": "Claimed origin class recorded with the write. A claim, never proof." + }, + "sourceRaw": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "description": "The original origin label when it differed from sourceClass. Audit only; never evidence." + }, + "temporal": { + "description": "Bi-temporal window for the relationship.", + "type": "object" + }, + "to": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "description": "Target entity identifier." + }, + "updatedAt": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "description": "ISO 8601 time of the last change." + } + }, + "required": [ + "id", + "from", + "to", + "relation" + ], + "type": "object" + }, + "type": "array" + }, + "schemaVersion": { + "description": "Schema version of the rebuilt projection.", + "type": "integer" + } + }, + "required": [ + "schemaVersion", + "records", + "facts", + "relations", + "idempotency" + ], + "type": "object" + }, + "reason": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "description": "Why the projection is not rebuildable, or null when it is." + }, + "rebuildable": { + "description": "True only when every entry in the replay range was folded and the result is trustworthy.", + "type": "boolean" + }, + "replayedFrom": { + "anyOf": [ + { + "type": "integer" + }, + { + "type": "null" + } + ], + "description": "Lowest sequence folded." + }, + "replayedTo": { + "anyOf": [ + { + "type": "integer" + }, + { + "type": "null" + } + ], + "description": "Highest sequence folded." + }, + "skipped": { + "description": "Entries not folded, each carrying seq, type, and a stable why such as unknown_entry_type or unsupported_schema_version.", + "type": "array" + } + }, + "required": [ + "ok", + "rebuildable", + "reason", + "projection", + "journalEpoch", + "replayedFrom", + "replayedTo", + "applied", + "skipped", + "legacy", + "duplicates" + ], + "type": "object" +}
- Changed
shadowgraph_recall14 fields changed- added
Input schema / properties / asOf / descriptionAdded value: +"ISO 8601 instant to select by valid time, returning what was true then rather than now. Also enables temporal ranking." - added
Input schema / properties / focalId / descriptionAdded value: +"Entity id to measure graph distance from. Without it the graph signal reports available:false." - changed
Input schema / properties / limit / descriptionPrevious value: -"Page size. Omitted means a declared default, never silent truncation."New value: +"Maximum items to return, 1-1000; the default is 50 and completeness.limitSource reports which applied. Out of range is rejected, never silently clamped." - added
Input schema / properties / memoryType / descriptionAdded value: +"Restrict memory candidates to this type." - changed
Input schema / properties / offset / descriptionPrevious value: -"Page offset."New value: +"Items to skip before this window. Ordering is total and deterministic, so paging cannot drop or duplicate an item." - added
Input schema / properties / preferRecent / descriptionAdded value: +"Enable temporal ranking against now. Ignored when asOf is supplied, which already selects a point in time." - added
Input schema / properties / project / descriptionAdded value: +"Project to recall from. Defaults to \"default\" for memory records rather than meaning all projects." - added
Input schema / properties / query / descriptionAdded value: +"Free text to rank against. An empty query still returns scope-matching records ranked by the remaining signals." - changed
Input schema / properties / queryEmbedding / descriptionPrevious value: -"Optional caller-supplied vector. When omitted, the configured embedding provider is used."New value: +"Caller-supplied query vector. Omit to use the configured provider; with neither, the semantic signal reports available:false and a reason." - added
Input schema / properties / scope / descriptionAdded value: +"Scope selector. Omitted or partial fields mean explicit nulls, not \"any\": identity is the exact (project, userId, agentId, runId, memoryType, key) tuple, so a run-scoped memory never leaks into a user-only read." - added
Input schema / properties / scope / properties / agentId / descriptionAdded value: +"Agent this memory belongs to, or null for none." - added
Input schema / properties / scope / properties / runId / descriptionAdded value: +"Single run or task this memory belongs to, or null for none." - added
Input schema / properties / scope / properties / userId / descriptionAdded value: +"Person this memory belongs to, or null for none." - changed
Output schema / (root)Previous value: -nullNew value: +{ + "description": "Fused results with a per-signal explanation of how they were ranked.", + "properties": { + "completeness": { + "description": "Declares exactly what this response left out, so a truncated result can never look complete.", + "properties": { + "complete": { + "description": "True only when every matching item is present.", + "type": "boolean" + }, + "limitSource": { + "description": "Whose choice bounded the result.", + "enum": [ + "caller", + "default" + ], + "type": "string" + }, + "losslessItems": { + "description": "Always true: each returned item is a full-fidelity record, never a summary or a truncated field.", + "type": "boolean" + }, + "omitted": { + "description": "total minus returned.", + "minimum": 0, + "type": "integer" + }, + "ranking": { + "description": "How the per-signal lists were fused.", + "properties": { + "k": { + "description": "Reciprocal rank fusion constant.", + "type": "number" + }, + "strategy": { + "description": "Fusion strategy identifier, currently weighted_rrf.", + "type": "string" + }, + "weights": { + "description": "Per-signal weights applied during fusion.", + "type": "object" + } + }, + "required": [ + "strategy", + "k", + "weights" + ], + "type": "object" + }, + "returned": { + "description": "Items in this response.", + "minimum": 0, + "type": "integer" + }, + "scope": { + "description": "The project, query, and structured filters that produced this result, so it explains its own derivation.", + "type": "object" + }, + "signals": { + "description": "Authoritative per-signal availability. A signal that could not run says so instead of being silently dropped or renamed.", + "properties": { + "graph": { + "description": "Graph-distance ranking from focalId.", + "properties": { + "available": { + "description": "Whether this signal could contribute at all.", + "type": "boolean" + }, + "matched": { + "description": "Candidates this signal contributed.", + "minimum": 0, + "type": "integer" + }, + "reason": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "description": "Why the signal was unavailable, when it was." + } + }, + "required": [ + "available", + "matched", + "reason" + ], + "type": "object" + }, + "lexical": { + "description": "BM25-style lexical matching over declared content.", + "properties": { + "available": { + "description": "True when the query contained terms.", + "type": "boolean" + }, + "matched": { + "description": "Candidates the lexical list contributed.", + "minimum": 0, + "type": "integer" + }, + "terms": { + "description": "The query terms that were used.", + "items": { + "type": "string" + }, + "type": "array" + } + }, + "required": [ + "available", + "matched", + "terms" + ], + "type": "object" + }, + "semantic": { + "description": "Cosine vector matching. available is false when no compatible query vector or provider existed; the result is then lexical, graph, and temporal only.", + "properties": { + "available": { + "description": "Whether this signal could contribute at all.", + "type": "boolean" + }, + "matched": { + "description": "Candidates this signal contributed.", + "minimum": 0, + "type": "integer" + }, + "reason": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "description": "Why the signal was unavailable, when it was." + } + }, + "required": [ + "available", + "matched", + "reason" + ], + "type": "object" + }, + "temporal": { + "description": "Recency ranking from asOf or preferRecent.", + "properties": { + "asOf": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "description": "The point in time selection was made against, or null for now." + }, + "available": { + "description": "Whether recency ranking ran.", + "type": "boolean" + }, + "matched": { + "description": "Candidates the temporal list contributed.", + "minimum": 0, + "type": "integer" + }, + "reason": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "description": "Why recency ranking did not run, when it did not." + } + }, + "required": [ + "available", + "matched", + "reason", + "asOf" + ], + "type": "object" + } + }, + "required": [ + "lexical", + "semantic", + "graph", + "temporal" + ], + "type": "object" + }, + "total": { + "description": "Items that matched in total.", + "minimum": 0, + "type": "integer" + } + }, + "required": [ + "scope", + "returned", + "total", + "complete", + "omitted", + "losslessItems", + "limitSource", + "signals", + "ranking" + ], + "type": "object" + }, + "items": { + "description": "The items in this window, in deterministic order.", + "items": { + "description": "One recalled record with its per-signal explanation.", + "properties": { + "ranks": { + "description": "Position this item held in each signal list, counting from 1, or null where that signal did not rank it.", + "properties": { + "graph": { + "anyOf": [ + { + "type": "integer" + }, + { + "type": "null" + } + ], + "description": "Position in the graph-distance list; null when no focalId was supplied." + }, + "lexical": { + "anyOf": [ + { + "type": "integer" + }, + { + "type": "null" + } + ], + "description": "Position in the BM25-style lexical list." + }, + "semantic": { + "anyOf": [ + { + "type": "integer" + }, + { + "type": "null" + } + ], + "description": "Position in the vector list; null when no compatible query vector or provider existed." + }, + "temporal": { + "anyOf": [ + { + "type": "integer" + }, + { + "type": "null" + } + ], + "description": "Position in the recency list; null when neither asOf nor preferRecent was supplied." + } + }, + "required": [ + "lexical", + "semantic", + "graph", + "temporal" + ], + "type": "object" + }, + "reasons": { + "description": "One entry per contributing signal, naming the rank it contributed.", + "items": { + "type": "string" + }, + "type": "array" + }, + "record": { + "description": "One stored entity: a decision, attempt, memory, fact, or alternative. Fields vary by kind, and an entity imported from an older schema may carry fewer of them.", + "properties": { + "actor": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "description": "Who performed the write." + }, + "client": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "description": "Which client performed the write." + }, + "createdAt": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "description": "ISO 8601 creation time." + }, + "id": { + "description": "Stable entity identifier.", + "type": "string" + }, + "kind": { + "description": "Entity kind: decision, attempt, memory, fact, relation, review, or alternative.", + "type": "string" + }, + "project": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "description": "Project namespace; records imported from a schema that predates projects may carry null." + }, + "schemaVersion": { + "description": "Storage schema version this entity was written under. A value above the build’s own version is preserved rather than downgraded.", + "type": "integer" + }, + "sessionId": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "description": "Session identifier recorded with the write." + }, + "sourceClass": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "description": "Claimed origin class recorded with the write. A claim, never proof." + }, + "sourceRaw": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "description": "The original origin label when it differed from sourceClass. Audit only; never evidence." + }, + "updatedAt": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "description": "ISO 8601 time of the last change." + } + }, + "type": "object" + }, + "score": { + "description": "Fused score.", + "type": "number" + }, + "scores": { + "description": "The raw value behind each rank, or null where that signal did not rank this item.", + "properties": { + "graph": { + "anyOf": [ + { + "type": "number" + }, + { + "type": "null" + } + ], + "description": "Hop distance from focalId." + }, + "lexical": { + "anyOf": [ + { + "type": "number" + }, + { + "type": "null" + } + ], + "description": "BM25-style lexical score." + }, + "semantic": { + "anyOf": [ + { + "type": "number" + }, + { + "type": "null" + } + ], + "description": "Cosine similarity between the query vector and the stored vector." + }, + "temporal": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "description": "The ISO 8601 validFrom or recordedAt instant recency ordering used, not a number." + } + }, + "required": [ + "lexical", + "semantic", + "graph", + "temporal" + ], + "type": "object" + } + }, + "required": [ + "record", + "score", + "ranks", + "scores", + "reasons" + ], + "type": "object" + }, + "type": "array" + }, + "page": { + "description": "The window actually applied to the matching items.", + "properties": { + "hasMore": { + "description": "True when matching items exist beyond this window.", + "type": "boolean" + }, + "limit": { + "description": "Window size applied, whether the caller set it or the default did.", + "minimum": 1, + "type": "integer" + }, + "offset": { + "description": "Index of the first item returned.", + "minimum": 0, + "type": "integer" + }, + "total": { + "description": "Matching items before the window was applied.", + "minimum": 0, + "type": "integer" + } + }, + "required": [ + "offset", + "limit", + "total", + "hasMore" + ], + "type": "object" + } + }, + "required": [ + "items", + "page", + "completeness" + ], + "type": "object" +}
- Changed
shadowgraph_record_attempt11 fields changed- changed
Input schema / properties / actor / descriptionPrevious value: -"Who performed this write, e.g. an agent name."New value: +"Who performed this write, such as an agent or person name. Stored for audit; never used to grant trust." - changed
Input schema / properties / client / descriptionPrevious value: -"Which client performed this write."New value: +"Which client software performed this write, such as the host application name." - added
Input schema / properties / environment / descriptionAdded value: +"Where it was tried, such as a runtime, OS, or version. Searchable content, so a later attempt can be matched to the same environment." - changed
Input schema / properties / idempotencyKey / descriptionPrevious value: -"Retry key scoped by project and operation; reuse only for the same logical write."New value: +"Retry key scoped by project and operation: reuse it so a retry returns the first result instead of writing a duplicate. Without it every call creates a new entity." - added
Input schema / properties / project / descriptionAdded value: +"Project namespace. Defaults to \"default\"; an empty string is rejected." - added
Input schema / properties / reason / descriptionAdded value: +"Why it turned out that way. Searchable content." - added
Input schema / properties / result / descriptionAdded value: +"What happened. Required, non-empty, and searchable content. Wording such as failed, error, or regression is what makes the attempt surface in shadowgraph_context as one to avoid." - changed
Input schema / properties / sessionId / descriptionPrevious value: -"Session identifier for this write."New value: +"Caller-owned identifier that groups related writes in the audit trail." - added
Input schema / properties / solution / descriptionAdded value: +"What was tried. Required, non-empty, and searchable content." - changed
Input schema / properties / sourceClass / descriptionPrevious value: -"Claimed origin class. A claim, not proof: no value here can make a fact verified."New value: +"Claimed origin, never proof: agent_claimed (the default), tool_observed, human_confirmed, or production_verified. It weights confidence only. An unrecognised label downgrades to agent_claimed, kept verbatim in sourceRaw." - changed
Output schema / (root)Previous value: -nullNew value: +{ + "description": "A stored attempt and its result.", + "properties": { + "actor": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "description": "Who performed the write." + }, + "client": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "description": "Which client performed the write." + }, + "createdAt": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "description": "ISO 8601 creation time." + }, + "environment": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "description": "Where it was tried." + }, + "id": { + "description": "Stable entity identifier.", + "type": "string" + }, + "kind": { + "description": "Entity kind: decision, attempt, memory, fact, relation, review, or alternative.", + "type": "string" + }, + "project": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "description": "Project namespace; records imported from a schema that predates projects may carry null." + }, + "reason": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "description": "Why it turned out that way." + }, + "relatedTo": { + "description": "Identifiers of related entities.", + "type": "array" + }, + "result": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "description": "What happened." + }, + "reusableWhen": { + "description": "Conditions under which the attempt is worth repeating.", + "type": "array" + }, + "schemaVersion": { + "description": "Storage schema version this entity was written under. A value above the build’s own version is preserved rather than downgraded.", + "type": "integer" + }, + "sessionId": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "description": "Session identifier recorded with the write." + }, + "solution": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "description": "What was tried." + }, + "sourceClass": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "description": "Claimed origin class recorded with the write. A claim, never proof." + }, + "sourceRaw": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "description": "The original origin label when it differed from sourceClass. Audit only; never evidence." + }, + "updatedAt": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "description": "ISO 8601 time of the last change." + } + }, + "required": [ + "id", + "kind" + ], + "type": "object" +}
- Changed
shadowgraph_record_decision20 fields changed- changed
Input schema / properties / actor / descriptionPrevious value: -"Who performed this write, e.g. an agent name."New value: +"Who performed this write, such as an agent or person name. Stored for audit; never used to grant trust." - added
Input schema / properties / alternatives / descriptionAdded value: +"Options considered and rejected. Alternatives belong to the decision and have no separate write API; they are what shadowgraph_review reconsiders." - added
Input schema / properties / alternatives / items / properties / label / descriptionAdded value: +"Name of the rejected option. Required in practice: an alternative without a non-empty label is rejected." - added
Input schema / properties / alternatives / items / properties / reason / descriptionAdded value: +"Accepted as an alias of reasonRejected for older callers." - added
Input schema / properties / alternatives / items / properties / reasonRejected / descriptionAdded value: +"Why it was rejected. Searchable content." - added
Input schema / properties / alternatives / items / properties / reopenWhen / descriptionAdded value: +"Rules that make this alternative worth reconsidering. Each is either a fact key as a plain string, matched only against changedFacts, or an object { key, operator, value } evaluated against stored facts so it still fires after a restart. operator defaults to equals." - added
Input schema / properties / assumptions / descriptionAdded value: +"What the decision takes for granted. Record each as a fact too if it should be able to reopen the decision." - added
Input schema / properties / chosen / descriptionAdded value: +"The option actually chosen. Required, non-empty, and searchable content." - changed
Input schema / properties / client / descriptionPrevious value: -"Which client performed this write."New value: +"Which client software performed this write, such as the host application name." - added
Input schema / properties / confidence / descriptionAdded value: +"Starting confidence, 0-1. Defaults to 0.5. Later outcomes and evidence move it from this baseline; it is a degree of belief, never a verification status." - added
Input schema / properties / evidence / descriptionAdded value: +"Supporting evidence. Counted as declared evidence in the confidence basis, but never re-checked." - changed
Input schema / properties / evidence / items / anyOfPrevious value: -[ - { - "type": "string" - }, - { - "additionalProperties": true, - "properties": { - "confidence": { - "maximum": 1, - "minimum": 0, - "type": "number" - }, - "detail": { - "type": "string" - }, - "observedAt": { - "type": "string" - }, - "source": { - "type": "string" - }, - "sourceClass": { - "enum": [ - "agent_claimed", - "tool_observed", - "human_confirmed", - "production_verified" - ], - "type": "string" - }, - "type": { - "type": "string" - } - }, - "type": "object" - } -]New value: +[ + { + "type": "string" + }, + { + "additionalProperties": true, + "properties": { + "confidence": { + "description": "How much weight the caller places on this item, 0-1. Defaults to 0.5.", + "maximum": 1, + "minimum": 0, + "type": "number" + }, + "detail": { + "description": "Free-text detail. Searchable content.", + "type": "string" + }, + "observedAt": { + "description": "ISO 8601 timestamp of the observation. Defaults to the time of the write.", + "type": "string" + }, + "source": { + "description": "Where the evidence came from, such as a document, ticket, or command. Searchable content.", + "type": "string" + }, + "sourceClass": { + "description": "Claimed origin class for this item; an unrecognised value downgrades to agent_claimed.", + "enum": [ + "agent_claimed", + "tool_observed", + "human_confirmed", + "production_verified" + ], + "type": "string" + }, + "type": { + "description": "Free-form evidence kind, such as benchmark, incident, or review.", + "type": "string" + } + }, + "type": "object" + } +] - added
Input schema / properties / evidence / items / descriptionAdded value: +"One piece of supporting evidence. A plain string is stored as its source; an object carries structured provenance. Nothing here is checked or re-verified: it records what the caller claimed." - added
Input schema / properties / goal / descriptionAdded value: +"What the decision is meant to achieve. Searchable content." - changed
Input schema / properties / idempotencyKey / descriptionPrevious value: -"Retry key scoped by project and operation; reuse only for the same logical write."New value: +"Retry key scoped by project and operation: reuse it so a retry returns the first result instead of writing a duplicate. Without it every call creates a new entity." - added
Input schema / properties / project / descriptionAdded value: +"Project namespace. Defaults to \"default\"; an empty string is rejected." - changed
Input schema / properties / sessionId / descriptionPrevious value: -"Session identifier for this write."New value: +"Caller-owned identifier that groups related writes in the audit trail." - changed
Input schema / properties / sourceClass / descriptionPrevious value: -"Claimed origin class. A claim, not proof: no value here can make a fact verified."New value: +"Claimed origin, never proof: agent_claimed (the default), tool_observed, human_confirmed, or production_verified. It weights confidence only. An unrecognised label downgrades to agent_claimed, kept verbatim in sourceRaw." - added
Input schema / properties / title / descriptionAdded value: +"Short name of the decision. Required, non-empty, and searchable content." - changed
Output schema / (root)Previous value: -nullNew value: +{ + "description": "A stored decision, including its alternatives and auditable confidence basis.", + "properties": { + "actor": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "description": "Who performed the write." + }, + "alternatives": { + "description": "Rejected alternatives, each with id, label, reasonRejected, status, and the reopenWhen rules that make it reconsiderable.", + "type": "array" + }, + "assumptions": { + "description": "Assumptions the decision rests on. Searchable content.", + "items": { + "type": "string" + }, + "type": "array" + }, + "chosen": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "description": "The option that was chosen." + }, + "client": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "description": "Which client performed the write." + }, + "confidence": { + "description": "Auditable confidence: initial, current (0-1), policy, a history entry per move, and a basis summarising the contributions it was folded from. Legacy records may lack basis.", + "type": "object" + }, + "createdAt": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "description": "ISO 8601 creation time." + }, + "evidence": { + "description": "Normalised evidence entries: source, type, sourceClass, confidence, observedAt, detail.", + "type": "array" + }, + "failedAttempts": { + "description": "Attempt identifiers or notes attached to this decision.", + "type": "array" + }, + "goal": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "description": "What the decision was trying to achieve." + }, + "id": { + "description": "Stable entity identifier.", + "type": "string" + }, + "kind": { + "description": "Entity kind: decision, attempt, memory, fact, relation, review, or alternative.", + "type": "string" + }, + "migration": { + "description": "Present only on migrated records; records the legacy value a field was mapped from.", + "type": "object" + }, + "outcome": { + "anyOf": [ + { + "type": "object" + }, + { + "type": "null" + } + ], + "description": "The recorded outcome, or null until one is recorded." + }, + "project": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "description": "Project namespace; records imported from a schema that predates projects may carry null." + }, + "reviewAfter": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "description": "ISO 8601 instant after which shadowgraph_maintain marks this decision stale." + }, + "schemaVersion": { + "description": "Storage schema version this entity was written under. A value above the build’s own version is preserved rather than downgraded.", + "type": "integer" + }, + "sessionId": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "description": "Session identifier recorded with the write." + }, + "sourceClass": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "description": "Claimed origin class recorded with the write. A claim, never proof." + }, + "sourceRaw": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "description": "The original origin label when it differed from sourceClass. Audit only; never evidence." + }, + "status": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "description": "Lifecycle state. Legacy records may carry a value this build does not recognise; shadowgraph_validate reports those." + }, + "supersededBy": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "description": "Identifier of the decision that replaced this one." + }, + "supersedes": { + "description": "Identifiers of decisions this one replaced.", + "type": "array" + }, + "title": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "description": "Short name of the decision." + }, + "updatedAt": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "description": "ISO 8601 time of the last change." + } + }, + "required": [ + "id", + "kind" + ], + "type": "object" +}
- Changed
shadowgraph_record_fact12 fields changed- changed
Input schema / properties / actor / descriptionPrevious value: -"Who performed this write, e.g. an agent name."New value: +"Who performed this write, such as an agent or person name. Stored for audit; never used to grant trust." - changed
Input schema / properties / client / descriptionPrevious value: -"Which client performed this write."New value: +"Which client software performed this write, such as the host application name." - added
Input schema / properties / confidence / descriptionAdded value: +"How much the caller trusts this observation, 0-1. Defaults to 0.5. It does not verify anything." - added
Input schema / properties / expiresAt / descriptionAdded value: +"ISO 8601 instant after which shadowgraph_maintain expires this fact. Combined with validTo, the earlier boundary wins." - changed
Input schema / properties / idempotencyKey / descriptionPrevious value: -"Retry key scoped by project and operation; reuse only for the same logical write."New value: +"Retry key scoped by project and operation: reuse it so a retry returns the first result instead of writing a duplicate. Without it every call creates a new entity." - added
Input schema / properties / key / descriptionAdded value: +"Fact name, unique per project among active facts. Required and non-empty. Use the same key that a decision’s reopenWhen rules refer to." - added
Input schema / properties / project / descriptionAdded value: +"Project namespace. Defaults to \"default\"; an empty string is rejected." - changed
Input schema / properties / sessionId / descriptionPrevious value: -"Session identifier for this write."New value: +"Caller-owned identifier that groups related writes in the audit trail." - changed
Input schema / properties / source / descriptionPrevious value: -"Legacy alias for sourceClass. Unknown labels downgrade to agent_claimed with the raw label kept in sourceRaw."New value: +"Legacy alias for sourceClass. An unknown label downgrades to agent_claimed with the raw label kept in sourceRaw." - changed
Input schema / properties / sourceClass / descriptionPrevious value: -"Claimed origin class. A claim, not proof: no value here can make a fact verified."New value: +"Claimed origin, never proof: agent_claimed (the default), tool_observed, human_confirmed, or production_verified. It weights confidence only. An unrecognised label downgrades to agent_claimed, kept verbatim in sourceRaw." - changed
Input schema / properties / verificationStatus / descriptionPrevious value: -"Only `contradicted` may be set by a caller; `verified` and `expired` are rejected."New value: +"Only \"contradicted\" may be set by a caller, because it lowers trust. \"verified\" and \"expired\" are rejected: verification is not self-assertable and expiry is owned by shadowgraph_maintain." - changed
Output schema / (root)Previous value: -nullNew value: +{ + "description": "A stored fact with its provenance claim and validity window.", + "properties": { + "actor": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "description": "Who performed the write." + }, + "client": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "description": "Which client performed the write." + }, + "confidence": { + "anyOf": [ + { + "type": "number" + }, + { + "type": "null" + } + ], + "description": "Caller-declared confidence in the observation, 0-1." + }, + "createdAt": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "description": "ISO 8601 creation time." + }, + "expiresAt": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "description": "Caller-declared expiry instant, or null." + }, + "id": { + "description": "Stable entity identifier.", + "type": "string" + }, + "key": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "description": "Fact name, unique per project among active facts." + }, + "kind": { + "description": "Entity kind: decision, attempt, memory, fact, relation, review, or alternative.", + "type": "string" + }, + "observedAt": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "description": "ISO 8601 time the fact was observed." + }, + "project": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "description": "Project namespace; records imported from a schema that predates projects may carry null." + }, + "schemaVersion": { + "description": "Storage schema version this entity was written under. A value above the build’s own version is preserved rather than downgraded.", + "type": "integer" + }, + "sessionId": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "description": "Session identifier recorded with the write." + }, + "source": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "description": "Legacy alias of sourceClass, retained for compatibility." + }, + "sourceClass": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "description": "Claimed origin class recorded with the write. A claim, never proof." + }, + "sourceRaw": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "description": "The original origin label when it differed from sourceClass. Audit only; never evidence." + }, + "status": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "description": "active, superseded, or expired." + }, + "temporal": { + "description": "Bi-temporal window: validFrom, validTo, recordedAt, invalidatedAt.", + "type": "object" + }, + "updatedAt": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "description": "ISO 8601 time of the last change." + }, + "validityPolicy": { + "description": "Declared expiry inputs and the effective expiration boundary derived from them.", + "type": "object" + }, + "value": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + }, + { + "type": "null" + }, + { + "type": "array" + }, + { + "type": "object" + } + ], + "description": "The observed value, any lossless JSON value." + }, + "verification": { + "description": "Present only on a signed verification: the attestation this build checked.", + "type": "object" + }, + "verificationStatus": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "description": "unverified, contradicted, expired, or verified. Only the separately configured signed-evidence verifier can produce verified." + } + }, + "required": [ + "key" + ], + "type": "object" +}
- Changed
shadowgraph_record_outcome7 fields changed- added
Input schema / properties / decisionId / descriptionAdded value: +"Identifier of an existing decision, as returned by shadowgraph_record_decision, shadowgraph_search, or shadowgraph_retrieve." - added
Input schema / properties / outcome / descriptionAdded value: +"The outcome to record." - added
Input schema / properties / outcome / properties / lessons / descriptionAdded value: +"What was learned, stored with the outcome." - added
Input schema / properties / outcome / properties / observedAt / descriptionAdded value: +"ISO 8601 time the outcome was observed. Defaults to now." - added
Input schema / properties / outcome / properties / sourceClass / descriptionAdded value: +"Claimed origin of this outcome observation. It weights how far confidence moves; it never verifies anything." - added
Input schema / properties / outcome / properties / status / descriptionAdded value: +"successful raises confidence, failed lowers it and makes the decision due for review, mixed lowers it by half, and unknown moves nothing because \"we do not know\" is not evidence." - changed
Output schema / (root)Previous value: -nullNew value: +{ + "description": "A stored decision, including its alternatives and auditable confidence basis.", + "properties": { + "actor": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "description": "Who performed the write." + }, + "alternatives": { + "description": "Rejected alternatives, each with id, label, reasonRejected, status, and the reopenWhen rules that make it reconsiderable.", + "type": "array" + }, + "assumptions": { + "description": "Assumptions the decision rests on. Searchable content.", + "items": { + "type": "string" + }, + "type": "array" + }, + "chosen": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "description": "The option that was chosen." + }, + "client": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "description": "Which client performed the write." + }, + "confidence": { + "description": "Auditable confidence: initial, current (0-1), policy, a history entry per move, and a basis summarising the contributions it was folded from. Legacy records may lack basis.", + "type": "object" + }, + "createdAt": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "description": "ISO 8601 creation time." + }, + "evidence": { + "description": "Normalised evidence entries: source, type, sourceClass, confidence, observedAt, detail.", + "type": "array" + }, + "failedAttempts": { + "description": "Attempt identifiers or notes attached to this decision.", + "type": "array" + }, + "goal": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "description": "What the decision was trying to achieve." + }, + "id": { + "description": "Stable entity identifier.", + "type": "string" + }, + "kind": { + "description": "Entity kind: decision, attempt, memory, fact, relation, review, or alternative.", + "type": "string" + }, + "migration": { + "description": "Present only on migrated records; records the legacy value a field was mapped from.", + "type": "object" + }, + "outcome": { + "anyOf": [ + { + "type": "object" + }, + { + "type": "null" + } + ], + "description": "The recorded outcome, or null until one is recorded." + }, + "project": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "description": "Project namespace; records imported from a schema that predates projects may carry null." + }, + "reviewAfter": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "description": "ISO 8601 instant after which shadowgraph_maintain marks this decision stale." + }, + "schemaVersion": { + "description": "Storage schema version this entity was written under. A value above the build’s own version is preserved rather than downgraded.", + "type": "integer" + }, + "sessionId": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "description": "Session identifier recorded with the write." + }, + "sourceClass": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "description": "Claimed origin class recorded with the write. A claim, never proof." + }, + "sourceRaw": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "description": "The original origin label when it differed from sourceClass. Audit only; never evidence." + }, + "status": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "description": "Lifecycle state. Legacy records may carry a value this build does not recognise; shadowgraph_validate reports those." + }, + "supersededBy": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "description": "Identifier of the decision that replaced this one." + }, + "supersedes": { + "description": "Identifiers of decisions this one replaced.", + "type": "array" + }, + "title": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "description": "Short name of the decision." + }, + "updatedAt": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "description": "ISO 8601 time of the last change." + } + }, + "required": [ + "id", + "kind" + ], + "type": "object" +}
- Changed
shadowgraph_redact3 fields changed- added
Input schema / properties / patterns / descriptionAdded value: +"Case-insensitive regular expressions matched against key names, replacing the default set (password, secret, token, api[-_]?key, authorization, private[-_]?key). Supplying this replaces the defaults rather than adding to them; idempotency keys, evidence references, and signatures are always redacted." - added
Input schema / properties / project / descriptionAdded value: +"Limit the export to one project. Omit to redact everything." - changed
Output schema / (root)Previous value: -nullNew value: +{ + "description": "A complete store export.", + "properties": { + "events": { + "description": "Compatibility event log.", + "type": "array" + }, + "facts": { + "description": "Observed facts with their provenance claims.", + "items": { + "description": "A stored fact with its provenance claim and validity window.", + "properties": { + "actor": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "description": "Who performed the write." + }, + "client": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "description": "Which client performed the write." + }, + "confidence": { + "anyOf": [ + { + "type": "number" + }, + { + "type": "null" + } + ], + "description": "Caller-declared confidence in the observation, 0-1." + }, + "createdAt": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "description": "ISO 8601 creation time." + }, + "expiresAt": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "description": "Caller-declared expiry instant, or null." + }, + "id": { + "description": "Stable entity identifier.", + "type": "string" + }, + "key": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "description": "Fact name, unique per project among active facts." + }, + "kind": { + "description": "Entity kind: decision, attempt, memory, fact, relation, review, or alternative.", + "type": "string" + }, + "observedAt": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "description": "ISO 8601 time the fact was observed." + }, + "project": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "description": "Project namespace; records imported from a schema that predates projects may carry null." + }, + "schemaVersion": { + "description": "Storage schema version this entity was written under. A value above the build’s own version is preserved rather than downgraded.", + "type": "integer" + }, + "sessionId": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "description": "Session identifier recorded with the write." + }, + "source": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "description": "Legacy alias of sourceClass, retained for compatibility." + }, + "sourceClass": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "description": "Claimed origin class recorded with the write. A claim, never proof." + }, + "sourceRaw": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "description": "The original origin label when it differed from sourceClass. Audit only; never evidence." + }, + "status": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "description": "active, superseded, or expired." + }, + "temporal": { + "description": "Bi-temporal window: validFrom, validTo, recordedAt, invalidatedAt.", + "type": "object" + }, + "updatedAt": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "description": "ISO 8601 time of the last change." + }, + "validityPolicy": { + "description": "Declared expiry inputs and the effective expiration boundary derived from them.", + "type": "object" + }, + "value": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + }, + { + "type": "null" + }, + { + "type": "array" + }, + { + "type": "object" + } + ], + "description": "The observed value, any lossless JSON value." + }, + "verification": { + "description": "Present only on a signed verification: the attestation this build checked.", + "type": "object" + }, + "verificationStatus": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "description": "unverified, contradicted, expired, or verified. Only the separately configured signed-evidence verifier can produce verified." + } + }, + "required": [ + "key" + ], + "type": "object" + }, + "type": "array" + }, + "idempotency": { + "description": "Retry-key entries, each { key, value }.", + "type": "array" + }, + "journal": { + "description": "The append-oriented journal.", + "items": { + "description": "One journal entry: a complete post-operation snapshot. Entries imported from older schemas may lack seq or payload.", + "properties": { + "at": { + "description": "ISO 8601 time the entry was appended.", + "type": "string" + }, + "causationId": { + "description": "Present only when this entry was caused by another; carries that entry id.", + "type": "string" + }, + "entityId": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "description": "Identifier of that entity; null on a redacted skeleton." + }, + "entityKind": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "description": "Kind of the entity the entry is about." + }, + "id": { + "description": "Entry identifier.", + "type": "string" + }, + "idempotencyKey": { + "description": "Present only when the write carried a retry key.", + "type": "string" + }, + "payload": { + "anyOf": [ + { + "type": "object" + }, + { + "type": "null" + } + ], + "description": "The complete post-operation snapshot, or null once a logical purge reduced the entry to an audit skeleton." + }, + "project": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "description": "Project the entry belongs to." + }, + "provenance": { + "description": "actor, client, and sessionId recorded with the write; all null on purged skeletons.", + "type": "object" + }, + "redacted": { + "description": "Present only on entries reduced by a logical purge.", + "type": "boolean" + }, + "redactedReason": { + "description": "Why the entry was reduced.", + "type": "string" + }, + "schemaVersion": { + "description": "Schema version the entry was written under.", + "type": "integer" + }, + "seq": { + "description": "Monotonic sequence number. Absent on pre-journal metadata entries.", + "type": "integer" + }, + "transition": { + "description": "Present only on lifecycle changes; carries from, to, and the actor that made them.", + "type": "object" + }, + "type": { + "description": "Entry type, such as decision.recorded, fact.observed, memory.superseded, or project.purged.", + "type": "string" + } + }, + "type": "object" + }, + "type": "array" + }, + "journalEpoch": { + "anyOf": [ + { + "type": "integer" + }, + { + "type": "null" + } + ], + "description": "First replayable sequence, or null when nothing is replayable." + }, + "journalSeq": { + "description": "Highest journal sequence issued.", + "type": "integer" + }, + "records": { + "description": "Decisions, attempts, and memories.", + "items": { + "description": "One stored entity: a decision, attempt, memory, fact, or alternative. Fields vary by kind, and an entity imported from an older schema may carry fewer of them.", + "properties": { + "actor": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "description": "Who performed the write." + }, + "client": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "description": "Which client performed the write." + }, + "createdAt": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "description": "ISO 8601 creation time." + }, + "id": { + "description": "Stable entity identifier.", + "type": "string" + }, + "kind": { + "description": "Entity kind: decision, attempt, memory, fact, relation, review, or alternative.", + "type": "string" + }, + "project": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "description": "Project namespace; records imported from a schema that predates projects may carry null." + }, + "schemaVersion": { + "description": "Storage schema version this entity was written under. A value above the build’s own version is preserved rather than downgraded.", + "type": "integer" + }, + "sessionId": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "description": "Session identifier recorded with the write." + }, + "sourceClass": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "description": "Claimed origin class recorded with the write. A claim, never proof." + }, + "sourceRaw": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "description": "The original origin label when it differed from sourceClass. Audit only; never evidence." + }, + "updatedAt": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "description": "ISO 8601 time of the last change." + } + }, + "type": "object" + }, + "type": "array" + }, + "relations": { + "description": "Relationships.", + "items": { + "description": "A stored relationship between two entities.", + "properties": { + "actor": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "description": "Who performed the write." + }, + "client": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "description": "Which client performed the write." + }, + "createdAt": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "description": "ISO 8601 creation time." + }, + "from": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "description": "Source entity identifier." + }, + "id": { + "description": "Stable entity identifier.", + "type": "string" + }, + "kind": { + "description": "Entity kind: decision, attempt, memory, fact, relation, review, or alternative.", + "type": "string" + }, + "project": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "description": "Project namespace; records imported from a schema that predates projects may carry null." + }, + "relation": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "description": "Relationship name, such as depends_on or supersedes." + }, + "schemaVersion": { + "description": "Storage schema version this entity was written under. A value above the build’s own version is preserved rather than downgraded.", + "type": "integer" + }, + "sessionId": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "description": "Session identifier recorded with the write." + }, + "sourceClass": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "description": "Claimed origin class recorded with the write. A claim, never proof." + }, + "sourceRaw": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "description": "The original origin label when it differed from sourceClass. Audit only; never evidence." + }, + "temporal": { + "description": "Bi-temporal window for the relationship.", + "type": "object" + }, + "to": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "description": "Target entity identifier." + }, + "updatedAt": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "description": "ISO 8601 time of the last change." + } + }, + "required": [ + "id", + "from", + "to", + "relation" + ], + "type": "object" + }, + "type": "array" + }, + "reviewSignals": { + "description": "Persisted review signals.", + "items": { + "description": "A persisted review signal.", + "properties": { + "acknowledgedAt": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "description": "ISO 8601 time of the most recent acknowledgement." + }, + "alternativesToReconsider": { + "description": "Alternative labels to look at again.", + "items": { + "type": "string" + }, + "type": "array" + }, + "createdAt": { + "description": "ISO 8601 time the signal was raised.", + "type": "string" + }, + "decisionId": { + "description": "The decision this signal is about.", + "type": "string" + }, + "id": { + "description": "Signal identifier, used by shadowgraph_ack_review.", + "type": "string" + }, + "kind": { + "const": "review", + "description": "Always \"review\".", + "type": "string" + }, + "reason": { + "description": "Why the signal was raised. Together with decisionId this is the dedupe identity, so the same cause never raises a second signal.", + "type": "string" + }, + "status": { + "description": "open until acknowledged.", + "enum": [ + "open", + "acknowledged" + ], + "type": "string" + }, + "title": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "description": "Decision title, when the stored decision has one." + } + }, + "required": [ + "id", + "kind", + "decisionId", + "reason", + "alternativesToReconsider", + "status", + "createdAt" + ], + "type": "object" + }, + "type": "array" + }, + "revision": { + "description": "Concurrency token of the state this export was taken from.", + "type": "integer" + }, + "schemaVersion": { + "description": "Storage schema version of this export.", + "type": "integer" + } + }, + "required": [ + "schemaVersion", + "revision", + "records", + "facts", + "relations", + "reviewSignals", + "idempotency", + "events", + "journal", + "journalSeq", + "journalEpoch" + ], + "type": "object" +}
- Changed
shadowgraph_remember32 fields changed- changed
Input schema / properties / actor / descriptionPrevious value: -"Who performed this write, e.g. an agent name."New value: +"Who performed this write, such as an agent or person name. Stored for audit; never used to grant trust." - changed
Input schema / properties / client / descriptionPrevious value: -"Which client performed this write."New value: +"Which client software performed this write, such as the host application name." - changed
Input schema / properties / embedding / descriptionPrevious value: -"Optional caller-supplied vector. When omitted, the configured embedding provider is used."New value: +"Caller-supplied vector for this text. Omit to use the configured embedding provider; with no provider the record is still stored and recall reports semantic.available=false instead of renaming lexical overlap as semantic." - added
Input schema / properties / key / descriptionAdded value: +"Stable caller-chosen name within this scope and type, such as hotel-style. Reusing it reconciles that memory rather than adding a second one." - added
Input schema / properties / memoryType / descriptionAdded value: +"Which kind of memory this is, and part of its identity. preference and profile are durable user facts, goal a desired state, instruction an operating constraint, procedure reusable steps, episode a recallable event, note general knowledge." - added
Input schema / properties / metadata / descriptionAdded value: +"Caller-owned JSON object kept with the memory. Part of the compared content, so changing it produces a new version." - added
Input schema / properties / operations / descriptionAdded value: +"A batch plan. Supply this instead of a single memory, typically from an extraction step. Every operation is validated before the first one is applied, so a malformed late operation cannot leave a half-applied batch." - added
Input schema / properties / operations / items / properties / action / descriptionAdded value: +"ADD and UPDATE both reconcile against the current memory and require text; DELETE invalidates the current one, keeping history; NOOP records that nothing should change." - changed
Input schema / properties / operations / items / properties / embedding / descriptionPrevious value: -"Optional caller-supplied vector. When omitted, the configured embedding provider is used."New value: +"Caller-supplied vector for this text. Omit to use the configured embedding provider; with no provider the record is still stored and recall reports semantic.available=false instead of renaming lexical overlap as semantic." - added
Input schema / properties / operations / items / properties / key / descriptionAdded value: +"Stable caller-chosen name within this scope and type, such as hotel-style. Reusing it reconciles that memory rather than adding a second one." - added
Input schema / properties / operations / items / properties / memoryType / descriptionAdded value: +"Which kind of memory this is, and part of its identity. preference and profile are durable user facts, goal a desired state, instruction an operating constraint, procedure reusable steps, episode a recallable event, note general knowledge." - added
Input schema / properties / operations / items / properties / metadata / descriptionAdded value: +"Caller-owned JSON object kept with the memory. Part of the compared content, so changing it produces a new version." - added
Input schema / properties / operations / items / properties / scope / descriptionAdded value: +"Scope selector. Omitted or partial fields mean explicit nulls, not \"any\": identity is the exact (project, userId, agentId, runId, memoryType, key) tuple, so a run-scoped memory never leaks into a user-only read." - added
Input schema / properties / operations / items / properties / scope / properties / agentId / descriptionAdded value: +"Agent this memory belongs to, or null for none." - added
Input schema / properties / operations / items / properties / scope / properties / runId / descriptionAdded value: +"Single run or task this memory belongs to, or null for none." - added
Input schema / properties / operations / items / properties / scope / properties / userId / descriptionAdded value: +"Person this memory belongs to, or null for none." - added
Input schema / properties / operations / items / properties / tags / descriptionAdded value: +"Free-form labels stored with the memory. Part of the compared content, so changing them produces a new version." - added
Input schema / properties / operations / items / properties / text / descriptionAdded value: +"The memory content itself. Stored verbatim, searched as content, and compared to decide ADD, UPDATE, or NOOP." - added
Input schema / properties / operations / items / properties / validFrom / descriptionAdded value: +"ISO 8601 instant from which this memory is true in the modeled world. Defaults to the write time. Writes for one identity must arrive in non-decreasing validFrom order." - added
Input schema / properties / operations / items / properties / validTo / descriptionAdded value: +"ISO 8601 instant after which it stops being true, or null for open-ended. Must be later than validFrom." - added
Input schema / properties / project / descriptionAdded value: +"Project namespace. Defaults to \"default\"; an empty string is rejected." - added
Input schema / properties / scope / descriptionAdded value: +"Scope selector. Omitted or partial fields mean explicit nulls, not \"any\": identity is the exact (project, userId, agentId, runId, memoryType, key) tuple, so a run-scoped memory never leaks into a user-only read." - added
Input schema / properties / scope / properties / agentId / descriptionAdded value: +"Agent this memory belongs to, or null for none." - added
Input schema / properties / scope / properties / runId / descriptionAdded value: +"Single run or task this memory belongs to, or null for none." - added
Input schema / properties / scope / properties / userId / descriptionAdded value: +"Person this memory belongs to, or null for none." - changed
Input schema / properties / sessionId / descriptionPrevious value: -"Session identifier for this write."New value: +"Caller-owned identifier that groups related writes in the audit trail." - changed
Input schema / properties / sourceClass / descriptionPrevious value: -"Claimed origin class. A claim, not proof: no value here can make a fact verified."New value: +"Claimed origin, never proof: agent_claimed (the default), tool_observed, human_confirmed, or production_verified. It weights confidence only. An unrecognised label downgrades to agent_claimed, kept verbatim in sourceRaw." - added
Input schema / properties / tags / descriptionAdded value: +"Free-form labels stored with the memory. Part of the compared content, so changing them produces a new version." - added
Input schema / properties / text / descriptionAdded value: +"The memory content itself. Stored verbatim, searched as content, and compared to decide ADD, UPDATE, or NOOP." - added
Input schema / properties / validFrom / descriptionAdded value: +"ISO 8601 instant from which this memory is true in the modeled world. Defaults to the write time. Writes for one identity must arrive in non-decreasing validFrom order." - added
Input schema / properties / validTo / descriptionAdded value: +"ISO 8601 instant after which it stops being true, or null for open-ended. Must be later than validFrom." - changed
Output schema / (root)Previous value: -nullNew value: +{ + "anyOf": [ + { + "properties": { + "indexUpdated": { + "description": "Present when identical content arrived with a different embedding: the index was refreshed without minting a new version.", + "type": "boolean" + }, + "memory": { + "description": "A stored scoped memory version.", + "properties": { + "actor": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "description": "Who performed the write." + }, + "client": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "description": "Which client performed the write." + }, + "createdAt": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "description": "ISO 8601 creation time." + }, + "embedding": { + "anyOf": [ + { + "type": "array" + }, + { + "type": "object" + }, + { + "type": "null" + } + ], + "description": "The stored vector, or null when none was supplied and no provider was configured." + }, + "id": { + "description": "Stable entity identifier.", + "type": "string" + }, + "key": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "description": "Caller-chosen name within the scope and type." + }, + "kind": { + "description": "Entity kind: decision, attempt, memory, fact, relation, review, or alternative.", + "type": "string" + }, + "memoryType": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "description": "preference, profile, goal, instruction, procedure, episode, or note." + }, + "metadata": { + "description": "Caller-owned JSON stored with the memory.", + "type": "object" + }, + "project": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "description": "Project namespace; records imported from a schema that predates projects may carry null." + }, + "schemaVersion": { + "description": "Storage schema version this entity was written under. A value above the build’s own version is preserved rather than downgraded.", + "type": "integer" + }, + "scope": { + "description": "The userId, agentId, and runId this memory is scoped to; each is a string or null.", + "type": "object" + }, + "sessionId": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "description": "Session identifier recorded with the write." + }, + "sourceClass": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "description": "Claimed origin class recorded with the write. A claim, never proof." + }, + "sourceRaw": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "description": "The original origin label when it differed from sourceClass. Audit only; never evidence." + }, + "status": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "description": "active, superseded, or invalidated." + }, + "supersededBy": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "description": "Identifier of the version that replaced this one." + }, + "supersedes": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "description": "Identifier of the version this one replaced." + }, + "tags": { + "description": "Labels stored with the memory.", + "type": "array" + }, + "temporal": { + "description": "Bi-temporal window: validFrom, validTo, recordedAt, invalidatedAt.", + "type": "object" + }, + "text": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "description": "The memory content." + }, + "updatedAt": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "description": "ISO 8601 time of the last change." + }, + "verificationStatus": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "description": "Always unverified for memories." + }, + "version": { + "anyOf": [ + { + "type": "integer" + }, + { + "type": "null" + } + ], + "description": "Version number within this identity, incrementing on each superseding write." + } + }, + "required": [ + "id", + "kind" + ], + "type": "object" + }, + "operation": { + "description": "ADD when no active memory existed, UPDATE when one was superseded, NOOP when content was identical.", + "enum": [ + "ADD", + "UPDATE", + "NOOP" + ], + "type": "string" + }, + "previous": { + "description": "A stored scoped memory version.", + "properties": { + "actor": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "description": "Who performed the write." + }, + "client": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "description": "Which client performed the write." + }, + "createdAt": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "description": "ISO 8601 creation time." + }, + "embedding": { + "anyOf": [ + { + "type": "array" + }, + { + "type": "object" + }, + { + "type": "null" + } + ], + "description": "The stored vector, or null when none was supplied and no provider was configured." + }, + "id": { + "description": "Stable entity identifier.", + "type": "string" + }, + "key": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "description": "Caller-chosen name within the scope and type." + }, + "kind": { + "description": "Entity kind: decision, attempt, memory, fact, relation, review, or alternative.", + "type": "string" + }, + "memoryType": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "description": "preference, profile, goal, instruction, procedure, episode, or note." + }, + "metadata": { + "description": "Caller-owned JSON stored with the memory.", + "type": "object" + }, + "project": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "description": "Project namespace; records imported from a schema that predates projects may carry null." + }, + "schemaVersion": { + "description": "Storage schema version this entity was written under. A value above the build’s own version is preserved rather than downgraded.", + "type": "integer" + }, + "scope": { + "description": "The userId, agentId, and runId this memory is scoped to; each is a string or null.", + "type": "object" + }, + "sessionId": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "description": "Session identifier recorded with the write." + }, + "sourceClass": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "description": "Claimed origin class recorded with the write. A claim, never proof." + }, + "sourceRaw": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "description": "The original origin label when it differed from sourceClass. Audit only; never evidence." + }, + "status": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "description": "active, superseded, or invalidated." + }, + "supersededBy": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "description": "Identifier of the version that replaced this one." + }, + "supersedes": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "description": "Identifier of the version this one replaced." + }, + "tags": { + "description": "Labels stored with the memory.", + "type": "array" + }, + "temporal": { + "description": "Bi-temporal window: validFrom, validTo, recordedAt, invalidatedAt.", + "type": "object" + }, + "text": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "description": "The memory content." + }, + "updatedAt": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "description": "ISO 8601 time of the last change." + }, + "verificationStatus": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "description": "Always unverified for memories." + }, + "version": { + "anyOf": [ + { + "type": "integer" + }, + { + "type": "null" + } + ], + "description": "Version number within this identity, incrementing on each superseding write." + } + }, + "required": [ + "id", + "kind" + ], + "type": "object" + } + }, + "required": [ + "operation", + "memory" + ], + "type": "object" + }, + { + "properties": { + "completeness": { + "description": "Plan accounting. This is not the paginated completeness envelope.", + "properties": { + "applied": { + "description": "Results produced, one per submitted operation.", + "minimum": 0, + "type": "integer" + }, + "complete": { + "description": "Always true: a plan is applied in full or rejected in full.", + "type": "boolean" + }, + "requested": { + "description": "Operations submitted.", + "minimum": 0, + "type": "integer" + } + }, + "required": [ + "complete", + "requested", + "applied" + ], + "type": "object" + }, + "results": { + "description": "One result per submitted operation, in order.", + "items": { + "properties": { + "indexUpdated": { + "description": "Present when only the embedding was refreshed.", + "type": "boolean" + }, + "memory": { + "anyOf": [ + { + "description": "A stored scoped memory version.", + "properties": { + "actor": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "description": "Who performed the write." + }, + "client": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "description": "Which client performed the write." + }, + "createdAt": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "description": "ISO 8601 creation time." + }, + "embedding": { + "anyOf": [ + { + "type": "array" + }, + { + "type": "object" + }, + { + "type": "null" + } + ], + "description": "The stored vector, or null when none was supplied and no provider was configured." + }, + "id": { + "description": "Stable entity identifier.", + "type": "string" + }, + "key": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "description": "Caller-chosen name within the scope and type." + }, + "kind": { + "description": "Entity kind: decision, attempt, memory, fact, relation, review, or alternative.", + "type": "string" + }, + "memoryType": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "description": "preference, profile, goal, instruction, procedure, episode, or note." + }, + "metadata": { + "description": "Caller-owned JSON stored with the memory.", + "type": "object" + }, + "project": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "description": "Project namespace; records imported from a schema that predates projects may carry null." + }, + "schemaVersion": { + "description": "Storage schema version this entity was written under. A value above the build’s own version is preserved rather than downgraded.", + "type": "integer" + }, + "scope": { + "description": "The userId, agentId, and runId this memory is scoped to; each is a string or null.", + "type": "object" + }, + "sessionId": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "description": "Session identifier recorded with the write." + }, + "sourceClass": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "description": "Claimed origin class recorded with the write. A claim, never proof." + }, + "sourceRaw": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "description": "The original origin label when it differed from sourceClass. Audit only; never evidence." + }, + "status": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "description": "active, superseded, or invalidated." + }, + "supersededBy": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "description": "Identifier of the version that replaced this one." + }, + "supersedes": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "description": "Identifier of the version this one replaced." + }, + "tags": { + "description": "Labels stored with the memory.", + "type": "array" + }, + "temporal": { + "description": "Bi-temporal window: validFrom, validTo, recordedAt, invalidatedAt.", + "type": "object" + }, + "text": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "description": "The memory content." + }, + "updatedAt": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "description": "ISO 8601 time of the last change." + }, + "verificationStatus": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "description": "Always unverified for memories." + }, + "version": { + "anyOf": [ + { + "type": "integer" + }, + { + "type": "null" + } + ], + "description": "Version number within this identity, incrementing on each superseding write." + } + }, + "required": [ + "id", + "kind" + ], + "type": "object" + }, + { + "type": "null" + } + ], + "description": "The resulting memory, or null for a NOOP on an identity that has no memory." + }, + "operation": { + "description": "What was actually applied, which may differ from the requested action when content already matched.", + "enum": [ + "ADD", + "UPDATE", + "DELETE", + "NOOP" + ], + "type": "string" + }, + "previous": { + "description": "A stored scoped memory version.", + "properties": { + "actor": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "description": "Who performed the write." + }, + "client": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "description": "Which client performed the write." + }, + "createdAt": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "description": "ISO 8601 creation time." + }, + "embedding": { + "anyOf": [ + { + "type": "array" + }, + { + "type": "object" + }, + { + "type": "null" + } + ], + "description": "The stored vector, or null when none was supplied and no provider was configured." + }, + "id": { + "description": "Stable entity identifier.", + "type": "string" + }, + "key": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "description": "Caller-chosen name within the scope and type." + }, + "kind": { + "description": "Entity kind: decision, attempt, memory, fact, relation, review, or alternative.", + "type": "string" + }, + "memoryType": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "description": "preference, profile, goal, instruction, procedure, episode, or note." + }, + "metadata": { + "description": "Caller-owned JSON stored with the memory.", + "type": "object" + }, + "project": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "description": "Project namespace; records imported from a schema that predates projects may carry null." + }, + "schemaVersion": { + "description": "Storage schema version this entity was written under. A value above the build’s own version is preserved rather than downgraded.", + "type": "integer" + }, + "scope": { + "description": "The userId, agentId, and runId this memory is scoped to; each is a string or null.", + "type": "object" + }, + "sessionId": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "description": "Session identifier recorded with the write." + }, + "sourceClass": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "description": "Claimed origin class recorded with the write. A claim, never proof." + }, + "sourceRaw": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "description": "The original origin label when it differed from sourceClass. Audit only; never evidence." + }, + "status": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "description": "active, superseded, or invalidated." + }, + "supersededBy": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "description": "Identifier of the version that replaced this one." + }, + "supersedes": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "description": "Identifier of the version this one replaced." + }, + "tags": { + "description": "Labels stored with the memory.", + "type": "array" + }, + "temporal": { + "description": "Bi-temporal window: validFrom, validTo, recordedAt, invalidatedAt.", + "type": "object" + }, + "text": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "description": "The memory content." + }, + "updatedAt": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "description": "ISO 8601 time of the last change." + }, + "verificationStatus": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "description": "Always unverified for memories." + }, + "version": { + "anyOf": [ + { + "type": "integer" + }, + { + "type": "null" + } + ], + "description": "Version number within this identity, incrementing on each superseding write." + } + }, + "required": [ + "id", + "kind" + ], + "type": "object" + } + }, + "required": [ + "operation", + "memory" + ], + "type": "object" + }, + "type": "array" + } + }, + "required": [ + "results", + "completeness" + ], + "type": "object" + } + ], + "description": "Either the outcome of one reconciliation, or the outcome of a plan.", + "type": "object" +}
- Changed
shadowgraph_repair_plan1 field changed- changed
Output schema / (root)Previous value: -nullNew value: +{ + "description": "A plan that is never applied automatically.", + "properties": { + "actions": { + "description": "One action per diagnostic.", + "items": { + "properties": { + "action": { + "description": "remove_relation for a relationship whose endpoint is missing; manual_review for everything else.", + "enum": [ + "remove_relation", + "manual_review" + ], + "type": "string" + }, + "code": { + "description": "The diagnostic code, on a manual_review action.", + "type": "string" + }, + "reason": { + "description": "The diagnostic code that justified a remove_relation action.", + "type": "string" + }, + "relationId": { + "description": "Relationship to remove, on a remove_relation action.", + "type": "string" + }, + "severity": { + "description": "The diagnostic severity, on a manual_review action.", + "type": "string" + } + }, + "required": [ + "action" + ], + "type": "object" + }, + "type": "array" + }, + "apply": { + "const": false, + "description": "Always false: this tool proposes, it never repairs.", + "type": "boolean" + } + }, + "required": [ + "apply", + "actions" + ], + "type": "object" +}
- Changed
shadowgraph_restore2 fields changed- added
Input schema / properties / source / descriptionAdded value: +"Server-side path of the backup to install. Required. It must match the configured storage backend: a JSON export cannot overwrite a SQLite database. The backup file itself is never rewritten." - changed
Output schema / (root)Previous value: -nullNew value: +{ + "description": "What was restored from where. Fields beyond source and destination depend on the storage backend and on whether cleanup was confirmed.", + "properties": { + "artifactCleanup": { + "description": "Cleanup outcome: status complete, incomplete, or unknown, plus any per-path errors.", + "type": "object" + }, + "destination": { + "description": "Path of the store that was replaced.", + "type": "string" + }, + "records": { + "description": "Records installed. JSON restores only.", + "type": "integer" + }, + "recoveryArtifact": { + "description": "Retained recovery copy, when one is left behind.", + "type": "string" + }, + "retainedArtifacts": { + "description": "Rollback or recovery files still present after the restore.", + "items": { + "type": "string" + }, + "type": "array" + }, + "rollbackArtifact": { + "description": "Retained rollback copy of the previous store, when one is left behind.", + "type": "string" + }, + "source": { + "description": "Path the backup was read from.", + "type": "string" + }, + "temporaryArtifact": { + "description": "Retained temporary file, when one is left behind.", + "type": "string" + }, + "unchanged": { + "description": "True when source and destination were the same path and nothing was replaced.", + "type": "boolean" + }, + "unknownArtifacts": { + "description": "Artifact paths whose existence could not be determined, each { path, code }.", + "type": "array" + } + }, + "required": [ + "source", + "destination" + ], + "type": "object" +}
- Changed
shadowgraph_retrieve8 fields changed- added
Input schema / properties / kind / descriptionAdded value: +"Restrict results to decisions or to attempts. A structured filter, never a content match." - changed
Input schema / properties / limit / descriptionPrevious value: -"Page size. Omitted means a declared default, never silent truncation."New value: +"Maximum items to return, 1-1000; the default is 50 and completeness.limitSource reports which applied. Out of range is rejected, never silently clamped." - added
Input schema / properties / minConfidence / descriptionAdded value: +"Return only decisions whose current confidence is at least this value, 0-1. A structured filter, never a content match." - changed
Input schema / properties / offset / descriptionPrevious value: -"Page offset."New value: +"Items to skip before this window. Ordering is total and deterministic, so paging cannot drop or duplicate an item." - added
Input schema / properties / project / descriptionAdded value: +"Restrict to one project, including which neighbours may be pulled in." - added
Input schema / properties / query / descriptionAdded value: +"Whitespace-separated terms matched against the declared content fields (title, goal, chosen, assumption, evidence, alternative, attempt solution, attempt result, attempt reason, environment), exactly as in shadowgraph_search. Omit to retrieve by filters alone." - added
Input schema / properties / status / descriptionAdded value: +"Return only decisions in this lifecycle state. A structured filter, so matching it is never counted as a content match." - changed
Output schema / (root)Previous value: -nullNew value: +{ + "description": "Matching records plus their one-hop neighbours, with pagination and completeness.", + "properties": { + "completeness": { + "description": "Declares exactly what this response left out, so a truncated result can never look complete.", + "properties": { + "complete": { + "description": "True only when every matching item is present.", + "type": "boolean" + }, + "contentFields": { + "description": "The declared content fields a query term could match.", + "items": { + "type": "string" + }, + "type": "array" + }, + "includesGraphNeighbours": { + "description": "Always true: this result may contain items reached by relationship rather than by content.", + "type": "boolean" + }, + "limitSource": { + "description": "Whose choice bounded the result.", + "enum": [ + "caller", + "default" + ], + "type": "string" + }, + "losslessItems": { + "description": "Always true: each returned item is a full-fidelity record, never a summary or a truncated field.", + "type": "boolean" + }, + "omitted": { + "description": "total minus returned.", + "minimum": 0, + "type": "integer" + }, + "returned": { + "description": "Items in this response.", + "minimum": 0, + "type": "integer" + }, + "scope": { + "description": "The project, query, and structured filters that produced this result, so it explains its own derivation.", + "type": "object" + }, + "total": { + "description": "Items that matched in total.", + "minimum": 0, + "type": "integer" + } + }, + "required": [ + "scope", + "returned", + "total", + "complete", + "omitted", + "losslessItems", + "limitSource", + "contentFields", + "includesGraphNeighbours" + ], + "type": "object" + }, + "items": { + "description": "The items in this window, in deterministic order.", + "items": { + "description": "One hit, which may be a content match or a one-hop graph neighbour.", + "properties": { + "filters": { + "description": "The structured filters that were applied.", + "type": "object" + }, + "graphBoost": { + "description": "1 for an item included as a graph neighbour, 0 for a direct content match.", + "type": "number" + }, + "matched": { + "description": "The content fields that actually matched, never schema keys.", + "items": { + "type": "string" + }, + "type": "array" + }, + "matchedBy": { + "description": "content when query terms matched, filter when only structured filters applied, graph when the item was pulled in as a neighbour.", + "enum": [ + "content", + "filter", + "graph" + ], + "type": "string" + }, + "reason": { + "description": "Human-readable explanation built from matched, so it can never claim a match it cannot name.", + "type": "string" + }, + "reasons": { + "description": "All reasons this item is present.", + "items": { + "type": "string" + }, + "type": "array" + }, + "record": { + "description": "One stored entity: a decision, attempt, memory, fact, or alternative. Fields vary by kind, and an entity imported from an older schema may carry fewer of them.", + "properties": { + "actor": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "description": "Who performed the write." + }, + "client": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "description": "Which client performed the write." + }, + "createdAt": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "description": "ISO 8601 creation time." + }, + "id": { + "description": "Stable entity identifier.", + "type": "string" + }, + "kind": { + "description": "Entity kind: decision, attempt, memory, fact, relation, review, or alternative.", + "type": "string" + }, + "project": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "description": "Project namespace; records imported from a schema that predates projects may carry null." + }, + "schemaVersion": { + "description": "Storage schema version this entity was written under. A value above the build’s own version is preserved rather than downgraded.", + "type": "integer" + }, + "sessionId": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "description": "Session identifier recorded with the write." + }, + "sourceClass": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "description": "Claimed origin class recorded with the write. A claim, never proof." + }, + "sourceRaw": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "description": "The original origin label when it differed from sourceClass. Audit only; never evidence." + }, + "updatedAt": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "description": "ISO 8601 time of the last change." + } + }, + "type": "object" + }, + "score": { + "description": "Relevance score; 0 when no query terms were supplied.", + "type": "number" + } + }, + "required": [ + "record", + "score", + "matched", + "reason", + "matchedBy", + "filters", + "graphBoost", + "reasons" + ], + "type": "object" + }, + "type": "array" + }, + "page": { + "description": "The window actually applied to the matching items.", + "properties": { + "hasMore": { + "description": "True when matching items exist beyond this window.", + "type": "boolean" + }, + "limit": { + "description": "Window size applied, whether the caller set it or the default did.", + "minimum": 1, + "type": "integer" + }, + "offset": { + "description": "Index of the first item returned.", + "minimum": 0, + "type": "integer" + }, + "total": { + "description": "Matching items before the window was applied.", + "minimum": 0, + "type": "integer" + } + }, + "required": [ + "offset", + "limit", + "total", + "hasMore" + ], + "type": "object" + } + }, + "required": [ + "items", + "page", + "completeness" + ], + "type": "object" +}
- Changed
shadowgraph_review3 fields changed- added
Input schema / properties / changedFacts / descriptionAdded value: +"Fact keys that just changed. Only string-form reopenWhen rules match this list; it is an ephemeral signal, not durable state." - changed
Input schema / properties / facts / descriptionPrevious value: -"Optional overrides; these take precedence over stored facts."New value: +"Fact key/value overrides evaluated instead of the stored facts of the same key. Stored facts are used for every key not listed here, so reopen rules still work after a restart." - added
Input schema / properties / project / descriptionAdded value: +"Review only this project. Omit to review every project."
- Changed
shadowgraph_review_signals2 fields changed- added
Input schema / properties / project / descriptionAdded value: +"Only signals whose decision belongs to this project. Omit for every project." - added
Input schema / properties / status / descriptionAdded value: +"Filter by state. Omit to return both."
- Changed
shadowgraph_search9 fields changed- added
Input schema / properties / kind / descriptionAdded value: +"Restrict results to decisions or to attempts. A structured filter, never a content match." - changed
Input schema / properties / limit / descriptionPrevious value: -"Page size. Omitted means a declared default, never silent truncation."New value: +"Maximum items to return, 1-1000; the default is 50 and completeness.limitSource reports which applied. Out of range is rejected, never silently clamped." - added
Input schema / properties / minConfidence / descriptionAdded value: +"Return only decisions whose current confidence is at least this value, 0-1. A structured filter, never a content match." - changed
Input schema / properties / offset / descriptionPrevious value: -"Page offset."New value: +"Items to skip before this window. Ordering is total and deterministic, so paging cannot drop or duplicate an item." - added
Input schema / properties / project / descriptionAdded value: +"Restrict to one project. Omitted, decisions and facts are searched across projects, while memories stay in the default project and all-null scope." - added
Input schema / properties / query / descriptionAdded value: +"Whitespace-separated terms, matched case-insensitively as substrings against the declared content fields (title, goal, chosen, assumption, evidence, alternative, attempt solution, attempt result, attempt reason, environment). Every term must match something, so more terms narrow the result. Omit to filter without searching." - added
Input schema / properties / sourceClass / descriptionAdded value: +"Return only records carrying this claimed origin class. A structured filter, never a content match." - added
Input schema / properties / status / descriptionAdded value: +"Return only decisions in this lifecycle state. A structured filter, so matching it is never counted as a content match." - changed
Output schema / (root)Previous value: -nullNew value: +{ + "description": "Matching records with their pagination and completeness declaration.", + "properties": { + "completeness": { + "description": "Declares exactly what this response left out, so a truncated result can never look complete.", + "properties": { + "complete": { + "description": "True only when every matching item is present.", + "type": "boolean" + }, + "contentFields": { + "description": "The declared content fields a query term could match.", + "items": { + "type": "string" + }, + "type": "array" + }, + "limitSource": { + "description": "Whose choice bounded the result.", + "enum": [ + "caller", + "default" + ], + "type": "string" + }, + "losslessItems": { + "description": "Always true: each returned item is a full-fidelity record, never a summary or a truncated field.", + "type": "boolean" + }, + "omitted": { + "description": "total minus returned.", + "minimum": 0, + "type": "integer" + }, + "returned": { + "description": "Items in this response.", + "minimum": 0, + "type": "integer" + }, + "scope": { + "description": "The project, query, and structured filters that produced this result, so it explains its own derivation.", + "type": "object" + }, + "total": { + "description": "Items that matched in total.", + "minimum": 0, + "type": "integer" + } + }, + "required": [ + "scope", + "returned", + "total", + "complete", + "omitted", + "losslessItems", + "limitSource", + "contentFields" + ], + "type": "object" + }, + "items": { + "description": "The items in this window, in deterministic order.", + "items": { + "description": "One hit and the evidence for why it matched.", + "properties": { + "filters": { + "description": "The structured filters that were applied.", + "type": "object" + }, + "matched": { + "description": "The content fields that actually matched, never schema keys.", + "items": { + "type": "string" + }, + "type": "array" + }, + "matchedBy": { + "description": "content when query terms matched, filter when only structured filters applied, graph when the item was pulled in as a neighbour.", + "enum": [ + "content", + "filter", + "graph" + ], + "type": "string" + }, + "reason": { + "description": "Human-readable explanation built from matched, so it can never claim a match it cannot name.", + "type": "string" + }, + "record": { + "description": "One stored entity: a decision, attempt, memory, fact, or alternative. Fields vary by kind, and an entity imported from an older schema may carry fewer of them.", + "properties": { + "actor": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "description": "Who performed the write." + }, + "client": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "description": "Which client performed the write." + }, + "createdAt": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "description": "ISO 8601 creation time." + }, + "id": { + "description": "Stable entity identifier.", + "type": "string" + }, + "kind": { + "description": "Entity kind: decision, attempt, memory, fact, relation, review, or alternative.", + "type": "string" + }, + "project": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "description": "Project namespace; records imported from a schema that predates projects may carry null." + }, + "schemaVersion": { + "description": "Storage schema version this entity was written under. A value above the build’s own version is preserved rather than downgraded.", + "type": "integer" + }, + "sessionId": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "description": "Session identifier recorded with the write." + }, + "sourceClass": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "description": "Claimed origin class recorded with the write. A claim, never proof." + }, + "sourceRaw": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "description": "The original origin label when it differed from sourceClass. Audit only; never evidence." + }, + "updatedAt": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "description": "ISO 8601 time of the last change." + } + }, + "type": "object" + }, + "score": { + "description": "Relevance score; 0 when no query terms were supplied.", + "type": "number" + } + }, + "required": [ + "record", + "score", + "matched", + "reason", + "matchedBy", + "filters" + ], + "type": "object" + }, + "type": "array" + }, + "page": { + "description": "The window actually applied to the matching items.", + "properties": { + "hasMore": { + "description": "True when matching items exist beyond this window.", + "type": "boolean" + }, + "limit": { + "description": "Window size applied, whether the caller set it or the default did.", + "minimum": 1, + "type": "integer" + }, + "offset": { + "description": "Index of the first item returned.", + "minimum": 0, + "type": "integer" + }, + "total": { + "description": "Matching items before the window was applied.", + "minimum": 0, + "type": "integer" + } + }, + "required": [ + "offset", + "limit", + "total", + "hasMore" + ], + "type": "object" + } + }, + "required": [ + "items", + "page", + "completeness" + ], + "type": "object" +}
- Changed
shadowgraph_supersede3 fields changed- added
Input schema / properties / decisionId / descriptionAdded value: +"The decision being replaced. It becomes superseded and is excluded from current context." - added
Input schema / properties / replacementId / descriptionAdded value: +"The decision replacing it. Must be in the same project and must not be superseded, archived, abandoned, or stale." - changed
Output schema / (root)Previous value: -nullNew value: +{ + "description": "Both sides of the supersession and the relationship that records it.", + "properties": { + "previous": { + "description": "A stored decision, including its alternatives and auditable confidence basis.", + "properties": { + "actor": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "description": "Who performed the write." + }, + "alternatives": { + "description": "Rejected alternatives, each with id, label, reasonRejected, status, and the reopenWhen rules that make it reconsiderable.", + "type": "array" + }, + "assumptions": { + "description": "Assumptions the decision rests on. Searchable content.", + "items": { + "type": "string" + }, + "type": "array" + }, + "chosen": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "description": "The option that was chosen." + }, + "client": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "description": "Which client performed the write." + }, + "confidence": { + "description": "Auditable confidence: initial, current (0-1), policy, a history entry per move, and a basis summarising the contributions it was folded from. Legacy records may lack basis.", + "type": "object" + }, + "createdAt": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "description": "ISO 8601 creation time." + }, + "evidence": { + "description": "Normalised evidence entries: source, type, sourceClass, confidence, observedAt, detail.", + "type": "array" + }, + "failedAttempts": { + "description": "Attempt identifiers or notes attached to this decision.", + "type": "array" + }, + "goal": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "description": "What the decision was trying to achieve." + }, + "id": { + "description": "Stable entity identifier.", + "type": "string" + }, + "kind": { + "description": "Entity kind: decision, attempt, memory, fact, relation, review, or alternative.", + "type": "string" + }, + "migration": { + "description": "Present only on migrated records; records the legacy value a field was mapped from.", + "type": "object" + }, + "outcome": { + "anyOf": [ + { + "type": "object" + }, + { + "type": "null" + } + ], + "description": "The recorded outcome, or null until one is recorded." + }, + "project": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "description": "Project namespace; records imported from a schema that predates projects may carry null." + }, + "reviewAfter": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "description": "ISO 8601 instant after which shadowgraph_maintain marks this decision stale." + }, + "schemaVersion": { + "description": "Storage schema version this entity was written under. A value above the build’s own version is preserved rather than downgraded.", + "type": "integer" + }, + "sessionId": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "description": "Session identifier recorded with the write." + }, + "sourceClass": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "description": "Claimed origin class recorded with the write. A claim, never proof." + }, + "sourceRaw": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "description": "The original origin label when it differed from sourceClass. Audit only; never evidence." + }, + "status": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "description": "Lifecycle state. Legacy records may carry a value this build does not recognise; shadowgraph_validate reports those." + }, + "supersededBy": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "description": "Identifier of the decision that replaced this one." + }, + "supersedes": { + "description": "Identifiers of decisions this one replaced.", + "type": "array" + }, + "title": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "description": "Short name of the decision." + }, + "updatedAt": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "description": "ISO 8601 time of the last change." + } + }, + "required": [ + "id", + "kind" + ], + "type": "object" + }, + "relation": { + "anyOf": [ + { + "description": "A stored relationship between two entities.", + "properties": { + "actor": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "description": "Who performed the write." + }, + "client": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "description": "Which client performed the write." + }, + "createdAt": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "description": "ISO 8601 creation time." + }, + "from": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "description": "Source entity identifier." + }, + "id": { + "description": "Stable entity identifier.", + "type": "string" + }, + "kind": { + "description": "Entity kind: decision, attempt, memory, fact, relation, review, or alternative.", + "type": "string" + }, + "project": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "description": "Project namespace; records imported from a schema that predates projects may carry null." + }, + "relation": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "description": "Relationship name, such as depends_on or supersedes." + }, + "schemaVersion": { + "description": "Storage schema version this entity was written under. A value above the build’s own version is preserved rather than downgraded.", + "type": "integer" + }, + "sessionId": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "description": "Session identifier recorded with the write." + }, + "sourceClass": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "description": "Claimed origin class recorded with the write. A claim, never proof." + }, + "sourceRaw": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "description": "The original origin label when it differed from sourceClass. Audit only; never evidence." + }, + "temporal": { + "description": "Bi-temporal window for the relationship.", + "type": "object" + }, + "to": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "description": "Target entity identifier." + }, + "updatedAt": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "description": "ISO 8601 time of the last change." + } + }, + "required": [ + "id", + "from", + "to", + "relation" + ], + "type": "object" + }, + { + "type": "null" + } + ], + "description": "The supersedes relationship, or null when a repeated supersession found none to report." + }, + "replacement": { + "description": "A stored decision, including its alternatives and auditable confidence basis.", + "properties": { + "actor": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "description": "Who performed the write." + }, + "alternatives": { + "description": "Rejected alternatives, each with id, label, reasonRejected, status, and the reopenWhen rules that make it reconsiderable.", + "type": "array" + }, + "assumptions": { + "description": "Assumptions the decision rests on. Searchable content.", + "items": { + "type": "string" + }, + "type": "array" + }, + "chosen": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "description": "The option that was chosen." + }, + "client": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "description": "Which client performed the write." + }, + "confidence": { + "description": "Auditable confidence: initial, current (0-1), policy, a history entry per move, and a basis summarising the contributions it was folded from. Legacy records may lack basis.", + "type": "object" + }, + "createdAt": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "description": "ISO 8601 creation time." + }, + "evidence": { + "description": "Normalised evidence entries: source, type, sourceClass, confidence, observedAt, detail.", + "type": "array" + }, + "failedAttempts": { + "description": "Attempt identifiers or notes attached to this decision.", + "type": "array" + }, + "goal": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "description": "What the decision was trying to achieve." + }, + "id": { + "description": "Stable entity identifier.", + "type": "string" + }, + "kind": { + "description": "Entity kind: decision, attempt, memory, fact, relation, review, or alternative.", + "type": "string" + }, + "migration": { + "description": "Present only on migrated records; records the legacy value a field was mapped from.", + "type": "object" + }, + "outcome": { + "anyOf": [ + { + "type": "object" + }, + { + "type": "null" + } + ], + "description": "The recorded outcome, or null until one is recorded." + }, + "project": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "description": "Project namespace; records imported from a schema that predates projects may carry null." + }, + "reviewAfter": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "description": "ISO 8601 instant after which shadowgraph_maintain marks this decision stale." + }, + "schemaVersion": { + "description": "Storage schema version this entity was written under. A value above the build’s own version is preserved rather than downgraded.", + "type": "integer" + }, + "sessionId": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "description": "Session identifier recorded with the write." + }, + "sourceClass": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "description": "Claimed origin class recorded with the write. A claim, never proof." + }, + "sourceRaw": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "description": "The original origin label when it differed from sourceClass. Audit only; never evidence." + }, + "status": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "description": "Lifecycle state. Legacy records may carry a value this build does not recognise; shadowgraph_validate reports those." + }, + "supersededBy": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "description": "Identifier of the decision that replaced this one." + }, + "supersedes": { + "description": "Identifiers of decisions this one replaced.", + "type": "array" + }, + "title": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "description": "Short name of the decision." + }, + "updatedAt": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "description": "ISO 8601 time of the last change." + } + }, + "required": [ + "id", + "kind" + ], + "type": "object" + } + }, + "required": [ + "previous", + "replacement", + "relation" + ], + "type": "object" +}
- Changed
shadowgraph_traverse7 fields changed- added
Input schema / properties / depth / descriptionAdded value: +"How many relationship hops to follow, 1-10. Defaults to 1. Anything outside the range is rejected." - added
Input schema / properties / direction / descriptionAdded value: +"out follows relationships whose from is in the frontier, in follows their to, both follows either. Defaults to both." - added
Input schema / properties / id / descriptionAdded value: +"Entity id to start from. Must exist." - added
Input schema / properties / projectAdded value: +{ + "description": "Project whose memory nodes are visible during the walk. Defaults to \"default\"; decisions, facts, and attempts are not filtered by it.", + "type": "string" +} - added
Input schema / properties / relation / descriptionAdded value: +"Follow only relationships with this exact name. Omit to follow all of them." - added
Input schema / properties / scopeAdded value: +{ + "additionalProperties": false, + "description": "Scope selector. Omitted or partial fields mean explicit nulls, not \"any\": identity is the exact (project, userId, agentId, runId, memoryType, key) tuple, so a run-scoped memory never leaks into a user-only read.", + "properties": { + "agentId": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "description": "Agent this memory belongs to, or null for none." + }, + "runId": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "description": "Single run or task this memory belongs to, or null for none." + }, + "userId": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "description": "Person this memory belongs to, or null for none." + } + }, + "type": "object" +} - changed
Output schema / (root)Previous value: -nullNew value: +{ + "description": "The reachable subgraph.", + "properties": { + "depth": { + "description": "The hop limit that was applied.", + "maximum": 10, + "minimum": 1, + "type": "integer" + }, + "direction": { + "description": "The direction that was applied.", + "enum": [ + "in", + "out", + "both" + ], + "type": "string" + }, + "nodes": { + "description": "Entities reached, root first. Mixed kinds, including alternatives synthesised from their decision.", + "items": { + "description": "One stored entity: a decision, attempt, memory, fact, or alternative. Fields vary by kind, and an entity imported from an older schema may carry fewer of them.", + "properties": { + "actor": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "description": "Who performed the write." + }, + "client": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "description": "Which client performed the write." + }, + "createdAt": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "description": "ISO 8601 creation time." + }, + "id": { + "description": "Stable entity identifier.", + "type": "string" + }, + "kind": { + "description": "Entity kind: decision, attempt, memory, fact, relation, review, or alternative.", + "type": "string" + }, + "project": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "description": "Project namespace; records imported from a schema that predates projects may carry null." + }, + "schemaVersion": { + "description": "Storage schema version this entity was written under. A value above the build’s own version is preserved rather than downgraded.", + "type": "integer" + }, + "sessionId": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "description": "Session identifier recorded with the write." + }, + "sourceClass": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "description": "Claimed origin class recorded with the write. A claim, never proof." + }, + "sourceRaw": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "description": "The original origin label when it differed from sourceClass. Audit only; never evidence." + }, + "updatedAt": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "description": "ISO 8601 time of the last change." + } + }, + "type": "object" + }, + "type": "array" + }, + "relations": { + "description": "Relationships traversed. Named relations, not \"edges\".", + "items": { + "description": "A stored relationship between two entities.", + "properties": { + "actor": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "description": "Who performed the write." + }, + "client": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "description": "Which client performed the write." + }, + "createdAt": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "description": "ISO 8601 creation time." + }, + "from": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "description": "Source entity identifier." + }, + "id": { + "description": "Stable entity identifier.", + "type": "string" + }, + "kind": { + "description": "Entity kind: decision, attempt, memory, fact, relation, review, or alternative.", + "type": "string" + }, + "project": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "description": "Project namespace; records imported from a schema that predates projects may carry null." + }, + "relation": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "description": "Relationship name, such as depends_on or supersedes." + }, + "schemaVersion": { + "description": "Storage schema version this entity was written under. A value above the build’s own version is preserved rather than downgraded.", + "type": "integer" + }, + "sessionId": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "description": "Session identifier recorded with the write." + }, + "sourceClass": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "description": "Claimed origin class recorded with the write. A claim, never proof." + }, + "sourceRaw": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "description": "The original origin label when it differed from sourceClass. Audit only; never evidence." + }, + "temporal": { + "description": "Bi-temporal window for the relationship.", + "type": "object" + }, + "to": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "description": "Target entity identifier." + }, + "updatedAt": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "description": "ISO 8601 time of the last change." + } + }, + "required": [ + "id", + "from", + "to", + "relation" + ], + "type": "object" + }, + "type": "array" + }, + "root": { + "description": "The entity the walk started from.", + "type": "string" + } + }, + "required": [ + "root", + "direction", + "depth", + "nodes", + "relations" + ], + "type": "object" +}
- Changed
shadowgraph_update_status3 fields changed- added
Input schema / properties / decisionId / descriptionAdded value: +"Identifier of an existing decision, as returned by shadowgraph_record_decision, shadowgraph_search, or shadowgraph_retrieve." - added
Input schema / properties / status / descriptionAdded value: +"Target state. Legal moves are proposed to planned/in_progress/abandoned/archived; planned to in_progress/abandoned/archived; in_progress to executed/failed/abandoned/archived; executed to validated/failed/reconsidered/archived; validated to reconsidered/archived; failed to reconsidered/abandoned/archived; reconsidered to planned/in_progress/abandoned/archived; stale to reconsidered/archived; abandoned to archived. stale and superseded cannot be set by a caller." - changed
Output schema / (root)Previous value: -nullNew value: +{ + "description": "A stored decision, including its alternatives and auditable confidence basis.", + "properties": { + "actor": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "description": "Who performed the write." + }, + "alternatives": { + "description": "Rejected alternatives, each with id, label, reasonRejected, status, and the reopenWhen rules that make it reconsiderable.", + "type": "array" + }, + "assumptions": { + "description": "Assumptions the decision rests on. Searchable content.", + "items": { + "type": "string" + }, + "type": "array" + }, + "chosen": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "description": "The option that was chosen." + }, + "client": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "description": "Which client performed the write." + }, + "confidence": { + "description": "Auditable confidence: initial, current (0-1), policy, a history entry per move, and a basis summarising the contributions it was folded from. Legacy records may lack basis.", + "type": "object" + }, + "createdAt": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "description": "ISO 8601 creation time." + }, + "evidence": { + "description": "Normalised evidence entries: source, type, sourceClass, confidence, observedAt, detail.", + "type": "array" + }, + "failedAttempts": { + "description": "Attempt identifiers or notes attached to this decision.", + "type": "array" + }, + "goal": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "description": "What the decision was trying to achieve." + }, + "id": { + "description": "Stable entity identifier.", + "type": "string" + }, + "kind": { + "description": "Entity kind: decision, attempt, memory, fact, relation, review, or alternative.", + "type": "string" + }, + "migration": { + "description": "Present only on migrated records; records the legacy value a field was mapped from.", + "type": "object" + }, + "outcome": { + "anyOf": [ + { + "type": "object" + }, + { + "type": "null" + } + ], + "description": "The recorded outcome, or null until one is recorded." + }, + "project": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "description": "Project namespace; records imported from a schema that predates projects may carry null." + }, + "reviewAfter": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "description": "ISO 8601 instant after which shadowgraph_maintain marks this decision stale." + }, + "schemaVersion": { + "description": "Storage schema version this entity was written under. A value above the build’s own version is preserved rather than downgraded.", + "type": "integer" + }, + "sessionId": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "description": "Session identifier recorded with the write." + }, + "sourceClass": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "description": "Claimed origin class recorded with the write. A claim, never proof." + }, + "sourceRaw": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "description": "The original origin label when it differed from sourceClass. Audit only; never evidence." + }, + "status": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "description": "Lifecycle state. Legacy records may carry a value this build does not recognise; shadowgraph_validate reports those." + }, + "supersededBy": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "description": "Identifier of the decision that replaced this one." + }, + "supersedes": { + "description": "Identifiers of decisions this one replaced.", + "type": "array" + }, + "title": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "description": "Short name of the decision." + }, + "updatedAt": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "description": "ISO 8601 time of the last change." + } + }, + "required": [ + "id", + "kind" + ], + "type": "object" +}
- Changed
shadowgraph_validate1 field changed- changed
Output schema / (root)Previous value: -nullNew value: +{ + "description": "Integrity diagnostics.", + "properties": { + "counts": { + "description": "Issue counts per severity.", + "properties": { + "error": { + "description": "Genuinely invalid data.", + "minimum": 0, + "type": "integer" + }, + "info": { + "description": "Declared discontinuities, such as a hard-purge journal gap.", + "minimum": 0, + "type": "integer" + }, + "legacy": { + "description": "Readable data that predates a contract.", + "minimum": 0, + "type": "integer" + }, + "unsupported": { + "description": "Data from a newer schema or policy this build cannot interpret.", + "minimum": 0, + "type": "integer" + } + }, + "required": [ + "error", + "legacy", + "unsupported", + "info" + ], + "type": "object" + }, + "issues": { + "description": "Every diagnostic found, each with a stable code and severity.", + "items": { + "description": "One diagnostic. Extra fields identify the affected entity, entry, or scope.", + "properties": { + "code": { + "description": "Stable diagnostic code, such as missing_relation_source, unknown_decision_status, or journal_gap.", + "type": "string" + }, + "detail": { + "description": "Human-readable explanation.", + "type": "string" + }, + "entityId": { + "description": "Affected entity identifier.", + "type": "string" + }, + "entryId": { + "description": "Affected journal entry identifier.", + "type": "string" + }, + "recordId": { + "description": "Affected record or fact identifier.", + "type": "string" + }, + "relationId": { + "description": "Affected relationship identifier.", + "type": "string" + }, + "seq": { + "anyOf": [ + { + "type": "integer" + }, + { + "type": "null" + } + ], + "description": "Affected journal sequence number." + }, + "severity": { + "description": "error is invalid data, legacy is readable but predates a contract, unsupported comes from a newer schema this build cannot interpret, info is a declared discontinuity.", + "enum": [ + "error", + "legacy", + "unsupported", + "info" + ], + "type": "string" + }, + "type": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "description": "Affected journal entry type." + } + }, + "required": [ + "code", + "severity" + ], + "type": "object" + }, + "type": "array" + }, + "valid": { + "description": "False when any error or unsupported issue is present.", + "type": "boolean" + } + }, + "required": [ + "valid", + "issues", + "counts" + ], + "type": "object" +}
27 tool updates
v0.40.0- First observed
shadowgraph_ack_review - First observed
shadowgraph_backup - First observed
shadowgraph_confidence_evidence - First observed
shadowgraph_context - First observed
shadowgraph_journal - First observed
shadowgraph_link - First observed
shadowgraph_maintain - First observed
shadowgraph_purge - First observed
shadowgraph_purge_preview - First observed
shadowgraph_rebuild - First observed
shadowgraph_recall - First observed
shadowgraph_record_attempt - First observed
shadowgraph_record_decision - First observed
shadowgraph_record_fact - First observed
shadowgraph_record_outcome - First observed
shadowgraph_redact - First observed
shadowgraph_remember - First observed
shadowgraph_repair_plan - First observed
shadowgraph_restore - First observed
shadowgraph_retrieve - First observed
shadowgraph_review - First observed
shadowgraph_review_signals - First observed
shadowgraph_search - First observed
shadowgraph_supersede - First observed
shadowgraph_traverse - First observed
shadowgraph_update_status - First observed
shadowgraph_validate
TDQS
Scored across 20 tools
The tools mostly have distinct roles, and descriptions explicitly contrast recall/search/retrieve/context and review/review_context/review_signals/reconsider. Still, the read/search and review clusters are dense enough that an agent could misselect without careful reading.
All tools use a consistent shadowgraph_ snake_case namespace with clear action-oriented names. Variants like record_decision, review_context, and confidence_evidence remain predictable within the same convention.
Twenty tools is heavy for a memory/decision graph MCP and creates a large surface to scan. Each tool covers a distinct lifecycle operation, but the count is borderline for practical agent use.
The surface covers recording, retrieval, review, maintenance, validation, and lifecycle updates well. However, descriptions reference shadowgraph_repair_plan and shadowgraph_rebuild tools that are not present, leaving a minor repair/replay gap.
Maintenance
Related MCP Connectors
- memnodeOAuthdev.memnode
Persistent, inspectable memory for AI agents with lineage, correction, and a hosted MCP endpoint.
Memory, reflection and safety for AI agents. Hosted or local, no vector database.
Graph-native persistent memory for AI agents — 33 MCP tools, zero-LLM writes.
Provenance-carrying memory for AI agents: corrections supersede, never overwrite. Free, API + MCP.
Related MCP Servers
AlicenseNot gradedqualityBmaintenancePersistent graph-based memory for AI agents, stored as plain markdown — no vector DB. Typed nodes and 11 relation types via 5 MCP tools (search, get, create, link, related), stdio and HTTP/SSE transports.3MIT- FlicenseNot gradedqualityCmaintenanceLocal-first cross-agent memory for AI coding agents. Persistent, shared memory over MCP — what you tell one agent can be recalled by another — with all data stored in a single local SQLite file, no cloud and no API keys.-
- AlicenseAqualityCmaintenanceLocal-first, source-traceable memory for AI agents — no LLM at ingest, $0 per message, zero data egress. Gives Claude Code, Cursor, and any MCP client one shared persistent memory with semantic recall, belief revision, selective forgetting, and a provenance guard that blocks acting on stale or unconfirmed memories.2315MIT
- AlicenseAqualityAmaintenanceSelf-hosted decision memory for AI coding agents. Captures decisions with the alternatives you rejected, and warns before an agent re-proposes a rejected approach.481Apache 2.0