Skip to content

Repository-artifact layer: artifacts, dependencies, config keys (python parity) #101

Open

Description

@rahlk

Is your feature request related to a problem? Please describe.

Schema v2 is code-only: nothing represents package.json manifests, lockfiles, tsconfig/rc configs, Dockerfiles, CI workflows, or the dependencies an app declares. Python shipped the three-family answer (artifact / dependency / config_key contained under the application node, ungated at every level); TS emits none of it, so cross-analyzer artifact queries dead-end at this repo.

Describe the solution you'd like

  • Model: TSArtifact / TSDependency / TSConfigKey mirroring python's shipped shapes field-for-field; application.artifacts{} with contained children; ids stamped per-run by assignIds (@artifact/ marker)
  • src/artifacts/ — walk (SKIP_DIRS, sorted) + rules table → artifact_kind/format; sha256 + size always; text capture under --artifact-text-max-bytes (256 KiB default, truncate+flag)
  • deps extraction: every package.json (workspaces included) → declared records with scope mapping incl. the coined additive peer token; JSON lockfile family (package-lock / npm-shrinkwrap / bun.lock) backfills resolved_version on declared records only
  • config extraction: .env-family flat keys (namespace "env") + JSON dotted keys
  • Neo4j 2.2.0: :TSArtifact/:TSDependency/:TSConfigKey + TS_HAS_ARTIFACT/TS_DECLARES_DEPENDENCY/TS_DEFINES_CONFIG + constraints; schema.neo4j.json regen
  • Wire gate: artifact content_hash MUST appear on the wire — restructure the internal-field strip so the module-cache trio's key names don't eat artifact fields
  • Fixture app covering every format + level-invariance, conformance, determinism, Neo4j row tests; python-sdk TS-model extras-tolerance verified

Describe alternatives you've considered

Not stated in the original issue.

Additional context

Plan

docs/design/specs/artifacts-and-dependencies.md (committed on the work branch). Parity anchor: codeanalyzer-python's SHIPPED layer (51ee29e) — implementation over draft where they differ.

Scope boundary

Additive only: no existing field, id tier, or level moves; schema_version stays put (python precedent), Neo4j contract bumps additively to 2.2.0. NOT in scope: import→package binding / unresolved_imports / purl (not in python's shipped unit), transitive lockfile records (direct:false reserved), YAML parsing (yarn.lock/pnpm-lock/yaml configs are inventory-only artifacts), caching of the scan.

Caveats and known risks

  • The strip-filter collision (module content_hash internal vs artifact content_hash wire) is called out in the spec — key-name stripping must become structural or scoped.
  • TSArtifact.source = producing subsystem (python's field), colliding in NAME with module.source semantics — inherited parity, documented, not "fixed".
  • One shared-vocabulary token coined: dependency scope peer — recorded in the spec + SCHEMA_DECISIONS; python's Literal grows when next touched.
  • yarn.lock / pnpm-lock.yaml ship as artifacts WITHOUT resolved_version — absence is the documented signal, not a parse failure.

Definition of done

Spec's DoD verbatim: identical artifacts at all levels; fixture asserts every format + peer scope + wire content_hash; Neo4j 2.2.0 rows + regen; two-run byte-identical determinism; suite/typecheck green; CLAUDE.md + SCHEMA_DECISIONS + README/--help updated.

Activity

  1. rahlk commented on Aug 30, 2026

    @rahlk
    ContributorAuthor

    The python train is complete and released (codeanalyzer-python 1.3.0, 2026-08-29): artifacts + dependencies (#157/#160), ConfigKey family (#152/#163), the level-graded config_use edge (#162/#164), and deployment-env namespaces (#165/#168). The epic (codellm-devkit/.github#45) now carries a "Contract as shipped" section — where this issue's original text follows the epic's older sketch, the shipped contract supersedes it. The load-bearing deltas:

    • No language-prefixed nouns: graph labels are neutral Artifact / Package / ConfigKey (shared MERGE targets across analyzers) — not JArtifact/TSArtifact-style triplets. Language-specific edges keep the prefix: your *_PROVIDES, *_UNRESOLVED_IMPORT, *_USES_CONFIG.
    • Ids: can://artifact/<app>/<path> (neutral namespace); packages by purl (pkg:maven/… / pkg:npm/…); config keys <artifact-id>@key/<dotted.key>. --app-name agreement is the join precondition.
    • Placement: application.artifacts sibling map, config keys nested per artifact; the code tree stays code-only.
    • Classification: open roles: string[] (never-drop inventory: unmatched decodable → unknown, binaries hash-only), not a closed artifact_kind enum.
    • Dependency record: kind {runtime, dev, optional, build}, prov {declared, lockfile, installed-metadata, heuristic}, direct: false for lockfile-only transitives, locked_version.
    • Text policy: capture-on default, 256 KiB cap, --artifact-text/--no-artifact-text, --artifact-text-max-bytes; extraction parses full on-disk text, never the stored copy.
    • config_use: literal tier at the call-graph level, dataflow tiers over your own def-use substrate, unresolved reads first-class with reasons; deployment-env sources (Dockerfile ENV, compose/k8s env) mint bindable env keys, Dockerfile ARG a non-bindable dockerfile namespace.
    • Neo4j SCHEMA_VERSION stays 2.0.0 until the layer settles across all analyzers.

    Copy-from reference: the three specs in codeanalyzer-python docs/design/specs/ (2026-08-27 artifacts, 2026-08-28 config-key family, 2026-08-28 config-use edge) and the v1.3.0 release assets — schema.json + schema.cypher are the machine-readable contract; analyzing-canpy-graphs-skill.tar.gz documents the query surface the layer should support.

    Your plan already anchors on the shipped python layer (51ee29e) — note the anchor has since moved: 1.3.0 additionally landed the level-graded config_use tiers, deployment-env namespaces, direct: false transitives, and the text-capture controls, so re-sync the parity anchor to the v1.3.0 tag rather than that commit. TS-specific: package.json dev/peer/optional map onto kind {dev, optional}; purl pkg:npm/<name>; tsconfig JSONC tolerance is your analogue of our overlay posture (parse failure → artifact kept, extraction: "partial").

  2. 5 remaining items

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions