0.1.0
·
64 commits
to main
since this release
Immutable
release. Only release title and notes can be modified.
The first stable release: the milestone closed at zero open issues, and
the pre-release alpha line ends here.
Added
- Scope builds the claim from CNF tiers (#100). The run wizard's Scope
screen gains a row of tier checkboxes — CORE, STANDARD, OPTIONS, SEC-BASIC —
each carrying the capabilities the capability matrix puts in that tier and
the number of catalogue cases those capabilities gate. Both counts come from
the published library's owntier_memberswalk, the one every profile
verdict is computed from, so the row cannot drift from the answer the
judgement gives. Composing writes an ad-hoc statement into the same paste box
the vendor path uses: the product identity from the Connect step, the checked
tiers as claimed profiles, their required capabilities as the claimed
capabilities, the schedule release read from the committed statements under
the mounted party tree, and the spec-component versions derived from the
catalogue's ownappliesfloors. The operator reads the document before
saving it, and it is then validated, stored and written into the run's output
directory exactly like a pasted one, so a verdict stays a pure function of a
statement. Option branches stay undeclared, because only the party running
the server knows which branch it realizes. - The console exports a signed record, and anyone can check one (#68). The
verdicts screen gains one step that hands the finished run to the pinned
instrument's ownverdicts --sign-key: the rendered documents, a digest
manifest over them, and a detached OpenPGP signature over that manifest. The
console seals nothing itself. Beside the sealed set it renders three files a
party publishes, each carrying the record digest prefix that ties it to the
signed bytes — the brand's seal card with its three slots filled from the
record, a compact badge SVG with copy-paste markdown and HTML snippets, and
a self-contained HTML report of the results and verdicts surfaces whose
footer carries the full digest, the signer fingerprint and the signing time.
All three are pure functions of the record, so the same bundle reproduces
the same bytes. The whole bundle downloads as one archive. /verifyis a public record check (#68). No run, no server and no
account: upload a bundle and the published library recomputes every digest
its manifest names and checks the detached signature. A tampered file names
itself. The upload is a plain HTML form posting to a server route, so it
works with no JavaScript at all; uploaded bundles are transient and swept on
a short timer. The honesty box renders on every outcome — a valid signature
proves integrity and origin since signing, not the run's conditions, not the
system under test's identity claims, not the catalogue's coverage — and the
page prints theveredictum verify-recordequivalent beside it, so nobody
has to trust the console to check the console.- The export surfaces carry the openEHR trademark acknowledgment and the
independence disclaimer visibly (#94). The seal card renders it in its
caption area and the report in its footer, because those are what a party
publishes. run --record-exchangespersists the wire (#96). The flag writes
transcript.jsonbesideresults.json: per case, in send order, the
request line, request headers and request body, and the response status,
headers and body. It is off by default, and persistence is a serialization
of exchanges the driver already holds, so a recorded run sends nothing extra
and reaches the same verdicts as an unrecorded one. The artifact records a
SUT's response bodies verbatim, so it can carry real patient data: it is
operator-controlled output, never a log, and theauthorizationrequest
header's value is withheld. With--sign-keythe sealed record manifest
covers the transcript.run-transcript.schema.jsonjoins the published schema set. The run
transcript is its own artifact family, separate from the verification pack's
replaytranscript.schema.json, which requires an adjudicated verdict per
entry and carries no request side at all.- The console records and reads the wire. Scope gains a "Record the wire
exchanges" checkbox, off by default with the clinical-data caution beside
it, and the results drawer renders each recorded exchange as request and
response panes. A run driven without the flag says so where the wire would
be.
Changed
- A measured population now varies leaf by leaf, so earlier measured records
are not comparable with later ones (#137). The performance pack used to
stamp each composition with only the event-context times and the composer
name, so every composition of a population carried identical clinical values.
A server storing that population can share structure, index entries and cache
pages that a real population would never let it share, which flattered every
number measured over it — records produced before this change are flattered
in exactly that way, and a number from one of them must not be compared with
a number produced after it. The pack now reads the leaf constraints the
operational template itself declares and redraws every numeric leaf inside
its own permitted range:DV_QUANTITYmagnitudes against the
C_DV_QUANTITYinterval declared for the leaf's units, andDV_COUNT
magnitudes against theC_INTEGERrange declared for aDV_COUNT
magnitude. A leaf whose permitted range the template does not declare, and
every coded, textual and date-time leaf, keeps its committed value, so no
arrival can send an instance the template refuses. The draw is seeded from
the template key and the arrival index, so the same run reproduces the same
population byte for byte. perf_run::pack::PackTemplatecarries aconstraintsfield. The library
type gains the leaf ranges read out of its operational template, which is a
breaking change for anything constructing the struct literally.- The console answers an unknown address with a real page (#84). A path
outside the route tree used to render the bare string "Page not found."
with no chrome, no title and no way back. It now renders inside the
console's own sidebar and toast chrome, sets its own title, names the path
that missed, and offers the instrument and the catalogue as routes out. The
HTTP status is unchanged at 404. - The console ships a full icon set (#84).
favicon.ico,
apple-touch-icon.png,icon-192.png,icon-512.pngand a web manifest,
every one of them rendered from the two brand SVG masters by
scripts/render/brand-icons.shso the mark cannot fork. The image serves
them from the samepublic/mount as the seal. - Every run-wizard mutation reports both outcomes as a notification.
Saving the scope, previewing the selection, starting a run and cancelling
one each raise a toast on success and on failure, with the failure copy
naming the object, the instrument's own diagnostic verbatim, and the next
action. The detailed inline panes stay beside them, which is where a
schema finding or a per-chapter breakdown is read line by line. - The console reads two new environment variables.
VEREDICTUM_SIGN_KEY
names the armored OpenPGP secret key the export seals with, and
VEREDICTUM_VERIFY_KEYnames the public half. Both are optional and both
unset is a first-class state the surfaces explain rather than an error. The
export asks for the public key too because it verifies its own bundle before
stating who signed it and when: it never prints a signing time it has not
checked. A passphrase reaches the spawned instrument through
VEREDICTUM_SIGN_PASSPHRASEand its child environment only — never a
signal, a file, a command line, or a log line.
Fixed
- Issue numbers inherited from FerroEHR now say so (#123). Three
ambiguity-register.schema.jsonandwire-surface.schema.jsondescriptions
carried bare#2545,#2546and#271, which resolve to unrelated issues
on this repository's tracker; they readFerroEHR#NNNNnow, as do the
runner comments and the generated wire-surface coverage report that carried
the same ids. Description text only: no schema keyword, type or constraint
moved. validate --write-reportwrites somewhere that exists (#91). The
coverage report's path was climbed out of the spec tree
(<specs>/../../conformance/coverage-report.md), which matched the old
mono-repo layout and, at this one, resolved to a repository-root
conformance/directory that has never existed. The report is now derived
from the artifact root it describes and lands at
<ROOT>/coverage-report.md, so it follows the catalogue rather than
wherever the specs happen to be mounted.coverage_report_pathtakes the
artifact root and returns a plainPathBuf, since the derivation can no
longer fail.