schemarouter 0.2.0a1__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 (107) hide show
  1. schemarouter-0.2.0a1/.github/dependabot.yml +21 -0
  2. schemarouter-0.2.0a1/.github/workflows/ci.yml +90 -0
  3. schemarouter-0.2.0a1/.github/workflows/compatibility.yml +43 -0
  4. schemarouter-0.2.0a1/.github/workflows/docs.yml +58 -0
  5. schemarouter-0.2.0a1/.github/workflows/release.yml +113 -0
  6. schemarouter-0.2.0a1/.gitignore +9 -0
  7. schemarouter-0.2.0a1/CHANGELOG.md +45 -0
  8. schemarouter-0.2.0a1/CONTRIBUTING.md +73 -0
  9. schemarouter-0.2.0a1/LICENSE +21 -0
  10. schemarouter-0.2.0a1/PKG-INFO +297 -0
  11. schemarouter-0.2.0a1/README.md +253 -0
  12. schemarouter-0.2.0a1/SECURITY.md +104 -0
  13. schemarouter-0.2.0a1/docs/adapter-authoring.md +127 -0
  14. schemarouter-0.2.0a1/docs/architecture.md +178 -0
  15. schemarouter-0.2.0a1/docs/assets/brand/README.md +33 -0
  16. schemarouter-0.2.0a1/docs/assets/brand/schemarouter-lockup-dark.svg +22 -0
  17. schemarouter-0.2.0a1/docs/assets/brand/schemarouter-lockup-light.svg +22 -0
  18. schemarouter-0.2.0a1/docs/assets/brand/schemarouter-mark-dark.svg +17 -0
  19. schemarouter-0.2.0a1/docs/assets/brand/schemarouter-mark-light.svg +17 -0
  20. schemarouter-0.2.0a1/docs/assets/brand/schemarouter-social-preview.svg +39 -0
  21. schemarouter-0.2.0a1/docs/changelog.md +36 -0
  22. schemarouter-0.2.0a1/docs/compatibility.md +48 -0
  23. schemarouter-0.2.0a1/docs/concepts/adapters.md +69 -0
  24. schemarouter-0.2.0a1/docs/concepts/execution.md +65 -0
  25. schemarouter-0.2.0a1/docs/concepts/planning.md +67 -0
  26. schemarouter-0.2.0a1/docs/concepts/registry.md +64 -0
  27. schemarouter-0.2.0a1/docs/concepts/schema-router.md +76 -0
  28. schemarouter-0.2.0a1/docs/concepts/tool-endpoint.md +67 -0
  29. schemarouter-0.2.0a1/docs/contributing.md +63 -0
  30. schemarouter-0.2.0a1/docs/framework-maturity.md +112 -0
  31. schemarouter-0.2.0a1/docs/getting-started/ingestion-paths.md +54 -0
  32. schemarouter-0.2.0a1/docs/getting-started/installation.md +61 -0
  33. schemarouter-0.2.0a1/docs/getting-started/quickstart.md +61 -0
  34. schemarouter-0.2.0a1/docs/guides/execution-policy.md +58 -0
  35. schemarouter-0.2.0a1/docs/guides/html-documentation.md +81 -0
  36. schemarouter-0.2.0a1/docs/guides/mcp.md +62 -0
  37. schemarouter-0.2.0a1/docs/guides/model-analyzer.md +63 -0
  38. schemarouter-0.2.0a1/docs/guides/openapi.md +82 -0
  39. schemarouter-0.2.0a1/docs/guides/optimade.md +147 -0
  40. schemarouter-0.2.0a1/docs/guides/python-tools.md +68 -0
  41. schemarouter-0.2.0a1/docs/guides/retry.md +60 -0
  42. schemarouter-0.2.0a1/docs/guides/runtime.md +95 -0
  43. schemarouter-0.2.0a1/docs/index.md +172 -0
  44. schemarouter-0.2.0a1/docs/integrations/langchain.md +66 -0
  45. schemarouter-0.2.0a1/docs/license.md +7 -0
  46. schemarouter-0.2.0a1/docs/project/brand.md +61 -0
  47. schemarouter-0.2.0a1/docs/recipes/many-tools.md +51 -0
  48. schemarouter-0.2.0a1/docs/recipes/mcp-agent.md +32 -0
  49. schemarouter-0.2.0a1/docs/recipes/openapi-agent.md +51 -0
  50. schemarouter-0.2.0a1/docs/reference/api.md +39 -0
  51. schemarouter-0.2.0a1/docs/reference/models.md +33 -0
  52. schemarouter-0.2.0a1/docs/reference/planning.md +25 -0
  53. schemarouter-0.2.0a1/docs/reference/runtime.md +17 -0
  54. schemarouter-0.2.0a1/docs/release-checklist.md +49 -0
  55. schemarouter-0.2.0a1/docs/releases/0.2.0a1.md +35 -0
  56. schemarouter-0.2.0a1/docs/security/threat-model.md +104 -0
  57. schemarouter-0.2.0a1/docs/stylesheets/brand.css +28 -0
  58. schemarouter-0.2.0a1/docs/versioning.md +59 -0
  59. schemarouter-0.2.0a1/examples/quickstart.py +37 -0
  60. schemarouter-0.2.0a1/mkdocs.yml +136 -0
  61. schemarouter-0.2.0a1/pyproject.toml +76 -0
  62. schemarouter-0.2.0a1/scripts/live_openapi_smoke.py +55 -0
  63. schemarouter-0.2.0a1/scripts/live_optimade_smoke.py +52 -0
  64. schemarouter-0.2.0a1/src/schemarouter/__init__.py +88 -0
  65. schemarouter-0.2.0a1/src/schemarouter/_version.py +8 -0
  66. schemarouter-0.2.0a1/src/schemarouter/adapters/__init__.py +29 -0
  67. schemarouter-0.2.0a1/src/schemarouter/adapters/base.py +71 -0
  68. schemarouter-0.2.0a1/src/schemarouter/adapters/mcp.py +179 -0
  69. schemarouter-0.2.0a1/src/schemarouter/adapters/openapi.py +418 -0
  70. schemarouter-0.2.0a1/src/schemarouter/adapters/optimade.py +656 -0
  71. schemarouter-0.2.0a1/src/schemarouter/adapters/python.py +188 -0
  72. schemarouter-0.2.0a1/src/schemarouter/analyzers/__init__.py +3 -0
  73. schemarouter-0.2.0a1/src/schemarouter/analyzers/model.py +185 -0
  74. schemarouter-0.2.0a1/src/schemarouter/errors.py +50 -0
  75. schemarouter-0.2.0a1/src/schemarouter/executor.py +207 -0
  76. schemarouter-0.2.0a1/src/schemarouter/ingestion.py +348 -0
  77. schemarouter-0.2.0a1/src/schemarouter/integrations/__init__.py +3 -0
  78. schemarouter-0.2.0a1/src/schemarouter/integrations/langchain.py +96 -0
  79. schemarouter-0.2.0a1/src/schemarouter/models.py +154 -0
  80. schemarouter-0.2.0a1/src/schemarouter/planner.py +253 -0
  81. schemarouter-0.2.0a1/src/schemarouter/policy.py +51 -0
  82. schemarouter-0.2.0a1/src/schemarouter/proposals.py +391 -0
  83. schemarouter-0.2.0a1/src/schemarouter/py.typed +0 -0
  84. schemarouter-0.2.0a1/src/schemarouter/registry.py +84 -0
  85. schemarouter-0.2.0a1/src/schemarouter/runs.py +77 -0
  86. schemarouter-0.2.0a1/src/schemarouter/runtime.py +686 -0
  87. schemarouter-0.2.0a1/src/schemarouter/validation.py +96 -0
  88. schemarouter-0.2.0a1/tests/fixtures/mcp_http_server.py +29 -0
  89. schemarouter-0.2.0a1/tests/test_adapter_registry.py +76 -0
  90. schemarouter-0.2.0a1/tests/test_adapters.py +348 -0
  91. schemarouter-0.2.0a1/tests/test_brand_assets.py +65 -0
  92. schemarouter-0.2.0a1/tests/test_executor.py +385 -0
  93. schemarouter-0.2.0a1/tests/test_ingestion.py +297 -0
  94. schemarouter-0.2.0a1/tests/test_langchain_integration.py +52 -0
  95. schemarouter-0.2.0a1/tests/test_mcp_integration.py +95 -0
  96. schemarouter-0.2.0a1/tests/test_model_analyzer.py +134 -0
  97. schemarouter-0.2.0a1/tests/test_optimade_adapter.py +409 -0
  98. schemarouter-0.2.0a1/tests/test_optimade_security.py +218 -0
  99. schemarouter-0.2.0a1/tests/test_package_metadata.py +5 -0
  100. schemarouter-0.2.0a1/tests/test_planner.py +79 -0
  101. schemarouter-0.2.0a1/tests/test_policy.py +161 -0
  102. schemarouter-0.2.0a1/tests/test_proposals.py +321 -0
  103. schemarouter-0.2.0a1/tests/test_public_api.py +71 -0
  104. schemarouter-0.2.0a1/tests/test_python_adapter.py +111 -0
  105. schemarouter-0.2.0a1/tests/test_registry.py +97 -0
  106. schemarouter-0.2.0a1/tests/test_release_metadata.py +47 -0
  107. schemarouter-0.2.0a1/tests/test_runtime_interface.py +308 -0
@@ -0,0 +1,21 @@
1
+ version: 2
2
+ updates:
3
+ - package-ecosystem: pip
4
+ directory: /
5
+ schedule:
6
+ interval: weekly
7
+ open-pull-requests-limit: 5
8
+ groups:
9
+ python-dependencies:
10
+ patterns:
11
+ - "*"
12
+
13
+ - package-ecosystem: github-actions
14
+ directory: /
15
+ schedule:
16
+ interval: weekly
17
+ open-pull-requests-limit: 5
18
+ groups:
19
+ github-actions:
20
+ patterns:
21
+ - "*"
@@ -0,0 +1,90 @@
1
+ name: CI
2
+
3
+ on:
4
+ push:
5
+ branches: [main]
6
+ pull_request:
7
+
8
+ permissions:
9
+ contents: read
10
+
11
+ jobs:
12
+ test:
13
+ runs-on: ubuntu-latest
14
+ strategy:
15
+ matrix:
16
+ python-version: ["3.10", "3.11", "3.12"]
17
+ steps:
18
+ - uses: actions/checkout@v7
19
+ - uses: actions/setup-python@v7
20
+ with:
21
+ python-version: ${{ matrix.python-version }}
22
+ - run: python -m pip install --upgrade pip
23
+ - run: pip install -e ".[dev]"
24
+ - run: ruff check .
25
+ - run: pytest -q -m "not mcp_integration"
26
+ - run: python examples/quickstart.py
27
+
28
+ package:
29
+ runs-on: ubuntu-latest
30
+ steps:
31
+ - uses: actions/checkout@v7
32
+ - uses: actions/setup-python@v7
33
+ with:
34
+ python-version: "3.12"
35
+ - run: python -m pip install --upgrade pip
36
+ - run: pip install build twine
37
+ - run: python -m build
38
+ - run: twine check dist/*
39
+ - name: Verify license is packaged
40
+ run: |
41
+ python - <<'PY'
42
+ import glob
43
+ import zipfile
44
+
45
+ wheel = glob.glob("dist/*.whl")[0]
46
+ names = zipfile.ZipFile(wheel).namelist()
47
+ assert any(name.endswith("/licenses/LICENSE") for name in names), names
48
+ PY
49
+ - run: python -m venv /tmp/schemarouter-wheel
50
+ - run: /tmp/schemarouter-wheel/bin/python -m pip install --upgrade pip
51
+ - run: /tmp/schemarouter-wheel/bin/pip install dist/*.whl
52
+ - run: /tmp/schemarouter-wheel/bin/python -c "import schemarouter; assert schemarouter.__version__ == '0.2.0a1'"
53
+ - run: /tmp/schemarouter-wheel/bin/python examples/quickstart.py
54
+
55
+ langchain-integration:
56
+ runs-on: ubuntu-latest
57
+ steps:
58
+ - uses: actions/checkout@v7
59
+ - uses: actions/setup-python@v7
60
+ with:
61
+ python-version: "3.12"
62
+ - run: python -m pip install --upgrade pip
63
+ - run: pip install -e ".[dev,langchain]"
64
+ - run: pytest -q tests/test_langchain_integration.py
65
+
66
+
67
+ mcp-integration:
68
+ runs-on: ubuntu-latest
69
+ steps:
70
+ - uses: actions/checkout@v7
71
+ - uses: actions/setup-python@v7
72
+ with:
73
+ python-version: "3.12"
74
+ - run: python -m pip install --upgrade pip
75
+ - run: pip install -e ".[dev,mcp]"
76
+ - run: pytest -q tests/test_mcp_integration.py
77
+
78
+
79
+ docs:
80
+ runs-on: ubuntu-latest
81
+ steps:
82
+ - uses: actions/checkout@v7
83
+ - uses: actions/setup-python@v7
84
+ with:
85
+ python-version: "3.12"
86
+ - run: python -m pip install --upgrade pip
87
+ - run: pip install -e ".[docs]"
88
+ - run: mkdocs build --strict
89
+ env:
90
+ NO_MKDOCS_2_WARNING: "1"
@@ -0,0 +1,43 @@
1
+ name: Compatibility Smoke
2
+
3
+ on:
4
+ workflow_dispatch:
5
+ schedule:
6
+ - cron: "17 3 * * 1"
7
+ pull_request:
8
+ paths:
9
+ - "src/schemarouter/adapters/**"
10
+ - "src/schemarouter/ingestion.py"
11
+ - "scripts/live_*"
12
+ - ".github/workflows/compatibility.yml"
13
+
14
+ permissions:
15
+ contents: read
16
+
17
+ jobs:
18
+ public-openapi:
19
+ continue-on-error: true
20
+ runs-on: ubuntu-latest
21
+ timeout-minutes: 10
22
+ steps:
23
+ - uses: actions/checkout@v7
24
+ - uses: actions/setup-python@v7
25
+ with:
26
+ python-version: "3.12"
27
+ - run: python -m pip install --upgrade pip
28
+ - run: pip install -e .
29
+ - run: python scripts/live_openapi_smoke.py
30
+
31
+
32
+ public-optimade:
33
+ continue-on-error: true
34
+ runs-on: ubuntu-latest
35
+ timeout-minutes: 10
36
+ steps:
37
+ - uses: actions/checkout@v7
38
+ - uses: actions/setup-python@v7
39
+ with:
40
+ python-version: "3.12"
41
+ - run: python -m pip install --upgrade pip
42
+ - run: pip install -e .
43
+ - run: python scripts/live_optimade_smoke.py
@@ -0,0 +1,58 @@
1
+ name: Docs
2
+
3
+ on:
4
+ push:
5
+ branches: [main]
6
+ workflow_dispatch:
7
+
8
+ concurrency:
9
+ group: github-pages
10
+ cancel-in-progress: true
11
+
12
+ jobs:
13
+ build:
14
+ permissions:
15
+ contents: read
16
+ pages: write
17
+ runs-on: ubuntu-latest
18
+ outputs:
19
+ pages_enabled: ${{ steps.pages.outputs.enabled }}
20
+ steps:
21
+ - uses: actions/checkout@v7
22
+ - uses: actions/setup-python@v7
23
+ with:
24
+ python-version: "3.12"
25
+ - name: Check whether GitHub Pages is enabled
26
+ id: pages
27
+ env:
28
+ GH_TOKEN: ${{ github.token }}
29
+ run: |
30
+ if gh api "repos/${GITHUB_REPOSITORY}/pages" >/dev/null 2>&1; then
31
+ echo "enabled=true" >> "$GITHUB_OUTPUT"
32
+ else
33
+ echo "enabled=false" >> "$GITHUB_OUTPUT"
34
+ echo "::notice::GitHub Pages is not enabled; deployment will be skipped."
35
+ fi
36
+ - run: python -m pip install --upgrade pip
37
+ - run: pip install -e ".[docs]"
38
+ - run: mkdocs build --strict
39
+ env:
40
+ NO_MKDOCS_2_WARNING: "1"
41
+ - uses: actions/upload-pages-artifact@v5
42
+ with:
43
+ path: site
44
+
45
+ deploy:
46
+ needs: build
47
+ if: needs.build.outputs.pages_enabled == 'true'
48
+ permissions:
49
+ pages: write
50
+ id-token: write
51
+ runs-on: ubuntu-latest
52
+ environment:
53
+ name: github-pages
54
+ url: ${{ steps.deployment.outputs.page_url }}
55
+ steps:
56
+ - name: Deploy to GitHub Pages
57
+ id: deployment
58
+ uses: actions/deploy-pages@v5
@@ -0,0 +1,113 @@
1
+ name: Release
2
+
3
+ on:
4
+ push:
5
+ tags:
6
+ - "v*"
7
+
8
+ permissions:
9
+ contents: read
10
+
11
+ jobs:
12
+ build:
13
+ runs-on: ubuntu-latest
14
+ steps:
15
+ - uses: actions/checkout@v7
16
+ - uses: actions/setup-python@v7
17
+ with:
18
+ python-version: "3.12"
19
+ - name: Verify tag matches package version
20
+ run: |
21
+ python - <<'PY'
22
+ import os
23
+ import tomllib
24
+ from pathlib import Path
25
+
26
+ version = tomllib.loads(Path("pyproject.toml").read_text())["project"]["version"]
27
+ tag = os.environ["GITHUB_REF_NAME"]
28
+ expected = f"v{version}"
29
+ if tag != expected:
30
+ raise SystemExit(f"tag {tag!r} does not match package version {expected!r}")
31
+ PY
32
+ - run: python -m pip install --upgrade pip
33
+ - run: pip install build twine
34
+ - run: python -m build
35
+ - run: twine check dist/*
36
+ - name: Verify release artifact
37
+ run: |
38
+ python - <<'PY'
39
+ import glob
40
+ import subprocess
41
+ import sys
42
+ import tempfile
43
+ import venv
44
+ import zipfile
45
+ from pathlib import Path
46
+
47
+ wheel = glob.glob("dist/*.whl")[0]
48
+ names = zipfile.ZipFile(wheel).namelist()
49
+ assert any(name.endswith("/licenses/LICENSE") for name in names), names
50
+
51
+ with tempfile.TemporaryDirectory() as root:
52
+ env = Path(root) / "venv"
53
+ venv.EnvBuilder(with_pip=True).create(env)
54
+ python = env / ("Scripts/python.exe" if sys.platform == "win32" else "bin/python")
55
+ subprocess.check_call([str(python), "-m", "pip", "install", wheel])
56
+ subprocess.check_call([
57
+ str(python),
58
+ "-c",
59
+ "import schemarouter; assert schemarouter.__version__ == '0.2.0a1'",
60
+ ])
61
+ PY
62
+ - uses: actions/upload-artifact@v4
63
+ with:
64
+ name: python-dist
65
+ path: dist/
66
+ if-no-files-found: error
67
+ retention-days: 7
68
+
69
+ github-release:
70
+ needs: build
71
+ permissions:
72
+ contents: write
73
+ runs-on: ubuntu-latest
74
+ steps:
75
+ - uses: actions/checkout@v7
76
+ - uses: actions/download-artifact@v4
77
+ with:
78
+ name: python-dist
79
+ path: dist
80
+ - name: Create or update GitHub prerelease
81
+ env:
82
+ GH_TOKEN: ${{ github.token }}
83
+ run: |
84
+ if gh release view "$GITHUB_REF_NAME" >/dev/null 2>&1; then
85
+ gh release upload "$GITHUB_REF_NAME" dist/* --clobber
86
+ gh release edit "$GITHUB_REF_NAME" \
87
+ --title "SchemaRouter 0.2.0a1" \
88
+ --notes-file "docs/releases/0.2.0a1.md" \
89
+ --prerelease
90
+ else
91
+ gh release create "$GITHUB_REF_NAME" dist/* \
92
+ --title "SchemaRouter 0.2.0a1" \
93
+ --notes-file "docs/releases/0.2.0a1.md" \
94
+ --prerelease \
95
+ --verify-tag
96
+ fi
97
+
98
+ pypi:
99
+ needs: build
100
+ permissions:
101
+ id-token: write
102
+ runs-on: ubuntu-latest
103
+ environment:
104
+ name: pypi
105
+ url: https://pypi.org/project/schemarouter/
106
+ steps:
107
+ - uses: actions/download-artifact@v4
108
+ with:
109
+ name: python-dist
110
+ path: dist
111
+ - uses: pypa/gh-action-pypi-publish@release/v1
112
+ with:
113
+ packages-dir: dist/
@@ -0,0 +1,9 @@
1
+ __pycache__/
2
+ *.py[cod]
3
+ .pytest_cache/
4
+ .ruff_cache/
5
+ .venv/
6
+ dist/
7
+ build/
8
+ *.egg-info/
9
+ site/
@@ -0,0 +1,45 @@
1
+ # Changelog
2
+
3
+ All notable changes to SchemaRouter are documented here.
4
+
5
+ The project is pre-1.0 and follows the compatibility rules in
6
+ [`docs/versioning.md`](docs/versioning.md).
7
+
8
+ ## Unreleased
9
+
10
+ No unreleased changes yet.
11
+
12
+ ## 0.2.0a1 - 2026-09-20
13
+
14
+ ### Added
15
+
16
+ - pluggable structured-source `AdapterRegistry` with explicit and priority-based auto discovery;
17
+ - OPTIMADE v1 discovery through base and entry-type info endpoints;
18
+ - OPTIMADE field-aware execution that maps planned fields to `response_fields`;
19
+ - call-aware invoker support for protocol adapters that need the full `ToolCall`;
20
+ - typed tool, endpoint, parameter, response-field, plan, and result contracts;
21
+ - namespaced versioned registry;
22
+ - schema-aware planning with recall-preserving field projection;
23
+ - provider-neutral model-assisted query analysis;
24
+ - OpenAPI 3.x URL ingestion and guarded HTTP execution;
25
+ - MCP tool discovery and execution;
26
+ - evidence-grounded proposals for human-readable API documentation;
27
+ - runtime JSON Schema validation for arguments and raw outputs;
28
+ - schema and invoker-binding drift detection;
29
+ - fail-closed execution policy for mutations, destructive calls, and unclassified remote tools;
30
+ - Runnable-style `invoke`, `batch`, `stream`, and typed event APIs;
31
+ - run configuration, concurrency control, and safe retry policy;
32
+ - typed Python callable registration with `@schema_tool`;
33
+ - optional LangChain `StructuredTool` integration;
34
+ - framework maturity, architecture, release, and versioning documentation;
35
+ - MIT licensing and package metadata;
36
+ - MkDocs Material documentation site with guides, recipes, and generated API reference;
37
+ - SchemaRouter brace-and-routing-hub brand system with light/dark marks, lockups, favicon, and social preview source artwork.
38
+
39
+ ### Security
40
+
41
+ - separated schema-fetch credentials from runtime API credentials;
42
+ - restricted schema redirects and runtime API origins;
43
+ - blocked model/tool control of sensitive runtime headers;
44
+ - redacted event payloads by default;
45
+ - prevented automatic retries for non-read-only calls.
@@ -0,0 +1,73 @@
1
+ # Contributing to SchemaRouter
2
+
3
+ SchemaRouter is a focused schema-aware planning and execution layer. Contributions should extend
4
+ that boundary without turning the project into a second general-purpose agent framework.
5
+
6
+ ## Development setup
7
+
8
+ ```bash
9
+ python -m venv .venv
10
+ source .venv/bin/activate
11
+ pip install -e ".[dev]"
12
+ ruff check .
13
+ pytest -q
14
+ python examples/quickstart.py
15
+ ```
16
+
17
+ Optional integrations have separate extras and tests. For example:
18
+
19
+ ```bash
20
+ pip install -e ".[dev,langchain]"
21
+ pytest -q tests/test_langchain_integration.py
22
+ ```
23
+
24
+ ## Design rules
25
+
26
+ Changes must preserve these principles:
27
+
28
+ 1. remote metadata describes capability but never grants execution authority;
29
+ 2. model output is untrusted until projected onto registered schemas;
30
+ 3. credentials remain outside model-visible arguments;
31
+ 4. schema and invoker drift fail closed;
32
+ 5. raw input/output values are validated before crossing the trusted execution boundary;
33
+ 6. mutations, destructive calls, and ambiguous remote side effects require local policy;
34
+ 7. observability must not expose payloads by default;
35
+ 8. integrations must call through SchemaRouter execution rather than bypassing it.
36
+
37
+ ## Adding an adapter
38
+
39
+ Adapters should produce normal `ToolSpec` / `EndpointSpec` contracts and a trusted invoker.
40
+ See [adapter authoring](docs/adapter-authoring.md).
41
+
42
+ Do not embed provider-specific authorization decisions into generic schema parsing.
43
+
44
+ ## Adding a framework integration
45
+
46
+ Integrations belong under `schemarouter.integrations` and should use optional dependencies with
47
+ lazy imports. The core package must remain importable without integration extras installed.
48
+
49
+ An integration should expose SchemaRouter contracts to another ecosystem; it should not duplicate
50
+ SchemaRouter planning, policy, schema validation, or transport authorization.
51
+
52
+ ## Brand changes
53
+
54
+ Production brand assets live under `docs/assets/brand/`. Treat the SVG files as the source of truth.
55
+
56
+ Brand changes should preserve the brace + routing-hub concept, graphite/teal palette, light/dark
57
+ contrast, and compact-mark legibility. Do not replace production SVGs with raster-only generated
58
+ artwork.
59
+
60
+ See the [brand guide](docs/project/brand.md).
61
+
62
+ ## Pull requests
63
+
64
+ A change is not complete until:
65
+
66
+ - tests cover its public behavior and adversarial failure cases;
67
+ - warnings remain clean;
68
+ - supported Python versions pass;
69
+ - public behavior is documented;
70
+ - new optional dependencies are isolated behind extras;
71
+ - breaking API changes include a changelog and migration note.
72
+
73
+ See [versioning](docs/versioning.md) and the [release checklist](docs/release-checklist.md).
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Yong-eun Cho
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.