{
  "access": "public",
  "type": "reference",
  "format": "markdown",
  "title": "Forensic Inference Tools Reference",
  "chunked": true,
  "url": "https://library.datagrout.ai/forensic-tools",
  "summary": "Structured agent debugging through fact accumulation and Prolog-based transitive reasoning.",
  "content_markdown": "# Forensic Inference Tools\n\nStructured agent debugging through fact accumulation and Prolog-based transitive reasoning.\n\n## How it works\n\nForensic Inference is a debugging paradigm where agents assert structured facts into the `_forensic` Logic Cell namespace during investigation, then query pre-built Prolog rules that perform exhaustive reasoning over the unified fact base. The agent does the observation; Prolog does the deduction.\n\nAll forensic operations use the standard Logic Cell tools (`logic.assert`, `logic.query`, `logic.constrain`, `logic.reflect`) with `namespace` set to `\"_forensic\"`. The forensic rule library is loaded automatically.\n\n---\n\n## Standard predicates\n\nAgents assert these predicates as facts. The rule library reasons over them.\n\n| Predicate | Arity | Description |\n|-----------|-------|-------------|\n| `causes(A, B)` | 2 | A causally leads to B |\n| `requires(X, Dep)` | 2 | X requires dependency Dep |\n| `provides(Source, Cap)` | 2 | Source provides capability Cap |\n| `config_value(C, K, V)` | 3 | Component C has config key K with value V |\n| `runtime_behavior(C, B, V)` | 3 | Component C exhibits behavior B with value V |\n| `code_behavior(F, B)` | 2 | Function F has code-level behavior B |\n| `invariant(Name, Cond)` | 2 | Named invariant with callable condition |\n| `asserts_property(S, P, V)` | 3 | Source S asserts property P has value V |\n| `depends_on(A, B, Kind, _)` | 4 | A depends on B with dependency kind (Invariant bridge) |\n| `calls_external(Caller, Mod, Func, Arity, Line)` | 5 | Call graph edge (Invariant bridge) |\n\n---\n\n## Rule library predicates\n\nThese are the pre-built rules agents can query. All return results derived from the asserted facts.\n\n### Causal analysis\n\n| Predicate | Description |\n|-----------|-------------|\n| `causal_chain(A, B, Chain)` | Finds a transitive causal path from A to B, returning the full chain as a list |\n| `blast_radius(Origin, Affected)` | Everything transitively affected by Origin |\n| `all_affected(Origin, List)` | Sorted list of all entities in the blast radius |\n| `common_cause(Effect1, Effect2, Cause)` | Finds a shared upstream cause of two effects |\n\n### Invariant checking\n\n| Predicate | Description |\n|-----------|-------------|\n| `invariant_holds(Name)` | True if the named invariant's condition succeeds |\n| `invariant_violated(Name, Cond)` | Binds Name and Cond for invariants whose conditions fail |\n| `all_violations(List)` | Collects all violated invariants as `inv(Name, Cond)` terms |\n\n### Dependency analysis\n\n| Predicate | Description |\n|-----------|-------------|\n| `missing_dependency(X, Dep)` | X requires Dep but nothing provides it |\n| `all_missing(List)` | Sorted list of all `missing(X, Dep)` terms |\n| `transitive_dep(A, B)` | A transitively depends on B (tabled for performance) |\n| `circular_dep(A, B)` | A and B are in a dependency cycle |\n\n### Contradiction detection\n\n| Predicate | Description |\n|-----------|-------------|\n| `contradiction(S1, S2, Prop)` | Two sources assert conflicting values for the same property |\n\n### Cross-domain analysis\n\n| Predicate | Description |\n|-----------|-------------|\n| `timeout_risk(Component, TimeoutMs, DeadlineMs)` | Component's idle timeout is shorter than a configured deadline |\n| `code_runtime_mismatch(Func, CodeBehavior, RuntimeBehavior)` | Code-level behavior doesn't match observed runtime behavior |\n| `unreachable_from(Origin, Target, Domain)` | Target is in Domain but not reachable from Origin via causal chains |\n\n---\n\n## Workflow\n\n### 1. Assert facts during investigation\n\n```json\n{\n  \"name\": \"data-grout@1/logic.assert@1\",\n  \"arguments\": {\n    \"namespace\": \"_forensic\",\n    \"facts\": [\n      {\"subject\": \"code_change\", \"relation\": \"causes\", \"object\": \"no_keepalives\"},\n      {\"subject\": \"no_keepalives\", \"relation\": \"causes\", \"object\": \"idle_connection\"},\n      {\"subject\": \"idle_connection\", \"relation\": \"causes\", \"object\": \"proxy_kill\"},\n      {\"subject\": \"proxy_kill\", \"relation\": \"causes\", \"object\": \"timeout_504\"}\n    ]\n  }\n}\n```\n\n### 2. Query the rule library\n\n```json\n{\n  \"name\": \"data-grout@1/logic.query@1\",\n  \"arguments\": {\n    \"namespace\": \"_forensic\",\n    \"query\": \"causal_chain(code_change, timeout_504, Chain)\"\n  }\n}\n```\n\nReturns: `Chain = [code_change, no_keepalives, idle_connection, proxy_kill, timeout_504]`\n\n### 3. Check for contradictions\n\n```json\n{\n  \"name\": \"data-grout@1/logic.query@1\",\n  \"arguments\": {\n    \"namespace\": \"_forensic\",\n    \"query\": \"contradiction(S1, S2, Property)\"\n  }\n}\n```\n\n### 4. Verify invariants\n\n```json\n{\n  \"name\": \"data-grout@1/logic.query@1\",\n  \"arguments\": {\n    \"namespace\": \"_forensic\",\n    \"query\": \"all_violations(V)\"\n  }\n}\n```\n\n---\n\n## The `_forensic` namespace\n\nThe `_forensic` namespace is a dedicated, visible Logic Cell namespace for forensic debugging. It is isolated from the user's default fact space, so forensic facts never pollute normal logic operations. Use `logic.worlds` to see it alongside other namespaces.\n"
}