diff --git a/docs/release/identity-export-candidate-2026-10-31.sources.txt b/docs/release/identity-export-candidate-2026-10-31.sources.txt new file mode 100644 index 0000000..8b4efd7 --- /dev/null +++ b/docs/release/identity-export-candidate-2026-10-31.sources.txt @@ -0,0 +1,7 @@ +/home/worsch/coulomb-social/scripts/verify-packaged-source.py: 99d734f20331e8d699081d3d77e7a0d0b3bc676be69ce101377bc69eae6c70d5 +/home/worsch/coulomb-social/scripts/rehearse-client-export.py: 4e722a696187d1c32112276ae66a526f4765a30c3ab8891bb22b4bc5727f4aec +/home/worsch/coulomb-social/scripts/verify-restored-application.py: d1a641bb93e9ba9c5f879b806d81b1de37ba0743c542fc11137dd555a6b9f9ac +/home/worsch/coulomb-social/tests/test_oidc_userinfo_binding.py: f57d1b434f837f1920a170d3b5aa547a4083811f8dbde9fab8d8fdf3f73583c7 +/home/worsch/coulomb-social/tests/test_client_export.py: e52749b0e2885bc3ccc278b26e2d37ed7d52e43a4336a14523e04d9933332bd8 +/tmp/csoc-packaged-candidate-tests-20261031.py: a19f94f3dbc71dfd80a2d380f03e5f737c7453b64df022b6e5c2ede8141976b3 +/tmp/csoc-packaged-recovery-check-20261031.py: 9c370b6e7e1acb442cb660cc3709e3ffd3676c87419a217a7656174c8a347f95 diff --git a/docs/release/identity-export-candidate-build-2026-10-31.json b/docs/release/identity-export-candidate-build-2026-10-31.json new file mode 100644 index 0000000..51aa01b --- /dev/null +++ b/docs/release/identity-export-candidate-build-2026-10-31.json @@ -0,0 +1,95 @@ +{ + "schema": "coulomb.identity-export-candidate-build.v1", + "source": "23ffe2cf4b214666754a2420558943438e54251a", + "tag": "forgejo.coulomb.social/coulomb/coulomb-social:23ffe2cf4b21", + "image": "forgejo.coulomb.social/coulomb/coulomb-social@sha256:522bcd7fce92436765a60c1e4afa2598f3cc40913352153ff1c4319a99ca92ed", + "registry_digest_independently_verified": true, + "source_revision_label_verified": true, + "build_context": "git archive of exact source; Dockerfile, dockerignore, lock, project, manage.py, app and entrypoint only", + "build_inputs": { + "Dockerfile": "d0e197a18db8980eb3e51cca842d693e10ab0b4208627bba28691d10719d4a00", + ".dockerignore": "901c8b95d95549d0e78c1c3d6d0538bf0252c8a77e9409129e0cadfa55c7c56c", + "pyproject.toml": "5758c56fd1be89b973861ccc5ecbadb495e742ee13ebd7e19a221a0f119c54ee", + "uv.lock": "e8ebb6fc4b5abd1ac80f1c9012f1983642d0528a8a213cfcc394261606fad887", + "scripts/docker-entrypoint.sh": "70100256ca41ae6afe77078c810a8b6012472f0a741919f403f32088f98ab463" + }, + "runtime": { + "live": { + "python": "3.12.16", + "distributions": { + "anyio": "4.14.2", + "asgiref": "3.12.1", + "authlib": "1.7.2", + "bleach": "6.4.0", + "certifi": "2026.7.22", + "cffi": "2.1.1", + "cryptography": "50.0.0", + "dj-database-url": "3.1.2", + "django": "6.1", + "gunicorn": "26.0.0", + "h11": "0.16.0", + "httpcore": "1.0.9", + "httpx": "0.28.1", + "idna": "3.18", + "joserfc": "1.7.4", + "markdown": "3.10.3", + "packaging": "26.3", + "psycopg": "3.3.4", + "psycopg-binary": "3.3.4", + "pycparser": "3.0", + "python-decouple": "3.8", + "sqlparse": "0.5.5", + "typing_extensions": "4.16.0", + "webencodings": "0.5.1", + "whitenoise": "6.12.0" + } + }, + "candidate": { + "python": "3.12.16", + "distributions": { + "anyio": "4.14.2", + "asgiref": "3.12.1", + "authlib": "1.7.2", + "bleach": "6.4.0", + "certifi": "2026.7.22", + "cffi": "2.1.1", + "cryptography": "50.0.0", + "dj-database-url": "3.1.2", + "django": "6.1", + "gunicorn": "26.0.0", + "h11": "0.16.0", + "httpcore": "1.0.9", + "httpx": "0.28.1", + "idna": "3.18", + "joserfc": "1.7.4", + "markdown": "3.10.3", + "packaging": "26.3", + "psycopg": "3.3.4", + "psycopg-binary": "3.3.4", + "pycparser": "3.0", + "python-decouple": "3.8", + "sqlparse": "0.5.5", + "typing_extensions": "4.16.0", + "webencodings": "0.5.1", + "whitenoise": "6.12.0" + } + }, + "runtime_packages_equal": true, + "python_versions_equal": true + }, + "production_deployed": false, + "live_release_pins_modified": false, + "new_database_migrations": false, + "not_an_offboarding_or_transfer_acceptance": true, + "source_manifest_sha256": "a90b0217c6424a89e166a7df514fe4a86c9643b502ecdc9ebf0b64b76c06b739", + "packaged_django_check": "passed", + "packaged_migration_drift_check": "passed_no_changes_detected", + "source_gate": { + "command": "make check", + "tests": 441, + "failures": 0, + "errors": 0, + "skipped": 0, + "junit_sha256": "1e5b3c63d85a23f176420f2004831b59406d294c1528b3be80d49669edbb116f" + } +} diff --git a/docs/release/identity-export-candidate-provenance-2026-10-31.json b/docs/release/identity-export-candidate-provenance-2026-10-31.json new file mode 100644 index 0000000..2b769b0 --- /dev/null +++ b/docs/release/identity-export-candidate-provenance-2026-10-31.json @@ -0,0 +1,20 @@ +{ + "schema": "coulomb.packaged-source-provenance.v1", + "image": "forgejo.coulomb.social/coulomb/coulomb-social@sha256:522bcd7fce92436765a60c1e4afa2598f3cc40913352153ff1c4319a99ca92ed", + "network": "none", + "read_only_root": true, + "entrypoint_bypassed": true, + "database_contact": false, + "production_changes": false, + "comparisons": [ + { + "commit": "23ffe2cf4b214666754a2420558943438e54251a", + "packaged_file_count": 80, + "source_file_count": 80, + "different_files": 0, + "all_packaged_source_bytes_match": true + } + ], + "actual_packaged_manifest_sha256": "6b5a7b339d88f3c5eafb70a33aa28a7d3972988645b246ae1a92a3f159d72528", + "dependency_or_build_reproducibility_proved": false +} diff --git a/docs/release/identity-export-candidate-recovery-2026-10-31.json b/docs/release/identity-export-candidate-recovery-2026-10-31.json new file mode 100644 index 0000000..6714caf --- /dev/null +++ b/docs/release/identity-export-candidate-recovery-2026-10-31.json @@ -0,0 +1,63 @@ +{ + "schema": "coulomb.packaged-identity-export-recovery.v1", + "status": "packaged_recovered_client_export_and_views_verified", + "source": "23ffe2cf4b214666754a2420558943438e54251a", + "image_id": "sha256:522bcd7fce92436765a60c1e4afa2598f3cc40913352153ff1c4319a99ca92ed", + "restore_receipt_sha256": "b648348780f87f81094b40876a6b0ebabaefff7986cf20fb426c3d7456a0bc84", + "client_export": { + "status": "recovered_client_export_verified", + "schema": "coulomb.client-dataset-export.v1", + "content_files": 85, + "records": { + "members.user": 1, + "members.member": 1, + "spaces.space": 1, + "spaces.spacemembership": 1 + }, + "admin_events": 0, + "archive_sha256": "8efa82e7c29c95840d61d1290e20cac4b8acf5ae33d2c5b632382a7f6b779c37", + "offboarding_complete": false, + "all_source_tables_compared": 13, + "all_source_files_compared": 86, + "archive_member_hashes_verified": true, + "selected_client_content_complete_locally": true, + "source_sql_and_content_unchanged": true, + "external_bindings_require_review": 0, + "sessions_and_credentials_excluded": true + }, + "candidate_application": { + "status": "isolated_application_recovery_verified", + "recovered_spaces_with_content": 1, + "actual_pages_rendered_through_view": 40, + "restored_owner_access_verified": true, + "synthetic_viewer_reads": 1, + "synthetic_viewer_mutation_denials": 1, + "same_tenant_ungranted_page_denials": 40, + "fixture_transaction_rolled_back": true, + "production_access": false, + "external_identity_provider_used": false, + "real_browser_journey_verified": false + }, + "previous_image_application": { + "status": "isolated_application_recovery_verified", + "recovered_spaces_with_content": 1, + "actual_pages_rendered_through_view": 40, + "restored_owner_access_verified": true, + "synthetic_viewer_reads": 1, + "synthetic_viewer_mutation_denials": 1, + "same_tenant_ungranted_page_denials": 40, + "fixture_transaction_rolled_back": true, + "production_access": false, + "external_identity_provider_used": false, + "real_browser_journey_verified": false + }, + "source_content_files_unchanged": 86, + "application_source_overlay": false, + "export_archive_removed": true, + "network_internal": true, + "published_ports": 0, + "production_access": false, + "production_restore": false, + "post_date_correction_data_claimed": false, + "driver_sha256": "9c370b6e7e1acb442cb660cc3709e3ffd3676c87419a217a7656174c8a347f95" +} diff --git a/docs/release/identity-export-candidate-review-2026-10-31.md b/docs/release/identity-export-candidate-review-2026-10-31.md new file mode 100644 index 0000000..97824af --- /dev/null +++ b/docs/release/identity-export-candidate-review-2026-10-31.md @@ -0,0 +1,80 @@ +# Identity binding and client export release candidate + +Candidate source: `23ffe2cf4b214666754a2420558943438e54251a`. +Published image: +`forgejo.coulomb.social/coulomb/coulomb-social@sha256:522bcd7fce92436765a60c1e4afa2598f3cc40913352153ff1c4319a99ca92ed`. +Commit tag: `23ffe2cf4b21`. + +The registry digest was independently read back after publication. All 80 +packaged source files match that exact Git commit, and the image's OCI revision +label matches it. The build used a clean Git archive containing only the Docker +build inputs. Python is 3.12.16 and all 25 installed Python distribution versions +match the existing live image. This does not establish byte-for-byte dependency +or OS-layer reproducibility. + +## Changes from the live image + +- OIDC callbacks require a verified ID token. Optional UserInfo must identify + the same subject and can enrich only name, email and preferred username. + UserInfo cannot replace identity, tenant or assurance assertions. The valid + ID-token fallback for an unavailable UserInfo endpoint remains supported. +- The operator client-data export includes attributable application records, + grants, content, assets, aliases and retained revisions, with schema inventory + and explicit refusal of ambiguous ownership or source drift. It excludes + credentials and does not delete or offboard anything. +- The previously reviewed date-backfill planning/journal/operation modules are + packaged. They do not run on startup. Their presence does not authorize another + correction or replay of the completed founder operation. + +There are no new database migrations. The additional `jsonschema` dependency is +development-only; installed runtime Python packages are unchanged. The Dockerfile +and application entrypoint are unchanged. Existing live release-unit pins still +identify revision 18/image `51281946…`. + +## Packaged verification + +The source commit's full `make check` gate passed 441 tests, including required +browser journeys. The candidate then passed 25 focused OIDC/export tests with +zero failures or skips inside its own read-only, network-disabled container. +Only test tooling and fixtures were supplied externally; application imports and +their hashes were verified inside `/app`. No application-source overlay was used. +Packaged Django checks and migration-drift checks also pass. + +The candidate was then run on the retained isolated PostgreSQL/content recovery +from the October 30 23:50 point. Its client export contains all 85 selected local +content/revision files and the four attributable application record sets, with +every member hash checked. All 13 source tables and 86 source files remain +unchanged; the temporary private ZIP was removed. This recovered scope has no +external bindings or attributable admin history. + +Actual candidate views render all 40 recovered pages for the owner and deny all +40 to an unsaved same-tenant outsider. Synthetic viewer read/mutation checks pass +and their transaction rolls back. The existing live image passes the same view +checks on the same retained store, supporting image rollback compatibility. +The network is internal, has no published ports and contains only the retained +database after test containers exit. This is not a production restore or a +productive browser/identity acceptance result. + +The retained point predates the founder's date correction. The rehearsal proves +packaged export/view behavior on that point, not current-target export acceptance +or a fresh rollback baseline. It does not replace the source-exception review, +productive journey verdicts or client offboarding contract. + +## Remaining deployment work + +Prepare a separate exact image-only release packet against the current revision +18 and post-correction data, with current owner values, fresh paired rollback +evidence, unchanged-data postflight, candidate and rollback checks, and the +snapshot helper's next image pin. The old storage launcher explicitly requires +the migration-0003 baseline to be absent. It is a completed historical operation +and must not be reused for this already-migrated database. + +The deployment owner's supervised execution boundary remains applicable. No +founder command is requested by this candidate evidence: the new execution packet +is not yet complete. No Helm release, installed helper, identity, grant, timer, +sender, apex record or production data was changed here. + +Evidence: `identity-export-candidate-build`, `-provenance`, `-tests` and `-recovery` +JSON files dated 2026-10-31, plus the source manifest. The two bounded verification +drivers are retained at the paths recorded in that manifest; their hashes bind +the executed checks. The recovery proof contains counts and hashes only. diff --git a/docs/release/identity-export-candidate-tests-2026-10-31.json b/docs/release/identity-export-candidate-tests-2026-10-31.json new file mode 100644 index 0000000..bda3298 --- /dev/null +++ b/docs/release/identity-export-candidate-tests-2026-10-31.json @@ -0,0 +1,17 @@ +{ + "schema": "coulomb.packaged-identity-export-tests.v1", + "source": "23ffe2cf4b214666754a2420558943438e54251a", + "image_id": "sha256:522bcd7fce92436765a60c1e4afa2598f3cc40913352153ff1c4319a99ca92ed", + "tests": 25, + "failures": 0, + "errors": 0, + "skipped": 0, + "network": "none", + "read_only_root": true, + "application_source_overlay": false, + "test_tooling_injected": true, + "application_modules_from_image_verified": true, + "production_access": false, + "junit_sha256": "85aac22d33a101d68e478f41f61bc3c7e7adb4f3d7f893a2810f7eb25fce5a39", + "driver_sha256": "a19f94f3dbc71dfd80a2d380f03e5f737c7453b64df022b6e5c2ede8141976b3" +} diff --git a/workplans/CSOC-WP-0012-durable-recovery-service-readiness.md b/workplans/CSOC-WP-0012-durable-recovery-service-readiness.md index bc4fc86..1072fd4 100644 --- a/workplans/CSOC-WP-0012-durable-recovery-service-readiness.md +++ b/workplans/CSOC-WP-0012-durable-recovery-service-readiness.md @@ -398,6 +398,19 @@ service execution remain open. Requested the missing receiver/response-owner information; no notification was sent. Existing schedule/custody approvals remain valid. No installed helper, unit, timer, data or task acceptance changed. +2026-10-31 packaged client-export candidate: built/published exact source 23ffe2c +at immutable digest 522bcd7f, with independently read-back registry digest and +all 80 packaged files matching Git. Its actual packaged exporter, without an app +source overlay, exports all 85 selected content/revision files on the retained +October 30 recovery point; all 13 tables/86 source files remain unchanged and the +temporary ZIP is removed. Candidate and existing image each render 40 owner pages +and deny 40 outsider requests. All 25 packaged identity/export tests pass; source +gate 441 passes. See docs/release/identity-export-candidate-review-2026-10-31.md. +This is not a current post-date-correction export or live release. A separate +revision 18 image-only execution packet/fresh paired rollback return is required; +the old migration launcher must not be replayed. §6.2 teardown/session/log/backup +expiry and productive offboarding acceptance remain open. + ## 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. diff --git a/workplans/CSOC-WP-0015-communication-runtime-acceptance.md b/workplans/CSOC-WP-0015-communication-runtime-acceptance.md index dbd4626..983e002 100644 --- a/workplans/CSOC-WP-0015-communication-runtime-acceptance.md +++ b/workplans/CSOC-WP-0015-communication-runtime-acceptance.md @@ -140,6 +140,17 @@ Full `make check`:396 passed, zero skips. Four separate synthetic JUnit-envelope checks refuse wrong/skipped/failed/extra nodes without publishing a proof; the real native gate itself passes its exact one node with zero skips. +2026-10-31 packaged OIDC fix: candidate source 23ffe2c is published at immutable +digest 522bcd7f and independently verified against the registry and all 80 packaged +source files. All 25 OIDC/export focused tests pass inside that image, with actual +packaged application imports, no source overlay, network none and synthetic +identity peers. Python and all 25 runtime distribution versions match the live +image. Source full gate 441 passes; recovered-store candidate/previous-image view +checks also pass. Review: docs/release/identity-export-candidate-review-2026-10-31.md. +The fix remains undeployed pending its separate exact current-target release +packet and supervised execution. Native owner/productive verdicts, sender and +inbox ownership remain open; this image publication grants no such acceptance. + ## 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.