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.
Files changed (24) hide show
  1. {socratic_engine-0.2.0/socratic_engine.egg-info → socratic_engine-0.2.2}/PKG-INFO +117 -30
  2. {socratic_engine-0.2.0 → socratic_engine-0.2.2}/README.md +115 -28
  3. {socratic_engine-0.2.0 → socratic_engine-0.2.2}/pyproject.toml +2 -2
  4. {socratic_engine-0.2.0 → socratic_engine-0.2.2}/socratic_engine/__init__.py +1 -1
  5. socratic_engine-0.2.2/socratic_engine/bridge_statecanon.py +219 -0
  6. {socratic_engine-0.2.0 → socratic_engine-0.2.2}/socratic_engine/cli.py +4 -4
  7. {socratic_engine-0.2.0 → socratic_engine-0.2.2}/socratic_engine/engine.py +11 -11
  8. {socratic_engine-0.2.0 → socratic_engine-0.2.2}/socratic_engine/mcp_server.py +44 -14
  9. {socratic_engine-0.2.0 → socratic_engine-0.2.2}/socratic_engine/tree.py +13 -5
  10. {socratic_engine-0.2.0 → socratic_engine-0.2.2/socratic_engine.egg-info}/PKG-INFO +117 -30
  11. {socratic_engine-0.2.0 → socratic_engine-0.2.2}/socratic_engine.egg-info/SOURCES.txt +3 -0
  12. socratic_engine-0.2.2/tests/test_bridge_statecanon.py +294 -0
  13. socratic_engine-0.2.2/tests/test_cli.py +154 -0
  14. socratic_engine-0.2.2/tests/test_engine.py +1320 -0
  15. socratic_engine-0.2.2/tests/test_mcp_server.py +254 -0
  16. socratic_engine-0.2.0/tests/test_engine.py +0 -434
  17. socratic_engine-0.2.0/tests/test_mcp_server.py +0 -89
  18. {socratic_engine-0.2.0 → socratic_engine-0.2.2}/LICENSE +0 -0
  19. {socratic_engine-0.2.0 → socratic_engine-0.2.2}/setup.cfg +0 -0
  20. {socratic_engine-0.2.0 → socratic_engine-0.2.2}/socratic_engine.egg-info/dependency_links.txt +0 -0
  21. {socratic_engine-0.2.0 → socratic_engine-0.2.2}/socratic_engine.egg-info/entry_points.txt +0 -0
  22. {socratic_engine-0.2.0 → socratic_engine-0.2.2}/socratic_engine.egg-info/requires.txt +0 -0
  23. {socratic_engine-0.2.0 → socratic_engine-0.2.2}/socratic_engine.egg-info/top_level.txt +0 -0
  24. {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.0
3
+ Version: 0.2.2
4
4
  Summary: Externalized epistemic scaffolding for AI agents. Recursive boolean certification trees.
5
- License: MIT
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:** early / exploratory — the core engine, VSL tree parser, CLI, MCP bridge, and test suite 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.
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
- > **Note:** the package is not published to PyPI yet. Install from source for now.
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
- 16 passed
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
- ├── examples/
713
- │ └── quickstart.py
787
+ ├── LICENSE
788
+ ├── benchmarks/
789
+ │ └── benchmark.py # deep/wide trees, cache speedup, diagnose
714
790
  ├── docs/
715
- │ └── ONTOLOGY.md
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 # trivalent evaluator + certification + diagnosis
719
- │ ├── tree.py # builder + VSL parser + tree routing
720
- │ ├── cli.py # command-line interface
721
- │ └── mcp_server.py # MCP / JSON-RPC bridge
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
- └── test_engine.py
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
- - [ ] CI workflow
918
- - [ ] coverage reporting
919
- - [ ] integration tests with `state-canon`
920
- - [ ] performance benchmarks
921
- - [ ] richer examples and architecture documentation
922
- - [ ] dialectical operator for legitimate contradictions
923
- - [ ] temporal / pragmatic predicates
924
- - [ ] caching and rate limiting for expensive predicates
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
- - **[ROADMAP.md](./ROADMAP.md)** — current development programme.
941
- - **[examples/quickstart.py](./examples/quickstart.py)** — three concrete cases: certified evidence, uncertified LLM judgment, and inverse diagnosis.
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:** early / exploratory — the core engine, VSL tree parser, CLI, MCP bridge, and test suite 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.
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
- > **Note:** the package is not published to PyPI yet. Install from source for now.
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
- 16 passed
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
- ├── examples/
689
- │ └── quickstart.py
763
+ ├── LICENSE
764
+ ├── benchmarks/
765
+ │ └── benchmark.py # deep/wide trees, cache speedup, diagnose
690
766
  ├── docs/
691
- │ └── ONTOLOGY.md
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 # trivalent evaluator + certification + diagnosis
695
- │ ├── tree.py # builder + VSL parser + tree routing
696
- │ ├── cli.py # command-line interface
697
- │ └── mcp_server.py # MCP / JSON-RPC bridge
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
- └── test_engine.py
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
- - [ ] CI workflow
894
- - [ ] coverage reporting
895
- - [ ] integration tests with `state-canon`
896
- - [ ] performance benchmarks
897
- - [ ] richer examples and architecture documentation
898
- - [ ] dialectical operator for legitimate contradictions
899
- - [ ] temporal / pragmatic predicates
900
- - [ ] caching and rate limiting for expensive predicates
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
- - **[ROADMAP.md](./ROADMAP.md)** — current development programme.
917
- - **[examples/quickstart.py](./examples/quickstart.py)** — three concrete cases: certified evidence, uncertified LLM judgment, and inverse diagnosis.
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.0"
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 = "MIT" }
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",
@@ -56,4 +56,4 @@ __all__ = [
56
56
  "tree_home",
57
57
  ]
58
58
 
59
- __version__ = "0.2.0"
59
+ __version__ = "0.2.2"