Skip to content

Autonomous Learning Pipeline

symfonic-core agents can learn procedures from their own experience without compromising production safety. The pipeline has four stages with a human review gate before any learned skill influences agent behaviour.

The Pipeline

Episodic Memory  -->  SleepConsolidator  -->  Human Review  -->  Approved Skill
(observation)         Phase 12               (draft/approve)     (execution)

Stage 1: Observation (Episodic Memory)

Every chat turn writes a timestamped event to episodic memory. No special annotation is required. Action patterns emerge naturally:

  • "I ran EXPLAIN ANALYZE on the slow query"
  • "I checked CloudWatch for the 5xx spike"
  • "I deployed the hotfix via the rollback script"

These entries accumulate across conversations and become the raw material for Phase 12 promotion.

Stage 2: Promotion (SleepConsolidator Phase 12)

During deep sleep (POST /memory/consolidate), Phase 12 scans recent episodic entries for repeated action patterns. When a pattern crosses the frequency threshold within the recency window, it is extracted as a candidate procedural skill in draft status.

Pattern extraction uses a two-pass heuristic: 1. Explicit metadata["action_type"] field on the episodic entry (preferred). 2. Action-verb prefix regex matching: phrases like "I ran X", "Then I deployed Y", "I checked Z" are parsed into normalised action tokens.

Config knobs (on FrameworkConfig and forwarded to SleepConsolidator):

Field Default Effect
promotion_min_pattern_count 3 Minimum occurrences before a pattern is promoted
promotion_recency_days 30 Only consider episodic entries within this window
promotion_max_drafts_per_run 5 Cap on new drafts per consolidation run

SemanticMerge runs inside store_skill to dedup against existing procedural nodes (draft or approved). Repeated consolidation runs do not flood the review queue with near-duplicates (similarity threshold: 0.65).

Phase 12 is silently skipped when either episodic_layer or procedural_layer is absent from the SleepConsolidator — backward-compatible with deployments that do not use full HMS.

ConsolidationReport.draft_skills_promoted surfaces the per-run count.

Stage 3: Review (Draft/Approve Endpoints)

Draft skills are invisible to the agent until a human approves them. Review happens via three endpoints:

Method Path Action
GET /api/v1/procedures/drafts List all skills awaiting review
POST /api/v1/procedures/{id}/approve Approve — skill becomes active
POST /api/v1/procedures/{id}/reject Reject — skill is archived

These REST endpoints are the shipped review surface. The scaffold does not include a skills-review UI — its admin dashboard is metrics-only — so build your own "Pending Skills" view (or an ops script) against these endpoints. Every approve/reject emits an audit event (see below).

GET /api/v1/procedures defaults to approved-only. Pass ?status=draft, ?status=rejected, or ?status=all to change the filter.

Approve and reject operations emit audit events to GET /api/v1/admin/audit.

Stage 4: Execution (Approved Skills + CorePreferences)

Once approved, a skill becomes visible to the agent during hydration. The ProceduralLayer.query_skills() method returns only active (approved) skills by default.

On real-time register_skill operations (agent-initiated, not Phase 12), MetacognitiveMiddleware can gate the skill before it is stored. When FrameworkConfig.metacognition_enabled = True, the middleware evaluates the draft response against active CorePreferences and returns one of:

  • approve — skill stored as active (or draft if skill_auto_approve=False)
  • revise — skill stored as draft with revised content
  • refuse — skill rejected; not persisted

Configuration Reference

from symfonic.agent import FrameworkConfig

config = FrameworkConfig(
    # Real-time skill gating
    metacognition_enabled=True,         # default: False
    skill_auto_approve=False,           # default: True (back-compat)

    # Phase 12 offline promotion
    promotion_min_pattern_count=3,      # default: 3
    promotion_recency_days=30,          # default: 30
    promotion_max_drafts_per_run=5,     # default: 5
)

Setting skill_auto_approve=False forces every new skill (real-time or Phase 12) into draft state regardless of metacognition verdict. Recommended for production deployments.

Safety Rails

The pipeline has five independent safety mechanisms:

  1. Draft-by-default — Phase 12 always stores as draft. The agent never acts on a learned skill until a human approves it.
  2. MetacognitiveMiddleware — gates real-time register_skill ops against CorePreferences when metacognition_enabled=True.
  3. CorePreferences — domain-owned behavioural rules with priority 1-10. Higher-priority preferences can override or block lower-priority skill candidates.
  4. Audit trail — approve/reject/erase operations emit AuditLogEntry records to the registered AuditLogger. Query via GET /admin/audit.
  5. SemanticMerge dedup — prevents near-duplicate skills from accumulating across consolidation runs (cosine similarity threshold: 0.65).
  6. retract_node — an explicit user correction retires a wrong fact/skill (soft-retract: hidden from all reads immediately, pruned after a grace window). See below.

The correctness caveat

These rails constrain what gets promoted and acted on — they do not make the pipeline able to tell a correct memory from a wrong one on its own. Reinforcement is frequency-based: what recurs gets stronger. There is no outcome/reward signal, so a behavior the agent learned wrong and keeps repeating is reinforced, not flagged. The only things that retire a reinforced-but-wrong memory are external signals — the human review gate, an explicit correction (retract_node / SOUL user_manual_edit), or the metacognitive gate.

retract_node (reactive correction). When the user explicitly corrects or invalidates a stored memory, the model emits a retract_node op; the engine soft-retracts the target node (flag + audit trail), which drops it from every read path at once, and Deep Sleep's prune_retracted phase deletes it after a grace window. Full details in Consolidation & Deep Sleep § Retracting a false-positive memory. Closing the proactive case (self-detecting a wrong memory from bad outcomes) would require an outcome-feedback signal that does not exist yet.

Example: Store Copilot

A typical Store Copilot workflow through the pipeline:

Day 1-30 — Observation. The Store Copilot helps the owner run the shop. Each turn writes episodic entries: "I called sales_trend and reported the weekend beverage spike", "I flagged energy drinks trending up over 90 days", "I updated stock via update_stock after confirming the delivery with the owner".

Night consolidation — Promotion. Phase 12 detects that "reported sales with the window and figures cited" appears 6 times in 30 days. A candidate skill "Cite the window and revenue figures when answering a sales question" is created as a draft. ConsolidationReport.draft_skills_promoted = 1.

Human review — Approve. An operator lists the draft (GET /api/v1/procedures/drafts) and calls POST /api/v1/procedures/{id}/approve — from a review UI you build on these endpoints, or directly. The skill is now active, and an audit event is emitted.

Next question — Execution. During hydration, the approved skill surfaces in the procedural context. The agent follows the documented procedure. The Store Copilot's sales_trend / revenue_summary tools read the seeded demo dataset (or the store's real sales DB / read-only DSN once wired in demo_data.py).

CorePreferences guard. The store-starter plugin ships CorePreferences at priority 9-10: never register a product or change stock without confirming first, treat any connected store database as read-only (never write/update/delete against the owner's DB), and cite the numbers behind every sales claim. These take precedence over any learned skill that would violate them — a skill that proposed calling update_stock without confirmation, or writing to the external store DB, is blocked.

Cross-temporal recall via autonomous entity linking

The procedural-learning pipeline above is one of two autonomous learning paths that ship in 7.2. The second one — Roadmap Item 12, the EntityLinker phase — solves a separate cognitive problem: the agent needs to remember entities across time, not just patterns.

The cognitive story

Imagine a user who visits the same restaurant three times over six months. Each visit produces an episodic memory in plain natural language: "had dinner at Bistro Nico", "took the team to Bistro Nico for the launch celebration", "Bistro Nico's lasagna is still the best in town". A month later, the user passes the restaurant's logo on a T-shirt at the mall and says "that uniform reminds me of somewhere".

For the agent to make that leap — T-shirt at the mall → Bistro Nico → three past dinners — spreading activation needs edges to traverse between the three temporally-distant episodics. Episodic similarity alone is not enough: the three episodics share a name, not a phrasing.

Before 7.2, the only way to build those edges was either:

  • planting [semantic:Bistro Nico] markers in every episodic by hand (Phase 11 synthetic_links would then link them), or
  • calling semantic_layer.link() manually from a domain plugin every time the agent mentioned the entity.

The EntityLinker phase replaces both workarounds. It scans the natural language of recent episodics, extracts entity mentions, mints a canonical Entity:place:Bistro Nico semantic node, and emits MENTIONS edges from each episodic to the canonical node. The three dinners and the T-shirt sighting now share a graph neighbourhood; spreading activation crosses time.

Where it fits in the broader pipeline

Phase Promotes... Output
Phase 12 procedural_promotion recurring action patterns ("I ran EXPLAIN ANALYZE") draft procedural skills awaiting human review
Phase 12.5 entity_links recurring entity mentions ("Bistro Nico") semantic Entity:<kind>:<surface> nodes + MENTIONS edges

Both paths feed the same hydration pipeline at the next turn — the agent retrieves a richer, more cross-linked context.

Safety rails

Unlike procedural promotion, entity linking does not require human review. The output is data, not behaviour: a new Entity node and an edge between two existing nodes cannot make the agent do anything new. The risk surface is therefore narrower (false-positive entities pollute spreading activation, they do not cause autonomous action), and the mitigation is the confidence threshold + the entity_linker_min_mention_count floor.

For the configuration recipe — extractor trade-offs, tuning knobs, and the runnable demo — see Guide 09 — Consolidation & Deep Sleep.