// Package oracle implements an I Ching oracle state machine that steers // the organism's data ingestion strategy. Hexagram readings chain from one // to the next — the resulting hexagram becomes the next primary, with 2 bits // of PRNG entropy XOR'd onto each line to evolve the state. // // The oracle steers all data sources: self-ingest, web search, local repos, // Nostr relays, market feeds. The inner trigram determines what kind of // understanding is needed; the outer trigram determines what kind of source // to emphasize; the ADSR phase determines engagement depth; changing lines // identify which dimensions are in flux. package oracle import ( "git.mleku.dev/mleku/dendrite/pkg/ratio" "git.mleku.dev/mleku/dendrite/pkg/state" ) // LineState is the 2-bit state of a single hexagram line. // Encoding is chosen so XOR gives clean transitions: // // state ^ 00 = same state (no change) // state ^ 01 = flip polarity (yin↔yang, keep stability) // state ^ 10 = flip stability (young↔old, keep polarity) // state ^ 11 = flip both (full inversion) type LineState uint8 const ( YoungYin LineState = 0b00 // fixed broken — stable yin YoungYang LineState = 0b01 // fixed solid — stable yang OldYin LineState = 0b10 // changing broken — yin becoming yang OldYang LineState = 0b11 // changing solid — yang becoming yin ) // IsChanging returns true if the line is old (transitioning). func (ls LineState) IsChanging() bool { return ls&0b10 != 0 } // IsYang returns true if the current polarity is yang (solid). func (ls LineState) IsYang() bool { return ls&0b01 != 0 } // Stabilize returns the young (fixed) version of this line state, // preserving the post-change polarity. For a changing line, this is // the state after the change has been applied (old→young, polarity // already flipped in the resulting hexagram). func (ls LineState) Stabilize() LineState { return ls &^ 0b10 } // Reading is a single I Ching casting with full line detail. type Reading struct { // Primary is the 6-bit hexagram (inner=low3, outer=high3). Primary state.Hexagram `json:"primary"` // Lines holds the state of each of the 6 lines (index 0 = bottom). // Indices 0-2 are the inner trigram, 3-5 are the outer trigram. Lines [6]LineState `json:"lines"` // Resulting is the hexagram after all changing lines have been applied. // If no lines are changing, Resulting == Primary. Resulting state.Hexagram `json:"resulting"` // Generation is the dendrite generation when this reading was cast. Generation uint32 `json:"generation"` // Sequence is the ordinal position in the reading chain (0 = abiogenesis). Sequence uint32 `json:"sequence"` // Source identifies what data source prompted this reading // (e.g., "self", "forage", "nostr", "market"). Source string `json:"source"` // Directives are the strategy instructions derived from this reading. Directives []Directive `json:"directives"` // Absorbed is true when the EWMA stability signal fires, indicating // the organism has finished absorbing this reading's content. Absorbed bool `json:"absorbed"` // AbsorbedAtGen records the generation when stability was detected. AbsorbedAtGen uint32 `json:"absorbed_at_gen,omitempty"` // Metrics captures learning effectiveness for this reading. Metrics LearningMetrics `json:"metrics"` } // ChangingLines returns the indices (0-5) of all changing lines. func (r *Reading) ChangingLines() []int { var out []int for i, ls := range r.Lines { if ls.IsChanging() { out = append(out, i) } } return out } // InnerTrigram returns the primary reading's inner trigram. func (r *Reading) InnerTrigram() state.Trigram { return r.Primary.Inner() } // OuterTrigram returns the primary reading's outer trigram. func (r *Reading) OuterTrigram() state.Trigram { return r.Primary.Outer() } // LearningMetrics tracks how well the organism absorbed a reading. type LearningMetrics struct { ElementsFetched int64 `json:"elements_fetched"` ElementsBonded int64 `json:"elements_bonded"` BondRate ratio.Ratio `json:"bond_rate"` EWMAAtCast ratio.Ratio `json:"ewma_at_cast"` EWMAAtAbsorb ratio.Ratio `json:"ewma_at_absorb"` DirectivesRun int `json:"directives_run"` } // DirectiveType classifies the kind of strategy instruction. type DirectiveType uint8 const ( DirectiveSearch DirectiveType = iota // web search query DirectiveWalkWeight // file prioritization weights DirectiveEnzyme // enzyme selection/params DirectiveSubscribe // Nostr subscription filter DirectiveFocus // general focus directive ) // Directive is a strategy instruction derived from the reading. type Directive struct { Type DirectiveType `json:"type"` Query string `json:"query,omitempty"` Domain DomainType `json:"domain"` Intention IntentionType `json:"intention"` Style EngagementStyle `json:"style"` ChangingBit int `json:"changing_bit"` // -1 = primary, 0-5 = changing line Params map[string]string `json:"params,omitempty"` Completed bool `json:"completed"` }