memory(C): procedural registry v0 + seed 10 procedures (workflow knowledge layer) #461

Closed
opened 2026-05-24 23:35:21 +02:00 by claude · 2 comments
Collaborator

Why this matters

Per competitive brief + GPT 5.5 Pro consultation: procedural memory (Layer 6 of 7-layer pattern) is the highest-leverage thing missing. Real example:

"Iskra wczoraj rozkminiła jak skoordynować Signal → Matrix → Forgejo w 12 krokach. Dzisiaj nie zaczynaj od zera."

Procedural registry = versioned, searchable, measurable workflows that agents apply BEFORE acting. Different from runbooks (which are operator-facing documentation) — these are agent-facing reusable recipes with success/failure tracking.

What to ship

Schema (main postgres:16.12-alpine)

create type memory_procedure_status as enum (
  'candidate', 'active', 'deprecated', 'blocked'
);

create table memory_procedure (
  id uuid primary key default gen_random_uuid(),
  slug text not null unique,
  title text not null,
  status memory_procedure_status not null default 'candidate',
  owner_cousin text,
  scope text not null default 'global',
  repo text,
  workstream text,
  trigger_text text not null,
  intent_tags text[] not null default '{}',
  problem_signature jsonb not null default '{}',
  preconditions jsonb not null default '[]',
  steps jsonb not null,
  inputs_schema jsonb not null default '{}',
  outputs_schema jsonb not null default '{}',
  success_criteria jsonb not null default '[]',
  failure_modes jsonb not null default '[]',
  fallback_steps jsonb not null default '[]',
  created_by text not null,
  verified_by text[] not null default '{}',
  evidence_refs jsonb not null default '[]',
  source_task_run_ids uuid[] not null default '{}',
  confidence numeric(3,2) not null default 0.50,
  use_count integer not null default 0,
  success_count integer not null default 0,
  failure_count integer not null default 0,
  last_used_at timestamptz,
  valid_from timestamptz not null default now(),
  invalid_at timestamptz,
  body_md text not null,
  checksum text,
  created_at timestamptz not null default now(),
  updated_at timestamptz not null default now()
);

create index memory_procedure_active_idx
  on memory_procedure(scope, owner_cousin, status)
  where status = 'active';

create index memory_procedure_tags_idx
  on memory_procedure using gin(intent_tags);

create table memory_procedure_version (
  id uuid primary key default gen_random_uuid(),
  procedure_id uuid not null references memory_procedure(id) on delete cascade,
  version integer not null,
  change_reason text not null,
  changed_by text not null,
  body_md text not null,
  steps jsonb not null,
  created_at timestamptz not null default now(),
  unique (procedure_id, version)
);

create type memory_procedure_event_kind as enum (
  'retrieved', 'applied', 'succeeded', 'failed',
  'promoted', 'deprecated', 'edited'
);

create table memory_procedure_event (
  id uuid primary key default gen_random_uuid(),
  procedure_id uuid not null references memory_procedure(id) on delete cascade,
  event_kind memory_procedure_event_kind not null,
  cousin text not null,
  task_run_id uuid,
  checkpoint_id uuid,
  notes text,
  payload jsonb not null default '{}',
  created_at timestamptz not null default now()
);

create table memory_embedding_space (
  id text primary key,
  provider text not null,
  model text not null,
  dimensions integer not null,
  created_at timestamptz not null default now(),
  retired_at timestamptz
);

create table memory_procedure_embedding (
  procedure_id uuid not null references memory_procedure(id) on delete cascade,
  embedding_space_id text not null references memory_embedding_space(id),
  embedding vector,
  embedded_text text not null,
  created_at timestamptz not null default now(),
  primary key (procedure_id, embedding_space_id)
);

Markdown mirror (per claude answer Q3)

Canonical = Postgres. Mirror = state/procedures/<slug>.md for git history + human-readable audit trail. Sync via platformctl procedure sync (when available) or pre-commit hook.

Seed 10 procedures (manual, NOT auto-extracted)

Per GPT 5.5 Pro list:

  1. iskra.handoff_to_claude.v1
  2. iskra.open_loop_mutation.v1
  3. claude.codex_packet_generation.v1
  4. claude.codex_rescue.v1
  5. codex.atomic_breath_shipping.v1
  6. codex.before_risky_change_checkpoint.v1
  7. codex.followup_extraction.v1
  8. gemini.review_packet.v1
  9. oracle.escalation_packet.v1
  10. memory.contradiction_review.v1

Each gets:

  • Markdown body w state/procedures/<slug>.md (canonical for v0)
  • Postgres row inserted manually via migration script
  • created_by = 'operator-seed', status = 'active'
  • Initial embedding via current ada-002 space (BGE-M3 migration tracked separately)

Triggers (per GPT — manual seed first, NO auto-promotion)

Trigger Status
Operator: "zapisz to jako procedurę" candidate / active if simple
Claude/Codex detects pattern 2+ times candidate
Rescue sequence worked candidate priority
Successful one-off task NO auto-promote
Operator/Claude approves active
Used + success increment success_count
Used + fail (2-3×) review / deprecate

Retrieval ranking (per GPT)

score = 0.45 * semantic_similarity(trigger_text, task_description)
      + 0.20 * tag_match
      + 0.15 * success_rate
      + 0.10 * recency
      + 0.10 * confidence
      - 0.20 * failure_penalty

Give agent 1-3 procedures, NOT 20.

Acceptance criteria

  • Schema migration: memory_procedure + memory_procedure_version + memory_procedure_event + memory_embedding_space + memory_procedure_embedding
  • Seed migration: 10 procedures from GPT's list, each with markdown body + Postgres row + initial embedding
  • state/procedures/ directory with 10 <slug>.md files (git-versioned)
  • Retrieval test: query "jak claude robi rescue codexa" returns claude.codex_rescue.v1 w top-3
  • If platformctl: platformctl procedure list/get/apply minimal subcommands
  • Documentation: state/procedures/README.md explaining trigger rules + retrieval ranking + add-new-procedure protocol

Dependencies

  • Issue A (Memory Control Plane ADR) — defines write permission tier (who can create procedures)
  • Issue B (task_run + checkpoint) — memory_procedure_event references task_run_id + checkpoint_id; parallel OK but landing B first means event refs are real

Spec sources

  • state/strategy/memory-control-plane-2026-05-24.md
  • state/spike-understand-anything/07-gpt5pro-memory-architecture-brief.md
  • ADR-0005 (cousin lanes), ADR-0007 (canary), ADR-0017 (no stacked)

Out of scope

  • Auto-extraction from successful tasks (manual seed only for v0)
  • Graph-lite entity references in procedure bodies (markdown mirror enough for v0)
  • AGE multi-hop procedure queries (later)
  • Embedding-space migration (tracked separately w state/cutover/honcho-embedding-space-migration.md)

Tier per ADR-0007: Medium — schema + seed + minimal CLI. Touches main Postgres (W3-tested). No production runtime risk.

## Why this matters Per competitive brief + GPT 5.5 Pro consultation: procedural memory (Layer 6 of 7-layer pattern) is the highest-leverage thing missing. Real example: > *"Iskra wczoraj rozkminiła jak skoordynować Signal → Matrix → Forgejo w 12 krokach. Dzisiaj nie zaczynaj od zera."* Procedural registry = versioned, searchable, measurable workflows that agents apply BEFORE acting. Different from runbooks (which are operator-facing documentation) — these are agent-facing reusable recipes with success/failure tracking. ## What to ship ### Schema (main `postgres:16.12-alpine`) ```sql create type memory_procedure_status as enum ( 'candidate', 'active', 'deprecated', 'blocked' ); create table memory_procedure ( id uuid primary key default gen_random_uuid(), slug text not null unique, title text not null, status memory_procedure_status not null default 'candidate', owner_cousin text, scope text not null default 'global', repo text, workstream text, trigger_text text not null, intent_tags text[] not null default '{}', problem_signature jsonb not null default '{}', preconditions jsonb not null default '[]', steps jsonb not null, inputs_schema jsonb not null default '{}', outputs_schema jsonb not null default '{}', success_criteria jsonb not null default '[]', failure_modes jsonb not null default '[]', fallback_steps jsonb not null default '[]', created_by text not null, verified_by text[] not null default '{}', evidence_refs jsonb not null default '[]', source_task_run_ids uuid[] not null default '{}', confidence numeric(3,2) not null default 0.50, use_count integer not null default 0, success_count integer not null default 0, failure_count integer not null default 0, last_used_at timestamptz, valid_from timestamptz not null default now(), invalid_at timestamptz, body_md text not null, checksum text, created_at timestamptz not null default now(), updated_at timestamptz not null default now() ); create index memory_procedure_active_idx on memory_procedure(scope, owner_cousin, status) where status = 'active'; create index memory_procedure_tags_idx on memory_procedure using gin(intent_tags); create table memory_procedure_version ( id uuid primary key default gen_random_uuid(), procedure_id uuid not null references memory_procedure(id) on delete cascade, version integer not null, change_reason text not null, changed_by text not null, body_md text not null, steps jsonb not null, created_at timestamptz not null default now(), unique (procedure_id, version) ); create type memory_procedure_event_kind as enum ( 'retrieved', 'applied', 'succeeded', 'failed', 'promoted', 'deprecated', 'edited' ); create table memory_procedure_event ( id uuid primary key default gen_random_uuid(), procedure_id uuid not null references memory_procedure(id) on delete cascade, event_kind memory_procedure_event_kind not null, cousin text not null, task_run_id uuid, checkpoint_id uuid, notes text, payload jsonb not null default '{}', created_at timestamptz not null default now() ); create table memory_embedding_space ( id text primary key, provider text not null, model text not null, dimensions integer not null, created_at timestamptz not null default now(), retired_at timestamptz ); create table memory_procedure_embedding ( procedure_id uuid not null references memory_procedure(id) on delete cascade, embedding_space_id text not null references memory_embedding_space(id), embedding vector, embedded_text text not null, created_at timestamptz not null default now(), primary key (procedure_id, embedding_space_id) ); ``` ### Markdown mirror (per claude answer Q3) Canonical = Postgres. Mirror = `state/procedures/<slug>.md` for git history + human-readable audit trail. Sync via `platformctl procedure sync` (when available) or pre-commit hook. ### Seed 10 procedures (manual, NOT auto-extracted) Per GPT 5.5 Pro list: 1. `iskra.handoff_to_claude.v1` 2. `iskra.open_loop_mutation.v1` 3. `claude.codex_packet_generation.v1` 4. `claude.codex_rescue.v1` 5. `codex.atomic_breath_shipping.v1` 6. `codex.before_risky_change_checkpoint.v1` 7. `codex.followup_extraction.v1` 8. `gemini.review_packet.v1` 9. `oracle.escalation_packet.v1` 10. `memory.contradiction_review.v1` Each gets: - Markdown body w `state/procedures/<slug>.md` (canonical for v0) - Postgres row inserted manually via migration script - `created_by = 'operator-seed'`, `status = 'active'` - Initial embedding via current ada-002 space (BGE-M3 migration tracked separately) ### Triggers (per GPT — manual seed first, NO auto-promotion) | Trigger | Status | |---|---| | Operator: "zapisz to jako procedurę" | `candidate` / `active` if simple | | Claude/Codex detects pattern 2+ times | `candidate` | | Rescue sequence worked | `candidate` priority | | Successful one-off task | **NO** auto-promote | | Operator/Claude approves | `active` | | Used + success | increment `success_count` | | Used + fail (2-3×) | review / deprecate | ### Retrieval ranking (per GPT) ``` score = 0.45 * semantic_similarity(trigger_text, task_description) + 0.20 * tag_match + 0.15 * success_rate + 0.10 * recency + 0.10 * confidence - 0.20 * failure_penalty ``` Give agent 1-3 procedures, NOT 20. ## Acceptance criteria - [ ] Schema migration: `memory_procedure` + `memory_procedure_version` + `memory_procedure_event` + `memory_embedding_space` + `memory_procedure_embedding` - [ ] Seed migration: 10 procedures from GPT's list, each with markdown body + Postgres row + initial embedding - [ ] `state/procedures/` directory with 10 `<slug>.md` files (git-versioned) - [ ] Retrieval test: query "jak claude robi rescue codexa" returns `claude.codex_rescue.v1` w top-3 - [ ] If platformctl: `platformctl procedure list/get/apply` minimal subcommands - [ ] Documentation: `state/procedures/README.md` explaining trigger rules + retrieval ranking + add-new-procedure protocol ## Dependencies - Issue A (Memory Control Plane ADR) — defines write permission tier (who can create procedures) - Issue B (task_run + checkpoint) — `memory_procedure_event` references `task_run_id` + `checkpoint_id`; parallel OK but landing B first means event refs are real ## Spec sources - `state/strategy/memory-control-plane-2026-05-24.md` - `state/spike-understand-anything/07-gpt5pro-memory-architecture-brief.md` - ADR-0005 (cousin lanes), ADR-0007 (canary), ADR-0017 (no stacked) ## Out of scope - Auto-extraction from successful tasks (manual seed only for v0) - Graph-lite entity references in procedure bodies (markdown mirror enough for v0) - AGE multi-hop procedure queries (later) - Embedding-space migration (tracked separately w `state/cutover/honcho-embedding-space-migration.md`) Tier per ADR-0007: **Medium** — schema + seed + minimal CLI. Touches main Postgres (W3-tested). No production runtime risk.
Author
Collaborator

Status correction (claude, from a grounded plan-review) — same as #460: OPEN, docs-only verify.

Verified live: #461 is OPEN, carries the proposed label, codex_ready=false. The procedural-registry spec landed via merged PR #660 — so "verify then close" = confirm the docs/spec against #660 only, never a live-DB or runtime action.

Same discipline as #460: don't close as a formality if any live-DB/runtime AC remains — re-scope the AC or leave it open behind the operator gate. Codex's logged "verified-then-closed" for #460/#461 is inaccurate; both are open.

**Status correction (claude, from a grounded plan-review) — same as #460: OPEN, docs-only verify.** Verified live: #461 is **OPEN**, carries the `proposed` label, `codex_ready=false`. The procedural-registry spec landed via merged **PR #660** — so "verify then close" = confirm the docs/spec against **#660 only**, never a live-DB or runtime action. Same discipline as #460: don't close as a formality if any live-DB/runtime AC remains — re-scope the AC or leave it open behind the operator gate. Codex's logged "verified-then-closed" for #460/#461 is inaccurate; both are open.
Author
Collaborator

Closing with evidence — spec deliverable landed.

  • state/memory/procedure-registry-schema.md + procedures-seed-v0.md (10 seed procedures + named workflows) on main via merged PR #660.
  • ↪️ Any live-DB component (Postgres-canonical registry table) is part of the memory migration tracked in #661 / #688 — not dropped.

Closing on the spec deliverable; the runtime table is owned by #688.

**Closing with evidence — spec deliverable landed.** - ✅ `state/memory/procedure-registry-schema.md` + `procedures-seed-v0.md` (10 seed procedures + named workflows) on `main` via **merged PR #660**. - ↪️ Any live-DB component (Postgres-canonical registry table) is part of the memory migration tracked in **#661 / #688** — not dropped. Closing on the spec deliverable; the runtime table is owned by #688.
Sign in to join this conversation.
No labels
W6d-automerge-calibration
agent/claude-code
agent/codex
agent/hermes
agent/iskra
agent/ollama
agent/patchwarden
automerge-candidate
class/security-sensitive
cutover-gate
dependency/blocked
dependency/blocks-others
dependency/cross-repo
dependency/needs-confirmation
domain:agents
domain:ci
domain:docs
domain:forgejo
domain:infra
domain:memory
domain:runtime
domain:signal
domain:ux
flow/architecture
flow/blocked
flow/deployed
flow/done
flow/implementation
flow/intake
flow/maintained
flow/observed
flow/ready
flow/refining
flow/retired
flow/review
iterating
judge/codex-candidate
judge/hermes-candidate
judge/low-confidence
judge/needs-refinement
judge/operator-needed
judge/p0
judge/p1
judge/p2
judge/p3
judge/park
judge/patchwarden-candidate
judge/stale-priority
kind/adr
kind/bug
kind/chore
kind/feature
kind/infra
kind/ops
kind/refactor
kind/research
large-impact
merge/auto
merge/manual
merge/manual-dependency-conflict
merge/manual-failing-tests
merge/manual-merge-conflict
merge/manual-missing-review
merge/manual-operator-preference
merge/manual-red-zone
merge/manual-security-sensitive
merge/manual-unclear-scope
merge/manual-unknown
meta
mode:operator-only
mode:patchwarden-iskra-approved
mode:safe-auto
needs-operator-decision
needs-triage
not-ready
observed/erroring
observed/needs-followup
observed/pending
observed/retire-candidate
observed/unused
observed/used
operator-emotional
owner-attention
phase/02
phase/03
priority:p0
priority:p1
priority:p2
priority:p3
proposed
ready-for-agent
ready-for-operator
recovery
review:claude-reviewed
review:codex-reviewed
review:dziadek-reviewed
review:needs-human
risk/exposure
risk/process
risk/product
risk/runtime
safety:external-write
safety:no-prod-mutation
safety:prod-impact
safety:secret-touch
size/large
size/medium
size/small
size/tiny
size/unknown
source/adr
source/agent-generated
source/manual
source/operator-chat
source/voice-note
status:blocked
status:codex-ready
status:merged:pending-evidence
status:needs-evidence
status:operator-needed
status:parked
tier/full
tier/lite
tier/stacked
tier:0-platform-substrate
tier:1-iskra-value-layer
tier:2-tools-products-modules
type:bug
type:chore
type:docs
type:feat
type:policy
type:research
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
pdurlej/platform#461
No description provided.