Upstream tracker
Claude Code plugin that automates the sprint workflow for projects using beads and Basic Memory
npx -y skills add voxpelli/claude-beads --skill upstream-trackerAssembled from the repository path, not quoted from the project. Check it against their README if it does not work.
One thing to look at
- 2 stars2 stars. Stars are a popularity signal and not a quality one, but at this level it is likely that nobody has read this closely except its author, and you would be relying on your own review.
What its author says it does
Copied from the file, not written here
Manage upstream issue tracking for this project. Use when the user wants to log a bug or friction point in a vendor package or npm dependency, review open upstream items, resolve a tracked issue, run a trend review, generate the upstream observations section of a sprint retrospective, promote upstream observations to Basic Memory, discover known friction from other projects, or track a contribution opportunity. Trigger phrases: 'upstream', 'track this', 'vendor issue', 'log this bug', 'review upstream', 'trend review', 'cross-vendor', 'this is a bug in X', 'promote to memory', 'promote upstream', 'sync from memory', 'known friction', 'resolved upstream', 'mark as fixed', 'tool issue', 'action bug', 'contribution opportunity', 'upstream this', 'contribute back', 'upstreamable', or any mention of friction with an external package.
SKILL.md
28.5 KB, as published. Nobody here has run it
Upstream Tracker
Manage the UPSTREAM-*.md files that track bugs, feature requests, contribution
opportunities, and friction discovered in upstream packages while building this
project.
Tracking Files
Vendor packages (permanent files)
Vendor packages are declared in .claude/vendor-registry.json (if it exists) as
an array of {prefix, remote, branch, package} objects, or as packages listed under
workspaces in package.json. Each vendor package gets a permanent
UPSTREAM-<package-name>.md tracking file that always exists, even when empty.
To discover which packages are vendors, read .claude/vendor-registry.json if
it exists, or inspect package.json workspaces. If neither is present, ask the
user which packages should be treated as permanent vendor fixtures.
Non-vendor dependencies (ephemeral files)
Any npm dependency can get an UPSTREAM-<package>.md file when you encounter a
bug or limitation worth tracking (e.g., UPSTREAM-umzeption.md). Create the
file on first encounter. Delete the file entirely once all its entries are
resolved — there's no reason to keep an empty tracking file for a regular
dependency. To discover existing non-vendor files, glob for UPSTREAM-*.md and
exclude the known vendor files.
Non-npm tools (ephemeral files)
Tools in the project's environment (Homebrew formulae, GitHub Actions, Docker
images, VSCode extensions) can also accumulate friction worth tracking. Create
an UPSTREAM-<tool-type>--<name>.md file on first encounter, using the same
ephemeral pattern: delete when all entries are resolved. See the file naming
convention in the Guidelines section for the tool-type prefix format.
Shared structure
All upstream files share the same structure: Feature Requests | Bugs | Upstream Opportunities | Cross-Vendor Inconsistencies | Trend Reviews
Non-vendor files typically use Feature Requests, Bugs, and Upstream Opportunities sections (cross-vendor inconsistencies only apply when multiple vendor packages share an API surface).
Workflows
Determine which workflow the user needs based on their request. If ambiguous, default to the most likely workflow based on context.
1. Log a new entry
When the user encounters upstream friction — a bug, a missing feature, an awkward API, a cross-vendor inconsistency, or a contribution opportunity — add it to the correct file. Infer the details from the current conversation context: what code was being written, what error occurred, what workaround was needed. The user shouldn't have to re-explain something that's already visible in the session.
Steps:
-
Identify which upstream package is involved from the conversation context (the code being discussed, the error encountered, or the workaround applied). If the observation is a cross-project pattern (shared approach, divergence, extraction candidate, capability gap) between sibling projects, redirect to
/synergy-tracker. Sibling projects that ship upstream artifacts (skills, hooks, agents) can still receive upstream-tracker entries for concrete bug reports, feature requests, or contribution opportunities against those artifacts. This can be a vendor package OR a regular npm dependency. This can also be a non-npm tool — a Homebrew formula, a Homebrew cask, a GitHub Action, a Docker image, or a VSCode extension. Use thebrew:<name>,cask:<name>,action:<owner>/<repo>,docker:<image>, orvscode:<ext>prefix notation when identifying tools (consistent with/tool-intelfrom vp-knowledge). 1a. Basic Memory pre-check. If Basic Memory MCP tools are available, callmcp__basic-memory__search_noteswith the package name. If a matching note exists and contains an## Upstream Frictionsection with entries related to the issue being logged, surface them to the user: "This friction is already tracked in Basic Memory from another project: [summary]. Logging it locally as well so this project tracks it." Also surface any### Upstream Opportunitiesentries — another project may have already attempted contributing this. Proceed regardless — this is informational, not a gate. If Basic Memory tools are not available, skip this step silently. -
If the package is a non-vendor dependency and no
UPSTREAM-<package>.mdfile exists yet, create it with this template:## Feature Requests _No entries yet._ ## Bugs _No entries yet._ ## Upstream Opportunities _No entries yet._Non-vendor files typically omit Cross-Vendor Inconsistencies and Trend Reviews sections unless the project uses multiple vendor packages sharing an API surface.
-
Classify the entry:
- Bug — unexpected behavior, something that doesn't work as documented
- Feature Request — a missing capability the package should have
- Upstream Opportunity — downstream code (a workaround, extension, or enhancement) that solves a real problem and could benefit the upstream package's users generally. Distinct from Feature Request: working code already exists locally. Use when the project has built something that should be contributed back.
- Cross-Vendor Inconsistency — a pattern, convention, or API that one vendor package supports but another doesn't, creating friction for the consumer. Relevant when multiple vendor packages share an API surface.
-
Read the target
UPSTREAM-*.mdfile -
Compose the entry from the consumer app's perspective (focus on impact, not internals)
-
Add the entry under the correct section heading, using today's date
Entry format for Feature Requests:
- **Short title** (YYYY-MM-DD) — Description of the desired behavior and why
it matters for the consuming app. [upstream: <url>]
Ownership: upstream|us|shared · Workaround: none|partial|full — description
Upstream URL is optional — add if you've filed a feature request upstream.
Entry format for Bugs:
- **Short title** (YYYY-MM-DD) [blocking|degraded|minor] — What happens, how to
reproduce, and the expected behavior. [upstream: <url>]
Severity: blocking|degraded|minor · Ownership: upstream|us|shared · Workaround: none|partial|full — description
Severity tag in brackets is optional — use blocking (no workaround), degraded
(workaround exists but costly), or minor (edge case). Upstream URL is optional —
add if you file an issue or PR upstream.
Entry format for Upstream Opportunities:
- **Short title** (YYYY-MM-DD) — What was built, why it could be valuable
upstream, and the consumer-side motivation. [upstream: <url>]
Source: <file-or-branch> · Merge readiness: direct|needs-redesign|proof-of-concept
Ownership: us|shared · Workaround: full|partial — description of local solution
Source: points to the local artifact (file path, branch, PR URL, or beads
issue ID). Merge readiness: assesses upstream integration effort: direct =
submittable as-is, needs-redesign = concept valid but too project-specific,
proof-of-concept = demonstrates approach but not library-quality. Ownership:
is typically us (we built it) or shared (upstream maintainer is
participating). [upstream: <url>] is added once a PR or issue has been filed.
Entry format for Cross-Vendor Inconsistencies:
- **Short title** (YYYY-MM-DD) — What the sibling package does, what this
package lacks, and the consumer-side friction it causes.
Ownership: upstream|us|shared · Workaround: none|partial|full — description
Structured fields (all optional — existing entries without them remain valid):
| Field | Values | When to use |
|---|---|---|
Severity: | blocking · degraded · minor | Bugs only. How much this hurts day-to-day development. blocking = no workaround, degraded = workaround exists but costly, minor = edge case or minor inconvenience |
Ownership: | upstream · us · shared | All entry types. Who needs to act: upstream = waiting on a release, us = we need to adapt or contribute a fix, shared = both sides need changes |
Workaround: | none · partial · full — description | All entry types. none = no mitigation, partial = mitigation exists but incomplete, full = fully mitigated (describe how). Helps prioritize: entries with none are more urgent |
Source: | file path, branch, PR URL, or beads issue ID | Upstream Opportunities only. Points to the local artifact that is the candidate for contribution |
Merge readiness: | direct · needs-redesign · proof-of-concept | Upstream Opportunities only. direct = submittable as-is, needs-redesign = concept valid but too project-specific, proof-of-concept = demonstrates approach but not library-quality |
These fields go on a continuation line below the entry's main description line,
indented to match. They are metadata for triage and trend review — the main
description line remains the primary content. Omit fields that don't add useful
signal (e.g., skip Workaround: none when the severity already says blocking).
When adding the first entry to a section, replace the _No entries yet._
placeholder. Keep entries concise — 1-3 sentences. The title should be
scannable (e.g., "Missing session type export", not "Issue with types").
6a. Eager promotion check. If Basic Memory MCP tools are available, assess
the project's tempo:
git rev-list --count --since="90 days ago" HEAD 2>/dev/null
Guard: skip if the repo has zero commits total
(git log --oneline -1 2>/dev/null returns empty).
| Tempo | Commits in 90 days | Promotion behavior |
|---|---|---|
| Dormant | 0–4 | Offer inline promotion for any promotable entry (Ownership: upstream/shared, or any Upstream Opportunity) |
| Moderate | 5–14 | Offer inline promotion for high-urgency entries only: blocking bugs with Ownership: upstream, or Upstream Opportunities with Merge readiness: direct |
| Active | 15+ | Skip — the normal sprint cadence will handle promotion via workflow 6 (Promote to Basic Memory) |
When offering inline promotion, present: "This project has low commit frequency — UPSTREAM entries can sit unread for months before the normal promotion cycle runs. This entry looks promotable to Basic Memory. Want to promote it now? I'll show you the generalized form first." For Upstream Opportunities in dormant repos, add: "This contribution opportunity may become harder to merge as upstream evolves — promoting sooner makes it discoverable from other projects."
If the user agrees, apply workflow 6 (Promote to Basic Memory) steps 3–4 scoped to this single entry (route by target type, draft generalized form, user confirms text, write or flag). If the user declines, or if Basic Memory tools are not available, or if the project is active, skip silently.
If the logged observation looks generalizable beyond this project (about the package's behavior, not a project-specific integration choice) and the eager promotion check did not fire, note that workflow 6 (Promote to Basic Memory) can share it across projects at the next sprint boundary.
2. Review open items
Summarize the current state of all upstream tracking files (vendor and non-vendor).
Steps:
- Glob for all
UPSTREAM-*.mdfiles and read them - Present a summary grouped by file, showing counts and listing open items
- Flag anything that looks stale (older than ~3 months with no activity)
Output format:
## Upstream Status
### <package-name>
- Feature Requests: N open
- Bugs: N open
- Upstream Opportunities: N open
- [list each with title and date]
### Notes
- [any stale items or observations]
- [flag Upstream Opportunities with Merge readiness: direct and no [upstream:] URL as "contribution-ready, not yet submitted"]
If all files are empty, say so and suggest checking whether any known friction points should be captured.
3. Resolve an entry
When an issue has been fixed upstream, simply delete it from the tracking file. There's no need to keep resolved entries — the version control history preserves what was tracked and when it was removed.
Steps:
-
Read the relevant
UPSTREAM-*.mdfile -
Find the entry (by title or user description)
-
Delete the entry from its section
-
For vendor files: if the section is now empty, restore the
_No entries yet._placeholder -
For non-vendor files: if the file has no remaining entries, delete the file entirely (
git rm) -
Mention the resolution in your commit message so the git log captures it
-
Basic Memory annotation. If Basic Memory MCP tools are available, call
mcp__basic-memory__search_notesfor the package name. If a matching note exists, callmcp__basic-memory__read_noteto get its exact content. If the note has an## Upstream Frictionsection containing the resolved entry, callmcp__basic-memory__edit_notewithfind_replaceto append an annotation to the entry's line. Use entry-type-specific annotation text:- Bugs / Feature Requests:
_(Resolved YYYY-MM-DD)_ - Upstream Opportunities (merged):
_(Contributed upstream: <url> merged YYYY-MM-DD)_ - Upstream Opportunities (abandoned):
_(Closed YYYY-MM-DD — not contributed)_
Match against the note's exact text from
read_note— do not construct match strings from memory. Annotate, never delete — only workflow 6 (Promote to Basic Memory) moves entries to the### Resolvedsubsection during its prune pass. If no matching Basic Memory entry exists (it was never promoted), skip silently. If Basic Memory tools are not available, skip silently. - Bugs / Feature Requests:
4. Trend review (quarterly)
Every 4th sprint, perform a cross-cutting analysis of all tracking files.
Steps:
- Glob for all
UPSTREAM-*.mdfiles and read them - Analyze open items for common themes (e.g., recurring type export issues, similar API gaps across packages)
- Look for cross-vendor inconsistencies — patterns or APIs that one vendor package supports but its siblings don't yet
- Evaluate continued validity — are any open items obsolete or already addressed? Delete resolved items (they're preserved in git history).
- Identify items that should be escalated, using these empirical timelines as
guidance:
- Bugs typically resolve in 5–10 sprints; items beyond 10 sprints warrant escalation (upstream PR, issue, or workaround acceptance)
- Feature requests typically take 10–20 sprints; items beyond 20 sprints may never land — consider permanent workarounds or forks
- Upstream Opportunities without an
[upstream:]URL after 5 sprints → escalate (submit the PR or close the opportunity). With a submitted PR but no merge after 10 sprints → ping upstream or consider a fork - Cross-vendor inconsistencies often resolve only on a next major version; track with low urgency unless actively blocking development
- Dormancy-aware scaling. In projects with ≤4 commits in the last 90 days (see project tempo in Guidelines), double escalation thresholds — entries in dormant repos age by calendar, not by sprint cadence
- Add a Trend Review entry to each file's Trend Reviews section
- Delete non-vendor UPSTREAM files that have no remaining open entries
- Present findings to the user
- Promotion candidates. Flag entries that have been open across multiple
trend reviews AND have
Ownership: upstreamorshared— these are strong candidates for workflow 6 (Promote to Basic Memory). Also flag Upstream Opportunities withMerge readiness: direct— these are particularly strong candidates because the cross-project signal (a proven approach exists) is immediately actionable. Suggest running workflow 6 (Promote to Basic Memory) if any are found.
Trend Review entry format:
### Review — YYYY-MM-DD (Sprint N)
- **Themes:** [common patterns across open items]
- **Still valid:** [items confirmed as still relevant]
- **Recommend closing:** [items that are obsolete or low-priority]
- **Escalate:** [items past their expected resolution window — include upstream URL if filed]
5. Sprint retrospective support
Help generate the "Upstream observations" section of a sprint retrospective.
Steps:
- Read all
UPSTREAM-*.mdfiles to understand current state - Review the conversation history for any vendor friction encountered during the session — workarounds, type issues, missing APIs, confusing behavior
- Log any untracked items discovered from context (workflow 1 (Log a new entry))
- Draft the upstream observations section for the retro
- Note any entries that appear generalizable beyond this project — the
retrospective may want to chain into workflow 6 (Promote to Basic Memory)
after the retro is written. List Upstream Opportunities and their submission
status. Flag
Merge readiness: directopportunities with no submitted PR as sprint action items.
6. Promote to Basic Memory
Promote generalizable upstream friction observations from project-local
UPSTREAM files into cross-project Basic Memory entity notes. This creates an
## Upstream Friction section in the target entity note (e.g., npm/<package>,
brew/<name>, actions/<owner>/<repo>). Use only MCP tools from this skill's
allowed-tools — mcp__basic-memory__search_notes, mcp__basic-memory__read_note,
mcp__basic-memory__edit_note. If Basic Memory MCP tools are not available,
report that promotion is unavailable and suggest checking Basic Memory manually.
Steps:
- Scan for candidates. Glob all
UPSTREAM-*.mdfiles and read them. Identify entries that meet ALL of these criteria:Ownership:isupstreamorshared(skipusentries — those are integration choices, not package friction)- The observation is about the package/tool itself, not about how this specific project uses it
- The entry has enough detail to be useful without project context
- When ownership is absent, default to promoting unless clearly project-specific
- Upstream Opportunities override. Entries in
## Upstream Opportunitiesare always eligible for promotion regardless ofOwnership:value. The knowledge that a working solution exists and could be contributed is inherently cross-project useful — other projects consuming the same package benefit from knowing a proven approach exists, even though the work was done on "our" side. Do not filter these by Ownership.
- Present candidates to the user. For each candidate, show:
- Package or tool name and target type (npm, brew, cask, action, etc.)
- Entry title and classification (Bug / Feature Request / Upstream Opportunity)
- A draft generalized version with project-specific file paths stripped.
For Upstream Opportunities: keep
Merge readiness:, replace local file paths inSource:with generic descriptions ("middleware adapter", "test helper", "compatibility shim") - Whether a Basic Memory note already exists for this package/tool Let the user approve, edit, or skip each candidate. Never auto-promote.
- Route by target type. Search Basic Memory for an existing entity note
using the routing table in
references/basic-memory-friction-format.md. - Write or flag. For each approved candidate:
- Note exists, has
## Upstream Friction— callmcp__basic-memory__edit_notewithfind_replaceto append the entry under the correct subsection (### Bugs,### Feature Requests, or### Upstream Opportunities). Anchor the match text to include the next###heading for uniqueness. Useexpected_replacements=1. Always callmcp__basic-memory__read_notefirst and match against its exact text. - Note exists, no
## Upstream Friction— callmcp__basic-memory__edit_notewithinsert_before_sectiononRelationsto add the full## Upstream Frictionsection with the entry. - No note exists — do NOT create a thin note. Flag for enrichment:
"No Basic Memory note for
<package>. Run/package-intel <package>(or/tool-intel <tool>for non-npm tools) to create one, then re-run workflow 6 (Promote to Basic Memory) to attach friction entries." - Deduplicate by entry title before appending — if the entry title already appears in the friction section, skip it.
- See
references/basic-memory-friction-format.mdforedit_notegotchas.
- Note exists, has
- Prune pass. For entries in the Basic Memory note's
## Upstream Frictionsection that are annotated with_(Resolved ...)_, offer to move them to the### Resolvedsubsection. The user confirms each. This is the only path that moves entries to Resolved — workflow 3 (Resolve) only annotates. - Report. Summarize what was promoted, pruned, skipped, and flagged for
enrichment. Suggest verifying notes with
build_context("memory://npm/<package>").
See references/basic-memory-friction-format.md for the target section structure,
generalization transform rules, and edit_note gotchas.
Division of labor: This workflow owns the ## Upstream Friction section of
entity notes in Basic Memory. The retrospective skill's step 7 owns
engineering/* notes (patterns, conventions, lessons). synergy-tracker
workflow 5 (Promote to Basic Memory) owns ## Cross-Project Synergy in sibling project entity notes. These
three sections never overlap — upstream friction is package-specific, synergy
entries are cross-project, learnings are domain-specific. For upstream friction
about specific packages or tools, use this workflow, not the retrospective.
7. Sync from Basic Memory
Discover friction already known in Basic Memory for packages and tools this project depends on, but not yet tracked in local UPSTREAM files. This is the reverse of workflow 6 (Promote to Basic Memory) — it pulls cross-project knowledge into the current project. If Basic Memory MCP tools are not available, report that sync is unavailable and suggest checking Basic Memory manually.
Steps:
- Identify project dependencies. Read
package.json(for npm deps and workspace entries) and.claude/vendor-registry.json(for vendor packages). Build a list of packages and tools to check. - Query Basic Memory. For each dependency, call
mcp__basic-memory__search_noteswith the package name. Filter results to notes that contain an## Upstream Frictionsection with active (non-resolved) entries. - Cross-reference with local UPSTREAM files. For each Basic Memory friction
entry found, check whether the project already has a matching entry in a
local
UPSTREAM-*.mdfile. - Surface unknown friction and opportunities. Present entries found in
Basic Memory but not tracked locally: "Basic Memory has known friction for
<package>not tracked in this project: [entry title — summary]. Want to add it to your UPSTREAM file?" Also surface### Upstream Opportunitiesentries: "Basic Memory shows a known contribution opportunity for<package>: [title — merge readiness]. Another project built a solution that could be relevant here." - Flag missing notes. For packages that have UPSTREAM entries locally but
no Basic Memory note, suggest
/package-intel <package>or/tool-intel <tool>for enrichment — this enables future promotion via workflow 6 (Promote to Basic Memory). - User decides. For each surfaced entry: add to local UPSTREAM file (via workflow 1 (Log a new entry)'s logging steps), skip, or dismiss. The user stays in control.
This workflow is pull-based, not automatic. Invoke it when starting a new sprint, onboarding to a project, or when you want cross-project awareness of known friction patterns.
Guidelines
- File naming convention. Use
UPSTREAM-<package-name>.mdwith slashes replaced by--. Scoped packages drop the@prefix:@voxpelli/typed-utilsbecomesUPSTREAM-voxpelli--typed-utils.md,umzeptionstaysUPSTREAM-umzeption.md. For non-npm tools, prefix with the tool type:UPSTREAM-brew--ripgrep.md,UPSTREAM-cask--docker.md,UPSTREAM-action--actions--checkout.md,UPSTREAM-docker--node.md,UPSTREAM-vscode--dbaeumer.vscode-eslint.md. - Infer from context. When the user asks to log an issue, look at what just happened in the session. Extract the relevant details — the package involved, the nature of the problem, the workaround used — rather than asking the user to repeat themselves.
- Consumer perspective. Write entries from the consuming app's point of view. Focus on impact: "Can't type-check session objects in route handlers" rather than "Missing type export in index.d.ts".
- Package identification. When unsure which package an issue belongs to,
check package documentation or README, or trace the code that triggered the
friction back to its source. For non-vendor packages, check
package.jsondependencies. - Cross-vendor awareness. When logging an entry, consider whether it's really a cross-vendor inconsistency. If the project uses multiple vendor packages that share an API surface, file the entry against the package that needs to change.
- Keep files lean. Delete resolved entries — they're preserved in git history. No duplicate entries, no stale placeholders mixed with real entries. For non-vendor files, delete the file itself when all entries are resolved.
- Basic Memory integration. Workflows 1 and 3 check and annotate Basic Memory entries opportunistically when MCP tools are available. Workflows 6 and 7 are dedicated Basic Memory operations — they require the MCP tools to function and will report unavailability if the tools are missing.
- Project tempo classification. Some workflows adjust behavior based on
how active the project is. Measure with
git rev-list --count --since="90 days ago" HEAD 2>/dev/null: dormant (0–4 commits), moderate (5–14), active (15+). Dormant and moderate repos get earlier promotion nudges at workflow 1 (Log) time because their normal sprint cadence is too slow to surface entries cross-project via Basic Memory. See step 6a in workflow 1 (Log) for the full decision matrix. - Scope boundary with synergy-tracker. Cross-project pattern observations
(shared approaches, divergences, extraction candidates between sibling
projects) belong in
/synergy-tracker, not here. This skill tracks friction, bugs, and contribution opportunities in upstream packages and tools.