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
- 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>
94 lines
4.9 KiB
Markdown
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.
|