dreamteamer 0.15.0 → 0.16.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (28) hide show
  1. package/README.md +6 -4
  2. package/collections/collections.collection.yaml +12 -2
  3. package/package.json +1 -1
  4. package/skills/using-dreamteamer/SKILL.md +103 -96
  5. package/skills/using-dreamteamer/references/agents.md +162 -0
  6. package/skills/using-dreamteamer/references/before-you-build.md +99 -0
  7. package/skills/using-dreamteamer/references/changes.md +55 -0
  8. package/skills/using-dreamteamer/references/collections.md +291 -0
  9. package/skills/using-dreamteamer/references/commands.md +190 -0
  10. package/skills/{building-dreamteamer → using-dreamteamer}/references/data-modeling.md +40 -25
  11. package/skills/using-dreamteamer/references/records.md +153 -74
  12. package/skills/using-dreamteamer/references/skills.md +185 -0
  13. package/skills/using-dreamteamer/references/ui-components.md +153 -0
  14. package/skills/using-dreamteamer/references/ui-views.md +170 -0
  15. package/src/cli.js +16 -6
  16. package/src/compile.js +1 -1
  17. package/src/events.js +1 -1
  18. package/src/harnesses.js +3 -4
  19. package/src/init.js +8 -1
  20. package/skills/building-dreamteamer/SKILL.md +0 -120
  21. package/skills/building-dreamteamer/references/agents.md +0 -44
  22. package/skills/building-dreamteamer/references/before-you-build.md +0 -42
  23. package/skills/building-dreamteamer/references/collections.md +0 -153
  24. package/skills/building-dreamteamer/references/commands.md +0 -69
  25. package/skills/building-dreamteamer/references/skills.md +0 -73
  26. package/skills/building-dreamteamer/references/ui-components.md +0 -78
  27. package/skills/building-dreamteamer/references/ui-views.md +0 -64
  28. package/skills/using-dreamteamer/references/git-events.md +0 -56
package/README.md CHANGED
@@ -146,10 +146,12 @@ workspace pins**, so the editor, the CLI and any agent session are provably runn
146
146
  This is an agent-native tool, so its documentation is shipped as skills the agent loads on demand —
147
147
  and you can read them like any other file:
148
148
 
149
- - [`skills/using-dreamteamer`](skills/using-dreamteamer) — the map: collections, conventions, the CLI,
150
- how records work
151
- - [`skills/building-dreamteamer`](skills/building-dreamteamer)authoring: collections, skills,
152
- agents, commands, UI views, and which of those a given request should become
149
+ - [`skills/using-dreamteamer`](skills/using-dreamteamer) — the one skill: working with records
150
+ (the CLI, conventions, commits) and modeling the workspace (collections, skills, agents,
151
+ commands, UI views and which of those a given request should become), each topic a reference
152
+ loaded on demand
153
+ - [`docs/one-skill-blast-radius.md`](docs/one-skill-blast-radius.md) — the 0.16.0 skill
154
+ consolidation: what breaks for a consumer, what to grep for, which claims were verified live
153
155
  - [`docs/repos-and-modules.md`](docs/repos-and-modules.md) — attached repos vs modules, and why they
154
156
  have different homes
155
157
  - [`docs/namespaces-blast-radius.md`](docs/namespaces-blast-radius.md) — scoping collections under a
@@ -37,7 +37,17 @@ schema:
37
37
  properties:
38
38
  path:
39
39
  type: string
40
- description: Folder holding the records, workspace-relative. `data/` for content, `state/` for operational records, `system/` for sources.
40
+ description: >-
41
+ Folder holding the records, workspace-relative. `data/<collection>` — that is the answer
42
+ unless you can state a reason. `state/<collection>` is DEPRECATED as a convention since
43
+ 2026-08-31: decision 4 created it for runs, triggers, registries and cursors, all seven
44
+ of those collections have been deleted, and the one real operational-data need that
45
+ arrived since went to a gitignored `.cache/*.jsonl` because append-only readings are the
46
+ wrong shape for records. The mechanism still works and is kept, exactly like `group`
47
+ below, so a workspace wanting a second root has one. ⚠ NEVER author `system/` — sources
48
+ have lived in `modules/<module>/<kind>/` since the 2026-08-05 flatten, and a `system/`
49
+ prefix is only how `runtime.js` recognises a RUNTIME collection in a descriptor compiled
50
+ by a pre-flatten engine.
41
51
  codec:
42
52
  type: string
43
53
  enum: [md, yaml, json, file]
@@ -89,7 +99,7 @@ schema:
89
99
  type: string
90
100
  description: >-
91
101
  Which field carries MANUAL order — the one a drag writes. The field must be declared by this
92
- collection's own schema, and holds a fractional index (`dt <collection> move`), never an
102
+ collection's own schema, and holds a fractional index (`dt move <collection>/<id>`), never an
93
103
  integer: renumbering is a multi-file commit against git. A surface offers dragging only while
94
104
  it is sorted by this field, because a handle that reorders nothing is a lie.
95
105
  icon:
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "dreamteamer",
3
- "version": "0.15.0",
3
+ "version": "0.16.0",
4
4
  "description": "A workspace compiler for coding agents — schema-validated records as plain files over git, compiled into every harness",
5
5
  "license": "Apache-2.0",
6
6
  "author": "Gilad Khen <giladkhen@gmail.com>",
@@ -1,131 +1,138 @@
1
1
  ---
2
2
  name: using-dreamteamer
3
- description: always load first describes this dreamteamer workspace, its collections, conventions and your pending tasks
3
+ description: always load first in a dreamteamer workspace — reading, writing and committing records, and changing what the workspace keeps or does (collections and fields, skills, commands, agents, ui-views, component code). Also when deciding which of those a request should become, when a compile or check error names a source file, or when a request names a new kind of thing to keep.
4
4
  ---
5
5
 
6
6
  # using dreamteamer
7
7
 
8
- this is a **dreamteamer** workspace: collections, skills, agents and commands are records compiled
9
- from sources into a runtime the harness reads.
8
+ this is a **dreamteamer** workspace: collections of typed records, plus the skills, commands,
9
+ agents and views that operate on them — all compiled from sources into a runtime the harness
10
+ reads.
10
11
 
11
- **core principle:** read the compiled runtime, write the sources, compile then `dt commit` to publish.
12
+ **core principle:** read the compiled runtime, write records with the CLI and sources under
13
+ `modules/`, compile after any source change — then `dt commit` publishes what you wrote.
12
14
 
13
- ## when to use
15
+ ## when to load
14
16
 
15
- load this **first, every session** in this repo. reload mid-session on any of these symptoms: you're
17
+ first thing, every session in this repo. reload mid-session on any of these symptoms: you're
16
18
  about to guess a collection's fields; you can't tell whether the file to edit lives under
17
19
  `modules/*/<kind>/` or `.dreamteamer/`; you wrote something and the harness didn't notice; you're
18
20
  unsure which skill owns the job in front of you.
19
21
 
20
- **this file is the MAP, not the procedure.** Detail lives in two references beside it, loaded on
21
- demand:
22
-
23
- | load | when |
24
- |---|---|
25
- | `references/records.md` | reading, creating, updating, renaming or deleting any record — the CLI verbs, hand-writing rules, the hard rules about ids and renames |
26
- | `references/git-events.md` | "what changed while I was away" — `dt changes`, and how record events are derived from git history |
27
-
28
22
  ## the contract
29
23
 
30
24
  | concern | where | rule |
31
25
  |---|---|---|
32
26
  | schemas (read) | `.dreamteamer/collections/*.collection.yaml` | the single source of truth for what exists and its shape. **never edit under `.dreamteamer/`** — generated and gitignored |
33
27
  | provenance | `.dreamteamer/manifest.yaml` | which module shipped which entry |
34
- | sources (write) | `modules/<module>/` — **including the workspace's own**, the `dreamteamer.workspace-module` named in `package.json` | a source folder at the workspace ROOT is a compile ERROR. same-name collisions across modules are compile errors too. after ANY source change: `npm run compile` |
35
- | content records | `data/<collection>/` | per each descriptor's `storage.path` |
36
- | operational records | `state/<collection>/` | whatever a module declares there; core ships none |
28
+ | sources (write) | `modules/<module>/<kind>/` — **including the workspace's own**, the `dreamteamer.workspace-module` named in `package.json` | a source folder at the workspace ROOT is a compile error (whenever `workspace-module` is set — every `dt init` workspace); same-name collisions across modules too. after ANY source change: `dt compile` |
29
+ | records (write) | `data/…`, per each descriptor's `storage.path` | the CLI writes them validated; hand-edits are legal and owe `dt check` |
37
30
 
38
- - a record is a `<id>.<suffix>.<ext>` file (or a folder, for folder-shape collections). **the id is
39
- the path** inside the collection folder minus suffix and extension — nested folders join in:
31
+ - a record is a `<id>.<suffix>.<ext>` file (or a folder, for folder-shape collections). **the id
32
+ is the path** inside the collection folder minus suffix and extension — nested folders join in:
40
33
  `data/meetings/2026/07/standup.meeting.md` ⇒ id `2026/07/standup`.
41
- - **references are `<collection>/<id>`** strings — always qualified, greppable, never a bare name and
42
- never a file path.
34
+ - **references are `<collection>/<id>`** strings — always qualified, greppable, never a bare name
35
+ and never a file path.
36
+
37
+ **lifecycle:** `dt init` writes a new workspace's skeleton (it never compiles). a FRESH CLONE owes
38
+ `dt install` (restores `git_modules/`) then `dt compile` before anything reads — `.dreamteamer/`
39
+ and the harness folders are gitignored build output, so a clone has no runtime until compile
40
+ writes one — and `.env` is per-machine (declared keys: `references/records.md`). `dt status` says
41
+ whether the runtime is fresh. the workspace's own switches live in `package.json`'s `dreamteamer`
42
+ block (`references/collections.md`, the workspace manifest).
43
43
 
44
44
  ## the CLI is the front door
45
45
 
46
- `npm run --silent dt -- help` is the command surface don't learn the generic verbs and flags from
47
- prose; prose drifts. it does **not** list the purpose-built verbs some collections have
48
- (`schema add-collection`, `schema add-field <collection>`, `ensure`) — those live in the skill that owns
49
- them, and a verb absent from `help` still works.
46
+ `dt` in this skill means the dreamteamer CLI: **`npx dreamteamer`** works in any workspace, and a
47
+ workspace may alias it as an npm script check `scripts` in `package.json` (the common spelling
48
+ is `npm run --silent dt -- <verb> …`).
50
49
 
51
- what you need to know *about* the CLI: collection verbs validate hard invalid writes, **including
52
- unknown fields**, are rejected before disk and a write does NOT commit (see conventions below).
50
+ **`dt help` is the complete command surface** record verbs, schema verbs, workspace verbs, and
51
+ their flags, on one page (there is no per-verb `--help`). don't learn syntax from prose, this skill included: prose drifts, and `help` ships in
52
+ the same file as the dispatch it documents. run it once before your first write of a session.
53
+ what prose adds is judgment — *when* a verb is the right move, and the guarantees you can lean
54
+ on: **validation is hard** (unknown fields included; an invalid write is rejected before disk
55
+ with no partial state), and **a write does not commit** — `dt commit` publishes, scoped
56
+ (`references/records.md`).
53
57
 
54
- ## routing
58
+ ## two acts, one map
55
59
 
56
- | the request is about | load |
57
- |---|---|
58
- | a record read, create, update, rename, delete | `references/records.md` |
59
- | authoring anything under a module's source folders — a collection, field, skill, command, agent, ui-view, or component code | `building-dreamteamer` |
60
- | "what changed while I was away" | `references/git-events.md` |
61
- | the workspace lacks the capability entirely | `building-dreamteamer` → `references/before-you-build.md`, then `references/data-modeling.md` |
62
-
63
- Domain work — meetings, contacts, tasks, content, design — is owned by the **module** that ships those
64
- collections, not by core. Read that module's own skills. Core knows about entity kinds and `repos`,
65
- and deliberately nothing else — including nothing about people. There is no `users` collection.
66
-
67
- ## conventions
68
-
69
- - **a write puts a record on disk; `dreamteamer commit` publishes it.** committing is POLICY —
70
- `"auto-commit"` in the workspace's `package.json`, default off — not a property of the write. so
71
- commit when a logical change is complete, and run `dt status` if you are unsure what is pending.
72
- subjects still read `dreamteamer: <verb> <detail>` for a single record (`dt commit` composes them
73
- from git's own status letters), and a multi-record commit says what it swept.
74
- - **one commit per REPO.** a module can own its records (`owns-data` in its package.json), and git
75
- has no cross-repo commit — so a rename whose inbound refs live in another repo is TWO commits.
76
- `dt commit` prints both. `--dry-run` shows the set first.
77
- - **scope the commit to what YOU wrote: `dt commit <collection>/<id>`.** any number of targets, each
78
- either a whole `<collection>` or one record — bare `dt commit` publishes everything pending, and
79
- `dt commit <collection>` publishes every dirty record under it *whoever wrote it*, which is the
80
- same sweep as the blanket add below when a second session shares the tree.
81
- - **never `git add -A`, `git add .`, or `git commit -a`.** stage explicit paths. more than one agent
82
- can be working in a tree, and a blanket add silently commits whatever another session has
83
- uncommitted right now — under your subject, leaving `git status` clean and the damage invisible.
84
- the CLI's own writes are pathspec-scoped for exactly this reason, which is why it is the preferred
85
- path for record writes.
86
- - **validate after bulk edits**: `npm run check` reports violations and never modifies files.
87
- - workspace-level rules live in `CLAUDE.md`, and a workspace's decision log (where one exists) wins
88
- over older documents.
89
- - **session greeting** — surface the operator's inbox from whatever collection this workspace uses for
90
- work, e.g. `npm run --silent dt -- list tasks --status todo`. ⚠ **there is no `users` collection and
91
- no `@me`** (both removed in 0.8.0); read the operator from `git config user.name` at the point you
92
- need one, and never filter on a person unless this workspace owns a collection of them.
93
-
94
- ## machine-specific references
95
-
96
- a path that exists on only one machine — a synced folder, an external disk — is written as a
97
- **template**, never as an absolute path:
98
-
99
- ```yaml
100
- source_file: ${env:FILES_FOLDER}/2026/q3.pdf
101
- ```
102
-
103
- | variable | renders to |
60
+ Act one is **working with data** — the records themselves. Act two is **modeling the workspace**
61
+ — changing what it keeps (collections, fields) or what it does (skills, commands, agents, views).
62
+ Load by the map; nothing here is loaded "just in case".
63
+
64
+ | the job | load |
104
65
  |---|---|
105
- | `${env:NAME}` | `NAME`'s value in the workspace's `.env` and only if `NAME` is listed in `dreamteamer.vars` in `package.json` AND has a non-empty value there (an empty or whitespace-only value fails exactly like an unset key) |
106
- | `${workspaceFolder}` | the workspace root, absolute |
107
- | `${userHome}` | the current user's home directory |
108
-
109
- - **declare the key before using it**: `"dreamteamer": { "vars": ["FILES_FOLDER"] }`. an undeclared
110
- key and a declared-but-absent one are deliberately different errors the first is a typo, the
111
- second is a machine nobody has set up. `npm run compile` warns per declared var with no value in
112
- `.env`, naming keys only.
113
- - **render with `dt resolve`, the only substitution point**: `dt resolve '${env:FILES_FOLDER}/x'`, or
114
- `dt resolve <collection>/<id> <field>` to render what a record already holds (an array field prints
115
- one item per line). an argument containing `${` is always a template, so a ref-shaped one is never
116
- split as a reference.
117
- - ⚠ **templates are ordinary data — write them literally; nothing substitutes until resolve is
118
- called.** `dt get`, `list`, `check` and every harness read the template verbatim. an un-namespaced
119
- `${VAR}` is inert, so prose may mention `${…}` freely.
66
+ | read, create, update, rename, delete, commitor UNDO a record | `references/records.md` |
67
+ | "what changed while I was away" | `references/changes.md` |
68
+ | the workspace seems unable to do something — a new kind of thing, a missing capability, "don't we already have this?" | `references/before-you-build.md` (look first); a new model then continues `references/data-modeling.md` (decide) → `references/collections.md` (write it) |
69
+ | a collection or field, mechanically — the descriptor, the `schema` verbs, `templates:`/`extends:`, a compile or check message | `references/collections.md` |
70
+ | knowledge a session should find on its own | `references/skills.md` |
71
+ | "let me type one word and have this done" | `references/commands.md` |
72
+ | "which command applies to this record?" a binding, a gate | `references/commands.md` |
73
+ | a job needing a fresh context and its own tools | `references/agents.md` |
74
+ | a route, a nav entry, a board / calendar / map over records | `references/ui-views.md` |
75
+ | a rendering or editing behaviour nothing registered has | `references/ui-components.md` |
76
+
77
+ three act-two tie-breakers, because they are the ones that go wrong:
78
+
79
+ - **skill vs command:** a skill triggers itself when the situation arises; a command needs the
80
+ operator to remember it exists. if the answer is "and they'd have to think of running it",
81
+ write the skill.
82
+ - **agent vs skill:** an agent costs a whole context. if "just tell the current session how"
83
+ works, it is a skill.
84
+ - **a multi-step process is a CHAIN OF COMMANDS** gated on record fields (`references/commands.md`),
85
+ never a workflow entity — there is no workflow kind, deliberately: the record's own state is
86
+ the progress marker.
87
+
88
+ domain work — meetings, patients, invoices, whatever this workspace is about — is owned by the
89
+ **module** that ships those collections; read that module's own skills. core knows entity kinds
90
+ and `repos`, and deliberately nothing else. workspace-level rules live in `CLAUDE.md`, and a
91
+ workspace's decision log (where one exists) wins over older documents.
92
+
93
+ ## the rules that hold in both acts
94
+
95
+ 1. **sources live in a module** — `modules/<module>/<kind>/`; the workspace's own go in its
96
+ workspace module. **a module is discovered by its `package.json` carrying a `dreamteamer`
97
+ key** (`"dreamteamer": {}` is enough) — without it, the folder is silently ignored.
98
+ 2. **the filename is the id.** where a record also carries a frontmatter `name` (agents,
99
+ commands), the two must agree, or the id lies and dispatch misses.
100
+ 3. **the meta-descriptor is the spec.** every source kind is itself a collection — read
101
+ `.dreamteamer/collections/<kind>.collection.yaml` plus one real record (`dt get <kind>/<id>`)
102
+ instead of learning a shape from prose.
103
+ 4. **`dt compile`, then `dt check`**, after any source change. compile fails closed — a bad
104
+ source is rejected and the previous runtime stands; check reports and never modifies.
105
+ 5. **a running session does not see new sources.** a new skill, command or agent is live in the
106
+ operator's NEXT session — say so rather than letting them wonder.
107
+ 6. **never edit generated output.** `.dreamteamer/`, `.claude/`, `.agents/`, `.cursor/` are
108
+ overwritten and pruned on the next compile — if you found the thing to change there, you are
109
+ in the wrong file.
110
+ 7. **the CLI refuses system-stored records on purpose** (`dt set skills/<id>` — no): edit the
111
+ module source and compile. the `schema` verbs are the sanctioned exception — they write
112
+ sources *through* a compile gate, so an uncompilable source can never land.
113
+ 8. **never duplicate a procedure across records.** a command body restating a skill, an agent
114
+ inlining its skill's steps — two copies, and one drifts. reference the owner.
115
+ 9. **nothing module-shipped names a person, an account or a machine path.** per-install values
116
+ are `${env:VAR}` templates plus a declared var, rendered only by `dt resolve`
117
+ (`references/records.md`).
118
+ 10. **commit discipline: scope to what YOU wrote** — `dt commit <collection>/<id> …` — and never
119
+ `git add -A`, `git add .` or `git commit -a`: a blanket add silently sweeps another session's
120
+ pending work under your subject. commit when a logical change is complete — records via
121
+ `dt commit`, sources via `git add <specific paths>`; `dt status` says what is pending, and
122
+ `dt check` runs after bulk edits.
120
123
 
121
124
  ## common mistakes
122
125
 
123
- | mistake | why it bites |
126
+ | mistake | reality |
124
127
  |---|---|
125
- | editing something under `.dreamteamer/` | generated + gitignored; the change vanishes on the next compile |
126
- | changing a source and not compiling | the harness and `check` still read the stale runtime |
128
+ | editing under `.dreamteamer/` or `.claude/` | generated the change vanishes next compile; find the module source |
129
+ | changing a source and not compiling | the CLI, `check` and every harness still read the stale runtime |
127
130
  | hand-writing a record the CLI could add | skips validation, id generation and defaults |
128
131
  | bare refs (`ada`, `data/contacts/x.contact.md`) | refs are `<collection>/<id>`; anything else fails check |
129
- | assuming a write was committed | it was not, unless `auto-commit` is on — `dt status` says what is pending |
132
+ | assuming a write was committed | it was not (unless `auto-commit` is on) — `dt status` shows pending |
133
+ | learning flags from prose or memory | `dt help` is the surface; prose carries judgment only |
134
+ | a new module folder compile ignores | its `package.json` needs a `dreamteamer` key |
130
135
  | `git add -A` in a shared tree | steals another session's uncommitted work, invisibly |
131
- | an absolute machine path in a record | it is wrong on every other machine — write `${env:NAME}` and declare the key |
136
+ | an absolute machine path in a record | wrong on every other machine — `${env:NAME}` + a declared var |
137
+ | picking an entity by what is easiest to write | pick by how it should be TRIGGERED — that is what the choice encodes |
138
+ | telling the operator a new source works now | it works in their **next** session |
@@ -0,0 +1,162 @@
1
+ # agents — a persona you pay a whole context for
2
+
3
+ `modules/<module>/agents/<name>.agent.md` — one markdown file whose filename MUST equal the
4
+ frontmatter `name`. Compile turns it into a dispatchable subagent definition with one real
5
+ transform (below), so the record *is* the subagent.
6
+
7
+ You are usually here for one of two reasons: deciding whether an agent is the right entity at all,
8
+ or authoring one. Either way, what you write is judged by three readers who are not you:
9
+
10
+ - the **dispatcher** — a harness or a master agent matching a request against `description`. That
11
+ one line is the agent's entire discoverability;
12
+ - the **agent itself** — waking with your body as its system prompt, its declared skills, its
13
+ declared tools, and **none of the caller's context**;
14
+ - the **caller** — who gets back only what the agent chooses to hand back, and must act on it.
15
+
16
+ | the question | read |
17
+ |---|---|
18
+ | should this be an agent at all | the economics |
19
+ | what compile does with the file | mechanics |
20
+ | the one line the dispatcher sees | the description |
21
+ | the body | the system prompt |
22
+ | tools, model, skills | the allowances |
23
+ | does it actually work | verification |
24
+
25
+ ## the economics — when an agent earns a context
26
+
27
+ An agent costs a whole context per dispatch: the harness spins up a fresh session, loads the
28
+ declared skills, and the persona re-orients from zero before its first useful act. That cost buys
29
+ exactly four things, and a job that needs none of them should be something cheaper:
30
+
31
+ | the job needs | why an agent and nothing else delivers it |
32
+ |---|---|
33
+ | **isolation** — fresh eyes that must not share the caller's context | a reviewer or critic run inside the author's context inherits the author's blind spots; the empty context IS the value |
34
+ | **a narrower tool set, as a guarantee** | "read-only" enforced by allowlist, not by promise — a skill inherits whatever tools the session already has |
35
+ | **parallelism** — several independent subtasks at once | each needs its own context by construction |
36
+ | **routing** — a persona whose whole job is picking the right collection, skill or agent | the master-agent pattern; core's own `dreamteamer` agent is exactly this |
37
+
38
+ What does *not* justify one:
39
+
40
+ - **Size.** "It's a big task" — the current session can do big tasks; a skill tells it how.
41
+ - **Recurrence.** A situation that keeps arising wants a skill, which triggers itself.
42
+ - **A shortcut.** Something the operator deliberately types is a command.
43
+ - **A procedure.** Procedures live in skills; an agent *references* its skills, never restates
44
+ them (the digest's never-duplicate rule — two copies drift).
45
+
46
+ The tie-breakers, as tests: if "just tell the current session how" works, write the skill. If the
47
+ operator must remember to run it, write the command. Write the agent only when the fresh context is
48
+ a *feature* — independence, enforcement, parallelism — rather than an overhead.
49
+
50
+ ## mechanics — what compile does with the file
51
+
52
+ - **Copies it to `.claude/agents/<name>.md`** (stamped as generated) with **one transform**: the
53
+ `skills:` frontmatter list is not a key any harness understands, so compile deletes it and
54
+ prepends a body line — *"ALWAYS load these skills (Skill tool) before acting: …"*. Everything
55
+ else passes through verbatim.
56
+ - **Validates the skill refs.** A `skills:` entry naming a skill that is not in this compile is a
57
+ **compile error**, not a dangling pointer — an agent cannot ship pointing at a skill its module
58
+ forgot to bring. Self-containment with teeth: the module that ships the agent ships (or depends
59
+ on) its skills.
60
+ - **Only claude-code gets native agent files.** The other harnesses' orientation blocks point at
61
+ `.dreamteamer/agents/` and leave dispatch to whoever reads them. Write for the record, not for
62
+ one harness's dispatch mechanics.
63
+ - Like every source: a new or changed agent exists in the **next** session, not this one.
64
+
65
+ | field | required | notes |
66
+ |---|---|---|
67
+ | `name` | yes | must equal the filename — this is the id, and dispatch misses when they disagree |
68
+ | `description` | yes | **when a dispatcher should pick this agent** — concrete triggers, never a role title |
69
+ | `tools` | no | the allowlist; give only what the job needs. Omit = the harness default set, which is broad |
70
+ | `model` | no | override (`sonnet`, `opus`, …); omit to inherit the session's |
71
+ | `skills` | no | qualified `skills/<id>` refs, verified at compile — loaded before the agent acts |
72
+
73
+ The body is the `instructions` field (`x-body: true`) and becomes the subagent's system prompt.
74
+
75
+ ## the description — written for the dispatcher
76
+
77
+ The dispatcher sees the description and nothing else. A role title ("the research agent") gives it
78
+ nothing to match against; triggers do — the request shapes, symptoms, and words a caller would
79
+ actually use:
80
+
81
+ ```yaml
82
+ # ✖ a role title — matches nothing in particular, so it matches wrongly
83
+ description: the review agent
84
+
85
+ # ✔ dispatch conditions — request shapes, concrete situations
86
+ description: dispatch when freshly-written records need checking against their collection's
87
+ conventions before commit — a batch import, a bulk edit, records written by a new skill
88
+ ```
89
+
90
+ Same discipline as a skill description (`skills.md`): conditions, not contents. A description that
91
+ summarizes what the agent will do invites the dispatcher to do it itself instead of dispatching.
92
+
93
+ ## the body — a system prompt for someone with no memory of this conversation
94
+
95
+ The agent wakes knowing only what the body, its skills, and the dispatch prompt tell it. Three
96
+ parts, in order, and rarely more than a paragraph:
97
+
98
+ 1. **What to read first** — the records, descriptors or files that orient it.
99
+ 2. **What to do** — by reference to its skills, never by restating them. The body says *which*
100
+ judgment to apply; the skill owns *how*.
101
+ 3. **What to hand back — the return contract.** The most-omitted part, and the one the caller
102
+ actually depends on. An agent whose body never states its output shape returns an essay, and
103
+ the caller re-derives what it needed from prose. Name the shape: the verdict, the evidence,
104
+ what was not checked.
105
+
106
+ A body growing past ~15 lines has swallowed a skill — extract the procedure into one and reference
107
+ it.
108
+
109
+ Two references worth copying. Core's `agents/dreamteamer.agent.md` — the only agent core ships —
110
+ shows the router shape: trigger description, tight tool list, one skill ref, one-paragraph body.
111
+ And the reviewer shape, annotated:
112
+
113
+ ```yaml
114
+ ---
115
+ name: record-reviewer
116
+ description: dispatch when freshly-written records need checking against their collection's
117
+ conventions before commit — a batch import, a bulk edit, records written by a new skill
118
+ tools: [Read, Grep, Glob, Bash] # no Write, no Edit — read-only is the guarantee
119
+ skills: [skills/using-dreamteamer] # qualified; verified at compile
120
+ ---
121
+ Load the skills above, then read the compiled descriptor of every collection the dispatch prompt
122
+ names. Sample the named records against them: field conventions, reference shape, id shape,
123
+ suspiciously empty required fields. Do not fix anything. Hand back one line per problem —
124
+ `<ref> — <what is wrong> — <the fix>` — then the list of records checked and found clean.
125
+ ```
126
+
127
+ Why each line earns its place: the tool list omits Write/Edit because the *allowlist* is the
128
+ enforcement (the body's "do not fix anything" is only the explanation); the description names three
129
+ dispatch situations, not a title; the body is read → judge → hand back, with the return contract
130
+ concrete enough that the caller can act on it mechanically.
131
+
132
+ ## the allowances — tools, model, skills
133
+
134
+ - **Tools**: subtract, don't add. Start from what the job cannot work without; a Write tool on a
135
+ read-only reviewer is a footgun, and "it might need it" is how footguns ship. Omitting the key
136
+ means the harness default — which is broad, and therefore also a choice.
137
+ - **Model**: omit to inherit. Override downward for cheap high-volume jobs (a formatter, a
138
+ triager); override upward only when the job measurably fails on the default.
139
+ - **Skills**: one or two. Each ref is loaded on *every* dispatch — a per-invocation cost, which is
140
+ why the procedure lives in the skill once instead of being pasted into both. Design the pair to
141
+ be self-sufficient: a subagent cannot reliably ask the caller questions mid-flight, so what it
142
+ needs must arrive in the body, the skills, or the dispatch prompt.
143
+
144
+ ## verification
145
+
146
+ Compile + check prove the record is well-formed, not that the persona works. In the next session
147
+ (or from a fresh dispatch): give it a realistic task and judge the **result shape** — did it load
148
+ its skills, did the tool limits hold, and above all did it hand back the return contract, or an
149
+ essay? Reading your own agent definition proves nothing; the same rule as skills.
150
+
151
+ ## common mistakes
152
+
153
+ | mistake | reality |
154
+ |---|---|
155
+ | a `description` that is a role title ("the research agent") | dispatchers match on triggers; say when to pick it |
156
+ | `skills: [using-dreamteamer]` | refs are qualified: `skills/using-dreamteamer` |
157
+ | pasting the skill's procedure into the body | two copies, one drifts; the body references, the skill owns |
158
+ | no return contract in the body | the agent returns an essay and the caller re-derives the answer |
159
+ | a broad `tools` list "just in case" | the allowlist is the enforcement — a Write tool on a reviewer is a footgun |
160
+ | creating an agent for a one-off instruction | a skill (recurring) or just doing it (one-off) is the right answer |
161
+ | creating an agent because the task is big | size is not isolation; a skill in the current session handles big |
162
+ | testing by reading the definition | dispatch it with a real task and judge what it hands back |
@@ -0,0 +1,99 @@
1
+ # before you build — look for it first
2
+
3
+ The situation: the operator asked for something the workspace does not seem to do, and you are one
4
+ `schema add-collection` or one new skill away from making it exist. This reference is the pause
5
+ before that. **When the workspace can't do something, look before you build — and when you do find
6
+ something, propose concretely, never install or copy silently.** The operator decides what enters
7
+ their workspace.
8
+
9
+ Two people meet in this decision, and only one of them is in the room. The session about to build
10
+ (you) experiences exactly one step of the capability's life: creating it, which is also its
11
+ cheapest step. The operator owns every other step — compiling it, maintaining it, paying for its
12
+ line in the orientation block every session loads, and eventually noticing it drifted or died.
13
+ Every rule below is that asymmetry applied.
14
+
15
+ | the question | read |
16
+ |---|---|
17
+ | where do I look, and how, concretely | the four places |
18
+ | I found something — is that "found"? | what found means |
19
+ | how do I put it to the operator | the proposal |
20
+ | nothing exists anywhere | build it — in the module that owns the concept (`data-modeling.md` Part III), after proposing (Part II §7) |
21
+
22
+ This replaced a standalone `discovering-new-capabilities` skill on 2026-07-31, whose premise — "find
23
+ and propose an **installable** module" — had been reversed: domain modules are no longer packages you
24
+ install. The looking still matters; the taking changed shape.
25
+
26
+ ## why looking wins
27
+
28
+ - **A duplicate is worse than a gap.** Two collections holding one concept under two names split
29
+ every future search, and neither ever learns what the other knows. A gap at least stays visible.
30
+ - **The thing you didn't find still costs you.** Building beside an existing capability means the
31
+ operator now maintains both, and the day they diverge nobody can say which is right.
32
+ - **Adoption is mostly deletion.** A found module arrives maximal — collections you don't need,
33
+ skills for accounts you don't have. The work of adopting it is cutting it down, which is far
34
+ cheaper than building up, and keeps the found thing's hard-won trap notes intact.
35
+ - **Hard-to-find is its own diagnosis.** When the capability existed and you missed it, the fix is
36
+ a better `description` or `use_when` on the existing entity — not a second entity. The miss you
37
+ just experienced is exactly the retrieval test that description failed.
38
+
39
+ ## the four places, in order
40
+
41
+ | # | look at | how, concretely | what you get |
42
+ |---|---|---|---|
43
+ | 1 | **this workspace's own modules** | the orientation block's COLLECTIONS list is already in your context — reread it with the concept's *synonyms* in mind; `.dreamteamer/manifest.yaml` names every module and entry; `dt help` shows the verbs and `dt commands <collection>` the bound ones; the skills index shows the techniques | the thing may already exist under a name you didn't guess. This is where misses actually happen, because it is the place you assume you already know |
44
+ | 2 | **a recipes repo — where this workspace's own CLAUDE.md names one** (reference modules maintained to be **copied and adapted**) | read that repo's own instructions first; they ARE the adoption procedure. no recipes repo declared → skip this row | a working module with its reasoning attached — descriptors, skills, and the trap notes that each cost someone a day |
45
+ | 3 | **a sibling workspace — where the operator has named one** | read-only; grep its `modules/` for the concept. none named → skip | another vault may have solved it concretely. That is a *reference*, not a source — it holds real personal data, so read the shape, never lift the content |
46
+ | 4 | **the engine's own surface** | `dt help` — the complete verb surface, schema verbs included; read it rather than recalling it | the capability may already be a verb (`relations rebuild`, `resolve`, `ensure`) rather than a missing module |
47
+
48
+ Only after all four: build it, in the module that owns the concept.
49
+
50
+ ## what "found" actually means
51
+
52
+ Rarely the exact thing. Four outcomes, each with its own move:
53
+
54
+ | what you found | the move |
55
+ |---|---|
56
+ | the exact capability, live in this workspace | use it — and if finding it took effort, fix the `description`/`use_when` that made it hard, in the same breath |
57
+ | a recipe covering most of it | propose copy-and-adapt (below). Adoption is deletion |
58
+ | a partial match — a collection that could grow a field, a skill that covers half the job | propose extending the existing thing, in the module that owns the concept. Growing a field on the right collection beats a new collection every time (`data-modeling.md` Part IX: additive first) |
59
+ | a concrete solution in a sibling workspace | read it for shape and traps, rebuild clean with a synthetic cast — never lift records, names, or account details |
60
+
61
+ ## how to propose
62
+
63
+ Say three things: **what you found**, **what adopting it would cost**, and **what you would delete
64
+ from it**. That last one is not politeness — adoption is mostly deletion, and a proposal that skips
65
+ it is asking the operator to accept a maximal module sight unseen. Name the `.env` keys, external
66
+ accounts and binaries it needs, because a skill whose setup nobody did is a skill that fails at the
67
+ worst possible moment.
68
+
69
+ The shape, at the size it should be:
70
+
71
+ > Found: `recipes/clinic` ships `health/lab-values` plus an ingest skill for lab-report PDFs.
72
+ > Cost: one `.env` key (`FILES_FOLDER`), no binaries, ~300 lines of skill prose in every future
73
+ > compile. I would delete: the portal-scraping half (you file PDFs by hand), the `insurers`
74
+ > collection (out of scope here), and its example cast. I would keep: the collection, the
75
+ > one-value-per-record grain, and the dedupe rule — that last one is the part worth having.
76
+
77
+ Then stop and let them choose. Copying a recipe in is a one-way door in practice: from that moment
78
+ the copy is theirs to maintain, and nothing will later tell them it drifted from the original.
79
+
80
+ ## the one-way doors, named
81
+
82
+ - **Copying a recipe in** — yours from that moment; drift from the original is silent by design.
83
+ - **Creating a collection** — cheap to make, expensive to retire: records accumulate, references
84
+ point at it, and deleting it later is a migration, not an undo.
85
+ - **Installing anything** (`npm i`, `git_modules/`) for a domain module — recipes are copied, not
86
+ installed; importing one re-creates the fork the copy-and-adapt split exists to avoid.
87
+
88
+ ## common mistakes
89
+
90
+ | mistake | reality |
91
+ |---|---|
92
+ | building because you didn't find it in 30 seconds | there are four places to look, and the first is this workspace |
93
+ | searching only the literal word the operator used | the existing thing is usually filed under a synonym — search the concept, not the string |
94
+ | `npm i` / `git_modules` a recipe module | recipes are copied, not installed — importing re-creates the fork the split exists to avoid |
95
+ | copying a recipe in and keeping all of it | deleting what you won't use IS the adoption step |
96
+ | lifting from another workspace under `projects/` | those hold real personal data; read for reference only |
97
+ | proposing without naming the setup cost | the `.env` keys and the accounts are the actual price |
98
+ | installing or copying, then telling the operator | they decide what enters their workspace, before it enters |
99
+ | finding it, using it, and leaving the bad description in place | the next session will miss it exactly as you just did |
@@ -0,0 +1,55 @@
1
+ # what changed — record events derived from git
2
+
3
+ **core principle:** record events are never observed live — they are **derived from git
4
+ history**. a closed laptop loses nothing, every derivation is auditable and replayable forever,
5
+ and history IS the queue: there is no events file, and there never should be.
6
+
7
+ ```bash
8
+ dt changes # what the last commit changed (--since HEAD~1)
9
+ dt changes --since <sha|YYYY-MM-DD>
10
+ dt changes --json
11
+ ```
12
+
13
+ per record it reports the collection, the id and one of `item-added` / `item-updated` /
14
+ `item-removed`, grouped by collection with counts. **read-only by construction** — no cursor,
15
+ nothing stored, so running it twice is free and running it wrong costs nothing.
16
+
17
+ ## when to use
18
+
19
+ the operator asks what changed or what they missed; you are reconciling after a batch of edits or
20
+ a bulk rewrite; you want to know what a range of commits did to the *data*. **not for** ordinary
21
+ "show me the diff" questions — plain `git log` / `git diff` is better — not for reading or
22
+ writing individual records (`records.md`), and not for UNCOMMITTED writes: it diffs commits, so
23
+ pending records are invisible to it (`dt commit --dry-run` shows those).
24
+
25
+ ## the mechanism — enough to trust its edges
26
+
27
+ 1. it covers **every repo that holds records**: each compiled descriptor's `storage.path`,
28
+ grouped per repo (a module can own its records). a changed path that matches no descriptor is
29
+ **skipped** — source and runtime churn are not data events — and runtime entities never
30
+ appear.
31
+ 2. `--since` takes a sha or a date. a sha is resolved to its commit DATE in the workspace repo
32
+ (a sha means nothing in another repo), and each repo then resolves that date against its own
33
+ history; a repo younger than the date reports everything in it as added. ⚠ a bare date is
34
+ pinned to **midnight** deliberately — git's own approxidate fills missing fields from the
35
+ current clock, so the same command would answer differently morning and evening (measured).
36
+ 3. the git status letter becomes the event: `A` → added, `M` → updated, `D` → removed. **a
37
+ rename emits removed + added** — there is deliberately no `item-renamed`, because the id IS
38
+ the path and a moved record is a different record to any consumer.
39
+
40
+ ## if you are ever asked to automate on top of this
41
+
42
+ this derivation is the surviving half of a removed automation layer (its run-records went unused:
43
+ one workflow, nine runs, seven abandoned, in three days). the lessons it left: **never store an
44
+ event queue** — a queue drifts from reality, history cannot; make every evaluator **idempotent
45
+ over a range** (the old design keyed on `trigger + item + commit` — reuse that shape); and **a
46
+ migration is not a data event** — a bulk rewrite looks like N added records, so scope past it
47
+ rather than run over it.
48
+
49
+ ## common mistakes
50
+
51
+ | mistake | reality |
52
+ |---|---|
53
+ | hand-rolling the diff + path mapping | `dt changes` is the mechanism; a hand-roll misses folder-shape records, per-repo grouping and the rename split |
54
+ | writing an events file to "remember" what changed | history is the record; anything you write can drift from it |
55
+ | reading the output as a to-do list | it says what changed, not what it means — the judgment is yours |