Skip to content

Commit 2a60f86

Browse files
authored
Merge pull request #165 from FreeshardBase/fix/clayde/config-docs-hygiene
Config & docs hygiene sweep: remove dead config and fix misleading docs
2 parents 1e601a3 + 8443eac commit 2a60f86

17 files changed

Lines changed: 81 additions & 109 deletions

File tree

.claude/skills/freeshard-architecture-contract/SKILL.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -69,8 +69,8 @@ endpoint, new mutating internal route), flag it in the PR.
6969

7070
## 2. Identity and session crypto
7171

72-
**The signing scheme is RSA, not Ed25519.** agents.md claims Ed25519 — that is wrong;
73-
do not propagate it.
72+
**The signing scheme is RSA, not Ed25519.** agents.md claimed Ed25519 until issue #128
73+
corrected it; if you meet that claim anywhere else, the code wins.
7474

7575
- Keys: RSA-4096, exponent 65537 (shard_core/service/crypto.py:52-57). Raw sign/verify uses PSS padding with MGF1(SHA256)+SHA256 (crypto.py:34-46,79-86).
7676
- Identity id = human-encoded SHA512 of the public key PEM (crypto.py:29-32). The encoding is 5-bits-per-char over the 32-char alphabet `abcdefghjklnpqrstvwxyz0123456789` (shard_core/service/human_encoding.py:102), giving a **103-char id** (512 bits / 5, zero-padded — verified by computation; some docs say 96, that is wrong).

.claude/skills/freeshard-build-and-env/SKILL.md

Lines changed: 4 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -101,8 +101,8 @@ Verified against `justfile` as of 2026-07-03. `just` (no args) lists recipes.
101101

102102
| Recipe | What it actually does | Gotchas |
103103
|---|---|---|
104-
| `just run-dev` | `fastapi dev --port 8080 shard_core/app.py` via `.venv/bin/fastapi`, with `PYTHONUNBUFFERED=1` | The `CONFIG=config.yml,local_config.yml` it also sets is **dead** — nothing reads `CONFIG`, and those `.yml` files don't exist (real files are `.toml`, picked up by settings.py automatically). Usage details: freeshard-run-and-operate. |
105-
| `just run-dev-for-freeshard-controller` | second dev instance on port 8081, *intended* to point at a local controller on 8080 | Dead-CONFIG caveat PLUS the `FREESHARD_FREESHARD_CONTROLLER_BASE_URL` var it sets is single-underscore-broken (inert) — the instance actually talks to the **production** controller. Working form: `FREESHARD_FREESHARD_CONTROLLER__BASE_URL`. See freeshard-config-and-flags. |
104+
| `just run-dev` | `fastapi dev --port 8080 shard_core/app.py` via `.venv/bin/fastapi`, with `PYTHONUNBUFFERED=1` | Config comes from `config.toml` plus `local_config.toml` if present, picked up by settings.py automatically. Usage details: freeshard-run-and-operate. |
105+
| `just run-dev-for-freeshard-controller` | second dev instance on port 8081, *intended* to point at a local controller on 8080 | Sets `FREESHARD_FREESHARD_CONTROLLER__BASE_URL=http://127.0.0.1:8080`. Until issue #128 this was a single underscore, which pydantic-settings silently ignored — the instance talked to the **production** controller. See freeshard-config-and-flags. |
106106
| `just cleanup` | `ruff check . --fix` then `black shard_core` and `black tests` | **Run after every code change** — it is the house formatting gate. Requires the dev extra installed (black is transitive). |
107107
| `just get-types` | **DESTRUCTIVE**: `rm -rf shard_core/data_model/backend`, then `cp -r` from the **LOCAL** sibling checkout `../freeshard-controller/freeshard-controller-backend/freeshard_controller/data_model`, prepending `# DO NOT MODIFY` to every file | Syncs from whatever your local controller checkout happens to be at. **You MUST `git -C ../freeshard-controller checkout main && git -C ../freeshard-controller pull` first.** A stale checkout has caused real bugs before (silently dropped billing fields — commits 6d4b101, e55ce51). As of 2026-07-03 the local controller checkout on the dev VM was verified BEHIND origin/main. Full procedure and drift checks: freeshard-ecosystem-contracts. |
108108
| `just set-version X.Y.Z` | rewrites `version` in pyproject.toml and the `ghcr.io/freeshardbase/freeshard:` tag in docker-compose.yml, then **`git add .` and `git commit`** | It stages EVERYTHING (`git add .`) — never run with a dirty tree. Release procedure: freeshard-change-control / freeshard-run-and-operate. |
@@ -134,18 +134,16 @@ uv run pytest tests # CI test job (needs Docker + internet)
134134

135135
`uv sync` without `--frozen` will also *update* uv.lock if pyproject.toml changed — fine during development, but a lockfile diff you didn't intend belongs out of your PR.
136136

137-
Two workflow variables are dead but still present (do not cargo-cult them): `TEST_ENV=full/sparse` (its consumer was removed; push and PR runs are identical) and `CONFIG=tests/config.yml` (nothing reads `CONFIG`; the file doesn't even exist).
137+
One workflow variable is dead but still present (do not cargo-cult it): `TEST_ENV=full/sparse` its consumer was removed, so push and PR runs are identical. A companion dead `CONFIG=tests/config.yml` was removed by issue #128.
138138

139139
## Known traps
140140

141141
| Trap | Reality | Evidence |
142142
|---|---|---|
143-
| `CONFIG` env var looks load-bearing | It is dead — justfile, CI, tests, and the README all set it; nothing reads it (config is hardcoded: `config.toml` + `local_config.toml` if present + `FREESHARD_*` env). Full evidence and history: freeshard-config-and-flags. | `grep -rn '"CONFIG"' shard_core/` → no hits |
144143
| `local_config.toml` silently not applied | It is resolved via `Path("local_config.toml").exists()`**relative to CWD**. Run the server/tests from the repo (or worktree) root, or your dev overlay (path_root=`run/`, dns.zone=localhost) vanishes and the app tries production paths. Also listed in `.dockerignore`, so it can never leak into the image — don't try to configure the container with it. | settings.py:148-152; .dockerignore |
145144
| Tests "just need pytest" | They need a running Docker daemon, compose v2, and internet: a session fixture does a **real `docker login`** to `portalapps.azurecr.io` using credentials committed in `config.toml:30-33`, and app-installation tests really pull images from that registry. If those credentials are ever rotated, api_client-based tests fail on pulls — that is an infra failure, not your bug. | tests/conftest.py:129-131 |
146145
| Concurrent test runs collide | tests/docker-compose.yml pins host port **5433** and conftest pins compose project name **`shard-core-test`**. Two worktrees running pytest simultaneously fight over both. Run suites serially across worktrees. | tests/docker-compose.yml:9; tests/conftest.py:96-98 |
147146
| Docker network `portal` and container names are host-global | The production compose stack, a locally running dev shard, and the test suite all use the network name `portal` and fixed container names (`postgres`, `traefik`, `shard_core`, app names like `filebrowser`). Test teardown force-removes the `portal` network — it will rip it out from under a dev shard running on the same host. | docker-compose.yml:1-3; tests/util.py:139-147 |
148-
| agents.md crypto claim | agents.md says Ed25519. The code is **RSA-4096 with PSS padding** (`shard_core/service/crypto.py`), and HTTP Message Signatures use `RSA_PSS_SHA512` (`shard_core/service/signed_call.py:27`). Trust the code. | crypto.py:54-56; signed_call.py:27 |
149147
| `scripts/generate_traefik_dyn_config_model.py` | Raises `Exception("Do no use! ...")` at import, deliberately: its output model was hand-patched (`authResponseHeadersRegex`) and regenerating would drop that field. Do not "fix" the script. | scripts/generate_traefik_dyn_config_model.py |
150148
| Leftover test infra after a crash | A killed pytest run leaves the test postgres and/or `portal` network behind; the next run fails on port/name conflicts. | Cleanup: `docker compose -p shard-core-test -f tests/docker-compose.yml down -v` and `docker network rm portal` |
151149

@@ -196,11 +194,10 @@ Drift-prone facts — re-verify before trusting:
196194
| Version 0.39.2 / image tag in compose | `grep '^version' pyproject.toml && grep 'freeshardbase/freeshard:' docker-compose.yml` |
197195
| 137 tests collected (origin/main; 134 at e55ce51) | `.venv/bin/pytest tests --collect-only -q \| tail -1` |
198196
| CI installs via `uv sync --frozen --extra dev` | `git fetch origin && git show origin/main:.github/workflows/test.yml \| grep -A3 'Install dependencies'` |
199-
| `CONFIG` env var still dead | `grep -rn '"CONFIG"' shard_core/` (expect no hits) |
200197
| dev extra contents / black still transitive | `grep -A12 'dev = \[' pyproject.toml` |
201198
| Test postgres port 5433 / project `shard-core-test` | `grep 5433 tests/docker-compose.yml && grep -n 'shard-core-test' tests/conftest.py` |
202199
| ACR creds still committed & logged into | `grep -n 'azurecr' config.toml && grep -n 'login_docker_registries' tests/conftest.py shard_core/service/app_installation/__init__.py` |
203200
| Local controller checkout current before get-types | `git -C ../freeshard-controller rev-parse HEAD && git -C ../freeshard-controller ls-remote origin main` (hashes must match) |
204201
| `.worktrees/` excluded locally | `grep worktrees .git/info/exclude` |
205-
| Crypto still RSA-4096/PSS, not Ed25519 | `grep -n 'generate_private_key\|key_size\|RSA_PSS' shard_core/service/crypto.py shard_core/service/signed_call.py` |
202+
| Crypto still RSA-4096/PSS | `grep -n 'generate_private_key\|key_size\|RSA_PSS' shard_core/service/crypto.py shard_core/service/signed_call.py` |
206203
| tini/docker/rclone still in runtime image | `grep -n 'tini\|get.docker.com\|rclone' Dockerfile` |

0 commit comments

Comments
 (0)