@ai-sdlc/orchestrator 0.5.0 → 0.9.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/dist/action-enforcement.d.ts +26 -0
- package/dist/action-enforcement.js +70 -0
- package/dist/admission-composite.d.ts +67 -0
- package/dist/admission-composite.js +158 -0
- package/dist/admission-enrichment.d.ts +142 -0
- package/dist/admission-enrichment.js +331 -0
- package/dist/admission-hc.d.ts +62 -0
- package/dist/admission-hc.js +83 -0
- package/dist/admission-score.d.ts +148 -0
- package/dist/admission-score.js +237 -0
- package/dist/analysis/analyzer.js +3 -2
- package/dist/analysis/convention-detector.d.ts +85 -2
- package/dist/analysis/convention-detector.js +375 -70
- package/dist/analysis/diff-analyzer.d.ts +33 -0
- package/dist/analysis/diff-analyzer.js +122 -0
- package/dist/analysis/hotspot-analyzer.js +3 -1
- package/dist/analysis/index.d.ts +2 -1
- package/dist/analysis/index.js +2 -1
- package/dist/artifacts/index.d.ts +65 -0
- package/dist/artifacts/index.js +142 -0
- package/dist/backlog-adapter.d.ts +121 -0
- package/dist/backlog-adapter.js +438 -0
- package/dist/calibration.d.ts +43 -0
- package/dist/calibration.js +76 -0
- package/dist/cli/commands/agents.d.ts +24 -0
- package/dist/cli/commands/agents.js +66 -1
- package/dist/cli/commands/git-remote.d.ts +49 -0
- package/dist/cli/commands/git-remote.js +91 -0
- package/dist/cli/commands/health.d.ts +4 -0
- package/dist/cli/commands/health.js +13 -1
- package/dist/cli/commands/init.d.ts +26 -0
- package/dist/cli/commands/init.js +164 -22
- package/dist/cli/commands/mcp-setup.d.ts +31 -0
- package/dist/cli/commands/mcp-setup.js +78 -8
- package/dist/cli/formatters/table.js +15 -2
- package/dist/cli/index.d.ts +14 -1
- package/dist/cli/index.js +81 -20
- package/dist/cli/versions.d.ts +57 -0
- package/dist/cli/versions.js +128 -0
- package/dist/code-area-classifier.d.ts +21 -0
- package/dist/code-area-classifier.js +48 -0
- package/dist/config.d.ts +33 -1
- package/dist/config.js +78 -8
- package/dist/cycle-utils.d.ts +51 -0
- package/dist/cycle-utils.js +77 -0
- package/dist/database/adapters/external.d.ts +24 -0
- package/dist/database/adapters/external.js +80 -0
- package/dist/database/adapters/neon.d.ts +41 -0
- package/dist/database/adapters/neon.js +98 -0
- package/dist/database/adapters/pg-snapshot-restore.d.ts +28 -0
- package/dist/database/adapters/pg-snapshot-restore.js +68 -0
- package/dist/database/adapters/sqlite-copy.d.ts +32 -0
- package/dist/database/adapters/sqlite-copy.js +145 -0
- package/dist/database/connection-injection.d.ts +35 -0
- package/dist/database/connection-injection.js +93 -0
- package/dist/database/index.d.ts +12 -0
- package/dist/database/index.js +23 -0
- package/dist/database/registry.d.ts +13 -0
- package/dist/database/registry.js +27 -0
- package/dist/database/topology.d.ts +52 -0
- package/dist/database/topology.js +44 -0
- package/dist/database/types.d.ts +89 -0
- package/dist/database/types.js +26 -0
- package/dist/defaults.d.ts +5 -0
- package/dist/defaults.js +5 -0
- package/dist/design-authority.d.ts +40 -0
- package/dist/design-authority.js +71 -0
- package/dist/design-lookahead.d.ts +64 -0
- package/dist/design-lookahead.js +86 -0
- package/dist/design-quality-trend.d.ts +87 -0
- package/dist/design-quality-trend.js +190 -0
- package/dist/design-system-context.d.ts +46 -0
- package/dist/design-system-context.js +80 -0
- package/dist/design-system-correction-loop.d.ts +64 -0
- package/dist/design-system-correction-loop.js +128 -0
- package/dist/design-system-metrics.d.ts +61 -0
- package/dist/design-system-metrics.js +104 -0
- package/dist/design-system-stewardship.d.ts +22 -0
- package/dist/design-system-stewardship.js +85 -0
- package/dist/design-system-validation.d.ts +37 -0
- package/dist/design-system-validation.js +88 -0
- package/dist/dispatch/index.d.ts +4 -0
- package/dist/dispatch/index.js +4 -0
- package/dist/dispatch/merge-gate.d.ts +46 -0
- package/dist/dispatch/merge-gate.js +90 -0
- package/dist/dispatch/requeue.d.ts +57 -0
- package/dist/dispatch/requeue.js +131 -0
- package/dist/dispatch/worker-pool.d.ts +62 -0
- package/dist/dispatch/worker-pool.js +60 -0
- package/dist/execute.d.ts +40 -0
- package/dist/execute.js +295 -30
- package/dist/fix-ci.js +40 -3
- package/dist/fix-review.d.ts +66 -0
- package/dist/fix-review.js +448 -0
- package/dist/harness/adapters/claude-code.d.ts +29 -0
- package/dist/harness/adapters/claude-code.js +191 -0
- package/dist/harness/adapters/codex.d.ts +25 -0
- package/dist/harness/adapters/codex.js +61 -0
- package/dist/harness/independence.d.ts +51 -0
- package/dist/harness/independence.js +67 -0
- package/dist/harness/index.d.ts +14 -0
- package/dist/harness/index.js +20 -0
- package/dist/harness/registry.d.ts +17 -0
- package/dist/harness/registry.js +31 -0
- package/dist/harness/types.d.ts +123 -0
- package/dist/harness/types.js +8 -0
- package/dist/harness/version-probe.d.ts +14 -0
- package/dist/harness/version-probe.js +123 -0
- package/dist/index.d.ts +39 -5
- package/dist/index.js +48 -3
- package/dist/models/classifier.d.ts +76 -0
- package/dist/models/classifier.js +221 -0
- package/dist/models/index.d.ts +3 -0
- package/dist/models/index.js +3 -0
- package/dist/models/registry.d.ts +97 -0
- package/dist/models/registry.js +173 -0
- package/dist/pillar-breakdown.d.ts +63 -0
- package/dist/pillar-breakdown.js +153 -0
- package/dist/pipeline-cycle-detector.d.ts +70 -0
- package/dist/pipeline-cycle-detector.js +111 -0
- package/dist/priority.d.ts +7 -76
- package/dist/priority.js +18 -5
- package/dist/review-meta.d.ts +65 -0
- package/dist/review-meta.js +149 -0
- package/dist/review.d.ts +35 -0
- package/dist/review.js +84 -0
- package/dist/runners/claude-code-sdk.d.ts +31 -0
- package/dist/runners/claude-code-sdk.js +238 -0
- package/dist/runners/claude-code.d.ts +3 -0
- package/dist/runners/claude-code.js +319 -73
- package/dist/runners/codex.js +4 -1
- package/dist/runners/copilot.js +4 -1
- package/dist/runners/cursor.js +4 -1
- package/dist/runners/git-utils.d.ts +81 -0
- package/dist/runners/git-utils.js +201 -0
- package/dist/runners/index.d.ts +5 -1
- package/dist/runners/index.js +4 -0
- package/dist/runners/review-agent.d.ts +67 -0
- package/dist/runners/review-agent.js +350 -0
- package/dist/runners/runner-registry.js +10 -0
- package/dist/runners/sdk-review-runner.d.ts +65 -0
- package/dist/runners/sdk-review-runner.js +185 -0
- package/dist/runners/security-triage.d.ts +20 -4
- package/dist/runners/security-triage.js +42 -14
- package/dist/runners/types.d.ts +25 -0
- package/dist/runtime/attestations.d.ts +274 -0
- package/dist/runtime/attestations.js +460 -0
- package/dist/runtime/git-env.d.ts +53 -0
- package/dist/runtime/git-env.js +60 -0
- package/dist/runtime/index.d.ts +7 -0
- package/dist/runtime/index.js +7 -0
- package/dist/runtime/parallelism-flag.d.ts +10 -0
- package/dist/runtime/parallelism-flag.js +18 -0
- package/dist/runtime/port-allocator.d.ts +21 -0
- package/dist/runtime/port-allocator.js +66 -0
- package/dist/runtime/worktree-pool.d.ts +86 -0
- package/dist/runtime/worktree-pool.js +204 -0
- package/dist/runtime/worktree.d.ts +25 -0
- package/dist/runtime/worktree.js +111 -0
- package/dist/sa-scoring/auto-calibrate.d.ts +69 -0
- package/dist/sa-scoring/auto-calibrate.js +107 -0
- package/dist/sa-scoring/c1-sa2-computable.d.ts +42 -0
- package/dist/sa-scoring/c1-sa2-computable.js +59 -0
- package/dist/sa-scoring/composite.d.ts +107 -0
- package/dist/sa-scoring/composite.js +139 -0
- package/dist/sa-scoring/depparse-client.d.ts +79 -0
- package/dist/sa-scoring/depparse-client.js +187 -0
- package/dist/sa-scoring/did-compiler.d.ts +122 -0
- package/dist/sa-scoring/did-compiler.js +286 -0
- package/dist/sa-scoring/drift-monitor.d.ts +84 -0
- package/dist/sa-scoring/drift-monitor.js +186 -0
- package/dist/sa-scoring/exemplar-bank.d.ts +78 -0
- package/dist/sa-scoring/exemplar-bank.js +154 -0
- package/dist/sa-scoring/feedback-store.d.ts +100 -0
- package/dist/sa-scoring/feedback-store.js +156 -0
- package/dist/sa-scoring/index.d.ts +71 -0
- package/dist/sa-scoring/index.js +158 -0
- package/dist/sa-scoring/layer1-deterministic.d.ts +115 -0
- package/dist/sa-scoring/layer1-deterministic.js +298 -0
- package/dist/sa-scoring/layer2-structural.d.ts +71 -0
- package/dist/sa-scoring/layer2-structural.js +151 -0
- package/dist/sa-scoring/layer3-llm.d.ts +86 -0
- package/dist/sa-scoring/layer3-llm.js +282 -0
- package/dist/sa-scoring/rescore-orchestrator.d.ts +52 -0
- package/dist/sa-scoring/rescore-orchestrator.js +47 -0
- package/dist/scheduling/burn-down.d.ts +27 -0
- package/dist/scheduling/burn-down.js +43 -0
- package/dist/scheduling/calibration.d.ts +42 -0
- package/dist/scheduling/calibration.js +150 -0
- package/dist/scheduling/index.d.ts +8 -0
- package/dist/scheduling/index.js +8 -0
- package/dist/scheduling/ledger.d.ts +59 -0
- package/dist/scheduling/ledger.js +216 -0
- package/dist/scheduling/off-peak.d.ts +27 -0
- package/dist/scheduling/off-peak.js +112 -0
- package/dist/scheduling/schedule-decision.d.ts +39 -0
- package/dist/scheduling/schedule-decision.js +89 -0
- package/dist/scheduling/tier-analysis.d.ts +47 -0
- package/dist/scheduling/tier-analysis.js +81 -0
- package/dist/scheduling/types.d.ts +140 -0
- package/dist/scheduling/types.js +11 -0
- package/dist/shared.d.ts +13 -0
- package/dist/shared.js +32 -0
- package/dist/state/index.d.ts +1 -1
- package/dist/state/schema.d.ts +6 -1
- package/dist/state/schema.js +276 -1
- package/dist/state/store.d.ts +71 -1
- package/dist/state/store.js +464 -7
- package/dist/state/types.d.ts +174 -0
- package/dist/types.d.ts +1 -1
- package/dist/validate-agent-output.js +4 -1
- package/dist/watch.js +6 -0
- package/dist/workflow-patterns/artifact-writer.d.ts +16 -0
- package/dist/workflow-patterns/artifact-writer.js +34 -0
- package/dist/workflow-patterns/classifiers.d.ts +10 -0
- package/dist/workflow-patterns/classifiers.js +72 -0
- package/dist/workflow-patterns/detector.d.ts +27 -0
- package/dist/workflow-patterns/detector.js +186 -0
- package/dist/workflow-patterns/index.d.ts +8 -0
- package/dist/workflow-patterns/index.js +7 -0
- package/dist/workflow-patterns/proposal-generator.d.ts +15 -0
- package/dist/workflow-patterns/proposal-generator.js +183 -0
- package/dist/workflow-patterns/telemetry-ingest.d.ts +27 -0
- package/dist/workflow-patterns/telemetry-ingest.js +103 -0
- package/dist/workflow-patterns/types.d.ts +61 -0
- package/dist/workflow-patterns/types.js +11 -0
- package/package.json +2 -2
package/dist/state/store.js
CHANGED
|
@@ -27,6 +27,13 @@ export class StateStore {
|
|
|
27
27
|
return new StateStore(pathOrDb);
|
|
28
28
|
}
|
|
29
29
|
migrate() {
|
|
30
|
+
// Each migration runs atomically: DDL + schema_version insert in one
|
|
31
|
+
// transaction so a crash mid-migration can't leave the DB in a
|
|
32
|
+
// half-applied state where the version row lies about actual schema.
|
|
33
|
+
const applyMigration = this.db.transaction((migration) => {
|
|
34
|
+
this.db.exec(migration.sql);
|
|
35
|
+
this.db.prepare('INSERT INTO schema_version (version) VALUES (?)').run(migration.version);
|
|
36
|
+
});
|
|
30
37
|
// Check current schema version
|
|
31
38
|
try {
|
|
32
39
|
const row = this.db.prepare('SELECT MAX(version) as v FROM schema_version').get();
|
|
@@ -35,16 +42,14 @@ export class StateStore {
|
|
|
35
42
|
return;
|
|
36
43
|
for (const migration of MIGRATIONS) {
|
|
37
44
|
if (migration.version > (current ?? 0)) {
|
|
38
|
-
|
|
39
|
-
this.db.prepare('INSERT INTO schema_version (version) VALUES (?)').run(migration.version);
|
|
45
|
+
applyMigration(migration);
|
|
40
46
|
}
|
|
41
47
|
}
|
|
42
48
|
}
|
|
43
49
|
catch {
|
|
44
50
|
// Table doesn't exist yet — run all migrations
|
|
45
51
|
for (const migration of MIGRATIONS) {
|
|
46
|
-
|
|
47
|
-
this.db.prepare('INSERT INTO schema_version (version) VALUES (?)').run(migration.version);
|
|
52
|
+
applyMigration(migration);
|
|
48
53
|
}
|
|
49
54
|
}
|
|
50
55
|
}
|
|
@@ -316,10 +321,10 @@ export class StateStore {
|
|
|
316
321
|
// ── Cost Ledger ────────────────────────────────────────────────
|
|
317
322
|
saveCostEntry(entry) {
|
|
318
323
|
const stmt = this.db.prepare(`
|
|
319
|
-
INSERT INTO cost_ledger (run_id, agent_name, pipeline_type, model, input_tokens, output_tokens, total_tokens, cost_usd, issue_id, issue_number, pr_number, stage_name, cache_read_tokens)
|
|
320
|
-
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
|
|
324
|
+
INSERT INTO cost_ledger (run_id, agent_name, pipeline_type, model, model_alias, input_tokens, output_tokens, total_tokens, cost_usd, shadow_cost_usd, issue_id, issue_number, pr_number, stage_name, cache_read_tokens)
|
|
325
|
+
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
|
|
321
326
|
`);
|
|
322
|
-
const result = stmt.run(entry.runId, entry.agentName, entry.pipelineType, entry.model ?? null, entry.inputTokens ?? 0, entry.outputTokens ?? 0, entry.totalTokens ?? 0, entry.costUsd ?? 0, entry.issueId ?? null, entry.issueNumber ?? null, entry.prNumber ?? null, entry.stageName ?? null, entry.cacheReadTokens ?? 0);
|
|
327
|
+
const result = stmt.run(entry.runId, entry.agentName, entry.pipelineType, entry.model ?? null, entry.modelAlias ?? null, entry.inputTokens ?? 0, entry.outputTokens ?? 0, entry.totalTokens ?? 0, entry.costUsd ?? 0, entry.shadowCostUsd ?? null, entry.issueId ?? null, entry.issueNumber ?? null, entry.prNumber ?? null, entry.stageName ?? null, entry.cacheReadTokens ?? 0);
|
|
323
328
|
return Number(result.lastInsertRowid);
|
|
324
329
|
}
|
|
325
330
|
getCostEntries(opts) {
|
|
@@ -361,10 +366,12 @@ export class StateStore {
|
|
|
361
366
|
agentName: row.agent_name,
|
|
362
367
|
pipelineType: row.pipeline_type,
|
|
363
368
|
model: row.model,
|
|
369
|
+
modelAlias: row.model_alias,
|
|
364
370
|
inputTokens: row.input_tokens,
|
|
365
371
|
outputTokens: row.output_tokens,
|
|
366
372
|
totalTokens: row.total_tokens,
|
|
367
373
|
costUsd: row.cost_usd,
|
|
374
|
+
shadowCostUsd: row.shadow_cost_usd,
|
|
368
375
|
issueId: row.issue_id,
|
|
369
376
|
issueNumber: row.issue_number,
|
|
370
377
|
prNumber: row.pr_number,
|
|
@@ -711,6 +718,456 @@ export class StateStore {
|
|
|
711
718
|
getDatabase() {
|
|
712
719
|
return this.db;
|
|
713
720
|
}
|
|
721
|
+
// ── Workflow Pattern Detection ─────────────────────────────────────
|
|
722
|
+
saveToolSequenceEvent(event) {
|
|
723
|
+
const stmt = this.db.prepare(`
|
|
724
|
+
INSERT INTO tool_sequence_events (session_id, tool_name, action_canonical, project_path, timestamp)
|
|
725
|
+
VALUES (?, ?, ?, ?, ?)
|
|
726
|
+
`);
|
|
727
|
+
const result = stmt.run(event.sessionId, event.toolName, event.actionCanonical, event.projectPath ?? null, event.timestamp);
|
|
728
|
+
return Number(result.lastInsertRowid);
|
|
729
|
+
}
|
|
730
|
+
saveToolSequenceEvents(events) {
|
|
731
|
+
const stmt = this.db.prepare(`
|
|
732
|
+
INSERT INTO tool_sequence_events (session_id, tool_name, action_canonical, project_path, timestamp)
|
|
733
|
+
VALUES (?, ?, ?, ?, ?)
|
|
734
|
+
`);
|
|
735
|
+
const tx = this.db.transaction((items) => {
|
|
736
|
+
for (const e of items) {
|
|
737
|
+
stmt.run(e.sessionId, e.toolName, e.actionCanonical, e.projectPath ?? null, e.timestamp);
|
|
738
|
+
}
|
|
739
|
+
return items.length;
|
|
740
|
+
});
|
|
741
|
+
return tx(events);
|
|
742
|
+
}
|
|
743
|
+
getToolSequenceEvents(opts) {
|
|
744
|
+
const conditions = [];
|
|
745
|
+
const params = [];
|
|
746
|
+
if (opts?.sessionId) {
|
|
747
|
+
conditions.push('session_id = ?');
|
|
748
|
+
params.push(opts.sessionId);
|
|
749
|
+
}
|
|
750
|
+
if (opts?.since) {
|
|
751
|
+
conditions.push('timestamp >= ?');
|
|
752
|
+
params.push(opts.since);
|
|
753
|
+
}
|
|
754
|
+
const where = conditions.length > 0 ? `WHERE ${conditions.join(' AND ')}` : '';
|
|
755
|
+
const limit = opts?.limit ?? 10000;
|
|
756
|
+
params.push(limit);
|
|
757
|
+
const rows = this.db
|
|
758
|
+
.prepare(`SELECT * FROM tool_sequence_events ${where} ORDER BY timestamp ASC LIMIT ?`)
|
|
759
|
+
.all(...params);
|
|
760
|
+
return rows.map((r) => ({
|
|
761
|
+
id: r.id,
|
|
762
|
+
sessionId: r.session_id,
|
|
763
|
+
toolName: r.tool_name,
|
|
764
|
+
actionCanonical: r.action_canonical,
|
|
765
|
+
projectPath: r.project_path,
|
|
766
|
+
timestamp: r.timestamp,
|
|
767
|
+
ingestedAt: r.ingested_at,
|
|
768
|
+
}));
|
|
769
|
+
}
|
|
770
|
+
saveWorkflowPattern(pattern) {
|
|
771
|
+
const stmt = this.db.prepare(`
|
|
772
|
+
INSERT OR REPLACE INTO workflow_patterns
|
|
773
|
+
(pattern_hash, pattern_type, sequence_json, frequency, session_count, confidence, first_seen, last_seen, status)
|
|
774
|
+
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)
|
|
775
|
+
`);
|
|
776
|
+
const result = stmt.run(pattern.patternHash, pattern.patternType, pattern.sequenceJson, pattern.frequency, pattern.sessionCount, pattern.confidence, pattern.firstSeen ?? null, pattern.lastSeen ?? null, pattern.status);
|
|
777
|
+
return Number(result.lastInsertRowid);
|
|
778
|
+
}
|
|
779
|
+
getWorkflowPatterns(opts) {
|
|
780
|
+
const conditions = [];
|
|
781
|
+
const params = [];
|
|
782
|
+
if (opts?.status) {
|
|
783
|
+
conditions.push('status = ?');
|
|
784
|
+
params.push(opts.status);
|
|
785
|
+
}
|
|
786
|
+
const where = conditions.length > 0 ? `WHERE ${conditions.join(' AND ')}` : '';
|
|
787
|
+
const rows = this.db
|
|
788
|
+
.prepare(`SELECT * FROM workflow_patterns ${where} ORDER BY confidence DESC`)
|
|
789
|
+
.all(...params);
|
|
790
|
+
return rows.map((r) => ({
|
|
791
|
+
id: r.id,
|
|
792
|
+
patternHash: r.pattern_hash,
|
|
793
|
+
patternType: r.pattern_type,
|
|
794
|
+
sequenceJson: r.sequence_json,
|
|
795
|
+
frequency: r.frequency,
|
|
796
|
+
sessionCount: r.session_count,
|
|
797
|
+
confidence: r.confidence,
|
|
798
|
+
firstSeen: r.first_seen,
|
|
799
|
+
lastSeen: r.last_seen,
|
|
800
|
+
status: r.status,
|
|
801
|
+
detectedAt: r.detected_at,
|
|
802
|
+
}));
|
|
803
|
+
}
|
|
804
|
+
savePatternProposal(proposal) {
|
|
805
|
+
const stmt = this.db.prepare(`
|
|
806
|
+
INSERT INTO pattern_proposals
|
|
807
|
+
(pattern_id, proposal_type, artifact_type, artifact_path, draft_content, confidence, status)
|
|
808
|
+
VALUES (?, ?, ?, ?, ?, ?, ?)
|
|
809
|
+
`);
|
|
810
|
+
const result = stmt.run(proposal.patternId, proposal.proposalType, proposal.artifactType, proposal.artifactPath ?? null, proposal.draftContent, proposal.confidence, proposal.status);
|
|
811
|
+
return Number(result.lastInsertRowid);
|
|
812
|
+
}
|
|
813
|
+
getPatternProposals(opts) {
|
|
814
|
+
const conditions = [];
|
|
815
|
+
const params = [];
|
|
816
|
+
if (opts?.status) {
|
|
817
|
+
conditions.push('status = ?');
|
|
818
|
+
params.push(opts.status);
|
|
819
|
+
}
|
|
820
|
+
const where = conditions.length > 0 ? `WHERE ${conditions.join(' AND ')}` : '';
|
|
821
|
+
const rows = this.db
|
|
822
|
+
.prepare(`SELECT * FROM pattern_proposals ${where} ORDER BY confidence DESC`)
|
|
823
|
+
.all(...params);
|
|
824
|
+
return rows.map((r) => ({
|
|
825
|
+
id: r.id,
|
|
826
|
+
patternId: r.pattern_id,
|
|
827
|
+
proposalType: r.proposal_type,
|
|
828
|
+
artifactType: r.artifact_type,
|
|
829
|
+
artifactPath: r.artifact_path,
|
|
830
|
+
draftContent: r.draft_content,
|
|
831
|
+
confidence: r.confidence,
|
|
832
|
+
status: r.status,
|
|
833
|
+
reviewedAt: r.reviewed_at,
|
|
834
|
+
reviewerReason: r.reviewer_reason,
|
|
835
|
+
createdAt: r.created_at,
|
|
836
|
+
}));
|
|
837
|
+
}
|
|
838
|
+
updateProposalStatus(id, status, reason) {
|
|
839
|
+
this.db
|
|
840
|
+
.prepare(`UPDATE pattern_proposals SET status = ?, reviewed_at = datetime('now'), reviewer_reason = ? WHERE id = ?`)
|
|
841
|
+
.run(status, reason ?? null, id);
|
|
842
|
+
}
|
|
843
|
+
// ── Design System Governance (RFC-0006) ───────────────────────────
|
|
844
|
+
insertDesignTokenEvent(record) {
|
|
845
|
+
const result = this.db
|
|
846
|
+
.prepare(`INSERT INTO design_token_events (binding_name, event_type, tokens_affected, diff_json, actor, pipeline_run_id, design_review_decision)
|
|
847
|
+
VALUES (?, ?, ?, ?, ?, ?, ?)`)
|
|
848
|
+
.run(record.bindingName, record.eventType, record.tokensAffected ?? 0, record.diffJson ?? null, record.actor ?? null, record.pipelineRunId ?? null, record.designReviewDecision ?? null);
|
|
849
|
+
return result.lastInsertRowid;
|
|
850
|
+
}
|
|
851
|
+
getDesignTokenEvents(bindingName, limit = 50) {
|
|
852
|
+
return this.db
|
|
853
|
+
.prepare(`SELECT * FROM design_token_events WHERE binding_name = ? ORDER BY created_at DESC LIMIT ?`)
|
|
854
|
+
.all(bindingName, limit);
|
|
855
|
+
}
|
|
856
|
+
insertDesignReviewEvent(record) {
|
|
857
|
+
const result = this.db
|
|
858
|
+
.prepare(`INSERT INTO design_review_events (binding_name, pr_number, component_name, reviewer, decision, categories_json, actionable_notes)
|
|
859
|
+
VALUES (?, ?, ?, ?, ?, ?, ?)`)
|
|
860
|
+
.run(record.bindingName, record.prNumber ?? null, record.componentName ?? null, record.reviewer, record.decision, record.categoriesJson ?? null, record.actionableNotes ?? null);
|
|
861
|
+
return result.lastInsertRowid;
|
|
862
|
+
}
|
|
863
|
+
getDesignReviewEvents(bindingName, limit = 50) {
|
|
864
|
+
return this.db
|
|
865
|
+
.prepare(`SELECT * FROM design_review_events WHERE binding_name = ? ORDER BY created_at DESC LIMIT ?`)
|
|
866
|
+
.all(bindingName, limit);
|
|
867
|
+
}
|
|
868
|
+
insertTokenComplianceSnapshot(record) {
|
|
869
|
+
const result = this.db
|
|
870
|
+
.prepare(`INSERT INTO token_compliance_history (binding_name, coverage_percent, violations_count) VALUES (?, ?, ?)`)
|
|
871
|
+
.run(record.bindingName, record.coveragePercent, record.violationsCount);
|
|
872
|
+
return result.lastInsertRowid;
|
|
873
|
+
}
|
|
874
|
+
getTokenComplianceHistory(bindingName, limit = 50) {
|
|
875
|
+
return this.db
|
|
876
|
+
.prepare(`SELECT * FROM token_compliance_history WHERE binding_name = ? ORDER BY scanned_at DESC LIMIT ?`)
|
|
877
|
+
.all(bindingName, limit);
|
|
878
|
+
}
|
|
879
|
+
insertVisualRegressionResult(record) {
|
|
880
|
+
const result = this.db
|
|
881
|
+
.prepare(`INSERT INTO visual_regression_results (binding_name, story_name, viewport, diff_percentage, approved, approver, baseline_url, current_url)
|
|
882
|
+
VALUES (?, ?, ?, ?, ?, ?, ?, ?)`)
|
|
883
|
+
.run(record.bindingName, record.storyName, record.viewport ?? null, record.diffPercentage, record.approved ? 1 : 0, record.approver ?? null, record.baselineUrl ?? null, record.currentUrl ?? null);
|
|
884
|
+
return result.lastInsertRowid;
|
|
885
|
+
}
|
|
886
|
+
getVisualRegressionResults(bindingName, limit = 50) {
|
|
887
|
+
return this.db
|
|
888
|
+
.prepare(`SELECT * FROM visual_regression_results WHERE binding_name = ? ORDER BY created_at DESC LIMIT ?`)
|
|
889
|
+
.all(bindingName, limit);
|
|
890
|
+
}
|
|
891
|
+
insertUsabilitySimulationResult(record) {
|
|
892
|
+
const result = this.db
|
|
893
|
+
.prepare(`INSERT INTO usability_simulation_results (binding_name, story_name, persona_id, task_id, completed, actions_taken, expected_actions, efficiency, findings_json)
|
|
894
|
+
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)`)
|
|
895
|
+
.run(record.bindingName, record.storyName, record.personaId ?? null, record.taskId ?? null, record.completed ? 1 : 0, record.actionsTaken ?? null, record.expectedActions ?? null, record.efficiency ?? null, record.findingsJson ?? null);
|
|
896
|
+
return result.lastInsertRowid;
|
|
897
|
+
}
|
|
898
|
+
getUsabilitySimulationResults(bindingName, limit = 50) {
|
|
899
|
+
return this.db
|
|
900
|
+
.prepare(`SELECT * FROM usability_simulation_results WHERE binding_name = ? ORDER BY created_at DESC LIMIT ?`)
|
|
901
|
+
.all(bindingName, limit);
|
|
902
|
+
}
|
|
903
|
+
// ── PPA Triad Integration (RFC-0008) ─────────────────────────────────
|
|
904
|
+
insertDidCompiledArtifact(record) {
|
|
905
|
+
const result = this.db
|
|
906
|
+
.prepare(`INSERT INTO did_compiled_artifacts (did_name, namespace, source_hash, scope_lists_json, constraint_rules_json, anti_pattern_lists_json, measurable_signals_json, bm25_corpus_blob, principle_corpora_blob)
|
|
907
|
+
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)`)
|
|
908
|
+
.run(record.didName, record.namespace ?? null, record.sourceHash, record.scopeListsJson ?? null, record.constraintRulesJson ?? null, record.antiPatternListsJson ?? null, record.measurableSignalsJson ?? null, record.bm25CorpusBlob ?? null, record.principleCorporaBlob ?? null);
|
|
909
|
+
return Number(result.lastInsertRowid);
|
|
910
|
+
}
|
|
911
|
+
getLatestDidCompiledArtifact(didName) {
|
|
912
|
+
const row = this.db
|
|
913
|
+
.prepare(`SELECT * FROM did_compiled_artifacts WHERE did_name = ? ORDER BY compiled_at DESC, id DESC LIMIT 1`)
|
|
914
|
+
.get(didName);
|
|
915
|
+
return row ? this.mapDidCompiledArtifact(row) : undefined;
|
|
916
|
+
}
|
|
917
|
+
getDidCompiledArtifactByHash(didName, sourceHash) {
|
|
918
|
+
const row = this.db
|
|
919
|
+
.prepare(`SELECT * FROM did_compiled_artifacts WHERE did_name = ? AND source_hash = ? ORDER BY compiled_at DESC, id DESC LIMIT 1`)
|
|
920
|
+
.get(didName, sourceHash);
|
|
921
|
+
return row ? this.mapDidCompiledArtifact(row) : undefined;
|
|
922
|
+
}
|
|
923
|
+
mapDidCompiledArtifact(row) {
|
|
924
|
+
return {
|
|
925
|
+
id: row.id,
|
|
926
|
+
didName: row.did_name,
|
|
927
|
+
namespace: row.namespace,
|
|
928
|
+
sourceHash: row.source_hash,
|
|
929
|
+
scopeListsJson: row.scope_lists_json,
|
|
930
|
+
constraintRulesJson: row.constraint_rules_json,
|
|
931
|
+
antiPatternListsJson: row.anti_pattern_lists_json,
|
|
932
|
+
measurableSignalsJson: row.measurable_signals_json,
|
|
933
|
+
bm25CorpusBlob: row.bm25_corpus_blob,
|
|
934
|
+
principleCorporaBlob: row.principle_corpora_blob,
|
|
935
|
+
compiledAt: row.compiled_at,
|
|
936
|
+
};
|
|
937
|
+
}
|
|
938
|
+
recordDidScoringEvent(record) {
|
|
939
|
+
const result = this.db
|
|
940
|
+
.prepare(`INSERT INTO did_scoring_events (did_name, issue_number, sa_dimension, phase, layer1_result_json, layer2_result_json, layer3_result_json, composite_score, phase_weights_json)
|
|
941
|
+
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)`)
|
|
942
|
+
.run(record.didName, record.issueNumber, record.saDimension, record.phase, record.layer1ResultJson ?? null, record.layer2ResultJson ?? null, record.layer3ResultJson ?? null, record.compositeScore ?? null, record.phaseWeightsJson ?? null);
|
|
943
|
+
return Number(result.lastInsertRowid);
|
|
944
|
+
}
|
|
945
|
+
getDidScoringEvents(opts) {
|
|
946
|
+
const conditions = [];
|
|
947
|
+
const params = [];
|
|
948
|
+
if (opts?.didName) {
|
|
949
|
+
conditions.push('did_name = ?');
|
|
950
|
+
params.push(opts.didName);
|
|
951
|
+
}
|
|
952
|
+
if (opts?.issueNumber !== undefined) {
|
|
953
|
+
conditions.push('issue_number = ?');
|
|
954
|
+
params.push(opts.issueNumber);
|
|
955
|
+
}
|
|
956
|
+
if (opts?.saDimension) {
|
|
957
|
+
conditions.push('sa_dimension = ?');
|
|
958
|
+
params.push(opts.saDimension);
|
|
959
|
+
}
|
|
960
|
+
if (opts?.since) {
|
|
961
|
+
conditions.push('created_at >= ?');
|
|
962
|
+
params.push(opts.since);
|
|
963
|
+
}
|
|
964
|
+
const where = conditions.length > 0 ? `WHERE ${conditions.join(' AND ')}` : '';
|
|
965
|
+
const limit = opts?.limit ?? 100;
|
|
966
|
+
params.push(limit);
|
|
967
|
+
const rows = this.db
|
|
968
|
+
.prepare(`SELECT * FROM did_scoring_events ${where} ORDER BY created_at DESC, id DESC LIMIT ?`)
|
|
969
|
+
.all(...params);
|
|
970
|
+
return rows.map((r) => ({
|
|
971
|
+
id: r.id,
|
|
972
|
+
didName: r.did_name,
|
|
973
|
+
issueNumber: r.issue_number,
|
|
974
|
+
saDimension: r.sa_dimension,
|
|
975
|
+
phase: r.phase,
|
|
976
|
+
layer1ResultJson: r.layer1_result_json,
|
|
977
|
+
layer2ResultJson: r.layer2_result_json,
|
|
978
|
+
layer3ResultJson: r.layer3_result_json,
|
|
979
|
+
compositeScore: r.composite_score,
|
|
980
|
+
phaseWeightsJson: r.phase_weights_json,
|
|
981
|
+
createdAt: r.created_at,
|
|
982
|
+
}));
|
|
983
|
+
}
|
|
984
|
+
recordDidFeedback(record) {
|
|
985
|
+
const result = this.db
|
|
986
|
+
.prepare(`INSERT INTO did_feedback_events (did_name, issue_number, dimension, signal, principal, category, structural_score, llm_score, composite_score, notes)
|
|
987
|
+
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`)
|
|
988
|
+
.run(record.didName, record.issueNumber, record.dimension, record.signal, record.principal ?? null, record.category ?? null, record.structuralScore ?? null, record.llmScore ?? null, record.compositeScore ?? null, record.notes ?? null);
|
|
989
|
+
return Number(result.lastInsertRowid);
|
|
990
|
+
}
|
|
991
|
+
getDidFeedbackEvents(opts) {
|
|
992
|
+
const conditions = [];
|
|
993
|
+
const params = [];
|
|
994
|
+
if (opts?.didName) {
|
|
995
|
+
conditions.push('did_name = ?');
|
|
996
|
+
params.push(opts.didName);
|
|
997
|
+
}
|
|
998
|
+
if (opts?.issueNumber !== undefined) {
|
|
999
|
+
conditions.push('issue_number = ?');
|
|
1000
|
+
params.push(opts.issueNumber);
|
|
1001
|
+
}
|
|
1002
|
+
if (opts?.signal) {
|
|
1003
|
+
conditions.push('signal = ?');
|
|
1004
|
+
params.push(opts.signal);
|
|
1005
|
+
}
|
|
1006
|
+
if (opts?.dimension) {
|
|
1007
|
+
conditions.push('dimension = ?');
|
|
1008
|
+
params.push(opts.dimension);
|
|
1009
|
+
}
|
|
1010
|
+
if (opts?.since) {
|
|
1011
|
+
conditions.push('created_at >= ?');
|
|
1012
|
+
params.push(opts.since);
|
|
1013
|
+
}
|
|
1014
|
+
const where = conditions.length > 0 ? `WHERE ${conditions.join(' AND ')}` : '';
|
|
1015
|
+
const limit = opts?.limit ?? 500;
|
|
1016
|
+
params.push(limit);
|
|
1017
|
+
const rows = this.db
|
|
1018
|
+
.prepare(`SELECT * FROM did_feedback_events ${where} ORDER BY created_at DESC, id DESC LIMIT ?`)
|
|
1019
|
+
.all(...params);
|
|
1020
|
+
return rows.map((r) => ({
|
|
1021
|
+
id: r.id,
|
|
1022
|
+
didName: r.did_name,
|
|
1023
|
+
issueNumber: r.issue_number,
|
|
1024
|
+
dimension: r.dimension,
|
|
1025
|
+
signal: r.signal,
|
|
1026
|
+
principal: r.principal,
|
|
1027
|
+
category: r.category,
|
|
1028
|
+
structuralScore: r.structural_score,
|
|
1029
|
+
llmScore: r.llm_score,
|
|
1030
|
+
compositeScore: r.composite_score,
|
|
1031
|
+
notes: r.notes,
|
|
1032
|
+
createdAt: r.created_at,
|
|
1033
|
+
}));
|
|
1034
|
+
}
|
|
1035
|
+
recordDesignChange(record) {
|
|
1036
|
+
const result = this.db
|
|
1037
|
+
.prepare(`INSERT INTO design_change_events (did_name, change_id, change_type, status, payload_json)
|
|
1038
|
+
VALUES (?, ?, ?, ?, ?)`)
|
|
1039
|
+
.run(record.didName, record.changeId, record.changeType, record.status, record.payloadJson);
|
|
1040
|
+
return Number(result.lastInsertRowid);
|
|
1041
|
+
}
|
|
1042
|
+
getDesignChangeEvents(opts) {
|
|
1043
|
+
const conditions = [];
|
|
1044
|
+
const params = [];
|
|
1045
|
+
if (opts?.didName) {
|
|
1046
|
+
conditions.push('did_name = ?');
|
|
1047
|
+
params.push(opts.didName);
|
|
1048
|
+
}
|
|
1049
|
+
if (opts?.changeId) {
|
|
1050
|
+
conditions.push('change_id = ?');
|
|
1051
|
+
params.push(opts.changeId);
|
|
1052
|
+
}
|
|
1053
|
+
const where = conditions.length > 0 ? `WHERE ${conditions.join(' AND ')}` : '';
|
|
1054
|
+
const limit = opts?.limit ?? 100;
|
|
1055
|
+
params.push(limit);
|
|
1056
|
+
const rows = this.db
|
|
1057
|
+
.prepare(`SELECT * FROM design_change_events ${where} ORDER BY emitted_at DESC, id DESC LIMIT ?`)
|
|
1058
|
+
.all(...params);
|
|
1059
|
+
return rows.map((r) => ({
|
|
1060
|
+
id: r.id,
|
|
1061
|
+
didName: r.did_name,
|
|
1062
|
+
changeId: r.change_id,
|
|
1063
|
+
changeType: r.change_type,
|
|
1064
|
+
status: r.status,
|
|
1065
|
+
payloadJson: r.payload_json,
|
|
1066
|
+
emittedAt: r.emitted_at,
|
|
1067
|
+
}));
|
|
1068
|
+
}
|
|
1069
|
+
insertCodeAreaMetrics(record) {
|
|
1070
|
+
const result = this.db
|
|
1071
|
+
.prepare(`INSERT INTO code_area_metrics (code_area, defect_density, churn_rate, pr_rejection_rate, code_acceptance_rate, has_frontend_components, design_metrics_json, data_point_count, window_start, window_end)
|
|
1072
|
+
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`)
|
|
1073
|
+
.run(record.codeArea, record.defectDensity ?? null, record.churnRate ?? null, record.prRejectionRate ?? null, record.codeAcceptanceRate ?? null, record.hasFrontendComponents ? 1 : 0, record.designMetricsJson ?? null, record.dataPointCount ?? 0, record.windowStart ?? null, record.windowEnd ?? null);
|
|
1074
|
+
return Number(result.lastInsertRowid);
|
|
1075
|
+
}
|
|
1076
|
+
/**
|
|
1077
|
+
* Get the most recent metrics snapshot for a code area.
|
|
1078
|
+
* `since` filters to rows where `computed_at >= since`.
|
|
1079
|
+
*/
|
|
1080
|
+
getCodeAreaMetrics(codeArea, opts) {
|
|
1081
|
+
const conditions = ['code_area = ?'];
|
|
1082
|
+
const params = [codeArea];
|
|
1083
|
+
if (opts?.since) {
|
|
1084
|
+
conditions.push('computed_at >= ?');
|
|
1085
|
+
params.push(opts.since);
|
|
1086
|
+
}
|
|
1087
|
+
const row = this.db
|
|
1088
|
+
.prepare(`SELECT * FROM code_area_metrics WHERE ${conditions.join(' AND ')} ORDER BY computed_at DESC, id DESC LIMIT 1`)
|
|
1089
|
+
.get(...params);
|
|
1090
|
+
return row ? this.mapCodeAreaMetrics(row) : undefined;
|
|
1091
|
+
}
|
|
1092
|
+
getCodeAreaMetricsHistory(codeArea, opts) {
|
|
1093
|
+
const conditions = ['code_area = ?'];
|
|
1094
|
+
const params = [codeArea];
|
|
1095
|
+
if (opts?.since) {
|
|
1096
|
+
conditions.push('computed_at >= ?');
|
|
1097
|
+
params.push(opts.since);
|
|
1098
|
+
}
|
|
1099
|
+
const limit = opts?.limit ?? 100;
|
|
1100
|
+
params.push(limit);
|
|
1101
|
+
const rows = this.db
|
|
1102
|
+
.prepare(`SELECT * FROM code_area_metrics WHERE ${conditions.join(' AND ')} ORDER BY computed_at DESC, id DESC LIMIT ?`)
|
|
1103
|
+
.all(...params);
|
|
1104
|
+
return rows.map((r) => this.mapCodeAreaMetrics(r));
|
|
1105
|
+
}
|
|
1106
|
+
mapCodeAreaMetrics(row) {
|
|
1107
|
+
return {
|
|
1108
|
+
id: row.id,
|
|
1109
|
+
codeArea: row.code_area,
|
|
1110
|
+
defectDensity: row.defect_density,
|
|
1111
|
+
churnRate: row.churn_rate,
|
|
1112
|
+
prRejectionRate: row.pr_rejection_rate,
|
|
1113
|
+
codeAcceptanceRate: row.code_acceptance_rate,
|
|
1114
|
+
hasFrontendComponents: Boolean(row.has_frontend_components),
|
|
1115
|
+
designMetricsJson: row.design_metrics_json,
|
|
1116
|
+
dataPointCount: row.data_point_count,
|
|
1117
|
+
windowStart: row.window_start,
|
|
1118
|
+
windowEnd: row.window_end,
|
|
1119
|
+
computedAt: row.computed_at,
|
|
1120
|
+
};
|
|
1121
|
+
}
|
|
1122
|
+
upsertDesignLookaheadNotification(record) {
|
|
1123
|
+
const result = this.db
|
|
1124
|
+
.prepare(`INSERT INTO design_lookahead_notifications (issue_number, pillar_breakdown_json)
|
|
1125
|
+
VALUES (?, ?)
|
|
1126
|
+
ON CONFLICT(issue_number) DO UPDATE SET
|
|
1127
|
+
last_notified_at = datetime('now'),
|
|
1128
|
+
pillar_breakdown_json = COALESCE(excluded.pillar_breakdown_json, pillar_breakdown_json)`)
|
|
1129
|
+
.run(record.issueNumber, record.pillarBreakdownJson ?? null);
|
|
1130
|
+
return Number(result.lastInsertRowid);
|
|
1131
|
+
}
|
|
1132
|
+
getDesignLookaheadNotification(issueNumber) {
|
|
1133
|
+
const row = this.db
|
|
1134
|
+
.prepare(`SELECT * FROM design_lookahead_notifications WHERE issue_number = ?`)
|
|
1135
|
+
.get(issueNumber);
|
|
1136
|
+
if (!row)
|
|
1137
|
+
return undefined;
|
|
1138
|
+
return {
|
|
1139
|
+
id: row.id,
|
|
1140
|
+
issueNumber: row.issue_number,
|
|
1141
|
+
firstNotifiedAt: row.first_notified_at,
|
|
1142
|
+
lastNotifiedAt: row.last_notified_at,
|
|
1143
|
+
pillarBreakdownJson: row.pillar_breakdown_json,
|
|
1144
|
+
};
|
|
1145
|
+
}
|
|
1146
|
+
// ── SA Phase Weights (RFC-0008 §B.8 AISDLC-66) ──────────────────────
|
|
1147
|
+
upsertSaPhaseWeights(record) {
|
|
1148
|
+
this.db
|
|
1149
|
+
.prepare(`INSERT INTO sa_phase_weights (dimension, w_structural, w_llm, calibrated_at)
|
|
1150
|
+
VALUES (?, ?, ?, datetime('now'))
|
|
1151
|
+
ON CONFLICT(dimension) DO UPDATE SET
|
|
1152
|
+
w_structural = excluded.w_structural,
|
|
1153
|
+
w_llm = excluded.w_llm,
|
|
1154
|
+
calibrated_at = excluded.calibrated_at`)
|
|
1155
|
+
.run(record.dimension, record.wStructural, record.wLlm);
|
|
1156
|
+
}
|
|
1157
|
+
getSaPhaseWeights(dimension) {
|
|
1158
|
+
const row = this.db
|
|
1159
|
+
.prepare(`SELECT * FROM sa_phase_weights WHERE dimension = ?`)
|
|
1160
|
+
.get(dimension);
|
|
1161
|
+
if (!row)
|
|
1162
|
+
return undefined;
|
|
1163
|
+
return {
|
|
1164
|
+
id: row.id,
|
|
1165
|
+
dimension: row.dimension,
|
|
1166
|
+
wStructural: row.w_structural,
|
|
1167
|
+
wLlm: row.w_llm,
|
|
1168
|
+
calibratedAt: row.calibrated_at,
|
|
1169
|
+
};
|
|
1170
|
+
}
|
|
714
1171
|
close() {
|
|
715
1172
|
this.db.close();
|
|
716
1173
|
}
|