{"_id":"@aman_asmuei/acore-core","_rev":"4-a91845acfe2d436ec067e577badbf4cb","name":"@aman_asmuei/acore-core","dist-tags":{"latest":"0.2.0"},"versions":{"0.1.0":{"name":"@aman_asmuei/acore-core","version":"0.1.0","keywords":["aman","acore","identity","multi-tenant","ai-companion","ecosystem"],"author":{"name":"Aman Asmuei"},"license":"MIT","_id":"@aman_asmuei/acore-core@0.1.0","maintainers":[{"name":"aman_asmuei","email":"amanasmuei@gmail.com"}],"homepage":"https://github.com/amanasmuei/acore-core#readme","bugs":{"url":"https://github.com/amanasmuei/acore-core/issues"},"dist":{"shasum":"95a9a47062e1acd85f161fb2819381f0d24a5fb3","tarball":"https://registry.npmjs.org/@aman_asmuei/acore-core/-/acore-core-0.1.0.tgz","fileCount":27,"integrity":"sha512-hndPs2kZ/npwEK/e+Bwy9wfRiFtOrAHHKDOK/6Ozs7AYhRD0Mbt8uf8Pj+TDlJwN2Svp64O6PizXi7Meq2EvyA==","signatures":[{"sig":"MEUCIQDiLbNQ1XVsHS6QTKz8feV8CNXjfehQbZRhMxsJpn5hRQIgJcW8GxXkrmBT2F1y8ftcYF6PMhcmdSfqiCDyBtRKYhI=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":57692},"main":"./dist/index.js","type":"module","types":"./dist/index.d.ts","engines":{"node":">=18.0.0"},"exports":{".":{"types":"./dist/index.d.ts","default":"./dist/index.js"}},"gitHead":"e5953097604f46a0b7ad7e57b61341359977732d","scripts":{"dev":"tsc --watch","lint":"tsc --noEmit","test":"vitest run","build":"tsc","prepare":"npm run build","test:watch":"vitest"},"_npmUser":{"name":"aman_asmuei","email":"amanasmuei@gmail.com"},"repository":{"url":"git+https://github.com/amanasmuei/acore-core.git","type":"git"},"_npmVersion":"10.9.7","description":"The identity layer for the aman ecosystem — multi-tenant Identity records over MarkdownFileStorage (dev) and DatabaseStorage (server), built on @aman_asmuei/aman-core.","directories":{},"_nodeVersion":"22.22.2","dependencies":{"better-sqlite3":"^12.0.0","@aman_asmuei/aman-core":"^0.2.0"},"_hasShrinkwrap":false,"devDependencies":{"vitest":"^3.0.0","typescript":"^5.7.0","@types/node":"^22.0.0","@types/better-sqlite3":"^7.6.0"},"_npmOperationalInternal":{"tmp":"tmp/acore-core_0.1.0_1775555263821_0.9011747654364259","host":"s3://npm-registry-packages-npm-production"},"deprecated":"Superseded by the aman-agentic package (npx -p aman-agentic aman-mcp / aman). Source: github.com/amanasmuei/aman-substrate"},"0.1.1":{"name":"@aman_asmuei/acore-core","version":"0.1.1","keywords":["aman","acore","identity","multi-tenant","ai-companion","ecosystem"],"author":{"name":"Aman Asmuei"},"license":"MIT","_id":"@aman_asmuei/acore-core@0.1.1","maintainers":[{"name":"aman_asmuei","email":"amanasmuei@gmail.com"}],"homepage":"https://github.com/amanasmuei/acore-core#readme","bugs":{"url":"https://github.com/amanasmuei/acore-core/issues"},"dist":{"shasum":"9b6f21733a95f6ddbb8504db2e3a870ec088d2d8","tarball":"https://registry.npmjs.org/@aman_asmuei/acore-core/-/acore-core-0.1.1.tgz","fileCount":27,"integrity":"sha512-oxPX1+XsviJtVbwuvYsKDPUYVv7kitvVarQtphPtlyWszLxNNNEFFDAI8dL9sIStx6y0iMmvCv75A5RNMUgy7Q==","signatures":[{"sig":"MEQCIEx043K3XCJcjE+jW6qNVlGMp+0jlE9EHbO+CmHh/8EYAiAspwVrw7o1s3XhxM8szvKLBtKOhBO+dUGJr+OVkOSYgQ==","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":57869},"main":"./dist/index.js","type":"module","types":"./dist/index.d.ts","engines":{"node":">=18.0.0"},"exports":{".":{"types":"./dist/index.d.ts","default":"./dist/index.js"}},"gitHead":"1c7f113f3f082c89802b52a9a87450a69d47536f","scripts":{"dev":"tsc --watch","lint":"tsc --noEmit","test":"vitest run","build":"tsc","prepare":"npm run build","test:watch":"vitest"},"_npmUser":{"name":"aman_asmuei","email":"amanasmuei@gmail.com"},"repository":{"url":"git+https://github.com/amanasmuei/acore-core.git","type":"git"},"_npmVersion":"10.9.7","description":"The identity layer for the aman ecosystem — multi-tenant Identity records over MarkdownFileStorage (dev) and DatabaseStorage (server), built on @aman_asmuei/aman-core.","directories":{},"_nodeVersion":"22.22.2","dependencies":{"better-sqlite3":"^12.0.0","@aman_asmuei/aman-core":"^0.2.0"},"_hasShrinkwrap":false,"devDependencies":{"vitest":"^3.0.0","typescript":"^5.7.0","@types/node":"^22.0.0","@types/better-sqlite3":"^7.6.0"},"_npmOperationalInternal":{"tmp":"tmp/acore-core_0.1.1_1775577998000_0.468277409881654","host":"s3://npm-registry-packages-npm-production"},"deprecated":"Superseded by the aman-agentic package (npx -p aman-agentic aman-mcp / aman). Source: github.com/amanasmuei/aman-substrate"},"0.2.0":{"name":"@aman_asmuei/acore-core","version":"0.2.0","keywords":["aman","acore","identity","multi-tenant","ai-companion","ecosystem"],"author":{"name":"Aman Asmuei"},"license":"MIT","_id":"@aman_asmuei/acore-core@0.2.0","maintainers":[{"name":"aman_asmuei","email":"amanasmuei@gmail.com"}],"homepage":"https://github.com/amanasmuei/acore-core#readme","bugs":{"url":"https://github.com/amanasmuei/acore-core/issues"},"dist":{"shasum":"23ac695dc0c91fd9083ca0f21d5e45d1b0b0b2ee","tarball":"https://registry.npmjs.org/@aman_asmuei/acore-core/-/acore-core-0.2.0.tgz","fileCount":27,"integrity":"sha512-RCJ3WnkTxRzBMmjWYMrW85oEhYQwmPITutPtizsGYVJ1jN/X9EI66s+KlohLKxCqpuyD3GBjaVi0kQRIBjf1vg==","signatures":[{"sig":"MEUCIQCjxQ11NjQ4ZdRL7DFoIY5gmda3a7jFHKAlrn3EjetCbwIgVrzC7GTw9wmSbCDxt8MRbACExkQdWLByaTYDFTtfRfU=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":59424},"main":"./dist/index.js","type":"module","types":"./dist/index.d.ts","engines":{"node":">=18.0.0"},"exports":{".":{"types":"./dist/index.d.ts","default":"./dist/index.js"}},"gitHead":"c6822f8dd429587b214df49a80bf7a2fced0bae3","scripts":{"dev":"tsc --watch","lint":"tsc --noEmit","test":"vitest run","build":"tsc","prepare":"npm run build","test:watch":"vitest"},"_npmUser":{"name":"aman_asmuei","email":"amanasmuei@gmail.com"},"repository":{"url":"git+https://github.com/amanasmuei/acore-core.git","type":"git"},"_npmVersion":"10.9.7","description":"The identity layer for the aman ecosystem — multi-tenant Identity records over MarkdownFileStorage (dev) and DatabaseStorage (server), built on @aman_asmuei/aman-core.","directories":{},"_nodeVersion":"22.22.2","dependencies":{"better-sqlite3":"^12.0.0","@aman_asmuei/aman-core":"^0.3.0"},"_hasShrinkwrap":false,"devDependencies":{"vitest":"^3.0.0","typescript":"^5.7.0","@types/node":"^22.0.0","@types/better-sqlite3":"^7.6.0"},"_npmOperationalInternal":{"tmp":"tmp/acore-core_0.2.0_1775745257502_0.3462024661945655","host":"s3://npm-registry-packages-npm-production"},"deprecated":"Superseded by the aman-agentic package (npx -p aman-agentic aman-mcp / aman). Source: github.com/amanasmuei/aman-substrate"}},"time":{"created":"2026-04-07T09:47:43.710Z","modified":"2026-06-10T08:37:27.894Z","0.1.0":"2026-04-07T09:47:43.966Z","0.1.1":"2026-04-07T16:06:38.169Z","0.2.0":"2026-04-09T14:34:17.717Z"},"bugs":{"url":"https://github.com/amanasmuei/acore-core/issues"},"author":{"name":"Aman Asmuei"},"license":"MIT","homepage":"https://github.com/amanasmuei/acore-core#readme","keywords":["aman","acore","identity","multi-tenant","ai-companion","ecosystem"],"repository":{"url":"git+https://github.com/amanasmuei/acore-core.git","type":"git"},"description":"The identity layer for the aman ecosystem — multi-tenant Identity records over MarkdownFileStorage (dev) and DatabaseStorage (server), built on @aman_asmuei/aman-core.","maintainers":[{"name":"aman_asmuei","email":"amanasmuei@gmail.com"}],"readme":"<div align=\"center\">\n\n# @aman_asmuei/acore-core\n\n**The identity layer for the aman ecosystem.**\n\nMulti-tenant `Identity` records — markdown blobs with surgical section\nhelpers, auto-routing storage, and a stable library API. The same\nidentity engine that powers Claude Code's persistent memory, the CLI\nagent, and Telegram super-app users.\n\n[![npm version](https://img.shields.io/npm/v/@aman_asmuei/acore-core?style=for-the-badge&logo=npm&logoColor=white&color=cb3837)](https://www.npmjs.com/package/@aman_asmuei/acore-core)\n[![License: MIT](https://img.shields.io/badge/license-MIT-blue?style=for-the-badge)](LICENSE)\n[![Node ≥18](https://img.shields.io/badge/node-%E2%89%A518-brightgreen?style=for-the-badge&logo=node.js&logoColor=white)](https://nodejs.org)\n[![TypeScript](https://img.shields.io/badge/TypeScript-strict-3178c6?style=for-the-badge&logo=typescript&logoColor=white)](https://www.typescriptlang.org)\n[![Tests](https://img.shields.io/badge/tests-57_passing-brightgreen?style=for-the-badge)](#quality-signals)\n[![Part of aman](https://img.shields.io/badge/part_of-aman_ecosystem-ff6b35?style=for-the-badge)](https://github.com/amanasmuei/aman)\n\n[Install](#install) &middot;\n[Quick start](#quick-start) &middot;\n[Why markdown-blob](#why-markdown-blob) &middot;\n[Concepts](#concepts) &middot;\n[API reference](#api-reference) &middot;\n[The aman ecosystem](#the-aman-ecosystem)\n\n</div>\n\n---\n\n## What it is\n\n`acore-core` is the identity layer of the aman engine. It manages \"what\nthe AI knows about you\" — your name, role, personality, current emotional\nread, dynamic context — as a structured but flexible markdown document,\nwith a programmable library API.\n\n**One identity per scope.** The same package serves your local dev identity\n(`dev:default`), your Claude Code session identity (`dev:plugin`), per-agent\npersonalities (`agent:jiran`), and per-user identities for thousands of\nTelegram users (`tg:12345`) — all from one library, with complete state\nisolation between scopes.\n\nThis package extracts a programmable library API out of the existing\n`@aman_asmuei/acore` CLI. The CLI keeps working unchanged. New consumers\n(`aman-mcp`, `aman-agent`, `aman-tg` backend, future tools) call this\nlibrary directly instead of reading `~/.acore/core.md` via filesystem and regex.\n\n---\n\n## Why markdown-blob\n\n`Identity` is intentionally **a markdown string**, not a typed struct:\n\n```typescript\ninterface Identity {\n  content: string;  // the full markdown of the identity file\n}\n```\n\nThree reasons:\n\n1. **Hand-editable.** A user can `vim ~/.acore/dev/default/core.md` and\n   the AI immediately knows the new thing. No SQL editor, no admin UI.\n2. **Git-versionable.** `cd ~/.acore && git init` and you have a full\n   personality history. No other AI personality system gives you this.\n3. **Backward compatible.** The existing `acore` CLI templates already\n   use this exact markdown shape. Zero-migration adoption.\n\nThe schema-flexibility tradeoff is deliberate: there's no type safety on\nindividual sections, but the section helpers in this package give you\nergonomic access patterns without locking the schema. You can add a new\n`## Whatever` section to the markdown, and `getSection(identity, \"Whatever\")`\njust works.\n\n---\n\n## Install\n\n```bash\nnpm install @aman_asmuei/acore-core\n```\n\n`acore-core` depends on `@aman_asmuei/aman-core` for the scope substrate\nand `Storage<T>` interface. `better-sqlite3` is required at runtime if you\nuse the `DatabaseStorage` backend (i.e. for non-`dev:*` scopes).\n\n---\n\n## Quick start\n\n```typescript\nimport {\n  getIdentity,\n  getOrCreateIdentity,\n  updateSection,\n  updateDynamics,\n  getSectionContent,\n  type Identity,\n} from \"@aman_asmuei/acore-core\";\n\n// Dev side: backed by ~/.acore/dev/default/core.md (markdown file)\nawait updateSection(\"Personality\", \"Warm and direct\", \"dev:default\");\n\nconst personality = await getSectionContent(\"Personality\", \"dev:default\");\n// → \"Warm and direct\"\n\n// Telegram user 12345: backed by ~/.aman/engine.db acore_identities table\nawait updateSection(\n  \"Personality\",\n  \"Manglish, friendly, helpful\",\n  \"tg:12345\",\n);\n\n// Update emotional state surgically (without rewriting whole sections)\nawait updateDynamics(\n  {\n    currentRead: \"late-night, focused on shipping\",\n    energy: \"high-drive\",\n    activeMode: \"Focused Work\",\n  },\n  \"dev:default\",\n);\n\n// Bootstrap a new identity from the default template\nconst identity = await getOrCreateIdentity(\"agent:jiran\");\n// Returns Jiran's identity record, creating it from a default markdown\n// template if it doesn't exist\n```\n\nThat's the whole API for 90% of use cases. **Same call, different scope,\ndifferent storage backend, complete state isolation.** No parameter\nthreading, no scope leakage.\n\n---\n\n## Concepts\n\n### Identity record\n\n`Identity` is a markdown blob:\n\n```typescript\ninterface Identity {\n  content: string;\n}\n```\n\nThe content follows the `acore` CLI's existing template shape:\n\n```markdown\n# Aman\n\n> Your AI companion (scope: dev:default)\n\n## User\n- Name: Aman\n- Role: Founder, builder of the aman ecosystem\n\n## Personality\nWarm, direct, technically curious. KISS-first.\n\n## Session\n- Last updated: 2026-04-07\n- Resume: shipping engine v1 alpha\n- Active topics: aman-core, acore-core, multi-tenant scope\n\n## Dynamics\n- Current read: focused, late-night\n- Baseline energy: high-drive\n- Active mode: Focused Work\n```\n\nThe structure is convention, not a hard schema. You can add `## Goals`,\n`## Appearance`, `## Relationships`, or anything else — the helpers below\nwork on whatever section names you use.\n\n### Section helpers\n\nPure functions over `Identity` records:\n\n```typescript\nimport {\n  getSection,\n  setSection,\n  setBulletField,\n  getBulletField,\n  listSections,\n} from \"@aman_asmuei/acore-core\";\n\nconst identity: Identity = { content: existingMarkdown };\n\n// Read a section's body\nconst personality = getSection(identity, \"Personality\");\n// → \"Warm, direct, technically curious. KISS-first.\"\n\n// Replace a section's body (returns new Identity, doesn't mutate)\nconst updated = setSection(identity, \"Personality\", \"Direct and warm.\");\n\n// Surgical bullet update for `- Field: value` lines\nconst newIdentity = setBulletField(identity, \"Current read\", \"calm, evening\");\n\n// Read a single bullet\nconst role = getBulletField(identity, \"Role\"); // \"Founder, builder...\"\n\n// List all top-level sections\nconst sections = listSections(identity);\n// → [\"User\", \"Personality\", \"Session\", \"Dynamics\"]\n```\n\nThe section parser is a simple line-based walker — no `m`-flag regex\ngotchas, no greediness surprises. It correctly handles section bodies that\nspan multiple lines, terminates at the next `## ` heading or `---`\nseparator or end-of-file, and ignores `### ` and lower headings.\n\n### Auto-routing storage — convention over configuration\n\n`acore-core` picks the right storage backend based on the scope's frontend\nprefix. You don't pass storage explicitly:\n\n| Scope prefix | Backend                | Where it persists                                  |\n|-------------|------------------------|----------------------------------------------------|\n| `dev:*`     | `MarkdownFileStorage`  | `~/.acore/{scope.replace(':','/')}/core.md`        |\n| `tg:*`      | `DatabaseStorage`      | `~/.aman/engine.db` table `acore_identities`       |\n| `agent:*`   | `DatabaseStorage`      | same                                                |\n| (other)     | `DatabaseStorage`      | same                                                |\n\n**Why this split?** Dev users want to hand-edit their identity in vim and\ncommit it to git. Telegram users at `tg:12345` need high-volume programmatic\nstorage with proper isolation. One library, two backends, picked by prefix.\n\nOverride the home directory via `$ACORE_HOME`. Override the engine DB\nlocation via `$AMAN_ENGINE_DB` (provided by `aman-core`).\n\n### Multi-tenant in practice\n\n```typescript\nimport { withScope } from \"@aman_asmuei/aman-core\";\nimport { getIdentity, updateSection } from \"@aman_asmuei/acore-core\";\n\n// In aman-tg's bot handler — every Telegram update gets its own scope:\nbot.on(\"message\", async (ctx) => {\n  const scope = `tg:${ctx.from.id}`;\n  await withScope(scope, async () => {\n    // No need to pass scope explicitly — it propagates via AsyncLocalStorage\n    const identity = await getIdentity();\n    if (!identity) {\n      await updateSection(\"User\", `- Name: ${ctx.from.first_name}`);\n    }\n    // ... handle the message\n  });\n});\n\n// Two concurrent users at the same instant — no bleed:\nawait Promise.all([\n  withScope(\"tg:alice\", () => updateSection(\"Personality\", \"Alice's vibe\")),\n  withScope(\"tg:bob\",   () => updateSection(\"Personality\", \"Bob's vibe\")),\n]);\n// → Alice's identity at tg:alice has \"Alice's vibe\"\n// → Bob's identity at tg:bob has \"Bob's vibe\"\n// → They never see each other's data, even though they ran in parallel\n```\n\nThis pattern is **proven in production** by `aman-tg`'s `apps/api/src/memory.ts`\nwhich has been using the same `tg:${telegramId}` convention for months.\n\n---\n\n## API reference\n\n### Read\n\n| Symbol                                       | Returns                  | Purpose                                                       |\n|---------------------------------------------|--------------------------|---------------------------------------------------------------|\n| `getIdentity(scope?)`                       | `Promise<Identity \\| null>` | Read identity for scope; null if missing                      |\n| `getOrCreateIdentity(scope?)`               | `Promise<Identity>`      | Read identity, bootstrapping from template if missing         |\n| `getSectionContent(name, scope?)`           | `Promise<string \\| null>`   | Read a single section's body                                  |\n| `listIdentityScopes()`                      | `Promise<{markdown, database}>` | List all stored scopes across both backends             |\n\n### Write\n\n| Symbol                                       | Returns        | Purpose                                                |\n|---------------------------------------------|----------------|--------------------------------------------------------|\n| `putIdentity(identity, scope?)`             | `Promise<void>` | Replace the entire identity                            |\n| `updateSection(name, content, scope?)`      | `Promise<void>` | Update one section's body; bootstraps if missing       |\n| `updateDynamics(update, scope?)`            | `Promise<void>` | Surgical update of `currentRead` / `energy` / `activeMode` bullets |\n| `deleteIdentity(scope?)`                    | `Promise<void>` | Remove the identity for a scope                        |\n\n### Pure section helpers\n\nFor when you already have an `Identity` in hand and don't want to round-trip storage:\n\n| Symbol                            | Returns       | Purpose                                          |\n|----------------------------------|---------------|--------------------------------------------------|\n| `getSection(identity, name)`     | `string \\| null` | Read a section's body                           |\n| `setSection(identity, name, c)`  | `Identity`    | Replace a section's body, return new Identity   |\n| `setBulletField(id, field, v)`   | `Identity`    | Update a `- field: value` bullet                |\n| `getBulletField(id, field)`      | `string \\| null` | Read a `- field: value` bullet                  |\n| `listSections(identity)`         | `string[]`    | List all top-level section names                 |\n\n### Storage routing\n\n| Symbol                          | Returns                       | Purpose                                          |\n|--------------------------------|-------------------------------|--------------------------------------------------|\n| `getStorageForScope(scope)`    | `Storage<Identity>`           | Pick the right backend for a scope              |\n| `getMarkdownStorage()`         | `MarkdownFileStorage<Identity>` | Cached singleton for `dev:*` scopes            |\n| `getDatabaseStorage()`         | `DatabaseStorage<Identity>`   | Cached singleton for everything else             |\n| `getAcoreHome()`               | `string`                      | Root directory (`$ACORE_HOME` or `~/.acore`)    |\n\n### Migration\n\n| Symbol                          | Returns                  | Purpose                                          |\n|--------------------------------|--------------------------|--------------------------------------------------|\n| `migrateLegacyAcoreFile()`     | `AcoreMigrationReport`   | One-time copy of `~/.acore/core.md` → `~/.acore/dev/default/core.md` |\n| `defaultIdentityTemplate(scope)` | `Identity`             | Default markdown template for a new scope        |\n\nThe legacy migration is idempotent and **never deletes** the legacy file.\nSafe to call multiple times.\n\n---\n\n## Architecture\n\n`acore-core` is one of three \"essential\" layer libraries in the aman engine v1:\n\n```\n                    ┌──────────────────────────┐\n                    │     aman engine v1       │\n                    │                          │\n                    │  ┌────────────────────┐  │\n                    │  │   aman-core        │  │ ← shared substrate\n                    │  │   Scope, Storage   │  │\n                    │  └─────────┬──────────┘  │\n                    │            │             │\n                    │       ┌────┴─────┐       │\n                    │       │          │       │\n                    │       ▼          ▼       │\n                    │  ┌─────────┐ ┌─────────┐ │\n                    │  │ acore-  │ │ arules- │ │\n                    │  │ core    │ │ core    │ │\n                    │  │ ←YOU    │ │         │ │\n                    │  │ identity│ │ rules   │ │\n                    │  └─────────┘ └─────────┘ │\n                    └──────────────────────────┘\n                              ▲\n                              │ consumed by\n        ┌─────────────────────┼─────────────────────┐\n        ▼                     ▼                     ▼\n   aman-mcp             aman-agent              aman-tg\n   (MCP server         (CLI runtime)         (Telegram backend)\n    aggregator)\n```\n\n**Where consumers use it**:\n\n- `aman-mcp` exposes `acore-core` via MCP tools (`identity_read`,\n  `identity_summary`, `identity_update_section`, `identity_update_dynamics`,\n  `avatar_prompt`) — all scope-aware\n- `aman-agent` calls `acore-core` directly from its `/identity` slash command\n- `aman-tg`'s per-user agents store per-Telegram-user personalities through\n  `acore-core` with `tg:${telegramId}` scopes (planned)\n\n---\n\n## What this is NOT\n\nTo stay focused, `acore-core` deliberately does not provide:\n\n- **Authentication.** Identity ≠ auth. `acore-core` manages \"what the AI\n  knows about you,\" not \"who you are to the system.\" Use your existing\n  auth system; pass the user ID in as the scope.\n- **Personality generation.** This is storage + helpers, not an LLM\n  prompt-engineering library.\n- **Schema enforcement.** The markdown blob is intentionally flexible.\n  Add or remove sections as needed.\n- **A CLI.** That's `@aman_asmuei/acore`. This package is the library\n  the CLI will eventually wrap.\n\n---\n\n## Quality signals\n\n- **57 unit tests, all passing**, across 3 test files:\n  - `identity.test.ts` — 21 tests covering section parsing, mutation, special\n    chars in section names, multi-line bodies, bullet field updates, isolation\n  - `api.test.ts` — 29 tests covering scope routing, get/update/delete,\n    `withScope` propagation, multi-tenant isolation, dev-vs-tg backend split\n  - `migrate.test.ts` — 7 tests covering idempotent legacy migration with\n    byte-exact preservation\n- **`tsc --noEmit` clean** with `strict` mode\n- **A real bug was caught during testing**: the section parser initially used\n  the `m` regex flag which made `$` match end-of-line, collapsing section\n  bodies to a single line. The fix is documented in the source. Tests caught\n  it on the first run.\n\n---\n\n## The aman ecosystem\n\n`acore-core` is one of several packages in the aman AI companion ecosystem:\n\n| Layer                                                                   | Role                                                |\n|------------------------------------------------------------------------|-----------------------------------------------------|\n| [@aman_asmuei/aman-core](https://github.com/amanasmuei/aman-core)       | Substrate — Scope, Storage, withScope               |\n| **[@aman_asmuei/acore-core](https://github.com/amanasmuei/acore-core)** | **Identity layer (this package)**                   |\n| [@aman_asmuei/arules-core](https://github.com/amanasmuei/arules-core)   | Guardrails layer — rule parsing and runtime checks  |\n| [@aman_asmuei/amem-core](https://github.com/amanasmuei/amem)            | Memory layer — semantic recall, embeddings          |\n| [@aman_asmuei/aman-mcp](https://github.com/amanasmuei/aman-mcp)         | MCP server aggregating all layers for any host      |\n| [@aman_asmuei/aman-agent](https://github.com/amanasmuei/aman-agent)     | Standalone CLI runtime, multi-LLM, scope-aware      |\n| [@aman_asmuei/acore](https://github.com/amanasmuei/acore)               | Single-user CLI — predates this library             |\n| [aman-plugin](https://github.com/amanasmuei/aman-plugin)                | Claude Code plugin (hooks + skills + MCP installer) |\n| [@aman_asmuei/aman](https://github.com/amanasmuei/aman)                 | Umbrella installer — one command for the ecosystem  |\n\n---\n\n## License\n\n[MIT](LICENSE) © Aman Asmuei\n\n---\n\n<div align=\"center\">\n  <sub>Built with ❤️ in 🇲🇾 <strong>Malaysia</strong> · Part of the <a href=\"https://github.com/amanasmuei\">aman ecosystem</a></sub>\n</div>\n","readmeFilename":"README.md"}