@h-rig/kernel-seed 0.0.6-alpha.135 → 0.0.6-alpha.136
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/dist/src/index.d.ts +1 -0
- package/dist/src/index.js +34 -0
- package/dist/src/journalConformance.d.ts +22 -0
- package/dist/src/journalConformance.js +34 -0
- package/dist/src/pluginAbi.d.ts +8 -0
- package/dist/src/seed.js +33 -0
- package/package.json +2 -2
package/dist/src/index.d.ts
CHANGED
package/dist/src/index.js
CHANGED
|
@@ -1,4 +1,33 @@
|
|
|
1
1
|
// @bun
|
|
2
|
+
// packages/kernel-seed/src/journalConformance.ts
|
|
3
|
+
class JournalConformanceError extends Error {
|
|
4
|
+
name = "JournalConformanceError";
|
|
5
|
+
}
|
|
6
|
+
var CONFORMANCE_RUN_ID = "rig.kernel.__journal-conformance__";
|
|
7
|
+
function sampleResolvedPipeline() {
|
|
8
|
+
return {
|
|
9
|
+
order: ["validate", "merge-gate"],
|
|
10
|
+
record: [
|
|
11
|
+
{ stageId: "validate", contributedBy: "default", isProtected: false },
|
|
12
|
+
{ stageId: "merge-gate", contributedBy: "default", isProtected: true }
|
|
13
|
+
],
|
|
14
|
+
cycles: [],
|
|
15
|
+
grantUses: [],
|
|
16
|
+
resolvedAt: "1970-01-01T00:00:00.000Z"
|
|
17
|
+
};
|
|
18
|
+
}
|
|
19
|
+
async function assertJournalConformance(journal, runId = CONFORMANCE_RUN_ID) {
|
|
20
|
+
const pipeline = sampleResolvedPipeline();
|
|
21
|
+
await journal.recordPipeline(runId, pipeline);
|
|
22
|
+
const events = await journal.read(runId);
|
|
23
|
+
if (!Array.isArray(events) || events.length === 0) {
|
|
24
|
+
throw new JournalConformanceError("journal.read returned no records after recordPipeline \u2014 provider does not durably record (append-and-record contract violated)");
|
|
25
|
+
}
|
|
26
|
+
const serialized = JSON.stringify(events);
|
|
27
|
+
if (!serialized.includes("merge-gate") || !serialized.includes("validate")) {
|
|
28
|
+
throw new JournalConformanceError("journal.read did not surface the recorded resolved-pipeline \u2014 provider does not expose the append-and-record contract");
|
|
29
|
+
}
|
|
30
|
+
}
|
|
2
31
|
// packages/kernel-seed/src/pluginAbi.ts
|
|
3
32
|
function loadedPluginId(plugin) {
|
|
4
33
|
return plugin.meta.id;
|
|
@@ -151,6 +180,9 @@ async function boot(config) {
|
|
|
151
180
|
throw new BootIncoherent("no kernel provider resolved");
|
|
152
181
|
}
|
|
153
182
|
assertSatisfiesKernelInterface(resolution.value);
|
|
183
|
+
if (config.verifyJournalConformance === true) {
|
|
184
|
+
await assertJournalConformance(resolution.value.journal);
|
|
185
|
+
}
|
|
154
186
|
return { kernel: resolution.value, plugins };
|
|
155
187
|
}
|
|
156
188
|
export {
|
|
@@ -159,6 +191,8 @@ export {
|
|
|
159
191
|
declaresReplacement,
|
|
160
192
|
boot,
|
|
161
193
|
assertSatisfiesKernelInterface,
|
|
194
|
+
assertJournalConformance,
|
|
195
|
+
JournalConformanceError,
|
|
162
196
|
CapabilityProviderMissingError,
|
|
163
197
|
BootIncoherent,
|
|
164
198
|
AmbiguousCapabilityError
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import type { JournalCapability } from "@rig/contracts";
|
|
2
|
+
/**
|
|
3
|
+
* Raised when a `journal` capability provider passes the *structural* check
|
|
4
|
+
* (append/recordPipeline/read present) but does not actually durably record —
|
|
5
|
+
* e.g. a no-op stub that would silently erase the audit trail / safety backstop.
|
|
6
|
+
*/
|
|
7
|
+
export declare class JournalConformanceError extends Error {
|
|
8
|
+
readonly name = "JournalConformanceError";
|
|
9
|
+
}
|
|
10
|
+
/**
|
|
11
|
+
* Behavioral journal-append conformance — the fixed contract every `journal`
|
|
12
|
+
* provider must satisfy (see the Journal-Append Invariant). The storage backend
|
|
13
|
+
* is swappable; the guarantee that the resolved-pipeline record is durably
|
|
14
|
+
* appended and exposed for projection is NOT. A structurally-complete no-op
|
|
15
|
+
* stub (all three methods present, recording nothing) fails this, which is the
|
|
16
|
+
* whole point: observability is the safety backstop, so a journal that does not
|
|
17
|
+
* record must be rejected — not merely accepted because it has the right shape.
|
|
18
|
+
*
|
|
19
|
+
* Uses a clearly-namespaced probe runId so the record is identifiable and
|
|
20
|
+
* harmless to real-run projections (which filter by the actual runId).
|
|
21
|
+
*/
|
|
22
|
+
export declare function assertJournalConformance(journal: JournalCapability, runId?: string): Promise<void>;
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
// @bun
|
|
2
|
+
// packages/kernel-seed/src/journalConformance.ts
|
|
3
|
+
class JournalConformanceError extends Error {
|
|
4
|
+
name = "JournalConformanceError";
|
|
5
|
+
}
|
|
6
|
+
var CONFORMANCE_RUN_ID = "rig.kernel.__journal-conformance__";
|
|
7
|
+
function sampleResolvedPipeline() {
|
|
8
|
+
return {
|
|
9
|
+
order: ["validate", "merge-gate"],
|
|
10
|
+
record: [
|
|
11
|
+
{ stageId: "validate", contributedBy: "default", isProtected: false },
|
|
12
|
+
{ stageId: "merge-gate", contributedBy: "default", isProtected: true }
|
|
13
|
+
],
|
|
14
|
+
cycles: [],
|
|
15
|
+
grantUses: [],
|
|
16
|
+
resolvedAt: "1970-01-01T00:00:00.000Z"
|
|
17
|
+
};
|
|
18
|
+
}
|
|
19
|
+
async function assertJournalConformance(journal, runId = CONFORMANCE_RUN_ID) {
|
|
20
|
+
const pipeline = sampleResolvedPipeline();
|
|
21
|
+
await journal.recordPipeline(runId, pipeline);
|
|
22
|
+
const events = await journal.read(runId);
|
|
23
|
+
if (!Array.isArray(events) || events.length === 0) {
|
|
24
|
+
throw new JournalConformanceError("journal.read returned no records after recordPipeline \u2014 provider does not durably record (append-and-record contract violated)");
|
|
25
|
+
}
|
|
26
|
+
const serialized = JSON.stringify(events);
|
|
27
|
+
if (!serialized.includes("merge-gate") || !serialized.includes("validate")) {
|
|
28
|
+
throw new JournalConformanceError("journal.read did not surface the recorded resolved-pipeline \u2014 provider does not expose the append-and-record contract");
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
export {
|
|
32
|
+
assertJournalConformance,
|
|
33
|
+
JournalConformanceError
|
|
34
|
+
};
|
package/dist/src/pluginAbi.d.ts
CHANGED
|
@@ -23,6 +23,14 @@ export type ResolvedBootConfig = {
|
|
|
23
23
|
readonly plugins?: readonly LoadedPlugin[];
|
|
24
24
|
readonly loadPlugins?: () => Promise<readonly LoadedPlugin[]> | readonly LoadedPlugin[];
|
|
25
25
|
readonly capabilityPrecedence?: CapabilityPrecedence;
|
|
26
|
+
/**
|
|
27
|
+
* When true, boot runs the behavioral journal-append conformance probe
|
|
28
|
+
* against the resolved kernel's journal (rejecting a structurally-complete
|
|
29
|
+
* no-op provider). Off by default to avoid writing a probe record into a live
|
|
30
|
+
* run journal on every boot; opt-in for managed/multi-tenant postures and
|
|
31
|
+
* exercised directly by the conformance test.
|
|
32
|
+
*/
|
|
33
|
+
readonly verifyJournalConformance?: boolean;
|
|
26
34
|
};
|
|
27
35
|
export type BootResult = {
|
|
28
36
|
readonly kernel: KernelCapability;
|
package/dist/src/seed.js
CHANGED
|
@@ -1,4 +1,34 @@
|
|
|
1
1
|
// @bun
|
|
2
|
+
// packages/kernel-seed/src/journalConformance.ts
|
|
3
|
+
class JournalConformanceError extends Error {
|
|
4
|
+
name = "JournalConformanceError";
|
|
5
|
+
}
|
|
6
|
+
var CONFORMANCE_RUN_ID = "rig.kernel.__journal-conformance__";
|
|
7
|
+
function sampleResolvedPipeline() {
|
|
8
|
+
return {
|
|
9
|
+
order: ["validate", "merge-gate"],
|
|
10
|
+
record: [
|
|
11
|
+
{ stageId: "validate", contributedBy: "default", isProtected: false },
|
|
12
|
+
{ stageId: "merge-gate", contributedBy: "default", isProtected: true }
|
|
13
|
+
],
|
|
14
|
+
cycles: [],
|
|
15
|
+
grantUses: [],
|
|
16
|
+
resolvedAt: "1970-01-01T00:00:00.000Z"
|
|
17
|
+
};
|
|
18
|
+
}
|
|
19
|
+
async function assertJournalConformance(journal, runId = CONFORMANCE_RUN_ID) {
|
|
20
|
+
const pipeline = sampleResolvedPipeline();
|
|
21
|
+
await journal.recordPipeline(runId, pipeline);
|
|
22
|
+
const events = await journal.read(runId);
|
|
23
|
+
if (!Array.isArray(events) || events.length === 0) {
|
|
24
|
+
throw new JournalConformanceError("journal.read returned no records after recordPipeline \u2014 provider does not durably record (append-and-record contract violated)");
|
|
25
|
+
}
|
|
26
|
+
const serialized = JSON.stringify(events);
|
|
27
|
+
if (!serialized.includes("merge-gate") || !serialized.includes("validate")) {
|
|
28
|
+
throw new JournalConformanceError("journal.read did not surface the recorded resolved-pipeline \u2014 provider does not expose the append-and-record contract");
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
|
|
2
32
|
// packages/kernel-seed/src/pluginAbi.ts
|
|
3
33
|
function loadedPluginId(plugin) {
|
|
4
34
|
return plugin.meta.id;
|
|
@@ -147,6 +177,9 @@ async function boot(config) {
|
|
|
147
177
|
throw new BootIncoherent("no kernel provider resolved");
|
|
148
178
|
}
|
|
149
179
|
assertSatisfiesKernelInterface(resolution.value);
|
|
180
|
+
if (config.verifyJournalConformance === true) {
|
|
181
|
+
await assertJournalConformance(resolution.value.journal);
|
|
182
|
+
}
|
|
150
183
|
return { kernel: resolution.value, plugins };
|
|
151
184
|
}
|
|
152
185
|
export {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@h-rig/kernel-seed",
|
|
3
|
-
"version": "0.0.6-alpha.
|
|
3
|
+
"version": "0.0.6-alpha.136",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"description": "Irreducible Rig bootstrap seed, plugin ABI, and capability resolver.",
|
|
6
6
|
"license": "UNLICENSED",
|
|
@@ -33,6 +33,6 @@
|
|
|
33
33
|
"module": "./dist/src/index.js",
|
|
34
34
|
"types": "./dist/src/index.d.ts",
|
|
35
35
|
"dependencies": {
|
|
36
|
-
"@rig/contracts": "npm:@h-rig/contracts@0.0.6-alpha.
|
|
36
|
+
"@rig/contracts": "npm:@h-rig/contracts@0.0.6-alpha.136"
|
|
37
37
|
}
|
|
38
38
|
}
|