Pin session decisions, questions, objections, scope constraints, and corrections to a persistent board that survives context compaction. Use PROACTIVELY when: (1) user approves/rejects a recommendation, (2) user asks a clarifying question about a proposal, (3) user states a scope constraint, (4) user corrects a misunderstanding. Also use when user says pin, track this, mark as approved, board, show pins. Auto-invoke without user asking whenever a decision, question, or constraint is detected.
84%
Does it follow best practices?
Run evals on this skill
Adds up to 20 points to the overall score
Passed
No findings from the security scan
Persist decisions, questions, constraints, and corrections to a JSON file that survives context compaction. A companion hook injects the board into every tool call so the model never forgets.
After responding to any user message where a decision was made, a question was asked about a proposal, or a constraint was stated, IMMEDIATELY invoke /pin with the appropriate category. Do not ask permission — just pin it.
Examples of auto-invoke triggers:
/pin ✅ use bun/pin ❓ split services — latency impact?/pin ❌ auth layer — skip for MVP/pin 📌 MVP only, max 3 files/pin 🔧 target = artisans, not developersDo NOT pin:
| Command | Action |
|---|---|
/pin ✅ <text> | Pin approved item |
/pin ❓ <text> | Pin pending question |
/pin ❌ <text> | Pin killed/rejected item |
/pin 📌 <text> | Pin scope constraint |
/pin 🔧 <text> | Pin correction |
/pin show or /pin | Display current board |
/pin rm <n> | Remove pin by number |
/pin clear | Clear all pins |
/pin clear triage | Clear ✅/❓ only, keep 📌/❌/🔧 |
Path: a session-scoped .session-logs/<slug>/pins.json file under a configurable base directory.
Derive slug from CWD:
GIT_ROOT=$(git rev-parse --show-toplevel 2>/dev/null)
REL_PATH="${PWD#$GIT_ROOT/}"
SLUG=$(echo "$REL_PATH" | tr '/' '-')
PINS_DIR="$PRAXIS_DIR/.session-logs/$SLUG"
PINS_FILE="$PINS_DIR/pins.json"Schema:
{
"items": [
{
"id": 1,
"type": "approved",
"emoji": "✅",
"content": "use bun everywhere",
"detail": "",
"ts": "2026-04-01T14:30:00Z"
}
],
"next_id": 2
}Type mapping: ✅=approved, ❓=pending, ❌=killed, 📌=scope, 🔧=correction
/pin <emoji> <text>)Parse the emoji prefix to determine type. Text after emoji is content. If text contains —, split into content and detail.
PINS_FILE path (see State File above)mkdir -p the directory{"items":[],"next_id":1}⚠️ Already pinned. and stopid=next_id, increment next_id📌 Pinned #N: <emoji> <content> — one line only, then resume prior work/pin show or /pin)PINS_FILE📋 Pin board is empty.📋 Pin Board (5 items)
1. ✅ use bun everywhere (minor: keep fallback for CI)
2. ✅ split the PR into 2
3. ❓ split services — latency impact?
4. ❌ auth rewrite — out of MVP scope
5. 📌 MVP only, max 3 files/pin rm <n>)If no number: ⚠️ Usage: /pin rm <number>
PINS_FILE, find item with id === n⚠️ Pin #N not found.🗑️ Pin #N removed./pin clear){"items":[],"next_id":<keep current next_id>}🗑️ Pin board cleared./pin clear triage)approved or pendingkilled, scope, or correction🗑️ Triage cleared. <N> pins remaining.The pin board is a capture tool, not a management tool. Its only job is to hold decisions and constraints in a persistent, queryable form so that context compaction does not erase them. ALWAYS treat the board as a write-once, append-only record during a session — edits and removals are operations of last resort, not routine cleanup. A well-run session generates fewer than 20 pins; if you hit the limit frequently, the signals are too granular.
next_id always increments, never reuses.📌 MVP only, max 3 files has the emoji as a 2-byte or 4-byte sequence; naive cut -d' ' will misparse on some shells.WHY: rewording introduces your interpretation and erases the original mental model; future agents will read the pin as authoritative, not as a paraphrase.
BAD: user says "no I meant artisans not developers" and you pin "refine target persona".
GOOD: pin 🔧 target = artisans, not developers using the user's own wording.
WHY: flooding the board with low-signal items makes it harder to spot the constraints that actually govern future choices.
BAD: /pin ✅ renamed helper in utils.ts.
GOOD: pin only decisions, constraints, questions, and corrections.
WHY: this skill is a capture tool; any extra output derails the primary conversation and signals that the board matters more than the user's task.
BAD: 📌 Pinned #3 ... followed by a paragraph on why the pin matters.
GOOD: one line, then resume prior work.
WHY: stable numbering prevents confusion when users reference pins by number across a session; id recycling silently corrupts that contract.
BAD: renumber the remaining pins after /pin rm 2, or reset next_id.
GOOD: leave gaps and let next_id only ever increment.
WHY: duplicate pins create a false picture of the decision count and waste the 20-item budget on noise.
BAD: append the same content a second time.
GOOD: compare incoming content against existing items and respond ⚠️ Already pinned. on a match.
WHY: the skill is auto-invoked; asking turns a silent capture into an interruption and the decision may be lost to compaction.
BAD: "Should I pin this?" after the user approves a recommendation.
GOOD: respond normally, then pin immediately with the right category.
WHY: greetings and repeats add noise and consume the per-type and total limits.
BAD: pin "thanks, sounds good" as an approval.
GOOD: check the board first and pin only genuine decisions and constraints.
WHY: /pin clear triage removes only approved and pending items, so a mistyped constraint can be wiped while a decision is kept.
BAD: pin a scope constraint with ✅.
GOOD: map ✅ approved, ❓ pending, ❌ killed, 📌 scope, 🔧 correction.
WHY: the pin is a side effect; the user's actual task is still waiting.
BAD: end the turn after 📌 Pinned #N.
GOOD: resume the prior work exactly where it left off.
Pinning a scope constraint mid-session:
# User says: "Keep this MVP only, no more than 3 new files"
/pin 📌 MVP only, max 3 files
# Response: 📌 Pinned #1: 📌 MVP only, max 3 files
# Session resumes immediately from where it left offPinning a decision reversal and viewing the board:
# User says: "Actually use PostgreSQL, not SQLite"
/pin 🔧 target database = PostgreSQL, not SQLite
# Response: 📌 Pinned #2: 🔧 target database = PostgreSQL, not SQLite
# Later: review all active pins
/pin show
# Response:
# 📋 Pin Board (2 items)
# 1. 📌 MVP only, max 3 files
# 2. 🔧 target database = PostgreSQL, not SQLitePinning an unresolved question and clearing triage items after resolution:
# Unresolved question surfaces during design
/pin ❓ split services — will latency exceed 200ms SLA?
# Response: 📌 Pinned #3: ❓ split services — will latency exceed 200ms SLA?
# After the question is answered, clear only approved/pending pins
/pin clear triage
# Response: 🗑️ Triage cleared. 1 pin remaining.| Topic | Reference | When to Use |
|---|---|---|
Read-only checks on pins.json | references/inspecting-the-board.md | Verifying limits, duplicates, and numbering before or after a write |
| Edge-case responses | references/edge-cases.md | Handling missing ids, full categories, and empty boards |
pantheon-org/tekhne
c8416e9
Also appears in
last in sync Aug 28, 2026
If you maintain this skill, you can claim it as your own. Once claimed, you can manage eval scenarios, bundle related skills, attach documentation or rules, and ensure cross-agent compatibility.