@mnstry/atelier 0.2.0-alpha.13 → 0.2.0-alpha.15

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (253) hide show
  1. package/CHANGELOG.md +283 -0
  2. package/README.md +102 -52
  3. package/SECURITY.md +1 -1
  4. package/TRADEMARKS.md +2 -2
  5. package/contracts/atelier-extension-manifest.v1.schema.json +412 -0
  6. package/contracts/atelier-graph-view.v1.schema.json +1085 -0
  7. package/contracts/public-api-baseline.json +298 -19
  8. package/docs/README.md +90 -0
  9. package/docs/blocks/capability-stewardship.md +1 -1
  10. package/docs/blocks/claims.md +2 -2
  11. package/docs/blocks/conformance-admission.md +1 -1
  12. package/docs/blocks/learning-harnesses.md +1 -1
  13. package/docs/{atelier-sync.md → guides/atelier-sync.md} +20 -14
  14. package/docs/{capability-stewardship.md → guides/capability-stewardship.md} +2 -4
  15. package/docs/guides/co-authoring.md +113 -0
  16. package/docs/{distributions.md → guides/distributions.md} +13 -8
  17. package/docs/guides/extensions.md +189 -0
  18. package/docs/guides/graph-refresh.md +152 -0
  19. package/docs/guides/graph-workspace.md +64 -0
  20. package/docs/{ingestion.md → guides/ingestion.md} +16 -15
  21. package/docs/{inquiry-harnesses.md → guides/inquiry-harnesses.md} +2 -3
  22. package/docs/{knowledge-workspace.md → guides/knowledge-workspace.md} +2 -2
  23. package/docs/{learning-harnesses.md → guides/learning-harnesses.md} +2 -3
  24. package/docs/{learning.md → guides/learning.md} +12 -5
  25. package/docs/{obsidian.md → guides/obsidian.md} +370 -23
  26. package/docs/guides/ontology-guide.md +111 -0
  27. package/docs/{personal-workspace.md → guides/personal-workspace.md} +17 -5
  28. package/docs/{research-starter.md → guides/research-starter.md} +1 -1
  29. package/docs/{tenant-readiness.md → guides/tenant-readiness.md} +39 -0
  30. package/docs/{upgrade.md → guides/upgrade.md} +197 -11
  31. package/docs/knowledge-health/assessment/capabilities.md +6 -15
  32. package/docs/knowledge-health/facilitator.md +15 -4
  33. package/docs/knowledge-health/{devday/participant-response.md → participant-response.md} +4 -2
  34. package/docs/knowledge-health/quickstart.md +97 -75
  35. package/docs/knowledge-health/readme.md +13 -5
  36. package/docs/maintainers/describing-the-atelier.md +173 -0
  37. package/docs/{release-engineering.md → maintainers/release-engineering.md} +5 -4
  38. package/docs/{announcements.md → reference/announcements.md} +1 -1
  39. package/docs/{architecture.md → reference/architecture.md} +31 -5
  40. package/docs/{atelier-runtime.md → reference/atelier-runtime.md} +1 -1
  41. package/docs/{connected-composition.md → reference/connected-composition.md} +7 -10
  42. package/docs/{coordination.md → reference/coordination.md} +1 -1
  43. package/docs/{decisions.md → reference/decisions.md} +3 -3
  44. package/docs/{design.md → reference/design.md} +1 -1
  45. package/docs/reference/edge-policy.md +151 -0
  46. package/docs/reference/graph-view-structured.md +119 -0
  47. package/docs/reference/graph-view.md +139 -0
  48. package/docs/reference/graph-workspace.md +37 -0
  49. package/docs/{intake-and-guides.md → reference/intake-and-guides.md} +3 -4
  50. package/docs/{knowledge-graph.md → reference/knowledge-graph.md} +120 -6
  51. package/docs/{local-services.md → reference/local-services.md} +43 -4
  52. package/docs/{obsidian-contract.md → reference/obsidian-contract.md} +29 -4
  53. package/docs/{obsidian-plugin.md → reference/obsidian-plugin.md} +218 -68
  54. package/docs/{practical-judgment.md → reference/phronesis.md} +12 -3
  55. package/docs/reference/portability.md +92 -0
  56. package/docs/{portable-presentation.md → reference/portable-presentation.md} +2 -2
  57. package/docs/{presentation-consumer-boundaries.md → reference/presentation-consumer-boundaries.md} +5 -0
  58. package/docs/{project-options.md → reference/project-options.md} +17 -0
  59. package/docs/{repo-boundary-guard.md → reference/repo-boundary-guard.md} +50 -4
  60. package/docs/{review-portability.md → reference/review-portability.md} +4 -0
  61. package/docs/{semantic-operation.md → reference/semantic-operation.md} +4 -3
  62. package/docs/{template-profile.md → reference/template-profile.md} +1 -1
  63. package/docs/{trackables.md → reference/trackables.md} +2 -2
  64. package/docs/start/independent-start.md +89 -0
  65. package/docs/{install.md → start/install.md} +9 -9
  66. package/docs/{knowledge-setup.md → start/knowledge-setup.md} +5 -5
  67. package/docs/{research-starter-quickstart.md → start/research-starter-quickstart.md} +6 -6
  68. package/fixtures/atelier-architecture/catalog/invalid/document.json +2 -2
  69. package/fixtures/atelier-architecture/catalog/valid/document.json +2 -2
  70. package/fixtures/graph-view/synthetic-authorized-input.v1.json +437 -0
  71. package/fixtures/graph-view/synthetic-view.v1.json +1 -0
  72. package/fixtures/knowledge-health/workshop/README.md +1 -1
  73. package/fixtures/templates/local-library.v1.json +3 -1
  74. package/package.json +22 -8
  75. package/plugins/obsidian/main.js +57 -8
  76. package/plugins/obsidian/manifest.json +1 -1
  77. package/skills/claude/atelier-guided-upgrade/SKILL.md +1 -1
  78. package/skills/claude/atelier-knowledge-setup/SKILL.md +2 -2
  79. package/skills/claude/atelier-local-service/SKILL.md +1 -1
  80. package/skills/claude/atelier-practical-judgment/SKILL.md +7 -2
  81. package/skills/claude/atelier-skill-steward/SKILL.md +1 -1
  82. package/skills/claude/mnstry-readiness/SKILL.md +2 -2
  83. package/skills/codex/atelier-guided-upgrade/SKILL.md +1 -1
  84. package/skills/codex/atelier-knowledge-setup/SKILL.md +2 -2
  85. package/skills/codex/atelier-local-service/SKILL.md +1 -1
  86. package/skills/codex/atelier-practical-judgment/SKILL.md +7 -2
  87. package/skills/codex/atelier-skill-steward/SKILL.md +1 -1
  88. package/skills/codex/mnstry-readiness/SKILL.md +2 -2
  89. package/src/architecture/catalog.mjs +2 -2
  90. package/src/attestation/sign.mjs +1 -1
  91. package/src/boundary/content-rules.mjs +534 -68
  92. package/src/boundary/policy.mjs +187 -60
  93. package/src/cli/run.mjs +26 -9
  94. package/src/commands/distribution.mjs +1 -1
  95. package/src/commands/extension.mjs +27 -0
  96. package/src/commands/ingest.mjs +1 -1
  97. package/src/commands/learn.mjs +1 -1
  98. package/src/commands/obsidian.mjs +49 -21
  99. package/src/commands/review.mjs +3 -0
  100. package/src/edge-policy/contract.mjs +69 -0
  101. package/src/edge-policy/policy.mjs +142 -0
  102. package/src/edge-policy/source-citation-adapter.mjs +43 -0
  103. package/src/extension-packs/loader.mjs +4 -3
  104. package/src/extensions/admission.mjs +83 -0
  105. package/src/extensions/client.d.mts +23 -0
  106. package/src/extensions/client.mjs +99 -0
  107. package/src/extensions/contracts.d.mts +29 -0
  108. package/src/extensions/contracts.mjs +163 -0
  109. package/src/extensions/convex.d.mts +24 -0
  110. package/src/extensions/convex.mjs +189 -0
  111. package/src/extensions/delegation.mjs +54 -0
  112. package/src/extensions/drizzle.d.mts +11 -0
  113. package/src/extensions/drizzle.mjs +33 -0
  114. package/src/extensions/postgres.d.mts +7 -0
  115. package/src/extensions/postgres.mjs +66 -0
  116. package/src/extensions/prisma.d.mts +13 -0
  117. package/src/extensions/prisma.mjs +63 -0
  118. package/src/extensions/project.mjs +432 -0
  119. package/src/extensions/scaffold-convex.mjs +130 -0
  120. package/src/extensions/scaffold-sql.mjs +144 -0
  121. package/src/extensions/server.d.mts +20 -0
  122. package/src/extensions/server.mjs +102 -0
  123. package/src/extensions/sql-scope.mjs +22 -0
  124. package/src/graph/graph.mjs +13 -5
  125. package/src/graph/knowledge-graph.mjs +20 -2
  126. package/src/graph/repo-contribution.mjs +405 -0
  127. package/src/graph/repo-contribution.types.mjs +32 -0
  128. package/src/graph-access/edge-decision-adapter.mjs +41 -0
  129. package/src/graph-access/edge-record-adapter.mjs +73 -0
  130. package/src/graph-access/index.mjs +253 -0
  131. package/src/graph-access/multi-contribution-record-adapter.mjs +101 -0
  132. package/src/graph-access/multi-record-projection-adapter.mjs +74 -0
  133. package/src/graph-access/source-adapter.mjs +81 -0
  134. package/src/graph-refresh/compare.mjs +110 -0
  135. package/src/graph-refresh/controller.mjs +324 -0
  136. package/src/graph-refresh/index.mjs +3 -0
  137. package/src/graph-refresh/local.mjs +78 -0
  138. package/src/graph-view/babylon/babylon-scene-port.mjs +64 -0
  139. package/src/graph-view/babylon/index.mjs +2 -0
  140. package/src/graph-view/babylon/navigator.mjs +312 -0
  141. package/src/graph-view/babylon/provenance.mjs +36 -0
  142. package/src/graph-view/babylon/scene-controller.mjs +131 -0
  143. package/src/graph-view/babylon/semantic-picking.mjs +35 -0
  144. package/src/graph-view/babylon/web-host.mjs +188 -0
  145. package/src/graph-view/cli.mjs +3 -0
  146. package/src/graph-view/command.mjs +34 -0
  147. package/src/graph-view/contracts.mjs +79 -0
  148. package/src/graph-view/errors.mjs +5 -0
  149. package/src/graph-view/index.mjs +4 -0
  150. package/src/graph-view/intents.mjs +30 -0
  151. package/src/graph-view/query.mjs +213 -0
  152. package/src/graph-view/refs.mjs +2 -0
  153. package/src/graph-view/structured/browser.mjs +262 -0
  154. package/src/graph-view/structured/styles.mjs +8 -0
  155. package/src/graph-workspace/authoring.mjs +185 -0
  156. package/src/graph-workspace/browser/constellation.mjs +369 -0
  157. package/src/graph-workspace/browser/dom.mjs +23 -0
  158. package/src/graph-workspace/browser/index.mjs +6 -0
  159. package/src/graph-workspace/browser/review.mjs +55 -0
  160. package/src/graph-workspace/browser/styles.mjs +11 -0
  161. package/src/graph-workspace/browser/workbench.mjs +351 -0
  162. package/src/graph-workspace/browser/workspace.mjs +431 -0
  163. package/src/graph-workspace/disclosure.mjs +39 -0
  164. package/src/graph-workspace/geometry.mjs +78 -0
  165. package/src/graph-workspace/index.mjs +11 -0
  166. package/src/graph-workspace/labels.mjs +50 -0
  167. package/src/graph-workspace/model.mjs +109 -0
  168. package/src/graph-workspace/recipes.mjs +88 -0
  169. package/src/graph-workspace/scale.mjs +95 -0
  170. package/src/graph-workspace/theme.mjs +156 -0
  171. package/src/ingestion/optional/graphify/graphify_supplier.py +5 -0
  172. package/src/ingestion/optional/graphify/native-closure-pins.json +275 -0
  173. package/src/ingestion/optional/graphify/native-pins.json +306 -0
  174. package/src/knowledge/ontology-guide.mjs +152 -0
  175. package/src/knowledge-health/proof/installed-check.mjs +2 -2
  176. package/src/knowledge-health/rule-identity.mjs +14 -9
  177. package/src/knowledge-health/workshop.mjs +22 -2
  178. package/src/personal-workspace/index.mjs +1 -1
  179. package/src/personal-workspace/selection.mjs +34 -3
  180. package/src/project/config.mjs +1 -1
  181. package/src/project/path-match.mjs +2 -1
  182. package/src/project/providers/github.mjs +24 -0
  183. package/src/project/repo-identity.mjs +3 -22
  184. package/src/projection/obsidian/contracts.mjs +1 -1
  185. package/src/projection/obsidian/materialize/path-registry.mjs +1 -1
  186. package/src/projection/obsidian/materialize/prepare-view.mjs +88 -6
  187. package/src/projection/obsidian/materialize/redaction.mjs +1 -1
  188. package/src/projection/obsidian/personal-workspace.mjs +84 -5
  189. package/src/projection/obsidian/plugin-bridge/channel.mjs +1 -1
  190. package/src/projection/obsidian/proposals/adapter.mjs +46 -23
  191. package/src/projection/obsidian/proposals/observation.mjs +40 -2
  192. package/src/projection/obsidian/publication/publisher.mjs +96 -8
  193. package/src/projection/project.mjs +21 -16
  194. package/src/readiness/readiness.mjs +20 -11
  195. package/src/readiness-protocols/bundled-pack.mjs +14 -766
  196. package/src/readiness-protocols/bundled-selection.mjs +32 -0
  197. package/src/readiness-protocols/evidence.mjs +2 -1
  198. package/src/readiness-protocols/packs/mnstry.mjs +766 -0
  199. package/src/readiness-protocols/runtime.mjs +43 -6
  200. package/src/runtime/obsidian/engine.mjs +387 -76
  201. package/src/runtime/obsidian/lifecycle.mjs +20 -15
  202. package/src/runtime/obsidian/login-item.mjs +6 -3
  203. package/src/runtime/obsidian/machine-settings.mjs +52 -8
  204. package/src/runtime/obsidian/observation.mjs +36 -4
  205. package/src/runtime/obsidian/opening.mjs +4 -3
  206. package/src/runtime/obsidian/personal-selection.mjs +187 -0
  207. package/src/runtime/obsidian/pipeline.mjs +115 -6
  208. package/src/runtime/obsidian/private-lock.mjs +50 -6
  209. package/src/runtime/obsidian/selection-continuity.mjs +124 -0
  210. package/src/runtime/obsidian/service-main.mjs +68 -16
  211. package/src/runtime/obsidian/service.mjs +80 -6
  212. package/src/runtime/obsidian/unheld-evidence.mjs +1 -1
  213. package/src/runtime/obsidian/view-permission.mjs +335 -0
  214. package/src/ui/control-system.mjs +201 -0
  215. package/src/ui/html-primitives.mjs +3 -0
  216. package/src/upgrade/closure-diagnostics.mjs +135 -0
  217. package/src/upgrade/closure.mjs +649 -0
  218. package/src/upgrade/upgrade.mjs +42 -11
  219. package/templates/distribution-workspace/README.md +2 -2
  220. package/templates/external-project-workspace/atelier.project.json +3 -0
  221. package/templates/external-project-workspace/pack-lifecycle.json +3 -1
  222. package/templates/knowledge-workspace/README.md +2 -2
  223. package/docs/integration-and-review-plan.md +0 -409
  224. package/docs/integration-contract-decisions.md +0 -44
  225. package/docs/knowledge-health/devday/facilitator.md +0 -16
  226. package/docs/knowledge-health/devday/public-default.md +0 -107
  227. package/docs/knowledge-health/devday/quickstart.md +0 -18
  228. package/docs/knowledge-health/devday/support.md +0 -22
  229. package/docs/knowledge-health/exercise.md +0 -17
  230. package/docs/knowledge-health/support.md +0 -34
  231. package/docs/presentation-review-disposition.md +0 -47
  232. package/docs/progressive-ingestion-acceptance.md +0 -89
  233. package/docs/progressive-ingestion.md +0 -235
  234. /package/docs/{exact-upgrades.md → guides/exact-upgrades.md} +0 -0
  235. /package/docs/{guided-upgrades.md → guides/guided-upgrades.md} +0 -0
  236. /package/docs/{local-review.md → guides/local-review.md} +0 -0
  237. /package/docs/{skill-steward.md → guides/skill-steward.md} +0 -0
  238. /package/docs/{template-upgrades.md → guides/template-upgrades.md} +0 -0
  239. /package/docs/{assurance-controls.md → maintainers/assurance-controls.md} +0 -0
  240. /package/docs/{attestation.md → reference/attestation.md} +0 -0
  241. /package/docs/{coauthor-session.md → reference/coauthor-session.md} +0 -0
  242. /package/docs/{continuity.md → reference/continuity.md} +0 -0
  243. /package/docs/{contract-stability.md → reference/contract-stability.md} +0 -0
  244. /package/docs/{decision-practices.md → reference/decision-practices.md} +0 -0
  245. /package/docs/{evidence-navigation.md → reference/evidence-navigation.md} +0 -0
  246. /package/docs/{extension-pack-lifecycle.md → reference/extension-pack-lifecycle.md} +0 -0
  247. /package/docs/{interaction-and-reflection.md → reference/interaction-and-reflection.md} +0 -0
  248. /package/docs/{local-state.md → reference/local-state.md} +0 -0
  249. /package/docs/{ontology.md → reference/ontology.md} +0 -0
  250. /package/docs/{optional-ingestion.md → reference/optional-ingestion.md} +0 -0
  251. /package/docs/{project-command-inventory.md → reference/project-command-inventory.md} +0 -0
  252. /package/docs/{semantic-ingestion.md → reference/semantic-ingestion.md} +0 -0
  253. /package/docs/{vault-service.md → reference/vault-service.md} +0 -0
@@ -0,0 +1,151 @@
1
+ # Experimental edge policy adapter
2
+
3
+ This additive module computes eligibility over repository-owned source records
4
+ and signed decisions. It is not a new ontology canonical, key registry, identity
5
+ provider, access host or source writer. No CLI, browser endpoint, root export or
6
+ existing graph/proposal behavior changes. Import the modules within an admitted
7
+ source integration; this experimental seam is not a published package subpath.
8
+
9
+ ## Authority reused
10
+
11
+ Repository sources and the existing graph vocabulary own declarations and
12
+ identity. Federation supplies `{repoId,localId}`; local titles, aliases and root
13
+ commits do not establish repository identity. The adapter reuses the existing
14
+ `attestation/jcs.mjs` RFC8785 canonicalization and `attestation/sign.mjs` detached
15
+ signature verification. Existing collaboration proposals remain copy-only.
16
+ Local review artifacts and boundary actor delegations remain attribution-grade;
17
+ they cannot stand in for authenticated steward approval.
18
+
19
+ Koiné contribution acceptance is unchanged. Withdrawing an edge's eligibility
20
+ does not withdraw or mutate an accepted Koiné proposal. Hosts retain their
21
+ existing proposal, receipt, withdrawal and source-owner incorporation paths.
22
+ This public adapter has no dependency on Koiné, a private bridge or MNSTRY.
23
+
24
+ ## Record and decision contract
25
+
26
+ `contract.mjs` validates closed experimental shapes. `edgeIdentity(record)` is
27
+ the full RFC8785 SHA-256 of the immutable record, prefixed `edge:`. These are
28
+ projection identities, never replacements for source node or repository IDs.
29
+
30
+ An edge record has:
31
+
32
+ - `schema: 'atelier-edge-record@experimental-v1'`, `family`, `subject`,
33
+ `predicate`, `object`, and `qualifications[]`;
34
+ - `home: {repoId,path,readership}`, `origin`, and `supports: [{id,source}]`;
35
+ - `policyDigest`, `proposalRef` and `sourceChange` (nullable only where review
36
+ is unnecessary). `sourceChange` preserves `{repoId,path,baseRevision,
37
+ diffDigest,reviewRef}` for the source owner's normal diff/PR path.
38
+
39
+ Each source reference contains `{repoId,path,revision,fileDigest,
40
+ locator:{byteStart,byteEnd},citedDigest}`. Byte offsets are zero-based with an
41
+ exclusive end. File and cited-span digests cover the exact raw bytes, without
42
+ normalization. A revision is the producer's exact snapshot revision, including
43
+ dirty-tree scope when applicable. Adapters must preserve the federation's raw
44
+ file digest separately from its normalized text digest. A pointer-only location
45
+ must be resolved to an exact raw-byte range before admission; do not guess a
46
+ range from reserialized front matter or JSON. Unknown, changed or absent sources
47
+ stay pending/stale. The origin occurrence is always retained along with every
48
+ support occurrence, even when two occur in the same file.
49
+
50
+ Families remain separate:
51
+
52
+ | Family | Meaning while eligible | Required review |
53
+ | --- | --- | --- |
54
+ | `hyperlink` | Navigation with predicate `links-to` | No semantic approval is claimed. Exact extracted origin and safe home remain required. |
55
+ | `source-declaration` | Native source relation | Same-repository declarations need no invented review. Every cross-repository declaration needs governed review. |
56
+ | `reviewed-assertion` | Policy-reviewed semantic assertion | Home-owner and applicable endpoint-steward review, followed by home-owner acceptance. |
57
+
58
+ The default policy rejects proposer self-review and a common steward for two
59
+ repository endpoints unless explicitly delegated by the trusted policy. Policy
60
+ is `{version,allowProposerReview,allowSharedSteward}`; its full digest is pinned.
61
+ Policy values come from the host, never the record. The version is a receiving
62
+ host's existing policy reference, not an admitted shared policy canonical.
63
+
64
+ Decisions use `atelier-edge-decision@experimental-v1` with `recordDigest`,
65
+ `sequence`, `previousDigest`, `action`, `actorId`, `at`, `policyDigest`, `reason`,
66
+ `roles[]` and the existing detached `signature` shape. Sign with the existing
67
+ `signDocument` procedure; private keys stay in the host's existing custody.
68
+ Approval roles are `{repoId,role:'home-owner'|'endpoint-steward'}`. The host
69
+ binds each role to its current actor. One verified actor may approve several
70
+ explicitly delegated roles, but a signature alone never creates that delegation.
71
+ This adapter's roles are repository-scoped. Conflicting endpoint steward IDs
72
+ inside one repository refuse instead of dropping one required review. A host
73
+ with finer resource stewardship needs an explicitly admitted mapping before use.
74
+
75
+ The chain begins with `propose`, followed by required `approve` decisions and
76
+ `accept`. The adapter derives `draft`, `awaiting-endpoint-review`, `active`,
77
+ `rejected`, `suspended`, `withdrawn` and `superseded` states. Changed citations
78
+ derive `stale`. Rejection, suspension, withdrawal and supersession are terminal
79
+ for that immutable chain. Revalidation/correction requires a new record and
80
+ ordinary source review; no accepted record, evidence pin or event is overwritten.
81
+ Retain all original records and chains in their safe source home. This module
82
+ does not persist, compact or modify them.
83
+
84
+ ## Trusted host ports
85
+
86
+ Call `await evaluateEdge({record,events}, host)` only after the access composer
87
+ has current recipient grants for the home, both endpoints and every source.
88
+ Evaluation is eligibility, not an ACL verdict. The host must maintain one
89
+ coherent current snapshot throughout the call. It supplies:
90
+
91
+ | Port / value | Required behavior and result |
92
+ | --- | --- |
93
+ | `policy`, `now`, `bindingId` | Current trusted policy, trusted ISO time and the access lane's current principal/grant/source snapshot binding. Never a browser assertion. |
94
+ | `readRecordHead({edgeId,recordDigest})` | Read the actual source home and complete current log head; return `{recordDigest,eventCount,eventDigest}`. Last-event digest is null only for an empty log. A caller's truncated history cannot replace the stored head. |
95
+ | `verifyOrigin({record,edgeId,recordDigest,policyDigest})` | Verify the exact extracted origin family, triple and occurrence against the source contribution, or the exact reviewed assertion source record; return `{recordDigest,bindingId,matches:true}` only on a match. Hashes alone do not prove that a link or relation actually declares this triple. |
96
+ | `checkSourceHome({record,edgeId,recordDigest,policyDigest})` | Check the home's entire intended readership can know every endpoint and provenance field, including evidence, qualifications, proposal/PR references and actor identities. Return `{recordDigest,policyDigest,bindingId,allowed:true}` only when safe. A current reader's larger access does not make a broad shared home safe. |
97
+ | `resolveEndpoint(ref)` | Exact current source identity, not an alias or external prefix; return `{ref,current:true,stewardId}`. Deleted/migrated identities refuse until explicitly revalidated. |
98
+ | `resolveHomeOwner(repoId)` | Current source-home ownership: `{actorId}`. |
99
+ | `readSource(source)` | Read that exact current authorized raw file, returning `{revision,bytes:Uint8Array}`. Recheck exact revision, file digest, byte bounds and cited bytes. Never silently replace pins. |
100
+ | `resolveActorKey({actorId,keyId,at})` | Use the existing trusted host registry to bind the exact actor/key and current revocation state: `{actorId,publicKey,revoked:false,notBefore,expiresAt}`. `publicKey` is the existing `verifyDocument` public-key document. The key must cover the decision time and remain valid now. Never accept a caller-supplied key registry. |
101
+ | `authorizeDecision({event,record,required,policyDigest})` | Verify current action/role scope, principal/key rights and revocation. Return `{eventDigest,policyDigest,bindingId,allowed:true,revoked:false,notBefore,expiresAt}` bound to that exact signed event and policy. Historical or expired rights cannot sustain an active edge. |
102
+
103
+ Missing ports, exceptions and malformed results fail closed. Key/reviewer/grant
104
+ changes, stale policy, missing endpoints, unsafe homes and invalid chains never
105
+ remain eligible. Port implementations are host-specific acceptance obligations;
106
+ synthetic test hosts do not qualify an actual Git provider or shared service.
107
+
108
+ ## Composer and projection seam
109
+
110
+ The immutable evaluation result contains `edgeId`, `recordDigest`, `policyDigest`,
111
+ `state`, `eligible`, `family`, `triple`, `supportRefs`, `reviewRefs`,
112
+ `qualifications`, source-owner handoff and full signed `history`. Failed
113
+ verification can return only a generic suspended result. This is an **owner
114
+ audit** object, not a response for an arbitrary reader.
115
+
116
+ `displayEligibleEdge(result)` accepts only an original in-process evaluated
117
+ eligible result. Deserialized or fabricated `eligible:true` objects are refused.
118
+ It returns `{edgeId,source,target,predicate,family,acceptanceState,assurance,
119
+ supportRefs,sourceRef,reviewRefs,qualifications,recordDigest,policyDigest,
120
+ verification:{checkedAt,bindingId}}`, with evidence and review references only.
121
+ `sourceRef` is the origin's evidence ID. Each evidence occurrence has a
122
+ content-bound ID namespaced to its assertion and original occurrence ID;
123
+ evaluation `supportRefs` retain the actual exact source refs for the authorized
124
+ evidence adapter. No raw decision body, source path, diff or private key reaches
125
+ the display shape. Evidence rows must undergo the access lane's own disclosure
126
+ filter before serialization.
127
+
128
+ The access host evaluates again for each new delivery and validates the binding
129
+ at use time. Do not persist eligibility decisions as reusable authority or serve
130
+ a cached result after a grant/source change. In-process provenance is a guard
131
+ against accidental data promotion, not a security sandbox against malicious
132
+ code executing inside the trusted host.
133
+
134
+ `groupEligibleEdges(results)` is an optional view grouping helper. It retains
135
+ every distinct assertion with all support occurrences and signed history,
136
+ orders deterministically, refuses conflicting results and never merges families
137
+ or qualifications. It only accepts evaluated results already authorized for one
138
+ reader in one host snapshot. Group output is also owner/audit data; renderers
139
+ consume bounded display edges, retaining distinct edge IDs for the same triple.
140
+ The helper explicitly refuses mixed binding IDs or policy digests.
141
+
142
+ ## Verification and integration limits
143
+
144
+ Run `node --test test/edge-policy.test.mjs`. Fixtures generate ephemeral signing
145
+ keys at runtime and use synthetic repositories, observations and actors. They
146
+ verify the control's refusal behavior without touching a live provider.
147
+
148
+ The graph builder, collaboration stores, Koiné operations, public package
149
+ exports, current host bindings, shared-view access service and source-owner Git
150
+ application are separate receiving work. Neither a local test pass nor a signed
151
+ decision proves deployment, human acceptance or source incorporation.
@@ -0,0 +1,119 @@
1
+ # Structured graph explorer
2
+
3
+ The structured explorer is a browser DOM consumer of `atelier.graph-view@v1`.
4
+ It provides record search, keyboard navigation, a directed relationship table,
5
+ questions, diagnostics and a shared evidence inspector without WebGL. It emits
6
+ presentation intents; it does not read repositories, accept assertions, perform
7
+ access checks, or create source records.
8
+
9
+ ## Host integration
10
+
11
+ The source entry is `src/graph-view/structured/browser.mjs`:
12
+
13
+ ```js
14
+ const explorer = mountStructuredGraphView(element, {
15
+ view: authorizedView,
16
+ selection: { projectionDigest: authorizedView.projectionDigest, ref },
17
+ onIntent: handleIntent,
18
+ })
19
+ explorer.update({ view: nextAuthorizedView, selection: nextSelection })
20
+ explorer.clear()
21
+ explorer.destroy()
22
+ ```
23
+
24
+ This source seam is awaiting a package export and a consuming browser host.
25
+ A source import or local test does not establish published package availability.
26
+ The host validates the complete versioned envelope and digest before delivery.
27
+ The component checks its required presentation shape, copies received values,
28
+ and presents source text as inert DOM text. It is not a browser authorization
29
+ control. Never deliver a combined graph and ask this component to hide denied
30
+ records. The access and projection owners must remove denied topology before
31
+ any bytes, counts, diagnostics, source references or cursors reach the browser.
32
+
33
+ `onIntent` receives the producer's digest-bound intents: `select` with exactly
34
+ one qualified `ref` or `edgeId`; `openEvidence` with an `evidenceId`;
35
+ `setQuestion` with a `questionId`; and `expand` with a qualified `ref` and
36
+ `direction` of `in`, `out` or `both`. Qualified refs use `{repoId, localId}`.
37
+ The component uses the producer's browser-safe intent validator. The host revalidates current grants and source before handling an intent.
38
+ Selection is controlled by `update`; a request never optimistically accepts an
39
+ assertion or changes source. Focus and selection are separate. Keyboard arrows,
40
+ Home and End move list focus; Enter or Space requests selection.
41
+
42
+ Host selection is `{projectionDigest, ref|edgeId|evidenceId|questionId}` with
43
+ exactly one target available in the delivered slice. Stale or unavailable
44
+ selection is cleared without rendering its identity or a placeholder.
45
+ Host updates preserve focus where the corresponding control remains available.
46
+ If it disappears, focus moves to the inspector. Search applies only to the
47
+ records already delivered, and it is labelled accordingly.
48
+
49
+ On grant loss or withdrawal, call `clear()` immediately and discard host caches.
50
+ The component clears source pins, controls, search text and selection. A late
51
+ intent callback cannot update the component's status after withdrawal. The host
52
+ must also cancel or reject stale query results and must not call `update` with
53
+ previously withdrawn bytes. `destroy()` removes the entire mounted DOM and
54
+ releases the mount reservation; no global listener or transport was installed.
55
+
56
+ ## Provenance and honest states
57
+
58
+ Each relationship retains its producer `edgeId`, direction, predicate, family,
59
+ assurance and acceptance state. Equal endpoint/predicate triples remain separate
60
+ rows. Origin and support IDs resolve into authorized evidence records, including
61
+ repository, path, exact source revision, content digest and structured locator.
62
+ Review receipt digests, policy/record digests, qualifications and check time
63
+ are displayed as supplied. An active source-declared edge is not labelled a
64
+ reviewed assertion. No source passage is invented when a view supplies only pins.
65
+
66
+ The initial producer fixture provides no edge currency field. The inspector
67
+ therefore says that staleness is not supplied and must not be assumed current.
68
+ It displays each support record's independent verification state. A host can also pass `refreshStatus` from the existing refresh controller's read result. A stale source view and rebuild failure receive explicit labels, including in the edge inspector; arbitrary failure details are never echoed. Selection updates for the same projection preserve that status, and a new projection or withdrawal clears it. A verification
69
+ check time is not a currentness guarantee. Explicit edge currency remains a
70
+ producer dependency.
71
+
72
+ Questions retain coverage, gaps, omissions and supporting/contradicting evidence.
73
+ An abstention states that the sources do not establish an answer. Authorized
74
+ diagnostics remain visible with record and evidence controls. A bounded view
75
+ states its truncation and omitted counts; search and counts never imply whole-corpus completeness. A host may supply onPage({projectionDigest, cursor}) to receive the visible Load next page control. Without a cursor, the view explains that a broader host query is needed.
76
+
77
+ ## Acceptance and limits
78
+
79
+ Run the opt-in network-blocked proof using the repository's locked Playwright
80
+ runtime and an installed Chromium. It does not download browsers or start a
81
+ service:
82
+
83
+ ```sh
84
+ ATELIER_STRUCTURED_BROWSER_PROOF=1 node --test test/graph-view-structured-browser.test.mjs
85
+ ```
86
+
87
+ The default shared fixture is `fixtures/graph-view/synthetic-view.v1.json`, owned
88
+ by the projection lane. `ATELIER_GRAPH_VIEW_FIXTURE` may select its exact received
89
+ file before the producer dependency lands. The test independently verifies the
90
+ fixture digest and records the file hash. `ATELIER_STRUCTURED_PROOF_OUTPUT`
91
+ selects the output directory; the default is `output/playwright/graph-structured`.
92
+
93
+ The proof exercises question/source/relationship/contradiction tasks, abstention,
94
+ qualified identity, repeated-edge provenance, keyboard selection and independent
95
+ focus, native accessibility-tree semantics, touch without dragging, 44px targets,
96
+ forced colors, reduced motion, 320px reflow, 200% CSS layout zoom, WebGL disabled,
97
+ withdrawal, failed/late delivery and disposal. CSS layout zoom supplements the
98
+ manual browser zoom test; it is not a claim of operating-system magnification.
99
+ Automated accessibility-tree inspection is not a human screen-reader result.
100
+
101
+ Before human acceptance, use the same reserved unseen task in the Babylon host
102
+ and structured explorer: locate a question, inspect a source, traverse a directed
103
+ relationship, recognize a contradiction or missing support, and explain the next
104
+ decision or abstention. Retain exact source/projection/browser identities. Run
105
+ keyboard only, a named screen reader, actual browser zoom at 200%, high contrast,
106
+ reduced motion, touch without dragging and WebGL disabled. Record correctness,
107
+ source trace, wrong turns and time separately. Keep A-only and A+B host views
108
+ separate; the A-only participant must receive no clue that B exists. A local
109
+ synthetic consumer test does not qualify that access boundary or pass an unseen
110
+ human task. The cohort validation owner retains that acceptance work.
111
+
112
+ ## Reused authority
113
+
114
+ Source records and predicates remain governed by `src/graph/knowledge-graph.mjs`.
115
+ Questions and expected evidence remain knowledge-plan projections. Graph-view
116
+ owns the qualified identity, envelope and intent contract; the host owns access
117
+ and delivery. Existing presentation semantics distinguish focused and selected
118
+ state. This component adds a presentation seam, not an ontology canonical or a
119
+ second authoring desk. Babylon scene and lifecycle remain with its owning lane.
@@ -0,0 +1,139 @@
1
+ # Renderer-neutral graph view
2
+
3
+ `atelier.graph-view@v1` is an additive, bounded JSON projection for independent
4
+ renderers. The source graph, repository identities, knowledge plan, edge policy
5
+ and consuming host retain their respective authority. The existing `atelier graph`
6
+ artifact and knowledge outputs remain unchanged. This module does not extract
7
+ sources, verify grants, admit assertions or fetch source bodies.
8
+
9
+ The implementation lives in `src/graph-view/index.mjs`; package export and shared
10
+ CLI dispatch adoption require the owning program's separate integration. No
11
+ published release or hosted permission implementation is established by this source.
12
+ The schema is `contracts/atelier-graph-view.v1.schema.json`. Optional epoch
13
+ `contractVersion` and empty `ext` containers follow existing schema conventions;
14
+ nonempty request/output extensions are unsupported at this boundary. The two fixtures under
15
+ `fixtures/graph-view/` are invented data, not access grants or provider receipts.
16
+
17
+ ## Host binding
18
+
19
+ The host creates a reader with closures over its actual authenticated context:
20
+
21
+ ```js
22
+ const reader = createGraphViewReader({
23
+ loadAuthorizedGraph: options => access.loadAuthorizedGraph(trustedContext, options),
24
+ revalidate: binding => access.revalidate(binding),
25
+ })
26
+ const view = await reader.readGraphView({ focusRef, direction: 'out', depth: 1, limit: 50 })
27
+ const bytes = await reader.exportGraphView({ snapshot: view.snapshot, limit: 50 })
28
+ ```
29
+
30
+ The loader returns `{graph,binding}`. Only the already-authorized graph enters the
31
+ query. The binding stays private and is revalidated after preparation, immediately
32
+ before return, including when query preparation fails. Expired or revoked bindings
33
+ refuse delivery. Host failures produce fixed errors without raw exception details.
34
+ No cache exists here. A receiving host still owns current access checks, output
35
+ transport, separately authorized evidence reads, and clearing previous views after
36
+ access changes. Parsing an existing file does not authorize reading or sharing it.
37
+
38
+ Browser requests cannot supply `readerScope`, identity, grant data, a graph payload
39
+ or a host binding. Unknown request fields refuse. The trusted access adapter is
40
+ responsible for excluding denied repositories, nodes, edge homes, endpoints,
41
+ evidence, text, diagnostics and suggestions before the serializer is called.
42
+ Closed serialization removes body fields, raw relations, arbitrary extensions,
43
+ principal identity and private edge binding IDs. It cannot detect confidential
44
+ information embedded inside metadata that an upstream host incorrectly admits.
45
+
46
+ ## Projection and provenance
47
+
48
+ Qualified references are `{repoId,localId}` from the source owner. Two repositories
49
+ with the same local identifier remain distinct. A source pointer is
50
+ `{repoId,path,revision,digest,locator?}`. `revision` is the exact repository snapshot
51
+ digest, including dirty bytes; `digest` is the file's raw-byte digest. Both are
52
+ `sha256:` followed by 64 lowercase hex digits. A locator retains the source owner's
53
+ `pointer`, half-open `range`, and/or `targetRange`; ranges preserve text offsets and
54
+ optional raw-byte offsets. Optional `rangeDigest` preserves the source producer's
55
+ digest of the exact raw byte slice in `locator.range`. No passage or full body is included.
56
+
57
+ `sourceSnapshot.repositories` preserves each delivered source snapshot's repo id,
58
+ HEAD, tree, dirty observation, scope and full snapshot digest. Its file list contains
59
+ only source pins needed by this slice; `omittedFiles` reports the other authorized
60
+ files. `inputs.config` and `inputs.plan` are exact verified source pointers or null;
61
+ no global config or plan pin is invented. The full snapshot digest still identifies
62
+ the complete input observation. An approved but unavailable repository has no
63
+ invented snapshot: `completeness` becomes `incomplete`, with one fixed authorized
64
+ unavailable diagnostic. Denied repositories have no placeholders or count effects.
65
+
66
+ Distinct edges retain `edgeId`, qualified directed endpoints, native predicate,
67
+ family, assurance, active admission state, every support and review reference,
68
+ qualifications, and record/policy digests. Families are `hyperlink`,
69
+ `source-declaration`, and `reviewed-assertion`. An edge's `sourceRef` is its origin
70
+ **evidence ID**, included in `supportRefs`; node/evidence `sourceRef` is the source
71
+ pointer object. Equivalent triples are not merged. Supporting evidence pointers
72
+ must all be present for an emitted edge. This projection does not infer review,
73
+ semantic acceptance or continuing currency. Optional `verification.checkedAt` means
74
+ verified at that time; absence means unavailable. A live currency claim requires
75
+ an actual current host binding.
76
+
77
+ Questions preserve decision, node/evidence refs, contradicting evidence refs,
78
+ coverage (`supported`, `partial`, `abstain`, `unknown`), omission state and modeling
79
+ gaps. Bounded node omissions are labelled on the question. An explicit abstention
80
+ can have no sources. The current access adapter supplies no question records;
81
+ an authorized knowledge-output binding is a separate receiving dependency.
82
+
83
+ ## Requests, bounds and determinism
84
+
85
+ `readGraphView` and `exportGraphView` accept only `snapshot`, `questionId`,
86
+ `focusRef`, `relationFilter`, `direction` (`in`, `out`, `both`), `depth`, `limit`,
87
+ `cursor` and metadata `search`. Search covers title, summary and tags. Focused
88
+ queries traverse admitted directed edges, with optional native predicate filters.
89
+ Questions select their declared source refs. Incoming focus expansion supplies
90
+ source-impact navigation; edge supports supply the pointer path to evidence.
91
+
92
+ Depth is at most two. A page contains at most 500 nodes (default 100), 2,000 edges,
93
+ 4,000 evidence pointers, 100 questions and 500 diagnostics, and canonical output
94
+ is at most 2 MiB. Hosts may lower node/depth limits. An individual record exceeding
95
+ the closed schema or an unrepresentable evidence closure refuses rather than
96
+ silently trimming provenance. File paths are portable relative paths. Queries
97
+ consume at most 20,000 input records in each table; the host owns source loading
98
+ budgets. Camera state, temporary clusters and visual coordinates are not graph data.
99
+
100
+ Ordering uses stable qualified refs and identifiers. Set-valued metadata is sorted.
101
+ The existing RFC 8785 serializer supplies canonical JSON. `projectionDigest` hashes
102
+ the entire payload with only that field excluded; exported bytes add one newline.
103
+ `snapshot` hashes the complete normalized authorized input, including access context,
104
+ source pins and producer version. Same inputs/request produce identical bytes.
105
+ Source or grant changes invalidate requested snapshots and cursors. Cursors are
106
+ opaque pagination recipes bound to that snapshot and query; they grant no authority.
107
+
108
+ `page.returned` counts emitted records. `page.omitted.nodes/edges` counts records
109
+ from the authorized matching query absent from this page; other omitted counters
110
+ refer to the authorized input universe. Counts include records on other pages and
111
+ never denied records. `nextCursor` pages nodes; cross-page edges are intentionally
112
+ omitted because both endpoints must be in the emitted slice. Use focused expansion
113
+ to inspect a particular relationship. `truncated` means any authorized records were
114
+ omitted; an exhausted node cursor alone does not imply all related data was emitted.
115
+
116
+ ## Consumer intents and command adapter
117
+
118
+ The browser-safe `src/graph-view/intents.mjs` exports `assertGraphViewIntent`.
119
+ Every intent binds `projectionDigest`. `select` carries exactly one `ref` or
120
+ `edgeId`; `expand` carries `ref` and `direction`; `openEvidence` carries `evidenceId`;
121
+ `setQuestion` carries `questionId`. `compareSnapshots` carries two snapshot digests;
122
+ `proposeModelChange` carries a draft ref and requires the host-advertised capability.
123
+ Validation returns data only; it performs no action and confers no write rights.
124
+ Focus and selection remain consumer state. A stale-sensitive host operation must
125
+ revalidate current source/access even when an intent passed structural validation.
126
+
127
+ `runGraphViewCommand(argv,{reader,...io})` is a host-injected CLI adapter. `--request`
128
+ reads a closed query and `--out` writes an authorized export to a new file with
129
+ exclusive creation and private permissions; existing files are never overwritten.
130
+ Without a bound reader, export refuses. The local fixture validator runs as:
131
+
132
+ ```sh
133
+ node src/graph-view/cli.mjs --validate fixtures/graph-view/synthetic-view.v1.json
134
+ ```
135
+
136
+ Validation prints only a fixed success label; it cannot write or re-export the file.
137
+ `parseGraphView` verifies schema, digest and reference closure, and
138
+ `serializeGraphView` emits canonical bytes. These functions verify a transport
139
+ contract, not host grants, provenance authenticity, semantic acceptance or live ACLs.
@@ -0,0 +1,37 @@
1
+ # Graph workspace reference
2
+
3
+ Two package subpaths. The first is pure and runs anywhere; the second needs a browser and injected renderer packages.
4
+
5
+ ## `@mnstry/atelier/graph-workspace`
6
+
7
+ | Export | Purpose |
8
+ | --- | --- |
9
+ | `buildWorkspaceModel({ graph, plan?, zoneRule?, summaryLength? })` | Read model `atelier.graph-workspace-model@v1` from an `mnstry.atelier-knowledge-graph@v1` graph and optional knowledge plan. Refuses duplicate ids and other schemas. |
10
+ | `zoneOf(path, rule)`, `validateZoneRule(rule)`, `ROOT_ZONE` | Zones from folders: `{ prefix, depth (1–4), labels, rootLabel }`. Records outside the rule share the zone `ROOT_ZONE` (`'/'`), which no folder can be. |
11
+ | `edgeClass(type)`, `EDGE_CLASSES` | `related` → `link`, `belongs_to` → `containment`, others → `relation`. |
12
+ | `neighbours(model, id)` | Neighbour ids in either direction. |
13
+ | `seedPositions`, `layoutWorkspace(model, { Graph, forceAtlas2, seed?, iterations?, settings? })`, `normalizePositions`, `LAYOUT_WEIGHTS` | Deterministic zone-seeded ForceAtlas2 layout (injected), normalised to a 1,000-unit frame. |
14
+ | `zoneGeometry(model, { cell? })` | Density blobs and a label anchor per zone. |
15
+ | `planConstellation(model, budget?)`, `DEFAULT_BUDGET` | `records` or `zones` mode for the whole view. |
16
+ | `aggregateZones(model)` | `atelier.graph-workspace-zones@v1`: counts by zone and type, directed bundles by edge class, coverage. |
17
+ | `zoneSlice(model, zoneId, { limit })` | Bounded sub-model. `slice` reports `linksTouchingZone` = drawn + `omittedLinksInsideZone` + `linksToOtherZonesCount` + `omittedLinksToOtherZones`, with `linksToOtherZones` per zone. `coverage.byClass` counts the drawn links. Plan concepts keep only kept declaring records, with `omittedDeclarations`. |
18
+ | `rankRecords(model)` | Records by connection count, then title. |
19
+ | `placeLabels({ candidates, measure, width, height, reserved?, budget?, threshold? })` | Collision-free label placement with four slots per label. Pure. |
20
+ | `labelThreshold(ratio, boost?)`, `labelBudget(width, height, ratio, boost?)`, `overlaps` | Defaults for zoom-dependent label density. |
21
+ | `DEFAULT_RECIPES`, `composeRecipes({ atelier?, coach?, owner? })`, `validateRecipe`, `availableRecipes(recipes, model)` | Layered recipes with per-field provenance (`setBy`). Rooms: `constellation`, `workbench`, `review`; lenses (constellation only): `question`, `concept`, `zone`; subjects (workbench only, required there): `record`, `concept`, `relation`; primary actions (`PRIMARY_ACTIONS`): `search`, `open-evidence`, `next-step`, `walk`, `review`, `pick`, of which `primaryActionsFor(recipe)` names those the shell honours in a recipe's room (review: `review`; workbench: `next-step`, or `walk` for a record; zone lens: `pick`, `search`; question or concept lens: `open-evidence`, `pick`, `search`; no lens: `search`). `composeRecipes` throws on any other combination; `availableRecipes` drops recipes the model cannot run (concept, relation or question work without them in the plan, a review without concepts, a zone lens without zones, a record subject without records). |
22
+ | `DEFAULT_THEME`, `composeTheme(base, ...layers)`, `validateTheme`, `contrastRatio` | `atelier.graph-workspace-theme@v1`, night (dark) by default with a paper (light) scheme. Every layer is checked before and after composing. Each CSS custom property has a declared type (colour, font list, length, shadow, duration, easing), so URLs, `image-set()` and other resource loads are refused, as are unknown fields, schemes and tokens. `--canvas` must equal `graph.canvas`; interface text must reach 4.5:1 on the canvas and surfaces, and on `--surface-glass` composited over the canvas and `--surface-2`; labels need 7:1 and zone colours 3:1. |
23
+ | `conceptSteps`, `relationSteps`, `guideConcept`, `guideRelation`, `stepState`, `readiness(plan, store, readableIds)` | Focused authoring steps and structural guidance. `readiness` needs the `Set` of record ids this reader can open; for concepts and relations alike, missing or unreadable evidence and a missing disconfirming case are errors, so `ready-for-human-review` means every step is complete and every citation is readable here. |
24
+ | `createDraftStore({ storage, key, identity, persistence?, delayMs? })`, `memoryStorage()` | Drafts behind a storage port `{ getItem, setItem, removeItem }`, saved in an `atelier.graph-workspace-draft@v1` envelope bound to `identity` (`{ workspace, ...scope }`); a draft saved under another identity is never restored. `persistence` is `tab`, `browser` or `host`. Status: `empty`, `restored`, `saving`, `saved`, `unavailable`. |
25
+ | `fingerprintsFrom({ graph?, plan?, names?, extra? })`, `scanForFingerprints(files, fingerprints)` | Shareable-content gate with masked findings. |
26
+
27
+ ## `@mnstry/atelier/graph-workspace/browser`
28
+
29
+ | Export | Purpose |
30
+ | --- | --- |
31
+ | `mountGraphWorkspace(element, { model, deps, recipes?, theme?, scheme?, profile?, storage?, draftIdentity?, persistence?, draftKey?, initialRecipe?, intro?, webgl? })` | Default shell with the three rooms, command bar, display menu, question, concept and zone lenses, the recipe's primary action, selection card and Text view. Drafts stay in the tab unless `draftIdentity` or `profile.id` names the workspace; a host `storage` port requires one. Returns `{ state, recipes, store, constellation, workbench, select, openWorkbench, openReview, setRecipe, runPrimary, backToConstellation, toggleText, setScheme, readiness, destroy }`. One per document. |
32
+ | `createConstellation({ container, model, palette, deps, font?, reserveSelector?, onSelect?, onHover?, onOpen? })` | The constellation room alone. `deps = { Sigma, Graph, EdgeArrowProgram, FA2Layout? }`. Elements matching `reserveSelector` (default `[data-graph-reserve]`) are kept free of labels. |
33
+ | `createWorkbench(...)`, `renderReview(...)` | The other two rooms, for custom shells. |
34
+ | `applyTheme(theme, scheme, element)` | Validate and apply a theme scheme as custom properties; returns the graph palette. |
35
+ | `GRAPH_WORKSPACE_CSS`, `injectGraphWorkspaceStyles(document)` | Styles scoped under `.atelier-gw`, responsive by container size. |
36
+
37
+ The opt-in browser acceptance test is `ATELIER_GRAPH_WORKSPACE_BROWSER_PROOF=1 node --test test/graph-workspace-browser.test.mjs`. It uses an invented fixture and makes no claim about human usefulness, screen-reader parity or a hosted deployment.
@@ -30,10 +30,9 @@ structure, missing-asset evidence, and format-specific completeness checks.
30
30
  Do not flatten a conversation export merely to satisfy a text-output API.
31
31
  Packet authoring can proceed before corpus ingestion.
32
32
 
33
- The [progressive ingestion proposal](progressive-ingestion.md) describes a
34
- possible coverage, routing and incremental-processing layer over this store.
35
- It is a design proposal; those orchestration capabilities are not supplied by
36
- the current intake API.
33
+ The [local ingestion runner](../guides/ingestion.md) composes this store with selected-file
34
+ planning, bounded deterministic extraction and lexical retrieval. The intake API
35
+ itself supplies no connector census, provider routing or processing orchestration.
37
36
 
38
37
  ## Guides and private implementations
39
38
 
@@ -1,12 +1,17 @@
1
1
  # MNSTRY Atelier Knowledge Graph
2
2
 
3
- The Atelier knowledge graph is a local, Git-backed operating model for project
4
- source material. It is not a taxonomy and it is not runtime retrieval. It is a
5
- durable model of source nodes, evidence, relationships, diagnostics, and
6
- projection readiness.
3
+ The Atelier Knowledge Graph is the shared, local, Git-backed representation of
4
+ project source material: source nodes, evidence, relationships, diagnostics and
5
+ projection readiness. It is not a taxonomy or runtime retrieval.
6
+
7
+ Knowledge Stewardship is the broader responsibility governing knowledge inclusion
8
+ and applicability. [Phronesis — practical judgment](phronesis.md) draws on this
9
+ graph and contributes through the existing Knowledge review and activation
10
+ routes. It creates no separate graph, store or canonical authority. Structural
11
+ graph checks do not establish semantic acceptance, wisdom or a universal score.
7
12
 
8
13
  For setting up useful domain concepts and testing whether the graph helps answer
9
- work questions, follow [knowledge setup](knowledge-setup.md). It builds on this
14
+ work questions, follow [knowledge setup](../start/knowledge-setup.md). It builds on this
10
15
  canonical source graph and keeps domain concepts, source types, semantic
11
16
  acceptance, and runtime authority distinct.
12
17
 
@@ -70,6 +75,115 @@ a schema-checked JSON sidecar is the trust boundary. Richer format adapters
70
75
  that derive metadata from asset contents belong to extension packs
71
76
  (`atelier-extension-pack.v1`), not the kit core.
72
77
 
78
+ ## A worked example
79
+
80
+ The policy below is invented to show the shape. Once a body of work is
81
+ authored, a policy file looks like this:
82
+
83
+ ```
84
+ policy/expenses/approval.md
85
+ ---
86
+ title: Expense approval policy
87
+ summary: Version 3 of who approves an expense claim, with the limits it depends on.
88
+ tags: [policy, expenses]
89
+ kg:
90
+ id: example:policy:expense-approval
91
+ type: document
92
+ status: active
93
+ audience: team
94
+ relations:
95
+ depends_on: [example:limits:expense-approval-v3]
96
+ ---
97
+ ## Rule 4
98
+ A claim up to the team limit needs one approver, the claimant's lead.
99
+ A claim over the team limit also needs the department head.
100
+ A claim over the department limit also needs the finance lead.
101
+ A claim without a receipt is held: neither approved nor refused.
102
+ ```
103
+
104
+ The limits live in their own file. The file itself is data a product reads:
105
+
106
+ ```
107
+ policy/limits/expense-approval-v3.json
108
+ { "version": 3, "limits": { "team": 500, "department": 5000 }, "holdWhenReceiptMissing": true }
109
+ ```
110
+
111
+ A sidecar beside it makes it a governed node, so the relationship between
112
+ rule, limits and test cases is declared rather than remembered:
113
+
114
+ ```
115
+ policy/limits/expense-approval-v3.json.kg.json
116
+ {
117
+ "schema": "mnstry.source-sidecar@v1",
118
+ "asset": "expense-approval-v3.json",
119
+ "title": "Approval limits, version 3",
120
+ "summary": "Amount limits and the missing-receipt hold for the expense approval policy.",
121
+ "tags": ["policy", "limits"],
122
+ "kg": {
123
+ "id": "example:limits:expense-approval-v3",
124
+ "type": "manifest",
125
+ "domain": "example",
126
+ "lifecycle": "active",
127
+ "status": "active",
128
+ "audience": "team",
129
+ "relations": {
130
+ "implements": ["example:policy:expense-approval"]
131
+ }
132
+ }
133
+ }
134
+ ```
135
+
136
+ A sidecar carries `lifecycle` as well as `status` because the sidecar
137
+ contract requires both; Markdown headers carry `status` alone.
138
+
139
+ The test cases are a third source, a table of sample claims with the approvals
140
+ they need, declared as evidence for the limits:
141
+
142
+ ```
143
+ policy/cases/expense-approval-v3.md
144
+ ---
145
+ title: Test cases, expense approval v3
146
+ summary: Sample claims with the approvals each one needs under version 3.
147
+ tags: [policy, cases]
148
+ kg:
149
+ id: example:cases:expense-approval-v3
150
+ type: evidence
151
+ status: active
152
+ audience: team
153
+ relations:
154
+ evidences: [example:limits:expense-approval-v3]
155
+ ---
156
+ | Claim | Receipt | Approvers |
157
+ | --- | --- | --- |
158
+ | 500 | yes | lead |
159
+ | 1800 | yes | lead, department head |
160
+ | 9000 | yes | lead, department head, finance lead |
161
+ | 300 | missing | none yet; held |
162
+ ```
163
+
164
+ From those headers the builder compiles three edges: the policy depends on the
165
+ limits, the limits implement the policy, and the test cases evidence the
166
+ limits. Ask an agent to revise Rule 4 and it follows those edges from the
167
+ policy to the limits it depends on, and from the limits to the test cases that
168
+ evidence them, then revises the affected files and runs the graph check against
169
+ the result. The graph check refuses a header that names a node which does not
170
+ exist, apart from configured external targets; what an export may include
171
+ across audiences is stated in the README's audience-visibility block.
172
+
173
+ To try it: the first line inside each fence above is the file's path relative
174
+ to the workspace's `content/` directory, not part of the file. Copy a
175
+ `fixtures/projects/sample-workspace`, save the lines after each path line as
176
+ that file under `content/` (so the policy lands at
177
+ `content/policy/expenses/approval.md`), then run
178
+ `atelier graph --project ./atelier.project.json` from the copy. With all four
179
+ files present the graph builds with no diagnostics, its edges include the
180
+ three above, and
181
+ `atelier graph --check` passes against the result. Remove the limits `.json`
182
+ and the build is refused: the sidecar has no asset (`sidecar has no matching
183
+ source asset`), and the two headers that name the limits no longer resolve.
184
+ Point the policy's `depends_on` at an id that does not exist and the build is
185
+ refused (`declared depends_on target ... was not found`).
186
+
73
187
  ## Census Rules
74
188
 
75
189
  Graph and projection walks skip git-ignored paths. A committed artifact must
@@ -89,7 +203,7 @@ treated exactly like a Git-ignored one (no node, no sidecar demand, no orphan
89
203
  error, no link or embed target). A sidecar follows its source. The scope is
90
204
  tracked for the same reason ignored paths are skipped: every machine must walk
91
205
  the same files. The rules and the decision behind them are in
92
- [install](install.md#scoping-what-the-graph-reads).
206
+ [install](../start/install.md#scoping-what-the-graph-reads).
93
207
 
94
208
  `atelier enroll documents` writes the sidecar the census demands of every
95
209
  non-Markdown document that has none, as the smallest classification that