mirror of
https://github.com/PR0M3TH3AN/SeedPass.git
synced 2026-11-01 18:32:05 +00:00
The "semantic (vector search)" entry in not_yet_ported was a misnomer. It is
not vector search and needs no model: MODEL_ID is "seedpass-token-overlap-v1",
and it scores by Jaccard overlap over tokenized metadata. That is why it could
be ported at all — there is nothing to embed.
Porting it surfaced two defects in the Python implementation.
**Stored secrets were written to a plaintext, 0664 file.** `_extract_text`
appended a key_value entry's `value` — the stored secret itself — and
`build()` wrote it to semantic_index/records.json in the clear, along with a
tokenized copy that leaked it just as thoroughly. The file was created at the
process umask, so on a default install it was group- and world-readable, next
to a vault that is encrypted and 0600. Anything that could read the directory
— a backup, a sync client, another user on a shared machine — got the secret
without the master password.
Fixed in Python (index the key NAME, never the value; chmod 0600 on both
files) and never done in TypeScript. The rule is worth keeping simple: nobody
searches for a secret they do not already know, so indexing one is pure
downside. MODEL_ID is bumped to v2 so an index built by the old code is
distinguishable — a v1 index on disk still contains the secrets and should be
rebuilt.
**Entry 0 was silently unsearchable.** The check was
`int(entry.get("id", 0) or 0) <= 0`, conflating "no id" with "id 0" — and
entry ids start at 0, so the first entry any user ever created was absent from
every search result with nothing to indicate why. Found by writing a test that
queried for it. Fixed in both implementations: skip an id that is absent,
unparseable or negative, which is what the check was reaching for.
The TypeScript port is wired into the CLI (`semantic build/status/search`),
the API (the /api/v1/semantic routes are now real rather than 501), and
writes through atomicWrite for a genuine 0600 inode. Fixtures come from
scripts/generate_ts_port_fixtures.py, which asserts the leaked value is absent
from its own output, so the fixture-drift job proves provenance the way it
does for every other fixture.
Co-Authored-By: Claude Opus 5 (1M context) <[email protected]>
Claude-Session: https://claude.ai/code/session_01Vtx94nXDmNgXEeThUZP4QN
326 lines
6.8 KiB
JSON
326 lines
6.8 KiB
JSON
{
|
|
"description": "semantic index records and rankings",
|
|
"entries": [
|
|
{
|
|
"id": 0,
|
|
"kind": "password",
|
|
"label": "first-ever.example",
|
|
"notes": "the very first entry a profile creates",
|
|
"tags": [
|
|
"edge"
|
|
],
|
|
"username": "zero"
|
|
},
|
|
{
|
|
"id": 1,
|
|
"kind": "password",
|
|
"label": "bank.example",
|
|
"notes": "main current account",
|
|
"tags": [
|
|
"money",
|
|
"daily"
|
|
],
|
|
"url": "https://bank.example",
|
|
"username": "alice"
|
|
},
|
|
{
|
|
"id": 2,
|
|
"key": "DEPLOY_TOKEN",
|
|
"kind": "key_value",
|
|
"label": "deploy-token",
|
|
"notes": "ci pipeline",
|
|
"tags": [
|
|
"ops"
|
|
],
|
|
"value": "SECRET-MUST-NOT-APPEAR"
|
|
},
|
|
{
|
|
"content": "how to recover the bank account if locked out",
|
|
"id": 3,
|
|
"kind": "document",
|
|
"label": "recovery notes",
|
|
"tags": [
|
|
"docs"
|
|
]
|
|
},
|
|
{
|
|
"id": 4,
|
|
"issuer": "Fastmail",
|
|
"kind": "totp",
|
|
"label": "email-2fa",
|
|
"notes": "",
|
|
"tags": [
|
|
"email"
|
|
]
|
|
},
|
|
{
|
|
"fingerprint": "SHA256:abcdef",
|
|
"id": 5,
|
|
"kind": "ssh",
|
|
"label": "prod-server",
|
|
"notes": "production access",
|
|
"tags": [
|
|
"ops"
|
|
]
|
|
},
|
|
{
|
|
"id": 6,
|
|
"kind": "nostr",
|
|
"label": "social",
|
|
"notes": "",
|
|
"npub": "npub1example",
|
|
"tags": []
|
|
},
|
|
{
|
|
"id": 7,
|
|
"kind": "seed",
|
|
"label": "child seed",
|
|
"notes": "not an indexed kind"
|
|
},
|
|
{
|
|
"content": "",
|
|
"id": 8,
|
|
"kind": "document",
|
|
"label": "",
|
|
"notes": "",
|
|
"tags": []
|
|
},
|
|
{
|
|
"id": 9,
|
|
"kind": "password",
|
|
"label": "linked",
|
|
"links": [
|
|
{
|
|
"note": "see recovery notes",
|
|
"relation": "depends_on"
|
|
}
|
|
],
|
|
"notes": "",
|
|
"tags": []
|
|
},
|
|
{
|
|
"content": "skipped",
|
|
"kind": "document",
|
|
"label": "no id at all"
|
|
}
|
|
],
|
|
"fixture_version": 1,
|
|
"kind_filtered": [
|
|
{
|
|
"entry_id": 5,
|
|
"excerpt": "prod-server\nproduction access\nops\nSHA256:abcdef",
|
|
"kind": "ssh",
|
|
"label": "prod-server",
|
|
"score": 0.142857
|
|
}
|
|
],
|
|
"queries": {
|
|
"DEPLOY_TOKEN": [
|
|
{
|
|
"entry_id": 2,
|
|
"excerpt": "deploy-token\nci pipeline\nops\nDEPLOY_TOKEN",
|
|
"kind": "key_value",
|
|
"label": "deploy-token",
|
|
"score": 0.166667
|
|
}
|
|
],
|
|
"bank": [
|
|
{
|
|
"entry_id": 1,
|
|
"excerpt": "bank.example\nmain current account\nmoney daily\nalice\nhttps://bank.example",
|
|
"kind": "password",
|
|
"label": "bank.example",
|
|
"score": 0.111111
|
|
},
|
|
{
|
|
"entry_id": 3,
|
|
"excerpt": "recovery notes\ndocs\nhow to recover the bank account if locked out",
|
|
"kind": "document",
|
|
"label": "recovery notes",
|
|
"score": 0.083333
|
|
}
|
|
],
|
|
"bank account": [
|
|
{
|
|
"entry_id": 1,
|
|
"excerpt": "bank.example\nmain current account\nmoney daily\nalice\nhttps://bank.example",
|
|
"kind": "password",
|
|
"label": "bank.example",
|
|
"score": 0.222222
|
|
},
|
|
{
|
|
"entry_id": 3,
|
|
"excerpt": "recovery notes\ndocs\nhow to recover the bank account if locked out",
|
|
"kind": "document",
|
|
"label": "recovery notes",
|
|
"score": 0.166667
|
|
}
|
|
],
|
|
"email": [
|
|
{
|
|
"entry_id": 4,
|
|
"excerpt": "email-2fa\nemail\nFastmail",
|
|
"kind": "totp",
|
|
"label": "email-2fa",
|
|
"score": 0.333333
|
|
}
|
|
],
|
|
"first entry": [
|
|
{
|
|
"entry_id": 0,
|
|
"excerpt": "first-ever.example\nthe very first entry a profile creates\nedge\nzero",
|
|
"kind": "password",
|
|
"label": "first-ever.example",
|
|
"score": 0.181818
|
|
}
|
|
],
|
|
"nothing matches here": [],
|
|
"ops production": [
|
|
{
|
|
"entry_id": 5,
|
|
"excerpt": "prod-server\nproduction access\nops\nSHA256:abcdef",
|
|
"kind": "ssh",
|
|
"label": "prod-server",
|
|
"score": 0.285714
|
|
},
|
|
{
|
|
"entry_id": 2,
|
|
"excerpt": "deploy-token\nci pipeline\nops\nDEPLOY_TOKEN",
|
|
"kind": "key_value",
|
|
"label": "deploy-token",
|
|
"score": 0.142857
|
|
}
|
|
],
|
|
"recover locked": [
|
|
{
|
|
"entry_id": 3,
|
|
"excerpt": "recovery notes\ndocs\nhow to recover the bank account if locked out",
|
|
"kind": "document",
|
|
"label": "recovery notes",
|
|
"score": 0.166667
|
|
}
|
|
]
|
|
},
|
|
"records": [
|
|
{
|
|
"entry_id": 0,
|
|
"kind": "password",
|
|
"label": "first-ever.example",
|
|
"text": "first-ever.example\nthe very first entry a profile creates\nedge\nzero",
|
|
"tokens": [
|
|
"a",
|
|
"creates",
|
|
"edge",
|
|
"entry",
|
|
"ever",
|
|
"example",
|
|
"first",
|
|
"profile",
|
|
"the",
|
|
"very",
|
|
"zero"
|
|
]
|
|
},
|
|
{
|
|
"entry_id": 1,
|
|
"kind": "password",
|
|
"label": "bank.example",
|
|
"text": "bank.example\nmain current account\nmoney daily\nalice\nhttps://bank.example",
|
|
"tokens": [
|
|
"account",
|
|
"alice",
|
|
"bank",
|
|
"current",
|
|
"daily",
|
|
"example",
|
|
"https",
|
|
"main",
|
|
"money"
|
|
]
|
|
},
|
|
{
|
|
"entry_id": 2,
|
|
"kind": "key_value",
|
|
"label": "deploy-token",
|
|
"text": "deploy-token\nci pipeline\nops\nDEPLOY_TOKEN",
|
|
"tokens": [
|
|
"ci",
|
|
"deploy",
|
|
"deploy_token",
|
|
"ops",
|
|
"pipeline",
|
|
"token"
|
|
]
|
|
},
|
|
{
|
|
"entry_id": 3,
|
|
"kind": "document",
|
|
"label": "recovery notes",
|
|
"text": "recovery notes\ndocs\nhow to recover the bank account if locked out",
|
|
"tokens": [
|
|
"account",
|
|
"bank",
|
|
"docs",
|
|
"how",
|
|
"if",
|
|
"locked",
|
|
"notes",
|
|
"out",
|
|
"recover",
|
|
"recovery",
|
|
"the",
|
|
"to"
|
|
]
|
|
},
|
|
{
|
|
"entry_id": 4,
|
|
"kind": "totp",
|
|
"label": "email-2fa",
|
|
"text": "email-2fa\nemail\nFastmail",
|
|
"tokens": [
|
|
"2fa",
|
|
"email",
|
|
"fastmail"
|
|
]
|
|
},
|
|
{
|
|
"entry_id": 5,
|
|
"kind": "ssh",
|
|
"label": "prod-server",
|
|
"text": "prod-server\nproduction access\nops\nSHA256:abcdef",
|
|
"tokens": [
|
|
"abcdef",
|
|
"access",
|
|
"ops",
|
|
"prod",
|
|
"production",
|
|
"server",
|
|
"sha256"
|
|
]
|
|
},
|
|
{
|
|
"entry_id": 6,
|
|
"kind": "nostr",
|
|
"label": "social",
|
|
"text": "social\nnpub1example",
|
|
"tokens": [
|
|
"npub1example",
|
|
"social"
|
|
]
|
|
},
|
|
{
|
|
"entry_id": 9,
|
|
"kind": "password",
|
|
"label": "linked",
|
|
"text": "linked\ndepends_on\nsee recovery notes",
|
|
"tokens": [
|
|
"depends_on",
|
|
"linked",
|
|
"notes",
|
|
"recovery",
|
|
"see"
|
|
]
|
|
}
|
|
]
|
|
}
|