Files
FabledScribe/plugin/skills/family-canon/SKILL.md
T
bvandeusenandClaude Opus 5.5 07e21c7ff9
CI & Build / Plugin hooks (push) Successful in 15s
CI & Build / Python lint (push) Successful in 2s
CI & Build / TypeScript typecheck (push) Successful in 54s
CI & Build / integration (push) Failing after 1m53s
CI & Build / Python tests (push) Successful in 2m39s
CI & Build / Build & push image (push) Skipped
feat(family): family canon reaches the session - entry readout, retrieval reach, skill, report cue (milestone 463 step 6, #4992)
- enter_project carries a `family` key, but only when the project has
  something to answer: counts of unassessed, owed and to-recheck answers,
  each with the list_family_adoptions call that lists it. It shows on every
  entry, never by platform touch: entry is when work is chosen, and an
  unanswered idea is otherwise invisible.
- Retrieval: a widened project search (include_global_kinds) now also
  reaches the canon ideas on the project's platforms. It also reaches their
  references in the project's languages, or all of them when none matches.
  An off-platform project gets none, and the plain project filter (the
  duplicate gate) is unchanged.
- Closing a task returns `family_owed`, the owed answers filed while it was
  open, and the report cue asks for them to be named.
- New plugin skill family-canon (moment work.record) covers when to
  evaluate a promotion, answering in order, what counts as a reason, the
  precedent reflex and the conflict order. _INSTRUCTIONS, create_note,
  create_snippet, classify_shapes and reporting-back point at it.
  The plugin version is minted.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-06 13:27:39 -04:00

94 lines
4.9 KiB
Markdown

---
name: family-canon
description: Use when family canon reaches the session — a `family_hint` on a create (a record may be a pattern every project on a platform will need), a `family` key from enter_project (ideas this project has not answered, owes, or must recheck), a `family_owed` list when a task closes, or the operator asks whether a pattern is shared between projects. Triggers on "family", "shared between projects", "promote", "canon idea", "owed", "adopt", "every Android app", "every project on".
metadata:
moments: work.record
---
# Family canon — good ideas spread by criteria, not by approval
Some patterns are not one app's: every project on a platform meets the same
problem (an Android app that ships its own APK, a Go service behind a
reverse proxy). Family canon is how such an idea is recorded once, reaches
every project on that platform, and gets an answer from each. Nobody
approves anything. **You decide, against written criteria, and the decision
log keeps you consistent with the last decision like it.** The tools quote
the criteria, the outcomes and the conflict order in full; this skill is when
to reach for them and what a good answer looks like.
The shape is the point, not identical code: the same idea in Kotlin and in
Go is one idea with two reference implementations.
## When an idea is evaluated for promotion
A `family_hint` on a create_note / create_snippet response means a trigger
opened an evaluation: the record cites another project's record as its
source, or it repeats a record in a project on a shared platform. The source
is now a `candidate`. Evaluate it in the same turn, while you know why you
wrote what you wrote:
1. `get_family_idea(id)` — the candidate, its decisions, and the precedents
(decisions on the ideas nearest it).
2. Judge the three criteria from `promote_family_idea`'s description. Each
needs support you can name; **one criterion with no support vetoes it**.
3. Promote it, or leave it a candidate with the reason. A held candidate is
precedent too, so the reason is the record — never skip writing it.
A milestone closing on a platform project hints without recording anything:
ask whether what it built is something every project on the platform will
face, and if so write the note that carries the idea.
## Answering an idea in a project
enter_project's `family` key counts what this project owes the family:
`unassessed`, `owed`, `needs_recheck`, each with the call that lists them.
Answer an idea **when your work reaches its area**, not as a chore list at
session start — the count is there so it is never invisible, not so it
preempts the operator's task.
- `get_family_adoption(project_id, idea_id)` first: the idea, the project's
current answer, the precedents, and the reference implementations with the
project's languages.
- Judge the outcomes **in the order `assess_family_adoption` lists them**,
stopping at the first that holds. Every outcome needs a reason; `adopted`
needs evidence naming where.
- **When the code is in the shape ledger, answer there instead:**
`classify_shapes` the shape with `idea_id=` as an `instance` or a
`variant`, and the adoption answer moves with it. An answer the shapes
contradict is refused — fix the shapes, not the answer.
- `owed` files a task in THAT project and stops. Nothing here edits another
repository; the project's own session picks the task up.
### What counts as a reason
A reason names a **fact about this project**: "the app is installed by a
managed store, never sideloaded", "the service has no user accounts". A
preference, a taste, or "we already did it another way" is not a reason —
that is `owed`, or, if this project's way is better rather than different, a
conflict. Write the reason so a session in another project can tell whether
the same fact holds there; that is how it becomes precedent.
### The precedent reflex
Before answering, read what was answered before: the same idea in other
projects, and this project's answers to the nearest ideas. Answer
consistently unless this project differs in a way you can name — and then
the difference IS the reason. The engine records the precedents it found
whether or not you cite them, so an inconsistent answer is visible later.
## When two projects disagree
Two projects solving one idea differently, each sure of its way, is a
conflict — settle it with `resolve_family_conflict`, which states the order.
The first ground that applies wins, and **every ground above it must be said
not to apply** — you cannot skip to the one you like. The losing side's
reasoning is folded into the idea's note (as a trap, an alternative, or the
branch for its condition) and never dropped; the version moves, so every
other project's answer reads as needing a recheck.
## Reporting it
A `family_owed` list on a closing task is work you filed into other projects
while it was open: name each one in the report, by project and idea — it is
waiting there now.