Skip to content

Make intent replay self-healing#57

Merged
KristjanPikhof merged 41 commits into
mainfrom
feature/intent-mode-self-healing
Jul 13, 2026
Merged

Make intent replay self-healing#57
KristjanPikhof merged 41 commits into
mainfrom
feature/intent-mode-self-healing

Conversation

@KristjanPikhof

Copy link
Copy Markdown
Owner

Feature Description

Make ACD intent replay self-healing so stale branch chains no longer block
background commits or require destructive manual cleanup. Captured work is
either proven as already published or preserved under a hidden recovery ref
before its queue state changes.

This also adds bounded planner-outage fallback, simpler everyday lifecycle
controls, and the observability needed to distinguish waiting, healing,
degraded, and needs-attention states.

User Story

As a developer who leaves ACD running in the background, I want replay and
branch transitions to recover safely on their own so that commits keep flowing
without losing captured work.

Type of Change

  • New feature

Implementation Details

  • Reconcile complete unpublished (branch_ref, generation) chains instead of
    deleting or retargeting individual barriers.
  • Prove exact final state as published; otherwise build an immutable recovery
    commit/ref before atomically marking the chain recovered.
  • Preserve work across branch switches, rewinds, fast-forwards, deleted refs,
    acd fix, and commit-all without changing the live worktree or index.
  • Persist planner circuit health, reuse one provider, and fall back to
    deterministic planning during bounded outage cooldowns.
  • Add read-only bare health plus idempotent acd on / acd off controls and
    expose recovery/circuit details through status and diagnose output.

Architecture

The state layer owns immutable capture provenance, recovery snapshots, and
atomic lifecycle transitions. The daemon owns Git proof/archive construction,
branch-transition reconciliation, and planner circuit behavior. CLI commands
delegate to the same exact-chain reconciler, while docs and harness templates
describe the shipped lifecycle and recovery contracts.

These pieces form one rollback unit: the schema, reconciler, transition paths,
controls, integration proof, and documentation need to ship together.

Key Files Changed

File Change
internal/state/recovery.go Load immutable chains and atomically record published/recovered snapshots
internal/daemon/reconcile.go Prove or archive complete chains without mutating live Git state
internal/daemon/intent_health.go Persist circuit state and bound planner outages
internal/daemon/daemon.go Reconcile transitions and reuse the planner/provider lifecycle
internal/cli/control.go Add bare health plus idempotent acd on and acd off
internal/cli/fix.go Route safe and forced repair through exact-chain recovery
test/integration/squash_backlog_recovery_test.go Prove 60-capture squash/deleted-branch recovery

API Changes

No HTTP API changes.

Method Endpoint Description
CLI acd Read-only health summary and next action
CLI acd on / acd off Idempotent repo lifecycle controls
CLI/JSON status / diagnose Recovery snapshots, active barriers, and planner-circuit observability

Database Changes

  • No database changes
  • Migration included and tested

Schema v12 adds immutable recovery snapshots and ordered event membership.
Schema v13 adds the covering index used to retain published materialization
prefixes efficiently while an unresolved same-base suffix exists. Existing
databases migrate through the idempotent schema bootstrap.

How to Test

  1. Run cleanenv make lint and cleanenv make test.
  2. Run cleanenv go test ./test/integration/... -tags=integration -race -count=1 -timeout 5m.
  3. Run cleanenv go test ./internal/daemon/... ./internal/git/... ./internal/state/... ./internal/pause/... ./internal/cli/... -race -count=3 -timeout 10m.
  4. Inspect acd status --repo . and verify the daemon is healthy with no pending, blocked, failed, or capture-error rows.

The full implementation gate passed before the final documentation/help-only
commits. On the final branch head, cleanenv make lint and focused
Status|Diagnose|Help CLI race tests also pass.

Edge Cases Considered

  • Squash/rebase recovery, deleted branches, same-SHA rewinds, fast-forwards,
    detached/missing refs, and linked worktrees.
  • Missing objects, partial final-state matches, recovery-ref collisions, Git
    CAS races, SQLite rollback, and restart idempotency.
  • Create, modify, delete, rename, mode, symlink, pathspec-magic, and whitespace
    filenames without touching user staging.
  • Provider transport failures, invalid plans, cancellation races, half-open
    probes, repeated fallback windows, and secret-safe persisted errors.

Checklist

  • Code follows the project's style guidelines
  • Self-reviewed the code
  • Added unit tests for new functionality
  • Added integration tests where applicable
  • Existing tests pass locally
  • Updated documentation
  • Tested on mobile (not applicable; CLI/daemon only)
  • No new warnings or console errors introduced
  • Backwards compatible (migration plan documented)

Feature Flag

  • No feature flag needed
  • Behind feature flag: FLAG_NAME

Intent behavior remains selected through the existing
ACD_COMMIT_STRATEGY=intent configuration.

Related Issues

None linked in the branch name or commit history.

Screenshots / Demo

Not applicable; this is CLI/daemon behavior covered by output contracts and
integration tests.

Deployment Notes

  • Restart the daemon after installing the new binary so schema migration and
    runtime environment resolution use the new version.
  • No new dependency or required environment variable is introduced.
  • Recovery refs under refs/acd/recovery/* are intentionally retained for
    operator inspection and restore workflows.

- Preserve blocked chains with collision-safe recovery refs
- Lock branch state and planner fallbacks across races
- Simplify health, lifecycle, and explicit recovery controls
- Cover branch surgery, outages, and large backlog recovery
- Explain automatic chain recovery and planner fallback behavior
- Present bare health plus idempotent on and off controls
- Clarify explicit fix and commit-all safety boundaries
- Consolidates project, release, workflow, and commit guidance
- Keeps the runbook concise while preserving essential test context
- Prevents timeout recovery from racing an in-place plugin rewrite
- Keeps the respawn test focused on using a distinct executable
- Clarify that daemon locking applies only to authorized mutations
- Keep previews and clean no-ops read-only while a daemon is active
- Align CLI behavior, user guidance, and regression coverage
- Treat pathspec-looking filenames as literal recovery paths
- Prevent Git pathspec magic from selecting the wrong entries
- Preserve published materialization prefixes needed by later chains
- Continue pruning ordinary published events when safe
- Treat pathspec-looking filenames as literal recovery paths
- Verify reconciliation publishes the intended external commit
- Remove sensitive URL paths from planner error messages
- Preserve the URL origin and surrounding punctuation
- Avoid initializing planner health before daemon lock acquisition
- Preserve existing health state when startup loses the lock
- Keep the commit-all safety guidance aligned with surrounding help text
- Improve readability without changing the documented behavior or
  examples
- Preserve health state when callers cancel during completion
- Treat caller cancellation as authoritative over provider failures
- Document declined prompts as safe while the daemon lock is held
- Cover the behavior in CLI help, guides, and regression tests
- Use distinct base identifiers so prune freshness checks remain
  unambiguous
- Keep decision-record tests isolated across table-driven cases
- Preserve direct context cancellation precedence during completion
- Remove the redundant cancellation helper
- Align related intent planner declarations consistently
- Remove incidental whitespace from daemon startup setup
- Keeps the schema version aligned with the new retention index
- Documents the migration path for bounded recovery-prefix pruning
- Verify recovery-prefix index restoration during schema migration
- Protect query-plan coverage for recovery lookups
- Preserve legal leading and trailing whitespace in paths
- Add regression coverage for literal pathspec generation
- Covers both pathspec magic and surrounding-whitespace names
- Reuses one assertion helper to keep literal-path cases consistent
- Keep the migration test aligned with the canonical schema version
- Improve the failure output by reporting the expected version
  explicitly
- Document the schema v13 index and related recovery safeguards
- Keep contributor guidance aligned with the current state schema
- Allow the respawn assertion more startup time under parallel race
  tests
- Keep the test focused on timeout behavior rather than scheduler load
- Align user-facing command guidance with the `acd`/`acd on`/`acd off`
  flow.
- Add the public command reference and clarify safe recovery sequencing.
- Keep documentation and diagnose guidance consistent with archive
  recovery.
- Clarify intent-mode recovery and planner validation rules
- Keep documentation aligned with current configuration behavior
- Explain compatibility selectors without listing them as primary
  options
- Clarify JSON planning behavior for fresh rewrite plans
- Describe barrier recovery as archive-only rather than purge-based
- Show how to pause capture around rewrite and commit-all flows
- Clarify safe versus forced recovery command usage
- Align version and workflow documentation with current behavior
- Align adapter setup guidance with current doctor checks
- Explain cleanup commands and retained per-repo state
- Document direnv and zsh installation workflows
- Add verification and uninstall guidance for shell users
- Makes the setup commands and approval workflow easier to scan
- Preserves the warnings while reducing dense inline instructions
- Clarifies the uninstall instruction without changing its behavior
- Reflect the enabled-repo dashboard and one-shot verbose view
- Match the documented commands to current list behavior
- Remove obsolete force-mode examples from the recovery sequence
- Keep the documented recovery path aligned with supported commands
- Describe repository state rather than daemon-only health
- Include off and attention-needed states in the observation step
- Keep local build and editor artifacts out of version control.
- Align CI, module metadata, and install guidance on Go 1.26.5
- Record the toolchain security fix in the changelog
- Add a deterministic synchronization point before branch-token sampling
- Exercise branch transition tests without timing races
- Give hidden recovery commits a stable built-in identity
- Verify explicit author and committer metadata independently of repo
  config
- Persist repository identity in shared fixtures used by replay tests
- Keep CI independent of runner-level Git configuration
@KristjanPikhof
KristjanPikhof force-pushed the feature/intent-mode-self-healing branch from 4839490 to b7b4788 Compare July 13, 2026 15:49
@KristjanPikhof KristjanPikhof self-assigned this Jul 13, 2026
@KristjanPikhof
KristjanPikhof marked this pull request as ready for review July 13, 2026 18:30
@KristjanPikhof
KristjanPikhof merged commit 4ec03b6 into main Jul 13, 2026
6 checks passed
@KristjanPikhof
KristjanPikhof deleted the feature/intent-mode-self-healing branch July 13, 2026 18:30
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant