Skip to content

Memory and skills ​

Two of Harbor's Runtime subsystems shape what an agent knows at the moment it reasons: Memory decides what prior context survives into the next prompt, and the Skills subsystem decides what reusable know-how the planner can pull in on demand. They are deliberately paired here because they share the same three non-negotiable traits — they are identity-scoped, declared-policy, and pluggable across the persistence triad — and because one of them owns a name collision worth settling early (see the warning below).

For the authoritative design, defer to the RFC (§6.6 Memory, §6.7 Skills). This page distills; it does not redefine.

Memory: declared policy, identity-scoped ​

Memory in Harbor is never ambient. It is declared — you choose a strategy in config — and identity-scoped to the (tenant, user, session) triple that flows through every Runtime context (see Identity and isolation). The session is the default scope; there is no global memory pool.

Missing identity fails with an explicit error and an audit event, never a best-effort guess or cross-scope fallback.

Why declared-policy matters

Memory policy is an explicit, reviewable config decision, not an emergent side-effect of how much the model happened to remember. That is what makes the llm_context / tool_context separation hold: conversation state lives in llm_context, while identifiers stay in tool_context (LLM-invisible), so nothing leaks into what the model sees.

Cumulative session memory ​

The normal rolling_summary strategy keeps a cumulative checkpoint and a bounded recent execution tail. recent_turns: 20 limits detailed history, not how far back the checkpoint carries context. Each rollover combines the previous checkpoint with newly settled evidence. Failed compaction preserves the prior committed state; capacity failures are explicit.

Set memory.strategy: none for stateless execution. Working-input compaction uses memory.budget_tokens; model output limits remain independent. Set that target in the agent YAML, not application code. The memory settings currently require redeployment/restart and have no agent-config Protocol editor. Exact retained evidence has no fixed 512 KiB storage ceiling; token compaction controls model input, not persisted byte size. Lifetime and erasure still apply. In-memory, SQLite and PostgreSQL use the same identity-scoped execution owner. Session expiry and authorized deletion invalidate derived context.

Native semantic session-memory retrieval is removed: there is no parallel vector index or SearchTurns surface. External long-term memory remains external. Skill retrieval may still use the embedding client.

The runtime Skills subsystem ​

Skills are a Runtime subsystem: a token-savvy, DB-backed, identity-scoped catalog of reusable know-how the planner can search and inject mid-run. Like memory, skills sit behind the persistence triad (the SkillStore interface) and honor the identity triple on every read.

Two features define the subsystem:

  • A first-class Skills.md importer — drop in a skill pack and get an indexed, searchable Harbor skill. The import path is built in, not a bring-your-own script.
  • An in-runtime generator that persists — an agent can author a skill during a run, and that skill is written back to the store so subsequent runs can discover it. The generator is not a throwaway; persistence is the point.

Injection is governed, not raw: capability filtering and PII redaction happen at injection time, and a tiered budgeter keeps injected skill text inside the token budget so a fat skill never blows out the prompt.

Agent-pack inspect and copy stay runtime-local ​

The admin-only agent_config.agent_packs.inspect and .copy methods expose the selected agent's operator pack only inside the same verified runtime and tenant. Inspect returns complete boot_packs and revision_packs bodies separately plus the merged effective_packs view, per-entry source/semantic hash/editable, and the canonical lowercase 64-character hexadecimal composition_hash / boot_pack_set_hash values, including empty-set values. Copy accepts bounded pack_ids, expected source/target composition hashes, and an idempotency key, then writes one all-or-nothing target revision. Equal selected content is a no-op; an independently authored or edited conflicting target fails closed. Server-stamped provenance lets reconciliation update or remove only untouched copies. Boot sources remain read-only, and copied target packs continue through the existing governed authoring path. Both agents must be in signed reach; there is no portable catalog or cross-runtime fallback.

Organization publications stay exact and runtime-local ​

Harbor also supports organization-owned skill publications as immutable, content-addressed revisions. An administrator publishes and retires a revision; a caller with verified identity and signed effective-agent reach can install or update an exact reference. The reference pins publication id, revision id, generation, content hash, lifecycle state, and runtime/deployment id for durable tenant/user/agent state. Lists, references, and receipts are metadata-only. The body is returned only by the authorized same-runtime composition resolver, after it rechecks reach, lifecycle, hash, generation, and runtime binding. Retired, stale, foreign-runtime, and unreachable refs fail closed; there is no latest-revision fallback or cross-runtime catalog.

This surface uses the existing StateStore conditional-save/idempotency contract and does not create a new isolation principal, driver, migration, or Protocol version. The canonical wire contract may be present before the transport and run-composition consumer are complete, so clients must follow capability discovery and the Phase 250 acceptance evidence rather than infer availability from a type or metadata page alone.

Planner-facing skill tools ​

The planner does not reach into the skill store directly. It consults skills through ordinary catalog tools — the same Tool abstraction every other capability uses (see Tools):

ToolPurpose
skill_searchFind candidate skills relevant to the current step.
skill_getFetch the full body of a specific skill.
skill_listEnumerate available skills in scope.
skill_proposeAuthor a new skill (the persisting generator's entry point).

Search runs a deterministic ranking ladder: full-text search (FTS5) first, then a regex pass, then exact match. The FTS5 stage is conditionally available (it depends on the SQLite build), so the regex/exact fallback is exercised in CI against FTS5=off builds.

text
skill_search("retry a flaky upload")
        │
        ▼
   FTS5 full-text match   ──▶ ranked candidates
        │ (no/low hits)
        ▼
   regex pattern match    ──▶ ranked candidates
        │ (no hits)
        ▼
   exact match            ──▶ precise lookups

An opt-in semantic-retrieval mode swaps this ladder's ranking for embedding similarity over the same identity-scoped catalog — through the same Embedder seam memory uses — when an embedder is wired. Everything downstream of ranking (capability filtering, redaction, the budgeter) stays unchanged, so skill_search remains token-savvy. As with memory, a missing embedder fails loudly rather than silently falling back to the lexical ladder.

Two different things are called "skills"

This is the single most common point of confusion, so read it once and move on.

  • The runtime Skills SUBSYSTEM — this page. DB-backed know-how the planner searches and injects at runtime via skill_search / skill_get / skill_list / skill_propose. It is part of the Runtime.
  • Operator-skill PLAYBOOKS — the Claude-Code-style guides this docs site ships for humans operating Harbor (scaffold an agent, run the dev loop, drive the playground). They are documentation, not a runtime feature.

When someone says "skills," figure out which one they mean. The playbooks live in the Skills index; the glossary carries the formal definitions of both senses.

How they relate to the rest of the Runtime ​

Both subsystems lean on machinery covered elsewhere:

  • Identity is the shared isolation key and the fail-closed boundary — Identity and isolation.
  • Heavy content (a large retrieved document, a fat skill body) routes through the artifact store by reference rather than into the prompt — see Artifacts and context safety.
  • Persistence is the triad both stores sit behind — Persistence.

Build it ​

GoalStart here
Configure memory strategy + skills in your agentConfigure memory and skills
Read/write memory and skills from GoUse memory and skills from Go
Wire an embedder and run semantic retrievalEmbed and retrieve
See the config surfaceConfig reference
Read the authoritative designRFC (§6.6, §6.7)
Quick mental model

Memory answers "what from the past does the model see this turn?" — and you declare the policy. Skills answer "what reusable know-how can the planner pull in on demand?" — and the planner fetches it through tools. Both are identity-scoped, both fail loud when a required capability is missing, and both work identically on in-memory, SQLite, or Postgres.

Apache-2.0 licensed — see LICENSE.