feat(#139): domain pattern fingerprint & drift engine#140
Conversation
6-task plan covering patterns.yaml, FingerprintExtractor, DriftScorer, cgis drift CLI, and gen_ideal_graph --from-ontology mode. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Implements the seven-component structural fingerprint (hub_count, star_count, chain_len, dag_depth, router_count, cycle_ratio, unresolved_ratio) for a domain FQN prefix, backed by HealthScorer for cycle detection. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Adds `cgis drift` subcommand that loads project domains from patterns.yaml, computes per-domain PatternFingerprints via FingerprintExtractor, scores them with DriftScorer, and exits 1 if any domain meets or exceeds the critical drift threshold. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Adds generate_from_ontology() to scripts/gen_ideal_graph.py, which reads a patterns.yaml file and generates an ideal graph per project_domain using the real fqn_prefix as the node namespace. Wires it up via --from-ontology CLI flag. Adds 4 TDD tests covering schema validity, unique IDs, prefix correctness, and no dangling edges. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
There was a problem hiding this comment.
Code Review
This pull request implements the Domain Pattern Fingerprint & Drift Engine, introducing a YAML-based pattern configuration, fingerprint extraction from the SQLite store, drift scoring against ideal templates, a new cgis drift CLI command, and an ontology-based ideal graph generator. The review feedback highlights critical algorithmic issues in the fingerprint extractor, specifically incorrect BFS traversals for path length and DAG depth calculations that should be replaced with memoized DFS. Additionally, the feedback identifies potential runtime errors, including a ZeroDivisionError and a KeyError in the drift scorer, a potential TypeError in the graph generator script when parsing empty configurations, and a lack of robust error handling in the new CLI command.
Important
The consumer version of Gemini Code Assist on GitHub is being sunset. Starting June 18, 2026, new organization installations will be blocked, and all code review activity will officially cease on July 17, 2026.
For more details on the timeline and next steps, please review the Help Documentation.
…except - fingerprint.py: replace BFS with memoized DFS in _avg_chain_length and _max_dag_depth — BFS with global visited underestimates depth in DAGs where a node is reachable via multiple paths of different lengths - drift.py: guard ZeroDivisionError when total_weight==0; replace raw KeyError on unknown expected_pattern with descriptive ValueError - cli.py: wrap drift command core logic in try-except for consistent UX - gen_ideal_graph.py: guard against yaml.safe_load returning None on empty file; use `or []` for project_domains to handle explicit None Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
|
/gemini review |
There was a problem hiding this comment.
Code Review
This pull request implements the Domain Pattern Fingerprint & Drift Engine, introducing the cgis drift CLI command to measure architectural drift against ideal patterns defined in docs/ontology/patterns.yaml. It adds fingerprint extraction, drift scoring, and an ontology-based ideal graph generator, along with comprehensive unit tests. The review feedback identifies a bug where the drift command's --format option uses an enum that does not support the expected json output, and a performance bottleneck in _count_routers that can be optimized from O(N * M) to O(N + M) by pre-building a calls mapping.
Important
The consumer version of Gemini Code Assist on GitHub is being sunset. Starting June 18, 2026, new organization installations will be blocked, and all code review activity will officially cease on July 17, 2026.
For more details on the timeline and next steps, please review the Help Documentation.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Split score() into _zero_drift_report() and _score_constraint() to bring cognitive complexity from 18 down to ≤15. Also fix remaining float equality check in test_fingerprint.py. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
|
/gemini review |
There was a problem hiding this comment.
Code Review
This pull request implements the Domain Pattern Fingerprint & Drift Engine, introducing the cgis drift CLI command to measure architectural drift against ideal patterns defined in patterns.yaml. It adds fingerprint extraction, drift scoring, and support for generating ideal graphs from the ontology, along with comprehensive unit tests. The review feedback focuses on performance and robustness improvements, including caching database queries and health scoring in FingerprintExtractor, optimizing the complexity of _count_routers from quadratic to linear, safely retrieving weights in DriftScorer to avoid potential KeyErrors, and adding file existence checks in generate_from_ontology to prevent unhandled FileNotFoundErrors.
Important
The consumer version of Gemini Code Assist on GitHub is being sunset. Starting June 18, 2026, new organization installations will be blocked, and all code review activity will officially cease on July 17, 2026.
For more details on the timeline and next steps, please review the Help Documentation.
… FingerprintExtractor, safe weights - cli: add DriftOutputFormat enum (TEXT/JSON) so --format json is a valid typer choice - fingerprint: pre-build calls_by_source in _count_routers to reduce O(N*M) -> O(N+M) - fingerprint: cache enriched nodes + edges in FingerprintExtractor._loaded() to avoid re-fetching per domain when scoring multiple domains in one drift run - drift: use self._weights.get(name, 0.0) to prevent KeyError on custom patterns.yaml - gen_ideal_graph: raise FileNotFoundError early in generate_from_ontology Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
|
/gemini review |
There was a problem hiding this comment.
Code Review
This pull request implements the Domain Pattern Fingerprint & Drift Engine, introducing pattern templates in patterns.yaml, fingerprint extraction in fingerprint.py, drift scoring in drift.py, a new cgis drift CLI command, and an ontology-based synthetic graph generator. Feedback focuses on ensuring deterministic behavior in graph traversal metrics by sorting set-derived lists, and improving YAML loading robustness in DriftScorer to prevent potential TypeError or KeyError exceptions.
Important
The consumer version of Gemini Code Assist on GitHub is being sunset. Starting June 18, 2026, new organization installations will be blocked, and all code review activity will officially cease on July 17, 2026.
For more details on the timeline and next steps, please review the Help Documentation.
- fingerprint: sort sources/roots before DFS to guarantee identical chain_len
and dag_depth across runs (set iteration order is non-deterministic)
- drift: use `or {}` / `.get()` in DriftScorer.__init__ so empty or malformed
patterns.yaml doesn't crash with TypeError/KeyError
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
|
/gemini review |
There was a problem hiding this comment.
Code Review
This pull request implements the Domain Pattern Fingerprint & Drift Engine, adding the cgis drift CLI command to measure how much a domain's graph topology deviates from its ideal architectural pattern. It introduces pattern configurations in patterns.yaml, a FingerprintExtractor to compute structural metrics, a DriftScorer to evaluate drift, and updates gen_ideal_graph.py with a --from-ontology mode. The review feedback focuses on improving robustness when parsing YAML configurations by ensuring the loaded content is a dictionary before calling .get(), and safely falling back to an empty dictionary when retrieving expected patterns.
Important
The consumer version of Gemini Code Assist on GitHub is being sunset. Starting June 18, 2026, new organization installations will be blocked, and all code review activity will officially cease on July 17, 2026.
For more details on the timeline and next steps, please review the Help Documentation.
- fingerprint: extract shared _root_depths() helper — the memoized DFS was duplicated verbatim in _avg_chain_length and _max_dag_depth (sonar 13.6% duplication on new code) - drift: isinstance guard on yaml.safe_load result (lists/strings no longer crash __init__); non-dict pattern template raises TypeError with a clear message instead of AttributeError in _parse_constraints - gen_ideal_graph: same isinstance guard for malformed YAML Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
|



Closes #139
Summary
docs/ontology/patterns.yaml— 5 named pattern templates (pure_utility,pipeline_stage,orchestrator,layered_dag,dispatcher) with drift weights and 5 project domain expectationssrc/cgis/query/fingerprint.py—PatternFingerprintfrozen dataclass (7-component structural vector) +FingerprintExtractor(usesHealthScorerfor cycle/fan metrics, BFS for chain length and DAG depth)src/cgis/query/drift.py—DriftScorer(per-component normalized weighted MAE, directional penalties) +DriftReport+DomainConfigcgis driftCLI command — scores all project domains, renders Rich table, exits 1 if any domain reaches critical thresholdgen_ideal_graph.py --from-ontologymode — generates ideal graph JSON using real FQN prefixes from patterns.yamlDrift formula
drift = Σ w_i * clip(|actual_i - ideal_i| / norm_i, 0, 1)over constrained components only (re-normalized weights). Directional:{min: X}penalizes undershoot only,{max: X}penalizes overshoot only.Test plan
uv run pytest tests/unit/test_patterns_yaml.py— 8 structural YAML validation testsuv run pytest tests/unit/test_fingerprint.py— 14 FingerprintExtractor unit testsuv run pytest tests/unit/test_drift.py— 11 DriftScorer unit testsuv run pytest tests/unit/test_cli.py -k drift— 4 CLI integration testsuv run pytest tests/unit/test_gen_ideal_graph.py -k ontology— 4 gen_ideal_graph testsmake format && make lint && make type-check && make pytest && make doc-coverage— all green (440 tests, 100% docstring coverage)uv run cgis ingest . --source-root src --output /tmp/g.db && uv run cgis drift --db /tmp/g.db --patterns docs/ontology/patterns.yaml🤖 Generated with Claude Code