Install any skill in seconds. Free to start, no credit card required.
Get Started Free →Search and record project memory (Discussions, journal, ADRs). Use before re-investigating anything. Do not use for settled battles; see failure-archaeology.
.claude/skills/athola-night-market-collective-memory/SKILL.md| Test case | Without → With | Effect | Δ tokens | Δ turns |
|---|---|---|---|---|
| case-11 | ✗→✓ | ▲ Improved | 179% | 0% |
| case-12 | ✗→✓ | ▲ Improved | 157% | 0% |
| case-05 | ✗→✓ | ▲ Improved | 17% | 0% |
| case-06 | ✗→✓ | ▲ Improved | 1631% | 0% |
| case-09 | ✗→✓ | ▲ Improved | 190% | 0% |
This repo treats GitHub Discussions as agent collective memory (ADR-0007, docs/adr/0007-github-discussions-integration.md, accepted 2026-02-19). Sessions are amnesiac by default. The memory system fixes that with four layers: Discussions (cross-session, searchable), the decision journal (append-only tradeoff and lesson logs), numbered ADRs (architecture decisions), and dated research syntheses in docs/research/. One caveat on the fourth layer: docs/research/ is gitignored and machine-local, so it exists only on the authoring machine and is empty on fresh clones. A synthesis counts as collective memory only after promotion to a Discussion, ADR, or rule. This skill tells you where each kind of knowledge lives, how to read it, and how to write to it.
One hard fact first: there is NO gh discussion subcommand. Discussions are GraphQL-only. Minister playbooks once referenced a CLI that does not exist, and ADR-0007 replaced every reference with gh api graphql calls. Never guess a gh discussion command.
| You have | Record or read it via | |----------|----------------------| | Settled battle, revert, dead end | night-market-failure-archaeology skill (read only, do not relitigate) | | Tradeoff (chose A, sacrificed B) | Decision journal docs/tradeoffs.md, TR-NNN entry | | Lesson, failed approach, rework | Decision journal docs/lessons-learned.md, LL-NNN entry | | Architecture decision | Numbered ADR in docs/adr/ (0001-0017 exist today) | | Session insight, skill stats | [Learning] Discussion (auto-posted daily, see below) | | Strategy debate, big design | [War Room] Discussion (Decisions category) | | Durable synthesis, audit result | [Knowledge] Discussion (Knowledge category) | | PR review finding worth keeping | [PR Finding] Discussion (Learnings category) | | Multi-source research output | Dated file in docs/research/ (LOCAL ONLY: gitignored, absent on fresh clones). Promote durable syntheses to a [Knowledge] Discussion, ADR, or rule to make them collective memory |
Before investigating any question about this repo's history, design, or past failures, run these searches first. Re-deriving a settled answer wastes a session and risks contradicting an accepted decision.
bash# 1. Search Discussions by keyword (tested 2026-07-02) gh api graphql -f query=' query($q: String!) { search(query: $q, type: DISCUSSION, first: 10) { nodes { ... on Discussion { number title url category { name } } } } }' -f q='repo:athola/claude-night-market YOUR SEARCH TERMS' # 2. Search local docs of record. Note: docs/research/ is gitignored # and machine-local, so it is empty on fresh clones and this # search only helps on the authoring machine. rg -il "your terms" docs/research/ docs/adr/ CHANGELOG.md # 3. Check the decision journal (if the files exist yet, see below) rg -in "your terms" docs/tradeoffs.md docs/lessons-learned.md
Also check the night-market-failure-archaeology sibling for settled battles. A leyline SessionStart hook (plugins/leyline/hooks/fetch-recent-discussions.sh) already injects the 5 most recent Decisions discussions at session start, bounded to under 600 tokens with a 3-second timeout.
Repo categories include the four ADR-0007 ones (Decisions, Deliberations, Learnings, Knowledge) plus GitHub defaults. Title prefixes are the working taxonomy:
| Prefix | Category | What it is | Verified examples | |--------|----------|------------|-------------------| | [Learning] | Learnings | Daily digest, auto-posted | #601, #602 (2026-07-01/02) | | [Knowledge] | Knowledge | Durable syntheses | #448, #449 (April 2026 skill audit synthesis and Wave-3 backlog) | | [War Room] | Decisions | Strategy deliberations | #222 (collective memory design), #271 (wiring publishing into workflows) | | [PR Finding] | Learnings | Review findings worth keeping | #424, #595 |
Daily digests are auto-posted by abstract's Stop hook, part of the improvement feedback loop (Issue #69). The chain:
plugins/abstract/hooks/skill_execution_logger.py(PreToolUse/PostToolUse) logs skill executions.
plugins/abstract/scripts/aggregate_skill_logs.py writes~/.claude/skills/LEARNINGS.md with skill-performance stats (skills analyzed, high-impact issues, slow and low-rated skills).
plugins/abstract/hooks/post_learnings_stop.py (Stop hook,registered in plugins/abstract/hooks/hooks.json) posts a [Learning] YYYY-MM-DD digest, deduplicated by title. Opt-out: ~/.claude/skills/discussions/config.json.
discussion promote it to a GitHub Issue via plugins/abstract/scripts/promote_discussion_to_issue.py (default threshold 3, configurable via promotion_threshold).
List recent discussions, newest first (tested 2026-07-02, returned #602 and siblings):
bashgh api graphql -f query=' query($owner: String!, $name: String!) { repository(owner: $owner, name: $name) { discussions(first: 10, orderBy: {field: CREATED_AT, direction: DESC}) { nodes { number title category { name } createdAt url } } } }' -f owner=athola -f name=claude-night-market
Fetch one discussion by number. The number is a GraphQL Int, so pass it with -F (typed), not -f (string). Passing -f fails with a type error:
bashgh api graphql -f query=' query($owner: String!, $name: String!, $number: Int!) { repository(owner: $owner, name: $name) { discussion(number: $number) { title body url category { name } comments(first: 10) { nodes { body } } } } }' -f owner=athola -f name=claude-night-market -F number=222
Publishing rules from ADR-0007: prompt the user [Y/n] before any create or comment (no auto-publish), cap bodies at 2000 words and link to local files for detail, and pass all values as -f/-F variables (never string-interpolate into the query).
Mutations need node IDs. Resolve them first (this read query was tested 2026-07-02):
bashgh api graphql -f query=' query($owner: String!, $repo: String!) { repository(owner: $owner, name: $repo) { id hasDiscussionsEnabled discussionCategories(first: 25) { nodes { id name slug } } } }' -f owner=athola -f repo=claude-night-market
Create a comment (mutation shape from the canonical leyline templates, untested here to avoid posting):
bashgh api graphql -f query=' mutation($discussionId: ID!, $body: String!) { addDiscussionComment(input: { discussionId: $discussionId, body: $body }) { comment { id url } } }' -f discussionId="$DISCUSSION_ID" -f body="$COMMENT_BODY"
Creating a discussion uses createDiscussion(input: {repositoryId, categoryId, title, body}) (same status: shape verified against the canonical templates, untested here). For threaded replies, mark-as- answer, and updates, use the canonical template file: plugins/leyline/skills/git-platform/modules/command-mapping.md, section "Discussion Operations". GitHub only: GitLab and Bitbucket have no Discussions equivalent, so skip with a warning there.
The contract lives in plugins/leyline/skills/decision-journal/SKILL.md. Two append-only logs, co-located with the code:
docs/tradeoffs.md: decisions and the alternatives sacrificed.Entry IDs TR-NNN, status proposed, then accepted, then superseded-by: TR-NNN or deprecated.
docs/lessons-learned.md: failed approaches and rework, framedblamelessly. Entry IDs LL-NNN, status open, then actioned, then closed.
Discipline: append-only, never edit or delete an accepted entry. A reversal adds a new entry, flips the old one's status, and links both ways. Every entry links to its PR, commit, or issue. Draft the entry, show it to the human, and append only on confirm.
Status as of 2026-07-02: neither docs/tradeoffs.md nor docs/lessons-learned.md exists in the repo yet. The contract is defined and the files are created on first use (scaffolding belongs to attune:project-init). The append helper:
bashpython3 plugins/leyline/scripts/journal_append.py tradeoffs \ --project-root . --title "Compliance check" \ --field context="verify" --dry-run
Big decisions do not go in the journal. They get a numbered ADR in docs/adr/, and a journal entry may reference the ADR number.
If the newest [Learning] discussion is more than about 2 days old, treat it as an incident signal. Precedent: the digest was once starved for two months because hooks read CLAUDE_TOOL_* env vars Claude Code never sets, and the missing digest was the only visible symptom (full record: night-market-failure-archaeology SB9; fix: stdin-first shared/hook_io.read_hook_payload, CHANGELOG 1.9.14).
Check the gap with the tested list query above. If starved, verify each chain segment in order: is ~/.claude/skills/LEARNINGS.md fresh, is the Stop hook registered in plugins/abstract/hooks/hooks.json, and does the logger receive a stdin payload. Then follow night-market-debugging-playbook for hook triage.
re-try: read night-market-failure-archaeology instead.
night-market-change-control.
docs/research/ syntheses: use night-market-research-methodology. This skill only covers where the outputs are stored and retrieved.
night-market-docs-and-writing.
docs/research/ search ran, and hits (or "no hits") were stated.
gh api graphql. Zerogh discussion invocations appear in the transcript.
named before writing anything).
an index row, and no prior entry was edited or deleted.
first, and used -f/-F variables (no string interpolation).
[Learning] digest date was checked, and any gapover 2 days was reported as a starvation alert.
Compiled 2026-07-02 against repo v1.9.15, branch discussions-fix-1.9.14. Read queries in this file were executed live against athola/claude-night-market on 2026-07-02. Mutation snippets were checked against the leyline templates but not executed.
Re-verification one-liners for facts that may drift:
bash# Taxonomy and digest freshness (also the starvation check) gh api graphql -f query='query($o:String!,$n:String!){repository(owner:$o,name:$n){discussions(first:5,orderBy:{field:CREATED_AT,direction:DESC}){nodes{number title createdAt}}}}' -f o=athola -f n=claude-night-market # Decision journal files exist yet? ls docs/tradeoffs.md docs/lessons-learned.md # Promotion threshold still 3 fire reactions? rg -n "promotion_threshold" plugins/abstract/scripts/promote_discussion_to_issue.py # Stop hook still registered? rg -n "post_learnings_stop" plugins/abstract/hooks/hooks.json # Canonical GraphQL templates still present? rg -n "Discussion Operations" plugins/leyline/skills/git-platform/modules/command-mapping.md # ADR count and 0007 status ls docs/adr/ && rg -n "^Accepted" docs/adr/0007-github-discussions-integration.md
| Case | Status | Duration (ms) | Turns | Tokens | Tool calls | ||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| Without | With | Δ | Without | With | Δ | Without | With | Δ | Without | With | Δ | ||
case-11 | fail→pass | 9,206 | 7,030 | -24% | 1 | 1 | 0% | 1,475 | 4,111 | +179% | 0 | 0 | — |
case-12 | fail→pass | 10,786 | 6,931 | -36% | 1 | 1 | 0% | 1,749 | 4,498 | +157% | 0 | 0 | — |
case-01 | fail→fail | 32,463 | 8,138 | -75% | 1 | 1 | 0% | 910 | 3,850 | +323% | 0 | 0 | — |
case-13 | pass→pass | 13,891 | 4,664 | -66% | 1 | 1 | 0% | 2,085 | 4,233 | +103% | 0 | 0 | — |
case-02 | fail→fail | 7,161 | 8,205 | +15% | 1 | 1 | 0% | 467 | 3,844 | +723% | 0 | 0 | — |
case-03 | fail→fail | 9,643 | 12,443 | +29% | 1 | 1 | 0% | 1,463 | 4,377 | +199% | 0 | 0 | — |
case-04 | fail→fail | 10,492 | 9,445 | -10% | 1 | 1 | 0% | 1,621 | 3,931 | +143% | 0 | 0 | — |
case-05 | fail→pass | 23,723 | 9,203 | -61% | 1 | 1 | 0% | 4,118 | 4,836 | +17% | 0 | 0 | — |
case-14 | pass→pass | 8,411 | 5,136 | -39% | 1 | 1 | 0% | 1,479 | 4,202 | +184% | 0 | 0 | — |
case-06 | fail→pass | 5,641 | 14,881 | +164% | 1 | 1 | 0% | 295 | 5,105 | +1631% | 0 | 0 | — |
case-07 | pass→pass | 8,738 | 4,030 | -54% | 1 | 1 | 0% | 1,548 | 4,119 | +166% | 0 | 0 | — |
case-08 | fail→fail | 9,851 | 5,475 | -44% | 1 | 1 | 0% | 1,624 | 4,207 | +159% | 0 | 0 | — |
case-09 | fail→pass | 9,154 | 5,288 | -42% | 1 | 1 | 0% | 1,466 | 4,249 | +190% | 0 | 0 | — |
case-10 | fail→pass | 6,248 | 4,133 | -34% | 1 | 1 | 0% | 1,106 | 4,087 | +270% | 0 | 0 | — |
case-15 | fail→pass | 4,279 | 4,835 | +13% | 1 | 1 | 0% | 675 | 4,188 | +520% | 0 | 0 | — |
case-16 | pass→pass | 8,862 | 5,878 | -34% | 1 | 1 | 0% | 1,471 | 4,371 | +197% | 0 | 0 | — |
case-17 | fail→pass | 20,052 | 2,043 | -90% | 1 | 1 | 0% | 1,338 | 3,647 | +173% | 0 | 0 | — |
case-18 | fail→pass | 11,611 | 5,438 | -53% | 1 | 1 | 0% | 1,784 | 4,259 | +139% | 0 | 0 | — |
case-19 | fail→pass | 8,044 | 3,946 | -51% | 1 | 1 | 0% | 1,442 | 4,081 | +183% | 0 | 0 | — |
case-20 | fail→pass | 13,950 | 6,428 | -54% | 1 | 1 | 0% | 2,192 | 4,503 | +105% | 0 | 0 | — |
case-21 | fail→pass | 7,610 | 3,064 | -60% | 1 | 1 | 0% | 1,156 | 3,773 | +226% | 0 | 0 | — |
case-22 | fail→fail | 13,726 | 3,841 | -72% | 1 | 1 | 0% | 2,130 | 3,991 | +87% | 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, and 18 counted toward the lift figure. The other 4 produced results that are not comparable between the two arms, so they are excluded from the headline rather than averaged into it. The headline lift of +55 percentage points is the difference between those two pass rates over the 18 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.