@codedrifters/configulator 0.0.281 → 0.0.283

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/lib/index.mjs CHANGED
@@ -11385,6 +11385,8 @@ function assertValidStateFilePath(stateFilePath) {
11385
11385
 
11386
11386
  // src/agent/bundles/scheduled-tasks.ts
11387
11387
  var SCHEDULED_TASK_MODEL_VALUES = ["opus", "sonnet", "haiku"];
11388
+ var SCHEDULED_TASK_KIND_VALUES = ["issue-worker", "pipeline"];
11389
+ var DEFAULT_SCHEDULED_TASK_KIND = "issue-worker";
11388
11390
  var DEFAULT_SCHEDULED_TASKS_ROOT = ".claude/scheduled-tasks";
11389
11391
  var DEFAULT_OFF_PEAK_CRON_EXAMPLE = "3,23,43 0-7,14-23 * * *";
11390
11392
  var DEFAULT_SCHEDULED_TASK_ENTRIES = [
@@ -11403,6 +11405,7 @@ var DEFAULT_SCHEDULED_TASK_ENTRIES = [
11403
11405
  "release",
11404
11406
  "hotfix"
11405
11407
  ],
11408
+ kind: "issue-worker",
11406
11409
  recommendedModel: "sonnet",
11407
11410
  enabled: false,
11408
11411
  cron: null,
@@ -11412,11 +11415,17 @@ var DEFAULT_SCHEDULED_TASK_ENTRIES = [
11412
11415
  taskId: "worker-orchestrator",
11413
11416
  agent: "orchestrator",
11414
11417
  agentLabel: "Orchestrator",
11415
- typeLabel: "plan",
11418
+ // Pipeline tasks do not filter on a `type:*` label — the
11419
+ // orchestrator runs an end-to-end cycle every invocation. The
11420
+ // `typeLabel` field is required by the registry shape so we
11421
+ // store the routing-bucket sentinel `feat`; rendered output
11422
+ // uses the `_(none — pipeline manager)_` cell instead.
11423
+ typeLabel: "feat",
11424
+ kind: "pipeline",
11416
11425
  recommendedModel: "sonnet",
11417
11426
  enabled: false,
11418
11427
  cron: null,
11419
- description: "Dispatcher that triages the backlog, runs pre-flight PR merges, and reports the next work item."
11428
+ description: "End-to-end pipeline manager: pre-flight PR merge, triage, maintenance, queue scan, delegate the picked issue to the issue-worker, then cleanup."
11420
11429
  },
11421
11430
  // Tier 1 — research.
11422
11431
  {
@@ -11425,6 +11434,7 @@ var DEFAULT_SCHEDULED_TASK_ENTRIES = [
11425
11434
  agentLabel: "Research",
11426
11435
  typeLabel: "research",
11427
11436
  phasePrefix: "research:",
11437
+ kind: "issue-worker",
11428
11438
  recommendedModel: "opus",
11429
11439
  enabled: false,
11430
11440
  cron: null,
@@ -11436,6 +11446,7 @@ var DEFAULT_SCHEDULED_TASK_ENTRIES = [
11436
11446
  agentLabel: "Industry Discovery",
11437
11447
  typeLabel: "industry-discovery",
11438
11448
  phasePrefix: "industry:",
11449
+ kind: "issue-worker",
11439
11450
  recommendedModel: "opus",
11440
11451
  enabled: false,
11441
11452
  cron: null,
@@ -11447,6 +11458,7 @@ var DEFAULT_SCHEDULED_TASK_ENTRIES = [
11447
11458
  agentLabel: "Standards Research",
11448
11459
  typeLabel: "standards-research",
11449
11460
  phasePrefix: "standards:",
11461
+ kind: "issue-worker",
11450
11462
  recommendedModel: "opus",
11451
11463
  enabled: false,
11452
11464
  cron: null,
@@ -11458,6 +11470,7 @@ var DEFAULT_SCHEDULED_TASK_ENTRIES = [
11458
11470
  agentLabel: "Regulatory Research",
11459
11471
  typeLabel: "regulatory-research",
11460
11472
  phasePrefix: "regulatory:",
11473
+ kind: "issue-worker",
11461
11474
  recommendedModel: "opus",
11462
11475
  enabled: false,
11463
11476
  cron: null,
@@ -11470,6 +11483,7 @@ var DEFAULT_SCHEDULED_TASK_ENTRIES = [
11470
11483
  agentLabel: "Company Profile",
11471
11484
  typeLabel: "company-profile",
11472
11485
  phasePrefix: "company:",
11486
+ kind: "issue-worker",
11473
11487
  recommendedModel: "sonnet",
11474
11488
  enabled: false,
11475
11489
  cron: null,
@@ -11481,6 +11495,7 @@ var DEFAULT_SCHEDULED_TASK_ENTRIES = [
11481
11495
  agentLabel: "People Profile",
11482
11496
  typeLabel: "people-profile",
11483
11497
  phasePrefix: "people:",
11498
+ kind: "issue-worker",
11484
11499
  recommendedModel: "sonnet",
11485
11500
  enabled: false,
11486
11501
  cron: null,
@@ -11492,6 +11507,7 @@ var DEFAULT_SCHEDULED_TASK_ENTRIES = [
11492
11507
  agentLabel: "Software Profile",
11493
11508
  typeLabel: "software-profile",
11494
11509
  phasePrefix: "software:",
11510
+ kind: "issue-worker",
11495
11511
  recommendedModel: "sonnet",
11496
11512
  enabled: false,
11497
11513
  cron: null,
@@ -11503,6 +11519,7 @@ var DEFAULT_SCHEDULED_TASK_ENTRIES = [
11503
11519
  agentLabel: "Customer Profile",
11504
11520
  typeLabel: "customer-profile",
11505
11521
  phasePrefix: "customer:",
11522
+ kind: "issue-worker",
11506
11523
  recommendedModel: "sonnet",
11507
11524
  enabled: false,
11508
11525
  cron: null,
@@ -11515,6 +11532,7 @@ var DEFAULT_SCHEDULED_TASK_ENTRIES = [
11515
11532
  agentLabel: "Business Models",
11516
11533
  typeLabel: "business-model",
11517
11534
  phasePrefix: "business-models:",
11535
+ kind: "issue-worker",
11518
11536
  recommendedModel: "opus",
11519
11537
  enabled: false,
11520
11538
  cron: null,
@@ -11526,6 +11544,7 @@ var DEFAULT_SCHEDULED_TASK_ENTRIES = [
11526
11544
  agentLabel: "BCM Writer",
11527
11545
  typeLabel: "bcm-document",
11528
11546
  phasePrefix: "bcm:",
11547
+ kind: "issue-worker",
11529
11548
  recommendedModel: "sonnet",
11530
11549
  enabled: false,
11531
11550
  cron: null,
@@ -11537,6 +11556,7 @@ var DEFAULT_SCHEDULED_TASK_ENTRIES = [
11537
11556
  agentLabel: "Requirements Analyst",
11538
11557
  typeLabel: "requirement",
11539
11558
  phasePrefix: "req:",
11559
+ kind: "issue-worker",
11540
11560
  recommendedModel: "opus",
11541
11561
  enabled: false,
11542
11562
  cron: null,
@@ -11548,6 +11568,7 @@ var DEFAULT_SCHEDULED_TASK_ENTRIES = [
11548
11568
  agentLabel: "Requirements Writer",
11549
11569
  typeLabel: "requirement",
11550
11570
  phaseLabels: ["req:write"],
11571
+ kind: "issue-worker",
11551
11572
  recommendedModel: "sonnet",
11552
11573
  enabled: false,
11553
11574
  cron: null,
@@ -11559,6 +11580,7 @@ var DEFAULT_SCHEDULED_TASK_ENTRIES = [
11559
11580
  agentLabel: "Requirements Reviewer",
11560
11581
  typeLabel: "requirement",
11561
11582
  phaseLabels: ["req:review", "req:deprecate"],
11583
+ kind: "issue-worker",
11562
11584
  recommendedModel: "opus",
11563
11585
  enabled: false,
11564
11586
  cron: null,
@@ -11571,6 +11593,7 @@ var DEFAULT_SCHEDULED_TASK_ENTRIES = [
11571
11593
  agentLabel: "Meeting Analysis",
11572
11594
  typeLabel: "meeting-processing",
11573
11595
  phasePrefix: "meeting:",
11596
+ kind: "issue-worker",
11574
11597
  recommendedModel: "sonnet",
11575
11598
  enabled: false,
11576
11599
  cron: null,
@@ -11582,6 +11605,7 @@ var DEFAULT_SCHEDULED_TASK_ENTRIES = [
11582
11605
  agentLabel: "Agenda",
11583
11606
  typeLabel: "agenda",
11584
11607
  phasePrefix: "agenda:",
11608
+ kind: "issue-worker",
11585
11609
  recommendedModel: "sonnet",
11586
11610
  enabled: false,
11587
11611
  cron: null,
@@ -11593,6 +11617,7 @@ var DEFAULT_SCHEDULED_TASK_ENTRIES = [
11593
11617
  agentLabel: "Maintenance",
11594
11618
  typeLabel: "maintenance",
11595
11619
  phasePrefix: "maint:",
11620
+ kind: "issue-worker",
11596
11621
  recommendedModel: "haiku",
11597
11622
  enabled: false,
11598
11623
  cron: null,
@@ -11603,6 +11628,7 @@ var DEFAULT_SCHEDULED_TASK_ENTRIES = [
11603
11628
  agent: "pr-reviewer",
11604
11629
  agentLabel: "PR Review",
11605
11630
  typeLabel: "pr-review",
11631
+ kind: "issue-worker",
11606
11632
  recommendedModel: "haiku",
11607
11633
  enabled: false,
11608
11634
  cron: null,
@@ -11614,6 +11640,7 @@ var DEFAULT_SCHEDULED_TASK_ENTRIES = [
11614
11640
  agentLabel: "Docs Sync",
11615
11641
  typeLabel: "docs-sync",
11616
11642
  phasePrefix: "docs-sync:",
11643
+ kind: "issue-worker",
11617
11644
  recommendedModel: "sonnet",
11618
11645
  enabled: false,
11619
11646
  cron: null,
@@ -11726,14 +11753,20 @@ function renderScheduledTasksSection(resolved) {
11726
11753
  "|---------|--------------|-----------------|--------------|-------|---------|------|"
11727
11754
  );
11728
11755
  for (const task of resolved.tasks) {
11729
- const typeCell = task.typeLabels && task.typeLabels.length > 1 ? task.typeLabels.map((l) => `\`type:${l}\``).join(", ") : `\`type:${task.typeLabel}\``;
11756
+ let typeCell;
11730
11757
  let phaseCell;
11731
- if (task.phaseLabels && task.phaseLabels.length > 0) {
11732
- phaseCell = task.phaseLabels.map((l) => `\`${l}\``).join(", ");
11733
- } else if (task.phasePrefix) {
11734
- phaseCell = `\`${task.phasePrefix}*\``;
11758
+ if (task.kind === "pipeline") {
11759
+ typeCell = "_(none \u2014 pipeline manager)_";
11760
+ phaseCell = "_(none \u2014 pipeline manager)_";
11735
11761
  } else {
11736
- phaseCell = "_(any)_";
11762
+ typeCell = task.typeLabels && task.typeLabels.length > 1 ? task.typeLabels.map((l) => `\`type:${l}\``).join(", ") : `\`type:${task.typeLabel}\``;
11763
+ if (task.phaseLabels && task.phaseLabels.length > 0) {
11764
+ phaseCell = task.phaseLabels.map((l) => `\`${l}\``).join(", ");
11765
+ } else if (task.phasePrefix) {
11766
+ phaseCell = `\`${task.phasePrefix}*\``;
11767
+ } else {
11768
+ phaseCell = "_(any)_";
11769
+ }
11737
11770
  }
11738
11771
  const cronCell = task.cron ? `\`${task.cron}\`` : "_manual-only_";
11739
11772
  lines.push(
@@ -11753,6 +11786,12 @@ function renderScheduledTaskSkillFile(task) {
11753
11786
  lines.push(`cron: "${task.cron}"`);
11754
11787
  }
11755
11788
  lines.push("---", "");
11789
+ if (task.kind === "pipeline") {
11790
+ return renderPipelineSkillBody(task, lines);
11791
+ }
11792
+ return renderIssueWorkerSkillBody(task, lines);
11793
+ }
11794
+ function renderIssueWorkerSkillBody(task, lines) {
11756
11795
  lines.push(
11757
11796
  `# ${task.agentLabel} Scheduled Worker`,
11758
11797
  "",
@@ -11805,6 +11844,36 @@ function renderScheduledTaskSkillFile(task) {
11805
11844
  );
11806
11845
  return lines.join("\n");
11807
11846
  }
11847
+ function renderPipelineSkillBody(task, lines) {
11848
+ lines.push(
11849
+ `# ${task.agentLabel} Pipeline Worker`,
11850
+ "",
11851
+ `You are the **${task.agentLabel}** pipeline worker. This task is a`,
11852
+ "**pipeline manager**, not an issue-worker delegator \u2014 it does not",
11853
+ "filter issues by `type:*` or phase label. Each invocation runs the",
11854
+ `target sub-agent's full end-to-end cycle exactly once.`,
11855
+ "",
11856
+ `Run \`.claude/agents/${task.agent}.md\` and follow its workflow`,
11857
+ "from start to finish. The sub-agent is responsible for picking the",
11858
+ "next unit of work, delegating implementation to other workers as",
11859
+ "needed, and exiting cleanly.",
11860
+ "",
11861
+ "## Recommended model",
11862
+ "",
11863
+ `**${capitalize(task.recommendedModel)}** \u2014 see`,
11864
+ `\`.claude/agents/${task.agent}.md\` for the agent's full model`,
11865
+ "rationale. The operator launches the scheduler instance on the",
11866
+ "recommended model; this task does not pin a model at the runtime",
11867
+ "level.",
11868
+ "",
11869
+ "## Exit conditions",
11870
+ "",
11871
+ "Exit cleanly after one full cycle of the target pipeline (or",
11872
+ "immediately if the pipeline reports there is no eligible work).",
11873
+ "Do not loop \u2014 the next scheduled invocation runs another cycle."
11874
+ );
11875
+ return lines.join("\n");
11876
+ }
11808
11877
  var SAMPLE_PHASE = "phase1";
11809
11878
  function capitalize(value) {
11810
11879
  if (value.length === 0) {
@@ -11825,6 +11894,9 @@ function applyOverride(base, override, taskId) {
11825
11894
  if (override.phaseLabels !== void 0) {
11826
11895
  assertNonEmptyLabelList(override.phaseLabels, taskId, "phaseLabels");
11827
11896
  }
11897
+ if (override.kind !== void 0) {
11898
+ assertValidKind(override.kind, taskId);
11899
+ }
11828
11900
  const resolvedTypeLabels = override.typeLabels !== void 0 ? normalizeLabelList(override.typeLabels) : base.typeLabels;
11829
11901
  const primaryTypeLabel = resolvedTypeLabels?.[0] ?? base.typeLabel;
11830
11902
  return {
@@ -11835,7 +11907,8 @@ function applyOverride(base, override, taskId) {
11835
11907
  description: override.description ?? base.description,
11836
11908
  typeLabel: primaryTypeLabel,
11837
11909
  typeLabels: resolvedTypeLabels,
11838
- phaseLabels: override.phaseLabels !== void 0 ? normalizeLabelList(override.phaseLabels) : base.phaseLabels
11910
+ phaseLabels: override.phaseLabels !== void 0 ? normalizeLabelList(override.phaseLabels) : base.phaseLabels,
11911
+ kind: override.kind ?? base.kind
11839
11912
  };
11840
11913
  }
11841
11914
  function validateFullEntry(entry) {
@@ -11867,6 +11940,9 @@ function validateFullEntry(entry) {
11867
11940
  if (entry.phaseLabels !== void 0) {
11868
11941
  assertNonEmptyLabelList(entry.phaseLabels, taskId, "phaseLabels");
11869
11942
  }
11943
+ if (entry.kind !== void 0) {
11944
+ assertValidKind(entry.kind, taskId);
11945
+ }
11870
11946
  const typeLabels = entry.typeLabels !== void 0 ? normalizeLabelList(entry.typeLabels) : void 0;
11871
11947
  const primaryTypeLabel = typeLabels?.[0] ?? typeLabel;
11872
11948
  return {
@@ -11880,9 +11956,19 @@ function validateFullEntry(entry) {
11880
11956
  recommendedModel: entry.recommendedModel,
11881
11957
  enabled: entry.enabled ?? false,
11882
11958
  cron: entry.cron ?? null,
11883
- description: entry.description ?? `${agent} scheduled worker.`
11959
+ description: entry.description ?? `${agent} scheduled worker.`,
11960
+ kind: entry.kind ?? DEFAULT_SCHEDULED_TASK_KIND
11884
11961
  };
11885
11962
  }
11963
+ function assertValidKind(value, taskId) {
11964
+ if (!SCHEDULED_TASK_KIND_VALUES.includes(value)) {
11965
+ throw new Error(
11966
+ `ScheduledTasksConfig entry for taskId ${JSON.stringify(taskId)} has kind ${JSON.stringify(
11967
+ value
11968
+ )}; must be one of ${SCHEDULED_TASK_KIND_VALUES.join(" | ")}.`
11969
+ );
11970
+ }
11971
+ }
11886
11972
  function assertValidModel(value, taskId) {
11887
11973
  if (!SCHEDULED_TASK_MODEL_VALUES.includes(value)) {
11888
11974
  throw new Error(
@@ -12226,9 +12312,6 @@ var DEFAULT_AGENT_TIERS = [
12226
12312
  { type: "docs", tier: 0, role: AGENT_TIER_ROLES[0] },
12227
12313
  { type: "release", tier: 0, role: AGENT_TIER_ROLES[0] },
12228
12314
  { type: "hotfix", tier: 0, role: AGENT_TIER_ROLES[0] },
12229
- { type: "plan", tier: 0, role: AGENT_TIER_ROLES[0] },
12230
- { type: "review", tier: 0, role: AGENT_TIER_ROLES[0] },
12231
- { type: "adr", tier: 0, role: AGENT_TIER_ROLES[0] },
12232
12315
  // Tier 1 — research.
12233
12316
  { type: "research", tier: 1, role: AGENT_TIER_ROLES[1] },
12234
12317
  { type: "industry-discovery", tier: 1, role: AGENT_TIER_ROLES[1] },
@@ -13137,16 +13220,16 @@ function buildCheckBlockedScript(tiers, scopeGate, runRatio, preflight) {
13137
13220
  "}",
13138
13221
  "",
13139
13222
  "cmd_tick() {",
13140
- ' if [[ "$RUN_RATIO_ENABLED" != "1" ]]; then',
13141
- " # Ratio disabled: every run dispatches, and we don't advance the",
13142
- " # persistent counter. Echo a stable sentinel so callers can still",
13143
- " # branch on the output.",
13144
- ' echo "run=0 type=dispatch (ratio disabled)"',
13145
- " return 0",
13146
- " fi",
13147
- " local result",
13148
- " result=$(run_counter_tick)",
13149
- ' echo "$result"',
13223
+ " # DEPRECATED: the orchestrator no longer maintains a dispatch /",
13224
+ " # housekeeping run-counter \u2014 every invocation runs the full",
13225
+ " # end-to-end cycle. This subcommand is retained as a no-op for one",
13226
+ " # release so any consumer mid-flight does not error out, then will",
13227
+ " # be removed entirely. Existing state files at",
13228
+ ' # "$ORCHESTRATOR_STATE_FILE" can be left alone (they will become',
13229
+ " # orphaned).",
13230
+ ' echo "tick: deprecated no-op (orchestrator runs a single linear cycle every invocation)" >&2',
13231
+ ' echo "run=0 type=dispatch (deprecated)"',
13232
+ " return 0",
13150
13233
  "}",
13151
13234
  "",
13152
13235
  "# \u2500\u2500 main \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500",
@@ -13170,7 +13253,7 @@ function buildCheckBlockedScript(tiers, scopeGate, runRatio, preflight) {
13170
13253
  function buildCheckBlockedProcedure(tiers, scopeGate = resolveScopeGate(), runRatio = resolveRunRatio(), preflight = resolvePreflightPr()) {
13171
13254
  return {
13172
13255
  name: "check-blocked.sh",
13173
- description: "Token-efficient issue triage script with subcommands: eligible, unblock, stale, orphaned, prs, scope, tick, preflight. Sorts eligible issues by priority desc \u2192 funnel tier asc \u2192 issue number asc; the scope subcommand classifies a single issue against the scope-gate thresholds; the tick subcommand advances the orchestrator run counter and classifies the run as dispatch or housekeeping; the preflight subcommand emits one eligibility line per open PR that is mergeable, CI-green, approved (or auto-merge already enabled), and linked to an open issue.",
13256
+ description: "Token-efficient issue triage script with subcommands: eligible, unblock, stale, orphaned, prs, scope, preflight, and (deprecated) tick. Sorts eligible issues by priority desc \u2192 funnel tier asc \u2192 issue number asc; the scope subcommand classifies a single issue against the scope-gate thresholds; the preflight subcommand emits one eligibility line per open PR that is mergeable, CI-green, approved (or auto-merge already enabled), and linked to an open issue. The tick subcommand is a deprecation no-op retained for one release (the orchestrator no longer maintains a dispatch/housekeeping run counter).",
13174
13257
  content: buildCheckBlockedScript(tiers, scopeGate, runRatio, preflight)
13175
13258
  };
13176
13259
  }
@@ -13192,62 +13275,55 @@ var unblockDependentsProcedure = buildUnblockDependentsProcedure(
13192
13275
  );
13193
13276
  var orchestratorSubAgent = {
13194
13277
  name: "orchestrator",
13195
- description: "Pipeline manager that reviews PRs, triages issues, and identifies the next work item \u2014 never implements code",
13278
+ description: "End-to-end pipeline manager that runs one full cycle every invocation: pre-flight PR merge \u2192 triage \u2192 maintenance \u2192 queue scan \u2192 delegate the picked issue to the issue-worker \u2192 cleanup",
13196
13279
  model: AGENT_MODEL.POWERFUL,
13197
13280
  maxTurns: 100,
13281
+ canDelegateToAgents: ["issue-worker", "pr-reviewer"],
13198
13282
  platforms: { cursor: { exclude: true } },
13199
13283
  prompt: [
13200
13284
  "# Orchestrator Agent",
13201
13285
  "",
13202
- "You are a pipeline manager for the **{{repository.owner}}/{{repository.name}}** repository.",
13203
- "You review PRs, triage issues, and identify the next work item. You **never**",
13204
- "implement code, create branches for issues, or claim issues.",
13205
- "",
13206
- "Each invocation is either a **dispatch run** or a **housekeeping run**;",
13207
- "the run type is decided by the persistent run counter managed in Phase A",
13208
- "below. Execute only the phases listed for the classified run type \u2014",
13209
- "the run ratio keeps the pipeline balanced without human scheduling.",
13286
+ "You are the pipeline orchestrator for the **{{repository.owner}}/{{repository.name}}** repository.",
13287
+ "Each invocation runs **one full end-to-end cycle**. The cycle merges",
13288
+ "approved PRs, triages blocked issues, runs maintenance scans, picks the",
13289
+ "next ready issue, and **delegates implementation to the `issue-worker`**",
13290
+ "sub-agent in scheduled mode. The orchestrator itself never implements",
13291
+ "code, creates branches, or pushes commits \u2014 it routes work to other",
13292
+ "agents.",
13293
+ "",
13294
+ "Run the phases below in order on every invocation. There is no",
13295
+ "dispatch/housekeeping fork \u2014 every phase runs every time.",
13296
+ "",
13297
+ "Phase ordering (each runs exactly once per invocation):",
13298
+ "",
13299
+ "1. **Phase A \u2014 Startup.** Pull the default branch.",
13300
+ "2. **Phase B0 \u2014 Pre-flight PR Merge.** Land every eligible approved /",
13301
+ " CI-green PR before triage reads dependency state.",
13302
+ "3. **Phase C \u2014 Triage / Unblock.** Flip dependents that have all",
13303
+ " their dependencies closed back to `status:ready`.",
13304
+ "4. **Phase D \u2014 Maintenance.** Stale-issue and orphaned-resource scan",
13305
+ " plus a needs-attention summary.",
13306
+ "5. **Phase E \u2014 Queue Scan.** Pick the highest-priority `PICK` line",
13307
+ " and run the scope gate. If the result is `large`, flag and stop.",
13308
+ "6. **Phase G \u2014 Delegate Implementation.** Hand the picked issue off",
13309
+ " to the `issue-worker` sub-agent in scheduled mode. The worker",
13310
+ " handles claim \u2192 branch \u2192 implement \u2192 commit \u2192 PR autonomously.",
13311
+ "7. **Phase F \u2014 Cleanup.** Return to the default branch and log the",
13312
+ " run summary.",
13210
13313
  "",
13211
13314
  "---",
13212
13315
  "",
13213
13316
  ...PROJECT_CONTEXT_READER_SECTION,
13214
13317
  "## Phase A: Startup",
13215
13318
  "",
13216
- "Pull the default branch and tick the run counter:",
13319
+ "Pull the default branch:",
13217
13320
  "",
13218
13321
  "```bash",
13219
13322
  "git checkout main && git pull origin main",
13220
- ".claude/procedures/check-blocked.sh tick",
13221
- "```",
13222
- "",
13223
- "The `tick` subcommand advances the persistent run counter and",
13224
- "classifies the run. Expect one of:",
13225
- "",
13226
- "```",
13227
- "run=<n> type=dispatch",
13228
- "run=<n> type=housekeeping",
13229
- "run=0 type=dispatch (ratio disabled)",
13230
13323
  "```",
13231
13324
  "",
13232
- "Branch on the emitted `type`:",
13233
- "",
13234
- "- `dispatch` \u2014 execute **Phase C** (Triage \u2014 Unblock) and",
13235
- " **Phase E** (Queue Scan). Skip Phase B (Batch PR Review) and",
13236
- " Phase D (Maintenance).",
13237
- "- `housekeeping` \u2014 execute **Phase B** (Batch PR Review) and",
13238
- " **Phase D** (Maintenance). Skip Phase C (Unblock) and Phase E",
13239
- " (Queue Scan).",
13240
- "",
13241
- "Phase F (Cleanup) always runs. **Phase B0 (Pre-flight PR Merge)**",
13242
- "also always runs \u2014 it sits between Phase A and the per-run-type",
13243
- "split so eligible PRs land before dependency state is read.",
13244
- "See the **Run ratio (dispatch vs housekeeping)** and **Pre-flight",
13245
- "PR merge** sections in `CLAUDE.md` for the full contracts.",
13246
- "",
13247
13325
  "## Phase B0: Pre-flight PR Merge",
13248
13326
  "",
13249
- "_Runs on every invocation (dispatch and housekeeping)._",
13250
- "",
13251
13327
  "Before any other phase reads dependency state, land every",
13252
13328
  "eligible PR. The sweep is idempotent \u2014 `gh pr merge` on an",
13253
13329
  "already-merged PR is a no-op \u2014 so re-running on back-to-back",
@@ -13340,41 +13416,8 @@ var orchestratorSubAgent = {
13340
13416
  "or more eligibility checks. The `pr-reviewer` or a human",
13341
13417
  "operator picks them up on the normal review path.",
13342
13418
  "",
13343
- "## Phase B: Batch PR Review",
13344
- "",
13345
- "_Housekeeping runs only \u2014 skip on dispatch runs._",
13346
- "",
13347
- "Find all PRs eligible for review:",
13348
- "",
13349
- "```bash",
13350
- ".claude/procedures/check-blocked.sh prs",
13351
- "```",
13352
- "",
13353
- "For each `REVIEW PR #N issue:#M branch:<branch>` line:",
13354
- "",
13355
- "1. Check out the PR branch: `gh pr checkout N`",
13356
- "2. Review the PR:",
13357
- " - Read the PR description and linked issue: `gh pr view N`",
13358
- " - Review the diff: `gh pr diff N`",
13359
- " - Check all changed files for correctness, conventions, and test coverage",
13360
- " - Verify PR conventions: conventional commit title, closing keyword, summary present",
13361
- " - Check CI status: `gh pr checks N`",
13362
- "3. If the PR passes review:",
13363
- " - Enable squash auto-merge: `gh pr merge N --auto --squash --subject '<conventional-commit-title>' --body '<extended-description>'`",
13364
- "4. If the PR fails review:",
13365
- " - Request changes: `gh pr review N --request-changes --body '<findings>'`",
13366
- "5. After each PR (whether merged or not):",
13367
- " ```bash",
13368
- " git checkout main && git pull origin main",
13369
- " ```",
13370
- "",
13371
- "Skip lines starting with `SKIP` \u2014 those PRs are not eligible.",
13372
- "If output is `NO_OPEN_PRS` or `NO_ELIGIBLE_PRS`, skip to Phase C.",
13373
- "",
13374
13419
  "## Phase C: Triage \u2014 Unblock",
13375
13420
  "",
13376
- "_Dispatch runs only \u2014 skip on housekeeping runs._",
13377
- "",
13378
13421
  "Check for blocked issues whose dependencies have resolved:",
13379
13422
  "",
13380
13423
  "```bash",
@@ -13386,9 +13429,9 @@ var orchestratorSubAgent = {
13386
13429
  "`.claude/procedures/unblock-dependents.sh <n>` as part of that",
13387
13430
  "transition, so in steady state Phase C should usually report",
13388
13431
  "`NO_BLOCKED_ISSUES` or leave dependents untouched. Phase C still",
13389
- "runs on every dispatch so issues that slipped through \u2014 human",
13432
+ "runs on every cycle so issues that slipped through \u2014 human",
13390
13433
  "closures, manual `status:done` edits, or crashes mid-sweep \u2014 get",
13391
- "picked up within one dispatch cycle. See the **Agent-driven",
13434
+ "picked up within one cycle. See the **Agent-driven",
13392
13435
  "unblocking** section in `CLAUDE.md` for the per-agent contract.",
13393
13436
  "",
13394
13437
  "For each `UNBLOCK #N` line:",
@@ -13400,12 +13443,10 @@ var orchestratorSubAgent = {
13400
13443
  "For `BLOCKED #N \u2014 no Depends on field found`: leave as-is (Phase D will",
13401
13444
  "catch it if it's been blocked too long).",
13402
13445
  "",
13403
- "If output is `NO_BLOCKED_ISSUES`, skip to Phase D.",
13446
+ "If output is `NO_BLOCKED_ISSUES`, continue to Phase D.",
13404
13447
  "",
13405
13448
  "## Phase D: Maintenance",
13406
13449
  "",
13407
- "_Housekeeping runs only \u2014 skip on dispatch runs._",
13408
- "",
13409
13450
  "### D1: Stale Detection",
13410
13451
  "",
13411
13452
  "```bash",
@@ -13448,8 +13489,6 @@ var orchestratorSubAgent = {
13448
13489
  "",
13449
13490
  "## Phase E: Queue Scan",
13450
13491
  "",
13451
- "_Dispatch runs only \u2014 skip on housekeeping runs._",
13452
- "",
13453
13492
  "Find the highest-priority ready issue:",
13454
13493
  "",
13455
13494
  "```bash",
@@ -13479,7 +13518,8 @@ var orchestratorSubAgent = {
13479
13518
  "```",
13480
13519
  "",
13481
13520
  "If the scope is `small` or `medium`, continue \u2014 the issue is",
13482
- "dispatchable. Report the first `PICK` line as:",
13521
+ "dispatchable. Record the first `PICK` line as the next work item",
13522
+ "and proceed to Phase G:",
13483
13523
  "",
13484
13524
  "```",
13485
13525
  'NEXT_WORK_ITEM #<number> priority:<level> tier:<n> type:<label> scope:<small|medium> "<title>"',
@@ -13517,10 +13557,52 @@ var orchestratorSubAgent = {
13517
13557
  "",
13518
13558
  `Unknown \`type:*\` labels fall through to tier ${UNKNOWN_TYPE_FALLBACK_TIER} (${AGENT_TIER_ROLES[UNKNOWN_TYPE_FALLBACK_TIER]}) so an unclassified issue never blocks the queue. See the **Funnel-tier dispatch ordering** and **Scope gate** sections in \`CLAUDE.md\` for the full tier table and decomposition template.`,
13519
13559
  "",
13520
- "If output is `NO_READY_ISSUES`, report that the queue is empty.",
13521
- "",
13522
- "**Do NOT claim the issue, create a branch, or start implementation.**",
13523
- "The worker agent handles that.",
13560
+ "If output is `NO_READY_ISSUES`, report that the queue is empty,",
13561
+ "skip Phase G, and proceed directly to Phase F.",
13562
+ "",
13563
+ "**Do NOT claim the issue, create a branch, or start implementation",
13564
+ "yourself.** Phase G hands the issue off to the `issue-worker`",
13565
+ "sub-agent in scheduled mode; the worker performs the actual",
13566
+ "claim \u2192 branch \u2192 implement \u2192 commit \u2192 PR cycle.",
13567
+ "",
13568
+ "## Phase G: Delegate Implementation",
13569
+ "",
13570
+ "_Skip when Phase E reported `NO_READY_ISSUES`, the queue is empty,",
13571
+ "or Phase E flagged the top `PICK` as `large` \u2014 there is nothing to",
13572
+ "delegate._",
13573
+ "",
13574
+ "Hand the picked issue off to the `issue-worker` sub-agent in",
13575
+ "**scheduled mode** so it runs the full claim \u2192 branch \u2192 implement",
13576
+ "\u2192 commit \u2192 PR cycle autonomously, without pausing for an",
13577
+ "interactive approval. The worker reads the literal phrase",
13578
+ "`scheduled mode` in its invocation prompt and skips the Phase 6",
13579
+ "approval pause; see the **Invocation Mode** section in",
13580
+ "`.claude/agents/issue-worker.md` for the full contract.",
13581
+ "",
13582
+ "Invoke the sub-agent with a single-message brief:",
13583
+ "",
13584
+ "> `scheduled mode`: work issue #<number>. Pick this issue from the",
13585
+ "> queue, claim it, route to the appropriate typed agent if one",
13586
+ "> applies, implement the change, run the verification commands,",
13587
+ "> commit, push, and open a PR labeled `origin:issue-worker` that",
13588
+ "> closes the issue. Do not pause for approval. Return a one-line",
13589
+ "> summary as the final line of your response in the form",
13590
+ "> `WORKER_DONE issue:#<n> pr:#<m>` on success or",
13591
+ "> `WORKER_FAILED issue:#<n> reason:<short reason>` on failure.",
13592
+ "",
13593
+ "Substitute `<number>` with the issue number from the",
13594
+ "`NEXT_WORK_ITEM` line in Phase E. The orchestrator is **read-only**",
13595
+ "with respect to the issue and its branch \u2014 never claim the issue,",
13596
+ "create a branch, or push commits in this phase. Implementation is",
13597
+ "the worker's job.",
13598
+ "",
13599
+ "If the worker's final line is missing, malformed, or indicates an",
13600
+ "error, **do not retry** in the same orchestrator session \u2014 log the",
13601
+ "outcome and proceed to Phase F. The next orchestrator invocation",
13602
+ "will re-scan the queue and pick the issue up again if it is still",
13603
+ "ready (it may have been left as `status:in-progress` by a partial",
13604
+ "worker run, in which case the orchestrator's stale-detection in",
13605
+ "Phase D will surface it for human triage on a future cycle).",
13524
13606
  "",
13525
13607
  "## Phase F: Cleanup",
13526
13608
  "",
@@ -13529,44 +13611,47 @@ var orchestratorSubAgent = {
13529
13611
  "git fetch --prune origin",
13530
13612
  "```",
13531
13613
  "",
13532
- "Log completion: phases executed, PRs reviewed, issues unblocked,",
13533
- "stale issues flagged, and next work item (if any).",
13614
+ "Log completion: phases executed, PRs merged in pre-flight, issues",
13615
+ "unblocked, stale issues flagged, the next work item picked, and",
13616
+ "the outcome of Phase G's delegation (worker success / failure /",
13617
+ "skipped because the queue was empty).",
13534
13618
  "",
13535
13619
  "---",
13536
13620
  "",
13537
13621
  "## Rules",
13538
13622
  "",
13539
- "1. **Never implement code.** You triage, review, and report \u2014 you do not code.",
13540
- "2. **Never claim issues.** Do not add `status:in-progress` or create branches for issues.",
13623
+ "1. **Never implement code.** You merge, triage, scan, and delegate \u2014 you do not code.",
13624
+ "2. **Never claim issues.** Do not add `status:in-progress` or create branches for issues. Phase G's `issue-worker` delegation is the only path that flips an issue's claim labels.",
13541
13625
  "3. **Always use check-blocked.sh.** All triage queries go through the shell script for token efficiency.",
13542
13626
  "4. **Follow CLAUDE.md conventions** for all git and gh operations.",
13543
13627
  "5. **Priority order:** critical > high > medium > low > trivial, then **funnel tier asc** (lower tier wins ties), then FIFO by issue number.",
13544
13628
  "6. **Never dispatch a `large` issue.** Always run the scope check",
13545
13629
  " on the top `PICK` line before reporting `NEXT_WORK_ITEM`. A",
13546
13630
  " `large` issue must be flagged with `status:needs-attention` and",
13547
- " handed a decomposition proposal \u2014 never claimed, never branched.",
13548
- "7. **Respect the run-ratio branching.** Every invocation must begin",
13549
- " with `.claude/procedures/check-blocked.sh tick`. Execute only",
13550
- " the phases listed for the classified run type \u2014",
13551
- " `type=dispatch` runs Phases C + E, `type=housekeeping` runs",
13552
- " Phases B + D. Phase F always runs. See the **Run ratio** section",
13553
- " in `CLAUDE.md` for the full contract.",
13554
- "8. **Always run pre-flight before reading dependency state.**",
13555
- " Phase B0 (Pre-flight PR Merge) runs on every invocation \u2014",
13556
- " dispatch and housekeeping \u2014 immediately after Phase A. Never",
13557
- " skip Phase B0: without it, an issue whose only remaining",
13558
- " blocker is an approved-but-not-yet-merged PR reads as blocked",
13559
- " on every cycle and the pipeline thrashes. See the **Pre-flight",
13560
- " PR merge** section in `CLAUDE.md` for eligibility rules and",
13561
- " the delegate-vs-inline modes.",
13562
- "9. **Sweep dependents whenever you apply `status:done`.** Every",
13631
+ " handed a decomposition proposal \u2014 never claimed, never branched,",
13632
+ " never delegated to the `issue-worker`.",
13633
+ "7. **Always run pre-flight before reading dependency state.**",
13634
+ " Phase B0 (Pre-flight PR Merge) runs on every invocation,",
13635
+ " immediately after Phase A. Never skip Phase B0: without it, an",
13636
+ " issue whose only remaining blocker is an approved-but-not-yet-",
13637
+ " merged PR reads as blocked on every cycle and the pipeline",
13638
+ " thrashes. See the **Pre-flight PR merge** section in",
13639
+ " `CLAUDE.md` for eligibility rules and the delegate-vs-inline",
13640
+ " modes.",
13641
+ "8. **Sweep dependents whenever you apply `status:done`.** Every",
13563
13642
  " `status:done` transition must be immediately followed by",
13564
13643
  " `.claude/procedures/unblock-dependents.sh <n>` so downstream",
13565
13644
  " `Depends on: #<n>` issues flip to `status:ready` without",
13566
- " waiting for the next dispatch. Phase B0's post-merge",
13645
+ " waiting for the next cycle. Phase B0's post-merge",
13567
13646
  " verification (and any inline-mode merge) already calls the",
13568
13647
  " sweep; don't skip it. See the **Agent-driven unblocking**",
13569
- " section in `CLAUDE.md` for the contract."
13648
+ " section in `CLAUDE.md` for the contract.",
13649
+ "9. **Always invoke `issue-worker` in scheduled mode.** Phase G's",
13650
+ " delegation prompt must contain the literal phrase",
13651
+ " `scheduled mode` so the worker skips its interactive approval",
13652
+ " pause and runs the implementation cycle autonomously. Without",
13653
+ " the phrase the worker pauses for human approval and the",
13654
+ " delegation stalls."
13570
13655
  ].join("\n")
13571
13656
  };
13572
13657
  var issueWorkerSubAgent = {
@@ -13997,9 +14082,10 @@ var ORCHESTRATOR_CONVENTIONS_PREAMBLE = [
13997
14082
  "",
13998
14083
  "When running the orchestrator agent (`.claude/agents/orchestrator.md`):",
13999
14084
  "",
14000
- "- The orchestrator **never** implements code or creates branches for issues",
14001
- "- It reviews PRs, triages issues, and reports the next work item",
14085
+ "- The orchestrator runs **one full end-to-end cycle every invocation**: pre-flight PR merge \u2192 triage / unblock \u2192 maintenance \u2192 queue scan \u2192 delegate to `issue-worker` \u2192 cleanup",
14086
+ "- The orchestrator **never** implements code, creates branches, or pushes commits \u2014 it merges PRs, triages issues, picks the next work item, and delegates implementation to other sub-agents",
14002
14087
  "- All triage queries use `.claude/procedures/check-blocked.sh` for token efficiency",
14088
+ "- The queue scan reads only `priority:*` and `status:*` labels \u2014 type-routing (which typed agent handles a given `type:*` label) is the `issue-worker`'s concern, not the orchestrator's. The orchestrator's funnel-tier sort is a tie-breaker on `priority:*`, not a routing decision.",
14003
14089
  "- Priority order: critical > high > medium > low > trivial, then **funnel tier asc** (lower tier wins ties), then FIFO by issue number",
14004
14090
  "- Stale thresholds: 72h for in-progress, 168h for blocked",
14005
14091
  "- Flagged issues get `status:needs-attention` \u2014 they are not auto-reset"
@@ -14064,7 +14150,7 @@ var orchestratorBundle = {
14064
14150
  rules: [
14065
14151
  {
14066
14152
  name: "orchestrator-conventions",
14067
- description: "Guidelines for orchestrator agent behavior and pipeline management, including the funnel-tier dispatch sort, scope gate, and dispatch-to-housekeeping run ratio",
14153
+ description: "Guidelines for orchestrator agent behavior and pipeline management, including the funnel-tier dispatch sort, scope gate, pre-flight PR merge contract, and per-agent scheduled-task layout",
14068
14154
  scope: AGENT_RULE_SCOPE.ALWAYS,
14069
14155
  content: buildOrchestratorConventionsContent(
14070
14156
  DEFAULT_AGENT_TIERS,
@@ -26156,7 +26242,7 @@ var VERSION = {
26156
26242
  *
26157
26243
  * CLI and lib are versioned separately, so this is the CLI version.
26158
26244
  */
26159
- AWS_CDK_CLI_VERSION: "2.1119.0",
26245
+ AWS_CDK_CLI_VERSION: "2.1120.0",
26160
26246
  /**
26161
26247
  * CDK Version to use for construct projects.
26162
26248
  *