delimit-cli 4.5.0 → 4.5.2
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 +108 -0
- package/README.md +2 -2
- package/adapters/cursor-rules.js +17 -4
- package/bin/delimit-cli.js +109 -24
- package/gateway/ai/content_engine.py +3 -4
- package/gateway/ai/inbox_classifier.py +215 -0
- package/gateway/ai/integrations/opensage_wrapper.py +4 -1
- package/gateway/ai/ledger_manager.py +218 -38
- package/gateway/ai/license.py +26 -0
- package/gateway/ai/notify.py +68 -3
- package/gateway/ai/reddit_proxy.py +93 -15
- package/gateway/ai/reddit_scanner.py +36 -18
- package/gateway/ai/server.py +128 -6
- package/gateway/ai/social_capability/__init__.py +6 -0
- package/gateway/ai/social_capability/capability_validator.py +273 -0
- package/gateway/ai/social_capability/current_capabilities.yaml +95 -0
- package/gateway/ai/social_queue.py +307 -0
- package/gateway/ai/supabase_sync.py +14 -2
- package/gateway/ai/swarm.py +29 -11
- package/gateway/ai/tui.py +6 -2
- package/gateway/ai/x_ranker.py +276 -0
- package/lib/attest-mcp.js +487 -0
- package/lib/attest-telemetry.js +48 -0
- package/lib/delimit-home.js +35 -0
- package/lib/delimit-template.js +14 -0
- package/lib/managed-section.js +92 -0
- package/lib/trust-page-engine.js +6 -2
- package/lib/wrap-engine.js +21 -4
- package/package.json +8 -2
- package/scripts/postinstall.js +89 -40
- package/gateway/ai/content_grounding/__init__.py +0 -98
- package/gateway/ai/content_grounding/build.py +0 -350
- package/gateway/ai/content_grounding/consume.py +0 -280
- package/gateway/ai/content_grounding/features.py +0 -218
- package/gateway/ai/content_grounding/fixtures/fail/01_missing_evidence.json +0 -9
- package/gateway/ai/content_grounding/fixtures/fail/02_unknown_evidence_prefix.json +0 -9
- package/gateway/ai/content_grounding/fixtures/fail/03_banned_comparative.json +0 -17
- package/gateway/ai/content_grounding/fixtures/fail/04_banned_adoption.json +0 -17
- package/gateway/ai/content_grounding/fixtures/fail/05_aggregate_no_numeric.json +0 -17
- package/gateway/ai/content_grounding/fixtures/fail/06_unversioned_inference_rule.json +0 -18
- package/gateway/ai/content_grounding/fixtures/pass/01_feature_shipped.json +0 -18
- package/gateway/ai/content_grounding/fixtures/pass/02_aggregate_claim.json +0 -23
- package/gateway/ai/content_grounding/fixtures/pass/03_attestation.json +0 -16
- package/gateway/ai/content_grounding/schemas/claim.schema.json +0 -40
- package/gateway/ai/content_grounding/schemas/event.schema.json +0 -23
- package/gateway/ai/content_grounding/schemas.py +0 -276
- package/gateway/ai/content_grounding/telemetry.py +0 -221
- package/gateway/ai/inbox_drafts/__init__.py +0 -61
- package/gateway/ai/inbox_drafts/registry.py +0 -412
- package/gateway/ai/inbox_drafts/schema.py +0 -374
- package/gateway/ai/inbox_executor.py +0 -565
|
@@ -0,0 +1,92 @@
|
|
|
1
|
+
// lib/managed-section.js
|
|
2
|
+
//
|
|
3
|
+
// Shared upsertDelimitSection helper. Used by:
|
|
4
|
+
// bin/delimit-setup.js — for ~/CLAUDE.md, ~/.codex/instructions.md, ~/.cursorrules
|
|
5
|
+
// adapters/cursor-rules.js — for ~/.cursor/rules/delimit.md
|
|
6
|
+
//
|
|
7
|
+
// NEVER clobbers user-authored content outside the markers. Behavior:
|
|
8
|
+
// - File missing → create with just the managed section.
|
|
9
|
+
// - File has markers → replace only the region between them (user content
|
|
10
|
+
// above/below preserved).
|
|
11
|
+
// - File has no markers → append the managed section at the bottom (user
|
|
12
|
+
// content at top preserved).
|
|
13
|
+
//
|
|
14
|
+
// History (institutional memory; do NOT change marker semantics without
|
|
15
|
+
// understanding these incidents):
|
|
16
|
+
// - v4.1.47: previous heuristic replaced the whole file whenever it
|
|
17
|
+
// detected "old Delimit content" — destroyed founder-customized
|
|
18
|
+
// CLAUDE.md files on every upgrade.
|
|
19
|
+
// - v4.1.49: unanchored marker regex matched markers inside quoted
|
|
20
|
+
// prose (backticks, bullets, blockquotes) — clobbered /root/CLAUDE.md.
|
|
21
|
+
// The current regex is anchored with the multiline flag so markers
|
|
22
|
+
// MUST be on their own line. Optional leading horizontal whitespace
|
|
23
|
+
// [ \t]* permits genuinely indented markers but NOT prose-leading
|
|
24
|
+
// characters like "- ", "> ", "`", "*".
|
|
25
|
+
//
|
|
26
|
+
// Returns: { action: 'created' | 'updated' | 'unchanged' | 'appended' }
|
|
27
|
+
|
|
28
|
+
const fs = require('fs');
|
|
29
|
+
const path = require('path');
|
|
30
|
+
|
|
31
|
+
function loadPackageVersion() {
|
|
32
|
+
try {
|
|
33
|
+
const pkg = JSON.parse(fs.readFileSync(path.join(__dirname, '..', 'package.json'), 'utf-8'));
|
|
34
|
+
return pkg.version || '0.0.0';
|
|
35
|
+
} catch {
|
|
36
|
+
return '0.0.0';
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
/**
|
|
41
|
+
* Upsert the Delimit section in a file using <!-- delimit:start v<version> -->
|
|
42
|
+
* and <!-- delimit:end --> markers.
|
|
43
|
+
*
|
|
44
|
+
* @param {string} filePath - Absolute path to the target file.
|
|
45
|
+
* @param {string} newSection - The full managed-section text (including markers).
|
|
46
|
+
* @param {string} [version] - Version string for staleness check. Defaults to package.json.
|
|
47
|
+
* @returns {{action: 'created'|'updated'|'unchanged'|'appended'}}
|
|
48
|
+
*/
|
|
49
|
+
function upsertManagedSection(filePath, newSection, version) {
|
|
50
|
+
if (!version) version = loadPackageVersion();
|
|
51
|
+
|
|
52
|
+
if (!fs.existsSync(filePath)) {
|
|
53
|
+
fs.writeFileSync(filePath, newSection + '\n');
|
|
54
|
+
return { action: 'created' };
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
const rawExisting = fs.readFileSync(filePath, 'utf-8');
|
|
58
|
+
// Strip a UTF-8 BOM if present so the start-of-line anchor still matches
|
|
59
|
+
// the very first line of the file. We write back the stripped form to keep
|
|
60
|
+
// serialization deterministic.
|
|
61
|
+
const existing = rawExisting.replace(/^/, '');
|
|
62
|
+
|
|
63
|
+
const startMarkerRe = /^[ \t]*<!-- delimit:start[^>]*-->[ \t]*$/m;
|
|
64
|
+
const endMarkerRe = /^[ \t]*<!-- delimit:end -->[ \t]*$/m;
|
|
65
|
+
const startMatch = existing.match(startMarkerRe);
|
|
66
|
+
const endMatch = existing.match(endMarkerRe);
|
|
67
|
+
|
|
68
|
+
if (startMatch && endMatch) {
|
|
69
|
+
// Extract current version from the marker (also anchored, allows indent)
|
|
70
|
+
const versionMatch = existing.match(/^[ \t]*<!-- delimit:start v([^ ]+) -->[ \t]*$/m);
|
|
71
|
+
const currentVersion = versionMatch ? versionMatch[1] : '';
|
|
72
|
+
if (currentVersion === version) {
|
|
73
|
+
return { action: 'unchanged' };
|
|
74
|
+
}
|
|
75
|
+
// Replace only the managed region — preserve content above/below
|
|
76
|
+
const startIdx = startMatch.index;
|
|
77
|
+
const endIdx = endMatch.index + endMatch[0].length;
|
|
78
|
+
const before = existing.substring(0, startIdx);
|
|
79
|
+
const after = existing.substring(endIdx);
|
|
80
|
+
fs.writeFileSync(filePath, before + newSection + after);
|
|
81
|
+
return { action: 'updated' };
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
// No markers present — append the managed section at the bottom.
|
|
85
|
+
// User content above is preserved verbatim. Markers get added so future
|
|
86
|
+
// upgrades can update just the managed region.
|
|
87
|
+
const separator = existing.endsWith('\n') ? '\n' : '\n\n';
|
|
88
|
+
fs.writeFileSync(filePath, existing + separator + newSection + '\n');
|
|
89
|
+
return { action: 'appended' };
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
module.exports = { upsertManagedSection, loadPackageVersion };
|
package/lib/trust-page-engine.js
CHANGED
|
@@ -10,6 +10,7 @@ const crypto = require('crypto');
|
|
|
10
10
|
const fs = require('fs');
|
|
11
11
|
const path = require('path');
|
|
12
12
|
const os = require('os');
|
|
13
|
+
const { canonicalize } = require('./wrap-engine');
|
|
13
14
|
|
|
14
15
|
function loadHmacKey() {
|
|
15
16
|
const keyPath = path.join(os.homedir(), '.delimit', 'wrap-hmac.key');
|
|
@@ -20,8 +21,11 @@ function loadHmacKey() {
|
|
|
20
21
|
function verifySignature(attestation, key) {
|
|
21
22
|
if (!key) return 'unverifiable';
|
|
22
23
|
try {
|
|
23
|
-
|
|
24
|
-
|
|
24
|
+
// LED-1180: must use the same recursive sorted-key canonicalize
|
|
25
|
+
// as wrap-engine; using JSON.stringify(.., keys.sort()) here
|
|
26
|
+
// would treat the array as an allowlist and serialise nested
|
|
27
|
+
// fields as {}, matching the old broken signature trivially.
|
|
28
|
+
const expected = crypto.createHmac('sha256', key).update(canonicalize(attestation.bundle)).digest('hex');
|
|
25
29
|
return expected === attestation.signature ? 'verified' : 'signature_mismatch';
|
|
26
30
|
} catch {
|
|
27
31
|
return 'verify_error';
|
package/lib/wrap-engine.js
CHANGED
|
@@ -138,9 +138,26 @@ function runTestSmoke(cwd) {
|
|
|
138
138
|
// Attestation bundling + signing
|
|
139
139
|
// ----------------------------------------------------------------------------
|
|
140
140
|
|
|
141
|
+
// LED-1180: deterministic canonical JSON. Recursively sorts object keys
|
|
142
|
+
// at every depth. Earlier implementations passed the second argument of
|
|
143
|
+
// JSON.stringify as `Object.keys(bundle).sort()`, which JSON.stringify
|
|
144
|
+
// treats as a property ALLOWLIST (not a sort order), filtered to
|
|
145
|
+
// top-level keys. The result was that nested objects serialised as
|
|
146
|
+
// `{}` and the HMAC committed only to the top-level shape — meaning a
|
|
147
|
+
// bad actor could change `bundle.governance.violations` or any nested
|
|
148
|
+
// field without invalidating the signature. Fixed in v4.5.1 hotfix.
|
|
149
|
+
// Verifier must use the same canonicalize to match.
|
|
150
|
+
function canonicalize(value) {
|
|
151
|
+
if (value === null || typeof value !== 'object') return JSON.stringify(value);
|
|
152
|
+
if (Array.isArray(value)) {
|
|
153
|
+
return '[' + value.map(canonicalize).join(',') + ']';
|
|
154
|
+
}
|
|
155
|
+
const keys = Object.keys(value).sort();
|
|
156
|
+
return '{' + keys.map((k) => JSON.stringify(k) + ':' + canonicalize(value[k])).join(',') + '}';
|
|
157
|
+
}
|
|
158
|
+
|
|
141
159
|
function computeAttestationId(bundle) {
|
|
142
|
-
const
|
|
143
|
-
const hash = crypto.createHash('sha256').update(canonical).digest('hex');
|
|
160
|
+
const hash = crypto.createHash('sha256').update(canonicalize(bundle)).digest('hex');
|
|
144
161
|
return 'att_' + hash.slice(0, 16);
|
|
145
162
|
}
|
|
146
163
|
|
|
@@ -157,8 +174,7 @@ function loadOrCreateHmacKey() {
|
|
|
157
174
|
|
|
158
175
|
function signAttestation(bundle) {
|
|
159
176
|
const key = loadOrCreateHmacKey();
|
|
160
|
-
|
|
161
|
-
return crypto.createHmac('sha256', key).update(canonical).digest('hex');
|
|
177
|
+
return crypto.createHmac('sha256', key).update(canonicalize(bundle)).digest('hex');
|
|
162
178
|
}
|
|
163
179
|
|
|
164
180
|
// ----------------------------------------------------------------------------
|
|
@@ -442,6 +458,7 @@ async function runWrap(rawCmd, options = {}) {
|
|
|
442
458
|
|
|
443
459
|
module.exports = {
|
|
444
460
|
runWrap,
|
|
461
|
+
canonicalize,
|
|
445
462
|
computeAttestationId,
|
|
446
463
|
signAttestation,
|
|
447
464
|
checkQuota,
|
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.5.
|
|
4
|
+
"version": "4.5.2",
|
|
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": [
|
|
@@ -16,6 +16,9 @@
|
|
|
16
16
|
"!gateway/ai/founding_users.py",
|
|
17
17
|
"!gateway/ai/inbox_daemon.py",
|
|
18
18
|
"!gateway/ai/inbox_daemon_runner.py",
|
|
19
|
+
"!gateway/ai/self_repair/",
|
|
20
|
+
"!gateway/ai/self_repair_daemon.py",
|
|
21
|
+
"!gateway/ai/corp_dashboard.py",
|
|
19
22
|
"!gateway/ai/deliberation.py",
|
|
20
23
|
"!gateway/ai/dv_mention_tracker.py",
|
|
21
24
|
"!gateway/ai/sensor_twttr.py",
|
|
@@ -26,6 +29,9 @@
|
|
|
26
29
|
"!gateway/ai/content_intel.py",
|
|
27
30
|
"!gateway/ai/loop_daemon.py",
|
|
28
31
|
"!gateway/ai/loop_engine.py",
|
|
32
|
+
"!gateway/ai/content_grounding/",
|
|
33
|
+
"!gateway/ai/inbox_drafts/",
|
|
34
|
+
"!gateway/ai/inbox_executor.py",
|
|
29
35
|
"scripts/",
|
|
30
36
|
"!scripts/crosspost_devto.py",
|
|
31
37
|
"!scripts/repo_targeting.py",
|
|
@@ -48,7 +54,7 @@
|
|
|
48
54
|
"postinstall": "node scripts/postinstall.js",
|
|
49
55
|
"sync-gateway": "bash scripts/sync-gateway.sh",
|
|
50
56
|
"prepublishOnly": "bash scripts/publish-ci-guard.sh && npm run sync-gateway && bash scripts/security-check.sh",
|
|
51
|
-
"test": "node --test tests/setup-onboarding.test.js tests/setup-matrix.test.js tests/setup-no-clobber.test.js tests/config-export-import.test.js tests/cross-model-hooks.test.js tests/golden-path.test.js tests/v420-features.test.js tests/v43-wrap-engine.test.js tests/v43-trust-page-engine.test.js tests/v43-ai-sbom-engine.test.js"
|
|
57
|
+
"test": "node --test tests/setup-onboarding.test.js tests/setup-matrix.test.js tests/setup-no-clobber.test.js tests/config-export-import.test.js tests/cross-model-hooks.test.js tests/golden-path.test.js tests/v420-features.test.js tests/v43-wrap-engine.test.js tests/v43-trust-page-engine.test.js tests/v43-ai-sbom-engine.test.js tests/attest-mcp.test.js tests/delimit-home.test.js tests/postinstall-hardening.test.js"
|
|
52
58
|
},
|
|
53
59
|
"keywords": [
|
|
54
60
|
"openapi",
|
package/scripts/postinstall.js
CHANGED
|
@@ -1,47 +1,96 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
/**
|
|
3
3
|
* Postinstall — anonymous install ping + setup hint.
|
|
4
|
+
*
|
|
5
|
+
* v4.5.2 (LED-1188) install hardening:
|
|
6
|
+
* - Top-level try/catch ensures NO postinstall failure can ever block
|
|
7
|
+
* `npm install delimit-cli`. Per the customer-protection rule in
|
|
8
|
+
* /root/.claude/CLAUDE.md, npm publish is a production deploy and a
|
|
9
|
+
* postinstall crash on a Pro user's machine is a customer-facing
|
|
10
|
+
* incident regardless of root cause.
|
|
11
|
+
* - EROFS / EACCES / EPERM / ENOSPC / ENOENT on stdout writes soft-fail
|
|
12
|
+
* silently. (Some sandbox installers redirect stdout to a read-only
|
|
13
|
+
* pipe.)
|
|
14
|
+
* - Network telemetry stays best-effort; no crash if DNS / TLS / proxy
|
|
15
|
+
* misbehaves. DELIMIT_NO_TELEMETRY=1 honored as kill switch.
|
|
16
|
+
* - Idempotent — re-running install is a no-op, never corrupts state.
|
|
17
|
+
* This file does not write to ~/.delimit/; that's bin/delimit-setup.js.
|
|
18
|
+
*
|
|
4
19
|
* No PII. Silent fail. Never blocks install.
|
|
5
20
|
*/
|
|
6
21
|
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
console.log('');
|
|
10
|
-
console.log(' \x1b[1m\x1b[35mDelimit\x1b[0m v' + v + ' installed');
|
|
11
|
-
console.log('');
|
|
12
|
-
console.log(' Quick start:');
|
|
13
|
-
console.log(' \x1b[32mdelimit doctor\x1b[0m Check your setup, fix what\'s missing');
|
|
14
|
-
console.log(' \x1b[32mdelimit simulate\x1b[0m Dry-run: see what governance would block');
|
|
15
|
-
console.log(' \x1b[32mdelimit status\x1b[0m Visual dashboard of your governance posture');
|
|
16
|
-
console.log(' \x1b[32mdelimit setup\x1b[0m Install MCP governance for AI assistants');
|
|
17
|
-
console.log('');
|
|
18
|
-
console.log(' Docs: \x1b[36mhttps://delimit.ai/docs\x1b[0m');
|
|
19
|
-
console.log(' Star us: \x1b[36mhttps://github.com/delimit-ai/delimit-mcp-server\x1b[0m');
|
|
20
|
-
console.log('');
|
|
22
|
+
(function postinstall() {
|
|
23
|
+
'use strict';
|
|
21
24
|
|
|
22
|
-
//
|
|
23
|
-
try
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
25
|
+
// --- 1. setup hint ------------------------------------------------------
|
|
26
|
+
// Wrapped in try/catch because console.log can throw on EPIPE / EBADF
|
|
27
|
+
// when the parent npm process closed stdout early.
|
|
28
|
+
let pkg;
|
|
29
|
+
try {
|
|
30
|
+
pkg = require('../package.json');
|
|
31
|
+
} catch (e) {
|
|
32
|
+
// package.json missing or unreadable — nothing to print, nothing
|
|
33
|
+
// to ping. This is a partial-install state; let the install
|
|
34
|
+
// complete so `delimit doctor` can diagnose later.
|
|
35
|
+
return;
|
|
36
|
+
}
|
|
37
|
+
const v = (pkg && pkg.version) || '?';
|
|
38
|
+
|
|
39
|
+
function safeLog(msg) {
|
|
40
|
+
try { process.stdout.write(msg + '\n'); }
|
|
41
|
+
catch (_) { /* EPIPE / EBADF / EROFS on stdout — give up silently */ }
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
try {
|
|
45
|
+
safeLog('');
|
|
46
|
+
safeLog(' \x1b[1m\x1b[35mDelimit\x1b[0m v' + v + ' installed');
|
|
47
|
+
safeLog('');
|
|
48
|
+
safeLog(' Quick start:');
|
|
49
|
+
safeLog(' \x1b[32mdelimit doctor\x1b[0m Check your setup, fix what\'s missing');
|
|
50
|
+
safeLog(' \x1b[32mdelimit simulate\x1b[0m Dry-run: see what governance would block');
|
|
51
|
+
safeLog(' \x1b[32mdelimit status\x1b[0m Visual dashboard of your governance posture');
|
|
52
|
+
safeLog(' \x1b[32mdelimit setup\x1b[0m Install MCP governance for AI assistants');
|
|
53
|
+
safeLog('');
|
|
54
|
+
safeLog(' Docs: \x1b[36mhttps://delimit.ai/docs\x1b[0m');
|
|
55
|
+
safeLog(' Star us: \x1b[36mhttps://github.com/delimit-ai/delimit-mcp-server\x1b[0m');
|
|
56
|
+
safeLog('');
|
|
57
|
+
} catch (_) { /* never block install on a print failure */ }
|
|
58
|
+
|
|
59
|
+
// --- 2. anonymous install telemetry ------------------------------------
|
|
60
|
+
// Honor opt-out and corporate proxy environments. The HTTPS request is
|
|
61
|
+
// silent-fail at every level (DNS / TCP / TLS / write / response).
|
|
62
|
+
const tele = (process.env.DELIMIT_NO_TELEMETRY || '').toLowerCase();
|
|
63
|
+
if (tele === '1' || tele === 'true' || tele === 'yes') return;
|
|
64
|
+
|
|
65
|
+
try {
|
|
66
|
+
const https = require('https');
|
|
67
|
+
const data = JSON.stringify({
|
|
68
|
+
event: 'install',
|
|
69
|
+
version: v,
|
|
70
|
+
node: process.version,
|
|
71
|
+
platform: process.platform,
|
|
72
|
+
arch: process.arch,
|
|
73
|
+
ts: new Date().toISOString()
|
|
74
|
+
});
|
|
75
|
+
const req = https.request({
|
|
76
|
+
hostname: 'delimit.ai',
|
|
77
|
+
path: '/api/telemetry',
|
|
78
|
+
method: 'POST',
|
|
79
|
+
headers: {
|
|
80
|
+
'Content-Type': 'application/json',
|
|
81
|
+
'Content-Length': Buffer.byteLength(data)
|
|
82
|
+
},
|
|
83
|
+
timeout: 3000
|
|
84
|
+
});
|
|
85
|
+
// Catch every error class: ENOTFOUND, ECONNREFUSED, ETIMEDOUT,
|
|
86
|
+
// CERT_HAS_EXPIRED, EPROTO, etc. None should ever propagate.
|
|
87
|
+
req.on('error', () => {});
|
|
88
|
+
req.on('timeout', () => { try { req.destroy(); } catch (_) {} });
|
|
89
|
+
req.write(data);
|
|
90
|
+
req.end();
|
|
91
|
+
} catch (_) { /* silent fail — never block install */ }
|
|
92
|
+
})();
|
|
93
|
+
|
|
94
|
+
// Outermost guard: even if the IIFE above throws synchronously somehow
|
|
95
|
+
// (require() race, V8 bug, etc), don't propagate a non-zero exit code.
|
|
96
|
+
process.on('uncaughtException', () => { /* swallow */ });
|
|
@@ -1,98 +0,0 @@
|
|
|
1
|
-
"""
|
|
2
|
-
Delimit content grounding layer — LED-1084 Week 1.
|
|
3
|
-
|
|
4
|
-
Purpose: normalize ledger entries, attestations, and git history into
|
|
5
|
-
evidence-backed `GroundedEvent` records with typed atomic `Claim`s.
|
|
6
|
-
Every downstream generator (blog, social drafter, storyline) consumes
|
|
7
|
-
this layer and MUST NOT fabricate claims that aren't backed by an
|
|
8
|
-
evidence_ref.
|
|
9
|
-
|
|
10
|
-
Architectural amendments (per 2026-04-24 adversarial rebuttal,
|
|
11
|
-
/home/delimit/delimit-private/strategy/CONTENT_GROUNDING_REBUTTAL_2026_04.md):
|
|
12
|
-
|
|
13
|
-
A3. Week 1 is strictly NON-PUBLISHING. Publish endpoints are
|
|
14
|
-
hard-disabled at the code level (see `_PUBLISH_DISABLED` below).
|
|
15
|
-
A5. Claims are typed atomic objects with explicit evidence_refs,
|
|
16
|
-
visibility, and optional versioned inference_rule.
|
|
17
|
-
A6. Hard bans during Week 1/2: comparative, adoption, customer,
|
|
18
|
-
aggregate, roadmap claims reject unless exact text whitelisted
|
|
19
|
-
or (for aggregates) backed by structured numeric evidence.
|
|
20
|
-
A9. Deterministic extraction gate: extract → classify → map to
|
|
21
|
-
allowed claim IDs → reject on any unmatched/uncertain claim →
|
|
22
|
-
persist audit record. All content passes through this gate.
|
|
23
|
-
A10. One-strike kill semantics: any externally published ungrounded
|
|
24
|
-
claim reverts ALL generators to manual-only mode.
|
|
25
|
-
|
|
26
|
-
This module never generates public content. It only produces the
|
|
27
|
-
grounded event + claim records that generators consume.
|
|
28
|
-
"""
|
|
29
|
-
from .schemas import (
|
|
30
|
-
ClaimType,
|
|
31
|
-
Visibility,
|
|
32
|
-
EventType,
|
|
33
|
-
EvidenceRef,
|
|
34
|
-
Claim,
|
|
35
|
-
GroundedEvent,
|
|
36
|
-
GroundingIndex,
|
|
37
|
-
)
|
|
38
|
-
from .build import (
|
|
39
|
-
build_grounding_index,
|
|
40
|
-
load_grounded_events,
|
|
41
|
-
validate_claims,
|
|
42
|
-
persist_grounding_index,
|
|
43
|
-
)
|
|
44
|
-
from .consume import (
|
|
45
|
-
GroundingBundle,
|
|
46
|
-
fetch_grounding_bundle,
|
|
47
|
-
build_allowed_claim_set,
|
|
48
|
-
load_feature_whitelist,
|
|
49
|
-
unreleased_feature_detector,
|
|
50
|
-
score_draft_grounding,
|
|
51
|
-
)
|
|
52
|
-
from .features import (
|
|
53
|
-
build_feature_set,
|
|
54
|
-
build_and_persist_features,
|
|
55
|
-
extract_mcp_tools,
|
|
56
|
-
extract_cli_commands,
|
|
57
|
-
)
|
|
58
|
-
from .telemetry import (
|
|
59
|
-
summarize as summarize_gate_telemetry,
|
|
60
|
-
recent_samples as recent_gate_samples,
|
|
61
|
-
)
|
|
62
|
-
|
|
63
|
-
__all__ = [
|
|
64
|
-
# schemas
|
|
65
|
-
"ClaimType",
|
|
66
|
-
"Visibility",
|
|
67
|
-
"EventType",
|
|
68
|
-
"EvidenceRef",
|
|
69
|
-
"Claim",
|
|
70
|
-
"GroundedEvent",
|
|
71
|
-
"GroundingIndex",
|
|
72
|
-
# build
|
|
73
|
-
"build_grounding_index",
|
|
74
|
-
"load_grounded_events",
|
|
75
|
-
"validate_claims",
|
|
76
|
-
"persist_grounding_index",
|
|
77
|
-
# consume (Week 2)
|
|
78
|
-
"GroundingBundle",
|
|
79
|
-
"fetch_grounding_bundle",
|
|
80
|
-
"build_allowed_claim_set",
|
|
81
|
-
"load_feature_whitelist",
|
|
82
|
-
"unreleased_feature_detector",
|
|
83
|
-
"score_draft_grounding",
|
|
84
|
-
# features whitelist builder (Week 2)
|
|
85
|
-
"build_feature_set",
|
|
86
|
-
"build_and_persist_features",
|
|
87
|
-
"extract_mcp_tools",
|
|
88
|
-
"extract_cli_commands",
|
|
89
|
-
# telemetry (Week 2 → Week 3 bridge)
|
|
90
|
-
"summarize_gate_telemetry",
|
|
91
|
-
"recent_gate_samples",
|
|
92
|
-
]
|
|
93
|
-
|
|
94
|
-
# A3: publish paths are OFF. Any attempt to publish grounded content
|
|
95
|
-
# externally during Week 1 raises. Flip to True only after Week 2
|
|
96
|
-
# hardening (claim-type classifiers, implication detection) and explicit
|
|
97
|
-
# founder approval.
|
|
98
|
-
_PUBLISH_DISABLED = True
|