@xhulz/nina 0.53.2 → 0.54.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.
- package/package.json +1 -1
- package/releases/0.53.3/core/GAPS.md +125 -0
- package/releases/0.53.3/core/answered.json +68 -0
- package/releases/0.53.3/core/defaults/tree/.claude/agents/architect.md +1 -0
- package/releases/0.53.3/core/defaults/tree/.claude/agents/dba.md +3 -0
- package/releases/0.53.3/core/defaults/tree/.claude/agents/devops.md +1 -0
- package/releases/0.53.3/core/defaults/tree/.claude/agents/implementer.md +1 -0
- package/releases/0.53.3/core/defaults/tree/.claude/agents/integration-tester.md +3 -0
- package/releases/0.53.3/core/defaults/tree/.claude/agents/qa.md +7 -0
- package/releases/0.53.3/core/defaults/tree/.claude/agents/reviewer.md +3 -0
- package/releases/0.53.3/core/defaults/tree/.claude/agents/secops.md +3 -0
- package/releases/0.53.3/core/defaults/tree/.claude/agents/solidity-auditor.md +3 -0
- package/releases/0.53.3/core/defaults/tree/.claude/agents/solidity-dev.md +3 -0
- package/releases/0.53.3/core/tree/.claude/agents/architect.md +129 -0
- package/releases/0.53.3/core/tree/.claude/agents/dba.md +117 -0
- package/releases/0.53.3/core/tree/.claude/agents/devops.md +118 -0
- package/releases/0.53.3/core/tree/.claude/agents/implementer.md +163 -0
- package/releases/0.53.3/core/tree/.claude/agents/integration-tester.md +168 -0
- package/releases/0.53.3/core/tree/.claude/agents/planner.md +132 -0
- package/releases/0.53.3/core/tree/.claude/agents/qa.md +150 -0
- package/releases/0.53.3/core/tree/.claude/agents/reviewer.md +184 -0
- package/releases/0.53.3/core/tree/.claude/agents/secops.md +120 -0
- package/releases/0.53.3/core/tree/.claude/agents/solidity-auditor.md +126 -0
- package/releases/0.53.3/core/tree/.claude/agents/solidity-dev.md +123 -0
- package/releases/0.53.3/core/tree/.claude/agents-overview.md +64 -0
- package/releases/0.53.3/core/tree/.claude/frontend.md +10 -0
- package/releases/0.53.3/core/tree/.claude/graph.md +75 -0
- package/releases/0.53.3/core/tree/.claude/patterns.md +251 -0
- package/releases/0.53.3/core/tree/.claude/pills/README.md +150 -0
- package/releases/0.53.3/core/tree/.claude/pipeline.md +101 -0
- package/releases/0.53.3/core/tree/.claude/retrieval.md +103 -0
- package/releases/0.53.3/core/tree/.claude/router.md +202 -0
- package/releases/0.53.3/core/tree/.claude/templates/integration.md +46 -0
- package/releases/0.53.3/core/tree/CLAUDE.md +164 -0
- package/releases/0.53.3/core/tree/scripts/cost-watch.mjs +25 -0
- package/releases/0.53.3/core/tree/scripts/edit-guard.mjs +24 -0
- package/releases/0.53.3/core/tree/scripts/harness-check.mjs +71 -0
- package/releases/0.53.3/core/tree/scripts/loop-gate.mjs +19 -0
- package/releases/0.53.3/core/vocabulary.json +13 -0
- package/releases/0.53.3/surfaces/blockchain/tree/.claude/agents/architect.md +5 -0
- package/releases/0.53.3/surfaces/blockchain/tree/.claude/agents/devops.md +5 -0
- package/releases/0.53.3/surfaces/blockchain/tree/.claude/agents/reviewer.md +5 -0
- package/releases/0.53.3/surfaces/blockchain/tree/.claude/agents/solidity-auditor.md +18 -0
- package/releases/0.53.3/surfaces/blockchain/tree/.claude/agents/solidity-dev.md +16 -0
- package/releases/0.53.3/surfaces/blockchain/tree/.claude/agents-overview.md +6 -0
- package/releases/0.53.3/surfaces/blockchain/tree/.claude/graph.md +11 -0
- package/releases/0.53.3/surfaces/blockchain/tree/.claude/router.md +6 -0
- package/releases/0.53.3/surfaces/blockchain/tree/CLAUDE.md +12 -0
- package/releases/0.53.3/surfaces/d1/tree/.claude/agents/dba.md +15 -0
- package/releases/0.53.3/surfaces/d1/tree/.claude/agents/devops.md +2 -0
- package/releases/0.53.3/surfaces/d1/tree/.claude/agents/implementer.md +2 -0
- package/releases/0.53.3/surfaces/d1/tree/.claude/patterns.md +8 -0
- package/releases/0.53.3/surfaces/d1/tree/CLAUDE.md +2 -0
- package/releases/0.53.3/surfaces/db/tree/.claude/agents/architect.md +5 -0
- package/releases/0.53.3/surfaces/db/tree/.claude/agents/dba.md +54 -0
- package/releases/0.53.3/surfaces/db/tree/.claude/agents/devops.md +5 -0
- package/releases/0.53.3/surfaces/db/tree/.claude/agents/implementer.md +2 -0
- package/releases/0.53.3/surfaces/db/tree/.claude/agents/integration-tester.md +10 -0
- package/releases/0.53.3/surfaces/db/tree/.claude/agents/planner.md +2 -0
- package/releases/0.53.3/surfaces/db/tree/.claude/agents/reviewer.md +22 -0
- package/releases/0.53.3/surfaces/db/tree/.claude/agents/secops.md +2 -0
- package/releases/0.53.3/surfaces/db/tree/.claude/agents-overview.md +5 -0
- package/releases/0.53.3/surfaces/db/tree/.claude/graph.md +8 -0
- package/releases/0.53.3/surfaces/db/tree/.claude/patterns.md +22 -0
- package/releases/0.53.3/surfaces/db/tree/.claude/pipeline.md +13 -0
- package/releases/0.53.3/surfaces/db/tree/.claude/retrieval.md +5 -0
- package/releases/0.53.3/surfaces/db/tree/.claude/router.md +4 -0
- package/releases/0.53.3/surfaces/db/tree/CLAUDE.md +17 -0
- package/releases/0.53.3/surfaces/drizzle/tree/.claude/agents/dba.md +9 -0
- package/releases/0.53.3/surfaces/drizzle/tree/.claude/agents/devops.md +5 -0
- package/releases/0.53.3/surfaces/drizzle/tree/.claude/agents/implementer.md +2 -0
- package/releases/0.53.3/surfaces/drizzle/tree/.claude/patterns.md +7 -0
- package/releases/0.53.3/surfaces/edge-cf/tree/.claude/agents/architect.md +14 -0
- package/releases/0.53.3/surfaces/edge-cf/tree/.claude/agents/dba.md +2 -0
- package/releases/0.53.3/surfaces/edge-cf/tree/.claude/agents/devops.md +29 -0
- package/releases/0.53.3/surfaces/edge-cf/tree/.claude/agents/implementer.md +14 -0
- package/releases/0.53.3/surfaces/edge-cf/tree/.claude/agents/integration-tester.md +11 -0
- package/releases/0.53.3/surfaces/edge-cf/tree/.claude/agents/qa.md +3 -0
- package/releases/0.53.3/surfaces/edge-cf/tree/.claude/agents/reviewer.md +8 -0
- package/releases/0.53.3/surfaces/edge-cf/tree/.claude/agents/secops.md +8 -0
- package/releases/0.53.3/surfaces/edge-cf/tree/.claude/patterns.md +17 -0
- package/releases/0.53.3/surfaces/edge-cf/tree/.claude/retrieval.md +8 -0
- package/releases/0.53.3/surfaces/edge-cf/tree/CLAUDE.md +27 -0
- package/releases/0.53.3/surfaces/frontend/tree/.claude/agents/architect.md +20 -0
- package/releases/0.53.3/surfaces/frontend/tree/.claude/agents/devops.md +28 -0
- package/releases/0.53.3/surfaces/frontend/tree/.claude/agents/implementer.md +25 -0
- package/releases/0.53.3/surfaces/frontend/tree/.claude/agents/qa.md +17 -0
- package/releases/0.53.3/surfaces/frontend/tree/.claude/agents/reviewer.md +56 -0
- package/releases/0.53.3/surfaces/frontend/tree/.claude/patterns.md +8 -0
- package/releases/0.53.3/surfaces/frontend/tree/.claude/retrieval.md +2 -0
- package/releases/0.53.3/surfaces/frontend/tree/.claude/router.md +14 -0
- package/releases/0.53.3/surfaces/frontend/tree/CLAUDE.md +5 -0
- package/releases/0.53.3/surfaces/integrations/tree/.claude/agents/architect.md +16 -0
- package/releases/0.53.3/surfaces/integrations/tree/.claude/agents/implementer.md +12 -0
- package/releases/0.53.3/surfaces/integrations/tree/.claude/agents/integration-tester.md +20 -0
- package/releases/0.53.3/surfaces/integrations/tree/.claude/agents/planner.md +2 -0
- package/releases/0.53.3/surfaces/integrations/tree/.claude/agents/reviewer.md +21 -0
- package/releases/0.53.3/surfaces/integrations/tree/.claude/agents/secops.md +2 -0
- package/releases/0.53.3/surfaces/integrations/tree/.claude/agents-overview.md +8 -0
- package/releases/0.53.3/surfaces/integrations/tree/.claude/graph.md +10 -0
- package/releases/0.53.3/surfaces/integrations/tree/.claude/patterns.md +38 -0
- package/releases/0.53.3/surfaces/integrations/tree/.claude/pipeline.md +16 -0
- package/releases/0.53.3/surfaces/integrations/tree/.claude/retrieval.md +16 -0
- package/releases/0.53.3/surfaces/integrations/tree/.claude/router.md +6 -0
- package/releases/0.53.3/surfaces/integrations/tree/CLAUDE.md +17 -0
- package/releases/0.53.3/surfaces/money/tree/.claude/agents/architect.md +12 -0
- package/releases/0.53.3/surfaces/money/tree/.claude/agents/dba.md +14 -0
- package/releases/0.53.3/surfaces/money/tree/.claude/agents/implementer.md +11 -0
- package/releases/0.53.3/surfaces/money/tree/.claude/agents/integration-tester.md +3 -0
- package/releases/0.53.3/surfaces/money/tree/.claude/agents/reviewer.md +23 -0
- package/releases/0.53.3/surfaces/money/tree/.claude/agents/secops.md +5 -0
- package/releases/0.53.3/surfaces/money/tree/.claude/agents/solidity-auditor.md +4 -0
- package/releases/0.53.3/surfaces/money/tree/.claude/agents/solidity-dev.md +4 -0
- package/releases/0.53.3/surfaces/money/tree/.claude/graph.md +2 -0
- package/releases/0.53.3/surfaces/money/tree/.claude/patterns.md +49 -0
- package/releases/0.53.3/surfaces/money/tree/.claude/pipeline.md +2 -0
- package/releases/0.53.3/surfaces/money/tree/.claude/retrieval.md +2 -0
- package/releases/0.53.3/surfaces/money/tree/CLAUDE.md +11 -0
- package/releases/0.53.3/surfaces/pii/tree/.claude/agents/dba.md +2 -0
- package/releases/0.53.3/surfaces/pii/tree/.claude/agents/devops.md +8 -0
- package/releases/0.53.3/surfaces/pii/tree/.claude/agents/reviewer.md +8 -0
- package/releases/0.53.3/surfaces/pii/tree/.claude/agents/secops.md +2 -0
- package/releases/0.53.3/surfaces/pii/tree/.claude/agents/solidity-auditor.md +5 -0
- package/releases/0.53.3/surfaces/pii/tree/CLAUDE.md +5 -0
- package/releases/0.53.3/surfaces/prisma/tree/.claude/agents/architect.md +2 -0
- package/releases/0.53.3/surfaces/prisma/tree/.claude/agents/dba.md +42 -0
- package/releases/0.53.3/surfaces/prisma/tree/.claude/agents/devops.md +11 -0
- package/releases/0.53.3/surfaces/prisma/tree/.claude/agents/implementer.md +2 -0
- package/releases/0.53.3/surfaces/prisma/tree/.claude/agents/integration-tester.md +2 -0
- package/releases/0.53.3/surfaces/prisma/tree/.claude/agents/reviewer.md +2 -0
- package/releases/0.53.3/surfaces/prisma/tree/.claude/patterns.md +15 -0
- package/releases/0.53.3/surfaces/prisma/tree/CLAUDE.md +5 -0
- package/releases/0.54.0/core/GAPS.md +125 -0
- package/releases/0.54.0/core/answered.json +68 -0
- package/releases/0.54.0/core/defaults/tree/.claude/agents/architect.md +1 -0
- package/releases/0.54.0/core/defaults/tree/.claude/agents/dba.md +3 -0
- package/releases/0.54.0/core/defaults/tree/.claude/agents/devops.md +1 -0
- package/releases/0.54.0/core/defaults/tree/.claude/agents/implementer.md +1 -0
- package/releases/0.54.0/core/defaults/tree/.claude/agents/integration-tester.md +3 -0
- package/releases/0.54.0/core/defaults/tree/.claude/agents/qa.md +7 -0
- package/releases/0.54.0/core/defaults/tree/.claude/agents/reviewer.md +3 -0
- package/releases/0.54.0/core/defaults/tree/.claude/agents/secops.md +3 -0
- package/releases/0.54.0/core/defaults/tree/.claude/agents/solidity-auditor.md +3 -0
- package/releases/0.54.0/core/defaults/tree/.claude/agents/solidity-dev.md +3 -0
- package/releases/0.54.0/core/tree/.claude/agents/architect.md +129 -0
- package/releases/0.54.0/core/tree/.claude/agents/dba.md +117 -0
- package/releases/0.54.0/core/tree/.claude/agents/devops.md +118 -0
- package/releases/0.54.0/core/tree/.claude/agents/implementer.md +163 -0
- package/releases/0.54.0/core/tree/.claude/agents/integration-tester.md +168 -0
- package/releases/0.54.0/core/tree/.claude/agents/planner.md +132 -0
- package/releases/0.54.0/core/tree/.claude/agents/qa.md +150 -0
- package/releases/0.54.0/core/tree/.claude/agents/reviewer.md +184 -0
- package/releases/0.54.0/core/tree/.claude/agents/secops.md +120 -0
- package/releases/0.54.0/core/tree/.claude/agents/solidity-auditor.md +126 -0
- package/releases/0.54.0/core/tree/.claude/agents/solidity-dev.md +123 -0
- package/releases/0.54.0/core/tree/.claude/agents-overview.md +64 -0
- package/releases/0.54.0/core/tree/.claude/frontend.md +10 -0
- package/releases/0.54.0/core/tree/.claude/graph.md +75 -0
- package/releases/0.54.0/core/tree/.claude/patterns.md +251 -0
- package/releases/0.54.0/core/tree/.claude/pills/README.md +150 -0
- package/releases/0.54.0/core/tree/.claude/pipeline.md +101 -0
- package/releases/0.54.0/core/tree/.claude/retrieval.md +103 -0
- package/releases/0.54.0/core/tree/.claude/router.md +202 -0
- package/releases/0.54.0/core/tree/.claude/templates/integration.md +48 -0
- package/releases/0.54.0/core/tree/CLAUDE.md +164 -0
- package/releases/0.54.0/core/tree/scripts/cost-watch.mjs +25 -0
- package/releases/0.54.0/core/tree/scripts/edit-guard.mjs +24 -0
- package/releases/0.54.0/core/tree/scripts/harness-check.mjs +71 -0
- package/releases/0.54.0/core/tree/scripts/loop-gate.mjs +19 -0
- package/releases/0.54.0/core/vocabulary.json +13 -0
- package/releases/0.54.0/surfaces/blockchain/tree/.claude/agents/architect.md +5 -0
- package/releases/0.54.0/surfaces/blockchain/tree/.claude/agents/devops.md +5 -0
- package/releases/0.54.0/surfaces/blockchain/tree/.claude/agents/reviewer.md +5 -0
- package/releases/0.54.0/surfaces/blockchain/tree/.claude/agents/solidity-auditor.md +18 -0
- package/releases/0.54.0/surfaces/blockchain/tree/.claude/agents/solidity-dev.md +16 -0
- package/releases/0.54.0/surfaces/blockchain/tree/.claude/agents-overview.md +6 -0
- package/releases/0.54.0/surfaces/blockchain/tree/.claude/graph.md +11 -0
- package/releases/0.54.0/surfaces/blockchain/tree/.claude/router.md +6 -0
- package/releases/0.54.0/surfaces/blockchain/tree/CLAUDE.md +12 -0
- package/releases/0.54.0/surfaces/d1/tree/.claude/agents/dba.md +15 -0
- package/releases/0.54.0/surfaces/d1/tree/.claude/agents/devops.md +2 -0
- package/releases/0.54.0/surfaces/d1/tree/.claude/agents/implementer.md +2 -0
- package/releases/0.54.0/surfaces/d1/tree/.claude/patterns.md +8 -0
- package/releases/0.54.0/surfaces/d1/tree/CLAUDE.md +2 -0
- package/releases/0.54.0/surfaces/db/tree/.claude/agents/architect.md +5 -0
- package/releases/0.54.0/surfaces/db/tree/.claude/agents/dba.md +54 -0
- package/releases/0.54.0/surfaces/db/tree/.claude/agents/devops.md +5 -0
- package/releases/0.54.0/surfaces/db/tree/.claude/agents/implementer.md +2 -0
- package/releases/0.54.0/surfaces/db/tree/.claude/agents/integration-tester.md +10 -0
- package/releases/0.54.0/surfaces/db/tree/.claude/agents/planner.md +2 -0
- package/releases/0.54.0/surfaces/db/tree/.claude/agents/reviewer.md +22 -0
- package/releases/0.54.0/surfaces/db/tree/.claude/agents/secops.md +2 -0
- package/releases/0.54.0/surfaces/db/tree/.claude/agents-overview.md +5 -0
- package/releases/0.54.0/surfaces/db/tree/.claude/graph.md +8 -0
- package/releases/0.54.0/surfaces/db/tree/.claude/patterns.md +22 -0
- package/releases/0.54.0/surfaces/db/tree/.claude/pipeline.md +13 -0
- package/releases/0.54.0/surfaces/db/tree/.claude/retrieval.md +5 -0
- package/releases/0.54.0/surfaces/db/tree/.claude/router.md +4 -0
- package/releases/0.54.0/surfaces/db/tree/CLAUDE.md +17 -0
- package/releases/0.54.0/surfaces/drizzle/tree/.claude/agents/dba.md +9 -0
- package/releases/0.54.0/surfaces/drizzle/tree/.claude/agents/devops.md +5 -0
- package/releases/0.54.0/surfaces/drizzle/tree/.claude/agents/implementer.md +2 -0
- package/releases/0.54.0/surfaces/drizzle/tree/.claude/patterns.md +7 -0
- package/releases/0.54.0/surfaces/edge-cf/tree/.claude/agents/architect.md +14 -0
- package/releases/0.54.0/surfaces/edge-cf/tree/.claude/agents/dba.md +2 -0
- package/releases/0.54.0/surfaces/edge-cf/tree/.claude/agents/devops.md +29 -0
- package/releases/0.54.0/surfaces/edge-cf/tree/.claude/agents/implementer.md +14 -0
- package/releases/0.54.0/surfaces/edge-cf/tree/.claude/agents/integration-tester.md +11 -0
- package/releases/0.54.0/surfaces/edge-cf/tree/.claude/agents/qa.md +3 -0
- package/releases/0.54.0/surfaces/edge-cf/tree/.claude/agents/reviewer.md +8 -0
- package/releases/0.54.0/surfaces/edge-cf/tree/.claude/agents/secops.md +8 -0
- package/releases/0.54.0/surfaces/edge-cf/tree/.claude/patterns.md +17 -0
- package/releases/0.54.0/surfaces/edge-cf/tree/.claude/retrieval.md +8 -0
- package/releases/0.54.0/surfaces/edge-cf/tree/CLAUDE.md +27 -0
- package/releases/0.54.0/surfaces/frontend/tree/.claude/agents/architect.md +20 -0
- package/releases/0.54.0/surfaces/frontend/tree/.claude/agents/devops.md +28 -0
- package/releases/0.54.0/surfaces/frontend/tree/.claude/agents/implementer.md +25 -0
- package/releases/0.54.0/surfaces/frontend/tree/.claude/agents/qa.md +17 -0
- package/releases/0.54.0/surfaces/frontend/tree/.claude/agents/reviewer.md +56 -0
- package/releases/0.54.0/surfaces/frontend/tree/.claude/patterns.md +8 -0
- package/releases/0.54.0/surfaces/frontend/tree/.claude/retrieval.md +2 -0
- package/releases/0.54.0/surfaces/frontend/tree/.claude/router.md +14 -0
- package/releases/0.54.0/surfaces/frontend/tree/CLAUDE.md +5 -0
- package/releases/0.54.0/surfaces/integrations/tree/.claude/agents/architect.md +16 -0
- package/releases/0.54.0/surfaces/integrations/tree/.claude/agents/implementer.md +12 -0
- package/releases/0.54.0/surfaces/integrations/tree/.claude/agents/integration-tester.md +20 -0
- package/releases/0.54.0/surfaces/integrations/tree/.claude/agents/planner.md +2 -0
- package/releases/0.54.0/surfaces/integrations/tree/.claude/agents/reviewer.md +21 -0
- package/releases/0.54.0/surfaces/integrations/tree/.claude/agents/secops.md +2 -0
- package/releases/0.54.0/surfaces/integrations/tree/.claude/agents-overview.md +8 -0
- package/releases/0.54.0/surfaces/integrations/tree/.claude/graph.md +10 -0
- package/releases/0.54.0/surfaces/integrations/tree/.claude/patterns.md +38 -0
- package/releases/0.54.0/surfaces/integrations/tree/.claude/pipeline.md +16 -0
- package/releases/0.54.0/surfaces/integrations/tree/.claude/retrieval.md +16 -0
- package/releases/0.54.0/surfaces/integrations/tree/.claude/router.md +6 -0
- package/releases/0.54.0/surfaces/integrations/tree/CLAUDE.md +17 -0
- package/releases/0.54.0/surfaces/money/tree/.claude/agents/architect.md +12 -0
- package/releases/0.54.0/surfaces/money/tree/.claude/agents/dba.md +14 -0
- package/releases/0.54.0/surfaces/money/tree/.claude/agents/implementer.md +11 -0
- package/releases/0.54.0/surfaces/money/tree/.claude/agents/integration-tester.md +3 -0
- package/releases/0.54.0/surfaces/money/tree/.claude/agents/reviewer.md +23 -0
- package/releases/0.54.0/surfaces/money/tree/.claude/agents/secops.md +5 -0
- package/releases/0.54.0/surfaces/money/tree/.claude/agents/solidity-auditor.md +4 -0
- package/releases/0.54.0/surfaces/money/tree/.claude/agents/solidity-dev.md +4 -0
- package/releases/0.54.0/surfaces/money/tree/.claude/graph.md +2 -0
- package/releases/0.54.0/surfaces/money/tree/.claude/patterns.md +49 -0
- package/releases/0.54.0/surfaces/money/tree/.claude/pipeline.md +2 -0
- package/releases/0.54.0/surfaces/money/tree/.claude/retrieval.md +2 -0
- package/releases/0.54.0/surfaces/money/tree/CLAUDE.md +11 -0
- package/releases/0.54.0/surfaces/pii/tree/.claude/agents/dba.md +2 -0
- package/releases/0.54.0/surfaces/pii/tree/.claude/agents/devops.md +8 -0
- package/releases/0.54.0/surfaces/pii/tree/.claude/agents/reviewer.md +8 -0
- package/releases/0.54.0/surfaces/pii/tree/.claude/agents/secops.md +2 -0
- package/releases/0.54.0/surfaces/pii/tree/.claude/agents/solidity-auditor.md +5 -0
- package/releases/0.54.0/surfaces/pii/tree/CLAUDE.md +5 -0
- package/releases/0.54.0/surfaces/prisma/tree/.claude/agents/architect.md +2 -0
- package/releases/0.54.0/surfaces/prisma/tree/.claude/agents/dba.md +42 -0
- package/releases/0.54.0/surfaces/prisma/tree/.claude/agents/devops.md +11 -0
- package/releases/0.54.0/surfaces/prisma/tree/.claude/agents/implementer.md +2 -0
- package/releases/0.54.0/surfaces/prisma/tree/.claude/agents/integration-tester.md +2 -0
- package/releases/0.54.0/surfaces/prisma/tree/.claude/agents/reviewer.md +2 -0
- package/releases/0.54.0/surfaces/prisma/tree/.claude/patterns.md +15 -0
- package/releases/0.54.0/surfaces/prisma/tree/CLAUDE.md +5 -0
- package/src/commands/check.mjs +107 -6
- package/src/commands/learn.mjs +60 -23
- package/src/commands/pills.mjs +6 -2
- package/src/dashboard.html +105 -20
- package/src/dashboard.mjs +5 -1
package/src/commands/learn.mjs
CHANGED
|
@@ -38,8 +38,8 @@ import { deepLearn, transcriptsOf } from '../deep.mjs';
|
|
|
38
38
|
import { autoExport } from './export.mjs';
|
|
39
39
|
import { beforeModel } from '../detectors.mjs';
|
|
40
40
|
|
|
41
|
-
/**
|
|
42
|
-
const CAPTURE_AT = 3;
|
|
41
|
+
/** Times one stage's work was sent back, since its newest lesson, that make a lesson overdue. */
|
|
42
|
+
export const CAPTURE_AT = 3;
|
|
43
43
|
|
|
44
44
|
/**
|
|
45
45
|
* How far back a loop-back still counts. Older ones are history nobody remembers well enough to
|
|
@@ -111,11 +111,16 @@ const SENT_BACK_HOURS = 24;
|
|
|
111
111
|
|
|
112
112
|
/**
|
|
113
113
|
* The stage each loop-back sent work back to: the next one dispatched in its session, after it reported, among
|
|
114
|
-
* the stages the project's graph routes that verdict of that stage to — or the only one it routes it to.
|
|
114
|
+
* the stages the project's graph routes that verdict of that stage to — or the only one it routes it to. One the
|
|
115
|
+
* graph routes to several, none of which has taken it back yet, went to no stage that can be told: it is charged to
|
|
116
|
+
* none, where it was charged to the stage that gave it — a gate that rejected work, doing its job, read as a stage
|
|
117
|
+
* sent back, and asked every turn for a lesson that was not its own.
|
|
115
118
|
*
|
|
116
119
|
* @param {object[]} records - Recorded dispatches.
|
|
117
120
|
* @param {Map<string, Map<string, Map<string, number>>>|null} loops - The graph's capped loop-back edges.
|
|
118
|
-
* @returns {Map<object, string>} Loop-back record → the stage it sent work back to,
|
|
121
|
+
* @returns {Map<object, {to: string|null, fix: object|null}>} Loop-back record → the stage it sent work back to, null
|
|
122
|
+
* while that cannot be told, and the dispatch of that stage that took the work back, where one was found. A
|
|
123
|
+
* loop-back the graph does not route is not in it.
|
|
119
124
|
*/
|
|
120
125
|
export function sentBackTo(records, loops) {
|
|
121
126
|
const out = new Map();
|
|
@@ -133,11 +138,32 @@ export function sentBackTo(records, loops) {
|
|
|
133
138
|
const within = (x) => Date.parse(x.ts) - Date.parse(back) <= SENT_BACK_HOURS * 3_600_000;
|
|
134
139
|
const next = (bySession.get(r.session) ?? []).find((x) => String(x.ts) > back && within(x) && targets.has(x.role));
|
|
135
140
|
const to = next?.role ?? (targets.size === 1 ? [...targets.keys()][0] : null);
|
|
136
|
-
|
|
141
|
+
out.set(r, { to, fix: next ?? null });
|
|
137
142
|
}
|
|
138
143
|
return out;
|
|
139
144
|
}
|
|
140
145
|
|
|
146
|
+
/**
|
|
147
|
+
* The stage a loop-back is charged to: where it sent work back (`sentBackTo`), none while that cannot be told, and
|
|
148
|
+
* the stage that gave it only where the graph routes it nowhere.
|
|
149
|
+
*
|
|
150
|
+
* @param {ReturnType<typeof sentBackTo>} owners
|
|
151
|
+
* @param {object} r - A loop-back record.
|
|
152
|
+
* @returns {string|null}
|
|
153
|
+
*/
|
|
154
|
+
const chargedTo = (owners, r) => (owners.has(r) ? owners.get(r).to : r.role);
|
|
155
|
+
|
|
156
|
+
/**
|
|
157
|
+
* How many rounds some loop-backs sent back: those one dispatch took back are one, since the checkers that run beside
|
|
158
|
+
* each other each reject the same work. One no dispatch took back counts on its own, since nothing then says which
|
|
159
|
+
* work it rejected.
|
|
160
|
+
*
|
|
161
|
+
* @param {ReturnType<typeof sentBackTo>} owners
|
|
162
|
+
* @param {object[]} loops - Loop-back records.
|
|
163
|
+
* @returns {number}
|
|
164
|
+
*/
|
|
165
|
+
const sendings = (owners, loops) => new Set(loops.map((r) => owners.get(r)?.fix ?? r)).size;
|
|
166
|
+
|
|
141
167
|
/**
|
|
142
168
|
* Roles that looped back often enough, since their newest lesson, that one is overdue.
|
|
143
169
|
*
|
|
@@ -155,7 +181,7 @@ export function overdue(records, known, now = new Date(), days = CAPTURE_DAYS, o
|
|
|
155
181
|
// A loop-back is the lesson of the stage it sent work back to, where that is known (`sentBackTo`): charged
|
|
156
182
|
// to the stage that gave the verdict, the reviewer owed the implementer's lessons, and only a pill naming
|
|
157
183
|
// every checker in its applies_to ever settled the count.
|
|
158
|
-
const ownerOf = (r) => owners
|
|
184
|
+
const ownerOf = (r) => chargedTo(owners, r);
|
|
159
185
|
const roles = [...new Set(records.map(ownerOf).filter(Boolean))];
|
|
160
186
|
const out = [];
|
|
161
187
|
for (const role of roles) {
|
|
@@ -175,12 +201,17 @@ export function overdue(records, known, now = new Date(), days = CAPTURE_DAYS, o
|
|
|
175
201
|
const at = floor === newest ? taught?.at ?? null : null;
|
|
176
202
|
const after = (r) => day(r.ts) > floor || (at !== null && day(r.ts) === floor && String(r.ts) > at);
|
|
177
203
|
const loops = records.filter((r) => ownerOf(r) === role && readable(r.verdict) && isLoopBack(r.verdict) && after(r));
|
|
178
|
-
|
|
204
|
+
// Rounds sent back, not loop-backs: three reviewers beside each other rejecting one change sent it back once.
|
|
205
|
+
const count = sendings(owners, loops);
|
|
206
|
+
if (count >= CAPTURE_AT) {
|
|
207
|
+
// One per round sent back, as the count is: three reviewers beside each other are one entry, not three.
|
|
208
|
+
const listed = new Set();
|
|
179
209
|
const recent = loops
|
|
180
210
|
.sort((a, b) => String(b.ts).localeCompare(String(a.ts)))
|
|
211
|
+
.filter((r) => !listed.has(owners.get(r)?.fix ?? r) && listed.add(owners.get(r)?.fix ?? r))
|
|
181
212
|
.slice(0, 3)
|
|
182
213
|
.map((r) => ({ ts: day(r.ts), desc: r.desc ?? '', session: String(r.session ?? '').slice(0, 8) }));
|
|
183
|
-
out.push({ role, count
|
|
214
|
+
out.push({ role, count, since: newest, recent });
|
|
184
215
|
}
|
|
185
216
|
}
|
|
186
217
|
return out.sort((a, b) => b.count - a.count);
|
|
@@ -214,7 +245,7 @@ export function applied(records, known) {
|
|
|
214
245
|
}
|
|
215
246
|
|
|
216
247
|
/** How many days either side of a lesson's date its role is measured over: the same on both sides. */
|
|
217
|
-
const VERIFY_DAYS = 14;
|
|
248
|
+
export const VERIFY_DAYS = 14;
|
|
218
249
|
|
|
219
250
|
/** A day as `YYYY-MM-DD`, moved by some days. */
|
|
220
251
|
const shift = (date, days) => new Date(Date.parse(`${date}T12:00:00Z`) + days * 86_400_000).toISOString().slice(0, 10);
|
|
@@ -248,18 +279,27 @@ function wilson(k, n) {
|
|
|
248
279
|
* graph sends work back to. A change is called only where the two intervals do not overlap. Not proof — the
|
|
249
280
|
* work changes too — but a number where one can be had, and the reason where it cannot.
|
|
250
281
|
*
|
|
282
|
+
* A round is counted sent back once, however many loop-backs sent it: the checkers that run beside each other
|
|
283
|
+
* each reject the same work, and one project's architect had 14 loop-backs on a day it ran 7 rounds, which the
|
|
284
|
+
* share read as 100% sent back where 5 of the 7 were. Loop-backs that the same dispatch took back are one.
|
|
285
|
+
*
|
|
251
286
|
* @param {object[]} records - Recorded dispatches.
|
|
252
287
|
* @param {Awaited<ReturnType<typeof lessons>>} known - The project's pills.
|
|
253
|
-
* @param {{owners?:
|
|
254
|
-
* back to, and the stages the graph sends work back to at all.
|
|
288
|
+
* @param {{owners?: ReturnType<typeof sentBackTo>, targets?: Set<string>|null}} [graph] - Who each loop-back sent
|
|
289
|
+
* work back to, and the stages the graph sends work back to at all.
|
|
255
290
|
* @returns {{rel: string, date: string, role: string, comparable: boolean, why?: string, on?: string|null,
|
|
256
|
-
* was?: string, before?:
|
|
257
|
-
*
|
|
291
|
+
* was?: string, before?: Side, after?: Side, change?: 'lower'|'higher'|'unclear', control?: {before: Side, after: Side}}[]}
|
|
292
|
+
* A `Side` is `{n, loops, span}`: the stage's rounds, how many were sent back, and the first and last day a round
|
|
293
|
+
* of it was recorded on, since a project younger than the window has fewer days than fourteen to show.
|
|
258
294
|
*/
|
|
259
295
|
export function verified(records, known, { owners = new Map(), targets = null } = {}) {
|
|
260
296
|
const out = [];
|
|
261
|
-
const ownerOf = (r) => owners
|
|
297
|
+
const ownerOf = (r) => chargedTo(owners, r);
|
|
262
298
|
const sentBack = records.filter((r) => readable(r.verdict) && isLoopBack(r.verdict));
|
|
299
|
+
const sideOf = (these, backs) => {
|
|
300
|
+
const days = these.map((r) => day(r.ts)).sort();
|
|
301
|
+
return { n: these.length, loops: Math.min(these.length, sendings(owners, backs)), span: [days[0] ?? null, days.at(-1) ?? null] };
|
|
302
|
+
};
|
|
263
303
|
const ranOn = (r) => (r.usage_model ? `${r.usage_model}${r.effort ? ` · ${r.effort}` : ''}` : null);
|
|
264
304
|
for (const lesson of known.filter((l) => l.date)) {
|
|
265
305
|
const from = shift(lesson.date, -VERIFY_DAYS);
|
|
@@ -274,10 +314,7 @@ export function verified(records, known, { owners = new Map(), targets = null }
|
|
|
274
314
|
}
|
|
275
315
|
const rounds = records.filter((r) => r.role === role && readable(r.verdict));
|
|
276
316
|
const backs = sentBack.filter((r) => ownerOf(r) === role);
|
|
277
|
-
const side = (pick, mine) =>
|
|
278
|
-
const n = mine.filter(pick).length;
|
|
279
|
-
return { n, loops: Math.min(n, backs.filter(pick).length) };
|
|
280
|
-
};
|
|
317
|
+
const side = (pick, mine) => sideOf(mine.filter(pick), backs.filter(pick));
|
|
281
318
|
if (side(pre, rounds).n < VERIFY_MIN || side(post, rounds).n < VERIFY_MIN) {
|
|
282
319
|
const [b, a] = [side(pre, rounds).n, side(post, rounds).n];
|
|
283
320
|
out.push({ ...base, comparable: false, why: `too few rounds of ${role} either side (${b} before, ${a} after, in ${VERIFY_DAYS} days each)` });
|
|
@@ -299,10 +336,10 @@ export function verified(records, known, { owners = new Map(), targets = null }
|
|
|
299
336
|
const [bLo, bHi] = wilson(before.loops, before.n);
|
|
300
337
|
const [aLo, aHi] = wilson(after.loops, after.n);
|
|
301
338
|
const change = aHi < bLo ? 'lower' : aLo > bHi ? 'higher' : 'unclear';
|
|
302
|
-
const others = [...(targets ?? new Set(sentBack.map(ownerOf)))].filter((x) => x !== role);
|
|
339
|
+
const others = [...(targets ?? new Set(sentBack.map(ownerOf)))].filter((x) => x && x !== role);
|
|
303
340
|
const theirs = records.filter((r) => others.includes(r.role) && readable(r.verdict));
|
|
304
341
|
const otherBacks = sentBack.filter((r) => others.includes(ownerOf(r)));
|
|
305
|
-
const control = (pick) => (
|
|
342
|
+
const control = (pick) => sideOf(theirs.filter(pick), otherBacks.filter(pick));
|
|
306
343
|
out.push({ ...base, comparable: true, on, before, after, change, control: { before: control(pre), after: control(post) } });
|
|
307
344
|
}
|
|
308
345
|
}
|
|
@@ -1047,7 +1084,7 @@ export async function learn(argv, ctx) {
|
|
|
1047
1084
|
}
|
|
1048
1085
|
for (const o of late) {
|
|
1049
1086
|
console.log(
|
|
1050
|
-
` ${o.role}: ${o.count}
|
|
1087
|
+
` ${o.role}: sent back ${o.count} time(s) in the last ${days} days ` +
|
|
1051
1088
|
(o.since ? `since its newest lesson (${o.since})` : 'and no lesson at all') +
|
|
1052
1089
|
' — the newest:',
|
|
1053
1090
|
);
|
|
@@ -1109,10 +1146,10 @@ export async function learn(argv, ctx) {
|
|
|
1109
1146
|
? ` observe ${learning.runs} run(s) in ${records.length} round(s) recorded, ${span}`
|
|
1110
1147
|
: ' observe ✗ nothing recorded — no transcripts found for this project, so no link below can be measured',
|
|
1111
1148
|
);
|
|
1112
|
-
if (late.length === 0) console.log(` capture ✓ no role has
|
|
1149
|
+
if (late.length === 0) console.log(` capture ✓ no role has been sent back ${CAPTURE_AT}+ times without a lesson in the last ${days} days`);
|
|
1113
1150
|
late.forEach((o, i) => {
|
|
1114
1151
|
console.log(
|
|
1115
|
-
` ${i === 0 ? 'capture ' : ' '} ✗ ${o.role}: ${o.count}
|
|
1152
|
+
` ${i === 0 ? 'capture ' : ' '} ✗ ${o.role}: sent back ${o.count} time(s) ` +
|
|
1116
1153
|
(o.since ? `since its newest lesson (${o.since})` : 'and no lesson at all'),
|
|
1117
1154
|
);
|
|
1118
1155
|
});
|
package/src/commands/pills.mjs
CHANGED
|
@@ -12,6 +12,7 @@
|
|
|
12
12
|
|
|
13
13
|
import { mkdir, readFile, readdir, rename } from 'node:fs/promises';
|
|
14
14
|
import { HARNESS, readProfile } from '../paths.mjs';
|
|
15
|
+
import { localDay } from '../store.mjs';
|
|
15
16
|
import { existsSync, readFileSync, statSync } from 'node:fs';
|
|
16
17
|
import { spawnSync } from 'node:child_process';
|
|
17
18
|
import { dirname, join, resolve } from 'node:path';
|
|
@@ -124,7 +125,7 @@ export function list(value) {
|
|
|
124
125
|
* @param {string} citation - `path` or `path:line`.
|
|
125
126
|
* @returns {{state: 'ok'|'gone'|'truncated', path: string, line: number|null, lines?: number}}
|
|
126
127
|
*/
|
|
127
|
-
function resolveCitation(target, citation) {
|
|
128
|
+
export function resolveCitation(target, citation) {
|
|
128
129
|
const at = /^(.*):(\d+)$/.exec(citation);
|
|
129
130
|
const path = at ? at[1] : citation;
|
|
130
131
|
const line = at ? Number(at[2]) : null;
|
|
@@ -350,7 +351,10 @@ export async function pillsData(target, ctx) {
|
|
|
350
351
|
.filter((f) => f.endsWith('.md'))
|
|
351
352
|
.map((f) => f.replace(/\.md$/, ''))
|
|
352
353
|
.sort();
|
|
353
|
-
|
|
354
|
+
// The day where this machine is, the one the capture detector counts loop-backs by and names its requests with: read
|
|
355
|
+
// in UTC, for an hour after midnight at UTC+1 a lesson dated today was refused as in the future, and the loop-backs
|
|
356
|
+
// it answered, dated today, went on being reported.
|
|
357
|
+
const today = localDay(new Date().toISOString());
|
|
354
358
|
const files = existsSync(pillsDir) ? await pillFiles(pillsDir) : [];
|
|
355
359
|
|
|
356
360
|
if (files.length === 0) return { files: 0, active: 0, retired: 0, problems: [], notes: [], pills: [] };
|
package/src/dashboard.html
CHANGED
|
@@ -61,7 +61,21 @@
|
|
|
61
61
|
.stage { display: grid; grid-template-columns: 170px 1fr; gap: 4px 14px; padding: 12px 0; border-bottom: 1px solid #2a2838; }
|
|
62
62
|
.empty { color: var(--faint); padding: 30px 0; text-align: center; }
|
|
63
63
|
.note { margin: 4px 0; font-size: 13px; }
|
|
64
|
-
|
|
64
|
+
.answer { background: var(--panel); border: 1px solid var(--line); border-left: 4px solid var(--faint); border-radius: 6px; padding: 12px 16px; margin: 0 0 14px; }
|
|
65
|
+
.answer[data-tone="ok"] { border-left-color: var(--green); } .answer[data-tone="bad"] { border-left-color: var(--red); } .answer[data-tone="warn"] { border-left-color: var(--amber); }
|
|
66
|
+
.answer .q { color: var(--faint); font-size: 12px; }
|
|
67
|
+
.answer .head { font: 600 18px var(--sans); margin: 2px 0 4px; }
|
|
68
|
+
.answer p { margin: 2px 0; color: var(--soft); font-size: 13px; }
|
|
69
|
+
.cmp { background: var(--panel); border: 1px solid var(--line); border-radius: 6px; padding: 12px 14px; margin: 0 0 10px; }
|
|
70
|
+
.cmp .top { display: flex; flex-wrap: wrap; align-items: baseline; gap: 4px 12px; margin-bottom: 8px; }
|
|
71
|
+
.cmp .verdict { margin-left: auto; font: 600 13px var(--mono); }
|
|
72
|
+
.chip.wraps { white-space: normal; overflow-wrap: anywhere; }
|
|
73
|
+
.meter { display: grid; grid-template-columns: 48px minmax(60px, 1fr) 44px minmax(0, 230px); align-items: center; gap: 2px 10px; margin: 4px 0; font-size: 13px; }
|
|
74
|
+
.meter .pctv { text-align: right; }
|
|
75
|
+
@media (max-width: 640px) {
|
|
76
|
+
.stage { grid-template-columns: 1fr; } nav { margin-left: 0; }
|
|
77
|
+
.meter { grid-template-columns: 48px minmax(60px, 1fr) 44px; } .meter .detail { grid-column: 2 / -1; }
|
|
78
|
+
}
|
|
65
79
|
</style>
|
|
66
80
|
</head>
|
|
67
81
|
<body>
|
|
@@ -210,34 +224,105 @@ const RENDER = {
|
|
|
210
224
|
|
|
211
225
|
learning(d) {
|
|
212
226
|
if (!d) return el('p', { class: 'empty' }, 'No profile here to read the learning cycle of.');
|
|
213
|
-
const
|
|
227
|
+
const name = (rel) => rel.replace(/^\.claude\/pills\//, '').replace(/^retired\//, '').replace(/\.md$/, '');
|
|
228
|
+
const graduated = (rel) => rel.startsWith('.claude/pills/retired/');
|
|
229
|
+
const dayOf = (iso) => new Date(`${iso}T12:00:00`).toLocaleDateString(undefined, { month: 'short', day: 'numeric' });
|
|
230
|
+
const daysIn = ([a, b]) => Math.round((Date.parse(`${b}T12:00:00Z`) - Date.parse(`${a}T12:00:00Z`)) / 86_400_000) + 1;
|
|
231
|
+
const lessonChip = (rel) => el('span', { class: 'chip wraps', title: rel }, name(rel), graduated(rel) ? el('span', { class: 'faint' }, ' · graduated') : null);
|
|
232
|
+
// Lessons written the same day for the same stage are read over the same rounds, so they are one comparison, not
|
|
233
|
+
// a row each repeating its numbers.
|
|
234
|
+
const groups = [];
|
|
235
|
+
for (const c of d.checks.filter((x) => x.before)) {
|
|
236
|
+
const same = groups.find((g) => g.role === c.role && g.date === c.date && g.on === c.on);
|
|
237
|
+
if (same) same.lessons.push(c.rel);
|
|
238
|
+
else groups.push({ ...c, lessons: [c.rel] });
|
|
239
|
+
}
|
|
240
|
+
const rank = { higher: 0, lower: 1, unclear: 2 };
|
|
241
|
+
groups.sort((a, b) => rank[a.change] - rank[b.change] || b.date.localeCompare(a.date) || a.role.localeCompare(b.role));
|
|
214
242
|
const unmeasured = d.checks.filter((c) => !c.before);
|
|
243
|
+
const [less, more, unclear] = ['lower', 'higher', 'unclear'].map((k) => groups.filter((g) => g.change === k).length);
|
|
244
|
+
const lessonsRead = new Set(groups.flatMap((g) => g.lessons)).size;
|
|
245
|
+
const history = d.span ? daysIn(d.span) : 0;
|
|
246
|
+
const shortest = Math.min(...groups.flatMap((g) => [g.before, g.after]).map((side) => (side.span[0] ? daysIn(side.span) : 0)));
|
|
247
|
+
// The share is of work sent back, so up is worse. A move the rounds are too few to tell from chance still says
|
|
248
|
+
// which way it went: "could be chance" alone read, beside 33% → 67%, as if the larger number were the better one.
|
|
249
|
+
const share = (side) => (side.n ? Math.round((100 * side.loops) / side.n) : 0);
|
|
250
|
+
const verdict = (g) =>
|
|
251
|
+
g.change === 'lower' ? ['ok', '▼ better: sent back less']
|
|
252
|
+
: g.change === 'higher' ? ['bad', '▲ worse: sent back more']
|
|
253
|
+
: share(g.after) > share(g.before) ? ['faint', '▲ sent back more, but could be chance']
|
|
254
|
+
: share(g.after) < share(g.before) ? ['faint', '▼ sent back less, but could be chance']
|
|
255
|
+
: ['faint', '≈ no change'];
|
|
256
|
+
|
|
257
|
+
const answer = !groups.length
|
|
258
|
+
? { tone: 'faint', head: 'Not measurable yet', body: unmeasured.length ? `None of the ${unmeasured.length} lesson-and-stage pairs has enough rounds of its stage on both sides of its date — the reasons are at the bottom.` : 'No lesson has been written yet.' }
|
|
259
|
+
: less && more
|
|
260
|
+
? { tone: 'warn', head: 'Mixed', body: `${less} comparison(s) sent back less since their lessons, ${more} sent back more, ${unclear} with no clear change.` }
|
|
261
|
+
: more
|
|
262
|
+
? { tone: 'bad', head: 'Sent back more since', body: `In ${more} of ${groups.length} comparison(s) the stage had more of its work sent back after its lessons than before; ${unclear ? `the other ${unclear} show no clear change` : 'none shows less'}.` }
|
|
263
|
+
: less
|
|
264
|
+
? { tone: 'ok', head: 'Sent back less since', body: `In ${less} of ${groups.length} comparison(s) the stage had less of its work sent back after its lessons than before${unclear ? `; the other ${unclear} show no clear change` : ''}.` }
|
|
265
|
+
: { tone: 'faint', head: 'No clear change yet', body: `None of the ${groups.length} comparison(s) moved by more than chance moves a share at that many rounds.` };
|
|
266
|
+
|
|
267
|
+
const meter = (label, side) => el('div', { class: 'meter' },
|
|
268
|
+
el('span', { class: 'faint' }, label),
|
|
269
|
+
bar([[side.n ? side.loops / side.n : 0, 'var(--amber)']]),
|
|
270
|
+
el('span', { class: 'mono pctv' }, pct(side.loops, side.n)),
|
|
271
|
+
el('span', { class: 'faint detail' }, `${side.loops} of ${side.n} rounds · ${side.span[0] ? `${dayOf(side.span[0])}${side.span[1] !== side.span[0] ? ` – ${dayOf(side.span[1])}` : ''}` : 'no day'}`),
|
|
272
|
+
);
|
|
273
|
+
const comparison = (g) => el('div', { class: 'cmp' },
|
|
274
|
+
el('div', { class: 'top' },
|
|
275
|
+
el('span', { class: 'role' }, g.role),
|
|
276
|
+
el('span', { class: 'soft' }, `${g.lessons.length} lesson${g.lessons.length > 1 ? 's' : ''} written ${dayOf(g.date)}`),
|
|
277
|
+
g.on ? el('span', { class: 'faint mono' }, g.on) : null,
|
|
278
|
+
el('span', { class: `verdict ${verdict(g)[0]}` }, verdict(g)[1]),
|
|
279
|
+
),
|
|
280
|
+
el('div', { class: 'faint', style: 'font-size:12px;margin:0 0 2px' }, `share of the ${g.role}'s rounds sent back to it · lower is better`),
|
|
281
|
+
meter('before', g.before),
|
|
282
|
+
meter('after', g.after),
|
|
283
|
+
el('div', { class: 'faint', style: 'margin:6px 0 8px' }, `for reference, the other stages over the same days: ${pct(g.control.before.loops, g.control.before.n)} → ${pct(g.control.after.loops, g.control.after.n)}`),
|
|
284
|
+
el('div', { class: 'chips' }, g.lessons.map(lessonChip)),
|
|
285
|
+
);
|
|
286
|
+
// What could not be measured, by its reason: the same reason, word for word, is one line.
|
|
287
|
+
const reasons = new Map();
|
|
288
|
+
for (const c of unmeasured) reasons.set(c.why, [...(reasons.get(c.why) ?? []), c.rel]);
|
|
289
|
+
|
|
215
290
|
return el('div', {},
|
|
216
291
|
el('h2', {}, 'Learning'),
|
|
217
292
|
el('p', { class: 'sub' }, said('Whether the pipeline learns from its own runs, link by link, as `nina learn` reads it.')),
|
|
293
|
+
el('div', { class: 'answer', 'data-tone': answer.tone },
|
|
294
|
+
el('div', { class: 'q' }, 'Did the lessons help?'),
|
|
295
|
+
el('div', { class: 'head' }, answer.head),
|
|
296
|
+
el('p', {}, answer.body),
|
|
297
|
+
groups.length && history < 2 * d.window + 1
|
|
298
|
+
? el('p', {}, `This project has ${history} day(s) of history, so a lesson is compared over fewer than the ${d.window} days either side the measure asks for: read it as an early sign.`)
|
|
299
|
+
: groups.length && shortest < d.window
|
|
300
|
+
? el('p', {}, `The shortest comparison has rounds on ${shortest} day(s) of one side, of the ${d.window} the measure reads: read it as an early sign.`)
|
|
301
|
+
: null,
|
|
302
|
+
),
|
|
218
303
|
el('div', { class: 'cards' },
|
|
219
|
-
card('observe', d.rounds ? `${d.runs} runs` : '—', d.rounds ? `${d.rounds} rounds, ${d.span[0]} → ${d.span[1]}` : 'nothing recorded'),
|
|
220
|
-
card('capture', d.late.length ? `${d.late.length} owed` : '✓', d.late.length ? 'stages sent back with nothing written down' : `no stage sent back
|
|
221
|
-
card('apply', d.use.measured ? pct(d.use.read, d.use.measured) : '—', d.use.measured ? `of ${d.use.measured} runs read a lesson` : 'not measured yet'),
|
|
222
|
-
card('
|
|
304
|
+
card('observe · what ran', d.rounds ? `${d.runs} runs` : '—', d.rounds ? `${d.rounds} rounds, ${d.span[0]} → ${d.span[1]}` : 'nothing recorded'),
|
|
305
|
+
card('capture · written down?', d.late.length ? `${d.late.length} owed` : '✓', d.late.length ? 'stages sent back with nothing written down' : `no stage sent back ${d.at}+ times without a lesson in ${d.days} days`),
|
|
306
|
+
card('apply · read?', d.use.measured ? pct(d.use.read, d.use.measured) : '—', d.use.measured ? `of ${d.use.measured} runs read a lesson` : 'not measured yet'),
|
|
307
|
+
card('verify · helped?', !groups.length ? '—' : less && more ? 'mixed' : more ? '▲ more' : less ? '▼ less' : '≈ unclear', groups.length ? `${groups.length} comparison(s) of ${lessonsRead} lesson(s): ${less} sent back less, ${more} more` : 'nothing measurable yet'),
|
|
308
|
+
card('graduate · made rules?', `${d.open.length} open`, `${d.ready.length} at ${d.at}+ · ${d.madeHere} made a rule here${d.relapses.length ? ` · ${d.relapses.length} watched` : ''}`),
|
|
223
309
|
card('loops', d.gated ? (d.activity ? String(d.activity.rounds) : '—') : 'no gate', d.activity ? `rounds on capped edges · ${d.activity.held} sent to you` : d.gated ? 'no ledger yet' : 'caps are instructions'),
|
|
224
310
|
),
|
|
225
|
-
d.late.length ? [el('h3', {}, 'capture · sent back with nothing written down'), d.late.map((o) => el('div', { class: 'note' }, el('span', { class: 'role' }, o.role), ` ${o.count}
|
|
311
|
+
d.late.length ? [el('h3', {}, 'capture · sent back with nothing written down'), d.late.map((o) => el('div', { class: 'note' }, el('span', { class: 'role' }, o.role), ` sent back ${o.count} time(s) ${o.since ? `since its newest lesson (${o.since})` : 'and no lesson at all'}`, el('ul', { class: 'list soft' }, o.recent.map((r) => el('li', {}, `${when(r.ts)} · ${r.desc ?? '(no description)'}`)))))] : null,
|
|
312
|
+
el('h3', {}, 'verify · is each stage sent back less since its lessons?'),
|
|
313
|
+
el('p', { class: 'note soft', style: 'margin-bottom:12px' }, `For each lesson, the share of its stage's rounds that a later stage sent back, in the ${d.window} days before it was written and the ${d.window} after — lower is better. A change is called only when it is larger than chance moves a share at that many rounds. The other stages, over the same days, say whether everything moved at once: then it was the work that changed, not the lesson.`),
|
|
314
|
+
groups.length ? groups.map(comparison) : el('p', { class: 'note faint' }, 'No lesson could be measured yet.'),
|
|
226
315
|
d.owed.length ? [el('h3', {}, 'to graduate · here or in the harness'), d.owed.map((o) => el('p', { class: 'note' }, el('span', { class: 'mono' }, o.rel), o.declined ? el('span', { class: 'soft' }, ` — declined by the harness${o.declined.in ? ` in ${o.declined.in}` : ''}: ${o.declined.why}`) : el('span', { class: 'soft' }, ` — recurred ${o.occurrences} times`)))] : null,
|
|
227
316
|
d.open.length ? [el('h3', {}, 'requests open in the harness'), table(['since', 'pill', 'proposed for'], d.open.map((r) => [el('span', { class: 'mono soft' }, r.date), el('span', { class: 'mono' }, r.pill), r.target]))] : null,
|
|
228
|
-
d.relapses.length ? [el('h3', {}, '
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
el('span', { class: 'soft' }, `${pct(c.control.before.loops, c.control.before.n)} → ${pct(c.control.after.loops, c.control.after.n)}`),
|
|
238
|
-
]), [3])
|
|
239
|
-
: el('p', { class: 'note faint' }, 'No lesson could be measured yet.'),
|
|
240
|
-
unmeasured.length ? el('p', { class: 'note faint' }, `${unmeasured.length} more could not be measured.`) : null,
|
|
317
|
+
d.relapses.length ? [el('h3', {}, 'graduated, then seen again'),
|
|
318
|
+
d.relapses.map((r) => el('p', { class: 'note' },
|
|
319
|
+
el('span', { class: r.due ? 'bad' : 'faint' }, r.due ? '✗ ' : '· '),
|
|
320
|
+
el('span', { class: 'mono', title: r.rel }, name(r.rel)),
|
|
321
|
+
el('span', { class: 'soft' }, ` — seen ${r.recurred} time(s) since its rule ${r.target === 'project' ? `was made here in ${r.rule_in}` : `shipped in ${r.answered_in || 'a release'}`}`),
|
|
322
|
+
r.due ? el('span', { class: 'bad' }, ': the rule did not hold') : el('span', { class: 'faint' }, `; watched, it reopens at ${d.at}`)))] : null,
|
|
323
|
+
unmeasured.length ? el('details', { style: 'margin-top:24px' },
|
|
324
|
+
el('summary', { class: 'soft', style: 'cursor:pointer' }, `${unmeasured.length} lesson-and-stage pair(s) could not be measured, and why`),
|
|
325
|
+
[...reasons].map(([why, rels]) => el('div', { class: 'note', style: 'margin:10px 0' }, el('div', { class: 'soft' }, why), el('div', { class: 'chips', style: 'margin-top:4px' }, rels.map(lessonChip))))) : null,
|
|
241
326
|
);
|
|
242
327
|
},
|
|
243
328
|
|
package/src/dashboard.mjs
CHANGED
|
@@ -21,7 +21,7 @@ import { layerRootFor } from './commands/compose.mjs';
|
|
|
21
21
|
import { taskList } from './commands/runs.mjs';
|
|
22
22
|
import { pipelineData } from './commands/pipeline.mjs';
|
|
23
23
|
import { pillsData } from './commands/pills.mjs';
|
|
24
|
-
import { learningData } from './commands/learn.mjs';
|
|
24
|
+
import { CAPTURE_AT, VERIFY_DAYS, learningData } from './commands/learn.mjs';
|
|
25
25
|
import { statsData } from './commands/stats.mjs';
|
|
26
26
|
|
|
27
27
|
/** The page: one self-contained file, nothing fetched from anywhere else. */
|
|
@@ -72,6 +72,10 @@ export function dashboardTabs(target, ctx) {
|
|
|
72
72
|
const d = await learningData(target, layers.dir, profile, { records: roundsOf(target) });
|
|
73
73
|
return {
|
|
74
74
|
days: d.days,
|
|
75
|
+
// How many times makes an event: a stage sent back, a lesson recurring, a rule that came back. And the days
|
|
76
|
+
// either side of a lesson that verify reads, which a project younger than them cannot fill.
|
|
77
|
+
at: CAPTURE_AT,
|
|
78
|
+
window: VERIFY_DAYS,
|
|
75
79
|
runs: d.runs,
|
|
76
80
|
rounds: d.rounds,
|
|
77
81
|
span: d.span,
|