You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
docs: refresh narrative docs for drawn-mask-only architecture (v1.5.0)
Doc-only follow-up to the ADR-076 cleanup. The previous commit landed code, tests, and ADRs; this one updates the narrative tier (concept/PRD/RFC/getting-started/api/index) so users reading the docs see the same architecture the code now reflects.
- RFC-003/004/009: status markers updated to "superseded by ADR-076".
- PRD-004: reframed as partially-shipped — drawn-form geometric masks today, content-aware masking deferred to Phase 4 via a sibling project producing darktable drawn-form geometry. Original aspirational lede preserved.
- concept/04-architecture.md: section 6 (Local adjustments) rewritten around mask_spec + drawn-form serialization; section 7.4 (Mask integration) collapses the dead PNG-storage option discussion into a one-paragraph "masks ride inside the XMP" note.
- concept/03-data-catalog.md: vocabulary-manifest example uses gradient_top_dampen_highlights; Generated-masks section becomes Mask-geometry-in-the-XMP; Masking-providers row reframed around v1.5 + Phase 4.
- concept/00-introduction.md: glossary updates — drops Raster mask / Mask registry / Symbolic mask reference / Masking provider entries; adds mask_spec and Content-aware masking (Phase 4).
- getting-started.md: session walkthrough rewritten around shipped drawn-form entries (gradient_top_dampen_highlights, gradient_bottom_lift_shadows) instead of the old generate_mask / mask_override flow; troubleshooting MASKING_ERROR re-aimed at malformed mask_spec.
- api/index.md, index.md: tool count corrected (27 → 22), masking subsystem bullet rewritten, masks/ removed from workspace tree.
- phase-3-preview.md: substantially rewritten — Phase 3 is now expanding the masked vocabulary across drawn-form + parametric flavors, both authorable today; content-aware framed as Phase 4.
No code or test changes.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Copy file name to clipboardExpand all lines: docs/concept/00-introduction.md
+8-12Lines changed: 8 additions & 12 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -93,7 +93,7 @@ The vocabulary used across the package. When in doubt about what a term means, f
93
93
94
94
**Chemigram** — the project itself. Named after the cameraless photographic process where an image emerges from chemical reaction on light-sensitive paper, guided but not fully controlled. The name fits because each edit emerges from a loop between photographer's intent, agent's moves, and tool's response.
95
95
96
-
**Engine** — the Python code that does the orchestration. Includes XMP composition, vocabulary loading, render pipeline, versioning, mask registry, and MCP server. See `04`/2.
96
+
**Engine** — the Python code that does the orchestration. Includes XMP composition, vocabulary loading, render pipeline, versioning, drawn-mask serialization, and MCP server. See `04`/2.
97
97
98
98
**Agent** — the AI capability that drives Mode A or Mode B sessions. Per the BYOA principle, the agent is photographer-configured (Claude, GPT, etc.), not bundled with Chemigram.
99
99
@@ -117,7 +117,7 @@ The vocabulary used across the package. When in doubt about what a term means, f
117
117
118
118
**`.dtstyle`** — the file format of a vocabulary primitive. XML, captures one module's parameters and blend operation. Authored by photographer (or community) in darktable's GUI; loaded by Chemigram at session start.
119
119
120
-
**Manifest** — the JSON metadata accompanying vocabulary entries. Contains layer assignment, modules touched, tags, description, mask kind, and other engine-relevant metadata.
120
+
**Manifest** — the JSON metadata accompanying vocabulary entries. Contains layer assignment, modules touched, tags, description, optional `mask_spec` (drawn-form geometry for mask-bound entries), and other engine-relevant metadata.
121
121
122
122
**Vocabulary gap** — when the agent needs a primitive that doesn't exist. Worked around by composing existing primitives, then logged to `vocabulary_gaps.jsonl` for later authoring. Gaps are content, not failure.
123
123
@@ -155,19 +155,15 @@ The vocabulary used across the package. When in doubt about what a term means, f
155
155
156
156
### Masks
157
157
158
-
**Mask** — a spatial selection that restricts an effect to part of the frame. Three kinds in Chemigram: parametric, drawn, raster.
158
+
**Mask** — a spatial selection that restricts an effect to part of the frame. Two kinds in Chemigram (per ADR-076): parametric and drawn. (The earlier raster-PNG path was retired in v1.5.0 — darktable doesn't read external PNGs for raster masks.)
159
159
160
160
**Parametric mask** — a mask defined by pixel-value conditions (luminance range, hue range, etc.) in `blendop_params`. Content-agnostic.
161
161
162
-
**Drawn mask** — a mask defined by geometric primitives (gradient, circle, ellipse, path) in `blendop_params`. Pre-authored by photographer in GUI.
162
+
**Drawn mask** — a mask defined by geometric primitives (gradient, ellipse, rectangle, path) encoded into `<darktable:masks_history>` and bound to plugins via `blendop_params.mask_id`. Either pre-authored by the photographer in darktable's GUI, or declared in a vocabulary entry's `mask_spec` and serialized at apply time.
163
163
164
-
**Raster mask** — a PNG mask file referenced by darktable. The path for AI-generated subject masks. Resolved symbolically at XMP synthesis time.
164
+
**`mask_spec`** — a vocabulary-entry field declaring drawn-form geometry. Shape: `{"dt_form": "gradient" | "ellipse" | "rectangle", "dt_params": {...}}`. Presence triggers the drawn-mask apply path. See `04`/6.2.
165
165
166
-
**Mask registry** — Chemigram's per-image record of generated masks. Tracks names, generators, prompts, freshness. See `04`/6.3.
167
-
168
-
**Symbolic mask reference** — a placeholder name like `current_subject_mask` that vocabulary entries use. The engine resolves the symbol to an actual PNG path at synthesis time. Lets multiple primitives reuse the same mask.
169
-
170
-
**Masking provider** — a pluggable implementation that generates masks. v1 ships a coarse agentic default; production-quality masking via `chemigram-masker-sam` sibling project. Configurable per target type. See `04`/6.4.
166
+
**Content-aware masking (Phase 4)** — pixel-precise organic masks (e.g., subject silhouettes) come from a future sibling project that produces darktable drawn-form geometry. Not available in v1.5.0; the `apply_with_drawn_mask` seam is ready when it ships. See `04`/6.4.
171
167
172
168
### Context files
173
169
@@ -177,15 +173,15 @@ The vocabulary used across the package. When in doubt about what a term means, f
177
173
178
174
**`notes.md`** — what we've learned about a specific image. Lives at `<image_id>/notes.md`. Accumulates across sessions on the same image.
**Agent is the only writer** — the photographer reads previews and gives feedback; the agent is the sole mutator of edit state. See `04`/1.1.
185
181
186
182
**darktable does the photography, Chemigram does the loop** — every image-processing capability comes from darktable. Chemigram contributes orchestration, vocabulary, agent loop, versioning, session capture. See `04`/1.2.
187
183
188
-
**BYOA (Bring Your Own AI)** — Chemigram doesn't ship AI capabilities; it integrates them via MCP. Maskers, evaluators, the photo agent itself are all photographer-configured. See `04`/1.3.
184
+
**BYOA (Bring Your Own AI)** — Chemigram doesn't ship AI capabilities; it integrates them via MCP. The photo agent itself is photographer-configured (Claude, GPT, etc.); future evaluators and content-aware maskers are sibling projects, not bundled in core. See `04`/1.3.
Copy file name to clipboardExpand all lines: docs/concept/03-data-catalog.md
+23-29Lines changed: 23 additions & 29 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -59,27 +59,28 @@ The agent's action space. The most important content type in the project.
59
59
| Format | XML per darktable's `.dtstyle` schema. Each `<plugin>` entry has `<operation>`, hex `<op_params>`, gzip+base64 `<blendop_params>`, modversion, iop_order |
60
60
| Authoring | In darktable GUI: set one module to desired value, save as named style, export as `.dtstyle`|
61
61
| Layer attribution | L1 (technical correction), L2 (look establishment), L3 (taste/agent vocabulary) — see `04`/Layer model |
62
-
| Mask kinds |`none` (global), `parametric` (luminance/hue/chroma masks in `blendop_params`), `drawn` (geometric primitives in `blendop_params`), `raster` (external PNG via mask reference)|
62
+
| Mask kinds |`none` (global), `parametric` (luminance/hue/chroma masks in `blendop_params`), `drawn` (geometric primitives — gradient/ellipse/rectangle/path — encoded into `masks_history` and bound via patched `blendop_params`). Per ADR-076 the earlier raster-PNG path was retired in v1.5.0.|
63
63
| Lifecycle | Authored once, used many times. Versioned alongside darktable releases. |
64
64
| Distribution | Bundled starter (this monorepo, MIT). Community packs (this monorepo, attributed). Personal vocabularies (separate private repos). See `docs/LICENSING.md`. |
The user's configuration. Vocabulary sources and L1/L2 binding rules.
106
107
107
108
```toml
108
109
[vocabulary]
@@ -112,9 +113,6 @@ sources = [
112
113
"~/private/chemigram-vocabulary-marko",
113
114
]
114
115
115
-
[masking]
116
-
default_provider = "sam-mcp"
117
-
118
116
[[layers.L1.bindings]]
119
117
camera = "NIKON D850"
120
118
lens = "AF-S Nikkor 24-70mm f/2.8E ED VR"
@@ -145,7 +143,6 @@ Each image is its own project (per `04`/Project structure):
145
143
sessions/ # transcripts
146
144
previews/ # render cache
147
145
exports/ # final outputs
148
-
masks/ # registered masks
149
146
vocabulary_gaps.jsonl # gaps surfaced this image
150
147
```
151
148
@@ -187,9 +184,9 @@ Content-addressed by SHA-256 over canonical XMP serialization. Each snapshot is
187
184
188
185
Full conversation logs from Mode A sessions. Per-session: goal, brief at start, full transcript, snapshots produced, vocabulary used, gaps surfaced, outcome. JSONL format, one entry per turn.
189
186
190
-
### Generated masks (`masks/`)
187
+
### Mask geometry (inside the XMP)
191
188
192
-
PNG raster masks generated by configured masking providers. Registered with symbolic names (`current_subject_mask`, `current_sky_mask`, custom-named persistent masks). Vocabulary entries reference these symbolically; engine resolves to actual paths at synthesis time.
189
+
Drawn-form masks ride inside the XMP they belong to — `<darktable:masks_history>` carries the geometry, plugins' `blendop_params` reference it via `mask_id`. There is no separate mask directory or registry; the snapshot's content hash captures both the dtstyle and its mask binding atomically. Per ADR-076 (the v1.5.0 cleanup), the previous PNG-based `masks/` directory was retired — darktable never read those files, so the path was a silent no-op.
193
190
194
191
## External AI capability (BYOA — Bring Your Own AI)
195
192
@@ -204,15 +201,13 @@ Per `04`'s BYOA principle, AI capabilities are not bundled with Chemigram. They'
204
201
| Required capabilities | Vision (to look at preview JPEGs), tool use (to call Chemigram's MCP tools), reasoning over reasonably-long context (~50-100K tokens for a typical session) |
205
202
| Not required | Specific model family. The system prompt is portable. |
206
203
207
-
### Masking providers
204
+
### Mask provision
208
205
209
206
| Property | Detail |
210
207
|-|-|
211
-
| Role | Generate PNG raster masks from preview images and target descriptions |
212
-
| Access |`MaskingProvider` protocol; default implementations call out via MCP |
213
-
| v1 default | Coarse agentic provider — uses photo agent's vision capability for bbox/gradient/color-region masks. No PyTorch dependency. Sufficient for many cases, especially Layer 1 vocabulary. |
214
-
| Production option |`chemigram-masker-sam` sibling project — wraps SAM/MobileSAM/SAM 2 as MCP server. Local install, GPU-accelerated. Pixel-precise subject segmentation. |
| v1.5.0 | Drawn-form geometry baked into vocabulary entries' `mask_spec`. Three forms supported: gradient, ellipse, rectangle. Encoded directly into the XMP's `masks_history` at apply time; no AI involved. See ADR-076. |
209
+
| Phase 4 | Sibling project (working name `chemigram-masker-sam`) producing darktable-compatible drawn-form geometry from natural-language prompts. Wire format is the same darktable schema the geometric primitives use today — not PNG bytes. The apply path stays unchanged when content-aware masking lands. |
210
+
| Out of scope | PNG-based mask interchange. The earlier `MaskingProvider` Protocol (returning PNG bytes) was retired in v1.5.0 — verified that darktable never reads external PNGs for raster masks. |
216
211
217
212
### Mode B evaluators (future)
218
213
@@ -244,7 +239,7 @@ Vocabulary entries can reference these via relative path. Engine copies path int
244
239
245
240
## Session data is local-only
246
241
247
-
A key principle: session data — transcripts, taste evolution, preference history, generated masks, vocabulary gaps — never leaves the photographer's machine automatically. No telemetry. No phone-home. No cloud dependency.
242
+
A key principle: session data — transcripts, taste evolution, preference history, vocabulary gaps — never leaves the photographer's machine automatically. No telemetry. No phone-home. No cloud dependency.
248
243
249
244
If a photographer chooses to publish anonymized insights, that's their choice. The project provides no infrastructure for publishing session data and no encouragement to do so by default.
250
245
@@ -264,9 +259,8 @@ This is part of the agent-is-the-only-writer discipline — not just an architec
What feeds Chemigram comes from four directions: darktable provides processing, photographer provides taste, configured agents provide AI capability, community provides vocabulary packs. Chemigram itself produces orchestration and accumulated state.
0 commit comments