@alecsibilia/luca 13.0.0-alpha.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +201 -0
- package/README.md +47 -0
- package/bin/luca.js +3 -0
- package/dist/chunks/branch.mjs +47 -0
- package/dist/chunks/bun-runtime.mjs +46 -0
- package/dist/chunks/checks.mjs +53 -0
- package/dist/chunks/claim-verify.mjs +465 -0
- package/dist/chunks/classify.mjs +105 -0
- package/dist/chunks/confidence.mjs +199 -0
- package/dist/chunks/doctor.mjs +158 -0
- package/dist/chunks/hook.mjs +696 -0
- package/dist/chunks/init.mjs +715 -0
- package/dist/chunks/muninndb-health.mjs +66 -0
- package/dist/chunks/phase.mjs +38 -0
- package/dist/chunks/pr-review.mjs +122 -0
- package/dist/chunks/preferences.mjs +61 -0
- package/dist/chunks/repair.mjs +111 -0
- package/dist/chunks/repo.mjs +58 -0
- package/dist/chunks/retro.mjs +86 -0
- package/dist/chunks/roadmap.mjs +58 -0
- package/dist/chunks/rules.mjs +527 -0
- package/dist/chunks/stale-mcp-server.mjs +90 -0
- package/dist/chunks/state.mjs +57 -0
- package/dist/chunks/stray-local-install.mjs +200 -0
- package/dist/chunks/telemetry.mjs +165 -0
- package/dist/chunks/todo.mjs +151 -0
- package/dist/chunks/vault-init.mjs +300 -0
- package/dist/chunks/verification.mjs +95 -0
- package/dist/chunks/version.mjs +70 -0
- package/dist/chunks/workflow.mjs +47 -0
- package/dist/claude/.claude/agents/architect.md +410 -0
- package/dist/claude/.claude/agents/build.md +111 -0
- package/dist/claude/.claude/agents/discuss.md +93 -0
- package/dist/claude/.claude/agents/discussion.md +149 -0
- package/dist/claude/.claude/agents/execute.md +416 -0
- package/dist/claude/.claude/agents/executor.md +161 -0
- package/dist/claude/.claude/agents/fast.md +84 -0
- package/dist/claude/.claude/agents/finalize.md +484 -0
- package/dist/claude/.claude/agents/learner.md +160 -0
- package/dist/claude/.claude/agents/plan-reviewer.md +129 -0
- package/dist/claude/.claude/agents/plan.md +96 -0
- package/dist/claude/.claude/agents/research.md +327 -0
- package/dist/claude/.claude/agents/researcher.md +78 -0
- package/dist/claude/.claude/agents/review.md +283 -0
- package/dist/claude/.claude/agents/reviewer.md +163 -0
- package/dist/claude/.claude/agents/shadow-scanner.md +257 -0
- package/dist/claude/.claude/agents/triage.md +230 -0
- package/dist/claude/.claude/agents/verifier.md +131 -0
- package/dist/claude/.claude/commands/bug-diagnose.md +12 -0
- package/dist/claude/.claude/commands/gh-issue-triage.md +14 -0
- package/dist/claude/.claude/commands/gh-pr-address.md +235 -0
- package/dist/claude/.claude/commands/gh-prepare.md +12 -0
- package/dist/claude/.claude/commands/grill-me.md +12 -0
- package/dist/claude/.claude/commands/lu-review.md +51 -0
- package/dist/claude/.claude/commands/lu.md +75 -0
- package/dist/claude/.claude/commands/luca-init.md +14 -0
- package/dist/claude/.claude/commands/luca-telemetry-report.md +12 -0
- package/dist/claude/.claude/commands/memory-audit.md +12 -0
- package/dist/claude/.claude/commands/milestone-new.md +122 -0
- package/dist/claude/.claude/commands/phase-discuss.md +45 -0
- package/dist/claude/.claude/commands/phase-execute.md +39 -0
- package/dist/claude/.claude/commands/phase-plan.md +53 -0
- package/dist/claude/.claude/commands/repo-cleanup.md +80 -0
- package/dist/claude/.claude/commands/todo-add.md +28 -0
- package/dist/claude/.claude/commands/todo-check.md +36 -0
- package/dist/claude/.claude/hooks/context-refresher.ts +285 -0
- package/dist/claude/.claude/hooks/continuation-messages.ts +215 -0
- package/dist/claude/.claude/hooks/pipeline-guard.ts +182 -0
- package/dist/claude/.claude/settings.json +41 -0
- package/dist/claude/skills/arch-audit/SKILL.md +161 -0
- package/dist/claude/skills/autopilot/SKILL.md +1299 -0
- package/dist/claude/skills/bug-diagnose/SKILL.md +102 -0
- package/dist/claude/skills/choose/SKILL.md +124 -0
- package/dist/claude/skills/gh-issue-triage/SKILL.md +97 -0
- package/dist/claude/skills/gh-pr-address/SKILL.md +235 -0
- package/dist/claude/skills/gh-prepare/SKILL.md +209 -0
- package/dist/claude/skills/grill-me/SKILL.md +46 -0
- package/dist/claude/skills/lu/SKILL.md +112 -0
- package/dist/claude/skills/lu-review/SKILL.md +51 -0
- package/dist/claude/skills/luca-init/SKILL.md +91 -0
- package/dist/claude/skills/luca-telemetry-report/SKILL.md +145 -0
- package/dist/claude/skills/luca-write-surface/SKILL.md +213 -0
- package/dist/claude/skills/memory-audit/SKILL.md +217 -0
- package/dist/claude/skills/milestone-audit/SKILL.md +545 -0
- package/dist/claude/skills/milestone-complete/SKILL.md +168 -0
- package/dist/claude/skills/milestone-gaps/SKILL.md +60 -0
- package/dist/claude/skills/milestone-new/SKILL.md +125 -0
- package/dist/claude/skills/note/SKILL.md +162 -0
- package/dist/claude/skills/phase-add/SKILL.md +91 -0
- package/dist/claude/skills/phase-assumptions/SKILL.md +92 -0
- package/dist/claude/skills/phase-discuss/SKILL.md +165 -0
- package/dist/claude/skills/phase-execute/SKILL.md +1786 -0
- package/dist/claude/skills/phase-insert/SKILL.md +100 -0
- package/dist/claude/skills/phase-plan/SKILL.md +461 -0
- package/dist/claude/skills/phase-remove/SKILL.md +113 -0
- package/dist/claude/skills/phase-research/SKILL.md +80 -0
- package/dist/claude/skills/post-init-tour/SKILL.md +58 -0
- package/dist/claude/skills/progress/SKILL.md +271 -0
- package/dist/claude/skills/project-new/SKILL.md +609 -0
- package/dist/claude/skills/quick/SKILL.md +256 -0
- package/dist/claude/skills/rename-audit/SKILL.md +52 -0
- package/dist/claude/skills/repo-audit/SKILL.md +88 -0
- package/dist/claude/skills/repo-cleanup/SKILL.md +80 -0
- package/dist/claude/skills/seed-memory/SKILL.md +235 -0
- package/dist/claude/skills/session-pause/SKILL.md +126 -0
- package/dist/claude/skills/session-plan/SKILL.md +112 -0
- package/dist/claude/skills/session-resume/SKILL.md +75 -0
- package/dist/claude/skills/todo-add/SKILL.md +85 -0
- package/dist/claude/skills/todo-check/SKILL.md +77 -0
- package/dist/claude/skills/workflow-save/SKILL.md +277 -0
- package/dist/index.d.mts +33 -0
- package/dist/index.d.ts +33 -0
- package/dist/index.mjs +69 -0
- package/dist/shared/luca.B3Mimc0P.mjs +52 -0
- package/dist/shared/luca.B3saVjJm.mjs +163 -0
- package/dist/shared/luca.BYdjkfnz.mjs +217 -0
- package/dist/shared/luca.BmhNkYe2.mjs +56 -0
- package/dist/shared/luca.C4gMUoBd.mjs +358 -0
- package/dist/shared/luca.CQ3g1xrD.mjs +19 -0
- package/dist/shared/luca.CRmaAfXR.mjs +713 -0
- package/dist/shared/luca.CrXzXueR.mjs +57 -0
- package/dist/shared/luca.DTomPq7I.mjs +91 -0
- package/dist/shared/luca.DjDTeDCi.mjs +1904 -0
- package/dist/shared/luca.HZxBTBgD.mjs +201 -0
- package/dist/shared/luca.TSMg1t7I.mjs +10 -0
- package/dist/shared/luca.dM-MKlNE.mjs +25 -0
- package/dist/shared/luca.naWEcQ4B.mjs +7 -0
- package/package.json +76 -0
|
@@ -0,0 +1,209 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: gh-prepare
|
|
3
|
+
description: "Ship committed work: ensure a changeset, push the feature branch, open a draft PR. Works standalone (outside the Luca pipeline) or within it. Use when user says \"prepare\", \"ship this\", \"open a PR\", \"push and PR\", or invokes /gh-prepare."
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# GH Prepare
|
|
7
|
+
|
|
8
|
+
Ship committed work to GitHub. Handles the mechanical steps between "code is done" and "PR is open": branch hygiene, changeset, push, and PR creation. No issue creation — that's external ideation handled by `gh-issue-triage`.
|
|
9
|
+
|
|
10
|
+
## Process
|
|
11
|
+
|
|
12
|
+
### 1. Detect context
|
|
13
|
+
|
|
14
|
+
```bash
|
|
15
|
+
git remote -v # confirm GitHub remote exists
|
|
16
|
+
git branch --show-current # current branch
|
|
17
|
+
git rev-parse --abbrev-ref origin/HEAD 2>/dev/null || echo main # default branch
|
|
18
|
+
git status --porcelain # dirty tree check
|
|
19
|
+
git log --oneline origin/<defaultBranch>..HEAD 2>/dev/null # commits ahead of default branch
|
|
20
|
+
```
|
|
21
|
+
|
|
22
|
+
Gather:
|
|
23
|
+
- `currentBranch` — the branch we're on
|
|
24
|
+
- `defaultBranch` — usually `main`
|
|
25
|
+
- `hasDirtyTree` — uncommitted changes exist
|
|
26
|
+
- `commitsAheadOfDefault` — commits ahead of `origin/<defaultBranch>`
|
|
27
|
+
- `hasUpstream` — whether the current branch has a tracking upstream (`git rev-parse --abbrev-ref @{u}`)
|
|
28
|
+
- `hasRemote` — GitHub remote exists
|
|
29
|
+
|
|
30
|
+
If no GitHub remote is detected, stop and tell the user.
|
|
31
|
+
|
|
32
|
+
If the working tree is dirty, warn: "You have uncommitted changes. Commit or stash them first." Do not proceed with a dirty tree — changeset and PR diffs will be wrong.
|
|
33
|
+
|
|
34
|
+
If `hasUpstream` is true and there are no unpushed commits relative to the upstream (`@{u}..HEAD` is empty) AND the branch is already pushed, stop: "Nothing to ship — branch is up to date with its upstream."
|
|
35
|
+
|
|
36
|
+
If on the default branch and `commitsAheadOfDefault` is empty (HEAD matches `origin/<defaultBranch>`), stop: "Nothing to ship — HEAD is up to date with origin/<defaultBranch>."
|
|
37
|
+
|
|
38
|
+
### 2. Branch hygiene
|
|
39
|
+
|
|
40
|
+
**If on `main` or `defaultBranch`:**
|
|
41
|
+
|
|
42
|
+
The commits shouldn't have been made directly to main. Create a feature branch and move the commits onto it:
|
|
43
|
+
|
|
44
|
+
```bash
|
|
45
|
+
# Determine branch name from commit messages
|
|
46
|
+
# Parse type from conventional commit prefix (feat, fix, refactor, chore)
|
|
47
|
+
# Slugify the first commit's subject for the branch name
|
|
48
|
+
git checkout -b <type>/<slug>
|
|
49
|
+
# The commits are now on the new branch; move local defaultBranch back to origin
|
|
50
|
+
git branch -f <defaultBranch> origin/<defaultBranch>
|
|
51
|
+
# This only rewrites the local branch ref; do not force-push
|
|
52
|
+
```
|
|
53
|
+
|
|
54
|
+
Check whether the branch name already exists on the remote:
|
|
55
|
+
```bash
|
|
56
|
+
git ls-remote --heads origin <branch-name>
|
|
57
|
+
```
|
|
58
|
+
If it exists, warn and ask the user whether to reuse it or pick a different name.
|
|
59
|
+
|
|
60
|
+
**If already on a feature branch:**
|
|
61
|
+
|
|
62
|
+
Use the current branch as-is. No action needed.
|
|
63
|
+
|
|
64
|
+
### 3. Consult preferences
|
|
65
|
+
|
|
66
|
+
**At skill start**, read project preferences once and reuse the result:
|
|
67
|
+
|
|
68
|
+
```
|
|
69
|
+
luca preferences read
|
|
70
|
+
```
|
|
71
|
+
|
|
72
|
+
This prints the project's `ProjectPreferences` object (`.luca/config.json#preferences`, with `ProjectPreferencesSchema` defaults applied to unset sections). Destructure `{ release, pr, tracker, commits, branching }` and reuse them throughout this skill.
|
|
73
|
+
|
|
74
|
+
### 4. Changeset (if applicable)
|
|
75
|
+
|
|
76
|
+
Check whether the repo uses changesets (`release.tool === 'changesets'` AND `.changeset/config.json` exists):
|
|
77
|
+
```bash
|
|
78
|
+
test -f .changeset/config.json
|
|
79
|
+
```
|
|
80
|
+
|
|
81
|
+
If yes:
|
|
82
|
+
1. Check whether a changeset already exists for this work:
|
|
83
|
+
```bash
|
|
84
|
+
find .changeset -maxdepth 1 -type f -name '*.md' ! -name 'README.md'
|
|
85
|
+
```
|
|
86
|
+
2. **Before writing a new changeset**, recall MuninnDB for changeset-authoring learnings (frontmatter conventions, package-name canonicalisation, per-package release-note patterns) — supplements the structured `release` preferences with historical pitfalls:
|
|
87
|
+
|
|
88
|
+
```
|
|
89
|
+
mcp__muninn__muninn_recall({
|
|
90
|
+
vault: "<repo_vault>",
|
|
91
|
+
context: ["changeset format", "release-note pitfalls"],
|
|
92
|
+
mode: "semantic",
|
|
93
|
+
limit: 5
|
|
94
|
+
})
|
|
95
|
+
```
|
|
96
|
+
|
|
97
|
+
Resolve `<repo_vault>` from `.luca/config.json` → `muninn.vault`, falling back to `"default"`. Apply directly relevant findings. If MuninnDB is unreachable, log and continue — never block.
|
|
98
|
+
3. If no changeset exists, create one:
|
|
99
|
+
- Determine the bump level from `release.versionBump[<commit-type>]`. The commit type comes from the branch prefix or the dominant commit type.
|
|
100
|
+
- Read package names from `.changeset/config.json` `"fixed"` groups or workspace `package.json` files
|
|
101
|
+
- Write `.changeset/<slug>.md` with the resolved bump level and summary
|
|
102
|
+
- `git add .changeset/<slug>.md && git commit -m "chore: add changeset"`
|
|
103
|
+
4. If a changeset already exists, verify it looks correct (right packages, right bump level). Don't duplicate.
|
|
104
|
+
|
|
105
|
+
Skip if `--no-changeset` is provided or if no `.changeset/config.json` exists.
|
|
106
|
+
|
|
107
|
+
### 5. Push branch
|
|
108
|
+
|
|
109
|
+
```bash
|
|
110
|
+
git push -u origin <branch-name>
|
|
111
|
+
```
|
|
112
|
+
|
|
113
|
+
If the push fails (e.g. the branch already exists with divergent history), report the error and stop. Do not force-push.
|
|
114
|
+
|
|
115
|
+
### 6. Discover the linked issue
|
|
116
|
+
|
|
117
|
+
Check whether this work originated from a triaged GitHub issue:
|
|
118
|
+
|
|
119
|
+
1. **From the todo backlog**: run `luca todo list`, execute the printed `mcp__muninn__muninn_recall` instruction, and look for a todo whose work matches the current branch. If that todo has `source: "gh-issue-#<N>"`, that's the linked issue.
|
|
120
|
+
2. **From MuninnDB**: recall recent `gh-prepare` memories or pipeline state that reference an issue number for this branch.
|
|
121
|
+
3. **From the branch name**: if the branch is named `feat/42-something`, extract `#42` as a candidate and verify it exists: `gh issue view 42 --json state`.
|
|
122
|
+
4. **From commit messages**: scan for `#N` references.
|
|
123
|
+
|
|
124
|
+
If an issue is found, build the issue-link line from `tracker.linkFormat` (e.g. `Closes #{issue}` → `Closes #42`). If no issue is found, that's fine — not all work originates from an issue. Omit the line.
|
|
125
|
+
|
|
126
|
+
### 7. Create the draft PR
|
|
127
|
+
|
|
128
|
+
Render the PR title from `pr.titleTemplate ?? pr.titleFormat`. Substitute the project's tokens (`{type}`, `{scope}`, `{version}`, `{issue}`, `{description}`) with values derived from the branch and commits. If `pr.forbidden[]` is set, reject any title matching one of those patterns.
|
|
129
|
+
|
|
130
|
+
The `--draft` flag is governed by `pr.draftByDefault`:
|
|
131
|
+
|
|
132
|
+
```bash
|
|
133
|
+
DRAFT_FLAG=""
|
|
134
|
+
if [ "<pr.draftByDefault>" = "true" ]; then DRAFT_FLAG="--draft"; fi
|
|
135
|
+
gh pr create $DRAFT_FLAG \
|
|
136
|
+
--title "<rendered title>" \
|
|
137
|
+
--body "<body>"
|
|
138
|
+
```
|
|
139
|
+
|
|
140
|
+
PR body template (rendered from `pr.bodyTemplate` when present; default template below):
|
|
141
|
+
|
|
142
|
+
```markdown
|
|
143
|
+
<tracker.linkFormat-rendered line, if a linked issue was found>
|
|
144
|
+
|
|
145
|
+
## What
|
|
146
|
+
|
|
147
|
+
<summary derived from commit messages — what changed>
|
|
148
|
+
|
|
149
|
+
## Why
|
|
150
|
+
|
|
151
|
+
<problem being solved, derived from commit messages and branch context>
|
|
152
|
+
|
|
153
|
+
## How
|
|
154
|
+
|
|
155
|
+
<brief technical approach, derived from diff stats>
|
|
156
|
+
|
|
157
|
+
## Test Plan
|
|
158
|
+
|
|
159
|
+
<how to verify — inferred from test files changed, or "Manual verification" if none>
|
|
160
|
+
```
|
|
161
|
+
|
|
162
|
+
Derive `type` from the branch prefix or dominant commit type (validated against `commits.types ?? branching.types`). Derive `scope` from the primary package or area changed. Apply scope-allowlist validation only when `commits.scopes.length > 0` — an empty array means "no allowlist enforced" (any scope permitted), not "no scopes allowed".
|
|
163
|
+
|
|
164
|
+
### 8. Store in MuninnDB
|
|
165
|
+
|
|
166
|
+
Remember the result for later recall (by the pipeline, other sessions, or dedup). The `gh-prepare` concept is project-scoped — it routes to the **repo** vault:
|
|
167
|
+
|
|
168
|
+
```
|
|
169
|
+
mcp__muninn__muninn_remember({
|
|
170
|
+
vault: "<repo_vault>",
|
|
171
|
+
concept: "gh-prepare",
|
|
172
|
+
content: "Shipped: branch <name>, PR #<M> (<url>). <Closes #N if linked.> Work: <description>",
|
|
173
|
+
tags: ["gh-prepare", "branch", "pr"],
|
|
174
|
+
entities: [
|
|
175
|
+
{ name: "pr-<M>", type: "github-pr" },
|
|
176
|
+
{ name: "<branch-name>", type: "git-branch" }
|
|
177
|
+
]
|
|
178
|
+
})
|
|
179
|
+
```
|
|
180
|
+
|
|
181
|
+
### 9. Pipeline integration
|
|
182
|
+
|
|
183
|
+
Run `luca state read`. If a Luca pipeline is active (`pipelineStep` is not `idle`/`complete`), later pipeline steps discover this PR by recalling the `gh-prepare` memory from Step 8 — no separate workflow-state write is needed. If no pipeline is active, skip — the skill works standalone.
|
|
184
|
+
|
|
185
|
+
### 10. Report
|
|
186
|
+
|
|
187
|
+
Print a clean summary:
|
|
188
|
+
|
|
189
|
+
```
|
|
190
|
+
Branch: feat/42-add-webhook-support (pushed)
|
|
191
|
+
PR: #43 (draft) — https://github.com/<owner>/<repo>/pull/43
|
|
192
|
+
Issue: Closes #42 on merge
|
|
193
|
+
```
|
|
194
|
+
|
|
195
|
+
Or, if no linked issue:
|
|
196
|
+
|
|
197
|
+
```
|
|
198
|
+
Branch: feat/add-webhook-support (pushed)
|
|
199
|
+
PR: #43 (draft) — https://github.com/<owner>/<repo>/pull/43
|
|
200
|
+
```
|
|
201
|
+
|
|
202
|
+
## Flags
|
|
203
|
+
|
|
204
|
+
| Flag | Effect |
|
|
205
|
+
|------|--------|
|
|
206
|
+
| `--no-changeset` | Skip changeset creation even if `.changeset/config.json` exists |
|
|
207
|
+
| `--no-pr` | Push the branch only, skip PR creation |
|
|
208
|
+
| `--title="..."` | Override the PR title |
|
|
209
|
+
| `--issue=<N>` | Explicitly link to issue #N instead of auto-discovering |
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: grill-me
|
|
3
|
+
description: "Interview the user relentlessly about a plan or design until reaching shared understanding. Walks each branch of the decision tree, resolving dependencies one-by-one. Updates docs/context.md and offers ADRs when decisions crystallize. Use when user says \"grill me\", \"stress-test this plan\", \"poke holes\", \"challenge my design\", or invokes /grill-me."
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# Grill Me
|
|
7
|
+
|
|
8
|
+
Interview me relentlessly about every aspect of this plan until we reach a shared understanding. Walk down each branch of the design tree, resolving dependencies between decisions one-by-one. For each question, provide your recommended answer.
|
|
9
|
+
|
|
10
|
+
Ask the questions **one at a time**, waiting for feedback before continuing.
|
|
11
|
+
|
|
12
|
+
If a question can be answered by exploring the codebase, explore the codebase instead of asking.
|
|
13
|
+
|
|
14
|
+
## During the Session
|
|
15
|
+
|
|
16
|
+
### Challenge against the glossary
|
|
17
|
+
|
|
18
|
+
If a `docs/context.md` exists, read it first — it is the project's domain glossary. (Check the repo root for a legacy `context.md` as a fallback.) When the user uses a term that conflicts with the existing language, call it out immediately: "Your glossary defines 'X' as Y, but you seem to mean Z — which is it?"
|
|
19
|
+
|
|
20
|
+
### Sharpen fuzzy language
|
|
21
|
+
|
|
22
|
+
When the user uses vague or overloaded terms, propose a precise canonical term. "You're saying 'account' — do you mean the Customer or the User? Those are different things."
|
|
23
|
+
|
|
24
|
+
### Discuss concrete scenarios
|
|
25
|
+
|
|
26
|
+
When domain relationships are being discussed, stress-test them with specific scenarios. Invent scenarios that probe edge cases and force the user to be precise about the boundaries between concepts.
|
|
27
|
+
|
|
28
|
+
### Cross-reference with code
|
|
29
|
+
|
|
30
|
+
When the user states how something works, check whether the code agrees. If you find a contradiction, surface it: "Your code does X, but you just said Y — which is right?"
|
|
31
|
+
|
|
32
|
+
### Update the glossary inline
|
|
33
|
+
|
|
34
|
+
When a term is resolved, update `docs/context.md` right there — don't batch these up. Create the file lazily at `docs/context.md` if it doesn't exist. The glossary is a plain project doc, not a `.luca/` pipeline artifact — `docs/` keeps it out of the strict `.luca/` contract and out of repo-root markdown debris.
|
|
35
|
+
|
|
36
|
+
Don't couple the glossary to implementation details. Only include terms meaningful to domain experts.
|
|
37
|
+
|
|
38
|
+
### Offer ADRs sparingly
|
|
39
|
+
|
|
40
|
+
Only offer to create an ADR when **all three** are true:
|
|
41
|
+
|
|
42
|
+
1. **Hard to reverse** — the cost of changing your mind later is meaningful
|
|
43
|
+
2. **Surprising without context** — a future reader will wonder "why did they do it this way?"
|
|
44
|
+
3. **The result of a real trade-off** — there were genuine alternatives and you picked one for specific reasons
|
|
45
|
+
|
|
46
|
+
If any of the three is missing, skip the ADR.
|
|
@@ -0,0 +1,112 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: lu
|
|
3
|
+
description: Unified entry point for all Luca workflows with cognitive pre-flight and complexity routing.
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
<main>
|
|
7
|
+
The single entry point for the Luca pipeline. This SKILL is the long-form companion to the modernized `/lu` slash command — it drives the pipeline loop end-to-end: triage → research → discuss → architect → plan → plan-review → execute → checks → verify → review → learn → milestone.
|
|
8
|
+
|
|
9
|
+
**Arguments:** `<task-description> [--complexity=TRIVIAL|SIMPLE|MODERATE|COMPLEX|CRITICAL] [--force-complex] [--skip-memory] [--skip-branch]`
|
|
10
|
+
|
|
11
|
+
**CRITICAL:** You are the **orchestrator**. You do not write code or planning artifacts directly — you read state, run each step (delegating to its skill or subagent), and advance the pipeline via `luca state advance`.
|
|
12
|
+
|
|
13
|
+
</main>
|
|
14
|
+
|
|
15
|
+
<sub-agent_delegation_requirements>
|
|
16
|
+
This skill uses TWO delegation mechanisms:
|
|
17
|
+
|
|
18
|
+
**Skill tool** — for workflow sub-skills (phase-discuss, phase-plan, phase-execute, etc.)
|
|
19
|
+
|
|
20
|
+
- Invoke: `Skill(skill: "skill-name", args: "...")`
|
|
21
|
+
- Each invoked skill loads its own SKILL.md with full instructions
|
|
22
|
+
- Users see visual skill headers for each step
|
|
23
|
+
|
|
24
|
+
**Task tool** — for specialized subagents (luca-researcher, luca-plan-reviewer, luca-verifier, luca-reviewer, luca-learner)
|
|
25
|
+
|
|
26
|
+
- Invoke: `Task(agent: "agent-name", prompt: "...")`
|
|
27
|
+
- Subagents run inside a fresh sub-context
|
|
28
|
+
|
|
29
|
+
### Model Resolution
|
|
30
|
+
|
|
31
|
+
Models are resolved at runtime via `resolveModelForAgent(agentName, complexity)` from the centralized routing table (`src/complexity/__helpers/model-routing.ts`). The skill does not pick model strings — it spawns the named agent and the routing layer handles tier selection.
|
|
32
|
+
|
|
33
|
+
</sub-agent_delegation_requirements>
|
|
34
|
+
|
|
35
|
+
<workflow>
|
|
36
|
+
Execute these steps in order. Each step is either a Task tool call (for subagents) or a Skill tool call (for sub-skills).
|
|
37
|
+
|
|
38
|
+
### Step 0: Read state
|
|
39
|
+
|
|
40
|
+
Run `luca state read`. Branch on `pipelineStep`:
|
|
41
|
+
|
|
42
|
+
- `idle` or `complete` → fresh start. Go to **Triage**.
|
|
43
|
+
- anything else → the pipeline is mid-flight. Skip triage, go straight to **Pipeline loop** and resume from the current step.
|
|
44
|
+
|
|
45
|
+
If the user passed a request but the pipeline is already mid-flight, surface that to the user and ask whether to resume the current run or finish it first — do NOT silently discard either.
|
|
46
|
+
|
|
47
|
+
### Triage
|
|
48
|
+
|
|
49
|
+
Triage runs once, at the start of a run. It is inline here — there is no separate triage skill.
|
|
50
|
+
|
|
51
|
+
1. **Classify complexity.** Read the request. Pick one of `TRIVIAL | SIMPLE | MODERATE | COMPLEX | CRITICAL` based on file count, scope, and risk. There is no CLI command to persist complexity — record it in your reasoning and pass it to every subagent you spawn (the model-routing table keys off it). If `--complexity=<level>` or `--force-complex` was passed, use that directly.
|
|
52
|
+
2. **Build the roadmap.** Decompose the request into ordered phases. Each phase is one deliverable unit. Stage the phases array in a JSON file, then run `luca roadmap create --file`:
|
|
53
|
+
```
|
|
54
|
+
# /tmp/luca-roadmap.json:
|
|
55
|
+
# [
|
|
56
|
+
# { "name": "<kebab-or-prose name>", "deps": [], "complexity": "<level>" },
|
|
57
|
+
# ...
|
|
58
|
+
# ]
|
|
59
|
+
luca roadmap create --file /tmp/luca-roadmap.json
|
|
60
|
+
```
|
|
61
|
+
For a single-deliverable request, that is a one-phase roadmap. `luca roadmap create` is only legal in `idle`/`triage` — it resets `currentPhase` to 0.
|
|
62
|
+
3. **Advance** `idle → triage → research` via two `luca state advance --to-step <step>` calls.
|
|
63
|
+
|
|
64
|
+
### Pipeline loop
|
|
65
|
+
|
|
66
|
+
Repeat until `pipelineStep` is `complete`:
|
|
67
|
+
|
|
68
|
+
1. Run `luca state read` to get the current `pipelineStep`.
|
|
69
|
+
2. Run the step using the table below.
|
|
70
|
+
3. Advance to the next step with `luca state advance --to-step <step>`. Transitions are validated against the pipeline-transitions table — illegal jumps are rejected.
|
|
71
|
+
|
|
72
|
+
| Step | How to run it |
|
|
73
|
+
|---------------|----------------------------------------------------------------------------|
|
|
74
|
+
| `research` | Spawn `luca-researcher` (Agent tool). Persist its output by writing `research.md` with the `Write` tool to the canonical phase path (get the dir from `luca phase current`). |
|
|
75
|
+
| `discuss` | Invoke `Skill(skill: "phase-discuss")`. |
|
|
76
|
+
| `architect` | Lightweight synthesis: read research + context, confirm the plan-ready brief. Advance to `plan`. |
|
|
77
|
+
| `plan` | Invoke `Skill(skill: "phase-plan")`. |
|
|
78
|
+
| `plan-review` | Spawn `luca-plan-reviewer` (Agent tool). On `NEEDS_REVISION`, loop back to `plan`. |
|
|
79
|
+
| `execute` | Invoke `Skill(skill: "phase-execute")`. |
|
|
80
|
+
| `checks` | Run `luca checks run --file <commands.json>` with the project's typecheck (and tests, if present). On failure, loop back to `execute`. |
|
|
81
|
+
| `verify` | Spawn `luca-verifier` (Agent tool). On `recommendation: fix`, loop back to `checks`; on `escalate`, stop and surface to the user. |
|
|
82
|
+
| `review` | Spawn `luca-reviewer` (Agent tool) — one per perspective, in parallel. |
|
|
83
|
+
| `learn` | Spawn `luca-learner` (Agent tool). Then: more phases remain → advance to `plan` for the next phase; last phase → advance to `milestone`. |
|
|
84
|
+
| `milestone` | Invoke `Skill(skill: "milestone-new")` to close out, or advance to `complete` if no milestone bookkeeping is needed. |
|
|
85
|
+
|
|
86
|
+
### Oversight
|
|
87
|
+
|
|
88
|
+
Read `oversight` from `luca state read`:
|
|
89
|
+
|
|
90
|
+
- `full-auto` — run the whole loop without pausing.
|
|
91
|
+
- `checkpoint` — pause after `plan-review`, `verify`, and `learn` for user confirmation.
|
|
92
|
+
- `human-in-loop` — pause after every step.
|
|
93
|
+
|
|
94
|
+
### What you must NOT do
|
|
95
|
+
|
|
96
|
+
- Do NOT write code directly. Phase artifact files are written with the `Write` tool to their canonical path by a subagent or `/phase-*` skill; structured `.luca/` mutations go through the `luca` CLI. The stage-gate hook blocks any other direct write.
|
|
97
|
+
- Do NOT skip steps. The pipeline-transitions table is the contract; `luca state advance` enforces it. There is no bypass.
|
|
98
|
+
- Do NOT re-triage a mid-flight pipeline. Resume from the current step instead.
|
|
99
|
+
- Do NOT commit. Commits happen only in the finalizing flow, never inside `/lu`.
|
|
100
|
+
|
|
101
|
+
### Other entry points (alternatives to /lu)
|
|
102
|
+
|
|
103
|
+
- New project initialization: `Skill(skill: "project-new", args: "<project description>")`
|
|
104
|
+
- New milestone: `Skill(skill: "milestone-new", args: "<milestone description>")`
|
|
105
|
+
- Quick / ad-hoc task that doesn't need a roadmap: `Skill(skill: "quick", args: "<task-description>")`
|
|
106
|
+
- Progress check: `Skill(skill: "progress")`
|
|
107
|
+
- Session planning: `Skill(skill: "session-plan")`
|
|
108
|
+
- Autonomous execution across multiple phases: `Skill(skill: "autopilot", args: "<flags>")`
|
|
109
|
+
|
|
110
|
+
PR-review and debug workflows are not bundled with the v13 Luca skill set; reach for the user's own `gh-pr-address` / `bug-diagnose` skills (under `~/.claude/skills/`) when present.
|
|
111
|
+
|
|
112
|
+
</workflow>
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: lu-review
|
|
3
|
+
description: Re-enter the Luca pipeline at the review step to audit completed work.
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# /lu-review
|
|
7
|
+
|
|
8
|
+
Run the **review** step against the active phase — a structured multi-perspective audit of executed code. Use this after `/phase-execute` + verification, or to re-audit a phase before closing it.
|
|
9
|
+
|
|
10
|
+
You are orchestration only: read state, run the reviewers, let them persist their audits with the `Write` tool.
|
|
11
|
+
|
|
12
|
+
## Step 0 — Read state
|
|
13
|
+
|
|
14
|
+
Run `luca state read`. The review step has exactly one legal entry: `verify → review`. There is no bypass — `luca state advance` rejects illegal jumps.
|
|
15
|
+
|
|
16
|
+
- `pipelineStep === "verify"` → run `luca state advance --to-step review`, then proceed.
|
|
17
|
+
- `pipelineStep === "review"` → already there, proceed.
|
|
18
|
+
- anything else → STOP. Tell the user the pipeline must reach `verify` before review can run, and point them at `/lu` to drive it there. Do not attempt to force the transition.
|
|
19
|
+
|
|
20
|
+
Run `luca phase current` to get the active slug. If no phase is active, abort.
|
|
21
|
+
|
|
22
|
+
## Run the reviewers
|
|
23
|
+
|
|
24
|
+
Spawn the `luca-reviewer` subagent via the `Agent` tool — once per perspective, in parallel:
|
|
25
|
+
|
|
26
|
+
- `architect` — structural correctness, dependency direction, API surface
|
|
27
|
+
- `dx` — readability, error messages, ergonomics
|
|
28
|
+
- `security` — input validation, injection, secret handling
|
|
29
|
+
- `simplification` — unnecessary complexity, dead code
|
|
30
|
+
- `test-quality` — vacuous mocks, presence-only assertions, coverage-by-existence
|
|
31
|
+
|
|
32
|
+
Pass each reviewer its assigned perspective and the active phase slug. Each reviewer persists its own audit by writing `audits/<reviewer>.md` with the `Write` tool to the canonical phase path (the stage-gate hook only permits that write in the `review` step).
|
|
33
|
+
|
|
34
|
+
Scale the perspective set to complexity: TRIVIAL/SIMPLE may run only `architect` + `security`; MODERATE+ runs the full set.
|
|
35
|
+
|
|
36
|
+
## Aggregate
|
|
37
|
+
|
|
38
|
+
When all reviewers return, summarize for the user:
|
|
39
|
+
|
|
40
|
+
- Total MUST-FIX / SHOULD-FIX / NOTE counts across audits
|
|
41
|
+
- Whether any reviewer returned `REQUEST_CHANGES`
|
|
42
|
+
|
|
43
|
+
If there are MUST-FIX findings, the phase is not ready to advance — direct the user back to `/phase-execute` to address them (the `verify → checks → execute` loop-back path). If all reviewers APPROVE, advance with `luca state advance --to-step learn`.
|
|
44
|
+
|
|
45
|
+
## What you must NOT do
|
|
46
|
+
|
|
47
|
+
- Do NOT force a transition into `review` from a non-`verify` state. Honor the no-bypass policy.
|
|
48
|
+
- Do NOT write audit files yourself — the reviewers write `audits/<reviewer>.md` with the `Write` tool to the canonical path; the hook blocks any other write.
|
|
49
|
+
- Do NOT fix the findings yourself in this skill. Review reports; execute fixes.
|
|
50
|
+
|
|
51
|
+
$ARGUMENTS
|
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: luca-init
|
|
3
|
+
description: |-
|
|
4
|
+
Repo-probing wizard that seeds project preferences into .luca/config.json. Detects branching conventions, commit format, PR title format, release tooling, and issue tracker from the local repo, confirms with the user, then writes the preferences section via the `luca preferences write` CLI.
|
|
5
|
+
|
|
6
|
+
Use when the user says "init luca", "set up preferences", "luca-init", "configure conventions", or invokes /luca-init.
|
|
7
|
+
---
|
|
8
|
+
|
|
9
|
+
# luca-init Skill
|
|
10
|
+
|
|
11
|
+
Seed repo-level project conventions so the Luca pipeline branches, commits, and ships PRs the way this team already does.
|
|
12
|
+
|
|
13
|
+
This skill manages the `preferences` section of `.luca/config.json`. It does not wire hooks or write the project skeleton — that is the `luca init` CLI's job, run earlier.
|
|
14
|
+
|
|
15
|
+
## When to run
|
|
16
|
+
|
|
17
|
+
- The user explicitly invokes `/luca-init` or asks to set up / reset preferences.
|
|
18
|
+
- After `luca init` (CLI) succeeds and the user wants to capture conventions next.
|
|
19
|
+
|
|
20
|
+
## Phase 1 — Probe
|
|
21
|
+
|
|
22
|
+
Read existing repo signal **before** asking any questions. Explore first; ask only for what cannot be inferred.
|
|
23
|
+
|
|
24
|
+
Run each heuristic, failing soft if a signal is unavailable:
|
|
25
|
+
|
|
26
|
+
1. **Branching**
|
|
27
|
+
- `git branch -r --no-color | head -50` → detect prefix patterns (`feat/`, `feature/`, `fix/`, `ENG-*`, `PT-*`, etc.).
|
|
28
|
+
- `git symbolic-ref refs/remotes/origin/HEAD --short 2>/dev/null` → default branch (fallback `main`).
|
|
29
|
+
2. **Commits**
|
|
30
|
+
- `git log --oneline -50` → conventional-commit prefixes (`feat:`, `fix:`, `chore:`, etc.).
|
|
31
|
+
- Recurring scopes (e.g. `feat(api):`) → suggested `commits.scopes`.
|
|
32
|
+
3. **PR title format**
|
|
33
|
+
- `gh pr list --state merged --limit 20 --json title -q '.[].title' 2>/dev/null` (skip on auth failure).
|
|
34
|
+
- Pattern-match against `{type}({scope}): {description}`.
|
|
35
|
+
4. **Release tooling**
|
|
36
|
+
- `.changeset/config.json` exists → `release.tool = "changesets"`.
|
|
37
|
+
- `.releaserc*` / `release.config.*` → `"semantic-release"`.
|
|
38
|
+
- Otherwise `"none"`.
|
|
39
|
+
5. **Tracker**
|
|
40
|
+
- Issue refs in commits (`#123`, `ENG-456`, `PROJ-789`) → infer `github` / `linear` / `jira`.
|
|
41
|
+
- `gh repo view --json owner,name 2>/dev/null` → confirms GitHub.
|
|
42
|
+
|
|
43
|
+
Build a candidate preferences object from the probe results. Leave any field you cannot infer unset — `ProjectPreferencesSchema` fills it with a safe default.
|
|
44
|
+
|
|
45
|
+
The candidate must respect the schema's free-form character allowlist: branch/commit/PR template strings permit letters, digits, spaces/tabs, and `{}/#,.():-` only. No quotes, backticks, or newlines. Regex fields (`branchTypes[].match`) must not contain nested quantifiers. `luca preferences write` rejects violations — surface any rejection to the user rather than working around it.
|
|
46
|
+
|
|
47
|
+
## Phase 2 — Confirm
|
|
48
|
+
|
|
49
|
+
Run `luca state read` and read `oversight`.
|
|
50
|
+
|
|
51
|
+
### Headless path
|
|
52
|
+
|
|
53
|
+
If `oversight === "full-auto"`, skip the question. Proceed directly to Phase 3 with the probed candidate. Log one line summarising the auto-seeded values.
|
|
54
|
+
|
|
55
|
+
### Interactive path
|
|
56
|
+
|
|
57
|
+
Otherwise, show the detected values and ask once with `AskUserQuestion`:
|
|
58
|
+
|
|
59
|
+
- **Approve** — seed these preferences as-is → Phase 3.
|
|
60
|
+
- **Edit a section** — ask which section (branching, commits, pr, release, tracker), collect new values, re-confirm. Up to 2 iterations; if still unresolved, treat as Abort.
|
|
61
|
+
- **Abort** — write nothing, stop. The pipeline proceeds with `ProjectPreferencesSchema` defaults (a `luca preferences read` with no stored preferences returns the defaults).
|
|
62
|
+
|
|
63
|
+
## Phase 3 — Seed
|
|
64
|
+
|
|
65
|
+
Write the approved candidate. Stage the partial preferences object in a JSON file, then run `luca preferences write --file`:
|
|
66
|
+
|
|
67
|
+
```
|
|
68
|
+
# /tmp/luca-preferences.json holds the approved candidate preferences object
|
|
69
|
+
luca preferences write --file /tmp/luca-preferences.json
|
|
70
|
+
```
|
|
71
|
+
|
|
72
|
+
This validates the merged result against `ProjectPreferencesSchema` and atomically rewrites `.luca/config.json`, preserving every other config key (`lucaVersion`, `vault`, `oversight`, …). `.luca/config.json#preferences` is the single source of truth — `luca preferences read` reads it deterministically, so no separate MuninnDB registration is needed.
|
|
73
|
+
|
|
74
|
+
If `luca preferences write` exits non-zero, surface the validation message verbatim. The most common cause is an unsafe free-form value picked up from git history in a cloned repo — re-probe or ask the user for a clean value.
|
|
75
|
+
|
|
76
|
+
## Phase 4 — Confirm to user
|
|
77
|
+
|
|
78
|
+
Print a one-line confirmation:
|
|
79
|
+
|
|
80
|
+
```
|
|
81
|
+
Project preferences seeded — branching=<types>, commits=<convention>, release=<tool>, tracker=<kind>.
|
|
82
|
+
Edit later with /luca-init.
|
|
83
|
+
```
|
|
84
|
+
|
|
85
|
+
## Failure modes
|
|
86
|
+
|
|
87
|
+
| Signal | Action |
|
|
88
|
+
|---|---|
|
|
89
|
+
| `git` unavailable | Use schema defaults for branching/commits; warn the user. |
|
|
90
|
+
| `gh` not authenticated | Skip the PR-title probe; the schema default `{type}({scope}): {description}` applies. |
|
|
91
|
+
| `luca preferences write` rejects the payload | Surface the validation error verbatim; re-probe or ask for a corrected value. Nothing is written on rejection. |
|
|
@@ -0,0 +1,145 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: luca-telemetry-report
|
|
3
|
+
description: |-
|
|
4
|
+
Cross-run aggregator over `.luca/telemetry/*.jsonl`. Reads per-run JSONL telemetry records (phase/wave/step/subagent/recall/review events), aggregates streaming-style, and emits a markdown report inline. Read-only over the telemetry dir; no MuninnDB writes, no state mutation.
|
|
5
|
+
|
|
6
|
+
Use when user says "telemetry report", "aggregate telemetry", "show telemetry summary", "luca-telemetry-report", or invokes `/luca-telemetry-report`.
|
|
7
|
+
|
|
8
|
+
Arguments: `--runs <N>` (default 10), `--since <ISO-date>`, `--vault <name>`.
|
|
9
|
+
---
|
|
10
|
+
|
|
11
|
+
# luca-telemetry-report Skill
|
|
12
|
+
|
|
13
|
+
Aggregate Luca pipeline telemetry across recent runs. Emits a single markdown report covering: run inventory, step durations, subagent costs, recall hit/miss, review-iteration convergence, cross-run trends.
|
|
14
|
+
|
|
15
|
+
## Scope guard — read first
|
|
16
|
+
|
|
17
|
+
This skill is **read-only over the telemetry directory**. It does not mutate workflow state and does not call any MuninnDB write API — it aggregates telemetry already on disk.
|
|
18
|
+
|
|
19
|
+
The following operations are FORBIDDEN inside this skill. Do not perform them under any circumstance:
|
|
20
|
+
|
|
21
|
+
- Any `luca` CLI write/mutation command (`luca state advance`, `luca roadmap create`, `luca workflow reset`, `luca confidence log`, `luca todo add/update`, `luca repo cleanup-apply`, `luca preferences write`, `luca checks run`)
|
|
22
|
+
- Any `Write` to a `.luca/` phase artifact file (research, context, plan, plan-review, summary, wave, verify, audit, learn)
|
|
23
|
+
- `mcp__muninn__muninn_remember`, `mcp__muninn__muninn_remember_batch`
|
|
24
|
+
- `mcp__muninn__muninn_forget`, `mcp__muninn__muninn_evolve`
|
|
25
|
+
- `mcp__muninn__muninn_state`, `mcp__muninn__muninn_consolidate`
|
|
26
|
+
|
|
27
|
+
If a record is malformed, log it in the report's "Failure Modes" section and continue.
|
|
28
|
+
|
|
29
|
+
## TelemetryRecord v:1 contract (canonical)
|
|
30
|
+
|
|
31
|
+
Every JSONL line conforms to the v:1 contract:
|
|
32
|
+
|
|
33
|
+
```
|
|
34
|
+
{ v:1, ts:ISO8601, runId, kind, phase, slug, wave, complexity, oversight, durationMs:number|null, meta:{} }
|
|
35
|
+
```
|
|
36
|
+
|
|
37
|
+
Known `kind` values:
|
|
38
|
+
|
|
39
|
+
- `phase.start` / `phase.end` — outer-loop phase boundaries
|
|
40
|
+
- `wave.start` / `wave.end` — inner-loop wave boundaries (execute step)
|
|
41
|
+
- `mode.start` / `mode.end` — pipeline step transitions
|
|
42
|
+
- `subagent.invoke` / `subagent.complete` — subagent dispatch boundaries
|
|
43
|
+
- `recall.hit` / `recall.miss` — MuninnDB recall outcomes
|
|
44
|
+
- `review.iteration` — review-step emit
|
|
45
|
+
|
|
46
|
+
Treat the union as **open**: the aggregator must tolerate unknown kinds (count them under "Unknown kinds" rather than crash).
|
|
47
|
+
|
|
48
|
+
## Arguments + pre-flight validation
|
|
49
|
+
|
|
50
|
+
| Flag | Type | Default | Validation |
|
|
51
|
+
|---|---|---|---|
|
|
52
|
+
| `--runs N` | integer | 10 | `N >= 1 && N <= 1000` |
|
|
53
|
+
| `--since <ISO>` | string | unset | `^\d{4}-\d{2}-\d{2}` (date-only or full ISO accepted) |
|
|
54
|
+
| `--vault <name>` | string | unset | `^[a-z0-9_-]+$`, max 64 chars |
|
|
55
|
+
|
|
56
|
+
If validation fails, abort with a clear error message — do not silently continue with defaults.
|
|
57
|
+
|
|
58
|
+
## Step 1: Pre-flight + scope resolve
|
|
59
|
+
|
|
60
|
+
1. Parse and validate the arguments above.
|
|
61
|
+
2. Read `.luca/config.json` if present. If `--vault` was supplied, override the config value; otherwise use the `muninn.vault` field, fallback `"default"`.
|
|
62
|
+
3. Resolve the telemetry dir as `.luca/telemetry/`. **`existsSync` guard**: if the dir is absent (no runs yet), short-circuit to Step 7 and emit an empty report citing "no telemetry recorded yet".
|
|
63
|
+
|
|
64
|
+
## Step 2: Enumerate JSONL files
|
|
65
|
+
|
|
66
|
+
The `.luca/` contract stores telemetry as flat per-run files (`.luca/telemetry/<runId>.jsonl`, no subdirectories). Enumerate them with:
|
|
67
|
+
|
|
68
|
+
```bash
|
|
69
|
+
find .luca/telemetry -maxdepth 1 -name '*.jsonl' -print 2>/dev/null
|
|
70
|
+
```
|
|
71
|
+
|
|
72
|
+
Use `find`, NOT a shell glob — it handles an empty dir gracefully. Each file is one run.
|
|
73
|
+
|
|
74
|
+
Sort by file mtime descending. Take the first `--runs N` files. If `--since <ISO>` is supplied, filter further by reading the first non-empty JSONL line and dropping files whose first `ts` is older than the threshold.
|
|
75
|
+
|
|
76
|
+
## Step 3: Streaming aggregation pass
|
|
77
|
+
|
|
78
|
+
For each selected file, stream lines (small files, ≤ a few MB each — a full read is fine). For each line:
|
|
79
|
+
|
|
80
|
+
1. `JSON.parse` defensively. On a parse error: increment `failures.parse++`, continue.
|
|
81
|
+
2. Validate the line has `v:1` and a `kind` string. On a miss: `failures.schema++`, continue.
|
|
82
|
+
3. Dispatch to the per-kind accumulator:
|
|
83
|
+
- `phase.*` / `wave.*`: sum `durationMs` into `byPhase[phase]` / `byWave[wave]` buckets
|
|
84
|
+
- `mode.*`: sum into `byStep[from|to]`
|
|
85
|
+
- `subagent.*`: tally `byRole[role]` with input/output token sums; pair `invoke`/`complete` by `meta.correlationId` for orchestrator-side duration (preferred over a null harness `durationMs`)
|
|
86
|
+
- `recall.*`: tally hit/miss/verifiedCount per `meta.callerMode`
|
|
87
|
+
- `review.iteration`: collect the verdict/mustFixCount/perspectives series
|
|
88
|
+
4. If `durationMs === null` for a `*.end` record, attempt a **ts-gap fallback** — find the matching `*.start` event with the same phase/slug/wave/runId, compute `Date.parse(end.ts) - Date.parse(start.ts)`. Only apply when both `Date.parse` calls return finite non-negative deltas. If the fallback fails, leave `null` and tally under `failures.unknownDuration`.
|
|
89
|
+
|
|
90
|
+
Memory note: aggregators are **per-run scoped** — release per-run accumulators between files. Cross-run totals are written to a separate top-level accumulator.
|
|
91
|
+
|
|
92
|
+
## Step 4: Build the markdown report
|
|
93
|
+
|
|
94
|
+
Render 6 sections:
|
|
95
|
+
|
|
96
|
+
### Run Inventory
|
|
97
|
+
Table: runId | start ts | end ts | complexity | oversight | total durationMs | phases | waves
|
|
98
|
+
|
|
99
|
+
### Step Durations
|
|
100
|
+
Per-step totals across the pipeline (`triage` / `research` / `discuss` / `architect` / `plan` / `plan-review` / `execute` / `checks` / `verify` / `review` / `learn` / `milestone`). Show mean + p50 + p95 across the selected runs. Flag any step where >20% of records have `durationMs:null`.
|
|
101
|
+
|
|
102
|
+
### Subagent Costs
|
|
103
|
+
Per-role breakdown: invocations, input/output token sums, mean tokens/call. List the top 5 most expensive single calls. Flag rows where `success:false` or `outcome` is in `{crashed, killed, timeout, completed_no_usage, completed_partial_parse}` (any non-clean terminal state — only `completed` is fully successful). When grouping, treat `crashed`/`killed`/`timeout` as hard failures and `completed_no_usage`/`completed_partial_parse` as soft failures (the subagent finished but usage telemetry is missing or malformed).
|
|
104
|
+
|
|
105
|
+
### Recall Stats
|
|
106
|
+
Per-mode hit-rate (hit / (hit+miss)). Verified-tier hit-rate (sum(verifiedCount) / sum(resultCount)). Flag modes with a hit-rate < 0.4.
|
|
107
|
+
|
|
108
|
+
### Review Convergence
|
|
109
|
+
Per-run review-iteration count, mustFixCount trajectory, time-to-APPROVED (sum of `review.iteration` durationMs). Flag runs that hit `maxReviewIterations`.
|
|
110
|
+
|
|
111
|
+
### Cross-Run Trends
|
|
112
|
+
For each numeric metric above, compute the trend over the selected runs (oldest first, newest last). Use delta arrows: up, down, flat.
|
|
113
|
+
|
|
114
|
+
End with a "Failure Modes" subsection enumerating parse/schema/unknownDuration counts and listing any unknown `kind` values seen.
|
|
115
|
+
|
|
116
|
+
## Step 5: Emit the report
|
|
117
|
+
|
|
118
|
+
Emit the markdown report **inline** in your response to the user. Do NOT write a file — the `.luca/` contract permits only `<runId>.jsonl` files under `telemetry/`, so a report `.md` there would violate the contract. The skill is read-only; the report is its output, not an artifact.
|
|
119
|
+
|
|
120
|
+
## Step 6: Summary to caller
|
|
121
|
+
|
|
122
|
+
After the report, print:
|
|
123
|
+
|
|
124
|
+
- Counts: runs aggregated, total records parsed, failures (parse/schema/unknownDuration)
|
|
125
|
+
- A one-line headline, e.g. `"10 runs, 7 phases avg, p95 step.execute=18m"`
|
|
126
|
+
|
|
127
|
+
## Step 7: Done
|
|
128
|
+
|
|
129
|
+
The skill exits. No further actions. The user invokes it again with different `--runs` / `--since` / `--vault` to explore.
|
|
130
|
+
|
|
131
|
+
## Failure Modes
|
|
132
|
+
|
|
133
|
+
| Failure | Cause | Skill behavior |
|
|
134
|
+
|---|---|---|
|
|
135
|
+
| `.luca/telemetry/` absent | No pipeline runs yet | Short-circuit to Step 7 with an empty report |
|
|
136
|
+
| JSONL parse error on a line | Corrupted record (mid-write crash) | Increment `failures.parse`, continue |
|
|
137
|
+
| Schema mismatch (`v` field missing) | Pre-v:1 record (none expected; v:1 is current) | Increment `failures.schema`, continue |
|
|
138
|
+
| `durationMs:null` on a `*.end` record | Aborted run or NaN guard fired | Attempt the ts-gap fallback (Step 3); else tally and continue |
|
|
139
|
+
| `--vault` unresolvable | Vault not in `.luca/config.json` | Continue with the supplied vault name; the report uses it as-is |
|
|
140
|
+
| Unknown `kind` value | Future telemetry kind added post-skill | Tally under "Unknown kinds" in the Failure Modes section; do not crash |
|
|
141
|
+
|
|
142
|
+
## Notes
|
|
143
|
+
|
|
144
|
+
- The skill does **not** write any state file. Re-runs are idempotent over the same input set (deterministic).
|
|
145
|
+
- The skill is external to the pipeline — it records nothing.
|