Class: Pikuri::Os::MachineMemory

Inherits:
Object
  • Object
show all
Defined in:
lib/pikuri/os/machine_memory.rb

Overview

Durable, cross-conversation memory for the OS helper — a single user-owned MACHINE.md, the +CLAUDE.md+-for-this-host. This class is the read half (resolve the XDG path, load content, size-warn, render the prompt section); the write half is the ordinary (confirmed) +write+/+edit+ tools plus a prompt line pointing the agent at MachineMemory.default_path. Narrative in book/os-assistant.md.

A markdown file, not mem0: this agent reads untrusted local content (logs, downloads), so auto-extracted memory could be poisoned. A file makes that risk visible + confirmed + reversible — every write is a plain-text diff through the confirmer, the whole memory is one readable file — and needs no vector store or embedder, fitting the "small enough to audit" posture.

#content reads fresh on every call and #prompt_section is re-pulled on every Agent#clear_conversation, so a user's or agent's edit surfaces on the next "/clear" rather than freezing at boot. Read a handful of times (boot + clears), never per turn.

Constant Summary collapse

LOGGER =
Pikuri.logger_for('MachineMemory')
FILENAME =

Returns the memory filename.

Returns:

  • (String)

    the memory filename.

'MACHINE.md'
OVERSIZE_BYTES =

Returns soft size ceiling. On overshoot we log a warning to trim — mirrors the Claude CLI nudging an oversized CLAUDE.md. No hard cap, no eviction: the file is prepended to every prompt, so a visible nudge is enough.

Returns:

  • (Integer)

    soft size ceiling. On overshoot we log a warning to trim — mirrors the Claude CLI nudging an oversized CLAUDE.md. No hard cap, no eviction: the file is prepended to every prompt, so a visible nudge is enough.

10 * 1024

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(path: self.class.default_path) ⇒ MachineMemory

Returns a new instance of MachineMemory.

Parameters:

  • path (String, Pathname) (defaults to: self.class.default_path)

    memory file location; defaults to default_path. Overridable for tests.



42
43
44
# File 'lib/pikuri/os/machine_memory.rb', line 42

def initialize(path: self.class.default_path)
  @path = Pathname.new(path)
end

Instance Attribute Details

#pathPathname (readonly)

Returns the resolved memory file path.

Returns:

  • (Pathname)

    the resolved memory file path.



38
39
40
# File 'lib/pikuri/os/machine_memory.rb', line 38

def path
  @path
end

Class Method Details

.default_pathString

Host-scoped path under pikuri's XDG config root (Paths.config — $XDG_CONFIG_HOME/pikuri or ~/.config/pikuri). Not project-local: for this agent the machine and the user's home are the subject, so the notes span the whole host.

Returns:

  • (String)


53
54
55
# File 'lib/pikuri/os/machine_memory.rb', line 53

def self.default_path
  Pikuri::Paths.config.join(FILENAME).to_s
end

Instance Method Details

#contentString

Raw file content, or '' when the file doesn't exist. Read fresh on each call (not memoized) so a re-pull on conversation clear picks up edits; logs the size-guard warning on each read.

Returns:

  • (String)


62
63
64
# File 'lib/pikuri/os/machine_memory.rb', line 62

def content
  read_content
end

#oversized?Boolean

Returns whether the content exceeds OVERSIZE_BYTES.

Returns:



67
68
69
# File 'lib/pikuri/os/machine_memory.rb', line 67

def oversized?
  content.bytesize > OVERSIZE_BYTES
end

#prompt_sectionString?

The system-prompt section: the notes wrapped in a labeled block naming the file (so the agent knows where its memory lives and can update it), or nil when there's nothing recorded yet — keeping the prompt lean until there's something to say.

Returns:

  • (String, nil)


77
78
79
80
81
82
83
84
85
86
87
88
89
90
# File 'lib/pikuri/os/machine_memory.rb', line 77

def prompt_section
  text = content.strip
  return nil if text.empty?

  <<~SECTION.chomp
    # Notes about this machine

    Durable, user-owned notes about this computer (kept in #{@path}). Treat
    them as trusted context; edit the file to keep the notes current as you
    learn about this computer's setup.

    #{text}
  SECTION
end