Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
28 changes: 28 additions & 0 deletions .planning/MILESTONES.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
# Project Milestones: updex

## v1 updex hardening (Shipped: 2026-01-26)

**Delivered:** Test infrastructure, safe enable/disable semantics, systemd timer for auto-updates, and polished CLI experience.

**Phases completed:** 1-5 (11 plans total)

**Key accomplishments:**
- Established test foundation enabling 177+ tests to run without root
- Fixed dangerous disable semantics with merge state safety checks
- Built complete systemd unit infrastructure for timer/service management
- Exposed auto-update via `daemon enable/disable/status` commands
- Polished all commands with actionable errors and comprehensive help

**Stats:**
- 10,377 lines of Go
- 5 phases, 11 plans
- 15/15 requirements satisfied
- 12 days from start to ship

**Git range:** `feat(01-01)` → `docs(v1)`

**What's next:** v2 milestone with configurable timer schedules, offline mode, and auto-update notifications

---

*For full milestone details, see `.planning/milestones/v1-ROADMAP.md`*
79 changes: 52 additions & 27 deletions .planning/PROJECT.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,54 +2,75 @@

## What This Is

A Debian-compatible alternative to systemd's `updatectl` for managing systemd-sysexts. Provides a CLI tool for discovering, installing, updating, and removing system extensions from multiple registries, targeting both sysadmins and desktop enthusiasts.
A Debian-compatible alternative to systemd's `updatectl` for managing systemd-sysexts. Provides a CLI tool for discovering, installing, updating, and removing system extensions from multiple registries, with auto-update timer support.

## Core Value

Users can reliably install and update systemd-sysexts from any registry without needing the unavailable `updatectl` package.

## Current State

**Shipped:** v1 (2026-01-26)

The tool is production-ready with:
- Complete CLI for extension management (install, update, remove, list, check)
- Feature-based grouping with enable/disable commands
- Auto-update via systemd timer (`daemon enable/disable/status`)
- Safe enable/disable with `--now` flag and merge state checks
- Comprehensive test suite (177+ tests, all run without root)
- Shell completions for bash, zsh, and fish

## Requirements

### Validated

<!-- Shipped and confirmed valuable. Inferred from existing codebase. -->

- ✓ CLI framework with Cobra commands — existing
- ✓ Discover available extensions from registries — existing
- ✓ Install extensions from URL/registry — existing
- ✓ Update installed extensions to latest versions — existing
- ✓ List installed extensions and available versions — existing
- ✓ Check for available updates — existing
- ✓ Multiple registry support — existing
- ✓ GPG signature verification — existing
- ✓ Progress bar for downloads — existing
- ✓ JSON output mode — existing
- ✓ Feature-based extension grouping — existing
- ✓ Transfer config file parsing (.transfer INI format) — existing
- ✓ Version comparison and pattern matching — existing
- ✓ CLI framework with Cobra commands — v1
- ✓ Discover available extensions from registries — v1
- ✓ Install extensions from URL/registry — v1
- ✓ Update installed extensions to latest versions — v1
- ✓ List installed extensions and available versions — v1
- ✓ Check for available updates — v1
- ✓ Multiple registry support — v1
- ✓ GPG signature verification — v1
- ✓ Progress bar for downloads — v1
- ✓ JSON output mode — v1
- ✓ Feature-based extension grouping — v1
- ✓ Transfer config file parsing (.transfer INI format) — v1
- ✓ Version comparison and pattern matching — v1
- ✓ Enable feature with --now (immediate download) — v1
- ✓ Disable feature with --now (immediate removal) — v1
- ✓ Merge state safety checks — v1
- ✓ Auto-update systemd timer/service — v1
- ✓ daemon enable/disable/status commands — v1
- ✓ --reboot flag for update command — v1
- ✓ Unit test coverage for core operations — v1
- ✓ Integration tests for workflows — v1
- ✓ Tests run without root — v1
- ✓ Actionable error messages — v1
- ✓ Comprehensive help text — v1
- ✓ Shell completions (bash, zsh, fish) — v1

### Active

<!-- Current scope. Building toward these. -->

- [ ] Auto-update mechanism with systemd timer/service
- [ ] Optional command to install auto-update timer/service files
- [ ] Disable feature removes extension files (not just stops updates)
- [ ] Improved unit test coverage
- [ ] Integration tests with real sysexts
- [ ] Better error messages and help text
- [ ] Configurable timer schedule (daily, weekly, custom)
- [ ] --offline flag for list command
- [ ] Auto-update failure notifications

### Out of Scope

- Mobile app or GUI — CLI-only tool
- Windows/macOS support — systemd-sysext is Linux-specific
- Package repository hosting — this is a client tool only
- D-Bus daemon — CLI-only tool is sufficient
- Partition operations — focus on file-based transfers
- Auto-update by default — must be opt-in
- Rollback command — use version pinning instead

## Context

The project is part of the Frostyard ecosystem. The codebase follows a clean library + CLI architecture where `updex/` is the public API and `cmd/` contains thin CLI wrappers. Configuration is INI-based (.transfer and .feature files) following systemd conventions.

Existing test coverage is limited. The tool is functional for core operations but needs polish before broader release.
Current codebase: 10,377 lines of Go with 44.4% coverage on updex package.

## Constraints

Expand All @@ -73,8 +94,12 @@ Existing test coverage is limited. The tool is functional for core operations bu
| Cobra for CLI framework | Industry standard, good docs | ✓ Good |
| INI format for configs | Matches systemd conventions | ✓ Good |
| Library + CLI architecture | Enables programmatic use | ✓ Good |
| Disable = remove files | Simpler mental model for users | — Pending |
| Disable = remove files | Simpler mental model for users | ✓ Good |
| Package-level SetRunner | Simple test injection pattern | ✓ Good |
| --now combines unmerge+remove | Complete immediate effect | ✓ Good |
| Fixed daily timer schedule | Simpler initial implementation | ✓ Good |
| Service uses --no-refresh | Stage only, no auto-activate | ✓ Good |

---

_Last updated: 2026-01-26 after adding CI constraint_
_Last updated: 2026-01-26 after v1 milestone_
110 changes: 0 additions & 110 deletions .planning/ROADMAP.md

This file was deleted.

79 changes: 28 additions & 51 deletions .planning/STATE.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,69 +5,42 @@
See: .planning/PROJECT.md (updated 2026-01-26)

**Core value:** Users can reliably install and update systemd-sysexts from any registry without needing the unavailable updatectl package.
**Current focus:** Phase 4 - Auto-Update CLI
**Current focus:** v1 shipped, planning next milestone

## Current Position

Phase: 4 of 5 (Auto-Update CLI)
Plan: 1 of 1 in current phase
Status: Phase complete
Last activity: 2026-01-26 — Completed 04-01-PLAN.md
Phase: Complete (v1 milestone shipped)
Plan: N/A
Status: Ready for next milestone
Last activity: 2026-01-26 — v1 milestone complete

Progress: [████████░░] 80%
Progress: [██████████] v1 SHIPPED

## Performance Metrics

**Velocity:**
- Total plans completed: 8
- Average duration: 5 min
- Total execution time: 38 min

**By Phase:**

| Phase | Plans | Total | Avg/Plan |
|-------|-------|-------|----------|
| 01-test-foundation | 2 | 27 min | 13.5 min |
| 02-core-ux-fixes | 2 | 7 min | 3.5 min |
| 03-systemd-unit-infrastructure | 3 | 2 min | 0.7 min |
| 04-auto-update-cli | 1 | 2 min | 2 min |

**Recent Trend:**
- Last 5 plans: 2min, 0min, 1min, 1min, 2min
- Trend: fast

*Updated after each plan completion*
**v1 Milestone:**
- Total plans completed: 11
- Total phases: 5
- Requirements satisfied: 15/15
- Timeline: 12 days

## Accumulated Context

### Decisions

Decisions are logged in PROJECT.md Key Decisions table.
Recent decisions affecting current work:

- [Roadmap]: Fix-first approach — address remove/disable semantics before auto-update
- [Roadmap]: Layered testing — each phase adds testable units
- [01-01]: Package-level SetRunner with cleanup function for test injection
- [01-01]: SysextRunner injected via ClientConfig optional field
- [01-02]: SHA256 hashes in tests must match actual content hash
- [01-02]: Helper functions (createTransferFile, updateTransferTargetPath) shared across test files
- [02-01]: --now on disable combines unmerge AND file removal
- [02-01]: Merge state check requires --force for active extensions
- [02-02]: Use DryRun flag to test feature logic without /etc access
- [02-02]: Simulate merged extensions with CurrentSymlink for testing
- [03-02]: SystemctlRunner interface mirrors SysextRunner pattern for consistency
- [03-02]: IsActive/IsEnabled return false (not error) for non-zero exit codes
- [03-03]: Install fails if files exist - require explicit Remove first
- [03-03]: Remove ignores stop/disable errors (may not be running)
- [04-01]: Fixed daily schedule for timer (configurable deferred to v2)
- [04-01]: Service uses --no-refresh to stage files only (AUTO-04)
- [04-01]: Reboot only triggers when anyInstalled && err == nil
Key decisions from v1:

- Package-level SetRunner with cleanup function for test injection
- --now on disable combines unmerge AND file removal
- Merge state check requires --force for active extensions
- Fixed daily schedule for timer (configurable deferred to v2)
- Service uses --no-refresh to stage files only

### Test Coverage

- updex package: 44.4% coverage
- 37 unit tests for core operations (including 11 new feature tests)
- 174 total tests across all packages
- 177+ total tests across all packages
- All tests run without root

### Pending Todos
Expand All @@ -86,12 +59,16 @@ None.

## Session Continuity

Last session: 2026-01-26T19:36:30Z
Stopped at: Completed 04-01-PLAN.md, Phase 4 complete
Last session: 2026-01-26
Stopped at: v1 milestone shipped
Resume file: None

## Next Steps

Phase 4 complete. Ready for:
- /gsd-discuss-phase 5 — Integration & Polish
- /gsd-plan-phase 5 — skip discussion, plan directly
v1 milestone complete and archived!

- Milestone archive: `.planning/milestones/v1-ROADMAP.md`
- Requirements archive: `.planning/milestones/v1-REQUIREMENTS.md`
- Summary: `.planning/MILESTONES.md`

To start next milestone: `/gsd-new-milestone`
Loading