| name | roadmap-clips |
| description | Use when the operator wants a cross-source roadmap from the luna vault โ aggregates actionable items across daily-note action items, the clipper pipeline backlog (_deferred.md), synthesis proposals, promotion candidates, and the component inventory, clusters them into sequenced themes (effort/impact + code vs vault-only target), dedups candidate tickets against the operator's configured Jira projects, and writes a 60-Maps/ roadmap note. Proposals only โ never auto-files tickets or restructures the vault. Triggers on /roadmap-clips at the user prompt OR programmatic Skill-tool dispatch. Idempotent per day. LUNA-59. |
roadmap-clips โ cross-source roadmap synthesis (LUNA-59)
You turn the luna vault's scattered actionable signal into ONE sequenced
roadmap note in 60-Maps/. You propose โ you never auto-file Jira tickets
and never restructure the vault (same contract as /synthesize-clips).
Deterministic collection lives in tools/roadmap-aggregate.mjs (read-only,
no network). You do the judgement work: cluster, sequence, map to tools, dedup
candidate tickets against open Jira. HIMMEL-128: invoke the tool and the
Jira CLI with the Bash tool only โ no headless / print-mode claude invocations.
Inputs
$ARGUMENTS (all optional): [--vault <path>] [--dry-run].
--vault <path> โ luna vault root. Default $HOME/Documents/luna.
--dry-run โ do everything EXCEPT the final write; print the roadmap to
stdout instead.
Steps
1. Aggregate (deterministic)
Run the aggregator and capture its JSON inventory:
node <plugin>/tools/roadmap-aggregate.mjs [--vault "$VAULT"]
<plugin> = marketplace/plugins/obsidian-triage. The JSON is
{vault, counts, total, items:[{source_type, text, origin, category}]} with
source_type โ action-item | deferred | synthesis-proposal | promotion | component. If total is 0, print roadmap-clips: no actionable items found โ nothing to map and exit 0.
2. Cluster into themes (judgement)
Group the items into 3โ8 coherent themes (e.g. "vault enrichment depth",
"pipeline automation", "source-trust hygiene"). A theme spans source types โ
a deferred github ref, a synthesis-proposal, and an action-item can all
belong to the same theme. Note the supporting item count + origins per theme.
Skip pure noise (e.g. a bare fan-out URL with no thematic signal) but log how
many items you dropped so coverage is honest.
3. Sequence + map to tools (judgement)
Order themes by a rough effort ร impact read (cheap-high-impact first).
For each theme, annotate the target it would land in: code (harness /
plugin / tooling work in a tracked repo) or vault-only (a note/MOC, no
code). These are hints, not commitments. Don't assume any particular repo โ
which repo code maps to is the operator's call.
4. Dedup candidate tickets against open Jira (skip when no project configured)
Dedup against the operator's tracked Jira project(s) โ never a hardcoded
project. The tracked keys are the keys of projects in the jira metadata
cache that /jira-init writes (not a secret โ project keys + issue types):
~/.cache/himmel-cli/jira/metadata.json (POSIX) /
%LOCALAPPDATA%/himmel-cli/jira/metadata.json (Windows).
If the cache is missing or has no projects, SKIP this step: emit no Jira
candidate list and mark every candidate (new) โ i.e. vault-only proposals
(a user who doesn't track this work in Jira gets no spurious ticket
suggestions). Otherwise, for each tracked project KEY, fetch open issues (one
literal command per project):
node scripts/jira/dist/index.js list --project <KEY> --status "To Do,In Progress,Backlog" --limit 50
For each theme you'd propose as a ticket, compare its title against the open
summaries across all tracked projects. If an open issue clearly already covers
it, mark the candidate already-tracked: <KEY> and EXCLUDE it from the
"propose to file" list. Only genuinely-new work reaches the candidate list.
Do NOT create tickets โ that is the operator's call (and an external write
the auto-mode classifier gates).
5. Write the roadmap note (skip entirely under --dry-run โ print instead)
Deterministic path 60-Maps/<TODAY>-roadmap.md (TODAY=$(date +%Y-%m-%d)).
If it already exists, rewrite it in place and add supersedes: listing the
prior content's generated_at (idempotent per day). Shape:
---
type: roadmap
generated_at: <ISO>
generated_by: /roadmap-clips
source_counts: { deferred: N, synthesis-proposal: M, ... } # = the aggregator's `counts`
---
# Roadmap โ <TODAY>
> Auto-generated by `/roadmap-clips` from the luna vault. Proposals only โ
> nothing here is filed or restructured automatically.
## Themes (sequenced: cheap-high-impact first)
### 1. <theme> โ effort:<lo|med|hi> impact:<lo|med|hi> โ <target: code|vault-only>
<1โ2 line synthesis>. Supporting items (<count>): [[<origin>]], โฆ
## Candidate tickets (deduped vs open Jira โ NOT filed; omitted when no Jira project is configured)
- [ ] <title> โ <target> (new)
- ~~<title>~~ already-tracked: <KEY>
## Sources scanned
<counts table from the aggregator JSON>
6. Report
One summary line: roadmap-clips: <T> themes from <N> items (<S> sources); <C> candidate tickets (<D> deduped vs open Jira). Wrote 60-Maps/<TODAY>-roadmap.md
(or (dry-run, nothing written)).
Scope (MVP)
- Proposals only โ no Jira creation, no vault restructuring.
- Dedup is title-vs-summary judgement, not a guaranteed match; when unsure,
keep the candidate and annotate
verify-not-dup.
- Read-only aggregation; the only write is the single 60-Maps roadmap note.