From 71c82526d4df3e7b6450522c9fd49fc975b8f873 Mon Sep 17 00:00:00 2001 From: gravermistakes <250037217+gravermistakes@users.noreply.github.com> Date: Wed, 10 Jun 2026 02:27:33 +0000 Subject: [PATCH] Fix compile errors so Gen.03 core builds and tests pass Built locally with GNAT 13.3 (gprbuild, -gnat2022). All four test suites (soul/trust/cycle/config) pass and the MCP server responds correctly to initialize / tools/list / tools/call over stdio. Fixes: - soul-state.ads: move session storage types (Session_Key/Slot/Table) out of the protected definition's private part (only data components are legal there) into the package visible part. - soul-state.ads: drop pre/postconditions that call the object's own protected function Is_Initialized (illegal internal call in a contract); the guards already live in the bodies. - mafiabot_types.ads: pin Axis_Value'Small to 0.01 so 1.0 doesn't land one past the signed-8-bit base range (GNAT default 2**-7 small). - config_loader.ads: name the Entries array type (anonymous arrays may not be record components). - ada_medium.adb: qualify Mafiabot_Types.Ada_Medium (the package name shadows the Organ_Id literal); fix a malformed Bounded_Text aggregate. - soul-state.adb: fix Bounded_Text aggregate and the single-Character Footer. - soul-celtic_cross.adb / soul_tests.adb: 'use type' for Slot_State equality. - hermes_protocol.adb: qualify a single-char String aggregate to disambiguate the Append overloads. - Remove soul.adb (empty body for a spec that does not allow one). - Add .gitignore for build artifacts and the Alire-generated config project. --- mafiabot_core/.gitignore | 11 ++++ .../src/config_loader/config_loader.ads | 4 +- .../src/organs/ada_medium/ada_medium.adb | 7 +- .../src/organs/soul/soul-celtic_cross.adb | 2 + mafiabot_core/src/organs/soul/soul-state.adb | 4 +- mafiabot_core/src/organs/soul/soul-state.ads | 65 ++++++++++--------- mafiabot_core/src/organs/soul/soul.adb | 4 -- .../src/protocol/hermes_protocol.adb | 2 +- mafiabot_core/src/types/mafiabot_types.ads | 5 ++ mafiabot_core/tests/soul_tests.adb | 2 + 10 files changed, 65 insertions(+), 41 deletions(-) create mode 100644 mafiabot_core/.gitignore delete mode 100644 mafiabot_core/src/organs/soul/soul.adb diff --git a/mafiabot_core/.gitignore b/mafiabot_core/.gitignore new file mode 100644 index 0000000..033cda1 --- /dev/null +++ b/mafiabot_core/.gitignore @@ -0,0 +1,11 @@ +# Build artifacts +/bin/ +/obj/ + +# Alire-generated config (regenerated by `alr build` / CI) +/config/*_config.gpr +/config/*_config.ads +/config/*_config.h + +# Alire workspace +/alire/ diff --git a/mafiabot_core/src/config_loader/config_loader.ads b/mafiabot_core/src/config_loader/config_loader.ads index 2bc3646..c0b0bcd 100644 --- a/mafiabot_core/src/config_loader/config_loader.ads +++ b/mafiabot_core/src/config_loader/config_loader.ads @@ -24,8 +24,10 @@ is type Entry_Index is range 1 .. Max_Keys; subtype Entry_Count is Natural range 0 .. Max_Keys; + type Entry_Array is array (Entry_Index) of Config_Entry; + type Config_Store is record - Entries : array (Entry_Index) of Config_Entry := + Entries : Entry_Array := (others => (Key => (others => ' '), Key_Len => 0, Val => (others => ' '), Val_Len => 0)); Count : Entry_Count := 0; diff --git a/mafiabot_core/src/organs/ada_medium/ada_medium.adb b/mafiabot_core/src/organs/ada_medium/ada_medium.adb index 6668b52..5a64860 100644 --- a/mafiabot_core/src/organs/ada_medium/ada_medium.adb +++ b/mafiabot_core/src/organs/ada_medium/ada_medium.adb @@ -168,7 +168,7 @@ is Msg : Organ_Message; Ref : Soul.State.Session_Ref := Soul.State.No_Session; begin - Output := (others => ' ', Length => 0); + Output := (Data => (others => ' '), Length => 0); Inference_Orchestrator.Reset; -- Resolve the session for this (uid, channel, server). The cross and @@ -304,7 +304,10 @@ is -- Step 20: sendAda Inference_Orchestrator.Advance (Phase_Send_Ada, S); if S /= OK then Status := S; return; end if; - Msg := Make_Internal_Msg (Ada_Medium, Ada_Medium, Accum); + -- Qualify the Organ_Id literal: the simple name Ada_Medium binds to + -- this package, shadowing the enum value of the same name. + Msg := Make_Internal_Msg + (Mafiabot_Types.Ada_Medium, Mafiabot_Types.Ada_Medium, Accum); -- Step 21: Ada routes (trust boundary outbound screen) Inference_Orchestrator.Advance (Phase_Route, S); diff --git a/mafiabot_core/src/organs/soul/soul-celtic_cross.adb b/mafiabot_core/src/organs/soul/soul-celtic_cross.adb index 4fab3f6..46c5971 100644 --- a/mafiabot_core/src/organs/soul/soul-celtic_cross.adb +++ b/mafiabot_core/src/organs/soul/soul-celtic_cross.adb @@ -2,6 +2,8 @@ package body Soul.Celtic_Cross with SPARK_Mode => On is + use type Soul.Tarot.Slot_State; + procedure Draw_Spread (D : in out Soul.Tarot.Deck; Spread : out CC_Spread; diff --git a/mafiabot_core/src/organs/soul/soul-state.adb b/mafiabot_core/src/organs/soul/soul-state.adb index 6dce3f3..d269c8c 100644 --- a/mafiabot_core/src/organs/soul/soul-state.adb +++ b/mafiabot_core/src/organs/soul/soul-state.adb @@ -157,7 +157,7 @@ is Sun_L : constant String := "## Sun: "; Moon_L : constant String := ASCII.LF & "## Moon: "; Asc_L : constant String := ASCII.LF & "## Ascendant: "; - Footer : constant String := ASCII.LF; + Footer : constant String := (1 => ASCII.LF); Total : constant Natural := Header'Length @@ -166,7 +166,7 @@ is + Asc_L'Length + Asc_T.Length + Footer'Length; begin - Buffer := (others => ' ', Length => 0); + Buffer := (Data => (others => ' '), Length => 0); if Total > Max_Text_Length then Status := Error_Overflow; return; diff --git a/mafiabot_core/src/organs/soul/soul-state.ads b/mafiabot_core/src/organs/soul/soul-state.ads index e2406c0..bafc188 100644 --- a/mafiabot_core/src/organs/soul/soul-state.ads +++ b/mafiabot_core/src/organs/soul/soul-state.ads @@ -43,24 +43,50 @@ is Channel : String; Server : String) return Bounded_Text; + -- Per-session storage types. These live in the visible part because the + -- Soul_State protected object (declared below) holds a Session_Table as a + -- private component, and a protected definition may only contain data + -- components — not type or constant declarations. + Max_Key : constant := 192; + subtype Key_Length is Natural range 0 .. Max_Key; + type Session_Key is record + Data : String (1 .. Max_Key) := (others => ' '); + Length : Key_Length := 0; + end record; + + type Layer_Flags is array (Soul.Celtic_Cross.CC_Layer) of Boolean; + + type Session_Slot is record + In_Use : Boolean := False; + Key : Session_Key; + Deck : Soul.Tarot.Deck := Soul.Tarot.Full_Deck; + Spread : Soul.Celtic_Cross.CC_Spread := + Soul.Celtic_Cross.Empty_Spread; + Layer_Done : Layer_Flags := (others => False); + Output_Counter : Natural := 0; + end record; + + type Session_Table is array (Valid_Session) of Session_Slot; + protected Soul_State is pragma Priority (System.Priority'Last - 2); -- Set the three immutable personality anchors. Fails if called twice. + -- (A protected operation may not reference its own protected functions + -- in pre/postconditions, so the Is_Initialized guard lives in the body.) procedure Initialize_Big_Three (B3 : in Soul.Tarot.Big_Three; - Status : out Operation_Status) - with Post => (if Status = OK then Is_Initialized); + Status : out Operation_Status); -- Resolve a session by key, allocating a fresh slot (with its own -- Big-3-pruned deck) on first sight. Returns No_Session + - -- Error_Overflow if the table is full. + -- Error_Overflow if the table is full. Callers must Initialize_Big_Three + -- first; Open_Session uses the global Big-3 to prune each new deck. procedure Open_Session (Key : in Bounded_Text; Ref : out Session_Ref; Status : out Operation_Status) - with Pre => Is_Initialized, - Post => (if Status = OK then Ref in Valid_Session); + with Post => (if Status = OK then Ref in Valid_Session); -- Accrete one cognitive layer of THIS session's cross from its pool. -- Idempotent per layer: re-forming an already-formed layer is a no-op @@ -79,10 +105,10 @@ is procedure Note_Output (Ref : in Valid_Session); -- Serialise the global identity into Bounded_Text for SOUL.md. + -- Caller must Initialize_Big_Three first (guard lives in the body). procedure Generate_Soul_MD (Buffer : out Bounded_Text; - Status : out Operation_Status) - with Pre => Is_Initialized; + Status : out Operation_Status); function Is_Initialized return Boolean; function Get_Big_Three return Soul.Tarot.Big_Three; @@ -96,30 +122,7 @@ is private Big_3 : Soul.Tarot.Big_Three; Initialized : Boolean := False; - - Max_Key : constant := 192; - subtype Key_Length is Natural range 0 .. Max_Key; - type Session_Key is record - Data : String (1 .. Max_Key) := (others => ' '); - Length : Key_Length := 0; - end record; - - type Layer_Flags is - array (Soul.Celtic_Cross.CC_Layer) of Boolean; - - type Session_Slot is record - In_Use : Boolean := False; - Key : Session_Key; - Deck : Soul.Tarot.Deck := Soul.Tarot.Full_Deck; - Spread : Soul.Celtic_Cross.CC_Spread := - Soul.Celtic_Cross.Empty_Spread; - Layer_Done : Layer_Flags := (others => False); - Output_Counter : Natural := 0; - end record; - - type Session_Table is array (Valid_Session) of Session_Slot; - - Sessions : Session_Table; + Sessions : Session_Table; end Soul_State; end Soul.State; diff --git a/mafiabot_core/src/organs/soul/soul.adb b/mafiabot_core/src/organs/soul/soul.adb deleted file mode 100644 index 766b87d..0000000 --- a/mafiabot_core/src/organs/soul/soul.adb +++ /dev/null @@ -1,4 +0,0 @@ -package body Soul - with SPARK_Mode => On -is -end Soul; diff --git a/mafiabot_core/src/protocol/hermes_protocol.adb b/mafiabot_core/src/protocol/hermes_protocol.adb index e91cf03..077535f 100644 --- a/mafiabot_core/src/protocol/hermes_protocol.adb +++ b/mafiabot_core/src/protocol/hermes_protocol.adb @@ -39,7 +39,7 @@ is when ASCII.LF => Append (Buf, "\n"); when ASCII.CR => Append (Buf, "\r"); when ASCII.HT => Append (Buf, "\t"); - when others => Append (Buf, (1 => S (I))); + when others => Append (Buf, String'(1 => S (I))); end case; end loop; end Append_Escaped; diff --git a/mafiabot_core/src/types/mafiabot_types.ads b/mafiabot_core/src/types/mafiabot_types.ads index 8385dbc..b7c4302 100644 --- a/mafiabot_core/src/types/mafiabot_types.ads +++ b/mafiabot_core/src/types/mafiabot_types.ads @@ -38,6 +38,11 @@ is type Ratio_Value is delta 0.001 range 0.0 .. 1.0; type Cost_Value is delta 0.001 range 0.0 .. 1000.0; type Axis_Value is delta 0.01 range -1.0 .. 1.0; + -- Pin 'Small to 0.01 so the bounds are +/-100 units (fits a byte) rather + -- than GNAT's default 2**-7 small, which would place 1.0 at exactly 128 -- + -- one past a signed-8-bit base range and rejected as "high bound outside + -- type range". + for Axis_Value'Small use 0.01; -- Provenance tags — trust boundary uses these to block reclassification type Provenance_Tag is ( diff --git a/mafiabot_core/tests/soul_tests.adb b/mafiabot_core/tests/soul_tests.adb index c376177..ce4e145 100644 --- a/mafiabot_core/tests/soul_tests.adb +++ b/mafiabot_core/tests/soul_tests.adb @@ -4,6 +4,8 @@ with Soul.Tarot; with Soul.Celtic_Cross; with Mafiabot_Types; use Mafiabot_Types; +use type Soul.Tarot.Slot_State; + procedure Soul_Tests is Fails : Natural := 0;