mirror of
https://github.com/profullstack/logicsrc.git
synced 2026-10-05 14:15:33 +00:00
* OpenErrand 0.1: an errand on a website with no API, with the human steps kept human docs/openerrand.md mints OpenErrand: one JSON file per errand (register an account, download a transcript) naming the site, the inputs with a sensitivity class and ordered sources (document, vault, prompt, generate, derive, candidate, literal), field rules matched by id then label, page and wait steps, five human gates a runner never performs (declare, identity-proofing, code, mail, captcha), outcomes, the never-retried shared secret, vault and download outputs, hand-off cards that may name only public inputs, the publisher index at /.well-known/openerrand.json, and thirteen runner rules. The worked example is the MyFTB business registration that cli-tools `ftb` performs (profullstack/cli-tools#125), with no personal data. - @logicsrc/schemas: openerrand + openerrand-index schemas and fixtures - @logicsrc/validators: semantic checks (references, templates, no personal or secret input on a card) and tests that validate the spec's own examples - logicsrc-web: registry entry (process family), /openerrand landing page, the example and the index served as static files, contract tests Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * OpenErrand: hand-off cards stay on the surface that owns the data Anthony's ruling: tax and finance data never touches a social or promotion tool, and nothing is sent to a CPA or preparer. - Hand-off cards are delivered only on the surface that owns the errand's data (for a tax or finance errand, the principal's finance app through its CLI, PWA, MCP server or API, such as CoinPay, or the runner's terminal), never a social, promotion or third-party posting service, and never to anyone but the principal. A card for an errand with personal or secret inputs does not leave that surface. Runner rule 9 says the same. - The run record and the sample run name the card by an opaque id (pin-letter/7f3k2q) instead of a mynaposter.com URL; the myna mention is gone. - `principal: represented` no longer cites a preparer with a power of attorney. - The FTB card's last step no longer suggests sending the PIN to someone else. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * OpenErrand: user-agent rule, captcha solver policy, reference runner note Anthony's answers on #227 ("go with your recommendations"): - Rule 11: a runner may run headless with a normal desktop browser user agent (dropping HeadlessChrome) and nothing more: no fingerprint spoofing beyond the UA string, no stealth plugins, no solving or evading a bot challenge. A challenge the browser completes itself is a wait step; any other is a captcha gate. - Captcha solvers: new site.sector and captcha step `solver` (forbidden by default | allowed). Never allowed on government, tax, financial, healthcare or identity-provider sites, nor on any errand with a declare or identity-proofing step or a secret input; elsewhere only when the file says so, with every use logged. The validator rejects `allowed` in the forbidden set or without a stated sector; six new tests. The FTB example states sector "tax". - Reference runner: @logicsrc/openerrand / `logicsrc errand run`, marked in progress; ftb stays the runner the example was taken from. - Name stays OpenErrand; family stays Agents and process. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * OpenErrand reference runner: @logicsrc/openerrand and logicsrc errand Ship the runner docs/openerrand.md promised. `logicsrc errand run <file>` reads an OpenErrand 0.1 file, validates it with @logicsrc/validators, and drives headless Chrome through it under the spec's thirteen rules; `errand validate` shows what a file will ask of you and `errand status` shows the last run of each errand, its card and any lockout. The engine is generalised from cli-tools `ftb` (PR #125) with no dependency on cli-tools: the CDP client and Chrome finder from wcag.ts, the page reader, native-setter fill and forward-button picker from ftb-run.ts, and the rule matcher, throttle and outcome logic from ftb.ts, all now driven by the file. - Inputs: document (an extractor hook; the one shipped runs a local command that reads JSON requests and prints records), vault (teams or OpenCreds), prompt (no echo for secrets), generate, derive, candidate, literal. `--input name=value` wins. Shared-secret candidates are ranked as the spec says, one is submitted, and a rejection lists the others for --candidate. - Rules: id before label, step rules first, choices before text, an id match final, an unmatched required field stops the run naming it. - Gates: declare only with --declare after the values are shown; identity proofing never touched (URL only) and handed over or stopped on; code from the terminal or a code file, used once, a wrong code waits for the next; mail ends the run waiting with the card; captcha is the person's, and a CaptchaSolver interface is called only where the spec permits (no solver is bundled); wait steps are polled, never solved. - Throttle: 2 runs per errand and account in 30 minutes, 4 a day, 2 minutes between runs on a site, lockouts from metadata.lockout or a default, held per site and account, never lifted by --force. - Outputs: credentials written before success to a teams vault by pull, merge, push (metadata.vault or --vault), else a 0600 file said aloud; downloads type-checked and never overwritten with different bytes; cards only in the local run record. - The user agent is Chrome's own with HeadlessChrome replaced, given at launch: a CDP override did not reach a navigation the page's own script started, which is exactly the proof-of-work interstitial case. Tests: 85 in the package (rule engine, inputs, gates, throttle, outcomes, captcha gating, vaults, outputs, commands) including an integration test that runs the published FTB example unchanged in real headless Chrome against a local HTTPS fake site (Chrome maps webapp.ftb.ca.gov to it and every other host to NOTFOUND; all data fictional), and 2 in the CLI. CLI 0.6.0 -> 0.7.0; @logicsrc/schemas and @logicsrc/validators 0.3.0 -> 0.4.0 (the OpenErrand schemas, and the vocabularies now exported for runners); PRD 0009; the spec's Reference runner section and the landing page say it ships. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
114 lines
4.4 KiB
Markdown
114 lines
4.4 KiB
Markdown
---
|
|
openprd: "0.3"
|
|
id: "0009"
|
|
title: "Ship the OpenErrand reference runner"
|
|
status: Draft
|
|
authors:
|
|
- anthony@profullstack.com
|
|
created: 2026-10-04
|
|
updated: 2026-10-04
|
|
repo: profullstack/logicsrc
|
|
discussion:
|
|
implementation: packages/openerrand
|
|
tags:
|
|
- openerrand
|
|
- errand
|
|
- browser-automation
|
|
- human-gates
|
|
- cli
|
|
supersedes:
|
|
superseded-by:
|
|
---
|
|
|
|
## Problem
|
|
|
|
OpenErrand 0.1 (docs/openerrand.md) describes an errand on a website with no
|
|
API as one JSON file, and its worked example was transcribed from `ftb` in
|
|
cli-tools, which has the same rule table compiled in. Until a runner reads the
|
|
file, the file is a description and not a program: nobody can run the example,
|
|
write a second errand, or check that a runner keeps the thirteen rules.
|
|
|
|
## Goals
|
|
|
|
- `logicsrc errand run <file>` runs any valid OpenErrand 0.1 file in headless
|
|
Chrome and stops exactly where the spec says a person is needed.
|
|
- The FTB example runs unchanged.
|
|
- The throttle that kept `ftb` from snowballing a lockout is part of every
|
|
errand, not of one tool.
|
|
|
|
## Non-Goals
|
|
|
|
- No document extractor beyond a `command` hook; reading a tax form is the
|
|
principal's tool's job.
|
|
- No captcha solver, ever. Only the interface, gated by the spec.
|
|
- No run against a real government site in tests.
|
|
|
|
## Users
|
|
|
|
- A person with a form to fill on a site with no API, who wants to read what
|
|
will be sent before it is sent.
|
|
- An agent running an errand for its human, which must hand back at every gate.
|
|
- A publisher writing an errand file who needs the page log to fix a rule.
|
|
|
|
## Requirements
|
|
|
|
- R1 [P0] `@logicsrc/openerrand` 0.1.0: load and validate with
|
|
`@logicsrc/validators`, resolve inputs (document via an extractor hook,
|
|
vault, prompt masked for secrets, generate, derive, candidate, literal),
|
|
rules matched id first then label with step rules first and choices before
|
|
text, outcomes rejected first, and the stopped reasons the spec names.
|
|
- R2 [P0] Gates: `declare` only with `--declare` after the values are shown;
|
|
`identity-proofing` never touched (URL only), stop or hand the window over;
|
|
`code` from the terminal or a code file, used once, a wrong code waits for
|
|
the next; `mail` ends the run waiting with the card; `captcha` is the
|
|
person's, and a solver interface is called only where the spec permits;
|
|
`wait` polled, never solved.
|
|
- R3 [P0] One shared secret per run, never retried; a rejection lists the
|
|
other candidates and `--candidate` chooses the next.
|
|
- R4 [P0] Throttle ledger: 2 runs per errand and account in 30 minutes, 4 a
|
|
day, 2 minutes between runs on a site, lockout from the file's
|
|
`metadata.lockout` or a default, held per site and account, never lifted by
|
|
`--force`.
|
|
- R5 [P0] Credentials written before success: a logicsrc teams vault by
|
|
pull, merge, push; OpenCreds read-only; else a 0600 file, said aloud.
|
|
- R6 [P0] Page log of fields only and result-page text; run record with no
|
|
values; cards kept in the run record and `errand status`, never posted.
|
|
- R7 [P1] Rule 1 (show before run, SHA-256 change shown), rule 11 (the user
|
|
agent drops `HeadlessChrome`, nothing more), rule 12 (dry run), rule 13
|
|
(loop and page limits).
|
|
- R8 [P1] `logicsrc errand run|validate|status` in CLI 0.7.0; docs and the
|
|
landing page say the runner ships.
|
|
- R9 [P1] Unit tests for the rule engine, gates, throttle, outcomes, inputs
|
|
and captcha gating; one integration test of the FTB example in real
|
|
headless Chrome against a local fake site with fictional data.
|
|
|
|
## UX Notes
|
|
|
|
A run prints the errand summary, the values it will use (secrets as `••••`),
|
|
each page's filled fields, and one final line on stdout (or the run record
|
|
with `--json`). A stop names the field, label, type and page, and where the
|
|
page log is.
|
|
|
|
## Tech Stack
|
|
|
|
TypeScript, NodeNext, commander 14, vitest 4, Chrome over CDP with no
|
|
dependency (ported from cli-tools' wcag.ts). Node 22+ for the global
|
|
WebSocket.
|
|
|
|
## Monetization
|
|
|
|
None. It is the reference implementation of an open standard.
|
|
|
|
## Success Metrics
|
|
|
|
- The FTB example runs end to end against the fake site, and `ftb` can later
|
|
be reduced to the errand files plus its PDF extractor.
|
|
- A second errand can be written and run without changing the runner.
|
|
|
|
## Risks & Open Questions
|
|
|
|
- The runner has not been run against the real MyFTB; the first real run
|
|
should be a `--dry-run`.
|
|
- Candidate order follows the spec's text (sources in order, newest year
|
|
within each); the worked example's `ftb secrets` listing orders by year
|
|
first. One of the two should change.
|