Skip to content

Latest commit

 

History

History
204 lines (166 loc) · 10.2 KB

CONTRIBUTING.md

File metadata and controls

204 lines (166 loc) · 10.2 KB

Contributing

Chaingraph is a watch-only Bitcoin workbench. The browser owns workspaces, wallets, scanning and encryption; the server is a bounded read-only bridge. Read docs/architecture.md before changing a module boundary, and keep chain observations, user annotations and heuristic hypotheses separate.

Use docs/source-map.md to find a product area's UI, state, helpers and tests. App owns React UI and wiring; Core owns workspace capabilities. Each Core concept holds its canonical data types and validity rules together; Core/Workspace/Persistence owns encrypted formats and storage. Behavior and tests stay grouped by their actual concept.

Set up

Node 24+, npm and a WebGL-capable browser.

npm ci
cp -n .env.example .env.testnet4     # and/or .env.mainnet
chmod 600 .env.testnet4
npm run dev                          # http://127.0.0.1:3001

Never commit environment files, wallet exports, credentials or personal browser artifacts. Use public key vectors or synthetic data in tests; example workspaces bundle verified real-chain snapshots.

Check

npm run format:check          # Prettier
npm run check                 # formatting, portability, linting, build and domain/integration tests
node scripts/release-check.mjs
docker buildx bake --check release-platform

Routine push/PR CI runs exactly these plus a license-notice diff, without a browser. Run npm run format after editing source and npm run licenses after changing runtime dependencies. Engine, data and interaction changes need relevant behavioral coverage; add or extend tests only when existing coverage does not protect the changed behavior. Copy-only and visual-only changes do not justify new unit, component or E2E tests. Documentation-only changes need no test run.

For shared behavior changes, follow the affected-consumer audit, including callers outside the diff. Workflow coverage must exercise the real consumer and its policy owner; testing the owner alone does not establish that a user action reaches it. Substantive interaction changes also need the source-based interaction review, without implying browser authorization or a separate reviewer.

Test user outcomes, state transitions and accessibility behavior rather than ordinary UI wording or styling. Text may locate a control in an interaction test, but avoid unnecessarily exact wording and redundant label assertions. Displayed amounts, identifiers and user-entered data still need meaningful coverage. Exact wording assertions require externally specified output or an explicit acceptance requirement. Before adding a test, identify the concrete user failure it catches. When a redesign breaks a copy-only assertion, remove or rewrite it while preserving behavioral coverage instead of automatically updating the expected string. See the validation rules for query and assertion guidance.

Narrower commands:

npm test                      # vitest domain/backend suites
npx vitest run src/Core/Workspace/ConnectionScan tests/integration/connection-scan
npm run test:live             # read-only smoke against configured real networks

Static demo build

npm run build:demo writes the backend-free demo to dist-demo/ using the /chaingraph/ project base by default. npm run check:demo checks that emitted artifact without a server or browser. Use CHAINGRAPH_BASE_PATH=/ for root hosting. Normal builds still use dist/. The static demo guide covers Pages setup and publication; local builds do not deploy.

Production and browser checks

Build and start the app (npm run build && SERVER_PORT=4300 npm start), then:

npm run test:production:http  # built assets, CSP and security headers, network discovery
npx playwright install chromium
npm run test:production       # the above plus a narrow browser runtime check
npm run test:e2e              # small smoke suite: the app renders and a workspace opens

CHAINGRAPH_SMOKE_URL selects another origin. The browser runtime check covers the real encryption worker under production CSP, WebGL initialization and encrypted save/reload/unlock/export with synthetic data. It does not establish visual usability. Browser and screenshot validation happen only on explicit request or within an agreed QA scope; otherwise run the non-browser checks and say that visual validation was not performed. The manual Browser QA GitHub workflow runs the runtime check or the smoke suite and publishes nothing.

Parallel worktrees

Each checkout needs its own npm ci and test output; do not symlink node_modules between worktrees. Browser tests fail if their port is occupied rather than silently testing another checkout, so assign distinct ports:

CHAINGRAPH_E2E_PORT=4176 CHAINGRAPH_GRAPH_TEST_PORT=4186 npm run test:e2e

Defaults are 4173 (app) and 4184 (renderer fixture). Run one browser suite at a time per checkout.

For an additional UI against a running backend, verify its listener and /proc/<pid>/cwd, choose an unused strict UI port, then reuse it with a frontend-only preview:

CHAINGRAPH_PROXY_TARGET=http://127.0.0.1:4400 \
  node --use-system-ca node_modules/vite/bin/vite.js --host 127.0.0.1 --port 3103 --strictPort

Vite preserves the browser-facing Host header so the backend can validate the request. Keep the browser and API on one origin through the proxy; do not weaken Origin checks to make a preview work. Browser storage is per origin, so each preview port has its own workspace list.

npm run dev remains the contained-stack option and starts both Node and Vite watchers. If a watcher reports ENOSPC or EMFILE, inspect and report the shared host settings fs.inotify.max_user_instances and fs.inotify.max_user_watches and the process owners. Do not change sysctls or kill unknown listeners automatically.

Review a change

Describe the user-visible problem, what changes, and the checks actually run. Cover arithmetic, cryptography, protocol handling, cancellation, evidence semantics and storage failures with meaningful regressions rather than tests that restate the implementation. When browser validation is in scope, exercise the real workflow with mouse and keyboard on desktop and phone widths, and count clicks and scrolling, not just green assertions.

For UI and copy changes, follow the product language rules in AGENTS.md and the product UI design skill. Choose whether information needs text before editing words. Review messages in their interaction context, including errors supplied by non-UI helpers; preserve evidence qualifications and verify recovery and saved-data claims. Apply the same criteria in review. These checks do not authorize browser validation.

Keep alternative designs in separate branches and compare working previews before adopting a redesign. Do not push or publish because a local check passed; the release process describes the tag workflow.

Layer boundaries

npm run lint (part of npm run check) enforces the dependency direction as well as style. Core production code cannot import React or App. Canonical schemas and pure validity rules do not load execution, transport or Persistence. Persistence consumes those rules, never App or the Session runtime. Session consumes the public persistence contract; App/appServices.ts constructs and supplies the facade. Domain has been removed. Core Bitcoin contains native primitives without application dependencies. Core ChainData consumes Bitcoin and provides shared chain models, validation, observation rules and workspace-independent RPC queries. Account-wallet policy belongs to Workspace Wallets; entity references belong to the Workspace root, not Bitcoin. Shared amount/reference formatting lives in Core Formatting. ChainData owns Bitcoin RPC decoding and fetch scheduling; Session owns workspace-bound request lifetime and accepted publication. Live queries use named-file imports and are not re-exported by the model/validation index, so canonical document parsing does not load the transport or scheduler.

App Selection and the shared wallet UTXO hook cannot import workbench internals. Wallet and Analysis reach Graph through GraphHandoff in Workbenches/workbenchHandoff.ts. ConnectionScan models, execution and retained result rules live together in Core; Graph owns target projection and path-add UI. Public interfaces may be named files, not just root indexes. Bitcoin, ChainData and workspace concepts allow direct imports; a folder alone does not imply private implementation. Persistence and Formatting retain explicit root interfaces. Outside callers cannot deep-import those two modules, including type imports, re-exports and literal dynamic imports. Internal files use direct imports. Browser, Codec and Migrations have no public subfolder entry points. Indexes must not initialize storage or workers. Do not export fault-injection options or private formats merely to support external tests.

Unit tests live beside their owner. Persistence's module-owned Integration/ suite exercises private storage/crypto fault injection together with real Session and App behavior. Only that test suite may cross those production dependency rules; no production caller may import it. Other cross-module tests remain in tests/integration/ and use the relevant concept and Persistence public interfaces.

Import cycles are rejected everywhere. Do not add forwarding files or hypothetical interfaces merely to make intermediate refactor states compile. Complete the related ownership changes and then validate the coherent chunk.

Portable content

Use repository-relative references in committed documentation. Do not commit a developer's absolute home path, private hostname or temporary handoff filename. npm run check:portability (part of npm run check) checks tracked text for user-home paths and rejects tracked environment files other than .env.example without echoing matched contents. It is not a secret scanner; review new screenshots and configuration separately. Local recordings and browser output belong in the ignored artifacts/ directory.