feat(agentic): soft-delete plans on delete

Co-Authored-By: Virgil <virgil@lethean.io>
This commit is contained in:
Virgil 2026-04-01 16:26:26 +00:00
parent 780b22a3f7
commit afb6b0f881
4 changed files with 20 additions and 30 deletions

View file

@ -303,7 +303,7 @@ func (s *PrepSubsystem) cmdPlanDelete(options core.Options) core.Result {
return core.Result{Value: err, OK: false}
}
core.Print(nil, "deleted: %s", output.Deleted)
core.Print(nil, "archived: %s", output.Deleted)
return core.Result{Value: output, OK: true}
}

View file

@ -1088,17 +1088,20 @@ func TestCommands_CmdPlanDelete_Good(t *testing.T) {
output := captureStdout(t, func() {
r := s.cmdPlanDelete(core.NewOptions(
core.Option{Key: "_arg", Value: created.ID},
core.Option{Key: "reason", Value: "RFC contract says soft delete"},
))
assert.True(t, r.OK)
})
assert.Contains(t, output, "deleted:")
assert.Contains(t, output, "archived:")
assert.False(t, fs.Exists(created.Path))
assert.True(t, fs.Exists(created.Path))
_, err = readPlan(PlansRoot(), created.ID)
require.Error(t, err)
assert.Contains(t, err.Error(), "not found")
plan, err := readPlan(PlansRoot(), created.ID)
require.NoError(t, err)
assert.Equal(t, "archived", plan.Status)
assert.False(t, plan.ArchivedAt.IsZero())
assert.Contains(t, plan.Notes, "RFC contract says soft delete")
}
func TestCommands_CmdExtract_Good(t *testing.T) {

View file

@ -366,23 +366,5 @@ func archivePlanResult(input PlanDeleteInput, missingMessage, op string) (*Plan,
}
func deletePlanResult(input PlanDeleteInput, missingMessage, op string) (*Plan, error) {
ref := planReference(input.ID, input.Slug)
if ref == "" {
return nil, core.E(op, missingMessage, nil)
}
plan, err := readPlan(PlansRoot(), ref)
if err != nil {
return nil, err
}
if result := fs.Delete(planPath(PlansRoot(), plan.ID)); !result.OK {
deleteErr, _ := result.Value.(error)
if deleteErr == nil {
deleteErr = core.E(op, "failed to delete plan", nil)
}
return nil, core.E(op, "failed to delete plan", deleteErr)
}
return plan, nil
return archivePlanResult(input, missingMessage, op)
}

View file

@ -263,16 +263,21 @@ func TestPlan_PlanDelete_Good(t *testing.T) {
Title: "Delete Me", Objective: "Will be deleted",
})
_, delOut, err := s.planDelete(context.Background(), nil, PlanDeleteInput{ID: createOut.ID})
_, delOut, err := s.planDelete(context.Background(), nil, PlanDeleteInput{
ID: createOut.ID,
Reason: "No longer needed",
})
require.NoError(t, err)
assert.True(t, delOut.Success)
assert.Equal(t, createOut.ID, delOut.Deleted)
assert.False(t, fs.Exists(createOut.Path))
assert.True(t, fs.Exists(createOut.Path))
_, readErr := readPlan(PlansRoot(), createOut.ID)
require.Error(t, readErr)
assert.Contains(t, readErr.Error(), "not found")
archivedPlan, readErr := readPlan(PlansRoot(), createOut.ID)
require.NoError(t, readErr)
assert.Equal(t, "archived", archivedPlan.Status)
assert.False(t, archivedPlan.ArchivedAt.IsZero())
assert.Contains(t, archivedPlan.Notes, "No longer needed")
}
func TestPlan_PlanDelete_Bad_MissingID(t *testing.T) {