Correct live image source pin and reconcile service attribution evidence
Some checks failed
Use-case regression gate / usecase-regressions (push) Has been cancelled

Assistant: codex
Assistant-Model: gpt-6.1-sol
Assistant-Session: 01a18e2d-f513-7742-b8e7-12af0b744ff3
This commit is contained in:
tegwick 2026-10-30 23:06:13 +01:00
parent 16c685f956
commit fa64e4f868
7 changed files with 244 additions and 1 deletions

View file

@ -26,3 +26,13 @@ WP-0012 owns the operating/service returns above. WP-0013 owns privacy/content
verdicts; WP-0014 owns all-space reconciliation and the separate cohort/apex
cutover decision. Existing canonical cross-owner records remain in their owners;
this assessment creates no credential grant or service acceptance.
October 30 source/attribution follow-through: actual retained image bytes match
all69packaged files at dd83c90, while the release-unit's796a1557source differs in
eight paths. Corrected that source pin without changing the image or live service.
The actual finance parser rejects the legacy resource ID as a client attribution
key. Resource/default tenant, retained cohort SQL tenant and financial entity are
distinct identifiers; their client × app × instance mapping is still unproven.
The local compatibility catalog has no matching service record; this does not
prove absence on the ops-hub owner surface. Detailed bounded proof and next
returns: service-provenance-reconciliation-2026-10-30.{md,json}.

View file

@ -0,0 +1,61 @@
{
"schema": "coulomb.packaged-source-provenance.v1",
"image": "forgejo.coulomb.social/coulomb/coulomb-social@sha256:9a646d8e01a61ba5316d3c2eb0273064e17f2d0300ad07af766ccedda65ecb18",
"network": "none",
"read_only_root": true,
"entrypoint_bypassed": true,
"database_contact": false,
"production_changes": false,
"comparisons": [
{
"commit": "dd83c90d73a1f7153581949424603e7b38eec014",
"packaged_file_count": 69,
"source_file_count": 69,
"different_files": 0,
"all_packaged_source_bytes_match": true
},
{
"commit": "796a1557e9e5ff68800f9676d050d5b1efe7a138",
"packaged_file_count": 69,
"source_file_count": 70,
"different_files": 8,
"all_packaged_source_bytes_match": false
}
],
"actual_packaged_manifest_sha256": "a8a86bc44c5dcc9340aafdc8aebed09dbf04f366d0f57a7ae781f55143c4c958",
"dependency_or_build_reproducibility_proved": false,
"observed_at": "2026-10-30T22:04:08.096662+00:00",
"verifier_source_sha256": "99d734f20331e8d699081d3d77e7a0d0b3bc676be69ce101377bc69eae6c70d5",
"native_read_only_deployment": {
"uid": "2dbe661a-d232-4477-bbd1-833813077fbe",
"image": "forgejo.coulomb.social/coulomb/coulomb-social@sha256:9a646d8e01a61ba5316d3c2eb0273064e17f2d0300ad07af766ccedda65ecb18",
"replicas": 1
},
"image_oci_revision_label": null,
"registry_previous_source": "796a1557e9e5ff68800f9676d050d5b1efe7a138",
"registry_corrected_source": "dd83c90d73a1f7153581949424603e7b38eec014",
"identity_reconciliation": {
"schema": "coulomb.service-identity-reconciliation.v1",
"observed_on": "2026-10-30",
"legacy_resource_id": "resource:tenant:coulomb:coulomb-social",
"legacy_id_is_fin_client_key": false,
"client_attribution": null,
"mapping_status": "unresolved_not_inferred",
"finance_parser_source_sha256": "bfee11197bdb3d10453a655f75319f446069c59c5edf14ca027023b44597c18b",
"resource_inventory_tenant": "tenant:coulomb",
"resource_financial_entity": "entity:coulomb",
"retained_accepted_cohort_tenant": "tenant:platform",
"deployment_values_default_tenant": "tenant:coulomb",
"application_id": "coulomb-social",
"state_hub_catalog_get_slug_http_status": 404,
"state_hub_catalog_repo_results": 0,
"state_hub_missing_record_does_not_prove_ops_hub_absence": true,
"booked_cost_or_allocation_invented": false,
"external_writes": false
},
"source_references": {
"/home/worsch/resource-control/data/resources/coulomb-social-production.json": "d50477b5c30f93e6adf648cf8c7b9c00471e3f002d668bad381a3f3462ed7da4",
"/home/worsch/railiance-apps/helm/coulomb-social-values.yaml": "f6a8a70da3c885167654aa362ad3fbb46a72e791ed5028e7ef41bbd7fd9e7ea6",
"/home/worsch/fin-hub/docs/fin-resource-authority-contract-v0.1.md": "10926027035c1afe115a654af3eaf49ec3c9ab278573f474a5d2e0c20ae7f4c3"
}
}

View file

@ -0,0 +1,87 @@
# Service source and attribution reconciliation
WP-0012-T03 remains open. This check corrects release-source evidence and
identifies the missing client attribution join; it does not deploy or register
anything, book cost, approve an identity mapping or finish service conformance.
## Current image source
A read-only native deployment query still observes deployment UID
`2dbe661a-d232-4477-bbd1-833813077fbe`, one replica and image digest
`9a646d8e01a61ba5316d3c2eb0273064e17f2d0300ad07af766ccedda65ecb18`.
The October 8 release receipt and current deployment-owner values name source
`dd83c90d73a1f7153581949424603e7b38eec014`. The app release-unit declaration
instead named `796a1557e9e5ff68800f9676d050d5b1efe7a138`.
The retained digest image has no OCI revision label, so that label cannot prove
either source claim. `scripts/verify-packaged-source.py` bypasses its entrypoint
and hashes the entire packaged application plus manage.py, pyproject.toml and
the renamed entrypoint. It compares those bytes with exact Git objects, without
starting Django, mounting host files, pulling an image or contacting a database.
The disposable container has no network and a read-only root.
All 69 packaged files match dd83c90 exactly. Commit 796a1557 has 70 source files
and eight differing/missing packaged paths. The release-unit declaration now
pins dd83c90, matching both the actual packaged source and owning release values.
The image digest, production and prepared storage proposal are unchanged.
This comparison proves source-byte equality, not dependency provenance or build
reproducibility. It does not retag or rebuild the historical artifact.
Repeat using the locally retained immutable image:
```sh
python3 scripts/verify-packaged-source.py \
--image forgejo.coulomb.social/coulomb/coulomb-social@sha256:9a646d8e01a61ba5316d3c2eb0273064e17f2d0300ad07af766ccedda65ecb18 \
--source dd83c90d73a1f7153581949424603e7b38eec014 \
--source 796a1557e9e5ff68800f9676d050d5b1efe7a138
```
This command reports each comparison; inspect `all_packaged_source_bytes_match`.
It does not select or publish a source pin automatically.
## Client attribution remains unresolved
The existing `resource:tenant:coulomb:coulomb-social` value is an authoritative
resource-control inventory ID and that inventory's dedicated allocation key.
It is not a fin-hub client attribution key. Running the actual fin-hub parser
rejects it. Fin-hub's current contract requires the three externally authoritative
dimensions and derives `client:<id>|app:<id>|instance:<id>`; resource/infrastructure
IDs retain their separate namespace. Do not simply rename the resource ID.
The inspected sources establish different axes:
| Axis | Evidence |
| --- | --- |
| Product/application | `coulomb-social` |
| Resource inventory tenant | `tenant:coulomb` |
| Resource financial consumer | `entity:coulomb`; procurer is `entity:railiance` |
| Deployment values' default tenant | `tenant:coulomb` |
| Retained accepted-cohort SQL selection | `tenant:platform` |
| Legal client baseline | The accepted business-app contract says Binky Hedgehog GmbH is client #1. |
Those values do not establish a canonical client × app × instance mapping by
themselves. A default tenant is not proof of every stored row's tenant, and a
financial entity is not automatically a client ID. Keep the native data and all
existing IDs unchanged. WP-0014's explicit source/tenant/grant reconciliation
must preserve the accepted cohort's actual tenant rather than changing it to
make a cost join pass.
Required return under the existing WP-0012-T03: an authoritative mapping for the
client and instance, linked to the resource/deployment and actual tenant scope;
then the same canonical key through finance ingestion and a per-instance report
backed by actual costs/authoritative shared allocation. Missing amounts stay
unknown. CPU requests, a synthetic CSV or a new alias cannot prove booked cost.
The local State Hub compatibility catalog returns 404 for the exact service slug
and zero rows for `repo_slug=coulomb-social`. This proves only that local surface
lacks the record. Ops-hub documents a hub-core-hosted owner surface and a separate
attended bootstrap; these local observations do not prove absence there or
authorize bootstrap. Its current typed compatibility schema also lacks a client
instance relation. A prose description alone would not satisfy the service
contract's complete client/environment/endpoint registration requirement.
The companion JSON retains bounded observations, source hashes and comparison
counts. It contains no application bodies, credentials, provider costs or
fabricated identity mapping. Ruff and whitespace checks pass; application
behavior/tests are unchanged, so the existing 383-case full gate is not claimed
as a newly executed acceptance result for this metadata correction.

View file

@ -28,3 +28,9 @@ Do **not** put secret values, provider credentials, or invoices here.
Inventory pointer (resource-control):
`resource-control/data/resources/coulomb-social-production.json`.
The resource ID above is not a fin-hub client attribution key. The current
client × app × instance mapping remains unresolved; see
[service provenance and attribution reconciliation](../release/service-provenance-reconciliation-2026-10-30.md).
Do not reinterpret historical forecast identifiers or missing costs as a
validated finance join.

View file

@ -43,4 +43,4 @@ pins:
digest:
hashAlgorithm: SHA-1
normalisationAlgorithm: gitCommit/v1
value: 796a1557e9e5ff68800f9676d050d5b1efe7a138
value: dd83c90d73a1f7153581949424603e7b38eec014

View file

@ -0,0 +1,67 @@
#!/usr/bin/env python3
"""Compare retained OCI application bytes with exact Git commits, without startup.
No pull, mounts, network, application entrypoint, database or external writes.
Inventory follows the runtime COPY instructions in this repo's Dockerfile.
This proves packaged source equality, not dependency/build reproducibility.
"""
import argparse
import hashlib
import json
import re
import subprocess
PROBE = """import hashlib,json,pathlib
r=pathlib.Path('/app')
f={str(p.relative_to(r)):hashlib.sha256(p.read_bytes()).hexdigest()
for p in (r/'coulomb_social').rglob('*')
if p.is_file() and '__pycache__' not in p.parts and p.suffix != '.pyc'}
for n in ['manage.py','pyproject.toml','docker-entrypoint.sh']:
f[n]=hashlib.sha256((r/n).read_bytes()).hexdigest()
print(json.dumps(f,sort_keys=True))
"""
def canonical(value):
return json.dumps(value, sort_keys=True, separators=(",", ":")).encode()
def verify(image, sources):
if not re.fullmatch(r"forgejo\.coulomb\.social/coulomb/"
r"coulomb-social@sha256:[a-f0-9]{64}", image):
raise ValueError("Exact retained application image digest required")
if not sources or any(not re.fullmatch(r"[a-f0-9]{40}", source) for source in sources):
raise ValueError("Full source commit hashes required")
actual = json.loads(subprocess.check_output([
"docker", "run", "--rm", "--pull=never", "--network", "none", "--read-only",
"--cap-drop", "ALL", "--security-opt", "no-new-privileges", "--entrypoint", "python",
image, "-c", PROBE], timeout=60))
comparisons = []
for source in sources:
paths = subprocess.check_output([
"git", "ls-tree", "-r", "--name-only", source, "coulomb_social", "manage.py",
"pyproject.toml", "scripts/docker-entrypoint.sh"], text=True).splitlines()
expected = {}
for name in paths:
packaged = (name.removeprefix("scripts/")
if name == "scripts/docker-entrypoint.sh" else name)
expected[packaged] = hashlib.sha256(subprocess.check_output(
["git", "show", source + ":" + name])).hexdigest()
differences = sum(expected.get(n) != actual.get(n) for n in set(expected) | set(actual))
comparisons.append({"commit": source, "packaged_file_count": len(actual),
"source_file_count": len(expected), "different_files": differences,
"all_packaged_source_bytes_match": differences == 0})
return {"schema": "coulomb.packaged-source-provenance.v1", "image": image,
"network": "none", "read_only_root": True, "entrypoint_bypassed": True,
"database_contact": False, "production_changes": False, "comparisons": comparisons,
"actual_packaged_manifest_sha256": hashlib.sha256(canonical(actual)).hexdigest(),
"dependency_or_build_reproducibility_proved": False}
if __name__ == "__main__":
parser = argparse.ArgumentParser(description=__doc__)
parser.add_argument("--image", required=True)
parser.add_argument("--source", action="append", required=True)
arguments = parser.parse_args()
print(json.dumps(verify(arguments.image, arguments.source), indent=2))

View file

@ -269,6 +269,18 @@ the app cannot read/export it. Include any future retained journals in operator
offboarding handoff and explicit expiry under the open service contract work.
No production date journal or expiry was created by the isolated rehearsal.
2026-10-30 service-source/attribution follow-through: read-only native metadata
still observes the old digest and one replica. An entrypoint-bypassed, network-none,
read-only retained-image comparison proves all69packaged files match dd83c90;
the registry's796a1557source differs in eight paths. Corrected only the app
release-unit source pin. The actual fin-hub parser rejects the resource inventory
ID as a client attribution key. The resource/default tenant (tenant:coulomb),
accepted-cohort SQL tenant (tenant:platform) and financial entity (entity:coulomb)
must remain distinct until an authoritative client/instance mapping is returned.
No identity rekey, cost, finance ingestion or ops bootstrap is inferred.
Local service-catalog slug404/repo0rows does not establish owner-surface absence.
Proof/next returns: docs/release/service-provenance-reconciliation-2026-10-30.{md,json}.
## Completion
Finish when every task above has its stated evidence and acceptance, or hand off any newly discovered residual to a live work record first. Cross-owner dependencies remain their existing canonical records.