/** * Where a PROJECT's co-located code graph lives, and what each member repo is called inside it. * * # Why a module instead of a `join()` at each call site * * This is `repoPaths.ts`'s posture applied one level up (see that module's header for the bill: * five spellings of the per-repo graph path against a sixth inside wicked-core, and every graph * query answering "nothing found" about a repo full of code). One producer, one consumer. Nothing * outside this module spells a project-graph path or mints a repo label. * * # Why NOT inside a repo checkout * * The per-repo graph USED TO live at `/.codegraph/estate.db` — inside the working tree — and * we spent the effort removing that directory from six checkouts it had polluted; since * wicked-core#406 the engine keeps it under `/repo-graphs//estate.db` and never * adopts an in-tree copy. A PROJECT graph * is worse on that axis, not better: it holds N repos, so there is no one checkout it belongs to, * and writing it into the first member's tree would make repo A's working directory grow with repo * B's symbols. It goes in the daemon's own state directory. * * # Why `~/.wicked-crew/project-graphs//` * * `~/.wicked-crew/` is already where this package keeps crew-side per-project state that the engine * does not own — `project-settings.json` (DES-MERGE-001 §7.1) sits there today. The project graph is * exactly that kind of thing: crew-owned, per-project, derived, and rebuildable. A directory per * project (rather than `.db` files in one flat folder) keeps the db and the refresh * manifest that describes it together, so removing a project's graph is one `rm -rf` that cannot * leave a manifest describing a database that is gone. * * # Why the root FOLLOWS `--db` (crew#330) * * `~/.wicked-crew` is the daemon's DEFAULT state home, not its definition. A daemon started with * `--db $SCRATCH/core.db --bus-db $SCRATCH/bus.db` reads as fully isolated — and then built its * project graph in the developer's real home, 41.7 MB keyed by project ids that only the scratch * store ever knew, with nothing to reap them. One `--db` must move everything durable, so the * bootstrap threads the RESOLVED state home (the `--db` parent) into `state-home.ts` (originally * a seam private to this module; generalized when crew#353 found the settings store making the * same escape), and the resolver here prefers it over the homedir fallback. With no `--db`, the * resolved state home IS `~/.wicked-crew`, so the default daemon's paths are byte-identical to * what they were before the fix. * * Overridable with `WICKED_CREW_PROJECT_GRAPH_ROOT` — the same escape hatch * `WICKED_CREW_PROJECT_SETTINGS` gives the settings store, and what lets the tests and the proof * scripts run without touching a developer's real home. The env override outranks the configured * state home: it is the more specific instruction ("graphs go THERE") and the one CI already uses. */ /** * The estate label charset, copied from the rule that enforces it * (`wicked-estate/src/repo_scope.rs::validate_label`): 1–64 chars of `[A-Za-z0-9._-]`, and never * `.` or `..`. * * The constraint is not cosmetic and not ours to relax. estate splices the label into `files.path` * AND into every SymbolId derived from it, so a `/` or a `..` in a label would forge paths inside * another repo's namespace — the exact collision the whole labelling mechanism exists to prevent. * A label that fails this test is refused by estate before a single row is written; we mint labels * that pass it instead of discovering that at index time. */ export declare function isValidRepoLabel(label: string): boolean; /** * The label one registered repo carries inside a project graph — its REGISTRY ID when that id is * already a legal estate label, and a deterministic sanitized form when it is not. * * WHY the registry id. The label becomes a path prefix on every row the repo writes and shows up in * every result this surface returns, so it has to be a name an operator can map back to a repo * without a lookup table. It also has to be STABLE: estate binds a label to a repo permanently * (re-indexing under a second label is refused as a duplicate; re-using a label for a different repo * is refused as a collision), so a label derived from anything mutable — the repo's display name, * its root path, its position in the member list — would break the next refresh after a rename or a * move. The registry id is the one identifier that is both stable and already unique per repo. * * Every repo id in the live registry today (`wicked-ledger`, `wicked-vault`, `pageindex-proof`, …) * satisfies estate's rule as-is, so the common path is the identity function and the label IS the * id. That is not guaranteed for ids minted later, so the fallback is real rather than theoretical: * illegal characters collapse to `-`, the stem is capped, and a 12-hex digest of the FULL id is * appended — the digest is what keeps `a/b` and `a:b` (which sanitize identically) apart, and what * keeps a truncated 200-character id distinct from another that shares its first 51 characters. * * The mapping is a pure function of the id, which is what makes it safe against estate's permanent * binding: the same repo resolves to the same label on every refresh, for the life of the graph. */ export declare function repoLabel(repoId: string): string; /** * Project ids are REJECTED, never sanitized. * * A sanitizing map is what would let two distinct project ids land in one directory and share one * database — the same class of silent collision that made a multi-repo graph impossible in the first * place, reintroduced at the project level. It is also the traversal guard: the id is a path * segment, so `../../x` must never be spelled into a path. Engine-minted ids (`proj_1787…`) and the * synthesized `default` both pass; anything that does not is a bug worth hearing about. */ export declare function assertProjectIdIsPathSafe(projectId: string): void; /** The root every project graph directory hangs off. Precedence: explicit env override, then the * daemon's state home (the `--db` parent when configured — crew#330 — and the `~/.wicked-crew` * default otherwise, which is also what the configured state home resolves to without `--db`). */ export declare function projectGraphRoot(env?: NodeJS.ProcessEnv): string; /** One project's graph directory — holds the database and the manifest that describes it. */ export declare function projectGraphDir(projectId: string, env?: NodeJS.ProcessEnv): string; /** The ONE database holding every member repo of this project, co-located under their labels. */ export declare function projectGraphDb(projectId: string, env?: NodeJS.ProcessEnv): string; /** * What the last refresh put in that database, per repo — the record incremental refresh reads. * * Deliberately a SIDECAR rather than a read of estate's own `repo: