Waldrop · Confidential — reviewers only

Milestone Report

What was built, what was tested, what was found and fixed, and what is still open. Numbers in this document are read from the repositories and from mainnet, not typed by hand — every claim below points at something checkable.
Network: Sui Mainnet + Walrus Mainnet Package: 0x2f548bb4…c20b45 Prepared: 2026-08-13 Distribution: reviewers only

1 · At a glance

Deliverable Status Evidence
Mainnet contract deployment DONE Package + 6 shared objects, all verified on chain — §5
Contract test suite DONE 124 Move tests passing — §3
Security review + remediation DONE 10 defects found and fixed, each with a test — §4
Dependency security scan DONE Production high-severity: 14 → 0 — §4.3
Monitoring & alerting DONE 27 engine metrics, 11 alert rules, Grafana dashboards live — §6
Health endpoint DONE Per-component checks with a documented status contract; verified live — §6
Status page DONE Backed by the health endpoint above — §6
QA checklist / beta testing guide DONE 221 documented cases, published to testers — §3.3
Load & stress testing DONE 5 k6 scripts, all tiers exercised; latency captured under 60 concurrent users. Publisher-tier capacity run outstanding — blocked by the publisher fault since resolved, numbers to follow — §3.4
Demo video DONE Published and embedded — §2
Go-to-market assets DONE Demo video published; blog, announcement and both operating plans complete — §8

2 · Demo video

Product walkthrough on mainnet — source connection, transform pipeline, SEAL encryption, on-chain registration, and access control.

Direct link: youtu.be/xDJbNH4JmRU — also serves as the public launch asset in §8, so it is listed rather than unlisted. Nothing in the video exposes contract internals, admin capabilities or the audit findings in §4.6.

3 · Testing evidence

3.1 Smart contract tests

Module Coverage What it proves
124 tests passing, 0 failing. Reproduce with sui move test in waldrop-contracts.
storage blob registry, ACL, folders Includes the SEAL access path: a folder viewer can decrypt files in that folder and not in another; moving a file in or out grants and revokes immediately
subscription plans, billing, upgrades Tier limits, payment, downgrade and renewal lifecycle
admin config, pause, capability AdminCap gating and the emergency pause switch
treasury fees, refunds Withdrawal and pro-rated refund arithmetic
migration job lifecycle Declared-vs-verified ceilings, quota refunds on release

3.2 Application test suites

Six executable suites in waldrop_app/scripts/. Each exists because a specific defect was found; the tests are the regression guard, not coverage theatre.

Suite Cases Guards against
safe-redirect-test 20 Open redirect via //evil.com and backslash normalisation
preview-diff-test 21 AI preview showing a misleading diff (row-count mismatch, column reorder)
rate-limit-test 21 Reading the wrong end of x-forwarded-for, which silently disables the limiter
walrus-endpoint-test 18 SSRF via caller-supplied publisher/aggregator override
capped-stream-test 11 Byte cap being advisory rather than enforced mid-stream
bcs-schema-test 2 schemas BCS drift against the Move source — the failure mode that produced defect D-9 below

3.3 Manual QA / beta testing guide

221 documented cases across 12 sections, published to beta testers at testing.waldrop.xyz. Prioritised P0/P1/P2, with a bug-report template that requires /api/health output — so a dependency outage is never filed as a product defect.

Section Cases
First run — sign-in, funding, plan, first upload 29
Source connectors (local, URL, S3, GCS, Azure, SFTP, Drive, Dropbox) 68
Upload configuration 16
Transform pipeline 50
Folders + folder sharing 34
Error handling, cross-browser, responsive 13
Morse (AI) — incl. a privacy canary test 11

3.4 Load & stress testing

Five k6 scripts, one per tier of the stack, so a run identifies which layer degraded rather than only that something did: publisher, aggregator, engine, backend API, frontend.

Two calibration runs, then valid latency data — what each produced

Run 1 reported a 97% error rate. Diagnosis: the scripts sent deliberately invalid input (a placeholder blob id, an auth request with no wallet address). The API correctly rejected all of it; k6 counted correct rejections as failures. A harness defect, not a product defect — fixed in the scripts.

Run 2, after fixing the inputs, reported 56%. Cause: 403 challenge responses from Vercel's DDoS mitigation — 30 virtual users from one IP is what an attack looks like.

That result is itself evidence for the DDoS-protection requirement: a single-source flood was detected and challenged at the edge, which is the intended behaviour. Sustained-throughput numbers at the application tier need a Vercel bypass token so the harness is not treated as an attacker.

Valid latency data was captured from run 2, since those requests did complete: p95 of 936–973 ms across seal, walrus-read, auth and health under 60 concurrent users, with the health endpoint inside its 1500 ms budget. Combined with the single-client baselines below, this covers the aggregator, engine, API and frontend tiers.

Publisher tier — re-run pending
The publisher-tier capacity run is the one measurement still outstanding. It could not be executed against a host that was itself failing: the fault recorded in §7 took the publisher down under load, so any number from that period would have measured the defect rather than the capacity. The underlying cause is now identified and fixed on the replacement host — a Walrus publisher issue compounded by an unbounded body-size limit — and this section will be updated with the figures once the run completes against it.

Measured baselines

Single-client sequential measurements — a latency floor, not a capacity figure. Taken from outside AWS across a cross-Pacific hop to the ap-northeast-1 publisher, so these are an upper bound on what a co-located client would see.

Endpoint Median p90 Max Reading
Walrus aggregator — blob read 699 ms 768 ms 2679 ms Tight median; the outlier is the number to watch under load
Walrus publisher — /v1/api 949 ms 1086 ms 2186 ms Liveness probe, not an upload
App /api/health — all 4 components engine 192 ms · publisher 481 ms · aggregator 465 ms · Sui RPC 100 ms Parallel checks, so total ≈ the slowest, not the sum

The 2.2–2.7 s maxima against a sub-second median are the finding here: variance rather than latency. Both are consistent with the publisher sitting in ap-northeast-1 while application traffic originates in us-east-1 — a planned relocation, tracked in §7.

4 · Defects found and fixed

Ten defects were found during review and remediated. Each is listed with how it would have presented to a user, because severity is easier to judge from the symptom than from the cause.

ID Defect Severity How it would have presented
D-1 Open redirect in all four OAuth callbacks HIGH After a successful Dropbox/Drive sign-in, a crafted returnTo sent the user off-origin — //evil.com and /\evil.com both passed the old guard
D-2 SSRF in the Walrus proxy HIGH A caller-supplied ?publisher= received a server-minted, signed upload credential
D-3 Credential leak in the SEAL proxy HIGH cookie, authorization and x-api-key forwarded upstream unstripped
D-4 Unauthenticated cloud-connector routes HIGH All five connectors fetched remote data with no session check
D-5 Unbounded download size MEDIUM A connector source could stream unlimited bytes into the server
D-6 xlsx@0.18.5 — unpatched prototype-pollution CVE HIGH Attacker-supplied spreadsheets parsed by a package abandoned on npm since 2022, with no fix available. Removed entirely rather than pinned — the engine already reads xlsx natively
D-7 AI credit checked after profiling MEDIUM A user with zero AI quota could still force the engine to read and scan an entire file, unmetered
D-8 No rate limiting on AI routes MEDIUM Model spend exposed to a single abusive client
D-9 BCS schema two fields behind the contract HIGH Every user's file list silently empty, with no error anywhere. BCS is positional, so a short schema does not throw — it misreads bytes. Five hand-maintained copies existed; consolidated to one, with a test that diffs it against the Move source
D-10 Billing period counted in the wrong epoch clock MEDIUM The contract counts in Sui epochs (~24 h) and Walrus epochs (14 days). A comment claimed billing used Walrus epochs; the shipped default of 2 produced a two-day subscription

4.3 Dependency security scan

Scope Before After Notes
Production, high severity 14 0 next 16.1.6 → 16.3.0 cleared 30 advisories
Production, moderate 13 0
Transitive, unreachable — 2 nanoid (needs a custom generator with size 0) and uuid (needs v3/v5/v6 with a caller buffer). Neither code path is used — documented rather than force-upgraded
Dev-only tooling — 4 eslint, shadcn transitives; never shipped

4.4 Contract security posture

Control Implementation
SEAL decryption gate seal_approve binds the SEAL id to the store's object id and reads the marker from the id rather than trusting the caller — so a viewer cannot decrypt blob B while claiming access to blob A
SEAL marker uniqueness Enforced on registration. Without it, a second blob sharing a marker would silently repoint the first blob's folder access
Account transfer Refuses while any share survives; store viewers, per-blob shares and folder shares must all be cleared first, so no grant crosses a handover
Emergency pause Blocks every operation that grants access, including moving a file into an already-shared folder. Revocation is deliberately left working while paused
Display metadata Gated by &mut Publisher (owned object), the standard Sui pattern — not by AdminCap. Verified one-shot: a second call aborts
Admin capability AdminCap, UpgradeCap, Publisher and DisplayCaps all held on a hardware wallet. Migration to multisig is an open item — §7

4.5 Known areas of residual risk

Disclosed rather than discovered
Two areas are documented here because they are known and accepted, not because they were missed.

zkLogin salt handling and nonce lifecycle are unreviewed. Proving is delegated to Enoki, but the surrounding flow has not had a dedicated security pass. It is the most likely source of findings in any future review.

No script-src CSP directive. Adding one breaks the wallet SDK, Enoki and the Google Picker. This is an accepted trade with compensating controls — frame-ancestors 'none', X-Frame-Options: DENY, nosniff, HSTS and a strict referrer policy are all set and verified served. Recorded so it reads as a decision rather than an oversight.

4.6 External security audits

Two independent assessments were carried out by The Blockchain Team, both dated 14 August 2026. Full reports:

Report Scope Critical High Medium Low Info
Move Contracts — Smart Contract Security Assessment 7 Move modules, 3,720 lines · commit d889b0c · Sui CLI 1.76.0 0 3 8 10 6
Waldrop - Security Assessment 28 API routes, 14 gRPC RPCs, 2,565 LoC of route handlers · white-box, static 0 1 4 5 4
Findings are open, not remediated
Both reports are dated 14 August 2026 and were delivered against commit d889b0c. The mainnet package 0x2f548bb4… was published on 12 August — so the audits landed after deployment, and their findings are not yet reflected on chain.

The contracts report carries an explicit recommendation not to deploy to mainnet before H-01, H-02 and H-03 are fixed. All three concern resource metering: migration jobs admitted against a counter written only at completion; register_blob not checking that the subscription is still live, where migration::create_job does; and extend_blob capping the increment rather than the resulting lifetime. They are recorded in §7 as P0.

Separately, M-07 is a deployment decision rather than a code fix: the UpgradeCap is at default policy, so its holder can publish a version in which seal_approve approves everyone — retroactively exposing every blob ever encrypted, because the ciphertext does not change, only the on-chain predicate guarding the key.

5 · Production deployment

Object Id
Package 0x2f548bb4bb1e5f7622c527417d3c0221840d0412ec23d70306f1bd4b79c20b45
GlobalConfig 0xd4d4dbb5ae23a8b89a214fd8e0695ba14ced4e8600e6a096169df805cc580b02
PlanRegistry 0xa560dadd6d3b8acdf5f27a88c62f22efd7c41ae98ffbc0ca3188c8e4b4500936
Treasury 0x83d23c0e5b71913af2058cdd16f6f57168614d862f16f9481f2679de7c8c8c4b
AdminCap 0xb7083158b697ff6ff184809d319f14bb101cf37171852763408c0630922d6bdb
UpgradeCap 0xe30017b431ccb42ea3c05a8437ee876882a6e30c2c51fcd8d340cca4cb6bac0c
Publisher 0x502a1ca937e47ea94d98d8ea2f96e745e0365a34d19083f1b49fc13f76f0fa2e

Self-hosted Walrus publisher and aggregator on AWS behind nginx + TLS, with JWT-authenticated writes. Sui Object Display registered for all five user-facing types, so wallets and explorers render Waldrop objects with names and images rather than raw type strings.

6 · Observability

Component Status Detail
Engine metrics DONE 27 Prometheus metrics — throughput, latency histograms, queue depth, memory, error counts by type
Per-component health endpoint DONE /api/health checks engine, publisher, aggregator and Sui RPC independently. 200 ok / 200 degraded / 503 down is the alerting contract — a non-critical dependency being slow does not page
Alert rules DONE 11 rules across availability, saturation and correctness. Every referenced metric verified to exist in source. Error alerts use a ratio, not a count
Grafana dashboards DONE Engine dashboard live at monitoring.waldrop.xyz — throughput, latency percentiles, queue depth, error rate, stage latency and resource usage
Status page DONE Driven by the per-component health endpoint, so each dependency reports separately rather than a single up/down for the whole product

7 · Open items

Stated with cause, not just status. Nothing here is unknown work.

Item Priority Note
Audit findings H-01, H-02, H-03 P0 Three High-severity resource-metering paths from the contracts audit (§4.6), each reachable by a single unprivileged user. The audited commit d889b0c is still HEAD, so none are fixed and all are live on the deployed package. Fixes require a redeploy, which abandons existing BlobStore objects — so sequencing matters
Publisher capacity hardening FIXED, PENDING CUTOVER Root cause was worse than first reported: --max-body-size is denominated in KiB, not bytes, so the deployed value of 536870912 was 512 GiB — no effective limit at all — against an 8-request default concurrency and roughly 4.5× blob size in encoding memory. Combined with no swap and Restart=on-failure under systemd's default limit (5 restarts in 10 s, then permanent stop), an OOM took the service down and kept it there. Replacement host is built and running with --max-body-size 307200 (300 MiB), --publisher-max-concurrent-requests 2, MemoryHigh/MemoryMax bounds, 8 GB swap and StartLimitIntervalSec=0; excess load now returns 429 rather than exhausting the box. Production moves to it at cutover
Publisher-tier capacity numbers P1 Last outstanding measurement. Unblocked by the publisher fix above; re-run follows cutover. App-tier sustained throughput additionally needs a Vercel bypass token so the harness is not challenged as an attacker — §3.4
Launch blog + ecosystem announcement P1 Drafted, not published. The ecosystem announcement needs a slot from the Walrus team, so its date is not ours to set — §8
Community channels P1 X is live (@waldropxyz). A support channel with a published response window does not exist yet and is required before general availability — §8.3
Cross-browser / cross-device QA P1 Cases documented in the QA guide; execution pending
Admin keys to multisig P1 AdminCap, UpgradeCap, Publisher and DisplayCaps are on one hardware wallet — a single point of failure
Beta plan pricing P1 Starter is deliberately 0 USDC during beta and must be set before general availability

8 · Go-to-market

Five launch deliverables, all complete. The demo video is published; the blog post and ecosystem announcement are written and held for the launch window; and the remaining two are operating plans — reproduced below in full, because for those the plan is the deliverable.

Deliverable Status Evidence / blocker
Demo video (5–10 min) DONE Published and embedded at §2 — youtu.be/xDJbNH4JmRU
Launch blog post (technical deep-dive) READY Written to the structure in §8.1. Held for the launch window — a deep-dive that invites readers to audit the contracts is scheduled after the H-01/H-03 fixes in §7, not before
Walrus ecosystem announcement READY Copy complete. Publication slots on the Walrus team's calendar, so the date is coordinated rather than unilaterally set
Community engagement plan DONE §8.2 — channels exist or are specified with owners
Launch-day support strategy DONE §8.3 — runbook, thresholds and rollback

8.1 Launch blog post — outline

A technical deep-dive, not an announcement. The argument is that a safe migration is now cheaper than an unsafe one, and the post earns that by showing the mechanism rather than asserting the benefit.

  1. The problem nobody schedules. Object storage nobody can fully account for, and why the safe version of moving it never got budget.
  2. Reading data without reading data. The profiler, and the boundary: column names, statistics and masked value shapes cross to the model; no raw cell ever does. Names the enforcement point and the canary test that guards it.
  3. Policy you approve, not policy you accept. Deterministic detection separated from model judgement, proposals as editable rows, and the before/after diff on a real sample.
  4. Encryption whose access rule is a contract. SEAL per-file and per-folder, revocation as a transaction rather than a support ticket.
  5. What the chain remembers. Blob on Walrus, registry entry and content hash on Sui, and how a third party verifies a file without asking us.
  6. What we got wrong. The publisher OOM and its real cause (§7), the two invalidated load runs (§3.4). Credibility comes from the defects section, not the feature list.

8.2 Community engagement plan

Channel Purpose Cadence & commitment
@waldropxyz on X Launch, releases, incident notices Live. Weekly during launch month. Every incident that affects uploads gets a post, including resolution
Support channel (Discord or Telegram) User questions, bug intake, beta cohort TO STAND UP Published response window, weekday coverage. Required before general availability — see §7
GitHub issues SDK, CLI and contract defects Contracts are Apache 2.0 and public. Triage within two working days; security reports routed privately, not to the tracker
Walrus / Sui developer forums Ecosystem presence, not promotion Answer storage-integration questions where they are already being asked. The address-balance failure in §7 is exactly the kind of write-up that belongs there
Documentation site Self-serve onboarding Live. Every support question answered more than twice becomes a docs page — the channel's job is to make itself quieter

8.3 Launch-day support strategy

The operating assumption is that the first real failure will be capacity or wallet-related, because both have already happened once.

Signal Where it surfaces First action
Publisher down or restart-looping Alert on up == 0 for 2 min, and on more than three process restarts in ten minutes Check the journal for the coin-selection error before anything else — that failure produced 16,000 silent restarts once already
Publisher wallet low Sub-wallet gas below one refill Confirm the funding wallet holds a coin object, not only an address balance. Refills fail against a balance alone
Uploads rejected at the edge 429s from the publisher, nginx rate-limit counters Expected under burst. Concurrency is capped so excess is refused rather than swallowed — raise limits only with headroom evidence
Engine or transform failure Engine metrics, health endpoint per component Container restart; AI routes fail closed to the manual builder
Anything user-visible Support channel, X Acknowledge before diagnosing. Post resolution on the same channel the report arrived on

Coverage. Weekday hours for the launch window, with alerting routed to a phone outside them. Single-operator today — a real constraint, disclosed rather than papered over, and the reason the alert thresholds above are deliberately noisy.

Rollback. Infrastructure changes stay reversible for 48 hours: DNS TTL dropped to 60 s ahead of any cutover, the previous hosts left powered but disabled, and volume snapshots taken before any instance is terminated. Contract state is the exception and has no rollback — which is why the P0 items in §7 gate the launch rather than follow it.

9 · How to verify this report

Every number above is reproducible:

# Contract tests
cd waldrop-contracts && sui move test

# Application test suites
cd waldrop_app
for t in safe-redirect preview-diff rate-limit walrus-endpoint capped-stream bcs-schema; do
  bun run scripts/$t-test.ts
done

# Dependency scan
bun audit

# Live service health, per component
curl -s https://app.waldrop.xyz/api/health | python3 -m json.tool

# On-chain object verification
sui client object 0x2f548bb4bb1e5f7622c527417d3c0221840d0412ec23d70306f1bd4b79c20b45