mirror of
https://github.com/PR0M3TH3AN/SeedPass.git
synced 2026-10-28 00:12:04 +00:00
I expected the 35 remaining findings to need a VaultIndex remodel. They did not. `vaultIndexSchema` and every entry schema are `.loose()`, which already gives both types an index signature — so `index["_system"]`, `entry["label"]` and assignment to `Record<string, unknown>` all compile with no cast at all. I checked before rewriting anything, and the answer was that 38 of the 44 were simply redundant, copied from each other rather than needed. That is the linter's real value here: it did not find a design flaw, it made me test an assumption I would otherwise have acted on. The remodel would have been work done to satisfy a belief that was false. Removing them let the compiler see three things the casts had been hiding: - `nextTotpIndex` filtered on `type === "totp" || kind === "totp"`, and TS reported the second half as unreachable. It is: withKind() populates kind from type at parse time and the union is discriminated on kind, so the fallback could never fire. Now filters on the discriminant alone. - `ensureIndex0Payload` always ran normalizeIndex0 and then returned `Dict`, throwing the guarantee away, so all three callers asserted it back with `as unknown as Index0`. It now returns an `Index0Payload` that carries what the function established, built in that shape rather than asserted into it, and the type propagates through compactIndex0Payload and rebuildCanonicalViewsPayload. - `sign()` in recoveryDrills declared a DrillRecord parameter it never used as one — it HMACs a canonical serialization — which forced the verifier to assert a shape it had not established while checking a signature. Also `rebuildIndex0Checkpoints` typed to the one field it reads, and console.ts asking `"isTTY" in this.out` rather than asserting a shape onto a WritableStream. One assertion remains, in entrySchema, and it is structural rather than evidential: z.preprocess types its output from an inner union deliberately wider than Entry, and no zod spelling expresses "parses to a superset, hands back the narrow type". Disabled inline with that written down. 44 -> 0. The lint step is now in ci_prepush.sh, and the gate runs green in 44.5 seconds. 689 tests still pass. Co-Authored-By: Claude Opus 5 (1M context) <[email protected]> Claude-Session: https://claude.ai/code/session_01Vtx94nXDmNgXEeThUZP4QN
73 lines
2.5 KiB
Bash
Executable File
73 lines
2.5 KiB
Bash
Executable File
#!/usr/bin/env bash
|
|
# The gate that runs before every push. Target: well under a minute.
|
|
#
|
|
# WHAT IS IN HERE AND WHY THAT LIST
|
|
#
|
|
# The budget is the design constraint, not an afterthought. A hook that takes
|
|
# minutes becomes `git push --no-verify` within a week, at which point it is a
|
|
# ceremonial control that everyone believes in and nobody runs. So this holds
|
|
# only checks that are cheap AND catch things CI would otherwise catch late.
|
|
#
|
|
# Measured on this machine, 2026-08-20:
|
|
#
|
|
# preflight 2.6s
|
|
# poetry check --lock 0.6s
|
|
# black --check 2.5s
|
|
# oxlint 0.9s
|
|
# tsc --noEmit (workspace) 7.3s
|
|
# pytest determinism subset 5.4s
|
|
# vitest core (node) 24.0s
|
|
# -----
|
|
# ~44s
|
|
#
|
|
# What is deliberately NOT here:
|
|
#
|
|
# vitest cli 176.3s <- alone, three times the budget
|
|
# pytest (full) ~350s
|
|
# cross-impl, fuzz, packaging smoke
|
|
#
|
|
# Those live in ci_parity.sh, which is what you run before calling a branch
|
|
# ready rather than before every push. The cli suite is slow for a good
|
|
# reason -- it spawns real daemons, real sockets and real subprocesses rather
|
|
# than mocking them -- and that is worth keeping, not worth waiting on twenty
|
|
# times a day.
|
|
#
|
|
# EVERY TOOL IS INVOKED THROUGH THE REPOSITORY ENVIRONMENT. `poetry run ...`
|
|
# and `pnpm -C js ...`, never a bare `black` or `vitest` off PATH. That rule is
|
|
# the whole reason preflight runs first: a bare tool name is how a local gate
|
|
# ends up passing while CI fails.
|
|
set -euo pipefail
|
|
cd "$(dirname "$0")/.."
|
|
|
|
step() { printf "\n\033[1m==> %s\033[0m\n" "$1"; }
|
|
|
|
step "preflight: does this machine agree with the lockfiles?"
|
|
python3 scripts/ci_preflight.py
|
|
|
|
step "python: lockfile consistency"
|
|
poetry check --lock
|
|
|
|
step "python: formatting (the pinned black, not whatever is on PATH)"
|
|
poetry run black --check .
|
|
|
|
step "javascript: lint"
|
|
pnpm -C js lint
|
|
|
|
step "javascript: typecheck"
|
|
pnpm -C js typecheck
|
|
|
|
step "javascript: core tests"
|
|
pnpm -C js --filter @seedpass/core test:node
|
|
|
|
step "python: deterministic artifact regression"
|
|
poetry run pytest -q src/tests/test_deterministic_artifact_regression.py
|
|
|
|
if command -v actionlint >/dev/null 2>&1; then
|
|
step "workflows: actionlint"
|
|
actionlint
|
|
else
|
|
printf "\n\033[2m(actionlint not installed — skipping workflow lint)\033[0m\n"
|
|
fi
|
|
|
|
printf "\n\033[32mci:prepush passed.\033[0m Run ./scripts/ci_parity.sh before calling a branch ready.\n"
|