@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.
Files changed (63) hide show
  1. package/README.md +10 -96
  2. package/dist/browser/{adapter-TM4IS5KT.js → adapter-CIMBGDC7.js} +5 -3
  3. package/dist/browser/{chunk-LE2ZJYFC.js → chunk-K377RW4V.js} +76 -0
  4. package/dist/{node/chunk-JQ64KMLN.js → browser/chunk-MBVHLOU2.js} +12 -1
  5. package/dist/browser/index.d.ts +32 -5
  6. package/dist/browser/index.js +15 -7
  7. package/dist/browser/integrations/svelte.d.ts +2 -2
  8. package/dist/browser/integrations/svelte.js +1 -1
  9. package/dist/browser/{reactive-engine.svelte-C9OpcTHf.d.ts → reactive-engine.svelte-9aS0kTa8.d.ts} +136 -1
  10. package/dist/node/{adapter-K6DOX6XS.js → adapter-75ISSMWD.js} +5 -3
  11. package/dist/node/chunk-5RH7UAQC.js +486 -0
  12. package/dist/{browser/chunk-JQ64KMLN.js → node/chunk-MBVHLOU2.js} +12 -1
  13. package/dist/node/{chunk-LE2ZJYFC.js → chunk-PRPQO6R5.js} +3 -72
  14. package/dist/node/chunk-R2PSBPKQ.js +150 -0
  15. package/dist/node/chunk-WZ6B3LZ6.js +638 -0
  16. package/dist/node/cli/index.cjs +2316 -832
  17. package/dist/node/cli/index.js +18 -0
  18. package/dist/node/components/index.d.cts +3 -2
  19. package/dist/node/components/index.d.ts +3 -2
  20. package/dist/node/index.cjs +620 -38
  21. package/dist/node/index.d.cts +259 -5
  22. package/dist/node/index.d.ts +259 -5
  23. package/dist/node/index.js +55 -65
  24. package/dist/node/integrations/svelte.cjs +76 -0
  25. package/dist/node/integrations/svelte.d.cts +2 -2
  26. package/dist/node/integrations/svelte.d.ts +2 -2
  27. package/dist/node/integrations/svelte.js +2 -1
  28. package/dist/node/{reactive-engine.svelte-1M4m_C_v.d.cts → reactive-engine.svelte-BFIZfawz.d.cts} +199 -1
  29. package/dist/node/{reactive-engine.svelte-ChNFn4Hj.d.ts → reactive-engine.svelte-CRNqHlbv.d.ts} +199 -1
  30. package/dist/node/reverse-W7THPV45.js +193 -0
  31. package/dist/node/{terminal-adapter-CWka-yL8.d.ts → terminal-adapter-B-UK_Vdz.d.ts} +28 -3
  32. package/dist/node/{terminal-adapter-CDzxoLKR.d.cts → terminal-adapter-BQSIF5bf.d.cts} +28 -3
  33. package/dist/node/validate-CNHUULQE.js +180 -0
  34. package/docs/core/pluresdb-integration.md +15 -15
  35. package/docs/decision-ledger/BEHAVIOR_LEDGER.md +225 -0
  36. package/docs/decision-ledger/DecisionLedger.tla +180 -0
  37. package/docs/decision-ledger/IMPLEMENTATION_SUMMARY.md +217 -0
  38. package/docs/decision-ledger/LATEST.md +166 -0
  39. package/docs/guides/cicd-pipeline.md +142 -0
  40. package/package.json +2 -2
  41. package/src/__tests__/cli-validate.test.ts +197 -0
  42. package/src/__tests__/decision-ledger.test.ts +485 -0
  43. package/src/__tests__/reverse-generator.test.ts +189 -0
  44. package/src/__tests__/scanner.test.ts +215 -0
  45. package/src/cli/commands/reverse.ts +289 -0
  46. package/src/cli/commands/validate.ts +264 -0
  47. package/src/cli/index.ts +47 -0
  48. package/src/core/pluresdb/adapter.ts +45 -2
  49. package/src/core/rules.ts +133 -0
  50. package/src/decision-ledger/README.md +400 -0
  51. package/src/decision-ledger/REVERSE_ENGINEERING.md +484 -0
  52. package/src/decision-ledger/facts-events.ts +121 -0
  53. package/src/decision-ledger/index.ts +70 -0
  54. package/src/decision-ledger/ledger.ts +246 -0
  55. package/src/decision-ledger/logic-ledger.ts +158 -0
  56. package/src/decision-ledger/reverse-generator.ts +426 -0
  57. package/src/decision-ledger/scanner.ts +506 -0
  58. package/src/decision-ledger/types.ts +247 -0
  59. package/src/decision-ledger/validation.ts +336 -0
  60. package/src/dsl/index.ts +13 -2
  61. package/src/index.browser.ts +2 -0
  62. package/src/index.ts +36 -0
  63. package/src/integrations/pluresdb.ts +14 -2
@@ -0,0 +1,400 @@
1
+ # Decision Ledger Integration
2
+
3
+ The Decision Ledger Integration extends Praxis with contract-based validation and documentation for rules and constraints, enabling teams to explicitly document, test, and enforce behavioral contracts.
4
+
5
+ ## Overview
6
+
7
+ Modern software systems—especially those incorporating AI-assisted logic, rules engines, and automated decision-making—lack a reliable, enforceable mechanism to explain, audit, and evolve decision logic over time. The Decision Ledger addresses this gap by providing:
8
+
9
+ 1. **Contract Objects** for rules and constraints with canonical behavior, examples, invariants, assumptions, and references
10
+ 2. **Compliance Pipeline** for build-time and runtime validation
11
+ 3. **First-class Facts** for tracking missing artifacts
12
+ 4. **Immutable Logic Ledger** with assumption invalidation and versioned snapshots
13
+ 5. **Reverse Engineering** for migrating existing codebases to contracts
14
+
15
+ ## Quick Start
16
+
17
+ ### For New Projects
18
+
19
+ Start with contracts from the beginning:
20
+
21
+ ```typescript
22
+ import { defineContract, defineRule } from '@plures/praxis';
23
+
24
+ // Define a contract
25
+ const loginContract = defineContract({
26
+ ruleId: 'auth.login',
27
+ behavior: 'Process login events and create user session facts',
28
+ examples: [
29
+ {
30
+ given: 'User provides valid credentials',
31
+ when: 'LOGIN event is received',
32
+ then: 'UserSessionCreated fact is emitted'
33
+ }
34
+ ],
35
+ invariants: [
36
+ 'Session must have unique ID',
37
+ 'Session must have timestamp'
38
+ ],
39
+ assumptions: [
40
+ {
41
+ id: 'assume-unique-username',
42
+ statement: 'Usernames are unique across the system',
43
+ confidence: 0.9,
44
+ justification: 'Standard practice in authentication systems',
45
+ impacts: ['spec', 'tests'],
46
+ status: 'active'
47
+ }
48
+ ],
49
+ references: [
50
+ { type: 'doc', url: 'https://docs.example.com/auth' }
51
+ ]
52
+ });
53
+
54
+ // Attach contract to rule
55
+ const loginRule = defineRule({
56
+ id: 'auth.login',
57
+ description: 'Process login events',
58
+ impl: (state, events) => {
59
+ // Implementation
60
+ return [];
61
+ },
62
+ meta: { contract: loginContract }
63
+ });
64
+ ```
65
+
66
+ ### For Existing Projects (Reverse Engineering)
67
+
68
+ Automatically generate contracts from existing code:
69
+
70
+ ```bash
71
+ # Scan your codebase and generate contracts
72
+ praxis reverse
73
+
74
+ # With interactive review
75
+ praxis reverse --interactive
76
+
77
+ # Using AI for better quality
78
+ export OPENAI_API_KEY="your-key"
79
+ praxis reverse --ai openai
80
+
81
+ # See REVERSE_ENGINEERING.md for complete guide
82
+ ```
83
+
84
+ ### Build-time Validation
85
+
86
+ ```bash
87
+ # Validate contracts in your registry
88
+ praxis validate
89
+
90
+ # Output as JSON
91
+ praxis validate --output json
92
+
93
+ # Output as SARIF (for CI/CD integration)
94
+ praxis validate --output sarif
95
+
96
+ # Strict mode (exit with error if contracts missing)
97
+ praxis validate --strict
98
+ ```
99
+
100
+ Example output:
101
+
102
+ ```
103
+ Contract Validation Report
104
+ ==================================================
105
+
106
+ Total: 5
107
+ Complete: 3
108
+ Incomplete: 1
109
+ Missing: 1
110
+
111
+ ✓ Complete Contracts:
112
+ ✓ auth.login (v1.0.0)
113
+ ✓ auth.logout (v1.0.0)
114
+ ✓ cart.checkout (v1.0.0)
115
+
116
+ ✗ Incomplete Contracts:
117
+ ⚠ cart.addItem - Missing: tests
118
+ Contract is incomplete: missing tests
119
+
120
+ ✗ No Contract:
121
+ ✗ order.process
122
+ ```
123
+
124
+ ### Runtime Validation
125
+
126
+ ```typescript
127
+ import { validateContracts } from '@plures/praxis';
128
+
129
+ const registry = new PraxisRegistry();
130
+ // ... register rules with contracts
131
+
132
+ const report = validateContracts(registry, {
133
+ strict: true,
134
+ requiredFields: ['behavior', 'examples']
135
+ });
136
+
137
+ console.log(`Complete: ${report.complete.length}`);
138
+ console.log(`Incomplete: ${report.incomplete.length}`);
139
+ console.log(`Missing: ${report.missing.length}`);
140
+ ```
141
+
142
+ ### Contract Gap Acknowledgment
143
+
144
+ ```typescript
145
+ import { AcknowledgeContractGap } from '@plures/praxis';
146
+
147
+ // Acknowledge a known gap with justification
148
+ const event = AcknowledgeContractGap.create({
149
+ ruleId: 'legacy.process',
150
+ missing: ['spec', 'tests'],
151
+ justification: 'Legacy rule to be deprecated in v2.0',
152
+ expiresAt: '2025-12-31'
153
+ });
154
+ ```
155
+
156
+ ### Behavior Ledger
157
+
158
+ ```typescript
159
+ import { createBehaviorLedger, defineContract } from '@plures/praxis';
160
+
161
+ const ledger = createBehaviorLedger();
162
+
163
+ // Append a contract to the ledger
164
+ ledger.append({
165
+ id: 'entry-1',
166
+ timestamp: new Date().toISOString(),
167
+ status: 'active',
168
+ author: 'team',
169
+ contract: loginContract
170
+ });
171
+
172
+ // Update contract (supersedes previous entry)
173
+ const updatedContract = defineContract({
174
+ ruleId: 'auth.login',
175
+ behavior: 'Updated behavior description',
176
+ examples: [...],
177
+ invariants: [...],
178
+ version: '2.0.0'
179
+ });
180
+
181
+ ledger.append({
182
+ id: 'entry-2',
183
+ timestamp: new Date().toISOString(),
184
+ status: 'active',
185
+ author: 'team',
186
+ contract: updatedContract,
187
+ supersedes: 'entry-1',
188
+ reason: 'behavior-updated'
189
+ });
190
+
191
+ // Query ledger
192
+ const latest = ledger.getLatestEntry('auth.login');
193
+ const history = ledger.getEntriesForRule('auth.login');
194
+ const activeAssumptions = ledger.getActiveAssumptions();
195
+
196
+ // Export/import
197
+ const json = ledger.toJSON();
198
+ const restored = BehaviorLedger.fromJSON(json);
199
+ ```
200
+
201
+ ## API Reference
202
+
203
+ ### Types
204
+
205
+ ```typescript
206
+ interface Contract {
207
+ ruleId: string;
208
+ behavior: string;
209
+ examples: Example[];
210
+ invariants: string[];
211
+ assumptions?: Assumption[];
212
+ references?: Reference[];
213
+ version?: string;
214
+ timestamp?: string;
215
+ }
216
+
217
+ interface Example {
218
+ given: string;
219
+ when: string;
220
+ then: string;
221
+ }
222
+
223
+ interface Assumption {
224
+ id: string;
225
+ statement: string;
226
+ confidence: number; // 0.0 to 1.0
227
+ justification: string;
228
+ derivedFrom?: string;
229
+ impacts: Array<'spec' | 'tests' | 'code'>;
230
+ status: 'active' | 'revised' | 'invalidated';
231
+ }
232
+
233
+ interface Reference {
234
+ type: string;
235
+ url?: string;
236
+ description?: string;
237
+ }
238
+ ```
239
+
240
+ ### Functions
241
+
242
+ #### `defineContract(options: DefineContractOptions): Contract`
243
+
244
+ Creates a contract for a rule or constraint.
245
+
246
+ #### `validateContracts(registry: PraxisRegistry, options?: ValidateOptions): ValidationReport`
247
+
248
+ Validates all rules and constraints in a registry.
249
+
250
+ #### `formatValidationReport(report: ValidationReport): string`
251
+
252
+ Formats a validation report as human-readable text.
253
+
254
+ #### `formatValidationReportJSON(report: ValidationReport): string`
255
+
256
+ Formats a validation report as JSON.
257
+
258
+ #### `formatValidationReportSARIF(report: ValidationReport): string`
259
+
260
+ Formats a validation report as SARIF (for CI/CD integration).
261
+
262
+ #### `scanRepository(options: ScanOptions): Promise<ScanResult>`
263
+
264
+ Scans a repository to discover existing rules and constraints.
265
+
266
+ #### `generateContractFromRule(descriptor: RuleDescriptor, options: ReverseGenerationOptions): Promise<GenerationResult>`
267
+
268
+ Generates a contract from an existing rule or constraint using AI or heuristics.
269
+
270
+ ### Facts and Events
271
+
272
+ ```typescript
273
+ // Fact: Contract is missing
274
+ const fact = ContractMissing.create({
275
+ ruleId: 'test.rule',
276
+ missing: ['behavior', 'examples'],
277
+ severity: 'warning'
278
+ });
279
+
280
+ // Event: Acknowledge contract gap
281
+ const event = AcknowledgeContractGap.create({
282
+ ruleId: 'legacy.rule',
283
+ missing: ['tests'],
284
+ justification: 'To be deprecated',
285
+ expiresAt: '2025-12-31'
286
+ });
287
+ ```
288
+
289
+ ## CLI Commands
290
+
291
+ ### `praxis validate`
292
+
293
+ Validates contract coverage for rules and constraints.
294
+
295
+ **Options:**
296
+ - `--output <format>` - Output format: `console` (default), `json`, or `sarif`
297
+ - `--strict` - Exit with error if contracts are missing (default: false)
298
+ - `--registry <path>` - Path to registry module (optional)
299
+
300
+ **Examples:**
301
+
302
+ ```bash
303
+ # Basic validation
304
+ praxis validate
305
+
306
+ # JSON output for programmatic processing
307
+ praxis validate --output json
308
+
309
+ # SARIF output for GitHub Actions/CI integration
310
+ praxis validate --output sarif > results.sarif
311
+
312
+ # Strict mode for CI/CD pipelines
313
+ praxis validate --strict
314
+ ```
315
+
316
+ ### `praxis reverse`
317
+
318
+ Reverse engineer contracts from existing codebase.
319
+
320
+ **Options:**
321
+ - `-d, --dir <path>` - Root directory to scan (default: current directory)
322
+ - `--ai <provider>` - AI provider: `none` (default), `github-copilot`, `openai`, `auto`
323
+ - `-o, --output <dir>` - Output directory for contracts (default: `./contracts`)
324
+ - `--ledger` - Write to logic ledger (default: false)
325
+ - `--dry-run` - Preview without writing files (default: false)
326
+ - `-i, --interactive` - Interactive mode, prompt for each (default: false)
327
+ - `--confidence <threshold>` - Confidence threshold 0.0-1.0 (default: 0.7)
328
+ - `--limit <n>` - Max number of rules to process
329
+ - `--author <name>` - Author name for ledger entries (default: 'reverse-engineer')
330
+ - `--format <format>` - Output format: `json` (default), `yaml`
331
+
332
+ **Examples:**
333
+
334
+ ```bash
335
+ # Basic reverse engineering
336
+ praxis reverse
337
+
338
+ # Interactive mode with AI
339
+ praxis reverse --interactive --ai auto
340
+
341
+ # Generate and write to ledger
342
+ praxis reverse --ledger --author "migration-2024"
343
+
344
+ # Preview what would be generated
345
+ praxis reverse --dry-run
346
+
347
+ # Process first 10 rules only
348
+ praxis reverse --limit 10
349
+
350
+ # See REVERSE_ENGINEERING.md for complete guide
351
+ ```
352
+
353
+ ## Integration with CI/CD
354
+
355
+ ### GitHub Actions Example
356
+
357
+ ```yaml
358
+ name: Validate Contracts
359
+
360
+ on: [push, pull_request]
361
+
362
+ jobs:
363
+ validate:
364
+ runs-on: ubuntu-latest
365
+ steps:
366
+ - uses: actions/checkout@v3
367
+ - uses: actions/setup-node@v3
368
+ with:
369
+ node-version: '18'
370
+ - run: npm install
371
+ - run: npm run build
372
+ - name: Validate contracts
373
+ run: npx praxis validate --output sarif > results.sarif
374
+ - name: Upload SARIF
375
+ uses: github/codeql-action/upload-sarif@v2
376
+ with:
377
+ sarif_file: results.sarif
378
+ ```
379
+
380
+ ## Documentation
381
+
382
+ - **Behavior Ledger**: See [docs/decision-ledger/BEHAVIOR_LEDGER.md](../../docs/decision-ledger/BEHAVIOR_LEDGER.md) for the canonical behavior specification
383
+ - **LATEST Snapshot**: See [docs/decision-ledger/LATEST.md](../../docs/decision-ledger/LATEST.md) for the current behavior summary
384
+ - **TLA+ Spec**: See [docs/decision-ledger/DecisionLedger.tla](../../docs/decision-ledger/DecisionLedger.tla) for formal specification
385
+
386
+ ## Design Principles
387
+
388
+ 1. **Contracts are Optional by Default**: Backward compatibility with existing Praxis code
389
+ 2. **Immutable Ledger**: Append-only history; entries can be superseded but never deleted
390
+ 3. **Explicit Assumptions**: All inferred requirements must be documented with confidence levels
391
+ 4. **JSON Serializable**: All types are JSON-friendly for cross-language compatibility
392
+ 5. **Validation is Deterministic**: Same inputs always produce same validation results
393
+
394
+ ## Examples
395
+
396
+ See [src/__tests__/decision-ledger.test.ts](../__tests__/decision-ledger.test.ts) for comprehensive usage examples.
397
+
398
+ ## License
399
+
400
+ MIT