feat: add memory, convergence, colette bridge, templates, progress, effectiveness, git integration
- skills/memory: cross-run learning from recurring findings + lib/archeflow-memory.sh - skills/convergence: oscillation detection + early termination in multi-cycle runs - skills/colette-bridge: auto-inject voice profiles, personas, characters from colette.yaml - skills/templates: workflow/team/archetype gallery with init/save/share - skills/progress: live .archeflow/progress.md during runs - skills/effectiveness: per-archetype signal-to-noise + cost efficiency scoring - skills/git-integration: auto-branch per run, commit per phase, rollback support
This commit is contained in:
392
skills/colette-bridge/SKILL.md
Normal file
392
skills/colette-bridge/SKILL.md
Normal file
@@ -0,0 +1,392 @@
|
||||
---
|
||||
name: colette-bridge
|
||||
description: |
|
||||
Bridges ArcheFlow with the Colette writing platform. Auto-detects colette.yaml in the project
|
||||
root, resolves voice profiles, personas, and character sheets, then builds a summarized context
|
||||
bundle that gets injected into every agent prompt via artifact routing. Eliminates manual
|
||||
copy-pasting of writing context into agent prompts.
|
||||
<example>Automatically loaded when colette.yaml is detected at run.start</example>
|
||||
<example>User: "archeflow:run" in a project with colette.yaml</example>
|
||||
---
|
||||
|
||||
# Colette Bridge — Writing Context Auto-Loader
|
||||
|
||||
When ArcheFlow detects `colette.yaml` in the project root, this skill automatically loads voice profiles, personas, character sheets, and project rules into a context bundle that every agent receives (filtered by archetype role).
|
||||
|
||||
## Prerequisites
|
||||
|
||||
- `archeflow:domains` — Colette Bridge sets domain to `writing` automatically
|
||||
- `archeflow:artifact-routing` — bundle is injected via the artifact routing system
|
||||
- `archeflow:run` — bridge hooks into run initialization
|
||||
|
||||
## Trigger
|
||||
|
||||
At `run.start`, after domain detection but before the Plan phase:
|
||||
|
||||
1. Check if `colette.yaml` exists in the project root
|
||||
2. If found, activate Colette Bridge
|
||||
3. If not found, skip silently (no error, no warning)
|
||||
|
||||
When the bridge activates, it emits a decision event:
|
||||
|
||||
```bash
|
||||
./lib/archeflow-event.sh "$RUN_ID" decision init "" \
|
||||
'{"what":"colette_bridge","chosen":"activated","signal":"colette.yaml found","files_resolved":<count>}'
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## File Resolution
|
||||
|
||||
Colette projects reference files by ID (e.g., `vp-giesing-gschichten-v1`) but the actual YAML files may live in different locations. The bridge resolves files using this search order:
|
||||
|
||||
### Search Priority (highest first)
|
||||
|
||||
| Priority | Location | Example |
|
||||
|----------|----------|---------|
|
||||
| 1 | Explicit path in `colette.yaml` | `voice.profile: ../writing.colette/profiles/custom.yaml` |
|
||||
| 2 | Project root subdirectories | `./profiles/vp-giesing-gschichten-v1.yaml` |
|
||||
| 3 | Parent directory + `writing.colette/` | `../writing.colette/profiles/vp-giesing-gschichten-v1.yaml` |
|
||||
|
||||
### What Gets Resolved
|
||||
|
||||
| Source | colette.yaml field | Search paths |
|
||||
|--------|-------------------|-------------|
|
||||
| Voice profile | `voice.profile` | `profiles/<id>.yaml`, `../writing.colette/profiles/<id>.yaml` |
|
||||
| Persona | `writing.persona` or inferred from profile | `personas/<id>.yaml`, `../writing.colette/personas/<id>.yaml` |
|
||||
| Characters | Auto-discovered | `characters/*.yaml` |
|
||||
| Series config | `series` section (if present) | `colette.yaml` itself, `../writing.colette/series/<name>.yaml` |
|
||||
| Project rules | Always | `CLAUDE.md` in project root |
|
||||
|
||||
### Resolution Procedure
|
||||
|
||||
```
|
||||
for each reference in colette.yaml:
|
||||
1. If the field contains a path (has / or .yaml) → use as-is, verify exists
|
||||
2. If the field contains an ID (e.g., "vp-giesing-gschichten-v1"):
|
||||
a. Check ./profiles/<id>.yaml (or ./personas/<id>.yaml)
|
||||
b. Check ../writing.colette/profiles/<id>.yaml (or ../writing.colette/personas/<id>.yaml)
|
||||
c. If not found → warn in event log, skip this file
|
||||
3. For characters/ → glob characters/*.yaml in project root
|
||||
4. For CLAUDE.md → check project root
|
||||
```
|
||||
|
||||
If a referenced file cannot be found at any location, emit a warning event but do not abort:
|
||||
|
||||
```bash
|
||||
./lib/archeflow-event.sh "$RUN_ID" decision init "" \
|
||||
'{"what":"colette_bridge_warning","chosen":"skip","file":"vp-giesing-gschichten-v1","reason":"not found in any search path"}'
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Context Bundle
|
||||
|
||||
The bridge generates `.archeflow/context/colette-bundle.md` — a summarized, token-efficient Markdown file that agents receive as part of their prompt context.
|
||||
|
||||
### Bundle Structure
|
||||
|
||||
```markdown
|
||||
# Writing Context (auto-loaded from Colette)
|
||||
|
||||
## Voice Profile: <id>
|
||||
**Tone:** <tone_summary from meta>
|
||||
**Perspective:** <perspektive>
|
||||
**Density:** <dichte>
|
||||
**Attitude:** <haltung>
|
||||
**Sharpness:** <schaerfe>
|
||||
**Humor:** <humor>
|
||||
**Tempo:** <tempo>
|
||||
**Reader relationship:** <leser_beziehung>
|
||||
|
||||
### Forbidden
|
||||
- <each item from verboten>
|
||||
|
||||
### Allowed
|
||||
- <each item from erlaubt>
|
||||
|
||||
### Style models
|
||||
- <each item from vorbilder, name only + one-word tag>
|
||||
|
||||
## Persona: <id>
|
||||
**Name:** <name>
|
||||
**Bio:** <bio, max 2 sentences>
|
||||
**Genres:** <genres, comma-separated>
|
||||
|
||||
### Rules
|
||||
- <each item from rules>
|
||||
|
||||
## Characters
|
||||
### <name> (<role>)
|
||||
- **Age:** <age>
|
||||
- **Key traits:** <first 3 personality items>
|
||||
- **Speech:** <speech_pattern, first sentence only>
|
||||
- **Relationships:** <key relationships, one line each>
|
||||
|
||||
[Repeated for each character in characters/*.yaml]
|
||||
|
||||
## Series Context
|
||||
[Only if series config found in colette.yaml]
|
||||
- **Shared concepts:** <list>
|
||||
- **Glossary:** <key terms>
|
||||
- **Forbidden cross-story:** <items>
|
||||
|
||||
## Project Rules (from CLAUDE.md)
|
||||
[Key writing rules extracted from CLAUDE.md, summarized as bullet points]
|
||||
- <rule 1>
|
||||
- <rule 2>
|
||||
- ...
|
||||
```
|
||||
|
||||
### Summarization Rules
|
||||
|
||||
The bundle is **summarized**, not a raw YAML dump. This reduces token cost:
|
||||
|
||||
- Voice profile dimensions: key name + value (no YAML formatting, no `dimensionen:` wrapper)
|
||||
- Verboten/erlaubt: bullet list, strip explanation after the dash if over 15 words
|
||||
- Characters: name, role, age, top 3 traits, first sentence of speech pattern, relationships
|
||||
- Persona bio: max 2 sentences
|
||||
- CLAUDE.md: extract only rules/style sections, skip meta/git/cost config
|
||||
- Target: bundle should be under 1500 tokens for a typical project
|
||||
|
||||
---
|
||||
|
||||
## Caching
|
||||
|
||||
The bundle is regenerated only when source files have changed. Cache validation uses file modification times.
|
||||
|
||||
### Cache Check Procedure
|
||||
|
||||
```
|
||||
bundle_path = .archeflow/context/colette-bundle.md
|
||||
|
||||
if bundle_path does not exist → generate
|
||||
if bundle_path exists:
|
||||
bundle_mtime = mtime of bundle_path
|
||||
for each resolved source file:
|
||||
if source_mtime > bundle_mtime → regenerate, break
|
||||
if no source file is newer → use cached bundle
|
||||
```
|
||||
|
||||
When the cache is valid, emit:
|
||||
|
||||
```bash
|
||||
./lib/archeflow-event.sh "$RUN_ID" decision init "" \
|
||||
'{"what":"colette_bundle_cache","chosen":"reuse","reason":"all sources older than bundle"}'
|
||||
```
|
||||
|
||||
When regenerating:
|
||||
|
||||
```bash
|
||||
./lib/archeflow-event.sh "$RUN_ID" decision init "" \
|
||||
'{"what":"colette_bundle_cache","chosen":"regenerate","reason":"<file> modified since last bundle"}'
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Per-Agent Attention Filters
|
||||
|
||||
Not every agent needs the full bundle. The bridge defines attention filters that control which sections each archetype receives. This extends the base attention filters from `archeflow:attention-filters`.
|
||||
|
||||
| Archetype | Bundle sections injected | Rationale |
|
||||
|-----------|------------------------|-----------|
|
||||
| **Explorer** | Full bundle | Needs all context for research — setting, characters, voice, rules |
|
||||
| **Creator** | Voice dimensions + persona rules + characters | Designs outline — needs to know who speaks how, who exists, what's allowed |
|
||||
| **Maker** | Full bundle | Writes prose — needs voice for style, characters for dialogue, rules for guardrails |
|
||||
| **Guardian** | Characters + series shared_concepts | Checks consistency — needs character facts and cross-story constraints |
|
||||
| **Sage** | Voice profile (full, including verboten/erlaubt) + persona rules | Checks voice drift — needs the complete voice spec and persona constraints |
|
||||
| **Trickster** | Characters + series glossary | Tests continuity — needs character facts and terminology for contradiction checks |
|
||||
|
||||
### Filter Implementation
|
||||
|
||||
When injecting the bundle into an agent prompt, extract only the relevant sections:
|
||||
|
||||
```
|
||||
# For Guardian:
|
||||
Extract: "## Characters" section (all characters)
|
||||
Extract: "## Series Context" section (if present)
|
||||
Skip: everything else
|
||||
|
||||
# For Sage:
|
||||
Extract: "## Voice Profile" section (full, with forbidden/allowed)
|
||||
Extract: "## Persona" section (rules subsection)
|
||||
Skip: characters, series, project rules
|
||||
|
||||
# For Explorer and Maker:
|
||||
Inject: full bundle as-is
|
||||
```
|
||||
|
||||
The filtering happens at prompt assembly time, not at bundle generation time. One bundle, multiple filtered views.
|
||||
|
||||
### Custom Archetypes
|
||||
|
||||
Custom archetypes (e.g., `story-explorer`, `story-sage`) inherit the filter of their closest base archetype:
|
||||
|
||||
| Custom archetype | Inherits filter from | Override |
|
||||
|-----------------|---------------------|----------|
|
||||
| `story-explorer` | Explorer | Full bundle |
|
||||
| `story-sage` | Sage | Full voice profile + persona rules |
|
||||
| `story-guardian` | Guardian | Characters + series |
|
||||
|
||||
If a custom archetype needs a different filter, define it in the archetype's markdown frontmatter:
|
||||
|
||||
```yaml
|
||||
---
|
||||
name: story-sage
|
||||
colette_filter: [voice_profile, persona, characters]
|
||||
---
|
||||
```
|
||||
|
||||
The `colette_filter` field accepts section keys: `voice_profile`, `persona`, `characters`, `series`, `project_rules`, `full`.
|
||||
|
||||
---
|
||||
|
||||
## Integration with Run Skill
|
||||
|
||||
The Colette Bridge hooks into `archeflow:run` initialization. The sequence is:
|
||||
|
||||
```
|
||||
run.start
|
||||
├── Domain detection (from archeflow:domains)
|
||||
│ └── colette.yaml found → domain = writing
|
||||
├── Colette Bridge activation
|
||||
│ ├── Resolve files (voice profile, persona, characters, CLAUDE.md)
|
||||
│ ├── Check bundle cache
|
||||
│ ├── Generate/refresh bundle → .archeflow/context/colette-bundle.md
|
||||
│ └── Register bundle path in artifact routing
|
||||
└── Continue to Plan phase
|
||||
```
|
||||
|
||||
### Artifact Routing Registration
|
||||
|
||||
The bundle path is registered so that every phase's context injection includes the (filtered) bundle:
|
||||
|
||||
```
|
||||
artifact_routing.register_context(
|
||||
path = ".archeflow/context/colette-bundle.md",
|
||||
inject_at = "all_phases",
|
||||
filter_by = "archetype" # Apply per-agent attention filters
|
||||
)
|
||||
```
|
||||
|
||||
In practice, this means the run skill prepends the filtered bundle content to each agent's prompt, after the standard task description but before phase-specific artifacts.
|
||||
|
||||
### Prompt Injection Order
|
||||
|
||||
```
|
||||
1. Archetype definition (from SKILL.md or custom archetype .md)
|
||||
2. Domain-specific review focus (from archeflow:domains)
|
||||
3. Colette bundle (filtered for this archetype)
|
||||
4. Task description
|
||||
5. Phase-specific artifacts (Explorer output, Creator proposal, etc.)
|
||||
6. Cycle feedback (if cycle 2+)
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Example: Giesing Gschichten
|
||||
|
||||
Given this `colette.yaml`:
|
||||
|
||||
```yaml
|
||||
project:
|
||||
name: "Giesing Gschichten"
|
||||
author: "C. Nennemann"
|
||||
language: de
|
||||
type: fiction
|
||||
|
||||
voice:
|
||||
profile: vp-giesing-gschichten-v1
|
||||
|
||||
writing:
|
||||
target_words: 6000
|
||||
style: "Ich-Erzaehler, lakonisch, Eberhofer-meets-Grossstadt"
|
||||
```
|
||||
|
||||
The bridge:
|
||||
|
||||
1. Reads `voice.profile: vp-giesing-gschichten-v1`
|
||||
2. Searches for `./profiles/vp-giesing-gschichten-v1.yaml` — not found
|
||||
3. Searches for `../writing.colette/profiles/vp-giesing-gschichten-v1.yaml` — found
|
||||
4. Infers persona from voice profile ID pattern or searches `personas/` — finds `giesinger.yaml` at `../writing.colette/personas/giesinger.yaml`
|
||||
5. Globs `characters/*.yaml` — finds `alex.yaml` (and others if present)
|
||||
6. Reads `CLAUDE.md` for writing rules
|
||||
7. Generates bundle:
|
||||
|
||||
```markdown
|
||||
# Writing Context (auto-loaded from Colette)
|
||||
|
||||
## Voice Profile: vp-giesing-gschichten-v1
|
||||
**Tone:** Lakonisch, warmherzig-genervt, trockener Humor
|
||||
**Perspective:** Ich-Erzaehler (Alex), nah dran, subjektiv
|
||||
**Density:** Alltagsdetails die Atmosphaere schaffen
|
||||
**Attitude:** Lakonisch, leicht genervt, aber mit Herz
|
||||
**Sharpness:** Beobachtungsscharf, sprachlich reduziert
|
||||
**Humor:** Trocken, Understatement, absurde Situationen
|
||||
**Tempo:** Gemaechlich mit Spannungsspitzen, Slow Burn
|
||||
**Reader relationship:** Kumpel am Stammtisch
|
||||
|
||||
### Forbidden
|
||||
- Hochdeutsch-Sterilitaet
|
||||
- Krimi-Klischees (CSI, Profiler, Tatort)
|
||||
- Lederhosen-Kitsch und Oktoberfest-Folklore
|
||||
- Dialekt-Overkill
|
||||
- Moralisieren oder Erklaeren
|
||||
- Kuenstliche Spannungsaufbauten
|
||||
- Adverb-Orgien und Adjektiv-Ketten
|
||||
- Infodumps
|
||||
|
||||
### Allowed
|
||||
- Bairische Einsprengsel in Hochdeutsch-Prosa
|
||||
- Essen und Trinken als Leitmotiv
|
||||
- Kiffer-Humor und Slow-Motion-Beobachtungen
|
||||
- Gentrification-Satire
|
||||
- Echte Giesinger Orte und Strassen
|
||||
- Skurrile Nachbarn
|
||||
- Kriminalplot aus dem Alltag
|
||||
- Kurze, lakonische Dialoge
|
||||
|
||||
### Style models
|
||||
- Rita Falk (Erzaehlton), Wolf Haas (lakonisch), Helmut Dietl (Muenchner Milieu), Friedrich Ani (duester), Bukowski (Anti-Held)
|
||||
|
||||
## Persona: giesinger
|
||||
**Name:** Der Giesinger
|
||||
**Bio:** Erzaehlt Geschichten aus Muenchen-Giesing. Eberhofer meets Grossstadt.
|
||||
**Genres:** Krimi, Kurzgeschichte, Milieustudie
|
||||
|
||||
### Rules
|
||||
- Ich-Erzaehler, immer — Alex erzaehlt
|
||||
- Hauptsaechlich Hochdeutsch mit bairischen Einsprengsel
|
||||
- Jede Geschichte hat einen Kriminalplot
|
||||
- Essen/Trinken in jeder Geschichte
|
||||
- Echte Giesinger Orte und Strassen
|
||||
- Humor durch Understatement
|
||||
- Alex ist kein Ermittler
|
||||
- Figuren reden wie echte Menschen
|
||||
|
||||
## Characters
|
||||
### Alex (protagonist)
|
||||
- **Age:** Mitte 30
|
||||
- **Key traits:** Lakonisch, funktionaler Kiffer, unmotiviert aber nicht dumm
|
||||
- **Speech:** Kurze Saetze, Hochdeutsch mit bairischen Einsprengsel.
|
||||
- **Relationships:** Mo — Nachbar, Kumpel und Unruhestifter
|
||||
|
||||
## Project Rules (from CLAUDE.md)
|
||||
- Jede Geschichte beginnt mit einer Alltagsszene
|
||||
- Kriminalplot ergibt sich organisch aus dem Alltag
|
||||
- Essen/Trinken in jeder Geschichte
|
||||
- Echte Giesinger Orte verwenden
|
||||
- Kein Moralisieren, kein Erklaerbaer
|
||||
- Ende muss nicht alles aufloesen
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Design Principles
|
||||
|
||||
1. **Summarize, don't dump.** Raw YAML wastes tokens and confuses agents. The bundle is a curated briefing.
|
||||
2. **Cache aggressively.** Voice profiles and characters rarely change mid-run. Only regenerate when mtimes change.
|
||||
3. **Filter per agent.** A Guardian checking plot consistency does not need the full voice profile. A Sage checking voice drift does not need character sheets.
|
||||
4. **Graceful degradation.** Missing files are warned about, not fatal. A project with `colette.yaml` but no characters/ still works — the Characters section is simply empty.
|
||||
5. **One bundle, filtered views.** Generate the full bundle once. Filter at injection time per archetype. This keeps caching simple.
|
||||
6. **Additive to existing skills.** The bridge does not replace domain detection or artifact routing — it hooks into them. Remove the bridge, everything still works (just without auto-loaded writing context).
|
||||
Reference in New Issue
Block a user