# sfcrm AppService Runtime-reconnect release closure

This evidence is bound to the AppService-only source change in this downstream
PR and compares the exact `nexuscrm-app-packs` revisions:

- previous AppService source: `047f9c119132ee3f36483bf5efb5051c79a60851`
- candidate AppService source: `bc0059beb8a05343682e10d610e4a56c0833c582`
- unchanged frontend source: `047f9c119132ee3f36483bf5efb5051c79a60851`
- unchanged CRM AppRelease: `0.3.0`,
  `sha256:2aca321c7a1ce14a4ea819bab2e4f82508919d36b0c1c9edc0df29935004b35c`

The candidate exact-main revision passed
[`sfcrm-appservice` run `29804415663`](https://github.com/pingcap-inc/nexuscrm-app-packs/actions/runs/29804415663).
The unchanged owner publisher then built, KMS-signed, independently verified,
and committed the stable image in
[`29804529821`](https://github.com/pingcap-inc/nexuscrm-app-packs/actions/runs/29804529821):

```text
ghcr.io/pingcap-inc/nexuscrm-sfcrm-appservice@sha256:ce719f1d4fcb56a8ff8eb29a59f59aecbf7c5c2fceb2676302fa303227139e6f
```

## Failure and owning correction

Signed D2A test2 run
[`29800064587`](https://github.com/pingcap-inc/nexuscrm-pingcap-pack/actions/runs/29800064587)
passed release verification, metadata, query/queryAll/queryMore/history,
cancellation, and SQL-count gates. It then failed after graceful Runtime restart
because an unused gRPC client remained `IDLE` and the AppService readiness probe
only observed connection state.

The app-blind owner correction is
[`nexuscrm-api-host#34`](https://github.com/pingcap-inc/nexuscrm-api-host/pull/34),
merged as `91d6ec5c0a1d8c3788945298f293624bc0730168` and released as
`v0.12.1`. An `IDLE` client now restarts its gRPC connection loop while
readiness remains false until the connection reaches `READY`.

The first downstream pin was closed because it found a second, independent
problem: D2B mutation code had been connected to the production command before
an AppRelease authorized that capability. The owner correction in
[`nexuscrm-app-packs#485`](https://github.com/pingcap-inc/nexuscrm-app-packs/pull/485)
keeps mutation implementation in L1 but removes its Runtime client, readiness
dependency, route, metrics, and process advertisement from current production
composition.

## Capability and source closure

CRM AppRelease `0.3.0` declares exactly:

```text
io.nexuscrm.sfcrm.query.v1
io.nexuscrm.sfcrm.ui.record-access.v1
```

The candidate production command advertises and installs exactly those two
capabilities. The owner boundary test derives the latest immutable AppRelease
capability set, derives the production command advertisement, requires exact
equality, and requires each current Runtime client/wiring pair to be present if
and only if its capability is released. Both exact-head Codex review passes on
#485 approved that closure with no blocker.

The source range also contains already-merged metadata, dialect, mutation, and
frontend work unrelated to this D2A patch. This downstream PR does not select
those changes as one artificial release. The AppService source and its
`app_installation.service_source_commit` advance together; the independently
published frontend remains pinned to `047f9c11...`. The immutable AppRelease,
Catalog, Runtime, Gateway, metadata tree, capability set, and all other desired
BOM facts remain unchanged.

## Verification contract

The downstream validator permits the independently published AppService and
frontend source commits to differ, but still requires the AppService source and
AppInstallation service binding to be identical. Existing source-tuple,
publication-receipt, signature, provenance, SBOM, and AppRelease capability
checks remain unchanged.

After merge, the existing L2 producer must independently verify the owner image
and resolve it by digest. The same signed-BOM test2 path must then pass Runtime
restart and all earlier D2A query assertions before this capability family is
complete.
