From 15c4ee5e1a15fc84f959627205e4aec2fa397e57 Mon Sep 17 00:00:00 2001 From: tegwick Date: Mon, 22 Jun 2026 22:02:19 +0200 Subject: [PATCH] Adapt repo to state-hub domain classification (DoI: full tier) - Rewrite SCOPE.md to the state-hub standard template (11 H2 sections + 2 parseable capability blocks under Provided Capabilities) - Add tpsc.yaml declaring the Binect REST API as the sole third-party service - Add Kaizen Agents reference to CLAUDE.md (C12) Registered binect-chrome under the communication domain; SBOM (566 pkgs) and TPSC ingested, active repo goal created, host path registered. Co-Authored-By: Claude Opus 4.8 --- CLAUDE.md | 6 ++ SCOPE.md | 180 +++++++++++++++++++++++++++++------------------------- tpsc.yaml | 9 +++ 3 files changed, 113 insertions(+), 82 deletions(-) create mode 100644 tpsc.yaml diff --git a/CLAUDE.md b/CLAUDE.md index 9c4f732..3f80258 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -72,6 +72,12 @@ Cap at ~500 entries to prevent unbounded growth. - Automated publication via Chrome Web Store - Must pass Chrome Web Store security review (minimal permissions critical) +## Kaizen Agents + +Specialized kaizen agent personas are available on demand via the state-hub MCP — +discover with `list_kaizen_agents()` and load with `get_kaizen_agent("")`, +then read and follow their instructions. + ## Contact & Support Feature requests and bug reports: bernd.worsch@binect.de diff --git a/SCOPE.md b/SCOPE.md index 4b311c0..65e0d9f 100644 --- a/SCOPE.md +++ b/SCOPE.md @@ -1,112 +1,128 @@ -# SCOPE.md +# SCOPE -> This document defines **what BinectChrome does and does not cover**, concretely and as currently built. Where [`INTENT.md`](INTENT.md) records *why* the project exists and the principles it must uphold, this file draws the **operational boundary**: which capabilities are implemented, which are explicitly excluded, and where the edges are. A feature request is answered first by checking it against this document. It reflects the state of the code at the 2026-06 lifecycle reconciliation. +> This file helps you quickly understand what this repository is about, +> when it is relevant, and when it is not. It draws the **operational +> boundary** of what BinectChrome does and does not cover, as currently built; +> [`INTENT.md`](INTENT.md) records *why* the project exists and the principles +> it must uphold. A feature request is answered first by checking it here. +> Reflects the state of the code at the 2026-06 lifecycle reconciliation. -## 1. Scope Statement +--- -BinectChrome covers **detecting a PDF in Chrome and sending it to Binect for physical mail, then tracking that document through its Binect lifecycle** — entirely from the browser, with no backend and no stored document content. It covers the detection, send, order, status, and local-tracking surface needed for that journey, and a thin credential layer to authenticate. It covers nothing on the server side beyond calling the Binect API, and nothing about creating or editing the documents themselves. +## One-liner -## 2. In Scope (Implemented) +A Chrome (MV3) extension that detects a PDF in the browser, sends it to Binect for physical mail, and tracks that document through its Binect lifecycle — backend-free and with zero stored document content. -### 2.1 PDF Detection (`src/utils/pdf-detector.ts`) +--- -| Capability | Status | Notes | -|------------|--------|-------| -| Detect completed PDF downloads via Chrome Downloads API | ✅ | By `.pdf` extension or `application/pdf` MIME. | -| Scan recent downloads on popup open | ✅ | `getLastPDFDownload` / popup `checkRecentDownloads`. | -| Detect PDF in the current tab | ✅ (best effort) | `checkCurrentTabForPDF` in popup. | -| Re-fetch PDF bytes from original URL using the user session | ✅ | `fetchPDFBytes`, `credentials: 'include'`. | -| Blob-URL / complex-JS-viewer PDFs | ❌ (accepted limitation) | Not reliably detectable or retrievable — by design. | +## Core Idea -### 2.2 Document Proxy Queue & Lifecycle (`src/utils/pdf-queue.ts`) +Sending a cloud-app PDF as physical mail normally means download → re-upload into Binect. BinectChrome collapses that into one click from the browser: it detects the PDF, re-fetches the bytes using the user's own session, uploads via the [`@binect/js`](../binect-js) SDK, and tracks the document through its Binect lifecycle — storing only metadata, never the PDF itself. See [`INTENT.md`](INTENT.md) for the full intent and inviolable principles. -- **Proxies**: metadata-only records of detected/sent PDFs (`DocumentProxy`); **never contain PDF content**. -- **Deduplication** by filename + content hash (`src/utils/hash.ts`). -- **Lifecycle states**: `pending → uploading → in_basket → ordering → in_production → sent`, plus `failed` and `canceled`, mirroring the Binect server status. -- **Live vs. archived** views; archived proxies age out after ~30 days; queue capped at ~100 entries. -- **Server sync / reconciliation**: `syncFromServer`, `attachServerDocument`, `clearServerFields` — adopt server-discovered documents, update statuses, and detach proxies for documents deleted upstream. +--- -### 2.3 Binect API Operations (`src/utils/binect-api.ts`, via `@binect/js`) +## In Scope -All Binect access is delegated to the [`@binect/js`](../binect-js) SDK; this module is a thin wrapper with extension-friendly types and error mapping. +- **PDF detection (`src/utils/pdf-detector.ts`)** — completed PDF downloads via the Chrome Downloads API (`.pdf`/`application/pdf`), recent-download scan on popup open, best-effort current-tab detection, and re-fetch of PDF bytes from the original URL with `credentials: 'include'`. +- **Document proxy queue & lifecycle (`src/utils/pdf-queue.ts`)** — metadata-only `DocumentProxy` records (never PDF content), dedup by filename + content hash, lifecycle `pending → uploading → in_basket → ordering → in_production → sent` (+ `failed`/`canceled`), live vs. archived views, and server sync/reconciliation. +- **Binect API operations (`src/utils/binect-api.ts`, via `@binect/js`)** — `uploadPDF`, `shipDocument`, `getDocumentStatus`, `listServerDocuments`, `deleteDocument`, `testConnection`, with structured error mapping. All Binect access delegated 1:1 to the SDK. +- **Authentication & credentials (`src/utils/crypto.ts`, `storage.ts`)** — username + password (HTTP Basic), AES-GCM (256-bit) encryption at rest via Web Crypto, 60-day inactivity expiry, manual wipe, self-deleting corrupted ciphertext. +- **UI (`src/popup/`, `src/tracking/`)** — login + lifecycle-grouped document list with send/order/refresh/archive/restore/delete actions, toolbar badge, and a tracking/help page. +- **Local tracking (`src/tracking/tracker.ts`)** — append-only, local-only transfer log (~500 cap), summary counts, CSV export, email-draft feedback. +- **Service worker & platform** — MV3 service worker message router, `chrome.alarms` for expiry/cleanup ticks, permissions `downloads`/`storage`/`alarms`/`activeTab` + host access. +- **Supporting material** — Jest tests (`@binect/js` mocked), TypeScript + Webpack build, ESLint, docs/ADRs. -| Operation | Status | -|-----------|--------| -| `uploadPDF` — base64 upload, places document in basket | ✅ | -| `shipDocument` — place the print/delivery order | ✅ | -| `getDocumentStatus` — per-document status refresh | ✅ | -| `listServerDocuments` — list documents Binect holds (for sync) | ✅ | -| `deleteDocument` — remove a document server-side | ✅ | -| `testConnection` — credential validation | ✅ | -| Structured errors (`BinectAPIError`, auth/size/4xx mapping) | ✅ | +--- -### 2.4 Authentication & Credentials (`src/utils/crypto.ts`, `src/utils/storage.ts`) +## Out of Scope -- Username + password (HTTP Basic, per the Binect API). -- **AES-GCM (256-bit)** encryption at rest via the Web Crypto API; key stored in `chrome.storage.local`; decrypted only in memory. -- **60-day inactivity expiry**: `lastUse` timestamp refreshed on use; expired credentials auto-deleted on next load and by a daily `chrome.alarms` check. -- Manual wipe (logout) always available; corrupted ciphertext is self-deleting. +- Storing, viewing, editing, or inspecting PDF content — zero-retention; proxies hold metadata only. +- Any server-side / backend component — the extension talks directly to Binect. +- Automatic or background sending, ordering, or deleting — every dispatch is explicit user intent. +- PDF generation, layout, or transformation — the user brings a finished PDF. +- Reinterpreting or extending the Binect API — delegated 1:1 to `@binect/js`; new coverage belongs upstream. +- Cross-browser support, credential federation/SSO/token auth, telemetry/analytics, and rule-based automation / multi-profile destinations (PRD future considerations, not built). -### 2.5 User Interface (`src/popup/`, `src/tracking/`) +--- -- **Popup**: login view, document list grouped by lifecycle stage (pending / erroneous / basket / production / completed / archived), send / order / refresh / archive / restore / delete actions, password-visibility toggle, badge, first-run pin reminder, auto-refresh. -- **Toolbar badge**: actionable count, or a `•` idle indicator (Binect blue). -- **Tracking / Help page** (`src/tracking/`): summary counts, chronological transfer list, accessible via the popup "?" link. +## Relevant When -### 2.6 Local Tracking & Feedback (`src/tracking/tracker.ts`) +- You want to send a PDF from any web app to Binect for physical mail without a manual download/upload round-trip. +- You need a browser-only, backend-free path to Binect with no document content leaving the user's control. +- You want to track documents through the Binect lifecycle (basket → order → production → sent) from the toolbar. -- Append-only transfer log (`TrackingEntry`): timestamp, source, destination, filesize, result/error class; **local-only**, capped at ~500 events. -- `getTrackingSummary` for counts; `exportAsCSV` for export. -- Feedback opens an email draft to `bernd.worsch@binect.de`; tracking data exportable as CSV (body / clipboard). +--- -### 2.7 Service Worker & Platform (`src/background/service-worker.ts`, `public/manifest.json`) +## Not Relevant When -- Manifest V3 service worker; message router for all popup ↔ background calls. -- `chrome.alarms` for credential-expiry and queue-cleanup ticks (survives worker suspension). -- Permissions requested: `downloads`, `storage`, `alarms`, `activeTab`; host access to `https://api.binect.de/*` and ``. +- You need server-side queueing, persistence, or automated/scheduled sending. +- You need a non-Chrome browser (Firefox/Edge) — Chromium MV3 only in v1. +- You need to create, render, or edit the PDF itself — that is the source app's job. +- You are integrating Binect from Node or a non-browser context — use [`@binect/js`](../binect-js) directly. -### 2.8 Supporting Material +--- -- Tests (`tests/`): Jest unit tests for crypto, pdf-detector, binect-api, tracker (`@binect/js` mocked). -- Build: TypeScript + Webpack (`npm run build` → `dist/`); ESLint; `tsc` type-check. -- Docs: [`CLAUDE.md`](CLAUDE.md), [`README.md`](README.md), `DEVELOPMENT.md`, `architecture/ADR-001-credential-encryption.md`, detection/testing guides. +## Current State -## 3. Out of Scope +- Status: active +- Implementation: substantial — detection, lifecycle queue, API ops, credentials, UI, and tracking all built +- Stability: evolving — pre-Chrome-Web-Store; `` host permission is a known review cost +- Usage: internal / pre-release -Excluded by design. A request requiring any of these is a request for a *different* product (see [`INTENT.md` §5](INTENT.md)). +--- -| Excluded | Reason | -|----------|--------| -| Storing, viewing, editing, or inspecting PDF content | Zero-retention principle; proxies hold metadata only. | -| Any server-side / backend component | The extension talks directly to Binect; no relay, no install-tied state. | -| Automatic or background sending, ordering, or deleting | Every dispatch action requires explicit user intent; mail costs money and is irreversible. | -| PDF generation, layout, or transformation | The user brings a finished PDF; document prep is the source app's job. | -| Reinterpreting or extending the Binect API | API behavior is delegated 1:1 to `@binect/js`; new coverage belongs upstream. | -| Cross-browser support (Firefox, Edge, …) | Chrome / Chromium MV3 only in v1. | -| Credential federation, SSO, token auth | Username + password only, until the API evolves. | -| Telemetry / analytics / remote logging | Tracking is local; data leaves only via explicit user feedback email. | -| Multi-profile destinations, rule-based automation, org policies | Listed as future considerations in the PRD §10, not built. | +## How It Fits -## 4. Boundary Cases & Known Edges +- Upstream dependencies: the Binect REST API (third-party service; see `tpsc.yaml`) and the [`@binect/js`](../binect-js) SDK (local `file:` dependency — sibling repo must be present to build). +- Downstream consumers: end users (the published Chrome extension). +- Often used with: cloud apps that produce PDFs (the detection source). -- **Uploaded ≠ sent.** Uploading places a document in the Binect *basket* (shippable). Physical dispatch is a separate, explicitly confirmed "order" step. Conflating the two would violate the explicit-intent principle. -- **`` host permission.** Required so the extension can re-fetch PDFs from arbitrary source domains using the user's session. It is broader than the "minimal permissions" the PRD/INTENT aspire to and is a known **Chrome Web Store review cost** — it should be justified in the store listing or narrowed, not silently expanded. -- **Content hash is a fast non-cryptographic digest** (`computeContentFingerprint`, `src/utils/hash.ts`) — a sampled rolling fingerprint used only for deduplication, never for security. -- **Two capped stores, not one.** Lifecycle *proxies* (~100, ~30-day archive aging) are distinct from the transfer *log* (~500 events). See PRD §4.6.3. -- **`@binect/js` is a local file dependency** (`file:../binect-js`). The sibling repo must be present to build; it is not yet published to a registry. -- **Service-worker lifecycle.** All state persists in `chrome.storage.local`; nothing relies on in-memory background state surviving suspension. +--- -## 5. Scope Change Process +## Terminology -1. Confirm the change violates no principle in [`INTENT.md` §4](INTENT.md) — especially zero-retention, explicit intent, no backend. -2. If it adds Binect API coverage, add it upstream in `@binect/js` and surface it through the thin wrapper — do not reimplement API logic here. -3. If it expands permissions, document the justification (review impact) before adding. -4. Update this file and, where the boundary genuinely moves, [`INTENT.md`](INTENT.md) and the [PRD](specs/ProductRequirementsDocument.md) together. +- Preferred terms: **proxy** (metadata-only record of a detected/sent PDF), **basket** (Binect shippable state), **order** (the explicit dispatch step), **transfer log** (local tracking). +- Also known as: "score" for the local tracking view. +- Potentially confusing terms: *uploaded ≠ sent* — upload places a document in the basket; physical dispatch is a separate confirmed order. `computeMD5` is a sampled non-cryptographic dedup hash, not true MD5. -## 6. Related Documents +--- -- [`INTENT.md`](INTENT.md) — why the project exists and its inviolable principles -- [`specs/ProductRequirementsDocument.md`](specs/ProductRequirementsDocument.md) — full PRD (reconciled with the lifecycle scope) -- [`architecture/ADR-001-credential-encryption.md`](architecture/ADR-001-credential-encryption.md) — credential encryption decision -- [`CLAUDE.md`](CLAUDE.md) — architecture and contributor instructions -- [`README.md`](README.md) — usage and developer setup +## Related / Overlapping + +- `binect-js` — the SDK this extension consumes for all Binect API access; API coverage belongs there, not here. +- `email-connect` — adjacent communication-domain delivery channel (email vs. physical mail); no code overlap. + +--- + +## Getting Oriented + +- Start with: [`INTENT.md`](INTENT.md), then [`README.md`](README.md) and `DEVELOPMENT.md`. +- Key files / directories: `src/utils/pdf-detector.ts`, `src/utils/pdf-queue.ts`, `src/utils/binect-api.ts`, `src/utils/crypto.ts`, `src/popup/`, `src/tracking/`, `src/background/service-worker.ts`, `public/manifest.json`. +- Entry points: the MV3 service worker (`src/background/service-worker.ts`) and the popup (`src/popup/`). + +--- + +## Provided Capabilities + +```capability +type: api +title: Browser PDF-to-physical-mail (BinectChrome extension) +description: Chrome MV3 extension that detects PDFs in the browser and sends them to Binect for physical mail, tracking each document through its lifecycle. Backend-free, zero document retention. +keywords: [chrome-extension, mv3, binect, physical-mail, pdf, browser, zero-retention] +``` + +```capability +type: security +title: Encrypted at-rest browser credential store +description: AES-GCM (256-bit) Web Crypto credential storage with 60-day inactivity expiry and manual wipe, for authenticating browser-side calls to a third-party API without a backend. +keywords: [aes-gcm, web-crypto, credentials, chrome-storage, basic-auth] +``` + +--- + +## Notes + +- Uploaded ≠ sent: dispatch is a separate, explicitly confirmed order step. +- `` host permission is required to re-fetch PDFs from arbitrary source domains using the user's session; it is a known Chrome Web Store review cost and should be justified or narrowed, not silently expanded. +- Two capped stores: lifecycle proxies (~100, ~30-day archive aging) are distinct from the transfer log (~500 events). +- Scope-change process: confirm against [`INTENT.md` §4](INTENT.md) (zero-retention, explicit intent, no backend); add Binect API coverage upstream in `@binect/js`; document any permission expansion before adding. diff --git a/tpsc.yaml b/tpsc.yaml new file mode 100644 index 0000000..019d88c --- /dev/null +++ b/tpsc.yaml @@ -0,0 +1,9 @@ +# tpsc.yaml — Third-Party Services Catalog declarations for binect-chrome +# Each entry references a service slug from the central catalog at: +# the-custodian/canon/tpsc/.yaml +# Ingest: cd state-hub && make ingest-tpsc REPO=binect-chrome + +services: + - slug: binect-api + purpose: Binect REST API — upload PDFs, place orders, and track document lifecycle for physical mail via Deutsche Post (accessed through the @binect/js SDK). + auth: basic_auth