aboutsummaryrefslogtreecommitdiff
path: root/docs
diff options
context:
space:
mode:
Diffstat (limited to 'docs')
-rw-r--r--docs/design/2026-07-15-subproject-pattern-proposal.org22
-rw-r--r--docs/design/2026-07-15-subprojects-convention-home-instance.org282
2 files changed, 304 insertions, 0 deletions
diff --git a/docs/design/2026-07-15-subproject-pattern-proposal.org b/docs/design/2026-07-15-subproject-pattern-proposal.org
new file mode 100644
index 0000000..61ade18
--- /dev/null
+++ b/docs/design/2026-07-15-subproject-pattern-proposal.org
@@ -0,0 +1,22 @@
+#+TITLE: Proposal: promote the "subproject" pattern into the claude-r
+#+SOURCE: from home
+#+DATE: 2026-07-15 23:24:07 -0500
+
+Proposal: promote the "subproject" pattern into the claude-rules layer.
+
+WHAT WE DID (in home, 2026-07-15)
+We named and built a pattern for what happens when a standalone project is consolidated into another project. home absorbed nine former projects on 2026-06-11 (danneel, finances, jr-estate, kit, health, documents, clipper, elibrary, philosophy). We now call each folded-in unit a "subproject": a former standalone project that lives as a subdirectory, shares the parent's .ai/ scope (one session, one toolchain), but keeps its own files, assets, and history self-contained under its subdir.
+
+The pattern has four parts:
+1. Vocabulary — parent project, subproject, consolidation (the process), subproject archiving. Terminology so we can talk precisely about where a subproject's documents/assets live and archive them cleanly.
+2. Subproject brief — a read-first orientation doc at <subproject>/<subproject>-brief.org (situation, current state, reading list, and for deep ones cast/timeline/key-facts-with-verify-flags). The parent's notes.org holds a thin index + a read-first rule + pointers to urgent items only, never a copy of subproject substance ("one fact, one home").
+3. Lifecycle criteria — when to CREATE a subproject (consolidate: domain fit, low independent cadence, shared-scope safety re: privacy/remote posture, no independent collaborators), and when/how to ARCHIVE one cleanly (terminal state -> move the self-contained subdir to <parent>/archive/, reconcile pointers/links/tags, manifest note).
+4. Instrumentation — a use/miss log, metrics weighted toward Craig-caught errors over self-report, review folded into task-audit, and a falsifiable kill criterion.
+
+WHY IT'S GENERAL (not just a home thing)
+Consolidating a project into another drops what the former project's own startup used to auto-load (its full depth), so sessions start cold and re-read files. That failure recurs whenever ANY project folds into another. The pattern also gives consolidation and archiving a named, repeatable shape, and the self-contained-subdir rule is what makes archiving a move-plus-pointer-reconcile instead of an excavation.
+
+THE PROPOSAL
+Promote this to a rulesets claude-rule (e.g. claude-rules/subprojects.md): the vocabulary, the brief convention, the parent-vs-subproject content criterion, and the create/archive criteria. Any parent/hub project would then inherit it. home's .ai/subprojects.org (attached next) becomes the local instance/index under the general rule. It's a companion to working-files.md (in-progress artifact layout) and docs-lifecycle.md (formal-doc lifecycle) — same family, different scope: this one governs whole-subproject orientation and lifecycle.
+
+Attached: the home instance .ai/subprojects.org as the reference draft to adapt. Apply your value gate; this is a proposal, not a synced-file edit.
diff --git a/docs/design/2026-07-15-subprojects-convention-home-instance.org b/docs/design/2026-07-15-subprojects-convention-home-instance.org
new file mode 100644
index 0000000..a1c4397
--- /dev/null
+++ b/docs/design/2026-07-15-subprojects-convention-home-instance.org
@@ -0,0 +1,282 @@
+#+TITLE: Subprojects — Convention
+#+AUTHOR: Craig Jennings
+#+DATE: 2026-07-15
+
+# The reference spec for the subproject pattern: what a subproject is, when to
+# create one (consolidation), how to keep it legible (the brief + content
+# split), and how to archive one cleanly. Not read every session — the
+# always-on parts (the subproject index + the read-first rule) live in
+# notes.org and point here. Read this when consolidating a project, creating
+# or maintaining a subproject brief, or archiving a subproject.
+
+* Vocabulary (say it the same way every time)
+
+The terminology is the point — it's what lets us talk precisely about where a
+subproject's documents and assets live, and archive them cleanly.
+
+- *Parent project* (a.k.a. hub) — a top-level project that owns an =.ai/=
+ scope: its own protocols, session cadence, memory, inbox, todo. home, work,
+ rulesets, .emacs.d are parent projects. Reached by launching an agent
+ session in its directory.
+- *Subproject* — a formerly-standalone project that has been *consolidated*
+ into a parent and now lives as a subdirectory of it (=danneel/=,
+ =finances/=, =kit/= …). A subproject shares the parent's =.ai/= tooling and
+ session — it is not a separate agent scope — but keeps its own working
+ files, assets, notes, and history self-contained under its one subdirectory.
+- *Consolidation* — the process of turning a standalone project into a
+ subproject of a parent. (home's nine subprojects were consolidated on
+ 2026-06-11.) The inverse — promoting a subproject back to a standalone
+ project — is rare but allowed; it's just consolidation run backward.
+- *Subproject archiving* — retiring a completed or abandoned subproject
+ cleanly. Because a subproject is self-contained under one subdirectory,
+ archiving is a move plus a pointer reconcile, not an excavation.
+- *Subproject brief* — the read-first orientation doc for one subproject, at
+ =<subproject>/<subproject>-brief.org=.
+
+The cross-project boundary rule (=claude-rules/cross-project.md=) governs
+*parent* projects, which are separate =.ai/= scopes. It does *not* apply
+between a parent and its subprojects — they share one scope.
+
+* Why the pattern exists
+
+As a standalone project, each of these units auto-loaded its own notes.org —
+its full depth — at every startup, so recall felt instant. Consolidated into a
+parent, a subproject is one compressed section competing with the others, and
+the parent's startup surfaces hub-wide state, not any one subproject's depth.
+So a session starts cold on a given subproject and re-reads several files on
+demand. This convention restores fast, accurate orientation without
+re-bloating what loads every session — and gives consolidation and archiving a
+named, repeatable shape.
+
+* Document & asset location (what makes clean archiving possible)
+
+Everything for a subproject lives under =<subproject>/= — its =notes.org=,
+=assets/=, working files, event log, briefs. Links *within* a subproject are
+relative to the subproject dir, so the whole tree can move without breaking
+them. The parent's own top-level =assets/= is for parent-level material only,
+never a subproject's. This self-containment is exactly what lets archiving be
+a single =mv= plus a pointer reconcile. Keep it strict: a subproject's asset
+in the parent's shared =assets/= is a future broken link.
+
+* The two layers (parent vs subproject)
+
+- *Always-on layer* — the parent's notes.org. Read at every startup, so every
+ line is a tax paid whether or not it's relevant today. Holds only what must
+ be seen session-independently.
+- *On-demand layer* — the subproject brief + the subproject's notes.org.
+ Loaded only when working that subproject. Holds the depth.
+
+The whole design is: sort content by *when it's needed*, keep the always-on
+layer thin, put the depth one open away.
+
+* Creating a subproject (consolidation criteria)
+
+Consolidate a standalone project into a parent as a subproject when *all* hold:
+
+1. *Domain fit* — the project is a facet of a domain the parent already owns
+ (danneel is home life-admin; finances is home).
+2. *Low independent cadence* — it no longer needs its own session rhythm.
+ You'd rather reach it from the parent than launch it standalone, and its
+ standalone startup/sync/session overhead now outweighs the isolation.
+3. *Shared-scope safety* — it does not need a git/remote/visibility posture
+ distinct from the parent. A public code project, a team repo, or anything
+ with its own CI or gitignore-privacy posture *stays standalone* — folding
+ it would break the parent's privacy model (see
+ =claude-rules/git-hosting-privacy-model= and the gitignore-vs-track
+ decision). Personal/documentation units fold; code-with-a-public-remote
+ does not.
+4. *No independent collaborators* depend on it as a standalone deliverable.
+
+Keep it standalone when any of those fail: active independent development, its
+own team or remote, a distinct visibility/security posture, or activity high
+enough that competing in the parent's hub would bury it.
+
+*The consolidation act itself* (mechanics, mirroring home's 2026-06-11 fold):
+move the project tree under the parent as =<parent>/<subproject>/=; import its
+tasks into the parent's todo with an area =:tag:= and a =:MIGRATED_FROM:=
+property; fold its live reminders/decisions into the parent's notes as
+pointers (see the content split); build the subproject brief; record the fold
+in a consolidation manifest (=docs/consolidation-manifest-<subproject>.org=).
+Retire the source to =~/projects/.retired/<name>= once parity is verified.
+
+* The subproject brief
+
+** Path (fixed — discovery is mechanical)
+
+=<subproject>/<subproject>-brief.org= (=danneel/danneel-brief.org=,
+=finances/finances-brief.org=). The subproject name is the directory name, so
+the brief name follows for free. One predictable name means the read-first
+rule never has to hunt; put descriptive richness *inside*, not in the filename.
+
+** Spine (scales from light to deep)
+
+Required in every brief, even a fifteen-line one:
+- *One-paragraph situation* — what this subproject is, in plain language.
+- *Current state / open threads* — the live stuff. The only high-churn
+ section; everything else is stable.
+- *Reading list* — the subproject's deeper files and what each holds. The
+ brief *points into* notes.org and the rest; it does not copy them.
+
+Add only where the subproject warrants it (danneel, jr-estate, finances earn
+all of these; elibrary or documents may earn none):
+- Cast / contacts.
+- Timeline (for matters with history).
+- Key facts / numbers, with explicit *verify* flags anywhere the underlying
+ record disagrees with itself. A brief that asserts a wrong number is worse
+ than no brief — flag, don't guess.
+
+** Read-first rule (the behavior)
+
+When a session's work targets a subproject — a file under =<subproject>/=, its
+=:tag:=, or Craig naming the topic — open =<subproject>/<subproject>-brief.org=
+*first*, before touching anything else in it. If the subproject has no brief
+yet, creating it is the first step of the work (lazy backfill), and the same
+pass reconciles that subproject's parent-vs-subproject content.
+
+* Parent-vs-subproject content criterion
+
+The test for any piece of content: *if next session I'm working a different
+subproject, do I still need to see this?* Three bins:
+
+1. *Yes, and it's a fact or policy* → hub-level → the parent's notes.org.
+ Machine names, mail policy, calendar access, the hub map, the subproject
+ index.
+2. *Yes, but only because it's urgent* — a deadline or blocking status that
+ would be missed if it only lived where I might not look this week → the
+ parent holds a *one-line pointer* (item + date + "see the subproject
+ brief"); the substance stays in the subproject.
+3. *No* → the subproject. Working depth: contacts, contract facts, case
+ theory, evidence, document index, and any reminder that isn't time-critical.
+
+One hard rule over both axes: *one fact, one home.* The parent never copies
+subproject substance — it points. The parent holds the trigger; the subproject
+holds the truth. Every parent↔subproject duplicate is a second surface that
+goes stale.
+
+* Archiving a subproject (archiving criteria + clean process)
+
+Archive a subproject when it reaches a *terminal* state:
+- *Complete* — the work is done and closed (a settlement signed, a probate
+ closed, a trip finished): no live threads, no open tasks, nothing
+ time-sensitive in the parent still pointing at it; or
+- *Abandoned / superseded* — dropped, or replaced by other work.
+
+Clean archive process (self-containment is what makes each step a one-liner):
+1. Close or settle its tasks in the parent's todo (DONE / CANCELLED), per the
+ todo completion rules.
+2. Move the whole subproject tree to the parent's archive:
+ =<parent>/archive/<subproject>/= (keep it intact — archiving is reversible,
+ not deletion).
+3. Update inbound =file:= links that pointed into it (grep first, per the
+ keep-links-current rule).
+4. Move or retire its brief with it, and drop its row from the active
+ subproject index (or mark it =archived= there).
+5. Strip its pointers/reminders from the parent's always-on layer, and retire
+ its =:tag:= from active use.
+6. Record the archive in a manifest note
+ (=docs/archive-manifest-<subproject>.org=): why, when, where it moved,
+ what links were repointed. Mirrors the consolidation manifest.
+
+The =:LAST_UPDATED:= on a brief plus "no open tasks under the tag" is the
+signal a subproject is a candidate for archiving — surfaced at the review
+cadence, never auto-archived.
+
+* Freshness
+
+- *Wrap-up hook*: at wrap-up, for each subproject touched this session, refresh
+ its brief's Current-state section and bump its =:LAST_UPDATED:= date. Stable
+ sections rarely change, so this is cheap.
+- *Staleness nudge*: a brief whose =:LAST_UPDATED:= is old while its subproject
+ was recently active is worth surfacing at startup.
+
+* Self-improvement loop
+
+Every real use emits a signal, and the signal is *captured*, not silently
+acted on:
+- Brief answers the question → *hit*.
+- Brief is missing something, stale, or wrong → *miss*, logged in
+ [[file:subprojects-log.org][subprojects-log.org]].
+- Each miss drives *two* updates: *local* (fix that brief) and, if the same
+ kind of miss recurs across subprojects, *structural* (fix this spine/spec,
+ not just the one file). The structural half is the actual self-improvement —
+ grow-and-refine from real use rather than rewriting from scratch (the ACE
+ idea behind the =codify= skill).
+
+* Metrics
+
+Split by who can trust them.
+
+*Process signals (I observe, cheaply):*
+- *Orientation cost* — files/tool-calls before my first correct action in a
+ subproject. Target: ~1 (the brief), occasionally a second deep dive.
+- *Brief hit rate* — fraction of subproject questions answered from the brief
+ alone. Should climb.
+- *Freshness gap* — days between =:LAST_UPDATED:= and last subproject activity.
+ Target ~0.
+
+*Outcome signals (Craig is ground truth — weight these over the above):*
+- *Craig-caught errors* — the real quality bar. Target: trend to zero. If
+ briefs work, Craig stops catching me.
+- *Felt speed* — did dropping into the subproject feel fast and right.
+
+*Honesty caveat.* Most process signals are self-observed, and self-report is
+biased toward "hit." So the external signals (Craig-caught errors, felt speed)
+outrank mine, and the log is auditable so Craig can spot-check my self-grades.
+The instrumentation must stay lighter than the briefs, or it rots like an
+unmaintained brief. Small N, no clean A/B — this is directional evidence, not
+proof.
+
+* Review cadence
+
+Fold a "subprojects health" check into the existing task-audit cadence: read
+the log, look at the hit-rate / correction / freshness trends, flag any
+subproject that's gone terminal (archive candidate), and check the
+parent-vs-subproject criterion — anywhere the parent holds a copy where it
+should hold a pointer. Decide continue / adjust / kill for the pattern itself.
+
+* Kill criteria (falsifiable)
+
+After ~6-8 subproject-sessions across ≥3 subprojects, drop or rework the
+pattern if:
+- the correction rate isn't falling, or Craig is still catching errors; or
+- the freshness gap keeps reopening despite the wrap-up hook; or
+- maintenance costs more time than the orientation it saves.
+
+Success is the mirror: orientation down to ~1 read, Craig catching ~nothing,
+briefs current, and I'm right fast in any subproject cold.
+
+* Rollout
+
+- Define the convention (this file) + the index scaffold in notes.org. Done
+ 2026-07-15.
+- *Lazy backfill*: the next session that touches a subproject with no brief
+ creates the brief as its first step — cost paid exactly when it's used.
+- *Reconcile in the same pass*: building a subproject's brief includes
+ reconciling its parent-vs-subproject content — push substance down, leave
+ pointers up, drop dead reminders.
+- *Promotion*: this pattern is home-instanced but general. Consolidation into
+ subprojects will recur whenever any project folds into another, so this is a
+ candidate to promote into the rulesets rules layer (proposed to rulesets
+ 2026-07-15).
+
+* Adoption status
+
+| Subproject | Brief exists | Reconciled | Notes |
+|------------+--------------+------------+---------------------------------------|
+| danneel | yes | yes | First worked instance, 2026-07-15. |
+|------------+--------------+------------+---------------------------------------|
+| clipper | no | no | Lazy backfill on next touch. |
+|------------+--------------+------------+---------------------------------------|
+| documents | no | no | Lazy backfill on next touch. |
+|------------+--------------+------------+---------------------------------------|
+| elibrary | no | no | No notes.org yet; lightest subproject.|
+|------------+--------------+------------+---------------------------------------|
+| finances | no | no | Deep; earns the full spine. |
+|------------+--------------+------------+---------------------------------------|
+| health | no | no | Has its own notes.org. |
+|------------+--------------+------------+---------------------------------------|
+| jr-estate | no | no | Deep; earns the full spine. |
+|------------+--------------+------------+---------------------------------------|
+| kit | no | no | Lazy backfill on next touch. |
+|------------+--------------+------------+---------------------------------------|
+| philosophy | no | no | Lazy backfill on next touch. |