feat: add AL (.al) language support - #2996
Conversation
There was a problem hiding this comment.
Graphify reviewed this change.
Worth a look — the grounded gate found no coupling regressions or blocking issues, but 5 advisory finding(s) below merit a look before merge.
Formal verification. No changes could be formally verified in this run.
Graphify review — findings
Adds Business Central AL (.al) as a supported language: introduces graphify/al_resolution.py for application-level, case-insensitive cross-file symbol resolution (objects, procedures, triggers, fields, enum values, extensions, interfaces, typed calls, event subscriptions) plus AL extractor/detector wiring and a new [al] extra with a Tree-sitter path on Python 3.12+ and a structural fallback elsewhere. Documents the new grammar and extra in the README (now 38 grammars) and CHANGELOG, and adds a test covering AL corpus extraction continuing past a failing file.
Worth a look
- Source-file comparison only handles one absolute/relative direction —
graphify/al_resolution.py:19· Escalate · medium- agreed by 2 of 2 members but NOT verified (no proof, no reproducing execution) — consensus is not a verdict; needs human review
- Uppercase AL files are not classified as code —
graphify/detect.py:45· Escalate · medium- agreed by 2 of 2 members but NOT verified (no proof, no reproducing execution) — consensus is not a verdict; needs human review
- AL fallback omits al_facts from extract_al return schema —
graphify/extractors/al.py· Escalate · medium- agreed by 2 of 2 members but NOT verified (no proof, no reproducing execution) — consensus is not a verdict; needs human review
- AL fallback returns callable parameters as string instead of metadata list —
graphify/extractors/al.py· Escalate · medium- agreed by 2 of 2 members but NOT verified (no proof, no reproducing execution) — consensus is not a verdict; needs human review
- Fallback callable metadata uses string parameters vs list in tree-sitter path —
graphify/extractors/al.py· Escalate · medium- agreed by 2 of 2 members but NOT verified (no proof, no reproducing execution) — consensus is not a verdict; needs human review
Analysis details — impact, health, verification
Impact & health
Graphify review
Impact — 2267 functions depend on the 596 functions this change touches.
Health — this change adds coupling hotspots:
- new:
extract()— 481 callers, 42 callees - new:
_rebuild_code()— 98 callers, 50 callees - new:
detect()— 108 callers, 15 callees - new:
save_manifest()— 39 callers, 11 callees - new:
extract_files_direct()— 17 callers, 20 callees - new:
extract_xaml()— 19 callers, 17 callees - new:
extract_corpus_parallel()— 26 callers, 11 callees - new:
extract_js()— 80 callers, 3 callees - …and 40 more — each is listed as a finding
Verification — 2267 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: 2072 function(s) in the blast radius were not formally verified this run
Formal verification
Could not verify: Could not verify extract.
The verifier did not have enough to check extract, 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: parameter `cache_root` is annotated `Path | None` — outside the synthesizable primitive/collection set
· 3 grounded finding(s) anchored inline below; 45 more finding(s) on lines outside this diff (see the check run).
There was a problem hiding this comment.
Graphify reviewed this change.
Worth a look — the grounded gate found no coupling regressions or blocking issues, but 5 advisory finding(s) below merit a look before merge.
Formal verification. No changes could be formally verified in this run.
Graphify review — findings
Adds Business Central AL (.al) extraction as the 38th tree-sitter grammar, with a new graphify/al_resolution.py module that does application-level, case-insensitive cross-file symbol resolution (objects, permission sets, procedures/overloads, triggers, fields, enums, extensions, interfaces, typed calls, event subscriptions, app dependencies, and TestPage/test-handler bindings). Wires up the optional [al] extra for full Tree-sitter extraction on Python 3.12+ and a structural object/procedure/trigger fallback elsewhere, plus tests covering the resolver, invalid/missing manifests, and the optional-extra parser path. Updates README (supported types table, prerequisites) and CHANGELOG accordingly.
Worth a look
- _same_source suffix match can produce false positives across distinct files —
graphify/al_resolution.py· Escalate · medium- agreed by 2 of 2 members but NOT verified (no proof, no reproducing execution) — consensus is not a verdict; needs human review
- AL fact ids collide across files —
graphify/al_resolution.py:106· Escalate · medium- agreed by 2 of 2 members but NOT verified (no proof, no reproducing execution) — consensus is not a verdict; needs human review
- Fallback AL callable IDs collide for repeated triggers —
graphify/extractors/al.py· Escalate · medium- agreed by 2 of 2 members but NOT verified (no proof, no reproducing execution) — consensus is not a verdict; needs human review
- masked.find with limited end may miss object opening brace —
graphify/extractors/al.py· Escalate · medium- agreed by 2 of 2 members but NOT verified (no proof, no reproducing execution) — consensus is not a verdict; needs human review
- Fallback AL object regex omits permissionset objects —
graphify/extractors/al.py:10· Escalate · medium- agreed by 2 of 2 members but NOT verified (no proof, no reproducing execution) — consensus is not a verdict; needs human review
Analysis details — impact, health, verification
Impact & health
Graphify review
Impact — 2270 functions depend on the 599 functions this change touches.
Health — this change adds coupling hotspots:
- new:
extract()— 483 callers, 42 callees - new:
_rebuild_code()— 98 callers, 50 callees - new:
detect()— 108 callers, 15 callees - new:
save_manifest()— 39 callers, 11 callees - new:
extract_files_direct()— 17 callers, 20 callees - new:
extract_xaml()— 19 callers, 17 callees - new:
extract_corpus_parallel()— 26 callers, 11 callees - new:
extract_js()— 80 callers, 3 callees - …and 40 more — each is listed as a finding
Verification — 2270 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: 2075 function(s) in the blast radius were not formally verified this run
Formal verification
Could not verify: Could not verify extract.
The verifier did not have enough to check extract, 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: parameter `cache_root` is annotated `Path | None` — outside the synthesizable primitive/collection set
· 3 grounded finding(s) anchored inline below; 45 more finding(s) on lines outside this diff (see the check run).
There was a problem hiding this comment.
Graphify reviewed this change.
Worth a look — the grounded gate found no coupling regressions or blocking issues, but 1 advisory finding(s) below merit a look before merge.
Formal verification. No changes could be formally verified in this run.
Graphify review — findings
Adds Business Central AL (.al) extraction: a new graphify/al_resolution.py performs application-level cross-file symbol resolution (objects, permission sets, procedures/overloads, triggers, fields, enums, extensions, interfaces, typed calls, event subscriptions, app dependencies, and TestPage/handler bindings) with case-insensitive matching and app.json manifest awareness, backed by new detectors and extractors (graphify_detect_*, graphify_extractors_al_*). Registers .al as the 38th grammar with an optional [al] extra and a structural fallback for non-3.12 Python, updating README supported-types and the CHANGELOG.
Worth a look
- Fallback AL extractor collapses duplicate trigger members —
graphify/extractors/al.py· Escalate · medium- agreed by 2 of 2 members but NOT verified (no proof, no reproducing execution) — consensus is not a verdict; needs human review
Analysis details — impact, health, verification
Impact & health
Graphify review
Impact — 2326 functions depend on the 655 functions this change touches.
Health — this change adds coupling hotspots:
- new:
extract()— 483 callers, 42 callees - new:
_rebuild_code()— 98 callers, 50 callees - new:
detect()— 108 callers, 15 callees - new:
save_manifest()— 39 callers, 11 callees - new:
extract_files_direct()— 17 callers, 20 callees - new:
extract_xaml()— 19 callers, 17 callees - new:
extract_corpus_parallel()— 26 callers, 11 callees - new:
extract_js()— 80 callers, 3 callees - …and 37 more — each is listed as a finding
Verification — 2326 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: 2131 function(s) in the blast radius were not formally verified this run
Formal verification
Could not verify: Could not verify extract.
The verifier did not have enough to check extract, 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: parameter `cache_root` is annotated `Path | None` — outside the synthesizable primitive/collection set
· 45 more finding(s) on lines outside this diff (see the check run).
There was a problem hiding this comment.
Graphify reviewed this change.
Worth a look — the grounded gate found no coupling regressions or blocking issues, but 5 advisory finding(s) below merit a look before merge.
Graphify review — findings
Adds Business Central AL (.al) extraction as the 38th grammar, spanning a new graphify/al_resolution.py application-level resolver (_ALSymbolResolver with manifest/dependency, object, member, and event-subscriber mapping) and AL extractor helpers (Tree-sitter parsing plus a structural fallback for non-3.12 Pythons). Registers the [al] optional extra and documents it in the README supported-types table and CHANGELOG. Includes AL tree-sitter tests asserting callable/field metadata preservation.
Worth a look
- target selected as candidates[0] after set() dedup on unhashable dicts —
graphify/al_resolution.py· Escalate · high- agreed by 2 of 2 members but NOT verified (no proof, no reproducing execution) — consensus is not a verdict; needs human review
- opening brace search fails when '{' is outside match span —
graphify/extractors/al.py· Escalate · high- agreed by 2 of 2 members but NOT verified (no proof, no reproducing execution) — consensus is not a verdict; needs human review
- Whitespace not stripped from split handler names —
graphify/al_resolution.py· Escalate · medium- agreed by 2 of 2 members but NOT verified (no proof, no reproducing execution) — consensus is not a verdict; needs human review
- _same_source suffix match can produce false positives across files —
graphify/al_resolution.py· Escalate · medium- agreed by 2 of 2 members but NOT verified (no proof, no reproducing execution) — consensus is not a verdict; needs human review
- Aggregate extractors package now requires optional AL extractor —
graphify/extractors/__init__.py:13· Escalate · medium- agreed by 2 of 2 members but NOT verified (no proof, no reproducing execution) — consensus is not a verdict; needs human review
Analysis details — impact, health, verification
Impact & health
Graphify review
Impact — 2327 functions depend on the 656 functions this change touches.
Health — this change adds coupling hotspots:
- new:
extract()— 483 callers, 42 callees - new:
_rebuild_code()— 98 callers, 50 callees - new:
detect()— 108 callers, 15 callees - new:
save_manifest()— 39 callers, 11 callees - new:
extract_files_direct()— 17 callers, 20 callees - new:
extract_xaml()— 19 callers, 17 callees - new:
extract_corpus_parallel()— 26 callers, 11 callees - new:
extract_js()— 80 callers, 3 callees - …and 37 more — each is listed as a finding
Verification — 2327 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: 2132 function(s) in the blast radius were not formally verified this run
· 45 more finding(s) on lines outside this diff (see the check run).
There was a problem hiding this comment.
Graphify reviewed this change.
Worth a look — the grounded gate found no coupling regressions or blocking issues, but 3 advisory finding(s) below merit a look before merge.
Graphify review — findings
Adds Business Central AL (.al) extraction with a new al_resolution.py application-level resolver and extractors/al.py, wiring the extractor into extractors/__init__.py and the language-family/detection paths. Models objects, permission sets, procedures/overloads, triggers, fields, enums, extensions, interfaces, typed calls, event subscriptions, and test-app relationships with case-insensitive cross-file resolution and app.json-driven dependency edges; full Tree-sitter parsing requires the optional [al] extra on Python 3.12+ with a structural fallback otherwise. Documents the new grammar in the README and CHANGELOG and adds AL parser fallback/read-error tests.
Worth a look
- ImportError from tree_sitter (not tree_sitter_al) misreported as fallback path or wrong error —
graphify/extractors/al.py· Escalate · medium- agreed by 2 of 2 members but NOT verified (no proof, no reproducing execution) — consensus is not a verdict; needs human review
- Comment masker treats // inside quoted AL identifiers as a real comment —
graphify/extractors/al.py:57· Escalate · medium- agreed by 2 of 2 members but NOT verified (no proof, no reproducing execution) — consensus is not a verdict; needs human review
- Only the first implemented interface is recorded —
graphify/extractors/al.py:268· Escalate · medium- agreed by 2 of 2 members but NOT verified (no proof, no reproducing execution) — consensus is not a verdict; needs human review
Analysis details — impact, health, verification
Impact & health
Graphify review
Impact — 2330 functions depend on the 659 functions this change touches.
Health — this change adds coupling hotspots:
- new:
extract()— 483 callers, 42 callees - new:
_rebuild_code()— 98 callers, 50 callees - new:
detect()— 108 callers, 15 callees - new:
save_manifest()— 39 callers, 11 callees - new:
extract_files_direct()— 17 callers, 20 callees - new:
extract_xaml()— 19 callers, 17 callees - new:
extract_corpus_parallel()— 26 callers, 11 callees - new:
extract_js()— 80 callers, 3 callees - …and 37 more — each is listed as a finding
Verification — 2330 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: 2135 function(s) in the blast radius were not formally verified this run
· 45 more finding(s) on lines outside this diff (see the check run).
There was a problem hiding this comment.
Graphify reviewed this change.
Worth a look — the grounded gate found no coupling regressions or blocking issues, but 4 advisory finding(s) below merit a look before merge.
Formal verification. No changes could be formally verified in this run.
Graphify review — findings
Adds Business Central AL (.al) extraction as the 38th tree-sitter grammar, introducing graphify/al_resolution.py for application-level cross-file symbol resolution (objects, procedures, fields, enums, extensions, events, app dependencies, and test-app bindings) plus new AL extractors. Documents the optional [al] extra in the README support table and language list, with a structural fallback for non-3.12 Python. Records the feature in the 0.9.48 changelog.
Worth a look
- _matching_brace ignores braces inside masked/unmasked strings and comments —
graphify/extractors/al.py· Escalate · medium- agreed by 2 of 2 members but NOT verified (no proof, no reproducing execution) — consensus is not a verdict; needs human review
- Fallback skipped when tree_sitter core import fails —
graphify/extractors/al.py· Escalate · medium- agreed by 2 of 2 members but NOT verified (no proof, no reproducing execution) — consensus is not a verdict; needs human review
- Regex fallback omits permissionset objects —
graphify/extractors/al.py:10· Escalate · medium- agreed by 2 of 2 members but NOT verified (no proof, no reproducing execution) — consensus is not a verdict; needs human review
- AL optional-extra guidance is codified with misspelled package name —
tests/test_al.py:50· Escalate · medium- agreed by 2 of 2 members but NOT verified (no proof, no reproducing execution) — consensus is not a verdict; needs human review
Analysis details — impact, health, verification
Impact & health
Graphify review
Impact — 2332 functions depend on the 661 functions this change touches.
Health — this change adds coupling hotspots:
- new:
extract()— 484 callers, 42 callees - new:
_rebuild_code()— 98 callers, 50 callees - new:
detect()— 108 callers, 15 callees - new:
save_manifest()— 39 callers, 11 callees - new:
extract_files_direct()— 17 callers, 20 callees - new:
extract_xaml()— 19 callers, 17 callees - new:
extract_corpus_parallel()— 26 callers, 11 callees - new:
extract_js()— 80 callers, 3 callees - …and 37 more — each is listed as a finding
Verification — 2332 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: 2137 function(s) in the blast radius were not formally verified this run
Formal verification
Could not verify: Could not verify extract.
The verifier did not have enough to check extract, 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: parameter `cache_root` is annotated `Path | None` — outside the synthesizable primitive/collection set
· 45 more finding(s) on lines outside this diff (see the check run).
There was a problem hiding this comment.
Graphify reviewed this change.
Worth a look — the grounded gate found no coupling regressions or blocking issues, but 3 advisory finding(s) below merit a look before merge.
Formal verification. No changes could be formally verified in this run.
Graphify review — findings
Adds Business Central AL (.al) extraction as the 38th tree-sitter grammar, introducing graphify/al_resolution.py with an _ALSymbolResolver that maps object/member facts and resolves cross-file references (calls, events, extensions, app dependencies, TestPage/handler bindings) case-insensitively. Registers the optional [al] extra with a structural object/procedure/trigger fallback for Python versions without the Tree-sitter grammar, including UTF-8 BOM handling. Updates README extension tables and adds the 0.9.48 changelog entry.
Worth a look
- Malformed non-object app.json crashes AL resolution —
graphify/al_resolution.py:52· Escalate · medium- agreed by 2 of 2 members but NOT verified (no proof, no reproducing execution) — consensus is not a verdict; needs human review
- Fallback AL object regex omits permissionset objects —
graphify/extractors/al.py:11· Escalate · medium- agreed by 2 of 2 members but NOT verified (no proof, no reproducing execution) — consensus is not a verdict; needs human review
- _matching_brace ignores masking and counts braces inside strings/comments —
graphify/extractors/al.py:128· Escalate · medium- agreed by 2 of 2 members but NOT verified (no proof, no reproducing execution) — consensus is not a verdict; needs human review
Analysis details — impact, health, verification
Impact & health
Graphify review
Impact — 2333 functions depend on the 662 functions this change touches.
Health — this change adds coupling hotspots:
- new:
extract()— 484 callers, 42 callees - new:
_rebuild_code()— 98 callers, 50 callees - new:
detect()— 108 callers, 15 callees - new:
save_manifest()— 39 callers, 11 callees - new:
extract_files_direct()— 17 callers, 20 callees - new:
extract_xaml()— 19 callers, 17 callees - new:
extract_corpus_parallel()— 26 callers, 11 callees - new:
extract_js()— 80 callers, 3 callees - …and 37 more — each is listed as a finding
Verification — 2333 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: 2138 function(s) in the blast radius were not formally verified this run
Formal verification
Could not verify: Could not verify extract.
The verifier did not have enough to check extract, 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: parameter `cache_root` is annotated `Path | None` — outside the synthesizable primitive/collection set
· 45 more finding(s) on lines outside this diff (see the check run).
There was a problem hiding this comment.
Graphify reviewed this change.
Worth a look — the grounded gate found no coupling regressions or blocking issues, but 2 advisory finding(s) below merit a look before merge.
Formal verification. No changes could be formally verified in this run.
Graphify review — findings
Adds Business Central AL (.al) extraction as a new tree-sitter grammar with an optional [al] extra, wiring it into graphify.detect (filetype detection, office/import paths) and the extractor registry, with a structural object/procedure/trigger fallback on Python versions lacking the Tree-sitter parser. Introduces graphify/al_resolution.py (_ALSymbolResolver) for application-level, case-insensitive cross-file symbol resolution — objects, members, extensions, typed calls, event subscriptions, TestPage/handler bindings, and app.json dependency edges. Documents the new grammar and extra in README/CHANGELOG and adds AL extraction tests.
Worth a look
- extract_al returns an error instead of falling back when the installed AL parser fails —
graphify/extractors/al.py· Escalate · medium- agreed by 2 of 2 members but NOT verified (no proof, no reproducing execution) — consensus is not a verdict; needs human review
- Valid AL permission set extensions are not recognized —
graphify/extractors/al.py:10· Escalate · medium- agreed by 2 of 2 members but NOT verified (no proof, no reproducing execution) — consensus is not a verdict; needs human review
Analysis details — impact, health, verification
Impact & health
Graphify review
Impact — 2339 functions depend on the 668 functions this change touches.
Health — this change adds coupling hotspots:
- new:
extract()— 485 callers, 42 callees - new:
_rebuild_code()— 98 callers, 50 callees - new:
detect()— 108 callers, 15 callees - new:
save_manifest()— 39 callers, 11 callees - new:
extract_files_direct()— 17 callers, 20 callees - new:
extract_xaml()— 19 callers, 17 callees - new:
extract_corpus_parallel()— 26 callers, 11 callees - new:
extract_js()— 80 callers, 3 callees - …and 37 more — each is listed as a finding
Verification — 2339 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: 2144 function(s) in the blast radius were not formally verified this run
Formal verification
Could not verify: Could not verify extract.
The verifier did not have enough to check extract, 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: parameter `cache_root` is annotated `Path | None` — outside the synthesizable primitive/collection set
· 45 more finding(s) on lines outside this diff (see the check run).
There was a problem hiding this comment.
Graphify reviewed this change.
Worth a look — the grounded gate found no coupling regressions or blocking issues, but 2 advisory finding(s) below merit a look before merge.
Formal verification. No changes could be formally verified in this run.
Graphify review — findings
Adds Business Central AL (.al) as a supported language, with full Tree-sitter extraction via the optional [al] extra and a structural fallback extractor for other Python versions. Introduces graphify/al_resolution.py for application-level, case-insensitive cross-file symbol resolution (objects, members/overloads, extensions, app-manifest dependencies) and adds AL extractor/resolver tests. Updates README (grammar count 37→38, extras table, extension list) and the CHANGELOG.
Worth a look
- Fallback flag overwritten across files of same extension —
graphify/extract.py:5704· Escalate · medium- agreed by 2 of 2 members but NOT verified (no proof, no reproducing execution) — consensus is not a verdict; needs human review
- Drops all but the first interface in implements clauses —
graphify/extractors/al.py:323· Escalate · medium- agreed by 2 of 2 members but NOT verified (no proof, no reproducing execution) — consensus is not a verdict; needs human review
Analysis details — impact, health, verification
Impact & health
Graphify review
Impact — 2342 functions depend on the 671 functions this change touches.
Health — this change adds coupling hotspots:
- new:
extract()— 485 callers, 42 callees - new:
_rebuild_code()— 98 callers, 50 callees - new:
detect()— 108 callers, 15 callees - new:
save_manifest()— 39 callers, 11 callees - new:
extract_files_direct()— 17 callers, 20 callees - new:
extract_xaml()— 19 callers, 17 callees - new:
extract_corpus_parallel()— 26 callers, 11 callees - new:
extract_js()— 80 callers, 3 callees - …and 37 more — each is listed as a finding
Verification — 2342 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: 2147 function(s) in the blast radius were not formally verified this run
Formal verification
Could not verify: Could not verify extract.
The verifier did not have enough to check extract, 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: parameter `cache_root` is annotated `Path | None` — outside the synthesizable primitive/collection set
· 45 more finding(s) on lines outside this diff (see the check run).
There was a problem hiding this comment.
Graphify reviewed this change.
Worth a look — the grounded gate found no coupling regressions or blocking issues, but 2 advisory finding(s) below merit a look before merge.
Formal verification. No changes could be formally verified in this run.
Graphify review — findings
Adds Microsoft Dynamics 365 Business Central AL (.al) extraction with a new al_resolution.py application-level resolver and al extractor covering objects, permission sets, extensions, procedures/overloads, triggers, fields, enums, interfaces, typed calls, event subscriptions, app dependencies, and TestPage/handler bindings. Registers the optional [al] extra (full Tree-sitter on Python 3.12+, structural fallback otherwise) and wires app.json manifest resolution with case-insensitive cross-file matching. Updates the README grammar count to 38, adds the extension/extra rows, and adds a 0.9.48 CHANGELOG entry.
Worth a look
- Comment masking starts inside quoted AL identifiers —
graphify/extractors/al.py:65· Escalate · medium- agreed by 2 of 2 members but NOT verified (no proof, no reproducing execution) — consensus is not a verdict; needs human review
- Optional tree_sitter dependency is required by fallback test —
tests/test_al.py:127· Escalate · medium- agreed by 2 of 2 members but NOT verified (no proof, no reproducing execution) — consensus is not a verdict; needs human review
Analysis details — impact, health, verification
Impact & health
Graphify review
Impact — 2564 functions depend on the 1033 functions this change touches.
Health — this change adds coupling hotspots:
- new:
extract()— 487 callers, 42 callees - new:
_rebuild_code()— 98 callers, 50 callees - new:
detect()— 108 callers, 15 callees - new:
save_manifest()— 39 callers, 11 callees - new:
extract_files_direct()— 17 callers, 20 callees - new:
extract_xaml()— 19 callers, 17 callees - new:
extract_corpus_parallel()— 26 callers, 11 callees - new:
extract_js()— 80 callers, 3 callees - …and 37 more — each is listed as a finding
Verification — 2564 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: 2369 function(s) in the blast radius were not formally verified this run
Formal verification
Could not verify: Could not verify extract.
The verifier did not have enough to check extract, 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: parameter `cache_root` is annotated `Path | None` — outside the synthesizable primitive/collection set
· 45 more finding(s) on lines outside this diff (see the check run).
There was a problem hiding this comment.
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
Adds first-class Business Central AL (.al) extraction: a new graphify/al_resolution.py with _ALSymbolResolver for application-level, case-insensitive cross-file symbol resolution (objects, members, app.json manifest dependencies), plus AL extractor internals (altreecontext, al_extract_member, mask_al_code) and the [al] optional extra with a Tree-sitter path on Python 3.12+ and a structural fallback elsewhere. Registers .al in the supported-language surface (README extension table now 38 grammars, environment-variable/extras docs) and adds the 0.9.48 changelog entry. Includes extensive AL parser and extraction tests covering fallback specs, optional-extra reporting, case-insensitive detection, and calls/handler edges.
No blocking issues surfaced. 21 lower-confidence candidates did not survive cross-model review.
Analysis details — impact, health, verification
Impact & health
Graphify review
Impact — 2567 functions depend on the 1036 functions this change touches.
Health — this change adds coupling hotspots:
- new:
extract()— 487 callers, 42 callees - new:
_rebuild_code()— 98 callers, 50 callees - new:
detect()— 108 callers, 15 callees - new:
save_manifest()— 39 callers, 11 callees - new:
extract_files_direct()— 17 callers, 20 callees - new:
extract_xaml()— 19 callers, 17 callees - new:
extract_corpus_parallel()— 26 callers, 11 callees - new:
extract_js()— 80 callers, 3 callees - …and 37 more — each is listed as a finding
Verification — 2567 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: 2372 function(s) in the blast radius were not formally verified this run
Formal verification
Could not verify: Could not verify extract.
The verifier did not have enough to check extract, 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: parameter `cache_root` is annotated `Path | None` — outside the synthesizable primitive/collection set
· 45 more finding(s) on lines outside this diff (see the check run).
There was a problem hiding this comment.
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
Adds a Business Central AL (.al) extractor with full Tree-sitter extraction under the optional [al] extra on Python 3.12+ and a structural object/procedure/trigger fallback otherwise, plus the new graphify/al_resolution.py for case-insensitive application-level symbol resolution (objects, members, extensions, ControlAddIns, event bindings, and app-manifest dependencies). Registers .al as the 38th grammar and documents the extra in the README and CHANGELOG. Includes extensive tests covering fallback paths, namespace/manifest resolution, and test-dispatch handling.
No blocking issues surfaced. 22 lower-confidence candidates did not survive cross-model review.
Analysis details — impact, health, verification
Impact & health
Graphify review
Impact — 2572 functions depend on the 1041 functions this change touches.
Health — this change adds coupling hotspots:
- new:
extract()— 488 callers, 42 callees - new:
_rebuild_code()— 98 callers, 50 callees - new:
detect()— 108 callers, 15 callees - new:
save_manifest()— 39 callers, 11 callees - new:
extract_files_direct()— 17 callers, 20 callees - new:
extract_xaml()— 19 callers, 17 callees - new:
extract_corpus_parallel()— 26 callers, 11 callees - new:
extract_js()— 80 callers, 3 callees - …and 39 more — each is listed as a finding
Verification — 2572 functions in the blast radius were not formally verified this run (proofs are advisory here).
Health delta baseline: last indexed commit 282976b (diverged from this PR's base — delta is approximate).
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: 2377 function(s) in the blast radius were not formally verified this run
Formal verification
Could not verify: Could not verify extract.
The verifier did not have enough to check extract, 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: parameter `cache_root` is annotated `Path | None` — outside the synthesizable primitive/collection set
· 2 grounded finding(s) anchored inline below; 45 more finding(s) on lines outside this diff (see the check run).
There was a problem hiding this comment.
Graphify reviewed this change.
Worth a look — the grounded gate found no coupling regressions or blocking issues, but 1 advisory finding(s) below merit a look before merge.
Formal verification. No changes could be formally verified in this run.
Graphify review — findings
Adds Microsoft Dynamics 365 Business Central AL (.al) extraction as the 38th tree-sitter grammar behind an optional [al] extra, modeling objects, permission sets/extensions, ControlAddIns and UserControls, procedures/overloads, scoped triggers, fields, enums, typed calls, event bindings/subscriptions, app dependencies, and test-app relationships via _ALSymbolResolver with case-insensitive cross-file resolution. Falls back to structural object/procedure/trigger extraction through ALFallbackExtractor when the Tree-sitter grammar is unavailable (non-3.12+ or extra not installed). Wires .al into detection via is_graphable_source and friends and updates the README/CHANGELOG accordingly.
Worth a look
- Missing-parser diagnostic test expects misspelled package extra —
tests/test_al.py:94· Escalate · medium- agreed by 2 of 2 members but NOT verified (no proof, no reproducing execution) — consensus is not a verdict; needs human review
Analysis details — impact, health, verification
Impact & health
Graphify review
Impact — 2576 functions depend on the 1045 functions this change touches.
Health — this change adds coupling hotspots:
- new:
extract()— 488 callers, 42 callees - new:
_rebuild_code()— 98 callers, 50 callees - new:
detect()— 108 callers, 15 callees - new:
save_manifest()— 39 callers, 11 callees - new:
extract_files_direct()— 17 callers, 20 callees - new:
extract_xaml()— 19 callers, 17 callees - new:
extract_corpus_parallel()— 26 callers, 11 callees - new:
extract_js()— 80 callers, 3 callees - …and 37 more — each is listed as a finding
Verification — 2576 functions in the blast radius were not formally verified this run (proofs are advisory here).
Health delta baseline: last indexed commit 282976b (diverged from this PR's base — delta is approximate).
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: 2381 function(s) in the blast radius were not formally verified this run
Formal verification
Could not verify: Could not verify extract.
The verifier did not have enough to check extract, 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: parameter `cache_root` is annotated `Path | None` — outside the synthesizable primitive/collection set
· 45 more finding(s) on lines outside this diff (see the check run).
There was a problem hiding this comment.
Graphify reviewed this change.
Worth a look — the grounded gate found no coupling regressions or blocking issues, but 3 advisory finding(s) below merit a look before merge.
Formal verification. No changes could be formally verified in this run.
Graphify review — findings
Adds full Business Central AL (.al) support as the 38th tree-sitter grammar, with a new al optional extra and ALFallbackExtractor that provides structural object/procedure/trigger extraction when Tree-sitter isn't available (Python < 3.12 or extra not installed). Extracts and emits application objects, permission sets/extensions, ControlAddIns, UserControls, procedures/overloads, scoped triggers, fields, enum values, interfaces, typed calls, event bindings/subscriptions, and TestPage/handler relationships, then resolves them across files case-insensitively via _ALSymbolResolver, using app.json manifests for application identity and dependency edges. Member resolution requires a unique candidate (_unique_member_id) matched by parent, signature, and source location, so ambiguous string ids or duplicated members are left unlinked rather than guessed.
Worth a look
- AL resolution is order-dependent across files —
graphify/al_resolution.py· Escalate · medium- agreed by 2 of 2 members but NOT verified (no proof, no reproducing execution) — consensus is not a verdict; needs human review
- Dependency warning is ignored when an extractor also reports an error —
graphify/extract.py:5696· Escalate · medium- agreed by 2 of 2 members but NOT verified (no proof, no reproducing execution) — consensus is not a verdict; needs human review
- Quoted-identifier masking corrupts identifier characters via wrong handler dispatch —
graphify/extractors/al.py:60· Escalate · medium- agreed by 2 of 2 members but NOT verified (no proof, no reproducing execution) — consensus is not a verdict; needs human review
Analysis details — impact, health, verification
Impact & health
Graphify review
Impact — 2576 functions depend on the 1045 functions this change touches.
Health — this change adds coupling hotspots:
- new:
extract()— 488 callers, 42 callees - new:
_rebuild_code()— 98 callers, 50 callees - new:
detect()— 108 callers, 15 callees - new:
save_manifest()— 39 callers, 11 callees - new:
extract_files_direct()— 17 callers, 20 callees - new:
extract_xaml()— 19 callers, 17 callees - new:
extract_corpus_parallel()— 26 callers, 11 callees - new:
extract_js()— 80 callers, 3 callees - …and 37 more — each is listed as a finding
Verification — 2576 functions in the blast radius were not formally verified this run (proofs are advisory here).
Health delta baseline: last indexed commit 282976b (diverged from this PR's base — delta is approximate).
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: 2381 function(s) in the blast radius were not formally verified this run
Formal verification
Could not verify: Could not verify extract.
The verifier did not have enough to check extract, 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: parameter `cache_root` is annotated `Path | None` — outside the synthesizable primitive/collection set
· 45 more finding(s) on lines outside this diff (see the check run).
There was a problem hiding this comment.
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
Adds Business Central AL as a first-class language: .al files now extract application objects, permission sets/extensions, ControlAddIns and hosted UserControls, procedures/overloads, scoped triggers, fields, enums, interfaces, and their typed calls, event bindings/subscriptions, app dependencies, and test-app relationships, with case-insensitive cross-file resolution via _ALSymbolResolver. Wires up manifest-aware application context by walking app.json up the tree to attach app ids/names and emit dependency edges. Full Tree-sitter extraction requires the optional [al] extra on Python 3.12+; other versions fall back to structural object/procedure/trigger extraction.
No blocking issues surfaced. 11 lower-confidence candidates did not survive cross-model review.
Analysis details — impact, health, verification
Impact & health
Graphify review
Impact — 2579 functions depend on the 1048 functions this change touches.
Health — this change adds coupling hotspots:
- new:
extract()— 490 callers, 42 callees - new:
_rebuild_code()— 98 callers, 50 callees - new:
detect()— 108 callers, 15 callees - new:
save_manifest()— 39 callers, 11 callees - new:
extract_files_direct()— 17 callers, 20 callees - new:
extract_xaml()— 19 callers, 17 callees - new:
extract_corpus_parallel()— 26 callers, 11 callees - new:
extract_js()— 80 callers, 3 callees - …and 37 more — each is listed as a finding
Verification — 2579 functions in the blast radius were not formally verified this run (proofs are advisory here).
Health delta baseline: last indexed commit 282976b (diverged from this PR's base — delta is approximate).
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: 2384 function(s) in the blast radius were not formally verified this run
Formal verification
Could not verify: Could not verify extract.
The verifier did not have enough to check extract, 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: parameter `cache_root` is annotated `Path | None` — outside the synthesizable primitive/collection set
· 45 more finding(s) on lines outside this diff (see the check run).
feat: add AL (.al) language support
What
Adds extraction support for Microsoft Dynamics 365 Business Central AL (
.al) source files, including production applications and dedicated AL test applications.On Python 3.12+, the optional
tree-sitter-alparser provides full structural and semantic extraction. On other supported Python versions, or when the parser is absent, graphify falls back to a built-in structural scanner for files, application objects, procedures, and triggers.Why
Business Central extensions are currently invisible to graphify because
.alis not treated as source code. This PR makes AL a first-class language while preserving graphify's Python 3.10+ compatibility and offline extraction behavior.What it extracts
OnValidaterepeatusingdeclarations, attributes, and visibilityapp.jsonapplication dependenciesHandlerFunctionsbindings in AL test appsTest application semantics
TestPage "X"declarations resolve to visible production page objects throughreferencesedges withtest_targetcontext.[HandlerFunctions('X')]entries resolve to unique procedures in the same test codeunit throughreferencesedges withtest_handlercontext.OpenView,SetValue,Invoke, andAssertEqualsare not fabricated as calls to undeclared production procedures.[Test], handler, and event attributes.Details
casefold().app.jsonmetadata for application and dependency boundaries without requiring a valid manifest.Validation corpora
AcmeComments
Tested against the 11-file Business Central extension:
InterestMgt and InterestMgtTest
Tested against both applications together:
OpenInterestCalculatoroverloads preserved; the one-argument call resolves correctlyChanges
graphify/extractors/al.py- dedicated Tree-sitter and fallback AL extractor, permission sets, scoped members, overload identities, and test factsgraphify/al_resolution.py- ambiguity-safe cross-file, test target, handler, overload, and application dependency resolutiongraphify/detect.py/graphify/extract.py-.aldetection, dispatch, diagnostics, and resolver registrationpyproject.toml/uv.lock- optional[al]extra usingtree-sitter-alon Python 3.12+tests/test_al.py/ AL fixtures - focused extraction, fallback, diagnostics, resolution, test-app, and overload coverageREADME.md/CHANGELOG.md- language support and installation documentationTests
uv run pytest tests/test_al.py -q- 17 passeduv run pytest tests/test_detect.py -q- 243 passed, 11 skippeduv run ruff check graphify/extractors/al.py graphify/al_resolution.py tests/test_al.pyNotes / possible follow-ups
.apppackage binary parsing remains intentionally out of scope.