Files
uupl-smart-contract/.superpowers/sdd/2026-08-17-uups-bank-demo/task-1-brief.md
T
golemandClaude Opus 5 fa36215def docs: track superpowers working documents in git
The uups-bank-demo wave's SDD records (ledger, six task briefs and reports,
review diffs) and the brainstorm design mockups were git-ignored, so they
existed only on one sandbox VM and reached no remote — this repo had no remote
at all until now.

Removes `.superpowers/` from .gitignore and the `*` .gitignore the superpowers
plugin writes inside .superpowers/sdd/; the second blocks the directory even
with the first removed.

Excluded as ephemeral local-server state, and now ignored by name:
.last-port, .last-token (a 64-char session token for a brainstorm server on a
port that is long gone), and the per-session state/ directories.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Fnwzj6McD6kSkXwjUKFKxe
2026-08-20 14:38:00 -06:00

6.9 KiB
Raw Blame History

Task 1: Pin and prove the repository toolchain

Files:

  • Modify: .gitignore
  • Create: .nvmrc
  • Create: .env.example
  • Create: .gitmodules (generated by forge install)
  • Create: foundry.lock (generated by forge install)
  • Create: foundry.toml
  • Create: remappings.txt
  • Create: Makefile
  • Create: package.json
  • Create: package-lock.json (generated by npm)
  • Create: tools/check-upgrades-cli.mjs
  • Create: web/package.json
  • Create: web/package-lock.json (generated by npm)
  • Create: web/index.html
  • Create: web/tsconfig.json
  • Create: web/tsconfig.app.json
  • Create: web/tsconfig.node.json
  • Create: web/vite.config.ts
  • Create: web/eslint.config.js
  • Create: web/src/test/toolchain.test.ts

Interfaces:

  • Produces make doctor, make setup, and the initial verification gate that later tasks extend.

  • Produces exact dependency revisions for every later Solidity and web task.

  • Consumes no application source.

  • Verify host tools and record the expected initial limitation:

forge --version
anvil --version
node --version
npm --version
make --version

Expected now: Foundry commands may be missing; Node/npm/make print their installed versions. If Foundry is missing during execution, request permission to install Foundry from its official installer, then pin with foundryup -i 1.7.1. Do not silently install system-wide tools.

  • Extend .gitignore with exactly these runtime classes:
.env
.env.local
.demo/
cache/
out/
broadcast/
deployments/*.json
deployments/**/*.json
!deployments/*.example.json
node_modules/
web/node_modules/
web/dist/
web/coverage/
web/public/deployment.json
web/src/generated/*.ts
!.gitkeep
.superpowers/
  • Pin Node/npm in .nvmrc and create a private root package.json with the same packageManager/engines fields plus exactly one dev dependency: "@openzeppelin/upgrades-core": "1.46.0". Generate and commit the root lockfile with npm install --save-exact. This locally satisfies the plugins hard-coded ^1.45.0 range.

  • Pin the browser dependencies in web/package.json; the package must be private and use only exact versions:

{
  "name": "uups-bank-operations-console",
  "private": true,
  "version": "0.1.0",
  "type": "module",
  "packageManager": "npm@11.17.0",
  "engines": { "node": ">=24.18.0 <25", "npm": ">=11.17.0 <12" },
  "scripts": {
    "dev": "vite --host 127.0.0.1",
    "lint": "eslint . --max-warnings 0",
    "typecheck": "tsc -b --pretty false",
    "test": "vitest run",
    "build": "tsc -b && vite build"
  }
}

Add exact runtime dependencies @tanstack/react-query@5.101.4, react@19.2.8, react-dom@19.2.8, viem@2.55.8, and wagmi@3.7.5. Add exact dev dependencies @eslint/js@10.0.1, @testing-library/dom@10.4.1, @testing-library/react@16.3.2, @types/node@24.10.0, @types/react@19.2.14, @types/react-dom@19.2.4, @vitejs/plugin-react@6.0.4, eslint@10.0.1, eslint-plugin-react-hooks@7.1.1, eslint-plugin-react-refresh@0.5.3, globals@17.7.0, jsdom@30.0.1, typescript@7.0.2, typescript-eslint@8.65.0, vite@8.2.0, and vitest@4.1.10. If npm rejects one exact revision because the registry changed, verify the official release before changing both this plan and the package file.

  • Configure Foundry in foundry.toml:
[profile.default]
src = "src"
test = "test"
script = "script"
out = "out"
libs = ["lib"]
solc_version = "0.8.35"
evm_version = "cancun"
optimizer = true
optimizer_runs = 200
ffi = true
ast = true
build_info = true
extra_output = ["storageLayout"]
fs_permissions = [
  { access = "read", path = "out" },
  { access = "read-write", path = "deployments" }
]

[fuzz]
runs = 512
seed = "0x5555505342414e4b"

[invariant]
runs = 128
depth = 64
fail_on_revert = true
  • Install exact Solidity dependencies as Git submodules and write canonical remappings:
forge install foundry-rs/forge-std@v1.16.1
forge install OpenZeppelin/openzeppelin-foundry-upgrades@v0.4.1
forge install OpenZeppelin/openzeppelin-contracts-upgradeable@v5.6.1
git submodule update --init --recursive
forge-std/=lib/forge-std/src/
openzeppelin-foundry-upgrades/=lib/openzeppelin-foundry-upgrades/src/
@openzeppelin/contracts/=lib/openzeppelin-contracts-upgradeable/lib/openzeppelin-contracts/contracts/
@openzeppelin/contracts-upgradeable/=lib/openzeppelin-contracts-upgradeable/contracts/

Do not install a second top-level copy of openzeppelin-contracts; the upgradeable submodules pinned transitive copy supplies both canonical remappings.

  • Create tools/check-upgrades-cli.mjs. It must assert that the plugin source contains UPGRADES_CORE = "^1.45.0", the root lockfile resolves @openzeppelin/upgrades-core to exactly 1.46.0, and the locally installed package reports 1.46.0. Then prove the CLI can start with networking disabled:
npm ci
node tools/check-upgrades-cli.mjs
npm_config_offline=true npx @openzeppelin/upgrades-core@^1.45.0 validate --help

Expected: all commands exit 0 without fetching. Do not patch the vendored OpenZeppelin version constant.

  • Create Vite/React/TypeScript/ESLint/Vitest configuration manually so no unpinned scaffold generator is executed. Configure jsdom, web/src/test/setup.ts, strict TypeScript, and React refresh. Run:
npm --prefix web install --save-exact
npm --prefix web test

Expected red: toolchain.test.ts cannot import the not-yet-created src/config/toolchain.ts.

  • Create web/src/config/toolchain.ts exporting the display labels Foundry 1.7.1, Solidity 0.8.35, OpenZeppelin 5.6.1, and UUPS; make the test assert those exact values.

  • Add an initial Makefile with shell safety (SHELL := /bin/bash, .SHELLFLAGS := -euo pipefail -c) and non-destructive targets:

.PHONY: doctor setup verify
doctor:
	@./tools/doctor.sh
setup:
	@git submodule update --init --recursive
	@npm ci
	@npm --prefix web ci
verify:
	@forge fmt --check
	@forge clean
	@npm_config_offline=true forge build --force
	@npm_config_offline=true forge test --force
	@npm --prefix web run lint
	@npm --prefix web run typecheck
	@npm --prefix web test
	@npm --prefix web run build

Create a temporary minimal tools/doctor.sh that reports missing commands and exact expected versions without installing anything; Task 9 replaces it with full port/config checks.

  • Run the green foundation checks:
forge fmt --check
forge clean
npm_config_offline=true forge build --force
npm_config_offline=true forge test --force
node tools/check-upgrades-cli.mjs
npm --prefix web run lint
npm --prefix web run typecheck
npm --prefix web test
npm --prefix web run build

Expected: all exit 0; the empty Solidity source tree builds and the toolchain test passes.

  • Commit the foundation:
git add .gitignore .nvmrc .env.example .gitmodules foundry.lock foundry.toml remappings.txt package.json package-lock.json Makefile tools/check-upgrades-cli.mjs tools/doctor.sh lib web
git commit -m "build: pin demo toolchains"