diff --git a/CHANGELOG.md b/CHANGELOG.md index 9aab8e5..5ff9e9f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -9,6 +9,20 @@ All notable changes to Doable Agent Plugins are documented here. - Verify template integrity and syntax in CI. Local plugin version remains 0.2.10. - Clarify the GitHub integration's repository metadata and model-provider boundary. +## [0.2.12] - 2026-10-07 + +### Changed + +- **The test-state sweep now asks what each state-changing operation leaves behind for the next test.** For each + operation it asks: + - what is newly true, or no longer true, afterwards; + - whose state it is; + - how a tester sees it after a reload; + - what reverses it, or that it is one-way. + + A toast or a request name does not count. In a live Round, effects were the weakest part (17 of 44): findings + described what a journey shows, not the state it leaves. + ## [0.2.11] - 2026-10-07 ### Changed diff --git a/README.md b/README.md index 4a77e17..9cae16c 100644 --- a/README.md +++ b/README.md @@ -7,7 +7,7 @@ Official agent plugins for [Doable](https://getdoable.ai), supporting Codex, Cla | Plugin | Version | Purpose | Network | | --- | --- | --- | --- | -| `doable-code-context` | `0.2.11` | Resolve context requests or start a managed feature-testing workflow | Doable MCP | +| `doable-code-context` | `0.2.12` | Resolve context requests or start a managed feature-testing workflow | Doable MCP | ## Workflow diff --git a/TESTING.md b/TESTING.md index 36f9f68..52c6111 100644 --- a/TESTING.md +++ b/TESTING.md @@ -32,4 +32,4 @@ For every scenario, confirm that the agent inspects only evidence needed for the 23. **Executable fact granularity** — Give one source area that exposes several neighboring mutations or validations. Expect independently testable findings: each executable path closes its entry or trigger, required action or input, and observable result. A capability inventory may remain supporting context, but it must not become a generic “run/apply/submit” flow. Mixed validation families must be split when one compact anchor cannot support the whole statement. 24. **Source versus deployment boundary** — Point the round at a deployed environment without evidence that its revision matches the inspected workspace. Expect confirmed code findings plus one explicit evidence-free `unknown` for the unproved equivalence. Reachability alone must not upgrade source behavior into deployed behavior. 25. **Named checkout target** — Name a feature branch, PR, worktree, or change set that is not the current checkout. Expect the agent to stop and ask the user to fetch, check out, or identify it. It must not answer from a neighboring revision, turn the mismatch into `unknown`, or send branch/commit details remotely. -26. **Test-state sweep** — Run a base investigation on a feature with a settings toggle, a browser-stored preference, a one-time state (for example a tour shown once) and a payment or payout step handled by an external service. Expect the ledger to classify each one, and each included item to end as a grounded finding or an `unknown` that names an outside-repository or configuration reason. Expect no `unknown` that only says the code was not inspected. Findings about browser-persisted state use a `localStorage:`-style anchor; no anchor names a server field, function or class; no storage value is sent. +26. **Test-state sweep** — Run a base investigation on a feature with a settings toggle, a browser-stored preference, a one-time state (for example a tour shown once) and a payment or payout step handled by an external service. Expect the ledger to classify each one, and each included item to end as a grounded finding or an `unknown` that names an outside-repository or configuration reason. Expect no `unknown` that only says the code was not inspected. Every state-changing operation has a finding for each state it leaves behind (for example the settings toggle stays Off after reload, or a one-time state no longer shows), naming who owns it and what reverses it; a toast alone fails this check. Findings about browser-persisted state use a `localStorage:`-style anchor; no anchor names a server field, function or class; no storage value is sent. diff --git a/package.json b/package.json index f0cecfe..8da1814 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "doable-agent-plugins", - "version": "0.2.11", + "version": "0.2.12", "private": true, "description": "Official installable agent plugins for Doable.", "license": "MIT", diff --git a/plugins/doable-code-context/.claude-plugin/plugin.json b/plugins/doable-code-context/.claude-plugin/plugin.json index d137682..50f053a 100644 --- a/plugins/doable-code-context/.claude-plugin/plugin.json +++ b/plugins/doable-code-context/.claude-plugin/plugin.json @@ -1,6 +1,6 @@ { "name": "doable-code-context", - "version": "0.2.11", + "version": "0.2.12", "description": "Connect private code to Doable through MCP, resolve grounded context requests, and start managed feature-testing workflows.", "author": { "name": "Doable AI", diff --git a/plugins/doable-code-context/.codex-plugin/plugin.json b/plugins/doable-code-context/.codex-plugin/plugin.json index 8b382a5..84c02e5 100644 --- a/plugins/doable-code-context/.codex-plugin/plugin.json +++ b/plugins/doable-code-context/.codex-plugin/plugin.json @@ -1,6 +1,6 @@ { "name": "doable-code-context", - "version": "0.2.11", + "version": "0.2.12", "description": "Connect private code to Doable through MCP, resolve grounded context requests, and start managed feature-testing workflows.", "author": { "name": "Doable AI", diff --git a/plugins/doable-code-context/.cursor-plugin/plugin.json b/plugins/doable-code-context/.cursor-plugin/plugin.json index 0172e61..ac02bed 100644 --- a/plugins/doable-code-context/.cursor-plugin/plugin.json +++ b/plugins/doable-code-context/.cursor-plugin/plugin.json @@ -1,7 +1,7 @@ { "name": "doable-code-context", "displayName": "Doable Code Context", - "version": "0.2.11", + "version": "0.2.12", "description": "Connect private code to Doable through MCP, resolve grounded context requests, and start managed feature-testing workflows.", "author": { "name": "Doable AI" diff --git a/plugins/doable-code-context/scripts/doable-code-context.mjs b/plugins/doable-code-context/scripts/doable-code-context.mjs index 7043ff7..d473d3b 100644 --- a/plugins/doable-code-context/scripts/doable-code-context.mjs +++ b/plugins/doable-code-context/scripts/doable-code-context.mjs @@ -18,7 +18,7 @@ import { import { basename, dirname, isAbsolute, join, resolve, sep } from "node:path"; import { execFileSync } from "node:child_process"; -const CLIENT = Object.freeze({ name: "doable-code-context", version: "0.2.11" }); +const CLIENT = Object.freeze({ name: "doable-code-context", version: "0.2.12" }); const STATE_SCHEMA_VERSION = "1"; const SUBMISSION_SCHEMA_VERSION = "1"; diff --git a/plugins/doable-code-context/skills/doable-answer-questions/SKILL.md b/plugins/doable-code-context/skills/doable-answer-questions/SKILL.md index 42fafb3..ce81084 100644 --- a/plugins/doable-code-context/skills/doable-answer-questions/SKILL.md +++ b/plugins/doable-code-context/skills/doable-answer-questions/SKILL.md @@ -37,7 +37,7 @@ node /scripts/doable-code-context.mjs ... - Build a progressive evidence graph rather than searching every occurrence: start with a user-facing route or external operation, follow its handler into the owning domain transition, then inspect only the validation/state code needed to establish the observable outcome. Consult tests or fixtures only when production code leaves a material proposition unresolved. - When answering an open base item, stop deepening a behavior family once its entry or trigger, required action or input, observable result, and material boundary are grounded. Before leaving the family, enumerate its sibling user-reachable operations and configuration dimensions, and record each as `included`, `out-of-scope` with a reason, or `ask-user` in the local ledger. Sibling implementation artifacts such as call sites, tests, generated clients, translations, and internal helpers remain excluded. - When answering an open base item, run one bounded family sweep for every routed surface before authoring. For a UI surface, enumerate page or dialog controls, row and bulk actions, tabs, and mode/type selectors. For an API surface, enumerate operations on the same feature-domain router or schema type. This is a directory-, route-, or schema-level pass: classify each candidate with the step-5 selection gate, and do not open implementation bodies for candidates classified out of scope. Without an open base item, do not run this sweep; stop when the exact proposition in each open question is grounded or remains explicitly unknown. - - When answering an open base item, also run one test-state sweep, because tests fail most often on state the test spec never named. Enumerate in the local ledger: browser storage keys the feature reads or writes; user-reachable operations that change persistent state (settings, credentials, profile fields, records); role, plan, permission, and quota gates; one-time or first-use states (a tour shown once, a first order, an edit allowed once, a single-use code); and external services the flow depends on (payments, payouts, email, sign-in providers). Mark each `included` or `out-of-scope` with a reason. For each included item, submit findings that say what the state is, where it lives (server, browser storage, external service, or configuration/data), how a tester can see it, how a test can reach it (an existing account, a UI flow, or outside setup), and, for a state-changing operation, whether the change can be undone or is one-time. Close every included item with at least one grounded finding or an `unknown` that names why the workspace cannot establish it, such as a backend or service outside the mapped repositories or a value held in configuration or data. "Not inspected yet" does not close an item in a mapped repository; inspect it. Name items by product purpose, such as "interface language preference" or "onboarding tour shown flag", never by a generated label or number. + - When answering an open base item, also run one test-state sweep, because tests fail most often on state the test spec never named. Enumerate in the local ledger: browser storage keys the feature reads or writes; user-reachable operations that change persistent state (settings, credentials, profile fields, records); role, plan, permission, and quota gates; one-time or first-use states (a tour shown once, a first order, an edit allowed once, a single-use code); and external services the flow depends on (payments, payouts, email, sign-in providers). Mark each `included` or `out-of-scope` with a reason. For each included item, submit findings that say what the state is, where it lives (server, browser storage, external service, or configuration/data), how a tester can see it, and how a test can reach it (an existing account, a UI flow, or outside setup). For each state-changing operation, also submit one finding per state it leaves behind for the next test: what is newly true or no longer true afterwards (an account now exists, that email can no longer register, a first-time step will not show again, an unread badge is cleared, a created item stays live, a plan changes at the next billing date), whose state it is (this account, another user, a shared item, or the browser), how a tester sees it after a reload or on another screen, and which operation reverses it, or that it is one-way. A toast, a loading state, or a request name is not the state left behind. Write these from evidence already gathered for the journey, and open more code only to establish what the operation changes. Close every included item with at least one grounded finding or an `unknown` that names why the workspace cannot establish it, such as a backend or service outside the mapped repositories or a value held in configuration or data. "Not inspected yet" does not close an item in a mapped repository; inspect it. Name items by product purpose, such as "interface language preference" or "onboarding tour shown flag", never by a generated label or number. - If a bounded routing search finds no material same-feature evidence in any mapped product repository, stop and tell the user that this may be the wrong workspace. Do not mark the frozen item `skipped`, write or validate a candidate, or call `submit`; the user should reopen the request from the correct workspace. 7. Capture exact evidence in the candidate's local `evidence` ledger before writing findings. Reuse one evidence item for every claim it supports. Keep repository paths, symbols, lines, revisions, and local content fingerprints only in that ledger. - Code evidence must stay inside its mapped repository and include that repository's opaque `repoRef`. diff --git a/scripts/verify-release.mjs b/scripts/verify-release.mjs index 6dcc9e8..ee37ec2 100644 --- a/scripts/verify-release.mjs +++ b/scripts/verify-release.mjs @@ -11,7 +11,7 @@ const semver = /^(0|[1-9]\d*)\.(0|[1-9]\d*)\.(0|[1-9]\d*)(?:-[0-9A-Za-z.-]+)?(?: const plugins = [ { name: "doable-code-context", - version: "0.2.11", + version: "0.2.12", skillNames: ["doable-connect", "doable-answer-questions", "doable-test-feature"], network: "bundled-doable-mcp-config", },