Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
58 changes: 52 additions & 6 deletions .github/workflows/wasm-installed-org.yml
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ on:
required: true
type: string
accepted_executor:
description: Root accepted protected publisher/qualification executor E
description: Root accepted current installed qualifier executor Q
required: true
type: string
promotion_binding_sha256:
Expand All @@ -42,6 +42,7 @@ permissions:
jobs:
installed:
strategy:
fail-fast: false
max-parallel: 1
matrix:
feed: [org, public]
Expand Down Expand Up @@ -72,6 +73,7 @@ jobs:
run: |
python3 tests/release/wasm/test-consumer-source-mapping.py
python3 tests/release/wasm/test-installed-org-workflow.py
python3 tests/release/wasm/test-installed-evidence.py
- name: Bind qualification source and immutable published receipts
env:
GH_TOKEN: ${{ github.token }}
Expand All @@ -91,6 +93,7 @@ jobs:
rustup default 1.90.0
scripts/wasm-release/install-browser-tools.sh
- name: Qualify fresh installed consumer
id: consumer
shell: bash
env:
GH_TOKEN: ${{ github.token }}
Expand All @@ -99,14 +102,57 @@ jobs:
set -euo pipefail
export NUGET_HTTP_CACHE_PATH="$RUNNER_TEMP/wasm-installed-${{ matrix.feed }}-http-cache"
mkdir -p artifacts/wasm-installed-${{ matrix.feed }}
scripts/verify-wasm-package-consumer.sh --feed-only 2>&1 | tee artifacts/wasm-installed-${{ matrix.feed }}/consumer.log
scripts/wasm-release/qualify-supervisor-installed.sh --feed-only "$RUNNER_TEMP/selected-${{ matrix.feed }}" 2>&1 | tee artifacts/wasm-installed-${{ matrix.feed }}/selected.log
cp -a "$RUNNER_TEMP/selected-${{ matrix.feed }}" "$RUNNER_TEMP/selected-${{ matrix.feed }}-browser" "$RUNNER_TEMP/wasm-installed-receipts" artifacts/wasm-installed-${{ matrix.feed }}/
export WASM_CONSUMER_EVIDENCE="$RUNNER_TEMP/consumer-${{ matrix.feed }}-evidence"
export WASM_CONSUMER_STATUS="$GITHUB_WORKSPACE/artifacts/wasm-installed-${{ matrix.feed }}/consumer-status.json"
phase=initial
command_exit=null
tee_exit=null
record_runtime() {
local original=$? recorded=0
trap - EXIT
set +e
printf '{"phase":"%s","exitCode":%s,"commandExit":%s,"logExit":%s}\n' "$phase" "$original" "$command_exit" "$tee_exit" > artifacts/wasm-installed-${{ matrix.feed }}/runtime-status.json
recorded=$?
if (( original != 0 )); then exit "$original"; fi
exit "$recorded"
}
trap record_runtime EXIT
run_logged() {
phase=$1
local log=$2
shift 2
set +e
"$@" 2>&1 | tee "$log"
local results=("${PIPESTATUS[@]}")
set -e
command_exit=${results[0]}
tee_exit=${results[1]}
if (( command_exit != 0 )); then return "$command_exit"; fi
return "$tee_exit"
}
run_logged consumer artifacts/wasm-installed-${{ matrix.feed }}/consumer.log scripts/verify-wasm-package-consumer.sh --feed-only
run_logged selected artifacts/wasm-installed-${{ matrix.feed }}/selected.log scripts/wasm-release/qualify-supervisor-installed.sh --feed-only "$RUNNER_TEMP/selected-${{ matrix.feed }}"
phase=complete
- name: Collect bounded installed evidence
if: always()
env:
RUNTIME_OUTCOME: ${{ steps.consumer.outcome }}
shell: bash
run: |
set -euo pipefail
logs="artifacts/wasm-installed-${{ matrix.feed }}"
mkdir -p "$logs"
runtime=1
[[ "$RUNTIME_OUTCOME" != success ]] || runtime=0
if [[ ! -e "$logs/runtime-status.json" ]]; then
printf '{"phase":"unreached","exitCode":null,"nativeOutcome":"%s"}\n' "$RUNTIME_OUTCOME" > "$logs/runtime-status.json"
fi
python3 scripts/wasm-release/installed-evidence.py assemble --work "$RUNNER_TEMP/selected-${{ matrix.feed }}" --consumer "$RUNNER_TEMP/consumer-${{ matrix.feed }}-evidence" --receipts "$RUNNER_TEMP/wasm-installed-receipts" --logs "$logs" --runtime "$runtime" --output "$RUNNER_TEMP/installed-${{ matrix.feed }}-evidence"
- name: Retain installed qualification output
if: always()
uses: actions/upload-artifact@v7
with:
name: wasm-installed-${{ matrix.feed }}-${{ github.sha }}-${{ inputs.version }}
path: artifacts/wasm-installed-${{ matrix.feed }}/
if-no-files-found: ignore
path: ${{ runner.temp }}/installed-${{ matrix.feed }}-evidence/
if-no-files-found: error
retention-days: 30
2 changes: 1 addition & 1 deletion docs/atlas/catalog.json
Original file line number Diff line number Diff line change
@@ -1 +1 @@
{"records":["0863093e69a16355fa9b90f8e7e29156ea4ad88c4523bc4883568bde831bdf35","231df3792931ad2333d00970a5993b3e13fa9dc38f687899f9fa2c966ed9fbfa","24fdc3980640ba58bedcae6f16d5b467eb7383c31161fb9b6ff10fd2e667b0e5","2b7dfb3a2f76368cb603161cdb6f8fa8c2b8afc3e96659dd37c975921ba5ba66","33df463263533529cca24a0b09937573f836d197cc1a739e9960b1cdd4deb1fd","343077d02ddd266b21d8677f7c256854134f7e3e2d18137b55ebe3f32564c5c0","34391bda3fb56135a2bddf74ab790958c175bc6a69c38175e6f8db792cfd50a0","36a19fefd7024f54f3391ffed19019c10222a514719edd7a44f0cde2a1c48258","3d3a0a302c02cd0bfee86715d09b0211baa8dad3e47402c638fc95c7cfa02e87","3de8718fb3ca9b15212e8bd84fba205995d24636087090a61c63c28a96a745b1","3df4f31fda99ad137c651322ad29809e36380400516399274870b4a4332b4a92","3f09ee199e3c2e808e0f6e74f197f2fdd8158ae099a7195c498ce9466bb78b03","44bda82d6f9a9625a83283bf56a15a1831f287037214dc134eeeae87f1faa869","6c5b38ee260d1f15f8029d699ec1cebceafb5e1407a6341dc7a4b96f4d9d3521","72742cbaa561237f10251e94aa5c61153ab5c7f14fc5771b7a5ebdece1e1cb11","87d6de6f3730cecd75d9a4411bf4dbac4e058127a3ce9f46b07f6de110bc26de","8b1cf51c5f03c0ae19c46ca3ea4a1158acbb6e47bf109ca8c506c5417b51cf9f","95115e1052b5ea4fcd393f5c9b9c6f0298657f0028eee84e16215ede97576cfa","ab4502eff76606ac8e58b623878f3d76e1e0b18f30796aec7c446e2aab8b57c8","c01c2c98f13a65b49113916a2f295e46a03fc4c185ece880267dd86c3f3dee8b","d557525e3ebfad227c8d6db9bb6350d42506fb02b1de8058cb443f4f008c0f67"],"schema":"fsgg.atlas/1"}
{"records":["0863093e69a16355fa9b90f8e7e29156ea4ad88c4523bc4883568bde831bdf35","231df3792931ad2333d00970a5993b3e13fa9dc38f687899f9fa2c966ed9fbfa","24fdc3980640ba58bedcae6f16d5b467eb7383c31161fb9b6ff10fd2e667b0e5","264a2f7887a9b6473cbc24102e1bf9be70e57f6d7ba224138140efa094d541f4","2b7dfb3a2f76368cb603161cdb6f8fa8c2b8afc3e96659dd37c975921ba5ba66","33df463263533529cca24a0b09937573f836d197cc1a739e9960b1cdd4deb1fd","343077d02ddd266b21d8677f7c256854134f7e3e2d18137b55ebe3f32564c5c0","34391bda3fb56135a2bddf74ab790958c175bc6a69c38175e6f8db792cfd50a0","36a19fefd7024f54f3391ffed19019c10222a514719edd7a44f0cde2a1c48258","3d3a0a302c02cd0bfee86715d09b0211baa8dad3e47402c638fc95c7cfa02e87","3de8718fb3ca9b15212e8bd84fba205995d24636087090a61c63c28a96a745b1","3df4f31fda99ad137c651322ad29809e36380400516399274870b4a4332b4a92","3f09ee199e3c2e808e0f6e74f197f2fdd8158ae099a7195c498ce9466bb78b03","44bda82d6f9a9625a83283bf56a15a1831f287037214dc134eeeae87f1faa869","6c5b38ee260d1f15f8029d699ec1cebceafb5e1407a6341dc7a4b96f4d9d3521","72742cbaa561237f10251e94aa5c61153ab5c7f14fc5771b7a5ebdece1e1cb11","87d6de6f3730cecd75d9a4411bf4dbac4e058127a3ce9f46b07f6de110bc26de","8b1cf51c5f03c0ae19c46ca3ea4a1158acbb6e47bf109ca8c506c5417b51cf9f","95115e1052b5ea4fcd393f5c9b9c6f0298657f0028eee84e16215ede97576cfa","ab4502eff76606ac8e58b623878f3d76e1e0b18f30796aec7c446e2aab8b57c8","c01c2c98f13a65b49113916a2f295e46a03fc4c185ece880267dd86c3f3dee8b","d557525e3ebfad227c8d6db9bb6350d42506fb02b1de8058cb443f4f008c0f67"],"schema":"fsgg.atlas/1"}
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
{"citations":[{"path":".github/workflows/wasm-installed-org.yml","repository":"FS-GG/FS.GG.Game","revision":"f0cc5d26bfb59aad08022c02e88c7b2ea09a0b5e","sha256":"5d9a89a860e6af539ce4c5e99add2a2d5cc50e217ae36b720a2b8f90a9434221"},{"path":"scripts/wasm-release/bind-installed-release.py","repository":"FS-GG/FS.GG.Game","revision":"f0cc5d26bfb59aad08022c02e88c7b2ea09a0b5e","sha256":"8b7b29fb557c4da4a9efb1c72019a7420d35f9b53d20a46ffa873e0d5e907ecc"},{"path":"scripts/wasm-release/promotion.py","repository":"FS-GG/FS.GG.Game","revision":"f0cc5d26bfb59aad08022c02e88c7b2ea09a0b5e","sha256":"04daa5cadd0e38c7356283bc69d6ebaefc6beca09689f59b0e9006579beee6cf"},{"path":"scripts/wasm-release/installed-evidence.py","repository":"FS-GG/FS.GG.Game","revision":"f0cc5d26bfb59aad08022c02e88c7b2ea09a0b5e","sha256":"7401ebe96e11b8d2b9042edf80b3457304f6d11ab8278a5944cc2b99a47b94d1"},{"path":"scripts/verify-wasm-package-consumer.sh","repository":"FS-GG/FS.GG.Game","revision":"f0cc5d26bfb59aad08022c02e88c7b2ea09a0b5e","sha256":"2b705552ff71e2e6bf71162748ec9b26751eb3e69b17d87d71aa5d1762fef3d1"},{"path":"tests/release/wasm/test-installed-evidence.py","repository":"FS-GG/FS.GG.Game","revision":"f0cc5d26bfb59aad08022c02e88c7b2ea09a0b5e","sha256":"58acaacfde28c90374562fafd60b218f4b595cbf7015bf48d71fe20b3a3c556f"},{"path":"tests/release/wasm/test-installed-org-workflow.py","repository":"FS-GG/FS.GG.Game","revision":"f0cc5d26bfb59aad08022c02e88c7b2ea09a0b5e","sha256":"6af07717fb185f0f86c369fabe25af7bbbe3acf459474e652bcea1c9edaa263a"},{"path":"tests/release/wasm/test-release-promotion.py","repository":"FS-GG/FS.GG.Game","revision":"f0cc5d26bfb59aad08022c02e88c7b2ea09a0b5e","sha256":"61e7cc8408712b0770016a5c6ba810dc8d13d5246337bddf56ed5e0cdce0cc08"},{"path":"docs/roadmaps/wasm-shared-01.md","repository":"FS-GG/FS.GG.Game","revision":"f0cc5d26bfb59aad08022c02e88c7b2ea09a0b5e","sha256":"e2266309d5b2eb233ebdd717f9ecac5143b84f53eff11522541d0e8d198d8b35"}],"conflictsWith":[],"id":"game/current-wasm-custody-source-boundary","kind":"boundary","recordedAt":"2026-10-17T08:46:10Z","repository":"FS-GG/FS.GG.Game","schema":"fsgg.atlas/1","status":"recorded","summary":"Current 0.4 publication is accepted at immutable producer/publisher P=E6732d2371d142d5ccc5d2d127f20e4f179800892, treecc71e7cfe73449919376acf775940ff9e8bdab56, original39015233527/attempt1. The first installed operation39016307973/attempt1 remains failed: org completed actual runtime tests, but recursive evidence upload rejected a colon in NuGet HTTP-cache paths and retained zero artifacts; public was cancelled before execution. This is not both-feed acceptance. The selected source correction introduces one clean current qualifier/executor Q separately from immutable publication P: current workflow/checkout/main/manual-event/first-attempt checks address Q, while original qualification, admission, transaction, tag, manifest, SDK, archive/member/hash/signature checks still address P. A complete P-to-Q path/blob/content-hash audit refuses changes outside the finite reviewed binding, evidence, controls and owning-documentation closure. Package/runtime/Worker sources, models, traces, projects, locks, semantic consumer assertions and tool/version inputs remain identical to P. Default publisher writer predicates retain same-current-source constraints; no global identity substitution, historical overlay, repack or package fallback is allowed. Functional citations identify executable f0cc5d26, the connected correction following initial candidate23d4ffb, before its final metadata append; independent final review remains required. The subsequent same-delivery amendment adds exactly the catalog and this content-addressed record path to that finite whitelist and requires exact review; neither citation revision nor source audit omits the final metadata delta. The general consumer projects actual archives, hidden NuGet metadata, raw lock/config, SDK, signature/member output and compiled runtime/Worker proof before temporary cleanup. Independent final collection retains selected proof, actual official/reference/runtime Core, P/Q/native-publication receipts and logs in a bounded portable archive, excluding HTTP/tool caches and node_modules. Original command exit, log-copy failure, collection, cleanup and native upload outcomes remain distinct; missing proof is ineligible. Both independently guarded feeds remain serial, with fail-fast disabled and unchanged45-minute per-job limit. Refusal caps are512MiB total,256MiB per file,32MiB logs,1MiB metadata and1024regular members including manifest; actual complete projection fit and both feed closures must be measured, not inferred. Source/inert checks and old org-only execution do not establish repaired runtime acceptance. Complete applicable coherent CI, a separately selected fresh installed operation and independent artifact/data readback remain owed before consumer adoption; publication stays accepted and original failures/unknown cleanup facts retain their identities.","supersedes":["8b1cf51c5f03c0ae19c46ca3ea4a1158acbb6e47bf109ca8c506c5417b51cf9f"],"tags":["wasm","installed","publication","qualification","source","evidence"],"title":"Installed qualification separates immutable publication from its current reviewed executor"}
Loading
Loading