socratic-engine 0.2.0__tar.gz → 0.2.2__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.
- {socratic_engine-0.2.0/socratic_engine.egg-info → socratic_engine-0.2.2}/PKG-INFO +117 -30
- {socratic_engine-0.2.0 → socratic_engine-0.2.2}/README.md +115 -28
- {socratic_engine-0.2.0 → socratic_engine-0.2.2}/pyproject.toml +2 -2
- {socratic_engine-0.2.0 → socratic_engine-0.2.2}/socratic_engine/__init__.py +1 -1
- socratic_engine-0.2.2/socratic_engine/bridge_statecanon.py +219 -0
- {socratic_engine-0.2.0 → socratic_engine-0.2.2}/socratic_engine/cli.py +4 -4
- {socratic_engine-0.2.0 → socratic_engine-0.2.2}/socratic_engine/engine.py +11 -11
- {socratic_engine-0.2.0 → socratic_engine-0.2.2}/socratic_engine/mcp_server.py +44 -14
- {socratic_engine-0.2.0 → socratic_engine-0.2.2}/socratic_engine/tree.py +13 -5
- {socratic_engine-0.2.0 → socratic_engine-0.2.2/socratic_engine.egg-info}/PKG-INFO +117 -30
- {socratic_engine-0.2.0 → socratic_engine-0.2.2}/socratic_engine.egg-info/SOURCES.txt +3 -0
- socratic_engine-0.2.2/tests/test_bridge_statecanon.py +294 -0
- socratic_engine-0.2.2/tests/test_cli.py +154 -0
- socratic_engine-0.2.2/tests/test_engine.py +1320 -0
- socratic_engine-0.2.2/tests/test_mcp_server.py +254 -0
- socratic_engine-0.2.0/tests/test_engine.py +0 -434
- socratic_engine-0.2.0/tests/test_mcp_server.py +0 -89
- {socratic_engine-0.2.0 → socratic_engine-0.2.2}/LICENSE +0 -0
- {socratic_engine-0.2.0 → socratic_engine-0.2.2}/setup.cfg +0 -0
- {socratic_engine-0.2.0 → socratic_engine-0.2.2}/socratic_engine.egg-info/dependency_links.txt +0 -0
- {socratic_engine-0.2.0 → socratic_engine-0.2.2}/socratic_engine.egg-info/entry_points.txt +0 -0
- {socratic_engine-0.2.0 → socratic_engine-0.2.2}/socratic_engine.egg-info/requires.txt +0 -0
- {socratic_engine-0.2.0 → socratic_engine-0.2.2}/socratic_engine.egg-info/top_level.txt +0 -0
- {socratic_engine-0.2.0 → socratic_engine-0.2.2}/tests/test_state_canon_integration.py +0 -0
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: socratic-engine
|
|
3
|
-
Version: 0.2.
|
|
3
|
+
Version: 0.2.2
|
|
4
4
|
Summary: Externalized epistemic scaffolding for AI agents. Recursive boolean certification trees.
|
|
5
|
-
License:
|
|
5
|
+
License: Apache-2.0
|
|
6
6
|
Keywords: socratic,epistemic,verification,certification,boolean-trees,trivalent-logic,mcp
|
|
7
7
|
Classifier: Development Status :: 3 - Alpha
|
|
8
8
|
Classifier: Intended Audience :: Developers
|
|
@@ -32,7 +32,7 @@ Dynamic: license-file
|
|
|
32
32
|
|
|
33
33
|
The engine is deliberately small. It does not try to make an LLM "smarter". It gives the model a formal structure in which complex questioning can be proposed, executed recursively, inspected, and diagnosed **outside the model's token-generation loop**.
|
|
34
34
|
|
|
35
|
-
**Status:**
|
|
35
|
+
**Status:** v0.2.2 published on PyPI — core engine, VSL tree parser, CLI, MCP bridge, dialectical operator, pragmatic predicates, caching, rate limiting, CI (pytest 3.10–3.12 + coverage gate at 90%), benchmarks, a 189-test suite at 100% statement coverage, and the official state-canon bridge ([`bridge_statecanon.py`](./socratic_engine/bridge_statecanon.py)) with end-to-end examples are working. The broader claim — that externalizing recursive structure improves reliability on tasks that exceed a model's implicit recursive reasoning capacity — is an experimental hypothesis, not a proclamation.
|
|
36
36
|
|
|
37
37
|
---
|
|
38
38
|
|
|
@@ -83,6 +83,7 @@ At its core, the engine evaluates trees composed of:
|
|
|
83
83
|
- `NOT`
|
|
84
84
|
- `XOR`
|
|
85
85
|
- `IMPLIES`
|
|
86
|
+
- `DIALECTICAL_AND`
|
|
86
87
|
- registered predicates
|
|
87
88
|
- boolean literals
|
|
88
89
|
|
|
@@ -419,6 +420,7 @@ The engine implements:
|
|
|
419
420
|
| `NOT` | invert one proposition | child must be certified |
|
|
420
421
|
| `XOR` | exactly one true branch | children must be certified |
|
|
421
422
|
| `IMPLIES` | antecedent → consequent | antecedent and consequent must be certified when relevant |
|
|
423
|
+
| `DIALECTICAL_AND` | contradiction is not rejection — a certified TRUE/FALSE conflict yields `UNKNOWN` (certified), with thesis/antithesis in metadata | in conflict: all children certified (the contradiction itself is a fact); without conflict: all children certified |
|
|
422
424
|
|
|
423
425
|
The distinction matters for diagnosis.
|
|
424
426
|
|
|
@@ -602,7 +604,7 @@ The model is therefore not trusted to produce executable logic merely because th
|
|
|
602
604
|
|
|
603
605
|
## Built-in predicates
|
|
604
606
|
|
|
605
|
-
The engine currently ships with deterministic predicates for structural classification:
|
|
607
|
+
The engine currently ships with deterministic predicates for structural classification and pragmatic behaviour:
|
|
606
608
|
|
|
607
609
|
| Predicate | Question | Missing subject |
|
|
608
610
|
|---|---|---|
|
|
@@ -612,9 +614,14 @@ The engine currently ships with deterministic predicates for structural classifi
|
|
|
612
614
|
| `type_has` | does TYPE contain a token? | `UNKNOWN` |
|
|
613
615
|
| `doc_has_status` | does a document declare a status? | evaluated from document |
|
|
614
616
|
| `ctx_has` | does context contain a key/value? | `UNKNOWN` |
|
|
617
|
+
| `trend_up` | is a time series growing sustainably (min_delta, noise guard)? | `UNKNOWN` |
|
|
618
|
+
| `trend_down` | is a time series falling sustainably (min_delta, noise guard)? | `UNKNOWN` |
|
|
619
|
+
| `feedback_loop` | does a topology have a closed cycle (length ≥ 2) through target? | `UNKNOWN` |
|
|
615
620
|
|
|
616
621
|
Registering custom predicates is the intended extension point.
|
|
617
622
|
|
|
623
|
+
Costly predicates can be wrapped with `@cached(ttl=...)` — hits are marked `metadata.cached=True` (historical evidence, not a fresh measurement), `UNKNOWN` is never cached, and `engine.cache.clear()` forces re-verification.
|
|
624
|
+
|
|
618
625
|
---
|
|
619
626
|
|
|
620
627
|
## MCP bridge
|
|
@@ -640,13 +647,70 @@ The current bridge exposes:
|
|
|
640
647
|
| `socratic_build` | validate a proposed reasoning tree |
|
|
641
648
|
| `socratic_evaluate` | execute a tree against context |
|
|
642
649
|
| `socratic_diagnose` | return inverse failure traces |
|
|
650
|
+
| `socratic_canon_query` | (opt-in) query state-canon through the registered bridge |
|
|
643
651
|
|
|
644
652
|
The MCP layer is intentionally thin.
|
|
645
653
|
|
|
654
|
+
It includes a per-tool sliding-window rate limiter (`SOCRATIC_MCP_RATE_LIMIT`, default 100 calls / `SOCRATIC_MCP_RATE_WINDOW`, default 60s): a rate-limited call returns error `-32029` with `retry_after_s` — a transient signal, not a rejection.
|
|
655
|
+
|
|
646
656
|
The reasoning contract remains in the engine.
|
|
647
657
|
|
|
648
658
|
---
|
|
649
659
|
|
|
660
|
+
## Bridge to `state-canon` (official)
|
|
661
|
+
|
|
662
|
+
The official integration between the engine and **state-canon** lives in
|
|
663
|
+
[`socratic_engine/bridge_statecanon.py`](./socratic_engine/bridge_statecanon.py).
|
|
664
|
+
|
|
665
|
+
**Division of labor** (from the "Relationship to `state-canon`" section):
|
|
666
|
+
|
|
667
|
+
> **state-canon grounds the agent in what is observed.**
|
|
668
|
+
> **socratic-engine constrains how claims about that state are evaluated.**
|
|
669
|
+
|
|
670
|
+
The bridge registers four predicates on any `SocraticEngine`, all prefixed
|
|
671
|
+
`canon_` — they query the provider (the reconciled ground truth, *observed*)
|
|
672
|
+
and convert the result into certified evidence:
|
|
673
|
+
|
|
674
|
+
| Predicate | Question it answers |
|
|
675
|
+
|---|---|
|
|
676
|
+
| `canon_query(domain, filter)` | Is there at least one record matching the filter? |
|
|
677
|
+
| `canon_matches(domain, filter, expected)` | Do the records match the expected fields exactly? |
|
|
678
|
+
| `canon_field_equals(domain, filter, field, expected)` | Does a specific field equal the expected value? |
|
|
679
|
+
| `canon_drift(domain, filter, declared_field, observed_field)` | Have declared and observed drifted apart? |
|
|
680
|
+
|
|
681
|
+
`filter` and `expected` accept either a JSON string or a Python dict.
|
|
682
|
+
|
|
683
|
+
Semantics follow the engine's epistemology (R9 — no silent concession):
|
|
684
|
+
|
|
685
|
+
- **TRUE / FALSE** are returned **certified** (structural evidence exists).
|
|
686
|
+
- **UNKNOWN** is returned **uncertified** when there is no evidence — no
|
|
687
|
+
records, an unknown filter field, a missing field, or an unparseable
|
|
688
|
+
filter. No inventing, no silent routing to `else_home`.
|
|
689
|
+
|
|
690
|
+
```python
|
|
691
|
+
from socratic_engine import SocraticEngine
|
|
692
|
+
from socratic_engine.bridge_statecanon import StateCanonBridge
|
|
693
|
+
|
|
694
|
+
eng = SocraticEngine()
|
|
695
|
+
bridge = StateCanonBridge(eng, provider) # provider: state_canon.StateProvider
|
|
696
|
+
|
|
697
|
+
ev = eng.evaluate({"op": "DIALECTICAL_AND", "children": [
|
|
698
|
+
{"predicate": "canon_field_equals",
|
|
699
|
+
"args": ["services", '{"name": "api"}', "declared_active", True]},
|
|
700
|
+
{"predicate": "canon_field_equals",
|
|
701
|
+
"args": ["services", '{"name": "api"}', "observed_active", True]},
|
|
702
|
+
]})
|
|
703
|
+
# declared TRUE, observed FALSE → certified conflict → UNKNOWN certified,
|
|
704
|
+
# with metadata.thesis / metadata.antithesis — the dialectical operator
|
|
705
|
+
# turns the drift into productive indetermination, not a false binary.
|
|
706
|
+
```
|
|
707
|
+
|
|
708
|
+
The MCP server accepts an optional `provider` (opt-in, R6): when set, the
|
|
709
|
+
`canon_*` predicates are registered and `socratic_canon_query` appears in
|
|
710
|
+
`tools/list`.
|
|
711
|
+
|
|
712
|
+
---
|
|
713
|
+
|
|
650
714
|
## CLI
|
|
651
715
|
|
|
652
716
|
Evaluate a JSON tree directly:
|
|
@@ -670,7 +734,17 @@ This makes the same engine usable from:
|
|
|
670
734
|
|
|
671
735
|
## Install
|
|
672
736
|
|
|
673
|
-
|
|
737
|
+
### From PyPI (v0.2.2)
|
|
738
|
+
|
|
739
|
+
```bash
|
|
740
|
+
pip install socratic-engine
|
|
741
|
+
```
|
|
742
|
+
|
|
743
|
+
### With MCP support
|
|
744
|
+
|
|
745
|
+
```bash
|
|
746
|
+
pip install "socratic-engine[mcp]"
|
|
747
|
+
```
|
|
674
748
|
|
|
675
749
|
### From source
|
|
676
750
|
|
|
@@ -682,12 +756,6 @@ python3 -m venv .venv
|
|
|
682
756
|
.venv/bin/python -m pip install -e .
|
|
683
757
|
```
|
|
684
758
|
|
|
685
|
-
### With MCP support
|
|
686
|
-
|
|
687
|
-
```bash
|
|
688
|
-
.venv/bin/python -m pip install -e ".[mcp]"
|
|
689
|
-
```
|
|
690
|
-
|
|
691
759
|
### Run the tests
|
|
692
760
|
|
|
693
761
|
```bash
|
|
@@ -697,9 +765,16 @@ python3 -m pytest tests/ -q
|
|
|
697
765
|
The current repository snapshot passes:
|
|
698
766
|
|
|
699
767
|
```text
|
|
700
|
-
|
|
768
|
+
189 passed
|
|
701
769
|
```
|
|
702
770
|
|
|
771
|
+
at 100% statement coverage (CI gates at 90%; uncovered lines are
|
|
772
|
+
documented `# pragma: no cover` defensive branches — see the rationale
|
|
773
|
+
inline in the source).
|
|
774
|
+
|
|
775
|
+
(includes integration tests with `state-canon`, available when that
|
|
776
|
+
package is installed or reachable at `~/state-canon-mcp`)
|
|
777
|
+
|
|
703
778
|
---
|
|
704
779
|
|
|
705
780
|
## Repository layout
|
|
@@ -709,18 +784,26 @@ socratic-engine/
|
|
|
709
784
|
├── README.md
|
|
710
785
|
├── ROADMAP.md
|
|
711
786
|
├── pyproject.toml
|
|
712
|
-
├──
|
|
713
|
-
|
|
787
|
+
├── LICENSE
|
|
788
|
+
├── benchmarks/
|
|
789
|
+
│ └── benchmark.py # deep/wide trees, cache speedup, diagnose
|
|
714
790
|
├── docs/
|
|
715
|
-
│
|
|
791
|
+
│ ├── ONTOLOGY.md # epistemic model
|
|
792
|
+
│ ├── ARCHITECTURE.md # how it fits together (code-faithful)
|
|
793
|
+
│ └── EXAMPLES.md # executable use cases
|
|
716
794
|
├── socratic_engine/
|
|
717
795
|
│ ├── __init__.py
|
|
718
|
-
│ ├── engine.py
|
|
719
|
-
│ ├── tree.py
|
|
720
|
-
│ ├── cli.py
|
|
721
|
-
│
|
|
796
|
+
│ ├── engine.py # trivalent evaluator + certification + diagnosis
|
|
797
|
+
│ ├── tree.py # builder + VSL parser + tree routing
|
|
798
|
+
│ ├── cli.py # command-line interface
|
|
799
|
+
│ ├── mcp_server.py # MCP / JSON-RPC bridge + rate limiter
|
|
800
|
+
│ └── bridge_statecanon.py # official state-canon bridge (opt-in)
|
|
722
801
|
└── tests/
|
|
723
|
-
|
|
802
|
+
├── test_engine.py
|
|
803
|
+
├── test_mcp_server.py
|
|
804
|
+
├── test_cli.py
|
|
805
|
+
├── test_bridge_statecanon.py
|
|
806
|
+
└── test_state_canon_integration.py
|
|
724
807
|
```
|
|
725
808
|
|
|
726
809
|
---
|
|
@@ -914,14 +997,16 @@ Its purpose is narrower:
|
|
|
914
997
|
|
|
915
998
|
### v0.2.x — maturation
|
|
916
999
|
|
|
917
|
-
- [
|
|
918
|
-
- [
|
|
919
|
-
- [
|
|
920
|
-
- [
|
|
921
|
-
- [
|
|
922
|
-
- [
|
|
923
|
-
- [
|
|
924
|
-
- [
|
|
1000
|
+
- [x] CI workflow (pytest 3.10–3.12 + coverage + CLI smoke + MCP job)
|
|
1001
|
+
- [x] coverage > 90% (now 100%; CI gates at 90%)
|
|
1002
|
+
- [x] integration tests with `state-canon`
|
|
1003
|
+
- [x] performance benchmarks
|
|
1004
|
+
- [x] richer examples and architecture documentation
|
|
1005
|
+
- [x] dialectical operator for legitimate contradictions
|
|
1006
|
+
- [x] temporal / pragmatic predicates
|
|
1007
|
+
- [x] caching and rate limiting for expensive predicates
|
|
1008
|
+
- [x] published on PyPI (v0.2.0 → v0.2.2; bridge + ejemplos incluidos desde 0.2.2)
|
|
1009
|
+
- [x] official state-canon bridge + end-to-end examples (Claude Code, OpenCode)
|
|
925
1010
|
|
|
926
1011
|
### v0.3.x — formal extension
|
|
927
1012
|
|
|
@@ -937,8 +1022,10 @@ The roadmap is intentionally open: the next features should be driven by failure
|
|
|
937
1022
|
## Going deeper
|
|
938
1023
|
|
|
939
1024
|
- **[docs/ONTOLOGY.md](./docs/ONTOLOGY.md)** — the epistemic model: truth, certification, UNKNOWN, operator semantics, and the LLM boundary.
|
|
940
|
-
- **[
|
|
941
|
-
- **[
|
|
1025
|
+
- **[docs/ARCHITECTURE.md](./docs/ARCHITECTURE.md)** — how the modules fit together, written against the code.
|
|
1026
|
+
- **[docs/EXAMPLES.md](./docs/EXAMPLES.md)** — executable use cases: classification, deploy gates, diagnosis, dialectics, caching, rate limiting.
|
|
1027
|
+
- **[ROADMAP.md](./ROADMAP.md)** — current development programme (tracked as [issue #1](https://github.com/rm-w3kufe/socratic-engine/issues/1)).
|
|
1028
|
+
- **[benchmarks/benchmark.py](./benchmarks/benchmark.py)** — performance numbers (deep/wide trees, cache speedup, diagnose).
|
|
942
1029
|
- **[tests/](./tests/)** — executable specification of the current semantics.
|
|
943
1030
|
|
|
944
1031
|
---
|
|
@@ -8,7 +8,7 @@
|
|
|
8
8
|
|
|
9
9
|
The engine is deliberately small. It does not try to make an LLM "smarter". It gives the model a formal structure in which complex questioning can be proposed, executed recursively, inspected, and diagnosed **outside the model's token-generation loop**.
|
|
10
10
|
|
|
11
|
-
**Status:**
|
|
11
|
+
**Status:** v0.2.2 published on PyPI — core engine, VSL tree parser, CLI, MCP bridge, dialectical operator, pragmatic predicates, caching, rate limiting, CI (pytest 3.10–3.12 + coverage gate at 90%), benchmarks, a 189-test suite at 100% statement coverage, and the official state-canon bridge ([`bridge_statecanon.py`](./socratic_engine/bridge_statecanon.py)) with end-to-end examples are working. The broader claim — that externalizing recursive structure improves reliability on tasks that exceed a model's implicit recursive reasoning capacity — is an experimental hypothesis, not a proclamation.
|
|
12
12
|
|
|
13
13
|
---
|
|
14
14
|
|
|
@@ -59,6 +59,7 @@ At its core, the engine evaluates trees composed of:
|
|
|
59
59
|
- `NOT`
|
|
60
60
|
- `XOR`
|
|
61
61
|
- `IMPLIES`
|
|
62
|
+
- `DIALECTICAL_AND`
|
|
62
63
|
- registered predicates
|
|
63
64
|
- boolean literals
|
|
64
65
|
|
|
@@ -395,6 +396,7 @@ The engine implements:
|
|
|
395
396
|
| `NOT` | invert one proposition | child must be certified |
|
|
396
397
|
| `XOR` | exactly one true branch | children must be certified |
|
|
397
398
|
| `IMPLIES` | antecedent → consequent | antecedent and consequent must be certified when relevant |
|
|
399
|
+
| `DIALECTICAL_AND` | contradiction is not rejection — a certified TRUE/FALSE conflict yields `UNKNOWN` (certified), with thesis/antithesis in metadata | in conflict: all children certified (the contradiction itself is a fact); without conflict: all children certified |
|
|
398
400
|
|
|
399
401
|
The distinction matters for diagnosis.
|
|
400
402
|
|
|
@@ -578,7 +580,7 @@ The model is therefore not trusted to produce executable logic merely because th
|
|
|
578
580
|
|
|
579
581
|
## Built-in predicates
|
|
580
582
|
|
|
581
|
-
The engine currently ships with deterministic predicates for structural classification:
|
|
583
|
+
The engine currently ships with deterministic predicates for structural classification and pragmatic behaviour:
|
|
582
584
|
|
|
583
585
|
| Predicate | Question | Missing subject |
|
|
584
586
|
|---|---|---|
|
|
@@ -588,9 +590,14 @@ The engine currently ships with deterministic predicates for structural classifi
|
|
|
588
590
|
| `type_has` | does TYPE contain a token? | `UNKNOWN` |
|
|
589
591
|
| `doc_has_status` | does a document declare a status? | evaluated from document |
|
|
590
592
|
| `ctx_has` | does context contain a key/value? | `UNKNOWN` |
|
|
593
|
+
| `trend_up` | is a time series growing sustainably (min_delta, noise guard)? | `UNKNOWN` |
|
|
594
|
+
| `trend_down` | is a time series falling sustainably (min_delta, noise guard)? | `UNKNOWN` |
|
|
595
|
+
| `feedback_loop` | does a topology have a closed cycle (length ≥ 2) through target? | `UNKNOWN` |
|
|
591
596
|
|
|
592
597
|
Registering custom predicates is the intended extension point.
|
|
593
598
|
|
|
599
|
+
Costly predicates can be wrapped with `@cached(ttl=...)` — hits are marked `metadata.cached=True` (historical evidence, not a fresh measurement), `UNKNOWN` is never cached, and `engine.cache.clear()` forces re-verification.
|
|
600
|
+
|
|
594
601
|
---
|
|
595
602
|
|
|
596
603
|
## MCP bridge
|
|
@@ -616,13 +623,70 @@ The current bridge exposes:
|
|
|
616
623
|
| `socratic_build` | validate a proposed reasoning tree |
|
|
617
624
|
| `socratic_evaluate` | execute a tree against context |
|
|
618
625
|
| `socratic_diagnose` | return inverse failure traces |
|
|
626
|
+
| `socratic_canon_query` | (opt-in) query state-canon through the registered bridge |
|
|
619
627
|
|
|
620
628
|
The MCP layer is intentionally thin.
|
|
621
629
|
|
|
630
|
+
It includes a per-tool sliding-window rate limiter (`SOCRATIC_MCP_RATE_LIMIT`, default 100 calls / `SOCRATIC_MCP_RATE_WINDOW`, default 60s): a rate-limited call returns error `-32029` with `retry_after_s` — a transient signal, not a rejection.
|
|
631
|
+
|
|
622
632
|
The reasoning contract remains in the engine.
|
|
623
633
|
|
|
624
634
|
---
|
|
625
635
|
|
|
636
|
+
## Bridge to `state-canon` (official)
|
|
637
|
+
|
|
638
|
+
The official integration between the engine and **state-canon** lives in
|
|
639
|
+
[`socratic_engine/bridge_statecanon.py`](./socratic_engine/bridge_statecanon.py).
|
|
640
|
+
|
|
641
|
+
**Division of labor** (from the "Relationship to `state-canon`" section):
|
|
642
|
+
|
|
643
|
+
> **state-canon grounds the agent in what is observed.**
|
|
644
|
+
> **socratic-engine constrains how claims about that state are evaluated.**
|
|
645
|
+
|
|
646
|
+
The bridge registers four predicates on any `SocraticEngine`, all prefixed
|
|
647
|
+
`canon_` — they query the provider (the reconciled ground truth, *observed*)
|
|
648
|
+
and convert the result into certified evidence:
|
|
649
|
+
|
|
650
|
+
| Predicate | Question it answers |
|
|
651
|
+
|---|---|
|
|
652
|
+
| `canon_query(domain, filter)` | Is there at least one record matching the filter? |
|
|
653
|
+
| `canon_matches(domain, filter, expected)` | Do the records match the expected fields exactly? |
|
|
654
|
+
| `canon_field_equals(domain, filter, field, expected)` | Does a specific field equal the expected value? |
|
|
655
|
+
| `canon_drift(domain, filter, declared_field, observed_field)` | Have declared and observed drifted apart? |
|
|
656
|
+
|
|
657
|
+
`filter` and `expected` accept either a JSON string or a Python dict.
|
|
658
|
+
|
|
659
|
+
Semantics follow the engine's epistemology (R9 — no silent concession):
|
|
660
|
+
|
|
661
|
+
- **TRUE / FALSE** are returned **certified** (structural evidence exists).
|
|
662
|
+
- **UNKNOWN** is returned **uncertified** when there is no evidence — no
|
|
663
|
+
records, an unknown filter field, a missing field, or an unparseable
|
|
664
|
+
filter. No inventing, no silent routing to `else_home`.
|
|
665
|
+
|
|
666
|
+
```python
|
|
667
|
+
from socratic_engine import SocraticEngine
|
|
668
|
+
from socratic_engine.bridge_statecanon import StateCanonBridge
|
|
669
|
+
|
|
670
|
+
eng = SocraticEngine()
|
|
671
|
+
bridge = StateCanonBridge(eng, provider) # provider: state_canon.StateProvider
|
|
672
|
+
|
|
673
|
+
ev = eng.evaluate({"op": "DIALECTICAL_AND", "children": [
|
|
674
|
+
{"predicate": "canon_field_equals",
|
|
675
|
+
"args": ["services", '{"name": "api"}', "declared_active", True]},
|
|
676
|
+
{"predicate": "canon_field_equals",
|
|
677
|
+
"args": ["services", '{"name": "api"}', "observed_active", True]},
|
|
678
|
+
]})
|
|
679
|
+
# declared TRUE, observed FALSE → certified conflict → UNKNOWN certified,
|
|
680
|
+
# with metadata.thesis / metadata.antithesis — the dialectical operator
|
|
681
|
+
# turns the drift into productive indetermination, not a false binary.
|
|
682
|
+
```
|
|
683
|
+
|
|
684
|
+
The MCP server accepts an optional `provider` (opt-in, R6): when set, the
|
|
685
|
+
`canon_*` predicates are registered and `socratic_canon_query` appears in
|
|
686
|
+
`tools/list`.
|
|
687
|
+
|
|
688
|
+
---
|
|
689
|
+
|
|
626
690
|
## CLI
|
|
627
691
|
|
|
628
692
|
Evaluate a JSON tree directly:
|
|
@@ -646,7 +710,17 @@ This makes the same engine usable from:
|
|
|
646
710
|
|
|
647
711
|
## Install
|
|
648
712
|
|
|
649
|
-
|
|
713
|
+
### From PyPI (v0.2.2)
|
|
714
|
+
|
|
715
|
+
```bash
|
|
716
|
+
pip install socratic-engine
|
|
717
|
+
```
|
|
718
|
+
|
|
719
|
+
### With MCP support
|
|
720
|
+
|
|
721
|
+
```bash
|
|
722
|
+
pip install "socratic-engine[mcp]"
|
|
723
|
+
```
|
|
650
724
|
|
|
651
725
|
### From source
|
|
652
726
|
|
|
@@ -658,12 +732,6 @@ python3 -m venv .venv
|
|
|
658
732
|
.venv/bin/python -m pip install -e .
|
|
659
733
|
```
|
|
660
734
|
|
|
661
|
-
### With MCP support
|
|
662
|
-
|
|
663
|
-
```bash
|
|
664
|
-
.venv/bin/python -m pip install -e ".[mcp]"
|
|
665
|
-
```
|
|
666
|
-
|
|
667
735
|
### Run the tests
|
|
668
736
|
|
|
669
737
|
```bash
|
|
@@ -673,9 +741,16 @@ python3 -m pytest tests/ -q
|
|
|
673
741
|
The current repository snapshot passes:
|
|
674
742
|
|
|
675
743
|
```text
|
|
676
|
-
|
|
744
|
+
189 passed
|
|
677
745
|
```
|
|
678
746
|
|
|
747
|
+
at 100% statement coverage (CI gates at 90%; uncovered lines are
|
|
748
|
+
documented `# pragma: no cover` defensive branches — see the rationale
|
|
749
|
+
inline in the source).
|
|
750
|
+
|
|
751
|
+
(includes integration tests with `state-canon`, available when that
|
|
752
|
+
package is installed or reachable at `~/state-canon-mcp`)
|
|
753
|
+
|
|
679
754
|
---
|
|
680
755
|
|
|
681
756
|
## Repository layout
|
|
@@ -685,18 +760,26 @@ socratic-engine/
|
|
|
685
760
|
├── README.md
|
|
686
761
|
├── ROADMAP.md
|
|
687
762
|
├── pyproject.toml
|
|
688
|
-
├──
|
|
689
|
-
|
|
763
|
+
├── LICENSE
|
|
764
|
+
├── benchmarks/
|
|
765
|
+
│ └── benchmark.py # deep/wide trees, cache speedup, diagnose
|
|
690
766
|
├── docs/
|
|
691
|
-
│
|
|
767
|
+
│ ├── ONTOLOGY.md # epistemic model
|
|
768
|
+
│ ├── ARCHITECTURE.md # how it fits together (code-faithful)
|
|
769
|
+
│ └── EXAMPLES.md # executable use cases
|
|
692
770
|
├── socratic_engine/
|
|
693
771
|
│ ├── __init__.py
|
|
694
|
-
│ ├── engine.py
|
|
695
|
-
│ ├── tree.py
|
|
696
|
-
│ ├── cli.py
|
|
697
|
-
│
|
|
772
|
+
│ ├── engine.py # trivalent evaluator + certification + diagnosis
|
|
773
|
+
│ ├── tree.py # builder + VSL parser + tree routing
|
|
774
|
+
│ ├── cli.py # command-line interface
|
|
775
|
+
│ ├── mcp_server.py # MCP / JSON-RPC bridge + rate limiter
|
|
776
|
+
│ └── bridge_statecanon.py # official state-canon bridge (opt-in)
|
|
698
777
|
└── tests/
|
|
699
|
-
|
|
778
|
+
├── test_engine.py
|
|
779
|
+
├── test_mcp_server.py
|
|
780
|
+
├── test_cli.py
|
|
781
|
+
├── test_bridge_statecanon.py
|
|
782
|
+
└── test_state_canon_integration.py
|
|
700
783
|
```
|
|
701
784
|
|
|
702
785
|
---
|
|
@@ -890,14 +973,16 @@ Its purpose is narrower:
|
|
|
890
973
|
|
|
891
974
|
### v0.2.x — maturation
|
|
892
975
|
|
|
893
|
-
- [
|
|
894
|
-
- [
|
|
895
|
-
- [
|
|
896
|
-
- [
|
|
897
|
-
- [
|
|
898
|
-
- [
|
|
899
|
-
- [
|
|
900
|
-
- [
|
|
976
|
+
- [x] CI workflow (pytest 3.10–3.12 + coverage + CLI smoke + MCP job)
|
|
977
|
+
- [x] coverage > 90% (now 100%; CI gates at 90%)
|
|
978
|
+
- [x] integration tests with `state-canon`
|
|
979
|
+
- [x] performance benchmarks
|
|
980
|
+
- [x] richer examples and architecture documentation
|
|
981
|
+
- [x] dialectical operator for legitimate contradictions
|
|
982
|
+
- [x] temporal / pragmatic predicates
|
|
983
|
+
- [x] caching and rate limiting for expensive predicates
|
|
984
|
+
- [x] published on PyPI (v0.2.0 → v0.2.2; bridge + ejemplos incluidos desde 0.2.2)
|
|
985
|
+
- [x] official state-canon bridge + end-to-end examples (Claude Code, OpenCode)
|
|
901
986
|
|
|
902
987
|
### v0.3.x — formal extension
|
|
903
988
|
|
|
@@ -913,8 +998,10 @@ The roadmap is intentionally open: the next features should be driven by failure
|
|
|
913
998
|
## Going deeper
|
|
914
999
|
|
|
915
1000
|
- **[docs/ONTOLOGY.md](./docs/ONTOLOGY.md)** — the epistemic model: truth, certification, UNKNOWN, operator semantics, and the LLM boundary.
|
|
916
|
-
- **[
|
|
917
|
-
- **[
|
|
1001
|
+
- **[docs/ARCHITECTURE.md](./docs/ARCHITECTURE.md)** — how the modules fit together, written against the code.
|
|
1002
|
+
- **[docs/EXAMPLES.md](./docs/EXAMPLES.md)** — executable use cases: classification, deploy gates, diagnosis, dialectics, caching, rate limiting.
|
|
1003
|
+
- **[ROADMAP.md](./ROADMAP.md)** — current development programme (tracked as [issue #1](https://github.com/rm-w3kufe/socratic-engine/issues/1)).
|
|
1004
|
+
- **[benchmarks/benchmark.py](./benchmarks/benchmark.py)** — performance numbers (deep/wide trees, cache speedup, diagnose).
|
|
918
1005
|
- **[tests/](./tests/)** — executable specification of the current semantics.
|
|
919
1006
|
|
|
920
1007
|
---
|
|
@@ -4,11 +4,11 @@ build-backend = "setuptools.build_meta"
|
|
|
4
4
|
|
|
5
5
|
[project]
|
|
6
6
|
name = "socratic-engine"
|
|
7
|
-
version = "0.2.
|
|
7
|
+
version = "0.2.2"
|
|
8
8
|
description = "Externalized epistemic scaffolding for AI agents. Recursive boolean certification trees."
|
|
9
9
|
readme = "README.md"
|
|
10
10
|
requires-python = ">=3.10"
|
|
11
|
-
license = { text = "
|
|
11
|
+
license = { text = "Apache-2.0" }
|
|
12
12
|
keywords = ["socratic", "epistemic", "verification", "certification", "boolean-trees", "trivalent-logic", "mcp"]
|
|
13
13
|
classifiers = [
|
|
14
14
|
"Development Status :: 3 - Alpha",
|