Skip to content

fix(cli): affected and god-nodes refresh the orientation stamp and write the query ledger - #3054

Open
Azeem1985 wants to merge 1 commit into
Graphify-Labs:v8from
TelB-io:upstream/cli-affected-godnodes-stamp
Open

fix(cli): affected and god-nodes refresh the orientation stamp and write the query ledger#3054
Azeem1985 wants to merge 1 commit into
Graphify-Labs:v8from
TelB-io:upstream/cli-affected-godnodes-stamp

Conversation

@Azeem1985

Copy link
Copy Markdown
Contributor

Fixes #3053. Same defect class as #3039 (MCP half: #3042), one door over — this is the CLI half.

Defect

The strict read hook admits an agent only while the "recently oriented" stamp (graphify-out/cache/last_query_stamp) is fresh, and the opt-in query ledger is the audit trail of graph consults. graphify query / path / explain each stamp + log on success (e.g. querylog.log_query at cli.py:1177 and _touch_query_stamp(gp) at cli.py:1187 for query) — but graphify affected and graphify god-nodes (#2004) do neither. An agent that orients through either verb stays blind to the strict guard (next raw read denied after it already consulted the graph) and invisible to the ledger.

Fix

Orientation is orientation regardless of which door it comes through. Both verbs now mirror the query verb's calls on the success path:

  • affected: querylog.log_query(kind="affected", question=<seed>, corpus=<graph>, nodes_returned=<impacted count>, depth, duration_ms) then _touch_query_stamp(gp), then print. The count is exact: each impacted node renders as exactly one - line and no header line starts with - .
  • god-nodes: querylog.log_query(kind="god_nodes", question="top N", corpus=<graph>, nodes_returned=len(gods)) then _touch_query_stamp(gp).

Both are fail-silent like the existing call sites (log_query never raises; _touch_query_stamp swallows); the ledger stays opt-in behind the GRAPHIFY_QUERY_LOG* gates; error paths (missing/corrupt graph) exit before either call, so a failed run stamps and logs nothing. Output bytes of both verbs are unchanged.

Not touched here: the MCP tools' stamping is #3042; if both land, god_nodes over MCP becomes the remaining non-stamping door for the same consult and can be folded into #3042's _ORIENTATION_TOOLS set as a follow-up.

Tests

  • test_affected_cli_stamps_orientation_and_logs — an aged stamp's mtime advances; exactly one ledger line with kind affected, the exact impacted count, depth, and duration; ledger env-gated via GRAPHIFY_QUERY_LOG exactly like tests/test_querylog.py; tmp graph fixture, offline.
  • test_god_nodes_cli_stamps_orientation_and_logs — same shape for god-nodes; the logged count equals the number of hubs actually printed, not the --top ceiling.
  • Families run on this branch: test_affected_cli + test_god_nodes_cli + test_querylog + test_query_cli + test_explain_cli + test_hook_strict — 82 passed; ruff + py_compile clean.

🤖 Generated with Claude Code

@graphify-labs graphify-labs Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Graphify reviewed this change.

Looks safe to merge — no coupling regressions and no blocking issues, checked against the code graph (not a self-assessment).

Formal verification. No changes could be formally verified in this run.


Graphify review — findings

Makes the CLI affected and god-nodes verbs count as orientation like query/path/explain: a successful run refreshes the strict read guard's freshness stamp via _touch_query_stamp and appends a query-ledger line (affected with the impacted-node count, god_nodes with the returned-hub count). Both querylog.log_query calls are fail-silent and stay opt-in behind the existing GRAPHIFY_QUERY_LOG* gates, so an agent that orients through either verb is no longer denied on its next raw read or left absent from the audit trail.

No blocking issues surfaced. 6 lower-confidence candidates did not survive cross-model review.

Analysis details — impact, health, verification

Impact & health

Graphify review

Impact — 463 functions depend on the 290 functions this change touches.

Health — this change adds coupling hotspots:

  • new: dispatch_command() — 2 callers, 122 callees
  • new: _stale_graph_sources() — 7 callers, 6 callees
  • new: _run_hook_guard() — 4 callers, 7 callees
  • new: test_poisoned_manifest_is_healed() — 0 callers, 6 callees

Verification — 463 functions in the blast radius were not formally verified this run (proofs are advisory here).

Gate & verification

graphify gate

PASS — objectively clean (no health regressions, tests not run — proofs not run this pass (advisory)). Grounded, not self-assessed.

Advisory (not blocking):

  • verification_scope: 421 function(s) in the blast radius were not formally verified this run

Formal verification

Could not verify: Could not verify dispatch\_command.

The verifier did not have enough to check dispatch\_command, so it is saying so rather than guessing. No false assurance is the whole point.

Guarantee: No guarantee either way, this is an honest abstention, not a pass.

Note: Reason: not verifiable: all 23 sampled inputs raised on both versions — the function never executed, so 'no divergence' would be vacuous (mostly SystemExit — names the real obstacle, not a sampling gap)

· 4 more finding(s) on lines outside this diff (see the check run).

@Azeem1985

Copy link
Copy Markdown
Contributor Author

Thanks for the automated review — glad it reads clean. To restate the intent for human reviewers: affected and god-nodes are orientation verbs exactly like query/path/explain (an agent that just mapped a blast radius has oriented), so they now refresh the strict-hook freshness stamp and write the opt-in query ledger the same way. Both additions are fail-silent and behind the existing GRAPHIFY_QUERY_LOG* gates; running in production on our side since 2026-08-25 (ledger shows affected/god_nodes lines landing). Happy to adjust shape or naming to taste.

…query ledger

The strict read guard admits an agent only while the "recently oriented"
stamp (graphify-out/cache/last_query_stamp) is fresh, and the query ledger
is the audit trail of graph consults. query/path/explain each stamp + log,
and PR #12 extended the stamp to the MCP orientation tools — but the CLI
affected and god-nodes verbs did neither: an agent orienting through them
stayed blind to the guard (next raw read denied) and invisible to the
audit trail.

Orientation is orientation regardless of door (PR #12): both verbs now
mirror the query verb's calls after a successful run — kind="affected"
with the impacted-node count, kind="god_nodes" with the returned-hub
count — followed by _touch_query_stamp. Both are fail-silent; the ledger
stays opt-in behind the GRAPHIFY_QUERY_LOG* gates. The MCP god_nodes tool
still does not stamp; widening that set is a deliberate follow-up.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@Azeem1985
Azeem1985 force-pushed the upstream/cli-affected-godnodes-stamp branch from 4fed5a4 to 912dcd8 Compare August 25, 2026 23:26
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

CLI affected and god-nodes never refresh the strict hook's orientation stamp nor write the query ledger

1 participant