From 4e10bd61d9beabd658465eeefe55dd36508c8618 Mon Sep 17 00:00:00 2001 From: Bruno Guidolim Date: Sun, 27 Sep 2026 02:56:41 +0200 Subject: [PATCH] Drop deprecated dependencies and isRequired manifest keys - Remove 10 dependencies and 3 isRequired entries mcs 2026.9.27 ignores - Restate CLAUDE.md invariants that cited isRequired as their reason --- CLAUDE.md | 4 ++-- techpack.yaml | 13 ------------- 2 files changed, 2 insertions(+), 15 deletions(-) diff --git a/CLAUDE.md b/CLAUDE.md index 5cadc84..acb370d 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -54,7 +54,7 @@ To measure any of this, `qmd bench -c memories` is usable as ship **The search call shape is stated in three places, deliberately.** "Typed `lex`+`vec` lines, `rerank: false`, `limit: 6`" appears in `templates/continuous-learning.md` (the only thing that reaches a user's `CLAUDE.md`), `skills/continuous-learning/SKILL.md`, and the `SubagentStart` briefing in `hooks/kb-gate.mts`. No single mechanism reaches all three consumers, so this is three copies rather than one source — change one and check the other two. It matters because the unguided path is measurably worse, not just slower. -**The index's `global_context` is deliberately not a fourth copy.** qmd serves that one string two ways: as the MCP server's `instructions`, once per connection, and as the `context` field of *every* search result. Guidance placed there is therefore paid for per result — at 342 characters it was 38% of a six-result response — while the only consumer it uniquely reaches is a client with no installed `CLAUDE.md` section, which cannot happen because the template is `isRequired`. So it carries identity only ("this is a project memory KB, not external documentation") and the guidance lives in the three copies that are not echoed. Resist putting the call shape back into it. +**The index's `global_context` is deliberately not a fourth copy.** qmd serves that one string two ways: as the MCP server's `instructions`, once per connection, and as the `context` field of *every* search result. Guidance placed there is therefore paid for per result — at 342 characters it was 38% of a six-result response — while the only consumer it uniquely reaches is a client with no installed `CLAUDE.md` section, which cannot happen because a pack installs every template it declares. So it carries identity only ("this is a project memory KB, not external documentation") and the guidance lives in the three copies that are not echoed. Resist putting the call shape back into it. **The same three copies carry "retrieve before relying on a result", and the reason is only recorded here.** qmd's MCP snippet is at most five lines and 300 characters (`extractSnippet` in `store.js`, called with a hardcoded `300` from `mcp/server.js`), and it is anchored by literal substring matching of the first `lex` sub-query. When those terms are not in the matched text it falls back to the top of the chunk — in practice the file's first three lines, which for a memory is its title and `Applies to:`. Measured on a 527-document corpus, 28% of results came back title-only. So a search result is a lead, and answering from it is guessing; `get`/`multi_get` is the step that makes the answer real. The instruction is phrased as an absolute in all three copies on purpose — stating the failure condition invites the reader to decide a snippet looks complete this time. Do not "simplify" it back into step 2's old wording (`Read matching memories`), which worked only because the previous backend returned a whole chunk. @@ -73,7 +73,7 @@ To measure any of this, `qmd bench -c memories` is usable as ship `skills/continuous-learning` (capture) and `skills/memory-audit` (audit) encode the same rules at two different times: capture decides whether to write a memory, audit decides whether to keep one. -**Capture is `isRequired: true`; audit is optional.** Capture must therefore stand alone and can never reference the audit skill's content. +**Capture must stand alone.** Audit is manual-only and a fork can drop it, so capture can never reference the audit skill's content. **Examples must be language-neutral.** The pack installs into projects of any stack, and Swift-specific examples have slipped in more than once. `references/templates.md` is the deliberate exception, since a filled-in example has to be concrete in some language. diff --git a/techpack.yaml b/techpack.yaml index 890c38e..29adf66 100644 --- a/techpack.yaml +++ b/techpack.yaml @@ -52,7 +52,6 @@ components: - id: qmd-install displayName: qmd description: Local search engine over markdown — no daemon, bundled SQLite + sqlite-vec - dependencies: [node] type: configuration shell: "npm install -g @tobilu/qmd@2.8.3" doctorChecks: @@ -91,7 +90,6 @@ components: - id: qmd-model displayName: Embedding model description: Downloads Qwen3-Embedding-0.6B once (~610 MB, shared across all projects) - dependencies: [qmd-install] type: configuration shell: | d=$(mktemp -d) @@ -123,8 +121,6 @@ components: # keep in sync with hooks/sync-memories.mts — it writes the index this opens. - id: memory-loop description: Semantic search over this project's memories, backed by local embeddings - isRequired: true - dependencies: [node, qmd-install, qmd-model] mcp: command: /bin/sh args: @@ -203,7 +199,6 @@ components: - id: skill-continuous-learning displayName: continuous-learning skill description: Extracts learnings and decisions from sessions into memory - isRequired: true skill: source: skills/continuous-learning destination: continuous-learning @@ -219,7 +214,6 @@ components: - id: hook-helpers displayName: Shared hook helpers description: Shared filesystem and project-path helpers for the hooks - dependencies: [node] hook: source: hooks/shared.mts destination: shared.mts @@ -227,7 +221,6 @@ components: - id: hook-continuous-learning displayName: Memory loop activator description: Reminds to evaluate learnings on each prompt - isRequired: true hookEvent: UserPromptSubmit hook: source: hooks/memory-loop-activator.sh @@ -236,7 +229,6 @@ components: - id: hook-sync-memories displayName: Sync memories hook description: Indexes memories into the project's search index on session start - dependencies: [qmd-install, hook-helpers] hookInterpreter: node --experimental-strip-types --disable-warning=ExperimentalWarning hookEvent: SessionStart hookAsync: true @@ -249,7 +241,6 @@ components: - id: hook-reindex-memories displayName: Reindex memories hook description: Reindexes memories when they have changed mid-session - dependencies: [qmd-install, hook-helpers] hookInterpreter: node --experimental-strip-types --disable-warning=ExperimentalWarning hookEvent: UserPromptSubmit hookAsync: true @@ -268,7 +259,6 @@ components: - id: hook-kb-gate-turn displayName: KB gate — turn boundary description: Marks each new prompt so the KB check is required again per turn - dependencies: [hook-helpers] hookInterpreter: node --experimental-strip-types --disable-warning=ExperimentalWarning hookEvent: UserPromptSubmit hook: @@ -287,7 +277,6 @@ components: - id: hook-kb-gate-record displayName: KB gate — record searches description: Records each KB search so delegated discovery can be checked against it - dependencies: [hook-helpers] hookInterpreter: node --experimental-strip-types --disable-warning=ExperimentalWarning hookEvent: PostToolUse hookMatcher: "mcp__memory-loop__query" @@ -305,7 +294,6 @@ components: - id: hook-kb-gate-check displayName: KB gate — check sub-agent spawns description: Warns or blocks when a discovery sub-agent is spawned without KB findings in its prompt - dependencies: [hook-helpers] hookInterpreter: node --experimental-strip-types --disable-warning=ExperimentalWarning hookEvent: PreToolUse # The spawn tool is `Agent` in current Claude Code and `Task` in older @@ -323,7 +311,6 @@ components: - id: hook-kb-subagent-brief displayName: Sub-agent KB brief description: Tells discovery sub-agents that the KB exists, so they search it instead of sweeping files - dependencies: [hook-helpers] hookInterpreter: node --experimental-strip-types --disable-warning=ExperimentalWarning hookEvent: SubagentStart hook: