Implement durable typed journals, subscriptions, and Reader document connections

Add checked native journal/subscription bindings, managed-reference retention,
bounded history and backpressure, atomic delivery receipts, and fenced hosting.
Preserve source publication prediction and replica reconciliation; subscription
attachment, controls, and delivery remain authoritative in this initial version.

Connect independent manual/Gutenberg document producers to Reader bookshelves
through typed adapters. Add connection inspection, shared provider selection,
authoring documentation, and restart/rejection/fan-out integration coverage.

Verified compiler suite (287 passed, two existing skips), Nix runtime and
PostgreSQL qualification, five example assemblies, headless Reader integration,
Chromium Reader integration, resource pins, formatting, and lint.
No pinned workspace runtime was deployed.
This commit is contained in:
Timothy J. Aveni
2026-09-28 19:35:51 -07:00
parent 0ace71eae6
commit 1e72713ae2
30 changed files with 2949 additions and 2033 deletions
+145 -32
View File
@@ -1,4 +1,10 @@
import { isStorableType } from "./generics.js";
import {
journalPayloadType,
journalPrimitiveSignature,
subscriptionContract,
subscriptionStatusType,
} from "./journals.js";
import { validateInitialization } from "./initialization.js";
import { validatePresentations } from "./presentations.js";
import { validateModules } from "./modules.js";
@@ -511,15 +517,32 @@ const atomSatisfiesConstraint = (
? constraint.atomId === atomId
: conformances.has(conformanceKey(atomId, constraint.interfaceRevisionId));
const interfaceImplies = (
indexes: ValidationIndexes,
actual: InterfaceRevisionId,
required: InterfaceRevisionId,
visited = new Set<string>(),
): boolean => {
if (actual === required) return true;
if (visited.has(actual)) return false;
visited.add(actual);
return (indexes.interfaces.get(actual)?.revision.requiredInterfaces ?? []).some((entry) =>
interfaceImplies(indexes, entry, required, visited),
);
};
const constraintSatisfiesConstraint = (
actual: EdgeEndpointConstraint,
required: EdgeEndpointConstraint,
conformances: ReadonlyMap<string, Conformance>,
indexes: ValidationIndexes,
) =>
constraintsEqual(actual, required) ||
(actual.kind === "atom" &&
required.kind === "interface" &&
atomSatisfiesConstraint(actual.atomId, required, conformances));
atomSatisfiesConstraint(actual.atomId, required, indexes.conformances)) ||
(actual.kind === "interface" &&
required.kind === "interface" &&
interfaceImplies(indexes, actual.interfaceRevisionId, required.interfaceRevisionId));
const canAccessAttachment = (
owner: AttachmentOwner,
@@ -858,24 +881,12 @@ const validateInterfaces = (
issues: CapabilityValidationIssue[],
indexes: ValidationIndexes,
) => {
const implies = (
actual: InterfaceRevisionId,
required: InterfaceRevisionId,
visited = new Set<string>(),
): boolean => {
if (actual === required) return true;
if (visited.has(actual)) return false;
visited.add(actual);
return (indexes.interfaces.get(actual)?.revision.requiredInterfaces ?? []).some((entry) =>
implies(entry, required, visited),
);
};
for (const [packageIndex, pkg] of workspace.packageImports.entries()) {
for (const obligation of pkg.argumentRequirements ?? []) {
const satisfied =
obligation.target.kind === "atom"
? indexes.conformances.has(conformanceKey(obligation.target.atomId, obligation.required))
: implies(obligation.target.interfaceRevisionId, obligation.required);
: interfaceImplies(indexes, obligation.target.interfaceRevisionId, obligation.required);
if (!satisfied)
issue(
issues,
@@ -890,7 +901,7 @@ const validateInterfaces = (
for (const required of revision.requiredInterfaces ?? []) {
if (!indexes.interfaces.has(required))
issue(issues, "unresolved-reference", path, `Unknown prerequisite interface ${required}`);
else if (implies(required, revision.revisionId))
else if (interfaceImplies(indexes, required, revision.revisionId))
issue(
issues,
"cyclic-conformance-requirement",
@@ -902,7 +913,7 @@ const validateInterfaces = (
const satisfied =
obligation.target.kind === "atom"
? indexes.conformances.has(conformanceKey(obligation.target.atomId, obligation.required))
: implies(obligation.target.interfaceRevisionId, obligation.required);
: interfaceImplies(indexes, obligation.target.interfaceRevisionId, obligation.required);
if (!satisfied)
issue(issues, "unsatisfied-interface", path, `Generic argument does not implement ${obligation.required}`);
}
@@ -946,7 +957,8 @@ const validateAttachments = (issues: CapabilityValidationIssue[], indexes: Valid
(type.kind === "variant" && Object.values(type.cases).some((entry) => containsRpcType(entry.value))) ||
((type.kind === "optional" || type.kind === "list") && containsRpcType(type.value));
if (
containsRpcType(attachment.valueType) ||
(!["journal", "subscription"].includes(attachment.storagePolicy.kind) &&
containsRpcType(attachment.valueType)) ||
(attachment.storagePolicy.kind === "crdt-document" && containsRpcType(attachment.storagePolicy.updateType))
) {
issue(
@@ -959,6 +971,43 @@ const validateAttachments = (issues: CapabilityValidationIssue[], indexes: Valid
if (attachment.storagePolicy.kind === "crdt-document") {
validateValueType(issues, attachment.storagePolicy.updateType, `${path}.storagePolicy.updateType`, indexes);
}
if (attachment.storagePolicy.kind === "journal") {
if (!journalPayloadType(attachment.valueType) || attachment.defaultValue !== undefined)
issue(issues, "invalid-attachment", path, "Journals require finite typed payloads and start empty");
const limits = attachment.storagePolicy.limits;
const ceilings = {
maxEntries: 10000,
maxBytes: 1048576,
maxPublicationBytes: 262144,
maxProtectedSubscriptions: 256,
};
if (
!limits ||
Object.keys(limits).length !== 4 ||
Object.entries(ceilings).some(
([key, ceiling]) =>
!Number.isSafeInteger(limits[key as keyof typeof limits]) ||
limits[key as keyof typeof limits] < 1 ||
limits[key as keyof typeof limits] > ceiling,
) ||
limits.maxPublicationBytes > limits.maxBytes
)
issue(issues, "invalid-attachment", path, "Invalid bounded journal limits");
}
if (attachment.storagePolicy.kind === "subscription") {
validateValueType(issues, attachment.storagePolicy.payload, `${path}.storagePolicy.payload`, indexes);
if (
!journalPayloadType(attachment.valueType) ||
!journalPayloadType(attachment.storagePolicy.payload) ||
attachment.defaultValue !== undefined
)
issue(
issues,
"invalid-attachment",
path,
"Subscriptions require finite typed payloads/parameters and start unattached",
);
}
if (owner.kind === "conformance") {
if (attachment.attachedTo !== owner.atomId) {
issue(
@@ -1413,6 +1462,13 @@ const validateBoundDependencies = (
break;
}
validateAttachmentAccess(issues, attachment, params.conformance, `${path}.binding.slotId`);
if (["journal", "subscription"].includes(attachment.attachment.storagePolicy.kind))
issue(
issues,
"invalid-dependency-binding",
path,
"Journal storage requires checked journal interface calls, not ordinary state ports",
);
const traversal = stateBinding.via
? validateTraversal(
issues,
@@ -1519,11 +1575,7 @@ const validateBoundDependencies = (
);
}
if (
!constraintSatisfiesConstraint(
projection.target.constraint,
requirement.target,
params.indexes.conformances,
) ||
!constraintSatisfiesConstraint(projection.target.constraint, requirement.target, params.indexes) ||
requirement.cardinality !== projection.endpoint.cardinality ||
requirement.keyType !== projection.endpoint.keyType
) {
@@ -1822,7 +1874,9 @@ const validateConformances = (
) {
const native =
member.kind === "value"
? binding.kind === "state" && binding.primitive === "read"
? (binding.kind === "state" && binding.primitive === "read") ||
(binding.kind === "journal" && binding.primitive === "head") ||
(binding.kind === "subscription" && binding.primitive === "status")
: binding.kind === "edge" && binding.primitive === "resolve";
if (!native && (member.queryRead.execution === "native" || binding.kind !== "package"))
issue(
@@ -1878,6 +1932,67 @@ const validateConformances = (
);
continue;
}
if (binding.kind === "journal") {
const attachment = findAttachment(indexes, "state", binding.slotId);
if (
!attachment ||
attachment.attachment.kind !== "state" ||
attachment.attachment.storagePolicy.kind !== "journal"
) {
issue(issues, "invalid-state-binding", bindingPath, "Expected native journal storage");
continue;
}
validateAttachmentAccess(issues, attachment, conformance, bindingPath);
if (
attachment.attachment.attachedTo !== conformance.atomId ||
!["publish", "readPage", "head"].includes(binding.primitive) ||
!signaturesMatch(operation, journalPrimitiveSignature(attachment.attachment.valueType, binding.primitive))
)
issue(
issues,
"invalid-state-binding",
bindingPath,
"Journal primitive does not match this object operation's signature",
);
continue;
}
if (binding.kind === "subscription") {
const attachment = findAttachment(indexes, "state", binding.slotId);
if (
!attachment ||
attachment.attachment.kind !== "state" ||
attachment.attachment.storagePolicy.kind !== "subscription"
) {
issue(issues, "invalid-state-binding", bindingPath, "Expected native subscription storage");
continue;
}
validateAttachmentAccess(issues, attachment, conformance, bindingPath);
const slot = attachment.attachment;
if (slot.storagePolicy.kind !== "subscription") continue;
if (slot.attachedTo !== conformance.atomId)
issue(issues, "invalid-state-binding", bindingPath, "Subscription belongs to another atom");
if (binding.primitive === "attach") {
try {
subscriptionContract(
slot.storagePolicy.payload,
slot.valueType,
operation,
[...indexes.interfaces.values()].map((value) => value.revision),
);
} catch (error) {
issue(issues, "invalid-state-binding", bindingPath, String(error));
}
} else if (
!["status", "pause", "resume", "retire"].includes(binding.primitive) ||
!signaturesMatch(operation, {
mode: "call",
inputType: valueType.unit,
outputType: binding.primitive === "status" ? subscriptionStatusType : valueType.unit,
})
)
issue(issues, "invalid-state-binding", bindingPath, "Subscription primitive signature mismatch");
continue;
}
if (binding.kind === "state") {
const attachment = findAttachment(indexes, "state", binding.slotId);
if (!attachment || attachment.attachment.kind !== "state") {
@@ -1890,6 +2005,8 @@ const validateConformances = (
continue;
}
validateAttachmentAccess(issues, attachment, conformance, `${bindingPath}.binding.slotId`);
if (["journal", "subscription"].includes(attachment.attachment.storagePolicy.kind))
issue(issues, "invalid-state-binding", bindingPath, "Use native journal primitives, not state access");
if (attachment.attachment.attachedTo !== conformance.atomId) {
issue(
issues,
@@ -1990,11 +2107,7 @@ const validateConformances = (
"Edge primitives may only implement relationship members",
);
} else if (
!constraintSatisfiesConstraint(
projection.target.constraint,
operationEntry.member.target,
indexes.conformances,
) ||
!constraintSatisfiesConstraint(projection.target.constraint, operationEntry.member.target, indexes) ||
operationEntry.member.cardinality !== projection.endpoint.cardinality ||
(operationEntry.member.keyType !== undefined && operationEntry.member.keyType !== projection.endpoint.keyType)
) {
@@ -2002,7 +2115,7 @@ const validateConformances = (
issues,
"invalid-edge-binding",
`${bindingPath}.binding`,
"Edge projection target or cardinality does not match relationship member",
`Edge projection target or cardinality does not match ${conformance.atomId}/${conformance.interfaceRevisionId}/${operationEntry.member.displayName}`,
);
}
if (!signaturesMatch(operation, expected)) {
@@ -2531,7 +2644,7 @@ export const resolveOperationPlan = (
attachment: owned as OwnedAttachment & { attachment: EdgeDefinition },
};
}
if (binding.kind === "lifecycle") return undefined; // Old runtime has no lifecycle provider.
if (binding.kind === "lifecycle" || binding.kind === "journal" || binding.kind === "subscription") return undefined; // These native providers require the current kernel.
const packageRevision = plan.packages.get(binding.packageRevisionId);
const packageExport = packageRevision?.exports.find(
(entry): entry is PackageOperationExport | PackageFunctionExport =>
@@ -2679,7 +2792,7 @@ export const computeCapabilityClosure = (
queued.push({ atomId: root.atomId, interfaceRevisionId: member.subject.interfaceRevisionId });
}
for (const binding of conformance.operationBindings.values()) {
if (binding.kind === "state") {
if (binding.kind === "state" || binding.kind === "journal" || binding.kind === "subscription") {
attachments.add(binding.slotId);
} else if (binding.kind === "edge") {
attachments.add(binding.edgeTypeId);