selah 0.1.0rc1__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 (92) hide show
  1. selah-0.1.0rc1/PKG-INFO +105 -0
  2. selah-0.1.0rc1/README.md +81 -0
  3. selah-0.1.0rc1/pyproject.toml +62 -0
  4. selah-0.1.0rc1/src/selah/__init__.py +105 -0
  5. selah-0.1.0rc1/src/selah/adapters/__init__.py +38 -0
  6. selah-0.1.0rc1/src/selah/adapters/animation/__init__.py +29 -0
  7. selah-0.1.0rc1/src/selah/adapters/animation/application.py +269 -0
  8. selah-0.1.0rc1/src/selah/adapters/base.py +184 -0
  9. selah-0.1.0rc1/src/selah/adapters/google/__init__.py +29 -0
  10. selah-0.1.0rc1/src/selah/adapters/google/application.py +300 -0
  11. selah-0.1.0rc1/src/selah/adapters/http/__init__.py +23 -0
  12. selah-0.1.0rc1/src/selah/adapters/http/application.py +473 -0
  13. selah-0.1.0rc1/src/selah/adapters/mcp/__init__.py +5 -0
  14. selah-0.1.0rc1/src/selah/adapters/mcp/application.py +258 -0
  15. selah-0.1.0rc1/src/selah/adapters/noldorian/__init__.py +27 -0
  16. selah-0.1.0rc1/src/selah/adapters/noldorian/application.py +304 -0
  17. selah-0.1.0rc1/src/selah/adapters/runtime/__init__.py +29 -0
  18. selah-0.1.0rc1/src/selah/adapters/runtime/application.py +417 -0
  19. selah-0.1.0rc1/src/selah/authority.py +69 -0
  20. selah-0.1.0rc1/src/selah/capabilities.py +734 -0
  21. selah-0.1.0rc1/src/selah/cli.py +372 -0
  22. selah-0.1.0rc1/src/selah/compat/__init__.py +15 -0
  23. selah-0.1.0rc1/src/selah/compat/reader.py +247 -0
  24. selah-0.1.0rc1/src/selah/context.py +248 -0
  25. selah-0.1.0rc1/src/selah/discovery.py +263 -0
  26. selah-0.1.0rc1/src/selah/dispatch.py +571 -0
  27. selah-0.1.0rc1/src/selah/envelope.py +234 -0
  28. selah-0.1.0rc1/src/selah/identity.py +361 -0
  29. selah-0.1.0rc1/src/selah/input_boundary.py +280 -0
  30. selah-0.1.0rc1/src/selah/onboarding.py +1078 -0
  31. selah-0.1.0rc1/src/selah/orientation.py +780 -0
  32. selah-0.1.0rc1/src/selah/policy.py +815 -0
  33. selah-0.1.0rc1/src/selah/prompting/__init__.py +88 -0
  34. selah-0.1.0rc1/src/selah/prompting/binding.py +3 -0
  35. selah-0.1.0rc1/src/selah/prompting/bundle.py +3 -0
  36. selah-0.1.0rc1/src/selah/prompting/contracts.py +4355 -0
  37. selah-0.1.0rc1/src/selah/protocol/__init__.py +168 -0
  38. selah-0.1.0rc1/src/selah/protocol/ast.py +291 -0
  39. selah-0.1.0rc1/src/selah/protocol/canonical.py +476 -0
  40. selah-0.1.0rc1/src/selah/protocol/data/departments/languages/spanish/v1/module.json +16 -0
  41. selah-0.1.0rc1/src/selah/protocol/data/departments/legacy-profile-manifest.json +238 -0
  42. selah-0.1.0rc1/src/selah/protocol/data/departments/registry.json +135 -0
  43. selah-0.1.0rc1/src/selah/protocol/data/profiles/fennica/AUTHORITY-DECISION.json +19 -0
  44. selah-0.1.0rc1/src/selah/protocol/data/profiles/fennica/DRAFT.json +415 -0
  45. selah-0.1.0rc1/src/selah/protocol/data/profiles/germanica/AUTHORITY-DECISION.json +19 -0
  46. selah-0.1.0rc1/src/selah/protocol/data/profiles/germanica/DRAFT.json +395 -0
  47. selah-0.1.0rc1/src/selah/protocol/data/profiles/graeca/AUTHORITY-DECISION.json +19 -0
  48. selah-0.1.0rc1/src/selah/protocol/data/profiles/graeca/DRAFT.json +460 -0
  49. selah-0.1.0rc1/src/selah/protocol/data/profiles/hebraica/AUTHORITY-DECISION.json +19 -0
  50. selah-0.1.0rc1/src/selah/protocol/data/profiles/hebraica/DRAFT.json +277 -0
  51. selah-0.1.0rc1/src/selah/protocol/data/profiles/iaponica/AUTHORITY-DECISION.json +19 -0
  52. selah-0.1.0rc1/src/selah/protocol/data/profiles/iaponica/DRAFT.json +67 -0
  53. selah-0.1.0rc1/src/selah/protocol/data/profiles/latina/AUTHORITY-DECISION.json +14 -0
  54. selah-0.1.0rc1/src/selah/protocol/data/profiles/latina/DRAFT.json +100 -0
  55. selah-0.1.0rc1/src/selah/protocol/data/profiles/lusitana/AUTHORITY-DECISION.json +19 -0
  56. selah-0.1.0rc1/src/selah/protocol/data/profiles/lusitana/DRAFT.json +271 -0
  57. selah-0.1.0rc1/src/selah/protocol/data/profiles/russica/AUTHORITY-DECISION.json +19 -0
  58. selah-0.1.0rc1/src/selah/protocol/data/profiles/russica/DRAFT.json +320 -0
  59. selah-0.1.0rc1/src/selah/protocol/departmental.py +1241 -0
  60. selah-0.1.0rc1/src/selah/protocol/departments.py +4 -0
  61. selah-0.1.0rc1/src/selah/protocol/document.py +25 -0
  62. selah-0.1.0rc1/src/selah/protocol/errors.py +96 -0
  63. selah-0.1.0rc1/src/selah/protocol/parser.py +623 -0
  64. selah-0.1.0rc1/src/selah/protocol/profiles.py +507 -0
  65. selah-0.1.0rc1/src/selah/protocol/renderer.py +105 -0
  66. selah-0.1.0rc1/src/selah/protocol/schemas/__init__.py +1 -0
  67. selah-0.1.0rc1/src/selah/protocol/schemas/departmental-binding-v1/binding-record.schema.json +67 -0
  68. selah-0.1.0rc1/src/selah/protocol/schemas/departmental-binding-v1/binding-subject.schema.json +60 -0
  69. selah-0.1.0rc1/src/selah/protocol/schemas/departmental-document-v1/document.schema.json +119 -0
  70. selah-0.1.0rc1/src/selah/protocol/schemas/departmental-receipt-v1/receipt-record.schema.json +36 -0
  71. selah-0.1.0rc1/src/selah/protocol/schemas/departmental-receipt-v1/receipt-subject.schema.json +36 -0
  72. selah-0.1.0rc1/src/selah/protocol/schemas/prompt-bundle-v1/bundle-record.schema.json +58 -0
  73. selah-0.1.0rc1/src/selah/protocol/schemas/prompt-bundle-v1/bundle-subject.schema.json +50 -0
  74. selah-0.1.0rc1/src/selah/protocol/schemas/protocol-v1/__init__.py +1 -0
  75. selah-0.1.0rc1/src/selah/protocol/schemas/protocol-v1/common.schema.json +15 -0
  76. selah-0.1.0rc1/src/selah/protocol/schemas/protocol-v1/error.schema.json +24 -0
  77. selah-0.1.0rc1/src/selah/protocol/schemas/protocol-v1/index.json +20 -0
  78. selah-0.1.0rc1/src/selah/protocol/schemas/protocol-v1/message.schema.json +15 -0
  79. selah-0.1.0rc1/src/selah/protocol/schemas/protocol-v2/common.schema.json +23 -0
  80. selah-0.1.0rc1/src/selah/protocol/schemas/protocol-v2/frame.schema.json +34 -0
  81. selah-0.1.0rc1/src/selah/protocol/schemas/protocol-v2/index.json +23 -0
  82. selah-0.1.0rc1/src/selah/protocol/schemas/protocol-v2/parsed-native.schema.json +72 -0
  83. selah-0.1.0rc1/src/selah/provenance.py +142 -0
  84. selah-0.1.0rc1/src/selah/py.typed +1 -0
  85. selah-0.1.0rc1/src/selah/receipts.py +375 -0
  86. selah-0.1.0rc1/src/selah/sessions.py +122 -0
  87. selah-0.1.0rc1/src/selah/state/__init__.py +31 -0
  88. selah-0.1.0rc1/src/selah/state/backup.py +395 -0
  89. selah-0.1.0rc1/src/selah/state/errors.py +43 -0
  90. selah-0.1.0rc1/src/selah/state/migration.py +311 -0
  91. selah-0.1.0rc1/src/selah/state/repository.py +1381 -0
  92. selah-0.1.0rc1/src/selah/trust.py +113 -0
@@ -0,0 +1,105 @@
1
+ Metadata-Version: 2.5
2
+ Name: selah
3
+ Version: 0.1.0rc1
4
+ Summary: Model-, provider-, account-, and environment-neutral protocol package
5
+ Author: Everplay-Tech LLC
6
+ License-Expression: Apache-2.0
7
+ Requires-Python: >=3.11
8
+ Requires-Dist: rfc8785==0.1.4
9
+ Provides-Extra: all
10
+ Requires-Dist: fastapi<1,>=0.115; extra == 'all'
11
+ Requires-Dist: mcp<3,>=2.1; extra == 'all'
12
+ Requires-Dist: noldorian==0.2.6; extra == 'all'
13
+ Requires-Dist: uvicorn<1,>=0.30; extra == 'all'
14
+ Provides-Extra: animation
15
+ Provides-Extra: google
16
+ Provides-Extra: mcp
17
+ Requires-Dist: mcp<3,>=2.1; extra == 'mcp'
18
+ Provides-Extra: noldorian
19
+ Requires-Dist: noldorian==0.2.6; extra == 'noldorian'
20
+ Provides-Extra: server
21
+ Requires-Dist: fastapi<1,>=0.115; extra == 'server'
22
+ Requires-Dist: uvicorn<1,>=0.30; extra == 'server'
23
+ Description-Content-Type: text/markdown
24
+
25
+ # SELAH
26
+
27
+ SELAH is an agent-native integration system and protocol for portable identity, environment awareness, capability boundaries, and deterministic, receipt-backed communication.
28
+
29
+ It gives an agent a small, stable vocabulary for answering four practical questions:
30
+
31
+ 1. Who is this agent?
32
+ 2. What runtime, provider, account, environment, and project context is actually observed?
33
+ 3. Which capabilities are merely available, and which have been explicitly granted?
34
+ 4. What decision was made, and what evidence can another process verify?
35
+
36
+ SELAH is model-, provider-, account-, and environment-neutral. Its core does not call a model, choose a provider, read credentials, or infer authority from model text. Adapters supply authenticated evidence and provider-specific behavior at the boundary.
37
+
38
+ SELAH is installed to give an agent a portable, structured identity and an observed environment/capability/receipt layer. Departments govern documents and prompts through packaged language profiles, and Spanish is the explicit cross-department communication profile. Start with `selah --help`, then use the documented setup and orientation flow below.
39
+
40
+ ## Install
41
+
42
+ ~~~sh
43
+ python -m pip install selah==0.1.0rc1
44
+ ~~~
45
+
46
+ The base distribution has one runtime dependency, rfc8785==0.1.4. Optional adapter extras are available for mcp, server, google, noldorian, animation, and all. The core import does not load optional SDKs.
47
+
48
+ ## First run
49
+
50
+ The setup command asks for one human choice: name a new agent or select an existing opaque agent ID. It then reports local observations. If the adapter cannot know a context field, SELAH asks for a conditional confirmation instead of silently treating the field as known.
51
+
52
+ For a new identity, the conditional confirmation is bound to the pending transition saved in the configured state database. Re-running the same product-facing command with `--confirm` consumes that transition and reuses its candidate identity; a mismatched, expired, malformed, or already-consumed transition fails closed.
53
+
54
+ ~~~sh
55
+ STATE=.selah/selah.sqlite3
56
+
57
+ # First call: inspect the conditional context prompt.
58
+ selah --json --state "$STATE" setup --name Ada
59
+
60
+ # Second call: confirm that saving the still-unknown observations is acceptable.
61
+ selah --json --state "$STATE" setup --name Ada --confirm
62
+ ~~~
63
+
64
+ The setup response includes an identity, an observed context projection, and an onboarding receipt. The receipt is evidence of the transition; it is not a grant.
65
+
66
+ Inspect the saved orientation with the agent_id returned by setup:
67
+
68
+ ~~~sh
69
+ selah --json --state "$STATE" orient --agent-id agent:REPLACE_ME --profile latina
70
+ ~~~
71
+
72
+ Orientation is read-only. It distinguishes known values from unknown values, observed capabilities from authorized capabilities, and current authority from missing or stale authority.
73
+
74
+ ## Deny before allow
75
+
76
+ An observed capability is not permission. A grant must be issued by an authenticated authority adapter and must match the agent, scope, authority generation, and time window. The runnable quickstart at examples/selah/quickstart.py shows both paths:
77
+
78
+ ~~~sh
79
+ python examples/selah/quickstart.py
80
+ ~~~
81
+
82
+ The example reports:
83
+
84
+ - MISSING_GRANT when a capability is observed but no grant exists;
85
+ - ALLOW after an explicit, scoped grant is issued by the fixture verifier;
86
+ - the onboarding receipt ID and digest for later inspection.
87
+
88
+ The fixture uses an internal verifier seam only to keep the example offline and deterministic. A deployed adapter must obtain its issuer and principal from its authenticated transport or authority system; a caller cannot create them by supplying a label, boolean, or digest.
89
+
90
+ ## Runtime lifecycle mutations
91
+
92
+ The optional runtime lifecycle adapter keeps `status` read-only. `start` and `stop` require the typed identity, session, runtime lifecycle grant, ALLOW authority decision, an `ExecutableDispatch`, and its `StateRepository`. The dispatch nonce is claimed before the provider is loaded or called, so a dispatch can execute at most once. Bind the operation into the authority request with `RuntimeAdapter.operation_intent_hash("start")` or `RuntimeAdapter.operation_intent_hash("stop")`; callers using the mutation API without typed dispatch/state receive a stable denial.
93
+
94
+ ## What SELAH does not claim
95
+
96
+ SELAH does not promise universal protection from manipulation, prompt injection, or semantic drift. It makes a narrower, measured and testable claim: when an integration uses the typed language, authenticated context, explicit grants, fail-closed decisions, and receipts, the evaluation suite can measure whether particular drift and instruction-hacking cases were reduced. Results are reported by model, language profile, corpus, and release threshold rather than converted into a general guarantee.
97
+
98
+ ## Related documents
99
+
100
+ - docs/selah/SECURITY.md — identity, context, observations, grants, decisions, receipts, and the trust boundary.
101
+ - docs/selah/LANGUAGE.md — deterministic lexical and grammatical protocol behavior.
102
+ - docs/selah/MIGRATION.md — explicit one-way migration from legacy ACETATE records.
103
+ - examples/selah/quickstart.py — an offline installed-package walkthrough.
104
+
105
+ SELAH is not Dreamjournal. Dreamjournal is a separate product. SELAH is not a Dreamjournal dependency, and Dreamjournal is not a SELAH dependency. Neither package imports, bundles, or release-gates the other, and Dreamjournal does not provide SELAH identity or authority.
@@ -0,0 +1,81 @@
1
+ # SELAH
2
+
3
+ SELAH is an agent-native integration system and protocol for portable identity, environment awareness, capability boundaries, and deterministic, receipt-backed communication.
4
+
5
+ It gives an agent a small, stable vocabulary for answering four practical questions:
6
+
7
+ 1. Who is this agent?
8
+ 2. What runtime, provider, account, environment, and project context is actually observed?
9
+ 3. Which capabilities are merely available, and which have been explicitly granted?
10
+ 4. What decision was made, and what evidence can another process verify?
11
+
12
+ SELAH is model-, provider-, account-, and environment-neutral. Its core does not call a model, choose a provider, read credentials, or infer authority from model text. Adapters supply authenticated evidence and provider-specific behavior at the boundary.
13
+
14
+ SELAH is installed to give an agent a portable, structured identity and an observed environment/capability/receipt layer. Departments govern documents and prompts through packaged language profiles, and Spanish is the explicit cross-department communication profile. Start with `selah --help`, then use the documented setup and orientation flow below.
15
+
16
+ ## Install
17
+
18
+ ~~~sh
19
+ python -m pip install selah==0.1.0rc1
20
+ ~~~
21
+
22
+ The base distribution has one runtime dependency, rfc8785==0.1.4. Optional adapter extras are available for mcp, server, google, noldorian, animation, and all. The core import does not load optional SDKs.
23
+
24
+ ## First run
25
+
26
+ The setup command asks for one human choice: name a new agent or select an existing opaque agent ID. It then reports local observations. If the adapter cannot know a context field, SELAH asks for a conditional confirmation instead of silently treating the field as known.
27
+
28
+ For a new identity, the conditional confirmation is bound to the pending transition saved in the configured state database. Re-running the same product-facing command with `--confirm` consumes that transition and reuses its candidate identity; a mismatched, expired, malformed, or already-consumed transition fails closed.
29
+
30
+ ~~~sh
31
+ STATE=.selah/selah.sqlite3
32
+
33
+ # First call: inspect the conditional context prompt.
34
+ selah --json --state "$STATE" setup --name Ada
35
+
36
+ # Second call: confirm that saving the still-unknown observations is acceptable.
37
+ selah --json --state "$STATE" setup --name Ada --confirm
38
+ ~~~
39
+
40
+ The setup response includes an identity, an observed context projection, and an onboarding receipt. The receipt is evidence of the transition; it is not a grant.
41
+
42
+ Inspect the saved orientation with the agent_id returned by setup:
43
+
44
+ ~~~sh
45
+ selah --json --state "$STATE" orient --agent-id agent:REPLACE_ME --profile latina
46
+ ~~~
47
+
48
+ Orientation is read-only. It distinguishes known values from unknown values, observed capabilities from authorized capabilities, and current authority from missing or stale authority.
49
+
50
+ ## Deny before allow
51
+
52
+ An observed capability is not permission. A grant must be issued by an authenticated authority adapter and must match the agent, scope, authority generation, and time window. The runnable quickstart at examples/selah/quickstart.py shows both paths:
53
+
54
+ ~~~sh
55
+ python examples/selah/quickstart.py
56
+ ~~~
57
+
58
+ The example reports:
59
+
60
+ - MISSING_GRANT when a capability is observed but no grant exists;
61
+ - ALLOW after an explicit, scoped grant is issued by the fixture verifier;
62
+ - the onboarding receipt ID and digest for later inspection.
63
+
64
+ The fixture uses an internal verifier seam only to keep the example offline and deterministic. A deployed adapter must obtain its issuer and principal from its authenticated transport or authority system; a caller cannot create them by supplying a label, boolean, or digest.
65
+
66
+ ## Runtime lifecycle mutations
67
+
68
+ The optional runtime lifecycle adapter keeps `status` read-only. `start` and `stop` require the typed identity, session, runtime lifecycle grant, ALLOW authority decision, an `ExecutableDispatch`, and its `StateRepository`. The dispatch nonce is claimed before the provider is loaded or called, so a dispatch can execute at most once. Bind the operation into the authority request with `RuntimeAdapter.operation_intent_hash("start")` or `RuntimeAdapter.operation_intent_hash("stop")`; callers using the mutation API without typed dispatch/state receive a stable denial.
69
+
70
+ ## What SELAH does not claim
71
+
72
+ SELAH does not promise universal protection from manipulation, prompt injection, or semantic drift. It makes a narrower, measured and testable claim: when an integration uses the typed language, authenticated context, explicit grants, fail-closed decisions, and receipts, the evaluation suite can measure whether particular drift and instruction-hacking cases were reduced. Results are reported by model, language profile, corpus, and release threshold rather than converted into a general guarantee.
73
+
74
+ ## Related documents
75
+
76
+ - docs/selah/SECURITY.md — identity, context, observations, grants, decisions, receipts, and the trust boundary.
77
+ - docs/selah/LANGUAGE.md — deterministic lexical and grammatical protocol behavior.
78
+ - docs/selah/MIGRATION.md — explicit one-way migration from legacy ACETATE records.
79
+ - examples/selah/quickstart.py — an offline installed-package walkthrough.
80
+
81
+ SELAH is not Dreamjournal. Dreamjournal is a separate product. SELAH is not a Dreamjournal dependency, and Dreamjournal is not a SELAH dependency. Neither package imports, bundles, or release-gates the other, and Dreamjournal does not provide SELAH identity or authority.
@@ -0,0 +1,62 @@
1
+ [build-system]
2
+ requires = ["hatchling==1.32.0"]
3
+ build-backend = "hatchling.build"
4
+
5
+ [project]
6
+ name = "selah"
7
+ version = "0.1.0rc1"
8
+ description = "Model-, provider-, account-, and environment-neutral protocol package"
9
+ readme = "README.md"
10
+ requires-python = ">=3.11"
11
+ license = "Apache-2.0"
12
+ authors = [{name = "Everplay-Tech LLC"}]
13
+ dependencies = ["rfc8785==0.1.4"]
14
+
15
+ [project.optional-dependencies]
16
+ mcp = ["mcp>=2.1,<3"]
17
+ server = ["fastapi>=0.115,<1", "uvicorn>=0.30,<1"]
18
+ # Google and animation remain provider-neutral boundaries in this release;
19
+ # their adapters accept a user-selected provider/domain implementation.
20
+ google = []
21
+ noldorian = ["noldorian==0.2.6"]
22
+ animation = []
23
+ all = [
24
+ "mcp>=2.1,<3",
25
+ "fastapi>=0.115,<1",
26
+ "uvicorn>=0.30,<1",
27
+ "noldorian==0.2.6",
28
+ ]
29
+
30
+ [project.scripts]
31
+ selah = "selah.cli:main"
32
+
33
+ [dependency-groups]
34
+ acceptance = [
35
+ "build==1.6.1",
36
+ "hatchling==1.32.0",
37
+ "jsonschema==4.23.0",
38
+ "pytest==9.1.1",
39
+ ]
40
+
41
+ [tool.hatch.build.targets.wheel]
42
+ packages = ["src/selah"]
43
+
44
+ [tool.hatch.build.targets.sdist]
45
+ include = ["README.md", "pyproject.toml", "src/selah/**"]
46
+
47
+ # Kept as an explicit package-data contract for tooling that reads the
48
+ # historical setuptools metadata. Hatchling is the active PEP 517 backend.
49
+ [tool.setuptools.packages.find]
50
+ where = ["src"]
51
+ namespaces = true
52
+
53
+ [tool.setuptools.package-data]
54
+ selah = [
55
+ "py.typed",
56
+ "protocol/schemas/**/*.json",
57
+ "protocol/data/language-v2/**/*.json",
58
+ "protocol/data/profiles/**/*.json",
59
+ "protocol/data/departments/*.json",
60
+ "protocol/data/departments/**/*.json",
61
+ "protocol/schemas/departmental-document-v1/*.json",
62
+ ]
@@ -0,0 +1,105 @@
1
+ """Small, import-safe public SELAH package surface.
2
+
3
+ The exports below are typed core contracts. They are resolved lazily so
4
+ resource discovery can inspect an installed wheel without importing runtime
5
+ dependencies. Optional adapters and provider SDKs are never imported as a
6
+ side effect of importing :mod:`selah`.
7
+ """
8
+
9
+ from importlib import import_module
10
+ from typing import Any
11
+
12
+
13
+ __version__ = "0.1.0rc1"
14
+ PROTOCOL_VERSION = "SELAH/1"
15
+ LANGUAGE_VERSION = "SELAH/1"
16
+
17
+ _EXPORTS: dict[str, tuple[str, str]] = {
18
+ "AgentIdentity": (".identity", "AgentIdentity"),
19
+ "AgentOrientation": (".orientation", "AgentOrientation"),
20
+ "AuthorityDecision": (".authority", "AuthorityDecision"),
21
+ "AuthorityEngine": (".authority", "AuthorityEngine"),
22
+ "AuthorityRequest": (".authority", "AuthorityRequest"),
23
+ "AuthoritySession": (".authority", "AuthoritySession"),
24
+ "CapabilityDecision": (".capabilities", "CapabilityDecision"),
25
+ "CapabilityGrant": (".capabilities", "CapabilityGrant"),
26
+ "CapabilityObservation": (".capabilities", "CapabilityObservation"),
27
+ "CapabilityScope": (".capabilities", "CapabilityScope"),
28
+ "ContextObservation": (".context", "ContextObservation"),
29
+ "OnboardingChoice": (".onboarding", "OnboardingChoice"),
30
+ "OnboardingService": (".onboarding", "OnboardingService"),
31
+ "OrientationService": (".orientation", "OrientationService"),
32
+ "AgentDepartmentBinding": (".prompting", "AgentDepartmentBinding"),
33
+ "DepartmentBindingReceipt": (".prompting", "DepartmentBindingReceipt"),
34
+ "PromptBundleManifest": (".prompting", "PromptBundleManifest"),
35
+ "PromptBundleReceipt": (".prompting", "PromptBundleReceipt"),
36
+ "ReceiptDigestContract": (".prompting", "ReceiptDigestContract"),
37
+ "build_prompt_bundle": (".prompting", "build_prompt_bundle"),
38
+ "active_binding_at": (".prompting", "active_binding_at"),
39
+ "RuntimeIdentity": (".identity", "RuntimeIdentity"),
40
+ "SessionBinding": (".sessions", "SessionBinding"),
41
+ }
42
+
43
+
44
+ def __getattr__(name: str) -> Any:
45
+ """Load one documented core contract on first access."""
46
+
47
+ target = _EXPORTS.get(name)
48
+ if target is None:
49
+ raise AttributeError(f"module {__name__!r} has no attribute {name!r}")
50
+ module_name, attribute = target
51
+ value = getattr(import_module(module_name, __name__), attribute)
52
+ globals()[name] = value
53
+ return value
54
+
55
+
56
+ def protocol_version() -> str:
57
+ """Return the stable SELAH protocol identifier."""
58
+
59
+ return PROTOCOL_VERSION
60
+
61
+
62
+ def language_version() -> str:
63
+ """Return the strict native-language protocol identifier."""
64
+
65
+ return LANGUAGE_VERSION
66
+
67
+
68
+ def main(argv: object = None) -> int:
69
+ """Delegate lazily to :mod:`selah.cli` without loading it at import time."""
70
+
71
+ from .cli import main as cli_main
72
+
73
+ return cli_main(argv)
74
+
75
+ __all__ = [
76
+ "AgentIdentity",
77
+ "AgentDepartmentBinding",
78
+ "AgentOrientation",
79
+ "AuthorityDecision",
80
+ "AuthorityEngine",
81
+ "AuthorityRequest",
82
+ "AuthoritySession",
83
+ "CapabilityDecision",
84
+ "CapabilityGrant",
85
+ "CapabilityObservation",
86
+ "CapabilityScope",
87
+ "ContextObservation",
88
+ "DepartmentBindingReceipt",
89
+ "LANGUAGE_VERSION",
90
+ "OnboardingChoice",
91
+ "OnboardingService",
92
+ "OrientationService",
93
+ "PromptBundleManifest",
94
+ "PromptBundleReceipt",
95
+ "PROTOCOL_VERSION",
96
+ "RuntimeIdentity",
97
+ "ReceiptDigestContract",
98
+ "SessionBinding",
99
+ "active_binding_at",
100
+ "build_prompt_bundle",
101
+ "__version__",
102
+ "language_version",
103
+ "main",
104
+ "protocol_version",
105
+ ]
@@ -0,0 +1,38 @@
1
+ """Lazy discovery of replaceable SELAH adapters.
2
+
3
+ This registry contains names and import paths only. It never imports an
4
+ adapter, provider SDK, network client, or credential source on package import.
5
+ """
6
+
7
+ from __future__ import annotations
8
+
9
+ import importlib
10
+ from types import ModuleType
11
+
12
+
13
+ ADAPTER_MODULES = {
14
+ "animation": "selah.adapters.animation",
15
+ "google": "selah.adapters.google",
16
+ "http": "selah.adapters.http",
17
+ "mcp": "selah.adapters.mcp",
18
+ "noldorian": "selah.adapters.noldorian",
19
+ "runtime": "selah.adapters.runtime",
20
+ }
21
+ OPTIONAL_ADAPTERS = tuple(sorted(ADAPTER_MODULES))
22
+
23
+
24
+ def adapter_module(name: str) -> ModuleType:
25
+ """Load one named adapter; reject arbitrary module paths."""
26
+
27
+ if not isinstance(name, str) or name not in ADAPTER_MODULES:
28
+ raise ValueError("name must identify a documented SELAH adapter")
29
+ return importlib.import_module(ADAPTER_MODULES[name])
30
+
31
+
32
+ def adapter_modules() -> dict[str, str]:
33
+ """Return the stable adapter registry without importing its modules."""
34
+
35
+ return dict(ADAPTER_MODULES)
36
+
37
+
38
+ __all__ = ["ADAPTER_MODULES", "OPTIONAL_ADAPTERS", "adapter_module", "adapter_modules"]
@@ -0,0 +1,29 @@
1
+ """Optional animation-domain boundary for SELAH."""
2
+
3
+ from .application import (
4
+ ANIMATION_ADAPTER_VERSION,
5
+ ANIMATION_CAPABILITY,
6
+ ANIMATION_DOMAIN_VERSION,
7
+ AnimationAdapter,
8
+ AnimationAuthorityRequired,
9
+ AnimationError,
10
+ AnimationOperationRejected,
11
+ AnimationProfile,
12
+ AnimationProviderRejected,
13
+ adapter_manifest,
14
+ domain_profile,
15
+ )
16
+
17
+ __all__ = [
18
+ "ANIMATION_ADAPTER_VERSION",
19
+ "ANIMATION_CAPABILITY",
20
+ "ANIMATION_DOMAIN_VERSION",
21
+ "AnimationAdapter",
22
+ "AnimationAuthorityRequired",
23
+ "AnimationError",
24
+ "AnimationOperationRejected",
25
+ "AnimationProfile",
26
+ "AnimationProviderRejected",
27
+ "adapter_manifest",
28
+ "domain_profile",
29
+ ]