Prepare attended Coulomb editor attachment visibility release
Assistant: codex Assistant-Model: gpt-6-astra Assistant-Session: 01a192e9-c28b-7533-bf25-e2341364c22a
This commit is contained in:
parent
b39910e330
commit
979b7819df
15 changed files with 1002 additions and 0 deletions
|
|
@ -44,6 +44,7 @@
|
|||
| task | RAPPS-WP-0015-T05 | done | — | workplans/RAPPS-WP-0015-coulomb-personal-content-release.md |
|
||||
| task | RAPPS-WP-0015-T06 | done | — | workplans/RAPPS-WP-0015-coulomb-personal-content-release.md |
|
||||
| task | RAPPS-WP-0015-T07 | done | — | workplans/RAPPS-WP-0015-coulomb-personal-content-release.md |
|
||||
| task | RAPPS-WP-0015-T08 | wait | — | workplans/RAPPS-WP-0015-coulomb-personal-content-release.md |
|
||||
| task | RAPPS-WP-0016-T01 | done | — | workplans/RAPPS-WP-0016-forgejo-netkingdom-login.md |
|
||||
| task | RAPPS-WP-0016-T02 | wait | — | workplans/RAPPS-WP-0016-forgejo-netkingdom-login.md |
|
||||
| task | RAPPS-WP-0016-T03 | wait | — | workplans/RAPPS-WP-0016-forgejo-netkingdom-login.md |
|
||||
|
|
|
|||
77
release/coulomb-editor-attachments-31eaa58.json
Normal file
77
release/coulomb-editor-attachments-31eaa58.json
Normal file
|
|
@ -0,0 +1,77 @@
|
|||
{
|
||||
"schema": "coulomb.reviewed-image-release.v1",
|
||||
"proposal_id": "CSOC-EDITOR-ATTACHMENTS-20261031",
|
||||
"scope": "ADMINISTER @ realm:kubernetes/railiance01; supervised founder execution only",
|
||||
"operation": "image_only_existing_migration_0003",
|
||||
"cluster_uid": "a553c742-0115-43d4-99a4-a5ca56fe0786",
|
||||
"baseline_revision": 20,
|
||||
"baseline_helm_manifest_sha256": "e388f62c97e97d54d87671825bd0b05c854a70b0cca8a00faee452ae7841799e",
|
||||
"candidate_render_sha256": "78ee8e0a73f87e1152b6f826029ed85385b6293c61a1cdab7171b6c6e40580bc",
|
||||
"deployment_uid": "2dbe661a-d232-4477-bbd1-833813077fbe",
|
||||
"pvc_uid": "9888abeb-9d52-4c70-a23d-b5494780d9c3",
|
||||
"baseline_spec_sha256": "8d79c64cff4bd2c62f03494e80847dc99b965ddabf35645da67e8d1020220798",
|
||||
"candidate_spec_sha256": "4deab26fc15d63e09922259b3362cd4e5c6bfa10884de058f776c0de8b642b00",
|
||||
"old_image": "forgejo.coulomb.social/coulomb/coulomb-social@sha256:7906f461bc8d2d5204fd4fde67a251850f725b914452a66172919d6853672ed5",
|
||||
"candidate_image": "forgejo.coulomb.social/coulomb/coulomb-social@sha256:b58d858abd5b4acbd6b893c3f622f7a9fdb5e606164ab9866eb3cfaa04df1a0e",
|
||||
"product_source": "31eaa581a65e454b6ef9979326c5bdfe10e13806",
|
||||
"expected_data": {
|
||||
"business_tables": 12,
|
||||
"migration_rows_sha256": "43471516387c0e2a3d35971033ed6af330e2963efe4da93293d97633825d04af",
|
||||
"business_rows": 97,
|
||||
"business_rows_sha256": "35b0ae7d9dd1ff21c2ceaa04649162545ec36a2c68629548238352d9cd0fb303",
|
||||
"content_files": 98,
|
||||
"content_files_sha256": "b657c0e470399b6c7500da500cbbec061bea12ab9633bd74e2f142d797b2d26a",
|
||||
"global_slug_constraint": true,
|
||||
"tenant_slug_constraint": true,
|
||||
"migration_0003_applied": true,
|
||||
"duplicate_slug_groups": 0
|
||||
},
|
||||
"public_recipient": "age1qm30jk8q0cezey652dk2dhcr3d9vs528v6lg8mavl6d4q3e3vgnqmrmyy3",
|
||||
"installed_helper_hashes": {
|
||||
"/opt/coulomb-social-backup/paired-backup.py": "d161c742d1a6a182460a57d0a1719591ab58fc94006f55169ad3d74442a93630",
|
||||
"/opt/coulomb-social-backup/snapshot-content-and-db.py": "23f92c96b840df61f92858004241e860e0ddb32ed6fd7448294d3c8278906e46",
|
||||
"/opt/coulomb-social-backup/mirror-paired-backup.py": "9ceb26d9083af016c4b787907e4dce7bdf437c782fb2d15eb28d9e334e6e431c",
|
||||
"/opt/coulomb-social-backup/check-paired-backup-health.py": "2d40ec6e4c59ea7fe1d46065d197b9a87ca6811f023cc6f3e20e4184a3490566",
|
||||
"/opt/coulomb-social-backup/backup_capacity.py": "cb699a79e67b129239b5aa5d6f3b0d4ffaa9773a8b073227ad17fdecb5b9d893",
|
||||
"/opt/railiance-platform/scripts/application_recovery_identities.py": "20f56255ed6eeec4aafe33f142bc3ee03f623d4957a7b0cabb741d340f15f79d",
|
||||
"/opt/railiance-platform/scripts/application_recovery_mirror.py": "d48ab95e89b9eeae36269d853ebe4c44c22e1f57d4e14224f03d0b9aeeb34178",
|
||||
"/opt/railiance-platform/scripts/application_recovery_resources.py": "ab70ec341e738272730eb0daf76840d0bca807caeb3c4e4c2357f162fbed4498",
|
||||
"/opt/railiance-platform/scripts/primary_application_archive.py": "a3f0a61e869a6012edb4b5288be14e3b0c4a9a1273b090320ab146d12e5aa94d",
|
||||
"/opt/coulomb-social-backup/backup_alerts.py": "07522437d4276b92f0a44149adc6c9e81bb18dbe59ce0f1f9e58a48347700d0e",
|
||||
"/opt/coulomb-social-backup/notify-backup-alert.py": "0bd53bc5ad22d8bcb0326fb18a17737744b06416fe785dad077308e45f051d5a",
|
||||
"/opt/coulomb-social-backup/observe-backup-alerts.py": "17caf4fa65283242f618b039ff1d018801c9890ea2a9178912cbdd4b50ee2664"
|
||||
},
|
||||
"clipboard_static_sha256": "347eabe0c8d93bf439df02b5a08a7ea71004600e6ff4e8a42cecbee52a9f0413",
|
||||
"fresh_backup_before_helm": true,
|
||||
"requires_dataset_equality_before_and_after": true,
|
||||
"node_request_percent_limit": 90,
|
||||
"helm_atomic_timeout_seconds": 300,
|
||||
"rollback": "Restore Helm revision20/image7906f461 and verified snapshot pin, preserving all data; no production restore or schema downgrade.",
|
||||
"approval_status": "prepared_not_admitted",
|
||||
"recovery_rehearsal_scope": "Candidate and previous image verified against independently recovered 2026-10-31T20:21:01Z point:13tables/86files unchanged,40owner views/40outsider denials,85export files verified. Current97-row/98-file baseline adds2spaces/2memberships/12files from productive acceptance; all prior rows and86files are unchanged. Fresh paired capture/readback before Helm and independent recovery afterward remain required.",
|
||||
"rehearsal_evidence_sha256": {
|
||||
"editor-attachments-build-2026-10-31.json": "bb58b2fe23d101ab82ee0b210cc8f552f3667c785bd0207b1e1656b0577c106d",
|
||||
"editor-attachments-provenance-2026-10-31.json": "3d4ec97702c5165af2198da4c4563cba204355480f5036fd22c48b9e3c300ba3",
|
||||
"editor-attachments-tests-2026-10-31.json": "59d2d121befa7a8c3853fc89172bad5ce2abad1c1615cc2f2bea550f4d68a62d",
|
||||
"editor-attachments-recovery-2026-10-31.json": "af68f6e86c0b3291d4ad880717c36eb95f1592f78d3c65596dd9cecd10755052",
|
||||
"editor-attachments-target-2026-10-31.json": "b6d767ecb93b4638ca77a5052dcf3aab8a95dee922d3927956ad578290f9e58f",
|
||||
"editor-attachments-baseline-change-2026-10-31.json": "db79f2838b88281c562b36996e74694c2a98e113c962b46eab0ef2cf69dd3b8c",
|
||||
"editor-attachments-validation-2026-10-31.json": "427e228a9f2763cd583496d65e21b7599ef5e0df074dc507277ce2051169f562",
|
||||
"backup-route-independent-return-2026-10-31.json": "3a3feb56c1af7e3db7b0f2380ec355bb465663073c0a0160034a35984ef23f6e",
|
||||
"backup-installation-independent-return-2026-10-31.json": "2fe1972f4db0ba2468027f4926cd8111d6aa4b61d404592eda794b47733ce0df",
|
||||
"content-acceptance-independent-postflight-2026-10-31.json": "6a8a4056b143011c50af24dd31d6338d00892bfe626666f85e607d86562dfe7c"
|
||||
},
|
||||
"new_resources_committed": 0,
|
||||
"autopilot_or_eur_budget_claimed": false,
|
||||
"values_file": "release/editor-attachments-values.yaml",
|
||||
"snapshot_file": "release/editor-attachments-snapshot.py",
|
||||
"evidence_directory": "release/editor-attachments-evidence",
|
||||
"prerequisite_installation_digest": "sha256:8f442bf0ebed8bbf3b7f227b52081df52613f3f5f6874c4a59511cfc2ba06d42",
|
||||
"requires_inactive_backup_units": true,
|
||||
"product_changes": [
|
||||
"Show saved attachments and downloads in editor tabs",
|
||||
"Keep attachment list and submitted text after stale edit refusal",
|
||||
"Open attachment management in a separate tab to preserve unsaved editor text"
|
||||
],
|
||||
"product_decision": "Productive review feedback: attachments present on original but absent from editing tabs."
|
||||
}
|
||||
|
|
@ -0,0 +1,371 @@
|
|||
{
|
||||
"schema": "coulomb.backup-installation-independent-postflight.v1",
|
||||
"verified_at": "2026-10-31T17:30:18.219708+00:00",
|
||||
"status": "installed_files_and_inactive_units_verified",
|
||||
"proposal_digest": "sha256:8f442bf0ebed8bbf3b7f227b52081df52613f3f5f6874c4a59511cfc2ba06d42",
|
||||
"receipt_sha256": "96329afbd5662f71bf6d6b05c003f0810be12c10036f9cadb41cc373d3a1108b",
|
||||
"receipt": {
|
||||
"schema": "coulomb.backup-source-supervised-installation.v1",
|
||||
"proposal_digest": "sha256:8f442bf0ebed8bbf3b7f227b52081df52613f3f5f6874c4a59511cfc2ba06d42",
|
||||
"status": "sources_installed_units_inactive_verified",
|
||||
"preflight": {
|
||||
"units": {
|
||||
"coulomb-social-paired-backup.service": {
|
||||
"LoadState": "not-found",
|
||||
"ActiveState": "inactive",
|
||||
"SubState": "dead",
|
||||
"FragmentPath": "",
|
||||
"UnitFileState": ""
|
||||
},
|
||||
"coulomb-social-paired-backup.timer": {
|
||||
"LoadState": "not-found",
|
||||
"ActiveState": "inactive",
|
||||
"SubState": "dead",
|
||||
"FragmentPath": "",
|
||||
"UnitFileState": ""
|
||||
},
|
||||
"coulomb-social-backup-freshness.service": {
|
||||
"LoadState": "not-found",
|
||||
"ActiveState": "inactive",
|
||||
"SubState": "dead",
|
||||
"FragmentPath": "",
|
||||
"UnitFileState": ""
|
||||
},
|
||||
"coulomb-social-backup-freshness.timer": {
|
||||
"LoadState": "not-found",
|
||||
"ActiveState": "inactive",
|
||||
"SubState": "dead",
|
||||
"FragmentPath": "",
|
||||
"UnitFileState": ""
|
||||
},
|
||||
"coulomb-social-backup-alert@coulomb-social-paired-backup.service.service": {
|
||||
"LoadState": "not-found",
|
||||
"ActiveState": "inactive",
|
||||
"SubState": "dead",
|
||||
"FragmentPath": "",
|
||||
"UnitFileState": ""
|
||||
}
|
||||
},
|
||||
"capacity": {
|
||||
"state_bytes": 11259904,
|
||||
"state_reserve_bytes": 7532969984,
|
||||
"disk_reserve_bytes": 8606711808,
|
||||
"free_bytes": 115579949056,
|
||||
"free_inodes": 24523113,
|
||||
"filesystem_blocks_reserved": false
|
||||
},
|
||||
"sdk": {
|
||||
"boto3": "1.40.18",
|
||||
"botocore": "1.40.76"
|
||||
},
|
||||
"route": {
|
||||
"helm_revision": 6,
|
||||
"runtime_and_complete_resources_verified": true
|
||||
}
|
||||
},
|
||||
"timers_activated": false,
|
||||
"capture_executed": false,
|
||||
"email_sent": false,
|
||||
"retained_data_deleted": false,
|
||||
"started_at": "2026-10-31T17:22:48.757530+00:00",
|
||||
"capacity_profile": {
|
||||
"maximum_new_file_bytes": 1073741824,
|
||||
"state_budget_bytes": 8589934592,
|
||||
"minimum_free_bytes": 8589934592,
|
||||
"minimum_free_inodes": 1024,
|
||||
"control_margin_bytes": 16777216
|
||||
},
|
||||
"founder_confirmed_profile_and_installation": true,
|
||||
"route_postflight": {
|
||||
"helm_revision": 6,
|
||||
"runtime_and_complete_resources_verified": true
|
||||
},
|
||||
"verified_targets": 19,
|
||||
"units": {
|
||||
"coulomb-social-paired-backup.service": {
|
||||
"LoadState": "loaded",
|
||||
"ActiveState": "inactive",
|
||||
"SubState": "dead",
|
||||
"FragmentPath": "/etc/systemd/system/coulomb-social-paired-backup.service",
|
||||
"UnitFileState": "static"
|
||||
},
|
||||
"coulomb-social-paired-backup.timer": {
|
||||
"LoadState": "loaded",
|
||||
"ActiveState": "inactive",
|
||||
"SubState": "dead",
|
||||
"FragmentPath": "/etc/systemd/system/coulomb-social-paired-backup.timer",
|
||||
"UnitFileState": "disabled"
|
||||
},
|
||||
"coulomb-social-backup-freshness.service": {
|
||||
"LoadState": "loaded",
|
||||
"ActiveState": "inactive",
|
||||
"SubState": "dead",
|
||||
"FragmentPath": "/etc/systemd/system/coulomb-social-backup-freshness.service",
|
||||
"UnitFileState": "static"
|
||||
},
|
||||
"coulomb-social-backup-freshness.timer": {
|
||||
"LoadState": "loaded",
|
||||
"ActiveState": "inactive",
|
||||
"SubState": "dead",
|
||||
"FragmentPath": "/etc/systemd/system/coulomb-social-backup-freshness.timer",
|
||||
"UnitFileState": "disabled"
|
||||
},
|
||||
"coulomb-social-backup-alert@coulomb-social-paired-backup.service.service": {
|
||||
"LoadState": "loaded",
|
||||
"ActiveState": "inactive",
|
||||
"SubState": "dead",
|
||||
"FragmentPath": "/etc/systemd/system/coulomb-social-backup-alert@.service",
|
||||
"UnitFileState": "static"
|
||||
}
|
||||
},
|
||||
"updated_at": "2026-10-31T17:22:54.560675+00:00"
|
||||
},
|
||||
"nested_receipt_sha256": "795d9eb672b24495c77ad636a210c5d2022c8c3124d276920db7eda02257e519",
|
||||
"verified_targets": 19,
|
||||
"installed_fingerprints": {
|
||||
"/opt/coulomb-social-backup/paired-backup.py": {
|
||||
"exists": true,
|
||||
"sha256": "d161c742d1a6a182460a57d0a1719591ab58fc94006f55169ad3d74442a93630",
|
||||
"mode": 384,
|
||||
"uid": 0,
|
||||
"gid": 0,
|
||||
"inode": 534009,
|
||||
"device": 2049,
|
||||
"mtime_ns": 1793467368826077309
|
||||
},
|
||||
"/opt/coulomb-social-backup/snapshot-content-and-db.py": {
|
||||
"exists": true,
|
||||
"sha256": "dcc8dd2a3989f279597595f9260b31b24fcc9b6dc787f04c17ef0491c53d830d",
|
||||
"mode": 384,
|
||||
"uid": 0,
|
||||
"gid": 0,
|
||||
"inode": 549255,
|
||||
"device": 2049,
|
||||
"mtime_ns": 1793430923413704430
|
||||
},
|
||||
"/opt/coulomb-social-backup/mirror-paired-backup.py": {
|
||||
"exists": true,
|
||||
"sha256": "9ceb26d9083af016c4b787907e4dce7bdf437c782fb2d15eb28d9e334e6e431c",
|
||||
"mode": 384,
|
||||
"uid": 0,
|
||||
"gid": 0,
|
||||
"inode": 549201,
|
||||
"device": 2049,
|
||||
"mtime_ns": 1793467368831077393
|
||||
},
|
||||
"/opt/coulomb-social-backup/check-paired-backup-health.py": {
|
||||
"exists": true,
|
||||
"sha256": "2d40ec6e4c59ea7fe1d46065d197b9a87ca6811f023cc6f3e20e4184a3490566",
|
||||
"mode": 384,
|
||||
"uid": 0,
|
||||
"gid": 0,
|
||||
"inode": 549309,
|
||||
"device": 2049,
|
||||
"mtime_ns": 1793467368836077477
|
||||
},
|
||||
"/opt/coulomb-social-backup/backup_capacity.py": {
|
||||
"exists": true,
|
||||
"sha256": "cb699a79e67b129239b5aa5d6f3b0d4ffaa9773a8b073227ad17fdecb5b9d893",
|
||||
"mode": 384,
|
||||
"uid": 0,
|
||||
"gid": 0,
|
||||
"inode": 549354,
|
||||
"device": 2049,
|
||||
"mtime_ns": 1793467368843077594
|
||||
},
|
||||
"/opt/coulomb-social-backup/mirror-platform-runtime.json": {
|
||||
"exists": true,
|
||||
"sha256": "9253c5f6e956b67f499d3e12d2851be7fabd3bc56b00496b8810bbd0be8209f1",
|
||||
"mode": 384,
|
||||
"uid": 0,
|
||||
"gid": 0,
|
||||
"inode": 549355,
|
||||
"device": 2049,
|
||||
"mtime_ns": 1793467368847077662
|
||||
},
|
||||
"/opt/coulomb-social-backup/backup_alerts.py": {
|
||||
"exists": true,
|
||||
"sha256": "07522437d4276b92f0a44149adc6c9e81bb18dbe59ce0f1f9e58a48347700d0e",
|
||||
"mode": 384,
|
||||
"uid": 0,
|
||||
"gid": 0,
|
||||
"inode": 549359,
|
||||
"device": 2049,
|
||||
"mtime_ns": 1793467368887078332
|
||||
},
|
||||
"/opt/coulomb-social-backup/notify-backup-alert.py": {
|
||||
"exists": true,
|
||||
"sha256": "0bd53bc5ad22d8bcb0326fb18a17737744b06416fe785dad077308e45f051d5a",
|
||||
"mode": 384,
|
||||
"uid": 0,
|
||||
"gid": 0,
|
||||
"inode": 549360,
|
||||
"device": 2049,
|
||||
"mtime_ns": 1793467368891078399
|
||||
},
|
||||
"/opt/coulomb-social-backup/observe-backup-alerts.py": {
|
||||
"exists": true,
|
||||
"sha256": "17caf4fa65283242f618b039ff1d018801c9890ea2a9178912cbdd4b50ee2664",
|
||||
"mode": 384,
|
||||
"uid": 0,
|
||||
"gid": 0,
|
||||
"inode": 549361,
|
||||
"device": 2049,
|
||||
"mtime_ns": 1793467368895078466
|
||||
},
|
||||
"/opt/railiance-platform/scripts/application_recovery_identities.py": {
|
||||
"exists": true,
|
||||
"sha256": "20f56255ed6eeec4aafe33f142bc3ee03f623d4957a7b0cabb741d340f15f79d",
|
||||
"mode": 384,
|
||||
"uid": 0,
|
||||
"gid": 0,
|
||||
"inode": 549356,
|
||||
"device": 2049,
|
||||
"mtime_ns": 1793467368852077745
|
||||
},
|
||||
"/opt/railiance-platform/scripts/application_recovery_mirror.py": {
|
||||
"exists": true,
|
||||
"sha256": "d48ab95e89b9eeae36269d853ebe4c44c22e1f57d4e14224f03d0b9aeeb34178",
|
||||
"mode": 384,
|
||||
"uid": 0,
|
||||
"gid": 0,
|
||||
"inode": 549357,
|
||||
"device": 2049,
|
||||
"mtime_ns": 1793467368857077829
|
||||
},
|
||||
"/opt/railiance-platform/scripts/application_recovery_resources.py": {
|
||||
"exists": true,
|
||||
"sha256": "ab70ec341e738272730eb0daf76840d0bca807caeb3c4e4c2357f162fbed4498",
|
||||
"mode": 384,
|
||||
"uid": 0,
|
||||
"gid": 0,
|
||||
"inode": 549358,
|
||||
"device": 2049,
|
||||
"mtime_ns": 1793467368862077913
|
||||
},
|
||||
"/opt/railiance-platform/scripts/primary_application_archive.py": {
|
||||
"exists": true,
|
||||
"sha256": "a3f0a61e869a6012edb4b5288be14e3b0c4a9a1273b090320ab146d12e5aa94d",
|
||||
"mode": 420,
|
||||
"uid": 0,
|
||||
"gid": 0,
|
||||
"inode": 540610,
|
||||
"device": 2049,
|
||||
"mtime_ns": 1791537447437616251
|
||||
},
|
||||
"/etc/systemd/system/coulomb-social-backup-freshness.service": {
|
||||
"exists": true,
|
||||
"sha256": "8d6278c2cbca7f48b659c239c1d1e181fa4b9cf023fe7429850e294c6cd84d0e",
|
||||
"mode": 420,
|
||||
"uid": 0,
|
||||
"gid": 0,
|
||||
"inode": 19366,
|
||||
"device": 2049,
|
||||
"mtime_ns": 1793467368868078014
|
||||
},
|
||||
"/etc/systemd/system/coulomb-social-paired-backup.service": {
|
||||
"exists": true,
|
||||
"sha256": "8b01b788bb08f453fdd4807104185c89411e0b0b4dedee9240f14f110ceb5513",
|
||||
"mode": 420,
|
||||
"uid": 0,
|
||||
"gid": 0,
|
||||
"inode": 14867,
|
||||
"device": 2049,
|
||||
"mtime_ns": 1793467368873078098
|
||||
},
|
||||
"/etc/systemd/system/coulomb-social-backup-freshness.timer": {
|
||||
"exists": true,
|
||||
"sha256": "75d1d0721c07fdd0703910c06bb8a678396440e7d95411a37ee7de4938f3ac31",
|
||||
"mode": 420,
|
||||
"uid": 0,
|
||||
"gid": 0,
|
||||
"inode": 19367,
|
||||
"device": 2049,
|
||||
"mtime_ns": 1793467368878078181
|
||||
},
|
||||
"/etc/systemd/system/coulomb-social-paired-backup.timer": {
|
||||
"exists": true,
|
||||
"sha256": "5e87235e66f89a64a972562d6f163f62420628fc44fb7fd8d603a96c347dfbb9",
|
||||
"mode": 420,
|
||||
"uid": 0,
|
||||
"gid": 0,
|
||||
"inode": 19368,
|
||||
"device": 2049,
|
||||
"mtime_ns": 1793467368882078248
|
||||
},
|
||||
"/etc/systemd/system/coulomb-social-backup-alert@.service": {
|
||||
"exists": true,
|
||||
"sha256": "4bfa019d29b1d0de278f03553602a5e824de50ed99ebcf3b5035cf4d5b06fe98",
|
||||
"mode": 420,
|
||||
"uid": 0,
|
||||
"gid": 0,
|
||||
"inode": 19370,
|
||||
"device": 2049,
|
||||
"mtime_ns": 1793467368899078533
|
||||
},
|
||||
"/etc/coulomb-social-backup/alerting.env": {
|
||||
"exists": true,
|
||||
"sha256": "509844b5c8ef618b812d52f32e19c3c559623636dca62f7b16f437aa90cc0458",
|
||||
"mode": 384,
|
||||
"uid": 0,
|
||||
"gid": 0,
|
||||
"inode": 19369,
|
||||
"device": 2049,
|
||||
"mtime_ns": 1793467368904078617
|
||||
}
|
||||
},
|
||||
"units": {
|
||||
"coulomb-social-paired-backup.service": {
|
||||
"LoadState": "loaded",
|
||||
"ActiveState": "inactive",
|
||||
"SubState": "dead",
|
||||
"FragmentPath": "/etc/systemd/system/coulomb-social-paired-backup.service",
|
||||
"UnitFileState": "static"
|
||||
},
|
||||
"coulomb-social-paired-backup.timer": {
|
||||
"LoadState": "loaded",
|
||||
"ActiveState": "inactive",
|
||||
"SubState": "dead",
|
||||
"FragmentPath": "/etc/systemd/system/coulomb-social-paired-backup.timer",
|
||||
"UnitFileState": "disabled"
|
||||
},
|
||||
"coulomb-social-backup-freshness.service": {
|
||||
"LoadState": "loaded",
|
||||
"ActiveState": "inactive",
|
||||
"SubState": "dead",
|
||||
"FragmentPath": "/etc/systemd/system/coulomb-social-backup-freshness.service",
|
||||
"UnitFileState": "static"
|
||||
},
|
||||
"coulomb-social-backup-freshness.timer": {
|
||||
"LoadState": "loaded",
|
||||
"ActiveState": "inactive",
|
||||
"SubState": "dead",
|
||||
"FragmentPath": "/etc/systemd/system/coulomb-social-backup-freshness.timer",
|
||||
"UnitFileState": "disabled"
|
||||
},
|
||||
"coulomb-social-backup-alert@coulomb-social-paired-backup.service.service": {
|
||||
"LoadState": "loaded",
|
||||
"ActiveState": "inactive",
|
||||
"SubState": "dead",
|
||||
"FragmentPath": "/etc/systemd/system/coulomb-social-backup-alert@.service",
|
||||
"UnitFileState": "static"
|
||||
}
|
||||
},
|
||||
"route": {
|
||||
"helm_revision": 6,
|
||||
"runtime_and_complete_resources_verified": true
|
||||
},
|
||||
"capacity": {
|
||||
"state_bytes": 11259904,
|
||||
"state_reserve_bytes": 7532969984,
|
||||
"disk_reserve_bytes": 8606711808,
|
||||
"free_bytes": 115555618816,
|
||||
"free_inodes": 24523041,
|
||||
"filesystem_blocks_reserved": false
|
||||
},
|
||||
"sdk": {
|
||||
"boto3": "1.40.18",
|
||||
"botocore": "1.40.76"
|
||||
},
|
||||
"runtime_modified_by_verification": false
|
||||
}
|
||||
|
|
@ -0,0 +1,29 @@
|
|||
{
|
||||
"schema": "coulomb.backup-route-independent-postflight.v1",
|
||||
"verified_at": "2026-10-31T17:19:36.926769+00:00",
|
||||
"status": "durable_receipt_and_live_route_verified",
|
||||
"execution_digest": "sha256:4d8481061dc9ce6835169defc96887945052332a0db8d4234ae84032d63cc328",
|
||||
"receipt": {
|
||||
"schema": "rapp-telemetry.backup-route-execution.v1",
|
||||
"execution_digest": "sha256:4d8481061dc9ce6835169defc96887945052332a0db8d4234ae84032d63cc328",
|
||||
"proposal_digest": "sha256:4bcad54f7b8e1e77b94112e452cbb58eaf8e882dc10305129c5f9ca69f014a66",
|
||||
"status": "backup_email_route_deployed_verified",
|
||||
"timers_activated": false,
|
||||
"notification_sent_by_helper": false,
|
||||
"production_data_restored": false,
|
||||
"started_at": "2026-10-31T17:17:13.743344+00:00",
|
||||
"helm_revision": 6,
|
||||
"verified_resource_count": 87,
|
||||
"after_resources_sha256": "600c4998e54b8e11845849c7d8e4c6b6699556c21f5df6ca79bb86b2e8d1683f",
|
||||
"live_desired_fields_verified": true,
|
||||
"runtime_config_verified": true,
|
||||
"existing_image_and_pvc_preserved": true,
|
||||
"completed_at": "2026-10-31T17:17:31.488654+00:00"
|
||||
},
|
||||
"receipt_sha256": "c26d636f59109956f281ad46f4885c4db800a9553cf05cac324aa3155ef7ac40",
|
||||
"original_execution_packet_matches": true,
|
||||
"live_desired_fields_verified": true,
|
||||
"runtime_config_verified": true,
|
||||
"existing_image_and_pvc_preserved": true,
|
||||
"runtime_modified_by_verification": false
|
||||
}
|
||||
|
|
@ -0,0 +1,41 @@
|
|||
{
|
||||
"schema": "coulomb.content-acceptance-independent-postflight.v1",
|
||||
"status": "deployed_image_and_complete_native_state_verified",
|
||||
"proposal_digest": "sha256:e96752ecfa7adef2fd1d9da48902c8e63de124ccfd272fe20ba79b758b3ca4a3",
|
||||
"receipt_sha256": "074ec03d62d43f35bd6c276213a28de4a7b0161132379221bec0e402b5334233",
|
||||
"helm_revision": 20,
|
||||
"image": "forgejo.coulomb.social/coulomb/coulomb-social@sha256:7906f461bc8d2d5204fd4fde67a251850f725b914452a66172919d6853672ed5",
|
||||
"source": "1139a6d30eee4f75317b46bd45120a15d818455f",
|
||||
"packaged_source_files_verified": 79,
|
||||
"sole_ready_content_writer": true,
|
||||
"all_frozen_capsule_files_verified": 23,
|
||||
"installed_helper_hashes_verified": true,
|
||||
"snapshot_pin_refreshed": true,
|
||||
"public_health_landing_static_verified": true,
|
||||
"postflight": {
|
||||
"business_tables": 12,
|
||||
"migration_rows_sha256": "43471516387c0e2a3d35971033ed6af330e2963efe4da93293d97633825d04af",
|
||||
"business_rows": 93,
|
||||
"business_rows_sha256": "7953b37b02b80d89ca6869dab6b2b0b996541de20ca0dd1b294a5f25572fb2ca",
|
||||
"content_files": 86,
|
||||
"content_files_sha256": "ed535246f4e8f46fcd7ce01f936127996aff873c6936b297f7272194b594aeda",
|
||||
"global_slug_constraint": true,
|
||||
"tenant_slug_constraint": true,
|
||||
"migration_0003_applied": true,
|
||||
"duplicate_slug_groups": 0,
|
||||
"actual_owner_pages_rendered": 40,
|
||||
"unsaved_outsider_page_denials": 40,
|
||||
"production_identity_or_grant_created": false
|
||||
},
|
||||
"fresh_paired_point": {
|
||||
"captured_at": "2026-10-31T20:21:01Z",
|
||||
"destination": "s3://railiance-platform-pg-backup/platform-pg/application-archives/coulomb-social/2026/10/31/20261031T202101Z-2ad4faf215939d67e82f67a4.tar.age",
|
||||
"version_id": "1793478121590106",
|
||||
"encrypted_sha256": "91b4ffe4874a53e3422d604b7c3fa85f6551a481411ef82b2209993552486bfb",
|
||||
"encrypted_bytes": 2181848,
|
||||
"image": "forgejo.coulomb.social/coulomb/coulomb-social@sha256:522bcd7fce92436765a60c1e4afa2598f3cc40913352153ff1c4319a99ca92ed"
|
||||
},
|
||||
"timers_activated": false,
|
||||
"production_data_restored": false,
|
||||
"productive_acceptance_inferred": false
|
||||
}
|
||||
|
|
@ -0,0 +1,39 @@
|
|||
{
|
||||
"schema": "coulomb.acceptance-baseline-change.v1",
|
||||
"retained_point": "2026-10-31T20:21:01Z",
|
||||
"old_business_rows": 93,
|
||||
"new_business_rows": 97,
|
||||
"table_changes": {
|
||||
"spaces_space": {
|
||||
"old": 2,
|
||||
"new": 4,
|
||||
"removed": 0,
|
||||
"added": 2
|
||||
},
|
||||
"spaces_spacemembership": {
|
||||
"old": 1,
|
||||
"new": 3,
|
||||
"removed": 0,
|
||||
"added": 2
|
||||
}
|
||||
},
|
||||
"old_content_files": 86,
|
||||
"new_content_files": 98,
|
||||
"old_files_missing": 0,
|
||||
"old_files_changed": 0,
|
||||
"new_files_added": 12,
|
||||
"old_rows_preserved": true,
|
||||
"current_baseline": {
|
||||
"business_tables": 12,
|
||||
"migration_rows_sha256": "43471516387c0e2a3d35971033ed6af330e2963efe4da93293d97633825d04af",
|
||||
"business_rows": 97,
|
||||
"business_rows_sha256": "35b0ae7d9dd1ff21c2ceaa04649162545ec36a2c68629548238352d9cd0fb303",
|
||||
"content_files": 98,
|
||||
"content_files_sha256": "b657c0e470399b6c7500da500cbbec061bea12ab9633bd74e2f142d797b2d26a",
|
||||
"global_slug_constraint": true,
|
||||
"tenant_slug_constraint": true,
|
||||
"migration_0003_applied": true,
|
||||
"duplicate_slug_groups": 0
|
||||
},
|
||||
"interpretation": "Changes observed during the user-requested productive acceptance session; no user verdict inferred."
|
||||
}
|
||||
|
|
@ -0,0 +1,45 @@
|
|||
{
|
||||
"schema": "coulomb.content-acceptance-build.v1",
|
||||
"completed_at": "2026-10-31T21:13:04.039838+00:00",
|
||||
"source": "31eaa581a65e454b6ef9979326c5bdfe10e13806",
|
||||
"image": "forgejo.coulomb.social/coulomb/coulomb-social@sha256:b58d858abd5b4acbd6b893c3f622f7a9fdb5e606164ab9866eb3cfaa04df1a0e",
|
||||
"build_context": "clean restricted git archive",
|
||||
"source_full_gate_tests": 568,
|
||||
"runtime_packages_and_python_unchanged": true,
|
||||
"runtime": {
|
||||
"python": "3.12.16",
|
||||
"distributions": {
|
||||
"h11": "0.16.0",
|
||||
"httpcore": "1.0.9",
|
||||
"psycopg": "3.3.4",
|
||||
"joserfc": "1.7.4",
|
||||
"anyio": "4.14.2",
|
||||
"cryptography": "50.0.0",
|
||||
"idna": "3.18",
|
||||
"certifi": "2026.7.22",
|
||||
"packaging": "26.3",
|
||||
"python-decouple": "3.8",
|
||||
"psycopg-binary": "3.3.4",
|
||||
"sqlparse": "0.5.5",
|
||||
"whitenoise": "6.12.0",
|
||||
"cffi": "2.1.1",
|
||||
"markdown": "3.10.3",
|
||||
"webencodings": "0.5.1",
|
||||
"pycparser": "3.0",
|
||||
"bleach": "6.4.0",
|
||||
"authlib": "1.7.2",
|
||||
"django": "6.1",
|
||||
"typing_extensions": "4.16.0",
|
||||
"gunicorn": "26.0.0",
|
||||
"asgiref": "3.12.1",
|
||||
"httpx": "0.28.1",
|
||||
"dj-database-url": "3.1.2"
|
||||
}
|
||||
},
|
||||
"django_checks": {
|
||||
"check": "System check identified no issues (0 silenced).",
|
||||
"makemigrations": "No changes detected"
|
||||
},
|
||||
"new_database_migrations": false,
|
||||
"production_deployed": false
|
||||
}
|
||||
|
|
@ -0,0 +1,11 @@
|
|||
{
|
||||
"schema": "coulomb.packaged-source-provenance.v1",
|
||||
"image": "forgejo.coulomb.social/coulomb/coulomb-social@sha256:b58d858abd5b4acbd6b893c3f622f7a9fdb5e606164ab9866eb3cfaa04df1a0e",
|
||||
"source": "31eaa581a65e454b6ef9979326c5bdfe10e13806",
|
||||
"packaged_file_count": 79,
|
||||
"all_packaged_source_bytes_match": true,
|
||||
"source_revision_label_verified": true,
|
||||
"registry_digest_resolves": true,
|
||||
"application_source_overlay": false,
|
||||
"manifest_sha256": "99401a60fdd9a95aff1168858e81fd7d8802cd7603f15c0ea35eb6917981f9fe"
|
||||
}
|
||||
|
|
@ -0,0 +1,67 @@
|
|||
{
|
||||
"schema": "coulomb.packaged-content-acceptance-recovery.v1",
|
||||
"status": "packaged_recovered_export_and_views_verified",
|
||||
"source": "31eaa581a65e454b6ef9979326c5bdfe10e13806",
|
||||
"image": "forgejo.coulomb.social/coulomb/coulomb-social@sha256:b58d858abd5b4acbd6b893c3f622f7a9fdb5e606164ab9866eb3cfaa04df1a0e",
|
||||
"restore_receipt_sha256": "9dacbd44544f93abf99354158cf610b4fb1f4e59611b22056b3086e0033231ab",
|
||||
"retained_point_captured_at": "2026-10-31T20:21:01Z",
|
||||
"candidate_application": {
|
||||
"business_tables": 12,
|
||||
"migration_rows_sha256": "43471516387c0e2a3d35971033ed6af330e2963efe4da93293d97633825d04af",
|
||||
"business_rows": 93,
|
||||
"business_rows_sha256": "7953b37b02b80d89ca6869dab6b2b0b996541de20ca0dd1b294a5f25572fb2ca",
|
||||
"content_files": 86,
|
||||
"content_files_sha256": "ed535246f4e8f46fcd7ce01f936127996aff873c6936b297f7272194b594aeda",
|
||||
"global_slug_constraint": true,
|
||||
"tenant_slug_constraint": true,
|
||||
"migration_0003_applied": true,
|
||||
"duplicate_slug_groups": 0,
|
||||
"actual_owner_pages_rendered": 40,
|
||||
"unsaved_outsider_page_denials": 40,
|
||||
"production_identity_or_grant_created": false
|
||||
},
|
||||
"previous_image_application": {
|
||||
"business_tables": 12,
|
||||
"migration_rows_sha256": "43471516387c0e2a3d35971033ed6af330e2963efe4da93293d97633825d04af",
|
||||
"business_rows": 93,
|
||||
"business_rows_sha256": "7953b37b02b80d89ca6869dab6b2b0b996541de20ca0dd1b294a5f25572fb2ca",
|
||||
"content_files": 86,
|
||||
"content_files_sha256": "ed535246f4e8f46fcd7ce01f936127996aff873c6936b297f7272194b594aeda",
|
||||
"global_slug_constraint": true,
|
||||
"tenant_slug_constraint": true,
|
||||
"migration_0003_applied": true,
|
||||
"duplicate_slug_groups": 0,
|
||||
"actual_owner_pages_rendered": 40,
|
||||
"unsaved_outsider_page_denials": 40,
|
||||
"production_identity_or_grant_created": false
|
||||
},
|
||||
"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": "ecf5dba7ce891475cd5df15eb30205606f805850af7339ecd46e1479b45d6c5f",
|
||||
"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
|
||||
},
|
||||
"source_content_files_unchanged": 86,
|
||||
"all_tables_unchanged": true,
|
||||
"application_source_overlay": false,
|
||||
"network_internal": true,
|
||||
"published_ports": 0,
|
||||
"production_access": false,
|
||||
"production_restore": false,
|
||||
"driver_sha256": "29c53d551eec2b4f4d60b047f123c727eef76ee7677c054bbfb0ab008355cff9"
|
||||
}
|
||||
|
|
@ -0,0 +1,21 @@
|
|||
{
|
||||
"baseline_revision": 20,
|
||||
"baseline_helm_manifest_sha256": "e388f62c97e97d54d87671825bd0b05c854a70b0cca8a00faee452ae7841799e",
|
||||
"deployment_uid": "2dbe661a-d232-4477-bbd1-833813077fbe",
|
||||
"baseline_spec_sha256": "8d79c64cff4bd2c62f03494e80847dc99b965ddabf35645da67e8d1020220798",
|
||||
"candidate_spec_sha256": "4deab26fc15d63e09922259b3362cd4e5c6bfa10884de058f776c0de8b642b00",
|
||||
"old_image": "forgejo.coulomb.social/coulomb/coulomb-social@sha256:7906f461bc8d2d5204fd4fde67a251850f725b914452a66172919d6853672ed5",
|
||||
"expected_data": {
|
||||
"business_tables": 12,
|
||||
"migration_rows_sha256": "43471516387c0e2a3d35971033ed6af330e2963efe4da93293d97633825d04af",
|
||||
"business_rows": 97,
|
||||
"business_rows_sha256": "35b0ae7d9dd1ff21c2ceaa04649162545ec36a2c68629548238352d9cd0fb303",
|
||||
"content_files": 98,
|
||||
"content_files_sha256": "b657c0e470399b6c7500da500cbbec061bea12ab9633bd74e2f142d797b2d26a",
|
||||
"global_slug_constraint": true,
|
||||
"tenant_slug_constraint": true,
|
||||
"migration_0003_applied": true,
|
||||
"duplicate_slug_groups": 0
|
||||
},
|
||||
"image_only_server_preview": true
|
||||
}
|
||||
|
|
@ -0,0 +1,13 @@
|
|||
{
|
||||
"schema": "coulomb.packaged-content-acceptance-tests.v1",
|
||||
"image": "forgejo.coulomb.social/coulomb/coulomb-social@sha256:b58d858abd5b4acbd6b893c3f622f7a9fdb5e606164ab9866eb3cfaa04df1a0e",
|
||||
"source": "31eaa581a65e454b6ef9979326c5bdfe10e13806",
|
||||
"tests": 110,
|
||||
"failures": 0,
|
||||
"errors": 0,
|
||||
"skipped": 0,
|
||||
"network": "none",
|
||||
"read_only_root": true,
|
||||
"application_source_overlay": false,
|
||||
"synthetic_fixtures_only": true
|
||||
}
|
||||
|
|
@ -0,0 +1,34 @@
|
|||
{
|
||||
"schema": "coulomb.editor-attachments-validation.v1",
|
||||
"reported_gap": "Attachments visible on the original page were absent from editor tabs.",
|
||||
"main_source": "8b38afddf3f3648f209c60b1bafe3dd25501d857",
|
||||
"release_source": "31eaa581a65e454b6ef9979326c5bdfe10e13806",
|
||||
"image": "forgejo.coulomb.social/coulomb/coulomb-social@sha256:b58d858abd5b4acbd6b893c3f622f7a9fdb5e606164ab9866eb3cfaa04df1a0e",
|
||||
"main_full_gate": {
|
||||
"tests": 670,
|
||||
"failures": 0,
|
||||
"errors": 0,
|
||||
"skipped": 0
|
||||
},
|
||||
"release_full_gate": {
|
||||
"tests": 568,
|
||||
"failures": 0,
|
||||
"errors": 0,
|
||||
"skipped": 0
|
||||
},
|
||||
"packaged_tests": 110,
|
||||
"browser_verifies": [
|
||||
"saved file list and exact download bytes in both editor tabs",
|
||||
"management opens separately and keeps unsaved text",
|
||||
"stale refusal keeps submitted text and attachments",
|
||||
"save keeps attachments and rejects stale overwrite",
|
||||
"existing copy/move/download/detach permissions journey"
|
||||
],
|
||||
"runtime_changes": [
|
||||
"coulomb_social/apps/spaces/views.py",
|
||||
"coulomb_social/templates/spaces/page_form.html"
|
||||
],
|
||||
"storage_schema_or_authority_changed": false,
|
||||
"productive_acceptance_inferred": false,
|
||||
"test_environment": "Main uses /var/tmp; isolated branch native observer requires /tmp. Final complete gates pass without deselection."
|
||||
}
|
||||
175
release/editor-attachments-snapshot.py
Normal file
175
release/editor-attachments-snapshot.py
Normal file
|
|
@ -0,0 +1,175 @@
|
|||
#!/usr/bin/env python3
|
||||
"""Node-side quiesced coulomb-social snapshot. Binary output stays private.
|
||||
|
||||
Run on railiance01 after reviewed live approval. Does not restore production.
|
||||
Default is server dry-run; --execute briefly pauses the app and captures a
|
||||
paired pg_dump/content archive. A separate isolated restore must validate it.
|
||||
"""
|
||||
from __future__ import annotations
|
||||
|
||||
import argparse
|
||||
import fcntl
|
||||
import hashlib
|
||||
import json
|
||||
import os
|
||||
import signal
|
||||
import stat
|
||||
import subprocess
|
||||
import sys
|
||||
import time
|
||||
from pathlib import Path
|
||||
|
||||
NS = 'coulomb-social'
|
||||
IMAGE = ('forgejo.coulomb.social/coulomb/coulomb-social@sha256:'
|
||||
'b58d858abd5b4acbd6b893c3f622f7a9fdb5e606164ab9866eb3cfaa04df1a0e')
|
||||
CLUSTER_UID = 'a553c742-0115-43d4-99a4-a5ca56fe0786'
|
||||
LOCK_PATH = Path('/var/lib/coulomb-social-backup/snapshot.lock')
|
||||
|
||||
|
||||
class Refused(RuntimeError):
|
||||
pass
|
||||
|
||||
|
||||
def run(args: list[str], *, payload: bytes | None = None, timeout: int = 180) -> bytes:
|
||||
p = subprocess.run(args, input=payload, capture_output=True, timeout=timeout)
|
||||
if p.returncode:
|
||||
raise Refused('command_failed')
|
||||
return p.stdout
|
||||
|
||||
|
||||
def k(*args: str, payload: bytes | None = None) -> bytes:
|
||||
return run(['kubectl', *args], payload=payload)
|
||||
|
||||
|
||||
def document(*args: str) -> dict:
|
||||
return json.loads(k(*args, '-o', 'json'))
|
||||
|
||||
|
||||
def private_write(path: Path, value: bytes) -> None:
|
||||
fd = os.open(path, os.O_WRONLY | os.O_CREAT | os.O_EXCL, 0o600)
|
||||
with os.fdopen(fd, 'wb') as f:
|
||||
f.write(value)
|
||||
|
||||
|
||||
def snapshot() -> int:
|
||||
parser = argparse.ArgumentParser(description=__doc__)
|
||||
parser.add_argument('--execute', action='store_true')
|
||||
parser.add_argument('--destination', type=Path, required=True)
|
||||
args = parser.parse_args()
|
||||
os.environ['KUBECONFIG'] = '/etc/rancher/k3s/k3s.yaml'
|
||||
started = time.monotonic()
|
||||
if document('get', 'namespace', 'kube-system')['metadata']['uid'] != CLUSTER_UID:
|
||||
raise Refused('wrong_cluster')
|
||||
dep = document('get', 'deployment', 'coulomb-social', '-n', NS)
|
||||
spec = dep['spec']['template']['spec']
|
||||
if dep['spec']['replicas'] != 1 or spec['containers'][0]['image'] != IMAGE:
|
||||
raise Refused('unexpected_release')
|
||||
if document('get', 'pvc', 'coulomb-social-content', '-n', NS)['status']['phase'] != 'Bound':
|
||||
raise Refused('pvc_not_bound')
|
||||
cluster = document('get', 'cluster', 'apps-pg', '-n', 'databases')
|
||||
primary = cluster['status']['currentPrimary']
|
||||
name = 'csoc-paired-snapshot-' + time.strftime('%Y%m%d%H%M%S', time.gmtime())
|
||||
pod = {
|
||||
'apiVersion': 'v1', 'kind': 'Pod',
|
||||
'metadata': {'name': name, 'namespace': NS, 'labels': {'csoc-recovery': name}},
|
||||
'spec': {
|
||||
'restartPolicy': 'Never', 'automountServiceAccountToken': False,
|
||||
'securityContext': {'runAsNonRoot': True, 'runAsUser': 10001,
|
||||
'runAsGroup': 10001, 'fsGroup': 10001,
|
||||
'fsGroupChangePolicy': 'OnRootMismatch'},
|
||||
'containers': [{'name': 'snapshot', 'image': IMAGE,
|
||||
'command': ['python', '-c', 'import time;time.sleep(1800)'],
|
||||
'resources': {'requests': {'cpu': '10m', 'memory': '64Mi'},
|
||||
'limits': {'cpu': '100m', 'memory': '256Mi'}},
|
||||
'securityContext': {'allowPrivilegeEscalation': False,
|
||||
'readOnlyRootFilesystem': True,
|
||||
'capabilities': {'drop': ['ALL']}},
|
||||
'volumeMounts': [{'name': 'content', 'mountPath': '/snapshot', 'readOnly': True}]}],
|
||||
'volumes': [{'name': 'content', 'persistentVolumeClaim':
|
||||
{'claimName': 'coulomb-social-content', 'readOnly': True}}],
|
||||
},
|
||||
}
|
||||
body = json.dumps(pod).encode()
|
||||
k('create', '--dry-run=server', '-f', '-', payload=body)
|
||||
if not args.execute:
|
||||
print(json.dumps({'status': 'reviewed', 'server_dry_run': True,
|
||||
'image_pinned': True, 'pvc_read_only': True,
|
||||
'db_scope': 'coulomb_social_db', 'replicas_restored_to': 1}))
|
||||
return 0
|
||||
dest = args.destination
|
||||
if not dest.is_absolute() or dest.exists():
|
||||
raise Refused('destination_must_be_new_absolute_directory')
|
||||
dest.mkdir(mode=0o700)
|
||||
paused = False
|
||||
created = False
|
||||
receipt = {'status': 'incomplete', 'app': 'coulomb-social',
|
||||
'database': 'coulomb_social_db', 'image': IMAGE,
|
||||
'started_at': time.strftime('%Y-%m-%dT%H:%M:%SZ', time.gmtime())}
|
||||
try:
|
||||
paused = True
|
||||
k('scale', 'deployment/coulomb-social', '-n', NS, '--replicas=0')
|
||||
k('wait', '--for=delete', 'pod', '-n', NS,
|
||||
'-l', 'app.kubernetes.io/instance=coulomb-social', '--timeout=120s')
|
||||
created = True
|
||||
k('create', '-f', '-', payload=body)
|
||||
k('wait', '--for=condition=Ready', 'pod/' + name, '-n', NS, '--timeout=120s')
|
||||
dump = k('exec', '-n', 'databases', primary, '-c', 'postgres', '--',
|
||||
'pg_dump', '-U', 'postgres', '-d', 'coulomb_social_db', '-Fc')
|
||||
if not dump.startswith(b'PGDMP'):
|
||||
raise Refused('invalid_pg_dump')
|
||||
private_write(dest / 'database.dump', dump)
|
||||
archive_code = ('import io,sys,tarfile; b=io.BytesIO(); '
|
||||
't=tarfile.open(fileobj=b,mode="w:gz"); '
|
||||
't.add("/snapshot",arcname="content"); '
|
||||
't.close();sys.stdout.buffer.write(b.getvalue())')
|
||||
content = k('exec', '-n', NS, name, '--', 'python', '-c', archive_code)
|
||||
private_write(dest / 'content.tar.gz', content)
|
||||
receipt.update(status='captured', writers_quiesced=True,
|
||||
database_sha256=hashlib.sha256(dump).hexdigest(),
|
||||
content_sha256=hashlib.sha256(content).hexdigest(),
|
||||
database_bytes=len(dump), content_bytes=len(content))
|
||||
finally:
|
||||
try:
|
||||
if created:
|
||||
k('delete', 'pod', name, '-n', NS, '--wait=true', '--timeout=120s')
|
||||
finally:
|
||||
if paused:
|
||||
k('scale', 'deployment/coulomb-social', '-n', NS, '--replicas=1')
|
||||
k('rollout', 'status', 'deployment/coulomb-social', '-n', NS, '--timeout=180s')
|
||||
receipt['app_resumed'] = True
|
||||
receipt['elapsed_seconds'] = round(time.monotonic() - started, 2)
|
||||
private_write(dest / 'receipt.json', json.dumps(receipt, indent=2).encode())
|
||||
print(json.dumps(receipt))
|
||||
return 0
|
||||
|
||||
|
||||
def main() -> int:
|
||||
if '--execute' not in sys.argv:
|
||||
return snapshot()
|
||||
LOCK_PATH.parent.mkdir(mode=0o700, parents=True, exist_ok=True)
|
||||
parent = LOCK_PATH.parent.lstat()
|
||||
if (not stat.S_ISDIR(parent.st_mode) or parent.st_uid != os.geteuid()
|
||||
or parent.st_mode & 0o077):
|
||||
raise Refused('lock_directory_not_private')
|
||||
fd = os.open(LOCK_PATH, os.O_CREAT | os.O_RDWR | os.O_NOFOLLOW, 0o600)
|
||||
with os.fdopen(fd, 'w') as lock:
|
||||
try:
|
||||
fcntl.flock(lock, fcntl.LOCK_EX | fcntl.LOCK_NB)
|
||||
except BlockingIOError:
|
||||
raise Refused('snapshot_already_running') from None
|
||||
def terminate(signum, frame):
|
||||
raise Refused('snapshot_interrupted')
|
||||
previous = signal.signal(signal.SIGTERM, terminate)
|
||||
try:
|
||||
return snapshot()
|
||||
finally:
|
||||
signal.signal(signal.SIGTERM, previous)
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
try:
|
||||
sys.exit(main())
|
||||
except Exception as exc:
|
||||
# Never expose child output, kubectl objects, credentials or raw exception messages.
|
||||
print(json.dumps({'status': 'failed', 'failure_type': type(exc).__name__}))
|
||||
sys.exit(1)
|
||||
50
release/editor-attachments-values.yaml
Normal file
50
release/editor-attachments-values.yaml
Normal file
|
|
@ -0,0 +1,50 @@
|
|||
# Production overrides for coulomb-social.
|
||||
# Non-secret values only. Secrets live in K8s Secret coulomb-social-env.
|
||||
|
||||
image:
|
||||
repository: forgejo.coulomb.social/coulomb/coulomb-social
|
||||
tag: "31eaa581a65e"
|
||||
digest: "sha256:b58d858abd5b4acbd6b893c3f622f7a9fdb5e606164ab9866eb3cfaa04df1a0e"
|
||||
|
||||
# Public host: app.coulomb.social (parallel to Bubble on apex coulomb.social).
|
||||
# Apex cutover is deferred until data + self-registration are ready.
|
||||
env:
|
||||
DJANGO_SETTINGS_MODULE: coulomb_social.settings.prod
|
||||
ALLOWED_HOSTS: app.coulomb.social,localhost
|
||||
CSRF_TRUSTED_ORIGINS: https://app.coulomb.social
|
||||
CONTENT_ROOT: /app/var/content
|
||||
DEFAULT_TENANT_ID: "tenant:coulomb"
|
||||
OIDC_ENABLED: "true"
|
||||
OIDC_ISSUER: https://kc.coulomb.social
|
||||
OIDC_CLIENT_ID: coulomb-social
|
||||
OIDC_REDIRECT_URI: https://app.coulomb.social/auth/callback/
|
||||
OIDC_SCOPES: "openid profile email groups"
|
||||
USER_ENGINE_BASE_URL: https://users.coulomb.social
|
||||
USER_ENGINE_APPLICATION_ID: coulomb-social
|
||||
USER_ENGINE_EXPECTED_AUDIENCE: user-engine-portal
|
||||
NETKINGDOM_REGISTRATION_URL: https://users.92-205-62-239.nip.io/register
|
||||
|
||||
probes:
|
||||
hostHeader: app.coulomb.social
|
||||
path: /healthz
|
||||
|
||||
# One writable local-path volume; Recreate prevents concurrent old/new writers.
|
||||
replicaCount: 1
|
||||
deploymentStrategy: Recreate
|
||||
persistence:
|
||||
content:
|
||||
enabled: true
|
||||
storageClass: local-path
|
||||
size: 2Gi
|
||||
mountPath: /app/var/content
|
||||
retain: true
|
||||
|
||||
# Wave-2 right-sizing (CSOC-WP-0017-T01, 2026-10-21 node budget): 7d p95
|
||||
# 0.4m CPU / 146Mi. Limits stay at the chart defaults (1000m/1Gi).
|
||||
resources:
|
||||
requests:
|
||||
cpu: 15m
|
||||
memory: 176Mi
|
||||
limits:
|
||||
cpu: 1000m
|
||||
memory: 1Gi
|
||||
|
|
@ -518,3 +518,31 @@ pass40owner/40outsider checks; client export verifies85files with all source
|
|||
SQL/files unchanged. Owner live values and consumer source/helper pins now match
|
||||
revision20. Recovery remains isolated; timers are inactive/disabled. Remaining
|
||||
user workflow verdicts are tracked by existing CSOC-WP-0013-T02/T03/T05/T06.
|
||||
|
||||
## T08 — Deliver the editor attachment visibility correction
|
||||
|
||||
```task
|
||||
id: RAPPS-WP-0015-T08
|
||||
status: wait
|
||||
priority: high
|
||||
needs_human: true
|
||||
wait_kind: human
|
||||
decision_id: "0d538348-aadd-41a2-88f6-191defcf22b2"
|
||||
blocking_reason: "Exact editor attachment proposal2cddcf38 passes native preflight; founder-terminal execution and independent return are required."
|
||||
```
|
||||
|
||||
Productive revision20 review identified that attachments are visible on the
|
||||
original page but absent from editor tabs. CSOC-WP-0013-T06 owns the correction:
|
||||
display saved attachments/downloads in the editor and preserve that list after
|
||||
stale-edit refusal, with management opening separately to retain unsaved text.
|
||||
Prepare the minimal follow-up image from the deployed source, preserve existing
|
||||
schema/data/permissions, and reuse the exact attended image-release lane with a
|
||||
fresh paired rollback point. Complete after founder execution and independent
|
||||
postflight/recovery/source-pin reconciliation. Productive acceptance remains
|
||||
CSOC-WP-0013-T03/T06; T07's verified revision20 delivery stays complete.
|
||||
|
||||
Prepared source31eaa58/imageb58d858a; exact proposal2cddcf38b7052287c10dce467a200a74cfa9699c666ae9ac538fc82917129e7a. Main670/isolated568/packaged110 pass.
|
||||
Recovered views/export pass. Full native preflight at revision20/97rows/98files
|
||||
passes; existing93rows/86files are unchanged by the productive review additions.
|
||||
Plan: release/coulomb-editor-attachments-31eaa58.json. Review/command:
|
||||
coulomb-social/docs/release/content-acceptance-review-2026-10-31.md.
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue