project-xox 0.1.0__tar.gz
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.
- project_xox-0.1.0/.gitignore +37 -0
- project_xox-0.1.0/Cargo.lock +132 -0
- project_xox-0.1.0/Cargo.toml +23 -0
- project_xox-0.1.0/LICENSE +176 -0
- project_xox-0.1.0/PKG-INFO +273 -0
- project_xox-0.1.0/README.md +252 -0
- project_xox-0.1.0/pyproject.toml +31 -0
- project_xox-0.1.0/src/binding.rs +161 -0
- project_xox-0.1.0/src/core.rs +59 -0
- project_xox-0.1.0/src/lib.rs +23 -0
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
# Agent-internal workspace
|
|
2
|
+
.agents/
|
|
3
|
+
|
|
4
|
+
# Python virtual environments
|
|
5
|
+
.venv/
|
|
6
|
+
venv/
|
|
7
|
+
|
|
8
|
+
# Build outputs & packaging artifacts
|
|
9
|
+
target/
|
|
10
|
+
dist/
|
|
11
|
+
build/
|
|
12
|
+
|
|
13
|
+
# Python caches and test artifacts
|
|
14
|
+
__pycache__/
|
|
15
|
+
*.py[cod]
|
|
16
|
+
.pytest_cache/
|
|
17
|
+
.mypy_cache/
|
|
18
|
+
.ruff_cache/
|
|
19
|
+
.coverage
|
|
20
|
+
htmlcov/
|
|
21
|
+
|
|
22
|
+
# Editor and OS files
|
|
23
|
+
.idea/
|
|
24
|
+
.vscode/
|
|
25
|
+
.DS_Store
|
|
26
|
+
*.swp
|
|
27
|
+
*.swo
|
|
28
|
+
*.tmp
|
|
29
|
+
*.log
|
|
30
|
+
|
|
31
|
+
# Secrets and environment files
|
|
32
|
+
.env
|
|
33
|
+
.env.*
|
|
34
|
+
*.pem
|
|
35
|
+
*.key
|
|
36
|
+
*.p12
|
|
37
|
+
*.pfx
|
|
@@ -0,0 +1,132 @@
|
|
|
1
|
+
# This file is automatically @generated by Cargo.
|
|
2
|
+
# It is not intended for manual editing.
|
|
3
|
+
version = 4
|
|
4
|
+
|
|
5
|
+
[[package]]
|
|
6
|
+
name = "heck"
|
|
7
|
+
version = "0.5.0"
|
|
8
|
+
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
9
|
+
checksum = "2304e00983f87ffb38b55b444b5e3b60a884b5d30c0fca7d82fe33449bbe55ea"
|
|
10
|
+
|
|
11
|
+
[[package]]
|
|
12
|
+
name = "libc"
|
|
13
|
+
version = "0.2.189"
|
|
14
|
+
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
15
|
+
checksum = "3eaf3ede3fee6db1a4c2ee091bf8a8b4dccdc6d17f656fb07896ee72867612f2"
|
|
16
|
+
|
|
17
|
+
[[package]]
|
|
18
|
+
name = "once_cell"
|
|
19
|
+
version = "1.21.4"
|
|
20
|
+
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
21
|
+
checksum = "9f7c3e4beb33f85d45ae3e3a1792185706c8e16d043238c593331cc7cd313b50"
|
|
22
|
+
|
|
23
|
+
[[package]]
|
|
24
|
+
name = "portable-atomic"
|
|
25
|
+
version = "1.15.0"
|
|
26
|
+
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
27
|
+
checksum = "05c8b63e8d9609db387f0324918f81d68fe27748f084ef092fb35954d0539a85"
|
|
28
|
+
|
|
29
|
+
[[package]]
|
|
30
|
+
name = "proc-macro2"
|
|
31
|
+
version = "1.0.107"
|
|
32
|
+
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
33
|
+
checksum = "985e7ec9bb745e6ce6535b544d84d6cd6f7ad8bd711c398938ae983b91a766d9"
|
|
34
|
+
dependencies = [
|
|
35
|
+
"unicode-ident",
|
|
36
|
+
]
|
|
37
|
+
|
|
38
|
+
[[package]]
|
|
39
|
+
name = "pyo3"
|
|
40
|
+
version = "0.29.2"
|
|
41
|
+
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
42
|
+
checksum = "4688ddedf473e32662b9b067670129a8afb8c18e351482c70d62ba4a88171e8b"
|
|
43
|
+
dependencies = [
|
|
44
|
+
"libc",
|
|
45
|
+
"once_cell",
|
|
46
|
+
"portable-atomic",
|
|
47
|
+
"pyo3-build-config",
|
|
48
|
+
"pyo3-ffi",
|
|
49
|
+
"pyo3-macros",
|
|
50
|
+
]
|
|
51
|
+
|
|
52
|
+
[[package]]
|
|
53
|
+
name = "pyo3-build-config"
|
|
54
|
+
version = "0.29.2"
|
|
55
|
+
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
56
|
+
checksum = "f41027e41b4bd03f6e60f9f417fe24a6341a6bb744edd62b6f709f2a52ea30e9"
|
|
57
|
+
dependencies = [
|
|
58
|
+
"target-lexicon",
|
|
59
|
+
]
|
|
60
|
+
|
|
61
|
+
[[package]]
|
|
62
|
+
name = "pyo3-ffi"
|
|
63
|
+
version = "0.29.2"
|
|
64
|
+
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
65
|
+
checksum = "e591a95526fead067432c3b3a33fc74770b87b1e04e73671090d9c2055a2b327"
|
|
66
|
+
dependencies = [
|
|
67
|
+
"libc",
|
|
68
|
+
"pyo3-build-config",
|
|
69
|
+
]
|
|
70
|
+
|
|
71
|
+
[[package]]
|
|
72
|
+
name = "pyo3-macros"
|
|
73
|
+
version = "0.29.2"
|
|
74
|
+
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
75
|
+
checksum = "73225868fc1cd84eef2c3c230ddb91273bf1de46aeb8a4248da76d32a0924a1c"
|
|
76
|
+
dependencies = [
|
|
77
|
+
"proc-macro2",
|
|
78
|
+
"pyo3-macros-backend",
|
|
79
|
+
"quote",
|
|
80
|
+
"syn",
|
|
81
|
+
]
|
|
82
|
+
|
|
83
|
+
[[package]]
|
|
84
|
+
name = "pyo3-macros-backend"
|
|
85
|
+
version = "0.29.2"
|
|
86
|
+
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
87
|
+
checksum = "571575aa3749fa6216757dd47d2a3e7ef360f329a40f0666a9fbd14889024952"
|
|
88
|
+
dependencies = [
|
|
89
|
+
"heck",
|
|
90
|
+
"proc-macro2",
|
|
91
|
+
"quote",
|
|
92
|
+
"syn",
|
|
93
|
+
]
|
|
94
|
+
|
|
95
|
+
[[package]]
|
|
96
|
+
name = "quote"
|
|
97
|
+
version = "1.0.47"
|
|
98
|
+
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
99
|
+
checksum = "1fbf4db142a473a8d80c26bbf18454ed458bf8d26c8219c331daecfdbd079001"
|
|
100
|
+
dependencies = [
|
|
101
|
+
"proc-macro2",
|
|
102
|
+
]
|
|
103
|
+
|
|
104
|
+
[[package]]
|
|
105
|
+
name = "syn"
|
|
106
|
+
version = "2.0.119"
|
|
107
|
+
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
108
|
+
checksum = "872831b642d1a07999a962a351ed35b955ea2cfc8f3862091e2a240a84f17297"
|
|
109
|
+
dependencies = [
|
|
110
|
+
"proc-macro2",
|
|
111
|
+
"quote",
|
|
112
|
+
"unicode-ident",
|
|
113
|
+
]
|
|
114
|
+
|
|
115
|
+
[[package]]
|
|
116
|
+
name = "target-lexicon"
|
|
117
|
+
version = "0.13.5"
|
|
118
|
+
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
119
|
+
checksum = "adb6935a6f5c20170eeceb1a3835a49e12e19d792f6dd344ccc76a985ca5a6ca"
|
|
120
|
+
|
|
121
|
+
[[package]]
|
|
122
|
+
name = "unicode-ident"
|
|
123
|
+
version = "1.0.24"
|
|
124
|
+
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
125
|
+
checksum = "e6e4313cd5fcd3dad5cafa179702e2b244f760991f45397d14d4ebf38247da75"
|
|
126
|
+
|
|
127
|
+
[[package]]
|
|
128
|
+
name = "xox"
|
|
129
|
+
version = "0.1.0"
|
|
130
|
+
dependencies = [
|
|
131
|
+
"pyo3",
|
|
132
|
+
]
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
[package]
|
|
2
|
+
name = "xox"
|
|
3
|
+
version = "0.1.0"
|
|
4
|
+
edition = "2021"
|
|
5
|
+
rust-version = "1.83"
|
|
6
|
+
exclude = [
|
|
7
|
+
".agents",
|
|
8
|
+
".git",
|
|
9
|
+
".github",
|
|
10
|
+
".venv",
|
|
11
|
+
".pytest_cache",
|
|
12
|
+
"target",
|
|
13
|
+
"tests",
|
|
14
|
+
"docs",
|
|
15
|
+
]
|
|
16
|
+
readme = "README.md"
|
|
17
|
+
|
|
18
|
+
[lib]
|
|
19
|
+
name = "xox"
|
|
20
|
+
crate-type = ["cdylib", "rlib"]
|
|
21
|
+
|
|
22
|
+
[dependencies]
|
|
23
|
+
pyo3 = { version = "0.29", features = ["extension-module"] }
|
|
@@ -0,0 +1,176 @@
|
|
|
1
|
+
Apache License
|
|
2
|
+
Version 2.0, January 2004
|
|
3
|
+
http://www.apache.org/licenses/
|
|
4
|
+
|
|
5
|
+
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
|
|
6
|
+
|
|
7
|
+
1. Definitions.
|
|
8
|
+
|
|
9
|
+
"License" shall mean the terms and conditions for use, reproduction,
|
|
10
|
+
and distribution as defined by Sections 1 through 9 of this document.
|
|
11
|
+
|
|
12
|
+
"Licensor" shall mean the copyright owner or entity authorized by
|
|
13
|
+
the copyright owner that is granting the License.
|
|
14
|
+
|
|
15
|
+
"Legal Entity" shall mean the union of the acting entity and all
|
|
16
|
+
other entities that control, are controlled by, or are under common
|
|
17
|
+
control with that entity. For the purposes of this definition,
|
|
18
|
+
"control" means (i) the power, direct or indirect, to cause the
|
|
19
|
+
direction or management of such entity, whether by contract or
|
|
20
|
+
otherwise, or (ii) ownership of fifty percent (50%) or more of the
|
|
21
|
+
outstanding shares, or (iii) beneficial ownership of such entity.
|
|
22
|
+
|
|
23
|
+
"You" (or "Your") shall mean an individual or Legal Entity
|
|
24
|
+
exercising permissions granted by this License.
|
|
25
|
+
|
|
26
|
+
"Source" form shall mean the preferred form for making modifications,
|
|
27
|
+
including but not limited to software source code, documentation
|
|
28
|
+
source, and configuration files.
|
|
29
|
+
|
|
30
|
+
"Object" form shall mean any form resulting from mechanical
|
|
31
|
+
transformation or translation of a Source form, including but
|
|
32
|
+
not limited to compiled object code, generated documentation,
|
|
33
|
+
and conversions to other media types.
|
|
34
|
+
|
|
35
|
+
"Work" shall mean the work of authorship, whether in Source or
|
|
36
|
+
Object form, made available under the License, as indicated by a
|
|
37
|
+
copyright notice that is included in or attached to the work
|
|
38
|
+
(an example is provided in the Appendix below).
|
|
39
|
+
|
|
40
|
+
"Derivative Works" shall mean any work, whether in Source or Object
|
|
41
|
+
form, that is based on (or derived from) the Work and for which the
|
|
42
|
+
editorial revisions, annotations, elaborations, or other modifications
|
|
43
|
+
represent, as a whole, an original work of authorship. For the purposes
|
|
44
|
+
of this License, Derivative Works shall not include works that remain
|
|
45
|
+
separable from, or merely link (or bind by name) to the interfaces of,
|
|
46
|
+
the Work and Derivative Works thereof.
|
|
47
|
+
|
|
48
|
+
"Contribution" shall mean any work of authorship, including
|
|
49
|
+
the original version of the Work and any modifications or additions
|
|
50
|
+
to that Work or Derivative Works thereof, that is intentionally
|
|
51
|
+
submitted to Licensor for inclusion in the Work by the copyright owner
|
|
52
|
+
or by an individual or Legal Entity authorized to submit on behalf of
|
|
53
|
+
the copyright owner. For the purposes of this definition, "submitted"
|
|
54
|
+
means any form of electronic, verbal, or written communication sent
|
|
55
|
+
to the Licensor or its representatives, including but not limited to
|
|
56
|
+
communication on electronic mailing lists, source code control systems,
|
|
57
|
+
and issue tracking systems that are managed by, or on behalf of, the
|
|
58
|
+
Licensor for the purpose of discussing and improving the Work, but
|
|
59
|
+
excluding communication that is conspicuously marked or otherwise
|
|
60
|
+
designated in writing by the copyright owner as "Not a Contribution."
|
|
61
|
+
|
|
62
|
+
"Contributor" shall mean Licensor and any individual or Legal Entity
|
|
63
|
+
on behalf of whom a Contribution has been received by Licensor and
|
|
64
|
+
subsequently incorporated within the Work.
|
|
65
|
+
|
|
66
|
+
2. Grant of Copyright License. Subject to the terms and conditions of
|
|
67
|
+
this License, each Contributor hereby grants to You a perpetual,
|
|
68
|
+
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
|
69
|
+
copyright license to reproduce, prepare Derivative Works of,
|
|
70
|
+
publicly display, publicly perform, sublicense, and distribute the
|
|
71
|
+
Work and such Derivative Works in Source or Object form.
|
|
72
|
+
|
|
73
|
+
3. Grant of Patent License. Subject to the terms and conditions of
|
|
74
|
+
this License, each Contributor hereby grants to You a perpetual,
|
|
75
|
+
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
|
76
|
+
(except as stated in this section) patent license to make, have made,
|
|
77
|
+
use, offer to sell, sell, import, and otherwise transfer the Work,
|
|
78
|
+
where such license applies only to those patent claims licensable
|
|
79
|
+
by such Contributor that are necessarily infringed by their
|
|
80
|
+
Contribution(s) alone or by combination of their Contribution(s)
|
|
81
|
+
with the Work to which such Contribution(s) was submitted. If You
|
|
82
|
+
institute patent litigation against any entity (including a
|
|
83
|
+
cross-claim or counterclaim in a lawsuit) alleging that the Work
|
|
84
|
+
or a Contribution incorporated within the Work constitutes direct
|
|
85
|
+
or contributory patent infringement, then any patent licenses
|
|
86
|
+
granted to You under this License for that Work shall terminate
|
|
87
|
+
as of the date such litigation is filed.
|
|
88
|
+
|
|
89
|
+
4. Redistribution. You may reproduce and distribute copies of the
|
|
90
|
+
Work or Derivative Works thereof in any medium, with or without
|
|
91
|
+
modifications, and in Source or Object form, provided that You
|
|
92
|
+
meet the following conditions:
|
|
93
|
+
|
|
94
|
+
(a) You must give any other recipients of the Work or
|
|
95
|
+
Derivative Works a copy of this License; and
|
|
96
|
+
|
|
97
|
+
(b) You must cause any modified files to carry prominent notices
|
|
98
|
+
stating that You changed the files; and
|
|
99
|
+
|
|
100
|
+
(c) You must retain, in the Source form of any Derivative Works
|
|
101
|
+
that You distribute, all copyright, patent, trademark, and
|
|
102
|
+
attribution notices from the Source form of the Work,
|
|
103
|
+
excluding those notices that do not pertain to any part of
|
|
104
|
+
the Derivative Works; and
|
|
105
|
+
|
|
106
|
+
(d) If the Work includes a "NOTICE" text file as part of its
|
|
107
|
+
distribution, then any Derivative Works that You distribute must
|
|
108
|
+
include a readable copy of the attribution notices contained
|
|
109
|
+
within such NOTICE file, excluding those notices that do not
|
|
110
|
+
pertain to any part of the Derivative Works, in at least one
|
|
111
|
+
of the following places: within a NOTICE text file distributed
|
|
112
|
+
as part of the Derivative Works; within the Source form or
|
|
113
|
+
documentation, if provided along with the Derivative Works; or,
|
|
114
|
+
within a display generated by the Derivative Works, if and
|
|
115
|
+
wherever such third-party notices normally appear. The contents
|
|
116
|
+
of the NOTICE file are for informational purposes only and
|
|
117
|
+
do not modify the License. You may add Your own attribution
|
|
118
|
+
notices within Derivative Works that You distribute, alongside
|
|
119
|
+
or as an addendum to the NOTICE text from the Work, provided
|
|
120
|
+
that such additional attribution notices cannot be construed
|
|
121
|
+
as modifying the License.
|
|
122
|
+
|
|
123
|
+
You may add Your own copyright statement to Your modifications and
|
|
124
|
+
may provide additional or different license terms and conditions
|
|
125
|
+
for use, reproduction, or distribution of Your modifications, or
|
|
126
|
+
for any such Derivative Works as a whole, provided Your use,
|
|
127
|
+
reproduction, and distribution of the Work otherwise complies with
|
|
128
|
+
the conditions stated in this License.
|
|
129
|
+
|
|
130
|
+
5. Submission of Contributions. Unless You explicitly state otherwise,
|
|
131
|
+
any Contribution intentionally submitted for inclusion in the Work
|
|
132
|
+
by You to the Licensor shall be under the terms and conditions of
|
|
133
|
+
this License, without any additional terms or conditions.
|
|
134
|
+
Notwithstanding the above, nothing herein shall supersede or modify
|
|
135
|
+
the terms of any separate license agreement you may have executed
|
|
136
|
+
with Licensor regarding such Contributions.
|
|
137
|
+
|
|
138
|
+
6. Trademarks. This License does not grant permission to use the trade
|
|
139
|
+
names, trademarks, service marks, or product names of the Licensor,
|
|
140
|
+
except as required for reasonable and customary use in describing the
|
|
141
|
+
origin of the Work and reproducing the content of the NOTICE file.
|
|
142
|
+
|
|
143
|
+
7. Disclaimer of Warranty. Unless required by applicable law or
|
|
144
|
+
agreed to in writing, Licensor provides the Work (and each
|
|
145
|
+
Contributor provides its Contributions) on an "AS IS" BASIS,
|
|
146
|
+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
|
147
|
+
implied, including, without limitation, any warranties or conditions
|
|
148
|
+
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
|
|
149
|
+
PARTICULAR PURPOSE. You are solely responsible for determining the
|
|
150
|
+
appropriement of using or redistributing the Work and assume any
|
|
151
|
+
risks associated with Your exercise of permissions under this License.
|
|
152
|
+
|
|
153
|
+
8. Limitation of Liability. In no event and under no legal theory,
|
|
154
|
+
whether in tort (including negligence), contract, or otherwise,
|
|
155
|
+
unless required by applicable law (such as deliberate and grossly
|
|
156
|
+
negligent acts) or agreed to in writing, shall any Contributor be
|
|
157
|
+
liable to You for damages, including any direct, indirect, special,
|
|
158
|
+
incidental, or consequential damages of any character arising as a
|
|
159
|
+
result of this License or out of the use or inability to use the
|
|
160
|
+
Work (including but not limited to damages for loss of goodwill,
|
|
161
|
+
work stoppage, computer failure or malfunction, or any and all
|
|
162
|
+
other commercial damages or losses), even if such Contributor
|
|
163
|
+
has been advised of the possibility of such damages.
|
|
164
|
+
|
|
165
|
+
9. Accepting Warranty or Additional Liability. While redistributing
|
|
166
|
+
the Work or Derivative Works thereof, You may choose to offer,
|
|
167
|
+
and charge a fee for, acceptance of support, warranty, indemnity,
|
|
168
|
+
or other liability obligations and/or rights consistent with this
|
|
169
|
+
License. However, in accepting such obligations, You may act only
|
|
170
|
+
on Your own behalf and on Your sole responsibility, not on behalf
|
|
171
|
+
of any other Contributor, and only if You agree to indemnify,
|
|
172
|
+
defend, and hold each Contributor harmless for any liability
|
|
173
|
+
incurred by, or claims asserted against, such Contributor by reason
|
|
174
|
+
of your accepting any such warranty or additional liability.
|
|
175
|
+
|
|
176
|
+
END OF TERMS AND CONDITIONS
|
|
@@ -0,0 +1,273 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: project-xox
|
|
3
|
+
Version: 0.1.0
|
|
4
|
+
Classifier: Programming Language :: Python :: 3
|
|
5
|
+
Classifier: Programming Language :: Python :: 3 :: Only
|
|
6
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
7
|
+
Classifier: Programming Language :: Python :: 3.13
|
|
8
|
+
Classifier: Programming Language :: Python :: 3.14
|
|
9
|
+
Classifier: Programming Language :: Python :: Implementation :: CPython
|
|
10
|
+
Classifier: Programming Language :: Rust
|
|
11
|
+
Classifier: License :: OSI Approved :: Apache Software License
|
|
12
|
+
Classifier: Operating System :: POSIX :: Linux
|
|
13
|
+
License-File: LICENSE
|
|
14
|
+
Summary: Tri-state epistemic uncertainty engine preserving explicit True, False, and Unknown decision semantics
|
|
15
|
+
License-Expression: Apache-2.0
|
|
16
|
+
Requires-Python: >=3.12
|
|
17
|
+
Description-Content-Type: text/markdown; charset=UTF-8; variant=GFM
|
|
18
|
+
Project-URL: Documentation, https://github.com/linuxx88/XoX/blob/main/docs/04_api/CORE_API.md
|
|
19
|
+
Project-URL: Homepage, https://github.com/linuxx88/XoX
|
|
20
|
+
|
|
21
|
+
# XoX
|
|
22
|
+
|
|
23
|
+
Tri-state epistemic uncertainty engine preserving explicit `True`, `False`, and `Unknown` decision semantics in Python.
|
|
24
|
+
|
|
25
|
+
---
|
|
26
|
+
|
|
27
|
+
## The Problem
|
|
28
|
+
|
|
29
|
+
Standard boolean logic provides only two states: `True` and `False`. When a system evaluates an assertion—such as whether an account is authorized, whether a remote record exists, or whether an external precondition holds—the state of that assertion is often indeterminate due to incomplete or unreachable information.
|
|
30
|
+
|
|
31
|
+
Coercing an unestablished proposition into `False` (or `True`) conflates **known falsity** with **absence of knowledge**. This silent collapse can introduce subtle defects, improper fallbacks, or security vulnerabilities where systems act on assumptions rather than established truth.
|
|
32
|
+
|
|
33
|
+
XoX provides a principled tri-state logical model where uncertainty is preserved across function boundaries, combined using Strong Kleene logic, and collapsed into Python booleans only when the application explicitly defines a fallback policy.
|
|
34
|
+
|
|
35
|
+
---
|
|
36
|
+
|
|
37
|
+
## Semantic Model
|
|
38
|
+
|
|
39
|
+
XoX represents three distinct, immutable logical states:
|
|
40
|
+
|
|
41
|
+
- **`xox.TRUE`**: The proposition is definitively established as true.
|
|
42
|
+
- **`xox.FALSE`**: The proposition is definitively refuted as false.
|
|
43
|
+
- **`xox.UNKNOWN`**: The proposition has not been established as true or false.
|
|
44
|
+
|
|
45
|
+
`Unknown` carries no intrinsic bias toward `True` or `False`.
|
|
46
|
+
|
|
47
|
+
### What `UNKNOWN` Is Not
|
|
48
|
+
|
|
49
|
+
To prevent semantic confusion, `xox.UNKNOWN` has strict boundaries:
|
|
50
|
+
- **Not `None`**: It represents an unresolved proposition, not the absence of an object.
|
|
51
|
+
- **Not an exception**: Runtime errors, system failures, and contract violations remain standard Python exceptions.
|
|
52
|
+
- **Not a pending async state**: It is an evaluated outcome, not an incomplete future or promise.
|
|
53
|
+
- **Not a timeout**: A timeout is an execution event, whereas `UNKNOWN` is a state of knowledge.
|
|
54
|
+
- **Not probabilistic confidence**: It indicates that truth has not been established, not a probability score.
|
|
55
|
+
- **Not an action directive**: `UNKNOWN` does not intrinsically mean retry, deny, allow, wait, fail, or default. Any action taken in response to uncertainty is defined strictly by caller policy.
|
|
56
|
+
|
|
57
|
+
---
|
|
58
|
+
|
|
59
|
+
## Installation
|
|
60
|
+
|
|
61
|
+
```bash
|
|
62
|
+
pip install project-xox
|
|
63
|
+
```
|
|
64
|
+
|
|
65
|
+
> **Note**: The package distribution name on PyPI is `project-xox`, while the Python import name is `xox`.
|
|
66
|
+
|
|
67
|
+
---
|
|
68
|
+
|
|
69
|
+
## Basic Usage
|
|
70
|
+
|
|
71
|
+
```python
|
|
72
|
+
import xox
|
|
73
|
+
|
|
74
|
+
# Canonical value constants
|
|
75
|
+
t = xox.TRUE
|
|
76
|
+
f = xox.FALSE
|
|
77
|
+
u = xox.UNKNOWN
|
|
78
|
+
|
|
79
|
+
# State inspection
|
|
80
|
+
if t.is_true():
|
|
81
|
+
print("Definitely True")
|
|
82
|
+
|
|
83
|
+
if f.is_false():
|
|
84
|
+
print("Definitely False")
|
|
85
|
+
|
|
86
|
+
if u.is_unknown():
|
|
87
|
+
print("State is indeterminate")
|
|
88
|
+
```
|
|
89
|
+
|
|
90
|
+
---
|
|
91
|
+
|
|
92
|
+
## Strict Domain Separation & Truthiness Prohibition
|
|
93
|
+
|
|
94
|
+
Python `bool` and `xox.XoX` belong to strictly separated domains. Crossing between them requires explicit operations.
|
|
95
|
+
|
|
96
|
+
### Truthiness is Prohibited
|
|
97
|
+
|
|
98
|
+
XoX values prohibit direct boolean coercion (`__bool__`). Evaluating an `XoX` instance in an `if`, `while`, `bool()`, `and`, `or`, or `not` context raises a `TypeError`:
|
|
99
|
+
|
|
100
|
+
```python
|
|
101
|
+
val = xox.UNKNOWN
|
|
102
|
+
|
|
103
|
+
# Prohibited - raises TypeError:
|
|
104
|
+
# if val:
|
|
105
|
+
# ...
|
|
106
|
+
# bool(val)
|
|
107
|
+
```
|
|
108
|
+
|
|
109
|
+
This prevents uncertainty from silently collapsing into boolean control flow.
|
|
110
|
+
|
|
111
|
+
### Domain Equality Isolation
|
|
112
|
+
|
|
113
|
+
XoX values never compare equal to native Python booleans:
|
|
114
|
+
|
|
115
|
+
```python
|
|
116
|
+
assert (xox.TRUE == True) is False
|
|
117
|
+
assert (xox.FALSE == False) is False
|
|
118
|
+
assert (xox.UNKNOWN == False) is False
|
|
119
|
+
```
|
|
120
|
+
|
|
121
|
+
---
|
|
122
|
+
|
|
123
|
+
## Ingress: Bool to XoX
|
|
124
|
+
|
|
125
|
+
To bring a Python boolean into the XoX domain, use `xox.from_bool()`:
|
|
126
|
+
|
|
127
|
+
```python
|
|
128
|
+
xox_val = xox.from_bool(True) # returns xox.TRUE
|
|
129
|
+
xox_val = xox.from_bool(False) # returns xox.FALSE
|
|
130
|
+
```
|
|
131
|
+
|
|
132
|
+
`xox.from_bool()` accepts only exact Python `bool` instances (`True` or `False`). Non-boolean values (including `1`, `0`, `None`, or truthy objects) raise a `TypeError`.
|
|
133
|
+
|
|
134
|
+
---
|
|
135
|
+
|
|
136
|
+
## Strong Kleene Logic Operations
|
|
137
|
+
|
|
138
|
+
XoX implements standard Strong Kleene ($K_3$) logic with host-level short-circuiting.
|
|
139
|
+
|
|
140
|
+
### Unary NOT (`~`)
|
|
141
|
+
|
|
142
|
+
The bitwise inversion operator `~` performs Strong Kleene negation:
|
|
143
|
+
|
|
144
|
+
```python
|
|
145
|
+
assert ~xox.TRUE == xox.FALSE
|
|
146
|
+
assert ~xox.FALSE == xox.TRUE
|
|
147
|
+
assert ~xox.UNKNOWN == xox.UNKNOWN
|
|
148
|
+
```
|
|
149
|
+
|
|
150
|
+
### Lazy Conjunction (`lazy_and`) & Disjunction (`lazy_or`)
|
|
151
|
+
|
|
152
|
+
Python evaluates binary operator operands (`&`, `|`) eagerly. To guarantee real short-circuit evaluation without evaluating unneeded branches, conjunction and disjunction require zero-argument callables:
|
|
153
|
+
|
|
154
|
+
```python
|
|
155
|
+
# Conjunction: FALSE short-circuits; RHS is never called
|
|
156
|
+
result = xox.FALSE.lazy_and(lambda: expensive_query()) # returns xox.FALSE
|
|
157
|
+
|
|
158
|
+
# Disjunction: TRUE short-circuits; RHS is never called
|
|
159
|
+
result = xox.TRUE.lazy_or(lambda: expensive_query()) # returns xox.TRUE
|
|
160
|
+
|
|
161
|
+
# When LHS cannot determine the outcome, RHS is executed exactly once:
|
|
162
|
+
result = xox.UNKNOWN.lazy_and(lambda: xox.TRUE) # returns xox.UNKNOWN
|
|
163
|
+
result = xox.UNKNOWN.lazy_or(lambda: xox.TRUE) # returns xox.TRUE
|
|
164
|
+
```
|
|
165
|
+
|
|
166
|
+
- **Short-circuiting**: If the outcome is determined by the LHS, the RHS callable executes **zero** times.
|
|
167
|
+
- **Evaluation**: When needed, the RHS callable executes **exactly once** and must return an `XoX` instance.
|
|
168
|
+
- **Exceptions**: Exceptions raised inside evaluated RHS callables propagate normally as standard Python exceptions.
|
|
169
|
+
|
|
170
|
+
---
|
|
171
|
+
|
|
172
|
+
## Egress: Collapsing Uncertainty to Python Bool
|
|
173
|
+
|
|
174
|
+
When application code must interface with a native boolean API, collapse the `XoX` value using `collapse_or()` with an explicit fallback callable:
|
|
175
|
+
|
|
176
|
+
```python
|
|
177
|
+
# TRUE and FALSE resolve directly without invoking fallback
|
|
178
|
+
assert xox.TRUE.collapse_or(lambda: False) is True
|
|
179
|
+
assert xox.FALSE.collapse_or(lambda: True) is False
|
|
180
|
+
|
|
181
|
+
# UNKNOWN executes the fallback callable exactly once
|
|
182
|
+
decision = xox.UNKNOWN.collapse_or(lambda: False) # returns False
|
|
183
|
+
```
|
|
184
|
+
|
|
185
|
+
- **Caller-Owned Policy**: The fallback callable represents an application policy decision (such as fail-closed or optimistic pass), not newly discovered truth.
|
|
186
|
+
- **Lazy Execution**: The fallback callable is evaluated only when the value is `xox.UNKNOWN`.
|
|
187
|
+
- **Type Contract**: The fallback callable must return an exact Python `bool` (`True` or `False`). Returning any other type raises a `TypeError`.
|
|
188
|
+
|
|
189
|
+
---
|
|
190
|
+
|
|
191
|
+
## Realistic Example: External Verification Gate
|
|
192
|
+
|
|
193
|
+
```python
|
|
194
|
+
import xox
|
|
195
|
+
import logging
|
|
196
|
+
|
|
197
|
+
def verify_remote_entitlement(user_id: str) -> xox.XoX:
|
|
198
|
+
"""Queries an upstream service; returns UNKNOWN if indeterminate."""
|
|
199
|
+
try:
|
|
200
|
+
response = call_auth_service(user_id)
|
|
201
|
+
if response.status == "AUTHORIZED":
|
|
202
|
+
return xox.TRUE
|
|
203
|
+
elif response.status == "DENIED":
|
|
204
|
+
return xox.FALSE
|
|
205
|
+
else:
|
|
206
|
+
# Service responded, but entitlement status is indeterminate
|
|
207
|
+
return xox.UNKNOWN
|
|
208
|
+
except NetworkTimeoutError:
|
|
209
|
+
# Runtime transport failure is handled by application logic
|
|
210
|
+
return xox.UNKNOWN
|
|
211
|
+
|
|
212
|
+
def handle_user_request(user_id: str):
|
|
213
|
+
entitlement = verify_remote_entitlement(user_id)
|
|
214
|
+
|
|
215
|
+
# 1. Explicit three-way branch
|
|
216
|
+
if entitlement.is_true():
|
|
217
|
+
grant_access()
|
|
218
|
+
elif entitlement.is_false():
|
|
219
|
+
deny_access("Explicitly denied by auth policy")
|
|
220
|
+
else: # entitlement.is_unknown()
|
|
221
|
+
# The reaction to UNKNOWN is owned by the application:
|
|
222
|
+
queue_for_manual_review(user_id)
|
|
223
|
+
|
|
224
|
+
# 2. Or explicit policy collapse at a boolean boundary (e.g., fail-closed)
|
|
225
|
+
def fail_closed_policy() -> bool:
|
|
226
|
+
logging.warning("Entitlement indeterminate for %s; applying fail-closed default.", user_id)
|
|
227
|
+
return False
|
|
228
|
+
|
|
229
|
+
can_proceed = entitlement.collapse_or(fail_closed_policy)
|
|
230
|
+
if can_proceed:
|
|
231
|
+
execute_privileged_task()
|
|
232
|
+
```
|
|
233
|
+
|
|
234
|
+
---
|
|
235
|
+
|
|
236
|
+
## Project Status: CORE 0.1.0
|
|
237
|
+
|
|
238
|
+
XoX `0.1.0` delivers the minimal public `CORE` semantic surface:
|
|
239
|
+
- Singleton constants: `xox.TRUE`, `xox.FALSE`, `xox.UNKNOWN`.
|
|
240
|
+
- Canonical ingress: `xox.from_bool()`.
|
|
241
|
+
- State inspection: `.is_true()`, `.is_false()`, `.is_unknown()`, and `==`.
|
|
242
|
+
- Strong Kleene logic: `~` (NOT), `.lazy_and()`, and `.lazy_or()`.
|
|
243
|
+
- Explicit egress: `.collapse_or()`.
|
|
244
|
+
- Strict domain separation and truthiness blocking.
|
|
245
|
+
|
|
246
|
+
Advanced capabilities (such as auditable policy tokens, evidence provenance tracking, and distributed consensus negotiation) are intentionally outside the scope of `CORE` and are not included in this release.
|
|
247
|
+
|
|
248
|
+
---
|
|
249
|
+
|
|
250
|
+
## Supported Platforms & Scope
|
|
251
|
+
|
|
252
|
+
- **Python Interpreters:** CPython 3.12, 3.13, and 3.14 (version-specific CPython extension wheels).
|
|
253
|
+
- **Supported Platform:** Linux x86_64.
|
|
254
|
+
- **Binary Compatibility Baseline:** `manylinux_2_34_x86_64` (glibc 2.34+).
|
|
255
|
+
- **Source Build MSRV:** Rust 1.83+.
|
|
256
|
+
- **Unclaimed / Unsupported:** macOS, Windows, Linux aarch64, musllinux, PyPy, GraalPy, and free-threaded CPython builds are not currently claimed or supported.
|
|
257
|
+
|
|
258
|
+
> **Note**: The binary compatibility baseline reflects the currently audited distribution artifact floor, not an intrinsic semantic limitation of XoX logic.
|
|
259
|
+
|
|
260
|
+
---
|
|
261
|
+
|
|
262
|
+
## Documentation
|
|
263
|
+
|
|
264
|
+
- [Normative Public CORE API Specification](docs/04_api/CORE_API.md)
|
|
265
|
+
- [Foundational Guarantees & Philosophy](docs/00_foundations/GUARANTEES.md)
|
|
266
|
+
- [Runtime & Portability Model](docs/03_runtime/PORTABILITY_MODEL.md)
|
|
267
|
+
|
|
268
|
+
---
|
|
269
|
+
|
|
270
|
+
## License
|
|
271
|
+
|
|
272
|
+
XoX is licensed under the [Apache-2.0 License](LICENSE).
|
|
273
|
+
|
|
@@ -0,0 +1,252 @@
|
|
|
1
|
+
# XoX
|
|
2
|
+
|
|
3
|
+
Tri-state epistemic uncertainty engine preserving explicit `True`, `False`, and `Unknown` decision semantics in Python.
|
|
4
|
+
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
## The Problem
|
|
8
|
+
|
|
9
|
+
Standard boolean logic provides only two states: `True` and `False`. When a system evaluates an assertion—such as whether an account is authorized, whether a remote record exists, or whether an external precondition holds—the state of that assertion is often indeterminate due to incomplete or unreachable information.
|
|
10
|
+
|
|
11
|
+
Coercing an unestablished proposition into `False` (or `True`) conflates **known falsity** with **absence of knowledge**. This silent collapse can introduce subtle defects, improper fallbacks, or security vulnerabilities where systems act on assumptions rather than established truth.
|
|
12
|
+
|
|
13
|
+
XoX provides a principled tri-state logical model where uncertainty is preserved across function boundaries, combined using Strong Kleene logic, and collapsed into Python booleans only when the application explicitly defines a fallback policy.
|
|
14
|
+
|
|
15
|
+
---
|
|
16
|
+
|
|
17
|
+
## Semantic Model
|
|
18
|
+
|
|
19
|
+
XoX represents three distinct, immutable logical states:
|
|
20
|
+
|
|
21
|
+
- **`xox.TRUE`**: The proposition is definitively established as true.
|
|
22
|
+
- **`xox.FALSE`**: The proposition is definitively refuted as false.
|
|
23
|
+
- **`xox.UNKNOWN`**: The proposition has not been established as true or false.
|
|
24
|
+
|
|
25
|
+
`Unknown` carries no intrinsic bias toward `True` or `False`.
|
|
26
|
+
|
|
27
|
+
### What `UNKNOWN` Is Not
|
|
28
|
+
|
|
29
|
+
To prevent semantic confusion, `xox.UNKNOWN` has strict boundaries:
|
|
30
|
+
- **Not `None`**: It represents an unresolved proposition, not the absence of an object.
|
|
31
|
+
- **Not an exception**: Runtime errors, system failures, and contract violations remain standard Python exceptions.
|
|
32
|
+
- **Not a pending async state**: It is an evaluated outcome, not an incomplete future or promise.
|
|
33
|
+
- **Not a timeout**: A timeout is an execution event, whereas `UNKNOWN` is a state of knowledge.
|
|
34
|
+
- **Not probabilistic confidence**: It indicates that truth has not been established, not a probability score.
|
|
35
|
+
- **Not an action directive**: `UNKNOWN` does not intrinsically mean retry, deny, allow, wait, fail, or default. Any action taken in response to uncertainty is defined strictly by caller policy.
|
|
36
|
+
|
|
37
|
+
---
|
|
38
|
+
|
|
39
|
+
## Installation
|
|
40
|
+
|
|
41
|
+
```bash
|
|
42
|
+
pip install project-xox
|
|
43
|
+
```
|
|
44
|
+
|
|
45
|
+
> **Note**: The package distribution name on PyPI is `project-xox`, while the Python import name is `xox`.
|
|
46
|
+
|
|
47
|
+
---
|
|
48
|
+
|
|
49
|
+
## Basic Usage
|
|
50
|
+
|
|
51
|
+
```python
|
|
52
|
+
import xox
|
|
53
|
+
|
|
54
|
+
# Canonical value constants
|
|
55
|
+
t = xox.TRUE
|
|
56
|
+
f = xox.FALSE
|
|
57
|
+
u = xox.UNKNOWN
|
|
58
|
+
|
|
59
|
+
# State inspection
|
|
60
|
+
if t.is_true():
|
|
61
|
+
print("Definitely True")
|
|
62
|
+
|
|
63
|
+
if f.is_false():
|
|
64
|
+
print("Definitely False")
|
|
65
|
+
|
|
66
|
+
if u.is_unknown():
|
|
67
|
+
print("State is indeterminate")
|
|
68
|
+
```
|
|
69
|
+
|
|
70
|
+
---
|
|
71
|
+
|
|
72
|
+
## Strict Domain Separation & Truthiness Prohibition
|
|
73
|
+
|
|
74
|
+
Python `bool` and `xox.XoX` belong to strictly separated domains. Crossing between them requires explicit operations.
|
|
75
|
+
|
|
76
|
+
### Truthiness is Prohibited
|
|
77
|
+
|
|
78
|
+
XoX values prohibit direct boolean coercion (`__bool__`). Evaluating an `XoX` instance in an `if`, `while`, `bool()`, `and`, `or`, or `not` context raises a `TypeError`:
|
|
79
|
+
|
|
80
|
+
```python
|
|
81
|
+
val = xox.UNKNOWN
|
|
82
|
+
|
|
83
|
+
# Prohibited - raises TypeError:
|
|
84
|
+
# if val:
|
|
85
|
+
# ...
|
|
86
|
+
# bool(val)
|
|
87
|
+
```
|
|
88
|
+
|
|
89
|
+
This prevents uncertainty from silently collapsing into boolean control flow.
|
|
90
|
+
|
|
91
|
+
### Domain Equality Isolation
|
|
92
|
+
|
|
93
|
+
XoX values never compare equal to native Python booleans:
|
|
94
|
+
|
|
95
|
+
```python
|
|
96
|
+
assert (xox.TRUE == True) is False
|
|
97
|
+
assert (xox.FALSE == False) is False
|
|
98
|
+
assert (xox.UNKNOWN == False) is False
|
|
99
|
+
```
|
|
100
|
+
|
|
101
|
+
---
|
|
102
|
+
|
|
103
|
+
## Ingress: Bool to XoX
|
|
104
|
+
|
|
105
|
+
To bring a Python boolean into the XoX domain, use `xox.from_bool()`:
|
|
106
|
+
|
|
107
|
+
```python
|
|
108
|
+
xox_val = xox.from_bool(True) # returns xox.TRUE
|
|
109
|
+
xox_val = xox.from_bool(False) # returns xox.FALSE
|
|
110
|
+
```
|
|
111
|
+
|
|
112
|
+
`xox.from_bool()` accepts only exact Python `bool` instances (`True` or `False`). Non-boolean values (including `1`, `0`, `None`, or truthy objects) raise a `TypeError`.
|
|
113
|
+
|
|
114
|
+
---
|
|
115
|
+
|
|
116
|
+
## Strong Kleene Logic Operations
|
|
117
|
+
|
|
118
|
+
XoX implements standard Strong Kleene ($K_3$) logic with host-level short-circuiting.
|
|
119
|
+
|
|
120
|
+
### Unary NOT (`~`)
|
|
121
|
+
|
|
122
|
+
The bitwise inversion operator `~` performs Strong Kleene negation:
|
|
123
|
+
|
|
124
|
+
```python
|
|
125
|
+
assert ~xox.TRUE == xox.FALSE
|
|
126
|
+
assert ~xox.FALSE == xox.TRUE
|
|
127
|
+
assert ~xox.UNKNOWN == xox.UNKNOWN
|
|
128
|
+
```
|
|
129
|
+
|
|
130
|
+
### Lazy Conjunction (`lazy_and`) & Disjunction (`lazy_or`)
|
|
131
|
+
|
|
132
|
+
Python evaluates binary operator operands (`&`, `|`) eagerly. To guarantee real short-circuit evaluation without evaluating unneeded branches, conjunction and disjunction require zero-argument callables:
|
|
133
|
+
|
|
134
|
+
```python
|
|
135
|
+
# Conjunction: FALSE short-circuits; RHS is never called
|
|
136
|
+
result = xox.FALSE.lazy_and(lambda: expensive_query()) # returns xox.FALSE
|
|
137
|
+
|
|
138
|
+
# Disjunction: TRUE short-circuits; RHS is never called
|
|
139
|
+
result = xox.TRUE.lazy_or(lambda: expensive_query()) # returns xox.TRUE
|
|
140
|
+
|
|
141
|
+
# When LHS cannot determine the outcome, RHS is executed exactly once:
|
|
142
|
+
result = xox.UNKNOWN.lazy_and(lambda: xox.TRUE) # returns xox.UNKNOWN
|
|
143
|
+
result = xox.UNKNOWN.lazy_or(lambda: xox.TRUE) # returns xox.TRUE
|
|
144
|
+
```
|
|
145
|
+
|
|
146
|
+
- **Short-circuiting**: If the outcome is determined by the LHS, the RHS callable executes **zero** times.
|
|
147
|
+
- **Evaluation**: When needed, the RHS callable executes **exactly once** and must return an `XoX` instance.
|
|
148
|
+
- **Exceptions**: Exceptions raised inside evaluated RHS callables propagate normally as standard Python exceptions.
|
|
149
|
+
|
|
150
|
+
---
|
|
151
|
+
|
|
152
|
+
## Egress: Collapsing Uncertainty to Python Bool
|
|
153
|
+
|
|
154
|
+
When application code must interface with a native boolean API, collapse the `XoX` value using `collapse_or()` with an explicit fallback callable:
|
|
155
|
+
|
|
156
|
+
```python
|
|
157
|
+
# TRUE and FALSE resolve directly without invoking fallback
|
|
158
|
+
assert xox.TRUE.collapse_or(lambda: False) is True
|
|
159
|
+
assert xox.FALSE.collapse_or(lambda: True) is False
|
|
160
|
+
|
|
161
|
+
# UNKNOWN executes the fallback callable exactly once
|
|
162
|
+
decision = xox.UNKNOWN.collapse_or(lambda: False) # returns False
|
|
163
|
+
```
|
|
164
|
+
|
|
165
|
+
- **Caller-Owned Policy**: The fallback callable represents an application policy decision (such as fail-closed or optimistic pass), not newly discovered truth.
|
|
166
|
+
- **Lazy Execution**: The fallback callable is evaluated only when the value is `xox.UNKNOWN`.
|
|
167
|
+
- **Type Contract**: The fallback callable must return an exact Python `bool` (`True` or `False`). Returning any other type raises a `TypeError`.
|
|
168
|
+
|
|
169
|
+
---
|
|
170
|
+
|
|
171
|
+
## Realistic Example: External Verification Gate
|
|
172
|
+
|
|
173
|
+
```python
|
|
174
|
+
import xox
|
|
175
|
+
import logging
|
|
176
|
+
|
|
177
|
+
def verify_remote_entitlement(user_id: str) -> xox.XoX:
|
|
178
|
+
"""Queries an upstream service; returns UNKNOWN if indeterminate."""
|
|
179
|
+
try:
|
|
180
|
+
response = call_auth_service(user_id)
|
|
181
|
+
if response.status == "AUTHORIZED":
|
|
182
|
+
return xox.TRUE
|
|
183
|
+
elif response.status == "DENIED":
|
|
184
|
+
return xox.FALSE
|
|
185
|
+
else:
|
|
186
|
+
# Service responded, but entitlement status is indeterminate
|
|
187
|
+
return xox.UNKNOWN
|
|
188
|
+
except NetworkTimeoutError:
|
|
189
|
+
# Runtime transport failure is handled by application logic
|
|
190
|
+
return xox.UNKNOWN
|
|
191
|
+
|
|
192
|
+
def handle_user_request(user_id: str):
|
|
193
|
+
entitlement = verify_remote_entitlement(user_id)
|
|
194
|
+
|
|
195
|
+
# 1. Explicit three-way branch
|
|
196
|
+
if entitlement.is_true():
|
|
197
|
+
grant_access()
|
|
198
|
+
elif entitlement.is_false():
|
|
199
|
+
deny_access("Explicitly denied by auth policy")
|
|
200
|
+
else: # entitlement.is_unknown()
|
|
201
|
+
# The reaction to UNKNOWN is owned by the application:
|
|
202
|
+
queue_for_manual_review(user_id)
|
|
203
|
+
|
|
204
|
+
# 2. Or explicit policy collapse at a boolean boundary (e.g., fail-closed)
|
|
205
|
+
def fail_closed_policy() -> bool:
|
|
206
|
+
logging.warning("Entitlement indeterminate for %s; applying fail-closed default.", user_id)
|
|
207
|
+
return False
|
|
208
|
+
|
|
209
|
+
can_proceed = entitlement.collapse_or(fail_closed_policy)
|
|
210
|
+
if can_proceed:
|
|
211
|
+
execute_privileged_task()
|
|
212
|
+
```
|
|
213
|
+
|
|
214
|
+
---
|
|
215
|
+
|
|
216
|
+
## Project Status: CORE 0.1.0
|
|
217
|
+
|
|
218
|
+
XoX `0.1.0` delivers the minimal public `CORE` semantic surface:
|
|
219
|
+
- Singleton constants: `xox.TRUE`, `xox.FALSE`, `xox.UNKNOWN`.
|
|
220
|
+
- Canonical ingress: `xox.from_bool()`.
|
|
221
|
+
- State inspection: `.is_true()`, `.is_false()`, `.is_unknown()`, and `==`.
|
|
222
|
+
- Strong Kleene logic: `~` (NOT), `.lazy_and()`, and `.lazy_or()`.
|
|
223
|
+
- Explicit egress: `.collapse_or()`.
|
|
224
|
+
- Strict domain separation and truthiness blocking.
|
|
225
|
+
|
|
226
|
+
Advanced capabilities (such as auditable policy tokens, evidence provenance tracking, and distributed consensus negotiation) are intentionally outside the scope of `CORE` and are not included in this release.
|
|
227
|
+
|
|
228
|
+
---
|
|
229
|
+
|
|
230
|
+
## Supported Platforms & Scope
|
|
231
|
+
|
|
232
|
+
- **Python Interpreters:** CPython 3.12, 3.13, and 3.14 (version-specific CPython extension wheels).
|
|
233
|
+
- **Supported Platform:** Linux x86_64.
|
|
234
|
+
- **Binary Compatibility Baseline:** `manylinux_2_34_x86_64` (glibc 2.34+).
|
|
235
|
+
- **Source Build MSRV:** Rust 1.83+.
|
|
236
|
+
- **Unclaimed / Unsupported:** macOS, Windows, Linux aarch64, musllinux, PyPy, GraalPy, and free-threaded CPython builds are not currently claimed or supported.
|
|
237
|
+
|
|
238
|
+
> **Note**: The binary compatibility baseline reflects the currently audited distribution artifact floor, not an intrinsic semantic limitation of XoX logic.
|
|
239
|
+
|
|
240
|
+
---
|
|
241
|
+
|
|
242
|
+
## Documentation
|
|
243
|
+
|
|
244
|
+
- [Normative Public CORE API Specification](docs/04_api/CORE_API.md)
|
|
245
|
+
- [Foundational Guarantees & Philosophy](docs/00_foundations/GUARANTEES.md)
|
|
246
|
+
- [Runtime & Portability Model](docs/03_runtime/PORTABILITY_MODEL.md)
|
|
247
|
+
|
|
248
|
+
---
|
|
249
|
+
|
|
250
|
+
## License
|
|
251
|
+
|
|
252
|
+
XoX is licensed under the [Apache-2.0 License](LICENSE).
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
[build-system]
|
|
2
|
+
requires = ["maturin>=1.5,<2.0"]
|
|
3
|
+
build-backend = "maturin"
|
|
4
|
+
|
|
5
|
+
[project]
|
|
6
|
+
name = "project-xox"
|
|
7
|
+
version = "0.1.0"
|
|
8
|
+
description = "Tri-state epistemic uncertainty engine preserving explicit True, False, and Unknown decision semantics"
|
|
9
|
+
readme = "README.md"
|
|
10
|
+
requires-python = ">=3.12"
|
|
11
|
+
license = "Apache-2.0"
|
|
12
|
+
license-files = ["LICENSE"]
|
|
13
|
+
classifiers = [
|
|
14
|
+
"Programming Language :: Python :: 3",
|
|
15
|
+
"Programming Language :: Python :: 3 :: Only",
|
|
16
|
+
"Programming Language :: Python :: 3.12",
|
|
17
|
+
"Programming Language :: Python :: 3.13",
|
|
18
|
+
"Programming Language :: Python :: 3.14",
|
|
19
|
+
"Programming Language :: Python :: Implementation :: CPython",
|
|
20
|
+
"Programming Language :: Rust",
|
|
21
|
+
"License :: OSI Approved :: Apache Software License",
|
|
22
|
+
"Operating System :: POSIX :: Linux",
|
|
23
|
+
]
|
|
24
|
+
|
|
25
|
+
[project.urls]
|
|
26
|
+
Homepage = "https://github.com/linuxx88/XoX"
|
|
27
|
+
Documentation = "https://github.com/linuxx88/XoX/blob/main/docs/04_api/CORE_API.md"
|
|
28
|
+
|
|
29
|
+
[tool.maturin]
|
|
30
|
+
module-name = "xox"
|
|
31
|
+
features = ["pyo3/extension-module"]
|
|
@@ -0,0 +1,161 @@
|
|
|
1
|
+
//! PyO3 bindings exposing the XoX CORE API to Python.
|
|
2
|
+
|
|
3
|
+
use pyo3::exceptions::PyTypeError;
|
|
4
|
+
use pyo3::prelude::*;
|
|
5
|
+
use pyo3::types::PyBool;
|
|
6
|
+
|
|
7
|
+
use crate::core::XoXValue;
|
|
8
|
+
|
|
9
|
+
/// Python representation of an immutable XoX tri-state logical value.
|
|
10
|
+
#[pyclass(name = "XoX", frozen, from_py_object)]
|
|
11
|
+
#[derive(Clone, Copy, Debug)]
|
|
12
|
+
pub struct PyXoX(pub XoXValue);
|
|
13
|
+
|
|
14
|
+
#[pymethods]
|
|
15
|
+
impl PyXoX {
|
|
16
|
+
/// Inspect if the value is definitively True.
|
|
17
|
+
pub fn is_true(&self) -> bool {
|
|
18
|
+
self.0 == XoXValue::True
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
/// Inspect if the value is definitively False.
|
|
22
|
+
pub fn is_false(&self) -> bool {
|
|
23
|
+
self.0 == XoXValue::False
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
/// Inspect if the value is Unknown.
|
|
27
|
+
pub fn is_unknown(&self) -> bool {
|
|
28
|
+
self.0 == XoXValue::Unknown
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
/// Strong Kleene unary NOT (~).
|
|
32
|
+
pub fn __invert__(&self) -> Self {
|
|
33
|
+
PyXoX(self.0.not())
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
/// Strong Kleene lazy conjunction (AND).
|
|
37
|
+
pub fn lazy_and(&self, rhs: &Bound<'_, PyAny>) -> PyResult<Self> {
|
|
38
|
+
if !rhs.is_callable() {
|
|
39
|
+
return Err(PyTypeError::new_err(
|
|
40
|
+
"lazy_and() requires a zero-argument callable returning XoX.",
|
|
41
|
+
));
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
if self.0.should_short_circuit_and() {
|
|
45
|
+
return Ok(PyXoX(XoXValue::False));
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
let res = rhs.call0()?;
|
|
49
|
+
let rhs_val = match res.extract::<PyRef<PyXoX>>() {
|
|
50
|
+
Ok(r) => r.0,
|
|
51
|
+
Err(_) => {
|
|
52
|
+
return Err(PyTypeError::new_err(
|
|
53
|
+
"RHS callable in lazy_and must return an XoX value (xox.TRUE, xox.FALSE, xox.UNKNOWN).",
|
|
54
|
+
))
|
|
55
|
+
}
|
|
56
|
+
};
|
|
57
|
+
|
|
58
|
+
Ok(PyXoX(self.0.and(rhs_val)))
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
/// Strong Kleene lazy disjunction (OR).
|
|
62
|
+
pub fn lazy_or(&self, rhs: &Bound<'_, PyAny>) -> PyResult<Self> {
|
|
63
|
+
if !rhs.is_callable() {
|
|
64
|
+
return Err(PyTypeError::new_err(
|
|
65
|
+
"lazy_or() requires a zero-argument callable returning XoX.",
|
|
66
|
+
));
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
if self.0.should_short_circuit_or() {
|
|
70
|
+
return Ok(PyXoX(XoXValue::True));
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
let res = rhs.call0()?;
|
|
74
|
+
let rhs_val = match res.extract::<PyRef<PyXoX>>() {
|
|
75
|
+
Ok(r) => r.0,
|
|
76
|
+
Err(_) => {
|
|
77
|
+
return Err(PyTypeError::new_err(
|
|
78
|
+
"RHS callable in lazy_or must return an XoX value (xox.TRUE, xox.FALSE, xox.UNKNOWN).",
|
|
79
|
+
))
|
|
80
|
+
}
|
|
81
|
+
};
|
|
82
|
+
|
|
83
|
+
Ok(PyXoX(self.0.or(rhs_val)))
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
/// Explicit lazy collapse of uncertainty into Python bool.
|
|
87
|
+
pub fn collapse_or(&self, fallback: &Bound<'_, PyAny>) -> PyResult<bool> {
|
|
88
|
+
if !fallback.is_callable() {
|
|
89
|
+
return Err(PyTypeError::new_err(
|
|
90
|
+
"collapse_or() requires a zero-argument callable returning Python bool.",
|
|
91
|
+
));
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
match self.0 {
|
|
95
|
+
XoXValue::True => Ok(true),
|
|
96
|
+
XoXValue::False => Ok(false),
|
|
97
|
+
XoXValue::Unknown => {
|
|
98
|
+
let res = fallback.call0()?;
|
|
99
|
+
if !res.is_exact_instance_of::<PyBool>() {
|
|
100
|
+
return Err(PyTypeError::new_err(
|
|
101
|
+
"Collapse fallback callable must return an exact Python bool (True or False).",
|
|
102
|
+
));
|
|
103
|
+
}
|
|
104
|
+
res.extract::<bool>()
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
/// Explicitly block Python truthiness evaluation for all states.
|
|
110
|
+
pub fn __bool__(&self) -> PyResult<bool> {
|
|
111
|
+
Err(PyTypeError::new_err(
|
|
112
|
+
"Cannot use XoX value directly in boolean context. Use '.is_true()', pattern match, or '.collapse_or(lambda: fallback)' to resolve uncertainty explicitly.",
|
|
113
|
+
))
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
/// State-identity equality. Comparing with Python bool evaluates to False.
|
|
117
|
+
pub fn __eq__(&self, other: &Bound<'_, PyAny>) -> PyResult<bool> {
|
|
118
|
+
if let Ok(other_xox) = other.extract::<PyRef<PyXoX>>() {
|
|
119
|
+
Ok(self.0 == other_xox.0)
|
|
120
|
+
} else {
|
|
121
|
+
Ok(false)
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
pub fn __ne__(&self, other: &Bound<'_, PyAny>) -> PyResult<bool> {
|
|
126
|
+
Ok(!self.__eq__(other)?)
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
/// Consistent hashing for dict/set collection isolation.
|
|
130
|
+
pub fn __hash__(&self) -> isize {
|
|
131
|
+
match self.0 {
|
|
132
|
+
XoXValue::True => 1_000_003,
|
|
133
|
+
XoXValue::False => 1_000_004,
|
|
134
|
+
XoXValue::Unknown => 1_000_005,
|
|
135
|
+
}
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
pub fn __repr__(&self) -> &'static str {
|
|
139
|
+
match self.0 {
|
|
140
|
+
XoXValue::True => "xox.TRUE",
|
|
141
|
+
XoXValue::False => "xox.FALSE",
|
|
142
|
+
XoXValue::Unknown => "xox.UNKNOWN",
|
|
143
|
+
}
|
|
144
|
+
}
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
/// Canonical single Bool-to-XoX ingress function.
|
|
148
|
+
#[pyfunction]
|
|
149
|
+
pub fn from_bool(value: &Bound<'_, PyAny>) -> PyResult<PyXoX> {
|
|
150
|
+
if !value.is_exact_instance_of::<PyBool>() {
|
|
151
|
+
return Err(PyTypeError::new_err(
|
|
152
|
+
"xox.from_bool() requires an exact Python bool (True or False).",
|
|
153
|
+
));
|
|
154
|
+
}
|
|
155
|
+
let b: bool = value.extract()?;
|
|
156
|
+
if b {
|
|
157
|
+
Ok(PyXoX(XoXValue::True))
|
|
158
|
+
} else {
|
|
159
|
+
Ok(PyXoX(XoXValue::False))
|
|
160
|
+
}
|
|
161
|
+
}
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
//! Pure Rust semantic core for XoX tri-state epistemic logic.
|
|
2
|
+
//!
|
|
3
|
+
//! This module contains zero dependencies on Python, PyO3, or runtime execution environments.
|
|
4
|
+
|
|
5
|
+
/// Canonical tri-state logical value.
|
|
6
|
+
#[derive(Copy, Clone, Eq, PartialEq, Hash, Debug)]
|
|
7
|
+
pub enum XoXValue {
|
|
8
|
+
True,
|
|
9
|
+
False,
|
|
10
|
+
Unknown,
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
impl XoXValue {
|
|
14
|
+
/// Strong Kleene unary NOT (~).
|
|
15
|
+
#[inline]
|
|
16
|
+
pub const fn not(self) -> Self {
|
|
17
|
+
match self {
|
|
18
|
+
Self::True => Self::False,
|
|
19
|
+
Self::False => Self::True,
|
|
20
|
+
Self::Unknown => Self::Unknown,
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
/// Strong Kleene binary conjunction (AND) for already-evaluated operands.
|
|
25
|
+
#[inline]
|
|
26
|
+
pub const fn and(self, other: Self) -> Self {
|
|
27
|
+
match (self, other) {
|
|
28
|
+
(Self::False, _) | (_, Self::False) => Self::False,
|
|
29
|
+
(Self::True, Self::True) => Self::True,
|
|
30
|
+
(Self::True, Self::Unknown)
|
|
31
|
+
| (Self::Unknown, Self::True)
|
|
32
|
+
| (Self::Unknown, Self::Unknown) => Self::Unknown,
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
/// Strong Kleene binary disjunction (OR) for already-evaluated operands.
|
|
37
|
+
#[inline]
|
|
38
|
+
pub const fn or(self, other: Self) -> Self {
|
|
39
|
+
match (self, other) {
|
|
40
|
+
(Self::True, _) | (_, Self::True) => Self::True,
|
|
41
|
+
(Self::False, Self::False) => Self::False,
|
|
42
|
+
(Self::False, Self::Unknown)
|
|
43
|
+
| (Self::Unknown, Self::False)
|
|
44
|
+
| (Self::Unknown, Self::Unknown) => Self::Unknown,
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
/// Returns true if an AND expression with `self` as LHS short-circuits (i.e. self is False).
|
|
49
|
+
#[inline]
|
|
50
|
+
pub const fn should_short_circuit_and(self) -> bool {
|
|
51
|
+
matches!(self, Self::False)
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
/// Returns true if an OR expression with `self` as LHS short-circuits (i.e. self is True).
|
|
55
|
+
#[inline]
|
|
56
|
+
pub const fn should_short_circuit_or(self) -> bool {
|
|
57
|
+
matches!(self, Self::True)
|
|
58
|
+
}
|
|
59
|
+
}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
//! XoX epistemic tri-state logic library and Python extension module.
|
|
2
|
+
|
|
3
|
+
pub mod binding;
|
|
4
|
+
pub mod core;
|
|
5
|
+
|
|
6
|
+
use pyo3::prelude::*;
|
|
7
|
+
|
|
8
|
+
use crate::binding::{from_bool, PyXoX};
|
|
9
|
+
use crate::core::XoXValue;
|
|
10
|
+
|
|
11
|
+
/// XoX core Python module.
|
|
12
|
+
#[pymodule]
|
|
13
|
+
fn xox(m: &Bound<'_, PyModule>) -> PyResult<()> {
|
|
14
|
+
m.add_class::<PyXoX>()?;
|
|
15
|
+
m.add_function(wrap_pyfunction!(from_bool, m)?)?;
|
|
16
|
+
|
|
17
|
+
// Canonical singleton constants
|
|
18
|
+
m.add("TRUE", PyXoX(XoXValue::True))?;
|
|
19
|
+
m.add("FALSE", PyXoX(XoXValue::False))?;
|
|
20
|
+
m.add("UNKNOWN", PyXoX(XoXValue::Unknown))?;
|
|
21
|
+
|
|
22
|
+
Ok(())
|
|
23
|
+
}
|