docs: record current state of the TypeScript port

Cutover plan gains a session log for 2026-08-15 and an honest status row:
every listed gate is green, and the remaining blocker is that no third party
has reviewed the code. Two rounds of subagent review found nine
criticals/highs that self-review missed, which is why that is treated as
load-bearing rather than optional.

Compatibility matrix gains rows for seed generation -- absent until this
session, so a new user could not create a vault at all -- and for the
interactive mode now that it follows Python's legacy v1 menus.

The exclusion lists in both documents now name TUI v2/v3, QR display and
script checksums, rather than leaving the earlier 'no TUI' claim standing.

Co-Authored-By: Claude Fable 5 <[email protected]>
This commit is contained in:
thePR0M3TH3ANandClaude Fable 5 committed 2026-08-15 18:05:12 -04:00
1 parent dce30d669a
commit 363d0edffd
2 files changed
+73 -5

No files matched your search

+71 -5
View File
@@ -17,9 +17,16 @@ P0 gate is green, Python remains the normative reference
| Cross-implementation profile interop | green |
| Sync protocol parity | green |
| Agent security model | green (TS ahead of Python) |
| Feature parity for daily use | green for daily use; 3 scoped exclusions |
| Feature parity for daily use | green for daily use; scoped exclusions below |
| Interactive mode (TUI) | green — legacy (v1) menu tree ported |
| Packaging + release | green |
| Migration + rollback story | green |
| Independent security review | **not done — the one open blocker** |
The gates below are green. The remaining blocker is not a gate in this list:
no third party has reviewed the code. Two rounds of subagent review found 9
criticals/highs between them that self-review missed entirely, which is the
evidence for treating that as load-bearing rather than optional.
## P0 gates (must be green to cut over)
@@ -47,15 +54,20 @@ P0 gate is green, Python remains the normative reference
and the TS CLI restores it with secrets intact. **Green.**
5. **Feature parity for real daily use.** **Green for daily use**, with
three scoped exclusions that are documented rather than hidden:
scoped exclusions that are documented rather than hidden:
- **PGP RSA keys** — unsupported by design. PyCryptodome's seeded prime
search is not reproducible, so TS refuses the key type instead of
deriving a different key. ed25519 PGP is at byte-for-byte parity.
- **`semantic`** (local vector search) — a derived index that can be
rebuilt; plan §8.5 rates it P2.
- **`api`** (FastAPI server) — a separate surface, not vault behavior.
- **TUI v2/v3** — interactive mode ports the legacy (v1) menu tree only.
- **QR display in the TUI** — no QR encoder in this build; the menu item
remains and offers the underlying value instead.
- **Script checksum verify/generate** — covers the Python source tree;
replaced by the release bundle's `.sha256`.
Recommendation: none of the three blocks cutover. Each is a bounded,
Recommendation: none of these blocks cutover. Each is a bounded,
named gap with the Python implementation still available for it, and the
migration guide tells users exactly that. Revisit if a real profile is
found to depend on RSA PGP entries.
@@ -93,8 +105,12 @@ P0 gate is green, Python remains the normative reference
- `_system.index0` / atlas content merge — Python-derived state, recomputed
on load; TS deliberately does not emit it and refuses to merge populated
index0 rather than corrupt it.
- TUI v2/v3 — the plan explicitly does not port these; terminal UX is the
CLI plus any future interactive mode.
- TUI v2/v3 — not ported. Interactive mode (`seedpass-js` with no
subcommand) reproduces the **legacy v1** menu tree instead: the same eight
main-menu items, nine entry types, eighteen settings under the same
numbers, and the Profiles/Nostr/entry-action/edit submenus. Items this
build cannot perform keep their position and say why, so the numbering
Python users have memorised still selects the same thing.
## Cutover mechanics (once gates are green)
@@ -114,3 +130,53 @@ The Python implementation stays in the repository and in CI as the
compatibility oracle, not as a shipped product. If a future change makes the
two diverge, the cross-impl suite fails and the change is wrong until proven
otherwise.
## Session log — 2026-08-15
Everything below was found by *running* the CLI, not by the 348-test suite.
That ratio is the most useful thing this session produced: keep exercising
the product by hand.
**Parity gap closed: there was no way to create a vault.** Every path assumed
an existing seed and told the user to export `SEEDPASS_MNEMONIC`, so a new
user could not start at all. `fingerprint create` now generates one the way
Python does (32 bytes of OS entropy through BIP-85 app 39 index 0, with the
entropy call outside any try/catch so a CSPRNG failure can never be caught
and substituted). Delivery of the phrase is chosen *before* generation and
happens *before* the profile is created, so no failure can leave a vault
whose seed nobody holds; `--out` is 0600 + O_EXCL; a non-TTY stdout with no
destination refuses outright rather than writing the only copy of a seed
into a pipe.
**Interactive mode added, then rebuilt.** The first version was list-and-
arrow-keys and was unnavigable to someone who knows SeedPass; the second
follows Python's legacy v1 menus item for item. Recorded because the lesson
generalises: parity means the interaction model, not just the feature list.
**Bugs fixed:** bare `seedpass-js` printed help then `error: (outputHelp)`;
unknown commands printed their error twice; `use --exec` always exited 0, so
`use db-pass --exec ./deploy.sh && echo ok` reported success after a failed
deploy; the sink command spec split on whitespace and ignored quotes, so
`--exec 'sh -c "..."'` died on an unterminated string; `--tags work,dev`
silently stored one tag named `work,dev`; a stopped agent reported raw
`connect ENOENT`; echo came back on between password retries, so a password
retyped after a typo was echoed in clear text.
**Stale claims corrected:** the capability map said SSH and PGP were not
ported (both are at parity), and the migration guide said there was no TUI.
**Verified this session:** a TS-generated seed opened in Python with the same
fingerprint, password and TOTP code; 128 CLI + 220 core tests; 36/36
cross-impl checks. `test/nostr.test.ts` is flaky under parallel load (live
relay) — it failed once and passed on rerun and three times in isolation.
### Next
1. **Independent security review before any real secrets.** The standing
recommendation, unchanged.
2. Fold the bundle checksum into the `release-integrity` signing workflow
(gate 6's remaining item).
3. Use the interactive mode for real work and report where it still does not
match muscle memory.
4. Deferred by the user until the project is ready to share: the Tessera
agent-plugin skill.
@@ -46,6 +46,8 @@ until a later milestone.
| Profiles + config (Python `~/.seedpass` layout) | P1 | green* | — | `fingerprint list/add/switch/remove`, `config get/set` over the Python directory layout (fingerprints.json, parent_seed.enc kdf/ct wrapper, index-key-encrypted config with ConfigManager defaults). *Layout-compatible and tested end-to-end in TS; opening a real Python-created profile is verified indirectly via the parent-seed wrapper fixture — direct cross-open test TODO. |
| Scoped tokens + audit chain (plan §9.3 / M8 core) | P1 | green | — (live agent tests) | Bearer tokens issued/held by the agent (hash-stored, shown once) with read/use/reveal scopes, kind + label-regex constraints, TTL and use counts; token-mode CLI reads the index and materializes secrets agent-side, never sees the mnemonic, and can never escalate to owner ops. Audit log uses Python AuditLogger's chain scheme (HMAC(prev_sig+canonical payload), KEY_INDEX key); verify/tail commands; tamper detection tested. Not yet: approval gates, high-risk partitions, persistent token store. |
| Session agent (vault unlock/lock) | new (TS-only) | green | — | ssh-agent-style unix-socket daemon holding seeds with TTL (0600 socket, in-memory only); seed resolution env -> agent; full lifecycle tested with no mnemonic in the environment. Designed enforcement point for the section-9.3 lease/token layer. Python has no equivalent (its lock is in-process TUI state). |
| Seed generation (new vault) | P0 | green | — | `fingerprint create`: 32 bytes of OS entropy through BIP-85 app 39 index 0, matching `PasswordManager.generate_bip85_seed`; 12 or 24 words. The entropy call is deliberately outside any try/catch (Python carries the same note from its entropy audit) so a CSPRNG failure can never be caught and a value substituted. Delivery is chosen before generation and happens before the profile is created, so no failure path leaves a profile whose seed was never delivered. **Was missing entirely until 2026-08-15** — a new user had no way to create a vault. |
| Interactive mode (legacy v1 TUI) | P1 | green | — | `seedpass-js` with no subcommand reproduces `src/main.py`'s menu tree: eight main-menu items, nine entry types under Add Entry, eighteen Settings items **under the same numbers**, plus Profiles, Nostr, entry-action and edit submenus. Line-based like Python's, blank input goes back. Not ported: TUI v2/v3, QR rendering (no encoder; the item offers the underlying value), semantic index, script checksums — each keeps its menu position and says why, so Python users' numbering still holds. Secret Mode matches Python: it routes reveals to the clipboard. Verified through a pty against a real vault and by 28 scripted-UI tests. |
## Environment coverage