feat: replace revision counters with domain state contracts

Use content digests, key fingerprints, binding and trust identities, immutable mutation receipts, and observation tokens instead of state-update ordinals across API, storage, Runtime, and Web contracts.

Preserve historical replay and secret material through frozen migrations; preflight uncertain removals before cutover, resume provisioning receipts, validate encrypted migration candidates, and align fresh/upgraded schemas. Include reviewed regression fixes, generated artifacts, and validation evidence.
This commit is contained in:
2026-10-10 15:55:20 +09:00
parent 72ce817de4
commit c78f7f7d80
358 changed files with 25965 additions and 12069 deletions
+79 -35
View File
@@ -5,7 +5,7 @@ declare const Deno: {
import {
createSubjektivSubject,
parseMemoryStagingListResponse,
parseSubjektivMemoryListRevisionsResponse,
parseSubjektivMemoryListChangesResponse,
parseSubjektivMemoryQueryResponse,
parseSubjektivMemoryReadResponse,
parseSubjektivResidentSurfaceResponse,
@@ -75,9 +75,8 @@ function subject(id = "subject-1") {
id,
role: "Release coordinator",
behavior_md: "Prefer explicit evidence.",
behavior_revision: 2,
state: "active",
store_revision: 12,
memory_fingerprint: "fingerprint-12",
created_at: "2026-09-01T00:00:00Z",
updated_at: "2026-09-02T00:00:00Z",
};
@@ -110,7 +109,7 @@ function currentWorker() {
function queryItem(id = "memory-1") {
return {
id,
revision: 3,
change_id: "change-current",
kind: "decision",
state: "active",
claim: "Keep provenance typed.",
@@ -127,12 +126,11 @@ function detailFixture() {
worker_id: "worker-1",
flow_selector: "builtin:coder-review",
flow_definition_id: "flow-1",
flow_definition_revision: 7,
};
return {
memory_id: "memory-1",
revision: 2,
current_revision: 3,
change_id: "change-earlier",
current_change_id: "change-current",
kind: "decision",
state: "resolved",
claim: "Keep provenance typed.",
@@ -173,13 +171,13 @@ function detailFixture() {
source_refs_total: 2,
source_refs_truncated: true,
}],
derived_from: [{ memory_id: "memory-parent", revision: 4 }],
derived_from: [{ memory_id: "memory-parent", change_id: "change-parent" }],
evidence_next_cursor: "evidence-page-2",
evidence_has_more: true,
};
}
Deno.test("Subject parsers enforce identity, exact enums, safe revisions, and bounds", () => {
Deno.test("Subject parsers enforce identity, exact enums, bounded fingerprints, and bounds", () => {
assertEquals(
parseSubjektivSubjectResponse(subject(), "subject-1"),
subject(),
@@ -196,9 +194,9 @@ Deno.test("Subject parsers enforce identity, exact enums, safe revisions, and bo
() =>
parseSubjektivSubjectResponse({
...subject(),
store_revision: Number.MAX_SAFE_INTEGER + 1,
memory_fingerprint: 12,
}),
"safe integer",
"bounded identifier",
);
assertThrows(
() => parseSubjektivSubjectResponse({ ...subject(), id: "x".repeat(513) }),
@@ -313,7 +311,7 @@ Deno.test("Subject behavior update uses CAS and preserves exact text", async ()
return Response.json({
...subject("subject/one"),
behavior_md: "Line one.\nLine two.",
behavior_revision: 3,
});
}) as typeof fetch;
@@ -321,9 +319,8 @@ Deno.test("Subject behavior update uses CAS and preserves exact text", async ()
fetchFn,
"workspace one",
"subject/one",
{ expected_behavior_revision: 2, behavior_md: "Line one.\nLine two." },
{ expected_behavior_md: "Prefer explicit evidence.", behavior_md: "Line one.\nLine two." },
);
assertEquals(updated.behavior_revision, 3);
assertEquals(updated.behavior_md, "Line one.\nLine two.");
assertEquals(
requests[0].path,
@@ -332,20 +329,20 @@ Deno.test("Subject behavior update uses CAS and preserves exact text", async ()
assertEquals(requests[0].init?.method, "PATCH");
assertEquals(
requests[0].init?.body,
'{"expected_behavior_revision":2,"behavior_md":"Line one.\\nLine two."}',
'{"expected_behavior_md":"Prefer explicit evidence.","behavior_md":"Line one.\\nLine two."}',
);
});
Deno.test("Subject behavior update reports conflicts without claiming Worker application", async () => {
const conflictFetch =
(async () =>
Response.json({ message: "revision conflict" }, {
Response.json({ message: "behavior content conflict" }, {
status: 409,
})) as typeof fetch;
await assertSubjectCreateRejects(
() =>
updateSubjektivSubjectBehavior(conflictFetch, "workspace", "subject", {
expected_behavior_revision: 1,
expected_behavior_md: "old",
behavior_md: "new",
}),
"rejected",
@@ -459,7 +456,7 @@ Deno.test("Resident surface parser accepts ready-empty and enforces snapshot inv
snapshot_id: "snapshot-empty",
body_md: "",
memory_refs: [],
built_from_store_revision: 0,
built_from_memory_fingerprint: "fingerprint-0",
created_at: "2026-09-02T00:00:00Z",
},
};
@@ -506,7 +503,7 @@ Deno.test("Resident surface parser accepts ready-empty and enforces snapshot inv
);
});
Deno.test("Current Memory list parser rejects unknown variants, unsafe integers, cursors, and oversized pages", () => {
Deno.test("Current Memory list parser rejects unknown variants, invalid change IDs, cursors, and oversized pages", () => {
const response = {
items: [queryItem()],
has_more: true,
@@ -533,9 +530,9 @@ Deno.test("Current Memory list parser rejects unknown variants, unsafe integers,
() =>
parseSubjektivMemoryQueryResponse({
...response,
items: [{ ...queryItem(), revision: 0 }],
items: [{ ...queryItem(), change_id: "" }],
}),
"positive safe integer",
"bounded identifier",
);
assertThrows(
() =>
@@ -572,7 +569,7 @@ Deno.test("Memory detail parser preserves body/evidence continuation, sources, o
);
assertEquals(parsed.derived_from, [{
memory_id: "memory-parent",
revision: 4,
change_id: "change-parent",
}]);
});
@@ -586,9 +583,9 @@ Deno.test("Memory detail parser fails closed on identity, variants, bounds, and
() =>
parseSubjektivMemoryReadResponse({
...fixture,
current_revision: Number.MAX_SAFE_INTEGER + 1,
current_change_id: 3,
}),
"safe integer",
"bounded identifier",
);
const missingBodyContinuation = structuredClone(fixture) as Record<
string,
@@ -637,26 +634,26 @@ Deno.test("Memory detail parser fails closed on identity, variants, bounds, and
);
});
Deno.test("Memory revision parser preserves immutable states and checks response identity", () => {
Deno.test("Memory change parser preserves immutable states and checks response identity", () => {
const response = {
memory_id: "memory-1",
current_revision: 3,
current_change_id: "change-current",
items: [{
revision: 3,
change_id: "change-current",
kind: "decision",
state: "active",
claim: "Current claim.",
change_reason: "Clarified wording.",
updated_at: "2026-09-03T00:00:00Z",
}, {
revision: 2,
change_id: "change-earlier",
kind: "decision",
state: "resolved",
claim: "Earlier claim.",
change_reason: "Resolved.",
updated_at: "2026-09-02T00:00:00Z",
}, {
revision: 1,
change_id: "change-original",
kind: "decision",
state: "retracted",
claim: "Original claim.",
@@ -666,16 +663,16 @@ Deno.test("Memory revision parser preserves immutable states and checks response
has_more: false,
};
assertEquals(
parseSubjektivMemoryListRevisionsResponse(response, "memory-1"),
parseSubjektivMemoryListChangesResponse(response, "memory-1"),
response,
);
assertThrows(
() => parseSubjektivMemoryListRevisionsResponse(response, "memory-2"),
() => parseSubjektivMemoryListChangesResponse(response, "memory-2"),
"identity does not match",
);
assertThrows(
() =>
parseSubjektivMemoryListRevisionsResponse({
parseSubjektivMemoryListChangesResponse({
...response,
items: [{ ...response.items[0], state: "archived" }],
}),
@@ -683,14 +680,61 @@ Deno.test("Memory revision parser preserves immutable states and checks response
);
assertThrows(
() =>
parseSubjektivMemoryListRevisionsResponse({
parseSubjektivMemoryListChangesResponse({
...response,
items: [{ ...response.items[0], revision: 4 }],
items: [response.items[0], response.items[0]],
}),
"future revision",
"Memory changes must be unique",
);
});
Deno.test("Memory changes preserve server order without interpreting opaque identities", () => {
const item = { kind: "decision", state: "active", claim: "Claim", change_reason: "Reason", updated_at: "2026-09-01T00:00:00Z" };
const response = {
memory_id: "memory-1",
current_change_id: "a/current",
items: [{ ...item, change_id: "z/earlier" }, { ...item, change_id: "a/current" }],
has_more: false,
};
assertEquals(parseSubjektivMemoryListChangesResponse(response), response);
assertEquals(parseSubjektivMemoryReadResponse({ ...detailFixture(), change_id: "z/earlier", current_change_id: "a/current" }).change_id, "z/earlier");
});
Deno.test("Memory identities reject numeric counters, empty and oversized strings, and legacy fields", () => {
for (const value of [3, "", "x".repeat(513)]) {
assertThrows(() => parseSubjektivMemoryReadResponse({ ...detailFixture(), change_id: value }), "bounded identifier");
assertThrows(() => parseSubjektivMemoryReadResponse({ ...detailFixture(), current_change_id: value }), "bounded identifier");
assertThrows(() => parseSubjektivSubjectResponse({ ...subject(), memory_fingerprint: value }), "bounded identifier");
}
assertThrows(() => parseSubjektivMemoryReadResponse({ ...detailFixture(), revision: 2 }), "unknown field");
assertThrows(() => parseSubjektivSubjectResponse({ ...subject(), behavior_revision: 2 }), "unknown field");
assertThrows(() => parseSubjektivSubjectResponse({ ...subject(), store_revision: 12 }), "unknown field");
});
Deno.test("Behavior CAS sends the observed text byte-for-byte including empty content", async () => {
for (const expected of ["", " Previous\nbehavior.\n"]) {
let body: unknown;
const fetchFn = (async (_path: string | URL | Request, init?: RequestInit) => {
body = JSON.parse(String(init?.body));
return Response.json({ ...subject(), behavior_md: "Replacement" });
}) as typeof fetch;
await updateSubjektivSubjectBehavior(fetchFn, "workspace", "subject-1", { expected_behavior_md: expected, behavior_md: "Replacement" });
assertEquals(body, { expected_behavior_md: expected, behavior_md: "Replacement" });
}
});
Deno.test("Behavior saves with mismatched response text have unknown outcome and are not retried", async () => {
let calls = 0;
const fetchFn = (async () => {
calls += 1;
return Response.json(subject());
}) as typeof fetch;
await assertSubjectCreateRejects(() => updateSubjektivSubjectBehavior(fetchFn, "workspace", "subject-1", {
expected_behavior_md: "Prefer explicit evidence.", behavior_md: "Replacement",
}), "unknown_outcome", "could not be confirmed");
assertEquals(calls, 1);
});
Deno.test("Legacy staging parser remains strict for deprecated compatibility", () => {
const origin = { kind: "worker_input", worker_id: "worker-1" };
const response = {
+10 -14
View File
@@ -44,8 +44,6 @@ const diagnostic = {
function profileSettingsFixture(): Record<string, unknown> {
return {
workspace_id: "workspace 1",
registry_revision: "config-source:7:tree:projection",
config_revision: 7,
tree_digest: "tree",
projection_digest: "projection",
default_profile: "workspace:coder",
@@ -68,7 +66,6 @@ function profileSettingsFixture(): Record<string, unknown> {
content_digest: "sha256:source",
provenance: "project_profile_source_tree",
editable: false,
revision: "config-source:7",
size_bytes: 128,
diagnostics: [],
}],
@@ -86,7 +83,7 @@ Deno.test("profile settings requests use scoped API and strictly validate respon
try {
const response = await fetchProfileSettings("workspace 1");
assertEquals(response.config_revision, 7);
assertEquals(response.tree_digest, "tree");
assertEquals(response.sources[0].provenance, "project_profile_source_tree");
assertEquals(requests.length, 1);
assertEquals(requests[0].url, "/api/w/workspace%201/settings/profiles");
@@ -103,7 +100,7 @@ Deno.test("workspace metadata requests use generated DTO shapes", async () => {
workspace_id: "workspace 1",
display_name: "Workspace",
created_at: "2026-01-01T00:00:00Z",
revision: "sha256:metadata",
updated_at: "2026-01-02T00:00:00Z",
source: "workspace-config",
diagnostics: [diagnostic],
};
@@ -118,13 +115,13 @@ Deno.test("workspace metadata requests use generated DTO shapes", async () => {
try {
assertEquals(
(await fetchWorkspaceMetadata("workspace 1")).revision,
"sha256:metadata",
(await fetchWorkspaceMetadata("workspace 1")).updated_at,
"2026-01-02T00:00:00Z",
);
assertEquals(
(await updateWorkspaceMetadata("workspace 1", {
display_name: "Renamed",
revision: "sha256:metadata",
expected_updated_at: "2026-01-02T00:00:00Z",
})).workspace.workspace_id,
"workspace 1",
);
@@ -135,7 +132,10 @@ Deno.test("workspace metadata requests use generated DTO shapes", async () => {
assertEquals(requests[1].init?.method, "PUT");
assertEquals(
requests[1].init?.body,
JSON.stringify({ display_name: "Renamed", revision: "sha256:metadata" }),
JSON.stringify({
display_name: "Renamed",
expected_updated_at: "2026-01-02T00:00:00Z",
}),
);
} finally {
globalThis.fetch = originalFetch;
@@ -152,7 +152,6 @@ Deno.test("Workspace signing identity requests use flat settings routes", async
workspace_id: "workspace 1",
key_id: "workspace-signing-key",
algorithm: "ed25519",
revision: 1,
state: "pending_provisioning",
created_at: "2026-01-01T00:00:00Z",
},
@@ -182,7 +181,7 @@ Deno.test("profile settings parser rejects missing, mistyped, stale, and invalid
);
const mistyped = profileSettingsFixture();
mistyped.config_revision = "7";
mistyped.tree_digest = 7;
assertThrows(
() => parseProfileSettingsResponse(mistyped),
ProfileApiError,
@@ -212,7 +211,6 @@ Deno.test("Workspace signing identity parser validates active and pending public
algorithm: "ed25519",
public_key: "public-key",
public_key_fingerprint: "sha256:fingerprint",
revision: 1,
state: "active",
created_at: "2026-01-01T00:00:00Z",
provisioned_at: "2026-01-01T00:00:00Z",
@@ -224,7 +222,6 @@ Deno.test("Workspace signing identity parser validates active and pending public
algorithm: "ed25519",
public_key: "public-key",
public_key_fingerprint: "sha256:fingerprint",
revision: 1,
},
};
assertEquals(
@@ -237,7 +234,6 @@ Deno.test("Workspace signing identity parser validates active and pending public
workspace_id: "workspace-1",
key_id: "WK-1",
algorithm: "ed25519",
revision: 1,
state: "pending_provisioning",
created_at: "2026-01-01T00:00:00Z",
},
@@ -13,7 +13,6 @@ const repository = {
kind: "git",
provider: "git",
source: { kind: "local_path", uri: "/srv/main" },
source_revision: 1,
source_fingerprint: "sha256:main",
observed_status: "ready",
record_authority: "workspace-control-plane",
@@ -19,7 +19,7 @@ function compatibleResponse(): Record<string, unknown> {
return {
workspace_id: "workspace-a",
runtime_id: "runtime-a",
binding_revision: 3,
binding_id: "binding-3",
connection_state: "verified",
verification: null,
checked_at: "2026-09-01T12:00:00Z",
@@ -67,12 +67,11 @@ Deno.test("runtime connection response rejects unknown fields and incoherent com
verified_at: "2026-09-01T12:00:00Z",
last_checked_at: "2026-09-01T12:00:01Z",
last_outcome: "verified",
binding_revision: 2,
binding_id: "binding-2",
workspace_key_id: "WK-a",
workspace_identity_revision: 1,
workspace_trust_generation: 1,
workspace_public_key_fingerprint: "sha256:workspace",
workspace_trust_id: "trust-a",
runtime_public_key_fingerprint: "sha256:runtime",
runtime_identity_revision: 1,
},
}),
null,
@@ -181,7 +181,7 @@ Deno.test("Runtime detail keeps trust controls owner-only and conflict-safe", as
"new RuntimeRemovalAttempt()",
"runtimeRemovalAttempt.operationId()",
"operation_id: operationId",
"expected_binding_revision: trust.revision",
"expected_binding_id: trust.binding_id",
"The Backend removes Workspace trust and this Runtime registration as one guarded operation.",
"deleteRuntimeConfirmation.trim() !== data.runtimeId",
"Delete Runtime registration",
+102 -23
View File
@@ -46,19 +46,18 @@ function runtime() {
binding: {
state: "verified",
connection_state: "verified",
revision: 3,
binding_id: "binding-3",
workspace_key_id: "WK-1",
workspace_key_generation: 1,
workspace_trust_id: "trust-1",
verification: {
verified_at: "2026-09-01T13:00:00Z",
last_checked_at: "2026-09-01T13:00:00Z",
last_outcome: "verified",
binding_revision: 3,
binding_id: "binding-3",
workspace_key_id: "WK-1",
workspace_identity_revision: 1,
workspace_trust_generation: 1,
workspace_public_key_fingerprint: "sha256:workspace-key",
workspace_trust_id: "trust-1",
runtime_public_key_fingerprint: "SHA256:current",
runtime_identity_revision: 1,
},
},
},
@@ -88,7 +87,7 @@ function detail() {
trust_key: {
status: "active",
fingerprint: "SHA256:current",
revision: 3,
binding_id: "binding-3",
created_at: "2026-09-01T12:00:00Z",
updated_at: "2026-09-01T13:00:00Z",
revoked_at: null,
@@ -98,7 +97,7 @@ function detail() {
actor_account_id: "account-a",
old_fingerprint: null,
new_fingerprint: "SHA256:current",
revision: 3,
binding_id: "binding-3",
at: "2026-09-01T13:00:00Z",
}],
};
@@ -124,12 +123,12 @@ Deno.test("Runtime list and detail parsers return generated Runtime DTO shapes",
const parsed = parseWorkspaceRuntimeDetail(detail());
assert(
parsed.trust_key.revision === 3,
"revision was not preserved as a safe integer",
parsed.trust_key.binding_id === "binding-3",
"binding identity was not preserved",
);
assert(
parsed.recent_audit[0]?.revision === 3,
"audit revision was not normalized",
parsed.recent_audit[0]?.binding_id === "binding-3",
"audit binding_id was not normalized",
);
});
@@ -144,7 +143,7 @@ Deno.test("Runtime list parser accepts the built-in Runtime's internal binding",
typeof embedded.management.binding
>;
delete binding.workspace_key_id;
delete binding.workspace_key_generation;
delete binding.workspace_trust_id;
delete binding.verification;
const list = parseWorkspaceRuntimeList({
@@ -166,7 +165,7 @@ Deno.test("Runtime management parser rejects Workspace identity bindings without
typeof payload.runtime.management.binding
>;
delete binding.workspace_key_id;
delete binding.workspace_key_generation;
delete binding.workspace_trust_id;
binding.state = "configured";
assertThrows(
() => parseWorkspaceRuntimeDetail(payload),
@@ -192,19 +191,19 @@ Deno.test("Runtime validators reject unknown object keys and enum variants", ()
parseRuntimeTrustConflict({
error: "future_conflict",
message: "conflict",
current_revision: 4,
current_binding_id: "binding-4",
current_fingerprint: "SHA256:new",
}),
"contains an unknown enum value",
);
});
Deno.test("Runtime validators reject unsafe revisions and bounded collection overflow", () => {
Deno.test("Runtime validators reject invalid binding identities and bounded collection overflow", () => {
const unsafeRevision = structuredClone(detail());
unsafeRevision.trust_key.revision = Number.MAX_SAFE_INTEGER + 1;
Object.assign(unsafeRevision.trust_key, { binding_id: 1 });
assertThrows(
() => parseWorkspaceRuntimeDetail(unsafeRevision),
"must be a safe integer",
"must be a string",
);
const tooMuchAudit = structuredClone(detail());
@@ -263,7 +262,7 @@ Deno.test("mismatched revoke fingerprint never sends a request", async () => {
await revokeRuntimeTrustKey(
"workspace-a",
"runtime-a",
{ expected_revision: 3 },
{ expected_binding_id: "binding-3" },
"sha256:current",
"sha256:different",
fetchImpl,
@@ -325,7 +324,7 @@ Deno.test("Runtime removal attempt retains its id across response-loss retry", a
const operation = await removeRemoteRuntime(
"workspace-a",
"runtime-a",
{ operation_id: operationId, expected_binding_revision: 4 },
{ operation_id: operationId, expected_binding_id: "binding-4" },
() => {
calls += 1;
if (calls === 1) return Promise.reject(new Error("response lost"));
@@ -391,7 +390,7 @@ Deno.test("Runtime removal uses the Workspace-scoped operation route", async ()
const operation = await removeRemoteRuntime(
"workspace a",
"runtime/a",
{ operation_id: "remove-runtime-a", expected_binding_revision: 7 },
{ operation_id: "remove-runtime-a", expected_binding_id: "binding-7" },
fetchImpl,
);
@@ -403,7 +402,7 @@ Deno.test("Runtime removal uses the Workspace-scoped operation route", async ()
assert(
JSON.stringify(requestedBody) === JSON.stringify({
operation_id: "remove-runtime-a",
expected_binding_revision: 7,
expected_binding_id: "binding-7",
}),
"Runtime removal request body drifted",
);
@@ -451,6 +450,85 @@ Deno.test("Runtime public key preview matches the Server fingerprint contract",
);
});
Deno.test("Runtime registration rejects empty or oversized enrollment identities before sending", async () => {
for (const enrollment of ["", "x".repeat(257)]) {
let calls = 0;
try {
await createRemoteRuntime("workspace-a", {
public_bundle: { identity_id: "runtime-a", public_key: "test-key" },
workspace_trust_id: enrollment,
endpoint: "https://runtime.example",
}, (() => { calls++; throw new Error("unexpected request"); }) as typeof fetch);
throw new Error("expected enrollment validation to reject");
} catch (error) {
assert(error instanceof Error && error.message.includes("workspace_trust_id"), "enrollment validation was bypassed");
}
assert(calls === 0, "invalid enrollment reached the Server");
}
});
Deno.test("Runtime trust replacement preserves binding conflicts without retrying", async () => {
for (const errorKind of ["stale_binding", "fingerprint_in_use"] as const) {
const request = {
public_bundle: {
identity_id: "runtime-a",
public_key: "yoi-ed25519-pub:v1:test",
},
display_name: null,
endpoint: "https://runtime.example",
workspace_trust_id: "runtime-issued-enrollment-id",
expected_binding_id: "observed-binding-id",
};
const conflict = {
error: errorKind,
message: "Reload the authoritative Runtime trust.",
current_binding_id: "current-binding-id",
current_fingerprint: "sha256:current-key",
};
let calls = 0;
const fetchImpl = ((input: RequestInfo | URL, init?: RequestInit) => {
calls++;
assert(String(input) === "/api/w/workspace-a/runtimes", "wrong trust route");
assert(init?.body === JSON.stringify(request), "observed binding ID changed");
return Promise.resolve(Response.json(conflict, { status: 409 }));
}) as typeof fetch;
try {
await createRemoteRuntime("workspace-a", request, fetchImpl);
throw new Error("expected trust replacement to reject");
} catch (error) {
assert(error instanceof RuntimeTrustConflictError, "binding conflict was hidden");
assert(
JSON.stringify(error.conflict) === JSON.stringify(conflict),
"authoritative conflict identity was changed",
);
}
assert(calls === 1, "trust replacement was retried");
}
});
Deno.test("Runtime trust replacement rejects legacy counter conflict responses", async () => {
const fetchImpl = (() => Promise.resolve(Response.json({
error: "stale_binding",
message: "Stale trust",
current_revision: 3,
}, { status: 409 }))) as typeof fetch;
try {
await createRemoteRuntime("workspace-a", {
public_bundle: { identity_id: "runtime-a", public_key: "test-key" },
endpoint: "https://runtime.example",
workspace_trust_id: "runtime-issued-enrollment-id",
expected_binding_id: "observed-binding-id",
}, fetchImpl);
throw new Error("expected malformed conflict to reject");
} catch (error) {
assert(!(error instanceof RuntimeTrustConflictError), "legacy conflict was accepted");
assert(
error instanceof Error && error.message === "Runtime trust conflict response was invalid",
"malformed conflict did not fail closed",
);
}
});
Deno.test("Runtime create surfaces bounded Settings error details", async () => {
const fetchImpl = (() =>
Promise.resolve(
@@ -473,7 +551,8 @@ Deno.test("Runtime create surfaces bounded Settings error details", async () =>
},
display_name: null,
endpoint: "https://runtime.example",
expected_revision: null,
workspace_trust_id: "runtime-issued-enrollment-id",
expected_binding_id: null,
},
fetchImpl,
);
+1 -1
View File
@@ -32,7 +32,7 @@ function plan() {
workspace_id: "workspace-a",
runtime_id: "runtime-a",
generated_at: "2026-09-01T00:00:00Z",
revision: "revision-a",
digest: "digest-a",
workers: [{
target_id: "worker-target",
+9 -17
View File
@@ -53,7 +53,6 @@ function workspaceProvenance() {
kind: "workspace",
id: "workspace:release",
virtual_path: "skills/release/SKILL.md",
revision: 42,
source_digest: "workspace-source-digest",
tree_digest: "tree-digest",
};
@@ -62,7 +61,7 @@ function workspaceProvenance() {
function catalogFixture(): Record<string, unknown> {
return {
authority: "workspace-config-skills-v1",
projection: { config_revision: 42, tree_digest: "tree-digest" },
projection: { tree_digest: "tree-digest" },
entries: [{
name: "errors",
description: "Builtin guidance",
@@ -92,7 +91,7 @@ function catalogFixture(): Record<string, unknown> {
function detailFixture(): Record<string, unknown> {
return {
authority: "workspace-config-skills-v1",
projection: { config_revision: 42, tree_digest: "tree-digest" },
projection: { tree_digest: "tree-digest" },
name: "release",
description: "Workspace guidance",
provenance: workspaceProvenance(),
@@ -117,7 +116,7 @@ Deno.test("Skill catalog parser accepts generated builtin, Workspace, and invali
assertEquals(parsed.entries[0].provenance.kind, "builtin");
assertEquals(parsed.entries[1].activation_status, "inactive");
assertEquals(parsed.entries[1].projection_status, "invalid");
assertEquals(parsed.projection.config_revision, 42);
assertEquals(parsed.projection.tree_digest, "tree-digest");
});
Deno.test("Skill detail parser preserves shared generated DTO fields", () => {
@@ -127,13 +126,7 @@ Deno.test("Skill detail parser preserves shared generated DTO fields", () => {
assertEquals(parsed.resources[0].supported, true);
});
Deno.test("Skill parser rejects stale Workspace projection revision and digest", () => {
const staleRevision = catalogFixture();
(staleRevision.projection as Record<string, unknown>).config_revision = 43;
assertContractError(
() => parseSkillCatalogResponse(staleRevision),
"stale Workspace Skill projection",
);
Deno.test("Skill parser rejects stale Workspace projection digest", () => {
const staleDigest = catalogFixture();
(staleDigest.projection as Record<string, unknown>).tree_digest = "new-tree";
@@ -168,13 +161,12 @@ Deno.test("Skill parser fails closed on unknown fields and newer enum values", (
);
});
Deno.test("Skill parser rejects unsafe revisions and oversized collections or strings", () => {
const unsafeRevision = catalogFixture();
(unsafeRevision.projection as Record<string, unknown>).config_revision =
Number.MAX_SAFE_INTEGER + 1;
Deno.test("Skill parser rejects removed revision fields and oversized collections or strings", () => {
const legacyRevision = catalogFixture();
(legacyRevision.projection as Record<string, unknown>).config_revision = 1;
assertContractError(
() => parseSkillCatalogResponse(unsafeRevision),
"safe integer",
() => parseSkillCatalogResponse(legacyRevision),
"unknown fields",
);
const oversizedCatalog = catalogFixture();
@@ -82,7 +82,6 @@ Deno.test("workspace catalog enriches each visible workspace without dropping si
kind: "git",
provider: "git",
source: { kind: "local_path", uri: "/srv/alpha" },
source_revision: 1,
source_fingerprint: "sha256:alpha",
observed_status: "ready",
default_selector: "develop",
+7 -16
View File
@@ -76,7 +76,6 @@ const repositoryList = {
kind: "git",
provider: "git",
source: { kind: "local_path", uri: "/srv/alpha" },
source_revision: 1,
source_fingerprint: "sha256:alpha",
observed_status: "ready",
record_authority: "workspace-control-plane",
@@ -153,21 +152,13 @@ Deno.test("stale repository aliases fail closed at the JSON boundary", () => {
);
});
Deno.test("repository source revisions enforce the OpenAPI integer range", () => {
const negative = structuredClone(repositoryList) as Record<string, unknown>;
const negativeItems = negative.items as Array<Record<string, unknown>>;
negativeItems[0].source_revision = -1;
Deno.test("repository JSON rejects removed source revision counters", () => {
const stale = structuredClone(repositoryList) as Record<string, unknown>;
const items = stale.items as Array<Record<string, unknown>>;
items[0].source_revision = 1;
assertThrows(
() => parseRepositoryListResponse(negative),
"must be between 0 and Number.MAX_SAFE_INTEGER",
);
const unsafe = structuredClone(repositoryList) as Record<string, unknown>;
const unsafeItems = unsafe.items as Array<Record<string, unknown>>;
unsafeItems[0].source_revision = Number.MAX_SAFE_INTEGER + 1;
assertThrows(
() => parseRepositoryListResponse(unsafe),
"must be a safe integer",
() => parseRepositoryListResponse(stale),
".source_revision is not part of the wire contract",
);
});
@@ -285,7 +276,7 @@ Deno.test("Workspace deletion DTOs fail closed and preserve durable operation st
const preflight = parseWorkspaceDeletionPreflightResponse({
workspace_id: "workspace-a",
display_name: "Alpha",
expected_revision: "2026-01-01T00:00:00Z",
expected_workspace_updated_at: "2026-01-01T00:00:00Z",
can_delete: true,
resources: {
workers: 2,