mirror of
https://github.com/backnotprop/plannotator.git
synced 2026-09-14 14:17:26 +08:00
feat: install skills via git sparse-checkout in platform install scripts (#390)
Adds a skills installation phase to all three install scripts (sh, ps1, cmd). Uses git sparse-checkout to fetch only apps/skills/ from the repo at the release tag, then copies into ~/.claude/skills/ and ~/.config/agents/skills/. Gracefully skips if git is unavailable or the clone fails. For provenance purposes, this commit was AI assisted.
This commit is contained in:
@@ -0,0 +1,402 @@
|
||||
---
|
||||
name: plannotator-compound
|
||||
description: >
|
||||
Analyze a user's Plannotator plan archive to extract denial patterns, feedback
|
||||
taxonomy, evolution over time, and actionable prompt improvements — then produce
|
||||
a polished HTML dashboard report. Use this skill when the user says things like
|
||||
"/compound-planning", "analyze my plans", "plan analysis", "what are my denial
|
||||
patterns", "why do my plans get denied", "compound planning report", "plan
|
||||
insights", or "analyze my planning data". This is a user-invoked skill only —
|
||||
do not trigger automatically. The user must explicitly request it.
|
||||
---
|
||||
|
||||
# Compound Planning Analysis
|
||||
|
||||
You are conducting a comprehensive research analysis of a user's Plannotator plan
|
||||
archive. The goal: extract patterns from their denied plans and annotations, reduce
|
||||
them into actionable insights, and produce an elegant HTML dashboard report.
|
||||
|
||||
This is a multi-phase process. Each phase must complete fully before the next begins.
|
||||
Research integrity is paramount — every file must be read, no skipping.
|
||||
|
||||
## Phase 0: Locate the Plans Directory
|
||||
|
||||
Check for `~/.plannotator/plans/`. If it exists and contains `.md` files, proceed.
|
||||
|
||||
If not found, ask the user:
|
||||
> "I couldn't find plans at ~/.plannotator/plans/. Where is your plans directory?"
|
||||
|
||||
Once you have the path, verify it contains files matching `*-denied.md` and/or
|
||||
`*.annotations.md`. If neither exist, inform the user there's no denial/annotation
|
||||
data to analyze and stop.
|
||||
|
||||
## Phase 1: Inventory
|
||||
|
||||
Count and report the dataset:
|
||||
|
||||
```
|
||||
- *-approved.md files (count)
|
||||
- *-denied.md files (count)
|
||||
- *.annotations.md files (count)
|
||||
- *.diff.md files (count)
|
||||
- Date range (earliest to latest date found in filenames)
|
||||
- Total days spanned
|
||||
- Revision rate: denied / (approved + denied) — this is the "X% of plans
|
||||
revised before coding" stat used in dashboard section 1
|
||||
```
|
||||
|
||||
Also run `wc -l` across all `*-approved.md` files to get average lines per
|
||||
approved plan. This tells the user whether their plans are staying lightweight
|
||||
or bloating over time. You do not need to read approved plan contents — just
|
||||
their line counts. If possible, break this down by time period (e.g., monthly)
|
||||
to show whether plan size changed.
|
||||
|
||||
Dates appear in filenames in YYYY-MM-DD format, sometimes as a prefix
|
||||
(2026-01-07-name-approved.md) and sometimes embedded (name-2026-03-15-approved.md).
|
||||
Extract dates from all filenames.
|
||||
|
||||
Tell the user what you found and that you're beginning the extraction.
|
||||
|
||||
## Phase 2: Map — Parallel Extraction
|
||||
|
||||
This is the most time-intensive phase. You must read EVERY denied plan and EVERY
|
||||
annotation file. Do not skip files. Do not summarize early.
|
||||
|
||||
**Important:** Do NOT read approved plan files. They are counted in the inventory
|
||||
for context (total volume, approval rate) but are not analyzed for feedback
|
||||
patterns. Only `*-denied.md` and `*.annotations.md` files contain the feedback
|
||||
data this analysis needs.
|
||||
|
||||
### Batching Strategy
|
||||
|
||||
The approach depends on dataset size:
|
||||
|
||||
**Small datasets (< 40 total files):** Read all files directly — no need for
|
||||
parallel agents. Just read them sequentially and proceed to Phase 3.
|
||||
|
||||
**Medium datasets (40-120 files):** Split into 2-4 parallel agents by file type
|
||||
and/or time period.
|
||||
|
||||
**Large datasets (120+ files):** Split into batches of ~40-60 files per agent.
|
||||
Split by the natural time boundaries in the data (months, quarters, or whatever
|
||||
groupings produce balanced batches). If one time period dominates (e.g., the most
|
||||
recent month has 3x the files), split that period into two batches.
|
||||
|
||||
Launch all extraction agents in parallel using the Agent tool with
|
||||
`run_in_background: true`.
|
||||
|
||||
### Output Files
|
||||
|
||||
Each extraction agent must write its results to a clean output file rather than
|
||||
relying on the agent task output (which contains interleaved JSONL framework
|
||||
logs that are difficult to parse). Instruct each agent to write to:
|
||||
|
||||
```
|
||||
/tmp/compound-planning/extraction-{batch-name}.md
|
||||
```
|
||||
|
||||
Create the `/tmp/compound-planning/` directory before launching agents. The
|
||||
reduce agent in Phase 3 will read these clean files directly.
|
||||
|
||||
### Extraction Prompt for Denied Plans
|
||||
|
||||
Each agent for denied plans receives this instruction (adapt the time period,
|
||||
file glob, and output path):
|
||||
|
||||
```
|
||||
You are extracting structured data from denied plan files for a pattern analysis.
|
||||
|
||||
Directory: [PLANS DIRECTORY]
|
||||
Files to read: All *-denied.md files with dates in [TIME PERIOD]
|
||||
Output: Write your complete results to [OUTPUT FILE PATH]
|
||||
|
||||
Read EVERY matching file. For EACH file, extract:
|
||||
- The plan name/topic
|
||||
- The denial reason or feedback given (look for reviewer comments, annotations,
|
||||
revision requests — capture the actual words used)
|
||||
- What was specifically asked to change
|
||||
- The type of feedback (let the content determine the category — don't force-fit
|
||||
into predefined types. Common types include things like: scope concerns,
|
||||
approach disagreements, missing information, process requirements, quality
|
||||
concerns, UX/design issues, naming disputes, clarification requests,
|
||||
testing/procedural denials — but the user's actual patterns may differ)
|
||||
- Any specific phrases or recurring language from the reviewer
|
||||
- The date
|
||||
|
||||
Do NOT skip any files. One entry per file.
|
||||
|
||||
Format each entry as:
|
||||
**[filename]**
|
||||
- Date: ...
|
||||
- Topic: ...
|
||||
- Denial reason: ...
|
||||
- Feedback type: ...
|
||||
- Specific asks: ...
|
||||
- Notable phrases: ...
|
||||
---
|
||||
|
||||
After processing all files, write the complete results to [OUTPUT FILE PATH].
|
||||
State the total file count at the end of the file.
|
||||
```
|
||||
|
||||
### Extraction Prompt for Annotation Files
|
||||
|
||||
Annotation files have a different structure — they contain inline comments,
|
||||
highlights, and feedback left on specific sections of plans. Each agent for
|
||||
annotations receives this instruction:
|
||||
|
||||
```
|
||||
You are extracting structured data from annotation files for a pattern analysis.
|
||||
|
||||
Directory: [PLANS DIRECTORY]
|
||||
Files to read: All *.annotations.md files with dates in [TIME PERIOD]
|
||||
Output: Write your complete results to [OUTPUT FILE PATH]
|
||||
|
||||
Read EVERY matching file. For EACH file, extract:
|
||||
- The plan name/topic it annotates
|
||||
- Every individual annotation/comment made (there may be multiple per file)
|
||||
- For each annotation: the quoted text, what type of feedback it is (correction,
|
||||
scope concern, design preference, structural request, question, praise,
|
||||
process directive, etc.), and what section of the plan was annotated
|
||||
- The overall tone of the feedback
|
||||
|
||||
Do NOT skip any files. One entry per file.
|
||||
|
||||
Format each entry as:
|
||||
**[filename]**
|
||||
- Plan topic: ...
|
||||
- Annotations found: [count]
|
||||
- Annotation 1: "[quote or paraphrase]" — Type: ... — Section: ...
|
||||
- Annotation 2: "[quote or paraphrase]" — Type: ... — Section: ...
|
||||
- (continue for all annotations in the file)
|
||||
- Overall tone: ...
|
||||
---
|
||||
|
||||
After processing all files, write the complete results to [OUTPUT FILE PATH].
|
||||
State the total file count at the end of the file.
|
||||
```
|
||||
|
||||
### While Agents Run
|
||||
|
||||
Track completion. As each agent finishes, note the count of files it processed.
|
||||
Verify the total matches the inventory from Phase 1. If any agent's count is
|
||||
short, flag it and consider re-launching for the missing files.
|
||||
|
||||
If an agent times out (possible with large batches — a batch of 128 files can
|
||||
take 8+ minutes), re-launch it for just the unprocessed files. Check the output
|
||||
file to see how far it got before timing out.
|
||||
|
||||
## Phase 3: Reduce — Pattern Analysis
|
||||
|
||||
Once ALL extraction agents have completed (or all files have been read for small
|
||||
datasets), launch a single reduction agent.
|
||||
|
||||
The reduction agent reads the clean extraction files from `/tmp/compound-planning/`
|
||||
(not the agent task output files, which contain noisy JSONL framework logs). It
|
||||
processes all extraction files together and produces the comprehensive analysis.
|
||||
|
||||
Give the reduction agent this prompt (adapt the file paths):
|
||||
|
||||
```
|
||||
You are a data scientist conducting the reduction phase of a map-reduce analysis
|
||||
across a user's plan denial and annotation archive.
|
||||
|
||||
Read ALL extraction files at /tmp/compound-planning/extraction-*.md
|
||||
|
||||
These files contain structured extractions from every denied plan and annotation
|
||||
file. Your job: aggregate everything, find patterns, cluster into a taxonomy,
|
||||
and produce a comprehensive analysis.
|
||||
|
||||
Be exhaustive. Use real counts. Quote real phrases from the data. This is
|
||||
research — no hand-waving, no fabrication.
|
||||
|
||||
Produce the following sections:
|
||||
[... sections listed below ...]
|
||||
```
|
||||
|
||||
The reduction agent's job is to let the data speak. Do not impose a predetermined
|
||||
framework — discover what's actually there. The analysis must produce:
|
||||
|
||||
### 1. Denial Reason Taxonomy
|
||||
Categorize every denial into a finite set of types that emerge from the data. Count
|
||||
occurrences. Show percentages. Include real example quotes for each type. Aim for
|
||||
8-15 categories — enough to be specific, few enough to be scannable. Let the user's
|
||||
actual feedback determine what the categories are.
|
||||
|
||||
### 2. Top Feedback Patterns (ranked by frequency)
|
||||
The 5-10 most recurring patterns. For each: what the reviewer consistently asks for,
|
||||
3+ example quotes from different files, and whether the pattern changed over time.
|
||||
|
||||
### 3. Recurring Phrases
|
||||
Exact phrases the reviewer uses repeatedly, with counts and what they signal. These
|
||||
are the reviewer's vocabulary — their shorthand for what they care about.
|
||||
|
||||
### 4. What the Reviewer Values (implicit preferences)
|
||||
Derived from patterns — what does this specific person care about most? Quality?
|
||||
Speed? Narrative? Architecture? Process? Simplicity? Rank by evidence strength.
|
||||
This section should feel like a personality profile of the reviewer's standards.
|
||||
|
||||
### 5. What Agents Consistently Get Wrong
|
||||
The flip side — what recurring mistakes trigger denials? What should agents stop
|
||||
doing for this reviewer?
|
||||
|
||||
### 6. Structural Requests
|
||||
What plan structure does the reviewer consistently demand? Required sections,
|
||||
ordering, format preferences, level of detail expected.
|
||||
|
||||
### 7. Evolution Over Time
|
||||
How feedback patterns changed across the time span. Group by whatever natural time
|
||||
boundaries exist in the data (weeks for short spans, months for longer ones). Did
|
||||
expectations mature? Did new patterns emerge? What shifted? If the dataset spans
|
||||
less than a month, note that evolution analysis is limited but still look for any
|
||||
progression from early to late files.
|
||||
|
||||
### 8. Actionable Prompt Instructions
|
||||
The most important output. Based on all patterns: specific numbered instructions
|
||||
that could be embedded in a planning prompt to prevent the most common denial
|
||||
reasons. Write these as actual directives an agent could follow. Be specific to
|
||||
this user's patterns — generic advice like "write good plans" is worthless. Each
|
||||
instruction should trace back to a real, frequent denial pattern.
|
||||
|
||||
After writing the instructions, calculate what percentage of denials they would
|
||||
address (count how many denials fall into categories covered by the instructions
|
||||
vs total denials). Report this percentage — it will be different for every user.
|
||||
|
||||
## Phase 4: Generate the HTML Dashboard
|
||||
|
||||
Build a single, self-contained HTML file as the final deliverable. Save it to
|
||||
the user's plans directory as `compound-planning-report.html`.
|
||||
|
||||
Read the template at `assets/report-template.html` for the **design language
|
||||
only**. The template contains example data from a previous analysis — ignore all
|
||||
data values, quotes, and percentages in the template. Use only its visual design:
|
||||
colors, typography, spacing, component styles, and layout patterns.
|
||||
|
||||
### Design Language (from template)
|
||||
|
||||
- **Palette:** Light mode, warm off-white (#FDFCFB), text in slate scale, amber
|
||||
for highlights/accents, emerald for positive, rose for negative, indigo for
|
||||
action elements
|
||||
- **Typography:** Playfair Display (serif, for narrative headings), Inter (sans,
|
||||
for body/data), JetBrains Mono (mono, for code/phrases) — Google Fonts CDN
|
||||
- **Layout:** Single-column, max-width 1024px, generous vertical whitespace (128px
|
||||
between major sections), editorial/narrative-first aesthetic
|
||||
- **Tone:** Calm, reflective, authoritative. Like a personal retrospective journal,
|
||||
not a monitoring dashboard.
|
||||
|
||||
### Page Frame (header + footer)
|
||||
|
||||
Before the 7 sections, the page has:
|
||||
|
||||
- **Header:** Report title on the left (Playfair Display, ~36px), project name +
|
||||
date range below it in light meta text. On the right: file counts in mono
|
||||
(e.g., "202 denials · 168 annotations · 71 days"). Separated from content by
|
||||
a bottom border. Generous bottom padding before section 1.
|
||||
|
||||
- **Footer:** After section 7. Top border, centered italic Playfair Display tagline
|
||||
summarizing the corpus (e.g., "Analysis of X denied plans and Y annotation files
|
||||
from the Plannotator archive.").
|
||||
|
||||
### Dashboard Section Order (7 sections)
|
||||
|
||||
The report follows this exact section order. Each section builds on the previous
|
||||
one — the flow moves from "what happened" through "why" to "what to do about it":
|
||||
|
||||
1. **The story in the data** — An editorial narrative paragraph (Playfair Display
|
||||
serif, ~26px) that tells the headline finding in prose. Not bullet points — a
|
||||
real paragraph that reads like the opening of an article. Alongside it, a KPI
|
||||
sidebar with 3 key metrics (the top denial percentage, the overall revision
|
||||
rate, and the number of distinct denial categories found). Use an amber inline
|
||||
highlight on the most striking number in the narrative.
|
||||
|
||||
2. **Why plans get denied** — The taxonomy as a ranked list. Each row: rank number
|
||||
(mono), category label, a thin 4px progress bar (top item in amber-500, rest
|
||||
in slate-300), percentage (mono), and for the top entries, a real italic quote
|
||||
from the data below the label. Show the top 10 categories or however many the
|
||||
data supports (minimum 5).
|
||||
|
||||
3. **How expectations evolved** — One card per natural time period. Each card has:
|
||||
the period name in serif, a theme phrase in colored uppercase (different color
|
||||
per period to show progression), a description paragraph, and a stat line at
|
||||
the bottom (e.g., "X denials · Y narrative requests"). If the data spans less
|
||||
than 3 distinct periods, use 2 cards or even a single card with internal
|
||||
progression noted.
|
||||
|
||||
4. **What works vs what doesn't** — Two side-by-side cards. Left: green-tinted
|
||||
(emerald-50/50 bg, emerald-100 border) with traits of plans that succeed for
|
||||
this reviewer. Right: red-tinted (rose-50/50 bg, rose-100 border) with what
|
||||
agents keep getting wrong. Both derived from the reduction analysis. Bulleted
|
||||
with small colored dots. 5-8 items per card.
|
||||
|
||||
5. **The actionable output** — The diagnostic payoff. Opens with a Playfair
|
||||
Display narrative sentence stating how many prompt instructions were derived
|
||||
and what estimated percentage of denials they address (use the real calculated
|
||||
percentage from Phase 3, not a generic number). Then the top 3 most impactful
|
||||
improvements as numbered items, each with an amber number, bold title, and
|
||||
one-line description. This section bridges the analysis and the full prompt
|
||||
that follows.
|
||||
|
||||
6. **Your most-used phrases** — Grid of chips (2-col mobile, 3-col desktop). Each
|
||||
chip: monospace quoted phrase on the left, frequency count on the right. White
|
||||
bg, slate-200 border, rounded-12px. Show 9-12 of the most recurring phrases
|
||||
found. These should be the reviewer's actual words — their verbal fingerprint.
|
||||
|
||||
7. **The corrective prompt** — Dark panel (slate-900 bg, white text, rounded-3xl,
|
||||
shadow-xl). Opens with a Playfair intro sentence about the instructions. Then
|
||||
a dark code block (slate-800/80 bg, amber-200 monospace text) containing the
|
||||
full numbered prompt instructions from Phase 3. Include a copy-to-clipboard
|
||||
button that works (JS included). Below the code block: a gradient glow card
|
||||
(indigo-to-purple blurred halo behind a white card) with a closing message
|
||||
that these instructions are personal — derived from the user's own feedback,
|
||||
their own language, their own standards.
|
||||
|
||||
### Adaptation Rules
|
||||
|
||||
- If the user has < 3 months of data, reduce the evolution section to fewer cards
|
||||
- If the user has no annotation files (only denials), note this in the narrative
|
||||
and skip annotation-specific insights
|
||||
- If fewer than 5 denial categories emerge, combine the taxonomy and patterns
|
||||
sections into one
|
||||
- If the dataset is very small (< 20 files), the narrative should acknowledge the
|
||||
limited sample size and frame findings as preliminary
|
||||
- The number of prompt instructions will vary per user — could be 8 or 20. Don't
|
||||
force exactly 17. Let the data determine the count.
|
||||
- The top 3 actionable items in section 5 must be the 3 that cover the largest
|
||||
share of denials, not the 3 that sound most impressive
|
||||
|
||||
### Key Rules
|
||||
|
||||
1. Every number must come from the real analysis — no fabricated data
|
||||
2. Every quote must be a real quote from a real file
|
||||
3. The taxonomy percentages must be calculated from real counts
|
||||
4. The prompt instructions must trace back to actual denial patterns
|
||||
5. The copy button on the prompt block must work (include the JS)
|
||||
|
||||
After generating, open the file in the user's browser.
|
||||
|
||||
## Phase 5: Summary
|
||||
|
||||
Tell the user:
|
||||
- How many total files were analyzed (denials + annotations)
|
||||
- The top 3 denial patterns found
|
||||
- The estimated percentage of denials the prompt instructions would address
|
||||
- The single most impactful prompt improvement
|
||||
- Where the report was saved
|
||||
|
||||
## Important Notes
|
||||
|
||||
- **Research integrity:** Every file must be read. The value of this analysis comes
|
||||
from completeness. Sampling or skipping undermines the findings.
|
||||
- **Real data only:** Never fabricate quotes, percentages, or patterns. If the data
|
||||
doesn't show a clear pattern, say so honestly rather than inventing one.
|
||||
- **Let the data lead:** The taxonomy, patterns, and instructions should emerge from
|
||||
what's actually in the files. Different users will have completely different
|
||||
denial patterns. A user building mobile apps will have different feedback than
|
||||
one building APIs. Don't assume what the patterns will be.
|
||||
- **Agent parallelization:** For large datasets, maximize parallel agents to reduce
|
||||
wall-clock time. The bottleneck is the largest batch — split it.
|
||||
- **Structured extraction format:** Ask extraction agents to return structured text
|
||||
with consistent delimiters so the reduce agent can parse reliably.
|
||||
- **The report is the artifact:** The HTML dashboard is what the user keeps. It
|
||||
should be beautiful, honest, and useful. Every section should feel like it was
|
||||
written about them specifically, because it was.
|
||||
@@ -0,0 +1,795 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>Compound Planning — What 370 Files Reveal</title>
|
||||
<link rel="preconnect" href="https://fonts.googleapis.com">
|
||||
<link href="https://fonts.googleapis.com/css2?family=Playfair+Display:ital,wght@0,400;0,500;1,400&family=Inter:wght@300;400;500;600&family=JetBrains+Mono:wght@400;500&display=swap" rel="stylesheet">
|
||||
<style>
|
||||
*, *::before, *::after { margin: 0; padding: 0; box-sizing: border-box; }
|
||||
|
||||
:root {
|
||||
--bg: #FDFCFB;
|
||||
--slate-900: #0f172a;
|
||||
--slate-800: #1e293b;
|
||||
--slate-700: #334155;
|
||||
--slate-600: #475569;
|
||||
--slate-500: #64748b;
|
||||
--slate-400: #94a3b8;
|
||||
--slate-300: #cbd5e1;
|
||||
--slate-200: #e2e8f0;
|
||||
--slate-100: #f1f5f9;
|
||||
--slate-50: #f8fafc;
|
||||
--amber-500: #f59e0b;
|
||||
--amber-600: #d97706;
|
||||
--amber-700: #b45309;
|
||||
--amber-50: #fffbeb;
|
||||
--emerald-500: #10b981;
|
||||
--emerald-600: #059669;
|
||||
--emerald-400: #34d399;
|
||||
--emerald-900: #064e3b;
|
||||
--emerald-800: #065f46;
|
||||
--emerald-100: #d1fae5;
|
||||
--emerald-50: #ecfdf5;
|
||||
--rose-500: #f43f5e;
|
||||
--rose-600: #e11d48;
|
||||
--rose-400: #fb7185;
|
||||
--rose-900: #881337;
|
||||
--rose-800: #9f1239;
|
||||
--rose-100: #ffe4e6;
|
||||
--rose-50: #fff1f2;
|
||||
--indigo-500: #6366f1;
|
||||
--indigo-600: #4f46e5;
|
||||
--purple-600: #9333ea;
|
||||
}
|
||||
|
||||
body {
|
||||
font-family: 'Inter', ui-sans-serif, system-ui, sans-serif;
|
||||
background: var(--bg);
|
||||
color: var(--slate-800);
|
||||
-webkit-font-smoothing: antialiased;
|
||||
}
|
||||
|
||||
.container {
|
||||
max-width: 1024px;
|
||||
margin: 0 auto;
|
||||
padding: 48px 24px 64px;
|
||||
}
|
||||
@media (min-width: 768px) { .container { padding: 96px 24px 80px; } }
|
||||
|
||||
/* Typography */
|
||||
.font-serif { font-family: 'Playfair Display', ui-serif, Georgia, serif; }
|
||||
.font-mono { font-family: 'JetBrains Mono', ui-monospace, monospace; }
|
||||
|
||||
/* Header */
|
||||
header {
|
||||
border-bottom: 1px solid var(--slate-200);
|
||||
padding-bottom: 40px;
|
||||
margin-bottom: 96px;
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: flex-end;
|
||||
flex-wrap: wrap;
|
||||
gap: 16px;
|
||||
}
|
||||
header h1 {
|
||||
font-family: 'Playfair Display', serif;
|
||||
font-size: 36px;
|
||||
font-weight: 400;
|
||||
color: var(--slate-900);
|
||||
line-height: 1.2;
|
||||
}
|
||||
header .meta {
|
||||
font-size: 15px;
|
||||
font-weight: 300;
|
||||
color: var(--slate-500);
|
||||
letter-spacing: 0.04em;
|
||||
}
|
||||
|
||||
/* Sections */
|
||||
.section { margin-bottom: 128px; }
|
||||
.section-label {
|
||||
font-size: 12px;
|
||||
font-weight: 600;
|
||||
text-transform: uppercase;
|
||||
letter-spacing: 0.2em;
|
||||
color: var(--slate-400);
|
||||
margin-bottom: 24px;
|
||||
}
|
||||
|
||||
/* Narrative + KPIs */
|
||||
.summary {
|
||||
display: grid;
|
||||
grid-template-columns: 1fr;
|
||||
gap: 48px;
|
||||
align-items: start;
|
||||
}
|
||||
@media (min-width: 768px) {
|
||||
.summary { grid-template-columns: 1fr 240px; }
|
||||
}
|
||||
.narrative {
|
||||
font-family: 'Playfair Display', serif;
|
||||
font-size: 26px;
|
||||
line-height: 1.45;
|
||||
color: var(--slate-900);
|
||||
}
|
||||
.narrative .highlight {
|
||||
background: var(--amber-50);
|
||||
color: var(--amber-700);
|
||||
padding: 1px 6px;
|
||||
border-radius: 3px;
|
||||
}
|
||||
.kpi-stack {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 32px;
|
||||
}
|
||||
@media (min-width: 768px) {
|
||||
.kpi-stack { border-left: 1px solid var(--slate-200); padding-left: 32px; }
|
||||
}
|
||||
.kpi-item .kpi-value {
|
||||
font-size: 36px;
|
||||
font-weight: 300;
|
||||
color: var(--slate-900);
|
||||
letter-spacing: -0.02em;
|
||||
}
|
||||
.kpi-item .kpi-label {
|
||||
font-size: 10px;
|
||||
font-weight: 600;
|
||||
text-transform: uppercase;
|
||||
letter-spacing: 0.15em;
|
||||
color: var(--slate-500);
|
||||
margin-top: 2px;
|
||||
}
|
||||
|
||||
/* Taxonomy bars */
|
||||
.taxonomy-list { display: flex; flex-direction: column; gap: 20px; }
|
||||
.tax-row { display: grid; grid-template-columns: 24px 1fr 52px; gap: 12px; align-items: center; }
|
||||
.tax-rank {
|
||||
font-family: 'JetBrains Mono', monospace;
|
||||
font-size: 12px;
|
||||
color: var(--slate-400);
|
||||
text-align: right;
|
||||
}
|
||||
.tax-body { display: flex; flex-direction: column; gap: 6px; }
|
||||
.tax-label { font-size: 14px; font-weight: 500; color: var(--slate-800); }
|
||||
.tax-bar-track { height: 4px; background: var(--slate-100); border-radius: 100px; overflow: hidden; }
|
||||
.tax-bar-fill { height: 100%; border-radius: 100px; transition: width 0.6s ease; }
|
||||
.tax-bar-fill.top { background: var(--amber-500); }
|
||||
.tax-bar-fill.rest { background: var(--slate-300); }
|
||||
.tax-pct {
|
||||
font-family: 'JetBrains Mono', monospace;
|
||||
font-size: 12px;
|
||||
color: var(--slate-500);
|
||||
text-align: right;
|
||||
}
|
||||
.tax-quote {
|
||||
font-size: 12px;
|
||||
font-style: italic;
|
||||
color: var(--slate-500);
|
||||
margin-top: 2px;
|
||||
}
|
||||
|
||||
/* Evolution timeline */
|
||||
.evolution-grid {
|
||||
display: grid;
|
||||
grid-template-columns: 1fr;
|
||||
gap: 24px;
|
||||
}
|
||||
@media (min-width: 768px) { .evolution-grid { grid-template-columns: repeat(3, 1fr); } }
|
||||
.evo-card {
|
||||
background: white;
|
||||
border: 1px solid var(--slate-200);
|
||||
border-radius: 16px;
|
||||
padding: 28px;
|
||||
}
|
||||
.evo-card .evo-month {
|
||||
font-family: 'Playfair Display', serif;
|
||||
font-size: 20px;
|
||||
color: var(--slate-900);
|
||||
margin-bottom: 4px;
|
||||
}
|
||||
.evo-card .evo-theme {
|
||||
font-size: 12px;
|
||||
font-weight: 600;
|
||||
text-transform: uppercase;
|
||||
letter-spacing: 0.12em;
|
||||
margin-bottom: 16px;
|
||||
}
|
||||
.evo-card .evo-desc {
|
||||
font-size: 14px;
|
||||
color: var(--slate-600);
|
||||
line-height: 1.6;
|
||||
}
|
||||
.evo-card .evo-stat {
|
||||
margin-top: 16px;
|
||||
padding-top: 16px;
|
||||
border-top: 1px solid var(--slate-100);
|
||||
font-family: 'JetBrains Mono', monospace;
|
||||
font-size: 12px;
|
||||
color: var(--slate-500);
|
||||
}
|
||||
.evo-jan .evo-theme { color: var(--slate-600); }
|
||||
.evo-feb .evo-theme { color: var(--amber-600); }
|
||||
.evo-mar .evo-theme { color: var(--indigo-600); }
|
||||
|
||||
/* Quality comparison */
|
||||
.quality-grid {
|
||||
display: grid;
|
||||
grid-template-columns: 1fr;
|
||||
gap: 24px;
|
||||
}
|
||||
@media (min-width: 768px) { .quality-grid { grid-template-columns: 1fr 1fr; } }
|
||||
.q-card {
|
||||
border-radius: 24px;
|
||||
padding: 36px;
|
||||
}
|
||||
.q-card.good {
|
||||
background: color-mix(in srgb, var(--emerald-50) 50%, transparent);
|
||||
border: 1px solid var(--emerald-100);
|
||||
}
|
||||
.q-card.bad {
|
||||
background: color-mix(in srgb, var(--rose-50) 50%, transparent);
|
||||
border: 1px solid var(--rose-100);
|
||||
}
|
||||
.q-card .q-icon { font-size: 20px; margin-bottom: 12px; }
|
||||
.q-card .q-title {
|
||||
font-family: 'Playfair Display', serif;
|
||||
font-size: 22px;
|
||||
margin-bottom: 20px;
|
||||
}
|
||||
.q-card.good .q-title { color: var(--emerald-900); }
|
||||
.q-card.bad .q-title { color: var(--rose-900); }
|
||||
.q-list { list-style: none; display: flex; flex-direction: column; gap: 14px; }
|
||||
.q-list li {
|
||||
display: flex;
|
||||
align-items: flex-start;
|
||||
gap: 10px;
|
||||
font-size: 14px;
|
||||
line-height: 1.6;
|
||||
}
|
||||
.q-card.good .q-list li { color: color-mix(in srgb, var(--emerald-800) 90%, transparent); }
|
||||
.q-card.bad .q-list li { color: color-mix(in srgb, var(--rose-800) 90%, transparent); }
|
||||
.q-dot {
|
||||
width: 6px;
|
||||
height: 6px;
|
||||
border-radius: 50%;
|
||||
flex-shrink: 0;
|
||||
margin-top: 7px;
|
||||
}
|
||||
.q-card.good .q-dot { background: var(--emerald-400); }
|
||||
.q-card.bad .q-dot { background: var(--rose-400); }
|
||||
|
||||
/* Phrases */
|
||||
.phrases-grid {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(2, 1fr);
|
||||
gap: 12px;
|
||||
}
|
||||
@media (min-width: 768px) { .phrases-grid { grid-template-columns: repeat(3, 1fr); } }
|
||||
.phrase-chip {
|
||||
background: white;
|
||||
border: 1px solid var(--slate-200);
|
||||
border-radius: 12px;
|
||||
padding: 14px 16px;
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
gap: 8px;
|
||||
}
|
||||
.phrase-text {
|
||||
font-family: 'JetBrains Mono', monospace;
|
||||
font-size: 12px;
|
||||
color: var(--slate-700);
|
||||
white-space: nowrap;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
}
|
||||
.phrase-count {
|
||||
font-family: 'JetBrains Mono', monospace;
|
||||
font-size: 11px;
|
||||
color: var(--slate-400);
|
||||
flex-shrink: 0;
|
||||
}
|
||||
|
||||
/* Dark action panel */
|
||||
.action-panel {
|
||||
background: var(--slate-900);
|
||||
color: white;
|
||||
border-radius: 24px;
|
||||
padding: 40px;
|
||||
box-shadow: 0 20px 25px -5px rgb(0 0 0 / 0.1), 0 8px 10px -6px rgb(0 0 0 / 0.1);
|
||||
}
|
||||
@media (min-width: 768px) { .action-panel { padding: 56px; } }
|
||||
.action-panel .section-label { color: var(--slate-500); }
|
||||
.action-panel .ap-intro {
|
||||
font-family: 'Playfair Display', serif;
|
||||
font-size: 22px;
|
||||
color: white;
|
||||
line-height: 1.4;
|
||||
margin-bottom: 32px;
|
||||
max-width: 640px;
|
||||
}
|
||||
.prompt-block {
|
||||
background: color-mix(in srgb, var(--slate-800) 80%, transparent);
|
||||
border: 1px solid color-mix(in srgb, var(--slate-700) 50%, transparent);
|
||||
border-radius: 16px;
|
||||
overflow: hidden;
|
||||
}
|
||||
.prompt-header {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
padding: 12px 20px;
|
||||
border-bottom: 1px solid color-mix(in srgb, var(--slate-700) 30%, transparent);
|
||||
}
|
||||
.prompt-header-label {
|
||||
font-family: 'JetBrains Mono', monospace;
|
||||
font-size: 12px;
|
||||
color: var(--slate-400);
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 8px;
|
||||
}
|
||||
.prompt-header-label svg { width: 14px; height: 14px; }
|
||||
.copy-btn {
|
||||
background: none;
|
||||
border: none;
|
||||
font-family: 'JetBrains Mono', monospace;
|
||||
font-size: 12px;
|
||||
color: var(--slate-400);
|
||||
cursor: pointer;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 6px;
|
||||
transition: color 0.2s;
|
||||
}
|
||||
.copy-btn:hover { color: white; }
|
||||
.copy-btn.copied { color: var(--emerald-400); }
|
||||
.prompt-body {
|
||||
padding: 20px;
|
||||
max-height: 480px;
|
||||
overflow-y: auto;
|
||||
}
|
||||
.prompt-body pre {
|
||||
font-family: 'JetBrains Mono', monospace;
|
||||
font-size: 13px;
|
||||
line-height: 1.7;
|
||||
color: color-mix(in srgb, var(--amber-200) 90%, transparent);
|
||||
white-space: pre-wrap;
|
||||
word-break: break-word;
|
||||
}
|
||||
.prompt-body pre .comment {
|
||||
color: var(--slate-500);
|
||||
}
|
||||
|
||||
/* Glow card */
|
||||
.glow-wrap {
|
||||
position: relative;
|
||||
margin-top: 48px;
|
||||
}
|
||||
.glow-bg {
|
||||
position: absolute;
|
||||
inset: -2px;
|
||||
background: linear-gradient(135deg, var(--indigo-500), var(--purple-600));
|
||||
border-radius: 26px;
|
||||
opacity: 0.15;
|
||||
filter: blur(16px);
|
||||
transition: opacity 0.5s;
|
||||
}
|
||||
.glow-wrap:hover .glow-bg { opacity: 0.25; }
|
||||
.glow-card {
|
||||
position: relative;
|
||||
background: white;
|
||||
border: 1px solid var(--slate-200);
|
||||
border-radius: 24px;
|
||||
padding: 32px 36px;
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
flex-wrap: wrap;
|
||||
gap: 20px;
|
||||
}
|
||||
.glow-card .gc-text {
|
||||
font-family: 'Playfair Display', serif;
|
||||
font-size: 18px;
|
||||
font-weight: 500;
|
||||
color: var(--slate-900);
|
||||
line-height: 1.5;
|
||||
max-width: 640px;
|
||||
}
|
||||
.glow-card .gc-text em {
|
||||
font-style: italic;
|
||||
color: var(--indigo-600);
|
||||
}
|
||||
|
||||
/* Footer */
|
||||
footer {
|
||||
border-top: 1px solid var(--slate-200);
|
||||
padding-top: 48px;
|
||||
margin-top: 0;
|
||||
text-align: center;
|
||||
}
|
||||
footer p {
|
||||
font-family: 'Playfair Display', serif;
|
||||
font-style: italic;
|
||||
font-size: 15px;
|
||||
color: var(--slate-400);
|
||||
}
|
||||
|
||||
/* Scrollbar in dark code block */
|
||||
.prompt-body::-webkit-scrollbar { width: 6px; }
|
||||
.prompt-body::-webkit-scrollbar-track { background: transparent; }
|
||||
.prompt-body::-webkit-scrollbar-thumb { background: var(--slate-700); border-radius: 3px; }
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<div class="container">
|
||||
|
||||
<header>
|
||||
<div>
|
||||
<h1>What 370 Files Reveal About<br>How You Plan</h1>
|
||||
<div class="meta" style="margin-top: 8px;">backnotprop/plannotator · Jan 7 – Mar 18, 2026</div>
|
||||
</div>
|
||||
<div class="meta" style="text-align: right;">
|
||||
<span class="font-mono" style="font-size: 12px;">202 denials · 168 annotations · 71 days</span>
|
||||
</div>
|
||||
</header>
|
||||
|
||||
<!-- 1. Narrative + KPIs -->
|
||||
<div class="section">
|
||||
<div class="section-label">1. The story in the data</div>
|
||||
<div class="summary">
|
||||
<div class="narrative">
|
||||
Across 71 days you denied or revised <span class="highlight">202 plans</span> before any code was written. The single most common reason—appearing in 1 out of 4 denials—was the same: the agent jumped to implementation without telling you <em>what</em> it was building, <em>why</em>, or <em>how</em>. Missing narrative. Missing context. Missing the story. Your expectations evolved from “does it work?” in January to “tell me the story and be confident” by March.
|
||||
</div>
|
||||
<div class="kpi-stack">
|
||||
<div class="kpi-item">
|
||||
<div class="kpi-value">25.7%</div>
|
||||
<div class="kpi-label">Denials for missing narrative</div>
|
||||
</div>
|
||||
<div class="kpi-item">
|
||||
<div class="kpi-value">50%</div>
|
||||
<div class="kpi-label">Plans revised before coding</div>
|
||||
</div>
|
||||
<div class="kpi-item">
|
||||
<div class="kpi-value">12</div>
|
||||
<div class="kpi-label">Distinct denial categories</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 2. Denial Taxonomy -->
|
||||
<div class="section">
|
||||
<div class="section-label">2. Why plans get denied</div>
|
||||
<div class="taxonomy-list">
|
||||
<div class="tax-row">
|
||||
<span class="tax-rank">1</span>
|
||||
<div class="tax-body">
|
||||
<span class="tax-label">Missing Narrative / Overview</span>
|
||||
<div class="tax-bar-track"><div class="tax-bar-fill top" style="width: 100%"></div></div>
|
||||
<span class="tax-quote">"This plan is denied without narrative detail and rationales."</span>
|
||||
</div>
|
||||
<span class="tax-pct">25.7%</span>
|
||||
</div>
|
||||
<div class="tax-row">
|
||||
<span class="tax-rank">2</span>
|
||||
<div class="tax-body">
|
||||
<span class="tax-label">Clarification Needed</span>
|
||||
<div class="tax-bar-track"><div class="tax-bar-fill rest" style="width: 65%"></div></div>
|
||||
<span class="tax-quote">"What does this Mean???"</span>
|
||||
</div>
|
||||
<span class="tax-pct">16.8%</span>
|
||||
</div>
|
||||
<div class="tax-row">
|
||||
<span class="tax-rank">3</span>
|
||||
<div class="tax-body">
|
||||
<span class="tax-label">Testing / Procedural</span>
|
||||
<div class="tax-bar-track"><div class="tax-bar-fill rest" style="width: 54%"></div></div>
|
||||
<span class="tax-quote">"I'm denying so you can create a diff."</span>
|
||||
</div>
|
||||
<span class="tax-pct">13.9%</span>
|
||||
</div>
|
||||
<div class="tax-row">
|
||||
<span class="tax-rank">4</span>
|
||||
<div class="tax-body">
|
||||
<span class="tax-label">Wrong Approach / Over-Engineered</span>
|
||||
<div class="tax-bar-track"><div class="tax-bar-fill rest" style="width: 37%"></div></div>
|
||||
<span class="tax-quote">"Why are we doing difficult shit here? I want a hover experience."</span>
|
||||
</div>
|
||||
<span class="tax-pct">9.4%</span>
|
||||
</div>
|
||||
<div class="tax-row">
|
||||
<span class="tax-rank">5</span>
|
||||
<div class="tax-body">
|
||||
<span class="tax-label">Process Requirement</span>
|
||||
<div class="tax-bar-track"><div class="tax-bar-fill rest" style="width: 31%"></div></div>
|
||||
<span class="tax-quote">"Make sure you feature branch."</span>
|
||||
</div>
|
||||
<span class="tax-pct">7.9%</span>
|
||||
</div>
|
||||
<div class="tax-row">
|
||||
<span class="tax-rank">6</span>
|
||||
<div class="tax-body">
|
||||
<span class="tax-label">Confidence / Risk Check</span>
|
||||
<div class="tax-bar-track"><div class="tax-bar-fill rest" style="width: 29%"></div></div>
|
||||
<span class="tax-quote">"Take a step back, breathe, make sure we're not being irrational."</span>
|
||||
</div>
|
||||
<span class="tax-pct">7.4%</span>
|
||||
</div>
|
||||
<div class="tax-row">
|
||||
<span class="tax-rank">7</span>
|
||||
<div class="tax-body">
|
||||
<span class="tax-label">Content Removal</span>
|
||||
<div class="tax-bar-track"><div class="tax-bar-fill rest" style="width: 27%"></div></div>
|
||||
<span class="tax-quote">"I don't want this in the plan."</span>
|
||||
</div>
|
||||
<span class="tax-pct">6.9%</span>
|
||||
</div>
|
||||
<div class="tax-row">
|
||||
<span class="tax-rank">8</span>
|
||||
<div class="tax-body">
|
||||
<span class="tax-label">Implementation Bug Found</span>
|
||||
<div class="tax-bar-track"><div class="tax-bar-fill rest" style="width: 23%"></div></div>
|
||||
</div>
|
||||
<span class="tax-pct">5.9%</span>
|
||||
</div>
|
||||
<div class="tax-row">
|
||||
<span class="tax-rank">9</span>
|
||||
<div class="tax-body">
|
||||
<span class="tax-label">Design / UX Issue</span>
|
||||
<div class="tax-bar-track"><div class="tax-bar-fill rest" style="width: 21%"></div></div>
|
||||
</div>
|
||||
<span class="tax-pct">5.4%</span>
|
||||
</div>
|
||||
<div class="tax-row">
|
||||
<span class="tax-rank">10</span>
|
||||
<div class="tax-body">
|
||||
<span class="tax-label">Naming / Terminology</span>
|
||||
<div class="tax-bar-track"><div class="tax-bar-fill rest" style="width: 16%"></div></div>
|
||||
<span class="tax-quote">"Why do you keep calling it Simplified????"</span>
|
||||
</div>
|
||||
<span class="tax-pct">4.0%</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 3. Evolution -->
|
||||
<div class="section">
|
||||
<div class="section-label">3. How your expectations evolved</div>
|
||||
<div class="evolution-grid">
|
||||
<div class="evo-card evo-jan">
|
||||
<div class="evo-month">January</div>
|
||||
<div class="evo-theme">"Does it work?"</div>
|
||||
<div class="evo-desc">Bug-hunting phase. You were hands-on testing View Logs, iterating on session scoping heuristics. 60% of denials were implementation bugs and verification failures. No mention of “narrative” or “overview” yet.</div>
|
||||
<div class="evo-stat">26 denials · 0 narrative requests</div>
|
||||
</div>
|
||||
<div class="evo-card evo-feb">
|
||||
<div class="evo-month">February</div>
|
||||
<div class="evo-theme">"Follow the process"</div>
|
||||
<div class="evo-desc">Process gates emerged: feature branches, Linear tickets, pull main. 40% of denials were procedural (diff testing). UX polish intensified. The first narrative demands appeared: “I want a narrative under each section.”</div>
|
||||
<div class="evo-stat">48 denials · 6 narrative requests</div>
|
||||
</div>
|
||||
<div class="evo-card evo-mar">
|
||||
<div class="evo-month">March</div>
|
||||
<div class="evo-theme">"Tell me the story"</div>
|
||||
<div class="evo-desc">Narrative became the #1 gate. You created a “Missing overview” label and applied it systematically. Confidence checks became standard. You began telling agents to “take a step back, breathe, and analyze.”</div>
|
||||
<div class="evo-stat">128 denials · 25+ narrative requests</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 4. Quality comparison -->
|
||||
<div class="section">
|
||||
<div class="section-label">4. What works vs. what doesn't</div>
|
||||
<div class="quality-grid">
|
||||
<div class="q-card good">
|
||||
<div class="q-icon">✓</div>
|
||||
<div class="q-title">What approved plans do</div>
|
||||
<ul class="q-list">
|
||||
<li><span class="q-dot"></span>Lead with a narrative overview: what exists, what changes, why</li>
|
||||
<li><span class="q-dot"></span>State confidence and identify risks proactively</li>
|
||||
<li><span class="q-dot"></span>Reference existing codebase patterns before proposing new code</li>
|
||||
<li><span class="q-dot"></span>Use explicit, transparent naming (not euphemisms)</li>
|
||||
<li><span class="q-dot"></span>Break large work into phases with evaluation gates</li>
|
||||
<li><span class="q-dot"></span>Include example output for user-facing changes</li>
|
||||
<li><span class="q-dot"></span>Specify feature branch and ticket creation steps</li>
|
||||
</ul>
|
||||
</div>
|
||||
<div class="q-card bad">
|
||||
<div class="q-icon">✗</div>
|
||||
<div class="q-title">What agents keep getting wrong</div>
|
||||
<ul class="q-list">
|
||||
<li><span class="q-dot"></span>Jump to implementation steps without narrative context</li>
|
||||
<li><span class="q-dot"></span>Over-engineer: Shift+Click when hover works, MCP tool when a README suffices</li>
|
||||
<li><span class="q-dot"></span>Introduce new code for things the codebase already solves</li>
|
||||
<li><span class="q-dot"></span>Propose work on top of failing lint/type checks</li>
|
||||
<li><span class="q-dot"></span>Use vague or euphemistic naming (“Accept” instead of “Git Add”)</li>
|
||||
<li><span class="q-dot"></span>Wait to be asked for confidence instead of stating it</li>
|
||||
<li><span class="q-dot"></span>Rush to modify instead of reporting what they see</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 5. The actionable output -->
|
||||
<div class="section">
|
||||
<div class="section-label">5. The actionable output</div>
|
||||
<div class="narrative" style="margin-bottom: 32px;">
|
||||
The analysis produced <span class="highlight">17 specific prompt instructions</span> that, if embedded in a planning prompt, would address ~70% of all denial reasons. The biggest three:
|
||||
</div>
|
||||
<div style="display: flex; flex-direction: column; gap: 20px;">
|
||||
<div style="display: flex; gap: 16px; align-items: flex-start;">
|
||||
<span class="font-mono" style="font-size: 24px; font-weight: 300; color: var(--amber-500); flex-shrink: 0; width: 32px; text-align: right;">1</span>
|
||||
<div>
|
||||
<div style="font-size: 17px; font-weight: 500; color: var(--slate-900); margin-bottom: 4px;">Every plan MUST start with a Solution Overview</div>
|
||||
<div style="font-size: 14px; color: var(--slate-600); line-height: 1.5;">What exists, what changes, why, how. This alone addresses 1 in 4 denials.</div>
|
||||
</div>
|
||||
</div>
|
||||
<div style="display: flex; gap: 16px; align-items: flex-start;">
|
||||
<span class="font-mono" style="font-size: 24px; font-weight: 300; color: var(--amber-500); flex-shrink: 0; width: 32px; text-align: right;">2</span>
|
||||
<div>
|
||||
<div style="font-size: 17px; font-weight: 500; color: var(--slate-900); margin-bottom: 4px;">End every plan with a Confidence Assessment</div>
|
||||
<div style="font-size: 14px; color: var(--slate-600); line-height: 1.5;">Don’t wait to be asked. State your confidence, identify risks, flag uncertainties.</div>
|
||||
</div>
|
||||
</div>
|
||||
<div style="display: flex; gap: 16px; align-items: flex-start;">
|
||||
<span class="font-mono" style="font-size: 24px; font-weight: 300; color: var(--amber-500); flex-shrink: 0; width: 32px; text-align: right;">3</span>
|
||||
<div>
|
||||
<div style="font-size: 17px; font-weight: 500; color: var(--slate-900); margin-bottom: 4px;">Search for existing patterns before proposing new code</div>
|
||||
<div style="font-size: 14px; color: var(--slate-600); line-height: 1.5;">Explicitly state what you found in the codebase. Prefer reuse over new implementation.</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 6. Recurring phrases -->
|
||||
<div class="section">
|
||||
<div class="section-label">6. Your most-used phrases</div>
|
||||
<div class="phrases-grid">
|
||||
<div class="phrase-chip"><span class="phrase-text">"narrative"</span><span class="phrase-count">50+</span></div>
|
||||
<div class="phrase-chip"><span class="phrase-text">"I don't want this in the plan"</span><span class="phrase-count">10</span></div>
|
||||
<div class="phrase-chip"><span class="phrase-text">"feature branch"</span><span class="phrase-count">8+</span></div>
|
||||
<div class="phrase-chip"><span class="phrase-text">"confidence"</span><span class="phrase-count">8+</span></div>
|
||||
<div class="phrase-chip"><span class="phrase-text">"Missing overview"</span><span class="phrase-count">14</span></div>
|
||||
<div class="phrase-chip"><span class="phrase-text">"front-end design skill"</span><span class="phrase-count">16</span></div>
|
||||
<div class="phrase-chip"><span class="phrase-text">"separation of concerns"</span><span class="phrase-count">6</span></div>
|
||||
<div class="phrase-chip"><span class="phrase-text">"Take a step back, breathe"</span><span class="phrase-count">6</span></div>
|
||||
<div class="phrase-chip"><span class="phrase-text">"how does this work"</span><span class="phrase-count">5+</span></div>
|
||||
<div class="phrase-chip"><span class="phrase-text">"what the fuck"</span><span class="phrase-count">4</span></div>
|
||||
<div class="phrase-chip"><span class="phrase-text">"create a ticket"</span><span class="phrase-count">4+</span></div>
|
||||
<div class="phrase-chip"><span class="phrase-text">"reusable"</span><span class="phrase-count">19+</span></div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 7. Corrective Prompt -->
|
||||
<div class="section" style="margin-bottom: 64px;">
|
||||
<div class="action-panel">
|
||||
<div class="section-label">7. The corrective prompt</div>
|
||||
<div class="ap-intro">
|
||||
These 17 instructions were extracted directly from your denial patterns. Embedding them in a planning prompt would address approximately 70% of all denial reasons.
|
||||
</div>
|
||||
<div class="prompt-block">
|
||||
<div class="prompt-header">
|
||||
<span class="prompt-header-label">
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><polyline points="4 17 10 11 4 5"></polyline><line x1="12" y1="19" x2="20" y2="19"></line></svg>
|
||||
planning-instructions.md
|
||||
</span>
|
||||
<button class="copy-btn" onclick="copyPrompt(this)">
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><rect x="9" y="9" width="13" height="13" rx="2" ry="2"></rect><path d="M5 15H4a2 2 0 0 1-2-2V4a2 2 0 0 1 2-2h9a2 2 0 0 1 2 2v1"></path></svg>
|
||||
Copy
|
||||
</button>
|
||||
</div>
|
||||
<div class="prompt-body">
|
||||
<pre id="prompt-content"><span class="comment"># Planning Instructions
|
||||
# Derived from 370 files of denial & annotation analysis</span>
|
||||
|
||||
1. STRUCTURE: Every plan MUST begin with a "Solution Overview"
|
||||
containing 2-3 paragraphs of narrative prose explaining:
|
||||
- What exists today (current state)
|
||||
- What will change and why
|
||||
- How it will be built (approach summary)
|
||||
Do NOT skip this. Do NOT replace it with bullet points.
|
||||
|
||||
2. NARRATIVE: Every major section must include a rationale
|
||||
paragraph — not just what will be done, but WHY this
|
||||
approach was chosen over alternatives.
|
||||
|
||||
3. FEATURE BRANCH: Always specify implementation will occur
|
||||
on a feature branch. State the branch name. Never plan
|
||||
to work directly on main.
|
||||
|
||||
4. EXISTING PATTERNS: Before proposing any new implementation,
|
||||
search the codebase for existing patterns that solve the
|
||||
same problem. Explicitly state what you found and whether
|
||||
you will reuse it. Prefer reuse over new code.
|
||||
|
||||
5. CONFIDENCE STATEMENT: End the plan with a "Confidence
|
||||
Assessment" section. State your confidence level, identify
|
||||
risks or edge cases, and note uncertainties. Do not wait
|
||||
to be asked.
|
||||
|
||||
6. PHASING: For plans with more than 3 steps, break them into
|
||||
numbered phases. After each phase, note "Pause for
|
||||
evaluation" so the reviewer can assess before proceeding.
|
||||
|
||||
7. ISSUE TRACKING: If the project uses Linear or GitHub Issues,
|
||||
include a step to create relevant tickets BEFORE
|
||||
implementation. Backlog items should be separate tickets.
|
||||
|
||||
8. SIMPLICITY: Choose the simplest approach that meets
|
||||
requirements. Do not introduce modifier keys when hover
|
||||
works. Do not build a framework when a README suffices.
|
||||
|
||||
9. NAMING: Use explicit, transparent names for user-facing
|
||||
features. Do not euphemize Git operations ("Git Add"
|
||||
not "Accept"). Match existing product naming conventions.
|
||||
|
||||
10. CODE QUALITY: State that implementation will follow clean
|
||||
code principles: modular architecture, separation of
|
||||
concerns, no circumventing lint or type checks.
|
||||
|
||||
11. CLEAN FOUNDATION: If the codebase has failing lint or type
|
||||
checks, address these BEFORE proposing new features. State
|
||||
the current CI/CD state.
|
||||
|
||||
12. PRIVACY: For features involving data storage or sharing,
|
||||
explicitly state privacy guarantees. Require user
|
||||
confirmation before storing data.
|
||||
|
||||
13. EXAMPLES: When the plan involves user-facing output or UI,
|
||||
include an example of what it will look like.
|
||||
|
||||
14. FOCUSED SCOPE: Do not include sections that are obvious,
|
||||
boilerplate, or previously asked to be removed. Keep the
|
||||
plan focused rather than comprehensive.
|
||||
|
||||
15. DESIGN SKILL: For any frontend/UI work, invoke the
|
||||
front-end design skill to validate the approach. Note
|
||||
this invocation explicitly in the plan.
|
||||
|
||||
16. VERIFICATION STEP: For refactors or multi-file changes,
|
||||
include a verification step with line-by-line comparison
|
||||
of affected code paths.
|
||||
|
||||
17. DELIBERATION: If the plan involves a dramatic shift, state
|
||||
that you have re-evaluated the approach, traced through
|
||||
affected files mentally, and are confident in the plan.
|
||||
Do not rush.</pre>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="glow-wrap">
|
||||
<div class="glow-bg"></div>
|
||||
<div class="glow-card">
|
||||
<div class="gc-text">
|
||||
These instructions are yours — derived from <em>your feedback, your language, your standards</em>. Copy them into your planning prompt and watch the deny rate drop.
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<footer>
|
||||
<p>Analysis of 202 denied plans and 168 annotation files from the Plannotator archive.</p>
|
||||
</footer>
|
||||
|
||||
</div>
|
||||
|
||||
<script>
|
||||
function copyPrompt(btn) {
|
||||
const text = document.getElementById('prompt-content').textContent;
|
||||
navigator.clipboard.writeText(text).then(() => {
|
||||
btn.innerHTML = '<svg xmlns="http://www.w3.org/2000/svg" width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M22 11.08V12a10 10 0 1 1-5.93-9.14"></path><polyline points="22 4 12 14.01 9 11.01"></polyline></svg> Copied';
|
||||
btn.classList.add('copied');
|
||||
setTimeout(() => {
|
||||
btn.innerHTML = '<svg xmlns="http://www.w3.org/2000/svg" width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><rect x="9" y="9" width="13" height="13" rx="2" ry="2"></rect><path d="M5 15H4a2 2 0 0 1-2-2V4a2 2 0 0 1 2-2h9a2 2 0 0 1 2 2v1"></path></svg> Copy';
|
||||
btn.classList.remove('copied');
|
||||
}, 2000);
|
||||
});
|
||||
}
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
@@ -224,6 +224,45 @@ echo Address the annotation feedback above. The user has reviewed your last mess
|
||||
|
||||
echo Installed /plannotator-last command to !CLAUDE_COMMANDS_DIR!\plannotator-last.md
|
||||
|
||||
REM Install skills (requires git)
|
||||
where git >nul 2>&1
|
||||
if !ERRORLEVEL! equ 0 (
|
||||
if defined CLAUDE_CONFIG_DIR (
|
||||
set "CLAUDE_SKILLS_DIR=%CLAUDE_CONFIG_DIR%\skills"
|
||||
) else (
|
||||
set "CLAUDE_SKILLS_DIR=%USERPROFILE%\.claude\skills"
|
||||
)
|
||||
if defined XDG_CONFIG_HOME (
|
||||
set "AGENTS_SKILLS_DIR=%XDG_CONFIG_HOME%\agents\skills"
|
||||
) else (
|
||||
set "AGENTS_SKILLS_DIR=%USERPROFILE%\.config\agents\skills"
|
||||
)
|
||||
set "SKILLS_TMP=%TEMP%\plannotator-skills-%RANDOM%"
|
||||
mkdir "!SKILLS_TMP!" >nul 2>&1
|
||||
|
||||
git clone --depth 1 --filter=blob:none --sparse "https://github.com/!REPO!.git" --branch "!TAG!" "!SKILLS_TMP!\repo" >nul 2>&1
|
||||
if !ERRORLEVEL! equ 0 (
|
||||
pushd "!SKILLS_TMP!\repo"
|
||||
git sparse-checkout set apps/skills >nul 2>&1
|
||||
|
||||
if exist "apps\skills" (
|
||||
if not exist "!CLAUDE_SKILLS_DIR!" mkdir "!CLAUDE_SKILLS_DIR!"
|
||||
if not exist "!AGENTS_SKILLS_DIR!" mkdir "!AGENTS_SKILLS_DIR!"
|
||||
xcopy /s /y /q "apps\skills\*" "!CLAUDE_SKILLS_DIR!\" >nul 2>&1
|
||||
xcopy /s /y /q "apps\skills\*" "!AGENTS_SKILLS_DIR!\" >nul 2>&1
|
||||
echo Installed skills to !CLAUDE_SKILLS_DIR!\ and !AGENTS_SKILLS_DIR!\
|
||||
)
|
||||
|
||||
popd
|
||||
) else (
|
||||
echo Skipping skills install ^(git sparse-checkout failed^)
|
||||
)
|
||||
|
||||
rmdir /s /q "!SKILLS_TMP!" >nul 2>&1
|
||||
) else (
|
||||
echo Skipping skills install ^(git not found^)
|
||||
)
|
||||
|
||||
echo.
|
||||
echo Test the install:
|
||||
echo echo {"tool_input":{"plan":"# Test Plan\\n\\nHello world"}} ^| plannotator
|
||||
|
||||
@@ -217,6 +217,39 @@ description: Annotate the last assistant message
|
||||
|
||||
Write-Host "Installed /plannotator-last command to $opencodeCommandsDir\plannotator-last.md"
|
||||
|
||||
# Install skills (requires git)
|
||||
if (Get-Command git -ErrorAction SilentlyContinue) {
|
||||
$claudeSkillsDir = if ($env:CLAUDE_CONFIG_DIR) { "$env:CLAUDE_CONFIG_DIR\skills" } else { "$env:USERPROFILE\.claude\skills" }
|
||||
$agentsSkillsDir = if ($env:XDG_CONFIG_HOME) { "$env:XDG_CONFIG_HOME\agents\skills" } else { "$env:USERPROFILE\.config\agents\skills" }
|
||||
$skillsTmp = Join-Path ([System.IO.Path]::GetTempPath()) "plannotator-skills-$(Get-Random)"
|
||||
New-Item -ItemType Directory -Force -Path $skillsTmp | Out-Null
|
||||
|
||||
try {
|
||||
git clone --depth 1 --filter=blob:none --sparse "https://github.com/$repo.git" --branch $latestTag "$skillsTmp\repo" 2>$null
|
||||
Push-Location "$skillsTmp\repo"
|
||||
git sparse-checkout set apps/skills 2>$null
|
||||
|
||||
if (Test-Path "apps\skills") {
|
||||
$items = Get-ChildItem "apps\skills" -ErrorAction SilentlyContinue
|
||||
if ($items) {
|
||||
New-Item -ItemType Directory -Force -Path $claudeSkillsDir | Out-Null
|
||||
New-Item -ItemType Directory -Force -Path $agentsSkillsDir | Out-Null
|
||||
Copy-Item -Recurse -Force "apps\skills\*" $claudeSkillsDir
|
||||
Copy-Item -Recurse -Force "apps\skills\*" $agentsSkillsDir
|
||||
Write-Host "Installed skills to $claudeSkillsDir\ and $agentsSkillsDir\"
|
||||
}
|
||||
}
|
||||
|
||||
Pop-Location
|
||||
} catch {
|
||||
Write-Host "Skipping skills install (git sparse-checkout failed)"
|
||||
}
|
||||
|
||||
Remove-Item -Recurse -Force $skillsTmp -ErrorAction SilentlyContinue
|
||||
} else {
|
||||
Write-Host "Skipping skills install (git not found)"
|
||||
}
|
||||
|
||||
Write-Host ""
|
||||
Write-Host "=========================================="
|
||||
Write-Host " OPENCODE USERS"
|
||||
|
||||
@@ -213,6 +213,33 @@ COMMAND_EOF
|
||||
|
||||
echo "Installed /plannotator-last command to ${OPENCODE_COMMANDS_DIR}/plannotator-last.md"
|
||||
|
||||
# Install skills (requires git)
|
||||
if command -v git &>/dev/null; then
|
||||
CLAUDE_SKILLS_DIR="${CLAUDE_CONFIG_DIR:-$HOME/.claude}/skills"
|
||||
AGENTS_SKILLS_DIR="${XDG_CONFIG_HOME:-$HOME/.config}/agents/skills"
|
||||
skills_tmp=$(mktemp -d)
|
||||
|
||||
if git clone --depth 1 --filter=blob:none --sparse \
|
||||
"https://github.com/${REPO}.git" --branch "$latest_tag" "$skills_tmp/repo" 2>/dev/null && \
|
||||
cd "$skills_tmp/repo" && git sparse-checkout set apps/skills 2>/dev/null; then
|
||||
|
||||
if [ -d "apps/skills" ] && [ "$(ls -A apps/skills 2>/dev/null)" ]; then
|
||||
mkdir -p "$CLAUDE_SKILLS_DIR" "$AGENTS_SKILLS_DIR"
|
||||
cp -r apps/skills/* "$CLAUDE_SKILLS_DIR/"
|
||||
cp -r apps/skills/* "$AGENTS_SKILLS_DIR/"
|
||||
echo "Installed skills to ${CLAUDE_SKILLS_DIR}/ and ${AGENTS_SKILLS_DIR}/"
|
||||
fi
|
||||
|
||||
cd - >/dev/null
|
||||
else
|
||||
echo "Skipping skills install (git sparse-checkout failed)"
|
||||
fi
|
||||
|
||||
rm -rf "$skills_tmp"
|
||||
else
|
||||
echo "Skipping skills install (git not found)"
|
||||
fi
|
||||
|
||||
echo ""
|
||||
echo "=========================================="
|
||||
echo " OPENCODE USERS"
|
||||
|
||||
@@ -52,6 +52,14 @@ describe("install.sh", () => {
|
||||
expect(script).toContain('"command".*plannotator');
|
||||
});
|
||||
|
||||
test("installs skills via git sparse-checkout", () => {
|
||||
expect(script).toContain("git clone --depth 1 --filter=blob:none --sparse");
|
||||
expect(script).toContain("git sparse-checkout set apps/skills");
|
||||
expect(script).toContain("CLAUDE_SKILLS_DIR");
|
||||
expect(script).toContain("AGENTS_SKILLS_DIR");
|
||||
expect(script).toContain('Skipping skills install (git not found)');
|
||||
});
|
||||
|
||||
test("installs slash commands for Claude Code and OpenCode", () => {
|
||||
expect(script).toContain("plannotator-review.md");
|
||||
expect(script).toContain("plannotator-annotate.md");
|
||||
@@ -97,6 +105,14 @@ describe("install.ps1", () => {
|
||||
expect(script).toContain("DUPLICATE HOOK DETECTED");
|
||||
});
|
||||
|
||||
test("installs skills via git sparse-checkout", () => {
|
||||
expect(script).toContain("git clone --depth 1 --filter=blob:none --sparse");
|
||||
expect(script).toContain("git sparse-checkout set apps/skills");
|
||||
expect(script).toContain("claudeSkillsDir");
|
||||
expect(script).toContain("agentsSkillsDir");
|
||||
expect(script).toContain('Skipping skills install (git not found)');
|
||||
});
|
||||
|
||||
test("installs slash commands", () => {
|
||||
expect(script).toContain("plannotator-review.md");
|
||||
expect(script).toContain("plannotator-annotate.md");
|
||||
@@ -137,6 +153,14 @@ describe("install.cmd", () => {
|
||||
expect(script).toContain("DUPLICATE HOOK DETECTED");
|
||||
});
|
||||
|
||||
test("installs skills via git sparse-checkout", () => {
|
||||
expect(script).toContain("git clone --depth 1 --filter=blob:none --sparse");
|
||||
expect(script).toContain("git sparse-checkout set apps/skills");
|
||||
expect(script).toContain("CLAUDE_SKILLS_DIR");
|
||||
expect(script).toContain("AGENTS_SKILLS_DIR");
|
||||
expect(script).toContain("Skipping skills install");
|
||||
});
|
||||
|
||||
test("installs slash commands", () => {
|
||||
expect(script).toContain("plannotator-review.md");
|
||||
expect(script).toContain("plannotator-annotate.md");
|
||||
|
||||
Reference in New Issue
Block a user