@pikku/core 0.12.143 → 0.12.145
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/dist/analytics/analytics.d.ts +14 -0
- package/dist/analytics/analytics.js +14 -0
- package/dist/analytics/analytics.types.d.ts +1 -0
- package/dist/analytics/anonymous-analytics-identity.d.ts +1 -0
- package/dist/analytics/cookie-analytics-identity.d.ts +1 -0
- package/dist/analytics/mint-cookie.d.ts +1 -0
- package/dist/{wirings/channel/channel-middleware-runner.d.ts → channel-middleware-runner.d.ts} +17 -3
- package/dist/{wirings/channel/channel-middleware-runner.js → channel-middleware-runner.js} +24 -8
- package/dist/classification/data-classification.d.ts +13 -0
- package/dist/classification/secret-value.d.ts +7 -0
- package/dist/classification/secret-value.js +7 -0
- package/dist/crypto-utils.d.ts +93 -0
- package/dist/crypto-utils.js +92 -0
- package/dist/dev/hot-reload.d.ts +16 -0
- package/dist/dev/hot-reload.js +16 -1
- package/dist/dev/module-runner.js +7 -3
- package/dist/dev/reload-meta.js +1 -1
- package/dist/errors/error-handler.d.ts +9 -0
- package/dist/errors/error-handler.js +8 -0
- package/dist/errors/errors.d.ts +219 -0
- package/dist/errors/errors.js +227 -0
- package/dist/errors/serialized-error.d.ts +4 -0
- package/dist/function/abort-scope.d.ts +5 -0
- package/dist/function/function-meta.types.d.ts +20 -0
- package/dist/function/function-runner.d.ts +41 -0
- package/dist/function/function-runner.js +57 -11
- package/dist/function/functions.types.d.ts +59 -0
- package/dist/function/functions.types.js +23 -0
- package/dist/function/list.types.d.ts +4 -0
- package/dist/lifecycle.d.ts +12 -1
- package/dist/lifecycle.js +12 -1
- package/dist/middleware/addon-scope-cap.d.ts +4 -0
- package/dist/middleware/addon-scope-cap.js +7 -3
- package/dist/middleware/auth-apikey.js +3 -3
- package/dist/middleware/auth-bearer.js +5 -13
- package/dist/middleware/auth-cookie.js +3 -3
- package/dist/middleware/middleware-factories.d.ts +17 -0
- package/dist/middleware/middleware-factories.js +17 -0
- package/dist/middleware/middleware.types.d.ts +23 -0
- package/dist/middleware/remote-auth.d.ts +15 -0
- package/dist/middleware/remote-auth.js +18 -3
- package/dist/middleware/remote-jobs-secret.js +2 -10
- package/dist/middleware-runner.d.ts +7 -0
- package/dist/middleware-runner.js +23 -7
- package/dist/permissions.d.ts +13 -0
- package/dist/permissions.js +13 -0
- package/dist/pikku-state.d.ts +49 -0
- package/dist/pikku-state.js +49 -0
- package/dist/remote.js +20 -5
- package/dist/schema.d.ts +36 -0
- package/dist/schema.js +36 -0
- package/dist/services/agent-run-state-service.d.ts +8 -0
- package/dist/services/agent-runner-service.d.ts +24 -0
- package/dist/services/agent-storage-service.d.ts +8 -0
- package/dist/services/ai-embedding-service.d.ts +4 -0
- package/dist/services/audit-service.d.ts +48 -0
- package/dist/services/audit-service.js +22 -0
- package/dist/services/content-service.d.ts +34 -0
- package/dist/services/credential-wire-service.d.ts +9 -0
- package/dist/services/credential-wire-service.js +9 -0
- package/dist/services/deployment-service.d.ts +14 -0
- package/dist/services/email-service.d.ts +20 -0
- package/dist/services/email-template.d.ts +24 -0
- package/dist/services/email-template.js +12 -0
- package/dist/services/file-scenario-run-store.d.ts +5 -0
- package/dist/services/file-scenario-run-store.js +4 -0
- package/dist/services/gateway-service.d.ts +5 -0
- package/dist/services/in-memory-agent-run-state-service.d.ts +5 -0
- package/dist/services/in-memory-agent-run-state-service.js +5 -0
- package/dist/services/in-memory-lease-service.d.ts +5 -0
- package/dist/services/in-memory-lease-service.js +5 -0
- package/dist/services/in-memory-session-store.d.ts +4 -0
- package/dist/services/in-memory-session-store.js +4 -0
- package/dist/services/incoming-webhook-queue.d.ts +2 -0
- package/dist/services/incoming-webhook-queue.js +2 -0
- package/dist/services/incoming-webhook-service.d.ts +9 -1
- package/dist/services/incoming-webhook-service.js +1 -1
- package/dist/services/index.d.ts +1 -5
- package/dist/services/index.js +1 -5
- package/dist/services/jwt-service.d.ts +8 -0
- package/dist/services/lease-service.d.ts +5 -0
- package/dist/services/lease-service.js +1 -0
- package/dist/services/local-content-request-handler.d.ts +20 -0
- package/dist/services/local-content-request-handler.js +11 -0
- package/dist/services/local-content.d.ts +45 -0
- package/dist/services/local-content.js +35 -0
- package/dist/services/local-credential-service.d.ts +5 -0
- package/dist/services/local-credential-service.js +5 -0
- package/dist/services/local-email-service.d.ts +7 -0
- package/dist/services/local-email-service.js +7 -0
- package/dist/services/local-secrets.d.ts +8 -0
- package/dist/services/local-secrets.js +8 -0
- package/dist/services/local-variables.d.ts +6 -0
- package/dist/services/local-variables.js +6 -0
- package/dist/services/logger.d.ts +4 -0
- package/dist/services/logger.js +4 -0
- package/dist/services/meta-service.d.ts +38 -0
- package/dist/services/meta-service.js +6 -0
- package/dist/services/queue-webhook-service.d.ts +19 -0
- package/dist/services/queue-webhook-service.js +19 -0
- package/dist/services/remote-jobs.d.ts +8 -13
- package/dist/services/remote-jobs.js +3 -54
- package/dist/services/scenario-cookie-jar.d.ts +4 -0
- package/dist/services/scheduler-service.d.ts +13 -0
- package/dist/services/scheduler-service.js +8 -0
- package/dist/services/schema-service.d.ts +9 -0
- package/dist/services/scope-service.d.ts +10 -0
- package/dist/services/scoped-secret-service.d.ts +5 -0
- package/dist/services/scoped-secret-service.js +5 -0
- package/dist/services/secret-host-binding.d.ts +5 -0
- package/dist/services/secret-host-binding.js +5 -0
- package/dist/services/secret-service.d.ts +19 -1
- package/dist/services/secretless.d.ts +6 -0
- package/dist/services/secretless.js +6 -0
- package/dist/services/session-store.d.ts +5 -0
- package/dist/services/stub-tracker.d.ts +1 -0
- package/dist/services/temporary-file-service.d.ts +9 -0
- package/dist/services/temporary-file-service.js +9 -0
- package/dist/services/trigger-service.d.ts +4 -0
- package/dist/services/trigger-source-store.d.ts +13 -0
- package/dist/services/trigger-source-store.js +7 -0
- package/dist/services/typed-credential-service.d.ts +6 -0
- package/dist/services/typed-credential-service.js +5 -0
- package/dist/services/typed-secret-service.d.ts +12 -0
- package/dist/services/typed-secret-service.js +11 -0
- package/dist/services/typed-variables-service.d.ts +1 -0
- package/dist/services/user-session-service.d.ts +31 -1
- package/dist/services/user-session-service.js +29 -3
- package/dist/services/v8-coverage-service.d.ts +27 -0
- package/dist/services/v8-coverage-service.js +5 -0
- package/dist/services/variables-service.d.ts +8 -0
- package/dist/services/virtual-user-sign-in.d.ts +1 -0
- package/dist/services/virtual-user-statement.d.ts +8 -0
- package/dist/services/virtual-user-statement.js +4 -0
- package/dist/services/webhook-service.d.ts +25 -0
- package/dist/services/webhook-service.js +15 -0
- package/dist/services/workflow-service.d.ts +6 -0
- package/dist/test-utils.js +1 -1
- package/dist/testing/service-tests.d.ts +4 -0
- package/dist/time-utils.d.ts +15 -0
- package/dist/time-utils.js +14 -0
- package/dist/types/core.types.d.ts +80 -0
- package/dist/types/state.types.d.ts +4 -0
- package/dist/utils/hmac.d.ts +3 -0
- package/dist/utils/safe-fetch.d.ts +14 -0
- package/dist/utils/safe-fetch.js +13 -0
- package/dist/utils/stable-stringify.d.ts +11 -0
- package/dist/utils/stable-stringify.js +33 -0
- package/dist/utils.d.ts +28 -0
- package/dist/utils.js +22 -0
- package/dist/version.d.ts +7 -0
- package/dist/version.js +7 -0
- package/dist/wirings/addon/define-screens.d.ts +2 -0
- package/dist/wirings/addon/remote-addon-auth.d.ts +9 -0
- package/dist/wirings/addon/remote-addon-auth.js +5 -0
- package/dist/wirings/addon/wire-addon.d.ts +4 -0
- package/dist/wirings/addon/wire-remote-addon.d.ts +1 -0
- package/dist/wirings/agent/agent-agui.d.ts +14 -5
- package/dist/wirings/agent/agent-agui.js +17 -6
- package/dist/wirings/agent/agent-helpers.d.ts +61 -1
- package/dist/wirings/agent/agent-helpers.js +62 -2
- package/dist/wirings/agent/agent-interrupt.d.ts +5 -0
- package/dist/wirings/agent/agent-output.d.ts +20 -0
- package/dist/wirings/agent/agent-output.js +69 -0
- package/dist/wirings/agent/agent-prepare.d.ts +41 -0
- package/dist/wirings/agent/agent-prepare.js +38 -2
- package/dist/wirings/agent/agent-registry.d.ts +8 -0
- package/dist/wirings/agent/agent-registry.js +10 -4
- package/dist/wirings/agent/agent-runner.d.ts +33 -0
- package/dist/wirings/agent/agent-runner.js +40 -7
- package/dist/wirings/agent/agent-stream.d.ts +30 -0
- package/dist/wirings/agent/agent-stream.js +33 -11
- package/dist/wirings/agent/agent.types.d.ts +43 -0
- package/dist/wirings/agent/voice-input.d.ts +12 -0
- package/dist/wirings/agent/voice-input.js +12 -0
- package/dist/wirings/agent/voice-output.d.ts +14 -0
- package/dist/wirings/agent/voice-output.js +10 -0
- package/dist/wirings/agent-scorer/agent-scorer-judge.js +1 -2
- package/dist/wirings/agent-scorer/agent-scorer-registry.d.ts +10 -0
- package/dist/wirings/agent-scorer/agent-scorer-registry.js +10 -0
- package/dist/wirings/agent-scorer/agent-scorer-snapshots.d.ts +1 -0
- package/dist/wirings/agent-scorer/agent-scorer-snapshots.js +1 -0
- package/dist/wirings/agent-scorer/agent-scorer.types.d.ts +7 -0
- package/dist/wirings/channel/channel-common.js +1 -1
- package/dist/wirings/channel/channel-rpc.types.d.ts +5 -0
- package/dist/wirings/channel/channel-runner.d.ts +22 -0
- package/dist/wirings/channel/channel-runner.js +22 -0
- package/dist/wirings/channel/channel-store.d.ts +8 -0
- package/dist/wirings/channel/channel-store.js +7 -0
- package/dist/wirings/channel/channel.types.d.ts +18 -0
- package/dist/wirings/channel/define-channel-routes.d.ts +5 -0
- package/dist/wirings/channel/define-channel-routes.js +5 -0
- package/dist/wirings/channel/eventhub-service.d.ts +9 -0
- package/dist/wirings/channel/eventhub-store.d.ts +1 -0
- package/dist/wirings/channel/eventhub-store.js +1 -0
- package/dist/wirings/channel/index.d.ts +1 -1
- package/dist/wirings/channel/index.js +1 -1
- package/dist/wirings/channel/local/local-channel-handler.d.ts +1 -0
- package/dist/wirings/channel/local/local-channel-handler.js +1 -0
- package/dist/wirings/channel/local/local-channel-runner.d.ts +13 -0
- package/dist/wirings/channel/local/local-channel-runner.js +13 -0
- package/dist/wirings/channel/local/local-eventhub-service.d.ts +1 -0
- package/dist/wirings/channel/local/local-eventhub-service.js +1 -0
- package/dist/wirings/channel/log-channels.d.ts +1 -0
- package/dist/wirings/channel/log-channels.js +1 -0
- package/dist/wirings/channel/pikku-abstract-channel-handler.d.ts +5 -0
- package/dist/wirings/channel/pikku-abstract-channel-handler.js +5 -0
- package/dist/wirings/channel/serverless/serverless-channel-runner.d.ts +32 -0
- package/dist/wirings/channel/serverless/serverless-channel-runner.js +31 -0
- package/dist/wirings/cli/channel/cli-channel-runner.d.ts +8 -0
- package/dist/wirings/cli/channel/cli-channel-runner.js +8 -0
- package/dist/wirings/cli/channel/cli-raw-channel-runner.d.ts +1 -0
- package/dist/wirings/cli/cli-runner.d.ts +43 -0
- package/dist/wirings/cli/cli-runner.js +43 -0
- package/dist/wirings/cli/cli.types.d.ts +4 -0
- package/dist/wirings/cli/command-parser.d.ts +13 -0
- package/dist/wirings/cli/command-parser.js +16 -0
- package/dist/wirings/credential/credential-overrides.d.ts +1 -0
- package/dist/wirings/credential/credential.types.d.ts +7 -0
- package/dist/wirings/credential/validate-credential-definitions.d.ts +7 -0
- package/dist/wirings/credential/validate-credential-definitions.js +7 -0
- package/dist/wirings/flag/cached-flag-source.d.ts +1 -0
- package/dist/wirings/flag/flag.types.d.ts +3 -0
- package/dist/wirings/gateway/gateway-runner.d.ts +23 -0
- package/dist/wirings/gateway/gateway-runner.js +23 -0
- package/dist/wirings/gateway/gateway.types.d.ts +3 -0
- package/dist/wirings/gateway/local-gateway-service.d.ts +10 -0
- package/dist/{services → wirings/gateway}/local-gateway-service.js +6 -2
- package/dist/wirings/http/http-routes.d.ts +21 -0
- package/dist/wirings/http/http-routes.js +11 -0
- package/dist/wirings/http/http-runner.d.ts +71 -0
- package/dist/wirings/http/http-runner.js +73 -5
- package/dist/wirings/http/http.types.d.ts +27 -0
- package/dist/wirings/http/index.d.ts +1 -0
- package/dist/wirings/http/index.js +1 -0
- package/dist/wirings/http/log-http-routes.d.ts +1 -0
- package/dist/wirings/http/log-http-routes.js +1 -0
- package/dist/wirings/http/merge-request-data.d.ts +12 -0
- package/dist/wirings/http/merge-request-data.js +42 -0
- package/dist/wirings/http/pikku-fetch-http-request.d.ts +1 -0
- package/dist/wirings/http/pikku-fetch-http-request.js +3 -32
- package/dist/wirings/http/pikku-fetch-http-response.d.ts +1 -0
- package/dist/wirings/http/pikku-fetch-http-response.js +1 -0
- package/dist/wirings/http/routers/http-router.d.ts +6 -0
- package/dist/wirings/http/routers/http-router.js +6 -0
- package/dist/wirings/http/web-request.d.ts +17 -0
- package/dist/wirings/http/web-request.js +17 -0
- package/dist/wirings/mcp/mcp-endpoint-registry.d.ts +7 -0
- package/dist/wirings/mcp/mcp-endpoint-registry.js +7 -0
- package/dist/wirings/mcp/mcp-runner.d.ts +63 -0
- package/dist/wirings/mcp/mcp-runner.js +62 -0
- package/dist/wirings/mcp/mcp.types.d.ts +12 -0
- package/dist/wirings/node/node.types.d.ts +4 -0
- package/dist/wirings/oauth2/oauth2.types.d.ts +2 -0
- package/dist/{services → wirings/queue}/in-memory-queue-service.d.ts +9 -1
- package/dist/{services → wirings/queue}/in-memory-queue-service.js +9 -1
- package/dist/wirings/queue/index.d.ts +1 -0
- package/dist/wirings/queue/index.js +1 -0
- package/dist/wirings/queue/queue-identity.js +2 -14
- package/dist/wirings/queue/queue-runner.d.ts +37 -0
- package/dist/wirings/queue/queue-runner.js +37 -0
- package/dist/wirings/queue/queue.types.d.ts +35 -0
- package/dist/wirings/queue/register-queue-helper.d.ts +12 -0
- package/dist/wirings/queue/register-queue-helper.js +11 -0
- package/dist/wirings/queue/remote-queue-job.d.ts +11 -0
- package/dist/wirings/queue/remote-queue-job.js +41 -0
- package/dist/wirings/queue/validate-worker-config.d.ts +1 -0
- package/dist/wirings/role/role.types.d.ts +3 -0
- package/dist/wirings/rpc/rpc-runner.d.ts +24 -0
- package/dist/wirings/rpc/rpc-runner.js +37 -2
- package/dist/wirings/rpc/rpc-types.d.ts +2 -0
- package/dist/wirings/scheduler/index.d.ts +1 -0
- package/dist/wirings/scheduler/index.js +1 -0
- package/dist/wirings/scheduler/log-schedulers.d.ts +1 -0
- package/dist/wirings/scheduler/log-schedulers.js +1 -0
- package/dist/wirings/scheduler/remote-scheduled-job.d.ts +11 -0
- package/dist/wirings/scheduler/remote-scheduled-job.js +20 -0
- package/dist/wirings/scheduler/scheduler-runner.d.ts +29 -0
- package/dist/wirings/scheduler/scheduler-runner.js +28 -0
- package/dist/wirings/scheduler/scheduler.types.d.ts +3 -0
- package/dist/wirings/scope/scope.types.d.ts +5 -0
- package/dist/wirings/secret/index.d.ts +2 -2
- package/dist/wirings/secret/index.js +1 -1
- package/dist/wirings/secret/secret.types.d.ts +26 -1
- package/dist/wirings/secret/secret.types.js +1 -0
- package/dist/wirings/secret/validate-secret-definitions.d.ts +8 -0
- package/dist/wirings/secret/validate-secret-definitions.js +15 -0
- package/dist/wirings/trigger/in-memory-trigger-service.d.ts +11 -0
- package/dist/{services → wirings/trigger}/in-memory-trigger-service.js +10 -3
- package/dist/wirings/trigger/index.d.ts +1 -1
- package/dist/wirings/trigger/pikku-trigger-service.d.ts +8 -3
- package/dist/wirings/trigger/pikku-trigger-service.js +14 -3
- package/dist/wirings/trigger/trigger-runner.d.ts +27 -2
- package/dist/wirings/trigger/trigger-runner.js +35 -2
- package/dist/wirings/trigger/trigger.types.d.ts +26 -4
- package/dist/wirings/trigger/webhook-source-runner.d.ts +24 -0
- package/dist/wirings/trigger/webhook-source-runner.js +19 -0
- package/dist/wirings/trigger/webhook-source.types.d.ts +12 -2
- package/dist/wirings/trigger/webhook-source.types.js +1 -1
- package/dist/wirings/variable/validate-variable-definitions.d.ts +7 -0
- package/dist/wirings/variable/validate-variable-definitions.js +7 -0
- package/dist/wirings/variable/variable.types.d.ts +7 -0
- package/dist/wirings/virtual-user/conversation/conversation.types.d.ts +5 -0
- package/dist/wirings/virtual-user/conversation/run-conversation.d.ts +6 -0
- package/dist/wirings/virtual-user/conversation/run-conversation.js +1 -1
- package/dist/{services → wirings/virtual-user}/http-virtual-users.d.ts +4 -3
- package/dist/{services → wirings/virtual-user}/http-virtual-users.js +6 -6
- package/dist/wirings/virtual-user/index.d.ts +1 -1
- package/dist/wirings/virtual-user/index.js +1 -1
- package/dist/wirings/virtual-user/run-virtual-user.d.ts +2 -1
- package/dist/wirings/virtual-user/run-virtual-user.js +1 -14
- package/dist/wirings/virtual-user/virtual-user-declaration.types.d.ts +4 -0
- package/dist/wirings/virtual-user/virtual-user-scaffold.d.ts +10 -1
- package/dist/wirings/virtual-user/virtual-user-scaffold.js +5 -0
- package/dist/wirings/virtual-user/virtual-user-schedule.d.ts +5 -0
- package/dist/wirings/virtual-user/virtual-user-schedule.js +1 -0
- package/dist/wirings/virtual-user/virtual-user-target.d.ts +1 -0
- package/dist/wirings/webhook/define-outgoing-webhook.d.ts +20 -0
- package/dist/wirings/webhook/define-outgoing-webhook.js +9 -0
- package/dist/wirings/workflow/dsl/workflow-dsl.types.d.ts +8 -4
- package/dist/wirings/workflow/dsl/workflow-runner.d.ts +7 -0
- package/dist/wirings/workflow/dsl/workflow-runner.js +7 -0
- package/dist/wirings/workflow/feature.d.ts +12 -0
- package/dist/wirings/workflow/feature.js +12 -0
- package/dist/wirings/workflow/graph/graph-node.d.ts +5 -0
- package/dist/wirings/workflow/graph/graph-node.js +5 -0
- package/dist/wirings/workflow/graph/template.d.ts +6 -0
- package/dist/wirings/workflow/graph/template.js +5 -0
- package/dist/wirings/workflow/graph/wire-workflow-graph.d.ts +12 -0
- package/dist/wirings/workflow/graph/wire-workflow-graph.js +10 -0
- package/dist/wirings/workflow/graph/workflow-graph.types.d.ts +11 -0
- package/dist/wirings/workflow/graph/workflow-graph.types.js +1 -0
- package/dist/{services → wirings/workflow}/in-memory-workflow-service.d.ts +8 -3
- package/dist/{services → wirings/workflow}/in-memory-workflow-service.js +9 -4
- package/dist/wirings/workflow/pikku-scenario-service.d.ts +1 -1
- package/dist/wirings/workflow/pikku-scenario-service.js +2 -2
- package/dist/wirings/workflow/pikku-workflow-service.d.ts +1 -0
- package/dist/wirings/workflow/pikku-workflow-service.js +1 -0
- package/dist/wirings/workflow/run-timeline.d.ts +21 -0
- package/dist/wirings/workflow/run-timeline.js +15 -7
- package/dist/wirings/workflow/scenario-coverage.d.ts +1 -0
- package/dist/wirings/workflow/scenario-poll.d.ts +1 -0
- package/dist/wirings/workflow/scenario-prose.d.ts +6 -0
- package/dist/wirings/workflow/scenario-prose.js +6 -0
- package/dist/wirings/workflow/scenario-run.types.d.ts +3 -0
- package/dist/wirings/workflow/scenario-step.types.d.ts +1 -0
- package/dist/wirings/workflow/scenario-step.types.js +1 -0
- package/dist/wirings/workflow/scenario-surface.js +1 -13
- package/dist/wirings/workflow/scenario.types.d.ts +6 -0
- package/dist/wirings/workflow/workflow-approval-policy.d.ts +6 -0
- package/dist/wirings/workflow/workflow-approval-policy.js +6 -0
- package/dist/wirings/workflow/workflow-constants.d.ts +7 -1
- package/dist/wirings/workflow/workflow-constants.js +10 -1
- package/dist/wirings/workflow/workflow-errors.d.ts +13 -0
- package/dist/wirings/workflow/workflow-errors.js +13 -0
- package/dist/wirings/workflow/workflow-invocation-id.d.ts +4 -0
- package/dist/wirings/workflow/workflow-invocation-id.js +4 -0
- package/dist/wirings/workflow/workflow-queue-workers.d.ts +3 -0
- package/dist/wirings/workflow/workflow-run-ownership.d.ts +1 -0
- package/dist/wirings/workflow/workflow-run-ownership.js +1 -0
- package/dist/wirings/workflow/workflow-status-stream.d.ts +1 -0
- package/dist/wirings/workflow/workflow-unwind-plan.js +2 -7
- package/dist/wirings/workflow/workflow.types.d.ts +40 -0
- package/package.json +26 -9
- package/CHANGELOG.md +0 -6978
- package/dist/services/in-memory-trigger-service.d.ts +0 -4
- package/dist/services/local-gateway-service.d.ts +0 -6
- package/dist/utils/hash.d.ts +0 -2
- package/dist/utils/hash.js +0 -23
- package/knowledge/decisions/index.md +0 -19
- package/knowledge/decisions/internals/a-credential-name-declared-twice-must-agree-on-schema-and-type.md +0 -29
- package/knowledge/decisions/internals/a-grant-can-name-a-scope-declared-without-its-addon.md +0 -29
- package/knowledge/decisions/internals/a-held-run-is-woken-later-not-retried.md +0 -28
- package/knowledge/decisions/internals/a-latency-budget-is-asserted-by-its-cause.md +0 -32
- package/knowledge/decisions/internals/a-non-streaming-agent-run-registers-with-agentrunstate-too.md +0 -22
- package/knowledge/decisions/internals/a-reset-suite-makes-the-dev-seed-the-fixture.md +0 -50
- package/knowledge/decisions/internals/a-resumed-agent-turn-is-as-interruptible-as-the-first.md +0 -20
- package/knowledge/decisions/internals/a-scenario-step-template-is-offered-unfilled.md +0 -21
- package/knowledge/decisions/internals/a-scheduled-task-writes-its-caller-session-before-it-runs.md +0 -22
- package/knowledge/decisions/internals/a-secret-set-in-memory-shadows-the-variable-of-the-same-name.md +0 -28
- package/knowledge/decisions/internals/a-secret-that-fails-to-decrypt-fails-the-whole-read.md +0 -49
- package/knowledge/decisions/internals/a-virtual-user-acts-through-invokeraw-so-a-refusal-is-data.md +0 -32
- package/knowledge/decisions/internals/a-virtual-user-cadence-is-a-row-not-a-timer.md +0 -66
- package/knowledge/decisions/internals/a-virtual-user-converse-signs-in-before-its-first-turn.md +0 -24
- package/knowledge/decisions/internals/a-virtual-user-decides-whether-to-trust-memory-once-per-turn.md +0 -21
- package/knowledge/decisions/internals/a-virtual-user-email-is-computed-with-the-run-id-as-a-sub-address.md +0 -34
- package/knowledge/decisions/internals/a-virtual-user-run-is-not-a-workflow-but-it-needs-a-trigger.md +0 -65
- package/knowledge/decisions/internals/a-wall-clock-threshold-is-a-load-test-in-disguise.md +0 -49
- package/knowledge/decisions/internals/a-workflow-wire-is-built-from-the-run-not-from-the-rpc-service.md +0 -45
- package/knowledge/decisions/internals/addon-package-roots-resolve-by-walking-node-module-search-paths.md +0 -26
- package/knowledge/decisions/internals/addon-pikku-meta-ships-at-the-package-root-or-under-dist.md +0 -32
- package/knowledge/decisions/internals/addon-singleton-services-are-cached-per-namespace-not-per-package.md +0 -33
- package/knowledge/decisions/internals/addon-workflow-names-are-prefixed-with-the-consumer-namespace.md +0 -28
- package/knowledge/decisions/internals/agent-agui-bridge-obeys-the-client-ordering-contract.md +0 -29
- package/knowledge/decisions/internals/agent-audio-chunks-carry-the-format-the-provider-returned.md +0 -20
- package/knowledge/decisions/internals/agent-context-waits-for-a-tool-result-still-being-written.md +0 -21
- package/knowledge/decisions/internals/agent-credential-suspensions-hide-the-tool-result.md +0 -26
- package/knowledge/decisions/internals/agent-delegate-and-supervise-hide-different-text.md +0 -26
- package/knowledge/decisions/internals/agent-llm-tool-arguments-have-nulls-stripped.md +0 -23
- package/knowledge/decisions/internals/agent-model-config-stays-a-single-resolution-seam.md +0 -25
- package/knowledge/decisions/internals/agent-onerror-hooks-cannot-change-the-failure.md +0 -22
- package/knowledge/decisions/internals/agent-runner-methods-must-keep-their-receiver.md +0 -22
- package/knowledge/decisions/internals/agent-speech-travels-as-a-custom-agui-event.md +0 -22
- package/knowledge/decisions/internals/agent-stream-persistence-is-best-effort.md +0 -27
- package/knowledge/decisions/internals/agent-sub-agents-inherit-the-parent-context-block.md +0 -26
- package/knowledge/decisions/internals/agent-tool-execute-failures-are-logged-unconditionally.md +0 -25
- package/knowledge/decisions/internals/agent-voice-input-transcribes-audio-parts-in-place.md +0 -22
- package/knowledge/decisions/internals/agent-working-memory-is-persisted-only-when-valid.md +0 -25
- package/knowledge/decisions/internals/an-addon-scope-root-loses-to-a-root-the-host-already-declares.md +0 -39
- package/knowledge/decisions/internals/an-agent-interrupt-is-not-a-failure.md +0 -23
- package/knowledge/decisions/internals/an-agent-is-offered-under-its-registry-key-and-only-within-the-virtual-users-scopes.md +0 -27
- package/knowledge/decisions/internals/an-agent-run-owned-by-another-instance-says-so.md +0 -25
- package/knowledge/decisions/internals/an-agent-stream-send-must-return-the-inner-sends-promise.md +0 -22
- package/knowledge/decisions/internals/an-empty-text-part-is-omitted-from-an-agent-message.md +0 -20
- package/knowledge/decisions/internals/an-empty-transcript-is-not-recorded.md +0 -22
- package/knowledge/decisions/internals/an-oauth2-credential-implies-an-optional-app-secret.md +0 -26
- package/knowledge/decisions/internals/an-unref-d-timer-cannot-be-awaited-under-node-test.md +0 -66
- package/knowledge/decisions/internals/analytics-identity-resolvers-run-in-declared-order.md +0 -22
- package/knowledge/decisions/internals/channel-message-handlers-accept-three-config-shapes.md +0 -30
- package/knowledge/decisions/internals/channel-middleware-caches-only-statically-resolved-middleware.md +0 -31
- package/knowledge/decisions/internals/channel-state-accessors-are-unsound-generics-that-every-implementation-asserts.md +0 -33
- package/knowledge/decisions/internals/channel-state-is-per-socket-session-state-is-per-user.md +0 -29
- package/knowledge/decisions/internals/channel-user-id-is-persisted-after-onconnect-middleware-runs.md +0 -28
- package/knowledge/decisions/internals/cli-option-names-are-camelcase-in-state-and-kebab-on-the-command-line.md +0 -27
- package/knowledge/decisions/internals/cli-parse-errors-are-routed-by-message-prefix.md +0 -28
- package/knowledge/decisions/internals/cli-stdout-is-reserved-for-machine-readable-output.md +0 -34
- package/knowledge/decisions/internals/cli-unknown-long-options-warn-instead-of-failing.md +0 -29
- package/knowledge/decisions/internals/core-column-form-is-an-axis-of-its-own.md +0 -84
- package/knowledge/decisions/internals/core-data-classification-brand-is-an-optional-property.md +0 -41
- package/knowledge/decisions/internals/core-function-runner-restores-the-wire-fields-it-overwrites.md +0 -44
- package/knowledge/decisions/internals/core-hot-reload-merges-generated-meta-never-replaces-it.md +0 -39
- package/knowledge/decisions/internals/core-hot-reload-owns-its-module-registry.md +0 -42
- package/knowledge/decisions/internals/core-middleware-order-is-scope-then-priority.md +0 -39
- package/knowledge/decisions/internals/core-schema-defaults-apply-on-every-transport.md +0 -43
- package/knowledge/decisions/internals/core-scopes-are-an-and-gate-separate-from-permissions.md +0 -38
- package/knowledge/decisions/internals/core-state-is-a-global-map-written-only-at-registration-time.md +0 -44
- package/knowledge/decisions/internals/email-meta-is-read-uncached-because-codegen-rewrites-it-mid-session.md +0 -27
- package/knowledge/decisions/internals/feature-flag-declarations-refuse-an-empty-anyof-and-conflicting-scopes.md +0 -22
- package/knowledge/decisions/internals/feature-flags-fail-open-and-never-enforce-access.md +0 -28
- package/knowledge/decisions/internals/flag-sync-rewrites-only-the-declared-text.md +0 -24
- package/knowledge/decisions/internals/gateway-adapters-resolve-lazily-and-are-promise-cached.md +0 -32
- package/knowledge/decisions/internals/gateway-listener-middleware-runs-without-an-rpc-on-the-wire.md +0 -43
- package/knowledge/decisions/internals/gateway-webhook-challenges-echo-bytes-not-json.md +0 -28
- package/knowledge/decisions/internals/gateway-wiring-is-a-meta-wiring-over-http-and-channels.md +0 -31
- package/knowledge/decisions/internals/generated-src-paths-in-pikku-meta-are-absolute.md +0 -26
- package/knowledge/decisions/internals/global-middleware-resolves-from-the-root-namespace-too.md +0 -32
- package/knowledge/decisions/internals/hot-reload-reads-the-changed-source-never-a-compiled-copy.md +0 -38
- package/knowledge/decisions/internals/hot-reload-writes-into-the-function-map-captured-at-startup.md +0 -26
- package/knowledge/decisions/internals/http-request-bodies-are-read-once-and-shared.md +0 -32
- package/knowledge/decisions/internals/http-route-groups-cascade-config-in-a-fixed-order.md +0 -28
- package/knowledge/decisions/internals/http-router-matches-normalized-paths-but-returns-registered-ones.md +0 -30
- package/knowledge/decisions/internals/http-runner-logs-through-a-trace-scoped-logger-functions-do-not.md +0 -26
- package/knowledge/decisions/internals/http-set-cookie-headers-are-appended-never-joined.md +0 -28
- package/knowledge/decisions/internals/http-sse-streams-flush-headers-only-after-middleware.md +0 -32
- package/knowledge/decisions/internals/http-wiring-without-metadata-is-skipped-not-fatal.md +0 -26
- package/knowledge/decisions/internals/in-a-scenario-a-4xx-is-data-not-an-exception.md +0 -25
- package/knowledge/decisions/internals/in-memory-workflow-history-aliases-the-live-step-object.md +0 -26
- package/knowledge/decisions/internals/index.md +0 -182
- package/knowledge/decisions/internals/istanbul-statement-counts-attach-to-the-start-line-only.md +0 -25
- package/knowledge/decisions/internals/local-trigger-and-gateway-services-assume-a-single-process.md +0 -26
- package/knowledge/decisions/internals/mcp-wire-names-are-assigned-over-the-whole-registry.md +0 -39
- package/knowledge/decisions/internals/node-only-builtins-are-imported-dynamically.md +0 -24
- package/knowledge/decisions/internals/one-project-shape-check-two-validators.md +0 -53
- package/knowledge/decisions/internals/only-exposed-functions-enter-a-virtual-user-catalogue.md +0 -21
- package/knowledge/decisions/internals/queue-group-concurrency-keeps-one-shared-queue-fair.md +0 -28
- package/knowledge/decisions/internals/queue-jobs-always-carry-an-explicit-attempts-count.md +0 -27
- package/knowledge/decisions/internals/remote-addons-dispatch-over-http-instead-of-local-meta.md +0 -31
- package/knowledge/decisions/internals/role-names-cannot-contain-the-scope-separator.md +0 -30
- package/knowledge/decisions/internals/rpc-names-resolve-through-package-scope-before-root.md +0 -32
- package/knowledge/decisions/internals/scenario-agent-calls-sign-in-on-401-only.md +0 -31
- package/knowledge/decisions/internals/scenario-given-and-when-are-sugar-but-then-is-not.md +0 -24
- package/knowledge/decisions/internals/scenario-meta-lives-apart-from-app-meta-but-merges-when-read-off-disk.md +0 -26
- package/knowledge/decisions/internals/scenario-steps-return-drained-response-records.md +0 -27
- package/knowledge/decisions/internals/scenarios-live-in-files-named-for-them.md +0 -48
- package/knowledge/decisions/internals/scope-roots-may-be-co-declared-by-an-addon-and-its-host-app.md +0 -30
- package/knowledge/decisions/internals/serverless-channel-disconnect-must-tolerate-a-missing-channel.md +0 -28
- package/knowledge/decisions/internals/side-effects-are-an-allowlist-not-a-boolean.md +0 -34
- package/knowledge/decisions/internals/speech-synthesis-picks-a-voice-per-sentence-and-warns-once.md +0 -24
- package/knowledge/decisions/internals/the-agent-done-event-goes-through-the-middleware-and-is-awaited.md +0 -26
- package/knowledge/decisions/internals/the-api-report-pins-members-not-just-names.md +0 -43
- package/knowledge/decisions/internals/the-core-scope-validator-refuses-separator-wildcard-and-empty-segments.md +0 -22
- package/knowledge/decisions/internals/the-dev-queue-copies-prod-timing-and-serialization-semantics.md +0 -30
- package/knowledge/decisions/internals/the-ecosystem-entry-point-carries-the-adapter-surface.md +0 -83
- package/knowledge/decisions/internals/the-embedding-model-is-pinned-per-service-and-doc-query-embedding-is-split.md +0 -29
- package/knowledge/decisions/internals/the-in-memory-workflow-service-is-inline-only-and-single-process.md +0 -27
- package/knowledge/decisions/internals/the-kek-salt-is-scoped-to-the-key-version.md +0 -40
- package/knowledge/decisions/internals/the-mcp-handshake-is-challenged-only-when-every-target-is-gated.md +0 -29
- package/knowledge/decisions/internals/the-middleware-resolution-cache-is-deliberately-unbounded.md +0 -40
- package/knowledge/decisions/internals/the-per-invocation-rpc-view-is-a-class.md +0 -40
- package/knowledge/decisions/internals/the-pikku-user-id-resolves-in-a-fixed-order.md +0 -24
- package/knowledge/decisions/internals/the-runner-resolves-wire-services-itself.md +0 -31
- package/knowledge/decisions/internals/the-schema-service-is-never-stubbed.md +0 -26
- package/knowledge/decisions/internals/the-transcript-event-is-sent-ahead-of-the-run.md +0 -25
- package/knowledge/decisions/internals/the-virtual-user-catalogue-is-the-only-gate-on-what-may-be-called.md +0 -21
- package/knowledge/decisions/internals/the-virtual-user-prompt-says-json-because-of-json-object-mode.md +0 -22
- package/knowledge/decisions/internals/the-virtual-user-runtime-is-exported-from-the-virtual-user-entry-point.md +0 -28
- package/knowledge/decisions/internals/the-worker-disposition-is-the-one-that-is-not-testing.md +0 -22
- package/knowledge/decisions/internals/thread-history-records-the-transcript-not-the-audio.md +0 -25
- package/knowledge/decisions/internals/trigger-declaration-is-split-from-trigger-source.md +0 -33
- package/knowledge/decisions/internals/typed-secret-service-caches-for-the-process-lifetime.md +0 -26
- package/knowledge/decisions/internals/validate-checks-virtual-users-through-a-shared-module.md +0 -43
- package/knowledge/decisions/internals/validate-runs-checks-by-precondition.md +0 -115
- package/knowledge/decisions/internals/virtual-user-conversation-drives-the-target-through-a-transport-seam.md +0 -24
- package/knowledge/decisions/internals/virtual-user-conversation-verdicts-are-llm-self-evaluations.md +0 -25
- package/knowledge/decisions/internals/virtual-user-conversations-seed-a-hidden-kickoff-message.md +0 -23
- package/knowledge/decisions/internals/virtual-user-step-order-comes-from-insertion-order.md +0 -21
- package/knowledge/decisions/internals/virtual-users-are-declared-in-one-definevirtualusers-call-per-codebase.md +0 -30
- package/knowledge/decisions/internals/voice-output-speaks-unless-voice-input-explicitly-says-otherwise.md +0 -24
- package/knowledge/decisions/internals/webhook-delivery-history-records-every-attempt-best-effort.md +0 -26
- package/knowledge/decisions/internals/webhook-service-collaborators-are-constructor-args-not-locator-lookups.md +0 -25
- package/knowledge/decisions/internals/whether-a-run-is-inline-is-read-from-the-run-record.md +0 -58
- package/knowledge/decisions/internals/wiring-registries-erase-the-generics-their-wire-functions-capture.md +0 -35
- package/knowledge/decisions/internals/workflow-approval-expiry-is-decided-from-a-recorded-deadline.md +0 -34
- package/knowledge/decisions/internals/workflow-core-never-imports-a-browser-driver.md +0 -42
- package/knowledge/decisions/internals/workflow-dsl-meta-separates-runtime-expressions-from-literals.md +0 -38
- package/knowledge/decisions/internals/workflow-features-resolve-scenarios-by-object-identity.md +0 -29
- package/knowledge/decisions/internals/workflow-graph-inline-and-queued-runs-share-one-planner.md +0 -42
- package/knowledge/decisions/internals/workflow-graph-node-notes-are-excluded-from-the-graph-hash.md +0 -25
- package/knowledge/decisions/internals/workflow-inline-runs-report-their-run-id-before-they-can-fail.md +0 -29
- package/knowledge/decisions/internals/workflow-invocation-id-is-the-dedupe-key-not-step-id.md +0 -43
- package/knowledge/decisions/internals/workflow-queued-step-dispatch-requires-an-explicit-opt-in.md +0 -29
- package/knowledge/decisions/internals/workflow-queues-are-per-workflow-by-default.md +0 -42
- package/knowledge/decisions/internals/workflow-repeated-step-names-get-an-ordinal-suffix.md +0 -33
- package/knowledge/decisions/internals/workflow-replay-reads-its-steps-once-and-caches-only-the-immutable-half.md +0 -32
- package/knowledge/decisions/internals/workflow-retries-are-owned-by-the-workflow-not-the-queue.md +0 -31
- package/knowledge/decisions/internals/workflow-run-capabilities-are-extensions-not-subclasses.md +0 -39
- package/knowledge/decisions/internals/workflow-run-mirror-is-never-a-source-of-truth.md +0 -29
- package/knowledge/decisions/internals/workflow-run-polling-backs-off-to-the-callers-ceiling.md +0 -33
- package/knowledge/decisions/internals/workflow-run-timeline-is-a-pure-fold-over-durable-history.md +0 -37
- package/knowledge/decisions/internals/workflow-scenario-assertions-never-retry-and-record-one-step.md +0 -54
- package/knowledge/decisions/internals/workflow-scenario-hooks-are-a-scenario-only-affordance.md +0 -43
- package/knowledge/decisions/internals/workflow-scenario-prose-is-rendered-from-typed-calls-not-parsed-from-english.md +0 -32
- package/knowledge/decisions/internals/workflow-scenario-quarantine-reason-lives-in-code.md +0 -18
- package/knowledge/decisions/internals/workflow-scenario-step-targets-are-string-literals-for-the-inspector.md +0 -34
- package/knowledge/decisions/internals/workflow-step-compensation-runs-as-its-own-durable-step.md +0 -29
- package/knowledge/decisions/internals/workflow-step-dispatch-failure-is-transient-not-a-run-failure.md +0 -33
- package/knowledge/decisions/internals/workflow-step-lock-is-held-only-to-claim-the-step.md +0 -34
- package/knowledge/decisions/internals/workflow-step-rpc-name-is-provenance-only.md +0 -34
- package/knowledge/decisions/internals/workflow-suspend-and-approval-reasons-are-durable-step-identities.md +0 -38
- package/knowledge/decisions/internals/workflow-suspended-runs-keep-their-in-process-context.md +0 -30
- package/knowledge/decisions/security/a-bearer-token-checked-against-a-secret-reads-it-per-request.md +0 -26
- package/knowledge/decisions/security/a-call-without-a-session-raises-missing-session-not-forbidden.md +0 -20
- package/knowledge/decisions/security/a-caller-cookie-wins-over-the-jar-for-the-same-name.md +0 -23
- package/knowledge/decisions/security/a-channel-lifecycle-acts-as-the-socket-upgrade-session.md +0 -16
- package/knowledge/decisions/security/a-channel-requires-a-session-unless-it-says-auth-false.md +0 -26
- package/knowledge/decisions/security/a-credential-read-path-follows-its-declared-type-not-absence.md +0 -32
- package/knowledge/decisions/security/a-credential-type-is-a-literal-the-inspector-checks-at-declaration.md +0 -27
- package/knowledge/decisions/security/a-dropped-audit-write-is-always-logged.md +0 -28
- package/knowledge/decisions/security/a-first-party-cookie-is-written-only-after-its-purposes-consent.md +0 -33
- package/knowledge/decisions/security/a-function-never-receives-the-secret-service.md +0 -37
- package/knowledge/decisions/security/a-graph-run-starts-at-an-entry-node-the-graph-declared.md +0 -33
- package/knowledge/decisions/security/a-permission-gets-a-wire-it-cannot-reply-on.md +0 -33
- package/knowledge/decisions/security/a-public-function-says-so-with-auth-false.md +0 -34
- package/knowledge/decisions/security/a-readonly-session-reaches-only-readonly-functions.md +0 -25
- package/knowledge/decisions/security/a-scaffold-flag-says-a-surface-exists-not-who-may-call-it.md +0 -52
- package/knowledge/decisions/security/a-scheduled-virtual-user-run-needs-no-admin-at-run-time.md +0 -27
- package/knowledge/decisions/security/a-scoped-credential-view-is-limited-to-declared-names.md +0 -26
- package/knowledge/decisions/security/a-scoped-secret-view-reads-only-declared-keys-and-never-writes.md +0 -25
- package/knowledge/decisions/security/a-secret-is-sent-only-to-the-hosts-it-declares.md +0 -29
- package/knowledge/decisions/security/a-step-can-name-an-identity-no-virtual-user-holds-through-per-call-headers.md +0 -25
- package/knowledge/decisions/security/a-step-runs-the-function-the-workflow-dispatched-it-with.md +0 -37
- package/knowledge/decisions/security/a-stopped-run-by-id-skips-the-ownership-check.md +0 -24
- package/knowledge/decisions/security/a-vault-secret-redacts-on-serialization-and-throws-on-coercion.md +0 -29
- package/knowledge/decisions/security/a-virtual-user-catalogue-entry-is-filtered-by-scope-and-approval-is-denied-by-default.md +0 -30
- package/knowledge/decisions/security/a-virtual-user-environment-fails-closed.md +0 -38
- package/knowledge/decisions/security/a-virtual-user-is-never-offered-a-step-that-would-forge-its-own-oracle.md +0 -27
- package/knowledge/decisions/security/a-virtual-user-never-runs-against-production.md +0 -23
- package/knowledge/decisions/security/a-virtual-user-reads-its-roles-from-the-apps-own-rpc-before-better-auth.md +0 -27
- package/knowledge/decisions/security/a-virtual-user-run-treats-an-unresolved-environment-as-production.md +0 -41
- package/knowledge/decisions/security/a-virtual-user-scopes-are-expanded-from-its-roles-once-at-run-preparation.md +0 -25
- package/knowledge/decisions/security/a-virtual-user-whose-roles-drift-from-the-declaration-refuses-to-run.md +0 -32
- package/knowledge/decisions/security/a-workflow-run-is-read-and-approved-by-its-owner.md +0 -50
- package/knowledge/decisions/security/addon-auth-and-tags-only-tighten.md +0 -43
- package/knowledge/decisions/security/addon-config-gates-apply-only-at-the-namespaced-rpc-boundary.md +0 -52
- package/knowledge/decisions/security/addon-scopes-are-resolved-where-the-function-runs.md +0 -46
- package/knowledge/decisions/security/addon-screen-scopes-hide-and-do-not-enforce.md +0 -20
- package/knowledge/decisions/security/agent-approval-forwarding-requires-a-symbol-brand.md +0 -27
- package/knowledge/decisions/security/agent-credential-requests-are-symbol-branded.md +0 -37
- package/knowledge/decisions/security/agent-gate-requires-a-session-only-when-auth-is-true.md +0 -31
- package/knowledge/decisions/security/agent-ownership-failures-never-echo-the-resource.md +0 -23
- package/knowledge/decisions/security/agent-resume-re-runs-the-authorization-gate.md +0 -22
- package/knowledge/decisions/security/agent-sessionless-deployments-have-no-thread-ownership.md +0 -39
- package/knowledge/decisions/security/agent-thread-ownership-composes-the-session-principal.md +0 -30
- package/knowledge/decisions/security/agent-tool-filtering-reads-the-live-function-config.md +0 -24
- package/knowledge/decisions/security/an-addon-header-can-only-narrow-the-session.md +0 -26
- package/knowledge/decisions/security/an-addon-instance-reads-only-the-secrets-and-credentials-it-is-named.md +0 -33
- package/knowledge/decisions/security/an-addon-may-reach-only-itself-and-the-addons-it-uses.md +0 -16
- package/knowledge/decisions/security/an-agent-approval-is-claimed-before-the-tool-runs.md +0 -33
- package/knowledge/decisions/security/an-api-key-is-jwt-decoded-into-the-session.md +0 -26
- package/knowledge/decisions/security/an-approval-answer-outlives-the-run-it-answered.md +0 -59
- package/knowledge/decisions/security/an-empty-owners-constraint-matches-nothing.md +0 -30
- package/knowledge/decisions/security/an-exposed-ungated-function-is-a-codegen-warning.md +0 -52
- package/knowledge/decisions/security/an-external-virtual-user-caller-presents-one-signed-statement.md +0 -38
- package/knowledge/decisions/security/an-inbound-webhook-source-dispatches-only-verified-requests.md +0 -31
- package/knowledge/decisions/security/an-mcp-call-with-no-http-request-stays-anonymous.md +0 -18
- package/knowledge/decisions/security/an-mcp-refusal-is-decided-before-dispatch.md +0 -48
- package/knowledge/decisions/security/an-oauth2-credential-is-read-by-its-account-row.md +0 -40
- package/knowledge/decisions/security/an-omitted-user-id-addresses-the-platform-credential.md +0 -32
- package/knowledge/decisions/security/an-upload-is-counted-as-it-arrives-not-buffered-then-measured.md +0 -24
- package/knowledge/decisions/security/analytics-identity-is-stamped-from-the-session-not-the-event.md +0 -24
- package/knowledge/decisions/security/app-access-is-a-scope-tree-synthesised-from-virtual-users.md +0 -26
- package/knowledge/decisions/security/approval-policy-decides-who-answers-a-tool-call.md +0 -27
- package/knowledge/decisions/security/auth-false-on-a-session-function-warns-and-still-requires-one.md +0 -25
- package/knowledge/decisions/security/bearer-token-hashes-are-unpeppered-sha256.md +0 -18
- package/knowledge/decisions/security/consent-is-read-from-a-cookie-and-a-recognised-denial-counts-as-refusal.md +0 -29
- package/knowledge/decisions/security/console-addon-privileged-functions-gate-themselves.md +0 -84
- package/knowledge/decisions/security/core-safe-fetch-blocks-ssrf-by-host-literal-not-dns.md +0 -39
- package/knowledge/decisions/security/core-secrets-use-a-per-secret-dek-wrapped-by-a-kek.md +0 -37
- package/knowledge/decisions/security/cors-defaults-to-any-origin-and-refuses-the-wildcard-with-credentials.md +0 -22
- package/knowledge/decisions/security/credential-backends-share-one-conformance-suite-for-per-user-isolation.md +0 -29
- package/knowledge/decisions/security/each-stage-has-one-virtual-user-key-pair.md +0 -27
- package/knowledge/decisions/security/gateway-handlers-run-through-the-function-runner-gate.md +0 -41
- package/knowledge/decisions/security/gateway-middleware-sessions-must-be-bridged-onto-the-wire.md +0 -30
- package/knowledge/decisions/security/global-permissions-and-function-permissions-are-independent-gates.md +0 -40
- package/knowledge/decisions/security/hmac-verification-fails-closed-on-empty-inputs.md +0 -25
- package/knowledge/decisions/security/http-error-detail-is-withheld-from-clients-in-production.md +0 -33
- package/knowledge/decisions/security/http-request-bodies-are-bounded-before-they-are-buffered.md +0 -46
- package/knowledge/decisions/security/index.md +0 -135
- package/knowledge/decisions/security/local-content-refuses-private-buckets-under-the-public-segment.md +0 -21
- package/knowledge/decisions/security/mail-is-allowlisted-before-a-virtual-user-run-sees-it.md +0 -38
- package/knowledge/decisions/security/mcp-internal-error-details-are-double-gated-on-production.md +0 -27
- package/knowledge/decisions/security/mcp-resources-tools-and-prompts-take-sessionless-functions.md +0 -18
- package/knowledge/decisions/security/origin-locked-routes-match-the-origin-exactly.md +0 -22
- package/knowledge/decisions/security/oss-auth-works-without-pikku-studio-cloud.md +0 -26
- package/knowledge/decisions/security/outbound-webhooks-use-an-allowlist-when-configured.md +0 -24
- package/knowledge/decisions/security/passphrases-are-stretched-key-material-is-expanded.md +0 -40
- package/knowledge/decisions/security/permission-auth-filtering-requires-live-permission-functions.md +0 -31
- package/knowledge/decisions/security/pikku-carries-virtual-user-scopes-as-data-and-the-app-grants-them.md +0 -35
- package/knowledge/decisions/security/queue-job-identities-are-signed-at-enqueue.md +0 -69
- package/knowledge/decisions/security/queue-jobs-carry-the-producers-pikku-user-id.md +0 -39
- package/knowledge/decisions/security/remote-addon-tokens-are-client-credentials-not-mesh-trust.md +0 -34
- package/knowledge/decisions/security/scaffold-features-are-authenticated-unless-opted-out.md +0 -55
- package/knowledge/decisions/security/scenario-step-functions-are-never-externally-invocable.md +0 -30
- package/knowledge/decisions/security/scope-resolution-happens-at-the-session-boundary-and-sync-never-deletes.md +0 -28
- package/knowledge/decisions/security/scoped-content-access-is-a-root-folder-with-longest-prefix-grants.md +0 -31
- package/knowledge/decisions/security/self-authentication-is-declared-not-detected.md +0 -34
- package/knowledge/decisions/security/services-without-secrets-get-a-throwing-secrets-accessor.md +0 -22
- package/knowledge/decisions/security/shared-guards-refuse-to-mutate-or-shadow-a-system-role.md +0 -34
- package/knowledge/decisions/security/signed-content-urls-bind-the-request-path.md +0 -37
- package/knowledge/decisions/security/signed-uploads-are-verified-by-the-same-check-as-signed-reads.md +0 -26
- package/knowledge/decisions/security/system-role-scopes-must-be-declared-with-define-scope.md +0 -24
- package/knowledge/decisions/security/system-roles-are-additive-and-immutable.md +0 -16
- package/knowledge/decisions/security/the-channel-rpc-does-not-send-the-callers-session.md +0 -21
- package/knowledge/decisions/security/the-remote-jobs-inbox-fails-closed-without-a-secret.md +0 -24
- package/knowledge/decisions/security/the-remote-rpc-gate-fails-closed-and-binds-the-token-to-its-function.md +0 -34
- package/knowledge/decisions/security/the-workflow-status-stream-rechecks-ownership-on-every-poll.md +0 -16
- package/knowledge/decisions/security/two-credentials-on-one-key-must-share-a-read-mode.md +0 -29
- package/knowledge/decisions/security/verified-bearer-claims-are-pass-through-data-that-core-never-fills.md +0 -23
- package/knowledge/decisions/security/virtual-user-catalogue-excludes-the-machinery-that-runs-virtual-users.md +0 -25
- package/knowledge/decisions/security/virtual-user-conversation-missing-approval-decisions-default-to-denied.md +0 -22
- package/knowledge/decisions/security/virtual-user-run-records-are-gated-behind-a-read-scope.md +0 -18
- package/knowledge/decisions/security/virtual-user-sign-in-does-not-exist-in-production.md +0 -25
- package/knowledge/decisions/security/virtual-user-sign-in-has-one-door.md +0 -42
- package/knowledge/decisions/security/virtual-user-sign-in-is-proven-by-set-cookie-not-a-non-empty-jar.md +0 -29
- package/knowledge/decisions/security/virtual-user-sign-in-only-works-for-virtual-user-flagged-users.md +0 -29
- package/knowledge/decisions/security/webhook-bodies-are-signed-before-they-are-enqueued.md +0 -25
- package/knowledge/decisions/security/wire-addon-expose-selects-the-rpc-surface.md +0 -51
- package/knowledge/decisions/security/workflow-approval-payloads-are-validated-on-replay-inside-the-workflow.md +0 -40
- package/knowledge/decisions/security/workflow-helper-functions-are-sessionless-by-declaration.md +0 -18
- package/knowledge/decisions/security/workflow-queued-steps-rehydrate-their-session-from-the-run-wire.md +0 -32
- package/knowledge/decisions/security/workflow-scenario-sessions-are-isolated-per-virtual-user-and-per-scenario.md +0 -32
- package/knowledge/decisions/security/workflow-scenario-steps-are-never-network-invocable.md +0 -31
- package/knowledge/decisions/security/workflow-virtual-user-steps-always-use-the-real-transport.md +0 -34
- package/knowledge/decisions/security/writing-a-virtual-user-schedule-is-gated-by-its-own-scope.md +0 -18
- package/knowledge/index.md +0 -24
- package/knowledge/questions/a-bearer-jwt-with-no-identity-becomes-a-session.md +0 -24
- package/knowledge/questions/channel-middleware-accepts-bare-factories-that-nothing-resolves.md +0 -35
- package/knowledge/questions/dev-quick-login-as-impersonation.md +0 -25
- package/knowledge/questions/does-a-delayed-rpc-run-as-the-session-it-was-scheduled-with.md +0 -26
- package/knowledge/questions/does-a-user-id-with-a-colon-read-another-users-credentials.md +0 -27
- package/knowledge/questions/does-a-wirecli-command-need-a-session-by-default.md +0 -26
- package/knowledge/questions/does-an-adversarial-in-scope-success-count-as-a-finding.md +0 -26
- package/knowledge/questions/does-approve-step-need-the-run-owners-session-or-the-gates-approvers.md +0 -34
- package/knowledge/questions/does-cors-origin-true-reflect-any-origin-with-credentials.md +0 -20
- package/knowledge/questions/does-skip-user-session-do-anything-on-a-channel.md +0 -24
- package/knowledge/questions/does-the-store-session-match-the-other-two.md +0 -19
- package/knowledge/questions/index.md +0 -41
- package/knowledge/questions/is-the-agent-score-worker-reachable-without-a-session.md +0 -21
- package/knowledge/questions/live-scheduled-tests-may-write.md +0 -19
- package/knowledge/questions/provision-virtual-users-has-no-caller-in-this-repo.md +0 -23
- package/knowledge/questions/remote-secret-refuses-requests-without-a-remote-token-on-every-path.md +0 -32
- package/knowledge/questions/should-a-middleware-set-session-persist-to-the-store.md +0 -25
- package/knowledge/questions/should-a-scoped-secret-view-throw-from-has-secret-for-a-disallowed-key.md +0 -23
- package/knowledge/questions/should-a-wrong-bearer-token-be-anonymous-or-refused.md +0 -35
- package/knowledge/questions/should-an-empty-webhook-signing-secret-send-unsigned.md +0 -23
- package/knowledge/questions/should-http-virtual-user-sessions-reset-between-scenarios-in-one-run.md +0 -27
- package/knowledge/questions/should-the-cookie-jar-scope-cookies-to-the-api-origin.md +0 -26
- package/knowledge/questions/should-voice-input-fetch-audio-urls-without-a-host-allowlist.md +0 -20
- package/knowledge/questions/staging-impersonation-rules.md +0 -27
- package/knowledge/questions/unauthorized-channel-replies-escape-the-declared-out-type.md +0 -44
- package/knowledge/questions/virtual-user-keys-on-cloud-stages-are-pikku-studios-to-build.md +0 -33
- package/knowledge/questions/virtual-user-statement-replay-is-per-process.md +0 -20
- package/knowledge/questions/what-an-impersonated-session-carries.md +0 -22
- package/run-tests.sh +0 -68
- package/scripts/generate-api-report.d.mts +0 -1
- package/scripts/generate-api-report.mjs +0 -96
- package/scripts/generate-api-report.mts +0 -333
- package/src/public-surface.json +0 -637
- package/src/public-surface.json.README +0 -43
- /package/dist/{function/compensation-name.d.ts → compensation-name.d.ts} +0 -0
- /package/dist/{function/compensation-name.js → compensation-name.js} +0 -0
|
@@ -1,25 +0,0 @@
|
|
|
1
|
-
---
|
|
2
|
-
type: decision
|
|
3
|
-
title: Working memory is persisted only when the merged value validates
|
|
4
|
-
description: A failed schema check logs and drops the update rather than saving it, because invalid state poisons every later read
|
|
5
|
-
tags: agent
|
|
6
|
-
---
|
|
7
|
-
|
|
8
|
-
# Working memory is persisted only when the merged value validates
|
|
9
|
-
|
|
10
|
-
`createWorkingMemoryMiddleware` in
|
|
11
|
-
`packages/core/src/wirings/agent/agent-memory.ts` parses the model's
|
|
12
|
-
`<working_memory>` block, deep-merges it into the stored value, validates the
|
|
13
|
-
merge against the agent's working-memory schema when one is declared, and calls
|
|
14
|
-
`saveWorkingMemory` only if the merge is valid. An invalid merge is logged as a
|
|
15
|
-
warning and discarded.
|
|
16
|
-
|
|
17
|
-
Working memory is read back into the system prompt on every subsequent run of the
|
|
18
|
-
thread, so a bad write is not a one-turn mistake — it is a permanently malformed
|
|
19
|
-
prompt that the model then has to reason around, and which the model itself
|
|
20
|
-
cannot repair. Dropping the update is recoverable; the next turn simply tries
|
|
21
|
-
again.
|
|
22
|
-
|
|
23
|
-
**What this rules out:** saving first and validating on read, persisting the raw
|
|
24
|
-
model output before the merge, and treating a validation failure as fatal to the
|
|
25
|
-
run.
|
|
@@ -1,39 +0,0 @@
|
|
|
1
|
-
---
|
|
2
|
-
type: decision
|
|
3
|
-
title: An addon's scope root loses to a root the host app already declares
|
|
4
|
-
description: loadAddonFunctionsMeta merges addon scope trees by root name, first declaration wins, so an addon sharing a root with its host contributes nothing — silently
|
|
5
|
-
tags: services
|
|
6
|
-
---
|
|
7
|
-
|
|
8
|
-
# An addon's scope root loses to a root the host app already declares
|
|
9
|
-
|
|
10
|
-
`loadAddonFunctionsMeta`
|
|
11
|
-
(`packages/inspector/src/utils/load-addon-functions-meta.ts`) reads each wired
|
|
12
|
-
addon's `pikku-scopes-meta.gen.json` and pushes its entries into
|
|
13
|
-
`state.scopes.definitions`, skipping any whose root name is already present. The
|
|
14
|
-
host app's own declarations were inspected first, so the host always wins.
|
|
15
|
-
|
|
16
|
-
The skip is per **root**, not per node. An addon declaring `admin.console.*` in
|
|
17
|
-
an app that declares `admin` contributes none of it — not the root it shares,
|
|
18
|
-
and not the branch the app never declared. Nothing errors: the scopes simply do
|
|
19
|
-
not exist, so `ScopeId` never gains them, no role can be granted one, and every
|
|
20
|
-
addon function requiring one denies everybody. The failure surfaces as a
|
|
21
|
-
`MissingScopeError` against a scope that cannot be granted, which reads as a
|
|
22
|
-
permissions bug rather than a merge that dropped.
|
|
23
|
-
|
|
24
|
-
This is a different rule from
|
|
25
|
-
[scope roots may be co-declared by an addon and its host
|
|
26
|
-
app](scope-roots-may-be-co-declared-by-an-addon-and-its-host-app.md): that one
|
|
27
|
-
is about `flattenScopeDefinitions` deduping ids _within_ a build where both
|
|
28
|
-
declarations are present and identical. This one is about the addon's copy never
|
|
29
|
-
arriving. The consequence for addon authors is the same either way — own a root
|
|
30
|
-
outright, named for the package or vendor, and nest everything under it. It is
|
|
31
|
-
why `@pikku/addon-console` declares `pikku:console:*` rather than
|
|
32
|
-
`admin:console:*`.
|
|
33
|
-
|
|
34
|
-
**What this rules out:** shipping an addon whose scopes hang off a root a host
|
|
35
|
-
is likely to declare, and deep-merging the two trees here so both survive. A
|
|
36
|
-
merge would have to reconcile conflicting descriptions and display names for the
|
|
37
|
-
shared nodes, and would let an addon graft capabilities onto the host's `admin`
|
|
38
|
-
tree — where a role granting `admin` would pick them up without anyone having
|
|
39
|
-
asked for them.
|
|
@@ -1,23 +0,0 @@
|
|
|
1
|
-
---
|
|
2
|
-
type: decision
|
|
3
|
-
title: An interrupt is not a failure, and the non-streaming path throws rather than returning
|
|
4
|
-
description: It skips the onError hooks and never becomes an errorMessage; with no partial reply to hand back, a typed throw is what distinguishes it from a provider outage
|
|
5
|
-
tags: core, agent
|
|
6
|
-
---
|
|
7
|
-
|
|
8
|
-
# An interrupt is not a failure
|
|
9
|
-
|
|
10
|
-
Interrupting a run skips the `onError` hooks entirely and never becomes an
|
|
11
|
-
`errorMessage`. Someone asked the agent to stop and it stopped; that is the
|
|
12
|
-
feature working, and running failure handlers over it would report an incident
|
|
13
|
-
that did not happen.
|
|
14
|
-
|
|
15
|
-
The streaming and non-streaming paths then diverge, because what they can hand
|
|
16
|
-
back differs. A stream has already delivered part of the reply, so it returns
|
|
17
|
-
that fragment. `runAgent` has delivered nothing — there is no partial answer to
|
|
18
|
-
return — so it throws a typed error instead. A caller can tell that apart from a
|
|
19
|
-
provider outage, which returning an empty result would not allow.
|
|
20
|
-
|
|
21
|
-
**What this rules out:** unifying the two paths on "return whatever you have".
|
|
22
|
-
For the non-streaming path that is an empty string, and an empty string is
|
|
23
|
-
indistinguishable from a model that answered with nothing.
|
|
@@ -1,27 +0,0 @@
|
|
|
1
|
-
---
|
|
2
|
-
type: decision
|
|
3
|
-
title: A reachable agent is offered by its registry key, filtered by the virtual user's scopes
|
|
4
|
-
description: reachableAgents offers an agent to a virtual user under the key it is registered with, and only when the virtual user holds the agent's declared scopes; the server still enforces access
|
|
5
|
-
tags: core, virtual-users, agents, scopes
|
|
6
|
-
---
|
|
7
|
-
|
|
8
|
-
# A reachable agent is offered by its registry key, filtered by the virtual user's scopes
|
|
9
|
-
|
|
10
|
-
`packages/core/src/wirings/virtual-user/virtual-user-agents.ts` decides which agents
|
|
11
|
-
a virtual user is told about.
|
|
12
|
-
|
|
13
|
-
An agent with no declared scopes is offered to everybody (`virtual-user-agents.ts:54-55`).
|
|
14
|
-
The doc comment says undeclared is not the same as denied (`virtual-user-agents.ts:45-46`).
|
|
15
|
-
Otherwise the agent is offered only when the virtual user's scopes satisfy the agent's
|
|
16
|
-
scopes (`virtual-user-agents.ts:57`, `hasScopes`).
|
|
17
|
-
|
|
18
|
-
The name offered is the registry key, not the agent's display name. The code uses
|
|
19
|
-
`name: id` (`virtual-user-agents.ts:59-60`), and the doc comment says the display
|
|
20
|
-
name "is frequently something else entirely", and offering it makes the run die
|
|
21
|
-
on a 500 (`virtual-user-agents.ts:30-37`).
|
|
22
|
-
|
|
23
|
-
The doc comment says this filter narrows only what is offered. The server decides
|
|
24
|
-
who may talk to which agent (`virtual-user-agents.ts:39-44`).
|
|
25
|
-
|
|
26
|
-
**What this rules out:** offering an agent name the server cannot resolve, and
|
|
27
|
-
treating the offer list as the access check.
|
|
@@ -1,25 +0,0 @@
|
|
|
1
|
-
---
|
|
2
|
-
type: decision
|
|
3
|
-
title: An interrupt for a run owned by another instance says so, rather than returning false
|
|
4
|
-
description: A bare false is indistinguishable from "already finished", which is the one deployment shape the in-process registry cannot cover
|
|
5
|
-
tags: core, agent
|
|
6
|
-
---
|
|
7
|
-
|
|
8
|
-
# An interrupt for a run owned by another instance says so
|
|
9
|
-
|
|
10
|
-
`interruptAgent` resolves a run through `agentRunState`, then tries to abort it
|
|
11
|
-
via the in-process registry. A run still marked `running` that this process has
|
|
12
|
-
no abort handle for is executing on another instance.
|
|
13
|
-
|
|
14
|
-
Returning a bare `false` there is indistinguishable from "the run already
|
|
15
|
-
finished" — the ordinary, uninteresting outcome. So the single deployment shape
|
|
16
|
-
the in-process registry does not cover, multi-instance, fails silently: an agent
|
|
17
|
-
that will not stop talking, and nothing in the logs to say why. The call reports
|
|
18
|
-
the condition instead.
|
|
19
|
-
|
|
20
|
-
**What this rules out:** collapsing the two outcomes into one boolean because
|
|
21
|
-
the caller "only cares whether it stopped". The caller cares a great deal about
|
|
22
|
-
the difference between _stopped_ and _cannot be stopped from here_.
|
|
23
|
-
|
|
24
|
-
The fix for the underlying gap is `signalRunInterrupt`, which fans the interrupt
|
|
25
|
-
out over `eventHub` so every instance tries locally.
|
package/knowledge/decisions/internals/an-agent-stream-send-must-return-the-inner-sends-promise.md
DELETED
|
@@ -1,22 +0,0 @@
|
|
|
1
|
-
---
|
|
2
|
-
type: decision
|
|
3
|
-
title: A wrapped agent-stream send must return the inner send's promise
|
|
4
|
-
description: Middleware runs asynchronously, so dropping the returned promise turns every awaited channel.send upstream into a no-op
|
|
5
|
-
tags: core, agent
|
|
6
|
-
---
|
|
7
|
-
|
|
8
|
-
# A wrapped agent-stream send must return the inner send's promise
|
|
9
|
-
|
|
10
|
-
`streamAgent` wraps the caller's channel so every event passes through the
|
|
11
|
-
stream middleware. That wrapper's `send` returns whatever the inner `send`
|
|
12
|
-
returns, and it must: the middleware chain is asynchronous, so a wrapper that
|
|
13
|
-
calls the inner `send` and returns `undefined` resolves immediately while the
|
|
14
|
-
event is still in flight.
|
|
15
|
-
|
|
16
|
-
Every `await channel.send(...)` upstream then becomes a no-op that resolves
|
|
17
|
-
before the thing it is waiting for has happened. The one that matters is the
|
|
18
|
-
final flush — a buffering hook such as `voiceOutput` is still synthesizing audio
|
|
19
|
-
when the awaited send resolves, and the `close()` that follows discards it.
|
|
20
|
-
|
|
21
|
-
**What this rules out:** writing the wrapper as a fire-and-forget `(msg) => {
|
|
22
|
-
inner.send(msg) }`, which reads as equivalent and is not.
|
package/knowledge/decisions/internals/an-empty-text-part-is-omitted-from-an-agent-message.md
DELETED
|
@@ -1,20 +0,0 @@
|
|
|
1
|
-
---
|
|
2
|
-
type: decision
|
|
3
|
-
title: A message with nothing to say carries no text part at all
|
|
4
|
-
description: An attachment on its own is a real turn, and providers are entitled to reject an empty text part sitting beside it
|
|
5
|
-
tags: core, agent
|
|
6
|
-
---
|
|
7
|
-
|
|
8
|
-
# A message with nothing to say carries no text part
|
|
9
|
-
|
|
10
|
-
When a turn has no text, the text part is omitted rather than included as an
|
|
11
|
-
empty string.
|
|
12
|
-
|
|
13
|
-
An attachment on its own is a legitimate turn — a spoken one carries audio and
|
|
14
|
-
no text whatsoever — so "no text" is a normal state, not a degenerate one.
|
|
15
|
-
Providers are entitled to reject a message part with empty content, and that
|
|
16
|
-
rejection would land on a caller who never wrote any text to begin with.
|
|
17
|
-
|
|
18
|
-
**What this rules out:** normalising the text to `''` for a uniform message
|
|
19
|
-
shape. Uniformity here buys nothing and costs a provider error on the one turn
|
|
20
|
-
type that most needs to work.
|
|
@@ -1,22 +0,0 @@
|
|
|
1
|
-
---
|
|
2
|
-
type: decision
|
|
3
|
-
title: A transcript is recorded only when something was actually heard
|
|
4
|
-
description: Recording an empty string sends a transcript event saying the user said nothing, which renders as an empty bubble rather than a pending one
|
|
5
|
-
tags: core, agent
|
|
6
|
-
---
|
|
7
|
-
|
|
8
|
-
# A transcript is recorded only when something was actually heard
|
|
9
|
-
|
|
10
|
-
A turn can carry audio that reads entirely as non-speech and still have content
|
|
11
|
-
— an image with a silent caption clip — so there is nothing above to throw.
|
|
12
|
-
`voiceInput` records the transcript only when speech was found.
|
|
13
|
-
|
|
14
|
-
Writing `''` instead would emit a transcript event asserting that the user said
|
|
15
|
-
nothing. A client that distinguishes "not transcribed yet" from "transcribed"
|
|
16
|
-
by whether the key is present would then render that turn as a permanently
|
|
17
|
-
empty bubble rather than a pending one — a worse outcome than showing nothing,
|
|
18
|
-
because it looks settled.
|
|
19
|
-
|
|
20
|
-
**What this rules out:** defaulting the transcript to an empty string for a
|
|
21
|
-
uniform event shape. Absence and emptiness mean different things to the client,
|
|
22
|
-
and only absence is recoverable.
|
package/knowledge/decisions/internals/an-oauth2-credential-implies-an-optional-app-secret.md
DELETED
|
@@ -1,26 +0,0 @@
|
|
|
1
|
-
---
|
|
2
|
-
type: decision
|
|
3
|
-
title: An OAuth2 credential implies its app client secret, optional and overridable by declaration
|
|
4
|
-
description: deriveOAuth2AppSecrets creates the app client id and secret for each OAuth2 credential, marked optional, unless the project already declares that secret id
|
|
5
|
-
tags: core, secrets, credentials, oauth2
|
|
6
|
-
---
|
|
7
|
-
|
|
8
|
-
# An OAuth2 credential implies its app client secret, optional and overridable by declaration
|
|
9
|
-
|
|
10
|
-
`packages/core/src/wirings/secret/derive-oauth2-app-secrets.ts` adds the app's
|
|
11
|
-
client id and secret for each OAuth2 credential a project declares. The doc comment
|
|
12
|
-
says the pair has the same shape every time, so writing it by hand "bought nothing"
|
|
13
|
-
and was often skipped (`derive-oauth2-app-secrets.ts:7-12`).
|
|
14
|
-
|
|
15
|
-
- A secret id that is already declared is skipped, so an explicit declaration
|
|
16
|
-
wins and keeps its own description or `docsUrl` (`derive-oauth2-app-secrets.ts:25`,
|
|
17
|
-
`31`, and the comment at `derive-oauth2-app-secrets.ts:14-15`).
|
|
18
|
-
- The derived secret has `optional: true` (`derive-oauth2-app-secrets.ts:38-39`).
|
|
19
|
-
The comment says an addon that also authenticates by API key "must still deploy
|
|
20
|
-
without an OAuth app configured" (`derive-oauth2-app-secrets.ts:17-19`).
|
|
21
|
-
- The OAuth2 settings (token secret, URLs, scopes, PKCE, extra params) are copied
|
|
22
|
-
from the credential (`derive-oauth2-app-secrets.ts:41-49`).
|
|
23
|
-
|
|
24
|
-
**What this rules out:** requiring a deployment to configure an OAuth app for a
|
|
25
|
-
credential that is not used, and a derived secret overriding one the author
|
|
26
|
-
declared.
|
|
@@ -1,66 +0,0 @@
|
|
|
1
|
-
---
|
|
2
|
-
type: decision
|
|
3
|
-
title: An unref'd timer cannot be awaited under node:test
|
|
4
|
-
description: The channel RPC registry unrefs its timeout so a pending call never holds a process open, which makes that timeout unawaitable in a test and silently cancels the rest of the file
|
|
5
|
-
tags: core, channel, testing
|
|
6
|
-
---
|
|
7
|
-
|
|
8
|
-
# An unref'd timer cannot be awaited under node:test
|
|
9
|
-
|
|
10
|
-
`ChannelRPCRegistry.register()` schedules the call's timeout and then unrefs it:
|
|
11
|
-
|
|
12
|
-
```ts
|
|
13
|
-
// Never hold the process open waiting on a peer that may not answer.
|
|
14
|
-
timer?.unref?.()
|
|
15
|
-
```
|
|
16
|
-
|
|
17
|
-
That is correct, and should stay. A server shutting down must not be held open
|
|
18
|
-
for up to 30 seconds per in-flight reverse RPC.
|
|
19
|
-
|
|
20
|
-
It also means the timeout can never fire in a test that awaits it. An unref'd
|
|
21
|
-
timer does not keep the event loop alive, so when the pending call is the only
|
|
22
|
-
thing left the loop drains first, and node:test reports:
|
|
23
|
-
|
|
24
|
-
```
|
|
25
|
-
Promise resolution is still pending but the event loop has already resolved
|
|
26
|
-
```
|
|
27
|
-
|
|
28
|
-
The damage is not local. That one test hangs, the runner cancels the **file**,
|
|
29
|
-
and every later test in it is reported `cancelledByParent` — 32 of them in
|
|
30
|
-
`channel-rpc.test.ts`, of which only two were the actual problem. Worse, the
|
|
31
|
-
count moves: under a full-suite run other ref'd handles sometimes keep the loop
|
|
32
|
-
alive long enough for the timer to land, so the file reported `32 cancelled` or
|
|
33
|
-
`1 fail + 31 cancelled` depending on timing. Two of the "failures" were tests
|
|
34
|
-
that pass perfectly well on their own.
|
|
35
|
-
|
|
36
|
-
Reproducible with no project code at all — a bare `node --test` file where one
|
|
37
|
-
test awaits a ref'd timer and one awaits an unref'd one passes the first and
|
|
38
|
-
cancels the second.
|
|
39
|
-
|
|
40
|
-
**The fix belongs in the test, not the registry.** Use the test-scoped mock
|
|
41
|
-
clock and drive it by hand:
|
|
42
|
-
|
|
43
|
-
```ts
|
|
44
|
-
test('times out instead of hanging forever', async (t) => {
|
|
45
|
-
t.mock.timers.enable({ apis: ['setTimeout'] })
|
|
46
|
-
const registry = new ChannelRPCRegistry(10)
|
|
47
|
-
const call = registry.register()
|
|
48
|
-
|
|
49
|
-
const rejected = assert.rejects(call.promise, ...) // attach BEFORE ticking
|
|
50
|
-
t.mock.timers.tick(10)
|
|
51
|
-
await rejected
|
|
52
|
-
})
|
|
53
|
-
```
|
|
54
|
-
|
|
55
|
-
`t.mock.timers` is scoped to the test and resets itself, so tests that want a
|
|
56
|
-
real clock are unaffected. Attach the rejection handler before ticking, or the
|
|
57
|
-
rejection lands unhandled.
|
|
58
|
-
|
|
59
|
-
**What this rules out:** dropping the `unref` to make the tests pass. That
|
|
60
|
-
trades a test-only annoyance for a production one — every in-flight call would
|
|
61
|
-
then pin the process during shutdown. Also rules out reading a cancelled count
|
|
62
|
-
in this file as a count of broken tests; check which test actually hangs first,
|
|
63
|
-
because the rest are collateral.
|
|
64
|
-
|
|
65
|
-
Related: [[the-api-report-pins-members-not-just-names]] for the other case where
|
|
66
|
-
a measurement in this repo counted the wrong thing convincingly.
|
|
@@ -1,22 +0,0 @@
|
|
|
1
|
-
---
|
|
2
|
-
type: decision
|
|
3
|
-
title: Analytics identity resolvers run in declared order so consent is read before a cookie is minted
|
|
4
|
-
description: composeAnalyticsIdentity threads each resolver's output into the next, so a cookie-minting resolver sees the consent that an earlier resolver read
|
|
5
|
-
tags: core, analytics, consent
|
|
6
|
-
---
|
|
7
|
-
|
|
8
|
-
# Analytics identity resolvers run in declared order so consent is read before a cookie is minted
|
|
9
|
-
|
|
10
|
-
`composeAnalyticsIdentity` in `packages/core/src/analytics/compose-analytics-identity.ts:22-35`
|
|
11
|
-
runs the resolvers in the order given. Each one receives the accumulated result of
|
|
12
|
-
the ones before it (`:26`, `:29`), and its output is merged over that result (`:31-33`).
|
|
13
|
-
|
|
14
|
-
The doc comment at `:8-15` states the ordering rule: a resolver that mints a cookie
|
|
15
|
-
may do so only once consent has been read, so the consent reader has to come first.
|
|
16
|
-
A later resolver wins a key it sets (`:17-18`).
|
|
17
|
-
|
|
18
|
-
The cookie-side rule is in `a-first-party-cookie-is-written-only-after-its-purposes-consent.md`.
|
|
19
|
-
That note does not record the order in which the resolvers are composed.
|
|
20
|
-
|
|
21
|
-
**What this rules out:** running a cookie-minting resolver ahead of the consent
|
|
22
|
-
reader, and merging independent resolver results so that no resolver sees another's output.
|
package/knowledge/decisions/internals/channel-message-handlers-accept-three-config-shapes.md
DELETED
|
@@ -1,30 +0,0 @@
|
|
|
1
|
-
---
|
|
2
|
-
type: decision
|
|
3
|
-
title: Channel message handlers accept three config shapes
|
|
4
|
-
description: onMessage may be a function config, a wrapper with middleware, or a wrapper around a function config — the runtime discriminates structurally
|
|
5
|
-
tags: channel
|
|
6
|
-
---
|
|
7
|
-
|
|
8
|
-
# Channel message handlers accept three config shapes
|
|
9
|
-
|
|
10
|
-
`processMessageHandlers` in
|
|
11
|
-
`packages/core/src/wirings/channel/channel-handler.ts` has to tell apart three
|
|
12
|
-
things a caller may put on `onMessage` or inside `onMessageWiring`:
|
|
13
|
-
|
|
14
|
-
- a direct function config, where `onMessage.func` is a plain `Function`;
|
|
15
|
-
- a wrapper, where `onMessage.func` is itself a `CorePikkuFunctionConfig` and so
|
|
16
|
-
has its own nested `.func`;
|
|
17
|
-
- a simple wrapper, which carries a plain `Function` under `func` _and_ a
|
|
18
|
-
sibling `middleware` array.
|
|
19
|
-
|
|
20
|
-
The `isWrapper` check tests exactly that: an object with `func`, where either
|
|
21
|
-
`func` is an object that itself has `func`, or the object also has `middleware`.
|
|
22
|
-
Only a wrapper contributes message-level middleware; a direct config contributes
|
|
23
|
-
none. `wireChannel` in `channel-runner.ts` performs the mirror-image unwrapping
|
|
24
|
-
when registering the function, using `(handler as any).func instanceof Function`
|
|
25
|
-
to decide whether to register the handler or its inner `func`.
|
|
26
|
-
|
|
27
|
-
**What this rules out:** narrowing on a single property (`'middleware' in
|
|
28
|
-
onMessage` alone misclassifies a nested function config; `'func' in onMessage`
|
|
29
|
-
alone misclassifies a direct config), and reducing the accepted shapes without
|
|
30
|
-
updating both this discriminator and the registration path in `wireChannel`.
|
|
@@ -1,31 +0,0 @@
|
|
|
1
|
-
---
|
|
2
|
-
type: decision
|
|
3
|
-
title: Channel middleware caching covers only statically resolved middleware
|
|
4
|
-
description: Inherited tag/named middleware is cached per uid; per-run closures are appended fresh every call, at the cost of re-allocating the array
|
|
5
|
-
tags: channel
|
|
6
|
-
---
|
|
7
|
-
|
|
8
|
-
# Channel middleware caching covers only statically resolved middleware
|
|
9
|
-
|
|
10
|
-
`combineChannelMiddleware` in
|
|
11
|
-
`packages/core/src/wirings/channel/channel-middleware-runner.ts` caches only the
|
|
12
|
-
`wireInheritedChannelMiddleware` slice — the tag groups and named middleware
|
|
13
|
-
resolved out of `pikkuState` — under the key `${wireType}:${uid}`. That slice is
|
|
14
|
-
deterministic for a given `uid`. `wireChannelMiddleware` is not: it is a per-run
|
|
15
|
-
set of closures, such as an AI agent's per-invocation stream middleware holding
|
|
16
|
-
that run's thread and session state. Caching it would let a later run of the same
|
|
17
|
-
`uid` reuse an earlier run's closures, leaking that run's state into a different
|
|
18
|
-
user's stream and growing memory run over run. It is therefore appended fresh on
|
|
19
|
-
every call, after the cached inherited slice.
|
|
20
|
-
|
|
21
|
-
The `uid` matters as much as the cache split. `processMessageHandlers` in
|
|
22
|
-
`channel-handler.ts` builds it from the channel name _plus_ the routing property
|
|
23
|
-
and router value (`${name}:${routingProperty}:${routerValue}`, or
|
|
24
|
-
`${name}:default`), because several message routes on one channel may point at
|
|
25
|
-
the same function — a key based on the function alone would serve one route's
|
|
26
|
-
middleware chain to another. Ordering within the combined chain is also fixed:
|
|
27
|
-
channel-level `middleware` runs before message-level `middleware`.
|
|
28
|
-
|
|
29
|
-
**What this rules out:** extending the cache key's value to include
|
|
30
|
-
`wireChannelMiddleware`, memoising the whole combined array, or simplifying the
|
|
31
|
-
cache key down to the channel or function name.
|
|
@@ -1,33 +0,0 @@
|
|
|
1
|
-
---
|
|
2
|
-
type: decision
|
|
3
|
-
title: `getState<T>()` lets the caller name any type, so every implementation asserts
|
|
4
|
-
description: The type parameter appears only in the return position with nothing to infer from, so it is a caller-chosen claim rather than a checked fact
|
|
5
|
-
tags: core, channel
|
|
6
|
-
---
|
|
7
|
-
|
|
8
|
-
# `getState<T>()` lets the caller name any type, so every implementation asserts
|
|
9
|
-
|
|
10
|
-
`PikkuChannel` declares its per-connection scratch state as:
|
|
11
|
-
|
|
12
|
-
```ts
|
|
13
|
-
setState<T>(state: T): Promise<void> | void
|
|
14
|
-
getState<T>(): Promise<T | undefined> | T | undefined
|
|
15
|
-
```
|
|
16
|
-
|
|
17
|
-
`T` on `getState` appears only in the return position, with no parameter to
|
|
18
|
-
infer it from. So `T` is whatever the caller writes, and the call site gets that
|
|
19
|
-
type back with nothing having checked it. `setState<T>` is separately generic,
|
|
20
|
-
so the two are not even tied to each other — a channel can be written with one
|
|
21
|
-
shape and read as another and neither call complains.
|
|
22
|
-
|
|
23
|
-
Every implementation therefore holds its state in a concrete variable and
|
|
24
|
-
asserts on the way out. The SSE channel in `http-runner.ts` and the CLI channel
|
|
25
|
-
in `cli-runner.ts` both do exactly that, and the assertion is unavoidable: no
|
|
26
|
-
concrete value is assignable to a type the caller has not yet chosen.
|
|
27
|
-
|
|
28
|
-
**What this rules out:** deleting the assertions in the implementations — they
|
|
29
|
-
are forced by the signature, not by sloppiness. Fixing this properly means
|
|
30
|
-
making the channel generic in its state type (`PikkuChannel<Opening, Out,
|
|
31
|
-
Remote, State>`) so `setState` and `getState` agree and inference has something
|
|
32
|
-
to work from, which changes the type of every channel in every app. Until that
|
|
33
|
-
is worth doing, the assertions stay and this note explains why they exist.
|
package/knowledge/decisions/internals/channel-state-is-per-socket-session-state-is-per-user.md
DELETED
|
@@ -1,29 +0,0 @@
|
|
|
1
|
-
---
|
|
2
|
-
type: decision
|
|
3
|
-
title: Channel state is per-socket, session state is per-user
|
|
4
|
-
description: ChannelStore holds connection-scoped scratch data keyed by channelId, deliberately separate from the pikkuUserId-keyed SessionStore
|
|
5
|
-
tags: channel
|
|
6
|
-
---
|
|
7
|
-
|
|
8
|
-
# Channel state is per-socket, session state is per-user
|
|
9
|
-
|
|
10
|
-
`ChannelStore.setState` / `getState` / `clearState` in
|
|
11
|
-
`packages/core/src/wirings/channel/channel-store.ts` are keyed by `channelId` and
|
|
12
|
-
hold scratch data that belongs to one socket: a per-connection subscription
|
|
13
|
-
filter, the current step of a connection-bound state machine, the last command
|
|
14
|
-
this socket sent. The store clears it when the channel is removed. `SessionStore`
|
|
15
|
-
is keyed by `pikkuUserId` and holds the user session, which is shared across HTTP
|
|
16
|
-
and channel transports and outlives any one connection.
|
|
17
|
-
|
|
18
|
-
The two are separate stores because their lifetimes and their scopes differ. One
|
|
19
|
-
user may hold several sockets at once; writing socket-local data into the session
|
|
20
|
-
would let those sockets overwrite each other and would leak connection state into
|
|
21
|
-
HTTP requests. The serverless runner in `serverless/serverless-channel-runner.ts`
|
|
22
|
-
rebinds `channel.setState/getState/clearState` onto the `ChannelStore` on every
|
|
23
|
-
connect, message and disconnect precisely because there is no in-process channel
|
|
24
|
-
object to hang the state off between invocations.
|
|
25
|
-
|
|
26
|
-
**What this rules out:** backing `channel.setState` with the session store, or
|
|
27
|
-
merging the two stores behind one interface "since both are key-value". Also
|
|
28
|
-
rules out assuming channel state survives a reconnect — a new socket is a new
|
|
29
|
-
`channelId` and starts empty.
|
|
@@ -1,28 +0,0 @@
|
|
|
1
|
-
---
|
|
2
|
-
type: decision
|
|
3
|
-
title: A channel's user id is persisted only after onConnect middleware has run
|
|
4
|
-
description: The channelId to pikkuUserId mapping is written post-onConnect, because auth middleware is what establishes the session
|
|
5
|
-
tags: channel
|
|
6
|
-
---
|
|
7
|
-
|
|
8
|
-
# A channel's user id is persisted only after onConnect middleware has run
|
|
9
|
-
|
|
10
|
-
`runChannelConnect` in
|
|
11
|
-
`packages/core/src/wirings/channel/serverless/serverless-channel-runner.ts`
|
|
12
|
-
reads `userSession.getPikkuUserId()` and calls `channelStore.setPikkuUserId`
|
|
13
|
-
_after_ `runChannelLifecycleWithMiddleware` has executed the `onConnect`
|
|
14
|
-
lifecycle, not before.
|
|
15
|
-
|
|
16
|
-
Auth middleware runs as part of that lifecycle — it is what inspects the upgrade
|
|
17
|
-
request's cookie or token and calls `setSession`. Before it runs there is no
|
|
18
|
-
`pikkuUserId` to store, so an earlier write would persist `undefined` and the
|
|
19
|
-
channel would stay anonymous for its whole life. That mapping is what
|
|
20
|
-
`runChannelMessage` and `runChannelDisconnect` later use to rehydrate the session
|
|
21
|
-
from the `sessionStore` on each subsequent invocation, since serverless keeps
|
|
22
|
-
nothing in memory between them.
|
|
23
|
-
|
|
24
|
-
**What this rules out:** moving the `setPikkuUserId` call up next to
|
|
25
|
-
`channelStore.addChannel` to group the store writes together, and assuming a
|
|
26
|
-
session exists on the wire before `onConnect` has completed. It also means an
|
|
27
|
-
`onConnect` handler that throws leaves the channel with no user mapping — the
|
|
28
|
-
error path deliberately does not persist one.
|
|
@@ -1,27 +0,0 @@
|
|
|
1
|
-
---
|
|
2
|
-
type: decision
|
|
3
|
-
title: CLI option names are camelCase in state and kebab-case on the command line
|
|
4
|
-
description: Option keys match the function's input field names so they can be plucked by schema, and are converted to kebab only for display and parsing
|
|
5
|
-
tags: cli
|
|
6
|
-
---
|
|
7
|
-
|
|
8
|
-
# CLI option names are camelCase in state and kebab-case on the command line
|
|
9
|
-
|
|
10
|
-
Every option key in `CLIOptions`, `CLICommandMeta.options` and the parsed
|
|
11
|
-
`ParsedCommand.options` is camelCase, because it must line up with a field name
|
|
12
|
-
on the command function's input type — that is what makes
|
|
13
|
-
`pluckCLIData` in `packages/core/src/wirings/cli/cli-runner.ts` able to select
|
|
14
|
-
fields by schema property name. Users type kebab-case.
|
|
15
|
-
|
|
16
|
-
`toCamelCase` and `toKebabCase` in
|
|
17
|
-
`packages/core/src/wirings/cli/command-parser.ts` are the only two points where
|
|
18
|
-
the conversion happens. The parser normalises every incoming `--from-plan` to
|
|
19
|
-
`fromPlan` on the way in, and both `formatOptions` (help text) and the
|
|
20
|
-
"Missing required option" / "Invalid value for" errors render back to kebab on
|
|
21
|
-
the way out. `suggestOption` deliberately compares the typed string against
|
|
22
|
-
_both_ forms, so `--autoApply` and `--auto-apply` both find `autoApply`.
|
|
23
|
-
|
|
24
|
-
**What this rules out:** storing option keys kebab-cased anywhere in CLI state or
|
|
25
|
-
metadata — the schema pluck would then match nothing and every option would be
|
|
26
|
-
dropped. It also rules out emitting camelCase in help text or error messages,
|
|
27
|
-
which would tell users to type a flag spelling that works only by accident.
|
|
@@ -1,28 +0,0 @@
|
|
|
1
|
-
---
|
|
2
|
-
type: decision
|
|
3
|
-
title: CLI parse errors are routed by message prefix
|
|
4
|
-
description: The CLI runners decide between printing help and printing errors by string-matching the prefixes the parser writes, so those message strings are an interface
|
|
5
|
-
tags: cli
|
|
6
|
-
---
|
|
7
|
-
|
|
8
|
-
# CLI parse errors are routed by message prefix
|
|
9
|
-
|
|
10
|
-
`parseCLIArguments` in `packages/core/src/wirings/cli/command-parser.ts` returns
|
|
11
|
-
a flat `string[]` of errors. It has no error codes and no error types. The
|
|
12
|
-
consumers — `executeCLI` in `cli-runner.ts` and `handleRawCLI` in
|
|
13
|
-
`channel/cli-raw-channel-runner.ts` — decide whether the user made a routing
|
|
14
|
-
mistake (show the help text) or a value mistake (print the errors) by
|
|
15
|
-
`error.startsWith(...)` against three literals: `'Unknown command:'`,
|
|
16
|
-
`'Command not found:'` and `'Missing subcommand:'`.
|
|
17
|
-
|
|
18
|
-
This is why the parser pushes `Missing subcommand: <path>` for a group command
|
|
19
|
-
that has subcommands but no `pikkuFuncId` of its own, rather than simply
|
|
20
|
-
returning the command meta and letting the runner discover it is unrunnable. The
|
|
21
|
-
message _is_ the routing signal. Rewording any of those three strings, or
|
|
22
|
-
localising them, silently turns "show me the subcommands" into a raw error dump.
|
|
23
|
-
|
|
24
|
-
**What this rules out:** editing those error message prefixes without updating
|
|
25
|
-
every `startsWith` site, and adding a new "this is a routing problem" parse error
|
|
26
|
-
without registering its prefix in both runners. If this needs to grow, replace
|
|
27
|
-
the whole scheme with a discriminated error type in one change — do not add a
|
|
28
|
-
fourth magic prefix.
|
|
@@ -1,34 +0,0 @@
|
|
|
1
|
-
---
|
|
2
|
-
type: decision
|
|
3
|
-
title: CLI stdout is reserved for machine-readable output
|
|
4
|
-
description: The default renderer emits single-line NDJSON, diagnostics go to stderr, and --json only hijacks rendering for commands that declared a renderer
|
|
5
|
-
tags: cli
|
|
6
|
-
---
|
|
7
|
-
|
|
8
|
-
# CLI stdout is reserved for machine-readable output
|
|
9
|
-
|
|
10
|
-
`defaultJSONRenderer` in `packages/core/src/wirings/cli/cli-runner.ts` (and its
|
|
11
|
-
twin in `channel/cli-channel-runner.ts`) calls `JSON.stringify` without an
|
|
12
|
-
indent argument. That is not laziness: one result per line is NDJSON, which stays
|
|
13
|
-
parseable when a command streams multiple results through the CLI channel.
|
|
14
|
-
Pretty-printing spreads one record over many lines and breaks every line-oriented
|
|
15
|
-
consumer downstream.
|
|
16
|
-
|
|
17
|
-
Two rules follow from the same principle in `executeCLI`. Parse warnings —
|
|
18
|
-
non-fatal by design, see the unknown-options decision — are written with
|
|
19
|
-
`console.error`, so they never interleave into a command's machine-readable
|
|
20
|
-
stdout. And `--json` / `--output json` only substitutes `defaultJSONRenderer`
|
|
21
|
-
when the command declared its own `render`; a command with no renderer is one
|
|
22
|
-
that prints inline as it works, and forcing its return value through the JSON
|
|
23
|
-
renderer would append a stray record after output that was never structured to
|
|
24
|
-
begin with. The `commandRenderer !== undefined` guard in the render block is what
|
|
25
|
-
enforces that.
|
|
26
|
-
|
|
27
|
-
Error formatting follows too: `isExpectedError(error)` prints `error.message`
|
|
28
|
-
alone with no `Error:` prefix, because an expected `PikkuError` (a build gate
|
|
29
|
-
tripping, a validation failure) has a message written to be read as the whole
|
|
30
|
-
output. Anything else is logged as an object so its stack survives.
|
|
31
|
-
|
|
32
|
-
**What this rules out:** adding an indent argument to `defaultJSONRenderer`,
|
|
33
|
-
routing warnings or progress messages to stdout, and dropping the
|
|
34
|
-
`commandRenderer !== undefined` condition so `--json` applies uniformly.
|
|
@@ -1,29 +0,0 @@
|
|
|
1
|
-
---
|
|
2
|
-
type: decision
|
|
3
|
-
title: CLI unknown long options warn instead of failing
|
|
4
|
-
description: Unrecognised --long options are accepted, warned about and dropped so older binaries tolerate newer invocations, while unknown short flags stay hard errors
|
|
5
|
-
tags: cli
|
|
6
|
-
---
|
|
7
|
-
|
|
8
|
-
# CLI unknown long options warn instead of failing
|
|
9
|
-
|
|
10
|
-
`warnUnknownOption` in `packages/core/src/wirings/cli/command-parser.ts` pushes
|
|
11
|
-
onto `ParsedCommand.warnings`, not `ParsedCommand.errors`, so an unrecognised
|
|
12
|
-
`--long` option does not abort the command. The value is still parsed into
|
|
13
|
-
`optionArgs`, but `pluckCLIData` in `cli-runner.ts` drops anything absent from
|
|
14
|
-
the function's input schema — so the option is silently ignored at execution
|
|
15
|
-
time. The warning exists precisely so that dropping is not silent.
|
|
16
|
-
|
|
17
|
-
The reason is forward compatibility: a script or wrapper written against a newer
|
|
18
|
-
command version may pass options an older installed binary does not know, and
|
|
19
|
-
failing hard there turns a harmless extra flag into a broken pipeline.
|
|
20
|
-
`RESERVED_OPTIONS` exempts flags the runner handles itself (`help`) from the
|
|
21
|
-
warning. Unknown _short_ flags are treated differently — they go to
|
|
22
|
-
`result.errors` and do fail — because a bundled short-flag cluster like `-abc`
|
|
23
|
-
cannot be reliably attributed, and a typo'd short flag is far more likely than a
|
|
24
|
-
version skew.
|
|
25
|
-
|
|
26
|
-
**What this rules out:** promoting unknown long options to errors "for
|
|
27
|
-
strictness", and removing the warning on the grounds that the schema pluck
|
|
28
|
-
already handles it — that restores the silent drop this was added to end. It also
|
|
29
|
-
rules out making unknown short flags non-fatal for symmetry.
|