mirror of
https://github.com/profullstack/logicsrc.git
synced 2026-10-05 06:05:28 +00:00
5 commits
| Author | SHA1 | Message | Date | |
|---|---|---|---|---|
|
dde596b276
|
OpenErrand reference runner: @logicsrc/openerrand and logicsrc errand (#228)
* 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> |
|||
|
d38db62e8b
|
vault: autosync the personal vault to the logicsrc account (#226)
`logicsrc vault` (OpenCreds) lived only in ~/.config/logicsrc/opencreds. Lose the machine and the vault went with it, and a second machine had no way to get it. It now syncs to the logged-in account. Server (apps/pwa, /api/opencreds, session or lsk_ bearer): - opencreds_vaults: one per user. meta (key material already wrapped under the master password) + an encrypted folder list, each with a revision. - opencreds_items: one row per item, as the spec asks; envelope NULL is a tombstone so purges propagate; seq for incremental pulls. - Every write names its base revision; a stale one gets 409 with the current row. Writes are conditional and read back (each envelope's random IV identifies our write), so this needs nothing dialect-specific from SQLite or Postgres. - Stores ciphertext only. The server learns item count and type codes, as OpenCreds security.md already accepts. Client (@logicsrc/opencreds sync.ts, key-free except where noted): - Pull before every vault command, push after. Offline, the command still works and the change goes up next time. - Conflicts never lose data: the account's edit keeps the id and this machine's becomes "<name> (conflict copy)" (needs the unlocked key, so it waits otherwise). An edit beats a purge. Byte-identical envelopes are adopted, not split, so a lost sync.json is harmless. - Two different vaults (meta.createdAt differs) are never merged: refused, with `vault sync --use-remote` (backs this machine's up to .bak-NNN) or `--use-local`. - Remote item ids must be plain ids; anything else is ignored and never becomes a path. - Folder names are AES-GCM encrypted under the user key before upload. CLI (0.6.0): `logicsrc vault sync [--status|--use-remote|--use-local]`. Only the default vault syncs, and only when logged in; a --home or OPENCREDS_HOME vault stays local unless LOGICSRC_VAULT_SYNC=on; LOGICSRC_VAULT_SYNC=off disables it. The standalone `opencreds` binary gets no remote and never syncs. `init` on a machine that just downloaded the account's vault says to unlock it instead of suggesting --force. Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com> |
|||
|
5bebc50beb
|
pwa: read vault values in the browser with a pasted identity key (#225)
* pwa: read vault values in the browser with a pasted identity key The web app listed vaults but could never show a value: decryption needs the member's X25519 secret key, which only lives in identity.json on the machine that ran `logicsrc login`. Each vault now has a page (/teams/:slug/vaults/:id, linked from the dashboard) listing its secret names. Paste the identity key (or the whole identity.json) and public/vault.js decrypts in the browser with the same libsodium calls as the CLI: crypto_box_seal_open for the grant, then crypto_secretbox_open_easy per value. Nothing is sent to the server. - The pasted key is checked against the public key the server has on file before use, so a key from another machine is named, not a generic failure. - Show / Copy per value, Download .env, Forget key. The key is kept in sessionStorage unless "remember on this device" is ticked. - A member with no identity yet can create one in the browser. That registers only the public half, and is offered only when no key is registered, since replacing one would orphan every grant sealed to it. - libsodium is served from node_modules at /vendor (no CDN), like simplewebauthn. - Vault pages are no-store and the service worker no longer caches no-store pages. - CLI: `logicsrc teams key` prints the secret key to stdout alone (pipe to pbcopy) and warns when the server holds a different public key. The page also gives a jq one-liner for CLIs released before this command. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * pwa: rename data-secret to data-key-name ThreatCrush read data-secret="…" as a hardcoded credential (2 high, both the attribute name, never a value). Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * CLI 0.5.0 for teams key; install via install.sh, not npm @logicsrc/cli is not on npm; the CLI ships through curl -fsSL https://logicsrc.com/install.sh | sh, which builds master and reports the version from packages/cli/package.json. 0.5.0 marks the first build with teams key, and the vault page now says so and points older installs at the jq fallback. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com> |
|||
|
722480f674
|
Upgrade Next.js to 16.3.8 (critical RCE advisories) (#223)
Patches GHSA-vcvr-r3jv-pc5j, GHSA-2xp9-vwfh-vxw4 and GHSA-p293-qw3h-jr36. Next 16.3's build type check now fails on src/lib/pagination.test.ts, which imports a .ts path; allow .ts import extensions (noEmit is already on) so the build passes. Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com> |
|||
|
20797a98f1
|
Run on Bun: bun install, bun --bun next, both dev2 sites on Bun (#222)
* Run on Bun: bun install, bun --bun next, both dev2 sites on Bun Moves logicsrc.com and app.logicsrc.com (one image) off Node + npm onto Bun, following the fleet recipe (phonenumbers.bot pilot). - Package manager: bun.lock migrated from package-lock.json, so every resolved version is unchanged; packageManager bun@1.4.2. Root scripts run each workspace with `bun run --cwd <dir>` instead of `npm --workspace`. - Bun 1.4.2, not the fleet's 1.4.0: 1.4.0 re-resolves this workspace's `file:` cross-references differently on every install, so its own lockfile never passes --frozen-lockfile. 1.4.2 is stable on it. - Runtime: logicsrc-web runs `bun --bun next build/start`; apps/pwa (Express, app.logicsrc.com) runs `bun src/server.mjs`. - Image: .nixpacks/Dockerfile (the path both dev2 compose stacks build) is now a hand-written oven/bun image carrying the whole workspace, run as the non-root bun user. ENTRYPOINT stays `bash -l -c` so a compose `command:` is one string, as before; app.logicsrc.com's compose starts it with "npm --workspace @logicsrc/pwa run start", which .nixpacks/npm (the image's only `npm`) turns into `bun run start` in apps/pwa. Port 3000, the PUBLIC_URL build arg and the / health path are unchanged. The nixpacks .nix and build.sh are gone. - CI: both workflows install with bun and run every script through bun (Node stays only as the interpreter for vitest/tsc/node --test/Playwright, as before), and CI now boots the site under Bun. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> * ci: boot check on port 3100 and stop it before Playwright needs 3000 Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> * fix(web): keep next dev on port 5174, which Playwright waits on Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 5.5 (1M context) <noreply@anthropic.com> |