# R1a: Current release artifact and delivery inventory

> **Status:** descriptive current-tree evidence for
> [NexusCRM#3624](https://github.com/pingcap-inc/NexusCRM/issues/3624), not a
> release design or release registry. This inventory does not define App
> semantics, evolve `PackManifest`, change a build/deploy workflow, publish an
> artifact, or approve a production migration.
>
> **Machine-readable companion:**
> [`release-artifact-delivery-inventory-r1a.json`](release-artifact-delivery-inventory-r1a.json).
> It prevents inventory omissions; it is explicitly non-authoritative and is
> not consumed by a build or deployment.
>
> **Audit-snapshot notice:** all `current_*` fields below mean current at the
> exact repository revisions in Section 1. After this audit, P1x advances the
> live NexusCRM root-contract pin from `v0.1.5` to `v0.1.7`. The JSON remains
> frozen evidence for `c9736c2da0e718980e7a8d8fe4d51a8b5133ace4`; live module
> ownership is `backend/go.mod`, not this R1a snapshot. R1b consumes the live
> owner rather than rewriting historical evidence.

## 1. Evidence boundary and method

The audit read the live commands, module manifests, Dockerfiles, build scripts,
workflows, pack manifests, lineage files, release tuple, deployment resolver,
environment configuration model, release-tag emitter, and production deploy
implementation at these exact revisions on 2026-07-13:

| Repository | Audited revision | Current release surface |
|---|---|---|
| `pingcap-inc/NexusCRM` | `c9736c2da0e718980e7a8d8fe4d51a8b5133ace4` | source commit, Go module closure, commands, Docker build definitions, frontend build |
| `pingcap-inc/nexuscrm-contract` | `917886fc6920e97f8ed93615629865a53cde8407` | root Go module `v0.1.7`; nested `wire-go/v0.1.1` |
| `pingcap-inc/nexuscrm-controlplane` | `2a760135ecc202c016ed9e3e2268357974cce65a` | latest audited tag `v0.1.20`; main is ahead of that tag |
| `pingcap-inc/nexuscrm-api-host` | `5930bcbb4bb46b709a69e1ce3a55372392834e31` | Go module `v0.4.0` |
| `pingcap-inc/nexuscrm-connectors` | `a4ff1938780b98b75ca6254e8bcef0c424ba5de9` | latest audited tag `v0.1.16`; main is ahead of that tag |
| `pingcap-inc/nexuscrm-app-packs` | `fc22e2049a41e5a1558ed07fdc1608d02439e9db` | untagged source commit, per-pack manifests, dialect modules, frontend source |
| `pingcap-inc/nexuscrm-pingcap-pack` | `330f27e7c3a96526e1d2eacc77bf5d86599cf9dc` | downstream source commit, overlay/final pack, lineage, staging release tags, deployment workflows |

The four L0 module release tags above are annotated Git tags; their peeled
commit identities are recorded in the JSON. `gh release list` returned no
GitHub Release objects for any of the seven repositories. Repository-wide
searches of build/release surfaces found no cosign, SLSA, SBOM, CycloneDX,
SPDX, syft, or GitHub artifact-attestation publication. This is a negative
current-tree finding, not a claim about artifacts held outside the repositories.

The L2 repository contains deployment-specific inputs. This public-core
inventory records input **names and ownership**, not tenant-specific values,
identifiers, endpoints, credentials, or payloads.

## 2. Executive result

The seven repository boundaries do not currently produce seven independently
deployable artifacts.

1. `nexuscrm-contract`, its nested `wire-go` module, `nexuscrm-controlplane`,
   `nexuscrm-api-host`, and `nexuscrm-connectors` are source-based Go module
   releases. NexusCRM pins their tags in `backend/go.mod` and
   `backend/distributions/go.mod`; the selected NexusCRM commit therefore
   implicitly closes over those L0 versions
   ([`backend/go.mod:14-18`](../../../backend/go.mod#L14-L18),
   [`backend/go.mod:118`](../../../backend/go.mod#L118),
   [`backend/distributions/go.mod:15-24`](../../../backend/distributions/go.mod#L15-L24),
   [`backend/distributions/go.mod:91`](../../../backend/distributions/go.mod#L91)).
2. NexusCRM defines CRM backend/setup binaries and independent Runtime API and
   worker images. CI builds and smokes them under runner-local tags; it does not
   push them or emit an immutable digest
   ([`go-ci.yml:529-557`](../../../.github/workflows/go-ci.yml#L529-L557)).
3. The production deployment audited here does not consume those Runtime
   images and does not promote a prebuilt CRM backend/frontend artifact. It
   resolves source commits, rebuilds the final pack and frontend on the target,
   and writes a runner whose final command is `go run`
   ([L2 `common.py:2716-2769`](https://github.com/pingcap-inc/nexuscrm-pingcap-pack/blob/330f27e7c3a96526e1d2eacc77bf5d86599cf9dc/deploy/online/runtime/common.py#L2716-L2769)).
4. The L1 app-packs repository publishes source commits, `pack.json` files,
   dialect Go source modules, and frontend source manifests. It has no tags,
   GitHub Releases, binary/image publication workflow, or production
   `AppService` command/image.
5. The L2 repository owns the current production release candidate: a staging
   release tag whose payload records resolved NexusCRM, app-packs and downstream
   commits plus final-pack evidence. Production accepts that tag, builds a
   version directory, and switches nginx/systemd pointers after verification
   ([L2 tag payload `emit_staging_release_tag.py:132-199`](https://github.com/pingcap-inc/nexuscrm-pingcap-pack/blob/330f27e7c3a96526e1d2eacc77bf5d86599cf9dc/deployments/offline/runtime/emit_staging_release_tag.py#L132-L199),
   [L2 production publish `deploy_multi_prod_env.py:1472-1504`](https://github.com/pingcap-inc/nexuscrm-pingcap-pack/blob/330f27e7c3a96526e1d2eacc77bf5d86599cf9dc/deploy/online/runtime/deploy_multi_prod_env.py#L1472-L1504)).
6. `release/release-tuple.json` is real reproducibility evidence, but it is not
   the sole production deployment authority. Release-class environments select
   companion refs from final-pack lineage and declare
   `verify_tuple_hash: false`
   ([L2 tuple `release-tuple.json:1-16`](https://github.com/pingcap-inc/nexuscrm-pingcap-pack/blob/330f27e7c3a96526e1d2eacc77bf5d86599cf9dc/release/release-tuple.json#L1-L16),
   [L2 production policy `deployment-config.json:270-295`](https://github.com/pingcap-inc/nexuscrm-pingcap-pack/blob/330f27e7c3a96526e1d2eacc77bf5d86599cf9dc/deployments/deployment-config.json#L270-L295)).

The current operational tuple is therefore a **source-and-lineage tuple**, not
an immutable artifact BOM.

## 3. Current release flow

```mermaid
flowchart TD
  C["contract tags\nroot + wire-go"] --> N["NexusCRM source commit\nGo module pins"]
  H["api-host tag"] --> N
  P["controlplane tag"] --> N
  X["connectors tag"] --> N
  A["app-packs source commit\nL1 pack + dialect + frontend source"] --> F["L2 final-pack builder"]
  D["L2 overlay source commit"] --> F
  N --> F
  F --> L["committed final pack\n.build-lineage.json + hash"]
  L --> S["staging build/verify"]
  S --> T["annotated staging release tag\nresolved refs + final-pack evidence"]
  T --> R["production target rebuild\nsetup apply + frontend build + go run"]
  R --> E["environment-local release directory\nrelease.json + current pointer"]

  N -. "CI local only" .-> RI["runtime-api / runtime-worker images"]
  A -. "no current artifact" .-> AS["optional L1 AppService: absent"]
  Q["release/release-tuple.json"] -. "gate/rebuild evidence, not prod SSoT" .-> L
```

### Owner/consumer boundaries

| Fact | Current owner | Current consumer/read path |
|---|---|---|
| L0 module version | owning L0 repository Git tag | NexusCRM `go.mod`; fetched by Go tooling |
| NexusCRM engine/host source version | NexusCRM Git commit | L2 final-pack lineage and release-tag payload |
| L1 pack source | app-packs Git commit + per-pack manifest | controlplane `official_repo:` source and L2 builder |
| L2 overlay/final composition | L2 Git commit + `stack.lock.json` + build scripts | final committed pack and deployment resolver |
| production candidate | L2 annotated staging release tag | production deploy workflow input `release_tag` |
| environment config | L2 deployment config + GitHub environment variables/secrets | selected environment deploy script |
| database convergence | selected setup/controlplane code + selected packs + optional patch bundle + existing DB stamps | `setup apply`/verify during deployment |

## 4. Release-shaped output inventory

### 4.1 L0 Go modules and generated wire

| Output | Owner / workflow | Identity and current consumption | Publication, integrity, rollback |
|---|---|---|---|
| Semantic contract module | `nexuscrm-contract`; `Contract` workflow only validates | audited tag `v0.1.7`; NexusCRM pins `v0.1.5` | annotated Git tag/Go source; consumer `go.sum`; rollback by repin/rebuild |
| Generated protobuf/wire module | `nexuscrm-contract/wire-go`; `Contract` workflow runs pinned generation/lint/breaking checks | audited and consumed `wire-go/v0.1.1` | generated files committed and tagged; no binary archive or attestation; rollback by repin/rebuild |
| Controlplane module | `nexuscrm-controlplane`; only Codex Review workflow is checked in | audited tag and NexusCRM pin `v0.1.20`; main is one commit ahead | annotated Git tag/Go source; no checked-in publisher; rollback code by repin, but applied DB state is forward state |
| API host module | `nexuscrm-api-host`; `go-ci` validates | audited and consumed `v0.4.0` | annotated Git tag/Go source; no checked-in publisher; rollback by repin/rebuild |
| Connectors module | `nexuscrm-connectors`; `go-ci` validates | audited tag and NexusCRM pin `v0.1.16`; main is ahead | annotated Git tag/Go source; no checked-in publisher; rollback by repin/rebuild |

Contract generation is reproducible in CI: pinned protobuf tools are installed,
`scripts/check.sh` runs lint/breaking/generated checks, and the nested module
owns protobuf/gRPC dependencies
([contract `contract.yml:11-38`](https://github.com/pingcap-inc/nexuscrm-contract/blob/917886fc6920e97f8ed93615629865a53cde8407/.github/workflows/contract.yml#L11-L38),
[contract `wire-go/go.mod:1-11`](https://github.com/pingcap-inc/nexuscrm-contract/blob/917886fc6920e97f8ed93615629865a53cde8407/wire-go/go.mod#L1-L11)).
That proves deterministic source generation, not release provenance.

NexusCRM's own engine modules are a single source-release closure. Local
composition uses `v0.0.0` plus local replacements, while external L0 modules
pin the same core modules through NexusCRM pseudo-versions. For example,
controlplane's current module maps its core dependencies to one NexusCRM commit
([controlplane `go.mod:101-131`](https://github.com/pingcap-inc/nexuscrm-controlplane/blob/2a760135ecc202c016ed9e3e2268357974cce65a/go.mod#L101-L131)).
Those pseudo-versions are build inputs, not independently approved service
releases.

### 4.2 Commands, binaries and images

| Output | Definition | Current publication / consumer | Pin and rollback |
|---|---|---|---|
| CRM server + setup binaries | NexusCRM `backend/cmd/*` and CRM distribution; `infra/backend.Dockerfile` | built into runner-local CI image; also rebuilt in L2 PR-UAT image | CI tag is mutable/local; no standalone digest |
| `runtime-api` binary/image | `backend/cmd/runtime-api`; `infra/runtime.Dockerfile` target | CI-local `nexuscrm-runtime-api-ci`; not pushed or consumed by audited production flow | image embeds `VERSION=$GITHUB_SHA`, but no registry digest exists |
| `runtime-worker` binary/image | `backend/cmd/runtime-worker`; `infra/runtime.Dockerfile` target | CI-local `nexuscrm-runtime-worker-ci`; not pushed or consumed by audited production flow | same as runtime-api |
| Generic Runtime manifests/config schemas | `infra/runtime/compose.yaml`, Kubernetes base, runtime JSON schemas | development/operational skeleton only; compose and kustomize default to `dev` tags | mutable image names; no environment release record |
| PR-UAT all-in-one image | L2 `infra/pr-uat/Dockerfile` and `PR UAT ECS EXP` | pushed to configured ECR and run by an ephemeral ECS task | tag is `pr-<number>-<downstream-prefix>`; workflow does not pass image digest; teardown/recreate is recovery |
| Optional L1 AppService | none | no command, image, manifest, workflow, or consumer found in app-packs | absent, so no revision or rollback mechanism exists |

The independent Runtime Dockerfile is structurally release-ready: it builds
separate static binaries, embeds version labels and config schemas, and keeps
L1 source out of the context
([`runtime.Dockerfile:27-64`](../../../infra/runtime.Dockerfile#L27-L64),
[`runtime.Dockerfile:113-147`](../../../infra/runtime.Dockerfile#L113-L147)).
Its compose and kustomize consumers still select mutable `dev` identities
([`compose.yaml:1-20`](../../../infra/runtime/compose.yaml#L1-L20),
[`kustomization.yaml:1-11`](https://github.com/pingcap-inc/NexusCRM/blob/c9736c2da0e718980e7a8d8fe4d51a8b5133ace4/infra/runtime/kubernetes/base/kustomization.yaml#L1-L11)).
This is current packaging evidence, not current service publication.

The PR-UAT image is the only audited pushed image. It contains server/setup,
frontend, TiDB, app-packs and L2 packs in one image
([L2 `infra/pr-uat/Dockerfile:106-148`](https://github.com/pingcap-inc/nexuscrm-pingcap-pack/blob/330f27e7c3a96526e1d2eacc77bf5d86599cf9dc/infra/pr-uat/Dockerfile#L106-L148)).
The ECS helper can record `image_digest`, but the workflow invokes it without
that option and passes the mutable tag
([L2 workflow `pr-uat-ecs-exp.yml:300-345`](https://github.com/pingcap-inc/nexuscrm-pingcap-pack/blob/330f27e7c3a96526e1d2eacc77bf5d86599cf9dc/.github/workflows/pr-uat-ecs-exp.yml#L300-L345),
[L2 helper `pr_uat_ecs.py:264-303`](https://github.com/pingcap-inc/nexuscrm-pingcap-pack/blob/330f27e7c3a96526e1d2eacc77bf5d86599cf9dc/scripts/pr_uat_ecs.py#L264-L303)).

### 4.3 Frontend outputs

The NexusCRM frontend build generates `dist/` after provisioning app-owned
source; `build:host` separately generates `dist-host/`
([`frontend/package.json:6-12`](../../../frontend/package.json#L6-L12)). The L1
repository supplies source manifests, not a published JS package or bundle
([app-packs `frontend/source-index.json:1-13`](https://github.com/pingcap-inc/nexuscrm-app-packs/blob/fc22e2049a41e5a1558ed07fdc1608d02439e9db/frontend/source-index.json#L1-L13),
[app-packs CRM source manifest `:1-12`](https://github.com/pingcap-inc/nexuscrm-app-packs/blob/fc22e2049a41e5a1558ed07fdc1608d02439e9db/salesforce-crm-standard/frontend/source-manifest.json#L1-L12)).

There are three consumers of a frontend build:

| Consumer | Build location | Durable identity |
|---|---|---|
| NexusCRM CI | Actions runner | none; validation output only |
| PR-UAT | image build stage | image tag plus source refs; no image or bundle digest in manifest |
| staging/test/watchdog/production | target environment | version-directory path plus source refs and `version.json`; no independent bundle digest |

Production materializes a synthetic app-packs source from the final pack and
official app-packs commit, runs `npm run build`, copies `dist`, and publishes a
symlink
([L2 `common.py:2579-2613`](https://github.com/pingcap-inc/nexuscrm-pingcap-pack/blob/330f27e7c3a96526e1d2eacc77bf5d86599cf9dc/deploy/online/runtime/common.py#L2579-L2613),
[L2 `common.py:2616-2674`](https://github.com/pingcap-inc/nexuscrm-pingcap-pack/blob/330f27e7c3a96526e1d2eacc77bf5d86599cf9dc/deploy/online/runtime/common.py#L2616-L2674)).
Consequently, “frontend revision” is currently a derived source closure, not a
promotable artifact identity.

### 4.4 L1 metadata and dialect source

The official CRM pack is a directory-level package with manifest format,
name/category, semantic version `0.2.0`, platform compatibility and component
descriptors
([app-packs `salesforce-crm-standard/pack.json:1-11`](https://github.com/pingcap-inc/nexuscrm-app-packs/blob/fc22e2049a41e5a1558ed07fdc1608d02439e9db/salesforce-crm-standard/pack.json#L1-L11)).
It is consumed from a Git checkout through `official_repo:<pack>`, not from a
package registry. Controlplane persists/validates source revision and payload
hash during install; NexusCRM separately embeds accepted current/prior pack
source revisions
([`appsource/source.go:3-27`](../../../backend/distributions/appsource/source.go#L3-L27),
[`appsource/source.go:29-59`](../../../backend/distributions/appsource/source.go#L29-L59)).

The app-packs repository contains four Go modules: the CRM dialect, its SOQL
module, issue-tracker compatibility residue, and the CI-only issue-tracker
conformance fixture. None has a repository tag or publication workflow. The CRM
dialect is compiled from the selected source checkout into the CRM distribution;
the issue-tracker paths are not production App artifacts.

### 4.5 L2 overlay, final pack and verification snapshot

`stack.lock.json` names the build script, app-shell config, official L1 pack,
intermediate L2 pack, final merged pack and installed pack list
([L2 `stack.lock.json:1-9`](https://github.com/pingcap-inc/nexuscrm-pingcap-pack/blob/330f27e7c3a96526e1d2eacc77bf5d86599cf9dc/stack.lock.json#L1-L9),
[L2 `stack.lock.json:89-93`](https://github.com/pingcap-inc/nexuscrm-pingcap-pack/blob/330f27e7c3a96526e1d2eacc77bf5d86599cf9dc/stack.lock.json#L89-L93)).
The final pack is a committed Git tree. Its `.build-lineage.json` records the
official app-packs ref and manifest hash, NexusCRM ref, downstream ref,
stack-lock hash, intermediate manifest/lineage hashes, and final assembly facts
([L2 final lineage `:1-28`](https://github.com/pingcap-inc/nexuscrm-pingcap-pack/blob/330f27e7c3a96526e1d2eacc77bf5d86599cf9dc/packs/NOT-EDIT-final-merged-packs/.build-lineage.json#L1-L28)).

The checked release tuple currently records only NexusCRM commit, app-packs
commit, stack-lock hash, pack paths and final-pack hash. Its validator can
verify the remote commits and committed pack hash
([L2 `validate_release_tuple.py:19-76`](https://github.com/pingcap-inc/nexuscrm-pingcap-pack/blob/330f27e7c3a96526e1d2eacc77bf5d86599cf9dc/scripts/validate_release_tuple.py#L19-L76),
[L2 `validate_release_tuple.py:250-279`](https://github.com/pingcap-inc/nexuscrm-pingcap-pack/blob/330f27e7c3a96526e1d2eacc77bf5d86599cf9dc/scripts/validate_release_tuple.py#L250-L279)).
The Release Tuple Gate regenerates twice and uploads the snapshot as a 14-day
Actions artifact, but artifact upload is `continue-on-error`; that artifact is
evidence, not the deployment source
([L2 `release-tuple-gate.yml:276-299`](https://github.com/pingcap-inc/nexuscrm-pingcap-pack/blob/330f27e7c3a96526e1d2eacc77bf5d86599cf9dc/.github/workflows/release-tuple-gate.yml#L276-L299)).

### 4.6 Schema, metadata and data migration artifacts

There is no standalone, complete schema-migration release. The effective
migration program is assembled from:

- the selected NexusCRM `setup` composition;
- the pinned controlplane code and NexusCRM schema provisioner;
- migration IDs/stamps compiled into that code;
- the selected L1/L2 pack payloads;
- optional L2 SQL patch-bundle input for workflows that authorize it;
- the existing database's apply/install/migration state.

`setup apply` invokes `controlplane.ApplyAllWithOptions`; separate commands
cover L0 initialization, metadata, packs, tenant overlay, install and reapply
([`setup.go:58-109`](../../../backend/internal/setupcmd/setup.go#L58-L109),
[`setup.go:154-204`](../../../backend/internal/setupcmd/setup.go#L154-L204)).
Production requires setup/bootstrap and uses a database without reset in the
audited deployment policy
([L2 production workflow `:10-28`](https://github.com/pingcap-inc/nexuscrm-pingcap-pack/blob/330f27e7c3a96526e1d2eacc77bf5d86599cf9dc/.github/workflows/deploy-multi-prod-environment.yml#L10-L28),
[L2 deployment policy `:279-287`](https://github.com/pingcap-inc/nexuscrm-pingcap-pack/blob/330f27e7c3a96526e1d2eacc77bf5d86599cf9dc/deployments/deployment-config.json#L279-L287)).

The release tag can carry patch title/time/file names and status, but the
production release record does not identify a single digest covering every
executable migration and metadata byte
([L2 tag payload `:184-198`](https://github.com/pingcap-inc/nexuscrm-pingcap-pack/blob/330f27e7c3a96526e1d2eacc77bf5d86599cf9dc/deployments/offline/runtime/emit_staging_release_tag.py#L184-L198)).

## 5. Publication and deployment paths

| Path | Authority/input | What is built/published | Final record | Rollback reality |
|---|---|---|---|---|
| L0 module consumption | semver tag in NexusCRM `go.mod` | source compiled into caller | `go.mod`/`go.sum` in selected source | repin and rebuild |
| NexusCRM CI | current commit + embedded module/app-packs locks | local CRM and Runtime images, frontend/tests | CI run only | rebuild another commit |
| Release Tuple Gate | committed tuple | reproducible final-pack snapshot | committed tuple + 14-day Actions artifact | rebuild prior tuple |
| CI/EXP | explicit/debug or latest-main policy | source-based backend/pack; EXP frontend/systemd/nginx | environment summary | reset/redeploy; not a production release |
| PR-UAT | downstream PR SHA, final-pack lineage refs | pushed all-in-one ECR image | ECS/ELB/task metadata + source refs/hash, but no image digest | destroy/recreate ephemeral environment |
| test/watchdog/staging | final-pack lineage; optionally an eligible release tag where supported | source runner + frontend + setup/apply | environment summary; staging also emits release manifest | slot/branch reset or redeploy |
| production | required staging release tag | target-host pack/frontend build and source runner | version `release.json`, deploy summary, current pointer | redeploy retained prior tag/directory; database stays forward |

The complete deployment-input classes are explicit below. Values owned by
protected L2 environments are intentionally not reproduced.

| Input class | Current input names | Owner | Consumer and identity |
|---|---|---|---|
| Release source selection | `release_tag`, downstream/upstream/app-packs refs, lineage path | L2 release workflow/final-pack lineage | release-class resolvers; immutable for tag/lineage flows, mutable only in explicit CI/EXP debug |
| L0 build closure | backend/distribution `go.mod`/`go.sum`, Go toolchain, CRM build tag | selected NexusCRM source and tagged L0 modules | all command/image/source builds; module versions immutable, complete build-environment identity absent |
| Pack composition/install | `stack.lock.json`, app-shell config, official/intermediate/final pack paths, `packs[]`, source ref/hash | L1 publisher + L2 composition + controlplane mechanism | pack builder/auditor, setup/install/reapply, frontend materializer |
| Frontend build | NexusCRM ref, frontend app-packs root/ref, L2 overlay, public URL/base path, npm lock | NexusCRM host + L1/L2 source + deploy runner | CI/image/environment bundle build; source can be pinned, bundle digest absent |
| Schema/metadata/data convergence | setup command/options, pack sources, optional patch manifest/directory, DB connection and existing stamps | setup/controlplane/pack/authorized patch owners | setup apply/install/reapply and deploy verification; no single identity |
| Runtime configuration | environment/mode, DB/auth/crypto, connector/provider, rate/admission/worker and bootstrap/reset controls | L2 checked config + protected variables/secrets | setup/backend/frontend/verification; mixed immutable and mutable inputs, no complete digest |
| Topology/cutover | target/slot, release root, ports, systemd/nginx, probes, retention/recovery | L2 deploy implementation | staging/test/watchdog/production; environment fact, not artifact identity |
| PR-UAT image/ECS | PR/head, source refs, ECR tag, ECS/ALB, ephemeral DB branch, runtime secrets | L2 PR-UAT workflow | image builder and ECS; source pinned but deployed image tag mutable |
| Independent Runtime skeleton | service image names, JSON config, workload token, addresses, admission/drain | NexusCRM | CI smoke and generic manifests only; not a current production input |

The JSON companion carries these rows with exact evidence anchors and forces
each artifact to declare its authoritative ref, build input, publication
destination, installation/deployment input, compatibility assumption,
integrity/provenance, consumer and rollback.

Release-class environment policy consistently names `final_pack_lineage` and
does not verify the checked tuple hash
([L2 PR-UAT `deployment-config.json:69-97`](https://github.com/pingcap-inc/nexuscrm-pingcap-pack/blob/330f27e7c3a96526e1d2eacc77bf5d86599cf9dc/deployments/deployment-config.json#L69-L97),
[L2 staging `:163-181`](https://github.com/pingcap-inc/nexuscrm-pingcap-pack/blob/330f27e7c3a96526e1d2eacc77bf5d86599cf9dc/deployments/deployment-config.json#L163-L181),
[L2 production `:275-295`](https://github.com/pingcap-inc/nexuscrm-pingcap-pack/blob/330f27e7c3a96526e1d2eacc77bf5d86599cf9dc/deployments/deployment-config.json#L275-L295)).
The resolver returns only upstream ref, official app-packs ref, and lineage path
from the committed final pack
([L2 `resolve_deploy_refs.py:32-64`](https://github.com/pingcap-inc/nexuscrm-pingcap-pack/blob/330f27e7c3a96526e1d2eacc77bf5d86599cf9dc/scripts/resolve_deploy_refs.py#L32-L64)).

Production's per-version `release.json` records the release tag, authority
mode, tag target, lineage path, resolved downstream/upstream/app-packs refs,
final-pack hash, frontend app-packs source ref, local version root and port
transition
([L2 `deploy_multi_prod_env.py:1714-1737`](https://github.com/pingcap-inc/nexuscrm-pingcap-pack/blob/330f27e7c3a96526e1d2eacc77bf5d86599cf9dc/deploy/online/runtime/deploy_multi_prod_env.py#L1714-L1737)).
It does not record the selected contract/wire/api-host/controlplane/connectors
pins, content digest of the built frontend, backend binary/source-build digest,
image digest, complete environment config digest, or resulting DB schema state.

## 6. Reconstructed current delivery tuple

For a production deployment, the effective selection is:

```text
required L2 staging release tag
  -> downstream tag target commit
  -> tag payload: NexusCRM commit + app-packs commit + final-pack hash
  -> downstream commit's final-pack lineage and stack.lock
  -> NexusCRM go.mod: contract + wire-go + controlplane + api-host + connectors
  -> app-packs source: L1 metadata + dialect source + frontend source
  -> L2 source: overlay + final merged pack + frontend overlay + deploy code
  -> target build: setup/apply + frontend dist + backend go-run runner
  -> environment config/secrets + existing database migration/install state
```

Mapped to the requested tuple axes:

| Axis | Current selection |
|---|---|
| NexusCRM/L0 revision | exact NexusCRM commit from release tag/final-pack lineage |
| contract and wire versions | implicit pins inside the selected NexusCRM `go.mod`; not repeated in the release tag |
| L0 service versions | absent: Runtime service images are not published/deployed in this production path |
| L1 app-pack revision | exact app-packs commit from release tag/final-pack lineage, plus per-pack manifest/source locks |
| L1 AppService revision | absent: no current AppService artifact |
| L2 overlay revision | downstream tag target/commit and committed final-pack lineage |
| frontend revision | NexusCRM commit plus materialized L1/L2 frontend source; no standalone digest |
| schema/migration revision | implicit executable closure of setup/controlplane/packs/patch plus DB stamps; no single identity |
| configuration | L2 deployment config plus environment variables/secrets; not copied into this public inventory |

This tuple is mostly immutable at source selection time, but it does not prove
that two environments run byte-identical outputs because backend/frontend are
rebuilt at each destination and the toolchain/base-image/config inputs are not
all captured in one immutable record.

## 7. One-source-of-truth and reproducibility violations

These are inventory findings only; R1a does not fix them.

### 7.1 Duplicate or implicit version facts

1. L1 identity has at least four distinct current facts: app-packs repo commit,
   per-pack `pack.json.version`, NexusCRM accepted source revision, and installed
   payload hash. They have legitimate different meanings, but no current BOM
   names those meanings together.
2. NexusCRM embeds separate repository-wide backend and frontend app-packs
   revisions plus current/prior per-pack revisions
   ([`appsource/source.go:3-27`](../../../backend/distributions/appsource/source.go#L3-L27),
   [`appsource/source.go:29-59`](../../../backend/distributions/appsource/source.go#L29-L59)).
3. L0 module versions are authoritative in the selected NexusCRM source, but
   absent from the L2 release tag and production release record.
4. `release-tuple.json` and final-pack lineage both record overlapping source
   refs and hashes, but only lineage is the normal release-class deployment
   resolver.

### 7.2 Mutable or incomplete artifact identities

1. NexusCRM CI image names and Runtime compose/kustomize defaults are mutable
   local/`dev` tags.
2. PR-UAT pushes a tag derived from PR number and a 12-character downstream
   prefix, and the deploy invocation omits the supported image digest. A rerun
   can replace the image under the same identity.
3. Production retains an immutable release tag/source tuple but rebuilds
   frontend and Go binaries on the target. The final record lacks output
   digests, so it cannot prove byte identity with staging.
4. CI/EXP intentionally allow explicit or latest-main refs; their summaries are
   test/canary evidence, not release identity.

### 7.3 Competing final-pack hash grammars

The release tuple's canonical pack hash excludes `.build-lineage.json` and uses
`./`-prefixed paths
([L2 `validate_release_tuple.py:19-76`](https://github.com/pingcap-inc/nexuscrm-pingcap-pack/blob/330f27e7c3a96526e1d2eacc77bf5d86599cf9dc/scripts/validate_release_tuple.py#L19-L76)).
The PR-UAT image builder hashes every file, including lineage, with a different
path grammar
([L2 `build_pr_uat_ecs_image.sh:230-244`](https://github.com/pingcap-inc/nexuscrm-pingcap-pack/blob/330f27e7c3a96526e1d2eacc77bf5d86599cf9dc/scripts/build_pr_uat_ecs_image.sh#L230-L244)).
The same final-pack tree therefore has more than one claimed content identity.

### 7.4 Missing provenance and deployment inputs

1. Go tags have no checked-in publisher, checksum manifest, SBOM, or
   attestation; `go.sum` protects consumer downloads but is not producer
   provenance.
2. No published Runtime image digest, SBOM, provenance, or attestation exists.
3. The frontend bundle and production source-run binary have no content digest.
4. The production release record does not contain the complete L0 module pins,
   configuration schema/input digest, optional patch digest, or resulting DB
   migration/install state.
5. The intermediate L2 lineage contains a historical absolute local source
   path, demonstrating that part of its provenance is machine-specific
   ([L2 intermediate lineage `:1-11`](https://github.com/pingcap-inc/nexuscrm-pingcap-pack/blob/330f27e7c3a96526e1d2eacc77bf5d86599cf9dc/packs/Salesforce-PingCAP-L2/.build-lineage.json#L1-L11)).

### 7.5 Rollback is not complete tuple restoration

Production keeps older version directories and records the previous release
tag before switching the current pointers
([L2 `deploy_multi_prod_env.py:1786-1819`](https://github.com/pingcap-inc/nexuscrm-pingcap-pack/blob/330f27e7c3a96526e1d2eacc77bf5d86599cf9dc/deploy/online/runtime/deploy_multi_prod_env.py#L1786-L1819),
[L2 `deploy_multi_prod_env.py:1867-1895`](https://github.com/pingcap-inc/nexuscrm-pingcap-pack/blob/330f27e7c3a96526e1d2eacc77bf5d86599cf9dc/deploy/online/runtime/deploy_multi_prod_env.py#L1867-L1895)).
Redeploying a prior tag can restore the source/frontend runner selection, but it
does not reverse shared database schema, pack installation, metadata, reference
data, or data migrations. Current rollback is therefore code/frontend
selection plus forward database compatibility/recovery, not restoration of a
complete prior tuple.

## 8. R1b-ready decision inputs

R1b can now design a target BOM without re-auditing release reality. It must
decide, after consuming the completed A1b App contract:

1. the one authoritative BOM/release identity and the exact immutable members;
2. whether NexusCRM source commit is allowed to derive L0 module versions or
   whether separately deployable service/module identities must be explicit;
3. the single final-pack/metadata content-digest grammar;
4. whether frontend and metadata become independently published artifacts or
   remain derived, and how their bytes are proven;
5. how a future optional L1 AppService digest is represented without putting it
   inside AppRelease or inventing an artifact before one exists;
6. the schema/migration compatibility fact and deployment result needed for
   rollback, while explicitly avoiding a false reverse-migration promise;
7. the compatibility matrix among contract/wire, L0 services, L1 metadata,
   frontend, L2 overlay, and database state;
8. the exact record that survives deployment and can reproduce the previous
   active tuple.

R1b must not turn this JSON inventory into a release registry or copy A1b's App
facts. A1b owns App domain semantics; R1b owns the artifact/BOM mapping.

## 9. Assigned gap list

### R1b — target release tuple decisions

- Select the single BOM identity, fields and derivation rules.
- Consume A1b AppRelease/AppInstallation outputs without redefining them.
- Close the module/service/frontend/metadata/schema compatibility model.
- Select one final-pack/content digest grammar.
- Define complete prior-tuple and forward-database rollback semantics.
- Classify which current duplicate facts are authoritative, derived or removed.

### R2 — build and publication work

- Add an owned, reviewable L0 Go-module tagging/publication process.
- Publish independent Runtime images by immutable digest with checksum, SBOM and
  attestation if R1b includes them.
- Publish frontend/metadata artifacts if R1b makes them independent release
  members; do not rebuild them from different source revisions.
- Record generated wire inputs and compatibility proof in release provenance.
- Make PR-UAT build/deploy record the pushed image digest.

### R3 — deployment integration work

- Make release-class deployment consume and persist the complete R1b BOM rather
  than infer only three refs from final-pack lineage.
- Promote immutable build outputs instead of rebuilding backend/frontend on
  each destination.
- Record configuration schema/input identity, patch selection and resulting DB
  convergence evidence without checking private values into public core.
- Make rollback select a complete prior artifact tuple and separately enforce
  database compatibility/recovery.
- Integrate independent Runtime deployment only after R2 publishes its images
  and R1b owns their identity.

## 10. R1a closure

All seven repositories are represented in the machine inventory. Every current
production artifact and deployment input class has an owner and consumer; the
only requested artifact class with neither is the explicitly absent optional
L1 AppService. Unknown future identities are assigned to R1b, publication gaps
to R2, and deployment consumption/rollback gaps to R3.

No runtime, build, publication, install, deployment, protobuf, App authority,
or metadata authority behavior is changed by this inventory. After this PR is
merged, #3624 can mark R1a Done and R1b Ready.

## 11. Validation

- `jq -e . docs/refactor/serviceification/release-artifact-delivery-inventory-r1a.json`: PASS.
- JSON evidence-revision check: all 65 evidence anchors use the exact audited
  repository revision: PASS.
- Cross-repository Markdown evidence check: all 35 GitHub file paths exist at
  the cited commit and every cited line range is inside the file: PASS.
- Local Markdown links and balanced code fences: PASS.
- `(cd backend && GOWORK=off go test ./internal/boundary -count=1)`: PASS.
- `(cd backend && GOWORK=off go test -race ./internal/boundary -run
  'TestReleaseInventoryR1A' -count=1)`: PASS.
- `(cd backend && GOWORK=off go vet ./internal/boundary)`: PASS.
- `(cd tools/boundarygate && GOWORK=off go test ./... -count=1)`: PASS.
- `go run ./tools/boundarygate`: PASS, zero forbidden edges and zero new
  dialect-token hits.
- In the audited L2 tree,
  `python3 scripts/validate_release_tuple.py --check-pack-hash --check-remote`:
  PASS.
- `git diff --cached --check`: PASS.
- Changed-path inspection: only this inventory/learned/index documentation and
  its boundary test change. No production command, image definition, workflow,
  route/deployment manifest, config schema, pack, protobuf/generated file,
  build/install/deploy script, or runtime code changes.
- `scripts/scan-public-core-boundary.sh` still reports the current-main
  baselined production/test-fixture hits; this diff adds no scanned production
  source or tenant payload. That raw scanner result is not represented as a
  clean pass.
