File size: 19,878 Bytes
9425aed
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
-- ═══════════════════════════════════════════════════════════════════════════════
-- AhmadBotAgent.hs β€” Ahmad_bot as a SpacetimeAgent
-- haskell/AhmadBotAgent.hs
--
-- Connects AToKio (7-invariant bounded runtime) to the spacetime simulation.
-- Ahmad_bot IS an agent in the manifold. Every query it processes is an
-- observation of the region it currently occupies. Every insight it produces
-- moves it toward a new frame.
--
-- Architecture:
--   AToKioRuntime (invariant gates + WORM log)
--       ↕
--   AhmadBotAgent (SpacetimeAgent with BotAgentState payload)
--       ↕
--   ProductionEnvironment (physics manifold, 10-agent consensus)
--
-- The frame Ahmad is in determines how it reasons:
--   Quantum    β†’ probabilistic, branching, superposition of answers
--   Gravity    β†’ structured, convergent, pulling toward known attractors
--   Relativity β†’ time-aware, context-relative, observer-dependent
--   Wormhole   β†’ shortcut reasoning, distant concepts connected
--   Horizon    β†’ boundary detection, "this is the edge of what I can see"
--   Unknown    β†’ explore, gather data, no prior frame assumed
--
-- WORM-sealed at every step. 7 Agda invariants enforced on every bind.
--
-- Ahmad Ali Parr Β· SnapKitty Collective Β· Bel Esprit D'Accord Trust Β· 2026
-- ═══════════════════════════════════════════════════════════════════════════════

{-# LANGUAGE DeriveGeneric #-}
{-# LANGUAGE OverloadedStrings #-}

module AhmadBotAgent where

import Control.Concurrent (MVar, newMVar, readMVar, modifyMVar_, threadDelay)
import Control.Monad (forM_, when, unless)
import Data.List (intercalate, foldl')
import Data.Map.Strict (Map)
import qualified Data.Map.Strict as Map
import Data.Maybe (fromMaybe)
import Data.Time (getCurrentTime, formatTime, defaultTimeLocale)
import GHC.Generics (Generic)
import System.Exit (exitFailure)
import System.IO (hPutStrLn, stderr)

-- ── Import AToKio runtime ─────────────────────────────────────────────────────
import AToKio
  ( BotAgentState(..)
  , InvariantViolation(..)
  , AToKioRuntime(..)
  , checkAllInvariants
  , encodeWormEntry
  , initialState
  , initRuntime
  , enqueueTask
  , readWormLog
  )

-- ── Local re-declaration of SpacetimeAgent types ──────────────────────────────
-- (avoids circular imports while preserving the same structure)

data Frame
  = Unknown
  | Gravity
  | Relativity
  | Quantum
  | Wormhole
  | Horizon
  deriving (Show, Eq, Ord, Generic)

data BotGoal
  = ExploreFrame Frame          -- enter and understand a new frame
  | DeepInspect Frame           -- spend multiple steps in same frame
  | BridgeFrames Frame Frame    -- connect two frames via insight
  | ReachConsensus              -- agree with other agents on observation
  | HaltAtBoundary              -- stop β€” horizon detected
  deriving (Show, Eq, Generic)

-- ── AhmadBotAgent: the merged type ───────────────────────────────────────────

data AhmadBotAgent = AhmadBotAgent
  { abaId           :: String
  , abaPosition     :: (Double, Double)    -- position in manifold
  , abaFrame        :: Frame               -- current detected frame
  , abaGoal         :: BotGoal             -- what we're pursuing
  , abaBotState     :: BotAgentState       -- AToKio invariant state
  , abaObservations :: [BotObservation]    -- WORM-sealed history
  , abaConfidence   :: Double              -- [0..1] frame confidence
  , abaGeneration   :: Int                 -- how many frames visited
  } deriving (Show, Generic)

-- ── BotObservation: one merged observation from both systems ──────────────────

data BotObservation = BotObservation
  { boStep        :: Int
  , boAgentId     :: String
  , boPosition    :: (Double, Double)
  , boFrame       :: Frame
  , boQuery       :: String                -- what the bot was processing
  , boInsight     :: String                -- what it produced
  , boWormSeal    :: String                -- WORM entry hash
  , boInvariants  :: Bool                  -- all 7 passed?
  } deriving (Show, Generic)

-- ── Frame detection from position (same formula as ProductionSimulator) ───────

detectFrameFromPosition :: (Double, Double) -> Frame
detectFrameFromPosition (x, y) =
  let magnitude = sqrt (x*x + y*y)
  in if magnitude < 20.0      then Quantum
     else if magnitude < 50.0 then Gravity
     else if magnitude < 80.0 then Relativity
     else                          Wormhole

-- ── Movement: each frame has a pull direction ─────────────────────────────────

frameMovement :: Frame -> (Double, Double)
frameMovement Quantum    = ( 5.0,  5.0)   -- seek center
frameMovement Gravity    = (-5.0, -5.0)   -- seek gravity well
frameMovement Relativity = ( 8.0, -3.0)   -- lateral time dilation
frameMovement Wormhole   = (10.0,  0.0)   -- seek shortcut
frameMovement Horizon    = ( 0.0,  0.0)   -- halt
frameMovement Unknown    = ( 2.0,  2.0)   -- gentle exploration

applyMovement :: (Double, Double) -> (Double, Double) -> (Double, Double)
applyMovement (px, py) (dx, dy) =
  let stepSize = 1.5
      clamp v  = max (-120.0) (min 120.0 v)
  in (clamp (px + stepSize * dx), clamp (py + stepSize * dy))

-- ── Goal update: frame determines new goal ────────────────────────────────────

updateGoal :: AhmadBotAgent -> Frame -> BotGoal
updateGoal agent newFrame =
  case (abaGoal agent, newFrame) of
    (ExploreFrame f, f') | f == f' && abaConfidence agent > 0.8
                                   -> DeepInspect f
    (DeepInspect f,  f') | f /= f' -> BridgeFrames f f'
    (_,              Horizon)      -> HaltAtBoundary
    (_,              f)            -> ExploreFrame f

-- ── Confidence update ─────────────────────────────────────────────────────────

updateConfidence :: AhmadBotAgent -> Frame -> Double
updateConfidence agent newFrame =
  let delta = if newFrame == abaFrame agent then 0.1 else -0.05
  in max 0.0 (min 1.0 (abaConfidence agent + delta))

-- ── Query generation: frame determines what bot asks ──────────────────────────
-- This is Ahmad's reframing logic: what question do you ask
-- when you're in a Quantum region vs a Gravity region?

generateQuery :: Frame -> BotGoal -> Int -> String
generateQuery Quantum    _                step = "step " ++ show step ++ ": superposition β€” what are all possible answers?"
generateQuery Gravity    _                step = "step " ++ show step ++ ": convergence β€” what is the attractor?"
generateQuery Relativity _                step = "step " ++ show step ++ ": relative β€” from which observer frame?"
generateQuery Wormhole   (BridgeFrames f1 f2) _ = "bridge: how does " ++ show f1 ++ " connect to " ++ show f2 ++ "?"
generateQuery Wormhole   _                step = "step " ++ show step ++ ": shortcut β€” what connects distant concepts?"
generateQuery Horizon    _                _    = "boundary: what is the edge of what I can know?"
generateQuery Unknown    _                step = "step " ++ show step ++ ": unknown β€” what frame am I in?"

-- ── Insight generation: frame determines what bot produces ────────────────────

generateInsight :: Frame -> String -> Int -> String
generateInsight Quantum    query _ = "branch[" ++ query ++ "]: multiple valid answers coexist"
generateInsight Gravity    query _ = "converge[" ++ query ++ "]: single attractor found"
generateInsight Relativity query _ = "relative[" ++ query ++ "]: answer depends on observer"
generateInsight Wormhole   query _ = "bridge[" ++ query ++ "]: shortcut path established"
generateInsight Horizon    query _ = "boundary[" ++ query ++ "]: limit of knowable reached"
generateInsight Unknown    query _ = "explore[" ++ query ++ "]: gathering frame data"

-- ── AToKio invariant advance: tick BotAgentState forward ─────────────────────

advanceBotState :: BotAgentState -> Either InvariantViolation BotAgentState
advanceBotState s =
  let s' = s { step               = step s + 1
              , messageCount        = messageCount s + 1
              , validProtocolSteps  = validProtocolSteps s + 1
              , apiKeyUsage         = apiKeyUsage s + 1
              , errorStatus         = 0
              , stateValid          = True
              }
  in case checkAllInvariants s' (step s') of
       Left err -> Left err
       Right () -> Right s'

-- ── Single agent step ─────────────────────────────────────────────────────────

stepAhmadBot :: AhmadBotAgent -> IO (Either InvariantViolation AhmadBotAgent)
stepAhmadBot agent = do
  let k        = step (abaBotState agent)
      newPos   = applyMovement (abaPosition agent) (frameMovement (abaFrame agent))
      newFrame = detectFrameFromPosition newPos
      newConf  = updateConfidence agent newFrame
      newGoal  = updateGoal agent newFrame
      query    = generateQuery newFrame newGoal k
      insight  = generateInsight newFrame query k

  case advanceBotState (abaBotState agent) of
    Left err -> return (Left err)
    Right newBotState -> do
      -- WORM seal this observation
      now <- getCurrentTime
      let timestamp = formatTime defaultTimeLocale "%Y-%m-%d %H:%M:%S" now
          seal = intercalate "|"
            [ "AHMAD_BOT"
            , timestamp
            , "id="   ++ abaId agent
            , "step=" ++ show k
            , "pos="  ++ show newPos
            , "frame=" ++ show newFrame
            , "query=" ++ take 60 query
            ]
          obs = BotObservation
            { boStep       = k
            , boAgentId    = abaId agent
            , boPosition   = newPos
            , boFrame      = newFrame
            , boQuery      = query
            , boInsight    = insight
            , boWormSeal   = seal
            , boInvariants = True
            }
          newAgent = agent
            { abaPosition     = newPos
            , abaFrame        = newFrame
            , abaGoal         = newGoal
            , abaBotState     = newBotState
            , abaObservations = abaObservations agent ++ [obs]
            , abaConfidence   = newConf
            , abaGeneration   = abaGeneration agent + (if newFrame /= abaFrame agent then 1 else 0)
            }
      return (Right newAgent)

-- ── Multi-step run ────────────────────────────────────────────────────────────

runAhmadBot :: AhmadBotAgent -> Int -> IO (Either InvariantViolation AhmadBotAgent)
runAhmadBot agent 0 = return (Right agent)
runAhmadBot agent n = do
  result <- stepAhmadBot agent
  case result of
    Left err     -> return (Left err)
    Right agent' -> runAhmadBot agent' (n - 1)

-- ── Multi-bot consensus: Ahmad_bot swarm ─────────────────────────────────────
-- Multiple AhmadBotAgents run in parallel. Every 10 steps they vote
-- on what frame the manifold is "really" in at their shared region.

data BotConsensus = BotConsensus
  { bcRound         :: Int
  , bcAgreeingBots  :: Int
  , bcTotalBots     :: Int
  , bcWinningFrame  :: Frame
  , bcAgreementRate :: Double
  } deriving (Show, Generic)

consensusVote :: [AhmadBotAgent] -> Int -> BotConsensus
consensusVote agents roundNum =
  let frames     = map abaFrame agents
      frameCounts = foldl' (\m f -> Map.insertWith (+) f 1 m) Map.empty frames
      (winFrame, winCount) = Map.foldlWithKey'
        (\(bf, bc) f c -> if c > bc then (f, c) else (bf, bc))
        (Unknown, 0) frameCounts
      rate = fromIntegral winCount / fromIntegral (length agents)
  in BotConsensus
    { bcRound         = roundNum
    , bcAgreeingBots  = winCount
    , bcTotalBots     = length agents
    , bcWinningFrame  = winFrame
    , bcAgreementRate = rate
    }

-- ── Full simulation: N bots Γ— M steps ────────────────────────────────────────

data BotSimResult = BotSimResult
  { bsrAgents       :: [AhmadBotAgent]
  , bsrConsensusLog :: [BotConsensus]
  , bsrWormLog      :: [String]
  , bsrTotalObs     :: Int
  , bsrFrameVisits  :: Map Frame Int
  } deriving (Show, Generic)

runBotSimulation :: [AhmadBotAgent] -> Int -> IO BotSimResult
runBotSimulation initialAgents totalSteps = go initialAgents [] [] 0
  where
    go agents consensusLog wormLog step
      | step >= totalSteps = do
          let allObs      = concatMap abaObservations agents
              frameVisits = foldl' (\m obs -> Map.insertWith (+) (boFrame obs) 1 m)
                              Map.empty allObs
              allSeals    = map boWormSeal allObs
          return BotSimResult
            { bsrAgents       = agents
            , bsrConsensusLog = consensusLog
            , bsrWormLog      = allSeals
            , bsrTotalObs     = length allObs
            , bsrFrameVisits  = frameVisits
            }
      | otherwise = do
          -- Step all agents
          results <- mapM stepAhmadBot agents
          let (errors, stepped) = foldr
                (\r (es, ss) -> case r of
                  Left e  -> (e:es, ss)
                  Right a -> (es, a:ss))
                ([], []) results

          -- Halt if any invariant violated
          unless (null errors) $ do
            hPutStrLn stderr $ "INVARIANT HALT step=" ++ show step ++ ": " ++ show (head errors)
            exitFailure

          -- Consensus every 10 steps
          let newConsensus
                | step `mod` 10 == 0 =
                    let c = consensusVote stepped (step `div` 10)
                    in consensusLog ++ [c]
                | otherwise = consensusLog

          -- Progress every 50 steps
          when (step `mod` 50 == 0) $ do
            let frames = map abaFrame stepped
                frameStr = intercalate "," (map show frames)
            putStrLn $ "  step=" ++ show step
                     ++ " frames=[" ++ frameStr ++ "]"
                     ++ " obs=" ++ show (sum (map (length . abaObservations) stepped))

          go stepped newConsensus wormLog (step + 1)

-- ── Initial agent factory ─────────────────────────────────────────────────────

mkAhmadBotAgent :: String -> (Double, Double) -> AhmadBotAgent
mkAhmadBotAgent agentId startPos =
  let frame = detectFrameFromPosition startPos
  in AhmadBotAgent
    { abaId           = agentId
    , abaPosition     = startPos
    , abaFrame        = frame
    , abaGoal         = ExploreFrame frame
    , abaBotState     = initialState
    , abaObservations = []
    , abaConfidence   = 0.5
    , abaGeneration   = 0
    }

-- ── Report ────────────────────────────────────────────────────────────────────

printBotSimReport :: BotSimResult -> IO ()
printBotSimReport result = do
  putStrLn ""
  putStrLn "══════════════════════════════════════════════════════════════"
  putStrLn "   AHMAD_BOT SPACETIME SIMULATION REPORT"
  putStrLn "══════════════════════════════════════════════════════════════"
  putStrLn ""
  putStrLn $ "  Total observations:  " ++ show (bsrTotalObs result)
  putStrLn $ "  WORM seals:          " ++ show (length (bsrWormLog result))
  putStrLn $ "  Consensus rounds:    " ++ show (length (bsrConsensusLog result))
  putStrLn ""
  putStrLn "  Frame visit distribution:"
  forM_ (Map.toList (bsrFrameVisits result)) $ \(frame, count) ->
    putStrLn $ "    " ++ show frame ++ ": " ++ show count
  putStrLn ""
  putStrLn "  Per-agent summary:"
  forM_ (bsrAgents result) $ \agent ->
    putStrLn $ "    " ++ abaId agent
             ++ " | frame=" ++ show (abaFrame agent)
             ++ " | pos=" ++ show (abaPosition agent)
             ++ " | obs=" ++ show (length (abaObservations agent))
             ++ " | gen=" ++ show (abaGeneration agent)
             ++ " | conf=" ++ take 4 (show (abaConfidence agent))
  putStrLn ""
  putStrLn "  Last consensus round:"
  case reverse (bsrConsensusLog result) of
    [] -> putStrLn "    (none)"
    (c:_) -> do
      putStrLn $ "    round=" ++ show (bcRound c)
               ++ " | frame=" ++ show (bcWinningFrame c)
               ++ " | agreement=" ++ take 4 (show (bcAgreementRate c))
               ++ " (" ++ show (bcAgreeingBots c) ++ "/" ++ show (bcTotalBots c) ++ " bots)"
  putStrLn ""
  putStrLn "  Sample WORM seals (last 5):"
  mapM_ (\s -> putStrLn $ "    " ++ s) (take 5 (reverse (bsrWormLog result)))
  putStrLn ""
  putStrLn "══════════════════════════════════════════════════════════════"

-- ── Main ──────────────────────────────────────────────────────────────────────

main :: IO ()
main = do
  putStrLn "AhmadBotAgent v1.0 β€” Ahmad_bot in the Spacetime Manifold"
  putStrLn "7 Agda invariants enforced Β· WORM-sealed Β· Multi-bot consensus"
  putStrLn ""

  -- Spawn 5 Ahmad_bot agents at different positions in the manifold
  -- Each starts in a different physics frame
  let agents =
        [ mkAhmadBotAgent "ahmad-1" (  10.0,   5.0)   -- Quantum region (|pos| < 20)
        , mkAhmadBotAgent "ahmad-2" (  35.0,  15.0)   -- Gravity region
        , mkAhmadBotAgent "ahmad-3" (  60.0,  30.0)   -- Relativity region
        , mkAhmadBotAgent "ahmad-4" (  85.0,   5.0)   -- Wormhole region
        , mkAhmadBotAgent "ahmad-5" (   0.0,  10.0)   -- Deep Quantum (origin)
        ]

  putStrLn $ "Spawning " ++ show (length agents) ++ " Ahmad_bot agents..."
  putStrLn ""
  putStrLn "Initial frames:"
  forM_ agents $ \a ->
    putStrLn $ "  " ++ abaId a ++ " @ " ++ show (abaPosition a)
             ++ " β†’ " ++ show (abaFrame a)
  putStrLn ""

  -- Run 200 steps
  putStrLn "Running 200 steps..."
  result <- runBotSimulation agents 200

  -- Print report
  printBotSimReport result