pomerado 0.1.2 → 0.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -4,7 +4,7 @@
4
4
  <p align="center">Describe what you want to do on a website. Pomerado builds an integration your agent can use.</p>
5
5
 
6
6
  <p align="center">
7
- <a href="LICENSE"><img src="https://img.shields.io/badge/license-AGPL--3.0--only-blue?style=for-the-badge" alt="License AGPL-3.0-only"></a>
7
+ <a href="LICENSE"><img src="https://img.shields.io/badge/license-MIT-blue?style=for-the-badge" alt="License MIT"></a>
8
8
  <img src="https://img.shields.io/badge/node-24.21%2B%20%3C25-339933?style=for-the-badge&amp;logo=nodedotjs&amp;logoColor=white" alt="Node 24.21 or later in Node 24">
9
9
  <img src="https://img.shields.io/badge/pnpm-10.34.5-F69220?style=for-the-badge&amp;logo=pnpm&amp;logoColor=white" alt="pnpm 10.34.5">
10
10
  </p>
@@ -103,13 +103,13 @@ integrations/example_reader/
103
103
  ├── pomerado.json Entrypoint and input/output schemas
104
104
  ├── deployment.json Tool name, description, URL, intent and authority
105
105
  ├── mcp.mjs Fixed launcher for the shared Pomerado runtime
106
- ├── codex-mcp.toml Local Codex server configuration
106
+ ├── mcp.json Standard MCP server entry, with no key
107
107
  └── README.md Commands and usage for this integration
108
108
  ```
109
109
 
110
- 1. Open the generated `README.md` and `codex-mcp.toml`.
111
- 2. Copy the generated MCP section into `~/.codex/config.toml`. It already contains your local Node, launcher and runtime paths.
112
- 3. Make sure Codex can forward `OPENAI_API_KEY`. Generated integrations still use Guardian.
110
+ 1. Open the generated `README.md`. It lists the add command for each major MCP client, with your local Node, launcher and runtime paths filled in.
111
+ 2. Add the server to your client, or copy the entry in `mcp.json` into a client that reads an `mcpServers` file.
112
+ 3. Make sure the server gets `OPENAI_API_KEY` from its environment. Generated integrations still use Guardian.
113
113
  4. Reload the MCP configuration in your client and ask it to use the integration.
114
114
 
115
115
  > Use example_reader to read the page heading.
@@ -168,7 +168,7 @@ This repository owns the shared minter, Guardian, operation runtime and live aut
168
168
  | `typescript/src/execution/` | Local workspaces, child processes and native Playwright adapter |
169
169
  | `typescript/src/standalone/` | Local library, terminal and MCP composition |
170
170
  | `typescript/src/mcp/schema.ts` | Pure schema adapter shared with the production MCP |
171
- | `typescript/authoring/` | Shared prompts and examples for local and hosted minting |
171
+ | `typescript/authoring/` | Shared prompts and examples, with sections a host can replace |
172
172
 
173
173
  <details>
174
174
  <summary>Runtime boundaries and browser compatibility</summary>
@@ -186,7 +186,7 @@ Here `kernel` is a compatibility object forwarding calls to native Playwright ov
186
186
 
187
187
  This public repository is the sole source for the shared core, portable tests, authoring assets and local MCP adapters. Cloud calls the installed library directly. Its hosted MCP frontend stays in the private repository with accounts, permissions and durable jobs.
188
188
 
189
- Cloud owns the REST backend, database, Kernel and hosted compute providers, recorder, evidence bundles, general privacy service, repair loop and credential storage. Cloud also owns Kernel CAPTCHA telemetry, antibot browser switching and proxy recovery notices.
189
+ Cloud owns the REST backend, database, hosted browser and compute providers, recorder, evidence bundles, general privacy service, repair loop, credential storage and its own hosted authoring text.
190
190
 
191
191
  Integrations run through native Playwright. The local host does not mint HTTP variants, record network traffic, produce `captures/routes.json`, or provide the hosted `SiteHttp` transport and capture replay helpers. Website requests made inside the browser remain available.
192
192
 
@@ -229,6 +229,7 @@ The package exposes local APIs and direct core library entry points. Importing a
229
229
  - Use explicit `pomerado/core/*` subpaths such as `pomerado/core/mint/harness`, `pomerado/core/guardian/review` and `pomerado/core/runtime/host-execute` for hosted library composition. The export map lists supported modules.
230
230
  - Use `pomerado/testing/*` for reusable test helpers and fixtures. Vitest is an optional peer for helpers that need it.
231
231
  - Use `getAuthoringDirectory` and `getGuardianPolicyPath` from `pomerado/assets` for installed prompt and policy paths. These paths resolve relative to the package.
232
+ - `loadAuthoringSkills` and `loadWorkspaceGuide` from `pomerado/core/mint/skills` render each named authoring section's standalone text by default. A host that supplies its own text for those sections composes the directory first, then loads it in `"hosted"` mode, which refuses any section left uncomposed.
232
233
 
233
234
  Run `corepack pnpm start --help` for the advanced terminal mint/run interface. Terminal mint retains its original source-artifact format. Use the MCP minting entrypoint for generated MCP packaging.
234
235
 
@@ -246,7 +247,7 @@ corepack pnpm test:browser
246
247
 
247
248
  This repository owns the portable tests for its shared core and local runtime, with synthetic fixtures and the existing Vitest and Playwright runners. Browser tests exercise native Playwright, minting through MCP, generated integration MCPs, authentication and autofill using local fixture sites and scripted model responses. They need no Cloud account or model API key. Tests for hosted services stay in the application repository.
248
249
 
249
- Outside pull requests are not accepted until a Contributor License Agreement is in place. Issues are welcome. See [CONTRIBUTING.md](CONTRIBUTING.md) for how changes land and [SECURITY.md](SECURITY.md) for reporting vulnerabilities privately.
250
+ Outside pull requests are not accepted yet. They open once the review and approval gate described in [CONTRIBUTING.md](CONTRIBUTING.md) is live. Issues are welcome. See [CONTRIBUTING.md](CONTRIBUTING.md) for how changes land and how to report a vulnerability privately.
250
251
 
251
252
  Public tests use synthetic sites and data. Keep customer-specific incidents, private credentials and internal issue references out of public contributions. CI enforces this with a gitleaks secret scan and a public content scan. Run `node tools/check-public-content.ts` before you push. Link a public issue by its full URL.
252
253
 
@@ -258,6 +259,8 @@ The clone and build quickstart works independently of npm releases. Contributors
258
259
 
259
260
  ---
260
261
 
261
- Copyright (c) 2026 Pomerado. Licensed under GNU Affero General Public License version 3 only (`AGPL-3.0-only`). See [LICENSE](LICENSE).
262
+ Copyright (c) 2026 Pomerado AI, Inc. Licensed under the MIT License (`MIT`). See [LICENSE](LICENSE).
263
+
264
+ Versions 0.1.2 and earlier were published under the GNU Affero General Public License version 3 only (`AGPL-3.0-only`).
262
265
 
263
266
  Third-party code keeps its own license. The Guardian policy in `typescript/src/guardian/upstream-policy.md` is adapted from [OpenAI Codex](https://github.com/openai/codex) under the Apache License 2.0. Its license and notice are in [third-party/codex/](third-party/codex/) and ship with the npm package.
@@ -15,12 +15,7 @@ or the data sits behind a login wall). Try a public task signed out first.
15
15
 
16
16
  # The login URL you record
17
17
 
18
- <!-- pomerado:hosted:start
19
- The `loginUrl` you pass on `authenticate` is published with the tool, and every run opens it to
20
- sign in. It must be a simple, stable route on the site: the page a person would bookmark to sign
21
- in, or where the site's own login link points before any redirect, read from that link. Never
22
- record:
23
- pomerado:hosted:end -->
18
+ <!-- pomerado:section auth.login-url -->
24
19
 
25
20
  - a URL carrying one-time values: `state`, `nonce`, `code_challenge`, `code`, `session_state`,
26
21
  `SAMLRequest`, or a signed token or opaque random value in its query or fragment;
@@ -62,79 +57,20 @@ ask with `request_input` right away. A preselected option says nothing about the
62
57
 
63
58
  # One screen at a time
64
59
 
65
- <!-- pomerado:hosted:start
66
- Before recording, reopen the published stable `loginUrl` and map the complete signed-out flow. Reopen that
67
- route and record the required entry navigation from there, not just the username form reached
68
- after manual choices. Record each observed panel opener, authorized account/plan choice or
69
- Continue control as `signInStep: { fields: [], submit: "the-observed-selector" }`. Include only
70
- navigation needed for sign-in; exploration before the login URL and Business account actions,
71
- registration and password reset do not belong in the recipe.
72
- pomerado:hosted:end -->
60
+ <!-- pomerado:section auth.signed-out-flow -->
73
61
 
74
62
  Record a field or submit only after observing its unique visible enabled match in the intended
75
63
  frame and form. Validate the complete live login and a fresh signed-out replay from the stable
76
64
  login URL. A saved DOM supports locator matching and extraction; it cannot prove live controls
77
65
  are actionable, their event handlers work or authentication succeeds.
78
66
 
79
- <!-- pomerado:hosted:start
80
- A run can begin partway through that flow because its bound profile or remembered device omitted
81
- an earlier stage. The host acts only on the observed recorded screen. It skips an earlier stage
82
- only when a later recorded page or distinct credential fields prove progression, or the published
83
- signed-in check verifies the session. A missing control, a timeout or a coincident Continue button
84
- on the same page does not prove an account choice happened. Record an authorized choice and its
85
- following Continue as separate steps.
86
- pomerado:hosted:end -->
67
+ <!-- pomerado:section auth.partial-flow -->
87
68
 
88
69
  Call `execute` with purpose `authenticate`, target `liveBrowser` and a `signInStep` for the screen in
89
70
  front of you. Pass the stable route you clicked as `loginUrl` on the first one (above), never the
90
71
  page it redirected to; runs open that route to replay your screens.
91
72
 
92
- <!-- pomerado:hosted:start
93
- - `fields`: each field the screen asks for, as a Playwright selector with exactly one visible match.
94
- A selector never reaches into another frame (no `>>` chains or `internal:` engines): the host finds
95
- each field in its own frame.
96
- - An identifier field lists every kind it accepts in `accepts`, from `username`, `email`,
97
- `phone` and `account_number`: a "username or email" field is `["username", "email"]`, an
98
- email-only field `["email"]`, a mobile-number field `["phone"]`, an account, member or customer
99
- number field `["account_number"]`. Read the label, type and placeholder. The host sends a kind
100
- the login holds (username first, then email, phone and account number) or asks the caller once
101
- for one it accepts. If it refuses the step as `identifier_conflict`, the answer was not this login's: send
102
- the step again to ask again.
103
- - `slot: "password"` for the password.
104
- - `slot: "code"` for a one-time or authenticator code. A saved authenticator seed answers it;
105
- otherwise the host asks the caller for the code. Never ask for a code yourself.
106
- - `slot: "date_of_birth"` for a date of birth, with `format`, how the field takes it, read from
107
- its placeholder, label, input mask or hint: `MM/DD/YYYY`, `DD/MM/YYYY`, `M/D/YYYY`,
108
- `D/M/YYYY`, `MM-DD-YYYY`, `DD-MM-YYYY`, `DD.MM.YYYY`, `YYYY-MM-DD`, `YYYY/MM/DD`, `MMDDYYYY`,
109
- `DDMMYYYY` or `YYYYMMDD`. A native date input (`type="date"`) is `YYYY-MM-DD`. A date split into
110
- a month, a day and a year is one field per part, each with its part's format: `MM` or `M` for a
111
- month by number, `MMM` or `MMMM` for a month by its short or full name, `DD` or `D` for the day,
112
- `YYYY` or `YY` for the year. A part may be a text box, a select or a custom dropdown: name the
113
- select, or the dropdown's own control (its combobox or the button that opens its list), never
114
- an option. The host fills the saved date into whatever control it finds, choosing the option
115
- whose label or value matches, and records the format and the control's shape with the tool,
116
- never the date. Every date layout, dropdowns included, is a screen you map.
117
- - `slot: "zip"` for a ZIP or postal code the site checks to prove the account.
118
- - `slot: "recovery_code"` for a backup or recovery code field. The host fills a saved one only
119
- while recovery codes are the method in force, else asks the caller. Never ask for one yourself.
120
- - `submit`: the observed enabled control that submits those fields or advances this sign-in screen
121
- ("Next", "Continue", "Sign in"). It may be a native button, a submit/button/image input, an HTML
122
- anchor or a custom ARIA action: use its evidenced role, label or stable selector and purpose.
123
- The host clicks it. A screen that advances by itself (the identifier fills and the password field
124
- appears by itself) names none; unrelated links or buttons on that page do not need a submit.
125
- A two-factor method choice ("Text me a code", "Use my authenticator app") fills no field: list
126
- every method the screen offers in `methods` (`sms`, `call`, `email`, `totp`, `push` or
127
- `recovery_code` for "use a backup code", each with
128
- the selector of the control that picks it) and name the one to pick now as `submit`, once the
129
- branch rule above settles which. The tool's runs pick again from that list. A method's selector
130
- publishes with the tool, so it never names the masked phone number or address the option shows
131
- (such as `***-1234`): use the method's own words or a stable attribute.
132
- - Every selector and submit you send publishes with the tool, as does each screen's page address.
133
- None may name this account's username, email or phone: not a "Continue as …" button's text, a
134
- data attribute holding it, or a placeholder for it. Name a control by its role, label or a stable
135
- attribute. The host refuses a step that names it (`selector_names_contact`), and a screen whose
136
- address names it (`page_names_contact`) is refused; use an account-independent route.
137
- pomerado:hosted:end -->
73
+ <!-- pomerado:section auth.step-fields -->
138
74
 
139
75
  A screen may record `rejectedMarkers`, each with a field slot and an observed, value-free
140
76
  rejection selector. The slots are `username`, `email`, `phone`, `account_number`, `password`,
@@ -142,14 +78,7 @@ rejection selector. The slots are `username`, `email`, `phone`, `account_number`
142
78
  sign-in; never invent a marker or submit bad credentials to discover one. The host reads only
143
79
  visibility and retains every rejected value so it cannot send that value again.
144
80
 
145
- <!-- pomerado:hosted:start
146
- On a combined password-and-code screen that returns empty, an explicit code rejection permits a
147
- fresh code with the unchanged password only while its two-send allowance remains. When the
148
- password remains in its field, retry only the fresh code. In a recorded replay, missing or
149
- ambiguous evidence about which field was rejected requests maintenance without resending the
150
- password. Report a rejection visible in the current mint even if no selector has been recorded
151
- yet; a visible recorded marker takes precedence over that report.
152
- pomerado:hosted:end -->
81
+ <!-- pomerado:section auth.code-rejection -->
153
82
 
154
83
  Guardian checks each step against the screen: that every field takes the kinds it lists, that the
155
84
  submit is the right sign-in action, including a fieldless continuation or verification-method
@@ -157,27 +86,9 @@ choice, and that a step without one advances by itself. The host checks that eac
157
86
  and visible and that its frame, form actions and link destination are on the site or a configured
158
87
  sign-in origin. A refused step typed and sent nothing and spends no sign-in: fix it from the evidence.
159
88
 
160
- <!-- pomerado:hosted:start
161
- Sign-in pages are often slow, and the next screen can take a while to show. Wait for its field with
162
- a bounded readiness wait (such as `locator.waitFor` with a timeout of about 30 seconds) before you
163
- map or fill it, and read the page again. Ask for a new browser with `request_browser_recovery` only
164
- after a reasonable wait still found nothing and the evidence points at the browser.
165
- pomerado:hosted:end -->
166
-
167
- <!-- pomerado:hosted:start
168
- After each step, read the next screen with a read-only `explore`. Never read, change or return a field
169
- the host filled, not even to check it. If the host reports that its click of the submit failed after
170
- the fields filled, you may click that one submit yourself in an `explore`, and nothing else; the host
171
- counts a value as sent only once it sees the form go out carrying it, whoever clicked. If it reports `submit: refused`, never click it.
172
- If the site says a field was wrong, send `signInStep: { rejected: { slot: "password" } }`
173
- with the actual rejected slot at once. The host asks for corrections; never ask for substitute
174
- credentials yourself or send a rejected value again. A primary identifier or password rejection
175
- asks for both username and password. A rejected secondary identifier, date of birth or ZIP asks
176
- only for that field; a recovery code uses the host's fresh-code ledger or question. The host allows
177
- at most two correction questions per rejected field per sign-in. Only submitted, visibly rejected
178
- fields consume their counters; `username` and the saved login's matching primary identifier share one
179
- counter. Worker takeover preserves these counters and rejected-value history.
180
- pomerado:hosted:end -->
89
+ <!-- pomerado:section auth.slow-screens -->
90
+
91
+ <!-- pomerado:section auth.next-screen -->
181
92
 
182
93
  A rejected code permits at most two fresh-code corrections within the remaining sign-in time.
183
94
  This does not extend the unchanged password's limit of two sends, including sends before worker
@@ -204,19 +115,11 @@ signed-in indicator; confirmation alone does not verify the session.
204
115
 
205
116
  # Signed in
206
117
 
207
- <!-- pomerado:hosted:start
208
- Prefer an observed protected business/account page or authenticated workflow control that the
209
- signed-out flow cannot reach, corroborated by the live business example. Generic Sign out or
210
- account chrome alone does not establish access to the caller's workflow. Call `authenticate`
211
- with `signInStep: { signedIn: { selector } }` (or `urlPath`, the observed signed-in page's path).
212
- When the landing page shows no such evidence, add `openPath`, the observed path of an account page
213
- that does, and the host opens it and checks there; never guess a protected route. The host checks
214
- that the submitted sign-in's recorded controls/form no longer show a password entry awaiting
215
- sign-in; unrelated password controls on the account page do not fail this check. It also checks
216
- that this sign-in submitted the login's identifier with its password, code or protected approval,
217
- then marks it verified; a Personal login locks to this site then. The indicator is part of the
218
- published tool: runs check it after they sign in. Business work waits for a verified sign-in.
219
- pomerado:hosted:end -->
118
+ <!-- pomerado:section auth.signed-in-evidence:start
119
+ Prefer an observed protected account page or authenticated workflow control that the signed-out
120
+ flow cannot reach, corroborated by the live business example. Generic Sign out or account chrome
121
+ alone does not establish access to the caller's workflow.
122
+ pomerado:section auth.signed-in-evidence:end -->
220
123
 
221
124
  # Popup sign-in
222
125
 
@@ -239,29 +142,15 @@ browser. A failed host check leaves this browser available for another evidenced
239
142
  that sign-in could not be verified when the site or the remaining allowance prevents recovery.
240
143
  Never send a visibly rejected value again. There is no provider-login fallback.
241
144
 
242
- <!-- pomerado:hosted:start
243
- After browser recovery, inspect the retained bound profile before signing in. When its published
244
- signed-in indicator verifies the identity, continue without another credential submission. When
245
- it is signed out, sign in from the observed recorded stage on that profile, preserving what the
246
- site remembers; do not clear storage or log out merely to force the full flow. A genuinely empty
247
- profile starts the observed fresh sign-in flow.
248
- pomerado:hosted:end -->
145
+ <!-- pomerado:section auth.after-recovery -->
249
146
 
250
147
  # Every sign-in ends with its check
251
148
 
252
- <!-- pomerado:hosted:start
253
- Every sign-in you record ends with a deterministic sign-in check, sent as `signInStep.signedIn`:
254
- a signed-in marker on the page the sign-in lands on (a selector, or the signed-in page's path), or,
255
- when that page shows none, an account page with `openPath` and the marker to check there. Choose a
256
- marker that every signed-in account shows and a signed-out page never does. Prefer an observed
257
- protected page or authenticated workflow control, corroborated by the live business example;
258
- generic Sign out or account chrome alone is insufficient. Never put an account's name, email or
259
- number in the marker: the check publishes with the tool and runs for every login, and the host
260
- refuses one that names this account. This strengthens the observed workflow evidence without
261
- adding a separate identity detector or guessing a protected route. The published
262
- tool records the check with its screens, and each run decides whether its sign-in worked by that
263
- check alone: a run whose check fails requests sign-in repair before its operation.
264
- pomerado:hosted:end -->
149
+ <!-- pomerado:section auth.sign-in-check:start
150
+ End every sign-in with a check that it worked: an observed signed-in marker that every
151
+ signed-in account shows and a signed-out page never does. Never use an account's name, email or
152
+ number as the marker.
153
+ pomerado:section auth.sign-in-check:end -->
265
154
 
266
155
  ## A sign-in refusal found by operation code
267
156
 
@@ -273,34 +162,7 @@ The caller receives `credentials_rejected` and `rejected_field`; this requests n
273
162
 
274
163
  A direct sign-in request signs in with one host-filled HTTP request instead of an autofill form submission. Runs are faster with it, so the host prefers it once a mint proves it.
275
164
 
276
- <!-- pomerado:hosted:start
277
- 1. From the explored login page, find what the form actually submits: its action, or the
278
- request the page script sends (method, path, content type, field names, and any CSRF
279
- field or header). Read the login page's HTML and scripts in the capture. Never submit
280
- the form yourself. A staged form with a separate identifier submission is not a
281
- single direct sign-in request. Omit this optional template and map the autofill screens.
282
- 2. Author `src/website-auth-http.json`, for example:
283
- `{"preload":"/login","request":{"method":"POST","url":"/api/login","headers":{"content-type":"application/json","x-csrf-token":"{{cookie.csrf_token}}"},"body":"{\"username\":\"{{identifier}}\",\"password\":\"{{password}}\"}"},"acceptedStatuses":[200]}`
284
- - URLs are paths on the site, or an https URL on an approved sign-in origin. `preload`
285
- loads a page first, so anti-bot and CSRF cookies are set before the request.
286
- - It holds placeholders, never values: `{{identifier}}`, `{{password}}`, `{{code}}` (a
287
- one-time code the host asks the user for), and `{{cookie.NAME}}` or `{{input.NAME}}`
288
- for this sign-in's own CSRF values, read after the preload. The host fills them;
289
- generated code never sees them. Never write a literal token or credential.
290
- - If a vendor computes a per-request sensor payload in page JavaScript, a direct
291
- request isn't possible. Omit the file.
292
- 3. Call `execute` with purpose `authenticate`, target `liveBrowser` and the authored operation
293
- entrypoint, without `signInStep`, to run this explicit host-filled template. The host validates
294
- it before sending. An accepted status verifies the sign-in, and the receipt reports `method:
295
- "direct"`. A failure returns control without another credential submission. Inspect the
296
- response and login page, then correct the template or use the evidenced autofill screens.
297
- A visibly rejected password is corrected through the host; never resend it yourself.
298
- 4. Publication includes the template only when this mint signed in with the same file and the
299
- business example then completed. A registered run's failed direct request requests sign-in
300
- repair before its operation. Until repaired, later calls use the verified autofill recipe.
301
- The host manages the resulting session and tokens; callers never hold them.
302
-
303
- pomerado:hosted:end --><!-- pomerado:standalone:start
165
+ <!-- pomerado:section auth.direct-request:start
304
166
 
305
167
  ## Standalone live authentication
306
168
 
@@ -310,4 +172,4 @@ Fields use the same slots and format declarations. `username` lists every accept
310
172
 
311
173
  Inspect each subsequent screen and send its observed step. A method or account choice needs caller input before selection. Wait for and verify an observed signed-in marker; disappearance of the login form is insufficient. Rejection requires caller correction and never authorizes replay of a private submission. Popup/frame sign-in uses the observed host target and configured sign-in origins, with the same destination guard.
312
174
 
313
- pomerado:standalone:end -->
175
+ pomerado:section auth.direct-request:end -->
@@ -13,64 +13,13 @@ Try first. Ask only for what the page or the caller uniquely knows at that point
13
13
  - a code the site sends during the action, such as a confirmation code by text or email;
14
14
  - a fact only the caller has that the site now asks for.
15
15
 
16
- <!-- pomerado:hosted:start
17
- Use a published input instead whenever the value is stable and the caller can supply it
18
- up front, such as a flight number, a date or a quantity. Never ask for a password, a
19
- username or any other login: the host asks for a login itself and signs in. Never ask
20
- for something the page shows, for permission to proceed with the operation the caller
21
- already asked for, or to solve a CAPTCHA.
22
- pomerado:hosted:end -->
16
+ <!-- pomerado:section caller-input.published-input -->
23
17
 
24
18
  ## Declare, read, ask
25
19
 
26
- <!-- pomerado:hosted:start
27
- 1. Declare every question the run may ask in the contract,
28
- `defineOperation({ name, input, output, questions }, ...)`, by id, with its `type`
29
- and a short `prompt`. The publication review reads these declarations once, so the
30
- prompt names the choice or value, never a private value. Write `questions` as a plain
31
- literal inside the entrypoint's own `defineOperation` call: during the build the host
32
- reads it from that source, not from the running script, and a computed or imported
33
- declaration declares nothing, so every question is refused as `Undeclared`. Each question
34
- the example asks is also reviewed before the build's owner sees it.
35
- - `{ type: "choice", prompt, allowOther? }`: one option; `allowOther` lets the caller
36
- type their own answer, returned as `{ other }`. Own text that repeats exactly one
37
- offered option's label (or its listed form entry, `id (label)`) returns that option.
38
- - `{ type: "multi_choice", prompt, minSelections?, maxSelections? }`: several options,
39
- at least one unless `minSelections` says otherwise, at most the options offered.
40
- - `{ type: "text", prompt, maxLength? }`: free text.
41
- - `{ type: "confirm", prompt, followUp? }`: yes or no, returned as `{ confirmed }`.
42
- - `{ type: "secret", secretKind, prompt, maxLength? }`: a code the site sent
43
- (`one_time_code`), an authenticator code (`totp`, which a saved login's TOTP fills
44
- without asking) or other private text (`private_text`). It stays out of traces,
45
- logs and the minting model. A secret you ask during the build with `request_input`
46
- comes back to you as a handle such as `{{secret.s1}}`, which the host fills in only
47
- when your explore, test or `act` source runs live, and only where it is the whole
48
- string passed to `fill`, `type` or `pressSequentially` or a field of a request to this
49
- site (core skill); the published script never holds a handle and asks for the value
50
- with `ask` instead.
51
- 2. For a choice, read the options in the execute call that reaches it and return them as
52
- plain JSON. Each option has a `value` the script acts on and a `label` the caller
53
- reads. Values are unique within a question. Offer only options the page will accept:
54
- skip taken seats, disabled slots and sold-out items. The value never leaves the run;
55
- the caller sees only the label.
56
- 3. Mark an option taken from the caller's own account (a saved traveler, address, card
57
- or account) with `accountSpecific: true` and a `maskedLabel` that keeps it
58
- recognizable without its numbers or email, such as `"Jane D. •••• 7890"`. The API
59
- and MCP show the masked label with a notice; only the owner's protected page shows
60
- the full label. A masked label that still shows five or more digits or an email
61
- address is replaced by the label's last four digits or a numbered placeholder.
62
- 4. Ask once for everything the step needs, between two execute calls:
63
- - `await ask("code")` returns that question's answer;
64
- - `await ask(["seat", "note"])` returns one answer per id;
65
- - `await ask({ seat: { options: seats }, code: {} })` passes a choice's options, and
66
- nothing for the other types.
67
- pomerado:hosted:end -->
68
-
69
- <!-- pomerado:hosted:start
70
- One ask takes up to eight questions, with up to 50 options per choice. A choice
71
- returns the chosen `value`, a multi-choice an array of values. Write answers into
72
- the next call's code with `JSON.stringify`.
73
- pomerado:hosted:end -->
20
+ <!-- pomerado:section caller-input.declare -->
21
+
22
+ <!-- pomerado:section caller-input.ask-limits -->
74
23
 
75
24
  The run waits with its browser open and its active budget stopped, and the next call
76
25
  starts on the same page. Continue from there. Do not reload, search again or repeat an
@@ -100,27 +49,17 @@ before the question is reported as a possible change when no answer comes.
100
49
 
101
50
  ## During a mint
102
51
 
103
- <!-- pomerado:hosted:start
104
- A read build's example run, or a write build's `act` step, asks the build's owner
105
- through the same request, and the answer comes back to the running script. Guardian
106
- reviews each question first. When it asks for a rewording, nobody is asked, the `ask`
107
- fails and the execution's result carries `scriptQuestion` with Guardian's rationale:
108
- change the declared question as it says and execute again. If the
109
- owner does not answer in time, the build ends as `no_response`; there is nothing to
110
- retry, and a write step after one that sent something is reported as a possible
111
- change. Do not turn an account-specific choice into a published input to work around
112
- a question.
113
- pomerado:hosted:end -->
52
+ <!-- pomerado:section caller-input.during-mint -->
114
53
 
115
54
  `references/caller-choice.ts` books a seat on the caller's chosen flight: it asks for a
116
55
  seat and a saved traveler once the flight's seat map is shown, then books once and calls
117
56
  `verified({ confirmation: "message" })` after reading the confirmation back.
118
57
  `references/caller-code.ts` asks for the code the site sends to confirm an address
119
58
  change and enters it on the same page.
120
- <!-- pomerado:standalone:start
59
+ <!-- pomerado:section caller-input.protected-answers:start
121
60
 
122
61
  ## Standalone protected answers
123
62
 
124
63
  Declare questions in the operation contract using the existing SDK schema and ask through `ask`. Ordinary answers are caller input, not extra authority. A `secret` answer is delivered privately for its declared purpose; during minting it returns an opaque handle. Use that handle only as a whole value at an authorized destination, never transformed, logged, returned, stored or read back. Website login credentials are requested only by the host during `authenticate`; TOTP/one-time codes are caller-supplied, with no stored seed automation.
125
64
 
126
- pomerado:standalone:end -->
65
+ pomerado:section caller-input.protected-answers:end -->