{
  "schemaVersion": 1,
  "sensitiveFieldsExcluded": true,
  "generatedAt": "1970-01-01T00:00:00.000Z",
  "packageName": "@happyvertical/smrt-personas",
  "packageVersion": "0.51.10",
  "sourceManifestPath": "dist/manifest.json",
  "agentDocPath": "AGENTS.md",
  "sourceHashes": {
    "manifest": "2c135e1ebc01a1f64822707821f9140aae3371c4aa1f122c5ca28e5ba2c788f9",
    "packageJson": "05f2fef935bb561d31f790e356014344690daae484313747f15a0606e8106e4e",
    "agents": "fe6c54f7d6c724b76906629eeb7bd17a332faad631179771acea73db1e159733"
  },
  "exports": [
    ".",
    "./manifest",
    "./manifest.json",
    "./svelte"
  ],
  "dependencies": {
    "@happyvertical/smrt-agents": "workspace:*",
    "@happyvertical/smrt-core": "workspace:*",
    "@happyvertical/smrt-messages": "workspace:*",
    "@happyvertical/smrt-prompts": "workspace:*",
    "@happyvertical/smrt-tenancy": "workspace:*",
    "@happyvertical/smrt-ui": "workspace:*",
    "@happyvertical/smrt-users": "workspace:*",
    "@happyvertical/sql": "catalog:",
    "@happyvertical/smrt-vitest": "workspace:*",
    "@sveltejs/package": "^2.5.8",
    "@sveltejs/vite-plugin-svelte": "^7.1.2",
    "@types/node": "24.13.2",
    "svelte": "^5.56.4",
    "svelte-check": "^4.7.1",
    "typescript": "5.9.3",
    "vite": "8.1.4",
    "vitest": "4.1.10"
  },
  "smrtDependencies": [
    "@happyvertical/smrt-agents",
    "@happyvertical/smrt-core",
    "@happyvertical/smrt-messages",
    "@happyvertical/smrt-prompts",
    "@happyvertical/smrt-tenancy",
    "@happyvertical/smrt-ui",
    "@happyvertical/smrt-users",
    "@happyvertical/smrt-vitest"
  ],
  "sdkDependencies": [
    "@happyvertical/sql"
  ],
  "tags": [
    "agents",
    "cross-package",
    "multi-tenant",
    "personas",
    "resolution",
    "smrt"
  ],
  "risks": [
    "cross-package-refs:2",
    "sensitive-fields-excluded"
  ],
  "objects": [
    {
      "name": "AgentPersona",
      "qualifiedName": "@happyvertical/smrt-personas:AgentPersona",
      "collection": "agentpersonas",
      "tableName": "agent_personas",
      "packageName": "@happyvertical/smrt-personas",
      "extends": "SmrtObject",
      "fields": [
        {
          "name": "tenantId",
          "type": "text",
          "required": true,
          "columnType": "UUID"
        },
        {
          "name": "agentClass",
          "type": "text",
          "required": false,
          "columnType": "TEXT"
        },
        {
          "name": "name",
          "type": "text",
          "required": false,
          "columnType": "TEXT",
          "default": ""
        },
        {
          "name": "contextType",
          "type": "text",
          "required": false,
          "columnType": "TEXT"
        },
        {
          "name": "contextId",
          "type": "text",
          "required": false,
          "columnType": "TEXT"
        },
        {
          "name": "instructions",
          "type": "text",
          "required": false,
          "columnType": "TEXT"
        },
        {
          "name": "allowedTools",
          "type": "text",
          "required": false,
          "columnType": "TEXT"
        },
        {
          "name": "runAsUserId",
          "type": "crossPackageRef",
          "required": true,
          "related": "@happyvertical/smrt-users:User",
          "columnType": "UUID"
        },
        {
          "name": "actsAsProfileId",
          "type": "crossPackageRef",
          "required": false,
          "related": "@happyvertical/smrt-profiles:Profile",
          "columnType": "UUID"
        },
        {
          "name": "memoryScope",
          "type": "text",
          "required": false,
          "columnType": "TEXT"
        },
        {
          "name": "priority",
          "type": "integer",
          "required": false,
          "columnType": "INTEGER",
          "default": 0
        },
        {
          "name": "enabled",
          "type": "boolean",
          "required": false,
          "columnType": "BOOLEAN"
        }
      ],
      "relationships": [
        {
          "name": "runAsUserId",
          "type": "crossPackageRef",
          "required": true,
          "related": "@happyvertical/smrt-users:User",
          "columnType": "UUID"
        },
        {
          "name": "actsAsProfileId",
          "type": "crossPackageRef",
          "required": false,
          "related": "@happyvertical/smrt-profiles:Profile",
          "columnType": "UUID"
        }
      ],
      "methods": [
        "getAllowedTools",
        "setAllowedTools"
      ],
      "methodSignatures": [
        {
          "name": "getAllowedTools",
          "returns": "string[]"
        },
        {
          "name": "setAllowedTools",
          "params": [
            "tools: string[]"
          ],
          "returns": "void"
        }
      ],
      "tenant": {
        "scoped": true,
        "mode": "required",
        "field": "tenantId"
      },
      "conflictColumns": [
        "tenant_id",
        "agent_class",
        "name"
      ],
      "surfaces": [
        {
          "kind": "api",
          "name": "agentpersonas.list",
          "operation": "list",
          "objectName": "@happyvertical/smrt-personas:AgentPersona",
          "path": "/agentpersonas",
          "method": "GET"
        },
        {
          "kind": "api",
          "name": "agentpersonas.get",
          "operation": "get",
          "objectName": "@happyvertical/smrt-personas:AgentPersona",
          "path": "/agentpersonas/[id]",
          "method": "GET"
        },
        {
          "kind": "api",
          "name": "agentpersonas.create",
          "operation": "create",
          "objectName": "@happyvertical/smrt-personas:AgentPersona",
          "path": "/agentpersonas",
          "method": "POST"
        },
        {
          "kind": "api",
          "name": "agentpersonas.update",
          "operation": "update",
          "objectName": "@happyvertical/smrt-personas:AgentPersona",
          "path": "/agentpersonas/[id]",
          "method": "PATCH"
        },
        {
          "kind": "api",
          "name": "agentpersonas.delete",
          "operation": "delete",
          "objectName": "@happyvertical/smrt-personas:AgentPersona",
          "path": "/agentpersonas/[id]",
          "method": "DELETE"
        },
        {
          "kind": "cli",
          "name": "agentpersona_list",
          "operation": "list",
          "objectName": "@happyvertical/smrt-personas:AgentPersona"
        },
        {
          "kind": "cli",
          "name": "agentpersona_get",
          "operation": "get",
          "objectName": "@happyvertical/smrt-personas:AgentPersona"
        },
        {
          "kind": "mcp",
          "name": "agentpersona_list",
          "operation": "list",
          "objectName": "@happyvertical/smrt-personas:AgentPersona"
        },
        {
          "kind": "mcp",
          "name": "agentpersona_get",
          "operation": "get",
          "objectName": "@happyvertical/smrt-personas:AgentPersona"
        }
      ],
      "withheldSurfaces": [
        {
          "kind": "api",
          "operation": "getAllowedTools",
          "code": "not-included",
          "reason": "not listed in api.include",
          "objectName": "@happyvertical/smrt-personas:AgentPersona"
        },
        {
          "kind": "api",
          "operation": "setAllowedTools",
          "code": "not-included",
          "reason": "not listed in api.include",
          "objectName": "@happyvertical/smrt-personas:AgentPersona"
        }
      ],
      "relationshipFeatures": [
        "crossPackageRef",
        "uuidColumns"
      ],
      "tags": [],
      "risks": []
    },
    {
      "name": "AgentPersonaCollection",
      "qualifiedName": "@happyvertical/smrt-personas:AgentPersonaCollection",
      "collection": "agentpersonas",
      "tableName": "agent_personas",
      "packageName": "@happyvertical/smrt-personas",
      "extends": "SmrtCollection",
      "fields": [],
      "relationships": [],
      "methods": [
        "byTenantAndClass",
        "findActive"
      ],
      "methodSignatures": [
        {
          "name": "byTenantAndClass",
          "async": true,
          "params": [
            "tenantId: string",
            "agentClass: string"
          ],
          "returns": "Promise<AgentPersona[]>"
        },
        {
          "name": "findActive",
          "async": true,
          "params": [
            "tenantId: string",
            "agentClass: string",
            "context?: object"
          ],
          "returns": "Promise<AgentPersona[]>"
        }
      ],
      "surfaces": [
        {
          "kind": "api",
          "name": "agentpersonas.byTenantAndClass",
          "operation": "byTenantAndClass",
          "objectName": "@happyvertical/smrt-personas:AgentPersonaCollection",
          "path": "/agentpersonas/byTenantAndClass",
          "method": "POST"
        },
        {
          "kind": "api",
          "name": "agentpersonas.findActive",
          "operation": "findActive",
          "objectName": "@happyvertical/smrt-personas:AgentPersonaCollection",
          "path": "/agentpersonas/findActive",
          "method": "POST"
        },
        {
          "kind": "cli",
          "name": "agentpersonacollection_byTenantAndClass",
          "operation": "byTenantAndClass",
          "objectName": "@happyvertical/smrt-personas:AgentPersonaCollection"
        },
        {
          "kind": "cli",
          "name": "agentpersonacollection_findActive",
          "operation": "findActive",
          "objectName": "@happyvertical/smrt-personas:AgentPersonaCollection"
        },
        {
          "kind": "mcp",
          "name": "agentpersonacollection_bytenantandclass",
          "operation": "byTenantAndClass",
          "objectName": "@happyvertical/smrt-personas:AgentPersonaCollection"
        },
        {
          "kind": "mcp",
          "name": "agentpersonacollection_findactive",
          "operation": "findActive",
          "objectName": "@happyvertical/smrt-personas:AgentPersonaCollection"
        }
      ],
      "relationshipFeatures": [
        "uuidColumns"
      ],
      "tags": [],
      "risks": []
    },
    {
      "name": "DirectiveProposal",
      "qualifiedName": "@happyvertical/smrt-personas:DirectiveProposal",
      "collection": "directiveproposals",
      "tableName": "directive_proposals",
      "packageName": "@happyvertical/smrt-personas",
      "extends": "SmrtObject",
      "fields": [
        {
          "name": "tenantId",
          "type": "text",
          "required": true,
          "columnType": "UUID"
        },
        {
          "name": "personaId",
          "type": "foreignKey",
          "required": true,
          "related": "AgentPersona",
          "columnType": "UUID"
        },
        {
          "name": "agentClass",
          "type": "text",
          "required": false,
          "columnType": "TEXT"
        },
        {
          "name": "promptKey",
          "type": "text",
          "required": false,
          "columnType": "TEXT"
        },
        {
          "name": "proposedInstructions",
          "type": "text",
          "required": false,
          "columnType": "TEXT"
        },
        {
          "name": "currentInstructions",
          "type": "text",
          "required": false,
          "columnType": "TEXT"
        },
        {
          "name": "rationale",
          "type": "text",
          "required": false,
          "columnType": "TEXT"
        },
        {
          "name": "evidence",
          "type": "text",
          "required": false,
          "columnType": "TEXT"
        },
        {
          "name": "status",
          "type": "text",
          "required": false,
          "columnType": "TEXT"
        },
        {
          "name": "fingerprint",
          "type": "text",
          "required": false,
          "columnType": "TEXT"
        },
        {
          "name": "confidence",
          "type": "decimal",
          "required": false,
          "columnType": "REAL",
          "default": 0
        },
        {
          "name": "proposedBy",
          "type": "text",
          "required": false,
          "columnType": "TEXT"
        },
        {
          "name": "reviewedBy",
          "type": "text",
          "required": false,
          "columnType": "TEXT"
        },
        {
          "name": "reviewedAt",
          "type": "datetime",
          "required": false,
          "columnType": "TIMESTAMP"
        },
        {
          "name": "reviewNote",
          "type": "text",
          "required": false,
          "columnType": "TEXT"
        },
        {
          "name": "activatedOverrideId",
          "type": "text",
          "required": false,
          "columnType": "TEXT"
        }
      ],
      "relationships": [
        {
          "name": "personaId",
          "type": "foreignKey",
          "required": true,
          "related": "AgentPersona",
          "columnType": "UUID"
        }
      ],
      "methods": [
        "getEvidence",
        "isPending",
        "setEvidence"
      ],
      "methodSignatures": [
        {
          "name": "getEvidence",
          "returns": "DirectiveEvidence"
        },
        {
          "name": "isPending",
          "returns": "boolean"
        },
        {
          "name": "setEvidence",
          "params": [
            "value: DirectiveEvidence"
          ],
          "returns": "void"
        }
      ],
      "tenant": {
        "scoped": true,
        "mode": "required",
        "field": "tenantId"
      },
      "conflictColumns": [
        "tenant_id",
        "slug",
        "context"
      ],
      "surfaces": [
        {
          "kind": "api",
          "name": "directiveproposals.list",
          "operation": "list",
          "objectName": "@happyvertical/smrt-personas:DirectiveProposal",
          "path": "/directiveproposals",
          "method": "GET"
        },
        {
          "kind": "api",
          "name": "directiveproposals.get",
          "operation": "get",
          "objectName": "@happyvertical/smrt-personas:DirectiveProposal",
          "path": "/directiveproposals/[id]",
          "method": "GET"
        },
        {
          "kind": "cli",
          "name": "directiveproposal_list",
          "operation": "list",
          "objectName": "@happyvertical/smrt-personas:DirectiveProposal"
        },
        {
          "kind": "cli",
          "name": "directiveproposal_get",
          "operation": "get",
          "objectName": "@happyvertical/smrt-personas:DirectiveProposal"
        },
        {
          "kind": "mcp",
          "name": "directiveproposal_list",
          "operation": "list",
          "objectName": "@happyvertical/smrt-personas:DirectiveProposal"
        },
        {
          "kind": "mcp",
          "name": "directiveproposal_get",
          "operation": "get",
          "objectName": "@happyvertical/smrt-personas:DirectiveProposal"
        }
      ],
      "withheldSurfaces": [
        {
          "kind": "api",
          "operation": "getEvidence",
          "code": "not-included",
          "reason": "not listed in api.include",
          "objectName": "@happyvertical/smrt-personas:DirectiveProposal"
        },
        {
          "kind": "api",
          "operation": "isPending",
          "code": "not-included",
          "reason": "not listed in api.include",
          "objectName": "@happyvertical/smrt-personas:DirectiveProposal"
        },
        {
          "kind": "api",
          "operation": "setEvidence",
          "code": "not-included",
          "reason": "not listed in api.include",
          "objectName": "@happyvertical/smrt-personas:DirectiveProposal"
        }
      ],
      "relationshipFeatures": [
        "foreignKey",
        "uuidColumns"
      ],
      "tags": [],
      "risks": []
    },
    {
      "name": "DirectiveProposalCollection",
      "qualifiedName": "@happyvertical/smrt-personas:DirectiveProposalCollection",
      "collection": "directiveproposals",
      "tableName": "directive_proposals",
      "packageName": "@happyvertical/smrt-personas",
      "extends": "SmrtCollection",
      "fields": [],
      "relationships": [],
      "methods": [
        "findByFingerprint",
        "pending"
      ],
      "methodSignatures": [
        {
          "name": "findByFingerprint",
          "async": true,
          "params": [
            "personaId: string",
            "fingerprint: string"
          ],
          "returns": "Promise<DirectiveProposal[]>"
        },
        {
          "name": "pending",
          "async": true,
          "params": [
            "options?: object"
          ],
          "returns": "Promise<DirectiveProposal[]>"
        }
      ],
      "surfaces": [
        {
          "kind": "api",
          "name": "directiveproposals.pending",
          "operation": "pending",
          "objectName": "@happyvertical/smrt-personas:DirectiveProposalCollection",
          "path": "/directiveproposals/pending",
          "method": "POST"
        },
        {
          "kind": "api",
          "name": "directiveproposals.findByFingerprint",
          "operation": "findByFingerprint",
          "objectName": "@happyvertical/smrt-personas:DirectiveProposalCollection",
          "path": "/directiveproposals/findByFingerprint",
          "method": "POST"
        },
        {
          "kind": "cli",
          "name": "directiveproposalcollection_pending",
          "operation": "pending",
          "objectName": "@happyvertical/smrt-personas:DirectiveProposalCollection"
        },
        {
          "kind": "cli",
          "name": "directiveproposalcollection_findByFingerprint",
          "operation": "findByFingerprint",
          "objectName": "@happyvertical/smrt-personas:DirectiveProposalCollection"
        },
        {
          "kind": "mcp",
          "name": "directiveproposalcollection_pending",
          "operation": "pending",
          "objectName": "@happyvertical/smrt-personas:DirectiveProposalCollection"
        },
        {
          "kind": "mcp",
          "name": "directiveproposalcollection_findbyfingerprint",
          "operation": "findByFingerprint",
          "objectName": "@happyvertical/smrt-personas:DirectiveProposalCollection"
        }
      ],
      "relationshipFeatures": [
        "uuidColumns"
      ],
      "tags": [],
      "risks": []
    },
    {
      "name": "Feedback",
      "qualifiedName": "@happyvertical/smrt-personas:Feedback",
      "collection": "feedbacks",
      "tableName": "agent_feedback",
      "packageName": "@happyvertical/smrt-personas",
      "extends": "SmrtObject",
      "fields": [
        {
          "name": "tenantId",
          "type": "text",
          "required": false,
          "columnType": "UUID"
        },
        {
          "name": "personaId",
          "type": "foreignKey",
          "required": true,
          "related": "AgentPersona",
          "columnType": "UUID"
        },
        {
          "name": "agentClass",
          "type": "text",
          "required": false,
          "columnType": "TEXT"
        },
        {
          "name": "memoryScope",
          "type": "text",
          "required": false,
          "columnType": "TEXT"
        },
        {
          "name": "scope",
          "type": "text",
          "required": false,
          "columnType": "TEXT"
        },
        {
          "name": "key",
          "type": "text",
          "required": false,
          "columnType": "TEXT"
        },
        {
          "name": "signalType",
          "type": "text",
          "required": false,
          "columnType": "TEXT"
        },
        {
          "name": "source",
          "type": "text",
          "required": false,
          "columnType": "TEXT"
        },
        {
          "name": "correlationId",
          "type": "text",
          "required": true,
          "columnType": "TEXT"
        },
        {
          "name": "correlationType",
          "type": "text",
          "required": false,
          "columnType": "TEXT"
        },
        {
          "name": "rating",
          "type": "decimal",
          "required": false,
          "columnType": "REAL"
        },
        {
          "name": "metric",
          "type": "decimal",
          "required": false,
          "columnType": "REAL"
        },
        {
          "name": "success",
          "type": "boolean",
          "required": false,
          "columnType": "BOOLEAN"
        },
        {
          "name": "correction",
          "type": "text",
          "required": false,
          "columnType": "TEXT"
        },
        {
          "name": "comment",
          "type": "text",
          "required": false,
          "columnType": "TEXT"
        },
        {
          "name": "actorId",
          "type": "text",
          "required": false,
          "columnType": "TEXT"
        },
        {
          "name": "metadata",
          "type": "text",
          "required": false,
          "columnType": "TEXT"
        },
        {
          "name": "reinforcedAt",
          "type": "datetime",
          "required": false,
          "columnType": "TIMESTAMP"
        }
      ],
      "relationships": [
        {
          "name": "personaId",
          "type": "foreignKey",
          "required": true,
          "related": "AgentPersona",
          "columnType": "UUID"
        }
      ],
      "methods": [
        "getCorrectionValue",
        "getMetadata",
        "isHuman",
        "setMetadata",
        "toLearningOutcome",
        "updateMetadata"
      ],
      "methodSignatures": [
        {
          "name": "getCorrectionValue",
          "returns": "string | undefined"
        },
        {
          "name": "getMetadata",
          "returns": "Record<string, unknown>"
        },
        {
          "name": "isHuman",
          "returns": "boolean"
        },
        {
          "name": "setMetadata",
          "params": [
            "value: Record<string, unknown>"
          ],
          "returns": "void"
        },
        {
          "name": "toLearningOutcome",
          "params": [
            "options?: FeedbackOutcomeOptions"
          ],
          "returns": "LearningOutcome | null"
        },
        {
          "name": "updateMetadata",
          "params": [
            "patch: Record<string, unknown>"
          ],
          "returns": "void"
        }
      ],
      "tenant": {
        "scoped": true,
        "mode": "optional",
        "field": "tenantId"
      },
      "conflictColumns": [
        "tenant_id",
        "slug",
        "context"
      ],
      "surfaces": [
        {
          "kind": "api",
          "name": "feedbacks.list",
          "operation": "list",
          "objectName": "@happyvertical/smrt-personas:Feedback",
          "path": "/feedbacks",
          "method": "GET"
        },
        {
          "kind": "api",
          "name": "feedbacks.get",
          "operation": "get",
          "objectName": "@happyvertical/smrt-personas:Feedback",
          "path": "/feedbacks/[id]",
          "method": "GET"
        },
        {
          "kind": "api",
          "name": "feedbacks.create",
          "operation": "create",
          "objectName": "@happyvertical/smrt-personas:Feedback",
          "path": "/feedbacks",
          "method": "POST"
        },
        {
          "kind": "cli",
          "name": "feedback_list",
          "operation": "list",
          "objectName": "@happyvertical/smrt-personas:Feedback"
        },
        {
          "kind": "cli",
          "name": "feedback_get",
          "operation": "get",
          "objectName": "@happyvertical/smrt-personas:Feedback"
        },
        {
          "kind": "mcp",
          "name": "feedback_list",
          "operation": "list",
          "objectName": "@happyvertical/smrt-personas:Feedback"
        },
        {
          "kind": "mcp",
          "name": "feedback_get",
          "operation": "get",
          "objectName": "@happyvertical/smrt-personas:Feedback"
        }
      ],
      "withheldSurfaces": [
        {
          "kind": "api",
          "operation": "getCorrectionValue",
          "code": "not-included",
          "reason": "not listed in api.include",
          "objectName": "@happyvertical/smrt-personas:Feedback"
        },
        {
          "kind": "api",
          "operation": "getMetadata",
          "code": "not-included",
          "reason": "not listed in api.include",
          "objectName": "@happyvertical/smrt-personas:Feedback"
        },
        {
          "kind": "api",
          "operation": "isHuman",
          "code": "not-included",
          "reason": "not listed in api.include",
          "objectName": "@happyvertical/smrt-personas:Feedback"
        },
        {
          "kind": "api",
          "operation": "setMetadata",
          "code": "not-included",
          "reason": "not listed in api.include",
          "objectName": "@happyvertical/smrt-personas:Feedback"
        },
        {
          "kind": "api",
          "operation": "toLearningOutcome",
          "code": "not-included",
          "reason": "not listed in api.include",
          "objectName": "@happyvertical/smrt-personas:Feedback"
        },
        {
          "kind": "api",
          "operation": "updateMetadata",
          "code": "not-included",
          "reason": "not listed in api.include",
          "objectName": "@happyvertical/smrt-personas:Feedback"
        }
      ],
      "relationshipFeatures": [
        "foreignKey",
        "uuidColumns"
      ],
      "tags": [],
      "risks": []
    },
    {
      "name": "FeedbackCollection",
      "qualifiedName": "@happyvertical/smrt-personas:FeedbackCollection",
      "collection": "feedbacks",
      "tableName": "agent_feedback",
      "packageName": "@happyvertical/smrt-personas",
      "extends": "SmrtCollection",
      "fields": [],
      "relationships": [],
      "methods": [
        "byCorrelation",
        "forPersona",
        "forScope"
      ],
      "methodSignatures": [
        {
          "name": "byCorrelation",
          "async": true,
          "params": [
            "correlationId: string"
          ],
          "returns": "Promise<Feedback[]>"
        },
        {
          "name": "forPersona",
          "async": true,
          "params": [
            "personaId: string",
            "options?: object"
          ],
          "returns": "Promise<Feedback[]>"
        },
        {
          "name": "forScope",
          "async": true,
          "params": [
            "memoryScope: string",
            "options?: object"
          ],
          "returns": "Promise<Feedback[]>"
        }
      ],
      "surfaces": [
        {
          "kind": "api",
          "name": "feedbacks.forPersona",
          "operation": "forPersona",
          "objectName": "@happyvertical/smrt-personas:FeedbackCollection",
          "path": "/feedbacks/forPersona",
          "method": "POST"
        },
        {
          "kind": "api",
          "name": "feedbacks.forScope",
          "operation": "forScope",
          "objectName": "@happyvertical/smrt-personas:FeedbackCollection",
          "path": "/feedbacks/forScope",
          "method": "POST"
        },
        {
          "kind": "api",
          "name": "feedbacks.byCorrelation",
          "operation": "byCorrelation",
          "objectName": "@happyvertical/smrt-personas:FeedbackCollection",
          "path": "/feedbacks/byCorrelation",
          "method": "POST"
        },
        {
          "kind": "cli",
          "name": "feedbackcollection_forPersona",
          "operation": "forPersona",
          "objectName": "@happyvertical/smrt-personas:FeedbackCollection"
        },
        {
          "kind": "cli",
          "name": "feedbackcollection_forScope",
          "operation": "forScope",
          "objectName": "@happyvertical/smrt-personas:FeedbackCollection"
        },
        {
          "kind": "cli",
          "name": "feedbackcollection_byCorrelation",
          "operation": "byCorrelation",
          "objectName": "@happyvertical/smrt-personas:FeedbackCollection"
        },
        {
          "kind": "mcp",
          "name": "feedbackcollection_forpersona",
          "operation": "forPersona",
          "objectName": "@happyvertical/smrt-personas:FeedbackCollection"
        },
        {
          "kind": "mcp",
          "name": "feedbackcollection_forscope",
          "operation": "forScope",
          "objectName": "@happyvertical/smrt-personas:FeedbackCollection"
        },
        {
          "kind": "mcp",
          "name": "feedbackcollection_bycorrelation",
          "operation": "byCorrelation",
          "objectName": "@happyvertical/smrt-personas:FeedbackCollection"
        }
      ],
      "relationshipFeatures": [
        "uuidColumns"
      ],
      "tags": [],
      "risks": []
    }
  ],
  "surfaces": [
    {
      "kind": "api",
      "name": "agentpersonas.list",
      "operation": "list",
      "objectName": "@happyvertical/smrt-personas:AgentPersona",
      "path": "/agentpersonas",
      "method": "GET"
    },
    {
      "kind": "api",
      "name": "agentpersonas.get",
      "operation": "get",
      "objectName": "@happyvertical/smrt-personas:AgentPersona",
      "path": "/agentpersonas/[id]",
      "method": "GET"
    },
    {
      "kind": "api",
      "name": "agentpersonas.create",
      "operation": "create",
      "objectName": "@happyvertical/smrt-personas:AgentPersona",
      "path": "/agentpersonas",
      "method": "POST"
    },
    {
      "kind": "api",
      "name": "agentpersonas.update",
      "operation": "update",
      "objectName": "@happyvertical/smrt-personas:AgentPersona",
      "path": "/agentpersonas/[id]",
      "method": "PATCH"
    },
    {
      "kind": "api",
      "name": "agentpersonas.delete",
      "operation": "delete",
      "objectName": "@happyvertical/smrt-personas:AgentPersona",
      "path": "/agentpersonas/[id]",
      "method": "DELETE"
    },
    {
      "kind": "cli",
      "name": "agentpersona_list",
      "operation": "list",
      "objectName": "@happyvertical/smrt-personas:AgentPersona"
    },
    {
      "kind": "cli",
      "name": "agentpersona_get",
      "operation": "get",
      "objectName": "@happyvertical/smrt-personas:AgentPersona"
    },
    {
      "kind": "mcp",
      "name": "agentpersona_list",
      "operation": "list",
      "objectName": "@happyvertical/smrt-personas:AgentPersona"
    },
    {
      "kind": "mcp",
      "name": "agentpersona_get",
      "operation": "get",
      "objectName": "@happyvertical/smrt-personas:AgentPersona"
    },
    {
      "kind": "api",
      "name": "agentpersonas.byTenantAndClass",
      "operation": "byTenantAndClass",
      "objectName": "@happyvertical/smrt-personas:AgentPersonaCollection",
      "path": "/agentpersonas/byTenantAndClass",
      "method": "POST"
    },
    {
      "kind": "api",
      "name": "agentpersonas.findActive",
      "operation": "findActive",
      "objectName": "@happyvertical/smrt-personas:AgentPersonaCollection",
      "path": "/agentpersonas/findActive",
      "method": "POST"
    },
    {
      "kind": "cli",
      "name": "agentpersonacollection_byTenantAndClass",
      "operation": "byTenantAndClass",
      "objectName": "@happyvertical/smrt-personas:AgentPersonaCollection"
    },
    {
      "kind": "cli",
      "name": "agentpersonacollection_findActive",
      "operation": "findActive",
      "objectName": "@happyvertical/smrt-personas:AgentPersonaCollection"
    },
    {
      "kind": "mcp",
      "name": "agentpersonacollection_bytenantandclass",
      "operation": "byTenantAndClass",
      "objectName": "@happyvertical/smrt-personas:AgentPersonaCollection"
    },
    {
      "kind": "mcp",
      "name": "agentpersonacollection_findactive",
      "operation": "findActive",
      "objectName": "@happyvertical/smrt-personas:AgentPersonaCollection"
    },
    {
      "kind": "api",
      "name": "directiveproposals.list",
      "operation": "list",
      "objectName": "@happyvertical/smrt-personas:DirectiveProposal",
      "path": "/directiveproposals",
      "method": "GET"
    },
    {
      "kind": "api",
      "name": "directiveproposals.get",
      "operation": "get",
      "objectName": "@happyvertical/smrt-personas:DirectiveProposal",
      "path": "/directiveproposals/[id]",
      "method": "GET"
    },
    {
      "kind": "cli",
      "name": "directiveproposal_list",
      "operation": "list",
      "objectName": "@happyvertical/smrt-personas:DirectiveProposal"
    },
    {
      "kind": "cli",
      "name": "directiveproposal_get",
      "operation": "get",
      "objectName": "@happyvertical/smrt-personas:DirectiveProposal"
    },
    {
      "kind": "mcp",
      "name": "directiveproposal_list",
      "operation": "list",
      "objectName": "@happyvertical/smrt-personas:DirectiveProposal"
    },
    {
      "kind": "mcp",
      "name": "directiveproposal_get",
      "operation": "get",
      "objectName": "@happyvertical/smrt-personas:DirectiveProposal"
    },
    {
      "kind": "api",
      "name": "directiveproposals.pending",
      "operation": "pending",
      "objectName": "@happyvertical/smrt-personas:DirectiveProposalCollection",
      "path": "/directiveproposals/pending",
      "method": "POST"
    },
    {
      "kind": "api",
      "name": "directiveproposals.findByFingerprint",
      "operation": "findByFingerprint",
      "objectName": "@happyvertical/smrt-personas:DirectiveProposalCollection",
      "path": "/directiveproposals/findByFingerprint",
      "method": "POST"
    },
    {
      "kind": "cli",
      "name": "directiveproposalcollection_pending",
      "operation": "pending",
      "objectName": "@happyvertical/smrt-personas:DirectiveProposalCollection"
    },
    {
      "kind": "cli",
      "name": "directiveproposalcollection_findByFingerprint",
      "operation": "findByFingerprint",
      "objectName": "@happyvertical/smrt-personas:DirectiveProposalCollection"
    },
    {
      "kind": "mcp",
      "name": "directiveproposalcollection_pending",
      "operation": "pending",
      "objectName": "@happyvertical/smrt-personas:DirectiveProposalCollection"
    },
    {
      "kind": "mcp",
      "name": "directiveproposalcollection_findbyfingerprint",
      "operation": "findByFingerprint",
      "objectName": "@happyvertical/smrt-personas:DirectiveProposalCollection"
    },
    {
      "kind": "api",
      "name": "feedbacks.list",
      "operation": "list",
      "objectName": "@happyvertical/smrt-personas:Feedback",
      "path": "/feedbacks",
      "method": "GET"
    },
    {
      "kind": "api",
      "name": "feedbacks.get",
      "operation": "get",
      "objectName": "@happyvertical/smrt-personas:Feedback",
      "path": "/feedbacks/[id]",
      "method": "GET"
    },
    {
      "kind": "api",
      "name": "feedbacks.create",
      "operation": "create",
      "objectName": "@happyvertical/smrt-personas:Feedback",
      "path": "/feedbacks",
      "method": "POST"
    },
    {
      "kind": "cli",
      "name": "feedback_list",
      "operation": "list",
      "objectName": "@happyvertical/smrt-personas:Feedback"
    },
    {
      "kind": "cli",
      "name": "feedback_get",
      "operation": "get",
      "objectName": "@happyvertical/smrt-personas:Feedback"
    },
    {
      "kind": "mcp",
      "name": "feedback_list",
      "operation": "list",
      "objectName": "@happyvertical/smrt-personas:Feedback"
    },
    {
      "kind": "mcp",
      "name": "feedback_get",
      "operation": "get",
      "objectName": "@happyvertical/smrt-personas:Feedback"
    },
    {
      "kind": "api",
      "name": "feedbacks.forPersona",
      "operation": "forPersona",
      "objectName": "@happyvertical/smrt-personas:FeedbackCollection",
      "path": "/feedbacks/forPersona",
      "method": "POST"
    },
    {
      "kind": "api",
      "name": "feedbacks.forScope",
      "operation": "forScope",
      "objectName": "@happyvertical/smrt-personas:FeedbackCollection",
      "path": "/feedbacks/forScope",
      "method": "POST"
    },
    {
      "kind": "api",
      "name": "feedbacks.byCorrelation",
      "operation": "byCorrelation",
      "objectName": "@happyvertical/smrt-personas:FeedbackCollection",
      "path": "/feedbacks/byCorrelation",
      "method": "POST"
    },
    {
      "kind": "cli",
      "name": "feedbackcollection_forPersona",
      "operation": "forPersona",
      "objectName": "@happyvertical/smrt-personas:FeedbackCollection"
    },
    {
      "kind": "cli",
      "name": "feedbackcollection_forScope",
      "operation": "forScope",
      "objectName": "@happyvertical/smrt-personas:FeedbackCollection"
    },
    {
      "kind": "cli",
      "name": "feedbackcollection_byCorrelation",
      "operation": "byCorrelation",
      "objectName": "@happyvertical/smrt-personas:FeedbackCollection"
    },
    {
      "kind": "mcp",
      "name": "feedbackcollection_forpersona",
      "operation": "forPersona",
      "objectName": "@happyvertical/smrt-personas:FeedbackCollection"
    },
    {
      "kind": "mcp",
      "name": "feedbackcollection_forscope",
      "operation": "forScope",
      "objectName": "@happyvertical/smrt-personas:FeedbackCollection"
    },
    {
      "kind": "mcp",
      "name": "feedbackcollection_bycorrelation",
      "operation": "byCorrelation",
      "objectName": "@happyvertical/smrt-personas:FeedbackCollection"
    }
  ],
  "prompts": [
    {
      "filePath": "src/persona-prompt.ts"
    }
  ],
  "relationshipsV2": {
    "foreignKeyFields": 2,
    "crossPackageRefFields": 2,
    "junctionCollections": 0,
    "hierarchicalObjects": 0,
    "polymorphicAssociations": 0,
    "uuidColumns": 20
  },
  "agentDoc": "# @happyvertical/smrt-personas\n\nTenant-owned, context-scoped agent personas and their resolution. Layers over\n`@happyvertical/smrt-agents`' `TenantAgent` availability/ceiling gate to decide\n*how* an agent behaves for a given tenant and context (its `TenantAgent` binding\ndecides *whether* it runs and caps its capabilities).\n\nThis is the L2 layer of the \"learning agents\" epic (#1885): the persona foundation\n(`AgentPersona` + `PersonaResolver`), the **persona learning & adaptation loop**\n(#1889) — feedback → confidence-scored reinforcement → a scheduled reflection\nrunner that emits pending directive proposals → a permission-gated approval\nsurface that activates an approved rewrite as a tenant/persona-scoped prompt\noverride — and the persona-as-durable-instance / multi-instance helpers (#1890,\nbelow). `ExecuteAsPrincipal` remains a separate issue (#1888).\n\n## Models\n\n- **AgentPersona** (`@TenantScoped({ mode: 'required' })`, table `agent_personas`):\n  a behavioral profile for one agent class within one tenant. Many per\n  `(tenant, agentClass)`; unique on `(tenant_id, agent_class, name)` via\n  `conflictColumns`. Fields:\n  - `agentClass` — canonical qualified agent type (e.g.\n    `@happyvertical/smrt-agents:Praeco`); stored canonical so it lines up with\n    `TenantAgent.agentClass`.\n  - `name` — persona name, unique per `(tenant, agentClass)`.\n  - `contextType` / `contextId` — optional scoping. No `contextType` = a\n    tenant-wide default; `contextType` only = type-scoped; both = exact context.\n  - `instructions` — system prompt layered onto the agent.\n  - `allowedTools` — JSON array of tool ids stored as a string; use\n    `getAllowedTools()` / `setAllowedTools()` (tolerant `try/catch` parse).\n  - `runAsUserId` — `@crossPackageRef('@happyvertical/smrt-users:User')`, the\n    principal the persona runs as.\n  - `actsAsProfileId` — optional `@crossPackageRef('@happyvertical/smrt-profiles:Profile')`,\n    a `Bot` identity for audit/attribution.\n  - `memoryScope` — memory/reflection partition key (empty → resolver-derived).\n  - `priority` — integer; higher wins among personas that apply at the same\n    tenant level.\n  - `enabled` — boolean; only enabled personas are resolved.\n\n- **Feedback** (`@TenantScoped({ mode: 'optional' })`, table `agent_feedback`):\n  one reinforcement signal against a persona and the learning episode it judges.\n  Human signals (`accept` / `reject` / `correction` / `rating`) and autonomous\n  signals (`outcome` / `metric`) each carry a required **`correlationId`** (+\n  optional `correlationType`) back to the AI call / dispatch / job. `scope` /\n  `key` name the `LearningMemory` episode; `toLearningOutcome()` maps the signal\n  onto a `LearningOutcome` (feeds reinforcement, #1886). `FeedbackCollection`:\n  `forPersona`, `forScope`, `byCorrelation`.\n\n- **DirectiveProposal** (`@TenantScoped({ mode: 'required' })`, table\n  `directive_proposals`): a pending, human-reviewable proposed edit to a\n  persona's `instructions`. Read-only generated surface (`api`/`cli`/`mcp` =\n  `list`/`get`) — writes go through the gated approval service, not CRUD. Key\n  fields: `promptKey`, `proposedInstructions`, `currentInstructions` (diff),\n  `rationale`, `evidence` (JSON: episode + feedback ids), `status`\n  (`pending`/`approved`/`rejected`/`superseded`), `fingerprint` (dedup so a\n  rejected rewrite is never re-surfaced), `proposedBy`, `reviewedBy` /\n  `reviewedAt` / `activatedOverrideId`. `DirectiveProposalCollection`:\n  `pending(...)` (the review queue), `findByFingerprint(...)`.\n\n## Learning loop (#1889)\n\n- **Persona instructions via prompt overrides** (`persona-prompt.ts`): a\n  persona's instructions apply through a per-persona registered prompt key\n  (`persona.<id>.instructions`, neutral empty base template) plus a\n  tenant-scoped `prompt_override`. Two personas of the same tenant/class resolve\n  different instructions without colliding on the override `(key, context)`\n  identity. `ensurePersonaInstructionsPrompt` (idempotent registration,\n  `editable` configurable), `applyPersonaInstructions` /\n  `upsertPromptTemplateOverride` (write the override — flows through\n  `PromptOverride.save()` → `validatePromptOverride`, so a non-editable template\n  is refused), `resolvePersonaInstructions`.\n- **Memory scoping** (`persona-memory.ts`): `personaLearningMemory` routes a\n  `LearningMemory` by the persona's `memoryScope` (used as `owner_id`), so\n  personas learn independently. `reinforceFromFeedback` applies a `Feedback`\n  signal to memory as automatic, confidence-only reinforcement (ungated).\n- **ReflectionRunner** (`reflection-runner.ts`): a schedulable pass that, under\n  the autonomous reflection principal (which **lacks**\n  `personas.activate-directive`), reinforces recent feedback, consolidates\n  episodes + feedback via an injected `reflect` boundary (the AI call, mocked in\n  tests), and records a **pending** `DirectiveProposal` (deduped by fingerprint).\n  It cannot activate anything.\n- **The gate = a permission split** (`directive-principal.ts`,\n  `directive-approval.ts`): activating a directive is the permissioned operation\n  `personas.activate-directive` (contributed to the manifest permission catalog\n  via `registerPermissionDefinitions`). `DirectiveApprovalService.approve` /\n  `reject` first `assertCanActivate(principal)`; approval writes the\n  persona-scoped override and records an `accept` signal, rejection records a\n  `reject` signal and closes the proposal. A `DirectivePrincipal` is built from\n  granted slugs (`principalFromPermissions`) or a `PermissionResolver`\n  (`resolveDirectivePrincipal`).\n\n## Svelte UI\n\n`@happyvertical/smrt-personas/svelte` ships a minimal, presentational\n`DirectiveReviewQueue` component (Svelte 5): it lists pending proposals with a\ncurrent-vs-proposed diff and Approve/Reject actions, delegating to `onApprove`\n(optionally with reviewer-edited text) / `onReject` callbacks a host wires to\nthe gated `DirectiveApprovalService`. Built with `svelte-package`; Svelte tests\nrun in CI only.\n\n## Collection\n\n`AgentPersonaCollection`:\n\n- `byTenantAndClass(tenantId, agentClass)` — all personas for the pair\n  (canonicalized), ordered by descending priority then name.\n- `findActive(tenantId, agentClass, context?)` — enabled personas applicable to\n  a context, same ordering.\n\n## PersonaResolver\n\n`resolve(tenantId, agentClass, context, options) → ResolvedPersona` layers,\nbottom to top: **manifest defaults → `TenantAgent` gate/ceiling → AgentPersona**.\n\n- **Hierarchy inheritance** mirrors `TenantAgentCollection.resolveForTenant`:\n  walks the requesting tenant then its ancestors (`options.getAncestorIds`,\n  nearest first). The nearest level with any applicable persona wins (a closer\n  level shadows a farther one).\n- **Selection within a level**: most context-specific first\n  (exact > type-scoped > tenant-wide), then highest `priority`, then name.\n- **Ceiling**: `options.availability` (a `PersonaAvailabilityGate`) gates\n  availability and intersects the resolved `allowedTools`. Build one from a\n  `ResolvedAgentAvailability` with `availabilityFromResolvedAgent()`.\n- **Default fallback**: when no persona applies, returns a defined default\n  (`source: 'default'`, `name: 'default'`) from manifest defaults + the gate.\n\nBecause the walk reads personas across tenants, `resolve()` is intended for a\nsystem/admin path where cross-tenant reads are allowed — not inside a strict\nper-tenant interceptor context (same expectation as `resolveForTenant`).\n\n## Persona as Durable Instance (#1890)\n\nA persona is a **durable instance** of an agent class — N per tenant, each\nindependently scheduled, memory-scoped, and permission-scoped. `persona-instance.ts`\nwires that to the `@happyvertical/smrt-agents` multi-instance primitives (which are\nper-package opt-in via `static multiInstance`, singleton by default):\n\n- **Identity** — `personaInstanceKey(persona)` returns the persona id, or `null`\n  for the `default` persona (`DEFAULT_PERSONA_NAME`). A `null` key reuses the\n  **singleton** runtime identity (class-keyed dispatch subscriber + un-suffixed\n  memory scope). `agentOptionsForPersona(persona)` always projects\n  `{ personaId, instanceKey, tenantId }`: `personaId` owns durable settings;\n  `instanceKey` owns execution partitioning.\n- **Scheduling** — `schedulePersonaInstance(schedules, persona, { cron, … })`\n  creates an `AgentSchedule` for the instance. The instance key rides in\n  `agentConfig` (which the scheduler spreads into the agent constructor →\n  `AgentOptions.personaId` / `instanceKey`); `agentId` is left **null** on purpose, because the\n  scheduler copies `agentId`→`SmrtJob.objectId` and the `TaskRunner`\n  `loadFromId()`s it against the agent's STI table — a persona id is not a row\n  there. The default persona carries its `personaId` but no instance key → runs\n  the singleton while retaining persona-owned settings.\n- **Admin** — `buildPersonaInstanceAdmin(personas, { tenantId, agentClass,\n  manifest })` renders the class's `uiSlots`/`adminRoutes` **once per instance**\n  (with the per-instance dispatch subscriber); `addPersonaInstance()` /\n  `removePersonaInstance(personaId)` are the add/remove affordances.\n- **Non-destructive upgrade** — `upgradeSingletonToDefaultPersona(personas, {\n  tenantId, agentClass, runAsUserId, … })` maps an existing singleton to a single\n  `default` persona. It's null-keyed, so the running agent's dispatch subscriber,\n  memory, and config are untouched; idempotent (a second call returns the\n  existing default with `created: false` and never overwrites it).\n\n## Dependencies\n\nLeaf package (acyclic by construction — nothing depends back on it):\n\n- Runtime: `@happyvertical/smrt-core`, `@happyvertical/smrt-tenancy`,\n  `@happyvertical/smrt-agents` (the `TenantAgent` type it bridges, plus the\n  `AgentSchedule`/multi-instance surface `persona-instance.ts` builds on),\n  `@happyvertical/smrt-messages` (the persona-fixed outbound messaging tool),\n  `@happyvertical/smrt-prompts` (persona instructions via `PromptOverride` +\n  `resolvePrompt`), `@happyvertical/smrt-users` (the permission catalog slug +\n  `PermissionResolver` principal), and `@happyvertical/sql` (`DatabaseInterface`\n  type). These edges are all acyclic (none of those packages depend on personas).\n- Svelte peer + `@happyvertical/smrt-ui` for the optional `./svelte` review-queue\n  component.\n- `runAsUserId` / `actsAsProfileId` reference `@happyvertical/smrt-users` and\n  `@happyvertical/smrt-profiles` via `@crossPackageRef` string ids only. No\n  inter-`smrt-*` `peerDependencies`.\n\n## Gotchas\n\n- **`conflictColumns` replaces the default `(slug, context)` unique index** — the\n  unique key is `(tenant_id, agent_class, name)`, so same-named personas across\n  tenants are allowed and tenant isolation is preserved.\n- **`allowedTools` is text, not `type: 'json'`** — stored as a JSON string and\n  read through the helpers, so it never auto-hydrates to an object.\n- **Resolver runs outside strict tenant context** — it deliberately crosses\n  tenants to walk the hierarchy.\n- **The gate is the permission split, not a bespoke check** — the reflection\n  principal simply lacks `personas.activate-directive`, so it can only propose;\n  everything privileged in `DirectiveApprovalService` calls `assertCanActivate`\n  first. Instruction rewrites are gated; confidence-only reinforcement is not.\n- **Persona messaging is fixed by trusted wiring** —\n  `createPersonaMessagingTool({ personaId })` exposes `messages.send` without\n  accepting persona, account, endpoint, or credential ids from tool arguments.\n  It requires both the persona tool allow-list and the live principal's\n  `messages.send` permission.\n- **Persona instructions live in the override layer, not the base prompt** — the\n  per-persona prompt key registers a neutral empty template, so re-registration\n  stays idempotent as instructions change; the tenant-scoped override carries the\n  actual text. Activation still honours `validatePromptOverride` editability.\n- **Directive dedup is by fingerprint across all statuses** — the runner skips a\n  proposal whose `(personaId, promptKey, proposedInstructions)` fingerprint\n  already exists (pending, approved, or rejected), so a rejected rewrite is never\n  re-surfaced.\n"
}