skills/docs/APPROACH-COMPARISON-gemini.md
dan 5fea49b7c0 feat(tufte-press): evolve skill to complete workflow with JSON generation and build automation
- 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
2025-11-10 15:03:44 -08:00

339 lines
9.5 KiB
Markdown
Raw Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# Approach Comparison: Our Plan vs Gemini's Analysis
**Context**: Both teams independently analyzed the skills deployment strategy
**Result**: Strong agreement on core approach (flake inputs)
**Differences**: Minor implementation details
## Core Agreement ✅
Both teams recommend **Flake Inputs** as primary pattern:
| Principle | Our Analysis | Gemini's Analysis | Status |
|-----------|--------------|-------------------|--------|
| Single source of truth | ✅ Skills repo is canonical | ✅ Both ops-dev and dotfiles reference skills | **Aligned** |
| Declarative updates | ✅ `nix flake lock --update-input skills` | ✅ Not manual copying | **Aligned** |
| Reproducible builds | ✅ flake.lock pins commits | ✅ flake.lock for identical builds | **Aligned** |
| Selective inclusion | ✅ Choose skills via config | ✅ Choose only needed skills | **Aligned** |
| Version control | ✅ Clear dependency graph | ✅ Clear dependency graph in Nix | **Aligned** |
## Implementation Differences
### 1. Flake Input URL
**Gemini's Recommendation**:
```nix
skills.url = "path:../skills"; # For local dev
```
**Our Initial Recommendation**:
```nix
skills.url = "git+http://192.168.1.108:3000/dan/skills.git";
```
**Analysis**:
- **Gemini's `path:` approach**:
- ✅ Offline-friendly (no network needed)
- ✅ Fast for local development
- ✅ Direct filesystem access
- ⚠️ Requires skills repo to be checked out locally
- ⚠️ Path must exist where flake is evaluated
- **Our `git+http:` approach**:
- ✅ Works for remote deployments
- ✅ Explicit version in flake.lock (commit hash)
- ✅ Can be used from anywhere with network
- ⚠️ Requires network on first fetch
- Cached in /nix/store, then works offline
**Verdict**: **Both are correct** - use based on context
**Recommended Strategy**:
```nix
# For local development machine (where skills repo is checked out)
skills.url = "path:/home/dan/proj/skills";
# For remote VMs (deployed via git)
skills.url = "git+http://192.168.1.108:3000/dan/skills.git";
# Can override at build time:
# nix build --override-input skills path:../skills
```
**Update our docs**: Support both, document when to use each ✅ (Done)
### 2. Deployment Method
**Gemini's Approach**:
```nix
let
devSkills = with skills.packages.${pkgs.system}; [
worklog
tufte-press
];
skillsDir = pkgs.symlinkJoin {
name = "dev-vm-skills";
paths = devSkills;
};
in {
environment.etc."opencode/skills".source = skillsDir;
environment.etc."claude/skills".source = skillsDir;
}
```
**Our Approach**:
```nix
imports = [ inputs.skills.nixosModules.ai-skills ];
services.ai-skills = {
enable = true;
selectedSkills = [ "worklog" "tufte-press" ];
deployTargets = [ "claude" "opencode" ];
};
```
**Comparison**:
| Aspect | Gemini (Direct) | Us (Module) |
|--------|-----------------|-------------|
| Lines of code | ~15 lines inline | ~6 lines config |
| Abstraction | Explicit, visible | Hidden in module |
| Reusability | Copy-paste to each project | Import once, use everywhere |
| User home symlinks | Must add manually | Handled automatically |
| Permissions | Must handle manually | Module handles it |
| opencode-skills plugin | Not included | Module installs it |
| Flexibility | Full control | Options-based control |
| Learning curve | Shows how it works | Must understand module |
**Analysis**:
- **Gemini's approach is excellent for**:
- Learning how Nix works
- Simple, one-off deployments
- Full visibility into mechanism
- No "magic" abstractions
- **Our module is excellent for**:
- Consistent pattern across multiple systems
- Reducing boilerplate
- Additional features (plugin installation)
- Maintenance (fix once, affects all users)
**Verdict**: **Both are valid**
**Recommendation**:
- **Use Gemini's direct approach** when:
- Learning Nix
- One-off setup
- Want full control
- Don't need our module's extra features
- **Use our ai-skills module** when:
- Multiple systems to manage
- Want consistency
- Need opencode-skills plugin
- Prefer declarative options
- **Hybrid** (recommended):
```nix
# Use Gemini's path: suggestion + our module
inputs.skills.url = "path:/home/dan/proj/skills";
imports = [ inputs.skills.nixosModules.ai-skills ];
services.ai-skills.enable = true;
```
### 3. Skill Selection Pattern
**Gemini**:
```nix
devSkills = with skills.packages.${pkgs.system}; [
worklog
tufte-press
];
```
**Us** (via module):
```nix
services.ai-skills.selectedSkills = [ "worklog" "tufte-press" ];
```
**Behind the scenes our module does**:
```nix
# modules/ai-skills.nix (simplified)
let
selectedPackages = map (name: skills.packages.${pkgs.system}.${name})
cfg.selectedSkills;
skillsDir = pkgs.symlinkJoin {
name = "ai-skills";
paths = selectedPackages;
};
in {
environment.etc."opencode/skills".source = skillsDir;
# ... etc
}
```
**Analysis**: Same underlying mechanism, different interface
**Verdict**: **Equivalent implementations**
### 4. Network Dependency Handling
**Gemini's Explanation**:
> "Self-contained" = "reproducible without live network," not "never had network"
> - Once fetched to /nix/store, rebuilds work offline
> - Use `nix flake prefetch` after updates to cache dependencies
**Our Understanding**: Identical
**Gemini's Additional Tip**:
```bash
nix flake prefetch
```
**Analysis**: This is excellent advice we should add to our docs
**Action**: Update migration guide with prefetch tip ✅
## What Gemini's Analysis Adds
### 1. Clear Network Dependency Explanation
Gemini explicitly addresses the "does it need network?" concern:
- First fetch requires network
- Subsequent builds work offline (from /nix/store)
- Standard Nix behavior, not a problem
- Use `prefetch` for predictable caching
**Action**: Add this clarification to our docs ✅
### 2. Practical Implementation Plan
Gemini provides concrete steps:
1. Add skills as flake input: `skills.url = "path:../skills"`
2. Select needed skills: `devSkills = [ worklog tufte-press ]`
3. Build combined skills dir: `skillsDir = pkgs.symlinkJoin`
4. Update environment.etc to use skillsDir
5. Delete copied ./skills directory from git
**Analysis**: This is essentially our migration guide, slightly different order
**Verdict**: Both plans are equivalent ✅
### 3. Encouragement to Use Same Pattern for Dotfiles
Gemini notes:
> Apply the same approach to ~/proj/dotfiles for consistency.
**Analysis**: Excellent point - we should document this pattern as general-purpose
**Action**: Note in docs that this pattern works for any Nix flake ✅
## Combined Recommendation
### Use This Approach (Best of Both)
**1. Flake Input** (Gemini's path suggestion):
```nix
inputs.skills = {
url = "path:/home/dan/proj/skills"; # Local dev, offline-friendly
inputs.nixpkgs.follows = "nixpkgs";
};
```
**2. Deployment** (Our module for convenience):
```nix
imports = [ inputs.skills.nixosModules.ai-skills ];
services.ai-skills = {
enable = true;
selectedSkills = [ "worklog" "tufte-press" ];
deployTargets = [ "claude" "opencode" ];
};
```
**3. Alternative** (Gemini's direct approach if module not needed):
```nix
let
skillsDir = pkgs.symlinkJoin {
name = "ops-dev-skills";
paths = with inputs.skills.packages.${pkgs.system}; [
worklog tufte-press
];
};
in {
environment.etc."opencode/skills".source = skillsDir;
environment.etc."claude/skills".source = skillsDir;
}
```
**4. Caching** (Gemini's tip):
```bash
nix flake prefetch # Pre-cache dependencies for offline work
```
## What to Document
### Updates to Our Documentation
1. **Migration guide** ✅ (Done)
- Add `path:` vs `git+http:` comparison
- Explain when to use each
- Add `nix flake prefetch` tip
2. **Best practices** ✅ (Done)
- Note that both URL types are valid
- Explain network dependency behavior
- Document `prefetch` for offline work
3. **Comparison doc** ✅ (This file)
- Show Gemini's approach
- Show our approach
- Explain trade-offs
- Recommend hybrid
4. **Module documentation**
- Document ai-skills module options
- Show equivalent manual approach
- Explain what module does behind the scenes
## Agreement Summary
### Strong Agreement ✅
1. **Use flake inputs** - Single source of truth pattern
2. **Declarative configuration** - No manual copying
3. **Version control** - flake.lock for reproducibility
4. **Selective inclusion** - Choose needed skills
5. **Network is OK** - Standard Nix behavior, caches to /nix/store
### Minor Differences (Both Valid)
1. **URL type**: `path:` vs `git+http:` - Use based on context
2. **Deployment**: Module vs direct - Use based on needs
3. **Abstraction level**: High (module) vs low (explicit) - Both work
### Key Insights from Gemini
1. **`path:` for local dev** - Simpler, offline-friendly
2. **Network dependency is fine** - Standard Nix, not a problem
3. **`nix flake prefetch`** - Proactive caching tip
4. **Apply pattern everywhere** - Dotfiles, other repos too
## Conclusion
**We are in strong agreement**
Both analyses arrived at the same core solution (flake inputs) independently, which validates the approach. Gemini's analysis adds:
- Preference for `path:` URLs (good suggestion)
- Explicit network dependency handling (helpful clarification)
- Direct implementation approach (valid alternative to our module)
**Recommendation**:
- Accept Gemini's implementation plan
- Use `path:` for local development
- Keep our ai-skills module as an optional convenience layer
- Document both approaches
- Proceed with migration
**Action**: Implement for ops-dev using hybrid approach (Gemini's `path:` + our module)