Keep the personal half of the desktop in one place, and ask before installing it

Agent instructions, skills, SSH host aliases and expansion triggers are worth
having identical on every machine one person owns, and belong in none of the
shared configuration. They live in user/ now, with a manifest saying where each
piece goes and a link-user stage that puts it there.

That stage does nothing unless the machine said yes. Somebody who clones Panama
to try the desktop keeps their own ~/.claude/CLAUDE.md exactly where it was;
the question names the destinations and defaults to no. Anything displaced goes
to config/old rather than being deleted.

~/.claude/CLAUDE.md and ~/.codex/AGENTS.md were byte-identical copies of one
file, which is the drift this exists to prevent.

Also adds the vitals toggles for the battery and Claude usage readouts, which
had preferences and no way to reach them.
This commit is contained in:
Gabriel Brown
2026-08-22 08:54:43 -04:00
parent 8b96d907a1
commit 89761a7da3
156 changed files with 16439 additions and 6 deletions
@@ -0,0 +1,52 @@
# ADR format
ADRs live in `docs/adr/`, numbered sequentially: `0001-slug.md`, `0002-slug.md`. Scan the directory
for the highest existing number and increment. Create `docs/adr/` lazily, only when the first ADR is
needed.
## Template
```md
# {Short title of the decision}
{One to three sentences: the context, what was decided, and why.}
```
That is the whole template. An ADR can be a single paragraph. The value is in recording *that* a
decision was made and *why*, not in filling out sections.
## Optional sections
Include these only where they add something. Most ADRs need none of them.
- **Status** frontmatter (`proposed | accepted | deprecated | superseded by ADR-NNNN`): useful once
decisions start getting revisited.
- **Considered options**: only where the rejected alternatives are worth remembering.
- **Consequences**: only where a non-obvious downstream effect needs calling out.
## When an ADR is warranted
All three must hold:
1. **Hard to reverse.** An easy decision to reverse does not need a record; it will simply be
reversed.
2. **Surprising without context.** If nobody would wonder why, nothing needs explaining.
3. **The result of a real trade-off.** With no genuine alternative there is nothing to record beyond
"we did the obvious thing."
### What qualifies
- **Architectural shape.** "The write model is event-sourced; the read model is projected."
- **Integration patterns between contexts.** "Ordering and Billing communicate via domain events, not
synchronous HTTP."
- **Technology choices carrying lock-in.** Database, message bus, auth provider, deployment target.
Not every library: the ones that would take a quarter to swap.
- **Boundary and scope decisions.** "Customer data is owned by the Customer context; others reference
it by ID only." The explicit noes are as valuable as the yeses.
- **Deliberate deviations from the obvious path.** "Manual SQL instead of an ORM, because X."
Anything a reasonable reader would assume the opposite of. These stop the next engineer from
"fixing" something deliberate.
- **Constraints invisible in the code.** "Response times must stay under 200ms because of the partner
API contract."
- **Rejected alternatives where the rejection is non-obvious.** Picking REST over GraphQL for subtle
reasons earns a record, or someone proposes GraphQL again in six months.
@@ -0,0 +1,65 @@
# CONTEXT.md format
## Structure
```md
# {Context name}
{One or two sentences: what this context is and why it exists.}
## Language
**Order**:
{One or two sentences describing the term.}
_Avoid_: Purchase, transaction
**Invoice**:
A request for payment sent to a customer after delivery.
_Avoid_: Bill, payment request
**Customer**:
A person or organization that places orders.
_Avoid_: Client, buyer, account
```
## Rules
- **Be opinionated.** Where several words exist for one concept, pick the best and list the rest
under `_Avoid_`. A glossary that refuses to choose is a thesaurus, and settles nothing.
- **Keep definitions tight.** One or two sentences. Define what the term *is*, not what it does.
- **Only terms specific to this project.** General programming concepts (timeouts, error types,
utility patterns) do not belong, however heavily the project uses them. Before adding a term, ask
whether it is unique to this context or just general vocabulary. Only the former earns a place.
- **Group under subheadings** once natural clusters emerge. A flat list is fine while the terms
belong to one cohesive area.
## Single vs multi-context repos
**Single context**, which is most repos: one `CONTEXT.md` at the root.
**Multiple contexts**: a `CONTEXT-MAP.md` at the root lists them, where they live, and how they
relate:
```md
# Context map
## Contexts
- [Ordering](./src/ordering/CONTEXT.md): receives and tracks customer orders
- [Billing](./src/billing/CONTEXT.md): generates invoices and processes payments
- [Fulfillment](./src/fulfillment/CONTEXT.md): manages warehouse picking and shipping
## Relationships
- **Ordering → Fulfillment**: Ordering emits `OrderPlaced`; Fulfillment consumes it to start picking
- **Fulfillment → Billing**: Fulfillment emits `ShipmentDispatched`; Billing generates the invoice
- **Ordering ↔ Billing**: shared types for `CustomerId` and `Money`
```
Infer which structure applies:
- `CONTEXT-MAP.md` exists → read it to find the contexts
- Only a root `CONTEXT.md` → single context
- Neither → single context; create the root `CONTEXT.md` lazily when the first term resolves
Where several contexts exist, infer which one the current topic belongs to, and ask if it is unclear.
+106
View File
@@ -0,0 +1,106 @@
---
name: domain-modeling
description: Use when a term is fuzzy, overloaded, or contradicts how the code behaves; when writing or editing a CONTEXT.md glossary; or when a hard-to-reverse decision needs recording as an ADR.
---
# Domain Modeling
Actively build and sharpen a project's domain model as you design: challenge terms, stress-test them
with scenarios, and write the glossary and the decisions down the moment they crystallise.
This is the *active* discipline. Merely **reading** `CONTEXT.md` for vocabulary is a one-line habit
any skill can do and is not this skill. Reach for this one when you are **changing** the model, not
consuming it.
## File structure
Most repos have a single context:
```
/
├── CONTEXT.md
├── docs/
│ └── adr/
│ ├── 0001-event-sourced-orders.md
│ └── 0002-postgres-for-write-model.md
└── src/
```
A `CONTEXT-MAP.md` at the root means the repo has several contexts, and the map points to where each
one lives:
```
/
├── CONTEXT-MAP.md
├── docs/adr/ ← system-wide decisions
└── src/
├── ordering/
│ ├── CONTEXT.md
│ └── docs/adr/ ← context-specific decisions
└── billing/
├── CONTEXT.md
└── docs/adr/
```
Create files lazily, only once there is something to write. No `CONTEXT.md` yet? Create it when the
first term is resolved. No `docs/adr/`? Create it when the first ADR is needed.
## During the session
### Challenge against the glossary
When a term conflicts with the language already in `CONTEXT.md`, call it out immediately.
> "Your glossary defines *cancellation* as X, but you seem to mean Y here. Which is it?"
### Sharpen fuzzy language
When a term is vague or overloaded, propose a precise canonical one.
> "You're saying *account*: do you mean the Customer or the User? Those are different things."
### Discuss concrete scenarios
When domain relationships are on the table, stress-test them with specific scenarios. Invent the
edge cases that force the boundaries between concepts to become precise.
### Cross-reference with the code
When a claim is made about how something works, check whether the code agrees, and surface any
contradiction.
> "The code cancels whole Orders, but you just said partial cancellation is possible. Which is right?"
The schema is the highest-signal place to check, because it is where the domain nouns are declared
rather than merely used. In a Convex project that is `convex/schema.ts`; elsewhere it is whatever
file defines the tables or types. A term that appears in conversation but nowhere in the schema is
either missing from the model or is not really a domain term.
### Update CONTEXT.md inline
When a term resolves, write it to `CONTEXT.md` right then. Do not batch them: capture each as it
happens, because the precision is what fades between now and the end of the session. Use the format
in [CONTEXT-FORMAT.md](CONTEXT-FORMAT.md).
`CONTEXT.md` is a glossary and nothing else. Keep implementation details, specs, and scratch notes
out of it.
### Offer ADRs sparingly
Offer an ADR only when all three are true:
1. **Hard to reverse**: the cost of changing your mind later is meaningful.
2. **Surprising without context**: a future reader will wonder "why on earth did they do it this
way?"
3. **The result of a real trade-off**: genuine alternatives existed and one was picked for specific
reasons.
Missing any one of the three, skip it. Use the format in [ADR-FORMAT.md](ADR-FORMAT.md).
## Done when
- Every term resolved this session is in `CONTEXT.md`, in the house format, with its rejected
synonyms under `_Avoid_`.
- No implementation detail has leaked into `CONTEXT.md`.
- Every contradiction found between a stated claim and the code was surfaced, not silently resolved.
- An ADR exists for each decision meeting all three tests, and for none that miss one.
@@ -0,0 +1,3 @@
interface:
display_name: Domain Modeling
short_description: Sharpen domain terms, maintain CONTEXT.md, and record ADRs.