- Transform tufte-press from reference guide to conversation-aware generator - Add JSON generation from conversation context following strict schema - Create build automation scripts with Nix environment handling - Integrate CUPS printing with duplex support - Add comprehensive workflow documentation Scripts added: - skills/tufte-press/scripts/generate-and-build.sh (242 lines) - skills/tufte-press/scripts/build-card.sh (23 lines) Documentation: - Updated SKILL.md with complete workflow instructions (370 lines) - Updated README.md with usage examples (340 lines) - Created SKILL-DEVELOPMENT-STRATEGY-tufte-press.md (450 lines) - Added worklog: 2025-11-10-tufte-press-skill-evolution.org Features: - Agent generates valid JSON from conversation - Schema validation before build (catches errors early) - Automatic Nix shell entry for dependencies - PDF build via tufte-press toolchain - Optional print with duplex support - Self-contained margin notes enforced - Complete end-to-end testing Workflow: Conversation → JSON → Validate → Build → Print Related: niri-window-capture, screenshot-latest, worklog skills
379 lines
12 KiB
Markdown
379 lines
12 KiB
Markdown
# Cross-Repo Skill Collaboration Strategy
|
|
|
|
**Context**: Skills may be developed in one repo but deployed/modified in others
|
|
**Example**: tufte-press skill - developed in `dan/skills`, deployed to `dan/ops-dev`
|
|
**Decision**: Use skills repo as single source of truth, consume via Nix flake inputs
|
|
**Philosophy**: Modern Nix with flakes, declarative deployment, version control
|
|
|
|
## Current Situation: tufte-press
|
|
|
|
### Lifecycle So Far
|
|
|
|
1. **2025-11-09 (skills repo)**: We built tufte-press skill
|
|
- Location: `~/proj/skills/skills/tufte-press/`
|
|
- Complete SKILL.md, README.md, example JSON
|
|
- Committed to skills repository
|
|
|
|
2. **2025-11-09 (ops-dev deployment)**: They deployed to VM
|
|
- Copied from `~/proj/skills/skills/tufte-press/` to `~/proj/ops-dev/skills/tufte-press/`
|
|
- Deployed via NixOS environment.etc (flake bundling)
|
|
- Now lives at `/etc/opencode/skills/tufte-press/` on ops-dev VM
|
|
|
|
3. **Current state**: Files are identical (verified by diff)
|
|
- `SKILL.md` - identical
|
|
- `README.md` - identical
|
|
- `examples/lambda-calculus-example.json` - identical
|
|
|
|
### The Question
|
|
|
|
**What happens when changes are needed?**
|
|
- Who makes the change - us or them?
|
|
- Where is the change made - skills repo or ops-dev repo?
|
|
- How do changes sync between repos?
|
|
- Who owns which version?
|
|
|
|
## Primary Pattern: Skills Repo as Single Source of Truth
|
|
|
|
**Decision**: This repository (`dan/skills`) is the canonical source for all skills. Other projects consume via Nix flake inputs.
|
|
|
|
**Rationale**:
|
|
- Modern Nix with flakes is declarative and version-controlled
|
|
- Clear ownership and maintenance responsibility
|
|
- Automatic propagation of updates to all consumers
|
|
- Consistent deployment across all environments
|
|
- Leverages Nix's reproducibility guarantees
|
|
|
|
## Collaboration Models
|
|
|
|
### Model 1: Single Source of Truth via Flake Input (PRIMARY PATTERN ✅)
|
|
|
|
**Approach**: Skills repo is canonical, others consume via Nix flake input
|
|
|
|
**Architecture**:
|
|
```
|
|
~/proj/skills/ (git@forgejo:dan/skills.git)
|
|
↓ [Nix flake input]
|
|
~/proj/ops-dev/flake.nix
|
|
inputs.skills.url = "git+http://192.168.1.108:3000/dan/skills.git"
|
|
↓ [module import]
|
|
NixOS configuration uses skills.lib.getSkillPath
|
|
↓ [deployment]
|
|
/etc/opencode/skills/tufte-press → /nix/store/.../skills/tufte-press
|
|
```
|
|
|
|
**Workflow**:
|
|
1. **Changes happen in**: skills repo only
|
|
2. **Deployment**: `nix flake lock --update-input skills` in ops-dev, then rebuild
|
|
3. **Benefits**:
|
|
- Single source of truth
|
|
- Automatic propagation to all consumers
|
|
- Clear ownership (skills repo maintainers)
|
|
- Version pinning via flake.lock
|
|
4. **Trade-offs**:
|
|
- Can't make quick local changes
|
|
- Requires git commit + push to update
|
|
- Dependency on skills repo availability
|
|
|
|
**Use for**: All skills (this is the default pattern)
|
|
|
|
### Model 2: Local Copy with Manual Sync (DEVELOPMENT ONLY)
|
|
|
|
**Approach**: Copy skill to destination repo, manually sync when needed
|
|
|
|
**Architecture**:
|
|
```
|
|
~/proj/skills/skills/tufte-press/ [original]
|
|
↓ [manual copy]
|
|
~/proj/ops-dev/skills/tufte-press/ [deployed copy]
|
|
↓ [flake bundling]
|
|
/etc/opencode/skills/tufte-press/ [runtime]
|
|
```
|
|
|
|
**Workflow**:
|
|
1. **Changes can happen in**: Either repo
|
|
2. **Sync process**:
|
|
```bash
|
|
# Push changes from ops-dev → skills repo
|
|
cp -r ~/proj/ops-dev/skills/tufte-press/ ~/proj/skills/skills/
|
|
cd ~/proj/skills && git add skills/tufte-press/ && git commit -m "Update from ops-dev"
|
|
|
|
# Pull changes from skills → ops-dev repo
|
|
cp -r ~/proj/skills/skills/tufte-press/ ~/proj/ops-dev/skills/
|
|
cd ~/proj/ops-dev && git add skills/ && git commit -m "Update tufte-press from skills repo"
|
|
```
|
|
3. **Benefits**:
|
|
- Fast local iteration
|
|
- No network dependency
|
|
- Can experiment freely
|
|
4. **Trade-offs**:
|
|
- Manual sync required
|
|
- Risk of divergence
|
|
- No clear source of truth
|
|
- Must remember to sync changes
|
|
|
|
**Use for**:
|
|
- Temporary during initial skill development (before committing to skills repo)
|
|
- Emergency hotfixes before proper deployment
|
|
- **NOT for production use**
|
|
|
|
### Model 3: Git Submodule (NOT RECOMMENDED)
|
|
|
|
**Approach**: ops-dev repo includes skills repo as submodule
|
|
|
|
**Architecture**:
|
|
```
|
|
~/proj/ops-dev/
|
|
skills/ → git submodule (points to dan/skills.git)
|
|
↓ [flake source]
|
|
/nix/store/.../skills/tufte-press/
|
|
```
|
|
|
|
**Workflow**:
|
|
1. **Changes happen in**: skills repo
|
|
2. **Update in ops-dev**: `git submodule update --remote`
|
|
3. **Benefits**:
|
|
- Version control of dependency
|
|
- Can pin to specific commit
|
|
- Clear separation of concerns
|
|
4. **Trade-offs**:
|
|
- Submodule complexity
|
|
- Still need git operations to update
|
|
- Can't make quick local edits
|
|
|
|
**Use for**: Legacy compatibility only - use Model 1 instead
|
|
|
|
**Why not recommended**: Adds submodule complexity without Nix benefits
|
|
|
|
### Model 4: Fork + Upstream (RARE CASES ONLY)
|
|
|
|
**Approach**: Fork skill to project repo, selectively merge upstream changes
|
|
|
|
**Architecture**:
|
|
```
|
|
~/proj/skills/skills/tufte-press/ [upstream]
|
|
↓ [initial copy]
|
|
~/proj/ops-dev/skills/tufte-press/ [fork with modifications]
|
|
```
|
|
|
|
**Workflow**:
|
|
1. **Initial copy**: Copy skill from skills repo
|
|
2. **Local changes**: Modify freely in ops-dev repo
|
|
3. **Upstream changes**: Manually review and cherry-pick from skills repo
|
|
4. **Benefits**:
|
|
- Full local control
|
|
- Can diverge intentionally
|
|
- Can still pull upstream improvements
|
|
5. **Trade-offs**:
|
|
- Merge conflicts possible
|
|
- Tracking upstream changes is manual
|
|
- Unclear which changes should go back to upstream
|
|
|
|
**Use for**:
|
|
- Skills requiring heavy project-specific customization
|
|
- Non-NixOS environments (copy the skill files manually)
|
|
- When you need to diverge significantly from upstream
|
|
|
|
**Better approach**: Request features in skills repo, use configuration options
|
|
|
|
## Recommended Approach by Skill Type
|
|
|
|
### All Skills (Default Pattern)
|
|
|
|
**Use Model 1**: Nix flake input from skills repo
|
|
- **Why**: Single source of truth, version controlled, declarative
|
|
- **Deployment**: All projects pull from skills repo via flake input
|
|
- **Changes**:
|
|
1. Make changes in skills repo
|
|
2. Commit and push to git
|
|
3. Update flake.lock in consumer projects
|
|
4. Rebuild systems
|
|
- **Example**:
|
|
```nix
|
|
# ops-dev/flake.nix
|
|
inputs.skills.url = "git+http://192.168.1.108:3000/dan/skills.git";
|
|
|
|
# Import and use the module
|
|
imports = [ inputs.skills.nixosModules.ai-skills ];
|
|
|
|
services.ai-skills = {
|
|
enable = true;
|
|
selectedSkills = [ "tufte-press" "worklog" "screenshot-latest" ];
|
|
deployTargets = [ "claude" "opencode" ];
|
|
};
|
|
```
|
|
|
|
### During Development (Before Skill is Ready)
|
|
|
|
**Use Model 2 temporarily**: Local copy for rapid iteration
|
|
- **Why**: Fast feedback loop while building/testing
|
|
- **Process**:
|
|
1. Create skill in skills repo on a branch or WIP commit
|
|
2. Copy to consumer project for testing
|
|
3. Iterate rapidly with local changes
|
|
4. When stable, commit to skills repo
|
|
5. Switch consumer to flake input (Model 1)
|
|
- **Duration**: Hours to days, not weeks
|
|
- **Transition**: Always move to Model 1 once stable
|
|
|
|
## Implementation Plan: Migrate Existing Skills to Flake Input
|
|
|
|
### Tufte-Press Migration (ops-dev)
|
|
|
|
**Current State**:
|
|
- ✅ Skill exists in skills repo at `skills/tufte-press/`
|
|
- ✅ Added to flake packages
|
|
- ✅ Deployed to ops-dev VM via local copy (Model 2)
|
|
- ✅ Files are identical between repos
|
|
|
|
**Target State**: Consume via flake input (Model 1)
|
|
|
|
**Rationale**:
|
|
1. Skill is stable and documented
|
|
2. Clear shared value (Tufte-inspired study cards)
|
|
3. No urgent need for project-specific changes
|
|
4. Better pattern for future skills
|
|
|
|
**Migration Steps**:
|
|
|
|
1. **Skills repo** (already done):
|
|
- ✅ Skill exists at `skills/tufte-press/`
|
|
- ✅ Added to flake packages
|
|
- ✅ Available via `skillsFlake.packages.${system}.tufte-press`
|
|
|
|
2. **ops-dev repo** (to do):
|
|
```nix
|
|
# flake.nix - add input
|
|
inputs.skills = {
|
|
url = "git+http://192.168.1.108:3000/dan/skills.git";
|
|
inputs.nixpkgs.follows = "nixpkgs";
|
|
};
|
|
|
|
# Use the module
|
|
imports = [ inputs.skills.nixosModules.ai-skills ];
|
|
|
|
services.ai-skills = {
|
|
enable = true;
|
|
selectedSkills = [ "tufte-press" "worklog" ];
|
|
deployTargets = [ "claude" "opencode" ];
|
|
};
|
|
```
|
|
|
|
3. **Remove local copy**:
|
|
```bash
|
|
cd ~/proj/ops-dev
|
|
rm -rf skills/tufte-press # Now comes from flake input
|
|
git add -A && git commit -m "Switch tufte-press to skills repo flake input"
|
|
```
|
|
|
|
4. **Deploy**:
|
|
```bash
|
|
ssh root@192.168.1.73 "cd /home/dev/ops-dev && nixos-rebuild switch --flake .#dev"
|
|
```
|
|
|
|
**Future Updates**:
|
|
```bash
|
|
# Update to latest skills
|
|
cd ~/proj/ops-dev
|
|
nix flake lock --update-input skills
|
|
ssh root@192.168.1.73 "cd /home/dev/ops-dev && nixos-rebuild switch --flake .#dev"
|
|
```
|
|
|
|
## Worklog-Compression Skill Strategy
|
|
|
|
**Context**: prox-setup repo has mature worklog compression workflow
|
|
|
|
### Development Approach
|
|
|
|
**Phase 1** (Development - use Model 2 temporarily):
|
|
- Build skill in skills repo (commit to main or feature branch)
|
|
- Copy to ops-dev for testing if needed
|
|
- Fast iteration with local changes
|
|
- Duration: Hours to 1-2 days
|
|
|
|
**Phase 2** (Deployment - switch to Model 1):
|
|
- Skill is working and tested
|
|
- Add to skills repo flake packages (if not already)
|
|
- ops-dev switches to flake input
|
|
- Remove local copy
|
|
|
|
**Phase 3** (Maintenance - stay on Model 1):
|
|
- All changes happen in skills repo
|
|
- Consumers update via `nix flake lock --update-input skills`
|
|
- Version controlled and declarative
|
|
|
|
**No forking or local copies in production** - this keeps the architecture clean
|
|
|
|
## Sync Coordination Practices
|
|
|
|
### Before Making Changes
|
|
|
|
**Check with stakeholders**:
|
|
- "Planning to update tufte-press skill - anyone else working on it?"
|
|
- Prevents conflicting changes
|
|
|
|
### After Making Changes
|
|
|
|
**Notify consumers**:
|
|
- Comment in shared chat: "Updated tufte-press skill - added X feature"
|
|
- Update CHANGELOG in skill directory
|
|
- Tag releases for significant changes
|
|
|
|
### For Breaking Changes
|
|
|
|
**Version carefully**:
|
|
- Consider creating `tufte-press-v2` skill
|
|
- Deprecate old version gracefully
|
|
- Document migration path
|
|
|
|
### For Experimental Changes
|
|
|
|
**Use branches**:
|
|
- `tufte-press-experimental-latex-engine` skill name
|
|
- Or git branches in skills repo
|
|
- Don't break the main version
|
|
|
|
## Summary
|
|
|
|
### Quick Decision Tree
|
|
|
|
```
|
|
Is the skill ready for use?
|
|
├─ Yes → Model 1 (Nix flake input) ✅ DEFAULT
|
|
│ - All stable skills
|
|
│ - tufte-press
|
|
│ - worklog
|
|
│ - screenshot-latest
|
|
│ - niri-window-capture
|
|
│ - Everything in production
|
|
│
|
|
└─ No, still developing → Model 2 (Temporary local copy)
|
|
- Use for 1-2 days max
|
|
- Switch to Model 1 when stable
|
|
- Don't leave in this state
|
|
```
|
|
|
|
### Key Principles
|
|
|
|
1. **Default to Model 1** - Flake input is the standard pattern
|
|
2. **Skills repo is source of truth** - All changes happen here
|
|
3. **Model 2 is temporary only** - Use during development, not production
|
|
4. **No forking or local modifications** - Request features instead
|
|
5. **Modern Nix with flakes** - Declarative, version-controlled, reproducible
|
|
6. **Always communicate** before/after significant changes
|
|
7. **Version breaking changes** carefully (consider skill-v2 naming)
|
|
|
|
## Next Actions
|
|
|
|
1. ✅ Document collaboration patterns (this file)
|
|
2. ⏳ Migrate tufte-press in ops-dev to flake input (when ready)
|
|
3. ⏳ Build worklog-compression skill (Model 2 initially)
|
|
4. ⏳ Test skills Nix module on ops-dev VM
|
|
5. ⏳ Document per-skill deployment decisions in each SKILL.md
|
|
|
|
---
|
|
|
|
**Related Documentation**:
|
|
- `AGENTS.md` - Skill development guidelines
|
|
- `NIX-FLAKE-USAGE.md` - How to consume skills via Nix
|
|
- `docs/SKILL-DEVELOPMENT-STRATEGY-prox-setup.md` - Hybrid development approach
|