feat: working on alignment to bDS - MCP proposal lifecycle

This commit is contained in:
2026-05-01 18:20:29 +02:00
parent 59e5d71396
commit 5d70f1b55a
4 changed files with 9 additions and 17 deletions

View File

@@ -1,13 +1,16 @@
# Alignment Tasks # Alignment Tasks
Allium CLI: `/opt/homebrew/bin/allium`. Use `allium check specs/<file>.allium` only when tending a spec; no Allium command is needed for code-only alignment tasks.
Goal: align bDS2 with old bDS behavior. Use the Allium specs as the contract only where they match old bDS. If old bDS and bDS2 agree but the spec differs, tend the spec. Goal: align bDS2 with old bDS behavior. Use the Allium specs as the contract only where they match old bDS. If old bDS and bDS2 agree but the spec differs, tend the spec.
## P0: MCP Proposal Lifecycle ## P0: MCP Proposal Lifecycle (done)
- Old bDS: proposals are in-memory and removed after `accept_proposal` or `discard_proposal`. - Old bDS: proposals are in-memory and removed after `accept_proposal` or `discard_proposal`.
- bDS2 now: proposals are persisted and marked `accepted` / `discarded`. - bDS2 now: proposals are persisted and marked `accepted` / `discarded`.
- Spec: matches old bDS; accepted/discarded proposals should no longer exist. - Spec: matches old bDS; accepted/discarded proposals should no longer exist.
- Action: change bDS2 to remove accepted/discarded proposals, update tests, and remove/adjust terminal-status expectations. - Action: change bDS2 to remove accepted/discarded proposals, update tests, and remove/adjust terminal-status expectations.
- Status: done.
## P0: MCP Cursor Resources ## P0: MCP Cursor Resources

View File

@@ -69,8 +69,8 @@ defmodule BDS.MCP.ProposalStore do
Enum.map(expired, &Repo.get(Proposal, &1.id)) Enum.map(expired, &Repo.get(Proposal, &1.id))
end end
def mark_accepted(id) when is_binary(id), do: mark_status(id, :accepted) def mark_accepted(id) when is_binary(id), do: remove(id)
def mark_discarded(id) when is_binary(id), do: mark_status(id, :discarded) def mark_discarded(id) when is_binary(id), do: remove(id)
defp mark_status(id, status) do defp mark_status(id, status) do
case Repo.get(Proposal, id) do case Repo.get(Proposal, id) do

View File

@@ -10,8 +10,6 @@ use "./template.allium" as template
enum ProposalStatus { enum ProposalStatus {
pending pending
accepted
discarded
expired expired
} }
@@ -49,8 +47,6 @@ entity Proposal {
is_expired: expires_at <= now is_expired: expires_at <= now
transitions status { transitions status {
pending -> accepted
pending -> discarded
pending -> expired pending -> expired
} }
} }
@@ -342,7 +338,6 @@ rule AcceptProposal {
media/UpdateMediaRequested(proposal.target_media, deserialize_media_changes(proposal.data)) media/UpdateMediaRequested(proposal.target_media, deserialize_media_changes(proposal.data))
if proposal.kind = propose_post_metadata: if proposal.kind = propose_post_metadata:
post/UpdatePostRequested(proposal.target_post, deserialize_post_changes(proposal.data)) post/UpdatePostRequested(proposal.target_post, deserialize_post_changes(proposal.data))
proposal.status = accepted
not exists proposal not exists proposal
} }
@@ -355,7 +350,6 @@ rule DiscardProposal {
script/DeleteScriptRequested(proposal.proposed_script) script/DeleteScriptRequested(proposal.proposed_script)
if proposal.kind = propose_template: if proposal.kind = propose_template:
template/DeleteTemplateRequested(proposal.proposed_template) template/DeleteTemplateRequested(proposal.proposed_template)
proposal.status = discarded
not exists proposal not exists proposal
} }

View File

@@ -180,7 +180,7 @@ defmodule BDS.MCPTest do
assert_raise Ecto.NoResultsError, fn -> BDS.Posts.get_post!(draft_post_id) end assert_raise Ecto.NoResultsError, fn -> BDS.Posts.get_post!(draft_post_id) end
end end
test "proposal lifecycle is persisted with pending, accepted, discarded, and expired statuses" do test "proposal lifecycle removes accepted and discarded proposals" do
assert {:ok, accepted_result} = assert {:ok, accepted_result} =
BDS.MCP.call_tool("draft_post", %{title: "Accept Me", content: "Body"}) BDS.MCP.call_tool("draft_post", %{title: "Accept Me", content: "Body"})
@@ -188,19 +188,14 @@ defmodule BDS.MCPTest do
assert ProposalStore.get(accepted_id).status == :pending assert ProposalStore.get(accepted_id).status == :pending
assert {:ok, _accepted} = BDS.MCP.call_tool("accept_proposal", %{proposalId: accepted_id}) assert {:ok, _accepted} = BDS.MCP.call_tool("accept_proposal", %{proposalId: accepted_id})
assert ProposalStore.get(accepted_id) == nil
accepted_proposal = ProposalStore.get(accepted_id)
assert accepted_proposal.status == :accepted
assert accepted_proposal.entity_id == accepted_result["post"]["id"]
assert {:ok, discarded_result} = assert {:ok, discarded_result} =
BDS.MCP.call_tool("draft_post", %{title: "Discard Me Later", content: "Body"}) BDS.MCP.call_tool("draft_post", %{title: "Discard Me Later", content: "Body"})
discarded_id = discarded_result["proposal_id"] discarded_id = discarded_result["proposal_id"]
assert {:ok, _discarded} = BDS.MCP.call_tool("discard_proposal", %{proposalId: discarded_id}) assert {:ok, _discarded} = BDS.MCP.call_tool("discard_proposal", %{proposalId: discarded_id})
assert ProposalStore.get(discarded_id) == nil
discarded_proposal = ProposalStore.get(discarded_id)
assert discarded_proposal.status == :discarded
expired = expired =
ProposalStore.create("draft_post", %{"post_id" => "expired-post"}, ProposalStore.create("draft_post", %{"post_id" => "expired-post"},