Reduce the client skill surface to three; always activate the graph - #720
Conversation
Six shipped skills become three (`hypaware-query`, `hypaware-reference`, `hypaware-privacy`) via three separate reductions, each recorded as a decision: - LLP 0212: `hypaware-ignore` / `hypaware-unignore` retire. They predated `hyp session ignore` and carried their own `curl` against the gateway, which drifted (stale `127.0.0.1:8787` fallback, a missing R9 caveat). The CLI verb is now the only implementation; the natural-language routing moves into `hypaware-reference`. - LLP 0213: `@hypaware/context-graph` and `@hypaware/ai-gateway-graph` ship in every install but activated in almost none, for no recorded reason. A new `compose_with` manifest field lets the walkthrough pull them in alongside `@hypaware/ai-gateway`, which removes the packaging constraint that blocked merging `hypaware-graph` into `hypaware-query` (GitHub enrichment splits out to `github.md`). - LLP 0216: report generation moves server-side, so `hypaware-report` (eight Markdown files across both client trees) is removed. `hyp report` stays; the eleven load-bearing constraints the skill was the only home of are handed to the server with their harm statements. LLP 0214 supplies the help surface those reductions lean on: verbs now carry a `help` string through `verbToCommand`, and `CommandRegistry` grows `registerGroup`/`getGroup` so a plugin-owned namespace like `graph` renders prose instead of a bare subcommand table. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
…bility Ten fixes from the round 1 review of #720. Code (LLP 0213 `compose_with`): - A rider no longer loses a user's `enabled: false`. A rider has no picker row by design, so that flag is its owner's only way to decline it, and `mergePlugin`'s pick-implies-enabled rule was deleting it on every reconfigure. `mergePlugin` now takes `isRider` and returns early. - `compose_with` can no longer cross the default-activation boundary. `loadPickerCatalog` filters riders through the new `ridersInDefaultSet`, so a plugin in `V1_EXCLUDED_FROM_DEFAULT` (an API-backed embedder, a credential holder) cannot compose itself in unasked by declaring the field. - `validateManifest` rejects a `compose_with` naming its own plugin. Such a rider is never composable and the fixpoint terminates silently, so the plugin would simply be absent everywhere with nothing to read. Graph availability (`hyp init claude-and-otel-local` wrote a brand new gateway config with no graph, while the skill beside it said otherwise): - The preset composes `@hypaware/context-graph` and `@hypaware/ai-gateway-graph`. `compose_with` is read in `composePickerConfig` alone, so a literal preset must name them itself. - Both `hypaware-query/SKILL.md` copies regain one diagnostic paragraph: if `hyp query status` lists no `node`/`edge`, answer from `ai_gateway_messages` and say to re-run `hyp init`. - LLP 0213 corrects the two claims that made the check look redundant. Docs and hygiene: - Codex `activate()` JSDoc drops `hypaware-report`, which is not registered. - Stale pointers to the retired skills: LLP 0067 gains the same Extended-by banner 0066 got; 0142's dead annotation bullets are struck; 0100 and 0196 gain scoped supersession notes. - LLP 0069's settled table cell is restored with an appended note, matching the append-not-replace pattern this PR set at LLP 0196. - LLP 0197 keeps `#t12-graph-was-already-owned` on the finding a live @ref cites, with the supersession note above it unanchored. - Both client manifests revert to their compact formatting, leaving six semantic lines instead of ~80. - LLP 0216 carries the fixture `pattern` sources into D3, re-homes the never-`rm`-the-sources rule (which guards a still-local surface), and corrects "21 to 10" to 17 to 10. Tests: rider opt-out survives a reconfigure, a picked plugin still loses a stale flag, an excluded plugin declaring `compose_with` is not composed, no excluded manifest declares it, the preset composes the pair in dependency order, self-reference rejected, mutual pair allowed, and the typo'd-name silent no-op is pinned.
|
Review round 1 of The reviewer read the full diff against The two consent and privacy findings, both fixed2. major - Fixed by scoping the delete: 3. major - Fixed with a new exported The other four majors, all fixed1. 4. Dangling reference in shipped runtime source. 5. Retired skills are never pruned from installed clients. 6. Stale pointers to deleted skills in Accepted/Active LLPs. LLP 0213 states the rule ("A retirement is finished when nothing points at it") and missed five sites: Minors, fixed
7. minor - LLP number collision. YOUR CALL, deliberately not touchedOpen PR #716 adds Whichever merges second has to renumber, which is mechanical and permitted under LLP 0156. Neutral is not picking which, since that is cross-PR coordination affecting a PR it does not own this decision for. Worth deciding before you merge either, not after. Also checked, clean
Cosmetic, not fixed: Gates after the fixes: One note from the fixer worth passing on: typecheck initially failed on a new test file, so The head has moved to |
The round-1 guard against `compose_with` bypassing `V1_EXCLUDED_FROM_DEFAULT` landed inside `loadPickerCatalog`, which `resolvePickSeeding` only reaches when no catalog is injected. But `runInitWizard` (the shipped `hyp init` entry point) always injects one, built by `loadWizardCatalog` from the loaded *and* excluded manifests, so the boundary held on the legacy walkthrough and not on the path that ships. `ridersInDefaultSet` now filters against `V1_EXCLUDED_FROM_DEFAULT` itself rather than a `loaded` array the caller has to supply: only one of the three catalog sources has such an array, and a filter that depends on what the caller passes is a filter a caller can skip. Both branches in `resolvePickSeeding` run it, so no catalog source (wizard, injected, or discovered) routes around it. The new regression test goes through `resolvePickSeeding` with an injected catalog rather than calling the filter directly: a unit test of the filter cannot catch a caller that does not call it, which was the whole bug. It fails if the `pick.js` filter is reverted. Also restores the two annotation bullets LLP 0142 (Accepted) settled, verbatim as at 207aaf1, with an appended `Superseded-by:` forward-ref on each noting the annotation sites no longer exist. Matches how 0069, 0100, and 0196 were handled in this PR: append, never replace.
|
Review round 2 of 1. major - the allowlist filter guarded the legacy path, not the shipped one. FIXEDRound 1's fix B (stop The reviewer reproduced it against the committed tree: staging the one-line manifest edit the filter exists to defeat and calling Not currently exploitable (no shipped excluded manifest declares Fixed by making the filter unavoidable rather than source-dependent. 2. minor -
|
|
Triage after the review budget (LLP 0017). Two review rounds ran (14 findings, 12 fixed). Both residuals were judged non-blocking, so this PR can ship. (A) Retired skills are never pruned on upgrade - deferred to #726. The mechanism was confirmed by reading: (B) The three-way LLP 0212 collision - repo-hygiene and merge sequencing, not a software defect. LLP docs are not runtime code and nothing acts on a doc's number. See the merge-time note below, which matters more than the classification. Merge-time note, please read before merging any of the three
The repo already has a settled procedure: If #720 is not merged first, its sweep touches 13 files: the doc, 2 |
…#750) (#757) * walkthrough_picker_to_first_query golden predates compose_with riders (#750) The Phase 5 golden config still lists the six plugins the picker rows compose, but `hyp init` has written eight since #720 landed LLP 0213 D1: `@hypaware/context-graph` and `@hypaware/ai-gateway-graph` declare `compose_with: ["@hypaware/ai-gateway"]` and ride the gateway pick. The picker is right and the golden is stale. #720 added the rider fold to `composePickerConfig` (+153 lines in `src/core/cli/walkthrough.js`) and touched no smoke flow, which is why neither `goldenPickerConfig` nor `bundled.js` shows the change in `git log`: the divergence arrived through the manifests. Rather than paste the two names in, the golden derives its rider tail from the same declarations the composer reads, so the next derived-data plugin is a manifest edit rather than a re-red smoke. The literal half is what the picker actually decides: which rows compose, the upstreams, the OTLP port, the sink shape, retention. The derivation reads manifests, not `ridersFor`, so a plugin that is neither picked nor declared a rider still fails the assertion; the rider mechanism itself keeps its unit coverage in `test/core/compose-picker-config.test.js`. Co-Authored-By: Claude <noreply@anthropic.com> * Make composedRiders a fixpoint and fix its default-activation comment (#750) composedRiders was single-pass while ridersFor runs to a fixpoint, so a rider whose compose_with names another rider (rather than a picked plugin) was composed by the implementation but missing from the golden, false-redding the smoke on a manifest-only edit. Run the same manifest set to a fixpoint, mirroring ridersFor, so second-order riders land in the golden too. Also corrects a comment that claimed discoverBundledPlugins's loaded bucket is "the same cut" ridersInDefaultSet makes on the composer. It is not the same cut (allowlist membership vs. exclude-set non-membership); they only agree because those two lists partition the whole bundled workspace and loadPickerCatalog reads only them. --------- Co-authored-by: test <test@test.com> Co-authored-by: Claude <noreply@anthropic.com>
Six shipped skills become three on a default install (
hypaware-query,hypaware-reference,hypaware-privacy). Three independent reductions land together, each recorded as an Accepted decision, plus the CLI help capability they all lean on.What changed
LLP 0212 - the session opt-out is a CLI verb.
hypaware-ignoreandhypaware-unignorewere written beforehyp session ignoreexisted, so each carried its owncurlagainst the gateway control route. Once LLP 0067 shipped the verb, the skills became a second, untested implementation, and drifted: a stalehttp://127.0.0.1:8787fallback (the real default is127.0.0.1:18521) and a missing LLP 0066 R9 caveat. Both skills are removed; the CLI verb is the only implementation, and the natural-language routing moves intohypaware-reference.LLP 0213 - the graph plugin is always active.
@hypaware/context-graphand@hypaware/ai-gateway-graphare in the bundled allowlist, so they ship everywhere, but day-to-day dispatch bootsbootProfile: 'config'and the walkthrough composesplugins[]from picker rows only. An engine plugin that is neither a client nor an export sink had no slot, so it was never written, andhyp graph --helpreported the plugin as unavailable on installs months old. A newcompose_withmanifest field lets a plugin be pulled in alongside another (here,@hypaware/ai-gateway). With the packaging constraint gone,hypaware-graphmerges intohypaware-queryas LLP 0196 intended, with the conditional GitHub bridge split out togithub.md.LLP 0216 - reports generate server-side. Generating a report is analysis over a fleet's whole recorded history, which the server is better placed to do.
hypaware-report(a routerSKILL.mdplus seven stage files, in both client trees) is removed.hyp reportstays, and the eleven load-bearing constraints the skill was the only home of are handed to the server along with the harm statements that justified them.LLP 0214 - verbs and plugin groups carry long help. The precondition for moving mechanical prose out of skills.
VerbRegistrationgains an optionalhelpthatverbToCommandpasses through to dispatch's existing--helpinterception, andCommandRegistrygainsregisterGroup/getGroupso a plugin-owned namespace likegraphrenders a header and paragraph instead of a bare subcommand table. Registering a group is metadata only: it adds nothing tolist(), so it cannot shadow a command or appear as its own subcommand.Testing
npm test- 3894 pass, 2 skipped. Two failures remain, both from stalenode_modulesin this checkout rather than from the diff:report-render.test.js/report-render-hrefs.test.js:Cannot find package 'marked'(declared inpackage.json, not installed).format-parquet-clustering.test.js: installedhyparquet-writeris 0.16.1,package.jsonpins 0.16.6.llp-ref-hygiene.test.jspasses. It readsgit ls-files, so it fails against unstaged deletions and is green once the removals are staged.New coverage:
test/core/group-and-verb-help.test.js,test/core/manifest-compose-with.test.js,test/core/compose-picker-config.test.js, and additions totest/plugins/context-graph-query.test.js.🤖 Generated with Claude Code