# Determinism

Every component tagged `deterministic` must produce identical output for identical input. Same graph state → same context package, same validation result, same lock-verification result. No heuristics, no repository search beyond declared mappings. No network calls. Git operations (e.g. findChangedNodes) are deterministic relative to repo state. Token estimation uses fixed heuristic (~4 chars/token). Hash algorithms use SHA-256. No Math.random or Date.now in core logic. Exceptions: (1) observability outputs (audit log timestamps, debug log timestamps) are not part of the deterministic contract — they record when something happened, not what happened. (2) Fallback filesystem reads for data that SHOULD be in the loaded graph (e.g. nodeYamlRaw) — defensive fallbacks, not primary data sources. (3) Filesystem reads that verify graph-declared paths exist on disk (mapping validation, directory scanning, file hashing for lock verification) — these operations are deterministic relative to filesystem state, just as git operations are deterministic relative to repo state. The "input" for these operations includes filesystem state, not just graph state.
