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.
@@ -23,248 +23,48 @@ against `typescript/src/runtime/index.ts` and show the real method signatures.
23
23
 
24
24
  ## Secret answers
25
25
 
26
- <!-- pomerado:hosted:start
27
- A `secret` answer comes back as a handle such as `{{secret.s1}}`, never the value,
28
- which you never see. In explore, test or `act` source, write the handle exactly as given as
29
- the whole string passed as the value to `fill`, `type` or `pressSequentially` on a `page`
30
- chain, or as a field of a `fetch` or `page.request` call to a literal URL on this site, inside
31
- the code of a `kernel.browsers.playwright.execute` call, such as
32
- `await page.getByLabel("Code").fill("{{secret.s1}}")`. The host fills in the value when it runs
33
- that source live and masks it in what comes back; offline targets get the handle unchanged.
34
- A handle anywhere else is refused before anything runs, naming its file and line: in a
35
- variable or a locator held in one, joined or transformed, returned, logged, in a URL or a JSON
36
- file, or beside code that reads the field back (`inputValue`, `evaluate`), reads its own source,
37
- or redefines JSON, a global, a prototype or a page or Kernel method; check the result in a later
38
- execute call. So is a handle the attempt never issued. An example and published
39
- source never hold a handle: a value the finished tool needs at run time is a declared
40
- `secret` question it asks with `ask` (caller-input skill).
41
- pomerado:hosted:end -->
26
+ <!-- pomerado:section core.secret-answers:start
27
+ A `secret` answer comes back as a handle such as `{{secret.s1}}`, never the value. Write the
28
+ handle exactly as given as the whole string passed as the value to `fill`, `type` or
29
+ `pressSequentially` on a `page` chain inside the code of a `kernel.browsers.playwright.execute`
30
+ call, such as `await page.getByLabel("Code").fill("{{secret.s1}}")`. The host fills in the value
31
+ when it runs that source live. Never hold a handle in a variable, transform, log, return or read
32
+ it back, or put it in a URL or a file. An example and published source never hold a handle: a
33
+ value the finished tool needs at run time is a declared `secret` question it asks with `ask`
34
+ (caller-input skill).
35
+ pomerado:section core.secret-answers:end -->
42
36
 
43
37
  ## Kernel scripts
44
38
 
45
- <!-- pomerado:hosted:start
46
- An operation is `defineOperation({ name, input, output }, async ({ kernel, sessionId,
47
- siteOrigin, siteDomain, input, decideDialog, ask, waitPastChallenge, verified, remainingMs, errors }) => ...)`. Its browser
48
- work is its own `kernel.browsers.playwright.execute(sessionId, { code, timeout_sec })`
49
- calls. Kernel runs each `code` string as plain Playwright code on its own `page` and
50
- answers `{ success, result, error, stderr }`. Throw
51
- `new errors.OperationFailure(String(answer.error), { stderr: answer.stderr })` when
52
- `success` is false or the page is not what the operation needs.
53
- pomerado:hosted:end -->
54
-
55
- <!-- pomerado:hosted:start
56
- - Make one execute call per operation. Add a call only at a `decideDialog` decision, an
57
- `ask` for the caller's choice, after `waitPastChallenge`, where the flow could run past
58
- 300 s, or in a composed write, which keeps one call per `act` step.
59
- `timeout_sec` is at most 300.
60
- - The code cannot see your variables. Write outside values into it with `JSON.stringify`,
61
- and return plain JSON, never a Locator or Response.
62
- - Start a response wait in the same call as the click that causes it, with
63
- `Promise.all([page.waitForResponse(...), button.click()])`. Listeners do not outlive a call.
64
- - Do site HTTP inside the page with `page.evaluate(() => fetch(...))`. Never use
65
- `page.request` or a Node-side fetch, because the host records only page requests.
66
- - Patchright runs `page.evaluate` in an isolated world. To read the page's own JavaScript
67
- variables, pass `false` as the fourth argument: `page.evaluate(fn, arg, undefined, false)`.
68
- - Console logs do not work. Return what you need to see.
69
- - When a challenge appears, call `await waitPastChallenge({ ready })`. `ready` is code that
70
- returns true once the page is usable. It throws `ChallengeFailure` if the page stays blocked.
71
- - Never repeat a call that may have run.
72
- - When the site itself refuses a caller's value, such as a past date, an unknown airport code
73
- or a party size over its limit, throw `new errors.InvalidInput(message)` saying why. `errors`
74
- exists only in the script, never in a call's `code`, so when the page shows the refusal,
75
- return a marker such as `{ refused: "why" }` from the call and throw once it returns. The
76
- run then fails as the caller's input and nothing repairs the tool. A write that throws it
77
- before entering a commit mark reports that it changed nothing. A page, control or response
78
- that changed is still `OperationFailure`.
79
- - After a write, call `verified()` just before returning, once a call has read the saved
80
- result back, or `verified({ confirmation: "message" })` when the site's own confirmation
81
- for this submission proves it. Without it the write stays a possible effect. A write
82
- declares which in its contract's `write`, and a write build runs as `act` steps; see
83
- `writes/SKILL.md` and `forms/SKILL.md`.
84
- pomerado:hosted:end -->
39
+ <!-- pomerado:section core.operation-shape -->
40
+
41
+ <!-- pomerado:section core.execute-calls -->
85
42
 
86
43
  **The input schema.** Every caller sees the tool's input schema, so build it from the
87
44
  request and the flow, never from one caller's account or example.
88
45
 
89
- <!-- pomerado:hosted:start
90
- - The code works for every value the schema accepts. Never let the schema promise what
91
- the code rejects, such as a string the code throws on unless it is the example's value.
92
- - Every value the code types, selects or fills on the site comes from the input and
93
- accepts what the site's field accepts. An enum lists the site's full set of options,
94
- never just the example's value. The example's values are one case, never limits.
95
- - Inputs are values a caller knows, such as codes, names, dates and counts, never a
96
- suggestion's full display text or an internal id the caller cannot know. A closed list
97
- of options stays an enum of the site's options, as above. When the options come from a
98
- query, as in an autocomplete, typeahead or searchable combobox, the tool types the
99
- caller's value and picks the matching suggestion itself: an exact code or name match
100
- wins (an airport code picks that airport, not its city), and it throws `InvalidInput`
101
- only when nothing matches or several match equally.
102
- - On a write, every choice the session met is an input: each option on the path,
103
- add-ons and pre-selected defaults included. Make it required when the site requires
104
- a choice (a fare class) and optional when it does not (a seat). An unset optional input
105
- keeps the page's default; an add-on, a pre-selected paid option or a saved payment is
106
- never left to a default, so ask about it (the writes skill).
107
- - Never make an account-specific value (a passenger, loyalty number, saved card or
108
- address, account or member ID) an enum member, example or default in a public
109
- schema. Take it as a free-form input.
110
- - The host's `businessInputTypes` is a value-free tree of the JSON types in the caller's
111
- input. Use it to pick compatible types when a credential in the input is masked; a mask
112
- does not mean the value was a string. It says nothing about
113
- required fields, array lengths, numeric bounds or future values: derive those from
114
- the request and reviewed evidence.
115
- - Never hard-code a value the caller could vary: it comes from the input, never a literal
116
- in source, a schema default or the definition. A good tool exposes the options its
117
- purpose calls for, not only the ones the request names: record every optional field the
118
- flow offers that bears on the tool's purpose as an optional input wired to its control,
119
- such as cabin class (economy or first) on a flight search, even when the request never
120
- mentions it. Leave out controls unrelated to the purpose, such as a language switch or a
121
- newsletter opt-in on a search. Record such a field as an optional input whether or not
122
- you ask about it, since callers of the tool can set it. Ask about one the input leaves
123
- open only when the request's purpose clearly depends on its value, in the same batch as
124
- your other questions; leave the rest unset, keeping the page's default.
125
- - When a read's caller input is empty (`{}`), write the example's input from the request
126
- and the owner's answers, with dates normalized (10/4 is the next October 4, as
127
- `2026-10-04`), and pass it as `exampleInput` on the example's execute. Make each of its
128
- keys a schema input; publication returns a key the schema lacks as an `example_input`
129
- input feedback.
130
- - Callers and Guardian see the JSON Schema form, so write every constraint in one it
131
- shows: a `Schema.filter` shows nothing, its description included, so use
132
- `Schema.NonEmptyString`, `pattern`, `minLength`, `Int`, `between` or `Literal`. Type every
133
- output field, never `Schema.Unknown`. A read publishes the schemas in its current source,
134
- and its example's own input and output must decode under them, so settle both before that
135
- example.
136
- - Give every input and output field, nested object and array item fields included, a short
137
- `description` annotation saying what it is, with the unit or format where one applies:
138
- "Departure airport as a three-letter IATA code", "Departure date, YYYY-MM-DD". Effect's
139
- stock text, such as "a non empty string", is no description. Annotate the field's own
140
- schema, inside `Schema.optional(...)` for an optional one; a `Schema.Date` keeps it only on
141
- `Schema.optional(Schema.Date)` or `Schema.propertySignature(Schema.Date)`. Callers see each
142
- beside its name.
143
- - Shape inputs and outputs like Pomerado's own API, so every tool reads alike: field names in
144
- snake_case; dates as `YYYY-MM-DD` and timestamps as ISO 8601 with an offset; money as an
145
- integer in minor units with an ISO 4217 `currency` beside it, such as `total_minor` 12999 and
146
- `currency` `"USD"`; enum values in lowercase snake_case (`"premium_economy"`); booleans named
147
- as statements (`refundable`, not `is_refundable_flag`); lists named in the plural; and the
148
- unit in the field name or its description (`duration_minutes`). Convert between these and the
149
- site's own formats in code.
150
- - Give every input field one `examples` annotation value, which callers, the docs and the Try it
151
- form use to assemble a sample request: public, generic data such as a well-known airport code
152
- (`examples: ["SFO"]`), a date a few weeks ahead or a common product category. Never use a value
153
- from this session: not the caller's input, the owner's answers or anything the site showed
154
- this account.
155
- - Descriptions, titles, examples and defaults are published and reviewed for private data,
156
- and an annotation never declares its contents public. Explain constraints without copying private input
157
- or unneeded numeric identifiers; for a nonnegative safe integer,
158
- `Schema.between(0, Number.MAX_SAFE_INTEGER, { title: "Safe integer", description:
159
- "Nonnegative safe integer amount" })` keeps the bound with public prose. Return a
160
- supplied currency value from the validated input instead of embedding it in source.
161
- Only host-approved standard enums and origins are recognized as public.
162
- - Guardian's publication review checks the schema and the code that fills it. A
163
- `not_published` result with reason `input_feedback` lists `account_specific_enum`,
164
- `input_option` and `example_value` findings. They are feedback, on a read or a write:
165
- correct the source (make the value free-form, add the option as an input, or widen the
166
- input and the code that sets it) and call `finish_build` again with the same
167
- `executionId`. The host reads the schemas offline from current source and checks that the
168
- example's or session's own input, and a read example's output, still decode. Never run a
169
- write again for it. After two such rounds, or if you stop
170
- without fixing them, the host publishes the last reviewed version privately to the
171
- caller's account and flags it.
172
- pomerado:hosted:end -->
46
+ <!-- pomerado:section core.schema-coverage -->
47
+
48
+ Typed output, where the site makes it easy:
49
+ - Prefer numbers for prices, amounts and counts, with the currency or unit in its own field.
50
+ - Prefer ISO 8601 for dates and times, and minutes for durations.
51
+ - Keep one field per fact. Split a combined line into separate fields.
52
+ - If a value does not parse cleanly, returning the site's own text is fine.
173
53
 
174
54
  **Search results.** When the site says how its results matched, such as exact matches
175
55
  against suggested or fallback items, a search tool returns that. Otherwise its description
176
56
  and output say plainly that results may include the site's own suggestions.
177
57
 
178
- <!-- pomerado:hosted:start
179
- The host owns input/output validation, deadlines, account binding, the browser,
180
- capture and screened logs. Do not close the page.
181
-
182
- pomerado:hosted:end --><!-- pomerado:standalone:start
58
+ <!-- pomerado:section core.host-ownership:start
183
59
 
184
60
  The host owns input/output validation, deadlines, caller authority and the browser. Do not close the page.
185
61
 
186
- pomerado:standalone:end -->A newly allocated Page may start at `about:blank`; the supplied site origin does
62
+ pomerado:section core.host-ownership:end -->A newly allocated Page may start at `about:blank`; the supplied site origin does
187
63
  not mean the host has navigated there. Navigate to the authorized site and wait
188
64
  for a named page condition before inspecting its title or controls. Empty content
189
65
  on a blank Page is not evidence about the website or its availability.
190
66
 
191
- <!-- pomerado:hosted:start
192
- Take the site origin from the context's `siteOrigin`. If it is undefined, fail before
193
- live navigation; offline fixtures intentionally have no live origin. Build URLs with
194
- `new URL("/", siteOrigin).href` or an observed relative path and write them into the
195
- code. Never embed the site's hostname or account-specific origin as a literal in
196
- authored source, schema examples, or logs, and never replace it with `page.url()`
197
- after a redirect. The host supplies the primary origin even when the model cannot see
198
- it. This value does not authorize other destinations or credential submission.
199
- The context's `siteDomain` is the site's registrable domain, which the host computed with
200
- the public suffix list: a page is on the site when it is `https:` and its hostname is
201
- `siteDomain` or ends with `"." + siteDomain`, and only `siteOrigin` itself is the site when
202
- `siteDomain` is undefined. Write it into the code as you do `siteOrigin`, and never derive it
203
- from the hostname: its last labels can be a public suffix (`co.uk`) or another tenant's
204
- (`github.io`). `references/native-page.ts` shows the check. Use `page.evaluate`,
205
- `locator.evaluate` or `locator.evaluateAll` when code needs browser globals such as
206
- `document`.
207
- For visible page text, prefer a scoped locator's `innerText`; `textContent` also
208
- includes hidden text and script/style contents. Read embedded data separately
209
- when it is relevant to the requested operation.
210
- Default budgets: action, readiness and navigation 30 s. Give every Playwright
211
- wait in the code an explicit `timeout`, and keep `timeout_sec` within `remainingMs()`.
212
- Child waits cannot extend the outer deadline. Explicitly name observation conditions.
213
- `domcontentloaded` is document readiness, not readiness of the requested page or
214
- control. Initial navigation can land on a temporary verification page before the
215
- site redirects or renders its controls. JavaScript challenges, redirects and
216
- delayed rendering can be intermittent: a fast exploration load does not establish
217
- that later executions will be immediately ready. Include a bounded wait for the
218
- expected page or control even when exploration never observed a delay. Derive
219
- that readiness condition from the intended page, not from having seen a particular
220
- challenge. Wait for a unique operation control or page state before testing absence
221
- or choosing a fallback. Use `locator.waitFor` or a bounded polling loop;
222
- `count()` and `isVisible()` only observe the current instant. A ready page should
223
- pass immediately; do not add a fixed sleep. Share one bounded navigation deadline across navigation
224
- and first-page readiness, as in `references/navigation.ts`. Readiness polling
225
- only observes: do not repeat `goto`, reload, login, submission or another action
226
- inside it. Preserve site/path and account guards while waiting.
227
- After an action that can navigate, wait for the observed destination URL when known,
228
- then a specific destination control or page state before extracting. Keep the action,
229
- readiness wait and extraction in the same Kernel execute call when possible. If a read
230
- reports “Execution context was destroyed,” the action may already have succeeded.
231
- Reacquire page/frame locators, wait for readiness and retry only the read within the
232
- original deadline. Never repeat the click or submission as part of that recovery.
233
- Use observed conditions, without fixed sleeps or whole-page network-idle waits.
234
- For an unknown destination, inspect after the document transition; do not invent a
235
- selector or repeat the action in a follow-up read.
236
- Hosted Kernel browsers already use stealth's automatic solver for supported
237
- challenges, including with the assigned proxy. Observing a challenge
238
- does not establish that the solver failed or that human input is required.
239
- After a probe reveals a challenge, inspect the retained Page in follow-up probes
240
- and wait for the intended page/control within the existing deadline and job budget;
241
- do not click the challenge, reload, or navigate to another route merely because
242
- the earlier probe timed out. A new probe execution does not require new navigation.
243
- A live example, a live read `test`, and a write session's first `act` step are
244
- different: the host resets
245
- the browser to the site origin before it runs,
246
- and clears exploration cookies and site storage. A signed-in build gets back the session
247
- saved right after sign-in instead, so a stale session shows up as a login wall that a new
248
- sign-in fixes. That source must perform the flow from its input,
249
- never rely on a page an exploration left open. So a read iterates from a clean start,
250
- and re-running its example or live test is normal. A live test stays read-only. A write
251
- session's later `act` steps continue on the page the previous step left.
252
- If the deadline expires, report the named readiness failure and use current
253
- screened evidence to distinguish a remaining challenge, loading and changed
254
- layout. The `captcha` skill covers the on-demand `captcha_state` check, the shared
255
- wait budget and `waitPastChallenge`, which operation code calls instead of
256
- raising `ChallengeFailure` itself. Do not invent a CAPTCHA bypass or replace the target with an arbitrary
257
- first element. Resolve role and computed accessible name from observed evidence;
258
- `searchbox` and `textbox`, and their exact names, are not interchangeable.
259
- When a Playwright timeout names a locator, repair that wait and keep the checks that
260
- already passed. A `DeadlineExceeded` phase of `execution` is the shared operation
261
- deadline. Before increasing a timeout, make one bounded observation of the candidate
262
- target count or state; increase it only when evidence shows that the correct unique
263
- target is slow. Do not catch-and-repeat timed-out work. A click or navigation that
264
- timed out is an uncertain transition: it may already have taken effect. Inspect the
265
- retained page in the next probe and do not repeat the action until you know where
266
- the page landed.
267
- pomerado:hosted:end -->
67
+ <!-- pomerado:section core.site-origin -->
268
68
 
269
69
  Never call `.first()` (or `.nth(0)`) on a broad text or regex match, whether to
270
70
  click it or to wait for readiness: collapsed menus often hold an earlier hidden
@@ -295,14 +95,10 @@ it. Bounded repeatable reads and transient search interactions may continue unde
295
95
  existing authority when source and current observations establish their semantics;
296
96
  inspect state before choosing a retry or safe read reconstruction. A search/query
297
97
  submission can be a read; autosave, drafts, uploads, holds and business commitments
298
- are writes regardless of method or control names. <!-- pomerado:hosted:start
299
- Raw Page calls require host review,
300
- capture and isolation; required services are dependencies, not permissions.
301
-
302
- pomerado:hosted:end --><!-- pomerado:standalone:start
98
+ are writes regardless of method or control names. <!-- pomerado:section core.raw-page-calls:start
303
99
  Raw Page calls require host review and caller authority.
304
100
 
305
- pomerado:standalone:end -->Preserve the host's reported failure stage and dispatch state. Missing output or
101
+ pomerado:section core.raw-page-calls:end -->Preserve the host's reported failure stage and dispatch state. Missing output or
306
102
  a provider 404 does not prove that navigation, login or a previous action never
307
103
  happened. A guard failure before one click says nothing about earlier actions in
308
104
  that script. For a reviewed current-state inspection, check that the page is on the
@@ -315,38 +111,11 @@ because a later extraction call timed out.
315
111
  Never recreate a write or login to recover an observation. See
316
112
  `references/native-page.ts` for a site-guarded read.
317
113
 
318
- <!-- pomerado:hosted:start
319
- The tools and the files you may edit are in `AGENTS.md`. The host binds the caller's actual input/account; no tool
320
- argument selects another account or private reference. A live read test's `testInput` is
321
- the one input you choose, with public values only (.agents/testing/SKILL.md). Every new
322
- command/probe/execution gets Guardian review, including maintenance residual work.
323
- Nested Playwright actions do not each trigger review. A probe operation still receives the host-bound business
324
- input. Its declared schema must accept that input even when the bounded observation
325
- does not use every field; do not replace it with an empty or probe-only schema.
326
- pomerado:hosted:end -->
327
-
328
- <!-- pomerado:hosted:start
329
- For captured parser checks, use the host's `savedHTTP` or `savedDOM` execute target
330
- with published capture paths in `fixtureRefs`. The testing skill explains the
331
- replayed HTTP service and the saved page. A `savedDOM` test runs only a Kernel
332
- script. The host owns fixture binding, offline Chromium, routes and cleanup. These
333
- checks retain original business input but do not sign in, count as a read's proving
334
- example or perform a write.
335
- pomerado:hosted:end -->
336
-
337
- <!-- pomerado:hosted:start
338
- Choose relevant references: writes, testing, pagination, variants/recovery, forms,
339
- HTTP/MCP, caller input for a choice only the page can offer, or a code, during the
340
- run, and publication before the first `finish_build`. Read their bodies only when useful.
341
- Finish with actual execution evidence and
342
- truthful coverage through `finish_build`. A write finishes after its session's
343
- confirmation read; never run the composed script live. Ask only as "Try hard, then
344
- ask" allows. If infrastructure prevents further
345
- work, report the recorded failure and unresolved effects, then end without
346
- publication; the host preserves an incomplete build. Do not ask the user to
347
- answer a provider outage. Publishing future code does not replace the build's own
348
- result or resolve uncertain effects.
349
- pomerado:hosted:end -->
114
+ <!-- pomerado:section core.tools-and-files -->
115
+
116
+ <!-- pomerado:section core.captured-checks -->
117
+
118
+ <!-- pomerado:section core.references -->
350
119
 
351
120
  Examples: `references/parser.ts`, `references/native-page.ts`,
352
121
  and `references/selection.ts`. For custom choices, the forms skill includes
@@ -365,16 +134,7 @@ Loading is not proof of a new version. An identity mismatch blocks every candida
365
134
 
366
135
  See the compiling `references/variants.ts` example.
367
136
 
368
- <!-- pomerado:hosted:start
369
- Use screened old/new captures and report tests of the guards against known layouts,
370
- ambiguous/unsupported/loading states and varied private inputs. Describe missing
371
- coverage honestly; the host associates its actual capture paths and test receipts
372
- privately with the published revision. A receipt records execution, not a claim
373
- that every declared variant was tested. Public bundles must exclude private fixtures.
374
- There is no fixed test count. Existing enabled variants cannot be silently omitted
375
- by a future publication. Explicit disable or a new validated publication affects
376
- future calls; a selected variant failure never restarts an old write script.
377
- pomerado:hosted:end -->
137
+ <!-- pomerado:section core.layout-captures -->
378
138
 
379
139
  ## Authenticated operations
380
140
 
@@ -391,41 +151,11 @@ reach the credential form from that entry. A URL no sign-in can start from, and
391
151
  a failed sign-in, come back with the reason and the next step; fix the cause and call
392
152
  authenticate again. Do not author a login-routing metadata file.
393
153
 
394
- <!-- pomerado:hosted:start
395
- Inspect login markup using reviewed read-only `explore` without private credential
396
- injection. Use execute purpose `authenticate`, target `liveBrowser`, to sign in. The
397
- host runs the explicit direct HTTP request or the observed `signInStep` and reports the sign-in. It runs no
398
- generated code, and it does not claim or execute the business example. Login effects
399
- have separate authentication evidence. If the same browser still shows a login page or
400
- a signed-out state afterwards, inspect the page and correct the recorded steps or report the failure.
401
- Credentials the site rejected are never resubmitted. After a browser recovery gives a
402
- new, empty profile, its notice says the signed-in session ended: submit `authenticate`
403
- again. The host signs in on each fresh profile, at most three times per attempt, and
404
- the notice says when that allowance is spent. Wait for the
405
- signed-in page to become ready after login. Disappearance of the login form alone is
406
- insufficient. The host requests codes and choices through protected input requests during
407
- `authenticate`.
408
- pomerado:hosted:end -->
409
-
410
- <!-- pomerado:hosted:start
411
- Only the host requests website credentials, and only during `authenticate`.
412
- When the invocation has no login yet, that `authenticate` uses the site's saved
413
- login when this build may use it, otherwise asks the caller for one, and signs in
414
- within the same call; a confirmed login rejection is corrected the same way, once.
415
- `request_input` cannot request credentials. If the site cannot be reached, report that instead
416
- of starting sign-in. Never request durable credentials in model arguments or
417
- history. With `save: false`, each NEW invocation needs a login
418
- of its own: username and password, or a username alone for a passwordless site
419
- (the host asks for a code when the observed autofill screen needs one); an existing profile alone
420
- cannot substitute for it.
421
- Saving credentials is separately authorized and does not change a successful
422
- website action into a reason to execute it again.
423
- pomerado:hosted:end -->
424
-
425
- <!-- pomerado:hosted:start
426
- For capture evidence, `README.md` lists `reference/captures.md`: what the index holds, pending
427
- screening and reading large files in parts.
428
- pomerado:hosted:end -->
154
+ <!-- pomerado:section core.login-markup -->
155
+
156
+ <!-- pomerado:section core.credentials -->
157
+
158
+ <!-- pomerado:section core.capture-evidence -->
429
159
 
430
160
  Keep exploratory output focused on the current question: the relevant control or
431
161
  container, its state, and the nearby choices. Prefer the existing accessibility
@@ -477,29 +207,9 @@ host's own entry-page load. The mint continued past each listed gap.
477
207
 
478
208
  `hostIncidents` kinds:
479
209
 
480
- <!-- pomerado:hosted:start
481
- - `observation_gap`: the host may have missed some of the browser's requests for a while, so
482
- that execution's effect is possible.
483
- - `capture_unavailable`: no screened capture exists for that execution, even after
484
- a retry, or for the last moments of a browser the host replaced. The build continues:
485
- use its result and events, and name the gap in `finish_build` coverage. Publication
486
- does not depend on background capture unless a publication response says so.
487
- - `dialog`: the host settled a page dialog itself. An expired or unobservable
488
- dialog was dismissed; an uncertain resolution leaves the effect possible.
489
- - `proxy_swap`: the host moved the browser to another outbound proxy. A request in
490
- flight at that moment may have failed, so treat it as possibly sent.
491
- pomerado:hosted:end -->
492
-
493
- <!-- pomerado:hosted:start
494
- Unclear means possible. `websiteEffect: may_have_dispatched` makes that execution's
495
- effect possible: reconcile current state before claiming success, and never repeat
496
- a claimed example or an uncertain write blindly: in a write session or a maintenance
497
- repair, read back whether the write happened first, and do the write only if it did not.
498
- `hostBug: true` marks a suspected Pomerado defect, which the host has reported. On a
499
- `dialog` or `observation_gap`, report it in your diagnostics and do not work around it;
500
- on `capture_unavailable`, keep building.
501
-
502
- pomerado:hosted:end --><!-- pomerado:standalone:start
210
+ <!-- pomerado:section core.incident-kinds -->
211
+
212
+ <!-- pomerado:section core.completion:start
503
213
 
504
214
  ## Standalone execution and completion
505
215
 
@@ -511,4 +221,4 @@ Declare explicit input and output schemas, concrete types and bounds for each su
511
221
 
512
222
  Only the host asks for website credentials and only during `authenticate`. Give it the observed field selectors, slots, allowed identifier kinds, format and submit. No generated source receives the raw password; follow the same destination, stale field/focus, no-readback and code-handle rules as hosted execution. Correct a refused binding by reading the current screen. A rejected credential needs caller correction; do not resubmit it.
513
223
 
514
- pomerado:standalone:end -->
224
+ pomerado:section core.completion:end -->
@@ -18,48 +18,7 @@ verified query. For an in-page update, wait for evidence that the new query has
18
18
  completed. An immediate snapshot with an empty title and missing controls can be
19
19
  a transition observation; it does not establish an empty business result.
20
20
 
21
- <!-- pomerado:hosted:start
22
- Derive `getByRole` names from a scoped `locator.ariaSnapshot()` or a retained ARIA
23
- snapshot. `getAttribute("aria-label")` reads only that DOM attribute, not the
24
- computed accessible name. The name may exist when the attribute is absent because
25
- it comes from text, labels or `aria-labelledby`. Read the snapshot or use an
26
- observed `getByRole` name; an `aria-label || innerText` fallback does not compute it.
27
- Use the observed role/name to build native locators and check their count,
28
- visibility and current value. Do not make exact indentation or adjacency in a
29
- whole-page ARIA snapshot a prerequisite for using an otherwise verified control.
30
- Snapshots describe a tree whose nesting and extra siblings can change. If a
31
- locator is missing or ambiguous, inspect its relevant scope and report what was
32
- observed before changing the locator. Use `inputValue()` on that same verified
33
- input for query readback instead of reconstructing its accessible name from DOM
34
- attributes inside a separate `evaluate` call.
35
- One broad body or main snapshot can be useful for initial orientation. When that
36
- snapshot has already succeeded, reuse it for related reads. If broad snapshot work
37
- is measured slow or times out during repeated-result extraction, prefer the
38
- established local result container or item locators instead of recomputing the
39
- whole subtree. CSS `locator("main")` matches a literal `main` element, while
40
- `getByRole("main")` matches the computed accessible role. When retained evidence
41
- does not establish which structure exists, compare their finite counts once under
42
- a bounded call, require the intended scope to be unique, then use that scope.
43
- Do this before changing timeouts. ARIA snapshots are multiline structured text;
44
- do not use a greedy cross-line capture for one quoted accessible name. Keep parsing
45
- bounded to the intended record, handle quoted escapes, and fail explicitly when
46
- the observed record does not match the established grammar.
47
- Keep the control's label, current value and selected state as separate observations.
48
- Use `inputValue()` for an input's current value; a nonempty label must not hide it.
49
- Treat counts as presentation text: support the site's observed singular and plural
50
- forms, and allow an owned menu option's computed accessible name to include an
51
- observed count suffix. Scope the option lookup to that menu and match only the
52
- established suffix grammar; do not require an exact raw `aria-label`.
53
- During exploration, read the selected state after the action to establish how this
54
- control commits a choice. For dates, establish the committed day, month and year
55
- from the control and its owned calendar state; a navigation URL, field label or
56
- requested input alone does not prove that the application accepted the date. In
57
- published code, keep a committed-state check when selection is the operation's
58
- final result or the next action needs that value. Do not turn every selection in a
59
- larger flow into an intermediate success assertion; the read-back before returning
60
- (`AGENTS.md`) checks each input the page shows. Reuse the current authorized
61
- page for missing observations instead of restarting a completed search.
62
- pomerado:hosted:end -->
21
+ <!-- pomerado:section forms.role-names -->
63
22
 
64
23
  A committed selection can change a control's accessible name. During exploration,
65
24
  reinspect its owned container to learn the committed state. If a later action needs
@@ -110,16 +69,7 @@ picker into a larger flow, establish its popup ownership and fresh-query signal
110
69
  choose the right option; read the committed state during exploration, when the next
111
70
  action needs it, or as part of validating the requested final outcome.
112
71
 
113
- <!-- pomerado:hosted:start
114
- Preserve add/replace and single/multiple intent. Query aliases
115
- are alternate searches for one stable choice, not extra selections. Demonstrate
116
- portal ownership, query-generation freshness and complete/windowed option coverage;
117
- virtualized options require bounded traversal with stable keys. An ambiguous choice
118
- needs a resolver or a `request_input` question, as `AGENTS.md`'s "Try hard, then
119
- ask" says; take the site's default only when the choice is not a write and is easy
120
- to reverse, and list it in `finish_build` `assumptions`. Do not claim uncaptured
121
- options do not exist.
122
- pomerado:hosted:end -->
72
+ <!-- pomerado:section forms.selection-intent -->
123
73
 
124
74
  Playwright `locator.count()` and `locator.isVisible()` are immediate observations,
125
75
  not waits. After opening a popup, wait for its owned, named container and requested
@@ -147,30 +97,9 @@ field change, file upload or draft creation may already be a website write.
147
97
 
148
98
  ## Multi-step forms
149
99
 
150
- <!-- pomerado:hosted:start
151
- Filling in or advancing a form that saves data on the site (an application, a profile,
152
- a contracting or checkout form) is a write, even when nothing is submitted yet: many
153
- such forms save each step as you go. A read build may not fill in or advance such a
154
- form (it asks for a write upgrade first, as the writes skill says); a write build does the whole form as its one task. A search, filter or query form
155
- whose read semantics are established stays a read.
156
- pomerado:hosted:end -->
157
-
158
- <!-- pomerado:hosted:start
159
- - Walk every step for real, in the session, with the caller's values. Never infer a
160
- later step's fields, options or wording in place of reaching it; the page after
161
- "Continue" is evidence only once you are on it.
162
- - Before the first `act` step, read what is already visible on the page, and read the
163
- page's own scripts or captured responses that describe the form (field lists,
164
- validation rules, step definitions) to anticipate what later steps ask. Use that to
165
- ask for the values up front, in one `request_input`, for every field you can see or
166
- anticipate that the input does not settle.
167
- - A step that asks for something you could not anticipate is asked in place when you
168
- reach it, with `request_input` during the session, or as a declared `ask` in the
169
- next step's script for a choice that exists only on that page. Check the page again
170
- after the answer.
171
- - A step the site saved stays saved. If a step fails, read the page before running it
172
- again; redo it only when it did not finish.
173
- pomerado:hosted:end -->
100
+ <!-- pomerado:section forms.saved-steps -->
101
+
102
+ <!-- pomerado:section forms.step-rules -->
174
103
 
175
104
  Expose prerequisite resolvers for valid choices. A prepare/confirm flow binds the
176
105
  draft to the account and requires caller-expected item, quantity, amount/currency
@@ -195,10 +124,10 @@ describes. Without it the write stays a possible effect. Never call it for a toa
195
124
  a status code alone or a missing confirmation, and make no execute call after it: a
196
125
  later call makes the effect possible again. Missing confirmation preserves uncertainty; it
197
126
  does not authorize another submit.
198
- <!-- pomerado:standalone:start
127
+ <!-- pomerado:section forms.fixture-checks:start
199
128
 
200
129
  ## Standalone fixture checks
201
130
 
202
131
  Use the same supplied-input/observed-control rules and browser helper APIs. Check pure parsers with `pureFiles` and supplied fixtures; verify actual interaction and final state with bounded `liveBrowser` steps. Never invent a live field value merely to test a control.
203
132
 
204
- pomerado:standalone:end -->
133
+ pomerado:section forms.fixture-checks:end -->
@@ -9,35 +9,18 @@ A cursor represents the query and a logical position under the same authorized
9
9
  tenant/account/site. The host protects and validates that scope; a saved profile
10
10
  or an agent's remembered Page is not a cursor authenticity check.
11
11
 
12
- <!-- pomerado:hosted:start
13
- 1. Validate cursor/query/account scope before browser effects.
14
- 2. Inspect restored live/profile state. Reuse it only if the current signed-in page,
15
- query and logical position are suitable.
16
- 3. Otherwise start from the host's fresh sign-in and reconstruct the
17
- repeatable read/search, then advance to the logical position. Loading a profile
18
- does not restore JS heaps, expiring server cursors, drafts or DOM state.
19
- 4. Tolerate changing live data. Return observed IDs and coverage; do not promise an
20
- immutable snapshot if the site has none. Prefer stable IDs over visual row index.
21
- 5. If reconstruction is unsupported, return bounded partial data with an explicit
22
- reason and no pretend next cursor.
23
- pomerado:hosted:end -->
24
-
25
- <!-- pomerado:hosted:start
26
- Never recreate a hold, draft, upload, payment token or write as pagination. Unknown
27
- prior effects require recovery, not fresh navigation. A mint question keeps the live
28
- browser for up to 10 minutes; that is not cursor expiry. Profile load/save failure
29
- or 24h inactivity expiry selects fresh reconstruction where supported; it does not
30
- invalidate an otherwise meaningful read cursor.
31
- pomerado:hosted:end -->
12
+ <!-- pomerado:section pagination.continuation -->
13
+
14
+ <!-- pomerado:section pagination.no-recreated-writes -->
32
15
 
33
16
  Use and test both warm and fresh paths, including expired state, changed live data,
34
17
  wrong query/account and unsupported reconstruction. `references/pagination.ts`
35
18
  provides a compiling authoring pattern; its hooks are site logic, not platform
36
19
  authentication or a universal pagination engine.
37
- <!-- pomerado:standalone:start
20
+ <!-- pomerado:section pagination.cursor-scope:start
38
21
 
39
22
  ## Standalone cursor scope
40
23
 
41
24
  A logical cursor is not proof of browser or account identity. Validate its supplied query and scope before effects, verify the current page and account context, and reconstruct only a repeatable read when the evidence supports it. Never recreate a write to recover a cursor.
42
25
 
43
- pomerado:standalone:end -->
26
+ pomerado:section pagination.cursor-scope:end -->