You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Is your feature request related to a problem? Please describe.
discover_artifacts classifies files against RULES (codeanalyzer/artifacts/discovery.py:13-60) into an open, kebab-case role set — dependency-manifest, tool-config, container-image, service-topology, iac, ci, env, packaging, legal, docs, script, unknown. There is no presentation-layer role. A Jinja2 template, a Django template, and everything under static/ all land as format="text", roles=["unknown"] — indistinguishable from a file the analyzer has never heard of.
Consequences today: a graph consumer cannot ask "which templates does this application ship", the artifact inventory reports an application's whole view layer as unknown, and unknown stops being a useful signal — it means both "not classified" and "classified as a thing we have no name for".
codeanalyzer-java is adding view-template artifact roles (.jsp, .xhtml, Thymeleaf .html) and a bundler-output inventory (static/, dist/) as part of its web-application theme. The roles vocabulary is shared and open across all three analyzers, and no analyzer has coined a template role yet (python: 44 rules, none; codeanalyzer-typescript rules.ts: none). Whoever lands first fixes the spelling for everyone — a term coined twice is permanently wrong.
So this issue exists to hold the python end of that thread, not to race it.
Describe the solution you'd like
A presentation-layer role value exists in the shared vocabulary, spelled identically in all three analyzers.
Python's Jinja2 / Django templates and static output carry it instead of ["unknown"].
format values for template files are added alongside, so a consumer can tell a JSP from a Jinja2 file without pattern-matching the path.
Describe alternatives you've considered
Not stated in the original issue.
Additional context
Scope boundary
In scope: adopting the role and format values java coins, and adding the RULES entries that classify python's equivalents — Jinja2 (templates/**.html, *.jinja, *.j2), Django templates, and bundler/static output.
Out of scope: parsing template internals ({{ }}, {% %}) into nodes, template↔code dataflow, and view-dispatch edges from render_template / render / TemplateResponse to the template artifact. Those are separate decisions on the same theme and each is larger than this one.
Blocked on codeanalyzer-java for the names only. Nothing else about it is blocked.
The naming input python owes java
view-template over bare template.template already means Helm chart templates and cookiecutter scaffolding in this ecosystem, and values.yaml / Chart.yaml are already service-topology here. view-template is unambiguous and reads correctly for JSP, Thymeleaf, Jinja2, and .ejs/.hbs/.vue on the TypeScript side.
format is a separate axis from roles.Artifact carries both (codeanalyzer/neo4j/schema.py, :Artifact props), so .jsp / .xhtml / .html are new format values and one new role — not one conflated string.
Bundler output needs its own role, not the template one. A minified dist/app.js is not a view template; it is a shipped asset. Whatever java picks for row 6 of its table should be a sibling value, and python wants the same one for static/.
Caveats and known risks
Template discovery in python is convention, not declaration: Flask's default is templates/, Django's is per-app templates/ plus DIRS in settings, and both are configurable. RULES is glob-based, so the rule will over- and under-match; that is acceptable for a role hint and must not be presented as authoritative.
templates/**.html and a plain docs/*.html are the same extension. Ordering inside RULES decides which wins, and the existing table already relies on that (the generic *.ini fallback sits after tox.ini on purpose).
roles is a list, so a file can be both — no need to force a single winner where view-template and something else genuinely both apply.
Is your feature request related to a problem? Please describe.
discover_artifactsclassifies files againstRULES(codeanalyzer/artifacts/discovery.py:13-60) into an open, kebab-case role set —dependency-manifest,tool-config,container-image,service-topology,iac,ci,env,packaging,legal,docs,script,unknown. There is no presentation-layer role. A Jinja2 template, a Django template, and everything understatic/all land asformat="text",roles=["unknown"]— indistinguishable from a file the analyzer has never heard of.Consequences today: a graph consumer cannot ask "which templates does this application ship", the artifact inventory reports an application's whole view layer as unknown, and
unknownstops being a useful signal — it means both "not classified" and "classified as a thing we have no name for".codeanalyzer-java is adding view-template artifact roles (
.jsp,.xhtml, Thymeleaf.html) and a bundler-output inventory (static/,dist/) as part of its web-application theme. The roles vocabulary is shared and open across all three analyzers, and no analyzer has coined a template role yet (python: 44 rules, none; codeanalyzer-typescriptrules.ts: none). Whoever lands first fixes the spelling for everyone — a term coined twice is permanently wrong.So this issue exists to hold the python end of that thread, not to race it.
Describe the solution you'd like
["unknown"].formatvalues for template files are added alongside, so a consumer can tell a JSP from a Jinja2 file without pattern-matching the path.Describe alternatives you've considered
Not stated in the original issue.
Additional context
Scope boundary
In scope: adopting the role and
formatvalues java coins, and adding theRULESentries that classify python's equivalents — Jinja2 (templates/**.html,*.jinja,*.j2), Django templates, and bundler/static output.Out of scope: parsing template internals (
{{ }},{% %}) into nodes, template↔code dataflow, and view-dispatch edges fromrender_template/render/TemplateResponseto the template artifact. Those are separate decisions on the same theme and each is larger than this one.Blocked on codeanalyzer-java for the names only. Nothing else about it is blocked.
The naming input python owes java
view-templateover baretemplate.templatealready means Helm chart templates and cookiecutter scaffolding in this ecosystem, andvalues.yaml/Chart.yamlare alreadyservice-topologyhere.view-templateis unambiguous and reads correctly for JSP, Thymeleaf, Jinja2, and.ejs/.hbs/.vueon the TypeScript side.formatis a separate axis fromroles.Artifactcarries both (codeanalyzer/neo4j/schema.py,:Artifactprops), so.jsp/.xhtml/.htmlare newformatvalues and one new role — not one conflated string.dist/app.jsis not a view template; it is a shipped asset. Whatever java picks for row 6 of its table should be a sibling value, and python wants the same one forstatic/.Caveats and known risks
templates/, Django's is per-apptemplates/plusDIRSin settings, and both are configurable.RULESis glob-based, so the rule will over- and under-match; that is acceptable for a role hint and must not be presented as authoritative.templates/**.htmland a plaindocs/*.htmlare the same extension. Ordering insideRULESdecides which wins, and the existing table already relies on that (the generic*.inifallback sits aftertox.inion purpose).rolesis a list, so a file can be both — no need to force a single winner whereview-templateand something else genuinely both apply..pyfile getsread_bytes()+ full-text capture indiscover_artifacts, so widening what counts as interesting has a memory cost on largestatic/trees. See The analyzer ingests its own output when -o sits inside -i, growing analysis.json exponentially #207 — the output-dir self-ingestion bug — which is the same code path and should land first.schema_versionand the graphSCHEMA_VERSIONstay2.0.0under the 2026-09-07 hold. Consumers gate on the analyzer version floor.Definition of done
formatspellings confirmed against codeanalyzer-java's landed work, cited by issue or PR number in this thread.RULESentries for Jinja2 / Django templates and for static/bundler output.templates/directory asserts the role and format on the emitted artifact, in both projections.unknownis no longer produced for those files.