/** * Post-write audit for the database-operator's raw `write_neo4j_cypher` tool *. Sibling to `[graph-write] accepted` for the wrapped writers * (`memory-write`, `contact-create`, etc.) — same module so the * `[graph-*]` log family stays uniform across both write surfaces. * * Design posture: * - Static parse first. Pre-flight regex on the cypher text catches missing * provenance stamps and unknown edge types cheaply, no driver round-trip. * - Dynamic orphan detection is the caller's responsibility — the graph-mcp * shim runs the detection query against Neo4j after the upstream commits * and passes the resulting elementId list as `orphanIds`. Keeping the * module pure (no neo4j-driver import) makes it unit-testable without a * live database. * - Audit is observational. Warnings never block the write. The * prompt-level Graph Stewardship Doctrine in * [database-operator.md](../../../templates/specialists/agents/database-operator.md) * names the discipline; the audit is the verification stream. * * String literals are stripped before pattern checks so that property values * containing words like `'createdByAgent in my bio'` cannot trip a false * provenance count, and edge-like patterns inside quoted strings cannot * trip a false unknown-type warning. The regex shape is duplicated from * [cypher-validate.ts](../../graph-mcp/src/cypher-validate.ts) intentionally: * graph-write does not depend on graph-mcp, and a one-line regex helper * doesn't justify a third package. Drift in either copy is a regression * surfaced by both the validator tests and the audit tests. */ export interface SchemaSnapshot { readonly labels: ReadonlySet; readonly relationshipTypes: ReadonlySet; } export interface CypherWriteAuditInput { cypher: string; schema: SchemaSnapshot; agentName: string; sessionId: string; /** Counter from upstream response — drives missing-provenance arithmetic. */ nodesCreated: number; /** Counter from upstream response — informational only. */ relsCreated: number; /** * elementIds of nodes the post-write orphan query identified. Caller scopes * the query to (createdBySession, createdAt >= writeStartTimestamp) so this * list cannot include nodes from prior writes in the same session. Empty * array = no orphans (or no scope to check). */ orphanIds: string[]; } export type AuditWarning = { kind: "orphan-warning"; orphanIds: string[]; } | { kind: "unknown-type-warning"; type: string; } | { kind: "missing-provenance-warning"; created: number; stamped: number; }; export type AuditLine = { kind: "accepted"; cypherPrefix: string; nodesCreated: number; relsCreated: number; agentName: string; sessionId: string; } | { kind: "orphan-warning"; cypherPrefix: string; orphanIds: string[]; } | { kind: "unknown-type-warning"; cypherPrefix: string; type: string; } | { kind: "missing-provenance-warning"; cypherPrefix: string; created: number; stamped: number; }; export declare function auditCypherWrite(input: CypherWriteAuditInput): AuditWarning[]; export declare function formatAuditLine(line: AuditLine): string; //# sourceMappingURL=audit.d.ts.map