akm docs

AKM Format-Neutral Bundle Workspace Architecture Specification

Status: Amended for implementation (reconciled)
Specification version: 0.5 Date: 2026-07-14 (v0.2 amended 2026-07-13 after the maintainer reconciliation and the design/plan review pass; v0.3 amended 2026-07-14 after the final scope decisions)
Target: Next major AKM architecture
Reference implementation reviewed: itlackey/akm at ddc0a1b417efc820ad73d76bfcbef65c9f87b243
Related proposal: AKM PR #718

This specification supersedes the prior directions that treated OKF as an AKM asset type, made OKF the hidden universal AKM file schema, introduced a semantic-view registry, or preserved the current asset system behind a permanent legacy adapter.

Amendment record. (v0.2, 2026-07-13) The maintainer reconciliation (DEV-1..DEV-7, §4) and the review pass applied in place: the ref grammar is [<bundle>//]<concept-id>[#fragment] (§7.8, §11); the normalized field is the open type (§14.1), which MAY drive presentation/ranking/filtering and MUST NOT drive execution, identity, or storage; adapter capabilities are optional methods on one interface (§12); nested component roots have a subtraction rule (§9.3); index persistence is a diff, not truncate-and-rewrite (§14.2). (v0.3, 2026-07-14 — final scope decisions, deviation §4.3a–3c) This document remains the target architecture; release staging is explicit where target and 0.9.0 diverge: the persisted Binding record, export digests, rebind-on-update, and the bind CLI are Tier B, deferred indefinitely (staging note at §18); the entire memory lifecycle (§25) is deferred behind the claim extractor + benchmark (staging note at §25); and the v0.2 trust-clamp additions (trusted labeling in the read path, action clamping, catch-all sensitive-content refusal) are withdrawn — new trust/approval machinery is rejected as false-confidence machinery; only protections that exist in code today survive the port (env/secret redaction, the origin-scoped dangerous-key rule). No section of this document is superseded by a banner elsewhere; this text is current. (v0.4, 2026-07-21 — owner ruling) The akm.bundle.yaml package manifest is removed entirely (it was never implemented and should never have been approved), and sub-mount / multi-component registration is replaced by adapter-owned file processing: a bundle maps to exactly one component = one adapter, and that component's adapter processes the files and subdirectories of its bundle as it sees fit — the core provides the walk and the persistence, the adapter's recognize claims or abstains per file. Consequences applied in place: §9.2 multi-component packages and §9.3 nested-root subtraction no longer apply to a single-adapter bundle; manifest-declared exports: are removed (exports with independent standing, if any, are unaffected); §14.2's scan flow is the core walk × adapter.recognize with per-directory incremental diff persist. Adapter dispatch is live in the indexer (unknown adapter id ⇒ component skipped with a warning). (v0.5, 2026-08-18 — owner ruling) Native agent-tool directories are bundles whose adapters translate native agents and commands at runtime; AKM does not synchronize, copy, or write those native assets. Agent/command/engine/model resolution, command execution, model maps, and tool-selection semantics are now governed by Agent, Command, Engine, and Model Resolution. Installed asset metadata participates in the normal nearest-wins cascade; machine/user authorization, not asset provenance, is the separate enforcement boundary. Sections 22, 28, and 29 are amended accordingly.


1. Normative language

The key words MUST, MUST NOT, REQUIRED, SHOULD, SHOULD NOT, and MAY are to be interpreted as described by RFC 2119 and RFC 8174 when they appear in uppercase.


2. Abstract

AKM is a format-neutral workspace for installing, indexing, searching, reading, validating, improving, distributing, and safely executing files contained in bundles.

AKM does not define one universal format for knowledge, memories, skills, agents, workflows, tasks, environment definitions, or scripts. Native file semantics belong to bundle adapters. AKM owns the cross-format operating capabilities around those files:

source materialization
+ bundle installation
+ local indexing and search
+ workspace bindings
+ execution policy
+ proposals and transactions
+ evidence-driven improvement
+ bounded memory lifecycle
+ audit and recovery

The core architecture is:

Workspace
├── installed bundles
│   ├── adapter-governed components
│   └── portable runtime exports
├── bindings and enabled schedules
├── local search index
├── durable operational state
├── engines and runtime services
├── evidence and memory lifecycle state
└── proposals and verified file changes

OKF is the first-class least-common-denominator for Markdown concepts through the built-in okf adapter. AKM-authored Markdown is an OKF-compatible superset, while non-Markdown serialization and all specialized capabilities remain adapter-owned. The shared IndexDocument is an additive cross-format projection whose basic Markdown fields align with OKF; it is not the database's on-disk document format. See okf-support.md.


3. Scope

This specification defines:


4. Goals

The architecture MUST:

  1. Make AKM independent of any single content format.
  2. Preserve native compatibility with OKF, LLM Wiki, Claude, OpenCode, Agent Skills, website snapshots, AKM workflows, AKM tasks, dotenv-style environments, scripts, and future standards.
  3. Reduce the core mental model and eliminate closed asset-type dispatch.
  4. Preserve or improve current search quality and latency.
  5. Keep ordinary file reads and file writes transparent and debuggable.
  6. Make installation distinct from execution authority.
  7. Allow reusable workflows, tasks, environment definitions, agents, skills, commands, and scripts to be distributed in bundles.
  8. Centralize native conventions, authoring rules, validation, and serialization in adapters.
  9. Make semantic changes proposal-first and objectively evaluated where possible.
  10. Bound memory growth without making age, low use, or storage pressure sufficient evidence for deletion.
  11. Preserve crash recovery, exact-path Git commits, reversible changes, and durable audit history.
  12. Permit an aggressive implementation replacement without requiring a separate greenfield product.

5. Non-goals

AKM MUST NOT:


6. Architectural principles

6.1 Files remain primary

Native files are the portable content source of truth. The index, summaries, embeddings, graph data, bindings, usage scores, proposals, and execution records are derived or operational workspace state.

6.2 Adapters own format semantics

Adapters own:

6.3 Core owns cross-format operations

The workspace core owns:

6.4 Installation is not activation

A bundle can be installed and searchable without being executable. Runtime use requires a workspace binding or an explicit per-invocation approval allowed by workspace policy.

6.5 Complexity carries a burden of proof

Any ranking feature, graph processor, self-refinement stage, evaluator loop, or improvement selector that adds significant complexity MUST demonstrate measurable value over a simpler baseline.

6.6 One stable snapshot per semantic run

A semantic improvement run MUST generate all candidates against one stable file/index snapshot. Accepted output MUST NOT become new semantic input during the same run.


7. Terminology

7.1 Workspace

The local AKM operating environment. It owns configuration, installed-bundle state, indexes, bindings, engines, proposals, evidence, schedules, logs, archives, audit history, and runtime policy.

A workspace is not a content bundle and is not a directory that must contain all user files.

7.2 Bundle package

A distribution and versioning unit registered with one native component root. A package may be a Git repository, archive, npm package, filesystem directory, website snapshot, or subdirectory of a larger repository; separately governed roots are registered as separate bundles.

7.3 Bundle installation

A local materialized revision of a bundle package, registered under a stable workspace bundle ID.

7.4 Component

A bundle installation's configured root, interpreted by exactly one adapter.

Examples of separate bundle component roots:

knowledge/  -> OKF adapter
wiki/       -> LLM Wiki adapter
.claude/    -> Claude adapter
workflows/  -> workflow adapter
tasks/      -> task adapter
env/        -> environment adapter
skills/     -> Agent Skills adapter

Every bundle has exactly one component in 0.9.0.

7.5 Materializer

The source-specific implementation that gets bytes onto the local filesystem and optionally refreshes them. Examples include filesystem, Git, archive/npm, and website materializers.

Materializers do not parse native content semantics.

7.6 Adapter

The implementation that understands a component's native files and rules.

7.7 Item

A native logical object discovered by an adapter and represented in the workspace index. An item normally resolves to one primary file but MAY reference supporting files.

7.8 Item ref

The workspace-unique, path-like identity of an indexed item (reconciled grammar, DEV-2):

ref        := [ bundle "//" ] conceptId [ "#" fragment ]
bundle     := slug            # workspace bundle name; no "/", ":", ".", or "#"
conceptId  := adapter-canonical path within the bundle;
              MAY contain "/"; MUST NOT contain "#"; opaque to the core below the "//"

Example:

team-catalog//tables/orders
release-automation//workflows/release
project-claude//skills/pdf-processing
knowledge/http-caching            # short form; CLI input sugar only (§11.1)

The component is not a ref segment. It is provenance supplied by the bundle's single configured component; the adapter derives each conceptId relative to that component root. Reclassifying the component does not change a ref; moving or renaming the native item does (§11.2).

7.9 Export

A portable runtime capability exposed by an adapter from a bundle item. Supported export kinds are initially:

workflow
task
environment
agent
command
skill
script

Export kind is an activation contract, not a storage type and not part of item identity.

7.10 Binding

A workspace-owned approval and configuration record connecting an installed export to local execution policy.

7.11 Proposal

A durable, reviewable set of native file changes with evidence, before-hash preconditions, evaluation results, and lifecycle status.

7.12 Memory-capable component

A component whose adapter implements the memory lifecycle facet and can inventory, render, validate, and retire native memory records.


8. System responsibility boundaries

8.1 Materializer responsibilities

A materializer MUST:

A materializer MAY support refresh, pull, checkout, cache expiration, conditional HTTP requests, or local writable checkouts.

8.2 Adapter responsibilities

An adapter MUST:

An adapter MAY implement authoring, export, or memory lifecycle facets.

8.3 Core responsibilities

The core MUST:

8.4 Runtime handler responsibilities

Runtime handlers or harnesses MUST:


9. Bundle composition

9.1 Single-component bundles

Every bundle is single-component (§9.2, v0.4). Workspace configuration mounts a root directly:

bundles:
  personal:
    path: ~/knowledge
    components:
      knowledge:
        root: .
        adapter: okf
        writable: true

defaultBundle: personal

9.2 One bundle = one component = one adapter

(Amended v0.4, 2026-07-21 — owner ruling: the akm.bundle.yaml manifest and multi-component packaging are removed.)

A bundle maps to exactly one component, owned by exactly one adapter. There is no akm.bundle.yaml package manifest and no manifest-declared exports:. A package that bundles heterogeneous content (knowledge, workflows, tasks, environment, skills) is served by the single adapter selected for its root: that adapter's recognize processes the files and subdirectories of the bundle however it sees fit — the core provides the walk and the persistence, and the adapter claims or abstains per file. Heterogeneous tool subtrees are the adapter's concern, not a reason to split the bundle into multiple components.

9.3 Component identity and conceptId collisions

(Amended v0.4, 2026-07-21 — nested-root subtraction removed: a single-adapter bundle has one component, so there are no other component roots to subtract and no cross-component ref collisions.)

Because a bundle has one component, every physical file in the walked tree is owned by that one component; refs are bundle-relative and unique. The persisted ref column is UNIQUE.

Within a component that supports multiple extensions, two files reducing to the same conceptId are a duplicate-concept-id validation diagnostic naming both paths. The adapter MUST declare a deterministic extension priority to pick the indexed winner, and the loser's path MUST be recorded so that deleting the winner later resets, rather than inherits, the ref's durable state history.

9.4 Adapter detection

Automatic detection MAY propose candidate component mounts. It MUST NOT establish permanent semantics without a deterministic winner or explicit configuration.

Once a component is registered, its adapter selection MUST be persisted and indexing MUST NOT rerun global format guessing.


10. Workspace configuration and resolved lock state

Workspace configuration represents desired installations and bindings. A lockfile represents resolved source state.

10.1 Desired configuration

bundles:
  team-catalog:
    git: https://github.com/acme/team-catalog.git
    revision: main
    components:
      main:
        root: .
        adapter: okf

  project-claude:
    path: .
    components:
      claude:
        root: .claude
        adapter: claude
        writable: true

  typescript-docs:
    website:
      url: https://www.typescriptlang.org/docs/
      refresh: 12h
      maxPages: 250
      maxDepth: 4
    components:
      pages:
        root: .
        adapter: website-snapshot
        writable: false

bindings:
  release:
    export: team-catalog//workflows/release
    enabled: true
    options:
      engine: claude
      environment: prod-release

10.2 Lock state

Resolved lock state SHOULD include:

Desired configuration MUST NOT duplicate resolved cache paths and revisions that belong exclusively in lock state.


11. Identity and refs

11.1 Canonical ref

The canonical item ref is (§7.8):

ref := [ <bundle> "//" ] <concept-id> [ "#" <fragment> ]

The bundle slug MUST NOT contain /, :, ., or # (this keeps bundle// lexically distinguishable from URLs and scheme-relative links in prose). The conceptId MAY contain /, MUST NOT contain #, and is otherwise opaque to the core below the //.

Canonical stored spelling. All durable state keys, index rows, bindings, and proposal targets MUST store the fully-qualified bundle//conceptId form, always. The short (bundle-omitted) form is CLI input sugar; it MUST NOT be persisted as a key. (Today's rekeyStateDbForMove probing three legacy spellings per ref is the cost of leaving this open.)

Short-ref resolution (amended per ref-grammar decision D-R4). A short ref from CLI/API input resolves to the defaultBundle if the conceptId exists there, otherwise to the first bundle containing the conceptId in installation priority order (the config/deriveInstallations order — the same order origin-less lookups walk today). First match wins, deterministically; no match is a not-found error naming the forms tried. Short refs inside bundle content resolve to the containing bundle, never defaultBundle. Scoped lookup (the old local//) is an explicit resolver option ({ only: bundleId }), not a ref spelling.

Short refs in portable content. A short ref appearing inside a file that ships in a bundle resolves to the containing bundle, never the installer's default bundle, so intra-bundle references stay portable by construction. Each adapter's native link form is preferred inside its format; for an OKF bundle that is the OKF bundle-relative link syntax (§26.3).

Canonicalization. conceptIds are normalized at index/parse time: path separators normalized to /; Unicode normalized to NFC; identity is byte-wise case-sensitive. Indexing MUST emit a case-collision diagnostic when two files in one component differ only under case folding or NFC/NFD normalization (they cannot round-trip through case-insensitive checkouts). The traversal, null-byte, and drive-letter guards of the current validateName are normative MUSTs for conceptId validation, together with a # rejection.

Body-ref grammar. Refs embedded in prose MUST use the fully-qualified bundle//conceptId form (the bundle-slug charset above makes it lexically anchored), or a native link form owned by the adapter. Lint's missing-ref scan operates only on these anchored forms; bare short refs in prose are not recognized as refs and MUST NOT be rewritten by any tool. (0.9.0: the other consumer of this rule, akm mv's inbound-xref rewriting, did not honour it — it implemented the rule inverted, rewriting bare conceptIds while matching no bundle// form at all, which is why the command shipped Experimental and outside the stability contract earlier in the 0.9.0 cycle.) (Amended 2026-07-30 — akm mv was removed outright before the 0.9.0 release; no tool rewrites inbound refs on rename today. See 0.9.0-decisions.md §D3.)

11.2 Ref invariants

11.3 Export refs

An export normally uses the item ref that exposes it. If one item exposes multiple exports, the adapter MAY append a stable fragment:

team//tools/toolbox#deploy

The fragment is adapter-owned and opaque to the core. Because # is forbidden inside conceptIds (§11.1), the fragment production is unambiguous.

11.4 Ref migration

The current [origin//]type:name namespace MUST be migrated once. Migration MUST rekey retained durable records such as:

A permanent dual-parser is prohibited.

Mapping and orphan policy. The old-ref → new-id mapping MUST be computed by joining against the last-good index (entry key → file path → conceptId) or by walking the old on-disk layout with a frozen copy of the old resolver — never by reconstructing paths from TYPE_DIRS heuristics at migration time. Mature installations provably hold state rows for items with no file and no index row (deleted-asset salience/outcome rows, append-only usage history, retained judged-state keys), so a literal zero-orphan requirement is unsatisfiable. The migration MUST therefore classify rows:

11.5 Bundle rename

Renaming a workspace bundle id is a mass identity migration (every ref in the bundle changes without any file moving). It MUST be performed by an explicit akm bundle rename <old> <new> that runs the same rekey transaction family as an item move — index rows, all ref-keyed state tables, bindings, and configuration, atomically. Startup MUST detect a configured bundle id whose index/state rows exist only under a missing id and refuse or warn rather than silently re-minting fresh state. Refs are workspace-scoped: two workspaces installing the same package under different bundle names produce different refs. The lock state SHOULD record the upstream package name so tooling can offer it as a resolvable alias for cross-workspace exchange; absent that, documentation MUST state that refs are not portable across workspaces.


12. Adapter contracts

12.1 Base contract

There is one adapter interface. Optional capabilities are optional methods on it (DEV-6, History §8.3) — not an extends hierarchy and not a semantic-view registry.

interface BundleAdapter {
  readonly id: string;
  readonly version: string;                 // feeds incrementality and fingerprints
  readonly extensions: readonly string[];   // recognized extensions, longest-match stripped (§11.2)

  // REQUIRED — the single-file recognition primitive.
  recognize(
    component: BundleComponent,
    file: FileContext,
  ): IndexDocument | null;

  // OPTIONAL — full-component scan for adapters whose layout is not per-file
  // (website snapshots, multi-file wiki semantics). When absent, the core scans:
  //   the core walk (git-aware, symlink-safe, skip-dirs) × adapter.recognize per
  //   file, drained and diff-persisted per directory (§14.2).
  // An adapter that overrides index() MUST either keep recognize() coherent with it
  // (conformance: index() output equals the fold of recognize() over the walk) or
  // declare component-level incrementality (§14.2).
  index?(
    installation: BundleInstallation,
    component: BundleComponent,
  ): AsyncIterable<IndexDocument>;

  // REQUIRED — native validation. The core supplies the context; the adapter never
  // reads the live filesystem during validation.
  validate(
    component: BundleComponent,
    changes: readonly FileChange[],
    ctx: ValidateContext,
  ): Promise<Diagnostic[]>;
}

interface ValidateContext {
  // Reads served from the run's snapshot WITH the pending changes overlaid —
  // one core overlay implementation, not one per adapter.
  readFile(path: string): Promise<string | Uint8Array | null>;
  list(dir: string): Promise<string[]>;
  // Read-only index lookup for link/xref existence checks (not search).
  resolveRef(ref: string): Promise<{ exists: boolean; path?: string }>;
}

The core walk is a single implementation carrying the security policy (symlink refusal, traversal containment, skip-dirs); adapters MUST NOT reimplement it. Native-shape rules belong to the adapter; cross-component ref existence is a core base check run on every transaction, since it belongs to no single adapter.

12.2 Authoring methods (optional)

  getAuthoringContext?(
    component: BundleComponent,
    target: { path?: string; conceptId?: string },
    operation: "create" | "update" | "move" | "consolidate",
  ): Promise<AuthoringContext>;

  create?(
    component: BundleComponent,
    request: CreateRequest,
  ): Promise<FileChange[]>;

  placeNew?(component: BundleComponent, conceptId: string): string;
  directoryList?(component: BundleComponent): string[];   // feeds git exact-path staging
  looksLikeRoot?(root: string): boolean;                   // install-time probe (§9.4 ordering)

AuthoringContext MUST include hashes or versions for the rules and guidance used so proposal fingerprints are reproducible.

12.3 Export methods (optional)

  listExports?(
    installation: BundleInstallation,
    component: BundleComponent,
  ): AsyncIterable<BundleExport>;

  planBinding?(
    component: BundleComponent,
    exported: BundleExport,
    request: BindingRequest,
  ): Promise<BindingPlan>;

12.4 Memory lifecycle methods (optional)

  listMemories?(
    installation: BundleInstallation,
    component: BundleComponent,
  ): AsyncIterable<MemoryRecord>;

  renderMemoryPlan?(
    component: BundleComponent,
    plan: MemorySemanticPlan,
  ): Promise<FileChange[]>;

  validateMemoryPlan?(
    component: BundleComponent,
    plan: MemorySemanticPlan,
    changes: readonly FileChange[],
  ): Promise<Diagnostic[]>;

The method groups in §12.2–§12.4 are members of the single BundleAdapter interface of §12.1, shown separately for readability.

12.5 Excluded adapter responsibilities

Adapters MUST NOT:

12.6 Built-in registry first

The first implementation SHOULD use a static built-in adapter registry. A public plugin ABI is deferred until the contract is proven by multiple independently maintained adapters.


13. Conventions and authoring rules

13.1 Adapter ownership

Conventions and authoring rules move to adapters. They are not removed.

Each authoring-capable adapter MUST own:

13.2 One source for prompts and validation

Hard-rule instructions shown to humans or models and hard-rule validators MUST derive from the same adapter-owned rule definitions.

A change to a required field, naming rule, or layout constraint MUST NOT require independent edits to an unrelated central prompt and validator.

13.3 Native examples

13.4 Workspace policy

Workspace policy remains cross-format and operational. It MAY restrict:

Workspace policy MUST NOT silently rewrite native format semantics.


14. Indexing

14.1 Normalized projection

The additive common projection ends at IndexDocument. Its basic Markdown surface aligns with OKF so any adapter can supply path identity, an open type, content, and links; native adapters may add fields and capabilities without narrowing that baseline:

interface IndexDocument {
  ref: string;              // fully-qualified "bundle//conceptId" (§11.1)
  bundle: string;
  component: string;        // provenance, derived (§7.8)
  conceptId: string;
  path: string;             // absolute local path (the read path)
  hash: string;
  adapterId: string;
  type?: string;            // open descriptive label supplied by the adapter

  // FTS columns (weights pinned, §14.4)
  name: string;             // 10
  description?: string;     // 5
  tags?: string[];          // 3
  hints?: string[];         // 2
  content?: string;         // 1

  // Core-parsed query-time signals. These fields are read by ranking contributors
  // and result filters at query time and are therefore FIRST-CLASS, not folded
  // into documentJson. This list is pinned by a lint; extending it is a
  // deliberate schema change.
  aliases?: string[];       // exact-alias boost is distinct from the tags signal
  searchHints?: string[];
  quality?: string;         // curated boost + proposed-by-default exclusion filter
  confidence?: number;
  beliefState?: string;     // + boosts, score ceilings, --belief filter
  currentBeliefRefs?: string[];
  supersededBy?: string;
  scope?: Record<string, string>;   // scope_user/agent/run/channel filters
  captureMode?: string;
  lessonStrength?: number;
  pinned?: boolean;
  fileSize?: number;        // hit size + estimated tokens
  derivedFrom?: string;     // derived-twin belief inheritance
  links?: string[];         // resolved native links = relationships (§26.3)
  updated?: string;

  documentJson?: unknown;   // opaque adapter extras ONLY; not FTS; never parsed by core
}

type is an open descriptive label supplied by the selected adapter. The OKF adapter reads OKF's frontmatter type; other adapters derive it from their own native semantics. It MAY drive presentation, ranking, and filtering. It MUST NOT authorize execution, be part of identity, or select the core storage/write path. Sensitivity suppression (env/secret redaction — existing behavior, ported) is keyed on the adapter, never on type, so content metadata cannot opt out of it.

The folding rules that map richer native metadata (examples, usage, intent, xrefs, when-to-use, outline, parameters, bounded content) into the FTS hints/content columns are a core-shared helper that adapters call — one fold, not one per adapter — because the embedding-input hashes and frozen retrieval canaries are pinned to that exact surface.

14.2 Scan flow and diff persistence

(Amended v0.4, 2026-07-21 — the implemented engine: the core walk × the dispatched adapter.recognize, drained and diff-persisted per directory. The retired scanComponent wrapper and its nested-root subtraction are gone with multi-component bundles.)

materialize bundle revision
-> select the persisted component and its adapter (adapterForId(component.adapter);
   unknown id ⇒ skip the component with a warning)
-> for each walked directory: core walk (universal hygiene) × adapter.recognize
   (or adapter.index override) → DRAIN the directory's document stream
-> one write transaction: DIFF persist against the directory's existing rows
-> build FTS/vector/native-link projections incrementally

Persistence is a diff, not truncate-and-rewrite:

Incrementality is item-scoped, not file-scoped. The mount manifest records {scanGeneration, adapterVersion, items: {conceptId → fileSet+hashes}}. A changed file re-recognizes every file belonging to the affected item(s); adapters MAY implement affectedItems(component, changedPaths) (default: identity for single-file items) and MAY declare coupling files (e.g. a wiki schema.md) whose change escalates to a component rescan. Directory-scoped items (a skill directory) are one item: sibling adds/edits/deletes invalidate the item, and deleting the primary file deletes the item. The canonical entry/FTS mutation boundary and the zero-row dir-state classification carry forward into this manifest design.

14.3 Query isolation

Adapters, materializers, registries, and network services MUST NOT execute during a normal search query.

If one adapter scan fails, AKM MUST preserve the last-known-good index records for that component (guaranteed by drain-before-transaction, §14.2) and continue serving unaffected bundles with a warning.

14.4 Search parity during migration

The initial adapter cutover MUST preserve the existing weighted fields and behavior unless a benchmarked change is separately approved:

name         10
description   5
tags          3
hints         2
content       1

The cutover gate MUST compare:

The retrieval-canary set is pinned to the old field-fold surface; the cutover MUST schedule an explicit canary re-mint as a named migration step.

14.5 Deterministic indexing by default

Index correctness MUST NOT require an LLM.

Index-time LLM metadata or graph enrichment MAY exist only as an explicit, versioned derived processor that has demonstrated measurable value. It MUST NOT mutate bundle content.

14.6 Index mutability rule

akm index MUST write only workspace index/cache state. It MUST NOT regenerate index.md, rewrite frontmatter, repair links, or otherwise mutate bundles.

Native maintenance fixes belong to adapter lint/fix, import, ingest, create, or improve operations.


15. Search and read behavior

akm search searches installed local bundle content only. Registry/package discovery is a separate operation.

Search MAY filter by:

Unknown native types MUST remain searchable.

(A v0.2 clause making the trusted flag load-bearing in search/show output — untrusted labeling and action clamping — was withdrawn in v0.3: new trust machinery is rejected as false-confidence machinery, deviation §4.3c. trusted remains reserved vocabulary on BundleInstallation for a possible Tier-B future; nothing reads it.)

15.2 Progressive disclosure

AKM SHOULD expose three retrieval levels:

L0 card      name, description, type, tags, hints
L1 overview  outline, navigation, relationships, applicability
L2 detail    full native file content and supporting resources

This follows the useful retrieval pattern demonstrated by OpenViking and Agent Skills, but AKM MUST keep generated cards, overviews, chunks, and embeddings in the index unless the native format itself defines portable sidecar files.

15.3 Direct reads

Normal item reads MUST use the absolute path stored in the index:

const content = await fs.promises.readFile(indexed.path, "utf8");

The core SHOULD NOT add adapter.read(), repository.read(), or content-provider layers around deterministic filesystem reads.

Adapters MAY provide specialized parsing only when a runtime or authoring operation needs native structure.

Sensitivity exception. The raw-read rule does not apply to items in sensitivity-suppressed components: for dotenv/secret components, show and search MUST present only the safe metadata surface (key names / file name, §21.2) and MUST NOT read or print the body. This suppression is keyed on the adapter/component, never on the open type, so a frontmatter type: cannot opt out of redaction and a generic fallback cannot dump a credential file.

15.4 show

show SHOULD:

  1. resolve the item ref from the index;
  2. read the stored path (subject to the §15.3 sensitivity exception);
  3. return native content plus indexed metadata, rendered by the named presentation function for its type;
  4. record a usage event.

It MUST NOT run global matchers, type-competition registries, graph extraction, or wiki/type special cases.

Presentation code home. The type → presentation mapping is a data table (TYPE_PRESENTATION, typed over the KNOWN_TYPES const tuple so the compiler enforces exhaustiveness for AKM's own known set, with an open-string lookup falling back to the generic entry), but the renderer implementations it names remain a small static core module of named functions (env-keys-only, secret-name-only, script-exec-hints, markdown view modes, generic). "No renderer registry" in the acceptance criteria means no per-type competition registry with dynamic registration — not that renderer code disappears.

15.5 Context selection

The current curated result-selection logic MAY remain as a search result shape or context command. It SHOULD NOT remain a separate content subsystem and MUST NOT trigger hidden model work or graph extraction.


16. Website sources

Website support remains a first-class source capability.

16.1 Refreshable website bundle

website materializer
-> bounded crawl and neutral snapshot files
-> website-snapshot adapter
-> read-only indexed component

The materializer MUST retain, per page where available:

It MUST preserve existing protections for:

A refresh creates a new materialized revision. Search uses the last successful local revision.

16.2 Website-to-native export

AKM MUST also support transforming a website snapshot into a writable native bundle component:

website snapshot
-> destination adapter authoring context
-> destination FileChange[]
-> native validation
-> proposal or application

Example:

akm ingest typescript-docs/pages --to personal/knowledge --adapter okf   // doclint:ignore — not yet implemented, target surface

The live website installation remains refreshable and read-only. The exported destination is separately editable, versioned, and eligible for ordinary improvement.


17. Registry and package discovery

Registry search MUST be separate from local content search.

A registry entry SHOULD describe:

Registry entries SHOULD NOT require per-item asset previews or an AKM-wide asset-type inventory.

The registry discovers installable bundle packages. The local workspace index discovers installed content.

Because default-mounting arbitrary repositories is easy under this design, integrity handling tightens for untrusted sources: installations MUST pin the resolved revision in lock state, and an unrecognized integrity format is a hard failure for an untrusted source rather than a warning. (Git commit-hash sources remain pin-by-revision; npm sources verify integrity as today.)


18. Installation, exports, bindings, and activation

Release-staging note (2026-07-14, deviation §4.3a/§4.3c — mirrors the §25 staging pattern). This section is target-state. What ships in 0.9.0 is Tier A only: §18.2's install-grants-nothing (already true in code, consolidated into one workspace activation-policy point and verified by port-preservation tests). The persisted Binding record (§18.3), digest-change detection and rebind (§18.5, §20 steps 1–5), one-shot approval checks (§18.4), and the bind CLI (§29) are Tier B, deferred indefinitely — revisit only on concrete demand. Deferral rationale: approval/trust machinery built ahead of demand provides false confidence and must be maintained as brittle code. The accepted Tier-A residual: enabled schedules and one-shot invocations that reference content in installed sources re-read current disk content per invocation (crontab semantics); §18.5/§20's update-review MUSTs therefore have no enforced trigger in 0.9.0 and bind (§18.1) reads as "explicit enable."

18.1 Lifecycle

discover
-> install/materialize
-> index
-> bind or explicitly approve one-shot use
-> enable external side effects where applicable

18.2 Installation

Installation makes content locally available and searchable. It MUST NOT:

18.3 Binding

A persistent binding SHOULD record:

18.4 One-shot invocation

A workspace MAY allow explicit one-shot execution without a persistent binding. Such execution MUST still pass the same approval, trust, digest, environment, and permission checks.

18.5 Update behavior

Updating an installed bundle MUST NOT silently alter:

AKM MUST detect export digest changes and require policy-controlled review or rebinding for meaningful runtime changes.


19. Workflow exports

Workflows remain portable bundle files.

A workflow adapter MUST be able to:

A workflow run MUST freeze:

An installed-bundle update MUST NOT change an in-flight run.

Workflow loading SHOULD be:

export ref
-> indexed absolute path
-> workflow adapter/codec
-> normalized definition
-> frozen plan

It SHOULD NOT depend on a universal workflow: ref, a core-required workflows/ directory, or a required workflow_documents index table.


20. Task exports and scheduling

Task definitions remain portable bundle content.

A task definition MAY contain:

Installation MUST NOT register an operating-system schedule.

Binding a task resolves:

Enabling the binding registers the schedule.

When an installed task definition changes, AKM MUST:

  1. detect the digest change;
  2. validate the new native definition;
  3. show schedule, target, and environment differences;
  4. preserve the currently active binding until the update is approved;
  5. retain run history across task versions.

21. Environment and secret exports

21.1 Portable environment content

Bundles MAY include:

21.2 Indexing

The environment adapter MUST index only safe metadata:

Values and comment text MUST NOT be indexed or printed.

21.3 Binding

A workspace environment binding MAY map a portable key to:

Using values from an installed bundle requires explicit approval. Installation alone is never sufficient.

21.4 Secret handling

Secret-bearing content MUST preserve current protections:


22. Agents, commands, skills, and scripts

22.1 Native formats

Claude agents, OpenCode agents, Agent Skills, commands, prompts, and scripts remain in their native files.

The core MUST NOT inject universal AKM metadata or OKF fields into native files when that would violate or distort their schema.

Native tool directories are installed as bundles. Their adapters translate recognized native assets into AKM runtime/index representations while reading them. AKM MUST NOT synchronize native tool directories, create canonical copies of their agent/command assets, or write translated agents/commands back to the native bundle. The native file remains authoritative.

22.2 Runtime separation

The architecture SHOULD separate:

BundleAdapter             native file interpretation
SessionEvidenceProvider   native session-log discovery
RuntimeHarness            execution and output normalization

A product such as Claude or OpenCode may implement all three, but they are distinct responsibilities.

22.3 Execution authority

An item carrying type: script, type: skill, or an executable export does not authorize execution. Execution requires an explicit invocation or enablement; runtime handlers never consult type for authority (§8.4).

Once explicitly invoked, installed agent and command metadata participates in the ordinary resolution cascade. Asset provenance does not create a second precedence system for engine, model, or requested tools. Machine/user policy separately authorizes the resolved request. The complete semantic rules are in Agent, Command, Engine, and Model Resolution.

This follows the useful distinction in MCP between passive resources and executable tools.


23. File changes and proposals

23.1 FileChange

interface FileChange {
  path: string;
  beforeHash?: string;
  after?: string | Uint8Array;
  delete?: true;
}

A proposal contains one or more FileChange records. Proposal and change set are the same durable object; AKM SHOULD NOT create a chain of candidate, proposal, mutation plan, and change-set wrappers unless a concrete requirement proves necessary.

23.2 Before-hash rule

Every update or deletion MUST carry the expected before hash. Application MUST fail when the current file differs.

23.3 Proposal evidence

A proposal SHOULD include:

interface ProposalEvidence {
  fingerprint: string;
  triggerIds: string[];
  evaluator?: string;
  passed?: boolean;
  metrics?: Record<string, number>;
  details?: unknown;
}

Recipe-specific details MAY remain opaque.

23.4 Transaction engine

The core transaction engine MUST:

  1. group changes by component root;
  2. validate path and symlink containment;
  3. verify before hashes;
  4. obtain the workspace mutation lease;
  5. stage replacement content;
  6. maintain a durable recovery journal;
  7. apply writes, deletes, and moves;
  8. invoke adapter validation;
  9. roll back on validation or publication failure;
  10. refresh affected index rows once;
  11. commit exact Git paths when configured;
  12. record proposal/change and audit outcomes.

Adapters MUST NOT apply their own writes or Git commits.

23.5 Change classes

Change class Default policy
Mechanical and deterministic Auto-apply after validation
Objectively verified semantic Auto-apply only when explicitly configured
Subjective semantic Queue for review
Destructive Queue unless exact and deterministic

Model self-confidence MAY be stored as diagnostic metadata. It MUST NOT authorize publication.

23.6 Input fingerprint

The fingerprint SHOULD be:

hash(
  recipe version
  + target before hashes
  + evidence IDs or hashes
  + applicable guidance hashes
  + relevant evaluator version
)

An already processed fingerprint SHOULD skip another model call unless explicitly forced.


24. Improve architecture

24.1 Purpose

akm improve is an evidence-driven, verified file-evolution loop. It is not a general maintenance daemon.

24.2 Semantic operations

The core supports three first-class semantic operations:

revise       update an existing durable item
learn        create a new durable item from evidence
consolidate  reduce or formalize bounded memory with source retirement

Adapters do not register arbitrary improve processes. Recipes are core-owned, separately designed, tested, and evaluated.

24.3 Run flow

collect corrective evidence and pressure signals
-> freeze file/index snapshot
-> select targets
-> read indexed paths directly
-> obtain adapter authoring context
-> generate candidate FileChange[]
-> validate native format and workspace policy
-> compare candidate with baseline
-> queue or apply
-> reindex affected files once
-> observe later field outcomes

24.4 Corrective evidence

Unattended semantic candidate generation MAY be triggered by:

High retrieval, age without retention policy, low retrieval, salience, file size, or elapsed time alone MUST NOT authorize semantic rewrite or deletion.

24.5 Verification ladder

Native safety

Objective comparison

Field outcome

A generic LLM judge may support classification but is not objective proof. This caution is supported by research on self-correction limitations and judge bias, including Large Language Models Cannot Self-Correct Reasoning Yet, Judging LLM-as-a-Judge with MT-Bench and Chatbot Arena, and Judging the Judges.

24.6 Removed from the replacement core

The replacement MUST NOT carry forward by default:

Any removed mechanism MAY return only after an ablation demonstrates positive verified quality per unit cost.


25. Bounded memory lifecycle

Release-staging note (2026-07-14, deviation §4.3b). This entire section is target-state; none of it is 0.9.0 scope. 0.9.0 ships only the consolidate.ts decomposition with existing behavior preserved exactly (plan §6): the current merge/delete/promote/contradict ops through archiveMemory, journals, LOOK/CHANGE separation, hot-capture guard, and proposal-gating, all as today. The lifecycle state model below (operational states, water-marks/backpressure, claim coverage, sandbox evaluation, content-addressed archive, purge, overlay) begins only after the claim extractor and its benchmark exist — it is feature work, staged behind its load-bearing dependency, and gets its own design pass then.

Memory lifecycle is a first-class product requirement and remains part of improve.

25.1 Adapter capability

A memory-capable adapter maps native records into a narrow MemoryRecord inventory and renders native changes from a semantic plan. It owns serialization and native lifecycle conventions. Core owns pressure, selection, evaluation, retirement state, archive, and purge.

25.2 Operational states

active
  -> retired
  -> purged

active
  -> quarantined
  -> restored | purged

Adapter-native relations such as superseded, contradicted, historical, or deprecated remain semantic metadata and do not replace operational lifecycle state.

25.3 Consolidation outcomes

Compact within memory

many duplicate or overlapping memories
-> fewer stronger memory records
-> retire redundant sources

Formalize into durable content

memory cluster
-> create or update knowledge, lesson, convention, workflow, etc.
-> verify source coverage
-> retire source memories

The destination is selected by bundle configuration and adapter capability, not a hard-coded core type.

Retire without formalization

Allowed only for:

Age or low use alone is insufficient.

25.4 High- and low-water policy

A memory-capable component MUST have either explicit bounds or a documented unbounded policy. The recommended bounded configuration is:

memory:
  highWaterItems: 1000
  lowWaterItems: 800
  highWaterBytes: 52428800
  retireGraceDays: 30
  archiveRetentionDays: 180
  archiveMaxBytes: 1073741824
  backgroundIntakeWhenBlocked: skip   # default; "queue" is allowed only as a bounded queue (§25.4)

When a high-water threshold is exceeded:

  1. deterministic cleanup runs first;
  2. semantic consolidation attempts to reach the low-water mark;
  3. unsafe deletion is prohibited;
  4. if safe consolidation cannot reduce pressure, background extraction stops publishing memory files for that component;
  5. explicit user-authored memory remains allowed with a warning;
  6. health reports the unresolved pressure and blocked intake.

Backpressure is the required fail-safe when safe deletion cannot be proven. The default blocked-intake behavior is SKIP-with-warning, not a new queue tier: sessions and captured evidence already persist durably in workspace state, so a blocked extraction simply defers — re-extraction picks the evidence up when pressure clears. An implementation MAY provide an explicit evidence queue instead, but only as a bounded one (item, byte, and age limits, a defined eviction policy with an event, and drain-on-pressure-clear semantics); an unbounded queue merely displaces the unboundedness this section exists to prevent. Pressure state MUST NOT be an input to per-item disposition classification (§25.6).

25.5 Consolidation pipeline

1. inventory and freeze snapshot
2. deterministic duplicate/supersession/TTL cleanup
3. build bounded semantic clusters
4. classify keep/compact/formalize/contradict/retire/quarantine
5. generate successor through destination adapter
6. build source-to-successor claim coverage map
7. render native FileChange[]
8. validate native formats and policy
9. build sandbox index and run retrieval/task checks
10. propose or apply
11. retire source memories
12. monitor grace period
13. purge archive when eligible

Two placement rules that implementations MUST NOT diverge on:

25.6 Claim coverage

For unattended semantic consolidation, every durable source claim MUST have one disposition:

preserved in successor
preserved in another active source
explicitly superseded
intentionally discarded with recorded reason

A durable claim with no disposition blocks unattended retirement.

Reviewed mode: when a semantic consolidation is queued as a proposal (the default, §25.9), explicit human approval of the proposal satisfies the disposition requirement — the reviewer is the disposition authority. The coverage map is still produced when an extractor is available, as review evidence.

Authority rules:

Staging: the claim extractor and its benchmark (§33) are the load-bearing prerequisite for this entire section — nothing here is built before they exist (release-staging note at the top of §25). When the lifecycle is built, unattended semantic retirement stays OFF until the extractor passes its benchmark; deterministic auto-retirement (§25.9 rows 1–4) and review-gated semantic proposals come first.

Temporal qualifiers and contradictions MUST NOT be flattened into a false single statement.

25.7 Retirement evaluation

Before retiring semantic source memories:

Scoping. The first shipped retirement gate is an FTS-only sandbox replay (canaries plus the logged per-source queries, with successor-following), advisory-blocking for unattended retirement; full rank-parity replay (utility/salience/graph extras) is deferred until the §26.2 ranking ablations decide which extras survive. The retrieval-canary probe and its store are preserved infrastructure — they are this gate's harness and are explicitly excluded from any prove-or-delete measurement of the advisory collapse-alert loop. Usage-event retention for memory-tier entries MUST be long enough (or per-source query lists snapshotted at capture time) that the replay set does not silently starve.

Cross-bundle or cross-repository formalization MUST use a recoverable two-phase protocol:

  1. publish and validate destination;
  2. retire sources only after destination success.

25.8 Retirement archive

Retired bytes MUST NOT accumulate in an unbounded bundle-local archive.

(Decision note: this deliberately supersedes the 2026-06-15 WS-3a in-code retirement of archive-retention machinery, which relied on git history as the sole recovery path. The reversal is recorded as D27 in the decision history: read-only components, non-git-backed bundles, and format-independent recovery all require a workspace-owned archive; git history remains an additional recovery path, not the only one. The existing bundle-local archiveMemory move is an acceptable bounded stopgap only until this store ships — there is one retirement encoding at any given time, not two.)

The default archive is a workspace content-addressed store:

$DATA/archive/blobs/sha256/<digest>

The blob store and its state records MUST use owner-only filesystem modes where the platform supports them (0600 files / 0700 directories) — retired and quarantined bytes can contain sensitive captures — and the same sensitive-content redaction and quarantine handling that applies to the live index applies to archive metadata.

State records SHOULD include:

Git history is an additional recovery path, not the only one.

25.9 Automatic policy

Candidate Default action
Byte-identical duplicate Auto-retire redundant copy
Equivalent normalized content and provenance Auto-retire after deterministic proof
Explicit supersession with valid successor Auto-retire
TTL-expired ephemeral memory Auto-retire
Unsafe or sensitive capture Quarantine
Semantic near-duplicate merge Proposal by default
Formalization into durable content Proposal by default
Contradictory memories Preserve and qualify
Old or low-use memory only Keep or de-prioritize
Failed coverage or retrieval evaluation Keep active

25.10 Read-only components

Workspace retirement MAY suppress a read-only installed memory from default retrieval without mutating its source. Actual source deletion or rewrite requires a writable component or a writable clone/export destination.


26. Feedback, ranking, graph, and evaluation

26.1 Feedback

AKM SHOULD retain explicit positive/negative feedback and usage events as workspace state.

Feedback MUST NOT mutate portable content merely to record telemetry. For example, lesson-use counters belong in state, not frontmatter.

26.2 Ranking baseline

Complex signals such as salience vectors, outcome scores, review pressure, project-context boosts, type boosts, replay, and forgetting-safety MUST be compared against a simpler baseline:

lexical/vector relevance
+ explicit feedback utility
+ recent successful use
+ negative-feedback review priority

Only features that materially improve nDCG, MRR, task-context success, verified-change yield, or user preference SHOULD remain.

New types receive no ranking boost by default.

26.3 Relationships

Adapters SHOULD expose deterministic native links and relationships first.

LLM graph extraction MAY remain as an optional derived index processor only if ablation shows material search or task-context value. It MUST NOT execute from show, context selection, or improve.

26.4 Candidate evaluation

AKM SHOULD reuse and extend its deterministic rank-aware benchmark infrastructure for before/after proposal evaluation, including:


27. Storage model

The target workspace uses three databases:

state.db  durable workspace truth
index.db  fully regenerable search and derived cache
logs.db   high-volume purgeable logs

27.1 state.db

Contains durable non-regenerable state such as:

workflow.db SHOULD be merged into state.db because both are durable workspace state and benefit from atomic run/event transitions.

27.2 index.db

Contains fully regenerable state such as:

Deleting index.db and rebuilding MUST be safe.

27.3 logs.db

Contains high-volume, append-only, purgeable logs. It remains separate to permit aggressive retention without affecting durable state.

27.4 Filesystem locations

AKM MUST NOT create .akm runtime state inside bundle roots.


28. Security and trust

28.1 Passive content versus executable authority

Indexing or displaying a bundle is not execution approval.

Runtime authority is granted through a binding or explicit approved invocation, following the same conceptual separation between passive resources and executable tools described by MCP.

28.2 Untrusted content

Untrusted bundle content MAY be indexed as text, subject to size and sensitivity policy. Indexing alone MUST NOT activate schedules, inject environment or secret values, execute scripts, or write outside its component root.

Agent and command assets may declare requested tools and engine/model defaults. Those declarations have no effect until explicit execution and then participate in the normal nearest-wins cascade. They MUST NOT override machine/user tool authorization, secret policy, budget policy, or execution activation. A denied tool request fails explicitly; AKM does not silently grant or silently reduce it.

(Two v0.2 clauses — untrusted presentation clamping and a catch-all sensitive-content refusal — were withdrawn in v0.3, deviation §4.3c. Catch-all adapters remain explicit-configuration-only and never auto-selected (§9.4): a user who mounts a root with generic-files indexes what they pointed it at, deliberately.)

The dangerous-environment-key policy keeps its origin asymmetry across the config migration as a port of the existing rule (today: registryId-bearing source → hard block; first-party → warn): an env export from a registry-installed source containing process-hijacking keys MUST still hard-error after installed[] is replaced, covered by a port-preservation conformance test. This is existing behavior surviving the migration, not new machinery.

28.3 Path safety

Materialization, indexing, validation, and mutation MUST enforce:

28.4 Secret safety

Secret values MUST NOT enter:


29. CLI and public API direction

The logical command surface SHOULD converge toward:

akm bundle create
akm info
akm health

akm bundle create|install|list|show|items|update|remove|sync|export  // doclint:ignore — not yet implemented, target surface
akm registry search|show  // doclint:ignore — target surface; `registry search` folded into `akm search --from registry` in 0.9.0, `registry show` not yet implemented

akm search
akm show
akm lint
akm import
akm ingest                      // doclint:ignore — not yet implemented, target surface

akm bind|unbind|bindings        // Tier B — deferred with the Binding record (§18 staging note); doclint:ignore — not yet implemented

akm proposal list|show|diff|accept|reject|revert
akm improve

akm workflow ...
akm task ...
akm agent ...
akm command run ...              // canonical adapter-rendered command executor
akm env ...
akm secret ...

The following concepts should be removed or folded:

Public in-process APIs SHOULD mirror CLI commands and option shapes rather than expose a separate orchestration abstraction.


30. Implementation and migration strategy

The implementation stays in the current repository. The current asset and improve centers are sacrificial modules; mature infrastructure is retained.

Phase 0 — Freeze and measure

Phase 1 — Workspace context and bundle catalog

Phase 2 — First native vertical slice

Implement an OKF component:

install/mount
-> adapter index
-> existing FTS/vector persistence
-> search
-> direct show
-> native lint

No improve or mutation support is required in this slice.

Phase 3 — New index projection

Phase 4 — Source and website lifecycle

Phase 5 — Bundle lifecycle and bindings

Phase 6 — Proposal and transaction replacement

Phase 7 — Memory lifecycle

Phase 8 — Improve replacement

Phase 9 — Runtime cutovers

Phase 10 — One-time current-layout migration

Migration MUST:

  1. inventory current files and durable state — the FROM-state is the shipped rc-train layout (state ledger already at its final pre-cutover migration, workflow.db present, vault already removed), not a pristine 0.8 tree; fixtures MUST cover that FROM-state;
  2. create semantically verified config and durable-database backups — the backup set MUST include every durable table's home, including usage/feedback events wherever they physically live pre-cutover; writable content is not duplicated, so its transforms MUST be atomic, idempotent, and replayable;
  3. propose destination bundles, components, and adapters;
  4. compute and persist the old-ref → new-id map before any filesystem re-layout (walk the old layout with the frozen legacy resolver; the cutover consumes only the persisted map);
  5. dry-run every file, ref, binding, and state mapping;
  6. write new configuration and lock state;
  7. move or convert files through adapter transactions;
  8. rekey durable refs under the §11.4 orphan taxonomy (expected orphans quarantined, integrity failures fail-closed);
  9. validate all destination components;
  10. rebuild the index after the committed state transaction: the old index file is quarantine-renamed (never early-unlinked), durable feedback tables are migrated out of it first, and a quarantine failure retains the incomplete sentinel for retry without rolling back the committed state transaction; the indexer self-heals on its next run;
  11. run search and runtime smoke tests;
  12. produce a migration report;
  13. retain the config/database backup plus persisted ref and reserved-rename plans until verification succeeds; other content transforms MUST be inherently idempotent or re-planned, and restore rolls back config and databases while content remains in its forward-compatible migrated form.

Phase 11 — Delete compatibility code

Completion requires zero production references, outside migration/archive code, to:

TYPE_DIRS
AkmAssetType
parseAssetRef
wikiName
StashEntry
resolveStashDir
bundle-local .akm state

The migration-only old-layout reader is then deleted.


31. Testing requirements

31.1 Adapter conformance

Every adapter MUST have tests for:

31.2 Search parity

Migration tests MUST compare old and new indexing on a frozen corpus and require approved thresholds for:

31.3 Transaction safety

Test:

31.4 Improve and memory

Test:

31.5 Architecture contracts

Static or runtime architecture tests SHOULD prove:


32. Acceptance criteria

Staging: these criteria describe the completed target architecture, not the 0.9.0 release. Criteria 11 and 13 (binding record/digests) are Tier B (§18 staging note); criteria 21–22 (memory lifecycle) are staged behind the claim extractor (§25 staging note); 0.9.0's own gates are the plan's §12.2 DoD.

The target architecture is complete when:

  1. AKM installs bundles containing one or multiple native components.
  2. OKF, LLM Wiki, Claude, OpenCode, Agent Skills, website snapshots, workflows, tasks, and environment definitions are supported without core asset types.
  3. Search uses one local index and performs no adapter, provider, registry, or network calls.
  4. Search quality meets the frozen parity gates, including filter-behavior and whyMatched parity (§14.4).
  5. show reads the indexed absolute path directly (subject to the §15.3 sensitivity exception).
  6. Indexing never mutates bundle content.
  7. Conventions and authoring rules are adapter-owned.
  8. Hard-rule prompt text and validation derive from one adapter rule source.
  9. Installation alone grants no execution, scheduling, tools, environment values, or secrets.
  10. Workflows, tasks, environments, agents, commands, skills, and scripts can be distributed as bundle exports.
  11. Bindings pin export digest and local runtime policy, and store secret references only (§28.4).
  12. In-flight workflows remain stable across bundle updates.
  13. Enabled tasks do not silently change when package definitions update.
  14. Environment and secret values never enter the index or output.
  15. Website bundles refresh safely and can export into writable native bundles.
  16. Proposals contain multi-file changes and before hashes.
  17. Transactions are journaled, recoverable, exact-path committed, and reversible.
  18. Model confidence cannot authorize semantic publication.
  19. Improve implements evidence-driven revise, learn, and consolidate operations.
  20. Same-run semantic self-feeding is absent.
  21. Memory-capable components enforce high-water, retirement, archive, purge, and backpressure policies.
  22. Unattended semantic memory retirement requires claim coverage and retrieval/task non-regression; reviewed retirement requires proposal approval (§25.6). Until the claim extractor passes its benchmark, unattended semantic retirement is off.
  23. Workspace state is confined to config/data/cache locations.
  24. state.db, index.db, and logs.db are the only databases.
  25. Registry discovery is separate from installed-content search.
  26. Wiki-specific core commands and wikiName are removed; the LLM Wiki adapter is a first-class built-in.
  27. AssetSpec, AkmAssetType, TYPE_DIRS, global matchers, type-competition renderer/action registries, and StashEntry are removed.
  28. The one-time old-layout migration is dry-runnable, backed up, idempotent, recoverable, and fully tested — including an orphan-bearing fixture that completes with quarantine (§11.4).
  29. All temporary compatibility seams have named deletion milestones and are deleted.
  30. Production code is materially smaller and the net-complexity reduction is reported, with the restored bindings/memory-lifecycle additions accounted as a signed adds line. (A v0.2 criterion 31 on untrusted-content labeling/clamping was withdrawn in v0.3 — deviation §4.3c.)

33. Deferred decisions

The following are intentionally deferred until implementation evidence is available:

These decisions MUST NOT block the foundational bundle, index, transaction, and memory-lifecycle work.


34. References

Formats and progressive disclosure

  1. Open Knowledge Format specification
  2. Open Knowledge Format README and reference implementation
  3. Agent Skills specification
  4. OpenViking context layers
  5. Model Context Protocol server concepts
  6. Claude Code memory and instruction hierarchy
  7. Claude Code custom subagents
  8. OpenCode rules and precedence
  9. OpenCode agents

Agent improvement and evaluation

  1. Anthropic: Building effective agents
  2. Reflexion: Language Agents with Verbal Reinforcement Learning
  3. Voyager: An Open-Ended Embodied Agent with Large Language Models
  4. Self-Refine: Iterative Refinement with Self-Feedback
  5. Large Language Models Cannot Self-Correct Reasoning Yet
  6. GEPA: Reflective Prompt Evolution Can Outperform Reinforcement Learning
  7. Darwin Gödel Machine: Open-Ended Evolution of Self-Improving Agents
  8. AlphaEvolve
  9. Judging LLM-as-a-Judge with MT-Bench and Chatbot Arena
  10. Judging the Judges: A Systematic Study of Position Bias in LLM-as-a-Judge

Memory systems

  1. Generative Agents: Interactive Simulacra of Human Behavior
  2. Zep: A Temporal Knowledge Graph Architecture for Agent Memory
  3. A-MEM: Agentic Memory for LLM Agents
  4. All-Mem: Agentic Lifelong Memory via Dynamic Topology Evolution
  5. E-mem: Multi-agent based Episodic Context Reconstruction for LLM Agent Memory

Modernization and delivery

  1. Martin Fowler: Strangler Fig
  2. Martin Fowler: Sacrificial Architecture
  3. Joel Spolsky: Things You Should Never Do, Part I
  4. Software Engineering at Google: Large-Scale Changes

AKM implementation context

  1. AKM repository
  2. AKM PR #718
  3. Current asset specification
  4. Current broad metadata model
  5. Current proposal transaction implementation
  6. Current consolidation implementation
  7. Current source-provider contract
  8. Current portable task schema
  9. Current workflow loader