@rotifer/playground 0.15.0 → 0.17.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +24 -0
- package/dist/arena/invalidation-criteria.d.ts +157 -0
- package/dist/arena/invalidation-criteria.d.ts.map +1 -0
- package/dist/arena/invalidation-criteria.js +236 -0
- package/dist/arena/invalidation-criteria.js.map +1 -0
- package/dist/cloud/client.d.ts +94 -1
- package/dist/cloud/client.d.ts.map +1 -1
- package/dist/cloud/client.js +132 -22
- package/dist/cloud/client.js.map +1 -1
- package/dist/cloud/types.d.ts +9 -0
- package/dist/cloud/types.d.ts.map +1 -1
- package/dist/cloud/types.js.map +1 -1
- package/dist/commands/agent-create.d.ts.map +1 -1
- package/dist/commands/agent-create.js +3 -4
- package/dist/commands/agent-create.js.map +1 -1
- package/dist/commands/arena-audit.d.ts +3 -0
- package/dist/commands/arena-audit.d.ts.map +1 -0
- package/dist/commands/arena-audit.js +190 -0
- package/dist/commands/arena-audit.js.map +1 -0
- package/dist/commands/arena-submit.d.ts.map +1 -1
- package/dist/commands/arena-submit.js +30 -8
- package/dist/commands/arena-submit.js.map +1 -1
- package/dist/commands/arena-watch.d.ts.map +1 -1
- package/dist/commands/arena-watch.js +3 -4
- package/dist/commands/arena-watch.js.map +1 -1
- package/dist/commands/compile.d.ts.map +1 -1
- package/dist/commands/compile.js +45 -5
- package/dist/commands/compile.js.map +1 -1
- package/dist/commands/run.d.ts.map +1 -1
- package/dist/commands/run.js +17 -1
- package/dist/commands/run.js.map +1 -1
- package/dist/commands/unpublish.d.ts +26 -0
- package/dist/commands/unpublish.d.ts.map +1 -0
- package/dist/commands/unpublish.js +190 -0
- package/dist/commands/unpublish.js.map +1 -0
- package/dist/index.js +5 -0
- package/dist/index.js.map +1 -1
- package/dist/utils/fidelity-discount.d.ts +51 -0
- package/dist/utils/fidelity-discount.d.ts.map +1 -0
- package/dist/utils/fidelity-discount.js +47 -0
- package/dist/utils/fidelity-discount.js.map +1 -0
- package/genes/genesis-code-format/index.ts +1 -1
- package/genes/genesis-code-format/phenotype.json +1 -1
- package/genes/genesis-file-read/index.ts +1 -1
- package/genes/genesis-file-read/phenotype.json +1 -1
- package/genes/genesis-l0-constraint/index.ts +1 -1
- package/genes/genesis-l0-constraint/phenotype.json +1 -1
- package/genes/genesis-web-search/index.ts +1 -1
- package/genes/genesis-web-search-lite/index.ts +1 -1
- package/genes/genesis-web-search-lite/phenotype.json +1 -1
- package/package.json +5 -5
package/CHANGELOG.md
CHANGED
|
@@ -5,6 +5,30 @@ All notable changes to this project will be documented in this file.
|
|
|
5
5
|
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/),
|
|
6
6
|
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
|
7
7
|
|
|
8
|
+
## [0.17.0](https://github.com/rotifer-protocol/rotifer-playground/compare/v0.16.0...v0.17.0) (2026-08-19)
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
### Features
|
|
12
|
+
|
|
13
|
+
* **arena:** apply the invalidation criteria to the board ([#224](https://github.com/rotifer-protocol/rotifer-playground/issues/224)) ([607a2fe](https://github.com/rotifer-protocol/rotifer-playground/commit/607a2febaf6c8b0fe11cb6c062ae307201f2b144))
|
|
14
|
+
* **arena:** carry base_fitness and the discount, and stop holding Hybrid to an artifact ([#220](https://github.com/rotifer-protocol/rotifer-playground/issues/220)) ([6fcc73d](https://github.com/rotifer-protocol/rotifer-playground/commit/6fcc73dfbfd4fee07858f8834aa4311a46dd894c))
|
|
15
|
+
* **arena:** give legacy rows the provenance their numbers can prove ([#223](https://github.com/rotifer-protocol/rotifer-playground/issues/223)) ([10fb0d4](https://github.com/rotifer-protocol/rotifer-playground/commit/10fb0d4eb63d77e14d6e06a8d93b6fa09ad0513e))
|
|
16
|
+
* **cli:** compile honours declared fidelity; F(g) carries the discount it owed ([#222](https://github.com/rotifer-protocol/rotifer-playground/issues/222)) ([ac7d21b](https://github.com/rotifer-protocol/rotifer-playground/commit/ac7d21b4fccd455decedd0578061bb036a85a972))
|
|
17
|
+
|
|
18
|
+
## [0.16.0](https://github.com/rotifer-protocol/rotifer-playground/compare/v0.15.0...v0.16.0) (2026-08-19)
|
|
19
|
+
|
|
20
|
+
|
|
21
|
+
### Features
|
|
22
|
+
|
|
23
|
+
* **arena:** the invalidation criteria, as code anyone can run ([#214](https://github.com/rotifer-protocol/rotifer-playground/issues/214)) ([4719278](https://github.com/rotifer-protocol/rotifer-playground/commit/47192784670602907e5d8810ed01e07822f97978))
|
|
24
|
+
* **cli:** rotifer unpublish — let an author take a version down ([#217](https://github.com/rotifer-protocol/rotifer-playground/issues/217)) ([d8f411f](https://github.com/rotifer-protocol/rotifer-playground/commit/d8f411faa257aa46a486cb5fd5dc73dde403d34e))
|
|
25
|
+
* **telemetry:** publish the evidence that would show double-counting returning ([#218](https://github.com/rotifer-protocol/rotifer-playground/issues/218)) ([46e5122](https://github.com/rotifer-protocol/rotifer-playground/commit/46e5122b44ab83fa4c4cfa1936b361879b409973))
|
|
26
|
+
|
|
27
|
+
|
|
28
|
+
### Bug Fixes
|
|
29
|
+
|
|
30
|
+
* **genes:** make the bundled corpus compilable again ([#216](https://github.com/rotifer-protocol/rotifer-playground/issues/216)) ([c7b018f](https://github.com/rotifer-protocol/rotifer-playground/commit/c7b018f2014086b183d4b66dfe42edd16b6e256a))
|
|
31
|
+
|
|
8
32
|
## [0.15.0](https://github.com/rotifer-protocol/rotifer-playground/compare/v0.14.1...v0.15.0) (2026-08-18)
|
|
9
33
|
|
|
10
34
|
|
|
@@ -0,0 +1,157 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The criteria that disqualify an Arena score — as code, over public data.
|
|
3
|
+
*
|
|
4
|
+
* ADR-319 D2 asks for invalidation to be reproducible rather than curated: no
|
|
5
|
+
* hand-written list of rows to drop, and no criterion that only the maintainer
|
|
6
|
+
* can evaluate. Everything here therefore reads what any anonymous caller can
|
|
7
|
+
* read (`arena_entries`, `genes`, and the public `gene-wasm` bucket), so a
|
|
8
|
+
* third party can run the same criteria and get the same verdicts. A criterion
|
|
9
|
+
* that needed a service key would defeat the point of writing it down.
|
|
10
|
+
*
|
|
11
|
+
* The criteria answer one question: *could this score have come from running
|
|
12
|
+
* the gene, and can anyone check?* They deliberately say nothing about whether
|
|
13
|
+
* a score is flattering or plausible — "0.97 looks too high" is not checkable
|
|
14
|
+
* and would put a human back in the loop that D2 exists to remove.
|
|
15
|
+
*/
|
|
16
|
+
/**
|
|
17
|
+
* Artifact-level shapes of an async `express()`.
|
|
18
|
+
*
|
|
19
|
+
* Kept byte-identical to `ASYNC_EXPRESS_MARKERS` in
|
|
20
|
+
* `crates/rotifer-core/src/sandbox/wasmtime_sandbox.rs`, which is what the
|
|
21
|
+
* runtime refuses to execute. If the two lists disagree, the Arena ranks a
|
|
22
|
+
* gene the sandbox will not run — the exact contradiction ADR-319 exists to
|
|
23
|
+
* remove — so `tests/unit/async-express-marker-parity.test.ts` reads the Rust
|
|
24
|
+
* source and fails when they drift.
|
|
25
|
+
*
|
|
26
|
+
* Note this is the *artifact* list, not the source list. The compiler's
|
|
27
|
+
* `detectAsyncExpress()` carries a third pattern (`express(): Promise<…>`)
|
|
28
|
+
* that is a TypeScript type annotation and cannot survive compilation, so it
|
|
29
|
+
* has no artifact-level counterpart by construction, not by omission.
|
|
30
|
+
*/
|
|
31
|
+
export declare const ARTIFACT_ASYNC_EXPRESS_MARKERS: readonly ["async function express", "express = async"];
|
|
32
|
+
export type CriterionId = "test-data" | "no-published-artifact" | "async-express-artifact";
|
|
33
|
+
/**
|
|
34
|
+
* Evaluation order, and the reason for it: each criterion answers a question
|
|
35
|
+
* that only makes sense once the previous one has been ruled out. Asking
|
|
36
|
+
* "does the artifact carry the defect" of a row that has no artifact — or of a
|
|
37
|
+
* row that was never a real gene — produces a true but useless reason. A row
|
|
38
|
+
* is reported under the first criterion it satisfies, and `allHits` keeps the
|
|
39
|
+
* rest so nothing is hidden.
|
|
40
|
+
*/
|
|
41
|
+
export declare const CRITERION_ORDER: readonly CriterionId[];
|
|
42
|
+
/** One Arena row plus the gene fields the criteria read. */
|
|
43
|
+
export interface AuditInput {
|
|
44
|
+
geneId: string;
|
|
45
|
+
/** `arena_entries.domain` — the domain recorded at submission time. */
|
|
46
|
+
domain: string | null;
|
|
47
|
+
/** Null when the gene is not publicly readable (unpublished; never orphaned — the FK cascades). */
|
|
48
|
+
gene: {
|
|
49
|
+
name: string;
|
|
50
|
+
version: string;
|
|
51
|
+
fidelity: string;
|
|
52
|
+
wasmPath: string | null;
|
|
53
|
+
wasmSize: number;
|
|
54
|
+
} | null;
|
|
55
|
+
evaluationMethod: string | null;
|
|
56
|
+
invalidatedAt: string | null;
|
|
57
|
+
invalidationReason: string | null;
|
|
58
|
+
}
|
|
59
|
+
export interface CriterionHit {
|
|
60
|
+
criterion: CriterionId;
|
|
61
|
+
/** Why this row is disqualified, in terms a reader can check against the evidence. */
|
|
62
|
+
reason: string;
|
|
63
|
+
/** The specific observation the verdict rests on. */
|
|
64
|
+
evidence: string;
|
|
65
|
+
}
|
|
66
|
+
/**
|
|
67
|
+
* `test-data` — the row is tagged as test traffic at submission time.
|
|
68
|
+
*
|
|
69
|
+
* Reads `arena_entries.domain` rather than `genes.domain`: the arena row
|
|
70
|
+
* records what the submitter declared when submitting, which is the claim
|
|
71
|
+
* being judged. A gene can also be renamed or re-domained after the fact.
|
|
72
|
+
*/
|
|
73
|
+
export declare function hitsTestData(row: AuditInput): CriterionHit | null;
|
|
74
|
+
/**
|
|
75
|
+
* `no-published-artifact` — the gene claims a WASM-executing fidelity but has
|
|
76
|
+
* published no artifact.
|
|
77
|
+
*
|
|
78
|
+
* Only Native is WASM-executing today; see WASM_BEARING_FIDELITIES for why
|
|
79
|
+
* Hybrid is not (yet) held to this.
|
|
80
|
+
*
|
|
81
|
+
* The verdict is about *recomputability*, not honesty. The score may well have
|
|
82
|
+
* come from a real local sandbox run; but with no published artifact nobody
|
|
83
|
+
* else can re-run it, and §9.7.1 asks that every published number be one a
|
|
84
|
+
* third party can arrive at independently. So the reason says what is missing,
|
|
85
|
+
* rather than accusing the author of a false declaration.
|
|
86
|
+
*
|
|
87
|
+
* Unpublished genes (`gene === null`) are deliberately *not* caught here. The
|
|
88
|
+
* FK from `arena_entries` cascades on delete, so a row can never be orphaned;
|
|
89
|
+
* an unreadable gene means the author unpublished it, which is a supported
|
|
90
|
+
* action, not a defect.
|
|
91
|
+
*/
|
|
92
|
+
export declare function hitsNoPublishedArtifact(row: AuditInput): CriterionHit | null;
|
|
93
|
+
/**
|
|
94
|
+
* `async-express-artifact` — the published artifact carries an async
|
|
95
|
+
* `express()`, which Javy/QuickJS cannot await.
|
|
96
|
+
*
|
|
97
|
+
* The gene returns a Promise, the shim serialises it to `{}`, and the run
|
|
98
|
+
* exits 0 — so the gene reports success while producing nothing. Any score
|
|
99
|
+
* measured against that output describes the empty object, not the gene.
|
|
100
|
+
*
|
|
101
|
+
* Takes bytes rather than fetching, so the criterion stays a pure function and
|
|
102
|
+
* the caller decides the transport (and can skip the download entirely).
|
|
103
|
+
*/
|
|
104
|
+
export declare function hitsAsyncExpressArtifact(row: AuditInput, artifact: Uint8Array | null): CriterionHit | null;
|
|
105
|
+
export interface RowVerdict {
|
|
106
|
+
geneId: string;
|
|
107
|
+
geneName: string;
|
|
108
|
+
/** The criterion this row is reported under — the first in CRITERION_ORDER that it satisfies. */
|
|
109
|
+
criterion: CriterionId | null;
|
|
110
|
+
reason: string | null;
|
|
111
|
+
evidence: string | null;
|
|
112
|
+
/** Every criterion the row satisfies, so a second reason is never silently dropped. */
|
|
113
|
+
allHits: CriterionHit[];
|
|
114
|
+
/** True when the artifact criterion could not be evaluated (download skipped or failed). */
|
|
115
|
+
artifactUnchecked: boolean;
|
|
116
|
+
/** What the database currently records, for the drift comparison. */
|
|
117
|
+
storedReason: string | null;
|
|
118
|
+
storedInvalidatedAt: string | null;
|
|
119
|
+
}
|
|
120
|
+
/**
|
|
121
|
+
* Apply every criterion to one row.
|
|
122
|
+
*
|
|
123
|
+
* `artifact` is the fetched WASM, or null when it was not fetched. Passing
|
|
124
|
+
* null does not make the row clean — it makes the artifact criterion
|
|
125
|
+
* *unevaluated*, which `artifactUnchecked` reports so a partial run is never
|
|
126
|
+
* mistaken for a clean bill of health.
|
|
127
|
+
*/
|
|
128
|
+
export declare function judgeRow(row: AuditInput, artifact: Uint8Array | null, opts: {
|
|
129
|
+
artifactFetched: boolean;
|
|
130
|
+
}): RowVerdict;
|
|
131
|
+
export type DriftKind =
|
|
132
|
+
/** Criteria say invalidate, the database has not recorded it. */
|
|
133
|
+
"missing"
|
|
134
|
+
/** The database records an invalidation no criterion reproduces. */
|
|
135
|
+
| "unreproducible"
|
|
136
|
+
/** Both agree it is invalid, but under different reasons. */
|
|
137
|
+
| "reason-mismatch";
|
|
138
|
+
export interface Drift {
|
|
139
|
+
geneId: string;
|
|
140
|
+
geneName: string;
|
|
141
|
+
kind: DriftKind;
|
|
142
|
+
computed: string | null;
|
|
143
|
+
stored: string | null;
|
|
144
|
+
}
|
|
145
|
+
/**
|
|
146
|
+
* Compare the criteria's verdicts against what the database records.
|
|
147
|
+
*
|
|
148
|
+
* This is the part that makes the criteria worth writing down. Anyone can run
|
|
149
|
+
* the audit and diff it against the live board; if the two disagree, either the
|
|
150
|
+
* job has not run or something wrote an invalidation by hand. A criteria engine
|
|
151
|
+
* with no way to check it against reality is just a second opinion.
|
|
152
|
+
*
|
|
153
|
+
* Rows whose artifact went unchecked are skipped for `unreproducible`: a
|
|
154
|
+
* partial run cannot tell "no criterion fires" from "we did not look".
|
|
155
|
+
*/
|
|
156
|
+
export declare function findDrift(verdicts: RowVerdict[]): Drift[];
|
|
157
|
+
//# sourceMappingURL=invalidation-criteria.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"invalidation-criteria.d.ts","sourceRoot":"","sources":["../../src/arena/invalidation-criteria.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AAEH;;;;;;;;;;;;;;GAcG;AACH,eAAO,MAAM,8BAA8B,wDAGjC,CAAC;AAEX,MAAM,MAAM,WAAW,GACnB,WAAW,GACX,uBAAuB,GACvB,wBAAwB,CAAC;AAE7B;;;;;;;GAOG;AACH,eAAO,MAAM,eAAe,EAAE,SAAS,WAAW,EAIjD,CAAC;AAqBF,4DAA4D;AAC5D,MAAM,WAAW,UAAU;IACzB,MAAM,EAAE,MAAM,CAAC;IACf,uEAAuE;IACvE,MAAM,EAAE,MAAM,GAAG,IAAI,CAAC;IACtB,mGAAmG;IACnG,IAAI,EAAE;QACJ,IAAI,EAAE,MAAM,CAAC;QACb,OAAO,EAAE,MAAM,CAAC;QAChB,QAAQ,EAAE,MAAM,CAAC;QACjB,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAC;QACxB,QAAQ,EAAE,MAAM,CAAC;KAClB,GAAG,IAAI,CAAC;IACT,gBAAgB,EAAE,MAAM,GAAG,IAAI,CAAC;IAChC,aAAa,EAAE,MAAM,GAAG,IAAI,CAAC;IAC7B,kBAAkB,EAAE,MAAM,GAAG,IAAI,CAAC;CACnC;AAED,MAAM,WAAW,YAAY;IAC3B,SAAS,EAAE,WAAW,CAAC;IACvB,sFAAsF;IACtF,MAAM,EAAE,MAAM,CAAC;IACf,qDAAqD;IACrD,QAAQ,EAAE,MAAM,CAAC;CAClB;AAED;;;;;;GAMG;AACH,wBAAgB,YAAY,CAAC,GAAG,EAAE,UAAU,GAAG,YAAY,GAAG,IAAI,CAOjE;AAED;;;;;;;;;;;;;;;;;GAiBG;AACH,wBAAgB,uBAAuB,CAAC,GAAG,EAAE,UAAU,GAAG,YAAY,GAAG,IAAI,CAW5E;AAED;;;;;;;;;;GAUG;AACH,wBAAgB,wBAAwB,CACtC,GAAG,EAAE,UAAU,EACf,QAAQ,EAAE,UAAU,GAAG,IAAI,GAC1B,YAAY,GAAG,IAAI,CAerB;AAYD,MAAM,WAAW,UAAU;IACzB,MAAM,EAAE,MAAM,CAAC;IACf,QAAQ,EAAE,MAAM,CAAC;IACjB,iGAAiG;IACjG,SAAS,EAAE,WAAW,GAAG,IAAI,CAAC;IAC9B,MAAM,EAAE,MAAM,GAAG,IAAI,CAAC;IACtB,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAC;IACxB,uFAAuF;IACvF,OAAO,EAAE,YAAY,EAAE,CAAC;IACxB,4FAA4F;IAC5F,iBAAiB,EAAE,OAAO,CAAC;IAC3B,qEAAqE;IACrE,YAAY,EAAE,MAAM,GAAG,IAAI,CAAC;IAC5B,mBAAmB,EAAE,MAAM,GAAG,IAAI,CAAC;CACpC;AAED;;;;;;;GAOG;AACH,wBAAgB,QAAQ,CACtB,GAAG,EAAE,UAAU,EACf,QAAQ,EAAE,UAAU,GAAG,IAAI,EAC3B,IAAI,EAAE;IAAE,eAAe,EAAE,OAAO,CAAA;CAAE,GACjC,UAAU,CA8BZ;AAED,MAAM,MAAM,SAAS;AACnB,iEAAiE;AAC/D,SAAS;AACX,oEAAoE;GAClE,gBAAgB;AAClB,6DAA6D;GAC3D,iBAAiB,CAAC;AAEtB,MAAM,WAAW,KAAK;IACpB,MAAM,EAAE,MAAM,CAAC;IACf,QAAQ,EAAE,MAAM,CAAC;IACjB,IAAI,EAAE,SAAS,CAAC;IAChB,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAC;IACxB,MAAM,EAAE,MAAM,GAAG,IAAI,CAAC;CACvB;AAED;;;;;;;;;;GAUG;AACH,wBAAgB,SAAS,CAAC,QAAQ,EAAE,UAAU,EAAE,GAAG,KAAK,EAAE,CA0BzD"}
|
|
@@ -0,0 +1,236 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* The criteria that disqualify an Arena score — as code, over public data.
|
|
4
|
+
*
|
|
5
|
+
* ADR-319 D2 asks for invalidation to be reproducible rather than curated: no
|
|
6
|
+
* hand-written list of rows to drop, and no criterion that only the maintainer
|
|
7
|
+
* can evaluate. Everything here therefore reads what any anonymous caller can
|
|
8
|
+
* read (`arena_entries`, `genes`, and the public `gene-wasm` bucket), so a
|
|
9
|
+
* third party can run the same criteria and get the same verdicts. A criterion
|
|
10
|
+
* that needed a service key would defeat the point of writing it down.
|
|
11
|
+
*
|
|
12
|
+
* The criteria answer one question: *could this score have come from running
|
|
13
|
+
* the gene, and can anyone check?* They deliberately say nothing about whether
|
|
14
|
+
* a score is flattering or plausible — "0.97 looks too high" is not checkable
|
|
15
|
+
* and would put a human back in the loop that D2 exists to remove.
|
|
16
|
+
*/
|
|
17
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
18
|
+
exports.CRITERION_ORDER = exports.ARTIFACT_ASYNC_EXPRESS_MARKERS = void 0;
|
|
19
|
+
exports.hitsTestData = hitsTestData;
|
|
20
|
+
exports.hitsNoPublishedArtifact = hitsNoPublishedArtifact;
|
|
21
|
+
exports.hitsAsyncExpressArtifact = hitsAsyncExpressArtifact;
|
|
22
|
+
exports.judgeRow = judgeRow;
|
|
23
|
+
exports.findDrift = findDrift;
|
|
24
|
+
/**
|
|
25
|
+
* Artifact-level shapes of an async `express()`.
|
|
26
|
+
*
|
|
27
|
+
* Kept byte-identical to `ASYNC_EXPRESS_MARKERS` in
|
|
28
|
+
* `crates/rotifer-core/src/sandbox/wasmtime_sandbox.rs`, which is what the
|
|
29
|
+
* runtime refuses to execute. If the two lists disagree, the Arena ranks a
|
|
30
|
+
* gene the sandbox will not run — the exact contradiction ADR-319 exists to
|
|
31
|
+
* remove — so `tests/unit/async-express-marker-parity.test.ts` reads the Rust
|
|
32
|
+
* source and fails when they drift.
|
|
33
|
+
*
|
|
34
|
+
* Note this is the *artifact* list, not the source list. The compiler's
|
|
35
|
+
* `detectAsyncExpress()` carries a third pattern (`express(): Promise<…>`)
|
|
36
|
+
* that is a TypeScript type annotation and cannot survive compilation, so it
|
|
37
|
+
* has no artifact-level counterpart by construction, not by omission.
|
|
38
|
+
*/
|
|
39
|
+
exports.ARTIFACT_ASYNC_EXPRESS_MARKERS = [
|
|
40
|
+
"async function express",
|
|
41
|
+
"express = async",
|
|
42
|
+
];
|
|
43
|
+
/**
|
|
44
|
+
* Evaluation order, and the reason for it: each criterion answers a question
|
|
45
|
+
* that only makes sense once the previous one has been ruled out. Asking
|
|
46
|
+
* "does the artifact carry the defect" of a row that has no artifact — or of a
|
|
47
|
+
* row that was never a real gene — produces a true but useless reason. A row
|
|
48
|
+
* is reported under the first criterion it satisfies, and `allHits` keeps the
|
|
49
|
+
* rest so nothing is hidden.
|
|
50
|
+
*/
|
|
51
|
+
exports.CRITERION_ORDER = [
|
|
52
|
+
"test-data",
|
|
53
|
+
"no-published-artifact",
|
|
54
|
+
"async-express-artifact",
|
|
55
|
+
];
|
|
56
|
+
/**
|
|
57
|
+
* Fidelities that promise a published WASM artifact.
|
|
58
|
+
*
|
|
59
|
+
* Native only. The spec's Hybrid tier (L-II, "partially native execution") is
|
|
60
|
+
* headed for a WASM core plus host functions for I/O, and when that lands a
|
|
61
|
+
* Hybrid gene will carry an artifact too. But the shipping Hybrid path is the
|
|
62
|
+
* one the v0.7 plan chose on purpose as an interim: the gene runs under
|
|
63
|
+
* Node.js with a gateway-wrapped fetch injected, and there is no WASM to
|
|
64
|
+
* publish. Holding Hybrid genes to an artifact they were told not to produce
|
|
65
|
+
* would invalidate them for following the toolchain. When the host-function
|
|
66
|
+
* path ships, add "Hybrid" here — and the production rows it then catches
|
|
67
|
+
* will be genuine.
|
|
68
|
+
*
|
|
69
|
+
* This is the one criterion whose answer depends on which Hybrid design is
|
|
70
|
+
* in force, which is why the dependency is written down here rather than left
|
|
71
|
+
* implicit in a set literal.
|
|
72
|
+
*/
|
|
73
|
+
const WASM_BEARING_FIDELITIES = new Set(["Native"]);
|
|
74
|
+
/**
|
|
75
|
+
* `test-data` — the row is tagged as test traffic at submission time.
|
|
76
|
+
*
|
|
77
|
+
* Reads `arena_entries.domain` rather than `genes.domain`: the arena row
|
|
78
|
+
* records what the submitter declared when submitting, which is the claim
|
|
79
|
+
* being judged. A gene can also be renamed or re-domained after the fact.
|
|
80
|
+
*/
|
|
81
|
+
function hitsTestData(row) {
|
|
82
|
+
if ((row.domain || "").trim().toLowerCase() !== "test")
|
|
83
|
+
return null;
|
|
84
|
+
return {
|
|
85
|
+
criterion: "test-data",
|
|
86
|
+
reason: "Submitted under the 'test' domain — test traffic, not a competing gene.",
|
|
87
|
+
evidence: `arena_entries.domain = ${JSON.stringify(row.domain)}`,
|
|
88
|
+
};
|
|
89
|
+
}
|
|
90
|
+
/**
|
|
91
|
+
* `no-published-artifact` — the gene claims a WASM-executing fidelity but has
|
|
92
|
+
* published no artifact.
|
|
93
|
+
*
|
|
94
|
+
* Only Native is WASM-executing today; see WASM_BEARING_FIDELITIES for why
|
|
95
|
+
* Hybrid is not (yet) held to this.
|
|
96
|
+
*
|
|
97
|
+
* The verdict is about *recomputability*, not honesty. The score may well have
|
|
98
|
+
* come from a real local sandbox run; but with no published artifact nobody
|
|
99
|
+
* else can re-run it, and §9.7.1 asks that every published number be one a
|
|
100
|
+
* third party can arrive at independently. So the reason says what is missing,
|
|
101
|
+
* rather than accusing the author of a false declaration.
|
|
102
|
+
*
|
|
103
|
+
* Unpublished genes (`gene === null`) are deliberately *not* caught here. The
|
|
104
|
+
* FK from `arena_entries` cascades on delete, so a row can never be orphaned;
|
|
105
|
+
* an unreadable gene means the author unpublished it, which is a supported
|
|
106
|
+
* action, not a defect.
|
|
107
|
+
*/
|
|
108
|
+
function hitsNoPublishedArtifact(row) {
|
|
109
|
+
if (!row.gene)
|
|
110
|
+
return null;
|
|
111
|
+
if (!WASM_BEARING_FIDELITIES.has(row.gene.fidelity))
|
|
112
|
+
return null;
|
|
113
|
+
if (row.gene.wasmSize > 0)
|
|
114
|
+
return null;
|
|
115
|
+
return {
|
|
116
|
+
criterion: "no-published-artifact",
|
|
117
|
+
reason: `Declares fidelity '${row.gene.fidelity}', which promises an executable WASM artifact, ` +
|
|
118
|
+
"but none is published — so this score cannot be recomputed by anyone (§9.7.1).",
|
|
119
|
+
evidence: `genes.fidelity = ${row.gene.fidelity}, genes.wasm_size = ${row.gene.wasmSize}, genes.wasm_path = ${JSON.stringify(row.gene.wasmPath)}`,
|
|
120
|
+
};
|
|
121
|
+
}
|
|
122
|
+
/**
|
|
123
|
+
* `async-express-artifact` — the published artifact carries an async
|
|
124
|
+
* `express()`, which Javy/QuickJS cannot await.
|
|
125
|
+
*
|
|
126
|
+
* The gene returns a Promise, the shim serialises it to `{}`, and the run
|
|
127
|
+
* exits 0 — so the gene reports success while producing nothing. Any score
|
|
128
|
+
* measured against that output describes the empty object, not the gene.
|
|
129
|
+
*
|
|
130
|
+
* Takes bytes rather than fetching, so the criterion stays a pure function and
|
|
131
|
+
* the caller decides the transport (and can skip the download entirely).
|
|
132
|
+
*/
|
|
133
|
+
function hitsAsyncExpressArtifact(row, artifact) {
|
|
134
|
+
if (!artifact || artifact.length === 0)
|
|
135
|
+
return null;
|
|
136
|
+
const text = Buffer.from(artifact).toString("latin1");
|
|
137
|
+
const found = exports.ARTIFACT_ASYNC_EXPRESS_MARKERS.filter((m) => text.includes(m));
|
|
138
|
+
if (found.length === 0)
|
|
139
|
+
return null;
|
|
140
|
+
return {
|
|
141
|
+
criterion: "async-express-artifact",
|
|
142
|
+
reason: "The published artifact carries an async express(); Javy/QuickJS has no event loop, " +
|
|
143
|
+
"so the gene returns a Promise that serialises to {} and still exits 0. " +
|
|
144
|
+
"The score describes that empty output, not the gene. The sandbox refuses to run it.",
|
|
145
|
+
evidence: found
|
|
146
|
+
.map((m) => `${JSON.stringify(m)} × ${countOccurrences(text, m)}`)
|
|
147
|
+
.join(", "),
|
|
148
|
+
};
|
|
149
|
+
}
|
|
150
|
+
function countOccurrences(haystack, needle) {
|
|
151
|
+
let n = 0;
|
|
152
|
+
let i = haystack.indexOf(needle);
|
|
153
|
+
while (i !== -1) {
|
|
154
|
+
n += 1;
|
|
155
|
+
i = haystack.indexOf(needle, i + needle.length);
|
|
156
|
+
}
|
|
157
|
+
return n;
|
|
158
|
+
}
|
|
159
|
+
/**
|
|
160
|
+
* Apply every criterion to one row.
|
|
161
|
+
*
|
|
162
|
+
* `artifact` is the fetched WASM, or null when it was not fetched. Passing
|
|
163
|
+
* null does not make the row clean — it makes the artifact criterion
|
|
164
|
+
* *unevaluated*, which `artifactUnchecked` reports so a partial run is never
|
|
165
|
+
* mistaken for a clean bill of health.
|
|
166
|
+
*/
|
|
167
|
+
function judgeRow(row, artifact, opts) {
|
|
168
|
+
const hits = [];
|
|
169
|
+
const testData = hitsTestData(row);
|
|
170
|
+
if (testData)
|
|
171
|
+
hits.push(testData);
|
|
172
|
+
const noArtifact = hitsNoPublishedArtifact(row);
|
|
173
|
+
if (noArtifact)
|
|
174
|
+
hits.push(noArtifact);
|
|
175
|
+
const asyncExpress = hitsAsyncExpressArtifact(row, artifact);
|
|
176
|
+
if (asyncExpress)
|
|
177
|
+
hits.push(asyncExpress);
|
|
178
|
+
hits.sort((a, b) => exports.CRITERION_ORDER.indexOf(a.criterion) - exports.CRITERION_ORDER.indexOf(b.criterion));
|
|
179
|
+
const primary = hits[0] || null;
|
|
180
|
+
// A row with no artifact to fetch is fully evaluated, not partially: there is
|
|
181
|
+
// nothing the artifact criterion could have found. Only a row that has an
|
|
182
|
+
// artifact we did not read is genuinely unchecked.
|
|
183
|
+
const hasArtifactToRead = Boolean(row.gene && row.gene.wasmSize > 0);
|
|
184
|
+
return {
|
|
185
|
+
geneId: row.geneId,
|
|
186
|
+
geneName: row.gene?.name || "(unpublished)",
|
|
187
|
+
criterion: primary?.criterion ?? null,
|
|
188
|
+
reason: primary?.reason ?? null,
|
|
189
|
+
evidence: primary?.evidence ?? null,
|
|
190
|
+
allHits: hits,
|
|
191
|
+
artifactUnchecked: hasArtifactToRead && !opts.artifactFetched,
|
|
192
|
+
storedReason: row.invalidationReason,
|
|
193
|
+
storedInvalidatedAt: row.invalidatedAt,
|
|
194
|
+
};
|
|
195
|
+
}
|
|
196
|
+
/**
|
|
197
|
+
* Compare the criteria's verdicts against what the database records.
|
|
198
|
+
*
|
|
199
|
+
* This is the part that makes the criteria worth writing down. Anyone can run
|
|
200
|
+
* the audit and diff it against the live board; if the two disagree, either the
|
|
201
|
+
* job has not run or something wrote an invalidation by hand. A criteria engine
|
|
202
|
+
* with no way to check it against reality is just a second opinion.
|
|
203
|
+
*
|
|
204
|
+
* Rows whose artifact went unchecked are skipped for `unreproducible`: a
|
|
205
|
+
* partial run cannot tell "no criterion fires" from "we did not look".
|
|
206
|
+
*/
|
|
207
|
+
function findDrift(verdicts) {
|
|
208
|
+
const drift = [];
|
|
209
|
+
for (const v of verdicts) {
|
|
210
|
+
const computed = v.criterion;
|
|
211
|
+
const stored = v.storedInvalidatedAt ? v.storedReason : null;
|
|
212
|
+
if (computed && !stored) {
|
|
213
|
+
drift.push({ geneId: v.geneId, geneName: v.geneName, kind: "missing", computed, stored });
|
|
214
|
+
}
|
|
215
|
+
else if (!computed && stored && !v.artifactUnchecked) {
|
|
216
|
+
drift.push({
|
|
217
|
+
geneId: v.geneId,
|
|
218
|
+
geneName: v.geneName,
|
|
219
|
+
kind: "unreproducible",
|
|
220
|
+
computed,
|
|
221
|
+
stored,
|
|
222
|
+
});
|
|
223
|
+
}
|
|
224
|
+
else if (computed && stored && computed !== stored) {
|
|
225
|
+
drift.push({
|
|
226
|
+
geneId: v.geneId,
|
|
227
|
+
geneName: v.geneName,
|
|
228
|
+
kind: "reason-mismatch",
|
|
229
|
+
computed,
|
|
230
|
+
stored,
|
|
231
|
+
});
|
|
232
|
+
}
|
|
233
|
+
}
|
|
234
|
+
return drift;
|
|
235
|
+
}
|
|
236
|
+
//# sourceMappingURL=invalidation-criteria.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"invalidation-criteria.js","sourceRoot":"","sources":["../../src/arena/invalidation-criteria.ts"],"names":[],"mappings":"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"}
|
package/dist/cloud/client.d.ts
CHANGED
|
@@ -24,7 +24,100 @@ export declare function publishGene(opts: {
|
|
|
24
24
|
}): Promise<CloudGene & {
|
|
25
25
|
isUpdate: boolean;
|
|
26
26
|
}>;
|
|
27
|
-
|
|
27
|
+
/** Public URL of a gene's WASM in the `gene-wasm` bucket — no credentials needed. */
|
|
28
|
+
export declare function geneWasmUrl(wasmPath: string): string;
|
|
29
|
+
/** One Arena row with the gene fields the invalidation criteria read. */
|
|
30
|
+
export interface ArenaAuditRow {
|
|
31
|
+
gene_id: string;
|
|
32
|
+
domain: string | null;
|
|
33
|
+
fitness_value: number | null;
|
|
34
|
+
evaluation_method: string | null;
|
|
35
|
+
invalidated_at: string | null;
|
|
36
|
+
invalidation_reason: string | null;
|
|
37
|
+
genes: {
|
|
38
|
+
name: string;
|
|
39
|
+
version: string;
|
|
40
|
+
fidelity: string;
|
|
41
|
+
wasm_path: string | null;
|
|
42
|
+
wasm_size: number | null;
|
|
43
|
+
} | null;
|
|
44
|
+
}
|
|
45
|
+
/**
|
|
46
|
+
* Every Arena row, with its gene, for a criteria audit.
|
|
47
|
+
*
|
|
48
|
+
* Paginated to completion rather than capped: an audit that silently stopped at
|
|
49
|
+
* the first page would report a clean tail it never looked at, which is the
|
|
50
|
+
* failure mode this whole audit exists to catch.
|
|
51
|
+
*
|
|
52
|
+
* `genes` comes back null for unpublished genes — RLS hides them from anonymous
|
|
53
|
+
* callers. That is not an orphaned row: the foreign key cascades on delete.
|
|
54
|
+
*/
|
|
55
|
+
export declare function fetchArenaAuditRows(): Promise<ArenaAuditRow[]>;
|
|
56
|
+
/** The version that was taken down, echoed back from the row the server actually changed. */
|
|
57
|
+
export interface UnpublishedGene {
|
|
58
|
+
id: string;
|
|
59
|
+
name: string;
|
|
60
|
+
version: string;
|
|
61
|
+
}
|
|
62
|
+
/**
|
|
63
|
+
* Take one published version off the public registry.
|
|
64
|
+
*
|
|
65
|
+
* The row is kept and only `published` flips, so nothing that referenced this
|
|
66
|
+
* version — Arena entries, invocation history, another author's dependency —
|
|
67
|
+
* loses its referent. Republishing the same version restores it: `publishGene`
|
|
68
|
+
* refuses to overwrite a *published* version but updates an unpublished one.
|
|
69
|
+
*
|
|
70
|
+
* Reads back the changed row rather than trusting the status code. RLS narrows
|
|
71
|
+
* the UPDATE to rows the caller owns, and an UPDATE that matches nothing is not
|
|
72
|
+
* an error in PostgREST — with `return=minimal` it answers 204, exactly like a
|
|
73
|
+
* successful one. So a caller trying to unpublish someone else's gene would
|
|
74
|
+
* have been told it worked. `return=representation` makes the two
|
|
75
|
+
* distinguishable: no rows back means nothing was changed.
|
|
76
|
+
*
|
|
77
|
+
* The published artifact is deliberately left in storage. An unpublished gene
|
|
78
|
+
* keeps its Arena row, and §9.7.1 asks that any published score stay
|
|
79
|
+
* recomputable — deleting the binary would strand a score with no way to check
|
|
80
|
+
* it, and would blind the `async-express-artifact` criterion that reads exactly
|
|
81
|
+
* that file. (The previous best-effort delete never ran anyway: its URL omitted
|
|
82
|
+
* the bucket segment, so the object path's first component was read as a bucket
|
|
83
|
+
* name and the request failed with `NoSuchBucket` inside a catch that swallowed
|
|
84
|
+
* it. Fixing that URL would have turned a silent no-op into real data loss.)
|
|
85
|
+
*/
|
|
86
|
+
export declare function unpublishGene(id: string): Promise<UnpublishedGene>;
|
|
87
|
+
/**
|
|
88
|
+
* Put an unpublished version back on the public registry.
|
|
89
|
+
*
|
|
90
|
+
* The inverse of `unpublishGene`, and it has to exist as its own call:
|
|
91
|
+
* `publishGene` always writes with a plain POST, so re-running it on a version
|
|
92
|
+
* that is merely unpublished collides with
|
|
93
|
+
* `genes_owner_id_name_version_key (owner_id, name, version)` instead of
|
|
94
|
+
* restoring it. Without this, unpublishing would be a one-way door for an
|
|
95
|
+
* author — the version could only come back under a new number.
|
|
96
|
+
*
|
|
97
|
+
* Immutability is preserved rather than bent: nothing but the `published` flag
|
|
98
|
+
* moves, so the artifact and content hash that were published under this
|
|
99
|
+
* version are the ones that come back.
|
|
100
|
+
*
|
|
101
|
+
* Same zero-row check as unpublish, for the same reason — RLS narrows the
|
|
102
|
+
* UPDATE and PostgREST does not treat "matched nothing" as an error.
|
|
103
|
+
*/
|
|
104
|
+
export declare function republishGene(id: string): Promise<UnpublishedGene>;
|
|
105
|
+
/** One of the caller's own versions, for resolving what `unpublish` should act on. */
|
|
106
|
+
export interface OwnedGeneVersion {
|
|
107
|
+
id: string;
|
|
108
|
+
name: string;
|
|
109
|
+
version: string;
|
|
110
|
+
published: boolean;
|
|
111
|
+
created_at: string;
|
|
112
|
+
}
|
|
113
|
+
/**
|
|
114
|
+
* The caller's own versions of a gene, newest first.
|
|
115
|
+
*
|
|
116
|
+
* Scoped to `owner_id` rather than searching the public registry: only an author
|
|
117
|
+
* can unpublish, so resolving a bare name against someone else's gene would only
|
|
118
|
+
* produce a confusing permission error later.
|
|
119
|
+
*/
|
|
120
|
+
export declare function listOwnGeneVersions(name: string): Promise<OwnedGeneVersion[]>;
|
|
28
121
|
export declare function downloadGeneWasm(wasmUrl: string): Promise<Buffer>;
|
|
29
122
|
export declare function trackDownload(geneId: string, source?: "cli" | "mcp" | "api" | "web"): Promise<void>;
|
|
30
123
|
/** One sandbox run's raw measurements (ADR-319 D3). */
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"client.d.ts","sourceRoot":"","sources":["../../src/cloud/client.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EACV,WAAW,EACX,SAAS,EACT,qBAAqB,EACrB,kBAAkB,EAClB,eAAe,EACf,aAAa,EACb,mBAAmB,EACpB,MAAM,YAAY,CAAC;AAUpB,wBAAgB,eAAe,IAAI,WAAW,CAa7C;AAoID,wBAAsB,SAAS,CAAC,OAAO,EAAE;IACvC,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB,GAAG,OAAO,CAAC,qBAAqB,CAAC,CAiDjC;AAED,wBAAsB,OAAO,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,SAAS,CAAC,
|
|
1
|
+
{"version":3,"file":"client.d.ts","sourceRoot":"","sources":["../../src/cloud/client.ts"],"names":[],"mappings":"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"}
|