/** * Parser for the three machine-readable regions of an account's SCHEMA.md. * * Shared because two separate builds need the same answer: the admin UI server * (platform/ui/server/lib/account-root-groups.ts, which groups the /data root * into home/system) and the session manager's standing schema reconcile * (platform/services/claude-session-manager/src/account-dir-schema-reconcile.ts, * which audits declared-versus-on-disk parity). A third reader, * platform/plugins/cloudflare/bin/schema-exposed-dirs.mjs, ships in a separate * deploy tree and keeps its own copy; a parity test asserts the two agree. * * The regions are written by platform/scripts/lib/account-schema-owned-dirs.py * merge(). Their separators differ: * * ontology roots: - `jobs/` - one folder per Job record. (ASCII hyphen) * plugin-owned: - `pages/` — Owned by the … plugin. (em dash) * * .docs/data-portal-folder-index.md records that parsing the ontology region on * the wrong separator matches nothing and reads as "this account has no * deliverables". This parser sidesteps that failure entirely by anchoring on the * backticked `dir/` head rather than the separator, and a test pins the * behaviour so a future edit cannot reintroduce separator sensitivity. */ /** * Non-ontology buckets that are still the operator's own work, so they are home * on every brand. They carry no ontology row because they are not entity * buckets. On a vertical with no `## Top-level node types` table * (schema-knowledge-work) they are the whole of home. * * The membership test is "would the operator go looking for this?", not "who * writes it". `output`, `generated` and `extracted` hold delivered work product; * `sites` holds published websites; `uploads` holds what a client sent in. The * shipped template groups those five under "tool-owned", but that is a rule * about not reorganising their internals — a write constraint, not a reason to * file them behind the platform's own plumbing. What stays out is genuinely * internal: caches, state, logs, secrets, temp, the git and Claude control * dirs, and plugin workspaces. * * Every name here is created at provision (provision-account-dir.sh `_seed_dirs`), * so the standing home-parity audit finds them on disk rather than reporting * them missing. * * Lives here rather than in either consumer because both the /data page and the * standing reconcile audit must agree on the same set; a hand-synced copy in * each build is precisely the drift this shared module exists to prevent. */ export const HOME_FIXED: readonly string[] = Object.freeze([ 'projects', 'contacts', 'documents', 'output', 'generated', 'extracted', 'sites', 'uploads', ]) const ONT_START = '' const ONT_END = '' const PLUGIN_START = '' const PLUGIN_END = '' const ALLOWED_FENCE = '```allowed-top-level' /** * A region line declaring a directory: `- \`