#23 add contract release checklist fix - #170
Open
onakijames-droid wants to merge 2 commits into
Open
Conversation
Contributor
| \nThis PR is currently blocked by merge conflicts.\n\nPlease update the branch with the latest main branch and resolve the conflicts before it can be merged. |
Contributor
| \nGitHub has not finished calculating whether this PR can be merged cleanly.\n\nThe auto-merge automation will skip this PR for now. Re-run the automation later. |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
CLOSE #23 Add contract release checklist
Description
Adds a repeatable release gate for contract changes, plus automation so the
mechanical parts cannot rot.
Finding. The repo had no release process.
CONTRIBUTING.mdcovered PRworkflow but nothing covered cutting a release, so a contract change could ship
without anyone verifying compliance enforcement, storage compatibility, or event
compatibility.
The deeper problem is that this codebase has tight, invisible coupling across
a language boundary. The
monitoring/service decodes contract events inJavaScript. A single
#[contractevent]change silently breaks four things —the monitor's decoder (
ACTION_SCHEMA), the dashboard tag style, the dashboarddetails()renderer, and analytics volume math — with no compile erroranywhere, because the seam is Rust → JS.
A prose-only checklist would not catch that, and would rot. So this PR ships
both halves:
docs/release-checklist.md— 10 sections covering every area the issueasked for, grounded in this codebase (real test names, real
DataKeyvariants, real panic strings), plus a versioning policy and a copy-paste
sign-off record.
scripts/check-release-compat.sh— enforces the mechanical items:storage layout, contract↔monitor event parity, namespace pinning, dashboard
render coverage, and spec documentation coverage.
Standing risk register (new)
Writing the Roles and Storage sections required reading the contract
closely, which surfaced five genuine pre-existing properties. These are now
documented as R1–R5 in §9, each with an owner prompt and re-confirmation
requirement at every release:
initialize()has norequire_auth()— any address can call it first on a fresh deployment and seize adminsrc/lib.rsset_adminabsent) — lost key ⇒ redeploysrc/compliance.rsextend_ttl()anywhere, despitedocs/architecture.mdclaiming entries are "rent-exempted appropriately" — archived balances become unreachabledistribute_yieldis a mock: emits an event, moves no valuesrc/asset.rsThese are documented, not fixed. This is a Documentation issue, and R1/R3
are design decisions for maintainers rather than something to patch silently.
R1 in particular deserves a follow-up issue.
Key files
docs/release-checklist.md(new, 314 lines)scripts/check-release-compat.sh(new, 212 lines)Makefilecompat-check(L42) andrelease-check(L56) targets;verifynow depends oncompat-check(L47)README.md## Releasingsection linking the checklistCONTRIBUTING.md## Releasingsection for maintainersNew public interfaces
No contract code changed. No new functions, events, error codes, or roles.
New developer-facing entry points only:
make compat-check— compatibility drift detection (exit 1 on drift)make release-check— full gate + WASM sha256 + manual sections to sign offBASELINE_DATAKEYSinscripts/check-release-compat.sh:30— editing thisline is the storage-migration decision, deliberately made explicit
Related Issues
Fixes #
Completion Table
docs/release-checklist.md— 10 sections (L32–L259) covering all nine suggested areas: tests (§1), storage (§2), events (§3), errors (§4), roles (§5), compliance (§6), SDK (§7), dashboard (§8), audit (§9); plus versioning policy (L261) and sign-off record (L276)make verifyexit 0. Section coverage audited against the issue's suggested list — 9/9 presentdocs/release-checklist.mdis_whitelistedcall site", insufficient-balance revert,WhitelistAddaudit trail,instant-drainalert rule. Ties to real teststest_mint_to_non_whitelisted_fails,test_transfer_insufficient_balance_fails. Scope boundary stated: ledger-level onlycargo test9/9. Compliance risk R3 (no revocation) documented at L255docs/contract-spec.md— enforcement semantics unchanged by this PRDataKeyvariants, variant reordering (positional encoding hazard), value-type changes, durability per key, no-upgrade-entrypoint reality, TTL/archival (R4). §3 (L95–L120) events: handler parity, topic order/arity, data format, ≤4 topic limit, fixture regeneration. Automated byscripts/check-release-compat.sh§1 (L53) and §2 (L76)DataKey::FeeBps→ 1 FAIL, exit 1. NT-2 newburnevent → 4 FAILs (undecodable + unstyled + unrenderable + undocumented). NT-3 namespace →aegis2→ 1 FAIL. NT-4 removed spec entry → 1 FAIL. Clean tree restored → exit 0 after eachdocs/architecture.md— storage model unchanged; R4 flags its existing rent claim as unimplementedsoroban-sdkpin (26.0.0), signature/arg-order stability, spec documentation, binding regeneration,i128exactness, deprecated-API avoidance. §8 (L207–L225) dashboard: tag style +details()coverage,VALUE_ACTIONSanalytics,defaults.jsrule validity, field-name parity, historical replay decode, contract-ID update. Automated atscripts/check-release-compat.sh§3 (L136) and §4 (L173)make compat-check— 10/10 PASS on clean tree. NT-2 proves dashboard gaps are caught (tag style +details()both FAIL). Monitoring suite 106/106monitoring/README.md— service behaviour unchangedcargo tree/npm audit), audit-status recording, testnet rehearsal + on-chainInitverification, standing risk register R1–R5 (L253–L257) requiring per-release re-confirmationmake verifyexit 0 (fmt + clippy-D warnings+ tests + build + monitoring). R1 mitigation is operational and stated as a §5 checkboxREADME.md## Releasingsection linksdocs/release-checklist.mdand documents the three make targets. Also linked fromCONTRIBUTING.mdfor maintainers../README.md,../CONTRIBUTING.md,../monitoring/README.md,../scripts/check-release-compat.sh,contract-spec.md,architecture.md) — 0 dead linksREADME.md,CONTRIBUTING.mdNo incomplete criteria.
Detailed Traceability Mapping
docs/release-checklist.mdmake verifyexit 0; contract 9/9, monitoring 106/106 unchanged from baselinetest_mint_to_non_whitelisted_fails(src/test.rs:L273),test_transfer_insufficient_balance_fails(src/test.rs:L287)scripts/check-release-compat.shL53, L76BASELINE_DATAKEYS = "Admin Balance TotalSupply Whitelist"(script L30) records the current layout; the script fails on any add/remove/renameinit,wl_add,mint,transfer,yield) still have off-chain handlersmonitoring/tests/onchain-compat.test.js10/10make compat-check10/10 PASS; NT-2 proves unstyled/unrenderable actions are caught; monitoring 106/106?on the compliance dashboard — a monitoring blind spot during an incidentmake verifyexit 0 — fmt clean, clippy 0 warnings, 9/9 + 106/106Initverification (R1 mitigation), explicit audited/unaudited disclosureREADME.md,CONTRIBUTING.mdStorage summary: this PR changes no storage, no events, and no contract
code.
DataKey::{Admin, Whitelist, Balance, TotalSupply}and all five eventsare untouched. The only contract-adjacent artifact is the recorded baseline
the drift checker compares against.
Type of Change
Makefiletargets +scripts/check-release-compat.shPR Evidence Checklist
1. Issue Reference
Fixes #<!-- number -->— fill in on open).2. Implementation Summary
tooling only). New developer-facing make targets documented.
3. Tests Added or Justification
Covered. This is a documentation/tooling change, so the "tests" are the
script's own negative tests — verifying it detects drift, not merely
that it passes:
DataKey::FeeBpstosrc/lib.rsburn#[contractevent]NAMESPACE→'aegis2'distribute_yieldfrom the specExisting suites unchanged and passing: contract 9/9 (
src/test.rs),monitoring 106/106 (
monitoring/tests/).Script robustness verified:
bash -nclean, runs correctly from any cwd,emits no ANSI escapes when piped (CI-safe).
No-Test Justification — not needed.
4. Commands Run
make verifypasses locally — exit 0. Output in Additional Context.5. CI Status
(
auto-trigger.yml,trigger-auto-assign.yml) only dispatch to anexternal automation repo; there is no build/test CI to observe. If CI is
added,
make verifyis the single command to wire in.6. Acceptance Criteria Coverage
N/A+reason where no doc change was needed (AC 2, AC 3, AC 4).
Policy & Standards
docs/contributor-evaluation-policy.mdis not present in this repo; could not read it.
CONTRIBUTING.mdand followed it (and extended it with amaintainer-facing Releasing section).
cargo fmt --all --check— clean.cargo clippy --all-targets -- -D warnings— 0 warnings.cargo test— 9 passed, 0 failed, 1 ignored. No contract logicchanged, so no new contract tests were required; the new tooling is
covered by the negative tests in §3.
explicitly "None", with the recorded baseline noted).
docs/reviewer-checklist.mdnot present.docs/legal-boundary-disclaimer.mdnot present; see note below.
Additional Context
make verifyoutput (exit 0)WASM sha256
c1ae3186984a151e2853d5da3f7510767e466350e19c1b009ad0369c86537666(15,470 bytes) — unchanged from before this PR, confirming no contract impact.
Two issues found and fixed during verification
The script lost its executable bit in transit, which would have broken
make compat-checkon a fresh clone withPermission denied. Fixed byinvoking it as
bash ./scripts/check-release-compat.shin the Makefile, sothe gate works regardless of file mode (common with zip downloads and some
Windows checkouts). Verified by deliberately running
chmod -xandconfirming the target still passes.
A full
cargo buildcan be OOM-killed on small runners(
signal: 9, SIGKILLwhile compilingstellar-xdr). This is an environmentlimit, not a code error. Documented in checklist §1 with the workaround
(
cargo test -j 1) so a maintainer does not mistake it for a broken release.Reviewer note on
BASELINE_DATAKEYSscripts/check-release-compat.sh:30hardcodes the current storage layout. Thisis intentional: it makes changing storage an explicit, reviewable line in the
diff rather than something that happens silently. If you'd prefer it generated
or moved to a separate manifest, that's an easy follow-up — but the property
worth preserving is that a storage change must be consciously acknowledged.