@mudraforge/statutory 2.8.1 → 2.10.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 +49 -0
- package/README.md +112 -130
- package/SECURITY.md +2 -2
- package/SKILL.md +7 -2
- package/bin/cli.js +215 -8
- package/calculators.d.ts +1 -0
- package/calculators.js +1 -0
- package/docs/ARCHITECTURE.md +8 -8
- package/docs/ARCHITECTURE_DECISIONS.md +4 -3
- package/docs/CATALOG.md +259 -64
- package/docs/CORPUS_QUALITY.md +14 -9
- package/docs/DOMAIN_BREADTH_AND_DEPTH_COMPARISON.md +1 -1
- package/docs/ENTERPRISE_GOVERNANCE.md +81 -22
- package/docs/PILOT_EVALUATION_GUIDE.md +155 -90
- package/docs/PROVENANCE.md +4 -4
- package/docs/VERIFICATION.md +7 -7
- package/okf/corporate_ma_restructuring/loss_carryforward_sec79/circulars/cbdt_circular_09_2020_startup_loss_continuity.md +37 -0
- package/okf/corporate_ma_restructuring/loss_carryforward_sec79/forms/section_79_shareholding_continuity_schedule.json +51 -0
- package/okf/corporate_ma_restructuring/loss_carryforward_sec79/section.json +66 -0
- package/okf/direct_tax/corporate_tax_115baa_115jb/circulars/cbdt_circular_29_2019_concessional_tax_regime.md +35 -0
- package/okf/direct_tax/corporate_tax_115baa_115jb/forms/form_10ic_concessional_tax_election.json +31 -0
- package/okf/direct_tax/corporate_tax_115baa_115jb/section.json +72 -0
- package/okf/direct_tax/special_rates_non_filer_206ab/section.json +7 -6
- package/okf/indirect_tax_gst/export_services_lut_sec16/circulars/cbic_circular_161_2021_intermediary_clarification.md +37 -0
- package/okf/indirect_tax_gst/export_services_lut_sec16/forms/lut_form_gst_rfnd_11_declaration.json +58 -0
- package/okf/indirect_tax_gst/export_services_lut_sec16/section.json +66 -0
- package/okf/international_tax/foreign_exchange_indas_21_109/circulars/mca_indas_21_foreign_exchange_rates.md +39 -0
- package/okf/international_tax/foreign_exchange_indas_21_109/forms/indas_109_cash_flow_hedge_reserve_schedule.json +45 -0
- package/okf/international_tax/foreign_exchange_indas_21_109/section.json +63 -0
- package/okf/international_tax/transfer_pricing_alp_92c/circulars/cbdt_notification_86_2015_range_concept_rule_10ca.md +54 -0
- package/okf/international_tax/transfer_pricing_alp_92c/forms/form_3ceb_transfer_pricing_report.json +67 -0
- package/okf/international_tax/transfer_pricing_alp_92c/section.json +72 -0
- package/okf/manifest.json +33 -8
- package/package.json +48 -1
- package/src/calculators.js +780 -0
- package/src/constants.js +10 -0
- package/src/index.js +235 -46
- package/src/outcomes.js +483 -0
- package/types/index.d.ts +69 -0
package/bin/cli.js
CHANGED
|
@@ -22,6 +22,9 @@ import {
|
|
|
22
22
|
runStatutoryDoctor,
|
|
23
23
|
crosswalkStatute,
|
|
24
24
|
getStatutoryDiff,
|
|
25
|
+
getStatutoryOutcomes,
|
|
26
|
+
explainStatutoryDisposition,
|
|
27
|
+
ignorePackageUpdate,
|
|
25
28
|
STATUTORY_EXIT_CODES,
|
|
26
29
|
STATUTORY_CLIENT_VERSION,
|
|
27
30
|
DEFAULT_LOCAL_OKF_DIR
|
|
@@ -33,7 +36,14 @@ const __dirname = path.dirname(__filename);
|
|
|
33
36
|
const rawArgs = process.argv.slice(2);
|
|
34
37
|
const isJsonMode = rawArgs.includes('--json') || rawArgs.includes('-j');
|
|
35
38
|
const isOfflineMode = rawArgs.includes('--offline') || rawArgs.includes('-o');
|
|
36
|
-
const
|
|
39
|
+
const isVerboseMode = rawArgs.includes('--verbose') || rawArgs.includes('-v');
|
|
40
|
+
const isNoUpdateCheck = rawArgs.includes('--no-update-check') || rawArgs.includes('--ignore-update');
|
|
41
|
+
const args = rawArgs.filter(a =>
|
|
42
|
+
a !== '--json' && a !== '-j' &&
|
|
43
|
+
a !== '--offline' && a !== '-o' &&
|
|
44
|
+
a !== '--verbose' && a !== '-v' &&
|
|
45
|
+
a !== '--no-update-check' && a !== '--ignore-update'
|
|
46
|
+
);
|
|
37
47
|
const command = args[0] ? args[0].toLowerCase() : 'help';
|
|
38
48
|
|
|
39
49
|
function getNamedArg(nameList, argList) {
|
|
@@ -89,6 +99,26 @@ async function main() {
|
|
|
89
99
|
break;
|
|
90
100
|
}
|
|
91
101
|
|
|
102
|
+
case 'outcomes':
|
|
103
|
+
case 'dispositions':
|
|
104
|
+
case 'states': {
|
|
105
|
+
const section = (args[1] && !args[1].startsWith('-')) ? args[1] : getNamedArg(['--provision', '-p', '--section', '-s'], rawArgs);
|
|
106
|
+
await handleOutcomes(section, { offline: isOfflineMode, verbose: isVerboseMode });
|
|
107
|
+
break;
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
case 'explain':
|
|
111
|
+
case 'why':
|
|
112
|
+
case 'remedy': {
|
|
113
|
+
const query = (args[1] && !args[1].startsWith('-')) ? args[1] : getNamedArg(['--code', '-c', '--query', '-q'], rawArgs);
|
|
114
|
+
if (!query) {
|
|
115
|
+
console.error('[ERROR] Please specify a disposition code or status to explain, e.g. npx @mudraforge/statutory explain BUYER_TURNOVER_UNVERIFIED');
|
|
116
|
+
process.exit(STATUTORY_EXIT_CODES.USAGE_ERROR);
|
|
117
|
+
}
|
|
118
|
+
await handleExplain(query);
|
|
119
|
+
break;
|
|
120
|
+
}
|
|
121
|
+
|
|
92
122
|
case 'init-skill':
|
|
93
123
|
case 'install-skill':
|
|
94
124
|
await handleInitSkill(args[1]);
|
|
@@ -96,9 +126,11 @@ async function main() {
|
|
|
96
126
|
|
|
97
127
|
case 'check-update':
|
|
98
128
|
case 'status':
|
|
99
|
-
case 'version':
|
|
100
|
-
|
|
129
|
+
case 'version': {
|
|
130
|
+
const shouldIgnore = rawArgs.includes('--ignore') || args[1] === '--ignore' || args[1] === 'ignore';
|
|
131
|
+
await handleCheckUpdate({ ignore: shouldIgnore });
|
|
101
132
|
break;
|
|
133
|
+
}
|
|
102
134
|
|
|
103
135
|
case 'sync':
|
|
104
136
|
case 'pull':
|
|
@@ -149,13 +181,14 @@ async function main() {
|
|
|
149
181
|
}
|
|
150
182
|
|
|
151
183
|
// Non-intrusive background npm package update notice
|
|
152
|
-
if (!isJsonMode && !
|
|
184
|
+
if (!isJsonMode && !isNoUpdateCheck && command !== 'check-update' && command !== 'status' && command !== 'version') {
|
|
153
185
|
try {
|
|
154
186
|
const updateInfo = await checkForPackageUpdate();
|
|
155
187
|
if (updateInfo && updateInfo.updateAvailable) {
|
|
156
188
|
console.log('───────────────────────────────────────────────────────────────────────────');
|
|
157
189
|
console.log(`[NOTICE] A new version of @mudraforge/statutory is available: ${updateInfo.currentVersion} -> ${updateInfo.latestVersion}`);
|
|
158
190
|
console.log(`Run: npm install @mudraforge/statutory@latest or npx @mudraforge/statutory@latest`);
|
|
191
|
+
console.log(`To dismiss: npx @mudraforge/statutory check-update --ignore`);
|
|
159
192
|
console.log('───────────────────────────────────────────────────────────────────────────\n');
|
|
160
193
|
}
|
|
161
194
|
} catch (_) {}
|
|
@@ -384,14 +417,182 @@ async function handleDiff(options) {
|
|
|
384
417
|
}
|
|
385
418
|
}
|
|
386
419
|
|
|
387
|
-
async function
|
|
420
|
+
async function handleOutcomes(provision, options = {}) {
|
|
421
|
+
try {
|
|
422
|
+
const result = await getStatutoryOutcomes(provision, options);
|
|
423
|
+
if (isJsonMode) {
|
|
424
|
+
console.log(JSON.stringify(result, null, 2));
|
|
425
|
+
process.exit(0);
|
|
426
|
+
}
|
|
427
|
+
|
|
428
|
+
console.log('\n===========================================================================');
|
|
429
|
+
console.log('MUDRAFORGE STATUTORY OUTCOMES & SEMANTIC DISPOSITION DICTIONARY');
|
|
430
|
+
console.log('===========================================================================');
|
|
431
|
+
console.log(`Source: ${result.source} ${result.offlineFallback ? '(Offline Fallback)' : ''}`);
|
|
432
|
+
console.log(`Version: v${result.version}`);
|
|
433
|
+
console.log(`Provision Filter: ${result.provision || 'ALL (Global Catalog)'}`);
|
|
434
|
+
console.log(`Total Outcomes: ${result.totalOutcomes}`);
|
|
435
|
+
console.log('===========================================================================');
|
|
436
|
+
|
|
437
|
+
if (result.outcomes.length === 0) {
|
|
438
|
+
console.log(`\nNo specific outcome codes mapped for provision "${result.provision}".`);
|
|
439
|
+
console.log('Showing all global disposition outcomes: run npx @mudraforge/statutory outcomes\n');
|
|
440
|
+
} else {
|
|
441
|
+
result.outcomes.forEach((o, idx) => {
|
|
442
|
+
console.log(`\n── Outcome #${idx + 1}: [${o.code}] ──`);
|
|
443
|
+
console.log(`Title: ${o.title}`);
|
|
444
|
+
console.log(`Category: ${o.category}`);
|
|
445
|
+
console.log(`Description: ${o.description}`);
|
|
446
|
+
console.log(`Trigger Condition: ${o.triggerCondition}`);
|
|
447
|
+
console.log(`Recommended Action: ${o.recommendedAction}`);
|
|
448
|
+
if (options.verbose && o.remedy) {
|
|
449
|
+
console.log(`Resolution Steps: ${o.remedy}`);
|
|
450
|
+
}
|
|
451
|
+
if (o.missingFacts && o.missingFacts.length > 0) {
|
|
452
|
+
console.log(`Missing Facts to Cure: ${o.missingFacts.join(', ')}`);
|
|
453
|
+
if (options.verbose && o.missingFactsExplanation) {
|
|
454
|
+
for (const [key, detail] of Object.entries(o.missingFactsExplanation)) {
|
|
455
|
+
console.log(` ↳ ${key} (${detail.type}): ${detail.description} (Source: ${detail.source})`);
|
|
456
|
+
}
|
|
457
|
+
}
|
|
458
|
+
}
|
|
459
|
+
if (options.verbose && o.consequenceIfUnresolved) {
|
|
460
|
+
console.log(`Consequence on Hold: ${o.consequenceIfUnresolved}`);
|
|
461
|
+
}
|
|
462
|
+
if (o.applicableProvisions && o.applicableProvisions.length > 0) {
|
|
463
|
+
console.log(`Applies to Sections: ${o.applicableProvisions.join(', ')}`);
|
|
464
|
+
}
|
|
465
|
+
console.log(`Governing Law: ${o.governingAuthority}`);
|
|
466
|
+
});
|
|
467
|
+
}
|
|
468
|
+
|
|
469
|
+
console.log('\n───────────────────────────────────────────────────────────────────────────');
|
|
470
|
+
console.log(`[PASS] Statutory outcomes dictionary retrieved successfully (${result.totalOutcomes} outcome(s)) (Exit 0).\n`);
|
|
471
|
+
process.exit(0);
|
|
472
|
+
} catch (err) {
|
|
473
|
+
if (isJsonMode) {
|
|
474
|
+
console.log(JSON.stringify({ status: 'ERROR', exitCode: STATUTORY_EXIT_CODES.USAGE_ERROR, error: err.message }, null, 2));
|
|
475
|
+
} else {
|
|
476
|
+
console.error(`[ERROR] Statutory outcomes lookup failure: ${err.message}`);
|
|
477
|
+
}
|
|
478
|
+
process.exit(STATUTORY_EXIT_CODES.USAGE_ERROR);
|
|
479
|
+
}
|
|
480
|
+
}
|
|
481
|
+
|
|
482
|
+
async function handleExplain(query) {
|
|
483
|
+
try {
|
|
484
|
+
const result = explainStatutoryDisposition(query);
|
|
485
|
+
if (isJsonMode) {
|
|
486
|
+
console.log(JSON.stringify(result, null, 2));
|
|
487
|
+
process.exit(0);
|
|
488
|
+
}
|
|
489
|
+
|
|
490
|
+
console.log('\n===========================================================================');
|
|
491
|
+
console.log(`MUDRAFORGE STATUTORY EXPLANATION: [${result.query}]`);
|
|
492
|
+
console.log('===========================================================================');
|
|
493
|
+
|
|
494
|
+
if (result.status === 'NOT_FOUND') {
|
|
495
|
+
console.log(`\nNo statutory disposition or indeterminate code found matching "${result.query}".`);
|
|
496
|
+
if (result.availableCodes && result.availableCodes.length > 0) {
|
|
497
|
+
console.log('\nAvailable disposition codes to inspect:');
|
|
498
|
+
result.availableCodes.forEach(c => console.log(` • ${c}`));
|
|
499
|
+
}
|
|
500
|
+
console.log('\nTip: Run "npx @mudraforge/statutory explain INDETERMINATE" to view all hold states.\n');
|
|
501
|
+
process.exit(STATUTORY_EXIT_CODES.USAGE_ERROR);
|
|
502
|
+
}
|
|
503
|
+
|
|
504
|
+
if (result.summary) {
|
|
505
|
+
console.log(`Summary: ${result.summary}`);
|
|
506
|
+
console.log(`Matched Dispositions: ${result.totalMatches}\n`);
|
|
507
|
+
}
|
|
508
|
+
|
|
509
|
+
result.matches.forEach((o, idx) => {
|
|
510
|
+
if (result.matches.length > 1) {
|
|
511
|
+
console.log(`\n── [${idx + 1}/${result.matches.length}] Disposition: [${o.code}] ──`);
|
|
512
|
+
} else {
|
|
513
|
+
console.log(`Code: [${o.code}]`);
|
|
514
|
+
}
|
|
515
|
+
console.log(`Title: ${o.title}`);
|
|
516
|
+
console.log(`Category: ${o.category}`);
|
|
517
|
+
console.log(`Governing Law: ${o.governingAuthority}`);
|
|
518
|
+
console.log('\n── What Happened:');
|
|
519
|
+
console.log(` ${o.description}`);
|
|
520
|
+
console.log('\n── Statutory Trigger:');
|
|
521
|
+
console.log(` ${o.triggerCondition}`);
|
|
522
|
+
console.log('\n── How to Resolve in Your Application:');
|
|
523
|
+
console.log(` ${o.remedy || o.recommendedAction}`);
|
|
524
|
+
|
|
525
|
+
if (o.missingFacts && o.missingFacts.length > 0) {
|
|
526
|
+
console.log('\n── Missing Evidence / Parameters to Supply:');
|
|
527
|
+
o.missingFacts.forEach(f => {
|
|
528
|
+
const meta = o.missingFactsExplanation ? o.missingFactsExplanation[f] : null;
|
|
529
|
+
if (meta) {
|
|
530
|
+
console.log(` • ${f} (${meta.type}): ${meta.description}`);
|
|
531
|
+
console.log(` Source: ${meta.source} | Example: ${JSON.stringify(meta.example)}`);
|
|
532
|
+
} else {
|
|
533
|
+
console.log(` • ${f}`);
|
|
534
|
+
}
|
|
535
|
+
});
|
|
536
|
+
}
|
|
537
|
+
|
|
538
|
+
if (o.consequenceIfUnresolved) {
|
|
539
|
+
console.log('\n── Consequence If Unresolved:');
|
|
540
|
+
console.log(` ${o.consequenceIfUnresolved}`);
|
|
541
|
+
}
|
|
542
|
+
|
|
543
|
+
if (o.applicableProvisions && o.applicableProvisions.length > 0) {
|
|
544
|
+
console.log(`\nApplies to Sections: ${o.applicableProvisions.join(', ')}`);
|
|
545
|
+
}
|
|
546
|
+
});
|
|
547
|
+
|
|
548
|
+
console.log('\n───────────────────────────────────────────────────────────────────────────');
|
|
549
|
+
console.log(`[PASS] Statutory explanation completed successfully (Exit 0).\n`);
|
|
550
|
+
process.exit(0);
|
|
551
|
+
} catch (err) {
|
|
552
|
+
if (isJsonMode) {
|
|
553
|
+
console.log(JSON.stringify({ status: 'ERROR', exitCode: STATUTORY_EXIT_CODES.USAGE_ERROR, error: err.message }, null, 2));
|
|
554
|
+
} else {
|
|
555
|
+
console.error(`[ERROR] Statutory explain failure: ${err.message}`);
|
|
556
|
+
}
|
|
557
|
+
process.exit(STATUTORY_EXIT_CODES.USAGE_ERROR);
|
|
558
|
+
}
|
|
559
|
+
}
|
|
560
|
+
|
|
561
|
+
async function handleCheckUpdate(options = {}) {
|
|
388
562
|
try {
|
|
389
563
|
let pkgUpdate = null;
|
|
390
564
|
try {
|
|
391
|
-
pkgUpdate = await checkForPackageUpdate({ cacheTtlMs: 0 });
|
|
565
|
+
pkgUpdate = await checkForPackageUpdate({ cacheTtlMs: 0, force: Boolean(options.ignore) });
|
|
392
566
|
} catch (_) {}
|
|
393
567
|
|
|
394
|
-
|
|
568
|
+
if (options.ignore) {
|
|
569
|
+
const versionToIgnore = pkgUpdate?.latestVersion || STATUTORY_CLIENT_VERSION;
|
|
570
|
+
ignorePackageUpdate(versionToIgnore);
|
|
571
|
+
if (isJsonMode) {
|
|
572
|
+
console.log(JSON.stringify({ status: 'SUCCESS', ignoredVersion: versionToIgnore }, null, 2));
|
|
573
|
+
process.exit(0);
|
|
574
|
+
}
|
|
575
|
+
console.log('\n===========================================================================');
|
|
576
|
+
console.log(`[OK] Update notifications will be ignored for version ${versionToIgnore}.`);
|
|
577
|
+
console.log('You will not see update notices until a newer version is published.');
|
|
578
|
+
console.log('===========================================================================\n');
|
|
579
|
+
process.exit(0);
|
|
580
|
+
}
|
|
581
|
+
|
|
582
|
+
let status = null;
|
|
583
|
+
try {
|
|
584
|
+
status = await checkUpdates();
|
|
585
|
+
} catch (netErr) {
|
|
586
|
+
if (isJsonMode) {
|
|
587
|
+
console.log(JSON.stringify({ status: 'OFFLINE_FALLBACK', packageUpdate: pkgUpdate, error: netErr.message }, null, 2));
|
|
588
|
+
process.exit(0);
|
|
589
|
+
}
|
|
590
|
+
console.log('───────────────────────────────────────────────────────────────────────────');
|
|
591
|
+
console.log(`Local OKF Version: ${STATUTORY_CLIENT_VERSION}`);
|
|
592
|
+
console.log(`Edge Synchronization: UNAVAILABLE (offline or remote network unreachable)`);
|
|
593
|
+
console.log('───────────────────────────────────────────────────────────────────────────\n');
|
|
594
|
+
process.exit(0);
|
|
595
|
+
}
|
|
395
596
|
|
|
396
597
|
if (isJsonMode) {
|
|
397
598
|
console.log(JSON.stringify({
|
|
@@ -710,10 +911,12 @@ Commands:
|
|
|
710
911
|
verify [path] Cryptographically verify OKF substrate authenticity & file integrity
|
|
711
912
|
crosswalk <section> Dual-act 1961 <-> 2025 bridge (earlier of credit vs payment)
|
|
712
913
|
diff Semantic regulatory changelog (--section, --since, --domain)
|
|
914
|
+
outcomes [provision] Inspect API dispositions, statutory states, trigger conditions & actions
|
|
915
|
+
explain <code/status> In-depth explanation, legal rationale & remediation steps for a disposition
|
|
713
916
|
browse Interactively browse local OKF statutory filesystem
|
|
714
917
|
lookup <section> [date] Look up section details & temporal status (e.g. 194Q 2025-06-01)
|
|
715
918
|
decode-id <pan_or_gstin> Offline ISO Mod-36 checksum, state name, and PAN entity decoding
|
|
716
|
-
check-update
|
|
919
|
+
check-update [--ignore] Check edge updates; pass --ignore to snooze notices for current version
|
|
717
920
|
sync [path] Download/sync latest versioned OKF bundle to disk (default: package okf/ or custom dir)
|
|
718
921
|
list List all indexed statutory sections
|
|
719
922
|
init-skill [path] Install SKILL.md into your agent workspace (defaults to .agents/skills/)
|
|
@@ -725,6 +928,10 @@ Options:
|
|
|
725
928
|
--since <YYYY-MM-DD> Filter amendments taking effect on or after date (used in diff)
|
|
726
929
|
--section, -s <section> Filter amendments by section code (used in diff)
|
|
727
930
|
--domain <domain> Filter amendments by statutory domain (used in diff)
|
|
931
|
+
--verbose, -v Display full remediation steps, parameter schemas, and consequences in outcomes
|
|
932
|
+
--no-update-check Bypass automated background npm package update checks
|
|
933
|
+
--json, -j Emit clean, machine-parseable JSON to stdout (suppresses banners)
|
|
934
|
+
--offline, -o Bypass outbound network checks (air-gapped / offline environment mode)
|
|
728
935
|
--json, -j Emit clean, machine-parseable JSON to stdout (suppresses banners)
|
|
729
936
|
--offline, -o Bypass outbound network checks (air-gapped / offline environment mode)
|
|
730
937
|
|
package/calculators.d.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from './types/index.js';
|
package/calculators.js
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from './src/calculators.js';
|
package/docs/ARCHITECTURE.md
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
# MudraForge Statutory Architecture
|
|
2
2
|
## Grounding Financial AI in Deterministic Law & Open Knowledge
|
|
3
3
|
|
|
4
|
-
> **MudraForge Statutory Bundle**: `v2.
|
|
4
|
+
> **MudraForge Statutory Bundle**: `v2.9.0`
|
|
5
5
|
> **Knowledge Specification**: Google Open Knowledge Format (OKF) specification (upstream v0.2)
|
|
6
6
|
> **License**: MIT (Public Knowledge Commons)
|
|
7
7
|
> **Status**: Public Beta
|
|
@@ -592,10 +592,10 @@ Data traveling between tiers is encapsulated within a deterministic verification
|
|
|
592
592
|
|
|
593
593
|
```json
|
|
594
594
|
{
|
|
595
|
-
"protocolVersion": "okf/2.
|
|
595
|
+
"protocolVersion": "okf/2.9.0",
|
|
596
596
|
"domain": "direct_tax",
|
|
597
597
|
"sectionCode": "194Q",
|
|
598
|
-
"manifestDigest": "sha256-
|
|
598
|
+
"manifestDigest": "sha256-4bbe36c3db841b833dd2bebbd6c1c5ed735498e7b20d1221c323ceb211529fe0",
|
|
599
599
|
"effectiveTemporalStatus": "ACTIVE",
|
|
600
600
|
"canonicalParameters": {
|
|
601
601
|
"standardRatePercent": 0.1,
|
|
@@ -614,9 +614,9 @@ Data traveling between tiers is encapsulated within a deterministic verification
|
|
|
614
614
|
### 9.3 Edge Consistency & Eventual Consistency Resolution (Cloudflare KV)
|
|
615
615
|
|
|
616
616
|
Cloudflare Workers KV provides global low-latency reads via eventual consistency across edge nodes. To prevent release skew during regulatory updates:
|
|
617
|
-
1. *Immutable Version Tagging*: All statutory releases are written under unique semver namespaces (`statutory:releases:v2.
|
|
618
|
-
2. *Atomic Manifest Flip*: The global pointer `statutory:active_release` is updated only after all
|
|
619
|
-
3. *Cache-Control Invalidation*: Manifest responses carry strict validation headers (`ETag: "v2.
|
|
617
|
+
1. *Immutable Version Tagging*: All statutory releases are written under unique semver namespaces (`statutory:releases:v2.9.0:...`).
|
|
618
|
+
2. *Atomic Manifest Flip*: The global pointer `statutory:active_release` is updated only after all 86 files across all domains are fully confirmed across edge replicas.
|
|
619
|
+
3. *Cache-Control Invalidation*: Manifest responses carry strict validation headers (`ETag: "v2.9.0"`, `stale-while-revalidate=600`).
|
|
620
620
|
4. *Local Fallback*: If Tier 2 returns HTTP 5xx or fails DNS resolution, Tier 1 and Tier 3 automatically fall back to the bundled local filesystem snapshot without failing the active business transaction.
|
|
621
621
|
|
|
622
622
|
### 9.4 Architectural Boundaries: The Autonomous Coprocessor vs. Stateless Subsystems
|
|
@@ -733,10 +733,10 @@ To prevent version skew across regions, the edge runtime employs an **Immutable
|
|
|
733
733
|
1. **Immutable Artifact Keys**: Every section schema, circular, and form is stored under an immutable, version-tagged key:
|
|
734
734
|
```
|
|
735
735
|
statutory:releases:<semver>:<domain>:<section_code>
|
|
736
|
-
# Example: statutory:releases:v2.
|
|
736
|
+
# Example: statutory:releases:v2.9.0:direct_tax:194Q
|
|
737
737
|
```
|
|
738
738
|
Once written to KV, the bytes for a specific semver key are permanently immutable.
|
|
739
|
-
2. **Atomic Manifest Pointers**: Releases are indexed by a versioned root manifest (`statutory:manifests:v2.
|
|
739
|
+
2. **Atomic Manifest Pointers**: Releases are indexed by a versioned root manifest (`statutory:manifests:v2.9.0`). The active pointer is switched only after all constituent keys are fully populated.
|
|
740
740
|
3. **Cache Invalidation & ETag Gates**: The manifest endpoint serves HTTP `ETag` validators with short edge TTLs (`Cache-Control: public, max-age=60, s-maxage=300, stale-while-revalidate=600`). This ensures edge caches converge globally within minutes while allowing clients to detect release changes via deterministic SHA-256 root hash comparisons.
|
|
741
741
|
- **Commercial Boundary**: Only the automated, continuously maintained edge update stream, neural discovery search, and deep deterministic calculator engines require an Enterprise API subscription post-beta.
|
|
742
742
|
|
|
@@ -69,7 +69,7 @@ We establish three independent, non-interchangeable versioning dimensions:
|
|
|
69
69
|
| :--- | :--- | :--- | :--- |
|
|
70
70
|
| **`okfVersion`** | Knowledge Schema Structure | Incremented only when the JSON schema or metadata fields change (e.g., adding a required field). | `0.2.0` |
|
|
71
71
|
| **`corpusRelease`** | Legal Corpus Snapshot | Incremented when statutory provisions, rates, or circulars are updated or added. | `2026.04.1` |
|
|
72
|
-
| **`version`** (SemVer) | NPM Client SDK & CLI | Standard Semantic Versioning for the JavaScript library, CLI commands, and test runners. | `2.
|
|
72
|
+
| **`version`** (SemVer) | NPM Client SDK & CLI | Standard Semantic Versioning for the JavaScript library, CLI commands, and test runners. | `2.9.0` |
|
|
73
73
|
|
|
74
74
|
---
|
|
75
75
|
|
|
@@ -82,14 +82,15 @@ To maintain institutional credibility, public documentation must never blur the
|
|
|
82
82
|
|
|
83
83
|
| Subsystem / Capability | Architectural Layer | Operational Status | Availability / Access | Verification Evidence |
|
|
84
84
|
| :--- | :--- | :--- | :--- | :--- |
|
|
85
|
-
| **Bundled OKF Statutory Corpus (
|
|
85
|
+
| **Bundled OKF Statutory Corpus (29 Provisions across 5 Domains)** | Layer 1: Public Package | `PUBLIC_BUNDLED` | Immediate (Local repo & release candidate) | 80/80 test suites passing; SHA-256 Merkle root verified |
|
|
86
86
|
| **Zero-Network CLI (`mudraforge-statutory`)** | Layer 1: Public Package | `PUBLIC_BUNDLED` | Immediate (Global / NPX) | `bin/cli.js` verified across Windows & Linux |
|
|
87
87
|
| **Vendor-Neutral Conformance Suite** | Layer 1: Public Package | `PUBLIC_BUNDLED` | Immediate (`conformance/`) | 12/12 fixture tests passing |
|
|
88
88
|
| **Local Query SDK (`src/index.js`)** | Layer 1: Public Package | `PUBLIC_BUNDLED` | Immediate (Node.js v18+) | Zero-dependency offline lookup and temporal checks |
|
|
89
89
|
| **Synthetic AP Execution Trace (`examples/`)** | Layer 1: Public Package | `PUBLIC_DEMO_SYNTHETIC` | Immediate (`npm run example:trace`) | Modeled 7-stage lifecycle with synthetic test fixtures |
|
|
90
90
|
| **Cloudflare Anycast Edge Sync** | Layer 2: Public Edge Service | `PUBLIC_EDGE_SYNC` | Free Beta (`api.mudraforge.in`) | Cloudflare Edge Worker manifest & bundle endpoints |
|
|
91
91
|
| **Interactive API Documentation** | Layer 2: Public Edge Service | `PUBLIC_EDGE_SYNC` | Free Beta (`/api/v1/statutory/docs`) | OpenAPI 3.1 schema rendered live on Anycast edge |
|
|
92
|
-
| **Deterministic
|
|
92
|
+
| **Deterministic Calculators (7 Pure Functions)** | Layer 1: Public Package | `PUBLIC_BUNDLED` | Immediate (`@mudraforge/statutory/calculators`) | Corporate tax MAT vs concessional, GST POS/LUT, TP ALP, Section 79, Ind AS 109, Section 288B |
|
|
93
|
+
| **Hosted AP Engine & Cumulative Spend Tracking** | Layer 3: Enterprise Internal | `PILOT_STAGE_INTERNAL` | Metered Enterprise API (Selective) | Hosted cumulative Section 194Q thresholding & Section 16 MSMED interest |
|
|
93
94
|
| **Dual-Custody Mobile Approval Harness** | Layer 4: Adesha Runtime | `INTERNAL_PROTOTYPE` | Enterprise License / Pilot Proposal | Mobile passkey approval prototype & TLA+ state machine |
|
|
94
95
|
| **ERP Two-Way Connectors (SAP/Tally/Zoho)** | Layer 4: Adesha Runtime | `INTERNAL_DEVELOPMENT` | Custom Enterprise Pilot | Shadow-mode test connectors; no turnkey plug-ins shipped |
|
|
95
96
|
| **Bank Rail API Adapters (ICICI/HDFC/RazorpayX)**| Layer 4: Adesha Runtime | `INTERNAL_DEVELOPMENT` | Custom Enterprise Pilot | Sandbox banking adapters requiring corporate partner onboarding |
|