@ixo/decision-oracle 0.0.0-stage → 0.2.1
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 +201 -0
- package/README.md +794 -2
- package/dist/act.d.ts +87 -0
- package/dist/act.d.ts.map +1 -0
- package/dist/act.js +20 -0
- package/dist/act.js.map +1 -0
- package/dist/app.d.ts +22 -0
- package/dist/app.d.ts.map +1 -0
- package/dist/app.js +128 -0
- package/dist/app.js.map +1 -0
- package/dist/c2pa.wasm +0 -0
- package/dist/cli/commands/api.d.ts +50 -0
- package/dist/cli/commands/api.d.ts.map +1 -0
- package/dist/cli/commands/api.js +737 -0
- package/dist/cli/commands/api.js.map +1 -0
- package/dist/cli/commands/create-collection.d.ts +40 -0
- package/dist/cli/commands/create-collection.d.ts.map +1 -0
- package/dist/cli/commands/create-collection.js +318 -0
- package/dist/cli/commands/create-collection.js.map +1 -0
- package/dist/cli/commands/create-deed.d.ts +31 -0
- package/dist/cli/commands/create-deed.d.ts.map +1 -0
- package/dist/cli/commands/create-deed.js +208 -0
- package/dist/cli/commands/create-deed.js.map +1 -0
- package/dist/cli/commands/delegation.d.ts +26 -0
- package/dist/cli/commands/delegation.d.ts.map +1 -0
- package/dist/cli/commands/delegation.js +162 -0
- package/dist/cli/commands/delegation.js.map +1 -0
- package/dist/cli/commands/derive.d.ts +22 -0
- package/dist/cli/commands/derive.d.ts.map +1 -0
- package/dist/cli/commands/derive.js +53 -0
- package/dist/cli/commands/derive.js.map +1 -0
- package/dist/cli/commands/engine.d.ts +25 -0
- package/dist/cli/commands/engine.d.ts.map +1 -0
- package/dist/cli/commands/engine.js +107 -0
- package/dist/cli/commands/engine.js.map +1 -0
- package/dist/cli/commands/erase.d.ts +17 -0
- package/dist/cli/commands/erase.d.ts.map +1 -0
- package/dist/cli/commands/erase.js +117 -0
- package/dist/cli/commands/erase.js.map +1 -0
- package/dist/cli/commands/facts-run.d.ts +30 -0
- package/dist/cli/commands/facts-run.d.ts.map +1 -0
- package/dist/cli/commands/facts-run.js +409 -0
- package/dist/cli/commands/facts-run.js.map +1 -0
- package/dist/cli/commands/facts-scaffold.d.ts +22 -0
- package/dist/cli/commands/facts-scaffold.d.ts.map +1 -0
- package/dist/cli/commands/facts-scaffold.js +208 -0
- package/dist/cli/commands/facts-scaffold.js.map +1 -0
- package/dist/cli/commands/init.d.ts +18 -0
- package/dist/cli/commands/init.d.ts.map +1 -0
- package/dist/cli/commands/init.js +34 -0
- package/dist/cli/commands/init.js.map +1 -0
- package/dist/cli/commands/login.d.ts +9 -0
- package/dist/cli/commands/login.d.ts.map +1 -0
- package/dist/cli/commands/login.js +16 -0
- package/dist/cli/commands/login.js.map +1 -0
- package/dist/cli/commands/logout.d.ts +10 -0
- package/dist/cli/commands/logout.d.ts.map +1 -0
- package/dist/cli/commands/logout.js +28 -0
- package/dist/cli/commands/logout.js.map +1 -0
- package/dist/cli/commands/manifest.d.ts +12 -0
- package/dist/cli/commands/manifest.d.ts.map +1 -0
- package/dist/cli/commands/manifest.js +48 -0
- package/dist/cli/commands/manifest.js.map +1 -0
- package/dist/cli/commands/oracle-init.d.ts +48 -0
- package/dist/cli/commands/oracle-init.d.ts.map +1 -0
- package/dist/cli/commands/oracle-init.js +1122 -0
- package/dist/cli/commands/oracle-init.js.map +1 -0
- package/dist/cli/commands/org.d.ts +28 -0
- package/dist/cli/commands/org.d.ts.map +1 -0
- package/dist/cli/commands/org.js +309 -0
- package/dist/cli/commands/org.js.map +1 -0
- package/dist/cli/commands/protocol-review.d.ts +20 -0
- package/dist/cli/commands/protocol-review.d.ts.map +1 -0
- package/dist/cli/commands/protocol-review.js +162 -0
- package/dist/cli/commands/protocol-review.js.map +1 -0
- package/dist/cli/commands/publish-protocol.d.ts +43 -0
- package/dist/cli/commands/publish-protocol.d.ts.map +1 -0
- package/dist/cli/commands/publish-protocol.js +345 -0
- package/dist/cli/commands/publish-protocol.js.map +1 -0
- package/dist/cli/commands/register.d.ts +16 -0
- package/dist/cli/commands/register.d.ts.map +1 -0
- package/dist/cli/commands/register.js +54 -0
- package/dist/cli/commands/register.js.map +1 -0
- package/dist/cli/commands/relink.d.ts +11 -0
- package/dist/cli/commands/relink.d.ts.map +1 -0
- package/dist/cli/commands/relink.js +36 -0
- package/dist/cli/commands/relink.js.map +1 -0
- package/dist/cli/commands/rubric-fetch-form.d.ts +16 -0
- package/dist/cli/commands/rubric-fetch-form.d.ts.map +1 -0
- package/dist/cli/commands/rubric-fetch-form.js +83 -0
- package/dist/cli/commands/rubric-fetch-form.js.map +1 -0
- package/dist/cli/commands/rubric-validate.d.ts +72 -0
- package/dist/cli/commands/rubric-validate.d.ts.map +1 -0
- package/dist/cli/commands/rubric-validate.js +163 -0
- package/dist/cli/commands/rubric-validate.js.map +1 -0
- package/dist/cli/commands/scan.d.ts +13 -0
- package/dist/cli/commands/scan.d.ts.map +1 -0
- package/dist/cli/commands/scan.js +39 -0
- package/dist/cli/commands/scan.js.map +1 -0
- package/dist/cli/commands/skills.d.ts +11 -0
- package/dist/cli/commands/skills.d.ts.map +1 -0
- package/dist/cli/commands/skills.js +19 -0
- package/dist/cli/commands/skills.js.map +1 -0
- package/dist/cli/commands/submit-claim.d.ts +25 -0
- package/dist/cli/commands/submit-claim.d.ts.map +1 -0
- package/dist/cli/commands/submit-claim.js +155 -0
- package/dist/cli/commands/submit-claim.js.map +1 -0
- package/dist/cli/index.d.ts +15 -0
- package/dist/cli/index.d.ts.map +1 -0
- package/dist/cli/index.js +206 -0
- package/dist/cli/index.js.map +1 -0
- package/dist/cli/lib/agent-card-schema.d.ts +8 -0
- package/dist/cli/lib/agent-card-schema.d.ts.map +1 -0
- package/dist/cli/lib/agent-card-schema.js +169 -0
- package/dist/cli/lib/agent-card-schema.js.map +1 -0
- package/dist/cli/lib/ai-rest.d.ts +12 -0
- package/dist/cli/lib/ai-rest.d.ts.map +1 -0
- package/dist/cli/lib/ai-rest.js +36 -0
- package/dist/cli/lib/ai-rest.js.map +1 -0
- package/dist/cli/lib/args.d.ts +33 -0
- package/dist/cli/lib/args.d.ts.map +1 -0
- package/dist/cli/lib/args.js +24 -0
- package/dist/cli/lib/args.js.map +1 -0
- package/dist/cli/lib/authhub.d.ts +7 -0
- package/dist/cli/lib/authhub.d.ts.map +1 -0
- package/dist/cli/lib/authhub.js +210 -0
- package/dist/cli/lib/authhub.js.map +1 -0
- package/dist/cli/lib/chain.d.ts +264 -0
- package/dist/cli/lib/chain.d.ts.map +1 -0
- package/dist/cli/lib/chain.js +584 -0
- package/dist/cli/lib/chain.js.map +1 -0
- package/dist/cli/lib/devvars.d.ts +59 -0
- package/dist/cli/lib/devvars.d.ts.map +1 -0
- package/dist/cli/lib/devvars.js +206 -0
- package/dist/cli/lib/devvars.js.map +1 -0
- package/dist/cli/lib/engine.d.ts +54 -0
- package/dist/cli/lib/engine.d.ts.map +1 -0
- package/dist/cli/lib/engine.js +112 -0
- package/dist/cli/lib/engine.js.map +1 -0
- package/dist/cli/lib/identity-cards.d.ts +188 -0
- package/dist/cli/lib/identity-cards.d.ts.map +1 -0
- package/dist/cli/lib/identity-cards.js +261 -0
- package/dist/cli/lib/identity-cards.js.map +1 -0
- package/dist/cli/lib/matrix-account.d.ts +79 -0
- package/dist/cli/lib/matrix-account.d.ts.map +1 -0
- package/dist/cli/lib/matrix-account.js +228 -0
- package/dist/cli/lib/matrix-account.js.map +1 -0
- package/dist/cli/lib/oracle-account.d.ts +108 -0
- package/dist/cli/lib/oracle-account.d.ts.map +1 -0
- package/dist/cli/lib/oracle-account.js +207 -0
- package/dist/cli/lib/oracle-account.js.map +1 -0
- package/dist/cli/lib/project.d.ts +22 -0
- package/dist/cli/lib/project.d.ts.map +1 -0
- package/dist/cli/lib/project.js +62 -0
- package/dist/cli/lib/project.js.map +1 -0
- package/dist/cli/lib/session.d.ts +109 -0
- package/dist/cli/lib/session.d.ts.map +1 -0
- package/dist/cli/lib/session.js +354 -0
- package/dist/cli/lib/session.js.map +1 -0
- package/dist/cli/lib/workorder.d.ts +57 -0
- package/dist/cli/lib/workorder.d.ts.map +1 -0
- package/dist/cli/lib/workorder.js +101 -0
- package/dist/cli/lib/workorder.js.map +1 -0
- package/dist/config.d.ts +221 -0
- package/dist/config.d.ts.map +1 -0
- package/dist/config.js +431 -0
- package/dist/config.js.map +1 -0
- package/dist/context.d.ts +88 -0
- package/dist/context.d.ts.map +1 -0
- package/dist/context.js +9 -0
- package/dist/context.js.map +1 -0
- package/dist/contracts/api.d.ts +3367 -0
- package/dist/contracts/api.d.ts.map +1 -0
- package/dist/contracts/api.js +1303 -0
- package/dist/contracts/api.js.map +1 -0
- package/dist/contracts/capabilities.d.ts +126 -0
- package/dist/contracts/capabilities.d.ts.map +1 -0
- package/dist/contracts/capabilities.js +164 -0
- package/dist/contracts/capabilities.js.map +1 -0
- package/dist/contracts/claim-source.d.ts +98 -0
- package/dist/contracts/claim-source.d.ts.map +1 -0
- package/dist/contracts/claim-source.js +17 -0
- package/dist/contracts/claim-source.js.map +1 -0
- package/dist/contracts/errors.d.ts +150 -0
- package/dist/contracts/errors.d.ts.map +1 -0
- package/dist/contracts/errors.js +121 -0
- package/dist/contracts/errors.js.map +1 -0
- package/dist/contracts/index.d.ts +15 -0
- package/dist/contracts/index.d.ts.map +1 -0
- package/dist/contracts/index.js +11 -0
- package/dist/contracts/index.js.map +1 -0
- package/dist/contracts/payment-gate.d.ts +129 -0
- package/dist/contracts/payment-gate.d.ts.map +1 -0
- package/dist/contracts/payment-gate.js +24 -0
- package/dist/contracts/payment-gate.js.map +1 -0
- package/dist/contracts/start-api-claim.d.ts +90 -0
- package/dist/contracts/start-api-claim.d.ts.map +1 -0
- package/dist/contracts/start-api-claim.js +22 -0
- package/dist/contracts/start-api-claim.js.map +1 -0
- package/dist/contracts/webhooks.d.ts +1487 -0
- package/dist/contracts/webhooks.d.ts.map +1 -0
- package/dist/contracts/webhooks.js +71 -0
- package/dist/contracts/webhooks.js.map +1 -0
- package/dist/contracts/work-order.d.ts +29 -0
- package/dist/contracts/work-order.d.ts.map +1 -0
- package/dist/contracts/work-order.js +12 -0
- package/dist/contracts/work-order.js.map +1 -0
- package/dist/cron/ai-cost.d.ts +29 -0
- package/dist/cron/ai-cost.d.ts.map +1 -0
- package/dist/cron/ai-cost.js +80 -0
- package/dist/cron/ai-cost.js.map +1 -0
- package/dist/cron/api-lane.d.ts +39 -0
- package/dist/cron/api-lane.d.ts.map +1 -0
- package/dist/cron/api-lane.js +203 -0
- package/dist/cron/api-lane.js.map +1 -0
- package/dist/cron/backlog.d.ts +50 -0
- package/dist/cron/backlog.d.ts.map +1 -0
- package/dist/cron/backlog.js +115 -0
- package/dist/cron/backlog.js.map +1 -0
- package/dist/cron/billing.d.ts +11 -0
- package/dist/cron/billing.d.ts.map +1 -0
- package/dist/cron/billing.js +69 -0
- package/dist/cron/billing.js.map +1 -0
- package/dist/cron/collection.d.ts +50 -0
- package/dist/cron/collection.d.ts.map +1 -0
- package/dist/cron/collection.js +118 -0
- package/dist/cron/collection.js.map +1 -0
- package/dist/cron/funding.d.ts +16 -0
- package/dist/cron/funding.d.ts.map +1 -0
- package/dist/cron/funding.js +262 -0
- package/dist/cron/funding.js.map +1 -0
- package/dist/cron/payer-billing.d.ts +38 -0
- package/dist/cron/payer-billing.d.ts.map +1 -0
- package/dist/cron/payer-billing.js +119 -0
- package/dist/cron/payer-billing.js.map +1 -0
- package/dist/cron/scan.d.ts +43 -0
- package/dist/cron/scan.d.ts.map +1 -0
- package/dist/cron/scan.js +250 -0
- package/dist/cron/scan.js.map +1 -0
- package/dist/db/client.d.ts +14 -0
- package/dist/db/client.d.ts.map +1 -0
- package/dist/db/client.js +14 -0
- package/dist/db/client.js.map +1 -0
- package/dist/db/index.d.ts +7 -0
- package/dist/db/index.d.ts.map +1 -0
- package/dist/db/index.js +7 -0
- package/dist/db/index.js.map +1 -0
- package/dist/db/schema.d.ts +6738 -0
- package/dist/db/schema.d.ts.map +1 -0
- package/dist/db/schema.js +1433 -0
- package/dist/db/schema.js.map +1 -0
- package/dist/define-oracle.d.ts +32 -0
- package/dist/define-oracle.d.ts.map +1 -0
- package/dist/define-oracle.js +80 -0
- package/dist/define-oracle.js.map +1 -0
- package/dist/dev-oracle.d.ts +9 -0
- package/dist/dev-oracle.d.ts.map +1 -0
- package/dist/dev-oracle.js +19 -0
- package/dist/dev-oracle.js.map +1 -0
- package/dist/dev-worker.d.ts +10 -0
- package/dist/dev-worker.d.ts.map +1 -0
- package/dist/dev-worker.js +12 -0
- package/dist/dev-worker.js.map +1 -0
- package/dist/env.d.ts +146 -0
- package/dist/env.d.ts.map +1 -0
- package/dist/env.js +10 -0
- package/dist/env.js.map +1 -0
- package/dist/facts/exif.d.ts +43 -0
- package/dist/facts/exif.d.ts.map +1 -0
- package/dist/facts/exif.js +224 -0
- package/dist/facts/exif.js.map +1 -0
- package/dist/facts/fact.d.ts +62 -0
- package/dist/facts/fact.d.ts.map +1 -0
- package/dist/facts/fact.js +105 -0
- package/dist/facts/fact.js.map +1 -0
- package/dist/facts/geo.d.ts +55 -0
- package/dist/facts/geo.d.ts.map +1 -0
- package/dist/facts/geo.js +267 -0
- package/dist/facts/geo.js.map +1 -0
- package/dist/facts/index.d.ts +31 -0
- package/dist/facts/index.d.ts.map +1 -0
- package/dist/facts/index.js +27 -0
- package/dist/facts/index.js.map +1 -0
- package/dist/facts/linked-doc.d.ts +60 -0
- package/dist/facts/linked-doc.d.ts.map +1 -0
- package/dist/facts/linked-doc.js +101 -0
- package/dist/facts/linked-doc.js.map +1 -0
- package/dist/facts/types.d.ts +278 -0
- package/dist/facts/types.d.ts.map +1 -0
- package/dist/facts/types.js +19 -0
- package/dist/facts/types.js.map +1 -0
- package/dist/index.d.ts +25 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +19 -0
- package/dist/index.js.map +1 -0
- package/dist/lib/api-lane/accept.d.ts +29 -0
- package/dist/lib/api-lane/accept.d.ts.map +1 -0
- package/dist/lib/api-lane/accept.js +218 -0
- package/dist/lib/api-lane/accept.js.map +1 -0
- package/dist/lib/api-lane/claim-list.d.ts +44 -0
- package/dist/lib/api-lane/claim-list.d.ts.map +1 -0
- package/dist/lib/api-lane/claim-list.js +92 -0
- package/dist/lib/api-lane/claim-list.js.map +1 -0
- package/dist/lib/api-lane/company.d.ts +56 -0
- package/dist/lib/api-lane/company.d.ts.map +1 -0
- package/dist/lib/api-lane/company.js +103 -0
- package/dist/lib/api-lane/company.js.map +1 -0
- package/dist/lib/api-lane/events.d.ts +21 -0
- package/dist/lib/api-lane/events.d.ts.map +1 -0
- package/dist/lib/api-lane/events.js +111 -0
- package/dist/lib/api-lane/events.js.map +1 -0
- package/dist/lib/api-lane/ids.d.ts +39 -0
- package/dist/lib/api-lane/ids.d.ts.map +1 -0
- package/dist/lib/api-lane/ids.js +78 -0
- package/dist/lib/api-lane/ids.js.map +1 -0
- package/dist/lib/api-lane/index.d.ts +16 -0
- package/dist/lib/api-lane/index.d.ts.map +1 -0
- package/dist/lib/api-lane/index.js +16 -0
- package/dist/lib/api-lane/index.js.map +1 -0
- package/dist/lib/api-lane/linked.d.ts +264 -0
- package/dist/lib/api-lane/linked.d.ts.map +1 -0
- package/dist/lib/api-lane/linked.js +272 -0
- package/dist/lib/api-lane/linked.js.map +1 -0
- package/dist/lib/api-lane/media-type.d.ts +15 -0
- package/dist/lib/api-lane/media-type.d.ts.map +1 -0
- package/dist/lib/api-lane/media-type.js +73 -0
- package/dist/lib/api-lane/media-type.js.map +1 -0
- package/dist/lib/api-lane/member-emails.d.ts +83 -0
- package/dist/lib/api-lane/member-emails.d.ts.map +1 -0
- package/dist/lib/api-lane/member-emails.js +213 -0
- package/dist/lib/api-lane/member-emails.js.map +1 -0
- package/dist/lib/api-lane/members.d.ts +42 -0
- package/dist/lib/api-lane/members.d.ts.map +1 -0
- package/dist/lib/api-lane/members.js +75 -0
- package/dist/lib/api-lane/members.js.map +1 -0
- package/dist/lib/api-lane/notify.d.ts +47 -0
- package/dist/lib/api-lane/notify.d.ts.map +1 -0
- package/dist/lib/api-lane/notify.js +240 -0
- package/dist/lib/api-lane/notify.js.map +1 -0
- package/dist/lib/api-lane/pause.d.ts +41 -0
- package/dist/lib/api-lane/pause.d.ts.map +1 -0
- package/dist/lib/api-lane/pause.js +155 -0
- package/dist/lib/api-lane/pause.js.map +1 -0
- package/dist/lib/api-lane/record.d.ts +76 -0
- package/dist/lib/api-lane/record.d.ts.map +1 -0
- package/dist/lib/api-lane/record.js +337 -0
- package/dist/lib/api-lane/record.js.map +1 -0
- package/dist/lib/api-lane/retention.d.ts +43 -0
- package/dist/lib/api-lane/retention.d.ts.map +1 -0
- package/dist/lib/api-lane/retention.js +176 -0
- package/dist/lib/api-lane/retention.js.map +1 -0
- package/dist/lib/api-lane/review.d.ts +76 -0
- package/dist/lib/api-lane/review.d.ts.map +1 -0
- package/dist/lib/api-lane/review.js +355 -0
- package/dist/lib/api-lane/review.js.map +1 -0
- package/dist/lib/api-lane/reviewers.d.ts +109 -0
- package/dist/lib/api-lane/reviewers.d.ts.map +1 -0
- package/dist/lib/api-lane/reviewers.js +755 -0
- package/dist/lib/api-lane/reviewers.js.map +1 -0
- package/dist/lib/api-lane/source-delete.d.ts +16 -0
- package/dist/lib/api-lane/source-delete.d.ts.map +1 -0
- package/dist/lib/api-lane/source-delete.js +50 -0
- package/dist/lib/api-lane/source-delete.js.map +1 -0
- package/dist/lib/api-lane/source.d.ts +19 -0
- package/dist/lib/api-lane/source.d.ts.map +1 -0
- package/dist/lib/api-lane/source.js +226 -0
- package/dist/lib/api-lane/source.js.map +1 -0
- package/dist/lib/api-lane/submitter.d.ts +22 -0
- package/dist/lib/api-lane/submitter.d.ts.map +1 -0
- package/dist/lib/api-lane/submitter.js +34 -0
- package/dist/lib/api-lane/submitter.js.map +1 -0
- package/dist/lib/api-lane/timeline.d.ts +20 -0
- package/dist/lib/api-lane/timeline.d.ts.map +1 -0
- package/dist/lib/api-lane/timeline.js +23 -0
- package/dist/lib/api-lane/timeline.js.map +1 -0
- package/dist/lib/api-lane/webhook-crypto.d.ts +44 -0
- package/dist/lib/api-lane/webhook-crypto.d.ts.map +1 -0
- package/dist/lib/api-lane/webhook-crypto.js +103 -0
- package/dist/lib/api-lane/webhook-crypto.js.map +1 -0
- package/dist/lib/api-lane/webhooks.d.ts +117 -0
- package/dist/lib/api-lane/webhooks.d.ts.map +1 -0
- package/dist/lib/api-lane/webhooks.js +503 -0
- package/dist/lib/api-lane/webhooks.js.map +1 -0
- package/dist/lib/archive.d.ts +64 -0
- package/dist/lib/archive.d.ts.map +1 -0
- package/dist/lib/archive.js +305 -0
- package/dist/lib/archive.js.map +1 -0
- package/dist/lib/bech32.d.ts +8 -0
- package/dist/lib/bech32.d.ts.map +1 -0
- package/dist/lib/bech32.js +39 -0
- package/dist/lib/bech32.js.map +1 -0
- package/dist/lib/claim-erase.d.ts +22 -0
- package/dist/lib/claim-erase.d.ts.map +1 -0
- package/dist/lib/claim-erase.js +44 -0
- package/dist/lib/claim-erase.js.map +1 -0
- package/dist/lib/cursor.d.ts +11 -0
- package/dist/lib/cursor.d.ts.map +1 -0
- package/dist/lib/cursor.js +20 -0
- package/dist/lib/cursor.js.map +1 -0
- package/dist/lib/email/send.d.ts +43 -0
- package/dist/lib/email/send.d.ts.map +1 -0
- package/dist/lib/email/send.js +71 -0
- package/dist/lib/email/send.js.map +1 -0
- package/dist/lib/email/template.d.ts +217 -0
- package/dist/lib/email/template.d.ts.map +1 -0
- package/dist/lib/email/template.js +713 -0
- package/dist/lib/email/template.js.map +1 -0
- package/dist/lib/engine/adr36.d.ts +56 -0
- package/dist/lib/engine/adr36.d.ts.map +1 -0
- package/dist/lib/engine/adr36.js +76 -0
- package/dist/lib/engine/adr36.js.map +1 -0
- package/dist/lib/engine/client.d.ts +162 -0
- package/dist/lib/engine/client.d.ts.map +1 -0
- package/dist/lib/engine/client.js +473 -0
- package/dist/lib/engine/client.js.map +1 -0
- package/dist/lib/engine/types.d.ts +1356 -0
- package/dist/lib/engine/types.d.ts.map +1 -0
- package/dist/lib/engine/types.js +562 -0
- package/dist/lib/engine/types.js.map +1 -0
- package/dist/lib/errors.d.ts +73 -0
- package/dist/lib/errors.d.ts.map +1 -0
- package/dist/lib/errors.js +96 -0
- package/dist/lib/errors.js.map +1 -0
- package/dist/lib/facts/builder.d.ts +88 -0
- package/dist/lib/facts/builder.d.ts.map +1 -0
- package/dist/lib/facts/builder.js +239 -0
- package/dist/lib/facts/builder.js.map +1 -0
- package/dist/lib/facts/ctx.d.ts +34 -0
- package/dist/lib/facts/ctx.d.ts.map +1 -0
- package/dist/lib/facts/ctx.js +51 -0
- package/dist/lib/facts/ctx.js.map +1 -0
- package/dist/lib/facts/expected.d.ts +23 -0
- package/dist/lib/facts/expected.d.ts.map +1 -0
- package/dist/lib/facts/expected.js +16 -0
- package/dist/lib/facts/expected.js.map +1 -0
- package/dist/lib/facts/fact-cache.d.ts +469 -0
- package/dist/lib/facts/fact-cache.d.ts.map +1 -0
- package/dist/lib/facts/fact-cache.js +52 -0
- package/dist/lib/facts/fact-cache.js.map +1 -0
- package/dist/lib/facts/factset.d.ts +608 -0
- package/dist/lib/facts/factset.d.ts.map +1 -0
- package/dist/lib/facts/factset.js +226 -0
- package/dist/lib/facts/factset.js.map +1 -0
- package/dist/lib/facts/producer.d.ts +190 -0
- package/dist/lib/facts/producer.d.ts.map +1 -0
- package/dist/lib/facts/producer.js +15 -0
- package/dist/lib/facts/producer.js.map +1 -0
- package/dist/lib/facts/runner.d.ts +111 -0
- package/dist/lib/facts/runner.d.ts.map +1 -0
- package/dist/lib/facts/runner.js +438 -0
- package/dist/lib/facts/runner.js.map +1 -0
- package/dist/lib/facts/stock/ai-check.d.ts +100 -0
- package/dist/lib/facts/stock/ai-check.d.ts.map +1 -0
- package/dist/lib/facts/stock/ai-check.js +526 -0
- package/dist/lib/facts/stock/ai-check.js.map +1 -0
- package/dist/lib/facts/stock/ai-inputs.d.ts +104 -0
- package/dist/lib/facts/stock/ai-inputs.d.ts.map +1 -0
- package/dist/lib/facts/stock/ai-inputs.js +332 -0
- package/dist/lib/facts/stock/ai-inputs.js.map +1 -0
- package/dist/lib/facts/stock/ai-provider.d.ts +105 -0
- package/dist/lib/facts/stock/ai-provider.d.ts.map +1 -0
- package/dist/lib/facts/stock/ai-provider.js +250 -0
- package/dist/lib/facts/stock/ai-provider.js.map +1 -0
- package/dist/lib/facts/stock/ai-unique.d.ts +85 -0
- package/dist/lib/facts/stock/ai-unique.d.ts.map +1 -0
- package/dist/lib/facts/stock/ai-unique.js +208 -0
- package/dist/lib/facts/stock/ai-unique.js.map +1 -0
- package/dist/lib/facts/stock/archive.d.ts +63 -0
- package/dist/lib/facts/stock/archive.d.ts.map +1 -0
- package/dist/lib/facts/stock/archive.js +349 -0
- package/dist/lib/facts/stock/archive.js.map +1 -0
- package/dist/lib/facts/stock/c2pa-trust-list.d.ts +16 -0
- package/dist/lib/facts/stock/c2pa-trust-list.d.ts.map +1 -0
- package/dist/lib/facts/stock/c2pa-trust-list.js +637 -0
- package/dist/lib/facts/stock/c2pa-trust-list.js.map +1 -0
- package/dist/lib/facts/stock/c2pa.d.ts +56 -0
- package/dist/lib/facts/stock/c2pa.d.ts.map +1 -0
- package/dist/lib/facts/stock/c2pa.js +234 -0
- package/dist/lib/facts/stock/c2pa.js.map +1 -0
- package/dist/lib/facts/stock/call.d.ts +91 -0
- package/dist/lib/facts/stock/call.d.ts.map +1 -0
- package/dist/lib/facts/stock/call.js +281 -0
- package/dist/lib/facts/stock/call.js.map +1 -0
- package/dist/lib/facts/stock/capability.d.ts +39 -0
- package/dist/lib/facts/stock/capability.d.ts.map +1 -0
- package/dist/lib/facts/stock/capability.js +59 -0
- package/dist/lib/facts/stock/capability.js.map +1 -0
- package/dist/lib/facts/stock/ext-source.d.ts +51 -0
- package/dist/lib/facts/stock/ext-source.d.ts.map +1 -0
- package/dist/lib/facts/stock/ext-source.js +201 -0
- package/dist/lib/facts/stock/ext-source.js.map +1 -0
- package/dist/lib/facts/stock/frequency-fact.d.ts +59 -0
- package/dist/lib/facts/stock/frequency-fact.d.ts.map +1 -0
- package/dist/lib/facts/stock/frequency-fact.js +86 -0
- package/dist/lib/facts/stock/frequency-fact.js.map +1 -0
- package/dist/lib/facts/stock/frequency.d.ts +32 -0
- package/dist/lib/facts/stock/frequency.d.ts.map +1 -0
- package/dist/lib/facts/stock/frequency.js +48 -0
- package/dist/lib/facts/stock/frequency.js.map +1 -0
- package/dist/lib/facts/stock/index.d.ts +27 -0
- package/dist/lib/facts/stock/index.d.ts.map +1 -0
- package/dist/lib/facts/stock/index.js +28 -0
- package/dist/lib/facts/stock/index.js.map +1 -0
- package/dist/lib/facts/stock/normalize.d.ts +45 -0
- package/dist/lib/facts/stock/normalize.d.ts.map +1 -0
- package/dist/lib/facts/stock/normalize.js +135 -0
- package/dist/lib/facts/stock/normalize.js.map +1 -0
- package/dist/lib/facts/stock/phash.d.ts +55 -0
- package/dist/lib/facts/stock/phash.d.ts.map +1 -0
- package/dist/lib/facts/stock/phash.js +256 -0
- package/dist/lib/facts/stock/phash.js.map +1 -0
- package/dist/lib/facts/stock/rule-defaults.d.ts +72 -0
- package/dist/lib/facts/stock/rule-defaults.d.ts.map +1 -0
- package/dist/lib/facts/stock/rule-defaults.js +55 -0
- package/dist/lib/facts/stock/rule-defaults.js.map +1 -0
- package/dist/lib/facts/stock/send.d.ts +52 -0
- package/dist/lib/facts/stock/send.d.ts.map +1 -0
- package/dist/lib/facts/stock/send.js +148 -0
- package/dist/lib/facts/stock/send.js.map +1 -0
- package/dist/lib/facts/stock/unique-score.d.ts +138 -0
- package/dist/lib/facts/stock/unique-score.d.ts.map +1 -0
- package/dist/lib/facts/stock/unique-score.js +257 -0
- package/dist/lib/facts/stock/unique-score.js.map +1 -0
- package/dist/lib/facts/stock/unique-store.d.ts +420 -0
- package/dist/lib/facts/stock/unique-store.d.ts.map +1 -0
- package/dist/lib/facts/stock/unique-store.js +328 -0
- package/dist/lib/facts/stock/unique-store.js.map +1 -0
- package/dist/lib/facts/stock/unique.d.ts +35 -0
- package/dist/lib/facts/stock/unique.d.ts.map +1 -0
- package/dist/lib/facts/stock/unique.js +327 -0
- package/dist/lib/facts/stock/unique.js.map +1 -0
- package/dist/lib/facts/tools.d.ts +57 -0
- package/dist/lib/facts/tools.d.ts.map +1 -0
- package/dist/lib/facts/tools.js +325 -0
- package/dist/lib/facts/tools.js.map +1 -0
- package/dist/lib/facts/validate.d.ts +33 -0
- package/dist/lib/facts/validate.d.ts.map +1 -0
- package/dist/lib/facts/validate.js +137 -0
- package/dist/lib/facts/validate.js.map +1 -0
- package/dist/lib/hash.d.ts +44 -0
- package/dist/lib/hash.d.ts.map +1 -0
- package/dist/lib/hash.js +80 -0
- package/dist/lib/hash.js.map +1 -0
- package/dist/lib/http/client.d.ts +113 -0
- package/dist/lib/http/client.d.ts.map +1 -0
- package/dist/lib/http/client.js +330 -0
- package/dist/lib/http/client.js.map +1 -0
- package/dist/lib/ids.d.ts +17 -0
- package/dist/lib/ids.d.ts.map +1 -0
- package/dist/lib/ids.js +26 -0
- package/dist/lib/ids.js.map +1 -0
- package/dist/lib/ixo/attachments.d.ts +116 -0
- package/dist/lib/ixo/attachments.d.ts.map +1 -0
- package/dist/lib/ixo/attachments.js +290 -0
- package/dist/lib/ixo/attachments.js.map +1 -0
- package/dist/lib/ixo/authz.d.ts +40 -0
- package/dist/lib/ixo/authz.d.ts.map +1 -0
- package/dist/lib/ixo/authz.js +113 -0
- package/dist/lib/ixo/authz.js.map +1 -0
- package/dist/lib/ixo/blocksync/index.d.ts +90 -0
- package/dist/lib/ixo/blocksync/index.d.ts.map +1 -0
- package/dist/lib/ixo/blocksync/index.js +251 -0
- package/dist/lib/ixo/blocksync/index.js.map +1 -0
- package/dist/lib/ixo/blocksync/queries.d.ts +15 -0
- package/dist/lib/ixo/blocksync/queries.d.ts.map +1 -0
- package/dist/lib/ixo/blocksync/queries.js +144 -0
- package/dist/lib/ixo/blocksync/queries.js.map +1 -0
- package/dist/lib/ixo/blocksync/types.d.ts +184 -0
- package/dist/lib/ixo/blocksync/types.d.ts.map +1 -0
- package/dist/lib/ixo/blocksync/types.js +108 -0
- package/dist/lib/ixo/blocksync/types.js.map +1 -0
- package/dist/lib/ixo/cellnode.d.ts +35 -0
- package/dist/lib/ixo/cellnode.d.ts.map +1 -0
- package/dist/lib/ixo/cellnode.js +43 -0
- package/dist/lib/ixo/cellnode.js.map +1 -0
- package/dist/lib/ixo/chain-write.d.ts +130 -0
- package/dist/lib/ixo/chain-write.d.ts.map +1 -0
- package/dist/lib/ixo/chain-write.js +460 -0
- package/dist/lib/ixo/chain-write.js.map +1 -0
- package/dist/lib/ixo/chain.d.ts +1046 -0
- package/dist/lib/ixo/chain.d.ts.map +1 -0
- package/dist/lib/ixo/chain.js +279 -0
- package/dist/lib/ixo/chain.js.map +1 -0
- package/dist/lib/ixo/claim-bot.d.ts +49 -0
- package/dist/lib/ixo/claim-bot.d.ts.map +1 -0
- package/dist/lib/ixo/claim-bot.js +141 -0
- package/dist/lib/ixo/claim-bot.js.map +1 -0
- package/dist/lib/ixo/delegation-verify.d.ts +44 -0
- package/dist/lib/ixo/delegation-verify.d.ts.map +1 -0
- package/dist/lib/ixo/delegation-verify.js +101 -0
- package/dist/lib/ixo/delegation-verify.js.map +1 -0
- package/dist/lib/ixo/did.d.ts +13 -0
- package/dist/lib/ixo/did.d.ts.map +1 -0
- package/dist/lib/ixo/did.js +85 -0
- package/dist/lib/ixo/did.js.map +1 -0
- package/dist/lib/ixo/grant-chain.d.ts +55 -0
- package/dist/lib/ixo/grant-chain.d.ts.map +1 -0
- package/dist/lib/ixo/grant-chain.js +185 -0
- package/dist/lib/ixo/grant-chain.js.map +1 -0
- package/dist/lib/ixo/identity.d.ts +32 -0
- package/dist/lib/ixo/identity.d.ts.map +1 -0
- package/dist/lib/ixo/identity.js +104 -0
- package/dist/lib/ixo/identity.js.map +1 -0
- package/dist/lib/ixo/index.d.ts +118 -0
- package/dist/lib/ixo/index.d.ts.map +1 -0
- package/dist/lib/ixo/index.js +395 -0
- package/dist/lib/ixo/index.js.map +1 -0
- package/dist/lib/ixo/payment.d.ts +104 -0
- package/dist/lib/ixo/payment.d.ts.map +1 -0
- package/dist/lib/ixo/payment.js +136 -0
- package/dist/lib/ixo/payment.js.map +1 -0
- package/dist/lib/ixo/ucan-store.d.ts +30 -0
- package/dist/lib/ixo/ucan-store.d.ts.map +1 -0
- package/dist/lib/ixo/ucan-store.js +134 -0
- package/dist/lib/ixo/ucan-store.js.map +1 -0
- package/dist/lib/ixo/ucan.d.ts +96 -0
- package/dist/lib/ixo/ucan.d.ts.map +1 -0
- package/dist/lib/ixo/ucan.js +216 -0
- package/dist/lib/ixo/ucan.js.map +1 -0
- package/dist/lib/ixo/verified-read.d.ts +43 -0
- package/dist/lib/ixo/verified-read.d.ts.map +1 -0
- package/dist/lib/ixo/verified-read.js +73 -0
- package/dist/lib/ixo/verified-read.js.map +1 -0
- package/dist/lib/ixo/vfs.d.ts +27 -0
- package/dist/lib/ixo/vfs.d.ts.map +1 -0
- package/dist/lib/ixo/vfs.js +42 -0
- package/dist/lib/ixo/vfs.js.map +1 -0
- package/dist/lib/ixo/web-did.d.ts +7 -0
- package/dist/lib/ixo/web-did.d.ts.map +1 -0
- package/dist/lib/ixo/web-did.js +9 -0
- package/dist/lib/ixo/web-did.js.map +1 -0
- package/dist/lib/logger.d.ts +34 -0
- package/dist/lib/logger.d.ts.map +1 -0
- package/dist/lib/logger.js +126 -0
- package/dist/lib/logger.js.map +1 -0
- package/dist/lib/matrix/api.d.ts +57 -0
- package/dist/lib/matrix/api.d.ts.map +1 -0
- package/dist/lib/matrix/api.js +58 -0
- package/dist/lib/matrix/api.js.map +1 -0
- package/dist/lib/matrix/client.d.ts +41 -0
- package/dist/lib/matrix/client.d.ts.map +1 -0
- package/dist/lib/matrix/client.js +104 -0
- package/dist/lib/matrix/client.js.map +1 -0
- package/dist/lib/matrix/deliver.d.ts +224 -0
- package/dist/lib/matrix/deliver.d.ts.map +1 -0
- package/dist/lib/matrix/deliver.js +788 -0
- package/dist/lib/matrix/deliver.js.map +1 -0
- package/dist/lib/matrix/events.d.ts +114 -0
- package/dist/lib/matrix/events.d.ts.map +1 -0
- package/dist/lib/matrix/events.js +143 -0
- package/dist/lib/matrix/events.js.map +1 -0
- package/dist/lib/matrix/mxid.d.ts +24 -0
- package/dist/lib/matrix/mxid.d.ts.map +1 -0
- package/dist/lib/matrix/mxid.js +47 -0
- package/dist/lib/matrix/mxid.js.map +1 -0
- package/dist/lib/metrics.d.ts +105 -0
- package/dist/lib/metrics.d.ts.map +1 -0
- package/dist/lib/metrics.js +204 -0
- package/dist/lib/metrics.js.map +1 -0
- package/dist/lib/oauth/approvals.d.ts +160 -0
- package/dist/lib/oauth/approvals.d.ts.map +1 -0
- package/dist/lib/oauth/approvals.js +273 -0
- package/dist/lib/oauth/approvals.js.map +1 -0
- package/dist/lib/oauth/standing.d.ts +152 -0
- package/dist/lib/oauth/standing.d.ts.map +1 -0
- package/dist/lib/oauth/standing.js +299 -0
- package/dist/lib/oauth/standing.js.map +1 -0
- package/dist/lib/oauth/token.d.ts +60 -0
- package/dist/lib/oauth/token.d.ts.map +1 -0
- package/dist/lib/oauth/token.js +129 -0
- package/dist/lib/oauth/token.js.map +1 -0
- package/dist/lib/payments/extend.d.ts +42 -0
- package/dist/lib/payments/extend.d.ts.map +1 -0
- package/dist/lib/payments/extend.js +98 -0
- package/dist/lib/payments/extend.js.map +1 -0
- package/dist/lib/payments/facilitator.d.ts +220 -0
- package/dist/lib/payments/facilitator.d.ts.map +1 -0
- package/dist/lib/payments/facilitator.js +451 -0
- package/dist/lib/payments/facilitator.js.map +1 -0
- package/dist/lib/payments/gate.d.ts +207 -0
- package/dist/lib/payments/gate.d.ts.map +1 -0
- package/dist/lib/payments/gate.js +481 -0
- package/dist/lib/payments/gate.js.map +1 -0
- package/dist/lib/payments/header-seal.d.ts +33 -0
- package/dist/lib/payments/header-seal.d.ts.map +1 -0
- package/dist/lib/payments/header-seal.js +76 -0
- package/dist/lib/payments/header-seal.js.map +1 -0
- package/dist/lib/payments/index.d.ts +12 -0
- package/dist/lib/payments/index.d.ts.map +1 -0
- package/dist/lib/payments/index.js +11 -0
- package/dist/lib/payments/index.js.map +1 -0
- package/dist/lib/payments/price.d.ts +25 -0
- package/dist/lib/payments/price.d.ts.map +1 -0
- package/dist/lib/payments/price.js +43 -0
- package/dist/lib/payments/price.js.map +1 -0
- package/dist/lib/payments/reconcile.d.ts +77 -0
- package/dist/lib/payments/reconcile.d.ts.map +1 -0
- package/dist/lib/payments/reconcile.js +317 -0
- package/dist/lib/payments/reconcile.js.map +1 -0
- package/dist/lib/payments/refund.d.ts +34 -0
- package/dist/lib/payments/refund.d.ts.map +1 -0
- package/dist/lib/payments/refund.js +123 -0
- package/dist/lib/payments/refund.js.map +1 -0
- package/dist/lib/payments/review-billing.d.ts +222 -0
- package/dist/lib/payments/review-billing.d.ts.map +1 -0
- package/dist/lib/payments/review-billing.js +609 -0
- package/dist/lib/payments/review-billing.js.map +1 -0
- package/dist/lib/payments/settle.d.ts +44 -0
- package/dist/lib/payments/settle.d.ts.map +1 -0
- package/dist/lib/payments/settle.js +306 -0
- package/dist/lib/payments/settle.js.map +1 -0
- package/dist/lib/payments/terms.d.ts +27 -0
- package/dist/lib/payments/terms.d.ts.map +1 -0
- package/dist/lib/payments/terms.js +21 -0
- package/dist/lib/payments/terms.js.map +1 -0
- package/dist/lib/payouts.d.ts +20 -0
- package/dist/lib/payouts.d.ts.map +1 -0
- package/dist/lib/payouts.js +30 -0
- package/dist/lib/payouts.js.map +1 -0
- package/dist/lib/readiness.d.ts +42 -0
- package/dist/lib/readiness.d.ts.map +1 -0
- package/dist/lib/readiness.js +130 -0
- package/dist/lib/readiness.js.map +1 -0
- package/dist/lib/redact.d.ts +23 -0
- package/dist/lib/redact.d.ts.map +1 -0
- package/dist/lib/redact.js +67 -0
- package/dist/lib/redact.js.map +1 -0
- package/dist/lib/register.d.ts +85 -0
- package/dist/lib/register.d.ts.map +1 -0
- package/dist/lib/register.js +390 -0
- package/dist/lib/register.js.map +1 -0
- package/dist/lib/review/attestation.d.ts +92 -0
- package/dist/lib/review/attestation.d.ts.map +1 -0
- package/dist/lib/review/attestation.js +264 -0
- package/dist/lib/review/attestation.js.map +1 -0
- package/dist/lib/review/reviewer-grant.d.ts +146 -0
- package/dist/lib/review/reviewer-grant.d.ts.map +1 -0
- package/dist/lib/review/reviewer-grant.js +359 -0
- package/dist/lib/review/reviewer-grant.js.map +1 -0
- package/dist/lib/review/tasks.d.ts +18 -0
- package/dist/lib/review/tasks.d.ts.map +1 -0
- package/dist/lib/review/tasks.js +36 -0
- package/dist/lib/review/tasks.js.map +1 -0
- package/dist/lib/sentry.d.ts +89 -0
- package/dist/lib/sentry.d.ts.map +1 -0
- package/dist/lib/sentry.js +284 -0
- package/dist/lib/sentry.js.map +1 -0
- package/dist/lib/spans.d.ts +14 -0
- package/dist/lib/spans.d.ts.map +1 -0
- package/dist/lib/spans.js +28 -0
- package/dist/lib/spans.js.map +1 -0
- package/dist/lib/tracing.d.ts +31 -0
- package/dist/lib/tracing.d.ts.map +1 -0
- package/dist/lib/tracing.js +66 -0
- package/dist/lib/tracing.js.map +1 -0
- package/dist/lib/ttl-cache.d.ts +26 -0
- package/dist/lib/ttl-cache.d.ts.map +1 -0
- package/dist/lib/ttl-cache.js +61 -0
- package/dist/lib/ttl-cache.js.map +1 -0
- package/dist/lib/validator.d.ts +19 -0
- package/dist/lib/validator.d.ts.map +1 -0
- package/dist/lib/validator.js +32 -0
- package/dist/lib/validator.js.map +1 -0
- package/dist/lib/work-order/form.d.ts +40 -0
- package/dist/lib/work-order/form.d.ts.map +1 -0
- package/dist/lib/work-order/form.js +316 -0
- package/dist/lib/work-order/form.js.map +1 -0
- package/dist/lib/work-order/index.d.ts +20 -0
- package/dist/lib/work-order/index.d.ts.map +1 -0
- package/dist/lib/work-order/index.js +66 -0
- package/dist/lib/work-order/index.js.map +1 -0
- package/dist/middleware/api/audit.d.ts +9 -0
- package/dist/middleware/api/audit.d.ts.map +1 -0
- package/dist/middleware/api/audit.js +38 -0
- package/dist/middleware/api/audit.js.map +1 -0
- package/dist/middleware/api/auth.d.ts +29 -0
- package/dist/middleware/api/auth.d.ts.map +1 -0
- package/dist/middleware/api/auth.js +105 -0
- package/dist/middleware/api/auth.js.map +1 -0
- package/dist/middleware/api/console.d.ts +92 -0
- package/dist/middleware/api/console.d.ts.map +1 -0
- package/dist/middleware/api/console.js +446 -0
- package/dist/middleware/api/console.js.map +1 -0
- package/dist/middleware/api/errors.d.ts +48 -0
- package/dist/middleware/api/errors.d.ts.map +1 -0
- package/dist/middleware/api/errors.js +133 -0
- package/dist/middleware/api/errors.js.map +1 -0
- package/dist/middleware/api/idempotency.d.ts +23 -0
- package/dist/middleware/api/idempotency.d.ts.map +1 -0
- package/dist/middleware/api/idempotency.js +158 -0
- package/dist/middleware/api/idempotency.js.map +1 -0
- package/dist/middleware/api/keys.d.ts +14 -0
- package/dist/middleware/api/keys.d.ts.map +1 -0
- package/dist/middleware/api/keys.js +66 -0
- package/dist/middleware/api/keys.js.map +1 -0
- package/dist/middleware/api/membership.d.ts +32 -0
- package/dist/middleware/api/membership.d.ts.map +1 -0
- package/dist/middleware/api/membership.js +48 -0
- package/dist/middleware/api/membership.js.map +1 -0
- package/dist/middleware/api/oauth.d.ts +28 -0
- package/dist/middleware/api/oauth.d.ts.map +1 -0
- package/dist/middleware/api/oauth.js +109 -0
- package/dist/middleware/api/oauth.js.map +1 -0
- package/dist/middleware/api/rate-limit.d.ts +23 -0
- package/dist/middleware/api/rate-limit.d.ts.map +1 -0
- package/dist/middleware/api/rate-limit.js +70 -0
- package/dist/middleware/api/rate-limit.js.map +1 -0
- package/dist/middleware/api/types.d.ts +92 -0
- package/dist/middleware/api/types.d.ts.map +1 -0
- package/dist/middleware/api/types.js +7 -0
- package/dist/middleware/api/types.js.map +1 -0
- package/dist/middleware/api/wait.d.ts +21 -0
- package/dist/middleware/api/wait.d.ts.map +1 -0
- package/dist/middleware/api/wait.js +85 -0
- package/dist/middleware/api/wait.js.map +1 -0
- package/dist/middleware/capability.d.ts +32 -0
- package/dist/middleware/capability.d.ts.map +1 -0
- package/dist/middleware/capability.js +113 -0
- package/dist/middleware/capability.js.map +1 -0
- package/dist/middleware/database.d.ts +14 -0
- package/dist/middleware/database.d.ts.map +1 -0
- package/dist/middleware/database.js +18 -0
- package/dist/middleware/database.js.map +1 -0
- package/dist/middleware/error-handler.d.ts +13 -0
- package/dist/middleware/error-handler.d.ts.map +1 -0
- package/dist/middleware/error-handler.js +127 -0
- package/dist/middleware/error-handler.js.map +1 -0
- package/dist/middleware/observability.d.ts +32 -0
- package/dist/middleware/observability.d.ts.map +1 -0
- package/dist/middleware/observability.js +134 -0
- package/dist/middleware/observability.js.map +1 -0
- package/dist/middleware/rate-limit.d.ts +16 -0
- package/dist/middleware/rate-limit.d.ts.map +1 -0
- package/dist/middleware/rate-limit.js +56 -0
- package/dist/middleware/rate-limit.js.map +1 -0
- package/dist/middleware/ucan-auth.d.ts +39 -0
- package/dist/middleware/ucan-auth.d.ts.map +1 -0
- package/dist/middleware/ucan-auth.js +278 -0
- package/dist/middleware/ucan-auth.js.map +1 -0
- package/dist/networks.d.ts +34 -0
- package/dist/networks.d.ts.map +1 -0
- package/dist/networks.js +49 -0
- package/dist/networks.js.map +1 -0
- package/dist/oracle.d.ts +193 -0
- package/dist/oracle.d.ts.map +1 -0
- package/dist/oracle.js +245 -0
- package/dist/oracle.js.map +1 -0
- package/dist/routes/health.d.ts +16 -0
- package/dist/routes/health.d.ts.map +1 -0
- package/dist/routes/health.js +29 -0
- package/dist/routes/health.js.map +1 -0
- package/dist/routes/v1/admin.d.ts +18 -0
- package/dist/routes/v1/admin.d.ts.map +1 -0
- package/dist/routes/v1/admin.js +101 -0
- package/dist/routes/v1/admin.js.map +1 -0
- package/dist/routes/v1/api/admin-claims.d.ts +14 -0
- package/dist/routes/v1/api/admin-claims.d.ts.map +1 -0
- package/dist/routes/v1/api/admin-claims.js +82 -0
- package/dist/routes/v1/api/admin-claims.js.map +1 -0
- package/dist/routes/v1/api/admin-facilitator.d.ts +20 -0
- package/dist/routes/v1/api/admin-facilitator.d.ts.map +1 -0
- package/dist/routes/v1/api/admin-facilitator.js +64 -0
- package/dist/routes/v1/api/admin-facilitator.js.map +1 -0
- package/dist/routes/v1/api/admin.d.ts +9 -0
- package/dist/routes/v1/api/admin.d.ts.map +1 -0
- package/dist/routes/v1/api/admin.js +110 -0
- package/dist/routes/v1/api/admin.js.map +1 -0
- package/dist/routes/v1/api/audit.d.ts +8 -0
- package/dist/routes/v1/api/audit.d.ts.map +1 -0
- package/dist/routes/v1/api/audit.js +56 -0
- package/dist/routes/v1/api/audit.js.map +1 -0
- package/dist/routes/v1/api/batch.d.ts +17 -0
- package/dist/routes/v1/api/batch.d.ts.map +1 -0
- package/dist/routes/v1/api/batch.js +192 -0
- package/dist/routes/v1/api/batch.js.map +1 -0
- package/dist/routes/v1/api/claims-read.d.ts +43 -0
- package/dist/routes/v1/api/claims-read.d.ts.map +1 -0
- package/dist/routes/v1/api/claims-read.js +123 -0
- package/dist/routes/v1/api/claims-read.js.map +1 -0
- package/dist/routes/v1/api/claims.d.ts +131 -0
- package/dist/routes/v1/api/claims.d.ts.map +1 -0
- package/dist/routes/v1/api/claims.js +407 -0
- package/dist/routes/v1/api/claims.js.map +1 -0
- package/dist/routes/v1/api/collections-link.d.ts +14 -0
- package/dist/routes/v1/api/collections-link.d.ts.map +1 -0
- package/dist/routes/v1/api/collections-link.js +97 -0
- package/dist/routes/v1/api/collections-link.js.map +1 -0
- package/dist/routes/v1/api/export.d.ts +48 -0
- package/dist/routes/v1/api/export.d.ts.map +1 -0
- package/dist/routes/v1/api/export.js +251 -0
- package/dist/routes/v1/api/export.js.map +1 -0
- package/dist/routes/v1/api/index.d.ts +16 -0
- package/dist/routes/v1/api/index.d.ts.map +1 -0
- package/dist/routes/v1/api/index.js +68 -0
- package/dist/routes/v1/api/index.js.map +1 -0
- package/dist/routes/v1/api/keys.d.ts +9 -0
- package/dist/routes/v1/api/keys.d.ts.map +1 -0
- package/dist/routes/v1/api/keys.js +95 -0
- package/dist/routes/v1/api/keys.js.map +1 -0
- package/dist/routes/v1/api/me.d.ts +21 -0
- package/dist/routes/v1/api/me.d.ts.map +1 -0
- package/dist/routes/v1/api/me.js +122 -0
- package/dist/routes/v1/api/me.js.map +1 -0
- package/dist/routes/v1/api/members.d.ts +17 -0
- package/dist/routes/v1/api/members.d.ts.map +1 -0
- package/dist/routes/v1/api/members.js +406 -0
- package/dist/routes/v1/api/members.js.map +1 -0
- package/dist/routes/v1/api/meta.d.ts +12 -0
- package/dist/routes/v1/api/meta.d.ts.map +1 -0
- package/dist/routes/v1/api/meta.js +59 -0
- package/dist/routes/v1/api/meta.js.map +1 -0
- package/dist/routes/v1/api/openapi.gen.d.ts +2 -0
- package/dist/routes/v1/api/openapi.gen.d.ts.map +1 -0
- package/dist/routes/v1/api/openapi.gen.js +7 -0
- package/dist/routes/v1/api/openapi.gen.js.map +1 -0
- package/dist/routes/v1/api/protocols.d.ts +22 -0
- package/dist/routes/v1/api/protocols.d.ts.map +1 -0
- package/dist/routes/v1/api/protocols.js +153 -0
- package/dist/routes/v1/api/protocols.js.map +1 -0
- package/dist/routes/v1/api/review-billing.d.ts +18 -0
- package/dist/routes/v1/api/review-billing.d.ts.map +1 -0
- package/dist/routes/v1/api/review-billing.js +196 -0
- package/dist/routes/v1/api/review-billing.js.map +1 -0
- package/dist/routes/v1/api/review.d.ts +30 -0
- package/dist/routes/v1/api/review.d.ts.map +1 -0
- package/dist/routes/v1/api/review.js +302 -0
- package/dist/routes/v1/api/review.js.map +1 -0
- package/dist/routes/v1/api/sources.d.ts +10 -0
- package/dist/routes/v1/api/sources.d.ts.map +1 -0
- package/dist/routes/v1/api/sources.js +293 -0
- package/dist/routes/v1/api/sources.js.map +1 -0
- package/dist/routes/v1/api/uploads.d.ts +37 -0
- package/dist/routes/v1/api/uploads.d.ts.map +1 -0
- package/dist/routes/v1/api/uploads.js +414 -0
- package/dist/routes/v1/api/uploads.js.map +1 -0
- package/dist/routes/v1/api/views.d.ts +18 -0
- package/dist/routes/v1/api/views.d.ts.map +1 -0
- package/dist/routes/v1/api/views.js +95 -0
- package/dist/routes/v1/api/views.js.map +1 -0
- package/dist/routes/v1/api/webhooks.d.ts +14 -0
- package/dist/routes/v1/api/webhooks.d.ts.map +1 -0
- package/dist/routes/v1/api/webhooks.js +282 -0
- package/dist/routes/v1/api/webhooks.js.map +1 -0
- package/dist/routes/v1/api/work-orders.d.ts +45 -0
- package/dist/routes/v1/api/work-orders.d.ts.map +1 -0
- package/dist/routes/v1/api/work-orders.js +171 -0
- package/dist/routes/v1/api/work-orders.js.map +1 -0
- package/dist/routes/v1/claims.d.ts +21 -0
- package/dist/routes/v1/claims.d.ts.map +1 -0
- package/dist/routes/v1/claims.js +153 -0
- package/dist/routes/v1/claims.js.map +1 -0
- package/dist/routes/v1/collections.d.ts +45 -0
- package/dist/routes/v1/collections.d.ts.map +1 -0
- package/dist/routes/v1/collections.js +201 -0
- package/dist/routes/v1/collections.js.map +1 -0
- package/dist/routes/v1/index.d.ts +13 -0
- package/dist/routes/v1/index.d.ts.map +1 -0
- package/dist/routes/v1/index.js +41 -0
- package/dist/routes/v1/index.js.map +1 -0
- package/dist/routes/v1/info.d.ts +14 -0
- package/dist/routes/v1/info.d.ts.map +1 -0
- package/dist/routes/v1/info.js +75 -0
- package/dist/routes/v1/info.js.map +1 -0
- package/dist/routes/v1/mcp/index.d.ts +33 -0
- package/dist/routes/v1/mcp/index.d.ts.map +1 -0
- package/dist/routes/v1/mcp/index.js +252 -0
- package/dist/routes/v1/mcp/index.js.map +1 -0
- package/dist/routes/v1/mcp/oauth.d.ts +27 -0
- package/dist/routes/v1/mcp/oauth.d.ts.map +1 -0
- package/dist/routes/v1/mcp/oauth.js +500 -0
- package/dist/routes/v1/mcp/oauth.js.map +1 -0
- package/dist/routes/v1/mcp/tools.d.ts +71 -0
- package/dist/routes/v1/mcp/tools.d.ts.map +1 -0
- package/dist/routes/v1/mcp/tools.js +432 -0
- package/dist/routes/v1/mcp/tools.js.map +1 -0
- package/dist/routes/v1/mcp/ui.d.ts +45 -0
- package/dist/routes/v1/mcp/ui.d.ts.map +1 -0
- package/dist/routes/v1/mcp/ui.js +454 -0
- package/dist/routes/v1/mcp/ui.js.map +1 -0
- package/dist/routes/v1/oauth.d.ts +29 -0
- package/dist/routes/v1/oauth.d.ts.map +1 -0
- package/dist/routes/v1/oauth.js +256 -0
- package/dist/routes/v1/oauth.js.map +1 -0
- package/dist/routes/v1/reviewers.d.ts +22 -0
- package/dist/routes/v1/reviewers.d.ts.map +1 -0
- package/dist/routes/v1/reviewers.js +165 -0
- package/dist/routes/v1/reviewers.js.map +1 -0
- package/dist/routes/v1/reviews.d.ts +38 -0
- package/dist/routes/v1/reviews.d.ts.map +1 -0
- package/dist/routes/v1/reviews.js +234 -0
- package/dist/routes/v1/reviews.js.map +1 -0
- package/dist/routes/v1/shared.d.ts +586 -0
- package/dist/routes/v1/shared.d.ts.map +1 -0
- package/dist/routes/v1/shared.js +229 -0
- package/dist/routes/v1/shared.js.map +1 -0
- package/dist/routes/well-known.d.ts +15 -0
- package/dist/routes/well-known.d.ts.map +1 -0
- package/dist/routes/well-known.js +35 -0
- package/dist/routes/well-known.js.map +1 -0
- package/dist/runtime.d.ts +100 -0
- package/dist/runtime.d.ts.map +1 -0
- package/dist/runtime.js +144 -0
- package/dist/runtime.js.map +1 -0
- package/dist/testing/fake-tools.d.ts +104 -0
- package/dist/testing/fake-tools.d.ts.map +1 -0
- package/dist/testing/fake-tools.js +213 -0
- package/dist/testing/fake-tools.js.map +1 -0
- package/dist/testing/index.d.ts +54 -0
- package/dist/testing/index.d.ts.map +1 -0
- package/dist/testing/index.js +104 -0
- package/dist/testing/index.js.map +1 -0
- package/dist/testing/samples.d.ts +70 -0
- package/dist/testing/samples.d.ts.map +1 -0
- package/dist/testing/samples.js +92 -0
- package/dist/testing/samples.js.map +1 -0
- package/dist/workflows/claim-ingest.d.ts +250 -0
- package/dist/workflows/claim-ingest.d.ts.map +1 -0
- package/dist/workflows/claim-ingest.js +1020 -0
- package/dist/workflows/claim-ingest.js.map +1 -0
- package/dist/workflows/claim-source.d.ts +25 -0
- package/dist/workflows/claim-source.d.ts.map +1 -0
- package/dist/workflows/claim-source.js +107 -0
- package/dist/workflows/claim-source.js.map +1 -0
- package/dist/workflows/review-complete.d.ts +82 -0
- package/dist/workflows/review-complete.d.ts.map +1 -0
- package/dist/workflows/review-complete.js +455 -0
- package/dist/workflows/review-complete.js.map +1 -0
- package/dist/workflows/steps.d.ts +125 -0
- package/dist/workflows/steps.d.ts.map +1 -0
- package/dist/workflows/steps.js +325 -0
- package/dist/workflows/steps.js.map +1 -0
- package/docs/api.md +2595 -0
- package/docs/guide.md +1525 -0
- package/migrations/0000_init.sql +108 -0
- package/migrations/0001_review_attestation.sql +1 -0
- package/migrations/0002_decisions_facts.sql +1 -0
- package/migrations/0003_api_lane.sql +171 -0
- package/migrations/0004_api_v1_1.sql +19 -0
- package/migrations/0005_member_notify.sql +3 -0
- package/migrations/0006_source_collections.sql +16 -0
- package/migrations/0007_api_settlement.sql +27 -0
- package/migrations/0008_review_extend.sql +1 -0
- package/migrations/0009_card_refunds.sql +4 -0
- package/migrations/0010_even_scorpion.sql +16 -0
- package/migrations/0011_mcp_oauth.sql +27 -0
- package/migrations/0012_mcp_standing.sql +21 -0
- package/migrations/0013_unknown_krista_starr.sql +2 -0
- package/migrations/0014_last_carnage.sql +14 -0
- package/migrations/0015_company_authority.sql +26 -0
- package/migrations/0016_owner_only_links.sql +6 -0
- package/migrations/0017_organisations.sql +35 -0
- package/migrations/0018_remove_app_signed.sql +4 -0
- package/migrations/0019_submitted_via.sql +2 -0
- package/migrations/0020_drop_decision_to_pay.sql +4 -0
- package/migrations/0021_manual_erase.sql +25 -0
- package/migrations/0022_errored_facts.sql +1 -0
- package/migrations/0023_review_billing.sql +20 -0
- package/migrations/0024_pending_task_details.sql +1 -0
- package/migrations/meta/0000_snapshot.json +707 -0
- package/migrations/meta/0001_snapshot.json +714 -0
- package/migrations/meta/0002_snapshot.json +721 -0
- package/migrations/meta/0003_snapshot.json +1845 -0
- package/migrations/meta/0004_snapshot.json +1969 -0
- package/migrations/meta/0005_snapshot.json +1991 -0
- package/migrations/meta/0006_snapshot.json +2097 -0
- package/migrations/meta/0007_snapshot.json +2128 -0
- package/migrations/meta/0008_snapshot.json +2133 -0
- package/migrations/meta/0009_snapshot.json +2161 -0
- package/migrations/meta/0010_snapshot.json +2265 -0
- package/migrations/meta/0011_snapshot.json +2448 -0
- package/migrations/meta/0012_snapshot.json +2577 -0
- package/migrations/meta/0013_snapshot.json +2594 -0
- package/migrations/meta/0014_snapshot.json +2602 -0
- package/migrations/meta/0015_snapshot.json +2778 -0
- package/migrations/meta/0016_snapshot.json +2778 -0
- package/migrations/meta/0017_snapshot.json +2792 -0
- package/migrations/meta/0018_snapshot.json +2778 -0
- package/migrations/meta/0019_snapshot.json +2792 -0
- package/migrations/meta/0020_snapshot.json +2785 -0
- package/migrations/meta/0021_snapshot.json +2762 -0
- package/migrations/meta/0022_snapshot.json +2769 -0
- package/migrations/meta/0023_snapshot.json +2900 -0
- package/migrations/meta/0024_snapshot.json +2907 -0
- package/migrations/meta/_journal.json +181 -0
- package/openapi/decision-api.yaml +12204 -0
- package/package.json +123 -4
- package/skills/README.md +19 -0
- package/skills/add-openhands-support/SKILL.md +113 -0
- package/skills/create-collection/SKILL.md +199 -0
- package/skills/create-collection/reference/claims-stack.md +106 -0
- package/skills/create-collection/reference/collection.md +111 -0
- package/skills/create-oracle/SKILL.md +400 -0
- package/skills/create-rubric/SKILL.md +130 -0
- package/skills/create-rubric/reference/format-cheatsheet.md +186 -0
- package/skills/create-rubric/templates/claim-form.example.json +60 -0
- package/skills/decision-api-client/SKILL.md +236 -0
- package/skills/decision-api-oracle/SKILL.md +336 -0
- package/skills/publish-protocol/SKILL.md +151 -0
- package/skills/publish-protocol/reference/publishing.md +116 -0
- package/skills/reference/engine-contract.md +222 -0
- package/skills/write-facts/SKILL.md +221 -0
- package/skills/write-facts/reference/examples/http-vendor.ts +88 -0
- package/skills/write-facts/reference/examples/price-matches-agreement.ts +67 -0
- package/skills/write-facts/reference/facts-api.md +232 -0
- package/templates/project/.dev.vars.example +93 -0
- package/templates/project/.editorconfig +9 -0
- package/templates/project/CLAUDE.md +45 -0
- package/templates/project/README.md +199 -0
- package/templates/project/biome.json +37 -0
- package/templates/project/gitignore +29 -0
- package/templates/project/package.json +32 -0
- package/templates/project/src/facts/index.ts +19 -0
- package/templates/project/src/index.ts +25 -0
- package/templates/project/test/api-lane.test.ts +57 -0
- package/templates/project/test/facts.test.ts +14 -0
- package/templates/project/tsconfig.json +25 -0
- package/templates/project/vitest.config.ts +13 -0
- package/templates/project/wrangler.jsonc +446 -0
|
@@ -0,0 +1,1020 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Durable, idempotent claim ingestion (README "How a claim flows" steps 3–6). One instance per claim — the
|
|
3
|
+
* instance id is the claimId itself when Cloudflare accepts it, else its sha256 (see lib/ids.ts) —
|
|
4
|
+
* each step checkpointed and auto-retried, so a crash/redeploy/transient failure never re-does
|
|
5
|
+
* work or drops a claim.
|
|
6
|
+
*
|
|
7
|
+
* THE WORKFLOW OWNS ITS LEDGER ROW — one writer, whole lifecycle:
|
|
8
|
+
* step "record-queued" → upsert the `claim_ingests` row as `queued` (durable: the row exists
|
|
9
|
+
* iff the instance started, so nothing can ever strand a row)
|
|
10
|
+
* step "evaluate" → mark the row `processing` (so a later attempt knows one ran), then
|
|
11
|
+
* ONE pull (chain metadata + body + attachment descriptors), the facts
|
|
12
|
+
* lane over the same in-memory claim (`buildFacts`: read the engine's
|
|
13
|
+
* rubric manifest, run the producer, freeze the FactSet), and `POST /v1/decisions` on
|
|
14
|
+
* the eval engine with that FactSet and the claim's content (the
|
|
15
|
+
* pull's `claimContent`: a chain claim's CID-verified bytes, an API
|
|
16
|
+
* claim's stored content) → one `decisions` row
|
|
17
|
+
* (`onConflictDoNothing` — decided once, matching the engine's own
|
|
18
|
+
* evaluated-once mutex). ONE step on purpose, exactly as the engine
|
|
19
|
+
* folded its pull into `evaluate`: the
|
|
20
|
+
* claim body and the FactSet — which CONTAINS the answers — may never
|
|
21
|
+
* be a step result, so pull → facts → decide has to live and die
|
|
22
|
+
* inside one step; only the small decision summary leaves it. A claim
|
|
23
|
+
* the facts lane cannot build for (a rubric the engine's manifest cannot
|
|
24
|
+
* bind, facts that don't match the rubric's work order) gets its row
|
|
25
|
+
* WITHOUT a decide call — nothing to decide, nothing charged
|
|
26
|
+
* step "act" → act on a terminal verdict (chain-write under the AUTO_SIGN policy;
|
|
27
|
+
* workflows/steps.ts). Fail-soft: a delivery failure NEVER fails the
|
|
28
|
+
* ingest — the decision is recorded, and an operator rerun re-enters
|
|
29
|
+
* delivery idempotently. A `pending_review` decision waits for the
|
|
30
|
+
* review lane (routes/v1/reviews.ts → ReviewComplete) to act instead
|
|
31
|
+
* step "mark-processed" → row → `processed`
|
|
32
|
+
* terminal catch → row → `failed` (+ the message), instance shows Errored in the dashboard
|
|
33
|
+
* The cron (cron/) only discovers claims and creates instances; it never writes this table.
|
|
34
|
+
*
|
|
35
|
+
* The engine's answers that are not "here is the decision" (docs/ENGINE-CONTRACT.md "Errors")
|
|
36
|
+
* are routed, not retried blindly: not hired for the collection ⇒ pause it and stop; credits
|
|
37
|
+
* exhausted ⇒ pause EVERY watched collection, alert, and keep retrying this claim (cheap — the
|
|
38
|
+
* engine returns the stored row once decided); a rubric pin the chain has since re-anchored ⇒
|
|
39
|
+
* invalidate the cached manifest, re-read and rebuild once; a facts shape the engine refuses ⇒
|
|
40
|
+
* our producer's bug, fail loudly. And the "no" that is not an error: an UNUSABLE rubric — said
|
|
41
|
+
* by the engine's manifest before a producer runs (`rubric-unusable` from the builder: no `#rub`,
|
|
42
|
+
* swapped bytes, a drifted `#vct`, an unbindable ref), or by `decision.status = "unusable"` at
|
|
43
|
+
* decide time (fact coverage; the oracle never pre-binds, the engine's
|
|
44
|
+
* binder is the only validator of rubric ⇄ form ⇄ facts). Both are recorded (the engine's with its
|
|
45
|
+
* receipt) AND pause the collection: every claim of it would be refused the same way, so a broken
|
|
46
|
+
* catalog entry is paid for once — or, from the manifest, not at all. `POST
|
|
47
|
+
* /v1/collections/:id/resume` lifts it once `#rub`/`#vct` are fixed.
|
|
48
|
+
*
|
|
49
|
+
* Replay safety: a step's checkpointed result is returned verbatim on replay and the body of a
|
|
50
|
+
* completed step never re-runs, so a step may only depend on its own inputs, the DB, and the small
|
|
51
|
+
* results of earlier steps — never on in-memory state another step built. A retry that re-enters
|
|
52
|
+
* `evaluate` after its row landed reads the row and returns: no second pull, no second connector
|
|
53
|
+
* run (AI charges), no second ask. A retry that re-enters in the window BETWEEN the engine
|
|
54
|
+
* deciding and that row landing finds the row marked `processing` and asks `GET
|
|
55
|
+
* /v1/decisions/:claimId` first (docs/ENGINE-CONTRACT.md "Auth + preconditions"): decided-once on
|
|
56
|
+
* the engine plus one extra read on retry ⇒ the producer never runs twice for one claim, and no
|
|
57
|
+
* claim is stranded. A first attempt never pays that read.
|
|
58
|
+
*
|
|
59
|
+
* Self-contained BY DESIGN so operator recovery is just the dashboard: RERUN an errored instance
|
|
60
|
+
* (params are retained) and the ledger converges. Hand-creating a new instance also works with the
|
|
61
|
+
* claim CID as the id and no params (the id doubles as the claimId; the collection is resolved
|
|
62
|
+
* on-chain); only hash-mapped claims (rare non-CID ids) need `{"claimId": "…"}` as params.
|
|
63
|
+
*
|
|
64
|
+
* Two front doors, one workflow (Go Prod §7.1): `params.lane` picks the `ClaimSource`
|
|
65
|
+
* (workflows/claim-source.ts) — `chain` (absent: the cron's claims) or `api` (`startApiClaims`,
|
|
66
|
+
* whose body lives in D1 and whose decision is never acted on). The steps are the same for both.
|
|
67
|
+
*
|
|
68
|
+
* On the chain lane the claim body and attachment bytes are NOT persisted in D1 — attachments are Matrix CID
|
|
69
|
+
* references, and the `decisions` row stores only the engine's answer plus the FactSet digest. The
|
|
70
|
+
* one copy is the operator's opt-in answer archive (`ANSWERS_ARCHIVE`, lib/archive.ts), written to
|
|
71
|
+
* R2 from inside `evaluate` and never a step result.
|
|
72
|
+
*
|
|
73
|
+
* Per-review billing (IXO's plan for the oracle, payments/review-billing.ts): a chain claim of a
|
|
74
|
+
* collection registered with a paying source (`billingSourceId`) is never decided without a
|
|
75
|
+
* reservation. Inside `evaluate`, before the pull: a claim id the facilitator cannot key (not a
|
|
76
|
+
* base32 CIDv1) is recorded `skipped` (`unbillable-claim-id`) — no offer, no decide, no chain
|
|
77
|
+
* write, no pause — and who pays is resolved fresh (no usable delegation ⇒ pause
|
|
78
|
+
* `payer-delegation`). AFTER the facts lane built — so a facts-lane `unusable` / `invalid_facts`
|
|
79
|
+
* never spends the delegation's cap — the price is reserved (offer → verify); a refusal for want of
|
|
80
|
+
* credits pauses `payer-credits`. While a payer pause stands, a retry stops before the pull, like
|
|
81
|
+
* `engine-credits`. The decision settles on its receipt (an engine `unusable` included), a
|
|
82
|
+
* `pending_review` extends its hold, and a reserved claim that will never get a receipt (a rebuild
|
|
83
|
+
* that failed, an engine refusal, a run that gave up) is released.
|
|
84
|
+
*/
|
|
85
|
+
import { WorkflowEntrypoint } from "cloudflare:workers";
|
|
86
|
+
import { NonRetryableError } from "cloudflare:workflows";
|
|
87
|
+
import * as Sentry from "@sentry/cloudflare";
|
|
88
|
+
import { and, eq, isNull } from "drizzle-orm";
|
|
89
|
+
import { getDb } from "../db/client.js";
|
|
90
|
+
import { apiCharges, apiClaims, claimIngests, decisions, watchedCollections, } from "../db/schema.js";
|
|
91
|
+
import { claimErrorCode, FAILURE } from "../lib/api-lane/record.js";
|
|
92
|
+
import { archiveAnswer } from "../lib/archive.js";
|
|
93
|
+
import { createEngineClient } from "../lib/engine/client.js";
|
|
94
|
+
import { EngineError, isManifestUnusable, } from "../lib/engine/types.js";
|
|
95
|
+
import { AppError } from "../lib/errors.js";
|
|
96
|
+
import { buildFacts, factDeps } from "../lib/facts/builder.js";
|
|
97
|
+
import { factCacheDelete } from "../lib/facts/fact-cache.js";
|
|
98
|
+
import { factsDigest } from "../lib/facts/factset.js";
|
|
99
|
+
import { finalVerdictUpdate, registryVerdictToken, voidUndecidedUpdate, } from "../lib/facts/stock/unique-store.js";
|
|
100
|
+
import { depsFromEnv } from "../lib/ixo/index.js";
|
|
101
|
+
import { getClaimById } from "../lib/ixo/blocksync/index.js";
|
|
102
|
+
import { peerCode, scopedStep, withMetrics } from "../lib/metrics.js";
|
|
103
|
+
import { extendForReview } from "../lib/payments/extend.js";
|
|
104
|
+
import { BILLING_PAUSES, CHAIN_CLAIM_ID, companyOf, planAllowsReviewBilling, releaseChainClaim, reserveChainClaim, resolvePayer, } from "../lib/payments/review-billing.js";
|
|
105
|
+
import { settleClaim } from "../lib/payments/settle.js";
|
|
106
|
+
import { payoutRequestFor } from "../lib/payouts.js";
|
|
107
|
+
import { reportAlert, reportError } from "../lib/sentry.js";
|
|
108
|
+
import { getOracle } from "../oracle.js";
|
|
109
|
+
import { isChain, sourceFor } from "./claim-source.js";
|
|
110
|
+
import { actStep, erroredFactsOf, pauseCollection, pauseForEngineCredits, pauseUnusable, RECEIPT_MISSING, reasonOf, requireReceipt, stepError, } from "./steps.js";
|
|
111
|
+
// Light garbage guard for manually-created instances, NOT a format check: real chain claimIds are
|
|
112
|
+
// CIDs *and* Matrix event ids (`$…`), so anything printable-ASCII of sane length is acceptable —
|
|
113
|
+
// the chain lookup is the actual validation (unknown id → fail-closed 404).
|
|
114
|
+
const CLAIM_ID_RE = /^[\x21-\x7e]{1,512}$/;
|
|
115
|
+
/**
|
|
116
|
+
* How a review-billing trouble is told apart in the ledger's `error` (a run that gave up while its
|
|
117
|
+
* collection was paused for payment): the resume cron restarts exactly those.
|
|
118
|
+
*/
|
|
119
|
+
export const PAYER_BILLING = "payer-billing:";
|
|
120
|
+
/** `evaluate`'s result for a claim a per-review collection cannot bill (see the header). */
|
|
121
|
+
const UNBILLABLE = "unbillable";
|
|
122
|
+
const isBillingPause = (reason) => BILLING_PAUSES.includes(reason ?? "");
|
|
123
|
+
/** The facts lane's deterministic negatives → the `decisions.status` they are recorded as (schema.ts). */
|
|
124
|
+
const BUILD_FAILURE_STATUS = {
|
|
125
|
+
"rubric-unusable": "unusable",
|
|
126
|
+
"invalid-facts": "invalid_facts",
|
|
127
|
+
};
|
|
128
|
+
/** The engine's refusals of the claim's content → the `decisions.status` they are recorded as. */
|
|
129
|
+
const CONTENT_REFUSAL_STATUS = {
|
|
130
|
+
CONTENT_MISMATCH: "content_mismatch",
|
|
131
|
+
PAYLOAD_TOO_LARGE: "payload_too_large",
|
|
132
|
+
};
|
|
133
|
+
/**
|
|
134
|
+
* `403 NO_EVALUATE_GRANT` is retry-ONCE (docs/ENGINE-CONTRACT.md): the grant may have landed on
|
|
135
|
+
* chain seconds ago — the portal grants and registers in one flow — so wait about a block and ask
|
|
136
|
+
* again before calling it a real "not hired". In-step on purpose: the FactSet may not leave the
|
|
137
|
+
* step, so a step-level sleep would cost a full rebuild (connectors, AI charges). An object so a
|
|
138
|
+
* test can shorten it.
|
|
139
|
+
*/
|
|
140
|
+
export const GRANT_RETRY_DELAY = { ms: 30_000 };
|
|
141
|
+
/** The evaluate step's retries (below) — its last attempt is the one that freezes outages (P0-7). */
|
|
142
|
+
const EVALUATE_RETRY_LIMIT = 8;
|
|
143
|
+
const resultOf = (row) => ({
|
|
144
|
+
status: row.status,
|
|
145
|
+
verdict: row.verdict,
|
|
146
|
+
resultDigest: row.resultDigest,
|
|
147
|
+
receiptCid: row.receiptCid,
|
|
148
|
+
});
|
|
149
|
+
export class ClaimIngest extends WorkflowEntrypoint {
|
|
150
|
+
async run(event, step) {
|
|
151
|
+
// Params may be absent when an operator hand-creates an instance whose id IS a claim CID; for
|
|
152
|
+
// hash-mapped ids params are required (see header).
|
|
153
|
+
const claimId = event.payload?.claimId ?? event.instanceId;
|
|
154
|
+
if (!CLAIM_ID_RE.test(claimId)) {
|
|
155
|
+
throw new NonRetryableError(`Invalid claimId ${JSON.stringify(claimId)}`);
|
|
156
|
+
}
|
|
157
|
+
// One traceId from accept (or the scan tick) through this run, the engine call and the
|
|
158
|
+
// webhook: the params carry the starter's trace (observability spec §3 "Correlation").
|
|
159
|
+
const deps = depsFromEnv(this.env, {
|
|
160
|
+
traceparent: event.payload?.traceparent,
|
|
161
|
+
requestId: event.payload?.requestId,
|
|
162
|
+
claimId,
|
|
163
|
+
instanceId: event.instanceId,
|
|
164
|
+
workflow: "claim-ingest",
|
|
165
|
+
});
|
|
166
|
+
// Ambient for the run AND inside every step callback (`scopedStep`), so the fetch client and
|
|
167
|
+
// the cache reads record into `deps.metrics`.
|
|
168
|
+
const scope = { metrics: deps.metrics, logger: deps.logger };
|
|
169
|
+
return withMetrics(scope, () => this.ingest(event, scopedStep(step, scope, "claim-ingest"), deps, claimId));
|
|
170
|
+
}
|
|
171
|
+
async ingest(event, step, deps, claimId) {
|
|
172
|
+
const lane = event.payload?.lane ?? "chain";
|
|
173
|
+
const source = sourceFor(lane, this.env, deps);
|
|
174
|
+
// `instrumentWorkflowWithSentry` auto-captures a throw out of any `step.do` — but with no tags,
|
|
175
|
+
// so that issue lands next to our explicit `reportError` one and is far less actionable. Tag the
|
|
176
|
+
// run's scope once here and BOTH carry the ids you need to chase a stuck claim.
|
|
177
|
+
Sentry.setTags({ claimId, instanceId: event.instanceId, workflow: "claim-ingest" });
|
|
178
|
+
// The ledger row never exists without its collection (schema.ts: NOT NULL) — known from the
|
|
179
|
+
// cron's params, or resolved on-chain for a hand-created instance inside `record-queued`.
|
|
180
|
+
let collectionId = event.payload?.collectionId;
|
|
181
|
+
try {
|
|
182
|
+
collectionId = await step.do("record-queued", async () => {
|
|
183
|
+
// An API claim's row was written at accept, scope id and all; a chain claim's collection
|
|
184
|
+
// is on-chain.
|
|
185
|
+
const resolved = collectionId ??
|
|
186
|
+
(lane === "api"
|
|
187
|
+
? (await this.ledgerRow(claimId))?.collectionId
|
|
188
|
+
: (await getClaimById(deps, claimId))?.collectionId);
|
|
189
|
+
if (!resolved)
|
|
190
|
+
throw new NonRetryableError(`No ${lane} claim for id ${claimId}`);
|
|
191
|
+
await this.recordStatus(claimId, event, { status: "queued", collectionId: resolved, lane });
|
|
192
|
+
return resolved;
|
|
193
|
+
});
|
|
194
|
+
// The API lane's `accepted` (timeline + `claim.accepted`) — before the decision, off the
|
|
195
|
+
// submit's request path. Fail-soft like the notify step below.
|
|
196
|
+
if (!isChain(source)) {
|
|
197
|
+
await step
|
|
198
|
+
.do("notify-accepted", {
|
|
199
|
+
retries: { limit: 3, delay: "5 seconds", backoff: "exponential" },
|
|
200
|
+
timeout: "1 minute",
|
|
201
|
+
}, () => source.after.notify(claimId))
|
|
202
|
+
.catch((err) => {
|
|
203
|
+
deps.logger.error("notify-accepted.failed", { claimId, detail: String(err) });
|
|
204
|
+
reportError(err, { lane: "notify", step: "notify-accepted", claimId, collectionId });
|
|
205
|
+
});
|
|
206
|
+
}
|
|
207
|
+
// Pull + facts + decide in ONE step (see header). No decision ⇒ the ingest failed, so this
|
|
208
|
+
// step is NOT fail-soft — unlike `act` below. A deterministic negative (not watched, no
|
|
209
|
+
// claim, CID mismatch, a 4xx from the engine) is NonRetryable — don't burn retries on a real
|
|
210
|
+
// "no"; transient (503) falls through and the step retries.
|
|
211
|
+
const result = await step.do("evaluate",
|
|
212
|
+
// Timeout: the pull (bot media ≤ 25 MB/file) + the ext/ai connector budgets (~30s each) +
|
|
213
|
+
// the engine round trip. Retries stretch over ~4 hours (1 min → 128 min doubling):
|
|
214
|
+
// exhausting them marks the ingest `failed` with NO re-queue from the cron, so the schedule
|
|
215
|
+
// must outlive a real Matrix/blocksync/engine outage, not just a blip. Hibernation between
|
|
216
|
+
// retries is free.
|
|
217
|
+
{
|
|
218
|
+
retries: { limit: EVALUATE_RETRY_LIMIT, delay: "1 minute", backoff: "exponential" },
|
|
219
|
+
timeout: "4 minutes",
|
|
220
|
+
},
|
|
221
|
+
// `ctx.attempt` is 1-indexed: attempt limit+1 is the last. On it an outage a handler (or a
|
|
222
|
+
// stock ext/AI lane) still reports freezes as the rubric's onError instead of retrying —
|
|
223
|
+
// bounded, so a claim is decided rather than failed for an outside service's outage.
|
|
224
|
+
async (ctx) => {
|
|
225
|
+
const finalAttempt = ctx !== undefined && ctx.attempt > (ctx.config?.retries?.limit ?? EVALUATE_RETRY_LIMIT);
|
|
226
|
+
try {
|
|
227
|
+
return await this.evaluate(deps, source, claimId, finalAttempt);
|
|
228
|
+
}
|
|
229
|
+
catch (err) {
|
|
230
|
+
throw stepError(err);
|
|
231
|
+
}
|
|
232
|
+
});
|
|
233
|
+
// Recorded `skipped` inside `evaluate`: nothing to act on, tell or mark.
|
|
234
|
+
if (result.status === UNBILLABLE)
|
|
235
|
+
return { claimId, ok: true, ...result };
|
|
236
|
+
// Only a `decided` row can act (chain-write.ts step 1); anything else would spend a step to
|
|
237
|
+
// log a skip. Off the checkpointed result, so a replay decides the same way.
|
|
238
|
+
if (source.after.act && result.status === "decided") {
|
|
239
|
+
await actStep(this.env, deps, step, {
|
|
240
|
+
claimId,
|
|
241
|
+
collectionId,
|
|
242
|
+
instanceId: event.instanceId,
|
|
243
|
+
workflow: "claim-ingest",
|
|
244
|
+
});
|
|
245
|
+
}
|
|
246
|
+
// The source's notify lane (chain: the Matrix review card) — its own step, NEVER inside
|
|
247
|
+
// `evaluate`: a step retry there would re-send. Self-contained and fail-soft like `act`
|
|
248
|
+
// above: the delivery has its own ledger (`matrix_deliveries`), and a dead receiver never
|
|
249
|
+
// fails an ingest. It no-ops when the claim's state has nothing to tell.
|
|
250
|
+
try {
|
|
251
|
+
await step.do("notify-review", {
|
|
252
|
+
retries: { limit: 3, delay: "5 seconds", backoff: "exponential" },
|
|
253
|
+
timeout: "1 minute",
|
|
254
|
+
}, () => source.after.notify(claimId));
|
|
255
|
+
}
|
|
256
|
+
catch (err) {
|
|
257
|
+
deps.logger.error("notify-review.failed", { claimId, detail: String(err) });
|
|
258
|
+
reportError(err, { lane: "notify", step: "notify-review", claimId, collectionId });
|
|
259
|
+
}
|
|
260
|
+
await step.do("mark-processed", async () => {
|
|
261
|
+
await this.recordStatus(claimId, event, {
|
|
262
|
+
status: "processed",
|
|
263
|
+
collectionId: collectionId,
|
|
264
|
+
});
|
|
265
|
+
});
|
|
266
|
+
return { claimId, ok: true, ...result };
|
|
267
|
+
}
|
|
268
|
+
catch (err) {
|
|
269
|
+
// Terminal failure — a deterministic negative or exhausted retries. Record it so the ledger
|
|
270
|
+
// never shows a dead claim as `queued`, then rethrow so the instance shows as Errored in the
|
|
271
|
+
// dashboard (where an operator can rerun it; see header). Best-effort: a DB hiccup here must
|
|
272
|
+
// not replace the real failure. No collection ⇒ `record-queued` itself failed and there is
|
|
273
|
+
// no row to mark.
|
|
274
|
+
if (collectionId) {
|
|
275
|
+
await this.recordStatus(claimId, event, {
|
|
276
|
+
status: "failed",
|
|
277
|
+
collectionId,
|
|
278
|
+
error: err instanceof Error ? err.message : String(err),
|
|
279
|
+
}).catch(() => { });
|
|
280
|
+
// Dead, so the connector-result cache is gone too (fact-cache.ts) — best-effort, like the
|
|
281
|
+
// row above: a DB hiccup must not replace the real failure.
|
|
282
|
+
await factCacheDelete(getDb(this.env), claimId).catch(() => { });
|
|
283
|
+
// A review reserved for a claim that will now never get a receipt: free it (fail-soft).
|
|
284
|
+
if (isChain(source)) {
|
|
285
|
+
await releaseChainClaim({ ...deps, db: getDb(this.env) }, claimId, "other");
|
|
286
|
+
}
|
|
287
|
+
// Never decided, so never evidence: its duplicate-registry rows stop blocking an honest
|
|
288
|
+
// resubmission of the same work (unique-store.ts `VOID_TOKEN`, P0-6). Best-effort too.
|
|
289
|
+
await voidUndecidedUpdate(getDb(this.env), { collectionId, claimId }).catch(() => { });
|
|
290
|
+
// The API lane owes the customer its `failed` (§5); the chain lane has no failure notice.
|
|
291
|
+
// Still best-effort — but a customer never hearing `failed` is worth an issue.
|
|
292
|
+
if (!isChain(source)) {
|
|
293
|
+
await source.after.notify(claimId).catch((err) => {
|
|
294
|
+
deps.logger.warn("notify-failed.failed", { claimId, detail: String(err) });
|
|
295
|
+
// An issue, not a page (`reportAlert`): a notify failure is one claim's, and
|
|
296
|
+
// Sentry's issue alert already fires when the lane as a whole starts failing.
|
|
297
|
+
reportError(err, { lane: "notify", step: "notify-failed", claimId, collectionId });
|
|
298
|
+
});
|
|
299
|
+
}
|
|
300
|
+
}
|
|
301
|
+
deps.metrics.count("ingest.terminal", 1, {
|
|
302
|
+
op: lane,
|
|
303
|
+
outcome: await this.failureClass(claimId, err),
|
|
304
|
+
});
|
|
305
|
+
reportError(err, {
|
|
306
|
+
lane: "ingest",
|
|
307
|
+
step: "terminal",
|
|
308
|
+
claimId,
|
|
309
|
+
collectionId,
|
|
310
|
+
instanceId: event.instanceId,
|
|
311
|
+
});
|
|
312
|
+
// The retries ran out with the engine still answering without a receipt: a final decision
|
|
313
|
+
// nobody can act on or pay out — a page, not an issue (steps.ts `requireReceipt`).
|
|
314
|
+
if (err instanceof Error && err.message.startsWith(RECEIPT_MISSING)) {
|
|
315
|
+
await reportAlert(deps, "engine.receipt-missing", { claimId, collectionId, code: RECEIPT_MISSING }, `engine.receipt-missing:${claimId}`);
|
|
316
|
+
}
|
|
317
|
+
throw err;
|
|
318
|
+
}
|
|
319
|
+
}
|
|
320
|
+
/**
|
|
321
|
+
* The evaluate step's body: pull → facts → decide → the `decisions` row. Reads the DB, not step
|
|
322
|
+
* results, so an operator rerun converges — and a retry that finds the row is done.
|
|
323
|
+
*/
|
|
324
|
+
async evaluate(deps, source, claimId, finalAttempt = false) {
|
|
325
|
+
const db = getDb(this.env);
|
|
326
|
+
// In this order: what the ledger says about this step's history, then the `processing` mark
|
|
327
|
+
// for the NEXT attempt — written before anything is pulled or spent, so a crash anywhere below
|
|
328
|
+
// leaves it behind. (Not one `db.batch`: Drizzle's D1 batch throws on a relational read that
|
|
329
|
+
// finds no row.)
|
|
330
|
+
const ingest = await db.query.claimIngests.findFirst({
|
|
331
|
+
where: (t, { eq: eqOp }) => eqOp(t.claimId, claimId),
|
|
332
|
+
});
|
|
333
|
+
await db
|
|
334
|
+
.update(claimIngests)
|
|
335
|
+
.set({ status: "processing" })
|
|
336
|
+
.where(eq(claimIngests.claimId, claimId));
|
|
337
|
+
const existing = await db.query.decisions.findFirst({
|
|
338
|
+
where: (t, { eq: eqOp }) => eqOp(t.claimId, claimId),
|
|
339
|
+
});
|
|
340
|
+
if (existing)
|
|
341
|
+
return resultOf(existing);
|
|
342
|
+
const engine = createEngineClient({
|
|
343
|
+
config: deps.config,
|
|
344
|
+
logger: deps.logger,
|
|
345
|
+
trace: deps.trace,
|
|
346
|
+
cache: deps.cache,
|
|
347
|
+
});
|
|
348
|
+
// `processing` already set ⇒ a previous attempt of this step ran and died before its row
|
|
349
|
+
// landed — possibly AFTER the engine decided. Decided-once on the engine means a resend would
|
|
350
|
+
// only replay that stored row, so one read recovers it and the claim is never stranded: the
|
|
351
|
+
// engine is NOT asked to decide again below. A 404 means the engine never got that far: the
|
|
352
|
+
// normal path. A first attempt (`queued`) never pays the read.
|
|
353
|
+
if (ingest?.status === "processing") {
|
|
354
|
+
const recovered = await engine.getDecision(claimId);
|
|
355
|
+
if (recovered) {
|
|
356
|
+
deps.logger.info("evaluate.recovered", {
|
|
357
|
+
claimId,
|
|
358
|
+
collectionId: ingest.collectionId,
|
|
359
|
+
status: recovered.decision.status,
|
|
360
|
+
resultDigest: recovered.resultDigest,
|
|
361
|
+
receiptCid: recovered.receipt?.cid ?? null,
|
|
362
|
+
});
|
|
363
|
+
if (!recovered.receipt && recovered.decision.status !== "pending_review") {
|
|
364
|
+
// Since CA10 the GET mints a missing receipt or answers 503, so this is a contract
|
|
365
|
+
// breach. Never recorded receipt-less (the receipt is the one credential act and the
|
|
366
|
+
// payout spend), and never re-decided either: that would re-run the handlers' AI spend.
|
|
367
|
+
// `requireReceipt` retries the step, whose next GET recovers it with its receipt.
|
|
368
|
+
deps.logger.warn("evaluate.recovered-without-receipt", {
|
|
369
|
+
claimId,
|
|
370
|
+
collectionId: ingest.collectionId,
|
|
371
|
+
status: recovered.decision.status,
|
|
372
|
+
});
|
|
373
|
+
}
|
|
374
|
+
requireReceipt(recovered, "decision");
|
|
375
|
+
return this.recordRecovered(deps, source, db, engine, claimId, ingest.collectionId, recovered);
|
|
376
|
+
}
|
|
377
|
+
}
|
|
378
|
+
// Out of engine credits, every decide call 402s until the credits cron resumes the scope, so an
|
|
379
|
+
// attempt here would pull, build and PAY for its AI calls up to eight times only to be refused.
|
|
380
|
+
// One projected read instead, AFTER the two ledger reads above (a decided or recovered claim
|
|
381
|
+
// returns regardless): the step retries on its own backoff and spends nothing meanwhile.
|
|
382
|
+
const paused = ingest?.collectionId ? await source.pausedReason(ingest.collectionId) : null;
|
|
383
|
+
if (paused === "engine-credits") {
|
|
384
|
+
throw AppError.unavailable(`${source.lane === "chain" ? "collection" : "source"} paused for engine credits — not pulling ${claimId}`);
|
|
385
|
+
}
|
|
386
|
+
// The same for a review nobody can pay for yet: the payer's fix, resumed by the payer cron.
|
|
387
|
+
if (isBillingPause(paused)) {
|
|
388
|
+
throw AppError.unavailable(`${PAYER_BILLING} collection paused ${paused} — not pulling ${claimId}`);
|
|
389
|
+
}
|
|
390
|
+
const billing = isChain(source) && ingest?.collectionId
|
|
391
|
+
? await this.billingFor(deps, source, db, claimId, ingest.collectionId)
|
|
392
|
+
: null;
|
|
393
|
+
if (billing === UNBILLABLE) {
|
|
394
|
+
await db
|
|
395
|
+
.update(claimIngests)
|
|
396
|
+
.set({ status: "skipped", error: "unbillable-claim-id" })
|
|
397
|
+
.where(eq(claimIngests.claimId, claimId));
|
|
398
|
+
deps.logger.warn("reserve.unbillable-claim-id", {
|
|
399
|
+
claimId,
|
|
400
|
+
collectionId: ingest?.collectionId,
|
|
401
|
+
});
|
|
402
|
+
return { status: UNBILLABLE, verdict: null, resultDigest: null, receiptCid: null };
|
|
403
|
+
}
|
|
404
|
+
return this.decideFresh(deps, source, db, engine, claimId, billing, finalAttempt);
|
|
405
|
+
}
|
|
406
|
+
/**
|
|
407
|
+
* Who pays for this chain claim's review (header): null when its collection pays by its
|
|
408
|
+
* evaluation leg (or the oracle no longer bills per review); `reserved` when a charge already
|
|
409
|
+
* holds it (a retry); else the payer, resolved fresh — never a guess: the engine's or the chain's
|
|
410
|
+
* trouble retries the step, and no usable delegation pauses the collection `payer-delegation`.
|
|
411
|
+
*/
|
|
412
|
+
async billingFor(deps, source, db, claimId, collectionId) {
|
|
413
|
+
const watched = await deps.getWatched(collectionId);
|
|
414
|
+
if (!watched?.billingSourceId)
|
|
415
|
+
return null;
|
|
416
|
+
// Registered to be paid per review, it is never decided unpaid: a plan IXO no longer grants
|
|
417
|
+
// pauses it (re-register on the escrow gate), and a plan the engine cannot tell retries.
|
|
418
|
+
if (!(await planAllowsReviewBilling(deps))) {
|
|
419
|
+
await this.pausePayer(deps, db, collectionId, "oracle-plan", "plan does not allow it");
|
|
420
|
+
throw AppError.unavailable(`${PAYER_BILLING} the plan does not allow per-review billing`);
|
|
421
|
+
}
|
|
422
|
+
if (!CHAIN_CLAIM_ID.test(claimId))
|
|
423
|
+
return UNBILLABLE;
|
|
424
|
+
const charge = await db.query.apiCharges.findFirst({
|
|
425
|
+
columns: { status: true },
|
|
426
|
+
where: eq(apiCharges.claimId, claimId),
|
|
427
|
+
});
|
|
428
|
+
if (charge && ["reserved", "settled", "paid"].includes(charge.status))
|
|
429
|
+
return "reserved";
|
|
430
|
+
const billingDeps = { ...deps, db };
|
|
431
|
+
const payer = await resolvePayer(billingDeps, await companyOf(billingDeps, collectionId), await source.protocolDid(collectionId));
|
|
432
|
+
if (!payer.ok) {
|
|
433
|
+
await this.pausePayer(deps, db, collectionId, "payer-delegation", payer.detail);
|
|
434
|
+
if (payer.detail.startsWith("no published price")) {
|
|
435
|
+
// The operator's config, not the payer's: every claim of the protocol stops here.
|
|
436
|
+
await reportAlert(deps, "payments.review.no-price", { collectionId });
|
|
437
|
+
}
|
|
438
|
+
throw AppError.unavailable(`${PAYER_BILLING} no one pays for collection ${collectionId}`);
|
|
439
|
+
}
|
|
440
|
+
// The organisation now pays from another source (one deleted, one added): follow it.
|
|
441
|
+
if (payer.source.sourceId !== watched.billingSourceId) {
|
|
442
|
+
await db
|
|
443
|
+
.update(watchedCollections)
|
|
444
|
+
.set({ billingSourceId: payer.source.sourceId })
|
|
445
|
+
.where(eq(watchedCollections.collectionId, collectionId));
|
|
446
|
+
}
|
|
447
|
+
return payer;
|
|
448
|
+
}
|
|
449
|
+
/**
|
|
450
|
+
* A billing pause. The payer's two: the owner's notice, never a page (a customer's condition).
|
|
451
|
+
* `oracle-plan`: IXO's to fix — paged, no notice to the owner or the payer.
|
|
452
|
+
*/
|
|
453
|
+
async pausePayer(deps, db, collectionId, reason, detail) {
|
|
454
|
+
if (reason === "oracle-plan") {
|
|
455
|
+
await db
|
|
456
|
+
.update(watchedCollections)
|
|
457
|
+
.set({ status: "paused", pausedReason: reason })
|
|
458
|
+
.where(eq(watchedCollections.collectionId, collectionId));
|
|
459
|
+
await reportAlert(deps, "payments.review.oracle-plan", { collectionId, code: peerCode(detail) }, "payments.review.oracle-plan");
|
|
460
|
+
}
|
|
461
|
+
else {
|
|
462
|
+
await pauseCollection(db, deps, collectionId, reason, undefined, false);
|
|
463
|
+
}
|
|
464
|
+
deps.logger.warn(`reserve.${reason}`, { collectionId, detail });
|
|
465
|
+
deps.metrics.count("review_billing.paused", 1, { outcome: reason });
|
|
466
|
+
}
|
|
467
|
+
/** The normal path: pull → build → (reserve) → decide → the `decisions` row. */
|
|
468
|
+
async decideFresh(deps, source, db, engine, claimId, billing = null, finalAttempt = false) {
|
|
469
|
+
// The one pull per claim: metadata + body + attachment descriptors (the source's store), and
|
|
470
|
+
// the content the engine binds the decision to — the engine's alone, so it is taken off here
|
|
471
|
+
// and no handler ever sees it. Like the body, it never leaves this step.
|
|
472
|
+
const { content, ...pulled } = await source.pull(claimId);
|
|
473
|
+
const { collectionId } = pulled;
|
|
474
|
+
const fdeps = { ...factDeps(deps, pulled.media, engine, db, this.env, source), finalAttempt };
|
|
475
|
+
// `subject.protocolDid` — where the engine reads `#rub`/`#vct` from, and what its manifest is
|
|
476
|
+
// keyed by, so it is resolved before the build (the manifest is the build's first read).
|
|
477
|
+
const protocolDid = await source.protocolDid(collectionId);
|
|
478
|
+
// The engine names the chain lane's subject `claim` (§8.1); the seam names lanes.
|
|
479
|
+
const kind = (await source.subject(claimId)).kind === "api" ? "api" : "claim";
|
|
480
|
+
// S16 — the payout block, beside the facts (never in them).
|
|
481
|
+
const payout = payoutRequestFor(protocolDid);
|
|
482
|
+
// RESOLVE + FREEZE (lib/facts/builder.ts). Nothing here is decided: a build that cannot
|
|
483
|
+
// complete is recorded as what it is, and the engine is never asked.
|
|
484
|
+
const built = await buildFacts(fdeps, { claim: pulled, protocolDid });
|
|
485
|
+
if (!built.ok) {
|
|
486
|
+
return this.buildFailure(deps, source, db, pulled, built);
|
|
487
|
+
}
|
|
488
|
+
// The claim WILL be decided: only now is a review reserved (never decide without one).
|
|
489
|
+
if (billing && billing !== "reserved") {
|
|
490
|
+
await this.reserve(deps, db, billing, { claimId, collectionId, protocolDid });
|
|
491
|
+
}
|
|
492
|
+
const request = (b) => ({
|
|
493
|
+
subject: { kind, claimId, collectionId, protocolDid },
|
|
494
|
+
rubric: { id: b.rubricId },
|
|
495
|
+
facts: b.facts,
|
|
496
|
+
...(payout ? { payout } : {}),
|
|
497
|
+
claimContent: content,
|
|
498
|
+
});
|
|
499
|
+
let decided;
|
|
500
|
+
try {
|
|
501
|
+
decided = await this.decide(deps, engine, fdeps, pulled, protocolDid, built, request);
|
|
502
|
+
}
|
|
503
|
+
catch (err) {
|
|
504
|
+
// The re-anchored rubric is the one that cannot be built for — recorded exactly as a first
|
|
505
|
+
// build's failure would be (see `decide`), never decided.
|
|
506
|
+
if (err instanceof BuildFailure) {
|
|
507
|
+
return this.buildFailure(deps, source, db, pulled, err.result);
|
|
508
|
+
}
|
|
509
|
+
throw await this.engineFailure(deps, source, db, claimId, collectionId, err);
|
|
510
|
+
}
|
|
511
|
+
const { response } = decided;
|
|
512
|
+
requireReceipt(response, "decision");
|
|
513
|
+
// Both sides hash the same canonical JSON (factset.ts); a drift here means the engine is
|
|
514
|
+
// binding its decision to facts other than the ones we froze — worth knowing, never fatal.
|
|
515
|
+
const ours = await factsDigest(decided.built.facts);
|
|
516
|
+
if (ours !== response.factsDigest) {
|
|
517
|
+
deps.logger.warn("evaluate.facts-digest-drift", {
|
|
518
|
+
claimId,
|
|
519
|
+
ours,
|
|
520
|
+
theirs: response.factsDigest,
|
|
521
|
+
});
|
|
522
|
+
}
|
|
523
|
+
// Null on the engine only when the protocol has no `#rub` — impossible past our own resolve,
|
|
524
|
+
// but never store a null pin for a claim we KNOW the rubric of.
|
|
525
|
+
const rubricId = response.rubricId ?? decided.built.rubricId;
|
|
526
|
+
const result = await this.record(deps, source, db, pulled, response, rubricId, decided.built.facts);
|
|
527
|
+
// The answer archive (lib/archive.ts), here because the body is in hand only inside this step.
|
|
528
|
+
// Fail-soft and returns nothing: the body goes to R2, never into the step result.
|
|
529
|
+
if (this.env.ANSWERS_ARCHIVE) {
|
|
530
|
+
await archiveAnswer(this.env, deps, {
|
|
531
|
+
lane: source.lane,
|
|
532
|
+
claim: pulled,
|
|
533
|
+
content,
|
|
534
|
+
submitter: await source.submitterKey(pulled).catch(() => null),
|
|
535
|
+
response,
|
|
536
|
+
facts: { ext: decided.built.facts.ext, ai: decided.built.facts.ai },
|
|
537
|
+
hooks: getOracle().config.archive,
|
|
538
|
+
});
|
|
539
|
+
}
|
|
540
|
+
return result;
|
|
541
|
+
}
|
|
542
|
+
/** Reserve the review (payments/review-billing.ts), or say why not — a pause, a retry, a stop. */
|
|
543
|
+
async reserve(deps, db, payer, claim) {
|
|
544
|
+
const out = await reserveChainClaim({ ...deps, db }, payer, claim);
|
|
545
|
+
if (out.ok)
|
|
546
|
+
return;
|
|
547
|
+
if ("pause" in out) {
|
|
548
|
+
await this.pausePayer(deps, db, claim.collectionId, out.pause, out.detail);
|
|
549
|
+
throw AppError.unavailable(`${PAYER_BILLING} collection paused ${out.pause} (${out.detail})`);
|
|
550
|
+
}
|
|
551
|
+
if ("fail" in out)
|
|
552
|
+
throw new NonRetryableError(`${PAYER_BILLING} ${out.detail}`);
|
|
553
|
+
throw AppError.unavailable(`${PAYER_BILLING} reservation refused (${out.detail})`);
|
|
554
|
+
}
|
|
555
|
+
/**
|
|
556
|
+
* A decision recovered from the engine's store → its `decisions` row.
|
|
557
|
+
*
|
|
558
|
+
* It is FINAL for this claim — the engine will not judge it twice — so it outranks anything this
|
|
559
|
+
* attempt would have concluded, including a build that failed. What it lacks is the facts it was
|
|
560
|
+
* decided on: the attempt that produced them died before writing the row, and the engine keeps a
|
|
561
|
+
* trace, not a FactSet. So they are rebuilt here — and stand in for the originals only if the
|
|
562
|
+
* rebuild is PROVABLY the same one, which is exactly what the engine's `factsDigest` proves.
|
|
563
|
+
* Anything else (a non-deterministic fact, a re-anchored rubric, a failed rebuild) is written as
|
|
564
|
+
* a park with its reason, at write time: better an explicit blocked row naming the drift than a
|
|
565
|
+
* decided row the act lane refuses later without knowing why.
|
|
566
|
+
*
|
|
567
|
+
* The rebuild may not even be ATTEMPTABLE: the owner's delegation can expire while the claim
|
|
568
|
+
* sits between attempts, and then the pull fail-closes 403. A deterministic "no" there is NOT a
|
|
569
|
+
* reason to lose the decision — the ingest would be marked `failed` with no row at all, while
|
|
570
|
+
* the engine holds a final answer it will never issue again. So it is recorded parked, facts
|
|
571
|
+
* null, and the act lane refuses to sign it (src/act.ts reads those facts). Only a transient
|
|
572
|
+
* failure is rethrown, so the step still retries and a later attempt can record the real facts.
|
|
573
|
+
*/
|
|
574
|
+
async recordRecovered(deps, source, db, engine, claimId, collectionId, recovered) {
|
|
575
|
+
let claim;
|
|
576
|
+
let built;
|
|
577
|
+
try {
|
|
578
|
+
// Nothing is sent here, so the content is dropped with the pull.
|
|
579
|
+
const { content: _content, ...rest } = await source.pull(claimId);
|
|
580
|
+
claim = rest;
|
|
581
|
+
const protocolDid = await source.protocolDid(claim.collectionId);
|
|
582
|
+
built = await buildFacts(factDeps(deps, claim.media, engine, db, this.env, source), {
|
|
583
|
+
claim,
|
|
584
|
+
protocolDid,
|
|
585
|
+
});
|
|
586
|
+
}
|
|
587
|
+
catch (err) {
|
|
588
|
+
// `stepError` is the retry/stop line the step itself is judged by (steps.ts) — reuse it so
|
|
589
|
+
// "deterministic" means the same thing here as it does there. Transient: rethrow untouched
|
|
590
|
+
// and let the step wrapper classify it, exactly as before.
|
|
591
|
+
if (!(stepError(err) instanceof NonRetryableError))
|
|
592
|
+
throw err;
|
|
593
|
+
const message = err instanceof Error ? err.message : String(err);
|
|
594
|
+
deps.logger.warn("evaluate.recovered-facts-unbuildable", {
|
|
595
|
+
claimId,
|
|
596
|
+
collectionId,
|
|
597
|
+
status: recovered.decision.status,
|
|
598
|
+
error: message,
|
|
599
|
+
});
|
|
600
|
+
return this.record(deps, source, db, { claimId, collectionId }, recovered, recovered.rubricId, null, `recovered decision; facts could not be rebuilt: ${message}`);
|
|
601
|
+
}
|
|
602
|
+
const rebuilt = built.ok && (await factsDigest(built.facts)) === recovered.factsDigest ? built.facts : null;
|
|
603
|
+
return this.record(deps, source, db, claim, recovered, recovered.rubricId, rebuilt, rebuilt
|
|
604
|
+
? undefined
|
|
605
|
+
: "recovered decision's factsDigest does not match the facts rebuilt in this attempt");
|
|
606
|
+
}
|
|
607
|
+
/**
|
|
608
|
+
* The engine's answer → the `decisions` row, the collection's rubric pin and the `unusable`
|
|
609
|
+
* pause: ONE path whether the answer came from `POST /v1/decisions` just now or was recovered
|
|
610
|
+
* from the engine's store on a retry (see `evaluate`), so the two can never drift apart.
|
|
611
|
+
*
|
|
612
|
+
* `sent` is the FactSet this decision was made on — its `ext`/`ai` are frozen onto the row for
|
|
613
|
+
* the act policy to read at signing time (schema.ts `decisions.facts`), and nothing else of it
|
|
614
|
+
* is: `answers`/`attachments` are the claim's erasable surface and never persisted here. Null
|
|
615
|
+
* only on the recovery path when the rebuild could not be proven to be the same facts, which is
|
|
616
|
+
* what `park` says: the row is written `blocked` with that reason instead of `pending`, so the
|
|
617
|
+
* claim read explains itself and the act lane never has to guess.
|
|
618
|
+
*/
|
|
619
|
+
async record(deps, source, db, claim, response, rubricId, sent, park) {
|
|
620
|
+
const { claimId, collectionId } = claim;
|
|
621
|
+
const row = {
|
|
622
|
+
claimId,
|
|
623
|
+
collectionId,
|
|
624
|
+
rubricId,
|
|
625
|
+
factsDigest: response.factsDigest,
|
|
626
|
+
verdict: response.decision.verdict,
|
|
627
|
+
status: response.decision.status,
|
|
628
|
+
resultDigest: response.resultDigest,
|
|
629
|
+
receiptCid: response.receipt?.cid ?? null,
|
|
630
|
+
receiptJws: response.receipt?.jws ?? null,
|
|
631
|
+
decision: response.decision,
|
|
632
|
+
explanation: response.explanation,
|
|
633
|
+
facts: sent ? { ext: sent.ext, ai: sent.ai } : null,
|
|
634
|
+
erroredFacts: erroredFactsOf(response),
|
|
635
|
+
// The review view's `duplicates` source (`{}` stores nothing, like an older engine's none).
|
|
636
|
+
pendingTaskDetails: Object.keys(response.pendingTaskDetails ?? {}).length > 0
|
|
637
|
+
? (response.pendingTaskDetails ?? null)
|
|
638
|
+
: null,
|
|
639
|
+
// Nothing is ever acted on for a source without an act step (the API lane, §7.1).
|
|
640
|
+
chainStatus: !source.after.act
|
|
641
|
+
? "skipped"
|
|
642
|
+
: park
|
|
643
|
+
? "blocked"
|
|
644
|
+
: "pending",
|
|
645
|
+
chainError: source.after.act ? (park ?? null) : null,
|
|
646
|
+
};
|
|
647
|
+
// The decision and, when it is FINAL, its verdict denormalized onto the claim's duplicate
|
|
648
|
+
// registry rows (stock/unique-store.ts; a no-op for a rubric without `unique`) land in ONE
|
|
649
|
+
// batch: a retry that finds the row is done (the early return above), so the token can never
|
|
650
|
+
// be owed separately. `pending_review` stays NULL (= pending, blockable) until the fold.
|
|
651
|
+
// The claim's connector-result cache rows die in the same batch (fact-cache.ts) — decided,
|
|
652
|
+
// so nothing is left for a retry to reuse. So does the collection's rubric pin, first sight
|
|
653
|
+
// only (NULL only): the chain is the authority and the per-claim pin is the row's own
|
|
654
|
+
// `rubricId`; this one is the dashboard's "which rules govern this collection", never
|
|
655
|
+
// re-written by a later re-anchor. Inside the batch, or a crash after it would lose the pin for
|
|
656
|
+
// good (the retry returns early on the row). Chain lane only — an API scope has no
|
|
657
|
+
// `watched_collections` row.
|
|
658
|
+
const token = registryVerdictToken(row.status, row.verdict);
|
|
659
|
+
await db.batch([
|
|
660
|
+
db.insert(decisions).values(row).onConflictDoNothing(),
|
|
661
|
+
...(token ? [finalVerdictUpdate(db, { collectionId, claimId, token })] : []),
|
|
662
|
+
factCacheDelete(db, claimId),
|
|
663
|
+
...(isChain(source)
|
|
664
|
+
? [
|
|
665
|
+
db
|
|
666
|
+
.update(watchedCollections)
|
|
667
|
+
.set({ rubricId: row.rubricId })
|
|
668
|
+
.where(and(eq(watchedCollections.collectionId, collectionId), isNull(watchedCollections.rubricId))),
|
|
669
|
+
]
|
|
670
|
+
: []),
|
|
671
|
+
]);
|
|
672
|
+
await this.decisionLatency(deps, source, db, claimId, response, sent);
|
|
673
|
+
// A payout scope whose claim names no payee: decided, its receipt without a payment binding
|
|
674
|
+
// (ENGINE-CONTRACT "Payee").
|
|
675
|
+
if (response.decisionToPayRefused) {
|
|
676
|
+
deps.logger.warn("payout.refused", {
|
|
677
|
+
claimId,
|
|
678
|
+
collectionId,
|
|
679
|
+
code: response.decisionToPayRefused,
|
|
680
|
+
});
|
|
681
|
+
}
|
|
682
|
+
// Settle on the receipt (payments spec §4 step 6): fail-soft, the reconcile re-settles a lost
|
|
683
|
+
// one; a claim with no charge (billing mode `none`, a chain claim its evaluation leg pays) is a
|
|
684
|
+
// no-op. An engine `unusable` is a decision with a receipt: settled, as on the API lane. A
|
|
685
|
+
// `pending_review` has no receipt until the fold: hold its reservation through the review
|
|
686
|
+
// instead (extend.ts).
|
|
687
|
+
if (deps.config.X402_FACILITATOR_URL) {
|
|
688
|
+
if (row.receiptJws)
|
|
689
|
+
await settleClaim({ ...deps, db }, claimId, row.receiptJws);
|
|
690
|
+
else if (row.status === "pending_review")
|
|
691
|
+
await extendForReview({ ...deps, db }, claimId);
|
|
692
|
+
}
|
|
693
|
+
// The engine could not bind the rubric to these facts (header): a real, receipted decision
|
|
694
|
+
// for THIS claim — and the same answer for every other claim of the collection.
|
|
695
|
+
if (response.decision.status === "unusable") {
|
|
696
|
+
await pauseUnusable(source, deps.logger, "evaluate", {
|
|
697
|
+
claimId,
|
|
698
|
+
collectionId,
|
|
699
|
+
rubricId: row.rubricId,
|
|
700
|
+
issues: response.decision.reasons,
|
|
701
|
+
receiptCid: row.receiptCid,
|
|
702
|
+
});
|
|
703
|
+
}
|
|
704
|
+
deps.logger.info("evaluate.done", {
|
|
705
|
+
claimId,
|
|
706
|
+
collectionId,
|
|
707
|
+
rubricId: row.rubricId,
|
|
708
|
+
status: response.decision.status,
|
|
709
|
+
verdict: response.decision.verdict,
|
|
710
|
+
pendingTasks: response.decision.pendingTasks,
|
|
711
|
+
resultDigest: response.resultDigest,
|
|
712
|
+
receiptCid: row.receiptCid,
|
|
713
|
+
traceId: response.traceId ?? null,
|
|
714
|
+
});
|
|
715
|
+
return resultOf(row);
|
|
716
|
+
}
|
|
717
|
+
/**
|
|
718
|
+
* `api.decision.latency` — accept → decision row, the SLO metric. Accepted is the API claim's
|
|
719
|
+
* `receivedAt`, or the chain claim's ledger `createdAt` (its first `record-queued`). `status` says
|
|
720
|
+
* whether the protocol's rubric runs AI checks: the frozen FactSet's `ai` keys are exactly the
|
|
721
|
+
* work order's (validate.ts holds them to the manifest), so no extra read; `-` only when a
|
|
722
|
+
* recovered decision's facts could not be rebuilt. Best-effort: a metric never fails the step.
|
|
723
|
+
*/
|
|
724
|
+
async decisionLatency(deps, source, db, claimId, response, sent) {
|
|
725
|
+
try {
|
|
726
|
+
const acceptedAt = isChain(source)
|
|
727
|
+
? (await db.query.claimIngests.findFirst({
|
|
728
|
+
columns: { createdAt: true },
|
|
729
|
+
where: eq(claimIngests.claimId, claimId),
|
|
730
|
+
}))?.createdAt
|
|
731
|
+
: (await db.query.apiClaims.findFirst({
|
|
732
|
+
columns: { receivedAt: true },
|
|
733
|
+
where: eq(apiClaims.claimId, claimId),
|
|
734
|
+
}))?.receivedAt;
|
|
735
|
+
if (!acceptedAt)
|
|
736
|
+
return;
|
|
737
|
+
const { protocolDid } = response.subject;
|
|
738
|
+
deps.metrics.timing("api.decision.latency", Date.now() - acceptedAt.getTime(), {
|
|
739
|
+
op: isChain(source) ? "chain" : "api",
|
|
740
|
+
status: sent ? (Object.keys(sent.ai).length > 0 ? "ai" : "no_ai") : null,
|
|
741
|
+
outcome: response.decision.verdict,
|
|
742
|
+
id: typeof protocolDid === "string" ? protocolDid : null,
|
|
743
|
+
});
|
|
744
|
+
}
|
|
745
|
+
catch (err) {
|
|
746
|
+
deps.logger.warn("metrics.decision-latency-failed", { claimId, detail: String(err) });
|
|
747
|
+
}
|
|
748
|
+
}
|
|
749
|
+
/**
|
|
750
|
+
* `POST /v1/decisions`, with the one recoverable refusal handled here: `RUBRIC_PIN_MISMATCH` —
|
|
751
|
+
* our pin ≠ the chain's `#rub` proof as the engine read it, i.e. `#rub` was re-anchored between
|
|
752
|
+
* our (KV-cached) manifest read and theirs. Invalidate and re-read the manifest ONCE: a changed
|
|
753
|
+
* pin is a new work order (new facts, so a rebuild — connectors run again; the fact cache is
|
|
754
|
+
* keyed by the pin, fact-cache.ts), the same pin means the engine and the chain disagree, which
|
|
755
|
+
* no retry of ours fixes. The manifest may also have turned `unusable` under the new anchor —
|
|
756
|
+
* then the rebuild records that, and never decides.
|
|
757
|
+
*/
|
|
758
|
+
async decide(deps, engine, fdeps, pulled, protocolDid, built, request) {
|
|
759
|
+
try {
|
|
760
|
+
return { response: await this.ask(deps, engine, request(built)), built };
|
|
761
|
+
}
|
|
762
|
+
catch (err) {
|
|
763
|
+
if (!(err instanceof EngineError) || err.code !== "RUBRIC_PIN_MISMATCH")
|
|
764
|
+
throw err;
|
|
765
|
+
await engine.invalidateManifest(protocolDid);
|
|
766
|
+
const fresh = await engine.getManifest(protocolDid);
|
|
767
|
+
const repinned = isManifestUnusable(fresh) ? null : fresh.rubricId.toLowerCase();
|
|
768
|
+
if (repinned === built.rubricId) {
|
|
769
|
+
throw new NonRetryableError(`Rubric pin mismatch that re-reading the manifest did not fix: ${err.message}`);
|
|
770
|
+
}
|
|
771
|
+
deps.logger.warn("evaluate.rubric-repinned", {
|
|
772
|
+
claimId: pulled.claimId,
|
|
773
|
+
collectionId: pulled.collectionId,
|
|
774
|
+
from: built.rubricId,
|
|
775
|
+
to: repinned,
|
|
776
|
+
});
|
|
777
|
+
const rebuilt = await buildFacts(fdeps, { claim: pulled, protocolDid, manifest: fresh });
|
|
778
|
+
if (!rebuilt.ok) {
|
|
779
|
+
// The re-anchored rubric is the one that cannot be built for — record THAT, no engine call.
|
|
780
|
+
throw new BuildFailure(rebuilt);
|
|
781
|
+
}
|
|
782
|
+
return { response: await this.ask(deps, engine, request(rebuilt)), built: rebuilt };
|
|
783
|
+
}
|
|
784
|
+
}
|
|
785
|
+
/** One decide call, with the contract's retry-once on `NO_EVALUATE_GRANT` (see `GRANT_RETRY_DELAY`). */
|
|
786
|
+
async ask(deps, engine, req) {
|
|
787
|
+
try {
|
|
788
|
+
return await engine.decide(req);
|
|
789
|
+
}
|
|
790
|
+
catch (err) {
|
|
791
|
+
if (!(err instanceof EngineError) || err.code !== "NO_EVALUATE_GRANT")
|
|
792
|
+
throw err;
|
|
793
|
+
deps.logger.warn("evaluate.no-grant-yet", {
|
|
794
|
+
claimId: req.subject.claimId,
|
|
795
|
+
collectionId: req.subject.collectionId,
|
|
796
|
+
retryInMs: GRANT_RETRY_DELAY.ms,
|
|
797
|
+
});
|
|
798
|
+
await new Promise((resolve) => setTimeout(resolve, GRANT_RETRY_DELAY.ms));
|
|
799
|
+
return engine.decide(req);
|
|
800
|
+
}
|
|
801
|
+
}
|
|
802
|
+
/**
|
|
803
|
+
* The engine said no (docs/ENGINE-CONTRACT.md "Errors"): do what the table says, then hand back
|
|
804
|
+
* the error to throw — NonRetryable for a deterministic refusal, the original for a retryable
|
|
805
|
+
* one. Non-engine errors pass through for `stepError` to classify.
|
|
806
|
+
*/
|
|
807
|
+
async engineFailure(deps, source, db, claimId, collectionId, err) {
|
|
808
|
+
if (!(err instanceof EngineError))
|
|
809
|
+
return err;
|
|
810
|
+
const scope = { claimId, collectionId, code: err.code, requestId: err.requestId ?? null };
|
|
811
|
+
switch (err.code) {
|
|
812
|
+
case "NO_EVALUATE_GRANT":
|
|
813
|
+
// Twice (see `ask`): not hired (any more) for this collection — no claim of it can be
|
|
814
|
+
// decided until the owner re-grants, so stop enqueuing and say why. The watched row stands.
|
|
815
|
+
// Only the chain lane's subject is grant-checked (§8.1); an API source never gets here.
|
|
816
|
+
if (isChain(source))
|
|
817
|
+
await source.pause(collectionId, "engine-no-grant");
|
|
818
|
+
deps.logger.error("evaluate.not-hired", scope);
|
|
819
|
+
reportError(err, { lane: "evaluate", step: "evaluate", claimId, collectionId });
|
|
820
|
+
return new NonRetryableError(`Not hired for collection ${collectionId}: ${err.message}`);
|
|
821
|
+
case "INSUFFICIENT_CREDITS": {
|
|
822
|
+
// The oracle OWNER's credits are exhausted at the engine (an invoice bounced): EVERY
|
|
823
|
+
// collection pauses (the credits are the owner's, shared across every collection we watch
|
|
824
|
+
// for them, never this kit's own wallet), the operator is paged, and this claim keeps
|
|
825
|
+
// retrying. While the pause stands, the cron enqueues nothing new and every in-flight
|
|
826
|
+
// claim's retry stops at the pause check before its pull (`evaluate`), spending nothing;
|
|
827
|
+
// once the billing cron lifts it, the next retry pulls, builds and the engine answers.
|
|
828
|
+
await pauseForEngineCredits(db, deps);
|
|
829
|
+
deps.logger.error("evaluate.credits-exhausted", { ...scope, topUpUrl: err.topUpUrl });
|
|
830
|
+
reportError(err, { lane: "evaluate", step: "evaluate", claimId, collectionId });
|
|
831
|
+
return err;
|
|
832
|
+
}
|
|
833
|
+
case "VALIDATION":
|
|
834
|
+
// The engine refused the facts' SHAPE — our connectors' bug, never a claim outcome. The
|
|
835
|
+
// details are Zod paths and messages (identifiers), logged so the fix is one grep away.
|
|
836
|
+
deps.logger.error("evaluate.facts-rejected", { ...scope, details: err.details ?? null });
|
|
837
|
+
reportError(err, { lane: "evaluate", step: "evaluate", claimId, collectionId });
|
|
838
|
+
return new NonRetryableError(`${FAILURE.engineRejected}: ${err.message}`);
|
|
839
|
+
case "CONTENT_MISMATCH":
|
|
840
|
+
case "PAYLOAD_TOO_LARGE": {
|
|
841
|
+
// The engine would not bind the decision to the content we sent (company authority): the
|
|
842
|
+
// bytes, the answers, the attachments, the agent — or a body over its cap, which the client
|
|
843
|
+
// also says before sending. No resend changes the claim, so it is recorded like a build
|
|
844
|
+
// failure (`skipped`: nothing to act on), the ingest fails, and the operator is paged —
|
|
845
|
+
// `details.reason` names the check, never an answer value.
|
|
846
|
+
const status = CONTENT_REFUSAL_STATUS[err.code];
|
|
847
|
+
const reason = reasonOf(err.details);
|
|
848
|
+
await db.batch([
|
|
849
|
+
db
|
|
850
|
+
.insert(decisions)
|
|
851
|
+
.values({
|
|
852
|
+
claimId,
|
|
853
|
+
collectionId,
|
|
854
|
+
status,
|
|
855
|
+
explanation: `${err.code}${reason ? ` (${reason})` : ""}: ${err.message}`,
|
|
856
|
+
chainStatus: "skipped",
|
|
857
|
+
})
|
|
858
|
+
.onConflictDoNothing(),
|
|
859
|
+
factCacheDelete(db, claimId),
|
|
860
|
+
]);
|
|
861
|
+
deps.logger.error("evaluate.content-refused", { ...scope, reason });
|
|
862
|
+
await reportAlert(deps, `engine.${status.replaceAll("_", "-")}`, { claimId, collectionId, code: err.code, reason }, `engine.${status}:${claimId}`);
|
|
863
|
+
return new NonRetryableError(`${err.code}: ${reason ?? err.message}`);
|
|
864
|
+
}
|
|
865
|
+
case "CONFLICT":
|
|
866
|
+
// The engine holds this claim's decision under a different `kind` or `collectionId` than
|
|
867
|
+
// we just sent — the same claimId reached it through two lanes or scopes. Our bug, never a
|
|
868
|
+
// claim outcome, and no retry changes the stored row: stop, and page it.
|
|
869
|
+
deps.logger.error("evaluate.subject-conflict", scope);
|
|
870
|
+
reportError(err, { lane: "evaluate", step: "evaluate", claimId, collectionId });
|
|
871
|
+
return new NonRetryableError(`${FAILURE.engineConflict}: the engine holds this claim under another subject: ${err.message}`);
|
|
872
|
+
case "RATE_LIMITED":
|
|
873
|
+
// The engine's per-IP limiter said "not now" (a backlog burst): the step's own backoff
|
|
874
|
+
// (1 min doubling) already outlasts its 60 s window, so retry as-is — logged with the
|
|
875
|
+
// engine's `Retry-After` so a throttled backlog is visible, never a permanent failure.
|
|
876
|
+
deps.logger.warn("evaluate.throttled", {
|
|
877
|
+
...scope,
|
|
878
|
+
retryAfterMs: err.retryAfterMs ?? null,
|
|
879
|
+
});
|
|
880
|
+
return err;
|
|
881
|
+
// The three refusals below all come out of the engine's OWN `POST /v1/oracles/register`
|
|
882
|
+
// (decision-engine spec §5/§9), surfacing HERE because `client.ts`'s `registered()` wrapper
|
|
883
|
+
// re-registers whenever its KV "registered" marker (REGISTERED_TTL_SEC, 30d) has expired —
|
|
884
|
+
// i.e. any `decide()` can hit one of these, not just a fresh boot. None pause a collection:
|
|
885
|
+
// unlike `engine-credits`, the engine's `/me` keeps answering `ok` here (billingStatus is a
|
|
886
|
+
// different gate), so `cron/billing.ts`'s auto-resume would never see the fix and un-pause —
|
|
887
|
+
// this is the owner's/operator's fix to make, not a chain-write concern.
|
|
888
|
+
case "NO_SUBSCRIPTION": {
|
|
889
|
+
// The owner has no IXO subscription, or it lapsed — the engine can't find a credit wallet
|
|
890
|
+
// to bill without one. `topUpUrl` is null for a bare "no subscription at all" (nothing to
|
|
891
|
+
// manage a URL for yet) — the kit's own PORTAL_BASE_URL still names somewhere to send them.
|
|
892
|
+
const topUpUrl = err.topUpUrl ?? deps.config.PORTAL_BASE_URL;
|
|
893
|
+
deps.logger.error("evaluate.owner-billing-refused", { ...scope, topUpUrl });
|
|
894
|
+
reportError(err, { lane: "evaluate", step: "evaluate", claimId, collectionId });
|
|
895
|
+
return new NonRetryableError(`Owner has no active IXO subscription: ${err.message}. Subscribe in the portal (${topUpUrl}), then register again.`);
|
|
896
|
+
}
|
|
897
|
+
case "DELEGATION_NOT_FOR_ORACLE":
|
|
898
|
+
// `OWNER_DELEGATION_CAR` is a real, unexpired CAR — just bound (`billing/pay with`) to a
|
|
899
|
+
// DIFFERENT oracle's did:web. Re-registering with the same file only fails the same way.
|
|
900
|
+
deps.logger.error("evaluate.owner-billing-refused", scope);
|
|
901
|
+
reportError(err, { lane: "evaluate", step: "evaluate", claimId, collectionId });
|
|
902
|
+
return new NonRetryableError(`Owner delegation is bound to a different oracle: ${err.message}. Re-mint the CAR for ` +
|
|
903
|
+
"THIS oracle (decision-oracle delegation --for engine --oracle <this did:web>) and " +
|
|
904
|
+
"set it as OWNER_DELEGATION_CAR.");
|
|
905
|
+
default: {
|
|
906
|
+
// A bad/expired CAR is a plain `400 BAD_REQUEST` (owner-delegation.ts's own checks — not a
|
|
907
|
+
// dedicated code), told apart from any other BAD_REQUEST only by its message naming the
|
|
908
|
+
// field this kit actually sends.
|
|
909
|
+
if (err.code === "BAD_REQUEST" && err.message.includes("ownerDelegation")) {
|
|
910
|
+
deps.logger.error("evaluate.owner-billing-refused", scope);
|
|
911
|
+
reportError(err, { lane: "evaluate", step: "evaluate", claimId, collectionId });
|
|
912
|
+
return new NonRetryableError(`Owner delegation rejected: ${err.message}. Re-mint the CAR ` +
|
|
913
|
+
"(decision-oracle delegation --for engine) and register again.");
|
|
914
|
+
}
|
|
915
|
+
return err.retryable ? err : new NonRetryableError(`${err.code}: ${err.message}`);
|
|
916
|
+
}
|
|
917
|
+
}
|
|
918
|
+
}
|
|
919
|
+
/**
|
|
920
|
+
* Facts that don't match the rubric's work order (lib/facts/validate.ts) — the producer's bug,
|
|
921
|
+
* never a claim outcome: the issue list is codes and paths (identifiers), logged and paged so the
|
|
922
|
+
* fix is one grep away, and the error to throw is NonRetryable (a retry would re-run the same
|
|
923
|
+
* producer). The row is already recorded by the caller.
|
|
924
|
+
*/
|
|
925
|
+
invalidFacts(deps, claimId, collectionId, built) {
|
|
926
|
+
deps.logger.error("evaluate.facts-invalid", {
|
|
927
|
+
claimId,
|
|
928
|
+
collectionId,
|
|
929
|
+
rubricId: built.rubricId ?? null,
|
|
930
|
+
issues: built.issues,
|
|
931
|
+
});
|
|
932
|
+
const err = new NonRetryableError(`Facts do not match the rubric's work order: ${built.issues.map((i) => `${i.code} ${i.path}`).join(", ")}`);
|
|
933
|
+
reportError(err, { lane: "evaluate", step: "evaluate", claimId, collectionId });
|
|
934
|
+
return err;
|
|
935
|
+
}
|
|
936
|
+
/**
|
|
937
|
+
* A claim the facts lane could not build for — recorded WITHOUT a decide call (schema.ts
|
|
938
|
+
* `decisions`): `status` names the reason, `explanation` the issues, and nothing will ever be
|
|
939
|
+
* acted on, so `chainStatus` is `skipped` from the start. Then the reason's consequence:
|
|
940
|
+
* `rubric-unusable` is the engine's manifest saying the rubric cannot be bound — the same
|
|
941
|
+
* handling as its decide-time `unusable` (pause the collection; steps.ts), minus the receipt, and
|
|
942
|
+
* the ingest completes; `invalid-facts` is OUR (or the provider's) bug, never a claim outcome —
|
|
943
|
+
* recorded so the claim read says why, then failed loudly, like the engine's own `VALIDATION`
|
|
944
|
+
* refusal this check exists to catch first.
|
|
945
|
+
*/
|
|
946
|
+
async buildFailure(deps, source, db, claim, built) {
|
|
947
|
+
const { claimId, collectionId } = claim;
|
|
948
|
+
const status = BUILD_FAILURE_STATUS[built.reason];
|
|
949
|
+
const rubricId = built.rubricId ?? null;
|
|
950
|
+
const explanation = built.issues.map((i) => `${i.code}: ${i.message} (${i.path})`).join("; ");
|
|
951
|
+
// A first build never cached anything, but a RUBRIC_PIN_MISMATCH rebuild lands here AFTER the
|
|
952
|
+
// first build's connectors ran — the cache dies with the outcome, same as `record`.
|
|
953
|
+
await db.batch([
|
|
954
|
+
db
|
|
955
|
+
.insert(decisions)
|
|
956
|
+
.values({ claimId, collectionId, rubricId, status, explanation, chainStatus: "skipped" })
|
|
957
|
+
.onConflictDoNothing(),
|
|
958
|
+
factCacheDelete(db, claimId),
|
|
959
|
+
]);
|
|
960
|
+
// Only a re-pinned rebuild gets here with a review reserved (the first build is checked before
|
|
961
|
+
// reserving): no receipt will ever come, so it is freed — its cap back too.
|
|
962
|
+
if (isChain(source)) {
|
|
963
|
+
await releaseChainClaim({ ...deps, db }, claimId, built.reason === "invalid-facts" ? "facts_invalid" : "facts_unusable");
|
|
964
|
+
}
|
|
965
|
+
if (built.reason === "invalid-facts")
|
|
966
|
+
throw this.invalidFacts(deps, claimId, collectionId, built);
|
|
967
|
+
await pauseUnusable(source, deps.logger, "evaluate", {
|
|
968
|
+
claimId,
|
|
969
|
+
collectionId,
|
|
970
|
+
rubricId,
|
|
971
|
+
issues: built.issues,
|
|
972
|
+
});
|
|
973
|
+
return { status, verdict: null, resultDigest: null, receiptCid: null };
|
|
974
|
+
}
|
|
975
|
+
/**
|
|
976
|
+
* A terminal failure's class — the API lane's §5 code (lib/api-lane/record.ts `claimErrorCode`,
|
|
977
|
+
* read off the same message the ledger stores), for either lane. Best-effort like the rest of
|
|
978
|
+
* the terminal path.
|
|
979
|
+
*/
|
|
980
|
+
async failureClass(claimId, err) {
|
|
981
|
+
const decided = await getDb(this.env)
|
|
982
|
+
.query.decisions.findFirst({
|
|
983
|
+
columns: { status: true },
|
|
984
|
+
where: eq(decisions.claimId, claimId),
|
|
985
|
+
})
|
|
986
|
+
.catch(() => undefined);
|
|
987
|
+
return claimErrorCode(err instanceof Error ? err.message : String(err), decided?.status ?? null);
|
|
988
|
+
}
|
|
989
|
+
ledgerRow(claimId) {
|
|
990
|
+
return getDb(this.env).query.claimIngests.findFirst({
|
|
991
|
+
where: (t, { eq: eqOp }) => eqOp(t.claimId, claimId),
|
|
992
|
+
});
|
|
993
|
+
}
|
|
994
|
+
/**
|
|
995
|
+
* Upsert this claim's ledger row. `error` is null unless `failed` (schema.ts), so a rerun that
|
|
996
|
+
* succeeds clears the old message.
|
|
997
|
+
*/
|
|
998
|
+
async recordStatus(claimId, event, update) {
|
|
999
|
+
const fields = {
|
|
1000
|
+
status: update.status,
|
|
1001
|
+
collectionId: update.collectionId,
|
|
1002
|
+
instanceId: event.instanceId,
|
|
1003
|
+
error: update.error ?? null,
|
|
1004
|
+
};
|
|
1005
|
+
await getDb(this.env)
|
|
1006
|
+
.insert(claimIngests)
|
|
1007
|
+
.values({ claimId, lane: update.lane, ...fields })
|
|
1008
|
+
.onConflictDoUpdate({ target: claimIngests.claimId, set: fields });
|
|
1009
|
+
}
|
|
1010
|
+
}
|
|
1011
|
+
/** The re-anchored rubric could not be built for — carries the result to be recorded (see `decide`, `buildFailure`). */
|
|
1012
|
+
class BuildFailure extends Error {
|
|
1013
|
+
result;
|
|
1014
|
+
constructor(result) {
|
|
1015
|
+
super(`facts lane: ${result.reason}`);
|
|
1016
|
+
this.result = result;
|
|
1017
|
+
this.name = "BuildFailure";
|
|
1018
|
+
}
|
|
1019
|
+
}
|
|
1020
|
+
//# sourceMappingURL=claim-ingest.js.map
|