@mudraforge/statutory 2.6.0 → 2.8.0
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 +46 -0
- package/README.md +60 -27
- package/bin/cli.js +368 -18
- package/docs/CORPUS_QUALITY.md +19 -6
- package/docs/PROVENANCE.md +33 -0
- package/okf/manifest.json +1 -1
- package/okf.publication.json +1 -1
- package/package.json +3 -2
- package/src/index.js +1162 -2
- package/types/index.d.ts +104 -0
package/bin/cli.js
CHANGED
|
@@ -18,6 +18,11 @@ import {
|
|
|
18
18
|
getLocalManifest,
|
|
19
19
|
checkForPackageUpdate,
|
|
20
20
|
decodeTaxIdentifier,
|
|
21
|
+
verifyLocalSubstrate,
|
|
22
|
+
runStatutoryDoctor,
|
|
23
|
+
crosswalkStatute,
|
|
24
|
+
getStatutoryDiff,
|
|
25
|
+
STATUTORY_EXIT_CODES,
|
|
21
26
|
STATUTORY_CLIENT_VERSION,
|
|
22
27
|
DEFAULT_LOCAL_OKF_DIR
|
|
23
28
|
} from '../src/index.js';
|
|
@@ -25,11 +30,65 @@ import {
|
|
|
25
30
|
const __filename = fileURLToPath(import.meta.url);
|
|
26
31
|
const __dirname = path.dirname(__filename);
|
|
27
32
|
|
|
28
|
-
const
|
|
33
|
+
const rawArgs = process.argv.slice(2);
|
|
34
|
+
const isJsonMode = rawArgs.includes('--json') || rawArgs.includes('-j');
|
|
35
|
+
const isOfflineMode = rawArgs.includes('--offline') || rawArgs.includes('-o');
|
|
36
|
+
const args = rawArgs.filter(a => a !== '--json' && a !== '-j' && a !== '--offline' && a !== '-o');
|
|
29
37
|
const command = args[0] ? args[0].toLowerCase() : 'help';
|
|
30
38
|
|
|
39
|
+
function getNamedArg(nameList, argList) {
|
|
40
|
+
for (let i = 0; i < argList.length; i++) {
|
|
41
|
+
const item = argList[i];
|
|
42
|
+
for (const name of nameList) {
|
|
43
|
+
if (item === name && i + 1 < argList.length && !argList[i + 1].startsWith('-')) {
|
|
44
|
+
return argList[i + 1];
|
|
45
|
+
}
|
|
46
|
+
if (item.startsWith(`${name}=`)) {
|
|
47
|
+
return item.slice(name.length + 1);
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
return null;
|
|
52
|
+
}
|
|
53
|
+
|
|
31
54
|
async function main() {
|
|
32
55
|
switch (command) {
|
|
56
|
+
case 'doctor':
|
|
57
|
+
case 'diagnose':
|
|
58
|
+
await handleDoctor();
|
|
59
|
+
break;
|
|
60
|
+
|
|
61
|
+
case 'verify':
|
|
62
|
+
case 'audit':
|
|
63
|
+
case 'check':
|
|
64
|
+
await handleVerify(args[1]);
|
|
65
|
+
break;
|
|
66
|
+
|
|
67
|
+
case 'crosswalk':
|
|
68
|
+
case 'bridge':
|
|
69
|
+
case 'transition': {
|
|
70
|
+
const section = (args[1] && !args[1].startsWith('-')) ? args[1] : getNamedArg(['--section', '-s'], rawArgs);
|
|
71
|
+
const creditDate = getNamedArg(['--credit', '-c'], rawArgs);
|
|
72
|
+
const paymentDate = getNamedArg(['--payment', '-p'], rawArgs);
|
|
73
|
+
const asOfDate = getNamedArg(['--date', '-d', '--as-of'], rawArgs);
|
|
74
|
+
if (!section) {
|
|
75
|
+
console.error('[ERROR] Please specify a section to crosswalk, e.g. npx @mudraforge/statutory crosswalk 194Q --credit 2026-03-25 --payment 2026-04-10');
|
|
76
|
+
process.exit(STATUTORY_EXIT_CODES.USAGE_ERROR);
|
|
77
|
+
}
|
|
78
|
+
await handleCrosswalk(section, { creditDate, paymentDate, asOfDate });
|
|
79
|
+
break;
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
case 'diff':
|
|
83
|
+
case 'changelog':
|
|
84
|
+
case 'amendments': {
|
|
85
|
+
const section = (args[1] && !args[1].startsWith('-')) ? args[1] : getNamedArg(['--section', '-s'], rawArgs);
|
|
86
|
+
const since = getNamedArg(['--since'], rawArgs);
|
|
87
|
+
const domain = getNamedArg(['--domain'], rawArgs);
|
|
88
|
+
await handleDiff({ section, since, domain });
|
|
89
|
+
break;
|
|
90
|
+
}
|
|
91
|
+
|
|
33
92
|
case 'init-skill':
|
|
34
93
|
case 'install-skill':
|
|
35
94
|
await handleInitSkill(args[1]);
|
|
@@ -43,9 +102,16 @@ async function main() {
|
|
|
43
102
|
|
|
44
103
|
case 'sync':
|
|
45
104
|
case 'pull':
|
|
46
|
-
case 'update':
|
|
47
|
-
|
|
105
|
+
case 'update': {
|
|
106
|
+
let target = args[1];
|
|
107
|
+
if (target === '--dest' || target === '-d') {
|
|
108
|
+
target = args[2];
|
|
109
|
+
} else if (target && target.startsWith('--dest=')) {
|
|
110
|
+
target = target.slice(7);
|
|
111
|
+
}
|
|
112
|
+
await handleSync(target);
|
|
48
113
|
break;
|
|
114
|
+
}
|
|
49
115
|
|
|
50
116
|
case 'browse':
|
|
51
117
|
case 'nav':
|
|
@@ -83,7 +149,7 @@ async function main() {
|
|
|
83
149
|
}
|
|
84
150
|
|
|
85
151
|
// Non-intrusive background npm package update notice
|
|
86
|
-
if (!['check-update', 'status', 'version'].includes(command)) {
|
|
152
|
+
if (!isJsonMode && !['check-update', 'status', 'version', 'verify', 'audit', 'check', 'crosswalk', 'bridge', 'transition', 'diff', 'changelog', 'amendments'].includes(command)) {
|
|
87
153
|
try {
|
|
88
154
|
const updateInfo = await checkForPackageUpdate();
|
|
89
155
|
if (updateInfo && updateInfo.updateAvailable) {
|
|
@@ -96,23 +162,244 @@ async function main() {
|
|
|
96
162
|
}
|
|
97
163
|
}
|
|
98
164
|
|
|
165
|
+
async function handleVerify(targetDir) {
|
|
166
|
+
try {
|
|
167
|
+
let dest = DEFAULT_LOCAL_OKF_DIR;
|
|
168
|
+
if (targetDir) {
|
|
169
|
+
dest = path.resolve(process.cwd(), targetDir);
|
|
170
|
+
}
|
|
171
|
+
const report = verifyLocalSubstrate(dest);
|
|
172
|
+
if (isJsonMode) {
|
|
173
|
+
console.log(JSON.stringify(report, null, 2));
|
|
174
|
+
process.exit(report.exitCode);
|
|
175
|
+
}
|
|
176
|
+
|
|
177
|
+
console.log('\n===========================================================================');
|
|
178
|
+
console.log(`MUDRAFORGE OPEN KNOWLEDGE FORMAT (OKF) — CRYPTOGRAPHIC VERIFIER [v${report.okfVersion || 'Unknown'}]`);
|
|
179
|
+
console.log('===========================================================================');
|
|
180
|
+
|
|
181
|
+
if (report.integrity.valid) {
|
|
182
|
+
console.log(`[OK] Integrity: ${report.integrity.totalFilesChecked} files verified against Merkle manifest.`);
|
|
183
|
+
console.log(` Root Merkle Hash: ${report.integrity.computedRoot}`);
|
|
184
|
+
} else {
|
|
185
|
+
console.error(`[FAIL] Integrity: Mismatches: ${report.integrity.mismatches.length}, Missing: ${report.integrity.missingFiles.length}, Untracked: ${report.integrity.untrackedFiles.length}`);
|
|
186
|
+
for (const m of report.integrity.mismatches) {
|
|
187
|
+
console.error(` • ${m.file} (Expected ${m.expected.slice(0, 10)}..., actual ${m.actual.slice(0, 10)}...)`);
|
|
188
|
+
}
|
|
189
|
+
for (const mf of report.integrity.missingFiles) {
|
|
190
|
+
console.error(` • Missing: ${mf}`);
|
|
191
|
+
}
|
|
192
|
+
}
|
|
193
|
+
|
|
194
|
+
if (report.authenticity.valid) {
|
|
195
|
+
console.log(`[OK] Authenticity: Provenance authenticated via ${report.authenticity.method}.`);
|
|
196
|
+
if (report.authenticity.keyId) {
|
|
197
|
+
console.log(` Signer Key ID: ${report.authenticity.keyId}`);
|
|
198
|
+
}
|
|
199
|
+
} else {
|
|
200
|
+
console.error(`[FAIL] Authenticity: Root hash "${report.integrity.computedRoot}" is neither pinned nor signed by an authorized MudraForge trust anchor.`);
|
|
201
|
+
}
|
|
202
|
+
|
|
203
|
+
if (report.baselineCheck.valid) {
|
|
204
|
+
console.log(`[OK] Statutory Policy: All mandatory baseline provisions present (${report.baselineCheck.baselineSections.join(', ')}).`);
|
|
205
|
+
} else {
|
|
206
|
+
console.error(`[FAIL] Statutory Policy: Missing mandatory baseline provisions: ${report.baselineCheck.missingBaseline.join(', ')}`);
|
|
207
|
+
}
|
|
208
|
+
|
|
209
|
+
console.log('───────────────────────────────────────────────────────────────────────────');
|
|
210
|
+
if (report.valid) {
|
|
211
|
+
console.log(`[PASS] Statutory substrate is authentic, intact, and compliant (Exit ${report.exitCode}).\n`);
|
|
212
|
+
} else {
|
|
213
|
+
console.error(`[FAIL] Verification failed with Exit Code ${report.exitCode}.\n`);
|
|
214
|
+
}
|
|
215
|
+
process.exit(report.exitCode);
|
|
216
|
+
} catch (err) {
|
|
217
|
+
if (isJsonMode) {
|
|
218
|
+
console.log(JSON.stringify({ valid: false, exitCode: STATUTORY_EXIT_CODES.USAGE_ERROR, error: err.message }, null, 2));
|
|
219
|
+
} else {
|
|
220
|
+
console.error(`[ERROR] Verification error: ${err.message}`);
|
|
221
|
+
}
|
|
222
|
+
process.exit(STATUTORY_EXIT_CODES.USAGE_ERROR);
|
|
223
|
+
}
|
|
224
|
+
}
|
|
225
|
+
|
|
226
|
+
async function handleDoctor() {
|
|
227
|
+
try {
|
|
228
|
+
const report = await runStatutoryDoctor({ offline: isOfflineMode });
|
|
229
|
+
if (isJsonMode) {
|
|
230
|
+
console.log(JSON.stringify(report, null, 2));
|
|
231
|
+
process.exit(report.exitCode);
|
|
232
|
+
}
|
|
233
|
+
|
|
234
|
+
console.log('\n===========================================================================');
|
|
235
|
+
console.log(`MUDRAFORGE STATUTORY DIAGNOSTIC DOCTOR [v${report.clientVersion}]`);
|
|
236
|
+
console.log('===========================================================================');
|
|
237
|
+
|
|
238
|
+
console.log('── 1. RUNTIME & HOST ENVIRONMENT ──');
|
|
239
|
+
console.log(`Node.js: ${report.runtime.nodeVersion} ${report.runtime.isSupportedNode ? '(Supported: v18+)' : '[UNSUPPORTED]'}`);
|
|
240
|
+
console.log(`Platform: ${report.runtime.platform} (${report.runtime.arch})`);
|
|
241
|
+
console.log(`Environment: ${report.runtime.environment}${report.runtime.isCI ? ' (CI Active)' : ''}`);
|
|
242
|
+
console.log(`API Key Config: ${report.runtime.hasApiKey ? 'CONFIGURED (Enterprise Tier Enabled)' : 'NOT_CONFIGURED (Free Commons Mode)'}`);
|
|
243
|
+
|
|
244
|
+
console.log('\n── 2. LOCAL OKF SUBSTRATE HEALTH ──');
|
|
245
|
+
if (report.substrate.valid) {
|
|
246
|
+
console.log(`Directory: ${DEFAULT_LOCAL_OKF_DIR}`);
|
|
247
|
+
console.log(`Manifest Version: v${report.substrate.okfVersion} (Published: ${report.substrate.publishedAt})`);
|
|
248
|
+
console.log(`Files Checked: ${report.substrate.integrity.totalFilesChecked} (0 mismatches, 0 missing, 0 untracked)`);
|
|
249
|
+
console.log(`Root Merkle Hash: ${report.substrate.integrity.computedRoot}`);
|
|
250
|
+
console.log(`Integrity: PASS`);
|
|
251
|
+
console.log(`Provenance: AUTHENTIC (${report.substrate.authenticity.method})`);
|
|
252
|
+
console.log(`Statutory Policy: PASS (All ${report.substrate.baselineCheck.baselineSections.length} mandatory baselines present)`);
|
|
253
|
+
} else {
|
|
254
|
+
console.error(`Substrate: FAILED (Exit Code ${report.substrate.exitCode})`);
|
|
255
|
+
if (report.substrate.error) console.error(`Error: ${report.substrate.error}`);
|
|
256
|
+
if (!report.substrate.integrity.valid) {
|
|
257
|
+
console.error(`Integrity Failure: ${report.substrate.integrity.mismatches.length} mismatch(es), ${report.substrate.integrity.missingFiles.length} missing files.`);
|
|
258
|
+
}
|
|
259
|
+
if (!report.substrate.authenticity.valid) {
|
|
260
|
+
console.error(`Authenticity: Root hash not authenticated.`);
|
|
261
|
+
}
|
|
262
|
+
if (!report.substrate.baselineCheck.valid) {
|
|
263
|
+
console.error(`Missing Baselines: ${report.substrate.baselineCheck.missingBaseline.join(', ')}`);
|
|
264
|
+
}
|
|
265
|
+
}
|
|
266
|
+
|
|
267
|
+
console.log('\n── 3. CLOUDFLARE ANYCAST EDGE CONNECTIVITY ──');
|
|
268
|
+
console.log(`Endpoint: ${report.edge.baseUrl}`);
|
|
269
|
+
if (report.edge.status === 'REACHABLE') {
|
|
270
|
+
console.log(`Status: REACHABLE (Latency: ${report.edge.latencyMs}ms)`);
|
|
271
|
+
} else if (report.edge.status === 'SKIPPED_AIR_GAPPED') {
|
|
272
|
+
console.log(`Status: SKIPPED (Air-Gapped / Offline Flag Enabled)`);
|
|
273
|
+
} else {
|
|
274
|
+
console.log(`Status: ${report.edge.status} (Offline-first local mode operative)`);
|
|
275
|
+
}
|
|
276
|
+
console.log(`Advisory: ${report.edge.advisory}`);
|
|
277
|
+
|
|
278
|
+
console.log('───────────────────────────────────────────────────────────────────────────');
|
|
279
|
+
if (report.healthy) {
|
|
280
|
+
console.log(`[PASS] All diagnostic checks passed with zero defects (Exit 0).\n`);
|
|
281
|
+
} else {
|
|
282
|
+
console.error(`[FAIL] Diagnostic doctor flagged health violations (Exit ${report.exitCode}).\n`);
|
|
283
|
+
}
|
|
284
|
+
process.exit(report.exitCode);
|
|
285
|
+
} catch (err) {
|
|
286
|
+
if (isJsonMode) {
|
|
287
|
+
console.log(JSON.stringify({ healthy: false, exitCode: STATUTORY_EXIT_CODES.USAGE_ERROR, error: err.message }, null, 2));
|
|
288
|
+
} else {
|
|
289
|
+
console.error(`[ERROR] Doctor diagnostic error: ${err.message}`);
|
|
290
|
+
}
|
|
291
|
+
process.exit(STATUTORY_EXIT_CODES.USAGE_ERROR);
|
|
292
|
+
}
|
|
293
|
+
}
|
|
294
|
+
|
|
295
|
+
async function handleCrosswalk(section, options) {
|
|
296
|
+
try {
|
|
297
|
+
const result = crosswalkStatute(section, options);
|
|
298
|
+
if (isJsonMode) {
|
|
299
|
+
console.log(JSON.stringify(result, null, 2));
|
|
300
|
+
process.exit(0);
|
|
301
|
+
}
|
|
302
|
+
|
|
303
|
+
console.log('\n===========================================================================');
|
|
304
|
+
console.log('MUDRAFORGE DUAL-ACT STATUTORY CROSSWALK (1961 ACT <-> 2025 ACT)');
|
|
305
|
+
console.log('===========================================================================');
|
|
306
|
+
console.log(`Query Section: ${result.querySection}`);
|
|
307
|
+
console.log(`Governing Statute: ${result.governingAct}`);
|
|
308
|
+
console.log(`Applicable Section: ${result.applicableSection}`);
|
|
309
|
+
console.log(`Temporal Status: ${result.temporalStatus}`);
|
|
310
|
+
|
|
311
|
+
console.log('\n── TEMPORAL CRYSTALLIZATION (EARLIER OF CREDIT OR PAYMENT) ──');
|
|
312
|
+
if (result.creditDate) console.log(`Credit in Books: ${result.creditDate}`);
|
|
313
|
+
if (result.paymentDate) console.log(`Payment Rail: ${result.paymentDate}`);
|
|
314
|
+
console.log(`Trigger Date: ${result.triggerDate}`);
|
|
315
|
+
console.log(`Trigger Event: ${result.triggerReason}`);
|
|
316
|
+
console.log(`Event Context: ${result.triggerDescription}`);
|
|
317
|
+
|
|
318
|
+
console.log('\n── STATUTORY BRIDGE & DUAL-ACT MAPPING ──');
|
|
319
|
+
console.log(`Predecessor (1961): ${result.crosswalk.predecessor.statutorySection} (${result.crosswalk.predecessor.title})`);
|
|
320
|
+
console.log(` Rate: ${result.crosswalk.predecessor.standardRate} | Challan: ${result.crosswalk.predecessor.challan} | Return: ${result.crosswalk.predecessor.returnForm}`);
|
|
321
|
+
console.log(`Successor (2025): ${result.crosswalk.successor.statutorySection} (Effective ${result.crosswalk.successor.effectiveDate})`);
|
|
322
|
+
console.log(` Rate: ${result.crosswalk.successor.standardRate} | Return: ${result.crosswalk.successor.returnForm}`);
|
|
323
|
+
|
|
324
|
+
console.log('\n── STATUTORY SAVINGS & LEGAL GROUNDING ──');
|
|
325
|
+
console.log(`Primary Authority: ${result.crosswalk.savingsAuthority.statute}`);
|
|
326
|
+
console.log(`Subsidiary Principle: ${result.crosswalk.savingsAuthority.subsidiary}`);
|
|
327
|
+
console.log(`Legal Analysis: ${result.legalAnalysis}`);
|
|
328
|
+
|
|
329
|
+
console.log('───────────────────────────────────────────────────────────────────────────');
|
|
330
|
+
console.log('[PASS] Statutory crosswalk resolved successfully (Exit 0).\n');
|
|
331
|
+
process.exit(0);
|
|
332
|
+
} catch (err) {
|
|
333
|
+
if (isJsonMode) {
|
|
334
|
+
console.log(JSON.stringify({ status: 'ERROR', exitCode: STATUTORY_EXIT_CODES.USAGE_ERROR, error: err.message }, null, 2));
|
|
335
|
+
} else {
|
|
336
|
+
console.error(`[ERROR] Crosswalk failure: ${err.message}`);
|
|
337
|
+
}
|
|
338
|
+
process.exit(STATUTORY_EXIT_CODES.USAGE_ERROR);
|
|
339
|
+
}
|
|
340
|
+
}
|
|
341
|
+
|
|
342
|
+
async function handleDiff(options) {
|
|
343
|
+
try {
|
|
344
|
+
const result = getStatutoryDiff(options);
|
|
345
|
+
if (isJsonMode) {
|
|
346
|
+
console.log(JSON.stringify(result, null, 2));
|
|
347
|
+
process.exit(0);
|
|
348
|
+
}
|
|
349
|
+
|
|
350
|
+
console.log('\n===========================================================================');
|
|
351
|
+
console.log('MUDRAFORGE STATUTORY REGULATORY CHANGELOG & AMENDMENT TRACKER');
|
|
352
|
+
console.log('===========================================================================');
|
|
353
|
+
console.log(`Filter Section: ${result.filterSection || 'ALL SECTIONS'}`);
|
|
354
|
+
console.log(`Filter Since: ${result.filterSince || 'ALL TIME'}`);
|
|
355
|
+
console.log(`Filter Domain: ${result.filterDomain || 'ALL DOMAINS'}`);
|
|
356
|
+
console.log(`Total Amendments: ${result.totalAmendments}`);
|
|
357
|
+
|
|
358
|
+
if (result.amendments.length === 0) {
|
|
359
|
+
console.log('\n[NOTICE] No statutory amendments matched the specified query filters.');
|
|
360
|
+
} else {
|
|
361
|
+
for (const am of result.amendments) {
|
|
362
|
+
console.log(`\n── [${am.id}] ${am.sectionCode} (${am.domain}) ──`);
|
|
363
|
+
console.log(`Title: ${am.title}`);
|
|
364
|
+
console.log(`Effective Date: ${am.effectiveDate} (${am.amendmentType})`);
|
|
365
|
+
console.log(`Governing Statute: ${am.statute}`);
|
|
366
|
+
console.log(`Enacted By: ${am.legalAuthority}`);
|
|
367
|
+
console.log(`Previous Baseline: ${am.previousValue}`);
|
|
368
|
+
console.log(`Amended Baseline: ${am.amendedValue}`);
|
|
369
|
+
console.log(`Summary: ${am.changeSummary}`);
|
|
370
|
+
console.log(`Statutory Impact: ${am.statutoryImpact}`);
|
|
371
|
+
}
|
|
372
|
+
}
|
|
373
|
+
|
|
374
|
+
console.log('───────────────────────────────────────────────────────────────────────────');
|
|
375
|
+
console.log(`[PASS] Statutory diff completed successfully (${result.totalAmendments} amendment(s) found) (Exit 0).\n`);
|
|
376
|
+
process.exit(0);
|
|
377
|
+
} catch (err) {
|
|
378
|
+
if (isJsonMode) {
|
|
379
|
+
console.log(JSON.stringify({ status: 'ERROR', exitCode: STATUTORY_EXIT_CODES.USAGE_ERROR, error: err.message }, null, 2));
|
|
380
|
+
} else {
|
|
381
|
+
console.error(`[ERROR] Statutory diff failure: ${err.message}`);
|
|
382
|
+
}
|
|
383
|
+
process.exit(STATUTORY_EXIT_CODES.USAGE_ERROR);
|
|
384
|
+
}
|
|
385
|
+
}
|
|
386
|
+
|
|
99
387
|
async function handleCheckUpdate() {
|
|
100
388
|
try {
|
|
101
|
-
|
|
389
|
+
let pkgUpdate = null;
|
|
102
390
|
try {
|
|
103
|
-
|
|
104
|
-
if (pkgUpdate && pkgUpdate.updateAvailable) {
|
|
105
|
-
console.log('───────────────────────────────────────────────────────────────────────────');
|
|
106
|
-
console.log(`[WARN] New npm package version available: v${pkgUpdate.latestVersion} (installed: v${pkgUpdate.currentVersion})`);
|
|
107
|
-
console.log(`Run: npm install @mudraforge/statutory@latest`);
|
|
108
|
-
console.log('───────────────────────────────────────────────────────────────────────────');
|
|
109
|
-
} else if (pkgUpdate) {
|
|
110
|
-
console.log(`[OK] npm package code is up to date (v${pkgUpdate.currentVersion}).`);
|
|
111
|
-
}
|
|
391
|
+
pkgUpdate = await checkForPackageUpdate({ cacheTtlMs: 0 });
|
|
112
392
|
} catch (_) {}
|
|
113
393
|
|
|
114
|
-
console.log('\n[INFO] Checking OKF knowledge substrate status against Cloudflare edge...');
|
|
115
394
|
const status = await checkUpdates();
|
|
395
|
+
|
|
396
|
+
if (isJsonMode) {
|
|
397
|
+
console.log(JSON.stringify({
|
|
398
|
+
packageUpdate: pkgUpdate,
|
|
399
|
+
substrateStatus: status
|
|
400
|
+
}, null, 2));
|
|
401
|
+
process.exit(0);
|
|
402
|
+
}
|
|
116
403
|
console.log('───────────────────────────────────────────────────────────────────────────');
|
|
117
404
|
console.log(`Local OKF Version: ${status.localVersion}`);
|
|
118
405
|
console.log(`Latest Edge Version: ${status.latestVersion}`);
|
|
@@ -179,6 +466,18 @@ async function handleSync(targetDir) {
|
|
|
179
466
|
async function handleBrowse() {
|
|
180
467
|
const manifest = getLocalManifest();
|
|
181
468
|
|
|
469
|
+
if (isJsonMode) {
|
|
470
|
+
console.log(JSON.stringify(manifest ? {
|
|
471
|
+
okfVersion: manifest.okfVersion,
|
|
472
|
+
publishedAt: manifest.publishedAt,
|
|
473
|
+
rootHash: manifest.rootHash,
|
|
474
|
+
totalSections: manifest.totalSections,
|
|
475
|
+
domains: manifest.domains,
|
|
476
|
+
sections: manifest.sections
|
|
477
|
+
} : { okfVersion: null, sections: [] }, null, 2));
|
|
478
|
+
process.exit(0);
|
|
479
|
+
}
|
|
480
|
+
|
|
182
481
|
console.log('\n===========================================================================');
|
|
183
482
|
console.log(`OPEN KNOWLEDGE FORMAT (OKF) — LOCAL BROWSER [v${manifest ? manifest.okfVersion : 'Local'}]`);
|
|
184
483
|
console.log('===========================================================================');
|
|
@@ -276,18 +575,28 @@ async function handleLookup(section, asOfDate) {
|
|
|
276
575
|
let temporalStatus = 'ACTIVE';
|
|
277
576
|
|
|
278
577
|
if (s) {
|
|
279
|
-
console.log(`\n[LOCAL OKF CACHE] Loaded section [${cleanSection}] from disk.`);
|
|
578
|
+
if (!isJsonMode) console.log(`\n[LOCAL OKF CACHE] Loaded section [${cleanSection}] from disk.`);
|
|
280
579
|
if (asOfDate) {
|
|
281
580
|
if (asOfDate < s.effectivePeriod.validFrom) temporalStatus = 'PRE_EFFECTIVE';
|
|
282
581
|
else if (s.effectivePeriod.validTo && asOfDate > s.effectivePeriod.validTo) temporalStatus = 'SUNSET_SUPERSEDED';
|
|
283
582
|
}
|
|
284
583
|
} else {
|
|
285
|
-
console.log(`\n[EDGE LOOKUP] Querying MudraForge Live Commons for [${cleanSection}]${asOfDate ? ` (as-of: ${asOfDate})` : ''}...`);
|
|
584
|
+
if (!isJsonMode) console.log(`\n[EDGE LOOKUP] Querying MudraForge Live Commons for [${cleanSection}]${asOfDate ? ` (as-of: ${asOfDate})` : ''}...`);
|
|
286
585
|
const remote = await lookupStatute(cleanSection, { asOfDate });
|
|
287
586
|
s = remote.statute;
|
|
288
587
|
temporalStatus = remote.temporalStatus;
|
|
289
588
|
}
|
|
290
589
|
|
|
590
|
+
if (isJsonMode) {
|
|
591
|
+
console.log(JSON.stringify({
|
|
592
|
+
status: 'SUCCESS',
|
|
593
|
+
sectionCode: cleanSection,
|
|
594
|
+
temporalStatus,
|
|
595
|
+
statute: s
|
|
596
|
+
}, null, 2));
|
|
597
|
+
process.exit(0);
|
|
598
|
+
}
|
|
599
|
+
|
|
291
600
|
console.log('───────────────────────────────────────────────────────────────────────────');
|
|
292
601
|
console.log(`Section: ${s.statutorySection} (${s.governingStatute})`);
|
|
293
602
|
console.log(`Title: ${s.title}`);
|
|
@@ -317,6 +626,14 @@ async function handleLookup(section, asOfDate) {
|
|
|
317
626
|
}
|
|
318
627
|
console.log('───────────────────────────────────────────────────────────────────────────\n');
|
|
319
628
|
} catch (err) {
|
|
629
|
+
if (isJsonMode) {
|
|
630
|
+
console.error(JSON.stringify({
|
|
631
|
+
status: 'ERROR',
|
|
632
|
+
error: err.message,
|
|
633
|
+
availableSections: err.availableSections || []
|
|
634
|
+
}, null, 2));
|
|
635
|
+
process.exit(1);
|
|
636
|
+
}
|
|
320
637
|
console.error(`[ERROR] Lookup failed: ${err.message}`);
|
|
321
638
|
if (err.availableSections) {
|
|
322
639
|
console.log(`Available sections: ${err.availableSections.join(', ')}`);
|
|
@@ -327,8 +644,13 @@ async function handleLookup(section, asOfDate) {
|
|
|
327
644
|
|
|
328
645
|
async function handleList() {
|
|
329
646
|
try {
|
|
330
|
-
console.log('\n[INFO] Fetching indexed statutory sections from MudraForge Commons...');
|
|
331
647
|
const sections = await listSections();
|
|
648
|
+
if (isJsonMode) {
|
|
649
|
+
console.log(JSON.stringify({ sections, total: sections.length }, null, 2));
|
|
650
|
+
process.exit(0);
|
|
651
|
+
}
|
|
652
|
+
|
|
653
|
+
console.log('\n[INFO] Fetching indexed statutory sections from MudraForge Commons...');
|
|
332
654
|
console.log('───────────────────────────────────────────────────────────────────────────');
|
|
333
655
|
for (const s of sections) {
|
|
334
656
|
const displayValidTo = (s.validTo === 'OPEN_ENDED' || s.validTo === '2099-12-31') ? 'In Force' : s.validTo;
|
|
@@ -336,6 +658,10 @@ async function handleList() {
|
|
|
336
658
|
}
|
|
337
659
|
console.log('───────────────────────────────────────────────────────────────────────────\n');
|
|
338
660
|
} catch (err) {
|
|
661
|
+
if (isJsonMode) {
|
|
662
|
+
console.error(JSON.stringify({ status: 'ERROR', error: err.message }, null, 2));
|
|
663
|
+
process.exit(1);
|
|
664
|
+
}
|
|
339
665
|
console.error(`[ERROR] Failed to list sections: ${err.message}`);
|
|
340
666
|
process.exit(1);
|
|
341
667
|
}
|
|
@@ -343,6 +669,11 @@ async function handleList() {
|
|
|
343
669
|
|
|
344
670
|
function handleDecodeId(rawId) {
|
|
345
671
|
const res = decodeTaxIdentifier(rawId);
|
|
672
|
+
if (isJsonMode) {
|
|
673
|
+
console.log(JSON.stringify(res, null, 2));
|
|
674
|
+
process.exit(res.isValid ? 0 : 1);
|
|
675
|
+
}
|
|
676
|
+
|
|
346
677
|
console.log('\n===========================================================================');
|
|
347
678
|
console.log('INDIAN TAX IDENTIFIER DECODER & OFFLINE MOD-36 VALIDATOR');
|
|
348
679
|
console.log('===========================================================================');
|
|
@@ -375,6 +706,10 @@ Usage:
|
|
|
375
706
|
npx @mudraforge/statutory <command> [options]
|
|
376
707
|
|
|
377
708
|
Commands:
|
|
709
|
+
doctor [--offline] Run full diagnostic check of runtime, substrate integrity, & edge status
|
|
710
|
+
verify [path] Cryptographically verify OKF substrate authenticity & file integrity
|
|
711
|
+
crosswalk <section> Dual-act 1961 <-> 2025 bridge (earlier of credit vs payment)
|
|
712
|
+
diff Semantic regulatory changelog (--section, --since, --domain)
|
|
378
713
|
browse Interactively browse local OKF statutory filesystem
|
|
379
714
|
lookup <section> [date] Look up section details & temporal status (e.g. 194Q 2025-06-01)
|
|
380
715
|
decode-id <pan_or_gstin> Offline ISO Mod-36 checksum, state name, and PAN entity decoding
|
|
@@ -383,6 +718,21 @@ Commands:
|
|
|
383
718
|
list List all indexed statutory sections
|
|
384
719
|
init-skill [path] Install SKILL.md into your agent workspace (defaults to .agents/skills/)
|
|
385
720
|
help Show this help message
|
|
721
|
+
|
|
722
|
+
Options:
|
|
723
|
+
--credit <YYYY-MM-DD> Date of credit to vendor/payee account in books (used in crosswalk)
|
|
724
|
+
--payment <YYYY-MM-DD> Date of actual payment/disbursement (used in crosswalk)
|
|
725
|
+
--since <YYYY-MM-DD> Filter amendments taking effect on or after date (used in diff)
|
|
726
|
+
--section, -s <section> Filter amendments by section code (used in diff)
|
|
727
|
+
--domain <domain> Filter amendments by statutory domain (used in diff)
|
|
728
|
+
--json, -j Emit clean, machine-parseable JSON to stdout (suppresses banners)
|
|
729
|
+
--offline, -o Bypass outbound network checks (air-gapped / offline environment mode)
|
|
730
|
+
|
|
731
|
+
Exit Code Conventions:
|
|
732
|
+
0 Success / Verification passed
|
|
733
|
+
1 Usage or operational error (invalid syntax / parameters)
|
|
734
|
+
2 Cryptographic authenticity or integrity violation (mismatch/revocation)
|
|
735
|
+
3 Statutory policy violation (e.g. missing baseline provision)
|
|
386
736
|
`);
|
|
387
737
|
}
|
|
388
738
|
|
package/docs/CORPUS_QUALITY.md
CHANGED
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
> **Format Reference**: Inspired by Google's *Data Cards Playbook* and the OpenSSF Project Quality Standards.
|
|
4
4
|
> **Target Package**: `@mudraforge/statutory` v2.4.0
|
|
5
5
|
> **Evaluation Mode**: Machine-audited against primary sources, official gazettes, and test fixtures.
|
|
6
|
-
> **Generated Timestamp**: 2026-10-
|
|
6
|
+
> **Generated Timestamp**: 2026-10-25T14:51:51.929Z
|
|
7
7
|
|
|
8
8
|
---
|
|
9
9
|
|
|
@@ -11,11 +11,11 @@
|
|
|
11
11
|
|
|
12
12
|
| Dimension | Metric | Denominator / Baseline | Coverage Rate | Status |
|
|
13
13
|
| :--- | :--- | :--- | :--- | :--- |
|
|
14
|
-
| **Primary Source Citations** |
|
|
15
|
-
| **Temporal Validity Bounds** |
|
|
16
|
-
| **Dual-Act 2025 Transition Bridges** |
|
|
17
|
-
| **Attached Administrative Circulars** |
|
|
18
|
-
| **Attached Return/Compliance Schemas** |
|
|
14
|
+
| **Primary Source Citations** | 61 resolvable gazette URLs | 61 total citations declared | **100.0%** | VERIFIED |
|
|
15
|
+
| **Temporal Validity Bounds** | 24 sections with explicit dates | 24 total bundled sections | **100.0%** | VERIFIED |
|
|
16
|
+
| **Dual-Act 2025 Transition Bridges** | 8 direct tax provisions mapped | 9 direct tax provisions | **88.9%** | VERIFIED |
|
|
17
|
+
| **Attached Administrative Circulars** | 25 official circulars | 6 sections across 4 domains | **100% Attached** | VERIFIED |
|
|
18
|
+
| **Attached Return/Compliance Schemas** | 22 schemas/templates | 6 sections across 4 domains | **100% Attached** | VERIFIED |
|
|
19
19
|
| **Cryptographic Merkle Verification** | 20 bundle files verified | SHA-256 Merkle root digest | **0 Mismatches** | VERIFIED |
|
|
20
20
|
|
|
21
21
|
---
|
|
@@ -49,16 +49,29 @@
|
|
|
49
49
|
| Section Code | Statutory Provision | Governing Statute | Temporal Window | Status | Citations | Circulars | Forms | 2025 Act Successor |
|
|
50
50
|
| :--- | :--- | :--- | :--- | :--- | :--- | :--- | :--- | :--- |
|
|
51
51
|
| **50B** | Special provision for computation of capital gains in case of slump sale | Income-tax Act, 1961 (Act No. 43 of 1961) | `2000-04-01` to `OPEN_ENDED` | `ACTIVE` | 3 | 2 | 2 | Income-tax Act, 2025 (Section 78 (Capital gains on slump sale of undertakings)) |
|
|
52
|
+
| **206AB** | Special provision for deduction of tax at source for non-filers of income-tax return | Income-tax Act, 1961 (Act No. 43 of 1961) | `2021-07-01` to `OPEN_ENDED` | `ACTIVE` | 1 | 1 | 0 | Income-tax Act, 2025 (Section 397(3)) |
|
|
52
53
|
| **206C(1H)** | Collection of tax at source by seller on receipt of consideration for sale of goods (Omitted effective 1 April 2025) | Income-tax Act, 1961 | `2020-10-01` to `2025-03-31` | `SUNSET_SUPERSEDED` | 2 | 1 | 0 | Finance Act, 2025 (Statutory Sunset) (Section 206C(1H) Omitted) |
|
|
53
54
|
| **194H** | Deduction of tax at source on commission or brokerage | Income-tax Act, 1961 (Act No. 43 of 1961) | `2001-06-01` to `2026-03-31` | `SUNSET_SUPERSEDED` | 3 | 1 | 1 | Income-tax Act, 2025 (Section 393(1), Table 4, Item (i)) |
|
|
54
55
|
| **194C** | Deduction of tax at source on payments to contractors and sub-contractors | Income-tax Act, 1961 (Act No. 43 of 1961) | `1972-04-01` to `2026-03-31` | `SUNSET_SUPERSEDED` | 3 | 1 | 2 | Income-tax Act, 2025 (Section 393(1), Table 3, Item (i)) |
|
|
55
56
|
| **194Q** | Deduction of tax at source on payment of a certain sum for purchase of goods | Income-tax Act, 1961 (Act No. 43 of 1961) | `2021-07-01` to `2026-03-31` | `SUNSET_SUPERSEDED` | 2 | 2 | 2 | Income-tax Act, 2025 (Section 393(1), Table 8, Item (ii)) |
|
|
56
57
|
| **393** | Deduction of tax at source on payment of a certain sum for purchase of goods | Income-tax Act, 2025 (Act No. 1 of 2025) | `2026-04-01` to `OPEN_ENDED` | `ACTIVE` | 3 | 0 | 0 | N/A |
|
|
58
|
+
| **194R** | Deduction of tax at source on benefit or perquisite in respect of business or profession | Income-tax Act, 1961 (Act No. 43 of 1961) | `2022-07-01` to `OPEN_ENDED` | `ACTIVE` | 2 | 1 | 0 | Income-tax Act, 2025 (Section 393(1), Table 8, Item 12) |
|
|
57
59
|
| **194I** | Deduction of tax at source on payment of rent | Income-tax Act, 1961 (Act No. 43 of 1961) | `1994-06-01` to `2026-03-31` | `SUNSET_SUPERSEDED` | 3 | 1 | 1 | Income-tax Act, 2025 (Section 393(1), Table 5, Item (i)) |
|
|
58
60
|
| **194J** | Fees for professional or technical services, royalty, and non-compete fees | Income-tax Act, 1961 | `1995-07-01` to `2026-03-31` | `SUNSET_SUPERSEDED` | 2 | 1 | 1 | Income-tax Act, 2025 (Section 393(1), Table 6, Item (iii)) |
|
|
59
61
|
| **17(5)** | Apportionment of credit and blocked input tax credits | Central Goods and Services Tax Act, 2017 (Act No. 12 of 2017) | `2017-07-01` to `OPEN_ENDED` | `ACTIVE` | 3 | 1 | 1 | CGST Act, 2017 (In force) (Section 17(5)(b)(i) & (b)(iii)) |
|
|
62
|
+
| **8** | Tax liability on composite and mixed supplies and classification of bundled goods and services contracts | Central Goods and Services Tax Act, 2017 | `2017-07-01` to `OPEN_ENDED` | `ACTIVE` | 3 | 1 | 1 | N/A |
|
|
63
|
+
| **10** | Composition levy and ineligible tax invoice restrictions | Central Goods and Services Tax Act, 2017 (Act No. 12 of 2017) | `2017-07-01` to `OPEN_ENDED` | `ACTIVE` | 2 | 1 | 0 | N/A |
|
|
64
|
+
| **34** | Credit and debit notes statutory adjustments and return filing deadlines | Central Goods and Services Tax Act, 2017 (Act No. 12 of 2017) | `2017-07-01` to `OPEN_ENDED` | `ACTIVE` | 2 | 1 | 0 | N/A |
|
|
65
|
+
| **RULE-48(4)** | Mandatory electronic invoicing (E-Invoicing), IRN generation, and invoice validity | Central Goods and Services Tax Rules, 2017 | `2020-10-01` to `OPEN_ENDED` | `ACTIVE` | 2 | 1 | 0 | N/A |
|
|
66
|
+
| **51** | Tax deduction at source under Goods and Services Tax | Central Goods and Services Tax Act, 2017 (Act No. 12 of 2017) | `2018-10-01` to `OPEN_ENDED` | `ACTIVE` | 2 | 1 | 0 | N/A |
|
|
67
|
+
| **16(2)** | Eligibility and conditions for taking input tax credit and mandatory 180-day payment rule | Central Goods and Services Tax Act, 2017 (Act No. 12 of 2017) | `2017-07-01` to `OPEN_ENDED` | `ACTIVE` | 4 | 1 | 1 | CGST Act, 2017 (In force) (Section 16(2), (3), (4), (5), (6)) |
|
|
68
|
+
| **9(3)** | Reverse Charge Mechanism (RCM) mandatory tax liability on recipient, self-invoicing, payment voucher issuance, and electronic cash discharge | Central Goods and Services Tax Act, 2017 read with Notification No. 13/2017-Central Tax (Rate) | `2017-07-01` to `OPEN_ENDED` | `ACTIVE` | 3 | 1 | 1 | N/A |
|
|
69
|
+
| **195** | Deduction of tax at source on foreign cross-border payments to non-residents, DTAA treaty benefits, documentation, Form 15CA/15CB, and cloud software exemption | Income-tax Act, 1961 read with Double Taxation Avoidance Agreements (DTAA) under Section 90 | `1962-04-01` to `OPEN_ENDED` | `ACTIVE` | 3 | 2 | 1 | Income-tax Act, 2025 Section 393(2) (Section 393(2) of Income-tax Act, 2025) |
|
|
60
70
|
| **IRC-901-904** | Foreign Tax Credit authorization, separate basket limitation, and partnership pass-through reporting (Form 1116 / Schedule K-3) | Internal Revenue Code of 1986 (Title 26, U.S. Code) | `2021-01-01` to `OPEN_ENDED` | `ACTIVE` | 2 | 0 | 2 | Title 26, U.S. Code (Continuous) (26 U.S.C. §§ 901, 904(d), 904(j), 469) |
|
|
61
71
|
| **MSMED-15-16** | Statutory payment timelines to Micro & Small Enterprises, compound penal interest, and income tax deduction disallowance | Micro, Small and Medium Enterprises Development Act, 2006 read with Income-tax Act, 1961 Section 43B(h) | `2006-10-02` to `OPEN_ENDED` | `ACTIVE` | 4 | 1 | 2 | Income-tax Act, 2025 Section 37(2)(g) (Section 37(2)(g) of Income-tax Act, 2025) |
|
|
72
|
+
| **MSMED-SEC-7** | Composite criteria for classification of Micro, Small and Medium Enterprises, investment calculations, and statutory exclusion of export turnover | Micro, Small and Medium Enterprises Development Act, 2006 read with Ministry of MSME Notification S.O. 2119(E) | `2020-07-01` to `OPEN_ENDED` | `ACTIVE` | 2 | 1 | 1 | N/A |
|
|
73
|
+
| **MCA-MSME-1** | Mandatory half-yearly reporting of outstanding dues exceeding 45 days to Micro & Small Enterprises (Form MSME-1) | Companies Act, 2013 read with Specified Companies (Furnishing of information about payment to micro and small enterprise suppliers) Order, 2019 | `2019-01-22` to `OPEN_ENDED` | `ACTIVE` | 2 | 1 | 1 | N/A |
|
|
74
|
+
| **MSMED-SEC-22** | Mandatory statutory disclosures in annual audited financial statements regarding dues to Micro and Small Enterprises and tax non-deductibility of penal interest | Micro, Small and Medium Enterprises Development Act, 2006 read with Companies Act, 2013 Schedule III | `2006-10-02` to `OPEN_ENDED` | `ACTIVE` | 3 | 1 | 2 | N/A |
|
|
62
75
|
|
|
63
76
|
---
|
|
64
77
|
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
# Published Release & Provenance Ledger
|
|
2
|
+
|
|
3
|
+
This document records the cryptographic provenance, normative specifications, and formal assurance artifacts for `@mudraforge/statutory`.
|
|
4
|
+
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
## Release Baseline Ledger
|
|
8
|
+
|
|
9
|
+
| Item | Value |
|
|
10
|
+
|---|---|
|
|
11
|
+
| **Package Release** | **`v2.8.0`** (Stable Minor Release) |
|
|
12
|
+
| **Knowledge Specification** | **Google Open Knowledge Format (OKF v0.2) + MudraForge Statutory Schema Extension** |
|
|
13
|
+
| **Regulatory Snapshot** | **CBDT / CBIC / MCA / MSME Baseline: October 2026** |
|
|
14
|
+
| **Corpus Quality Card** | 100% Citation Resolution (15/15 URLs) in [`docs/CORPUS_QUALITY.md`](./CORPUS_QUALITY.md) |
|
|
15
|
+
| **Architecture Decision Records** | 6 Normative ADRs documented in [`docs/ARCHITECTURE_DECISIONS.md`](./ARCHITECTURE_DECISIONS.md) |
|
|
16
|
+
| **Vendor Conformance Suite** | 12/12 Passing Fixture Tests in [`conformance/`](../conformance/) |
|
|
17
|
+
| **End-to-End Execution Trace** | Audited 7-stage AP lifecycle in [`examples/`](../examples/) (`npm run example:trace`) |
|
|
18
|
+
| **Enterprise Assurance Preview** | Formal TLA+ & mutation defenses in [`docs/ADESHA_ASSURANCE_OVERVIEW.md`](./ADESHA_ASSURANCE_OVERVIEW.md) |
|
|
19
|
+
| **Integrity Root** | SHA-256 root manifest in [`okf/manifest.json`](../okf/manifest.json) (reproducible byte-level non-tampering proof) |
|
|
20
|
+
| **Temporal Framework** | Dual-Act Bridge: *Income-tax Act, 1961* & *Income-tax Act, 2025* |
|
|
21
|
+
| **Verification Gate** | 100% Pass across cumulative thresholds, legislative sunsets, and excess math |
|
|
22
|
+
|
|
23
|
+
---
|
|
24
|
+
|
|
25
|
+
## Cryptographic & Epistemic Scope
|
|
26
|
+
|
|
27
|
+
The SHA-256 root hash in `okf/manifest.json` provides mathematical verification of **byte-level integrity** (ensuring local files have not been corrupted, altered, or partially written). A hash certifies that bytes match the published release; it does not by itself constitute legal or statutory authority.
|
|
28
|
+
|
|
29
|
+
Epistemic authority is established strictly via:
|
|
30
|
+
1. Primary gazette citations and statutory text enacted by Parliament.
|
|
31
|
+
2. Executive circulars and notifications issued by the CBDT, CBIC, MCA, and Ministry of MSME.
|
|
32
|
+
3. Cryptographic Ed25519 signatures anchored to the MudraForge Root Authority.
|
|
33
|
+
4. Independent legal ground-truth test suites parameterizing effective dates and cumulative turnover thresholds.
|
package/okf/manifest.json
CHANGED
package/okf.publication.json
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
"$schema": "https://okf.dev/schema/v0.2/publication.json",
|
|
3
3
|
"publicationId": "mudraforge-statutory-commons",
|
|
4
4
|
"title": "MudraForge Statutory Knowledge Substrate (India & Cross-Border)",
|
|
5
|
-
"version": "2.
|
|
5
|
+
"version": "2.8.0",
|
|
6
6
|
"lifecycle": "PUBLIC_BETA",
|
|
7
7
|
"specification": "OKF-0.2",
|
|
8
8
|
"publisher": {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@mudraforge/statutory",
|
|
3
|
-
"version": "2.
|
|
3
|
+
"version": "2.8.0",
|
|
4
4
|
"description": "Open Knowledge Format (OKF) client & AI Agent Skill for Indian and cross-border statutory tax provisions. Zero dependencies.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "src/index.js",
|
|
@@ -33,7 +33,8 @@
|
|
|
33
33
|
"example:trace": "node examples/simulate_end_to_end_trace.js",
|
|
34
34
|
"manifest": "node scripts/generate_manifest.js",
|
|
35
35
|
"manifest:check": "node scripts/generate_manifest.js --check",
|
|
36
|
-
"catalog": "node scripts/build_catalog.js"
|
|
36
|
+
"catalog": "node scripts/build_catalog.js",
|
|
37
|
+
"release": "node scripts/release.js"
|
|
37
38
|
},
|
|
38
39
|
"repository": {
|
|
39
40
|
"type": "git",
|