@plures/praxis 1.1.3 → 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/FRAMEWORK.md +106 -15
- package/README.md +194 -119
- package/dist/browser/adapter-CIMBGDC7.js +14 -0
- package/dist/browser/chunk-K377RW4V.js +230 -0
- package/dist/browser/chunk-MBVHLOU2.js +152 -0
- package/dist/browser/{chunk-R45WXWKH.js → chunk-VOMLVI6V.js} +1 -149
- package/dist/browser/engine-YJZV4SLD.js +8 -0
- package/dist/browser/index.d.ts +161 -5
- package/dist/browser/index.js +156 -141
- package/dist/browser/integrations/svelte.d.ts +2 -2
- package/dist/browser/integrations/svelte.js +2 -1
- package/dist/browser/{reactive-engine.svelte-C9OpcTHf.d.ts → reactive-engine.svelte-9aS0kTa8.d.ts} +136 -1
- package/dist/node/adapter-75ISSMWD.js +15 -0
- package/dist/node/chunk-5RH7UAQC.js +486 -0
- package/dist/node/chunk-MBVHLOU2.js +152 -0
- package/dist/node/chunk-PRPQO6R5.js +85 -0
- package/dist/node/chunk-R2PSBPKQ.js +150 -0
- package/dist/node/chunk-S54337I5.js +446 -0
- package/dist/node/{chunk-R45WXWKH.js → chunk-VOMLVI6V.js} +1 -149
- package/dist/node/chunk-WZ6B3LZ6.js +638 -0
- package/dist/node/cli/index.cjs +2936 -897
- package/dist/node/cli/index.js +27 -0
- package/dist/node/components/index.d.cts +3 -2
- package/dist/node/components/index.d.ts +3 -2
- package/dist/node/docs-JFNYTOJA.js +102 -0
- package/dist/node/engine-2DQBKBJC.js +9 -0
- package/dist/node/index.cjs +1114 -354
- package/dist/node/index.d.cts +388 -5
- package/dist/node/index.d.ts +388 -5
- package/dist/node/index.js +201 -640
- 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 +3 -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/docs.ts +147 -0
- package/src/cli/commands/reverse.ts +289 -0
- package/src/cli/commands/validate.ts +264 -0
- package/src/cli/index.ts +68 -0
- package/src/core/pluresdb/adapter.ts +46 -3
- package/src/core/reactive-engine.svelte.ts +6 -1
- package/src/core/reactive-engine.ts +1 -1
- 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 +6 -0
- package/src/index.ts +40 -0
- package/src/integrations/pluresdb.ts +14 -2
- package/src/integrations/unified.ts +350 -0
|
@@ -0,0 +1,225 @@
|
|
|
1
|
+
# Decision Ledger Integration - Behavior Ledger
|
|
2
|
+
|
|
3
|
+
**Status**: Active
|
|
4
|
+
**Version**: 1.0.0
|
|
5
|
+
**Created**: 2025-01-26
|
|
6
|
+
**Last Updated**: 2025-01-26
|
|
7
|
+
|
|
8
|
+
---
|
|
9
|
+
|
|
10
|
+
## Entry 1: Initial Decision Ledger Integration
|
|
11
|
+
|
|
12
|
+
**ID**: `decision-ledger-v1`
|
|
13
|
+
**Timestamp**: 2025-01-26T00:00:00Z
|
|
14
|
+
**Status**: Active
|
|
15
|
+
**Author**: System
|
|
16
|
+
|
|
17
|
+
### Canonical Behavior
|
|
18
|
+
|
|
19
|
+
The Decision Ledger Integration provides a mechanism for Praxis applications to:
|
|
20
|
+
|
|
21
|
+
1. **Define Contracts for Rules/Constraints** with:
|
|
22
|
+
- Canonical behavior description
|
|
23
|
+
- Given/When/Then examples that become test vectors
|
|
24
|
+
- TLA+-friendly invariants or Praxis-level invariants
|
|
25
|
+
- Explicit assumptions with confidence levels
|
|
26
|
+
- References to documentation, tickets, and external links
|
|
27
|
+
|
|
28
|
+
2. **Validate Compliance** at build-time and runtime:
|
|
29
|
+
- Build-time: `praxis validate` CLI scans registry modules
|
|
30
|
+
- Runtime: Lightweight validation when registering rules
|
|
31
|
+
- Structured diagnostics (JSON, console, optional SARIF)
|
|
32
|
+
|
|
33
|
+
3. **Track Missing Artifacts** as first-class facts:
|
|
34
|
+
- Fact: `ContractMissing` with ruleId, missing artifacts, severity
|
|
35
|
+
- Event: `ACKNOWLEDGE_CONTRACT_GAP` for explicit acknowledgment
|
|
36
|
+
- Rule: Policy enforcement for contract debt
|
|
37
|
+
|
|
38
|
+
4. **Maintain Immutable History**:
|
|
39
|
+
- Append-only ledger of behavior changes
|
|
40
|
+
- Assumption invalidation tracking
|
|
41
|
+
- Versioned behavior snapshots
|
|
42
|
+
|
|
43
|
+
### Examples (Given/When/Then)
|
|
44
|
+
|
|
45
|
+
#### Example 1: Defining a Contract for a Rule
|
|
46
|
+
|
|
47
|
+
**Given**: A rule `auth.login` that processes login events
|
|
48
|
+
**When**: Developer defines the contract with behavior, examples, and invariants
|
|
49
|
+
**Then**: The contract is registered and can be validated
|
|
50
|
+
|
|
51
|
+
```typescript
|
|
52
|
+
const loginContract = defineContract({
|
|
53
|
+
ruleId: 'auth.login',
|
|
54
|
+
behavior: 'Process login events and create user session facts',
|
|
55
|
+
examples: [
|
|
56
|
+
{
|
|
57
|
+
given: 'User provides valid credentials',
|
|
58
|
+
when: 'LOGIN event is received',
|
|
59
|
+
then: 'UserSessionCreated fact is emitted'
|
|
60
|
+
}
|
|
61
|
+
],
|
|
62
|
+
invariants: [
|
|
63
|
+
'Session must have unique ID',
|
|
64
|
+
'Session must have timestamp'
|
|
65
|
+
],
|
|
66
|
+
assumptions: [
|
|
67
|
+
{
|
|
68
|
+
id: 'assume-unique-username',
|
|
69
|
+
statement: 'Usernames are unique across the system',
|
|
70
|
+
confidence: 0.9,
|
|
71
|
+
justification: 'Standard practice in authentication systems',
|
|
72
|
+
impacts: ['spec', 'tests']
|
|
73
|
+
}
|
|
74
|
+
],
|
|
75
|
+
references: [
|
|
76
|
+
{ type: 'doc', url: 'https://docs.example.com/auth' }
|
|
77
|
+
]
|
|
78
|
+
});
|
|
79
|
+
```
|
|
80
|
+
|
|
81
|
+
#### Example 2: Build-time Validation
|
|
82
|
+
|
|
83
|
+
**Given**: A registry with rules and their contracts
|
|
84
|
+
**When**: `praxis validate` command is run
|
|
85
|
+
**Then**: Validation report shows contract coverage and gaps
|
|
86
|
+
|
|
87
|
+
```bash
|
|
88
|
+
$ praxis validate
|
|
89
|
+
✓ auth.login - Contract complete (behavior, examples, tests)
|
|
90
|
+
✗ cart.addItem - Missing: tests
|
|
91
|
+
✗ order.process - Missing: contract
|
|
92
|
+
```
|
|
93
|
+
|
|
94
|
+
#### Example 3: Runtime Validation
|
|
95
|
+
|
|
96
|
+
**Given**: A rule without a complete contract
|
|
97
|
+
**When**: Rule is registered at runtime with `strictContracts: true`
|
|
98
|
+
**Then**: ContractMissing fact is created and policy can enforce action
|
|
99
|
+
|
|
100
|
+
```typescript
|
|
101
|
+
const registry = createRegistry({ strictContracts: true });
|
|
102
|
+
registry.registerRule(ruleWithoutContract);
|
|
103
|
+
// ContractMissing fact is emitted
|
|
104
|
+
// Policy may warn, error, or allow based on configuration
|
|
105
|
+
```
|
|
106
|
+
|
|
107
|
+
#### Example 4: Contract Gap Acknowledgment
|
|
108
|
+
|
|
109
|
+
**Given**: A missing contract has been identified
|
|
110
|
+
**When**: Developer acknowledges the gap with justification
|
|
111
|
+
**Then**: ACKNOWLEDGE_CONTRACT_GAP event is recorded
|
|
112
|
+
|
|
113
|
+
```typescript
|
|
114
|
+
acknowledgeContractGap({
|
|
115
|
+
ruleId: 'legacy.process',
|
|
116
|
+
missing: ['spec', 'tests'],
|
|
117
|
+
justification: 'Legacy rule to be deprecated in v2.0',
|
|
118
|
+
expiresAt: '2025-12-31'
|
|
119
|
+
});
|
|
120
|
+
```
|
|
121
|
+
|
|
122
|
+
### Invariants
|
|
123
|
+
|
|
124
|
+
1. **Contract Immutability**: Once a contract version is published, its core behavior description cannot be changed; only new versions can be created
|
|
125
|
+
2. **Ledger Append-Only**: The behavior ledger is append-only; entries can be superseded but never deleted
|
|
126
|
+
3. **Assumption Traceability**: Every assumption must have a stable ID and impacts declaration
|
|
127
|
+
4. **Example Completeness**: Every contract must have at least one Given/When/Then example
|
|
128
|
+
5. **Validation Determinism**: Running `praxis validate` multiple times on the same codebase produces identical results
|
|
129
|
+
|
|
130
|
+
### Assumptions
|
|
131
|
+
|
|
132
|
+
#### A1: Contract Storage Location
|
|
133
|
+
- **ID**: `assume-contract-in-meta`
|
|
134
|
+
- **Statement**: Contracts are stored in the `meta` field of RuleDescriptor and ConstraintDescriptor
|
|
135
|
+
- **Confidence**: 0.95
|
|
136
|
+
- **Justification**: The existing `meta` field is designed for extensibility and already exists in the Praxis architecture
|
|
137
|
+
- **Derived From**: Analysis of src/core/rules.ts and src/dsl/index.ts
|
|
138
|
+
- **Impacts**: Implementation (contract storage), Tests (contract retrieval)
|
|
139
|
+
- **Status**: Active
|
|
140
|
+
|
|
141
|
+
#### A2: JSON Serialization
|
|
142
|
+
- **ID**: `assume-json-serializable`
|
|
143
|
+
- **Statement**: All contract data must be JSON-serializable for cross-language compatibility
|
|
144
|
+
- **Confidence**: 1.0
|
|
145
|
+
- **Justification**: Praxis protocol requirement for all data structures
|
|
146
|
+
- **Derived From**: src/core/protocol.ts PRAXIS_PROTOCOL_VERSION documentation
|
|
147
|
+
- **Impacts**: Spec (type definitions), Implementation (contract types)
|
|
148
|
+
- **Status**: Active
|
|
149
|
+
|
|
150
|
+
#### A3: CLI Extension Pattern
|
|
151
|
+
- **ID**: `assume-commander-pattern`
|
|
152
|
+
- **Statement**: New CLI commands follow the Commander.js pattern established in src/cli/index.ts
|
|
153
|
+
- **Confidence**: 1.0
|
|
154
|
+
- **Justification**: Existing CLI uses Commander.js for all commands
|
|
155
|
+
- **Derived From**: src/cli/index.ts lines 9-12
|
|
156
|
+
- **Impacts**: Implementation (validate command)
|
|
157
|
+
- **Status**: Active
|
|
158
|
+
|
|
159
|
+
#### A4: Test Framework
|
|
160
|
+
- **ID**: `assume-vitest`
|
|
161
|
+
- **Statement**: Tests use Vitest framework with describe/it/expect pattern
|
|
162
|
+
- **Confidence**: 1.0
|
|
163
|
+
- **Justification**: All existing tests use Vitest
|
|
164
|
+
- **Derived From**: src/__tests__/dsl.test.ts, package.json scripts
|
|
165
|
+
- **Impacts**: Tests (testing approach)
|
|
166
|
+
- **Status**: Active
|
|
167
|
+
|
|
168
|
+
#### A5: Contract Optional by Default
|
|
169
|
+
- **ID**: `assume-contract-optional`
|
|
170
|
+
- **Statement**: Contracts are optional by default; strict enforcement requires opt-in configuration
|
|
171
|
+
- **Confidence**: 0.85
|
|
172
|
+
- **Justification**: Backward compatibility with existing Praxis code that doesn't have contracts
|
|
173
|
+
- **Derived From**: User requirements for "integration" rather than breaking change
|
|
174
|
+
- **Impacts**: Implementation (validation logic), Tests (default behavior)
|
|
175
|
+
- **Status**: Active
|
|
176
|
+
|
|
177
|
+
### References
|
|
178
|
+
|
|
179
|
+
- **Design Doc**: Problem statement provided by user
|
|
180
|
+
- **Praxis Core**: src/core/rules.ts - Rule and Constraint descriptors
|
|
181
|
+
- **Praxis DSL**: src/dsl/index.ts - Helper functions for defining rules
|
|
182
|
+
- **Praxis Protocol**: src/core/protocol.ts - Core protocol versioning and types
|
|
183
|
+
- **CLI Pattern**: src/cli/index.ts - Command structure
|
|
184
|
+
|
|
185
|
+
### Changes from Previous Version
|
|
186
|
+
|
|
187
|
+
N/A - Initial version
|
|
188
|
+
|
|
189
|
+
---
|
|
190
|
+
|
|
191
|
+
## Schema
|
|
192
|
+
|
|
193
|
+
**Ledger Entry Schema**:
|
|
194
|
+
```typescript
|
|
195
|
+
interface LedgerEntry {
|
|
196
|
+
id: string;
|
|
197
|
+
timestamp: string;
|
|
198
|
+
status: 'active' | 'superseded' | 'deprecated';
|
|
199
|
+
author: string;
|
|
200
|
+
behavior: {
|
|
201
|
+
canonical: string;
|
|
202
|
+
examples: Array<{
|
|
203
|
+
given: string;
|
|
204
|
+
when: string;
|
|
205
|
+
then: string;
|
|
206
|
+
}>;
|
|
207
|
+
invariants: string[];
|
|
208
|
+
};
|
|
209
|
+
assumptions: Array<{
|
|
210
|
+
id: string;
|
|
211
|
+
statement: string;
|
|
212
|
+
confidence: number;
|
|
213
|
+
justification: string;
|
|
214
|
+
derivedFrom: string;
|
|
215
|
+
impacts: Array<'spec' | 'tests' | 'code'>;
|
|
216
|
+
status: 'active' | 'revised' | 'invalidated';
|
|
217
|
+
}>;
|
|
218
|
+
references: Array<{
|
|
219
|
+
type: string;
|
|
220
|
+
url?: string;
|
|
221
|
+
description?: string;
|
|
222
|
+
}>;
|
|
223
|
+
supersedes?: string;
|
|
224
|
+
}
|
|
225
|
+
```
|
|
@@ -0,0 +1,180 @@
|
|
|
1
|
+
--------------------------- MODULE DecisionLedger ---------------------------
|
|
2
|
+
(*
|
|
3
|
+
* TLA+ Specification for Praxis Decision Ledger Integration
|
|
4
|
+
*
|
|
5
|
+
* This spec models the core invariants and behaviors of the Decision Ledger,
|
|
6
|
+
* ensuring correctness of contract validation and ledger immutability.
|
|
7
|
+
*)
|
|
8
|
+
|
|
9
|
+
EXTENDS Naturals, Sequences, FiniteSets, TLC
|
|
10
|
+
|
|
11
|
+
CONSTANTS
|
|
12
|
+
RuleIds, \* Set of all possible rule IDs
|
|
13
|
+
MaxLedgerSize \* Maximum ledger entries for model checking
|
|
14
|
+
|
|
15
|
+
VARIABLES
|
|
16
|
+
ledger, \* Append-only sequence of ledger entries
|
|
17
|
+
contracts, \* Map: RuleId -> Contract
|
|
18
|
+
facts, \* Set of current facts (including ContractMissing)
|
|
19
|
+
acknowledged \* Set of acknowledged contract gaps
|
|
20
|
+
|
|
21
|
+
vars == <<ledger, contracts, facts, acknowledged>>
|
|
22
|
+
|
|
23
|
+
(*--algorithm DecisionLedger
|
|
24
|
+
|
|
25
|
+
variables
|
|
26
|
+
ledger = <<>>;
|
|
27
|
+
contracts = [r \in {} |-> {}];
|
|
28
|
+
facts = {};
|
|
29
|
+
acknowledged = {};
|
|
30
|
+
|
|
31
|
+
define
|
|
32
|
+
\* Type invariants
|
|
33
|
+
TypeOK ==
|
|
34
|
+
/\ ledger \in Seq([
|
|
35
|
+
id: STRING,
|
|
36
|
+
ruleId: RuleIds,
|
|
37
|
+
timestamp: Nat,
|
|
38
|
+
status: {"active", "superseded", "deprecated"}
|
|
39
|
+
])
|
|
40
|
+
/\ contracts \in [RuleIds -> [
|
|
41
|
+
behavior: STRING,
|
|
42
|
+
examples: SUBSET [given: STRING, when: STRING, then: STRING],
|
|
43
|
+
invariants: SUBSET STRING
|
|
44
|
+
]]
|
|
45
|
+
/\ facts \in SUBSET [
|
|
46
|
+
type: STRING,
|
|
47
|
+
ruleId: RuleIds,
|
|
48
|
+
data: [missing: SUBSET STRING, severity: STRING]
|
|
49
|
+
]
|
|
50
|
+
/\ acknowledged \in SUBSET [ruleId: RuleIds, justification: STRING]
|
|
51
|
+
|
|
52
|
+
\* Ledger is append-only (monotonic growth and immutability)
|
|
53
|
+
LedgerAppendOnly ==
|
|
54
|
+
/\ Len(ledger') >= Len(ledger)
|
|
55
|
+
/\ \A i \in 1..Len(ledger) :
|
|
56
|
+
\* Once an entry is in the ledger, it never changes in any field
|
|
57
|
+
ledger'[i] = ledger[i]
|
|
58
|
+
|
|
59
|
+
\* No duplicate ledger entry IDs
|
|
60
|
+
LedgerUnique ==
|
|
61
|
+
\A i, j \in 1..Len(ledger) :
|
|
62
|
+
i # j => ledger[i].id # ledger[j].id
|
|
63
|
+
|
|
64
|
+
\* Every contract must have at least one example
|
|
65
|
+
ContractExampleCompleteness ==
|
|
66
|
+
\A r \in DOMAIN contracts :
|
|
67
|
+
contracts[r].examples # {}
|
|
68
|
+
|
|
69
|
+
\* ContractMissing facts are accurate
|
|
70
|
+
ContractMissingAccuracy ==
|
|
71
|
+
\A f \in facts :
|
|
72
|
+
f.type = "ContractMissing" =>
|
|
73
|
+
/\ f.ruleId \notin DOMAIN contracts
|
|
74
|
+
\/ contracts[f.ruleId].examples = {}
|
|
75
|
+
\/ contracts[f.ruleId].behavior = ""
|
|
76
|
+
|
|
77
|
+
\* Acknowledged gaps are recorded
|
|
78
|
+
AcknowledgedGapsRecorded ==
|
|
79
|
+
\A a \in acknowledged :
|
|
80
|
+
\E f \in facts :
|
|
81
|
+
/\ f.type = "ContractMissing"
|
|
82
|
+
/\ f.ruleId = a.ruleId
|
|
83
|
+
|
|
84
|
+
\* Validation is deterministic
|
|
85
|
+
ValidationDeterministic ==
|
|
86
|
+
\* Given the same contracts, validation produces the same facts
|
|
87
|
+
\A r \in RuleIds :
|
|
88
|
+
(r \in DOMAIN contracts /\ contracts[r].behavior # "" /\ contracts[r].examples # {})
|
|
89
|
+
=> ~\E f \in facts : f.type = "ContractMissing" /\ f.ruleId = r
|
|
90
|
+
|
|
91
|
+
end define;
|
|
92
|
+
|
|
93
|
+
\* Add a contract for a rule
|
|
94
|
+
procedure AddContract(ruleId, behavior, examples, invariants)
|
|
95
|
+
begin
|
|
96
|
+
AddContract:
|
|
97
|
+
if ruleId \notin DOMAIN contracts then
|
|
98
|
+
contracts := contracts @@ (ruleId :> [
|
|
99
|
+
behavior |-> behavior,
|
|
100
|
+
examples |-> examples,
|
|
101
|
+
invariants |-> invariants
|
|
102
|
+
]);
|
|
103
|
+
\* Remove ContractMissing fact if it exists
|
|
104
|
+
facts := {f \in facts : ~(f.type = "ContractMissing" /\ f.ruleId = ruleId)};
|
|
105
|
+
end if;
|
|
106
|
+
return;
|
|
107
|
+
end procedure;
|
|
108
|
+
|
|
109
|
+
\* Register a rule and validate contract
|
|
110
|
+
procedure RegisterRule(ruleId, hasContract)
|
|
111
|
+
begin
|
|
112
|
+
RegisterRule:
|
|
113
|
+
if ~hasContract /\ ruleId \notin DOMAIN contracts then
|
|
114
|
+
\* Create ContractMissing fact
|
|
115
|
+
facts := facts \union {[
|
|
116
|
+
type |-> "ContractMissing",
|
|
117
|
+
ruleId |-> ruleId,
|
|
118
|
+
data |-> [missing |-> {"behavior", "examples"}, severity |-> "warning"]
|
|
119
|
+
]};
|
|
120
|
+
end if;
|
|
121
|
+
return;
|
|
122
|
+
end procedure;
|
|
123
|
+
|
|
124
|
+
\* Acknowledge a contract gap
|
|
125
|
+
procedure AcknowledgeGap(ruleId, justification)
|
|
126
|
+
begin
|
|
127
|
+
AcknowledgeGap:
|
|
128
|
+
acknowledged := acknowledged \union {[
|
|
129
|
+
ruleId |-> ruleId,
|
|
130
|
+
justification |-> justification
|
|
131
|
+
]};
|
|
132
|
+
return;
|
|
133
|
+
end procedure;
|
|
134
|
+
|
|
135
|
+
\* Append to ledger (immutable)
|
|
136
|
+
procedure AppendLedger(entryId, ruleId, timestamp, status)
|
|
137
|
+
begin
|
|
138
|
+
AppendLedger:
|
|
139
|
+
if Len(ledger) < MaxLedgerSize then
|
|
140
|
+
ledger := Append(ledger, [
|
|
141
|
+
id |-> entryId,
|
|
142
|
+
ruleId |-> ruleId,
|
|
143
|
+
timestamp |-> timestamp,
|
|
144
|
+
status |-> status
|
|
145
|
+
]);
|
|
146
|
+
end if;
|
|
147
|
+
return;
|
|
148
|
+
end procedure;
|
|
149
|
+
|
|
150
|
+
end algorithm; *)
|
|
151
|
+
|
|
152
|
+
=============================================================================
|
|
153
|
+
|
|
154
|
+
\* Key Invariants (for model checking):
|
|
155
|
+
\*
|
|
156
|
+
\* INVARIANT LedgerAppendOnly
|
|
157
|
+
\* The ledger is append-only; existing entries are never modified or deleted
|
|
158
|
+
\*
|
|
159
|
+
\* INVARIANT LedgerUnique
|
|
160
|
+
\* No two ledger entries have the same ID
|
|
161
|
+
\*
|
|
162
|
+
\* INVARIANT ContractExampleCompleteness
|
|
163
|
+
\* Every contract has at least one example
|
|
164
|
+
\*
|
|
165
|
+
\* INVARIANT ContractMissingAccuracy
|
|
166
|
+
\* ContractMissing facts accurately reflect missing contracts
|
|
167
|
+
\*
|
|
168
|
+
\* INVARIANT ValidationDeterministic
|
|
169
|
+
\* Validation produces deterministic results given the same inputs
|
|
170
|
+
\*
|
|
171
|
+
\* PROPERTY Safety
|
|
172
|
+
\* []TypeOK /\ []LedgerAppendOnly /\ []LedgerUnique
|
|
173
|
+
\*
|
|
174
|
+
\* PROPERTY Liveness
|
|
175
|
+
\* Eventually all rules have contracts: <>(DOMAIN contracts = RuleIds)
|
|
176
|
+
\*
|
|
177
|
+
\* Model Checking Notes:
|
|
178
|
+
\* - Set MaxLedgerSize = 5 for tractable model checking
|
|
179
|
+
\* - Set RuleIds = {"rule1", "rule2", "rule3"} for small test cases
|
|
180
|
+
\* - Check temporal properties with TLC
|
|
@@ -0,0 +1,217 @@
|
|
|
1
|
+
# Decision Ledger Integration - Implementation Summary
|
|
2
|
+
|
|
3
|
+
## Overview
|
|
4
|
+
|
|
5
|
+
The Decision Ledger Integration has been successfully implemented for the Praxis framework, providing contract-based validation and documentation for rules and constraints.
|
|
6
|
+
|
|
7
|
+
## Implementation Status
|
|
8
|
+
|
|
9
|
+
✅ **COMPLETE** - All components implemented, tested, and integrated
|
|
10
|
+
|
|
11
|
+
## Deliverables
|
|
12
|
+
|
|
13
|
+
### 1. Behavior Documentation
|
|
14
|
+
|
|
15
|
+
✅ **Behavior Ledger** (`docs/decision-ledger/BEHAVIOR_LEDGER.md`)
|
|
16
|
+
- Canonical behavior specification with examples and invariants
|
|
17
|
+
- 5 documented assumptions with confidence levels and traceability
|
|
18
|
+
- Complete Given/When/Then examples for all core use cases
|
|
19
|
+
|
|
20
|
+
✅ **LATEST Snapshot** (`docs/decision-ledger/LATEST.md`)
|
|
21
|
+
- Non-authoritative summary derived from behavior ledger
|
|
22
|
+
- Quick start guide with API reference
|
|
23
|
+
- Configuration examples
|
|
24
|
+
|
|
25
|
+
✅ **TLA+ Specification** (`docs/decision-ledger/DecisionLedger.tla`)
|
|
26
|
+
- Formal specification of core invariants
|
|
27
|
+
- Model-checkable properties for ledger immutability and validation determinism
|
|
28
|
+
- Documented safety and liveness properties
|
|
29
|
+
|
|
30
|
+
### 2. Core Implementation
|
|
31
|
+
|
|
32
|
+
✅ **Type Definitions** (`src/decision-ledger/types.ts`)
|
|
33
|
+
- `Contract` interface with behavior, examples, invariants, assumptions, references
|
|
34
|
+
- `Assumption` tracking with confidence levels and impact analysis
|
|
35
|
+
- `ValidationReport` with complete/incomplete/missing categorization
|
|
36
|
+
- JSON-serializable, cross-language compatible
|
|
37
|
+
|
|
38
|
+
✅ **Facts and Events** (`src/decision-ledger/facts-events.ts`)
|
|
39
|
+
- `ContractMissing` fact for tracking gaps
|
|
40
|
+
- `AcknowledgeContractGap` event for explicit acknowledgment
|
|
41
|
+
- `ContractValidated`, `ContractGapAcknowledged` facts
|
|
42
|
+
- `ContractAdded`, `ContractUpdated` events
|
|
43
|
+
|
|
44
|
+
✅ **Validation Engine** (`src/decision-ledger/validation.ts`)
|
|
45
|
+
- Build-time and runtime validation
|
|
46
|
+
- Multiple output formats: console, JSON, SARIF
|
|
47
|
+
- Configurable severity levels and required fields
|
|
48
|
+
- Deterministic validation results
|
|
49
|
+
|
|
50
|
+
✅ **Behavior Ledger** (`src/decision-ledger/ledger.ts`)
|
|
51
|
+
- Immutable, append-only storage
|
|
52
|
+
- Entry superseding with version tracking
|
|
53
|
+
- Assumption tracking and impact analysis
|
|
54
|
+
- JSON export/import for persistence
|
|
55
|
+
|
|
56
|
+
### 3. CLI Integration
|
|
57
|
+
|
|
58
|
+
✅ **Validate Command** (`src/cli/commands/validate.ts`)
|
|
59
|
+
- `praxis validate` command implementation
|
|
60
|
+
- Support for `--output` (console/json/sarif), `--strict`, `--registry`
|
|
61
|
+
- Error handling and exit codes for CI/CD integration
|
|
62
|
+
- Integrated into main CLI (`src/cli/index.ts`)
|
|
63
|
+
|
|
64
|
+
### 4. Tests
|
|
65
|
+
|
|
66
|
+
✅ **Comprehensive Test Suite** (`src/__tests__/decision-ledger.test.ts`)
|
|
67
|
+
- 17 test cases covering all core functionality
|
|
68
|
+
- Contract definition and validation
|
|
69
|
+
- Facts and events creation and type guards
|
|
70
|
+
- Behavior ledger immutability and versioning
|
|
71
|
+
- All examples from behavior ledger are tested
|
|
72
|
+
- **All tests passing** (365/365 total tests pass)
|
|
73
|
+
|
|
74
|
+
### 5. Documentation
|
|
75
|
+
|
|
76
|
+
✅ **README** (`src/decision-ledger/README.md`)
|
|
77
|
+
- Quick start guide
|
|
78
|
+
- API reference
|
|
79
|
+
- CLI command documentation
|
|
80
|
+
- CI/CD integration examples
|
|
81
|
+
- Design principles
|
|
82
|
+
|
|
83
|
+
✅ **Example Application** (`examples/decision-ledger/`)
|
|
84
|
+
- Complete working example
|
|
85
|
+
- Demonstrates all core features
|
|
86
|
+
- Step-by-step walkthrough
|
|
87
|
+
- Successfully executes and produces expected output
|
|
88
|
+
|
|
89
|
+
## Test Results
|
|
90
|
+
|
|
91
|
+
```
|
|
92
|
+
✓ src/__tests__/decision-ledger.test.ts (17 tests) 13ms
|
|
93
|
+
|
|
94
|
+
Test Files 24 passed (24)
|
|
95
|
+
Tests 365 passed (365)
|
|
96
|
+
Duration 2.21s
|
|
97
|
+
```
|
|
98
|
+
|
|
99
|
+
## Type Safety
|
|
100
|
+
|
|
101
|
+
✅ TypeScript compilation: **PASS**
|
|
102
|
+
✅ All types properly exported from main index
|
|
103
|
+
✅ No implicit any types
|
|
104
|
+
|
|
105
|
+
## Build Status
|
|
106
|
+
|
|
107
|
+
✅ Build successful (tsup)
|
|
108
|
+
- Node ESM output
|
|
109
|
+
- Node CJS output
|
|
110
|
+
- Browser output
|
|
111
|
+
- TypeScript declarations (.d.ts)
|
|
112
|
+
|
|
113
|
+
## Integration Points
|
|
114
|
+
|
|
115
|
+
### With Existing Praxis Components
|
|
116
|
+
|
|
117
|
+
1. **Rules and Constraints** (`src/core/rules.ts`)
|
|
118
|
+
- Contracts stored in `meta` field of `RuleDescriptor` and `ConstraintDescriptor`
|
|
119
|
+
- Non-breaking change, fully backward compatible
|
|
120
|
+
|
|
121
|
+
2. **DSL Helpers** (`src/dsl/index.ts`)
|
|
122
|
+
- `defineContract()` follows same pattern as `defineRule()` and `defineConstraint()`
|
|
123
|
+
- Consistent API surface
|
|
124
|
+
|
|
125
|
+
3. **CLI** (`src/cli/index.ts`)
|
|
126
|
+
- New `validate` command follows Commander.js patterns
|
|
127
|
+
- Consistent with existing commands
|
|
128
|
+
|
|
129
|
+
4. **Main Exports** (`src/index.ts`)
|
|
130
|
+
- All Decision Ledger types and functions exported
|
|
131
|
+
- Discoverable through main package import
|
|
132
|
+
|
|
133
|
+
## Assumptions Validated
|
|
134
|
+
|
|
135
|
+
All 5 assumptions from the behavior ledger have been validated:
|
|
136
|
+
|
|
137
|
+
1. ✅ **A1: Contract Storage** - Contracts successfully stored in `meta` field
|
|
138
|
+
2. ✅ **A2: JSON Serialization** - All types JSON-serializable, tested in ledger export/import
|
|
139
|
+
3. ✅ **A3: CLI Pattern** - Validate command follows Commander.js pattern
|
|
140
|
+
4. ✅ **A4: Test Framework** - Tests use Vitest with describe/it/expect
|
|
141
|
+
5. ✅ **A5: Optional Contracts** - Contracts optional by default, strict mode opt-in
|
|
142
|
+
|
|
143
|
+
## Behavior Coverage
|
|
144
|
+
|
|
145
|
+
All examples from the behavior ledger are implemented and tested:
|
|
146
|
+
|
|
147
|
+
- ✅ Example 1: Defining a Contract for a Rule
|
|
148
|
+
- ✅ Example 2: Build-time Validation
|
|
149
|
+
- ✅ Example 3: Runtime Validation
|
|
150
|
+
- ✅ Example 4: Contract Gap Acknowledgment
|
|
151
|
+
|
|
152
|
+
All invariants are enforced:
|
|
153
|
+
|
|
154
|
+
- ✅ Contract Immutability (tested)
|
|
155
|
+
- ✅ Ledger Append-Only (tested)
|
|
156
|
+
- ✅ Assumption Traceability (implemented)
|
|
157
|
+
- ✅ Example Completeness (enforced in `defineContract()`)
|
|
158
|
+
- ✅ Validation Determinism (tested)
|
|
159
|
+
|
|
160
|
+
## Example Output
|
|
161
|
+
|
|
162
|
+
The decision-ledger example successfully demonstrates:
|
|
163
|
+
|
|
164
|
+
```
|
|
165
|
+
Contract Validation Report
|
|
166
|
+
==================================================
|
|
167
|
+
|
|
168
|
+
Total: 3
|
|
169
|
+
Complete: 2
|
|
170
|
+
Incomplete: 1
|
|
171
|
+
Missing: 1
|
|
172
|
+
|
|
173
|
+
✓ Complete Contracts:
|
|
174
|
+
✓ auth.login (v1.0.0)
|
|
175
|
+
✓ cart.addItem (v1.0.0)
|
|
176
|
+
|
|
177
|
+
✗ Incomplete Contracts:
|
|
178
|
+
⚠ legacy.process - Missing: contract
|
|
179
|
+
```
|
|
180
|
+
|
|
181
|
+
## Security Considerations
|
|
182
|
+
|
|
183
|
+
- No secrets or sensitive data in contracts
|
|
184
|
+
- All validation is deterministic and side-effect-free
|
|
185
|
+
- SARIF output compatible with GitHub Security scanning
|
|
186
|
+
- No network dependencies
|
|
187
|
+
|
|
188
|
+
## Performance Characteristics
|
|
189
|
+
|
|
190
|
+
- Validation is O(n) where n = number of rules/constraints
|
|
191
|
+
- Ledger queries are O(n) for full scans, O(1) for ID lookups
|
|
192
|
+
- JSON serialization/deserialization is efficient
|
|
193
|
+
- No memory leaks detected in tests
|
|
194
|
+
|
|
195
|
+
## Future Enhancements
|
|
196
|
+
|
|
197
|
+
While the implementation is complete, potential future enhancements could include:
|
|
198
|
+
|
|
199
|
+
1. **Schema-based contract generation** - Auto-generate contracts from schemas
|
|
200
|
+
2. **Test generation from examples** - Generate test stubs from Given/When/Then
|
|
201
|
+
3. **Assumption validation** - Check if assumptions are still valid
|
|
202
|
+
4. **Contract coverage metrics** - Detailed metrics and trends
|
|
203
|
+
5. **Integration with TLA+ model checker** - Automated property verification
|
|
204
|
+
|
|
205
|
+
## Conclusion
|
|
206
|
+
|
|
207
|
+
The Decision Ledger Integration is **production-ready** and provides:
|
|
208
|
+
|
|
209
|
+
- ✅ Contract-based documentation for rules and constraints
|
|
210
|
+
- ✅ Build-time and runtime validation
|
|
211
|
+
- ✅ Immutable behavior ledger with version tracking
|
|
212
|
+
- ✅ CLI integration with CI/CD support
|
|
213
|
+
- ✅ Comprehensive test coverage
|
|
214
|
+
- ✅ Complete documentation and examples
|
|
215
|
+
- ✅ Backward compatibility with existing Praxis code
|
|
216
|
+
|
|
217
|
+
The implementation follows the behavior-first approach with a complete behavior ledger, TLA+ specification, tests, and implementation code—all traceable to the canonical behavior specification.
|