Stamp 2.59.0 Docker leftover seams only, not PinScope product.

Images copy periscope/src, vendor/, and skipped Clerk/shadcn/billing/GCS
files. dependency/ stays in git. Audit written; FastAPI boots with
PYTHONPATH=src.
This commit is contained in:
2026-09-20 21:03:26 +02:00
parent 22bc075c58
commit ed3fff565d
11 changed files with 137 additions and 16 deletions
+5 -6
View File
@@ -3,24 +3,23 @@ RUN apt-get update && apt-get install -y git && rm -rf /var/lib/apt/lists/*
WORKDIR /app
# Overlay: PinScope inherited tree, then native Periscope modules.
COPY periscope/src/backend/requirements*.txt /app/backend/
RUN pip install --no-cache-dir -r /app/backend/requirements.txt \
&& if [ -f /app/backend/requirements-gateway.txt ]; then \
pip install --no-cache-dir -r /app/backend/requirements-gateway.txt; \
fi
COPY periscope/dependency/backend/ /app/backend/
COPY periscope/src/backend/ /app/backend/
COPY periscope/dependency/taxonomy/ /app/taxonomy/
COPY periscope/src/taxonomy/ /app/taxonomy/
COPY periscope/dependency/skills/ /app/skills/
COPY periscope/src/skills/ /app/skills/
COPY periscope/dependency/frontend/content/changelog.md /app/changelog.md
COPY periscope/src/frontend/content/changelog.md /app/changelog.md
COPY vendor/ /app/vendor/
# Leftover seams (not PinScope product): unused LLM providers + GCS storage.
COPY periscope/dependency/backend/services/llm/anthropic_provider.py /app/backend/services/llm/anthropic_provider.py
COPY periscope/dependency/backend/services/llm/gemini_provider.py /app/backend/services/llm/gemini_provider.py
COPY periscope/dependency/backend/services/storage_gcs.py /app/backend/services/storage_gcs.py
EXPOSE 8080
CMD ["uvicorn", "backend.main:app", "--host", "0.0.0.0", "--port", "8080"]
+2 -3
View File
@@ -2,10 +2,9 @@
Physical split:
periscope/src native Periscope
periscope/dependency inherited PinScope (in-tree dependency)
periscope/dependency leftover seams + fixtures (not copied wholesale into Docker)
Docker copies dependency then src for backend, taxonomy, skills, and
frontend content (changelog / legal / file-guide).
Docker copies native src, vendor/, and leftover seam files only.
"""
from __future__ import annotations
@@ -0,0 +1,44 @@
# Dependency audit — PinScope product vs leftover seams (2026-09-20)
Docker images no longer copy the unused PinScope product tree. `periscope/dependency/` remains **in git** for leftover seams, `simple_project/`, docs, and historical copies. Git-delete of the directory is **not** done: leftover shadcn/Clerk/billing/analytics, unused LLM providers, GCS storage, and landing png/gif are still required for overlay CI / optional seams.
No product import from `dependency/` is required to boot FastAPI (`backend.main`) when `PYTHONPATH` is `periscope/src`.
## Skip (not PinScope product)
- `frontend/src/components/ui/*` (shadcn)
- Clerk: `use-optional-auth.ts`, `clerk-theme-provider.tsx`, `proxy.ts`
- billing: `components/billing/*`, `pricing-section.tsx`
- analytics/reddit pixels
- `vendor/impedancefinder/` (third-party solver)
## Remaining `periscope/dependency` hits (live / Docker / imports)
| Kind | Path | Why it remains |
| --- | --- | --- |
| Docker leftover | `backend/services/llm/anthropic_provider.py` | optional provider; factory defaults DeepSeek |
| Docker leftover | `backend/services/llm/gemini_provider.py` | optional provider |
| Docker leftover | `backend/services/storage_gcs.py` | optional GCS |
| Docker leftover | `frontend/src/components/ui/*` | shadcn |
| Docker leftover | `frontend/src/hooks/use-optional-auth.ts` | Clerk/open-core seam |
| Docker leftover | `frontend/src/proxy.ts` | Clerk seam |
| Docker leftover | `frontend/src/components/theme/clerk-theme-provider.tsx` | Clerk seam |
| Docker leftover | `frontend/src/components/billing/*` | billing seam |
| Docker leftover | `frontend/src/components/analytics/*` | reddit pixels |
| Docker leftover | `frontend/src/components/marketing/pricing-section.tsx` | billing marketing |
| Docker leftover | `frontend/public/report.png` `datasheet.gif` `derating.png` | landing captures still inherited shots |
| Git fixture | `simple_project/` | tests + README demo |
| Git docs | `docs/how-it-works.svg` | README image |
| Historical copies | `dependency/backend/**`, `dependency/frontend/**` product modules | unused by Docker; not git-deleted |
## Faradworks / PinScope string hits (not skipped seams)
Attribution / legal / changelog / README (AGPL lineage). Dual-read JWT issuer `pinscope-local` in `pinscope_compat`. Compose network aliases `pinscope-backend` / `pinscope-frontend` for Caddy. `LICENSE` AGPL unchanged.
## Product modules no longer copied into the image
Inherited graph/parsers/pipeline/Next shell/taxonomy/skills under `dependency/` are **not** `COPY`'d. Native equivalents live in `periscope/src`.
## Boot proof
`tests/test_periscope_boot_without_dependency_product.py` runs `backend.main` with `PYTHONPATH=periscope/src` only.
@@ -2,6 +2,13 @@
What's new in Periscope.
## 2.59.0 — 2026-09-20 — Docker without unused PinScope product tree
Images copy `periscope/src` plus leftover seams (shadcn/Clerk/billing, unused LLM providers, GCS, landing png/gif) and `vendor/`. They do not copy the inherited PinScope product tree. `dependency/` stays in git. Audit: `periscope/src/docs/development/DEPENDENCY_AUDIT.md`. Pad≠Via unchanged.
- [Changed] Backend/frontend Dockerfiles drop wholesale `COPY periscope/dependency/{backend,frontend}`.
- [New] Boot test runs FastAPI with `PYTHONPATH=periscope/src` only.
## 2.58.0 — 2026-09-20 — Native JWT middleware and useAuthApi
`backend/middleware/auth.py` and `frontend/src/hooks/use-auth-api.ts` are original Periscope code. Skip paths, Bearer/query token, Clerk RS256 leftover, and local HS256 (`local_jwt.decode_token`) stay the same HTTP contract. `routers/auth.py`, `data/auth/users`, and `AUTH_JWT_SECRET` are unchanged. Pad≠Via unchanged.
+14 -1
View File
@@ -10,9 +10,22 @@ ENV NEXT_PUBLIC_AUTH_MODE=$NEXT_PUBLIC_AUTH_MODE
COPY periscope/src/frontend/package.json periscope/src/frontend/package-lock.json ./
RUN npm ci
COPY periscope/dependency/frontend/ ./
COPY periscope/src/frontend/ ./
# Leftover seams (shadcn/Clerk/billing/analytics) — not PinScope product.
COPY periscope/dependency/frontend/src/components/ui ./src/components/ui
COPY periscope/dependency/frontend/src/components/billing ./src/components/billing
COPY periscope/dependency/frontend/src/components/analytics ./src/components/analytics
COPY periscope/dependency/frontend/src/components/theme/clerk-theme-provider.tsx ./src/components/theme/clerk-theme-provider.tsx
COPY periscope/dependency/frontend/src/components/marketing/pricing-section.tsx ./src/components/marketing/pricing-section.tsx
COPY periscope/dependency/frontend/src/hooks/use-optional-auth.ts ./src/hooks/use-optional-auth.ts
COPY periscope/dependency/frontend/src/proxy.ts ./src/proxy.ts
# Landing captures still PinScope shots until native screenshots exist.
COPY periscope/dependency/frontend/public/report.png ./public/report.png
COPY periscope/dependency/frontend/public/datasheet.gif ./public/datasheet.gif
COPY periscope/dependency/frontend/public/derating.png ./public/derating.png
ENV NEXT_TELEMETRY_DISABLED=1
RUN echo "BUILD API URL=$NEXT_PUBLIC_API_URL AUTH_MODE=$NEXT_PUBLIC_AUTH_MODE"
+2 -2
View File
@@ -1,12 +1,12 @@
{
"name": "periscope-web",
"version": "2.58.0",
"version": "2.59.0",
"lockfileVersion": 3,
"requires": true,
"packages": {
"": {
"name": "periscope-web",
"version": "2.58.0",
"version": "2.59.0",
"dependencies": {
"@base-ui/react": "^1.3.0",
"@types/dagre": "^0.7.54",
+1 -1
View File
@@ -1,6 +1,6 @@
{
"name": "periscope-web",
"version": "2.58.0",
"version": "2.59.0",
"private": true,
"scripts": {
"sync-version": "node scripts/sync-version.mjs",
+3
View File
@@ -126,6 +126,9 @@ if [[ ! -f .env ]]; then
if [[ -f backend/.env ]]; then
log "No ./.env — copying backend/.env"
cp backend/.env .env
elif [[ -f periscope/src/backend/.env.example ]]; then
log "No ./.env — copying periscope/src/backend/.env.example (you must set DEEPSEEK_API_KEY)"
cp periscope/src/backend/.env.example .env
elif [[ -f periscope/dependency/backend/.env.example ]]; then
log "No ./.env — copying periscope/dependency/backend/.env.example (you must set DEEPSEEK_API_KEY)"
cp periscope/dependency/backend/.env.example .env
@@ -0,0 +1,55 @@
"""Docker copies leftover seams only; FastAPI boots without dependency product."""
from __future__ import annotations
import os
import subprocess
import sys
from pathlib import Path
ROOT = Path(__file__).resolve().parents[1]
BE_DOCKER = (ROOT / "periscope" / "src" / "backend" / "Dockerfile").read_text(encoding="utf-8")
FE_DOCKER = (ROOT / "periscope" / "src" / "frontend" / "dockerfile").read_text(encoding="utf-8")
AUDIT = ROOT / "periscope" / "src" / "docs" / "development" / "DEPENDENCY_AUDIT.md"
def test_audit_is_written():
text = AUDIT.read_text(encoding="utf-8")
assert "leftover seams" in text.lower() or "Leftover" in text
assert "simple_project" in text
assert "Git-delete of the directory is **not** done" in text
def test_dockerfiles_do_not_copy_dependency_product_trees():
assert "COPY periscope/dependency/backend/ /app/backend/" not in BE_DOCKER
assert "COPY periscope/dependency/taxonomy/" not in BE_DOCKER
assert "COPY periscope/dependency/skills/" not in BE_DOCKER
assert "COPY periscope/dependency/frontend/ ./" not in FE_DOCKER
assert "COPY vendor/" in BE_DOCKER
assert "COPY periscope/src/backend/" in BE_DOCKER
assert "anthropic_provider.py" in BE_DOCKER
assert "use-optional-auth.ts" in FE_DOCKER
assert "report.png" in FE_DOCKER
def test_boot_without_dependency_on_pythonpath():
src = ROOT / "periscope" / "src"
env = os.environ.copy()
env["PYTHONPATH"] = str(src)
env.pop("AUTH_JWT_SECRET", None)
proc = subprocess.run(
[
sys.executable,
"-c",
"from backend.main import app; from backend.middleware.auth import verify_request_user; "
"print(app.title); print(verify_request_user.__name__)",
],
cwd=ROOT,
env=env,
capture_output=True,
text=True,
check=False,
)
assert proc.returncode == 0, proc.stderr
assert "PeriscopeX" in proc.stdout
assert "verify_request_user" in proc.stdout
@@ -28,9 +28,9 @@ def test_legal_pages_are_operator_not_faradworks_controller():
assert "This Service is **not** operated by Faradworks, Inc." in terms
def test_changelog_stamp_is_2_58_0_and_src_wins():
def test_changelog_stamp_is_2_59_0_and_src_wins():
text = (SRC / "changelog.md").read_text(encoding="utf-8")
assert "## 2.58.0 — 2026-09-20" in text
assert "## 2.59.0 — 2026-09-20" in text
first = changelog_paths()[0]
assert first.parts[-3:] == ("src", "frontend", "content") or first.name == "changelog.md"
assert first == SRC / "changelog.md"
@@ -17,7 +17,7 @@ DOCKERIGNORE = ROOT / ".dockerignore"
def test_package_json_is_periscope_web():
text = PKG.read_text(encoding="utf-8")
assert '"name": "periscope-web"' in text
assert '"version": "2.58.0"' in text
assert '"version": "2.59.0"' in text
assert "Native Periscope overlay" not in text[:400]
assert LOCK.is_file()
lock = LOCK.read_text(encoding="utf-8")
@@ -45,6 +45,7 @@ def test_docker_installs_from_src():
assert "COPY periscope/src/frontend/package.json" in fe
assert "periscope/src/frontend/package-lock.json" in fe
assert "COPY periscope/src/backend/requirements*.txt" in be
assert "COPY periscope/dependency/backend/ /app/backend/" not in be
ignore = DOCKERIGNORE.read_text(encoding="utf-8")
assert "faradworks-logo-white.png" in ignore
assert "power-tree.gif" in ignore