feat(server): expose typed semantic transition review
This commit is contained in:
+114
-6
@@ -763,6 +763,18 @@ bearer token, if any. Non-loopback binding requires a configured token.</p>
|
||||
<td><p><span class="docutils literal"><span class="pre">/api/v1/projects/{id}/transitions/apply</span></span></p></td>
|
||||
<td><p>Conditionally apply that client-held plan and base_revision.</p></td>
|
||||
</tr>
|
||||
<tr><td><p>POST</p></td>
|
||||
<td><p><span class="docutils literal"><span class="pre">/api/v1/projects/{id}/semantic-transitions/query</span></span></p></td>
|
||||
<td><p>Read selected traces' typed facts, own drift and linked impacts.</p></td>
|
||||
</tr>
|
||||
<tr><td><p>POST</p></td>
|
||||
<td><p><span class="docutils literal"><span class="pre">/api/v1/projects/{id}/semantic-transitions/preview</span></span></p></td>
|
||||
<td><p>Prepare typed semantic decisions and source writeback without writing.</p></td>
|
||||
</tr>
|
||||
<tr><td><p>POST</p></td>
|
||||
<td><p><span class="docutils literal"><span class="pre">/api/v1/projects/{id}/semantic-transitions/apply</span></span></p></td>
|
||||
<td><p>Apply that prepared candidate under its original shared revision/ETag.</p></td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
<p><span class="docutils literal"><span class="pre">Content-Type:</span> application/json</span> is required for JSON requests.
|
||||
@@ -784,8 +796,8 @@ candidate validation reports the same diagnostic in its 200 response.
|
||||
Parsing, validation and query processing use snapshot workers, so this work
|
||||
does not hold the catalog lock or serialize unrelated model preparation.</p>
|
||||
<p>Import accepts schema-1 JSON through the shared explicit migration adapter,
|
||||
as well as schema-2, schema-3 and current schema-4 JSON. Source import uses the shared language parser
|
||||
and its supported migrations. Export uses schema 4 / arcadia 4. Native JSON
|
||||
as well as schema-2, schema-3, schema-4 and current schema-5 JSON. Source import uses the shared language parser
|
||||
and its supported migrations. Export uses schema 5 / arcadia 5. Native JSON
|
||||
replacement accepts supported older schemas through the same explicit migration.
|
||||
Only documented query parameters are accepted. In particular, appending
|
||||
<span class="docutils literal"><span class="pre">?revision=...</span></span> to model/source export is an error, not historical retrieval.</p>
|
||||
@@ -796,7 +808,7 @@ Only documented query parameters are accepted. In particular, appending
|
||||
<pre class="literal-block">{
|
||||
"entry": "rescue.arcadia",
|
||||
"files": {
|
||||
"rescue.arcadia": "arcadia 4; project rescue \"Rescue\" { include \"oa/work.arcadia\"; }\n",
|
||||
"rescue.arcadia": "arcadia 5; project rescue \"Rescue\" { include \"oa/work.arcadia\"; }\n",
|
||||
"oa/work.arcadia": "// Engineering rationale\noa_activity assess \"Assess assistance\" {}\n"
|
||||
}
|
||||
}</pre>
|
||||
@@ -807,7 +819,7 @@ targets or another hosted resource. All submitted files must be reachable;
|
||||
missing files, cycles, duplicate keys, case collisions and escaping paths are
|
||||
rejected. The bundle permits at most 256 files, 32 include edges along a path,
|
||||
and 1,024 include edges in total. Model and source-byte budgets apply across
|
||||
the complete bundle, not separately per file. Current bundle syntax is source4; source3 bundles migrate explicitly while
|
||||
the complete bundle, not separately per file. Current bundle syntax is source5; source3/4 bundles migrate explicitly while
|
||||
preserving their files/includes/comments. V1/V2 single-file migration remains
|
||||
available through interchange import.</p>
|
||||
<p>Compilation inserts UUIDs into headers that omit them. Import returns 201 with
|
||||
@@ -999,7 +1011,7 @@ contract in the same transaction when removing a used interface allocation.</p>
|
||||
<p>Explicit schema1/2/3 migration preserves prior identities and typed ports. Reports
|
||||
add semantic defaults, generated interface allocations and unresolved message
|
||||
values. Old source3 bundles retain files/includes/comments during upgrade; all
|
||||
current exports use schema4/source4. Reading an old envelope does not write it or
|
||||
current exports use schema5/source5. Reading an old envelope does not write it or
|
||||
advance its ETag. Canonical exports omit transient migration reports.</p>
|
||||
</section>
|
||||
<section id="validation">
|
||||
@@ -1009,7 +1021,7 @@ advance its ETag. Canonical exports omit transient migration reports.</p>
|
||||
<p>or:</p>
|
||||
<pre class="literal-block">{"format":"arcadia", "source":"complete source document"}</pre>
|
||||
<p>or:</p>
|
||||
<pre class="literal-block">{"format":"source-project", "source_project":{"entry":"rescue.arcadia", "files":{"rescue.arcadia":"arcadia 4; project rescue \"Rescue\" {}"}}}</pre>
|
||||
<pre class="literal-block">{"format":"source-project", "source_project":{"entry":"rescue.arcadia", "files":{"rescue.arcadia":"arcadia 5; project rescue \"Rescue\" {}"}}}</pre>
|
||||
<p>A well-formed validation request returns 200 with <span class="docutils literal">valid</span> and <span class="docutils literal">issues</span> even
|
||||
if its candidate is invalid, including a model record that fails typed decoding.
|
||||
Malformed request JSON or an invalid format/payload envelope is a 400.
|
||||
@@ -1093,6 +1105,102 @@ authenticated as an untouched server preview; the same authenticated client
|
||||
can submit ordinary typed commands. The core fingerprint is a change detector,
|
||||
not a security digest. There is no plan token, expiration store or receipt.</p>
|
||||
</section>
|
||||
<section id="typed-semantic-transition-review">
|
||||
<h2>Typed semantic transition review</h2>
|
||||
<p>The sibling <span class="docutils literal"><span class="pre">semantic-transitions</span></span> routes use the <a class="reference external" href="language.html#typed-semantic-review-facts">typed review semantics</a> in <span class="docutils literal">language.rst</span> sections 5.1–5.5.
|
||||
The original prose transition routes keep
|
||||
their existing contract. All new routes use JSON and the existing authentication,
|
||||
capacity, worker and error boundaries.</p>
|
||||
<p>Query accepts <span class="docutils literal"><span class="pre">{"traces":["trace-uuid"],"references":{},"revision":1}</span></span>.
|
||||
<span class="docutils literal">references</span> is an optional map of canonical OA UUIDs to SA UUIDs, including
|
||||
historical deleted identities. It never guesses correspondences from names.
|
||||
<span class="docutils literal">revision</span> is optional; a mismatch returns 409. Select 1–100 unique existing
|
||||
trace IDs; an empty or duplicate selection returns 400 and a missing trace
|
||||
returns 404. The response includes the current revision and items containing
|
||||
<span class="docutils literal">trace</span>, <span class="docutils literal">oa</span>, <span class="docutils literal">sa</span>, typed <span class="docutils literal">facets</span>, <span class="docutils literal">drift</span> and <span class="docutils literal">linked_impacts</span>.
|
||||
Own and linked drift and their unreviewed flags remain distinct. Query reads one
|
||||
immutable snapshot, does not refresh baselines, and does not fetch artifact URIs.</p>
|
||||
<p>Preview accepts <span class="docutils literal">SemanticTransitionRequest</span>:</p>
|
||||
<pre class="literal-block">{
|
||||
"transition": {
|
||||
"direction": "OaToSa",
|
||||
"sources": ["40000000-0000-4000-8000-000000000002"],
|
||||
"scope": "SelectedOnly",
|
||||
"mappings": [{
|
||||
"source": "40000000-0000-4000-8000-000000000002",
|
||||
"target": "40000000-0000-4000-8000-000000000003",
|
||||
"target_kind": null
|
||||
}],
|
||||
"fields": [], "resolutions": [], "destination_diagram": null
|
||||
},
|
||||
"traces": {}, "references": {},
|
||||
"reviews": [{
|
||||
"source": "40000000-0000-4000-8000-000000000002",
|
||||
"resolutions": [
|
||||
{"facet":{"Header":"Name"}, "decision":"TakeSource"},
|
||||
{"facet":{"Data":"Unit"}, "decision":"KeepTarget"}
|
||||
],
|
||||
"reset": []
|
||||
}],
|
||||
"candidates": [], "accepted_impacts": []
|
||||
}</pre>
|
||||
<p>The example maps an existing OA data type to its traced SA counterpart, takes
|
||||
only its name and acknowledges intentionally different units. Other facets stay
|
||||
unreviewed or retain their earlier drift. Select an explicit trace through the
|
||||
<span class="docutils literal">traces</span> map (source UUID to trace UUID) when multiple trace kinds connect the
|
||||
pair. <span class="docutils literal">reset</span> deliberately invalidates exact old selectors after changed
|
||||
correspondence. The optional collections default to empty. Semantic header
|
||||
decisions use typed facets; leave legacy <span class="docutils literal">transition.fields</span> and
|
||||
<span class="docutils literal">transition.resolutions</span> empty.</p>
|
||||
<p>Facet selectors are closed enums, for example <span class="docutils literal"><span class="pre">{"Data":"IntegerMinimum"}</span></span>
|
||||
or <span class="docutils literal"><span class="pre">{"Member":{"collection":"SignalItems","keys":{"oa":"oa-uuid","sa":"sa-uuid"}}}</span></span>.
|
||||
Annotation keys contain the entire path and field; enum literal keys are exact
|
||||
strings. <span class="docutils literal">KeepTarget</span>, <span class="docutils literal">TakeSource</span> and <span class="docutils literal">Candidate</span> operate on independently
|
||||
selected facts. Candidate records use existing Element/Relation/ArtifactLink
|
||||
types, must preserve identity/alias, and must equal precisely the result of
|
||||
the selected facets. Constructor review covers its coupled introduced/removed
|
||||
fields. Membership review does not silently acknowledge order; target-only
|
||||
members remain independent. OpenAPI defines every selector and typed payload.</p>
|
||||
<p>Preview requires <span class="docutils literal"><span class="pre">If-Match</span></span> and returns <span class="docutils literal"><span class="pre">{"base_revision":1,"plan":{...}}</span></span>.
|
||||
The plan contains the original typed request, mapping plan, review facts,
|
||||
acknowledged/retired selectors, linked impacts, exact prepared impacts, conflicts,
|
||||
commands, and base/prepared fingerprints. A conflict-free preview also prepares
|
||||
the complete authored source bundle and checks its model equivalence and capacity.
|
||||
No preview changes the model, source, revision or stored bytes.</p>
|
||||
<p>If ordinary preparation induces additional cleanup, the plan reports exact typed
|
||||
before/after impacts and a conflict. Review those impacts, place the accepted
|
||||
records in <span class="docutils literal">accepted_impacts</span>, and request another preview. Acceptance cannot
|
||||
override a contradictory selected facet. Missing mappings, ambiguous order,
|
||||
duplicate decisions, invalid candidates or unresolved impacts cannot be applied.
|
||||
This is the shared core planner and command preparation, with no server-specific
|
||||
semantic mutation engine.</p>
|
||||
<p>Apply accepts the entire preview envelope under the same <span class="docutils literal"><span class="pre">If-Match</span></span>. It checks
|
||||
<span class="docutils literal">base_revision</span>, the model fingerprint, unresolved conflicts, the prepared
|
||||
candidate fingerprint, ordinary model validation and coupled source preparation,
|
||||
then atomically stores one accepted model/source revision. The final store check
|
||||
also catches a concurrent edit during preparation. Source-only edits invalidate
|
||||
the preview through the shared ETag even when the model fingerprint is unchanged.
|
||||
Stale ETag/revision returns 412; semantic rejection returns 422 with code
|
||||
<span class="docutils literal">semantic_transition_rejected</span>. Exact no-op candidates preserve revision.
|
||||
Read and preview again after a successful changed apply before reviewing further.</p>
|
||||
<p>A supplied plan remains a client-owned candidate. Fingerprints detect stale or
|
||||
inconsistent proposals; they are not tamper-proof signatures, authentication
|
||||
receipts or proof of original review authorship. Apply preserves preview-generated
|
||||
identities and does not rerun the planner with fresh random IDs. Authenticated
|
||||
clients already have ordinary model/source editing privileges. The server does
|
||||
not persist plans, tokens or review sessions.</p>
|
||||
<p>Requests allow 100 sources, trace choices and reviews; 200 mappings, candidates
|
||||
and accepted impacts; 5,000 canonical reference mappings; and 5,000 facet
|
||||
resolutions plus resets across all reviews. The legacy 400 prose-resolution
|
||||
limit and 200-command transaction limit still apply. Query has the same 5,000
|
||||
reference-map limit. Core bounded linked traversal errors remain observable as
|
||||
semantic rejection; no truncated result silently claims complete review.</p>
|
||||
<p>Schema/source 5 adds <span class="docutils literal">TraceBaseline.semantic</span>. Absence or null is Unreviewed;
|
||||
migrating older prose baselines does not fabricate semantic history. The persisted
|
||||
baseline contains only closed typed <span class="docutils literal">FacetReview</span> facts, not whole candidate
|
||||
records or a generic JSON value tree. Historical UUIDs remain historical, including
|
||||
after deletion, and source uses explicit <span class="docutils literal">uuid</span> tokens for them.</p>
|
||||
</section>
|
||||
<section id="error-contract">
|
||||
<h2>Error contract</h2>
|
||||
<p>All errors have <span class="docutils literal"><span class="pre">Content-Type:</span> application/problem+json</span>. Example:</p>
|
||||
|
||||
Reference in New Issue
Block a user