Chapter 1: Introduction and Fundamental Principles
BEAST (Browser-based Embodied Agent Simulation and Testing) is a browser application that models individual adaptability. The goal is not to create a "working creature", but to formalize and implement the theory of adaptive systems as software code. The project acts as a tool for learning and debugging the architecture, where every detail of behavior follows strict, documented, and executable algorithms.
In the /demos/ folder there are demos that illustrate the implemented principles.
BEAST is positioned as the most adequate way to implement the theory of individual adaptability. Just as mathematics formalizes physical laws, BEAST serves as a formalization layer for adaptive systems theory. The code is not only a product: it is also a specification and a "working diagram" of how the system works, enabling testing, modification, and debugging of adaptive behavior.
Complex verbal interfaces (phrase recognition, symbols, tone of messages) are intentionally excluded. The focus stays on core layers: homeostasis, basic contexts, stimuli, reflexes, an evidence/condition tree, semantic and episodic memory, the consciousness (awareness) process, and automatisms.
BEAST is built around a hierarchical model: each new layer abstracts and makes behavior more capable than the layer below.
vitals (_1_Genetic_vitals).
It is a set of parameters (wounds, hunger, stress, etc.) whose values change dynamically (via shift)
every pulse. The vitals state determines the integral condition importance (IntergalConditionImportance)
and the base condition: Poor (1), Normal (2), Well (3) (BadNormWell).
_2_Genetic_basic_styles) - behavioral/emotional patterns
(Fear, Aggression, Play, Curiosity, Calm, etc.). Their combination forms an emotion (an EmotionId),
which together with the base state and the current stimulus defines the perception tree branch
(_7_perception_tree). That branch (branchId) is a key identifier of the current situation.
_3_perception).
The combination of active stimuli forms the final image (FinalImageId). In response,
genetic reflexes (_5_Genetic__reflexes) fire and trigger base actions (e.g. Cry, Eat).
These actions are registered as action images (an ActionImageId). The system can also
form conditional reflexes (_5_2_synonyms_reflexes) by linking the final image to an action
under specific context conditions.
_6_semantic_memory) stores how important (via meanImportance)
a stimulus is in given conditions (base state + emotion). This becomes the basis for evaluating usefulness or
harmfulness of stimuli.
_10_Episodic_memory) stores rules:
stimulus → action → effect (effect).
Each memory frame represents a chain condition (branch) → action → consequence
(a change in importance). If the operator provides a stimulus response during waiting, the resulting rule
is stored as a teacher rule (responseStimulusImageId).
ConsciousnessCycles) and an iterative dispatcher
(consciousness_dispatcher.js).
_8_Hippocampus) is the trigger. It selects the most relevant stimulus
among all active ones by evaluating novelty and importance. When it passes the threshold (OR_well_known),
it starts the consciousness process (stimuls_consciousness) and creates an episodic memory frame.
The fundamental unit of time in BEAST is the pulse (puls.js).
It is an artificial, discrete timeline used to run most system processes.
VitalsArr) time-varying organism state parameters.BasicContexts) behavioral/emotional modes activated by vitals outputs relative to the norm.FinalImageId) a unique identifier for each combination of active stimuli.BadNormWell) and emotion (EmotionId) describing the context for stimulus perception.perceptionNodeId) a full path across 6 levels
(base state → emotion → stimulus → ...), uniquely identifying the situation.ActionImageId) an abstraction of an action that can include one or more base actions.effect) quantitative evaluation of how the action changes integral condition importance.
Range: [-10, +10].branchId) that prescribes executing a given action image
when the branch becomes active. It has usefulness (usefulness).Chapter 2: Pulse Flow: From Stimulus to Action (Corrected Version)
The central loop is implemented in beast/puls.js via a recursive function sep_of_puls() that simulates a heartbeat.
Each pulse follows a fixed sequence of steps:
| # | Step | Description |
|---|---|---|
| 1 | Fix zero importance marker | Call getDiffImportance() to store current state in PrevDiffForEpisode for future episodic effect calculation. |
| 2 | Save to IndexedDB | Call runIndexedDBSavesForPulse(): all modules marked dirty persist their state. |
| 3 | Increment pulse counter | Cur_puls_val++, update UI and localStorage. |
| 4 | Episodic memory tick | EpisodicMemory_onPulse(): waiting counter, close frame by timeout. |
| 5 | Update vitals | performSensorOperations(): apply shifts, account for active stimuli. |
| 6 | Update contexts | getActiveBasicContexts(): compute BadVitalsValue, choose active BasicContexts, update BadNormWell. |
| 7 | Update UI | Update contexts, perception tree branch, and info panel (Info_updateFromPerceptionTree). |
| 8 | Start consciousness cycle (pulse 3) | If no main cycle exists, create an initial awareness cycle with stimulus 0. |
| 9 | Consciousness dispatcher | dispetchConsciousnessThinking(): a main-step plus background steps (every 5 pulses). |
| 10 | Reflexes | processGeneticReflexes(): deferred, conditional, genetic reflexes. |
| 11 | Reset UR gate | EpisodicMemory_skipConditionalReflexFormation = false. |
| 12 | Pulse visualization | Blink the green circle in the UI. |
OR (orientation_reflex.js) starts on any change in the set of active stimuli (operator click).
It is the central mechanism for deciding what the system should pay attention to.
FinalImageId,
and each active stimulus separately as candidates (each candidate corresponds to its own FinalImageId).relevance = novelty × importance.OR_HYSTERESIS = 0.5,
with modifiers such as doubling under an ImportantProblem condition and skipping hysteresis for stimuli from a priority chain.samplesCount < OR_well_known) before running the full episodic flow.branchId,
enter consciousness processing (stimuls_consciousness(context)), and create the episodic memory frame.
stimuls_consciousness (conscious_attention_channel.js) is a gate that decides whether the system
should interrupt the current thought with a new stimulus.
If there is an active main consciousness cycle and it is not marked expired, the new stimulus competes with it.
The base condition compares effective stimulus significance with the current thinkingImportance and an interrupt ratio
(INTERRUPT_THRESHOLD_ATTENTION_RATIO with a default of 1.5). Additional modifiers apply depending on
situation/theme mismatch, important problem state, priority chains, or the orientation reflex winner.
ConsciousnessBackgroundStack).Consciousness_createCycle with weight equal to stimulus significance.Consciousness_setMainCycle).unsolved_problem as the current stimulus, then call conscience_level_2(context) to determine a goal
with priority from survival to life-experience-driven goals. If an automatism is started, the cycle waits for operator feedback.expired and set awaitingAutomatismEpisodeFeedback = true,
storing the started automatism ID in EpisodicMemory_pendingFeedbackAutomatizmId.
Reflex processing (processGeneticReflexes) occurs on each pulse after the consciousness dispatcher.
This ensures that if awareness already started an automatism, a reflex for the same branch does not fire in the same pulse.
synonyms_tryRunReflexes()) after maturity checks (tryCount > 3) with stimulus and context match
A conditional reflex is created when synonyms_onGeneticActionFired is called (from startAction), provided:
'synonym' (no re-trigger of conditional reflex)noConditionalReflex flag is not setCore structure:
context: a string like "well:id1,id2" (base state + basic contexts)stimulIds: global stimulus IDs active except the one that triggered the responseactionId: an ID of a base actiontryCount: number of learned combinations (maturity threshold = 3)isReady: becomes true after tryCount > 3
startAction (genetic_reflexes_engine.js) is the final point where an action becomes a fact.
Typical effects:
Info_setMode('target'))ActionsImage_registerReaction(finalImageId, actionId))EpisodicMemory_setLastFrameActionFromActionId(actionId))synonyms_onGeneticActionFired(stimId, sourceType, actionId))Closing the episodic frame is the moment when feedback is obtained. It can happen in three ways:
| Trigger | When it happens | Result |
|---|---|---|
| Operator answer | Stimulus appears while waiting | closeLastFrame(stimulus_answer) closes the frame with the answer stimulus |
| Timeout | Waiting period ends | closeLastFrame(null) records 0/no action marker into the frame |
| New OR winner | OR is triggered while a frame is open | Close the previous frame with answer = new winner |
Inside closeLastFrame, the effect is computed (conceptually):
effect = clamp(diffAfter - diffBefore, -10, +10),
missing parts of the rule are filled with 0 markers, and the effect is passed to automatisms as usefulness updates.
It then notifies modules (gestalt, abstractions cloning, semantic/mental rules updates).
Chapter 3: Memory Models and Abstractions (Episode ? Knowledge)
| Level | Stored in | What it stores | Key |
|---|---|---|---|
| Semantic | SemanticMemory, SemanticMemoryIndex |
Stimulus significance (meanImportance) in conditions |
(well, emotionId, finalImageId) |
| Episodic | Episodes |
Rules: condition ? stimulus ? action ? effect ? operator response | Index in array (order matters) |
| Abstractions (clones) | AbstractPerceptionImages, AbstractActionImages |
Clones of hard images; their semanticStructure contains rules by branch+context |
(perceptionNodeId, stimulusImageId) or (perceptionNodeId, actionImageId) |
Semantic memory answers: How important is this stimulus in these circumstances?. A semantic record stores a running average of effect-based usefulness.
Semantic record (structure):
{
wellNormaBad: 1|2|3, // Poor/Normal/Well
emotionId: number, // Emotion (combination of basic contexts)
finalImageId: number,// Stimulus image ID
meanImportance: number, // average importance (smoothed effect)
samplesCount: number, // number of observations
lastImportance: number // last stored value
}
Semantic records are updated in two places:
addUsefulnessSample as clones average importance based on effect.Episodic memory stores frames describing what happened: in which conditions, what stimulus, what action, what effect, and how the operator responded.
Episodic frame (structure):
{
perceptionNodeId: number, // perception tree branch ID (conditions)
stimulusImageId: number, // stimulus image ID
situationId: number, // situation ID (from situations tree)
actionImageId: number|null, // action image ID (null until executed)
effect: number|null, // effect (-10..+10, null while open)
responseStimulusImageId: number|null, // operator answer image ID
diffBefore: number, // importance before activation (for effect calculation)
createdAt: number // timestamp
}
A frame has a lifecycle: created after OR threshold passes (waiting starts), filled with actions during startAction,
and closed by operator response, timeout, or a new OR winner.
Abstractions are clones of hard perception/action images. Unlike their hard prototypes, they can be freely combined
and exist as long-lived structures. Abstractions maintain a semanticStructure, a set of rules bound to specific
conditions (branch + situation).
| Type | Array | Key | Created when |
|---|---|---|---|
| Perception clone | AbstractPerceptionImages |
perceptionNodeId + stimulusImageId |
When the episodic frame closes (always) |
| Action clone | AbstractActionImages |
perceptionNodeId + actionImageId |
When the episodic frame closes (only if actionImageId > 0) |
teacher has highest priorityepisodic has medium priorityfantasy has lowest priority
Over abstractions, an additional mental layer is built:
symbols (abstractions) and mental automatisms (MentalAutomatizms).
Mental rules are created from episodic feedback and link the semantic abstraction to a mental action.
After operator feedback with positive effect, mental automatisms can be created from semanticStructure rules.
Chapter 4: Gestalts, Dominants, and Insights
A gestalt is a long-lived dominant: a record about an unsolved task. Unlike an episodic frame (what happened within one cycle), a gestalt lives across many cycles and can accumulate information about attempts to solve the problem.
goalImageId)automatismIds)status from 0 (new) to 3 (successfully closed)analogyPoolA gestalt has a FIFO resonance buffer containing signatures of closed episodic frames. Each signature is an experience snapshot that can later support analogy-based reasoning.
MAX_RESONANCE_BUFFER (48 entries)closeLastFrame)Insights link a gestalts goal-image representation to a concrete candidate solution (an automatism/analogy), changing how the system understands the problem.
status=3), a new record for the same goal is not created.status=4) are not deleted/cleaned.Chapter 5: Persistence and State Saving
| Strategy | Mechanism | Purpose | Frequency |
|---|---|---|---|
| Automatic | IndexedDB |
Save system state between page reloads | On every data change (dirty flags) |
| Manual | File System Access API |
Export/import a full memory snapshot | On operator command (Save/Load buttons) |
The wrapper and saver registration mechanism are implemented in sys/IndexedDB/indexeddb.js.
Each module registers a function via registerIndexedDBSaver.
runIndexedDBSavesForPulse().dirty flag).Modules use a combination of:
*Dirty flag (e.g. epDirty)last*SavedSig (a JSON signature of the last saved state)serializeState() to obtain a state snapshotIf the signature did not change, the system avoids writing again even if some metadata changed semantically.
In date/saving_ui.js there is a registry of BEAST.persistentModules.
Each module registers:
key (the JSON file key)serialize (returns the state for saving)apply (applies loaded state)Examples of registered modules:
| Key | Module | What is saved |
|---|---|---|
Cur_puls_val | puls.js | Pulse counter |
VitalsValues | vitals.js | Vitals values |
SemanticState | semantic_memory.js | All semantic memory |
ConditionalReflexesState | synonyms_reflexes.js | Conditional reflexes |
PerceptionTreeState | perception_tree.js | Perception tree |
ActionImagesState | actions_image.js | Action images |
EpisodesState | episodic_memory.js | Episodic frames (episodes) |
AutomatizmsState | automatizms.js | Automatisms |
GoalImagesState | goals.js | Goal images (life goals) |
Abstractions | abstract_images.js | Abstract clones |
Gestalts | gestalt.js | Gestalt state |
SituationsAndThemes | situations tree | Situations/themes |
End of manual.