feat(family): family canon reaches the session - entry readout, retrieval reach, skill, report cue (milestone 463 step 6, #4992)
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
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>
This commit is contained in:
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"name": "scribe",
|
||||
"description": "Scribe for Claude Code: connects the scribe MCP server, adds the hooks that deliver live project state and relevant records at the right moment, ships the shared client-neutral Scribe skills (using-scribe, writing-plans, reporting-back, systematic-debugging, verification, brainstorming, reusing-code, shape-accounting), and syncs your saved Scribe Processes as skills (/scribe:sync).",
|
||||
"version": "2026.10.05.2219",
|
||||
"description": "Scribe for Claude Code: connects the scribe MCP server, adds the hooks that deliver live project state and relevant records at the right moment, ships the shared client-neutral Scribe skills (using-scribe, writing-plans, reporting-back, systematic-debugging, verification, brainstorming, reusing-code, shape-accounting, family-canon), and syncs your saved Scribe Processes as skills (/scribe:sync).",
|
||||
"version": "2026.10.06.1726",
|
||||
"author": {
|
||||
"name": "Bryan Van Deusen"
|
||||
},
|
||||
|
||||
@@ -6,7 +6,7 @@ once, in the **`using-scribe`** skill: reach for it at the start of the session
|
||||
and whenever you are unsure what Scribe expects. Each tool's contract is in its
|
||||
description, and the process skills (writing-plans, reporting-back,
|
||||
reusing-code, systematic-debugging, verification, brainstorming,
|
||||
shape-accounting) carry their arcs.
|
||||
shape-accounting, family-canon) carry their arcs.
|
||||
|
||||
What only Claude Code needs said:
|
||||
|
||||
|
||||
@@ -0,0 +1,93 @@
|
||||
---
|
||||
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.
|
||||
@@ -207,6 +207,8 @@ Notes on each section:
|
||||
the task alone is enough.
|
||||
- **What now works** — outcomes the operator would notice: "You can now…",
|
||||
"X no longer…". The files and steps behind them belong in the task's log.
|
||||
A `family_owed` list on the closing response is work you filed into other
|
||||
projects: name each by project and idea (the family-canon skill).
|
||||
- **How / why** — only the decisions worth knowing, plus **how it was
|
||||
verified**. If something could not be verified, say what and why here rather
|
||||
than letting it read as passed.
|
||||
|
||||
Reference in New Issue
Block a user