Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
310 commits
Select commit Hold shift + click to select a range
63774aa
test(release): model complete receipt-bound updater publication set
seonghobae Sep 14, 2026
03555ee
test(release): reproduce updater manifest publication gap
seonghobae Sep 14, 2026
340b476
fix(release): bind updater manifest to receipt-authorized bytes
seonghobae Sep 14, 2026
4d6f7cb
fix(release): publish receipt-bound updater manifest
seonghobae Sep 14, 2026
64fbd14
fix(release): preserve exact updater signature text
seonghobae Sep 14, 2026
889554d
test(release): cover manifest publication boundary cleanly
seonghobae Sep 14, 2026
f0d6dd5
docs(release): trace receipt-bound updater manifest publication
seonghobae Sep 14, 2026
db4ad06
test(release): reproduce hosted asset re-verification gap
seonghobae Sep 14, 2026
e022794
fix(release): re-admit downloaded hosted release assets
seonghobae Sep 14, 2026
3c9221b
fix(release): re-verify draft and published release bytes
seonghobae Sep 14, 2026
3412a19
test(release): format hosted re-verification coverage
seonghobae Sep 14, 2026
4c1dfe9
docs(release): trace hosted release byte re-verification
seonghobae Sep 14, 2026
0f13ef0
test(release): require immutable release attestation gate
seonghobae Sep 14, 2026
b65f00c
fix(release): verify immutable release attestation
seonghobae Sep 14, 2026
d6cc359
docs(release): trace immutable release attestation gate
seonghobae Sep 14, 2026
57ced89
test(release): require updater manifest security metadata
seonghobae Sep 14, 2026
21ee4ff
fix(release): bind updater security metadata to receipts
seonghobae Sep 14, 2026
209f58e
docs(release): trace updater security metadata boundary
seonghobae Sep 14, 2026
857e1e9
test(release): cover updater policy metadata admission
seonghobae Sep 14, 2026
4467a9e
test(distribution): require Rust updater lifecycle core
seonghobae Sep 14, 2026
1339cfd
feat(distribution): add updater lifecycle Rust core crate
seonghobae Sep 14, 2026
0fbb2e8
build(distribution): lock updater lifecycle core
seonghobae Sep 14, 2026
42fdeed
fix(distribution): enforce updater anti-replay and rollback decisions
seonghobae Sep 14, 2026
cd25fab
docs(distribution): trace anti-replay rollback decision core
seonghobae Sep 14, 2026
d80a477
chore(distribution): deny warnings and missing rustdoc
seonghobae Sep 14, 2026
a0a9eec
docs(architecture): register Distribution update decision core
seonghobae Sep 14, 2026
9df9e61
docs(product): establish commercial technical gap baseline
seonghobae Sep 14, 2026
fa5690b
test(distribution): require durable highest-seen state suite
seonghobae Sep 14, 2026
f07f35e
feat(distribution): establish highest-seen state crate
seonghobae Sep 14, 2026
30159e0
build(distribution): lock highest-seen state graph
seonghobae Sep 14, 2026
95889b6
feat(distribution): persist replay authority as bounded append log
seonghobae Sep 14, 2026
05a8dc9
docs(distribution): trace durable updater freshness state
seonghobae Sep 14, 2026
9a481cc
docs(product): record durable updater-state progress
seonghobae Sep 14, 2026
fb1ac16
fix(distribution): disambiguate bounded state read
seonghobae Sep 14, 2026
6826c92
docs(architecture): register durable Distribution state owner
seonghobae Sep 14, 2026
e525aa1
test(distribution): require authenticated runtime admission suite
seonghobae Sep 14, 2026
5c95912
feat(distribution): add runtime admission crate manifest
seonghobae Sep 14, 2026
b9f72be
build(distribution): lock runtime path dependency graph
seonghobae Sep 14, 2026
85db601
feat(distribution): bound raw updater metadata as provisional input
seonghobae Sep 14, 2026
def74ef
refactor(distribution): keep provisional runtime admission stateless
seonghobae Sep 14, 2026
418c68d
build(distribution): minimize provisional runtime lock graph
seonghobae Sep 14, 2026
1c52911
docs(distribution): correct raw updater metadata trust boundary
seonghobae Sep 14, 2026
d0bdea0
docs(product): expose updater metadata-authentication gap
seonghobae Sep 14, 2026
8533403
docs(architecture): separate provisional updater metadata from authority
seonghobae Sep 14, 2026
59bc8c8
fix(updater): pin provisional release download namespace
seonghobae Sep 14, 2026
daad6e5
fix(updater): keep URL admission Rust-stable
seonghobae Sep 14, 2026
e25c3f1
docs(updater): trace pinned release URL admission
seonghobae Sep 14, 2026
1e1f1c2
test(distribution): require bounded updater download contract
seonghobae Sep 14, 2026
f183c0c
feat(distribution): add bounded updater artifact streaming
seonghobae Sep 14, 2026
19c5983
docs(distribution): trace bounded updater streaming boundary
seonghobae Sep 14, 2026
21f3bee
docs(product): make bounded updater download gap code-current
seonghobae Sep 14, 2026
539fbe2
docs(architecture): add bounded updater download owner
seonghobae Sep 14, 2026
dcc04b7
test(distribution): require crash-safe updater staging sink
seonghobae Sep 14, 2026
ed079fd
feat(distribution): add exclusive updater staging sink
seonghobae Sep 14, 2026
7620248
test(distribution): cover updater staging failure cleanup
seonghobae Sep 14, 2026
00825be
docs(distribution): trace exclusive updater staging lifecycle
seonghobae Sep 14, 2026
e485b3a
docs(product): record updater staging boundary
seonghobae Sep 14, 2026
a956bcf
test(distribution): remove unverified sealed artifacts on drop
seonghobae Sep 14, 2026
e76abdd
fix(distribution): clean sealed artifacts until trust promotion
seonghobae Sep 14, 2026
2909133
docs(distribution): trace sealed-artifact cleanup before trust promotion
seonghobae Sep 14, 2026
a065ceb
docs(product): keep sealed updater bytes provisional
seonghobae Sep 14, 2026
56aa746
test(distribution): require sealed read-only descriptor stream
seonghobae Sep 14, 2026
13ca9b7
test(distribution): stop depending on writable sealed handle
seonghobae Sep 14, 2026
6144302
fix(distribution): withhold writable sealed artifact handle
seonghobae Sep 14, 2026
fdd9705
docs(traceability): bind sealed updater reads to descriptor
seonghobae Sep 14, 2026
5568e22
docs(product): keep sealed updater descriptor read-only
seonghobae Sep 14, 2026
f6723cf
docs(architecture): withhold sealed updater write capability
seonghobae Sep 14, 2026
1c8d83d
docs(architecture): restore sources and narrow sealed reader capability
seonghobae Sep 14, 2026
5713689
docs(architecture): restore exact verification wording
seonghobae Sep 14, 2026
e1274be
test(distribution): RED bound sealed reads to admitted bytes
seonghobae Sep 14, 2026
c451096
fix(distribution): cap sealed verifier reads at admitted bytes
seonghobae Sep 14, 2026
e294147
test(distribution): reject sealed descriptor truncation
seonghobae Sep 14, 2026
f6b376a
docs(distribution): trace sealed reader byte-bound repair
seonghobae Sep 14, 2026
56d215e
docs(product): keep sealed verifier resource bound code-current
seonghobae Sep 14, 2026
9f7bddd
test(distribution): require admitted artifact transport binding
seonghobae Sep 15, 2026
663affc
fix(distribution): bind admitted artifact transport fields
seonghobae Sep 15, 2026
ed7426f
docs(distribution): trace admitted transport binding
seonghobae Sep 15, 2026
9c95c71
docs(product): align updater transport gap baseline
seonghobae Sep 15, 2026
46c4cba
docs(architecture): bind updater transport metadata owner
seonghobae Sep 15, 2026
9d1dc2f
test(release): reject runtime-incompatible release versions
seonghobae Sep 15, 2026
e268c9b
fix(release): align release version grammar with updater core
seonghobae Sep 15, 2026
97f9c2a
docs(traceability): bind stable release version grammar
seonghobae Sep 15, 2026
6cee7a6
docs(product): record stable release grammar invariant
seonghobae Sep 15, 2026
1cf9656
test(release): reject version components beyond u64
seonghobae Sep 15, 2026
1c44f25
fix(release): align stable version range with runtime
seonghobae Sep 15, 2026
c2fd0cd
docs(traceability): close stable version range drift
seonghobae Sep 15, 2026
ba426b4
docs(product): record stable version range invariant
seonghobae Sep 15, 2026
6e6ebe2
feat(distribution): add updater transport crate
seonghobae Sep 15, 2026
5f29863
build(distribution): lock transport owner graph
seonghobae Sep 15, 2026
2819481
feat(distribution): add transport response boundary
seonghobae Sep 15, 2026
8f39dfc
test(distribution): require admitted GitHub release redirect
seonghobae Sep 15, 2026
1b4f7a0
test(distribution): gate transport contract in root suite
seonghobae Sep 15, 2026
4964c3c
fix(distribution): admit one-hop GitHub release asset redirects
seonghobae Sep 15, 2026
d424dd8
docs(distribution): trace updater transport policy
seonghobae Sep 15, 2026
adc52ef
docs(product): align distribution transport gap baseline
seonghobae Sep 15, 2026
2e77173
docs(architecture): register updater transport boundary
seonghobae Sep 15, 2026
8313e9f
test(distribution): reject malformed Tauri signature envelopes
seonghobae Sep 15, 2026
6e5e42f
fix(distribution): validate Tauri signature envelope before network
seonghobae Sep 15, 2026
03c1314
test(release): reject non-base64 updater signatures
seonghobae Sep 15, 2026
2c7c772
fix(release): enforce Tauri signature envelope before publication
seonghobae Sep 15, 2026
fd906e2
docs(distribution): trace signature-envelope admission
seonghobae Sep 15, 2026
0e318ef
docs(product): align updater signature-envelope gap
seonghobae Sep 15, 2026
2f5af3e
docs(architecture): align updater signature-envelope ownership
seonghobae Sep 15, 2026
e376325
test(distribution): reject encoded updater response bodies
seonghobae Sep 15, 2026
606095e
fix(distribution): reject transformed updater response bodies
seonghobae Sep 15, 2026
f616421
docs(distribution): trace exact response-byte framing admission
seonghobae Sep 15, 2026
80fdc39
docs(product): record exact-byte updater response framing
seonghobae Sep 15, 2026
c3dbebe
test(distribution): redact redirect queries in diagnostics
seonghobae Sep 15, 2026
be91505
fix(distribution): redact redirect query data from diagnostics
seonghobae Sep 15, 2026
6b8cabb
docs(distribution): trace updater diagnostic redaction
seonghobae Sep 15, 2026
935266a
test(distribution): bound updater signature debug output
seonghobae Sep 15, 2026
1a4e8f5
fix(distribution): bound signature diagnostics
seonghobae Sep 15, 2026
b290bf0
docs(distribution): trace bounded signature diagnostics
seonghobae Sep 15, 2026
027ba14
test(distribution): reject provisional signature debug exposure
seonghobae Sep 15, 2026
90855cc
fix(distribution): redact provisional signature diagnostics
seonghobae Sep 15, 2026
bd17041
docs(distribution): record provisional diagnostic redaction
seonghobae Sep 15, 2026
93526ae
docs(gap): keep updater diagnostics buyer truth current
seonghobae Sep 15, 2026
5b0ddb5
test(distribution): require restart recovery for stale staging artifact
seonghobae Sep 15, 2026
b7a1839
fix(distribution): reclaim stale unverified staging artifact on restart
seonghobae Sep 15, 2026
e1b4a81
docs(distribution): trace stale staging restart recovery
seonghobae Sep 15, 2026
84d4a7b
docs(product): record updater staging restart recovery boundary
seonghobae Sep 15, 2026
dcd7a80
docs(distribution): align bounded staging with restart recovery
seonghobae Sep 15, 2026
74565b8
repair(distribution): return product baseline to canonical owner
seonghobae Sep 15, 2026
82843b4
test(distribution): reject reclaiming active staging attempts
seonghobae Sep 15, 2026
40cd754
fix(distribution): lease staging namespace before stale recovery
seonghobae Sep 15, 2026
ebf9428
test(distribution): account for persistent staging lease sentinel
seonghobae Sep 15, 2026
d2d1872
test(distribution): cover sealed lease and lease symlink boundary
seonghobae Sep 15, 2026
ebefa23
docs(distribution): trace active staging lease recovery
seonghobae Sep 15, 2026
9046e90
docs(distribution): make bounded staging lease code-current
seonghobae Sep 15, 2026
752b534
test(distribution): avoid platform-specific reads under staging lease
seonghobae Sep 15, 2026
c30167d
docs(distribution): record cross-platform staging lease fixture
seonghobae Sep 15, 2026
41afd2a
test(distribution): require staging lease contracts on shipped OS fam…
seonghobae Sep 15, 2026
cfb3ec1
ci(distribution): gate staging lease tests on Windows macOS and Linux
seonghobae Sep 15, 2026
137d162
docs(distribution): require cross-platform staging lease evidence
seonghobae Sep 15, 2026
44265a0
test(distribution): prove staging lease across real processes
seonghobae Sep 15, 2026
a999376
docs(distribution): trace real-process staging lease coverage
seonghobae Sep 15, 2026
af89337
test(release): red for descriptor-bound identity inputs
seonghobae Sep 15, 2026
42d34b5
fix(release): bind identity reads to stable descriptors
seonghobae Sep 15, 2026
0ef8912
docs(release): trace descriptor-bound identity admission
seonghobae Sep 15, 2026
68f1bb5
test(release): reject nonstandard JSON constants in identity inputs
seonghobae Sep 15, 2026
494aa0f
fix(release): require strict standard JSON identity metadata
seonghobae Sep 15, 2026
6808f29
docs(traceability): record strict JSON release identity admission
seonghobae Sep 15, 2026
8d56ab1
test(distribution): reject malformed nonselected signature envelope
seonghobae Sep 15, 2026
4e28d0c
fix(distribution): validate all updater signature envelopes
seonghobae Sep 15, 2026
9b691d7
refactor(distribution): keep signature syntax in metadata owner
seonghobae Sep 15, 2026
5b85e03
test(distribution): assert signature envelope owner boundary
seonghobae Sep 15, 2026
89f97a2
docs(distribution): make metadata owner authoritative for signature e…
seonghobae Sep 15, 2026
eb29922
test(distribution): cover signature envelope padding bounds
seonghobae Sep 15, 2026
a62b9ca
docs(architecture): align updater signature-envelope ownership
seonghobae Sep 15, 2026
26ff403
test(distribution): use admitted signature envelopes
seonghobae Sep 15, 2026
11a5a47
test(distribution): bind redirect decisions to policy identity
seonghobae Sep 15, 2026
35b851e
fix(distribution): bind redirect state to policy identity
seonghobae Sep 15, 2026
3f7daa8
docs(distribution): trace redirect policy binding repair
seonghobae Sep 15, 2026
a418640
test(release): reject same-size identity mutation during read
seonghobae Sep 15, 2026
438dca0
fix(release): verify stable identity bytes across descriptor reads
seonghobae Sep 15, 2026
24f8135
docs(release): trace stable descriptor snapshot admission
seonghobae Sep 15, 2026
f0b38c0
test(release): reject path replacement during identity read
seonghobae Sep 15, 2026
906b4f4
fix(release): revalidate identity path after stable read
seonghobae Sep 15, 2026
9671144
docs(traceability): bind release reads back to repository paths
seonghobae Sep 15, 2026
e25fd44
test(distribution): reject concurrent freshness-state writer
seonghobae Sep 15, 2026
dd2ae7f
fix(distribution): serialize highest-seen state access
seonghobae Sep 15, 2026
027963a
docs(distribution): trace highest-seen state lease
seonghobae Sep 15, 2026
e578644
test(distribution-state): reject impossible torn version prefixes
seonghobae Sep 15, 2026
e793d00
fix(distribution-state): reject impossible torn version prefixes
seonghobae Sep 15, 2026
e8a064c
docs(distribution-state): trace impossible torn-tail admission
seonghobae Sep 15, 2026
b633482
test(distribution): reject hard-linked freshness state
seonghobae Sep 15, 2026
4f8c933
fix(distribution): reject hard-linked freshness authority
seonghobae Sep 15, 2026
bd694de
docs(distribution): trace hard-link state admission
seonghobae Sep 15, 2026
8832e62
test(ci): require hosted coverage for Distribution owners
seonghobae Sep 15, 2026
c5a09d5
fix(ci): execute standalone Distribution owner tests
seonghobae Sep 15, 2026
835bfb5
docs(ci): bind Distribution owners to hosted platform tests
seonghobae Sep 15, 2026
4aca07e
test(distribution): reject replacement-path cleanup
seonghobae Sep 15, 2026
bc72745
fix(distribution): preserve replaced staging paths
seonghobae Sep 15, 2026
ecec997
docs(distribution): trace staging cleanup identity
seonghobae Sep 15, 2026
e07a50d
fix(distribution): publish Windows freshness state without alias muta…
seonghobae Sep 15, 2026
5303792
test(distribution): scope link-count rejection to Unix
seonghobae Sep 15, 2026
2f231d6
test(distribution): prove Windows state alias preservation
seonghobae Sep 15, 2026
c2b61b0
docs(distribution): correct Windows freshness-state authority
seonghobae Sep 15, 2026
e3313b9
docs(architecture): align updater state publication semantics
seonghobae Sep 15, 2026
7904f10
test(distribution): reject vulnerable HTTP TLS admission
seonghobae Sep 15, 2026
40496d5
fix(distribution): gate HTTP TLS dependency admission
seonghobae Sep 15, 2026
117962a
docs(distribution): trace HTTP TLS dependency admission
seonghobae Sep 15, 2026
3def1e1
fix(ci): run Distribution HTTP gate in quickcheck
seonghobae Sep 15, 2026
5f81143
test(distribution): reject vendored native TLS no-ALPN feature
seonghobae Sep 15, 2026
b26fc7d
fix(distribution): reject every native TLS reqwest feature
seonghobae Sep 15, 2026
fc22b46
docs(distribution): trace complete reqwest TLS feature admission
seonghobae Sep 15, 2026
621bac6
test(distribution): reject implicit reqwest decoding features
seonghobae Sep 15, 2026
43d7863
fix(distribution): allow-list reqwest transport features
seonghobae Sep 15, 2026
eb10409
test(distribution): cover reqwest feature allow-list
seonghobae Sep 15, 2026
372dd9d
docs(distribution): make reqwest feature admission explicit
seonghobae Sep 15, 2026
d36c4d6
test(distribution): reject target-specific reqwest bypass
seonghobae Sep 15, 2026
da209f1
fix(distribution): inspect target-scoped reqwest dependencies
seonghobae Sep 15, 2026
2b10fe9
docs(distribution): cover target-scoped dependency admission
seonghobae Sep 15, 2026
c58ed76
style(distribution): keep dependency admission formatter-safe
seonghobae Sep 15, 2026
7330af6
test(distribution): reject renamed reqwest admission bypass
seonghobae Sep 15, 2026
5356dcf
fix(distribution): admit renamed reqwest by package identity
seonghobae Sep 15, 2026
49b84eb
docs(distribution): trace Cargo reqwest alias admission
seonghobae Sep 15, 2026
cf6655d
test(distribution): reject workspace-inherited reqwest bypass
seonghobae Sep 15, 2026
8284ae6
fix(distribution): reject workspace-inherited reqwest ownership
seonghobae Sep 15, 2026
6958feb
docs(distribution): trace workspace reqwest inheritance
seonghobae Sep 15, 2026
a8d91b3
test(distribution): reject noncanonical reqwest sources
seonghobae Sep 15, 2026
914609c
fix(distribution): pin reqwest to canonical registry source
seonghobae Sep 15, 2026
e6a0663
test(distribution): reject noncanonical rustls source
seonghobae Sep 15, 2026
4fdc294
fix(distribution): require canonical rustls lock source
seonghobae Sep 15, 2026
2ff17b7
docs(distribution): trace HTTP dependency source provenance
seonghobae Sep 15, 2026
09852dd
test(distribution): reject unbounded reqwest requirements
seonghobae Sep 15, 2026
106d1f6
fix(distribution): bound reqwest version requirements
seonghobae Sep 15, 2026
bd359a3
docs(distribution): trace bounded reqwest requirements
seonghobae Sep 15, 2026
308f4a6
test(distribution): expose Windows staging replacement cleanup
seonghobae Sep 15, 2026
1d60331
fix(distribution): defer unprovable Windows staging unlink
seonghobae Sep 15, 2026
1a6ee09
test(distribution): prove deferred Windows staging reclaim
seonghobae Sep 15, 2026
0bae56f
docs(distribution): trace Windows staging cleanup authority
seonghobae Sep 15, 2026
c69e91d
docs(architecture): align Windows staging cleanup semantics
seonghobae Sep 15, 2026
7996cc2
test(distribution): align sealed cleanup with Windows contract
seonghobae Sep 15, 2026
2acb2f3
test(distribution): align transport staging cleanup by platform
seonghobae Sep 15, 2026
4c94b46
test(distribution): align staging lifecycle with Windows cleanup
seonghobae Sep 15, 2026
2e4c355
test(distribution): clean persistent lease fixtures explicitly
seonghobae Sep 15, 2026
6a85d35
test(distribution): account for persistent staging lease
seonghobae Sep 15, 2026
57385c1
docs(distribution): align bounded staging cleanup claims
seonghobae Sep 15, 2026
64fe0bc
docs(distribution): make restart recovery OS-cleanup current
seonghobae Sep 15, 2026
106e03a
test(distribution): reject unreviewed reqwest release lines
seonghobae Sep 15, 2026
13be264
fix(distribution): bind reqwest admission to reviewed release line
seonghobae Sep 15, 2026
7662556
docs(distribution): trace reviewed reqwest release line
seonghobae Sep 15, 2026
8564741
fix(distribution): expose in-flight staging path
seonghobae Sep 16, 2026
fd29aa1
test(distribution): bind redirects to full provisional identity
seonghobae Sep 16, 2026
6b0fe81
fix(distribution): bind redirect token to full candidate identity
seonghobae Sep 16, 2026
b79a250
docs(distribution): trace full redirect identity binding
seonghobae Sep 16, 2026
9901b2d
test(distribution): preserve candidate identity through sealing
seonghobae Sep 16, 2026
e42f6e6
fix(distribution): bind sealed artifacts to release identity
seonghobae Sep 16, 2026
3ef753f
test(distribution): read sealed artifact through owned descriptor
seonghobae Sep 16, 2026
50f072e
docs(distribution): trace sealed candidate identity binding
seonghobae Sep 16, 2026
dea8f7b
test(distribution): redact sealed transport diagnostics
seonghobae Sep 16, 2026
1136d34
docs(distribution): trace sealed transport diagnostics
seonghobae Sep 16, 2026
dbe7988
test(distribution): reject prerelease TLS boundary drift
seonghobae Sep 16, 2026
98a53d6
fix(distribution): compare TLS advisory prereleases correctly
seonghobae Sep 16, 2026
a3737a3
docs(distribution): trace prerelease advisory boundary repair
seonghobae Sep 16, 2026
269bd4a
test(distribution): align prerelease rejection receipt
seonghobae Sep 16, 2026
c85402f
docs(distribution): record prerelease regression verification
seonghobae Sep 16, 2026
340e7eb
test(distribution): reject transitive HTTP source substitution
seonghobae Sep 16, 2026
92162da
fix(distribution): bind full HTTP lock graph provenance
seonghobae Sep 16, 2026
6cded37
docs(distribution): trace full HTTP lock provenance
seonghobae Sep 16, 2026
5324118
test(distribution): cover lock provenance admission edges
seonghobae Sep 16, 2026
4920cf2
docs(distribution): record lock provenance edge evidence
seonghobae Sep 16, 2026
ed5be00
test(distribution): reject reqwest feature forwarding
seonghobae Sep 16, 2026
bc56faa
fix(distribution): block reqwest feature forwarding
seonghobae Sep 16, 2026
0f74972
test(distribution): cover weak reqwest feature forwarding
seonghobae Sep 16, 2026
ae98559
docs(distribution): trace reqwest feature forwarding gate
seonghobae Sep 16, 2026
da5c690
test(distribution): document integration test crates
seonghobae Sep 16, 2026
2cd906c
fix(release): revalidate publication asset list
seonghobae Sep 16, 2026
528ba04
docs(distribution): explain consumed staging cleanup
seonghobae Sep 16, 2026
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
44 changes: 43 additions & 1 deletion .github/workflows/build-baseline.yml
Original file line number Diff line number Diff line change
Expand Up @@ -411,7 +411,14 @@ jobs:
supply-chain/supplemental-component-inventory.json
- name: Validate release asset set
run: python3 scripts/release/select_release_assets.py --output release-assets.txt
- name: Create draft release with complete assets, then publish
- name: Build receipt-bound updater manifest
run: |
python3 scripts/release/build_updater_manifest.py \
--git-sha "${{ github.sha }}" \
--repository "${{ github.repository }}" \
--server-url "${{ github.server_url }}" \
--output latest.json
- name: Create draft release, re-verify hosted bytes, then publish
env:
GH_TOKEN: ${{ secrets.BANDSCOPE_RELEASE_TOKEN }}
RELEASE_TAG: ${{ github.ref_name }}
Expand All @@ -426,6 +433,13 @@ jobs:
exit 1
fi
python3 scripts/release/select_release_assets.py --input release-assets.txt
python3 scripts/release/build_updater_manifest.py \
--git-sha "${{ github.sha }}" \
--repository "${{ github.repository }}" \
--server-url "${{ github.server_url }}" \
--output latest.json \
--check
printf '%s\n' latest.json >> release-assets.txt
mapfile -t release_assets < release-assets.txt
(( ${#release_assets[@]} > 0 ))
gh release create "$RELEASE_TAG" \
Expand All @@ -435,4 +449,32 @@ jobs:
--title "BandScope ${RELEASE_TAG#v}" \
--verify-tag \
--repo "${{ github.repository }}"

rm -rf draft-release-download
mkdir draft-release-download
gh release download "$RELEASE_TAG" \
--dir draft-release-download \
--repo "${{ github.repository }}"
python3 scripts/release/verify_hosted_release_assets.py \
--local-root . \
--hosted-root draft-release-download \
--asset-list release-assets.txt

gh release edit "$RELEASE_TAG" --draft=false --repo "${{ github.repository }}"

rm -rf published-release-download
mkdir published-release-download
gh release download "$RELEASE_TAG" \
--dir published-release-download \
--repo "${{ github.repository }}"
python3 scripts/release/verify_hosted_release_assets.py \
--local-root . \
--hosted-root published-release-download \
--asset-list release-assets.txt

gh release verify "$RELEASE_TAG" --repo "${{ github.repository }}"
while IFS= read -r asset; do
[ -n "$asset" ] || continue
gh release verify-asset "$RELEASE_TAG" "$asset" \
--repo "${{ github.repository }}"
done < release-assets.txt
51 changes: 50 additions & 1 deletion .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,8 @@ jobs:
- uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0
with:
persist-credentials: false
- name: Validate Distribution HTTP dependency admission
run: python3 scripts/checks/verify_distribution_http_dependencies.py
- uses: actions/setup-node@48b55a011bda9f5d6aeb4c2d9c7362e8dae4041e # v6.4.0
with:
node-version: "22.22.3"
Expand All @@ -48,9 +50,56 @@ jobs:
- name: Reject manifest or lockfile drift
run: git diff --exit-code -- package.json package-lock.json

distribution-download-platform:
name: gate / ci / distribution-download / ${{ matrix.os }}
needs: lock-validation
strategy:
fail-fast: false
matrix:
os:
- ubuntu-latest
- windows-2025
- macos-15
runs-on: ${{ matrix.os }}
steps:
- uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0
with:
persist-credentials: false
- name: Install stable Rust toolchain
run: rustup toolchain install stable --profile minimal
- name: Test Distribution download staging and lease contracts
run: cargo +stable test --manifest-path apps/desktop/distribution-download/Cargo.toml --locked --all-targets

distribution-owned-platform:
name: gate / ci / distribution-owned / ${{ matrix.os }}
needs: lock-validation
strategy:
fail-fast: false
matrix:
os:
- ubuntu-latest
- windows-2025
- macos-15
runs-on: ${{ matrix.os }}
steps:
- uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0
with:
persist-credentials: false
- name: Install stable Rust toolchain
run: rustup toolchain install stable --profile minimal
- name: Test Distribution state authority contracts
run: cargo +stable test --manifest-path apps/desktop/distribution-state/Cargo.toml --locked --all-targets
- name: Test Distribution metadata admission contracts
run: cargo +stable test --manifest-path apps/desktop/distribution-runtime/Cargo.toml --locked --all-targets
- name: Test Distribution transport contracts
run: cargo +stable test --manifest-path apps/desktop/distribution-transport/Cargo.toml --locked --all-targets

verify:
name: ci / build-and-test
needs: lock-validation
needs:
- lock-validation
- distribution-download-platform
- distribution-owned-platform
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0
Expand Down
28 changes: 26 additions & 2 deletions ARCHITECTURE.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# ARCHITECTURE.md

Last updated: 2026-03-11
Last updated: 2026-09-16

## Brand source

Expand Down Expand Up @@ -58,11 +58,34 @@ Last updated: 2026-03-11
## Repository map

- `apps/desktop` - desktop shell and user-facing React UI
- `apps/desktop/distribution-core` - Tauri-independent Rust security policy for updater release identity, anti-replay, target compatibility, and project-schema-aware rollback decisions
- `apps/desktop/distribution-runtime` - stateless Rust admission boundary for untrusted Tauri updater JSON; validates the complete four-target document including each platform's canonical standard-base64 outer signature envelope, then returns provisional metadata with the selected target's exact admitted URL/signature and cannot mutate freshness state
- `apps/desktop/distribution-transport` - deterministic Rust response-state bridge from the strict provisional target projection to bounded updater staging; consumes metadata-owner signature syntax guarantees and owns exact effective-URL checks plus one-hop release-asset redirect admission, but not sockets, TLS, metadata authentication, minisign verification or installation
- `apps/desktop/distribution-download` - network-library-independent Rust streaming/staging boundary for updater artifacts; owns expected-size/content-length/chunk/cumulative limits, exclusive temporary artifact lifecycle, descriptor-bound Unix cleanup, conservative Windows deferred stale-file reclamation, and read-only descriptor-bound verifier access, but not HTTP, signatures, digests or installation
- `apps/desktop/distribution-state` - Distribution-owned bounded highest-authenticated-release state; Unix uses a single-link append/sync log, while Windows publishes synchronized replacement snapshots to avoid mutating pre-existing hard-link aliases on stable Rust; it consumes `distribution-core` identity and never project bytes
- `packages/shared-types` - stable cross-layer types shared by the UI and orchestration layer
- `services/analysis-engine` - Python analysis service for source separation and music analysis
- `scripts/harness` - fail-fast repo verification
- `scripts/checks` - small doc and structure checks

## Distribution/update bounded context

- Distribution owns commercial release identity, native signing/notarization admission, updater policy, immutable publication evidence, bounded updater artifact transport/storage admission, highest-seen update freshness state, and last-known-good installer recovery decisions.
- `apps/desktop/distribution-core` contains deterministic security decisions only. It does not fetch metadata, verify Tauri signatures, write project data, run installers, or manufacture signing/key authority.
- `apps/desktop/distribution-runtime` admits the current static updater JSON only as bounded provisional remote input. It rejects duplicate/unknown members, unexpected targets, mutable release URLs, invalid release-identity syntax, and any supported platform signature that is not a bounded canonical RFC 4648 standard-base64 outer envelope; retains the selected target's canonical URL/signature from that same strict parse for later transport consumption; and projects the fixed app-owned highest-seen path without creating or writing it. It deliberately has no `distribution-state` dependency, and retained transport fields remain provisional rather than authenticated authority.
- `apps/desktop/distribution-transport` consumes only that already-selected provisional projection and admits updater transport state without reparsing `raw_json` or duplicating signature-envelope syntax. A direct `200` must report the exact canonical initial URL. GitHub release-asset `302` handling is explicit and limited to one HTTPS hop to the current `release-assets.githubusercontent.com` egress allowlist; the follow-up must terminate in `200` at the exact admitted Location and redirect chaining fails closed. The CDN hostname is a product allowlist, not a claim that GitHub guarantees it permanently. The crate has no HTTP client, socket, installer, metadata-authentication, minisign-verification or freshness-state capability.
- Publication mirrors that outer signature-envelope contract after exact receipt binding: `scripts/release/build_updater_manifest.py` requires `.sig` bytes to be canonical standard base64 and the decoded envelope payload to be UTF-8 before static updater JSON can be emitted. This is publication admission only and does not replace Tauri's updater signature verification.
- `apps/desktop/distribution-download` owns the pure streaming/staging primitive used before artifact trust is established. It enforces a 2 GiB artifact ceiling, exact optional `Content-Length`, 1 MiB maximum caller chunk, cumulative overrun rejection before sink write, sink-error poisoning, exact-length completion, exclusive app-owned staging and descriptor-safe cleanup. A sealed artifact remains provisional; downstream verification reads the exact still-open descriptor through a positional `Read` wrapper and cannot obtain the underlying write-capable staging `File` through the public API. Unix cleanup unlinks the staging pathname only when the current direct regular-file `(dev, ino)` still matches the open descriptor, so an already-replaced basename is not deleted as if it were the owned artifact. Windows does not unlink a remembered pathname on `Drop` when stable Rust cannot prove descriptor/path identity; it closes the handle and leaves the unverified scratch file for the next staging attempt, which may reclaim a stale direct regular child only after acquiring the shared staging lease. This trades bounded scratch retention for avoiding deletion of an unrelated replacement object and is not trust promotion. It does not perform network I/O, authenticate metadata, verify signatures/digests, run installers or mutate freshness state. Commercial completion requires the production HTTP adapter to disable implicit redirects, report response state through `distribution-transport`, and route actual response chunks through this boundary rather than relying on Tauri's full-response buffering.
- `apps/desktop/distribution-state` persists only the highest authenticated release identity as a bounded ordered log under a sibling OS lease. It revalidates committed identities, rejects local version regression/equivocation, and recovers only a syntactically valid torn final-record prefix. Unix admits only a single-link state object and uses synchronized append/truncate repair. Windows does not depend on nightly-only link-count metadata: when mutation is required it writes the complete committed bounded log to a `create_new` sibling snapshot, synchronizes it, and replaces only the state pathname, preserving any pre-existing hard-link alias file record. This source-level design is not packaged Windows power-loss proof and does not claim protection from a same-user actor that ignores the advisory lease and races filesystem namespace changes.
- Tauri updater signatures authenticate downloaded updater artifact bytes. They do not, by themselves, authenticate the whole `Update.raw_json` response or BandScope's `sourceCommit`/digest extensions. Remote metadata therefore stays provisional until a canonical metadata-authentication path binds its release identity to trusted authority.
- Only after metadata authentication and updater artifact signature/digest/size binding may exact `version`, `sourceCommit`, updater SHA-256, target, and compatibility floor enter `distribution-core` and `distribution-state` as freshness authority.
- Stable-channel automatic update decisions use canonical numeric `MAJOR.MINOR.PATCH`. Prerelease/build ordering is not approximated; a future beta channel requires a separate ADR and canonical SemVer implementation.
- A release older than locally persisted highest-seen authenticated metadata is replay, and the same version with a different source commit or updater digest is equivocation. Neither may be silently downgraded into a normal update offer.
- Highest-seen release identity belongs to Distribution-owned app state and is recorded only after its metadata identity has authenticated authority; installation completion is not required, but syntactically valid remote JSON alone is insufficient. Project Persistence remains owner of project bytes and project-schema truth.
- Automatic rollback may use only a previously authenticated known-good installer whose version is older than the current installation and whose declared reader can open the current on-disk project schema. The decision core does not bypass project recovery or schema ownership.
- `release/updater-policy.json` remains fail-closed while organization-approved updater key/production endpoint authority is absent. No source code or test fixture is production authority.
- Traceability and claim boundaries live in `docs/traceability/updater-release-admission.md`, `docs/traceability/release-artifact-receipt.md`, `docs/traceability/updater-security-metadata.md`, `docs/traceability/updater-bounded-download.md`, `docs/traceability/updater-staging-path-identity.md`, `docs/traceability/updater-highest-seen-concurrency.md`, and `docs/traceability/updater-transport-policy.md`.

## Product capability scope

- BandScope is not only a shell around chord labels, stems, and ranges.
Expand Down Expand Up @@ -96,10 +119,11 @@ Last updated: 2026-03-11
## Harness decisions

- The harness uses `npm` workspaces for JavaScript/TypeScript and `uv` for Python.
- The desktop app is scaffolded as `Tauri + Vite + React`, but initial verification keeps Rust packaging out of the default quickcheck path.
- The desktop app is scaffolded as `Tauri + Vite + React`. Full Tauri packaging remains outside the default quickcheck path, while security-critical Tauri-independent Rust bounded-context suites may be invoked from repository tests through a narrow validation boundary.
- The desktop shell uses an explicit Tauri CSP that only allows self-hosted assets, inline styles, Tauri IPC, and loopback development traffic.
- Mechanical gates focus on lint, typecheck, unit tests, coverage for Python, and documentation presence.
- Python quality gates also require 100% docstring coverage via `package.json` script `check:python-docstrings`, enforced with Ruff rules `D100` through `D107` across tracked packages, modules, classes, nested classes, functions, methods (including `__init__`), `services/analysis-engine` tests, and repo-owned Python scripts.
- Distribution `distribution-core`, `distribution-runtime`, `distribution-transport`, `distribution-download`, and `distribution-state` Rust compilation denies warnings and missing public rustdoc; their standalone locked unit suites are invoked by the repository analysis test harness without adding Python production logic.
- Mechanical gates also enforce security document presence, plan `Security Notes`, and basic forbidden-pattern checks.
- Security context is part of architecture, not just implementation detail; docs and plans must record the trust boundary touched by risky changes.
- Supply-chain controls are part of the bootstrap architecture, not a release-afterthought.
Expand Down
7 changes: 7 additions & 0 deletions apps/desktop/distribution-core/Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

13 changes: 13 additions & 0 deletions apps/desktop/distribution-core/Cargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
[package]
name = "bandscope-distribution-core"
version = "0.1.0"
edition = "2021"
description = "Pure Distribution/update anti-replay and rollback decision core for BandScope."
publish = false

[workspace]

[lints.rust]
unsafe_code = "forbid"
warnings = "deny"
missing_docs = "deny"
Loading
Loading