WhatToChange: recommended-changes/2026-09-21-docs-and-cors/ What-to-Change.md What-to-Change-To.md How-to-implement-the-changes.md What was actually done: - Markdown, HTML, and PDF for standards, architecture, API, and the operator guide. - README points at scripts/build-docs.sh. - VERAE_MCP_CORS=1 enables CORS and JSON responses on the Streamable HTTP app. What was not done: - (none)
95 lines
3.2 KiB
HTML
95 lines
3.2 KiB
HTML
<!DOCTYPE html>
|
|
<html xmlns="http://www.w3.org/1999/xhtml">
|
|
<head>
|
|
<meta charset="utf-8" />
|
|
<meta name="generator" content="pandoc" />
|
|
<meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=yes" />
|
|
<title>architecture</title>
|
|
<style>
|
|
/* Default styles provided by pandoc.
|
|
** See https://pandoc.org/MANUAL.html#variables-for-html for config info.
|
|
*/
|
|
code{white-space: pre-wrap;}
|
|
span.smallcaps{font-variant: small-caps;}
|
|
div.columns{display: flex; gap: min(4vw, 1.5em);}
|
|
div.column{flex: auto; overflow-x: auto;}
|
|
div.hanging-indent{margin-left: 1.5em; text-indent: -1.5em;}
|
|
/* The extra [class] is a hack that increases specificity enough to
|
|
override a similar rule in reveal.js */
|
|
ul.task-list[class]{list-style: none;}
|
|
ul.task-list li input[type="checkbox"] {
|
|
font-size: inherit;
|
|
width: 0.8em;
|
|
margin: 0 0.8em 0.2em -1.6em;
|
|
vertical-align: middle;
|
|
}
|
|
.display.math{display: block; text-align: center; margin: 0.5rem auto;}
|
|
</style>
|
|
<link rel="stylesheet" href="style.css" />
|
|
</head>
|
|
<body>
|
|
<header id="title-block-header">
|
|
<h1 class="title">architecture</h1>
|
|
</header>
|
|
<h1 id="architecture">Architecture</h1>
|
|
<h2 id="flow">Flow</h2>
|
|
<ol type="1">
|
|
<li>An MCP client calls <code>stamp</code>, <code>verify</code>, or
|
|
<code>hash_report</code>.</li>
|
|
<li><code>RoutingLedger</code> sends <code>scope=global</code> to
|
|
<code>GlobalLedger</code> and every other scope to
|
|
<code>FileLedger</code>.</li>
|
|
<li><code>FileLedger</code> keeps an idempotent JSON list. The same
|
|
digest, org, and scope returns the existing receipt.</li>
|
|
<li><code>GlobalClient</code> posts the digest to VeraeTime and, when
|
|
the body has no certificate yet, polls
|
|
<code>/api/status/{jobId}</code>.</li>
|
|
<li><code>verify</code> with <code>want_scope=global</code> posts
|
|
<code>{ "certificate": "<id>" }</code> to
|
|
<code>/api/verify</code>. Otherwise it checks the local file first, then
|
|
VeraeTime.</li>
|
|
</ol>
|
|
<h2 id="modules">Modules</h2>
|
|
<table>
|
|
<colgroup>
|
|
<col style="width: 50%" />
|
|
<col style="width: 50%" />
|
|
</colgroup>
|
|
<thead>
|
|
<tr>
|
|
<th>Module</th>
|
|
<th>Role</th>
|
|
</tr>
|
|
</thead>
|
|
<tbody>
|
|
<tr>
|
|
<td><code>server.py</code></td>
|
|
<td>MCP tools and process entry</td>
|
|
</tr>
|
|
<tr>
|
|
<td><code>ledger.py</code></td>
|
|
<td>Receipt model, memory ledger, file ledger, router</td>
|
|
</tr>
|
|
<tr>
|
|
<td><code>global_client.py</code></td>
|
|
<td>VeraeTime HTTPS client; blocking I/O runs in a worker thread</td>
|
|
</tr>
|
|
<tr>
|
|
<td><code>nats_ledger.py</code></td>
|
|
<td>Optional leaf <code>locald</code> client</td>
|
|
</tr>
|
|
</tbody>
|
|
</table>
|
|
<h2 id="idempotency">Idempotency</h2>
|
|
<p>Local stamps are idempotent per digest + org + scope. Global stamps
|
|
send <code>restamp: false</code> and <code>wait: true</code>. VeraeTime
|
|
may return the same certificate for the same digest. This server does
|
|
not cache global receipts in the local file.</p>
|
|
<h2 id="what-this-process-is-not">What this process is not</h2>
|
|
<p>It does not replace <code>verae-timestamp</code> /
|
|
<code>locald</code>. It does not write JetStream. It does not store
|
|
document bytes. Memory ledger exists for tests and for
|
|
<code>mcp dev</code> when a caller injects it. <code>main()</code>
|
|
always builds <code>RoutingLedger</code>.</p>
|
|
</body>
|
|
</html>
|