@timurproko/a1 0.1.8-dev.259 → 0.1.8-dev.260
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/foundation/release/bootstrap.d.ts +2 -0
- package/dist/foundation/release/bootstrap.js +4 -0
- package/dist/foundation/release/dependency-layer.d.ts +5 -1
- package/dist/foundation/release/dependency-layer.js +15 -6
- package/dist/foundation/release/release-store.d.ts +4 -2
- package/dist/foundation/release/release-store.js +4 -4
- package/dist/foundation/supervision/main.js +5 -2
- package/dist/native/darwin-arm64/manifest.json +1 -1
- package/dist/native/linux-x64/manifest.json +1 -1
- package/dist/native/win32-x64/manifest.json +2 -2
- package/dist/native/win32-x64/process-guardian.exe +0 -0
- package/package.json +1 -1
|
@@ -27,6 +27,8 @@ export interface BootstrapOptions {
|
|
|
27
27
|
}
|
|
28
28
|
export declare function runBootstrap(options: BootstrapOptions): Promise<number>;
|
|
29
29
|
export declare function certifyMaterializedRelease(release: MaterializedRelease, dataDir: string, verification?: VerifyMaterializedReleaseOptions): Promise<string>;
|
|
30
|
+
/** Persist current-format evidence after an authenticated parent has certified the exact release. */
|
|
31
|
+
export declare function recordParentCertifiedRelease(release: MaterializedRelease, dataDir: string): Promise<string>;
|
|
30
32
|
export interface SupervisorStartupAttempt extends SupervisorStartupAttemptIdentity {
|
|
31
33
|
readonly childOutcome: Promise<{
|
|
32
34
|
readonly exitCode: number | null;
|
|
@@ -193,6 +193,10 @@ export async function certifyMaterializedRelease(release, dataDir, verification
|
|
|
193
193
|
if (!consumeMaterializationProof(release)) {
|
|
194
194
|
await verifyMaterializedRelease(release.releaseRoot, release, resolve(dataDir, "releases"), verification);
|
|
195
195
|
}
|
|
196
|
+
return await recordParentCertifiedRelease(release, dataDir);
|
|
197
|
+
}
|
|
198
|
+
/** Persist current-format evidence after an authenticated parent has certified the exact release. */
|
|
199
|
+
export async function recordParentCertifiedRelease(release, dataDir) {
|
|
196
200
|
const path = resolve(dataDir, `certification-${release.releaseId}.json`);
|
|
197
201
|
const restartSeal = await createRestartSeal(release, dataDir);
|
|
198
202
|
await chmod(path, 0o600).catch(() => { });
|
|
@@ -37,6 +37,10 @@ export interface DependencyLayerOperationEvent {
|
|
|
37
37
|
readonly path: string;
|
|
38
38
|
readonly bytes: number;
|
|
39
39
|
}
|
|
40
|
+
export interface ReadCertifiedDependencyLayerOptions {
|
|
41
|
+
/** Accept and replace certification written by the immediately preceding updater format. */
|
|
42
|
+
readonly allowLegacyParentCertification?: boolean;
|
|
43
|
+
}
|
|
40
44
|
export interface SelectedRuntimePayload {
|
|
41
45
|
readonly paths: readonly string[];
|
|
42
46
|
readonly inventory: RuntimePayloadInventory;
|
|
@@ -71,7 +75,7 @@ export interface MaterializeDependencyLayerOptions {
|
|
|
71
75
|
/** Materialize or reuse an exact immutable dependency layer after one source-content pass. */
|
|
72
76
|
export declare function materializeDependencyLayer(packageRoot: string, dataDir: string, paths: readonly string[], options: MaterializeDependencyLayerOptions): Promise<MaterializedDependencyLayer | null>;
|
|
73
77
|
/** Read trusted layer certification and canonical metadata without rereading every payload byte. */
|
|
74
|
-
export declare function readCertifiedDependencyLayer(dataDir: string, layerId: string, expected?: Pick<DependencyLayerIdentity, "layerId" | "contentDigest"
|
|
78
|
+
export declare function readCertifiedDependencyLayer(dataDir: string, layerId: string, expected?: Pick<DependencyLayerIdentity, "layerId" | "contentDigest">, options?: ReadCertifiedDependencyLayerOptions): Promise<Omit<MaterializedDependencyLayer, "reused">>;
|
|
75
79
|
/** Fully verify a layer when certification is absent or explicit tamper evidence is required. */
|
|
76
80
|
export declare function verifyDependencyLayer(dataDir: string, reference: DependencyLayerReference, onOperation?: (event: DependencyLayerOperationEvent) => void): Promise<Omit<MaterializedDependencyLayer, "reused">>;
|
|
77
81
|
export declare function dependencyReference(layer: MaterializedDependencyLayer): DependencyLayerReference;
|
|
@@ -269,7 +269,7 @@ export async function materializeDependencyLayer(packageRoot, dataDir, paths, op
|
|
|
269
269
|
}
|
|
270
270
|
}
|
|
271
271
|
/** Read trusted layer certification and canonical metadata without rereading every payload byte. */
|
|
272
|
-
export async function readCertifiedDependencyLayer(dataDir, layerId, expected) {
|
|
272
|
+
export async function readCertifiedDependencyLayer(dataDir, layerId, expected, options = {}) {
|
|
273
273
|
const layersRoot = await realpath(resolve(dataDir, "dependency-layers"));
|
|
274
274
|
const layerRoot = await realpath(resolveWithin(layersRoot, layerId));
|
|
275
275
|
assertDirectChild(layersRoot, layerRoot);
|
|
@@ -278,14 +278,23 @@ export async function readCertifiedDependencyLayer(dataDir, layerId, expected) {
|
|
|
278
278
|
throw new Error(`dependency layer is not a managed non-link directory: ${layerId}`);
|
|
279
279
|
const manifest = JSON.parse(await readFile(resolve(layerRoot, DEPENDENCY_LAYER_MANIFEST), "utf8"));
|
|
280
280
|
validateLayerManifest(manifest);
|
|
281
|
-
const certification = JSON.parse(await readFile(certificationPath(dataDir, layerId), "utf8"));
|
|
282
|
-
if (certification.schema !== PRODUCT_IDENTITY.evidence.dependencyLayerCertificationSchema || certification.layerId !== manifest.layerId || certification.contentDigest !== manifest.contentDigest
|
|
283
|
-
|| certification.platform !== process.platform || certification.platformPolicy !== immutablePlatformPolicy()) {
|
|
284
|
-
throw new Error(`dependency layer certification differs from manifest: ${layerId}`);
|
|
285
|
-
}
|
|
286
281
|
if (expected && (expected.layerId !== manifest.layerId || expected.contentDigest !== manifest.contentDigest)) {
|
|
287
282
|
throw new Error(`dependency layer identity mismatch: ${layerId}`);
|
|
288
283
|
}
|
|
284
|
+
const certification = JSON.parse(await readFile(certificationPath(dataDir, layerId), "utf8"));
|
|
285
|
+
const identityMatches = certification.schema === PRODUCT_IDENTITY.evidence.dependencyLayerCertificationSchema
|
|
286
|
+
&& certification.layerId === manifest.layerId && certification.contentDigest === manifest.contentDigest;
|
|
287
|
+
const currentPlatformEvidence = certification.platform === process.platform && certification.platformPolicy === immutablePlatformPolicy();
|
|
288
|
+
// Compatibility: the updater that introduced layers certified these exact identities but did
|
|
289
|
+
// not record platform fields. Only an authenticated parent-started supervisor opts into this
|
|
290
|
+
// transition; durable/reuse readers remain strict and cannot treat the legacy marker as authority.
|
|
291
|
+
const legacyParentCertification = options.allowLegacyParentCertification === true
|
|
292
|
+
&& certification.platform === undefined && certification.platformPolicy === undefined;
|
|
293
|
+
if (!identityMatches || (!currentPlatformEvidence && !legacyParentCertification)) {
|
|
294
|
+
throw new Error(`dependency layer certification differs from manifest: ${layerId}`);
|
|
295
|
+
}
|
|
296
|
+
if (legacyParentCertification)
|
|
297
|
+
await writeLayerCertification(dataDir, manifest);
|
|
289
298
|
return { ...manifest, layerRoot };
|
|
290
299
|
}
|
|
291
300
|
/** Fully verify a layer when certification is absent or explicit tamper evidence is required. */
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { type ReleaseIdentity } from "./release.js";
|
|
2
|
-
import { type RuntimePayloadInventory } from "./dependency-layer.js";
|
|
2
|
+
import { type ReadCertifiedDependencyLayerOptions, type RuntimePayloadInventory } from "./dependency-layer.js";
|
|
3
3
|
export declare const RELEASE_MANIFEST_FILENAME: string;
|
|
4
4
|
export interface MaterializedRelease extends ReleaseIdentity {
|
|
5
5
|
readonly releaseRoot: string;
|
|
@@ -29,6 +29,8 @@ export interface CertifiedReleaseRecord {
|
|
|
29
29
|
readonly packageVersion?: string;
|
|
30
30
|
readonly contentDigest: string;
|
|
31
31
|
}
|
|
32
|
+
/** Process-authority compatibility controls for metadata-only release loading. */
|
|
33
|
+
export type ReadCertifiedReleaseManifestOptions = ReadCertifiedDependencyLayerOptions;
|
|
32
34
|
export declare function materializeRelease(packageRoot: string, dataDir: string, options?: MaterializeReleaseOptions): Promise<MaterializedRelease>;
|
|
33
35
|
/** Consume proof that this exact object was freshly materialized or fully verified in this process. */
|
|
34
36
|
export declare function consumeMaterializationProof(release: MaterializedRelease): boolean;
|
|
@@ -39,7 +41,7 @@ export declare function readMaterializedRelease(releaseRoot: string, selectedSto
|
|
|
39
41
|
* establish one of those preconditions; untrusted releases require full
|
|
40
42
|
* verification.
|
|
41
43
|
*/
|
|
42
|
-
export declare function readCertifiedReleaseManifest(record: CertifiedReleaseRecord, selectedStoreRoot: string): Promise<MaterializedRelease>;
|
|
44
|
+
export declare function readCertifiedReleaseManifest(record: CertifiedReleaseRecord, selectedStoreRoot: string, options?: ReadCertifiedReleaseManifestOptions): Promise<MaterializedRelease>;
|
|
43
45
|
export declare function verifyMaterializedRelease(releaseRoot: string, expected?: ReleaseIdentity, selectedStoreRoot?: string, options?: VerifyMaterializedReleaseOptions): Promise<MaterializedRelease>;
|
|
44
46
|
export declare function assertImmutableExecutionRoot(release: MaterializedRelease, dataDir: string): Promise<void>;
|
|
45
47
|
export declare function resolveReleaseEntryPoint(release: MaterializedRelease, entryPoint: string): Promise<string>;
|
|
@@ -106,7 +106,7 @@ export async function readMaterializedRelease(releaseRoot, selectedStoreRoot) {
|
|
|
106
106
|
* establish one of those preconditions; untrusted releases require full
|
|
107
107
|
* verification.
|
|
108
108
|
*/
|
|
109
|
-
export async function readCertifiedReleaseManifest(record, selectedStoreRoot) {
|
|
109
|
+
export async function readCertifiedReleaseManifest(record, selectedStoreRoot, options = {}) {
|
|
110
110
|
const canonical = await realpath(record.releaseRoot);
|
|
111
111
|
const canonicalStoreRoot = await realpath(selectedStoreRoot);
|
|
112
112
|
assertContained(canonicalStoreRoot, canonical, "release root is outside the selected release store");
|
|
@@ -118,7 +118,7 @@ export async function readCertifiedReleaseManifest(record, selectedStoreRoot) {
|
|
|
118
118
|
}
|
|
119
119
|
if (canonical.split(sep).at(-1) !== manifest.releaseId)
|
|
120
120
|
throw new Error(`release directory does not match identity ${manifest.releaseId}`);
|
|
121
|
-
await verifyReleaseDependencies(canonical, canonicalStoreRoot, manifest.dependencyLayers ?? [], false);
|
|
121
|
+
await verifyReleaseDependencies(canonical, canonicalStoreRoot, manifest.dependencyLayers ?? [], false, {}, options);
|
|
122
122
|
return { ...manifest, releaseRoot: canonical };
|
|
123
123
|
}
|
|
124
124
|
export async function verifyMaterializedRelease(releaseRoot, expected, selectedStoreRoot, options = {}) {
|
|
@@ -162,7 +162,7 @@ export async function resolveReleaseEntryPoint(release, entryPoint) {
|
|
|
162
162
|
assertContained(release.releaseRoot, canonical, "entry point resolves outside the selected release root");
|
|
163
163
|
return canonical;
|
|
164
164
|
}
|
|
165
|
-
async function verifyReleaseDependencies(releaseRoot, storeRoot, references, fullVerification, options = {}) {
|
|
165
|
+
async function verifyReleaseDependencies(releaseRoot, storeRoot, references, fullVerification, options = {}, certificationOptions = {}) {
|
|
166
166
|
if (references.length === 0)
|
|
167
167
|
return;
|
|
168
168
|
if (references.length !== 1)
|
|
@@ -171,7 +171,7 @@ async function verifyReleaseDependencies(releaseRoot, storeRoot, references, ful
|
|
|
171
171
|
const reference = references[0];
|
|
172
172
|
const layer = fullVerification
|
|
173
173
|
? await verifyDependencyLayer(dataDir, reference, event => options.onOperation?.({ operation: event.operation, path: event.path, bytes: event.bytes }))
|
|
174
|
-
: await readCertifiedDependencyLayer(dataDir, reference.layerId, reference);
|
|
174
|
+
: await readCertifiedDependencyLayer(dataDir, reference.layerId, reference, certificationOptions);
|
|
175
175
|
const binding = resolveWithin(releaseRoot, reference.binding);
|
|
176
176
|
const metadata = await lstat(binding);
|
|
177
177
|
if (!metadata.isSymbolicLink())
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { randomUUID } from "node:crypto";
|
|
2
2
|
import { appendFileSync, mkdirSync } from "node:fs";
|
|
3
3
|
import { resolve } from "node:path";
|
|
4
|
-
import { assertImmutableExecutionRoot, CohortStateStore, readCertifiedReleaseManifest } from "../release/index.js";
|
|
4
|
+
import { assertImmutableExecutionRoot, CohortStateStore, readCertifiedReleaseManifest, recordParentCertifiedRelease } from "../release/index.js";
|
|
5
5
|
import { publishSupervisorStartupResult, supervisorStartupFailure, supervisorStartupReady, supervisorStartupResultPath } from "../lifecycle/index.js";
|
|
6
6
|
import { ControlStore } from "../storage/index.js";
|
|
7
7
|
import { resolveCohortEndpoint, resolveProductPaths } from "./paths.js";
|
|
@@ -24,7 +24,10 @@ export async function runSupervisor(arguments_ = []) {
|
|
|
24
24
|
if (!releaseRoot || !releaseId || !contentDigest)
|
|
25
25
|
throw new Error(PRODUCT_TEXT.diagnostic("supervisor must be launched from a verified immutable release"));
|
|
26
26
|
stage = "release-certification";
|
|
27
|
-
const release = await readCertifiedReleaseManifest({ releaseRoot, releaseId, contentDigest }, resolve(paths.dataDir, "releases"));
|
|
27
|
+
const release = await readCertifiedReleaseManifest({ releaseRoot, releaseId, contentDigest }, resolve(paths.dataDir, "releases"), { allowLegacyParentCertification: true });
|
|
28
|
+
// Compatibility: an older updater may have written release evidence before restart seals
|
|
29
|
+
// existed, even when its layer certification has already been upgraded by a retry.
|
|
30
|
+
await recordParentCertifiedRelease(release, paths.dataDir);
|
|
28
31
|
stage = "immutable-root";
|
|
29
32
|
await assertImmutableExecutionRoot(release, paths.dataDir);
|
|
30
33
|
// Protocol: one endpoint per cohort: a superseded cohort keeps serving what it already has while the
|
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
"platform": "darwin",
|
|
6
6
|
"architecture": "arm64",
|
|
7
7
|
"capability": "supported",
|
|
8
|
-
"builtAt": "2026-09-
|
|
8
|
+
"builtAt": "2026-09-06T12:29:18.472Z",
|
|
9
9
|
"artifact": {
|
|
10
10
|
"filename": "process-guardian",
|
|
11
11
|
"sha256": "dc03605e5780e2aeebb4ecafd62868dc673e22ddd38b024a369aff704ff136dc",
|
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
"platform": "linux",
|
|
6
6
|
"architecture": "x64",
|
|
7
7
|
"capability": "supported",
|
|
8
|
-
"builtAt": "2026-09-
|
|
8
|
+
"builtAt": "2026-09-06T12:29:19.551Z",
|
|
9
9
|
"artifact": {
|
|
10
10
|
"filename": "process-guardian",
|
|
11
11
|
"sha256": "ee8a00eaaf79c707459bbbfb52518e9739314967049fbe5fa625f36ce33db9ee",
|
|
@@ -5,10 +5,10 @@
|
|
|
5
5
|
"platform": "win32",
|
|
6
6
|
"architecture": "x64",
|
|
7
7
|
"capability": "supported",
|
|
8
|
-
"builtAt": "2026-09-
|
|
8
|
+
"builtAt": "2026-09-06T12:30:04.599Z",
|
|
9
9
|
"artifact": {
|
|
10
10
|
"filename": "process-guardian.exe",
|
|
11
|
-
"sha256": "
|
|
11
|
+
"sha256": "ce28943a65f5bdd6fd5a2c8b7d513a87402652e9c9089fb3a0b6323083fdd9d2",
|
|
12
12
|
"size": 177664
|
|
13
13
|
},
|
|
14
14
|
"provenance": {
|
|
Binary file
|