Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion check.html
Original file line number Diff line number Diff line change
Expand Up @@ -214,7 +214,7 @@ <h4>What this runs</h4>
signed payload is rebuilt from the record's own fields, under the construction <em>the record itself states</em> rather than
whichever version this page ships, and the signature is checked against the key the record names.</p>
<p>Both are the constructions <code>@observer-protocol/policy-engine</code> exports at
<span data-engine-version="current">1.0.0-rc.12</span>, the version npm's <code>latest</code> tag serves a reader today.
<span data-engine-version="current">1.0.0-rc.21</span>, the version npm's <code>latest</code> tag serves a reader today.
This page loads nothing, so it cannot import the package; it carries its own copy of those constructions and CI asserts,
on every build, that the bytes it produces are identical to the package's own over every refusal this repository publishes.
A divergence turns the build red rather than turning a verdict here wrong.
Expand Down
4 changes: 2 additions & 2 deletions docs.html
Original file line number Diff line number Diff line change
Expand Up @@ -218,7 +218,7 @@ <h2>Choose your path.</h2>
</a>
<a href="https://github.com/observer-protocol/op-policy-engine" target="_blank" class="qs-card">
<div class="qs-icon">📦</div>
<div class="qs-tag">NPM INSTALL · v<span data-engine-version="current">1.0.0-rc.12</span></div>
<div class="qs-tag">NPM INSTALL · v<span data-engine-version="current">1.0.0-rc.21</span></div>
<div class="qs-name">Verify a credential</div>
<div class="qs-meta">npm install @observer-protocol/policy-engine</div>
<div class="qs-desc" data-shared-copy="offline-scope">Verify a delegation credential yourself — issuer, structure, validity window, eddsa-jcs-2022 proof against the issuer DID document, and revocation. No API key, no token, no Observer Protocol API in the path. It fetches the issuer's DID document and the revocation status list over ordinary HTTPS from the origins the credential names; point <code>offline.didDocumentPath</code> at a local copy and it makes no network call at all. The hosted verifier is a separate deployment running a different engine version; see the SDK section.</div>
Expand Down Expand Up @@ -447,7 +447,7 @@ <h2>@observer-protocol/policy-engine</h2>
unauthenticated <code>POST /v1/verify</code> returns 200 with a signed result.
<br><br>
It is a <em>different build</em>, though. The hosted service reports
<code>engine.running: "0.3.3"</code>; the package above is <code><span data-engine-version="current">1.0.0-rc.12</span></code>. Re-measured against
<code>engine.running: "0.3.3"</code>; the package above is <code><span data-engine-version="current">1.0.0-rc.21</span></code>. Re-measured against
rc.10 on 9 August 2026: they agree on 7 of the 8 artifacts this site publishes. The eighth is
never evaluated by the hosted engine at all &mdash; it is refused at that deployment's issuer
allowlist, which does not carry the testbed issuer. So the agreement is on samples rather
Expand Down
6 changes: 3 additions & 3 deletions index.html
Original file line number Diff line number Diff line change
Expand Up @@ -983,7 +983,7 @@ <h3 style="font-family:'Fraunces',serif; font-size:1.3rem; font-weight:600; marg
<strong style="color:var(--text);">It fails closed, and it will refuse us too.</strong> <code>onUnreachable: 'cache-then-deny'</code> is the only accepted value: if the revocation list cannot be fetched, a cached answer is used and then the credential is denied. A status list hosted on an origin other than the pinned issuer's is refused until you allowlist it, and Observer Protocol's own clause-zero revocation demonstration is exactly such a pair, so it does not verify out of the box. That limit is published in the package.
</p>
<div style="font-family:'IBM Plex Mono',monospace; font-size:0.68rem; color:var(--text-faint); line-height:2; border-top:1px solid var(--border); padding-top:1rem;">
<div>package · <span style="color:var(--amber);">@observer-protocol/policy-engine</span> <span data-engine-version="current">1.0.0-rc.12</span></div>
<div>package · <span style="color:var(--amber);">@observer-protocol/policy-engine</span> <span data-engine-version="current">1.0.0-rc.21</span></div>
<div>licence · MIT · self-hostable · no account</div>
<div>limits · <a href="https://github.com/observer-protocol/op-policy-engine/blob/main/KNOWN-LIMITS.md" target="_blank" rel="noopener" style="color:var(--amber); text-decoration:none;">KNOWN-LIMITS.md ↗</a></div>
</div>
Expand Down Expand Up @@ -1105,7 +1105,7 @@ <h2>The register, stated plainly.</h2>
<div class="reg-row">
<div>
<div class="reg-what" data-shared-copy="offline-scope">Offline verification with nothing from us</div>
<div class="reg-detail" data-shared-copy="offline-scope"><code>@observer-protocol/policy-engine</code> <span data-engine-version="current">1.0.0-rc.12</span> on npm, MIT. Section 05 is a transcript of it running against a credential served from this domain.</div>
<div class="reg-detail" data-shared-copy="offline-scope"><code>@observer-protocol/policy-engine</code> <span data-engine-version="current">1.0.0-rc.21</span> on npm, MIT. Section 05 is a transcript of it running against a credential served from this domain.</div>
</div>
<div class="reg-state live">Live</div>
</div>
Expand Down Expand Up @@ -1147,7 +1147,7 @@ <h2>The register, stated plainly.</h2>
<div class="reg-row">
<div>
<div class="reg-what">Signed records an outside party can rebuild</div>
<div class="reg-detail">Of <span data-measured="signed-record-coverage:signedRecordTotal">11,432</span> signed records across <span data-measured="signed-record-coverage:storeFileCount">13</span> record stores we hold, written between <span data-measured="signed-record-coverage:signedRange.earliestDate">2026-08-05</span> and <span data-measured="signed-record-coverage:signedRange.latestDate">2026-08-15</span>, <strong><span data-measured="signed-record-coverage:headline.neverRebuildable.count">3,089</span> of them (<span data-measured="signed-record-coverage:headline.neverRebuildable.percentOfSigned">27.0%</span>) cannot be checked by anyone.</strong> They are <code><span data-measured="signed-record-coverage:headline.neverRebuildable.kinds">instructed, report</span></code> records, and <strong>no version of the engine ever published rebuilds their signed bytes</strong>, so there is nothing to verify a signature against. This is not a version pin and it is not a gap that a reader can work around by installing something else: those records carry a signature that no counterparty, and no one here, can check. <strong>Principle 04 below says the evidence is portable or it isn't evidence.</strong> For better than a quarter of what we sign, it isn't. A further <span data-measured="signed-record-coverage:headline.notRebuildableAtNpmLatest.count">122</span> <code><span data-measured="signed-record-coverage:headline.notRebuildableAtNpmLatest.kinds">resolution</span></code> records are rebuildable at some published version but not at the one <code>npm install</code> serves; section 04 of <a href="/verify" style="color:var(--amber); text-decoration:none;">/verify</a> carries that. Every figure in this row is read from <code>results/</code> and fails the build if the copy and the measurement disagree.</div>
<div class="reg-detail">Of <span data-measured="signed-record-coverage:signedRecordTotal">11,432</span> signed records across <span data-measured="signed-record-coverage:storeFileCount">13</span> record stores we hold, written between <span data-measured="signed-record-coverage:signedRange.earliestDate">2026-08-05</span> and <span data-measured="signed-record-coverage:signedRange.latestDate">2026-08-15</span>, <strong><span data-measured="signed-record-coverage:headline.neverRebuildable.count">3,089</span> of them (<span data-measured="signed-record-coverage:headline.neverRebuildable.percentOfSigned">27.0%</span>) cannot be checked by anyone.</strong> They are <code><span data-measured="signed-record-coverage:headline.neverRebuildable.kinds">instructed, report</span></code> records, and <strong>no version of the engine ever published rebuilds their signed bytes</strong>, so there is nothing to verify a signature against. This is not a version pin and it is not a gap that a reader can work around by installing something else: those records carry a signature that no counterparty, and no one here, can check. <strong>Principle 04 below says the evidence is portable or it isn't evidence.</strong> For better than a quarter of what we sign, it isn't. A second class, resolution records, was rebuildable at some published version but not at the one <code>npm install</code> served, for four releases. That count is now <span data-measured="signed-record-coverage:headline.notRebuildableAtNpmLatest.count">0</span>; section 02 of /verify carries what happened. Every figure in this row is read from <code>results/</code> and fails the build if the copy and the measurement disagree.</div>
</div>
<div class="reg-state no"><span data-measured="signed-record-coverage:headline.neverRebuildable.percentOfSigned">27.0%</span> unverifiable</div>
</div>
Expand Down
7 changes: 4 additions & 3 deletions results/engine-payload-exports.json
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@
"versionCount"
],
"computedAgainstRegistryState": {
"npmLatest": "1.0.0-rc.12",
"npmLatest": "1.0.0-rc.21",
"npmRc": "1.0.0-rc.21",
"versionCount": 26
},
Expand All @@ -33,7 +33,7 @@
}
},
"package": "@observer-protocol/policy-engine",
"npmLatest": "1.0.0-rc.12",
"npmLatest": "1.0.0-rc.21",
"npmRc": "1.0.0-rc.21",
"versionCount": 26,
"withdrawals": {
Expand All @@ -56,7 +56,8 @@
"npmLatestExports": [
"evaluationVerdictPayload",
"lapsePayload",
"refusalPayload"
"refusalPayload",
"resolutionPayload"
],
"versions": [
{
Expand Down
20 changes: 9 additions & 11 deletions results/signed-record-coverage.json
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@
"no reader sees. A figure that announces it is unchecked where nobody reads the",
"announcement is a marker doing no work, so the announcement is now in the artifact."
],
"measuredOn": "2026-08-16",
"measuredOn": "2026-08-23",
"provenance": {
"corpusHalf": {
"fields": [
Expand All @@ -25,7 +25,7 @@
"signedRange",
"headline.neverRebuildable"
],
"measuredOn": "2026-08-16",
"measuredOn": "2026-08-23",
"over": "13 store file(s) under ~/op-artifacts",
"reDerivable": false,
"why": "The stores are working artifacts outside this repository. CI cannot reach them, so these figures are a DATED MEASUREMENT and nothing re-confirms them. The per-file sha256 list below exists so a later run can prove it measured the same population."
Expand All @@ -36,12 +36,12 @@
"headline.notRebuildableAtNpmLatest"
],
"computedAgainstRegistryState": {
"npmLatest": "1.0.0-rc.12",
"npmLatest": "1.0.0-rc.21",
"source": "results/engine-payload-exports.json",
"thatFileMeasuredOn": "2026-08-23"
},
"reDerivable": true,
"why": "These depend on which symbols npm's `latest` exports, which is public and is re-read by check-measured-figures.mjs on every run. THEY GO FALSE WHEN THE `latest` DIST-TAG MOVES, without this file being touched. If npm latest is not 1.0.0-rc.12, treat every field listed here as stale."
"why": "These depend on which symbols npm's `latest` exports, which is public and is re-read by check-measured-figures.mjs on every run. THEY GO FALSE WHEN THE `latest` DIST-TAG MOVES, without this file being touched. If npm latest is not 1.0.0-rc.21, treat every field listed here as stale."
}
},
"storesRoot": "~/op-artifacts",
Expand Down Expand Up @@ -102,7 +102,7 @@
"total": 122,
"rebuildRoute": "resolutionPayload",
"rebuildableEver": true,
"rebuildableAtNpmLatest": false
"rebuildableAtNpmLatest": true
}
],
"headline": {
Expand All @@ -116,12 +116,10 @@
"note": "No published version of the package rebuilds these. Not fragile, not version-pinned: unverifiable by anyone, permanently, on the evidence of every version published to date."
},
"notRebuildableAtNpmLatest": {
"kinds": [
"resolution"
],
"count": 122,
"percentOfSigned": "1.1%",
"note": "Rebuildable at some published version but NOT at 1.0.0-rc.12, which is what npm install serves a reader today."
"kinds": [],
"count": 0,
"percentOfSigned": "0.0%",
"note": "Rebuildable at some published version but NOT at 1.0.0-rc.21, which is what npm install serves a reader today."
}
},
"files": [
Expand Down
26 changes: 26 additions & 0 deletions scripts/check-measured-figures.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -511,6 +511,32 @@ if (engine) {
// which one they are looking at.
const PREDICATES = {
// True when the version npm's `latest` tag serves does NOT export the named symbol.
// The affirmative of the same question. Both exist because BOTH SIDES OF A TAG MOVE NEED A
// PREDICATE: the page says one thing before `latest` moves past a withdrawal band and the
// opposite after, and a swap between two markers is mechanical where a hand edit on the day
// is not. Adding this one is safe BEFORE the move — it is unused until a marker names it.
//
// NOT THE NEGATION OF THE OTHER, deliberately. `latest-does-not-export` returns false when
// the version is unmeasured, and so does this: an unevaluable claim is not true, whichever
// direction it points, and a predicate defined as `!other` would turn one of those refusals
// into a pass.
'latest-exports': (res, arg, fresh) => {
const version = fresh ?? res.npmLatest;
const entry = (res.versions ?? []).find((v) => v.version === version);
if (!entry) {
return {
ok: false,
why: `npm serves ${version} at latest, and results/ carries no measurement for it. ` +
`The claim cannot be evaluated, which is not the same as it being true. ` +
`Re-run: node scripts/measure-engine-payload-exports.mjs`,
};
}
const exports_ = entry.exports ?? [];
return exports_.includes(arg)
? { ok: true, why: `latest (${version}) exports \`${arg}\`.` }
: { ok: false, why: `the version at latest (${version}) does NOT export \`${arg}\`, so this sentence is false.` };
},

'latest-does-not-export': (res, arg, fresh) => {
const version = fresh ?? res.npmLatest;
const entry = (res.versions ?? []).find((v) => v.version === version);
Expand Down
Loading
Loading