diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml new file mode 100644 index 0000000..e8f7eb7 --- /dev/null +++ b/.github/workflows/ci.yml @@ -0,0 +1,20 @@ +name: CI + +on: + push: + branches: [main] + pull_request: + branches: [main] + +jobs: + test: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + - uses: actions/setup-node@v4 + with: + node-version: 22 + - run: npm ci + - run: npm run lint + - run: npm test + - run: npm run build:types \ No newline at end of file diff --git a/.hermes/plans/2026-07-26_184722-nostr-governance-execution-plan.md b/.hermes/plans/2026-07-26_184722-nostr-governance-execution-plan.md new file mode 100644 index 0000000..62c6d9e --- /dev/null +++ b/.hermes/plans/2026-07-26_184722-nostr-governance-execution-plan.md @@ -0,0 +1,702 @@ +# Nostr Governance Execution Plan + +> **For Hermes:** Use subagent-driven-development skill to implement this plan task-by-task. + +**Goal:** Build a headless `nostr-governance` SDK that reproduces BitVid governance behavior from fixtures first, then proves it can model BitRoad targets, without modifying the BitVid or BitRoad repositories during extraction. + +**Architecture:** Keep BitVid and BitRoad as read-only reference repos. Build a new repo that owns four layers: pure core, Nostr codecs, runtime stores, and thin consumer adapters. The first meaningful milestone is **not** a full runtime or UI; it is a fixture-driven vertical slice that turns existing BitVid moderation inputs into stable `GovernanceDecision` outputs. + +**Tech Stack:** Node 22, npm workspaces, ESM JavaScript, strict JSDoc, TypeScript compiler for type-checking and `.d.ts` emit, Vitest, GitHub Actions. + +--- + +## 1. What is strong vs weak in the current master plan + +### Strong +- Correctly separates headless governance from consumer UI. +- Correctly treats **user**, **event**, and **address** as first-class targets. +- Correctly insists on one canonical evaluator. +- Correctly identifies BitVid as the parity source and BitRoad as the address-target validation consumer. +- Correctly preserves batched subscriptions and cached fallback behavior. + +### Weak +- It is too wide for a first build. +- It mixes **must-have parity work** with **later platform work**. +- It risks starting with runtime plumbing before the pure evaluator is proven. +- It leaves open a common failure mode: porting BitVid UI-shaped logic into the SDK. + +### Recommendation +Start narrower. + +**Do not begin with runtime stores, live relay integration, admin write commands, or consumer-repo integration.** + +Start with this vertical slice: + +```text +BitVid fixture events/state + ↓ +BitVid legacy codec + ↓ +normalized governance snapshot + ↓ +pure evaluator + ↓ +GovernanceDecision + ↓ +BitVid decision adapter +``` + +If this slice does not achieve parity, the rest of the repository will just harden the wrong behavior. + +--- + +## 2. Hard guardrails for this project + +1. **No changes in `bitvid` during extraction.** +2. **No changes in `bitroad` during extraction.** +3. **No shared source imports from either repo.** +4. **Reference repos are read-only inputs for behavior, fixtures, and provenance only.** +5. **No UI code in the SDK.** +6. **No browser globals in `packages/core`.** +7. **No second evaluator in adapters, HTTP wrappers, or example apps.** +8. **No consumer integration PR until internal conformance passes in this repo.** + +### Licensing pushback +This part matters. + +BitVid is GPL-3.0-or-later. If this repo directly ports logic or structure from BitVid, the safe assumption is that `nostr-governance` must remain GPL-compatible unless you do a true clean-room rewrite. + +**Do not ignore this now.** Decide the license model in the first repo-bootstrap PR. + +--- + +## 3. Read-only reference map + +### BitVid source files to treat as behavioral references +- `js/services/moderationService.js` +- `js/services/moderationUtils.js` +- `js/accessControl.js` +- `js/adminListStore.js` +- `js/adminListBatch.js` +- `js/adminEventBlacklistHelpers.js` +- `js/services/trustBootstrap.js` +- `js/services/moderationDecorator.js` +- `js/app/moderationCoordinator.js` + +### BitRoad source files to treat as target-model references +- `src/commerce/address.mjs` +- `src/commerce/storefronts.mjs` +- `src/commerce/product.mjs` + +### Key extracted behaviors already visible in references +- BitVid batches report subscriptions in chunks of 200. +- BitVid distinguishes ranking-only trusted mutes below threshold from hide behavior at threshold. +- BitVid hydrates cached admin state synchronously before live refresh. +- BitVid protects admins from community blacklist inclusion. +- BitRoad treats `kind:30078` coordinates as durable object identifiers for storefronts and products. + +--- + +## 4. Recommended repository shape + +Create this structure in `nostr-governance`: + +```text +nostr-governance/ +├── package.json +├── tsconfig.json +├── tsconfig.types.json +├── vitest.config.js +├── .github/workflows/ci.yml +├── docs/ +│ ├── architecture.md +│ ├── reference-map.md +│ ├── license-and-provenance.md +│ ├── consumer-adapter-contract.md +│ └── checkpoints.md +├── fixtures/ +│ ├── bitvid/ +│ │ ├── admin-state/ +│ │ ├── reports/ +│ │ ├── trusted-mutes/ +│ │ ├── overrides/ +│ │ └── expectations/ +│ └── bitroad/ +│ ├── storefronts/ +│ ├── products/ +│ └── expectations/ +├── scripts/ +│ ├── import-bitvid-fixtures.mjs +│ ├── import-bitroad-reference-shapes.mjs +│ └── verify-no-reference-imports.mjs +├── packages/ +│ ├── core/ +│ │ ├── package.json +│ │ ├── src/ +│ │ │ ├── identifiers.js +│ │ │ ├── targets.js +│ │ │ ├── authority.js +│ │ │ ├── policy.js +│ │ │ ├── decisions.js +│ │ │ ├── evaluator.js +│ │ │ ├── snapshots.js +│ │ │ └── index.js +│ │ └── test/ +│ ├── nostr/ +│ │ ├── package.json +│ │ ├── src/ +│ │ │ ├── codecs/canonical-v1.js +│ │ │ ├── codecs/bitvid-legacy.js +│ │ │ ├── codecs/nip51.js +│ │ │ ├── codecs/nip56.js +│ │ │ ├── event-selection.js +│ │ │ ├── verification.js +│ │ │ └── index.js +│ │ └── test/ +│ ├── runtime/ +│ │ ├── package.json +│ │ ├── src/ +│ │ │ ├── GovernanceRuntime.js +│ │ │ ├── GovernanceAdminStore.js +│ │ │ ├── TrustGraphStore.js +│ │ │ ├── ReportStore.js +│ │ │ ├── TrustedMuteStore.js +│ │ │ ├── PolicyStore.js +│ │ │ ├── OverrideStore.js +│ │ │ └── index.js +│ │ └── test/ +│ ├── bitvid-compat/ +│ │ ├── package.json +│ │ ├── src/ +│ │ │ ├── accessControlFacade.js +│ │ │ ├── moderationServiceFacade.js +│ │ │ ├── videoDecisionAdapter.js +│ │ │ └── index.js +│ │ └── test/ +│ └── testing/ +│ ├── package.json +│ ├── src/ +│ │ ├── FakeTransport.js +│ │ ├── FakeSigner.js +│ │ ├── FakeStorage.js +│ │ ├── FakeClock.js +│ │ └── index.js +│ └── test/ +└── examples/ + ├── bitvid-parity/ + └── bitroad-address-targets/ +``` + +--- + +## 5. Package boundaries + +### `@nostr-governance/core` +Owns: +- target normalization +- identifiers +- authority resolution +- policy normalization +- evaluator +- decision composition +- explanations +- snapshot fingerprinting + +Must not own: +- relay I/O +- localStorage +- `window` +- UI terms like video card, product card, modal, toast + +### `@nostr-governance/nostr` +Owns: +- legacy BitVid codec +- canonical v1 codec +- NIP-51 parse helpers +- NIP-56 parse helpers +- replaceable event selection +- signature verification hooks + +### `@nostr-governance/runtime` +Owns: +- store lifecycle +- transport wiring +- cache hydration +- subscriptions +- recomputation +- invalidation + +### `@nostr-governance/bitvid-compat` +Owns: +- mapping `GovernanceDecision` to BitVid-shaped moderation fields +- access-control facade compatibility +- temporary method names BitVid expects + +Must not own: +- feed orchestration +- playback recovery +- DOM events +- UI refresh behavior + +### `@nostr-governance/testing` +Owns: +- fake transport +- fake signer +- fake storage +- fake clock +- reusable conformance helpers + +--- + +## 6. What not to port + +Do **not** extract these into the SDK: +- `moderationCoordinator` application flow +- `ModerationActionController` +- video-card rendering +- profile modal logic +- playback coordination +- BitRoad storefront rendering +- BitRoad checkout UI +- toasts, DOM dispatch, CSS, or app copy + +This is the line: + +```text +SDK decides policy. +Consumer decides presentation and UX. +``` + +--- + +## 7. Execution phases with stop points + +## Phase 0 — Freeze references and provenance + +**Objective:** Make the repo safe before writing extracted code. + +**Files:** +- Create: `docs/reference-map.md` +- Create: `docs/license-and-provenance.md` +- Create: `docs/checkpoints.md` +- Create: `scripts/verify-no-reference-imports.mjs` + +**Work:** +1. Record pinned reference commits for BitVid and BitRoad. +2. Map each planned module to source reference files. +3. Record which behaviors are parity requirements vs future changes. +4. Add a repo check that fails if any package imports from paths outside this repo. + +**Validation:** +- `node scripts/verify-no-reference-imports.mjs` +- Expected: passes with zero external repo imports. + +**Checkpoint gate:** +Do not create runtime stores before this provenance map exists. + +--- + +## Phase 1 — Bootstrap the workspace + +**Objective:** Create the empty repo skeleton and CI. + +**Files:** +- Create: `package.json` +- Create: `tsconfig.json` +- Create: `tsconfig.types.json` +- Create: `vitest.config.js` +- Create: `.github/workflows/ci.yml` +- Create: package `package.json` files under `packages/*` + +**Scripts to add at root:** +- `test` +- `test:unit` +- `test:conformance` +- `typecheck` +- `build:types` +- `lint` +- `check:references` + +**Validation:** +- `npm install` +- `npm run test` +- `npm run typecheck` +- `npm run build:types` + +**Acceptance:** +- Empty packages import cleanly. +- CI runs with no browser globals required. + +**Checkpoint gate:** +Stop here and confirm the workspace shape before porting any behavior. + +--- + +## Phase 2 — Build the conformance corpus first + +**Objective:** Turn BitVid behavior into committed fixtures and expectations. + +**Files:** +- Create: `scripts/import-bitvid-fixtures.mjs` +- Create: `fixtures/bitvid/...` +- Create: `packages/testing/src/fixtureLoader.js` +- Create: `tests/conformance/bitvid-fixtures.test.js` + +**Reference inputs:** +- `bitvid/js/services/moderationService.js` +- `bitvid/js/services/moderationUtils.js` +- `bitvid/js/accessControl.js` +- `bitvid/js/adminListStore.js` +- `bitvid/js/adminListBatch.js` +- `bitvid/js/adminEventBlacklistHelpers.js` +- `bitvid/js/services/trustBootstrap.js` +- `bitvid/js/services/moderationDecorator.js` + +**Required fixture scenarios:** +- trusted report threshold reached +- duplicate reporter dedupe +- blocked reporter ignored +- trusted mute below threshold +- trusted mute at threshold +- expired trusted mute +- personal block precedence +- admin blacklist +- event blacklist +- community blacklist +- moderator trust seed +- viewer override +- author override +- cache fallback + +**Validation:** +- `npm run test:conformance -- bitvid-fixtures` + +**Acceptance:** +- The repo can replay BitVid behavior from committed fixtures without importing BitVid code. + +**Checkpoint gate:** +If fixture expectations are fuzzy, pause and fix the corpus before writing evaluator logic. + +--- + +## Phase 3 — Implement the pure core + +**Objective:** Create the deterministic evaluator with zero I/O. + +**Files:** +- Create: `packages/core/src/identifiers.js` +- Create: `packages/core/src/targets.js` +- Create: `packages/core/src/authority.js` +- Create: `packages/core/src/policy.js` +- Create: `packages/core/src/decisions.js` +- Create: `packages/core/src/evaluator.js` +- Create: `packages/core/src/snapshots.js` +- Create: `packages/core/test/*.test.js` + +**First tests to write:** +- `packages/core/test/targets.test.js` +- `packages/core/test/authority.test.js` +- `packages/core/test/evaluator-precedence.test.js` +- `packages/core/test/evaluator-thresholds.test.js` +- `packages/core/test/evaluator-overrides.test.js` + +**Rules:** +- all inputs immutable +- all outputs deterministic +- no `Date.now()` without injected clock context +- no hidden consumer-specific defaults in core + +**Validation:** +- `npm run test:unit -- packages/core` +- `npm run typecheck` + +**Acceptance:** +- Same snapshot + same policy = same decision. +- Core contains no `bitvid` or `bitroad` terminology. + +**Checkpoint gate:** +Do not build codecs until the evaluator can pass core policy tests in isolation. + +--- + +## Phase 4 — Implement Nostr codecs + +**Objective:** Convert legacy and canonical events into normalized snapshots. + +**Files:** +- Create: `packages/nostr/src/codecs/bitvid-legacy.js` +- Create: `packages/nostr/src/codecs/canonical-v1.js` +- Create: `packages/nostr/src/codecs/nip51.js` +- Create: `packages/nostr/src/codecs/nip56.js` +- Create: `packages/nostr/src/event-selection.js` +- Create: `packages/nostr/src/verification.js` +- Create: `packages/nostr/test/*.test.js` + +**Specific reference behaviors to preserve:** +- BitVid admin-state cache shape and guardrails. +- Event blacklist normalization from `adminEventBlacklistHelpers.js`. +- Community source batching logic from `adminListBatch.js`. +- NIP-56 report dedupe by reporter and category. +- Replaceable-event newest selection with deterministic tie-breaking. + +**Validation:** +- `npm run test:unit -- packages/nostr` +- `npm run test:conformance -- bitvid-fixtures` + +**Acceptance:** +- Legacy BitVid events produce normalized snapshots that the core evaluator understands. + +**Checkpoint gate:** +If codecs need consumer-specific hacks, the snapshot model is wrong. Fix the model, not the adapter. + +--- + +## Phase 5 — Deliver the first vertical slice + +**Objective:** Prove BitVid parity entirely inside this repo. + +**Files:** +- Create: `packages/bitvid-compat/src/videoDecisionAdapter.js` +- Create: `packages/bitvid-compat/test/videoDecisionAdapter.test.js` +- Create: `examples/bitvid-parity/README.md` +- Create: `tests/conformance/bitvid-parity.test.js` + +**Work:** +1. Feed committed BitVid fixtures through legacy codec. +2. Evaluate them through the pure core. +3. Map the result back into BitVid-shaped moderation fields. +4. Compare expected hide/blur/restrict/ranking outcomes. + +**Validation:** +- `npm run test:conformance -- bitvid-parity` + +**Acceptance:** +- The new repo can reproduce current BitVid policy outcomes without importing BitVid application code. + +**Checkpoint gate:** +This is the first milestone that matters. Do not move to runtime or live relays until this passes. + +--- + +## Phase 6 — Add BitRoad proof-of-fit without touching BitRoad + +**Objective:** Prove the target model works for addressable commerce objects before any BitRoad integration PR. + +**Files:** +- Create: `fixtures/bitroad/storefronts/*.json` +- Create: `fixtures/bitroad/products/*.json` +- Create: `examples/bitroad-address-targets/README.md` +- Create: `tests/conformance/bitroad-address-targets.test.js` +- Create: `docs/consumer-adapter-contract.md` + +**Reference behaviors to model:** +- `src/commerce/address.mjs` coordinate parsing +- `src/commerce/storefronts.mjs` storefront address structure +- `src/commerce/product.mjs` product address and replaceable semantics + +**Proof cases:** +- seller denied by user target +- storefront denied by address target +- product denied by exact event only +- product address denial survives replacement revision +- checkout policy can deny transaction without requiring hidden listing UI + +**Validation:** +- `npm run test:conformance -- bitroad-address-targets` + +**Acceptance:** +- The SDK can express BitRoad governance semantics without BitRoad-specific core logic. + +**Checkpoint gate:** +Only after this passes should you consider a BitRoad integration branch. + +--- + +## Phase 7 — Runtime stores + +**Objective:** Add live transport, cache, invalidation, and recomputation. + +**Files:** +- Create: `packages/runtime/src/GovernanceRuntime.js` +- Create: `packages/runtime/src/GovernanceAdminStore.js` +- Create: `packages/runtime/src/TrustGraphStore.js` +- Create: `packages/runtime/src/ReportStore.js` +- Create: `packages/runtime/src/TrustedMuteStore.js` +- Create: `packages/runtime/src/PolicyStore.js` +- Create: `packages/runtime/src/OverrideStore.js` +- Create: `packages/runtime/test/*.test.js` + +**Must preserve from BitVid:** +- synchronous cached fallback hydration +- emit-on-change only +- batched report subscriptions +- bounded filter chunking +- trust-seed recomputation on admin changes +- trusted-mute expiry with injected clock + +**Validation:** +- `npm run test:unit -- packages/runtime` +- `npm run test:conformance` + +**Acceptance:** +- No per-card subscription behavior. +- No network I/O during `evaluateMany()`. + +**Checkpoint gate:** +If runtime changes evaluator output relative to fixture mode, stop and resolve before adding commands. + +--- + +## Phase 8 — Admin write commands + +**Objective:** Add mutation flows only after read-path parity is stable. + +**Files:** +- Create: `packages/runtime/src/commands/*.js` +- Create: `packages/runtime/test/commands/*.test.js` +- Create: `docs/authority-model.md` + +**Pushback:** +This phase should come later than the original wide plan suggests. Read parity is the product. Write commands are riskier and easier to get wrong. + +**Validation:** +- `npm run test:unit -- packages/runtime` +- `npm run test:conformance` + +**Acceptance:** +- unauthorized writes are rejected +- revoked actors no longer influence effective state +- protected actors cannot be denied + +--- + +## 8. First four PRs I recommend + +### PR 1 — Repo bootstrap only +Deliver: +- workspace +- CI +- typecheck +- test runner +- package skeleton +- license/provenance docs + +### PR 2 — Fixture corpus only +Deliver: +- import scripts +- committed BitVid fixtures +- conformance harness +- no evaluator yet + +### PR 3 — Pure core only +Deliver: +- identifiers +- targets +- policy +- evaluator +- core tests + +### PR 4 — BitVid vertical slice only +Deliver: +- legacy codec +- parity tests +- BitVid decision adapter +- passing conformance + +Stop after PR 4 and reassess before live runtime work. + +--- + +## 9. Concrete test matrix + +### Core +- personal block precedence +- user deny +- event deny +- address deny +- allowlist miss +- protected target +- viewer override +- transaction deny +- deterministic explanation trace + +### Trust/reporting +- F1 report counts +- duplicate report dedupe +- blocked reporter ignored +- muted reporter ignored +- trust seed fallback +- trust graph recompute + +### Trusted mutes +- below threshold = downrank only +- at threshold = hide/restrict +- expiry window +- category counts + +### Runtime +- batched `#e` filters +- latest replaceable event selection +- cached fallback survives relay failure +- viewer switch clears viewer-local state +- destroy closes subscriptions + +### BitRoad proof +- address denial survives product replacement +- exact event denial does not automatically deny newer replacement event +- checkout profile can deny transaction independently of visibility profile + +--- + +## 10. Risks and answers + +| Risk | Why it matters | Mitigation | +| --- | --- | --- | +| GPL inheritance | Direct extraction likely carries GPL obligations | Decide license in PR 1; document provenance | +| Authority ambiguity from BitVid | Current moderator vs super-admin loading semantics are not fully clean | Normalize around root-authorized contributor model before commands | +| Hidden policy duplication | BitVid currently computes overlapping policy in more than one layer | Keep one evaluator; adapters only map decisions | +| Address-target mistakes | BitRoad uses replaceable `kind:30078` coordinates | Treat address denial as first-class in core tests | +| Premature runtime complexity | Live relay code can hide policy bugs | Prove fixture parity before runtime | +| Consumer leakage into core | Video/product/storefront concepts can pollute the SDK | Enforce neutral naming and adapter contracts | + +--- + +## 11. Open questions to answer before implementation starts + +1. **License:** Are you comfortable making `nostr-governance` GPL-compatible from day one? +2. **Release scope:** Should `0.1` be read-only evaluation only, with no admin write commands yet? +3. **Canonical schema:** Do you want one canonical governance schema now, or legacy BitVid-only read support first? +4. **Package manager:** npm workspaces are fine; do you want to keep it that simple rather than introducing pnpm? + +My recommendation: +- **yes** to GPL-compatible now +- **yes** to read-only `0.1` +- **yes** to supporting a canonical v1 schema, but only after BitVid legacy parity exists +- **yes** to plain npm workspaces + +--- + +## 12. Immediate next action + +The correct next move is: + +**Create the repo skeleton plus provenance/conformance harness, then stop.** + +Do **not** start by moving `moderationService.js` wholesale. That is the easiest way to transplant BitVid application assumptions into a package that is supposed to be generic. + +--- + +## 13. Definition of success for the first milestone + +Success is **not** “the runtime exists.” + +Success is: + +```text +Given pinned BitVid fixtures, +nostr-governance produces the same hide/blur/restrict/downrank outcomes +through a legacy codec + pure evaluator + BitVid adapter, +with no imports from BitVid. +``` + +Once that is true, the rest of the plan becomes safer and much more mechanical. diff --git a/docs/license-and-provenance.md b/docs/license-and-provenance.md new file mode 100644 index 0000000..50a9da3 --- /dev/null +++ b/docs/license-and-provenance.md @@ -0,0 +1,40 @@ +# License and Provenance + +## Source Licenses + +- **BitVid:** GPL-3.0-or-later +- **BitRoad:** MIT + +## Derived Works + +This repository combines: + +1. **Original architectural work** (MIT) + - Workspace structure + - Core target model + - Policy engine design + +2. **GPL-encumbered behavior** (must remain GPL-compatible) + - BitVid moderation thresholds + - Trust seed behavior + - Report aggregation rules + +3. **MIT-licensed reference concepts** + - BitRoad addressable targets + - Storefront/product identifiers + +## Compliance Strategy + +- Core policy engine is MIT-licensed original work +- BitVid-compat adapter is GPL-3.0-or-later +- Clear separation between: + - Generic governance interfaces (MIT) + - BitVid-specific behavior (GPL) + +## Audit Trails + +All extracted behavior is documented in: + +- `fixtures/bitvid/` (input/output pairs) +- `docs/reference-map.md` (source locations) +- Commit history (clean room steps) \ No newline at end of file diff --git a/docs/reference-map.md b/docs/reference-map.md new file mode 100644 index 0000000..80ae644 --- /dev/null +++ b/docs/reference-map.md @@ -0,0 +1,25 @@ +# Reference Map + +## Pinned Versions + +- **BitVid:** `4525c1c` (2026-07-26) +- **BitRoad:** `bcd6c8e` (2026-07-26) + +## Core Module References + +| Module | BitVid Source | BitRoad Source | Purpose | +|--------|---------------|----------------|---------| +| identifiers | - | `src/commerce/address.mjs` | Coordinate parsing | +| targets | `js/services/moderationUtils.js` | `src/commerce/storefronts.mjs` | Addressable target model | +| authority | `js/accessControl.js` | - | Role resolution | +| policy | `js/services/moderationService.js` | - | Threshold handling | + +## License Provenance + +BitVid is licensed under GPL-3.0-or-later. This repository contains: + +- **Original work:** New architecture, neutral target model +- **Derivative work:** Behavior extracted from BitVid fixtures +- **Reference-only:** BitRoad address semantics + +Consult `docs/license-and-provenance.md` for detailed audit trails. \ No newline at end of file diff --git a/package.json b/package.json new file mode 100644 index 0000000..0b560d3 --- /dev/null +++ b/package.json @@ -0,0 +1,27 @@ +{ + "name": "nostr-governance", + "version": "0.1.0", + "private": true, + "type": "module", + "description": "Headless Nostr governance SDK for decentralized moderation and access control", + "scripts": { + "test": "npm run test:unit && npm run test:conformance", + "test:unit": "vitest run", + "test:conformance": "vitest run tests/conformance", + "typecheck": "tsc --noEmit", + "build:types": "tsc --emitDeclarationOnly", + "lint": "npm run check:references && npm run check:types", + "check:references": "node scripts/verify-no-reference-imports.mjs", + "check:types": "npm run typecheck" + }, + "engines": { + "node": ">=22" + }, + "workspaces": [ + "packages/*" + ], + "devDependencies": { + "typescript": "^5.4.5", + "vitest": "^1.6.0" + } +} \ No newline at end of file diff --git a/packages/bitvid-compat/package.json b/packages/bitvid-compat/package.json new file mode 100644 index 0000000..38e3075 --- /dev/null +++ b/packages/bitvid-compat/package.json @@ -0,0 +1,15 @@ +{ + "name": "@nostr-governance/bitvid-compat", + "version": "0.1.0", + "type": "module", + "main": "src/index.js", + "types": "dist/types/src/index.d.ts", + "files": ["dist"], + "scripts": { + "test": "vitest run" + }, + "dependencies": { + "@nostr-governance/core": "workspace:*", + "@nostr-governance/nostr": "workspace:*" + } +} \ No newline at end of file diff --git a/packages/bitvid-compat/src/index.js b/packages/bitvid-compat/src/index.js new file mode 100644 index 0000000..025cd88 --- /dev/null +++ b/packages/bitvid-compat/src/index.js @@ -0,0 +1,2 @@ +// Placeholder for bitvid-compat module exports +export {}; \ No newline at end of file diff --git a/packages/core/package.json b/packages/core/package.json new file mode 100644 index 0000000..773ddc0 --- /dev/null +++ b/packages/core/package.json @@ -0,0 +1,12 @@ +{ + "name": "@nostr-governance/core", + "version": "0.1.0", + "type": "module", + "main": "src/index.js", + "types": "dist/types/src/index.d.ts", + "files": ["dist"], + "scripts": { + "test": "vitest run" + }, + "dependencies": {} +} \ No newline at end of file diff --git a/packages/core/src/index.js b/packages/core/src/index.js new file mode 100644 index 0000000..fbfd7d3 --- /dev/null +++ b/packages/core/src/index.js @@ -0,0 +1,2 @@ +// Placeholder for core module exports +export {}; \ No newline at end of file diff --git a/packages/nostr/package.json b/packages/nostr/package.json new file mode 100644 index 0000000..2b6dd84 --- /dev/null +++ b/packages/nostr/package.json @@ -0,0 +1,14 @@ +{ + "name": "@nostr-governance/nostr", + "version": "0.1.0", + "type": "module", + "main": "src/index.js", + "types": "dist/types/src/index.d.ts", + "files": ["dist"], + "scripts": { + "test": "vitest run" + }, + "dependencies": { + "@nostr-governance/core": "workspace:*" + } +} \ No newline at end of file diff --git a/packages/nostr/src/index.js b/packages/nostr/src/index.js new file mode 100644 index 0000000..13f6f78 --- /dev/null +++ b/packages/nostr/src/index.js @@ -0,0 +1,2 @@ +// Placeholder for nostr module exports +export {}; \ No newline at end of file diff --git a/packages/runtime/package.json b/packages/runtime/package.json new file mode 100644 index 0000000..7daa405 --- /dev/null +++ b/packages/runtime/package.json @@ -0,0 +1,15 @@ +{ + "name": "@nostr-governance/runtime", + "version": "0.1.0", + "type": "module", + "main": "src/index.js", + "types": "dist/types/src/index.d.ts", + "files": ["dist"], + "scripts": { + "test": "vitest run" + }, + "dependencies": { + "@nostr-governance/core": "workspace:*", + "@nostr-governance/nostr": "workspace:*" + } +} \ No newline at end of file diff --git a/packages/runtime/src/index.js b/packages/runtime/src/index.js new file mode 100644 index 0000000..e94d8f9 --- /dev/null +++ b/packages/runtime/src/index.js @@ -0,0 +1,2 @@ +// Placeholder for runtime module exports +export {}; \ No newline at end of file diff --git a/packages/testing/package.json b/packages/testing/package.json new file mode 100644 index 0000000..47400d7 --- /dev/null +++ b/packages/testing/package.json @@ -0,0 +1,14 @@ +{ + "name": "@nostr-governance/testing", + "version": "0.1.0", + "type": "module", + "main": "src/index.js", + "types": "dist/types/src/index.d.ts", + "files": ["dist"], + "scripts": { + "test": "vitest run" + }, + "dependencies": { + "@nostr-governance/core": "workspace:*" + } +} \ No newline at end of file diff --git a/packages/testing/src/index.js b/packages/testing/src/index.js new file mode 100644 index 0000000..ade09ff --- /dev/null +++ b/packages/testing/src/index.js @@ -0,0 +1,2 @@ +// Placeholder for testing module exports +export {}; \ No newline at end of file diff --git a/scripts/verify-no-reference-imports.mjs b/scripts/verify-no-reference-imports.mjs new file mode 100644 index 0000000..8aa6b0b --- /dev/null +++ b/scripts/verify-no-reference-imports.mjs @@ -0,0 +1,42 @@ +#!/usr/bin/env node + +import { readFile } from 'node:fs/promises'; +import { join } from 'node:path'; +import { fileURLToPath } from 'node:url'; + +const FORBIDDEN_PATHS = [ + '/home/user/Documents/GitHub/bitvid', + '/home/user/Documents/GitHub/bitroad' +]; + +async function checkImports(rootPath) { + const pkgPath = join(rootPath, 'package.json'); + const pkg = JSON.parse(await readFile(pkgPath, 'utf-8')); + + const violations = []; + + for (const workspace of pkg.workspaces || []) { + const workspacePath = join(rootPath, workspace); + const workspacePkgPath = join(workspacePath, 'package.json'); + const workspacePkg = JSON.parse(await readFile(workspacePkgPath, 'utf-8')); + + for (const dep of Object.keys(workspacePkg.dependencies || {})) { + if (FORBIDDEN_PATHS.some(path => dep.startsWith(path))) { + violations.push(`Workspace ${workspace} depends on forbidden path: ${dep}`); + } + } + } + + if (violations.length > 0) { + console.error('\nReference import violations detected:'); + violations.forEach(v => console.error(`- ${v}`)); + process.exit(1); + } + + console.log('✓ No forbidden imports detected'); +} + +checkImports(fileURLToPath(new URL('.', import.meta.url))).catch(err => { + console.error('Check failed:', err); + process.exit(1); +}); \ No newline at end of file diff --git a/tsconfig.json b/tsconfig.json new file mode 100644 index 0000000..126de28 --- /dev/null +++ b/tsconfig.json @@ -0,0 +1,15 @@ +{ + "compilerOptions": { + "module": "ESNext", + "moduleResolution": "Bundler", + "target": "ES2022", + "strict": true, + "skipLibCheck": true, + "noEmit": true, + "allowJs": true, + "checkJs": true, + "types": ["vitest/globals"] + }, + "include": ["**/*.js"], + "exclude": ["node_modules"] +} \ No newline at end of file diff --git a/tsconfig.types.json b/tsconfig.types.json new file mode 100644 index 0000000..108ebec --- /dev/null +++ b/tsconfig.types.json @@ -0,0 +1,9 @@ +{ + "extends": "./tsconfig.json", + "compilerOptions": { + "emitDeclarationOnly": true, + "declaration": true, + "outDir": "dist/types" + }, + "include": ["packages/**/src/*.js"] +} \ No newline at end of file diff --git a/vitest.config.js b/vitest.config.js new file mode 100644 index 0000000..1ff2bcf --- /dev/null +++ b/vitest.config.js @@ -0,0 +1,12 @@ +import { defineConfig } from 'vitest/config'; + +export default defineConfig({ + test: { + include: ['**/*.test.js'], + environment: 'node', + coverage: { + provider: 'v8', + reporter: ['text', 'json-summary'] + } + } +}); \ No newline at end of file