ci: promote next to main - #920
Merged
Merged
Conversation
) `opencode-plugin.js` spawned `./journal.cjs` as its own sibling. Since the build stopped materialising every hook script flat into `.opencode/plugin/` and started namespacing them under `.opencode/hooks/<plugin>/`, that path names nothing: every spawn exited MODULE_NOT_FOUND, the plugin's own try/catch swallowed it, and OpenCode recorded no session at all while still reading as covered. Measured, not inferred: a real `opencode run` in an installed project wrote zero journal lines; the same run after repointing the path wrote session_start, task_declared and turn_end, and `telemetry read` returned 2 requests, 16,303 input and 39,104 cache-read tokens. The literal now matches what the generated bridge two files away already resolves, `../hooks/<plugin>/`. Two guards, because neither alone would have caught it. build.unit.test.ts reads the JOURNAL_SCRIPT literal out of the shipped module and resolves it against the path the build contract declares — red on flipping the literal back, red on moving OPENCODE_HOOKS_DIR. opencode-plugin.test.js staged its fixture in the layout the build no longer writes, so it agreed with the bug; it now mirrors the split the loader actually sees, and goes red 2 of 3 on the old path. The plugin README drops to what a reader needs to understand the thing: what it is, why it exists, how it works, how to start, what each tool can answer. Every partly-measurable tool keeps its reason, since a limit a reader has to look up gets read as a zero. Claude-Session: https://claude.ai/code/session_01VWNxk63AGKkqE8HRqHLjGp AIDD-Session-Id: 2c21d903-3a7e-47ac-83f8-d8b7ae3aa579 Co-authored-by: Claude Opus 5 <noreply@anthropic.com>
ci: reuse validated mutation gates on promotion
…813) * fix(cli): an interactive restore that ticks nothing restores nothing `RestoreAllUseCase` forwarded an empty checkbox answer as `files: []`, which the restore reads as "no selection made", the same as a non-interactive run, and every drifted file was restored. An empty selection now ends the run with nothing restored; a run where nothing drifted, so no checkbox was shown, still restores the plugin files the picker never offers. Red first: the new test failed with `expected '{ "respectGitignore": false, …' to be 'EDITED OUTSIDE THE CLI'`. Closes #805 Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_011x4ms5qcGuZgYhCxfdHMUb AIDD-Session-Id: 4acc9a1c-19bc-4468-b8b6-e86644bcba60 * test(cli): the picker tests say what an empty selection now means Two tests from #804 pinned the behaviour #805 fixes: an empty selection forwarded as `files: []`. They now assert that the run never delegates when nothing was ticked, and that a run with no drifted entry delegates with no selection at all. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_011x4ms5qcGuZgYhCxfdHMUb AIDD-Session-Id: 4acc9a1c-19bc-4468-b8b6-e86644bcba60 --------- Co-authored-by: Claude Fable 5.1 <noreply@anthropic.com>
* test(cli): kill the surviving mutants of the telemetry context The telemetry scope held at a floor of 75 with 844 survivors and 135 uncovered mutants of 4413. Tests now name the behaviour each survivor stood for, across the domain (attribution, report, formats), the application use cases (report, diagnose, on, off, identity, local cost) and the adapters (sink, evidence, identity, backlog, run journal, the four per-tool transcript readers). Each was red against its hand-applied mutant before it went green; nothing under src/ changed. Mutation score measured on this tree: 95.1. The floor moves to 93. Refs #799 Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_011x4ms5qcGuZgYhCxfdHMUb AIDD-Session-Id: 4acc9a1c-19bc-4468-b8b6-e86644bcba60 * test(cli): keep the identity tests off the real Windows profile On Windows the identity file lives under %APPDATA%, never HOME, and these tests moved HOME alone: the runner's CI wrote and read C:\Users\runneradmin\AppData\Roaming\aidd\identity.json, so "no identity exists" found one a previous test had left there. Every sandbox now moves both together. The two tests asserting a POSIX ENOTDIR skip on Windows, which answers ENOENT for a path running through a file. The backlog "unreadable" case read through a file used as a folder, which is ENOTDIR on POSIX and ENOENT on Windows. A directory where the link file belongs is EISDIR on both; still red when ENOENT stops being told apart. Refs #799 Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_011x4ms5qcGuZgYhCxfdHMUb AIDD-Session-Id: 4acc9a1c-19bc-4468-b8b6-e86644bcba60 * test(cli): name the POSIX-errno skip once in the identity tests The same Windows explanation sat above two skips. Stacked with the runtime tests, the repetition pushed tests/ past its comment baseline (2989 against 2987); one named predicate says it once. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_011x4ms5qcGuZgYhCxfdHMUb AIDD-Session-Id: 4acc9a1c-19bc-4468-b8b6-e86644bcba60 --------- Co-authored-by: Claude Opus 5 <noreply@anthropic.com>
* refactor(cli): drop the MCP exclusion no command could reach `framework remove` was the only caller of UninstallUseCase and passed an empty mcpFilter, so UninstallMcpExclusionUseCase never removed or recorded anything, and nothing read the manifest's excludedMcp. Deleted: the use case, the mcpFilter option, McpExclusion and its equality, the manifest's exclusion methods and the excludedMcp member of a tool entry, with the tests and the round-trip fixture that exercised only that path. A manifest already carrying excludedMcp still loads: the tool-entry parser reads named fields and ignores the rest, so the field is dropped on the next write. The new test asserting the rewrite omits it failed before the deletion (the rewrite still held excludedMcp) and passes after. Measured: typecheck, lint, knip and the type-honesty check clean; test:arch 126 passed; unit and integration 4994 passed; e2e 297 passed. Refs #806 Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_011x4ms5qcGuZgYhCxfdHMUb AIDD-Session-Id: 4acc9a1c-19bc-4468-b8b6-e86644bcba60 * docs(cli): stop listing mcp-exclusions among the manifest members The framework skill's concept table named a module the previous commit deleted. Refs #806 Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_011x4ms5qcGuZgYhCxfdHMUb AIDD-Session-Id: 4acc9a1c-19bc-4468-b8b6-e86644bcba60 --------- Co-authored-by: Claude Opus 5 <noreply@anthropic.com>
…#818) Removing the commit-trailer delegate rewrote prepare-commit-msg through the atomic temp-and-rename write, which does not carry the mode over: a hook that was executable came back without its bit, and git skips such a hook silently, so the rest of the person's own hook stopped running. The bit is read before the write and restored after it, only when it was set. Two tests on a real temporary repository: the removal keeps the hook executable (red without the fix), and a hook that was not executable stays so (red with the restore made unconditional). The second is POSIX-only. Fixes #817 Claude-Session: https://claude.ai/code/session_011x4ms5qcGuZgYhCxfdHMUb AIDD-Session-Id: 4acc9a1c-19bc-4468-b8b6-e86644bcba60 Co-authored-by: Claude Opus 5 <noreply@anthropic.com>
…nal line (#820) v5.10.0 shipped an OpenCode telemetry plugin that spawned a journal.cjs the build no longer puts beside it (#812): every session journalled nothing, and smoke:real's real `opencode run` still passed, because it installs the smoke fixture, which journals nothing, and only asks whether the bridge loads. smoke:real now installs this repository's own aidd-telemetry into a throwaway project for opencode, turns measurement on, runs `opencode run` and reads the run journal. A session opens on its first call, so only a turn that completed can prove an empty journal: a completed turn with no session_start line is a failure, a model that never answered is a skip that says so. Refs #814 Claude-Session: https://claude.ai/code/session_011x4ms5qcGuZgYhCxfdHMUb AIDD-Session-Id: 4acc9a1c-19bc-4468-b8b6-e86644bcba60 Co-authored-by: Claude Opus 5 <noreply@anthropic.com>
…ode profiles (#821) * test(cli): kill the surviving mutants of the copilot profile tools-copilot under run-mutation.mjs --force, 426 mutants: - before: 82.39, 55 survived, 20 uncovered - after: 95.31, 19 survived, 1 uncovered Floor raised from 80 to 93. Refs #799 Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_011x4ms5qcGuZgYhCxfdHMUb AIDD-Session-Id: 4acc9a1c-19bc-4468-b8b6-e86644bcba60 * test(cli): kill the surviving mutants of the codex profile tools-codex under run-mutation.mjs --force, 381 mutants: - before: 89.50, 38 survived, 2 uncovered - after: 96.33, 14 survived, 0 uncovered Floor raised from 87 to 94. Refs #799 Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_011x4ms5qcGuZgYhCxfdHMUb AIDD-Session-Id: 4acc9a1c-19bc-4468-b8b6-e86644bcba60 * test(cli): kill the surviving mutants of the opencode profile tools-opencode under run-mutation.mjs --force, 283 mutants: - before: 87.63, 34 survived, 1 uncovered - after: 96.82, 8 survived, 1 uncovered Floor raised from 81 to 94. Refs #799 Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_011x4ms5qcGuZgYhCxfdHMUb AIDD-Session-Id: 4acc9a1c-19bc-4468-b8b6-e86644bcba60 --------- Co-authored-by: Claude Opus 5 <noreply@anthropic.com>
…nothing calls (#823) The copilot commands capability is built with convertCommandFrontmatter directly, so commandsHandler.convertFrontmatter was never reached: the handler serves buildFilePath alone. Copilot's commands are unchanged; the tools suite and the golden snapshots pass as they were. Fixes #822 Claude-Session: https://claude.ai/code/session_011x4ms5qcGuZgYhCxfdHMUb AIDD-Session-Id: 4acc9a1c-19bc-4468-b8b6-e86644bcba60 Co-authored-by: Claude Opus 5 <noreply@anthropic.com>
#827) fix(telemetry): a sink record's day comes from the moment it parses to, never from its text telemetrySinkRecordDayKey sliced the first ten characters of any parseable timestamp ending in Z. A moment not written in canonical ISO form got the wrong day or no day at all: "2026-09-10T24:00:00Z" read as 2026-09-10 instead of 2026-09-11, "Thu, 10 Sep 2026 23:00:00 Z" as "Thu, 10 Se", a key outside every period, so the record left a report without being counted as undated. The day is now always the parsed moment's UTC day. Two tests, both red before the change. The three comment lines that explained the shortcut go with it, and the src comment ceiling drops by the same three. Fixes #825 Claude-Session: https://claude.ai/code/session_011x4ms5qcGuZgYhCxfdHMUb AIDD-Session-Id: 4acc9a1c-19bc-4468-b8b6-e86644bcba60 Co-authored-by: Claude Opus 5 <noreply@anthropic.com>
…ed (#828) parseWorktree's comment promised that a torn or empty worktree_id reads as "not stated", on the ground that asString rejects "". It does not: a session_start carrying "worktree_id": "" was read as a worktree named nothing. An empty value is now dropped like an absent one, for the repo id too, and the comment says what the code does. Two tests, the first ones the worktree fields ever had: an empty id and repo id read as absent (red before the change), and stated ones are kept as written (red with both dropped unconditionally). Fixes #826 Claude-Session: https://claude.ai/code/session_011x4ms5qcGuZgYhCxfdHMUb AIDD-Session-Id: 4acc9a1c-19bc-4468-b8b6-e86644bcba60 Co-authored-by: Claude Opus 5 <noreply@anthropic.com>
…waway home (#832) A test that relocated only AIDD_USER_CONFIG_DIR was one mutant away from the real profile: a mutant dropping that override sent it to ~/.config/aidd of whoever ran the mutation. The mutant was killed, and the file was already written. One run left a test marketplace entry in a real registry, and another overwrote a real auth.json with a test token. A global setup, shared by the suite's and the mutation run's unit and integration projects, points HOME, USERPROFILE and APPDATA at a temp home and unsets the overrides, so every route to a profile ends there. It runs in the main process because Stryker runs vitest in worker threads: a thread's own process.env never reaches os.homedir(), so a per-file setup left that route on the real home. One test proves what a test sees, in threads and in forks. One proves all four projects declare the setup. Fixes #831 Claude-Session: https://claude.ai/code/session_011x4ms5qcGuZgYhCxfdHMUb AIDD-Session-Id: 4acc9a1c-19bc-4468-b8b6-e86644bcba60 Co-authored-by: Claude Opus 5 <noreply@anthropic.com>
#834) * fix(cli): leave what a project did not install to whoever installed it A host keys a plugin by `<plugin>@<catalog name>` (codex, copilot, claude) or by the plugin's name alone (cursor, `~/.cursor/plugins/local/<plugin>`). A project installing a plugin a person already had under that key took it over, and the project's `clean` or `plugin remove` then undid the person's own install: a codex `[plugins."…"]` section deleted with its cache, a copilot key flipped to `false`, a cursor `plugin.json` overwritten then deleted. - sync: a ref the host already reports enabled, and that this project never recorded, is neither enabled again nor recorded in `pluginRefs`. A ref this project recorded stays its own on every later sync, whatever the host reports. An unreadable host registry changes nothing: the ref is enabled as before. - plugin remove: a ref absent from this project's recorded `pluginRefs` is left enabled and named, never uninstalled. - plugin add: a user-scope plugin directory this project had no entry for is neither overwritten nor tracked, and the warning names it. A re-install of this project's own plugin still overwrites it. Fixes #829 Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_011x4ms5qcGuZgYhCxfdHMUb AIDD-Session-Id: 4acc9a1c-19bc-4468-b8b6-e86644bcba60 * fix(cli): keep a skipped cursor install's project hooks and manifest entry Skipping the whole install for a user-scope plugin directory someone else owns also skipped what the install does inside the project: the plugin's hooks merged into `.cursor/hooks.json`, its MCP entries, and the manifest entry. A second project on the same machine then journaled nothing, and `aidd plugin remove <plugin> --tool cursor` failed with "Plugin is not installed" (smoke: `plugin remove → cursor`, exit 1). The guard moves to the two user-scope translators, between writing the files and recording them: the user-scope directory is neither written nor tracked, while project hooks, MCP and the manifest entry land as before. The entry owns no files, so `plugin remove` and `clean` delete nothing of the directory. Refs #829 Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_011x4ms5qcGuZgYhCxfdHMUb AIDD-Session-Id: 4acc9a1c-19bc-4468-b8b6-e86644bcba60 --------- Co-authored-by: Claude Opus 5 <noreply@anthropic.com>
…819) * test(cli): kill the surviving mutants of the kernel Every error class now has its exact name and message pinned, and the pure kernel helpers that had no test of their own (jsonc stripping, confined file names, the JSON narrowers, describeError, isMergeContentEmpty, removeRedundantGitkeeps) get one. The frontmatter parser, semver precedence, plugin-source messages and the built-cache path parsers are asserted structure by structure, so a dropped anchor, a swapped join or a missing branch turns a test red. Kernel scope, every mutant replayed: 75.2 to 97.1 (killed 1449, timeout 32, survived 45, uncovered 0 of 1526). The 45 left are documented equivalents plus seven stryker records as survived although the hand-applied mutation turns the named test red. Floor raised from 71 to 95. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_011x4ms5qcGuZgYhCxfdHMUb AIDD-Session-Id: 4acc9a1c-19bc-4468-b8b6-e86644bcba60 * test(cli): kill the surviving mutants of the runtime GitAdapter gets its first test, against a real temporary repository: hook install and removal under this CLI and under lefthook or husky, core.hooksPath, the trailer count and every answer of readCommitTrailerSetup. The auth adapters, the self-updater, the file adapter, the prompter, the HTTP client, the update check, the release resolver, the project-root and git-environment helpers and the composition root (createDeps, wireTools, the build registry) are asserted on their exact commands, messages, headers and shapes. The removal test found a defect rather than a mutant: prepare-commit-msg lost its executable bit. The fix ships on its own in #818, which this branch sits on. Runtime scope, every mutant replayed: 69.8 to 92.2 (killed 1182, timeout 16, survived 88, uncovered 13 of 1299). Floor raised from 67 to 90. Two POSIX-only checks skip where the platform cannot show them: a mode bit on Windows, and a read-only directory on Windows or as root. Refs #799 Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_011x4ms5qcGuZgYhCxfdHMUb AIDD-Session-Id: 4acc9a1c-19bc-4468-b8b6-e86644bcba60 * test(cli): skip the trailer setup's mode-bit checks on Windows Windows CI failed two readCommitTrailerSetup tests that expect a hook or a delegate to read as not executable: there `access(X_OK)` answers like `F_OK`, so every existing file reads as executable, and git needs no mode bit to run a hook. They skip on Windows, as the removal test already does. Refs #799 Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_011x4ms5qcGuZgYhCxfdHMUb AIDD-Session-Id: 4acc9a1c-19bc-4468-b8b6-e86644bcba60 * test(cli): name the mode-bit skip once in the git adapter tests The same Windows explanation sat above three skips. Stacked with the telemetry tests, the repetition pushed tests/ past its comment baseline (2989 against 2987); one named predicate says it once. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_011x4ms5qcGuZgYhCxfdHMUb AIDD-Session-Id: 4acc9a1c-19bc-4468-b8b6-e86644bcba60 --------- Co-authored-by: Claude Fable 5.1 <noreply@anthropic.com>
…835) `clean` removes every project-scope marketplace recorded in a tool's native registrations. Sync recorded each marketplace it tried, whether or not the host accepted it: when a host refused `marketplace add` because it already held that name under another registration, or when the build failed, the entry was recorded anyway, and `clean` then ran the host's `marketplace remove <name>` against a registration this project never made. A marketplace is now recorded when this run registered it, or took it back from a dead registration, or when an earlier run of this project had already recorded it. A refused or failed one is left to whoever holds it. Plugin refs are enabled exactly as before. Fixes #833 Claude-Session: https://claude.ai/code/session_011x4ms5qcGuZgYhCxfdHMUb AIDD-Session-Id: 4acc9a1c-19bc-4468-b8b6-e86644bcba60 Co-authored-by: Claude Opus 5 <noreply@anthropic.com>
…es (#836) `tools/domain/mcp-exclusion.ts` holds only `transformFor`, the transform of an MCP server's launch command for the target platform. The exclusion it was named for was deleted with #816, so the name pointed at a feature that no longer exists. The module becomes `mcp-launch-command.ts`, with its test file, its one import and its entry in the context-boundary public-module list. No behaviour change. Fixes #824 Claude-Session: https://claude.ai/code/session_011x4ms5qcGuZgYhCxfdHMUb AIDD-Session-Id: 4acc9a1c-19bc-4468-b8b6-e86644bcba60 Co-authored-by: Claude Opus 5 <noreply@anthropic.com>
GitHub closes a pull request whose base branch is deleted, unless the merge itself deletes it. Deleting the base of #819 through the API after #818 merged closed #819 instead of retargeting it. `vcs.md` now says to retarget first, and how to replay a dependent branch after its base was squashed. Fixes #843 Claude-Session: https://claude.ai/code/session_011x4ms5qcGuZgYhCxfdHMUb AIDD-Session-Id: 4acc9a1c-19bc-4468-b8b6-e86644bcba60 Co-authored-by: Claude Opus 5 <noreply@anthropic.com>
…ng a load failure as a kill (#857) Stryker's vitest runner scores a mutant that stops a module from loading as survived, on its own and in every release up to 10.0.0 (stryker-js #6150); the reporter from #851 is what turns it into a kill. Nothing in the suite proved the last step, Stryker itself scoring that mutant Killed. tests/fixtures/stryker-canary/settings.ts holds exactly one mutant, a static StringLiteral whose replacement makes JSON.parse throw on import. The canary scope mutates it with a floor of 100. It runs whenever the harness changes, so on every Stryker or vitest upgrade, and on any change to the reporter. Evidence: - inventory: one mutant, Killed, "Unexpected end of JSON input"; - reporter neutralized: Survived with testsCompleted 0, and the gate fails (exit 1, "mutation score 0.0 is below the 100 declared in mutation-scopes.json"); - restored: score 100.0, floor 100. The architecture check that every scope matches a file now also looks under tests/fixtures, the one place a scope may mutate something that is not product. Fixes #856 Claude-Session: https://claude.ai/code/session_011x4ms5qcGuZgYhCxfdHMUb AIDD-Session-Id: 4acc9a1c-19bc-4468-b8b6-e86644bcba60 Co-authored-by: Claude Opus 5 <noreply@anthropic.com>
In a linked worktree git exports GIT_DIR into every hook. A pre-commit or pre-push job that runs pnpm inside cli/ (`cd cli && pnpm lint`, `pnpm --dir cli test`, ...) lets pnpm 12 install missing dependencies first, which ran cli's `"prepare": "lefthook install"`. With GIT_DIR set and no GIT_WORK_TREE, git took cli/ for the work tree root: lefthook found no config there, wrote its example into cli/lefthook.yml and reinstalled the hooks every worktree shares. Reproduced in throwaway repos with lefthook 2.1.12 and pnpm 12.3.4. The root package's `prepare` already installs the hooks, so cli drops its own along with its lefthook devDependency, which nothing else used (knip flagged it once the script was gone). An architecture test asserts that no script of this package calls lefthook; it failed on the old package.json. Fixes #860 Claude-Session: https://claude.ai/code/session_011x4ms5qcGuZgYhCxfdHMUb AIDD-Session-Id: 4acc9a1c-19bc-4468-b8b6-e86644bcba60 Co-authored-by: Claude Opus 5 <noreply@anthropic.com>
Analyze only relevant scopes in parallel when their context can stay isolated. Render grounded findings, categorical savings, and an editable execution prompt without inventing unavailable metrics.
Bumps the github-actions group with 3 updates: [github/codeql-action/init](https://github.com/github/codeql-action), [github/codeql-action/autobuild](https://github.com/github/codeql-action) and [github/codeql-action/analyze](https://github.com/github/codeql-action). Updates `github/codeql-action/init` from 4.37.9 to 4.38.0 - [Release notes](https://github.com/github/codeql-action/releases) - [Changelog](https://github.com/github/codeql-action/blob/main/CHANGELOG.md) - [Commits](github/codeql-action@cdf488f...b96794f) Updates `github/codeql-action/autobuild` from 4.37.9 to 4.38.0 - [Release notes](https://github.com/github/codeql-action/releases) - [Changelog](https://github.com/github/codeql-action/blob/main/CHANGELOG.md) - [Commits](github/codeql-action@cdf488f...b96794f) Updates `github/codeql-action/analyze` from 4.37.9 to 4.38.0 - [Release notes](https://github.com/github/codeql-action/releases) - [Changelog](https://github.com/github/codeql-action/blob/main/CHANGELOG.md) - [Commits](github/codeql-action@cdf488f...b96794f) --- updated-dependencies: - dependency-name: github/codeql-action/init dependency-version: 4.38.0 dependency-type: direct:production update-type: version-update:semver-minor dependency-group: github-actions - dependency-name: github/codeql-action/autobuild dependency-version: 4.38.0 dependency-type: direct:production update-type: version-update:semver-minor dependency-group: github-actions - dependency-name: github/codeql-action/analyze dependency-version: 4.38.0 dependency-type: direct:production update-type: version-update:semver-minor dependency-group: github-actions ... Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
# Conflicts: # plugins/aidd-refine/.claude-plugin/plugin.json
feat(aidd-refine): add conversation improvement workflow
…cannot (#871) Two claims in the plugin README were false, and both read as a capability. `00-init` never runs `check`: its actions are check the CLI, enable, then prove a session is journalled by reading a run file back. The table said "then check". OpenCode gives no step: its profile declares `stepStart: null`, and its plugin forwards task paths only, so no skill invocation ever reaches the journal. The coverage table gave it a step, and a limit a reader has to look up reads as a zero, so it is named with the others. Claude-Session: https://claude.ai/code/session_01VWNxk63AGKkqE8HRqHLjGp AIDD-Session-Id: 2c21d903-3a7e-47ac-83f8-d8b7ae3aa579 Co-authored-by: Claude Opus 5 <noreply@anthropic.com>
* fix(cli): preserve shared plugin state across project clean Project cleanup could delete machine-owned plugin files or native refs that another project still uses. Record canonical ownership and refuse uncertain machine cleanup. Refs #829 AIDD-Session-Id: 01a080fc-b4fe-78d3-9317-8d5ea071ca46 * test(telemetry): isolate claude session fixture from codex env Codex task environments expose CODEX_THREAD_ID ahead of the simulated Claude anchor. Clear it only in the two Claude-anchored checks so the test reads the intended session. AIDD-Session-Id: 01a080fc-b4fe-78d3-9317-8d5ea071ca46 * fix(cli): refuse unproven shared plugin mutations Project install and clean must not take over pre-existing user-scope plugins, native catalogue sources, or foreign host refs. Preserve project claims until local cleanup succeeds, and require current source/ref proof before host mutation. This is a partial draft candidate: the framework mutation floor remains pending. Refs #829 AIDD-Session-Id: 01a080fc-b4fe-78d3-9317-8d5ea071ca46 * test(cli): harden shared-scope mutation witnesses Prove ownership boundaries and refusal preservation through public behavior rather than weakening the mutation gate. Framework mutation: 93.5837% against the unchanged 93% floor. Functional suite: 6700 passing tests. Refs #829 AIDD-Session-Id: 01a080fc-b4fe-78d3-9317-8d5ea071ca46 * test(cli): align portable fixtures and native host proofs Resolve symlink and realpath fault keys consistently on Windows. Check the correct Copilot removal contract when its binary is absent and preserve native refusal witnesses when present. Reject malformed Codex source listings without inferring absence and retain actionable diagnostics. Mutation floors and production behavior remain unchanged. Refs #829 AIDD-Session-Id: 01a080fc-b4fe-78d3-9317-8d5ea071ca46 * test(cli): preserve seeded identities in realpath fixtures Resolve only symlink lookup keys, retaining virtual project and target identities. Reproduce the drive-qualified lookup and identity-preservation contracts without changing production code. Codex mutation consolidation passes at 95.4248% with zero timeouts; 274 focused tests pass. Refs #829 AIDD-Session-Id: 01a080fc-b4fe-78d3-9317-8d5ea071ca46 * test(cli): a path assertion is written the way the platform builds it The three Windows failures were in the assertions, not in the code they cover. Two cache-warning expectations spelled a path POSIX while the source builds it with `join`, so they only ever matched on a platform whose separator is a slash — one `it.each` line, played twice. The neighbour-list expectation compared `listAll()`, whose keys the in-memory adapter normalizes to a single spelling by design, against a key built with `join`. Both sides now use the same builder, so they agree on either platform by construction rather than by luck. No production behaviour changed and no refusal assertion was relaxed. Refs #829 Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01FPREgkoNtK4PYh2YyZbztq AIDD-Session-Id: 2261efcd-a873-4e60-9893-2217f702bde2 * test(cli): the in-memory key is spelled the way the source resolves it On Windows `resolve` prefixes the current drive, so the source wrote the rebuilt settings to `D:/project/.claude/settings.json` while the test seeded and read `/project/.claude/settings.json` — two different files in the in-memory double. The rebuild was happening all along; every assertion was looking somewhere else. Ten failing cases in `marketplace-sync-recovery-contract` came from that one key. Verified on the CI Windows job, the only Windows available: a throwaway branch carried a deliberately failing case that dumped the separator, the roots, the resolved path and every key the double held. Local simulation cannot reach it — aliasing `node:path` to win32 breaks the test helpers before the code under test. Refs #829 AIDD-Session-Id: 2261efcd-a873-4e60-9893-2217f702bde2 * test(cli): a registered catalogue is spelled the way a host stored it The last Windows failure was the fixture, not the code. The source compares the directory it would register — read back through `realpath`, which resolves — against the one the host reports, taken raw. The two agree everywhere the root already carries a drive, which every real Windows install does; they diverge only under a drive-less fixture root like `/user-cache`, where `resolve` adds the current drive to one side alone. So the host now reports what a host would hold: the resolved directory. The rollback refusal, the legitimate update and the pre-migration migration all keep their outcomes, because those turn on which directory is named, not on how it is spelled. Deliberately not touched: the comparison in `marketplace-sync-settings-use-case`. Canonicalizing both sides there would be defensible, but it is plugin provenance — the code #829 is about — and no evidence yet says a real install can reach the mismatch. Refs #829 AIDD-Session-Id: 2261efcd-a873-4e60-9893-2217f702bde2 * Revert "test(cli): a registered catalogue is spelled the way a host stored it" This reverts commit 6b3d45e. AIDD-Session-Id: 2261efcd-a873-4e60-9893-2217f702bde2 * fix(cli): a registered catalogue is compared by the directory, not its spelling `realpath` answers in one spelling and a host stores another. The sync write path compared the two with `===`, so on Windows a catalogue the host already follows was never recognised and got registered again — the fourth scenario of the rollback refusal, red since the suite first ran there. The CI Windows job was the only way to see it. A throwaway branch dumped all four scenarios at once: `realpath` returned `/user-cache/cache/built/1.0.0/…` where the host held `\user-cache\cache\built\1.0.0\…`. Same directory, two spellings, never equal. On posix they coincide, which is why no developer machine ever showed it. `samePath` folds what a case-insensitive filesystem folds, and only there: a backslash separates on win32 and is an ordinary character in a name everywhere else. `pathContainsOrEquals` already normalised separators for containment; this is the equality half, and the two comparison sites in the sync write path now use it. An earlier attempt fixed this in the fixture instead and broke three scenarios, because three places there carry a spelling and only two were changed. The defect is in the comparison, not in the decor. Refs #829 AIDD-Session-Id: 2261efcd-a873-4e60-9893-2217f702bde2 * test(cli): an e2e workspace hands out the path the CLI will print The CLI resolves the roots it prints and compares; `tmpdir()` does not. Windows returns the 8.3 short form (`C:\Users\RUNNER~1\…`) where the CLI prints `C:\Users\runneradmin\…`, so an assertion naming the workspace compared two spellings of one directory. These two e2e files had never run on Windows: the integration failure fixed in the previous commit stopped the job before them. macOS carries the same shape through a symlink, /var to /private/var, so the whole e2e project ran there against this change: 53 files, 302 tests, green. Refs #829 AIDD-Session-Id: 2261efcd-a873-4e60-9893-2217f702bde2 * test(cli): the manifest is searched as a tree, not as its serialization `JSON.stringify(manifest)).toContain(path)` compares an escaped rendering: Windows backslashes come back doubled and match a raw path never. The manifest held the right value all along — the assertion was reading the wrong shape of it. Two lines below, the same file already asserts structurally against the references file. This makes the manifest assertion do the same. Refs #829 AIDD-Session-Id: 2261efcd-a873-4e60-9893-2217f702bde2 --------- Co-authored-by: Claude Opus 5 <noreply@anthropic.com>
…d.cwd (#892) handleFileWritten resolved the runs directory from payload.cwd, one host's spelling read as a rule, where handleTaskFilesObserved already reads the host's own readCwd. A host naming its workspace any other way had every write it stated dropped, and the turn-end walk then recorded the same file as "observed". No declared host changes behaviour: the four naming no written path return before that line, and Claude Code declares readCwd: (payload) => payload.cwd. The regression test therefore carries a test-only host entry. Refs #859 Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com>
Co-authored-by: nightcityblade <nightcityblade@gmail.com>
The >=3.1.2 floor is open-ended, so the lockfile resolved fast-uri@4.0.0 on the production Ajv path - outside the ^3.0.1 range ajv@8 declares. Constrain it to >=3.1.6 <4: the smallest range that keeps Ajv 8 compatibility and excludes every reported vulnerable v3 release. Closes #463 Claude-Session: https://claude.ai/code/session_01BZF7CTRvfq3FWDqaCWhkCJ Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com>
* feat(aidd-vcs): recover from scoped commit hook failures * refactor(aidd-vcs): simplify scoped hook recovery
* fix(cli): check names an anchor that belongs to another project `hook fired` graded FAIL whenever the anchored session left no run file here, including for a session that never ran in this project: the anchor is inherited by any process nested inside a session, whatever directory it runs in, so a `check` run from a shell another project's session spawned was told the chain was broken when it was not. The stored records already decide it. `anchorProjectElsewhere` compares what the sink holds for the anchor against the projects this project's own run files name, and the claim reads `unknown`, naming that project, instead of `fail`. `fail` keeps its meaning: this project's own session ran and the hook wrote nothing. Two values are compared only when the same field named them — `project_id` is a directory name, `project_remote` a URL — so an anchor no stored record places, or places by a field this project never used, decides nothing and falls through to the verdict it already had. Fixes #872 Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> AIDD-Session-Id: 58b68db5-0bfc-485b-aefa-1fcb609ac8f7 * fix(cli): the foreign-anchor detail claims only what was read A run file in another project is not something this command read; the stored figures naming that project are. The wording says that, and the details suite pins it word for word like every other claim's. Refs #872 Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> AIDD-Session-Id: 58b68db5-0bfc-485b-aefa-1fcb609ac8f7 * test(telemetry): kill the mutants the foreign-anchor guard left alive `run-mutation --changed` scored the new lines 77: the sink was asked for the anchor in every case the tests could see, so the two guards that keep it from being asked — an anchor this project journalled itself, and a project no run file here names — were indistinguishable from nothing. The double now records which vendors it was asked about, and the cases assert it was asked none. The domain cases were comparing a record the field filter already dropped, never `projectOfRecord` itself; they now name a project by both fields so the record reaches it. Score 97.7, the two survivors being a type narrowing the field filter makes unobservable. Refs #872 Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> AIDD-Session-Id: 58b68db5-0bfc-485b-aefa-1fcb609ac8f7 --------- Co-authored-by: Claude Opus 5 <noreply@anthropic.com>
…ule (#885) * feat(framework): refuse an AI edit that breaks a named architecture rule docs/ARCHITECTURE.md stated cross-plugin orthogonality and nothing verified it, so a hardcoded sibling address landed and no one noticed. Two rules now decide a prospective edit: a dispatch surface never names a sibling plugin, and a skill's `## Actions` section names exactly the actions it provides. They live in a pure module, so a test hands them the same inputs the hook does, without either touching disk through them. A PreToolUse hook is the enforcement, not lefthook and not CI: the decision is to prevent the write, and PostToolUse can only report one already made. The hook fails open on every shape it does not recognise, because it gates every write in this repository. The rule's own exceptions are encoded rather than assumed. An agent's permission list, an orchestration reference and everything a plugin keeps under assets/ stay silent, so the guard reports nothing on the tree as it stands — 474 script tests, and the 374 governed files replayed through the hook as writes. Closes #250 Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01FPREgkoNtK4PYh2YyZbztq AIDD-Session-Id: 2261efcd-a873-4e60-9893-2217f702bde2 * fix(framework): the guard reads architecture, not notation An independent review broke the first cut in seven places. The worst: the address pattern required a leading slash or at-sign, so the bare form `aidd-pm:04-spec` — the one a contributor types by hand — walked straight past it. Eight such addresses were already in the tree, six of them in reference directories the classifier never looked into. The rule now matches an address by its own shape at any depth, and the router rule matches a stem as a whole token: `assert` no longer counts as named because `assert-architecture` happens to contain it. A citation is read from the column that actually carries action names, so a table with a keyword column is no longer refused. Writing an action file now re-checks its own skill's router, which is the direction a contributor creates one. The hook spliced an Edit with String.replace, which expands `$&` and `$'` as replacement patterns where the tool writes them literally. Both branches splice literally now. Two exemptions were removed and one added. Router coherence no longer skips the orchestrator — addressing and coherence are different rules. Two branches that no test could kill got the fixtures they were missing. `00-onboard` is exempt because its menus hand a person the command to type; that exemption is temporary and #883 closes it. Refs #250 Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01FPREgkoNtK4PYh2YyZbztq AIDD-Session-Id: 2261efcd-a873-4e60-9893-2217f702bde2 * fix(framework): rule two enforces the direction that can be decided A second review found the guard refused adding an action to a skill in either order. Creating the file first was refused for not being named; naming it first was refused for having no file behind it. The second order is the one `aidd-context:04-skill-generate` documents, so the framework's own generator was refused by the framework's own guard, with no way out in the refusal text. A citation with no file behind it cannot be told apart from a citation written seconds before the file it names, so that direction is gone, and with it the column heuristics and table parsing that existed only to serve it. What remains is decidable at any moment: an action file the section never cites. The section names an action by citing it — a table cell, a fenced `actions/<name>.md` path, a backticked file name — never by a word in running prose. Containment over prose let `plan` pass because the same section reads "the plan is the culmination"; measured over the tree it missed 20 of 78 row deletions. Citation matching misses none that has a row. Rule two fires on a `SKILL.md` write alone. An action file created and never cited is caught at the next write to its router, not at its own creation — recorded in the spec's non-goals rather than left to be discovered. Refs #250 Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01FPREgkoNtK4PYh2YyZbztq AIDD-Session-Id: 2261efcd-a873-4e60-9893-2217f702bde2 * fix(framework): a citation comes from the column a table calls Action A third review found the refusal told a contributor to keep the section "naming exactly the action files, no more, no fewer" — the second half of which the guard stopped enforcing a commit ago — and never said what counts as naming one. Someone who had written the file's name in prose had already done what the text asked. The refusal now names the three shapes a citation takes. Citations were collected from every cell of every table in the section, so a glossary satisfied rule two while routing nothing, and an action whose row was deleted stayed covered by its name sitting in a "next step" column. Each table now declares its own action column and only that column cites. Resolving that column once per section rather than once per table was a defect the mutation caught: a glossary standing before the router made the router's own column unreadable. A table is a table. phase-1.md still specified the direction commit 29489f7 deleted. The sweep's reason, the fixtures it names, and its acceptance criteria now say what the engine does. One non-goal blamed the deadlock on the wrong half of the mechanism, and claimed an orphan action file is caught at the next router write — there is no such guarantee, and it now says so. Refs #250 Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01FPREgkoNtK4PYh2YyZbztq AIDD-Session-Id: 2261efcd-a873-4e60-9893-2217f702bde2 * fix(framework): a table resumed after a blank line is still that table A fourth review caught a regression the third commit's own hot path introduced. A blank line inside a router table started a new block, that block had no header row, so no column declared itself and every row below the blank line cited nothing. Inserting one blank line — changing no content — refused three actions the section visibly lists. A run of rows with no `| --- |` under it is the same table resumed, and it keeps the column its header declared. Two header shapes were wrong in opposite directions. `Next action` was read as an action column, so a deleted row could hide behind a routing hint; the match is exact now. `Actions` was not read at all, so a router echoing its own section heading refused every action it provides; the match takes the plural. And a separator written `| -- |` — which `00-onboard` does, and GitHub renders — was not recognised as a separator at all. The sweep over the real tree is what caught that one, which is the whole reason it exists. plan.md still claimed both directions of rule two were measured green, and nothing recorded that one plugin source was repaired. `04-plan.md:16` addressed a sibling skill in prose; the spec's non-goal keeps existing violations out of scope, so the exception is now named where a reviewer reads the contract, not left to be found in a diff. Refs #250 Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01FPREgkoNtK4PYh2YyZbztq AIDD-Session-Id: 2261efcd-a873-4e60-9893-2217f702bde2 * fix(framework): a fence holds an example, and a shared stem cites nobody A fifth review asked for the one thing no test could supply: a recorded refusal through a real tool call. Everything until now was verified upstream of the wire — the tests spawn the script and hand it a payload, which proves the script. The matcher, the `$CLAUDE_PROJECT_DIR` expansion and `node` on `PATH` are only exercised by an actual Write, and the hook fails open at every one of those steps, so a broken wire looks exactly like a clean tree. `wiring-proof.md` records both halves: the refusal, verbatim, and the permission list carrying the same address through untouched. Two holes the review named are closed rather than disclosed. `01-plan.md` and `04-plan.md` both reduce to `plan`, so one citation covered both and deleting either row went unnoticed; a shared stem now cites nobody and the numbered name still does. And a fenced block is an example: a documented `## Actions` is no longer mistaken for the section, a `##` inside one no longer ends it early, and an example table inside one no longer cites. The exception is a fenced `actions/<name>.md` path, which `10-todo` uses for its only action — the sweep over the real tree caught that the moment fences went blank. Refs #250 Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01FPREgkoNtK4PYh2YyZbztq AIDD-Session-Id: 2261efcd-a873-4e60-9893-2217f702bde2 * fix(framework): only the path shape reads through a fence A sixth review found the raw view carried two exceptions where the contract named one. Reading a backticked `<name>.md` through a fence let an example cite, so a deleted router row hid behind a fenced table — the exact defect blanking fences was written for. `10-todo` needs the path shape and nothing needs the other, so the exception is now one shape wide. A fence nobody closed used to blank the rest of the file, so a `## Actions` that is visibly there produced "has action files but no ## Actions section". An unclosed fence is not a fence. Two shapes stay generous and now say so in the spec instead of being found: a separator-less run below the router is read as that router resumed, and rule one reads addresses through fences. Both were measured against a width check that did not discriminate them — the reviewer's own glossary has the router's column count — so the check is gone and the limit is written down. Refs #250 Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01FPREgkoNtK4PYh2YyZbztq AIDD-Session-Id: 2261efcd-a873-4e60-9893-2217f702bde2 * test(framework): rule two decided by one property over every router shape Six review rounds found the same class of defect one shape at a time: a separator written with two dashes, a plural header, a blank line splitting the table, a fenced example citing like a router, prose carrying a stem. Each got its own test after the fact, which is how the next shape gets missed rather than found. One property replaces the hunt: a section citing every action it provides is silent, and dropping any one citation yields exactly that one violation. It runs over 432 generated shapes — three headers, three separators, four citation forms, six kinds of surrounding noise, split and unsplit — and over every router in the tree, removing each of the 152 citations in turn. The shapes are enumerated, not random. A guard that fails on a seed nobody can reproduce is worse than no guard, and the repository root carries six dev dependencies, none of them a generator library — `fast-check` lives in `cli/`, which this suite does not run in. Five of the six engine mutations these rounds fixed are killed by the property alone. The sixth, a stem shared by two action files, cannot live in the matrix because a collision changes the expected verdict; it keeps the unit test written for it. Refs #250 Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01FPREgkoNtK4PYh2YyZbztq AIDD-Session-Id: 2261efcd-a873-4e60-9893-2217f702bde2 * refactor(framework): the guard reads without its commentary Six rounds of review left the rules correct and unreadable: 36% of the engine was comment, and four functions had accumulated a branch per round without anyone designing them together. Names carry what the prose used to. `exemptAgentLines` is `permissionListLines`, `findAddresses` is `addressesIn`, and the three citation shapes are three functions instead of one paragraph and three inline loops. `withoutFences` no longer repeats its fence detection twice, `classifyFile` destructures the path instead of indexing it, and the violation object is built in one place rather than three. What stays is why, never what: the exemption that expires with #883, the literal splice that `String.replace` would corrupt, the project root a readdir must resolve against. The reasoning behind each rule already lives in the plan's decisions table, and the header now points there instead of restating it. Comments fall from 36% to 9% in the engine and 30% to 11% in the hook, and one function remains above the size threshold instead of six. Behaviour is unchanged: the same 506 tests pass, and nine mutations — separator, plural header, fences, backticked file name, resumed table, shared stem, action column, and both exemptions — each still turn red. Refs #250 Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01FPREgkoNtK4PYh2YyZbztq AIDD-Session-Id: 2261efcd-a873-4e60-9893-2217f702bde2 * docs(framework): the decisions table holds what the code stopped saying The refactor cut its comments on the premise that the why lives in the plan's decisions table, then pointed there for three decisions the table never held: a table resumed after a blank line keeping its column, a separator row counting from two dashes, and an unterminated fence not being a fence. A pointer that misses is worse than the comment it replaced, and it undermines the refactor's own argument. `citationsIn` also defended a parameter its single caller always passes. The default is gone. Both found by an independent review that also ran the old engine against the new one over 4550 content cases, 60000 fuzzed paths and 26 hook payloads — zero differences. That is stronger evidence of an unchanged behaviour than the nine mutations the refactor commit cited. Refs #250 Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01FPREgkoNtK4PYh2YyZbztq AIDD-Session-Id: 2261efcd-a873-4e60-9893-2217f702bde2 * feat(framework): the same two rules refuse an edit at commit time, for every tool The write-time hook only ever sees Claude Code, so a contributor on Cursor, Codex, Copilot or opencode met no guard at all. The rules now run as a pre-commit job, which every edit reaching a commit passes through, and validate.yml replays it over the whole tree on each pull request. Nothing is duplicated to get there: architecture-scan.js holds the one filesystem layer the pure engine refuses to own, and the hook and the command are both thin callers of it. The hook stays as the fast path, refusing in the same turn rather than at commit time. --root exists so the refusal itself is testable against a tree that is not this repository. A gate whose refusal nothing exercises is a gate nobody can trust. Refs #250 Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01FPREgkoNtK4PYh2YyZbztq AIDD-Session-Id: 2261efcd-a873-4e60-9893-2217f702bde2 --------- Co-authored-by: Claude Opus 5 <noreply@anthropic.com>
…l passes (#895) * chore(framework): the architecture rules are enforced where every tool passes The write-time refusal was a Claude Code PreToolUse hook. It bought one turn of latency for a mechanism no other tool can host: across every plugin shipped here the portable hook surface is SessionStart, and a write-time refusal has no equivalent on Codex, Cursor or Copilot. A guard this repository can only enforce for one of the tools it supports contradicts the premise of the repository. The pre-commit job already covers every edit that reaches a commit, whichever tool or person made it, and validate.yml replays it over the whole tree on each pull request, so nothing that was enforced stops being enforced. The hook also failed open by design, and nothing lints scripts/ or .claude/hooks/, so it could have stopped working without anything saying so. architecture-scan.js keeps only the three functions the command uses. Refs #250 Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01FPREgkoNtK4PYh2YyZbztq AIDD-Session-Id: 2261efcd-a873-4e60-9893-2217f702bde2 * docs(framework): the enforcement gets a line, not three paragraphs 231 words to say a pre-commit job runs. The file breakdown is readable in the code, the reason the write-time hook went lives in its own commit and pull request, and "never refuses a citation with no file behind it" is a test's job to state, not a sentence's. What stays is the rule, and the one exemption a reader applying that rule would otherwise trip over. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01FPREgkoNtK4PYh2YyZbztq AIDD-Session-Id: 2261efcd-a873-4e60-9893-2217f702bde2 * docs(framework): the mechanism moves to where mechanisms are read ARCHITECTURE.md states the rule and the one exception to it. What runs the rule belongs in the pre-commit gates table, which is where someone asks what a commit checks. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01FPREgkoNtK4PYh2YyZbztq AIDD-Session-Id: 2261efcd-a873-4e60-9893-2217f702bde2 * fix(framework): three reviewers found what the author did not A critical pass over the two documents, one reader at a time, found five defects in this branch's own edits. All five are corrected here. - The `--no-verify` sentence was replaced by a second falsehood. Checked against all nine workflows this time: no workflow fires on a push to a feature branch, `ci.yml` and `cli-ci.yml` fire on any pull request whatever its base, and only `validate.yml` filters `main` and `next`, minus three `cli` jobs it excludes. - Reading "Claude Code" as "an AI coding tool" made line 9 false. The manifest it points at is `.claude-plugin/marketplace.json`; codex emits `.agents/plugins/`, cursor `.cursor-plugin/`, copilot `.plugin/`. All three substitutions are reverted. That framing needs a rewrite, not a word swap. - The exemption bullet named one of the two holes in rule one. `isExemptFromOrthogonality` also exempts every path under `plugins/aidd-orchestrator/`. - The doc test read tables by position, so a `Runs` cell could name a deleted script and stay green. Tables are now found by their header cells and read by column name. A fifth test opens the script the table names. - Its failure message named one exemption bullet after this branch split it into two. Nine attacks replayed against the rewritten parser: a missing script, an un-backticked name and a wrong event go red; a blank line inside a table, an escaped pipe and an inserted column stay green. Four semantic mutations each redden exactly the test that names them. 503 tests pass. Referenced paths 0 dead, doc duplication 0, architecture rules 350 governed files clean. Refs #250 Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01FPREgkoNtK4PYh2YyZbztq AIDD-Session-Id: 2261efcd-a873-4e60-9893-2217f702bde2 --------- Co-authored-by: Claude Opus 5 <noreply@anthropic.com>
…898) Bumps the npm-dev-dependencies group with 2 updates: [js-yaml](https://github.com/nodeca/js-yaml) and [lefthook](https://github.com/evilmartians/lefthook). Updates `js-yaml` from 5.4.1 to 5.4.2 - [Changelog](https://github.com/nodeca/js-yaml/blob/master/CHANGELOG.md) - [Commits](nodeca/js-yaml@5.4.1...5.4.2) Updates `lefthook` from 2.1.12 to 2.1.14 - [Release notes](https://github.com/evilmartians/lefthook/releases) - [Changelog](https://github.com/evilmartians/lefthook/blob/master/CHANGELOG.md) - [Commits](evilmartians/lefthook@v2.1.12...v2.1.14) --- updated-dependencies: - dependency-name: js-yaml dependency-version: 5.4.2 dependency-type: direct:development update-type: version-update:semver-patch dependency-group: npm-dev-dependencies - dependency-name: lefthook dependency-version: 2.1.14 dependency-type: direct:development update-type: version-update:semver-patch dependency-group: npm-dev-dependencies ... Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Bumps the github-actions group with 3 updates: [github/codeql-action/init](https://github.com/github/codeql-action), [github/codeql-action/autobuild](https://github.com/github/codeql-action) and [github/codeql-action/analyze](https://github.com/github/codeql-action). Updates `github/codeql-action/init` from 4.38.0 to 4.38.1 - [Release notes](https://github.com/github/codeql-action/releases) - [Changelog](https://github.com/github/codeql-action/blob/main/CHANGELOG.md) - [Commits](github/codeql-action@b96794f...1c5b675) Updates `github/codeql-action/autobuild` from 4.38.0 to 4.38.1 - [Release notes](https://github.com/github/codeql-action/releases) - [Changelog](https://github.com/github/codeql-action/blob/main/CHANGELOG.md) - [Commits](github/codeql-action@b96794f...1c5b675) Updates `github/codeql-action/analyze` from 4.38.0 to 4.38.1 - [Release notes](https://github.com/github/codeql-action/releases) - [Changelog](https://github.com/github/codeql-action/blob/main/CHANGELOG.md) - [Commits](github/codeql-action@b96794f...1c5b675) --- updated-dependencies: - dependency-name: github/codeql-action/init dependency-version: 4.38.1 dependency-type: direct:production update-type: version-update:semver-patch dependency-group: github-actions - dependency-name: github/codeql-action/autobuild dependency-version: 4.38.1 dependency-type: direct:production update-type: version-update:semver-patch dependency-group: github-actions - dependency-name: github/codeql-action/analyze dependency-version: 4.38.1 dependency-type: direct:production update-type: version-update:semver-patch dependency-group: github-actions ... Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Bumps [react](https://github.com/react/react/tree/HEAD/packages/react) and [@types/react](https://github.com/DefinitelyTyped/DefinitelyTyped/tree/HEAD/types/react). These dependencies needed to be updated together. Updates `react` from 19.2.7 to 19.3.0 - [Release notes](https://github.com/react/react/releases) - [Changelog](https://github.com/react/react/blob/main/CHANGELOG.md) - [Commits](https://github.com/react/react/commits/v19.3.0/packages/react) Updates `@types/react` from 19.2.17 to 19.3.0 - [Release notes](https://github.com/DefinitelyTyped/DefinitelyTyped/releases) - [Commits](https://github.com/DefinitelyTyped/DefinitelyTyped/commits/HEAD/types/react) --- updated-dependencies: - dependency-name: react dependency-version: 19.3.0 dependency-type: direct:production update-type: version-update:semver-minor - dependency-name: "@types/react" dependency-version: 19.3.0 dependency-type: direct:development update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Bumps [@inquirer/prompts](https://github.com/SBoudrias/Inquirer.js) from 8.7.0 to 8.7.2. - [Release notes](https://github.com/SBoudrias/Inquirer.js/releases) - [Commits](https://github.com/SBoudrias/Inquirer.js/compare/@inquirer/prompts@8.7.0...@inquirer/prompts@8.7.2) --- updated-dependencies: - dependency-name: "@inquirer/prompts" dependency-version: 8.7.2 dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
AIDD-Session-Id: 01a0c87c-6995-74d2-9e11-dd8597116055
Fixes #618 AIDD-Session-Id: 01a0ca9a-53ab-7ec2-bdc8-d6a3b3ae164c
* feat(cli): add Kilo Code support AIDD-Session-Id: 01a0c897-e6c0-78d0-8f7c-3e908106d4a9 * test(cli): make Kilo runtime smoke portable AIDD-Session-Id: 01a0c897-e6c0-78d0-8f7c-3e908106d4a9 --------- Co-authored-by: Frantz Priou <waewoo@gmail.com> Co-authored-by: Baptiste LAFOURCADE <baptiste.lafourcade@gmail.com>
* ci(release): accept only merge commits on main A squashed promote collapses the week's commits into one hidden `ci:` subject, so release-please reports no user-facing commits and the entries vanish from the notes; it also collapses authorship onto whoever merged. A rebase breaks the merge base the back-merge relies on. The ruleset file now allows only merge commits on main. A bypass in pull_request mode does not lift that restriction (proven in a sandbox), so the Release PR moves from --squash --admin to --merge --admin, which this repository already released from once (#135). The live ruleset is left unchanged: it must be applied only after one release has merged with --merge. Refs #911 Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> AIDD-Session-Id: 3adb1fb2-3894-4e52-afab-424803c7fcad * feat(release): credit each release line's commit author Generated GitHub releases never named the people behind a change. release-please's own include-commit-authors option is a no-op in every 17.x release so far: parseConventionalCommits drops the author before the changelog notes see it (googleapis/release-please#2761, fix pending in #2892). After release-please creates the cycle's releases, a CI step appends each line's commit author as (@login), or the name when no account resolves, resolved from the line's commit SHA. Lines already credited are left alone, so a re-run changes nothing, and a crediting failure never blocks the build and publish jobs. Delete the step once a fixed release-please is pinned. Refs #911 Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> AIDD-Session-Id: 3adb1fb2-3894-4e52-afab-424803c7fcad * docs(release): state the merge-only rule as declared, not live The live main ruleset still allows squash and rebase until a maintainer applies .github/rulesets/main.json, which must wait for one release to merge with --merge. The docs now describe the rule the file declares instead of claiming it is enforced today. Refs #911 Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> AIDD-Session-Id: 3adb1fb2-3894-4e52-afab-424803c7fcad * fix(release): make release crediting fail loudly and never block publishing A missing RELEASE_OUTPUTS made the script credit nothing and exit 0, and a failing checkout before the credit step would fail the release-please job and skip every build and publish job. The script now exits non-zero on missing outputs, both crediting steps carry continue-on-error, and tests pin the wiring. A second pass no longer re-appends an author name containing parentheses, and a release is written back only when its body changed. Refs #911 Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> AIDD-Session-Id: 3adb1fb2-3894-4e52-afab-424803c7fcad * fix(release): merge into main with an empty commit body The repository fills a merge commit's body with the PR title, and release-please splits a message on each conventional line, so a PR merged into main as a merge commit is parsed twice: the change appears twice in the notes, the copy credited to whoever merged. No repository setting yields an empty body with the "Merge pull request" subject. The Release PR and promote merges now pass --body "", and hotfixes are documented to merge with an empty description. Proven in a sandbox: a default-body merge duplicated the line, an empty-body merge did not. Refs #911 Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> AIDD-Session-Id: 3adb1fb2-3894-4e52-afab-424803c7fcad * fix(release): drop merge-commit duplicates when crediting releases A hotfix merged with the default body still reaches release-please twice. When crediting, a line whose commit is a merge commit is removed if a non-merge line in the same release carries the same text; a lone merge-commit line is credited to its pull request's author instead of whoever merged it. CHANGELOG.md keeps the duplicate. Refs #911 Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> AIDD-Session-Id: 3adb1fb2-3894-4e52-afab-424803c7fcad * refactor(release): shorten the release crediting comments Refs #911 Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> AIDD-Session-Id: 3adb1fb2-3894-4e52-afab-424803c7fcad --------- Co-authored-by: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
* feat(aidd-qa): scaffold acceptance QA plugin from browser QA Moves plugins/aidd-dev/skills/11-browser-qa to plugins/aidd-qa/skills/01-acceptance-qa (git history preserved) and rewrites it to derive scenarios only from acceptance criteria, never the diff or the source code. Renames its Playwright reference to interface-browser-playwright-cli.md, adds Criterion/Expected/Actual columns to the QA report template, and pins the architecture-rules sweep count to 49 skills-with-actions. Refs #908 Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> AIDD-Session-Id: 6d6ccc35-f6c1-417d-84a6-9a0b70474e6b * feat(aidd-dev): retire browser-qa to a redirect plugins/aidd-dev/skills/11-browser-qa now holds a single redirect action that names the aidd-qa plugin and its install command, then stops without loading a scope or recording evidence. Drops Browser QA from the plugin description and README now that it moved. Refs #908 Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> AIDD-Session-Id: 6d6ccc35-f6c1-417d-84a6-9a0b70474e6b * chore(marketplace): register aidd-qa plugin Adds the aidd-qa entry to marketplace.json (recommended: false, off the curated install path like aidd-ui and aidd-telemetry), versions it in release-please-config.json and the manifest, adds it to the build-plugin CI matrix, and adds aidd-qa/qa as commitlint scopes. Updates docs/ARCHITECTURE.md, docs/CATALOG.md, docs/MAINTAINERS.md, README.md and the project memory bank (architecture, deployment, project-brief, testing) to name the 9th plugin and its new owner of browser acceptance QA. Refs #908 Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> AIDD-Session-Id: 6d6ccc35-f6c1-417d-84a6-9a0b70474e6b * docs(aidd-qa): add the plan and its validation record Adds the phased plan behind the aidd-qa plugin (issue #908) and the gate, host-proof, and architecture-conformance evidence collected while implementing it. Refs #908 Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> AIDD-Session-Id: 6d6ccc35-f6c1-417d-84a6-9a0b70474e6b * docs(aidd-qa): correct the validation record The previous version overstated what was observed: it claimed each commit's hook run was gate evidence for that commit's own tree, when every gate actually ran once against the final working tree. Records the two intermediate trees are not independently clean, the blocked push (pre-existing, machine-specific cli-test failure, isolated and unrelated to this branch's changes), and deviations not yet noted. Refs #908 Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> AIDD-Session-Id: 6d6ccc35-f6c1-417d-84a6-9a0b70474e6b * fix(aidd-dev): scope 06-test to developer-side validation The skills description did not exclude acceptance QA, so it could be picked for reviewer evidence instead of the dedicated aidd-qa plugin. Frame it as developer-side test validation during implementation and add that exclusion; CATALOG.md is regenerated from the new description. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> AIDD-Session-Id: 6d6ccc35-f6c1-417d-84a6-9a0b70474e6b * fix(aidd-qa): restrict criteria sourcing and complete the report contract 01-load-scope admitted a plan as a criteria source outright; criteria now come only from the issue, spec, or user story (or ones the user gives), and a plans browser Test Scope edge case is admitted only when it maps to one of those. The stale fewer-than-3 edge-case count check is dropped, and the first process step now opens with a verb. qa-report-template gains an Out of interface section so a criterion with no browser-observable outcome is listed, never silently dropped, and the header verdict cannot read pass without stating that list. Verdict values are now explicit (pass | fail | blocked per scenario, plus skipped at the header when nothing is browser-observable), and the Duration column is restored. 03-run-scenarios is wired to fill both. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> AIDD-Session-Id: 6d6ccc35-f6c1-417d-84a6-9a0b70474e6b * docs: correct plugin count and the pushed validation record architecture.mds fits-together diagram still read plugins/ dot 8 after the aidd-qa plugin landed; the stack table already said 9. Align the diagram with it. The aidd-qa plugin tasks validation.md described the push as blocked on a local node/codex PATH collision. It has since been resolved (node binary copied into an isolated directory, prepended to PATH; a symlink does not work because process.execPath resolves it) and cd048e6 was pushed with the full pre-push gate passing, no --no-verify. Replace the stale blocked account with what actually happened. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> AIDD-Session-Id: 6d6ccc35-f6c1-417d-84a6-9a0b70474e6b * fix(aidd-qa): add run-verdict rule and stop load-scope early Give run-scenarios an ordered rule for the header verdict (any fail beats any blocked, beats no scenario ran producing skipped, else pass), restoring the "mark the run failed" behavior review #908 found missing after e8d3538. Move the zero-browser-observable-criteria short circuit into load-scope itself: it now stops right after its Filter step and reports skipped, so prerequisites and prepare-run never run for a scope with no browser-observable criterion. Document the exception in SKILL.md's transversal rules, since the router's linear flow otherwise implies prerequisites always runs first. Also merges a duplicate load-scope Test bullet review #908 flagged. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> AIDD-Session-Id: 6d6ccc35-f6c1-417d-84a6-9a0b70474e6b * fix(aidd-dev): describe 06-test as developer-side in its README The 06-test SKILL.md description was narrowed to developer-side validation with no acceptance evidence and no sibling-plugin address in ba2a59a, but this hand-written README row still read like generic "write and iterate on tests" coverage. Review #908 flagged the drift. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> AIDD-Session-Id: 6d6ccc35-f6c1-417d-84a6-9a0b70474e6b * docs: correct 06-test's catalog description and the validation record docs/CATALOG.md still described 06-test as generic test coverage after ba2a59a narrowed its scope; align it with the SKILL.md description and the now-fixed aidd-dev README row. The aidd-qa plugin's validation record had gone stale across three commits landed after it was last corrected (ba2a59a, e8d3538, cff70e6): its commit table stopped five commits short of HEAD and its push section named only the first push's SHA. Rewrite both against the current branch history, re-run the scripts suite and architecture check on the final tree with one consistent number instead of the earlier 503-pass/501-pass-plus-2-skip split, and describe the push mechanism (an isolated copied-node PATH, never --no-verify) without freezing it to a SHA the next push would make stale again. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> AIDD-Session-Id: 6d6ccc35-f6c1-417d-84a6-9a0b70474e6b * fix(aidd-qa): route the zero-criterion skip before prerequisites The prior transversal rule said prerequisites never runs when load-scope finds no browser-observable criterion, but the router still lists 00-prerequisites ahead of 01-load-scope, so an executor following "read only the next action's file" would check and possibly install ffmpeg/Playwright before load-scope ever got to decide. Move the check itself ahead of 00: the router now says to test the criteria before invoking prerequisites at all, and to run load-scope alone (reporting skipped) when none is browser-observable. Also corrects 8924333's commit body, which said this short circuit happens "after its Filter step" -- load-scope actually stops one step later, after Locate resolves the evidence folder the skip report needs. That commit is already pushed and is not being amended; recorded here instead. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> AIDD-Session-Id: 6d6ccc35-f6c1-417d-84a6-9a0b70474e6b * fix(aidd-dev): drop the addressing note from the 06-test README row db49dea's fix copied the dispatch's own writing constraint ("no sibling-plugin address") into the README row as if it described what 06-test does. Replace it with what a reader actually needs: 06-test is not independent acceptance QA or reviewer evidence, mirroring the SKILL.md description's own "Do NOT use for" clause. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> AIDD-Session-Id: 6d6ccc35-f6c1-417d-84a6-9a0b70474e6b * docs: correct 06-test's catalog description and the validation record docs/CATALOG.md's 06-test row still ended with the addressing note "no sibling-plugin address" that a6e0cda already dropped from the README row for the same reason: it is this task's own writing constraint, not a description of what the skill does. Replace it with the same "not independent acceptance QA or reviewer evidence" wording. Rewrite the validation record's "Commits" and "Push" sections, which had gone stale across three commits (ba2a59a, e8d3538, cff70e6) and now this repair's own nine, and describe the repair itself honestly: what review #908 found, the routing-rule and docs-wording bugs the first pass at fixing it introduced and a second pass corrected, and the final gate re-run's numbers with exit codes captured directly rather than through a wrapper that can mask them. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> AIDD-Session-Id: 6d6ccc35-f6c1-417d-84a6-9a0b70474e6b * fix(aidd-qa): report a fully rejected scenario set as blocked, not skipped A run with browser-observable criteria whose every scenario got rejected (no executable teardown, etc.) fell through to header verdict skipped, which the template and load-scope reserve for zero browser-observable criteria. A rejected criterion then appeared in neither Scenarios nor Out of interface, so a candidate that was never validated read as nothing to validate. Rejections are now carried forward with their reason from load-scope's Validate and prepare-run's Reset into run-scenarios' report, which adds a Rejected section and blocks the run whenever any exists. load-scope's own Skip step (zero criteria survive the Filter) now writes and returns <evidence-folder>/qa.md instead of leaving the destination to the agent. SKILL.md's router row and mermaid are corrected to say "at most one" happy path and to show the skip exit from load-scope to the report. Review #908. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> AIDD-Session-Id: 6d6ccc35-f6c1-417d-84a6-9a0b70474e6b * docs: correct the validation record's defect count and commit table, add install proof Review #908's second follow-up pass on this record found "fourth defect" where the load-scope-skips-prerequisites fix is really the second in its own list, row 14's subject carrying a spurious "(final)" that never appeared in 3c81dfb's real message, and "this repair's own three commits (9-11, then 12-14)" undercounting a six-commit repair. All three are fixed here; "defect four" describing the 06-test docs fix is left alone, since that one really is the fourth defect in the list. Also adds rows 15-16 for this round's own commits (row 16, this commit, referred to generically since it cannot state its own SHA), a new "Second repair re-run" gate table, and a Host proof entry for criterion 10: an isolated-HOME sandbox install of aidd-qa for both --tool claude and --tool codex, run to close the gap the review found between the criterion and its recorded proof. Review #908. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> AIDD-Session-Id: 6d6ccc35-f6c1-417d-84a6-9a0b70474e6b * fix(aidd-qa): guard resets and tighten scope order after a real run A first real run on a PWA wiped the developer's own database through the documented test reset. Resets now require proof of test-only storage, or one question. - run load-scope before prerequisites; drop the special skip rule - split partly observable criteria, quote the rest out of interface - run-code returns per-step expected, actual, ok; a throw is tooling only - run browser commands from a temp dir outside the application repository Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> AIDD-Session-Id: 6d6ccc35-f6c1-417d-84a6-9a0b70474e6b * fix(aidd-qa): condense load-scope and align teardown with session close - load-scope: 7 steps, 4 tests; edges only when a criterion names them, an unmapped plan edge is never a candidate nor a rejection - prepare-run: prefer a test-only entry over the development one - reference: tear down and verify baseline before closing the session; the no-substitution rule scopes to runner commands Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> AIDD-Session-Id: 6d6ccc35-f6c1-417d-84a6-9a0b70474e6b * fix(aidd-qa): let project memory decide the entry, locate the reset guard - prepare-run: Reuse before Preflight; drop the generic test-only preference, project memory decides and the reset guard asks - load-scope: teardown is checked in prepare-run only; Show names the evidence folder Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> AIDD-Session-Id: 6d6ccc35-f6c1-417d-84a6-9a0b70474e6b * fix(aidd-qa): check storage before starting the entry The reset guard ran only at teardown, after the entry had already started on possibly shared storage (and run its migrations). It now runs in Reuse, before anything starts. The router row matches load-scope's edge rule. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> AIDD-Session-Id: 6d6ccc35-f6c1-417d-84a6-9a0b70474e6b * refactor(aidd-qa): condense prepare-run and run-scenarios Same behavior in fewer words: the verdict order is stated once, the prepare-run return step folds into its output, and run-scenarios' input names everything load-scope hands over. A blocked row reports evidence `none`; only a failed take is kept. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> AIDD-Session-Id: 6d6ccc35-f6c1-417d-84a6-9a0b70474e6b * feat(aidd-dev): remove the retired browser-qa redirect Browser QA now lives in the aidd-qa plugin, so aidd-dev owns no QA surface. The catalog lists aidd-qa's renumbered actions, and the plan records the removal. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> AIDD-Session-Id: 6d6ccc35-f6c1-417d-84a6-9a0b70474e6b * chore(aidd-qa): start the plugin at 1.0.0 Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> AIDD-Session-Id: 6d6ccc35-f6c1-417d-84a6-9a0b70474e6b * chore(aidd-qa): release the plugin as 1.0.0 Pin the first release with the package's `release-as`; the manifest stays at 0.1.0 until release-please writes 1.0.0. A `Release-As` footer would re-version every other path the squash commit touches. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01WuxKN5bm96LFhU97rsgBUW AIDD-Session-Id: 6d6ccc35-f6c1-417d-84a6-9a0b70474e6b --------- Co-authored-by: Claude Sonnet 5 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Automated promotion of
nexttomain, from a snapshot of next taken at run 35987816792. Merged as a merge commit somainkeeps every conventional commit for release-please, and so both branches keep a shared merge base for the back-merge. Do not squash, do not rebase.