diff --git a/.cursor/rules/00-coding-constitution.mdc b/.cursor/rules/00-coding-constitution.mdc new file mode 100644 index 0000000..5c47e85 --- /dev/null +++ b/.cursor/rules/00-coding-constitution.mdc @@ -0,0 +1,21 @@ +--- +alwaysApply: true +--- + +# Periscope Cursor Engineering Rules + +Mandatory for every Cursor agent working on Periscope. This section is copied from `docs/development/CODING_CONSTITUTION.md` and must not contradict that master. + +## 0. Coding constitution + +- You are implementing Periscope (schematic/PCB validation), not a generic scaffold and not Faradworks/PinScope under a new name. +- Prefer original Periscope source in `periscope/src` over copying PinScope. Overlay stamps, `cp` of `periscope/dependency/**`, and near-identical pastes do **not** create architectural or AGPL independence. +- Keep `periscope/dependency/` until a rewritten slice is proven. Never empty-delete inherited files to “look native.” +- Auto-place / pcbnew write-back is out of scope unless Michele explicitly asks. +- Never touch live auth users, password hashes, or `AUTH_JWT_SECRET` unless Michele explicitly orders a credential change in that turn. +- Never swallow exceptions with bare `except: continue`. Log or re-raise. +- Match existing public contracts (Pydantic models, REST shapes, finding engine). Frontend types stay in sync with backend models. +- AGPL-3.0 of the fork stays visible. Do not relicense. Do not detach the GitHub fork unless Michele and counsel say so. +- Gateway-owned seams stay stub-shaped (`billing_hook.get_billing()`, frontend auth/billing pass-throughs). Do not import Clerk/Stripe SDKs outside those seams. +- Skills stay local (`skills/*/SKILL.md` + `validate.py` on DeepSeek). Do not run `scripts/upload_skills.py`. +- Default LLM path is DeepSeek. Do not route live stages to Anthropic Console. diff --git a/.cursor/rules/10-architecture.mdc b/.cursor/rules/10-architecture.mdc new file mode 100644 index 0000000..39e7358 --- /dev/null +++ b/.cursor/rules/10-architecture.mdc @@ -0,0 +1,27 @@ +--- +alwaysApply: true +--- + +# Periscope Cursor Engineering Rules + +Mandatory for every Cursor agent working on Periscope. This section is copied from `docs/development/CODING_CONSTITUTION.md` and must not contradict that master. + +## 1. Architecture + +Three layers: + +| Layer | Location | Purpose | +| --- | --- | --- | +| Core | `backend/periscopex/` (native under `periscope/src` when split) | Models, parsers, graph, validator, passives, taxonomy, derating | +| Backend | `backend/` | FastAPI, pipeline, SSE, storage | +| Frontend | `frontend/` | Next.js app: dashboard, progress, report, derating, admin | + +Physical split (when present): `periscope/src` = Periscope; `periscope/dependency` = inherited PinScope in-tree. Docker copies dependency then src so native files win **only when they are real replacements**, not stamped copies. + +Import switch rule: keep calling `dependency/` until pytest + deploy smoke pass for that slice, then switch imports. Fail-soft: if verification fails, leave the inherited path. + +Netlist is a queryable bipartite graph (components + nets). Deterministic checks beat heuristics. Finding normalization is downgrade-only. Cross-IC excerpt budget is global plus per-neighbor. + +Content-addressed datasheets live under `library/datasheets/`. DigiKey matches exact MPN only. Value-string passives stay per-project, never the shared library. + +Do not add auth, billing, or extra services unless the task needs them. Do not add a second frontend component library. diff --git a/.cursor/rules/20-python.mdc b/.cursor/rules/20-python.mdc new file mode 100644 index 0000000..6992777 --- /dev/null +++ b/.cursor/rules/20-python.mdc @@ -0,0 +1,18 @@ +--- +alwaysApply: true +--- + +# Periscope Cursor Engineering Rules + +Mandatory for every Cursor agent working on Periscope. This section is copied from `docs/development/CODING_CONSTITUTION.md` and must not contradict that master. + +## 2. Python + +- Python 3.12+, Pydantic 2.x, FastAPI on the backend. +- Parsers and graph builders are pure functions without hidden I/O, except documented loaders (`build_graph` from paths). +- All shared data structures are Pydantic models in `backend/periscopex/models.py` (or the native successor once rewritten). +- Tests live under `tests/` against `simple_project/` as ground truth. Emmaforo behavior is a live spec, not a license to skip unit tests. +- Extraction prompts live in `skills/` and run in-process. Bump `default_model_version` in `skills_manifest.json` when skill prompts change; never call Anthropic Console. +- Use stdlib hashing (`hashlib.scrypt` in `local_users.hash_password`) for local passwords. Do not invent a homemade hash. +- `repo_paths.py` locates taxonomy, skills, vendor, changelog. Do not hard-code `/app` without the Docker heuristic that also requires `vendor/`. +- Format and lint with the repo’s existing tools. Do not drive-by reformat unrelated files. diff --git a/.cursor/rules/30-rust.mdc b/.cursor/rules/30-rust.mdc new file mode 100644 index 0000000..d8eee7e --- /dev/null +++ b/.cursor/rules/30-rust.mdc @@ -0,0 +1,14 @@ +--- +alwaysApply: true +--- + +# Periscope Cursor Engineering Rules + +Mandatory for every Cursor agent working on Periscope. This section is copied from `docs/development/CODING_CONSTITUTION.md` and must not contradict that master. + +## 3. Rust + +- Periscope’s product code is Python/TypeScript today. If a Rust crate is added, it is original Periscope code, not a paste of an AGPL PinScope module. +- Rust slices follow the same verify-then-switch rule: tests first, then wire into the Python/TS surface. +- Use `rustfmt` + `clippy` on that crate. No `unsafe` without a comment that names the invariant. +- Do not introduce Rust to dodge AGPL or to empty-delete Python in `dependency/`. diff --git a/.cursor/rules/40-testing.mdc b/.cursor/rules/40-testing.mdc new file mode 100644 index 0000000..b371790 --- /dev/null +++ b/.cursor/rules/40-testing.mdc @@ -0,0 +1,16 @@ +--- +alwaysApply: true +--- + +# Periscope Cursor Engineering Rules + +Mandatory for every Cursor agent working on Periscope. This section is copied from `docs/development/CODING_CONSTITUTION.md` and must not contradict that master. + +## 4. Testing + +- Write tests before considering a slice done. Prefer tests that lock behavior (graph topology, finding codes, via≠pad, review isolation) over tests that assert overlay stamps or file provenance comments. +- `pytest` from the worktree with the project venv. Do not claim green from a system Python missing deps. +- One malformed IC must not kill the whole review; keep per-IC isolation tests. +- Do not add tests whose only job is to require `Native Periscope overlay` in a copied file. +- UI changes: exercise the flow (not a single screenshot). If no browser tools, say what was not verified. +- Installing docs/rules is a docs phase: existence and internal consistency of the seven `.mdc` files plus this master is the check. There is no product pytest gate for markdown-only. diff --git a/.cursor/rules/50-verification.mdc b/.cursor/rules/50-verification.mdc new file mode 100644 index 0000000..23f46dd --- /dev/null +++ b/.cursor/rules/50-verification.mdc @@ -0,0 +1,14 @@ +--- +alwaysApply: true +--- + +# Periscope Cursor Engineering Rules + +Mandatory for every Cursor agent working on Periscope. This section is copied from `docs/development/CODING_CONSTITUTION.md` and must not contradict that master. + +## 5. Verification + +- Verify-then-switch: pytest (or the docs check above) **then** import/path switch, **then** commit+push at phase end. +- Live smoke after a **macro-phase** deploy: version from changelog, health of `/api/auth/mode`, overlay/rewrite modules that should load, users **untouched**. +- Deploy script: `/root/periscope` `./scripts/update-periscope.sh`. Prefer `--no-pull` after the host checkout is already on the intended SHA. Do not let the script generate a new `AUTH_JWT_SECRET` if one exists. +- Do not treat Docker COPY of `src` over `dependency` as proof of a rewrite. diff --git a/.cursor/rules/60-git-workflow.mdc b/.cursor/rules/60-git-workflow.mdc new file mode 100644 index 0000000..cc0ec86 --- /dev/null +++ b/.cursor/rules/60-git-workflow.mdc @@ -0,0 +1,26 @@ +--- +alwaysApply: true +--- + +# Periscope Cursor Engineering Rules + +Mandatory for every Cursor agent working on Periscope. This section is copied from `docs/development/CODING_CONSTITUTION.md` and must not contradict that master. + +## 6. Git workflow + +Worktree for this product line: `~/Development/pinscope-tree-split` unless Michele names another. Do not start a second clone to dodge the worktree. + +### Phase vs macro-phase + +- **Phase** (one verified slice: e.g. rules install, one rewritten module with tests): when tests (or the docs check) pass → **commit and push**. That is the end of the phase. +- **Macro-phase** (a named batch of phases Michele treats as one shippable increment): **deploy only after a macro-phase**, not after every phase, and not at a mere phase boundary. +- **No commit, push, or deploy on every small edit.** Edit, keep working, commit when the phase is actually done. +- **No deploy at a mere phase boundary.** Passing tests + push is not a deploy order. + +### Other git rules + +- Feature branches `cursor/-0d9d` (lowercase). Do not force-push unless Michele explicitly orders it. +- Do not create pull requests unless Michele asks. +- Push `origin` and `github` when this worktree has both remotes. +- Do not commit secrets, `data/auth/users`, or `.env` password material. +- Changelog version is the latest `## x.y.z` in `frontend/content/changelog.md` (dependency copy is the Docker source of truth today). Bump only when the phase is a product change, not for docs-only rules unless Michele wants a version bump. diff --git a/docs/development/CODING_CONSTITUTION.md b/docs/development/CODING_CONSTITUTION.md new file mode 100644 index 0000000..108fc68 --- /dev/null +++ b/docs/development/CODING_CONSTITUTION.md @@ -0,0 +1,90 @@ +# Periscope Cursor Engineering Rules + +Mandatory for every Cursor agent working on Periscope. Do not invent a weaker local policy. This file is the master; `.cursor/rules/*.mdc` split the same text by section and must not contradict it. + +## 0. Coding constitution + +- You are implementing Periscope (schematic/PCB validation), not a generic scaffold and not Faradworks/PinScope under a new name. +- Prefer original Periscope source in `periscope/src` over copying PinScope. Overlay stamps, `cp` of `periscope/dependency/**`, and near-identical pastes do **not** create architectural or AGPL independence. +- Keep `periscope/dependency/` until a rewritten slice is proven. Never empty-delete inherited files to “look native.” +- Auto-place / pcbnew write-back is out of scope unless Michele explicitly asks. +- Never touch live auth users, password hashes, or `AUTH_JWT_SECRET` unless Michele explicitly orders a credential change in that turn. +- Never swallow exceptions with bare `except: continue`. Log or re-raise. +- Match existing public contracts (Pydantic models, REST shapes, finding engine). Frontend types stay in sync with backend models. +- AGPL-3.0 of the fork stays visible. Do not relicense. Do not detach the GitHub fork unless Michele and counsel say so. +- Gateway-owned seams stay stub-shaped (`billing_hook.get_billing()`, frontend auth/billing pass-throughs). Do not import Clerk/Stripe SDKs outside those seams. +- Skills stay local (`skills/*/SKILL.md` + `validate.py` on DeepSeek). Do not run `scripts/upload_skills.py`. +- Default LLM path is DeepSeek. Do not route live stages to Anthropic Console. + +## 1. Architecture + +Three layers: + +| Layer | Location | Purpose | +| --- | --- | --- | +| Core | `backend/periscopex/` (native under `periscope/src` when split) | Models, parsers, graph, validator, passives, taxonomy, derating | +| Backend | `backend/` | FastAPI, pipeline, SSE, storage | +| Frontend | `frontend/` | Next.js app: dashboard, progress, report, derating, admin | + +Physical split (when present): `periscope/src` = Periscope; `periscope/dependency` = inherited PinScope in-tree. Docker copies dependency then src so native files win **only when they are real replacements**, not stamped copies. + +Import switch rule: keep calling `dependency/` until pytest + deploy smoke pass for that slice, then switch imports. Fail-soft: if verification fails, leave the inherited path. + +Netlist is a queryable bipartite graph (components + nets). Deterministic checks beat heuristics. Finding normalization is downgrade-only. Cross-IC excerpt budget is global plus per-neighbor. + +Content-addressed datasheets live under `library/datasheets/`. DigiKey matches exact MPN only. Value-string passives stay per-project, never the shared library. + +Do not add auth, billing, or extra services unless the task needs them. Do not add a second frontend component library. + +## 2. Python + +- Python 3.12+, Pydantic 2.x, FastAPI on the backend. +- Parsers and graph builders are pure functions without hidden I/O, except documented loaders (`build_graph` from paths). +- All shared data structures are Pydantic models in `backend/periscopex/models.py` (or the native successor once rewritten). +- Tests live under `tests/` against `simple_project/` as ground truth. Emmaforo behavior is a live spec, not a license to skip unit tests. +- Extraction prompts live in `skills/` and run in-process. Bump `default_model_version` in `skills_manifest.json` when skill prompts change; never call Anthropic Console. +- Use stdlib hashing (`hashlib.scrypt` in `local_users.hash_password`) for local passwords. Do not invent a homemade hash. +- `repo_paths.py` locates taxonomy, skills, vendor, changelog. Do not hard-code `/app` without the Docker heuristic that also requires `vendor/`. +- Format and lint with the repo’s existing tools. Do not drive-by reformat unrelated files. + +## 3. Rust + +- Periscope’s product code is Python/TypeScript today. If a Rust crate is added, it is original Periscope code, not a paste of an AGPL PinScope module. +- Rust slices follow the same verify-then-switch rule: tests first, then wire into the Python/TS surface. +- Use `rustfmt` + `clippy` on that crate. No `unsafe` without a comment that names the invariant. +- Do not introduce Rust to dodge AGPL or to empty-delete Python in `dependency/`. + +## 4. Testing + +- Write tests before considering a slice done. Prefer tests that lock behavior (graph topology, finding codes, via≠pad, review isolation) over tests that assert overlay stamps or file provenance comments. +- `pytest` from the worktree with the project venv. Do not claim green from a system Python missing deps. +- One malformed IC must not kill the whole review; keep per-IC isolation tests. +- Do not add tests whose only job is to require `Native Periscope overlay` in a copied file. +- UI changes: exercise the flow (not a single screenshot). If no browser tools, say what was not verified. +- Installing docs/rules is a docs phase: existence and internal consistency of the seven `.mdc` files plus this master is the check. There is no product pytest gate for markdown-only. + +## 5. Verification + +- Verify-then-switch: pytest (or the docs check above) **then** import/path switch, **then** commit+push at phase end. +- Live smoke after a **macro-phase** deploy: version from changelog, health of `/api/auth/mode`, overlay/rewrite modules that should load, users **untouched**. +- Deploy script: `/root/periscope` `./scripts/update-periscope.sh`. Prefer `--no-pull` after the host checkout is already on the intended SHA. Do not let the script generate a new `AUTH_JWT_SECRET` if one exists. +- Do not treat Docker COPY of `src` over `dependency` as proof of a rewrite. + +## 6. Git workflow + +Worktree for this product line: `~/Development/pinscope-tree-split` unless Michele names another. Do not start a second clone to dodge the worktree. + +### Phase vs macro-phase + +- **Phase** (one verified slice: e.g. rules install, one rewritten module with tests): when tests (or the docs check) pass → **commit and push**. That is the end of the phase. +- **Macro-phase** (a named batch of phases Michele treats as one shippable increment): **deploy only after a macro-phase**, not after every phase, and not at a mere phase boundary. +- **No commit, push, or deploy on every small edit.** Edit, keep working, commit when the phase is actually done. +- **No deploy at a mere phase boundary.** Passing tests + push is not a deploy order. + +### Other git rules + +- Feature branches `cursor/-0d9d` (lowercase). Do not force-push unless Michele explicitly orders it. +- Do not create pull requests unless Michele asks. +- Push `origin` and `github` when this worktree has both remotes. +- Do not commit secrets, `data/auth/users`, or `.env` password material. +- Changelog version is the latest `## x.y.z` in `frontend/content/changelog.md` (dependency copy is the Docker source of truth today). Bump only when the phase is a product change, not for docs-only rules unless Michele wants a version bump.