Repo impact map#33
Draft
mattford63 wants to merge 13 commits into
Draft
Conversation
Introduces allium:impact, a narrow skill that builds and queries a bidirectional JSON map linking spec constructs to implementation symbols via the built-in LSP tool. Python ships as the first language adapter (pyright-lsp); additional languages are added by dropping an adapter file under skills/impact/adapters/ -- no change to the core pipeline or schema. Wires weed, distill, propagate and tend to consult the map before falling back to grep-based correlation. All callers degrade gracefully when no adapter matches or the LSP is unavailable, so the map is an accuracy/consistency win rather than a prerequisite. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Re-runs against a real Python codebase showed the impact map was pulling weed toward structural findings (fields, types, renames) at the expense of behavioural ones (does the code actually emit the warning this rule promises?). The first fix split "How you work" into structural and behavioural passes; the second recognised that @guidance and @Guarantee live on surfaces, not rules, and extended the behavioural pass to iterate spec:Surface.* and spec:Invariant.* links alongside spec:Rule.* After both edits, weed recovered 6/6 of the behavioural findings the no-map baseline caught, plus produced surface-obligation tick-lists and contract-level per-invariant reads that neither run could produce before. Also adds one line to the impact-map reference's "Reading the map" contract: the map points consumers at code, it does not replace reading it. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
The adapter named `pyright-lsp` as its LSP plugin dependency but didn't say how to get it. Adds uv tool / uv pip install commands for the pyright binary and the /plugin marketplace steps for the Claude Code plugin, plus /reload-plugins as the no-restart path. Also tidies pre-existing MD032 lint warnings in §5 (blank lines around bullet lists under bold framework headings). Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Empirical testing against a real Python project with pyright installed on PATH showed Claude Code's LSP tool runs pyright in single-file mode: documentSymbol and hover work, workspaceSymbol returns empty, and cross-file findReferences / goToDefinition don't resolve project-internal imports. The impact skill was designed assuming workspace-wide symbol search via LSP workspaceSymbol, which is not available. Rewrites the Build pipeline's step 3 to use Glob + per-file documentSymbol for candidate discovery, with workspaceSymbol treated as an optional additional source rather than the primary one. Surface mapping now uses Grep + documentSymbol instead of workspaceSymbol + findReferences. Adds a fourth degraded-exit reason tag (lsp-single-file-mode), clarifies the other three with required details strings, and explicitly instructs callers to quote the reason and details verbatim rather than paraphrase — the prior paraphrase-as-diagnosis pattern turned "Executable not found in $PATH" into "workspaceSymbol doesn't accept query strings" in a weed report footer, which was misleading. The Python adapter's install note now makes explicit that uv pip install into a project venv does not put pyright-langserver on the global PATH that Claude Code's LSP tool inspects; uv tool install is required. Added a "which pyright-langserver" verification step. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Two related tightenings to weed's §How you work, both driven by empirical regressions observed in runs against a real Python project with a working impact map. Run 4 showed that a dense impact map can crowd out behavioural coverage: weed visited 2 of 9 specs and called the report done. Adds a testable coverage constraint: count the specs in the map, count the specs mentioned in the report, the two numbers must match. Adds a per-spec budget rule: behavioural pass first, structural/orphan findings collected in a batch at the end, so structural signal doesn't exhaust context before later specs get visited. Run 5 confirmed 9/9 coverage but showed that surface-level `@guidance` and `@guarantee` narrative findings were still getting lost (streaming guidance and FK target-table guarantee missed) — the behavioural pass's sub-bullets were present but not producing structured output, so surfaces were being compressed into one-line summaries. Adds a required output format: every visited `spec:Surface.*` MUST appear as a tick-list sub-section with one row per obligation, each tagged ✓/✗/⚠ with a file:line citation. All-✓ surfaces still belong in the report as positive alignment evidence. Includes a worked example showing exactly the target output shape. Run 6 (post-edit) achieved 9/9 coverage and 5/6 behavioural recovery — both previously missed narrative findings returned, plus new signal only the tick-list format could produce (exposed-but-not-rendered ✗ rows, undeclared state-graph transitions, all-✓ positive-evidence rows). The remaining miss (`batch_size` hardcoded) is a separate failure class — declared config values not referenced by any rule — not addressed by these edits. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Two follow-ups after run 6: The surface tick-list format required every visited surface to emit every obligation (✓/✗/⚠). That made the report heavy — surfaces with no issues still produced long subsections of positive evidence. The internal walk stays exhaustive (still load-bearing for @guidance / @Guarantee catches), but output is now filtered: only ✗ and ⚠ rows are emitted, and a surface with no issues produces no subsection. Run 6 caught 5/6 of the behavioural baseline — the missing finding was `config.batch_size` declared in the spec, hardcoded `BATCH_SIZE = 200` in code, with no rule referencing the config value so the rule-level "each referenced config value" sub-check never fired. Adds a per-spec-config pass: enumerate every declared config value and check both (a) at least one rule references it by qualified name, and (b) code reads from the config layer using that name. Catches values no rule happens to mention. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Adds skills/impact/adapters/java.md covering jdtls-lsp with JDK 17+. Name-variant generator handles Java's layered-architecture conventions (<Name>Service, <Name>Repository, <Name>Controller, <Name>Impl, <Name>Dto, <Name>Factory, I<Name> interface prefix) plus CQRS-style handlers (<VerbPhrase>Command, handle<VerbPhrase>). Surface entry-points cover Spring Boot (@RestController, @GetMapping etc.), JAX-RS (@path, @get), Micronaut, Quarkus, Servlet API, gRPC, and the integration patterns Spring/Micronaut projects actually use (@KafkaListener, @RabbitListener, @JmsListener, @scheduled, @eventlistener, AWS Lambda RequestHandler). Project-root rule handles Maven multi-module (topmost pom.xml with packaging=pom wins), Gradle multi-module (settings.gradle* marker), and excludes the usual generated-sources paths that Lombok, MapStruct and codegen tools produce. Install path is more involved than pyright — brew install jdtls on macOS, AUR on Arch, manual download elsewhere — and a first-call cost warning is included since JDT.LS indexes the classpath on cold start. Registers the adapter in the impact SKILL.md fingerprint table and the "currently supported" list. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Adds skills/impact/adapters/typescript.md covering typescript-lsp (typescript-language-server + tsserver). Name-variant generator handles camelCase / PascalCase conventions plus React's use<Name> hook prefix, CQRS suffixes (<VerbPhrase>Command / Handler / UseCase), and common DTO / schema / props suffixes. Surface entry-points cover Express / Fastify / Koa / NestJS / Hono for HTTP APIs, Next.js App Router and Pages Router (both), tRPC procedures, GraphQL resolvers (Apollo and NestJS), React / Vue / Svelte / React Native for UI, and the JS-ecosystem integration patterns (BullMQ, node-cron, kafkajs, NATS, WebSocket, AWS Lambda, Vercel/Netlify functions, Cloudflare Workers, Temporal workflows). Project-root rule handles monorepos: npm/pnpm/yarn workspaces, Nx, Turborepo. Exclusions cover the build outputs (dist, .next, .turbo, .vercel), test/story files, ambient .d.ts types, and the generated-code patterns TS codegen produces (graphql-codegen, Prisma, Protobuf). Notes the tsconfig scope caveat: tsserver degrades on files outside the nearest tsconfig.json's include/files set, which matters when picking sentinel files. Registers the adapter in the impact SKILL.md fingerprint table and currently-supported list. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Adds skills/impact/adapters/kotlin.md covering kotlin-lsp (JetBrains' official LSP at github.com/Kotlin/kotlin-lsp, installed via `brew install JetBrains/utils/kotlin-lsp`). Requires JDK 17+ shared with the Java adapter when both are loaded. Name-variant generator handles Kotlin-idiomatic patterns not shared with Java: companion-object factories (Foo.Companion.create instead of createFoo), `suspend fun` coroutine handlers, extension functions, data/sealed classes, and the clean-architecture / Android MVVM suffixes Kotlin projects use heavily (<Name>UseCase, <Name>ViewModel, <Name>UiState, <Name>Screen, <Name>Composable). Surface entry-points cover Ktor (routing DSL, plugin install, WebSocket blocks), Spring Boot / Micronaut / Quarkus / JAX-RS (reuses the Java annotations), Android (Activity, Fragment, Hilt @androidentrypoint), Jetpack Compose (@composable), graphql-kotlin, gRPC Kotlin, and coroutines-based integration surfaces (Flow collectors, Channel receivers, Retrofit suspend interfaces, WorkManager workers). Project-root rule handles Gradle multi-module, Kotlin Multiplatform source sets (commonMain / jvmMain / androidMain / nativeMain), and Android buildSrc exclusion. Generated-code exclusions cover Hilt, Dagger, Room, DataBinding, kapt, KSP output. Notes three call-hierarchy quirks specific to Kotlin: extension functions appearing as methods on the receiver type, top-level functions with no enclosing class, and companion-object members showing as static-like in the LSP. Plus the Gradle-dependency prerequisite caveat (./gradlew help must succeed before impact can map cleanly). Registers the adapter in the impact SKILL.md fingerprint table and currently-supported list. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
weed, propagate and distill previously auto-invoked the impact skill at
startup, bending their default flow around the map's existence. Revert
each to its pre-impact behaviour (grep + read correlation) and gate map
use behind explicit user direction ("use the impact map", "in map mode",
"via impact"). Each affected skill grows a "Map mode" appendix listing
per-step overrides, so the default body stays stable and the map's
surface area is one section per skill.
tend keeps its defensive pre-rename orphan-link check (one-shot warning,
not a gate) and now quotes the map's built_at so a stale map is visible.
The impact-map reference doc gains an "Opting in" section and the "When
to rebuild" triggers are reframed as user-initiated.
Addresses TODO item #1.
Co-Authored-By: Claude Opus 4.7 (1M context) <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.
Add the capability to use an impact map with Allium. The skills require you to say "use map" in order to invoke it otherwise it produces normal Allium output.