From 5d70f1b55a5e261c7f1e1caf30282de5122a4983 Mon Sep 17 00:00:00 2001 From: Chili Palmer Date: Fri, 1 May 2026 18:20:29 +0200 Subject: [PATCH] feat: working on alignment to bDS - MCP proposal lifecycle --- ALIGNMENT.md | 5 ++++- lib/bds/mcp/proposal_store.ex | 4 ++-- specs/mcp.allium | 6 ------ test/bds/mcp_test.exs | 11 +++-------- 4 files changed, 9 insertions(+), 17 deletions(-) diff --git a/ALIGNMENT.md b/ALIGNMENT.md index b64adb8..8c0cf3c 100644 --- a/ALIGNMENT.md +++ b/ALIGNMENT.md @@ -1,13 +1,16 @@ # Alignment Tasks +Allium CLI: `/opt/homebrew/bin/allium`. Use `allium check specs/.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. -## P0: MCP Proposal Lifecycle +## P0: MCP Proposal Lifecycle (done) - Old bDS: proposals are in-memory and removed after `accept_proposal` or `discard_proposal`. - bDS2 now: proposals are persisted and marked `accepted` / `discarded`. - 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. +- Status: done. ## P0: MCP Cursor Resources diff --git a/lib/bds/mcp/proposal_store.ex b/lib/bds/mcp/proposal_store.ex index b5d7fd4..45f62b9 100644 --- a/lib/bds/mcp/proposal_store.ex +++ b/lib/bds/mcp/proposal_store.ex @@ -69,8 +69,8 @@ defmodule BDS.MCP.ProposalStore do Enum.map(expired, &Repo.get(Proposal, &1.id)) end - def mark_accepted(id) when is_binary(id), do: mark_status(id, :accepted) - def mark_discarded(id) when is_binary(id), do: mark_status(id, :discarded) + def mark_accepted(id) when is_binary(id), do: remove(id) + def mark_discarded(id) when is_binary(id), do: remove(id) defp mark_status(id, status) do case Repo.get(Proposal, id) do diff --git a/specs/mcp.allium b/specs/mcp.allium index b5ab05f..753b960 100644 --- a/specs/mcp.allium +++ b/specs/mcp.allium @@ -10,8 +10,6 @@ use "./template.allium" as template enum ProposalStatus { pending - accepted - discarded expired } @@ -49,8 +47,6 @@ entity Proposal { is_expired: expires_at <= now transitions status { - pending -> accepted - pending -> discarded pending -> expired } } @@ -342,7 +338,6 @@ rule AcceptProposal { media/UpdateMediaRequested(proposal.target_media, deserialize_media_changes(proposal.data)) if proposal.kind = propose_post_metadata: post/UpdatePostRequested(proposal.target_post, deserialize_post_changes(proposal.data)) - proposal.status = accepted not exists proposal } @@ -355,7 +350,6 @@ rule DiscardProposal { script/DeleteScriptRequested(proposal.proposed_script) if proposal.kind = propose_template: template/DeleteTemplateRequested(proposal.proposed_template) - proposal.status = discarded not exists proposal } diff --git a/test/bds/mcp_test.exs b/test/bds/mcp_test.exs index 55c8607..86e4e5d 100644 --- a/test/bds/mcp_test.exs +++ b/test/bds/mcp_test.exs @@ -180,7 +180,7 @@ defmodule BDS.MCPTest do assert_raise Ecto.NoResultsError, fn -> BDS.Posts.get_post!(draft_post_id) 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} = 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 {:ok, _accepted} = BDS.MCP.call_tool("accept_proposal", %{proposalId: accepted_id}) - - accepted_proposal = ProposalStore.get(accepted_id) - assert accepted_proposal.status == :accepted - assert accepted_proposal.entity_id == accepted_result["post"]["id"] + assert ProposalStore.get(accepted_id) == nil assert {:ok, discarded_result} = BDS.MCP.call_tool("draft_post", %{title: "Discard Me Later", content: "Body"}) discarded_id = discarded_result["proposal_id"] assert {:ok, _discarded} = BDS.MCP.call_tool("discard_proposal", %{proposalId: discarded_id}) - - discarded_proposal = ProposalStore.get(discarded_id) - assert discarded_proposal.status == :discarded + assert ProposalStore.get(discarded_id) == nil expired = ProposalStore.create("draft_post", %{"post_id" => "expired-post"},