@plures/praxis 1.2.12 → 1.2.41

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 (85) hide show
  1. package/README.md +63 -0
  2. package/dist/browser/{chunk-VOMLVI6V.js → chunk-BBP2F7TT.js} +70 -1
  3. package/dist/browser/{chunk-K377RW4V.js → chunk-FCEH7WMH.js} +1 -1
  4. package/dist/browser/{engine-YJZV4SLD.js → engine-65QDGCAN.js} +1 -1
  5. package/dist/browser/index.d.ts +104 -2
  6. package/dist/browser/index.js +181 -5
  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-Cqd8Mod2.d.ts} +56 -1
  10. package/dist/node/{chunk-PRPQO6R5.js → chunk-32YFEEML.js} +1 -1
  11. package/dist/node/{chunk-VOMLVI6V.js → chunk-BBP2F7TT.js} +70 -1
  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-7CXQV6RC.js} +1 -1
  21. package/dist/node/index.cjs +408 -3
  22. package/dist/node/index.d.cts +308 -7
  23. package/dist/node/index.d.ts +308 -7
  24. package/dist/node/index.js +336 -6
  25. package/dist/node/integrations/svelte.cjs +70 -1
  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-BocKczNv.d.cts} +1 -1
  30. package/dist/node/{protocol-Qek7ebBl.d.cts → protocol-BocKczNv.d.ts} +1 -1
  31. package/dist/node/{reactive-engine.svelte-CRNqHlbv.d.ts → reactive-engine.svelte-CGe8SpVE.d.cts} +57 -2
  32. package/dist/node/{reactive-engine.svelte-BFIZfawz.d.cts → reactive-engine.svelte-D-xTDxT5.d.ts} +57 -2
  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 +7 -2
  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/cli/commands/conversations.ts +252 -0
  60. package/src/cli/index.ts +73 -0
  61. package/src/conversations/README.md +230 -0
  62. package/src/conversations/candidate.schema.json +123 -0
  63. package/src/conversations/candidates.ts +114 -0
  64. package/src/conversations/capture.ts +56 -0
  65. package/src/conversations/classify.ts +110 -0
  66. package/src/conversations/conversation.schema.json +106 -0
  67. package/src/conversations/emitters/fs.ts +65 -0
  68. package/src/conversations/emitters/github.ts +115 -0
  69. package/src/conversations/gate.ts +102 -0
  70. package/src/conversations/index.ts +28 -0
  71. package/src/conversations/normalize.ts +51 -0
  72. package/src/conversations/redact.ts +57 -0
  73. package/src/conversations/types.ts +96 -0
  74. package/src/core/chronicle/chronicle.ts +227 -0
  75. package/src/core/chronicle/context.ts +80 -0
  76. package/src/core/chronicle/index.ts +53 -0
  77. package/src/core/chronicle/mcp.ts +135 -0
  78. package/src/core/chronicle/types.ts +61 -0
  79. package/src/core/engine.ts +99 -1
  80. package/src/core/pluresdb/index.ts +22 -0
  81. package/src/core/pluresdb/store.ts +162 -5
  82. package/src/core/rules.ts +12 -0
  83. package/src/dsl/index.ts +6 -0
  84. package/src/index.ts +18 -0
  85. package/src/integrations/pluresdb.ts +22 -0
@@ -1,4 +1,4 @@
1
- import { P as PraxisState, a as PraxisEvent, b as PraxisFact, c as PraxisStepResult, d as PraxisStepConfig } from './protocol-Qek7ebBl.js';
1
+ import { P as PraxisState, a as PraxisEvent, b as PraxisFact, c as PraxisStepResult, d as PraxisStepConfig, e as PraxisDiagnostics } from './protocol-BocKczNv.cjs';
2
2
 
3
3
  /**
4
4
  * Decision Ledger - Contract Types
@@ -209,6 +209,18 @@ interface RuleDescriptor<TContext = unknown> {
209
209
  description: string;
210
210
  /** Implementation function */
211
211
  impl: RuleFn<TContext>;
212
+ /**
213
+ * Optional event type filter — only evaluate this rule when at least one
214
+ * event in the batch has a matching `tag`. When omitted, the rule runs on
215
+ * every step (catch-all).
216
+ *
217
+ * Accepts a single tag string or an array of tags.
218
+ *
219
+ * @example
220
+ * { id: 'sprint-behind', eventTypes: ['sprint.update'], impl: ... }
221
+ * { id: 'note-check', eventTypes: 'note.update', impl: ... }
222
+ */
223
+ eventTypes?: string | string[];
212
224
  /** Optional contract for rule behavior */
213
225
  contract?: Contract;
214
226
  /** Optional metadata */
@@ -337,6 +349,20 @@ interface PraxisEngineOptions<TContext = unknown> {
337
349
  initialFacts?: PraxisFact[];
338
350
  /** Initial metadata (optional) */
339
351
  initialMeta?: Record<string, unknown>;
352
+ /**
353
+ * Fact deduplication strategy (default: 'last-write-wins').
354
+ *
355
+ * - 'none': facts accumulate without dedup (original behavior)
356
+ * - 'last-write-wins': only keep the latest fact per tag (most common)
357
+ * - 'append': keep all facts but cap at maxFacts
358
+ */
359
+ factDedup?: 'none' | 'last-write-wins' | 'append';
360
+ /**
361
+ * Maximum number of facts to retain (default: 1000).
362
+ * When exceeded, oldest facts are evicted (FIFO).
363
+ * Set to 0 for unlimited (not recommended).
364
+ */
365
+ maxFacts?: number;
340
366
  }
341
367
  /**
342
368
  * The Praxis Logic Engine
@@ -347,6 +373,8 @@ interface PraxisEngineOptions<TContext = unknown> {
347
373
  declare class LogicEngine<TContext = unknown> {
348
374
  private state;
349
375
  private readonly registry;
376
+ private readonly factDedup;
377
+ private readonly maxFacts;
350
378
  constructor(options: PraxisEngineOptions<TContext>);
351
379
  /**
352
380
  * Get the current state (immutable copy)
@@ -385,6 +413,23 @@ declare class LogicEngine<TContext = unknown> {
385
413
  * @param updater Function that produces new context from old context
386
414
  */
387
415
  updateContext(updater: (context: TContext) => TContext): void;
416
+ /**
417
+ * Atomically update context AND process events in a single call.
418
+ *
419
+ * This avoids the fragile pattern of calling updateContext() then step()
420
+ * separately, where rules could see stale context if the ordering is wrong.
421
+ *
422
+ * @param updater Function that produces new context from old context
423
+ * @param events Events to process after context is updated
424
+ * @returns Result with new state and diagnostics
425
+ *
426
+ * @example
427
+ * engine.stepWithContext(
428
+ * ctx => ({ ...ctx, sprintName: sprint.name, items: sprint.items }),
429
+ * [{ tag: 'sprint.update', payload: { name: sprint.name } }]
430
+ * );
431
+ */
432
+ stepWithContext(updater: (context: TContext) => TContext, events: PraxisEvent[]): PraxisStepResult;
388
433
  /**
389
434
  * Add facts directly (for exceptional cases).
390
435
  * Generally, facts should be added through rules.
@@ -392,6 +437,16 @@ declare class LogicEngine<TContext = unknown> {
392
437
  * @param facts Facts to add
393
438
  */
394
439
  addFacts(facts: PraxisFact[]): void;
440
+ /**
441
+ * Check all constraints without processing any events.
442
+ *
443
+ * Useful for validation-only scenarios (e.g., form validation,
444
+ * pre-save checks) where you want constraint diagnostics without
445
+ * triggering any rules.
446
+ *
447
+ * @returns Array of constraint violation diagnostics (empty = all passing)
448
+ */
449
+ checkConstraints(): PraxisDiagnostics[];
395
450
  /**
396
451
  * Clear all facts
397
452
  */
@@ -495,4 +550,4 @@ declare class ReactiveLogicEngine<TContext extends object> {
495
550
  */
496
551
  declare function createReactiveEngine<TContext extends object>(options: ReactiveEngineOptions<TContext>): ReactiveLogicEngine<TContext>;
497
552
 
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 };
553
+ 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 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, createPraxisEngine as m, defineContract as n, getContract as o, isContract as p };
@@ -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 { P as PraxisState, a as PraxisEvent, b as PraxisFact, c as PraxisStepResult, d as PraxisStepConfig, e as PraxisDiagnostics } from './protocol-BocKczNv.js';
2
2
 
3
3
  /**
4
4
  * Decision Ledger - Contract Types
@@ -209,6 +209,18 @@ interface RuleDescriptor<TContext = unknown> {
209
209
  description: string;
210
210
  /** Implementation function */
211
211
  impl: RuleFn<TContext>;
212
+ /**
213
+ * Optional event type filter — only evaluate this rule when at least one
214
+ * event in the batch has a matching `tag`. When omitted, the rule runs on
215
+ * every step (catch-all).
216
+ *
217
+ * Accepts a single tag string or an array of tags.
218
+ *
219
+ * @example
220
+ * { id: 'sprint-behind', eventTypes: ['sprint.update'], impl: ... }
221
+ * { id: 'note-check', eventTypes: 'note.update', impl: ... }
222
+ */
223
+ eventTypes?: string | string[];
212
224
  /** Optional contract for rule behavior */
213
225
  contract?: Contract;
214
226
  /** Optional metadata */
@@ -337,6 +349,20 @@ interface PraxisEngineOptions<TContext = unknown> {
337
349
  initialFacts?: PraxisFact[];
338
350
  /** Initial metadata (optional) */
339
351
  initialMeta?: Record<string, unknown>;
352
+ /**
353
+ * Fact deduplication strategy (default: 'last-write-wins').
354
+ *
355
+ * - 'none': facts accumulate without dedup (original behavior)
356
+ * - 'last-write-wins': only keep the latest fact per tag (most common)
357
+ * - 'append': keep all facts but cap at maxFacts
358
+ */
359
+ factDedup?: 'none' | 'last-write-wins' | 'append';
360
+ /**
361
+ * Maximum number of facts to retain (default: 1000).
362
+ * When exceeded, oldest facts are evicted (FIFO).
363
+ * Set to 0 for unlimited (not recommended).
364
+ */
365
+ maxFacts?: number;
340
366
  }
341
367
  /**
342
368
  * The Praxis Logic Engine
@@ -347,6 +373,8 @@ interface PraxisEngineOptions<TContext = unknown> {
347
373
  declare class LogicEngine<TContext = unknown> {
348
374
  private state;
349
375
  private readonly registry;
376
+ private readonly factDedup;
377
+ private readonly maxFacts;
350
378
  constructor(options: PraxisEngineOptions<TContext>);
351
379
  /**
352
380
  * Get the current state (immutable copy)
@@ -385,6 +413,23 @@ declare class LogicEngine<TContext = unknown> {
385
413
  * @param updater Function that produces new context from old context
386
414
  */
387
415
  updateContext(updater: (context: TContext) => TContext): void;
416
+ /**
417
+ * Atomically update context AND process events in a single call.
418
+ *
419
+ * This avoids the fragile pattern of calling updateContext() then step()
420
+ * separately, where rules could see stale context if the ordering is wrong.
421
+ *
422
+ * @param updater Function that produces new context from old context
423
+ * @param events Events to process after context is updated
424
+ * @returns Result with new state and diagnostics
425
+ *
426
+ * @example
427
+ * engine.stepWithContext(
428
+ * ctx => ({ ...ctx, sprintName: sprint.name, items: sprint.items }),
429
+ * [{ tag: 'sprint.update', payload: { name: sprint.name } }]
430
+ * );
431
+ */
432
+ stepWithContext(updater: (context: TContext) => TContext, events: PraxisEvent[]): PraxisStepResult;
388
433
  /**
389
434
  * Add facts directly (for exceptional cases).
390
435
  * Generally, facts should be added through rules.
@@ -392,6 +437,16 @@ declare class LogicEngine<TContext = unknown> {
392
437
  * @param facts Facts to add
393
438
  */
394
439
  addFacts(facts: PraxisFact[]): void;
440
+ /**
441
+ * Check all constraints without processing any events.
442
+ *
443
+ * Useful for validation-only scenarios (e.g., form validation,
444
+ * pre-save checks) where you want constraint diagnostics without
445
+ * triggering any rules.
446
+ *
447
+ * @returns Array of constraint violation diagnostics (empty = all passing)
448
+ */
449
+ checkConstraints(): PraxisDiagnostics[];
395
450
  /**
396
451
  * Clear all facts
397
452
  */
@@ -495,4 +550,4 @@ declare class ReactiveLogicEngine<TContext extends object> {
495
550
  */
496
551
  declare function createReactiveEngine<TContext extends object>(options: ReactiveEngineOptions<TContext>): ReactiveLogicEngine<TContext>;
497
552
 
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 };
553
+ 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 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, createPraxisEngine as m, defineContract as n, getContract as o, isContract as p };
@@ -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