Skip to content

feat: make analysis artifacts self-describing with source and invocation provenance #63

Description

@rahlk

Problem

A canonical analysis.json cannot currently establish how or from what source state it was produced. The audited v1 artifact has only:

  • symbol_table
  • call_graph
  • external_symbols
  • synthesized_callables

It does not record the schema version, repository/source revision, analyzer invocation options, call-graph provider, analysis level, test/scope policy, dependency-materialization degradation, or generation identity. A companion cache happens to contain an analyzer version, but the canonical artifact must stand alone and the cache is not a report contract.

Issue #29 adds analyzer {name, version} to the v2 JSON envelope, and #43 aligns Neo4j analyzer identity. This issue covers the remaining source/invocation provenance needed to reproduce and interpret an analysis.

Why this matters

The same repository can produce materially different graphs depending on:

  • -a/--analysis-level;
  • --tsc-only / Jelly / union provider selection;
  • --skip-tests versus --include-tests;
  • --no-phantoms;
  • target-file mode;
  • dependency materialization success/degraded mode;
  • compiler config/project selection;
  • source commit and dirty state.

Without these fields, consumers cannot distinguish a complete level-2 union graph from a partial/degraded or differently scoped artifact. Audits also cannot tie stored hashes back to a repository revision without out-of-band information.

Expected behavior

JSON and Neo4j outputs should carry a portable, stable manifest describing analyzer identity, source identity when available, and all graph-shaping options.

Acceptance criteria

Extend the v2 envelope (or define a sidecar contract used by both projections) with at least:

  • schema_version;
  • analyzer: { name, version } from feat: analyzer{name,version} schema envelope #29;
  • source identity when input is a Git checkout: commit SHA, dirty flag, and optionally a normalized remote/repository name;
  • graph-shaping options: analysis level, provider, test inclusion policy, phantom policy, target-file scope, and selected compiler config(s);
  • materialization/degraded status and non-secret notes;
  • application/logical name used by Neo4j.

Constraints:

  • never serialize credentials or secret-bearing clone URLs;
  • avoid absolute checkout paths (see fix: emit project-relative callable paths for portable deterministic artifacts #61);
  • preserve deterministic artifacts: omit wall-clock timestamps or clearly isolate them from canonical hashing;
  • represent non-Git source trees without failure (source.revision = null plus content identity/counts);
  • emit equivalent provenance on the Neo4j :Application node;
  • add tests for Git, dirty Git, and non-Git inputs and for secret redaction.

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementNew feature or requestfeatureNew feature or capability

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions