@contractspec/lib.contracts 0.0.0-canary-20260113162409
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/LICENSE +21 -0
- package/README.md +109 -0
- package/dist/_virtual/rolldown_runtime.js +37 -0
- package/dist/app-config/app-config.capability.d.ts +7 -0
- package/dist/app-config/app-config.capability.js +23 -0
- package/dist/app-config/app-config.feature.d.ts +11 -0
- package/dist/app-config/app-config.feature.js +61 -0
- package/dist/app-config/branding.d.ts +55 -0
- package/dist/app-config/branding.js +0 -0
- package/dist/app-config/contracts.d.ts +245 -0
- package/dist/app-config/contracts.js +395 -0
- package/dist/app-config/docs/app-config.docblock.d.ts +6 -0
- package/dist/app-config/docs/app-config.docblock.js +21 -0
- package/dist/app-config/events.d.ts +122 -0
- package/dist/app-config/events.js +174 -0
- package/dist/app-config/index.d.ts +10 -0
- package/dist/app-config/index.js +9 -0
- package/dist/app-config/lifecycle-contracts.d.ts +273 -0
- package/dist/app-config/lifecycle-contracts.js +440 -0
- package/dist/app-config/lifecycle.d.ts +27 -0
- package/dist/app-config/lifecycle.js +0 -0
- package/dist/app-config/runtime.d.ts +120 -0
- package/dist/app-config/runtime.js +617 -0
- package/dist/app-config/spec.d.ts +175 -0
- package/dist/app-config/spec.js +19 -0
- package/dist/app-config/validation.d.ts +49 -0
- package/dist/app-config/validation.js +538 -0
- package/dist/capabilities/capabilities.d.ts +41 -0
- package/dist/capabilities/capabilities.js +48 -0
- package/dist/capabilities/docs/capabilities.docblock.d.ts +6 -0
- package/dist/capabilities/docs/capabilities.docblock.js +21 -0
- package/dist/capabilities/index.d.ts +3 -0
- package/dist/capabilities/index.js +4 -0
- package/dist/capabilities/openbanking.d.ts +10 -0
- package/dist/capabilities/openbanking.js +92 -0
- package/dist/client/index.d.ts +6 -0
- package/dist/client/index.js +9 -0
- package/dist/client/react/drivers/rn-reusables.d.ts +22 -0
- package/dist/client/react/drivers/rn-reusables.js +21 -0
- package/dist/client/react/drivers/shadcn.d.ts +12 -0
- package/dist/client/react/drivers/shadcn.js +11 -0
- package/dist/client/react/feature-render.d.ts +23 -0
- package/dist/client/react/feature-render.js +44 -0
- package/dist/client/react/form-render.d.ts +92 -0
- package/dist/client/react/form-render.js +301 -0
- package/dist/client/react/index.d.ts +5 -0
- package/dist/client/react/index.js +8 -0
- package/dist/contract-registry/index.d.ts +3 -0
- package/dist/contract-registry/index.js +3 -0
- package/dist/contract-registry/schemas.d.ts +124 -0
- package/dist/contract-registry/schemas.js +61 -0
- package/dist/contract-registry/types.d.ts +46 -0
- package/dist/contract-registry/types.js +0 -0
- package/dist/data-views/data-views.d.ts +5 -0
- package/dist/data-views/data-views.js +5 -0
- package/dist/data-views/docs/data-views.docblock.d.ts +6 -0
- package/dist/data-views/docs/data-views.docblock.js +21 -0
- package/dist/data-views/index.d.ts +4 -0
- package/dist/data-views/index.js +4 -0
- package/dist/data-views/query-generator.d.ts +40 -0
- package/dist/data-views/query-generator.js +48 -0
- package/dist/data-views/registry.d.ts +17 -0
- package/dist/data-views/registry.js +20 -0
- package/dist/data-views/runtime.d.ts +32 -0
- package/dist/data-views/runtime.js +68 -0
- package/dist/data-views/spec.d.ts +32 -0
- package/dist/data-views/spec.js +10 -0
- package/dist/data-views/types.d.ts +157 -0
- package/dist/data-views/types.js +0 -0
- package/dist/docs/accessibility_wcag_compliance_specs.docblock.d.ts +6 -0
- package/dist/docs/accessibility_wcag_compliance_specs.docblock.js +17 -0
- package/dist/docs/index.d.ts +6 -0
- package/dist/docs/index.js +30 -0
- package/dist/docs/meta.docs.d.ts +6 -0
- package/dist/docs/meta.docs.js +29 -0
- package/dist/docs/presentations.d.ts +31 -0
- package/dist/docs/presentations.js +57 -0
- package/dist/docs/registry.d.ts +23 -0
- package/dist/docs/registry.js +51 -0
- package/dist/docs/tech/auth/better-auth-nextjs.docblock.d.ts +6 -0
- package/dist/docs/tech/auth/better-auth-nextjs.docblock.js +81 -0
- package/dist/docs/tech/cli.docblock.d.ts +6 -0
- package/dist/docs/tech/cli.docblock.js +138 -0
- package/dist/docs/tech/contracts/README.docblock.d.ts +6 -0
- package/dist/docs/tech/contracts/README.docblock.js +21 -0
- package/dist/docs/tech/contracts/migrations.docblock.d.ts +6 -0
- package/dist/docs/tech/contracts/migrations.docblock.js +21 -0
- package/dist/docs/tech/contracts/openapi-export.docblock.d.ts +6 -0
- package/dist/docs/tech/contracts/openapi-export.docblock.js +58 -0
- package/dist/docs/tech/contracts/openapi-import.docblock.d.ts +6 -0
- package/dist/docs/tech/contracts/openapi-import.docblock.js +65 -0
- package/dist/docs/tech/contracts/ops-to-presentation-linking.docblock.d.ts +6 -0
- package/dist/docs/tech/contracts/ops-to-presentation-linking.docblock.js +21 -0
- package/dist/docs/tech/contracts/overlays.docblock.d.ts +6 -0
- package/dist/docs/tech/contracts/overlays.docblock.js +21 -0
- package/dist/docs/tech/contracts/tests.docblock.d.ts +6 -0
- package/dist/docs/tech/contracts/tests.docblock.js +21 -0
- package/dist/docs/tech/contracts/themes.docblock.d.ts +6 -0
- package/dist/docs/tech/contracts/themes.docblock.js +21 -0
- package/dist/docs/tech/contracts/vertical-pocket-family-office.docblock.d.ts +6 -0
- package/dist/docs/tech/contracts/vertical-pocket-family-office.docblock.js +126 -0
- package/dist/docs/tech/lifecycle-stage-system.docblock.d.ts +6 -0
- package/dist/docs/tech/lifecycle-stage-system.docblock.js +17 -0
- package/dist/docs/tech/llm/llm-integration.docblock.d.ts +7 -0
- package/dist/docs/tech/llm/llm-integration.docblock.js +358 -0
- package/dist/docs/tech/mcp-endpoints.docblock.d.ts +6 -0
- package/dist/docs/tech/mcp-endpoints.docblock.js +38 -0
- package/dist/docs/tech/presentation-runtime.docblock.d.ts +6 -0
- package/dist/docs/tech/presentation-runtime.docblock.js +17 -0
- package/dist/docs/tech/schema/README.docblock.d.ts +6 -0
- package/dist/docs/tech/schema/README.docblock.js +21 -0
- package/dist/docs/tech/studio/learning-events.docblock.d.ts +6 -0
- package/dist/docs/tech/studio/learning-events.docblock.js +49 -0
- package/dist/docs/tech/studio/learning-journeys.docblock.d.ts +6 -0
- package/dist/docs/tech/studio/learning-journeys.docblock.js +80 -0
- package/dist/docs/tech/studio/platform-admin-panel.docblock.d.ts +6 -0
- package/dist/docs/tech/studio/platform-admin-panel.docblock.js +85 -0
- package/dist/docs/tech/studio/project-access-teams.docblock.d.ts +6 -0
- package/dist/docs/tech/studio/project-access-teams.docblock.js +48 -0
- package/dist/docs/tech/studio/project-routing.docblock.d.ts +6 -0
- package/dist/docs/tech/studio/project-routing.docblock.js +68 -0
- package/dist/docs/tech/studio/sandbox-unlogged.docblock.d.ts +6 -0
- package/dist/docs/tech/studio/sandbox-unlogged.docblock.js +41 -0
- package/dist/docs/tech/studio/team-invitations.docblock.d.ts +6 -0
- package/dist/docs/tech/studio/team-invitations.docblock.js +70 -0
- package/dist/docs/tech/studio/workspace-ops.docblock.d.ts +6 -0
- package/dist/docs/tech/studio/workspace-ops.docblock.js +48 -0
- package/dist/docs/tech/studio/workspaces.docblock.d.ts +6 -0
- package/dist/docs/tech/studio/workspaces.docblock.js +63 -0
- package/dist/docs/tech/telemetry-ingest.docblock.d.ts +6 -0
- package/dist/docs/tech/telemetry-ingest.docblock.js +156 -0
- package/dist/docs/tech/vscode-extension.docblock.d.ts +6 -0
- package/dist/docs/tech/vscode-extension.docblock.js +102 -0
- package/dist/docs/tech-contracts.docs.d.ts +6 -0
- package/dist/docs/tech-contracts.docs.js +96 -0
- package/dist/docs/types.d.ts +41 -0
- package/dist/docs/types.js +0 -0
- package/dist/events.d.ts +47 -0
- package/dist/events.js +19 -0
- package/dist/examples/docs/examples.docblock.d.ts +6 -0
- package/dist/examples/docs/examples.docblock.js +165 -0
- package/dist/examples/index.d.ts +13 -0
- package/dist/examples/index.js +13 -0
- package/dist/examples/registry.d.ts +43 -0
- package/dist/examples/registry.js +88 -0
- package/dist/examples/schema.d.ts +282 -0
- package/dist/examples/schema.js +125 -0
- package/dist/examples/types.d.ts +167 -0
- package/dist/examples/types.js +43 -0
- package/dist/examples/validation.d.ts +65 -0
- package/dist/examples/validation.js +144 -0
- package/dist/experiments/docs/experiments.docblock.d.ts +6 -0
- package/dist/experiments/docs/experiments.docblock.js +21 -0
- package/dist/experiments/evaluator.d.ts +37 -0
- package/dist/experiments/evaluator.js +101 -0
- package/dist/experiments/spec-resolver.d.ts +17 -0
- package/dist/experiments/spec-resolver.js +0 -0
- package/dist/experiments/spec.d.ts +80 -0
- package/dist/experiments/spec.js +15 -0
- package/dist/features/index.d.ts +13 -0
- package/dist/features/index.js +12 -0
- package/dist/features/install.d.ts +22 -0
- package/dist/features/install.js +36 -0
- package/dist/features/registry.d.ts +26 -0
- package/dist/features/registry.js +49 -0
- package/dist/features/types.d.ts +88 -0
- package/dist/features/types.js +0 -0
- package/dist/features/validation.d.ts +8 -0
- package/dist/features/validation.js +14 -0
- package/dist/forms/docs/forms.docblock.d.ts +6 -0
- package/dist/forms/docs/forms.docblock.js +21 -0
- package/dist/forms/forms.d.ts +266 -0
- package/dist/forms/forms.js +143 -0
- package/dist/forms/index.d.ts +2 -0
- package/dist/forms/index.js +3 -0
- package/dist/index.d.ts +154 -0
- package/dist/index.js +132 -0
- package/dist/install.d.ts +77 -0
- package/dist/install.js +40 -0
- package/dist/integrations/binding.d.ts +17 -0
- package/dist/integrations/binding.js +0 -0
- package/dist/integrations/connection.d.ts +51 -0
- package/dist/integrations/connection.js +0 -0
- package/dist/integrations/docs/integrations.docblock.d.ts +6 -0
- package/dist/integrations/docs/integrations.docblock.js +94 -0
- package/dist/integrations/health.d.ts +21 -0
- package/dist/integrations/health.js +69 -0
- package/dist/integrations/index.d.ts +34 -0
- package/dist/integrations/index.js +23 -0
- package/dist/integrations/integrations.capability.d.ts +7 -0
- package/dist/integrations/integrations.capability.js +17 -0
- package/dist/integrations/integrations.feature.d.ts +11 -0
- package/dist/integrations/integrations.feature.js +67 -0
- package/dist/integrations/openbanking/contracts/accounts.d.ts +289 -0
- package/dist/integrations/openbanking/contracts/accounts.js +236 -0
- package/dist/integrations/openbanking/contracts/balances.d.ts +165 -0
- package/dist/integrations/openbanking/contracts/balances.js +166 -0
- package/dist/integrations/openbanking/contracts/index.d.ts +10 -0
- package/dist/integrations/openbanking/contracts/index.js +12 -0
- package/dist/integrations/openbanking/contracts/transactions.d.ts +213 -0
- package/dist/integrations/openbanking/contracts/transactions.js +217 -0
- package/dist/integrations/openbanking/guards.d.ts +12 -0
- package/dist/integrations/openbanking/guards.js +33 -0
- package/dist/integrations/openbanking/models.d.ts +228 -0
- package/dist/integrations/openbanking/models.js +240 -0
- package/dist/integrations/openbanking/openbanking.capability.d.ts +7 -0
- package/dist/integrations/openbanking/openbanking.capability.js +21 -0
- package/dist/integrations/openbanking/openbanking.feature.d.ts +11 -0
- package/dist/integrations/openbanking/openbanking.feature.js +76 -0
- package/dist/integrations/openbanking/telemetry.d.ts +15 -0
- package/dist/integrations/openbanking/telemetry.js +39 -0
- package/dist/integrations/operations.d.ts +437 -0
- package/dist/integrations/operations.js +392 -0
- package/dist/integrations/providers/calendar.d.ts +78 -0
- package/dist/integrations/providers/calendar.js +0 -0
- package/dist/integrations/providers/elevenlabs.d.ts +8 -0
- package/dist/integrations/providers/elevenlabs.js +56 -0
- package/dist/integrations/providers/email.d.ts +86 -0
- package/dist/integrations/providers/email.js +0 -0
- package/dist/integrations/providers/embedding.d.ts +24 -0
- package/dist/integrations/providers/embedding.js +0 -0
- package/dist/integrations/providers/gcs-storage.d.ts +8 -0
- package/dist/integrations/providers/gcs-storage.js +79 -0
- package/dist/integrations/providers/gmail.d.ts +8 -0
- package/dist/integrations/providers/gmail.js +91 -0
- package/dist/integrations/providers/google-calendar.d.ts +8 -0
- package/dist/integrations/providers/google-calendar.js +70 -0
- package/dist/integrations/providers/impls/elevenlabs-voice.d.ts +20 -0
- package/dist/integrations/providers/impls/elevenlabs-voice.js +95 -0
- package/dist/integrations/providers/impls/gcs-storage.d.ts +24 -0
- package/dist/integrations/providers/impls/gcs-storage.js +88 -0
- package/dist/integrations/providers/impls/gmail-inbound.d.ts +26 -0
- package/dist/integrations/providers/impls/gmail-inbound.js +200 -0
- package/dist/integrations/providers/impls/gmail-outbound.d.ts +18 -0
- package/dist/integrations/providers/impls/gmail-outbound.js +105 -0
- package/dist/integrations/providers/impls/google-calendar.d.ts +23 -0
- package/dist/integrations/providers/impls/google-calendar.js +154 -0
- package/dist/integrations/providers/impls/index.d.ts +15 -0
- package/dist/integrations/providers/impls/index.js +16 -0
- package/dist/integrations/providers/impls/mistral-embedding.d.ts +23 -0
- package/dist/integrations/providers/impls/mistral-embedding.js +41 -0
- package/dist/integrations/providers/impls/mistral-llm.d.ts +31 -0
- package/dist/integrations/providers/impls/mistral-llm.js +247 -0
- package/dist/integrations/providers/impls/postmark-email.d.ts +19 -0
- package/dist/integrations/providers/impls/postmark-email.js +55 -0
- package/dist/integrations/providers/impls/powens-client.d.ts +124 -0
- package/dist/integrations/providers/impls/powens-client.js +171 -0
- package/dist/integrations/providers/impls/powens-openbanking.d.ts +27 -0
- package/dist/integrations/providers/impls/powens-openbanking.js +218 -0
- package/dist/integrations/providers/impls/provider-factory.d.ts +26 -0
- package/dist/integrations/providers/impls/provider-factory.js +146 -0
- package/dist/integrations/providers/impls/qdrant-vector.d.ts +24 -0
- package/dist/integrations/providers/impls/qdrant-vector.js +69 -0
- package/dist/integrations/providers/impls/stripe-payments.d.ts +28 -0
- package/dist/integrations/providers/impls/stripe-payments.js +202 -0
- package/dist/integrations/providers/impls/twilio-sms.d.ts +20 -0
- package/dist/integrations/providers/impls/twilio-sms.js +58 -0
- package/dist/integrations/providers/index.d.ts +22 -0
- package/dist/integrations/providers/index.js +13 -0
- package/dist/integrations/providers/llm.d.ts +82 -0
- package/dist/integrations/providers/llm.js +0 -0
- package/dist/integrations/providers/mistral.d.ts +8 -0
- package/dist/integrations/providers/mistral.js +72 -0
- package/dist/integrations/providers/openbanking.d.ts +128 -0
- package/dist/integrations/providers/openbanking.js +0 -0
- package/dist/integrations/providers/payments.d.ts +109 -0
- package/dist/integrations/providers/payments.js +0 -0
- package/dist/integrations/providers/postmark.d.ts +8 -0
- package/dist/integrations/providers/postmark.js +72 -0
- package/dist/integrations/providers/powens.d.ts +8 -0
- package/dist/integrations/providers/powens.js +120 -0
- package/dist/integrations/providers/qdrant.d.ts +8 -0
- package/dist/integrations/providers/qdrant.js +77 -0
- package/dist/integrations/providers/registry.d.ts +11 -0
- package/dist/integrations/providers/registry.js +34 -0
- package/dist/integrations/providers/sms.d.ts +34 -0
- package/dist/integrations/providers/sms.js +0 -0
- package/dist/integrations/providers/storage.d.ts +60 -0
- package/dist/integrations/providers/storage.js +0 -0
- package/dist/integrations/providers/stripe.d.ts +8 -0
- package/dist/integrations/providers/stripe.js +87 -0
- package/dist/integrations/providers/twilio-sms.d.ts +8 -0
- package/dist/integrations/providers/twilio-sms.js +65 -0
- package/dist/integrations/providers/vector-store.d.ts +43 -0
- package/dist/integrations/providers/vector-store.js +0 -0
- package/dist/integrations/providers/voice.d.ts +34 -0
- package/dist/integrations/providers/voice.js +0 -0
- package/dist/integrations/runtime.d.ts +99 -0
- package/dist/integrations/runtime.js +186 -0
- package/dist/integrations/secrets/aws-secret-manager.d.ts +31 -0
- package/dist/integrations/secrets/aws-secret-manager.js +231 -0
- package/dist/integrations/secrets/env-secret-provider.d.ts +31 -0
- package/dist/integrations/secrets/env-secret-provider.js +81 -0
- package/dist/integrations/secrets/gcp-secret-manager.d.ts +32 -0
- package/dist/integrations/secrets/gcp-secret-manager.js +229 -0
- package/dist/integrations/secrets/index.d.ts +7 -0
- package/dist/integrations/secrets/index.js +8 -0
- package/dist/integrations/secrets/manager.d.ts +47 -0
- package/dist/integrations/secrets/manager.js +103 -0
- package/dist/integrations/secrets/provider.d.ts +52 -0
- package/dist/integrations/secrets/provider.js +58 -0
- package/dist/integrations/secrets/scaleway-secret-manager.d.ts +38 -0
- package/dist/integrations/secrets/scaleway-secret-manager.js +247 -0
- package/dist/integrations/secrets-types.d.ts +17 -0
- package/dist/integrations/secrets-types.js +0 -0
- package/dist/integrations/spec.d.ts +77 -0
- package/dist/integrations/spec.js +22 -0
- package/dist/jobs/define-job.d.ts +18 -0
- package/dist/jobs/define-job.js +16 -0
- package/dist/jobs/gcp-cloud-tasks.d.ts +41 -0
- package/dist/jobs/gcp-cloud-tasks.js +53 -0
- package/dist/jobs/gcp-pubsub.d.ts +25 -0
- package/dist/jobs/gcp-pubsub.js +39 -0
- package/dist/jobs/handlers/gmail-sync-handler.d.ts +9 -0
- package/dist/jobs/handlers/gmail-sync-handler.js +9 -0
- package/dist/jobs/handlers/index.d.ts +9 -0
- package/dist/jobs/handlers/index.js +12 -0
- package/dist/jobs/handlers/ping-handler.d.ts +10 -0
- package/dist/jobs/handlers/ping-handler.js +15 -0
- package/dist/jobs/handlers/storage-document-handler.d.ts +12 -0
- package/dist/jobs/handlers/storage-document-handler.js +14 -0
- package/dist/jobs/index.d.ts +3 -0
- package/dist/jobs/index.js +4 -0
- package/dist/jobs/memory-queue.d.ts +18 -0
- package/dist/jobs/memory-queue.js +71 -0
- package/dist/jobs/queue.d.ts +131 -0
- package/dist/jobs/queue.js +33 -0
- package/dist/jobs/scaleway-sqs-queue.d.ts +30 -0
- package/dist/jobs/scaleway-sqs-queue.js +153 -0
- package/dist/jsonschema.d.ts +42 -0
- package/dist/jsonschema.js +51 -0
- package/dist/knowledge/binding.d.ts +25 -0
- package/dist/knowledge/binding.js +0 -0
- package/dist/knowledge/docs/knowledge.docblock.d.ts +6 -0
- package/dist/knowledge/docs/knowledge.docblock.js +21 -0
- package/dist/knowledge/index.d.ts +11 -0
- package/dist/knowledge/index.js +10 -0
- package/dist/knowledge/ingestion/document-processor.d.ts +24 -0
- package/dist/knowledge/ingestion/document-processor.js +54 -0
- package/dist/knowledge/ingestion/embedding-service.d.ts +12 -0
- package/dist/knowledge/ingestion/embedding-service.js +25 -0
- package/dist/knowledge/ingestion/gmail-adapter.d.ts +18 -0
- package/dist/knowledge/ingestion/gmail-adapter.js +51 -0
- package/dist/knowledge/ingestion/index.d.ts +6 -0
- package/dist/knowledge/ingestion/index.js +7 -0
- package/dist/knowledge/ingestion/storage-adapter.d.ts +15 -0
- package/dist/knowledge/ingestion/storage-adapter.js +26 -0
- package/dist/knowledge/ingestion/vector-indexer.d.ts +18 -0
- package/dist/knowledge/ingestion/vector-indexer.js +32 -0
- package/dist/knowledge/knowledge.capability.d.ts +7 -0
- package/dist/knowledge/knowledge.capability.js +21 -0
- package/dist/knowledge/knowledge.feature.d.ts +11 -0
- package/dist/knowledge/knowledge.feature.js +68 -0
- package/dist/knowledge/operations.d.ts +318 -0
- package/dist/knowledge/operations.js +321 -0
- package/dist/knowledge/query/index.d.ts +2 -0
- package/dist/knowledge/query/index.js +3 -0
- package/dist/knowledge/query/service.d.ts +29 -0
- package/dist/knowledge/query/service.js +65 -0
- package/dist/knowledge/runtime.d.ts +32 -0
- package/dist/knowledge/runtime.js +49 -0
- package/dist/knowledge/source.d.ts +32 -0
- package/dist/knowledge/source.js +0 -0
- package/dist/knowledge/spaces/email-threads.d.ts +7 -0
- package/dist/knowledge/spaces/email-threads.js +37 -0
- package/dist/knowledge/spaces/financial-docs.d.ts +7 -0
- package/dist/knowledge/spaces/financial-docs.js +37 -0
- package/dist/knowledge/spaces/financial-overview.d.ts +7 -0
- package/dist/knowledge/spaces/financial-overview.js +41 -0
- package/dist/knowledge/spaces/index.d.ts +7 -0
- package/dist/knowledge/spaces/index.js +8 -0
- package/dist/knowledge/spaces/product-canon.d.ts +7 -0
- package/dist/knowledge/spaces/product-canon.js +37 -0
- package/dist/knowledge/spaces/support-faq.d.ts +7 -0
- package/dist/knowledge/spaces/support-faq.js +40 -0
- package/dist/knowledge/spaces/uploaded-docs.d.ts +7 -0
- package/dist/knowledge/spaces/uploaded-docs.js +37 -0
- package/dist/knowledge/spec.d.ts +46 -0
- package/dist/knowledge/spec.js +17 -0
- package/dist/llm/exporters.d.ts +70 -0
- package/dist/llm/exporters.js +542 -0
- package/dist/llm/index.d.ts +4 -0
- package/dist/llm/index.js +4 -0
- package/dist/llm/prompts.d.ts +52 -0
- package/dist/llm/prompts.js +410 -0
- package/dist/llm/types.d.ts +215 -0
- package/dist/llm/types.js +0 -0
- package/dist/markdown.d.ts +22 -0
- package/dist/markdown.js +119 -0
- package/dist/migrations.d.ts +52 -0
- package/dist/migrations.js +31 -0
- package/dist/model-registry.d.ts +13 -0
- package/dist/model-registry.js +33 -0
- package/dist/onboarding-base.d.ts +138 -0
- package/dist/onboarding-base.js +195 -0
- package/dist/openapi.d.ts +31 -0
- package/dist/openapi.js +82 -0
- package/dist/operations/index.d.ts +3 -0
- package/dist/operations/index.js +4 -0
- package/dist/operations/operation.d.ts +186 -0
- package/dist/operations/operation.js +35 -0
- package/dist/operations/registry.d.ts +54 -0
- package/dist/operations/registry.js +176 -0
- package/dist/ownership.d.ts +84 -0
- package/dist/ownership.js +38 -0
- package/dist/policy/docs/policy.docblock.d.ts +6 -0
- package/dist/policy/docs/policy.docblock.js +21 -0
- package/dist/policy/engine.d.ts +40 -0
- package/dist/policy/engine.js +225 -0
- package/dist/policy/index.d.ts +5 -0
- package/dist/policy/index.js +5 -0
- package/dist/policy/opa-adapter.d.ts +45 -0
- package/dist/policy/opa-adapter.js +71 -0
- package/dist/policy/registry.d.ts +9 -0
- package/dist/policy/registry.js +11 -0
- package/dist/policy/spec.d.ts +103 -0
- package/dist/policy/spec.js +0 -0
- package/dist/presentations/docs/presentations-conventions.docblock.d.ts +6 -0
- package/dist/presentations/docs/presentations-conventions.docblock.js +21 -0
- package/dist/presentations/index.d.ts +4 -0
- package/dist/presentations/index.js +5 -0
- package/dist/presentations/presentations.d.ts +50 -0
- package/dist/presentations/presentations.js +7 -0
- package/dist/presentations/registry.d.ts +10 -0
- package/dist/presentations/registry.js +12 -0
- package/dist/presentations/transform-engine.d.ts +66 -0
- package/dist/presentations/transform-engine.js +282 -0
- package/dist/prompt.d.ts +53 -0
- package/dist/prompt.js +10 -0
- package/dist/promptRegistry.d.ts +15 -0
- package/dist/promptRegistry.js +31 -0
- package/dist/regenerator/adapters.d.ts +19 -0
- package/dist/regenerator/adapters.js +0 -0
- package/dist/regenerator/docs/regenerator.docblock.d.ts +6 -0
- package/dist/regenerator/docs/regenerator.docblock.js +21 -0
- package/dist/regenerator/executor.d.ts +70 -0
- package/dist/regenerator/executor.js +86 -0
- package/dist/regenerator/index.d.ts +7 -0
- package/dist/regenerator/index.js +6 -0
- package/dist/regenerator/service.d.ts +33 -0
- package/dist/regenerator/service.js +93 -0
- package/dist/regenerator/sinks.d.ts +26 -0
- package/dist/regenerator/sinks.js +32 -0
- package/dist/regenerator/types.d.ts +107 -0
- package/dist/regenerator/types.js +0 -0
- package/dist/regenerator/utils.d.ts +9 -0
- package/dist/regenerator/utils.js +51 -0
- package/dist/registry-utils.d.ts +106 -0
- package/dist/registry-utils.js +122 -0
- package/dist/registry.d.ts +32 -0
- package/dist/registry.js +61 -0
- package/dist/resources.d.ts +64 -0
- package/dist/resources.js +50 -0
- package/dist/schema-to-markdown.d.ts +54 -0
- package/dist/schema-to-markdown.js +217 -0
- package/dist/server/contracts-adapter-hydration.d.ts +15 -0
- package/dist/server/contracts-adapter-hydration.js +41 -0
- package/dist/server/contracts-adapter-input.d.ts +9 -0
- package/dist/server/contracts-adapter-input.js +83 -0
- package/dist/server/graphql-pothos.d.ts +31 -0
- package/dist/server/graphql-pothos.js +134 -0
- package/dist/server/index.d.ts +9 -0
- package/dist/server/index.js +10 -0
- package/dist/server/mcp/createMcpServer.d.ts +15 -0
- package/dist/server/mcp/createMcpServer.js +27 -0
- package/dist/server/mcp/mcpTypes.d.ts +27 -0
- package/dist/server/mcp/mcpTypes.js +0 -0
- package/dist/server/mcp/registerPresentations.d.ts +7 -0
- package/dist/server/mcp/registerPresentations.js +54 -0
- package/dist/server/mcp/registerPrompts.d.ts +8 -0
- package/dist/server/mcp/registerPrompts.js +41 -0
- package/dist/server/mcp/registerResources.d.ts +8 -0
- package/dist/server/mcp/registerResources.js +35 -0
- package/dist/server/mcp/registerTools.d.ts +8 -0
- package/dist/server/mcp/registerTools.js +22 -0
- package/dist/server/provider-mcp.d.ts +2 -0
- package/dist/server/provider-mcp.js +3 -0
- package/dist/server/rest-elysia.d.ts +40 -0
- package/dist/server/rest-elysia.js +20 -0
- package/dist/server/rest-express.d.ts +16 -0
- package/dist/server/rest-express.js +36 -0
- package/dist/server/rest-generic.d.ts +32 -0
- package/dist/server/rest-generic.js +124 -0
- package/dist/server/rest-next-app.d.ts +35 -0
- package/dist/server/rest-next-app.js +38 -0
- package/dist/server/rest-next-mcp.d.ts +11 -0
- package/dist/server/rest-next-mcp.js +45 -0
- package/dist/server/rest-next-pages.d.ts +9 -0
- package/dist/server/rest-next-pages.js +22 -0
- package/dist/telemetry/anomaly.d.ts +27 -0
- package/dist/telemetry/anomaly.js +48 -0
- package/dist/telemetry/docs/telemetry.docblock.d.ts +6 -0
- package/dist/telemetry/docs/telemetry.docblock.js +21 -0
- package/dist/telemetry/index.d.ts +4 -0
- package/dist/telemetry/index.js +5 -0
- package/dist/telemetry/spec.d.ts +91 -0
- package/dist/telemetry/spec.js +42 -0
- package/dist/telemetry/tracker.d.ts +51 -0
- package/dist/telemetry/tracker.js +76 -0
- package/dist/tests/index.d.ts +3 -0
- package/dist/tests/index.js +4 -0
- package/dist/tests/runner.d.ts +43 -0
- package/dist/tests/runner.js +150 -0
- package/dist/tests/spec.d.ts +82 -0
- package/dist/tests/spec.js +34 -0
- package/dist/themes.d.ts +51 -0
- package/dist/themes.js +17 -0
- package/dist/translations/catalog.d.ts +28 -0
- package/dist/translations/catalog.js +0 -0
- package/dist/translations/tenant.d.ts +15 -0
- package/dist/translations/tenant.js +0 -0
- package/dist/types.d.ts +92 -0
- package/dist/types.js +0 -0
- package/dist/versioning/index.d.ts +3 -0
- package/dist/versioning/index.js +4 -0
- package/dist/versioning/types.d.ts +127 -0
- package/dist/versioning/types.js +24 -0
- package/dist/versioning/utils.d.ts +95 -0
- package/dist/versioning/utils.js +180 -0
- package/dist/workflow/adapters/db-adapter.d.ts +46 -0
- package/dist/workflow/adapters/db-adapter.js +83 -0
- package/dist/workflow/adapters/file-adapter.d.ts +14 -0
- package/dist/workflow/adapters/file-adapter.js +11 -0
- package/dist/workflow/adapters/index.d.ts +4 -0
- package/dist/workflow/adapters/index.js +5 -0
- package/dist/workflow/adapters/memory-store.d.ts +18 -0
- package/dist/workflow/adapters/memory-store.js +58 -0
- package/dist/workflow/expression.d.ts +9 -0
- package/dist/workflow/expression.js +99 -0
- package/dist/workflow/index.d.ts +17 -0
- package/dist/workflow/index.js +16 -0
- package/dist/workflow/overview.docblock.d.ts +6 -0
- package/dist/workflow/overview.docblock.js +21 -0
- package/dist/workflow/runner.d.ts +77 -0
- package/dist/workflow/runner.js +337 -0
- package/dist/workflow/sla-monitor.d.ts +20 -0
- package/dist/workflow/sla-monitor.js +47 -0
- package/dist/workflow/spec.d.ts +93 -0
- package/dist/workflow/spec.js +11 -0
- package/dist/workflow/state.d.ts +35 -0
- package/dist/workflow/state.js +0 -0
- package/dist/workflow/validation.d.ts +29 -0
- package/dist/workflow/validation.js +176 -0
- package/dist/workspace-config/contractsrc-schema.d.ts +1162 -0
- package/dist/workspace-config/contractsrc-schema.js +421 -0
- package/dist/workspace-config/index.d.ts +2 -0
- package/dist/workspace-config/index.js +3 -0
- package/dist/workspace-config/workspace-config.docblock.d.ts +6 -0
- package/dist/workspace-config/workspace-config.docblock.js +45 -0
- package/package.json +618 -0
|
@@ -0,0 +1,3 @@
|
|
|
1
|
+
import { AnyOperationSpec, EmitDecl, EmitDeclInline, EmitDeclRef, ImplementationRef, ImplementationType, OpKind, OperationSpec, OperationSpecMeta, TelemetryTrigger, defineCommand, defineQuery, isEmitDeclRef } from "./operation.js";
|
|
2
|
+
import { OperationKey, OperationSpecRegistry, opKey } from "./registry.js";
|
|
3
|
+
export { AnyOperationSpec, EmitDecl, EmitDeclInline, EmitDeclRef, ImplementationRef, ImplementationType, OpKind, OperationKey, OperationSpec, OperationSpecMeta, OperationSpecRegistry, TelemetryTrigger, defineCommand, defineQuery, isEmitDeclRef, opKey };
|
|
@@ -0,0 +1,186 @@
|
|
|
1
|
+
import { OwnerShipMeta } from "../ownership.js";
|
|
2
|
+
import { PolicyRef } from "../policy/spec.js";
|
|
3
|
+
import { ResourceRefDescriptor } from "../resources.js";
|
|
4
|
+
import { TestSpecRef } from "../tests/spec.js";
|
|
5
|
+
import { EventSpec } from "../events.js";
|
|
6
|
+
import { AnySchemaModel } from "@contractspec/lib.schema";
|
|
7
|
+
|
|
8
|
+
//#region src/operations/operation.d.ts
|
|
9
|
+
|
|
10
|
+
/**
|
|
11
|
+
* Distinguishes between state-changing operations (command) and read-only operations (query).
|
|
12
|
+
*/
|
|
13
|
+
type OpKind = 'command' | 'query';
|
|
14
|
+
/**
|
|
15
|
+
* Type of implementation artifact.
|
|
16
|
+
*/
|
|
17
|
+
type ImplementationType = 'handler' | 'component' | 'form' | 'test' | 'service' | 'hook' | 'other';
|
|
18
|
+
/**
|
|
19
|
+
* Reference to an implementation file for a spec.
|
|
20
|
+
* Used for explicit implementation mapping.
|
|
21
|
+
*/
|
|
22
|
+
interface ImplementationRef {
|
|
23
|
+
/** Path to implementation file (relative to workspace root) */
|
|
24
|
+
path: string;
|
|
25
|
+
/** Type of implementation artifact */
|
|
26
|
+
type: ImplementationType;
|
|
27
|
+
/** Optional human-readable description */
|
|
28
|
+
description?: string;
|
|
29
|
+
}
|
|
30
|
+
interface EmitDeclRef {
|
|
31
|
+
ref: EventSpec<AnySchemaModel>['meta'];
|
|
32
|
+
when: string;
|
|
33
|
+
}
|
|
34
|
+
interface EmitDeclInline {
|
|
35
|
+
key: string;
|
|
36
|
+
version: string;
|
|
37
|
+
when: string;
|
|
38
|
+
payload: AnySchemaModel;
|
|
39
|
+
}
|
|
40
|
+
/**
|
|
41
|
+
* Declaration of an event that an operation may emit.
|
|
42
|
+
* Can be a reference to an `EventSpec` or an inline definition.
|
|
43
|
+
*/
|
|
44
|
+
type EmitDecl = EmitDeclRef | EmitDeclInline;
|
|
45
|
+
declare const isEmitDeclRef: (e: EmitDecl) => e is EmitDeclRef;
|
|
46
|
+
interface TelemetryTrigger {
|
|
47
|
+
event: {
|
|
48
|
+
key: string;
|
|
49
|
+
version?: string;
|
|
50
|
+
};
|
|
51
|
+
properties?: (args: {
|
|
52
|
+
input: unknown;
|
|
53
|
+
output?: unknown;
|
|
54
|
+
error?: unknown;
|
|
55
|
+
}) => Record<string, unknown>;
|
|
56
|
+
}
|
|
57
|
+
interface OperationSpecMeta extends OwnerShipMeta {
|
|
58
|
+
kind: OpKind;
|
|
59
|
+
/** Business goal: why this exists */
|
|
60
|
+
goal: string;
|
|
61
|
+
/** Background, constraints, scope edges (feeds docs & LLM context) */
|
|
62
|
+
context: string;
|
|
63
|
+
}
|
|
64
|
+
/**
|
|
65
|
+
* The core specification interface for any operation (Command or Query).
|
|
66
|
+
*
|
|
67
|
+
* @template Input - The Zod-backed schema model for the input payload.
|
|
68
|
+
* @template Output - The Zod-backed schema model for the output payload, or a resource reference.
|
|
69
|
+
* @template Events - Tuple of events that this operation may emit.
|
|
70
|
+
*/
|
|
71
|
+
interface OperationSpec<Input extends AnySchemaModel, Output extends AnySchemaModel | ResourceRefDescriptor<boolean>, Events extends readonly EmitDecl[] | undefined = readonly EmitDecl[] | undefined> {
|
|
72
|
+
meta: OperationSpecMeta;
|
|
73
|
+
io: {
|
|
74
|
+
/** Zod schema for input body payload */
|
|
75
|
+
input: Input | null;
|
|
76
|
+
/** Zod schema for URL path parameters */
|
|
77
|
+
params?: AnySchemaModel;
|
|
78
|
+
/** Zod schema for query string parameters */
|
|
79
|
+
query?: AnySchemaModel;
|
|
80
|
+
/** Zod schema for HTTP headers */
|
|
81
|
+
headers?: AnySchemaModel;
|
|
82
|
+
/** Zod schema for output payload */
|
|
83
|
+
output: Output;
|
|
84
|
+
/** Named, typed errors this op may throw (optional) */
|
|
85
|
+
errors?: Record<string, {
|
|
86
|
+
description: string;
|
|
87
|
+
http?: number;
|
|
88
|
+
gqlCode?: string;
|
|
89
|
+
when: string;
|
|
90
|
+
}>;
|
|
91
|
+
};
|
|
92
|
+
policy: {
|
|
93
|
+
/** Minimal auth category allowed to call this op */
|
|
94
|
+
auth: 'anonymous' | 'user' | 'admin';
|
|
95
|
+
/** Idempotency hint. Queries default true; commands default false. */
|
|
96
|
+
idempotent?: boolean;
|
|
97
|
+
/** Soft rate limit suggestion; adapter enforces via limiter */
|
|
98
|
+
rateLimit?: {
|
|
99
|
+
rpm: number;
|
|
100
|
+
key: 'user' | 'org' | 'global';
|
|
101
|
+
};
|
|
102
|
+
/** Feature flags that must be ON for this op to run */
|
|
103
|
+
flags?: string[];
|
|
104
|
+
/** Whether a human must approve before action (e.g., risky commands) */
|
|
105
|
+
escalate?: 'human_review' | null;
|
|
106
|
+
/** JSONPath-like pointers to redact from logs/prompts */
|
|
107
|
+
pii?: string[];
|
|
108
|
+
/** Referenced policy specs governing access */
|
|
109
|
+
policies?: PolicyRef[];
|
|
110
|
+
/** Field-level overrides referencing policy specs */
|
|
111
|
+
fieldPolicies?: {
|
|
112
|
+
field: string;
|
|
113
|
+
actions: ('read' | 'write')[];
|
|
114
|
+
policy?: PolicyRef;
|
|
115
|
+
}[];
|
|
116
|
+
};
|
|
117
|
+
sideEffects?: {
|
|
118
|
+
/** Declared events this op may emit; runtime will guard against others */
|
|
119
|
+
emits?: Events;
|
|
120
|
+
/** Analytics intents (names); the service decides the sink */
|
|
121
|
+
analytics?: string[];
|
|
122
|
+
/** Audit intents (labels); the service decides storage */
|
|
123
|
+
audit?: string[];
|
|
124
|
+
};
|
|
125
|
+
telemetry?: {
|
|
126
|
+
success?: TelemetryTrigger;
|
|
127
|
+
failure?: TelemetryTrigger;
|
|
128
|
+
};
|
|
129
|
+
tests?: TestSpecRef[];
|
|
130
|
+
transport?: {
|
|
131
|
+
rest?: {
|
|
132
|
+
/** Override HTTP method (default: POST for commands, GET for queries) */
|
|
133
|
+
method?: 'GET' | 'POST';
|
|
134
|
+
/** Override path (default derived from meta.name/version) */
|
|
135
|
+
path?: string;
|
|
136
|
+
};
|
|
137
|
+
gql?: {
|
|
138
|
+
/** Override field name (default: dots→underscores + _vN) */
|
|
139
|
+
field?: string;
|
|
140
|
+
returns?: string;
|
|
141
|
+
};
|
|
142
|
+
mcp?: {
|
|
143
|
+
/** Override tool identifier (default: "<name>.v<version>") */
|
|
144
|
+
toolName?: string;
|
|
145
|
+
};
|
|
146
|
+
};
|
|
147
|
+
acceptance?: {
|
|
148
|
+
/** Gherkin-lite scenarios for docs & auto tests */
|
|
149
|
+
scenarios?: {
|
|
150
|
+
key: string;
|
|
151
|
+
given: string[];
|
|
152
|
+
when: string[];
|
|
153
|
+
then: string[];
|
|
154
|
+
}[];
|
|
155
|
+
/** Request/response examples (used for docs & snapshot tests) */
|
|
156
|
+
examples?: {
|
|
157
|
+
key: string;
|
|
158
|
+
input: unknown;
|
|
159
|
+
output: unknown;
|
|
160
|
+
}[];
|
|
161
|
+
};
|
|
162
|
+
/**
|
|
163
|
+
* Explicit implementation file mappings.
|
|
164
|
+
* Used for tracking and verifying that this spec is correctly implemented.
|
|
165
|
+
*/
|
|
166
|
+
implementations?: ImplementationRef[];
|
|
167
|
+
}
|
|
168
|
+
type AnyOperationSpec = OperationSpec<AnySchemaModel, AnySchemaModel | ResourceRefDescriptor<boolean>>;
|
|
169
|
+
/**
|
|
170
|
+
* Helper to define a Command (write operation).
|
|
171
|
+
* Sets `kind: 'command'` and defaults `idempotent: false`.
|
|
172
|
+
*/
|
|
173
|
+
declare const defineCommand: <I extends AnySchemaModel, O extends AnySchemaModel | ResourceRefDescriptor<boolean>, E extends readonly EmitDecl[] | undefined = undefined>(spec: Omit<OperationSpec<I, O, E>, "meta" | "policy"> & {
|
|
174
|
+
meta: Omit<OperationSpec<I, O, E>["meta"], "kind">;
|
|
175
|
+
policy: Omit<OperationSpec<I, O, E>["policy"], "idempotent">;
|
|
176
|
+
}) => OperationSpec<I, O, E>;
|
|
177
|
+
/**
|
|
178
|
+
* Helper to define a Query (read-only operation).
|
|
179
|
+
* Sets `kind: 'query'` and forces `idempotent: true`.
|
|
180
|
+
*/
|
|
181
|
+
declare const defineQuery: <I extends AnySchemaModel, O extends AnySchemaModel | ResourceRefDescriptor<boolean>, E extends readonly EmitDecl[] | undefined = undefined>(spec: Omit<OperationSpec<I, O, E>, "meta" | "policy"> & {
|
|
182
|
+
meta: Omit<OperationSpec<I, O, E>["meta"], "kind">;
|
|
183
|
+
policy: Omit<OperationSpec<I, O, E>["policy"], "idempotent">;
|
|
184
|
+
}) => OperationSpec<I, O, E>;
|
|
185
|
+
//#endregion
|
|
186
|
+
export { AnyOperationSpec, EmitDecl, EmitDeclInline, EmitDeclRef, ImplementationRef, ImplementationType, OpKind, OperationSpec, OperationSpecMeta, TelemetryTrigger, defineCommand, defineQuery, isEmitDeclRef };
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
//#region src/operations/operation.ts
|
|
2
|
+
const isEmitDeclRef = (e) => "ref" in e;
|
|
3
|
+
/**
|
|
4
|
+
* Helper to define a Command (write operation).
|
|
5
|
+
* Sets `kind: 'command'` and defaults `idempotent: false`.
|
|
6
|
+
*/
|
|
7
|
+
const defineCommand = (spec) => ({
|
|
8
|
+
...spec,
|
|
9
|
+
meta: {
|
|
10
|
+
...spec.meta,
|
|
11
|
+
kind: "command"
|
|
12
|
+
},
|
|
13
|
+
policy: {
|
|
14
|
+
...spec.policy,
|
|
15
|
+
idempotent: spec.policy?.["policy"]?.idempotent ?? false
|
|
16
|
+
}
|
|
17
|
+
});
|
|
18
|
+
/**
|
|
19
|
+
* Helper to define a Query (read-only operation).
|
|
20
|
+
* Sets `kind: 'query'` and forces `idempotent: true`.
|
|
21
|
+
*/
|
|
22
|
+
const defineQuery = (spec) => ({
|
|
23
|
+
...spec,
|
|
24
|
+
meta: {
|
|
25
|
+
...spec.meta,
|
|
26
|
+
kind: "query"
|
|
27
|
+
},
|
|
28
|
+
policy: {
|
|
29
|
+
...spec.policy,
|
|
30
|
+
idempotent: true
|
|
31
|
+
}
|
|
32
|
+
});
|
|
33
|
+
|
|
34
|
+
//#endregion
|
|
35
|
+
export { defineCommand, defineQuery, isEmitDeclRef };
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
import { ResourceRefDescriptor } from "../resources.js";
|
|
2
|
+
import { AnyOperationSpec, OperationSpec } from "./operation.js";
|
|
3
|
+
import { HandlerForOperationSpec } from "../install.js";
|
|
4
|
+
import { HandlerCtx } from "../types.js";
|
|
5
|
+
import { SpecContractRegistry } from "../registry.js";
|
|
6
|
+
import { AnySchemaModel } from "@contractspec/lib.schema";
|
|
7
|
+
|
|
8
|
+
//#region src/operations/registry.d.ts
|
|
9
|
+
|
|
10
|
+
type OperationKey = `${string}.v${string}`;
|
|
11
|
+
declare function opKey(key: string, version: string): OperationKey;
|
|
12
|
+
type AnyOperationHandler = (args: unknown, ctx: HandlerCtx) => Promise<unknown>;
|
|
13
|
+
/**
|
|
14
|
+
* In-memory registry for ContractSpecs and their bound handlers.
|
|
15
|
+
* Provides validation, policy enforcement, and guarded event emission at execute time.
|
|
16
|
+
*/
|
|
17
|
+
declare class OperationSpecRegistry extends SpecContractRegistry<'operation', AnyOperationSpec> {
|
|
18
|
+
private handlers;
|
|
19
|
+
constructor(items?: AnyOperationSpec[]);
|
|
20
|
+
/**
|
|
21
|
+
* Binds a runtime handler implementation to a previously registered spec.
|
|
22
|
+
*
|
|
23
|
+
* @param spec - The spec to bind to.
|
|
24
|
+
* @param handler - The async function implementing the business logic.
|
|
25
|
+
* @returns The registry instance for chaining.
|
|
26
|
+
* @throws If the spec is not found or a handler is already bound.
|
|
27
|
+
*/
|
|
28
|
+
bind<I extends AnySchemaModel, O extends AnySchemaModel | ResourceRefDescriptor<boolean>>(spec: OperationSpec<I, O>, handler: HandlerForOperationSpec<OperationSpec<I, O>>): this;
|
|
29
|
+
/**
|
|
30
|
+
* Retrieves the bound handler for a spec.
|
|
31
|
+
*/
|
|
32
|
+
getHandler(key: string, version?: string): AnyOperationHandler | undefined;
|
|
33
|
+
/** Iterate all bound operations (spec+handler). */
|
|
34
|
+
listBound(): {
|
|
35
|
+
spec: AnyOperationSpec;
|
|
36
|
+
handler: AnyOperationHandler;
|
|
37
|
+
}[];
|
|
38
|
+
/**
|
|
39
|
+
* Execute an operation by name/version with full runtime protections:
|
|
40
|
+
* 1. Validates input against Zod schema.
|
|
41
|
+
* 2. Enforces policy (Auth, RBAC, Rate Limits) via PDP.
|
|
42
|
+
* 3. Guards event emission to ensure only declared events are sent.
|
|
43
|
+
* 4. Validates output against Zod schema (if applicable).
|
|
44
|
+
* 5. Tracks telemetry (success/failure).
|
|
45
|
+
*
|
|
46
|
+
* @param key - Operation key.
|
|
47
|
+
* @param version - Operation version (optional, defaults to latest).
|
|
48
|
+
* @param rawInput - The raw input payload (e.g. from JSON body).
|
|
49
|
+
* @param ctx - The runtime context (actor, tenant, etc.).
|
|
50
|
+
*/
|
|
51
|
+
execute(key: string, version: string | undefined, rawInput: unknown, ctx: HandlerCtx): Promise<unknown>;
|
|
52
|
+
}
|
|
53
|
+
//#endregion
|
|
54
|
+
export { OperationKey, OperationSpecRegistry, opKey };
|
|
@@ -0,0 +1,176 @@
|
|
|
1
|
+
import { SpecContractRegistry } from "../registry.js";
|
|
2
|
+
import { eventKey } from "../events.js";
|
|
3
|
+
import { isEmitDeclRef } from "./operation.js";
|
|
4
|
+
|
|
5
|
+
//#region src/operations/registry.ts
|
|
6
|
+
/**
|
|
7
|
+
* OperationSpecRegistry:
|
|
8
|
+
* - Registers ContractSpecs (unique by name+version)
|
|
9
|
+
* - Binds runtime handlers to specs
|
|
10
|
+
* - Provides lookup, iteration, and a safe execute() with validation/policy/enforcement
|
|
11
|
+
*
|
|
12
|
+
* Includes a minimal OpRegistry shim for backward-compat (deprecated).
|
|
13
|
+
*/
|
|
14
|
+
function opKey(key, version) {
|
|
15
|
+
return `${key}.v${version}`;
|
|
16
|
+
}
|
|
17
|
+
/**
|
|
18
|
+
* In-memory registry for ContractSpecs and their bound handlers.
|
|
19
|
+
* Provides validation, policy enforcement, and guarded event emission at execute time.
|
|
20
|
+
*/
|
|
21
|
+
var OperationSpecRegistry = class extends SpecContractRegistry {
|
|
22
|
+
handlers = /* @__PURE__ */ new Map();
|
|
23
|
+
constructor(items) {
|
|
24
|
+
super("operation", items);
|
|
25
|
+
}
|
|
26
|
+
/**
|
|
27
|
+
* Binds a runtime handler implementation to a previously registered spec.
|
|
28
|
+
*
|
|
29
|
+
* @param spec - The spec to bind to.
|
|
30
|
+
* @param handler - The async function implementing the business logic.
|
|
31
|
+
* @returns The registry instance for chaining.
|
|
32
|
+
* @throws If the spec is not found or a handler is already bound.
|
|
33
|
+
*/
|
|
34
|
+
bind(spec, handler) {
|
|
35
|
+
const key = opKey(spec.meta.key, spec.meta.version);
|
|
36
|
+
if (!this.items.has(key)) throw new Error(`Cannot bind; spec not found: ${key}`);
|
|
37
|
+
if (this.handlers.has(key)) throw new Error(`Handler already bound for ${key}`);
|
|
38
|
+
this.handlers.set(key, handler);
|
|
39
|
+
return this;
|
|
40
|
+
}
|
|
41
|
+
/**
|
|
42
|
+
* Retrieves the bound handler for a spec.
|
|
43
|
+
*/
|
|
44
|
+
getHandler(key, version) {
|
|
45
|
+
const spec = this.get(key, version);
|
|
46
|
+
if (!spec) return void 0;
|
|
47
|
+
return this.handlers.get(opKey(spec.meta.key, spec.meta.version));
|
|
48
|
+
}
|
|
49
|
+
/** Iterate all bound operations (spec+handler). */
|
|
50
|
+
listBound() {
|
|
51
|
+
const out = [];
|
|
52
|
+
for (const [k, spec] of this.items.entries()) {
|
|
53
|
+
const h = this.handlers.get(k);
|
|
54
|
+
if (h) out.push({
|
|
55
|
+
spec,
|
|
56
|
+
handler: h
|
|
57
|
+
});
|
|
58
|
+
}
|
|
59
|
+
return out;
|
|
60
|
+
}
|
|
61
|
+
/**
|
|
62
|
+
* Execute an operation by name/version with full runtime protections:
|
|
63
|
+
* 1. Validates input against Zod schema.
|
|
64
|
+
* 2. Enforces policy (Auth, RBAC, Rate Limits) via PDP.
|
|
65
|
+
* 3. Guards event emission to ensure only declared events are sent.
|
|
66
|
+
* 4. Validates output against Zod schema (if applicable).
|
|
67
|
+
* 5. Tracks telemetry (success/failure).
|
|
68
|
+
*
|
|
69
|
+
* @param key - Operation key.
|
|
70
|
+
* @param version - Operation version (optional, defaults to latest).
|
|
71
|
+
* @param rawInput - The raw input payload (e.g. from JSON body).
|
|
72
|
+
* @param ctx - The runtime context (actor, tenant, etc.).
|
|
73
|
+
*/
|
|
74
|
+
async execute(key, version, rawInput, ctx) {
|
|
75
|
+
const baseSpec = this.get(key, version);
|
|
76
|
+
if (!baseSpec) throw new Error(`Spec not found for ${key}${version ? `.v${version}` : ""}`);
|
|
77
|
+
const spec = await ctx.specVariantResolver?.resolve({
|
|
78
|
+
name: baseSpec.meta.key,
|
|
79
|
+
version: baseSpec.meta.version,
|
|
80
|
+
kind: baseSpec.meta.kind
|
|
81
|
+
}, ctx) ?? baseSpec;
|
|
82
|
+
let handlerKey = opKey(spec.meta.key, spec.meta.version);
|
|
83
|
+
let handler = this.handlers.get(handlerKey);
|
|
84
|
+
if (!handler) {
|
|
85
|
+
const fallbackKey = opKey(baseSpec.meta.key, baseSpec.meta.version);
|
|
86
|
+
handler = this.handlers.get(fallbackKey);
|
|
87
|
+
handlerKey = fallbackKey;
|
|
88
|
+
}
|
|
89
|
+
if (!handler) throw new Error(`No handler bound for ${handlerKey}`);
|
|
90
|
+
const parsedInput = spec.io.input?.getZod().parse(rawInput);
|
|
91
|
+
if (ctx.decide) {
|
|
92
|
+
const [service, command] = spec.meta.key.split(".");
|
|
93
|
+
if (!service || !command) throw new Error(`Invalid spec name: ${spec.meta.key}`);
|
|
94
|
+
const decision = await ctx.decide({
|
|
95
|
+
service,
|
|
96
|
+
command,
|
|
97
|
+
version: spec.meta.version,
|
|
98
|
+
actor: ctx.actor ?? "anonymous",
|
|
99
|
+
channel: ctx.channel,
|
|
100
|
+
roles: ctx.roles,
|
|
101
|
+
organizationId: ctx.organizationId,
|
|
102
|
+
userId: ctx.userId,
|
|
103
|
+
flags: []
|
|
104
|
+
});
|
|
105
|
+
if (decision.effect === "deny") throw new Error(`PolicyDenied: ${spec.meta.key}.v${spec.meta.version}`);
|
|
106
|
+
if (decision.rateLimit && ctx.rateLimit) {
|
|
107
|
+
const key$1 = decision.rateLimit.key ?? "default";
|
|
108
|
+
const rpm = decision.rateLimit.rpm ?? 60;
|
|
109
|
+
await ctx.rateLimit(key$1, 1, rpm);
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
const allowedEvents = /* @__PURE__ */ new Map();
|
|
113
|
+
if (spec.sideEffects?.emits) for (const e of spec.sideEffects.emits) if (isEmitDeclRef(e)) {
|
|
114
|
+
const eventSpec = ctx.eventSpecResolver?.get(e.ref.key, e.ref.version);
|
|
115
|
+
if (eventSpec) allowedEvents.set(`${e.ref.key}.v${e.ref.version}`, eventSpec.payload);
|
|
116
|
+
} else allowedEvents.set(`${e.key}.v${e.version}`, e.payload);
|
|
117
|
+
const emitGuard = async (eventName, eventVersion, payload) => {
|
|
118
|
+
const key2 = eventKey(eventName, eventVersion);
|
|
119
|
+
const schema = allowedEvents.get(key2);
|
|
120
|
+
if (!schema) throw new Error(`UndeclaredEvent: ${key2} not allowed by ${opKey(spec.meta.key, spec.meta.version)}`);
|
|
121
|
+
const parsed = schema.getZod().parse(payload);
|
|
122
|
+
await ctx.eventPublisher?.({
|
|
123
|
+
key: eventName,
|
|
124
|
+
version: eventVersion,
|
|
125
|
+
payload: parsed,
|
|
126
|
+
traceId: ctx.traceId
|
|
127
|
+
});
|
|
128
|
+
};
|
|
129
|
+
if (ctx.appConfig) {
|
|
130
|
+
if (!ctx.branding) ctx.branding = ctx.appConfig.branding;
|
|
131
|
+
if (!ctx.translation) ctx.translation = { config: ctx.appConfig.translation };
|
|
132
|
+
else if (!ctx.translation.config) ctx.translation = {
|
|
133
|
+
...ctx.translation,
|
|
134
|
+
config: ctx.appConfig.translation
|
|
135
|
+
};
|
|
136
|
+
}
|
|
137
|
+
const telemetryContext = ctx.telemetry;
|
|
138
|
+
const trackTelemetry = async (trigger, details) => {
|
|
139
|
+
if (!telemetryContext || !trigger?.event) return;
|
|
140
|
+
try {
|
|
141
|
+
const props = trigger.properties?.(details) ?? {};
|
|
142
|
+
await telemetryContext.track(trigger.event.key, trigger.event.version ?? "1.0.0", props, {
|
|
143
|
+
tenantId: ctx.organizationId ?? void 0,
|
|
144
|
+
organizationId: ctx.organizationId,
|
|
145
|
+
userId: ctx.userId,
|
|
146
|
+
actor: ctx.actor,
|
|
147
|
+
channel: ctx.channel,
|
|
148
|
+
metadata: ctx.traceId ? { traceId: ctx.traceId } : void 0
|
|
149
|
+
});
|
|
150
|
+
} catch (_error) {}
|
|
151
|
+
};
|
|
152
|
+
let result;
|
|
153
|
+
try {
|
|
154
|
+
result = await handler(parsedInput, {
|
|
155
|
+
...ctx,
|
|
156
|
+
__emitGuard__: emitGuard
|
|
157
|
+
});
|
|
158
|
+
} catch (error) {
|
|
159
|
+
if (spec.telemetry?.failure) await trackTelemetry(spec.telemetry.failure, {
|
|
160
|
+
input: parsedInput ?? rawInput,
|
|
161
|
+
error
|
|
162
|
+
});
|
|
163
|
+
throw error;
|
|
164
|
+
}
|
|
165
|
+
if (spec.telemetry?.success) await trackTelemetry(spec.telemetry.success, {
|
|
166
|
+
input: parsedInput ?? rawInput,
|
|
167
|
+
output: result
|
|
168
|
+
});
|
|
169
|
+
const outputModel = spec.io.output;
|
|
170
|
+
if (outputModel?.getZod) return outputModel.getZod().parse(result);
|
|
171
|
+
return result;
|
|
172
|
+
}
|
|
173
|
+
};
|
|
174
|
+
|
|
175
|
+
//#endregion
|
|
176
|
+
export { OperationSpecRegistry, opKey };
|
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
import { DocId } from "./docs/registry.js";
|
|
2
|
+
import "./docs/index.js";
|
|
3
|
+
|
|
4
|
+
//#region src/ownership.d.ts
|
|
5
|
+
declare const StabilityEnum: {
|
|
6
|
+
readonly Idea: "idea";
|
|
7
|
+
readonly InCreation: "in_creation";
|
|
8
|
+
readonly Experimental: "experimental";
|
|
9
|
+
readonly Beta: "beta";
|
|
10
|
+
readonly Stable: "stable";
|
|
11
|
+
readonly Deprecated: "deprecated";
|
|
12
|
+
};
|
|
13
|
+
type Stability = (typeof StabilityEnum)[keyof typeof StabilityEnum];
|
|
14
|
+
declare const OwnersEnum: {
|
|
15
|
+
readonly PlatformCore: "platform.core";
|
|
16
|
+
readonly PlatformSigil: "platform.sigil";
|
|
17
|
+
readonly PlatformMarketplace: "platform.marketplace";
|
|
18
|
+
readonly PlatformMessaging: "platform.messaging";
|
|
19
|
+
readonly PlatformContent: "platform.content";
|
|
20
|
+
readonly PlatformFeatureFlags: "platform.featureflags";
|
|
21
|
+
readonly PlatformFinance: "platform.finance";
|
|
22
|
+
};
|
|
23
|
+
type Owner = (typeof OwnersEnum)[keyof typeof OwnersEnum] | (string & {});
|
|
24
|
+
declare const Owners: {
|
|
25
|
+
readonly PlatformCore: "platform.core";
|
|
26
|
+
readonly PlatformSigil: "platform.sigil";
|
|
27
|
+
readonly PlatformMarketplace: "platform.marketplace";
|
|
28
|
+
readonly PlatformMessaging: "platform.messaging";
|
|
29
|
+
readonly PlatformContent: "platform.content";
|
|
30
|
+
readonly PlatformFeatureFlags: "platform.featureflags";
|
|
31
|
+
readonly PlatformFinance: "platform.finance";
|
|
32
|
+
};
|
|
33
|
+
declare const TagsEnum: {
|
|
34
|
+
readonly Spots: "spots";
|
|
35
|
+
readonly Collectivity: "collectivity";
|
|
36
|
+
readonly Marketplace: "marketplace";
|
|
37
|
+
readonly Sellers: "sellers";
|
|
38
|
+
readonly Auth: "auth";
|
|
39
|
+
readonly Login: "login";
|
|
40
|
+
readonly Signup: "signup";
|
|
41
|
+
readonly Guide: "guide";
|
|
42
|
+
readonly Docs: "docs";
|
|
43
|
+
readonly I18n: "i18n";
|
|
44
|
+
readonly Incident: "incident";
|
|
45
|
+
readonly Automation: "automation";
|
|
46
|
+
readonly Hygiene: "hygiene";
|
|
47
|
+
};
|
|
48
|
+
type Tag = (typeof TagsEnum)[keyof typeof TagsEnum] | (string & {});
|
|
49
|
+
declare const Tags: {
|
|
50
|
+
readonly Spots: "spots";
|
|
51
|
+
readonly Collectivity: "collectivity";
|
|
52
|
+
readonly Marketplace: "marketplace";
|
|
53
|
+
readonly Sellers: "sellers";
|
|
54
|
+
readonly Auth: "auth";
|
|
55
|
+
readonly Login: "login";
|
|
56
|
+
readonly Signup: "signup";
|
|
57
|
+
readonly Guide: "guide";
|
|
58
|
+
readonly Docs: "docs";
|
|
59
|
+
readonly I18n: "i18n";
|
|
60
|
+
readonly Incident: "incident";
|
|
61
|
+
readonly Automation: "automation";
|
|
62
|
+
readonly Hygiene: "hygiene";
|
|
63
|
+
};
|
|
64
|
+
interface OwnerShipMeta {
|
|
65
|
+
/** Breaking changes => bump version */
|
|
66
|
+
version: string;
|
|
67
|
+
/** Fully-qualified spec key (e.g., "sigil.beginSignup") */
|
|
68
|
+
key: string;
|
|
69
|
+
/** Human-friendly spec title (e.g., "Signup begin") */
|
|
70
|
+
title?: string;
|
|
71
|
+
/** Short human-friendly summary */
|
|
72
|
+
description: string;
|
|
73
|
+
domain?: string;
|
|
74
|
+
/** Lifecycle marker for comms & tooling */
|
|
75
|
+
stability: Stability;
|
|
76
|
+
/** Owners for CODEOWNERS / on-call / approvals */
|
|
77
|
+
owners: Owner[];
|
|
78
|
+
/** Search tags, grouping, docs navigation */
|
|
79
|
+
tags: Tag[];
|
|
80
|
+
/** Doc block(s) for this operation. */
|
|
81
|
+
docId?: DocId[];
|
|
82
|
+
}
|
|
83
|
+
//#endregion
|
|
84
|
+
export { Owner, OwnerShipMeta, Owners, OwnersEnum, Stability, StabilityEnum, Tag, Tags, TagsEnum };
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
//#region src/ownership.ts
|
|
2
|
+
const StabilityEnum = {
|
|
3
|
+
Idea: "idea",
|
|
4
|
+
InCreation: "in_creation",
|
|
5
|
+
Experimental: "experimental",
|
|
6
|
+
Beta: "beta",
|
|
7
|
+
Stable: "stable",
|
|
8
|
+
Deprecated: "deprecated"
|
|
9
|
+
};
|
|
10
|
+
const OwnersEnum = {
|
|
11
|
+
PlatformCore: "platform.core",
|
|
12
|
+
PlatformSigil: "platform.sigil",
|
|
13
|
+
PlatformMarketplace: "platform.marketplace",
|
|
14
|
+
PlatformMessaging: "platform.messaging",
|
|
15
|
+
PlatformContent: "platform.content",
|
|
16
|
+
PlatformFeatureFlags: "platform.featureflags",
|
|
17
|
+
PlatformFinance: "platform.finance"
|
|
18
|
+
};
|
|
19
|
+
const Owners = OwnersEnum;
|
|
20
|
+
const TagsEnum = {
|
|
21
|
+
Spots: "spots",
|
|
22
|
+
Collectivity: "collectivity",
|
|
23
|
+
Marketplace: "marketplace",
|
|
24
|
+
Sellers: "sellers",
|
|
25
|
+
Auth: "auth",
|
|
26
|
+
Login: "login",
|
|
27
|
+
Signup: "signup",
|
|
28
|
+
Guide: "guide",
|
|
29
|
+
Docs: "docs",
|
|
30
|
+
I18n: "i18n",
|
|
31
|
+
Incident: "incident",
|
|
32
|
+
Automation: "automation",
|
|
33
|
+
Hygiene: "hygiene"
|
|
34
|
+
};
|
|
35
|
+
const Tags = TagsEnum;
|
|
36
|
+
|
|
37
|
+
//#endregion
|
|
38
|
+
export { Owners, OwnersEnum, StabilityEnum, Tags, TagsEnum };
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import { registerDocBlocks } from "../../docs/registry.js";
|
|
2
|
+
|
|
3
|
+
//#region src/policy/docs/policy.docblock.ts
|
|
4
|
+
const tech_contracts_policy_DocBlocks = [{
|
|
5
|
+
id: "docs.tech.contracts.policy",
|
|
6
|
+
title: "PolicySpec & PolicyEngine",
|
|
7
|
+
summary: "`PolicySpec` gives a declarative, typed home for access-control logic covering:",
|
|
8
|
+
kind: "reference",
|
|
9
|
+
visibility: "public",
|
|
10
|
+
route: "/docs/tech/contracts/policy",
|
|
11
|
+
tags: [
|
|
12
|
+
"tech",
|
|
13
|
+
"contracts",
|
|
14
|
+
"policy"
|
|
15
|
+
],
|
|
16
|
+
body: "# PolicySpec & PolicyEngine\n\n## Purpose\n\n`PolicySpec` gives a declarative, typed home for access-control logic covering:\n- **Who** can perform an action (ABAC/ReBAC style rules)\n- **What** they can access (resources + optional field-level overrides)\n- **When** special conditions apply (contextual expressions)\n- **How** PII should be handled (consent/retention hints)\n\n`PolicyEngine` evaluates one or more policies and returns an `allow`/`deny` decision, field-level outcomes, and PII metadata suitable for downstream enforcement (`OperationSpecRegistry` → `ctx.decide`).\n\n## Location\n\n- Types & registry: `packages/libs/contracts/src/policy/spec.ts`\n- Runtime evaluation: `packages/libs/contracts/src/policy/engine.ts`\n- Tests: `packages/.../policy/engine.test.ts`\n\n## `PolicySpec`\n\n```ts\nexport interface PolicySpec {\n meta: PolicyMeta; // ownership metadata + { name, version, scope? }\n rules: PolicyRule[]; // allow/deny rules for actions\n fieldPolicies?: FieldPolicyRule[];\n pii?: { fields: string[]; consentRequired?: boolean; retentionDays?: number };\n relationships?: RelationshipDefinition[];\n consents?: ConsentDefinition[];\n rateLimits?: RateLimitDefinition[];\n opa?: { package: string; decision?: string };\n}\n```\n\n- `PolicyRule`\n - `effect`: `'allow' | 'deny'`\n - `actions`: e.g., `['read', 'write', 'delete']` (string namespace is flexible)\n - `subject`: `{ roles?: string[]; attributes?: { attr: matcher } }`\n - `resource`: `{ type: string; fields?: string[]; attributes?: {...} }`\n - `relationships`: `{ relation, objectId?, objectType? }[]` → ReBAC checks (use `objectId: '$resource'` to target the current resource)\n - `requiresConsent`: `['consent_id']` → references spec-level consent definitions\n - `flags`: feature flags that must be enabled (`DecisionContext.flags`)\n - `rateLimit`: string reference to `rateLimits` entry or inline object `{ rpm, key?, windowSeconds?, burst? }`\n - `escalate`: `'human_review' | null` to indicate manual approval\n - `conditions`: optional expression snippets evaluated against `{ subject, resource, context }`\n- `FieldPolicyRule`\n - `field`: dot-path string (e.g., `contact.email`)\n - `actions`: subset of `['read', 'write']`\n - Same `subject` / `resource` / `conditions` shape\n - Useful for redacting specific fields, even when the global action is allowed\n- `RelationshipDefinition`\n - Canonical tuples for relationship graph (`subjectType`, `relation`, `objectType`, `transitive?`)\n- `ConsentDefinition`\n - `{ id, scope, purpose, lawfulBasis?, expiresInDays?, required? }`\n- `RateLimitDefinition`\n - `{ id, rpm, key?, windowSeconds?, burst? }`\n- `PolicyRef`\n - `{ name: string; version: string }` → attach to contract specs / workflows\n\n## Registry\n\n```ts\nconst registry = new PolicyRegistry();\nregistry.register(CorePolicySpec);\nconst spec = registry.get('core.default', 1);\n```\n\nGuarantees uniqueness per `(name, version)` and exposes helpers to resolve highest versions.\n\n## Engine\n\n```ts\nconst engine = new PolicyEngine(policyRegistry);\n\nconst decision = engine.decide({\n action: 'read',\n subject: { roles: ['admin'] },\n resource: { type: 'resident', fields: ['contact.email'] },\n policies: [{ name: 'core.default', version: '1.0.0' }],\n});\n/*\n{\n effect: 'allow',\n reason: 'core.default',\n fieldDecisions: [{ field: 'contact.email', effect: 'allow' }],\n pii: { fields: ['contact.email'], consentRequired: true }\n}\n*/\n```\n\n- First matching **deny** wins; otherwise the first **allow** is returned.\n- Field policies are aggregated across referenced policies:\n - Later denies override earlier allows for a given field.\n - Returned as `fieldDecisions` to simplify downstream masking.\n- PII metadata is surfaced when defined to help adapt logging/telemetry.\n\n### Expression Support\n\nConditions accept small JS snippets (e.g., `subject.attributes.orgId === context.orgId`). The engine runs them in a constrained scope (`subject`, `resource`, `context`) without access to global state.\n\n### ReBAC & Relationships\n\n- Provide relationship tuples via `PolicySpec.relationships` for documentation/validation.\n- Reference them inside rules with `relationships: [{ relation: 'manager_of', objectType: 'resident', objectId: '$resource' }]`.\n- The execution context must populate `subject.relationships` (`[{ relation, object, objectType }]`) for the engine to evaluate ReBAC guards.\n\n### Consent & Rate Limits\n\n- Declare reusable consent definitions under `consents`. Rules list the IDs they require; if a user session lacks the consent (`DecisionContext.consents`), the engine returns `effect: 'deny'` with `reason: 'consent_required'` and enumerates missing consents.\n- Attach rate limits either inline or via `rateLimits` references. When a rule matches, the engine surfaces `{ rpm, key, windowSeconds?, burst? }` so callers can feed it to shared limiters.\n\n### OPA Adapter\n\n- `OPAPolicyAdapter` bridges engine decisions to Open Policy Agent (OPA). It forwards the evaluation context + policies to OPA and merges any override result (`effect`, `reason`, `fieldDecisions`, `requiredConsents`).\n- Use when migrating to OPA policies or running defense-in-depth: call `engine.decide()`, then pass the preliminary decision to `adapter.evaluate(...)`. The adapter marks merged decisions with `evaluatedBy: 'opa'`.\n- OPA inputs include meta, rules, relationships, rate limits, and consent catalogs to simplify policy authoring on the OPA side.\n\n## Contract Integration\n\n`ContractSpec.policy` now supports:\n\n```ts\npolicy: {\n auth: 'anonymous' | 'user' | 'admin';\n ...\n policies?: PolicyRef[]; // policies evaluated before execution\n fieldPolicies?: { // field hints (read/write) per policy\n field: string;\n actions: ('read' | 'write')[];\n policy?: PolicyRef;\n }[];\n}\n```\n\nAdapters can resolve refs through a shared `PolicyEngine` and populate `ctx.decide` so `OperationSpecRegistry.execute` benefits from centralized enforcement.\n\n## Authoring Guidelines\n\n1. Prefer **allow-by-default** policies but explicitly deny sensitive flows (defense-in-depth).\n2. Keep rule scopes narrow (per feature/operation) and compose multiple `PolicyRef`s when necessary.\n3. Store PII field lists here to avoid duplication across logs/telemetry.\n4. Use explicit rule reasons for auditability and better developer feedback.\n5. Treat versioning seriously; bump `meta.version` whenever behavior changes.\n\n## Future Enhancements\n\n- Richer expression language (composable predicates, time-based conditions).\n- Multi-tenant relationship graph services (store/resolve relationships at scale).\n- Tooling that auto-generates docs/tests for policies referenced in specs.\n\n"
|
|
17
|
+
}];
|
|
18
|
+
registerDocBlocks(tech_contracts_policy_DocBlocks);
|
|
19
|
+
|
|
20
|
+
//#endregion
|
|
21
|
+
export { tech_contracts_policy_DocBlocks };
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
import { PolicyRef } from "./spec.js";
|
|
2
|
+
import { PolicyRegistry } from "./registry.js";
|
|
3
|
+
import { PolicyDecision } from "../types.js";
|
|
4
|
+
|
|
5
|
+
//#region src/policy/engine.d.ts
|
|
6
|
+
interface SubjectRelationship {
|
|
7
|
+
relation: string;
|
|
8
|
+
object: string;
|
|
9
|
+
objectType?: string;
|
|
10
|
+
}
|
|
11
|
+
interface SubjectContext {
|
|
12
|
+
roles?: string[];
|
|
13
|
+
attributes?: Record<string, unknown>;
|
|
14
|
+
relationships?: SubjectRelationship[];
|
|
15
|
+
}
|
|
16
|
+
interface ResourceContext {
|
|
17
|
+
type: string;
|
|
18
|
+
id?: string;
|
|
19
|
+
fields?: string[];
|
|
20
|
+
attributes?: Record<string, unknown>;
|
|
21
|
+
}
|
|
22
|
+
interface DecisionContext {
|
|
23
|
+
subject: SubjectContext;
|
|
24
|
+
resource: ResourceContext;
|
|
25
|
+
context?: Record<string, unknown>;
|
|
26
|
+
action: string;
|
|
27
|
+
policies: PolicyRef[];
|
|
28
|
+
consents?: string[];
|
|
29
|
+
flags?: string[];
|
|
30
|
+
}
|
|
31
|
+
declare class PolicyEngine {
|
|
32
|
+
private readonly registry;
|
|
33
|
+
constructor(registry: PolicyRegistry);
|
|
34
|
+
decide(input: DecisionContext): PolicyDecision;
|
|
35
|
+
private resolvePolicies;
|
|
36
|
+
private matchRuleSet;
|
|
37
|
+
private evaluateFields;
|
|
38
|
+
}
|
|
39
|
+
//#endregion
|
|
40
|
+
export { DecisionContext, PolicyEngine, ResourceContext, SubjectContext, SubjectRelationship };
|