@plures/praxis 1.2.13 → 1.3.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.
Files changed (93) hide show
  1. package/README.md +44 -0
  2. package/dist/browser/chunk-MJK3IYTJ.js +384 -0
  3. package/dist/browser/{chunk-K377RW4V.js → chunk-N63K4KWS.js} +1 -1
  4. package/dist/browser/{engine-YJZV4SLD.js → engine-YIEGSX7U.js} +1 -1
  5. package/dist/browser/index.d.ts +104 -2
  6. package/dist/browser/index.js +188 -7
  7. package/dist/browser/integrations/svelte.d.ts +2 -2
  8. package/dist/browser/integrations/svelte.js +2 -2
  9. package/dist/browser/{reactive-engine.svelte-9aS0kTa8.d.ts → reactive-engine.svelte-DjynI82A.d.ts} +139 -5
  10. package/dist/node/{chunk-PRPQO6R5.js → chunk-5JQJZADT.js} +1 -1
  11. package/dist/node/chunk-KMJWAFZV.js +389 -0
  12. package/dist/node/{chunk-5RH7UAQC.js → chunk-PTH6MD6P.js} +1 -0
  13. package/dist/node/cli/index.cjs +1553 -839
  14. package/dist/node/cli/index.js +39 -2
  15. package/dist/node/cloud/index.d.cts +1 -1
  16. package/dist/node/cloud/index.d.ts +1 -1
  17. package/dist/node/components/index.d.cts +2 -2
  18. package/dist/node/components/index.d.ts +2 -2
  19. package/dist/node/conversations-KQBXTP3N.js +596 -0
  20. package/dist/node/{engine-2DQBKBJC.js → engine-FEN5IYZ5.js} +1 -1
  21. package/dist/node/index.cjs +911 -43
  22. package/dist/node/index.d.cts +574 -7
  23. package/dist/node/index.d.ts +574 -7
  24. package/dist/node/index.js +672 -26
  25. package/dist/node/integrations/svelte.cjs +190 -3
  26. package/dist/node/integrations/svelte.d.cts +3 -3
  27. package/dist/node/integrations/svelte.d.ts +3 -3
  28. package/dist/node/integrations/svelte.js +2 -2
  29. package/dist/node/{protocol-Qek7ebBl.d.ts → protocol-DcyGMmWY.d.cts} +8 -1
  30. package/dist/node/{protocol-Qek7ebBl.d.cts → protocol-DcyGMmWY.d.ts} +8 -1
  31. package/dist/node/{reactive-engine.svelte-CRNqHlbv.d.ts → reactive-engine.svelte-Cg0Yc2Hs.d.cts} +145 -6
  32. package/dist/node/{reactive-engine.svelte-BFIZfawz.d.cts → reactive-engine.svelte-DekxqFu0.d.ts} +145 -6
  33. package/dist/node/{terminal-adapter-B-UK_Vdz.d.ts → terminal-adapter-CvIvgTo4.d.ts} +1 -1
  34. package/dist/node/{terminal-adapter-BQSIF5bf.d.cts → terminal-adapter-Db-snPJ3.d.cts} +1 -1
  35. package/dist/node/{validate-CNHUULQE.js → validate-EN3M4FUR.js} +1 -1
  36. package/dist/node/{verify-KLJRXVJS.js → verify-7VZRP2WS.js} +2 -2
  37. package/docs/BOT_UPDATE_POLICY.md +125 -0
  38. package/docs/DOGFOODING_CHECKLIST.md +254 -0
  39. package/docs/DOGFOODING_INDEX.md +169 -0
  40. package/docs/DOGFOODING_QUICK_START.md +140 -0
  41. package/docs/KNO_ENG_EXTRACTION_PLAN.md +577 -0
  42. package/docs/PLURES_TOOLS_INVENTORY.md +170 -0
  43. package/docs/README.md +12 -0
  44. package/docs/TESTING_BOT_WORKFLOWS.md +154 -0
  45. package/docs/conversations/INTEGRATION_POINTS.md +719 -0
  46. package/docs/conversations/README.md +168 -0
  47. package/docs/core/extending-praxis-core.md +604 -0
  48. package/docs/core/praxis-core-api.md +385 -0
  49. package/docs/decision-ledger/contract-index.json +2 -2
  50. package/docs/decision-ledger/decisions/2026-02-01-monorepo-organization.md +130 -0
  51. package/docs/examples/DOGFOODING_WORKFLOW_EXAMPLE.md +295 -0
  52. package/docs/examples/README.md +41 -0
  53. package/docs/workflows/pr-overlap-guard.md +50 -0
  54. package/package.json +8 -3
  55. package/src/__tests__/chronicle.test.ts +512 -0
  56. package/src/__tests__/conversations.test.ts +312 -0
  57. package/src/__tests__/edge-cases.test.ts +1 -1
  58. package/src/__tests__/engine-dx.test.ts +355 -0
  59. package/src/__tests__/engine-v2.test.ts +532 -0
  60. package/src/cli/commands/conversations.ts +252 -0
  61. package/src/cli/index.ts +73 -0
  62. package/src/conversations/README.md +230 -0
  63. package/src/conversations/candidate.schema.json +123 -0
  64. package/src/conversations/candidates.ts +114 -0
  65. package/src/conversations/capture.ts +56 -0
  66. package/src/conversations/classify.ts +110 -0
  67. package/src/conversations/conversation.schema.json +106 -0
  68. package/src/conversations/emitters/fs.ts +65 -0
  69. package/src/conversations/emitters/github.ts +115 -0
  70. package/src/conversations/gate.ts +102 -0
  71. package/src/conversations/index.ts +28 -0
  72. package/src/conversations/normalize.ts +51 -0
  73. package/src/conversations/redact.ts +57 -0
  74. package/src/conversations/types.ts +96 -0
  75. package/src/core/chronicle/chronicle.ts +227 -0
  76. package/src/core/chronicle/context.ts +80 -0
  77. package/src/core/chronicle/index.ts +53 -0
  78. package/src/core/chronicle/mcp.ts +135 -0
  79. package/src/core/chronicle/types.ts +61 -0
  80. package/src/core/completeness.ts +274 -0
  81. package/src/core/engine.ts +143 -3
  82. package/src/core/pluresdb/index.ts +22 -0
  83. package/src/core/pluresdb/store.ts +171 -8
  84. package/src/core/protocol.ts +7 -0
  85. package/src/core/rule-result.ts +130 -0
  86. package/src/core/rules.ts +24 -5
  87. package/src/core/ui-rules.ts +340 -0
  88. package/src/dsl/index.ts +6 -0
  89. package/src/index.ts +45 -0
  90. package/src/integrations/pluresdb.ts +22 -0
  91. package/src/vite/completeness-plugin.ts +72 -0
  92. package/dist/browser/chunk-VOMLVI6V.js +0 -197
  93. package/dist/node/chunk-VOMLVI6V.js +0 -197
@@ -1,4 +1,4 @@
1
- import { P as PraxisState, a as PraxisEvent, b as PraxisFact, c as PraxisStepResult, d as PraxisStepConfig } from './protocol-Qek7ebBl.cjs';
1
+ import { b as PraxisFact, P as PraxisState, a as PraxisEvent, c as PraxisStepResult, d as PraxisStepConfig, e as PraxisDiagnostics } from './protocol-DcyGMmWY.js';
2
2
 
3
3
  /**
4
4
  * Decision Ledger - Contract Types
@@ -162,6 +162,83 @@ interface ValidationReport {
162
162
  timestamp: string;
163
163
  }
164
164
 
165
+ /**
166
+ * The result of evaluating a rule. Every rule MUST return one of:
167
+ * - `RuleResult.emit(facts)` — rule produced facts
168
+ * - `RuleResult.noop(reason?)` — rule evaluated but had nothing to say
169
+ * - `RuleResult.skip(reason?)` — rule decided to skip (preconditions not met)
170
+ * - `RuleResult.retract(tags)` — rule retracts previously emitted facts
171
+ */
172
+ declare class RuleResult {
173
+ /** The kind of result */
174
+ readonly kind: 'emit' | 'noop' | 'skip' | 'retract';
175
+ /** Facts produced (only for 'emit') */
176
+ readonly facts: PraxisFact[];
177
+ /** Fact tags to retract (only for 'retract') */
178
+ readonly retractTags: string[];
179
+ /** Optional reason (for noop/skip/retract — useful for debugging) */
180
+ readonly reason?: string;
181
+ /** The rule ID that produced this result (set by engine) */
182
+ ruleId?: string;
183
+ private constructor();
184
+ /**
185
+ * Rule produced facts.
186
+ *
187
+ * @example
188
+ * return RuleResult.emit([
189
+ * { tag: 'sprint.behind', payload: { deficit: 5 } }
190
+ * ]);
191
+ */
192
+ static emit(facts: PraxisFact[]): RuleResult;
193
+ /**
194
+ * Rule evaluated but had nothing to report.
195
+ * Unlike returning [], this is explicit and traceable.
196
+ *
197
+ * @example
198
+ * if (ctx.completedHours >= expectedHours) {
199
+ * return RuleResult.noop('Sprint is on pace');
200
+ * }
201
+ */
202
+ static noop(reason?: string): RuleResult;
203
+ /**
204
+ * Rule decided to skip because preconditions were not met.
205
+ * Distinct from noop: skip means "I can't evaluate", noop means "I evaluated and found nothing".
206
+ *
207
+ * @example
208
+ * if (!ctx.sprintName) {
209
+ * return RuleResult.skip('No active sprint');
210
+ * }
211
+ */
212
+ static skip(reason?: string): RuleResult;
213
+ /**
214
+ * Rule retracts previously emitted facts by tag.
215
+ * Used when a condition that previously produced facts is no longer true.
216
+ *
217
+ * @example
218
+ * // Sprint was behind, but caught up
219
+ * if (ctx.completedHours >= expectedHours) {
220
+ * return RuleResult.retract(['sprint.behind'], 'Sprint caught up');
221
+ * }
222
+ */
223
+ static retract(tags: string[], reason?: string): RuleResult;
224
+ /** Whether this result produced facts */
225
+ get hasFacts(): boolean;
226
+ /** Whether this result retracts facts */
227
+ get hasRetractions(): boolean;
228
+ }
229
+ /**
230
+ * A rule function that returns a typed RuleResult.
231
+ * New API — replaces the old PraxisFact[] return type.
232
+ */
233
+ type TypedRuleFn<TContext = unknown> = (state: PraxisState & {
234
+ context: TContext;
235
+ events: PraxisEvent[];
236
+ }, events: PraxisEvent[]) => RuleResult;
237
+ /**
238
+ * Convenience: create a fact object (just a shorthand)
239
+ */
240
+ declare function fact(tag: string, payload: unknown): PraxisFact;
241
+
165
242
  /**
166
243
  * Rules and Constraints System
167
244
  *
@@ -182,13 +259,20 @@ type ConstraintId = string;
182
259
  * A rule function derives new facts or transitions from context + input facts/events.
183
260
  * Rules must be pure - no side effects.
184
261
  *
185
- * @param state Current Praxis state
186
- * @param events Events to process
187
- * @returns Array of new facts to add to the state
262
+ * Returns either:
263
+ * - `RuleResult` (new API — typed, traceable, supports retraction)
264
+ * - `PraxisFact[]` (legacy backward compatible, will be deprecated)
265
+ *
266
+ * The state parameter includes `events` — the current batch being processed.
267
+ *
268
+ * @param state Current Praxis state (includes state.events for current batch)
269
+ * @param events Events to process (same as state.events, provided for convenience)
270
+ * @returns RuleResult or array of new facts
188
271
  */
189
272
  type RuleFn<TContext = unknown> = (state: PraxisState & {
190
273
  context: TContext;
191
- }, events: PraxisEvent[]) => PraxisFact[];
274
+ events: PraxisEvent[];
275
+ }, events: PraxisEvent[]) => RuleResult | PraxisFact[];
192
276
  /**
193
277
  * A constraint function checks that an invariant holds.
194
278
  * Constraints must be pure - no side effects.
@@ -209,6 +293,18 @@ interface RuleDescriptor<TContext = unknown> {
209
293
  description: string;
210
294
  /** Implementation function */
211
295
  impl: RuleFn<TContext>;
296
+ /**
297
+ * Optional event type filter — only evaluate this rule when at least one
298
+ * event in the batch has a matching `tag`. When omitted, the rule runs on
299
+ * every step (catch-all).
300
+ *
301
+ * Accepts a single tag string or an array of tags.
302
+ *
303
+ * @example
304
+ * { id: 'sprint-behind', eventTypes: ['sprint.update'], impl: ... }
305
+ * { id: 'note-check', eventTypes: 'note.update', impl: ... }
306
+ */
307
+ eventTypes?: string | string[];
212
308
  /** Optional contract for rule behavior */
213
309
  contract?: Contract;
214
310
  /** Optional metadata */
@@ -337,6 +433,20 @@ interface PraxisEngineOptions<TContext = unknown> {
337
433
  initialFacts?: PraxisFact[];
338
434
  /** Initial metadata (optional) */
339
435
  initialMeta?: Record<string, unknown>;
436
+ /**
437
+ * Fact deduplication strategy (default: 'last-write-wins').
438
+ *
439
+ * - 'none': facts accumulate without dedup (original behavior)
440
+ * - 'last-write-wins': only keep the latest fact per tag (most common)
441
+ * - 'append': keep all facts but cap at maxFacts
442
+ */
443
+ factDedup?: 'none' | 'last-write-wins' | 'append';
444
+ /**
445
+ * Maximum number of facts to retain (default: 1000).
446
+ * When exceeded, oldest facts are evicted (FIFO).
447
+ * Set to 0 for unlimited (not recommended).
448
+ */
449
+ maxFacts?: number;
340
450
  }
341
451
  /**
342
452
  * The Praxis Logic Engine
@@ -347,6 +457,8 @@ interface PraxisEngineOptions<TContext = unknown> {
347
457
  declare class LogicEngine<TContext = unknown> {
348
458
  private state;
349
459
  private readonly registry;
460
+ private readonly factDedup;
461
+ private readonly maxFacts;
350
462
  constructor(options: PraxisEngineOptions<TContext>);
351
463
  /**
352
464
  * Get the current state (immutable copy)
@@ -385,6 +497,23 @@ declare class LogicEngine<TContext = unknown> {
385
497
  * @param updater Function that produces new context from old context
386
498
  */
387
499
  updateContext(updater: (context: TContext) => TContext): void;
500
+ /**
501
+ * Atomically update context AND process events in a single call.
502
+ *
503
+ * This avoids the fragile pattern of calling updateContext() then step()
504
+ * separately, where rules could see stale context if the ordering is wrong.
505
+ *
506
+ * @param updater Function that produces new context from old context
507
+ * @param events Events to process after context is updated
508
+ * @returns Result with new state and diagnostics
509
+ *
510
+ * @example
511
+ * engine.stepWithContext(
512
+ * ctx => ({ ...ctx, sprintName: sprint.name, items: sprint.items }),
513
+ * [{ tag: 'sprint.update', payload: { name: sprint.name } }]
514
+ * );
515
+ */
516
+ stepWithContext(updater: (context: TContext) => TContext, events: PraxisEvent[]): PraxisStepResult;
388
517
  /**
389
518
  * Add facts directly (for exceptional cases).
390
519
  * Generally, facts should be added through rules.
@@ -392,6 +521,16 @@ declare class LogicEngine<TContext = unknown> {
392
521
  * @param facts Facts to add
393
522
  */
394
523
  addFacts(facts: PraxisFact[]): void;
524
+ /**
525
+ * Check all constraints without processing any events.
526
+ *
527
+ * Useful for validation-only scenarios (e.g., form validation,
528
+ * pre-save checks) where you want constraint diagnostics without
529
+ * triggering any rules.
530
+ *
531
+ * @returns Array of constraint violation diagnostics (empty = all passing)
532
+ */
533
+ checkConstraints(): PraxisDiagnostics[];
395
534
  /**
396
535
  * Clear all facts
397
536
  */
@@ -495,4 +634,4 @@ declare class ReactiveLogicEngine<TContext extends object> {
495
634
  */
496
635
  declare function createReactiveEngine<TContext extends object>(options: ReactiveEngineOptions<TContext>): ReactiveLogicEngine<TContext>;
497
636
 
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 };
637
+ 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, type ReactiveEngineOptions as R, type Severity as S, type TypedRuleFn as T, type ValidationReport as V, ReactiveLogicEngine as a, type RuleDescriptor as b, createReactiveEngine as c, type ConstraintFn as d, type Contract as e, type RuleFn as f, type PraxisModule as g, type ConstraintId as h, type ContractGap as i, type PraxisEngineOptions as j, type Reference as k, type RuleId as l, RuleResult as m, createPraxisEngine as n, defineContract as o, fact as p, getContract as q, isContract as r };
@@ -320,4 +320,4 @@ declare function createMockExecutor(responses: Record<string, {
320
320
  error?: string;
321
321
  }>): CommandExecutor;
322
322
 
323
- export { type CommandExecutor as C, InMemoryPraxisDB as I, type PraxisDB as P, TerminalAdapter as T, type UnsubscribeFn as U, type TerminalExecutionResult as a, type TerminalNodeState as b, createTerminalAdapter as c, type TerminalAdapterOptions as d, createMockExecutor as e, type PluresDBInstance as f, type PluresDBAdapterConfig as g, type PraxisLocalFirstOptions as h, createInMemoryDB as i, PluresDBPraxisAdapter as j, createPluresDB as k, createPraxisLocalFirst as l, runTerminalCommand as r };
323
+ export { type CommandExecutor as C, InMemoryPraxisDB as I, type PraxisDB as P, TerminalAdapter as T, type UnsubscribeFn as U, type PluresDBAdapterConfig as a, type PluresDBInstance as b, createTerminalAdapter as c, PluresDBPraxisAdapter as d, type PraxisLocalFirstOptions as e, type TerminalAdapterOptions as f, type TerminalExecutionResult as g, type TerminalNodeState as h, createInMemoryDB as i, createMockExecutor as j, createPluresDB as k, createPraxisLocalFirst as l, runTerminalCommand as r };
@@ -320,4 +320,4 @@ declare function createMockExecutor(responses: Record<string, {
320
320
  error?: string;
321
321
  }>): CommandExecutor;
322
322
 
323
- export { type CommandExecutor as C, InMemoryPraxisDB as I, type PraxisDB as P, TerminalAdapter as T, type UnsubscribeFn as U, type TerminalExecutionResult as a, type TerminalNodeState as b, createTerminalAdapter as c, type TerminalAdapterOptions as d, createMockExecutor as e, type PluresDBInstance as f, type PluresDBAdapterConfig as g, type PraxisLocalFirstOptions as h, createInMemoryDB as i, PluresDBPraxisAdapter as j, createPluresDB as k, createPraxisLocalFirst as l, runTerminalCommand as r };
323
+ export { type CommandExecutor as C, InMemoryPraxisDB as I, type PraxisDB as P, TerminalAdapter as T, type UnsubscribeFn as U, type PluresDBAdapterConfig as a, type PluresDBInstance as b, createTerminalAdapter as c, PluresDBPraxisAdapter as d, type PraxisLocalFirstOptions as e, type TerminalAdapterOptions as f, type TerminalExecutionResult as g, type TerminalNodeState as h, createInMemoryDB as i, createMockExecutor as j, createPluresDB as k, createPraxisLocalFirst as l, runTerminalCommand as r };
@@ -4,7 +4,7 @@ import {
4
4
  formatValidationReportJSON,
5
5
  formatValidationReportSARIF,
6
6
  validateContracts
7
- } from "./chunk-5RH7UAQC.js";
7
+ } from "./chunk-PTH6MD6P.js";
8
8
  import {
9
9
  writeLogicLedgerEntry
10
10
  } from "./chunk-WZ6B3LZ6.js";
@@ -4,9 +4,9 @@ import {
4
4
  __toESM
5
5
  } from "./chunk-QGM4M3NI.js";
6
6
 
7
- // node_modules/typescript/lib/typescript.js
7
+ // node_modules/.pnpm/typescript@5.9.3/node_modules/typescript/lib/typescript.js
8
8
  var require_typescript = __commonJS({
9
- "node_modules/typescript/lib/typescript.js"(exports, module) {
9
+ "node_modules/.pnpm/typescript@5.9.3/node_modules/typescript/lib/typescript.js"(exports, module) {
10
10
  "use strict";
11
11
  var ts2 = {};
12
12
  ((module2) => {
@@ -0,0 +1,125 @@
1
+ # Bot Update Policy
2
+
3
+ ## Overview
4
+
5
+ This document describes how automated updates (dependency bumps, pin updates, etc.) are managed in the Praxis repository to reduce commit churn and improve reviewability.
6
+
7
+ ## Goals
8
+
9
+ 1. **Batch Updates**: Group related updates together instead of creating many small PRs
10
+ 2. **Improve Auditability**: Require summaries and upstream links for all bot PRs
11
+ 3. **Maintain Tracking**: Keep audit trail even without dedicated GitHub issues
12
+ 4. **Reduce Noise**: Weekly batching instead of continuous small updates
13
+
14
+ ## How It Works
15
+
16
+ ### Dependabot Configuration
17
+
18
+ Dependabot is configured to:
19
+ - Run weekly on Mondays at 09:00 UTC
20
+ - Group updates by ecosystem (npm production, npm dev, github-actions)
21
+ - Limit to 5 open PRs at a time
22
+ - Use consistent labels: `dependencies`, `bot-update`
23
+ - Follow standardized commit message format: `chore(deps): ...`
24
+
25
+ See `.github/dependabot.yml` for full configuration.
26
+
27
+ ### Weekly Pin Bumps
28
+
29
+ The `batch-pin-bumps.yml` workflow:
30
+ - Runs every Monday at 08:00 UTC (before dependabot)
31
+ - Checks for lockfile updates (pnpm-lock.yaml, package-lock.json)
32
+ - Creates a single PR with all pin bumps for the week
33
+ - Uses the standard bot PR template for consistency
34
+
35
+ ### Weekly Activity Log
36
+
37
+ The `bot-weekly-log.yml` workflow:
38
+ - Runs every Monday at 10:00 UTC (after updates run)
39
+ - Collects all bot PRs merged in the past week
40
+ - Creates a weekly activity log in `.github/bot-logs/`
41
+ - Provides audit trail without requiring GitHub issues
42
+ - Commits log directly to main branch
43
+
44
+ ### PR Template
45
+
46
+ All bot PRs use `.github/BOT_PR_TEMPLATE.md` which requires:
47
+ - Brief summary of changes
48
+ - List of updated dependencies/files
49
+ - Links to upstream changelogs or release notes
50
+ - Impact assessment (breaking changes, security, testing)
51
+ - Weekly batch identifier for tracking
52
+
53
+ ## For Repository Maintainers
54
+
55
+ ### Reviewing Bot PRs
56
+
57
+ When reviewing automated PRs:
58
+
59
+ 1. **Check the Summary**: Understand what's being updated
60
+ 2. **Review Upstream Links**: Look for breaking changes or security fixes
61
+ 3. **Verify CI Passes**: Ensure all tests and checks pass
62
+ 4. **Check Impact Assessment**: Pay attention to flagged items
63
+ 5. **Merge Weekly Batches**: Approve and merge to reduce backlog
64
+
65
+ ### Customizing Pin Updates
66
+
67
+ To add custom pin update checks in `batch-pin-bumps.yml`:
68
+
69
+ 1. Edit the "Check for pin updates" step
70
+ 2. Add logic to detect your specific pin files
71
+ 3. Update the summary to describe what changed
72
+ 4. Test with workflow_dispatch before scheduling
73
+
74
+ ### Adjusting Schedule
75
+
76
+ To change update frequency:
77
+
78
+ 1. Edit cron schedules in workflow files
79
+ 2. Update dependabot.yml schedule.interval
80
+ 3. Coordinate timing (pin bumps → dependabot → weekly log)
81
+
82
+ ## For Other Repositories
83
+
84
+ This bot update approach can be adopted by other repositories in the Plures organization:
85
+
86
+ ### Setup Steps
87
+
88
+ 1. Copy `.github/dependabot.yml` and adjust for your ecosystem
89
+ 2. Copy `.github/BOT_PR_TEMPLATE.md`
90
+ 3. Copy `.github/workflows/bot-weekly-log.yml`
91
+ 4. (Optional) Copy `.github/workflows/batch-pin-bumps.yml` and customize
92
+ 5. Create `.github/bot-logs/` directory structure
93
+ 6. Update your README to reference the new bot policy
94
+
95
+ ### Target Repositories
96
+
97
+ As mentioned in the original issue, these repos should adopt this approach:
98
+ - ✅ plures/praxis (this repo)
99
+ - ⬜ plures/nix-openclaw (issues disabled; track here)
100
+ - ⬜ plures/praxis-business
101
+ - ⬜ plures/behavior-ledger-github-cicd
102
+
103
+ ## References
104
+
105
+ - Original Issue: Practice: reduce bot churn (batch pin bumps; prefer PRs; add audit trail)
106
+ - Dependabot Documentation: https://docs.github.com/en/code-security/dependabot
107
+ - GitHub Actions Workflow Syntax: https://docs.github.com/en/actions/using-workflows/workflow-syntax-for-github-actions
108
+
109
+ ## FAQ
110
+
111
+ ### Why weekly instead of daily?
112
+
113
+ Weekly batching significantly reduces PR volume while still keeping dependencies reasonably up-to-date. Security updates can still be handled immediately through manual intervention.
114
+
115
+ ### What if I need an urgent update?
116
+
117
+ You can always create a manual PR for urgent updates. The weekly batching is for routine maintenance only.
118
+
119
+ ### Where do I find the weekly logs?
120
+
121
+ All weekly logs are stored in `.github/bot-logs/` with an index at `.github/bot-logs/INDEX.md`.
122
+
123
+ ### Can I trigger updates manually?
124
+
125
+ Yes! All workflows support `workflow_dispatch` for manual triggering via the GitHub Actions UI.
@@ -0,0 +1,254 @@
1
+ # Dogfooding Checklist
2
+
3
+ This document provides daily, weekly, and monthly checklists to ensure we're actively dogfooding Plures tools and filing issues when friction is discovered.
4
+
5
+ ## Philosophy
6
+
7
+ **Dogfooding = Using + Observing + Reporting**
8
+
9
+ We dogfood to:
10
+ - Find friction before users do
11
+ - Validate our tools work in real scenarios
12
+ - Generate actionable improvements
13
+ - Build empathy with users
14
+
15
+ **Key Principle:** Prefer small, high-signal issues over comprehensive reports. File friction immediately when encountered.
16
+
17
+ ---
18
+
19
+ ## Daily Development Workflow
20
+
21
+ ### Before Starting Work
22
+
23
+ - [ ] **Pull Latest**: Ensure you have the latest changes
24
+ ```bash
25
+ git pull origin main
26
+ ```
27
+
28
+ - [ ] **Build & Validate**: Run the build and validation
29
+ ```bash
30
+ npm run build
31
+ npm run validate:contracts
32
+ ```
33
+
34
+ - [ ] **Check for Failures**: Review any contract validation warnings
35
+ - If warnings exist, assess if they relate to your work
36
+ - File dogfooding issue if validation is unclear or unhelpful
37
+
38
+ ### During Development
39
+
40
+ When adding or modifying rules/constraints:
41
+
42
+ - [ ] **Define Contract**: Create contract via `defineContract()`
43
+ ```typescript
44
+ const myContract = defineContract({
45
+ behavior: "Clear description of what this does",
46
+ examples: [/* Given/When/Then scenarios */],
47
+ invariants: [/* Constraints that must hold */],
48
+ assumptions: [/* Explicit assumptions with confidence */],
49
+ references: [/* Links to docs, issues, discussions */]
50
+ });
51
+ ```
52
+
53
+ - [ ] **Attach Contract**: Add to rule/constraint meta
54
+ ```typescript
55
+ const myRule = defineRule({
56
+ id: 'module.action',
57
+ meta: { contract: myContract },
58
+ // ...
59
+ });
60
+ ```
61
+
62
+ - [ ] **Write Tests**: Cover every Given/When/Then example
63
+ - Name tests to include rule ID for validation tracking
64
+ - Test all invariants explicitly
65
+
66
+ - [ ] **Use Praxis CLI**: Leverage CLI for generation when applicable
67
+ ```bash
68
+ npx praxis generate --schema src/schemas/my-schema.ts
69
+ ```
70
+
71
+ - [ ] **File Friction Immediately**: When you encounter any friction
72
+ - Confusing error message? → File issue
73
+ - Unclear API? → File issue
74
+ - Manual step that should be automated? → File issue
75
+ - Use the dogfooding issue template (see below)
76
+
77
+ ### Before Committing
78
+
79
+ - [ ] **Scan Rules**: Run the rule scanner
80
+ ```bash
81
+ npm run scan:rules
82
+ ```
83
+
84
+ - [ ] **Validate Contracts**: Ensure all contracts are valid
85
+ ```bash
86
+ npm run validate:contracts
87
+ ```
88
+
89
+ - [ ] **Run Tests**: Ensure tests pass
90
+ ```bash
91
+ npm test
92
+ ```
93
+
94
+ - [ ] **TypeCheck**: Verify no type errors
95
+ ```bash
96
+ npm run typecheck
97
+ ```
98
+
99
+ ---
100
+
101
+ ## Weekly Review (Friday or End of Sprint)
102
+
103
+ ### Tool Usage Review
104
+
105
+ - [ ] **Review Plures Tools Usage**: Check which tools were used this week
106
+ - Praxis CLI: What commands did you use?
107
+ - PluresDB: Did you use it in development or tests?
108
+ - State-Docs: Did you generate documentation?
109
+ - CodeCanvas: Did you visualize any schemas?
110
+ - Unum: Did you use distributed features?
111
+
112
+ - [ ] **Identify Gaps**: What could you have used but didn't?
113
+ - File a note or issue about why you didn't use a tool
114
+ - Was it not obvious when to use it?
115
+ - Was it too difficult to set up?
116
+
117
+ - [ ] **Review Filed Issues**: Check dogfooding issues from the week
118
+ - Are they tagged with `dogfood` label?
119
+ - Are they small and actionable?
120
+ - Do they have proper context?
121
+
122
+ ### Contract Coverage Review
123
+
124
+ - [ ] **Run Coverage Check**: Validate contract coverage
125
+ ```bash
126
+ npm run validate:contracts
127
+ ```
128
+
129
+ - [ ] **Review Contract Gaps**: Check for rules without contracts
130
+ - Prioritize high-impact rules
131
+ - File issues for contract gaps if needed
132
+
133
+ - [ ] **Update Documentation**: If contracts changed behavior
134
+ - Update `docs/decision-ledger/BEHAVIOR_LEDGER.md`
135
+ - Update `docs/decision-ledger/LATEST.md`
136
+
137
+ ---
138
+
139
+ ## Monthly Assessment (First Week of Month)
140
+
141
+ ### Strategic Review
142
+
143
+ - [ ] **Review Plures Tools Inventory**
144
+ - Update `docs/PLURES_TOOLS_INVENTORY.md`
145
+ - Reassess adoption status and priorities
146
+ - Update usage levels and integration status
147
+
148
+ - [ ] **Analyze Dogfooding Issues**
149
+ - Group issues by tool/component
150
+ - Identify patterns and systemic problems
151
+ - Prioritize high-impact improvements
152
+
153
+ - [ ] **Measure Adoption Progress**
154
+ - How many new tools were adopted this month?
155
+ - What percentage of development uses dogfooded tools?
156
+ - Are we using tools more effectively?
157
+
158
+ ### Contract Quality Review
159
+
160
+ - [ ] **Contract Drift Analysis**
161
+ - Run ledger snapshot and compare to last month
162
+ - Identify rules with frequent contract changes
163
+ - Assess if changes indicate instability or evolution
164
+
165
+ - [ ] **Test Coverage for Contracts**
166
+ - Ensure all contract examples have corresponding tests
167
+ - Verify invariants are tested
168
+ - Check for untested edge cases
169
+
170
+ ### Documentation Update
171
+
172
+ - [ ] **Update Adoption Status**: Reflect changes in inventory
173
+ - [ ] **Share Learnings**: Document what worked and what didn't
174
+ - [ ] **Update Guidelines**: If new patterns emerge, update CONTRIBUTING.md
175
+
176
+ ---
177
+
178
+ ## Filing Dogfooding Issues
179
+
180
+ ### When to File
181
+
182
+ File an issue **immediately** when you encounter:
183
+ - Confusing error messages or validation output
184
+ - Unclear or missing documentation
185
+ - Manual steps that should be automated
186
+ - Unexpected behavior from tools
187
+ - Difficulty using a feature
188
+ - Missing features that would help
189
+ - Performance issues or slow commands
190
+
191
+ ### How to File
192
+
193
+ 1. **Use the Dogfooding Issue Template**: `.github/ISSUE_TEMPLATE/dogfooding.yml`
194
+ 2. **Be Specific**: Focus on one friction point per issue
195
+ 3. **Provide Context**: Include what you were trying to do
196
+ 4. **Suggest Solutions**: If you have ideas, share them
197
+ 5. **Link to Related Work**: Reference PRs, commits, or conversations
198
+
199
+ ### Example Good Issues
200
+
201
+ ✅ **Good**: "Praxis CLI `validate` command doesn't show which file has the missing contract"
202
+ ❌ **Bad**: "Validation is confusing"
203
+
204
+ ✅ **Good**: "State-Docs generator requires manual configuration - should auto-detect schema files"
205
+ ❌ **Bad**: "State-Docs is hard to use"
206
+
207
+ ✅ **Good**: "No example of using CodeCanvas to visualize a schema with nested objects"
208
+ ❌ **Bad**: "CodeCanvas documentation is incomplete"
209
+
210
+ ---
211
+
212
+ ## Quick Reference
213
+
214
+ ### Essential Commands
215
+
216
+ ```bash
217
+ # Build and validate
218
+ npm run build
219
+ npm run validate:contracts
220
+
221
+ # Scan and check
222
+ npm run scan:rules
223
+ npm test
224
+ npm run typecheck
225
+
226
+ # Generate docs
227
+ npx praxis docs generate
228
+
229
+ # Canvas export
230
+ npx praxis canvas src/schemas/app.schema.ts
231
+ ```
232
+
233
+ ### Where to Find Things
234
+
235
+ - **Tools Inventory**: `docs/PLURES_TOOLS_INVENTORY.md`
236
+ - **Decision Ledger**: `docs/decision-ledger/DOGFOODING.md`
237
+ - **Contributing**: `CONTRIBUTING.md`
238
+ - **Examples**: `examples/` directory
239
+
240
+ ---
241
+
242
+ ## Meta-Dogfooding
243
+
244
+ Even this checklist is dogfooding! If you find:
245
+ - Missing items that should be checked
246
+ - Steps that are unclear
247
+ - Friction in following this checklist
248
+
249
+ **File a dogfooding issue!** Tag it with `dogfood` and `documentation`.
250
+
251
+ ---
252
+
253
+ Last Updated: 2026-02-01
254
+ Maintainer: Praxis Core Team