voyd 0.1.0__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- voyd/__init__.py +105 -0
- voyd/declare.py +649 -0
- voyd/engine/__init__.py +111 -0
- voyd/engine/admission/__init__.py +120 -0
- voyd/engine/admission/composition.py +120 -0
- voyd/engine/admission/core.py +814 -0
- voyd/engine/admission/handle.py +69 -0
- voyd/engine/admission/lineage.py +241 -0
- voyd/engine/admission/marks.py +560 -0
- voyd/engine/admission/reads.py +166 -0
- voyd/engine/admission/reasons.py +97 -0
- voyd/engine/admission/receipts.py +279 -0
- voyd/engine/admission/rerank.py +244 -0
- voyd/engine/admission/rules.py +895 -0
- voyd/engine/admission/sealing.py +256 -0
- voyd/engine/admission/spec.py +302 -0
- voyd/engine/admission/transforms.py +128 -0
- voyd/engine/attest.py +168 -0
- voyd/engine/authority.py +240 -0
- voyd/engine/capabilities.py +128 -0
- voyd/engine/custody.py +426 -0
- voyd/engine/errors.py +364 -0
- voyd/engine/expiry.py +92 -0
- voyd/engine/keyring.py +815 -0
- voyd/engine/plan.py +547 -0
- voyd/engine/py.typed +1 -0
- voyd/engine/search.py +456 -0
- voyd/engine/time.py +145 -0
- voyd/engine/trait.py +47 -0
- voyd/py.typed +1 -0
- voyd/wire/__init__.py +37 -0
- voyd/wire/__main__.py +19 -0
- voyd/wire/bench.py +758 -0
- voyd/wire/cascade.py +232 -0
- voyd/wire/cli.py +393 -0
- voyd/wire/codec.py +292 -0
- voyd/wire/ensure.py +179 -0
- voyd/wire/health.py +66 -0
- voyd/wire/identity.py +190 -0
- voyd/wire/metrics.py +552 -0
- voyd/wire/plan.py +504 -0
- voyd/wire/plan_report.py +347 -0
- voyd/wire/policy/__init__.py +97 -0
- voyd/wire/policy/erasure.py +137 -0
- voyd/wire/policy/guarding.py +460 -0
- voyd/wire/policy/handshake.py +110 -0
- voyd/wire/policy/reads.py +526 -0
- voyd/wire/policy/refusals.py +327 -0
- voyd/wire/policy/verbs.py +287 -0
- voyd/wire/preflight.py +429 -0
- voyd/wire/proxy.py +1149 -0
- voyd/wire/report.py +98 -0
- voyd/wire/seal.py +631 -0
- voyd/wire/upstream.py +277 -0
- voyd-0.1.0.dist-info/METADATA +746 -0
- voyd-0.1.0.dist-info/RECORD +59 -0
- voyd-0.1.0.dist-info/WHEEL +4 -0
- voyd-0.1.0.dist-info/entry_points.txt +5 -0
- voyd-0.1.0.dist-info/licenses/LICENSE +21 -0
voyd/__init__.py
ADDED
|
@@ -0,0 +1,105 @@
|
|
|
1
|
+
"""VOYD: a retrieval read path that refuses what it has forgotten.
|
|
2
|
+
|
|
3
|
+
Ranking is not permission. A vector index ranks by relevance and is never
|
|
4
|
+
asked the other question -- may this fact reach a prompt? -- so a retrieval
|
|
5
|
+
answers with a confident score and no idea whether the hit was allowed to be
|
|
6
|
+
there: an expired row the sweeper has not reached, a fact somebody revoked, a
|
|
7
|
+
vector from a model that was swapped.
|
|
8
|
+
|
|
9
|
+
VOYD answers that question at the one place every read passes through on the
|
|
10
|
+
way out.
|
|
11
|
+
|
|
12
|
+
**There is one way to use it, and it is not an import.** VOYD is a proxy.
|
|
13
|
+
Declare the rules once, in a file that is not your application::
|
|
14
|
+
|
|
15
|
+
# voydfile.py
|
|
16
|
+
from voyd import guard, deadline, revocable, tenant
|
|
17
|
+
|
|
18
|
+
@guard("notes")
|
|
19
|
+
class Notes:
|
|
20
|
+
expire_at = deadline()
|
|
21
|
+
forgotten = revocable()
|
|
22
|
+
tenant_id = tenant()
|
|
23
|
+
|
|
24
|
+
# then: voyd-wire --config voydfile.py --target localhost:27017
|
|
25
|
+
|
|
26
|
+
No code. Any driver in any language pointed at that port cannot read a
|
|
27
|
+
forgotten fact, because the boundary is not something a caller can forget
|
|
28
|
+
to use -- there is nothing to reach past.
|
|
29
|
+
|
|
30
|
+
What this package exports is the vocabulary above -- ``guard``,
|
|
31
|
+
``deadline``, ``revocable`` and the rest -- because the proxy loads your
|
|
32
|
+
policy file, and the parts ``--ensure`` and ``--verify`` provision with.
|
|
33
|
+
There is nothing here for an application to import and no handle for it to
|
|
34
|
+
hold: a boundary you can forget to route a read through is not one.
|
|
35
|
+
|
|
36
|
+
The check itself is pure -- no database, no connection, no I/O -- which is
|
|
37
|
+
what lets it run inside a proxy at all. The proxy opens one connection of
|
|
38
|
+
its own, and only when a policy declares ``lineage_field``: making a
|
|
39
|
+
refusal reach what was derived from a fact is a write the caller did not
|
|
40
|
+
issue, so it does not go on the caller's session.
|
|
41
|
+
|
|
42
|
+
The pieces, and everything else is mechanics:
|
|
43
|
+
|
|
44
|
+
**Deadline** -- one ``expire_at``, inherited by every row in the scope and
|
|
45
|
+
collected by one TTL index. Enforced in the *read path* as well as by the
|
|
46
|
+
reaper: MongoDB's TTL monitor runs about once a minute (measured: 60.0s), so
|
|
47
|
+
an expired document lives on disk for a window afterwards, and serving it
|
|
48
|
+
during that window is the whole bug class.
|
|
49
|
+
|
|
50
|
+
**Refusal** -- not a convention each call site remembers, because a rule you
|
|
51
|
+
have to remember to apply is not enforced. ``revoke()`` makes a fact
|
|
52
|
+
unreachable on the next read while its row is still on disk: deletion is a
|
|
53
|
+
storage event, refusal is a retrieval guarantee, and only the second can be
|
|
54
|
+
immediate. Not every refusal is an erasure, and the difference is declared on
|
|
55
|
+
the reason rather than decided by the verb -- one word, ``reversible``, says
|
|
56
|
+
whether ``lift()`` works and whether imposing it schedules the reaper. See
|
|
57
|
+
``examples/refuse.py``.
|
|
58
|
+
|
|
59
|
+
**A rule is a protocol, not a list.** ``reason`` + ``refuses(doc)`` +
|
|
60
|
+
``clause()``, and a stranger's rule is a first-class one. That is what makes
|
|
61
|
+
the set-relative reasons possible -- a token budget, a de-duplicator, a
|
|
62
|
+
provenance quota -- which refuse a document because of the *other* documents
|
|
63
|
+
on the page, and which no index filter and no policy engine can express. See
|
|
64
|
+
``examples/rosetta.py`` and ``examples/portfolio.py``.
|
|
65
|
+
|
|
66
|
+
**Refusal travels.** A collection declaring ``lineage_field`` records what
|
|
67
|
+
each document was made out of, so revoking a source reaches the summary, the
|
|
68
|
+
answer and the embedding built on it -- children marked first, then the
|
|
69
|
+
source, because a crash the other way round leaves a summary of an erased
|
|
70
|
+
fact still answering prompts. The boundary closes a document's ancestry
|
|
71
|
+
transitively when it is written, which is what makes the cascade one query
|
|
72
|
+
at any depth, and refuses an insert that claims a parent it may not reach.
|
|
73
|
+
``find({"lineage": id})`` answers the question from the other end.
|
|
74
|
+
|
|
75
|
+
**And refusal is not the whole answer, which is said here rather than
|
|
76
|
+
discovered later.** Refusal binds a read path, and a restored snapshot does
|
|
77
|
+
not run it. That is what ``sealed()`` and ``--key-vault`` are for -- a key
|
|
78
|
+
per scope, so destroying it makes every copy unreadable at once, and the
|
|
79
|
+
boundary revokes the documents *first* so the key cache is not a second
|
|
80
|
+
window. See ``examples/shred.py``.
|
|
81
|
+
|
|
82
|
+
Every claim above is asserted by the test suite against a real MongoDB --
|
|
83
|
+
no mock tier, on purpose, because these properties are only true if the
|
|
84
|
+
*queries* are right.
|
|
85
|
+
"""
|
|
86
|
+
|
|
87
|
+
from __future__ import annotations
|
|
88
|
+
|
|
89
|
+
from .declare import (auto_embed, budget, clearance, deadline, distinct,
|
|
90
|
+
embedded_with, guard, holdable, restricted_to,
|
|
91
|
+
rerank, revocable, sealed, subjects, tenant, transform)
|
|
92
|
+
|
|
93
|
+
__version__ = "0.1.0"
|
|
94
|
+
|
|
95
|
+
__all__ = [
|
|
96
|
+
# The declarative policy surface -- everything `voydfile.py` needs.
|
|
97
|
+
"guard", "deadline", "revocable", "holdable", "tenant",
|
|
98
|
+
"restricted_to", "clearance", "embedded_with", "budget", "distinct",
|
|
99
|
+
"sealed", "auto_embed", "subjects",
|
|
100
|
+
# Page-shaping, which is not a rule and is exported beside them
|
|
101
|
+
# anyway: it is declared in the same file, and a vocabulary split
|
|
102
|
+
# across two imports is a vocabulary people get wrong.
|
|
103
|
+
"transform", "rerank",
|
|
104
|
+
"__version__",
|
|
105
|
+
]
|