@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.
Files changed (72) hide show
  1. package/dist/action-enforcement.d.ts +26 -0
  2. package/dist/action-enforcement.js +70 -0
  3. package/dist/adapters.d.ts +18 -3
  4. package/dist/adapters.js +92 -2
  5. package/dist/admission-score.d.ts +58 -0
  6. package/dist/admission-score.js +164 -0
  7. package/dist/cli/commands/init.js +4 -8
  8. package/dist/cli/commands/run.js +2 -2
  9. package/dist/config.d.ts +3 -0
  10. package/dist/config.js +14 -5
  11. package/dist/cycle-utils.d.ts +51 -0
  12. package/dist/cycle-utils.js +77 -0
  13. package/dist/defaults.d.ts +5 -0
  14. package/dist/defaults.js +5 -0
  15. package/dist/execute.d.ts +5 -2
  16. package/dist/execute.js +212 -62
  17. package/dist/fix-ci.js +45 -13
  18. package/dist/fix-review.d.ts +66 -0
  19. package/dist/fix-review.js +441 -0
  20. package/dist/index.d.ts +14 -4
  21. package/dist/index.js +18 -3
  22. package/dist/orchestrator.d.ts +1 -1
  23. package/dist/orchestrator.js +31 -9
  24. package/dist/pipeline-cycle-detector.d.ts +70 -0
  25. package/dist/pipeline-cycle-detector.js +111 -0
  26. package/dist/plugin.d.ts +9 -3
  27. package/dist/priority.d.ts +28 -0
  28. package/dist/priority.js +230 -0
  29. package/dist/review.d.ts +31 -0
  30. package/dist/review.js +74 -0
  31. package/dist/runners/claude-code.js +367 -35
  32. package/dist/runners/codex.js +15 -4
  33. package/dist/runners/copilot.js +15 -4
  34. package/dist/runners/cursor.js +15 -4
  35. package/dist/runners/generic-llm.js +1 -1
  36. package/dist/runners/index.d.ts +3 -1
  37. package/dist/runners/index.js +2 -0
  38. package/dist/runners/review-agent.d.ts +47 -0
  39. package/dist/runners/review-agent.js +220 -0
  40. package/dist/runners/security-triage.d.ts +43 -0
  41. package/dist/runners/security-triage.js +158 -0
  42. package/dist/runners/types.d.ts +24 -1
  43. package/dist/security.d.ts +8 -3
  44. package/dist/security.js +13 -2
  45. package/dist/shared.d.ts +17 -0
  46. package/dist/shared.js +27 -0
  47. package/dist/state/index.d.ts +1 -1
  48. package/dist/state/schema.d.ts +4 -1
  49. package/dist/state/schema.js +89 -1
  50. package/dist/state/store.d.ts +31 -1
  51. package/dist/state/store.js +208 -13
  52. package/dist/state/types.d.ts +52 -0
  53. package/dist/triage.d.ts +36 -0
  54. package/dist/triage.js +133 -0
  55. package/dist/types.d.ts +1 -1
  56. package/dist/watch.d.ts +6 -2
  57. package/dist/watch.js +34 -6
  58. package/dist/workflow-patterns/artifact-writer.d.ts +16 -0
  59. package/dist/workflow-patterns/artifact-writer.js +34 -0
  60. package/dist/workflow-patterns/classifiers.d.ts +10 -0
  61. package/dist/workflow-patterns/classifiers.js +72 -0
  62. package/dist/workflow-patterns/detector.d.ts +27 -0
  63. package/dist/workflow-patterns/detector.js +186 -0
  64. package/dist/workflow-patterns/index.d.ts +8 -0
  65. package/dist/workflow-patterns/index.js +7 -0
  66. package/dist/workflow-patterns/proposal-generator.d.ts +15 -0
  67. package/dist/workflow-patterns/proposal-generator.js +183 -0
  68. package/dist/workflow-patterns/telemetry-ingest.d.ts +27 -0
  69. package/dist/workflow-patterns/telemetry-ingest.js +103 -0
  70. package/dist/workflow-patterns/types.d.ts +61 -0
  71. package/dist/workflow-patterns/types.js +11 -0
  72. package/package.json +4 -2
package/dist/index.d.ts CHANGED
@@ -5,7 +5,9 @@ export { validateAgentOutput, type ValidationContext, type ValidationResult, typ
5
5
  export { createLogger, type Logger } from './logger.js';
6
6
  export { validateConfigFiles, type FileValidationResult } from './validate-config.js';
7
7
  export { executeFixCI, countRetryAttempts, fetchCILogs, type FixCIOptions } from './fix-ci.js';
8
- export { getGitHubConfig, resolveRepoRoot, createDefaultAuditLog, resolveAutonomyLevel, resolveConstraints, mergeBlockedPaths, isAutonomousStrategy, recordMetric, validateAndAuditOutput, createPipelineMemory, evaluatePipelineCompliance, authorizeFilesChanged, extractIssueNumber, BRANCH_PATTERN, createAbacPermissionHook, createBlockedPathsHook, createAuditLoggingHook, createPipelineAuthorizationChain, type GitHubEnvConfig, type ValidateAndAuditParams, } from './shared.js';
8
+ export { executeFixReview, countRetryAttempts as countReviewRetryAttempts, fetchReviewFindings, type FixReviewOptions, } from './fix-review.js';
9
+ export { executeTriage, type TriageOptions, type TriageResult } from './triage.js';
10
+ export { getGitHubConfig, resolveRepoRoot, createDefaultAuditLog, resolveAutonomyLevel, resolveConstraints, mergeBlockedPaths, isAutonomousStrategy, recordMetric, validateAndAuditOutput, createPipelineMemory, evaluatePipelineCompliance, authorizeFilesChanged, extractIssueNumber, extractIssueId, issueIdToNumber, formatIssueRef, BRANCH_PATTERN, createAbacPermissionHook, createBlockedPathsHook, createAuditLoggingHook, createPipelineAuthorizationChain, type GitHubEnvConfig, type ValidateAndAuditParams, } from './shared.js';
9
11
  export { DEFAULT_MODEL, DEFAULT_GITHUB_ORG, DEFAULT_GITHUB_REPO, DEFAULT_GITHUB_REPOSITORY, DEFAULT_CONFIG_DIR_NAME, DEFAULT_SANDBOX_MEMORY_MB, DEFAULT_SANDBOX_CPU_PERCENT, DEFAULT_SANDBOX_NETWORK_POLICY, DEFAULT_SANDBOX_TIMEOUT_MS, defaultSandboxConstraints, DEFAULT_RUNNER_TIMEOUT_MS, DEFAULT_ALLOWED_TOOLS, DEFAULT_MAX_FILES_PER_CHANGE, DEFAULT_REQUIRE_TESTS, DEFAULT_BLOCKED_PATHS, DEFAULT_MAX_FIX_ATTEMPTS, DEFAULT_MAX_LOG_LINES, DEFAULT_GH_CLI_TIMEOUT_MS, DEFAULT_JIT_TTL_MS, DEFAULT_JIT_SCOPE, DEFAULT_BRANCH_TEMPLATE, DEFAULT_BRANCH_PATTERN, DEFAULT_PR_TITLE_TEMPLATE, DEFAULT_PR_FOOTER, DEFAULT_COMPLEXITY_THRESHOLDS, DEFAULT_MAX_LINES_PER_PR, DEFAULT_ANALYSIS_INCLUDE, DEFAULT_ANALYSIS_EXCLUDE, DEFAULT_GIT_HISTORY_DAYS, DEFAULT_HOTSPOT_THRESHOLD, NOTIFICATION_TITLES, DEFAULT_MODEL_COSTS, DEFAULT_COST_BUDGET_USD, DEFAULT_DASHBOARD_REFRESH_MS, PROGRESSIVE_GATE_PROFILES, DEFAULT_LINT_COMMAND, DEFAULT_FORMAT_COMMAND, DEFAULT_COMMIT_MESSAGE_TEMPLATE, DEFAULT_COMMIT_CO_AUTHOR, DEFAULT_OPENAI_API_URL, DEFAULT_OPENAI_MODEL, DEFAULT_ANTHROPIC_API_URL, DEFAULT_ANTHROPIC_MODEL, DEFAULT_GENERIC_LLM_MODEL, DEFAULT_LLM_TIMEOUT_MS, DEFAULT_LLM_MAX_TOKENS, DEFAULT_LLM_SYSTEM_PROMPT, DEFAULT_DOCKER_IMAGE, DEFAULT_WORKFLOW_FILE, DEFAULT_LABEL_TO_SKILL_MAP, DEFAULT_ANALYSIS_CACHE_TTL_MS, } from './defaults.js';
10
12
  export type { ComplexityBand, GateProfile } from './defaults.js';
11
13
  export { renderTemplate } from './notifications.js';
@@ -16,19 +18,25 @@ export { createPipelineMetricStore, createInstrumentedEnforcement, createInstrum
16
18
  export { createPipelineDiscovery, findMatchingAgent, resolveAgentForIssue, matchAgentBySkill, createStubAgentCardFetcher, createPipelineAgentCardFetcher, } from './discovery.js';
17
19
  export { createStructuredConsoleLogger, createStructuredBufferLogger, } from './structured-logger.js';
18
20
  export { startWatch, type WatchOptions, type WatchHandle } from './watch.js';
21
+ export { computePriority, rankWorkItems, type PriorityScore, type PriorityInput, type PriorityConfig, } from './priority.js';
22
+ export { checkAction, enforceAction, DEFAULT_BLOCKED_ACTIONS, type ActionEnforcementResult, } from './action-enforcement.js';
23
+ export { scoreIssueForAdmission, mapIssueToPriorityInput, type AdmissionInput, type AdmissionThresholds, type IssueAdmissionResult, type AuthorAssociation, } from './admission-score.js';
24
+ export { executeReview, type ReviewContext, type ReviewOptions } from './review.js';
19
25
  export { createPipelineOrchestration, executePipelineOrchestration, validatePipelineHandoffs, sequential, parallel, hybrid, hierarchical, swarm, validateHandoff, simpleSchemaValidate, } from './orchestration.js';
20
26
  export { createPipelineRegoEvaluator, createPipelineCELEvaluator, createPipelineABACHook, createPipelineExpressionEvaluator, createPipelineLLMEvaluator, evaluatePipelineGate, scorePipelineComplexity, evaluatePipelineComplexityRouting, } from './policy-evaluators.js';
21
- export { createPipelineAdapterRegistry, createPipelineWebhookBridge, resolveAdapterFromGit, resolveInfrastructure, scanPipelineAdapters, } from './adapters.js';
27
+ export { createPipelineAdapterRegistry, createPipelineWebhookBridge, resolveAdapterFromGit, resolveInfrastructure, resolveIssueTrackerFromConfig, scanPipelineAdapters, } from './adapters.js';
22
28
  export { createPipelineReconciler, createGateReconciler, createAutonomyReconciler, hasResourceChanged, fingerprintResource, } from './reconcilers.js';
23
29
  export { createFileAuditLog, verifyAuditIntegrity, loadAuditEntries, rotateAuditLog, computeAuditHash, } from './audit-extended.js';
24
30
  export { checkFrameworkCompliance, getControlCatalog, getFrameworkMappings, listSupportedFrameworks, } from './compliance-extended.js';
25
31
  export { createSilentLogger, withPipelineSpanSync, getPipelineTracer, validateResourceSchema, } from './telemetry-extended.js';
26
- export { ClaudeCodeRunner, ClaudeCodeRunner as GitHubActionsRunner, GenericLLMRunner, CopilotRunner, CursorRunner, CodexRunner, RunnerRegistry, createRunnerRegistry, type AgentRunner, type AgentContext, type AgentResult, type GenericLLMConfig, type RegisteredRunner, } from './runners/index.js';
32
+ export { ClaudeCodeRunner, ClaudeCodeRunner as GitHubActionsRunner, GenericLLMRunner, CopilotRunner, CursorRunner, CodexRunner, RunnerRegistry, createRunnerRegistry, SecurityTriageRunner, ReviewAgentRunner, REVIEW_PROMPTS, type AgentRunner, type AgentContext, type AgentResult, type AgentProgressEvent, type GenericLLMConfig, type RegisteredRunner, type SecurityTriageConfig, type TriageVerdict, type ReviewAgentConfig, type ReviewType, type ReviewFinding, type ReviewVerdict, } from './runners/index.js';
27
33
  export type { TokenUsage } from './runners/index.js';
28
34
  export { SlackMessenger, TeamsMessenger, NotificationRouter } from './notifications/index.js';
29
35
  export type { SlackConfig, TeamsConfig, PipelineEvent, PipelineEventType, NotificationRoute, NotificationTemplate, } from './notifications/index.js';
30
36
  export { StateStore } from './state/index.js';
31
- export type { HotspotRecord, RoutingDecision, CostLedgerEntry, GateThresholdOverride, AutonomyEvent, AutonomyEventType, HandoffEvent, DeploymentRecord, DeploymentRecordState, RolloutStepRecord, AuditEntryRecord, } from './state/index.js';
37
+ export type { HotspotRecord, RoutingDecision, CostLedgerEntry, GateThresholdOverride, AutonomyEvent, AutonomyEventType, HandoffEvent, DeploymentRecord, DeploymentRecordState, RolloutStepRecord, AuditEntryRecord, PriorityCalibrationSample, ToolSequenceEvent, WorkflowPattern, PatternProposal, } from './state/index.js';
38
+ export { readToolSequenceJSONL, readSessionMetaFiles, sessionMetaToEvents, categorizeAction, DEFAULT_DETECTION_OPTIONS, } from './workflow-patterns/index.js';
39
+ export type { CanonicalStep, NGram, DetectedPattern, DetectionOptions, RawToolSequenceEntry, SessionMeta, } from './workflow-patterns/index.js';
32
40
  export { createKubernetesTarget, createVercelTarget, createFlyioTarget, createHttpMetricsCollector, createStubMetricsCollector, RolloutController, } from './deploy/index.js';
33
41
  export type { DeploymentTargetConfig, HealthCheckConfig, DeploymentState, DeploymentResult, DeploymentTarget, ExecFn, FetchFn, KubernetesConfig, VercelConfig, FlyioConfig, CanaryStep, CanaryConfig, BlueGreenConfig, RollingConfig, RolloutStrategy, RolloutPhase, RolloutStatus, RolloutMetrics, MetricsSource, RolloutControllerConfig, HttpMetricsConfig, } from './deploy/index.js';
34
42
  export { getComplexityBand, getGateProfile, adjustEnforcement, adjustGateForComplexity, adjustGatesForComplexity, computeGateAdjustments, } from './progressive-gates.js';
@@ -67,5 +75,7 @@ export type { ArchiveManifest, ArchivalOptions } from './audit-archival.js';
67
75
  export { Orchestrator, type OrchestratorConfig, type WebhookConfig } from './orchestrator.js';
68
76
  export type { OrchestratorPlugin, PluginContext, BeforeRunEvent, AfterRunEvent, RunErrorEvent, } from './plugin.js';
69
77
  export { CostGovernancePlugin } from './cost-governance.js';
78
+ export { PipelineCycleDetector, createStageMarker, parseStageInvocations, DEFAULT_CYCLE_LIMITS, type PipelineStage, type CycleConfig, type CycleDetectionResult, } from './pipeline-cycle-detector.js';
79
+ export { checkAndHandleCycle, createCycleDetectorFromConfig, type CycleHandlerOptions, type CycleCheckResult, } from './cycle-utils.js';
70
80
  export type { ApiVersion, Metadata, Condition, SecretRef, MetricCondition, Duration, Resource, TriggerFilter, Trigger, Provider, RoutingStrategy, ComplexityThreshold, Routing, Stage, PipelineSpec, PipelinePhase, PipelineStatus, Pipeline, AgentConstraints, HandoffContractRef, Handoff, SkillExample, Skill, AgentCard, AgentRoleSpec, AgentRoleStatus, AgentRole, GateScope, MetricRule, ToolRule, ReviewerRule, DocumentationRule, ProvenanceRule, ExpressionRule, GateRule, EnforcementLevel, Override, RetryPolicy, Evaluation, Gate, QualityGateSpec, QualityGateStatus, QualityGate, Permissions, ApprovalRequirement, Guardrails, MonitoringLevel, AutonomyLevel, PromotionCriteria, DemotionTrigger, AgentAutonomyStatus, AutonomyPolicySpec, AutonomyPolicyStatus, AutonomyPolicy, AdapterInterface, HealthCheck, AdapterBindingSpec, AdapterBindingStatus, AdapterBinding, AnyResource, ResourceKind, ValidationError, GateVerdict, DemotionResult, ComplexityFactor, AuthorizationContext, AuthorizationResult, AuthIdentity, AuthenticationResult, Authenticator, MutatingGateContext, ExpressionEvaluator, ExpressionVerdict, LLMEvaluationDimension, LLMEvaluationResult, LLMGateVerdict, AgentExecutionState, HandoffValidationError, SchemaResolver, SchemaValidationError, MemoryTier, MemoryEntry, WorkingMemory, ShortTermMemory, LongTermMemory, SharedMemory, EpisodicMemory, } from './types.js';
71
81
  //# sourceMappingURL=index.d.ts.map
package/dist/index.js CHANGED
@@ -6,8 +6,10 @@ export { validateAgentOutput, } from './validate-agent-output.js';
6
6
  export { createLogger } from './logger.js';
7
7
  export { validateConfigFiles } from './validate-config.js';
8
8
  export { executeFixCI, countRetryAttempts, fetchCILogs } from './fix-ci.js';
9
+ export { executeFixReview, countRetryAttempts as countReviewRetryAttempts, fetchReviewFindings, } from './fix-review.js';
10
+ export { executeTriage } from './triage.js';
9
11
  // Shared utilities
10
- export { getGitHubConfig, resolveRepoRoot, createDefaultAuditLog, resolveAutonomyLevel, resolveConstraints, mergeBlockedPaths, isAutonomousStrategy, recordMetric, validateAndAuditOutput, createPipelineMemory, evaluatePipelineCompliance, authorizeFilesChanged, extractIssueNumber, BRANCH_PATTERN, createAbacPermissionHook, createBlockedPathsHook, createAuditLoggingHook, createPipelineAuthorizationChain, } from './shared.js';
12
+ export { getGitHubConfig, resolveRepoRoot, createDefaultAuditLog, resolveAutonomyLevel, resolveConstraints, mergeBlockedPaths, isAutonomousStrategy, recordMetric, validateAndAuditOutput, createPipelineMemory, evaluatePipelineCompliance, authorizeFilesChanged, extractIssueNumber, extractIssueId, issueIdToNumber, formatIssueRef, BRANCH_PATTERN, createAbacPermissionHook, createBlockedPathsHook, createAuditLoggingHook, createPipelineAuthorizationChain, } from './shared.js';
11
13
  // Defaults
12
14
  export { DEFAULT_MODEL, DEFAULT_GITHUB_ORG, DEFAULT_GITHUB_REPO, DEFAULT_GITHUB_REPOSITORY, DEFAULT_CONFIG_DIR_NAME, DEFAULT_SANDBOX_MEMORY_MB, DEFAULT_SANDBOX_CPU_PERCENT, DEFAULT_SANDBOX_NETWORK_POLICY, DEFAULT_SANDBOX_TIMEOUT_MS, defaultSandboxConstraints, DEFAULT_RUNNER_TIMEOUT_MS, DEFAULT_ALLOWED_TOOLS, DEFAULT_MAX_FILES_PER_CHANGE, DEFAULT_REQUIRE_TESTS, DEFAULT_BLOCKED_PATHS, DEFAULT_MAX_FIX_ATTEMPTS, DEFAULT_MAX_LOG_LINES, DEFAULT_GH_CLI_TIMEOUT_MS, DEFAULT_JIT_TTL_MS, DEFAULT_JIT_SCOPE, DEFAULT_BRANCH_TEMPLATE, DEFAULT_BRANCH_PATTERN, DEFAULT_PR_TITLE_TEMPLATE, DEFAULT_PR_FOOTER, DEFAULT_COMPLEXITY_THRESHOLDS, DEFAULT_MAX_LINES_PER_PR, DEFAULT_ANALYSIS_INCLUDE, DEFAULT_ANALYSIS_EXCLUDE, DEFAULT_GIT_HISTORY_DAYS, DEFAULT_HOTSPOT_THRESHOLD, NOTIFICATION_TITLES, DEFAULT_MODEL_COSTS, DEFAULT_COST_BUDGET_USD, DEFAULT_DASHBOARD_REFRESH_MS, PROGRESSIVE_GATE_PROFILES, DEFAULT_LINT_COMMAND, DEFAULT_FORMAT_COMMAND, DEFAULT_COMMIT_MESSAGE_TEMPLATE, DEFAULT_COMMIT_CO_AUTHOR, DEFAULT_OPENAI_API_URL, DEFAULT_OPENAI_MODEL, DEFAULT_ANTHROPIC_API_URL, DEFAULT_ANTHROPIC_MODEL, DEFAULT_GENERIC_LLM_MODEL, DEFAULT_LLM_TIMEOUT_MS, DEFAULT_LLM_MAX_TOKENS, DEFAULT_LLM_SYSTEM_PROMPT, DEFAULT_DOCKER_IMAGE, DEFAULT_WORKFLOW_FILE, DEFAULT_LABEL_TO_SKILL_MAP, DEFAULT_ANALYSIS_CACHE_TTL_MS, } from './defaults.js';
13
15
  // Notifications
@@ -26,12 +28,20 @@ export { createPipelineDiscovery, findMatchingAgent, resolveAgentForIssue, match
26
28
  export { createStructuredConsoleLogger, createStructuredBufferLogger, } from './structured-logger.js';
27
29
  // Watch mode
28
30
  export { startWatch } from './watch.js';
31
+ // Priority scoring (PPA)
32
+ export { computePriority, rankWorkItems, } from './priority.js';
33
+ // Action enforcement
34
+ export { checkAction, enforceAction, DEFAULT_BLOCKED_ACTIONS, } from './action-enforcement.js';
35
+ // Issue admission scoring
36
+ export { scoreIssueForAdmission, mapIssueToPriorityInput, } from './admission-score.js';
37
+ // PR review orchestration
38
+ export { executeReview } from './review.js';
29
39
  // Agent orchestration
30
40
  export { createPipelineOrchestration, executePipelineOrchestration, validatePipelineHandoffs, sequential, parallel, hybrid, hierarchical, swarm, validateHandoff, simpleSchemaValidate, } from './orchestration.js';
31
41
  // Policy evaluators
32
42
  export { createPipelineRegoEvaluator, createPipelineCELEvaluator, createPipelineABACHook, createPipelineExpressionEvaluator, createPipelineLLMEvaluator, evaluatePipelineGate, scorePipelineComplexity, evaluatePipelineComplexityRouting, } from './policy-evaluators.js';
33
43
  // Adapter ecosystem
34
- export { createPipelineAdapterRegistry, createPipelineWebhookBridge, resolveAdapterFromGit, resolveInfrastructure, scanPipelineAdapters, } from './adapters.js';
44
+ export { createPipelineAdapterRegistry, createPipelineWebhookBridge, resolveAdapterFromGit, resolveInfrastructure, resolveIssueTrackerFromConfig, scanPipelineAdapters, } from './adapters.js';
35
45
  // Reconcilers (generalized names)
36
46
  export { createPipelineReconciler, createGateReconciler, createAutonomyReconciler, hasResourceChanged, fingerprintResource, } from './reconcilers.js';
37
47
  // Extended audit
@@ -41,11 +51,13 @@ export { checkFrameworkCompliance, getControlCatalog, getFrameworkMappings, list
41
51
  // Extended telemetry
42
52
  export { createSilentLogger, withPipelineSpanSync, getPipelineTracer, validateResourceSchema, } from './telemetry-extended.js';
43
53
  // Runners
44
- export { ClaudeCodeRunner, ClaudeCodeRunner as GitHubActionsRunner, GenericLLMRunner, CopilotRunner, CursorRunner, CodexRunner, RunnerRegistry, createRunnerRegistry, } from './runners/index.js';
54
+ export { ClaudeCodeRunner, ClaudeCodeRunner as GitHubActionsRunner, GenericLLMRunner, CopilotRunner, CursorRunner, CodexRunner, RunnerRegistry, createRunnerRegistry, SecurityTriageRunner, ReviewAgentRunner, REVIEW_PROMPTS, } from './runners/index.js';
45
55
  // Notifications
46
56
  export { SlackMessenger, TeamsMessenger, NotificationRouter } from './notifications/index.js';
47
57
  // State store
48
58
  export { StateStore } from './state/index.js';
59
+ // Workflow pattern detection
60
+ export { readToolSequenceJSONL, readSessionMetaFiles, sessionMetaToEvents, categorizeAction, DEFAULT_DETECTION_OPTIONS, } from './workflow-patterns/index.js';
49
61
  // Deployment targets
50
62
  export { createKubernetesTarget, createVercelTarget, createFlyioTarget, createHttpMetricsCollector, createStubMetricsCollector, RolloutController, } from './deploy/index.js';
51
63
  // Progressive gates
@@ -85,4 +97,7 @@ export { archiveEntries, loadArchivedEntries, verifyArchiveContinuity } from './
85
97
  export { Orchestrator } from './orchestrator.js';
86
98
  // Cost governance plugin
87
99
  export { CostGovernancePlugin } from './cost-governance.js';
100
+ // Pipeline cycle detection
101
+ export { PipelineCycleDetector, createStageMarker, parseStageInvocations, DEFAULT_CYCLE_LIMITS, } from './pipeline-cycle-detector.js';
102
+ export { checkAndHandleCycle, createCycleDetectorFromConfig, } from './cycle-utils.js';
88
103
  //# sourceMappingURL=index.js.map
@@ -74,7 +74,7 @@ export declare class Orchestrator {
74
74
  /**
75
75
  * Run the full pipeline for a single issue.
76
76
  */
77
- run(issueNumber: number, overrides?: Partial<ExecuteOptions>): Promise<PipelineResult>;
77
+ run(issueId: string, overrides?: Partial<ExecuteOptions>): Promise<PipelineResult>;
78
78
  /**
79
79
  * Start watch mode — continuous reconciliation loop.
80
80
  */
@@ -8,6 +8,7 @@ import { executeFixCI } from './fix-ci.js';
8
8
  import { loadConfig } from './config.js';
9
9
  import { StateStore } from './state/index.js';
10
10
  import { createLogger } from './logger.js';
11
+ import { issueIdToNumber } from './shared.js';
11
12
  import { analyzeCodebase } from './analysis/analyzer.js';
12
13
  import { buildCodebaseContext } from './analysis/context-builder.js';
13
14
  import { DEFAULT_ANALYSIS_CACHE_TTL_MS } from './defaults.js';
@@ -48,14 +49,16 @@ export class Orchestrator {
48
49
  /**
49
50
  * Run the full pipeline for a single issue.
50
51
  */
51
- async run(issueNumber, overrides) {
52
- const runId = `run-${Date.now()}-${issueNumber}`;
52
+ async run(issueId, overrides) {
53
+ const issueNumber = issueIdToNumber(issueId);
54
+ const runId = `run-${Date.now()}-${issueId}`;
53
55
  const startedAt = new Date().toISOString();
54
56
  // Record pipeline start in state store
55
57
  if (this._state) {
56
58
  this._state.savePipelineRun({
57
59
  runId,
58
- issueNumber,
60
+ issueId,
61
+ issueNumber: issueNumber ?? undefined,
59
62
  pipelineType: 'execute',
60
63
  status: 'running',
61
64
  currentStage: 'init',
@@ -84,11 +87,16 @@ export class Orchestrator {
84
87
  }
85
88
  // Notify plugins before run
86
89
  for (const plugin of this.plugins) {
87
- await plugin.beforeRun?.({ runId, issueNumber, startedAt });
90
+ await plugin.beforeRun?.({
91
+ runId,
92
+ issueId,
93
+ issueNumber: issueNumber ?? undefined,
94
+ startedAt,
95
+ });
88
96
  }
89
97
  const runStart = Date.now();
90
98
  try {
91
- const result = await executePipeline(issueNumber, {
99
+ const result = await executePipeline(issueId, {
92
100
  configDir: this.config.configDir,
93
101
  workDir: this.config.workDir,
94
102
  runner: this.config.runner,
@@ -109,7 +117,8 @@ export class Orchestrator {
109
117
  }),
110
118
  });
111
119
  this._state.saveEpisodicRecord({
112
- issueNumber,
120
+ issueId,
121
+ issueNumber: issueNumber ?? undefined,
113
122
  pipelineType: 'execute',
114
123
  outcome: 'success',
115
124
  filesChanged: result.filesChanged.length,
@@ -118,7 +127,13 @@ export class Orchestrator {
118
127
  // Notify plugins after successful run
119
128
  const durationMs = Date.now() - runStart;
120
129
  for (const plugin of this.plugins) {
121
- await plugin.afterRun?.({ runId, issueNumber, result, durationMs });
130
+ await plugin.afterRun?.({
131
+ runId,
132
+ issueId,
133
+ issueNumber: issueNumber ?? undefined,
134
+ result,
135
+ durationMs,
136
+ });
122
137
  }
123
138
  return result;
124
139
  }
@@ -131,7 +146,8 @@ export class Orchestrator {
131
146
  }),
132
147
  });
133
148
  this._state.saveEpisodicRecord({
134
- issueNumber,
149
+ issueId,
150
+ issueNumber: issueNumber ?? undefined,
135
151
  pipelineType: 'execute',
136
152
  outcome: 'failure',
137
153
  errorMessage: err instanceof Error ? err.message : String(err),
@@ -141,7 +157,13 @@ export class Orchestrator {
141
157
  const errorDurationMs = Date.now() - runStart;
142
158
  const error = err instanceof Error ? err : new Error(String(err));
143
159
  for (const plugin of this.plugins) {
144
- await plugin.onError?.({ runId, issueNumber, error, durationMs: errorDurationMs });
160
+ await plugin.onError?.({
161
+ runId,
162
+ issueId,
163
+ issueNumber: issueNumber ?? undefined,
164
+ error,
165
+ durationMs: errorDurationMs,
166
+ });
145
167
  }
146
168
  throw err;
147
169
  }
@@ -0,0 +1,70 @@
1
+ /**
2
+ * PipelineCycleDetector — tracks stage invocations per issue/PR across
3
+ * all workflow runs to detect infinite orchestration loops.
4
+ *
5
+ * Uses GitHub issue/PR comments as shared state (hidden HTML markers)
6
+ * to work across workflow boundaries.
7
+ */
8
+ import type { IssueTracker } from '@ai-sdlc/reference';
9
+ export type PipelineStage = 'admission' | 'triage' | 'agent' | 'review' | 'fix-ci' | 'fix-review';
10
+ export interface CycleConfig {
11
+ /** Max invocations per stage (default: 3 for agent stages, 2 for fix stages). */
12
+ maxInvocations: Record<PipelineStage, number>;
13
+ }
14
+ export interface CycleDetectionResult {
15
+ cycleDetected: boolean;
16
+ loopingStages: Array<{
17
+ stage: PipelineStage;
18
+ count: number;
19
+ max: number;
20
+ }>;
21
+ totalInvocations: number;
22
+ }
23
+ /**
24
+ * Default max invocations per stage.
25
+ * These must be HIGHER than the per-stage retry limits (which are the
26
+ * primary guard). The cycle detector is a safety net for cross-stage
27
+ * loops, not a replacement for retry counting.
28
+ *
29
+ * Per-stage retry limits: fix-ci=2, fix-review=2
30
+ * Cycle limits: set to retry_limit + 2 to allow retries + headroom
31
+ */
32
+ export declare const DEFAULT_CYCLE_LIMITS: Record<PipelineStage, number>;
33
+ /**
34
+ * Generate HTML comment marker for a stage invocation.
35
+ * Format: <!-- ai-sdlc-cycle:{stage}:{timestamp} -->
36
+ */
37
+ export declare function createStageMarker(stage: PipelineStage): string;
38
+ /**
39
+ * Parse stage invocation markers from comment bodies.
40
+ * Returns a map of stage -> invocation count.
41
+ */
42
+ export declare function parseStageInvocations(comments: string[]): Map<PipelineStage, number>;
43
+ export declare class PipelineCycleDetector {
44
+ private config;
45
+ constructor(config?: Partial<CycleConfig>);
46
+ /**
47
+ * Check if a cycle exists for the given issue/PR by analyzing comment history.
48
+ * @param pendingStage — if set, adds +1 to this stage's count to account for the upcoming invocation
49
+ */
50
+ detectCycle(tracker: IssueTracker, issueOrPrId: string, pendingStage?: PipelineStage): Promise<CycleDetectionResult>;
51
+ /**
52
+ * Detect cycle from comment bodies (for testing without IssueTracker).
53
+ * @param pendingStage — if set, adds +1 to this stage's count for the pending invocation
54
+ */
55
+ detectCycleFromComments(comments: string[], pendingStage?: PipelineStage): CycleDetectionResult;
56
+ /**
57
+ * Record a stage invocation by creating a marker.
58
+ * The caller should append this to their comment.
59
+ */
60
+ recordInvocation(stage: PipelineStage): string;
61
+ /**
62
+ * Get the max invocation limit for a stage.
63
+ */
64
+ getMaxInvocations(stage: PipelineStage): number;
65
+ /**
66
+ * Update max invocations for specific stages.
67
+ */
68
+ updateMaxInvocations(overrides: Partial<Record<PipelineStage, number>>): void;
69
+ }
70
+ //# sourceMappingURL=pipeline-cycle-detector.d.ts.map
@@ -0,0 +1,111 @@
1
+ /**
2
+ * PipelineCycleDetector — tracks stage invocations per issue/PR across
3
+ * all workflow runs to detect infinite orchestration loops.
4
+ *
5
+ * Uses GitHub issue/PR comments as shared state (hidden HTML markers)
6
+ * to work across workflow boundaries.
7
+ */
8
+ /**
9
+ * Default max invocations per stage.
10
+ * These must be HIGHER than the per-stage retry limits (which are the
11
+ * primary guard). The cycle detector is a safety net for cross-stage
12
+ * loops, not a replacement for retry counting.
13
+ *
14
+ * Per-stage retry limits: fix-ci=2, fix-review=2
15
+ * Cycle limits: set to retry_limit + 2 to allow retries + headroom
16
+ */
17
+ export const DEFAULT_CYCLE_LIMITS = {
18
+ admission: 5,
19
+ triage: 5,
20
+ agent: 5,
21
+ review: 4,
22
+ 'fix-ci': 4,
23
+ 'fix-review': 4,
24
+ };
25
+ /**
26
+ * Generate HTML comment marker for a stage invocation.
27
+ * Format: <!-- ai-sdlc-cycle:{stage}:{timestamp} -->
28
+ */
29
+ export function createStageMarker(stage) {
30
+ const timestamp = Date.now();
31
+ return `<!-- ai-sdlc-cycle:${stage}:${timestamp} -->`;
32
+ }
33
+ /**
34
+ * Parse stage invocation markers from comment bodies.
35
+ * Returns a map of stage -> invocation count.
36
+ */
37
+ export function parseStageInvocations(comments) {
38
+ const counts = new Map();
39
+ // Non-backtracking pattern: stage names are alphanumeric with optional single hyphens
40
+ const markerPattern = /<!-- ai-sdlc-cycle:([a-z][a-z0-9-]{0,30}):(\d{1,15}) -->/g;
41
+ for (const body of comments) {
42
+ let match;
43
+ while ((match = markerPattern.exec(body)) !== null) {
44
+ const stage = match[1];
45
+ counts.set(stage, (counts.get(stage) ?? 0) + 1);
46
+ }
47
+ }
48
+ return counts;
49
+ }
50
+ export class PipelineCycleDetector {
51
+ config;
52
+ constructor(config) {
53
+ this.config = {
54
+ maxInvocations: { ...DEFAULT_CYCLE_LIMITS, ...config?.maxInvocations },
55
+ };
56
+ }
57
+ /**
58
+ * Check if a cycle exists for the given issue/PR by analyzing comment history.
59
+ * @param pendingStage — if set, adds +1 to this stage's count to account for the upcoming invocation
60
+ */
61
+ async detectCycle(tracker, issueOrPrId, pendingStage) {
62
+ const comments = await tracker.getComments(issueOrPrId);
63
+ const commentBodies = comments.map((c) => c.body);
64
+ return this.detectCycleFromComments(commentBodies, pendingStage);
65
+ }
66
+ /**
67
+ * Detect cycle from comment bodies (for testing without IssueTracker).
68
+ * @param pendingStage — if set, adds +1 to this stage's count for the pending invocation
69
+ */
70
+ detectCycleFromComments(comments, pendingStage) {
71
+ const invocations = parseStageInvocations(comments);
72
+ // Account for the pending invocation that hasn't been recorded yet
73
+ if (pendingStage) {
74
+ invocations.set(pendingStage, (invocations.get(pendingStage) ?? 0) + 1);
75
+ }
76
+ const loopingStages = [];
77
+ let totalInvocations = 0;
78
+ for (const [stage, count] of invocations.entries()) {
79
+ totalInvocations += count;
80
+ const max = this.config.maxInvocations[stage];
81
+ if (count >= max) {
82
+ loopingStages.push({ stage, count, max });
83
+ }
84
+ }
85
+ return {
86
+ cycleDetected: loopingStages.length > 0,
87
+ loopingStages,
88
+ totalInvocations,
89
+ };
90
+ }
91
+ /**
92
+ * Record a stage invocation by creating a marker.
93
+ * The caller should append this to their comment.
94
+ */
95
+ recordInvocation(stage) {
96
+ return createStageMarker(stage);
97
+ }
98
+ /**
99
+ * Get the max invocation limit for a stage.
100
+ */
101
+ getMaxInvocations(stage) {
102
+ return this.config.maxInvocations[stage];
103
+ }
104
+ /**
105
+ * Update max invocations for specific stages.
106
+ */
107
+ updateMaxInvocations(overrides) {
108
+ this.config.maxInvocations = { ...this.config.maxInvocations, ...overrides };
109
+ }
110
+ }
111
+ //# sourceMappingURL=pipeline-cycle-detector.js.map
package/dist/plugin.d.ts CHANGED
@@ -19,18 +19,24 @@ export interface PluginContext {
19
19
  }
20
20
  export interface BeforeRunEvent {
21
21
  runId: string;
22
- issueNumber: number;
22
+ issueId: string;
23
+ /** @deprecated Use `issueId` instead. */
24
+ issueNumber?: number;
23
25
  startedAt: string;
24
26
  }
25
27
  export interface AfterRunEvent {
26
28
  runId: string;
27
- issueNumber: number;
29
+ issueId: string;
30
+ /** @deprecated Use `issueId` instead. */
31
+ issueNumber?: number;
28
32
  result: PipelineResult;
29
33
  durationMs: number;
30
34
  }
31
35
  export interface RunErrorEvent {
32
36
  runId: string;
33
- issueNumber: number;
37
+ issueId: string;
38
+ /** @deprecated Use `issueId` instead. */
39
+ issueNumber?: number;
34
40
  error: Error;
35
41
  durationMs: number;
36
42
  }
@@ -0,0 +1,28 @@
1
+ /**
2
+ * Product Priority Algorithm (PPA) — composite scoring module.
3
+ *
4
+ * Implements the PPA priority function:
5
+ * P(w) = Sα(w) × Dπ(w) × Mφ(w) × Eρ(w) × (1 − Eτ) × (1 + HC(w)) × Cκ(w)
6
+ *
7
+ * Each dimension maps real-world product signals into a bounded numeric
8
+ * range and the multiplicative composite lets any single zero-score
9
+ * dimension veto the work item.
10
+ *
11
+ * RFC reference: PPA section (priority scoring).
12
+ */
13
+ import type { PriorityScore, PriorityInput, PriorityConfig } from '@ai-sdlc/reference';
14
+ export type { PriorityScore, PriorityInput, PriorityConfig };
15
+ /**
16
+ * Compute the PPA composite priority score for a single work item.
17
+ *
18
+ * P(w) = Sα × Dπ × Mφ × Eρ × (1 − Eτ) × (1 + HC) × Cκ
19
+ */
20
+ export declare function computePriority(input: PriorityInput, config?: PriorityConfig): PriorityScore;
21
+ /**
22
+ * Score and rank multiple work items by descending composite priority.
23
+ * Override items (composite = Infinity) always sort first.
24
+ */
25
+ export declare function rankWorkItems(items: PriorityInput[], config?: PriorityConfig): Array<PriorityInput & {
26
+ score: PriorityScore;
27
+ }>;
28
+ //# sourceMappingURL=priority.d.ts.map