@ai-sdlc/orchestrator 0.4.0 → 0.6.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/adapters.d.ts +18 -3
- package/dist/adapters.js +92 -2
- package/dist/admission-score.d.ts +58 -0
- package/dist/admission-score.js +164 -0
- package/dist/cli/commands/init.js +4 -8
- package/dist/cli/commands/run.js +2 -2
- package/dist/config.d.ts +3 -0
- package/dist/config.js +14 -5
- package/dist/cycle-utils.d.ts +51 -0
- package/dist/cycle-utils.js +77 -0
- package/dist/defaults.d.ts +5 -0
- package/dist/defaults.js +5 -0
- package/dist/execute.d.ts +5 -2
- package/dist/execute.js +212 -62
- package/dist/fix-ci.js +45 -13
- package/dist/fix-review.d.ts +66 -0
- package/dist/fix-review.js +441 -0
- package/dist/index.d.ts +14 -4
- package/dist/index.js +18 -3
- package/dist/orchestrator.d.ts +1 -1
- package/dist/orchestrator.js +31 -9
- package/dist/pipeline-cycle-detector.d.ts +70 -0
- package/dist/pipeline-cycle-detector.js +111 -0
- package/dist/plugin.d.ts +9 -3
- package/dist/priority.d.ts +28 -0
- package/dist/priority.js +230 -0
- package/dist/review.d.ts +31 -0
- package/dist/review.js +74 -0
- package/dist/runners/claude-code.js +367 -35
- package/dist/runners/codex.js +15 -4
- package/dist/runners/copilot.js +15 -4
- package/dist/runners/cursor.js +15 -4
- package/dist/runners/generic-llm.js +1 -1
- package/dist/runners/index.d.ts +3 -1
- package/dist/runners/index.js +2 -0
- package/dist/runners/review-agent.d.ts +47 -0
- package/dist/runners/review-agent.js +220 -0
- package/dist/runners/security-triage.d.ts +43 -0
- package/dist/runners/security-triage.js +158 -0
- package/dist/runners/types.d.ts +24 -1
- package/dist/security.d.ts +8 -3
- package/dist/security.js +13 -2
- package/dist/shared.d.ts +17 -0
- package/dist/shared.js +27 -0
- package/dist/state/index.d.ts +1 -1
- package/dist/state/schema.d.ts +4 -1
- package/dist/state/schema.js +89 -1
- package/dist/state/store.d.ts +31 -1
- package/dist/state/store.js +208 -13
- package/dist/state/types.d.ts +52 -0
- package/dist/triage.d.ts +36 -0
- package/dist/triage.js +133 -0
- package/dist/types.d.ts +1 -1
- package/dist/watch.d.ts +6 -2
- package/dist/watch.js +34 -6
- 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 +4 -2
package/dist/state/schema.d.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* SQLite DDL and migrations for the state store.
|
|
3
3
|
*/
|
|
4
|
-
export declare const CURRENT_SCHEMA_VERSION =
|
|
4
|
+
export declare const CURRENT_SCHEMA_VERSION = 9;
|
|
5
5
|
export declare const SCHEMA_DDL = "\nCREATE TABLE IF NOT EXISTS schema_version (\n version INTEGER PRIMARY KEY,\n applied_at TEXT DEFAULT (datetime('now'))\n);\n\nCREATE TABLE IF NOT EXISTS complexity_profile (\n id INTEGER PRIMARY KEY,\n repo_path TEXT NOT NULL,\n score REAL NOT NULL,\n files_count INTEGER,\n modules_count INTEGER,\n dependency_count INTEGER,\n analyzed_at TEXT DEFAULT (datetime('now')),\n raw_data TEXT\n);\n\nCREATE TABLE IF NOT EXISTS episodic_memory (\n id INTEGER PRIMARY KEY,\n issue_number INTEGER,\n pr_number INTEGER,\n pipeline_type TEXT NOT NULL,\n outcome TEXT NOT NULL,\n duration_ms INTEGER,\n files_changed INTEGER,\n error_message TEXT,\n metadata TEXT,\n created_at TEXT DEFAULT (datetime('now'))\n);\n\nCREATE TABLE IF NOT EXISTS autonomy_ledger (\n id INTEGER PRIMARY KEY,\n agent_name TEXT NOT NULL UNIQUE,\n current_level INTEGER DEFAULT 0,\n total_tasks INTEGER DEFAULT 0,\n success_count INTEGER DEFAULT 0,\n failure_count INTEGER DEFAULT 0,\n last_task_at TEXT,\n metrics TEXT\n);\n\nCREATE TABLE IF NOT EXISTS pipeline_runs (\n id INTEGER PRIMARY KEY,\n run_id TEXT NOT NULL UNIQUE,\n issue_number INTEGER,\n pr_number INTEGER,\n pipeline_type TEXT NOT NULL,\n status TEXT NOT NULL,\n current_stage TEXT,\n started_at TEXT DEFAULT (datetime('now')),\n completed_at TEXT,\n result TEXT,\n gate_results TEXT\n);\n\nCREATE TABLE IF NOT EXISTS conventions (\n id INTEGER PRIMARY KEY,\n category TEXT NOT NULL,\n pattern TEXT NOT NULL,\n confidence REAL,\n examples TEXT,\n detected_at TEXT DEFAULT (datetime('now'))\n);\n";
|
|
6
6
|
export interface Migration {
|
|
7
7
|
version: number;
|
|
@@ -12,5 +12,8 @@ export declare const MIGRATION_V3 = "\n-- Cost tracking\nCREATE TABLE IF NOT EXI
|
|
|
12
12
|
export declare const MIGRATION_V4 = "\n-- Handoff audit trail\nCREATE TABLE IF NOT EXISTS handoff_events (\n id INTEGER PRIMARY KEY,\n run_id TEXT NOT NULL,\n from_agent TEXT NOT NULL,\n to_agent TEXT NOT NULL,\n payload_hash TEXT,\n validation_result TEXT NOT NULL,\n error_message TEXT,\n created_at TEXT DEFAULT (datetime('now'))\n);\nCREATE INDEX IF NOT EXISTS idx_handoff_events_run ON handoff_events(run_id);\n";
|
|
13
13
|
export declare const MIGRATION_V5 = "\n-- Deployment records\nCREATE TABLE IF NOT EXISTS deployments (\n id INTEGER PRIMARY KEY,\n deployment_id TEXT NOT NULL UNIQUE,\n target_name TEXT NOT NULL,\n provider TEXT NOT NULL,\n version TEXT NOT NULL,\n environment TEXT NOT NULL,\n state TEXT NOT NULL,\n url TEXT,\n error TEXT,\n started_at TEXT DEFAULT (datetime('now')),\n completed_at TEXT\n);\nCREATE INDEX IF NOT EXISTS idx_deployments_target ON deployments(target_name);\nCREATE INDEX IF NOT EXISTS idx_deployments_env ON deployments(environment);\n\n-- Rollout step records\nCREATE TABLE IF NOT EXISTS rollout_steps (\n id INTEGER PRIMARY KEY,\n deployment_id TEXT NOT NULL,\n step_number INTEGER NOT NULL,\n weight_percent INTEGER NOT NULL,\n state TEXT NOT NULL,\n metrics_snapshot TEXT,\n started_at TEXT DEFAULT (datetime('now')),\n completed_at TEXT,\n FOREIGN KEY (deployment_id) REFERENCES deployments(deployment_id)\n);\nCREATE INDEX IF NOT EXISTS idx_rollout_steps_deployment ON rollout_steps(deployment_id);\n\n-- Audit entries (indexed, queryable)\nCREATE TABLE IF NOT EXISTS audit_entries (\n id INTEGER PRIMARY KEY,\n entry_id TEXT NOT NULL UNIQUE,\n actor TEXT NOT NULL,\n action TEXT NOT NULL,\n resource_type TEXT,\n resource_id TEXT,\n detail TEXT,\n hash TEXT,\n previous_hash TEXT,\n signature TEXT,\n created_at TEXT DEFAULT (datetime('now'))\n);\nCREATE INDEX IF NOT EXISTS idx_audit_entries_actor ON audit_entries(actor);\nCREATE INDEX IF NOT EXISTS idx_audit_entries_action ON audit_entries(action);\nCREATE INDEX IF NOT EXISTS idx_audit_entries_resource ON audit_entries(resource_type, resource_id);\nCREATE INDEX IF NOT EXISTS idx_audit_entries_created ON audit_entries(created_at);\n";
|
|
14
14
|
export declare const MIGRATION_V6 = "\n-- Cost governance: add stage_name and cache_read_tokens to cost_ledger\nALTER TABLE cost_ledger ADD COLUMN stage_name TEXT;\nALTER TABLE cost_ledger ADD COLUMN cache_read_tokens INTEGER DEFAULT 0;\n";
|
|
15
|
+
export declare const MIGRATION_V7 = "\n-- String issue IDs\nALTER TABLE pipeline_runs ADD COLUMN issue_id TEXT;\nALTER TABLE episodic_memory ADD COLUMN issue_id TEXT;\nALTER TABLE cost_ledger ADD COLUMN issue_id TEXT;\nALTER TABLE routing_history ADD COLUMN issue_id TEXT;\n";
|
|
16
|
+
export declare const MIGRATION_V8 = "\n-- Priority calibration table (RFC-0005 PPA)\nCREATE TABLE IF NOT EXISTS priority_calibration (\n id INTEGER PRIMARY KEY,\n issue_id TEXT NOT NULL,\n priority_composite REAL NOT NULL,\n priority_confidence REAL NOT NULL,\n priority_dimensions TEXT,\n actual_complexity INTEGER,\n files_changed INTEGER,\n outcome TEXT,\n sampled_at TEXT DEFAULT (datetime('now'))\n);\nCREATE INDEX IF NOT EXISTS idx_priority_calibration_issue ON priority_calibration(issue_id);\nCREATE INDEX IF NOT EXISTS idx_priority_calibration_sampled ON priority_calibration(sampled_at);\n\n-- Extend episodic_memory with priority columns\nALTER TABLE episodic_memory ADD COLUMN priority_composite REAL;\nALTER TABLE episodic_memory ADD COLUMN priority_confidence REAL;\n";
|
|
17
|
+
export declare const MIGRATION_V9 = "\n-- Workflow pattern detection tables\n\n-- Tool sequence events captured by PostToolUse hook\nCREATE TABLE IF NOT EXISTS tool_sequence_events (\n id INTEGER PRIMARY KEY,\n session_id TEXT NOT NULL,\n tool_name TEXT NOT NULL,\n action_canonical TEXT NOT NULL,\n project_path TEXT,\n timestamp TEXT NOT NULL,\n ingested_at TEXT DEFAULT (datetime('now'))\n);\nCREATE INDEX IF NOT EXISTS idx_tool_seq_session ON tool_sequence_events(session_id);\nCREATE INDEX IF NOT EXISTS idx_tool_seq_ts ON tool_sequence_events(timestamp);\n\n-- Detected workflow patterns (from n-gram mining)\nCREATE TABLE IF NOT EXISTS workflow_patterns (\n id INTEGER PRIMARY KEY,\n pattern_hash TEXT NOT NULL UNIQUE,\n pattern_type TEXT NOT NULL,\n sequence_json TEXT NOT NULL,\n frequency INTEGER NOT NULL,\n session_count INTEGER NOT NULL,\n confidence REAL NOT NULL,\n first_seen TEXT,\n last_seen TEXT,\n status TEXT DEFAULT 'detected',\n detected_at TEXT DEFAULT (datetime('now'))\n);\nCREATE INDEX IF NOT EXISTS idx_workflow_patterns_status ON workflow_patterns(status);\n\n-- Automation proposals for human review\nCREATE TABLE IF NOT EXISTS pattern_proposals (\n id INTEGER PRIMARY KEY,\n pattern_id INTEGER NOT NULL,\n proposal_type TEXT NOT NULL,\n artifact_type TEXT NOT NULL,\n artifact_path TEXT,\n draft_content TEXT NOT NULL,\n confidence REAL NOT NULL,\n status TEXT DEFAULT 'pending',\n reviewed_at TEXT,\n reviewer_reason TEXT,\n created_at TEXT DEFAULT (datetime('now')),\n FOREIGN KEY (pattern_id) REFERENCES workflow_patterns(id)\n);\nCREATE INDEX IF NOT EXISTS idx_pattern_proposals_status ON pattern_proposals(status);\n";
|
|
15
18
|
export declare const MIGRATIONS: Migration[];
|
|
16
19
|
//# sourceMappingURL=schema.d.ts.map
|
package/dist/state/schema.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* SQLite DDL and migrations for the state store.
|
|
3
3
|
*/
|
|
4
|
-
export const CURRENT_SCHEMA_VERSION =
|
|
4
|
+
export const CURRENT_SCHEMA_VERSION = 9;
|
|
5
5
|
export const SCHEMA_DDL = `
|
|
6
6
|
CREATE TABLE IF NOT EXISTS schema_version (
|
|
7
7
|
version INTEGER PRIMARY KEY,
|
|
@@ -235,6 +235,82 @@ export const MIGRATION_V6 = `
|
|
|
235
235
|
ALTER TABLE cost_ledger ADD COLUMN stage_name TEXT;
|
|
236
236
|
ALTER TABLE cost_ledger ADD COLUMN cache_read_tokens INTEGER DEFAULT 0;
|
|
237
237
|
`;
|
|
238
|
+
export const MIGRATION_V7 = `
|
|
239
|
+
-- String issue IDs
|
|
240
|
+
ALTER TABLE pipeline_runs ADD COLUMN issue_id TEXT;
|
|
241
|
+
ALTER TABLE episodic_memory ADD COLUMN issue_id TEXT;
|
|
242
|
+
ALTER TABLE cost_ledger ADD COLUMN issue_id TEXT;
|
|
243
|
+
ALTER TABLE routing_history ADD COLUMN issue_id TEXT;
|
|
244
|
+
`;
|
|
245
|
+
export const MIGRATION_V8 = `
|
|
246
|
+
-- Priority calibration table (RFC-0005 PPA)
|
|
247
|
+
CREATE TABLE IF NOT EXISTS priority_calibration (
|
|
248
|
+
id INTEGER PRIMARY KEY,
|
|
249
|
+
issue_id TEXT NOT NULL,
|
|
250
|
+
priority_composite REAL NOT NULL,
|
|
251
|
+
priority_confidence REAL NOT NULL,
|
|
252
|
+
priority_dimensions TEXT,
|
|
253
|
+
actual_complexity INTEGER,
|
|
254
|
+
files_changed INTEGER,
|
|
255
|
+
outcome TEXT,
|
|
256
|
+
sampled_at TEXT DEFAULT (datetime('now'))
|
|
257
|
+
);
|
|
258
|
+
CREATE INDEX IF NOT EXISTS idx_priority_calibration_issue ON priority_calibration(issue_id);
|
|
259
|
+
CREATE INDEX IF NOT EXISTS idx_priority_calibration_sampled ON priority_calibration(sampled_at);
|
|
260
|
+
|
|
261
|
+
-- Extend episodic_memory with priority columns
|
|
262
|
+
ALTER TABLE episodic_memory ADD COLUMN priority_composite REAL;
|
|
263
|
+
ALTER TABLE episodic_memory ADD COLUMN priority_confidence REAL;
|
|
264
|
+
`;
|
|
265
|
+
export const MIGRATION_V9 = `
|
|
266
|
+
-- Workflow pattern detection tables
|
|
267
|
+
|
|
268
|
+
-- Tool sequence events captured by PostToolUse hook
|
|
269
|
+
CREATE TABLE IF NOT EXISTS tool_sequence_events (
|
|
270
|
+
id INTEGER PRIMARY KEY,
|
|
271
|
+
session_id TEXT NOT NULL,
|
|
272
|
+
tool_name TEXT NOT NULL,
|
|
273
|
+
action_canonical TEXT NOT NULL,
|
|
274
|
+
project_path TEXT,
|
|
275
|
+
timestamp TEXT NOT NULL,
|
|
276
|
+
ingested_at TEXT DEFAULT (datetime('now'))
|
|
277
|
+
);
|
|
278
|
+
CREATE INDEX IF NOT EXISTS idx_tool_seq_session ON tool_sequence_events(session_id);
|
|
279
|
+
CREATE INDEX IF NOT EXISTS idx_tool_seq_ts ON tool_sequence_events(timestamp);
|
|
280
|
+
|
|
281
|
+
-- Detected workflow patterns (from n-gram mining)
|
|
282
|
+
CREATE TABLE IF NOT EXISTS workflow_patterns (
|
|
283
|
+
id INTEGER PRIMARY KEY,
|
|
284
|
+
pattern_hash TEXT NOT NULL UNIQUE,
|
|
285
|
+
pattern_type TEXT NOT NULL,
|
|
286
|
+
sequence_json TEXT NOT NULL,
|
|
287
|
+
frequency INTEGER NOT NULL,
|
|
288
|
+
session_count INTEGER NOT NULL,
|
|
289
|
+
confidence REAL NOT NULL,
|
|
290
|
+
first_seen TEXT,
|
|
291
|
+
last_seen TEXT,
|
|
292
|
+
status TEXT DEFAULT 'detected',
|
|
293
|
+
detected_at TEXT DEFAULT (datetime('now'))
|
|
294
|
+
);
|
|
295
|
+
CREATE INDEX IF NOT EXISTS idx_workflow_patterns_status ON workflow_patterns(status);
|
|
296
|
+
|
|
297
|
+
-- Automation proposals for human review
|
|
298
|
+
CREATE TABLE IF NOT EXISTS pattern_proposals (
|
|
299
|
+
id INTEGER PRIMARY KEY,
|
|
300
|
+
pattern_id INTEGER NOT NULL,
|
|
301
|
+
proposal_type TEXT NOT NULL,
|
|
302
|
+
artifact_type TEXT NOT NULL,
|
|
303
|
+
artifact_path TEXT,
|
|
304
|
+
draft_content TEXT NOT NULL,
|
|
305
|
+
confidence REAL NOT NULL,
|
|
306
|
+
status TEXT DEFAULT 'pending',
|
|
307
|
+
reviewed_at TEXT,
|
|
308
|
+
reviewer_reason TEXT,
|
|
309
|
+
created_at TEXT DEFAULT (datetime('now')),
|
|
310
|
+
FOREIGN KEY (pattern_id) REFERENCES workflow_patterns(id)
|
|
311
|
+
);
|
|
312
|
+
CREATE INDEX IF NOT EXISTS idx_pattern_proposals_status ON pattern_proposals(status);
|
|
313
|
+
`;
|
|
238
314
|
export const MIGRATIONS = [
|
|
239
315
|
{
|
|
240
316
|
version: 1,
|
|
@@ -260,5 +336,17 @@ export const MIGRATIONS = [
|
|
|
260
336
|
version: 6,
|
|
261
337
|
sql: MIGRATION_V6,
|
|
262
338
|
},
|
|
339
|
+
{
|
|
340
|
+
version: 7,
|
|
341
|
+
sql: MIGRATION_V7,
|
|
342
|
+
},
|
|
343
|
+
{
|
|
344
|
+
version: 8,
|
|
345
|
+
sql: MIGRATION_V8,
|
|
346
|
+
},
|
|
347
|
+
{
|
|
348
|
+
version: 9,
|
|
349
|
+
sql: MIGRATION_V9,
|
|
350
|
+
},
|
|
263
351
|
];
|
|
264
352
|
//# sourceMappingURL=schema.js.map
|
package/dist/state/store.d.ts
CHANGED
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
* optional — the orchestrator works without it.
|
|
6
6
|
*/
|
|
7
7
|
import type BetterSqlite3 from 'better-sqlite3';
|
|
8
|
-
import type { ComplexityProfile, EpisodicRecord, AutonomyLedgerEntry, PipelineRun, PipelineRunStatus, Convention, HotspotRecord, RoutingDecision, CostLedgerEntry, GateThresholdOverride, AutonomyEvent, HandoffEvent, DeploymentRecord, DeploymentRecordState, RolloutStepRecord, AuditEntryRecord } from './types.js';
|
|
8
|
+
import type { ComplexityProfile, EpisodicRecord, AutonomyLedgerEntry, PipelineRun, PipelineRunStatus, Convention, HotspotRecord, RoutingDecision, CostLedgerEntry, GateThresholdOverride, AutonomyEvent, HandoffEvent, DeploymentRecord, DeploymentRecordState, RolloutStepRecord, AuditEntryRecord, PriorityCalibrationSample, ToolSequenceEvent, WorkflowPattern, PatternProposal } from './types.js';
|
|
9
9
|
export declare class StateStore {
|
|
10
10
|
private db;
|
|
11
11
|
constructor(db: BetterSqlite3.Database);
|
|
@@ -102,8 +102,38 @@ export declare class StateStore {
|
|
|
102
102
|
}): AuditEntryRecord[];
|
|
103
103
|
getAuditEntry(entryId: string): AuditEntryRecord | undefined;
|
|
104
104
|
private mapAuditEntry;
|
|
105
|
+
savePrioritySample(sample: PriorityCalibrationSample): number;
|
|
106
|
+
getPrioritySamples(opts?: {
|
|
107
|
+
since?: string;
|
|
108
|
+
limit?: number;
|
|
109
|
+
}): PriorityCalibrationSample[];
|
|
110
|
+
/**
|
|
111
|
+
* Compute a calibration coefficient from historical priority samples.
|
|
112
|
+
* Returns 1.0 when no data is available.
|
|
113
|
+
* When data exists, compares predicted priority ordering with actual outcomes
|
|
114
|
+
* and adjusts the coefficient to correct systematic over/under-scoring.
|
|
115
|
+
*/
|
|
116
|
+
computeCalibrationCoefficient(opts?: {
|
|
117
|
+
since?: string;
|
|
118
|
+
}): number;
|
|
105
119
|
/** Expose the underlying database for direct queries (e.g. dashboard). */
|
|
106
120
|
getDatabase(): BetterSqlite3.Database;
|
|
121
|
+
saveToolSequenceEvent(event: ToolSequenceEvent): number;
|
|
122
|
+
saveToolSequenceEvents(events: ToolSequenceEvent[]): number;
|
|
123
|
+
getToolSequenceEvents(opts?: {
|
|
124
|
+
sessionId?: string;
|
|
125
|
+
since?: string;
|
|
126
|
+
limit?: number;
|
|
127
|
+
}): ToolSequenceEvent[];
|
|
128
|
+
saveWorkflowPattern(pattern: WorkflowPattern): number;
|
|
129
|
+
getWorkflowPatterns(opts?: {
|
|
130
|
+
status?: string;
|
|
131
|
+
}): WorkflowPattern[];
|
|
132
|
+
savePatternProposal(proposal: PatternProposal): number;
|
|
133
|
+
getPatternProposals(opts?: {
|
|
134
|
+
status?: string;
|
|
135
|
+
}): PatternProposal[];
|
|
136
|
+
updateProposalStatus(id: number, status: string, reason?: string): void;
|
|
107
137
|
close(): void;
|
|
108
138
|
}
|
|
109
139
|
//# sourceMappingURL=store.d.ts.map
|
package/dist/state/store.js
CHANGED
|
@@ -82,11 +82,12 @@ export class StateStore {
|
|
|
82
82
|
// ── Episodic Memory ──────────────────────────────────────────────
|
|
83
83
|
saveEpisodicRecord(record) {
|
|
84
84
|
const stmt = this.db.prepare(`
|
|
85
|
-
INSERT INTO episodic_memory (issue_number, pr_number, pipeline_type, outcome, duration_ms, files_changed, error_message, metadata,
|
|
86
|
-
agent_name, complexity_score, routing_strategy, gate_pass_count, gate_fail_count, cost_usd, is_regression, related_episodes
|
|
87
|
-
|
|
85
|
+
INSERT INTO episodic_memory (issue_id, issue_number, pr_number, pipeline_type, outcome, duration_ms, files_changed, error_message, metadata,
|
|
86
|
+
agent_name, complexity_score, routing_strategy, gate_pass_count, gate_fail_count, cost_usd, is_regression, related_episodes,
|
|
87
|
+
priority_composite, priority_confidence)
|
|
88
|
+
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
|
|
88
89
|
`);
|
|
89
|
-
const result = stmt.run(record.issueNumber ?? null, record.prNumber ?? null, record.pipelineType, record.outcome, record.durationMs ?? null, record.filesChanged ?? null, record.errorMessage ?? null, record.metadata ?? null, record.agentName ?? null, record.complexityScore ?? null, record.routingStrategy ?? null, record.gatePassCount ?? null, record.gateFailCount ?? null, record.costUsd ?? null, record.isRegression ?? 0, record.relatedEpisodes ?? null);
|
|
90
|
+
const result = stmt.run(record.issueId ?? null, record.issueNumber ?? null, record.prNumber ?? null, record.pipelineType, record.outcome, record.durationMs ?? null, record.filesChanged ?? null, record.errorMessage ?? null, record.metadata ?? null, record.agentName ?? null, record.complexityScore ?? null, record.routingStrategy ?? null, record.gatePassCount ?? null, record.gateFailCount ?? null, record.costUsd ?? null, record.isRegression ?? 0, record.relatedEpisodes ?? null, record.priorityComposite ?? null, record.priorityConfidence ?? null);
|
|
90
91
|
return Number(result.lastInsertRowid);
|
|
91
92
|
}
|
|
92
93
|
getEpisodicRecords(issueNumber, limit = 50) {
|
|
@@ -99,6 +100,7 @@ export class StateStore {
|
|
|
99
100
|
mapEpisodicRecord(row) {
|
|
100
101
|
return {
|
|
101
102
|
id: row.id,
|
|
103
|
+
issueId: row.issue_id,
|
|
102
104
|
issueNumber: row.issue_number,
|
|
103
105
|
prNumber: row.pr_number,
|
|
104
106
|
pipelineType: row.pipeline_type,
|
|
@@ -116,6 +118,8 @@ export class StateStore {
|
|
|
116
118
|
costUsd: row.cost_usd,
|
|
117
119
|
isRegression: row.is_regression,
|
|
118
120
|
relatedEpisodes: row.related_episodes,
|
|
121
|
+
priorityComposite: row.priority_composite,
|
|
122
|
+
priorityConfidence: row.priority_confidence,
|
|
119
123
|
};
|
|
120
124
|
}
|
|
121
125
|
// ── Autonomy Ledger ──────────────────────────────────────────────
|
|
@@ -172,11 +176,11 @@ export class StateStore {
|
|
|
172
176
|
// ── Pipeline Runs ────────────────────────────────────────────────
|
|
173
177
|
savePipelineRun(run) {
|
|
174
178
|
const stmt = this.db.prepare(`
|
|
175
|
-
INSERT INTO pipeline_runs (run_id, issue_number, pr_number, pipeline_type, status, current_stage, result, gate_results,
|
|
179
|
+
INSERT INTO pipeline_runs (run_id, issue_id, issue_number, pr_number, pipeline_type, status, current_stage, result, gate_results,
|
|
176
180
|
cost_usd, tokens_used, model, agent_name, complexity_score)
|
|
177
|
-
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
|
|
181
|
+
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
|
|
178
182
|
`);
|
|
179
|
-
const result = stmt.run(run.runId, run.issueNumber ?? null, run.prNumber ?? null, run.pipelineType, run.status, run.currentStage ?? null, run.result ?? null, run.gateResults ?? null, run.costUsd ?? 0, run.tokensUsed ?? 0, run.model ?? null, run.agentName ?? null, run.complexityScore ?? null);
|
|
183
|
+
const result = stmt.run(run.runId, run.issueId ?? null, run.issueNumber ?? null, run.prNumber ?? null, run.pipelineType, run.status, run.currentStage ?? null, run.result ?? null, run.gateResults ?? null, run.costUsd ?? 0, run.tokensUsed ?? 0, run.model ?? null, run.agentName ?? null, run.complexityScore ?? null);
|
|
180
184
|
return Number(result.lastInsertRowid);
|
|
181
185
|
}
|
|
182
186
|
updatePipelineRunStatus(runId, status, opts) {
|
|
@@ -210,6 +214,7 @@ export class StateStore {
|
|
|
210
214
|
return {
|
|
211
215
|
id: row.id,
|
|
212
216
|
runId: row.run_id,
|
|
217
|
+
issueId: row.issue_id,
|
|
213
218
|
issueNumber: row.issue_number,
|
|
214
219
|
prNumber: row.pr_number,
|
|
215
220
|
pipelineType: row.pipeline_type,
|
|
@@ -283,10 +288,10 @@ export class StateStore {
|
|
|
283
288
|
// ── Routing History ───────────────────────────────────────────
|
|
284
289
|
saveRoutingDecision(decision) {
|
|
285
290
|
const stmt = this.db.prepare(`
|
|
286
|
-
INSERT INTO routing_history (issue_number, task_complexity, codebase_complexity, routing_strategy, agent_name, reason)
|
|
287
|
-
VALUES (?, ?, ?, ?, ?, ?)
|
|
291
|
+
INSERT INTO routing_history (issue_id, issue_number, task_complexity, codebase_complexity, routing_strategy, agent_name, reason)
|
|
292
|
+
VALUES (?, ?, ?, ?, ?, ?, ?)
|
|
288
293
|
`);
|
|
289
|
-
const result = stmt.run(decision.issueNumber ?? null, decision.taskComplexity, decision.codebaseComplexity, decision.routingStrategy, decision.agentName ?? null, decision.reason ?? null);
|
|
294
|
+
const result = stmt.run(decision.issueId ?? null, decision.issueNumber ?? null, decision.taskComplexity, decision.codebaseComplexity, decision.routingStrategy, decision.agentName ?? null, decision.reason ?? null);
|
|
290
295
|
return Number(result.lastInsertRowid);
|
|
291
296
|
}
|
|
292
297
|
getRoutingHistory(limit = 50) {
|
|
@@ -298,6 +303,7 @@ export class StateStore {
|
|
|
298
303
|
mapRoutingDecision(row) {
|
|
299
304
|
return {
|
|
300
305
|
id: row.id,
|
|
306
|
+
issueId: row.issue_id,
|
|
301
307
|
issueNumber: row.issue_number,
|
|
302
308
|
taskComplexity: row.task_complexity,
|
|
303
309
|
codebaseComplexity: row.codebase_complexity,
|
|
@@ -310,10 +316,10 @@ export class StateStore {
|
|
|
310
316
|
// ── Cost Ledger ────────────────────────────────────────────────
|
|
311
317
|
saveCostEntry(entry) {
|
|
312
318
|
const stmt = this.db.prepare(`
|
|
313
|
-
INSERT INTO cost_ledger (run_id, agent_name, pipeline_type, model, input_tokens, output_tokens, total_tokens, cost_usd, issue_number, pr_number, stage_name, cache_read_tokens)
|
|
314
|
-
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
|
|
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 (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
|
|
315
321
|
`);
|
|
316
|
-
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.issueNumber ?? null, entry.prNumber ?? null, entry.stageName ?? null, entry.cacheReadTokens ?? 0);
|
|
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);
|
|
317
323
|
return Number(result.lastInsertRowid);
|
|
318
324
|
}
|
|
319
325
|
getCostEntries(opts) {
|
|
@@ -359,6 +365,7 @@ export class StateStore {
|
|
|
359
365
|
outputTokens: row.output_tokens,
|
|
360
366
|
totalTokens: row.total_tokens,
|
|
361
367
|
costUsd: row.cost_usd,
|
|
368
|
+
issueId: row.issue_id,
|
|
362
369
|
issueNumber: row.issue_number,
|
|
363
370
|
prNumber: row.pr_number,
|
|
364
371
|
stageName: row.stage_name,
|
|
@@ -633,11 +640,199 @@ export class StateStore {
|
|
|
633
640
|
createdAt: row.created_at,
|
|
634
641
|
};
|
|
635
642
|
}
|
|
643
|
+
// ── Priority Calibration ──────────────────────────────────────────
|
|
644
|
+
savePrioritySample(sample) {
|
|
645
|
+
const stmt = this.db.prepare(`
|
|
646
|
+
INSERT INTO priority_calibration (issue_id, priority_composite, priority_confidence, priority_dimensions, actual_complexity, files_changed, outcome)
|
|
647
|
+
VALUES (?, ?, ?, ?, ?, ?, ?)
|
|
648
|
+
`);
|
|
649
|
+
const result = stmt.run(sample.issueId, sample.priorityComposite, sample.priorityConfidence, sample.priorityDimensions ?? null, sample.actualComplexity ?? null, sample.filesChanged ?? null, sample.outcome ?? null);
|
|
650
|
+
return Number(result.lastInsertRowid);
|
|
651
|
+
}
|
|
652
|
+
getPrioritySamples(opts) {
|
|
653
|
+
const conditions = [];
|
|
654
|
+
const params = [];
|
|
655
|
+
if (opts?.since) {
|
|
656
|
+
conditions.push('sampled_at >= ?');
|
|
657
|
+
params.push(opts.since);
|
|
658
|
+
}
|
|
659
|
+
const where = conditions.length > 0 ? `WHERE ${conditions.join(' AND ')}` : '';
|
|
660
|
+
const limit = opts?.limit ?? 500;
|
|
661
|
+
params.push(limit);
|
|
662
|
+
const rows = this.db
|
|
663
|
+
.prepare(`SELECT * FROM priority_calibration ${where} ORDER BY sampled_at DESC LIMIT ?`)
|
|
664
|
+
.all(...params);
|
|
665
|
+
return rows.map((r) => ({
|
|
666
|
+
id: r.id,
|
|
667
|
+
issueId: r.issue_id,
|
|
668
|
+
priorityComposite: r.priority_composite,
|
|
669
|
+
priorityConfidence: r.priority_confidence,
|
|
670
|
+
priorityDimensions: r.priority_dimensions,
|
|
671
|
+
actualComplexity: r.actual_complexity,
|
|
672
|
+
filesChanged: r.files_changed,
|
|
673
|
+
outcome: r.outcome,
|
|
674
|
+
sampledAt: r.sampled_at,
|
|
675
|
+
}));
|
|
676
|
+
}
|
|
677
|
+
/**
|
|
678
|
+
* Compute a calibration coefficient from historical priority samples.
|
|
679
|
+
* Returns 1.0 when no data is available.
|
|
680
|
+
* When data exists, compares predicted priority ordering with actual outcomes
|
|
681
|
+
* and adjusts the coefficient to correct systematic over/under-scoring.
|
|
682
|
+
*/
|
|
683
|
+
computeCalibrationCoefficient(opts) {
|
|
684
|
+
const samples = this.getPrioritySamples({ since: opts?.since });
|
|
685
|
+
if (samples.length === 0)
|
|
686
|
+
return 1.0;
|
|
687
|
+
// Filter to samples that have both predicted priority and actual outcome
|
|
688
|
+
const scored = samples.filter((s) => s.outcome === 'success' || s.outcome === 'failure');
|
|
689
|
+
if (scored.length === 0)
|
|
690
|
+
return 1.0;
|
|
691
|
+
// Compute average composite for successes vs failures
|
|
692
|
+
const successes = scored.filter((s) => s.outcome === 'success');
|
|
693
|
+
const failures = scored.filter((s) => s.outcome === 'failure');
|
|
694
|
+
if (successes.length === 0 || failures.length === 0)
|
|
695
|
+
return 1.0;
|
|
696
|
+
const avgSuccess = successes.reduce((sum, s) => sum + s.priorityComposite, 0) / successes.length;
|
|
697
|
+
const avgFailure = failures.reduce((sum, s) => sum + s.priorityComposite, 0) / failures.length;
|
|
698
|
+
// If high-priority items are failing more than low-priority ones,
|
|
699
|
+
// reduce the coefficient to dampen over-scoring; otherwise increase.
|
|
700
|
+
// The ratio is clamped to [0.7, 1.3] per PPA spec.
|
|
701
|
+
if (avgSuccess === 0 && avgFailure === 0)
|
|
702
|
+
return 1.0;
|
|
703
|
+
const ratio = avgSuccess > 0 ? avgFailure / avgSuccess : 1.0;
|
|
704
|
+
// ratio > 1 means failures had higher scores → over-scoring → reduce
|
|
705
|
+
// ratio < 1 means successes had higher scores → well-calibrated or under → increase slightly
|
|
706
|
+
const coefficient = 1.0 / Math.max(ratio, 0.01);
|
|
707
|
+
return Math.min(1.3, Math.max(0.7, coefficient));
|
|
708
|
+
}
|
|
636
709
|
// ── Utilities ────────────────────────────────────────────────────
|
|
637
710
|
/** Expose the underlying database for direct queries (e.g. dashboard). */
|
|
638
711
|
getDatabase() {
|
|
639
712
|
return this.db;
|
|
640
713
|
}
|
|
714
|
+
// ── Workflow Pattern Detection ─────────────────────────────────────
|
|
715
|
+
saveToolSequenceEvent(event) {
|
|
716
|
+
const stmt = this.db.prepare(`
|
|
717
|
+
INSERT INTO tool_sequence_events (session_id, tool_name, action_canonical, project_path, timestamp)
|
|
718
|
+
VALUES (?, ?, ?, ?, ?)
|
|
719
|
+
`);
|
|
720
|
+
const result = stmt.run(event.sessionId, event.toolName, event.actionCanonical, event.projectPath ?? null, event.timestamp);
|
|
721
|
+
return Number(result.lastInsertRowid);
|
|
722
|
+
}
|
|
723
|
+
saveToolSequenceEvents(events) {
|
|
724
|
+
const stmt = this.db.prepare(`
|
|
725
|
+
INSERT INTO tool_sequence_events (session_id, tool_name, action_canonical, project_path, timestamp)
|
|
726
|
+
VALUES (?, ?, ?, ?, ?)
|
|
727
|
+
`);
|
|
728
|
+
const tx = this.db.transaction((items) => {
|
|
729
|
+
for (const e of items) {
|
|
730
|
+
stmt.run(e.sessionId, e.toolName, e.actionCanonical, e.projectPath ?? null, e.timestamp);
|
|
731
|
+
}
|
|
732
|
+
return items.length;
|
|
733
|
+
});
|
|
734
|
+
return tx(events);
|
|
735
|
+
}
|
|
736
|
+
getToolSequenceEvents(opts) {
|
|
737
|
+
const conditions = [];
|
|
738
|
+
const params = [];
|
|
739
|
+
if (opts?.sessionId) {
|
|
740
|
+
conditions.push('session_id = ?');
|
|
741
|
+
params.push(opts.sessionId);
|
|
742
|
+
}
|
|
743
|
+
if (opts?.since) {
|
|
744
|
+
conditions.push('timestamp >= ?');
|
|
745
|
+
params.push(opts.since);
|
|
746
|
+
}
|
|
747
|
+
const where = conditions.length > 0 ? `WHERE ${conditions.join(' AND ')}` : '';
|
|
748
|
+
const limit = opts?.limit ?? 10000;
|
|
749
|
+
params.push(limit);
|
|
750
|
+
const rows = this.db
|
|
751
|
+
.prepare(`SELECT * FROM tool_sequence_events ${where} ORDER BY timestamp ASC LIMIT ?`)
|
|
752
|
+
.all(...params);
|
|
753
|
+
return rows.map((r) => ({
|
|
754
|
+
id: r.id,
|
|
755
|
+
sessionId: r.session_id,
|
|
756
|
+
toolName: r.tool_name,
|
|
757
|
+
actionCanonical: r.action_canonical,
|
|
758
|
+
projectPath: r.project_path,
|
|
759
|
+
timestamp: r.timestamp,
|
|
760
|
+
ingestedAt: r.ingested_at,
|
|
761
|
+
}));
|
|
762
|
+
}
|
|
763
|
+
saveWorkflowPattern(pattern) {
|
|
764
|
+
const stmt = this.db.prepare(`
|
|
765
|
+
INSERT OR REPLACE INTO workflow_patterns
|
|
766
|
+
(pattern_hash, pattern_type, sequence_json, frequency, session_count, confidence, first_seen, last_seen, status)
|
|
767
|
+
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)
|
|
768
|
+
`);
|
|
769
|
+
const result = stmt.run(pattern.patternHash, pattern.patternType, pattern.sequenceJson, pattern.frequency, pattern.sessionCount, pattern.confidence, pattern.firstSeen ?? null, pattern.lastSeen ?? null, pattern.status);
|
|
770
|
+
return Number(result.lastInsertRowid);
|
|
771
|
+
}
|
|
772
|
+
getWorkflowPatterns(opts) {
|
|
773
|
+
const conditions = [];
|
|
774
|
+
const params = [];
|
|
775
|
+
if (opts?.status) {
|
|
776
|
+
conditions.push('status = ?');
|
|
777
|
+
params.push(opts.status);
|
|
778
|
+
}
|
|
779
|
+
const where = conditions.length > 0 ? `WHERE ${conditions.join(' AND ')}` : '';
|
|
780
|
+
const rows = this.db
|
|
781
|
+
.prepare(`SELECT * FROM workflow_patterns ${where} ORDER BY confidence DESC`)
|
|
782
|
+
.all(...params);
|
|
783
|
+
return rows.map((r) => ({
|
|
784
|
+
id: r.id,
|
|
785
|
+
patternHash: r.pattern_hash,
|
|
786
|
+
patternType: r.pattern_type,
|
|
787
|
+
sequenceJson: r.sequence_json,
|
|
788
|
+
frequency: r.frequency,
|
|
789
|
+
sessionCount: r.session_count,
|
|
790
|
+
confidence: r.confidence,
|
|
791
|
+
firstSeen: r.first_seen,
|
|
792
|
+
lastSeen: r.last_seen,
|
|
793
|
+
status: r.status,
|
|
794
|
+
detectedAt: r.detected_at,
|
|
795
|
+
}));
|
|
796
|
+
}
|
|
797
|
+
savePatternProposal(proposal) {
|
|
798
|
+
const stmt = this.db.prepare(`
|
|
799
|
+
INSERT INTO pattern_proposals
|
|
800
|
+
(pattern_id, proposal_type, artifact_type, artifact_path, draft_content, confidence, status)
|
|
801
|
+
VALUES (?, ?, ?, ?, ?, ?, ?)
|
|
802
|
+
`);
|
|
803
|
+
const result = stmt.run(proposal.patternId, proposal.proposalType, proposal.artifactType, proposal.artifactPath ?? null, proposal.draftContent, proposal.confidence, proposal.status);
|
|
804
|
+
return Number(result.lastInsertRowid);
|
|
805
|
+
}
|
|
806
|
+
getPatternProposals(opts) {
|
|
807
|
+
const conditions = [];
|
|
808
|
+
const params = [];
|
|
809
|
+
if (opts?.status) {
|
|
810
|
+
conditions.push('status = ?');
|
|
811
|
+
params.push(opts.status);
|
|
812
|
+
}
|
|
813
|
+
const where = conditions.length > 0 ? `WHERE ${conditions.join(' AND ')}` : '';
|
|
814
|
+
const rows = this.db
|
|
815
|
+
.prepare(`SELECT * FROM pattern_proposals ${where} ORDER BY confidence DESC`)
|
|
816
|
+
.all(...params);
|
|
817
|
+
return rows.map((r) => ({
|
|
818
|
+
id: r.id,
|
|
819
|
+
patternId: r.pattern_id,
|
|
820
|
+
proposalType: r.proposal_type,
|
|
821
|
+
artifactType: r.artifact_type,
|
|
822
|
+
artifactPath: r.artifact_path,
|
|
823
|
+
draftContent: r.draft_content,
|
|
824
|
+
confidence: r.confidence,
|
|
825
|
+
status: r.status,
|
|
826
|
+
reviewedAt: r.reviewed_at,
|
|
827
|
+
reviewerReason: r.reviewer_reason,
|
|
828
|
+
createdAt: r.created_at,
|
|
829
|
+
}));
|
|
830
|
+
}
|
|
831
|
+
updateProposalStatus(id, status, reason) {
|
|
832
|
+
this.db
|
|
833
|
+
.prepare(`UPDATE pattern_proposals SET status = ?, reviewed_at = datetime('now'), reviewer_reason = ? WHERE id = ?`)
|
|
834
|
+
.run(status, reason ?? null, id);
|
|
835
|
+
}
|
|
641
836
|
close() {
|
|
642
837
|
this.db.close();
|
|
643
838
|
}
|
package/dist/state/types.d.ts
CHANGED
|
@@ -21,6 +21,7 @@ export interface ComplexityProfile {
|
|
|
21
21
|
}
|
|
22
22
|
export interface EpisodicRecord {
|
|
23
23
|
id?: number;
|
|
24
|
+
issueId?: string;
|
|
24
25
|
issueNumber?: number;
|
|
25
26
|
prNumber?: number;
|
|
26
27
|
pipelineType: string;
|
|
@@ -38,6 +39,8 @@ export interface EpisodicRecord {
|
|
|
38
39
|
costUsd?: number;
|
|
39
40
|
isRegression?: number;
|
|
40
41
|
relatedEpisodes?: string;
|
|
42
|
+
priorityComposite?: number;
|
|
43
|
+
priorityConfidence?: number;
|
|
41
44
|
}
|
|
42
45
|
export interface AutonomyLedgerEntry {
|
|
43
46
|
id?: number;
|
|
@@ -59,6 +62,7 @@ export type PipelineRunStatus = 'pending' | 'running' | 'completed' | 'failed' |
|
|
|
59
62
|
export interface PipelineRun {
|
|
60
63
|
id?: number;
|
|
61
64
|
runId: string;
|
|
65
|
+
issueId?: string;
|
|
62
66
|
issueNumber?: number;
|
|
63
67
|
prNumber?: number;
|
|
64
68
|
pipelineType: string;
|
|
@@ -95,6 +99,7 @@ export interface HotspotRecord {
|
|
|
95
99
|
}
|
|
96
100
|
export interface RoutingDecision {
|
|
97
101
|
id?: number;
|
|
102
|
+
issueId?: string;
|
|
98
103
|
issueNumber?: number;
|
|
99
104
|
taskComplexity: number;
|
|
100
105
|
codebaseComplexity: number;
|
|
@@ -113,6 +118,7 @@ export interface CostLedgerEntry {
|
|
|
113
118
|
outputTokens?: number;
|
|
114
119
|
totalTokens?: number;
|
|
115
120
|
costUsd?: number;
|
|
121
|
+
issueId?: string;
|
|
116
122
|
issueNumber?: number;
|
|
117
123
|
prNumber?: number;
|
|
118
124
|
stageName?: string;
|
|
@@ -150,6 +156,17 @@ export interface HandoffEvent {
|
|
|
150
156
|
errorMessage?: string;
|
|
151
157
|
createdAt?: string;
|
|
152
158
|
}
|
|
159
|
+
export interface PriorityCalibrationSample {
|
|
160
|
+
id?: number;
|
|
161
|
+
issueId: string;
|
|
162
|
+
priorityComposite: number;
|
|
163
|
+
priorityConfidence: number;
|
|
164
|
+
priorityDimensions?: string;
|
|
165
|
+
actualComplexity?: number;
|
|
166
|
+
filesChanged?: number;
|
|
167
|
+
outcome?: string;
|
|
168
|
+
sampledAt?: string;
|
|
169
|
+
}
|
|
153
170
|
export type DeploymentRecordState = 'pending' | 'deploying' | 'healthy' | 'unhealthy' | 'rolled-back' | 'failed';
|
|
154
171
|
export interface DeploymentRecord {
|
|
155
172
|
id?: number;
|
|
@@ -187,4 +204,39 @@ export interface AuditEntryRecord {
|
|
|
187
204
|
signature?: string;
|
|
188
205
|
createdAt?: string;
|
|
189
206
|
}
|
|
207
|
+
export interface ToolSequenceEvent {
|
|
208
|
+
id?: number;
|
|
209
|
+
sessionId: string;
|
|
210
|
+
toolName: string;
|
|
211
|
+
actionCanonical: string;
|
|
212
|
+
projectPath?: string;
|
|
213
|
+
timestamp: string;
|
|
214
|
+
ingestedAt?: string;
|
|
215
|
+
}
|
|
216
|
+
export interface WorkflowPattern {
|
|
217
|
+
id?: number;
|
|
218
|
+
patternHash: string;
|
|
219
|
+
patternType: string;
|
|
220
|
+
sequenceJson: string;
|
|
221
|
+
frequency: number;
|
|
222
|
+
sessionCount: number;
|
|
223
|
+
confidence: number;
|
|
224
|
+
firstSeen?: string;
|
|
225
|
+
lastSeen?: string;
|
|
226
|
+
status: string;
|
|
227
|
+
detectedAt?: string;
|
|
228
|
+
}
|
|
229
|
+
export interface PatternProposal {
|
|
230
|
+
id?: number;
|
|
231
|
+
patternId: number;
|
|
232
|
+
proposalType: string;
|
|
233
|
+
artifactType: string;
|
|
234
|
+
artifactPath?: string;
|
|
235
|
+
draftContent: string;
|
|
236
|
+
confidence: number;
|
|
237
|
+
status: string;
|
|
238
|
+
reviewedAt?: string;
|
|
239
|
+
reviewerReason?: string;
|
|
240
|
+
createdAt?: string;
|
|
241
|
+
}
|
|
190
242
|
//# sourceMappingURL=types.d.ts.map
|
package/dist/triage.d.ts
ADDED
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Security triage pipeline — lightweight entry point that fetches an issue,
|
|
3
|
+
* runs the SecurityTriageRunner, posts findings as a comment, and applies
|
|
4
|
+
* a `rejected` or `triage-passed` label.
|
|
5
|
+
*
|
|
6
|
+
* **Asymmetric by design**: the triage agent can auto-reject issues above the
|
|
7
|
+
* risk threshold, but NEVER auto-approves (no `ai-ready` label). A human
|
|
8
|
+
* must review the triage analysis and manually apply `ai-ready`.
|
|
9
|
+
*/
|
|
10
|
+
import type { IssueTracker } from '@ai-sdlc/reference';
|
|
11
|
+
import { type SecurityTriageConfig, type TriageVerdict } from './runners/security-triage.js';
|
|
12
|
+
import { type Logger } from './logger.js';
|
|
13
|
+
export interface TriageOptions {
|
|
14
|
+
/** Override the issue tracker (skips config-driven resolution). */
|
|
15
|
+
tracker?: IssueTracker;
|
|
16
|
+
/** SecurityTriageRunner configuration overrides. */
|
|
17
|
+
triageConfig?: SecurityTriageConfig;
|
|
18
|
+
/** Custom logger. */
|
|
19
|
+
logger?: Logger;
|
|
20
|
+
/** Working directory for config loading. Defaults to cwd. */
|
|
21
|
+
workDir?: string;
|
|
22
|
+
/** If true, skip posting a comment to the issue. */
|
|
23
|
+
dryRun?: boolean;
|
|
24
|
+
}
|
|
25
|
+
export interface TriageResult {
|
|
26
|
+
issueId: string;
|
|
27
|
+
verdict: TriageVerdict;
|
|
28
|
+
/** Whether the issue was auto-rejected (riskScore >= threshold). */
|
|
29
|
+
rejected: boolean;
|
|
30
|
+
/** The label applied to the issue, if any. */
|
|
31
|
+
labelApplied?: string;
|
|
32
|
+
/** Error message if the triage pipeline failed. */
|
|
33
|
+
error?: string;
|
|
34
|
+
}
|
|
35
|
+
export declare function executeTriage(issueId: string, options?: TriageOptions): Promise<TriageResult>;
|
|
36
|
+
//# sourceMappingURL=triage.d.ts.map
|