@airprompter/agent-core 0.1.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/README.md +28 -0
- package/dist/cjs/bundle/apbundle.js +98 -0
- package/dist/cjs/bundle/apbundle.js.map +1 -0
- package/dist/cjs/bundle/hpke.js +120 -0
- package/dist/cjs/bundle/hpke.js.map +1 -0
- package/dist/cjs/checks/index.js +450 -0
- package/dist/cjs/checks/index.js.map +1 -0
- package/dist/cjs/control/client.js +85 -0
- package/dist/cjs/control/client.js.map +1 -0
- package/dist/cjs/golden/index.js +138 -0
- package/dist/cjs/golden/index.js.map +1 -0
- package/dist/cjs/index.js +125 -0
- package/dist/cjs/index.js.map +1 -0
- package/dist/cjs/judge/index.js +134 -0
- package/dist/cjs/judge/index.js.map +1 -0
- package/dist/cjs/package.json +1 -0
- package/dist/cjs/ports/node.js +30 -0
- package/dist/cjs/ports/node.js.map +1 -0
- package/dist/cjs/protocol/assignment.js +158 -0
- package/dist/cjs/protocol/assignment.js.map +1 -0
- package/dist/cjs/protocol/canonicalJson.js +72 -0
- package/dist/cjs/protocol/canonicalJson.js.map +1 -0
- package/dist/cjs/protocol/errors.js +22 -0
- package/dist/cjs/protocol/errors.js.map +1 -0
- package/dist/cjs/protocol/ports.js +19 -0
- package/dist/cjs/protocol/ports.js.map +1 -0
- package/dist/cjs/protocol/trust.js +225 -0
- package/dist/cjs/protocol/trust.js.map +1 -0
- package/dist/cjs/protocol/types.js +15 -0
- package/dist/cjs/protocol/types.js.map +1 -0
- package/dist/cjs/protocol/version.js +8 -0
- package/dist/cjs/protocol/version.js.map +1 -0
- package/dist/cjs/release/bundleRelease.js +61 -0
- package/dist/cjs/release/bundleRelease.js.map +1 -0
- package/dist/cjs/release/reader.js +12 -0
- package/dist/cjs/release/reader.js.map +1 -0
- package/dist/cjs/render/runRef.js +33 -0
- package/dist/cjs/render/runRef.js.map +1 -0
- package/dist/cjs/render/template.js +71 -0
- package/dist/cjs/render/template.js.map +1 -0
- package/dist/cjs/telemetry/feedback.js +81 -0
- package/dist/cjs/telemetry/feedback.js.map +1 -0
- package/dist/cjs/telemetry/rows.js +28 -0
- package/dist/cjs/telemetry/rows.js.map +1 -0
- package/dist/cjs/telemetry/uploadSink.js +13 -0
- package/dist/cjs/telemetry/uploadSink.js.map +1 -0
- package/dist/cjs/testing/controlPlane.js +381 -0
- package/dist/cjs/testing/controlPlane.js.map +1 -0
- package/dist/cjs/testing/index.js +45 -0
- package/dist/cjs/testing/index.js.map +1 -0
- package/dist/cjs/testing/memoryFs.js +236 -0
- package/dist/cjs/testing/memoryFs.js.map +1 -0
- package/dist/esm/.tsbuildinfo +1 -0
- package/dist/esm/bundle/apbundle.d.ts +33 -0
- package/dist/esm/bundle/apbundle.js +89 -0
- package/dist/esm/bundle/apbundle.js.map +1 -0
- package/dist/esm/bundle/hpke.d.ts +48 -0
- package/dist/esm/bundle/hpke.js +107 -0
- package/dist/esm/bundle/hpke.js.map +1 -0
- package/dist/esm/checks/index.d.ts +85 -0
- package/dist/esm/checks/index.js +436 -0
- package/dist/esm/checks/index.js.map +1 -0
- package/dist/esm/control/client.d.ts +78 -0
- package/dist/esm/control/client.js +81 -0
- package/dist/esm/control/client.js.map +1 -0
- package/dist/esm/golden/index.d.ts +97 -0
- package/dist/esm/golden/index.js +130 -0
- package/dist/esm/golden/index.js.map +1 -0
- package/dist/esm/index.d.ts +41 -0
- package/dist/esm/index.js +31 -0
- package/dist/esm/index.js.map +1 -0
- package/dist/esm/judge/index.d.ts +51 -0
- package/dist/esm/judge/index.js +127 -0
- package/dist/esm/judge/index.js.map +1 -0
- package/dist/esm/ports/node.d.ts +8 -0
- package/dist/esm/ports/node.js +27 -0
- package/dist/esm/ports/node.js.map +1 -0
- package/dist/esm/protocol/assignment.d.ts +49 -0
- package/dist/esm/protocol/assignment.js +143 -0
- package/dist/esm/protocol/assignment.js.map +1 -0
- package/dist/esm/protocol/canonicalJson.d.ts +10 -0
- package/dist/esm/protocol/canonicalJson.js +65 -0
- package/dist/esm/protocol/canonicalJson.js.map +1 -0
- package/dist/esm/protocol/errors.d.ts +15 -0
- package/dist/esm/protocol/errors.js +19 -0
- package/dist/esm/protocol/errors.js.map +1 -0
- package/dist/esm/protocol/ports.d.ts +65 -0
- package/dist/esm/protocol/ports.js +16 -0
- package/dist/esm/protocol/ports.js.map +1 -0
- package/dist/esm/protocol/trust.d.ts +60 -0
- package/dist/esm/protocol/trust.js +211 -0
- package/dist/esm/protocol/trust.js.map +1 -0
- package/dist/esm/protocol/types.d.ts +235 -0
- package/dist/esm/protocol/types.js +12 -0
- package/dist/esm/protocol/types.js.map +1 -0
- package/dist/esm/protocol/version.d.ts +4 -0
- package/dist/esm/protocol/version.js +5 -0
- package/dist/esm/protocol/version.js.map +1 -0
- package/dist/esm/release/bundleRelease.d.ts +45 -0
- package/dist/esm/release/bundleRelease.js +57 -0
- package/dist/esm/release/bundleRelease.js.map +1 -0
- package/dist/esm/release/reader.d.ts +30 -0
- package/dist/esm/release/reader.js +11 -0
- package/dist/esm/release/reader.js.map +1 -0
- package/dist/esm/render/runRef.d.ts +17 -0
- package/dist/esm/render/runRef.js +29 -0
- package/dist/esm/render/runRef.js.map +1 -0
- package/dist/esm/render/template.d.ts +38 -0
- package/dist/esm/render/template.js +65 -0
- package/dist/esm/render/template.js.map +1 -0
- package/dist/esm/telemetry/feedback.d.ts +21 -0
- package/dist/esm/telemetry/feedback.js +77 -0
- package/dist/esm/telemetry/feedback.js.map +1 -0
- package/dist/esm/telemetry/rows.d.ts +85 -0
- package/dist/esm/telemetry/rows.js +22 -0
- package/dist/esm/telemetry/rows.js.map +1 -0
- package/dist/esm/telemetry/uploadSink.d.ts +52 -0
- package/dist/esm/telemetry/uploadSink.js +12 -0
- package/dist/esm/telemetry/uploadSink.js.map +1 -0
- package/dist/esm/testing/controlPlane.d.ts +116 -0
- package/dist/esm/testing/controlPlane.js +341 -0
- package/dist/esm/testing/controlPlane.js.map +1 -0
- package/dist/esm/testing/index.d.ts +25 -0
- package/dist/esm/testing/index.js +35 -0
- package/dist/esm/testing/index.js.map +1 -0
- package/dist/esm/testing/memoryFs.d.ts +64 -0
- package/dist/esm/testing/memoryFs.js +232 -0
- package/dist/esm/testing/memoryFs.js.map +1 -0
- package/package.json +45 -0
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The trust chain (`protocol/trust-chain.md`): thumbprints, ES256 over
|
|
3
|
+
* canonical bytes, root-metadata acceptance R1–R5 and manifest verification
|
|
4
|
+
* M1–M12. Pure over its inputs; `now` is always passed in. This is what
|
|
5
|
+
* decides whether bytes go live, so it never reads the network or the disk.
|
|
6
|
+
*/
|
|
7
|
+
import { type Manifest, type ManifestPayload, type ManifestSlot, type P256PrivateJwk, type P256PublicJwk, type RefusalCode, type RootMetadata, type Target } from "./types.js";
|
|
8
|
+
export declare const SUPPORTED_PROTOCOL_MAJORS: ReadonlySet<number>;
|
|
9
|
+
/** RFC 7638: sha256 over canonical {crv, kty, x, y}, lowercase hex. */
|
|
10
|
+
export declare function keyThumbprint(jwk: P256PublicJwk): string;
|
|
11
|
+
export declare function publicJwkOf(jwk: P256PublicJwk | P256PrivateJwk): P256PublicJwk;
|
|
12
|
+
/** ES256, P1363 r‖s, base64url without padding. Local keys only (the platform signs in KMS). */
|
|
13
|
+
export declare function signBytes(bytes: Uint8Array, privateJwk: P256PrivateJwk): string;
|
|
14
|
+
export declare function verifyBytes(bytes: Uint8Array, signature: string, publicJwk: P256PublicJwk): boolean;
|
|
15
|
+
/** Timestamps compare as instants (RFC 3339), never as strings. */
|
|
16
|
+
export declare function instant(text: string): number;
|
|
17
|
+
/** The synthetic trusted document a runtime starts from: the pinned root key alone, in the root role. */
|
|
18
|
+
export declare function trustedRootFromPinnedKey(input: {
|
|
19
|
+
purpose: "platform" | "countersign";
|
|
20
|
+
environment: Target;
|
|
21
|
+
pinnedRoot: P256PublicJwk;
|
|
22
|
+
}): RootMetadata;
|
|
23
|
+
export type Verdict<T = object> = ({
|
|
24
|
+
ok: true;
|
|
25
|
+
} & T) | {
|
|
26
|
+
ok: false;
|
|
27
|
+
reason: RefusalCode;
|
|
28
|
+
};
|
|
29
|
+
/** R1–R5. */
|
|
30
|
+
export declare function verifyRootMetadata(input: {
|
|
31
|
+
candidate: RootMetadata;
|
|
32
|
+
trusted: RootMetadata;
|
|
33
|
+
now: string;
|
|
34
|
+
}): Verdict;
|
|
35
|
+
/** Every content hash a manifest references, with the declared length: slots, steps, arm overrides. */
|
|
36
|
+
export declare function referencedPayloads(payload: ManifestPayload): Map<string, number>;
|
|
37
|
+
export interface VerifyManifestInput {
|
|
38
|
+
manifest: Manifest;
|
|
39
|
+
root: RootMetadata;
|
|
40
|
+
now: string;
|
|
41
|
+
scope: {
|
|
42
|
+
organizationId: string;
|
|
43
|
+
agentId: string;
|
|
44
|
+
target: Target;
|
|
45
|
+
};
|
|
46
|
+
storedGeneration: number;
|
|
47
|
+
/** contentHash → bytes for whatever was fetched; null skips M9/M10 (verify the envelope before fetching). */
|
|
48
|
+
payloads?: ReadonlyMap<string, Uint8Array> | null;
|
|
49
|
+
countersignRoot?: RootMetadata | null;
|
|
50
|
+
/** The local side may be stricter than the manifest. */
|
|
51
|
+
requireCountersign?: boolean;
|
|
52
|
+
}
|
|
53
|
+
/** M1–M14. */
|
|
54
|
+
export declare function verifyManifest(input: VerifyManifestInput): Verdict<{
|
|
55
|
+
signingKeyId: string;
|
|
56
|
+
generation: number;
|
|
57
|
+
}>;
|
|
58
|
+
/** The digest input: pins sorted by tag, projected to exactly the covered members (canonical-json.md). */
|
|
59
|
+
export declare function releaseDigestInput(slots: readonly ManifestSlot[]): unknown[];
|
|
60
|
+
export declare function releaseDigest(slots: readonly ManifestSlot[]): `sha256:${string}`;
|
|
@@ -0,0 +1,211 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The trust chain (`protocol/trust-chain.md`): thumbprints, ES256 over
|
|
3
|
+
* canonical bytes, root-metadata acceptance R1–R5 and manifest verification
|
|
4
|
+
* M1–M12. Pure over its inputs; `now` is always passed in. This is what
|
|
5
|
+
* decides whether bytes go live, so it never reads the network or the disk.
|
|
6
|
+
*/
|
|
7
|
+
import { createHash, createPrivateKey, createPublicKey, sign as cryptoSign, verify as cryptoVerify } from "node:crypto";
|
|
8
|
+
import { isAssignmentError, validateRamp } from "./assignment.js";
|
|
9
|
+
import { canonicalBytes, canonicalJson, sha256Prefixed } from "./canonicalJson.js";
|
|
10
|
+
import { DIRECTIVE_KINDS } from "./types.js";
|
|
11
|
+
export const SUPPORTED_PROTOCOL_MAJORS = new Set([0]);
|
|
12
|
+
/** RFC 7638: sha256 over canonical {crv, kty, x, y}, lowercase hex. */
|
|
13
|
+
export function keyThumbprint(jwk) {
|
|
14
|
+
return createHash("sha256").update(canonicalJson({ crv: jwk.crv, kty: jwk.kty, x: jwk.x, y: jwk.y }), "utf8").digest("hex");
|
|
15
|
+
}
|
|
16
|
+
export function publicJwkOf(jwk) {
|
|
17
|
+
return { kty: "EC", crv: "P-256", x: jwk.x, y: jwk.y };
|
|
18
|
+
}
|
|
19
|
+
/** ES256, P1363 r‖s, base64url without padding. Local keys only (the platform signs in KMS). */
|
|
20
|
+
export function signBytes(bytes, privateJwk) {
|
|
21
|
+
const key = createPrivateKey({ key: privateJwk, format: "jwk" });
|
|
22
|
+
return cryptoSign("sha256", bytes, { key, dsaEncoding: "ieee-p1363" }).toString("base64url");
|
|
23
|
+
}
|
|
24
|
+
export function verifyBytes(bytes, signature, publicJwk) {
|
|
25
|
+
if (!/^[A-Za-z0-9_-]{86}$/.test(signature))
|
|
26
|
+
return false;
|
|
27
|
+
try {
|
|
28
|
+
const key = createPublicKey({ key: publicJwk, format: "jwk" });
|
|
29
|
+
return cryptoVerify("sha256", bytes, { key, dsaEncoding: "ieee-p1363" }, Buffer.from(signature, "base64url"));
|
|
30
|
+
}
|
|
31
|
+
catch {
|
|
32
|
+
return false;
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
/** Timestamps compare as instants (RFC 3339), never as strings. */
|
|
36
|
+
export function instant(text) {
|
|
37
|
+
const ms = Date.parse(text);
|
|
38
|
+
if (!Number.isFinite(ms))
|
|
39
|
+
throw new Error(`not an RFC 3339 timestamp: ${text}`);
|
|
40
|
+
return ms;
|
|
41
|
+
}
|
|
42
|
+
/** The synthetic trusted document a runtime starts from: the pinned root key alone, in the root role. */
|
|
43
|
+
export function trustedRootFromPinnedKey(input) {
|
|
44
|
+
const keyId = keyThumbprint(input.pinnedRoot);
|
|
45
|
+
return {
|
|
46
|
+
signed: {
|
|
47
|
+
type: "root",
|
|
48
|
+
protocol: "0.0.0",
|
|
49
|
+
purpose: input.purpose,
|
|
50
|
+
environment: input.environment,
|
|
51
|
+
version: 0,
|
|
52
|
+
expires: "9999-12-31T23:59:59Z",
|
|
53
|
+
keys: { [keyId]: { keyType: "ecdsa-p256", scheme: "ES256", publicKey: publicJwkOf(input.pinnedRoot) } },
|
|
54
|
+
roles: { root: { keyIds: [keyId], threshold: 1 }, targets: { keyIds: [], threshold: 1 } },
|
|
55
|
+
},
|
|
56
|
+
signatures: [],
|
|
57
|
+
};
|
|
58
|
+
}
|
|
59
|
+
function countValidSignatures(bytes, signatures, keyIds, keys) {
|
|
60
|
+
const seen = new Set();
|
|
61
|
+
let valid = 0;
|
|
62
|
+
for (const signature of signatures) {
|
|
63
|
+
if (!keyIds.includes(signature.keyId) || seen.has(signature.keyId))
|
|
64
|
+
continue;
|
|
65
|
+
const key = keys[signature.keyId];
|
|
66
|
+
if (!key)
|
|
67
|
+
continue;
|
|
68
|
+
if (verifyBytes(bytes, signature.sig, key.publicKey)) {
|
|
69
|
+
seen.add(signature.keyId);
|
|
70
|
+
valid += 1;
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
return valid;
|
|
74
|
+
}
|
|
75
|
+
/** R1–R5. */
|
|
76
|
+
export function verifyRootMetadata(input) {
|
|
77
|
+
const signed = input.candidate.signed;
|
|
78
|
+
const trusted = input.trusted.signed;
|
|
79
|
+
if (signed.purpose !== trusted.purpose || signed.environment !== trusted.environment)
|
|
80
|
+
return { ok: false, reason: "root_scope_mismatch" };
|
|
81
|
+
for (const [keyId, key] of Object.entries(signed.keys)) {
|
|
82
|
+
if (keyThumbprint(key.publicKey) !== keyId)
|
|
83
|
+
return { ok: false, reason: "key_id_mismatch" };
|
|
84
|
+
}
|
|
85
|
+
if (signed.version < trusted.version)
|
|
86
|
+
return { ok: false, reason: "root_rollback" };
|
|
87
|
+
if (signed.version === trusted.version && canonicalJson(signed) !== canonicalJson(trusted))
|
|
88
|
+
return { ok: false, reason: "root_rollback" };
|
|
89
|
+
const role = trusted.roles.root;
|
|
90
|
+
if (countValidSignatures(canonicalBytes(signed), input.candidate.signatures, role.keyIds, trusted.keys) < role.threshold) {
|
|
91
|
+
return { ok: false, reason: "root_signature_invalid" };
|
|
92
|
+
}
|
|
93
|
+
if (!(instant(signed.expires) > instant(input.now)))
|
|
94
|
+
return { ok: false, reason: "root_expired" };
|
|
95
|
+
return { ok: true };
|
|
96
|
+
}
|
|
97
|
+
/** Every content hash a manifest references, with the declared length: slots, steps, arm overrides. */
|
|
98
|
+
export function referencedPayloads(payload) {
|
|
99
|
+
const hashes = new Map();
|
|
100
|
+
const add = (slot) => {
|
|
101
|
+
hashes.set(slot.contentHash, slot.byteLength);
|
|
102
|
+
for (const step of slot.steps ?? [])
|
|
103
|
+
hashes.set(step.contentHash, step.byteLength);
|
|
104
|
+
if (slot.goldenSet)
|
|
105
|
+
hashes.set(slot.goldenSet.contentHash, slot.goldenSet.byteLength);
|
|
106
|
+
};
|
|
107
|
+
for (const slot of payload.slots)
|
|
108
|
+
add(slot);
|
|
109
|
+
for (const arm of payload.experiment?.arms ?? [])
|
|
110
|
+
for (const override of arm.overrides)
|
|
111
|
+
add(override);
|
|
112
|
+
return hashes;
|
|
113
|
+
}
|
|
114
|
+
function keyUsableAt(key, now) {
|
|
115
|
+
const at = instant(now);
|
|
116
|
+
if (key.notBefore && !(instant(key.notBefore) <= at))
|
|
117
|
+
return false;
|
|
118
|
+
if (key.notAfter && !(at < instant(key.notAfter)))
|
|
119
|
+
return false;
|
|
120
|
+
return true;
|
|
121
|
+
}
|
|
122
|
+
/** M1–M14. */
|
|
123
|
+
export function verifyManifest(input) {
|
|
124
|
+
const { manifest, root } = input;
|
|
125
|
+
const payload = manifest.payload;
|
|
126
|
+
if (!(instant(root.signed.expires) > instant(input.now)))
|
|
127
|
+
return { ok: false, reason: "root_expired" };
|
|
128
|
+
const major = Number(payload.protocol.split(".")[0]);
|
|
129
|
+
if (!SUPPORTED_PROTOCOL_MAJORS.has(major))
|
|
130
|
+
return { ok: false, reason: "protocol_unsupported" };
|
|
131
|
+
const targets = root.signed.roles.targets;
|
|
132
|
+
const named = manifest.signatures.filter((signature) => targets.keyIds.includes(signature.keyId) && root.signed.keys[signature.keyId]);
|
|
133
|
+
if (named.length === 0)
|
|
134
|
+
return { ok: false, reason: "unknown_signing_key" };
|
|
135
|
+
const usable = named.filter((signature) => keyUsableAt(root.signed.keys[signature.keyId], input.now));
|
|
136
|
+
if (usable.length === 0)
|
|
137
|
+
return { ok: false, reason: "signing_key_expired" };
|
|
138
|
+
const valid = countValidSignatures(canonicalBytes(payload), usable, targets.keyIds, root.signed.keys);
|
|
139
|
+
if (valid === 0)
|
|
140
|
+
return { ok: false, reason: "signature_invalid" };
|
|
141
|
+
if (valid < targets.threshold)
|
|
142
|
+
return { ok: false, reason: "signature_threshold" };
|
|
143
|
+
if (payload.organizationId !== input.scope.organizationId || payload.agentId !== input.scope.agentId || payload.target !== input.scope.target) {
|
|
144
|
+
return { ok: false, reason: "scope_mismatch" };
|
|
145
|
+
}
|
|
146
|
+
if (payload.generation < input.storedGeneration)
|
|
147
|
+
return { ok: false, reason: "generation_rollback" };
|
|
148
|
+
// M13 (S4): the kinds a runtime honours are a closed set; one it does not know refuses the whole manifest before a byte is fetched.
|
|
149
|
+
if (!Array.isArray(payload.directives) || payload.directives.some((directive) => !directive || typeof directive !== "object" || !DIRECTIVE_KINDS.has(directive.kind))) {
|
|
150
|
+
return { ok: false, reason: "directive_unknown" };
|
|
151
|
+
}
|
|
152
|
+
// M14 (S9): a ramp plan, when present, is well-formed — a malformed one is refused whole rather than walked wrongly.
|
|
153
|
+
if (payload.experiment?.ramp !== undefined) {
|
|
154
|
+
try {
|
|
155
|
+
validateRamp(payload.experiment.ramp, payload.experiment.arms.length);
|
|
156
|
+
}
|
|
157
|
+
catch (error) {
|
|
158
|
+
if (isAssignmentError(error) && error.reason === "ramp_invalid")
|
|
159
|
+
return { ok: false, reason: "ramp_invalid" };
|
|
160
|
+
throw error;
|
|
161
|
+
}
|
|
162
|
+
}
|
|
163
|
+
if (input.payloads) {
|
|
164
|
+
for (const [hash, byteLength] of referencedPayloads(payload)) {
|
|
165
|
+
const bytes = input.payloads.get(hash);
|
|
166
|
+
if (bytes === undefined)
|
|
167
|
+
return { ok: false, reason: "payload_missing" };
|
|
168
|
+
if (bytes.length !== byteLength || sha256Prefixed(bytes) !== hash)
|
|
169
|
+
return { ok: false, reason: "payload_hash_mismatch" };
|
|
170
|
+
}
|
|
171
|
+
}
|
|
172
|
+
if (payload.requireCountersign || input.requireCountersign) {
|
|
173
|
+
const digests = new Set([payload.releaseDigest, ...(payload.experiment?.arms ?? []).map((arm) => arm.releaseDigest)]);
|
|
174
|
+
const role = input.countersignRoot?.signed.roles.targets ?? { keyIds: [], threshold: 1 };
|
|
175
|
+
const keys = input.countersignRoot?.signed.keys ?? {};
|
|
176
|
+
for (const digest of digests) {
|
|
177
|
+
const candidates = (manifest.countersignatures ?? []).filter((c) => c.releaseDigest === digest && role.keyIds.includes(c.keyId) && keys[c.keyId]);
|
|
178
|
+
if (candidates.length === 0)
|
|
179
|
+
return { ok: false, reason: "countersign_missing" };
|
|
180
|
+
if (countValidSignatures(Buffer.from(digest, "utf8"), candidates, role.keyIds, keys) < role.threshold)
|
|
181
|
+
return { ok: false, reason: "countersign_invalid" };
|
|
182
|
+
}
|
|
183
|
+
}
|
|
184
|
+
return { ok: true, signingKeyId: usable[0].keyId, generation: payload.generation };
|
|
185
|
+
}
|
|
186
|
+
/** The digest input: pins sorted by tag, projected to exactly the covered members (canonical-json.md). */
|
|
187
|
+
export function releaseDigestInput(slots) {
|
|
188
|
+
return [...slots]
|
|
189
|
+
.sort((a, b) => (a.tag < b.tag ? -1 : a.tag > b.tag ? 1 : 0))
|
|
190
|
+
.map((slot) => ({
|
|
191
|
+
tag: slot.tag,
|
|
192
|
+
kind: slot.kind,
|
|
193
|
+
artifactId: slot.artifactId,
|
|
194
|
+
versionId: slot.versionId,
|
|
195
|
+
versionOrdinal: slot.versionOrdinal,
|
|
196
|
+
contentHash: slot.contentHash,
|
|
197
|
+
byteLength: slot.byteLength,
|
|
198
|
+
model: slot.model,
|
|
199
|
+
...(slot.modelRequired === true ? { modelRequired: true } : {}),
|
|
200
|
+
...(Array.isArray(slot.outputChecks) && slot.outputChecks.length > 0 ? { outputChecks: slot.outputChecks } : {}),
|
|
201
|
+
...(slot.goldenSet ? { goldenSet: { setId: slot.goldenSet.setId, cases: slot.goldenSet.cases, contentHash: slot.goldenSet.contentHash, byteLength: slot.goldenSet.byteLength, minPassBps: slot.goldenSet.minPassBps } } : {}),
|
|
202
|
+
variables: slot.variables.map((v) => ({ name: v.name, required: v.required, trust: v.trust })),
|
|
203
|
+
...(slot.steps
|
|
204
|
+
? { steps: slot.steps.map((s) => ({ stepId: s.stepId, ordinal: s.ordinal, promptArtifactId: s.promptArtifactId, promptVersionId: s.promptVersionId, contentHash: s.contentHash, byteLength: s.byteLength })) }
|
|
205
|
+
: {}),
|
|
206
|
+
}));
|
|
207
|
+
}
|
|
208
|
+
export function releaseDigest(slots) {
|
|
209
|
+
return sha256Prefixed(canonicalBytes(releaseDigestInput(slots)));
|
|
210
|
+
}
|
|
211
|
+
//# sourceMappingURL=trust.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"trust.js","sourceRoot":"","sources":["../../../src/protocol/trust.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,235 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Wire types for protocol 0.2 — hand-written to match `protocol/schemas/*`.
|
|
3
|
+
* The conformance vectors, not these types, are what proves agreement; keep
|
|
4
|
+
* them narrow and let the schema tests catch drift.
|
|
5
|
+
*/
|
|
6
|
+
export type Target = "dev" | "staging" | "prod";
|
|
7
|
+
export type Sha256 = `sha256:${string}`;
|
|
8
|
+
export interface SlotVariable {
|
|
9
|
+
name: string;
|
|
10
|
+
required: boolean;
|
|
11
|
+
trust: "operator" | "end_user";
|
|
12
|
+
}
|
|
13
|
+
export interface SlotStep {
|
|
14
|
+
stepId: string;
|
|
15
|
+
ordinal: number;
|
|
16
|
+
promptArtifactId: string;
|
|
17
|
+
promptVersionId: string;
|
|
18
|
+
contentHash: Sha256;
|
|
19
|
+
byteLength: number;
|
|
20
|
+
}
|
|
21
|
+
/** One declared output check as a pin carries it (checks.md): the kind's own members only. */
|
|
22
|
+
export type OutputCheck = {
|
|
23
|
+
kind: "json_schema";
|
|
24
|
+
name: string;
|
|
25
|
+
schema: Record<string, unknown>;
|
|
26
|
+
} | {
|
|
27
|
+
kind: "enum";
|
|
28
|
+
name: string;
|
|
29
|
+
path: string;
|
|
30
|
+
values: string[];
|
|
31
|
+
} | {
|
|
32
|
+
kind: "length";
|
|
33
|
+
name: string;
|
|
34
|
+
minTokens?: number;
|
|
35
|
+
maxTokens?: number;
|
|
36
|
+
} | {
|
|
37
|
+
kind: "must_match" | "must_not_match";
|
|
38
|
+
name: string;
|
|
39
|
+
pattern: string;
|
|
40
|
+
flags?: "i";
|
|
41
|
+
};
|
|
42
|
+
export interface ManifestSlot {
|
|
43
|
+
tag: string;
|
|
44
|
+
kind: "prompt" | "workflow";
|
|
45
|
+
artifactId: string;
|
|
46
|
+
versionId: string;
|
|
47
|
+
versionOrdinal: number | null;
|
|
48
|
+
contentHash: Sha256;
|
|
49
|
+
byteLength: number;
|
|
50
|
+
model: string;
|
|
51
|
+
/** The model is required: a runtime whose declared catalog lacks it refuses the release (`model_unavailable`). In the digest input only when true. */
|
|
52
|
+
modelRequired?: boolean;
|
|
53
|
+
/** T29: the slot's enabled output checks (checks.md), sorted by name; in the digest input only when present. */
|
|
54
|
+
outputChecks?: OutputCheck[];
|
|
55
|
+
/** T34: the slot's golden set (golden-sets.md) — a reference to a payload the runtime opens and runs before activation; in the digest input only when present. */
|
|
56
|
+
goldenSet?: GoldenSetRef;
|
|
57
|
+
variables: SlotVariable[];
|
|
58
|
+
steps?: SlotStep[];
|
|
59
|
+
}
|
|
60
|
+
/** T34: what the pin carries — the cases themselves are the payload under `contentHash`. */
|
|
61
|
+
export interface GoldenSetRef {
|
|
62
|
+
setId: string;
|
|
63
|
+
cases: number;
|
|
64
|
+
contentHash: Sha256;
|
|
65
|
+
byteLength: number;
|
|
66
|
+
/** Pass-rate floor in basis points; below it a staged release is not activated. */
|
|
67
|
+
minPassBps: number;
|
|
68
|
+
}
|
|
69
|
+
export interface ExperimentArm {
|
|
70
|
+
arm: string;
|
|
71
|
+
weightBps: number;
|
|
72
|
+
releaseDigest: Sha256;
|
|
73
|
+
overrides: ManifestSlot[];
|
|
74
|
+
}
|
|
75
|
+
/** S9: one step of the signed ramp plan — from `notBefore` (inclusive, the host's clock) these are the arms' weights, in manifest order. */
|
|
76
|
+
export interface RampStep {
|
|
77
|
+
notBefore: string;
|
|
78
|
+
weightBps: number[];
|
|
79
|
+
}
|
|
80
|
+
export interface Experiment {
|
|
81
|
+
experimentId: string;
|
|
82
|
+
salt: string;
|
|
83
|
+
subjectKey: "request" | "instance";
|
|
84
|
+
arms: ExperimentArm[];
|
|
85
|
+
/**
|
|
86
|
+
* S9: the signed ramp plan (assignment-hash.md › The ramp plan). The runtime walks it on its own clock — no check-in
|
|
87
|
+
* needed: the weights in force are the last step whose `notBefore` has passed, else `arms[].weightBps`. Steps are
|
|
88
|
+
* strictly increasing and at least an hour apart; each carries one weight per arm summing to 10000.
|
|
89
|
+
*/
|
|
90
|
+
ramp?: RampStep[];
|
|
91
|
+
}
|
|
92
|
+
export type Directive = {
|
|
93
|
+
kind: "request_unlock";
|
|
94
|
+
releaseDigest: Sha256;
|
|
95
|
+
requestedBy: string;
|
|
96
|
+
requestedAt: string;
|
|
97
|
+
expiresAt: string;
|
|
98
|
+
note?: string;
|
|
99
|
+
} | {
|
|
100
|
+
kind: "disable";
|
|
101
|
+
scope: "agent" | "slot" | "arm";
|
|
102
|
+
tag?: string;
|
|
103
|
+
arm?: string;
|
|
104
|
+
issuedAt: string;
|
|
105
|
+
reason?: string;
|
|
106
|
+
};
|
|
107
|
+
/**
|
|
108
|
+
* S4: the set of directive kinds a runtime honours is closed. `disable` is the one kind that acts without a
|
|
109
|
+
* local act (a reduction: it only ever stops serving); `request_unlock` is a request the runtime surfaces and
|
|
110
|
+
* never grants. A manifest carrying any other kind is refused whole (`directive_unknown`) — never partly obeyed.
|
|
111
|
+
*/
|
|
112
|
+
export declare const DIRECTIVE_KINDS: ReadonlySet<string>;
|
|
113
|
+
/** S4: the apply policy a host holds, as store.json records it. */
|
|
114
|
+
export type ApplyPolicy = "auto" | "unlock_required";
|
|
115
|
+
export interface ManifestPayload {
|
|
116
|
+
protocol: string;
|
|
117
|
+
organizationId: string;
|
|
118
|
+
agentId: string;
|
|
119
|
+
target: Target;
|
|
120
|
+
generation: number;
|
|
121
|
+
releaseDigest: Sha256;
|
|
122
|
+
previousReleaseDigest?: Sha256;
|
|
123
|
+
issuedAt: string;
|
|
124
|
+
leaseSeconds: number;
|
|
125
|
+
onLeaseExpiry: "degrade" | "halt";
|
|
126
|
+
applyPolicy: "auto" | "unlock_required";
|
|
127
|
+
/** T9: the console's update window (advisory; a local `apply.window` wins). Only with `unlock_required`. */
|
|
128
|
+
unlockWindow?: {
|
|
129
|
+
timezone: string;
|
|
130
|
+
start: string;
|
|
131
|
+
end: string;
|
|
132
|
+
days?: Array<"mon" | "tue" | "wed" | "thu" | "fri" | "sat" | "sun">;
|
|
133
|
+
};
|
|
134
|
+
requireCountersign: boolean;
|
|
135
|
+
slots: ManifestSlot[];
|
|
136
|
+
experiment?: Experiment;
|
|
137
|
+
directives: Directive[];
|
|
138
|
+
}
|
|
139
|
+
export interface Signature {
|
|
140
|
+
keyId: string;
|
|
141
|
+
alg: "ES256";
|
|
142
|
+
sig: string;
|
|
143
|
+
}
|
|
144
|
+
export interface Countersignature extends Signature {
|
|
145
|
+
releaseDigest: Sha256;
|
|
146
|
+
signedAt: string;
|
|
147
|
+
}
|
|
148
|
+
export interface Manifest {
|
|
149
|
+
payload: ManifestPayload;
|
|
150
|
+
signatures: Signature[];
|
|
151
|
+
countersignatures?: Countersignature[];
|
|
152
|
+
}
|
|
153
|
+
export interface P256PublicJwk {
|
|
154
|
+
kty: "EC";
|
|
155
|
+
crv: "P-256";
|
|
156
|
+
x: string;
|
|
157
|
+
y: string;
|
|
158
|
+
}
|
|
159
|
+
export interface P256PrivateJwk extends P256PublicJwk {
|
|
160
|
+
d: string;
|
|
161
|
+
}
|
|
162
|
+
export interface RootKeyEntry {
|
|
163
|
+
keyType: "ecdsa-p256";
|
|
164
|
+
scheme: "ES256";
|
|
165
|
+
publicKey: P256PublicJwk;
|
|
166
|
+
notBefore?: string;
|
|
167
|
+
notAfter?: string;
|
|
168
|
+
}
|
|
169
|
+
export interface RootRole {
|
|
170
|
+
keyIds: string[];
|
|
171
|
+
threshold: number;
|
|
172
|
+
}
|
|
173
|
+
export interface RootMetadataSigned {
|
|
174
|
+
type: "root";
|
|
175
|
+
protocol: string;
|
|
176
|
+
purpose: "platform" | "countersign";
|
|
177
|
+
environment: Target;
|
|
178
|
+
version: number;
|
|
179
|
+
expires: string;
|
|
180
|
+
keys: Record<string, RootKeyEntry>;
|
|
181
|
+
roles: {
|
|
182
|
+
root: RootRole;
|
|
183
|
+
targets: RootRole;
|
|
184
|
+
};
|
|
185
|
+
}
|
|
186
|
+
export interface RootMetadata {
|
|
187
|
+
signed: RootMetadataSigned;
|
|
188
|
+
signatures: Signature[];
|
|
189
|
+
}
|
|
190
|
+
export interface EdgePointer {
|
|
191
|
+
generation: number;
|
|
192
|
+
releaseDigest: Sha256;
|
|
193
|
+
leaseSeconds: number;
|
|
194
|
+
issuedAt?: string;
|
|
195
|
+
}
|
|
196
|
+
export interface BundleContents {
|
|
197
|
+
createdAt: string;
|
|
198
|
+
notAfter: string;
|
|
199
|
+
manifest: Manifest;
|
|
200
|
+
keySet: RootMetadata;
|
|
201
|
+
countersignKeySet?: RootMetadata;
|
|
202
|
+
payloads: Array<{
|
|
203
|
+
contentHash: Sha256;
|
|
204
|
+
byteLength: number;
|
|
205
|
+
bytes: string;
|
|
206
|
+
}>;
|
|
207
|
+
}
|
|
208
|
+
export type Bundle = {
|
|
209
|
+
format: "apbundle";
|
|
210
|
+
version: 1;
|
|
211
|
+
protocol: string;
|
|
212
|
+
encryption: {
|
|
213
|
+
scheme: "none";
|
|
214
|
+
contents: BundleContents;
|
|
215
|
+
};
|
|
216
|
+
} | {
|
|
217
|
+
format: "apbundle";
|
|
218
|
+
version: 1;
|
|
219
|
+
protocol: string;
|
|
220
|
+
encryption: {
|
|
221
|
+
scheme: "hpke-x25519-hkdf-sha256-aes-256-gcm";
|
|
222
|
+
recipientKeyId: string;
|
|
223
|
+
enc: string;
|
|
224
|
+
info?: "airprompter-apbundle-v1";
|
|
225
|
+
ciphertext: string;
|
|
226
|
+
};
|
|
227
|
+
};
|
|
228
|
+
/** trust-chain.md refusal vocabulary, in verification order. */
|
|
229
|
+
export type RefusalCode = "root_scope_mismatch" | "key_id_mismatch" | "root_rollback" | "root_signature_invalid" | "root_expired" | "protocol_unsupported" | "unknown_signing_key" | "signing_key_expired" | "signature_invalid" | "signature_threshold" | "scope_mismatch" | "generation_rollback" | "payload_missing" | "payload_hash_mismatch" | "countersign_missing" | "countersign_invalid" | "schema_invalid"
|
|
230
|
+
/** S4: a directive of a kind this runtime does not honour — the manifest is refused whole, never partly obeyed. */
|
|
231
|
+
| "directive_unknown"
|
|
232
|
+
/** S9: the ramp plan is malformed (order, spacing, a weight per arm, sums) — refused whole before a byte is fetched. */
|
|
233
|
+
| "ramp_invalid"
|
|
234
|
+
/** The chain verified; a slot's required model is not in this runtime's declared catalog (T15). */
|
|
235
|
+
| "model_unavailable";
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Wire types for protocol 0.2 — hand-written to match `protocol/schemas/*`.
|
|
3
|
+
* The conformance vectors, not these types, are what proves agreement; keep
|
|
4
|
+
* them narrow and let the schema tests catch drift.
|
|
5
|
+
*/
|
|
6
|
+
/**
|
|
7
|
+
* S4: the set of directive kinds a runtime honours is closed. `disable` is the one kind that acts without a
|
|
8
|
+
* local act (a reduction: it only ever stops serving); `request_unlock` is a request the runtime surfaces and
|
|
9
|
+
* never grants. A manifest carrying any other kind is refused whole (`directive_unknown`) — never partly obeyed.
|
|
10
|
+
*/
|
|
11
|
+
export const DIRECTIVE_KINDS = new Set(["request_unlock", "disable"]);
|
|
12
|
+
//# sourceMappingURL=types.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.js","sourceRoot":"","sources":["../../../src/protocol/types.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAsFH;;;;GAIG;AACH,MAAM,CAAC,MAAM,eAAe,GAAwB,IAAI,GAAG,CAAoB,CAAC,gBAAgB,EAAE,SAAS,CAAC,CAAC,CAAC"}
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
/** The protocol this SDK speaks (`protocol/VERSION`); the manifest carries it and the heartbeat reports it. */
|
|
2
|
+
export declare const PROTOCOL_VERSION = "0.2.5";
|
|
3
|
+
/** This package's own version, as the heartbeat and store.json (S8: the writer) record it. */
|
|
4
|
+
export declare const SDK_VERSION = "0.1.0";
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
/** The protocol this SDK speaks (`protocol/VERSION`); the manifest carries it and the heartbeat reports it. */
|
|
2
|
+
export const PROTOCOL_VERSION = "0.2.5";
|
|
3
|
+
/** This package's own version, as the heartbeat and store.json (S8: the writer) record it. */
|
|
4
|
+
export const SDK_VERSION = "0.1.0";
|
|
5
|
+
//# sourceMappingURL=version.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"version.js","sourceRoot":"","sources":["../../../src/protocol/version.ts"],"names":[],"mappings":"AAAA,+GAA+G;AAC/G,MAAM,CAAC,MAAM,gBAAgB,GAAG,OAAO,CAAC;AACxC,8FAA8F;AAC9F,MAAM,CAAC,MAAM,WAAW,GAAG,OAAO,CAAC"}
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* A bundle the customer loads, as a `ReleaseReader` (S10): `agent-runtime`
|
|
3
|
+
* on its own — no store, no daemon, no network — renders and assigns over
|
|
4
|
+
* it. The same chain as OTA runs before a byte is served: the bundle's key
|
|
5
|
+
* set must descend from the pinned root (or be it), and the manifest's
|
|
6
|
+
* signatures, scope, expiry and every payload hash must verify. There is
|
|
7
|
+
* no anti-rollback here because there is no stored generation; that is the
|
|
8
|
+
* slot store's rule (`agent-sync`).
|
|
9
|
+
*/
|
|
10
|
+
import { type DistributionKey } from "../bundle/apbundle.js";
|
|
11
|
+
import type { Bundle, RefusalCode, RootMetadata, Target } from "../protocol/types.js";
|
|
12
|
+
import type { LoadedRelease, ReleaseReader } from "./reader.js";
|
|
13
|
+
export interface BundleReleaseInput {
|
|
14
|
+
bundle: Bundle;
|
|
15
|
+
/** The pinned root of trust (`trustedRootFromPinnedKey`, or root metadata the host already holds). */
|
|
16
|
+
root: RootMetadata;
|
|
17
|
+
scope: {
|
|
18
|
+
organizationId: string;
|
|
19
|
+
agentId: string;
|
|
20
|
+
target: Target;
|
|
21
|
+
};
|
|
22
|
+
now: string;
|
|
23
|
+
distributionKey?: DistributionKey;
|
|
24
|
+
countersignRoot?: RootMetadata | null;
|
|
25
|
+
requireCountersign?: boolean;
|
|
26
|
+
}
|
|
27
|
+
/** A bundle refused before it became a release: the bundle itself (`bundle_*`), or the chain (a `RefusalCode`). */
|
|
28
|
+
export type BundleReleaseRefusal = RefusalCode | "bundle_malformed" | "bundle_wrong_recipient" | "bundle_decrypt_failed" | "bundle_relabelled";
|
|
29
|
+
export declare class BundleRelease implements ReleaseReader {
|
|
30
|
+
private readonly release;
|
|
31
|
+
/** The key set the bundle carried, once it verified against the pinned root: what a host pins next. */
|
|
32
|
+
readonly keySet: RootMetadata;
|
|
33
|
+
readonly notAfter: string;
|
|
34
|
+
readonly kind: "bundle";
|
|
35
|
+
private constructor();
|
|
36
|
+
/** Open, verify, and hold: `{ ok: false, reason }` names the first rule the bundle failed. */
|
|
37
|
+
static load(input: BundleReleaseInput): {
|
|
38
|
+
ok: true;
|
|
39
|
+
release: BundleRelease;
|
|
40
|
+
} | {
|
|
41
|
+
ok: false;
|
|
42
|
+
reason: BundleReleaseRefusal;
|
|
43
|
+
};
|
|
44
|
+
current(): LoadedRelease;
|
|
45
|
+
}
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* A bundle the customer loads, as a `ReleaseReader` (S10): `agent-runtime`
|
|
3
|
+
* on its own — no store, no daemon, no network — renders and assigns over
|
|
4
|
+
* it. The same chain as OTA runs before a byte is served: the bundle's key
|
|
5
|
+
* set must descend from the pinned root (or be it), and the manifest's
|
|
6
|
+
* signatures, scope, expiry and every payload hash must verify. There is
|
|
7
|
+
* no anti-rollback here because there is no stored generation; that is the
|
|
8
|
+
* slot store's rule (`agent-sync`).
|
|
9
|
+
*/
|
|
10
|
+
import { bundlePayloadBytes, openBundle } from "../bundle/apbundle.js";
|
|
11
|
+
import { verifyManifest, verifyRootMetadata } from "../protocol/trust.js";
|
|
12
|
+
export class BundleRelease {
|
|
13
|
+
release;
|
|
14
|
+
keySet;
|
|
15
|
+
notAfter;
|
|
16
|
+
kind = "bundle";
|
|
17
|
+
constructor(release,
|
|
18
|
+
/** The key set the bundle carried, once it verified against the pinned root: what a host pins next. */
|
|
19
|
+
keySet, notAfter) {
|
|
20
|
+
this.release = release;
|
|
21
|
+
this.keySet = keySet;
|
|
22
|
+
this.notAfter = notAfter;
|
|
23
|
+
}
|
|
24
|
+
/** Open, verify, and hold: `{ ok: false, reason }` names the first rule the bundle failed. */
|
|
25
|
+
static load(input) {
|
|
26
|
+
let contents;
|
|
27
|
+
try {
|
|
28
|
+
contents = openBundle(input.bundle, { agentId: input.scope.agentId, target: input.scope.target }, input.distributionKey);
|
|
29
|
+
}
|
|
30
|
+
catch (error) {
|
|
31
|
+
const code = error.name === "BundleError" ? error.code : "malformed";
|
|
32
|
+
return { ok: false, reason: `bundle_${code}` };
|
|
33
|
+
}
|
|
34
|
+
let root = input.root;
|
|
35
|
+
const rootVerdict = verifyRootMetadata({ candidate: contents.keySet, trusted: root, now: input.now });
|
|
36
|
+
if (rootVerdict.ok)
|
|
37
|
+
root = contents.keySet;
|
|
38
|
+
const payloads = bundlePayloadBytes(contents);
|
|
39
|
+
const verdict = verifyManifest({
|
|
40
|
+
manifest: contents.manifest,
|
|
41
|
+
root,
|
|
42
|
+
now: input.now,
|
|
43
|
+
scope: input.scope,
|
|
44
|
+
storedGeneration: 0,
|
|
45
|
+
payloads,
|
|
46
|
+
countersignRoot: input.countersignRoot ?? null,
|
|
47
|
+
...(input.requireCountersign !== undefined ? { requireCountersign: input.requireCountersign } : {}),
|
|
48
|
+
});
|
|
49
|
+
if (!verdict.ok)
|
|
50
|
+
return { ok: false, reason: verdict.reason };
|
|
51
|
+
return { ok: true, release: new BundleRelease({ manifest: contents.manifest, generation: verdict.generation, payloads }, root, contents.notAfter) };
|
|
52
|
+
}
|
|
53
|
+
current() {
|
|
54
|
+
return this.release;
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
//# sourceMappingURL=bundleRelease.js.map
|