bensz-skill-kernel 0.14.1__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.
- bensz_skill_kernel/__init__.py +159 -0
- bensz_skill_kernel/atomic_verifiers.py +93 -0
- bensz_skill_kernel/builtins.py +114 -0
- bensz_skill_kernel/cli.py +640 -0
- bensz_skill_kernel/contract_packs.py +864 -0
- bensz_skill_kernel/contracts.py +121 -0
- bensz_skill_kernel/packs.py +215 -0
- bensz_skill_kernel/runtime.py +1090 -0
- bensz_skill_kernel/state_ids.py +39 -0
- bensz_skill_kernel/states/active/STATE.md +42 -0
- bensz_skill_kernel/states/cancelled/STATE.md +32 -0
- bensz_skill_kernel/states/checking/STATE.md +45 -0
- bensz_skill_kernel/states/completed/STATE.md +35 -0
- bensz_skill_kernel/states/delivering/STATE.md +43 -0
- bensz_skill_kernel/states/failed/STATE.md +33 -0
- bensz_skill_kernel/states/index.json +16 -0
- bensz_skill_kernel/states/planned/STATE.md +41 -0
- bensz_skill_kernel/states/waiting/STATE.md +41 -0
- bensz_skill_kernel/states/workspace-closed/STATE.md +37 -0
- bensz_skill_kernel/states/workspace-ready/STATE.md +42 -0
- bensz_skill_kernel/states.py +706 -0
- bensz_skill_kernel/verifier_ids.py +34 -0
- bensz_skill_kernel/verifiers/artifact-file-exists/VERIFIER.md +4 -0
- bensz_skill_kernel/verifiers/artifact-file-exists/scripts/verify.py +24 -0
- bensz_skill_kernel/verifiers/citation-truth-and-fit/VERIFIER.md +6 -0
- bensz_skill_kernel/verifiers/contract-conformance/VERIFIER.md +3 -0
- bensz_skill_kernel/verifiers/contract-conformance/scripts/verify.py +5 -0
- bensz_skill_kernel/verifiers/diff-scope/VERIFIER.md +3 -0
- bensz_skill_kernel/verifiers/diff-scope/scripts/verify.py +5 -0
- bensz_skill_kernel/verifiers/event-integrity/VERIFIER.md +3 -0
- bensz_skill_kernel/verifiers/event-integrity/scripts/verify.py +5 -0
- bensz_skill_kernel/verifiers/evidence-provenance/VERIFIER.md +3 -0
- bensz_skill_kernel/verifiers/evidence-provenance/scripts/verify.py +5 -0
- bensz_skill_kernel/verifiers/index.json +18 -0
- bensz_skill_kernel/verifiers/markdown-link-integrity/VERIFIER.md +8 -0
- bensz_skill_kernel/verifiers/markdown-link-integrity/scripts/collector.py +261 -0
- bensz_skill_kernel/verifiers/markdown-link-integrity/scripts/verify.py +47 -0
- bensz_skill_kernel/verifiers/path-scope/VERIFIER.md +3 -0
- bensz_skill_kernel/verifiers/path-scope/scripts/verify.py +5 -0
- bensz_skill_kernel/verifiers/schema-conformance/VERIFIER.md +3 -0
- bensz_skill_kernel/verifiers/schema-conformance/scripts/verify.py +5 -0
- bensz_skill_kernel/verifiers/secret-redaction/VERIFIER.md +3 -0
- bensz_skill_kernel/verifiers/secret-redaction/scripts/verify.py +5 -0
- bensz_skill_kernel/verifiers/state-transition/VERIFIER.md +3 -0
- bensz_skill_kernel/verifiers/state-transition/scripts/verify.py +5 -0
- bensz_skill_kernel/verifiers/task-completeness/VERIFIER.md +3 -0
- bensz_skill_kernel/verifiers/task-completeness/scripts/verify.py +5 -0
- bensz_skill_kernel/verifiers.py +896 -0
- bensz_skill_kernel/workspace.py +269 -0
- bensz_skill_kernel-0.14.1.dist-info/METADATA +159 -0
- bensz_skill_kernel-0.14.1.dist-info/RECORD +55 -0
- bensz_skill_kernel-0.14.1.dist-info/WHEEL +5 -0
- bensz_skill_kernel-0.14.1.dist-info/entry_points.txt +2 -0
- bensz_skill_kernel-0.14.1.dist-info/licenses/LICENSE +21 -0
- bensz_skill_kernel-0.14.1.dist-info/top_level.txt +1 -0
|
@@ -0,0 +1,159 @@
|
|
|
1
|
+
"""Minimal, append-only runtime kernel for Agent Skill task lifecycles."""
|
|
2
|
+
|
|
3
|
+
from .runtime import (
|
|
4
|
+
CompletionError,
|
|
5
|
+
EventEnvelope,
|
|
6
|
+
EventLog,
|
|
7
|
+
IntegrityError,
|
|
8
|
+
IdempotencyConflict,
|
|
9
|
+
AuthorizationError,
|
|
10
|
+
InvalidTransition,
|
|
11
|
+
KernelError,
|
|
12
|
+
VALID_STATES,
|
|
13
|
+
reduce_events,
|
|
14
|
+
)
|
|
15
|
+
from .contracts import Artifact, Authorization, Contract, Effect, Requirement, Subject, RUNTIME_PROTOCOL_VERSION
|
|
16
|
+
from .contract_packs import (
|
|
17
|
+
COMPONENT_RESULT_PROTOCOL,
|
|
18
|
+
CONTRACT_EXECUTION_PROTOCOL,
|
|
19
|
+
ComponentHandoff,
|
|
20
|
+
ComponentResult,
|
|
21
|
+
ContractBindingError,
|
|
22
|
+
ContractComponent,
|
|
23
|
+
ContractExecutionError,
|
|
24
|
+
ContractExecutionReport,
|
|
25
|
+
ContractPack,
|
|
26
|
+
ContractPackExecutor,
|
|
27
|
+
)
|
|
28
|
+
from .verifiers import (
|
|
29
|
+
Evidence,
|
|
30
|
+
CombinedVerifierRegistry,
|
|
31
|
+
FilesystemVerifierRegistry,
|
|
32
|
+
GateDecision,
|
|
33
|
+
PackRegistry,
|
|
34
|
+
VerifierPack,
|
|
35
|
+
VerifierRunner,
|
|
36
|
+
VerifierSpec,
|
|
37
|
+
VerifierDefinition,
|
|
38
|
+
VerifierRegistry,
|
|
39
|
+
VerificationRequest,
|
|
40
|
+
VerificationResult,
|
|
41
|
+
VerifierContractAdapter,
|
|
42
|
+
VerifierContractExecution,
|
|
43
|
+
apply_gate,
|
|
44
|
+
builtin_verifier_root,
|
|
45
|
+
normalize_result,
|
|
46
|
+
snapshot_evidence,
|
|
47
|
+
summarize_metrics,
|
|
48
|
+
normalize_requirements,
|
|
49
|
+
)
|
|
50
|
+
from .builtins import CITATION_TRUTH_FIT_SPEC, FILE_SPEC, build_builtin_registry, collect_markdown
|
|
51
|
+
from .verifier_ids import validate_verifier_id
|
|
52
|
+
from .state_ids import validate_state_id
|
|
53
|
+
from .states import CombinedStateRegistry, FilesystemStateRegistry, META_STATE_PROTOCOL_VERSION, SKILL_STATE_DECLARATION_VERSION, SkillStateDeclaration, StateContractAdapter, StateDefinition, StateDefinitionError, StateExecutionError, StateExecutionResult, StateTransitionError, StateMachine, build_builtin_state_registry, build_state_registry, check_state_invariants, execute_state
|
|
54
|
+
from .workspace import META_STATE_SNAPSHOT_VERSION, TaskWorkspace, WorkspaceError, WorkspacePaths, WORKSPACE_KINDS, WORKSPACE_PROTOCOL_VERSION, state_snapshot_hash, workspace_path
|
|
55
|
+
|
|
56
|
+
__all__ = [
|
|
57
|
+
"CompletionError",
|
|
58
|
+
"EventEnvelope",
|
|
59
|
+
"EventLog",
|
|
60
|
+
"IntegrityError",
|
|
61
|
+
"IdempotencyConflict",
|
|
62
|
+
"AuthorizationError",
|
|
63
|
+
"InvalidTransition",
|
|
64
|
+
"KernelError",
|
|
65
|
+
"VALID_STATES",
|
|
66
|
+
"reduce_events",
|
|
67
|
+
"Artifact",
|
|
68
|
+
"Authorization",
|
|
69
|
+
"Contract",
|
|
70
|
+
"Effect",
|
|
71
|
+
"Requirement",
|
|
72
|
+
"Subject",
|
|
73
|
+
"RUNTIME_PROTOCOL_VERSION",
|
|
74
|
+
"COMPONENT_RESULT_PROTOCOL",
|
|
75
|
+
"CONTRACT_EXECUTION_PROTOCOL",
|
|
76
|
+
"ComponentHandoff",
|
|
77
|
+
"ComponentResult",
|
|
78
|
+
"ContractBindingError",
|
|
79
|
+
"ContractComponent",
|
|
80
|
+
"ContractExecutionError",
|
|
81
|
+
"ContractExecutionReport",
|
|
82
|
+
"ContractPack",
|
|
83
|
+
"ContractPackExecutor",
|
|
84
|
+
"Evidence",
|
|
85
|
+
"CombinedVerifierRegistry",
|
|
86
|
+
"FilesystemVerifierRegistry",
|
|
87
|
+
"VerifierRegistry",
|
|
88
|
+
"GateDecision",
|
|
89
|
+
"PackRegistry",
|
|
90
|
+
"VerifierPack",
|
|
91
|
+
"VerifierRunner",
|
|
92
|
+
"VerifierSpec",
|
|
93
|
+
"VerifierDefinition",
|
|
94
|
+
"VerificationRequest",
|
|
95
|
+
"VerificationResult",
|
|
96
|
+
"VerifierContractAdapter",
|
|
97
|
+
"VerifierContractExecution",
|
|
98
|
+
"apply_gate",
|
|
99
|
+
"builtin_verifier_root",
|
|
100
|
+
"normalize_result",
|
|
101
|
+
"snapshot_evidence",
|
|
102
|
+
"summarize_metrics",
|
|
103
|
+
"normalize_requirements",
|
|
104
|
+
"CITATION_TRUTH_FIT_SPEC",
|
|
105
|
+
"FILE_SPEC",
|
|
106
|
+
"build_builtin_registry",
|
|
107
|
+
"collect_markdown",
|
|
108
|
+
"validate_verifier_id",
|
|
109
|
+
"validate_state_id",
|
|
110
|
+
"FilesystemStateRegistry",
|
|
111
|
+
"CombinedStateRegistry",
|
|
112
|
+
"META_STATE_PROTOCOL_VERSION",
|
|
113
|
+
"SKILL_STATE_DECLARATION_VERSION",
|
|
114
|
+
"SkillStateDeclaration",
|
|
115
|
+
"StateDefinition",
|
|
116
|
+
"StateContractAdapter",
|
|
117
|
+
"StateDefinitionError",
|
|
118
|
+
"StateExecutionError",
|
|
119
|
+
"StateExecutionResult",
|
|
120
|
+
"StateTransitionError",
|
|
121
|
+
"StateMachine",
|
|
122
|
+
"build_builtin_state_registry",
|
|
123
|
+
"build_state_registry",
|
|
124
|
+
"execute_state",
|
|
125
|
+
"check_state_invariants",
|
|
126
|
+
"TaskWorkspace",
|
|
127
|
+
"WorkspaceError",
|
|
128
|
+
"WorkspacePaths",
|
|
129
|
+
"WORKSPACE_KINDS",
|
|
130
|
+
"WORKSPACE_PROTOCOL_VERSION",
|
|
131
|
+
"META_STATE_SNAPSHOT_VERSION",
|
|
132
|
+
"workspace_path",
|
|
133
|
+
"state_snapshot_hash",
|
|
134
|
+
]
|
|
135
|
+
|
|
136
|
+
def _distribution_version() -> str:
|
|
137
|
+
"""Resolve the runtime version from the source metadata or installed wheel."""
|
|
138
|
+
from pathlib import Path
|
|
139
|
+
import importlib.metadata
|
|
140
|
+
import re
|
|
141
|
+
|
|
142
|
+
# During source-tree execution package metadata may describe an older
|
|
143
|
+
# globally installed wheel. Prefer the adjacent pyproject as the source
|
|
144
|
+
# of truth in that case.
|
|
145
|
+
pyproject = Path(__file__).resolve().parents[2] / "pyproject.toml"
|
|
146
|
+
try:
|
|
147
|
+
text = pyproject.read_text(encoding="utf-8")
|
|
148
|
+
match = re.search(r"(?m)^version\s*=\s*['\"]([^'\"]+)['\"]", text)
|
|
149
|
+
if match:
|
|
150
|
+
return match.group(1)
|
|
151
|
+
except OSError:
|
|
152
|
+
pass
|
|
153
|
+
try:
|
|
154
|
+
return importlib.metadata.version("bensz-skill-kernel")
|
|
155
|
+
except importlib.metadata.PackageNotFoundError:
|
|
156
|
+
return "0.0.0"
|
|
157
|
+
|
|
158
|
+
|
|
159
|
+
__version__ = _distribution_version()
|
|
@@ -0,0 +1,93 @@
|
|
|
1
|
+
"""Implementations for the small, domain-neutral atomic verifier packs.
|
|
2
|
+
|
|
3
|
+
This module lives beside the directory contracts so reviewers can inspect the
|
|
4
|
+
rules independently from the registry and runner plumbing. Each directory's
|
|
5
|
+
``scripts/verify.py`` is a thin JSON-stdio adapter around ``run_atomic``.
|
|
6
|
+
"""
|
|
7
|
+
|
|
8
|
+
from __future__ import annotations
|
|
9
|
+
|
|
10
|
+
import json
|
|
11
|
+
import re
|
|
12
|
+
from pathlib import Path
|
|
13
|
+
from typing import Any, Mapping
|
|
14
|
+
|
|
15
|
+
from bensz_skill_kernel.runtime import ALLOWED_TRANSITIONS, EventLog
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
def _parts(request: Any) -> tuple[Mapping[str, Any], Mapping[str, Any]]:
|
|
19
|
+
if hasattr(request, "subject"):
|
|
20
|
+
return request.subject, request.context
|
|
21
|
+
return request.get("subject") or {}, request.get("context") or {}
|
|
22
|
+
|
|
23
|
+
|
|
24
|
+
def _evidence_map(request: Any, evidence: Mapping[str, Any] | None) -> Mapping[str, Any]:
|
|
25
|
+
if evidence:
|
|
26
|
+
return evidence
|
|
27
|
+
if hasattr(request, "evidence"):
|
|
28
|
+
return {item.ref: item for item in request.evidence}
|
|
29
|
+
raw = request.get("evidence") or []
|
|
30
|
+
return {str(item.get("ref", index)): item for index, item in enumerate(raw) if isinstance(item, Mapping)}
|
|
31
|
+
|
|
32
|
+
|
|
33
|
+
def run_atomic(name: str, request: Any, evidence: Mapping[str, Any] | None = None) -> Mapping[str, Any]:
|
|
34
|
+
subject, context = _parts(request)
|
|
35
|
+
evidence = _evidence_map(request, evidence)
|
|
36
|
+
if name == "contract-conformance":
|
|
37
|
+
required = tuple(context.get("required_fields", ()))
|
|
38
|
+
missing = [field for field in required if field not in subject]
|
|
39
|
+
return _result(not missing, {"required_fields": list(required), "missing": missing}, "missing-field", missing)
|
|
40
|
+
if name == "path-scope":
|
|
41
|
+
raw_paths = subject.get("paths") or ([subject["path"]] if subject.get("path") else [])
|
|
42
|
+
allowed = [Path(item).expanduser().resolve() for item in context.get("allowed_paths", ())]
|
|
43
|
+
violations = []
|
|
44
|
+
for raw in raw_paths:
|
|
45
|
+
target = Path(raw).expanduser().resolve()
|
|
46
|
+
# Scope is lexical after ``resolve()`` and must not depend on an
|
|
47
|
+
# allowed directory already existing. Requiring ``is_dir()``
|
|
48
|
+
# made valid output paths fail before their parent was created.
|
|
49
|
+
if not any(target == root or root in target.parents for root in allowed):
|
|
50
|
+
violations.append(str(target))
|
|
51
|
+
return _result(not violations, {"paths": list(raw_paths), "violations": violations}, "path-out-of-scope", violations)
|
|
52
|
+
if name == "schema-conformance":
|
|
53
|
+
data = subject.get("data", subject)
|
|
54
|
+
schema = context.get("schema", {})
|
|
55
|
+
required = schema.get("required", ()) if isinstance(schema, Mapping) else ()
|
|
56
|
+
missing = [key for key in required if not isinstance(data, Mapping) or key not in data]
|
|
57
|
+
return _result(not missing, {"missing": missing}, "schema-required-field", missing)
|
|
58
|
+
if name == "diff-scope":
|
|
59
|
+
changed = set(subject.get("changed_paths", ()))
|
|
60
|
+
violations = sorted(changed - set(context.get("allowed_paths", ())))
|
|
61
|
+
return _result(not violations, {"changed": sorted(changed), "violations": violations}, "unexpected-change", violations)
|
|
62
|
+
if name == "secret-redaction":
|
|
63
|
+
raw = json.dumps(subject, ensure_ascii=False, default=str)
|
|
64
|
+
patterns = (r"[\"']?(?:api[_-]?key|token|password|cookie)[\"']?\s*[:=]\s*[\"']?[^,\s}\"']+", r"sk-[A-Za-z0-9_-]{8,}")
|
|
65
|
+
matches = [pattern for pattern in patterns if re.search(pattern, raw, re.IGNORECASE)]
|
|
66
|
+
return {"verdict": "fail" if matches else "pass", "facts": {"matched_patterns": len(matches)}, "findings": [{"id": "secret-detected", "verdict": "fail"}] if matches else []}
|
|
67
|
+
if name == "evidence-provenance":
|
|
68
|
+
def value(item: Any, key: str) -> Any:
|
|
69
|
+
return item.get(key) if isinstance(item, Mapping) else getattr(item, key, None)
|
|
70
|
+
invalid = [ref for ref, item in evidence.items() if not value(item, "source_type") or not value(item, "content_hash") or not value(item, "collected_at")]
|
|
71
|
+
return _result(not invalid, {"evidence_count": len(evidence)}, "missing-provenance", invalid)
|
|
72
|
+
if name == "event-integrity":
|
|
73
|
+
path = subject.get("path")
|
|
74
|
+
if not path:
|
|
75
|
+
return _result(False, {}, "missing-events-path", ["events"])
|
|
76
|
+
try:
|
|
77
|
+
count = len(EventLog(path).read())
|
|
78
|
+
except Exception as exc:
|
|
79
|
+
return {"verdict": "fail", "uncertainty_reason": str(exc), "findings": [{"id": "event-integrity", "verdict": "fail"}]}
|
|
80
|
+
return {"verdict": "pass", "facts": {"event_count": count}, "findings": []}
|
|
81
|
+
if name == "state-transition":
|
|
82
|
+
current, target = subject.get("current_state"), subject.get("target_state")
|
|
83
|
+
allowed = target in ALLOWED_TRANSITIONS.get(current, ())
|
|
84
|
+
return _result(allowed, {"current_state": current, "target_state": target}, "illegal-transition", [target] if not allowed else [])
|
|
85
|
+
if name == "task-completeness":
|
|
86
|
+
required = tuple(context.get("required_fields", ("artifacts", "verifications", "delivery_report")))
|
|
87
|
+
missing = [key for key in required if not subject.get(key)]
|
|
88
|
+
return _result(not missing, {"missing": missing}, "task-incomplete", missing)
|
|
89
|
+
raise ValueError(f"unknown atomic verifier: {name}")
|
|
90
|
+
|
|
91
|
+
|
|
92
|
+
def _result(ok: bool, facts: Mapping[str, Any], finding_id: str, values: list[Any]) -> Mapping[str, Any]:
|
|
93
|
+
return {"verdict": "pass" if ok else "fail", "facts": dict(facts), "findings": [{"id": finding_id, "value": value, "verdict": "fail"} for value in values]}
|
|
@@ -0,0 +1,114 @@
|
|
|
1
|
+
"""Small, dependency-free verifier packs shipped with the kernel.
|
|
2
|
+
|
|
3
|
+
Skills select these by stable id and tags. Domain-specific packs can still be
|
|
4
|
+
registered by a Skill, but common packs live here so Skills do not duplicate
|
|
5
|
+
command, result, or Gate plumbing.
|
|
6
|
+
"""
|
|
7
|
+
|
|
8
|
+
from __future__ import annotations
|
|
9
|
+
|
|
10
|
+
from functools import lru_cache
|
|
11
|
+
from importlib.util import module_from_spec, spec_from_file_location
|
|
12
|
+
from pathlib import Path
|
|
13
|
+
from typing import Any, Mapping
|
|
14
|
+
|
|
15
|
+
from .verifiers import Evidence, PackRegistry, VerifierPack, VerifierSpec
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
@lru_cache(maxsize=1)
|
|
19
|
+
def _markdown_collector_module():
|
|
20
|
+
"""Load the legacy Markdown API without keeping its implementation here."""
|
|
21
|
+
collector_path = (
|
|
22
|
+
Path(__file__).resolve().parent
|
|
23
|
+
/ 'verifiers'
|
|
24
|
+
/ 'markdown-link-integrity'
|
|
25
|
+
/ 'scripts'
|
|
26
|
+
/ 'collector.py'
|
|
27
|
+
)
|
|
28
|
+
spec = spec_from_file_location('bensz_skill_kernel._markdown_link_integrity_collector', collector_path)
|
|
29
|
+
if spec is None or spec.loader is None:
|
|
30
|
+
raise ImportError(f'cannot load Markdown collector: {collector_path}')
|
|
31
|
+
module = module_from_spec(spec)
|
|
32
|
+
spec.loader.exec_module(module)
|
|
33
|
+
return module
|
|
34
|
+
|
|
35
|
+
|
|
36
|
+
def collect_markdown(*args: Any, **kwargs: Any) -> dict[str, Any]:
|
|
37
|
+
"""Backward-compatible proxy to the Markdown Verifier collector.
|
|
38
|
+
|
|
39
|
+
New code should invoke ``markdown-link-integrity`` through the filesystem
|
|
40
|
+
Verifier entrypoint instead of importing this compatibility API.
|
|
41
|
+
"""
|
|
42
|
+
return _markdown_collector_module().collect_markdown(*args, **kwargs)
|
|
43
|
+
|
|
44
|
+
|
|
45
|
+
@lru_cache(maxsize=1)
|
|
46
|
+
def _atomic_module():
|
|
47
|
+
atomic_path = Path(__file__).resolve().parent / 'atomic_verifiers.py'
|
|
48
|
+
spec = spec_from_file_location('bensz_skill_kernel._atomic_verifiers', atomic_path)
|
|
49
|
+
if spec is None or spec.loader is None:
|
|
50
|
+
raise ImportError(f'cannot load atomic verifier rules: {atomic_path}')
|
|
51
|
+
module = module_from_spec(spec)
|
|
52
|
+
spec.loader.exec_module(module)
|
|
53
|
+
return module
|
|
54
|
+
|
|
55
|
+
|
|
56
|
+
CITATION_TRUTH_FIT_SPEC = VerifierSpec(
|
|
57
|
+
verifier_id='bensz.evidence.citation-truth-fit',
|
|
58
|
+
version='1.0.0',
|
|
59
|
+
mode='hybrid',
|
|
60
|
+
capabilities=('evidence.identity', 'semantic.entailment', 'semantic.appropriateness'),
|
|
61
|
+
evidence_requirements=('subject_context', 'source_metadata', 'source_excerpt'),
|
|
62
|
+
uncertainty_policy={'missing_evidence': 'manual_review', 'engine_unavailable': 'unchecked'},
|
|
63
|
+
tags=('common', 'citation', 'semantic', 'evidence'),
|
|
64
|
+
aliases=('citation.truth-and-fit',),
|
|
65
|
+
metadata={'side_effects': 'none', 'requires_external_engine': True},
|
|
66
|
+
)
|
|
67
|
+
|
|
68
|
+
|
|
69
|
+
def _citation_engine_gap(request: Any, evidence: Mapping[str, Evidence]) -> Mapping[str, Any]:
|
|
70
|
+
return {
|
|
71
|
+
'execution_status': 'unchecked',
|
|
72
|
+
'verdict': 'unchecked',
|
|
73
|
+
'uncertainty_reason': 'semantic citation engine is not bundled with the kernel',
|
|
74
|
+
'evidence_refs': ['subject_context', 'source_metadata', 'source_excerpt'],
|
|
75
|
+
'model_or_engine': 'none',
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
|
|
79
|
+
def _file_exists(request: Any, evidence: Mapping[str, Evidence]) -> Mapping[str, Any]:
|
|
80
|
+
path = request.subject.get('path')
|
|
81
|
+
exists = bool(path and Path(path).is_file())
|
|
82
|
+
return {'verdict': 'pass' if exists else 'fail', 'facts': {'path': path, 'exists': exists}, 'findings': [] if exists else [{'id': 'missing-file', 'severity': 'required', 'verdict': 'fail', 'message': f'file does not exist: {path}'}]}
|
|
83
|
+
|
|
84
|
+
|
|
85
|
+
FILE_SPEC = VerifierSpec(
|
|
86
|
+
verifier_id='bensz.artifact.file-existence',
|
|
87
|
+
version='1.0.0',
|
|
88
|
+
mode='rule',
|
|
89
|
+
capabilities=('filesystem.read',),
|
|
90
|
+
tags=('common', 'filesystem', 'deterministic'),
|
|
91
|
+
aliases=('artifact.file-exists',),
|
|
92
|
+
metadata={'side_effects': 'none'},
|
|
93
|
+
)
|
|
94
|
+
|
|
95
|
+
|
|
96
|
+
def build_builtin_registry() -> PackRegistry:
|
|
97
|
+
registry = PackRegistry()
|
|
98
|
+
registry.register(VerifierPack(FILE_SPEC, rules=(('file-exists', _file_exists),)))
|
|
99
|
+
registry.register(VerifierPack(CITATION_TRUTH_FIT_SPEC, prompts=(('citation-semantics', _citation_engine_gap),)))
|
|
100
|
+
atomic = (
|
|
101
|
+
("bensz.contract.conformance", "contract-conformance", "contract"),
|
|
102
|
+
("bensz.artifact.path-scope", "path-scope", "artifact"),
|
|
103
|
+
("bensz.artifact.schema-conformance", "schema-conformance", "artifact"),
|
|
104
|
+
("bensz.source.diff-scope", "diff-scope", "source"),
|
|
105
|
+
("bensz.security.secret-redaction", "secret-redaction", "security"),
|
|
106
|
+
("bensz.evidence.provenance", "evidence-provenance", "evidence"),
|
|
107
|
+
("bensz.runtime.event-integrity", "event-integrity", "runtime"),
|
|
108
|
+
("bensz.runtime.state-transition", "state-transition", "runtime"),
|
|
109
|
+
("bensz.runtime.task-completeness", "task-completeness", "runtime"),
|
|
110
|
+
)
|
|
111
|
+
for verifier_id, rule_name, tag in atomic:
|
|
112
|
+
rule = lambda request, evidence, name=rule_name: _atomic_module().run_atomic(name, request, evidence)
|
|
113
|
+
registry.register(VerifierPack(VerifierSpec(verifier_id, "1.0.0", "rule", tags=("common", tag, "deterministic")), rules=((rule_name, rule),)))
|
|
114
|
+
return registry
|