skillpool 4.3.0__py3-none-any.whl

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 (90) hide show
  1. skillpool/__init__.py +74 -0
  2. skillpool/__main__.py +6 -0
  3. skillpool/adapters/__init__.py +8 -0
  4. skillpool/adapters/base.py +41 -0
  5. skillpool/adapters/claude_adapter.py +36 -0
  6. skillpool/adapters/codex_adapter.py +92 -0
  7. skillpool/adapters/hermes_adapter.py +38 -0
  8. skillpool/audit/__init__.py +651 -0
  9. skillpool/bridge/__init__.py +16 -0
  10. skillpool/bridge/freeze_detector.py +134 -0
  11. skillpool/bridge/maintenance.py +119 -0
  12. skillpool/bridge/wal_manager.py +136 -0
  13. skillpool/clawmem_client.py +176 -0
  14. skillpool/cli.py +700 -0
  15. skillpool/combiner/__init__.py +31 -0
  16. skillpool/combiner/lifecycle.py +453 -0
  17. skillpool/combiner/models.py +99 -0
  18. skillpool/config.py +34 -0
  19. skillpool/cost/__init__.py +111 -0
  20. skillpool/cost/audit_hash.py +51 -0
  21. skillpool/cost/budget_tracker.py +66 -0
  22. skillpool/cost/dashboard.py +189 -0
  23. skillpool/cost/models.py +129 -0
  24. skillpool/cost/token_governor.py +264 -0
  25. skillpool/cost/trace_ceiling.py +38 -0
  26. skillpool/csdf.py +126 -0
  27. skillpool/evolver/__init__.py +978 -0
  28. skillpool/gain/__init__.py +285 -0
  29. skillpool/gate.py +282 -0
  30. skillpool/gate_policy/__init__.py +31 -0
  31. skillpool/gate_policy/incremental.py +157 -0
  32. skillpool/gate_policy/parser.py +258 -0
  33. skillpool/gate_policy/state_machine.py +432 -0
  34. skillpool/graph/__init__.py +14 -0
  35. skillpool/graph/ppr.py +279 -0
  36. skillpool/health/__init__.py +73 -0
  37. skillpool/health/check.py +85 -0
  38. skillpool/health/degradation.py +90 -0
  39. skillpool/health/models.py +43 -0
  40. skillpool/hooks/__init__.py +4 -0
  41. skillpool/hooks/security_scanner.py +288 -0
  42. skillpool/lifecycle.py +150 -0
  43. skillpool/materializer/__init__.py +124 -0
  44. skillpool/materializer/budget_cropper.py +178 -0
  45. skillpool/materializer/csdf_loader.py +114 -0
  46. skillpool/materializer/lazy_loader.py +265 -0
  47. skillpool/materializer/lifecycle_filter.py +93 -0
  48. skillpool/materializer/mapper.py +178 -0
  49. skillpool/materializer/models.py +66 -0
  50. skillpool/mcp_server.py +2005 -0
  51. skillpool/monitor/__init__.py +576 -0
  52. skillpool/monitor/bug_collector.py +392 -0
  53. skillpool/monitor/defect_classifier.py +218 -0
  54. skillpool/monitor/self_healing.py +530 -0
  55. skillpool/monitor/telemetry_bridge.py +197 -0
  56. skillpool/paradigm/__init__.py +312 -0
  57. skillpool/paradigm/override.py +285 -0
  58. skillpool/profile.py +94 -0
  59. skillpool/quality.py +254 -0
  60. skillpool/registry/__init__.py +509 -0
  61. skillpool/registry/models.py +98 -0
  62. skillpool/resolver/__init__.py +320 -0
  63. skillpool/resolver/cache.py +103 -0
  64. skillpool/resolver/circuit_breaker.py +103 -0
  65. skillpool/resolver/conflict_detector.py +111 -0
  66. skillpool/resolver/health_filter.py +38 -0
  67. skillpool/resolver/models.py +154 -0
  68. skillpool/resolver/rate_limiter.py +48 -0
  69. skillpool/resolver/skill_graph.py +183 -0
  70. skillpool/review/__init__.py +242 -0
  71. skillpool/review/async_queue.py +96 -0
  72. skillpool/review/checkpoint_runner.py +345 -0
  73. skillpool/review/models.py +164 -0
  74. skillpool/review/suspect_marker.py +39 -0
  75. skillpool/review/veto_evaluator.py +94 -0
  76. skillpool/router/__init__.py +481 -0
  77. skillpool/schemas.py +119 -0
  78. skillpool/synergy/__init__.py +240 -0
  79. skillpool/synergy/detector.py +5 -0
  80. skillpool/telemetry.py +126 -0
  81. skillpool/utils/__init__.py +21 -0
  82. skillpool/utils/changelog.py +218 -0
  83. skillpool/utils/logger.py +273 -0
  84. skillpool/utils/runtime_audit.py +163 -0
  85. skillpool/utils/time_utils.py +13 -0
  86. skillpool-4.3.0.dist-info/METADATA +21 -0
  87. skillpool-4.3.0.dist-info/RECORD +90 -0
  88. skillpool-4.3.0.dist-info/WHEEL +5 -0
  89. skillpool-4.3.0.dist-info/entry_points.txt +3 -0
  90. skillpool-4.3.0.dist-info/top_level.txt +1 -0
@@ -0,0 +1,273 @@
1
+ """SkillPoolLogger — structlog-style structured logging without external dependencies.
2
+
3
+ Processor chain: add_timestamp -> add_trace_id -> add_skill_context -> format_json
4
+ Context binding: bind_contextvars(skill_id=..., checkpoint=..., gate_result=...)
5
+ Canonical log lines: single JSON line with all context
6
+ Two renderers: JSONRenderer (prod) and ConsoleRenderer (dev, colored)
7
+ """
8
+
9
+ from __future__ import annotations
10
+
11
+ __all__ = [
12
+ "ConsoleRenderer",
13
+ "ContextVarsBinding",
14
+ "JSONRenderer",
15
+ "SkillPoolLogger",
16
+ "get_skillpool_logger",
17
+ ]
18
+
19
+ import json
20
+ import sys
21
+ from contextvars import ContextVar
22
+ from typing import Any
23
+
24
+ from skillpool.utils.time_utils import utc_now
25
+
26
+
27
+ # ── Context Variables ──
28
+
29
+ _context_vars: dict[str, ContextVar[Any]] = {}
30
+
31
+
32
+ def _get_context_var(key: str) -> ContextVar[Any]:
33
+ """Get or create a ContextVar for the given key."""
34
+ if key not in _context_vars:
35
+ _context_vars[key] = ContextVar(f"skillpool_log_{key}", default=None)
36
+ return _context_vars[key]
37
+
38
+
39
+ class ContextVarsBinding:
40
+ """Thread-safe + asyncio-safe context variable binding.
41
+
42
+ Uses Python's contextvars module for automatic propagation across
43
+ asyncio tasks and thread pools.
44
+ """
45
+
46
+ @staticmethod
47
+ def bind(**kwargs: Any) -> None:
48
+ """Bind context variables. These will be included in all subsequent log entries."""
49
+ for key, value in kwargs.items():
50
+ var = _get_context_var(key)
51
+ var.set(value)
52
+
53
+ @staticmethod
54
+ def unbind(*keys: str) -> None:
55
+ """Unbind context variables by resetting them to None."""
56
+ for key in keys:
57
+ var = _get_context_var(key)
58
+ var.set(None)
59
+
60
+ @staticmethod
61
+ def get() -> dict[str, Any]:
62
+ """Get all currently bound context variables as a dict."""
63
+ result: dict[str, Any] = {}
64
+ for key, var in _context_vars.items():
65
+ value = var.get(None)
66
+ if value is not None:
67
+ result[key] = value
68
+ return result
69
+
70
+
71
+ # ── Processors ──
72
+
73
+
74
+ def add_timestamp(logger: str, method: str, event_dict: dict[str, Any]) -> dict[str, Any]:
75
+ """Add ISO 8601 UTC timestamp to the event dict."""
76
+ if "timestamp" not in event_dict:
77
+ event_dict["timestamp"] = utc_now().isoformat()
78
+ return event_dict
79
+
80
+
81
+ def add_trace_id(logger: str, method: str, event_dict: dict[str, Any]) -> dict[str, Any]:
82
+ """Add trace_id from context vars if not already present."""
83
+ if "trace_id" not in event_dict:
84
+ ctx = ContextVarsBinding.get()
85
+ if "trace_id" in ctx:
86
+ event_dict["trace_id"] = ctx["trace_id"]
87
+ return event_dict
88
+
89
+
90
+ def add_skill_context(logger: str, method: str, event_dict: dict[str, Any]) -> dict[str, Any]:
91
+ """Add skill_id, checkpoint, gate_result from context vars."""
92
+ ctx = ContextVarsBinding.get()
93
+ for key in ("skill_id", "checkpoint", "gate_result"):
94
+ if key not in event_dict and key in ctx:
95
+ event_dict[key] = ctx[key]
96
+ return event_dict
97
+
98
+
99
+ def format_json(logger: str, method: str, event_dict: dict[str, Any]) -> dict[str, Any]:
100
+ """Ensure event_dict is JSON-serializable. No-op processor for consistency."""
101
+ return event_dict
102
+
103
+
104
+ # ── Renderers ──
105
+
106
+
107
+ class JSONRenderer:
108
+ """Render log events as single JSON lines (production)."""
109
+
110
+ def __call__(self, logger: str, method: str, event_dict: dict[str, Any]) -> str:
111
+ """Render event dict to a JSON string."""
112
+ return json.dumps(event_dict, sort_keys=True, ensure_ascii=False, default=str)
113
+
114
+
115
+ class ConsoleRenderer:
116
+ """Render log events as colored console output (development).
117
+
118
+ Color codes:
119
+ - DEBUG: grey
120
+ - INFO: green
121
+ - WARNING: yellow
122
+ - ERROR: red
123
+ """
124
+
125
+ _COLORS: dict[str, str] = {
126
+ "debug": "\033[90m", # grey
127
+ "info": "\033[32m", # green
128
+ "warning": "\033[33m", # yellow
129
+ "error": "\033[31m", # red
130
+ }
131
+ _RESET = "\033[0m"
132
+
133
+ def __init__(self, stream: Any | None = None) -> None:
134
+ self._stream = stream or sys.stderr
135
+ self._is_tty = hasattr(self._stream, "isatty") and self._stream.isatty()
136
+
137
+ def __call__(self, logger: str, method: str, event_dict: dict[str, Any]) -> str:
138
+ """Render event dict to a colored console line."""
139
+ level = method.upper()
140
+ timestamp = event_dict.pop("timestamp", "")
141
+ message = event_dict.pop("event", "")
142
+
143
+ # Build context suffix from remaining fields
144
+ context_parts = []
145
+ for k, v in sorted(event_dict.items()):
146
+ context_parts.append(f"{k}={v}")
147
+ context_str = " ".join(context_parts)
148
+
149
+ if self._is_tty:
150
+ color = self._COLORS.get(method, "")
151
+ line = f"{color}{level:<8}{self._RESET} {timestamp} {message}"
152
+ if context_str:
153
+ line += f" {context_str}"
154
+ else:
155
+ line = f"{level:<8} {timestamp} {message}"
156
+ if context_str:
157
+ line += f" {context_str}"
158
+
159
+ # Restore popped keys so the dict is not mutated for other processors
160
+ if timestamp:
161
+ event_dict["timestamp"] = timestamp
162
+ event_dict["event"] = message
163
+
164
+ return line
165
+
166
+
167
+ # ── Default processor chain ──
168
+
169
+ DEFAULT_PROCESSORS = [
170
+ add_timestamp,
171
+ add_trace_id,
172
+ add_skill_context,
173
+ format_json,
174
+ ]
175
+
176
+ DEFAULT_RENDERER = JSONRenderer()
177
+
178
+
179
+ def get_skillpool_logger(name: str) -> SkillPoolLogger:
180
+ """Factory: return a SkillPoolLogger with the appropriate renderer.
181
+
182
+ In prod (SKILLPOOL_LOG_LEVEL=PROD or when not a TTY), uses JSONRenderer.
183
+ Otherwise uses ConsoleRenderer for readable dev output.
184
+ """
185
+ import os as _os
186
+
187
+ _log_level = _os.environ.get("SKILLPOOL_LOG_LEVEL", "INFO").upper()
188
+ renderer: Any = ConsoleRenderer() if sys.stderr.isatty() else JSONRenderer()
189
+ return SkillPoolLogger(name=name, renderer=renderer)
190
+
191
+
192
+ # ── Logger ──
193
+
194
+
195
+ class SkillPoolLogger:
196
+ """structlog-style structured logger.
197
+
198
+ Processor chain: add_timestamp -> add_trace_id -> add_skill_context -> format_json
199
+ Each log entry goes through the processor chain, then gets rendered.
200
+
201
+ Args:
202
+ name: Logger name (usually module path).
203
+ processors: List of processor callables. Each takes (logger, method, event_dict) -> event_dict.
204
+ renderer: Final renderer callable. Takes (logger, method, event_dict) -> str.
205
+ """
206
+
207
+ def __init__(
208
+ self,
209
+ name: str,
210
+ processors: list | None = None,
211
+ renderer: Any | None = None,
212
+ ) -> None:
213
+ self._name = name
214
+ self._processors = processors or list(DEFAULT_PROCESSORS)
215
+ self._renderer = renderer or DEFAULT_RENDERER
216
+ self._bound: dict[str, Any] = {}
217
+
218
+ def bind(self, **kwargs: Any) -> SkillPoolLogger:
219
+ """Return a new logger with additional bound context.
220
+
221
+ The original logger is not modified.
222
+ """
223
+ new_logger = SkillPoolLogger(
224
+ name=self._name,
225
+ processors=self._processors,
226
+ renderer=self._renderer,
227
+ )
228
+ new_logger._bound = {**self._bound, **kwargs}
229
+ return new_logger
230
+
231
+ def _log(self, level: str, message: str, **kwargs: Any) -> None:
232
+ """Core logging method: build event dict, run processors, render, emit."""
233
+ event_dict: dict[str, Any] = {
234
+ "event": message,
235
+ "logger": self._name,
236
+ "level": level,
237
+ }
238
+
239
+ # Merge bound context
240
+ event_dict.update(self._bound)
241
+
242
+ # Merge call-site kwargs (override bound)
243
+ event_dict.update(kwargs)
244
+
245
+ # Run processor chain
246
+ for processor in self._processors:
247
+ event_dict = processor(self._name, level, event_dict)
248
+
249
+ # Render
250
+ output = self._renderer(self._name, level, event_dict)
251
+
252
+ # Emit to stderr
253
+ try:
254
+ sys.stderr.write(output + "\n")
255
+ sys.stderr.flush()
256
+ except (ValueError, OSError):
257
+ pass # stderr closed or broken — don't crash
258
+
259
+ def debug(self, message: str, **kwargs: Any) -> None:
260
+ """Log at DEBUG level."""
261
+ self._log("debug", message, **kwargs)
262
+
263
+ def info(self, message: str, **kwargs: Any) -> None:
264
+ """Log at INFO level."""
265
+ self._log("info", message, **kwargs)
266
+
267
+ def warning(self, message: str, **kwargs: Any) -> None:
268
+ """Log at WARNING level."""
269
+ self._log("warning", message, **kwargs)
270
+
271
+ def error(self, message: str, **kwargs: Any) -> None:
272
+ """Log at ERROR level."""
273
+ self._log("error", message, **kwargs)
@@ -0,0 +1,163 @@
1
+ """Runtime Audit Hook — Security monitoring via sys.addaudithook (PEP 578).
2
+
3
+ Tracks security-sensitive operations: exec, compile, open, subprocess.Popen,
4
+ socket.connect. Cannot be removed once registered (by design).
5
+ """
6
+
7
+ from __future__ import annotations
8
+
9
+ __all__ = [
10
+ "RuntimeAuditHook",
11
+ ]
12
+
13
+ import json
14
+ import os
15
+ import sys
16
+ from datetime import datetime, timezone
17
+ from pathlib import Path
18
+ from typing import Any, Callable
19
+
20
+
21
+ from skillpool.config import get_data_dir
22
+
23
+ _DEFAULT_LOG_DIR = get_data_dir() / "logs"
24
+ _DEFAULT_LOG_FILE = _DEFAULT_LOG_DIR / "runtime_audit.jsonl"
25
+
26
+
27
+ class RuntimeAuditHook:
28
+ """Monitor security-sensitive operations via sys.addaudithook.
29
+
30
+ Tracks: exec, compile, open, subprocess.Popen, socket.connect.
31
+ Cannot be removed once registered (by design — PEP 578 constraint).
32
+
33
+ Usage:
34
+ hook = RuntimeAuditHook()
35
+ hook.install()
36
+ # ... code runs, events are logged ...
37
+ events = hook.get_events()
38
+ """
39
+
40
+ MONITORED_EVENTS: frozenset[str] = frozenset(
41
+ {
42
+ "exec",
43
+ "compile",
44
+ "open",
45
+ "subprocess.Popen",
46
+ "socket.connect",
47
+ }
48
+ )
49
+
50
+ def __init__(
51
+ self,
52
+ callback: Callable[[str, tuple[Any, ...]], None] | None = None,
53
+ log_file: Path | None = None,
54
+ ) -> None:
55
+ """Initialize the audit hook.
56
+
57
+ Args:
58
+ callback: Optional custom callback receiving (event_name, args).
59
+ If None, events are logged to the default JSONL file.
60
+ log_file: Override the default log file path.
61
+ """
62
+ self._callback = callback
63
+ self._log_file = log_file or _DEFAULT_LOG_FILE
64
+ self._installed = False
65
+ self._events: list[dict[str, Any]] = []
66
+ self._in_handler = False # Reentrancy guard
67
+
68
+ def install(self, force: bool = False) -> None:
69
+ """Register the audit hook via sys.addaudithook.
70
+
71
+ Safe to call multiple times — subsequent calls are no-ops.
72
+ The hook cannot be removed once registered (PEP 578 design).
73
+
74
+ By default, only installs in production environments
75
+ (SKILLPOOL_ENV=prod). In dev/test, the I/O overhead of
76
+ monitoring every open/exec/subprocess event is prohibitive.
77
+ Use force=True to override this check.
78
+
79
+ Args:
80
+ force: Install regardless of environment (for tests).
81
+ """
82
+ if self._installed:
83
+ return
84
+
85
+ # Skip in non-production environments unless forced
86
+ env = os.environ.get("SKILLPOOL_ENV", "dev")
87
+ if env != "prod" and not force:
88
+ self._installed = True # Mark as installed to prevent retries
89
+ return
90
+ if self._installed:
91
+ return
92
+
93
+ def _audit_handler(event_name: str, args: tuple[Any, ...]) -> None:
94
+ if event_name not in self.MONITORED_EVENTS:
95
+ return
96
+
97
+ # Reentrancy guard: prevent infinite recursion when
98
+ # _log_to_file triggers its own 'open' audit event
99
+ if self._in_handler:
100
+ return
101
+ self._in_handler = True
102
+
103
+ try:
104
+ entry = {
105
+ "event": event_name,
106
+ "args": _serialize_args(args),
107
+ "timestamp": datetime.now(timezone.utc).isoformat(),
108
+ }
109
+
110
+ self._events.append(entry)
111
+
112
+ if self._callback:
113
+ self._callback(event_name, args)
114
+ else:
115
+ self._log_to_file(entry)
116
+ finally:
117
+ self._in_handler = False
118
+
119
+ sys.addaudithook(_audit_handler)
120
+ self._installed = True
121
+
122
+ def get_events(self) -> list[dict[str, Any]]:
123
+ """Retrieve all logged events since hook installation.
124
+
125
+ Returns:
126
+ List of event dicts with keys: event, args, timestamp.
127
+ """
128
+ return list(self._events)
129
+
130
+ def is_installed(self) -> bool:
131
+ """Check if the audit hook has been registered."""
132
+ return self._installed
133
+
134
+ def _log_to_file(self, entry: dict[str, Any]) -> None:
135
+ """Append an event entry to the JSONL log file."""
136
+ try:
137
+ self._log_file.parent.mkdir(parents=True, exist_ok=True)
138
+ with open(self._log_file, "a", encoding="utf-8") as f:
139
+ f.write(json.dumps(entry, ensure_ascii=False) + "\n")
140
+ except OSError:
141
+ # Silently fail — audit hook must not raise (PEP 578 constraint)
142
+ pass
143
+
144
+
145
+ def _serialize_args(args: tuple[Any, ...]) -> list[Any]:
146
+ """Convert audit hook args to JSON-serializable form.
147
+
148
+ Args may contain arbitrary objects; we convert what we can and
149
+ stringify the rest.
150
+ """
151
+ result: list[Any] = []
152
+ for arg in args:
153
+ if isinstance(arg, (str, int, float, bool, type(None))):
154
+ result.append(arg)
155
+ elif isinstance(arg, bytes):
156
+ result.append(arg.decode("utf-8", errors="replace"))
157
+ elif isinstance(arg, (list, tuple, set, frozenset)):
158
+ result.append(_serialize_args(tuple(arg)))
159
+ elif isinstance(arg, dict):
160
+ result.append({str(k): str(v) for k, v in arg.items()})
161
+ else:
162
+ result.append(str(arg))
163
+ return result
@@ -0,0 +1,13 @@
1
+ """Time utilities — timezone-aware UTC helpers."""
2
+
3
+ from __future__ import annotations
4
+
5
+ from datetime import datetime, timezone
6
+
7
+
8
+ def utc_now() -> datetime:
9
+ """Return the current UTC datetime (timezone-aware).
10
+
11
+ Replaces datetime.utcnow() which is deprecated and returns naive datetimes.
12
+ """
13
+ return datetime.now(timezone.utc)
@@ -0,0 +1,21 @@
1
+ Metadata-Version: 2.4
2
+ Name: skillpool
3
+ Version: 4.3.0
4
+ Summary: Skill Pool V4.3 — AI Agent Skill Governance & Delivery Platform
5
+ License: MIT
6
+ Requires-Python: >=3.11
7
+ Requires-Dist: click>=8.0
8
+ Requires-Dist: pydantic>=2.0
9
+ Requires-Dist: fastmcp>=0.2.0
10
+ Requires-Dist: pyyaml>=6.0
11
+ Requires-Dist: httpx>=0.24.0
12
+ Provides-Extra: graph
13
+ Requires-Dist: numpy>=1.24; extra == "graph"
14
+ Requires-Dist: scipy>=1.10; extra == "graph"
15
+ Provides-Extra: dev
16
+ Requires-Dist: pytest>=7.0; extra == "dev"
17
+ Requires-Dist: pytest-cov>=4.0; extra == "dev"
18
+ Requires-Dist: pytest-xdist>=3.0; extra == "dev"
19
+ Requires-Dist: pytest-asyncio>=0.21; extra == "dev"
20
+ Requires-Dist: pytest-bdd>=7.0; extra == "dev"
21
+ Requires-Dist: ruff>=0.1; extra == "dev"
@@ -0,0 +1,90 @@
1
+ skillpool/__init__.py,sha256=iqCqRbDt8qM961d-QyQePsf7lrGV5ge4LeGFEAoqW9I,2155
2
+ skillpool/__main__.py,sha256=4NyWBZ_yt1y4GxeCVehQv4XF3_7LZAUiTwkH0ms-wMY,125
3
+ skillpool/clawmem_client.py,sha256=7sQmBP6Jp6jb9dSNe-uQv97tBueqYnaurcixOgxZg1w,5973
4
+ skillpool/cli.py,sha256=k2bzzgJPzGOsQBL5F0soQQis5E1earcatrwImBwXcUI,26937
5
+ skillpool/config.py,sha256=_-wlKZjggznLD-i1KETzukeUmfeHsABp1t805wI2jLg,1109
6
+ skillpool/csdf.py,sha256=xtq9r3imOFzl-tw3Oj74McX-ILjWq-pYIZIRZ6No4yU,4103
7
+ skillpool/gate.py,sha256=cWadO5l-HYSk5dIO7VfvGfRIfjShBVjU-PSeS5unPKI,9190
8
+ skillpool/lifecycle.py,sha256=6CskpHbouOozUrwpUCZH7mZUtasa-jy5nQR2upISYR4,4869
9
+ skillpool/mcp_server.py,sha256=BfFEDzQtDGzUj59DtqtheTyI-tbndRi4NbV5FrJ1STs,73378
10
+ skillpool/profile.py,sha256=5Qr0s65IBgshazu4UCnqYyhOI-9Qd1DR5AZz7l4AOJA,3466
11
+ skillpool/quality.py,sha256=BHt5Uoq2VlVJF-zSLeFqqfwlmwy544qLpebwlnQi5Vs,8893
12
+ skillpool/schemas.py,sha256=CL0fY5_uUrH_LF8izJs7IXq_0_gN14C7MJPuTytrbpo,3837
13
+ skillpool/telemetry.py,sha256=8cNH7iBqP8cghkWj_-y2UFEsa44z1lSLpixaPxqP4g8,4104
14
+ skillpool/adapters/__init__.py,sha256=xkyEmCrHeLa5pZjkMBnBxEmSTfVv75z7RBYrBu3stVU,318
15
+ skillpool/adapters/base.py,sha256=-RaOTYdJelPlajkvf9AAhEuSZda0SnBbgldaQdVsN44,1518
16
+ skillpool/adapters/claude_adapter.py,sha256=CQ0AMtPWrj-EfDvbEpuhpH0SFL87UhXpCsQpvhh1jkg,1528
17
+ skillpool/adapters/codex_adapter.py,sha256=Zmaee0KAUCLTbRThBGKvi58s6DoZS-rhv0CaHpUPzpU,3903
18
+ skillpool/adapters/hermes_adapter.py,sha256=4d7LUSzRKb-1XtJ6h6XlcslSi8cHvk8xfbZRKOw2L0c,1658
19
+ skillpool/audit/__init__.py,sha256=VqifTn0OAmsaMxh1ovjL04I9AedpoEjOdXjcZpzRlhc,23726
20
+ skillpool/bridge/__init__.py,sha256=XDAu38vD3tCXt44IlyBFKAPA2mnQ4NRhUY_cNHSCnro,462
21
+ skillpool/bridge/freeze_detector.py,sha256=-_Dagt8vRyA1GBpZxVXBXTpjrmHo3LuvZWOt2XH9quw,4659
22
+ skillpool/bridge/maintenance.py,sha256=KdX58HDbee4EAPhe2L5aRjlfml57W6AkQWDS8vYlaYk,4271
23
+ skillpool/bridge/wal_manager.py,sha256=Zqa_s5y0-RsbvJuBStLTw-Hw1kufZwscLl73aumYIF4,4758
24
+ skillpool/combiner/__init__.py,sha256=IC8fH_6KqbgrkIq0IhuT5qhinyMwBnBBtVqim-YNjuM,1025
25
+ skillpool/combiner/lifecycle.py,sha256=2lJiRbs3ySsyJ__hdlMV9AjVZD7iWE_s6LcS8XL3My4,17167
26
+ skillpool/combiner/models.py,sha256=0K_W5TM1xWo9JRY3LiMMysPYam4wzjf0Ydd_gSZN0Cs,3912
27
+ skillpool/cost/__init__.py,sha256=3msWWd8zDJdC5nzmzSqRajzeisyQtMjtTYz7m2Lq8uU,4031
28
+ skillpool/cost/audit_hash.py,sha256=1kznujWw-ejUz94xKv9ahOtP-X0SxIKuUby8YZJsgHI,1797
29
+ skillpool/cost/budget_tracker.py,sha256=0GRHyxYlhgB2HVMXk3JhCtDGlE2SKeYnaKhLQHG4fgQ,2615
30
+ skillpool/cost/dashboard.py,sha256=PXOcKbcdbbg-xGlMcGjYufera5OQ3UArG7vvt1NiC80,7124
31
+ skillpool/cost/models.py,sha256=6NJU44FbWMn_i3DAD8b9vjHggQw3aggN5Kkd0YzPmlM,4491
32
+ skillpool/cost/token_governor.py,sha256=TXdCDd3T-iJZcLl9UbFx9-QiD0-GgtEQMW9ZXRE_h3o,10588
33
+ skillpool/cost/trace_ceiling.py,sha256=-SCYu5tnVjWf7niUJlug2gcHIc4zD1fvXFjAYPxXW6Y,1410
34
+ skillpool/evolver/__init__.py,sha256=DAoM0QhHtV8CBmJ6lkGsAv2f6ToDRBXo9POw9I41XoE,35972
35
+ skillpool/gain/__init__.py,sha256=4oIjzdwHPvhQ6-BA48T_rhLnPRB9VGH_GLTjm2GWC7Q,10464
36
+ skillpool/gate_policy/__init__.py,sha256=xfOoI5zbNcPqXyuDgwcTzJFTuwEWnRvlZS1CVlUM8cw,708
37
+ skillpool/gate_policy/incremental.py,sha256=s-DfM4KbTfEthaQfCxlbKJoki2p_brKGiSVr1xiDAho,4982
38
+ skillpool/gate_policy/parser.py,sha256=ZvpYRfpb0kh0tDqaquTAw6YhoQT2cImsbQ1dFcoUexo,8346
39
+ skillpool/gate_policy/state_machine.py,sha256=QCUlTVlgsfYSdy1HMwujzlBz-tzTBtRJ3DKnaSEMMyk,15592
40
+ skillpool/graph/__init__.py,sha256=V3gQE11svLSlFIKP_po6hCDHt8r4_PQg25fvvtFvpKM,486
41
+ skillpool/graph/ppr.py,sha256=-PKarRL0yU1t9s5YQTMp5X5sODOtkSCs9aNJtRUx9h0,7961
42
+ skillpool/health/__init__.py,sha256=ZeOs9tJGhRXOAideatmOkFP2Fqz-Q19MJJ7VF6ZeF6E,2748
43
+ skillpool/health/check.py,sha256=rtH2NK3_wPENYJ4_-R9fn2PxY2vL7xpyLPcq1SNhl8U,2693
44
+ skillpool/health/degradation.py,sha256=8rJCbTyH2JkN5Ob9hTDdwEYGjmuIi833ePNfJrHd7kQ,3722
45
+ skillpool/health/models.py,sha256=iZT4LcDlAHspRBsxz159myuQadUiilDUwmD2nZdeQbg,1410
46
+ skillpool/hooks/__init__.py,sha256=d7xaAwAcSmipiT9MRlaKOygFvtUCuXmycPTkL45X0vg,145
47
+ skillpool/hooks/security_scanner.py,sha256=sdhj3scNGolaUX7GAUInJBcayPgdFqbg7wH2VEUY_fk,11059
48
+ skillpool/materializer/__init__.py,sha256=lK2iQcHj8S63Ue58ANRNInaCPIFMNsuS0mOSABE0AhM,3883
49
+ skillpool/materializer/budget_cropper.py,sha256=2BPx-K_oh4O2UpKG28sePfllx7oWev5S499nNxZDGIw,6465
50
+ skillpool/materializer/csdf_loader.py,sha256=Tt-RC1XQrT6ap6eg2J5ir_EXPQfylDxPvgSatiSJIUo,3636
51
+ skillpool/materializer/lazy_loader.py,sha256=dtpHPuyeqdFe2MnQ_EaD6fHKfzB0Nmx3dPHCEMlwW0I,9922
52
+ skillpool/materializer/lifecycle_filter.py,sha256=tVtnTRptoP58yF0elovtZLSqlrXYaC1QCUU8ajyf538,3569
53
+ skillpool/materializer/mapper.py,sha256=8PZg1EXDAURmLSKtNLF6ePFFmS2VwpiRnv4DJFE9cg4,6021
54
+ skillpool/materializer/models.py,sha256=AgflQMn-9KHzeEQ9UDvmDSoCD7B2Xn0oHXrglRKgfEw,1998
55
+ skillpool/monitor/__init__.py,sha256=nsBkbNw1JUTijdyoPzKs3pWgL2rYNrhGaRvniHaSuUo,19319
56
+ skillpool/monitor/bug_collector.py,sha256=bJzWWJOevr6-HHE_lgvnPLcpCH8iWGWFJxLTr1HQa-Y,13779
57
+ skillpool/monitor/defect_classifier.py,sha256=yYSz5TBQaAkbSddfjUqJnLavbHDNWnXA3VWXa2pGHRk,8135
58
+ skillpool/monitor/self_healing.py,sha256=mNrlRCEsI4YSWNQBixk_HKKlyGZFUgAb8cKdtQG0CUo,19195
59
+ skillpool/monitor/telemetry_bridge.py,sha256=9vRxzoohO1i4oH6fi9VHUmCnN4zyCZ9g8m01f2aIuB4,6113
60
+ skillpool/paradigm/__init__.py,sha256=zXZBydz9yDryR4YWawrKnRX4B-mBR-lKQjB1CvkQHg4,11301
61
+ skillpool/paradigm/override.py,sha256=oOv788wwYhR_NZ5tmBIwtIjrIXFfNDlFkqnBHxv5l6c,9031
62
+ skillpool/registry/__init__.py,sha256=h5TjYzWCkSRJgAMgeeVVfUeu14HxBxqvySZVU_1Z-NE,17443
63
+ skillpool/registry/models.py,sha256=mTV6R1YxJ7tUKlLp3NWWYOdP_Bq2c-1ywjaoA_d85sg,2192
64
+ skillpool/resolver/__init__.py,sha256=Qkq4CATCmDel40S_G4rJqDzsWDMASAiVtg_MMCcsbqE,11410
65
+ skillpool/resolver/cache.py,sha256=uYIUBBTOwnzILQyKBvqiJFYfzfOn1Q7lY1V2juDAoSQ,3505
66
+ skillpool/resolver/circuit_breaker.py,sha256=bt-V3WL6fV1LkwcMgU0uA3kL9mEK8hiPfzEHsyFhlWw,3324
67
+ skillpool/resolver/conflict_detector.py,sha256=XUo7AdbvJUoNLZR1xjNBMhCqnbDotyWH880i7G8ZLRc,4212
68
+ skillpool/resolver/health_filter.py,sha256=qJmhrpET0WRQMdNeCQHtC8hGgZXUEfE1tBC8E_5MhkQ,1042
69
+ skillpool/resolver/models.py,sha256=1LzE4v6-vlW1EsF1eCymeY0cpI5EwEbLZlvVYBT8U7k,5451
70
+ skillpool/resolver/rate_limiter.py,sha256=P_asznbAVQT7U7EC6Cl8sdGb7G0gEBF-M4e2It7diWI,1474
71
+ skillpool/resolver/skill_graph.py,sha256=29xadJeFtAz46N2e7j6CskLlqxDObLp-uznpuHGD6Hk,6031
72
+ skillpool/review/__init__.py,sha256=u9wR2u7AwCGr3W7kAqXh9t7UX0IoXre6pvqAK5Q_NjE,9254
73
+ skillpool/review/async_queue.py,sha256=F9nqVSyHFMCikiHGDqar7EBv-gXY95Lwenza7_7-Gfs,3524
74
+ skillpool/review/checkpoint_runner.py,sha256=3cD_V8rip7Dtqr6BNuNdabdeOsbNHopc_g0eXRSkB44,12061
75
+ skillpool/review/models.py,sha256=HIL_1jXo58RnuDmYaSJ2_KBcmrMES4VTJcYn9M5mvMU,5147
76
+ skillpool/review/suspect_marker.py,sha256=SRp3nbNJIJZYEe0RgFmZoBJr5wDB43TdS3R7t0DG1Mw,1254
77
+ skillpool/review/veto_evaluator.py,sha256=Q6SEyWQuuvtwnlDrejGrNTQyhyYfG9JzDKu8nE4OLMo,3399
78
+ skillpool/router/__init__.py,sha256=CnS53PQ81IAkBAGgBnEgtxs3r_MQt0j5_z9_d5jIoLY,19540
79
+ skillpool/synergy/__init__.py,sha256=ggki1UfjGk4e0qT21Y97rRBFWUSZt1GL-oAthUb4_Qk,9695
80
+ skillpool/synergy/detector.py,sha256=2PXH_ImR-RHU4jYbwlZ2MWwA_m2JkquxH3UtM1x2oKk,216
81
+ skillpool/utils/__init__.py,sha256=28bgrDSBhCFHRpxlmq0qhj5GGkDKyriS4zeoMHhQ4x8,445
82
+ skillpool/utils/changelog.py,sha256=tIMSnJwsHKPI2Wig970hSbJxJ-qGlianN3PVepz128Y,7326
83
+ skillpool/utils/logger.py,sha256=uPlNPD0OQ9Ncthb4NDkKK5bZoLeMIP8FV0rTeVR1Rs4,8594
84
+ skillpool/utils/runtime_audit.py,sha256=D4irlvJ5NBKzF0gEtuCSyW9tDbrrQqzUWodAqQuK2ws,5274
85
+ skillpool/utils/time_utils.py,sha256=QUoDWFSQUEei-U6QfQOaASA5J-4obleWqickg008hdA,343
86
+ skillpool-4.3.0.dist-info/METADATA,sha256=hzNizCDwF59B7WjxlpQos37BWgHqWCkNNDQfYSnDR6E,717
87
+ skillpool-4.3.0.dist-info/WHEEL,sha256=aeYiig01lYGDzBgS8HxWXOg3uV61G9ijOsup-k9o1sk,91
88
+ skillpool-4.3.0.dist-info/entry_points.txt,sha256=BHsoSynXvvIDkxBXgjdv-sO0_IpWT3m1D5BkFEzLl8o,91
89
+ skillpool-4.3.0.dist-info/top_level.txt,sha256=ne3n_NFhpOKwQk8NODbsGyod7FIuqDczdDHv8S9xKzs,10
90
+ skillpool-4.3.0.dist-info/RECORD,,
@@ -0,0 +1,5 @@
1
+ Wheel-Version: 1.0
2
+ Generator: setuptools (82.0.1)
3
+ Root-Is-Purelib: true
4
+ Tag: py3-none-any
5
+
@@ -0,0 +1,3 @@
1
+ [console_scripts]
2
+ skillpool = skillpool.cli:main
3
+ skillpool-mcp = skillpool.mcp_server:main
@@ -0,0 +1 @@
1
+ skillpool