Repository navigation
feat(fingerprint, ticket-013): export read-only CFG and DFG fingerprints for semantic retrieval (#9) - #19
Conversation
…nts for semantic retrieval (#9)
There was a problem hiding this comment.
Validator approval after policy checks for exact head 4d417117c0bd3ee1c00bd5b48f9cab7cdc349fa2.
Ticket: ticket-013
Correlation ID: local-semcod-code2logic-pr-19-ticket-013
Model: openai/cursor-auto
Reviewed diff chunks: 7
Advisory LLM verdict: REQUEST_CHANGES
Advisory summary: Reviewed all 7 diff chunk(s). Required checks passed, but the visible alpha-normalization implementation does not consistently normalize equivalent method receiver parameters. | Required checks pass, and the visible implementation provides immutable, advisory-only structural records. However, the f-string normalization omits behaviorally significant formatting details. | Required checks pass, but the visible CFG construction for try/finally does not preserve Python's mandatory-finally execution semantics. | Required checks pass, but the visible implementation has unresolved structural-fingerprint correctness defects in control-flow and I/O-profile extraction. | Required checks pass, but the visible effects extraction has a semantic correctness defect: it attributes effects from nested function/class bodies to the enclosing symbol. | The visible chunk implements deterministic advisory-only structural similarity ranking, exports the intended public API, records ticket scope, and adds focused tests for alpha-renaming, recursive self-calls, and behavior-changing divergence. All protected required checks passed. | The visible test chunk verifies export metadata, serialization, candidate counts, exact structural-equivalence ranking, advisory-only authority, and lower ranking for an unrelated recursive function. No unresolved code or security defects are evident. All protected required checks passed.
Advisory findings: _SymbolAlphaNormalizer._bind_parameters maps a method's first parameter to "$self" only when its source name is literally "self" or "cls". An otherwise equivalent method using a different receiver name is mapped to "$arg0", producing a different normalized representation and structural digest solely because of alpha-renaming. This contradicts the stated symbol-local parameter alpha-renaming guarantee. Normalize the first method receiver by position or otherwise ensure receiver renames remain structurally equivalent, and add a regression test.; ast.JoinedStr normalization records only the formatted value expression and ignores each ast.FormattedValue node's conversion and format_spec. Consequently, behavior-changing expressions such as f"{value}", f"{value!r}", and f"{value:.2f}" can receive identical normalized AST and downstream structural fingerprints, contradicting the stated requirement that behavior-changing edits diverge. Include normalized conversion and format-spec information and cover these cases with tests.; In _CFGBuilder._process_block, the finally_block is connected only from try_tails + handler_tails. Abrupt control transfers inside the try or handlers—such as return, raise, break, and continue—are not tails and therefore bypass the finally node in the generated CFG, even though Python always executes the finally suite before completing those transfers. This can produce structurally incorrect fingerprints and similarity results for functions using try/finally.; CFG construction drops break control flow: a break node is created, but no edge connects it to the enclosing loop exit, and current_incoming is cleared. This produces an incomplete/incorrect CFG for loops containing break.; _build_io_profile uses ast.walk over each top-level statement without pruning nested function, async-function, class, or lambda scopes. Consequently, returns and yields inside nested definitions are attributed to the enclosing function, corrupting its return/yield shapes and potentially misclassifying it as a generator.; _build_effects_profile uses ast.walk(stmt) without stopping at nested FunctionDef, AsyncFunctionDef, Lambda, or ClassDef scopes. Consequently, calls, raises, awaits, and mutations inside a nested definition are recorded as effects of the enclosing function even though those bodies are not executed when the enclosing function runs. Scope-aware traversal is required.
The LLM output above is advisory and was not used as the approval trust root.
Semantic review prerequisite: not_required; policy 676cb4516bbfed2a000e40b9b1b6e4a430ecc761ec546aeb53d721a1905cfdd7.
Actual PR impact radar
Exact range: 2906d908b70411513553a7337f17a0b4f34a8849...4d417117c0bd3ee1c00bd5b48f9cab7cdc349fa2
Change digest: cb665c6ac3b952d7437497dae94a6cf6d06d6319b82a913b7c4c499b1ab8e698
Score: 68/100 (L), estimated 127 min, split recommended: true
Affected services/components: repository-wide/unclassified
Machine-readable radar JSONL and SVG
{"actual_change":{"additions":1881,"base_sha":"2906d908b70411513553a7337f17a0b4f34a8849","binary_files":0,"categories":{"code":2,"configuration":1,"docs":2,"tests":1},"change_digest":"cb665c6ac3b952d7437497dae94a6cf6d06d6319b82a913b7c4c499b1ab8e698","comparison":"2906d908b70411513553a7337f17a0b4f34a8849...4d417117c0bd3ee1c00bd5b48f9cab7cdc349fa2","deletions":0,"file_count":6,"files":["code2logic/core/__init__.py","code2logic/fingerprint.py","project/TICKETS.md","project/ticket-013/README.md","project/ticket-013/intent.json","tests/test_structural_fingerprint.py"],"head_sha":"4d417117c0bd3ee1c00bd5b48f9cab7cdc349fa2","service_count":0,"services":[]},"assessment_mode":"observed-pr","axes":{"coupling":5,"delivery":3,"scope":5,"uncertainty":3,"validation":1},"complexity":"L","confidence":0.9,"diagnostics":["RADAR-ACCEPTANCE-MISSING","RADAR-BUDGET-EXCEEDED"],"estimate":{"budget_minutes":30,"minutes":127,"within_budget":false},"impact":{"components":["I","code2logic","code2logic.structural_export","code2logic.structural_fingerprint","code2logic.structural_similarity","docstrings","mutations","project","tests"],"files":["I/O","code2logic.structural_export/v1","code2logic.structural_fingerprint/v1","code2logic.structural_similarity/v1","code2logic/core/__init__.py","code2logic/fingerprint.py","docstrings/comments","mutations/exceptions","project/TICKETS.md","project/ticket-013/README.md","project/ticket-013/intent.json","tests/test_structural_fingerprint.py"],"public_interfaces":[],"runtime_dependencies":1},"schema":"subactor.ticket-radar/v1","score":68,"split":{"parts":[{"estimated_minutes":13,"name":"Implement I","scope":["I"]},{"estimated_minutes":13,"name":"Implement code2logic","scope":["code2logic"]},{"estimated_minutes":13,"name":"Implement code2logic.structural_export","scope":["code2logic.structural_export"]},{"estimated_minutes":13,"name":"Implement code2logic.structural_fingerprint","scope":["code2logic.structural_fingerprint"]},{"estimated_minutes":13,"name":"Implement code2logic.structural_similarity","scope":["code2logic.structural_similarity"]},{"estimated_minutes":15,"name":"Validate and project to trackers","scope":["tests","planfile","github/gitlab/jira projections"]}],"reason":"estimated_minutes_exceed_budget","recommended":true},"standards":[{"id":"wellmanifest/dsl","revision":"6c60fc4e0dd1f1bb74f46a7745e28019908d1203","version":"0.1.0-dev"},{"id":"wellmanifest/ticket-lifecycle","revision":"5bf581907a87b46a13a73e6c033d3abe4d9a306f","version":"0.1.0-dev"},{"id":"wellmanifest/git-lifecycle","revision":"7d77d4b7af57e69bc75c3a0290b3a4805c5c4438","version":"0.2.0-dev"},{"id":"wellmanifest/logs","revision":"48c284ef7a069055c0bcb6b900147ce5e65f8b43","version":"0.3.0"}],"ticket_ref":"ticket-013"}<svg xmlns="http://www.w3.org/2000/svg" width="128" height="128" viewBox="0 0 128 128" role="img"><title>ticket-013: feat(fingerprint, ticket-013): export read-only CFG and DFG fingerprints for semantic retrieval (#9)</title><rect width="128" height="128" rx="12" fill="#f8fafc"/><g stroke-width="1"><polygon points="64,55 72,61 69,71 59,71 56,61" fill="none" stroke="#d7dde5"/><polygon points="64,47 80,59 74,78 54,78 48,59" fill="none" stroke="#d7dde5"/><polygon points="64,38 89,56 79,85 49,85 39,56" fill="none" stroke="#d7dde5"/><polygon points="64,30 97,53 84,92 44,92 31,53" fill="none" stroke="#d7dde5"/><polygon points="64,21 105,51 89,99 39,99 23,51" fill="none" stroke="#d7dde5"/><line x1="64" y1="64" x2="64" y2="21" stroke="#aab4c0"/><line x1="64" y1="64" x2="105" y2="51" stroke="#aab4c0"/><line x1="64" y1="64" x2="89" y2="99" stroke="#aab4c0"/><line x1="64" y1="64" x2="39" y2="99" stroke="#aab4c0"/><line x1="64" y1="64" x2="23" y2="51" stroke="#aab4c0"/></g><polygon points="64,21 105,51 79,85 59,71 39,56" fill="#fb923c" fill-opacity="0.45" stroke="#c2410c" stroke-width="2"/><circle cx="64" cy="64" r="3" fill="#c2410c"/><g font-family="sans-serif" font-size="7" fill="#334155"><text x="64" y="11" text-anchor="middle">SCO</text><text x="114" y="48" text-anchor="middle">COU</text><text x="95" y="107" text-anchor="middle">UNC</text><text x="33" y="107" text-anchor="middle">VAL</text><text x="14" y="48" text-anchor="middle">DEL</text></g><text x="64" y="124" text-anchor="middle" font-family="sans-serif" font-size="8" fill="#0f172a">L · 127m</text></svg>DECISION D-013-8016
TICKET ticket-013
HEAD_SHA 4d417117c0bd3ee1c00bd5b48f9cab7cdc349fa2
CORRELATION_ID local-semcod-code2logic-pr-19-ticket-013
ACTOR agent:ifuri-validator-agent[bot]
APPLIED_RULE P-CORE-015
INPUT author_login = "tom-sapletta-com"
INPUT observed_checks = ["test (3.11)=PASS","test (3.13)=PASS","governance / enforce=PASS","test (3.12)=PASS","governance / remote lifecycle=PASS","test (3.11)=PASS","test (3.13)=PASS","test (3.12)=PASS"]
INPUT required_checks = ["test (3.11)","test (3.12)","test (3.13)"]
INPUT required_checks_source = "protected registry (env/request)"
INPUT reviewer_login = "ifuri-validator-agent[bot]"
INPUT semantic_review_assessment = {"schema":"subactor.validator/semantic-review-assessment/v1","subject":{"repository":"semcod/code2logic","pull_request":19,"head_sha":"4d417117c0bd3ee1c00bd5b48f9cab7cdc349fa2","base_sha":"2906d908b70411513553a7337f17a0b4f34a8849","diff_sha256":"f75ac053f59d15e6e9ca8abcb44c3790676e8bcdc7786701c7d05e6a1fc64313"},"policy":{"policy_schema":"subactor.validator/semantic-review-policy/v1","policy_version":1,"policy_sha256":"676cb4516bbfed2a000e40b9b1b6e4a430ecc761ec546aeb53d721a1905cfdd7","required":false,"critical_paths":[],"observed_paths":["code2logic/core/__init__.py","code2logic/fingerprint.py","project/TICKETS.md","project/ticket-013/README.md","project/ticket-013/intent.json","tests/test_structural_fingerprint.py"]},"grounding":"full-diff-not-per-finding-proof","execution_authority":false,"status":"not_required","reason":null,"review_sha256":null,"unresolved":[]}
INPUT superseded_checks = []
INPUT ticket_radar_receipt = {"schema":"subactor.ticket-radar/v1","base_sha":"2906d908b70411513553a7337f17a0b4f34a8849","head_sha":"4d417117c0bd3ee1c00bd5b48f9cab7cdc349fa2","change_digest":"cb665c6ac3b952d7437497dae94a6cf6d06d6319b82a913b7c4c499b1ab8e698","score":68,"complexity":"L","estimated_minutes":127,"split_recommended":true,"services":[],"authority":"ADVISORY","promotion":"FORBIDDEN"}
VERDICT APPROVE AUTHORITY DETERMINISTIC
REJECTED REQUEST_CHANGES BECAUSE NO_UNSAFE_CHANGE_REASON_FOUND
ADVISORY llm_verdict = "REQUEST_CHANGES" MODEL "openai/cursor-auto"
ASSERT VERDICT_AUTHORITY != "ADVISORY"
Implement read-only structural IR export (
code2logic.structural_fingerprint/v1,code2logic.structural_export/v1,code2logic.structural_similarity/v1) for semantic retrieval candidates (PLF-006).Summary
code2logic/fingerprint.py(re-exported viacode2logic.core).read_only=True,authority="advisory_only",grants_authority=False).Closes #9
Ticket:
ticket-013