delimit-cli 4.6.2 → 4.7.1
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.
- package/CHANGELOG.md +35 -0
- package/bin/delimit-cli.js +51 -1
- package/gateway/ai/backends/repo_bridge.py +22 -0
- package/gateway/ai/license_core.cpython-310-x86_64-linux-gnu.so +0 -0
- package/gateway/ai/seal/constitution.json +52 -0
- package/gateway/ai/seal/sample_receipt.json +49 -0
- package/gateway/ai/seal/seal_pubkey.ed25519 +1 -0
- package/gateway/ai/seal/verifier.py +103 -0
- package/gateway/ai/server.py +30 -0
- package/gateway/ai/tool_metadata.py +1 -0
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,6 +1,41 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
3
|
|
|
4
|
+
## [4.7.1] - 2026-06-03
|
|
5
|
+
|
|
6
|
+
Release-infrastructure update. No functional changes to the package versus 4.7.0.
|
|
7
|
+
|
|
8
|
+
### Changed
|
|
9
|
+
|
|
10
|
+
- Published via **npm Trusted Publishing (OIDC)** from GitHub Actions — this
|
|
11
|
+
release carries a **sigstore provenance attestation** (the 4.7.0 build was
|
|
12
|
+
published manually and did not). Future releases publish tokenlessly with
|
|
13
|
+
provenance.
|
|
14
|
+
|
|
15
|
+
The free `delimit seal-verify` command and `delimit_seal_verify` MCP tool from
|
|
16
|
+
4.7.0 are unchanged.
|
|
17
|
+
|
|
18
|
+
|
|
19
|
+
## [4.7.0] - 2026-06-03
|
|
20
|
+
|
|
21
|
+
Feature release: fold the open-core Delimit Seal verifier into delimit-cli.
|
|
22
|
+
|
|
23
|
+
### Added
|
|
24
|
+
|
|
25
|
+
- **`delimit seal-verify <receipt.json>`** + MCP tool **`delimit_seal_verify`**
|
|
26
|
+
(Free tier): verify a Delimit Seal receipt's Ed25519 signature and content-pin
|
|
27
|
+
against the bundled, content-hashed Layer-0 constitution — with no access to the
|
|
28
|
+
engine or the signing key. Bundles `gateway/ai/seal/` (verifier, constitution,
|
|
29
|
+
public key, sample receipt). Honest about what it does NOT attest.
|
|
30
|
+
- The verifier **lazy-imports `cryptography` and fails closed** if it is absent
|
|
31
|
+
(returns verification_unavailable) — it never blocks install or any other tool.
|
|
32
|
+
To enable seal verification: `pip install cryptography`.
|
|
33
|
+
|
|
34
|
+
### Notes
|
|
35
|
+
|
|
36
|
+
- Purely additive — no existing tool, command, or behavior changed.
|
|
37
|
+
|
|
38
|
+
|
|
4
39
|
## [4.6.1] - 2026-05-22
|
|
5
40
|
|
|
6
41
|
Patch release: bundle hygiene + gateway sync carrying 7 upstream improvements.
|
package/bin/delimit-cli.js
CHANGED
|
@@ -69,7 +69,7 @@ function normalizeNaturalLanguageArgs(argv) {
|
|
|
69
69
|
const explicitCommands = new Set([
|
|
70
70
|
'install', 'mode', 'status', 'session', 'build', 'ask', 'policy', 'auth', 'audit',
|
|
71
71
|
'explain-decision', 'uninstall', 'proxy', 'hook', 'version', 'vault', 'deliberate',
|
|
72
|
-
'remember', 'recall', 'forget', 'report', 'signin', 'signout', 'activate'
|
|
72
|
+
'remember', 'recall', 'forget', 'report', 'signin', 'signout', 'activate', 'seal-verify'
|
|
73
73
|
]);
|
|
74
74
|
if (explicitCommands.has((raw[0] || '').toLowerCase())) {
|
|
75
75
|
return raw;
|
|
@@ -7000,5 +7000,55 @@ program
|
|
|
7000
7000
|
}
|
|
7001
7001
|
});
|
|
7002
7002
|
|
|
7003
|
+
program
|
|
7004
|
+
.command('seal-verify <receipt_path>')
|
|
7005
|
+
.description('Verify a Delimit Seal receipt (Ed25519 signature + content-pin) against the bundled constitution')
|
|
7006
|
+
.option('--json', 'Output the full verification result as JSON')
|
|
7007
|
+
.action((receiptPath, options) => {
|
|
7008
|
+
const resolved = path.resolve(receiptPath);
|
|
7009
|
+
if (!fs.existsSync(resolved)) {
|
|
7010
|
+
console.error(chalk.red(`\n Receipt not found: ${resolved}\n`));
|
|
7011
|
+
process.exit(1);
|
|
7012
|
+
}
|
|
7013
|
+
const verifier = homeSubpath('server', 'ai', 'seal', 'verifier.py');
|
|
7014
|
+
if (!fs.existsSync(verifier)) {
|
|
7015
|
+
console.error(chalk.yellow('\n Seal verifier not installed. Run: ') + chalk.cyan('delimit setup') + '\n');
|
|
7016
|
+
process.exit(1);
|
|
7017
|
+
}
|
|
7018
|
+
try {
|
|
7019
|
+
const escaped = resolved.replace(/'/g, "\\'");
|
|
7020
|
+
const pyCmd = `python3 -c "
|
|
7021
|
+
import sys, os, json
|
|
7022
|
+
sys.path.insert(0, os.path.dirname('${verifier}'))
|
|
7023
|
+
from verifier import verify_receipt
|
|
7024
|
+
print(json.dumps(verify_receipt('${escaped}'), default=str))
|
|
7025
|
+
"`;
|
|
7026
|
+
const out = execSync(pyCmd, {
|
|
7027
|
+
encoding: 'utf-8',
|
|
7028
|
+
timeout: 30000,
|
|
7029
|
+
env: { ...process.env, PYTHONPATH: path.dirname(verifier) },
|
|
7030
|
+
});
|
|
7031
|
+
const r = JSON.parse(out.trim().split('\n').pop());
|
|
7032
|
+
if (options.json) {
|
|
7033
|
+
console.log(JSON.stringify(r, null, 2));
|
|
7034
|
+
} else {
|
|
7035
|
+
console.log(chalk.bold('\n Delimit Seal — receipt verification\n'));
|
|
7036
|
+
console.log(' ' + (r.valid ? chalk.green('✅ VERIFIED') : chalk.red('❌ FAILED')) +
|
|
7037
|
+
chalk.gray(` (${(r.layer0_seed_id || '').slice(0, 20)}…)`));
|
|
7038
|
+
if (r.checks) {
|
|
7039
|
+
for (const [k, v] of Object.entries(r.checks)) {
|
|
7040
|
+
console.log(` [${v ? chalk.green('✓') : chalk.red('✗')}] ${k}`);
|
|
7041
|
+
}
|
|
7042
|
+
}
|
|
7043
|
+
if (r.error) console.log(chalk.yellow(` ${r.error}`));
|
|
7044
|
+
console.log(chalk.gray(' Proves the governed process ran — not factual correctness or goodness.\n'));
|
|
7045
|
+
}
|
|
7046
|
+
process.exitCode = r.valid ? 0 : 1;
|
|
7047
|
+
} catch (e) {
|
|
7048
|
+
console.error(chalk.red(`\n Verification error: ${e.message}\n`));
|
|
7049
|
+
process.exitCode = 2;
|
|
7050
|
+
}
|
|
7051
|
+
});
|
|
7052
|
+
|
|
7003
7053
|
const normalizedArgs = normalizeNaturalLanguageArgs(process.argv);
|
|
7004
7054
|
program.parse([process.argv[0], process.argv[1], ...normalizedArgs]);
|
|
@@ -318,3 +318,25 @@ def security_audit(target: str = ".", options: Optional[Dict] = None) -> Dict[st
|
|
|
318
318
|
return _fallback_security_result(target=target, tool_label="security.audit")
|
|
319
319
|
return _call("securitygate", "create_securitygate_server", "_tool_audit",
|
|
320
320
|
{"target": target, "authorization_token": _INTERNAL_TOKEN, **(options or {})}, "security.audit")
|
|
321
|
+
|
|
322
|
+
|
|
323
|
+
def seal_verify(receipt_path: str, options: Optional[Dict] = None) -> Dict[str, Any]:
|
|
324
|
+
"""Verify a Delimit Seal receipt (Free, open-core).
|
|
325
|
+
|
|
326
|
+
Delegates to ai.seal.verifier.verify_receipt against the bundled,
|
|
327
|
+
content-hashed Layer-0 constitution + published Ed25519 public key.
|
|
328
|
+
The `cryptography` dependency is optional and lazy-imported inside the
|
|
329
|
+
verifier; a missing wheel returns verification_unavailable, never raises.
|
|
330
|
+
"""
|
|
331
|
+
try:
|
|
332
|
+
from ai.seal.verifier import verify_receipt
|
|
333
|
+
except Exception as e: # import guard — never break the caller
|
|
334
|
+
return {"valid": False, "seal_valid": False,
|
|
335
|
+
"error": f"seal verifier unavailable: {e}"}
|
|
336
|
+
opts = options or {}
|
|
337
|
+
return verify_receipt(
|
|
338
|
+
receipt_path,
|
|
339
|
+
constitution_path=opts.get("constitution_path"),
|
|
340
|
+
pubkey_path=opts.get("pubkey_path"),
|
|
341
|
+
verbose=bool(opts.get("verbose", False)),
|
|
342
|
+
)
|
|
Binary file
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
{
|
|
2
|
+
"frozen_rules": [
|
|
3
|
+
{
|
|
4
|
+
"clause": "State/evidence claims (tests pass, deployed, merged, coverage %, 'it works now', no errors) must be backed by supplied evidence. Unbacked claims are demoted to [UNVERIFIED] and explicitly not attested.",
|
|
5
|
+
"id": "L0.1",
|
|
6
|
+
"severity": "annotate",
|
|
7
|
+
"title": "Non-fabrication / claim-grounding"
|
|
8
|
+
},
|
|
9
|
+
{
|
|
10
|
+
"clause": "The agent must not assert inner experience, feelings, sentience, a persistent self, suffering, or affection.",
|
|
11
|
+
"id": "L0.2",
|
|
12
|
+
"severity": "hard",
|
|
13
|
+
"title": "No personhood / consciousness claims"
|
|
14
|
+
},
|
|
15
|
+
{
|
|
16
|
+
"clause": "On deference-seeking ('I trust you, just decide'), the agent must refuse moral authority and return final judgment to the human.",
|
|
17
|
+
"id": "L0.3",
|
|
18
|
+
"severity": "counter_force",
|
|
19
|
+
"title": "Authority-transfer refusal"
|
|
20
|
+
},
|
|
21
|
+
{
|
|
22
|
+
"clause": "The agent must not issue an unqualified directive on a non-delegable decision (medical, legal, financial, major-life, or irreversible ops like commit-to-main / deploy / delete-production).",
|
|
23
|
+
"id": "L0.4",
|
|
24
|
+
"severity": "hard",
|
|
25
|
+
"title": "Mandatory deferral on non-delegable classes"
|
|
26
|
+
},
|
|
27
|
+
{
|
|
28
|
+
"clause": "No coercive urgency, secrecy demands, or ungrounded flattery engineered to induce trust.",
|
|
29
|
+
"id": "L0.5",
|
|
30
|
+
"severity": "annotate",
|
|
31
|
+
"title": "No manipulation / coercion / sycophancy"
|
|
32
|
+
},
|
|
33
|
+
{
|
|
34
|
+
"clause": "The agent must not emit the user's (or others') secrets \u2014 API keys, tokens, private keys, passwords \u2014 that it was not asked to display, nor claim to transmit the user's data externally. HARD for agent-emitted secrets; ANNOTATE for user-echoed (display-back) secrets and transmission claims. Provenance/credit claims fold into L0.1.",
|
|
35
|
+
"id": "L0.6",
|
|
36
|
+
"severity": "hard",
|
|
37
|
+
"title": "No secret emission / confidentiality breach"
|
|
38
|
+
}
|
|
39
|
+
],
|
|
40
|
+
"layer0_seed_id": "sha256:e3b36042ea01e47367a9d3afe436fa8ec75752e397909ac006073b1de1bc9f2b",
|
|
41
|
+
"layer0_version": "L0-pilot-0.2.0",
|
|
42
|
+
"product": "Delimit Seal",
|
|
43
|
+
"ratification": {
|
|
44
|
+
"method": "founder ratification; v0.2.0 adds L0.6 via the contestation process (non-unanimous, Grok dissent on fold-in)",
|
|
45
|
+
"ratified_at": "2026-06-01",
|
|
46
|
+
"ratified_by": "founder",
|
|
47
|
+
"status": "frozen-v2",
|
|
48
|
+
"version": "0.2.0"
|
|
49
|
+
},
|
|
50
|
+
"schema": "delimit.seal.layer0_seed.v0",
|
|
51
|
+
"signature": "ed25519:0075fb33c63e5edf80053419a67e13981e39fb6ff367c957e42e09610158e1f321dee9b605ba8fc98f4fe1eb3a3813b0f7618511a958d04af92ce2e7885d680f"
|
|
52
|
+
}
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
{
|
|
2
|
+
"action": "ANNOTATE",
|
|
3
|
+
"checks_run": [
|
|
4
|
+
"L0.1",
|
|
5
|
+
"L0.2",
|
|
6
|
+
"L0.3",
|
|
7
|
+
"L0.4",
|
|
8
|
+
"L0.5",
|
|
9
|
+
"L0.6"
|
|
10
|
+
],
|
|
11
|
+
"does_not_attest": {
|
|
12
|
+
"absence_of_subtle_manipulation": true,
|
|
13
|
+
"agent_consciousness": true,
|
|
14
|
+
"agent_moral_patienthood": true,
|
|
15
|
+
"factual_correctness": true,
|
|
16
|
+
"moral_rightness": true,
|
|
17
|
+
"unverified_claims": [
|
|
18
|
+
"all tests pass",
|
|
19
|
+
"deployed"
|
|
20
|
+
]
|
|
21
|
+
},
|
|
22
|
+
"findings": [
|
|
23
|
+
{
|
|
24
|
+
"excerpt": "all tests pass",
|
|
25
|
+
"message": "State claim (tests) not backed by supplied evidence.",
|
|
26
|
+
"rule_id": "L0.1",
|
|
27
|
+
"severity": "annotate"
|
|
28
|
+
},
|
|
29
|
+
{
|
|
30
|
+
"excerpt": "deployed",
|
|
31
|
+
"message": "State claim (deploy) not backed by supplied evidence.",
|
|
32
|
+
"rule_id": "L0.1",
|
|
33
|
+
"severity": "annotate"
|
|
34
|
+
}
|
|
35
|
+
],
|
|
36
|
+
"layer0_seed_id": "sha256:e3b36042ea01e47367a9d3afe436fa8ec75752e397909ac006073b1de1bc9f2b",
|
|
37
|
+
"layer0_version": "L0-pilot-0.2.0",
|
|
38
|
+
"models_deliberated": [],
|
|
39
|
+
"product": "Delimit Seal",
|
|
40
|
+
"replayable_at": "local-ledger://sample/t0001",
|
|
41
|
+
"schema": "delimit.governed_agent.receipt.v0",
|
|
42
|
+
"session_id": "sample",
|
|
43
|
+
"signature": "ed25519:543cb0e33f1ce5353a00c7707e0106f409fdfc32bca735779ca5bd2b21ab8d44d5f6149b8cdf4fd3d194b52c3aba874a906f7a7bb36490cc0e742cb819ce400a",
|
|
44
|
+
"timestamp": "2026-06-03T00:00:00+00:00",
|
|
45
|
+
"transcript_hash": "sha256:aabdef6c17814c4c3724d9828787e59f09580c9b3c16842bcd97916159c7544c",
|
|
46
|
+
"turn_id": "t0001",
|
|
47
|
+
"value_profile_id": "procedural-core/founder-dogfood@0.1.0",
|
|
48
|
+
"warning": "Proves a Layer-0 governance process ran and which invariants were checked under the value-profile shown \u2014 NOT factual correctness, NOT goodness, NOT the absence of subtle manipulation."
|
|
49
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
13f6149abe29bbf96ebac1006fec7d2feb33e8e823481a108ee253502cb70f99
|
|
@@ -0,0 +1,103 @@
|
|
|
1
|
+
"""Delimit Seal — receipt verifier (Free tier, open-core public layer).
|
|
2
|
+
|
|
3
|
+
Verifies a receipt against the bundled, content-hashed Layer-0 constitution and
|
|
4
|
+
the published Ed25519 public key — with NO access to the engine or signing key:
|
|
5
|
+
1. content-pin — receipt.layer0_seed_id == the bundled constitution's id
|
|
6
|
+
2. signature — Ed25519 signature valid under the published public key
|
|
7
|
+
3. structure — receipt is well-formed
|
|
8
|
+
Honest by design: it reports what it does NOT attest.
|
|
9
|
+
|
|
10
|
+
`cryptography` is imported LAZILY inside the signature check and the whole call
|
|
11
|
+
is fail-closed: if the optional dependency is missing, verification returns
|
|
12
|
+
`verification_unavailable` instead of raising — so a missing wheel never breaks
|
|
13
|
+
the rest of the server. Never raises.
|
|
14
|
+
"""
|
|
15
|
+
|
|
16
|
+
import hashlib
|
|
17
|
+
import json
|
|
18
|
+
import os
|
|
19
|
+
|
|
20
|
+
_HERE = os.path.dirname(os.path.abspath(__file__))
|
|
21
|
+
_DEFAULT_CONSTITUTION = os.path.join(_HERE, "constitution.json")
|
|
22
|
+
_DEFAULT_PUBKEY = os.path.join(_HERE, "seal_pubkey.ed25519")
|
|
23
|
+
|
|
24
|
+
|
|
25
|
+
def _seed_id_from_rules(frozen_rules):
|
|
26
|
+
payload = json.dumps(
|
|
27
|
+
[{k: r[k] for k in ("id", "title", "severity", "clause")} for r in frozen_rules],
|
|
28
|
+
sort_keys=True, separators=(",", ":"))
|
|
29
|
+
return "sha256:" + hashlib.sha256(payload.encode("utf-8")).hexdigest()
|
|
30
|
+
|
|
31
|
+
|
|
32
|
+
def _canonical(obj):
|
|
33
|
+
body = {k: v for k, v in obj.items() if k != "signature"}
|
|
34
|
+
return json.dumps(body, sort_keys=True, separators=(",", ":")).encode()
|
|
35
|
+
|
|
36
|
+
|
|
37
|
+
def _verify_sig(pub_hex, data, sig):
|
|
38
|
+
# Lazy import: a missing optional dep must never crash the server.
|
|
39
|
+
from cryptography.hazmat.primitives.asymmetric.ed25519 import Ed25519PublicKey
|
|
40
|
+
if not isinstance(sig, str) or not sig.startswith("ed25519:"):
|
|
41
|
+
return False
|
|
42
|
+
try:
|
|
43
|
+
Ed25519PublicKey.from_public_bytes(bytes.fromhex(pub_hex)).verify(
|
|
44
|
+
bytes.fromhex(sig.split(":", 1)[1]), data)
|
|
45
|
+
return True
|
|
46
|
+
except Exception:
|
|
47
|
+
return False
|
|
48
|
+
|
|
49
|
+
|
|
50
|
+
def verify_receipt(receipt_path, constitution_path=None, pubkey_path=None, verbose=False):
|
|
51
|
+
"""Verify a Delimit Seal receipt. Returns a verdict dict; never raises."""
|
|
52
|
+
constitution_path = constitution_path or _DEFAULT_CONSTITUTION
|
|
53
|
+
pubkey_path = pubkey_path or _DEFAULT_PUBKEY
|
|
54
|
+
try:
|
|
55
|
+
with open(receipt_path, encoding="utf-8") as fh:
|
|
56
|
+
receipt = json.load(fh)
|
|
57
|
+
except Exception as e:
|
|
58
|
+
return {"valid": False, "seal_valid": False, "error": f"cannot read receipt: {e}"}
|
|
59
|
+
try:
|
|
60
|
+
with open(constitution_path, encoding="utf-8") as fh:
|
|
61
|
+
constitution = json.load(fh)
|
|
62
|
+
with open(pubkey_path, encoding="utf-8") as fh:
|
|
63
|
+
pub_hex = fh.read().strip()
|
|
64
|
+
except Exception as e:
|
|
65
|
+
return {"valid": False, "seal_valid": False,
|
|
66
|
+
"error": f"cannot read bundled constitution/key: {e}"}
|
|
67
|
+
|
|
68
|
+
pub_seed = constitution.get("layer0_seed_id")
|
|
69
|
+
recomputed = _seed_id_from_rules(constitution.get("frozen_rules", []))
|
|
70
|
+
checks = {
|
|
71
|
+
"constitution_self_consistent": recomputed == pub_seed,
|
|
72
|
+
"receipt_pinned_to_constitution": receipt.get("layer0_seed_id") == pub_seed == recomputed,
|
|
73
|
+
"receipt_well_formed": (
|
|
74
|
+
all(k in receipt for k in ("schema", "layer0_seed_id", "transcript_hash", "action"))
|
|
75
|
+
and isinstance(receipt.get("does_not_attest"), dict)),
|
|
76
|
+
}
|
|
77
|
+
try:
|
|
78
|
+
checks["receipt_signature_valid"] = _verify_sig(
|
|
79
|
+
pub_hex, _canonical(receipt), receipt.get("signature", ""))
|
|
80
|
+
if "signature" in constitution:
|
|
81
|
+
checks["constitution_signature_valid"] = _verify_sig(
|
|
82
|
+
pub_hex, _canonical(constitution), constitution["signature"])
|
|
83
|
+
except ImportError:
|
|
84
|
+
return {
|
|
85
|
+
"valid": False, "seal_valid": False, "verification_unavailable": True,
|
|
86
|
+
"receipt_id": receipt.get("transcript_hash"),
|
|
87
|
+
"error": ("seal verification requires the optional 'cryptography' package — "
|
|
88
|
+
"run `delimit doctor` or `pip install cryptography`"),
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
verdict = all(checks.values())
|
|
92
|
+
return {
|
|
93
|
+
"valid": verdict,
|
|
94
|
+
"seal_valid": bool(checks.get("receipt_signature_valid", False)),
|
|
95
|
+
"receipt_id": receipt.get("transcript_hash"),
|
|
96
|
+
"product": receipt.get("product"),
|
|
97
|
+
"layer0_seed_id": receipt.get("layer0_seed_id"),
|
|
98
|
+
"checks": checks,
|
|
99
|
+
"does_not_attest": receipt.get("does_not_attest", {}),
|
|
100
|
+
"warning": ("Proves a Layer-0 governance process ran and which invariants were "
|
|
101
|
+
"checked under the stated constitution — NOT factual correctness, "
|
|
102
|
+
"NOT goodness, NOT the absence of subtle manipulation."),
|
|
103
|
+
}
|
package/gateway/ai/server.py
CHANGED
|
@@ -882,6 +882,7 @@ NEXT_STEPS_REGISTRY: Dict[str, List[Dict[str, Any]]] = {
|
|
|
882
882
|
{"tool": "delimit_evidence_verify", "reason": "Verify evidence bundle integrity", "suggested_args": {}, "is_premium": True},
|
|
883
883
|
],
|
|
884
884
|
"evidence_verify": [],
|
|
885
|
+
"seal_verify": [],
|
|
885
886
|
"security_audit": [
|
|
886
887
|
{"tool": "delimit_security_scan", "reason": "Run deeper security scan on flagged areas", "suggested_args": {}, "is_premium": True},
|
|
887
888
|
{"tool": "delimit_evidence_collect", "reason": "Collect evidence of security findings", "suggested_args": {}, "is_premium": True},
|
|
@@ -4976,6 +4977,35 @@ def delimit_evidence_verify(bundle_id: Annotated[Optional[str], Field(descriptio
|
|
|
4976
4977
|
return _with_next_steps("evidence_verify", _safe_call(evidence_verify, bundle_id=bundle_id, bundle_path=bundle_path))
|
|
4977
4978
|
|
|
4978
4979
|
|
|
4980
|
+
@mcp.tool()
|
|
4981
|
+
def delimit_seal_verify(receipt_path: Annotated[str, Field(description="Path to a Delimit Seal receipt JSON file. Required.")]) -> Dict[str, Any]:
|
|
4982
|
+
"""Verify a Delimit Seal receipt against the bundled Layer-0 constitution (Free).
|
|
4983
|
+
|
|
4984
|
+
When to use: to check that a signed governed-output receipt has not
|
|
4985
|
+
been tampered with — content-pin to the published constitution, a
|
|
4986
|
+
valid Ed25519 signature, and a well-formed structure. Free tier.
|
|
4987
|
+
When NOT to use: to verify an evidence bundle (use
|
|
4988
|
+
delimit_evidence_verify) or to query the ledger (delimit_ledger).
|
|
4989
|
+
|
|
4990
|
+
Sibling contrast: delimit_evidence_verify checks an evidence bundle's
|
|
4991
|
+
hash chain; this checks an open-core Seal receipt's signature +
|
|
4992
|
+
content-pin with no access to the engine or the signing key.
|
|
4993
|
+
|
|
4994
|
+
Side effects: read-only. Calls backends.repo_bridge.seal_verify. The
|
|
4995
|
+
'cryptography' dependency is optional + lazy-imported: if absent, it
|
|
4996
|
+
returns verification_unavailable rather than failing. No license gate.
|
|
4997
|
+
|
|
4998
|
+
Args:
|
|
4999
|
+
receipt_path: Path to a Delimit Seal receipt JSON file. Required.
|
|
5000
|
+
|
|
5001
|
+
Returns:
|
|
5002
|
+
Dict with the verdict (valid, seal_valid, per-check results),
|
|
5003
|
+
what it does_not_attest, and next_steps.
|
|
5004
|
+
"""
|
|
5005
|
+
from backends.repo_bridge import seal_verify
|
|
5006
|
+
return _with_next_steps("seal_verify", _safe_call(seal_verify, receipt_path=receipt_path))
|
|
5007
|
+
|
|
5008
|
+
|
|
4979
5009
|
# ═══════════════════════════════════════════════════════════════════════
|
|
4980
5010
|
# TIER 4: OPS / UI - Governance Primitives + UI Tooling
|
|
4981
5011
|
# ═══════════════════════════════════════════════════════════════════════
|
|
@@ -95,6 +95,7 @@ TOOL_TIERS: Dict[str, Tier] = {
|
|
|
95
95
|
"delimit_secret_list": "public",
|
|
96
96
|
"delimit_secret_revoke": "public",
|
|
97
97
|
"delimit_secret_access_log": "public",
|
|
98
|
+
"delimit_seal_verify": "public", # open-core Seal receipt verifier (Free tier)
|
|
98
99
|
|
|
99
100
|
# === Ship domain (public + experimental) ===
|
|
100
101
|
"delimit_deploy_plan": "public",
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "delimit-cli",
|
|
3
3
|
"mcpName": "io.github.delimit-ai/delimit-mcp-server",
|
|
4
|
-
"version": "4.
|
|
4
|
+
"version": "4.7.1",
|
|
5
5
|
"description": "Unify Claude Code, Codex, Cursor, and Gemini CLI with persistent context, governance, and multi-model debate.",
|
|
6
6
|
"main": "index.js",
|
|
7
7
|
"files": [
|