plm-skill-kernel 1.0.0__tar.gz → 1.0.2__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (53) hide show
  1. {plm_skill_kernel-1.0.0 → plm_skill_kernel-1.0.2}/PKG-INFO +137 -135
  2. {plm_skill_kernel-1.0.0 → plm_skill_kernel-1.0.2}/README.md +115 -115
  3. {plm_skill_kernel-1.0.0 → plm_skill_kernel-1.0.2}/plm_skill_kernel/__init__.py +33 -33
  4. {plm_skill_kernel-1.0.0 → plm_skill_kernel-1.0.2}/plm_skill_kernel/__main__.py +13 -13
  5. {plm_skill_kernel-1.0.0 → plm_skill_kernel-1.0.2}/plm_skill_kernel/dispatcher.py +141 -141
  6. {plm_skill_kernel-1.0.0 → plm_skill_kernel-1.0.2}/plm_skill_kernel/registry.py +80 -80
  7. {plm_skill_kernel-1.0.0 → plm_skill_kernel-1.0.2}/plm_skill_kernel/sdk/__init__.py +29 -29
  8. {plm_skill_kernel-1.0.0 → plm_skill_kernel-1.0.2}/plm_skill_kernel/sdk/_registry.py +111 -111
  9. {plm_skill_kernel-1.0.0 → plm_skill_kernel-1.0.2}/plm_skill_kernel/sdk/context.py +66 -66
  10. {plm_skill_kernel-1.0.0 → plm_skill_kernel-1.0.2}/plm_skill_kernel/sdk/decorator.py +147 -147
  11. {plm_skill_kernel-1.0.0 → plm_skill_kernel-1.0.2}/plm_skill_kernel/sdk/types.py +86 -86
  12. {plm_skill_kernel-1.0.0 → plm_skill_kernel-1.0.2}/plm_skill_kernel/server.py +173 -173
  13. {plm_skill_kernel-1.0.0 → plm_skill_kernel-1.0.2}/plm_skill_kernel/skills/__init__.py +16 -16
  14. {plm_skill_kernel-1.0.0 → plm_skill_kernel-1.0.2}/plm_skill_kernel/skills/agents/__init__.py +13 -13
  15. {plm_skill_kernel-1.0.0 → plm_skill_kernel-1.0.2}/plm_skill_kernel/skills/agents/suggest.py +191 -191
  16. {plm_skill_kernel-1.0.0 → plm_skill_kernel-1.0.2}/plm_skill_kernel/skills/bpmn/__init__.py +9 -9
  17. {plm_skill_kernel-1.0.0 → plm_skill_kernel-1.0.2}/plm_skill_kernel/skills/bpmn/generate.py +147 -147
  18. {plm_skill_kernel-1.0.0 → plm_skill_kernel-1.0.2}/plm_skill_kernel/skills/cleansing/__init__.py +10 -10
  19. {plm_skill_kernel-1.0.0 → plm_skill_kernel-1.0.2}/plm_skill_kernel/skills/cleansing/dedupe.py +162 -162
  20. {plm_skill_kernel-1.0.0 → plm_skill_kernel-1.0.2}/plm_skill_kernel/skills/cleansing/normalise.py +178 -178
  21. {plm_skill_kernel-1.0.0 → plm_skill_kernel-1.0.2}/plm_skill_kernel/skills/documents/__init__.py +12 -12
  22. {plm_skill_kernel-1.0.0 → plm_skill_kernel-1.0.2}/plm_skill_kernel/skills/documents/parse.py +202 -202
  23. {plm_skill_kernel-1.0.0 → plm_skill_kernel-1.0.2}/plm_skill_kernel/skills/knowledge/__init__.py +32 -32
  24. {plm_skill_kernel-1.0.0 → plm_skill_kernel-1.0.2}/plm_skill_kernel/skills/knowledge/_v1_corpus.py +153 -153
  25. {plm_skill_kernel-1.0.0 → plm_skill_kernel-1.0.2}/plm_skill_kernel/skills/knowledge/get_record.py +102 -102
  26. {plm_skill_kernel-1.0.0 → plm_skill_kernel-1.0.2}/plm_skill_kernel/skills/knowledge/resolve.py +143 -143
  27. {plm_skill_kernel-1.0.0 → plm_skill_kernel-1.0.2}/plm_skill_kernel/skills/knowledge/retrieve.py +143 -143
  28. {plm_skill_kernel-1.0.0 → plm_skill_kernel-1.0.2}/plm_skill_kernel/skills/knowledge/search.py +161 -161
  29. {plm_skill_kernel-1.0.0 → plm_skill_kernel-1.0.2}/plm_skill_kernel/skills/knowledge/validate.py +222 -222
  30. {plm_skill_kernel-1.0.0 → plm_skill_kernel-1.0.2}/plm_skill_kernel/skills_legacy/knowledge_pack_loader.py +17 -17
  31. {plm_skill_kernel-1.0.0 → plm_skill_kernel-1.0.2}/plm_skill_kernel/skills_legacy/knowledge_search_engine.py +25 -25
  32. {plm_skill_kernel-1.0.0 → plm_skill_kernel-1.0.2}/plm_skill_kernel/skills_legacy/plm_skill_registry.py +573 -573
  33. {plm_skill_kernel-1.0.0 → plm_skill_kernel-1.0.2}/plm_skill_kernel/skills_legacy/plm_tool_definitions.py +44 -44
  34. {plm_skill_kernel-1.0.0 → plm_skill_kernel-1.0.2}/plm_skill_kernel/skills_legacy/skill_orchestrator.py +172 -163
  35. {plm_skill_kernel-1.0.0 → plm_skill_kernel-1.0.2}/plm_skill_kernel.egg-info/PKG-INFO +137 -135
  36. {plm_skill_kernel-1.0.0 → plm_skill_kernel-1.0.2}/plm_skill_kernel.egg-info/requires.txt +3 -0
  37. {plm_skill_kernel-1.0.0 → plm_skill_kernel-1.0.2}/pyproject.toml +6 -1
  38. {plm_skill_kernel-1.0.0 → plm_skill_kernel-1.0.2}/setup.cfg +4 -4
  39. {plm_skill_kernel-1.0.0 → plm_skill_kernel-1.0.2}/tests/test_agents_suggest_asgi.py +208 -208
  40. {plm_skill_kernel-1.0.0 → plm_skill_kernel-1.0.2}/tests/test_agents_suggest_unit.py +72 -72
  41. {plm_skill_kernel-1.0.0 → plm_skill_kernel-1.0.2}/tests/test_dispatcher.py +98 -98
  42. {plm_skill_kernel-1.0.0 → plm_skill_kernel-1.0.2}/tests/test_documents_parse_asgi.py +197 -197
  43. {plm_skill_kernel-1.0.0 → plm_skill_kernel-1.0.2}/tests/test_documents_parse_unit.py +99 -99
  44. {plm_skill_kernel-1.0.0 → plm_skill_kernel-1.0.2}/tests/test_sdk_decorator.py +113 -113
  45. {plm_skill_kernel-1.0.0 → plm_skill_kernel-1.0.2}/tests/test_server.py +202 -202
  46. {plm_skill_kernel-1.0.0 → plm_skill_kernel-1.0.2}/tests/test_skills_cleansing.py +203 -203
  47. {plm_skill_kernel-1.0.0 → plm_skill_kernel-1.0.2}/tests/test_skills_knowledge.py +376 -376
  48. {plm_skill_kernel-1.0.0 → plm_skill_kernel-1.0.2}/tests/test_skills_knowledge_registry.py +81 -81
  49. {plm_skill_kernel-1.0.0 → plm_skill_kernel-1.0.2}/plm_skill_kernel/skills_legacy/__init__.py +0 -0
  50. {plm_skill_kernel-1.0.0 → plm_skill_kernel-1.0.2}/plm_skill_kernel.egg-info/SOURCES.txt +0 -0
  51. {plm_skill_kernel-1.0.0 → plm_skill_kernel-1.0.2}/plm_skill_kernel.egg-info/dependency_links.txt +0 -0
  52. {plm_skill_kernel-1.0.0 → plm_skill_kernel-1.0.2}/plm_skill_kernel.egg-info/entry_points.txt +0 -0
  53. {plm_skill_kernel-1.0.0 → plm_skill_kernel-1.0.2}/plm_skill_kernel.egg-info/top_level.txt +0 -0
@@ -1,135 +1,137 @@
1
- Metadata-Version: 2.4
2
- Name: plm-skill-kernel
3
- Version: 1.0.0
4
- Summary: TracePulse PLM Skill Kernel — Wave 2 Conv A. Decorator-based Skill SDK + V1 in-process dispatcher + Kernel HTTP server stub matching CR.10 §7.bis (POST /v1/skills/{id}/invoke). Ships 3 starter skills (cleansing.normalise, cleansing.dedupe, bpmn.generate). Sibling of plm-engine-core; the two communicate over the V1.1 HTTP loopback (SKILL_KERNEL_LOOPBACK=on) — no Python-level coupling at the dispatch boundary.
5
- Author: TracePulse
6
- License: Proprietary
7
- Requires-Python: >=3.12
8
- Description-Content-Type: text/markdown
9
- Requires-Dist: plm-shared
10
- Requires-Dist: pydantic>=2.5.0
11
- Requires-Dist: fastapi>=0.110
12
- Requires-Dist: uvicorn>=0.27
13
- Requires-Dist: httpx>=0.27.0
14
- Requires-Dist: plm-engine-core
15
- Requires-Dist: plm-knowledge
16
- Provides-Extra: test
17
- Requires-Dist: pytest; extra == "test"
18
- Requires-Dist: pytest-asyncio; extra == "test"
19
- Requires-Dist: httpx<1,>=0.27; extra == "test"
20
-
21
- # plm-skill-kernel
22
-
23
- Wave 2 Conv A (FTR-604). The Skill Kernel package — sibling of
24
- `plm-engine-core` — that hosts the decorator-based Skill SDK, the V1
25
- in-process dispatcher, and the Kernel HTTP server stub matching CR.10
26
- §7.bis verbatim.
27
-
28
- ## Layout
29
-
30
- ```
31
- 02_App/plm-skill-kernel/
32
- ├── pyproject.toml # editable install + import-linter contracts
33
- ├── plm_skill_kernel/
34
- │ ├── __init__.py # re-exports `skill`, `SkillContext`, etc.
35
- │ ├── __main__.py # `python -m plm_skill_kernel` → server
36
- │ ├── server.py # FastAPI app at POST /v1/skills/{id}/invoke
37
- │ ├── dispatcher.py # V1 in-process invoker
38
- │ ├── registry.py # boot wiring — discovers + registers skills
39
- │ ├── sdk/
40
- │ │ ├── decorator.py # `@skill(id=, version=)`
41
- │ │ ├── context.py # SkillContext Pydantic
42
- │ │ ├── types.py # SkillInvokeRequest / SkillInvokeResult
43
- │ │ └── _registry.py # in-process decorator registry
44
- │ └── skills/ # 3 starter skills (Q-W2A-1 nested layout)
45
- │ ├── cleansing/
46
- │ │ ├── normalise.py # cleansing.normalise / 1.0.0 / L2
47
- │ │ └── dedupe.py # cleansing.dedupe / 1.0.0 / L2
48
- │ └── bpmn/
49
- │ └── generate.py # bpmn.generate / 1.0.0 / L1 (thin proxy)
50
- └── tests/ # unit + ASGI in-process integration
51
- ```
52
-
53
- ## Editable install
54
-
55
- ```bash
56
- cd 02_App/backend
57
- .\venv\Scripts\Activate.ps1 # Windows
58
- pip install -e ../plm-skill-kernel
59
- ```
60
-
61
- Mirrors the plm-engine-core editable-install pattern.
62
-
63
- ## Dev launch (Q-W2A-3)
64
-
65
- ```bash
66
- python -m plm_skill_kernel # uvicorn on port 8100
67
- plm-skill-kernel --port 8100 # equivalent CLI
68
- ```
69
-
70
- The backend at port 8000 is unaffected. The V1.1 loopback round-trip
71
- (D-CONV-M-4 closure) sends HTTP from the Engine Core dispatcher to
72
- this Kernel server when `SKILL_KERNEL_LOOPBACK=on`.
73
-
74
- ## V1 wire contract
75
-
76
- `POST /v1/skills/{id}/invoke` — frozen at CR.10 §7.bis.
77
-
78
- ```
79
- Headers:
80
- X-Core-Caller: <UUID> (required when caller is Core)
81
- Idempotency-Key: <uuid> (optional, V1)
82
- traceparent: <W3C> (optional)
83
-
84
- Request body (SkillInvokeRequest):
85
- payload: Dict[str, Any]
86
- version: str ("1.0.0", etc.)
87
- autonomy_hint: Optional[str] ("L1" / "L2" / "L3")
88
-
89
- Response body (SkillInvokeResult):
90
- ok: bool
91
- result: Optional[Dict[str, Any]]
92
- error: Optional[SkillErrorEnvelope]
93
- deferred_to: Optional[str]
94
- cancelled: Optional[bool]
95
- ```
96
-
97
- ## Skill authoring (Decision #59 — decorator)
98
-
99
- ```python
100
- from plm_skill_kernel import skill, SkillContext
101
-
102
- @skill(id="cleansing.normalise", version="1.0.0")
103
- async def normalise(payload: dict, ctx: SkillContext) -> dict:
104
- return {"normalised": _normalise_records(payload["records"])}
105
- ```
106
-
107
- The decorator auto-registers into the in-process registry at module
108
- import time + carries `version` through to the federated manifest
109
- builder (CR.9).
110
-
111
- ## Import-linter contracts
112
-
113
- Two Forbidden contracts live in `pyproject.toml`:
114
-
115
- 1. `plm_skill_kernel` MUST NOT import `plm_engine_core` — federation
116
- contract preservation. The two communicate over HTTP, not Python.
117
- 2. `plm_skill_kernel` MUST NOT import `plm_accelerators` (Workbench)
118
- — mirror of the plm-engine-core constraint.
119
-
120
- Run:
121
-
122
- ```bash
123
- lint-imports --config 02_App/plm-skill-kernel/pyproject.toml
124
- ```
125
-
126
- ## Tests
127
-
128
- ```bash
129
- cd 02_App/plm-skill-kernel
130
- python -m pytest -q
131
- ```
132
-
133
- The V1.1 HTTP round-trip integration test mounts the FastAPI app via
134
- httpx.AsyncClient(ASGITransport) — no subprocess, no real port
135
- (Q-W2A-4).
1
+ Metadata-Version: 2.4
2
+ Name: plm-skill-kernel
3
+ Version: 1.0.2
4
+ Summary: TracePulse PLM Skill Kernel — Wave 2 Conv A. Decorator-based Skill SDK + V1 in-process dispatcher + Kernel HTTP server stub matching CR.10 §7.bis (POST /v1/skills/{id}/invoke). Ships 3 starter skills (cleansing.normalise, cleansing.dedupe, bpmn.generate). Sibling of plm-engine-core; the two communicate over the V1.1 HTTP loopback (SKILL_KERNEL_LOOPBACK=on) — no Python-level coupling at the dispatch boundary.
5
+ Author: TracePulse
6
+ License: Proprietary
7
+ Requires-Python: >=3.12
8
+ Description-Content-Type: text/markdown
9
+ Requires-Dist: plm-shared
10
+ Requires-Dist: pydantic>=2.5.0
11
+ Requires-Dist: fastapi>=0.110
12
+ Requires-Dist: uvicorn>=0.27
13
+ Requires-Dist: httpx>=0.27.0
14
+ Requires-Dist: plm-engine-core
15
+ Requires-Dist: plm-knowledge
16
+ Provides-Extra: test
17
+ Requires-Dist: pytest; extra == "test"
18
+ Requires-Dist: pytest-asyncio; extra == "test"
19
+ Requires-Dist: httpx<1,>=0.27; extra == "test"
20
+ Provides-Extra: docs
21
+ Requires-Dist: pdoc>=14.0; extra == "docs"
22
+
23
+ # plm-skill-kernel
24
+
25
+ Wave 2 Conv A (FTR-604). The Skill Kernel package — sibling of
26
+ `plm-engine-core` — that hosts the decorator-based Skill SDK, the V1
27
+ in-process dispatcher, and the Kernel HTTP server stub matching CR.10
28
+ §7.bis verbatim.
29
+
30
+ ## Layout
31
+
32
+ ```
33
+ 02_App/plm-skill-kernel/
34
+ ├── pyproject.toml # editable install + import-linter contracts
35
+ ├── plm_skill_kernel/
36
+ │ ├── __init__.py # re-exports `skill`, `SkillContext`, etc.
37
+ │ ├── __main__.py # `python -m plm_skill_kernel` → server
38
+ │ ├── server.py # FastAPI app at POST /v1/skills/{id}/invoke
39
+ │ ├── dispatcher.py # V1 in-process invoker
40
+ │ ├── registry.py # boot wiring — discovers + registers skills
41
+ │ ├── sdk/
42
+ │ │ ├── decorator.py # `@skill(id=, version=)`
43
+ │ │ ├── context.py # SkillContext Pydantic
44
+ │ │ ├── types.py # SkillInvokeRequest / SkillInvokeResult
45
+ │ │ └── _registry.py # in-process decorator registry
46
+ │ └── skills/ # 3 starter skills (Q-W2A-1 nested layout)
47
+ │ ├── cleansing/
48
+ │ │ ├── normalise.py # cleansing.normalise / 1.0.0 / L2
49
+ │ │ └── dedupe.py # cleansing.dedupe / 1.0.0 / L2
50
+ │ └── bpmn/
51
+ │ └── generate.py # bpmn.generate / 1.0.0 / L1 (thin proxy)
52
+ └── tests/ # unit + ASGI in-process integration
53
+ ```
54
+
55
+ ## Editable install
56
+
57
+ ```bash
58
+ cd 02_App/backend
59
+ .\venv\Scripts\Activate.ps1 # Windows
60
+ pip install -e ../plm-skill-kernel
61
+ ```
62
+
63
+ Mirrors the plm-engine-core editable-install pattern.
64
+
65
+ ## Dev launch (Q-W2A-3)
66
+
67
+ ```bash
68
+ python -m plm_skill_kernel # uvicorn on port 8100
69
+ plm-skill-kernel --port 8100 # equivalent CLI
70
+ ```
71
+
72
+ The backend at port 8000 is unaffected. The V1.1 loopback round-trip
73
+ (D-CONV-M-4 closure) sends HTTP from the Engine Core dispatcher to
74
+ this Kernel server when `SKILL_KERNEL_LOOPBACK=on`.
75
+
76
+ ## V1 wire contract
77
+
78
+ `POST /v1/skills/{id}/invoke` — frozen at CR.10 §7.bis.
79
+
80
+ ```
81
+ Headers:
82
+ X-Core-Caller: <UUID> (required when caller is Core)
83
+ Idempotency-Key: <uuid> (optional, V1)
84
+ traceparent: <W3C> (optional)
85
+
86
+ Request body (SkillInvokeRequest):
87
+ payload: Dict[str, Any]
88
+ version: str ("1.0.0", etc.)
89
+ autonomy_hint: Optional[str] ("L1" / "L2" / "L3")
90
+
91
+ Response body (SkillInvokeResult):
92
+ ok: bool
93
+ result: Optional[Dict[str, Any]]
94
+ error: Optional[SkillErrorEnvelope]
95
+ deferred_to: Optional[str]
96
+ cancelled: Optional[bool]
97
+ ```
98
+
99
+ ## Skill authoring (Decision #59 — decorator)
100
+
101
+ ```python
102
+ from plm_skill_kernel import skill, SkillContext
103
+
104
+ @skill(id="cleansing.normalise", version="1.0.0")
105
+ async def normalise(payload: dict, ctx: SkillContext) -> dict:
106
+ return {"normalised": _normalise_records(payload["records"])}
107
+ ```
108
+
109
+ The decorator auto-registers into the in-process registry at module
110
+ import time + carries `version` through to the federated manifest
111
+ builder (CR.9).
112
+
113
+ ## Import-linter contracts
114
+
115
+ Two Forbidden contracts live in `pyproject.toml`:
116
+
117
+ 1. `plm_skill_kernel` MUST NOT import `plm_engine_core` — federation
118
+ contract preservation. The two communicate over HTTP, not Python.
119
+ 2. `plm_skill_kernel` MUST NOT import `plm_accelerators` (Workbench)
120
+ — mirror of the plm-engine-core constraint.
121
+
122
+ Run:
123
+
124
+ ```bash
125
+ lint-imports --config 02_App/plm-skill-kernel/pyproject.toml
126
+ ```
127
+
128
+ ## Tests
129
+
130
+ ```bash
131
+ cd 02_App/plm-skill-kernel
132
+ python -m pytest -q
133
+ ```
134
+
135
+ The V1.1 HTTP round-trip integration test mounts the FastAPI app via
136
+ httpx.AsyncClient(ASGITransport) — no subprocess, no real port
137
+ (Q-W2A-4).
@@ -1,115 +1,115 @@
1
- # plm-skill-kernel
2
-
3
- Wave 2 Conv A (FTR-604). The Skill Kernel package — sibling of
4
- `plm-engine-core` — that hosts the decorator-based Skill SDK, the V1
5
- in-process dispatcher, and the Kernel HTTP server stub matching CR.10
6
- §7.bis verbatim.
7
-
8
- ## Layout
9
-
10
- ```
11
- 02_App/plm-skill-kernel/
12
- ├── pyproject.toml # editable install + import-linter contracts
13
- ├── plm_skill_kernel/
14
- │ ├── __init__.py # re-exports `skill`, `SkillContext`, etc.
15
- │ ├── __main__.py # `python -m plm_skill_kernel` → server
16
- │ ├── server.py # FastAPI app at POST /v1/skills/{id}/invoke
17
- │ ├── dispatcher.py # V1 in-process invoker
18
- │ ├── registry.py # boot wiring — discovers + registers skills
19
- │ ├── sdk/
20
- │ │ ├── decorator.py # `@skill(id=, version=)`
21
- │ │ ├── context.py # SkillContext Pydantic
22
- │ │ ├── types.py # SkillInvokeRequest / SkillInvokeResult
23
- │ │ └── _registry.py # in-process decorator registry
24
- │ └── skills/ # 3 starter skills (Q-W2A-1 nested layout)
25
- │ ├── cleansing/
26
- │ │ ├── normalise.py # cleansing.normalise / 1.0.0 / L2
27
- │ │ └── dedupe.py # cleansing.dedupe / 1.0.0 / L2
28
- │ └── bpmn/
29
- │ └── generate.py # bpmn.generate / 1.0.0 / L1 (thin proxy)
30
- └── tests/ # unit + ASGI in-process integration
31
- ```
32
-
33
- ## Editable install
34
-
35
- ```bash
36
- cd 02_App/backend
37
- .\venv\Scripts\Activate.ps1 # Windows
38
- pip install -e ../plm-skill-kernel
39
- ```
40
-
41
- Mirrors the plm-engine-core editable-install pattern.
42
-
43
- ## Dev launch (Q-W2A-3)
44
-
45
- ```bash
46
- python -m plm_skill_kernel # uvicorn on port 8100
47
- plm-skill-kernel --port 8100 # equivalent CLI
48
- ```
49
-
50
- The backend at port 8000 is unaffected. The V1.1 loopback round-trip
51
- (D-CONV-M-4 closure) sends HTTP from the Engine Core dispatcher to
52
- this Kernel server when `SKILL_KERNEL_LOOPBACK=on`.
53
-
54
- ## V1 wire contract
55
-
56
- `POST /v1/skills/{id}/invoke` — frozen at CR.10 §7.bis.
57
-
58
- ```
59
- Headers:
60
- X-Core-Caller: <UUID> (required when caller is Core)
61
- Idempotency-Key: <uuid> (optional, V1)
62
- traceparent: <W3C> (optional)
63
-
64
- Request body (SkillInvokeRequest):
65
- payload: Dict[str, Any]
66
- version: str ("1.0.0", etc.)
67
- autonomy_hint: Optional[str] ("L1" / "L2" / "L3")
68
-
69
- Response body (SkillInvokeResult):
70
- ok: bool
71
- result: Optional[Dict[str, Any]]
72
- error: Optional[SkillErrorEnvelope]
73
- deferred_to: Optional[str]
74
- cancelled: Optional[bool]
75
- ```
76
-
77
- ## Skill authoring (Decision #59 — decorator)
78
-
79
- ```python
80
- from plm_skill_kernel import skill, SkillContext
81
-
82
- @skill(id="cleansing.normalise", version="1.0.0")
83
- async def normalise(payload: dict, ctx: SkillContext) -> dict:
84
- return {"normalised": _normalise_records(payload["records"])}
85
- ```
86
-
87
- The decorator auto-registers into the in-process registry at module
88
- import time + carries `version` through to the federated manifest
89
- builder (CR.9).
90
-
91
- ## Import-linter contracts
92
-
93
- Two Forbidden contracts live in `pyproject.toml`:
94
-
95
- 1. `plm_skill_kernel` MUST NOT import `plm_engine_core` — federation
96
- contract preservation. The two communicate over HTTP, not Python.
97
- 2. `plm_skill_kernel` MUST NOT import `plm_accelerators` (Workbench)
98
- — mirror of the plm-engine-core constraint.
99
-
100
- Run:
101
-
102
- ```bash
103
- lint-imports --config 02_App/plm-skill-kernel/pyproject.toml
104
- ```
105
-
106
- ## Tests
107
-
108
- ```bash
109
- cd 02_App/plm-skill-kernel
110
- python -m pytest -q
111
- ```
112
-
113
- The V1.1 HTTP round-trip integration test mounts the FastAPI app via
114
- httpx.AsyncClient(ASGITransport) — no subprocess, no real port
115
- (Q-W2A-4).
1
+ # plm-skill-kernel
2
+
3
+ Wave 2 Conv A (FTR-604). The Skill Kernel package — sibling of
4
+ `plm-engine-core` — that hosts the decorator-based Skill SDK, the V1
5
+ in-process dispatcher, and the Kernel HTTP server stub matching CR.10
6
+ §7.bis verbatim.
7
+
8
+ ## Layout
9
+
10
+ ```
11
+ 02_App/plm-skill-kernel/
12
+ ├── pyproject.toml # editable install + import-linter contracts
13
+ ├── plm_skill_kernel/
14
+ │ ├── __init__.py # re-exports `skill`, `SkillContext`, etc.
15
+ │ ├── __main__.py # `python -m plm_skill_kernel` → server
16
+ │ ├── server.py # FastAPI app at POST /v1/skills/{id}/invoke
17
+ │ ├── dispatcher.py # V1 in-process invoker
18
+ │ ├── registry.py # boot wiring — discovers + registers skills
19
+ │ ├── sdk/
20
+ │ │ ├── decorator.py # `@skill(id=, version=)`
21
+ │ │ ├── context.py # SkillContext Pydantic
22
+ │ │ ├── types.py # SkillInvokeRequest / SkillInvokeResult
23
+ │ │ └── _registry.py # in-process decorator registry
24
+ │ └── skills/ # 3 starter skills (Q-W2A-1 nested layout)
25
+ │ ├── cleansing/
26
+ │ │ ├── normalise.py # cleansing.normalise / 1.0.0 / L2
27
+ │ │ └── dedupe.py # cleansing.dedupe / 1.0.0 / L2
28
+ │ └── bpmn/
29
+ │ └── generate.py # bpmn.generate / 1.0.0 / L1 (thin proxy)
30
+ └── tests/ # unit + ASGI in-process integration
31
+ ```
32
+
33
+ ## Editable install
34
+
35
+ ```bash
36
+ cd 02_App/backend
37
+ .\venv\Scripts\Activate.ps1 # Windows
38
+ pip install -e ../plm-skill-kernel
39
+ ```
40
+
41
+ Mirrors the plm-engine-core editable-install pattern.
42
+
43
+ ## Dev launch (Q-W2A-3)
44
+
45
+ ```bash
46
+ python -m plm_skill_kernel # uvicorn on port 8100
47
+ plm-skill-kernel --port 8100 # equivalent CLI
48
+ ```
49
+
50
+ The backend at port 8000 is unaffected. The V1.1 loopback round-trip
51
+ (D-CONV-M-4 closure) sends HTTP from the Engine Core dispatcher to
52
+ this Kernel server when `SKILL_KERNEL_LOOPBACK=on`.
53
+
54
+ ## V1 wire contract
55
+
56
+ `POST /v1/skills/{id}/invoke` — frozen at CR.10 §7.bis.
57
+
58
+ ```
59
+ Headers:
60
+ X-Core-Caller: <UUID> (required when caller is Core)
61
+ Idempotency-Key: <uuid> (optional, V1)
62
+ traceparent: <W3C> (optional)
63
+
64
+ Request body (SkillInvokeRequest):
65
+ payload: Dict[str, Any]
66
+ version: str ("1.0.0", etc.)
67
+ autonomy_hint: Optional[str] ("L1" / "L2" / "L3")
68
+
69
+ Response body (SkillInvokeResult):
70
+ ok: bool
71
+ result: Optional[Dict[str, Any]]
72
+ error: Optional[SkillErrorEnvelope]
73
+ deferred_to: Optional[str]
74
+ cancelled: Optional[bool]
75
+ ```
76
+
77
+ ## Skill authoring (Decision #59 — decorator)
78
+
79
+ ```python
80
+ from plm_skill_kernel import skill, SkillContext
81
+
82
+ @skill(id="cleansing.normalise", version="1.0.0")
83
+ async def normalise(payload: dict, ctx: SkillContext) -> dict:
84
+ return {"normalised": _normalise_records(payload["records"])}
85
+ ```
86
+
87
+ The decorator auto-registers into the in-process registry at module
88
+ import time + carries `version` through to the federated manifest
89
+ builder (CR.9).
90
+
91
+ ## Import-linter contracts
92
+
93
+ Two Forbidden contracts live in `pyproject.toml`:
94
+
95
+ 1. `plm_skill_kernel` MUST NOT import `plm_engine_core` — federation
96
+ contract preservation. The two communicate over HTTP, not Python.
97
+ 2. `plm_skill_kernel` MUST NOT import `plm_accelerators` (Workbench)
98
+ — mirror of the plm-engine-core constraint.
99
+
100
+ Run:
101
+
102
+ ```bash
103
+ lint-imports --config 02_App/plm-skill-kernel/pyproject.toml
104
+ ```
105
+
106
+ ## Tests
107
+
108
+ ```bash
109
+ cd 02_App/plm-skill-kernel
110
+ python -m pytest -q
111
+ ```
112
+
113
+ The V1.1 HTTP round-trip integration test mounts the FastAPI app via
114
+ httpx.AsyncClient(ASGITransport) — no subprocess, no real port
115
+ (Q-W2A-4).
@@ -1,33 +1,33 @@
1
- """TracePulse PLM Skill Kernel — Wave 2 Conv A (FTR-604).
2
-
3
- Sibling of ``plm-engine-core``. Owns:
4
-
5
- * The decorator-based Skill SDK (Decision #59 — Q-W2A-1 nested layout).
6
- * The V1 in-process dispatcher.
7
- * The Kernel HTTP server stub at ``POST /v1/skills/{id}/invoke``
8
- matching CR.10 §7.bis verbatim.
9
- * 3 starter skills harvested per Decision #60 — ``cleansing.normalise``,
10
- ``cleansing.dedupe``, ``bpmn.generate``.
11
-
12
- The Kernel and the Engine Core are deployed-separable. Their only
13
- sanctioned interaction is the V1.1 HTTP loopback (env-flagged on
14
- ``SKILL_KERNEL_LOOPBACK``); any Python-level reach-in is forbidden by
15
- the import-linter contract in ``pyproject.toml``.
16
- """
17
- __version__ = "0.1.0-alpha"
18
-
19
- # The decorator + sdk surface is the public authoring API. Re-exported
20
- # here so callers write ``from plm_skill_kernel import skill`` rather
21
- # than the deeper path. Skill author imports stay short + stable.
22
- from .sdk.decorator import skill
23
- from .sdk.context import SkillContext
24
- from .sdk.types import SkillInvokeRequest, SkillInvokeResult, SkillErrorEnvelope
25
-
26
- __all__ = [
27
- "SkillContext",
28
- "SkillErrorEnvelope",
29
- "SkillInvokeRequest",
30
- "SkillInvokeResult",
31
- "__version__",
32
- "skill",
33
- ]
1
+ """TracePulse PLM Skill Kernel — Wave 2 Conv A (FTR-604).
2
+
3
+ Sibling of ``plm-engine-core``. Owns:
4
+
5
+ * The decorator-based Skill SDK (Decision #59 — Q-W2A-1 nested layout).
6
+ * The V1 in-process dispatcher.
7
+ * The Kernel HTTP server stub at ``POST /v1/skills/{id}/invoke``
8
+ matching CR.10 §7.bis verbatim.
9
+ * 3 starter skills harvested per Decision #60 — ``cleansing.normalise``,
10
+ ``cleansing.dedupe``, ``bpmn.generate``.
11
+
12
+ The Kernel and the Engine Core are deployed-separable. Their only
13
+ sanctioned interaction is the V1.1 HTTP loopback (env-flagged on
14
+ ``SKILL_KERNEL_LOOPBACK``); any Python-level reach-in is forbidden by
15
+ the import-linter contract in ``pyproject.toml``.
16
+ """
17
+ __version__ = "1.0.2"
18
+
19
+ # The decorator + sdk surface is the public authoring API. Re-exported
20
+ # here so callers write ``from plm_skill_kernel import skill`` rather
21
+ # than the deeper path. Skill author imports stay short + stable.
22
+ from .sdk.decorator import skill
23
+ from .sdk.context import SkillContext
24
+ from .sdk.types import SkillInvokeRequest, SkillInvokeResult, SkillErrorEnvelope
25
+
26
+ __all__ = [
27
+ "SkillContext",
28
+ "SkillErrorEnvelope",
29
+ "SkillInvokeRequest",
30
+ "SkillInvokeResult",
31
+ "__version__",
32
+ "skill",
33
+ ]
@@ -1,13 +1,13 @@
1
- """``python -m plm_skill_kernel`` entry — delegates to :func:`server._cli_entry`.
2
-
3
- Q-W2A-3 picked the standalone launch shape. The ``__main__`` module is
4
- the canonical Python idiom; the ``plm-skill-kernel`` console script
5
- points at the same function via ``pyproject.toml [project.scripts]``.
6
- """
7
- from __future__ import annotations
8
-
9
- from .server import _cli_entry
10
-
11
-
12
- if __name__ == "__main__":
13
- _cli_entry()
1
+ """``python -m plm_skill_kernel`` entry — delegates to :func:`server._cli_entry`.
2
+
3
+ Q-W2A-3 picked the standalone launch shape. The ``__main__`` module is
4
+ the canonical Python idiom; the ``plm-skill-kernel`` console script
5
+ points at the same function via ``pyproject.toml [project.scripts]``.
6
+ """
7
+ from __future__ import annotations
8
+
9
+ from .server import _cli_entry
10
+
11
+
12
+ if __name__ == "__main__":
13
+ _cli_entry()