@pikku/core 0.12.141 → 0.12.142

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.
Files changed (237) hide show
  1. package/CHANGELOG.md +33 -0
  2. package/dist/errors/errors.d.ts +1 -1
  3. package/dist/errors/errors.js +1 -1
  4. package/dist/function/function-meta.types.d.ts +6 -6
  5. package/dist/function/functions.types.d.ts +2 -2
  6. package/dist/services/audit-service.d.ts +4 -4
  7. package/dist/services/feature-flag-service.d.ts +3 -3
  8. package/dist/services/{http-personas.d.ts → http-virtual-users.d.ts} +25 -47
  9. package/dist/services/{http-personas.js → http-virtual-users.js} +29 -53
  10. package/dist/services/index.d.ts +2 -2
  11. package/dist/services/index.js +1 -1
  12. package/dist/services/meta-service.d.ts +6 -6
  13. package/dist/services/meta-service.js +8 -8
  14. package/dist/{wirings/workflow → services}/scenario-cookie-jar.d.ts +2 -0
  15. package/dist/{wirings/workflow → services}/scenario-cookie-jar.js +18 -14
  16. package/dist/services/system-role-guard.d.ts +1 -1
  17. package/dist/services/virtual-user-sign-in.d.ts +52 -0
  18. package/dist/services/virtual-user-sign-in.js +80 -0
  19. package/dist/services/virtual-user-statement.d.ts +31 -0
  20. package/dist/services/virtual-user-statement.js +24 -0
  21. package/dist/services/{personas-service.d.ts → virtual-users-service.d.ts} +25 -23
  22. package/dist/services/{personas-service.js → virtual-users-service.js} +3 -3
  23. package/dist/types/core.types.d.ts +11 -11
  24. package/dist/wirings/role/define-system-role.d.ts +1 -1
  25. package/dist/wirings/role/define-system-role.js +1 -1
  26. package/dist/wirings/{actor-flow/actor-flow.types.d.ts → virtual-user/conversation/conversation.types.d.ts} +5 -5
  27. package/dist/wirings/virtual-user/conversation/index.d.ts +2 -0
  28. package/dist/wirings/virtual-user/conversation/run-conversation.d.ts +36 -0
  29. package/dist/wirings/{actor-flow → virtual-user/conversation}/run-conversation.js +30 -30
  30. package/dist/wirings/virtual-user/define-virtual-users.d.ts +32 -0
  31. package/dist/wirings/{persona/define-personas.js → virtual-user/define-virtual-users.js} +9 -9
  32. package/dist/wirings/virtual-user/index.d.ts +30 -7
  33. package/dist/wirings/virtual-user/index.js +23 -4
  34. package/dist/wirings/virtual-user/prepare-virtual-user-run.d.ts +8 -8
  35. package/dist/wirings/virtual-user/prepare-virtual-user-run.js +9 -9
  36. package/dist/wirings/virtual-user/run-virtual-user.d.ts +6 -6
  37. package/dist/wirings/virtual-user/run-virtual-user.js +10 -10
  38. package/dist/wirings/{persona/validate-personas.d.ts → virtual-user/validate-virtual-users.d.ts} +11 -11
  39. package/dist/wirings/{persona/validate-personas.js → virtual-user/validate-virtual-users.js} +24 -24
  40. package/dist/wirings/virtual-user/virtual-user-agents.d.ts +7 -7
  41. package/dist/wirings/virtual-user/virtual-user-agents.js +2 -2
  42. package/dist/wirings/{persona/persona-app-scopes.d.ts → virtual-user/virtual-user-app-scopes.d.ts} +10 -10
  43. package/dist/wirings/{persona/persona-app-scopes.js → virtual-user/virtual-user-app-scopes.js} +12 -12
  44. package/dist/wirings/virtual-user/virtual-user-catalogue.d.ts +3 -3
  45. package/dist/wirings/virtual-user/virtual-user-catalogue.js +2 -2
  46. package/dist/wirings/{persona/persona.types.d.ts → virtual-user/virtual-user-declaration.types.d.ts} +24 -24
  47. package/dist/wirings/virtual-user/virtual-user-derive.js +13 -7
  48. package/dist/wirings/virtual-user/virtual-user-dispositions.d.ts +1 -1
  49. package/dist/wirings/{persona/persona-email.d.ts → virtual-user/virtual-user-email.d.ts} +11 -11
  50. package/dist/wirings/{persona/persona-email.js → virtual-user/virtual-user-email.js} +19 -19
  51. package/dist/wirings/{persona/persona-environments.d.ts → virtual-user/virtual-user-environments.d.ts} +10 -10
  52. package/dist/wirings/{persona/persona-environments.js → virtual-user/virtual-user-environments.js} +21 -21
  53. package/dist/wirings/virtual-user/virtual-user-intents.d.ts +3 -3
  54. package/dist/wirings/virtual-user/virtual-user-intents.js +3 -3
  55. package/dist/wirings/{persona/persona-mailbox.d.ts → virtual-user/virtual-user-mailbox.d.ts} +4 -4
  56. package/dist/wirings/virtual-user/virtual-user-run-store.d.ts +4 -4
  57. package/dist/wirings/virtual-user/virtual-user-scaffold.d.ts +42 -61
  58. package/dist/wirings/virtual-user/virtual-user-scaffold.js +69 -117
  59. package/dist/wirings/virtual-user/virtual-user-schedule-store.d.ts +15 -15
  60. package/dist/wirings/virtual-user/virtual-user-schedule.d.ts +6 -6
  61. package/dist/wirings/virtual-user/virtual-user-schedule.js +11 -11
  62. package/dist/wirings/virtual-user/virtual-user-target.d.ts +6 -6
  63. package/dist/wirings/virtual-user/virtual-user-target.js +5 -5
  64. package/dist/wirings/virtual-user/virtual-user.types.d.ts +11 -11
  65. package/dist/wirings/virtual-user/virtual-user.types.js +1 -1
  66. package/dist/wirings/workflow/dsl/workflow-dsl.types.d.ts +9 -9
  67. package/dist/wirings/workflow/pikku-scenario-service.d.ts +28 -28
  68. package/dist/wirings/workflow/pikku-scenario-service.js +77 -77
  69. package/dist/wirings/workflow/pikku-workflow-service.d.ts +2 -2
  70. package/dist/wirings/workflow/pikku-workflow-service.js +4 -4
  71. package/dist/wirings/workflow/scenario-prose.d.ts +8 -8
  72. package/dist/wirings/workflow/scenario-prose.js +12 -8
  73. package/dist/wirings/workflow/scenario-run.types.d.ts +13 -13
  74. package/dist/wirings/workflow/scenario-step.types.d.ts +23 -23
  75. package/dist/wirings/workflow/workflow.types.d.ts +2 -2
  76. package/knowledge/decisions/index.md +0 -2
  77. package/knowledge/decisions/internals/a-credential-name-declared-twice-must-agree-on-schema-and-type.md +29 -0
  78. package/knowledge/decisions/internals/a-grant-can-name-a-scope-declared-without-its-addon.md +29 -0
  79. package/knowledge/decisions/internals/a-scheduled-task-writes-its-caller-session-before-it-runs.md +22 -0
  80. package/knowledge/decisions/internals/a-secret-set-in-memory-shadows-the-variable-of-the-same-name.md +28 -0
  81. package/knowledge/decisions/internals/a-virtual-user-acts-through-invokeraw-so-a-refusal-is-data.md +32 -0
  82. package/knowledge/decisions/internals/a-virtual-user-cadence-is-a-row-not-a-timer.md +12 -12
  83. package/knowledge/decisions/internals/a-virtual-user-converse-signs-in-before-its-first-turn.md +24 -0
  84. package/knowledge/decisions/internals/a-virtual-user-email-is-computed-with-the-run-id-as-a-sub-address.md +34 -0
  85. package/knowledge/decisions/internals/a-virtual-user-run-is-not-a-workflow-but-it-needs-a-trigger.md +2 -2
  86. package/knowledge/decisions/internals/an-agent-is-offered-under-its-registry-key-and-only-within-the-virtual-users-scopes.md +27 -0
  87. package/knowledge/decisions/internals/an-oauth2-credential-implies-an-optional-app-secret.md +26 -0
  88. package/knowledge/decisions/internals/analytics-identity-resolvers-run-in-declared-order.md +22 -0
  89. package/knowledge/decisions/internals/feature-flag-declarations-refuse-an-empty-anyof-and-conflicting-scopes.md +22 -0
  90. package/knowledge/decisions/internals/feature-flags-fail-open-and-never-enforce-access.md +28 -0
  91. package/knowledge/decisions/internals/flag-sync-rewrites-only-the-declared-text.md +24 -0
  92. package/knowledge/decisions/internals/in-a-scenario-a-4xx-is-data-not-an-exception.md +3 -3
  93. package/knowledge/decisions/internals/index.md +46 -31
  94. package/knowledge/decisions/internals/one-project-shape-check-two-validators.md +10 -10
  95. package/knowledge/decisions/internals/role-names-cannot-contain-the-scope-separator.md +30 -0
  96. package/knowledge/decisions/internals/scenario-agent-calls-sign-in-on-401-only.md +23 -19
  97. package/knowledge/decisions/internals/scenario-steps-return-drained-response-records.md +2 -2
  98. package/knowledge/decisions/internals/scenarios-live-in-files-named-for-them.md +12 -12
  99. package/knowledge/decisions/internals/the-core-scope-validator-refuses-separator-wildcard-and-empty-segments.md +22 -0
  100. package/knowledge/decisions/internals/the-pikku-user-id-resolves-in-a-fixed-order.md +24 -0
  101. package/knowledge/decisions/internals/{the-actor-prompt-says-json-because-of-json-object-mode.md → the-virtual-user-prompt-says-json-because-of-json-object-mode.md} +4 -4
  102. package/knowledge/decisions/internals/{the-persona-runtime-is-exported-from-the-persona-entry-point.md → the-virtual-user-runtime-is-exported-from-the-virtual-user-entry-point.md} +8 -8
  103. package/knowledge/decisions/internals/validate-checks-virtual-users-through-a-shared-module.md +43 -0
  104. package/knowledge/decisions/internals/{actor-flow-drives-the-target-through-a-transport-seam.md → virtual-user-conversation-drives-the-target-through-a-transport-seam.md} +6 -6
  105. package/knowledge/decisions/internals/virtual-user-conversation-verdicts-are-llm-self-evaluations.md +25 -0
  106. package/knowledge/decisions/internals/virtual-user-conversations-seed-a-hidden-kickoff-message.md +23 -0
  107. package/knowledge/decisions/internals/virtual-users-are-declared-in-one-definevirtualusers-call-per-codebase.md +30 -0
  108. package/knowledge/decisions/internals/workflow-core-never-imports-a-browser-driver.md +5 -5
  109. package/knowledge/decisions/internals/workflow-run-capabilities-are-extensions-not-subclasses.md +2 -2
  110. package/knowledge/decisions/internals/workflow-scenario-assertions-never-retry-and-record-one-step.md +4 -4
  111. package/knowledge/decisions/internals/workflow-scenario-hooks-are-a-scenario-only-affordance.md +1 -1
  112. package/knowledge/decisions/internals/workflow-scenario-prose-is-rendered-from-typed-calls-not-parsed-from-english.md +2 -2
  113. package/knowledge/decisions/internals/workflow-scenario-step-targets-are-string-literals-for-the-inspector.md +1 -1
  114. package/knowledge/decisions/internals/workflow-suspended-runs-keep-their-in-process-context.md +1 -1
  115. package/knowledge/decisions/security/a-bearer-token-checked-against-a-secret-reads-it-per-request.md +26 -0
  116. package/knowledge/decisions/security/a-call-without-a-session-raises-missing-session-not-forbidden.md +20 -0
  117. package/knowledge/decisions/security/a-caller-cookie-wins-over-the-jar-for-the-same-name.md +23 -0
  118. package/knowledge/decisions/security/a-channel-lifecycle-acts-as-the-socket-upgrade-session.md +16 -0
  119. package/knowledge/decisions/security/a-channel-requires-a-session-unless-it-says-auth-false.md +26 -0
  120. package/knowledge/decisions/security/a-credential-read-path-follows-its-declared-type-not-absence.md +32 -0
  121. package/knowledge/decisions/security/a-credential-type-is-a-literal-the-inspector-checks-at-declaration.md +27 -0
  122. package/knowledge/decisions/security/a-first-party-cookie-is-written-only-after-its-purposes-consent.md +33 -0
  123. package/knowledge/decisions/security/a-readonly-session-reaches-only-readonly-functions.md +25 -0
  124. package/knowledge/decisions/security/a-scaffold-flag-says-a-surface-exists-not-who-may-call-it.md +10 -5
  125. package/knowledge/decisions/security/a-scheduled-virtual-user-run-needs-no-admin-at-run-time.md +27 -0
  126. package/knowledge/decisions/security/a-scoped-credential-view-is-limited-to-declared-names.md +26 -0
  127. package/knowledge/decisions/security/a-scoped-secret-view-reads-only-declared-keys-and-never-writes.md +25 -0
  128. package/knowledge/decisions/security/a-secret-is-sent-only-to-the-hosts-it-declares.md +29 -0
  129. package/knowledge/decisions/security/a-step-can-name-an-identity-no-virtual-user-holds-through-per-call-headers.md +25 -0
  130. package/knowledge/decisions/security/a-stopped-run-by-id-skips-the-ownership-check.md +24 -0
  131. package/knowledge/decisions/security/a-vault-secret-redacts-on-serialization-and-throws-on-coercion.md +29 -0
  132. package/knowledge/decisions/security/a-virtual-user-catalogue-entry-is-filtered-by-scope-and-approval-is-denied-by-default.md +30 -0
  133. package/knowledge/decisions/security/a-virtual-user-environment-fails-closed.md +38 -0
  134. package/knowledge/decisions/security/a-virtual-user-never-runs-against-production.md +23 -0
  135. package/knowledge/decisions/security/a-virtual-user-reads-its-roles-from-the-apps-own-rpc-before-better-auth.md +27 -0
  136. package/knowledge/decisions/security/a-virtual-user-run-treats-an-unresolved-environment-as-production.md +41 -0
  137. package/knowledge/decisions/security/a-virtual-user-scopes-are-expanded-from-its-roles-once-at-run-preparation.md +25 -0
  138. package/knowledge/decisions/security/a-virtual-user-whose-roles-drift-from-the-declaration-refuses-to-run.md +32 -0
  139. package/knowledge/decisions/security/addon-screen-scopes-hide-and-do-not-enforce.md +20 -0
  140. package/knowledge/decisions/security/an-addon-header-can-only-narrow-the-session.md +26 -0
  141. package/knowledge/decisions/security/an-addon-instance-reads-only-the-secrets-and-credentials-it-is-named.md +33 -0
  142. package/knowledge/decisions/security/an-addon-may-reach-only-itself-and-the-addons-it-uses.md +16 -0
  143. package/knowledge/decisions/security/an-api-key-is-jwt-decoded-into-the-session.md +26 -0
  144. package/knowledge/decisions/security/an-external-virtual-user-caller-presents-one-signed-statement.md +38 -0
  145. package/knowledge/decisions/security/an-inbound-webhook-source-dispatches-only-verified-requests.md +31 -0
  146. package/knowledge/decisions/security/an-mcp-call-with-no-http-request-stays-anonymous.md +18 -0
  147. package/knowledge/decisions/security/an-omitted-user-id-addresses-the-platform-credential.md +32 -0
  148. package/knowledge/decisions/security/analytics-identity-is-stamped-from-the-session-not-the-event.md +24 -0
  149. package/knowledge/decisions/security/app-access-is-a-scope-tree-synthesised-from-virtual-users.md +26 -0
  150. package/knowledge/decisions/security/approval-policy-decides-who-answers-a-tool-call.md +27 -0
  151. package/knowledge/decisions/security/auth-false-on-a-session-function-warns-and-still-requires-one.md +25 -0
  152. package/knowledge/decisions/security/bearer-token-hashes-are-unpeppered-sha256.md +18 -0
  153. package/knowledge/decisions/security/consent-is-read-from-a-cookie-and-a-recognised-denial-counts-as-refusal.md +29 -0
  154. package/knowledge/decisions/security/cors-defaults-to-any-origin-and-refuses-the-wildcard-with-credentials.md +22 -0
  155. package/knowledge/decisions/security/credential-backends-share-one-conformance-suite-for-per-user-isolation.md +29 -0
  156. package/knowledge/decisions/security/each-stage-has-one-virtual-user-key-pair.md +27 -0
  157. package/knowledge/decisions/security/hmac-verification-fails-closed-on-empty-inputs.md +25 -0
  158. package/knowledge/decisions/security/index.md +88 -24
  159. package/knowledge/decisions/security/local-content-refuses-private-buckets-under-the-public-segment.md +21 -0
  160. package/knowledge/decisions/security/mail-is-allowlisted-before-a-virtual-user-run-sees-it.md +38 -0
  161. package/knowledge/decisions/security/mcp-resources-tools-and-prompts-take-sessionless-functions.md +18 -0
  162. package/knowledge/decisions/security/origin-locked-routes-match-the-origin-exactly.md +22 -0
  163. package/knowledge/decisions/security/oss-auth-works-without-pikku-studio-cloud.md +26 -0
  164. package/knowledge/decisions/security/outbound-webhooks-use-an-allowlist-when-configured.md +24 -0
  165. package/knowledge/decisions/security/pikku-carries-virtual-user-scopes-as-data-and-the-app-grants-them.md +35 -0
  166. package/knowledge/decisions/security/scoped-content-access-is-a-root-folder-with-longest-prefix-grants.md +31 -0
  167. package/knowledge/decisions/security/services-without-secrets-get-a-throwing-secrets-accessor.md +22 -0
  168. package/knowledge/decisions/security/shared-guards-refuse-to-mutate-or-shadow-a-system-role.md +34 -0
  169. package/knowledge/decisions/security/signed-uploads-are-verified-by-the-same-check-as-signed-reads.md +26 -0
  170. package/knowledge/decisions/security/system-role-scopes-must-be-declared-with-define-scope.md +24 -0
  171. package/knowledge/decisions/security/system-roles-are-additive-and-immutable.md +16 -0
  172. package/knowledge/decisions/security/the-channel-rpc-does-not-send-the-callers-session.md +21 -0
  173. package/knowledge/decisions/security/the-remote-jobs-inbox-fails-closed-without-a-secret.md +24 -0
  174. package/knowledge/decisions/security/the-remote-rpc-gate-fails-closed-and-binds-the-token-to-its-function.md +34 -0
  175. package/knowledge/decisions/security/the-workflow-status-stream-rechecks-ownership-on-every-poll.md +16 -0
  176. package/knowledge/decisions/security/two-credentials-on-one-key-must-share-a-read-mode.md +29 -0
  177. package/knowledge/decisions/security/verified-bearer-claims-are-pass-through-data-that-core-never-fills.md +23 -0
  178. package/knowledge/decisions/security/virtual-user-catalogue-excludes-the-machinery-that-runs-virtual-users.md +25 -0
  179. package/knowledge/decisions/security/{actor-flow-missing-approval-decisions-default-to-denied.md → virtual-user-conversation-missing-approval-decisions-default-to-denied.md} +7 -7
  180. package/knowledge/decisions/security/virtual-user-run-records-are-gated-behind-a-read-scope.md +18 -0
  181. package/knowledge/decisions/security/virtual-user-sign-in-does-not-exist-in-production.md +25 -0
  182. package/knowledge/decisions/security/virtual-user-sign-in-has-one-door.md +42 -0
  183. package/knowledge/decisions/security/{actor-sign-in-is-proven-by-set-cookie-not-a-non-empty-jar.md → virtual-user-sign-in-is-proven-by-set-cookie-not-a-non-empty-jar.md} +10 -8
  184. package/knowledge/decisions/security/virtual-user-sign-in-only-works-for-virtual-user-flagged-users.md +29 -0
  185. package/knowledge/decisions/security/workflow-helper-functions-are-sessionless-by-declaration.md +18 -0
  186. package/knowledge/decisions/security/{workflow-scenario-sessions-are-isolated-per-actor-and-per-scenario.md → workflow-scenario-sessions-are-isolated-per-virtual-user-and-per-scenario.md} +6 -6
  187. package/knowledge/decisions/security/workflow-scenario-steps-are-never-network-invocable.md +5 -5
  188. package/knowledge/decisions/security/{workflow-actor-steps-always-use-the-real-transport.md → workflow-virtual-user-steps-always-use-the-real-transport.md} +11 -11
  189. package/knowledge/decisions/security/writing-a-virtual-user-schedule-is-gated-by-its-own-scope.md +18 -0
  190. package/knowledge/index.md +0 -2
  191. package/knowledge/questions/a-bearer-jwt-with-no-identity-becomes-a-session.md +24 -0
  192. package/knowledge/questions/dev-quick-login-as-impersonation.md +25 -0
  193. package/knowledge/questions/does-a-delayed-rpc-run-as-the-session-it-was-scheduled-with.md +26 -0
  194. package/knowledge/questions/does-a-user-id-with-a-colon-read-another-users-credentials.md +27 -0
  195. package/knowledge/questions/does-a-wirecli-command-need-a-session-by-default.md +26 -0
  196. package/knowledge/questions/does-an-adversarial-in-scope-success-count-as-a-finding.md +26 -0
  197. package/knowledge/questions/does-approve-step-need-the-run-owners-session-or-the-gates-approvers.md +34 -0
  198. package/knowledge/questions/does-cors-origin-true-reflect-any-origin-with-credentials.md +20 -0
  199. package/knowledge/questions/does-skip-user-session-do-anything-on-a-channel.md +24 -0
  200. package/knowledge/questions/does-the-store-session-match-the-other-two.md +19 -0
  201. package/knowledge/questions/index.md +25 -2
  202. package/knowledge/questions/is-the-agent-score-worker-reachable-without-a-session.md +21 -0
  203. package/knowledge/questions/live-scheduled-tests-may-write.md +19 -0
  204. package/knowledge/questions/provision-virtual-users-has-no-caller-in-this-repo.md +23 -0
  205. package/knowledge/questions/remote-secret-refuses-requests-without-a-remote-token-on-every-path.md +32 -0
  206. package/knowledge/questions/should-a-middleware-set-session-persist-to-the-store.md +25 -0
  207. package/knowledge/questions/should-a-scoped-secret-view-throw-from-has-secret-for-a-disallowed-key.md +23 -0
  208. package/knowledge/questions/should-a-wrong-bearer-token-be-anonymous-or-refused.md +35 -0
  209. package/knowledge/questions/should-an-empty-webhook-signing-secret-send-unsigned.md +23 -0
  210. package/knowledge/questions/should-http-virtual-user-sessions-reset-between-scenarios-in-one-run.md +27 -0
  211. package/knowledge/questions/should-the-cookie-jar-scope-cookies-to-the-api-origin.md +26 -0
  212. package/knowledge/questions/should-voice-input-fetch-audio-urls-without-a-host-allowlist.md +20 -0
  213. package/knowledge/questions/staging-impersonation-rules.md +27 -0
  214. package/knowledge/questions/virtual-user-keys-on-cloud-stages-are-pikku-studios-to-build.md +34 -0
  215. package/knowledge/questions/virtual-user-statement-replay-is-per-process.md +20 -0
  216. package/knowledge/questions/what-an-impersonated-session-carries.md +22 -0
  217. package/package.json +2 -3
  218. package/src/public-surface.json +38 -47
  219. package/dist/services/persona-actor-secret.d.ts +0 -38
  220. package/dist/services/persona-actor-secret.js +0 -39
  221. package/dist/services/persona-sign-in.d.ts +0 -117
  222. package/dist/services/persona-sign-in.js +0 -154
  223. package/dist/wirings/actor-flow/index.d.ts +0 -2
  224. package/dist/wirings/actor-flow/run-conversation.d.ts +0 -36
  225. package/dist/wirings/persona/define-personas.d.ts +0 -32
  226. package/dist/wirings/persona/index.d.ts +0 -23
  227. package/dist/wirings/persona/index.js +0 -19
  228. package/knowledge/decisions/internals/actor-flow-conversations-seed-a-hidden-kickoff-message.md +0 -23
  229. package/knowledge/decisions/internals/actor-flow-verdicts-are-llm-self-evaluations.md +0 -25
  230. package/knowledge/decisions/internals/validate-checks-personas-through-a-shared-module.md +0 -43
  231. package/knowledge/decisions/security/actor-sign-in-only-works-for-actor-flagged-users.md +0 -31
  232. package/knowledge/decisions/security/an-actor-credential-is-derived-per-persona.md +0 -42
  233. package/knowledge/decisions/security/pikku-carries-actor-scopes-as-data-and-the-app-grants-them.md +0 -26
  234. /package/dist/wirings/{actor-flow/actor-flow.types.js → virtual-user/conversation/conversation.types.js} +0 -0
  235. /package/dist/wirings/{actor-flow → virtual-user/conversation}/index.js +0 -0
  236. /package/dist/wirings/{persona/persona.types.js → virtual-user/virtual-user-declaration.types.js} +0 -0
  237. /package/dist/wirings/{persona/persona-mailbox.js → virtual-user/virtual-user-mailbox.js} +0 -0
@@ -1,21 +1,21 @@
1
1
  /**
2
- * No-op function for declaring personas.
2
+ * No-op function for declaring virtual users.
3
3
  * This exists purely for TypeScript type checking and will be tree-shaken.
4
- * The CLI extracts metadata via AST parsing and generates a `PersonaId` union
5
- * and a `personas.gen.json` the console and `pikku persona run` read off disk —
4
+ * The CLI extracts metadata via AST parsing and generates a `VirtualUserId` union
5
+ * and a `virtual-users.gen.json` the console and `pikku virtual-user run` read off disk —
6
6
  * describing, listing or running one never has to load the app.
7
7
  *
8
- * `definePersonas` rather than `defineVirtualUsers` because declaring is not
9
- * running: a persona that exists only to be acted upon (the account an admin
10
- * bans, the colleague a document is shared with) is seeded and never run.
8
+ * Declaring is not running: a virtual user that exists only to be acted upon
9
+ * (the account an admin bans, the colleague a document is shared with) is
10
+ * seeded and never run.
11
11
  *
12
- * Exactly one `definePersonas(...)` is allowed per codebase, so there is one
12
+ * Exactly one `defineVirtualUsers(...)` is allowed per codebase, so there is one
13
13
  * place to read the cast from and one place to add to. A second call — even in
14
14
  * the same file — fails the build.
15
15
  *
16
16
  * @example
17
17
  * ```typescript
18
- * definePersonas({
18
+ * defineVirtualUsers({
19
19
  * susan: {
20
20
  * name: 'Susan',
21
21
  * jobTitle: 'Buys for a small café',
@@ -28,4 +28,4 @@
28
28
  * })
29
29
  * ```
30
30
  */
31
- export const definePersonas = (_config) => { };
31
+ export const defineVirtualUsers = (_config) => { };
@@ -1,7 +1,7 @@
1
1
  /**
2
2
  * Virtual user module exports.
3
3
  *
4
- * A virtual user is an LLM playing a persona that signs into a *running* stage
4
+ * A virtual user is an LLM that signs into a *running* stage
5
5
  * and works its API in character — non-deterministically, with a budget, and
6
6
  * with oracles watching what comes back. It is not a test runner: nothing here
7
7
  * asserts an expected outcome, because the point is the outcomes nobody thought
@@ -9,24 +9,47 @@
9
9
  *
10
10
  * Everything it needs is derived from what a pikku project already generates —
11
11
  * the function meta becomes the catalogue, the scenario meta becomes the
12
- * intents, the declared personas become the identities — so adopting it is
12
+ * intents, the declared virtual users become the identities — so adopting it is
13
13
  * configuration rather than authoring.
14
14
  *
15
15
  * The engine is transport-agnostic: the virtual user drives an
16
- * {@link VirtualUserTarget}, which in production is an `HttpPersona`
16
+ * {@link VirtualUserTarget}, which in production is an `HttpVirtualUser`
17
17
  * signed in as a real user against staging or production.
18
18
  */
19
19
  export type { ApiCatalogueEntry, IntentRecord, IntentSource, StepRecord, VirtualUserBudget, VirtualUserDisposition, VirtualUserFinding, VirtualUserRunResult, VirtualUserTarget, } from './virtual-user.types.js';
20
20
  export { PRODUCTION_DISPOSITION } from './virtual-user.types.js';
21
21
  export { runVirtualUser, type RunVirtualUserParams, } from './run-virtual-user.js';
22
- export { personaScopes, prepareVirtualUserRun, type VirtualUserPreparation, } from './prepare-virtual-user-run.js';
22
+ export { virtualUserScopes, prepareVirtualUserRun, type VirtualUserPreparation, } from './prepare-virtual-user-run.js';
23
23
  export type { VirtualUserRunOutcome, VirtualUserRunRecord, VirtualUserRunStart, VirtualUserRunStore, } from './virtual-user-run-store.js';
24
24
  export type { VirtualUserScheduleInput, VirtualUserScheduleRecord, VirtualUserScheduleStore, } from './virtual-user-schedule-store.js';
25
25
  export { DEFAULT_MAX_INTERVAL_MS, DEFAULT_MIN_INTERVAL_MS, isDue, nextRunAt, STALE_RUN_AFTER_MS, tickVirtualUserSchedules, type VirtualUserTickParams, type VirtualUserTickResult, } from './virtual-user-schedule.js';
26
26
  export { DISPOSITIONS, dispositionProfile, type DispositionProfile, type VirtualUserTuning, } from './virtual-user-dispositions.js';
27
27
  export { catalogueClassification, catalogueLookup, isReadOnly, reachableCatalogue, unreachableCatalogue, } from './virtual-user-catalogue.js';
28
28
  export { type AgentReachability, type ReachableAgent, } from './virtual-user-agents.js';
29
- export { IntentStack, intentsForPersona } from './virtual-user-intents.js';
29
+ export { IntentStack, intentsForVirtualUser } from './virtual-user-intents.js';
30
30
  export { deriveCatalogue, deriveIntents, type SchemaMap, } from './virtual-user-derive.js';
31
- export { personaVirtualUserTarget, type PersonaTargetOptions, } from './virtual-user-target.js';
32
- export { executeVirtualUserRun, logVirtualUserTick, requireVirtualUserRunStore, requireVirtualUserScheduleStore, runnablePersona, serializeVirtualUserRun, serializeVirtualUserSchedule, serializeVirtualUserSteps, signInPathFor, startVirtualUserRun, VIRTUAL_USER_VARIABLES, virtualUserScheduleRunInput, writeVirtualUserSchedule, type ExecuteVirtualUserRunParams, type ScaffoldPersonas, type StartedVirtualUserRun, type StartVirtualUserRunParams, type WriteVirtualUserScheduleParams, } from './virtual-user-scaffold.js';
31
+ export { virtualUserTarget, type VirtualUserTargetOptions, } from './virtual-user-target.js';
32
+ export { executeVirtualUserRun, logVirtualUserTick, requireVirtualUserRunStore, requireVirtualUserScheduleStore, runnableVirtualUser, serializeVirtualUserRun, serializeVirtualUserSchedule, serializeVirtualUserSteps, startVirtualUserRun, VIRTUAL_USER_VARIABLES, virtualUserScheduleRunInput, writeVirtualUserSchedule, type ExecuteVirtualUserRunParams, type ScaffoldVirtualUsers, type StartedVirtualUserRun, type StartVirtualUserRunParams, type WriteVirtualUserScheduleParams, } from './virtual-user-scaffold.js';
33
+ export { defineVirtualUsers } from './define-virtual-users.js';
34
+ export { isRunnableVirtualUser, roleMismatchMessage, runnableVirtualUsers, validateAndBuildVirtualUsersMeta, verifyVirtualUserRoles, } from './validate-virtual-users.js';
35
+ export type { RoleVerification } from './validate-virtual-users.js';
36
+ export { virtualUserEnvironmentErrors, virtualUserEnvironmentRefusal, } from './virtual-user-environments.js';
37
+ export type { VirtualUserEnvironment, VirtualUserEnvironmentSubject, } from './virtual-user-environments.js';
38
+ export { virtualUserEmail, virtualUserEmails } from './virtual-user-email.js';
39
+ export { APP_SCOPE_ROOT, appScopeId, buildAppScopeDefinition, } from './virtual-user-app-scopes.js';
40
+ export type { MailboxAllowlist, VirtualUserMailbox, ReceivedEmail, } from './virtual-user-mailbox.js';
41
+ export type { CoreVirtualUser, CoreVirtualUsers, VirtualUserAccountMeta, VirtualUserDefinitions, VirtualUserMeta, VirtualUsersMeta, } from './virtual-user-declaration.types.js';
42
+ /**
43
+ * Signing in as a virtual user and talking to a stage over HTTP.
44
+ *
45
+ * Deliberately reached through this entry point rather than `@pikku/core/services`.
46
+ * `HttpVirtualUser` pulls in the conversation runner and, through it, the
47
+ * agent runner — none of which a production server has any use for. Exporting it
48
+ * from the services barrel put that chain in the module graph of every app that
49
+ * imports services, which only a bundler could remove and an unbundled Node or
50
+ * Lambda deploy would load outright.
51
+ */
52
+ export { HttpVirtualUser, createHttpVirtualUsers, type HttpVirtualUsersConfig, } from '../../services/http-virtual-users.js';
53
+ export { statementSignIn, inProcessSignIn, authMount, type VirtualUserSignIn, type VirtualUserStatementMint, type StatementSignInOptions, type InProcessAuth, } from '../../services/virtual-user-sign-in.js';
54
+ export { createCookieJar, type ScenarioCookieJar, } from '../../services/scenario-cookie-jar.js';
55
+ export { postScenarioJson, readScenarioHttpResponse, } from '../../services/virtual-users-service.js';
@@ -1,10 +1,29 @@
1
1
  export { PRODUCTION_DISPOSITION } from './virtual-user.types.js';
2
2
  export { runVirtualUser, } from './run-virtual-user.js';
3
- export { personaScopes, prepareVirtualUserRun, } from './prepare-virtual-user-run.js';
3
+ export { virtualUserScopes, prepareVirtualUserRun, } from './prepare-virtual-user-run.js';
4
4
  export { DEFAULT_MAX_INTERVAL_MS, DEFAULT_MIN_INTERVAL_MS, isDue, nextRunAt, STALE_RUN_AFTER_MS, tickVirtualUserSchedules, } from './virtual-user-schedule.js';
5
5
  export { DISPOSITIONS, dispositionProfile, } from './virtual-user-dispositions.js';
6
6
  export { catalogueClassification, catalogueLookup, isReadOnly, reachableCatalogue, unreachableCatalogue, } from './virtual-user-catalogue.js';
7
- export { IntentStack, intentsForPersona } from './virtual-user-intents.js';
7
+ export { IntentStack, intentsForVirtualUser } from './virtual-user-intents.js';
8
8
  export { deriveCatalogue, deriveIntents, } from './virtual-user-derive.js';
9
- export { personaVirtualUserTarget, } from './virtual-user-target.js';
10
- export { executeVirtualUserRun, logVirtualUserTick, requireVirtualUserRunStore, requireVirtualUserScheduleStore, runnablePersona, serializeVirtualUserRun, serializeVirtualUserSchedule, serializeVirtualUserSteps, signInPathFor, startVirtualUserRun, VIRTUAL_USER_VARIABLES, virtualUserScheduleRunInput, writeVirtualUserSchedule, } from './virtual-user-scaffold.js';
9
+ export { virtualUserTarget, } from './virtual-user-target.js';
10
+ export { executeVirtualUserRun, logVirtualUserTick, requireVirtualUserRunStore, requireVirtualUserScheduleStore, runnableVirtualUser, serializeVirtualUserRun, serializeVirtualUserSchedule, serializeVirtualUserSteps, startVirtualUserRun, VIRTUAL_USER_VARIABLES, virtualUserScheduleRunInput, writeVirtualUserSchedule, } from './virtual-user-scaffold.js';
11
+ export { defineVirtualUsers } from './define-virtual-users.js';
12
+ export { isRunnableVirtualUser, roleMismatchMessage, runnableVirtualUsers, validateAndBuildVirtualUsersMeta, verifyVirtualUserRoles, } from './validate-virtual-users.js';
13
+ export { virtualUserEnvironmentErrors, virtualUserEnvironmentRefusal, } from './virtual-user-environments.js';
14
+ export { virtualUserEmail, virtualUserEmails } from './virtual-user-email.js';
15
+ export { APP_SCOPE_ROOT, appScopeId, buildAppScopeDefinition, } from './virtual-user-app-scopes.js';
16
+ /**
17
+ * Signing in as a virtual user and talking to a stage over HTTP.
18
+ *
19
+ * Deliberately reached through this entry point rather than `@pikku/core/services`.
20
+ * `HttpVirtualUser` pulls in the conversation runner and, through it, the
21
+ * agent runner — none of which a production server has any use for. Exporting it
22
+ * from the services barrel put that chain in the module graph of every app that
23
+ * imports services, which only a bundler could remove and an unbundled Node or
24
+ * Lambda deploy would load outright.
25
+ */
26
+ export { HttpVirtualUser, createHttpVirtualUsers, } from '../../services/http-virtual-users.js';
27
+ export { statementSignIn, inProcessSignIn, authMount, } from '../../services/virtual-user-sign-in.js';
28
+ export { createCookieJar, } from '../../services/scenario-cookie-jar.js';
29
+ export { postScenarioJson, readScenarioHttpResponse, } from '../../services/virtual-users-service.js';
@@ -5,19 +5,19 @@ import { type SchemaMap } from './virtual-user-derive.js';
5
5
  import { type AgentReachability, type ReachableAgent } from './virtual-user-agents.js';
6
6
  import type { ApiCatalogueEntry, IntentSource } from './virtual-user.types.js';
7
7
  /**
8
- * The scopes a persona holds, resolved through its roles.
8
+ * The scopes a virtual user holds, resolved through its roles.
9
9
  *
10
- * Roles are the only thing a persona declares; scopes are what a function
10
+ * Roles are the only thing a virtual user declares; scopes are what a function
11
11
  * checks. Narrowing a virtual user's catalogue needs the second, so the
12
12
  * expansion happens once, here, against the same `defineSystemRole` definitions
13
13
  * the seed grants from.
14
14
  */
15
- export declare const personaScopes: (persona: {
15
+ export declare const virtualUserScopes: (virtualUser: {
16
16
  roles?: readonly string[];
17
17
  }, roleScopes: Record<string, readonly string[]>) => string[];
18
18
  /** Everything a run needs that is derived rather than decided. */
19
19
  export interface VirtualUserPreparation {
20
- /** Every RPC the app exposes, narrowed to what this persona can reach. */
20
+ /** Every RPC the app exposes, narrowed to what this virtual user can reach. */
21
21
  catalogue: ApiCatalogueEntry[];
22
22
  intents: IntentSource[];
23
23
  scopes: string[];
@@ -27,18 +27,18 @@ export interface VirtualUserPreparation {
27
27
  * Derive what a virtual user needs from what the project already generates.
28
28
  *
29
29
  * Shared because there are two callers with the same problem and different
30
- * sources for it: `pikku persona run` reads the inspector state at build time,
30
+ * sources for it: `pikku virtual-user run` reads the inspector state at build time,
31
31
  * and the scaffolded `runVirtualUser` RPC reads `metaService` at runtime. They
32
- * must agree — a persona whose catalogue is narrower over RPC than on the CLI
32
+ * must agree — a virtual user whose catalogue is narrower over RPC than on the CLI
33
33
  * finds different things from the same seed, which is exactly the property a
34
34
  * seed exists to give.
35
35
  *
36
36
  * Nothing here is authored for the virtual user's benefit: the function meta is
37
37
  * the catalogue, the scenario meta is the intents, and the role definitions are
38
- * what turn a persona's declared roles into the scopes a function checks.
38
+ * what turn a virtual user's declared roles into the scopes a function checks.
39
39
  */
40
40
  export declare const prepareVirtualUserRun: (input: {
41
- persona: {
41
+ virtualUser: {
42
42
  roles?: readonly string[];
43
43
  };
44
44
  functionsMeta: FunctionsMeta;
@@ -2,16 +2,16 @@ import { flattenSystemRoleDefinitions } from '../role/validate-role-definitions.
2
2
  import { deriveCatalogue, deriveIntents, } from './virtual-user-derive.js';
3
3
  import { reachableAgents, } from './virtual-user-agents.js';
4
4
  /**
5
- * The scopes a persona holds, resolved through its roles.
5
+ * The scopes a virtual user holds, resolved through its roles.
6
6
  *
7
- * Roles are the only thing a persona declares; scopes are what a function
7
+ * Roles are the only thing a virtual user declares; scopes are what a function
8
8
  * checks. Narrowing a virtual user's catalogue needs the second, so the
9
9
  * expansion happens once, here, against the same `defineSystemRole` definitions
10
10
  * the seed grants from.
11
11
  */
12
- export const personaScopes = (persona, roleScopes) => {
12
+ export const virtualUserScopes = (virtualUser, roleScopes) => {
13
13
  const scopes = new Set();
14
- for (const role of persona.roles ?? []) {
14
+ for (const role of virtualUser.roles ?? []) {
15
15
  for (const scope of roleScopes[role] ?? []) {
16
16
  scopes.add(scope);
17
17
  }
@@ -22,15 +22,15 @@ export const personaScopes = (persona, roleScopes) => {
22
22
  * Derive what a virtual user needs from what the project already generates.
23
23
  *
24
24
  * Shared because there are two callers with the same problem and different
25
- * sources for it: `pikku persona run` reads the inspector state at build time,
25
+ * sources for it: `pikku virtual-user run` reads the inspector state at build time,
26
26
  * and the scaffolded `runVirtualUser` RPC reads `metaService` at runtime. They
27
- * must agree — a persona whose catalogue is narrower over RPC than on the CLI
27
+ * must agree — a virtual user whose catalogue is narrower over RPC than on the CLI
28
28
  * finds different things from the same seed, which is exactly the property a
29
29
  * seed exists to give.
30
30
  *
31
31
  * Nothing here is authored for the virtual user's benefit: the function meta is
32
32
  * the catalogue, the scenario meta is the intents, and the role definitions are
33
- * what turn a persona's declared roles into the scopes a function checks.
33
+ * what turn a virtual user's declared roles into the scopes a function checks.
34
34
  */
35
35
  export const prepareVirtualUserRun = (input) => {
36
36
  const catalogue = deriveCatalogue(input.functionsMeta, input.schemas ?? {});
@@ -40,10 +40,10 @@ export const prepareVirtualUserRun = (input) => {
40
40
  for (const role of flattenSystemRoleDefinitions(Array.isArray(declared) ? declared : Object.values(declared))) {
41
41
  roleScopes[role.name] = role.scopes;
42
42
  }
43
- const scopes = personaScopes(input.persona, roleScopes);
43
+ const scopes = virtualUserScopes(input.virtualUser, roleScopes);
44
44
  // Gated by the same scopes as the RPCs, because an agent is reached rather
45
45
  // than declared: `CoreAgent.scopes` is checked against the session, so a
46
- // persona finds the specialists its roles unlock and no others.
46
+ // virtual user finds the specialists its roles unlock and no others.
47
47
  const agents = reachableAgents(input.agentsMeta ?? {}, scopes);
48
48
  return { catalogue, intents, scopes, agents };
49
49
  };
@@ -1,5 +1,5 @@
1
- import type { ResolvedPersona } from '../../services/personas-service.js';
2
- import type { ActorLLM } from '../actor-flow/run-conversation.js';
1
+ import type { ResolvedVirtualUser } from '../../services/virtual-users-service.js';
2
+ import type { VirtualUserLLM } from './conversation/run-conversation.js';
3
3
  import { type VirtualUserTuning } from './virtual-user-dispositions.js';
4
4
  import type { ApiCatalogueEntry, IntentSource, VirtualUserBudget, VirtualUserDisposition, VirtualUserFinding, VirtualUserRunResult, VirtualUserTally, VirtualUserTarget } from './virtual-user.types.js';
5
5
  /** What an app-specific oracle is shown about one call. */
@@ -15,9 +15,9 @@ export interface VirtualUserCallContext {
15
15
  }
16
16
  export interface RunVirtualUserParams {
17
17
  /** The person being run — name, job title, personality, goals. */
18
- persona: ResolvedPersona;
18
+ virtualUser: ResolvedVirtualUser;
19
19
  /** The id they were declared under, as the intent sources refer to them. */
20
- personaId: string;
20
+ virtualUserId: string;
21
21
  /** How it behaves. Default `realistic`. */
22
22
  disposition?: VirtualUserDisposition;
23
23
  /** Per-user overrides for that disposition's dials. */
@@ -31,7 +31,7 @@ export interface RunVirtualUserParams {
31
31
  /** The transport it acts through. */
32
32
  target: VirtualUserTarget;
33
33
  /** The user's own LLM. */
34
- llm: ActorLLM;
34
+ llm: VirtualUserLLM;
35
35
  model: string;
36
36
  budget?: VirtualUserBudget;
37
37
  /**
@@ -60,7 +60,7 @@ export interface RunVirtualUserParams {
60
60
  /** Ids and slugs remembered from an earlier run, for a `stale` user. */
61
61
  memory?: Record<string, string>;
62
62
  /**
63
- * The scopes this persona actually holds, resolved from its roles at sign-in.
63
+ * The scopes this virtual user actually holds, resolved from its roles at sign-in.
64
64
  *
65
65
  * Used two ways: to narrow a large catalogue to what it is entitled to reach,
66
66
  * and as an oracle — a call whose scopes it does not hold that nonetheless
@@ -1,7 +1,7 @@
1
1
  import { getDurationInMilliseconds } from '../../time-utils.js';
2
2
  import { catalogueIndex, catalogueLookup, describeEntry, isReadOnly, reachableCatalogue, renderCatalogue, } from './virtual-user-catalogue.js';
3
3
  import { dispositionProfile, } from './virtual-user-dispositions.js';
4
- import { IntentStack, intentsForPersona } from './virtual-user-intents.js';
4
+ import { IntentStack, intentsForVirtualUser } from './virtual-user-intents.js';
5
5
  import { createRng } from './virtual-user-rng.js';
6
6
  /** One turn: what the user decided to do next, and why. */
7
7
  const ACTION_SCHEMA = {
@@ -108,11 +108,11 @@ export const rememberIds = (body, into, depth = 0) => {
108
108
  }
109
109
  return into;
110
110
  };
111
- const personaInstructions = (persona, profile, catalogue, agents, fixtures) => [
111
+ const virtualUserInstructions = (virtualUser, profile, catalogue, agents, fixtures) => [
112
112
  `You are a real person using a product through its API. Stay in character; you are the user, not the system.`,
113
- `Your name is ${persona.name}.`,
114
- persona.jobTitle ? `Your role: ${persona.jobTitle}.` : '',
115
- persona.personality ? `Your manner: ${persona.personality}.` : '',
113
+ `Your name is ${virtualUser.name}.`,
114
+ virtualUser.jobTitle ? `Your role: ${virtualUser.jobTitle}.` : '',
115
+ virtualUser.personality ? `Your manner: ${virtualUser.personality}.` : '',
116
116
  '',
117
117
  profile.instructions,
118
118
  '',
@@ -146,7 +146,7 @@ const personaInstructions = (persona, profile, catalogue, agents, fixtures) => [
146
146
  * work inside it stays genuinely open-ended.
147
147
  */
148
148
  export const runVirtualUser = async (params) => {
149
- const { persona, personaId, disposition = 'realistic', tuning, target, llm, model, budget, stop, validateOutput, classify, fixtures = [], agents = [], scopes, allowApprovalRequired = false, maxStepsPerIntent = DEFAULT_MAX_STEPS_PER_INTENT, } = params;
149
+ const { virtualUser, virtualUserId, disposition = 'realistic', tuning, target, llm, model, budget, stop, validateOutput, classify, fixtures = [], agents = [], scopes, allowApprovalRequired = false, maxStepsPerIntent = DEFAULT_MAX_STEPS_PER_INTENT, } = params;
150
150
  const profile = dispositionProfile(disposition, tuning);
151
151
  const seed = params.seed ?? Math.floor(Math.random() * 2 ** 31);
152
152
  const rng = createRng(seed);
@@ -161,7 +161,7 @@ export const runVirtualUser = async (params) => {
161
161
  });
162
162
  const index = catalogueIndex(reachable);
163
163
  const sources = [
164
- ...intentsForPersona(params.intents, personaId),
164
+ ...intentsForVirtualUser(params.intents, virtualUserId),
165
165
  ...(params.goals ?? []).map((goal, i) => ({
166
166
  id: `goal_${i + 1}`,
167
167
  title: goal,
@@ -191,7 +191,7 @@ export const runVirtualUser = async (params) => {
191
191
  : typeof budget.duration === 'number'
192
192
  ? budget.duration
193
193
  : getDurationInMilliseconds(budget.duration);
194
- const instructions = personaInstructions(persona, profile, renderCatalogue(reachable), agents, fixtures);
194
+ const instructions = virtualUserInstructions(virtualUser, profile, renderCatalogue(reachable), agents, fixtures);
195
195
  const addFinding = (finding) => {
196
196
  findings.push(finding);
197
197
  tally.findings++;
@@ -423,7 +423,7 @@ export const runVirtualUser = async (params) => {
423
423
  });
424
424
  }
425
425
  }
426
- // This persona does not hold the scopes this endpoint declares, and the
426
+ // This virtual user does not hold the scopes this endpoint declares, and the
427
427
  // server served it anyway — the declaration and the enforcement disagree.
428
428
  if (response.ok &&
429
429
  scopes &&
@@ -431,7 +431,7 @@ export const runVirtualUser = async (params) => {
431
431
  kinds.push('unexpected-success');
432
432
  addFinding({
433
433
  kind: 'unexpected-success',
434
- detail: `${entry.name} succeeded for '${personaId}', who does not hold ${entry.scopes
434
+ detail: `${entry.name} succeeded for '${virtualUserId}', who does not hold ${entry.scopes
435
435
  .filter((scope) => !scopes.includes(scope))
436
436
  .join(', ')}`,
437
437
  rpcName: entry.name,
@@ -1,9 +1,9 @@
1
- import type { PersonaDefinitions, PersonaMeta, PersonasMeta } from './persona.types.js';
1
+ import type { VirtualUserDefinitions, VirtualUserMeta, VirtualUsersMeta } from './virtual-user-declaration.types.js';
2
2
  /**
3
- * Whether a persona can actually be driven by a virtual user.
3
+ * Whether a virtual user can actually be run.
4
4
  *
5
5
  * A provider login cannot: driving Google's or GitHub's consent screen needs a
6
- * human, so the persona is seedable and assertable but not runnable. Derived
6
+ * human, so the virtual user is seedable and assertable but not runnable. Derived
7
7
  * rather than asked for, because it is a consequence of the account rather than
8
8
  * a separate decision — and a flag someone must remember to set is a flag that
9
9
  * ships wrong.
@@ -11,22 +11,22 @@ import type { PersonaDefinitions, PersonaMeta, PersonasMeta } from './persona.ty
11
11
  * An explicit `runnable: false` still wins: it marks the person who is only
12
12
  * ever acted *upon*, which no account shape reveals.
13
13
  */
14
- export declare const isRunnablePersona: (persona: {
14
+ export declare const isRunnableVirtualUser: (virtualUser: {
15
15
  runnable?: boolean;
16
16
  account?: {
17
17
  provider?: string;
18
18
  };
19
19
  }) => boolean;
20
20
  /**
21
- * Validates declared personas and keys them by id.
21
+ * Validates declared virtual users and keys them by id.
22
22
  *
23
23
  * Definitions sharing an id must be identical; a conflicting redeclaration is a
24
24
  * hard error naming both source files, on the same terms as scopes and roles.
25
25
  */
26
- export declare function validateAndBuildPersonasMeta(definitions: PersonaDefinitions): PersonasMeta;
26
+ export declare function validateAndBuildVirtualUsersMeta(definitions: VirtualUserDefinitions): VirtualUsersMeta;
27
27
  /** What a run compares against the store before its first step. */
28
28
  export interface RoleVerification {
29
- persona: string;
29
+ virtualUserId: string;
30
30
  expected: string[];
31
31
  actual: string[];
32
32
  missing: string[];
@@ -34,20 +34,20 @@ export interface RoleVerification {
34
34
  ok: boolean;
35
35
  }
36
36
  /**
37
- * Compares a persona's declared roles against what the stage actually granted.
37
+ * Compares a virtual user's declared roles against what the stage actually granted.
38
38
  *
39
39
  * Run at sign-in, before the first step. The declaration is authoritative —
40
40
  * the generated seed applies it — but pikku cannot guarantee the seed ran on a
41
41
  * stage it did not deploy, and virtual users are meant to run against staging
42
42
  * and production, so that case is the normal one.
43
43
  *
44
- * Both directions matter, for opposite reasons. An under-granted persona
44
+ * Both directions matter, for opposite reasons. An under-granted virtual user
45
45
  * reports authorization bugs that are really seed drift. An over-granted one
46
46
  * silently stops testing the boundary it was written to test — nothing fails,
47
47
  * the findings just quietly stop being about anything.
48
48
  */
49
- export declare const verifyPersonaRoles: (persona: string, expected: readonly string[], actual: readonly string[]) => RoleVerification;
49
+ export declare const verifyVirtualUserRoles: (virtualUserId: string, expected: readonly string[], actual: readonly string[]) => RoleVerification;
50
50
  /** The message a run stops with, or `null` when the roles line up. */
51
51
  export declare const roleMismatchMessage: (verification: RoleVerification) => string | null;
52
52
  /** Convenience: the meta a run needs, with `runnable` already resolved. */
53
- export declare const runnablePersonas: (meta: PersonasMeta) => PersonaMeta[];
53
+ export declare const runnableVirtualUsers: (meta: VirtualUsersMeta) => VirtualUserMeta[];
@@ -1,8 +1,8 @@
1
1
  /**
2
- * Whether a persona can actually be driven by a virtual user.
2
+ * Whether a virtual user can actually be run.
3
3
  *
4
4
  * A provider login cannot: driving Google's or GitHub's consent screen needs a
5
- * human, so the persona is seedable and assertable but not runnable. Derived
5
+ * human, so the virtual user is seedable and assertable but not runnable. Derived
6
6
  * rather than asked for, because it is a consequence of the account rather than
7
7
  * a separate decision — and a flag someone must remember to set is a flag that
8
8
  * ships wrong.
@@ -10,62 +10,62 @@
10
10
  * An explicit `runnable: false` still wins: it marks the person who is only
11
11
  * ever acted *upon*, which no account shape reveals.
12
12
  */
13
- export const isRunnablePersona = (persona) => {
14
- if (persona.runnable === false) {
13
+ export const isRunnableVirtualUser = (virtualUser) => {
14
+ if (virtualUser.runnable === false) {
15
15
  return false;
16
16
  }
17
- return persona.account?.provider === undefined;
17
+ return virtualUser.account?.provider === undefined;
18
18
  };
19
19
  /**
20
- * Validates declared personas and keys them by id.
20
+ * Validates declared virtual users and keys them by id.
21
21
  *
22
22
  * Definitions sharing an id must be identical; a conflicting redeclaration is a
23
23
  * hard error naming both source files, on the same terms as scopes and roles.
24
24
  */
25
- export function validateAndBuildPersonasMeta(definitions) {
25
+ export function validateAndBuildVirtualUsersMeta(definitions) {
26
26
  const meta = {};
27
- for (const persona of definitions) {
28
- if (!persona.id) {
29
- throw new Error('A persona is declared with an empty id.');
27
+ for (const virtualUser of definitions) {
28
+ if (!virtualUser.id) {
29
+ throw new Error('A virtual user is declared with an empty id.');
30
30
  }
31
- if (!persona.name) {
32
- throw new Error(`Persona '${persona.id}' has no name. A persona is a person; give them one.`);
31
+ if (!virtualUser.name) {
32
+ throw new Error(`VirtualUser '${virtualUser.id}' has no name. A virtual user is a person; give them one.`);
33
33
  }
34
- const existing = meta[persona.id];
34
+ const existing = meta[virtualUser.id];
35
35
  if (existing) {
36
36
  const same = JSON.stringify({ ...existing, sourceFile: undefined }) ===
37
- JSON.stringify({ ...persona, sourceFile: undefined });
37
+ JSON.stringify({ ...virtualUser, sourceFile: undefined });
38
38
  if (!same) {
39
- throw new Error(`Persona '${persona.id}' is declared twice with different content.\n` +
39
+ throw new Error(`VirtualUser '${virtualUser.id}' is declared twice with different content.\n` +
40
40
  ` First declaration: ${existing.sourceFile ?? 'unknown'}\n` +
41
- ` Second declaration: ${persona.sourceFile ?? 'unknown'}`);
41
+ ` Second declaration: ${virtualUser.sourceFile ?? 'unknown'}`);
42
42
  }
43
43
  continue;
44
44
  }
45
- meta[persona.id] = persona;
45
+ meta[virtualUser.id] = virtualUser;
46
46
  }
47
47
  return meta;
48
48
  }
49
49
  /**
50
- * Compares a persona's declared roles against what the stage actually granted.
50
+ * Compares a virtual user's declared roles against what the stage actually granted.
51
51
  *
52
52
  * Run at sign-in, before the first step. The declaration is authoritative —
53
53
  * the generated seed applies it — but pikku cannot guarantee the seed ran on a
54
54
  * stage it did not deploy, and virtual users are meant to run against staging
55
55
  * and production, so that case is the normal one.
56
56
  *
57
- * Both directions matter, for opposite reasons. An under-granted persona
57
+ * Both directions matter, for opposite reasons. An under-granted virtual user
58
58
  * reports authorization bugs that are really seed drift. An over-granted one
59
59
  * silently stops testing the boundary it was written to test — nothing fails,
60
60
  * the findings just quietly stop being about anything.
61
61
  */
62
- export const verifyPersonaRoles = (persona, expected, actual) => {
62
+ export const verifyVirtualUserRoles = (virtualUserId, expected, actual) => {
63
63
  const expectedSet = new Set(expected);
64
64
  const actualSet = new Set(actual);
65
65
  const missing = [...expectedSet].filter((r) => !actualSet.has(r)).sort();
66
66
  const extra = [...actualSet].filter((r) => !expectedSet.has(r)).sort();
67
67
  return {
68
- persona,
68
+ virtualUserId,
69
69
  expected: [...expectedSet].sort(),
70
70
  actual: [...actualSet].sort(),
71
71
  missing,
@@ -85,10 +85,10 @@ export const roleMismatchMessage = (verification) => {
85
85
  if (verification.extra.length) {
86
86
  parts.push(`unexpectedly holds ${verification.extra.join(', ')}`);
87
87
  }
88
- return (`Persona '${verification.persona}' ${parts.join(' and ')}. ` +
88
+ return (`VirtualUser '${verification.virtualUserId}' ${parts.join(' and ')}. ` +
89
89
  `Declared: ${verification.expected.join(', ') || 'none'}. ` +
90
90
  `On the stage: ${verification.actual.join(', ') || 'none'}. ` +
91
- `Refusing to run — findings from a persona whose roles have drifted are about the seed, not the product.`);
91
+ `Refusing to run — findings from a virtual user whose roles have drifted are about the seed, not the product.`);
92
92
  };
93
93
  /** Convenience: the meta a run needs, with `runnable` already resolved. */
94
- export const runnablePersonas = (meta) => Object.values(meta).filter((persona) => persona.runnable);
94
+ export const runnableVirtualUsers = (meta) => Object.values(meta).filter((virtualUser) => virtualUser.runnable);
@@ -1,14 +1,14 @@
1
1
  /**
2
- * Which of the product's agents a persona can actually talk to.
2
+ * Which of the product's agents a virtual user can actually talk to.
3
3
  *
4
- * An agent is not something a persona declares. It is something a persona
4
+ * An agent is not something a virtual user declares. It is something a virtual user
5
5
  * *reaches*, under exactly the rule an RPC is reached by: `CoreAgent.scopes`
6
- * is checked against the session, so a persona holding the scopes an agent
6
+ * is checked against the session, so a virtual user holding the scopes an agent
7
7
  * requires finds it in front of them, and one that does not, does not.
8
8
  *
9
- * That is the whole reason a persona has no `agent:` field. Naming one would
9
+ * That is the whole reason a virtual user has no `agent:` field. Naming one would
10
10
  * add no capability the roles do not already confer, and would narrow the
11
- * persona to a single brain when the interesting behaviour is the choice
11
+ * virtual user to a single brain when the interesting behaviour is the choice
12
12
  * between calling the API directly and handing the work to a specialist.
13
13
  */
14
14
  /** The part of an agent's meta this needs. */
@@ -28,12 +28,12 @@ export interface ReachableAgent {
28
28
  * That key is the export's own name, which is what `addAgent` stores and what
29
29
  * `resolveAgent` looks up. The `name` an agent declares in its config is a
30
30
  * display label and is frequently something else entirely — offering that one
31
- * hands the persona a name the server cannot resolve, and the run dies on a
31
+ * hands the virtual user a name the server cannot resolve, and the run dies on a
32
32
  * 500 the moment it takes the offer.
33
33
  *
34
34
  * Like {@link reachableCatalogue}, this narrows *what is offered* and never
35
35
  * what is enforced: the server decides who may talk to what, and an agent
36
- * answering a persona this filter would have withheld is a finding rather than
36
+ * answering a virtual user this filter would have withheld is a finding rather than
37
37
  * a bug here.
38
38
  *
39
39
  * An agent declaring no scopes is offered to everybody, on the same terms as a
@@ -5,12 +5,12 @@ import { hasScopes } from '../../scopes.js';
5
5
  * That key is the export's own name, which is what `addAgent` stores and what
6
6
  * `resolveAgent` looks up. The `name` an agent declares in its config is a
7
7
  * display label and is frequently something else entirely — offering that one
8
- * hands the persona a name the server cannot resolve, and the run dies on a
8
+ * hands the virtual user a name the server cannot resolve, and the run dies on a
9
9
  * 500 the moment it takes the offer.
10
10
  *
11
11
  * Like {@link reachableCatalogue}, this narrows *what is offered* and never
12
12
  * what is enforced: the server decides who may talk to what, and an agent
13
- * answering a persona this filter would have withheld is a finding rather than
13
+ * answering a virtual user this filter would have withheld is a finding rather than
14
14
  * a bug here.
15
15
  *
16
16
  * An agent declaring no scopes is offered to everybody, on the same terms as a
@@ -1,5 +1,5 @@
1
1
  import type { ScopeDefinitionMeta } from '../scope/scope.types.js';
2
- import type { PersonaMeta } from './persona.types.js';
2
+ import type { VirtualUserMeta } from './virtual-user-declaration.types.js';
3
3
  /**
4
4
  * The root every app grant hangs off. One segment, so a grant of `app` alone
5
5
  * means "may use all of them" under the same parent-grant rule the admin tree
@@ -10,16 +10,16 @@ export declare const APP_SCOPE_ROOT = "app";
10
10
  /** `app:staff` for `staff`. */
11
11
  export declare const appScopeId: (app: string) => string;
12
12
  /**
13
- * The apps named across the declared personas, sorted and deduplicated.
13
+ * The apps named across the declared virtual users, sorted and deduplicated.
14
14
  *
15
- * The personas *are* the registry. There is no separate list of apps to keep in
15
+ * The virtual users *are* the registry. There is no separate list of apps to keep in
16
16
  * step, because a frontend nobody signs into is not a thing the auth layer has
17
17
  * an opinion about — and the moment somebody does sign into it, they are a
18
- * persona and they name it.
18
+ * virtual user and they name it.
19
19
  */
20
- export declare const declaredApps: (personas: PersonaMeta[]) => string[];
20
+ export declare const declaredApps: (virtualUsers: VirtualUserMeta[]) => string[];
21
21
  /**
22
- * The `app` scope tree, synthesised from the personas that name an app.
22
+ * The `app` scope tree, synthesised from the virtual users that name an app.
23
23
  *
24
24
  * Which frontend a person may sign into is a different question from what they
25
25
  * may do once inside it, but it is the same *kind* of question — a grant that
@@ -31,11 +31,11 @@ export declare const declaredApps: (personas: PersonaMeta[]) => string[];
31
31
  *
32
32
  * Synthesised rather than written by hand because the declaration already
33
33
  * exists. Asking an app to also spell out `defineScope({ app: { staff: {} } })`
34
- * beside its personas invites the two to drift, and the failure that produces —
35
- * a persona provisioned with a grant the vocabulary no longer declares — is one
34
+ * beside its virtual users invites the two to drift, and the failure that produces —
35
+ * a virtual user provisioned with a grant the vocabulary no longer declares — is one
36
36
  * `pikku scopes prune` away from silently revoking sign-in.
37
37
  *
38
- * Null when no persona names an app, which is the single-frontend case: nothing
38
+ * Null when no virtual user names an app, which is the single-frontend case: nothing
39
39
  * to declare, and no empty root cluttering the console's grant list.
40
40
  */
41
- export declare const buildAppScopeDefinition: (personas: PersonaMeta[]) => ScopeDefinitionMeta | null;
41
+ export declare const buildAppScopeDefinition: (virtualUsers: VirtualUserMeta[]) => ScopeDefinitionMeta | null;