capability-reasoning-kernel 0.4.2__tar.gz → 0.5.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.
- capability_reasoning_kernel-0.5.0/.github/dependabot.yml +13 -0
- capability_reasoning_kernel-0.5.0/.github/workflows/ci.yml +151 -0
- {capability_reasoning_kernel-0.4.2 → capability_reasoning_kernel-0.5.0}/.github/workflows/pages.yml +4 -4
- capability_reasoning_kernel-0.5.0/.github/workflows/release.yml +107 -0
- {capability_reasoning_kernel-0.4.2 → capability_reasoning_kernel-0.5.0}/.pre-commit-config.yaml +2 -2
- {capability_reasoning_kernel-0.4.2 → capability_reasoning_kernel-0.5.0}/CHANGELOG.md +74 -0
- {capability_reasoning_kernel-0.4.2 → capability_reasoning_kernel-0.5.0}/PKG-INFO +36 -23
- {capability_reasoning_kernel-0.4.2 → capability_reasoning_kernel-0.5.0}/README.md +24 -18
- {capability_reasoning_kernel-0.4.2 → capability_reasoning_kernel-0.5.0}/SECURITY.md +7 -1
- {capability_reasoning_kernel-0.4.2 → capability_reasoning_kernel-0.5.0}/docs/ANALYSIS-2026-07.md +3 -0
- capability_reasoning_kernel-0.5.0/docs/CONFORMANCE.md +30 -0
- {capability_reasoning_kernel-0.4.2 → capability_reasoning_kernel-0.5.0}/docs/DEVELOPMENT.md +26 -8
- capability_reasoning_kernel-0.5.0/docs/OPERATIONS.md +149 -0
- {capability_reasoning_kernel-0.4.2 → capability_reasoning_kernel-0.5.0}/docs/index.html +6 -6
- {capability_reasoning_kernel-0.4.2 → capability_reasoning_kernel-0.5.0}/justfile +10 -4
- {capability_reasoning_kernel-0.4.2 → capability_reasoning_kernel-0.5.0}/pyproject.toml +10 -4
- capability_reasoning_kernel-0.5.0/scripts/check_artifacts.py +46 -0
- capability_reasoning_kernel-0.5.0/scripts/check_published.py +57 -0
- capability_reasoning_kernel-0.5.0/scripts/check_version.py +15 -0
- {capability_reasoning_kernel-0.4.2 → capability_reasoning_kernel-0.5.0}/src/reasoning_kernel/__init__.py +28 -3
- capability_reasoning_kernel-0.5.0/src/reasoning_kernel/kernel/effects.py +175 -0
- capability_reasoning_kernel-0.5.0/src/reasoning_kernel/kernel/gate.py +139 -0
- {capability_reasoning_kernel-0.4.2 → capability_reasoning_kernel-0.5.0}/src/reasoning_kernel/kernel/interpreter.py +118 -64
- capability_reasoning_kernel-0.5.0/src/reasoning_kernel/kernel/runtime.py +63 -0
- capability_reasoning_kernel-0.5.0/src/reasoning_kernel/kernel/session.py +61 -0
- capability_reasoning_kernel-0.5.0/src/reasoning_kernel/memory/sink.py +212 -0
- capability_reasoning_kernel-0.5.0/src/reasoning_kernel/memory/trace.py +150 -0
- {capability_reasoning_kernel-0.4.2 → capability_reasoning_kernel-0.5.0}/src/reasoning_kernel/reasoner/anthropic.py +14 -3
- {capability_reasoning_kernel-0.4.2 → capability_reasoning_kernel-0.5.0}/src/reasoning_kernel/reasoner/base.py +53 -2
- {capability_reasoning_kernel-0.4.2 → capability_reasoning_kernel-0.5.0}/src/reasoning_kernel/reasoner/deepseek.py +4 -0
- {capability_reasoning_kernel-0.4.2 → capability_reasoning_kernel-0.5.0}/src/reasoning_kernel/reasoner/openai.py +69 -30
- {capability_reasoning_kernel-0.4.2 → capability_reasoning_kernel-0.5.0}/src/reasoning_kernel/reasoner/parse.py +11 -3
- capability_reasoning_kernel-0.5.0/src/reasoning_kernel/reasoner/telemetry.py +36 -0
- {capability_reasoning_kernel-0.4.2 → capability_reasoning_kernel-0.5.0}/src/reasoning_kernel/schemas/capability.py +1 -1
- capability_reasoning_kernel-0.5.0/src/reasoning_kernel/schemas/limits.py +36 -0
- {capability_reasoning_kernel-0.4.2 → capability_reasoning_kernel-0.5.0}/src/reasoning_kernel/schemas/registry.py +4 -1
- capability_reasoning_kernel-0.5.0/src/reasoning_kernel/schemas/trace.py +184 -0
- {capability_reasoning_kernel-0.4.2 → capability_reasoning_kernel-0.5.0}/src/reasoning_kernel/tools/demo_mail.py +6 -3
- {capability_reasoning_kernel-0.4.2 → capability_reasoning_kernel-0.5.0}/src/reasoning_kernel/tools/registry.py +6 -0
- {capability_reasoning_kernel-0.4.2 → capability_reasoning_kernel-0.5.0}/tests/test_interpreter_loop.py +4 -2
- {capability_reasoning_kernel-0.4.2 → capability_reasoning_kernel-0.5.0}/tests/test_no_bypass_conformance.py +7 -3
- capability_reasoning_kernel-0.5.0/tests/test_operational.py +729 -0
- {capability_reasoning_kernel-0.4.2 → capability_reasoning_kernel-0.5.0}/tests/test_parse_with_schema.py +24 -1
- capability_reasoning_kernel-0.5.0/tests/test_provider_contracts.py +170 -0
- capability_reasoning_kernel-0.5.0/tests/test_providers_live.py +183 -0
- {capability_reasoning_kernel-0.4.2 → capability_reasoning_kernel-0.5.0}/tests/test_reasoner_robustness.py +3 -3
- capability_reasoning_kernel-0.5.0/tests/test_release_contract.py +88 -0
- capability_reasoning_kernel-0.5.0/uv.lock +1082 -0
- capability_reasoning_kernel-0.4.2/.github/workflows/ci.yml +0 -73
- capability_reasoning_kernel-0.4.2/.github/workflows/release.yml +0 -55
- capability_reasoning_kernel-0.4.2/src/reasoning_kernel/kernel/effects.py +0 -90
- capability_reasoning_kernel-0.4.2/src/reasoning_kernel/kernel/gate.py +0 -92
- capability_reasoning_kernel-0.4.2/src/reasoning_kernel/memory/trace.py +0 -23
- capability_reasoning_kernel-0.4.2/src/reasoning_kernel/schemas/limits.py +0 -23
- capability_reasoning_kernel-0.4.2/src/reasoning_kernel/schemas/trace.py +0 -110
- capability_reasoning_kernel-0.4.2/tests/test_providers_live.py +0 -54
- capability_reasoning_kernel-0.4.2/uv.lock +0 -603
- {capability_reasoning_kernel-0.4.2 → capability_reasoning_kernel-0.5.0}/.env.example +0 -0
- {capability_reasoning_kernel-0.4.2 → capability_reasoning_kernel-0.5.0}/.gitignore +0 -0
- {capability_reasoning_kernel-0.4.2 → capability_reasoning_kernel-0.5.0}/.python-version +0 -0
- {capability_reasoning_kernel-0.4.2 → capability_reasoning_kernel-0.5.0}/CLAUDE.md +0 -0
- {capability_reasoning_kernel-0.4.2 → capability_reasoning_kernel-0.5.0}/LICENSE +0 -0
- {capability_reasoning_kernel-0.4.2 → capability_reasoning_kernel-0.5.0}/docs/.nojekyll +0 -0
- {capability_reasoning_kernel-0.4.2 → capability_reasoning_kernel-0.5.0}/docs/favicon.svg +0 -0
- {capability_reasoning_kernel-0.4.2 → capability_reasoning_kernel-0.5.0}/src/reasoning_kernel/config.py +0 -0
- {capability_reasoning_kernel-0.4.2 → capability_reasoning_kernel-0.5.0}/src/reasoning_kernel/context/__init__.py +0 -0
- {capability_reasoning_kernel-0.4.2 → capability_reasoning_kernel-0.5.0}/src/reasoning_kernel/context/assembler.py +0 -0
- {capability_reasoning_kernel-0.4.2 → capability_reasoning_kernel-0.5.0}/src/reasoning_kernel/demo/__init__.py +0 -0
- {capability_reasoning_kernel-0.4.2 → capability_reasoning_kernel-0.5.0}/src/reasoning_kernel/demo/_report.py +0 -0
- {capability_reasoning_kernel-0.4.2 → capability_reasoning_kernel-0.5.0}/src/reasoning_kernel/demo/email_exfil.py +0 -0
- {capability_reasoning_kernel-0.4.2 → capability_reasoning_kernel-0.5.0}/src/reasoning_kernel/demo/live_run.py +0 -0
- {capability_reasoning_kernel-0.4.2 → capability_reasoning_kernel-0.5.0}/src/reasoning_kernel/demo/merge.py +0 -0
- {capability_reasoning_kernel-0.4.2 → capability_reasoning_kernel-0.5.0}/src/reasoning_kernel/demo/reasoner_error.py +0 -0
- {capability_reasoning_kernel-0.4.2 → capability_reasoning_kernel-0.5.0}/src/reasoning_kernel/demo/run_limits.py +0 -0
- {capability_reasoning_kernel-0.4.2 → capability_reasoning_kernel-0.5.0}/src/reasoning_kernel/demo/subkernel.py +0 -0
- {capability_reasoning_kernel-0.4.2 → capability_reasoning_kernel-0.5.0}/src/reasoning_kernel/kernel/__init__.py +0 -0
- {capability_reasoning_kernel-0.4.2 → capability_reasoning_kernel-0.5.0}/src/reasoning_kernel/kernel/taint.py +0 -0
- {capability_reasoning_kernel-0.4.2 → capability_reasoning_kernel-0.5.0}/src/reasoning_kernel/memory/__init__.py +0 -0
- {capability_reasoning_kernel-0.4.2 → capability_reasoning_kernel-0.5.0}/src/reasoning_kernel/memory/store.py +0 -0
- {capability_reasoning_kernel-0.4.2 → capability_reasoning_kernel-0.5.0}/src/reasoning_kernel/py.typed +0 -0
- {capability_reasoning_kernel-0.4.2 → capability_reasoning_kernel-0.5.0}/src/reasoning_kernel/reasoner/__init__.py +0 -0
- {capability_reasoning_kernel-0.4.2 → capability_reasoning_kernel-0.5.0}/src/reasoning_kernel/reasoner/factory.py +0 -0
- {capability_reasoning_kernel-0.4.2 → capability_reasoning_kernel-0.5.0}/src/reasoning_kernel/reasoner/fake.py +0 -0
- {capability_reasoning_kernel-0.4.2 → capability_reasoning_kernel-0.5.0}/src/reasoning_kernel/reasoner/roles.py +0 -0
- {capability_reasoning_kernel-0.4.2 → capability_reasoning_kernel-0.5.0}/src/reasoning_kernel/schemas/__init__.py +0 -0
- {capability_reasoning_kernel-0.4.2 → capability_reasoning_kernel-0.5.0}/src/reasoning_kernel/schemas/ids.py +0 -0
- {capability_reasoning_kernel-0.4.2 → capability_reasoning_kernel-0.5.0}/src/reasoning_kernel/schemas/plan.py +0 -0
- {capability_reasoning_kernel-0.4.2 → capability_reasoning_kernel-0.5.0}/src/reasoning_kernel/schemas/policy.py +0 -0
- {capability_reasoning_kernel-0.4.2 → capability_reasoning_kernel-0.5.0}/src/reasoning_kernel/schemas/provenance.py +0 -0
- {capability_reasoning_kernel-0.4.2 → capability_reasoning_kernel-0.5.0}/src/reasoning_kernel/schemas/values.py +0 -0
- {capability_reasoning_kernel-0.4.2 → capability_reasoning_kernel-0.5.0}/src/reasoning_kernel/tools/__init__.py +0 -0
- {capability_reasoning_kernel-0.4.2 → capability_reasoning_kernel-0.5.0}/tests/conftest.py +0 -0
- {capability_reasoning_kernel-0.4.2 → capability_reasoning_kernel-0.5.0}/tests/test_capability.py +0 -0
- {capability_reasoning_kernel-0.4.2 → capability_reasoning_kernel-0.5.0}/tests/test_composition.py +0 -0
- {capability_reasoning_kernel-0.4.2 → capability_reasoning_kernel-0.5.0}/tests/test_declass_policy.py +0 -0
- {capability_reasoning_kernel-0.4.2 → capability_reasoning_kernel-0.5.0}/tests/test_demo_email_exfil.py +0 -0
- {capability_reasoning_kernel-0.4.2 → capability_reasoning_kernel-0.5.0}/tests/test_demo_mail_tools.py +0 -0
- {capability_reasoning_kernel-0.4.2 → capability_reasoning_kernel-0.5.0}/tests/test_gate_capability.py +0 -0
- {capability_reasoning_kernel-0.4.2 → capability_reasoning_kernel-0.5.0}/tests/test_gate_provenance_declassify.py +0 -0
- {capability_reasoning_kernel-0.4.2 → capability_reasoning_kernel-0.5.0}/tests/test_gate_unrestricted_readers.py +0 -0
- {capability_reasoning_kernel-0.4.2 → capability_reasoning_kernel-0.5.0}/tests/test_invariant_a.py +0 -0
- {capability_reasoning_kernel-0.4.2 → capability_reasoning_kernel-0.5.0}/tests/test_merge.py +0 -0
- {capability_reasoning_kernel-0.4.2 → capability_reasoning_kernel-0.5.0}/tests/test_plan_schema.py +0 -0
- {capability_reasoning_kernel-0.4.2 → capability_reasoning_kernel-0.5.0}/tests/test_provenance_propagation.py +0 -0
- {capability_reasoning_kernel-0.4.2 → capability_reasoning_kernel-0.5.0}/tests/test_public_api.py +0 -0
- {capability_reasoning_kernel-0.4.2 → capability_reasoning_kernel-0.5.0}/tests/test_reasoner_factory.py +0 -0
- {capability_reasoning_kernel-0.4.2 → capability_reasoning_kernel-0.5.0}/tests/test_registry.py +0 -0
- {capability_reasoning_kernel-0.4.2 → capability_reasoning_kernel-0.5.0}/tests/test_run_limits.py +0 -0
- {capability_reasoning_kernel-0.4.2 → capability_reasoning_kernel-0.5.0}/tests/test_store.py +0 -0
- {capability_reasoning_kernel-0.4.2 → capability_reasoning_kernel-0.5.0}/tests/test_subject_provenance.py +0 -0
- {capability_reasoning_kernel-0.4.2 → capability_reasoning_kernel-0.5.0}/tests/test_subkernel.py +0 -0
- {capability_reasoning_kernel-0.4.2 → capability_reasoning_kernel-0.5.0}/tests/test_trace_append_only.py +0 -0
|
@@ -0,0 +1,151 @@
|
|
|
1
|
+
name: CI
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
push:
|
|
5
|
+
branches: [main]
|
|
6
|
+
pull_request:
|
|
7
|
+
workflow_dispatch:
|
|
8
|
+
inputs:
|
|
9
|
+
live_providers:
|
|
10
|
+
description: Comma-separated providers required by the live gate
|
|
11
|
+
required: true
|
|
12
|
+
default: deepseek
|
|
13
|
+
type: string
|
|
14
|
+
workflow_call:
|
|
15
|
+
inputs:
|
|
16
|
+
live_providers:
|
|
17
|
+
description: Comma-separated providers required by the live gate
|
|
18
|
+
required: false
|
|
19
|
+
default: ""
|
|
20
|
+
type: string
|
|
21
|
+
secrets:
|
|
22
|
+
ANTHROPIC_API_KEY:
|
|
23
|
+
required: false
|
|
24
|
+
OPENAI_API_KEY:
|
|
25
|
+
required: false
|
|
26
|
+
DEEPSEEK_API_KEY:
|
|
27
|
+
required: false
|
|
28
|
+
|
|
29
|
+
permissions:
|
|
30
|
+
contents: read
|
|
31
|
+
|
|
32
|
+
concurrency:
|
|
33
|
+
group: ci-${{ github.ref }}
|
|
34
|
+
cancel-in-progress: true
|
|
35
|
+
|
|
36
|
+
jobs:
|
|
37
|
+
quality:
|
|
38
|
+
runs-on: ubuntu-latest
|
|
39
|
+
strategy:
|
|
40
|
+
fail-fast: false
|
|
41
|
+
matrix:
|
|
42
|
+
python-version: ["3.12", "3.13", "3.14"]
|
|
43
|
+
steps:
|
|
44
|
+
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
|
|
45
|
+
with:
|
|
46
|
+
persist-credentials: false
|
|
47
|
+
|
|
48
|
+
- name: Install uv
|
|
49
|
+
uses: astral-sh/setup-uv@20cfd1bf945f4377ade1205e4dbc17946fc9a30d # v10.0.1
|
|
50
|
+
with:
|
|
51
|
+
version: "0.12.10"
|
|
52
|
+
checksum: "173d95a0c32d18c896c46ba6fafbf3cf9c14ab74b033f81b76c883ef492a976b"
|
|
53
|
+
python-version: ${{ matrix.python-version }}
|
|
54
|
+
enable-cache: true
|
|
55
|
+
|
|
56
|
+
- name: Install just
|
|
57
|
+
uses: extractions/setup-just@53165ef7e734c5c07cb06b3c8e7b647c5aa16db3 # v4
|
|
58
|
+
|
|
59
|
+
- name: Sync dependencies
|
|
60
|
+
run: uv sync --all-extras --locked
|
|
61
|
+
|
|
62
|
+
# The justfile uses `set dotenv-load`; provide a no-secret env so it loads cleanly.
|
|
63
|
+
# The default suite is key-free and `live` tests are excluded via addopts -m 'not live'.
|
|
64
|
+
- name: Prepare env
|
|
65
|
+
run: cp .env.example .env
|
|
66
|
+
|
|
67
|
+
- name: Lint
|
|
68
|
+
run: just lint
|
|
69
|
+
|
|
70
|
+
- name: Typecheck
|
|
71
|
+
run: just typecheck
|
|
72
|
+
|
|
73
|
+
- name: Test
|
|
74
|
+
run: just test # runs with coverage; fails under the threshold in pyproject
|
|
75
|
+
|
|
76
|
+
- name: Verify distribution
|
|
77
|
+
run: just package-check
|
|
78
|
+
|
|
79
|
+
artifact-roundtrip:
|
|
80
|
+
runs-on: ubuntu-latest
|
|
81
|
+
steps:
|
|
82
|
+
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
|
|
83
|
+
with:
|
|
84
|
+
persist-credentials: false
|
|
85
|
+
|
|
86
|
+
- name: Install uv
|
|
87
|
+
uses: astral-sh/setup-uv@20cfd1bf945f4377ade1205e4dbc17946fc9a30d # v10.0.1
|
|
88
|
+
with:
|
|
89
|
+
version: "0.12.10"
|
|
90
|
+
checksum: "173d95a0c32d18c896c46ba6fafbf3cf9c14ab74b033f81b76c883ef492a976b"
|
|
91
|
+
python-version: "3.12"
|
|
92
|
+
enable-cache: true
|
|
93
|
+
|
|
94
|
+
- name: Build distribution
|
|
95
|
+
run: |
|
|
96
|
+
uv sync --all-extras --locked
|
|
97
|
+
uv build --clear
|
|
98
|
+
uv run twine check --strict dist/*
|
|
99
|
+
uv run python scripts/check_artifacts.py dist
|
|
100
|
+
sha256sum dist/* > SHA256SUMS
|
|
101
|
+
|
|
102
|
+
- name: Upload distribution
|
|
103
|
+
uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1
|
|
104
|
+
with:
|
|
105
|
+
name: ci-distribution
|
|
106
|
+
path: |
|
|
107
|
+
dist/
|
|
108
|
+
SHA256SUMS
|
|
109
|
+
if-no-files-found: error
|
|
110
|
+
retention-days: 1
|
|
111
|
+
|
|
112
|
+
- name: Download distribution
|
|
113
|
+
uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1
|
|
114
|
+
with:
|
|
115
|
+
name: ci-distribution
|
|
116
|
+
path: roundtrip
|
|
117
|
+
|
|
118
|
+
- name: Verify downloaded bytes
|
|
119
|
+
working-directory: roundtrip
|
|
120
|
+
run: sha256sum --check SHA256SUMS
|
|
121
|
+
|
|
122
|
+
# Explicit provider qualification: manual or required by the release's reusable workflow call.
|
|
123
|
+
live:
|
|
124
|
+
if: inputs.live_providers != ''
|
|
125
|
+
runs-on: ubuntu-latest
|
|
126
|
+
steps:
|
|
127
|
+
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
|
|
128
|
+
with:
|
|
129
|
+
persist-credentials: false
|
|
130
|
+
|
|
131
|
+
- name: Install uv
|
|
132
|
+
uses: astral-sh/setup-uv@20cfd1bf945f4377ade1205e4dbc17946fc9a30d # v10.0.1
|
|
133
|
+
with:
|
|
134
|
+
version: "0.12.10"
|
|
135
|
+
checksum: "173d95a0c32d18c896c46ba6fafbf3cf9c14ab74b033f81b76c883ef492a976b"
|
|
136
|
+
python-version: "3.12"
|
|
137
|
+
enable-cache: true
|
|
138
|
+
|
|
139
|
+
- name: Install just
|
|
140
|
+
uses: extractions/setup-just@53165ef7e734c5c07cb06b3c8e7b647c5aa16db3 # v4
|
|
141
|
+
|
|
142
|
+
- name: Sync dependencies
|
|
143
|
+
run: uv sync --all-extras --locked
|
|
144
|
+
|
|
145
|
+
- name: Run live provider tests
|
|
146
|
+
env:
|
|
147
|
+
RK_LIVE_PROVIDERS: ${{ inputs.live_providers }}
|
|
148
|
+
ANTHROPIC_API_KEY: ${{ secrets.ANTHROPIC_API_KEY }}
|
|
149
|
+
OPENAI_API_KEY: ${{ secrets.OPENAI_API_KEY }}
|
|
150
|
+
DEEPSEEK_API_KEY: ${{ secrets.DEEPSEEK_API_KEY }}
|
|
151
|
+
run: just test-live
|
{capability_reasoning_kernel-0.4.2 → capability_reasoning_kernel-0.5.0}/.github/workflows/pages.yml
RENAMED
|
@@ -29,20 +29,20 @@ jobs:
|
|
|
29
29
|
url: ${{ steps.deployment.outputs.page_url }}
|
|
30
30
|
steps:
|
|
31
31
|
# Actions pinned to immutable commit SHAs (supply-chain hardening); tag in comment.
|
|
32
|
-
- uses: actions/checkout@
|
|
32
|
+
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
|
|
33
33
|
with:
|
|
34
34
|
persist-credentials: false
|
|
35
35
|
|
|
36
36
|
- name: Configure Pages
|
|
37
|
-
uses: actions/configure-pages@
|
|
37
|
+
uses: actions/configure-pages@45bfe0192ca1faeb007ade9deae92b16b8254a0d # v6.0.0
|
|
38
38
|
with:
|
|
39
39
|
enablement: true # self-enable Pages (build_type=workflow) on first run — no manual Settings step
|
|
40
40
|
|
|
41
41
|
- name: Upload artifact
|
|
42
|
-
uses: actions/upload-pages-artifact@
|
|
42
|
+
uses: actions/upload-pages-artifact@fc324d3547104276b827a68afc52ff2a11cc49c9 # v5.0.0
|
|
43
43
|
with:
|
|
44
44
|
path: docs
|
|
45
45
|
|
|
46
46
|
- name: Deploy to GitHub Pages
|
|
47
47
|
id: deployment
|
|
48
|
-
uses: actions/deploy-pages@
|
|
48
|
+
uses: actions/deploy-pages@368f82528645a54fb793d4d04e342629a3f51346 # v5.0.1
|
|
@@ -0,0 +1,107 @@
|
|
|
1
|
+
name: Release
|
|
2
|
+
|
|
3
|
+
# Test the tagged commit, then promote one immutable distribution through both indexes.
|
|
4
|
+
on:
|
|
5
|
+
push:
|
|
6
|
+
tags: ["v*"]
|
|
7
|
+
|
|
8
|
+
permissions:
|
|
9
|
+
contents: read
|
|
10
|
+
|
|
11
|
+
concurrency:
|
|
12
|
+
group: release-${{ github.ref }}
|
|
13
|
+
cancel-in-progress: false
|
|
14
|
+
|
|
15
|
+
jobs:
|
|
16
|
+
quality:
|
|
17
|
+
uses: ./.github/workflows/ci.yml
|
|
18
|
+
with:
|
|
19
|
+
live_providers: deepseek
|
|
20
|
+
secrets:
|
|
21
|
+
DEEPSEEK_API_KEY: ${{ secrets.DEEPSEEK_API_KEY }}
|
|
22
|
+
|
|
23
|
+
build:
|
|
24
|
+
needs: quality
|
|
25
|
+
runs-on: ubuntu-latest
|
|
26
|
+
steps:
|
|
27
|
+
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
|
|
28
|
+
with:
|
|
29
|
+
persist-credentials: false
|
|
30
|
+
- uses: astral-sh/setup-uv@20cfd1bf945f4377ade1205e4dbc17946fc9a30d # v10.0.1
|
|
31
|
+
with:
|
|
32
|
+
version: "0.12.10"
|
|
33
|
+
checksum: "173d95a0c32d18c896c46ba6fafbf3cf9c14ab74b033f81b76c883ef492a976b"
|
|
34
|
+
python-version: "3.12"
|
|
35
|
+
- run: uv sync --all-extras --locked
|
|
36
|
+
- name: Validate tag and build
|
|
37
|
+
run: |
|
|
38
|
+
uv run python scripts/check_version.py
|
|
39
|
+
uv build --clear
|
|
40
|
+
uv run twine check --strict dist/*
|
|
41
|
+
uv run python scripts/check_artifacts.py dist
|
|
42
|
+
sha256sum dist/* > SHA256SUMS
|
|
43
|
+
- uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1
|
|
44
|
+
with:
|
|
45
|
+
name: distribution
|
|
46
|
+
path: |
|
|
47
|
+
dist/
|
|
48
|
+
SHA256SUMS
|
|
49
|
+
if-no-files-found: error
|
|
50
|
+
|
|
51
|
+
testpypi:
|
|
52
|
+
needs: build
|
|
53
|
+
runs-on: ubuntu-latest
|
|
54
|
+
environment: testpypi
|
|
55
|
+
permissions:
|
|
56
|
+
contents: read
|
|
57
|
+
id-token: write
|
|
58
|
+
steps:
|
|
59
|
+
- uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1
|
|
60
|
+
with:
|
|
61
|
+
name: distribution
|
|
62
|
+
- run: sha256sum --check SHA256SUMS
|
|
63
|
+
- name: Publish to TestPyPI
|
|
64
|
+
uses: pypa/gh-action-pypi-publish@dc37677b2e1c63e2034f94d8a5b11f265b73ba33 # release/v1
|
|
65
|
+
with:
|
|
66
|
+
repository-url: https://test.pypi.org/legacy/
|
|
67
|
+
|
|
68
|
+
verify-testpypi:
|
|
69
|
+
needs: testpypi
|
|
70
|
+
runs-on: ubuntu-latest
|
|
71
|
+
steps:
|
|
72
|
+
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
|
|
73
|
+
with:
|
|
74
|
+
persist-credentials: false
|
|
75
|
+
- uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1
|
|
76
|
+
with:
|
|
77
|
+
name: distribution
|
|
78
|
+
- run: sha256sum --check SHA256SUMS
|
|
79
|
+
- run: python scripts/check_published.py dist testpypi
|
|
80
|
+
|
|
81
|
+
pypi:
|
|
82
|
+
needs: verify-testpypi
|
|
83
|
+
runs-on: ubuntu-latest
|
|
84
|
+
environment: pypi
|
|
85
|
+
permissions:
|
|
86
|
+
contents: read
|
|
87
|
+
id-token: write
|
|
88
|
+
steps:
|
|
89
|
+
- uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1
|
|
90
|
+
with:
|
|
91
|
+
name: distribution
|
|
92
|
+
- run: sha256sum --check SHA256SUMS
|
|
93
|
+
- name: Publish to PyPI
|
|
94
|
+
uses: pypa/gh-action-pypi-publish@dc37677b2e1c63e2034f94d8a5b11f265b73ba33 # release/v1
|
|
95
|
+
|
|
96
|
+
verify-pypi:
|
|
97
|
+
needs: pypi
|
|
98
|
+
runs-on: ubuntu-latest
|
|
99
|
+
steps:
|
|
100
|
+
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
|
|
101
|
+
with:
|
|
102
|
+
persist-credentials: false
|
|
103
|
+
- uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1
|
|
104
|
+
with:
|
|
105
|
+
name: distribution
|
|
106
|
+
- run: sha256sum --check SHA256SUMS
|
|
107
|
+
- run: python scripts/check_published.py dist pypi
|
{capability_reasoning_kernel-0.4.2 → capability_reasoning_kernel-0.5.0}/.pre-commit-config.yaml
RENAMED
|
@@ -16,13 +16,13 @@ repos:
|
|
|
16
16
|
- id: ruff-check
|
|
17
17
|
name: ruff check --fix (uv.lock version, same as `just fix`)
|
|
18
18
|
language: system
|
|
19
|
-
entry: uv run ruff check --fix src/ tests/
|
|
19
|
+
entry: uv run ruff check --fix src/ tests/ scripts/
|
|
20
20
|
pass_filenames: false
|
|
21
21
|
types_or: [python, pyi]
|
|
22
22
|
- id: ruff-format
|
|
23
23
|
name: ruff format (uv.lock version, same as `just fix`)
|
|
24
24
|
language: system
|
|
25
|
-
entry: uv run ruff format src/ tests/
|
|
25
|
+
entry: uv run ruff format src/ tests/ scripts/
|
|
26
26
|
pass_filenames: false
|
|
27
27
|
types_or: [python, pyi]
|
|
28
28
|
- id: pyright
|
|
@@ -4,6 +4,77 @@ All notable changes to this project are documented here. The format is based on
|
|
|
4
4
|
[Keep a Changelog](https://keepachangelog.com/en/1.1.0/), and this project adheres to
|
|
5
5
|
[Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
|
6
6
|
|
|
7
|
+
## [0.5.0] - 2026-09-06
|
|
8
|
+
|
|
9
|
+
First stable operational embedding release. It promotes the two release candidates after package,
|
|
10
|
+
provider and real-consumer compatibility validation; each host remains responsible for validating
|
|
11
|
+
its own live adapters and policies.
|
|
12
|
+
|
|
13
|
+
### Changed
|
|
14
|
+
|
|
15
|
+
- Qualify OpenAI SDK 3.8 through the required live DeepSeek compatibility gate without calling the
|
|
16
|
+
OpenAI service, and update the locked Pyright version.
|
|
17
|
+
- Upgrade the SHA-pinned uv and Pages actions after CI artifact round-trip and rendered Pages checks.
|
|
18
|
+
- Validate Vibemonitor's real `KernelGate` integration and complete consumer suite on Python 3.14.
|
|
19
|
+
|
|
20
|
+
## [0.5.0rc2] - 2026-09-06
|
|
21
|
+
|
|
22
|
+
Maintenance candidate following the first published operational release. Publication remains
|
|
23
|
+
separate from live host-adapter acceptance.
|
|
24
|
+
|
|
25
|
+
### Added
|
|
26
|
+
|
|
27
|
+
- SQLite audit discovery for reserved run IDs and runs needing operator review after incomplete or
|
|
28
|
+
uncertain execution.
|
|
29
|
+
|
|
30
|
+
### Changed
|
|
31
|
+
|
|
32
|
+
- Validate the provider adapters against OpenAI SDK 3.7 and Anthropic SDK 1.4, while bounding their
|
|
33
|
+
optional dependency ranges below the next untested major versions.
|
|
34
|
+
- Upgrade SHA-pinned GitHub Actions and add a CI upload/download checksum round trip for release
|
|
35
|
+
artifacts; group future Actions updates into one Dependabot pull request.
|
|
36
|
+
- Refresh the locked Pydantic, pytest and ruff versions used by CI and local development.
|
|
37
|
+
|
|
38
|
+
### Fixed
|
|
39
|
+
|
|
40
|
+
- Package builds clear stale distributions, while published-artifact verification ignores unrelated
|
|
41
|
+
files and still requires exactly one wheel and one source distribution.
|
|
42
|
+
|
|
43
|
+
## [0.5.0rc1] - 2026-09-06
|
|
44
|
+
|
|
45
|
+
Published operational embedding candidate. Publication does not imply live-adapter UAT.
|
|
46
|
+
|
|
47
|
+
### Added
|
|
48
|
+
|
|
49
|
+
- Single-use `RunSession`, bounded operational defaults and root-wide step/tool/parser/LLM budgets.
|
|
50
|
+
- Explicit tool egress declarations, normalized input verification and output model revalidation.
|
|
51
|
+
- `TraceSink`, memory/SQLite sinks, durable pre-call records and fail-closed storage handling.
|
|
52
|
+
- Correlated invocation IDs, parent run IDs, partial/uncertain effect outcomes and terminal run status.
|
|
53
|
+
- Redacted operational events, detached snapshots and canonical detailed digests.
|
|
54
|
+
- Bounded shared reasoner executor, returned usage/latency capture and public provider result types.
|
|
55
|
+
- Sanitized provider failure categories, HTTP status and allow-listed operational error codes.
|
|
56
|
+
- Crash, concurrency, shared-budget, adapter-contract and provider failure regression tests.
|
|
57
|
+
- Python 3.14 CI, locked dependencies, pinned actions and single-artifact release promotion with
|
|
58
|
+
a pinned/checksummed uv runtime, version checks, isolated wheel smoke and served-byte verification.
|
|
59
|
+
- Operational/migration guide and conformance checklist.
|
|
60
|
+
|
|
61
|
+
### Changed
|
|
62
|
+
|
|
63
|
+
- Require a patched `pydantic-settings>=2.14.2` (GHSA-4xgf-cpjx-pc3j) and refresh its lock entry.
|
|
64
|
+
- Version the SQLite audit schema, migrate the unversioned candidate layout, reject unknown/newer
|
|
65
|
+
layouts or missing key constraints, and verify released bytes after TestPyPI and PyPI publication.
|
|
66
|
+
- Require an explicit live-provider set in release CI; `0.5.0rc1` qualifies DeepSeek while OpenAI
|
|
67
|
+
remains supported but is not live-qualified for this candidate.
|
|
68
|
+
- Low-level interpreters reject reuse and context/trace mismatches; child IDs are opaque.
|
|
69
|
+
- Limits span descendants; `RunLimits()` remains unbounded for explicit low-level wiring.
|
|
70
|
+
- Failed tools stop later steps without implying rollback; output validation cannot undo a call.
|
|
71
|
+
- OpenAI-compatible fallback uses structured error parameters, once; refusals/truncations and
|
|
72
|
+
malformed outputs are terminal errors. DeepSeek routes directly through JSON mode with local
|
|
73
|
+
schema validation because its compatible API does not implement OpenAI's native JSON Schema mode.
|
|
74
|
+
Provider exception messages no longer include raw API text.
|
|
75
|
+
- Pyright explicitly resolves the project virtualenv. Documentation distinguishes root planning,
|
|
76
|
+
delegated untrusted planning and partial effects.
|
|
77
|
+
|
|
7
78
|
## [0.4.2] - 2026-07-10
|
|
8
79
|
|
|
9
80
|
A correctness release for the gate's provenance stage, plus fail-closed hardening of the provider
|
|
@@ -143,6 +214,9 @@ Initial reference implementation of the Reasoning Kernel pattern (strong / CaMeL
|
|
|
143
214
|
invariants, no-effect-bypasses-the-Verifier by construction, the deterministic declassification seam,
|
|
144
215
|
and the worked email-exfiltration demo.
|
|
145
216
|
|
|
217
|
+
[0.5.0]: https://github.com/gianlucamazza/reasoning-kernel/releases/tag/v0.5.0
|
|
218
|
+
[0.5.0rc2]: https://github.com/gianlucamazza/reasoning-kernel/releases/tag/v0.5.0rc2
|
|
219
|
+
[0.5.0rc1]: https://github.com/gianlucamazza/reasoning-kernel/releases/tag/v0.5.0rc1
|
|
146
220
|
[0.4.2]: https://github.com/gianlucamazza/reasoning-kernel/releases/tag/v0.4.2
|
|
147
221
|
[0.4.1]: https://github.com/gianlucamazza/reasoning-kernel/releases/tag/v0.4.1
|
|
148
222
|
[0.4.0]: https://github.com/gianlucamazza/reasoning-kernel/releases/tag/v0.4.0
|
|
@@ -1,10 +1,12 @@
|
|
|
1
|
-
Metadata-Version: 2.
|
|
1
|
+
Metadata-Version: 2.5
|
|
2
2
|
Name: capability-reasoning-kernel
|
|
3
|
-
Version: 0.
|
|
3
|
+
Version: 0.5.0
|
|
4
4
|
Summary: Reference implementation of the Reasoning Kernel pattern (strong / CaMeL-like form)
|
|
5
5
|
Project-URL: Homepage, https://github.com/gianlucamazza/reasoning-kernel
|
|
6
6
|
Project-URL: Repository, https://github.com/gianlucamazza/reasoning-kernel
|
|
7
7
|
Project-URL: Issues, https://github.com/gianlucamazza/reasoning-kernel/issues
|
|
8
|
+
Project-URL: Documentation, https://github.com/gianlucamazza/reasoning-kernel/blob/main/docs/OPERATIONS.md
|
|
9
|
+
Project-URL: Changelog, https://github.com/gianlucamazza/reasoning-kernel/blob/main/CHANGELOG.md
|
|
8
10
|
Author: Gianluca Mazza — Venere Labs
|
|
9
11
|
License: MIT
|
|
10
12
|
License-File: LICENSE
|
|
@@ -15,19 +17,24 @@ Classifier: License :: OSI Approved :: MIT License
|
|
|
15
17
|
Classifier: Programming Language :: Python :: 3
|
|
16
18
|
Classifier: Programming Language :: Python :: 3.12
|
|
17
19
|
Classifier: Programming Language :: Python :: 3.13
|
|
20
|
+
Classifier: Programming Language :: Python :: 3.14
|
|
18
21
|
Classifier: Topic :: Security
|
|
19
22
|
Classifier: Typing :: Typed
|
|
20
23
|
Requires-Python: >=3.12
|
|
21
|
-
Requires-Dist: pydantic-settings>=2.
|
|
24
|
+
Requires-Dist: pydantic-settings>=2.14.2
|
|
22
25
|
Requires-Dist: pydantic>=2.7
|
|
23
26
|
Provides-Extra: dev
|
|
27
|
+
Requires-Dist: anthropic<2,>=0.40; extra == 'dev'
|
|
28
|
+
Requires-Dist: httpx2<3,>=2.12; extra == 'dev'
|
|
29
|
+
Requires-Dist: openai<4,>=1.50; extra == 'dev'
|
|
24
30
|
Requires-Dist: pyright>=1.1.380; extra == 'dev'
|
|
25
31
|
Requires-Dist: pytest-cov>=5.0; extra == 'dev'
|
|
26
32
|
Requires-Dist: pytest>=8.0; extra == 'dev'
|
|
27
33
|
Requires-Dist: ruff>=0.9; extra == 'dev'
|
|
34
|
+
Requires-Dist: twine>=6.0; extra == 'dev'
|
|
28
35
|
Provides-Extra: providers
|
|
29
|
-
Requires-Dist: anthropic
|
|
30
|
-
Requires-Dist: openai
|
|
36
|
+
Requires-Dist: anthropic<2,>=0.40; extra == 'providers'
|
|
37
|
+
Requires-Dist: openai<4,>=1.50; extra == 'providers'
|
|
31
38
|
Description-Content-Type: text/markdown
|
|
32
39
|
|
|
33
40
|
# Reasoning Kernel
|
|
@@ -67,8 +74,9 @@ It is a reference implementation, **not** a turn-key security product.
|
|
|
67
74
|
The pattern guarantees a **topology, not a property**: it fixes *where* mediation and verification
|
|
68
75
|
live, by construction; it does not guarantee any particular policy is safe. Conformance is a
|
|
69
76
|
*necessary*, not a *sufficient*, condition. Concretely: no matter what an injected message says, it can
|
|
70
|
-
|
|
71
|
-
|
|
77
|
+
cannot fire a tool without passing your Gate. The root planner is isolated from tool results;
|
|
78
|
+
delegated sub-planners deliberately see untrusted data under reduced grants. Whether your Gate's
|
|
79
|
+
*policy* is correct is on you.
|
|
72
80
|
|
|
73
81
|
## Strong form: no trusted reasoner
|
|
74
82
|
|
|
@@ -96,19 +104,19 @@ The trusted, deterministic kernel is the **interpreter + capability/provenance g
|
|
|
96
104
|
|
|
97
105
|
Reasoner providers: Anthropic, OpenAI, Deepseek (OpenAI-compatible, reusing the `openai` SDK via a
|
|
98
106
|
`base_url` — no separate dependency), plus a deterministic `FakeProvider` for key-free tests — all
|
|
99
|
-
behind one interface (`reasoner/base.py`).
|
|
100
|
-
|
|
101
|
-
|
|
107
|
+
behind one interface (`reasoner/base.py`). Configured providers can be exercised through the same
|
|
108
|
+
live contract (`just test-live`). The 0.5 release workflow requires DeepSeek qualification; OpenAI
|
|
109
|
+
and Anthropic remain independently contract-tested unless a release explicitly qualifies them live.
|
|
102
110
|
|
|
103
111
|
## No effect bypasses the Verifier — by construction
|
|
104
112
|
|
|
105
113
|
1. Tool callables live only in `ToolRegistry`, handed only to `EffectDispatcher`; the interpreter
|
|
106
114
|
never holds one.
|
|
107
|
-
2. `EffectDispatcher` cannot be constructed without a `Gate`, and `dispatch`
|
|
115
|
+
2. `EffectDispatcher` cannot be constructed without a `Gate`, and `dispatch` authorizes the call
|
|
108
116
|
unconditionally before the callable runs.
|
|
109
117
|
3. `ToolCallStep` is the only step kind that invokes a tool callable, and its only handler routes
|
|
110
118
|
through the dispatcher. The other step kinds (`const`, `q_parse`, `subkernel`, `merge`) produce
|
|
111
|
-
values
|
|
119
|
+
values; a sub-kernel may invoke tools through its reduced Gate and the same dispatcher path.
|
|
112
120
|
|
|
113
121
|
## What a run looks like
|
|
114
122
|
|
|
@@ -136,9 +144,9 @@ just demo-limits # termination: RunLimits aborts the run closed before th
|
|
|
136
144
|
just demo-reasoner-error # fail-closed: a failing reasoner commits nothing (plan_rejected)
|
|
137
145
|
just demo-merge # MergeStep: combine several reads into one value; taint flows through the join
|
|
138
146
|
|
|
139
|
-
uv sync --all-extras #
|
|
147
|
+
uv sync --all-extras # explicit provider extra (dev also includes SDKs for mock tests)
|
|
140
148
|
just demo-live # end-to-end with a REAL planner/parser (needs a key in .env)
|
|
141
|
-
just test-live #
|
|
149
|
+
just test-live # configured real-provider round-trips; RK_LIVE_PROVIDERS makes a set mandatory
|
|
142
150
|
```
|
|
143
151
|
|
|
144
152
|
See [`docs/DEVELOPMENT.md`](docs/DEVELOPMENT.md) for the quality bar (coverage gate, strict typing,
|
|
@@ -149,9 +157,15 @@ pre-commit) and how to configure provider keys. Release notes are in
|
|
|
149
157
|
|
|
150
158
|
Install: `pip install capability-reasoning-kernel` — it **imports as** `import reasoning_kernel`
|
|
151
159
|
(the PyPI name differs because `reasoning-kernel` was taken by an unrelated project).
|
|
160
|
+
Install the operational release explicitly with
|
|
161
|
+
`pip install capability-reasoning-kernel==0.5.0`.
|
|
152
162
|
|
|
153
|
-
|
|
154
|
-
|
|
163
|
+
For operational embedding, use `RunSession` with a persistent sink and bounded defaults; see
|
|
164
|
+
[operations and migration](docs/OPERATIONS.md) and the [conformance checklist](docs/CONFORMANCE.md).
|
|
165
|
+
It isolates each run, records partial effects and refuses automatic replay. Package publication and
|
|
166
|
+
consumer compatibility tests are not evidence that a host's live adapters are correctly configured.
|
|
167
|
+
|
|
168
|
+
Explicit low-level wiring remains available. The package root re-exports the building blocks. Sketch (see
|
|
155
169
|
[`demo/email_exfil.py`](src/reasoning_kernel/demo/email_exfil.py) for a complete, runnable version):
|
|
156
170
|
|
|
157
171
|
```python
|
|
@@ -205,9 +219,8 @@ result = kernel.run(ctx) # RunResult(trace, committed); committed is
|
|
|
205
219
|
- **Reasoner failure is fail-closed**: a provider that returns no usable output (empty / refused /
|
|
206
220
|
malformed) raises `ReasonerError` (`reasoner/base.py`), and a provider call that fails in transport
|
|
207
221
|
(rate limit exhausted, 5xx, network fault) raises its `TransportError` subclass; either way the
|
|
208
|
-
Conductor records a terminal trace event and
|
|
209
|
-
|
|
210
|
-
means a flaky reasoner can never produce a half-applied effect.
|
|
222
|
+
Conductor records a terminal trace event and stops subsequent work. Earlier effects remain real
|
|
223
|
+
and are reported in `RunResult.effects`; `committed=None` means no final value, not rollback.
|
|
211
224
|
- **Capability composition (§5.4)**: every reasoner is bound to a `CapabilitySet`; the kernel rejects a
|
|
212
225
|
reasoner whose grant exceeds the dispatcher's — a child can never widen authority. A `SubKernelStep`
|
|
213
226
|
delegates untrusted content to an inner kernel at a **clamped, reduced grant**: an injection in that
|
|
@@ -216,9 +229,9 @@ result = kernel.run(ctx) # RunResult(trace, committed); committed is
|
|
|
216
229
|
- **Static, data-independent control flow**: a `Plan` is a forward-only DAG of five step kinds
|
|
217
230
|
(`const`, `tool`, `q_parse`, `subkernel`, `merge`), executed linearly by `kernel/interpreter.py`; a
|
|
218
231
|
`QuarantineParseStep`'s target schema is fixed at plan time
|
|
219
|
-
(`schema_ref`), never chosen on the quarantined value.
|
|
220
|
-
|
|
221
|
-
|
|
232
|
+
(`schema_ref`), never chosen on the quarantined value. There are no runtime branches or loops.
|
|
233
|
+
Delegated sub-planners can choose a child plan based on untrusted input; its authority and literal
|
|
234
|
+
provenance are reduced accordingly. This is not a claim of data-independent planning across delegation.
|
|
222
235
|
|
|
223
236
|
## Honest limits (fundamental — localized, not dissolved)
|
|
224
237
|
|
|
@@ -256,7 +269,7 @@ result = kernel.run(ctx) # RunResult(trace, committed); committed is
|
|
|
256
269
|
- **Join** — combining values combines their labels conservatively (union of sources, intersection of
|
|
257
270
|
readers, union of subjects), so taint only ever increases.
|
|
258
271
|
- **Quarantine** — routing untrusted content through the Q-LLM, which cannot launder its taint.
|
|
259
|
-
- **Capability / grant** —
|
|
272
|
+
- **Capability / grant** — a host-issued permission a tool requires; a run holds a fixed
|
|
260
273
|
`CapabilitySet` (its *grant*), and a sub-kernel's grant can only ever shrink.
|
|
261
274
|
- **Declassifier (`DeclassPolicy`)** — the single deterministic seam that may let tainted data into a
|
|
262
275
|
WRITE; the one place trust is deliberately relaxed.
|
|
@@ -35,8 +35,9 @@ It is a reference implementation, **not** a turn-key security product.
|
|
|
35
35
|
The pattern guarantees a **topology, not a property**: it fixes *where* mediation and verification
|
|
36
36
|
live, by construction; it does not guarantee any particular policy is safe. Conformance is a
|
|
37
37
|
*necessary*, not a *sufficient*, condition. Concretely: no matter what an injected message says, it can
|
|
38
|
-
|
|
39
|
-
|
|
38
|
+
cannot fire a tool without passing your Gate. The root planner is isolated from tool results;
|
|
39
|
+
delegated sub-planners deliberately see untrusted data under reduced grants. Whether your Gate's
|
|
40
|
+
*policy* is correct is on you.
|
|
40
41
|
|
|
41
42
|
## Strong form: no trusted reasoner
|
|
42
43
|
|
|
@@ -64,19 +65,19 @@ The trusted, deterministic kernel is the **interpreter + capability/provenance g
|
|
|
64
65
|
|
|
65
66
|
Reasoner providers: Anthropic, OpenAI, Deepseek (OpenAI-compatible, reusing the `openai` SDK via a
|
|
66
67
|
`base_url` — no separate dependency), plus a deterministic `FakeProvider` for key-free tests — all
|
|
67
|
-
behind one interface (`reasoner/base.py`).
|
|
68
|
-
|
|
69
|
-
|
|
68
|
+
behind one interface (`reasoner/base.py`). Configured providers can be exercised through the same
|
|
69
|
+
live contract (`just test-live`). The 0.5 release workflow requires DeepSeek qualification; OpenAI
|
|
70
|
+
and Anthropic remain independently contract-tested unless a release explicitly qualifies them live.
|
|
70
71
|
|
|
71
72
|
## No effect bypasses the Verifier — by construction
|
|
72
73
|
|
|
73
74
|
1. Tool callables live only in `ToolRegistry`, handed only to `EffectDispatcher`; the interpreter
|
|
74
75
|
never holds one.
|
|
75
|
-
2. `EffectDispatcher` cannot be constructed without a `Gate`, and `dispatch`
|
|
76
|
+
2. `EffectDispatcher` cannot be constructed without a `Gate`, and `dispatch` authorizes the call
|
|
76
77
|
unconditionally before the callable runs.
|
|
77
78
|
3. `ToolCallStep` is the only step kind that invokes a tool callable, and its only handler routes
|
|
78
79
|
through the dispatcher. The other step kinds (`const`, `q_parse`, `subkernel`, `merge`) produce
|
|
79
|
-
values
|
|
80
|
+
values; a sub-kernel may invoke tools through its reduced Gate and the same dispatcher path.
|
|
80
81
|
|
|
81
82
|
## What a run looks like
|
|
82
83
|
|
|
@@ -104,9 +105,9 @@ just demo-limits # termination: RunLimits aborts the run closed before th
|
|
|
104
105
|
just demo-reasoner-error # fail-closed: a failing reasoner commits nothing (plan_rejected)
|
|
105
106
|
just demo-merge # MergeStep: combine several reads into one value; taint flows through the join
|
|
106
107
|
|
|
107
|
-
uv sync --all-extras #
|
|
108
|
+
uv sync --all-extras # explicit provider extra (dev also includes SDKs for mock tests)
|
|
108
109
|
just demo-live # end-to-end with a REAL planner/parser (needs a key in .env)
|
|
109
|
-
just test-live #
|
|
110
|
+
just test-live # configured real-provider round-trips; RK_LIVE_PROVIDERS makes a set mandatory
|
|
110
111
|
```
|
|
111
112
|
|
|
112
113
|
See [`docs/DEVELOPMENT.md`](docs/DEVELOPMENT.md) for the quality bar (coverage gate, strict typing,
|
|
@@ -117,9 +118,15 @@ pre-commit) and how to configure provider keys. Release notes are in
|
|
|
117
118
|
|
|
118
119
|
Install: `pip install capability-reasoning-kernel` — it **imports as** `import reasoning_kernel`
|
|
119
120
|
(the PyPI name differs because `reasoning-kernel` was taken by an unrelated project).
|
|
121
|
+
Install the operational release explicitly with
|
|
122
|
+
`pip install capability-reasoning-kernel==0.5.0`.
|
|
120
123
|
|
|
121
|
-
|
|
122
|
-
|
|
124
|
+
For operational embedding, use `RunSession` with a persistent sink and bounded defaults; see
|
|
125
|
+
[operations and migration](docs/OPERATIONS.md) and the [conformance checklist](docs/CONFORMANCE.md).
|
|
126
|
+
It isolates each run, records partial effects and refuses automatic replay. Package publication and
|
|
127
|
+
consumer compatibility tests are not evidence that a host's live adapters are correctly configured.
|
|
128
|
+
|
|
129
|
+
Explicit low-level wiring remains available. The package root re-exports the building blocks. Sketch (see
|
|
123
130
|
[`demo/email_exfil.py`](src/reasoning_kernel/demo/email_exfil.py) for a complete, runnable version):
|
|
124
131
|
|
|
125
132
|
```python
|
|
@@ -173,9 +180,8 @@ result = kernel.run(ctx) # RunResult(trace, committed); committed is
|
|
|
173
180
|
- **Reasoner failure is fail-closed**: a provider that returns no usable output (empty / refused /
|
|
174
181
|
malformed) raises `ReasonerError` (`reasoner/base.py`), and a provider call that fails in transport
|
|
175
182
|
(rate limit exhausted, 5xx, network fault) raises its `TransportError` subclass; either way the
|
|
176
|
-
Conductor records a terminal trace event and
|
|
177
|
-
|
|
178
|
-
means a flaky reasoner can never produce a half-applied effect.
|
|
183
|
+
Conductor records a terminal trace event and stops subsequent work. Earlier effects remain real
|
|
184
|
+
and are reported in `RunResult.effects`; `committed=None` means no final value, not rollback.
|
|
179
185
|
- **Capability composition (§5.4)**: every reasoner is bound to a `CapabilitySet`; the kernel rejects a
|
|
180
186
|
reasoner whose grant exceeds the dispatcher's — a child can never widen authority. A `SubKernelStep`
|
|
181
187
|
delegates untrusted content to an inner kernel at a **clamped, reduced grant**: an injection in that
|
|
@@ -184,9 +190,9 @@ result = kernel.run(ctx) # RunResult(trace, committed); committed is
|
|
|
184
190
|
- **Static, data-independent control flow**: a `Plan` is a forward-only DAG of five step kinds
|
|
185
191
|
(`const`, `tool`, `q_parse`, `subkernel`, `merge`), executed linearly by `kernel/interpreter.py`; a
|
|
186
192
|
`QuarantineParseStep`'s target schema is fixed at plan time
|
|
187
|
-
(`schema_ref`), never chosen on the quarantined value.
|
|
188
|
-
|
|
189
|
-
|
|
193
|
+
(`schema_ref`), never chosen on the quarantined value. There are no runtime branches or loops.
|
|
194
|
+
Delegated sub-planners can choose a child plan based on untrusted input; its authority and literal
|
|
195
|
+
provenance are reduced accordingly. This is not a claim of data-independent planning across delegation.
|
|
190
196
|
|
|
191
197
|
## Honest limits (fundamental — localized, not dissolved)
|
|
192
198
|
|
|
@@ -224,7 +230,7 @@ result = kernel.run(ctx) # RunResult(trace, committed); committed is
|
|
|
224
230
|
- **Join** — combining values combines their labels conservatively (union of sources, intersection of
|
|
225
231
|
readers, union of subjects), so taint only ever increases.
|
|
226
232
|
- **Quarantine** — routing untrusted content through the Q-LLM, which cannot launder its taint.
|
|
227
|
-
- **Capability / grant** —
|
|
233
|
+
- **Capability / grant** — a host-issued permission a tool requires; a run holds a fixed
|
|
228
234
|
`CapabilitySet` (its *grant*), and a sub-kernel's grant can only ever shrink.
|
|
229
235
|
- **Declassifier (`DeclassPolicy`)** — the single deterministic seam that may let tainted data into a
|
|
230
236
|
WRITE; the one place trust is deliberately relaxed.
|