Skip to content

docs(testnet): data retention policy, breaking-change notice period, and scoped contribution guide - #754

Merged
phertyameen merged 1 commit into
bridgelet-org:mainfrom
Fahmedo:docs/testnet-policy-documents
Sep 27, 2026
Merged

phertyameen merged 1 commit into
bridgelet-org:mainfrom
Fahmedo:docs/testnet-policy-documents

Conversation

@Fahmedo

@Fahmedo Fahmedo commented Sep 27, 2026 •

Copy link
Copy Markdown
Contributor

Summary

Three policies for the testnet/ documentation tree. testnet/policies/ contained only versioning-scheme.md, so this is most of the substance of that directory. Each follows the house structure of the tree's existing documents rather than the thinness of its one sibling.

File Issue Lines
testnet/policies/data-retention.md #658 434
testnet/policies/breaking-change-notice.md #659 522
testnet/policies/contribution-guide.md #660 451

versioning-scheme.md is unmodified. scripts/, tools/, contracts/ and deployments/ are untouched.

data-retention.md — no PII on a shared testnet

The argument that actually persuades is up front, because a policy without it gets ignored: once written, data is irretrievable and may be preserved by third parties — explorer indexing, RPC archival, mirrors — outside the project's control. So "delete it later" is not available, and everything else follows.

The rules are concrete rather than categorical: real names, contact and government ID numbers, addresses, payment and bank details, seed phrases, customer or employee records, medical and financial data, live credentials. "Synthetic" is defined precisely — generated for this purpose, mapping to no real entity, and not a transformation of real data — with the note that a lightly-anonymised real customer name is still a real customer name.

The metadata angle is grounded rather than asserted: several EphemeralAccount events carry addresses and amounts, so on-chain metadata really is world-readable, with testnet/registry/event-topics.md as the mechanism.

The relationship to the existing no-secrets rules is stated rather than duplicated — testnet/config/README.md and testnet/security/README.md permit public on-chain identifiers, while this policy says do not associate real people with them in the first place. The no-secrets discipline is extended, not restated.

A pre-flight checklist covers the specific Bridgelet touchpoints, including recovery_address (the fallback wallet funds return to on expiry, so putting a real personal wallet there is a concrete risk). The wallet-key rule is stated hard: never a mainnet key or a key holding real funds, on testnet, ever — and if someone discovers they violated it, they get a concrete recovery path rather than an implied obligation.

breaking-change-notice.md — 7 days, with a 14-day tier

A concrete number, justified against a realistic consumer integration loop rather than picked as a round number. 3 days cannot fit the integration-suite cycle the period exists to protect. And promising 14 before the project has ever sustained 7 would teach integrators the changelog is advisory.

The 14-day tier covers changes that fail silently — error discriminants, enum ordering, new preconditions on all calls — because those are the ones that don't announce themselves: indexers stop matching and clients misclassify.

"What counts as breaking" is derived from the real code, using the changelog's own Unreleased entry as the worked example: initialize gains an authorized_signer argument, moving from five arguments to six, so existing five-argument calls fail after redeployment. The passphrase check is the second example — a change that only rejects testnet calls at runtime is a spectacular way to surprise an integrator.

The notification channel is testnet/docs/changelog.md, whose existing "How to update this file" section and five-field entry template are reused rather than replaced by a parallel process. A notice published after the fact is not notice, and the document says so.

Exemptions are enumerated honestly — an SDF-initiated reset, a security fix where notice widens exposure, a platform change outside project control — each requiring maximum-possible notice plus a prominent retrospective entry, and naming them as the cases integrators will actually be bitten by. What Is Not Decided is a real section, following the precedent of testnet/tooling/decision-log.md; inventing false certainty there would be a defect.

contribution-guide.md — scoped, because the repo needs it

There is no top-level CONTRIBUTING.md anywhere in the repository, and .github/ contains only two workflow files — no issue template, no PR template, no CODEOWNERS. A project-wide guide would be a separate, larger piece of work, and pretending otherwise would create the exact confusion this document exists to prevent.

The most useful section maps what belongs in each testnet/ subdirectory, read from the existing files rather than assumed, and reuses the distinction decision-log.md already draws between testnet/tooling/ specs and scripts/ build scripts.

The non-negotiable rules are separated out because violating them is harmful: never claim on-chain observation, never paste a secret, verify every fact against the source, don't edit scripts/ or tools/, keep changes inside testnet/.

That third rule names the specific traps found while writing this batch: the changelog's error-namespacing claim is not implemented in the source, and SweepController's UnauthorizedDestination = 13 leaves a gap at 12. A contributor who trusts a document over the code gets both wrong.

Workflow and a definition-of-done checklist follow, plus an honest not-decided section on the tree's future shape.

Repository defects found, documented rather than papered over

Beyond the two I already knew (the error-namespacing claim, the = 13 gap):

  1. The changelog's #1007 passphrase check and is_initialized() -> bool are not in the source. A repo-wide grep for 1007|Standalone|passphrase over contracts/ and tools/ returns nothing; the only is_initialized is an internal helper in storage.rs, not a #[contractimpl] function. Same failure mode as the namespacing claim.
  2. bridgelet_shared::passphrase::TESTNET_PASSPHRASE does not exist. network-config.md:97-98 cites it; contracts/shared/src/ contains only lib.rs and types.rs.
  3. network-config.md:63 says deployments/testnet.json "still contains null placeholders" — it contains four populated contract IDs and six config values. The registry conflict is real, but this characterisation of it is wrong.
  4. testnet/docs/support.md bakes in the unimplemented namespacing — its issue template tells reporters to expect Error(Contract, #2003).
  5. testnet/tooling/decision-log.md:11 references testnet/tooling/README.md as "the index for this directory" — the file did not exist until Ogunmepon's PR docs(testnet): tooling directory index, sweep-signer usage notes, and two tooling specs #753. Same for testnet/config/friendbot.md at line 93.
  6. testnet/reset/communication-template.md points integrators at config/testnet_contracts.json — that path does not exist.
  7. cargo_description and a notes field do not exist in this repository at all. AccountInitRequest is exactly { expiry_ledger: u32, recovery_address: Address }. The policies name these as phantom touchpoints explicitly, on the reasoning that a contributor reading a sibling document could otherwise believe cargo_description exists and try to document it — a policy naming non-existent arguments would be worse than one that doesn't.

Verification

  • git status shows exactly three new files. versioning-scheme.md, scripts/, tools/, contracts/ and deployments/ are all unmodified.
  • All 36 relative links ls-verified.
  • No secret-shaped strings.
  • No on-chain observation claims — the only matches for such phrasing are the prohibitions themselves.
  • testnet/policies/ has no README.md, so the additive-index-line allowance had nothing to apply to. I did not create one, since a fourth file is a scope decision; it is flagged as an open question instead.

Closes #658
Closes #659
Closes #660

…ontribution guide

Three policies for the testnet/ documentation tree. testnet/policies/
contained only versioning-scheme.md, so this is most of the substance of that
directory. Each follows the house structure of the tree's existing documents
rather than the thinness of its one sibling.

testnet/policies/data-retention.md

No PII or production-equivalent data on a shared, public testnet. The
argument that actually persuades is up front: once written, data is
irretrievable and may be preserved by third parties - explorer indexing, RPC
archival, mirrors - outside the project's control, so "delete it later" is
not available. Everything else follows from that.

The rules are concrete rather than categorical, since vague categories are
what makes policies get ignored: real names, contact and government ID
numbers, addresses, payment and bank details, seed phrases, customer or
employee records, medical and financial data, and live credentials. "Synthetic"
is defined precisely - generated for this purpose, mapping to no real entity,
and not a transformation of real data - and the document says plainly that a
lightly-anonymised real customer name is still a real customer name.

The metadata angle is grounded rather than asserted: several EphemeralAccount
events carry addresses and amounts, so on-chain metadata really is
world-readable, with testnet/registry/event-topics.md as the mechanism.

The relationship to the existing no-secrets rules is stated rather than
duplicated - testnet/config/README.md and testnet/security/README.md permit
public on-chain identifiers, while this policy says do not associate real
people with them in the first place - and the no-secrets discipline is
extended, not restated.

A pre-flight checklist covers the specific Bridgelet touchpoints, and the
wallet-key rule is stated hard: never a mainnet key or a key holding real
funds, ever. If someone discovers they have violated it, they get a concrete
recovery path rather than an implied obligation. There is also an honest
incident path, given that on-chain data generally cannot be deleted.

testnet/policies/breaking-change-notice.md

A minimum advance-notice period, with a concrete number: 7 days default and a
14-day tier, justified against a realistic consumer integration loop rather
than picked as a round number. 3 days cannot fit the integration-suite cycle
the period exists to protect, and promising 14 before the project has ever
sustained 7 would teach integrators the changelog is advisory.

The 14-day tier covers changes that fail silently - error discriminants, enum
ordering, and new preconditions on all calls - because those are the ones that
do not announce themselves: indexers stop matching and clients misclassify.

"What counts as breaking" is derived from the real code, using the changelog's
own Unreleased entry as the worked example: initialize gains an
authorized_signer argument, moving from five arguments to six, so existing
five-argument calls fail after redeployment. The passphrase check is the
second example, since a change that only rejects testnet calls at runtime is
a spectacular way to surprise an integrator.

The notification channel is testnet/docs/changelog.md, whose existing "How to
update this file" section and five-field entry template are reused rather than
replaced by a parallel process. A notice published after the fact is not
notice, and the document says so.

Exemptions are enumerated honestly - an SDF-initiated reset, a security fix
where notice widens exposure, a platform change outside project control - each
requiring maximum-possible notice plus a prominent retrospective entry, and
naming them as the cases integrators will actually be bitten by. What Is Not
Decided is a real section, following the precedent of
testnet/tooling/decision-log.md; inventing false certainty there would be a
defect.

testnet/policies/contribution-guide.md

A scoped mini-guide, which is the right size of answer here: there is no
top-level CONTRIBUTING.md anywhere in the repository, and .github/ contains
only two workflow files - no issue template, no PR template, no CODEOWNERS. A
project-wide guide would be a separate, larger piece of work, and pretending
otherwise would create the confusion this document exists to prevent.

The most useful section maps what belongs in each testnet/ subdirectory, read
from the existing files rather than assumed, and reuses the house distinction
already drawn by decision-log.md between testnet/tooling/ specs and scripts/
build scripts. The non-negotiable rules are called out separately because
violating them is harmful: never claim on-chain observation (nothing is
deployed), never paste a secret, verify every fact against the source and
prefer the source over another document, do not edit scripts/ or tools/, and
keep changes inside testnet/.

That third rule names the specific traps found while writing this batch: the
changelog's error-namespacing claim is not implemented in the source, and
SweepController's UnauthorizedDestination = 13 leaves a gap at 12. A
contributor who trusts a document over the code gets both wrong.

The workflow and a definition-of-done checklist follow, plus an honest
not-decided section on the tree's future shape.

All three state that these are documentation and process, not enforcement:
nothing is deployed, initialize cannot distinguish a synthetic address from a
real one, and compliance with the notice period has no automated check.

Closes bridgelet-org#658
Closes bridgelet-org#659
Closes bridgelet-org#660
@drips-wave

drips-wave Bot commented Sep 27, 2026

Copy link
Copy Markdown

@Fahmedo Great news! 🎉 Based on an automated assessment of this PR, the linked Wave issue(s) no longer count against your application limits.

You can now already apply to more issues while waiting for a review of this PR. Keep up the great work! 🚀

Learn more about application limits

@phertyameen
phertyameen merged commit 87c04b6 into bridgelet-org:main Sep 27, 2026
1 check passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

2 participants