Repository navigation
chore: rolling promotion dev -> main - #2880
Conversation
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_013gGxGgKskzyzr1HRUB6cV3
…ndoff docs(wish): handoff for executing skills-everywhere b and c
wishes-lint imported the validator from plugins/genie/scripts/src, which wish skills-everywhere-b Group 4 deletes. Create scripts/validate-wish.ts and scripts/wish-template-text.d.ts as a maintained verbatim mirror -- the two files differ from the plugin originals only in the two relative import specifiers the depth change forces -- and re-point scripts/wishes-lint.ts at the local copy. The mirror is biome-ignored exactly as plugins/genie/scripts already is, so the byte parity between the two copies stays a fact rather than a formatting negotiation.
…omic-fs Wish skills-everywhere-b deletes agent-sync.ts (Group 5) and codex-activation-persistence.ts (Group 3). Both lend primitives to modules that survive the wish, so the primitives move first, verbatim, into the leaf module that already owns the crash-safety contract. From agent-sync.ts: the whole physical-tree digest cluster -- computeDirDigest/computeFileDigest plus the private traversal helpers, and the MANIFEST_NAME / PHYSICAL_TREE_IDENTITY_VERSION constants the digest grammar is defined in terms of. agent-sync.ts imports the four it still uses internally (computeExactDirDigest, computeLegacyRegularTreeDigest, physicalEntryKind, PhysicalTreeEntry) and re-exports the four public ones, so doctor, uninstall, runtime-integrations and the retirement module keep their current imports. Its two remaining private hashFile calls now say computeFileDigest. From codex-activation-persistence.ts: readBoundedRegularFile, fsyncParentDir, atomicWriteFileSync and unlinkWithParentFsync with their private helpers. The old module keeps renameNonOverwriting (Codex-only) and re-exports the four, so install-version-marker.ts and update-capabilities.ts -- both survivors -- need no change this wave. The BoundedFileRead / AtomicWriteOptions types are not re-exported: no module outside that file ever imported them, and a re-export with no importer is a knip failure. Both stay exported from atomic-fs. Tests: the computeDirDigest describe block moves to atomic-fs.test.ts and the four durable-write primitives gain coverage there (they had none). The GENIE_HOME permission scan's exemption is re-keyed from a drifting <path>:<line> to a content anchor, with a new test asserting every exemption still matches exactly one real call site -- a stale line key failed OPEN, this one fails closed; and its atomicWriteFileSync pin follows the call to atomic-fs.ts.
…every home skills@1.5.23 ignores the `@<ref>` suffix and always serves the repository default branch, so `add <repo>@v<version>` was never a pin. The channel now points the CLI at $GENIE_HOME/skills — the signed tarball's own bytes — and records `source: 'local:<abs root>'` beside the release tag. The same install now records what the CLI ACTUALLY wrote: a bounded $HOME discovery scan (depth/entry/wall-clock caps, symlinks never followed) unioned with the known-home floor replaces the four-row table that reported 4 where the CLI had written 57, and the operator line prints that real N. A pre-install collision snapshot backs up every foreign same-named skill directory --copy is about to overwrite, records it in an optional `collisions[]`, and reports it. `source` and `collisions` are optional so every 5.260830.x record on disk still parses and still drives `genie uninstall`.
…private legacy-integration-retirement.ts was agent-sync.ts's only surviving non-test importer, pulling nine symbols. computeFileDigest went to atomic-fs.ts with the digest cluster; the other eight -- MANIFEST_NAME excepted -- are now copied verbatim into the retirement module as module-private, with their transitive leaf helpers (the manifest parsers, the physical-identity reader, the workflow ownership read, the Hermes profile resolver). Decision 6: this module is deleted two stable releases after the wish ships, so a new shared home would outlive its only user. MANIFEST_NAME and PHYSICAL_TREE_IDENTITY_VERSION are imported from atomic-fs rather than copied: they travelled there with computeDirDigest, which outlives this module, and a second definition of the manifest name would silently diverge on what counts as a managed directory. The Hermes managed-skills marker becomes this module's own constant. Its drift guard pinned the literal inside hermes-skills-config.ts, which Group 5 deletes; a guard that fails on the deletion rather than on drift is not a contract. The mcp half of that test stays -- hermes-mcp-config.ts survives. No cycle: atomic-fs <- lifecycle-lease <- agent-sync, and retirement imports neither upward.
…ne safety
Five hardening items the Wish A G2/G3 reviews carried into this wish:
writeJsonDocument now stages, fsyncs, renames and fsyncs the directory. It
rewrites the user's known_marketplaces.json and settings.json in place, so a
truncating writeFileSync that died mid-flight destroyed exactly what this
module's backup-first story promises never to lose. Every failure path unlinks
the staging file; the target's mode survives the republish. The cost is that an
unwritable parent directory now fails the write instead of truncating in place,
and that failure is reported per-surface with the original bytes intact.
Two surfaces join the roster, taking LEGACY_INTEGRATION_SURFACES to seventeen:
codex-role-agent-inventory (the .genie-role-agents.json sidecar plus every
.genie-role-agents.{txn,conflict,prepare,committed-cleanup}-* directory a
crashed transaction left, none of which the genie-*.toml classifier ever saw)
and claude-marketplace-cache (~/.claude/plugins/marketplaces/automagik, which
inspectRuntimeIntegrationEvidence kept reading as installed evidence long after
retirement). Each has managed-clean / managed-modified / unmanaged / absent
coverage, and a new end-to-end test proves one run flips the evidence probe to
{codex:false, claude:false} while a second prints nothing to retire and
allocates no backup root.
planCodexPluginRegistrationRemoval now tracks TOML multi-line strings. A
"""...""" or '''...''' body containing a line that reads like a table header
used to either start a drop inside an unrelated operator's value or end the
genie table's drop early; three of the four new tests fail on the prior code.
A sidecar-less directory in the hidden .curated lane is now reported by path as
kept with a reason instead of being skipped silently. The same rule is
deliberately NOT applied under ~/.claude/skills, where the skills.sh channel's
own plain copies live and an advisory per skill would bury the report.
The scan's cap counted every directory entry, so on an ordinary developer $HOME it exhausted 50,000 long before the walk finished: a real host measures 112,885 entries under the same depth and prune rules. The scan reported `capped`, `agentDirs` fell back to the four-row known-home table, and the honest-N defect this group exists to fix survived in production. The cap now counts only the directories the walk considers (files, symlinks and pruned trees are free) and the ceiling is a runaway-walk backstop at 200,000 with the 10 s wall clock as the binding bound. Measured on this host after the change: status ok, 221 homes, 353 ms. A delivered $GENIE_HOME also holds a second, byte-identical skills tree at plugins/genie/skills, freshly stamped by tarball extraction — exactly what the selection rule keeps — so it could be recorded as an agent home and land in the uninstall manifest. The scan now prunes $GENIE_HOME whole, which on this host also removes plugins/hermes-genie/skills and an update staging payload a mirror-only prune would have missed. Collision backups taken before a FAILED install were also unreported: the snapshot runs pre-spawn, but the ok:false outcome carried no warnings, so an operator whose install then failed had no path to the bytes in state-backups. Warnings now ride both outcome variants and the convergence helper prints them after the failure line. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01GKqeXSyZMD8YmQtk4vtXFZ
…nvergence The update-convergence retirement test pins the exact sorted surface list one pass retires. Its fixture's `~/.codex/agents` carries the `.genie-role-agents.json` sidecar, which the new surface now classifies and removes, so the list grows by one entry. CI caught it: this file is not in the group's local validation set, and the full suite OOMs the dev host.
Wish skills-everywhere-b, Group 3. Removes authenticated Codex delivery, activation, generations, fallback lanes, repair/rollback and role profiles; leaves `doctor` with only the checks whose dependencies survive; decouples `genie uninstall` from the Codex lifecycle lease and runs plugin-era retirement before the home is removed. Rehomed first, so no surviving consumer loses a primitive: - src/lib/release-payload-proof.ts parseReleaseVersion + scanPhysicalTree - src/lib/delivery-evidence-verify.ts the offline evidence verifier - src/lib/delivery-evidence-verify.test-support.ts its deterministic pack - route-layer classifier -> src/lib/codex-project-mcp.ts (MCP surface) `genie update --publish-local-delivery` survives with its production verification reassigned: it materializes the request, extracts and proves the candidate, and runs the real embedded-trust-root verifier, then reports `delivery-verified` (exit 0). The release-update-path-smoke assertion moves with it. Manifests are delisted from the five toolchain lists in this same commit, and the codex-smoke CI job leaves with the scripts it invoked.
Deliverable 8 stopped staging `.agents/plugins/marketplace.json` in build-binary.sh but left two consumers declaring it, one of them release-breaking. `INSTALL_PAYLOAD_MEMBERS` is an exact allowlist: verifyPayloadLayout compares the staged member count AND every sorted name, so a seven-member tarball against the eight-member list aborted install.sh's promoter with "staged install does not match the exact installer member allowlist". `bun test scripts/install-swap.test.ts` reproduced it (3 fail; 12 pass on the base commit). Drop the entry and re-point the payload fixtures, including install-promotion.test.ts's per-member interruption scenarios, which used `.agents` as the first member. update.ts's AUXILIARY_DELIVERY_TREE_NAMES and syncAuxiliaryContent mirrored a tree that is no longer delivered, and the docblock still claimed parity with install.ts's AUX_LAYOUT_DIRS, which lost `.agents` in the same group. Proof: the freshly built linux-x64-glibc tarball's top-level set is exactly `.claude-plugin LICENSE VERSION genie plugins skills templates`. install.test.ts's negative assertion that an extracted `.agents/` is not a managed layout dir is deliberately left as-is.
…minal The job comment still described `codex-native-dogfood` as the other runner of the update-side delivery path and still promised an activation withheld "until explicit consent". Both left with the Codex activation store: the mode's terminal is now offline evidence verification, and the harness reference is stale on a head that no longer ships setup --codex.
…ents Completes the previous commit: `EXPECTED_MEMBER_KINDS` is keyed by `InstallPayloadMember`, so leaving `.agents` there is a typecheck error once the allowlist loses it (TS2353, caught by the pre-push gate). Carries the wish amendments in the same commit because this worktree may not rebase: amend the four G3 criteria the head legitimately contradicts (the publish-local-delivery terminal, the codex-module grep's two non-importer classes, the dropped integrationSummary key), transfer the two deferred deliverable halves to the groups that own them by name (D5's role-agent transaction engine to G5 D3, D7e's agent-sync import block to G5 D2), record the codex-native-dogfood release freeze that runs from G3 to G6, and add the installer payload-member rule the .agents delisting turned out to need.
# Conflicts: # src/lib/skills-installer.ts
Codex Review SummaryThis comment shows the latest Codex review activity on this pull request.
ℹ️ About Codex in GitHubYour team has set up Codex to review pull requests in this repo. Reviews are triggered when you
Codex reacts with 👀 while any review is running, comments if it has suggestions, and reacts with 👍 once all reviews finish with no findings. |
|
Important Review skippedToo many files! This PR contains 350 files, which is 250 over the limit of 100. To get a review, reduce the PR to 100 files or fewer by splitting it into smaller PRs or changing its base branch. Upgrade to a paid plan to raise the limit. Usage-priced reviews support at most 300 files. ⚙️ Run configurationConfiguration used: Path: .coderabbit.yaml Review profile: ASSERTIVE Plan: Team Run ID: ⛔ Files ignored due to path filters (18)
📒 Files selected for processing (350)
You can disable this status message by setting the No actionable comments were generated in the recent review. 🎉 ℹ️ Recent review info⚙️ Run configurationConfiguration used: Path: .coderabbit.yaml Review profile: ASSERTIVE Plan: Team Run ID: 📒 Files selected for processing (10)
Included review availability: Your plan provides up to 2 included reviews per hour; 1 remains after this review. 📝 WalkthroughWalkthroughThe PR updates Genie package and plugin metadata from ChangesGenie release updates
Estimated code review effort: 1 (Trivial) | ~5 minutes Merge Risk: ⚪ Minimal · up to This rolling promotion updates release metadata and adds handoff documentation; no actionable merge-blocking risk remains after normal checks and review. 🚥 Pre-merge checks | ✅ 5✅ Passed checks (5 passed)
Full details: Docstring CoverageExplanation No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check. Docstring coverage is scoped to functions touched by this diff. Analyzed 0 functions across 0 files. (10 skipped: 10 unsupported.) ✨ Finishing Touches🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 6b00a9807b
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
|
|
||
| 1. **skills.sh 1.5.23 IGNORES `@ref`** — it always serves the repo's DEFAULT branch (`dist/cli.mjs` binds the third regex capture to `skillFilter`, not ref; only a `#fragment` is a ref). Local-path sources are discovered correctly. B G1 therefore switches the install source to the local delivered tree (`$GENIE_HOME/skills`). Never "verify" a pin with `add repo@ref --list`. | ||
| 2. **skills.sh writes into every supported home** (57 on this host; the CLI registry names 77 agents) while genie records 4 — B G1 fixes recording via a post-install $HOME discovery scan + collision check, and the `installed … into N agent dir(s)` line must report the real N. | ||
| 3. **Host gotchas** (also in agent memory): umask 0077 breaks fresh-worktree lints — run `umask 022` + normalize modes after every `git worktree add`; **never run the full `bun test`** or unfiltered `src/lib/runtime-integrations.test.ts` locally (OOM exit 137, pre-existing `Worker` tests) — CI is the full gate; `scripts/reconcile-release-assets.test.ts` times out locally (pre-existing). |
There was a problem hiding this comment.
Reconcile the conflicting full-test instructions
This tells implementors never to run the full bun test locally, but line 26 requires every group to leave bun run check green, and the check script ends by running the full bun test. An implementor cannot follow both requirements, so they may skip the repository's required validation gate or unexpectedly trigger the documented OOM; specify a viable local gate or narrow the prohibition to the known failing test.
AGENTS.md reference: AGENTS.md:L5-L13
Useful? React with 👍 / 👎.
…ayload Wish skills-everywhere-b, Group 4. One commit so `check` never observes a half-deleted plugin. Deleted: src/hooks/** (27 files: six handlers, the fail-closed envelope, `genie hook dispatch`, the Codex wire adapter, the quarantined trust loader), tests/hooks/, src/term-commands/hook/, the Claude marketplace plugin and the Kimi payload under plugins/genie (.claude-plugin, .kimi-plugin, agents, hooks, workflows, rules, scripts, the skills mirror, settings.json, genie.ts, index.ts and every reference except orca-orchestration.md), root .claude-plugin/marketplace.json, and the six lint scripts that existed only to lint them (council-workflow-lint, hook-bundle-parity, hook-budgets-lint, hook-content-binding, plugin-executables-check, sync-plugin-skills) with their tests and fixtures. `check` is now exactly eight steps and `check:fast` seven: the six `lint:*` gates and `hooks:bind` leave both compositions, ci.yml drops the five matching steps, and build-tarballs.yml drops their path filters. Payload contract: `.claude-plugin/` was staged only for the deleted marketplace manifest, so it leaves INSTALL_PAYLOAD_MEMBERS, AUX_LAYOUT_DIRS, syncAuxiliaryContent and the five toolchain version lists in the same commit — a tarball with a member the installer's exact allowlist does not name is rejected by install.sh's promoter, invisibly to `check`. fresh-install-smoke loses its whole plugin-layout half (it can no longer resolve a payload that does not ship) and derives its inventory from skills/*/SKILL.md; build-binary.sh stops passing --plugin-root. Orphans the deletions exposed, removed rather than left reachable: doctor's `omni hook timeout > pollBudget` check and its helpers, the 115s/125s PermissionRequest ladder constants in omni-config, the `hook` workspace exemption, and the council-stamp.cjs parity half of agent-sync.test.ts. plugins/genie/README.md is rewritten to Orca-only content with the release-docs content assertions re-pointed. AGENTS.md gets the minimum Decision-12 edit; README.md/CLAUDE.md get the command-inventory edit the live CLI registry test forces (16 -> 15 commands). Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01GKqeXSyZMD8YmQtk4vtXFZ
…anifests The .claude-plugin and .kimi-plugin manifests this test read left with their payloads; the surviving shipped manifests are orca-plugin.json and the compatibility plugin.json beside it. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01GKqeXSyZMD8YmQtk4vtXFZ
…ime-integrations G4 deleted the root .claude-plugin/marketplace.json and delisted the payload member, but the Claude runtime integration that registers it survived G5. On any host with the claude CLI, `genie install` printed a spurious failure line and an explicit `--integrations claude` (or `all`) aborted with an unhandled stack trace and exit 1, which install.sh treats as a fatal, incomplete installation. Found by the Group 7 fresh-host pass as finding H1. Executes the ratified disposition A: the install-side Claude subsystem is deleted rather than guarded, because G5 deliverable 3's exhaustive keep-list already excludes every one of its symbols. Deleted from src/lib/runtime-integrations.ts (2,088 -> 1,364 lines): installRuntimeIntegrations, InstallIntegrationsOptions, IntegrationResult, convergeClaudePlugin, installClaudeIntegration, convergeClaudePayloadIdentity, addClaudeMarketplace, verifyClaudePhysicalPayload, ClaudePayloadVerifier, readClaudeMarketplaceSource, fingerprintPhysicalPluginTree, hashPhysicalFileIncrementally, parseClaudePluginState and its validators, the whole RefreshIntent state machine, runChecked, IntegrationCommandError, and the bundle-root resolver with its GENIE_BUNDLE_ROOT probe. RuntimeName and RuntimeExecutableResolver stop being exported. src/genie-commands/update-integrations.ts is deleted whole (refreshUpdatePlugins was its only export and convergeClaudePlugin its only subject), taking narrowUpdatePluginRefreshSelection, ManualUpdateConvergenceResult.integrations and the failed-integration exit arm out of update.ts. install.ts loses the integration-results block: an explicit runtime selection now reports the retirement on one green line and cannot fail. Kept, each with a named consumer: inspectRuntimeIntegrationEvidence, removeRuntimeIntegrations, inspectCodexAgentOwnership, setCodexPluginEnabled, removeCodexPluginRegistration, CODEX_AGENT_INVENTORY_NAME, the consent read/write, CommandRunner/CommandResult/runBoundedIntegrationCommand, resolveRuntimeExecutable and IntegrationSelection. `genie update --sync-only` keeps the ratified contract in substance: it is still identical to a plain `genie update`'s convergence on the same head. The Claude refresh leg is now a structural no-op, so the ledger wording needs a one-line amendment; that is proposed in the PR, not applied here. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01GKqeXSyZMD8YmQtk4vtXFZ
…d genie hook command
feat(wish): skills-everywhere-b — honest pinned install, delete every non-Orca integration
…ost-plugin world Wish skills-everywhere-c, Group 2. Reduce the three contract files to the three surfaces Wish B leaves behind — the signed binary, the skills.sh channel, and the Orca plugin — and make the drift guard enforce it. CLAUDE.md: drop the seven plugin-era gotchas (H3/H4/H6, hook dispatch, the AskUserQuestion carve-out, Codex delivery/activation owners, the .curated lane, SessionStart parity, the stamp root); rewrite the post-delivery convergence gotcha to keep the argv protocol and drop the second activation hop; point the Codex-OTel gotcha at migrateDeadGenieOtel; add four new gotchas (the skills channel, --all consent widening, consent none, the legacy-integration retirement). Remove the src/hooks rows from the architecture tree, drop the setup --codex clause, and rewrite the GENIE_AGENT_NAME / GENIE_AGENT_ID descriptions off the deleted hook subsystem. The skills-channel gotcha is transcribed from merged code, not from the plan: argv from buildSkillsAddArgv, record fields from skillsInstallRecordSchema (including dirDigests, which the plan omitted), and the doctor comparison from checkSkillsChannel — doctor iterates KNOWN_AGENT_SKILL_HOMES and compares the record's inventory and ref; agentDirs is uninstall's removal authority, not doctor's. AGENTS.md: rewrite the release contract (no both marketplaces), the Codex runtime note (no .codex-plugin, no hook review), and the skills bullet; record the git-state freeze as operator policy enforced only by server-side branch protection. README.md: replace the delivery/activation and hook-trust paragraphs with the three-surface story, delete the five plugin-era Codex sections, and rewrite the quickstart selectors, command table rows and the Omni remote-approval bullet. Drift test: RETIRED_FOSSILS gains the nine RETIRED-9 tokens plus native-surfaces.md, .codex-plugin and 'both marketplaces'; the list is now asserted against both files, 'hook' leaves REQUIRED_V5_COMMANDS, and both files must name the public skills command and the install record.
…post-plugin contract Two Group E assertions were drift guards for exactly the README passages this group was mandated to delete, so they went red on the rewrite: - "operator docs distinguish product, role-agent, personal, MCP, and hook inventories" required the five plugin-era inventory rows, the H3/H4/H6 hook table and the fallback-quarantine section. Retargeted to the three delivery surfaces the rewritten README does describe (the public skills command, the install record, the shared agent skills home, MCP retirement, the consent-none line), with the plugin-era strings kept as negative assertions so they cannot come back. - "lifecycle and operator docs name design, plan, and implementation review as distinct mandatory gates" additionally required three Codex-setup sentences. The three review-gate terms — the test's actual subject — still assert against both files; the setup sentences are dropped with the command they described.
…he architecture tree The spot-check that every retained section names something that still exists found src/lib/transcript.ts, src/lib/codex-logs.ts and src/lib/claude-logs.ts in the architecture tree; all three left with the v4 runtime deletion. Replaced with modules that do exist, and rewrote the src/lib/ summary line to match them.
…ll dirs Two new rule families in the existing gate, no parallel script and no new `check` entry. Token rule: BANNED-13 matched as PLAIN SUBSTRINGS (String.includes; no regex, no word boundaries, no allowlist) on EVERY file the walk finds under the scanned skills dir, .md and non-.md alike, so agents/openai.yaml starter prompts are in scope. Each violation reports <path>:<line>, the offending token, and the portable replacement. The scan runs BEFORE the `skills-lint:ignore` bailout; the bailout now skips only the command/resource checks it was introduced for. Structure rules by IMPORT, not re-implementation: scanRepoSkills already computes both findings and is already CI-gated, so skills-lint surfaces them as `empty skill dir` / `nested skill dir` errors instead of silently continuing. scanRepoSkills gains an explicit skillsRoot override so the SKILLS_LINT_DIR fixture root reuses that one walk. Fixtures: one negative per BANNED-13 token, one non-.md fixture, one ignore-marker fixture, nested and empty-dir fixtures, and a positive prose fixture - each asserting the exit code and the message text. Also refreshes the parity script's stale header docstring (the published inventory is the LOCAL checkout; skills@1.5.23 binds the third capture to skillFilter, so an @<ref> suffix is ignored and the default branch is served) and adds the newly imported helper to build-tarballs.yml's PR path filter, which release-docs.test.ts derives transitively.
Applies the BANNED-13 -> portable-role mapping to the five skill files that carried the retired tokens, taking `skills/` from 13 hits to 0: - work/SKILL.md: the role table becomes implementor-low / implementor-mid / implementor-high / reviewer / fixer / final-gate / scout as bare names, the dispatch paragraph no longer promises a runtime custom-agent profile, and the git-state freeze is stated as operator policy - verbatim, in both the shared-workspace paragraph and the freeze block quoted into briefs. The block is additive and stays verbatim-quotable. - wish/templates/wish-template.md: the routing rubric names the portable roles; the structural contract parseWishTemplateContract reads is unchanged (wishes:lint green over all 85 wishes). - README.md: invocation is skills.sh discovery, not plugin selectors; the reason a starter card stays selector-free survives as a reason. The distribution contract drops the deleted plugin mirror and its generator, the inventory table gains the three genie-orca lanes, and the count is 25. - trace/SKILL.md and genie-hacks/references/catalog.md: bare `scout` and `implementor-low`; the catalog's identity comment no longer credits a deleted hook-dispatch subsystem. skills-installer.ts: bumping SKILLS_CLI_VERSION now explicitly requires re-auditing KNOWN_AGENT_SKILL_HOMES and the post-install discovery scan, and the timeout rationale drops its stale "22 skills" literal. release-docs.test.ts moves with the README rewrite it guards.
automagik-dev/docs has no .github/workflows, so the 'Mintlify docs-lint run on that PR is green' criterion was unsatisfiable as written; it now names the four checks that repository actually runs and points at Group 4 for the genie-side docs-lint gate. The validation block no longer opens with 'git submodule update --init .docs-vendor', which resets the submodule to the still-unbumped superproject pointer and turns the hooks.mdx and RETIRED-9 assertions into false negatives while making merge-base --is-ancestor a false pass.
… drop genie selectors
lint:docs-markdown and lint:docs-links now cover docs/installation.mdx and the new docs/release-notes.mdx alongside SECURITY.md and the canisterworm runbook, so the two pages this wish rewrites are gated like the rest. Mintlify pages link to site-absolute routes (/genie/<page>), which the existing ^/ replacement resolved to a path that does not exist on disk. A new replacement pattern maps /genie/<page>[#anchor] to the real file under docs/, so the cross-page anchor from release-notes into the installation page is verified rather than skipped.
A third job greps docs/ for RETIRED-9 plus the docs-only 'plugin marketplace add' bootstrap step and fails with the matches printed. The pattern is byte-identical to the wish's Group 3 validation grep (137 bytes, sha256 12fe1d4a37f66d04...): one list, two call sites. It lives in CI and deliberately not in 'bun run check': docs/ is a symlink into the .docs-vendor submodule, so a contributor with an unpopulated submodule would see a false failure, while every job here checks out with submodules: recursive. Decision 11's blind spot -- a violation landed on docs main after the last pointer bump stays invisible until the next bump -- is recorded in the workflow header. package.json joins the path triggers because it now carries the lint:docs-markdown / lint:docs-links target lists.
…able grep exits 2, not 1, when docs/ does not resolve — an unpopulated .docs-vendor, or the docs repo moving the genie/ subdir the symlink points at. Read as a plain `if` condition that status was indistinguishable from a clean scan, so the job printed its success line and exited 0 having read nothing. Assert docs/ is populated before grepping, and treat any grep status other than 0 (matched) or 1 (clean) as a failure. The 137-byte RETIRED-9 + 'plugin marketplace add' pattern is untouched and still byte-identical to the wish's Group 3 validation grep (sha256 12fe1d4a37f66d046bf661d127630841021f1b8761caff9d16709df820a9bc61).
markdownlint-cli2 treats every argument as a glob, so a target that does not exist is silently skipped and the run reports green over fewer files than it was asked for: 'markdownlint-cli2 SECURITY.md docs/release-notes-DOES-NOT-EXIST.mdx' prints 'Linting: 1 file' and exits 0. With docs/ backed by the .docs-vendor submodule that turns an unpopulated (or not-yet-bumped) pointer into an uncovered pass. Gate the run on the three docs/ targets resolving first, so a missing page fails the script instead of shrinking its scope. lint:docs-links already failed correctly (markdown-link-check throws ENOENT).
The new replacement maps /genie/<route> to docs/<route>.mdx, which holds for every /genie/ link in the two newly-linted pages but not for a route served by a directory index (/genie/config) or written with a trailing slash (/genie/installation/) — either would resolve to a path that does not exist and be reported dead. Latent, not current; note the assumption in the config so the next reader extends the pattern instead of deleting a good link.
docs(wish): skills-everywhere-c — skill-content lint + contract/docs rewrite
Rolling Promotion PR
Auto-maintained rolling promotion PR from
devtomain.Process:
ready-to-mergeadded when all checks passSummary by CodeRabbit
Release
Documentation