Repository navigation
feat(extract): deterministic business-process path extractor + Tier-1 processes gate - #27
Merged
Merged
Conversation
… processes gate Step 2 toward the grounded business-process extractor (DESIGN §14 item 2): materialize NAMED REAL PATHS deterministically — an extracted entrypoint (api_route / event_handler handler) -> a shortest chain of resolved first-party call edges -> a terminal function containing a SINK call. The LLM labeler is the next slice; the path itself needs no model. This is the first SECOND-ORDER extractor: ExtractContext gains `prior_artifacts` (the pipeline threads each extractor's outputs to later ones via dataclasses.replace; registration order is load-bearing — ProcessPathExtractor runs last in default_extractors()). The pipeline also materializes the analyzed repo's `.kb/` directory (new git.repo.iter_files_under_at + an extra_files channel kept OUT of the Python file map, so root discovery / parsing / diff reuse never see non-Python paths). PathEngine (the first shipped increment of the DESIGN §11 seam) BFS-slices the call_edge graph: visited-on-enqueue (cycle-safe, O(V+E), shortest path, deterministic tie-breaks via sorted adjacency), paths terminate at the first sink-bearing node, 0-hop supported (a handler with a direct sink grounds a single-span artifact, the direct-recursion precedent), depth/path caps retro-flag `limitations` — never silent. Sinks are typically third-party calls that the precision-first call_edge extractor skips, so sink detection is a separate textual scan against a registry, reusing calls.py's exact attribution machinery (_caller_scan_root lifted to module level) so edges and sinks always agree. Registry = built-in defaults (collision-averse) merged with an optional `.kb/sinks.yaml` override (strictly validated, loud on malformed input); the effective registry's digest is folded into framework_versions so a registry edit can never serve a stale payload (the identity-v2 discipline). Found paths are exact (confidence 1.0); incompleteness is an explicit payload fact, priced into the future labeled artifact. One `process_path` per (entrypoint, sink, terminal), grounded on EVERY span along the path (roles entrypoint/step/terminal — multi-file provenance, the thesis apex: the gate proves ONE artifact spanning THREE files). pyyaml moves to runtime deps; summarize/embed_text gain process_path branches. New Tier-1 HARD gate tier1_processes_test (hand-labeled oracle): 2-hop cross-file chain via the override-only sink, 0-hop built-in sink, event-handler entrypoint, reachable cycle no-hang, no-sink route yields nothing, override chain proven end-to-end, re-index determinism, depth caps. Headline HARD gates: thirteen -> fourteen. 102 eval tests pass.
This was referenced Jul 7, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What
Step 2 toward the crown jewel (DESIGN §14 item 2): deterministic named real paths — extracted entrypoint (
api_route/event_handlerhandler) → shortest chain of resolvedcall_edges → terminal function containing a sink (registry match). The LLM labeler is the next slice; the path itself needs no model.Architecture
ExtractContext.prior_artifacts+ pipeline threading (dataclasses.replaceper extractor; registration order is load-bearing —ProcessPathExtractorruns last). Existing gates unaffected (they pass their own extractor lists)..kb/materialization: the materialized tree previously contained only*.py; a newiter_files_under_at+extra_fileschannel ships the analyzed repo's.kb/sinks.yamlinto the snapshot without touching root discovery/parsing/diff-reuse.limitations(no silent caps)..kb/sinks.yamloverride (strictly validated, loudValueErroron malformed input). The effective registry's digest is identity-bearing (framework_versions) — a registry edit can never silently serve a stale payload (identity-v2 discipline).calls.py's attribution machinery (_caller_scan_rootlifted to module level) — edges and sinks agree bit-identically about which function contains a call.Gate #14 (
tier1_processes_test, 8 tests)Hand-labeled oracle: 2-hop cross-file chain to an override-only sink; 0-hop built-in sink; event-handler entrypoint; reachable cycle no-hang; no-sink route yields nothing; ONE artifact grounded across THREE files (the thesis apex);
.kb/sinks.yamloverride proven end-to-end (git blob → materialization → merge); re-index determinism; depth caps. Headline HARD gates: thirteen → fourteen.Checks
ruff+mypy --strictclean (77 files); 102 passed, 1 skipped (94 + 8 new)pyyaml→ runtime deps (uv lockrefreshed);kb indexstays static/offline.Next slice: LLM labeling of paths via
kb describe(target_kind="process", samevalidate_claimsfloor) + the span-binding validator.