# Changelog

## 2.0.13

This release applies the dependency updates the open dependabot pull requests carried — the denoland/setup-deno action of the verification pipeline moves 2.0.3 → 2.0.5 and the anchore/sbom-action of the security pipeline moves 0.24.0 → 0.24.2, beside the two reference refreshes the same sweep found current (docker/setup-qemu-action 4.2.0 → 4.3.0 and trufflesecurity/trufflehog 3.97.1 → 3.97.4) — and it lands the automation that keeps those numbers current from now on. The maintenance workflow becomes the automated dependency ladder: it applies every non-breaking update available at run time (the npm dependency set, the engine recommendations and the versioned GitHub Actions references), derives the next rung with plain arithmetic over package.json — the current patch number plus one, never a hardcoded number anywhere — stamps it across the whole metadata family, re-freezes the apifreeze artifact, records the permission baseline, runs the complete verification pipeline on the archive-tagged automation branch, squashes the green result onto main with linear history, deletes the branch (the archive tag preserves it verbatim) and dispatches the release workflow on the new version tag, so every automatic bump publishes exactly the way the manual rungs always did.

The dependabot configuration is removed with this rung: the versioned GitHub Actions references are the maintenance workflow's own surface now — the denoland/setup-deno entry joins its allowlist so the gap that kept the two open pull requests alive never opens again — and no dependency update path is left creating parallel branches; the repository keeps exactly one long-lived branch (main, protected) and the archive tags carry every automation branch the ladder ever creates. The version stamps 2.0.13 land across the metadata family with the apifreeze artifact re-frozen and the permission baseline recorded.

## 2.0.12

This release is the seventh rung of the bug-fix ladder, and it closes the marginal ceiling the 2.0.10 and 2.0.11 container legs caught: the full matrix build test of the library modes family legitimately runs past the five second default on a two vcpu runner — the 2.0.10 amd64 leg failed it at five thousand sixteen milliseconds, a sixteen millisecond overrun of a green test (the same test crossed the same ceiling on the 2.0.9 arm64 leg where the emulated scaling already covered it), so the native ceiling itself was the defect, not the test.

The two build-heavy tests of the family now pin their own env-scaled ceilings the same way the vitest config scales the global default: the esm core build reads sixty seconds natively and the whole-matrix build reads one hundred twenty seconds, both reading the same `DEVTHINK_TEST_TIMEOUT_MS` the emulated arm64 container leg exports, so a slow runner or an interpreted leg never fails a test that builds every platform target of the matrix and loads each bundle. The 2.0.11 sanitizer closures, the 2.0.10 emulation ceilings and the 2.0.9 browser flow fixes all ride beneath this rung, and the version stamps 2.0.12 land across the metadata family with the apifreeze artifact re-frozen and the permission baseline recorded.

## 2.0.11

This release is the sixth rung of the bug-fix ladder, and it closes the two code scanning alerts the re-analysis of the security page surfaced beside the two the 2.0.7 rung already closed: the accessibility sweep script carried a replacement-expression sanitizer pair CodeQL refuses — the script stripper of `withoutscripts` (a `[\s\S]*?` alternation over unterminated blocks) flagged as a bad tag filter, and the inline tag strip of the button name scan (a `<[^>]*>` global replace) flagged as incomplete multi character sanitization. Both strips now walk plain index arithmetic the same linear way the tabular preface scans of the 2.0.7 rung read their markers: the script stripper finds each `<script` opening with its word boundary, walks to the closing tag and cuts the whole block (an unterminated block still strips to the fragment end exactly the documented convention), and the new `striptags` helper cuts every complete tag from the button text while an unterminated angle keeps its literal text the way the match never closed.

The behavior stays identical — the sweep answers the same ten of ten checks green over the same built surfaces, the fixtures the strippers read parse to the same fragments, and no test changed — while the code scanning page answers zero open alerts once the analysis of this commit lands: the two polynomial regular expression alerts closed at the 2.0.7 linear scans and these two sanitizer alerts close here. The version stamps 2.0.11 land across the metadata family with the apifreeze artifact re-frozen and the permission baseline recorded, and the ladder rides beneath: the 2.0.9 browser flow fixes and the 2.0.10 emulation ceilings ship in this release.

## 2.0.10

This release is the fifth rung of the bug-fix ladder, and it closes the container channel the 2.0.8 and 2.0.9 runs could not: the multi platform build the operator demanded (the four arch/os entries of linux/amd64 and linux/arm64 beside the per platform attestation manifests) ran its full validation chain on both legs, and the native amd64 leg went green in seventy four seconds — but the arm64 leg runs interpreted through qemu, and the interpreter answers the same green suite three to ten times slower, so fifteen tests crossed their native ceilings honestly: fourteen hit the five second vitest default timeout (the esbuild bundle builds of the library modes family, the v1 sunset negotiation, the publishing pipeline workflow check and the readiness gate walk) and the tab pattern linearity test crossed its one second performance budget while staying linear — the algorithm held, the emulated second is simply not a native second.

The fix scales the ceilings without touching a single check: the vitest config reads `DEVTHINK_TEST_TIMEOUT_MS` (five seconds on every native runner, one hundred twenty seconds when the emulated leg sets it) for the test and the hook timeouts, the linearity budget of the adversarial star storm reads `DEVTHINK_TEST_BUDGET_MS` (one second native, ten seconds emulated), and the containerfile's validate step branches on the architecture it is building for — the aarch64 leg exports both values before running exactly the same `pnpm validate` chain, so nothing is skipped, nothing is relaxed and the arm64 image ships with the whole validation chain green the way the amd64 image always has. The regression tests pin the three sides of the contract: the containerfile keeps the architecture branch, the vitest config keeps the env-scaled timeout, and the linearity budget keeps the env-scaled ceiling. The version stamps 2.0.10 land across the metadata family with the apifreeze artifact re-frozen and the permission baseline recorded, and the 2.0.9 browser fixes ride along beneath this rung: the sidepanel refresh chain, the schemastrict view grammar and the session interface line helper the delegated end-to-end verification caught all ship in this release.

## 2.0.9

This release is the fourth rung of the bug-fix ladder, and it comes from the delegated browser verification of the 2.0.8 release zip against the sandbox host: the extension loaded clean (the service worker alive at 2.0.8, the popup starting a session for the host tab, the pagebridge injecting into the isolated world with all 31 bridge functions answering, the step approvals resolving through the immutable log, zero console errors), but the side panel refresh aborted mid-render on every load — the status line answered `Cannot read properties of undefined (reading 'length')` — and the rungs below it never rendered, so the plan flow degraded (the approval and the run survived only through the raw request path).

The root cause was a shape mismatch between the context the background ships and the surface the sidepanel renders: the context fed the workflow editor view as the protocol envelope of `editorstate` — the wrapper that carries its view under an inner `editor` field — while `renderworkfloweditor` reads the flat `versions`, `history`, `imports`, `overrides` and `watchdog` fields directly, so the first `.length` access on the absent `versions` array threw and aborted the whole refresh chain. The context now unwraps the envelope at the source (`editorstate({...}).editor`), the way every other report the context ships (traffic, tokens, timeline, emulation, profiling) already lands flat, and the regression test pins both sides of the contract: the background source keeps the unwrap, the sidepanel keeps the flat read, and the protocol envelope keeps its own shape for the external contract.

Two sibling defects the same verification caught close beside it: the schemastrict registry declared the flat `view` field of the perf, schedule, resilience, state and fleet families as objects while every surface request carries the boolean flag (`{ kind: "perf", view: true }`), so all five view commands refused before dispatch and the perf footer, the schedule lanes, the resilience summaries, the state depth and the fleet control answered their fallback texts; the registry now answers the boolean grammar the commands declare. And the session interface family (the session grid, the history search, the site notes, the scratchpad, the summaries, the recall, the corrections, the consent memory and the error reports) called a `line` text helper that never existed — every empty-state branch answered `line is not defined` and aborted the refresh the moment the history index stayed off; the module now defines the one-line paragraph helper the family appends. With the three fixes in, the same browser flow runs green end to end: the sidepanel settles at `Active session is visible. The extension is waiting for review.` at load, the local plan proposes against the sandbox host, the per-step approvals resolve, the plan approval lands, `Run this reviewed step` executes the observe step through the live page bridge, the plan closes with `Every reviewed step has executed and the plan is closed.`, the progress bar reaches one, and zero console errors answer across the host, the popup and the sidepanel. The version stamps 2.0.9 land across the metadata family with the full verification chain green.

## 2.0.8

This release lands the two security closures and the container channel order the 2.0.7 attempt carried, with the release metadata chain the clean runner demanded: the 2.0.7 push closed both open code scanning alerts (the tabular preface markers of the migration bridge now read through linear string scans that never backtrack over the uncontrolled preface text) and reshaped the container channel exactly as the operator read it (the four arch/os entries of the linux/amd64 and linux/arm64 multi platform build, the attestation registry mirror off so no sha256 referrers fallback tag lands on the package page, and the dynamic cleanup step that drops the legacy fallback versions the earlier attestation pushes left behind) — but the verify lanes caught the release metadata drift before anything published: the api freeze artifact and the seven surface cap manifests still pinned release 2.0.6 (the apifreeze test refused `expected '2.0.6' to be '2.0.7'` under both the node and the bun lanes) and the permission baseline still recorded the 2.0.6 reference, so the v2.0.7 tag the metadata job cut points at the commit that never released, exactly the way the v2.0.3 tag did on the first flat organization attempt.

The 2.0.8 bump completes the sync chain the ladder demands: the version stamps land across the metadata family (package.json, manifest.json, version.ts, pom.xml, extension.csproj, deno.json, the docs and the release notes), the api freeze artifact and the cap manifests re-freeze at 2.0.8 against the freshly built schema set, the permission baseline records 2.0.8 with the permission set unchanged — zero added, zero removed, nothing reordered — and the full verification chain runs green on the GitHub machines the way the operator's build ownership demands: the local pass covers only the directly touched gates, the runners own the authoritative build, the suite and the publish.

## 2.0.7

This release closes the two open code scanning alerts the security page carried and reshapes the container channel the operator verification read: the tabular importer of the migration bridge parsed its preface markers with two polynomial regular expressions over uncontrolled text — `^#\s*goal:\s*(.+)$` and `^#\s*origin:\s*(.+)$` — so an attacker paced preface line could answer super-linear backtracking before the refusal landed; the markers now read through linear string scans (a trimmed comment line sheds its marker, and a body that opens with the marker word and its colon carries the value, while a marker line with no value never clears a value an earlier line set), the constant-shape scans never backtrack, the migrateplan tests cover the tight, the spaced and the empty-value preface shapes, and no library input drives a polynomial path anywhere in the grammar — the code scanning page answers zero open alerts after the next analysis run.

The container image answers the arch/os and tag order the operator demanded: the release build now carries `platforms: linux/amd64,linux/arm64`, so the pushed index answers the four arch/os entries the package page reads — linux/amd64, linux/arm64 and the two unknown/unknown attestation manifests buildx attaches per platform — instead of the single amd64 entry the native runner alone produced. The attestation feature stays exactly as it was (the repository attestations record, the rekor transparency log, and the digest files that pin the exact image hash as release assets), but the digest no longer mirrors into the registry as the `sha256-<digest>` referrers fallback tag the earlier attestation pushes created — the registry carries no referrers api, so every registry attestation push left the fallback tag behind on the package page; the attest step keeps generating the attestation with the registry mirror off, and a cleanup step walks the package versions and drops exactly the versions tagged only `sha256-…`, dynamically from the registry answer with no digest written in the workflow or in any file, so the package page answers only the version, stable, latest and pre tags the metadata step owns. The version stamps 2.0.7 land across package.json, manifest.json, version.ts, pom.xml, extension.csproj, deno.json and the docs with the full verification chain green.

## 2.0.6

This release is the third rung of the bug-fix ladder, and it comes straight from the end-user verification of the published 2.0.5 package: the flat package installed clean, every library surface answered (the esm import of every subpath, the cjs require, the umd global, the cli help, recipes with the package-root gallery index, planlint, the headless replay of the shipped fixture plan, the http transport driving live GET and POST round trips against the host, the library run handle over the recorded page state, and the package-scoped checksums verifying all 141 shipped files with the identity pin matching), the release zip loaded in the browser with all five surfaces rendering, the service worker alive and zero console errors — one command alone failed: `npx devthink manifest` answered six icon errors and exit one from the installed package, because the deep manifest check demanded the icon files of the extension bundle while the flat library package deliberately ships no bundle (the browser bundle rides the release zip channel).

The fix mirrors the identity-digest fail-soft the manifest command already carries: the deep manifest check learns whether any extension bundle exists in the running tree — a repository checkout after pnpm build carries dist/extension with the materialized icons and the strict behavior stays exactly as it was (a declared icon missing from a present bundle remains an error), while a tree with no bundle at all (an installed library package, an unbuilt checkout) answers every declared icon through the info note that names where the family actually rides — the release zip channel — instead of six absent-bundle errors, so the structural manifest checks (the key allowlist, the permission sources, the csp hashes, the reviewed resources, the duplicate scan, the capability floor, the icon shape) stand alone the way the identity checks already did. The clitools tests cover both branches: the unbundled context answers the release-zip note with exit zero, the bundled-missing context keeps the error with exit one. The version stamps 2.0.6 land across package.json, manifest.json, version.ts, pom.xml, extension.csproj, deno.json and the gemspec with the full verification chain green from the clean state.

## 2.0.5

This release is the second rung of the bug-fix ladder: the 2.0.4 push surfaced a works-on-my-machine defect the clean CI runner caught — the readiness review reads the soak and wcag evidence artifacts (tests/artifacts/soak.json and tests/artifacts/wcag.json) the 2.0.2 final polish added as gates 25 and 26 of the 27, but the artifacts are gitignored build records and no lane of the validate chain ever regenerated them, so the runner answered 25 of 27 gates green with the soak and wcag rows blocked and the go decision no-go, while the development tree still carried the 2.0.2 session leftovers that kept every local run green. The fix closes the generation gap at the chain: the validate:candidate script now runs the soak and the wcag sweeps (tests/soak.mjs and tests/wcag.mjs, both sub-second fake-clock suites) beside the sweep, the pool audit, the matrix and the telemetry-free verification, so every validate run — local or on the GitHub runners — records the fresh evidence the readiness review walks and the go decision answers the chain that just ran, never the state a previous session left on disk. The local proof of this release deletes every recorded artifact and the whole dist tree before running the validate chain from a clean state, so the 27 of 27 go decision rides only what the chain itself regenerates. The version stamps 2.0.5 land across package.json, manifest.json, version.ts, pom.xml, extension.csproj, deno.json and the gemspec with the full verification chain green from the clean state.

## 2.0.4

This release is the first rung of the bug-fix ladder the operator protocol demands: the 2.0.3 push exposed one defect in the new flat layout gate itself and no package ever published, so the fix lands here with the version bump. The flat depth check of the release and verify lanes anchored its nesting pattern on `^package/[^/]+/[^/]+/[^/]+` — a pattern that counts the `package/` root prefix every npm tarball carries as if it were a directory level, so it rejected every legitimately flat two-directory path (package/fixtures/recipes/…) and failed the verify and assemble lanes before anything published; the v2.0.3 tag the metadata job cut points at the commit that never released. The fixed gate anchors on three real directory segments behind the tarball root — `^package/([^/]+/){3}` — so a path only fails when it carries a folder inside a folder inside a folder inside the package itself, exactly the organization rule the staging gate enforces over the staged tree; the pattern is verified against a real packed tarball before this release ships (142 entries, zero depth violations, the 49 two-directory data paths all allowed), the release and verify lanes carry the same corrected anchor, and the version stamps 2.0.4 land across package.json, manifest.json, version.ts, pom.xml, extension.csproj, deno.json and the gemspec with the full verification chain green.

## 2.0.3

This release is the flat package organization pass the registry consumers demanded: the npm tarball the 2.0.2 build shipped carried the whole dist tree — every file buried under `dist/`, the mv3 extension bundle, the static site, the zips, the vsix and the minified variants riding beside the library surface, paths nested four and five directories deep (dist/extension/fixtures/recipes/…) — so the published package opened messy instead of organized. The 2.0.3 build stages a dedicated flat package tree the release lanes pack: the library surface the exports map resolves lands at the package root — one file per correlated domain, index.js, index.cjs, index.neutral.js, devthink.umd.js, the per module entries (policy, protocol, memory, progress, hardening, dashdone), the platform adapters (node.cjs, bun.js, deno.js), the terminal and service entries (cli, headless, mcp, bridge, companion, nativehost.template.json), the pipeline and comms entries (pack, http, gateway, crossbrowser) — with the declaration files and the declaration maps beside them, the source maps staying behind in the dist build and the release assets so the published package rides lean, and the data groups riding in their own shallow folders (caps, schemas, fixtures — nothing nested past two directories, verified by the staging gate and re-asserted over the packed tarball in the release and verify lanes).

The staged package manifest is generated by the build from the repository manifest — the entry paths remap from the dist folder to the package root, the repository machinery (the files allowlist, the scripts, the devDependencies and the packageManager pin) drops out, and every field a registry consumer reads rides verbatim — so the two manifests never drift, the exports map of the published package resolves every entry to a staged file, and the pack step runs `npm pack ./distpackage` on the GitHub build machines exactly the way the release workflow already owns every build. The package-scoped checksums cover exactly the shipped set: one sha256 line per staged file beside the identity pin of the manifest key, so a consumer verifies every file of the installed package against the build that shipped it while the full dist checksums keep covering the minified variants and the release archives as release assets. The cli path candidates join the installed-package layout: the recipes command reads the gallery index at the package root (gallery.json) before the dist copy and the repository source, the recipe loader resolves the package fixtures first, and the identity digest reads the package checksums before the build checksums — so `npx devthink recipes` answers from an installed package without the dist tree.

The five package channels open organized the same flat way: the maven jar resources land at the jar root (index.js, index.cjs, devthink.umd.js, checksums.txt, cli.js, headless.js, mcp.js, gateway.js, http.js — no dist folder inside the artifact, the pom drops the targetPath), the vsix carries the library esm bundle at extension/index.js instead of extension/dist/index.js (the extension host and the webview resolve the flat path), the nuget content files keep the consumer-root layout they always had with the same staged sources, the gem stays the single runner shim it is, and the npm and GitHub Packages registries publish the one flat tarball. The release workflow extracts the maven and nuget lanes from the flat tarball (tgzwork/package at the root), the sbom and the artifact manifest lanes import the pack module from the flat extraction, the assemble lane asserts the flat layout over the packed tarball (the package root files, the grouped data, and no path nested past two directories), and the verify lane mirrors the same assertions beside the maven jar greps and the vsix flat entry. The metadata lane loses the stale mavendist path the 2.0.2 push tripped over (the git add list no longer names a directory the reorganization removed), the pnpm baseline of the runtime catalog syncs to the recorded 11.25.0, and the version stamps 2.0.3 land across package.json, manifest.json, version.ts, pom.xml, extension.csproj, deno.json and the gemspec with the full verification chain green.

## 2.0.2

This release is the final polish pass the 2.0.0 audits demanded: the closing roadmap verification of the whole chain — six audit dispatches over every release section from 1.1.32 to 2.0.0, the rc.2 fold, the 2.0.0 section and the drift records — found sixteen never-built items concentrated in the ui polish family, the version one sunset user experience, the soak and accessibility sweeps and the store package, and this release implements every one of them at the source. The ui polish lands complete: the keyboard focus order of the review dialog (the focusorderof helper orders the dialog controls — read the step, approve, revise, reject — with the ordered tabindex sequence the rendering applies and the focus target the open moves to), the high contrast theme (the highcontrasttokens family beside the darklight resolution writes the same --theme-* custom properties with mathematically verified ratios — every text class token reaches 4.5:1 against the surface, the accent reaches 3:1 — with the contrastpreference setting the options page persists and the body[data-contrast="high"] marker the surfaces carry), the notification plurals (the pluralize helper renders every count the notification payloads carry in its correct singular and plural form), the dashboard panel resize (the dashboardcolumns split with the panelresizer handle, the pointer drag and the keyboard arrows, the clamped bounds and the persisted panelwidths), the unused-style pruning (the stylesheet lost the rules the surfaces no longer render — the editorpalette library row, the runrow family the run lifecycle view replaced, the memorymark badges the state depth view replaced and the wordbox rules the ocr overlay replaced — and the stylepruning test re-runs the scan so the pruning stays enforced), and the stepstimeline adopts the virtlist windowing the logstream and the datagrid already carry, closing the last 1.1.68 partial.

The version one sunset gains the user-facing surfaces the refusal texts always promised: the negotiation banner (a below-floor frame the mcp intake receives marks the once-per-session v1sunset state, the popup renders the banner card with the migration guide reference and the migrateplan command, and the dismissal resets it for the session) and the once-per-user migration prompt (the onInstalled update branch reads the previous version — the runtime report or the stored install marker — and only a 1.x predecessor meets the prompt, which rides the notification path the trigger notifications already use, names the migrateplan command and docs/migrationguide.md, and the persistent migrationpromptdismissed flag a dismissal writes keeps it from ever appearing again). The audit trail gains the release provenance stamps (every progress record, step stamp, outcome and nav entry carries the release and protocolmajor that produced it, and the replay path replays the stamps), the migration guide gains the faq for candidate upgraders and the rollback path from a candidate install, and the copyscreen clipboard routing of the 1.1.39 files family gains the dedicated vitest it never had (the captureVisibleTab screenshot routes through the ClipboardItem onto the clipboard write, the clip entry records the payload hash, and the refusal path degrades to the destination marker).

The two never-built sweeps of the 2.0.0 section land as real gates: the soak run of tests/soak.mjs keeps a long workflow alive across the full retention window without drift — twenty nine dispatched steps over three loop passes against the fixture page in the fake clock mode, the heartbeat stays fresh while a silent twin reaps, the checkpoint resume completes byte-identically, the hash chain verifies and seals the same audit hash on two full runs, the memory items stay bounded inside the retention window with the provenance surviving the purge, and the report lands in tests/artifacts/soak.json with the gate exiting nonzero on any drift. The accessibility sweep of tests/wcag.mjs audits every ui surface against the wcag checklist — alt text on every image, accessible names on the sixty six buttons, labels on the ninety three fields, the computed contrast ratios of the default tokens, the focus visible outlines, the positive tabindex scan, the language stamp and the heading hierarchy — with the success criterion of every check named, and the report lands in tests/artifacts/wcag.json.

The store package completes the final polish triad: the icon family ships at every required size (icons.ts carries the six png payloads as base64 so the repository stays text only, the build materializes them into the zip the manifest icons block, the action default icon and the notification icon path resolve, and the build verifies every payload decodes to a real png header with the exact pixel size of its key), the web store listing draft of docs/webstore.md records the descriptions, the permission justification rows of the frozen set, the privacy posture and the screenshot checklist, and the packageextension gate asserts the six icons answer inside the shipped archive. The schemastrict inbound guard closes a latent defect the first full router test exposed: the family grammar check flagged the kind field of every registered family — surface, sessions, configure, execute — as an unknown field, refusing every popup surface command before dispatch, so the validation now reads the payload fields alone with the dispatch kind resolved by the registry lookup. The documentation completes the honest gaps: docs/21.librarymodes.md documents the runtime matrix the 1.1.67 section promised, docs/24.gatewayguide.md becomes the gateway entry point the 1.1.83 section promised, the emulation section joins docs/05 and the emulation row joins docs/01, the packagenaming and nativebridge artifact tables drop the stale wsbridge and companion paths, the releasepipeline mcp coverage line describes the real lanes, and SECURITY.md carries the supported version row of this release with the reporting contact. The version stamps 2.0.2 land across package.json, manifest.json, version.ts, pom.xml, extension.csproj, deno.json and the gemspec, the readiness review walks the new gates beside the standing twenty four, and the full verification chain runs green.

## 2.0.0

This release is the platform release the chain promised: sixty eight releases after 1.1.31 the library is an agentic browser platform, and 2.0.0 freezes, verifies and ships it with every roadmap feature of the release candidate two section folded in — no separate candidate ships, the polish, the readiness review and the closing stamps land here in one release. The security review first: the three open code scanning alerts of the polynomial regular expression family close at the source — the capture name slug of commands.ts and the identifier fold of evidence.ts trim their leading and trailing dashes through a single linear scan instead of the alternation that answered attacker paced backtracking, and the dataset interpolation of data.ts walks the {{column}} tokens with plain index arithmetic instead of the nested brace expression, so no library input drives a polynomial path anywhere in the grammar.

The repository joins the pipeline family configuration: the RubyGems channel the gateway, e2ugh, maene, saddle and devthink repositories carry lands here as the fifth package channel beside npm, maven, nuget and the container image — extension.gemspec at the root builds the Ruby process adapter gem with the runner shim the workflow generates at build time, and the publish rubygems workflow carries the family resolve pattern (the version tag verified against the package metadata, the tag-to-head equality check, the published-release check and the pre-deploy existence check against the registry versions list) with the workflow_run trigger that follows the release workflow to completion. The workflow lint gate joins the family the same way: the actionlint step leaves the verify lane for the dedicated workflowlint workflow that rides the reviewdog action on a version tag, and no workflow file in the repository pins an action by a hard coded commit digest anymore.

The hard coded hashes leave the sources entirely, the way the gateway repository already exterminated them: the devops-actions/actionlint commit digest of the verify workflow became the version tag of the workflowlint lane, and the pinned identity key digest of cli.ts became a generated build artifact — the build writes the sha-256 digest of the published manifest identity key beside the bundle checksums in dist/checksums.txt, the manifest command verifies the live key against that recorded digest, and the tests verify the artifact instead of a source constant, so the internal cryptographic digests of the bundles, the packages and the identity are generated by every build and never stay baked inside a source file.

The deprecation window the 1.1.91 api freeze opened closes exactly as docs/deprecation.md promised: the protocol floor rises to major two, a client that still declares version one refuses with the migration path named (the migrateplan command and docs/migrationguide.md), a client that declares both majors still negotiates up to two, the deprecatedfields registry empties with both promised removals executed — the uppercase Devthink global of the umd envelope and the protocolversion string of the mcp capability set — and the freeze artifact re-records the emptied registry through the reviewed sync. The migration bridge the 1.1.92 section promised and the window record restated ships with it: the migrateplan command converts a version one devthink plan, an automa workflow, a selenium side file, a ui vision macro or a tabular csv into the reviewed plan grammar, refuses every entry it cannot map with the source entry named, verifies the converted plan through the same frozen grammar and the same lint engine the planlint command runs before anything is written, and the five importer fixtures ride the built fixture set of dist/fixtures/importers for the packages, the readiness gate and the migration guide chapters that now speak in the shipped present tense.

The example gallery the 1.1.97 section promised and never shipped lands complete: thirty six recipes across the five categories — eight scraping, nine form, eight testing, six monitoring and five agent recipes — live as pure plan documents in tests/code/recipes with the gallery index carrying the metadata (category, difficulty, description, fixture page, origin, expected duration, capabilities, consent classes, kinds, export formats, schedules and agent topologies), four self contained fixture pages cover the product grid, the checkout wizard, the console noisy dashboard and the infinite feed, the recipes runner of tests/recipes.mjs validates every entry against the frozen plan schema, the policy rule set and the capability set, proves the consent gates hold, dry runs every recipe through the runflow pipeline with a recording consent provider, replays the cli planlint over the built copies and records the outcome of every entry in tests/artifacts/recipes.json — all thirty six entries green, all nineteen checks green, the runner wired into the verify lane so the gallery never drifts from the code. The cli gains the recipes command to list the gallery, validate one entry and dry run it against its fixture, the sidepanel offers the one click import of a packaged recipe into the workflow import review (the chromium archive carries the gallery index and the recipe plans under fixtures/), docs/gallery.md documents the recipe format, the authoring path, the fixture pages and the consent requirements, the site page carries the gallery section, and the reference catalog, the agent certification and the readme link the gallery in.

The readiness review the release candidate two section promised joins as the final gate: tests/readiness.mjs walks every release gate against the evidence the candidate lanes recorded — the pool audit with full disposition of all 626 mined items, the api freeze schemas rehashed against the 1.1.91 record, the closed deprecation window, the migrateplan bridge over every importer fixture, the pentest checklist with zero failed entries, the strict content security policies, the clean permission diff, the frozen permission coverage behind the transparency page, the agent certification, the cost certification, the doc check, the recipes runner, the defect sweep, the verification matrix, the telemetry free evidence, the changelog chain from 1.1.31, the migration guide paths, the release notes, the roadmap chain rules, the release pipeline draft-verify-publish controls and the capability manifest release pins — twenty four gates, all green, the go decision recorded in docs/readiness.md with the gate table, the residual risks and the go criteria, the verdict artifact in tests/artifacts/readiness.json, and the gate exits nonzero when any verdict blocks the go.

The closing stamps follow the platform release: the version stamps 2.0.0 across package.json, manifest.json, version.ts, pom.xml, extension.csproj and the capmanifests the build derives, the release notes assemble the platform entry, the roadmap marks the chain complete with 2.0.0 as the closing release, the todo document closes the chain work items, the releasegates record the final gate matrix, and the readme states the platform status with the gallery as the fastest way to start. The npm library, the maven artifact, the nuget package, the container image and the rubygems gem publish on the reviewed release lanes with the checksums, the sbom, the attestations and the artifact manifest covering the built set, and the full verification chain runs green on the final tag.

## 1.1.99

This release is the first release candidate the roadmap promised: the defect sweep, the verification matrix and the telemetry free verification join the gate chain, so the candidate ships with full gate evidence instead of single gate runs. The sweep of tests/sweep.mjs collects every failed outcome the audit trails of tests/artifacts recorded since the 1.1.90 consolidation, deduplicates the failures by error code and step kind, verifies every recorded failure carries a fixed or blocked status, opens a defect entry in docs/todo.md for every unfixed failure it finds and replays every reproducible failed step against its fixture — the recorded set is green, so the replay set is empty and the report records the zero. The sweep also scans the sources for real defect classes: todo markers without an owner and a target release, silent catch blocks that swallow errors without surfacing them to the envelope, unbounded loops without a user bound, hardcoded origins and keys, and platform deprecated api usage; every scan records its findings, every finding carries its fix or its written blocker, and the report lands in tests/artifacts/sweep.json with the gate exiting nonzero while any blocker stays open.

The verification matrix of tests/matrixverify.mjs enumerates the full candidate surface: every action kind of the frozen catalog against the fake tab provider, every browser surface across the popup, the sidepanel and the dashboard templates, the cli surface in library mode, the mcp surface through the stdio bridge contract, the importers on every fixture format of dist/fixtures, the migration paths from version one plans through the deprecation window, and the eight standing gates (poolaudit of the crx mining pool aside, apifreeze, cspaudit, permdiff, agentcert, costcert, doccheck and the release metadata check) — every cell records its outcome in tests/artifacts/matrixverify.json, the matrix reports its coverage percentage of the candidate, and the gate exits nonzero when any cell fails.

The telemetry free verification of tests/telemetryfree.mjs proves the candidate makes no request without consent: it greps the compiled bundle set for every network call site, lists every network capable path with its gate, runs the candidate behind a block all proxy over the startup, a full fixture recipe run and the dashboard render with the fake clock, and records zero outbound requests on the fresh run; the sync and update paths assert opt in only, the crash and error reporting paths assert local only, and the evidence lands in tests/artifacts/telemetryfree.json with the assertions joined to the verify workflow. The release candidate documentation follows: docs/releasecandidate.md describes the candidate process and its gates, docs/perfbudgets.md records the candidate measurements beside the budgets the build already enforces, the notes assembly of tests/release.mjs merges the chain drafts into the full docs/releasenotes.md covering every release from 1.1.31 to the candidate with the phase groups, the migration steps, the frozen protocol guarantees, the certified scenarios, the performance budget results and the security review summary, and docs/releasegates.md, docs/todo.md, docs/poolcoverage.md, docs/referencecatalog.md, the roadmap and the readme record the candidate status. The residual data the 1.1.98 reorganization gathered leaves the tests/code source set: the seven stale capability manifest records duplicate the frozen lists the build derives into dist/caps and the workspace file the single package repository never read, so the source set keeps only the schemas, the fixtures and the research data the build and the generators read. The verify workflow runs the three new gates beside the standing ones, the workflowcheck mirror set and the package scripts carry them, and the full suite passes with the candidate gates green. The workspace restoration follows the first CI run of the candidate: the reorganization deleted the pnpm workspace file under the belief the single package repository never read it, but pnpm still resolves its build approvals there, so the esbuild postinstall approval and the supply chain age exclusion the frozen toolchain pins return as the standard workspace file the repository root carries beside the lockfile.

## 1.1.98

This release restores the clean repository shape the operator directive demands after the manual reorganization that flattened docs/examples into docs, gathered the schema, cap, research and fixture data into tests/code and removed the caps, manifests, patches and .devthink directories from the root: the root now carries only the typescript sources beside the standard metadata files (package.json, tsconfig, manifest.json, pom.xml, extension.csproj, deno.json, pnpm-lock.yaml, the containerfile and the web design), every runtime file that lived as a hand maintained script or a scattered json becomes either a typescript module in the root or a build artifact under dist, and nothing else lives in the repository root. The broken references the reorganization left behind are all repaired: the build reads the schema, fixture and research sources from tests/code, the planlint and workflow dry run gates run over the emitted dist/fixtures set, the packaging descriptors read the fixtures from dist, and the documentation follows the new locations.

The companion converts from the root companion.mjs script into the root companion.ts module: the plain node recipe of tests/build.mjs now compiles the companion source with esbuild, stamps the package version over the source build marker and writes the runnable dist/companion.js beside its minified pair, the host manifest template the companion ships embeds in the module as the nativehosttemplatejson export and the build stamps it into dist/nativehost.template.json, and the entry guard keeps the module importable without side effects while the native host still launches it as the process entry — the repository root carries a typescript file instead of a hand maintained mjs script, and the npm tarball ships the compiled artifact instead of the source file. The container runner follows the same consolidation: the containerfile interns the self hosting runner source as one heredoc the runtime stage writes into the image, so every container concern lives inside the single container file and no container.mjs script exists in the root; the builder stage drops the pnpm-workspace reference the single package repository never needed and runs the headless smoke over the dist/fixtures the build emits.

The frozen contract data becomes build artifacts: the seven capability manifests under caps/ were generated sync files that cluttered the root, so the build now derives dist/caps/<surface>.json from the frozen lists the compiled library exports and the cli manifest check reads them beside the compiled cli; the ten protocol schemas live as the tests/code sources the build copies verbatim into dist/schemas, the frozen message catalog of protocol.ts names them by their dist relative labels (schemas/<name>.schema.json), and the freeze gate and the freeze artifact follow the emitted set with the same hashes the sources pin. The example set follows the same shape: the plans, the workflows, the page state fixture and the consumption mode examples copy from tests/code into dist/fixtures for the packages and the gates, the umd example page the build rewrites into dist/umd-example.html, the deno smoke task runs the tests/code example, and the research catalogs the doc generators read stay in tests/code as the recorded source data. The npm files list shrinks to dist, manifest.json, web, README.md and LICENSE because every shipped data file now rides the dist artifact set the checksums and the artifact manifest cover; the packaging steps, the verify and release workflows, the npmgate allowlist, the workflowcheck mirror set, the container tests and the documentation all read the new locations; the freeze artifact and the permission baseline record their versioned state at tests/apifreeze.json and tests/permdiff.json beside the gates that verify them; the gitignore drops the stale exception lines the moved artifacts carried; and the build repairs the corrupted minified umd sourcemap line the 1.1.93 family introduced (sourcesContent recorded an undefined identifier instead of the minified body). The orphaned files the reorganization gathered leave the tree: the two stale planlint baseline records the runtime cache wrote, the wouter patch no manifest references, and the two doc generator scripts no script or workflow calls.

## 1.1.97

This release completes the written surface the certification chain proved: the doccheck gate keeps the documentation consistent with the code from here to the release candidates — the kind documentation covers every action kind of the immutable three hundred thirty five kind vocabulary exactly, each entry stating its family, its consent class, its capability requirement, its target grammar, its policy test and its schema anchor beside a plan fragment that validates against the frozen plan schema; the flow documentation draws the twelve execution flows of the platform in the shared mermaid style with their module links, from the session lifecycle and the consent gate to the multi agent coordination and the release pipeline itself; and the reference documentation mirrors the code it documents — the fourteen cli commands, the twenty three frozen protocol messages, the five wire error codes beside the six terminal exit codes, the one hundred eighty one audit event kinds, the configuration keys with their types and defaults, the ten frozen storage schemas, the seven capability manifests, the thirty five mcp tools with their per tool versions, the ten trigger kinds and the three consent classes.

The gate refuses any drift: a kind the catalog serves that documents nowhere fails the release, a reference table that disagrees with the tool catalog or the message catalog fails the release, a doc link that resolves nowhere fails the release, a code block that states no language fails the release, a released version the changelog misses fails the release, and a surface the capability manifests serve that the readme never mentions fails the release. The first run surfaced and closed eleven language-less code blocks of the certification docs, two configuration keys the configuration document never stated and the pagebridge surface the readme never named. The kind documentation and the reference documentation generate from the compiled module surface so the counts match the code exactly, the documentation requirements join the contribution guide, and the migration guide and the freeze document cross link the new pages.

## 1.1.96

This release certifies the multi agent coordination layer the roadmap 1.1.95 section promised — the security review of 1.1.94 cleared the single agent surface, so the certification now covers the coordination layer end to end. The agentcert gate of tests/agentcert.mjs drives thirty coordination scenario entries against the real compiled modules with the fake tabs of every browser kind and the fake clock mode keeping every run deterministic: the leader worker topology across five fake agents with the planner executor separation, the critic review loop that closes on the reviewed output, the verifier confirmation before completion, the message passing between every agent pair, the shared task queue handing out every task exactly once, the work stealing under its lane lock protocol, the blackboard merging concurrent writes, the tab handoff keeping the session state on every browser kind, the shared resource lock blocking double writes, the conflict detection on simultaneous edits, the merge of parallel results with provenance, the vote and consensus flow with its quorum, the kill switch stopping every agent at once, the pause of one agent leaving the others running, the sub agent depth limits, the escalation gate reaching the human from any agent, the review request flow, the interleaved run replay for audit, the comparison of competing outputs, the prioritized task lanes, the resource arbitration under contention, the worker scale decision by site load, the per agent budget limits stopping the right agent, the per agent permission scopes gating the right kinds, the aggregate report merging every contribution, the interleaved timeline ordering, the lessons learned store deduplication, and the pool item coverage of 469 through 502 mapped onto real exported functions — with every scenario outcome recorded deterministically in tests/artifacts/agentcert.json and the gate exiting nonzero on any failure.

The costcert gate of tests/costcert.mjs proves the shared accounting reconciles: it replays recorded runs and recomputes every cost line, verifies the token accounting per agent matches the step logs, that the shared cost accounting sums the agent totals, that the budget alerts fire at the configured thresholds, that the refunds on cancelled steps match the provider rules (the provider bills only the chunks that left the wire, so a cancelled step refunds the completion tokens that never streamed), that the model routing costs land on the right agent, that the exported cost report reconciles to the total, and that no cost event is missing from the audit trail — with the reconciliation report written to tests/artifacts/costcert.json and the gate exiting nonzero on any accounting mismatch. The certification entry gate runs agentcert and costcert together through the new validate:agents chain that joins the validate chain after validate:security, the verify workflow runs both gates beside the security gates, the workflowcheck permitted set gains them, and the certification artifacts join the release evidence bundle.

The dashdone completion lands the multi agent dashboard: the dashboardpage gains the multi agent overview panel with the topology status, the per agent status cards with live progress, the shared queue view with its lane filter, the message flow view between agents, the conflict and arbitration log panel, the cost per agent panel fed by the costcert totals, the escalation inbox with its human answer controls, the kill switch and the per agent pause controls, the timeline scrubber over the interleaved events, the aggregate report download, the read only rendering for observers without the run role, and the empty states that guide the first multi agent run — all served through the new multiagent view the background shapes from the live swarm state through the dashdone family module, and the agent registry snapshot exports the certified topology inventory of the six certified scenario families of docs/agentscenarios.md: the leader worker scrape, the planner executor critic, the parallel form fill, the monitoring swarm, the competing extraction, and the escalation and review scenarios, each with its topology diagram, its cost characteristics, its fake tab provider setup reference and its consent model.

The documentation surface completes the certification: docs/agentcert.md documents the suite and every scenario with its verified pool item, docs/agentscenarios.md describes the six certified topologies with the pool mapping of items 469 through 502, docs/dashdone.md documents the dashboard panels, docs/costcert.md explains the accounting verification method, docs/releasegates.md requires green agentcert and costcert runs, the roadmap progress line marks the multi agent certification complete, docs/todo.md records the certification results, the README notes the certified multi agent topologies, docs/05.agentalgorithms.md links the certified scenarios, docs/07.featureflowmatrix.md gains the coordination verification rows, docs/perfbudgets.md gains the coordination suite runtime budget, docs/configuration.md documents the fake clock mode for deterministic runs, and docs/referencecatalog.md records the certification artifact inventory. The test suite covers the certification chain: tests/agentcert.test.ts verifies the artifact covers every scenario (running the gate itself when a built tree carries no fresh artifact, so the bun and deno lanes that build before vitest verify it without gate ordering), tests/costcert.test.ts verifies the reconciliation invariants the same way, the protocol tests cover the coordination messages against the frozen schemas, the policy tests cover the per agent scope gates, the chromium smoke executes one coordination scenario end to end inside the live browser against the shipped bundles, and the full vitest suite passes with the certification chain green.

## 1.1.95

This release hardens the security surface for the release candidates: the pentest checklist of docs/pentest.md now runs end to end through tests/pentest.mjs — twenty one automated entries that exercise the real modules, from the consent gate blocking a sensitive kind on a fresh profile, the origin check refusing cross origin messages, the connectallow list dropping unknown external senders and the schemastrict rejection of malformed envelopes, through the escape hatch halting every native call, the kill switch stopping all agents at once, the revoked consent aborting the in flight step, the ratelimit buckets throttling command floods and the http bind refusing remote addresses by its documented localhost default, to the pairing handshake refusing unpaired clients, session tokens expiring on their timer, the secretvault never leaking into the audit trail, the loghash chain detecting tampering, the sandbox frame isolating untrusted renders, the quarantine holding downloads until a clean scan verdict, the cookie jar staying isolated per run, the phishguard warning before login flows on lookalike origins, the payment and delete gates refusing every non human resolution, and the purge and export passes removing and returning every stored record — with every executed entry and its outcome recorded deterministically in tests/artifacts/pentest.json and the gate exiting nonzero on any failure.

The content security audit lands with the strict policies: tests/cspaudit.mjs extracts every content security policy from the root manifest and both browser overlays, verifies no injected code path uses eval or remote code, that the pagebridge script stays the only injected file, that the sidepanel and popup load no remote resources, that every script, style and connect source stays local or consented, that the dashboard renders untrusted extracts inside the sandbox frame the manifest declares, and that no frozen policy carries a wildcard source; the root manifest gains the strict extension pages policy `script-src 'self'; object-src 'self'; frame-ancestors 'self'` the release candidates carry, the extension pages refuse framing by remote origins, and the inline event handlers stay absent from every extension page.

The permission diff gate proves the permission set never grew silently: tests/permdiff.mjs extracts the permission set of the manifest, compares it against the previous release artifact resolved from the git tag or the release commit, reports every added, removed and reordered permission, requires the written justification table of docs/01.extensionpermissions.md for every addition, blocks on any unjustified permission and writes tests/artifacts/permdiff.json — this release gains no permission, the diff reads clean, and the audit trail records the permission set hash of the release beside the permdiff history the transparency export carries for incident reviews.

The transparency page reaches completion: it lists every granted origin with its grant date, every permission with its consuming surface from the capability manifest coverage, every stored data kind with its location and its purge and export links, the active consent sessions with their expiry, and the audit trail integrity check result of the loghash chain — all rendered entirely offline with no external request. The hardening pass closes the remaining gaps: input masking covers every field the logs gained since the audit, the redaction pass covers the transparency page exports, the virus scanning hook gains the local signature check option, the quarantine exposes its contents only through the review flow, the escape hatch shows its visible confirmation banner, review mode pauses on new domains with an explanatory card, the safe defaults apply to every newly encountered site, the minimization pass trims extracts before storage, the purge action removes every trace of a run, the export action returns all stored data in one archive, the encrypted sync path gains its key rotation entry point, the mcp transport refuses plaintext remote connections, and the local stdio bridge verifies the client signature when the platform allows it.

The security review closes the release: docs/securityreview.md summarizes the pentest execution with every finding, its fix and its verification, records the cspaudit results per surface, the permdiff history since the 1.1.31 baseline and the residual risks with their owners; docs/pentest.md documents the checklist and its rerun instructions, docs/cspaudit.md explains the policy set and the audit rules, docs/transparency.md documents the page contents, docs/01.extensionpermissions.md gains the permdiff justification table, docs/releasegates.md requires green pentest, cspaudit and permdiff runs, SECURITY.md links the review, docs/securitytriage.md gains the release candidate triage flow, and the go decision checklist gains the security review entry. The gates join the tooling: the verify workflow runs the three security gates beside the api freeze, the package validate chain grows the validate security chain, the chromium smoke executes the pentest checklist end to end, the runtime policy accepts the transparency page surface, the extension validation verifies the transparency page bundle, and the full vitest suite passes with the security chain green.

## 1.1.94

This release folds every browser manifest into the one root manifest.json the operator directive names: the firefox overlay, the safari overlay and the vs code packaging overlay lived as three separate files under manifests/ beside the chromium source manifest — four hand maintained files each duplicating the release version the root manifest already carries. The single manifest design moves the firefox and the safari adaptation data under the `browsers` key of the root manifest and the vs code packaging data under the `vsix` key, the manifests/ directory leaves the tree, and no overlay declares a version of its own because the root manifest's version stays the single source the release synchronization stamps — a version drift between the overlays and the package is structurally impossible from this release on. The firefoxprep adapter strips the two metadata keys from every derived browser manifest before it ships, the shipped chromium extension copy of the manifest drops the browsers and vsix keys the other targets own, and the build, the verify workflow, the release workflow, the containerfile, the npm file list and the publishing pipeline tests all read the overlays from the one root manifest — one manifest speaks every webextension dialect and no correlated manifest file lives beside another.

## 1.1.93

This release closes the first bug the real consumer simulation of the test campaign exposed: a user installing the npm package and running the documented `devthink manifest` command inside the installed package hit a missing file crash, because the manifest deep checks of 1.1.91 began reading the seven capability manifest files under caps/ while the npm file allowlist never shipped them — the package carried manifest.json, manifests, web, dist and the docs, but the freeze contract the manifest command verifies needs the pinned capmanifests beside them. The npm files list now ships the caps directory with its seven surface manifests, the tarball size budget absorbs the few kilobytes, and the consumer simulation — the pack, the fresh /tmp project, the install, the esm import, the commonjs require, the cli describe and the cli manifest inside the installed package — runs end to end against the shipped artifact exactly the way a library user works.

## 1.1.92

This release is the first stabilization wave of the test campaign the operator directed before the roadmap continues: the suite grows by seven hundred torture tests across fifteen new files in tests/ — torture-run, torture-plan, torture-session, torture-swarm, torture-agent, torture-memory, torture-workflow, torture-tools, torture-llm, torture-http, torture-export, torture-environments, torture-commands, torture-data and the replay-verified extensions of the existing sandboxframe coverage — taking the full vitest suite from one thousand seven hundred and thirty to two thousand four hundred and thirty one tests. The campaign torture-tests every family with adversarial markup reassembly payloads, csv and markdown formula injection, prototype pollution keys, lookalike origins, homograph hosts, boundary values at every budget, window and quorum edge, malformed envelopes, forged tokens, replayed nonces, star-storm patterns that would backtrack catastrophically, unicode and control character payloads, million byte inputs and state machine abuse of terminal transitions.

Six library bugs the torture tests exposed close in this release. The sandbox render result acceptance documented that a replayed nonce refuses while the implementation carried no replay tracking at all: the sandboxrender type gains its answeredat marker, acceptrenderresult returns the updated renders with the accepted render closed, and a second message through the same nonce never passes again while tests/sandboxframe.test.ts threads the closed render through its refusal coverage. The fetch redirect handling leaked the request body onto the downgraded GET hop of a 301, 302 or 303: the hop now rebuilds its init without the body whenever the method went bodiless, so a secret POST payload never rides a redirect the contract downgraded. The json rpc posted frame intake accepted an empty batch array as a valid empty message set: an empty batch now refuses with the parse error the json rpc spec demands. The client ceiling enforcement never refused under a non finite configured maximum because two is never greater than NaN: a nonsensical ceiling now fails closed. The prefetch warming misplaced a duplicate granted url into the refused list — a duplicate warms once and stays allowed. The workflow editor template expansion accepted malformed nested parameters without validation: expandtemplate validates every parameter through the nested param normalizer and refuses the malformed ones loudly, matching the import side that always refused them.

The earlier hardening the campaign verified along the way lands in the same wave: the tab pattern matcher walks adversarial star storms through one linear token table with a dynamic programming pass instead of a compiled regular expression, the dataset interpolation only answers the row's own string values so inherited properties never leak object internals into a step payload, the plan origin profile tolerates the blank origin of a hostile plan file, the agent budget spend refuses negative and non finite amounts, the swarm consensus vote refuses a blank agent id, the tool idempotency lookup scopes its search by client so one client's key never replays another client's record, the sealed run state open guards against a null payload, and the heartbeat, budget pressure and timeout decisions survive non finite telemetry values.

## 1.1.91

This release freezes the external contracts before the release candidates: the audit of 1.1.90 proved the feature surface complete, so nothing new enters the library here — only versioned contracts, manifests and guarantees. protocolv2 pins the message schemas: the frozen message catalog of protocol.ts declares every message type with its family, its schema file, its envelope class and its carrier, ten schema files under docs/schemas (session, proposal, plan, observation, envelope, capability, audit, memory, progress and tool) freeze the wire shapes with the protocolv2 id and a frozen semantic version of their own, every message field carries a documented type with a plain language description, the response envelope covers the success, error and cancel outcomes with the stable error code table — parse, method, params, internal and consentrefused with the retry semantics of every code — the stdio and http framing rules join the written contract, the observation payload keeps its schemaversion field forward compatible with a reserved fields map for future additions, the plan schema documents the review surface without hard caps, the tool catalog entries carry per tool versions from this release on, and the action kind identifiers become immutable constants in types.ts with the option grammar of every kind frozen inside the plan schema.

The capability manifests describe every surface: caps/background.json, caps/pagebridge.json, caps/sidepanel.json, caps/popup.json, caps/cli.json, caps/library.json and caps/mcp.json each list the message types, the kinds and the permissions their surface speaks, pinned to the release version and the frozen protocol major, with the permission coverage map that ties every manifest permission to its consuming capability and the per tool versions of the mcp surface. the background serves the capmanifest of its surface on request through the new capmanifest message that also answers the highest shared protocol version of the negotiation, the cli prints the manifest of every surface through the new describe command, and the capmanifest comparison flags the capability drift between releases — every added or removed message, kind, permission and tool version answers as one named drift entry the drift gate refuses. the protocol major negotiation answers version two as the default for new clients, accepts version one messages with the deprecation notice of the window, and refuses every major above two until a future major bump with the supported range inside the refusal; schema validation runs on every incoming message before dispatch — strict mode for version two rejects unknown fields while version one tolerates them through the deprecation window — and library consumers pin the protocol version through the explicit pinnedprotocolversion import.

The deprecation policy defines what stability means until 2.0.0: the deprecation window opens at 1.1.91 and closes at 2.0.0, every deprecated field — the uppercase devthink global shim of the umd surface and the full package version string of the version one mcp capability exchange — carries its sunset release in docs/deprecation.md and logs exactly one warning per session inside the window, and the stability rules promise additive changes only inside protocolv2 with breaking changes demanding a new major protocol version by written rule. the new tests/apifreeze.mjs gate verifies the freeze on every release: it enumerates the frozen message catalog, verifies the envelope carriers, the protocol version constants, the tool catalog coverage, the observation schema forward compatibility, the response envelope outcomes, the cli, mcp, sidepanel, popup, pagebridge and library surfaces against the code they freeze, the permission coverage of the manifest, and hashes every frozen schema and contract list into tests/artifacts/apifreeze.json — exiting nonzero when a frozen hash changes without a version bump, reporting the surface size per message family and joining the validate chain and the verify workflow as a required check. the docs land beside the code: docs/apifreeze.md, docs/deprecation.md with its sunset list and the migration tooling pointer to 1.1.92, docs/stability.md with the compatibility promise from 1.1.91 to 2.0.0, docs/capmanifest.md with the manifest format and versioning, docs/poolcoverage.md with the protocol versioning items recorded as implemented, the protocol reference with every message and its schema link, the permission evidence with the capmanifest surface map, the architecture document with the frozen message boundaries, and the readme, the configuration, the reference catalog, the release gates and the roadmap updates. the full vitest suite passes with every frozen contract validated and the chromium smoke exercises the version negotiation end to end.

## 1.1.90

This release merges every correlated logic of the root into one module per category: the operator directive names the run family as the example — run history, run budget, run state, run resume, run replay, run parallel, the background run queue, the run timeline and the run resilience lifecycle all intern into run.ts — and the same consolidation applies to every file of the root, because the analysis of the whole tree found ninety four modules whose logics belong to twenty five categories that each carry between zero and one hundred correlated logics, so the repository now speaks one module per category instead of one module per half of a category.

The merged families follow the correlation map: flowlibrary, flowrun and the syncbridge intern into flow.ts; planlint and planreview intern into plan.ts; sessions and sessioninterface intern into session.ts; orchestration, taskqueue and the blackboard intern into swarm.ts; netwatch, socketbus and netcontrol intern into net.ts; servercontract, socketrelay, chatbridge, wsbridge and nativehost intern into bridge.ts; confirmgates and approvalgate intern into gates.ts; originpolicy, inboundguard, maskinputs, immutablelog, phishguard, secretvault and transparency intern into security.ts; jsonrpc, resourceexpose and promptexpose intern into serve.ts; media, vision and redactshots intern into capture.ts beside the capture base; surfaces, statusviews, pickerviews, tourviews, evidenceviews, datagrid, virtlist, siteprefs, quickactions and attentionfeed intern into views.ts; emulation and sandboxframe intern into environments.ts beside the environments base; platformadapter, runtimeadapters and platformtargets intern into runtime.ts; perfrecords, snapshotdelta, dombatch, stepmeter, resourceaware, batchscheduling and lazyload intern into perf.ts; browserpolyfills, firefoxprep, xpipack and safariskeleton intern into crossbrowser.ts; controlflow, trigger and workfloweditor intern into workflow.ts beside the engine base (the merge resolves the workflow and controlflow import cycle); modelroute and promptlibrary intern into llm.ts beside the llm base; toolcatalog and toolcalls intern into tools.ts; datacommand, pipelines and streamparse intern into data.ts; tabscommand, filescommand and navigation intern into commands.ts; exporttools, minimization and portability intern into export.ts; forensics and outputcompare intern into evidence.ts; artifactmanifest, sbom, vsixpack, mavenpack, nugetpack and containerpack intern into pack.ts; and cdpbus and profilers intern into debug.ts. Every family file organizes its sections hierarchically from the base and most important logic to the derived ones, with the standard jsdoc family header and one merged from marker per section, and every export of every source survives with the same name and semantics except the two collisions the merge resolved: the pipeline grid preview renames to pipelinegridpreview inside data.ts so the dataset grid preview keeps the gridpreview name, and the tool call retry hint renames to callretryhintof inside tools.ts so the session retry hint keeps the retryhintof name.

The dist bundles, the exports map and the release chain follow the families: the wsbridge and nativehost bundles merge into the one bridge bundle, the browserpolyfills, firefoxprep, xpipack and safariskeleton bundles merge into the one crossbrowser bundle, the vsixpack, mavenpack, nugetpack, containerpack, sbom and artifactmanifest bundles merge into the one pack bundle, and the runtime family carries the platform matrix build; the exports map replaces the wsbridge, sbom and artifactmanifest entries with the bridge, crossbrowser and pack entries, the declaration emit covers every family module, the npmgate, the nativesmoke, the containerfile, the verify workflow and the release workflow speak the family bundle names, and the publishing pipeline tests assert the family set. The four maven packages the single distribution already replaced — extension mcp, extension headless, extension cli and extension library — retire from the github packages registry through the dispatched package cleanup workflow, so io.github.wenathlan.extension stays the only maven coordinate. The index and the neutral entry collapse their star export lists from the ninety four module lines to the twenty five family lines, the explicit type reexports keep the public surface stable (the loopstep type stays the types module export the surface always carried), and the full test suite of one thousand seven hundred and seven tests passes over the merged tree with the imports repointed at the family modules.

## 1.1.89

This release clears every open code scanning finding of the 1.1.88 tree: the sanitizer of the sandbox frame rewrites as one linear character scan, and the two polynomial regular expressions leave the vsix marketplace check and the css selector tokenizer.

The stripscripts rewrite closes the five incomplete multi character sanitization findings: the replace chain over the whole markup (script elements, script tags, event handler attributes and script url schemes removed through global regular expressions inside a convergence loop) reads as incomplete sanitization to static analysis, because a pass over a reassembled payload like `<scr<script>ipt>` leaves a usable fragment behind from the analyzer view. The new scanner rebuilds the markup instead of removing fragments from it: a well formed tag keeps its name and its safe attributes with the script url schemes stripped from the values through plain index finds, every `on` event handler attribute drops, a script element drops with its whole content through the closing tag, a malformed tag whose body carries another open angle drops entirely, and no regular expression ever runs over the untrusted text — the output provably carries no `<script` sequence and no `on...=` attribute, because the scan either keeps a reconstructed tag or drops the whole construct.

The vsix marketplace check closes the polynomial redos finding: the vendor url scan replaces the nested quantifier pattern (`scheme`, then any run, then the download, installer or update alternation, then any run) with a linear url match followed by plain substring finds over each matched url, so no alternation rides inside a repetition and adversarial manifests cannot push the expression into backtracking. The css selector tokenizer closes the second polynomial redos finding: the combinator spacing collapses the whitespace runs first and pads the single combinator characters second, so the optional whitespace on both sides of the alternation never overlaps and a selector of thousands of spaces tokenizes in linear time.

## 1.1.88

This release consolidates the repository into the one design the operator directive names: every logical module, every runtime context and every packaging concern lives at the repository root, and every design artifact — the stylesheet, the surface markup, the sandbox frame, the dashboard and options pages, the site chatbridge surface, the capacitor configuration and the vercel configuration — lives inside the one web/index.html file, so a single design renders on the web, inside the extension, on android through the capacitor wrapper and on tv, and the static deploy of web/ reaches vercel, netlify, github pages or any plain static host unchanged.

The correlated module families merge into one module each: agentfleet, agentmailbox, agentreview, agentstream, agentwork, multiagent and coordination intern into agent.ts; clientauth, netauth and sharedauth intern into auth.ts; httpclient, httpserve, httpstream, relayserve and stdioserve intern into http.ts; gateway, webapi and apimap intern into gateway.ts; memorycare and selcache intern into memory.ts; mcpmode and mcpserver intern into mcp.ts; headlesslib interns into headless.ts; the terminal entry of cli/devthink.ts and the cli tools intern into cli.ts; and the twenty one page modules of the extension surface intern into page.ts beside the pagebridge content script entry. The companion recipe and the companion runtime intern into companion.mjs (the self stamping build branch replaces the separate build script), the container runner moves to container.mjs, the extension manifest moves to the root manifest.json, the native host template moves to the root nativehost.template.json, and the vsix of the previous release moves to the repository root — no variation of the same file lives beside another.

The layout split runs design against logic: web/index.html embeds the extension stylesheet, the site stylesheet, every surface template of the extension interface and the chatbridge wiring of the site surface behind a hash driven surface switcher, web/sitemanifest.json rides the site contract, and web/vercel.json with web/capacitor.config.json make the folder the deploy ready interface for the web and android channels; the build splits the embedded templates into the per-surface extension pages (popup, sidepanel, dashboard, options, transparency, sandbox and offscreen) with the stylesheet written beside them, so the extension zip and the deployed site render from one design. The maven distribution collapses into the single io.github.wenathlan.extension artifact: the root pom.xml carries the jar packaging with every consumption mode embedded as jar resources (the library core, the cli, the headless entry, the mcp server, the gateway and the http module) and the extension zip and the declarations zip attach with their classifiers beside the one jar, the four mavendist module poms leave the tree, and the maven channel publishes one coordinate instead of five.

The build, the packaging and the ci follow the layout: the extension surfaces build from the root entries into dist/extension, the chromium zip, the firefox xpi, the safari skeleton, the vsix and the site zip write into dist, the static site builds from the one design file with the hashed site manifest, the companion recipe stamps itself through companion.mjs --build, the container runner imports the relay state machine from the merged http module, the npm files list ships the manifest, the web folder, the companion recipe and the host template beside the dist bundles, the release notes speak the single maven artifact, the version sync stamps the manifest at the root and the design file, and the verify and release workflows run the single maven module, the dist artifact paths and the root manifest checks. Honest notes: the pagebridge content script stays its own module because the content script injection needs a self executing entry, the headless entry keeps the headless fixture helpers the cli and the headless family share, and the library index stamps the esm core explicitly so the merged entries that carry their own bundle stamps never leave a foreign stamp on the library surface.

## 1.1.87

This release multiplies the publishing channels around the buildable artifacts of 1.1.86: the nuget package grows from a bare extension zip into a full distribution (the cli, headless and mcp entries as content files, the umd and cjs bundles as content assets, the declaration files for ide integration, the framework targets matching the csproj profile, the project url, license expression and readme in the manifest, and the fixtures directory as sample content), the maven distribution grows from one descriptor into one module per consumption mode (the library core, the cli, the headless entry and the mcp server each ship as their own jar with the bundles embedded as resources inside it, the declarations zip attaches as a classifier artifact beside the extension zip, and the pom records the project metadata and license), and the container moves to a multi stage build whose builder stage runs the whole validation chain with the cli manifest and the headless smoke as build checks before the runtime stage copies the lean output onto the plain node base.

The runtime image exposes the static site, the socket relay and the mcp server: the relay speaks the servercontract for self hosting through the pure state machine of relayserve (the session create and join handshake, the pairing code exchange, the per frame token authentication with rotation, the event routing between the extension and the site members, and the idle sweep inside the operator chosen window), the site serves the hashed assets with their immutable cache headers, the mcp listener stays loopback until the operator widens the bind, and every bind, port and path is an environment choice — the image tags carry the version beside the stable channel alias with a pre suffix for prereleases, and the digest files pin the exact image hash. The vsixpack brings devthink into vs code as a pure zip-based vsix: the extension manifest at the archive root, the package manifest, the extension host, the webview page and the library esm build inside the extension folder; the chatbridge surface runs in a webview panel, the consent gates stay visible inside the panel before any socket frame crosses, the relay url stays the user configured value with an empty default, and the manifest declares no telemetry and no network default — no vendor marketplace url and no download url appears anywhere in the package, the operator installs it from the release asset with their own credentials.

The release workflow publishes a package for every mode in one chain: the channel jobs (npm, nuget, maven, container, vsix, firefox and site) each gate on the assemble job, every publish retries inside a bounded three attempt policy, the registry jobs and the github release require the release-approval environment protection, the digest job computes and publishes the container image digest, the sbom job emits a cyclonedx inventory over every release artifact, the attestation job creates the provenance attestations after every channel job through the workflow identity (no signing key material lives in the repository — everything rides the oidc token or repository secrets), and the releaseassets job emits the artifact manifest that lists the name, the byte size, the sha256 checksum and the publishing channels of every artifact. The github release gathers every artifact into a draft first, the verification step downloads every asset back and verifies the checksums, and only then the release publishes. The version sync step stamps the same number into package.json, the extension manifest, the pom, the csproj, the vsix manifest, the xpi overlay manifest, the safari overlay manifest and every maven module pom, the check mode verifies zero drift across every packaging file, and the release notes carry the per channel artifact sections that record every artifact of the release.

The npm tarball grows the fixtures, the declarations, the docs and every library bundle while the file allowlist keeps its size budget honest, the verify workflow runs the vsix package build, the nuget pack dry run, the maven pack dry run, the container image build with its smoke and the artifact manifest check against the built set, the npmgate allows the publishing pipeline bundles in the tarball, the workflowcheck covers the new jobs and gates, and the drift, checksum, sbom, rollback, tarball, channel section, marketplace metadata and packaging layout tests encode the whole contract on plain fixtures. The rollback procedure freezes the previous release artifact set through its immutable tag with the pinned checksums, the artifact retention keeps every published release, the stable channel aliases track the latest release, and the docs/19.distribution.md covers every channel and artifact with the nuget and maven package contents, the container image usage, the vsix installation and the artifact manifest format.

## 1.1.86

This release reaches every browser: the native bridge of 1.1.85 removed the chromium only assumption in transport, and 1.1.86 removes it in packaging. The apimap module records every webextension api the codebase touches, maps each to its chromium, firefox and safari equivalent, resolves the right call through a runtime browser probe the in memory cache holds for the run, and reports unmapped apis at build time so a new api without a row fails the build before it ships. The polyfill layer prefers the browser namespace when present and normalizes the callback and promise styles across browsers: the sidepanel polyfill opens a popup window when the sidepanel api is missing and preserves the review gate layout inside it, the scripting polyfill falls back to tabs execute script on older engines, the storage polyfill keeps session tokens under the same keys on every browser, the tabs and windows polyfills normalize query, create, update and bounds handling, the notifications and contextmenu polyfills normalize options and item creation, the clipboard, downloads and runtime messaging polyfills normalize envelopes and shapes, and the runtime polyfill normalizes geturl so the same reviewed resource path reaches every browser.

The firefox and safari packaging grow beside the chromium source: firefoxprep adapts the source manifest into a firefox overlay (writes the browser specific settings with the generated extension id, maps the action keys to the firefox equivalents, moves the service worker to an event page for the firefox mv3 background semantics, rewrites the optional permission names where they differ, keeps host permissions empty on every browser and splits the background bundle for the event page semantics while keeping the permission deny list in force across overlays), xpipack assembles the firefox build into a zip ready for signing with the browser specific manifest and the hashed assets and a name that carries the release version, and the addons linter passes the output with zero errors; safariskeleton generates the xcode project wrapper that embeds the chromium build as the safari web extension payload, declares the app entitlements for the extension distribution and includes a minimal app shell that opens the extension, and the safari build renders the sidepanel surface as a popover equivalent. The build keeps one source manifest with per browser overlays (the csp overlay records the per browser content security policy and the web accessible resources overlay maps to the firefox pattern syntax), the cross browser build keeps the kind catalog, the policy gates, the observation schema and the audit trail format identical on every browser, and the bridge pairing works from any browser build to the same relay.

The cross browser feature flags gate surfaces a browser cannot host and default to the intersection set across browsers so a feature surface a single browser lacks stays off everywhere by default; the native transport stays chromium first and reports unsupported elsewhere, the extension id per browser feeds the servercontract handshake, the gateway adapters and the mcpmode run unchanged on every browser through the fetch seam, the unsupported api calls surface as structured errors with retry hints and the version sync stamps the same version into every browser manifest. The tests/build.mjs gains the firefox target that emits the adapted bundle and the safari target that embeds the chromium payload, with per browser size budgets, the no underscore bundle naming and the checksum step that records digests for the firefox and safari artifacts. The verify workflow runs the addons linter over the xpipack output and installs firefox for a load smoke on the xpipack build, the release workflow attaches the xpi and the safari skeleton as release assets beside the existing artifacts, the workflowcheck covers the firefox and safari jobs, the npmgate check allows the cross browser build scripts in the tarball, the containerfile smoke runs the firefox prep step offline, the package.json files list includes the browser overlay manifests and the docs/18.browsercoverage.md covers the chromium, firefox and safari builds with the apimap table, the per browser permission differences, the sidepanel fallback behavior and the signing and notarization path per browser.

## 1.1.85

This release reaches the desktop: the native host bridge adds the optional native messaging transport the mcp server of 1.1.84 left mined but closed. The manifest declares the native messaging permission in the optional set only, the deep manifest checks of the cli manifest command allow it there and refuse it in the required set (a required native messaging permission installs a host grant the user never reviewed), and the native transport adds no required manifest permission and no host permission — the bridge ships deny by default and nothing native runs until the user installs it. The nativehost module at the repo root carries the whole pure surface: the host manifest template with its generated extension id placeholder (the installer fills the extension id of the installed build), the installer that writes the host manifest into the user profile directory and refuses a system wide install without the explicit flag, the uninstaller that removes the host manifest and its preferences, the runtime port with its attach, crash, reattach and detach states, the companion handshake that reports the build and protocol versions with the one major version upgrade window, the capability negotiation that lists the host features and enumerates the native surfaces on connect, the correlation ids one run stamps on every frame, the heartbeat frames that detect the host process liveness, the origin and session checks that validate every incoming native frame, the secret exclusion that keeps key vault material out of every frame, the structured errors with their retry hints, the per session rate cap accounting, the native call records of the audit trail and the diagnostics report of the port state, the versions and the last errors.

The wsbridge translates the native port to a localhost websocket server: the companion process binds a random free port on the loopback and refuses every address outside localhost (a connection from another machine refuses at the bind itself), mints a per session token, authenticates every frame against it, advertises the port and the token to the extension over the native port (the only place the raw token ever appears — the session records, the logs and the audit entries keep its sha-256 hash), expires a quiet session after the user configured idle window, holds exactly one extension connection at a time, and reuses the servercontract envelopes of the 1.1.82 family so the native frames carry the same negotiated version, operation id and stream multiplexing the relay family speaks. The companionbin recipe lives in the companion directory as source plus a build command: main.mjs speaks length prefixed json over stdin and stdout (the chromium native messaging wire), the handshake answers with the build and protocol versions and the surfaces, the os dialog and notification surfaces wait behind their consent grants (a desktop surface never opens from a class grant alone, and the sensitive class routes through the human approval gate), the log rotates with size bounds from the launch environment, and the build recipe uses plain node with no native compiler — the companion never ships as a binary blob, and the packaging build asserts the recipe runs.

The consent line holds everywhere: the install consent gate explains the scope before any host registration (the companion process the manifest launches, the profile directory it writes into and the extension origins it allows), the transport consent gate asks per call class so read, interaction and sensitive stay separate grants, the surface consents stay per surface, the kill switch stops the host instantly and the escape hatch key stops every native call in one press, the per session rate cap counts the calls inside the user configured window, the audit trail records every native call with its correlation id, surface, call class and outcome (never a payload), the native transport events stream to subscribed mcp clients as native/call notifications, and the install state persists across service worker restarts with the installer version recorded for the upgrade path. The graceful degradation keeps runs alive when the host sits absent, outdated or crashed — the engine turns the transport off and every step runs inside the browser — and the headless mode keeps the transport disabled unless the user configured a host.

The build and the ci join: the build emits the wsbridge bundle as dist/wsbridge.js and the companion script bundle as dist/companion.js (the plain node recipe stamps the package version over the source build marker), the bundle size accounting covers both, the naming check keeps them free of underscored identifiers, the declaration emit covers the nativehost and wsbridge modules, the package.json files list includes the companion recipe and the host manifest template, the cli gains the native command (install behind the consent flag, uninstall and diagnostics), the verify workflow runs the native bridge smoke against a fake host process, installs the host manifest for an isolated chromium profile, asserts the native messaging permission stays absent from the required set and removes the manifest after the smoke, the containerfile smoke runs the wsbridge against the fake host, the release workflow attaches the host manifest template as a release asset, the npmgate check allows the new bundles in the tarball, and the workflowcheck covers the native smoke steps. The docs grow with docs/17.nativebridge.md (the install, consent and diagnostics walkthrough, the wsbridge protocol and token model, the companionbin build recipe), the optional native messaging posture of the permission doc, the native transport settings and the kill switch of the configuration page, the native bridge section with the install walkthrough of the readme, the native transport threat model of the security triage doc, the native module layout of the architecture doc, the native surface rows of the feature flow matrix, the native install walkthrough of the examples, the host manifest template asset of the artifact inventory, the native bundle names of the package naming doc, the native smoke job of the release pipeline doc, the add a native surface guide of the contribution page, the native event stream reference of the mcp server doc and the native frame envelope reference of the servercontract doc. The vitest suite grows thirty cases in `tests/nativebridge.test.ts`: the manifest template and the installer and uninstaller of a temp profile behind the consent, the per class and per surface consent gates, the human approval of the sensitive calls, the headless posture, the handshake against the spawned fake host process, the version negotiation and the mismatch of another major version, the crash and reattach degradation, the heartbeat liveness, the frame checks and the correlation ids, the secret exclusion and the redaction, the structured errors, the audit recording with class and outcome, the rate caps, the kill switch and the escape hatch, the surface enumeration and the surface results, the diagnostics report, the wsbridge bind refusals outside localhost, the token authentication and the idle expiry, the one extension connection rule, the envelope round trip and the advertisement, and the fake host surface calls with their consent refusals. Honest notes: the extension never writes the user profile itself — the manifest write runs through the reviewed cli installer the options page names, because the service worker holds no filesystem; the companion surfaces delegate their execution to the user configured presenter and answer a graceful unavailable result without one, because no desktop tool is ever hardcoded; the wsbridge token rides the native port advertisement and nothing else, the escape hatch and the kill switch share one stop path, the idle window, the heartbeat interval and the rate cap stay user choices with no code default, and no native path — attach, call, surface, event or diagnostics — ever bypasses a review.

## 1.1.84

This release lets any agent client call devthink: the mcpmode entry point runs the engine as a model context protocol server with the toolcatalog, resourceexpose and promptexpose surfaces over the stdioserve and httpserve transports, and the cli gains the serve command that starts it. The json rpc framing layer encodes and decodes every message with structured errors and retry hints; the toolcatalog maps the action kind catalog to mcp tools with json schema inputs for every tool, the domain namespaces (browser, workflow, memory, system), a version on every tool definition, the consent requirement and risk class in the metadata, and the descriptions in the openapi style field layout — the browser domain exposes the snapshot, extract, readtext, readtable, readlinks, a11ytree, observe, tablist and windowlist read tools beside the gated interaction and sensitive tools, the plan proposal tool carries the full grammar, the review gate tool waits for the human approval, and the tab, window, session and memory tools join the catalog.

The transports hold the consent line: the stdioserve transport speaks json rpc over stdin and stdout with newline delimited frames for the local clients the user launches, the httpserve transport speaks streamable http on a localhost bind by default (tls when the user provides a certificate, and the auth handshake of the servercontract pairing family for any non localhost connection), and both transports can run at the same time on separate ports. The sampling callbacks route the generation requests back into the client model, the tool calls stream their partial results as they arrive, the long calls emit progress notifications, the in flight calls cancel on demand, the idempotency keys deduplicate the repeated calls so a retried request never double applies its effect, the batch execution runs several calls in one request, the dry run mode executes without side effects, and the tool mocks let the tests exercise the whole catalog without a browser. The multiple concurrent clients hold isolated sessions through the client bindings, the client allowlist restricts which clients may connect, the rate limiting caps the requests per client, and the session tokens pair a client with one extension session.

The consent stays in the loop everywhere: the sensitive tools block until the human approval gate answers (the gate renders in the sidepanel with the caller and its intent), the consent requirements refuse execution when the grant is missing, every tool call writes an audit entry with the caller, the tool and the outcome, and the mcpmode shares the policy and the kind catalog with the extension engine (a tool the current grants do not cover never exposes, and the server degrades to read only tools when no origin grant exists). The tool results return the same structured details as the sidepanel steps, the server events stream the plan progress to the subscribed clients, the mcpmode reports the servercontract version alongside the mcp version, the shutdown drains the in flight calls before the exit, the health resource reports the version and the uptime, and the client metadata records the name and version for the audit trail while the event streams reuse the servercontract envelopes. The resourceexpose surface publishes the page state, the plan, the audit trail and the session record as mcp resources with the subscription support and the change notifications, and the promptexpose surface publishes the prompt template library with the walkthrough prompts for the common tasks.

The build and the ci join: the build emits the mcp server bundle as dist/mcp.js with its minified variant, its sourcemaps and its declaration file (the declaration emit covers every new module — mcp, mcpmode, jsonrpc, toolcatalog, resourceexpose, promptexpose, stdioserve and httpserve), the package.json exports map gains the mcp entry and the files list includes the bundle, the verify workflow runs an mcp client script against the stdioserve transport in ci and another against the httpserve transport on localhost, the containerfile smoke starts mcpmode and lists the tools, the bundle size accounting covers the mcp bundle, the naming check keeps it free of underscored identifiers, and the npmgate check allows it in the tarball. The docs grow with the server specification of docs/16.mcpserver.md (the server, the transports and the catalog with every exposed tool's consent requirement, every resource and prompt, and the client configuration for the common mcp hosts), the serve command flags of the configuration page, the mcp quick start of the readme, the no new manifest permissions note of the permission doc, the approval gate flow for the remote callers of the algorithms doc, the remote caller threat model of the security model doc, the mcp rows of the feature flow matrix, the mcp client script and the toolcatalog walkthrough of the examples, the mcp bundle name of the package naming doc, the mcp ci checks of the release pipeline doc, the add a tool guide of the contribution page and the mcp event envelope reference of the servercontract doc. The vitest suite grows twenty-four cases in `tests/mcpserver.test.ts`: the json rpc framing accept and reject cases, every kind mapping to a schema valid tool with the consent metadata matching policy, the resource subscriptions with the change notifications, the prompt template listing and rendering, the stdioserve drive through a spawned process, the httpserve localhost binds with the non local refusal, the auth handshake token exchange, the approval gate blocking the sensitive tools until the human answers, the audit recording of the caller, tool and outcome, the rate limit and allowlist caps, the idempotency deduplication, the batch and cancellation lifecycle, the concurrent client session isolation and the mock tool runs of the full catalog. Honest notes: the serve flags, the allowlist, the rate caps and the drain window stay user choices with no engine default, the sensitive tools never answer on a timeout or in a batch (the human approval is the only path), the degraded read only mode ships as the explicit posture when no origin grant exists, the tool mocks exist for tests only, the mcp bundle joins the size accounting beside the cli and headless targets, and no mcp path — list, call, stream, batch, cancel, subscribe or approve — ever bypasses a review.

## 1.1.83

This release makes the agent reachable from any model provider: the gateway module defines the provider adapter interface with one request, stream and cancel contract shared by every adapter, and the four adapters speak their wire formats — the openaicompat adapter speaks the chat completions api shape with any compatible endpoint the user configures and streams the response deltas as they arrive, the anthropicgateway adapter speaks the messages api shape with streamed content blocks and the system prompts mapped to the provider format, the geminigateway adapter speaks the generate content api shape with streamed candidate parts and the tool schemas mapped to the function declarations format, and the ollamalocal adapter speaks to a localhost endpoint that defaults to the local machine and never to a cloud url and lists the locally installed models. The dispatch loop behind the shared contract runs the consent and base url gates first, races the timeout of every attempt, retries the transient failures under the jittered backoff, honors the retry-after header of the 429 answer with its announced window, maps the 401 and 403 answers to the unauthorized error the vault rotation answers, stops before the dispatch and between the attempts when the cancel state fires, and every failure answers the structured gateway error with its retry hint.

Nothing is hardcoded: no remote endpoint, no model name and no key ever leaves the user configuration. The baseurlconfig validates the scheme, host and path shape before saving — a query or a fragment refuses, a relative path segment refuses (the raw url checks before the url constructor normalizes it away), the remote providers must speak https, and the ollamalocal adapter accepts the localhost hosts only — while every remote default stays empty (the ollamalocal adapter alone defaults to the localhost machine). The keys live in the keyvault: the storeproviderkey seam writes the key behind its storage id with the consent stamp, the resolveproviderkey seam resolves the material at the last possible moment before the request leaves, the revokeproviderkey seam drops it on demand, the keyexportcheck refuses any export that carries a key shape, the requests mask before any log (the authorization header and the key query parameter of the gemini shape mask to their label), and the api key literal scan of the built bundles enforces that no key shape ever ships inside the dist artifacts. The hardcoded provider url scan of the shipped sources enforces the same posture for the endpoints — no provider endpoint literal exists anywhere in the shipped code.

The discovery and the advertisement join the vocabulary: modellist discovers what a provider offers (the cache window the user configured decides whether the cached list still serves, a fresh fetch rides the model list endpoint of the wire format, the discovered models annotate with their context and modality hints when the provider offers them, and a failed fetch keeps the cache untouched), capabilityad advertises the tool catalog in return (the tools serialize into the provider specific schema — the function schema of the chat completions shape, the input schema of the messages shape, the function declarations of the generate content shape or the function schema of the local runtime — every tool declares its consent requirement from its metadata, and the plan review gate rides the required capabilities because a model answer never executes a step the human review did not approve). The resolvegatewayroute resolution maps each task kind onto its provider and model through the user routing table, a remote provider the consent or enable gates refuse falls back to the user configured fallback pair, and when the remote calls are not allowed at all the resolution falls back to the local provider so the task stays on the machine.

The budget tracking and the guardrails hold every parsed response: the gateway calls pass the same costbudget gate the llm family already runs (the usage records carry the request id for the correlation across the run, the per session and per run totals, the cost answers the user configured price per million tokens, and the local marker stamps the calls that never left the machine), the budget warning reports the token and cost ratios before the halt, the cost estimates project the configured prices over the recorded usage, and the guardrails wrap the parse — the gatewayguard caps the parse attempts with its retry prompt, the guardretryprompt names exactly what the retry asks, and a response that never parses answers the structured gateway error instead of leaking through. The gateway composes with the llm provider model instead of duplicating it (the three remote adapters speak through the same request shaping, answer parsing and stream parsing the llm module owns), the background routes the gateway calls through the existing llm task machinery, the options page configures the providers with the consent gate before the first remote call, and the streamed tokens render incrementally through the cursor batches of the sidepanel chat. The vitest suite grows nineteen cases in `tests/gateway.test.ts`: the wire request shaping of every adapter with its key placement and message envelope, the base url joining with the per provider path prefix, the recorded stream bodies parsing into ordered tokens with the done marker, the incremental cursor rendering, the tool catalog serialization with the consent metadata, the baseurlconfig validation with the empty default posture, the consent gate blocking the disabled, unconsented and unconfigured providers while the local runtime needs no remote consent, the timeout race with the transient retries, the jittered backoff and the retry-after honoring, the vault key seams with the masking and the export refusal, the routing table with the fallback pairs and the local fallback, the usage records with the budget gate, the guardrails, the fixture server e2e that serves the recorded shapes over localhost http for the call, the stream and the model list, and the two posture scans of the shipped sources and the built bundles. Honest notes: the endpoint, the model, the key, the timeout, the retry count, the backoff base, the jitter window and the cache window stay user choices with no engine default (the ollamalocal localhost default is the contract's one explicit exception), the keys resolve at the last possible moment and mask in every log, the local calls stamp their local marker and never leave the machine, the gemini tool catalog wraps its declarations in the single Tool object the provider's canonical shape expects, the fixture server and the fixture bodies exist for tests only, and no gateway path — configure, consent, route, call, stream, retry, cancel or parse — ever bypasses a review or leaks a key.

## 1.1.82

This release connects the library to the open web: the servercontract module defines the message envelope spoken between the static devthink.pro site and the extension (a versioned envelope with capability negotiation, the sessioncreate, sessionjoin, eventpost and eventstream operations, the chat, plan proposal, plan review and progress event types, the schema validation rejections and one stable operation id per message for correlation), the socketrelay client connects to the user configured relay url over wss with an exponential backoff reconnect, the stream multiplexing of chat, review and progress over one socket and the frame authentication of every frame with the sharedauth session token, and the sharedauth module mints the pairing codes inside the extension options with an expiry countdown, exchanges each code exactly once per origin for a session token, rotates the token on every reconnect, stores the tokens scoped to the relay origin and revokes all sessions with one click. No platform functions are involved anywhere, and the relay server url is always a user setting, never a hardcoded default: the serverurl setting stores the relay url in storage.local with no default value, an empty value disables the bridge completely, any wss url the user chooses works without vendor assumptions after the scheme, host and port shape validate, and the extension ships no hardcoded relay url or vendor endpoint anywhere — the source scan test enforces it.

The chatbridge conversation surface never executes actions: the static site widget renders the conversation and the proposed plans as review cards, returns the review decisions to the extension review gate, and the extension stays the only executor — the sensitive steps approve only through the extension approval flow. The staticdeploy directory holds the devthink.pro static site assets that build to hashed assets with an immutable cache header configuration, the config targets a plain static host with zero server functions (no edge functions, no redirect rules and no vendor runtime), the site works fully from static assets when opened from a local file or any static host, the site manifest declares the servercontract version it speaks, and the site asks the visitor for the relay url before connecting and stores it in the browser localstorage.

The security posture holds the widened boundary. The origin checks validate the sender of every incoming extension message while the external connect allowlist restricts which pages may talk to the extension, the rate limiting caps the bridge messages per session per second, the audit trail records every bridge event with its session id and operation, the data minimization sends only plan text and statuses over the bridge (page content never crosses without the explicit consent flag, and the held keys refuse loudly), the site and the bridge collect no telemetry by default, the bridge kill switch disables the socket and the pairing instantly, and the popup bridge status icon shows the connected, paired and offline states with the queued frame count. The offline queue buffers the review requests while the socket is down and replays them with the operation id deduplication on reconnect, the heartbeat frames keep the socket alive during long runs under the user interval, the relay sessions expire after the configurable idle window, the relay allows one extension and one site member per session, and the session tokens never appear in urls or logs. The site and the extension negotiate the features through the servercontract handshake, the bridge consent gate asks the user before the first socket connection, and the pairing walkthrough ships in the examples.

The build and the verification grow beside the site: tests/build.mjs gains the staticdeploy build step that emits the site to dist/site with hashed file names, the verify workflow builds the site, asserts it contains only static file types, runs the bridge e2e test against the testrelay on localhost and keeps the static site scan that refuses any serverless function file in the repository, the release workflow packages the site as the devthink-site.zip static asset published beside the extension artifacts, the package.json exports map stays free of site entries (the site ships as its own artifact), and the testrelay helper implements the servercontract for tests only — a minimal frame-level websocket server over node:net that binds to localhost with a random free port, speaks the handshake and the text frame codec directly with no ws dependency, and serves the sessioncreate and sessionjoin operations with the pairing code exchange and the token rotation for the vitest suite (the containerfile serves the static site for local bridge testing). The docs grow with the servercontract specification of docs/14 (every envelope and operation with wire examples and the relay expectations of any static host plus open socket deployment), the serverurl setting and the pairing flow of the configuration page, the chatbridge flow with the pairing walkthrough of the readme, the bridge module layout of the architecture doc, the bridge threat model of the security model doc, the site zip artifact name of the package naming doc, the site artifact publication of the release pipeline doc, the site zip rows of the artifact transport matrix, the static site artifact of the artifact inventory, the bridge pairing walkthrough of the examples, the privacy note that the relay sees metadata only, the run the site locally guide of the contribution page, the no new host permissions note of the permission doc and the bridge review flow of the agent algorithms doc. The vitest suite grows fifteen cases in `tests/bridge.test.ts`: the envelope accept and reject cases per operation, the connect, reconnect and backoff behavior with the frame authentication, the sharedauth pairing, rotation and revocation, the chatbridge e2e against the testrelay that pairs the site with the extension, runs the chat and plan review round trip, rotates the token on reconnect and refuses the reused pairing code, the consent gate that blocks the first connection without approval, the audit event kinds, the per session rate caps, the offline queue buffering with the replay deduplication, the static site scan that asserts no function directories exist in the site output, the hardcoded url scan of the source tree, the data minimization that asserts no page content in the bridge frames by default, the heartbeat and idle expiry of the session lifecycle, the origin check rejections of unpaired senders and the popup bridge states. Honest notes: the relay url, the idle window, the heartbeat interval, the rate cap and window, the pairing lifetime and the page content consent stay user choices with no engine default, the pairing code redeems exactly once and its reuse refuses, the relay sees metadata only, the site bundle carries its own manifest and not the library banner (the stamp tests skip the site assets), the testrelay exists for tests only and the production relay is always the user configured url, and no bridge path — connect, pair, authenticate, post, review, replay or revoke — ever bypasses a review.

## 1.1.81

This release makes every consumption mode of the library first class: the cjs build joins the esm build with the same named exports wrapped behind a stable getter object, the umd build exposes the `window.devthink` global with the full public surface and the consent gates intact inside the browser bundle, the declaration files ship one per public module with the doc comments and one example per export, and the neutral target keeps every platform access behind one injected adapter seam so the same consent-first library loads from any host. The platform adapter contract carries every primitive the library touches — the storage adapter the memory module takes instead of importing one, the clock adapter the progress module takes instead of creating one, the logger and the fetch adapters of the transport seams — with the node default adapters binding to the node apis for the node build, the browser default adapters binding to the browser apis for the browser build, and the deno adapter reading its configuration through the deno runtime; the policy and protocol modules keep zero platform dependencies, and the shared state module avoids the dual package hazard between the esm and cjs modes of one process.

The runtimes join as verified matrix lanes: bunruntime runs the full library through the bun interpreter and joins the engines field of package.json, denoruntime runs the library through deno with npm specifiers behind a deno.json file declaring the compatibility map, and the deno adapter reads the configuration through the deno runtime permissions. The package.json exports map grows the import, require, types, default and browser conditions for the root entry (the browser condition selects the neutral target), the per-module entries for policy, protocol, memory and progress, and the cli and headless entries beside them; the sideEffects false field keeps tree shaking whole, the files list grows the cjs, umd and declaration files, and the publishconfig pins the registry provenance settings. Every bundle embeds the version stamp from package.json and the license banner, every target emits its sourcemap beside a minified and an unminified variant, the `bundlestamp()` export reports the version, the mode and the target of the running bundle, the public api surface freeze lists every export of every mode, and the deprecation shim keeps the old root import working with a notice.

The build and the verification hold the line: the build orchestrator emits the esm, cjs, umd, neutral, per-module, cli, headless and runtime targets (node.cjs, bun.js, deno.js) with a checksums file for every dist target, the tsconfig gains strict declaration emit settings, the verify workflow runs the build matrix under node, bun and deno (a require smoke against dist/index.cjs, an import smoke against dist/index.js, a global smoke against dist/devthink.umd.js, a deno check over the deno entry and the vitest suite once under bun), the release workflow attaches the umd bundle and the declaration bundle as release assets, the containerfile verifies the cjs entry with a require call, the npmgate check allows the cjs, umd and declaration files in the tarball, the tarball content check asserts every mode file ships, and the bundle size budget asserts per target limits so an oversized bundle fails the build before it ships (index 1800000b, indexcjs 1900000b, neutral 1800000b, umd 1900000b, node 1900000b, bun 1800000b, deno 1800000b, policy 600000b, protocol 380000b, memory 330000b, progress 60000b, cli 600000b, headless 700000b).

The vitest suite grows the mode suites in `tests/librarymodes.test.ts` and the new `tests/platformtargets.test.ts`: the api surface snapshot compares the exports of every mode, the interop test imports the library from both esm and cjs in one process and asserts the shared adapter registry stays consistent across both modes, the umd test asserts the global object exposes every public export, the node require smoke runs in the validate chain, the adapter tests cover the node, browser and deno default adapters, the exports resolution test asserts every package.json condition resolves, the version stamp test asserts every bundle reports the same version, the deprecation shim test asserts the old import path still works, the bundle size tests enforce the per target budgets, the naming check asserts no underscored identifiers in any bundle, the sourcemap tests assert every target emits valid maps, the minified variant tests assert behavior parity with the unminified build, the fixtures loader tests run under every runtime adapter, the policy and protocol tests assert no platform imports leak into the modules, the engines field test asserts the bun and node ranges stay in sync with the ci, the deno.json test asserts the compatibility map matches package.json, and the checksums test asserts the build emits hashes for every target. The docs grow with the import examples of the readme for esm, cjs, umd and script tag modes beside the bun and deno quick starts, the dist file names of every mode in the package naming doc, the adapter seam and neutral target of the architecture doc, the runtime specific configuration discovery of the configuration page, the multi runtime matrix of the release pipeline doc, the build target guide of the contribution page, and one runnable example per consumption mode in docs/examples (cjs.js, bun.ts, deno.ts and umd.html). Honest notes: the deno binary does not run inside this repository's own container — the deno entry, the deno.json compatibility map, the deno adapter and its tests ship with the pure logic verified in the suite while the deno check lane runs in the ci image the verify workflow installs, the bundle size budgets are build-time engineering bounds and not user runtime choices, the minified variants build beside the unminified ones with the parity asserted by the suite, and no mode — esm, cjs, umd, neutral, node, bun or deno — ever bypasses a review or leaks a platform import into the policy or protocol modules.

## 1.1.80

This release turns the cli into a complete operator surface beside the extension: deep manifest checks, the planlint command, the runworkflow command, the exportdata command and the headlessmode library runtime let users lint, run, export and replay without opening the browser ui, and every command reuses the same policy, protocol, memory and progress modules as the extension so the consent gates hold everywhere. The manifest command deepens into the full review: every manifest key verifies against the runtime policy allowlist (a key outside the list is a review miss, never a silent pass), every permission reports its source file and line in the form editors consume, the content security policy script hashes verify against the bundled script bytes through the digest seam (an unsafe-inline, unsafe-eval or wildcard source refuses, and a declared hash that pins no shipped file refuses), the web accessible resources verify against the reviewed resource set, a permission that declares in both the required and the optional sets refuses because one permission declares exactly once, the minimum chrome version checks against the capability report of the declared apis (a browser below the floor installs an extension whose apis miss), and every declared icon verifies its file presence and its png dimensions against its size key.

The planlint command runs the static validation of saved plan files: every step carries a reviewed action kind from the shared kind catalog (a forbidden kind refuses the plan before any run starts and the command exits nonzero), every selector verifies against the selector grammar shared with policy (a target reference parses through the same target reference grammar the extension runs), steps whose options payload misses the required fields for their kind flag exactly the fields the executor enforces at run time, steps whose target origin sits outside the consent allowlist flag the same grant the extension demands, and a risk summary per plan reports the counts by risk class (read, interaction, sensitive) so the review reads the plan risk shape at a glance; findings print in a stable line format consumable by editors, a plan path argument or the default plan location from configuration feeds the command, and planlint shares the kind catalog with policy instead of keeping a copy.

The runworkflow command executes saved workflows from the terminal: the workflow document parses under schemastrict (unknown fields refuse with the path that names them, the origins must be granted HTTPS origins), the document composes through the same engine the extension runs so the terminal replay and the browser run grade one workflow identically, progress events stream to the terminal as each step completes, the review gate pauses for approval before sensitive steps, a sealed audit trail file (one json line per run log entry under a sealed header) writes beside the workflow after each run, the dry run mode evaluates every step with no browser mutation, execution resumes from a checkpoint id, and the structured outcome summary reports the state, the per step durations, the checkpoint and the exit class the terminal maps onto its documented exit code (`0` ok, `1` consent refused, `2` step failed, `3` schema error, `4` unsupported, `5` cancelled — an unknown class refuses as a schema error because the mapping itself is contract). The exportdata command serves the session, audit and extraction data: the session history writes as json, the audit trail as json lines, the extracted table data as csv or markdown, all through the shared export serializers of the extension export menu (the mask verdicts honor in every format), the from and to flags select the time window, the output goes to stdout when no path is given, and the secret store material — a vault marker or an unmasked secret shaped value — refuses the export in full because the vault never ships through an export.

The headlessmode joins as a library runtime without a browser extension: `openheadlesssession` and `openlibraryrun` run the plan engine against recorded page state fixtures, the read only vocabulary with a recorded projection (observe, readtext, readforms, inspect, a11ytree, countelements) executes against the observation of the live snapshot schema, every other kind reports unsupported with the reason a fixture cannot satisfy it (an interaction or sensitive kind needs a live tab), the fixtures load from the directory named in configuration, the fixture scoped consent gates keep the same review the extension keeps, and the outcomes record through the same progress model the live runs record so a headless replay renders on the progress surfaces a live run renders on; the library entry point accepts a plan, a state source and a policy and returns a run handle with progress, pause and cancel. The build emits the expanded cli bundle and the headless library entry as its own dist target under size accounting (the cli and headless budgets fail the build before they ship), the naming check keeps every bundle free of underscored identifiers, package.json exports map gains the headless entry point and the files list includes the example fixtures directory, the cli smoke step joins the validate script chain, and the verify workflow runs planlint over every example plan in docs/examples and runworkflow in dry run mode over the example workflows while the release workflow includes the fixtures directory in the npm tarball. The docs grow with the examples directory (sample plans, workflows and fixtures with the fixture file format readme), the cli section of the readme with the exit code table, the configuration page with every global flag and exit code, the manifest check rules of the permission doc, the dist target names of the package naming doc, the cli smoke step of the release pipeline doc, the contribution guide section on adding a new cli command and the library entry point seam of the architecture doc. The vitest suite grows six cases in `tests/clitools.test.ts` covering the deep manifest checks (allowlist, permission sources, csp hash verification, reviewed resources, duplicate permissions, the capability floor and the icon dimensions), the planlint accept and reject cases with the risk summary counts, the runworkflow document parsing with the exit code mapping and the audit trail lines, the exportdata windows with the four formats and the secret store refusal, the headless fixture replay with the consent gates and the unsupported kind reporting, and the bundle size accounting. Honest notes: the bundle size budgets are build-time engineering bounds (the cli and headless dist targets) and not user runtime choices, the headless projections cover the read only vocabulary a recorded page state can satisfy while every other kind reports unsupported instead of pretending, the exportdata stdout mode writes exactly what the file mode writes, the containerfile runs the manifest command as an install sanity check and one fixture through headlessmode as a container smoke step, and no cli path — manifest, planlint, runworkflow, exportdata or headless — ever bypasses a review or emits secret store material.

## 1.1.79

This release minimizes the data footprint: page data stays local first with the identity fields stripped unless the review listed them, telemetry stays off by default and by construction, sync turns on per data class behind an opt in with every payload encrypted before any transport, purge and export answer on request, cookie jars isolate every task run, artifacts clean up after their run and downloads wait in quarantine until the scanner verdict releases or deletes them, all inside the new `minimization` module that extends the reviewed families instead of duplicating them — the cookie entries ride the cookierecord shapes the cookie control family already writes, the quarantine verdicts reuse the scanverdict grammar and the quarantineentry record of the security family with its new lifecycle status, the exportall provenance composes the provlog entries of the 1.1.75 pipeline family, and the purge receipts answer the audit trail the immutable log family already seals.

The local first arithmetic keeps the device between the page and every export. `localfirst` processes every extraction before anything leaves: the extractapi replay executor runs its mapped fields through the pass, the extraction, the aggregation and the diffing stay on the device, the identity fields (email, phone, name, address, account, session, user, ip, location, cookie and token shapes) strip unless the reviewed plan listed them, and the localrule fields of the origin strip always — a field the user marked local never leaves the device for any review — with the strip report and the held fields named in the step details and the audit trail; the `localgate` refuses any outbound payload that carries a local rule field at every boundary while the `outboundpayloadcheck` enforces the same refusal at the protocol boundary. The posture arithmetic fixes the counters: the telemetrypolicy type fixes the enabled literal to false so an on state is unrepresentable by construction, every counter keeps living inside the local memory, the background worker issues no outbound usage call from any context, and the requestbody omits every telemetry field by construction because no telemetry key exists on the wire format at all — the notelemetry invariant holds at the schema level and the vitest suite holds it with a zero outbound call counter over the transport seam.

The sync arithmetic stays opt in and encrypted. `optinsync` keeps the sync disabled until the user lists every data class — runs, memory, captures, settings and provenance — and turns each one on with the consent stamp of every enablement recorded per class for the audit trail (a class the listing never offered never enables) while the `syncgate` requires the opt in flag before any transport fires; `encryptsync` derives the key from the user passphrase through the webcrypto PBKDF2 seam (the passphrase never persists and never rides a payload), encrypts every payload through the AES-GCM cipher seam, stamps the devthink-sync-1 format tag, refuses a sync without the passphrase because a passphrase the user never typed never defaults in code, and the `encryptsyncgate` refuses plaintext payloads while the syncpass composes the whole pass with the payload hash recorded in the syncrecord. The lifecycle arithmetic answers the user requests: `purgeonrequest` deletes the stored families by scope with the typed confirmation phrase demanded for the full scope under the `purgegate`, the data inventory lists every stored key with its class, size and record count, the audit class never deletes because the immutable audit hashes survive every purge, and every deleted key enters the audit trail; `exportall` bundles the runs, the memory items, the captures, the settings and the provenance entries into one portable file on the explicit user action under the `exportallgate` and `streambundle` walks it in chunks of the explicit size with no cap because a bundle the user asked for streams whole; the cookie jar arithmetic assigns one jar per task run at the run open, binds every cookie read and write to the active jar under the `jargate` (a sealed jar refuses every write), seals the jar at the run completion under the user expiry window so the expiry pass clears the expired entries, and `cleanupafterrun` clears the task artifacts under the user cleanup schedule while the artifacts flagged for retention stay and the `cleanupgate` never deletes the audit history without consent; `enforcequarantine` holds every download in the sandbox folder until the verdict arrives with the `quarantineopengate` blocking every open without a clean verdict, the `scannerhookgate` keeping the verdicts on the user configured scanner endpoints, a clean verdict releasing, a flagged verdict deleting and a pending or error verdict holding because a hook failure never releases anything.

The background wires the whole surface through the same seams (the cookie executor routes every setcookies, readcookies and clearcookies step through the jar of its run with the jarid on the session and in the step details, the quarantinedownload and scanvirus executors build their entries through enforcequarantine with the verdict report in the step details, the run open assigns the jar beside the run record with its artifacts list, the plan completion seals the jar and runs the afterrun cleanup beside the other teardown passes, the propose requestbody carries the minimization kinds beside the vision and forensic kinds, and the view, sync, purge, exportall, jar, quarantine, cleanup, localrule, schedule, retain and settings branches serve the sidepanel through the new minimization command family of the schemastrict router), the sidepanel gains the Data minimization section (the stored data inventory with its classes and sizes, the telemetry badge fixed to off, the sync opt in with its consent stamps and encrypted records, the purge controls with the typed confirmation, the exportall scope with its streamed chunk count, the cookie jars with their seal state, the quarantine entries with their verdicts, the cleanup schedule with the retention flags, the local rule fields and the minimization choices of the sync cadence, the cleanup delay and the jar expiry) and the popup shows the telemetry line fixed to off; the memory seam persists the family (the data inventory, the minimization policies of the purge scope, the cleanup schedule and the sync settings, the sync records with their payload hashes, the cookie jars with their seal state and expiry windows, the local rule field lists per origin, the telemetry policy fixed to off, the exportall bundles with their download links and the retained artifact flags) with the seam comment documenting an encrypted sync backend, the protocol documents the sync payload, exportall bundle and quarantine verdict schemas with the jarid in the session records, the sync consent in the audit payload and the version bump carrying the minimization contract, and the auditkind grows sync and minimize beside the existing purge, quarantine and cleanup kinds. The vitest suite grows six cases in `tests/minimization.test.ts` covering the localfirst stripping with the localrule blocking, the notelemetry invariant with zero outbound calls on the transport seam, the optinsync consent with the encryptsync refusal and the encrypted syncpass, the purgeonrequest scopes with the cleanup retention, the exportall completeness with the streaming chunks, and the cookiejar sealing with the enforcequarantine verdicts. Honest notes: no sync backend endpoint ships inside this release, so the sync transport seam answers the not delivered state and the encrypted envelope holds on the device until a reviewed sync backend takes the seam over — the opt in, the consent stamps, the encryptsync pass and the syncrecord all work and the transport itself stays a documented seam; the purge writes empty families through the purgekeys accessor so the stored families reset while the immutable audit chain survives untouched; the sync cadence, the cleanup delay, the jar expiry, the cleanup schedule, the purge scope and the local rule fields stay user choices with no code default — an absent cadence keeps every pass off, an absent delay leaves every cleanup to the explicit pass and an absent expiry keeps every sealed jar until the purge; the sync passphrase passes through the command input for the single pass and never persists anywhere; and no minimization path — strip, counter, sync, purge, export, jar, cleanup or quarantine — ever bypasses a review.

## 1.1.78

This release records what a run changed: before and after captures around every action step, console and network timelines aligned with the steps, baseline diffing that flags visual regressions, thumbnails and time lapses that summarize the activity, and consistent naming plus export that make the captures portable evidence, all inside the new `forensics` module that extends the reviewed families instead of duplicating them — the capture rectangle grammar rides the ocrregion shape the vision family already reads, the correlation joining composes the correlateids map the web api family of the 1.1.76 release already assigns, the console levels and sources reuse the loglevel and timelinesource grammars the run timeline family serves, the provlog provenance rides the append only log of the 1.1.75 pipeline family, and the naming carries the capturename grammar of the files family forward into the lowercase identifier rule. `beforeafter` pairs the page state around one action step: a sensitive or interactive step grabs the pre capture and the post capture through a capture grab seam the executor wires (the same tabshot the capture steps ride, stored through the same redaction pipeline so every forensic pixel carries the store time redaction evidence), a read only step skips its pre capture because a page a read never changed needs no before state while the post capture still answers what the step saw, both captures link to the stepid they wrap, and the pair records the heartbeat beat of the run so a restarted service worker never mixes the beats of two windows — the `forensicscopegate` keeps every forensic record inside the reviewed plan scope and the `forensicsreadonlygate` marks the pairing a read only observation.

The timeline arithmetic aligns the console and the network with the steps. `consoletimeline` collects the console entries in capture order, attaches the stepid active at each entry's timestamp, classifies errors, warnings and logs by the loglevel grammar, and preserves the run wide sequence numbers across page reloads — the page bridge queues the console lines the hooked page console captured (the same page injected listeners behind the consented debugger capability, so no debugger permission exists anywhere) and the new flushconsole seam hands them to the background on every step completion while the `consolemaskgate` keeps the masked text only because a console line that carries a secret shaped value leaks it into the evidence. `nettimeline` collects the request and response trace entries of the consented request observation, attaches each entry to the step running at its timestamp, and joins the request with its response through the correlation map of the run — a request without its pair stays unjoined so the gap names itself — while the `nettraceorigingate` keeps every traced url inside the origin grants of the session. The diffing arithmetic flags the regressions: `diffbase` freezes one stored screenshot for one page state under the user configured similarity threshold (the `diffbasegate` requires the user confirmation because a baseline the review never saw flags nothing honestly), `diffshot` runs a new capture against its baseline through the pixel diff seam (the executor wires the image bitmap block walk), computes the changed regions by merging the changed pixel blocks into css pixel rectangles, reports the similarity score between zero and one, and flags the visual regression only above the user threshold — an absent threshold never flags because the bound never defaults in code — while every sensitive step runs the comparison automatically with the score recorded in the step details and the diffscore of the last step riding the proposal requestbody.

The summary and portability arithmetic make the evidence readable. `thumbshot` sizes the thumbnail of every post capture for the capture log inside the user configured maximum edge with the aspect ratio held — an absent edge keeps the capture size because the bound stays a user choice — and every thumbnailrecord links back to its full capture. `timelapse` plans the lapse from the user reviewed interval and duration (the `timelapsegate` requires the explicit user start because a capture cadence the review never started never starts, and the interval carries no code floor so an unconfigured interval leaves the lapse to the explicit start), the loop captures one frame per interval through the same redaction pipeline, the lapse stops on the duration end, the plan completion or the user stop, and `assemblelapse` sorts the frames into the ordered sequence the playback reads. `namecaptures` builds the lowercase file names from the {plan}, {step}, {timestamp} and {sequence} parts of the user naming rule, folds every name into the lowercase identifier rule and bumps a counter suffix so the names stay unique per run, while `parseproposal` accepts the capture options on the capture steps (the naming pattern, the pair mode of beforeafter, post or none, and the diff flag) and rejects an opaque or empty naming pattern at the boundary. `exportcaptures` assembles the captures, their beforeafter pairs, the console and net timeline counts, the diff results, the thumbnails and the lapse frames into one `capturebundle` under the capture names — every capture must carry its provlog provenance entry because an export payload without provenance never leaves the device, the bundle assembles only after the redactshot masks answered the review, and the `captureexportgate` requires the explicit user action with the masks and the provenance aboard — writing the bundle report through the reviewed download flow.

The background wires the evidence surface through the same seams (the plan executor wraps every step with the forensic pairing, the post capture thumbnail and the sensitive step diffshot through the `runstepwithforensics` wrapper around executestep, the watchconsole executor feeds the forensic console timeline while the page bridge flushes its pending console entries on every step completion, the watchrequests executor records the net trace entries through the correlation join tied to the run heartbeat, the timelapse loop stops on the plan completion beside the other run teardown passes, the propose requestbody carries the diffscore of the last step and the forensic kinds beside the vision kinds, and the baseline, diff, thumb, timelapse, name, export, cleanup and settings branches serve the sidepanel through the new forensics command family of the schemastrict router), the sidepanel gains the Capture forensics section (the before after pairs side by side with their step links and beats, the console timeline with its level filters, the net timeline with its status filters, the diff results with their scores and changed region counts, the capture thumbnails of the run log, the timelapse frames with their playback, the baseline, diffshot, timelapse and export controls with the capture file name preview and the forensic user choices) and the popup shows the forensic evidence line; the memory seam persists the family — the beforeafter pairs, the per run console and net timelines, the diff baselines with their page state labels and the diff results with their changed regions, the thumbnails linked back to their full captures, the per run timelapse configurations with their ordered frame references, the user capture naming rule and the forensic choices of the diff threshold, the timelapse interval, the thumbnail edge and the retention — with the seam comment documenting a capture store backend, the protocol documents the beforeafterpair, console trace and nettraceentry schemas, the beforeafter and diff blocks in the step results, the capture names in the audit payload and the export refusal without provenance, and the auditkind grows timelapse and thumb beside the existing diff and export. The vitest suite grows six cases in `tests/forensics.test.ts` covering the beforeafter pairing with the step linkage and the read only pre capture skip, the consoletimeline ordering with the reload continuity and the sequence continuation, the nettimeline joining through the correlation map, the diffbase storage with the diffshot scoring and the region merging, the thumbshot sizing with the timelapse planning and the frame assembly, and the namecaptures uniqueness with the exportcaptures provenance and mask refusals. Honest notes: the forensic capture around every step adds two tab captures per action step (one pre for the mutating steps and one post), so a run of many steps gathers proportionally more capture bytes and the forensicretention window of the user prunes them only through the explicit cleanup pass — no silent sweep ever prunes on its own; the diff regression flag answers the user threshold alone and an absent threshold never flags, so an unconfigured run reports scores without verdicts instead of inventing a bound; the timelapse loop lives inside the service worker lifetime (the config record and its ordered frames survive restarts through the memory seam while a dead worker stops the interval until the user restarts the lapse); the console timeline derives from the same page injected listeners behind the consented debugger capability, so no debugger permission exists anywhere and the console text stores through the masking rules only; the net timeline traces only the observed exchanges of the consented request observation inside the origin grants; the export bundle requires every capture to carry its provlog provenance entry and its redaction answer — an unmasked capture or a capture without provenance refuses loudly instead of leaving the device; the capture naming needs the user configured rule because no pattern defaults in code; and no forensic path — pairing, timeline, diff, thumbnail, lapse, naming or export — ever bypasses a review.

## 1.1.77

This release teaches the agent to see: image, region, pdf and video frame ocr join vision model descriptions, element crops, sensitive region redaction, screenshot grounding and dom pairing, all inside the new `vision` module that extends the reviewed families instead of duplicating them — the crop and scale geometry composes the capture rectangle rules of the 1.1.40 family, the sensitive field shapes come from the maskinputs recognizer the redactshots family already uses, the streamcursor checkpoint grammar comes from the pipeline family of the 1.1.75 release, and the image hash rides the same bodyhashof shape identity the web api cache of the 1.1.76 family keys its entries with. `imageocr` runs one captured image through an ocr read seam the executor wires and returns every word with its box and its confidence, `mergelines` joins the words whose boxes share more than half of the shorter box's height into lines with the lowest word confidence dragging its line down instead of hiding inside an average, `mergeparagraphs` joins the lines whose vertical gap stays inside the shorter line's height, and `ocrtext` folds the recognition into searchable text — pure geometry with no configurable bound. `regionocr` reads one sidepanel drawn ocrregion with the region clamped into the viewport and the word boxes offset to absolute screenshot coordinates (the `regionboundsgate` validates the drawn region against the viewport bounds while a region fully outside refuses loudly instead of reading wrong pixels), `pdfocr` reads one scanned pdf one page at a time through the rasterize seam with the streamcursor checkpointing after every page so an interrupted pass resumes exactly at its page and a cursor of another document refuses, and `frameocr` refuses the frame of a playing video before any pixel moves — the pause enforcement is the rule, the seek waits inside the user configured `visionwaitbudget` window under the `framebudgetgate`, and the framereference records the position the run read under its `frameretention` window.

The description, grounding and pairing arithmetic map every visual claim back to the page. `visionshot` carries the reviewed prompt with the image to the configured vision model through the vision send seam (an empty prompt refuses loudly because the model answers exactly what the review asked) and returns a `visiondescription` with labeled regions so every claim traces back to pixels, under the `visiongate` that requires the user consent for the configured model endpoint — the endpoint origin must sit inside the session grants before any frame leaves the device while the `visionconsentgate` requires the recorded consent for the frames that travel — and the `visionsensitivegrade` marks the visionshot payloads sensitive so the audit trail records the provenance and never the image bytes or the description text; the `ocrgate` marks imageocr, regionocr, pdfocr and frameocr read only because the recognition never writes the page. `groundshot` scores every candidate element by its text match with the description label (the shared significant words over the label's words) and its geometry match with the region box (the intersection over union after the image pixel ratio converts the box into css pixels), averages the halves and returns the ranked selectors in a `groundingresult` while the `groundgate` keeps the grounding a read only observation — the grounding matches feed the new observation vision block beside the descriptions and the ocr text. `pairshot` pairs every screenshot with the dom snapshot of the same viewport captured nearest in time under the `pairgate` that keeps the dom snapshots inside the session boundary, and `pairquery` answers one query by searching the normalized text of both sides so a visual claim answers its page side. `cropshot` computes the element crop geometry scaled with device pixel ratio awareness (the bounds scale by the ratio, clamp into the captured image and refuse when they fall fully outside), and the shotelement executor rides it with the page bridge element bounds.

The redaction arithmetic guards the shares: `redactshot` applies one `redactionmask` through the mask fill seam before any sharing — every region clamps into the capture, a mask whose every region falls outside refuses loudly because a share that promises redaction while covering nothing leaks, the fill seam draws the opaque rectangles through the capture canvas, and the summary records the mask in the audit trail while the `redactionreport` envelope carries the capture id, the region count and the reason into the audit payload — and `proposeredactionmasks` derives the proposals from the sensitive field shapes by field type so the sidepanel offers exactly the masks the field types imply. The `redactgate` refuses the external share of an unredacted screenshot (the clipboard, a download or an export carries its reviewed mask first) while an internal destination needs none. The cost and cache arithmetic keep the family accounted: `visioncost` counts the model calls per run for the costshare ledger under the `visioncostgrade` that keeps the reporting local and read only, and the visioncache stores every recognition and description by its image hash so a repeated read serves without a model call — `visioncacheserve` bumps the hit counter while the `visioncacheexpirygate` ties the expiry to the user `visioncacheretention` window with no code default.

The background wires the seeing surface through the same seams (the storecapture path runs the reviewed ocr and vision passes on the stored capture bytes with every pass serving through the visioncache first, the pairshot pairing binds the dom snapshot beside every screenshot, the shotelement executor rides the cropshot geometry, the captureframe executor runs frameocr on paused videos through the new page bridge videostate read, the regionocr, pdfocr, visionshot, ground, mask, propose, redact, query, cachecleanup and cost branches serve the sidepanel through the new vision command family of the schemastrict router, the observation snapshot feeds the vision block, and every pass reports its activity to the sidepanel per call), the sidepanel gains the Vision and ocr section (the ocr results with their word box overlay, the vision descriptions beside the screenshots, the redaction masks editable on the capture with the field shape proposals, the grounding candidates with their scores, the dom snapshots paired with the screenshot view, the frame reads with their positions, the visioncache hits, the pair queries and the vision user choices) and the popup shows the vision model status; the memory seam persists the family — the ocr results and the vision descriptions under the user `visionretention`, the redaction masks with their region evidence, the screenshot pairs, the grounding results, the frame reads under the `frameretention`, the vision model configuration, the visioncache entries with their image hashes and the vision call log that feeds the costshare ledger — with the seam comment documenting a model provider backend, the protocol documents the ocrresult and visiondescription schemas, the grounding selectors in the step results, the redaction masks in the audit payload, the vision capability report in the requestbody and the vision prompt validation of the extract steps (a vision prompt that is not a non-empty string refuses at the boundary), and the auditkind grows ocr, vision, redact and ground. The vitest suite grows six cases in `tests/vision.test.ts` covering the imageocr line merging with the confidence reporting, the regionocr bounds with the pdfocr page streaming, the frameocr pause enforcement, the cropshot scaling with the pairshot alignment, the redactshot masking with the audit records and the proposals, and the groundshot ranking with the visioncache hits. Honest notes: no recognition or description ships inside the extension — the ocr read, the vision send and the pdf rasterize seams ride the user configured vision model provider and refuse loudly while unconfigured, so the model and the endpoint stay user choices with no code default; the vision retention, the visioncache retention, the frame retention and the frameocr wait budget stay user choices too (an absent value keeps every record, every entry and every frame read and never refuses a wait); the line and paragraph merging runs on the boxes' own geometry with no configurable bound; the visionshot payload grades sensitive so the audit carries the provenance and never the image bytes or the description text; the grounding stays a read only observation that never clicks, writes or scrolls anything; the dom snapshots never cross the session boundary of their run; the visioncache serves only inside its run namespace; and no vision path — recognition, description, crop, redaction, grounding, pairing, cache serve or cost report — ever bypasses a review.

## 1.1.76

This release widens the transport layer to the web api surface: server sent events, long polling, graphql subscriptions, multipart uploads and form posts join the vocabulary, while correlation ids, rate limit respect and per run response caching keep every call accounted, all inside the new `webapi` module that extends the reviewed families instead of duplicating them — the event stream grammar and the poll cursor decisions come from the socketbus of the 1.1.43 family, the urlencoded and multipart wire shapes come from the netauth encodings of the 1.1.44 family, and the retry after parsing comes from the netcontrol of the network family. `subevents` opens the server sent events channel through a stream open seam the executor wires: every complete block parses into its event, data, id and retry fields, the last event id persists so a reconnect resumes exactly where the stream stopped (the request headers carry the last event id of the record), a cancelled step or an elapsed lifetime closes the channel cleanly, and a channel error surfaces to the run state machine instead of dying silently — the `subscribegate` requires the channel origin grant before anything opens and the `subscriptionboundgate` bounds the open subscriptions per run by the user ceiling only. `longpoll` issues the request the reviewed cursor builds (the cursor rides the reviewed query parameter when one is set and posts inside the request body otherwise), retries a timed out request under the user configured backoff, and stops on the reviewed stop condition, the cancellation flag, the plan expiry or the reviewed poll ceiling — the loop never invents a bound of its own, and the poll timeout and backoff stay user choices through the `pollchoices` resolution of the settings.

The graphql and posting arithmetic joins the vocabulary. `graphqlsubscribeframe` builds the graphql-ws subscribe frame with the operation id, the reviewed query and its variables, `parsegraphqlmessage` parses the next, error and complete frames (an unparseable frame reports itself as an error instead of dying silently), and `graphqlsub` maps the inbound messages into step results with the errors collected and the complete marker closing the mapping. `formpost` encodes the reviewed fields with the urlencoded content type and refuses an origin outside the grants before any byte moves; `multipartpost` encodes the fields and the files into ordered chunks under one boundary — the part headers build from the new `multipartfield` grammar with the field name, the filename and the content type — the progress callback reports each streamed chunk with its sent and total bytes without ever buffering the whole payload, and an unreviewed file refuses before any byte encodes. The `transportgate` restricts every api call of the family to the granted origins (the widened transport surface moves the same reviewed bytes the fetch family moves and never widens what the review granted), the `postgate` grades formpost and multipartpost sensitive while the subscription, poll and observation transports stay read only, and the `uploadgate` requires the explicit file review before a multipart upload encodes.

The accountability arithmetic keeps every call accounted. `correlateids` assigns one request id per outbound request of the run (the correlation id derives from the run and the request order), `joincorrelation` joins the response onto its request through the shared correlation id (a request id the map does not carry refuses instead of pairing the wrong pair), `correlationexport` exports the per run request map to the audit trail, and the `correlationmappinggate` keeps the mapping read only inside the run so it never drives a step, a queue or a verdict — the proposal requestbody now includes the correlations block so the endpoint sees exactly which outbound requests the run already made, and the response envelope carries the correlation block so every api result answers its request. The rate limit arithmetic respects the endpoint budgets: `ratelimitdirectiveof` parses the remaining count, the reset window of the x-ratelimit family and the retry after wait of a 429 or 503 answer into one `ratelimitdirective` scoped to the origin, `ratelimitwaitof` resolves the milliseconds the next request of the origin owes (an absent or passed directive waits nothing), `ratelimitrespect` sleeps the wait until the reset window passes so a call never crosses a limit the endpoint published, and the `ratelimitrespectgate` holds a wait past the reviewed budget as a loud refusal instead of dropping the call silently. The caching arithmetic serves the repeats read only: `cacheresponse` keys the entry by the run namespace, the method, the url and the body hash (the hash carries only the shape identity, never the body values), only a read only method stores, a response that carries credentials refuses through the `cachegate`, and a response that follows a mutation on its origin never stores while the invalidated entries of the origin drop; `cacheserv` serves the repeated read only call of the same run with its hit counter bumped, an entry whose origin saw a mutation or whose expiry passed stops serving, `cacheexpiryof` derives the expiry from the cache-control max-age, the expires date and the user retention policy, `cachecleanup` runs the expiry pass that reports exactly what it expired, and the step results carry the cachehit block so a served read names the entry it came from.

The background executes the transport steps through the webapi module (the subscribesse executor runs through `subevents` with the stream open seam wired to the fetch streams, the longpoll executor runs the loop with the poll fetch seam and the user poll choices, the postform and postfiles executors encode through `formpost` and `multipartpost` with the transport and upload gates, every outbound request of the run assigns its correlation id and joins its response pair, the rate limit directives parse from the response headers with the wait slept before the next call of the origin, the repeat read only calls serve through the per run cache with the hit recorded in the step details, the observed page api calls land as `apicallrecord` entries beside the discovered api map during the navigation waits, and the run cancel, the session stop and the killswitch close every open transport), the webapi command family serves the sidepanel through the same schemastrict router (view with the subscriptions, the graphql channels, the poll loops, the upload progress, the rate directives, the cache entries, the correlation map and the observed api calls, cancel for any open transport, the correlation export, the cache cleanup pass and the user choices for the poll timeout, the poll backoff, the subscription ceiling, the cache retention and the apicall retention). The sidepanel gains the Web api transports section (the open subscriptions with their channels and last event ids and their cancel controls, the graphql channels with their result and error counts, the poll loops with their cursors, the upload progress bars, the rate limit waits with their reset times, the cache hits per step, the correlated request pairs per run with the export control, the observed api calls and the transport user choices) and the popup shows the open transport count; the memory seam persists the family — the event subscription records with their persisted last event ids for the resume, the per run cached responses namespaced through their run embedded cache keys, the cache expiry cleanup pass, the per run correlation maps, the ratelimitdirective records per origin and scope, the observed page api calls under their retention and the poll choices — with the seam comment documenting a reviewed cache backend, the protocol documents the eventsubscription, graphqlsubscription, longpollrequest and multipartfield grammars, the required cancellation path of every subscription (a subscription without its cancellation path refuses at the boundary before any channel opens), the correlations block in the requestbody and the correlation and cachehit blocks in the envelope, and the auditkind grows subscribe, poll, post, cache and correlate. The vitest suite grows six cases in `tests/webapi.test.ts` covering the subevents parsing with the last event id resume and the clean cancel, the longpoll timeout retry with the stop conditions, the graphqlsub message mapping with the subscribe frame, the formpost and multipartpost encodings with the progress and the upload refusal, the correlateids assignment with the pair joining and the export, and the ratelimitrespect waits with the cacheresponse expiry and mutation invalidation. Honest notes: the poll timeout, the poll backoff, the subscription ceiling, the cache retention and the apicall retention stay user choices with no engine default (an absent value leaves the poll unbounded and the subscription count unbounded), the rate limit wait never drops a call silently (a wait past the reviewed budget refuses loudly), the cache serves only inside its run namespace and never stores a response that follows a mutation or carries credentials, the correlation mapping stays read only and never drives a step, the observed api calls record and never replay, and no transport path — subscribe, poll, graphql, form post, multipart upload, correlation, rate wait or cache serve — ever bypasses a review.

## 1.1.75

This release grows the extraction into full data pipelines: large extracts now stream to disk chunk by chunk with a cursor that checkpoints after every write and a resume that continues exactly the extraction it came from, transform rules reshape one value at a time between extraction and export with the raw value always beside the transformed one, rows deduplicate under the configured key, grids preview before anything exports, and a provenance log records every pipeline operation, all inside the new `pipelines` module. `streamdisk` splits the rows under the user chosen chunk size (an absent size streams the whole pass as one chunk because the bound never defaults in code), only the active chunk rides the write so the memory holds exactly one chunk at a time, every chunk reports the rows and the bytes it persisted, and the streamcursor records the last written position after each chunk while the checkpoint callback observes every boundary; the `streamgate` allows the disk writes only through the reviewed download flow (a bare filesystem path or an unreviewed endpoint refuses because the pipeline layer moves bytes through the same reviewed export machinery every other export flows through and never opens a side channel), the `streamchunkgate` bounds the chunk by the user ceiling only, and the `streamnamespacegate` binds every stream file name to the runid namespace so a stream never collides with the files of another run. `resumeextract` continues an interrupted pipeline from its streamcursor: the rows the cursor offset and the persisted row keys already cover skip so nothing writes twice, the resume marks the pipeline in the provlog, and a finished pipeline, a cursor of another pipeline, a resume of another plan and a resume of another origin all refuse loudly (the `resumegate` checks the plan and the origin before any row skips).

The transform, dedupe and sampling arithmetic holds the value line. `transformvalues` applies the reviewed rules between extraction and export — trim folds the whitespace, case folds the letters, number strips the non numeric shapes and date normalizes to ISO 8601 — while the raw value stays beside the transformed value so the audit reads both sides, an operation outside the reviewed list (trim, case, number, date) refuses with its refusal named and without ever dropping a row, a value that parses as no date keeps its raw shape, and the `transformgate` restricts the pass to the rules the plan review approved so the pipeline never widens what the review read. `deduperows` joins the configured key columns into one comparison value under the configured normalization (whitespace folding, case folding, both or none), keeps the first occurrence of every key, and reports the dropped rows by count and by key while the dedupe configuration stays per pipeline as a user choice (an empty key list refuses because an implicit key would silently drop rows the user never chose to compare, and the `dedupeconfiggate` holds the same line). `samplerows` selects the preview subset by the sample policy — first takes the leading rows, random shuffles deterministically under the seed the policy names, stratified spreads the pick evenly across the ordered extract — and the full extract never mutates because the subset copies its rows while the `samplegate` marks the samplerows pass as the only read only pass of the family. `sourcestamp` attaches the url, the step id and the capture time to every row of the pass, every cell links to its stamp id so each value answers which page and step captured it, and a stamped timestamp never rewrites (the `rowstampgate` refuses a restamp whose capturedat moved).

The projection and the provenance arithmetic carry the audit. `gridpreview` projects the rows and the columns into a read only grid model: the column kinds infer from the sampled values (numbers, booleans and ISO dates infer their kind while every other shape stays text and an all empty column never guesses a kind it did not observe), the sort orders by any observed column and the filter keeps the matching rows without ever touching the stored extract, every projected row carries its marks (stamped when its stamps exist, transformed for the fields whose raw values survive beside them, deduplicated for the rows a dedupe pass kept), the `gridexportconfirmgate` requires the explicit user confirmation before a preview exports because a preview that ships on its own would export a subset the user only meant to inspect, and the `provgate` requires the provlog provenance on every exported row so an extract that leaves without its provenance would answer neither where it came from nor which operations reshaped it. `provlog` appends exactly one entry per stream, transform, dedupe, sample and resume pass with the row keys it touched and its redacted summary — the log stays append only (an entry id that already sits in it refuses) for the audit integrity, and the secret shaped values (tokens, passwords, keys, bearer credentials, sk- and ghp- shaped strings, private key blocks) mask before any entry lands — while `provlogquery` answers the provenance of one row key with every entry that touches it in order, and `pipelinestate` tracks the running, paused and finished counts per run that the popup and the sidepanel read.

The background executes the extract steps through the pipelines: `runpipelinepass` runs after every extraction grid (the `pipelinetargetgate` refuses the fields outside the reviewed target before any value persists, `sourcestamp` stamps the rows with the page url and the reviewed step, `transformvalues` applies the reviewed rules before persistence, `streamdisk` streams the rows chunk by chunk through the reviewed sink with the cursor checkpointed after every chunk, one provlog entry lands per stream and per transform pass, the preview batch persists under the user `previewretention` window, and the completed pass exports through the reviewed csv, json and excel flows with the `provgate` provenance check on every exported row), the interrupted extractions resume through `resumeextract` with the origin verified against the original, the dedupe pass runs before the export with its `dedupereport` persisted and carried in the response envelope, and a new pipeline command family serves the sidepanel through the same schemastrict router (view with the grid preview, sortable columns and the provlog of a selected row, resume for the interrupted pipelines, the transform editing per field, the sample policy per plan, the stream progress in rows and bytes, and the user choices for the chunk ceiling and the preview retention). The sidepanel gains the Data pipelines section and the popup shows the active pipeline count per run, the memory seam persists the whole family — the extractpipelines per run, the streamcursors checkpointed after every chunk, the reviewed transformrule lists per run, the preview extractbatches under their user retention, the append only provlog entries per run, the samplepolicies per plan, the dedupereports with their dropped counts, the streamfilerecord metadata for the cleanup after each run and the sourcestamprecords beside their rows — through the same local adapter with the seam comment documenting a reviewed disk backed sink backend, the protocol documents the extractpipeline schema, the transformrule grammar, the pipeline option on extract steps, the streamcursor block in the step results and the dedupe reports in the response envelope, and the auditkind grows stream, transform, dedupe, sample and resume. The vitest suite grows six cases in `tests/pipelines.test.ts` covering the streamdisk chunking with the cursor persistence, the resumeextract skip and completion with the moved origin refusal, the transformvalues operations with the raw retention and the unknown operation refusal, the deduperows key normalization with the dropped reports, the samplerows strategies without mutation, and the sourcestamp cell links with the gridpreview kind inference, sorting, filtering, marks, the provlog redaction with the append only refusal and the provenance queries by row key. Honest notes: the chunk size, the chunk ceiling, the preview retention and every sample row count stay user choices with no engine default, the transform pass never drops a row even when a rule refuses, the sample preview reads a copy and never mutates the stored extract, the provlog carries its operation and its row keys but never a payload, and no pipeline path — stream, resume, transform, dedupe, sample, stamp, preview or export — ever bypasses a review.

## 1.1.74

This release opens the navigation intelligence phase by returning attention from the fleet to the page itself: navigation now predicts the pages the approved plan is about to need, warms them ahead of the steps and verifies every url before anything opens, all inside the new `navigation` module. `navintent` reads the approved plan steps in order, keeps the https navigation values it finds (duplicates fold to their first occurrence), weighs every candidate by how often the urlhistory of the run already visited it, and ranks the predictions by the combined step order and history confidence — an earlier step and a more visited url win — while `navintent` and `prefetchpage` both grade read only observations through the `navigationobservationgrade` gate: the prediction and the warming compute sets and never issue a request of their own. `prefetchpage` warms only the urls the session grants cover (`prefetchgate` refuses any candidate outside the grants because a speculative dns resolution of an ungranted origin would observe a site the user never consented to), drops every stored prediction the moment the plan it came from changes so stale predictions never warm a page the new plan no longer visits, and the page world resolves the speculative dns hints read only while no mutating request ever fires during the warming. The background computes the navintent predictions right after each plan approval (the run record opens, the prediction plan persists for restart survival, the navintentrecord carries its `predictedurls`, and one audit event names the ranked set), the prefetch step executor warms the stored predictions when the reviewed step carries none of its own, and the proposal requestbody now includes the `predictedurls` so the endpoint plans against the predicted pages; `toolstep` gains its `intenthint` field so a navigate step names the predicted navigation it belongs to, and `parseproposal` accepts it while rejecting a `batchopen` proposal whose reviewed urls leave the grants because a batch never widens the grants.

The transport and the deep links open ahead of the steps: `preconnectorigin` filters the expected origins through the host grants of the session, every target carries the time its connection is expected, and every socket stays read only and revocable (`preconnectgate` refuses a revoked target and a target outside the host grants) — the session start preconnects to the granted origins ahead of the first steps, the preconnect step executor records the targets for the sidepanel sockets view, and the auditkind grows preconnect, reopen, safecheck and batch beside the existing prefetch. `deeplinkapp` maps the common web apps to route patterns (github, youtube, maps, wikipedia, amazon and x beside the user stored `deeplinkpatterns` with the `{ app, origin, route, params }` grammar documented in the protocol header), builds the url from the first pattern whose named parameters the reviewed step supplies, refuses a missing parameter loudly instead of building a half url, encodes every substituted value, and the `deeplinkgate` requires the pattern origin grant before anything builds. Closed tabs come back: every tab removal now lands a `closedtabrecord` with its url, title, tab, window and close time under the user configured `closedtabretention` window (the earlier session era `closedtab` and `recenttab` memories stay untouched), `reopentab` restores the most recent record the retention window still carries after the `reopentabgate` grant recheck (an explicit url restores its own record, a record whose origin lost its grant refuses loudly because the closing of a tab never carries the consent of its origin forward, and a reopened record never reopens twice), the popup lists the recent closed tabs with a reopen button, and the sidepanel navigation section carries the same records. `restoretrail` rebuilds the navtrail of the run from its urlhistory with consecutive duplicates folded — repeated restores return the same entries so a replayed trail never doubles — while `recordnavigation` captures the final url of every navigation into the per run navtrail, the `trailorigingate` verifies every entry stays inside the session origins, the on demand replay walks the ordered entries into one fresh tab, and the `trailexportgate` keeps the trail exports behind the explicit audit consent.

The pace of navigation now holds behind user choices only. `pausenavconsent` freezes every navigation kind while a consent prompt is open (the `pausenavconsentgate` blocks openlink, openprivate, followlink, spanav, navlist, openclipboard, batchopen, prefetch, preconnect, deeplink and reopentab) and queues the pending navigation url of the refused step into the persisted navpause record until the answer — the resume hands the queued url back so the run continues exactly where the prompt stopped it, and the sidepanel marks the paused state with its pending url. `navratelimit` tracks the navigation count of one domain inside a sliding window: every navigation stamps its hit, the hits older than the user configured `navratewindow` age out as the window slides, a full window delays the step for the milliseconds the oldest hit needs to age out and never drops it silently (`navratelimitgate` names the delay, the executor sleeps it, the `ratelimitwait` block rides the response envelope with the domain and the waited milliseconds, and a window that stays full refuses with its retry guidance), the reviewed per domain ceiling applies beside the window, and an absent window and ceiling leave the counting manual because both stay user choices with no code default. The clipboard opens only behind the gesture: `openclipboardurl` parses the clipboard text into one https url and requires the origin grant while the `clipboardgate` requires the explicit user action of the reviewed step beside it. `checksafeurl` deepens the safety verification — https only, no embedded credentials, no private network or raw address targets, no punycode labels, and the lookalike heuristics against the granted origins (the granted host embedded in a longer host, joined through hyphens or squatted through the flat joined name refuses with the matched origin named in the reasons) — every verdict persists into the safetyverdict history, the `safetygate` refuses any url that fails, the safety block with its reasons rides the step results, and the `safecheck` audit events record every refusal. `batchopenlinks` curates the reviewed urls through the per url verdicts (one unsafe url refuses the whole batch as a curated record that waits for review), bounds the batch size by the user `batchsizelimit` ceiling only (`batchsizelimitgate`), accounts every open against the per domain sliding windows across the whole batch, and moves the urls a full window holds into the waits the executor delays on — one tab per link opens, in order, and nothing drops silently.

The sidepanel gains the Navigation intelligence section (the predicted next pages with their prefetch state and confidence, the open preconnect sockets with their read only badges, the navtrail of the active run, the rate limit state per domain with its full and live marks, the safety verdicts with their reasons, the batch open offer with its link checklist (the pasted urls verify through the session grants and the checksafeurl heuristics on the check, the checklist lists every link with its safe or unsafe mark and its reasons, and the open control appears only when every link checked safe so one tab per link opens behind the user gesture of the click), the closed tab records with their reopen controls, the paused consent navigation with its pending url and resume control, and the navigation user choices for the rate window, the batch ceiling and the closed tab retention) served by a new nav command family through the same schemastrict router, the memory seam persists the navigation family — the closedtabrecords under the user retention window, the navtrails per run with their deduplicated entries, the per domain rate windows, the deep link patterns, the safety verdict history, the prefetchplan of the latest navintent pass and the navpause state with its pending url — through the same local adapter with the seam comment documenting a reviewed session restore backend, and the protocol documents the navintent prediction schema, the deeplinkpattern grammar, the intenthint on navigate steps, the batch origin verification and the rate limit waits in the response envelope. The vitest suite grows six cases in `tests/navigation.test.ts` covering the navintent ranking with the prefetchpage plan change dropping, the preconnectorigin grant filtering, the deeplinkapp pattern building, the reopentab grant recheck with the restoretrail folding and replay, the pausenavconsent queueing with the navratelimit sliding windows, and the checksafeurl verdicts with the batchopenlinks ordering. The action kinds stay at 334 (the navigation kinds already lived in the catalog), the manifest permissions and the pinned identity key stay untouched, and honest notes: the rate window, the batch ceiling, the closed tab retention and every delay stay user choices with no engine default (an absent window and ceiling leave the navigation counting manual), the preconnect sockets warm the transport only and never carry a request, the session start preconnect records the granted targets while the socket warming itself rides the preconnect step family when the page bridge is live, a lookalike heuristic that refuses errs on the safe side exactly like the phishguard posture, and no navigation path — prediction, warming, deep link, reopen, trail, pause, rate window, clipboard, safety or batch — ever bypasses a review.

## 1.1.73

This release opens the multi agent part four phase by scaling the coordination itself: sub agents now spawn on demand under the user configured depth limit with the `agentwork` module — `spawnsubagent` finds the parent in the fleet registry, refuses a paused or stopped parent, requires the child depth to sit exactly one level under the parent lineage depth, registers the child through the same `agentname` uniqueness rule of the fleet, and copies the parent scope into the child unless the spec narrows it (a narrowing that lands entirely outside the parent refuses loudly instead of silently widening, `subsetscopegate` re-validates the subset before the write, and a child of a read only observer never gains the write side) — while `depthoflineage` walks the spawn records from the agent up through its parents (a cycle in the lineage refuses instead of looping), `depthlimitof` checks the lineage against the user configured ceiling with an absent limit staying unbounded because the recursion bound never defaults in code, and the `depthgate` runs the same refusal at the policy boundary. Parallel results aggregate into one report: `aggregatereport` merges the agent cells with their per agent sections and run provenance kept visible, a section two agents both wrote conflicts, the user configured `conflictorder` resolves it by naming its agent precedence, a conflict without an order stays unresolved with the record open, the `aggregateconflictescalationgate` sends the unresolved conflicts to the escalation instead of silently dropping, the `aggregatemergegrade` marks the merge read only, and the background builds the merge automatically when the expected parallel agents finish their runs — each completed run appends its ordered step summaries as its section cell and the merge closes when the last expected agent delivered. The `interleave` orders the actions of every agent into one merged timeline sorted by time with each event carrying its lane so the per agent lanes stay visible inside the one stream (the `interleavereadonlygate` keeps the view read only for the audit), the executor appends one interleaveevent per executed agent step, and the sidepanel renders the timeline with its lane badges.

Lessons spread across the fleet: `lessonrecordof` records the finding of a finished run with its origin and a reuse count starting at zero, `lessonmatches` serves the lessons of the same origin first and the findings that share words with the task after (with the origin match weighing double), `lessonreuse` counts one reuse per served lesson, `lessondecay` retires the lessons nobody reused for the whole user configured window while the reused ones stay (an absent window keeps every lesson), the `lessonsecretgate` refuses a finding that carries a token, a password, a key or a bearer credential because the lessons spread across every agent, `lessonsanitizestep` masks the secret shaped assignments before storage, and the propose path serves the decayed matches at proposal time through the request body so the endpoint plans on what the fleet already learned. Resources arbitrate under prioritized lanes: `arbitrationcaseof` opens a case when at least two agents contest one resource, grants it to the first requester by default, and honors the priority lanes — a requester of a higher priority lane takes the grant over the first requester with the lane named in the verdict — `releasecase` frees the resource when the holder finishes (the completion path releases the verdicts of every holder agent of the finished plan), the `arbitrationverdictgate` keeps every verdict inside the sessionlock and the origin grants so a grant stays a queue position and never a permission, and the executor opens the case on real contention: an agent stepping on an origin with a granted case it does not hold joins the requesters, the verdict recomputes through the lanes, and the step waits behind the verdict. `prioritylaneof` ranks the queued tasks by the user configured lane priority with the interactive lane always first, the sensitive tasks stay in the interactive lane whatever lane asked for them, and every further lane serves one task per round robin cycle in its priority order so no lane starves behind a busy higher priority lane — the task queue drain reorders through it before every claim.

Workers scale by site load and costs share across the fleet: `loadreportof` freezes the worker concurrency and the wait latency of one origin into a sample the navigation waits collect (the navlist executor measures every entry wait and counts the live fleet workers of the origin), `scalesuggestion` suggests spawning one more worker when the load stays low and pausing one when an origin throttles past the threshold while absent thresholds hold the suggestions, the `scaleconsentgate` keeps every suggestion behind the user consent because the fleet size never changes alone, and the sidepanel surfaces the suggestions with their consent controls. The `costentryof` lands one entry in the shared ledger per executed agent step with its runid and plain language description, `sharedcostsplit` attributes a solo cost fully to its agent and splits a cost several agents share through the same description equally among its causers with the peers named, the `costsharegate` keeps the accounting local and read only, and the protocol attributes every entry to its requesting agentid through the `costledgerreport` envelope. The protocol documents the spawn grammar `{ parentid, objective, role, narrowscope, depth }` with `parsespawnrequest` rejecting a spawn whose depth exceeds the configured limit before any registry write and carrying the parentid and depth in the `spawnreply` response, the `aggregationreport` envelope carries the per agent sections with their conflicts and state, the `lessonreport` envelope carries the served lessons with their reuse counts, and the request body now includes the active lanes, the latest load reports per origin and the matching lessons. The memory seam persists the work family — the spawn lineage with its parent objectives, the aggregaterecords under the user `aggregateretention`, the interleaved timeline under its own retention, the lessons, the arbitration cases with their verdicts, the priority lanes, the latest load reports per origin, the shared cost ledger, the user depthlimit and the user `maxworkersorigin` worker ceiling per origin — through the same local adapter as everything else, and the seam comment documents the work shapes a reviewed shared fleet backend may take over later. The background wires the work command family (spawn, depth, aggregate, lesson, arbitrate, release, lanes with drag and drop order, scale consent, view): the spawn runs through the agent endpoint contract with every gate enforced, a cancelled parent run stops its spawned children because the children work on the objective their parent handed over, the auditkind grows spawn, arbitrate, lesson, lane and scale, and the audit trail records every spawn, verdict, lesson and lane change. The sidepanel gains the agent work section (the spawn tree with its depth indicators, the aggregatereport with its per agent sections and conflict resolutions, the interleaved timeline with its lanes, the lessons with their reuse counts, the arbitration cases with their verdicts and release controls, the priority lanes with their drag and drop ordering, the scaleworkers suggestions with their consent controls and the shared cost ledger with its per agent shares), and the popup shows the live worker count per origin. The vitest suite grows eight cases in `tests/agentwork.test.ts` covering the spawnsubagent lineage with the depthlimit refusal, the aggregatereport merge with its conflict escalation, the interleave ordering across concurrent agents, the lessonshare matching with its sanitization and decay, the arbitrate verdicts with their lanes and release, and the prioritylane ordering with the costshare attribution. The action kinds stay at 334, the manifest permissions and the pinned identity key stay untouched, and honest notes: the depth ceiling, the conflict order, the lesson decay window, both retentions and the worker ceiling per origin stay user choices with no engine default, a scaleworkers suggestion never spawns or pauses a worker without the explicit user consent, the load samples ride the navigation waits the navlist executor already runs so no extra page traffic appears, and no work path — spawn, aggregate, lesson, arbitrate, lane, scale or cost — ever bypasses a review.

## 1.1.72

This release opens the multi agent part three phase by giving the fleet the control and accountability layers the swarm of 1.1.58 and the coordination of 1.1.59 lacked: every agent now registers in a fleet registry through `agentname` — the helper lowercases the user proposal, refuses names outside the lowercase identifier rule, the reserved identities (user, operator, human, system) and duplicates, and lands an `agentrecord` with its role, its home origin and its live control state before its first run — while `agentsession`, `runrecord`, `toolstep` and `planproposal` all gain their `agentid` field so every session, run and step attributes to its requesting agent. The `agentscope` type grows its `actionkinds` narrowing and its `readonly` flag: `agentscopeof` intersects the requested origins and action kinds with the session grants and the allowed catalog (a request that lands entirely outside refuses loudly instead of silently widening), `readonlyscope` builds the observer scope over the read side vocabulary, and the `agentscopegate` refuses any step whose kind or origin leaves its agent scope while a read only scope refuses every mutating kind. The `agentbudget` type grows its `maxdurationms` ceiling, `agentbudgetof` grants the budget from user configuration with no hardcoded cap into a fresh `budgetstate`, `spendbudget` spends one unit per executed step (with the measured step duration beside it) and refuses past a user configured ceiling until the user raises it or stops the agent, `budgetremaining` reports what is left per agent, and the `budgetgate` runs the same refusal before every step. `pauseagent` pauses one agent without stopping its peers — their records and their run records stay exactly as they were, the `pauseagentgate` names the peers that stay runnable, and the executor refuses the steps of a paused agent while everything else keeps running — while `engagekillswitch` cancels every agent run, clears every queue (the swarm taskqueue and the offlinequeue) and stops every fleet record in one call, returning one stop entry per agent so one audit event lands per stopped agent; the `killswitchgate` now refuses an agent trigger outright and stays effective over paused agents because a pause never shields an agent from the stop, and the popup carries the killswitch button beside Stop.

The accountability side arrives with the `agentreview` module: the `escalationrecord` grows its `stepid` so the sidepanel reads the step context beside the agent question, `escalate` lifts the stalled decision to the user exactly as orchestration built it, the new `escalationblock` and the `escalateholdgate` block the raising agent until the human answers (the answer closes the record through the fleet command and lifts the hold), and the auditkind grows `escalate`, `review`, `vote` and `kill` beside the existing pause and budget kinds. The `reviewrecord` carries one agent output to a peer for review — `reviewrecordof` routes it only between two registered agents, the `reviewrequestgate` requires both to share the origin grant so a review never crosses an origin boundary, and `recordverdict` writes the approve, changes or reject verdict beside the original output which stays untouched forever. The `replayrecord` captures the ordered steps and results of one agent run at the end of every completed run under the user `replayretention` window, `reconstructreplay` rebuilds the same shape from the audit trail when the run memory is gone (marked `reconstructed`), and the `replayexportgate` binds every replay export to the audit consent boundary. The `comparisonrecord` aligns two competing agent outputs field by field through `outputcompare` — every field grades matching, conflicting or missing so the user reads exactly where the agents disagree — and the `consensusrecord` collects one vote per agent on one proposal through `consensusrecordof` (the `voteweightvalid` refuses a duplicate voter, the `consensusquorumvalid` keeps the quorum a user configured value, the dissenting votes with their reasons stay in the record) while the `consensusreport` envelope carries the vote records, the tally and the outcome; `outputcompare` and `consensusvote` grade read only through the `fleetoperationgrade` and never touch the page.

The protocol carries the fleet identity end to end: the `requestbody` includes the `agent` block of the requesting agent's id, name and role beside its `budget` state, `parseproposal` attributes every step of the plan to its requesting agent and refuses proposals naming agents missing from the fleet registry, the protocol version bumps with the package version, and the header documents the escalation and reviewrequest message grammars. The memory seam persists the fleet family — `getagent`, `setagent`, `listagents`, `getbudget`, `getagentscope`, `getreviews`, `getreplays` under the user retention, `getcomparison`, `getvotes`, the killswitch stamp and the paused agents beside the orchestration era escalations — through the same local adapter as everything else, and the seam comment documents the fleet shapes a reviewed shared backend may take over later. The background wires the fleet command family with its schemastrict grammar (register, pause, unpause, killswitch, answer, review, verdict, compare, vote, replay, view): registration runs through `agentname` before the first run, the executor enforces the scope, the budget and the escalation hold on every attributed step with a `deny`, `budget` or escalation audit event per refusal, the step spend charges the budget with the measured duration, the approval attributes the runrecord to the plan's agent, the completion captures the runreplay, the consensusvote opens when the plan asks through the vote action, the fleet view returns after every action so the sidepanel reads the live state, and the protocol boundary refuses unknown agentids at the parse, the executor and the fleet commands. The sidepanel gains the fleet control section (the fleet list with names, roles, states, budgets and the single agent pause from its row, the open escalations with their answer controls, the review requests with their verdict controls, the outputcompare side by side and the vote tally with its outcome and dissent), the popup gains the killswitch button and the fleet state line, and the style marks every control state with fleet badges. The vitest suite grows twelve cases across `tests/agentfleet.test.ts` and `tests/agentreview.test.ts` covering the naming uniqueness with the scope narrowing, the budget grant with its spend refusal and reporting, the pause isolation with the killswitch completeness, the escalation blocking with the review routing, the replay capture with its audit reconstruction and the outputcompare alignment with the consensusvote tallies. The action kinds stay at 334, the manifest permissions and the pinned identity key stay untouched, and honest notes: the five roadmap literals that collided with existing type names became `agentscopeof`, `agentbudgetof`, `engagekillswitch`, `reviewrecordof` and `consensusrecordof` (the types keep their names and the export star of the library index stays unambiguous), the escalation store reuses the orchestration era accessors (`addescalation`, `updateescalation`, `getescalations`) so one escalation trail serves both layers, every budget ceiling, the quorum, the replay retention and the fleet size stay user choices with no engine default, the killswitch stays user triggered only, and no fleet path — scope, budget, pause, kill, review, vote or replay — ever bypasses a review.

## 1.1.71

This release opens the state depth phase by making the state of every run observable and safe: each run now keeps its own urlhistory through the urlvisit records the executor appends on every completed navigation step — with the final url the redirect chain landed on reported by the pagebridge and the live tab, consecutive visits to the same url folded, and the urlhistorygate confining every visit to the approved origin of its run while the urlhistoryscopegate never merges the histories of two runs — and the runtimeline merges the step results, the audit events and the url visits of one run into a single timestamp ordered stream that buckettimeline groups into phase buckets for the timeline view, rendered read only through the timelinereadonlygate so the timeline never executes or mutates anything. Tab isolation namespaces the memory keys per tabid through tabisolate so runs never share state, copying the shared config into the tab namespace on demand, and the tabisolategate refuses steps whose tabid differs from the isolated namespace. The sessionlock acquires a lockrecord for a run on its session before the first step, refuses a second concurrent run while naming the holder in its reason, releases on completion, failure and cancel, and expires the abandoned locks at startup before the zombiecheck pass under the user configured window with no code ceiling; the protocol preserves the lockid across proposal replays, carries the isolated tab namespace id and the provenance of the observations in the request body, rejects memory payloads that lack their provenance fields through the memoryitemframe parser, validates urlvisit records against the session origin, and documents the runtimeline event schema and the auditexportrecord grammar through the runtimelinereport and auditexportreport envelopes. Memory items now wrap their stored values with a provenancerecord of origin, runid, stepid and capture time — the executor attaches provenance to every observation it stores — and expirememory evaluates the user configured expiryrules, purges the expired items only behind the expirygate confirmation, keeps a summary with the provenance of every purged item for the audit trail, and leaves the audit events untouched unless the user opts in. encryptrest derives its AES-GCM key from the user secret through the webcrypto api — the secret entry is a consent prompt and the derived key never persists — encrypts the sensitive memory classes at rest while the encryptmemorygate refuses their plaintext writes, decrypts on read without altering the audit trail, and migrates the items that predate encryption lazily on first access. quotawatch polls the storage estimate after each completed run, ranks its cleanup candidates by age and expiry policy, proposes cleanup batches that never touch the audit history and wait behind the explicit per batch approval of the quotacleanupgate, and reports the bytes reclaimed after every pass. The auditexport bundles the runs with their visits, the memory with its provenance, the expiry rules, the timeline streams and the locks into one auditexportrecord that streams through exportchunks without a size cap and leaves only behind the explicit user action of the auditexportgate with the exportprovenancegate requiring provenance on every item, served through the download flow. The sidepanel renders the state depth section with the runtimeline phase buckets, the urlhistory of the active run, the lock holder naming, the quotareport with its cleanup control, the expiryrules editor per memory class and the audit bundle export, the popup shows the encryption status, and the style marks the encrypted, expired and isolated items; the background runs expirememory on the user configured interval, quotawatch after every completed run, and expires the stale locks before the zombiecheck at startup. Honest notes: the lock expiry window, the expire interval, every expiryrule lifetime and the audit event expiry opt-in stay user choices with no code ceiling, the derived encryption key never persists so encrypted values only read back while the user re-enters the secret through its consent prompt, and the quota candidates rank only the stored memory items because the audit history never enters a cleanup batch without consent.

## 1.1.70

This release opens the resilience phase by turning the engine from a best effort loop into a survivable run manager: every approved plan now opens a runrecord the moment the user approves it, and the runstatemachine tracks its legal transitions through queued, running, paused, awaitingapproval, completed, failed, cancelled and rolledback so a service worker restart or a lost connection no longer loses work. Approved plans queue offline through the offlinegate with monotonic sequence numbers when the endpoint is unreachable, the browser online event replays the queue in sequence order while the tasks whose plan window passed offline expire and fail for the audit trail instead of replaying, and every step carries a deterministic idempotencykey derived from its plan and step identity so a replay of the same step deduplicates through the replaycheck and the pagebridge executed key set. The makecheckpoint captures the completed steps with a page digest after each successfully executed sensitive step, the resumecheckpoint skips the completed steps and continues at the first open step, and the checkpointgate refuses a resume against a changed page. Running runs send a runheartbeat before each step, the zombiecheck lists the running runs whose last beat sits past the user configured staleness window, reaprun fails a zombie through a reap audit event, and the zombiegate blocks new runs while a reap stays unresolved. When a step fails mid run the executor offers the rollbackrun compensations for every executed side effect — typed per mutating kind in plain language while read only steps carry none — and the compensating steps run only behind the rollbackgate and the explicit user choice, inside the origin the approved plan named through the rollbackorigingate; cancelrun pairs one cancellation with its optional rollback through cancelrollback. The protocol parses the resumedfrom marker of a resumed proposal, refuses idempotencykeys that collide inside one plan, carries the runstate and the queue depth in the request body and the runid and runstate in every response envelope, and validates that rollback summaries stay human readable; the memory seam persists the runrecords, the checkpoints, the heartbeats, the offlinequeue with restart survival, the rollback items, the executed idempotencykeys and the user heartbeat window, queue depth and failed run retention; the sidepanel shows the live runstate badge beside the plan with the checkpoint position and its resume control, the offline queue depth with its replay now control, the zombie runs with their reap timestamps and the rollback or plain cancel choices of a failed run, while the popup shows the heartbeat staleness of long tasks and the styles color every runstate. Honest notes: the broadcast of the run summary rides the runtime message channel because the surfaces refresh on the next frame anyway, the checkpoint digest falls back to a step derived digest when no observation stands on record, and the service worker shutdown persistence rides the per state change writes plus the wake pass because mv3 offers no reliable shutdown event — none of this bypasses a review, and the heartbeat window, the queue depth and the failed run retention stay user choices with no code ceiling.

## 1.1.69

This release closes the performance phase by making the platform from 1.1.68 polite, measured and budgeted. Batch run queues pause their enqueueing when the completed outcomes fall behind past the user configured backpressure window while every queued step stays queued, every domain runs at most its user chosen concurrency slots with the overflow queued per domain lane that the sidepanel renders during batch runs, politedelay spaces batch requests per domain above the siteprofile floors with a jitter window, adaptivepoll widens its interval while observations stay unchanged and narrows the moment changes resume inside the user floor and ceiling, requestcoalesce merges identical pending queries into one dispatch whose single result fans out to every waiter, and the snapshot cadence widens under memory pressure and restores when the pressure clears. The runbudget tracker records the step usage against the user step budget and the memory pressure the worker telemetry reported; the budgetalerts fire at the user thresholds with their severity levels — the warning reports while the critical threshold pauses the run pending a user choice through the session pause — and the dashboardpage renders every alert with its thresholds. The timeoutcancel races the reviewed dispatch against the user chosen bound and records its cancel event in the immutable log beside the step outcome while the sidepanel shows the events with their retry hints, the tabsuspend discards an idle tab only during a wait longer than the user window and restores it before the step that needs it with the run state preserved across the suspend and restore. The runcache stores fetched resources per run keyed by their digest, serves the repeat fetches of the same run and clears at the run end unless the user pins the profile cache; stepprefetch derives its likely next pages and selectors from the plan structure alone behind a gate that refuses anything outside the reviewed plan; the efficientresume checkpoints every step boundary with its cursor and page digest, skips the completed steps after a restart and revalidates the page fingerprint before it continues; navdedupe skips navigations to the already active url and folds repeated planned visits into one navigation; and sessionreuse attaches an authenticated profile to a run only through its explicit per profile consent prompt with the cookies isolated per task through separate containers. The durationmeter measures every step with monotonic clocks and writes its samples into the perf records of the 1.1.68 family, the selectorprofile counts the resolution time and the failure rate per selector and flags the selectors above the user latency threshold in the dashboardpage chart, the steptrace spans nest per step and per worker task and export as one trace file for the timeline view, the startupmeter measures the cold start from the startup event to ready with the lazymods budget spent and the coldstart keeps the ready path under the user target with the heavy modules out of the first paint path, the artifactcompress compresses captures and logs at rest through the user codec and decompresses them lazily on read, the logprune removes whole sealed runs past the user age and size windows only so the chain stays verifiable, the batteryaware scheduler defers non urgent scheduled runs on a low battery and surfaces the deferrals in the attentionfeed, the networkaware retry policies adapt their backoff to the failure kind and honor the server signals when present, readparallel groups independent page reads into parallel lanes under the user ceiling and joins them before the dependent steps, warmselectors carry validated selectors between adjacent steps and revalidate on a fingerprint change only, and slowmo replays a recorded run at the user chosen speed factor riding the runreplay service with its inspection pauses linked to their steptrace spans. The scheduling model ships in six pure modules (batchscheduling, runbudget, stepmeter, runresume, resourceaware, runparallel) beside the schedulereport protocol envelope, fifteen new memory accessors, sixteen new policy gates that keep every budget, limit, window and factor a user choice with no hidden cap, and the schedule command family with its schemastrict grammar in the background beside the executor instrumentation (the navdedupe skip, the timeout race with its logged cancel event, the suspend plan on long waits, the runcache serve and store on fetch steps, the monotonic metering, the selectorprofile and steptrace recording beside every step outcome, the runbudget evaluation with its critical pause, the resume checkpoints at the step boundaries and the run end sweeps of the runcache, the checkpoints and the suspend states). The optionspage gains the full scheduling and budgets section, the sidepanel gains the batch lanes with the timeoutcancel events and the dashboardpage gains the budgetalert and selectorprofile views. The action kinds stay at 334, the manifest permissions and the pinned identity key stay untouched, and honest notes: the timeoutcancel races the dispatch from the runner side, so an aborted step's underlying page work may still settle in the background while the outcome records the abort; the memory pressure ratio derives from the worker queue telemetry (the deferred share of the queue depth) because the service worker exposes no heap meter; the battery level reads through the schedule command and the deferral state stays advisory; and the logprune plan reports alongside the existing sealed log retention path rather than replacing it. Every limit, delay, window and budget stays the user's choice: performance work optimizes, never caps, and never bypasses the review.

## 1.1.68

This release starts the performance work. `lazymods` keep the heavy parsers and the capture, compare and export families out of the startup path: every lazy module declares its id, its load reason and its capability requirements ahead of load, the loader resolves a module on first use under exactly the capability checks the eager path runs, the prewarm hook warms the user chosen set on startup, and every resolution records load telemetry for startup analysis while the user configured startup module budget reports overruns without ever refusing a load. `debouncedom` coalesces scroll, input, resize and mutation storms per user configured window with no engine default, the dom observer folds rapid mutation bursts into one batch, and `batchquery` plans fold repeated selectors so one snapshot costs a single query pass that executes as one offscreen worker task. `incrsnapshot` computes deltas against the base snapshot of the same run with stable region fingerprints, emits only the changed regions, returns the full snapshot on the user configured cadence, and lets the executor skip the recomputation in full when the delta comes back empty; the observation schema gains its delta flag, progress deltas reuse the same change format, and identical snapshot requests within a run deduplicate through the executor request cache. `selcache` caches selector resolutions per generation, advances the generation on every mutation batch, invalidates wholesale on navigation and selectively on matching mutation fingerprints, revalidates every hit before dispatch, and refuses stale generation hits with an errorsurface retry hint that routes through a fresh reviewed dispatch. `virtlist` renders long lists through a virtualized window with measured height maps and recycled row nodes across the datagrid, the logstream, the stepstimeline and the compareviewer. `streamparse` tokenizes pages too large for one pass chunk by chunk inside the worker pool, yields observations progressively as each chunk completes, never holds the full page text in memory, and passes every chunk through the same schemastrict validation; `chunkextract` slices big tables into resumable row windows that carry their table fingerprint, emit partial extraction results the datagrid appends as they arrive with a cursor progress line, and resume after an interruption once the fingerprint verifies. The worker queue gains backpressure that defers parse tasks past the user configured depth instead of refusing them, records its depth over time for tuning, cancels abandoned parse tasks when a run halts, and defers heavy capture work behind the user speed or evidence priority choice; every step records a perf record with duration, query counts, cache hits and provenance beside its outcome, the sidepanel run footer shows the query counts, cache hits and selcache generation, the stepstimeline shows parse durations, the popup shows the active worker queue depth, and the dashboardpage renders a perf summary per recent run with a step duration chart. Honest notes: the virtlist window, the worker depth, the debounce windows, the snapshot cadence, the chunk bounds and the capture priority stay user choices with no engine defaults because performance features optimize and never cap, the manifest permissions and pinned identity key stay untouched, and the action vocabulary stays at three hundred thirty four kinds; the optionspage gained the performance section while the 1.1.60 smoke-test lesson applies only to manifest changes, which this release does not make beyond the version field.

## 1.1.67

This release completes the ecosystem by taking the reviewed core out of the browser and into every runtime. `planlint` checks plan files on disk against the same policy engine the extension uses, refusing drifted vocabularies, ungated sensitive steps and origin violations before anything runs; `flowrun` executes an exported plan headlessly from a terminal through the same review gates, printing step outcomes as they land; `exporttools` move runs, extractions, datasets and notes to disk as reviewed artifacts with checksums. The `headlesslib` entry drives a remote browser session without any extension surface while keeping the consent model intact, and the library now builds once into esm, cjs and umd bundles with complete type definitions: neutral `platformtargets` and `runtimeadapters` carry one core into `node.ts`, `bun.ts` and `deno.ts` entry points, so any runtime, any gateway and any llm speaks the same protocol the browser ships. The action vocabulary stays at three hundred thirty four kinds, the manifest permissions and pinned identity key stay untouched, and every new surface inherits the same session, plan approval and origin gates established since 1.1.32; the build pipeline grows the three library targets without changing the packaged extension bundle.

## 1.1.66

This feature release opens the ecosystem layer on the interface foundation of 1.1.65. The flowlibrary lets users browse, install, fork and share workflow templates: every browsed manifest validates under schemastrict before anything else (id, title, description, version, publisher, steps, kinds, required grants, data expectations with their minimization hints and the sensitive mark, with unknown fields refused and every error naming its path), its action kinds stay inside the installed capability set so a template that needs a capability the user never granted refuses in full, its required origin grants surface as a grant diff that maps onto originprofiles at import time before any import completes, a sensitive manifest installs only after a fresh consent prompt, an entry from an unverified publisher quarantines until the user verifies it and a present publisher signature verifies against the sha-256 digest of the manifest body (the seal covers the publisher, the digest and the provenance, and a signature over any other body refuses in full) while every completed install lands as a pending workflow import that still passes the same import and plan review as a native task, the installer resolves the manifest into a native workflow record with its selector namespaces rewritten for the local profile, the updater diffs versions before it replaces a local entry, removal keeps local forks untouched, and forking creates an independent local workflow that owns its name from its creation on; the dashboardpage hosts the library browser with search and filters showing the publisher, version and required grants per entry, the full step list before install and the grant diff dialog, the sidepanel lists the installed entries beside the native workflows with fork and remove actions, and the onboarding walkthrough gains an optional library stop. The syncbridge moves manifests between machines behind an explicit opt in with no default on: the file provider pulls and pushes through manual import and export payloads that carry manifests and their digests only (a payload that carries a secretvault value shape or a log entry refuses in full under any flag), the web provider stays an honest stub behind the opt in gate until the ecosystem part two backend exists, every hook keeps its user configured endpoint with nothing hardcoded, and the manifest digests detect conflicts so both versions surface instead of a silent overwrite with local, remote and merge resolutions recorded once each; the optionspage manages the providers and their opt in states and shows the conflict records with their resolve actions. The background run queue keeps workflows executing without an open surface: a queued workflow needs its approved review exactly like a foreground run, the executor picks the oldest entry, a running entry holds the keepalive signal of the run state family for its whole duration with every checkpoint restoring it on each worker wake, the queue state persists for restart recovery so interrupted entries requeue after a service worker restart, and the dashboardpage shows the queue with its progress while the popup recenttray grows a background section; the attentionfeed collects every gate wait, phishguard block, deferral and failure as one entry with its cause, run and gate refs and its deep link to the exact waiting surface, deduplicates repeated causes per run while the first occurrence keeps its time, ranks the entries by cause severity, renders them as content free system notifications (the notifications permission stays outside the manifest, so the payloads ride the broadcast channel, the stored history and the badge) and counts them on the statusbadge beside the waiting gates, with the retention window a user setting and the onboarding stop optional. The runreplay walks a sealed chain step by step for audit: the replay opens only a sealed run whose chain verified, derives one replay step per verified log entry with the restored observation version and capture id of each step and its gate resolutions, and the viewer steps forward, backward and to any chosen step or plays and pauses through the recorded chain while every viewer action records in the audit trail and the cursor persists per viewed run; the sidepanel renders the stepstimeline with the replay cursor, the restored observation and capture per step and the play, pause, step and jump controls. The outputcompare sets two competing runs beside each other: only runs that share a task input signature (the same workflow step kinds and objective) compare, the join pairs the runs on their step sequence, each pair grades its agreement, divergence and duration delta, the first divergent step highlights, the metric set the session used records in the audit trail, and the comparison reads the stored runlog outcomes only without ever executing a step. Under the surfaces one ecosystem command family rides the same schemastrict grammar, the same audit trail and the same broadcast channel with twelve new policy gates (the library manifest schemastrict gate, the capability set gate, the required grants gate, the sensitive fresh consent gate, the publisher quarantine gate, the import proposal gate, the syncbridge opt in gate, the syncbridge manifests only gate, the runreplay sealed chain gate, the outputcompare shared signature gate, the outputcompare read only gate and the background run review plus keepalive gate), a libraryversion field on imported workflow records, and the memory seam storing the flowlibrary entries deduplicated by manifest digest with their provenance per profile workspace, the library install and removal events, the syncbridge hooks and conflict records, the attentionfeed entries with their configurable retention, the runreplay cursors per viewed run, the outputcompare sessions with their metric results and the background run queue state, beside the ecosystemviews protocol envelope; the immutable run log gains the library and background event kinds so every library install, update and removal and every background run start and completion record in the chain. Honest notes: the publisher signature is a self-certifying sha-256 seal over the manifest digest and provenance rather than asymmetric publisher keys (a future release may add them), the web provider is a stub that ships no network call, and the marketplace registry remains the documented memory adapter seam — no registry url is hardcoded anywhere. No bound, window or endpoint is hardcoded: the attention retention window and every registry endpoint stay user choices, the manifest permissions and key stay untouched, and no ecosystem operation ever bypasses the human review. The vitest suite grows to 1267 tests on plain fixtures.

## 1.1.65


This feature release finishes the interface layer that 1.1.64 opened. The datagrid arranges every extraction result into columns and rows with the column types inferred from the observed values (numbers, booleans, iso dates and text), sorts and filters rows locally inside the surface and selects an inclusive row range for a partial export, while the exportmenu offers the csv, json and clipboard formats scoped to the selection, one step or the whole run and writes masked values only, honoring the maskinputs verdicts so no clear sensitive value ever leaves the grid. Quickactions bind the context menu entries of the active tab (extract page, capture shot, run recent and open dashboardpage) behind the origin allowlist of the clicked tab so only permitted actions surface (the manifest permissions stay untouched, so the entries ride the surface family and the popup quick action list rather than a declared contextMenus permission, and the changelog says so honestly), shortcutkeys bind run, pause, resume, cancelrun and the commandpalette to user editable combinations that dispatch only through the same palette action gate with its gates intact, and the omniboxtask parses the keyword text into a taskinput submission that lands in exactly the same proposal and review flow as the api (the omnibox keyword itself stays outside the manifest by the same permission rule, so the parser serves the surface family entry point that routes every goal through the reviewed plan). The statusbadge derives its idle, running, waiting and attention states from the run state and counts the waiting gates on the toolbar icon through the action badge the manifest already declares; notifydone fires on run completion with a deep link to the runsummary and notifyattention fires on gate waits, phishguard blocks and deferrals with a deep link to the exact waiting step, every notification respects the os do not disturb state and a body that carries page content builds only after its content consent (the notifications permission deliberately stays outside the manifest, so the payloads ride the broadcast channel, the badge and the stored history with their deep links instead of os toasts); the recenttray lists the latest runs in the popup with resume for halted runs and reopen for completed ones inside a user configured depth; and the stetoasts confirm step completion with the step kind and its duration, stacking inside a user configured live count with the full history queryable. The pickeroverlay starts from the sidepanel, lists the element candidates of the granted origin with stability scored selectors (an id anchor, stable attributes, an aria role and a unique text each lift the score while a positional shape lowers it) and locks one candidate for the proposed step; the targethalo outlines the active target element during a run with its color following the step state; the guidedtips explain the selector choice during picker sessions and dismiss and recall from the optionspage; the shotpanel previews captures per step with their provenance and redaction verdicts behind the granted origin gate and zooms and pans the large stitched captures; the compareviewer pairs the before and after captures of every executed write step and overlays the two with a slider; and the pagechips render inline confirmations anchored to the target element with approve and reject actions whose resolutions write to the immutable log exactly like stepapprove, one distinct human action per step. The siteprofiles store the per site theme, shortcutkeys and default view beside the originprofiles policy preferences and activate automatically on their origin while never adjusting a policy gate; the darklight theme follows the os preference with a manual override and the siteprofile layer first, and its tokens cover every surface including the dashboardpage through shared custom properties with the shipped colors as fallback; the locale bundles ship the interface strings of every supported language (english and portuguese) with an english fallback for missing strings and per language date, number and duration formatting; the importexport bundles move the originprofiles, the siteprofiles, the notes and the preferences between profiles while the secretvault values and the unmasked logs never enter any bundle under any flag — the validation refuses a bundle that carries either in full — and the dropimport accepts the csv, json and workflow files the user drops on the optionspage and the dashboardpage with its file kind detection; the featuretour replays the onboarding walkthrough on demand with added stops for the datagrid, the compareviewer and the pickeroverlay; and the a11ylabels name every control across the popup, the sidepanel, the dashboardpage and the optionspage with role, name, state and value for screen readers, following the language of the interface through the same locale bundles. Under the surfaces one views command family rides the same schemastrict grammar, the same audit trail and the same broadcast channel, with eight new policy gates (the quickaction origin allowlist gate, the omniboxtask proposal gate, the shortcutkey palette binding gate, the notification content consent gate, the pickeroverlay granted origin gate, the shotpanel granted origin gate, the siteprofile https gate and the importexport secrets and unmasked logs refusal gate) and the memory seam storing the siteprofiles per origin, the shortcutkeys bindings and the theme preference per profile, the recenttray entries with their configurable depth and the notification consent and preference per profile. No depth, live count, zoom factor or bound is hardcoded: the recenttray depth, the steteoast live count, the theme preference and the interface language stay user choices with no engine cap, the manifest permissions and key stay untouched, and no interface element ever bypasses the human review. The vitest suite grows to 1229 tests on plain fixtures.

## 1.1.64

This feature release gives the interface its first five full surfaces. The popup grows into a command surface: a taskinput box submits natural language goals that attach the active origin and the page outline and route through exactly the same proposal flow as the api (the status line walks idle, generating, ready and failed while the plan builds), quick actions offer run, pause, resume and cancelrun through the command bus, the origin allowlist state and the environment status stay visible, and the onboarding walkthrough card walks a first install. The sidepanel becomes a workspace with plan, run and review tabs: the taskinput sits at the top of the plan tab, and the review tab renders plancards — one card per proposed step with its kind, risk class, execution environment, reviewed options and the matching corrections from correctionmemory, grouped by risk class with the sensitive classes expanded by default — beside stepapprove buttons that resolve exactly one step per distinct human action (approve, reject or edit, with the edited shape riding the plan and the correction memory recording the change, and the resolution landing in the immutable log), diffpreview buttons that compare the observed before state with the predicted after state of write class steps only (added, changed and removed fields with masked values carrying their mask verdicts, and generation offloading to the offscreen worker pool above the user byte ceiling), a stepstimeline whose nodes derive from the progress records with no new state (pending, running, waiting, done, failed and halted statuses with durations, environment badges and deep link anchors), and a live logstream whose events carry level, source, step ref and the mask verdict of their source payload behind a sha-256 hash chain verified live as entries arrive, with pause, level filtering and the copy of a verified range as an audit excerpt that refuses to leave the stream while the chain is broken. The dashboardpage opens a full page view in a new tab from the popup and the sidepanel and through the new tab chrome url override, aggregating the sessiongrid and historysearch of 1.1.63, the site notes, the transparency views and the onboarding state; the optionspage gathers every setting into one page with sections (the onboarding replay, the palette recent window and shortcut, the logstream live buffer bound, the taskinput history retention, the diffpreview offload ceiling, the session interface options and the embedded transparency, consent and security sections of the earlier releases) where every write takes effect without reloading the extension; and the onboarding runs once on first install, walks the origin grants, the plan review, the run control and the log audit, replays on demand from the optionspage and writes exactly one consent scoped event on full completion. A commandpalette opens from a keyboard shortcut in every surface, registers its catalog from every module at startup, lists only the actions the current capability set allows, fuzzy searches ids, labels and keywords and ranks the recent commands first through the stored usage counts. Under the surfaces one command bus routes every surface action through the same policy gates (the palette action gate behind the existing permission of each command, the taskinput proposal gate, the plan review gate requiring the plancard review before any execution, the stepapprove gate with no batch approval and no background provenance, the diffpreview write class gate, the onboarding consent gate and the logstream egress gate for the verified range copy) and records each routing in the audit trail, while one broadcast channel carries run state, logstream frames, session store updates and settings changes to every surface that subscribes. No window, bound or ranking depth is hardcoded: the palette recent window, the logstream live buffer bound, the taskinput history retention and the diffpreview offload ceiling all stay user choices with no engine cap, the manifest permissions and key stay untouched beside the optionspage entry and the dashboardpage chrome url, and no interface surface ever bypasses the human review. The vitest suite grows to 1192 tests on plain fixtures.

## 1.1.63

This feature release turns the session itself into the primary interface. A sessiongrid now lists every live and saved run as one filterable grid row derived from the existing session stores with no new state — each row carries its session and run ids, its origin set, its step count, its state and outcome, the per tab lock state of concurrent sessions, the seal hash link to its sealed log chain and the resume, cancelrun and reopen actions the row offers — while a historysearch box indexes session metadata, site notes and run summaries into one incremental corpus written on each store change and serves text queries with origin, time range and outcome filters and the matched terms highlighted, emptystate guidance explains the first run, the first query, the note flow and the agent scratchpad whenever a surface holds nothing to show, and errorsurface payloads classify every failed step cause as page, network, policy or gate with a retry hint that carries the policy verdict (a retry passes only through a new reviewed dispatch that rides the full consent gate chain, never an automatic one). Behind the surfaces the agent gains five session stores scoped per profile workspace: sitenotes keep one record per origin with title, body, author provenance and timestamps while sensitive bodies seal at rest with a local keystream so the plain text never persists, the scratchpad holds append only entries per task with timestamps and step provenance that the executor appends live beside every step outcome and prunes only at the user configured window, runsummary distills a completed run into the origins visited, the kinds executed and the per step outcomes inside the user configured length window (no fixed cap, and the distillation runs as one offscreen worker task under the granted capability with an inline fallback), semanticrecall embeds past extraction records into a local fingerprint indexed corpus that deduplicates repeated extractions and ranks matches by text similarity inside the run scope with the run id and step id provenance of every match (a query across origins outside the run scope refuses), correctionmemory captures both the step edits of replan reviews and the rejected steps of plan rejections per origin and kind and feeds the matching history into later proposal reviews, and consentmemory records every grant, denial, expiry and revocation per origin with its boundary and expiry fields as advisory history that surfaces inside the consent prompt yet never auto grants, with denials carrying the same weight as grants. cancelrun arrives as a first class action with a rollback option descriptor: the queued scope rolls only the queued steps back while the executed steps stay untouched in the sealed immutable log, and the user preference picks the queued or the none scope. The sidepanel gains the session grid with its row actions, the history search box with highlighted hits, the inline site notes editor, the live scratchpad and one session memory section with the run summaries, the semantic recall results while planning, the past corrections, the consent decisions and the error surfaces with their reviewed retry buttons; the popup shows a compact session grid of recent sessions with deep links that open the sidepanel run view; the declared options page configures the recall index window, the retention windows of the notes, the scratchpad, the summaries and the corrections, the summary length window, the historysearch index toggle and the cancelrun rollback preference; per tab session references isolate parallel tabs so they never collide; and the notes, summaries and corrections export as one audit bundle with sensitive bodies staying sealed. The consent gates do not move: every interface action rides the same session, plan and origin review, sitenotes reads stay inside the granted origins, writes need explicit consent, scratchpad access stays inside its owning task session, and the correction and consent memory reads open during planning and prompting alone. The vitest suite grows to 1161 tests on plain fixtures.

## 1.1.62

This feature release finishes the security core by protecting secrets, messages and money: a secretvault keeps passwords and tokens behind a vault seam whose persisted records carry only labels, exact origin scopes, profile workspaces, provenance and sha-256 digests (no plaintext value ever reaches a storage writer, log entry or export; the leak scan refuses plan texts, variables and step options whose value digests to a vault record and raw typed values behind masked field shapes never ride a step, while credential steps resolve vault id markers at the last possible moment so the value flows from the vault to the field with no logging), redactshots mask sensitive capture regions derived from field shapes or drawn by the user across viewport, element and stitched captures alike with the overlays drawn before every shot and the records carrying the redaction evidence, schemastrict validates every inbound command before dispatch and rejects unknown fields with the path and expected shape while echoing no payload, origincheck verdicts guard every runtime message and every port connection and connectallow drops every sender absent from the user managed list that ships empty by default, ratelimit buckets bound automation commands per origin and per session by deferring past the user configured bound until the window resets with no hidden ceiling, confirmpay, confirmdelete and confirmcreds put one distinct human action in front of payments (amount, payee origin and target element), destructive deletions (target, scope and irreversibility) and credential use (label only, never the value) with no timeout ever resolving a gate and no batch approval resolving two, phishguard watches login targets for lookalike origins against the granted origins under the user threshold and blocks with the matched known origin named while verdicts expire past the freshness window, safedefaults profile unknown origins as reads only with every sensitive class denied until the user widens the profile in the editor the popup notice links to, extracted markup grades untrusted before any render and routes through the 1.1.60 sandboxframe while page context injection refuses, and every installed update records its permdiff for the new transparencypage — the declared options surface that lists every active grant with its revoke action, every consent window ever granted with its expiry, the connectallow senders, the permdiffs, the safedefaults applications and the secretvault labels, served by one memory read — all without adding a single action kind (the reviewed vocabulary stays 334 kinds), without touching the four required permissions, the optional capability set or the pinned manifest key (the manifest only declares the transparencypage options surface), and without hardcoding anything: the lookalike threshold, the verdict freshness, the ratelimit bounds and the redact regions are user choices with no engine defaults. Six new root modules group the logic (secretvault, redactshots, inboundguard, confirmgates, phishguard, transparency), policy gains fourteen gates, memory gains the security part two persistence with the transparency one read, the immutable log gains the gate, phish, schema and inbound event kinds, and the vitest suite grows from 1052 to 1130 tests on plain fixtures covering the schemastrict rejections with path and expected shape, the origincheck on the message and port paths, the connectallow drops for unknown senders, the ratelimit buckets with deferral and reset, the three confirm gates with their no batch and no timeout refusal paths, the secretvault flows with no plaintext persistence, redactshots across every capture kind, the phishguard verdicts at the threshold boundary, the safedefaults application to unknown origins and the permdiff computation between two permission sets; docs/16.securitymodel.md documents the vault, the gates, the guards and the permdiff.

## 1.1.61

This feature release hardens the trust boundary itself: automation now runs behind a per origin automation allowlist under a denydefault posture that refuses every ungranted origin before any step dispatches, per site originprofiles grant and deny single action kinds, consentwindows bind every sensitive grant in time with a duration the user chooses and a boundary the prompt always names (no grant ever defaults to unlimited, a window past its boundary suspends the run mid step and the executor refuses to resume without a new explicit prompt), revokerun halts the pending step and every queued step without executing them as a terminal session event, sensitive kinds classify into the payment, credential, delete and publish classes refined by their kind options rather than kind names alone with uploads, downloads and evaluate sensitive by default and credential bearing form submits in the credential class so each class needs one fresh consent prompt per origin, every step transition, grant, expiry, revoke, deny and suspension lands in an append only immutablelog whose loghash chains each entry to the sha-256 of its predecessor at append time with no update or delete path, the session close seals the chain with a final hash, the audit accessor verifies the whole chain before serving a single entry and refuses reads of a broken link as tamper evidence, and maskinputs keeps typed values, form values and stored values out of every log, observation and export behind the documented password, token, card and secret field shapes the user extends with global and per origin mask rules — all without adding a single action kind (the reviewed vocabulary stays 334 kinds), without touching the four required permissions, the optional capability set or the pinned manifest key, and without hardcoding anything: the consent window duration, the sealed log retention and the mask shapes are user choices with no engine defaults. Three new root modules group the logic (`originpolicy.ts` with the denydefault allowlist checks, exact origin matching with no wildcard expansion, the active tab as exactly one explicit single origin grant, the profile grammar, the sensitive classification, the consent windows, the renewals and the revocations; `immutablelog.ts` with the hash chain append, seal, verification and export arithmetic; `maskinputs.ts` with the shape recognition and the log, observation, storage and export masking), the policy gains eight gates (automationallowlistgate, originprofilegate, consentwindowgate, revokerungate, sensitiveclassgate, sensitivepipelingate, consentdurationvalid and logreadgate), the protocol gains the consentmodel, securityreport and logchainreport envelopes, the memory store persists the allowlist per profile workspace, the originprofiles, the consentwindows with their expiry sweep, the class consents, the revocation history, the mask rules and the sealed immutable logs with an adapter seam documented for the future append only backend, the progress log records denied steps with their deny reason and revoked runs as halted with the revoked step, the background executor checks the allowlist, the profile, the window and the class consents before every dispatch, records allowlist misses as denied events without navigation, appends every step transition to the session log with masked values, writes the consentscope grant into the log at session start and seals the log at session close, the page bridge masks typed values and form state before they reach the log writer, the sidepanel gains a Security section (the allowlist editor, the origin profile editor, the consent windows with their remaining time and renew action, the consent prompts with their class badges, the revoke confirm dialog naming the halted steps, the mask rules, the redacted field notes and the per run chain verification with the seal hash and the audit file export) and the popup shows the origin allowlist state of the active tab with its grant request, the originprofile summary, the consent window countdown and the denydefault notice. The test suite grows from 1012 to 1052 plain fixture tests with no jsdom covering the denydefault refusals, the exact origin matching, the consentwindow expiry mid run, the revokerun halts, the hash chain across append, seal and read, the tamper detection on a broken link, the maskinputs across log and observation paths, the sensitive class routing through the consent gate and the originprofile grants and denials per kind, plus the new persistence, evidence and envelope paths. Known honest limits: the browser storage areas offer no append only hardware, so the immutable log derives its integrity from the sha-256 hash chain that makes any rewrite detectable at read time rather than from a write once backend; the consent prompt durations, the retention windows and the mask shape lists carry no engine defaults because they stay the user's choices.

## 1.1.60

This feature release opens phase four by giving every reviewed step a concrete execution environment — heavy parsing moves into offscreen documents and a pool of offscreenworker threads, injected logic stays inside an isolatedworld that page scripts cannot touch, untrusted markup renders only inside a sandboxframe, and a keepalive signal holds the service worker alive for the whole run — and it lands without adding a single action kind (the reviewed vocabulary stays 334 kinds), without touching the four required permissions or the pinned key, and without hardcoding anything: the worker pool size, the parse offload toggle, the keepalive heartbeat interval, the zombie tolerance, the run state retention and pressure ceiling, the sandbox origin list and the environment grants are all user choices with no engine cap, and every environment executes only reviewed steps of approved plans against granted origins because no environment ever bypasses the human review. Three new root modules group the logic: `environments.ts` groups the environment grammar (the per kind requirement table where evaluate is isolatedworld only, a step carrying untrusted markup is sandboxframe only, the six parse families — html snapshots, network json payloads, table row reductions, accessibility tree shaping, complex selector evaluation and screenshot stitching — choose between pagecontext and offscreenworker, and every other kind keeps the pagecontext of the page bridge because page events only fire there, the executor registry mapping each environmentkind to its runtime adapter, the routing with the inline fallback, the worker request and response envelopes with their transferable plan and streamed partial results, the worker pool plan that grows and shrinks with the pending parse queue under the user configured size, the offscreen document lifecycle spawning on first use, reusing one document across the steps of a run and closing at completion, and the isolated world injection carrying reviewed arguments only); `sandboxframe.ts` groups the untrusted markup rules (the script and event handler stripping before any render, the per render nonce, the postmessage envelope on the devthinksandbox channel, the nonce checked acceptance that keeps render results from ever reentering the dom outside the frame, and the provenance with source origin and nonce); and `runstate.ts` groups the typed run state (openrun, beatrun and closerun with the port lifecycle events, the reattach after a service worker restart, the url history of every navigation inside the run, the environment and worker turnaround of every step, the recovery plan that resumes exactly the pending step, the zombie reaping past the tolerated silent intervals, the storage level run lock holding one session against concurrent runs, the serialization of steps that share one tab across parallel branches, the sha-256 integrity sealing of persisted run state, the quota pruning under pressure and the single record export). types.ts gains environmentkind, the environment requirement profile, the worker traffic envelopes, the sandbox render descriptors, the keepalive state with its events, the run state record with url history, environments, turnarounds and provenance, worker events, the offscreen registry entry, the run lock and the sealed run state envelope (about twenty contracts) plus the toolstep environment field, the session environment grants that join the origin grants, the observation and stepoutcome environment fields, the parseoffload, workerpoolsize, runstateretention, sandboxorigins, keepaliveinterval, zombieintervals and runstatebytes run settings and the environment, worker and sandbox audit kinds. policy.ts gains eight gates: stepenvironmentvalid of the environment field of every step kind, environmentgrantgate refusing steps whose environment sits outside the session grant list, offscreencapabilitygate refusing offscreenworker steps when the grant is absent, keepalivegate limiting the port to sessions with an active reviewed plan, keepaliveintervalvalid and workerpoolsizevalid as positive user values with no engine cap, sandboxorigingate carrying the per origin render toggle and environmentrequirements exposing the per kind table. protocol.ts gains the environment grammar envelope with its consent notes and the environment report envelope while the response envelope returns the environment beside the step outcome; progress.ts records the environment of each completed step and the worker turnaround for profiling. The manifest adds the optional offscreen permission to the capability set, declares the offscreen document with its DOM_PARSER and WORKERS reasons and justification, lists the sandbox page under the sandbox key with no extension privileges and registers content scripts in the isolated world by default with an empty match list so injection stays behind the granted scripting calls; the cli manifest validator allows the sandbox key and the offscreen declaration, keeps the privileged pages out of the sandbox and refuses any non isolated world registration. memory.ts seals every persisted run state with a sha-256 digest through the storage api (the browser offers no at-rest encryption for its storage areas, so the honest derivation is the integrity seal that makes tampering detectable before any recovery uses the record), scopes run state per profile so parallel profiles never share it, expires stale stopped runs to their keepalive summaries under the user configured window, tracks the storage quota usage and prunes the oldest finished run states under the pressure ceiling, stores worker spawn and teardown events with provenance, the offscreen registry with reasons, sandbox renders with source origin and nonce and the run locks, and documents the adapter seam for the future worker state backend. background.ts negotiates the offscreen capability through the permissions api, routes every dispatched step through the environment gates before the page dispatch (the sandboxframe renders strip and nonce inside the sandboxed page, the isolatedworld evaluate rides the scripting api with reviewed arguments, the offscreenworker parses ride the worker pool with the turnaround recorded, and every other step keeps the page bridge), opens the keepalive port behind the keepalive gate with the run lock, persists the run state on every heartbeat, resumes exactly the pending step after a service worker restart, reaps zombies, closes the offscreen document when the run completes, serializes shared-tab steps across parallel branches, and audits environment grant, worker spawn and sandbox render events in the three new audit kinds. The popup shows the active environment status per running session with the keepalive heartbeat indicator, the zombie run warning with its reap action and the offscreen grant request; the sidepanel gains the environments panel with the environment badge on each step row, steps grouped by execution environment, worker activity counts and turnarounds, the offscreen registry, sandbox renders, the url history of the open run, the restart recovery notice with the resume action, the run locks, the environment grant editor that links to the same consent flow the origins use, the offscreen capability request and the per profile options of the parse offload toggle, the worker pool size with no hard cap, the sandbox origin list and the keepalive documentation. The vitest suite grows from 969 to 1012 tests over pure fixtures without jsdom: environments tests cover the routing of every reviewed action kind, the isolatedworld and sandboxframe exclusivity, the offload families, the executor registry, the routing fallbacks, the worker round trips with transferables and partial streams, the pool plan, the offscreen lifecycle and the isolated injection; sandboxframe tests cover script and handler stripping, noncing, the postmessage round trip, the refusal of stale and off channel messages and the render provenance; runstate tests cover the heartbeat emission and port closure, the reattach, the url history, environment and turnaround records, the recovery plan, the zombie detection and reaping, the concurrency lock with its expiry, the shared tab serialization, the integrity sealing with tamper refusal, the quota pruning and the export; and the policy, protocol, memory, progress and manifest suites extend for the eight gates, the two envelopes, the sealed per profile persistence with expiry, quota and provenance, the environment and turnaround evidence and the new manifest keys. Honest limitation: the worker pool runs only when the user grants the optional offscreen permission — without it every parse heavy kind keeps its inline fallback inside the page, the sandbox frame needs an open host surface (the granted offscreen document or the review panel) to render, and the offscreen declaration in the manifest is a reviewed declaration the runtime api reads rather than a browser enforced manifest key.

## 1.1.59

This feature release completes the multi agent phase with orchestration on top of the 1.1.58 swarm — leader worker topology, planner executor separation, critic review and verifier agents, tab handoffs mid run, resource locks with conflict scans, result merging into one report and a progressboard that shows every agent at once — and it lands without adding a single action kind (the reviewed vocabulary stays 334 kinds), without touching the manifest permissions or the pinned key, and without hardcoding anything: the election rule, the worker scale bound, the consensus quorum, the lock kinds and expiries, the merge rules and the verifier method list are all user choices with no engine cap, and every coordinated action still passes the same human review a single agent passes because orchestration never bypasses review. Two new root modules group the logic: `orchestration.ts` groups the leader worker and verification flows (electleader by the user rule of first registration or one named agent with the leader, worker, critic and verifier lanes, assignwork slicing tasks across workers, collectresults gathering the worker outputs with their pending status, scaleworkers adding or retiring workers by load under the user configured bound with no engine cap, the planner executor split that keeps plan drafting and execution in different agents with the executor reporting every step outcome back, requestreview and applyreview routing critic verdicts with ack and timeout, sweepreviews expiring unanswered requests past the user configured window, checkclaim recording pass or fail verifier checks with the method used, boardstate aggregating the agents, queue and topology into progressboard lanes with milestones, escalate lifting stalled decisions to the user with full context where they stay human decided, arbitrate ordering competing claims by the user rule of priority, age or leader, and the consensus rounds that carry at yes quorum); `coordination.ts` groups handoffs, locks and merges (preparehandoff packaging the tab and the task state, transferhandoff moving the tab binding under the one agent per tab rule while preserving the original session grants, resumehandoff continuing from the packaged state, acquirelock and releaselock with exclusive and shared kinds keyed by exactly one origin and one selector, expirelocks returning abandoned locks past their user configured expiry, scanconflicts detecting overlapping writes with a deterministic suggested ordering, mergeresults folding parallel values under first, last, preferagent or fail rules with every merged value keeping its provenance, swarmreport building the aggregate report across agents, compareoutputs contrasting competing outputs, interleavetimeline ordering the actions of every agent into one stream, sharelesson writing verified lessons to the blackboard, swarmcosts summing the per agent usage into the swarm totals and replayagentrun rebuilding one agent run from the audit trail). types.ts gains the leaderworker topology with worker assignments, criticreview and verifiercheck, the plannerexecutor split, handoff requests and records, resourcelocks, conflictscans, mergeentry and resultreport with provenance, the progressboard layout, review requests, escalation records, arbitration rules and consensus rounds (about twenty contracts) plus the swarmquorum, swarmworkers, boardretention and verifiermethods run settings; the agentrole union documents the two new internal roles critic (read only over agent outputs) and verifier (read side re-reads) beside planner, worker and observer. policy.ts gains ten gates: leaderelectionvalid of the user configured rule, criticreviewgrade keeping reviews read only, verifiermethodgrade against the methods the user allows, handoffgrantgate requiring the handoff to preserve the original session grants, lockscopevalid keeping one lock inside one origin, conflictresolutiongrade marking the overwriting merge rules sensitive, escalationgate keeping every lifted decision human, consensusquorumvalid of the user configured quorum, workerscalevalid bounding the worker scale by user choice with no engine cap and mergeegressgrade grading exported reports that include page content as data egress events. protocol.ts gains the boardstate snapshot envelope for dashboards plus the agents/handoff and agents/review event frames and documents the leader worker, handoff, lock, conflict and merge grammar. memory.ts persists the topology, the planner executor splits, the critic reviews, the verifier checks, the review requests, the handoff log with the resumed state, the locks, the conflict scans, the merged report, the progressboard snapshots under the user configured retention, the escalations, the consensus rounds, the interleaved swarm timeline with the getswarmtimeline filters and the shared cost accounting. background.ts adds the swarmleader (elect, assign, collect, scale, split, stepreport, milestone), swarmreview (request, ack, apply, sweep, verify, escalate, decide, consensus, vote), swarmhandoff (prepare, transfer behind the grant gate, resume), swarmlocks (acquire behind the scope validation, release, sweep, scan, arbitrate) and swarmmerge (merge, report, export behind the egress grade, compare, lesson, costs, timeline, replay, snapshot) handlers, records elect, assign, review, verify, handoff, lock and merge events in the swarm audit kind and feeds the interleaved timeline from the queue lifecycle too; the sidepanel agents tab grows the topology box with election, assignment, scaling and split controls, the progressboard with milestones, the review cards with critic verdicts and verifier pass or fail badges, the escalation inbox with user decisions, the consensus view with votes and quorum, the handoff log with transfer and resume, the lock view with expiry countdowns and releases, the conflict scans with the suggested ordering, the merged report preview with its export, the compare, lesson and cost controls and the interleaved timeline with replay; the popup shows the elected leader and the held lock count beside the swarm summary. The vitest suite grows from 921 to 969 tests over pure fixtures without jsdom: orchestration tests cover leader election, work slicing, collection, scaling, the planner executor split reporting, critic verdict flows, verifier pass and fail checks, boardstate, escalation, arbitration and consensus quorum math; coordination tests cover handoff prepare, transfer and resume, lock acquire, release and expiry, conflict scan detection, result merging under every rule with provenance, comparison, timeline interleave, lessons, costs and replay; policy, protocol, memory and multiagent tests extend for the ten gates, the three envelopes, the new persistence and the critic and verifier role defaults. Honest limitation: the orchestrating agents still execute through the same workflow engine and plan review, so the leader, critics and verifiers organize and judge work rather than run unreviewed page actions, and the arbitration of simultaneous lock claims orders the claimants while the lock acquisition itself stays first come first served.

## 1.1.58

This feature release opens the multi agent phase — several agents working at once over one shared context — and it lands without adding a single action kind (the reviewed vocabulary stays 334 kinds), without touching the manifest permissions or the pinned key, and without hardcoding anything: the agent count, the agent names, the roles, the lane names, the priority scale, the freshness windows, the claim windows and the sub agent depth ceilings are all user choices with no code cap, and every agent proposal still passes the same human review the single agent passed because multi agent coordination never bypasses review. Three new root modules group the swarm logic: `multiagent.ts` groups identities, roles and lifecycle (agent registration bound to one tab with the one agent per tab rule, role assignment with the documented defaults of planner, worker and observer plus any custom user role, sub agent spawning under a spawnrequest that refuses recursion past the user configured depthlimit, pauseone and resumeone for single agent isolation, stopone, the killall killswitch that halts every agent at once and returns the claims to the queue, the per agent budget check that halts an agent past its token, cost or step ceilings, the per agent scope gate that refuses origins and tool namespaces outside the grant, per agent usage accumulation, the per agent run contexts that reuse the workflow engine run records, the lifecycle events and the swarm overview); `taskqueue.ts` groups the shared queue (enqueue into user configured lanes with user configured priorities, claim of the highest priority task with the oldest task winning ties, work stealing between agents that respects the lane ownership rules the user configures, completion that releases the claim, claim heartbeats, the requeue pass that returns the tasks of dead agents whose heartbeats stayed silent past the user configured window, cancellation, the lane report and the completion policy of all or any); and `blackboard.ts` groups the shared memory (posting with authors into the goals, facts, findings and scratch sections, reading with freshness filters, retirement by the user configured window, cross agent visibility — every agent of the swarm reads the same board — and the consent class inheritance of the source extraction so a sensitive extraction stays sensitive on the board), while `agentmailbox.ts` groups the agent mailboxes (direct, broadcast and role addressed routing, inbox and outbox records with unread counters, and the receive drain with ack tracking; the user composes messages to any agent and policy grades the cross agent messages that carry page content as data egress events in the audit trail). Policy gains the swarm gates (queuelanesvalid of the user configured lanes, priorities and completion policy, workstealgrade that permits stealing only inside one user approved swarm with the lane ownership rules, agentbudgetvalid of positive user ceilings, agentscopevalid against the session grant list so no agent scope widens the session, spawngrade with the risk class of the requested role, killswitchgate that keeps the switch available with no configuration barrier, messageegressgrade and blackboardconsentgrade), the protocol gains the swarmstate envelope with the agents, the queue and the mailboxes plus the agents/notify lifecycle event frames and documents the task queue, mailbox and blackboard grammar, and memory stores the swarm as first class records (agent identities with their tabs and roles, the task queue with lanes and claims, the mailboxes with the user configured retention, the blackboard sections, the spawn and depth histories, the per agent usage against the budgets and the swarmoverview accessor). The background runs the swarm behind the same consent gates: the swarmagent handler (register, assign, bind, spawn behind the spawn grade and the depth limit, pause, resume, stop, killall with its claims release, budgets, scopes and heartbeats), the swarmqueue handler (configuration, enqueue, claim behind the killswitch, agent state and budget gates with the per agent run context, steal behind the work steal grade, complete with the usage counters, cancel and requeue), the swarmmailbox handler and the swarmblackboard handler, with every register, assign, claim, steal, complete, spawn, killswitch and pause event landing its swarm audit entry. The sidepanel gains the agents tab (agent cards with role, tab, current task, budget use and heartbeat, pause, resume and stop per agent, the killswitch button with confirmation, the task queue view with lanes, priorities and claims plus enqueue, requeue and cancel, the mailbox view with the compose form, the blackboard view with its editor, the spawn dialog and the lifecycle event feed) and the popup shows the swarm size and the active task count. The vitest suite grows from 861 to 921 tests over plain fixtures covering agent registration and role assignment, the one agent per tab binding, enqueue, claim and complete with priority ordering, work stealing with lane ownership, heartbeat expiry and requeue, mailbox send, receive and broadcast with role addressed routing, blackboard post, read and retire with freshness and cross agent visibility, spawn with depth limit refusal, pauseone isolation, killall cancellation, per agent budget halts, agentscope refusal paths, the queue, budget and scope validation gates, the swarmstate and agentevent envelopes and the queue, mailbox and blackboard persistence; docs/multiagent.md documents agents, roles and tabs, the shared task queue and work stealing, mailboxes and messages, the blackboard memory, budgets, scopes and the killswitch and sub agents with depth limits.

## 1.1.57

This feature release opens the heart of the product vision — any llm drives the extension — and it lands without adding a single action kind (the reviewed vocabulary stays 334 kinds), without touching the manifest permissions or the pinned key, and above all without hardcoding anything: no provider, no endpoint, no model name, no key, no temperature and no token ceiling ever ships in code, because every gateway url, base url, model name, protocol shape and parameter is a user configured value and the four protocol styles (the openai compatible chat completions shape, the openai responses shape, the anthropic messages shape and the google gemini shape) are wire shapes the user picks for interoperability, never provider allowlists. The new root `llm.ts` module groups the provider machinery: the request shaping per protocol style (with the key riding the bearer header, the x-api-key header or the url query the style expects, and the user configured headers merging over the shape headers so any gateway works), the response parsing per style with its usage token counts, the completion call through the established fetch machinery with its reviewed retries and backoff, the local model calls that refuse every non loopback endpoint so no call ever leaves the machine, the streaming token parse per style over server sent event bodies, the natural language command parsing with the deterministic intent classifier that works without any provider (the six intent kinds navigate, extract, fill, monitor, automate and ask with confidence thresholds), the goal to plan drafting, the replan of failed runs, the per step reflection with its running lessons, the openapi style tool briefs rendered from the tool catalog for model consumption, the parse guardrails that strip code fences and chatter, validate the model text against the expected schema, retry malformed output up to the configured count and refuse after exhaustion so invalid output never executes, and the usage records with the cost budget halts that ask the user at the ceiling. The new root `modelroute.ts` module groups the routing table: task kinds map to provider and model pairs the user picks, unavailable providers mark themselves after failures and the user configured fallback pair takes over on refusal, with no default route ever applying. The new root `promptlibrary.ts` module groups the user template library: variable extraction, rendering with the consent notice requirement of sensitive flows, versioning with change notes and search — no built-in template ships. Policy gains the model side gates: provider validation (user configured http or https endpoint, non-empty model list, one of the four wire shapes, auth references that carry storage ids and never key material), the data egress grading of every provider call for the audit trail, the explicit consent requirement before any page content leaves the browser, the local endpoint preference for sensitive extractions, the plan review requirement of model drafted plans, the fresh review requirement of replanned steps, the cost budget validation and the guard verdict gate; the plan lint checks every model drafted step against the action grammar before review. The protocol gains the modelproposal envelope that carries a drafted plan to the human review and the modeloutcome envelope that reports the usage totals with every guard verdict. Memory persists provider configs (references only, never secrets), the routing table with its revision history, every usage record with run and step ids, the plan drafts and replans, the reflection notes, the prompt template versions and the cost budgets, and answers token and cost totals per period. The background wires it: provider save, test call and removal handlers, the local endpoint save and health check, the route editor with revision bumps, the command parse that falls back to the deterministic classifier or the local endpoint when no route serves the task kind, the plan drafting through the routed model with lint, the draft decision that turns an approved draft into a pending plan that still passes the same plan review every local plan passes (model proposals never bypass review), the replan and its fresh review decision, the reflection of executed steps, the budget setter, the template library handlers and the llm state snapshot; every provider call lands one usage record and one data egress audit entry with its endpoint, model and token counts, every guard refusal lands its notice with the verdict reason, and api keys stay in the browser credential store behind their storage ids. The sidepanel gains the models tab — the provider list with endpoint editing and test call buttons, the modelroute table per task kind, the local model endpoint with its health check, the model drafted plan review cards with editable steps and approve or reject, the replan reviews with the highlighted changed tail, the reflection notes under the completed steps, the budget meter against the configured ceiling, the prompt library browser and the guard refusal notices — plus the natural language command box at the panel top with the intent badge, and the popup shows the active model per task kind. The vitest suite grows from 792 to 861 tests on plain fixtures without jsdom: the llm suites cover the request shaping of every protocol style, the response parsing per style with usage, provider calls against a stubbed endpoint (including the refusal paths of the missing resolved key, the ungranted page content and the malformed answer), local model calls with no external network, the streamed token parse, the command parsing across the intent kinds, the deterministic intent confidence thresholds, the plan drafting with grammar lint, the replan keeping completed steps with fresh review markers, the reflection with running lessons, the guardrail stripping with schema validation, retries and refusal after exhaustion, the tool briefs, the usage accumulation and the budget halts; the modelroute suites cover the task kind resolution, the availability marking and the fallback; the promptlibrary suites cover the render, the consent notices, the versioning and the search; the policy, protocol and memory suites gain the new gates, the envelopes and the persistence. The honest limitation stays: the extension runs in the browser, so the model calls ride the ambient fetch of the extension context and every remote endpoint must be reachable from it, while the local endpoint keeps sensitive work on the machine.

## 1.1.56

This feature release completes the agent protocol core trilogy and hands remote clients the full protocol surface without adding a single action kind — the reviewed vocabulary stays 334 kinds, the manifest permissions stay unchanged and the pinned key stays untouched — because 1.1.56 is a protocol completion release: paired clients now receive server events, page state deltas, sampling callbacks, prompt tools, streaming results, progress notices, in flight cancellation, per client rate limits, structured errors with retry hints, idempotency keys, batch calls, tool dry runs and tool mocks. The new root `agentstream.ts` module groups the streaming side of the protocol: the event subscriptions with their protocol event kinds (callstarted, callresult, streamchunk, progress, resourcedelta, sampling and cancellation), their optional origin and tool filters and the notification frames that push matching events to matching subscribers only, the resource watchers with their page state baselines and the page state deltas of the changed keys that absorb the baseline after delivery, the sampling callbacks that respect the client declared model capabilities (the capability set now carries sampling, prompts and streaming flags) and strip the page content unless the user granted it, the prompt defs exposed as callable tools (runreview, pagesummary and failuretriage) with their template rendering, required argument validation and reviewed defaults, the stream chunks of progressive tool results with their sequence numbers and done markers, the progress notices with their percent, message and cancel hint, and the cancellation frames that abort an in flight call while preserving its partial result. The new root `toolcalls.ts` module groups the call runtime: the per client rate limits that count calls inside their window, reset past it and answer excess with a structured error carrying its retry after while an absent limit or budget keeps the client unbounded because no silent default ever applies, the structured error mapping of executor failures with its retry hint classification of retryable timeouts, busy windows and consent refusals that never retry, the idempotency keys that replay the stored result of the same client inside their window and expire after it, the ordered batch calls that stop at the first error when the flag requests it, the tool dry runs that validate arguments against the tool json schema and evaluate the same consent gates without any execution, the tool mocks that answer declared tools with canned results only in test contexts and never touch the browser, and the call contexts that isolate the concurrent calls of concurrent clients with their idempotency key, dry run and batch markers, chunk counters and preserved partial results. Policy extends the protocol gates: `subscriptiongrade` grades a subscription read only when its filters exclude the callstarted mutation mirror, `samplinggrade` grades sampling callbacks sensitive behind the page content grant, `callratelimitvalid` validates the windows and budgets as user configured values with no silent defaults, `callauditcomplete` requires one audit entry for every tool call without exception, `batchgrade` grades a batch by its most sensitive member so a sensitive batch runs only behind the approval gates, `dryrunpurity` refuses any dry run record that claims execution or a page mutation, and `mockusagevalid` confines tool mocks to test contexts. The routing table grows by `prompts/list`, `prompts/call` and `calls/cancel` while the stateful `events/subscribe`, `events/unsubscribe`, `resources/watch`, `resources/unwatch`, `sampling/answer`, `calls/cancel` and `calls/batch` frames route through the frame intake with their persisted state; every tools/call frame now runs through the call runtime — the rate limit counts first, a repeated idempotency key replays the stored result, mocks answer only in test contexts, the armed or requested dry run evaluates without side effects, and the live call opens an isolated call context that emits the callstarted, progress, streamchunk and callresult events to subscribers, streams the result content in ordered chunks, consults the cooperative cancellation seam before and after the page executor (so a cancelled call stops anything further from running while its partial result survives) and lands its audit entry with its idempotency key and outcome; the tool call records gain the call id, idempotency key, dry run, mock, batch and replay markers, the maintenance sweeps expire idempotency records past their window with audits, and the subscribe, unsubscribe, cancel and mock events all land in the audit trail. The protocol envelopes document the whole family: the subscription frames with their filters, the event notification frames, the page state delta reports, the sampling frames with the exact prompt payload, the prompt tool report and call frame, the stream chunk and progress notice frames, the cancellation frames with the preserved partial result, the structured error report with its retry hints and usage, the idempotent replay frame and record report, the batch report with its per item outcomes, the rate limit usage report, the audited call log report, the in flight call report, the dry run report and the mock report. The sidepanel renders the live audited call log with caller, tool, outcome, idempotency key and replay, mock, dry run and batch markers, the per client rate limit usage bars with their reset windows, the in flight calls with cancel buttons, the streaming results as they arrive with the progress notices, the sampling callbacks with the exact prompt payload and the manual answer path for local testing, the subscriptions per client with unsubscribe and the resource watchers with unwatch, the batch call progress with per item outcomes, the tool dry run toggle for the next call and the tool mock editor, while the popup announces the long tool progress of the in flight calls when the panel stays hidden; the memory stores event subscriptions, resource watchers with their baselines, sampling requests with their provenance, idempotency records, rate limit counters, batch outcomes, call contexts, stream chunks, progress notices, tool mocks and the dry run toggle, and the getcalllog accessor returns the audited calls under client, tool, outcome, time and limit filters. The vitest suite grows from 750 to 792 tests over plain fixtures covering the event subscription registration, filters and notification delivery, the resource delta push with baseline absorption, the sampling round trips with capability and grant refusals, the prompt tool listing and rendering, the streaming chunking and reassembly, the progress notices, the in flight cancellation with partial results, the rate limit windows and retry after, the isolated call contexts of concurrent clients, the audit completeness, the structured error mapping and retry hints, the idempotency replay and expiry, the batch stop on error, the dry run purity, the tool mocks with canned results, the new policy gates, the new protocol envelopes end to end, the routing table additions and the call log and counter persistence; subscriptions and sampling, streaming, progress and cancellation, rate limits and structured errors, and idempotency, batching, dry runs and tool mocks are documented in docs/agentprotocol.md.
## 1.1.55

This feature release opens the second half of the agent protocol for remote clients — the stream http transport with tls, session tokens, client allowlists, approval gates and the auth handshake — without adding a single action kind: the reviewed vocabulary stays 334 kinds, the manifest permissions stay unchanged and the pinned key stays untouched. The new root `clientauth.ts` module groups the remote client auth: the one time pairing codes with their single use state and user configured window, the session tokens issued in the pairing exchange that leave exactly once while the stored records carry only their sha-256 tokenhash values computed through the platform crypto seam, the token verification on every frame with its scope limits, expiry and revocation, the client allowlist with the grant history of every scope change, the auth challenges with their single use nonces, the handshake completion that marks a client paired and the fixed json rpc refusal message that never leaks pairing state. The new root `httpstream.ts` module groups the http stream transport: the posted json rpc endpoint and server sent event channel paths, the stream channels with their user configured heartbeat rhythm and idle window that closes dead channels, the tls termination that requires valid certificates before any remote traffic (the required mode refuses any peer without a certificate matching the user configured sha-256 fingerprint), the user configured client ceiling that refuses connections past it while an absent value keeps the count unbounded, the remote status report of endpoint, tls and client counts, and the ordered intake pipeline — tls terminates first, the token verifies on every frame, the allowlist refuses unknown fingerprints and the namespace scope check runs before any consent gate so unknown tools fail fast. The new root `approvalgate.ts` module groups the approval gates of sensitive remote tool calls: the raise with the full call arguments, the secret redaction of the fields the user marked secret, the prompts that carry the client identity and called tool, the approve and refuse resolution with the actor and latency record and the configurable timeout that refuses an unanswered gate by default. Policy extends the protocol gates: `consentmetagrade` grades every sensitive tool with the approval gate requirement derived from the policy risk grading and the session origin scope (the tools/list report now carries the full consent metadata), `allowlistentryvalid` validates entries against the known client identities, `tokenlifetimevalid` and `approvaltimeoutvalid` validate the user configured windows, `remotetransporttls` requires tls for any non localhost transport, `pairingreadinessgate` refuses pairing without a live session, `remoteenablementgate` grades the remote transport enablement as a sensitive user choice behind the explicit remote review, `tokenscopevalid` limits scopes to the granted namespaces and `revocationgate` keeps the revocation an always available user action. The background keeps the remote handlers and persistence: the pairing issue, the challenge and exchange intake, the allowlist and remote config handlers, the revocation, the approval decisions that execute or refuse exactly the held calls, the ordered http frame intake with the client ceiling and the channel heartbeats, the maintenance sweeps that expire tokens and unanswered gates with audits, the auth handshake events with their outcomes, and the audits of pair, revoke, expire, allow, refuse and approval decisions with actor and latency — while sensitive calls of remote clients land behind the approval gates instead of executing and the negotiated per client tool floor persists on the client record. The sidepanel renders the remote transport status with the tls state, the pairing flow with the copyable code, the paired clients with their scopes, token expiry countdowns, per client tool floors and revoke controls, the approval gate cards with the redacted arguments and approve or refuse, the allowlist editor with namespace scopes, the auth failures with their json rpc error codes and the tls certificate options (the endpoint, tls mode, certificate fingerprint, client ceiling, token lifetime and approval window are all user configured with no code ceiling), and the popup surfaces the pending approval gates as notifications; the browser runtime exposes no listening socket under the current permission set, so the http frame intake rides the same seam as the stdio bridge with the tls, token, allowlist, scope and approval machinery fully enforced on every frame and the honest limitation documented like the native messaging refusal. The vitest suite grows from 710 to 750 tests over plain fixtures covering the stream channel open, heartbeat and dead close math, the tls requirement enforcement, the max client refusal, the pairing issue, exchange and single use, the token verification with scopes and expiry, the allowlist refusal paths, the auth challenge handshake completion, the approval gate raise, approve, refuse and timeout refusal, the namespace scoping and the ordered pipeline, the per client tool floor negotiation, the secret redaction, the remote status reporting, the new policy gates, the pairing, token, approval and handshake envelopes, and the token, allowlist, approval and identity persistence; the full http stream transport, pairing, tokens and scopes and the approval gates, tls and the auth handshake are documented in docs/agentprotocol.md.
## 1.1.54

This feature release opens the agent protocol phase and turns the browser into a tool server, growing the reviewed vocabulary from three hundred thirty three to three hundred thirty four kinds with one new read action kind (`listruns`) that lists the stored workflow run records from local memory: the new root `mcpserver.ts` module groups the whole mcp server — the json rpc frame grammar with newline delimited blocks and http post envelopes and its parse and serialize round trips, the frame validation that rejects malformed ids, unknown methods, non object params and frames over the user configured size, the rpc error codes mapped onto the classic json rpc numbers with `consentrefused` reserved at -32001, the routing table of `initialize`, `ping`, `tools/list`, `negotiate` and `tools/call` behind their `methodentry` records, the initialize handshake with the server info and the plain language consent instructions, the capability negotiation over the protocol version, the tool compatibility floor and the transports, the client records with their pairing state, the per client request queue serialization under the user configured depth with an absent depth keeping the queue unbounded, the consent gated tool dispatch, the localhost bind with its documented default, the stdio bridge that launches through the native messaging host manifest, relays frames in both directions and restarts a dead client process, and the framed logs that never carry payloads — while the new root `toolcatalog.ts` module groups the tool definitions of the four namespaces (browser, workflow, memory and system) with namespaced, versioned tooldefs whose inputs map to json schemas of typed properties with required markers and default values, whose descriptions state the consent class and side effects in plain language and whose tools with side effects declare their `consentmeta` review requirement, so a paired client can never widen what the human approved: read only tools (the browser snapshot, extraction, tab and window inventories, the workflow listing and dry run, the memory run, variable and audit accessors and the system reports) take their reviewed `target`, `value` and `options` inputs and run under the dryrun risk class once the session is approved, while every tool with side effects takes only the `stepid` of the approved plan step whose reviewed payload it executes and the tooldispatchgate folds the paired client, the live session, the approved plan, the origin grants and the matching step kind in that order — the protocol layer never bypasses review. Policy validates the whole catalog against the action kind grammar (namespaced unique names, domain membership, typed properties with their required list and non empty property maps), re-derives every tool's risk grade from its wrapped kind, demands consentmeta on side effects, keeps the version floor, gates the namespace membership, grades a non localhost bind sensitive behind the explicit remote review and demands the explicit user enablement before the server ever listens, with the bind address, port, transports, frame size, queue depth and tool call record retention all user configured with no code ceiling. The background keeps the server handlers and persistence: the config, start and stop handlers, the pairing decision and disconnect handlers, the bridge launch and restart through the native messaging host when the browser exposes it (with the honest refusal stated otherwise, because the manifest permission set stays unchanged and the pinned key stays untouched), the frame intake that gates every frame on the running server and the allowed transport, registers one client record per transport and serializes concurrent frames per client in arrival order, the routed frame path that audits initialize, tools/list, negotiate and every tools/call with the client id, tool name and origin but never the payload, the negotiated capability set stored on the client record, tool call records under the user configured call retention, the toolcall evidence in the plan progress and the `tool` block of the response envelope. The sidepanel gains the agent protocol tab with the server status and start and stop controls, the bind state and port, the connected clients with their transports, negotiated capabilities and the pairing prompt, the disconnect control, the tool catalog grouped by namespace, the stdio bridge status with restart and the recent tool calls with their caller and outcome, and the popup shows the mcp server running indicator — every tool call lands behind the same consent gates that govern the panels, and the full protocol grammar with the tool list, the json rpc framing and error codes, the stdio bridge setup and the capability negotiation with the localhost binding is documented in docs/agentprotocol.md.

## 1.1.53

This feature release gives the workflow stack its visible home and adds no new action kinds — the reviewed vocabulary stays three hundred thirty three kinds — because the 1.1.53 editor is a surface release: the new root `workfloweditor.ts` module groups the whole visual builder as pure logic (the canvas model of nodes, typed binding edges, block containers and layout state, the load and save round trips through the same composeworkflow grammar every other path uses, the drag and drop snapping onto the reviewed grid and the nearest block column, the reorder persistence, the grouping of a selection into a new block, the palette of curated drop blocks and the step library of every reviewed kind grouped into actions, control flow, waits, variables and triggers, the template insertion with nested parameters, the mini map projection and viewport math with click navigation, the zoom that keeps step labels readable at every level, the step search by label, kind and variable name, the breakpoint markers with the debug run segmentation that pauses before marked steps and resumes exactly there, the version diffing of added, removed and changed steps, the json and yaml file format for import, export and template sharing with the documented yaml subset of quoted scalars, mappings and block sequences, the per site override application to the reviewed knobs, and the undo and redo stacks covering every canvas edit) while the sidepanel renders the canvas with draggable nodes, typed sockets, block containers with nested child steps, the searchable palette, the step library, the step inspector with options, bindings and nested params, the variable inspector, the run log with breakpoint marks, the run history with filters, the version timeline with diffs and rollbacks, the import review before activation, the export and share buttons, the background run toggle, the watchdog status and the per site override editor. Background runs keep executing with the panel closed — every step checkpoints and every worker wake restores an interrupted run through the same session, plan and origin gates — the watchdog scans running runs for stalled steps and zombie runs left by browser shutdowns and recovers them by the user configured retry, pause or cancel action with the stall threshold and zombie window as pure user choices with no code ceiling, run history keeps the outcome, duration and trigger cause of every execution under a user configured retention, imports grade unreviewed until the import review approves the expanded step list and version rollbacks grade unreviewed until the rollback review does the same, the export content review refuses any step option or template payload that names a secret, token, api key, password or authorization field so secrets never leave the browser, per site overrides adjust only the reviewed knobs of loop bounds, step and run timeouts, element wait timeouts and delay bases per https origin pattern or subdomain glob, and every editor save passes the editorsavegate of a live session, an approved plan, unique node ids, forward only edges so no cycle forms and the full workflow grammar — all with the manifest permissions unchanged and the pinned key untouched.

## 1.1.52

This feature release lets reviewed workflows start themselves and grows the reviewed vocabulary from three hundred twenty three to three hundred thirty three kinds with ten new action kinds (`visitrule`, `urlrule`, `menurule`, `keyrule`, `buttonrule`, `cronrule`, `intervalrule`, `urllistrule`, `webhookrule`, `eventrule`) that arm trigger rules launching reviewed workflows: the new root `trigger.ts` module groups the whole trigger engine — the family payload normalizers enforce the grammar of every rule kind with HTTPS visit origin lists, glob url patterns where `*` spans one path segment and `**` spans across segments with explicit ports honored, non-empty context menu titles, lowercase command names with suggested key bindings, five field cron expressions with lists, ranges, steps, named weekdays and months, the classic day of month and day of week or semantics and optional timezones resolved through the runtime timezone database, interval periods with seeded jitter windows, HTTPS url lists, webhook shared secrets over the documented entropy floor of twenty four characters mixing letters and digits (a floor, never a cap) with payload schemas of named primitive fields, and event subscriptions of the observed event catalog of mutate, focus, banner, console, error and navigate — while the cron parser and its timezone aware next fire computation walk minute boundaries over sparse schedules honestly, the interval scheduler spreads repeated fires inside the seeded jitter window, the cooldown suppressor reports the remaining window, the dedupe keeps one pending fire per rule while a run is active, the trigger queue holds fires that arrive while the target run is busy or the session is paused and drains in arrival order on resume through the same gates, the url list planner starts one run per url, the webhook verifier checks the shared secret in constant time and every required field kind before anything persists, the observeevents seam subscribes armed event rules to the page observation vocabulary, and the manual run step preview renders every expanded step with its control summaries before confirmation so a human always sees what a trigger will do before it runs — every rule arms behind the explicit arm review that renders its match fields and bound workflow first, every rule grades sensitive because it launches runs automatically, evaluation skips disabled, paused, unreviewed or cooled down rules, and every launch re-passes the live session, approved plan and origin gates through the same run machinery as a reviewed runworkflow step with the triggering url, title and payload riding into the run context as seed variables. The background listens to tabs onUpdated for visit and url rules and the navigate event, evaluates the observed mutation, focus, banner, console and error events through the observeevents seam, registers context menu entries of menu rules when the context menus api is exposed, routes command listeners of key rules, evaluates the button rule of the toolbar once per popup open, and walks the cron and interval schedules forward on every service worker wake with the persisted next fire times while the alarms api rides the browser opportunistically when exposed without a declared permission — the honest scheduling pattern since 1.1.49 where the manifest permissions stay unchanged; webhook schemas persist now and receive traffic once the agent protocol http transport lands. The trigger list envelope carries the rules with their workflow names, states and queue depth, the triggerfired notification envelope announces fires with their run binding, the response envelope returns the next scheduled fire time per rule, memory stores rules, fire records under the user configured trigger retention with no code ceiling, verified webhook payloads, the trigger queue and manual run previews with their confirmation outcomes, the audit trail records rule enable, disable, arm, fire and cooldown suppression events, the sidepanel renders the trigger list with enable and disable toggles, the next scheduled fire of cron and interval rules, the fire history of every rule, a visit rule creator from the current page, rule duplication to a second workflow, the manual run step preview with approve and cancel and the webhook status with secret rotation, and the popup shows the armed rule count with the queued fires held while the session is paused — all with the manifest permissions unchanged and the pinned key untouched.

## 1.1.51

This feature release gives the workflow engine control flow and grows the reviewed vocabulary from three hundred fifteen to three hundred twenty three kinds with eight new action kinds (`condition`, `branch`, `loop`, `repeatuntil`, `whileloop`, `foreach`, `parallel`, `trycatch`) that make workflows robust on fragile pages: the new root `controlflow.ts` module groups the whole control engine — the payload normalizers enforce the grammar of unique branch paths with boolean match expressions and a mandatory else path so every branch terminates, distinct item and index variables with optional positive safety bounds (an absent bound keeps the documented default of one thousand iterations and any user value wins, while a while loop without a bound is refused at composition), unique parallel branch ids with reviewed join policies, and try blocks with catch handlers, retry policies of user configured attempts with no code ceiling over fixed or exponential seeded backoff shapes and the reviewed error classes, and timeout policies of positive per step and per run millisecond budgets — while condition steps evaluate their reviewed boolean expression over the extracted values with no page side effect, branch steps choose the first path whose condition holds through the page state accessor that exposes the pageurl, pagetitle and pageready variables of the run tab, loop steps deep copy the current item, rebind the item and index variables per iteration and emit iteration markers with nested outer and inner index paths for audit, foreach steps resolve their selector into element references through the new queryelements seam of the page bridge with an empty match reported as an honest zero iteration outcome, parallel steps launch their branches concurrently in isolated scopes that the join merges under the first, last or fail strategy over conflicting writes with cancel or continue on branch failure and no engine cap on the branch count, and try steps run their fragile body under the retry and timeout policies, hand the failure with its error class and message to the catch handler, rerun the body once when reviewed and abort exceeded budgets with the cancelled error class carrying the exceeded budget. Composition validates every control payload before the record freezes, collects every nested child step so no construct hides a step behind its body and grades the record by its worst child kind, control steps dispatch through the run executor seam that returns the merged scopes and the iteration runlog to the run loop so checkpoints, resume and the audit trail see every child outcome, and every child step keeps the same consent gate and dispatch chain as a plan step so no construct bypasses review — all with the manifest permissions unchanged and the pinned key untouched. The risk table grades condition and branch read only and the loop, foreach, parallel and trycatch kinds interaction, the workflow proposal envelope gains the control flow summaries of every control step for review rendering, the workflow outcome carries the branch outcomes, loop counters, retry attempts with backoff durations, timeout aborts, join records and parallel branch outcomes while the response envelope reports timeout aborts and retry exhaustion distinctly, memory stores every control flow decision per run with a branch history accessor across runs, progress counts loop iterations over a user defined denominator with no code ceiling, and the sidepanel renders the chosen branch path highlighted, loop iterations as collapsible groups, retry attempts with backoff countdowns, parallel branches as concurrent timeline lanes with the join result and merged variables, try blocks with their catch path, timeout aborts with the exceeded budget, an editor for the loop safety bounds before a run and the else path preview during review, while the popup shows the active loop iteration count of running workflows.

## 1.1.50

This feature release opens the workflow phase and grows the reviewed vocabulary from three hundred seven to three hundred fifteen kinds with eight new action kinds (`composeworkflow`, `savetemplate`, `runworkflow`, `dryrun`, `delay`, `waitelement`, `compute`, `extractvars`) that compose reviewed steps into freezable workflows: the new root `workflow.ts` module groups the whole engine — composition validates the name, version, granted HTTPS origins, steps and blocks, expands every nested block before review so no step stays hidden and grades the record read, interaction or sensitive by its worst step — while typed variable scopes stack per block with shadowing and resolution from the nearest scope outward, variable bindings link earlier step outcomes to named variables of the following steps, expressions evaluate arithmetic, comparison, logic, text, contains and length operators with operand coercion that refuses mismatched kinds, `${name}` interpolation substitutes scope variables into step targets, values and options, regex rules store their named captures as variables with the no match case reported as an honest outcome instead of a crash, jittered delays sample a seeded window, and element waits poll a selector until appearance, the reviewed timeout or a clean abort when the tab navigates away. Runs advance one step at a time behind the consent gates of a live session, an approved plan and origin grants inside the session, checkpoint after every completed step so they survive service worker restarts (the startup hook marks interrupted runs paused at their last checkpoint and the resume continues exactly there), pause and cancel record their reasons, single step execution runs one chosen step outside the run loop for debugging, and the dry run evaluates every step read only through per kind projections while refusing mutation steps that carry no projection — all with the manifest permissions unchanged and the pinned key untouched. `runworkflow` grades sensitive because it executes the whole expanded list behind the explicit run review flag that the proposal parser also demands, every other workflow kind stays read only in the risk table, the response envelope gains a workflow block and a workflow report with the saved records, runs, templates, runlog, scope values and provenance, memory stores workflow record versions, runs, runlogs under a user configured retention, scope values, expression and regex provenance and shareable step templates, and every compose, run, dry run, pause, resume, cancel and single step event lands in the audit trail while the sidepanel renders the workflow list with run and dry run actions, the approval prompt with the expanded step list, the live step timeline with checkpoint markers and dry run marks, variables per scope, provenance and the runlog stream, and the popup shows the active run state with pause, resume and cancel buttons plus a badge count of background runs.

## 1.1.49

This feature release opens the memory phase and grows the reviewed vocabulary from two hundred ninety five to three hundred three kinds with eight new action kinds (`persiststate`, `capturesession`, `restoresession`, `namedsessions`, `diffsessions`, `searchsessions`, `exportsessions`, `importsessions`) that make every run survivable: the task state of the run persists as a checksummed checkpoint after every completed step and resumes after a service worker or browser restart, the browsing session is captured beyond tabs and windows into scroll positions, non password form state, the local storage and the cookie names of granted origins, saved sessions restore on demand and after a crash behind an explicit restore review that lists every tab, form field and capture before anything reopens, origins whose grants expired are skipped and reported instead of reopened, auto snapshots run on a reviewed interval with the snapshot count and expiry window as pure user choices with no code ceiling, sessions organize under unique names, folders and tags, two saved sessions diff into classified tab, url, form and storage changes kept as read only comparison evidence, cross session search matches urls, titles, names and captured text inside a reviewed time window, and session files export through the reviewed download flow and import only after a full record review of the known format version with an intact checksum — the manifest permissions stay unchanged and the pinned key untouched, so the honest limits are: the restore reopens tabs through the tabs api behind the optional tabs capability while storage and cookie capture rides the scripting seam of granted origins only with cookie values and password fields never joining a capture, the crash detector marks interrupted runs on browser startup and the crash restore prompt stays inside the session consent model of a live session, the auto snapshot interval wakes through the alarms api only when the browser exposes it because the manifest keeps its permission set unchanged and otherwise resumes on the next service worker wake, and export files carry the format version, record ids, byte size and checksum so a corrupted or unknown file never imports. Every session kind runs behind the session consent gates (live session, approved plan, the restore review of every restore plan, the export review before any file leaves the device and the full record review of every import), read only kinds stay read only in the risk table while restores grade sensitive because they open tabs and write form state, the response envelope gains a session block with the record id and section counts, snapshot and restore ids travel in the step result details, the proposal parser refuses restores that reopen ungranted origins and import files of unknown format versions, and every persist, snapshot, restore, import and export event lands in the audit trail beside the session history with timestamps.

## 1.1.48

This feature release opens the emulation phase and grows the reviewed vocabulary from two hundred ninety four to three hundred kinds with six new action kinds (`emulatedevice`, `emulatenetwork`, `emulatelocate`, `setuseragent`, `overridepermission`, `blackboxscripts`) that let the agent wear reviewed masks over device metrics, network conditions, the geographic location, the per task user agent and browser permission answers, plus read only blackboxing of third party scripts in traces, with the manifest permissions unchanged and the pinned key untouched because the `geolocation`, `notifications` and `debugger` permissions deliberately stay out — the device layer overrides the page pixel ratio and the mobile hint through page-injected properties while the viewport bounds ride the window update api, the network layer shapes only the traffic the extension itself initiates with the reviewed latency, download and upload bounds and the offline window of the reviewed plan (page traffic stays observed only), the location layer overrides navigator geolocation with the reviewed coordinates behind an explicit per origin location consent whose prompt shows the exact latitude and longitude, the agent layer overrides the navigator user agent string, platform and brand list together and scoped to the run tab only, and the permission layer answers navigator permission queries of the reviewed browser permission set (geolocation, notifications, camera, microphone, clipboard-read, clipboard-write, midi, persistent-storage) with the reviewed granted, denied or prompt state graded by name while the browser permission itself stays untouched — every derivation is recorded on each layer and this changelog instead of hidden. Every emulation kind runs behind the new emugate (live session on the run tab, approved plan, the explicit reviewed flag and a reviewed revert plan beside every layer, and layers stack only while the reviewed plan lists their steps because the last applied layer wins conflicts), every layer records the prior page state for the exact revert, and the whole stack reverts in reverse apply order the moment the run ends, fails, is cancelled, navigates away or drops its tab, with the emulation state persisted per run so the masks survive service worker restarts and a crash restore stays one panel click away; the user curated device, network, location and agent preset libraries live in user data with an editor and versioned import and export files through review instead of hardcoded lists, blackbox rules of explicit origin patterns with single star segments and double star subtrees hide third party frames from captured stack traces and shape the traces and profiles of the run only, the reverted layer prior states expire after the user configured retention window while the layer history always survives, and the response envelope gains an emulation block with the applied and reverted layer names beside the audit trail that logs every applied and reverted layer with its values. The honest limits stay: without the debugger permission the device metrics, network stack, true geolocation, request headers and permission state of the browser remain the user's own, so every mask is a page-injected derivation of the run tab and the changelog, the layer records and the review panel say so on every apply.

## 1.1.47

This feature release closes the debugging chain and grows the reviewed vocabulary from two hundred eighty five to two hundred ninety four kinds with nine new action kinds (`measureflow`, `heapshot`, `trackmemory`, `profilecpu`, `watchshifts`, `traceload`, `annotatetrace`, `replaytrace`, `capturesourcemaps`) that measure flow performance, snapshot the heap on demand, track memory growth beside every step, profile the cpu window of a heavy step, watch layout shifts, record annotated traces, replay them offline and capture the source maps of loaded scripts, with the manifest permissions unchanged and the pinned key untouched because the `debugger` permission deliberately stays out — flow timings derive from the performance timeline buffers with injected marks per reviewed step window, heap bytes from the page performance memory buffer with the dom node count, cpu samples from the long task attribution and event timing buffers, layout shifts from the layout-shift buffer with the impacted selectors of the shift sources, traces from the derived json format of the observed entries (never the devtools binary trace format) and source map declarations from re-fetching the loaded same origin scripts, with every derivation recorded on each record and this changelog instead of hidden. `measureflow` runs read only behind the new targetgate (live session, run tab only, origin grants) after the approved debugger grant of the origin covers the profiling instrumentation — the first profiling step of a run prompts once with the derivation shown — while its reviewed flow spec carries the mark prefix, the step window and the metric list bounded by the reviewed metric set (navigation, paint, largest contentful paint, first input delay, interaction timings and the blocking time summed per step window over the fifty millisecond threshold) and the watch window stays inside the reviewed wait budget. `heapshot` and `profilecpu` are graded heavy sensitive steps with a review note: the snapshot frequency is bounded by the user chosen interval only with no code ceiling and the profiled duration stays inside the reviewed wait budget, while hot functions rank by their accumulated sampled time. `trackmemory` runs as read only telemetry: the reviewed slope in bytes per millisecond governs the flagged steps, the sampling interval stays a user choice, a sample is taken beside every following step of the run while the tracker stays active and the growth trend with its flagged steps flows into the run timeline as warnings. `watchshifts` scores the layout shifts of the reviewed observation window with their impacted element selectors, and `traceload` records a trace under the reviewed category list (navigation, scripting, rendering, painting, loading, network), stops at the reviewed window end, respects the user configured trace byte ceiling at export and exports through the reviewed download flow; `annotatetrace` aligns the step ids and labels of a stored trace with the run timeline entries so exported traces never lose their step annotations, and `replaytrace` renders the stored file offline with its events grouped by category and step. `capturesourcemaps` needs the new per origin source map consent before any map file is fetched, keeps the script sources inside the page bridge so only the map urls and parsed state leave it, and rewrites reviewed stack locations through a minimal source map mapping lookup. `attachcdp` now accepts iframe, worker and service worker targets through the reviewed attachtargets of the new attach target grammar, flattens a sub session per target for nested access, attaches the service worker of the page origin through the controller state, and the profiling target gate keeps every non page target inside the granted origins; service worker console and network entries flow into the run timeline as derived entries because the worker's own console and network stay unobservable without the debugger permission — an honest boundary this changelog states plainly, like the heap node counts deriving from the dom rather than a heap graph and the trace file being a derived json format rather than the devtools binary one. Memory stores the flow metric series per run, heap records with byte and node counts, growth samples with computed trends, cpu profiles with hot function lists, shift entries with scores and selectors, trace records with their exported file bytes and step annotations filtered by run and categories through listtraces, and source map references per origin, while the user configured profile retention window expires the heavy bytes and sample payloads with the counts, hot functions, category lists and annotations always surviving; every profile, trace and source map capture lands in the audit trail with its derivation note and no source text, map content or header values. The review panel gains the profiling view with flow duration bars per step, heap sample bars with the growth trend line and flagged steps, hot function lists, layout shift scores with impacted selectors, trace records with export through the reviewed download flow and an offline replay view grouped by category and step, source map consent prompts with approve and revoke, the attach target state of iframes and workers, and the profile retention and trace byte ceiling settings; the popup shows the profiling badge while a profile or trace runs and counts waiting source map prompts; the protocol version carries the profiling contract with a profile block of metric and sample counts in the response envelope, flow durations, heap and profile record ids, shift entries, trace records and rewritten stack locations in step details, and the proposal parser refuses trace categories outside the reviewed list, attach targets and source map scripts of ungranted origins, and trace annotation steps without reviewed step annotations.

## 1.1.46

This feature release continues the debugging chain and grows the reviewed vocabulary from two hundred seventy seven to two hundred eighty five kinds with eight new action kinds (`attachcdp`, `detachcdp`, `cdpcmd`, `watchcdp`, `setbreakpoint`, `stepcode`, `watchexpr`, `overridescript`) that attach a devtools-style session to the run tab and find the causes behind the symptoms the 1.1.45 timeline recorded, with the manifest permissions unchanged and the pinned key untouched because the debugger permission deliberately stays out — the chrome devtools protocol needs the `debugger` permission the CLI manifest gate forbids, so every command routes through the page-instrumented harness injected through the existing scripting seams, and the derivation is recorded on every session, every step result and this changelog instead of hidden. `attachcdp` attaches the instrumented session to the run tab behind the debuggate (live session, run tab only, origin grants) after the reviewed debugger consent of the origin covers every requested domain — the first attach of a run prompts once with the domain allowlist shown, the approved decision persists per origin, revocation removes the coverage, and the grant revokes when the run ends, fails or is cancelled — while the enabled domains stay a user choice bounded only by the reviewed domain grammar (`Runtime`, `Log`, `Debugger`, `DOM`, `Network`, `Page`), an optional method allowlist of `Domain.method` gates narrows the raw surface further, every attach requires its reviewed teardown plan of revert steps and a resume policy before approval (attaches without one are refused at validation and in the proposal parser), and the session record carries the honest debugger version note. `cdpcmd` sends a raw reviewed command of the `Domain.method` form to the session: concurrent commands serialize per session in send order, each command record carries its method, domain, dotted result path, duration and error class, the full command result returns as step details while the params never enter the audit trail, protocol errors fail the step with their error class, and the honest instrumented surface implements `Runtime.evaluate` with scope injection, the domain enables, `DOM.getSnapshot` and `Page.getNavigationHistory` while every other method reports the `uninstrumented` error class instead of pretending. `watchcdp` subscribes to reviewed domain event rules of domain, event name and optional payload match filter for a reviewed lifetime window kept inside the reviewed wait budget: matched events forward into the run timeline as `cdp` sourced entries beside the console, error and task capture, per-domain event counts return in the step result, and every subscription closes at run end, on step cancel and on the run tab navigation. `setbreakpoint` registers a reviewed instrumentation hook of https url, zero based line, optional column and a condition of the reviewed expression grammar (member chains, number, string, boolean and null literals, comparison and logic operators, negation and parentheses — assignments and calls are refused outright) behind the user configured breakpoint ceiling that an absent value never enforces because the cap stays a user choice only; when an instrumented probe of the run hits the breakpoint the run pauses and the pause state captures its reason, hit breakpoint, call frames and the dom state through the page bridge snapshot reference. `stepcode` steps the paused probe through the reviewed modes of stepover, stepinto, stepout and resume and captures the pause state after every step; `watchexpr` evaluates the reviewed expression (explicit reviewed flag required before any evaluation) at every pause in its pause scope and stores the values with their pause correlation in the watch record and the run timeline; and `overridescript` applies a reviewed page script override of an explicit https origin url pattern with its full fixture source behind the explicit reviewed flag on new document evaluation, applies to later instrumented evaluations of the pattern, and reverts at run end, on failure, on cancellation and from a manual revert control while the fixture source never enters any report, envelope or audit trail. Clean teardown holds on every path: the reviewed teardown plan reverts every breakpoint and override in order with audited revert events, `detachcdp` confirms the detach with the reverted counts, the run tab navigation tears the session down because the injected harness dies with the destroyed context, and when the user detaches the debugger every consent revokes, every breakpoint and override reverts, the session record stays alive for review and the run pauses for review before continuing. Storage and review grow with the family: cdpsession records with domains and durations, raw command outcomes with durations and error classes, event rules with match counts, breakpoint records with hit counts, pause states per run (the `listpauses` accessor) whose call frames and dom snapshot references expire under the user configured pause retention while the pause reason and hit breakpoint survive, watch expressions with per pause values, script overrides with review provenance and sources held back, and debugger consents with consent and revoke times; the response envelope gains a cdp block with the session state and command ids, the cdp report carries every record with override sources and grant prompts held back, parseproposal rejects cdp steps for ungranted origins, attach steps without teardown plans and raw commands outside the plan attach allowlist, and the protocol version moves to 1.1.46. The review panel gains the debugger view with the consent prompt showing the domain allowlist, the session state with the honest derivation, the sent commands with durations and the raw protocol badge marking the sensitive class, the breakpoints with hit counts and conditions, the pause banner with call frames while paused, the watch expression values at each pause, the script override list with revert controls, the domain event counts streamed beside the run timeline and the pause retention and breakpoint ceiling settings, the popup shows the debugger attached badge during runs, the action badge counts pending debugger consent prompts, and every audit lands as the new `debugger` kind naming the origin, domains, durations and revert events without params, sources or values. Honest limits, stated plainly: without the `debugger` permission the session instruments the page it can reach through the scripting api only — breakpoints pause instrumented probes of the run rather than arbitrary page scripts, stepping advances the instrumented pause cursor, domain events derive from the harness console hooks and the performance navigation buffer rather than the full devtools event stream, and script overrides steer instrumented evaluations of the run instead of the network stack; the changelog says so and the derivation note rides on every session record.

## 1.1.45

This feature release opens the debugging chain and grows the reviewed vocabulary from two hundred seventy four to two hundred seventy seven kinds with three new read only action kinds (`watchconsole`, `watcherrors`, `watchtasks`) that record what pages say and how they misbehave into one run timeline bound to step ids and consent per origin, with the manifest permissions unchanged and the pinned key untouched because the debugger permission deliberately stays out — console, error and task watching derives from page-injected listeners installed through the scripting api plus the performance buffers, the closest consent-preserving seam, documented honestly below. `watchconsole` captures console output at every level of the reviewed level set (`error`, `warn`, `info`, `log`, `debug`, `trace`): the page bridge hooks every console method and forwards the calls with their arguments, object arguments are serialized through a reviewed depth bound (deeper objects collapse to their constructor tag and the bound carries no code ceiling), the reviewed redaction pattern list is required before any console text is captured and every match is replaced before an entry leaves the page bridge, every entry is tagged with the current step id and carries the run correlation id of its step, spam detection collapses repeated identical messages inside the reviewed window into repeat counts and flags the patterns that exceed the reviewed collapse threshold, and log rotation moves overflow entries to the reviewed overflow target store with the newest window kept per run without data loss. `watcherrors` captures javascript errors with their stack traces (the frame parser reads function names, urls, lines and columns and skips unparseable rows), unhandled promise rejections with their reasons, and resource load failures with element context, while stack capture outside the granted origin is refused by the stack gate; `watchtasks` observes longtask performance entries with their attribution names, filters entries below the reviewed threshold, and reports the blocking duration summed per step window. Every watch kind carries a reviewed watch window kept inside the reviewed wait budget through the debug wait budget gate (both bounds user choices with no code ceiling), an optional level floor from the level set that drops more verbose entries, and optional source filters drawn from the reviewed timeline source grammar (`console`, `error`, `rejection`, `resource`, `longtask`, `network`); the new `timelinegate` scopes capture to the run tab only, the proposal parser refuses watch steps for ungranted origins and level floors outside the level set, the timeline capture consent prompts once per origin and the approved decision persists, and a plan of watch kinds alone is valid because timeline capture runs without any other action kind. The memory stores the run timeline with entries filtered by run, level and step id, error and rejection records with stack frames, long task entries with attribution names, rotation targets with their overflow entry counts, per origin console consent decisions and the one console diff result, while the user configured timeline retention window expires the oldest entries into per run level count summaries that always survive; the netwatch request observer marks the failed requests of the run in the timeline as network sourced entries. The response envelope gains a timeline block with the entry counts per level and the spam collapse count, step results carry the error and rejection ids, and the timeline and console diff reports carry every entry, record and the added, removed and repeated line classes of two compared runs — console diffing grades as read only comparison evidence. The background cancels watchers on run cancel and the killswitch with the captured window discarded, detaches them cleanly when the tab navigates or closes (a navigation inside the watch window closes the watcher and every page hook of the destroyed context goes with it), and audits every watcher attach and detach with origin and scope; the timeline entries stream to the sidepanel live through the context refresh. The sidepanel gains the timeline view with level, source and step id filters, entries paired with their step markers, spam collapse counts, errors expandable into their stack frames, long task bars beside their steps, the console consent prompt with its approve control, the level count summary with the retention setting, and the diff view comparing the console output of two runs with added, removed and repeated lines highlighted; the popup counts the errors captured in the active run beside pending console consent prompts; error level entries are marked with the alert palette. The vitest suite grows from 399 to 426 tests covering console capture at every level with redaction and argument kinds, depth bounded serialization, stack frame parsing, error, rejection, resource failure and net failure capture, long task attribution windows and blocking duration, spam collapse thresholds, rotation without entry loss, level floors and source filters, console diff line classification, watcher detach on navigation, the timelinegate, console consent and stack gates, the wait budget gate, the debug options grammar of every kind, the timeline block and report envelopes, the parseproposal rejections, timeline storage with filters, retention expiry into level summaries, error, rejection, long task, rotation target and console consent records, and timeline progress evidence, all on plain fixtures; the isolated Chromium smoke test captures the console output and one error of a fixture page through the shipped run timeline module. Honest limits: console, error and task watching sees only the isolated world of the injected page bridge, so messages logged before the reviewed window opens or after it closes are not captured; the performance buffers expose longtask timings with attribution container names only, so richer attribution (script urls, element targets) is unavailable without the debugger permission this manifest refuses; console capture covers the page's own console calls and standard error and rejection events, not devtools protocol console messages of other frames; and the stack trace text is whatever the browser hands the error event, so frames may be absent for minified cross-origin scripts.

## 1.1.44

This feature release takes the steering wheel over the traffic the agent itself creates and grows the reviewed vocabulary from two hundred sixty three to two hundred seventy four kinds with eleven new action kinds (`blockrequest`, `mockresponse`, `rewriteheaders`, `setcookies`, `readcookies`, `clearcookies`, `authflow`, `saveapikey`, `routeproxy`, `postform`, `postfiles`), every one still a reviewed step behind the session, plan approval and origin gates, all run scoped so every rule applies for the run only and reverts the moment the run ends, fails or is cancelled, and the manifest permissions stay unchanged with the pinned key untouched because the forbidden cookies, webRequest, declarativeNetRequest and proxy permissions all stay out and every mechanism routes through the closest consent-preserving seam, documented honestly below. `blockrequest` is graded sensitive traffic control behind the new `blockgate`: the reviewed block rule needs a url pattern that names an https origin explicitly (patterns without one are refused at validation and inside the proposal parser), an optional resource type list and the explicit reviewed flag; because webRequest and declarativeNetRequest stay outside the manifest, blocking refuses matched requests of extension-initiated traffic — every outbound fetch of the run consults the active rule set first and matched requests are refused with their per-rule hit counts reported to the step result — while page-initiated requests stay honestly visible in the 1.1.43 watch buffers instead of being blocked. `mockresponse` serves a reviewed fixture for matched requests: the fixture needs the full reviewed body behind the explicit reviewed flag, serves its status, headers and body for matched extension fetches without touching the network, counts its hits, and clears at run end; `rewriteheaders` applies set, append and remove operations to the headers of matched extension requests with the provenance of every applied rule audited, its rules must name their origin patterns explicitly, and reverts at run end. Cookie control is honest about the missing cookies permission: `setcookies`, `readcookies` and `clearcookies` run behind the new `cookiegate` that scopes every kind to a granted domain (a domain equal to a granted origin host or beneath it, every other domain refused) and every operation happens through the page document cookie jar of the granted origin via the page bridge — writes carry name, value, path and optional expiry, reads return the name and value pairs the origin jar exposes (document.cookie exposes no domain, path or expiry metadata), clears expire the matched names, every operation is mirrored as a cookie operation record with timestamps, cookie values are redacted from the audit trail, and no cross-domain cookie access exists because the storage-scoped mirror plus the page jar cover exactly the granted origin. `authflow` is graded sensitive and runs a reviewed oauth flow for an external api: the flow needs a provider, https authorize and token urls, scopes and a redirect origin inside the grants plus the reviewed provider consent prompt ref; the executor builds the consent page url with a run-scoped state token, opens it in a reviewed tab through the optional tabs capability requested from the review panel (reading the redirect url needs it and the manifest gains nothing), captures the authorization code only when the redirect lands on the granted redirect origin with the matching state token, refuses provider error redirects with their reason, exchanges the code for tokens through the token endpoint inside the origin grants, stores the token material behind storage ids while the tokenrecord keeps only provider, scopes, origin scope, expiry and refresh timestamps, refreshes expired tokens through the reviewed refresh grant scoped to the provider token origin, revokes stored tokens on user demand from the review panel or through reviewed revocation rules, and run cancel or the killswitch closes every open flow with its tab. `saveapikey` is graded sensitive and stores an api key locally behind the explicit consent prompt ref: the entry keeps name, https origin scopes, header name, created time and a last use timestamp stamped on every attach, the key material stays behind its storage id — the platform exposes no extension key store, so the honest boundary is that key material never enters any report, protocol envelope or audit trail rather than claiming at-rest encryption the browser does not offer. `routeproxy` is graded sensitive behind the new `proxygate` (live session, reviewed consent ref, and a route of scheme, host, port and the required non-empty bypass list that the proposal parser also demands): the route applies for the run only, bypassed origins send direct, and because the proxy permission stays outside the manifest the non-bypassed extension traffic routes through the reviewed relay endpoint pattern (the configured https endpoint carries the target url in a reviewed header, devtools-proxy style); when no relay endpoint is configured the request sends direct with the route still recorded for review, and the route reverts with an audited revert time at run end, on failure, on cancellation and from the manual revert button of the traffic view. The rate limiter parses the remaining, limit and reset headers of every response (a reset value beyond the read time counts as epoch seconds, a smaller one as seconds remaining), delays the next call until the reset window passes as user configured behavior kept inside the reviewed wait budget through the new ratelimit budget gate, honors Retry-After values of 429 and 503 responses in seconds or HTTP dates, and stores rate limit states per origin that expire at their reset windows. `postform` is graded sensitive and submits urlencoded form data to a granted origin after the rate limiter pass; `postfiles` is graded sensitive and uploads multipart fields and reviewed files where every file carries the explicit reviewed flag before the upload includes it, the payload streams as ordered chunks — one per field part, file part and the closing boundary — without buffering the whole body, and the chunk and byte progress reports to the run view. The response envelope gains a control block with the applied, blocked and mocked rule counts, the auth report carries token metadata per provider with scopes and expiry windows but no token values or storage ids, the traffic report carries the rule lists with hit counts and mock bodies held back, and the memory gains the block, mock and rewrite rule sets per run, cookie operations per domain with timestamps, token metadata without values, api key entries with last use, proxy route history with apply and revert times and rate limit states that expire at their reset windows, all audited through the new control audit kind where every applied and reverted rule names its origin. The sidepanel gains the traffic view with the block, mock and rewrite rule lists showing live hits during the run, the cookie operations, the oauth flow state with provider and scopes, token metadata with revoke buttons, the proxy state with a manual revert button, rate limit waits with reset times, api key entries with their origin scope, and multipart upload progress; the popup shows the active rule count badge during controlled runs and the action badge counts the active rules. Honest limits: blocking, mocking, header rewriting and proxy routing steer extension-initiated traffic only because the manifest keeps webRequest, declarativeNetRequest and proxy out; page requests cannot be blocked and stay observable instead; the relay endpoint must be the user's own configured https endpoint before proxy routing actually reroutes anything; the page cookie jar covers only the granted origin with no domain, path or expiry metadata on reads; and the oauth code capture needs the optional tabs capability because url visibility of the redirect tab is what it reads. The vitest suite grows from 366 to 399 tests covering rule registration and reversion at run end, mock fixtures and header operations, cookie scopes and domain refusals, rate limit waits and retry after parsing, form encodings and multipart chunk streaming, oauth code capture with state matching and token exchange and refresh, the control gates and the control options grammar of every kind, the control and auth protocol envelopes with held-back values, the parseproposal rejections, the control storage with rate limit expiry and last use timestamps, and the traffic control and upload progress evidence, all on plain fixtures.

## 1.1.43

This feature release closes the network observation phase by teaching the agent to listen and grows the reviewed vocabulary from two hundred fifty three to two hundred sixty three kinds with ten new action kinds (`opensocket`, `sendmessage`, `waitmessage`, `watchrequests`, `readheaders`, `capturebodies`, `subscribesse`, `longpoll`, `mapapi`, `extractapi`), every one still a reviewed step behind the session, plan approval and origin gates with the manifest permissions unchanged because websocket and event stream connections open from the extension context itself and request watching derives from the page performance and navigation buffers the page already exposes, never through webRequest or host permissions. `opensocket` is graded read only and gated by the new `socketgate` policy gate: every channel url must be a wss websocket or https event stream url without embedded credentials whose https origin sits inside the session origin grants, the new `socketoptions` carry the reviewed protocols, reconnect attempt budget, backoff base and backoff ceiling (each a user choice with no code ceiling), and the new `socketbus` module opens the channel through a connect seam with exponential backoff waits that stop growing at the user configured ceiling, reconnects dropped channels inside the reviewed budget, multiplexes named message streams over one channel and tags every message with a channel scoped sequence number whose integrity the bus verifies. `sendmessage` is graded sensitive because publishing a reviewed payload on an open channel moves data outbound, `waitmessage` waits on the reviewed message filter of stream name, dotted json path and match limit until the limit or the reviewed wait budget, and channels close cleanly at run end, on plan completion and on the killswitch. `subscribesse` opens a server sent events stream behind the same socket gate, parses the id, event, data and retry fields of every event, resumes from the last event id after a drop through the last event id request header, and cancels cleanly when the reviewed cancellation path or the run ends; `longpoll` issues requests on a reviewed poll cursor of url, cursor field, interval and stop condition, kept inside the reviewed wait budget, and stops on the stop condition, the cancellation flag, the plan expiry or the user configured poll ceiling. Request observation arrives with `watchrequests` behind the new `watchgate` that requires the user granted webrequest toggle in the review panel: the observation derives from the page timing buffers of the run tab only, assigns one correlation id per run request, records the full request lifecycle with timings, marks failed requests with status and error class, and honestly reports that the timing buffers expose no header names, body bytes, subresource status codes or request verbs, so fetch initiated exchanges carry a question mark method and unknown statuses unless a navigation entry exposes its response status. `readheaders` inspects the headers of captured exchanges through a reviewed header filter whose name allowlist and redaction list are both required before any header value is stored, and redacts every redaction listed value to a marker before storage; `capturebodies` grades interaction and sensitive when the reviewed mime list carries private document or data payload types, matches exchanges through the reviewed body filter of url pattern, mime list and byte ceiling, and honestly captures each matched body through a fresh reviewed fetch of the matched url through the extension context because the timing buffers expose no body bytes, truncating at the user configured ceiling and linking every body to its exchange through the correlation id while the user configured body retention window expires the oldest bodies and keeps the exchange metadata for the audit trail. `mapapi` detects the api endpoints the page uses from the observed exchanges and captured bodies, ranking them by frequency, json share and payload stability, and `extractapi` grades read only when the replay verb is read and sensitive otherwise, replaying a captured endpoint with reviewed parameter overrides through the granted origins and mapping response fields onto dotted extraction paths. The protocol envelope gains a network block with the exchange count and channel state, the new exchanges report carries every exchange, channel, subscription and api map entry of the run, and parseproposal now rejects channel urls outside the grants, subscriptions without a cancellation path, poll steps without a stop condition and channel lifetimes beyond the reviewed plan window. The sidepanel gains the network view listing every exchange of the run with method, url, status, size and duration, expandable into the stored redacted headers and a body preview, error class badges, correlation id grouping, live channel state with message counters, event stream names, poll loop cursor values and stop conditions, the webrequest grant toggle, the body retention control and the netlog export, while the popup shows the observed request count of the active run beside the live channel count. Honest notes: subresource status codes and verbs are not exposed by the timing buffers so derived exchanges report unknown statuses and question mark methods for fetch initiators, captured bodies come from fresh reviewed fetches rather than the original page responses, header values exist only for exchanges captured through the extension context, and the sse reconnect cadence and message queue polling run on internal service worker timers that cap no reviewed value.

## 1.1.42

This feature release opens the network observation phase by teaching the agent to speak to the network under consent and grows the reviewed vocabulary from two hundred forty eight to two hundred fifty three kinds with five new action kinds (`fetchurl`, `parsejson`, `parsehtml`, `callrest`, `callgraphql`), every one still a reviewed step behind the session, plan approval and origin gates with the manifest permissions unchanged because outbound http runs from the extension context itself through the same fetch the proposal endpoint already uses, never through webRequest or host permissions. `fetchurl` is graded read only but gated by the new `origincheck` policy gate: every outbound request must be a reviewed HTTPS url without embedded credentials inside the session origin grants, the new `fetchoptions` object carries the reviewed timeout, retries, backoff base and redirect follow limit (each a user choice with no code ceiling) whose worst case must fit the reviewed wait budget, and the new `sendfetch` executor enforces the timeout through a race on each attempt, retries failed attempts after the reviewed backoff waits, honors the redirect follow limit, and streams large response bodies chunk by chunk through the new `readstream` window where every chunk passes the reviewed handler path and the user configured byte budget aborts past the ceiling. Custom headers are consent first: the reviewed header allowlist is the exact set the executor transmits, every custom header needs a reviewed consent ref before any send, credential bearing header names (authorization, cookie, api keys and friends) need the explicit consent that names them, and the new `fetchconsent` records persist per origin with the header names and values shown to the user in the review prompt — prompts appear once per origin and expire on the reviewed window, while header values and body bytes never enter the audit trail. `parsejson` and `parsehtml` are graded read only and parse a stored call body by its reviewed call id: `readpath` extracts named fields through dotted json paths (array indexes included) with reviewed kinds, reviewed defaults and honest miss flags reported as step outcomes instead of crashes, while `parsehtml` parses the fetched markup through the page bridge domparser and runs reviewed html queries that return attribute values, text and element counts per query with the multi flag widening the first match to every match. `callrest` and `callgraphql` are graded sensitive because they carry mutation verbs and credentials: typed endpoints are user configured records with a name, method, HTTPS url template, header allowlist and a payload schema (rest calls refuse to run without one), `callrest` validates the reviewed payload against the schema, applies schema defaults, templates the url variables from the reviewed values, maps response codes to step outcomes through the reviewed success status list or the two hundred class by default and parses json error bodies into structured step details, while `callgraphql` wraps the reviewed operation with its variables and operation name, unwraps the data and errors blocks of the response and maps every returned error beside the step that produced it; `mutationcallof` grades mutating rest verbs and graphql mutations as the sensitive reviews they are, and stored `apikeyref` records attach their secrets under reviewed header names only when the plan reviews them and only inside their origin scope, with the key material never appearing in any report or audit. The transport block joins the response envelope with status, response header names, byte size and duration; step details carry parsed field values, retry counts, stream byte counts and the endpoint name; `parseproposal` now rejects fetch requests to ungranted origins (defaulting to the plan origin and honoring the session grants when they exist) and header allowlists with empty names; memory stores every call record with method, origin, status class, duration, retries and byte counts through one call store with `listcalls` filtering by run and origin, expires call bodies after the user configured call retention window while the metadata always survives, keeps typed endpoint definitions with full version history, fetch consent decisions per origin and api key references with their secrets behind storage ids; progress records every call completion and every fetch retry so the sidepanel reports fetch progress on each retry; audits use the new call audit kind with method, origin and status class only; run cancel, killswitch and session stop abort every in flight request through tracked abort controllers; and the sidepanel gains the network calls view listing every fetch of the run with status, duration, retries and byte counts, expanding one call into header names, parsed fields and errors, with fetch consent prompts showing name and value, stream progress bars for streamed responses, filters by origin, method and status class, typed endpoint listings, api key reference management, the call retention setting and the reviewed download flow export, while the popup shows the outbound call count of the active run and credential bearing calls wear a distinct badge. Honest notes: cross origin redirect hops stay opaque to extension fetch (opaqueredirect responses expose no readable location header), so the engine follows redirects within the reviewed follow limit and a zero limit refuses redirects outright instead of the executor counting hops it cannot see; the stream budget is enforced on the decoded chunk stream of the response body reader; the default fetch consent expiry window is a reviewed default the user may change with no code ceiling; and page request observation (websockets, server sent events, request correlation) stays out of scope until network observation part two. The vitest suite grows from three hundred six to three hundred thirty five tests covering sendfetch timeout, retry and backoff behavior with per attempt waits, the redirect follow limit, readpath extraction with kinds, defaults and miss outcomes, html query selectors with counts, readstream chunking with byte budget aborts and the abort flag, callrest schema validation, url templating, defaults and reviewed success classes, callgraphql envelope wrapping with data and error unwrapping, the origincheck, header consent and sensitive grading gates, the fetch, parse and typed call grammar with endpoint schemas, the transport block and calls report envelopes, call storage with consent expiry, body retention that keeps metadata, endpoint version history and api key secrets, and call and fetch retry progress evidence on plain fixtures without jsdom, while the isolated Chromium smoke test now also fetches a reviewed url through the shipped http client and parses its json.

## 1.1.41

This feature release completes the media capture phase by widening the lens from still images to documents and moving media, growing the reviewed vocabulary from two hundred thirty six to two hundred forty eight kinds with twelve new action kinds (`capturepdf`, `recordscreen`, `captureaudio`, `captureframe`, `downloadimages`, `shotcanvas`, `probestream`, `readmedia`, `readassets`, `timelapse`, `convertimage`, `makethumbs`), every one still a reviewed step behind the session, plan approval and origin gates, with the new mediagate requiring the active tab grant of the live session for every media kind exactly as the capturegate does for shots, and the manifest permissions unchanged. `capturepdf` composes a derived pdf document from the page text: the bridge collects the text of each report segment, reviewed break point selectors (or automatic viewport steps when the paginate flag is set) split long reports into page segments, and the composer writes a valid PDF 1.4 document with the reviewed paper width and height in inches, margins, scale and landscape orientation, naming report pages with the buildname rule of 1.1.40 and routing exports to memory or the reviewed download flow behind the optional downloads capability (pdf documents never route to the clipboard). `recordscreen` and `captureaudio` are graded sensitive capture of user activity and refuse to start without a reviewed consentref of an approved recording consent prompt that the memory persists per origin with every start consuming its own prompt, the recording duration comes from the reviewed step options or the user configured recording window with no code ceiling on either side, and run scoped recordings stop cleanly at run end. Honest derivation notes: tabCapture and desktopCapture stay outside the manifest by review, so recordscreen derives an ordered frame sequence from capturevisibletab at the reviewed fps (the browser caps visible tab captures at roughly two per second, missed frames are counted honestly) and stores an honest JSON manifest with the frame index through the reviewed download flow instead of encoded video bytes, and captureaudio derives audio element evidence (sources, durations, live states) from the page instead of encoded audio bytes; no offscreen recording host exists because the offscreen permission stays outside the manifest. `captureframe` seeks a video element to the reviewed timestamp, pauses it and draws the frame to a canvas that encodes as an image (cross origin videos without cors headers refuse the draw honestly); `downloadimages` detects every image on the page inside an optional selector scope, matches the reviewed imagefilter of minimum dimensions and a format list, deduplicates identical urls, stamps names with the image counter and downloads through the reviewed download flow behind the optional downloads capability, with filter match counts carried in the step details; `shotcanvas` reads canvas content through the page bridge, requesting the buffer of webgl canvases through a readPixels pass when the drawing buffer is not preserved (tainted canvases refuse honestly); `probestream` reports the track kinds, labels, resolutions and live states of the media streams attached to page elements (peer connection statistics such as round trip time and frame drops need main world access that stays outside the reviewed isolated world bridge — an honest limit); `readmedia` extracts embedded video and audio sources with mime types, durations, dimensions, codecs and track lists; `readassets` collects declared favicons, apple touch icons, manifest declared icons and logo candidates with their declared sizes; `timelapse` captures the page on the reviewed interval over the reviewed duration kept inside the reviewed wait budget and assembles the ordered lapse sequence; `convertimage` re-encodes stored captures between png, jpeg and webp with the reviewed quality; and `makethumbs` crops or fits thumbnails of stored captures to the reviewed size with the reviewed fit and naming suffix, both offered as review panel actions on stored captures beside the plan steps. Memory stores pdf, recording, frame, canvas, stream and asset records per run through one media store with listmedia filtering by run and kind and getrecording returning one recording with its file reference, expires the media bytes after the user configured media retention window while keeping the metadata and the recording frame index, and persists image batches and recording consent decisions; progress records every media capture with kind, scope and byte size as reviewable evidence; the response envelope gains a media block with record id, kind and byte size and the media report carries every stored record and image batch; audits use the new media audit kind with kind, scope and byte size; the sidepanel gains the media tab with pdf, image, video and audio sections — recordings listed with play (frame sequence playback at the recorded interval), download and delete controls and a distinct outline marking sensitive recordings, image batches with filter match counts, stream probe results with track details, the recording indicator while recordscreen runs, lapse playback and the convertimage and makethumbs actions — while the popup shows the recording state badge during active captures. The vitest suite grows from two hundred eighty five to three hundred six tests covering the pdf options and pagination grammar with break point segments, the derived pdf document structure with header, xref offsets, landscape swap and text escaping, the recording records with scope, duration and clean stops, image filter matching with url deduplication and counter names, lapse frame ordering with interval bounds, canvas-adjacent thumbnail geometry for cover and contain fits, the mediagate, recording consent and download grading, the media block and media report envelopes, media storage with retention expiry that keeps the recording index, and media progress evidence on plain fixtures without jsdom.

## 1.1.40

This feature release opens phase two of the unlimited agentic core by giving the agent eyes of its own and grows the reviewed vocabulary from two hundred thirty one to two hundred thirty six kinds with the media capture family: five read only kinds (`shotview`, `shotfullpage`, `shotelement`, `shotregion`, `contactsheet`) that capture the page itself as evidence, every one still a reviewed step behind the session, plan approval and origin gates with the manifest permissions unchanged, because the visible tab capture api only needs the activeTab permission the extension already holds. Every capture kind carries a reviewed `capture` options object (`format` restricted to png, jpeg or webp, `quality` anywhere in the zero to one hundred range with no code cap, `pixelratio` from one up to any user configured ceiling, an `annotate` flag and an `exporttarget` of memory, download or clipboard); `shotview` shoots the visible viewport through `capturevisibletab` with the reviewed format and quality, `shotfullpage` measures the full scroll geometry through the page bridge, scrolls the page in reviewed tile steps with a reviewed settle window between tiles, and composes the tiles on an offscreencanvas inside the service worker where overlap rows blend with linear seam weights and a repeated fixed header band (a tile top band matching the first tile) is skipped so fixed headers never stitch twice, with the capture scrollbars hidden through a scoped style rule and the original scroll position restored after the last tile; the stitching scroll budget of tiles times settle must fit inside the reviewed wait window or the step refuses; `shotelement` resolves the pixel ratio scaled element rect through the page bridge, crops the element from the viewport capture, and falls back to tiled capture in reviewed steps when the element crosses the viewport edge; `shotregion` requires a reviewed `regionrect` with the explicit reviewed flag before it runs, captures a scrollable container by scrolling it in reviewed steps, and draws the target outline on annotated captures; `contactsheet` tiles the element captures of a reviewed selector list into one labeled grid image with cell captions stamped from the reviewed label style while cell counts and sizes stay user choices; and every capture may carry a reviewed `naming` rule of run, step, sequence and kind segment flags that extends the 1.1.39 capture naming counters so names stay unique inside a run through the sequence counter. The annotator draws the step number marker, the target rect outline and a footer with the capture time and page url onto annotated captures, marking them distinctly in the gallery as annotated evidence. Before and after state capture arrives as a run policy: the `capturepolicy` setting (off, manual, annotated or beforeafter) lets the sidepanel toggle state pairs per run, and beforeafter wraps every page moving action with a before shot, the action, an after shot and a `shotpair` record linked to the dom snapshot id of the same moment, while a failed action skips the pair. Export routing is consent layered: memory keeps the bytes in the session store under the user configured capture retention window (expired bytes drop while the metadata survives for the audit trail), clipboard export needs the optional clipboardwrite capability negotiated through the permissions api, and download export runs only through the reviewed download flow behind the optional downloads capability; disk writes outside that flow do not exist. Capture evidence is auditable end to end: every capture writes a `capture` audit event with kind, target and export target, the response envelope gains a capture block with record id, format and byte size, the capture report envelope carries every record and pair, memory stores shotrecords with their bytes and step linkage plus `listcaptures` filtering by run, step and kind, and progress records capture completions and pair ids as reviewable evidence. The sidepanel gains the capture gallery with thumbnails per run, full size opening with metadata and download or clipboard copy actions, shotpairs rendered side by side with a divider control, clickable contact sheet cells, live stitch progress for running full page captures and the capture policy toggle, while the popup shows the capture count of the run beside the policy and the action badge counts captures. Honest notes: webp output re-encodes the png shot on the capture canvas because the visible tab api only returns png or jpeg; horizontally overflowing elements clamp to the viewport width in the tiled fallback which walks the element vertically; fixed header detection compares a sampled pixel band of each tile top against the first tile within the reviewed overlap rows, so headers taller than the overlap can still repeat; the clipboard image write happens in the extension service worker exactly as the 1.1.39 copyscreen step because a service worker cannot borrow the sidepanel document context; and screen capture beyond the page (desktop or tab screencast) stays out of the manifest and out of scope until media capture part two. The vitest suite grows from two hundred sixty eight to two hundred eighty five tests covering the options payload validation of every capture kind, the capturegate with its active tab grant, format, quality and retention validation, stitch tiling with repeating fixed headers, overlap blending math across tile seams, element rect scaling at pixel ratios one, two and three, region capture of a scrollable container, contact sheet grid layout and cell labels, state pairing around a click action with the failed action skip, name uniqueness across a long run, the capture block and options grammar, and capture storage with retention expiry on plain fixtures.

## 1.1.39

This feature release closes phase one of the unlimited agentic core by moving bytes safely and grows the reviewed vocabulary from two hundred eighteen to two hundred thirty one kinds with the files, clipboard and downloads family: ten sensitive kinds (`batchdownload`, `pausedownload`, `resumedownload`, `interceptmime`, `readclipboard`, `writeclipboard`, `copyscreen`, `quarantinedownload`, `scanvirus`, `cleanupartifacts`) and three read only kinds (`verifydownload`, `exportnetlog`, `namecaptures`), every one still a reviewed step behind the session, plan approval and origin gates with the manifest permissions unchanged. The download story is a batch queue with per file states: a `downloadspec` carries the reviewed url list, the filename rule and the completion criterion (`size` or `checksum`), the executor starts each wave under the user configured concurrent window with no code ceiling, resolves filename conflicts with sequence suffixes, persists every `downloadrecord` with its state, browser download id, resolved path, byte count and checksum, and `pausedownload` and `resumedownload` walk the queue transitions (queued to running, running to paused, paused to running, running or queued to complete or failed) through the downloads api while refusing impossible transitions. `verifydownload` is a read only step that compares the recorded state, byte count and checksum against the reviewed expectations; `interceptmime` arms a reviewed `mimefilter` (include patterns, exclude patterns and the deny or allow default for unlisted mime types, with exclude winning over include) whose filename determination listener reroutes matching downloads into a `devthink-quarantine/` path and denies unlisted types under the deny default, only while the session origin grants cover the active origin and never for downloads the extension itself started; the network log collector correlates one record per navigation watch event with its step through request ids (`url`, method, status, timing), `exportnetlog` exports the run with an optional step filter and every header value redacted, and netlog retention is a user setting. The clipboard story is consent first: `readclipboard` requires a reviewed consent ref and an approved single use consent prompt (each execution without one opens the prompt card in the review panel and returns without reading), the read result carries only the length, the payload hash and a masked preview, the payload text never persists in memory, outcomes or logs (`maskclipboard` replaces every payload with a length marker), `writeclipboard` dispatches through the page bridge which reports the write result with the payload hash for audit, and `copyscreen` captures the visible tab into the clipboard as png data with a clip entry hash. The quarantine story gates every release on a scan verdict: `quarantinedownload` moves a download record into the quarantine store outside the downloads folder with a pending verdict, `scanvirus` calls the user configured scanning hook (an HTTPS endpoint behind its optional origin permission) and maps its `{verdict}` response to `pending`, `clean`, `flagged` or `error`, hook failures and unconfigured hooks stay pending instead of releasing, and the release action refuses anything but a clean verdict while auditing every release with its verdict. `namecaptures` stamps consistent capture filenames from task, step and sequence parts with per task counters (`task-step-1.png`, `task-step-2.png`), and `cleanupartifacts` applies reviewed `cleanuprule` sets (age window, artifact kind, keep policy of none, latest or all) against the stored artifact inventory while keeping every artifact referenced by open review cards, recording each sweep in the run history. The correlated logics are grouped by context in `extension/filescommand.ts` (queue transitions, concurrent window, filename conflicts, verification matching, mime matching, header redaction, netlog correlation, clipboard entries, quarantine paths and scan verdicts, capture naming counters, cleanup sweeps and open review references) while `extension/pagebridge.ts` keeps the dispatch seam and `extension/background.ts` keeps the executors, the persistence (downloads, netlogs under the user configured retention, clipboard consent records, clip entries, quarantines, cleanup rules and run history, capture counters, artifact inventory, scan hooks, armed mime filters) and every audit, with four new audit kinds (intercept, clipboard, quarantine, cleanup) beside download and the observation mapping for verifydownload, exportnetlog and namecaptures; the protocol documents the files grammar and adds the downloadreport envelope with per file states, paths and checksums, the netlog report with step correlation and the quarantine report; progress tracks batch downloads as files completed over total with one outcome per settled file; memory gains accessors for every new store plus artifact removal for the sweeper; the side panel gains the files section with the download queue and per file pause, resume and verify actions, the armed mime rules with origin grants, clipboard consent prompts with the requesting step, the netlog viewer with step correlation and the redaction notice, the quarantine list with scan verdicts and release actions, capture naming previews, cleanup policy editing, the artifact inventory with sizes and ages, copyscreen results and the scan hook configuration; and the popup shows the live download states, the quarantined files awaiting scan verdicts in the action badge and the clipboard consent state while a read waits. Honest notes: `verifydownload` compares the browser reported file size and state plus the reviewed checksum when the plan supplies one, because the downloads api exposes no byte stream so checksum verification stays reviewed input based rather than a re hash of the file on disk; the quarantine store keeps files under a `devthink-quarantine/` path through the downloads api filename suggestion rather than moving files on disk, because the manifest deliberately excludes file system permissions; the scan hook posts the quarantine record (id, path, reason) to the reviewed HTTPS endpoint and reads back the verdict, so an absent or malformed response stays pending; and netlog records derive from the navigation watch buffers the extension already observes, which correlate requests with steps through request ids but carry no header values (exports redact any that would appear). The vitest suite grows to 268 tests covering the queue transition table with impossible transitions, the concurrent window as a user choice, filename conflict suffixes, verification matching, mime filter matching with the deny default, netlog correlation and header redaction, clipboard entry hashing without payloads, quarantine release only after clean verdicts, scan hook failure mapping, capture naming counters, cleanup sweeps by age and kind with kept references, the files grammar with consent and origin gates, the download, netlog and quarantine envelopes, every new memory accessor with netlog retention and artifact removal, and the batch download progress share on plain fixtures.

## 1.1.38

This feature release completes the forms and data story by turning filled pages into structured, auditable data and grows the reviewed vocabulary from two hundred one to two hundred eighteen kinds with the forms and data part two family: eight sensitive kinds (`exportcsv`, `exportjson`, `exportexcel`, `copytable`, `pushsheets`, `streamdisk`, `paginateextract`, `resumeextract`) and nine read only kinds (`scrapetable`, `importcsv`, `looprows`, `transformvalues`, `deduperows`, `mergepages`, `stamplerows`, `previewgrid`, `logprovenance`), every one still a reviewed step behind the session, plan approval and origin gates with no new manifest permission. The table reader normalizes headers into stable slugified column keys with unique suffixes, expands rowspan and colspan cells into filled rectangular grids, classifies columns as number only when every present value parses numerically, extracts nested tables into child datasets linked to their parent rows, and the pagination follower resolves the next control from numbered page entries (the entry after the current one, or a next word control) and waits for fresh rows between page turns before merging every page into one aligned dataset. The parameter grammar arrives with five reviewed shapes: a `dataset` with column specs, keyed rows and source refs; a `columnspec` with a stable key, label, value kind and normalized name; a `transformrule` applying one reviewed expression (`trim`, `upper`, `lower`, `number`, `prefix:x`, `suffix:x`, `replace:from=>to`) to source columns and writing the target column, with unsupported expressions surfaced as per rule errors while the original values stay; an `extractsession` tracking visited pages, collected rows and the resume cursor; and a `provenancerecord` keeping the url, timestamp, step ref, row range and checksum of every exported artifact. Consent is graded on the export axis: every kind that moves data out of local memory (csv, json, excel, clipboard, sheet push and disk streaming) is sensitive, and canexecute refuses the export while the session origin grants do not cover the active origin; `pushsheets` additionally requires the explicit reviewed flag, a configured HTTPS sheet endpoint and its optional origin permission, and never a provider lock-in; `copytable` negotiates the optional clipboardWrite capability; extraction row limits, page counts, sample sizes and streaming chunk sizes are user configured with no code ceilings anywhere. The background executors write csv, json and excel artifacts into the task artifact store with deterministic checksums and a provenance record per export, stream large extracts chunk by chunk with backpressure while the stream state stays persisted for resume after a service worker restart, keep extractsession cursors across restarts so `resumeextract` continues an interrupted extraction from its stored cursor, expose dataset rows to `looprows` as step variables through `{{column}}` interpolation into the wrapped inner step so imported csv data can drive fill loops, parse imported csv with quoted fields and reviewed column mappings, deduplicate rows by reviewed keys with removal counts, merge page datasets with gap filling, stamp every row with its source url, timestamp and step ref, and preview grids before any export leaves local memory. The correlated logics are grouped by context: `extension/pagedata.ts` holds the table reader, the span filler, the nested walker, the pagination follower, the row hasher, the transform engine, the merge engine, the sampler and the csv, json and excel serializers; `extension/datacommand.ts` holds the dataset records, artifact exports with checksums, chunk planning with backpressure, cursor advancement, loop variables, provenance records and artifact retention; `extension/pagebridge.ts` keeps the dispatch seam; while `extension/background.ts` keeps the executors, the persistence (datasets, imports, extract sessions, stream states, provenance, task rules, sheet endpoints, exported artifacts under the user configured artifact retention) and every audit, with five new audit kinds (scrape, export, stream, resume, provenance). The protocol documents the dataset, transformrule and extractsession grammars and adds the dataset envelope with column specs and sampled rows, the extraction progress report with page counts, row counts and cursors, and the provenance report per exported artifact; progress tracks extraction as rows collected over the user estimated total and records one outcome per extracted page; memory gains accessors for datasets by id, imported csv datasets, extract session cursors and page histories, stream chunk states, provenance records, transform rules and dedupe keys per task, sheet endpoint configs and exported artifacts with retention. The side panel gains the datasets section with the sortable preview grid, the extraction progress cards with resume prompts for interrupted extractions, per dataset export actions with csv, json and excel choices, transform rule previews, dedupe results with removed counts, provenance records per artifact, the csv import picker with column mapping, the sheet endpoint grant states and the per iteration loop variables on the step timeline; the popup shows the active dataset row count and stream state and the action badge counts the datasets collected in the session. Honest notes: the excel export emits the SpreadsheetML 2003 workbook format because the manifest and the bundle deliberately exclude zip libraries for real .xlsx containers (Excel opens the workbook natively); `streamdisk` streams each reviewed chunk through the persisted stream state into the artifact store rather than a direct file handle, because the manifest deliberately excludes file system permissions; and `resumeextract` steps the reviewed next control forward from the first page, which is the natural state after a reload, rather than assuming the tab still sits on the interrupted page. The vitest suite grows to 243 tests covering header normalization, span expansion, nested table extraction, pagination following with row freshness waits, row hashing and dedupe removal counts, transform expressions and error surfacing, merge alignment, row sampling, csv round trips with quoted fields, column mapping, artifact checksums, chunked streaming with backpressure, cursor resume after a simulated restart, loop variable interpolation, provenance row ranges, retention, the grading and origin gates of the export family, the full data grammar, the dataset, extraction and provenance envelopes, every new memory accessor and the extraction progress share on plain fixtures.

## 1.1.37

This feature release turns the reviewed vocabulary toward structured form work and grows it from one hundred seventy nine to two hundred one kinds with the forms and data part one family: thirteen sensitive fill, submit and wizard kinds (`fillform`, `filllabel`, `fillplaceholder`, `submitform`, `retryform`, `runwizard`, `selectchain`, `picktypeahead`, `pickdate`, `attachfile`, `fillcard`, `fillcode`, `consentpassword`) and nine read only inspection kinds (`detectfields`, `generatevalues`, `saveprofiles`, `asksubmit`, `readerrors`, `skiphoneypot`, `detectlogin`, `detecttemplate`, `handoffcaptcha`), every one still a reviewed step behind the session, plan approval and origin gates with no new manifest permission. The form parameter grammar arrives with four reviewed shapes: a `formrecord` with an optional form selector and non-empty entries of `{ match, kind, value }` where the match is a `fieldmatch` addressing one control by label, placeholder, aria label or name mode; a `valuegen` rule with a field kind, an optional locale and an optional numeric seed; a `formprofile` saved under a reviewed name with its field entries and origin grants; and a `submitticket` recording the form ref, the values hash of the read field values and the consent ref of its asksubmit approval. Field work is consent graded on three axes: every form submission requires an asksubmit review step before it (the proposal parser refuses a submitform or retryform step with no earlier asksubmit, and canexecute rechecks the same gate), every password fill requires the explicit consentpassword kind with a reviewed consent ref while password entries are refused outright inside form records and saved profiles, and generated values are refused whenever they look like real card numbers or personal identifiers — a Luhn valid thirteen to nineteen digit run outside the 4111 test prefix is rejected, as is the dashed identifier shape, so generatevalues only ever emits test prefixed card groups, seeded locale aware names, emails and phones, and deterministic dates, numbers, codes and passwords. The page bridge gains the field matcher that resolves controls by label, placeholder, aria label and name with case insensitive substring matching, the field classifier that infers the twelve field kinds from input type, autocomplete hint and label text (card through `cc-` autocompletes, one time codes through `one-time-code`), the native setter fill that writes each control through its prototype value setter with input and change events, the honeypot detector that flags hidden, offscreen and time trap fields so fills skip them, the login detector that matches a password field plus an identifier with session links, the template detector that matches signup and checkout shapes against known markers, and the error reader that associates validation messages with fields through aria describedby refs and sibling text. Wizard and payment work lands in the same family: `runwizard` advances one step per execution and tracks the wizard state with step index and per step completion flags, `selectchain` selects a parent option then polls for the dependent child option count to change, `picktypeahead` waits for the suggestion list and clicks the reviewed entry, `pickdate` plans the month navigation and day cell click for a reviewed yyyy-mm-dd date, `fillcard` types its reviewed segments group by group with pauses between card number groups, and `fillcode` waits for the reviewed code source before typing. The background keeps the consent heavy work: `saveprofiles` stores form profiles in local memory behind the session origin grants and never stores password entries, `asksubmit` reads the live field values, records the submission ticket with its values hash and opens the prompt through the sidepanel approval surface whose badge count grows with every open prompt, `submitform` verifies the reviewed consent ref against an approved ticket before the page submits through the owning form's requestSubmit, `retryform` enforces the reviewed backoff windows (wait and factor with no code ceiling) between resubmission attempts, `consentpassword` audits the consent ref without ever echoing the password, `attachfile` resolves the reviewed artifact name against the run store before the page fills the file input, and `handoffcaptcha` reads captcha presence through the marker probe, hands control back to the user, records the captcha handoff and pauses the plan until the user resolves it. Memory grows accessors for form profiles with origin grants and timestamps (getprofile by name, replace by name, remove by name), wizard states with step history, submission tickets with values hashes, error reports for correction loops, typeahead picks, captcha handoffs with resolution state, login and template detections per origin and the consent gated one time code; progress tracks wizard completion as executed steps over total steps; audit kinds grow with fill, submit, consent and handoff events; the protocol documents the formrecord, fieldmatch and valuegen grammars and gains the formreport envelope with detected fields, kinds and matched controls, the errorreport envelope with field refs and messages, and the wizardreport carried in the session context with wizard states and typeahead picks. The side panel gains a forms and data surface: the form map with matched fields, kinds and honeypot skips highlighted, generated values with a regenerate button per field, saved profiles with their origin grants plus apply and remove actions, asksubmit cards with the full values diff before approval or decline, wizard progress with step indicators, inline error reports with field refs, login signup and checkout template badges, masked card fill segments and the one time code entry behind the consent gate of an active session; the popup shows the captcha handoff state while a plan waits. The vitest suite grows to two hundred fifteen tests covering the sensitive and read only grading of the whole family, the asksubmit review gate at parse and execution time, the password consent gate and the password refusal inside form records, the generated value refusal for real looking card numbers and personal identifiers, the full form grammar from records and pairs to backoff, chain, typeahead, calendar, card, code and profile shapes, field matching across all four modes, field kind classification fixtures, seeded locale aware generation per field kind, fill operations with honeypot skips and ambiguity refusals, error association and backoff windows, wizard advancement, dependent loads, typeahead picks, calendar plans, artifact attachments, card group splitting and masking, code source readiness, honeypot flags, login and template detection, captcha handoff, every new memory accessor and the wizard progress math on plain fixture shapes without jsdom. Four pragmatic notes are recorded honestly: the honeypot detector infers hidden and offscreen traps from visibility and viewport geometry at execution time while the time trap rule needs creation evidence that a single live pass cannot measure, so the pure detector accepts creation timestamps and the live pass covers the hidden and offscreen reasons; the one time code entry stores the reviewed code in local storage behind the consent gate of an active session and the reviewed source is the only source the page filler waits for, because the clipboard and artifact sources have no background delivery path yet; submission tickets carry the values hash rather than the values themselves, so the sidepanel renders the full values diff from the asksubmit step outcome while the ticket proves the approval; and calendar picking reads the visible month header to plan navigation, which works for the common widgets but stays a heuristic rather than a widget protocol. The required permission set is unchanged (`activeTab`, `storage`, `scripting`, `sidePanel`), the optional capability set stays `tabs`, `downloads`, `clipboardRead`, `clipboardWrite`, and the manifest key stays untouched.

## 1.1.36

This feature release gives the agent command over the whole browser surface on top of the 1.1.35 navigation mastery and grows the reviewed action vocabulary from one hundred forty seven to one hundred seventy nine kinds, with twenty four new sensitive tab and window command kinds and eight new read only tab kinds, every one of them still a reviewed step behind the session, plan approval and origin gates and the optional tabs capability. The tab and window parameter grammar arrives with four reviewed shapes: a `tabquery` with url, title, id and pattern matchers where at least one matcher is required and patterns use `*` and `**` wildcards; a `tabgroupspec` with name, Chromium tab group color, member tab ids and collapse state; a `tablayout` with name, tabs carrying positions and pin state, groups and window bounds; and a `windowstate` with bounds, maximize state and a profile kind that separates normal, scratch and incognito windows. Tab queries and enumeration arrive with `querytabs`, which resolves the reviewed matchers against the live tab set and returns a tab report whose entries carry audio state and per tab metadata, `searchtabs`, which searches across open tabs by title and url, `findclones`, which detects duplicate tabs by normalized url comparison that ignores fragments and trailing slashes, `listaudio`, which lists the tabs that are playing audio, `watchtab`, which observes tab title, activation and closure events across a reviewed lifetime window through persisted registrations that survive service worker restarts, and `snapshotsession`, which captures the full session of tabs and windows as a stored snapshot. Tab mutation covers `duplicatetab` with its history, `closepattern`, which closes every tab matching a reviewed pattern only under the explicit reviewed flag and always refuses to close the session tab itself, `pintab` and `mutetab` by reviewed flags, `movetab` to a reviewed index, `movetabwindow` across windows, `reloadtabs` over a reviewed id list, `zoomin` and `zoomout` by a reviewed step that never crosses zero, `switchtab` to the next or previous tab with wraparound, `discardtab`, which releases only inactive and unpinned tabs while their urls survive for on demand restore, `restoretab` from the closed tab history, `reopenrun`, which reopens the tabs of a previous run from its snapshot, and `badgetab`, which sets a per tab task status badge refreshed from the live progress state of each task. Window command covers `maximizewindow`, `minimizewindow`, `restorewindow` to reviewed bounds, `focuswindow`, `scratchwindow` for split work, and `incognitowindow`, which opens a private window only on the explicit reviewed request and stays separated from the session grant inheritance. Groups and layouts turn the browser into plan targets: `grouptabs` groups related tabs under a reviewed name and color, `colorgroup` and `collapsegroup` update a stored group, `savelayout` saves the current tab layout under a name with its window bounds and group states, and `restorelayout` brings back only the urls that are not already open; group and layout mutations refuse to run outside the active session. Memory grows accessors for named layouts with timestamps, tab group definitions with their color choices, tabmeta records with task refs, provenance and free text labels that route through the plan progress, session snapshots, the closed tab history, badge states per task, the watchtab event stream, scratch window ids and the pinned control tab state; progress tracks tasks across their assigned tabs so the window close gate can demand review, badges refresh from live progress, and the popup badge now counts the tabs with active tasks beside the queued navigation targets; audit kinds grow with group, layout, discard and badge events; the protocol documents the tabquery, group and layout grammars and gains a tabreport envelope with matches, groups and badges plus a layout report carried in the session context. `tabcreate` gains a reviewed background option that never activates the new tab and a window option that targets a specific window, `windowcreate` gains reviewed left, top, width, height and state options, and `windowclose` requires explicit review whenever the window holds more than one task tab. The side panel gains a tabs and windows surface: a quick switcher listing tabs by recency with filter keys and jump actions, a searchtabs runner with jump to tab results, tab groups with their colors and collapse states, per tab task badges, pin state and audio marks, duplicate tab warnings from findclones, layout save and restore from the session menu, the session snapshot card with restore actions, the concurrent task tab budget shown as a user configured gauge whose ceiling is set from the panel and never in code, a prompt before closing windows that hold task tabs, and the pinned control tab feed with live task status; the popup shows the current window layout with quick maximize, minimize and restore buttons. Consent stays exactly where the chain requires it: every close still asks for consent through the explicit reviewed flag, the whole family negotiates the optional tabs capability before execution, layout mutations stay inside the active session, and no hardcoded cap was added to any user configurable value. The vitest suite grows to one hundred ninety five tests covering the tabquery grammar and matching, clone detection, group membership across moves and renames, layout save and restore with window bounds, watchtab event dispatch, discard and restore of inactive tabs, incognito separation from session grants, badge updates from progress state, snapshotsession capture and reopenrun restore, the tabcreate and windowcreate option grammar, closepattern matching with consent refusal paths, sensitive and read grading, the window close gate, the layout session gate, every new memory accessor and the task tab budget as a user choice on plain fixture shapes. Three pragmatic notes are recorded honestly: tab group membership, colors and collapse states live in the Devthink group registry instead of the Chromium tabGroups api because the manifest deliberately excludes that permission, so group steps move member tabs and keep registry state rather than calling the native api; opening an incognito window requires the user to allow the extension in incognito mode, and the window never inherits the session origin grants; and watchtab steps observe browser tab events from the background worker whose event listeners fill persisted event streams, so a lifetime that outlives the service worker idles is reconciled on restart like every other watch registration. The required permission set is unchanged (`activeTab`, `storage`, `scripting`, `sidePanel`), the optional capability set stays `tabs`, `downloads`, `clipboardRead`, `clipboardWrite`, and the manifest key stays untouched.

## 1.1.35

This feature release gives the agent navigation mastery on top of the 1.1.34 observation depth and grows the reviewed action vocabulary from one hundred eighteen to one hundred forty seven kinds, with twenty new sensitive navigation kinds and nine new read only navigation detection kinds, every one of them still a reviewed step inside the session origin gates. The navigation parameter grammar arrives with three reviewed shapes: a `navtarget` with url, container (`current`, `tab`, `window` or `private`), position and private flag; a `waitprofile` with non-empty load signals, idle and timeout thresholds and per origin overrides; and a `urlpattern` with an `exact`, `prefix`, `host` or `pattern` match mode (with `*` and `**` path wildcards), required query parameter expectations where `*` matches any value, and a fragment part. Container navigation opens pages without leaving the current one: `openlink` opens a reviewed url in a new tab or window, `openprivate` opens it in a private window whose resolved container stays separated from normal windows, `reopentab` restores the most recently closed tab whose url is remembered through tab watchers, `deeplink` builds a deep link into a common web app (github repositories, youtube videos or searches, maps queries, wikipedia articles, amazon searches and x profiles) from a reviewed app pattern and params, and `openclipboard` opens a url read from the clipboard on the explicit consent of the approved step behind the optional clipboard read capability. Page world navigation covers `reloadcache` which reloads bypassing the browser cache through the tabs api, `stopnav` which halts a pending document load, `waitload` which waits for the load event and reports the ready state and load phase, `waiturl` which polls until the url matches the reviewed pattern, `followlink` which follows a link matched by its visible text or by its href fragment when the reviewed option asks for it and refuses ambiguous matches, `spanav` which clicks a reviewed control and waits for the route change without a reload, `spawait` which waits for a single page app url change through popstate, hashchange and history polling, `rewritequery` which reads the current query parameters, applies reviewed set and remove edits through pushstate and reports the parameters read and the new url, and `setfragment` which sets the url fragment and scrolls to its anchor with smooth behavior. Sequential and stateful navigation covers `navlist`, which navigates a reviewed list of urls one entry at a time with every entry recorded in the plan progress as it completes and the current url and remaining count rendered in the review panel, `navprofile`, which applies a per site wait profile stored per origin so following steps consult its signals and thresholds, `navintent`, which records the navigation intent detected from the plan for audit review, `pausenav`, which pauses navigation while a consent prompt is open and resumes it on the next review, and `trailaudit`, which restores the navigation trail of the session for audit. Safety and network state navigation covers `checksafe`, which verifies a url for HTTPS protocol, embedded credentials, private network targets and raw ip hosts and stores the verdict, `batchopen`, which curates a reviewed link list with per url safety states and refuses to open the whole batch when any url is unsafe, `prefetch` and `preconnect`, which verify their candidates against the session grants before injecting prefetch and preconnect hints into the page, `detecthttp`, which reports the http error, offline and certificate interstitial states with reasons, `readredirects` and `readfinalurl`, which return the observed redirect chain with statuses and timing and the final url after redirects, and `handleauth`, which answers a basic auth prompt from credentials stored only after the user reviews them behind the consent gate of an active session, while `printpdf` prints the page and routes the artifact record into the task artifact store. Consent gates stay exactly where 1.1.34 left them: navigation that would move a granted task tab outside the session origin grants is refused until the user consents through a grant, an unreviewed origin refuses to open until a safe checksafe verdict vouches for it, `navlist` refuses to start outside an approved session plan, the per domain navigation rate limit of `navrate` is a user configured window and ceiling with no hardcoded cap and every navigation the background performs counts against it, paused navigation blocks the navigation family until it resumes, and navigation kinds that create tabs or windows negotiate the optional tabs capability while `openclipboard` negotiates clipboard read. Memory grows accessors for the navigation trail per session with timestamps and step refs, wait profiles per origin with user configured values, navigation records with redirect chains and final urls per step, navintent records, rate limit windows per domain, curated link lists with their review state, reviewed basic auth records per origin, printpdf artifacts, the navigation control state, url safety verdicts, recently closed tabs and the queued prefetch and batch open target counts that drive the popup badge; audit kinds grow with navigation, redirect, auth, prefetch and rate events; the protocol documents the navtarget, waitprofile and urlpattern grammars and gains a navstate envelope with load phase, final url and redirect chain, a navigation trail report carried in the session context, and a safety verdict envelope. The side panel renders the navigation trail as a timeline of visited urls, redirect chains and final urls on navigation steps, the navlist progress with the current url and remaining count, rate limit windows per domain in the session card, paused navigation highlighted while a consent prompt holds it, curated link lists with per url safety states before batch opening, a checksafe runner for any external link target and the basic auth credential prompt behind the consent gate; the popup shows the load phase, offline state and active wait profile beside the badge count of queued prefetch and batch open targets. The vitest suite grows to one hundred sixty tests covering the navigation grammar, risk grading, rate window math, wait signal evaluation, url pattern matching, query rewriting, link matching, deep link building, redirect chain assembly from navigation watch fixtures, spa route classification, http and interstitial detection, safety verdicts, batch refusal on unsafe urls, prefetch grant checks, auth credential gating and every new memory accessor on plain fixture shapes. Three pragmatic notes are recorded honestly: redirect chains are assembled from tabs onUpdated url transitions because the manifest deliberately excludes the webNavigation permission, the isolated world cannot intercept history pushState so spa route waits listen for popstate and hashchange while polling the url as a fallback, and the native basic auth prompt cannot be programmatically answered without the webRequest permission the manifest also excludes, so handleauth verifies and arms the reviewed credentials, audits the flow with the password kept out of every step detail, and printpdf drives the browser print pipeline whose output the extension records as a task artifact rather than capturing the pdf bytes itself. The required permission set is unchanged (`activeTab`, `storage`, `scripting`, `sidePanel`), the optional capability set stays `tabs`, `downloads`, `clipboardRead`, `clipboardWrite`, and no hardcoded caps were added to any user configurable value.

## 1.1.34

This feature release gives the agent every way to see on top of the 1.1.33 interaction universe and grows the reviewed action vocabulary from ninety to one hundred eighteen kinds, with all twenty eight new kinds graded read only and grouped into passive, watching and diffing observation modes behind the same session, plan approval and origin gates. Passive observation arrives with `a11ytree`, whose walker pierces open shadow roots and same origin iframes (frame nesting bounded only to refuse recursive self embedding) and converts the page into an accessibility tree of roles, accessible names, states and values with hidden subtrees excluded; `readvisible` returns the rendered text of each visible element; `readertree` scores text density to split the densest article region into a reader view with title, byline, blocks and word counts; `readoutline` returns the heading outline; `readselection` reads the current user selection; `readopengraph` extracts open graph fields and structured data payloads while refusing malformed ones; `readlang` resolves the page language from the document lang attribute, the content language meta and stopword based content signals in that order; and `detectlanguage` tags extracted text with its detected language code so it routes to the matching language stream. Page shape detection adds `detectlists`, which samples sibling structures and infers the shared item selector of repeated lists, `detecttables` with normalized header rows, column specs and captions, `countpages` estimating the total from the pagination entries the page itself renders, `detectinfinitescroll` measuring scroll ranges and load more triggers, `detectvirtual`, `detectlazy`, `detectsticky` measuring fixed and sticky geometry against the viewport, `detectscrolllock` surveying overflow, body position and modal state, `readscrollpos` with edge flags, `classifypage` and `fingerprintsection` storing stable structural fingerprints per origin, and `listshadow` and `listframes` enumerating open shadow root host paths and iframes with their origins and sizes. The watch vocabulary observes over reviewed lifetime windows: `watchmutate` batches MutationObserver records inside reviewed selector scopes through a reviewed poll interval, `watchfocus` records focus and blur events with element paths, `watchbanner` polls the consent banner shape matcher across a keyword vocabulary and reports banner controls, `waitquiet` samples in flight requests through the performance timeline until the reviewed idle threshold holds or the reviewed timeout ends with no code ceiling, and every watch registration is persisted so it survives service worker restarts, audited with its reviewed window, reconciled when a restart finds a window that ended while the worker was down, and counted as completed only once the window closes. `diffsnapshots` requires exactly two reviewed observation versions, the background loads both stored captures, injects their node summaries into the bridge, the diff engine hashes them into added, removed and changed sets, and the version pair attaches to every diff result; `readjson` extracts embedded json state from inline scripts, refuses malformed payloads and stays gated behind the session origin grants; `deriveselector` ranks id, attribute, text and structural selector candidates by stability score and stores the best for reuse. Memory grows accessors for observation versions, a11y trees and reader articles under a user configured observation retention, mutation, focus and banner event streams per session, snapshot diffs with their version pairs, derived selectors with stability scores, and detected templates and section fingerprints per origin; audit kinds grow with observation, watch and diff events; the protocol envelope gains a11y, reader, listpattern, tableshape and diff sections, mutation, focus and banner event records, snapshot diff payloads, derived selector candidates and a context payload reporting the detected page language, template class, scroll lock and banner state. The side panel renders the accessibility tree beside the dom snapshot, the reader view with heading blocks highlighted, detected lists, tables and pagination shapes as plan suggestions the user can pick as target hints, the live mutation and focus stream, snapshot diff rows colored by change kind, a consent banner review card before any interaction, derived selector candidates with their stability scores and network quiet progress during waitquiet steps; the popup shows the page language, template class and scroll lock state. The vitest suite grows to one hundred twenty four tests covering the read only grading, watch lifetimes, quiet rules, diff version pairs, origin gated json reads, the observation envelopes, event records, diff payloads, page signals and every stored evidence accessor on plain fixture shapes. Two pragmatic notes recorded honestly: the virtualization detector infers row recycling from uniform rendered row geometry against the measured scroll range instead of performing a reviewed scroll, because observation kinds never mutate the page, and the lazy image detector inspects loading attributes and deferred sources because registered intersection observers are not inspectable from the isolated world; likewise the accessibility tree is built by the bridge walker with explicit and implicit roles rather than the Chrome debugger accessibility backend, which the manifest deliberately excludes. The required permission set is unchanged (`activeTab`, `storage`, `scripting`, `sidePanel`), the optional capability set stays `tabs`, `downloads`, `clipboardRead`, `clipboardWrite`, and no hardcoded caps were added to any user configurable value.

## 1.1.33

This feature release completes the interaction universe on top of the 1.1.32 core and grows the reviewed action vocabulary from sixty three to ninety kinds. Pointer travel becomes reviewable: `movepointer` follows a reviewed `pointpath` with start, end, waypoints and duration while honoring a `speedprofile` of easing shape, peak velocity and jitter window, dispatching pointerover, pointermove and pointerout events and settling every hop; `clickpoint` clicks reviewed viewport coordinates through the full pointer sequence; `shiftclick` clicks with the shift modifier for range and multi selection. Element addressing stops depending on css selectors alone: a reviewed `targetref` may use `selector`, `text`, `aria`, `name`, `xpath`, `index` or `point` mode, resolved against the live dom at preview and execution time in one pass, with `clicktext`, `clickaria`, `clickname` and the read only `resolvexpath` as convenience kinds, ambiguous matches refused with candidate lists, and a `resolvedtarget` summary attached to step results, outcome envelopes and pre approval previews. The typing and control surface adds `typetime` with a per keystroke delay, `appendtext`, `setvalue` through the dom property with input and change events, `typeedit` for content editable regions, `submitsearch` that presses enter and waits for the reviewed results region, `selectmulti`, `chooseradio`, `setslider`, `setdate`, `setcolor` and `expanddetails`. `keyhold` and `keyrelease` press and release keys across steps under reviewed hold ids kept in a persisted registry that survives service worker restarts, with press and release timestamps audited. `dismissdialog` answers unexpected confirm, alert and prompt dialogs per a reviewed `dialogpolicy` installed in the main world through the scripting api, because the isolated world cannot override window dialogs; every decision is audited with the dialog text and the reviewed answer, prompts refuse to run without a reviewed answer, and a persistent auto handler is armed for session tabs once the user has approved a plan carrying a dialog policy. `pierceshadow` resolves and clicks targets across open shadow roots and `enterframe` routes a wrapped step through same origin iframes by reviewed frame path, refusing cross origin hops and staying inside the session origin grants. `retryaction` re-runs a failed interaction under a reviewed `retryrule` of attempts, settle window and movement tolerance with no code ceiling, revalidating the target geometry between attempts and recording attempts and movement deltas. The read set gains `mapclicks`, `verifyvisible` and `verifyenabled`; every clickable element is numbered into a `clickablemap` stored under its observation version, so the review panel renders the numbered list beside the plan and lets the user pick an entry as the target hint for the next plan input. Every new kind passes the same session, plan approval and origin gates established in 1.1.32, the required permission set is unchanged (`activeTab`, `storage`, `scripting`, `sidePanel`) and the optional capability set stays `tabs`, `downloads`, `clipboardRead`, `clipboardWrite`. Memory grows accessors for clickable maps, key holds, dialog decisions, retry outcomes, resolution summaries and the default dialog policy; audit kinds grow with pointer, dialog, hold and retry events; the popup shows held keys and answered dialogs in the live status card; the side panel groups the new kinds into pointer, typing, keys, controls, dialogs, frames and retry rows, shows resolvedtarget details before approval, highlights ambiguous resolutions and asks the user to choose a candidate, renders hold ids on key hold and release steps, and marks retry attempts on the step timeline. The vitest suite grows a pagebridge family that exercises resolution modes, the xpath subset, pointer math, control math, the hold registry, dialog policies, frame walking and the retry loop on plain fixture shapes without a live dom, while policy, protocol, memory and progress tests cover the new risk classes, options grammar, envelopes and stored evidence.

## 1.1.32

This feature release removes every arbitrary bound from the consent-first library and grows the reviewed action vocabulary from eleven to sixty three kinds. The action set now covers the full pointer and keyboard surface (`presskey`, `clickdeep`, `rightclick`, `doubleclick`), html5 drag and drop (`drag`, `drop`), file `upload`, form state control (`clear`, `check`, `uncheck`, `toggle`, `submit`), page movement (`reload`, `back`, `forward`, `scrollpage`, `scrollby`, `scrollend`, `scrolltop`), a complete read vocabulary (`readattribute`, `readstyle`, `readgeometry`, `readvalue`, `readtext`, `readhtml`, `countelements`, `readtable`, `readlinks`, `readimages`, `readmeta`, `readforms`, `readstorage`, `waitfor`, `waittext`, `highlight`), page mutation under review (`setattribute`, `removeattribute`, `writestorage`, `evaluate`, `fullscreen`) and browser-level command (`tablist`, `tabcreate`, `tabactivate`, `tabclose`, `tabreload`, `tabsnapshot`, `windowlist`, `windowcreate`, `windowclose`, `zoomset`, `windowresize`, `downloadfile`). Every bound is now a user choice rather than a code ceiling: wait durations have no cap, plans accept any number of steps, plan expiry is proposal configured, the audit trail and step outcome history keep configurable retention with an unlimited default, and snapshots capture every interactive element, every form control, every select option and the complete page text. Steps carry a reviewed JSON `options` field for modifiers, amounts, coordinates and similar parameters, and step results now return structured `details` payloads that the side panel renders beside each reviewed step. The optional capability model arrives with this release: the manifest declares `tabs`, `downloads`, `clipboardRead` and `clipboardWrite` as optional permissions, the background negotiates the granted set through the permissions api, browser kinds refuse to run without their capability, the review panel can request a grant, and every grant is audited. The required permission set is unchanged (`activeTab`, `storage`, `scripting`, `sidePanel`), navigation remains inside the approved origin, and every sensitive kind still requires the same session, approval and origin gates. The side panel groups steps by risk class, shows plan completion progress and the live capability report; the popup shows the same capability status. Sessions now record an origin grants list prepared for multi origin work, progress preserves prior history snapshots when a plan is replaced, and the observation schema is versioned for forward compatibility. A follow-up correction on the same day restored the stable extension identity key that this release had accidentally corrupted during manifest editing: the corrupted key was not strict base64 and Chrome for Testing refused to start the profile with the packaged extension, which the isolated smoke test caught; the manifest gate now decodes the key strictly (base64 alphabet and length, DER sequence header, declared length match and the published 294 byte RSA subject public key) so a corrupted identity key can never reach a packaged release again, and the never published v1.1.32 tag was deleted and recreated from the corrected source.

## 1.1.31

This feature release expands the consent-first action vocabulary, adds session pause control, closes plans automatically when every reviewed step has executed, and widens the passive CRX evidence catalogue. The page bridge now supports five new reviewed step kinds — `scroll` (bring one reviewed target into view), `select` (choose one existing option of a reviewed select element), `hover` (deliver bounded hover events to one reviewed target), `extract` (read-only bounded text or link extraction) and `wait` (a bounded pause of at most ten seconds) — all gated by the same session, plan-approval, tab and origin checks, with `select` classified as sensitive like typing. Sessions can now be paused and resumed from the popup; a paused session blocks every execution and preview while keeping the session and plan alive, and both transitions are audited. Plan progress is tracked per step, the side panel marks completed steps, and an approved plan is closed as `completed` once its last reviewed step finishes. Proposals may now carry up to fifty reviewed steps, and snapshots record bounded select options so agents can propose valid `select` steps. No new browser permission is requested: the package still uses only `activeTab`, `storage`, `scripting` and `sidePanel`. The evidence catalogue grew from 58 to 67 reviewed Chrome extension IDs — adding Selenium IDE, Instant Data Scraper, Table Capture, Copyfish OCR and Session Buddy — with 62 manifests now verified; the four update-service 404 results and the one non-CRX store artifact are recorded as unavailable rather than guessed.

## 1.1.30

The v1.1.29 hosted diagnostic established that branded Google Chrome blocks the command-line loading of the temporary unpacked Devthink package (`ERR_BLOCKED_BY_CLIENT`). This behavior is intentional for ordinary Chrome builds; the Chromium Extensions team recommends Chromium or Chrome for Testing for automated extension tests. CI now uses the stable Chrome for Testing binary provided by `browser-actions/setup-chrome@v2.2.0`, whose documented default source is Chrome for Testing, and passes its explicit output path to the same temporary-profile smoke test. No unsafe compatibility flag is added, and the extension's runtime permissions or behavior do not change.

## 1.1.29

The v1.1.28 hosted run showed that Chromium can load Devthink's local popup while the DevTools evaluation context intentionally has no `chrome.runtime` object. Requiring an idle MV3 worker target after that inspection therefore produced a false negative: extension service workers are event-driven and may be suspended when no supported browser event is active. The smoke test now proves the packaged extension is registered under its stable ID in the temporary profile, confirms the declared `background.js` MV3 bundle exists, and checks that the real Devthink popup DOM loads in the isolated browser. It does not execute any extension action, contact any endpoint, load an external page, use a user profile, or inspect credentials.

## 1.1.28

The v1.1.27 diagnostic identified a syntax error in the test's DevTools expression: the fallback template literal for a rejected local context request was missing its closing delimiter. This patch replaces it with ordinary string concatenation. The evaluated request remains `chrome.runtime.sendMessage({ kind: "context" })` inside Devthink's own temporary popup and still cannot perform any browser, permission, navigation, form or network action.

## 1.1.27

The v1.1.26 runner opened Devthink's local popup but the read-only context evaluation returned no value. This patch retains the same local-only context request and strict worker requirement, while reporting the bounded DevTools evaluation exception or protocol error instead of only `undefined`. It does not modify extension permissions, browser actions, profile isolation, remote endpoints or runtime data handling.

## 1.1.26

The v1.1.25 diagnosis confirmed that the hosted runner opens Devthink's local popup but does not eagerly retain its MV3 worker. This patch adds one bounded, read-only wake-up check: through the existing loopback debugger, it evaluates the same `chrome.runtime.sendMessage({ kind: "context" })` request that the popup issues on load, waits for its response, and then requires the matching worker target. The message reads only Devthink's own local session/configuration context and cannot navigate, click, type, grant permissions or send data to a remote endpoint.

## 1.1.25

The v1.1.24 hosted runner still did not expose its DevTools target list while Chrome was launched directly at a `chrome-extension://` URL. This patch starts the same isolated browser at `about:blank`, waits for its local loopback endpoint, then opens only Devthink's stable-ID `popup.html` through that endpoint and separately waits for its page and MV3 worker. The profile remains temporary and Devthink-only; no external page, user profile, credential, form or browser action is accessed.

## 1.1.24

The v1.1.23 diagnostic showed no readable DevTools target list during its ten-second startup window; hosted Chrome initialization had consumed a material portion of that window before the profile was ready. This patch removes verbose Chrome tracing and extends only the bounded wait for the disposable browser's local DevTools endpoint and Devthink popup/worker targets to thirty seconds. It changes no extension capability, host access, profile source, network target or action behavior.

## 1.1.23

The v1.1.22 GitHub-hosted run still did not expose the expected local popup or worker, whereas both isolated local modes passed. This diagnostic corrective release preserves the strict pass condition and adds bounded Chrome startup logging plus a compact list of observed local DevTools target types and URLs only when it fails. This evidence is limited to the disposable profile and local browser endpoints; it contains no personal URLs, profiles, credentials, form data or external-page content.

## 1.1.22

The v1.1.20 hosted Chrome run showed that loading an unpacked extension alongside `about:blank` does not reliably start an MV3 worker on that runner. With the stable public manifest key now available, the test derives Devthink's extension ID from that public key and opens only Devthink's own local `popup.html` as the initial page. The pass condition requires that exact local page and its matching `background.js` service worker in the loopback DevTools targets. The fresh profile, Devthink-only allowlist, virtual display, bounded wait and removal of all temporary files remain unchanged.

## 1.1.21

The v1.1.20 virtual display started correctly, but the hosted Chrome process still did not register an unpacked extension worker. This patch adds a public development key to `manifest.json`, giving the unpacked Devthink package a stable extension identity across temporary directories and runners. No private key is stored, transmitted or required at runtime. The smoke test remains a local, profile-isolated check of the packaged ZIP and Devthink-only worker target.

## 1.1.20

The v1.1.19 profile was correctly limited to Devthink, yet the GitHub-hosted `google-chrome --headless=new` process still did not expose extension workers while the same isolated invocation did locally. The CI test now runs Chrome in a disposable virtual display instead of headless mode. It retains its fresh profile, loopback-only debugging endpoint, unpacked ZIP, Devthink-only extension allowlist, bounded timeout and cleanup. It loads no external site or user profile and performs no browser action.

## 1.1.19

The v1.1.18 runner still did not report the expected Devthink page or worker because it tried to infer the profile registry before Chrome had created that optional preferences file. This patch explicitly allows only the unpacked Devthink directory, then waits for its MV3 `background.js` service-worker target in Chromium's loopback DevTools list. The test neither reads a personal profile nor opens an external page; the temporary profile is deleted after the bounded verification.

## 1.1.18

The v1.1.17 smoke test correctly discovered Chromium's dynamic loopback debugging port, but MV3 service workers are intentionally lazy and the GitHub-hosted browser did not start one for an otherwise idle `about:blank` launch. This patch keeps the temporary profile, unpacked release ZIP and loopback-only debugger. After Chromium starts, the test deterministically derives the unpacked extension ID from its temporary directory, opens the extension's own local `popup.html` through the debugging protocol, and then requires both that extension page and its MV3 service worker to appear. No external website, user profile, credential, page form or browser action is touched.

## 1.1.17

The v1.1.16 source/tag synchronization succeeded, but the isolated Chromium smoke test stopped before the registry and release jobs. The test assumed a predetermined debugging port, which can be unavailable on a shared GitHub-hosted runner. This corrective release keeps the isolated temporary profile and unpacked ZIP test, but asks Chromium for an ephemeral loopback debugging port and reads the browser-created `DevToolsActivePort` file. It now records a bounded local launch diagnostic if Chromium exits early, and still accepts success only when the extension's MV3 service worker appears in the browser target list.

## 1.1.16

This release simplifies the NuGet source layout by moving its only distribution identity file to the repository root and removing the unnecessary `nuget/` folder. The package ID, embedded extension ZIP and versioned release behaviour remain `extension` and are validated by the NuGet package test.

The release also adds a consent-first **target preview**. During review, a user can temporarily highlight the currently resolved target of a reviewed `focus`, `inspect`, `click` or `type` step. The preview checks the live active tab, session, origin, plan expiry and target selector; it does not change form values, navigate, issue network requests or execute the action. The highlight clears itself automatically and executing an action still requires a separately approved plan plus a fresh target check.

The documentation now contains a refreshed passive CRX inventory of all 58 supplied identifiers (57 manifests verified, one unavailable response), aggregate permission and transport matrices, source-linked public reference summaries, and an independent Devthink architecture that excludes broad browser permissions, credential access, covert automation and third-party protocol reuse.

## 1.1.15

The v1.1.14 release verified the updated Node, npm, pnpm and Bun toolchain and completed the npm, GitHub Packages, Maven and NuGet jobs, but the Node 26.8.1 container image no longer ships Corepack. Its container job therefore stopped before GHCR publication and asset aggregation; the v1.1.14 tag remains immutable.

This patch removes Corepack from the container build. The container reads the declared npm minimum and the exact pnpm `packageManager` pin from `package.json`, installs those versions directly, verifies them, and only then installs the frozen lockfile. This keeps the image reproducible as Node 26 evolves and avoids a second untracked package-manager version. The original release chain is otherwise unchanged and will run automatically from the v1.1.15 `main` push.

## 1.1.14

The release workflow no longer contains the consumed `migratelegacynuget` job. The historical migration had already deleted only `Wenathlan.Devthink.Extension` in v1.1.12; future releases no longer carry any package-deletion capability. The current NuGet package remains `extension`.

The supported build baseline now pins Node 26.8.1 and declares bounded Node 26.x, npm 12.x and Bun 1.x compatibility. Direct development dependencies were refreshed from npmjs, and verification installs the declared npm version plus a Bun smoke check for the compiled CLI. The maintenance workflow now reads current stable releases from Node's official index, npmjs and official GitHub Action releases, updates only non-breaking lines automatically in a reviewable pull request, refreshes the lockfile, and uses the proposed runtime during validation.

The documentation layout is normalized to a flat `docs/` directory. The existing evidence-only CRX analysis records are retained, their generators now write to the flat layout, and the catalogue distinguishes store claims, manifest facts and source-verified architecture from implementation claims.

## 1.1.13

Corrects the release checksum manifest so its entries are bare asset filenames rather than runner-local `release/` paths. The aggregate job now excludes `SHA256SUMS.txt` from its own digest input, sorts the exact filenames and writes a manifest that can be verified directly after downloading the GitHub Release assets into one directory. The v1.1.12 release remains immutable; its package migrations and registry publications succeeded, while this patch repairs the independently discovered artifact-verification defect.

## 1.1.12

This release adds one bounded, idempotent migration step for the explicitly superseded GitHub Packages NuGet identifier `Wenathlan.Devthink.Extension`. It runs only from the automatic `main` push release for 1.1.12, first reads the exact organization-scoped package endpoint to prove the identifier, type and namespace, and deletes only that complete legacy package with the workflow token. A missing legacy package is reported as an idempotent no-op; an authorization or API error fails the migration rather than falling back to another name. The current NuGet package `extension`, all release tags and all other registries are outside this operation.

The release documentation now records that v1.1.10 reached all non-npm targets but its npm jobs misinterpreted an artifact path without `./` as a Git source. The v1.1.11 automatic corrective release used an explicit local tarball path, completed the public npmjs publication, and attached the extension ZIP, npm tarball, source ZIP, NuGet package, Maven descriptor, container reference/digest/JSON, isolated notes and SHA-256 manifest to its GitHub Release.

## 1.1.11

Corrects the automatic release publisher to pass the generated npm tarballs as explicit local paths. The v1.1.10 release used a path without `./`, causing npm to resolve it as a Git source rather than the downloaded release artifact. Version 1.1.11 preserves the immutable v1.1.10 tag and reruns the full automatic chain with idempotent registry checks.

## 1.1.10

Release automation now starts from a push to `main` that changes `package.json` or `CHANGELOG.md`. It synchronizes all derived metadata and isolated release notes, creates the immutable `v1.1.10` tag if that version has not already been released, validates that commit, and then publishes the full extension release without a manual workflow dispatch.

The GitHub Release receives the extension ZIP, npm tarball, source archive, NuGet distribution package, Maven descriptor, container reference, container digest, release notes and a SHA-256 manifest for every attached binary or archive. The public npmjs package is published automatically after `npm whoami` confirms the configured `NODE_AUTH_TOKEN` or fallback `NPM_TOKEN`; an existing exact package version is skipped idempotently. Routine dependency and workflow updates remain reviewable pull requests, while cache retention runs automatically after successful security analysis and on a daily schedule.

The NuGet distribution identifier remains exactly `extension`. Older NuGet packages are intentionally retained pending an explicit package-specific migration confirmation, because deleting a published package is destructive and can break existing consumers.

## 1.1.9

This release publishes the corrected NuGet distribution under the package ID and assembly name `extension`, with no `Wenathlan` or `Devthink` prefix. The root descriptor, distribution source, release workflow and generated NuGet metadata were reaudited together; the Maven artifact remains `extension` while its mandatory Maven group stays `io.github.wenathlan`.

The versioned release is required because existing registry packages and tags are immutable. The v1.1.9 tag is the first published NuGet package expected to display exactly `extension`.

## 1.1.8

The NuGet distribution identifier and assembly name are now `extension`. The Maven artifact identifier was already `extension`; its `io.github.wenathlan:extension` form remains the mandatory Maven group-and-artifact coordinate. The npm package remains `@wenathlan/extension`, because the unscoped npm name `extension` is independently owned and already published.

The npmjs publication step now accepts the organization-provided `NODE_AUTH_TOKEN`, falling back to `NPM_TOKEN`, without revealing either value. It remains intentionally gated by the repository variable `PUBLISH_NPM=true` so a release cannot publish publicly by accident.

## 1.1.7

This metadata-correction release adds the README to the canonical version synchronization check and maintenance workflow. The package overview, capability table and protocol payload example are now always derived from `package.json`, alongside the extension manifest, library protocol, popup, Maven descriptor, NuGet descriptor, release gates and isolated release notes.

It corrects the stale README values present in earlier release assets without moving any immutable prior tag. The v1.1.7 release tag is the complete distribution where all declared version metadata is validated as one coherent set.

## 1.1.6

This final release-pipeline correction installs both `zip` and `unzip` in the GHCR validation image. The image can therefore generate and inspect the reproducible Devthink extension archive while executing the same release gate used by GitHub Actions.

The immutable v1.1.3, v1.1.4 and v1.1.5 tags remain unchanged. Version 1.1.6 is the tag that includes all release-path repairs and is used to complete the container publication and attestation path.

## 1.1.5

This corrective release completes the v1.1.4 release recovery. The GitHub Packages npm job now checks out the release tag before loading the canonical Node version, and the GHCR validation container installs the `zip` binary required by the reproducible extension archive builder.

The immutable v1.1.3 and v1.1.4 tags remain unchanged. Version 1.1.5 is the first tag that contains all release-path repairs, so it is the tag used to verify the complete GitHub Release, npm package and container publication flow.

## 1.1.4

This corrective release repairs the release destinations that could not complete in v1.1.3. The GitHub Release command now declares its repository explicitly, GitHub Packages npm receives the scoped registry configuration, and the GHCR container receives the checked-in pnpm build-allowlist required for reproducible installation.

The immutable v1.1.3 tag remains intact. Maven and NuGet were successfully published from that tag; v1.1.4 reruns the complete, corrected multi-artifact release path and will produce the GitHub Release assets, GitHub Packages npm package and GHCR image when the matching tag is pushed.

## 1.1.3

This release fixes the CodeQL incomplete-sanitization findings in the evidence-only public-research catalogue generator. Externally supplied repository metadata is now encoded before it can enter generated Markdown, and repository links accept only canonical HTTPS GitHub URLs.

It upgrades the pinned `devops-actions/actionlint` revision to the current Dependabot-reviewed 0.1.13 release and corrects the release assembly job to build the extension ZIP before collecting release artifacts. This enables the tag-triggered release workflow to publish the validated release notes, checksums and compatible package artifacts.

## 1.1.2

This release consolidates automation into four non-overlapping GitHub Actions responsibilities: verification, security, maintenance and release. The maintenance workflow now synchronizes every derived version metadata file and the isolated release notes whenever `package.json` or `CHANGELOG.md` changes on `main`.

It also adds reviewable, non-breaking dependency, runtime and action updates with an explicit manual gate for SemVer-major changes. Maven and NuGet distribution packages are validated locally and in CI before the single release workflow can publish them.

## 1.1.1

This release reorients Devthink as an original, library-first browser extension. It adds a permission-minimized Manifest V3 target, user-entered HTTPS endpoint configuration, active-tab sessions, bounded observation, typed plan proposals, explicit approval and stop gates, same-origin action execution, local audit storage, a CLI manifest gate and reproducible builds.

It also adds a documented clean-room research record covering public extension listings, manifest metadata and selected open-source architecture patterns. No third-party extension source code, visual assets, trademarks or private protocols are included.
