@pithy-sh/core 0.13.0 → 0.15.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 +54 -0
- package/dist/audit/auditEvent.js +1 -1
- package/dist/audit/chain.d.ts +289 -0
- package/dist/audit/chain.d.ts.map +1 -0
- package/dist/audit/chain.js +400 -0
- package/dist/audit/citations.d.ts +52 -0
- package/dist/audit/citations.d.ts.map +1 -0
- package/dist/audit/citations.js +13 -0
- package/dist/capability/bindings.d.ts +22 -0
- package/dist/capability/bindings.d.ts.map +1 -1
- package/dist/capability/bindings.js +32 -2
- package/dist/capability/capability.d.ts +123 -16
- package/dist/capability/capability.d.ts.map +1 -1
- package/dist/capability/capability.js +17 -2
- package/dist/capability/erasure.d.ts +75 -0
- package/dist/capability/erasure.d.ts.map +1 -0
- package/dist/capability/erasure.js +2 -0
- package/dist/capability/manifest.d.ts +5 -0
- package/dist/capability/manifest.d.ts.map +1 -1
- package/dist/capability/personColumns.d.ts +28 -0
- package/dist/capability/personColumns.d.ts.map +1 -0
- package/dist/capability/personColumns.js +66 -0
- package/dist/capability/personRows.d.ts +62 -0
- package/dist/capability/personRows.d.ts.map +1 -0
- package/dist/capability/personRows.js +59 -0
- package/dist/capability/purge.d.ts +86 -19
- package/dist/capability/purge.d.ts.map +1 -1
- package/dist/capability/purge.js +83 -5
- package/dist/capability/settings.d.ts +10 -0
- package/dist/capability/settings.d.ts.map +1 -1
- package/dist/capability/vectorIndex.d.ts +36 -0
- package/dist/capability/vectorIndex.d.ts.map +1 -0
- package/dist/capability/vectorIndex.js +25 -0
- package/dist/cli/commandCatalog.generated.d.ts +438 -3
- package/dist/cli/commandCatalog.generated.d.ts.map +1 -1
- package/dist/cli/commandCatalog.generated.js +454 -2
- package/dist/cli/commandFacts.d.ts +8 -5
- package/dist/cli/commandFacts.d.ts.map +1 -1
- package/dist/cli/commandFacts.js +12 -3
- package/dist/consent/purpose.d.ts +70 -0
- package/dist/consent/purpose.d.ts.map +1 -0
- package/dist/consent/purpose.js +97 -0
- package/dist/consent/reader.d.ts +99 -0
- package/dist/consent/reader.d.ts.map +1 -0
- package/dist/consent/reader.js +33 -0
- package/dist/controlPlane/audit/actions.d.ts +15 -4
- package/dist/controlPlane/audit/actions.d.ts.map +1 -1
- package/dist/controlPlane/audit/actions.js +16 -5
- package/dist/controlPlane/capability.d.ts +10 -0
- package/dist/controlPlane/capability.d.ts.map +1 -1
- package/dist/controlPlane/capability.js +56 -8
- package/dist/controlPlane/context.d.ts +4 -0
- package/dist/controlPlane/context.d.ts.map +1 -1
- package/dist/controlPlane/context.js +3 -2
- package/dist/controlPlane/data/connection.d.ts +21 -2
- package/dist/controlPlane/data/connection.d.ts.map +1 -1
- package/dist/controlPlane/data/connection.js +13 -4
- package/dist/controlPlane/data/connections.d.ts +94 -0
- package/dist/controlPlane/data/connections.d.ts.map +1 -0
- package/dist/controlPlane/data/connections.js +151 -0
- package/dist/controlPlane/data/hold.d.ts +46 -0
- package/dist/controlPlane/data/hold.d.ts.map +1 -0
- package/dist/controlPlane/data/hold.js +36 -0
- package/dist/controlPlane/data/oidcTrust.d.ts +122 -0
- package/dist/controlPlane/data/oidcTrust.d.ts.map +1 -0
- package/dist/controlPlane/data/oidcTrust.js +173 -0
- package/dist/controlPlane/data/tables.d.ts +4 -0
- package/dist/controlPlane/data/tables.d.ts.map +1 -1
- package/dist/controlPlane/data/tables.js +9 -4
- package/dist/controlPlane/data/trustFirstCall.d.ts +16 -0
- package/dist/controlPlane/data/trustFirstCall.d.ts.map +1 -0
- package/dist/controlPlane/data/trustFirstCall.js +25 -0
- package/dist/controlPlane/discovery/adminRoute.d.ts +165 -2
- package/dist/controlPlane/discovery/adminRoute.d.ts.map +1 -1
- package/dist/controlPlane/discovery/adminRoute.js +32 -8
- package/dist/controlPlane/discovery/routeInput.d.ts +23 -0
- package/dist/controlPlane/discovery/routeInput.d.ts.map +1 -0
- package/dist/controlPlane/discovery/routeInput.js +80 -0
- package/dist/controlPlane/discovery/toolName.d.ts +21 -0
- package/dist/controlPlane/discovery/toolName.d.ts.map +1 -0
- package/dist/controlPlane/discovery/toolName.js +25 -0
- package/dist/controlPlane/erasure/attest.d.ts +78 -0
- package/dist/controlPlane/erasure/attest.d.ts.map +1 -0
- package/dist/controlPlane/erasure/attest.js +164 -0
- package/dist/controlPlane/erasure/read.d.ts +39 -0
- package/dist/controlPlane/erasure/read.d.ts.map +1 -0
- package/dist/controlPlane/erasure/read.js +140 -0
- package/dist/controlPlane/error/errors.d.ts +61 -2
- package/dist/controlPlane/error/errors.d.ts.map +1 -1
- package/dist/controlPlane/error/errors.js +13 -0
- package/dist/controlPlane/evidence/derive.d.ts +124 -0
- package/dist/controlPlane/evidence/derive.d.ts.map +1 -0
- package/dist/controlPlane/evidence/derive.js +343 -0
- package/dist/controlPlane/evidence/mapping.d.ts +85 -0
- package/dist/controlPlane/evidence/mapping.d.ts.map +1 -0
- package/dist/controlPlane/evidence/mapping.js +114 -0
- package/dist/controlPlane/evidence/pack.d.ts +46 -0
- package/dist/controlPlane/evidence/pack.d.ts.map +1 -0
- package/dist/controlPlane/evidence/pack.js +124 -0
- package/dist/controlPlane/http/connections.d.ts +96 -0
- package/dist/controlPlane/http/connections.d.ts.map +1 -0
- package/dist/controlPlane/http/connections.js +109 -0
- package/dist/controlPlane/http/guard.d.ts +23 -2
- package/dist/controlPlane/http/guard.d.ts.map +1 -1
- package/dist/controlPlane/http/guard.js +69 -12
- package/dist/controlPlane/http/handlers.d.ts +212 -10
- package/dist/controlPlane/http/handlers.d.ts.map +1 -1
- package/dist/controlPlane/http/handlers.js +117 -26
- package/dist/controlPlane/http/holds.d.ts +57 -0
- package/dist/controlPlane/http/holds.d.ts.map +1 -0
- package/dist/controlPlane/http/holds.js +98 -0
- package/dist/controlPlane/http/presence.d.ts +27 -0
- package/dist/controlPlane/http/presence.d.ts.map +1 -0
- package/dist/controlPlane/http/presence.js +67 -0
- package/dist/controlPlane/http/processing.d.ts +73 -0
- package/dist/controlPlane/http/processing.d.ts.map +1 -0
- package/dist/controlPlane/http/processing.js +17 -0
- package/dist/controlPlane/http/responses.d.ts +927 -3
- package/dist/controlPlane/http/responses.d.ts.map +1 -1
- package/dist/controlPlane/http/responses.js +283 -7
- package/dist/controlPlane/http/routes.d.ts +12 -2
- package/dist/controlPlane/http/routes.d.ts.map +1 -1
- package/dist/controlPlane/http/routes.js +182 -5
- package/dist/controlPlane/http/schemas.d.ts +63 -0
- package/dist/controlPlane/http/schemas.d.ts.map +1 -1
- package/dist/controlPlane/http/schemas.js +39 -1
- package/dist/controlPlane/http/verify.d.ts.map +1 -1
- package/dist/controlPlane/http/verify.js +13 -1
- package/dist/controlPlane/http/verifyTrust.d.ts +76 -0
- package/dist/controlPlane/http/verifyTrust.d.ts.map +1 -0
- package/dist/controlPlane/http/verifyTrust.js +75 -0
- package/dist/controlPlane/migrations/0004_connection_trusts.d.ts +15 -0
- package/dist/controlPlane/migrations/0004_connection_trusts.d.ts.map +1 -0
- package/dist/controlPlane/migrations/0004_connection_trusts.js +23 -0
- package/dist/controlPlane/migrations/0005_holds.d.ts +12 -0
- package/dist/controlPlane/migrations/0005_holds.d.ts.map +1 -0
- package/dist/controlPlane/migrations/0005_holds.js +26 -0
- package/dist/controlPlane/processing/derive.d.ts +77 -0
- package/dist/controlPlane/processing/derive.d.ts.map +1 -0
- package/dist/controlPlane/processing/derive.js +206 -0
- package/dist/controlPlane/processing/read.d.ts +10 -0
- package/dist/controlPlane/processing/read.d.ts.map +1 -0
- package/dist/controlPlane/processing/read.js +89 -0
- package/dist/controlPlane/scope/kind.d.ts +46 -0
- package/dist/controlPlane/scope/kind.d.ts.map +1 -0
- package/dist/controlPlane/scope/kind.js +52 -0
- package/dist/controlPlane/scope/scope.d.ts +58 -3
- package/dist/controlPlane/scope/scope.d.ts.map +1 -1
- package/dist/controlPlane/scope/scope.js +59 -4
- package/dist/controlPlane/token/jws.js +1 -1
- package/dist/controlPlane/token/mint.js +1 -1
- package/dist/controlPlane/wire.d.ts +23 -0
- package/dist/controlPlane/wire.d.ts.map +1 -1
- package/dist/controlPlane/wire.js +24 -1
- package/dist/createBackend.d.ts +13 -0
- package/dist/createBackend.d.ts.map +1 -1
- package/dist/createBackend.js +11 -3
- package/dist/createEntrypoint.d.ts +7 -0
- package/dist/createEntrypoint.d.ts.map +1 -1
- package/dist/createEntrypoint.js +4 -0
- package/dist/error/http.d.ts +168 -0
- package/dist/error/http.d.ts.map +1 -1
- package/dist/error/payload.d.ts +336 -0
- package/dist/error/payload.d.ts.map +1 -1
- package/dist/error/payload.js +112 -0
- package/dist/error/pithyError.d.ts +22 -0
- package/dist/error/pithyError.d.ts.map +1 -1
- package/dist/error/pithyError.js +31 -1
- package/dist/http/routeSpec.d.ts +46 -1
- package/dist/http/routeSpec.d.ts.map +1 -1
- package/dist/http/routeSpec.js +39 -5
- package/dist/http/verification.d.ts.map +1 -1
- package/dist/http/verification.js +1 -1
- package/dist/i18n/translator.d.ts +2 -1
- package/dist/i18n/translator.d.ts.map +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +3 -3
- package/dist/logger/record.d.ts +98 -0
- package/dist/logger/record.d.ts.map +1 -1
- package/dist/mcp/annotations.d.ts +20 -0
- package/dist/mcp/annotations.d.ts.map +1 -0
- package/dist/mcp/annotations.js +23 -0
- package/dist/mcp/tools.d.ts +75 -0
- package/dist/mcp/tools.d.ts.map +1 -0
- package/dist/mcp/tools.js +118 -0
- package/dist/openapi/document.d.ts.map +1 -1
- package/dist/openapi/document.js +8 -26
- package/dist/openapi/operations.d.ts +35 -0
- package/dist/openapi/operations.d.ts.map +1 -0
- package/dist/openapi/operations.js +37 -0
- package/dist/presence/channel.d.ts +11 -0
- package/dist/presence/channel.d.ts.map +1 -0
- package/dist/presence/channel.js +65 -0
- package/dist/presence/declaration.d.ts +154 -0
- package/dist/presence/declaration.d.ts.map +1 -0
- package/dist/presence/declaration.js +164 -0
- package/dist/presence/durableObject.d.ts +61 -0
- package/dist/presence/durableObject.d.ts.map +1 -0
- package/dist/presence/durableObject.js +257 -0
- package/dist/presence/frames.d.ts +166 -0
- package/dist/presence/frames.d.ts.map +1 -0
- package/dist/presence/frames.js +90 -0
- package/dist/presence/http/guard.d.ts +11 -0
- package/dist/presence/http/guard.d.ts.map +1 -0
- package/dist/presence/http/guard.js +20 -0
- package/dist/presence/http/responses.d.ts +31 -0
- package/dist/presence/http/responses.d.ts.map +1 -0
- package/dist/presence/http/responses.js +34 -0
- package/dist/presence/http/routes.d.ts +24 -0
- package/dist/presence/http/routes.d.ts.map +1 -0
- package/dist/presence/http/routes.js +127 -0
- package/dist/presence/http/schemas.d.ts +29 -0
- package/dist/presence/http/schemas.d.ts.map +1 -0
- package/dist/presence/http/schemas.js +28 -0
- package/dist/presence/names.d.ts +23 -0
- package/dist/presence/names.d.ts.map +1 -0
- package/dist/presence/names.js +22 -0
- package/dist/presence/room.d.ts +95 -0
- package/dist/presence/room.d.ts.map +1 -0
- package/dist/presence/room.js +105 -0
- package/dist/presence/ticket.d.ts +55 -0
- package/dist/presence/ticket.d.ts.map +1 -0
- package/dist/presence/ticket.js +109 -0
- package/dist/privacy/classify.js +1 -1
- package/dist/privacy/encrypted.js +1 -1
- package/dist/processing/activity.d.ts +134 -0
- package/dist/processing/activity.d.ts.map +1 -0
- package/dist/processing/activity.js +161 -0
- package/dist/processing/composed.d.ts +18 -0
- package/dist/processing/composed.d.ts.map +1 -0
- package/dist/processing/composed.js +28 -0
- package/dist/processing/vocabulary.d.ts +26 -0
- package/dist/processing/vocabulary.d.ts.map +1 -0
- package/dist/processing/vocabulary.js +35 -0
- package/dist/queue/consumer.d.ts +59 -0
- package/dist/queue/consumer.d.ts.map +1 -0
- package/dist/queue/consumer.js +46 -0
- package/dist/retention/composed.d.ts +37 -0
- package/dist/retention/composed.d.ts.map +1 -0
- package/dist/retention/composed.js +66 -0
- package/dist/retention/holds.d.ts +61 -0
- package/dist/retention/holds.d.ts.map +1 -0
- package/dist/retention/holds.js +107 -0
- package/dist/retention/holdsPurge.d.ts +22 -0
- package/dist/retention/holdsPurge.d.ts.map +1 -0
- package/dist/retention/holdsPurge.js +50 -0
- package/dist/retention/policy.d.ts +132 -0
- package/dist/retention/policy.d.ts.map +1 -0
- package/dist/retention/policy.js +197 -0
- package/dist/session/rotated.d.ts +34 -0
- package/dist/session/rotated.d.ts.map +1 -0
- package/dist/session/rotated.js +25 -0
- package/dist/test-utils/connectionFixtures.d.ts +13 -0
- package/dist/test-utils/connectionFixtures.d.ts.map +1 -0
- package/dist/test-utils/connectionFixtures.js +58 -0
- package/dist/test-utils/interleave.d.ts +12 -0
- package/dist/test-utils/interleave.d.ts.map +1 -0
- package/dist/test-utils/interleave.js +26 -0
- package/dist/testWorker.d.ts +8 -0
- package/dist/testWorker.d.ts.map +1 -0
- package/dist/testWorker.js +9 -0
- package/dist/version.generated.d.ts +1 -1
- package/dist/version.generated.js +1 -1
- package/dist/workflow/dispatchRoute.js +1 -1
- package/package.json +1 -1
- package/src/audit/auditEvent.ts +1 -1
- package/src/audit/chain.ts +551 -0
- package/src/audit/citations.ts +63 -0
- package/src/capability/bindings.ts +61 -0
- package/src/capability/capability.ts +156 -19
- package/src/capability/erasure.ts +82 -0
- package/src/capability/personColumns.ts +83 -0
- package/src/capability/personRows.ts +125 -0
- package/src/capability/purge.ts +158 -21
- package/src/capability/settings.ts +7 -0
- package/src/capability/vectorIndex.ts +60 -0
- package/src/cli/commandCatalog.generated.ts +487 -2
- package/src/cli/commandFacts.ts +12 -3
- package/src/cloudflare-test.d.ts +3 -1
- package/src/consent/purpose.ts +160 -0
- package/src/consent/reader.ts +134 -0
- package/src/controlPlane/audit/actions.ts +15 -4
- package/src/controlPlane/capability.ts +99 -20
- package/src/controlPlane/context.ts +10 -2
- package/src/controlPlane/data/connection.ts +16 -2
- package/src/controlPlane/data/connections.ts +231 -0
- package/src/controlPlane/data/hold.ts +52 -0
- package/src/controlPlane/data/oidcTrust.ts +249 -0
- package/src/controlPlane/data/tables.ts +7 -0
- package/src/controlPlane/data/trustFirstCall.ts +37 -0
- package/src/controlPlane/discovery/adminRoute.ts +71 -9
- package/src/controlPlane/discovery/routeInput.ts +86 -0
- package/src/controlPlane/discovery/toolName.ts +23 -0
- package/src/controlPlane/erasure/attest.ts +205 -0
- package/src/controlPlane/erasure/read.ts +169 -0
- package/src/controlPlane/error/errors.ts +69 -2
- package/src/controlPlane/evidence/derive.ts +426 -0
- package/src/controlPlane/evidence/mapping.ts +118 -0
- package/src/controlPlane/evidence/pack.ts +190 -0
- package/src/controlPlane/http/connections.ts +129 -0
- package/src/controlPlane/http/guard.ts +118 -9
- package/src/controlPlane/http/handlers.ts +172 -40
- package/src/controlPlane/http/holds.ts +108 -0
- package/src/controlPlane/http/presence.ts +71 -0
- package/src/controlPlane/http/processing.ts +19 -0
- package/src/controlPlane/http/responses.ts +590 -7
- package/src/controlPlane/http/routes.ts +302 -3
- package/src/controlPlane/http/schemas.ts +126 -0
- package/src/controlPlane/http/verify.ts +19 -2
- package/src/controlPlane/http/verifyTrust.ts +176 -0
- package/src/controlPlane/migrations/0004_connection_trusts.ts +30 -0
- package/src/controlPlane/migrations/0005_holds.ts +40 -0
- package/src/controlPlane/processing/derive.ts +359 -0
- package/src/controlPlane/processing/read.ts +102 -0
- package/src/controlPlane/scope/kind.ts +63 -0
- package/src/controlPlane/scope/scope.ts +65 -3
- package/src/controlPlane/wire.ts +26 -0
- package/src/createBackend.ts +31 -6
- package/src/createEntrypoint.ts +17 -0
- package/src/error/payload.ts +234 -0
- package/src/error/pithyError.ts +42 -0
- package/src/http/routeSpec.ts +75 -5
- package/src/http/verification.ts +3 -1
- package/src/i18n/translator.ts +2 -1
- package/src/index.ts +2 -0
- package/src/mcp/annotations.ts +38 -0
- package/src/mcp/tools.ts +220 -0
- package/src/openapi/document.ts +8 -28
- package/src/openapi/operations.ts +62 -0
- package/src/presence/channel.ts +46 -0
- package/src/presence/declaration.ts +283 -0
- package/src/presence/durableObject.ts +287 -0
- package/src/presence/frames.ts +153 -0
- package/src/presence/http/guard.ts +23 -0
- package/src/presence/http/responses.ts +63 -0
- package/src/presence/http/routes.ts +165 -0
- package/src/presence/http/schemas.ts +39 -0
- package/src/presence/names.ts +45 -0
- package/src/presence/room.ts +145 -0
- package/src/presence/ticket.ts +145 -0
- package/src/processing/activity.ts +289 -0
- package/src/processing/composed.ts +33 -0
- package/src/processing/vocabulary.ts +43 -0
- package/src/queue/consumer.ts +104 -0
- package/src/retention/composed.ts +75 -0
- package/src/retention/holds.ts +175 -0
- package/src/retention/holdsPurge.ts +50 -0
- package/src/retention/policy.ts +305 -0
- package/src/session/rotated.ts +53 -0
- package/src/test-utils/connectionFixtures.ts +58 -0
- package/src/test-utils/interleave.ts +31 -0
- package/src/testWorker.ts +13 -0
- package/src/version.generated.ts +1 -1
|
@@ -4,9 +4,12 @@ import type { ExecutionContext, ForwardableEmailMessage } from "@cloudflare/work
|
|
|
4
4
|
import type { Hono, MiddlewareHandler } from "hono";
|
|
5
5
|
import type { z } from "zod";
|
|
6
6
|
import type { ActingOrganizationResolver } from "../access/acting";
|
|
7
|
+
import type { AuditCitationReader } from "../audit/citations";
|
|
7
8
|
import type { AuditEmit } from "../audit/recorder";
|
|
9
|
+
import { type ConsentPurpose } from "../consent/purpose";
|
|
10
|
+
import type { ConsentGrantedListener, ConsentReader, ConsentWithdrawnListener } from "../consent/reader";
|
|
8
11
|
import type { ControlPlaneContext } from "../controlPlane/context";
|
|
9
|
-
import type {
|
|
12
|
+
import type { AdminRouteDeclaration } from "../controlPlane/discovery/adminRoute";
|
|
10
13
|
import type { CapabilityManifestConfig } from "../controlPlane/discovery/configuration";
|
|
11
14
|
import type { CapabilityHealth } from "../controlPlane/discovery/health";
|
|
12
15
|
import type { ControlPlaneVerifier } from "../controlPlane/http/guard";
|
|
@@ -20,12 +23,19 @@ import type { LocaleContext } from "../i18n/locale";
|
|
|
20
23
|
import type { Translator } from "../i18n/translator";
|
|
21
24
|
import type { KvNamespaceSpecMap } from "../kv/namespaces";
|
|
22
25
|
import type { Logger } from "../logger/logger";
|
|
26
|
+
import { type PresenceDeclaration } from "../presence/declaration";
|
|
27
|
+
import { type ProcessingActivity, type ProcessingActivityInput } from "../processing/activity";
|
|
28
|
+
import type { CapabilityQueueHandler } from "../queue/consumer";
|
|
29
|
+
import type { PurgeWindowDefault } from "../retention/policy";
|
|
23
30
|
import type { SeedSet } from "../seed/seed";
|
|
31
|
+
import type { SessionRotatedListener } from "../session/rotated";
|
|
24
32
|
import type { WorkflowSpecMap } from "../workflow/spec";
|
|
25
33
|
import { BindingSpec, type BindingSpecInput } from "./bindings";
|
|
26
34
|
import type { ClientProjection, ClientProjectionContext } from "./client";
|
|
35
|
+
import type { ErasureRecords } from "./erasure";
|
|
27
36
|
import { type PurgeContribution } from "./purge";
|
|
28
37
|
import type { CapabilitySettings } from "./settings";
|
|
38
|
+
import { type VectorIndexContribution } from "./vectorIndex";
|
|
29
39
|
/** Hono `Variables` every capability's routes are typed against. `createBackend` seeds these per request. */
|
|
30
40
|
export interface PithyVars {
|
|
31
41
|
/** The authenticated identity, populated by `@pithy-sh/auth`; `null` until a strategy sets it. */
|
|
@@ -176,7 +186,7 @@ export interface SecretRegistryEntrySeam {
|
|
|
176
186
|
readonly devValue?: string;
|
|
177
187
|
/**
|
|
178
188
|
* The Worker binding this value exists to reach, or absent when it reaches none — the constant half
|
|
179
|
-
* of *can this composition use this secret
|
|
189
|
+
* of *can this composition use this secret*.
|
|
180
190
|
*
|
|
181
191
|
* Read here and never interpreted, exactly like {@link devValue}: the CLI joins it against a Worker's
|
|
182
192
|
* `declinedBindings` so a credential whose bucket the project declined stops being listed as
|
|
@@ -200,7 +210,7 @@ export type SecretRegistrySeam = Record<string, SecretRegistryEntrySeam>;
|
|
|
200
210
|
* **It is declared, not matched by name.** `PaymentsRailToggles.paddle` and
|
|
201
211
|
* `PaymentsProviderCredentials.paddle` happen to be spelled the same today, and a CLI that keyed off
|
|
202
212
|
* that would be right by coincidence: nothing makes a config flag and a schema key the same thing, and
|
|
203
|
-
* two of them one line apart cannot be told apart by convention
|
|
213
|
+
* two of them one line apart cannot be told apart by convention. The capability already knows
|
|
204
214
|
* the answer at construction — it has both halves in hand — so it states it, and the CLI reads a fact
|
|
205
215
|
* instead of inferring one.
|
|
206
216
|
*
|
|
@@ -221,8 +231,8 @@ export type SecretBranchSeam = Record<string, readonly string[]>;
|
|
|
221
231
|
* The neighbor of {@link SecretBranchSeam}, one level up. That one says which *blocks* of a bundle
|
|
222
232
|
* apply when the bundle itself does; this says that a whole secret does not. `@pithy-sh/auth` declares
|
|
223
233
|
* one credential per OAuth provider, so a project running Google and GitHub has two secrets that no
|
|
224
|
-
* code path will ever read
|
|
225
|
-
*
|
|
234
|
+
* code path will ever read, and `pithy doctor` does not list them as outstanding work: the configuration
|
|
235
|
+
* has refused them.
|
|
226
236
|
*
|
|
227
237
|
* **Declared, never inferred**, for {@link SecretBranchSeam}'s reason: `auth-apple-credentials` and
|
|
228
238
|
* `providers.apple` are spelled alike today and nothing makes a secret name and a config key the same
|
|
@@ -296,7 +306,7 @@ export interface CapabilityComposeContext {
|
|
|
296
306
|
* message (an untouched message is dropped by the runtime).
|
|
297
307
|
*
|
|
298
308
|
* **`ForwardableEmailMessage` and `ExecutionContext` are imported rather than assumed ambient**, and
|
|
299
|
-
* that is
|
|
309
|
+
* that is deliberate. This module is reachable from a client: a browser program
|
|
300
310
|
* that names a control-plane scope through a capability's guards lands here, and a browser program
|
|
301
311
|
* has no Workers globals. Read off the global scope, the two names resolved only for a consumer that
|
|
302
312
|
* had `@cloudflare/workers-types` in its `types` — so an adopter's DOM program failed on two errors
|
|
@@ -379,7 +389,7 @@ export interface Capability<Databases extends DatabaseSpecMap = DatabaseSpecMap,
|
|
|
379
389
|
* The CF permissions this capability's **deployed Workers** call Cloudflare with, as short catalog keys
|
|
380
390
|
* (`secrets:write`, `images:write`, `analytics:read`). The runtime counterpart of {@link ciPermissions}.
|
|
381
391
|
*
|
|
382
|
-
* **A deployed application holds one Cloudflare API token, and this is the only way into it
|
|
392
|
+
* **A deployed application holds one Cloudflare API token, and this is the only way into it.**
|
|
383
393
|
* Every composed capability's keys union into the project-level `runtime` profile, minted per
|
|
384
394
|
* environment into the Secrets Store and read by every Worker of that environment through one binding,
|
|
385
395
|
* the way every capability's `ciPermissions` union into the one `ci-system` token. A capability cannot
|
|
@@ -406,10 +416,10 @@ export interface Capability<Databases extends DatabaseSpecMap = DatabaseSpecMap,
|
|
|
406
416
|
* the router that actually mounted; a stale declaration is worse than none, because a client
|
|
407
417
|
* believes it.
|
|
408
418
|
*/
|
|
409
|
-
adminRoutes?: readonly
|
|
419
|
+
adminRoutes?: readonly AdminRouteDeclaration[];
|
|
410
420
|
/**
|
|
411
421
|
* The bounded health summary this capability contributes to its own manifest entry — a small, fixed
|
|
412
|
-
* set of scalars a management client can render beside a rail without a second round trip
|
|
422
|
+
* set of scalars a management client can render beside a rail without a second round trip.
|
|
413
423
|
* Omit it when a capability has nothing to say, which is the normal case.
|
|
414
424
|
*
|
|
415
425
|
* **Declared alongside the routes, and only through `defineCapabilityHealth`.** The type is branded,
|
|
@@ -425,7 +435,7 @@ export interface Capability<Databases extends DatabaseSpecMap = DatabaseSpecMap,
|
|
|
425
435
|
health?: CapabilityHealth;
|
|
426
436
|
/**
|
|
427
437
|
* The configured facts this capability states into its own manifest entry — the decisions an adopter
|
|
428
|
-
* already made that a management client has to respect to call anything
|
|
438
|
+
* already made that a management client has to respect to call anything. Omit it when nothing
|
|
429
439
|
* this capability is configured with changes how a client calls it, which is the normal case.
|
|
430
440
|
*
|
|
431
441
|
* **A third field, because the two obvious names are taken and neither is this.**
|
|
@@ -446,7 +456,7 @@ export interface Capability<Databases extends DatabaseSpecMap = DatabaseSpecMap,
|
|
|
446
456
|
manifestConfig?: CapabilityManifestConfig;
|
|
447
457
|
/**
|
|
448
458
|
* How this capability checks that its own **settings work**, as opposed to being merely present — the
|
|
449
|
-
* seam `pithy doctor` runs for every capability every Worker composes
|
|
459
|
+
* seam `pithy doctor` runs for every capability every Worker composes. Omit it when a capability
|
|
450
460
|
* has nothing worth checking, which is the normal case and is silent rather than a fault.
|
|
451
461
|
*
|
|
452
462
|
* Declared here, on the instance, and **never keyed off `pithy.manifest.json`**: `@pithy-sh/matchmaking`
|
|
@@ -484,7 +494,7 @@ export interface Capability<Databases extends DatabaseSpecMap = DatabaseSpecMap,
|
|
|
484
494
|
* The npm **package** that supplies this capability, or `null` where there is none.
|
|
485
495
|
*
|
|
486
496
|
* The join key {@link Capability.version} is useless without. A version joins against a release feed
|
|
487
|
-
* by package name, and this
|
|
497
|
+
* by package name, and without this a client has to guess
|
|
488
498
|
* `@pithy-sh/${name}`, which is right for most capabilities and wrong for the one that matters:
|
|
489
499
|
* `controlplane` ships inside `@pithy-sh/core`, so the guess reaches a package that has never been
|
|
490
500
|
* published and the join comes back empty, which is indistinguishable from "up to date".
|
|
@@ -523,7 +533,7 @@ export interface Capability<Databases extends DatabaseSpecMap = DatabaseSpecMap,
|
|
|
523
533
|
* *load*, because the adopter's own toolchain has to keep working on the project while they fix it.
|
|
524
534
|
* `@pithy-sh/payments` is the case it exists for: `pithy add` scaffolds an unimplemented
|
|
525
535
|
* `resolveSubject`, every CLI command keeps loading that config, and the Worker refuses to boot until
|
|
526
|
-
* the adopter has written it
|
|
536
|
+
* the adopter has written it. A check that can be made at composition still belongs at
|
|
527
537
|
* composition — earlier is better, and a refusal the CLI can raise is a refusal an adopter sees sooner.
|
|
528
538
|
*/
|
|
529
539
|
boot?: (context: CapabilityComposeContext) => void;
|
|
@@ -535,6 +545,18 @@ export interface Capability<Databases extends DatabaseSpecMap = DatabaseSpecMap,
|
|
|
535
545
|
* parsed with. A capability with no socket leaves it unset.
|
|
536
546
|
*/
|
|
537
547
|
sockets?: readonly SocketChannel[];
|
|
548
|
+
/**
|
|
549
|
+
* The presence room kinds this capability serves (`../presence/declaration.ts`): who else has one of its
|
|
550
|
+
* records open, live. Omit it when a capability has no record more than one person acts on, which is the
|
|
551
|
+
* normal case.
|
|
552
|
+
*
|
|
553
|
+
* **Declaring it is the whole of the wiring.** `defineCapability` adds the `PRESENCE_ROOMS` Durable Object
|
|
554
|
+
* binding and the room socket to this capability's {@link requiredBindings} and {@link sockets};
|
|
555
|
+
* `createBackend` mounts `{basePath}/presence/tickets` and `{basePath}/presence/rooms/:kind/:recordId`
|
|
556
|
+
* beside its routes; the control-plane seam answers `POST /control-plane/presence/tickets` for every kind
|
|
557
|
+
* and lists them in the manifest. Build it from the resolved config, like {@link adminRoutes}.
|
|
558
|
+
*/
|
|
559
|
+
presence?: PresenceDeclaration;
|
|
538
560
|
/**
|
|
539
561
|
* Composable middleware (e.g. turnstile(), requireAuth()). Runs on every request, the control-plane
|
|
540
562
|
* surface included. A refusal that protects a route — a rate limit, authentication, a CSRF check —
|
|
@@ -573,7 +595,7 @@ export interface Capability<Databases extends DatabaseSpecMap = DatabaseSpecMap,
|
|
|
573
595
|
/**
|
|
574
596
|
* Whether this capability fills `AuthContext.scopes` — whether anything will ever put a string in the
|
|
575
597
|
* array the scope gates read. `@pithy-sh/auth` declares it when an adopter supplies `resolveScopes`, and
|
|
576
|
-
* not otherwise
|
|
598
|
+
* not otherwise.
|
|
577
599
|
*
|
|
578
600
|
* The same reason {@link providesEntitlements} exists, one seam over. Every scope gate fails closed, so a
|
|
579
601
|
* Worker composing `leaderboard` with no resolver is not broken: it refuses every caller on the gated
|
|
@@ -612,9 +634,16 @@ export interface Capability<Databases extends DatabaseSpecMap = DatabaseSpecMap,
|
|
|
612
634
|
* capability that declares one (e.g. `@pithy-sh/email`'s bounce/complaint handler).
|
|
613
635
|
*/
|
|
614
636
|
email?: CapabilityEmailHandler;
|
|
637
|
+
/**
|
|
638
|
+
* Queue consumer. The entrypoint (`createEntrypoint`) exposes the Worker's one `queue` export when any
|
|
639
|
+
* capability declares one, and hands each the messages of a batch whose body names it — see
|
|
640
|
+
* `../queue/consumer.ts` for why the body, not the queue name, decides. The queue itself is declared as a
|
|
641
|
+
* `queue` binding with a `consumer`, which is what writes the `queues.consumers` entry that delivers here.
|
|
642
|
+
*/
|
|
643
|
+
queue?: CapabilityQueueHandler;
|
|
615
644
|
/**
|
|
616
645
|
* The audit recorder this capability provides **for code that has no request** — a Workflow step, which the
|
|
617
|
-
* runtime constructs with `env` and nothing else
|
|
646
|
+
* runtime constructs with `env` and nothing else. `@pithy-sh/audit` declares it; nothing else does.
|
|
618
647
|
*
|
|
619
648
|
* A route records through `c.var.emit`, which the same capability's middleware fills, and keeps doing that.
|
|
620
649
|
* This is the other door, for the purge that erases a deleted account: it runs in a Workflow and still owes
|
|
@@ -623,6 +652,59 @@ export interface Capability<Databases extends DatabaseSpecMap = DatabaseSpecMap,
|
|
|
623
652
|
* from the env per call, like the request recorder is built per request. Non-fatal by the same contract.
|
|
624
653
|
*/
|
|
625
654
|
auditRecorder?: (env: Record<string, unknown>) => AuditEmit;
|
|
655
|
+
/**
|
|
656
|
+
* The trail's citation reader: which recorded events name a resource, and where each sits in its chain.
|
|
657
|
+
* `@pithy-sh/audit` declares it; nothing else does. The erasure attestation cites a purge's events through it,
|
|
658
|
+
* found among the composed capabilities by `../audit/citations.ts`, so the control plane imports no audit package.
|
|
659
|
+
*/
|
|
660
|
+
auditCitations?: (env: Record<string, unknown>) => AuditCitationReader;
|
|
661
|
+
/**
|
|
662
|
+
* The purposes this capability processes under consent — `@pithy-sh/email` declares `email.marketing`
|
|
663
|
+
* and `email.tracking`. Omit it when nothing here needs consent, which is the ordinary case.
|
|
664
|
+
*
|
|
665
|
+
* **Only under this capability's own `name`**, as `<name>.<purpose>`: `defineCapability` refuses anything else,
|
|
666
|
+
* the rule tables and error codes follow. The consent capability composes every declaration into the catalog its
|
|
667
|
+
* `hasConsent` answers from, and `pithy doctor` names a composition that declares purposes and records no consent.
|
|
668
|
+
*/
|
|
669
|
+
consentPurposes?: readonly ConsentPurpose[];
|
|
670
|
+
/**
|
|
671
|
+
* The processing activities this capability performs on personal data — `@pithy-sh/auth` declares `auth.account`.
|
|
672
|
+
* Each names a purpose, the data classes it uses and, where the capability can say, a default legal basis. Only
|
|
673
|
+
* under this capability's own `name`, as `<name>.<activity>`. `GET /control-plane/processing` derives the GDPR
|
|
674
|
+
* Article 30 record from them; see `../processing/activity.ts`. Build it from the resolved config, so a recipient
|
|
675
|
+
* that is switched off is not named.
|
|
676
|
+
*/
|
|
677
|
+
processing?: readonly ProcessingActivity[];
|
|
678
|
+
/**
|
|
679
|
+
* The consent seam's provider: a reader built over this run's env. `@pithy-sh/consent` declares it;
|
|
680
|
+
* nothing else does. A capability asks it through `composedConsent` in `../consent/reader.ts`, never by
|
|
681
|
+
* importing the consent package.
|
|
682
|
+
*/
|
|
683
|
+
consentReader?: (env: Record<string, unknown>) => ConsentReader;
|
|
684
|
+
/**
|
|
685
|
+
* Hear of a withdrawal from one of this capability's own purposes, to keep its own state in step — email
|
|
686
|
+
* suppresses an address for marketing when `email.marketing` is withdrawn. The consent capability calls
|
|
687
|
+
* it after the withdrawal is recorded, only for purposes under this capability's name.
|
|
688
|
+
*/
|
|
689
|
+
consentWithdrawn?: ConsentWithdrawnListener;
|
|
690
|
+
/**
|
|
691
|
+
* Hear of a grant to one of this capability's own purposes once it stands — the other half of
|
|
692
|
+
* {@link Capability.consentWithdrawn}. Email lifts the marketing suppression a withdrawal wrote when
|
|
693
|
+
* `email.marketing` is granted again, so the suppression list and the record never disagree either way.
|
|
694
|
+
*/
|
|
695
|
+
consentGranted?: ConsentGrantedListener;
|
|
696
|
+
/**
|
|
697
|
+
* Hear of a session replaced by its successor, to carry state keyed on the old session id to the new one —
|
|
698
|
+
* `@pithy-sh/organization` moves the acting selection. The capability that owns sessions announces it through
|
|
699
|
+
* `announceSessionRotated` in `../session/rotated.ts`, so neither side imports the other.
|
|
700
|
+
*/
|
|
701
|
+
sessionRotated?: SessionRotatedListener;
|
|
702
|
+
/**
|
|
703
|
+
* An account's email address, by user id, or `null` when it has none — the capability that owns accounts
|
|
704
|
+
* declares it (`@pithy-sh/auth`), so a capability holding state by address finds one without importing auth.
|
|
705
|
+
* Read on demand, never carried.
|
|
706
|
+
*/
|
|
707
|
+
addressOf?: (env: Record<string, unknown>, userId: string) => Promise<string | null>;
|
|
626
708
|
/**
|
|
627
709
|
* Named D1 databases this capability contributes tables to (database name → {@link DatabaseSpec}).
|
|
628
710
|
* `createBackend` merges every capability's slices per database (via `composeDatabases`) and serves
|
|
@@ -660,6 +742,24 @@ export interface Capability<Databases extends DatabaseSpecMap = DatabaseSpecMap,
|
|
|
660
742
|
* on their own `app` capability for their own tables, with the same types.
|
|
661
743
|
*/
|
|
662
744
|
purge?: readonly PurgeContribution[];
|
|
745
|
+
/**
|
|
746
|
+
* How this capability's record of a purge is read back — declared by the capability that owns a purge
|
|
747
|
+
* subject and runs its purge: `@pithy-sh/auth` for a user, `@pithy-sh/organization` for an organization. The
|
|
748
|
+
* control plane's erasure attestation reads it. See `./erasure.ts`.
|
|
749
|
+
*/
|
|
750
|
+
erasureRecords?: ErasureRecords;
|
|
751
|
+
/**
|
|
752
|
+
* This capability's own soft-delete window — declared by the capability that owns a deletion, from its
|
|
753
|
+
* own `retention.purgeAfterDays`. A Worker's `retention` block may replace it; `GET /control-plane/manifest`
|
|
754
|
+
* and `pithy doctor` report which window takes effect and where it came from. See `../retention/policy.ts`.
|
|
755
|
+
*/
|
|
756
|
+
purgeWindow?: PurgeWindowDefault;
|
|
757
|
+
/**
|
|
758
|
+
* The audit actions that record this capability's lifecycle transitions beyond its erasure — a suspension, a
|
|
759
|
+
* reinstatement, a restore. The retention floor covers each, beside the actions `erasureRecords` names, so an
|
|
760
|
+
* operator lifting a suspension is kept as long as the deletion it reversed. See `../retention/policy.ts`.
|
|
761
|
+
*/
|
|
762
|
+
lifecycleAuditActions?: readonly string[];
|
|
663
763
|
/**
|
|
664
764
|
* The role powers this capability's own routes gate on, through the acting-organization seam —
|
|
665
765
|
* `media:manage`, `storage:manage`. Omit it when a capability asks no power, which is the normal case.
|
|
@@ -671,12 +771,19 @@ export interface Capability<Databases extends DatabaseSpecMap = DatabaseSpecMap,
|
|
|
671
771
|
* importing any of them.
|
|
672
772
|
*/
|
|
673
773
|
powers?: readonly string[];
|
|
774
|
+
/**
|
|
775
|
+
* The Vectorize indexes this capability owns and re-embeds in a Workflow of its own — see `./vectorIndex.ts`.
|
|
776
|
+
* `pithy vector reprocess` reads them beside `vector()`'s own indexes, so one command re-embeds every
|
|
777
|
+
* index in the project. Omit it when a capability owns no index, which is the ordinary case.
|
|
778
|
+
*/
|
|
779
|
+
vectorIndexes?: readonly VectorIndexContribution[];
|
|
674
780
|
/** Bindings this capability needs in the env (normalized — `optional` is always set). */
|
|
675
781
|
requiredBindings: BindingSpec[];
|
|
676
782
|
}
|
|
677
783
|
/** Authoring shape: `requiredBindings` may omit `optional`; `defineCapability` normalizes them. */
|
|
678
|
-
export type CapabilityInput<Databases extends DatabaseSpecMap = Record<never, never>, Namespaces extends KvNamespaceSpecMap = Record<never, never>, Name extends string = string, Workflows extends WorkflowSpecMap = Record<never, never>> = Omit<Capability<Databases, Namespaces, Name, Workflows>, "requiredBindings"> & {
|
|
784
|
+
export type CapabilityInput<Databases extends DatabaseSpecMap = Record<never, never>, Namespaces extends KvNamespaceSpecMap = Record<never, never>, Name extends string = string, Workflows extends WorkflowSpecMap = Record<never, never>> = Omit<Capability<Databases, Namespaces, Name, Workflows>, "requiredBindings" | "processing"> & {
|
|
679
785
|
requiredBindings: BindingSpecInput[];
|
|
786
|
+
processing?: readonly ProcessingActivityInput[];
|
|
680
787
|
};
|
|
681
788
|
/**
|
|
682
789
|
* Author a capability. Parses each binding through `BindingSpec` — normalizing `optional`
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"capability.d.ts","sourceRoot":"","sources":["../../src/capability/capability.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,gBAAgB,EAAE,uBAAuB,EAAE,MAAM,2BAA2B,CAAC;AAC3F,OAAO,KAAK,EAAE,IAAI,EAAE,iBAAiB,EAAE,MAAM,MAAM,CAAC;AACpD,OAAO,KAAK,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAC7B,OAAO,KAAK,EAAE,0BAA0B,EAAE,MAAM,kBAAkB,CAAC;AACnE,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,mBAAmB,CAAC;AACnD,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,yBAAyB,CAAC;AACnE,OAAO,KAAK,EAAE,
|
|
1
|
+
{"version":3,"file":"capability.d.ts","sourceRoot":"","sources":["../../src/capability/capability.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,8 +1,13 @@
|
|
|
1
1
|
// SPDX-FileCopyrightText: 2026 Pithy
|
|
2
2
|
// SPDX-License-Identifier: MIT
|
|
3
3
|
import { BindingSpec } from "./bindings.js";
|
|
4
|
+
import { parseConsentPurposes } from "../consent/purpose.js";
|
|
4
5
|
import { declareRetained } from "../migrations/retainedDeclaration.js";
|
|
6
|
+
import { PRESENCE_ROOMS_BINDING_SPEC, assertPresenceDeclaration } from "../presence/declaration.js";
|
|
7
|
+
import { presenceRoomsSocket } from "../presence/channel.js";
|
|
8
|
+
import { parseProcessingActivities } from "../processing/activity.js";
|
|
5
9
|
import { assertPurgeContributions } from "./purge.js";
|
|
10
|
+
import { assertVectorIndexContributions } from "./vectorIndex.js";
|
|
6
11
|
//#region src/capability/capability.ts
|
|
7
12
|
/**
|
|
8
13
|
* Author a capability. Parses each binding through `BindingSpec` — normalizing `optional`
|
|
@@ -13,9 +18,19 @@ import { assertPurgeContributions } from "./purge.js";
|
|
|
13
18
|
function defineCapability(input) {
|
|
14
19
|
for (const spec of Object.values(input.databases ?? {})) if (spec.migrations && spec.retained) declareRetained(spec.migrations, spec.retained);
|
|
15
20
|
if (input.purge) assertPurgeContributions(input.name, input.purge);
|
|
21
|
+
if (input.vectorIndexes) assertVectorIndexContributions(input.name, input.vectorIndexes, Object.keys(input.workflows ?? {}));
|
|
22
|
+
const consentPurposes = input.consentPurposes ? parseConsentPurposes(input.name, input.consentPurposes, input.name) : void 0;
|
|
23
|
+
const processing = input.processing ? parseProcessingActivities(input.name, input.processing, input.name) : void 0;
|
|
24
|
+
const presence = input.presence && input.presence.rooms.length > 0 ? input.presence : void 0;
|
|
25
|
+
if (presence) assertPresenceDeclaration(input.name, presence, input.adminRoutes ?? []);
|
|
26
|
+
const requiredBindings = presence && !input.requiredBindings.some((binding) => binding.name === PRESENCE_ROOMS_BINDING_SPEC.name) ? [...input.requiredBindings, PRESENCE_ROOMS_BINDING_SPEC] : input.requiredBindings;
|
|
27
|
+
const { processing: _declared, ...declared } = input;
|
|
16
28
|
return {
|
|
17
|
-
...
|
|
18
|
-
|
|
29
|
+
...declared,
|
|
30
|
+
...consentPurposes ? { consentPurposes } : {},
|
|
31
|
+
...processing ? { processing } : {},
|
|
32
|
+
...presence ? { sockets: [...input.sockets ?? [], presenceRoomsSocket(input.name, presence)] } : {},
|
|
33
|
+
requiredBindings: requiredBindings.map((binding) => BindingSpec.parse(binding))
|
|
19
34
|
};
|
|
20
35
|
}
|
|
21
36
|
//#endregion
|
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
// SPDX-FileCopyrightText: 2026 Pithy
|
|
2
|
+
// SPDX-License-Identifier: MIT
|
|
3
|
+
import type { PurgeSubject } from "./purge";
|
|
4
|
+
/**
|
|
5
|
+
* **The erasure record (#823): what a capability that runs a purge kept about it, read back.**
|
|
6
|
+
*
|
|
7
|
+
* A purge (#620, #623) records its progress in the lifecycle table of the capability that owns the subject:
|
|
8
|
+
* `pithy_auth_user_lifecycle` for a user, `pithy_organization_lifecycle` for an organization. Each holds the
|
|
9
|
+
* deletion, one row per step (erased, or retained with its basis under #814), a failure when the purge gave up, and
|
|
10
|
+
* the `purged` row at the end, keyed by the subject's id and nothing else.
|
|
11
|
+
*
|
|
12
|
+
* The control plane's erasure attestation assembles those rows into a record an auditor can be handed. It cannot
|
|
13
|
+
* import auth or organization (principle 4), so the capability that owns a subject declares how its rows are read,
|
|
14
|
+
* here, and which audit actions its purge records — so the attestation can cite them in the chain (#822).
|
|
15
|
+
*
|
|
16
|
+
* **Nothing about the person crosses this seam** beyond the id the trail already keeps: no address, no name.
|
|
17
|
+
*/
|
|
18
|
+
/** What happened, as the lifecycle tables name it. Only the rows an erasure is made of. */
|
|
19
|
+
export type ErasureHistoryAction = "deleted" | "restored" | "purge_step" | "purge_retained" | "purge_failed" | "purged";
|
|
20
|
+
/** How a deletion was asked for: with a window (`soft`) or none (`hard`). */
|
|
21
|
+
export type ErasureDeletionMode = "soft" | "hard";
|
|
22
|
+
/** One row of a subject's lifecycle, as the attestation reads it. Oldest first, in the order it was written. */
|
|
23
|
+
export interface ErasureHistoryRow {
|
|
24
|
+
/** The subject's id. */
|
|
25
|
+
readonly subjectId: string;
|
|
26
|
+
/** What happened. */
|
|
27
|
+
readonly action: ErasureHistoryAction;
|
|
28
|
+
/** Who did it: `control-plane`, `user` or `system`. */
|
|
29
|
+
readonly actorType: string;
|
|
30
|
+
/** Why, in whoever acted's words. A step's summary, a retained step's basis. Null when nobody had to say. */
|
|
31
|
+
readonly reason: string | null;
|
|
32
|
+
/** The purge step a step, retained or failed row names — the capability, or the purge's own step. */
|
|
33
|
+
readonly step: string | null;
|
|
34
|
+
/** On a `deleted` row written since #823, how the deletion was asked for. Null before. */
|
|
35
|
+
readonly mode: ErasureDeletionMode | null;
|
|
36
|
+
/** On a `deleted` row written since #823, when its purge comes due. Null before. */
|
|
37
|
+
readonly purgeAfter: Date | null;
|
|
38
|
+
/** When it happened. */
|
|
39
|
+
readonly at: Date;
|
|
40
|
+
}
|
|
41
|
+
/** The audit actions one subject's purge records, so the attestation cites them. */
|
|
42
|
+
export interface ErasureAuditActions {
|
|
43
|
+
/** Every action a deletion of the subject is recorded under — soft, hard, by its owner. */
|
|
44
|
+
readonly deleted: readonly string[];
|
|
45
|
+
/** One purge step: erased or retained, its `metadata.step` naming which. */
|
|
46
|
+
readonly step: string;
|
|
47
|
+
/** The purge giving up, its `metadata.step` naming where. */
|
|
48
|
+
readonly failed: string;
|
|
49
|
+
/** The purge finishing. */
|
|
50
|
+
readonly purged: string;
|
|
51
|
+
}
|
|
52
|
+
/** Reading one kind of subject's erasure rows, over one env. */
|
|
53
|
+
export interface ErasureHistoryReader {
|
|
54
|
+
/** Every erasure row for these subjects, oldest first. A subject with none is absent. */
|
|
55
|
+
history(subjectIds: readonly string[]): Promise<ErasureHistoryRow[]>;
|
|
56
|
+
/**
|
|
57
|
+
* Every subject with a purge in the window: a step, a failure or a completion written in it, a deletion whose
|
|
58
|
+
* purge came due in it, or one still outstanding in it — due by its end (or recorded before a due instant was) and
|
|
59
|
+
* neither purged nor restored before it opened. The last is the purge that came due earlier and has written nothing
|
|
60
|
+
* since, which is the one a period read exists to name. Inclusive at both ends.
|
|
61
|
+
*/
|
|
62
|
+
subjectsIn(since: Date, until: Date): Promise<string[]>;
|
|
63
|
+
}
|
|
64
|
+
/** What a capability that owns a purge subject declares: which subject, its trail, and how its rows are read. */
|
|
65
|
+
export interface ErasureRecords {
|
|
66
|
+
/** The subject this capability's purge erases. One capability per subject. */
|
|
67
|
+
readonly subject: PurgeSubject;
|
|
68
|
+
/** The `resourceType` its audit events are recorded against. */
|
|
69
|
+
readonly resourceType: string;
|
|
70
|
+
/** The audit actions its purge records. */
|
|
71
|
+
readonly auditActions: ErasureAuditActions;
|
|
72
|
+
/** The reader, over one env. */
|
|
73
|
+
readonly read: (env: Record<string, unknown>) => ErasureHistoryReader;
|
|
74
|
+
}
|
|
75
|
+
//# sourceMappingURL=erasure.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"erasure.d.ts","sourceRoot":"","sources":["../../src/capability/erasure.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AAE5C;;;;;;;;;;;;;GAaG;AAEH,2FAA2F;AAC3F,MAAM,MAAM,oBAAoB,GAAG,SAAS,GAAG,UAAU,GAAG,YAAY,GAAG,gBAAgB,GAAG,cAAc,GAAG,QAAQ,CAAC;AAExH,6EAA6E;AAC7E,MAAM,MAAM,mBAAmB,GAAG,MAAM,GAAG,MAAM,CAAC;AAElD,gHAAgH;AAChH,MAAM,WAAW,iBAAiB;IAChC,wBAAwB;IACxB,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;IAC3B,qBAAqB;IACrB,QAAQ,CAAC,MAAM,EAAE,oBAAoB,CAAC;IACtC,uDAAuD;IACvD,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;IAC3B,6GAA6G;IAC7G,QAAQ,CAAC,MAAM,EAAE,MAAM,GAAG,IAAI,CAAC;IAC/B,qGAAqG;IACrG,QAAQ,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI,CAAC;IAC7B,0FAA0F;IAC1F,QAAQ,CAAC,IAAI,EAAE,mBAAmB,GAAG,IAAI,CAAC;IAC1C,oFAAoF;IACpF,QAAQ,CAAC,UAAU,EAAE,IAAI,GAAG,IAAI,CAAC;IACjC,wBAAwB;IACxB,QAAQ,CAAC,EAAE,EAAE,IAAI,CAAC;CACnB;AAED,oFAAoF;AACpF,MAAM,WAAW,mBAAmB;IAClC,2FAA2F;IAC3F,QAAQ,CAAC,OAAO,EAAE,SAAS,MAAM,EAAE,CAAC;IACpC,4EAA4E;IAC5E,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,6DAA6D;IAC7D,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,2BAA2B;IAC3B,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;CACzB;AAED,gEAAgE;AAChE,MAAM,WAAW,oBAAoB;IACnC,yFAAyF;IACzF,OAAO,CAAC,UAAU,EAAE,SAAS,MAAM,EAAE,GAAG,OAAO,CAAC,iBAAiB,EAAE,CAAC,CAAC;IACrE;;;;;OAKG;IACH,UAAU,CAAC,KAAK,EAAE,IAAI,EAAE,KAAK,EAAE,IAAI,GAAG,OAAO,CAAC,MAAM,EAAE,CAAC,CAAC;CACzD;AAED,iHAAiH;AACjH,MAAM,WAAW,cAAc;IAC7B,8EAA8E;IAC9E,QAAQ,CAAC,OAAO,EAAE,YAAY,CAAC;IAC/B,gEAAgE;IAChE,QAAQ,CAAC,YAAY,EAAE,MAAM,CAAC;IAC9B,2CAA2C;IAC3C,QAAQ,CAAC,YAAY,EAAE,mBAAmB,CAAC;IAC3C,gCAAgC;IAChC,QAAQ,CAAC,IAAI,EAAE,CAAC,GAAG,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,KAAK,oBAAoB,CAAC;CACvE"}
|
|
@@ -309,6 +309,11 @@ export declare const CapabilityManifest: z.ZodObject<{
|
|
|
309
309
|
global: "global";
|
|
310
310
|
}>>;
|
|
311
311
|
resource: z.ZodOptional<z.ZodString>;
|
|
312
|
+
consumer: z.ZodOptional<z.ZodObject<{
|
|
313
|
+
deadLetter: z.ZodString;
|
|
314
|
+
maxRetries: z.ZodNumber;
|
|
315
|
+
maxBatchSize: z.ZodOptional<z.ZodNumber>;
|
|
316
|
+
}, z.core.$strip>>;
|
|
312
317
|
}, z.core.$strip>>;
|
|
313
318
|
peerCapabilities: z.ZodDefault<z.ZodArray<z.ZodString>>;
|
|
314
319
|
optionalCapabilities: z.ZodDefault<z.ZodArray<z.ZodString>>;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"manifest.d.ts","sourceRoot":"","sources":["../../src/capability/manifest.ts"],"names":[],"mappings":"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
|
|
1
|
+
{"version":3,"file":"manifest.d.ts","sourceRoot":"","sources":["../../src/capability/manifest.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
// SPDX-FileCopyrightText: 2026 Pithy
|
|
2
|
+
// SPDX-License-Identifier: MIT
|
|
3
|
+
import type { DatabaseSpecMap } from "../data/databases";
|
|
4
|
+
/** Whether a column, by its camelCase name, names a person: an id of one, or an address. */
|
|
5
|
+
export declare function isPersonColumn(column: string): boolean;
|
|
6
|
+
/** What the check reads off a capability — its name, its tables and its purge contributions. */
|
|
7
|
+
export interface PersonRowsSubject {
|
|
8
|
+
readonly name: string;
|
|
9
|
+
readonly databases?: DatabaseSpecMap;
|
|
10
|
+
readonly purge?: readonly {
|
|
11
|
+
readonly subject: string;
|
|
12
|
+
readonly export?: unknown;
|
|
13
|
+
}[];
|
|
14
|
+
}
|
|
15
|
+
/** One capability that holds rows about a person and does not answer for them. */
|
|
16
|
+
export interface PersonRowGap {
|
|
17
|
+
/** The capability. */
|
|
18
|
+
readonly capability: string;
|
|
19
|
+
/** Its person columns, as `table.column`. */
|
|
20
|
+
readonly columns: readonly string[];
|
|
21
|
+
/** `no_contribution` — no `user` purge contribution at all; `no_export` — one that does not export. */
|
|
22
|
+
readonly gap: "no_contribution" | "no_export";
|
|
23
|
+
}
|
|
24
|
+
/** Every person column in a capability's tables, as `table.column`, in declaration order. */
|
|
25
|
+
export declare function personColumnsOf(capability: PersonRowsSubject): string[];
|
|
26
|
+
/** Every capability among `capabilities` that holds rows about a person and does not answer for them. */
|
|
27
|
+
export declare function personRowGaps(capabilities: readonly PersonRowsSubject[]): PersonRowGap[];
|
|
28
|
+
//# sourceMappingURL=personColumns.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"personColumns.d.ts","sourceRoot":"","sources":["../../src/capability/personColumns.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,mBAAmB,CAAC;AAgCzD,4FAA4F;AAC5F,wBAAgB,cAAc,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAEtD;AAED,gGAAgG;AAChG,MAAM,WAAW,iBAAiB;IAChC,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,SAAS,CAAC,EAAE,eAAe,CAAC;IACrC,QAAQ,CAAC,KAAK,CAAC,EAAE,SAAS;QAAE,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;QAAC,QAAQ,CAAC,MAAM,CAAC,EAAE,OAAO,CAAA;KAAE,EAAE,CAAC;CACrF;AAED,kFAAkF;AAClF,MAAM,WAAW,YAAY;IAC3B,sBAAsB;IACtB,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC;IAC5B,6CAA6C;IAC7C,QAAQ,CAAC,OAAO,EAAE,SAAS,MAAM,EAAE,CAAC;IACpC,uGAAuG;IACvG,QAAQ,CAAC,GAAG,EAAE,iBAAiB,GAAG,WAAW,CAAC;CAC/C;AAED,6FAA6F;AAC7F,wBAAgB,eAAe,CAAC,UAAU,EAAE,iBAAiB,GAAG,MAAM,EAAE,CASvE;AAED,yGAAyG;AACzG,wBAAgB,aAAa,CAAC,YAAY,EAAE,SAAS,iBAAiB,EAAE,GAAG,YAAY,EAAE,CAWxF"}
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
// SPDX-FileCopyrightText: 2026 Pithy
|
|
2
|
+
// SPDX-License-Identifier: MIT
|
|
3
|
+
//#region src/capability/personColumns.ts
|
|
4
|
+
/**
|
|
5
|
+
* **Every capability that holds rows about a person answers for them** — erases them on a purge, or keeps them and
|
|
6
|
+
* says why, and in both cases exports them (#814). This is the check that holds a capability to it, from its own
|
|
7
|
+
* schema rather than from a list somebody maintains.
|
|
8
|
+
*
|
|
9
|
+
* A table carries a row about a person when a column names one: an id (`userId`, `ownerId`, `subjectId`, `actorId`,
|
|
10
|
+
* any `…UserId`, the two sides of an invite or a friendship) or an address (`email`, `recipient`, any `…Address`).
|
|
11
|
+
* A capability whose schema carries one must declare a `user` purge contribution with an `export`. `retain` requires
|
|
12
|
+
* one already; an erasing contribution may omit it, and for an adopter's own capability that is the honest
|
|
13
|
+
* `not_exported` — but no kit capability may.
|
|
14
|
+
*
|
|
15
|
+
* Over-reaching is cheap here and under-reaching is the defect: a column that names an operator or a sender rather
|
|
16
|
+
* than the person still costs only a contribution that finds nothing, while a person column the rule missed is rows
|
|
17
|
+
* an access request never answers for.
|
|
18
|
+
*/
|
|
19
|
+
/** Column names that name a person outright. */
|
|
20
|
+
const PERSON_COLUMNS = /* @__PURE__ */ new Set([
|
|
21
|
+
"userId",
|
|
22
|
+
"ownerId",
|
|
23
|
+
"subjectId",
|
|
24
|
+
"actorId",
|
|
25
|
+
"inviterId",
|
|
26
|
+
"inviteeId",
|
|
27
|
+
"userA",
|
|
28
|
+
"userB",
|
|
29
|
+
"email",
|
|
30
|
+
"recipient"
|
|
31
|
+
]);
|
|
32
|
+
/** Whether a column, by its camelCase name, names a person: an id of one, or an address. */
|
|
33
|
+
function isPersonColumn(column) {
|
|
34
|
+
return PERSON_COLUMNS.has(column) || column.endsWith("UserId") || column.endsWith("Address");
|
|
35
|
+
}
|
|
36
|
+
/** Every person column in a capability's tables, as `table.column`, in declaration order. */
|
|
37
|
+
function personColumnsOf(capability) {
|
|
38
|
+
const found = [];
|
|
39
|
+
for (const spec of Object.values(capability.databases ?? {})) for (const [table, schema] of Object.entries(spec.tables)) {
|
|
40
|
+
const shape = schema.shape ?? {};
|
|
41
|
+
for (const column of Object.keys(shape)) if (isPersonColumn(column)) found.push(`${table}.${column}`);
|
|
42
|
+
}
|
|
43
|
+
return found;
|
|
44
|
+
}
|
|
45
|
+
/** Every capability among `capabilities` that holds rows about a person and does not answer for them. */
|
|
46
|
+
function personRowGaps(capabilities) {
|
|
47
|
+
const gaps = [];
|
|
48
|
+
for (const capability of capabilities) {
|
|
49
|
+
const columns = personColumnsOf(capability);
|
|
50
|
+
if (columns.length === 0) continue;
|
|
51
|
+
const contribution = capability.purge?.find((candidate) => candidate.subject === "user");
|
|
52
|
+
if (!contribution) gaps.push({
|
|
53
|
+
capability: capability.name,
|
|
54
|
+
columns,
|
|
55
|
+
gap: "no_contribution"
|
|
56
|
+
});
|
|
57
|
+
else if (typeof contribution.export !== "function") gaps.push({
|
|
58
|
+
capability: capability.name,
|
|
59
|
+
columns,
|
|
60
|
+
gap: "no_export"
|
|
61
|
+
});
|
|
62
|
+
}
|
|
63
|
+
return gaps;
|
|
64
|
+
}
|
|
65
|
+
//#endregion
|
|
66
|
+
export { isPersonColumn, personColumnsOf, personRowGaps };
|