Install any skill in seconds. Free to start, no credit card required.
Get Started Free →Contract for the project decision journal (tradeoffs and lessons-learned logs). Use when recording a decision, tradeoff, or lesson, or building a consumer hook.
.claude/skills/athola-decision-journal/SKILL.md| Test case | Without → With | Effect | Δ tokens | Δ turns |
|---|---|---|---|---|
| case-02 | ✗→✓ | ▲ Improved | 106% | 0% |
| case-03 | ✗→✓ | ▲ Improved | 249% | 0% |
| case-01 | ✗→✓ | ▲ Improved | 230% | 0% |
| case-04 | ✗→✓ | ▲ Improved | 49% | 0% |
| case-07 | ✗→✓ | ▲ Improved | 85% | 0% |
what was chosen, what was rejected, what was sacrificed.
record the lesson.
attune:project-init).docs/adr/; reference its number from a journal entry instead of duplicating it.
This is a convention and a helper rather than a hard runtime dependency. Consumers degrade gracefully when leyline is absent (see Fallback).
AI-assisted work tends to narrate tool output ("the agent built X") and lose the human reasoning: the decision, the road not taken, and the honest rework nobody mentions. Two append-only logs, co-located with the code, fix that:
docs/tradeoffs.md records decisions and the alternatives sacrificed.docs/lessons-learned.md records insights, failed approaches, and rework,framed blamelessly.
Both files live in docs/ (co-location is the strongest anti-staleness lever). Each is a single append-only running log with a scannable ## Active index at the top and an ## Archive section at the bottom.
Status changes.
entry's status to superseded-by: <new-id>, and links both ways.
TR-001, LL-001) so links from PRs, commits, and codenever break.
Status vocabularies:
proposed -> accepted -> (superseded-by: TR-NNN | deprecated)open -> actioned -> closedWhen a workflow reaches a decision or lesson point:
what was given up, the failure and its root cause).
proposed; lessons start open.Do not auto-write without the confirm step. The point is to capture the human reasoning, not to generate noise.
Run the helper from leyline:
python3 ${LEYLINE}/scripts/journal_append.py <tradeoffs|lessons> \ --project-root <repo-root> \ --title "<short title>" \ --phase <phase>] --status <status>] \ --field key=value ...] \ --json '<full field object>'] \ --supersedes TR-NNN] \ --dry-run]
The helper assigns the next ID, renders the template, inserts the entry above the ## Archive marker, updates the active index, and (with --supersedes) flips the prior entry's status and adds backlinks. It is idempotent: appending an entry whose substantive fields already appear is a no-op.
title (required), context, drivers (list), options (list of {name, pros, cons, chosen}), decision, ystatement, consequences_positive, consequences_negative, phase, deciders, links. Prefer --json for the list-valued fields. status and date are auto-set (proposed / today) but can be overridden.
title (required), what_happened, what_went_well, what_didnt_work, root_cause, action, category, owner, phase, links. status and date are auto-set (open / today) but can be overridden.
The entry template ships inside each scaffolded file as an HTML-comment footer (<!-- ENTRY TEMPLATE ... -->). When the helper is unavailable, a consumer (or a human) copies that block into the section above ## Archive, assigns the next sequential ID, fills it in, and adds an index row by hand. The fallback template covers the same core sections as the canonical one so entries stay consistent across the two paths.
Each workflow adds one block at its natural endpoint:
Record to the decision journal (draft + confirm):
drafting fields from this phase's context; show the draft; append on confirm.
using the footer ENTRY TEMPLATE; assign the next sequential ID.
python3 ${LEYLINE}/scripts/journal_append.py tradeoffs \ --title "Compliance check" --field context="verify" --dry-run
Must print a rendered entry containing ## TR-001: and write nothing.
docs/tradeoffs.md and docs/lessons-learned.md exist with a## Active index and an ## Archive section.
TR-NNN/LL-NNN id and an index row.superseded-by: <id> andadds bidirectional links; the old entry is not deleted.
from the in-file ENTRY TEMPLATE.
The last criterion holds even for consumers that name leyline in their dependencies. That field is marketplace metadata; no installer acts on it, so spec-kit or imbue can be installed without leyline present. The fallback is the guard at that boundary, not leftover code. See docs/metadata.md, "What dependencies Does Not Mean".
| Case | Status | Duration (ms) | Turns | Tokens | Tool calls | ||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| Without | With | Δ | Without | With | Δ | Without | With | Δ | Without | With | Δ | ||
case-02 | fail→pass | 10,304 | 9,801 | -5% | 1 | 1 | 0% | 1,623 | 3,340 | +106% | 0 | 0 | — |
case-03 | fail→pass | 7,290 | 18,984 | +160% | 1 | 1 | 0% | 1,181 | 4,127 | +249% | 0 | 0 | — |
case-01 | fail→pass | 5,575 | 10,829 | +94% | 1 | 1 | 0% | 822 | 2,712 | +230% | 0 | 0 | — |
case-04 | fail→pass | 8,310 | 3,828 | -54% | 1 | 1 | 0% | 1,453 | 2,161 | +49% | 0 | 0 | — |
case-05 | pass→pass | 13,881 | 4,742 | -66% | 1 | 1 | 0% | 2,209 | 2,399 | +9% | 0 | 0 | — |
case-06 | pass→pass | 10,410 | 5,050 | -51% | 1 | 1 | 0% | 1,758 | 2,338 | +33% | 0 | 0 | — |
case-07 | fail→pass | 6,246 | 2,429 | -61% | 1 | 1 | 0% | 1,013 | 1,877 | +85% | 0 | 0 | — |
case-08 | fail→pass | 5,398 | 1,849 | -66% | 1 | 1 | 0% | 780 | 1,741 | +123% | 0 | 0 | — |
case-09 | pass→pass | 6,933 | 5,983 | -14% | 1 | 1 | 0% | 1,165 | 2,618 | +125% | 0 | 0 | — |
case-10 | fail→pass | 6,012 | 2,129 | -65% | 1 | 1 | 0% | 1,074 | 1,925 | +79% | 0 | 0 | — |
case-11 | fail→pass | 9,622 | 9,484 | -1% | 1 | 1 | 0% | 1,664 | 3,264 | +96% | 0 | 0 | — |
case-12 | fail→pass | 9,805 | 2,321 | -76% | 1 | 1 | 0% | 1,779 | 1,869 | +5% | 0 | 0 | — |
case-13 | pass→pass | 11,877 | 2,013 | -83% | 1 | 1 | 0% | 1,977 | 1,872 | -5% | 0 | 0 | — |
case-14 | pass→pass | 9,252 | 3,050 | -67% | 1 | 1 | 0% | 1,556 | 2,056 | +32% | 0 | 0 | — |
case-15 | pass→pass | 7,713 | 1,338 | -83% | 1 | 1 | 0% | 1,350 | 1,703 | +26% | 0 | 0 | — |
case-16 | pass→fail | 8,665 | 1,967 | -77% | 1 | 1 | 0% | 1,342 | 1,788 | +33% | 0 | 0 | — |
case-17 | fail→pass | 7,493 | 1,975 | -74% | 1 | 1 | 0% | 1,263 | 1,810 | +43% | 0 | 0 | — |
case-18 | pass→pass | 5,079 | 1,877 | -63% | 1 | 1 | 0% | 829 | 1,776 | +114% | 0 | 0 | — |
case-19 | fail→pass | 13,445 | 6,122 | -54% | 1 | 1 | 0% | 2,108 | 2,603 | +23% | 0 | 0 | — |
case-20 | fail→pass | 14,937 | 3,876 | -74% | 1 | 1 | 0% | 2,551 | 2,100 | -18% | 0 | 0 | — |
case-21 | fail→pass | 11,224 | 5,764 | -49% | 1 | 1 | 0% | 1,757 | 2,499 | +42% | 0 | 0 | — |
case-22 | fail→pass | 10,705 | 3,557 | -67% | 1 | 1 | 0% | 1,616 | 2,220 | +37% | 0 | 0 | — |
DecimalAI ran this skill against gemini-3.6-flash twice over the same eval suite — once with the skill loaded and once without — and compared the two runs case by case. 22 cases were attempted. The headline lift of +59 percentage points is the difference between those two pass rates over the 22 comparable cases. 1 case got worse with the skill loaded, and it is included in that figure.
Without the skill loaded, the model failed this case. With it loaded, the same prompt on the same model passed. This is one improved case from the latest verified run; every case, including any that regressed, is in the table above.
Other measured skills in the registry, with their headline benchmark lift.