Archived completed OpenSpec change after successful deployment. The template path fix has been applied to specs and is now in production. Change archived as: 2026-01-12-fix-coverletter-template-path Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
18 KiB
Design Document: Application Archiving
Overview
This document captures the technical design decisions and architectural considerations for implementing the application archiving feature.
Design Principles
1. Follow Existing Patterns
Principle: The archive command should follow established patterns from existing commands.
Rationale:
- Consistency in user experience
- Easier maintenance and understanding
- Leverages proven patterns from
write-cover-letter.mdandwrite-application-email.md
Application:
- Command file structure: Markdown with procedural instructions for Claude Code
- Argument parsing: Position-based with optional parameters and flags
- Error handling: Clear, actionable error messages with examples
- Validation: Check inputs before performing operations
2. Safety First
Principle: Protect user work by detecting and warning about generated documents.
Rationale:
- Users may invest significant time in cover letters and emails
- Accidental archiving of work-in-progress could be frustrating
- Better to err on the side of caution
Application:
- Detect:
cover-letter.md,application-email.md, files inattachments/ - Warn: Show detailed message listing all detected work
- Require: Explicit
--forceflag to bypass warnings - Preserve: All files during move (nothing is deleted)
3. Minimal Metadata Updates
Principle: Update only what's necessary, preserve everything else.
Rationale:
- Reduce risk of data corruption
- Simple updates are easier to verify and rollback
- Users may have customized other fields
Application:
- Only modify: Status field in Metadata section
- Format:
- **Status**: [State] (Archived: YYYY-MM-DD HH:MM) - Preserve: All other content in
application.md - Rollback: If move fails, don't update status
4. On-Demand Creation
Principle: Create archive folders only when needed.
Rationale:
- Avoid cluttering file system with empty folders
- Simpler initial setup (no migration needed)
- Users who don't use archiving don't see archive folders
Application:
- Check: Does
applications/rejected/exist? - Create: Only if first time archiving with "rejected"
- Same: For
applications/not-interested/ - Track: In git with
.gitkeepif desired
Technical Architecture
Command Flow
User Input: /archive-application [reason] [app-name] [--force]
↓
┌─────────────────────────┐
│ 1. Parse Arguments │
│ - Extract reason │
│ - Extract app name │
│ - Check for --force │
└──────────┬──────────────┘
↓
┌─────────────────────────┐
│ 2. Validate Inputs │
│ - Reason is valid? │
│ - App exists? │
└──────────┬──────────────┘
↓
┌─────────────────────────┐
│ 3. Detect Location │
│ - Current dir? │
│ - Or resolve path │
└──────────┬──────────────┘
↓
┌─────────────────────────┐
│ 4. Safety Checks │
│ - Cover letter? │
│ - Email? │
│ - Attachments? │
└──────────┬──────────────┘
↓
┌────────┴────────┐
│ Documents found? │
└────────┬────────┘
│
Yes ┌─────┴─────┐ No
↓ ↓
┌──────────────┐ ┌──────────────┐
│ --force set? │ │ 5. Update │
└──────┬───────┘ │ Status │
│ └──────┬───────┘
Yes ┌──┴──┐ No ↓
↓ ↓ ┌──────────────┐
│ STOP │ 6. Create │
│ (warn) │ Archive │
↓ │ Folder │
┌──────────────┐ └──────┬───────┘
│ 5. Update │ ↓
│ Status │ ┌──────────────┐
└──────┬───────┘ │ 7. Move │
↓ │ Folder │
┌──────────────┐ └──────┬───────┘
│ 6. Create │ ↓
│ Archive │ ┌──────────────┐
│ Folder │ │ 8. Verify │
└──────┬───────┘ │ Success │
↓ └──────┬───────┘
┌──────────────┐ ↓
│ 7. Move │ ┌──────────────┐
│ Folder │ │ 9. Confirm │
└──────┬───────┘ │ Message │
↓ └──────────────┘
┌──────────────┐
│ 8. Verify │
│ Success │
└──────┬───────┘
↓
┌──────────────┐
│ 9. Confirm │
│ Message │
└──────────────┘
Data Flow
Input: applications/pending/2025-11-02-TechCorp-Developer/
↓
┌─────────────────────────┐
│ Read application.md │
│ Current Status: Draft │
└──────────┬──────────────┘
↓
┌─────────────────────────┐
│ Update in Memory │
│ New Status: Rejected │
│ Timestamp: 2025-12-18 │
└──────────┬──────────────┘
↓
┌─────────────────────────┐
│ Write Back to File │
│ application.md updated │
└──────────┬──────────────┘
↓
┌─────────────────────────┐
│ Move Entire Folder │
│ Including updated file │
└──────────┬──────────────┘
↓
Output: applications/rejected/2025-11-02-TechCorp-Developer/
File System Operations
# 1. Status Update (before move)
cd applications/pending/[folder]/
cat application.md | sed 's/- \*\*Status\*\*:.*/- **Status**: Rejected (Archived: 2025-12-18 15:30)/' > application.md.tmp
mv application.md.tmp application.md
# 2. Create Archive Directory (if needed)
mkdir -p applications/rejected/
# 3. Move Application
mv applications/pending/[folder]/ applications/rejected/[folder]/
# 4. Verify
test -d applications/rejected/[folder]/ && echo "Success"
test ! -d applications/pending/[folder]/ && echo "Source removed"
Key Design Decisions
Decision 1: Status Update Timing
Options:
- A) Update status BEFORE moving folder
- B) Update status AFTER moving folder
- C) Update status IN PLACE after moving
Chosen: Option A - Update status BEFORE moving
Rationale:
- Easier to rollback if move fails (just revert file)
- Status update is atomic operation (less likely to fail)
- If update fails, we stop early (don't move)
- Move operation is riskier, so do simpler operation first
Trade-offs:
- If move fails, status is updated but folder isn't moved
- User sees "Rejected" status in pending folder
- Mitigation: Show clear error, user can fix status or retry move
Decision 2: Safety Check Scope
Options:
- A) Only check for generated documents (cover-letter.md, application-email.md)
- B) Check for any modifications to application.md
- C) Check for generated documents + attachments folder
- D) No safety checks, always allow archiving
Chosen: Option C - Generated documents + attachments
Rationale:
- Generated documents represent significant work
- Attachments likely contain CV and certificates
- Checking application.md changes is too broad (may be auto-populated)
- Some safety is better than none, but not overly restrictive
Trade-offs:
- Users can still accidentally archive applications with manual edits to application.md
- Acceptable: application.md is easier to recreate than generated documents
Decision 3: Archive Folder Naming
Options:
- A)
rejected/andnot-interested/ - B)
archived-rejected/andarchived-not-interested/ - C)
archive/rejected/andarchive/not-interested/ - D)
rejected/andwithdrawn/
Chosen: Option A - rejected/ and not-interested/
Rationale:
- Short, clear folder names
- "rejected" clearly indicates company rejected
- "not-interested" clearly indicates user withdrew
- No redundant "archived" prefix (location implies archived)
- Consistent with user's original request
Trade-offs:
- "not-interested" is verbose compared to "withdrawn"
- Acceptable: clarity over brevity
Decision 4: Auto-Detection Scope
Options:
- A) Only detect if in exact application folder
- B) Detect from application folder or subfolders
- C) Detect from anywhere in pending folder tree
- D) No auto-detection, always require application name
Chosen: Option B - Application folder or subfolders
Rationale:
- Users may be in
input/orattachments/when deciding to archive - Detecting parent folder is user-friendly
- Not too broad (don't detect from root or pending folder itself)
- Matches pattern from other commands
Trade-offs:
- Slightly more complex path resolution logic
- Acceptable: improves user experience
Decision 5: Error Handling Strategy
Options:
- A) Fail fast, stop on first error
- B) Try to proceed, show warnings
- C) Rollback on any error
- D) Partial success allowed (e.g., move but don't update status)
Chosen: Option A - Fail fast with Option C rollback on critical errors
Rationale:
- Validate all inputs BEFORE making changes
- Stop early if anything is wrong
- Rollback status update if move fails (critical path)
- Allow partial success only for non-critical operations (e.g., Timeline update)
Trade-offs:
- Less forgiving for edge cases
- Acceptable: better to stop and fix than proceed with errors
Component Responsibilities
Command File (archive-application.md)
Responsibilities:
- Parse and validate command arguments
- Detect application location
- Perform safety checks
- Update Status field
- Create archive directory
- Move application folder
- Verify success
- Show confirmation message
NOT Responsible For:
- Modifying other files besides application.md
- Validating application completeness (separate concern)
- Tracking archived applications (future enhancement)
- Providing archive search (future enhancement)
Framework Documentation (CLAUDE.md)
Responsibilities:
- Explain when and how to use archiving
- Document command syntax
- Describe safety features
- Show integration with workflow
NOT Responsible For:
- Implementation details (that's in command file)
- Specification (that's in OpenSpec)
Specifications (application-archiving/spec.md)
Responsibilities:
- Define requirements with scenarios
- Document expected behaviors
- Specify error handling
- Define integration points
NOT Responsible For:
- Implementation approach (that's in command file)
- User-facing documentation (that's in CLAUDE.md)
Integration Points
With Existing Commands
/new-application
↓ creates
application.md (with Status: Draft)
↓ populated by
/populate-application
↓ validated by
/validate-application
↓ generates
/write-cover-letter → cover-letter.md
↓ generates
/write-application-email → application-email.md
↓ user sends
(Application submitted)
↓ archives
/archive-application → moves to rejected/ or not-interested/
With File System
File System Operations:
- Read: application.md (for current status)
- Write: application.md (to update status)
- Check: cover-letter.md, application-email.md, attachments/*
- Create: applications/rejected/, applications/not-interested/
- Move: applications/pending/[folder]/ → applications/[reason]/[folder]/
- Verify: Destination exists, source removed
With User Workflow
User Decision Points:
1. Should I archive? → User decides based on application outcome
2. Which reason? → rejected (company) or not-interested (user)
3. Force or not? → If documents exist, user decides to proceed or cancel
4. Where is it? → User can check archive folders if needed
Performance Considerations
Operation Speed
Status update:
- Fast: Read/write single text file
- ~10-50ms typical
Safety checks:
- Fast: Check file existence (no content reading)
- ~5-20ms per file
Folder move:
- Fast: On same filesystem, just updates directory entries
- ~10-100ms typical
- Slow: On different filesystems, copies all files
- ~1-10s depending on file count and size
Total typical time: < 1 second
Resource Usage
Memory:
- Minimal: Read/write application.md (~5-20KB)
- No large file operations or in-memory copies
Disk I/O:
- Light: Status update (one file write)
- Moderate: Folder move (directory metadata updates)
- Heavy: Only if moving across filesystems (full copy)
Optimization:
- Not needed for typical use case
- Could add progress indicator for large attachments folders
Security Considerations
File System Access
Concerns:
- User must have write permissions on pending/ and archive folders
- Must be able to modify application.md
- Must be able to move folders
Mitigations:
- Check permissions before attempting operations
- Clear error messages if permissions denied
- No privilege escalation or dangerous operations
Data Preservation
Concerns:
- Accidental data loss if move fails partway
- Status update without successful move
Mitigations:
- Verify move succeeded before confirming
- Rollback status if move fails
- Never delete source until verified at destination
- Safety warnings for generated documents
Path Traversal
Concerns:
- User could provide application name like "../../../etc"
- Could try to move folders outside applications/
Mitigations:
- Validate application name is valid folder in pending/
- Resolve full paths and check they're within applications/
- No user-provided target paths (only reason parameter)
Testing Strategy
Unit-Level Testing
Test each component:
- Argument parsing (valid/invalid inputs)
- Location detection (current dir vs. explicit name)
- Safety checks (detect documents correctly)
- Status update (find and replace correctly)
- Folder move (succeed and rollback)
Integration Testing
Test command flow:
- End-to-end archiving (from pending to rejected)
- End-to-end with safety checks
- Error scenarios (not found, invalid reason, etc.)
Edge Case Testing
Test unusual scenarios:
- Missing Status field (add it)
- Empty attachments folder (don't warn)
- Re-archiving (error appropriately)
- Concurrent access (handle gracefully)
Manual Testing
User acceptance:
- Run through complete workflow
- Verify intuitive behavior
- Check error messages are clear
- Confirm success messages are helpful
Future Considerations
Extensibility
Easy to add later:
- Additional archive reasons (accepted, on-hold, etc.)
- Archive search and listing commands
- Bulk archiving operations
- Archive statistics and reporting
Design supports:
- Parameterized reason (easy to add new values)
- Consistent folder structure (easy to extend)
- Status field format (can add more states)
Scalability
Current design:
- Handles dozens to hundreds of applications fine
- Linear search in pending folder (acceptable scale)
- File system operations are efficient
If needed later:
- Index of archived applications
- Database for faster searches
- Bulk operations for managing many archives
Maintenance
Design for maintainability:
- Follows existing command patterns
- Clear separation of concerns
- Well-documented in code and specs
- Testable components
Future updates:
- Easy to modify error messages
- Easy to add new safety checks
- Easy to extend with new features
- Easy to update status field format
Summary
The archiving feature is designed to:
- ✅ Follow established patterns for consistency
- ✅ Protect user work with safety checks
- ✅ Minimize changes to existing files
- ✅ Create resources on-demand
- ✅ Integrate naturally with existing workflow
- ✅ Handle errors gracefully with clear messages
- ✅ Support future enhancements
Complexity: Low to moderate Risk: Low (additive feature, no breaking changes) Maintenance: Low (follows patterns, well-documented) User Impact: High (solves real organizational need)
Design Status: Complete and ready for implementation Next Steps: Review proposal, implement according to tasks.md