{"openapi":"3.1.0","info":{"title":"Heirmos API","description":"Cloud memory infrastructure shared across Claude / ChatGPT / Grok","version":"0.1.0"},"paths":{"/v1/schema":{"get":{"tags":["schema"],"summary":"Get Schema","description":"Return the user's SCHEMA.md.\n\nIf the user has never PUT a schema, return an empty seed (content=\"\", version=0)\nrather than 404 — SPEC §5.3 response shape is always a single object, and the\nspec text says this endpoint \"must be called before storing memory\", so 404\nwould force every AI client to special-case bootstrap.","operationId":"get_schema_v1_schema_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/SchemaRead"}}}}},"security":[{"HTTPBearer":[]}]},"put":{"tags":["schema"],"summary":"Put Schema","operationId":"put_schema_v1_schema_put","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SchemaUpdate"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/SchemaRead"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}},"security":[{"HTTPBearer":[]}]}},"/v1/memories":{"get":{"tags":["memories"],"summary":"List Memories","operationId":"list_memories_v1_memories_get","security":[{"HTTPBearer":[]}],"parameters":[{"name":"prefix","in":"query","required":false,"schema":{"type":"string","default":"","title":"Prefix"}},{"name":"limit","in":"query","required":false,"schema":{"type":"integer","default":50,"title":"Limit"}},{"name":"include_archived","in":"query","required":false,"schema":{"type":"boolean","default":false,"title":"Include Archived"}},{"name":"deleted_only","in":"query","required":false,"schema":{"type":"boolean","default":false,"title":"Deleted Only"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/MemoryListResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"post":{"tags":["memories"],"summary":"Create Memory","operationId":"create_memory_v1_memories_post","security":[{"HTTPBearer":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/MemoryCreate"}}}},"responses":{"201":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/MemoryRead"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/memories/{path}":{"get":{"tags":["memories"],"summary":"Get Memory","operationId":"get_memory_v1_memories__path__get","security":[{"HTTPBearer":[]}],"parameters":[{"name":"path","in":"path","required":true,"schema":{"type":"string","title":"Path"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/MemoryRead"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"patch":{"tags":["memories"],"summary":"Patch Memory","operationId":"patch_memory_v1_memories__path__patch","security":[{"HTTPBearer":[]}],"parameters":[{"name":"path","in":"path","required":true,"schema":{"type":"string","title":"Path"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/MemoryPatch"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/MemoryRead"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"delete":{"tags":["memories"],"summary":"Archive Memory","operationId":"archive_memory_v1_memories__path__delete","security":[{"HTTPBearer":[]}],"parameters":[{"name":"path","in":"path","required":true,"schema":{"type":"string","title":"Path"}},{"name":"purge","in":"query","required":false,"schema":{"type":"boolean","default":false,"title":"Purge"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"anyOf":[{"$ref":"#/components/schemas/MemoryArchiveResponse"},{"$ref":"#/components/schemas/MemoryPurgeResponse"}],"title":"Response Archive Memory V1 Memories  Path  Delete"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/memories/consolidate":{"post":{"tags":["memories"],"summary":"Consolidate Memories","description":"Merge N memories into one via LLM (P7-2).\n\nThe new memory lands at ``body.paths[0]``; the rest are soft-deleted.\n``source`` on the merged row is hard-coded to ``\"consolidate\"`` so audit\nqueries can distinguish AI-generated merges from user/AI writes.","operationId":"consolidate_memories_v1_memories_consolidate_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ConsolidateRequest"}}},"required":true},"responses":{"201":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ConsolidateResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}},"security":[{"HTTPBearer":[]}]}},"/v1/memories/organize":{"post":{"tags":["memories"],"summary":"Organize Memories","description":"Propose-only cleanup analysis for the dashboard \"정리\" button (#2).\n\nReturns near-duplicate clusters, conflicting/needs-review memories, and\nlow-value stale candidates. **Never mutates** — the user confirms each\naction client-side; applying reuses POST /consolidate + DELETE /{path}\n(Heirmos principle: AI proposes, user owns).","operationId":"organize_memories_v1_memories_organize_post","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/OrganizeProposal"}}}}},"security":[{"HTTPBearer":[]}]}},"/v1/memories/organize/audit":{"post":{"tags":["memories"],"summary":"Organize Audit","description":"AI 정밀 검수 (#2 deeper) — LLM audits each memory and proposes\nre-classify(move) / supplement / delete. One LLM call per memory\n(concurrency-capped, per-run cap surfaced as ``skipped``). **Never mutates** —\nthe user applies each proposal client-side (POST /move, PATCH /{path},\nDELETE /{path}). Rate-limited (LLM-heavy).","operationId":"organize_audit_v1_memories_organize_audit_post","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/OrganizeAudit"}}}}},"security":[{"HTTPBearer":[]}]}},"/v1/memories/restore":{"post":{"tags":["memories"],"summary":"Restore Memory","description":"복구 — un-archive the latest archived memory at ``body.path`` (SPEC §14.9\nsoft-delete is reversible). 404 if nothing archived there; PATH_CONFLICT if a\ncurrent memory already occupies the path.","operationId":"restore_memory_v1_memories_restore_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RestoreRequest"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/MemoryRead"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}},"security":[{"HTTPBearer":[]}]}},"/v1/memories/move":{"post":{"tags":["memories"],"summary":"Move Memories","description":"Relocate memories (a file or a whole folder) to new paths — pure path change.\n\nRegistered before ``/{path:path}`` so ``POST /v1/memories/move`` is not\nshadowed by the wildcard (which only serves GET/PATCH/DELETE anyway).","operationId":"move_memories_v1_memories_move_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/MoveRequest"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/MoveResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}},"security":[{"HTTPBearer":[]}]}},"/v1/episodes":{"post":{"tags":["episodes"],"summary":"Create Episode","operationId":"create_episode_v1_episodes_post","security":[{"HTTPBearer":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EpisodeCreate"}}}},"responses":{"201":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/EpisodeProcessResult"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"get":{"tags":["episodes"],"summary":"List Episodes","operationId":"list_episodes_v1_episodes_get","security":[{"HTTPBearer":[]}],"parameters":[{"name":"limit","in":"query","required":false,"schema":{"type":"integer","default":50,"title":"Limit"}},{"name":"status_filter","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Status Filter"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/EpisodeListResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/episodes/{episode_id}":{"get":{"tags":["episodes"],"summary":"Get Episode","operationId":"get_episode_v1_episodes__episode_id__get","security":[{"HTTPBearer":[]}],"parameters":[{"name":"episode_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Episode Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/EpisodeRead"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/attachments":{"post":{"tags":["attachments"],"summary":"Upload Attachment","operationId":"upload_attachment_v1_attachments_post","requestBody":{"content":{"multipart/form-data":{"schema":{"$ref":"#/components/schemas/Body_upload_attachment_v1_attachments_post"}}},"required":true},"responses":{"201":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AttachmentRead"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}},"security":[{"HTTPBearer":[]}]}},"/v1/attachments/lookup":{"post":{"tags":["attachments"],"summary":"Lookup Attachments","operationId":"lookup_attachments_v1_attachments_lookup_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AttachmentLookupRequest"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AttachmentListResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}},"security":[{"HTTPBearer":[]}]}},"/v1/attachments/upload-url":{"post":{"tags":["attachments"],"summary":"Create Upload Url","description":"Mint a one-shot upload URL (Phase 25 — the MCP side channel).\n\nAn AI chat host cannot hand this server the bytes of an image the user\npasted: MCP has no binary primitive and base64 in a tool argument would cost\n~1.4M tokens for a 4 MiB file. So the model asks for this URL and uploads\nwith ``curl -X PUT`` from its own sandbox — the bytes never pass through the\ncontext window.\n\nSame 20/min bucket as the multipart upload: each ticket ultimately costs one\nstorage object and one vision call.","operationId":"create_upload_url_v1_attachments_upload_url_post","responses":{"201":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AttachmentUploadTicket"}}}}},"security":[{"HTTPBearer":[]}]}},"/v1/attachments/upload/{raw_token}":{"put":{"tags":["attachments"],"summary":"Upload With Token","description":"Spend an upload token and store the raw body as an attachment.\n\n**This route carries no Bearer header** — the token in the path is the whole\ncredential, and ``resolve_upload_token`` restores the owner by DB lookup, so\n§14.6 tenant isolation holds for an anonymous request.\n\nThe token is consumed FIRST, before a single byte of the body is read: the\ncredential must be dead the moment it is presented, whatever happens next.\nEverything after that is the ordinary path — magic-byte mime sniffing, the\nsize cap, upload-before-INSERT ordering and the background vision pass are\nthe same code the dashboard uses.\n\nThe limit is looser than the 20/min on the authenticated routes because\nslowapi keys an anonymous request by IP, which one office NAT would share.\nThe real control here is the token itself: opaque, single-use, 10-minute TTL.","operationId":"upload_with_token_v1_attachments_upload__raw_token__put","parameters":[{"name":"raw_token","in":"path","required":true,"schema":{"type":"string","title":"Raw Token"}}],"responses":{"201":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AttachmentUploadResult"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/attachments/{attachment_id}/dismiss":{"post":{"tags":["attachments"],"summary":"Dismiss Attachment","description":"Reject the vision proposal (MEMO-5) — advisory opt-out, not a delete.","operationId":"dismiss_attachment_v1_attachments__attachment_id__dismiss_post","security":[{"HTTPBearer":[]}],"parameters":[{"name":"attachment_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Attachment Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AttachmentRead"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/attachments/{attachment_id}":{"get":{"tags":["attachments"],"summary":"Get Attachment","operationId":"get_attachment_v1_attachments__attachment_id__get","security":[{"HTTPBearer":[]}],"parameters":[{"name":"attachment_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Attachment Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AttachmentRead"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"delete":{"tags":["attachments"],"summary":"Archive Attachment","operationId":"archive_attachment_v1_attachments__attachment_id__delete","security":[{"HTTPBearer":[]}],"parameters":[{"name":"attachment_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Attachment Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AttachmentArchiveResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/attachments/{attachment_id}/content":{"get":{"tags":["attachments"],"summary":"Get Attachment Content","operationId":"get_attachment_content_v1_attachments__attachment_id__content_get","security":[{"HTTPBearer":[]}],"parameters":[{"name":"attachment_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Attachment Id"}}],"responses":{"200":{"description":"Successful Response"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/briefing":{"post":{"tags":["briefing"],"summary":"Post Briefing","description":"Session-start context packet — index only, never full content.","operationId":"post_briefing_v1_briefing_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/BriefingRequest"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BriefingResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}},"security":[{"HTTPBearer":[]}]}},"/v1/feedback":{"post":{"tags":["feedback"],"summary":"Submit Feedback","operationId":"submit_feedback_v1_feedback_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/FeedbackCreate"}}},"required":true},"responses":{"201":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/FeedbackRead"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}},"security":[{"HTTPBearer":[]}]}},"/v1/needs-review":{"get":{"tags":["feedback"],"summary":"List Needs Review","operationId":"list_needs_review_v1_needs_review_get","security":[{"HTTPBearer":[]}],"parameters":[{"name":"limit","in":"query","required":false,"schema":{"type":"integer","default":50,"title":"Limit"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/NeedsReviewResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/folders/maintenance":{"get":{"tags":["folders"],"summary":"Folder Maintenance","operationId":"folder_maintenance_v1_folders_maintenance_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/FolderMaintenanceProposal"}}}}},"security":[{"HTTPBearer":[]}]}},"/v1/imports":{"post":{"tags":["imports"],"summary":"Create Import","operationId":"create_import_v1_imports_post","security":[{"HTTPBearer":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ImportJobCreate"}}}},"responses":{"201":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ImportJobRead"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"get":{"tags":["imports"],"summary":"List Imports","operationId":"list_imports_v1_imports_get","security":[{"HTTPBearer":[]}],"parameters":[{"name":"limit","in":"query","required":false,"schema":{"type":"integer","default":20,"title":"Limit"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ImportJobListResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/imports/{job_id}":{"get":{"tags":["imports"],"summary":"Get Import","operationId":"get_import_v1_imports__job_id__get","security":[{"HTTPBearer":[]}],"parameters":[{"name":"job_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Job Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ImportJobRead"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/imports/{job_id}/items":{"post":{"tags":["imports"],"summary":"Add Import Items","operationId":"add_import_items_v1_imports__job_id__items_post","security":[{"HTTPBearer":[]}],"parameters":[{"name":"job_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Job Id"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ImportItemsIn"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ImportJobRead"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/imports/{job_id}/start":{"post":{"tags":["imports"],"summary":"Start Import","operationId":"start_import_v1_imports__job_id__start_post","security":[{"HTTPBearer":[]}],"parameters":[{"name":"job_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Job Id"}}],"responses":{"202":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ImportJobRead"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/insights/graph":{"get":{"tags":["insights"],"summary":"Graph Insights","operationId":"graph_insights_v1_insights_graph_get","security":[{"HTTPBearer":[]}],"parameters":[{"name":"include_proposed","in":"query","required":false,"schema":{"type":"boolean","default":false,"title":"Include Proposed"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/GraphInsightResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/insights/gaps":{"get":{"tags":["insights"],"summary":"Gap Insights","operationId":"gap_insights_v1_insights_gaps_get","security":[{"HTTPBearer":[]}],"parameters":[{"name":"include_proposed","in":"query","required":false,"schema":{"type":"boolean","default":false,"title":"Include Proposed"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/GapsInsightResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/insights/geology":{"get":{"tags":["insights"],"summary":"Geology Insights","description":"기억의 지질학 P17-4 — measured terrain metrics per current memory.\n\nLLM 0 calls, nothing persisted (Phase 16 on-demand pattern). Three queries:\ncurrent memories + recall aggregate (물길/풍화) + incoming derived_from\ncounts (기반암). Raw days/counts only — the simulation constants (rate, k)\nlive in the visualization layer (CEO 2026-06-11 ①).","operationId":"geology_insights_v1_insights_geology_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/GeologyResponse"}}}}},"security":[{"HTTPBearer":[]}]}},"/v1/insights/surface":{"post":{"tags":["insights"],"summary":"Surface Insights","description":"시추(프루스트 트리거, P19-1) — surface deep + weathered + near memories.\n\nThe opposite of search: given the current context, returns memories you\nhaven't recalled in a while but are semantically standing on. On-demand,\nread-only, **never logs a recall** (the server is recalling, not the user —\nlogging would reset weathering and self-destruct the signal).","operationId":"surface_insights_v1_insights_surface_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SurfaceRequest"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/SurfaceResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}},"security":[{"HTTPBearer":[]}]}},"/v1/insights/relations":{"get":{"tags":["insights"],"summary":"Relations Insights","description":"모순(변증법) + 열린 질문 surfacing — LLM 0 calls, list only (P16-4+5).","operationId":"relations_insights_v1_insights_relations_get","security":[{"HTTPBearer":[]}],"parameters":[{"name":"include_proposed","in":"query","required":false,"schema":{"type":"boolean","default":false,"title":"Include Proposed"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/RelationsInsightResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/insights/relations/{edge_id}/synthesize":{"post":{"tags":["insights"],"summary":"Synthesize Relation","description":"One LLM synthesis DRAFT for a tension edge — returned only, never stored.\n\nLazy by design (CEO 2026-06-11 Q1-b): the list endpoint stays LLM-free and\nthe user pays one call only for the contradiction they actually care about.\nAccepting a draft = the client saves it via the existing POST /v1/memories.","operationId":"synthesize_relation_v1_insights_relations__edge_id__synthesize_post","security":[{"HTTPBearer":[]}],"parameters":[{"name":"edge_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Edge Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/SynthesisResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/relations":{"get":{"tags":["relations"],"summary":"List Relations","operationId":"list_relations_v1_relations_get","security":[{"HTTPBearer":[]}],"parameters":[{"name":"memory_id","in":"query","required":false,"schema":{"anyOf":[{"type":"string","format":"uuid"},{"type":"null"}],"title":"Memory Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/RelationListResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/relations/{relation_id}/confirm":{"post":{"tags":["relations"],"summary":"Confirm Relation","operationId":"confirm_relation_v1_relations__relation_id__confirm_post","security":[{"HTTPBearer":[]}],"parameters":[{"name":"relation_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Relation Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/RelationRead"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/relations/{relation_id}/dismiss":{"post":{"tags":["relations"],"summary":"Dismiss Relation","operationId":"dismiss_relation_v1_relations__relation_id__dismiss_post","security":[{"HTTPBearer":[]}],"parameters":[{"name":"relation_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Relation Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/RelationRead"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/search":{"post":{"tags":["search"],"summary":"Search","operationId":"search_v1_search_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SearchRequest"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/SearchResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}},"security":[{"HTTPBearer":[]}]}},"/v1/admin/stats":{"get":{"tags":["admin"],"summary":"Admin Stats","operationId":"admin_stats_v1_admin_stats_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AdminStats"}}}}},"security":[{"HTTPBearer":[]}]}},"/v1/admin/digest":{"get":{"tags":["admin"],"summary":"Admin Digest","description":"Weekly usage digest as plain text — the host cron pipes this to alert.sh.\n\nAggregate-only (§14.6), owner-gated. Computed in-container (DB access here);\nTelegram delivery stays on the host (alert.sh holds the bot token).","operationId":"admin_digest_v1_admin_digest_get","responses":{"200":{"description":"Successful Response","content":{"text/plain":{"schema":{"type":"string"}}}}},"security":[{"HTTPBearer":[]}]}},"/v1/reservations/me":{"get":{"tags":["reservations"],"summary":"My Reservation","operationId":"my_reservation_v1_reservations_me_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReservationStatus"}}}}},"security":[{"HTTPBearer":[]}]}},"/v1/reservations":{"post":{"tags":["reservations"],"summary":"Reserve","operationId":"reserve_v1_reservations_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReservationRequest"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReservationStatus"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}},"security":[{"HTTPBearer":[]}]}},"/auth/google/login":{"get":{"tags":["auth"],"summary":"Google Login","operationId":"google_login_auth_google_login_get","parameters":[{"name":"next","in":"query","required":false,"schema":{"type":"string","default":"","title":"Next"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/auth/google/callback":{"get":{"tags":["auth"],"summary":"Google Callback","operationId":"google_callback_auth_google_callback_get","parameters":[{"name":"code","in":"query","required":true,"schema":{"type":"string","title":"Code"}},{"name":"state","in":"query","required":true,"schema":{"type":"string","title":"State"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/auth/logout":{"post":{"tags":["auth"],"summary":"Logout","operationId":"logout_auth_logout_post","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}}}},"/v1/auth/whoami":{"get":{"tags":["auth"],"summary":"Whoami","description":"U2 — the lightest authenticated probe: auth + two scalar fields, no list\nquery. The MCP token verifier delegates Bearer validation here (previously\n``GET /v1/memories?limit=1``, which paid a memory list just to learn \"is\nthis token valid\").","operationId":"whoami_v1_auth_whoami_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/WhoamiResponse"}}}}},"security":[{"HTTPBearer":[]}]}},"/v1/api-keys":{"get":{"tags":["api-keys"],"summary":"List Keys","operationId":"list_keys_v1_api_keys_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"items":{"$ref":"#/components/schemas/ApiKeyRead"},"type":"array","title":"Response List Keys V1 Api Keys Get"}}}}}},"post":{"tags":["api-keys"],"summary":"Create","operationId":"create_v1_api_keys_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiKeyCreate"}}},"required":true},"responses":{"201":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiKeyCreated"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/api-keys/{key_id}":{"delete":{"tags":["api-keys"],"summary":"Revoke","operationId":"revoke_v1_api_keys__key_id__delete","parameters":[{"name":"key_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Key Id"}}],"responses":{"204":{"description":"Successful Response"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/.well-known/oauth-authorization-server":{"get":{"tags":["oauth"],"summary":"Authorization Server Metadata","operationId":"authorization_server_metadata__well_known_oauth_authorization_server_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"additionalProperties":true,"type":"object","title":"Response Authorization Server Metadata  Well Known Oauth Authorization Server Get"}}}}}}},"/oauth/register":{"post":{"tags":["oauth"],"summary":"Register Client","operationId":"register_client_oauth_register_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ClientRegistrationRequest"}}},"required":true},"responses":{"201":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ClientRegistrationResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/oauth/authorize":{"get":{"tags":["oauth"],"summary":"Authorize","operationId":"authorize_oauth_authorize_get","parameters":[{"name":"client_id","in":"query","required":true,"schema":{"type":"string","title":"Client Id"}},{"name":"redirect_uri","in":"query","required":true,"schema":{"type":"string","title":"Redirect Uri"}},{"name":"response_type","in":"query","required":true,"schema":{"type":"string","title":"Response Type"}},{"name":"code_challenge","in":"query","required":false,"schema":{"type":"string","default":"","title":"Code Challenge"}},{"name":"code_challenge_method","in":"query","required":false,"schema":{"type":"string","default":"","title":"Code Challenge Method"}},{"name":"state","in":"query","required":false,"schema":{"type":"string","default":"","title":"State"}},{"name":"scope","in":"query","required":false,"schema":{"type":"string","default":"","title":"Scope"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/oauth/token":{"post":{"tags":["oauth"],"summary":"Token","operationId":"token_oauth_token_post","requestBody":{"content":{"application/x-www-form-urlencoded":{"schema":{"$ref":"#/components/schemas/Body_token_oauth_token_post"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/":{"get":{"tags":["dashboard"],"summary":"Root","operationId":"root__get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}}}},"/dashboard":{"get":{"tags":["dashboard"],"summary":"Dashboard Page","operationId":"dashboard_page_dashboard_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}}}},"/dashboard/api-keys":{"get":{"tags":["dashboard"],"summary":"Api Keys List Partial","operationId":"api_keys_list_partial_dashboard_api_keys_get","responses":{"200":{"description":"Successful Response","content":{"text/html":{"schema":{"type":"string"}}}}}},"post":{"tags":["dashboard"],"summary":"Api Keys Create Partial","operationId":"api_keys_create_partial_dashboard_api_keys_post","requestBody":{"content":{"application/x-www-form-urlencoded":{"schema":{"$ref":"#/components/schemas/Body_api_keys_create_partial_dashboard_api_keys_post"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"text/html":{"schema":{"type":"string"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/dashboard/api-keys/{key_id}":{"delete":{"tags":["dashboard"],"summary":"Api Keys Revoke Partial","operationId":"api_keys_revoke_partial_dashboard_api_keys__key_id__delete","parameters":[{"name":"key_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Key Id"}}],"responses":{"200":{"description":"Successful Response","content":{"text/html":{"schema":{"type":"string"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/dashboard/memories":{"get":{"tags":["dashboard"],"summary":"Memories List Partial","operationId":"memories_list_partial_dashboard_memories_get","responses":{"200":{"description":"Successful Response","content":{"text/html":{"schema":{"type":"string"}}}}}}},"/dashboard/search":{"post":{"tags":["dashboard"],"summary":"Search Partial","operationId":"search_partial_dashboard_search_post","requestBody":{"content":{"application/x-www-form-urlencoded":{"schema":{"$ref":"#/components/schemas/Body_search_partial_dashboard_search_post"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"text/html":{"schema":{"type":"string"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/health":{"get":{"summary":"Health","operationId":"health_health_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"additionalProperties":{"type":"string"},"type":"object","title":"Response Health Health Get"}}}}}}}},"components":{"schemas":{"AdminStats":{"properties":{"user_count":{"type":"integer","minimum":0.0,"title":"User Count"},"memory_count":{"type":"integer","minimum":0.0,"title":"Memory Count"},"new_memories_7d":{"type":"integer","minimum":0.0,"title":"New Memories 7D"},"new_memories_30d":{"type":"integer","minimum":0.0,"title":"New Memories 30D"},"recall_events_count":{"type":"integer","minimum":0.0,"title":"Recall Events Count"},"recent_signups":{"items":{"$ref":"#/components/schemas/RecentSignup"},"type":"array","title":"Recent Signups"},"source_distribution":{"additionalProperties":{"type":"integer"},"type":"object","title":"Source Distribution"}},"type":"object","required":["user_count","memory_count","new_memories_7d","new_memories_30d","recall_events_count","recent_signups","source_distribution"],"title":"AdminStats","description":"GET /v1/admin/stats — owner operations snapshot (aggregates only)."},"ApiKeyCreate":{"properties":{"name":{"type":"string","maxLength":120,"minLength":1,"title":"Name"}},"type":"object","required":["name"],"title":"ApiKeyCreate"},"ApiKeyCreated":{"properties":{"id":{"type":"string","format":"uuid","title":"Id"},"name":{"type":"string","title":"Name"},"key_prefix":{"type":"string","title":"Key Prefix"},"key":{"type":"string","title":"Key"},"created_at":{"type":"string","format":"date-time","title":"Created At"}},"type":"object","required":["id","name","key_prefix","key","created_at"],"title":"ApiKeyCreated"},"ApiKeyRead":{"properties":{"id":{"type":"string","format":"uuid","title":"Id"},"name":{"type":"string","title":"Name"},"key_prefix":{"type":"string","title":"Key Prefix"},"created_at":{"type":"string","format":"date-time","title":"Created At"},"last_used_at":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Last Used At"},"revoked_at":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Revoked At"}},"type":"object","required":["id","name","key_prefix","created_at"],"title":"ApiKeyRead"},"AttachmentArchiveResponse":{"properties":{"archived":{"type":"boolean","title":"Archived","default":true},"id":{"type":"string","format":"uuid","title":"Id"},"archived_at":{"type":"string","format":"date-time","title":"Archived At"}},"type":"object","required":["id","archived_at"],"title":"AttachmentArchiveResponse","description":"DELETE /v1/attachments/{id} — soft-delete confirmation (§14.9).\n\nThe storage object is retained (P0 has no purge — DECISIONS ## 가정\n2026-07-30)."},"AttachmentListResponse":{"properties":{"items":{"items":{"$ref":"#/components/schemas/AttachmentRead"},"type":"array","title":"Items"},"total":{"type":"integer","minimum":0.0,"title":"Total"}},"type":"object","required":["items","total"],"title":"AttachmentListResponse","description":"Lookup response."},"AttachmentLookupRequest":{"properties":{"ids":{"items":{"type":"string","format":"uuid"},"type":"array","maxItems":100,"minItems":1,"title":"Ids"}},"type":"object","required":["ids"],"title":"AttachmentLookupRequest","description":"POST /v1/attachments/lookup — batch metadata by id.\n\nMEMO-5 regex-extracts the ``/api/att/{id}`` references out of the memory\nbeing edited and resolves them in one round-trip. Unknown or other-users'\nids are silently absent from the response (§14.6 — no existence oracle)."},"AttachmentRead":{"properties":{"id":{"type":"string","format":"uuid","title":"Id"},"mime":{"type":"string","title":"Mime"},"size_bytes":{"type":"integer","title":"Size Bytes"},"created_at":{"type":"string","format":"date-time","title":"Created At"},"vision_status":{"type":"string","title":"Vision Status"},"caption":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Caption"},"ocr_text":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Ocr Text"},"vision_tags":{"anyOf":[{"items":{"type":"string"},"type":"array"},{"type":"null"}],"title":"Vision Tags"},"privacy_sensitivity":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Privacy Sensitivity"},"vision_model":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Vision Model"},"dismissed_at":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Dismissed At"}},"type":"object","required":["id","mime","size_bytes","created_at","vision_status"],"title":"AttachmentRead","description":"Attachment metadata — upload response, GET, and lookup items."},"AttachmentUploadResult":{"properties":{"id":{"type":"string","format":"uuid","title":"Id"},"mime":{"type":"string","title":"Mime"},"size_bytes":{"type":"integer","title":"Size Bytes"},"vision_status":{"type":"string","title":"Vision Status"}},"type":"object","required":["id","mime","size_bytes","vision_status"],"title":"AttachmentUploadResult","description":"PUT /v1/attachments/upload/{token} — deliberately narrower than\n``AttachmentRead``.\n\nThis response is served to an **unauthenticated** request (the token is the\nwhole credential), so it carries only what the uploader needs to reference\nthe image: the vision fields are all still empty at this point anyway, and\nare fetched later through the authenticated ``GET /v1/attachments/{id}``."},"AttachmentUploadTicket":{"properties":{"upload_url":{"type":"string","title":"Upload Url"},"expires_at":{"type":"string","format":"date-time","title":"Expires At"},"max_bytes":{"type":"integer","title":"Max Bytes"},"accepted_mime_types":{"items":{"type":"string"},"type":"array","title":"Accepted Mime Types"}},"type":"object","required":["upload_url","expires_at","max_bytes","accepted_mime_types"],"title":"AttachmentUploadTicket","description":"POST /v1/attachments/upload-url — a one-shot upload address (Phase 25).\n\nThe plaintext token appears here and nowhere else (only its sha256 is\nstored), embedded in ``upload_url`` so the caller has a single string to\nhand to ``curl -X PUT``. ``max_bytes`` / ``accepted_mime_types`` ride along\nbecause the consumer is an LLM that would otherwise have to guess, and a\nrejected upload costs a burnt token."},"AuditDelete":{"properties":{"path":{"type":"string","title":"Path"},"title":{"type":"string","title":"Title"},"reason":{"type":"string","title":"Reason"}},"type":"object","required":["path","title","reason"],"title":"AuditDelete","description":"AI judges the memory obsolete/worthless (삭제 → archive, recoverable)."},"AuditMove":{"properties":{"path":{"type":"string","title":"Path"},"title":{"type":"string","title":"Title"},"suggested_path":{"type":"string","title":"Suggested Path"},"reason":{"type":"string","title":"Reason"}},"type":"object","required":["path","title","suggested_path","reason"],"title":"AuditMove","description":"AI judges the memory belongs in a different folder (재분류 → 이동)."},"AuditSupplement":{"properties":{"path":{"type":"string","title":"Path"},"title":{"type":"string","title":"Title"},"improved_content":{"type":"string","title":"Improved Content"},"reason":{"type":"string","title":"Reason"}},"type":"object","required":["path","title","improved_content","reason"],"title":"AuditSupplement","description":"AI proposes improved content for the memory (보완 → PATCH full_content)."},"Body_api_keys_create_partial_dashboard_api_keys_post":{"properties":{"name":{"type":"string","title":"Name"}},"type":"object","required":["name"],"title":"Body_api_keys_create_partial_dashboard_api_keys_post"},"Body_search_partial_dashboard_search_post":{"properties":{"q":{"type":"string","title":"Q"}},"type":"object","required":["q"],"title":"Body_search_partial_dashboard_search_post"},"Body_token_oauth_token_post":{"properties":{"grant_type":{"type":"string","title":"Grant Type"},"code":{"type":"string","title":"Code","default":""},"redirect_uri":{"type":"string","title":"Redirect Uri","default":""},"client_id":{"type":"string","title":"Client Id","default":""},"code_verifier":{"type":"string","title":"Code Verifier","default":""},"client_secret":{"type":"string","title":"Client Secret","default":""},"refresh_token":{"type":"string","title":"Refresh Token","default":""}},"type":"object","required":["grant_type"],"title":"Body_token_oauth_token_post"},"Body_upload_attachment_v1_attachments_post":{"properties":{"file":{"type":"string","contentMediaType":"application/octet-stream","title":"File"}},"type":"object","required":["file"],"title":"Body_upload_attachment_v1_attachments_post"},"BridgeInfo":{"properties":{"memory_id":{"type":"string","format":"uuid","title":"Memory Id"},"path":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Path"},"title":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Title"},"score":{"type":"number","minimum":0.0,"title":"Score"}},"type":"object","required":["memory_id","score"],"title":"BridgeInfo","description":"A high-betweenness memory — it connects otherwise-separate thought areas."},"BriefingItem":{"properties":{"path":{"type":"string","title":"Path"},"title":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Title"},"summary":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Summary"},"source":{"type":"string","title":"Source"},"updated_at":{"type":"string","format":"date-time","title":"Updated At"},"occurred_at":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Occurred At"}},"type":"object","required":["path","source","updated_at"],"title":"BriefingItem","description":"One memory line in the packet — index only, never the full content."},"BriefingRequest":{"properties":{"prefix":{"type":"string","maxLength":512,"title":"Prefix","default":""},"context":{"type":"string","maxLength":4000,"title":"Context","default":""},"limit":{"type":"integer","maximum":20.0,"minimum":1.0,"title":"Limit","default":8},"surface_limit":{"type":"integer","maximum":10.0,"minimum":0.0,"title":"Surface Limit","default":5}},"type":"object","title":"BriefingRequest","description":"Body of ``POST /v1/briefing``."},"BriefingResponse":{"properties":{"prefix":{"type":"string","title":"Prefix"},"total_in_prefix":{"type":"integer","minimum":0.0,"title":"Total In Prefix"},"recent":{"items":{"$ref":"#/components/schemas/BriefingItem"},"type":"array","title":"Recent"},"surfaced":{"items":{"$ref":"#/components/schemas/BriefingItem"},"type":"array","title":"Surfaced"},"markdown":{"type":"string","title":"Markdown"},"generated_at":{"type":"string","format":"date-time","title":"Generated At"}},"type":"object","required":["prefix","total_in_prefix","recent","surfaced","markdown","generated_at"],"title":"BriefingResponse"},"CandidateOutcome":{"properties":{"action":{"type":"string","enum":["created","needs_review","conflicting","skipped_duplicate","dropped_unworthy","dropped_low_importance"],"title":"Action"},"statement":{"type":"string","title":"Statement"},"path":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Path"},"memory_id":{"anyOf":[{"type":"string","format":"uuid"},{"type":"null"}],"title":"Memory Id"},"type":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Type"},"scope":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Scope"},"status":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Status"},"confidence":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Confidence"},"importance":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Importance"},"relation":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Relation"},"suggested_path":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Suggested Path"},"reason":{"type":"string","title":"Reason","default":""}},"type":"object","required":["action","statement"],"title":"CandidateOutcome","description":"The fate of one extracted memory candidate (advisory + auditable).\n\n``action`` records what the pipeline did; ``status`` mirrors the persisted\natom's lifecycle status when one was created. For ``skipped_duplicate`` /\n``conflicting`` the ``suggested_path`` points at the existing memory the\nuser/client may want to merge into or reconcile — the server never applies\nthat itself."},"ClientRegistrationRequest":{"properties":{"redirect_uris":{"items":{"type":"string"},"type":"array","minItems":1,"title":"Redirect Uris"},"client_name":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Client Name"},"token_endpoint_auth_method":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Token Endpoint Auth Method"},"grant_types":{"anyOf":[{"items":{"type":"string"},"type":"array"},{"type":"null"}],"title":"Grant Types"},"response_types":{"anyOf":[{"items":{"type":"string"},"type":"array"},{"type":"null"}],"title":"Response Types"}},"type":"object","required":["redirect_uris"],"title":"ClientRegistrationRequest"},"ClientRegistrationResponse":{"properties":{"client_id":{"type":"string","title":"Client Id"},"client_id_issued_at":{"type":"integer","title":"Client Id Issued At"},"redirect_uris":{"items":{"type":"string"},"type":"array","title":"Redirect Uris"},"client_name":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Client Name"},"token_endpoint_auth_method":{"type":"string","title":"Token Endpoint Auth Method"},"grant_types":{"items":{"type":"string"},"type":"array","title":"Grant Types"},"response_types":{"items":{"type":"string"},"type":"array","title":"Response Types"},"code_challenge_methods_supported":{"items":{"type":"string"},"type":"array","title":"Code Challenge Methods Supported"}},"type":"object","required":["client_id","client_id_issued_at","redirect_uris","client_name","token_endpoint_auth_method","grant_types","response_types","code_challenge_methods_supported"],"title":"ClientRegistrationResponse"},"ClusterInfo":{"properties":{"cluster_id":{"type":"integer","title":"Cluster Id"},"memory_ids":{"items":{"type":"string","format":"uuid"},"type":"array","title":"Memory Ids"},"paths":{"items":{"type":"string"},"type":"array","title":"Paths"},"size":{"type":"integer","minimum":1.0,"title":"Size"}},"type":"object","required":["cluster_id","memory_ids","paths","size"],"title":"ClusterInfo","description":"A Louvain community — a densely-linked group of memories."},"ConflictItem":{"properties":{"id":{"type":"string","title":"Id"},"path":{"type":"string","title":"Path"},"title":{"type":"string","title":"Title"},"content":{"type":"string","title":"Content"},"status":{"type":"string","title":"Status"},"reason":{"type":"string","title":"Reason"},"confidence":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Confidence"},"ai_reasoning_summary":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Ai Reasoning Summary"}},"type":"object","required":["id","path","title","content","status","reason"],"title":"ConflictItem","description":"A memory flagged conflicting/needs-review — reviewed inline in /organize\n(the former /needs-review tab merged here). Carries id/content/status so the\npage can render the full review card + feedback buttons."},"ConsolidateRequest":{"properties":{"paths":{"items":{"type":"string"},"type":"array","maxItems":100,"minItems":2,"title":"Paths"}},"type":"object","required":["paths"],"title":"ConsolidateRequest","description":"POST /v1/memories/consolidate request body (P7-2)."},"ConsolidateResponse":{"properties":{"merged":{"$ref":"#/components/schemas/MemoryRead"},"archived_paths":{"items":{"type":"string"},"type":"array","title":"Archived Paths"}},"type":"object","required":["merged","archived_paths"],"title":"ConsolidateResponse","description":"POST /v1/memories/consolidate response (P7-2).\n\nReturns the freshly inserted merged memory plus the paths that were\narchived in the process (so the caller can refresh its UI / cache)."},"ContradictsPair":{"properties":{"edge_id":{"type":"string","format":"uuid","title":"Edge Id"},"relation_type":{"type":"string","title":"Relation Type"},"status":{"type":"string","title":"Status"},"edge_created_at":{"type":"string","format":"date-time","title":"Edge Created At"},"source_memory_id":{"type":"string","format":"uuid","title":"Source Memory Id"},"target_memory_id":{"type":"string","format":"uuid","title":"Target Memory Id"},"source_path":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Source Path"},"source_title":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Source Title"},"source_summary":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Source Summary"},"target_path":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Target Path"},"target_title":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Target Title"},"target_summary":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Target Summary"},"ai_reasoning":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Ai Reasoning"}},"type":"object","required":["edge_id","relation_type","status","edge_created_at","source_memory_id","target_memory_id"],"title":"ContradictsPair","description":"A tension edge (contradicts / raises_question) with both ends judgeable\nin place (P16-4+5) — summaries prefer summary_for_ai → summary → content."},"DedupInfo":{"properties":{"relation":{"type":"string","enum":["same","similar","related","conflicting","new"],"title":"Relation"},"suggested_path":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Suggested Path"},"rationale":{"type":"string","title":"Rationale","default":""},"similarity":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Similarity"}},"type":"object","required":["relation"],"title":"DedupInfo","description":"Advisory write-time dedup result — Phase 13 P13-2 (SPEC §10 + §15 #17).\n\nRides on the ``POST /v1/memories`` response body **only** (never persisted).\nThe server always saves the memory (201); this tells the client/user that\nthe new memory resembles an existing one so they can choose to merge into\n``suggested_path``. Propose-only — the server never blocks or auto-mutates."},"DuplicateCluster":{"properties":{"paths":{"items":{"type":"string"},"type":"array","title":"Paths"},"titles":{"items":{"type":"string"},"type":"array","title":"Titles"},"similarity":{"type":"number","title":"Similarity"}},"type":"object","required":["paths","titles","similarity"],"title":"DuplicateCluster","description":"A set of near-duplicate memories proposed for a merge (consolidate)."},"EpisodeCreate":{"properties":{"raw_text":{"type":"string","maxLength":100000,"minLength":1,"title":"Raw Text"},"kind":{"type":"string","enum":["conversation","note","document","event","task","other"],"title":"Kind","default":"conversation"},"title":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Title"},"participants":{"anyOf":[{"items":{"type":"string"},"type":"array"},{"type":"null"}],"title":"Participants"},"project_hint":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Project Hint"},"source_kind":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Source Kind"},"source_id":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Source Id"},"occurred_at":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Occurred At"}},"type":"object","required":["raw_text"],"title":"EpisodeCreate","description":"POST /v1/episodes request body — SPEC §9.1."},"EpisodeListResponse":{"properties":{"items":{"items":{"$ref":"#/components/schemas/EpisodeRead"},"type":"array","title":"Items"},"total":{"type":"integer","minimum":0.0,"title":"Total"}},"type":"object","required":["items","total"],"title":"EpisodeListResponse","description":"GET /v1/episodes response."},"EpisodeProcessResult":{"properties":{"episode":{"$ref":"#/components/schemas/EpisodeRead"},"outcomes":{"items":{"$ref":"#/components/schemas/CandidateOutcome"},"type":"array","title":"Outcomes"},"created":{"type":"integer","title":"Created","default":0},"skipped":{"type":"integer","title":"Skipped","default":0},"dropped":{"type":"integer","title":"Dropped","default":0}},"type":"object","required":["episode","outcomes"],"title":"EpisodeProcessResult","description":"POST /v1/episodes response — the stored episode + pipeline outcomes."},"EpisodeRead":{"properties":{"id":{"type":"string","format":"uuid","title":"Id"},"kind":{"type":"string","title":"Kind"},"title":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Title"},"project_hint":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Project Hint"},"status":{"type":"string","title":"Status"},"created_at":{"type":"string","format":"date-time","title":"Created At"},"processed_at":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Processed At"},"occurred_at":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Occurred At"}},"type":"object","required":["id","kind","status","created_at"],"title":"EpisodeRead","description":"Episode summary surfaced on ingest + GET."},"FeedbackCreate":{"properties":{"memory_id":{"type":"string","format":"uuid","title":"Memory Id"},"folder_path":{"type":"string","title":"Folder Path"},"signal":{"type":"string","enum":["correct","wrong","move"],"title":"Signal"}},"type":"object","required":["memory_id","folder_path","signal"],"title":"FeedbackCreate","description":"POST /v1/feedback request body.\n\n``memory_id`` identifies the memory; ``folder_path`` is the placement the\nfeedback is about (primary or a secondary); ``signal`` is the verdict."},"FeedbackRead":{"properties":{"id":{"type":"string","format":"uuid","title":"Id"},"memory_id":{"type":"string","format":"uuid","title":"Memory Id"},"folder_path":{"type":"string","title":"Folder Path"},"signal":{"type":"string","title":"Signal"},"created_at":{"type":"string","format":"date-time","title":"Created At"}},"type":"object","required":["id","memory_id","folder_path","signal","created_at"],"title":"FeedbackRead","description":"A stored feedback event."},"FolderMaintenanceProposal":{"properties":{"merge_candidates":{"items":{"$ref":"#/components/schemas/FolderMergeCandidate"},"type":"array","title":"Merge Candidates"},"split_candidates":{"items":{"$ref":"#/components/schemas/FolderSplitCandidate"},"type":"array","title":"Split Candidates"},"summary":{"$ref":"#/components/schemas/FolderMaintenanceSummary"}},"type":"object","required":["summary"],"title":"FolderMaintenanceProposal","description":"``GET /v1/folders/maintenance`` response (§14). Proposals only — no\nmutation. Count-based MVP; full §14.2 similarity-merge / §14.3 cluster-split\nis deferred (DECISIONS 2026-06-02)."},"FolderMaintenanceSummary":{"properties":{"total_folders":{"type":"integer","title":"Total Folders"},"merge_candidates":{"type":"integer","title":"Merge Candidates"},"split_candidates":{"type":"integer","title":"Split Candidates"}},"type":"object","required":["total_folders","merge_candidates","split_candidates"],"title":"FolderMaintenanceSummary"},"FolderMergeCandidate":{"properties":{"folder":{"type":"string","title":"Folder"},"parent":{"type":"string","title":"Parent"},"count":{"type":"integer","title":"Count"},"sibling_folders":{"items":{"type":"string"},"type":"array","title":"Sibling Folders"},"reason":{"type":"string","title":"Reason"}},"type":"object","required":["folder","parent","count","reason"],"title":"FolderMergeCandidate","description":"A small folder that fragments its parent (§14.1/§14.2 cond4) — propose\nconsolidating it with a sibling. Advisory: the server names no target and\nnever moves; the user applies via ``POST /v1/memories/move``."},"FolderSplitCandidate":{"properties":{"folder":{"type":"string","title":"Folder"},"count":{"type":"integer","title":"Count"},"reason":{"type":"string","title":"Reason"}},"type":"object","required":["folder","count","reason"],"title":"FolderSplitCandidate","description":"An oversized folder (§14.3) — propose splitting into sub-topics. Advisory;\nthe server proposes no concrete split (semantic clustering is deferred)."},"GapPair":{"properties":{"cluster_a":{"type":"integer","title":"Cluster A"},"cluster_b":{"type":"integer","title":"Cluster B"},"bridge_memory_id":{"anyOf":[{"type":"string","format":"uuid"},{"type":"null"}],"title":"Bridge Memory Id"}},"type":"object","required":["cluster_a","cluster_b"],"title":"GapPair","description":"Two clusters with at most one direct edge — a structural gap.\n\nThe research-backed locus of creative discovery (Burt structural holes):\nP16-3 feeds these pairs to an LLM to propose bridging questions.\n``bridge_memory_id`` is the higher-betweenness endpoint of the single\nconnecting edge, or ``None`` when the clusters share no edge at all."},"GapQuestion":{"properties":{"cluster_a_ids":{"items":{"type":"string","format":"uuid"},"type":"array","title":"Cluster A Ids"},"cluster_b_ids":{"items":{"type":"string","format":"uuid"},"type":"array","title":"Cluster B Ids"},"cluster_a_paths":{"items":{"type":"string"},"type":"array","title":"Cluster A Paths"},"cluster_b_paths":{"items":{"type":"string"},"type":"array","title":"Cluster B Paths"},"bridge_memory_id":{"anyOf":[{"type":"string","format":"uuid"},{"type":"null"}],"title":"Bridge Memory Id"},"question":{"type":"string","title":"Question"}},"type":"object","required":["cluster_a_ids","cluster_b_ids","cluster_a_paths","cluster_b_paths","question"],"title":"GapQuestion","description":"One structural gap + the LLM's exploratory bridging question (P16-3)."},"GapsInsightResponse":{"properties":{"gaps":{"items":{"$ref":"#/components/schemas/GapQuestion"},"type":"array","title":"Gaps"},"message":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Message"}},"type":"object","required":["gaps"],"title":"GapsInsightResponse","description":"GET /v1/insights/gaps — bridging questions, advisory only."},"GeologyMemory":{"properties":{"memory_id":{"type":"string","format":"uuid","title":"Memory Id"},"path":{"type":"string","title":"Path"},"title":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Title"},"depth":{"type":"number","minimum":0.0,"title":"Depth"},"channel_width":{"type":"integer","minimum":0.0,"title":"Channel Width"},"weathering":{"anyOf":[{"type":"number","minimum":0.0},{"type":"null"}],"title":"Weathering"},"bedrock_score":{"type":"integer","minimum":0.0,"title":"Bedrock Score"},"recent_recalls":{"items":{"$ref":"#/components/schemas/RecallTick"},"type":"array","title":"Recent Recalls"}},"type":"object","required":["memory_id","path","depth","channel_width","bedrock_score"],"title":"GeologyMemory","description":"One memory's measured terrain — Phase 17 P17-4 (기억의 지질학 §5).\n\nRAW values only (days / counts): the rate/k constants of the 물리 법칙 are\nvisualization parameters, applied client-side (\"디자인하지 말고\n시뮬레이션하라\" — the server reports what happened, CEO 2026-06-11 ①).\n``weathering=None`` = never recalled yet (NULL = \"not yet\" semantics, ②)."},"GeologyResponse":{"properties":{"memories":{"items":{"$ref":"#/components/schemas/GeologyMemory"},"type":"array","title":"Memories"},"stats":{"$ref":"#/components/schemas/GeologyStats"}},"type":"object","required":["memories","stats"],"title":"GeologyResponse","description":"GET /v1/insights/geology — on-demand, read-only, nothing persisted."},"GeologyStats":{"properties":{"total_memories":{"type":"integer","minimum":0.0,"title":"Total Memories"},"avg_depth":{"type":"number","minimum":0.0,"title":"Avg Depth"},"max_channel_width":{"type":"integer","minimum":0.0,"title":"Max Channel Width"},"avg_bedrock_score":{"type":"number","minimum":0.0,"title":"Avg Bedrock Score"}},"type":"object","required":["total_memories","avg_depth","max_channel_width","avg_bedrock_score"],"title":"GeologyStats","description":"Aggregate terrain statistics — all zeros over an empty terrain."},"GraphInsightResponse":{"properties":{"clusters":{"items":{"$ref":"#/components/schemas/ClusterInfo"},"type":"array","title":"Clusters"},"bridges":{"items":{"$ref":"#/components/schemas/BridgeInfo"},"type":"array","title":"Bridges"},"gap_pairs":{"items":{"$ref":"#/components/schemas/GapPair"},"type":"array","title":"Gap Pairs"},"node_count":{"type":"integer","minimum":0.0,"title":"Node Count"},"edge_count":{"type":"integer","minimum":0.0,"title":"Edge Count"}},"type":"object","required":["clusters","bridges","gap_pairs","node_count","edge_count"],"title":"GraphInsightResponse","description":"GET /v1/insights/graph — on-demand, read-only, nothing persisted."},"HTTPValidationError":{"properties":{"detail":{"items":{"$ref":"#/components/schemas/ValidationError"},"type":"array","title":"Detail"}},"type":"object","title":"HTTPValidationError"},"ImportItemIn":{"properties":{"text":{"type":"string","maxLength":8000,"minLength":1,"title":"Text"},"title":{"anyOf":[{"type":"string","maxLength":300},{"type":"null"}],"title":"Title"},"occurred_at":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Occurred At"},"source_id":{"anyOf":[{"type":"string","maxLength":200},{"type":"null"}],"title":"Source Id"}},"type":"object","required":["text"],"title":"ImportItemIn","description":"One chunk of one conversation."},"ImportItemsIn":{"properties":{"items":{"items":{"$ref":"#/components/schemas/ImportItemIn"},"type":"array","maxItems":100,"minItems":1,"title":"Items"}},"type":"object","required":["items"],"title":"ImportItemsIn","description":"POST /v1/imports/{id}/items request body."},"ImportJobCreate":{"properties":{"source_kind":{"type":"string","enum":["chatgpt","claude"],"title":"Source Kind"}},"type":"object","required":["source_kind"],"title":"ImportJobCreate","description":"POST /v1/imports request body."},"ImportJobListResponse":{"properties":{"items":{"items":{"$ref":"#/components/schemas/ImportJobRead"},"type":"array","title":"Items"},"total":{"type":"integer","minimum":0.0,"title":"Total"}},"type":"object","required":["items","total"],"title":"ImportJobListResponse"},"ImportJobRead":{"properties":{"id":{"type":"string","format":"uuid","title":"Id"},"source_kind":{"type":"string","title":"Source Kind"},"status":{"type":"string","title":"Status"},"total_items":{"type":"integer","minimum":0.0,"title":"Total Items"},"done_items":{"type":"integer","minimum":0.0,"title":"Done Items"},"failed_items":{"type":"integer","minimum":0.0,"title":"Failed Items"},"created_count":{"type":"integer","minimum":0.0,"title":"Created Count"},"skipped_count":{"type":"integer","minimum":0.0,"title":"Skipped Count"},"dropped_count":{"type":"integer","minimum":0.0,"title":"Dropped Count"},"error":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Error"},"created_at":{"type":"string","format":"date-time","title":"Created At"},"started_at":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Started At"},"finished_at":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Finished At"}},"type":"object","required":["id","source_kind","status","total_items","done_items","failed_items","created_count","skipped_count","dropped_count","created_at"],"title":"ImportJobRead","description":"Job + progress. Polled by the dashboard while the background loop runs."},"MemoryArchiveResponse":{"properties":{"archived":{"type":"boolean","title":"Archived"},"path":{"type":"string","title":"Path"},"archived_at":{"type":"string","format":"date-time","title":"Archived At"}},"type":"object","required":["archived","path","archived_at"],"title":"MemoryArchiveResponse","description":"DELETE /v1/memories/{path:path} response — SPEC §5.3 line 426-429."},"MemoryCreate":{"properties":{"path":{"type":"string","maxLength":1024,"minLength":1,"title":"Path"},"title":{"anyOf":[{"type":"string","maxLength":1024},{"type":"null"}],"title":"Title"},"content":{"type":"string","maxLength":100000,"minLength":1,"title":"Content"},"tags":{"items":{"type":"string"},"type":"array","maxItems":64,"title":"Tags"},"importance":{"type":"number","maximum":1.0,"minimum":0.0,"title":"Importance","default":0.5},"source":{"$ref":"#/components/schemas/Source"}},"type":"object","required":["path","content","source"],"title":"MemoryCreate","description":"POST /v1/memories request body — SPEC §5.3 line 346-356."},"MemoryEdit":{"properties":{"old":{"type":"string","minLength":1,"title":"Old"},"new":{"type":"string","title":"New"}},"type":"object","required":["old","new"],"title":"MemoryEdit","description":"Single str_replace edit — SPEC §5.3 PATCH Mode B."},"MemoryListItem":{"properties":{"path":{"type":"string","title":"Path"},"title":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Title"},"summary":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Summary"},"tags":{"items":{"type":"string"},"type":"array","title":"Tags"},"source":{"type":"string","title":"Source"},"updated_at":{"type":"string","format":"date-time","title":"Updated At"},"occurred_at":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Occurred At"}},"type":"object","required":["path","tags","source","updated_at"],"title":"MemoryListItem","description":"GET /v1/memories items[] — SPEC §5.3 line 304-316.\n\n``source`` is a plain ``str`` (not the ``Source`` enum) so values written\noutside the request enum — e.g. ``consolidate`` — surface without error."},"MemoryListResponse":{"properties":{"items":{"items":{"$ref":"#/components/schemas/MemoryListItem"},"type":"array","title":"Items"},"total":{"type":"integer","minimum":0.0,"title":"Total"}},"type":"object","required":["items","total"],"title":"MemoryListResponse","description":"GET /v1/memories response — SPEC §5.3 line 305-317."},"MemoryPatch":{"properties":{"content":{"anyOf":[{"type":"string","maxLength":100000},{"type":"null"}],"title":"Content"},"edits":{"anyOf":[{"items":{"$ref":"#/components/schemas/MemoryEdit"},"type":"array","maxItems":200},{"type":"null"}],"title":"Edits"},"title":{"anyOf":[{"type":"string","maxLength":1024},{"type":"null"}],"title":"Title"}},"type":"object","title":"MemoryPatch","description":"PATCH /v1/memories/{path:path} request — SPEC §5.3 line 360-379.\n\n본문은 `content` (Mode A — full replace) 또는 `edits` (Mode B — surgical\nstr_replace) 중 **정확히 하나**로 바꾼다. 둘 다 생략하고 `title` 만 보내면\n제목만 바뀐다(본문 불변) — 2026-08-23, 그전까지 제목은 생성 시에만 정할 수\n있어서 \"이름 바꾸기\" 가 불가능했다."},"MemoryPurgeResponse":{"properties":{"purged":{"type":"boolean","title":"Purged"},"path":{"type":"string","title":"Path"},"rows_deleted":{"type":"integer","minimum":0.0,"title":"Rows Deleted"}},"type":"object","required":["purged","path","rows_deleted"],"title":"MemoryPurgeResponse","description":"DELETE /v1/memories/{path:path}?purge=true response — hard delete.\n\nSPEC §14.9 EXCEPTION (2026-06-10, owner-approved): permanent removal of an\nalready-archived memory from the 보관함. Distinct from MemoryArchiveResponse\n(which is reversible) — there is no ``archived_at`` because the row is gone."},"MemoryRead":{"properties":{"id":{"type":"string","format":"uuid","title":"Id"},"path":{"type":"string","title":"Path"},"title":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Title"},"content":{"type":"string","title":"Content"},"summary":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Summary"},"tags":{"items":{"type":"string"},"type":"array","title":"Tags"},"importance":{"type":"number","title":"Importance"},"source":{"type":"string","title":"Source"},"version":{"type":"integer","title":"Version"},"created_at":{"type":"string","format":"date-time","title":"Created At"},"updated_at":{"type":"string","format":"date-time","title":"Updated At"},"type":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Type"},"scope":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Scope"},"status":{"type":"string","title":"Status","default":"active"},"confidence":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Confidence"},"privacy_sensitivity":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Privacy Sensitivity"},"secondary_folders":{"items":{"type":"string"},"type":"array","title":"Secondary Folders"},"source_kind":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Source Kind"},"source_id":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Source Id"},"evidence_quote":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Evidence Quote"},"ai_reasoning_summary":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Ai Reasoning Summary"},"valid_from":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Valid From"},"valid_until":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Valid Until"},"occurred_at":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Occurred At"},"summary_for_ai":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Summary For Ai"},"retrieval_keywords":{"anyOf":[{"items":{"type":"string"},"type":"array"},{"type":"null"}],"title":"Retrieval Keywords"},"embedding_text":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Embedding Text"},"folder_context":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Folder Context"},"related_memory_ids":{"anyOf":[{"items":{"type":"string","format":"uuid"},"type":"array"},{"type":"null"}],"title":"Related Memory Ids"},"dedup":{"anyOf":[{"$ref":"#/components/schemas/DedupInfo"},{"type":"null"}]}},"type":"object","required":["id","path","content","tags","importance","source","version","created_at","updated_at"],"title":"MemoryRead","description":"GET /v1/memories/{path:path} response — SPEC §5.3 line 326-339.\n\n`summary` is included even though SPEC's example omits it: the column exists\n(SPEC §4.1) and list responses surface it, so a single-memory read should too."},"MoveItem":{"properties":{"from_path":{"type":"string","maxLength":1024,"minLength":1,"title":"From Path"},"to_path":{"type":"string","maxLength":1024,"minLength":1,"title":"To Path"}},"type":"object","required":["from_path","to_path"],"title":"MoveItem","description":"A single path remap — move the memory at ``from_path`` to ``to_path``."},"MoveRequest":{"properties":{"moves":{"items":{"$ref":"#/components/schemas/MoveItem"},"type":"array","maxItems":2000,"minItems":1,"title":"Moves"}},"type":"object","required":["moves"],"title":"MoveRequest","description":"POST /v1/memories/move — relocate memories (a file or a whole folder).\n\nThe client computes the explicit per-memory remaps (it knows the tree); the\nserver validates ownership + conflicts and applies them atomically. A pure\npath change — content/version/embedding are untouched."},"MoveResponse":{"properties":{"moved":{"type":"integer","minimum":0.0,"title":"Moved"}},"type":"object","required":["moved"],"title":"MoveResponse"},"NeedsReviewResponse":{"properties":{"items":{"items":{"$ref":"#/components/schemas/MemoryRead"},"type":"array","title":"Items"},"total":{"type":"integer","minimum":0.0,"title":"Total"}},"type":"object","required":["items","total"],"title":"NeedsReviewResponse","description":"GET /v1/needs-review response — memories flagged needs_review/conflicting.\n\nFull ``MemoryRead`` items so the UI sees status + ``ai_reasoning_summary`` +\n``secondary_folders`` + confidence (the routing explanation, AC#7)."},"OrganizeAudit":{"properties":{"moves":{"items":{"$ref":"#/components/schemas/AuditMove"},"type":"array","title":"Moves"},"supplements":{"items":{"$ref":"#/components/schemas/AuditSupplement"},"type":"array","title":"Supplements"},"deletes":{"items":{"$ref":"#/components/schemas/AuditDelete"},"type":"array","title":"Deletes"},"audited":{"type":"integer","title":"Audited"},"skipped":{"type":"integer","title":"Skipped"}},"type":"object","required":["moves","supplements","deletes","audited","skipped"],"title":"OrganizeAudit"},"OrganizeProposal":{"properties":{"duplicate_clusters":{"items":{"$ref":"#/components/schemas/DuplicateCluster"},"type":"array","title":"Duplicate Clusters"},"conflicts":{"items":{"$ref":"#/components/schemas/ConflictItem"},"type":"array","title":"Conflicts"},"stale":{"items":{"$ref":"#/components/schemas/StaleItem"},"type":"array","title":"Stale"},"summary":{"$ref":"#/components/schemas/OrganizeSummary"}},"type":"object","required":["duplicate_clusters","conflicts","stale","summary"],"title":"OrganizeProposal"},"OrganizeSummary":{"properties":{"total":{"type":"integer","title":"Total"},"duplicate_clusters":{"type":"integer","title":"Duplicate Clusters"},"conflicts":{"type":"integer","title":"Conflicts"},"stale":{"type":"integer","title":"Stale"}},"type":"object","required":["total","duplicate_clusters","conflicts","stale"],"title":"OrganizeSummary"},"RecallTick":{"properties":{"recalled_at":{"type":"string","format":"date","title":"Recalled At"},"kind":{"type":"string","title":"Kind"}},"type":"object","required":["recalled_at","kind"],"title":"RecallTick","description":"One recall event, day-truncated — W4 회상 리듬 (성좌 다차원 강화 §6).\n\nThe scalar ``channel_width``/``weathering`` collapse a memory's whole recall\nhistory into two numbers; this restores the per-event rhythm (\"꾸준히 vs\n몰아서\"). ``recalled_at`` is truncated to the day (response size + §7 data\nminimization); ``kind`` distinguishes a search summon from a direct read."},"RecentSignup":{"properties":{"email":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Email"},"created_at":{"type":"string","format":"date-time","title":"Created At"}},"type":"object","required":["created_at"],"title":"RecentSignup"},"RelationListResponse":{"properties":{"items":{"items":{"$ref":"#/components/schemas/RelationRead"},"type":"array","title":"Items"},"total":{"type":"integer","minimum":0.0,"title":"Total"}},"type":"object","required":["items","total"],"title":"RelationListResponse","description":"GET /v1/relations?memory_id= — edges touching a memory (in + out)."},"RelationRead":{"properties":{"id":{"type":"string","format":"uuid","title":"Id"},"source_memory_id":{"type":"string","format":"uuid","title":"Source Memory Id"},"target_memory_id":{"type":"string","format":"uuid","title":"Target Memory Id"},"relation_type":{"type":"string","title":"Relation Type"},"confidence":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Confidence"},"status":{"type":"string","title":"Status"},"ai_reasoning":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Ai Reasoning"},"created_at":{"type":"string","format":"date-time","title":"Created At"},"source_path":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Source Path"},"target_path":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Target Path"},"target_title":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Target Title"},"source_summary":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Source Summary"},"target_summary":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Target Summary"},"source_type":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Source Type"},"target_type":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Target Type"},"source_updated_at":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Source Updated At"},"target_updated_at":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Target Updated At"}},"type":"object","required":["id","source_memory_id","target_memory_id","relation_type","status","created_at"],"title":"RelationRead","description":"A directed knowledge-graph edge between two memories."},"RelationsInsightResponse":{"properties":{"contradicts":{"items":{"$ref":"#/components/schemas/ContradictsPair"},"type":"array","title":"Contradicts"},"questions":{"items":{"$ref":"#/components/schemas/ContradictsPair"},"type":"array","title":"Questions"},"total":{"type":"integer","minimum":0.0,"title":"Total"},"include_proposed":{"type":"boolean","title":"Include Proposed"}},"type":"object","required":["contradicts","questions","total","include_proposed"],"title":"RelationsInsightResponse","description":"GET /v1/insights/relations — 모순(변증법) + 열린 질문, LLM 0-call list."},"ReservationRequest":{"properties":{"plan_intent":{"anyOf":[{"type":"string","enum":["monthly","annual"]},{"type":"null"}],"title":"Plan Intent"},"locale":{"anyOf":[{"type":"string","maxLength":16},{"type":"null"}],"title":"Locale"},"marketing_consent":{"type":"boolean","title":"Marketing Consent","default":false}},"type":"object","title":"ReservationRequest"},"ReservationStatus":{"properties":{"reserved":{"type":"boolean","title":"Reserved"},"total":{"type":"integer","minimum":0.0,"title":"Total"},"cap":{"type":"integer","minimum":0.0,"title":"Cap"},"spots_left":{"type":"integer","minimum":0.0,"title":"Spots Left"},"plan_intent":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Plan Intent"},"created_at":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Created At"}},"type":"object","required":["reserved","total","cap","spots_left"],"title":"ReservationStatus"},"RestoreRequest":{"properties":{"path":{"type":"string","title":"Path"}},"type":"object","required":["path"],"title":"RestoreRequest","description":"POST /v1/memories/restore — un-archive (복구) the latest archived memory\nat ``path``. Only valid when no current memory occupies the path."},"SchemaRead":{"properties":{"content":{"type":"string","title":"Content"},"version":{"type":"integer","title":"Version"},"updated_at":{"type":"string","format":"date-time","title":"Updated At"}},"type":"object","required":["content","version","updated_at"],"title":"SchemaRead","description":"GET /v1/schema response — SPEC §5.3 line 277-283."},"SchemaUpdate":{"properties":{"content":{"type":"string","maxLength":200000,"minLength":1,"title":"Content"}},"type":"object","required":["content"],"title":"SchemaUpdate","description":"PUT /v1/schema request — SPEC §5.3 line 289-292."},"SearchFilters":{"properties":{"path_prefix":{"anyOf":[{"type":"string","maxLength":1024},{"type":"null"}],"title":"Path Prefix"},"tags":{"anyOf":[{"items":{"type":"string"},"type":"array"},{"type":"null"}],"title":"Tags"},"min_importance":{"anyOf":[{"type":"number","maximum":1.0,"minimum":0.0},{"type":"null"}],"title":"Min Importance"},"source":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Source"}},"type":"object","title":"SearchFilters","description":"Optional filter block — SPEC §5.3 line 392-396 + §6.4 (P9-10 ``source``)."},"SearchHit":{"properties":{"path":{"type":"string","title":"Path"},"title":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Title"},"summary":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Summary"},"score":{"type":"number","title":"Score"},"snippet":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Snippet"},"matched_via":{"items":{"type":"string"},"type":"array","title":"Matched Via"},"status":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Status"},"summary_for_ai":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Summary For Ai"},"retrieval_keywords":{"anyOf":[{"items":{"type":"string"},"type":"array"},{"type":"null"}],"title":"Retrieval Keywords"},"related_memory_ids":{"anyOf":[{"items":{"type":"string","format":"uuid"},"type":"array"},{"type":"null"}],"title":"Related Memory Ids"},"folder_context":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Folder Context"}},"type":"object","required":["path","score","matched_via"],"title":"SearchHit","description":"Single search result — SPEC §5.3 line 403-411.\n\n`matched_via` lists the retrieval signals that surfaced this hit\n(e.g. ``[\"semantic\", \"bm25\"]``). Phase 2 emits only `[\"semantic\"]`;\nPhase 3 adds `\"bm25\"` once RRF merge lands."},"SearchRequest":{"properties":{"query":{"type":"string","maxLength":2000,"minLength":1,"title":"Query"},"limit":{"type":"integer","maximum":50.0,"minimum":1.0,"title":"Limit","default":5},"filters":{"anyOf":[{"$ref":"#/components/schemas/SearchFilters"},{"type":"null"}]}},"type":"object","required":["query"],"title":"SearchRequest","description":"POST /v1/search request — SPEC §5.3 line 388-398."},"SearchResponse":{"properties":{"results":{"items":{"$ref":"#/components/schemas/SearchHit"},"type":"array","title":"Results"}},"type":"object","required":["results"],"title":"SearchResponse","description":"POST /v1/search response — SPEC §5.3 line 401-413."},"Source":{"type":"string","enum":["claude","chatgpt","grok","codex","claude-code","manual","quick","system"],"title":"Source"},"StaleItem":{"properties":{"path":{"type":"string","title":"Path"},"title":{"type":"string","title":"Title"},"importance":{"type":"number","title":"Importance"}},"type":"object","required":["path","title","importance"],"title":"StaleItem","description":"A low-value memory proposed for archive (soft-delete, recoverable)."},"SurfaceItem":{"properties":{"path":{"type":"string","title":"Path"},"title":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Title"},"summary":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Summary"},"score":{"type":"number","minimum":0.0,"title":"Score"},"reason":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Reason"}},"type":"object","required":["path","score"],"title":"SurfaceItem","description":"One surfaced memory — deep, dormant, yet semantically touching the now."},"SurfaceRequest":{"properties":{"context":{"type":"string","maxLength":4000,"title":"Context","default":""},"limit":{"type":"integer","maximum":10.0,"minimum":1.0,"title":"Limit","default":5}},"type":"object","title":"SurfaceRequest","description":"POST /v1/insights/surface — 시추(프루스트 트리거, Phase 19 P19-1).\n\nThe AI passes its current conversation context; the server surfaces deep +\nweathered + semantically-near memories (the OPPOSITE of search — what you\ndidn't ask for but are standing on)."},"SurfaceResponse":{"properties":{"items":{"items":{"$ref":"#/components/schemas/SurfaceItem"},"type":"array","title":"Items"},"context_used":{"type":"string","title":"Context Used"}},"type":"object","required":["items","context_used"],"title":"SurfaceResponse","description":"POST /v1/insights/surface — on-demand, read-only, NOTHING persisted.\n\nThe surfacing is the SERVER recalling, not the user — so it does NOT log a\nrecall_event (that would reset weathering and self-destruct the very signal\nit rides on; DECISIONS ## 정책, 2026-06-14)."},"SynthesisResponse":{"properties":{"edge_id":{"type":"string","format":"uuid","title":"Edge Id"},"synthesis_draft":{"type":"string","title":"Synthesis Draft"}},"type":"object","required":["edge_id","synthesis_draft"],"title":"SynthesisResponse","description":"POST /v1/insights/relations/{id}/synthesize — LLM draft only, NOT stored.\n\nThe user accepts a draft by saving it through the existing\n``POST /v1/memories`` (server auto-mutation stays 0)."},"ValidationError":{"properties":{"loc":{"items":{"anyOf":[{"type":"string"},{"type":"integer"}]},"type":"array","title":"Location"},"msg":{"type":"string","title":"Message"},"type":{"type":"string","title":"Error Type"},"input":{"title":"Input"},"ctx":{"type":"object","title":"Context"}},"type":"object","required":["loc","msg","type"],"title":"ValidationError"},"WhoamiResponse":{"properties":{"user_id":{"type":"string","format":"uuid","title":"User Id"},"email":{"type":"string","title":"Email"},"is_admin":{"type":"boolean","title":"Is Admin","default":false}},"type":"object","required":["user_id","email"],"title":"WhoamiResponse","description":"GET /v1/auth/whoami — the lightest possible authenticated probe (U2).\n\nExists so the MCP token verifier (and any client health check) can validate\na Bearer without paying for a memory list query."}},"securitySchemes":{"HTTPBearer":{"type":"http","scheme":"bearer"}}}}