{"contextKind":"public_baseline","language":"en","id":"work-repository","version":"0.1","contractDigest":"sha256:c44422bb9dc074e87573e14b95feee6124d897b2f49481f5402748d012ef0bcc","title":"Work Repository","kind":"repository-contract","files":[{"path":"contracts/work-repository/work-repository-contract-v0.1.md","digest":"sha256:355552fa54ee230ef60e651e18f35eb913ef41664b7bf6b59e7c6b386516bba0","mediaType":"text/markdown","content":"---\nrole: exploration\nlifecycle: draft\nversion: \"0.1\"\nlanguage: en\n---\n# OrivelaIQ Work Repository Contract v0.1\n\n## 1. Purpose\n\nThis contract defines a portable, Git-native representation of existing OrivelaIQ Work semantics for manual repository import.\n\nIt does not create a second Work model.\n\nThe repository representation follows the implemented Work aggregate exactly:\n\n```text\nTopic\n  └── Item\n        └── Entry\n              type = INSIGHT | CLARIFICATION_POINT | DECISION | RESULT\n```\n\nRepository files are structured Work definition data. They are not Knowledge Artifacts and are never processed by Knowledge indexing.\n\nThe v0.1 operating model is deliberately manual:\n\n```text\nsaved import configuration\n        ↓\nHuman starts import\n        ↓\nPLAN\n        ↓\npreview / blockers\n        ↓\nHuman starts APPLY\n        ↓\nshared OrivelaIQ Work\n```\n\nv0.1 has no automatic polling, scheduled PLAN or automatic APPLY.\n\n## 2. Core boundary\n\n> Git carries portable Work definitions. OrivelaIQ owns Work identity, authorization and runtime state.\n\nThe repository describes intended Topic / Item / Entry content and selected links.\n\nOrivelaIQ remains authoritative for:\n\n- internal Topic, Item, Entry, Reference and Relation IDs;\n- Topic revision;\n- Topic owner and members;\n- assigned internal Workspace IDs;\n- authenticated actor and channel stamps;\n- Entry creation/update stamps;\n- Clarification Point `open | closed` state;\n- server-resolved Artifact origin/projection evidence;\n- mutation and import receipts.\n\nRepository import must use the same Work authorization and mutation invariants as Browser/MCP.\n\n## 3. Canonical repository format\n\nv0.1 uses JSON only.\n\nRecommended layout:\n\n```text\nwork/\n└── <topic-directory>/\n    ├── topic.json\n    └── items/\n        ├── <item>.json\n        └── ...\n```\n\nPaths are locators only. Stable repository identity is carried by `externalKey`.\n\n## 4. Saved import configuration\n\nRepository connection details are not re-entered for every import.\n\nOrivelaIQ persists one named import configuration for one repository Work root.\n\nA v0.1 configuration contains conceptually:\n\n- configuration ID and revision;\n- display name;\n- GitHub `credentialId`;\n- repository `owner/name`;\n- explicit Git ref;\n- Work root;\n- Workspace alias → internal Workspace ID mappings;\n- optional bound internal Topic ID after the first successful APPLY;\n- created/updated audit metadata.\n\nThe configuration is OrivelaIQ-owned data and is not stored inside the source repository.\n\nThere is no import mode or schedule in v0.1. Every PLAN and APPLY is Human-triggered.\n\n### Configuration authority\n\nExisting GitHub credentials are Admin-only resources.\n\nTherefore:\n\n- only Admin may create, edit or remove an import configuration or select/change its `credentialId`;\n- the configuration stores only the credential ID, never token material;\n- the credential must still be active at PLAN and APPLY;\n- an unbound configuration may be run only by Admin;\n- after first successful APPLY binds the configuration to a Topic, later PLAN/APPLY requires current Topic manage authority: Topic owner or Admin.\n\nThis does not grant a general repository browser. The saved configuration is the explicit server-side delegation to read that one configured repository/ref/root for Work import.\n\n## 5. Topic repository definition\n\nRequired:\n\n- `schemaVersion`\n- `externalKey`\n- `title`\n\nOptional:\n\n- `description`\n\nExample:\n\n```json\n{\n  \"schemaVersion\": \"0.1\",\n  \"externalKey\": \"service-handover\",\n  \"title\": \"Service handover knowledge\",\n  \"description\": \"Capture reusable findings while improving service handover instructions.\"\n}\n```\n\nTopic members, owner and Workspace IDs are not repository fields.\n\nWorkspace assignment required for Artifact References comes from the saved import configuration and remains subject to existing Topic/Workspace authorization.\n\n## 6. Item repository definition\n\nAn Item groups one or more semantic Entries.\n\nRequired:\n\n- `schemaVersion`\n- `externalKey`\n- `topicExternalKey`\n- `title`\n- `entries`\n\nOptional:\n\n- `labels`\n- `knowledgeContextExposure` (`include | exclude`, default `include`)\n- `artifactRefs`\n\nExample:\n\n```json\n{\n  \"schemaVersion\": \"0.1\",\n  \"externalKey\": \"handover-preparation\",\n  \"topicExternalKey\": \"service-handover\",\n  \"title\": \"Service handover preparation\",\n  \"labels\": [\n    \"service-handover\",\n    \"readiness\"\n  ],\n  \"entries\": [\n    {\n      \"externalKey\": \"handover-checklist\",\n      \"type\": \"INSIGHT\",\n      \"text\": \"Service handovers work best when responsibilities, operating instructions and open issues are prepared before the handover meeting.\",\n      \"artifactRefs\": [\n        {\n          \"workspaceAlias\": \"knowledge-base\",\n          \"sourceKey\": \"service-handbook\",\n          \"path\": \"docs/service-handover.md\",\n          \"view\": \"stable\"\n        }\n      ]\n    },\n    {\n      \"externalKey\": \"handover-ownership\",\n      \"type\": \"CLARIFICATION_POINT\",\n      \"text\": \"Clarify who owns the service handover record.\",\n      \"relatesTo\": [\n        \"handover-checklist\"\n      ]\n    }\n  ]\n}\n```\n\nThis mirrors the existing Work model:\n\n- Item owns `title` and `labels`;\n- Entry owns semantic `type` and `text`;\n- Artifact References may belong to Item or Entry;\n- entry-to-entry relation is plain `relates-to`, not a new typed dependency vocabulary.\n\n`knowledgeContextExposure` controls only the derived Knowledge-side Related Work Context projection available in Knowledge. `exclude` does not remove the Item, its Entries, references or relations; it grants and revokes no access. Re-import updates this field while keeping mapped Work identities and runtime clarification state.\n\n## 7. Entry semantics\n\nAllowed types are exactly the implemented Work Entry values:\n\n- `INSIGHT`\n- `CLARIFICATION_POINT`\n- `DECISION`\n- `RESULT`\n\nNo `OPEN_ITEM` type exists in this contract.\n\nOnly `CLARIFICATION_POINT` has runtime state `open | closed`.\n\nThe repository does not author that state. A newly created Clarification Point starts `open` through the existing Work mutation rule; later Browser/MCP/import runs never reopen or close it merely because the JSON is re-imported.\n\nEntry type is immutable after creation. A repository change that attempts to retype an already mapped Entry is a blocking `TYPE_CONFLICT`; the author must use a new Entry `externalKey` when the semantic role truly changes.\n\n## 8. External keys and internal identity\n\nRepository `externalKey` is import identity, not OrivelaIQ Domain identity.\n\nOrivelaIQ continues to generate its existing internal IDs.\n\nThe importer persists a mapping scoped to the saved import configuration:\n\n```text\nconfiguration + object kind + externalKey\n        → internal OrivelaIQ ID\n```\n\nv0.1 requires:\n\n- one Topic definition per import configuration;\n- Topic externalKey unique within that configuration;\n- Item externalKey unique within the Topic;\n- Entry externalKey unique across that Topic so relations can resolve without path coupling.\n\nFile moves and title changes do not create new objects.\n\nBrowser/MCP-created Work without an import mapping remains ordinary Work and is not implicitly adopted by the importer.\n\nIf a removed repository definition later reappears with the same mapped externalKey, it resolves to the same existing Work object.\n\n## 9. Labels\n\nLabels apply to Item exactly as the Work model defines them.\n\nRepository validation mirrors the existing limits:\n\n- maximum eight labels per Item;\n- maximum 30 characters per label;\n- normalization/deduplication is enforced by the Work mutation service.\n\nThe repository does not introduce Topic labels or Entry labels.\n\n## 10. Portable Artifact selectors\n\nRepository JSON cannot store ephemeral internal Artifact IDs or projection IDs.\n\nIt therefore stores a portable selector:\n\n```json\n{\n  \"workspaceAlias\": \"knowledge-base\",\n  \"sourceKey\": \"service-handbook\",\n  \"path\": \"docs/service-handover.md\",\n  \"view\": \"stable\"\n}\n```\n\n`workspaceAlias` resolves through the saved import configuration to one explicitly configured internal Workspace ID.\n\nPLAN must then use the existing authorized Work catalog/projection boundary to resolve the selector to the exact Work mutation tuple:\n\n```text\nworkspaceId\nartifactId\nview\nprojectionId\n```\n\nA plan is APPLY-ready only when the selector resolves uniquely in the current authorized projection and source.\n\nMissing, ambiguous, hidden, unassigned or no-longer-readable targets produce `UNRESOLVED_REFERENCE`.\n\nAPPLY uses the resolved exact tuple through the existing `add_reference` Work invariant. Repository selectors never bypass Work Artifact validation and never become arbitrary URL/path bookmarks.\n\n## 11. Entry relations\n\nWork supports one relation semantic: exact Entry `relates-to`.\n\nRepository Entries may therefore declare:\n\n```json\n{\n  \"relatesTo\": [\n    \"another-entry-external-key\"\n  ]\n}\n```\n\nPLAN resolves both endpoints through the import identity map.\n\nThe existing Work rules apply:\n\n- both Entries exist in the same Topic;\n- self-relations fail;\n- duplicate/reverse-duplicate relations fail;\n- relation creation/removal is authorized through the Topic.\n\nNo `depends_on`, `supports`, `blocks` or `supersedes` Work relation vocabulary is introduced.\n\n## 12. Repository-managed definition surface\n\nFor mapped objects the repository may propose changes only to fields already mutable through Work operations:\n\nTopic:\n\n- `title`\n- `description`\n\nItem:\n\n- `title`\n- `labels`\n- `knowledgeContextExposure` (default `include`; projection preference only)\n\nEntry:\n\n- `text`\n\nEntry `type` is create-time identity and cannot be changed in place.\n\nRepository-declared Artifact References and relates-to edges are import-managed links. Browser/MCP-created links remain outside import management unless they originated from the same import mapping.\n\nNo other Work field is repository-owned.\n\n## 13. Source removal\n\nAbsence is never automatic deletion.\n\nWhen a previously mapped Topic child is no longer defined in the current repository snapshot, PLAN reports:\n\n```text\nSOURCE_REMOVED\n```\n\nv0.1 does not automatically delete the Item/Entry, close a Clarification Point, remove Topic access or otherwise destroy Work.\n\nThe mapping is retained so a later reappearance of the same externalKey resumes the same object.\n\n## 14. PLAN\n\nPLAN is read-only.\n\nIt reads the saved import configuration, resolves the configured ref to an exact Git commit and creates a bounded plan for the single configured Topic.\n\nThe persisted plan contains at minimum:\n\n- `planId`;\n- configuration ID + configuration revision;\n- authenticated planner identity;\n- resolved repository commit SHA;\n- root;\n- target Topic ID when already bound;\n- target Topic revision when already bound;\n- canonical plan digest;\n- validated definition snapshot / hashes;\n- exact resolved Artifact mutation targets;\n- external-key mappings used;\n- proposed Work actions;\n- object/action states and blockers;\n- created-at timestamp.\n\nPLAN performs no Work mutation and no configuration binding mutation.\n\nPlan result states include:\n\n- `CREATE`\n- `UPDATE`\n- `UNCHANGED`\n- `SOURCE_REMOVED`\n- `CONFLICT`\n- `TYPE_CONFLICT`\n- `UNRESOLVED_REFERENCE`\n\n## 15. Three-way comparison\n\nFor repository-managed fields/links, OrivelaIQ stores the last successfully imported canonical repository representation as baseline.\n\nConceptually:\n\n```text\nB = last applied repository definition\nR = current repository definition\nO = current mapped OrivelaIQ definition\n```\n\n- `O = B`, `R != B` → repository change may UPDATE;\n- `R = B`, `O != B` → Browser/MCP change is preserved; no repository overwrite;\n- `R != B`, `O != B` → `CONFLICT`;\n- `R = B`, `O = B` → `UNCHANGED`.\n\nComparison excludes runtime-owned fields such as Topic revision/stamps and Clarification state.\n\nv0.1 performs no automatic semantic conflict merge.\n\n## 16. PLAN freshness\n\nAPPLY must reject a stale plan.\n\nBefore any mutation, APPLY revalidates:\n\n1. the import configuration still exists and its revision equals the planned configuration revision;\n2. the Git credential is still active;\n3. the configured ref still resolves to the exact planned repository commit SHA;\n4. the bound Topic still exists and current manage authority still holds;\n5. the current Topic revision equals the planned Topic revision;\n6. exact planned Artifact projections/targets are still valid and authorized;\n7. the plan digest matches the stored immutable plan payload.\n\nAny mismatch returns `PLAN_STALE` or the relevant authorization/reference error and requires a new PLAN.\n\nFor an unbound first import, APPLY additionally verifies the configuration is still unbound.\n\n## 17. APPLY and existing Work mutation invariants\n\nAPPLY must not write Work tables through a parallel importer-specific mutation model.\n\nImplementation must reuse/factor the existing Work domain mutation rules so the import batch is checked with the same:\n\n- active Human validation;\n- Topic owner/Admin manage boundary where Topic mutation requires it;\n- Topic membership/authorization;\n- Workspace assignment/readability constraints;\n- label limits/normalization;\n- immutable Entry type semantics;\n- exact Artifact reference validation;\n- same-Topic Entry relation rules;\n- Topic aggregate limits;\n- expected Topic revision / stale-write protection;\n- authenticated actor/time/channel attribution.\n\nThe importer compiles repository differences and configured Workspace bindings into the existing Work action vocabulary:\n\n- `create_topic` / `update_topic`;\n- `assign_workspace` when a configured Workspace is not yet assigned to the Topic;\n- `create_item` / `update_item`;\n- `create_entry` / `update_entry`;\n- `add_reference` / `remove_reference`;\n- `add_relation` / `remove_relation`.\n\nIt does not compile repository data into `set_clarification`.\n\nv0.1 never removes a Topic Workspace assignment merely because an alias is removed from the import configuration. Workspace removal remains an explicit existing Work management action.\n\n### Atomicity\n\nOne APPLY is one bounded transaction for one configured Topic.\n\nThe transaction includes:\n\n- all compiled Work changes;\n- Topic revision advancement;\n- external-key → internal-ID mappings;\n- imported baseline snapshot/hash;\n- initial configuration → Topic binding when needed;\n- durable import receipt.\n\nAny failed action or guard rolls back the whole APPLY.\n\nPartial repository import is not a v0.1 outcome.\n\n### Idempotency\n\nAPPLY has a durable `requestId` and immutable `planId` / plan digest.\n\n- same current actor + same requestId + same plan returns the original receipt;\n- same requestId with a different plan/payload conflicts;\n- uncertain client retry cannot create duplicate Topic/Item/Entry/Reference/Relation objects;\n- current Human and Topic authorization are rechecked on replay.\n\nThis extends, rather than bypasses, existing Work request/receipt semantics.\n\n## 18. First import and binding\n\nAn unbound saved configuration represents a potential new Topic.\n\nFirst successful APPLY:\n\n1. creates the Topic through the existing `create_topic` invariant;\n2. creates the configured Items/Entries/links;\n3. persists external-key mappings;\n4. atomically binds the import configuration to the new internal Topic ID.\n\nThe authenticated Admin who runs the unbound import becomes the Topic owner under existing `create_topic` semantics.\n\nSubsequent runs operate only on that bound Topic.\n\nv0.1 does not retarget a configuration to another Topic.\n\n## 19. Git read authority\n\nRepository read uses the existing encrypted GitHub Credential Store.\n\nRules:\n\n- import configuration stores only `credentialId`;\n- raw token is never returned to Browser or stored in Work definitions;\n- configuration creation/edit remains Admin-only because credentials are Admin-only resources;\n- PLAN/APPLY fail when the credential is disabled/error/expired/unavailable;\n- repository access is read-only and limited to the configured repository/ref/root;\n- import never creates/changes a Knowledge Source;\n- import never writes Git;\n- import never treats a Workspace membership as Git repository authority.\n\nThe saved import configuration is the explicit delegation that allows later Topic owner/Admin runs against that configured repository root without exposing the credential itself.\n\n## 20. Manual-only v0.1 UX\n\nThe normal Work experience starts from saved configurations, not repeated source-entry forms.\n\nConceptually:\n\n```text\nWork\n└── Repository imports\n    ├── Service handover knowledge\n    │     service-handbook · main\n    │     /work/service-handover\n    │     [Run import] [Manage]\n    └── ...\n```\n\n`Run import` performs PLAN.\n\nThe Human reviews the plan and explicitly chooses APPLY.\n\n`Manage` reopens the saved configuration.\n\nAutomatic checks, schedules and auto-apply do not appear in v0.1.\n\n## 21. Validation\n\nCanonical schema artifacts:\n\n- `work-topic.schema.json`\n- `work-item.schema.json`\n\nRepository CI may validate them where practical; OrivelaIQ validates again during PLAN.\n\nUnsupported `schemaVersion` fails closed.\n\nThe `read_work_repository_authoring` MCP tool returns these canonical schemas, a complete schema/runtime-valid example and the current Human-authorized saved import contexts. It is a read-only projection of this contract. It does not authorize Git access or replace the existing manual PLAN/Preview/APPLY validation. Schema validity alone does not prove cross-file relation resolution, current Artifact availability, content/aggregate limits, import freshness or absence of conflicts.\n\n## 22. AI authoring rule\n\nAI should create a small coherent Topic → Item → Entry structure with continuing work value.\n\nDo not create one Entry per sentence, slide, transcript paragraph or extracted fact merely because it exists.\n\nThe repository contract is a durable Work authoring surface, not a replacement extraction register.\n\n## 23. Current v0.1 coverage\n\nv0.1 supports:\n\n1. saved manual import configurations;\n2. one repository Work Topic per configuration;\n3. exact Topic → Item → Entry representation;\n4. stable external-key mapping to existing internal IDs;\n5. existing Work labels, Entry types, Artifact References and relates-to relations;\n6. mutation-free PLAN;\n7. freshness validation;\n8. atomic/idempotent APPLY through existing Work invariants;\n9. three-way conflict detection for import-managed definition fields/links;\n10. Clarification runtime-state preservation;\n11. safe `SOURCE_REMOVED` handling;\n12. exact repository revision and durable import receipt traceability.\n\nAutomatic/scheduled import is explicitly outside v0.1.\n"},{"path":"contracts/work-repository/work-topic.schema.json","digest":"sha256:304a9a3e78d2e19d878960d018c8d9f8d665c0b486d237c736b73611d0995fc3","mediaType":"application/json","content":"{\n  \"$schema\": \"https://json-schema.org/draft/2020-12/schema\",\n  \"$id\": \"https://orivelaiq.dev/contracts/work-repository/0.1/work-topic.schema.json\",\n  \"title\": \"OrivelaIQ Work Topic Repository Definition v0.1\",\n  \"type\": \"object\",\n  \"additionalProperties\": false,\n  \"required\": [\n    \"schemaVersion\",\n    \"externalKey\",\n    \"title\"\n  ],\n  \"properties\": {\n    \"schemaVersion\": {\n      \"const\": \"0.1\"\n    },\n    \"externalKey\": {\n      \"type\": \"string\",\n      \"pattern\": \"^[a-z0-9][a-z0-9-]*$\",\n      \"maxLength\": 160\n    },\n    \"title\": {\n      \"type\": \"string\",\n      \"minLength\": 1,\n      \"maxLength\": 160\n    },\n    \"description\": {\n      \"type\": \"string\",\n      \"maxLength\": 1000\n    }\n  }\n}\n"},{"path":"contracts/work-repository/work-item.schema.json","digest":"sha256:c167cd5d5e8bcf364e1b41c7bb0c46fb34da062b790b2d19118a6b7243b07bd7","mediaType":"application/json","content":"{\n  \"$schema\": \"https://json-schema.org/draft/2020-12/schema\",\n  \"$id\": \"https://orivelaiq.dev/contracts/work-repository/0.1/work-item.schema.json\",\n  \"title\": \"OrivelaIQ Work Item Repository Definition v0.1\",\n  \"type\": \"object\",\n  \"additionalProperties\": false,\n  \"required\": [\n    \"schemaVersion\",\n    \"externalKey\",\n    \"topicExternalKey\",\n    \"title\",\n    \"entries\"\n  ],\n  \"properties\": {\n    \"schemaVersion\": {\n      \"const\": \"0.1\"\n    },\n    \"externalKey\": {\n      \"$ref\": \"#/$defs/externalKey\"\n    },\n    \"topicExternalKey\": {\n      \"$ref\": \"#/$defs/externalKey\"\n    },\n    \"title\": {\n      \"type\": \"string\",\n      \"minLength\": 1,\n      \"maxLength\": 160\n    },\n    \"labels\": {\n      \"type\": \"array\",\n      \"maxItems\": 8,\n      \"uniqueItems\": true,\n      \"items\": {\n        \"type\": \"string\",\n        \"minLength\": 1,\n        \"maxLength\": 30\n      }\n    },\n    \"knowledgeContextExposure\": {\n      \"enum\": [\n        \"include\",\n        \"exclude\"\n      ],\n      \"default\": \"include\",\n      \"description\": \"Controls only whether this Item's directly referencing Entries appear in Knowledge-side Related Work Context. It is not authorization.\"\n    },\n    \"artifactRefs\": {\n      \"type\": \"array\",\n      \"items\": {\n        \"$ref\": \"#/$defs/artifactSelector\"\n      }\n    },\n    \"entries\": {\n      \"type\": \"array\",\n      \"minItems\": 1,\n      \"maxItems\": 200,\n      \"items\": {\n        \"$ref\": \"#/$defs/entry\"\n      }\n    }\n  },\n  \"$defs\": {\n    \"externalKey\": {\n      \"type\": \"string\",\n      \"pattern\": \"^[a-z0-9][a-z0-9-]*$\",\n      \"maxLength\": 160\n    },\n    \"artifactSelector\": {\n      \"type\": \"object\",\n      \"additionalProperties\": false,\n      \"required\": [\n        \"workspaceAlias\",\n        \"sourceKey\",\n        \"path\",\n        \"view\"\n      ],\n      \"properties\": {\n        \"workspaceAlias\": {\n          \"type\": \"string\",\n          \"minLength\": 1,\n          \"maxLength\": 160\n        },\n        \"sourceKey\": {\n          \"type\": \"string\",\n          \"minLength\": 1,\n          \"maxLength\": 200\n        },\n        \"path\": {\n          \"type\": \"string\",\n          \"minLength\": 1,\n          \"maxLength\": 2000\n        },\n        \"view\": {\n          \"enum\": [\n            \"stable\",\n            \"dynamic\"\n          ]\n        }\n      }\n    },\n    \"entry\": {\n      \"type\": \"object\",\n      \"additionalProperties\": false,\n      \"required\": [\n        \"externalKey\",\n        \"type\",\n        \"text\"\n      ],\n      \"properties\": {\n        \"externalKey\": {\n          \"$ref\": \"#/$defs/externalKey\"\n        },\n        \"type\": {\n          \"enum\": [\n            \"INSIGHT\",\n            \"CLARIFICATION_POINT\",\n            \"DECISION\",\n            \"RESULT\"\n          ]\n        },\n        \"text\": {\n          \"type\": \"string\",\n          \"minLength\": 1,\n          \"maxLength\": 4000\n        },\n        \"artifactRefs\": {\n          \"type\": \"array\",\n          \"items\": {\n            \"$ref\": \"#/$defs/artifactSelector\"\n          }\n        },\n        \"relatesTo\": {\n          \"type\": \"array\",\n          \"maxItems\": 200,\n          \"uniqueItems\": true,\n          \"items\": {\n            \"$ref\": \"#/$defs/externalKey\"\n          }\n        }\n      }\n    }\n  }\n}\n"}]}