diff --git a/.gitignore b/.gitignore index c108600..a4e70bf 100644 --- a/.gitignore +++ b/.gitignore @@ -60,6 +60,9 @@ coverage.xml # Unleashed session transcripts (auto-generated, untracked) data/unleashed/ +# Unleashed wrapper config — local/machine-specific, never in a public repo +.unleashed.json + # Silphe recordings — local biometric movement data, never published recordings/ **/recordings/ diff --git a/.unleashed.json b/.unleashed.json deleted file mode 100644 index cbc3f4c..0000000 --- a/.unleashed.json +++ /dev/null @@ -1,13 +0,0 @@ -{ - "profile": "default", - "claude": { - "model": "claude-opus-4-7[1M]", - "effort": "max" - }, - "assemblyZero": true, - "onboard": { - "auto": true, - "guide": null, - "plan": null - } -} diff --git a/docs/00003-file-inventory.md b/docs/00003-file-inventory.md deleted file mode 100644 index ee9421b..0000000 --- a/docs/00003-file-inventory.md +++ /dev/null @@ -1,94 +0,0 @@ -# 00003 - silphe File Inventory - -**Status:** Active -**Created:** 2026-06-11 -**Last Updated:** 2026-06-11 - ---- - -## Purpose - -This document provides a complete inventory of files in the silphe project, organized by directory. It serves as a quick reference for agents and developers to understand the project structure. - ---- - -## Directory Structure - -``` -silphe/ -├── .claude/ # Claude Code configuration -├── data/ # Ephemeral data (git-ignored fleet-wide) -├── data-g/ # Git-tracked source-of-truth data (see data-g/README.md) -├── docs/ # All documentation -│ ├── adrs/ # Architecture Decision Records -│ ├── standards/ # Project-specific standards -│ ├── templates/ # Document templates -│ ├── lld/ # Low-Level Designs -│ │ ├── active/ # In-progress LLDs -│ │ └── done/ # Completed LLDs -│ ├── reports/ # Implementation & test reports -│ │ ├── active/ # In-progress reports -│ │ └── done/ # Completed reports -│ ├── runbooks/ # Operational procedures -│ ├── session-logs/ # Agent session context -│ ├── audit-results/ # Historical audit outputs -│ ├── media/ # Artwork, videos, tutorials -│ ├── legal/ # ToS, privacy policy, regulatory -│ └── design/ # UI mockups, style guides -├── src/ # Application source code -├── tests/ # Test suites -│ ├── unit/ # Fast, isolated tests -│ ├── integration/ # Multiple components together -│ ├── e2e/ # End-to-end tests -│ ├── smoke/ # Quick sanity/environment tests -│ ├── contract/ # API contract tests -│ ├── visual/ # Visual regression tests -│ ├── benchmark/ # Performance tests -│ ├── security/ # Security tests -│ ├── accessibility/ # Accessibility tests -│ ├── compliance/ # Compliance tests -│ ├── fixtures/ # Test data -│ └── harness/ # Test utilities -├── tools/ # Development utilities -├── CLAUDE.md # Claude agent instructions -├── GEMINI.md # Gemini agent instructions -├── README.md # Project overview -├── LICENSE # PolyForm Noncommercial 1.0.0 -├── .gitignore # Git ignore rules -└── .unleashed.json # Unleashed wrapper config (model, effort) -``` - ---- - -## Key Files - -| File | Purpose | -|------|---------| -| `CLAUDE.md` | Instructions for Claude agents working on this project | -| `GEMINI.md` | Instructions for Gemini agents working on this project | -| `README.md` | Project overview and quick start guide | -| `.claude/project.json` | Project variables for AssemblyZero template generation | - ---- - -## Documentation Numbering - -This project uses the AssemblyZero numbering scheme: - -| Range | Category | Location | -|-------|----------|----------| -| `0xxxx` | Foundational (ADRs, standards) | `docs/adrs/`, `docs/standards/` | -| `1xxxx` | Issue-specific (LLDs, reports) | `docs/lld/`, `docs/reports/` | -| `3xxxx` | Runbooks | `docs/runbooks/` | -| `4xxxx` | Media | `docs/media/` | - ---- - -## Maintenance - -This inventory should be updated when: -- New directories are added -- Significant new files are created -- Project structure changes - -Use `/audit` to verify structure compliance with AssemblyZero standards. diff --git a/docs/0004-pypi-publish.md b/docs/0004-pypi-publish.md index 65c9ea1..04afda4 100644 --- a/docs/0004-pypi-publish.md +++ b/docs/0004-pypi-publish.md @@ -1,81 +1,50 @@ # Publishing Silphe to PyPI (and actually reserving the name) -Silphe publishes via **OIDC Trusted Publishing**: GitHub Actions mints a -short-lived token and PyPI trusts it. **No API token is stored anywhere.** - -This is the silphe-specific version of AssemblyZero runbook -`0934-pypi-trusted-publisher-setup.md`, with two corrections that runbook still -needs (tracked in AssemblyZero #1582 and #1583). +The **first** release is uploaded manually with `twine` — that's what reserves +the name. **Automated OIDC tag-push publishing comes later**, once the release +workflow lands (currently blocked on a PAT scope issue, tracked in #6). ## The one thing everyone gets wrong -> **Registering a "pending publisher" does NOT reserve the name.** +> **Nothing reserves a PyPI name except publishing an actual release.** -PyPI's own docs: +Registering a Trusted-Publisher "pending publisher" reserves *nothing* — PyPI's +own docs say so: > "A 'pending' publisher does not create a project or reserve a project's name -> until it is actually used to publish. If you create a 'pending' publisher but -> another user registers the project name before you actually publish to it, -> your 'pending' publisher will be invalidated." +> until it is actually used to publish." > > — -**The only action that reserves `silphe` is publishing a real release.** Until -the first `v*.*.*` tag publishes successfully, the name is free for anyone to -take — and if they take it, your pending publisher silently invalidates. +So `silphe` is unclaimed until the upload below succeeds. -## Credentials — what you actually need +## Credentials — what you need - **PyPI has no "Sign in with GitHub."** Account login is username/email + - password + **2FA** (authenticator app or passkey) + recovery codes. It's in - your password manager from a prior project's setup — reuse that account. -- The GitHub connection in Step 1 is only the OIDC *publish* trust, never login. -- **You need zero API token** for this path. Nothing to generate or store. - -## Pre-flight (done by the library PR) - -- [x] `pyproject.toml` → `[project] name = "silphe"`, `version = "0.1.0"` -- [x] `.github/workflows/release.yml` present, `environment: pypi`, tag `v*.*.*` -- [x] `poetry build` produces a wheel + sdist -- [x] Library PR merged to `main` - -## Step 1 — Register the pending publisher (browser, ~2 min) - -1. Log in at (your existing account). -2. Under **"Add a new pending publisher,"** fill in exactly: - - | Field | Value | - |---|---| - | PyPI Project Name | `silphe` | - | Owner | `martymcenroe` | - | Repository name | `silphe` | - | Workflow filename | `release.yml` | - | Environment name | `pypi` | - -3. Click **Add**. This configures trust. It does **not** yet reserve the name — - Step 2 does. - -## Step 2 — Publish (the tag push that reserves the name) + password + **2FA** (authenticator app or passkey) + recovery codes — in your + password manager from a prior project. Reuse that account; don't make a second. +- For this manual first upload you need a **PyPI API token**: create one at + ("Entire account" scope works for the + first upload, since the project doesn't exist yet). It looks like `pypi-…`. +- **Secret hygiene:** paste the token at twine's password prompt — do **not** put + it in the command, an env var, or anywhere shell history captures it. Delete or + re-scope the token after the first upload. -From `main`, with the tag matching `pyproject.toml`'s version: +## Reserve the name — first release (you run this) ```bash -git tag v0.1.0 -git push origin v0.1.0 +cd /c/Users/mcwiz/Projects/silphe +poetry build # fresh wheel + sdist in dist/ +python -m pip install --upgrade twine +twine upload dist/* +# username: __token__ +# password: ``` -Watch it: +On success the release is live at and +**the name is now reserved.** -```bash -gh run watch --repo martymcenroe/silphe -``` - -The workflow builds the distributions and publishes via OIDC. On success the -release is live at within seconds, the -name is **now reserved**, and the pending publisher promotes to a permanent -trusted publisher. - -## Step 3 — Verify +## Verify ```bash pip install silphe @@ -83,26 +52,33 @@ python -c "import silphe; print(silphe.__version__)" # 0.1.0 silphe-analyze # entry point resolves ``` -## Subsequent releases +Then: clear your clipboard, and delete or project-scope the API token. -Bump the version, tag, push the tag. No browser steps ever again. +## Future releases — switch to OIDC (no token, ever) -```bash -poetry version patch -git commit -am "chore: bump to $(poetry version -s)" -git tag "v$(poetry version -s)" -git push origin main "v$(poetry version -s)" -``` +Once the release workflow lands (#6): + +1. On the now-existing PyPI project → **Manage → Publishing → Add a trusted + publisher**: owner `martymcenroe`, repo `silphe`, workflow `release.yml`, + environment `pypi`. +2. From then on every release is just a tag push — no token, no browser: + + ```bash + poetry version patch + git commit -am "chore: bump to $(poetry version -s)" + git tag "v$(poetry version -s)" + git push origin main "v$(poetry version -s)" + ``` ## If it fails | Symptom | Cause | Fix | |---|---|---| -| `Trusted publisher not found` | Step 1 not done, or a field mismatched | Re-check owner / repo / `release.yml` / `pypi` match exactly | -| `Project name is not available` | Someone else already took `silphe` | The name is gone; choose another in `pyproject.toml` and re-register | -| Workflow never starts | Tag isn't `v*.*.*` | `v0.1.0` matches; `0.1.0` does not | +| `403 Forbidden` on upload | Bad/expired token, or wrong username | Username must be `__token__`; regenerate the token | +| `Project name is not available` | Someone else already took `silphe` | The name is gone; pick another in `pyproject.toml` | +| `File already exists` | That version was already uploaded | Bump the version; PyPI never lets you re-upload a version | ## References -- AssemblyZero `0934-pypi-trusted-publisher-setup.md` — the fleet runbook (corrections tracked in AZ #1582, #1583) +- AssemblyZero `0934-pypi-trusted-publisher-setup.md` — the fleet OIDC runbook (corrections tracked in AZ #1582, #1583) - PyPI Trusted Publishers — diff --git a/src/silphe/arc.py b/src/silphe/arc.py index 7bf5ca3..6a0ac17 100644 --- a/src/silphe/arc.py +++ b/src/silphe/arc.py @@ -1,7 +1,7 @@ """ arc.py — the longitudinal "arc" view: your movement signature over time. -Reads every session in recordings/ and plots your cognitive fingerprint drifting +Reads every session in recordings/ and plots your movement signature drifting over time: reaction, accuracy, speed, tracking, tremor — one point per session, with a trend (improving / declining) once there's more than one. Plus a "tonight, round by round" strip so there's a real line on night one.