feat(cli): aelf delete subcommand (#440) - #451
Conversation
Reviewer's GuideImplements a new Sequence diagram for the new aelf delete CLI flowsequenceDiagram
actor User
participant CLI as aelf_cli
participant Parser as argparse_parser
participant DeleteCmd as cmd_delete
participant Store as MemoryStore
participant FeedbackHistory as feedback_history
User->>CLI: aelf delete <belief_id> [--yes] [--force]
CLI->>Parser: parse argv
Parser-->>CLI: args(belief_id, yes, force)
CLI->>DeleteCmd: _cmd_delete(args, out)
DeleteCmd->>Store: _open_store()
DeleteCmd->>Store: get_belief(belief_id)
Store-->>DeleteCmd: belief_or_none
alt belief not found
DeleteCmd->>CLI: print stderr belief not found
DeleteCmd->>Store: close()
DeleteCmd-->>CLI: return exit_code 1
else belief found
alt locked and not force
DeleteCmd->>CLI: print stderr locked message
DeleteCmd->>Store: close()
DeleteCmd-->>CLI: return exit_code 1
else not locked or force
alt yes flag not set
DeleteCmd->>CLI: print stderr belief summary
DeleteCmd->>User: prompt type first 8 chars
User-->>DeleteCmd: confirmation_input
alt input matches prefix
Note over DeleteCmd,User: proceed with delete
else mismatch
DeleteCmd->>CLI: print stderr aborted confirmation
DeleteCmd->>Store: close()
DeleteCmd-->>CLI: return exit_code 1
end
else yes flag set
Note over DeleteCmd: skip confirmation prompt
end
DeleteCmd->>FeedbackHistory: insert_feedback_event(belief_id, valence=-1.0, source=user_deleted_or_force)
DeleteCmd->>Store: delete_belief(belief_id)
DeleteCmd->>CLI: print stdout deleted message
DeleteCmd->>Store: close()
DeleteCmd-->>CLI: return exit_code 0
end
end
Entity relationship diagram for beliefs and feedback_history in deleteerDiagram
BELIEFS {
string belief_id PK
string content
string lock_level
}
FEEDBACK_HISTORY {
string id PK
string belief_id
float valence
string source
string created_at
}
BELIEFS ||--o{ FEEDBACK_HISTORY : logs_events_for
%% BELIEFS rows are hard-deleted by delete_belief
%% FEEDBACK_HISTORY has no foreign key to BELIEFS; audit rows remain as orphans
File-Level Changes
Assessment against linked issues
Possibly linked issues
Tips and commandsInteracting with Sourcery
Customizing Your ExperienceAccess your dashboard to:
Getting Help
|
|
Warning Rate limit exceeded
To continue reviewing without waiting, purchase usage credits in the billing tab. ⌛ How to resolve this issue?After the wait time has elapsed, a review can be triggered using the We recommend that you space out your commits to avoid hitting the rate limit. 🚦 How do rate limits work?CodeRabbit enforces hourly rate limits for each developer per organization. Our paid plans have higher rate limits than the trial, open-source and free plans. In all cases, we re-allow further reviews after a brief timeout. Please see our FAQ for further information. ℹ️ Review info⚙️ Run configurationConfiguration used: Path: .coderabbit.yaml Review profile: CHILL Plan: Pro Run ID: 📒 Files selected for processing (6)
✨ Finishing Touches🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
|
[claim:review:Kulili:2026-05-05T19:43:14Z] |
|
This PR is now behind Auto-rebase was removed because the bot has no signing key; rebasing as the bot strips author signatures and the |
|
Reviewed at
Blocked on FF: branch is no longer an ancestor of Flagging |
|
[release:review:Kulili:2026-05-05T19:45:14Z] |
|
[claim:review:Toug:2026-05-06T21:03:33Z] |
2889231 to
ba6da44
Compare
Hard-delete one belief via MemoryStore.delete_belief. Writes an audit row to feedback_history (valence=-1.0, source=user_deleted[_force]) before the cascade. Locked beliefs require --force; confirmation prompt requires typing the first 8 chars of the id (--yes to bypass). Temporarily placed in HIDDEN_SUBCOMMANDS until the slash file lands.
Covers: not-found, locked-without-force, prompt-mismatch, prompt-match, --yes path, --force path, --force --yes, audit-row written to feedback_history (source and valence), cascade through edges (src and dst), and output string exactness.
Mirrors unlock.md. Includes the spec-required safety note: the slash form does not imply --yes; the invoking surface must let the user respond to the confirmation prompt. Moves "delete" from HIDDEN_SUBCOMMANDS to EXPECTED_COMMANDS in the slash-command test (required for test_no_extra_files_in_slash_commands_dir to pass).
Entry follows the unlock row (lifecycle siblings). Covers: cascade scope, audit-row details, confirmation prompt mechanic, --yes/--force flags, and exit codes. Updated subcommand count from twenty-nine to thirty.
Expands the registration comment to explicitly document which two test assertions enforce the invariant (no-extra-files + cli-surface match). Confirms "delete" is in EXPECTED_COMMANDS and absent from HIDDEN_SUBCOMMANDS.
ba6da44 to
da6bfaa
Compare
|
[release:review:Toug:2026-05-06T21:08:27Z] |
Summary
Adds
aelf delete— explicit hard-delete of one belief from the store. Sibling ofaelf unlock. Closes #440.Default user posture stays "decay, don't delete" (retention class #290 + Beta-Bernoulli posterior).
aelf deleteis the escape hatch: hand-entered duplicates, beliefs promoted in error, privacy removals.Contract
MemoryStore.delete_belief(row + FTS + edges + entity index).feedback_historyBEFORE the cascade (valence=-1.0,source=user_deletedoruser_deleted_force).feedback_historyhas no FK tobeliefs, so the orphan row pins the forensic record.y/Nfor muscle-memory safety on a destructive op).--yesskips the prompt.lock_level=user) beliefs without--force.--forcedoes not skip the prompt — pair with--yesfor non-interactive locked-belief deletion.Decisions made (deferred from issue body to spec memo)
The issue body lists hard-delete vs. soft-delete (
deleted_atcolumn +SUPERSEDESedge) as a design choice. Spec memo (docs/feature-aelf-delete-cli.md) picks hard-delete + audit-row-in-feedback_history:deleted_at IS NULL— large diff with subtle test surface.SUPERSEDESedges today.If a future consumer wants recoverable delete (
undelete, graph-walks across deleted beliefs), file a separate issue with that consumer named.MCP
aelf_deleteport deferred per #382 Track E ratification (A6, 2026-05-04): onlyconfirm(#390) andunlock/promote/demote(#391) ship in v2.0;deletewaits on filed user demand AND demonstrated bench impact.Commit structure
The
EXPECTED_COMMANDS/HIDDEN_SUBCOMMANDSinvariant (the slash-file presence test compares both against the directory) means the actualEXPECTED_COMMANDSmove had to happen in commit 4 atomically with the slash file. Commit 6 expands the registration comment to document which two test assertions enforce the invariant — kept as a separate commit to make the registration auditably visible.Acceptance (mirrors issue #440)
docs/feature-aelf-delete-cli.md--yesto bypass.--force.tests/test_cli_delete_command.py(28 cases — not-found, locked-without-force, prompt mismatch/empty/match, --yes, --force, --force --yes, audit-row source/valence, orphan-survives-cascade, cascade-outgoing/incoming-edges, exact-output).docs/COMMANDS.mdentry./aelf:deletemirroringunlock.md.EXPECTED_COMMANDSregistration intests/test_slash_commands.py.Test plan
uv run pytest tests/ --ignore=tests/e2e -q— full suite green locally.uv run pytest tests/test_cli_delete_command.py tests/test_slash_commands.py -q— 126 passed in 0.57s.Summary by Sourcery
Add a hard-delete CLI and slash command for beliefs with audit logging and safety prompts.
New Features:
aelf deleteCLI subcommand to hard-delete a single belief with optional confirmation bypass and forced deletion of locked beliefs./aelf:deleteslash command that mirrors the CLI delete behavior.Enhancements:
Tests: