@plures/praxis 1.2.0 → 1.2.10
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/README.md +10 -96
- package/dist/browser/{adapter-TM4IS5KT.js → adapter-CIMBGDC7.js} +5 -3
- package/dist/browser/{chunk-LE2ZJYFC.js → chunk-K377RW4V.js} +76 -0
- package/dist/{node/chunk-JQ64KMLN.js → browser/chunk-MBVHLOU2.js} +12 -1
- package/dist/browser/index.d.ts +32 -5
- package/dist/browser/index.js +15 -7
- package/dist/browser/integrations/svelte.d.ts +2 -2
- package/dist/browser/integrations/svelte.js +1 -1
- package/dist/browser/{reactive-engine.svelte-C9OpcTHf.d.ts → reactive-engine.svelte-9aS0kTa8.d.ts} +136 -1
- package/dist/node/{adapter-K6DOX6XS.js → adapter-75ISSMWD.js} +5 -3
- package/dist/node/chunk-5RH7UAQC.js +486 -0
- package/dist/{browser/chunk-JQ64KMLN.js → node/chunk-MBVHLOU2.js} +12 -1
- package/dist/node/{chunk-LE2ZJYFC.js → chunk-PRPQO6R5.js} +3 -72
- package/dist/node/chunk-R2PSBPKQ.js +150 -0
- package/dist/node/chunk-WZ6B3LZ6.js +638 -0
- package/dist/node/cli/index.cjs +2316 -832
- package/dist/node/cli/index.js +18 -0
- package/dist/node/components/index.d.cts +3 -2
- package/dist/node/components/index.d.ts +3 -2
- package/dist/node/index.cjs +620 -38
- package/dist/node/index.d.cts +259 -5
- package/dist/node/index.d.ts +259 -5
- package/dist/node/index.js +55 -65
- package/dist/node/integrations/svelte.cjs +76 -0
- package/dist/node/integrations/svelte.d.cts +2 -2
- package/dist/node/integrations/svelte.d.ts +2 -2
- package/dist/node/integrations/svelte.js +2 -1
- package/dist/node/{reactive-engine.svelte-1M4m_C_v.d.cts → reactive-engine.svelte-BFIZfawz.d.cts} +199 -1
- package/dist/node/{reactive-engine.svelte-ChNFn4Hj.d.ts → reactive-engine.svelte-CRNqHlbv.d.ts} +199 -1
- package/dist/node/reverse-W7THPV45.js +193 -0
- package/dist/node/{terminal-adapter-CWka-yL8.d.ts → terminal-adapter-B-UK_Vdz.d.ts} +28 -3
- package/dist/node/{terminal-adapter-CDzxoLKR.d.cts → terminal-adapter-BQSIF5bf.d.cts} +28 -3
- package/dist/node/validate-CNHUULQE.js +180 -0
- package/docs/core/pluresdb-integration.md +15 -15
- package/docs/decision-ledger/BEHAVIOR_LEDGER.md +225 -0
- package/docs/decision-ledger/DecisionLedger.tla +180 -0
- package/docs/decision-ledger/IMPLEMENTATION_SUMMARY.md +217 -0
- package/docs/decision-ledger/LATEST.md +166 -0
- package/docs/guides/cicd-pipeline.md +142 -0
- package/package.json +2 -2
- package/src/__tests__/cli-validate.test.ts +197 -0
- package/src/__tests__/decision-ledger.test.ts +485 -0
- package/src/__tests__/reverse-generator.test.ts +189 -0
- package/src/__tests__/scanner.test.ts +215 -0
- package/src/cli/commands/reverse.ts +289 -0
- package/src/cli/commands/validate.ts +264 -0
- package/src/cli/index.ts +47 -0
- package/src/core/pluresdb/adapter.ts +45 -2
- package/src/core/rules.ts +133 -0
- package/src/decision-ledger/README.md +400 -0
- package/src/decision-ledger/REVERSE_ENGINEERING.md +484 -0
- package/src/decision-ledger/facts-events.ts +121 -0
- package/src/decision-ledger/index.ts +70 -0
- package/src/decision-ledger/ledger.ts +246 -0
- package/src/decision-ledger/logic-ledger.ts +158 -0
- package/src/decision-ledger/reverse-generator.ts +426 -0
- package/src/decision-ledger/scanner.ts +506 -0
- package/src/decision-ledger/types.ts +247 -0
- package/src/decision-ledger/validation.ts +336 -0
- package/src/dsl/index.ts +13 -2
- package/src/index.browser.ts +2 -0
- package/src/index.ts +36 -0
- package/src/integrations/pluresdb.ts +14 -2
package/dist/node/index.js
CHANGED
|
@@ -1,9 +1,39 @@
|
|
|
1
|
+
import {
|
|
2
|
+
AcknowledgeContractGap,
|
|
3
|
+
BehaviorLedger,
|
|
4
|
+
ContractAdded,
|
|
5
|
+
ContractGapAcknowledged,
|
|
6
|
+
ContractMissing,
|
|
7
|
+
ContractUpdated,
|
|
8
|
+
ContractValidated,
|
|
9
|
+
ValidateContracts,
|
|
10
|
+
createBehaviorLedger,
|
|
11
|
+
defineConstraint,
|
|
12
|
+
defineEvent,
|
|
13
|
+
defineFact,
|
|
14
|
+
defineModule,
|
|
15
|
+
defineRule,
|
|
16
|
+
filterEvents,
|
|
17
|
+
filterFacts,
|
|
18
|
+
findEvent,
|
|
19
|
+
findFact,
|
|
20
|
+
formatValidationReport,
|
|
21
|
+
formatValidationReportJSON,
|
|
22
|
+
formatValidationReportSARIF,
|
|
23
|
+
validateContracts
|
|
24
|
+
} from "./chunk-5RH7UAQC.js";
|
|
25
|
+
import {
|
|
26
|
+
defineContract,
|
|
27
|
+
getContract,
|
|
28
|
+
isContract
|
|
29
|
+
} from "./chunk-WZ6B3LZ6.js";
|
|
1
30
|
import {
|
|
2
31
|
InMemoryPraxisDB,
|
|
3
32
|
PluresDBPraxisAdapter,
|
|
4
33
|
createInMemoryDB,
|
|
5
|
-
createPluresDB
|
|
6
|
-
|
|
34
|
+
createPluresDB,
|
|
35
|
+
createPraxisLocalFirst
|
|
36
|
+
} from "./chunk-MBVHLOU2.js";
|
|
7
37
|
import {
|
|
8
38
|
StateDocsGenerator,
|
|
9
39
|
createStateDocsGenerator,
|
|
@@ -18,10 +48,12 @@ import {
|
|
|
18
48
|
validateWithGuardian
|
|
19
49
|
} from "./chunk-SRM3OPPM.js";
|
|
20
50
|
import {
|
|
21
|
-
PraxisRegistry,
|
|
22
51
|
ReactiveLogicEngine,
|
|
23
52
|
createReactiveEngine
|
|
24
|
-
} from "./chunk-
|
|
53
|
+
} from "./chunk-PRPQO6R5.js";
|
|
54
|
+
import {
|
|
55
|
+
PraxisRegistry
|
|
56
|
+
} from "./chunk-R2PSBPKQ.js";
|
|
25
57
|
import {
|
|
26
58
|
TerminalAdapter,
|
|
27
59
|
createMockExecutor,
|
|
@@ -590,65 +622,6 @@ function createIntrospector(registry) {
|
|
|
590
622
|
return new RegistryIntrospector(registry);
|
|
591
623
|
}
|
|
592
624
|
|
|
593
|
-
// src/dsl/index.ts
|
|
594
|
-
function defineFact(tag) {
|
|
595
|
-
return {
|
|
596
|
-
tag,
|
|
597
|
-
create(payload) {
|
|
598
|
-
return { tag, payload };
|
|
599
|
-
},
|
|
600
|
-
is(fact) {
|
|
601
|
-
return fact.tag === tag;
|
|
602
|
-
}
|
|
603
|
-
};
|
|
604
|
-
}
|
|
605
|
-
function defineEvent(tag) {
|
|
606
|
-
return {
|
|
607
|
-
tag,
|
|
608
|
-
create(payload) {
|
|
609
|
-
return { tag, payload };
|
|
610
|
-
},
|
|
611
|
-
is(event) {
|
|
612
|
-
return event.tag === tag;
|
|
613
|
-
}
|
|
614
|
-
};
|
|
615
|
-
}
|
|
616
|
-
function defineRule(options) {
|
|
617
|
-
return {
|
|
618
|
-
id: options.id,
|
|
619
|
-
description: options.description,
|
|
620
|
-
impl: options.impl,
|
|
621
|
-
meta: options.meta
|
|
622
|
-
};
|
|
623
|
-
}
|
|
624
|
-
function defineConstraint(options) {
|
|
625
|
-
return {
|
|
626
|
-
id: options.id,
|
|
627
|
-
description: options.description,
|
|
628
|
-
impl: options.impl,
|
|
629
|
-
meta: options.meta
|
|
630
|
-
};
|
|
631
|
-
}
|
|
632
|
-
function defineModule(options) {
|
|
633
|
-
return {
|
|
634
|
-
rules: options.rules ?? [],
|
|
635
|
-
constraints: options.constraints ?? [],
|
|
636
|
-
meta: options.meta
|
|
637
|
-
};
|
|
638
|
-
}
|
|
639
|
-
function filterEvents(events, definition) {
|
|
640
|
-
return events.filter(definition.is);
|
|
641
|
-
}
|
|
642
|
-
function filterFacts(facts, definition) {
|
|
643
|
-
return facts.filter(definition.is);
|
|
644
|
-
}
|
|
645
|
-
function findEvent(events, definition) {
|
|
646
|
-
return events.find(definition.is);
|
|
647
|
-
}
|
|
648
|
-
function findFact(facts, definition) {
|
|
649
|
-
return facts.find(definition.is);
|
|
650
|
-
}
|
|
651
|
-
|
|
652
625
|
// src/core/pluresdb/store.ts
|
|
653
626
|
var PRAXIS_PATHS = {
|
|
654
627
|
/** Base path for all Praxis data */
|
|
@@ -1471,7 +1444,7 @@ function generateTauriConfig(config) {
|
|
|
1471
1444
|
// src/integrations/unified.ts
|
|
1472
1445
|
async function createUnifiedApp(config) {
|
|
1473
1446
|
const { createPraxisEngine: createPraxisEngine2 } = await import("./engine-2DQBKBJC.js");
|
|
1474
|
-
const { createInMemoryDB: createInMemoryDB2 } = await import("./adapter-
|
|
1447
|
+
const { createInMemoryDB: createInMemoryDB2 } = await import("./adapter-75ISSMWD.js");
|
|
1475
1448
|
const db = config.db || createInMemoryDB2();
|
|
1476
1449
|
const pluresdb = createPluresDBAdapter({
|
|
1477
1450
|
db,
|
|
@@ -1545,7 +1518,7 @@ async function createUnifiedApp(config) {
|
|
|
1545
1518
|
};
|
|
1546
1519
|
}
|
|
1547
1520
|
async function attachAllIntegrations(engine, registry, options = {}) {
|
|
1548
|
-
const { createInMemoryDB: createInMemoryDB2 } = await import("./adapter-
|
|
1521
|
+
const { createInMemoryDB: createInMemoryDB2 } = await import("./adapter-75ISSMWD.js");
|
|
1549
1522
|
const db = options.db || createInMemoryDB2();
|
|
1550
1523
|
const pluresdb = createPluresDBAdapter({
|
|
1551
1524
|
db,
|
|
@@ -1600,7 +1573,14 @@ async function attachAllIntegrations(engine, registry, options = {}) {
|
|
|
1600
1573
|
};
|
|
1601
1574
|
}
|
|
1602
1575
|
export {
|
|
1576
|
+
AcknowledgeContractGap,
|
|
1603
1577
|
ActorManager,
|
|
1578
|
+
BehaviorLedger,
|
|
1579
|
+
ContractAdded,
|
|
1580
|
+
ContractGapAcknowledged,
|
|
1581
|
+
ContractMissing,
|
|
1582
|
+
ContractUpdated,
|
|
1583
|
+
ContractValidated,
|
|
1604
1584
|
ReactiveLogicEngine2 as FrameworkAgnosticReactiveEngine,
|
|
1605
1585
|
InMemoryPraxisDB,
|
|
1606
1586
|
LogicEngine,
|
|
@@ -1615,6 +1595,7 @@ export {
|
|
|
1615
1595
|
RegistryIntrospector,
|
|
1616
1596
|
StateDocsGenerator,
|
|
1617
1597
|
TerminalAdapter,
|
|
1598
|
+
ValidateContracts,
|
|
1618
1599
|
attachAllIntegrations,
|
|
1619
1600
|
attachTauriToEngine,
|
|
1620
1601
|
attachToEngine,
|
|
@@ -1622,6 +1603,7 @@ export {
|
|
|
1622
1603
|
canvasToMermaid,
|
|
1623
1604
|
canvasToSchema,
|
|
1624
1605
|
canvasToYaml,
|
|
1606
|
+
createBehaviorLedger,
|
|
1625
1607
|
createCanvasEditor,
|
|
1626
1608
|
createReactiveEngine2 as createFrameworkAgnosticReactiveEngine,
|
|
1627
1609
|
createInMemoryDB,
|
|
@@ -1633,6 +1615,7 @@ export {
|
|
|
1633
1615
|
createPluresDBGenerator,
|
|
1634
1616
|
createPraxisDBStore,
|
|
1635
1617
|
createPraxisEngine,
|
|
1618
|
+
createPraxisLocalFirst,
|
|
1636
1619
|
createReactiveEngine,
|
|
1637
1620
|
createSchemaRegistry,
|
|
1638
1621
|
createSchemaTemplate,
|
|
@@ -1643,6 +1626,7 @@ export {
|
|
|
1643
1626
|
createUnifiedApp,
|
|
1644
1627
|
createUnumAdapter,
|
|
1645
1628
|
defineConstraint,
|
|
1629
|
+
defineContract,
|
|
1646
1630
|
defineEvent,
|
|
1647
1631
|
defineFact,
|
|
1648
1632
|
defineModule,
|
|
@@ -1651,12 +1635,17 @@ export {
|
|
|
1651
1635
|
filterFacts,
|
|
1652
1636
|
findEvent,
|
|
1653
1637
|
findFact,
|
|
1638
|
+
formatValidationReport,
|
|
1639
|
+
formatValidationReportJSON,
|
|
1640
|
+
formatValidationReportSARIF,
|
|
1654
1641
|
generateDocs,
|
|
1655
1642
|
generateId,
|
|
1656
1643
|
generateTauriConfig,
|
|
1644
|
+
getContract,
|
|
1657
1645
|
getEventPath,
|
|
1658
1646
|
getFactPath,
|
|
1659
1647
|
getSchemaPath,
|
|
1648
|
+
isContract,
|
|
1660
1649
|
loadSchema,
|
|
1661
1650
|
loadSchemaFromFile,
|
|
1662
1651
|
loadSchemaFromJson,
|
|
@@ -1664,6 +1653,7 @@ export {
|
|
|
1664
1653
|
registerSchema,
|
|
1665
1654
|
runTerminalCommand,
|
|
1666
1655
|
schemaToCanvas,
|
|
1656
|
+
validateContracts,
|
|
1667
1657
|
validateForGeneration,
|
|
1668
1658
|
validateSchema,
|
|
1669
1659
|
validateWithGuardian
|
|
@@ -50,6 +50,17 @@ var $ = __toESM(require("svelte/internal/client"), 1);
|
|
|
50
50
|
var PraxisRegistry = class {
|
|
51
51
|
rules = /* @__PURE__ */ new Map();
|
|
52
52
|
constraints = /* @__PURE__ */ new Map();
|
|
53
|
+
compliance;
|
|
54
|
+
contractGaps = [];
|
|
55
|
+
constructor(options = {}) {
|
|
56
|
+
const defaultEnabled = typeof process !== "undefined" ? process.env?.NODE_ENV !== "production" : false;
|
|
57
|
+
this.compliance = {
|
|
58
|
+
enabled: defaultEnabled,
|
|
59
|
+
requiredFields: ["behavior", "examples", "invariants"],
|
|
60
|
+
missingSeverity: "warning",
|
|
61
|
+
...options.compliance
|
|
62
|
+
};
|
|
63
|
+
}
|
|
53
64
|
/**
|
|
54
65
|
* Register a rule
|
|
55
66
|
*/
|
|
@@ -58,6 +69,7 @@ var PraxisRegistry = class {
|
|
|
58
69
|
throw new Error(`Rule with id "${descriptor.id}" already registered`);
|
|
59
70
|
}
|
|
60
71
|
this.rules.set(descriptor.id, descriptor);
|
|
72
|
+
this.trackContractCompliance(descriptor.id, descriptor);
|
|
61
73
|
}
|
|
62
74
|
/**
|
|
63
75
|
* Register a constraint
|
|
@@ -67,6 +79,7 @@ var PraxisRegistry = class {
|
|
|
67
79
|
throw new Error(`Constraint with id "${descriptor.id}" already registered`);
|
|
68
80
|
}
|
|
69
81
|
this.constraints.set(descriptor.id, descriptor);
|
|
82
|
+
this.trackContractCompliance(descriptor.id, descriptor);
|
|
70
83
|
}
|
|
71
84
|
/**
|
|
72
85
|
* Register a module (all its rules and constraints)
|
|
@@ -115,6 +128,69 @@ var PraxisRegistry = class {
|
|
|
115
128
|
getAllConstraints() {
|
|
116
129
|
return Array.from(this.constraints.values());
|
|
117
130
|
}
|
|
131
|
+
/**
|
|
132
|
+
* Get collected contract gaps from registration-time validation.
|
|
133
|
+
*/
|
|
134
|
+
getContractGaps() {
|
|
135
|
+
return [...this.contractGaps];
|
|
136
|
+
}
|
|
137
|
+
/**
|
|
138
|
+
* Clear collected contract gaps.
|
|
139
|
+
*/
|
|
140
|
+
clearContractGaps() {
|
|
141
|
+
this.contractGaps = [];
|
|
142
|
+
}
|
|
143
|
+
trackContractCompliance(id, descriptor) {
|
|
144
|
+
if (!this.compliance.enabled) {
|
|
145
|
+
return;
|
|
146
|
+
}
|
|
147
|
+
const gaps = this.validateDescriptorContract(id, descriptor);
|
|
148
|
+
for (const gap of gaps) {
|
|
149
|
+
this.contractGaps.push(gap);
|
|
150
|
+
if (this.compliance.onGap) {
|
|
151
|
+
this.compliance.onGap(gap);
|
|
152
|
+
} else {
|
|
153
|
+
const label = gap.severity === "error" ? "ERROR" : gap.severity === "warning" ? "WARN" : "INFO";
|
|
154
|
+
console.warn(`[Praxis][${label}] Contract gap for "${gap.ruleId}": missing ${gap.missing.join(", ")}`);
|
|
155
|
+
}
|
|
156
|
+
}
|
|
157
|
+
}
|
|
158
|
+
validateDescriptorContract(id, descriptor) {
|
|
159
|
+
const requiredFields = this.compliance.requiredFields ?? ["behavior", "examples", "invariants"];
|
|
160
|
+
const missingSeverity = this.compliance.missingSeverity ?? "warning";
|
|
161
|
+
const contract = descriptor.contract ?? (descriptor.meta?.contract && typeof descriptor.meta.contract === "object" ? descriptor.meta.contract : void 0);
|
|
162
|
+
if (!contract) {
|
|
163
|
+
return [
|
|
164
|
+
{
|
|
165
|
+
ruleId: id,
|
|
166
|
+
missing: ["contract"],
|
|
167
|
+
severity: missingSeverity,
|
|
168
|
+
message: `Contract missing for "${id}"`
|
|
169
|
+
}
|
|
170
|
+
];
|
|
171
|
+
}
|
|
172
|
+
const missing = [];
|
|
173
|
+
if (requiredFields.includes("behavior") && (!contract.behavior || contract.behavior.trim() === "")) {
|
|
174
|
+
missing.push("behavior");
|
|
175
|
+
}
|
|
176
|
+
if (requiredFields.includes("examples") && (!contract.examples || contract.examples.length === 0)) {
|
|
177
|
+
missing.push("examples");
|
|
178
|
+
}
|
|
179
|
+
if (requiredFields.includes("invariants") && (!contract.invariants || contract.invariants.length === 0)) {
|
|
180
|
+
missing.push("invariants");
|
|
181
|
+
}
|
|
182
|
+
if (missing.length === 0) {
|
|
183
|
+
return [];
|
|
184
|
+
}
|
|
185
|
+
return [
|
|
186
|
+
{
|
|
187
|
+
ruleId: id,
|
|
188
|
+
missing,
|
|
189
|
+
severity: "warning",
|
|
190
|
+
message: `Contract for "${id}" is incomplete: missing ${missing.join(", ")}`
|
|
191
|
+
}
|
|
192
|
+
];
|
|
193
|
+
}
|
|
118
194
|
};
|
|
119
195
|
|
|
120
196
|
// src/core/protocol.ts
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { L as LogicEngine } from '../reactive-engine.svelte-
|
|
2
|
-
export { a as ReactiveEngineOptions, R as ReactiveLogicEngine, c as createReactiveEngine } from '../reactive-engine.svelte-
|
|
1
|
+
import { L as LogicEngine } from '../reactive-engine.svelte-BFIZfawz.cjs';
|
|
2
|
+
export { a as ReactiveEngineOptions, R as ReactiveLogicEngine, c as createReactiveEngine } from '../reactive-engine.svelte-BFIZfawz.cjs';
|
|
3
3
|
import { P as PraxisState, a as PraxisEvent } from '../protocol-Qek7ebBl.cjs';
|
|
4
4
|
|
|
5
5
|
/**
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { L as LogicEngine } from '../reactive-engine.svelte-
|
|
2
|
-
export { a as ReactiveEngineOptions, R as ReactiveLogicEngine, c as createReactiveEngine } from '../reactive-engine.svelte-
|
|
1
|
+
import { L as LogicEngine } from '../reactive-engine.svelte-CRNqHlbv.js';
|
|
2
|
+
export { a as ReactiveEngineOptions, R as ReactiveLogicEngine, c as createReactiveEngine } from '../reactive-engine.svelte-CRNqHlbv.js';
|
|
3
3
|
import { P as PraxisState, a as PraxisEvent } from '../protocol-Qek7ebBl.js';
|
|
4
4
|
|
|
5
5
|
/**
|
package/dist/node/{reactive-engine.svelte-1M4m_C_v.d.cts → reactive-engine.svelte-BFIZfawz.d.cts}
RENAMED
|
@@ -1,5 +1,167 @@
|
|
|
1
1
|
import { P as PraxisState, a as PraxisEvent, b as PraxisFact, c as PraxisStepResult, d as PraxisStepConfig } from './protocol-Qek7ebBl.cjs';
|
|
2
2
|
|
|
3
|
+
/**
|
|
4
|
+
* Decision Ledger - Contract Types
|
|
5
|
+
*
|
|
6
|
+
* Types for defining and validating contracts for rules and constraints.
|
|
7
|
+
* All types are JSON-serializable for cross-language compatibility.
|
|
8
|
+
*/
|
|
9
|
+
/**
|
|
10
|
+
* A single assumption made during contract definition.
|
|
11
|
+
*/
|
|
12
|
+
interface Assumption {
|
|
13
|
+
/** Stable unique identifier for the assumption */
|
|
14
|
+
id: string;
|
|
15
|
+
/** The assumption statement */
|
|
16
|
+
statement: string;
|
|
17
|
+
/** Confidence level (0.0 to 1.0) */
|
|
18
|
+
confidence: number;
|
|
19
|
+
/** Justification for the assumption */
|
|
20
|
+
justification: string;
|
|
21
|
+
/** What this assumption was derived from */
|
|
22
|
+
derivedFrom?: string;
|
|
23
|
+
/** What artifacts this assumption impacts */
|
|
24
|
+
impacts: Array<'spec' | 'tests' | 'code'>;
|
|
25
|
+
/** Current status of the assumption */
|
|
26
|
+
status: 'active' | 'revised' | 'invalidated';
|
|
27
|
+
}
|
|
28
|
+
/**
|
|
29
|
+
* A reference to external documentation or resources.
|
|
30
|
+
*/
|
|
31
|
+
interface Reference {
|
|
32
|
+
/** Type of reference (e.g., 'doc', 'ticket', 'issue') */
|
|
33
|
+
type: string;
|
|
34
|
+
/** URL to the reference */
|
|
35
|
+
url?: string;
|
|
36
|
+
/** Human-readable description */
|
|
37
|
+
description?: string;
|
|
38
|
+
}
|
|
39
|
+
/**
|
|
40
|
+
* A Given/When/Then example for a contract.
|
|
41
|
+
*/
|
|
42
|
+
interface Example {
|
|
43
|
+
/** Initial state or preconditions */
|
|
44
|
+
given: string;
|
|
45
|
+
/** Triggering event or action */
|
|
46
|
+
when: string;
|
|
47
|
+
/** Expected outcome or postconditions */
|
|
48
|
+
then: string;
|
|
49
|
+
}
|
|
50
|
+
/**
|
|
51
|
+
* Contract for a rule or constraint.
|
|
52
|
+
* Documents the expected behavior, test cases, invariants, and assumptions.
|
|
53
|
+
*/
|
|
54
|
+
interface Contract {
|
|
55
|
+
/** ID of the rule or constraint this contract applies to */
|
|
56
|
+
ruleId: string;
|
|
57
|
+
/** Canonical behavior description */
|
|
58
|
+
behavior: string;
|
|
59
|
+
/** Given/When/Then examples (become test vectors) */
|
|
60
|
+
examples: Example[];
|
|
61
|
+
/** TLA+-friendly invariants or Praxis-level invariants */
|
|
62
|
+
invariants: string[];
|
|
63
|
+
/** Explicit assumptions with confidence levels */
|
|
64
|
+
assumptions?: Assumption[];
|
|
65
|
+
/** References to docs, tickets, links */
|
|
66
|
+
references?: Reference[];
|
|
67
|
+
/** Contract version (for evolution tracking) */
|
|
68
|
+
version?: string;
|
|
69
|
+
/** Timestamp of contract creation */
|
|
70
|
+
timestamp?: string;
|
|
71
|
+
}
|
|
72
|
+
/**
|
|
73
|
+
* Type guard to check if an object is a valid Contract.
|
|
74
|
+
*/
|
|
75
|
+
declare function isContract(obj: unknown): obj is Contract;
|
|
76
|
+
/**
|
|
77
|
+
* Options for defining a contract.
|
|
78
|
+
*/
|
|
79
|
+
interface DefineContractOptions {
|
|
80
|
+
/** ID of the rule or constraint */
|
|
81
|
+
ruleId: string;
|
|
82
|
+
/** Canonical behavior description */
|
|
83
|
+
behavior: string;
|
|
84
|
+
/** Given/When/Then examples */
|
|
85
|
+
examples: Example[];
|
|
86
|
+
/** Invariants that must hold */
|
|
87
|
+
invariants: string[];
|
|
88
|
+
/** Optional assumptions */
|
|
89
|
+
assumptions?: Assumption[];
|
|
90
|
+
/** Optional references */
|
|
91
|
+
references?: Reference[];
|
|
92
|
+
/** Optional version */
|
|
93
|
+
version?: string;
|
|
94
|
+
}
|
|
95
|
+
/**
|
|
96
|
+
* Define a contract for a rule or constraint.
|
|
97
|
+
*
|
|
98
|
+
* @example
|
|
99
|
+
* const loginContract = defineContract({
|
|
100
|
+
* ruleId: 'auth.login',
|
|
101
|
+
* behavior: 'Process login events and create user session facts',
|
|
102
|
+
* examples: [
|
|
103
|
+
* {
|
|
104
|
+
* given: 'User provides valid credentials',
|
|
105
|
+
* when: 'LOGIN event is received',
|
|
106
|
+
* then: 'UserSessionCreated fact is emitted'
|
|
107
|
+
* }
|
|
108
|
+
* ],
|
|
109
|
+
* invariants: ['Session must have unique ID']
|
|
110
|
+
* });
|
|
111
|
+
*/
|
|
112
|
+
declare function defineContract(options: DefineContractOptions): Contract;
|
|
113
|
+
/**
|
|
114
|
+
* Extract contract from rule/constraint metadata.
|
|
115
|
+
*/
|
|
116
|
+
declare function getContract(meta?: Record<string, unknown>): Contract | undefined;
|
|
117
|
+
/**
|
|
118
|
+
* Severity levels for contract gaps.
|
|
119
|
+
*/
|
|
120
|
+
type Severity = 'warning' | 'error' | 'info';
|
|
121
|
+
/**
|
|
122
|
+
* Types of missing contract artifacts.
|
|
123
|
+
*/
|
|
124
|
+
/**
|
|
125
|
+
* Types of artifacts that can be missing from a contract.
|
|
126
|
+
*
|
|
127
|
+
* Note: 'tests' and 'spec' are included in this type for future extensibility
|
|
128
|
+
* and SARIF reporting compatibility, but are not currently validated by the
|
|
129
|
+
* validateContract function. To check for these, implement custom validation
|
|
130
|
+
* logic that scans for test files or spec files in your codebase.
|
|
131
|
+
*/
|
|
132
|
+
type MissingArtifact = 'behavior' | 'examples' | 'invariants' | 'tests' | 'spec' | 'contract';
|
|
133
|
+
/**
|
|
134
|
+
* A gap in contract coverage.
|
|
135
|
+
*/
|
|
136
|
+
interface ContractGap {
|
|
137
|
+
/** ID of the rule or constraint */
|
|
138
|
+
ruleId: string;
|
|
139
|
+
/** What is missing */
|
|
140
|
+
missing: MissingArtifact[];
|
|
141
|
+
/** Severity of the gap */
|
|
142
|
+
severity: Severity;
|
|
143
|
+
/** Optional human-readable message */
|
|
144
|
+
message?: string;
|
|
145
|
+
}
|
|
146
|
+
/**
|
|
147
|
+
* Result of contract validation.
|
|
148
|
+
*/
|
|
149
|
+
interface ValidationReport {
|
|
150
|
+
/** Rules/constraints with complete contracts */
|
|
151
|
+
complete: Array<{
|
|
152
|
+
ruleId: string;
|
|
153
|
+
contract: Contract;
|
|
154
|
+
}>;
|
|
155
|
+
/** Rules/constraints with incomplete contracts */
|
|
156
|
+
incomplete: ContractGap[];
|
|
157
|
+
/** Rules/constraints with no contract at all */
|
|
158
|
+
missing: string[];
|
|
159
|
+
/** Total number of rules/constraints validated */
|
|
160
|
+
total: number;
|
|
161
|
+
/** Timestamp of validation */
|
|
162
|
+
timestamp: string;
|
|
163
|
+
}
|
|
164
|
+
|
|
3
165
|
/**
|
|
4
166
|
* Rules and Constraints System
|
|
5
167
|
*
|
|
@@ -47,6 +209,8 @@ interface RuleDescriptor<TContext = unknown> {
|
|
|
47
209
|
description: string;
|
|
48
210
|
/** Implementation function */
|
|
49
211
|
impl: RuleFn<TContext>;
|
|
212
|
+
/** Optional contract for rule behavior */
|
|
213
|
+
contract?: Contract;
|
|
50
214
|
/** Optional metadata */
|
|
51
215
|
meta?: Record<string, unknown>;
|
|
52
216
|
}
|
|
@@ -60,6 +224,8 @@ interface ConstraintDescriptor<TContext = unknown> {
|
|
|
60
224
|
description: string;
|
|
61
225
|
/** Implementation function */
|
|
62
226
|
impl: ConstraintFn<TContext>;
|
|
227
|
+
/** Optional contract for constraint behavior */
|
|
228
|
+
contract?: Contract;
|
|
63
229
|
/** Optional metadata */
|
|
64
230
|
meta?: Record<string, unknown>;
|
|
65
231
|
}
|
|
@@ -75,6 +241,25 @@ interface PraxisModule<TContext = unknown> {
|
|
|
75
241
|
/** Optional module metadata */
|
|
76
242
|
meta?: Record<string, unknown>;
|
|
77
243
|
}
|
|
244
|
+
/**
|
|
245
|
+
* Compliance validation options for rule/constraint registration.
|
|
246
|
+
*/
|
|
247
|
+
interface RegistryComplianceOptions {
|
|
248
|
+
/** Enable contract checks during registration (default: true in dev) */
|
|
249
|
+
enabled?: boolean;
|
|
250
|
+
/** Required contract fields to be present */
|
|
251
|
+
requiredFields?: Array<'behavior' | 'examples' | 'invariants'>;
|
|
252
|
+
/** Severity to use for missing contracts */
|
|
253
|
+
missingSeverity?: Severity;
|
|
254
|
+
/** Callback for contract gaps (e.g., to emit facts) */
|
|
255
|
+
onGap?: (gap: ContractGap) => void;
|
|
256
|
+
}
|
|
257
|
+
/**
|
|
258
|
+
* PraxisRegistry configuration options.
|
|
259
|
+
*/
|
|
260
|
+
interface PraxisRegistryOptions {
|
|
261
|
+
compliance?: RegistryComplianceOptions;
|
|
262
|
+
}
|
|
78
263
|
/**
|
|
79
264
|
* Registry for rules and constraints.
|
|
80
265
|
* Maps IDs to their descriptors.
|
|
@@ -82,6 +267,9 @@ interface PraxisModule<TContext = unknown> {
|
|
|
82
267
|
declare class PraxisRegistry<TContext = unknown> {
|
|
83
268
|
private rules;
|
|
84
269
|
private constraints;
|
|
270
|
+
private readonly compliance;
|
|
271
|
+
private contractGaps;
|
|
272
|
+
constructor(options?: PraxisRegistryOptions);
|
|
85
273
|
/**
|
|
86
274
|
* Register a rule
|
|
87
275
|
*/
|
|
@@ -118,6 +306,16 @@ declare class PraxisRegistry<TContext = unknown> {
|
|
|
118
306
|
* Get all constraints
|
|
119
307
|
*/
|
|
120
308
|
getAllConstraints(): ConstraintDescriptor<TContext>[];
|
|
309
|
+
/**
|
|
310
|
+
* Get collected contract gaps from registration-time validation.
|
|
311
|
+
*/
|
|
312
|
+
getContractGaps(): ContractGap[];
|
|
313
|
+
/**
|
|
314
|
+
* Clear collected contract gaps.
|
|
315
|
+
*/
|
|
316
|
+
clearContractGaps(): void;
|
|
317
|
+
private trackContractCompliance;
|
|
318
|
+
private validateDescriptorContract;
|
|
121
319
|
}
|
|
122
320
|
|
|
123
321
|
/**
|
|
@@ -297,4 +495,4 @@ declare class ReactiveLogicEngine<TContext extends object> {
|
|
|
297
495
|
*/
|
|
298
496
|
declare function createReactiveEngine<TContext extends object>(options: ReactiveEngineOptions<TContext>): ReactiveLogicEngine<TContext>;
|
|
299
497
|
|
|
300
|
-
export { type ConstraintDescriptor as C, LogicEngine as L, PraxisRegistry as P, ReactiveLogicEngine as R, type ReactiveEngineOptions as a, type RuleDescriptor as b, createReactiveEngine as c, type RuleFn as d, type
|
|
498
|
+
export { type Assumption as A, type ConstraintDescriptor as C, type DefineContractOptions as D, type Example as E, LogicEngine as L, type MissingArtifact as M, PraxisRegistry as P, ReactiveLogicEngine as R, type Severity as S, type ValidationReport as V, type ReactiveEngineOptions as a, type RuleDescriptor as b, createReactiveEngine as c, type RuleFn as d, type Contract as e, type ConstraintFn as f, type PraxisModule as g, type RuleId as h, type ConstraintId as i, type PraxisEngineOptions as j, createPraxisEngine as k, defineContract as l, getContract as m, isContract as n, type Reference as o, type ContractGap as p };
|