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
14 changes: 0 additions & 14 deletions .cursor/rules/00-project.mdc

This file was deleted.

9 changes: 0 additions & 9 deletions .cursor/rules/10-contracts.mdc

This file was deleted.

9 changes: 0 additions & 9 deletions .cursor/rules/20-web.mdc

This file was deleted.

43 changes: 26 additions & 17 deletions .env.example
Original file line number Diff line number Diff line change
@@ -1,19 +1,28 @@
# Public browser configuration — safe to expose in the client bundle.
NEXT_PUBLIC_MONAD_RPC_URL=https://rpc.testnet.monad.xyz
NEXT_PUBLIC_MONAD_EXPLORER_URL=https://testnet.monadscan.com
NEXT_PUBLIC_DROPS_CONTRACT_ADDRESS=
NEXT_PUBLIC_SUPABASE_URL=
NEXT_PUBLIC_SUPABASE_PUBLISHABLE_KEY=
# NO SUS Canary: every secret and setting, with no values.
# Nothing here is needed to run the app locally (it uses the hosted devnet backend).
# Real values go in Supabase function secrets (`supabase secrets set ...`) or a git-ignored
# .env file. Never commit a filled-in copy. See docs/SELF_HOSTING.md.

# Server-only values — never prefix these with NEXT_PUBLIC_.
SUPABASE_SERVICE_ROLE_KEY=
LIT_NETWORK=naga-dev
LIT_ACCOUNT_API_KEY=
DEPLOYER_PRIVATE_KEY=
CONFIRM_MONAD_DEPLOY=
# --- Relayer: Supabase Edge Function `canary` (function secrets) ---
# 64 hex chars, random (openssl rand -hex 32). Salts the anonymous reader tag. Never share it.
CANARY_TAG_SALT=
# Devnet relayer keypairs, comma-separated: base58 64-byte secret keys or solana-keygen JSON
# arrays. Fund them at https://faucet.solana.com. Devnet only.
SOLANA_RELAYER_KEYS=
# Optional. Default https://api.devnet.solana.com
SOLANA_RPC_URL=
# Optional. Default MemoSq4gqABAXKb96qnH8TysNcWxMyWCqXgDLGmfcHr (SPL Memo)
SOLANA_MEMO_PROGRAM=
# Leave unset. Setting it turns on a legacy prototype path the product does not use.
CANARY_CONTRACT_ADDRESS=
# SUPABASE_URL and SUPABASE_SERVICE_ROLE_KEY are injected by Supabase. Never set them by hand
# and never put the service-role key in the app.

# Gate T1 live runner only (tool/threshold-spike). Never put these in NEXT_PUBLIC_*.
# DROPS_CONTRACT_ADDRESS=
# RECIPIENT_PRIVATE_KEY=
# STRANGER_PRIVATE_KEY=
# THRESHOLD_SPIKE_RUN=
# --- Flutter build (--dart-define, public by design) ---
# true = the standalone Canary web app that is deployed.
NOSUS_CANARY_ONLY=true
# Repo link shown in the app.
CANARY_REPO_URL=https://github.com/https-shubhamsahu/nosus-canary

# --- tool/solana-spike (optional, local only) ---
# The spike writes its own devnet key to tool/solana-spike/.keys/ (git-ignored).
7 changes: 0 additions & 7 deletions .github/CODEOWNERS
Original file line number Diff line number Diff line change
@@ -1,8 +1 @@
# Replace the handle if the GitHub repository uses a different owner account.
* @https-shubhamsahu

/contracts/ @https-shubhamsahu
/web/ @https-shubhamsahu
/supabase/ @https-shubhamsahu
/.github/ @https-shubhamsahu
/docs/ @https-shubhamsahu
34 changes: 0 additions & 34 deletions .github/workflows/checks.yml

This file was deleted.

78 changes: 78 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
name: CI

on:
pull_request:
push:
branches: [main]

permissions:
contents: read

concurrency:
group: ci-${{ github.ref }}
cancel-in-progress: true

jobs:
flutter:
name: Flutter app
runs-on: ubuntu-latest
defaults:
run:
working-directory: app
steps:
- uses: actions/checkout@v5
- uses: subosito/flutter-action@v2
with:
channel: stable
flutter-version: 3.47.7
cache: true
- run: flutter pub get
- name: Analyze
run: flutter analyze
- name: Test
run: flutter test
- name: Fingerprint harness (must print FAILURES 0)
run: dart run tool/canary_fingerprint_harness.dart | tail -4

receipts-dart:
name: Receipts library (Dart)
runs-on: ubuntu-latest
defaults:
run:
working-directory: packages/receipts-dart
steps:
- uses: actions/checkout@v5
- uses: subosito/flutter-action@v2
with:
channel: stable
flutter-version: 3.47.7
cache: true
- run: dart pub get
- run: dart analyze --fatal-infos
- run: dart format --output=none --set-exit-if-changed .
- run: dart test

deno:
name: Relayer + receipts library (TypeScript)
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v5
- uses: denoland/setup-deno@v2
with:
deno-version: v2.9.x
- name: Receipts library checks
working-directory: packages/receipts-ts
run: |
deno check mod.ts cli.ts test/
deno lint
deno fmt --check
deno test
- name: Relayer checks
working-directory: app/supabase/functions/canary
run: |
deno check index.ts
deno test --allow-env
- name: Relayer bundles for deploy
run: deno bundle --platform=deno app/supabase/functions/canary/index.ts -o "$RUNNER_TEMP/canary.bundle.js"
- name: Devnet spike type-checks
run: deno check tool/solana-spike/send_memo.ts
104 changes: 45 additions & 59 deletions AGENTS.md
Original file line number Diff line number Diff line change
@@ -1,59 +1,45 @@
# NO SUS — Monad Experiment agent map

This repository is an isolated, **testnet-only** experiment. Read
[docs/STATUS.md](docs/STATUS.md), then only the local guide for files you will change.

## Current workstream: NO SUS Canary (owner decision, 19 Sep 2026)

- Brand: **NO SUS**. Feature: **NO SUS Canary**. This supersedes the "NO SUS — Monad Experiment"
naming rule below for user-facing text.
- Build plan: [docs/canary/NOSUS_CANARY_BUILD_PLAN.md](docs/canary/NOSUS_CANARY_BUILD_PLAN.md)
(executed; the live code in `app/` and `contracts/` is the source of truth). Verification log:
[docs/canary/VERIFICATION.md](docs/canary/VERIFICATION.md).
- Canary is server-gated copy delivery and is described as such. It does not use Lit, does not
change Gate T1, and does not change `monadThresholdVerified`.
- Still requires explicit owner approval each time: contract deploys, funding wallets, applying
SQL, setting secrets, deploying functions, creating public repos or Pages, commits and pushes.

## Product boundaries

- Brand it **NO SUS — Monad Experiment**. Do not call it Rasid and do not change the production
NO SUS repository, credentials, Supabase project, deployment, or URL.
- Use only harmless, personally owned test notes. Never use credentials, third-party documents,
employment records, financial information, or sensitive personal data.
- The product may say "threshold-gated decryption after a wallet acknowledgement." It must never
claim legal proof, a human read, screenshot prevention, serverless deletion, or identity proof.
- The contract must never receive plaintext, encryption keys, salts, filenames, or document content.
- Threshold custody is a release gate, not decoration: if the Monad-to-Lit proof is not clean, do
not present it as shipped and never substitute a hidden server key-release path.

## How to navigate

| Area | Read first |
|---|---|
| Contract | `contracts/README.md` and `contracts/AGENTS.md` |
| Web app | `web/README.md` and `web/AGENTS.md` |
| Storage schema | `supabase/README.md` |
| Handover | `docs/CURSOR_HANDOFF.md` |
| Lit technical gate | `docs/LIT_MONAD_SPIKE.md` |
| Parallel work | `docs/AGENT_COLLABORATION.md` |

## Working rules

- Use the smallest necessary change. Do not add an abstraction, dependency, code generator, or
generic utility without a current consumer.
- Keep all secrets in ignored environment files. `NEXT_PUBLIC_*` values are public by design; never
put service-role keys, private keys, Lit account keys, or test-wallet keys there.
- Work in a dedicated branch and small commits. Update `docs/STATUS.md` and local README files when
behavior, contracts, or setup changes.
- Normal work uses focused checks and localhost. Do not deploy, fund wallets, apply a Supabase
migration, or use a real test note without explicit user direction.
- After each substantive response that changes files, ask exactly: "Would you like to finalize today's
work? If yes, say whether to verify only, build a target, or deploy a named target."

Would you like to finalize today's work? If yes, say whether to verify only, build a target, or deploy a named target.

## Finalization

"Verify only" permits the contract tests, web checks, repository checks, and the real Monad/Lit
technical gate. A deployment additionally needs an explicitly named target.
# NO SUS Canary: agent map

Read [docs/STATUS.md](docs/STATUS.md) first, then only the guide for the files you will change.

## What this is

NO SUS Canary: every reader of a note gets a uniquely marked copy, and every seal and every open is
one SPL Memo transaction on **Solana devnet**, sent by a relayer (Supabase Edge Function `canary`)
so readers need no wallet. Leak matching runs on the sender's device.

## Map

| Area | Code | Read first |
|---|---|---|
| Canary UI and fingerprinting | `app/lib/features/canary/` | `app/AGENTS.md` |
| Relayer | `app/supabase/functions/canary/` | `docs/ARCHITECTURE.md` |
| Receipt format and libraries | `packages/receipts-ts/`, `packages/receipts-dart/`, `packages/test-vectors/` | `docs/RECEIPTS_SPEC.md` |
| Schema | `app/supabase/migrations/2026091909*`, `2026101009*` | `docs/SELF_HOSTING.md` |
| Security model | — | `SECURITY.md` |

## Rules

- Backend: experiment project `ffidvfguojalzpclipzi` only. Never touch the NO SUS production
project, its credentials or deployment.
- Never put note text, keys, names or device ids on chain. Memos carry hashes only; the format is
frozen at v1 (see the spec) and both libraries must stay byte-identical with the test vectors.
- Secrets live in Supabase function secrets or git-ignored files (`.env.example` lists them). The
Supabase publishable key in `app/lib/config/supabase_credentials.dart` is public by design.
- Keep the legacy EVM prototype path off: `CANARY_MONAD` stays false in Flutter and
`CANARY_CONTRACT_ADDRESS` stays unset for the function. User-facing text mentions Solana only.
- Never claim screenshot prevention, legal proof, identity proof or proof that a human read a note.
- Use harmless test notes only.
- Smallest change that works. No new dependency or abstraction without a current consumer.
- Owner approval is needed every time for: commits and pushes, merges, deploying the function,
applying SQL, setting secrets, funding keys or spending devnet SOL, changing gh-pages, and
making anything public.

## Checks (CI runs all of these)

```bash
(cd app && flutter analyze && flutter test && dart run tool/canary_fingerprint_harness.dart)
(cd app/supabase/functions/canary && deno check index.ts && deno test --allow-env)
(cd packages/receipts-ts && deno check mod.ts cli.ts && deno lint && deno fmt --check && deno test)
(cd packages/receipts-dart && dart pub get && dart analyze && dart format --set-exit-if-changed . && dart test)
```
2 changes: 1 addition & 1 deletion CLAUDE.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
# NO SUS — Monad Experiment
# NO SUS Canary

Read [AGENTS.md](AGENTS.md). It is the single source of truth for humans and coding agents.
Loading
Loading