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

    Fields

    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions