@codedrifters/configulator 0.0.291 → 0.0.293

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.js CHANGED
@@ -210,6 +210,8 @@ __export(index_exports, {
210
210
  DEFAULT_DISPATCH_MODEL: () => DEFAULT_DISPATCH_MODEL,
211
211
  DEFAULT_DISPATCH_TO_HOUSEKEEPING_RATIO: () => DEFAULT_DISPATCH_TO_HOUSEKEEPING_RATIO,
212
212
  DEFAULT_HOUSEKEEPING_MODEL: () => DEFAULT_HOUSEKEEPING_MODEL,
213
+ DEFAULT_ISSUE_PRIORITY: () => DEFAULT_ISSUE_PRIORITY,
214
+ DEFAULT_ISSUE_STATUS: () => DEFAULT_ISSUE_STATUS,
213
215
  DEFAULT_ISSUE_TEMPLATES_BUNDLE_PATH_PATTERNS: () => DEFAULT_ISSUE_TEMPLATES_BUNDLE_PATH_PATTERNS,
214
216
  DEFAULT_ISSUE_TEMPLATES_EMIT_CHECKER: () => DEFAULT_ISSUE_TEMPLATES_EMIT_CHECKER,
215
217
  DEFAULT_ISSUE_TEMPLATES_EMIT_STARTER: () => DEFAULT_ISSUE_TEMPLATES_EMIT_STARTER,
@@ -226,6 +228,7 @@ __export(index_exports, {
226
228
  DEFAULT_PROGRESS_FILES_STALE_AFTER_HOURS: () => DEFAULT_PROGRESS_FILES_STALE_AFTER_HOURS,
227
229
  DEFAULT_PROGRESS_FILES_STATE_DIR: () => DEFAULT_PROGRESS_FILES_STATE_DIR,
228
230
  DEFAULT_REQUIRE_PRODUCT_CONTEXT: () => DEFAULT_REQUIRE_PRODUCT_CONTEXT,
231
+ DEFAULT_RESOLVED_ISSUE_DEFAULTS: () => DEFAULT_RESOLVED_ISSUE_DEFAULTS,
229
232
  DEFAULT_SAMPLE_COMPILER_OPTIONS: () => DEFAULT_SAMPLE_COMPILER_OPTIONS,
230
233
  DEFAULT_SCHEDULED_TASKS_ROOT: () => DEFAULT_SCHEDULED_TASKS_ROOT,
231
234
  DEFAULT_SCHEDULED_TASK_ENTRIES: () => DEFAULT_SCHEDULED_TASK_ENTRIES,
@@ -277,6 +280,8 @@ __export(index_exports, {
277
280
  TypeScriptConfig: () => TypeScriptConfig,
278
281
  TypeScriptProject: () => TypeScriptProject,
279
282
  UNKNOWN_TYPE_FALLBACK_TIER: () => UNKNOWN_TYPE_FALLBACK_TIER,
283
+ VALID_PRIORITY_VALUES: () => VALID_PRIORITY_VALUES,
284
+ VALID_STATUS_VALUES: () => VALID_STATUS_VALUES,
280
285
  VERSION: () => VERSION,
281
286
  VERSION_KEYS_SKIP: () => VERSION_KEYS_SKIP,
282
287
  VERSION_NPM_PACKAGES: () => VERSION_NPM_PACKAGES,
@@ -335,6 +340,7 @@ __export(index_exports, {
335
340
  githubWorkflowBundle: () => githubWorkflowBundle,
336
341
  industryDiscoveryBundle: () => industryDiscoveryBundle,
337
342
  jestBundle: () => jestBundle,
343
+ labelsForPhase: () => labelsForPhase,
338
344
  maintenanceAuditBundle: () => maintenanceAuditBundle,
339
345
  meetingAnalysisBundle: () => meetingAnalysisBundle,
340
346
  orchestratorBundle: () => orchestratorBundle,
@@ -388,6 +394,7 @@ __export(index_exports, {
388
394
  resolveAgentTiers: () => resolveAgentTiers,
389
395
  resolveAstroProjectOutdir: () => resolveAstroProjectOutdir,
390
396
  resolveAwsCdkProjectOutdir: () => resolveAwsCdkProjectOutdir,
397
+ resolveIssueDefaults: () => resolveIssueDefaults,
391
398
  resolveIssueTemplates: () => resolveIssueTemplates,
392
399
  resolveModelAlias: () => resolveModelAlias,
393
400
  resolveOrchestratorAssets: () => resolveOrchestratorAssets,
@@ -411,6 +418,7 @@ __export(index_exports, {
411
418
  typescriptBundle: () => typescriptBundle,
412
419
  upstreamConfigulatorDocsBundle: () => upstreamConfigulatorDocsBundle,
413
420
  validateAgentTierConfig: () => validateAgentTierConfig,
421
+ validateIssueDefaultsConfig: () => validateIssueDefaultsConfig,
414
422
  validateIssueTemplatesConfig: () => validateIssueTemplatesConfig,
415
423
  validateMonorepoLayout: () => validateMonorepoLayout,
416
424
  validateProgressFilesConfig: () => validateProgressFilesConfig,
@@ -3901,8 +3909,21 @@ function buildBaseBundle(paths = DEFAULT_AGENT_PATHS) {
3901
3909
  "| `status:in-progress` | A worker has claimed the issue and a branch exists. Set when the worker starts; cleared only when the worker opens a PR or the issue fails. |",
3902
3910
  "| `status:ready-for-review` | A PR has been opened for this issue and is awaiting review and merge. Replaces `status:in-progress` at the moment the PR opens. |",
3903
3911
  "| `status:needs-attention` | Automated triage has flagged the issue for human review (stale, failed worker, or ambiguous state). Humans reset this label manually. |",
3912
+ "| `status:deferred` | Captured for provenance only; should not be auto-dispatched. Used by consumers that want a low-priority backlog (e.g. people-profile follow-ups in research-heavy planning repos) to stay out of the orchestrator's queue until a human or a consumer-configured scheduled task promotes it. |",
3904
3913
  "| `status:done` | The change has shipped. Set when the PR merges and the issue closes. |",
3905
3914
  "",
3915
+ "### Configurable filing-site defaults",
3916
+ "",
3917
+ "The bundle-shipped `gh issue create` recipes default to",
3918
+ "`status:ready` + `priority:medium`. Consumers can override the",
3919
+ "defaults per-phase-label via",
3920
+ "`AgentConfigOptions.issueDefaults` \u2014 e.g. flip every",
3921
+ "`people:research` filing to `status:deferred` + `priority:low`",
3922
+ "without touching the bundle source. See the **`issueDefaults`**",
3923
+ "section in the configulator agent-config docs for the full",
3924
+ "schema and consumer example. `status:deferred` is a valid",
3925
+ "override value reserved for this exact use case.",
3926
+ "",
3906
3927
  "### Blocking Rules",
3907
3928
  "",
3908
3929
  "Two rules force `status:blocked` \u2014 both are non-negotiable:",
@@ -4230,8 +4251,92 @@ function buildBaseBundle(paths = DEFAULT_AGENT_PATHS) {
4230
4251
  }
4231
4252
  var baseBundle = buildBaseBundle();
4232
4253
 
4254
+ // src/agent/bundles/issue-defaults.ts
4255
+ var VALID_STATUS_VALUES = [
4256
+ "ready",
4257
+ "blocked",
4258
+ "in-progress",
4259
+ "ready-for-review",
4260
+ "needs-attention",
4261
+ "done",
4262
+ "deferred"
4263
+ ];
4264
+ var VALID_PRIORITY_VALUES = [
4265
+ "critical",
4266
+ "high",
4267
+ "medium",
4268
+ "low",
4269
+ "trivial"
4270
+ ];
4271
+ var DEFAULT_ISSUE_STATUS = "ready";
4272
+ var DEFAULT_ISSUE_PRIORITY = "medium";
4273
+ var DEFAULT_RESOLVED_ISSUE_DEFAULTS = {
4274
+ defaults: {
4275
+ status: DEFAULT_ISSUE_STATUS,
4276
+ priority: DEFAULT_ISSUE_PRIORITY
4277
+ },
4278
+ overrides: {}
4279
+ };
4280
+ function resolveIssueDefaults(config) {
4281
+ if (config === void 0) {
4282
+ return DEFAULT_RESOLVED_ISSUE_DEFAULTS;
4283
+ }
4284
+ const overrides = {};
4285
+ for (const [phaseLabel, override] of Object.entries(config)) {
4286
+ assertValidPhaseLabel(phaseLabel);
4287
+ assertValidOverride(phaseLabel, override);
4288
+ overrides[phaseLabel] = {
4289
+ status: override.status ?? DEFAULT_ISSUE_STATUS,
4290
+ priority: override.priority ?? DEFAULT_ISSUE_PRIORITY
4291
+ };
4292
+ }
4293
+ return {
4294
+ defaults: {
4295
+ status: DEFAULT_ISSUE_STATUS,
4296
+ priority: DEFAULT_ISSUE_PRIORITY
4297
+ },
4298
+ overrides
4299
+ };
4300
+ }
4301
+ function validateIssueDefaultsConfig(config) {
4302
+ return resolveIssueDefaults(config);
4303
+ }
4304
+ function labelsForPhase(resolved, phaseLabel) {
4305
+ return resolved.overrides[phaseLabel] ?? resolved.defaults;
4306
+ }
4307
+ function assertValidPhaseLabel(phaseLabel) {
4308
+ if (typeof phaseLabel !== "string" || phaseLabel.trim() === "") {
4309
+ throw new Error(
4310
+ "AgentConfigOptions.issueDefaults: phase-label keys must be non-empty strings (e.g. `people:research`)."
4311
+ );
4312
+ }
4313
+ }
4314
+ function assertValidOverride(phaseLabel, override) {
4315
+ if (override === null || typeof override !== "object" || Array.isArray(override)) {
4316
+ throw new Error(
4317
+ `AgentConfigOptions.issueDefaults["${phaseLabel}"] must be an object with optional \`status\` and \`priority\` fields.`
4318
+ );
4319
+ }
4320
+ const { status, priority } = override;
4321
+ if (status === void 0 && priority === void 0) {
4322
+ throw new Error(
4323
+ `AgentConfigOptions.issueDefaults["${phaseLabel}"] must declare at least one of \`status\` or \`priority\`. Empty entries are rejected because they are almost always a typo on the field name.`
4324
+ );
4325
+ }
4326
+ if (status !== void 0 && !VALID_STATUS_VALUES.includes(status)) {
4327
+ throw new Error(
4328
+ `AgentConfigOptions.issueDefaults["${phaseLabel}"].status="${status}" is not a recognised status value. Allowed values: ${VALID_STATUS_VALUES.join(", ")}.`
4329
+ );
4330
+ }
4331
+ if (priority !== void 0 && !VALID_PRIORITY_VALUES.includes(priority)) {
4332
+ throw new Error(
4333
+ `AgentConfigOptions.issueDefaults["${phaseLabel}"].priority="${priority}" is not a recognised priority value. Allowed values: ${VALID_PRIORITY_VALUES.join(", ")}.`
4334
+ );
4335
+ }
4336
+ }
4337
+
4233
4338
  // src/agent/bundles/bcm-writer.ts
4234
- function buildBcmWriterSubAgent(paths) {
4339
+ function buildBcmWriterSubAgent(paths, issueDefaults) {
4235
4340
  return {
4236
4341
  name: "bcm-writer",
4237
4342
  description: "Writes BCM (Business Capability Model) capability-model documents through a 4-phase pipeline (outline \u2192 scaffold \u2192 context \u2192 connect), one phase per session, tracked by bcm:* GitHub issue labels with filesystem-based durability between phases. Produces BIZBOK-aligned capability documents \u2014 not requirement documents.",
@@ -4729,20 +4834,37 @@ function buildBcmWriterSubAgent(paths) {
4729
4834
  " section of sibling/parent docs.",
4730
4835
  "",
4731
4836
  "5. **Create downstream research issues.** For each distinct item",
4732
- " surfaced during authoring:",
4837
+ " surfaced during authoring, file one issue against the appropriate",
4838
+ " downstream bundle. Every handoff issue includes a brief scope",
4839
+ " statement, a link back to this BCM document for traceability, and",
4840
+ " a reference to the context-phase output that revealed the item.",
4841
+ "",
4842
+ " **Unfamiliar person (role holder, stakeholder).** Hand off to the",
4843
+ " `people-profile` bundle by creating a `people:research` issue.",
4844
+ " The issue must carry:",
4845
+ "",
4846
+ " - `type:people-profile`",
4847
+ " - `people:research`",
4848
+ ` - \`priority:${labelsForPhase(issueDefaults, "people:research").priority}\``,
4849
+ ` - \`status:${labelsForPhase(issueDefaults, "people:research").status}\``,
4733
4850
  "",
4734
- " | Surfaced item | Downstream label | Bundle |",
4735
- " |---------------|------------------|--------|",
4736
- " | Unfamiliar person (role holder, stakeholder) | `people:research` | `people-profile` |",
4737
- " | Unfamiliar company (enabling vendor, partner, competitor) | `company:research` | `company-profile` |",
4738
- " | Missing research topic (value stream, market sizing, etc.) | `research:scope` | `research-pipeline` |",
4851
+ " **Unfamiliar company (enabling vendor, partner, competitor).**",
4852
+ " Hand off to the `company-profile` bundle by creating a",
4853
+ " `company:research` issue. The issue must carry:",
4739
4854
  "",
4740
- " Each downstream issue should:",
4741
- " - Carry the listed phase label plus the bundle's `type:*` label,",
4742
- " `priority:medium`, and `status:ready`",
4743
- " - Include a brief scope statement and a link back to this BCM",
4744
- " document for traceability",
4745
- " - Reference the context-phase output that revealed the item",
4855
+ " - `type:company-profile`",
4856
+ " - `company:research`",
4857
+ ` - \`priority:${labelsForPhase(issueDefaults, "company:research").priority}\``,
4858
+ ` - \`status:${labelsForPhase(issueDefaults, "company:research").status}\``,
4859
+ "",
4860
+ " **Missing research topic (value stream, market sizing, etc.).**",
4861
+ " Hand off to the `research-pipeline` bundle by creating a",
4862
+ " `research:scope` issue. The issue must carry:",
4863
+ "",
4864
+ " - `type:research`",
4865
+ " - `research:scope`",
4866
+ ` - \`priority:${labelsForPhase(issueDefaults, "research:scope").priority}\``,
4867
+ ` - \`status:${labelsForPhase(issueDefaults, "research:scope").status}\``,
4746
4868
  "",
4747
4869
  " This phase assumes the `people-profile`, `company-profile`, and",
4748
4870
  " `research-pipeline` bundles are enabled in the consuming project.",
@@ -4818,7 +4940,7 @@ function buildBcmWriterSubAgent(paths) {
4818
4940
  ].join("\n")
4819
4941
  };
4820
4942
  }
4821
- function buildWriteBcmSkill(paths) {
4943
+ function buildWriteBcmSkill(paths, issueDefaults) {
4822
4944
  return {
4823
4945
  name: "write-bcm",
4824
4946
  description: "Kick off a BCM capability-model document authoring cycle. Creates a bcm:outline issue carrying the capability name and dispatches Phase 1 (Outline) in the bcm-writer agent.",
@@ -4863,9 +4985,11 @@ function buildWriteBcmSkill(paths) {
4863
4985
  "## Steps",
4864
4986
  "",
4865
4987
  "1. Create a `bcm:outline` issue with `type:bcm-document`,",
4866
- " `priority:medium`, and `status:ready`. Body must include the",
4988
+ ` \`priority:${labelsForPhase(issueDefaults, "bcm:outline").priority}\`, and \`status:${labelsForPhase(issueDefaults, "bcm:outline").status}\`. Body must include the`,
4867
4989
  " verbatim capability name and any overrides.",
4990
+ "",
4868
4991
  "2. Execute Phase 1 (Outline) of the bcm-writer agent.",
4992
+ "",
4869
4993
  "3. Phase 1 creates a `bcm:scaffold` issue, which Phase 2 follows with",
4870
4994
  " `bcm:context`, then Phase 4 (`bcm:connect`). Each downstream issue",
4871
4995
  " declares its `Depends on:` predecessor. Phase 4 creates downstream",
@@ -4884,7 +5008,7 @@ function buildWriteBcmSkill(paths) {
4884
5008
  ].join("\n")
4885
5009
  };
4886
5010
  }
4887
- function buildBcmWriterBundle(paths = DEFAULT_AGENT_PATHS) {
5011
+ function buildBcmWriterBundle(paths = DEFAULT_AGENT_PATHS, issueDefaults = DEFAULT_RESOLVED_ISSUE_DEFAULTS) {
4888
5012
  return {
4889
5013
  name: "bcm-writer",
4890
5014
  description: "BCM (Business Capability Model) capability-model document authoring pipeline: outline, scaffold, context, connect. Enabled by default; BIZBOK-aligned; filesystem-durable between phases.",
@@ -4929,8 +5053,8 @@ function buildBcmWriterBundle(paths = DEFAULT_AGENT_PATHS) {
4929
5053
  tags: ["workflow"]
4930
5054
  }
4931
5055
  ],
4932
- skills: [buildWriteBcmSkill(paths)],
4933
- subAgents: [buildBcmWriterSubAgent(paths)],
5056
+ skills: [buildWriteBcmSkill(paths, issueDefaults)],
5057
+ subAgents: [buildBcmWriterSubAgent(paths, issueDefaults)],
4934
5058
  labels: [
4935
5059
  {
4936
5060
  name: "type:bcm-document",
@@ -5702,7 +5826,7 @@ function buildBusinessModelsAnalystSubAgent(paths) {
5702
5826
  ].join("\n")
5703
5827
  };
5704
5828
  }
5705
- function buildScanBusinessModelsSkill(paths) {
5829
+ function buildScanBusinessModelsSkill(paths, issueDefaults) {
5706
5830
  return {
5707
5831
  name: "scan-business-models",
5708
5832
  description: "Kick off the scan phase of a business-model analysis cycle. Creates a business-models:scan issue for the supplied industry and dispatches Phase 1 of the business-models-analyst, which reads industry-discovery output and identifies segments needing a canvas.",
@@ -5741,7 +5865,7 @@ function buildScanBusinessModelsSkill(paths) {
5741
5865
  "## Steps",
5742
5866
  "",
5743
5867
  "1. Create a `business-models:scan` issue with `type:business-model`,",
5744
- " `priority:medium`, and `status:ready`. The body must include the",
5868
+ ` \`priority:${labelsForPhase(issueDefaults, "business-models:scan").priority}\`, and \`status:${labelsForPhase(issueDefaults, "business-models:scan").status}\`. The body must include the`,
5745
5869
  " industry slug, the source plan path (if any), and any overrides.",
5746
5870
  "2. Execute Phase 1 (Scan) of the business-models-analyst agent.",
5747
5871
  "3. Phase 1 creates one `business-models:canvas` issue per in-scope",
@@ -5758,7 +5882,7 @@ function buildScanBusinessModelsSkill(paths) {
5758
5882
  ].join("\n")
5759
5883
  };
5760
5884
  }
5761
- function buildCanvasBusinessModelSkill(paths) {
5885
+ function buildCanvasBusinessModelSkill(paths, issueDefaults) {
5762
5886
  return {
5763
5887
  name: "canvas-business-model",
5764
5888
  description: "Kick off the canvas phase of a business-model analysis cycle. Creates a business-models:canvas issue for the supplied industry/segment and dispatches Phase 2 of the business-models-analyst, which researches and writes the Osterwalder nine-block canvas.",
@@ -5814,7 +5938,7 @@ function buildCanvasBusinessModelSkill(paths) {
5814
5938
  "## Steps",
5815
5939
  "",
5816
5940
  "1. Create a `business-models:canvas` issue with",
5817
- " `type:business-model`, `priority:medium`, and `status:ready`.",
5941
+ ` \`type:business-model\`, \`priority:${labelsForPhase(issueDefaults, "business-models:canvas").priority}\`, and \`status:${labelsForPhase(issueDefaults, "business-models:canvas").status}\`.`,
5818
5942
  " The body must include the industry slug, segment slug, and any",
5819
5943
  " scan-report reference.",
5820
5944
  "2. Execute Phase 2 (Canvas) of the business-models-analyst agent.",
@@ -5830,7 +5954,7 @@ function buildCanvasBusinessModelSkill(paths) {
5830
5954
  ].join("\n")
5831
5955
  };
5832
5956
  }
5833
- function buildCompleteBusinessModelSkill(paths) {
5957
+ function buildCompleteBusinessModelSkill(paths, issueDefaults) {
5834
5958
  return {
5835
5959
  name: "complete-business-model",
5836
5960
  description: "Kick off the complete phase of a business-model analysis cycle. Creates a business-models:complete issue for an already-authored canvas and dispatches Phase 3 of the business-models-analyst, which derives BIZBOK value streams, documents variations, and hands off capability work to bcm-writer.",
@@ -5874,7 +5998,7 @@ function buildCompleteBusinessModelSkill(paths) {
5874
5998
  "## Steps",
5875
5999
  "",
5876
6000
  "1. Create a `business-models:complete` issue with",
5877
- " `type:business-model`, `priority:medium`, and `status:ready`.",
6001
+ ` \`type:business-model\`, \`priority:${labelsForPhase(issueDefaults, "business-models:complete").priority}\`, and \`status:${labelsForPhase(issueDefaults, "business-models:complete").status}\`.`,
5878
6002
  " Body must include the canvas document path.",
5879
6003
  "2. Execute Phase 3 (Complete) of the business-models-analyst agent.",
5880
6004
  "",
@@ -5889,7 +6013,7 @@ function buildCompleteBusinessModelSkill(paths) {
5889
6013
  ].join("\n")
5890
6014
  };
5891
6015
  }
5892
- function buildBusinessModelsBundle(paths = DEFAULT_AGENT_PATHS) {
6016
+ function buildBusinessModelsBundle(paths = DEFAULT_AGENT_PATHS, issueDefaults = DEFAULT_RESOLVED_ISSUE_DEFAULTS) {
5893
6017
  return {
5894
6018
  name: "business-models",
5895
6019
  description: "Business-model authoring pipeline: Osterwalder Business Model Canvas plus BIZBOK value streams per industry segment. 3 phases (scan, canvas, complete) with business-models:* phase labels. Sits between industry-discovery and bcm-writer in the research pipeline. Enabled by default; domain-neutral; filesystem-durable between phases.",
@@ -5941,9 +6065,9 @@ function buildBusinessModelsBundle(paths = DEFAULT_AGENT_PATHS) {
5941
6065
  }
5942
6066
  ],
5943
6067
  skills: [
5944
- buildScanBusinessModelsSkill(paths),
5945
- buildCanvasBusinessModelSkill(paths),
5946
- buildCompleteBusinessModelSkill(paths)
6068
+ buildScanBusinessModelsSkill(paths, issueDefaults),
6069
+ buildCanvasBusinessModelSkill(paths, issueDefaults),
6070
+ buildCompleteBusinessModelSkill(paths, issueDefaults)
5947
6071
  ],
5948
6072
  subAgents: [buildBusinessModelsAnalystSubAgent(paths)],
5949
6073
  labels: [
@@ -5973,7 +6097,7 @@ function buildBusinessModelsBundle(paths = DEFAULT_AGENT_PATHS) {
5973
6097
  var businessModelsBundle = buildBusinessModelsBundle();
5974
6098
 
5975
6099
  // src/agent/bundles/company-profile.ts
5976
- function buildCompanyProfileAnalystSubAgent(paths) {
6100
+ function buildCompanyProfileAnalystSubAgent(paths, issueDefaults) {
5977
6101
  return {
5978
6102
  name: "company-profile-analyst",
5979
6103
  description: "Researches an external company (competitor, vendor, partner, customer, etc.) from public sources and produces a structured markdown profile, then enqueues downstream `people:research` and `software:research` issues for notable people and software products surfaced during profiling. Also handles profile enrichment against business-model canvases (`company:match`), maintenance refreshes on a configurable staleness cadence (`company:refresh`), and cross-profile competitive synthesis for a segment (`company:analyze`). One company or segment per session, tracked by company:* GitHub issue labels.",
@@ -6383,8 +6507,8 @@ function buildCompanyProfileAnalystSubAgent(paths) {
6383
6507
  "",
6384
6508
  " - `type:people-profile`",
6385
6509
  " - `people:research`",
6386
- " - `priority:medium`",
6387
- " - `status:ready`",
6510
+ ` - \`priority:${labelsForPhase(issueDefaults, "people:research").priority}\``,
6511
+ ` - \`status:${labelsForPhase(issueDefaults, "people:research").status}\``,
6388
6512
  "",
6389
6513
  " The issue body must include:",
6390
6514
  " - A **discovery source** line naming this company profile",
@@ -6400,8 +6524,8 @@ function buildCompanyProfileAnalystSubAgent(paths) {
6400
6524
  "",
6401
6525
  " - `type:software-profile`",
6402
6526
  " - `software:research`",
6403
- " - `priority:medium`",
6404
- " - `status:ready`",
6527
+ ` - \`priority:${labelsForPhase(issueDefaults, "software:research").priority}\``,
6528
+ ` - \`status:${labelsForPhase(issueDefaults, "software:research").status}\``,
6405
6529
  "",
6406
6530
  " The issue body must include:",
6407
6531
  " - A **discovery source** line naming this company profile",
@@ -6842,47 +6966,52 @@ function buildCompanyProfileAnalystSubAgent(paths) {
6842
6966
  ].join("\n")
6843
6967
  };
6844
6968
  }
6845
- var PROFILE_COMPANY_EVALS_JSON = JSON.stringify(
6846
- {
6847
- skill_name: "profile-company",
6848
- evals: [
6849
- {
6850
- id: 1,
6851
- prompt: "/profile-company Acme Registration \u2014 they're a mid-market B2B event platform we ran into at a trade show last month. framing: competitive analysis for our self-service registration feature.",
6852
- expected_output: "A `company:research` issue is created with `type:company-profile`, `priority:medium`, and `status:ready`. The issue body carries the company name, an inferred or stated type (likely `competitor` given the framing), the framing text, and any supplied overrides. Phase 1 produces a research-notes file under the project's notes directory with sources annotated by tier (T1/T2/T3/T4) and date. Phase 2 opens a `company:draft` issue and may additionally open `people:research` issues for notable leaders surfaced and `software:research` issues for adjacent product mentions. The skill does not author person profiles, software profiles, or comparative analyses itself.",
6853
- files: [],
6854
- product_context_refs: [
6855
- "Mission",
6856
- "Domain Vocabulary",
6857
- "In-Scope Capabilities"
6858
- ]
6859
- },
6860
- {
6861
- id: 2,
6862
- prompt: "Profile a startup called Lumen Events. Their current company page lists a 150-person team but a TechCrunch article from six months ago said they were at 80 people. Handle the conflict.",
6863
- expected_output: "The `company:research` issue body captures the conflict up-front under a dedicated conflict-resolution note. The research notes file annotates the live company page as a T1 living source and the TechCrunch article as a T3 secondary source. Conflict resolution follows the documented hierarchy: T1 wins on headcount (a fast-decay claim), so the current-state profile records 150 employees. The profile adds an inline note flagging that the T3 source is six months old and may simply be stale. Sources section lists each citation with tier, access date or publish date, and URL.",
6864
- files: [],
6865
- product_context_refs: ["Domain Vocabulary"]
6866
- },
6867
- {
6868
- id: 3,
6869
- prompt: "/profile-company Acme Registration \u2014 we already have a profile for them but it's nine months old. Refresh it.",
6870
- expected_output: "The pipeline routes through the refresh phase (not a fresh profile). It reads the existing profile slug and refuses to create a second profile under a new slug. When the existing profile is younger than the configured staleness threshold and `force: true` is not set, the refresh phase exits early and appends a revision-history row noting the review. When the profile is past cadence (nine months qualifies for most fast-decay fields), the refresh updates fast-decay claims in place (headcount, leadership, pricing, product features) while preserving stable history, and appends a revision-history row citing what changed and which sources were re-checked. No new profile file is created.",
6871
- files: [],
6872
- product_context_refs: ["Domain Vocabulary"]
6873
- }
6874
- ]
6875
- },
6876
- null,
6877
- 2
6878
- );
6879
- var PROFILE_COMPANY_REFERENCE_FILES = [
6880
- {
6881
- path: "evals/evals.json",
6882
- content: PROFILE_COMPANY_EVALS_JSON
6883
- }
6884
- ];
6885
- function buildProfileCompanySkill(paths) {
6969
+ function buildProfileCompanyEvalsJson(issueDefaults) {
6970
+ const research = labelsForPhase(issueDefaults, "company:research");
6971
+ return JSON.stringify(
6972
+ {
6973
+ skill_name: "profile-company",
6974
+ evals: [
6975
+ {
6976
+ id: 1,
6977
+ prompt: "/profile-company Acme Registration \u2014 they're a mid-market B2B event platform we ran into at a trade show last month. framing: competitive analysis for our self-service registration feature.",
6978
+ expected_output: `A \`company:research\` issue is created with \`type:company-profile\`, \`priority:${research.priority}\`, and \`status:${research.status}\`. The issue body carries the company name, an inferred or stated type (likely \`competitor\` given the framing), the framing text, and any supplied overrides. Phase 1 produces a research-notes file under the project's notes directory with sources annotated by tier (T1/T2/T3/T4) and date. Phase 2 opens a \`company:draft\` issue and may additionally open \`people:research\` issues for notable leaders surfaced and \`software:research\` issues for adjacent product mentions. The skill does not author person profiles, software profiles, or comparative analyses itself.`,
6979
+ files: [],
6980
+ product_context_refs: [
6981
+ "Mission",
6982
+ "Domain Vocabulary",
6983
+ "In-Scope Capabilities"
6984
+ ]
6985
+ },
6986
+ {
6987
+ id: 2,
6988
+ prompt: "Profile a startup called Lumen Events. Their current company page lists a 150-person team but a TechCrunch article from six months ago said they were at 80 people. Handle the conflict.",
6989
+ expected_output: "The `company:research` issue body captures the conflict up-front under a dedicated conflict-resolution note. The research notes file annotates the live company page as a T1 living source and the TechCrunch article as a T3 secondary source. Conflict resolution follows the documented hierarchy: T1 wins on headcount (a fast-decay claim), so the current-state profile records 150 employees. The profile adds an inline note flagging that the T3 source is six months old and may simply be stale. Sources section lists each citation with tier, access date or publish date, and URL.",
6990
+ files: [],
6991
+ product_context_refs: ["Domain Vocabulary"]
6992
+ },
6993
+ {
6994
+ id: 3,
6995
+ prompt: "/profile-company Acme Registration \u2014 we already have a profile for them but it's nine months old. Refresh it.",
6996
+ expected_output: "The pipeline routes through the refresh phase (not a fresh profile). It reads the existing profile slug and refuses to create a second profile under a new slug. When the existing profile is younger than the configured staleness threshold and `force: true` is not set, the refresh phase exits early and appends a revision-history row noting the review. When the profile is past cadence (nine months qualifies for most fast-decay fields), the refresh updates fast-decay claims in place (headcount, leadership, pricing, product features) while preserving stable history, and appends a revision-history row citing what changed and which sources were re-checked. No new profile file is created.",
6997
+ files: [],
6998
+ product_context_refs: ["Domain Vocabulary"]
6999
+ }
7000
+ ]
7001
+ },
7002
+ null,
7003
+ 2
7004
+ );
7005
+ }
7006
+ function buildProfileCompanyReferenceFiles(issueDefaults) {
7007
+ return [
7008
+ {
7009
+ path: "evals/evals.json",
7010
+ content: buildProfileCompanyEvalsJson(issueDefaults)
7011
+ }
7012
+ ];
7013
+ }
7014
+ function buildProfileCompanySkill(paths, issueDefaults) {
6886
7015
  return {
6887
7016
  name: "profile-company",
6888
7017
  description: "Kick off a company-profile pipeline. Creates a company:research issue for the given company and dispatches Phase 1 (Research) in the company-profile-analyst agent.",
@@ -6891,7 +7020,7 @@ function buildProfileCompanySkill(paths) {
6891
7020
  context: "fork",
6892
7021
  agent: "company-profile-analyst",
6893
7022
  platforms: { cursor: { exclude: true } },
6894
- referenceFiles: PROFILE_COMPANY_REFERENCE_FILES,
7023
+ referenceFiles: buildProfileCompanyReferenceFiles(issueDefaults),
6895
7024
  instructions: [
6896
7025
  "# Profile Company",
6897
7026
  "",
@@ -6922,7 +7051,7 @@ function buildProfileCompanySkill(paths) {
6922
7051
  "## Steps",
6923
7052
  "",
6924
7053
  "1. Create a `company:research` issue with `type:company-profile`,",
6925
- " `priority:medium`, and `status:ready`. Body must include the",
7054
+ ` \`priority:${labelsForPhase(issueDefaults, "company:research").priority}\`, and \`status:${labelsForPhase(issueDefaults, "company:research").status}\`. Body must include the`,
6926
7055
  " company name, selected type, framing, and any overrides.",
6927
7056
  "2. Execute Phase 1 (Research) of the company-profile-analyst agent.",
6928
7057
  "3. Phase 1 creates the `company:draft` issue. Phase 2 may create a",
@@ -6946,7 +7075,7 @@ function buildProfileCompanySkill(paths) {
6946
7075
  ].join("\n")
6947
7076
  };
6948
7077
  }
6949
- function buildMatchCompanySkill(paths) {
7078
+ function buildMatchCompanySkill(paths, issueDefaults) {
6950
7079
  return {
6951
7080
  name: "match-company",
6952
7081
  description: "Kick off a company-profile match (enrichment) cycle. Creates a company:match issue for an existing profile and dispatches Phase 4 (Match) in the company-profile-analyst agent. Match enriches the profile with business-model, segment, and size context from existing docs \u2014 no web searches.",
@@ -6996,7 +7125,7 @@ function buildMatchCompanySkill(paths) {
6996
7125
  "## Steps",
6997
7126
  "",
6998
7127
  "1. Create a `company:match` issue with `type:company-profile`,",
6999
- " `priority:medium`, and `status:ready`. Body must include the",
7128
+ ` \`priority:${labelsForPhase(issueDefaults, "company:match").priority}\`, and \`status:${labelsForPhase(issueDefaults, "company:match").status}\`. Body must include the`,
7000
7129
  " profile path and any overrides.",
7001
7130
  "2. Execute Phase 4 (Match) of the company-profile-analyst agent.",
7002
7131
  "",
@@ -7011,7 +7140,7 @@ function buildMatchCompanySkill(paths) {
7011
7140
  ].join("\n")
7012
7141
  };
7013
7142
  }
7014
- function buildRefreshCompanySkill(paths) {
7143
+ function buildRefreshCompanySkill(paths, issueDefaults) {
7015
7144
  return {
7016
7145
  name: "refresh-company",
7017
7146
  description: "Kick off a company-profile refresh cycle. Creates a company:refresh issue for an existing profile and dispatches Phase 5 (Refresh) in the company-profile-analyst agent. Refresh re-verifies the profile with 4\u20136 targeted web searches and updates it in place. Respects a configurable staleness threshold so profiles younger than the threshold exit early.",
@@ -7069,7 +7198,7 @@ function buildRefreshCompanySkill(paths) {
7069
7198
  "## Steps",
7070
7199
  "",
7071
7200
  "1. Create a `company:refresh` issue with `type:company-profile`,",
7072
- " `priority:medium`, and `status:ready`. Body must include the",
7201
+ ` \`priority:${labelsForPhase(issueDefaults, "company:refresh").priority}\`, and \`status:${labelsForPhase(issueDefaults, "company:refresh").status}\`. Body must include the`,
7073
7202
  " profile path and any overrides.",
7074
7203
  "2. Execute Phase 5 (Refresh) of the company-profile-analyst agent.",
7075
7204
  "",
@@ -7085,7 +7214,7 @@ function buildRefreshCompanySkill(paths) {
7085
7214
  ].join("\n")
7086
7215
  };
7087
7216
  }
7088
- function buildAnalyzeSegmentSkill(paths) {
7217
+ function buildAnalyzeSegmentSkill(paths, issueDefaults) {
7089
7218
  return {
7090
7219
  name: "analyze-segment",
7091
7220
  description: "Kick off a segment-level competitive-analysis cycle. Creates a company:analyze issue for the target segment and dispatches Phase 6 (Analyze) in the company-profile-analyst agent. Analyze synthesizes every profile in the segment into one competitive-analysis document. Blocks on open company:draft issues for the segment.",
@@ -7142,7 +7271,7 @@ function buildAnalyzeSegmentSkill(paths) {
7142
7271
  "## Steps",
7143
7272
  "",
7144
7273
  "1. Create a `company:analyze` issue with `type:company-profile`,",
7145
- " `priority:medium`, and `status:ready`. Body must include the",
7274
+ ` \`priority:${labelsForPhase(issueDefaults, "company:analyze").priority}\`, and \`status:${labelsForPhase(issueDefaults, "company:analyze").status}\`. Body must include the`,
7146
7275
  " segment slug and any overrides.",
7147
7276
  "2. Execute Phase 6 (Analyze) of the company-profile-analyst agent.",
7148
7277
  "",
@@ -7159,7 +7288,7 @@ function buildAnalyzeSegmentSkill(paths) {
7159
7288
  ].join("\n")
7160
7289
  };
7161
7290
  }
7162
- function buildCompanyProfileBundle(paths = DEFAULT_AGENT_PATHS) {
7291
+ function buildCompanyProfileBundle(paths = DEFAULT_AGENT_PATHS, issueDefaults = DEFAULT_RESOLVED_ISSUE_DEFAULTS) {
7163
7292
  return {
7164
7293
  name: "company-profile",
7165
7294
  description: "Company research and profiling pipeline: research, draft profile, followup, match, refresh, analyze. Enabled by default; domain-neutral; filesystem-durable between phases. Phase 3 (Followup) hands surfaced people and software products off to the `people-profile` and `software-profile` bundles via `people:research` and `software:research` issues. Phase 4 (Match) enriches profiles against business-model canvases. Phase 5 (Refresh) re-verifies profiles on a configurable staleness cadence. Phase 6 (Analyze) synthesizes profiles in a segment into a competitive-analysis document.",
@@ -7212,12 +7341,12 @@ function buildCompanyProfileBundle(paths = DEFAULT_AGENT_PATHS) {
7212
7341
  }
7213
7342
  ],
7214
7343
  skills: [
7215
- buildProfileCompanySkill(paths),
7216
- buildMatchCompanySkill(paths),
7217
- buildRefreshCompanySkill(paths),
7218
- buildAnalyzeSegmentSkill(paths)
7344
+ buildProfileCompanySkill(paths, issueDefaults),
7345
+ buildMatchCompanySkill(paths, issueDefaults),
7346
+ buildRefreshCompanySkill(paths, issueDefaults),
7347
+ buildAnalyzeSegmentSkill(paths, issueDefaults)
7219
7348
  ],
7220
- subAgents: [buildCompanyProfileAnalystSubAgent(paths)],
7349
+ subAgents: [buildCompanyProfileAnalystSubAgent(paths, issueDefaults)],
7221
7350
  labels: [
7222
7351
  {
7223
7352
  name: "type:company-profile",
@@ -7397,7 +7526,7 @@ var CUSTOMER_PROFILE_REFERENCE_FILES = [
7397
7526
  content: TEMPLATE_CUSTOMER_PROFILE
7398
7527
  }
7399
7528
  ];
7400
- function buildCustomerProfileAnalystSubAgent(paths) {
7529
+ function buildCustomerProfileAnalystSubAgent(paths, issueDefaults) {
7401
7530
  return {
7402
7531
  name: "customer-profile-analyst",
7403
7532
  description: "Authors customer-archetype research through a 3-phase pipeline (discover \u2192 profile \u2192 competitors). Segments customer archetypes, profiles each archetype's goals, jobs-to-be-done, constraints, and buying process, then maps competitor features (from the shared software-profile feature matrix) to each archetype's needs and hands off unmet-need gaps to the requirements-analyst as req:scan seeds. One phase per session, tracked by customer:* GitHub issue labels with filesystem-based durability between phases.",
@@ -7721,12 +7850,23 @@ function buildCustomerProfileAnalystSubAgent(paths) {
7721
7850
  " customer organizations that do not already have a canonical",
7722
7851
  " profile or an open `company:research` issue. The",
7723
7852
  " `company-profile` bundle owns the downstream profile; this",
7724
- " agent only hands off.",
7853
+ " agent only hands off. Each issue must carry:",
7854
+ "",
7855
+ " - `type:company-profile`",
7856
+ " - `company:research`",
7857
+ ` - \`priority:${labelsForPhase(issueDefaults, "company:research").priority}\``,
7858
+ ` - \`status:${labelsForPhase(issueDefaults, "company:research").status}\``,
7725
7859
  "",
7726
7860
  "9. **Create `people:research` issues** for notable contacts",
7727
7861
  " (economic buyers, technical buyers, user champions) surfaced in",
7728
7862
  " sources. Keep the list small \u2014 at most three individuals per",
7729
7863
  " profile session \u2014 and skip anyone already profiled or queued.",
7864
+ " Each issue must carry:",
7865
+ "",
7866
+ " - `type:people-profile`",
7867
+ " - `people:research`",
7868
+ ` - \`priority:${labelsForPhase(issueDefaults, "people:research").priority}\``,
7869
+ ` - \`status:${labelsForPhase(issueDefaults, "people:research").status}\``,
7730
7870
  "",
7731
7871
  "10. **Verify all handoffs were created** before committing.",
7732
7872
  "",
@@ -7822,21 +7962,39 @@ function buildCustomerProfileAnalystSubAgent(paths) {
7822
7962
  "7. **Create `req:scan` issues** for each unmet need. Each issue",
7823
7963
  " hands off to the `requirements-analyst` bundle so its scan phase",
7824
7964
  " can deduplicate and open `req:write` issues in the appropriate",
7825
- " category. Each handoff issue body must:",
7826
- " - Carry `type:requirement` and `req:scan` labels",
7965
+ " category. Each handoff issue must carry:",
7966
+ "",
7967
+ " - `type:requirement`",
7968
+ " - `req:scan`",
7969
+ ` - \`priority:${labelsForPhase(issueDefaults, "req:scan").priority}\``,
7970
+ ` - \`status:${labelsForPhase(issueDefaults, "req:scan").status}\``,
7971
+ "",
7972
+ " The body must also:",
7827
7973
  " - Link back to the archetype page and the competitor page",
7828
7974
  " - Cite the specific unmet-need row and the originating job",
7829
- " - Inherit priority from the unmet need (escalate if the",
7830
- " archetype is high-priority and the gap is a deal-breaker)",
7975
+ " - Escalate the priority above the bundle default when the",
7976
+ " archetype is high-priority and the gap is a deal-breaker",
7831
7977
  "",
7832
7978
  "8. **Create `company:research` issues** for competitor organizations",
7833
7979
  " referenced in the analysis that do not already have a canonical",
7834
- " profile or an open `company:research` issue.",
7980
+ " profile or an open `company:research` issue. Each issue must",
7981
+ " carry:",
7982
+ "",
7983
+ " - `type:company-profile`",
7984
+ " - `company:research`",
7985
+ ` - \`priority:${labelsForPhase(issueDefaults, "company:research").priority}\``,
7986
+ ` - \`status:${labelsForPhase(issueDefaults, "company:research").status}\``,
7835
7987
  "",
7836
7988
  "9. **Create `people:research` issues** for notable competitor",
7837
7989
  " leadership or customer-advocacy figures surfaced in the analysis.",
7838
7990
  " Keep this list small \u2014 at most three individuals per competitors",
7839
- " session \u2014 and skip anyone already profiled or queued.",
7991
+ " session \u2014 and skip anyone already profiled or queued. Each",
7992
+ " issue must carry:",
7993
+ "",
7994
+ " - `type:people-profile`",
7995
+ " - `people:research`",
7996
+ ` - \`priority:${labelsForPhase(issueDefaults, "people:research").priority}\``,
7997
+ ` - \`status:${labelsForPhase(issueDefaults, "people:research").status}\``,
7840
7998
  "",
7841
7999
  "10. **Commit and push** the competitor-analysis page and the",
7842
8000
  " updated archetype page. Close the competitors issue.",
@@ -7980,7 +8138,7 @@ function buildCustomerProfileAnalystSubAgent(paths) {
7980
8138
  ].join("\n")
7981
8139
  };
7982
8140
  }
7983
- function buildDiscoverCustomersSkill(paths) {
8141
+ function buildDiscoverCustomersSkill(paths, issueDefaults) {
7984
8142
  return {
7985
8143
  name: "discover-customers",
7986
8144
  description: "Kick off the discover phase of a customer-research campaign. Creates a customer:discover issue for the supplied scope (industry, segment, or the consuming project as a whole) and dispatches Phase 1 of the customer-profile-analyst, which scans existing documentation for archetype candidates, writes a discovery report, and creates downstream customer:profile issues.",
@@ -8022,7 +8180,7 @@ function buildDiscoverCustomersSkill(paths) {
8022
8180
  "## Steps",
8023
8181
  "",
8024
8182
  "1. Create a `customer:discover` issue with `type:customer-profile`,",
8025
- " `priority:medium`, and `status:ready`. The body must include the",
8183
+ ` \`priority:${labelsForPhase(issueDefaults, "customer:discover").priority}\`, and \`status:${labelsForPhase(issueDefaults, "customer:discover").status}\`. The body must include the`,
8026
8184
  " scope slug and any known archetypes to include or exclude.",
8027
8185
  "2. Execute Phase 1 (Discover) of the customer-profile-analyst agent.",
8028
8186
  "3. Phase 1 writes the discovery report and creates one",
@@ -8037,7 +8195,7 @@ function buildDiscoverCustomersSkill(paths) {
8037
8195
  ].join("\n")
8038
8196
  };
8039
8197
  }
8040
- function buildProfileCustomerSkill(paths) {
8198
+ function buildProfileCustomerSkill(paths, issueDefaults) {
8041
8199
  return {
8042
8200
  name: "profile-customer",
8043
8201
  description: "Kick off the profile phase for one customer archetype. Creates a customer:profile issue for the supplied archetype and dispatches Phase 2 of the customer-profile-analyst, which populates the archetype page with segment, goals, jobs-to-be-done, constraints, buying process, technology landscape, and regulatory applicability using the ship-with customer-profile-page template.",
@@ -8097,7 +8255,7 @@ function buildProfileCustomerSkill(paths) {
8097
8255
  "## Steps",
8098
8256
  "",
8099
8257
  "1. Create a `customer:profile` issue with `type:customer-profile`,",
8100
- " `priority:medium`, and `status:ready`. The body must include the",
8258
+ ` \`priority:${labelsForPhase(issueDefaults, "customer:profile").priority}\`, and \`status:${labelsForPhase(issueDefaults, "customer:profile").status}\`. The body must include the`,
8101
8259
  " archetype slug and (optionally) the segment slug.",
8102
8260
  "2. Execute Phase 2 (Profile) of the customer-profile-analyst agent.",
8103
8261
  " The agent runs 4\u20138 targeted web searches and populates the",
@@ -8117,7 +8275,7 @@ function buildProfileCustomerSkill(paths) {
8117
8275
  ].join("\n")
8118
8276
  };
8119
8277
  }
8120
- function buildAnalyzeCustomerCompetitorsSkill(paths) {
8278
+ function buildAnalyzeCustomerCompetitorsSkill(paths, issueDefaults) {
8121
8279
  return {
8122
8280
  name: "analyze-customer-competitors",
8123
8281
  description: "Kick off the competitors phase for one customer archetype. Creates a customer:competitors issue for the supplied archetype and dispatches Phase 3 of the customer-profile-analyst, which maps rows from the shared software-profile feature matrix to the archetype's needs, identifies unmet needs, and hands off each unmet need as a req:scan seed to the requirements-analyst bundle.",
@@ -8171,8 +8329,8 @@ function buildAnalyzeCustomerCompetitorsSkill(paths) {
8171
8329
  "## Steps",
8172
8330
  "",
8173
8331
  "1. Create a `customer:competitors` issue with",
8174
- " `type:customer-profile`, `priority:medium`, and",
8175
- " `status:ready` (or `status:blocked` when still dependent on a",
8332
+ ` \`type:customer-profile\`, \`priority:${labelsForPhase(issueDefaults, "customer:competitors").priority}\`, and`,
8333
+ ` \`status:${labelsForPhase(issueDefaults, "customer:competitors").status}\` (or \`status:blocked\` when still dependent on a`,
8176
8334
  " Phase 2 profile issue). Body must include the archetype page",
8177
8335
  " path.",
8178
8336
  "2. Execute Phase 3 (Competitors) of the customer-profile-analyst",
@@ -8197,7 +8355,7 @@ function buildAnalyzeCustomerCompetitorsSkill(paths) {
8197
8355
  ].join("\n")
8198
8356
  };
8199
8357
  }
8200
- function buildCustomerProfileBundle(paths = DEFAULT_AGENT_PATHS) {
8358
+ function buildCustomerProfileBundle(paths = DEFAULT_AGENT_PATHS, issueDefaults = DEFAULT_RESOLVED_ISSUE_DEFAULTS) {
8201
8359
  return {
8202
8360
  name: "customer-profile",
8203
8361
  description: "Customer-archetype research pipeline: discover, profile, competitors. 3 phases with customer:* phase labels. Segments customer archetypes, profiles each archetype's goals, jobs-to-be-done, constraints, and buying process, then maps competitor features (from the shared software-profile feature matrix) to each archetype's needs and hands off unmet-need gaps to the requirements-analyst bundle as req:scan seeds. Enabled by default; domain-neutral; customer-centric (distinct from company-profile); filesystem-durable between phases.",
@@ -8268,11 +8426,11 @@ function buildCustomerProfileBundle(paths = DEFAULT_AGENT_PATHS) {
8268
8426
  }
8269
8427
  ],
8270
8428
  skills: [
8271
- buildDiscoverCustomersSkill(paths),
8272
- buildProfileCustomerSkill(paths),
8273
- buildAnalyzeCustomerCompetitorsSkill(paths)
8429
+ buildDiscoverCustomersSkill(paths, issueDefaults),
8430
+ buildProfileCustomerSkill(paths, issueDefaults),
8431
+ buildAnalyzeCustomerCompetitorsSkill(paths, issueDefaults)
8274
8432
  ],
8275
- subAgents: [buildCustomerProfileAnalystSubAgent(paths)],
8433
+ subAgents: [buildCustomerProfileAnalystSubAgent(paths, issueDefaults)],
8276
8434
  labels: [
8277
8435
  {
8278
8436
  name: "type:customer-profile",
@@ -9478,7 +9636,7 @@ var githubWorkflowBundle = {
9478
9636
  };
9479
9637
 
9480
9638
  // src/agent/bundles/industry-discovery.ts
9481
- function buildIndustryDiscoveryAnalystSubAgent(paths) {
9639
+ function buildIndustryDiscoveryAnalystSubAgent(paths, issueDefaults) {
9482
9640
  return {
9483
9641
  name: "industry-discovery-analyst",
9484
9642
  description: "Discovers candidate industry verticals, scores each against a configurable capability/fit rubric, and creates planning issues for verticals that clear the threshold. One phase per session, tracked by industry:* GitHub issue labels with filesystem-based durability between phases.",
@@ -9816,8 +9974,8 @@ function buildIndustryDiscoveryAnalystSubAgent(paths) {
9816
9974
  "4. **Create one `research:scope` issue per cleared vertical.** This",
9817
9975
  " assumes the `research-pipeline` bundle is enabled in the consuming",
9818
9976
  " project. Each downstream issue should:",
9819
- " - Carry `type:research`, `research:scope`, `priority:medium`, and",
9820
- " `status:ready` labels",
9977
+ ` - Carry \`type:research\`, \`research:scope\`, \`priority:${labelsForPhase(issueDefaults, "research:scope").priority}\`, and`,
9978
+ ` \`status:${labelsForPhase(issueDefaults, "research:scope").status}\` labels`,
9821
9979
  " - Include the research question framed for the vertical (what the",
9822
9980
  " downstream research needs to answer)",
9823
9981
  " - Cite the evaluation row that justified advancing the vertical",
@@ -9868,7 +10026,7 @@ function buildIndustryDiscoveryAnalystSubAgent(paths) {
9868
10026
  ].join("\n")
9869
10027
  };
9870
10028
  }
9871
- function buildDiscoverIndustriesSkill(paths) {
10029
+ function buildDiscoverIndustriesSkill(paths, issueDefaults) {
9872
10030
  return {
9873
10031
  name: "discover-industries",
9874
10032
  description: "Kick off an industry-discovery pipeline. Creates an industry:discover issue carrying the discovery scope and dispatches Phase 1 (Discover) in the industry-discovery-analyst agent.",
@@ -9910,7 +10068,7 @@ function buildDiscoverIndustriesSkill(paths) {
9910
10068
  "## Steps",
9911
10069
  "",
9912
10070
  "1. Create an `industry:discover` issue with `type:industry-discovery`,",
9913
- " `priority:medium`, and `status:ready`. Body must include the",
10071
+ ` \`priority:${labelsForPhase(issueDefaults, "industry:discover").priority}\`, and \`status:${labelsForPhase(issueDefaults, "industry:discover").status}\`. Body must include the`,
9914
10072
  " verbatim scope, authorized sources, and any overrides.",
9915
10073
  "2. Execute Phase 1 (Discover) of the industry-discovery-analyst",
9916
10074
  " agent.",
@@ -9931,7 +10089,7 @@ function buildDiscoverIndustriesSkill(paths) {
9931
10089
  ].join("\n")
9932
10090
  };
9933
10091
  }
9934
- function buildIndustryDiscoveryBundle(paths = DEFAULT_AGENT_PATHS) {
10092
+ function buildIndustryDiscoveryBundle(paths = DEFAULT_AGENT_PATHS, issueDefaults = DEFAULT_RESOLVED_ISSUE_DEFAULTS) {
9935
10093
  return {
9936
10094
  name: "industry-discovery",
9937
10095
  description: "Industry-vertical discovery pipeline: discover candidates, evaluate against a fit rubric, plan downstream research. Enabled by default; domain-neutral; filesystem-durable between phases.",
@@ -9965,8 +10123,8 @@ function buildIndustryDiscoveryBundle(paths = DEFAULT_AGENT_PATHS) {
9965
10123
  tags: ["workflow"]
9966
10124
  }
9967
10125
  ],
9968
- skills: [buildDiscoverIndustriesSkill(paths)],
9969
- subAgents: [buildIndustryDiscoveryAnalystSubAgent(paths)],
10126
+ skills: [buildDiscoverIndustriesSkill(paths, issueDefaults)],
10127
+ subAgents: [buildIndustryDiscoveryAnalystSubAgent(paths, issueDefaults)],
9970
10128
  labels: [
9971
10129
  {
9972
10130
  name: "type:industry-discovery",
@@ -10578,7 +10736,7 @@ function buildMaintenanceAuditSubAgent(paths) {
10578
10736
  ].join("\n")
10579
10737
  };
10580
10738
  }
10581
- function buildMaintenanceAuditSkill(paths) {
10739
+ function buildMaintenanceAuditSkill(paths, issueDefaults) {
10582
10740
  return {
10583
10741
  name: "audit-docs",
10584
10742
  description: "Kick off a documentation-maintenance audit cycle (scan \u2192 fix \u2192 verify). Creates a maint:scan issue for the supplied scope and dispatches Phase 1.",
@@ -10613,7 +10771,7 @@ function buildMaintenanceAuditSkill(paths) {
10613
10771
  "## Steps",
10614
10772
  "",
10615
10773
  "1. Create a `maint:scan` issue with `type:maintenance`,",
10616
- " `priority:medium`, and `status:ready`. Body must list:",
10774
+ ` \`priority:${labelsForPhase(issueDefaults, "maint:scan").priority}\`, and \`status:${labelsForPhase(issueDefaults, "maint:scan").status}\`. Body must list:`,
10617
10775
  " - `<DOCS_ROOT>` \u2014 the doc tree to audit",
10618
10776
  " - `<AUDIT_ROOT>` \u2014 where to write the audit report",
10619
10777
  " - `<AUDIT_SLUG>` \u2014 short identifier for this audit",
@@ -10635,7 +10793,7 @@ function buildMaintenanceAuditSkill(paths) {
10635
10793
  ].join("\n")
10636
10794
  };
10637
10795
  }
10638
- function buildMaintenanceVerifySkill() {
10796
+ function buildMaintenanceVerifySkill(issueDefaults) {
10639
10797
  return {
10640
10798
  name: "verify-audit",
10641
10799
  description: "Kick off the verify phase of a documentation-maintenance audit cycle. Creates a maint:verify issue that re-runs the scan checks scoped to the paths a fix phase touched, compares pre/post findings, and closes the parent maint:scan issue when clean or files a follow-up maint:scan for residual findings.",
@@ -10676,7 +10834,7 @@ function buildMaintenanceVerifySkill() {
10676
10834
  "## Steps",
10677
10835
  "",
10678
10836
  "1. Create a `maint:verify` issue with `type:maintenance`,",
10679
- " `priority:medium`, and `status:ready`. Body must list:",
10837
+ ` \`priority:${labelsForPhase(issueDefaults, "maint:verify").priority}\`, and \`status:${labelsForPhase(issueDefaults, "maint:verify").status}\`. Body must list:`,
10680
10838
  " - The parent `maint:scan` issue number",
10681
10839
  " - The Phase 1 audit report path",
10682
10840
  " - The Phase 2 fix report path (if one exists)",
@@ -10693,7 +10851,7 @@ function buildMaintenanceVerifySkill() {
10693
10851
  ].join("\n")
10694
10852
  };
10695
10853
  }
10696
- function buildMaintenanceAuditBundle(paths = DEFAULT_AGENT_PATHS) {
10854
+ function buildMaintenanceAuditBundle(paths = DEFAULT_AGENT_PATHS, issueDefaults = DEFAULT_RESOLVED_ISSUE_DEFAULTS) {
10697
10855
  return {
10698
10856
  name: "maintenance-audit",
10699
10857
  description: "Documentation-maintenance agent bundle. 3-phase pipeline (scan, fix, verify) with maint:* phase labels for auditing registries and cross-references, applying idempotent fixes, and confirming the fixes cleared the originally-flagged findings. Enabled by default.",
@@ -10736,7 +10894,10 @@ function buildMaintenanceAuditBundle(paths = DEFAULT_AGENT_PATHS) {
10736
10894
  tags: ["workflow"]
10737
10895
  }
10738
10896
  ],
10739
- skills: [buildMaintenanceAuditSkill(paths), buildMaintenanceVerifySkill()],
10897
+ skills: [
10898
+ buildMaintenanceAuditSkill(paths, issueDefaults),
10899
+ buildMaintenanceVerifySkill(issueDefaults)
10900
+ ],
10740
10901
  subAgents: [buildMaintenanceAuditSubAgent(paths)],
10741
10902
  labels: [
10742
10903
  {
@@ -13145,80 +13306,81 @@ function buildCheckBlockedScript(tiers, scopeGate, runRatio) {
13145
13306
  "}",
13146
13307
  "",
13147
13308
  "cmd_eligible() {",
13148
- " local issues",
13149
- ' issues=$(gh issue list --label "status:ready" --state open \\',
13150
- ' --search "sort:created-asc" \\',
13151
- ' --json number,title,body,labels --limit 50 2>/dev/null || echo "[]")',
13152
- "",
13153
- " local count",
13154
- ` count=$(echo "$issues" | jq 'length')`,
13155
- ' if [[ "$count" -eq 0 ]]; then',
13156
- ' echo "NO_READY_ISSUES"',
13157
- " return 0",
13158
- " fi",
13309
+ " # Bucketed scan: walk priority levels critical \u2192 high \u2192 medium \u2192 low \u2192",
13310
+ " # trivial, fetching one bucket at a time. The first bucket with at",
13311
+ " # least one survivor (after the Depends-on filter) short-circuits the",
13312
+ " # loop \u2014 lower-priority buckets are never queried in the common case.",
13313
+ " # This guarantees that every higher-priority issue is visible even",
13314
+ " # when the global ready backlog exceeds 50, at the cost of up to one",
13315
+ " # extra `gh issue list` call per empty bucket above the first hit.",
13316
+ " local level",
13317
+ " for level in critical high medium low trivial; do",
13318
+ " local issues",
13319
+ ' issues=$(gh issue list --label "status:ready" --label "priority:${level}" --state open \\',
13320
+ ' --search "sort:created-asc" \\',
13321
+ ' --json number,title,body,labels --limit 50 2>/dev/null || echo "[]")',
13322
+ "",
13323
+ " local count",
13324
+ ` count=$(echo "$issues" | jq 'length')`,
13325
+ ' if [[ "$count" -eq 0 ]]; then',
13326
+ " continue",
13327
+ " fi",
13159
13328
  "",
13160
- " local issue_data",
13161
- ` issue_data=$(echo "$issues" | jq -r '`,
13162
- " .[] |",
13163
- ' (.body | split("\\n") | map(select(test("Depends on:"; "i"))) | .[0] // "") as $dep_line |',
13164
- ' (.labels | map(.name) | join(",")) as $label_str |',
13165
- ' (.labels | map(.name) | map(select(startswith("type:"))) | .[0] // "") as $type_label |',
13166
- ' "\\(.number)\\t\\(.title)\\t\\($dep_line)\\t\\($label_str)\\t\\($type_label)"',
13167
- " ')",
13329
+ " local issue_data",
13330
+ ` issue_data=$(echo "$issues" | jq -r '`,
13331
+ " .[] |",
13332
+ ' (.body | split("\\n") | map(select(test("Depends on:"; "i"))) | .[0] // "") as $dep_line |',
13333
+ ' (.labels | map(.name) | map(select(startswith("type:"))) | .[0] // "") as $type_label |',
13334
+ ' "\\(.number)\\t\\(.title)\\t\\($dep_line)\\t\\($type_label)"',
13335
+ " ')",
13168
13336
  "",
13169
- ' local results=""',
13170
- " while IFS=$'\\t' read -r num title dep_line labels_str type_label; do",
13171
- ' [[ -z "$num" ]] && continue',
13337
+ ' local results=""',
13338
+ " while IFS=$'\\t' read -r num title dep_line type_label; do",
13339
+ ' [[ -z "$num" ]] && continue',
13172
13340
  "",
13173
- ' local deps=""',
13174
- ' if [[ -n "$dep_line" ]]; then',
13175
- ' deps=$(parse_deps "$dep_line")',
13176
- " fi",
13341
+ ' local deps=""',
13342
+ ' if [[ -n "$dep_line" ]]; then',
13343
+ ' deps=$(parse_deps "$dep_line")',
13344
+ " fi",
13177
13345
  "",
13178
- " # Check if any dep is still open.",
13179
- " local has_open_dep=false",
13180
- ' local open_deps=""',
13181
- ' if [[ -n "${deps// /}" ]]; then',
13182
- " for dep in $deps; do",
13183
- ' if ! is_closed "$dep"; then',
13184
- " has_open_dep=true",
13185
- ' open_deps="${open_deps}#${dep} "',
13186
- " fi",
13187
- " done",
13188
- " fi",
13346
+ " # Check if any dep is still open.",
13347
+ " local has_open_dep=false",
13348
+ ' local open_deps=""',
13349
+ ' if [[ -n "${deps// /}" ]]; then',
13350
+ " for dep in $deps; do",
13351
+ ' if ! is_closed "$dep"; then',
13352
+ " has_open_dep=true",
13353
+ ' open_deps="${open_deps}#${dep} "',
13354
+ " fi",
13355
+ " done",
13356
+ " fi",
13189
13357
  "",
13190
- " if $has_open_dep; then",
13191
- ' echo "SKIP #${num} \u2014 dep ${open_deps% } still open"',
13192
- " continue",
13193
- " fi",
13358
+ " if $has_open_dep; then",
13359
+ ' echo "SKIP #${num} \u2014 dep ${open_deps% } still open"',
13360
+ " continue",
13361
+ " fi",
13194
13362
  "",
13195
- " # 5-level priority sort key.",
13196
- " local priority_key=2",
13197
- ' local priority="medium"',
13198
- ' case "$labels_str" in',
13199
- ' *priority:critical*) priority_key=0; priority="critical" ;;',
13200
- ' *priority:high*) priority_key=1; priority="high" ;;',
13201
- ' *priority:medium*) priority_key=2; priority="medium" ;;',
13202
- ' *priority:low*) priority_key=3; priority="low" ;;',
13203
- ' *priority:trivial*) priority_key=4; priority="trivial" ;;',
13204
- " esac",
13363
+ " # Funnel-tier sort key (0-4; 0 dispatches first within a bucket).",
13364
+ ' local type_value="${type_label#type:}"',
13365
+ " local tier_key",
13366
+ ' tier_key=$(tier_of "$type_value")',
13205
13367
  "",
13206
- " # Funnel-tier sort key (0-4; 0 dispatches first on priority tie).",
13207
- ' local type_value="${type_label#type:}"',
13208
- " local tier_key",
13209
- ' tier_key=$(tier_of "$type_value")',
13368
+ ' local label_info=""',
13369
+ ' [[ -n "$type_label" ]] && label_info=" ${type_label}"',
13210
13370
  "",
13211
- ' local label_info=""',
13212
- ' [[ -n "$type_label" ]] && label_info=" ${type_label}"',
13371
+ ' results="${results}${tier_key}\\t${num}\\tPICK #${num} priority:${level} tier:${tier_key}${label_info} \\"${title}\\"\\n"',
13372
+ ' done <<< "$issue_data"',
13213
13373
  "",
13214
- ' results="${results}${priority_key}\\t${tier_key}\\t${num}\\tPICK #${num} priority:${priority} tier:${tier_key}${label_info} \\"${title}\\"\\n"',
13215
- ' done <<< "$issue_data"',
13374
+ " # Within this bucket: sort by funnel tier asc \u2192 issue number asc",
13375
+ " # (FIFO). If any PICK lines survived the Depends-on filter, emit",
13376
+ " # them and short-circuit before querying lower-priority buckets.",
13377
+ ' if [[ -n "$results" ]]; then',
13378
+ ` printf '%b' "$results" | sort -t$'\\t' -k1,1n -k2,2n | cut -f3`,
13379
+ " return 0",
13380
+ " fi",
13381
+ " done",
13216
13382
  "",
13217
- " # Sort by priority (asc, lower priority_key wins), then funnel tier",
13218
- " # (asc, lower tier wins on priority tie), then issue number (FIFO).",
13219
- ' if [[ -n "$results" ]]; then',
13220
- ` printf '%b' "$results" | sort -t$'\\t' -k1,1n -k2,2n -k3,3n | cut -f4`,
13221
- " fi",
13383
+ ' echo "NO_READY_ISSUES"',
13222
13384
  "}",
13223
13385
  "",
13224
13386
  "cmd_stale() {",
@@ -13653,9 +13815,25 @@ var orchestratorSubAgent = {
13653
13815
  ".claude/procedures/check-blocked.sh eligible",
13654
13816
  "```",
13655
13817
  "",
13818
+ "The script walks the priority buckets **critical \u2192 high \u2192 medium \u2192 low",
13819
+ "\u2192 trivial** in order, querying one bucket at a time and short-circuiting",
13820
+ "on the first non-empty bucket whose survivors clear the `Depends on:`",
13821
+ "filter. Each bucket is fetched with",
13822
+ '`gh issue list --label "status:ready" --label "priority:<level>" --limit 50`,',
13823
+ "so every higher-priority issue is visible even when the global ready",
13824
+ "backlog exceeds 50 \u2014 a `priority:critical` filing can never be hidden",
13825
+ "behind 50 older medium/low issues. The cost in the common case (the",
13826
+ "first bucket the script queries is non-empty) is **one `gh issue list`",
13827
+ "call**, identical to the previous single-fetch implementation; the",
13828
+ "worst case is five calls when every higher-priority bucket is empty",
13829
+ "or fully dep-blocked. Per-priority bucket size is still capped at 50",
13830
+ "issues \u2014 see the **Orchestrator Conventions** section in `CLAUDE.md`.",
13831
+ "",
13656
13832
  "The script emits `PICK` lines sorted by **priority desc \u2192 funnel tier asc",
13657
- "\u2192 issue number asc**. Each line carries both `priority:<level>` and",
13658
- "`tier:<n>` so the sort is legible at a glance:",
13833
+ "\u2192 issue number asc** (priority order is enforced by the bucket walk;",
13834
+ "the in-bucket sort handles funnel tier and FIFO). Each line carries",
13835
+ "both `priority:<level>` and `tier:<n>` so the sort is legible at a",
13836
+ "glance:",
13659
13837
  "",
13660
13838
  "```",
13661
13839
  'PICK #42 priority:high tier:1 type:research "FHIR extension analysis"',
@@ -14286,7 +14464,7 @@ var ORCHESTRATOR_CONVENTIONS_PREAMBLE = [
14286
14464
  "- The orchestrator **never** implements code, creates branches, pushes commits, **or merges PRs** \u2014 it triages issues, picks the next work item, and delegates implementation to other sub-agents. Approved-PR merging is owned by the `pr-reviewer` sub-agent (invoked via `/review-pr` / `/review-prs`).",
14287
14465
  "- All triage queries use `.claude/procedures/check-blocked.sh` for token efficiency",
14288
14466
  "- 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.",
14289
- "- Priority order: critical > high > medium > low > trivial, then **funnel tier asc** (lower tier wins ties), then FIFO by issue number",
14467
+ "- Priority order: critical > high > medium > low > trivial, then **funnel tier asc** (lower tier wins ties), then FIFO by issue number. Phase E's queue scan walks each priority bucket in turn (one `gh issue list` call per bucket, **capped at 50 issues per bucket**) and short-circuits on the first bucket whose survivors clear the `Depends on:` filter, so every higher-priority issue is visible even when the global ready backlog is much larger than 50.",
14290
14468
  "- Stale thresholds: 72h for in-progress, 168h for blocked",
14291
14469
  "- Flagged issues get `status:needs-attention` \u2014 they are not auto-reset",
14292
14470
  "",
@@ -14373,7 +14551,7 @@ var orchestratorBundle = {
14373
14551
  };
14374
14552
 
14375
14553
  // src/agent/bundles/people-profile.ts
14376
- function buildPeopleProfileAnalystSubAgent(paths) {
14554
+ function buildPeopleProfileAnalystSubAgent(paths, issueDefaults) {
14377
14555
  return {
14378
14556
  name: "people-profile-analyst",
14379
14557
  description: "Researches an individual person (colleague, customer contact, vendor contact, partner contact, industry expert, or connector) from public sources and produces a structured markdown profile cross-linked to companies, software, and meeting notes, then enqueues downstream `company:research` and `software:research` issues for unprofiled companies and software products surfaced during profiling. Also handles maintenance refreshes on a configurable staleness cadence (`people:refresh`). One person per session, tracked by people:* GitHub issue labels.",
@@ -14810,8 +14988,8 @@ function buildPeopleProfileAnalystSubAgent(paths) {
14810
14988
  "",
14811
14989
  " - `type:company-profile`",
14812
14990
  " - `company:research`",
14813
- " - `priority:medium`",
14814
- " - `status:ready`",
14991
+ ` - \`priority:${labelsForPhase(issueDefaults, "company:research").priority}\``,
14992
+ ` - \`status:${labelsForPhase(issueDefaults, "company:research").status}\``,
14815
14993
  "",
14816
14994
  " The issue body must include:",
14817
14995
  " - A **discovery source** line naming this person profile",
@@ -14830,8 +15008,8 @@ function buildPeopleProfileAnalystSubAgent(paths) {
14830
15008
  "",
14831
15009
  " - `type:software-profile`",
14832
15010
  " - `software:research`",
14833
- " - `priority:medium`",
14834
- " - `status:ready`",
15011
+ ` - \`priority:${labelsForPhase(issueDefaults, "software:research").priority}\``,
15012
+ ` - \`status:${labelsForPhase(issueDefaults, "software:research").status}\``,
14835
15013
  "",
14836
15014
  " The issue body must include:",
14837
15015
  " - A **discovery source** line naming this person profile",
@@ -15050,7 +15228,7 @@ function buildPeopleProfileAnalystSubAgent(paths) {
15050
15228
  ].join("\n")
15051
15229
  };
15052
15230
  }
15053
- function buildProfilePersonSkill(paths) {
15231
+ function buildProfilePersonSkill(paths, issueDefaults) {
15054
15232
  return {
15055
15233
  name: "profile-person",
15056
15234
  description: "Kick off a people-profile pipeline. Creates a people:research issue for the given person and dispatches Phase 1 (Research) in the people-profile-analyst agent. Phase 3 (Followup) enqueues downstream `company:research` and `software:research` issues for unprofiled, genuinely-relevant entities surfaced in the profile.",
@@ -15101,7 +15279,7 @@ function buildProfilePersonSkill(paths) {
15101
15279
  "## Steps",
15102
15280
  "",
15103
15281
  "1. Create a `people:research` issue with `type:people-profile`,",
15104
- " `priority:medium`, and `status:ready`. Body must include the",
15282
+ ` \`priority:${labelsForPhase(issueDefaults, "people:research").priority}\`, and \`status:${labelsForPhase(issueDefaults, "people:research").status}\`. Body must include the`,
15105
15283
  " person's name, selected role, primary company, framing, and any",
15106
15284
  " overrides.",
15107
15285
  "2. Execute Phase 1 (Research) of the people-profile-analyst agent.",
@@ -15126,7 +15304,7 @@ function buildProfilePersonSkill(paths) {
15126
15304
  ].join("\n")
15127
15305
  };
15128
15306
  }
15129
- function buildRefreshPersonSkill(paths) {
15307
+ function buildRefreshPersonSkill(paths, issueDefaults) {
15130
15308
  return {
15131
15309
  name: "refresh-person",
15132
15310
  description: "Kick off a people-profile refresh cycle. Creates a people:refresh issue for an existing profile and dispatches Phase 4 (Refresh) in the people-profile-analyst agent. Refresh re-verifies the profile's narrow delta set (role, employer, primary public channel) with 3\u20135 targeted web searches and updates it in place. Respects a configurable staleness threshold so profiles younger than the threshold exit early.",
@@ -15193,7 +15371,7 @@ function buildRefreshPersonSkill(paths) {
15193
15371
  "## Steps",
15194
15372
  "",
15195
15373
  "1. Create a `people:refresh` issue with `type:people-profile`,",
15196
- " `priority:medium`, and `status:ready`. Body must include the",
15374
+ ` \`priority:${labelsForPhase(issueDefaults, "people:refresh").priority}\`, and \`status:${labelsForPhase(issueDefaults, "people:refresh").status}\`. Body must include the`,
15197
15375
  " profile path and any overrides.",
15198
15376
  "2. Execute Phase 4 (Refresh) of the people-profile-analyst agent.",
15199
15377
  "",
@@ -15207,7 +15385,7 @@ function buildRefreshPersonSkill(paths) {
15207
15385
  ].join("\n")
15208
15386
  };
15209
15387
  }
15210
- function buildPeopleProfileBundle(paths = DEFAULT_AGENT_PATHS) {
15388
+ function buildPeopleProfileBundle(paths = DEFAULT_AGENT_PATHS, issueDefaults = DEFAULT_RESOLVED_ISSUE_DEFAULTS) {
15211
15389
  return {
15212
15390
  name: "people-profile",
15213
15391
  description: "People research and profiling pipeline: research, draft profile, followup, refresh. Enabled by default; domain-neutral; filesystem-durable between phases. Cross-references existing companies, software, and meeting notes, and Phase 3 (Followup) hands unprofiled, genuinely-relevant companies and software products off to the `company-profile` and `software-profile` bundles via `company:research` and `software:research` issues. Phase 4 (Refresh) re-verifies profiles on a configurable staleness cadence.",
@@ -15251,8 +15429,11 @@ function buildPeopleProfileBundle(paths = DEFAULT_AGENT_PATHS) {
15251
15429
  tags: ["workflow"]
15252
15430
  }
15253
15431
  ],
15254
- skills: [buildProfilePersonSkill(paths), buildRefreshPersonSkill(paths)],
15255
- subAgents: [buildPeopleProfileAnalystSubAgent(paths)],
15432
+ skills: [
15433
+ buildProfilePersonSkill(paths, issueDefaults),
15434
+ buildRefreshPersonSkill(paths, issueDefaults)
15435
+ ],
15436
+ subAgents: [buildPeopleProfileAnalystSubAgent(paths, issueDefaults)],
15256
15437
  labels: [
15257
15438
  {
15258
15439
  name: "type:people-profile",
@@ -17417,7 +17598,7 @@ var REGULATORY_RESEARCH_REFERENCE_FILES = [
17417
17598
  content: TEMPLATE_REGULATION
17418
17599
  }
17419
17600
  ];
17420
- function buildRegulatoryResearchAnalystSubAgent(paths) {
17601
+ function buildRegulatoryResearchAnalystSubAgent(paths, issueDefaults) {
17421
17602
  return {
17422
17603
  name: "regulatory-research-analyst",
17423
17604
  description: "Authors jurisdictional compliance research through a 3-phase pipeline (scan \u2192 research \u2192 impact). Enumerates applicable regulations by jurisdiction and business activity, researches each in depth, and produces an impact analysis that hands off actionable obligations to the requirements-analyst as req:scan seeds in the SEC category. One phase per session, tracked by regulatory:* GitHub issue labels with filesystem-based durability between phases.",
@@ -17772,6 +17953,12 @@ function buildRegulatoryResearchAnalystSubAgent(paths) {
17772
17953
  " regulator agencies that do not already have a canonical profile",
17773
17954
  " or an open `company:research` issue. The `company-profile`",
17774
17955
  " bundle owns the downstream profile; this agent only hands off.",
17956
+ " Each issue must carry:",
17957
+ "",
17958
+ " - `type:company-profile`",
17959
+ " - `company:research`",
17960
+ ` - \`priority:${labelsForPhase(issueDefaults, "company:research").priority}\``,
17961
+ ` - \`status:${labelsForPhase(issueDefaults, "company:research").status}\``,
17775
17962
  "",
17776
17963
  "9. **Verify all handoffs were created** before committing.",
17777
17964
  "",
@@ -17840,25 +18027,42 @@ function buildRegulatoryResearchAnalystSubAgent(paths) {
17840
18027
  "4. **Create `req:scan` issues** for each capability gap identified.",
17841
18028
  " Each issue hands off to the `requirements-analyst` bundle so its",
17842
18029
  " scan phase can deduplicate and open `req:write` issues in the",
17843
- " SEC category. The issue body must:",
17844
- " - Carry `type:requirement` and `req:scan` labels",
18030
+ " SEC category. Each issue must carry:",
18031
+ "",
18032
+ " - `type:requirement`",
18033
+ " - `req:scan`",
18034
+ ` - \`priority:${labelsForPhase(issueDefaults, "req:scan").priority}\``,
18035
+ ` - \`status:${labelsForPhase(issueDefaults, "req:scan").status}\``,
18036
+ "",
18037
+ " The body must also:",
17845
18038
  " - Identify the target category as **SEC** (security & compliance)",
17846
18039
  " in the body so the downstream writer phase picks up the right",
17847
18040
  " template",
17848
18041
  " - Link back to the regulation page and cite the triggering",
17849
18042
  " requirement",
17850
- " - Inherit priority from the impact issue (escalate if the",
17851
- " regulation is already in force and the gap is unmitigated)",
18043
+ " - Escalate the priority above the bundle default when the",
18044
+ " regulation is already in force and the gap is unmitigated",
17852
18045
  "",
17853
18046
  "5. **Create `company:research` issues** for any enforcement body",
17854
18047
  " mentioned on the regulation page that does not already have a",
17855
- " canonical profile or an open `company:research` issue.",
18048
+ " canonical profile or an open `company:research` issue. Each",
18049
+ " issue must carry:",
18050
+ "",
18051
+ " - `type:company-profile`",
18052
+ " - `company:research`",
18053
+ ` - \`priority:${labelsForPhase(issueDefaults, "company:research").priority}\``,
18054
+ ` - \`status:${labelsForPhase(issueDefaults, "company:research").status}\``,
17856
18055
  "",
17857
18056
  "6. **Create `people:research` issues** for notable regulatory",
17858
18057
  " leaders (commissioners, agency directors, lead policy authors)",
17859
18058
  " mentioned on the regulation page. Keep this list small \u2014 at most",
17860
18059
  " three individuals per impact session \u2014 and skip anyone already",
17861
- " profiled or queued.",
18060
+ " profiled or queued. Each issue must carry:",
18061
+ "",
18062
+ " - `type:people-profile`",
18063
+ " - `people:research`",
18064
+ ` - \`priority:${labelsForPhase(issueDefaults, "people:research").priority}\``,
18065
+ ` - \`status:${labelsForPhase(issueDefaults, "people:research").status}\``,
17862
18066
  "",
17863
18067
  "7. **Commit and push** the updated regulation page. Close the",
17864
18068
  " impact issue.",
@@ -17977,7 +18181,7 @@ function buildRegulatoryResearchAnalystSubAgent(paths) {
17977
18181
  ].join("\n")
17978
18182
  };
17979
18183
  }
17980
- function buildScanRegulatoryLandscapeSkill(paths) {
18184
+ function buildScanRegulatoryLandscapeSkill(paths, issueDefaults) {
17981
18185
  return {
17982
18186
  name: "scan-regulatory-landscape",
17983
18187
  description: "Kick off the scan phase of a regulatory-research campaign. Creates a regulatory:scan issue for the supplied scope (industry, jurisdiction, or platform) and dispatches Phase 1 of the regulatory-research-analyst, which writes a scan report and creates downstream regulatory:research issues.",
@@ -18024,7 +18228,7 @@ function buildScanRegulatoryLandscapeSkill(paths) {
18024
18228
  "## Steps",
18025
18229
  "",
18026
18230
  "1. Create a `regulatory:scan` issue with `type:regulatory-research`,",
18027
- " `priority:medium`, and `status:ready`. The body must include the",
18231
+ ` \`priority:${labelsForPhase(issueDefaults, "regulatory:scan").priority}\`, and \`status:${labelsForPhase(issueDefaults, "regulatory:scan").status}\`. The body must include the`,
18028
18232
  " scope slug, the scope type, and any known regulations to include",
18029
18233
  " or exclude.",
18030
18234
  "2. Execute Phase 1 (Scan) of the regulatory-research-analyst agent.",
@@ -18041,7 +18245,7 @@ function buildScanRegulatoryLandscapeSkill(paths) {
18041
18245
  ].join("\n")
18042
18246
  };
18043
18247
  }
18044
- function buildResearchRegulationSkill(paths) {
18248
+ function buildResearchRegulationSkill(paths, issueDefaults) {
18045
18249
  return {
18046
18250
  name: "research-regulation",
18047
18251
  description: "Kick off the research phase for one regulation. Creates a regulatory:research issue for the supplied scope and regulation and dispatches Phase 2 of the regulatory-research-analyst, which populates the regulation page with scope, triggers, key requirements, jurisdiction variations, enforcement, and penalties using the ship-with regulation-page template.",
@@ -18100,8 +18304,8 @@ function buildResearchRegulationSkill(paths) {
18100
18304
  "## Steps",
18101
18305
  "",
18102
18306
  "1. Create a `regulatory:research` issue with",
18103
- " `type:regulatory-research`, `priority:medium`, and",
18104
- " `status:ready`. The body must include the scope slug and the",
18307
+ ` \`type:regulatory-research\`, \`priority:${labelsForPhase(issueDefaults, "regulatory:research").priority}\`, and`,
18308
+ ` \`status:${labelsForPhase(issueDefaults, "regulatory:research").status}\`. The body must include the scope slug and the`,
18105
18309
  " regulation slug.",
18106
18310
  "2. Execute Phase 2 (Research) of the regulatory-research-analyst",
18107
18311
  " agent. The agent runs 6\u201312 targeted web searches and populates",
@@ -18119,7 +18323,7 @@ function buildResearchRegulationSkill(paths) {
18119
18323
  ].join("\n")
18120
18324
  };
18121
18325
  }
18122
- function buildImpactRegulationSkill(paths) {
18326
+ function buildImpactRegulationSkill(paths, issueDefaults) {
18123
18327
  return {
18124
18328
  name: "impact-regulation",
18125
18329
  description: "Kick off the impact phase for one regulation. Creates a regulatory:impact issue for the supplied regulation and dispatches Phase 3 of the regulatory-research-analyst, which assesses product impact, documents capability gaps, and hands off each actionable obligation as a req:scan seed in the SEC (security & compliance) category for the requirements-analyst bundle to consume.",
@@ -18166,8 +18370,8 @@ function buildImpactRegulationSkill(paths) {
18166
18370
  "## Steps",
18167
18371
  "",
18168
18372
  "1. Create a `regulatory:impact` issue with",
18169
- " `type:regulatory-research`, `priority:medium`, and",
18170
- " `status:ready` (or `status:blocked` when still dependent on a",
18373
+ ` \`type:regulatory-research\`, \`priority:${labelsForPhase(issueDefaults, "regulatory:impact").priority}\`, and`,
18374
+ ` \`status:${labelsForPhase(issueDefaults, "regulatory:impact").status}\` (or \`status:blocked\` when still dependent on a`,
18171
18375
  " Phase 2 research issue). Body must include the regulation page",
18172
18376
  " path.",
18173
18377
  "2. Execute Phase 3 (Impact) of the regulatory-research-analyst",
@@ -18188,7 +18392,7 @@ function buildImpactRegulationSkill(paths) {
18188
18392
  ].join("\n")
18189
18393
  };
18190
18394
  }
18191
- function buildRegulatoryResearchBundle(paths = DEFAULT_AGENT_PATHS) {
18395
+ function buildRegulatoryResearchBundle(paths = DEFAULT_AGENT_PATHS, issueDefaults = DEFAULT_RESOLVED_ISSUE_DEFAULTS) {
18192
18396
  return {
18193
18397
  name: "regulatory-research",
18194
18398
  description: "Regulatory compliance research pipeline: scan, research, impact. 3 phases with regulatory:* phase labels. Enumerates jurisdictional regulations by industry and activity, researches each in depth with specific section citations, and hands off actionable obligations to the requirements-analyst bundle as req:scan seeds that become SEC (security & compliance) requirements. Enabled by default; domain-neutral; documents obligations without interpreting them; filesystem-durable between phases.",
@@ -18255,11 +18459,11 @@ function buildRegulatoryResearchBundle(paths = DEFAULT_AGENT_PATHS) {
18255
18459
  }
18256
18460
  ],
18257
18461
  skills: [
18258
- buildScanRegulatoryLandscapeSkill(paths),
18259
- buildResearchRegulationSkill(paths),
18260
- buildImpactRegulationSkill(paths)
18462
+ buildScanRegulatoryLandscapeSkill(paths, issueDefaults),
18463
+ buildResearchRegulationSkill(paths, issueDefaults),
18464
+ buildImpactRegulationSkill(paths, issueDefaults)
18261
18465
  ],
18262
- subAgents: [buildRegulatoryResearchAnalystSubAgent(paths)],
18466
+ subAgents: [buildRegulatoryResearchAnalystSubAgent(paths, issueDefaults)],
18263
18467
  labels: [
18264
18468
  {
18265
18469
  name: "type:regulatory-research",
@@ -18387,7 +18591,7 @@ var REQ_WRITE_ISSUE_SCHEMA_SECTION = [
18387
18591
  ];
18388
18592
 
18389
18593
  // src/agent/bundles/requirements-analyst.ts
18390
- function buildRequirementsAnalystSubAgent(paths) {
18594
+ function buildRequirementsAnalystSubAgent(paths, issueDefaults) {
18391
18595
  return {
18392
18596
  name: "requirements-analyst",
18393
18597
  description: "Discovers requirement gaps from BCM model docs, competitive analysis, product docs, and meeting extracts. Produces scan reports, proposals, and req:write issues for the downstream requirements-writer agent. Runs through a 2-phase pipeline (scan \u2192 draft-trace), one phase per session, tracked by req:* GitHub issue labels.",
@@ -18705,14 +18909,14 @@ function buildRequirementsAnalystSubAgent(paths) {
18705
18909
  " `## Template: req:write` of",
18706
18910
  " `docs/src/content/docs/agents/issue-templates.md`.",
18707
18911
  "",
18708
- " All `type:requirement` issues default to `priority:medium` (override",
18912
+ ` All \`type:requirement\` issues default to \`priority:${labelsForPhase(issueDefaults, "req:write").priority}\` (override`,
18709
18913
  " only if the proposal's priority was explicitly High or Low). Each",
18710
18914
  " issue must also carry the `req:write` phase label plus the matching",
18711
18915
  " `tier:*` label so the downstream `requirements-writer` bundle picks",
18712
18916
  " it up with the correct tier. Concretely, the label list includes",
18713
18917
  ' `--label "type:requirement"`, `--label "req:write"`,',
18714
- ' `--label "tier:<tier-slug>"`, `--label "status:ready"`, and',
18715
- ' `--label "priority:medium"`.',
18918
+ ` \`--label "tier:<tier-slug>"\`, \`--label "status:${labelsForPhase(issueDefaults, "req:write").status}"\`, and`,
18919
+ ` \`--label "priority:${labelsForPhase(issueDefaults, "req:write").priority}"\`.`,
18716
18920
  "",
18717
18921
  " The body must carry the three writer-required fields in an",
18718
18922
  " `## Objective` block, written as bold-prefixed lines so the",
@@ -18729,7 +18933,7 @@ function buildRequirementsAnalystSubAgent(paths) {
18729
18933
  "",
18730
18934
  " When one of Category / Tier / Output Path could not be derived",
18731
18935
  " from the proposal (for example, the proposal omitted the Tier",
18732
- " line), replace `status:ready` with `status:needs-attention` in",
18936
+ ` line), replace \`status:${labelsForPhase(issueDefaults, "req:write").status}\` with \`status:needs-attention\` in`,
18733
18937
  " the label list and add a `Missing: <field> \u2014 <reason>` line",
18734
18938
  " directly below the Output Path line in the body. Populate",
18735
18939
  " whichever of the three fields **could** be derived so a human",
@@ -18795,48 +18999,50 @@ function buildRequirementsAnalystSubAgent(paths) {
18795
18999
  ].join("\n")
18796
19000
  };
18797
19001
  }
18798
- var scanRequirementsSkill = {
18799
- name: "scan-requirements",
18800
- description: "Kick off a requirements-analyst scan across BCM model docs, competitive analysis, product docs, or meeting extracts. Creates a req:scan issue and dispatches Phase 1.",
18801
- disableModelInvocation: true,
18802
- userInvocable: true,
18803
- context: "fork",
18804
- agent: "requirements-analyst",
18805
- platforms: { cursor: { exclude: true } },
18806
- instructions: [
18807
- "# Scan Requirements",
18808
- "",
18809
- "Kick off a requirements-analyst scan cycle. Creates a `req:scan` issue",
18810
- "targeted at the requested scope and dispatches Phase 1 (Scan) in the",
18811
- "requirements-analyst agent.",
18812
- "",
18813
- "## Usage",
18814
- "",
18815
- "/scan-requirements <scope>",
18816
- "",
18817
- "Where `<scope>` is one of:",
18818
- "- `bcm:<PREFIX-NNN>` \u2014 a single BCM model doc",
18819
- "- `competitive:<slug>` \u2014 a single competitive analysis doc",
18820
- "- `product-roadmap` \u2014 the prioritized feature roadmap",
18821
- "- `entity-taxonomy` \u2014 the entity taxonomy doc",
18822
- "- `meeting:<slug>` \u2014 a meeting extract",
18823
- "- `all-bcm` / `all-competitive` \u2014 full sweep (long-running)",
18824
- "",
18825
- "## Steps",
18826
- "",
18827
- "1. Create a `req:scan` issue with `type:requirement`, `priority:medium`,",
18828
- " and `status:ready`. Body must list the files to read and the scan scope.",
18829
- "2. Execute Phase 1 (Scan) of the requirements-analyst agent.",
18830
- "3. If gaps are found, a `req:draft-trace` issue is created automatically.",
18831
- "",
18832
- "## Output",
18833
- "",
18834
- "- A `req-scan-<scope>-<YYYY-MM-DD>.md` file under the project's research",
18835
- " requirements directory.",
18836
- "- A `req:draft-trace` issue if any gaps were identified."
18837
- ].join("\n")
18838
- };
18839
- function buildRequirementsAnalystBundle(paths = DEFAULT_AGENT_PATHS) {
19002
+ function buildScanRequirementsSkill(issueDefaults) {
19003
+ return {
19004
+ name: "scan-requirements",
19005
+ description: "Kick off a requirements-analyst scan across BCM model docs, competitive analysis, product docs, or meeting extracts. Creates a req:scan issue and dispatches Phase 1.",
19006
+ disableModelInvocation: true,
19007
+ userInvocable: true,
19008
+ context: "fork",
19009
+ agent: "requirements-analyst",
19010
+ platforms: { cursor: { exclude: true } },
19011
+ instructions: [
19012
+ "# Scan Requirements",
19013
+ "",
19014
+ "Kick off a requirements-analyst scan cycle. Creates a `req:scan` issue",
19015
+ "targeted at the requested scope and dispatches Phase 1 (Scan) in the",
19016
+ "requirements-analyst agent.",
19017
+ "",
19018
+ "## Usage",
19019
+ "",
19020
+ "/scan-requirements <scope>",
19021
+ "",
19022
+ "Where `<scope>` is one of:",
19023
+ "- `bcm:<PREFIX-NNN>` \u2014 a single BCM model doc",
19024
+ "- `competitive:<slug>` \u2014 a single competitive analysis doc",
19025
+ "- `product-roadmap` \u2014 the prioritized feature roadmap",
19026
+ "- `entity-taxonomy` \u2014 the entity taxonomy doc",
19027
+ "- `meeting:<slug>` \u2014 a meeting extract",
19028
+ "- `all-bcm` / `all-competitive` \u2014 full sweep (long-running)",
19029
+ "",
19030
+ "## Steps",
19031
+ "",
19032
+ `1. Create a \`req:scan\` issue with \`type:requirement\`, \`priority:${labelsForPhase(issueDefaults, "req:scan").priority}\`,`,
19033
+ ` and \`status:${labelsForPhase(issueDefaults, "req:scan").status}\`. Body must list the files to read and the scan scope.`,
19034
+ "2. Execute Phase 1 (Scan) of the requirements-analyst agent.",
19035
+ "3. If gaps are found, a `req:draft-trace` issue is created automatically.",
19036
+ "",
19037
+ "## Output",
19038
+ "",
19039
+ "- A `req-scan-<scope>-<YYYY-MM-DD>.md` file under the project's research",
19040
+ " requirements directory.",
19041
+ "- A `req:draft-trace` issue if any gaps were identified."
19042
+ ].join("\n")
19043
+ };
19044
+ }
19045
+ function buildRequirementsAnalystBundle(paths = DEFAULT_AGENT_PATHS, issueDefaults = DEFAULT_RESOLVED_ISSUE_DEFAULTS) {
18840
19046
  return {
18841
19047
  name: "requirements-analyst",
18842
19048
  description: "Requirements gap-discovery agent bundle for BCM-driven projects. 2-phase pipeline (scan, draft-trace) with req:* phase labels.",
@@ -18873,8 +19079,8 @@ function buildRequirementsAnalystBundle(paths = DEFAULT_AGENT_PATHS) {
18873
19079
  tags: ["workflow"]
18874
19080
  }
18875
19081
  ],
18876
- skills: [scanRequirementsSkill],
18877
- subAgents: [buildRequirementsAnalystSubAgent(paths)],
19082
+ skills: [buildScanRequirementsSkill(issueDefaults)],
19083
+ subAgents: [buildRequirementsAnalystSubAgent(paths, issueDefaults)],
18878
19084
  labels: [
18879
19085
  {
18880
19086
  name: "type:requirement",
@@ -21375,7 +21581,7 @@ function buildRequirementsWriterSubAgent(paths) {
21375
21581
  ].join("\n")
21376
21582
  };
21377
21583
  }
21378
- function buildWriteRequirementSkill(paths) {
21584
+ function buildWriteRequirementSkill(paths, issueDefaults) {
21379
21585
  return {
21380
21586
  name: WRITE_REQUIREMENT_SKILL_NAME,
21381
21587
  description: "Write one formal requirement document (BR / FR / NFR / TR / ADR / SEC / DR / INT / OPS / UX / MT) using the shipped category template and decision-authority rules. Picks up a req:write issue created by the upstream requirements-analyst pipeline (or kicked off ad hoc) and dispatches the requirements-writer agent.",
@@ -21429,7 +21635,7 @@ function buildWriteRequirementSkill(paths) {
21429
21635
  "## Steps",
21430
21636
  "",
21431
21637
  "1. Create a `req:write` issue with `type:requirement`,",
21432
- " `priority:medium`, `status:ready`, and the matching `tier:*` label.",
21638
+ ` \`priority:${labelsForPhase(issueDefaults, "req:write").priority}\`, \`status:${labelsForPhase(issueDefaults, "req:write").status}\`, and the matching \`tier:*\` label.`,
21433
21639
  " Body must include the category, tier, output path, and a pointer",
21434
21640
  " to the upstream proposal (or a direct user description if no",
21435
21641
  " proposals file exists).",
@@ -21448,7 +21654,7 @@ function buildWriteRequirementSkill(paths) {
21448
21654
  ].join("\n")
21449
21655
  };
21450
21656
  }
21451
- function buildRequirementsWriterBundle(paths = DEFAULT_AGENT_PATHS) {
21657
+ function buildRequirementsWriterBundle(paths = DEFAULT_AGENT_PATHS, issueDefaults = DEFAULT_RESOLVED_ISSUE_DEFAULTS) {
21452
21658
  return {
21453
21659
  name: "requirements-writer",
21454
21660
  description: "Requirements writer agent bundle. Authors formal requirement documents from upstream proposals using the 11-category taxonomy (BR, FR, NFR, TR, ADR, SEC, DR, INT, OPS, UX, MT), the four-tier classification, and decision-authority rules (direct-write vs. propose-only). Ships 13 templates plus a standards-and-frameworks reference.",
@@ -21496,7 +21702,7 @@ function buildRequirementsWriterBundle(paths = DEFAULT_AGENT_PATHS) {
21496
21702
  tags: ["workflow"]
21497
21703
  }
21498
21704
  ],
21499
- skills: [buildWriteRequirementSkill(paths)],
21705
+ skills: [buildWriteRequirementSkill(paths, issueDefaults)],
21500
21706
  subAgents: [buildRequirementsWriterSubAgent(paths)],
21501
21707
  labels: [
21502
21708
  {
@@ -21530,7 +21736,7 @@ function buildRequirementsWriterBundle(paths = DEFAULT_AGENT_PATHS) {
21530
21736
  var requirementsWriterBundle = buildRequirementsWriterBundle();
21531
21737
 
21532
21738
  // src/agent/bundles/requirements-reviewer.ts
21533
- function buildRequirementsReviewerSubAgent(paths) {
21739
+ function buildRequirementsReviewerSubAgent(paths, issueDefaults) {
21534
21740
  return {
21535
21741
  name: "requirements-reviewer",
21536
21742
  description: "Audits and deprecates existing requirement documents (BR, FR, NFR, TR, ADR, SEC, DR, INT, OPS, UX, MT). In `req:review` mode, runs the 12-check audit (structural compliance, categorization, traceability, cross-reference integrity, sequence integrity, content quality, registry sync, decision-authority compliance, tier classification, cross-referencing conventions, stale `Proposed` ADR/TR decisions) and produces a report grouped by Critical / Warning / Info (plus a dedicated Stale decisions section). In `req:deprecate` mode, transitions target documents to `Deprecated` or `Superseded`, updates the category index row, and files `req:write` follow-ups for every back-reference so the writer can rewrite them. One phase per session.",
@@ -22495,7 +22701,7 @@ function buildRequirementsReviewerSubAgent(paths) {
22495
22701
  " reference).",
22496
22702
  "- Labels: `type:requirement`, `req:write`, the matching",
22497
22703
  " `tier:*` label derived from the referencing document's Tier,",
22498
- " `priority:medium`, `status:ready`.",
22704
+ ` \`priority:${labelsForPhase(issueDefaults, "req:write").priority}\`, \`status:${labelsForPhase(issueDefaults, "req:write").status}\`.`,
22499
22705
  "- If any of Category / Tier / Output Path cannot be derived from",
22500
22706
  " the referencing document, open the follow-up with",
22501
22707
  " `status:needs-attention` and a `Missing:` line, per the same",
@@ -22585,7 +22791,7 @@ function buildRequirementsReviewerSubAgent(paths) {
22585
22791
  ].join("\n")
22586
22792
  };
22587
22793
  }
22588
- function buildReviewRequirementsSkill(paths) {
22794
+ function buildReviewRequirementsSkill(paths, issueDefaults) {
22589
22795
  return {
22590
22796
  name: "review-requirements",
22591
22797
  description: "Audit existing requirement documents (BR / FR / NFR / TR / ADR / SEC / DR / INT / OPS / UX / MT) for structural compliance, categorization, traceability, cross-reference integrity, sequence integrity, content quality, registry sync, decision-authority compliance, tier classification, cross-referencing conventions, and stale `Proposed` ADR/TR decisions. Supports four scopes (full audit, category, single document, targeted check) and dispatches the requirements-reviewer agent. Audits documents \u2014 never writes them. Soft dependency: expects requirement templates at `" + REQUIREMENTS_WRITER_PATHS.templatesRoot + "`, shipped by the requirements-writer bundle.",
@@ -22648,7 +22854,7 @@ function buildReviewRequirementsSkill(paths) {
22648
22854
  "## Steps",
22649
22855
  "",
22650
22856
  "1. Create a `req:review` issue with `type:requirement`,",
22651
- " `priority:medium`, and `status:ready`. Body must include the",
22857
+ ` \`priority:${labelsForPhase(issueDefaults, "req:review").priority}\`, and \`status:${labelsForPhase(issueDefaults, "req:review").status}\`. Body must include the`,
22652
22858
  " scope, the requirements root (or accept the default), and the",
22653
22859
  " output path.",
22654
22860
  "2. Execute the review phase of the requirements-reviewer agent.",
@@ -22687,7 +22893,7 @@ function buildReviewRequirementsSkill(paths) {
22687
22893
  ].join("\n")
22688
22894
  };
22689
22895
  }
22690
- function buildDeprecateRequirementSkill(_paths) {
22896
+ function buildDeprecateRequirementSkill(_paths, issueDefaults) {
22691
22897
  return {
22692
22898
  name: "deprecate-requirement",
22693
22899
  description: "Transition one or more requirement documents to `Deprecated` or `Superseded`. Creates a `req:deprecate` issue and dispatches the requirements-reviewer agent's deprecation phase, which edits the target document's Status, Revision History, Superseded-by traceability link, and category index row, then files `req:write` follow-ups for every back-reference so the requirements-writer can rewrite them. The deprecation phase pauses for explicit human confirmation before editing (unless the issue body pre-approves the change).",
@@ -22750,7 +22956,7 @@ function buildDeprecateRequirementSkill(_paths) {
22750
22956
  "## Steps",
22751
22957
  "",
22752
22958
  "1. Create a `req:deprecate` issue with `type:requirement`,",
22753
- " `priority:medium`, and `status:ready`. Body must include the",
22959
+ ` \`priority:${labelsForPhase(issueDefaults, "req:deprecate").priority}\`, and \`status:${labelsForPhase(issueDefaults, "req:deprecate").status}\`. Body must include the`,
22754
22960
  " Targets, Transition, and Reason sections above (optionally",
22755
22961
  " `Pre-approved: yes`).",
22756
22962
  "2. Execute the deprecation phase of the requirements-reviewer",
@@ -22791,7 +22997,7 @@ function buildDeprecateRequirementSkill(_paths) {
22791
22997
  ].join("\n")
22792
22998
  };
22793
22999
  }
22794
- function buildRequirementsReviewerBundle(paths = DEFAULT_AGENT_PATHS) {
23000
+ function buildRequirementsReviewerBundle(paths = DEFAULT_AGENT_PATHS, issueDefaults = DEFAULT_RESOLVED_ISSUE_DEFAULTS) {
22795
23001
  return {
22796
23002
  name: "requirements-reviewer",
22797
23003
  description: "Requirements reviewer agent bundle. Audits existing requirement documents (BR, FR, NFR, TR, ADR, SEC, DR, INT, OPS, UX, MT) via the 12-check review phase (including Check 12: stale `Proposed` ADR/TR decisions), and transitions requirements to `Deprecated` or `Superseded` via the deprecation phase (narrow writes to Status, Revision History, Superseded-by, and category index row, with `req:write` follow-ups for every back-reference). Reads templates from the requirements-writer bundle's reference directory; ships no templates of its own.",
@@ -22904,10 +23110,10 @@ function buildRequirementsReviewerBundle(paths = DEFAULT_AGENT_PATHS) {
22904
23110
  }
22905
23111
  ],
22906
23112
  skills: [
22907
- buildReviewRequirementsSkill(paths),
22908
- buildDeprecateRequirementSkill(paths)
23113
+ buildReviewRequirementsSkill(paths, issueDefaults),
23114
+ buildDeprecateRequirementSkill(paths, issueDefaults)
22909
23115
  ],
22910
- subAgents: [buildRequirementsReviewerSubAgent(paths)],
23116
+ subAgents: [buildRequirementsReviewerSubAgent(paths, issueDefaults)],
22911
23117
  labels: [
22912
23118
  {
22913
23119
  name: "req:review",
@@ -23281,7 +23487,7 @@ function buildResearchAnalystSubAgent(paths) {
23281
23487
  ].join("\n")
23282
23488
  };
23283
23489
  }
23284
- function buildResearchSkill(paths) {
23490
+ function buildResearchSkill(paths, issueDefaults) {
23285
23491
  return {
23286
23492
  name: "research",
23287
23493
  description: "Kick off a generic research micro-task pipeline. Creates a research:scope issue and dispatches Phase 1 (Scope) in the research-analyst agent.",
@@ -23321,7 +23527,7 @@ function buildResearchSkill(paths) {
23321
23527
  "## Steps",
23322
23528
  "",
23323
23529
  "1. Create a `research:scope` issue with `type:research`,",
23324
- " `priority:medium`, and `status:ready`. Body must include the",
23530
+ ` \`priority:${labelsForPhase(issueDefaults, "research:scope").priority}\`, and \`status:${labelsForPhase(issueDefaults, "research:scope").status}\`. Body must include the`,
23325
23531
  " verbatim question, authorized sources, and any overrides.",
23326
23532
  "2. Execute Phase 1 (Scope) of the research-analyst agent.",
23327
23533
  "3. Phase 1 creates `research:slice` issues (one per slice) and a",
@@ -23339,7 +23545,7 @@ function buildResearchSkill(paths) {
23339
23545
  ].join("\n")
23340
23546
  };
23341
23547
  }
23342
- function buildResearchPipelineBundle(paths = DEFAULT_AGENT_PATHS) {
23548
+ function buildResearchPipelineBundle(paths = DEFAULT_AGENT_PATHS, issueDefaults = DEFAULT_RESOLVED_ISSUE_DEFAULTS) {
23343
23549
  return {
23344
23550
  name: "research-pipeline",
23345
23551
  description: "Generic research micro-task pipeline: scope, N-way slice search/synthesize, and verify. Enabled by default; domain-neutral; filesystem-durable between phases.",
@@ -23372,7 +23578,7 @@ function buildResearchPipelineBundle(paths = DEFAULT_AGENT_PATHS) {
23372
23578
  tags: ["workflow"]
23373
23579
  }
23374
23580
  ],
23375
- skills: [buildResearchSkill(paths)],
23581
+ skills: [buildResearchSkill(paths, issueDefaults)],
23376
23582
  subAgents: [buildResearchAnalystSubAgent(paths)],
23377
23583
  labels: [
23378
23584
  {
@@ -23561,7 +23767,7 @@ var slackBundle = {
23561
23767
  };
23562
23768
 
23563
23769
  // src/agent/bundles/software-profile.ts
23564
- function buildSoftwareProfileAnalystSubAgent(paths) {
23770
+ function buildSoftwareProfileAnalystSubAgent(paths, issueDefaults) {
23565
23771
  return {
23566
23772
  name: "software-profile-analyst",
23567
23773
  description: "Researches a software product (competitor, adjacent, incumbent, enabler, infrastructure, or ecosystem-tool) from public sources, produces a structured markdown profile, contributes rows to a shared feature matrix ranked against configurable segment-importance weights, maps features back to the BCM capability model and flags unmapped features, then enqueues downstream `bcm:outline`, `company:research`, and `people:research` issues for new sub-capabilities, the vendor company, and primary-attribution founders/leaders surfaced during profiling. One product per session, tracked by software:* GitHub issue labels.",
@@ -24100,8 +24306,8 @@ function buildSoftwareProfileAnalystSubAgent(paths) {
24100
24306
  "",
24101
24307
  " - `type:bcm-document`",
24102
24308
  " - `bcm:outline`",
24103
- " - `priority:medium`",
24104
- " - `status:ready`",
24309
+ ` - \`priority:${labelsForPhase(issueDefaults, "bcm:outline").priority}\``,
24310
+ ` - \`status:${labelsForPhase(issueDefaults, "bcm:outline").status}\``,
24105
24311
  "",
24106
24312
  " The issue body must include:",
24107
24313
  " - A **discovery source** line naming this software profile",
@@ -24169,7 +24375,7 @@ function buildSoftwareProfileAnalystSubAgent(paths) {
24169
24375
  " `Follow-up Candidates > Adjacent products to evaluate`. Each new",
24170
24376
  " issue follows the same 4-phase pipeline \u2014 start it in the",
24171
24377
  " `software:research` phase with `type:software-profile`,",
24172
- " `priority:medium`, and `status:ready`.",
24378
+ ` \`priority:${labelsForPhase(issueDefaults, "software:research").priority}\`, and \`status:${labelsForPhase(issueDefaults, "software:research").status}\`.`,
24173
24379
  "",
24174
24380
  "3. **Enqueue a `company:research` issue for the vendor company** if",
24175
24381
  " no matching profile already exists under `<COMPANY_PROFILES_DIR>/`.",
@@ -24180,8 +24386,8 @@ function buildSoftwareProfileAnalystSubAgent(paths) {
24180
24386
  "",
24181
24387
  " - `type:company-profile`",
24182
24388
  " - `company:research`",
24183
- " - `priority:medium`",
24184
- " - `status:ready`",
24389
+ ` - \`priority:${labelsForPhase(issueDefaults, "company:research").priority}\``,
24390
+ ` - \`status:${labelsForPhase(issueDefaults, "company:research").status}\``,
24185
24391
  "",
24186
24392
  " The issue body must include:",
24187
24393
  " - A **discovery source** line naming this software profile",
@@ -24199,8 +24405,8 @@ function buildSoftwareProfileAnalystSubAgent(paths) {
24199
24405
  "",
24200
24406
  " - `type:people-profile`",
24201
24407
  " - `people:research`",
24202
- " - `priority:medium`",
24203
- " - `status:ready`",
24408
+ ` - \`priority:${labelsForPhase(issueDefaults, "people:research").priority}\``,
24409
+ ` - \`status:${labelsForPhase(issueDefaults, "people:research").status}\``,
24204
24410
  "",
24205
24411
  " The issue body must include:",
24206
24412
  " - A **discovery source** line naming this software profile",
@@ -24343,7 +24549,7 @@ function buildSoftwareProfileAnalystSubAgent(paths) {
24343
24549
  ].join("\n")
24344
24550
  };
24345
24551
  }
24346
- function buildProfileSoftwareSkill(paths) {
24552
+ function buildProfileSoftwareSkill(paths, issueDefaults) {
24347
24553
  return {
24348
24554
  name: "profile-software",
24349
24555
  description: "Kick off a software-profile pipeline. Creates a software:research issue for the given product and dispatches Phase 1 (Research) in the software-profile-analyst agent. Phase 4 (Map) writes a BCM capability mapping onto the profile and enqueues `bcm:outline` issues for unmapped features. Phase 5 (Followup) enqueues downstream `company:research` and `people:research` issues for the vendor company and primary-attribution founders/leaders surfaced in the profile.",
@@ -24390,7 +24596,7 @@ function buildProfileSoftwareSkill(paths) {
24390
24596
  "## Steps",
24391
24597
  "",
24392
24598
  "1. Create a `software:research` issue with `type:software-profile`,",
24393
- " `priority:medium`, and `status:ready`. Body must include the",
24599
+ ` \`priority:${labelsForPhase(issueDefaults, "software:research").priority}\`, and \`status:${labelsForPhase(issueDefaults, "software:research").status}\`. Body must include the`,
24394
24600
  " product name, selected type, framing, and any overrides.",
24395
24601
  "2. Execute Phase 1 (Research) of the software-profile-analyst",
24396
24602
  " agent.",
@@ -24423,7 +24629,7 @@ function buildProfileSoftwareSkill(paths) {
24423
24629
  ].join("\n")
24424
24630
  };
24425
24631
  }
24426
- function buildMapSoftwareSkill(paths) {
24632
+ function buildMapSoftwareSkill(paths, issueDefaults) {
24427
24633
  return {
24428
24634
  name: "map-software",
24429
24635
  description: "Kick off a standalone software-capability mapping session. Creates a software:map issue for an already-profiled product and dispatches Phase 4 (Map) in the software-profile-analyst agent. Produces the `## Capability Mapping` section on the profile and enqueues `bcm:outline` issues for unmapped features above the configured threshold.",
@@ -24478,7 +24684,7 @@ function buildMapSoftwareSkill(paths) {
24478
24684
  "## Steps",
24479
24685
  "",
24480
24686
  "1. Create a `software:map` issue with `type:software-profile`,",
24481
- " `priority:medium`, and `status:ready`. Body must include the",
24687
+ ` \`priority:${labelsForPhase(issueDefaults, "software:map").priority}\`, and \`status:${labelsForPhase(issueDefaults, "software:map").status}\`. Body must include the`,
24482
24688
  " profile path and any overrides.",
24483
24689
  "2. Execute Phase 4 (Map) of the software-profile-analyst agent.",
24484
24690
  "3. Phase 4 writes the `## Capability Mapping` section, enqueues",
@@ -24500,7 +24706,7 @@ function buildMapSoftwareSkill(paths) {
24500
24706
  ].join("\n")
24501
24707
  };
24502
24708
  }
24503
- function buildSoftwareProfileBundle(paths = DEFAULT_AGENT_PATHS) {
24709
+ function buildSoftwareProfileBundle(paths = DEFAULT_AGENT_PATHS, issueDefaults = DEFAULT_RESOLVED_ISSUE_DEFAULTS) {
24504
24710
  return {
24505
24711
  name: "software-profile",
24506
24712
  description: "Software research, profiling, feature-matrix, and capability-mapping pipeline: research, profile, matrix, map, followup. Enabled by default; domain-neutral; filesystem-durable between phases; ranks features against configurable segment-importance weights and maps features back to the BCM capability model. Phase 4 (Map) hands unmapped features off to the `bcm-writer` bundle via `bcm:outline` issues. Phase 5 (Followup) hands the vendor company and primary-attribution founders/leaders off to the `company-profile` and `people-profile` bundles via `company:research` and `people:research` issues.",
@@ -24553,8 +24759,11 @@ function buildSoftwareProfileBundle(paths = DEFAULT_AGENT_PATHS) {
24553
24759
  tags: ["workflow"]
24554
24760
  }
24555
24761
  ],
24556
- skills: [buildProfileSoftwareSkill(paths), buildMapSoftwareSkill(paths)],
24557
- subAgents: [buildSoftwareProfileAnalystSubAgent(paths)],
24762
+ skills: [
24763
+ buildProfileSoftwareSkill(paths, issueDefaults),
24764
+ buildMapSoftwareSkill(paths, issueDefaults)
24765
+ ],
24766
+ subAgents: [buildSoftwareProfileAnalystSubAgent(paths, issueDefaults)],
24558
24767
  labels: [
24559
24768
  {
24560
24769
  name: "type:software-profile",
@@ -24712,7 +24921,7 @@ var STANDARDS_COMPARE_REFERENCE_FILES = [
24712
24921
  content: TEMPLATE_COMPARISON_GRID
24713
24922
  }
24714
24923
  ];
24715
- function buildStandardsResearchAnalystSubAgent(paths) {
24924
+ function buildStandardsResearchAnalystSubAgent(paths, issueDefaults) {
24716
24925
  return {
24717
24926
  name: "standards-research-analyst",
24718
24927
  description: "Authors version-aware interoperability standards research through a 5-phase pipeline (scope \u2192 research \u2192 compare \u2192 extension \u2192 organizations). Researches one standard version per session, synthesizes cross-version comparisons, profiles extensions/profiles/implementation guides, and profiles standards-body organizations. Hands off canonical company and people profiles to the company-profile and people-profile bundles via company:research and people:research issues. One phase per session, tracked by standards:* GitHub issue labels with filesystem-based durability between phases.",
@@ -25076,12 +25285,23 @@ function buildStandardsResearchAnalystSubAgent(paths) {
25076
25285
  " *Organizations of Interest* that does not already have a",
25077
25286
  " canonical company profile or an open `company:research` issue.",
25078
25287
  " The `company-profile` bundle owns the downstream profile; this",
25079
- " agent only hands off.",
25288
+ " agent only hands off. Each issue must carry:",
25289
+ "",
25290
+ " - `type:company-profile`",
25291
+ " - `company:research`",
25292
+ ` - \`priority:${labelsForPhase(issueDefaults, "company:research").priority}\``,
25293
+ ` - \`status:${labelsForPhase(issueDefaults, "company:research").status}\``,
25080
25294
  "",
25081
25295
  "6. **Create `people:research` issues** for every entry in *People of",
25082
25296
  " Interest* that does not already have a canonical person profile",
25083
25297
  " or an open `people:research` issue. The `people-profile` bundle",
25084
- " owns the downstream profile; this agent only hands off.",
25298
+ " owns the downstream profile; this agent only hands off. Each",
25299
+ " issue must carry:",
25300
+ "",
25301
+ " - `type:people-profile`",
25302
+ " - `people:research`",
25303
+ ` - \`priority:${labelsForPhase(issueDefaults, "people:research").priority}\``,
25304
+ ` - \`status:${labelsForPhase(issueDefaults, "people:research").status}\``,
25085
25305
  "",
25086
25306
  "7. **Verify all handoffs were created** before committing. For each",
25087
25307
  " entity in both tables, confirm an existing profile or a fresh",
@@ -25368,12 +25588,23 @@ function buildStandardsResearchAnalystSubAgent(paths) {
25368
25588
  " `company:research` issue if no canonical profile exists and no",
25369
25589
  " open `company:research` issue is already tracking this",
25370
25590
  " organization. The `company-profile` bundle owns the downstream",
25371
- " profile.",
25591
+ " profile. The issue must carry:",
25592
+ "",
25593
+ " - `type:company-profile`",
25594
+ " - `company:research`",
25595
+ ` - \`priority:${labelsForPhase(issueDefaults, "company:research").priority}\``,
25596
+ ` - \`status:${labelsForPhase(issueDefaults, "company:research").status}\``,
25372
25597
  "",
25373
25598
  "6. **Hand off canonical people profiles** by creating one",
25374
25599
  " `people:research` issue per leadership entry that does not",
25375
25600
  " already have a canonical profile or an open `people:research`",
25376
25601
  " issue. The `people-profile` bundle owns the downstream profiles.",
25602
+ " Each issue must carry:",
25603
+ "",
25604
+ " - `type:people-profile`",
25605
+ " - `people:research`",
25606
+ ` - \`priority:${labelsForPhase(issueDefaults, "people:research").priority}\``,
25607
+ ` - \`status:${labelsForPhase(issueDefaults, "people:research").status}\``,
25377
25608
  "",
25378
25609
  "7. **Commit and push** the organization page. Close the",
25379
25610
  " organizations issue.",
@@ -25499,7 +25730,7 @@ function buildStandardsResearchAnalystSubAgent(paths) {
25499
25730
  ].join("\n")
25500
25731
  };
25501
25732
  }
25502
- function buildScopeStandardsResearchSkill(paths) {
25733
+ function buildScopeStandardsResearchSkill(paths, issueDefaults) {
25503
25734
  return {
25504
25735
  name: "scope-standards-research",
25505
25736
  description: "Kick off the scope phase of an interoperability-standards research campaign. Creates a standards:scope issue for the supplied standard and dispatches Phase 1 of the standards-research-analyst, which writes a query plan and creates downstream standards:research, standards:compare, and standards:organizations issues.",
@@ -25546,7 +25777,7 @@ function buildScopeStandardsResearchSkill(paths) {
25546
25777
  "## Steps",
25547
25778
  "",
25548
25779
  "1. Create a `standards:scope` issue with `type:standards-research`,",
25549
- " `priority:medium`, and `status:ready`. The body must include the",
25780
+ ` \`priority:${labelsForPhase(issueDefaults, "standards:scope").priority}\`, and \`status:${labelsForPhase(issueDefaults, "standards:scope").status}\`. The body must include the`,
25550
25781
  " standard slug, the list of target versions (or a request to",
25551
25782
  " enumerate), and any known governance bodies.",
25552
25783
  "2. Execute Phase 1 (Scope) of the standards-research-analyst agent.",
@@ -25565,7 +25796,7 @@ function buildScopeStandardsResearchSkill(paths) {
25565
25796
  ].join("\n")
25566
25797
  };
25567
25798
  }
25568
- function buildResearchStandardSkill(paths) {
25799
+ function buildResearchStandardSkill(paths, issueDefaults) {
25569
25800
  return {
25570
25801
  name: "research-standard",
25571
25802
  description: "Kick off the research phase for one version of an interoperability standard. Creates a standards:research issue for the supplied standard and version and dispatches Phase 2 of the standards-research-analyst, which populates the version page with status, key changes, resources, adoption, and governance touch-points.",
@@ -25611,7 +25842,7 @@ function buildResearchStandardSkill(paths) {
25611
25842
  "## Steps",
25612
25843
  "",
25613
25844
  "1. Create a `standards:research` issue with",
25614
- " `type:standards-research`, `priority:medium`, and `status:ready`.",
25845
+ ` \`type:standards-research\`, \`priority:${labelsForPhase(issueDefaults, "standards:research").priority}\`, and \`status:${labelsForPhase(issueDefaults, "standards:research").status}\`.`,
25615
25846
  " The body must include the standard slug and the version slug.",
25616
25847
  "2. Execute Phase 2 (Research) of the standards-research-analyst",
25617
25848
  " agent. The agent runs 6\u201310 targeted web searches and populates",
@@ -25630,7 +25861,7 @@ function buildResearchStandardSkill(paths) {
25630
25861
  ].join("\n")
25631
25862
  };
25632
25863
  }
25633
- function buildCompareStandardsSkill(paths) {
25864
+ function buildCompareStandardsSkill(paths, issueDefaults) {
25634
25865
  return {
25635
25866
  name: "compare-standards",
25636
25867
  description: "Kick off the compare phase across researched versions of an interoperability standard. Creates a standards:compare issue for the supplied standard and dispatches Phase 3 of the standards-research-analyst, which synthesizes the overview page using the ship-with comparison-grid template.",
@@ -25683,7 +25914,7 @@ function buildCompareStandardsSkill(paths) {
25683
25914
  "## Steps",
25684
25915
  "",
25685
25916
  "1. Create a `standards:compare` issue with",
25686
- " `type:standards-research`, `priority:medium`, and `status:ready`.",
25917
+ ` \`type:standards-research\`, \`priority:${labelsForPhase(issueDefaults, "standards:compare").priority}\`, and \`status:${labelsForPhase(issueDefaults, "standards:compare").status}\`.`,
25687
25918
  " Body must include the standard slug and the list of version",
25688
25919
  " pages under comparison.",
25689
25920
  "2. Execute Phase 3 (Compare) of the standards-research-analyst",
@@ -25700,7 +25931,7 @@ function buildCompareStandardsSkill(paths) {
25700
25931
  ].join("\n")
25701
25932
  };
25702
25933
  }
25703
- function buildExtensionStandardSkill(paths) {
25934
+ function buildExtensionStandardSkill(paths, issueDefaults) {
25704
25935
  return {
25705
25936
  name: "extension-standard",
25706
25937
  description: "Kick off the extension phase for one domain entity against an interoperability standard. Creates a standards:extension issue for the supplied standard and domain entity and dispatches Phase 4 of the standards-research-analyst, which analyzes the gap and hands off a Proposed ADR to the requirements pipeline.",
@@ -25750,7 +25981,7 @@ function buildExtensionStandardSkill(paths) {
25750
25981
  "## Steps",
25751
25982
  "",
25752
25983
  "1. Create a `standards:extension` issue with",
25753
- " `type:standards-research`, `priority:medium`, and `status:ready`.",
25984
+ ` \`type:standards-research\`, \`priority:${labelsForPhase(issueDefaults, "standards:extension").priority}\`, and \`status:${labelsForPhase(issueDefaults, "standards:extension").status}\`.`,
25754
25985
  " The body must include the standard slug, the entity slug, the",
25755
25986
  " closest resource, and a link to the source BCM or canvas",
25756
25987
  " document.",
@@ -25770,7 +26001,7 @@ function buildExtensionStandardSkill(paths) {
25770
26001
  ].join("\n")
25771
26002
  };
25772
26003
  }
25773
- function buildOrganizationsStandardSkill(paths) {
26004
+ function buildOrganizationsStandardSkill(paths, issueDefaults) {
25774
26005
  return {
25775
26006
  name: "organizations-standard",
25776
26007
  description: "Kick off the organizations phase for one standards-body organization. Creates a standards:organizations issue for the supplied standard and organization and dispatches Phase 5 of the standards-research-analyst, which writes a standards-organization page and hands off canonical company and people profiles to the company-profile and people-profile bundles.",
@@ -25816,7 +26047,7 @@ function buildOrganizationsStandardSkill(paths) {
25816
26047
  "## Steps",
25817
26048
  "",
25818
26049
  "1. Create a `standards:organizations` issue with",
25819
- " `type:standards-research`, `priority:medium`, and `status:ready`.",
26050
+ ` \`type:standards-research\`, \`priority:${labelsForPhase(issueDefaults, "standards:organizations").priority}\`, and \`status:${labelsForPhase(issueDefaults, "standards:organizations").status}\`.`,
25820
26051
  " Body must include the standard slug, the organization slug, and",
25821
26052
  " the organization's governance role.",
25822
26053
  "2. Execute Phase 5 (Organizations) of the",
@@ -25837,7 +26068,7 @@ function buildOrganizationsStandardSkill(paths) {
25837
26068
  ].join("\n")
25838
26069
  };
25839
26070
  }
25840
- function buildStandardsResearchBundle(paths = DEFAULT_AGENT_PATHS) {
26071
+ function buildStandardsResearchBundle(paths = DEFAULT_AGENT_PATHS, issueDefaults = DEFAULT_RESOLVED_ISSUE_DEFAULTS) {
25841
26072
  return {
25842
26073
  name: "standards-research",
25843
26074
  description: "Interoperability-standards research pipeline: scope, research, compare, extension, organizations. 5 phases with standards:* phase labels. Version-aware research, cross-version comparison, extension/profile profiling, and standards-body organization profiling. Hands off canonical profiles to company-profile and people-profile via company:research and people:research issues, extension ADRs to requirements-writer via req:write, and domain-entity mappings to bcm-writer. Enabled by default; domain-neutral; filesystem-durable between phases.",
@@ -25903,13 +26134,13 @@ function buildStandardsResearchBundle(paths = DEFAULT_AGENT_PATHS) {
25903
26134
  }
25904
26135
  ],
25905
26136
  skills: [
25906
- buildScopeStandardsResearchSkill(paths),
25907
- buildResearchStandardSkill(paths),
25908
- buildCompareStandardsSkill(paths),
25909
- buildExtensionStandardSkill(paths),
25910
- buildOrganizationsStandardSkill(paths)
26137
+ buildScopeStandardsResearchSkill(paths, issueDefaults),
26138
+ buildResearchStandardSkill(paths, issueDefaults),
26139
+ buildCompareStandardsSkill(paths, issueDefaults),
26140
+ buildExtensionStandardSkill(paths, issueDefaults),
26141
+ buildOrganizationsStandardSkill(paths, issueDefaults)
25911
26142
  ],
25912
- subAgents: [buildStandardsResearchAnalystSubAgent(paths)],
26143
+ subAgents: [buildStandardsResearchAnalystSubAgent(paths, issueDefaults)],
25913
26144
  labels: [
25914
26145
  {
25915
26146
  name: "type:standards-research",
@@ -27133,7 +27364,7 @@ function renderPriorityRulesSection(rules) {
27133
27364
  }
27134
27365
 
27135
27366
  // src/agent/bundles/index.ts
27136
- function buildBuiltInBundles(paths = DEFAULT_AGENT_PATHS) {
27367
+ function buildBuiltInBundles(paths = DEFAULT_AGENT_PATHS, issueDefaults = DEFAULT_RESOLVED_ISSUE_DEFAULTS) {
27137
27368
  return [
27138
27369
  buildBaseBundle(paths),
27139
27370
  upstreamConfigulatorDocsBundle,
@@ -27150,20 +27381,20 @@ function buildBuiltInBundles(paths = DEFAULT_AGENT_PATHS) {
27150
27381
  agendaBundle,
27151
27382
  orchestratorBundle,
27152
27383
  prReviewBundle,
27153
- buildRequirementsAnalystBundle(paths),
27154
- buildRequirementsWriterBundle(paths),
27155
- buildRequirementsReviewerBundle(paths),
27156
- buildResearchPipelineBundle(paths),
27157
- buildCompanyProfileBundle(paths),
27158
- buildCustomerProfileBundle(paths),
27159
- buildPeopleProfileBundle(paths),
27160
- buildSoftwareProfileBundle(paths),
27161
- buildIndustryDiscoveryBundle(paths),
27162
- buildBusinessModelsBundle(paths),
27163
- buildBcmWriterBundle(paths),
27164
- buildStandardsResearchBundle(paths),
27165
- buildRegulatoryResearchBundle(paths),
27166
- buildMaintenanceAuditBundle(paths),
27384
+ buildRequirementsAnalystBundle(paths, issueDefaults),
27385
+ buildRequirementsWriterBundle(paths, issueDefaults),
27386
+ buildRequirementsReviewerBundle(paths, issueDefaults),
27387
+ buildResearchPipelineBundle(paths, issueDefaults),
27388
+ buildCompanyProfileBundle(paths, issueDefaults),
27389
+ buildCustomerProfileBundle(paths, issueDefaults),
27390
+ buildPeopleProfileBundle(paths, issueDefaults),
27391
+ buildSoftwareProfileBundle(paths, issueDefaults),
27392
+ buildIndustryDiscoveryBundle(paths, issueDefaults),
27393
+ buildBusinessModelsBundle(paths, issueDefaults),
27394
+ buildBcmWriterBundle(paths, issueDefaults),
27395
+ buildStandardsResearchBundle(paths, issueDefaults),
27396
+ buildRegulatoryResearchBundle(paths, issueDefaults),
27397
+ buildMaintenanceAuditBundle(paths, issueDefaults),
27167
27398
  buildDocsSyncBundle(paths)
27168
27399
  ];
27169
27400
  }
@@ -27201,6 +27432,152 @@ function prefix(rel, entry) {
27201
27432
  return path.posix.join(rel, entry);
27202
27433
  }
27203
27434
 
27435
+ // src/agent/renderers/cursor-renderer.ts
27436
+ var import_projen6 = require("projen");
27437
+ var import_textfile2 = require("projen/lib/textfile");
27438
+ var GENERATED_MARKER = "# ~~ Generated by @codedrifters/configulator. Edits welcome \u2014 please contribute improvements back. ~~";
27439
+ var CursorRenderer = class _CursorRenderer {
27440
+ /**
27441
+ * Render all Cursor configuration files.
27442
+ */
27443
+ static render(component, rules, skills, subAgents, mcpServers, settings) {
27444
+ _CursorRenderer.renderRules(component, rules);
27445
+ _CursorRenderer.renderSkills(component, skills);
27446
+ _CursorRenderer.renderSubAgents(component, subAgents);
27447
+ _CursorRenderer.renderMcpServers(component, mcpServers);
27448
+ _CursorRenderer.renderHooks(component, settings);
27449
+ _CursorRenderer.renderIgnoreFiles(component, settings);
27450
+ }
27451
+ static renderRules(component, rules) {
27452
+ for (const rule of rules) {
27453
+ if (rule.platforms?.cursor?.exclude) continue;
27454
+ const lines = [];
27455
+ const description = rule.platforms?.cursor?.description ?? rule.description;
27456
+ const isAlways = rule.scope === AGENT_RULE_SCOPE.ALWAYS;
27457
+ lines.push("---");
27458
+ lines.push(`description: "${description}"`);
27459
+ lines.push(`alwaysApply: ${isAlways}`);
27460
+ if (!isAlways && rule.filePatterns && rule.filePatterns.length > 0) {
27461
+ lines.push(`path: ${JSON.stringify([...rule.filePatterns])}`);
27462
+ }
27463
+ lines.push("---");
27464
+ lines.push("");
27465
+ lines.push(...rule.content.split("\n"));
27466
+ new import_textfile2.TextFile(component, `.cursor/rules/${rule.name}.mdc`, { lines });
27467
+ }
27468
+ }
27469
+ static renderSkills(component, skills) {
27470
+ for (const skill of skills) {
27471
+ if (skill.platforms?.cursor?.exclude) continue;
27472
+ const lines = [];
27473
+ lines.push("---");
27474
+ lines.push(`name: "${skill.name}"`);
27475
+ lines.push(`description: "${skill.description}"`);
27476
+ if (skill.disableModelInvocation) {
27477
+ lines.push(`disable-model-invocation: true`);
27478
+ }
27479
+ if (skill.userInvocable === false) {
27480
+ lines.push(`user-invocable: false`);
27481
+ }
27482
+ if (skill.context) {
27483
+ lines.push(`context: "${skill.context}"`);
27484
+ }
27485
+ if (skill.agent) {
27486
+ lines.push(`agent: "${skill.agent}"`);
27487
+ }
27488
+ if (skill.shell) {
27489
+ lines.push(`shell: "${skill.shell}"`);
27490
+ }
27491
+ if (skill.allowedTools && skill.allowedTools.length > 0) {
27492
+ lines.push(`allowed-tools:`);
27493
+ for (const tool of skill.allowedTools) {
27494
+ lines.push(` - "${tool}"`);
27495
+ }
27496
+ }
27497
+ lines.push("---");
27498
+ lines.push("");
27499
+ lines.push(...skill.instructions.split("\n"));
27500
+ new import_textfile2.TextFile(component, `.cursor/skills/${skill.name}/SKILL.md`, {
27501
+ lines
27502
+ });
27503
+ if (skill.referenceFiles && skill.referenceFiles.length > 0) {
27504
+ for (const file of skill.referenceFiles) {
27505
+ new import_textfile2.TextFile(component, `.cursor/skills/${skill.name}/${file.path}`, {
27506
+ lines: file.content.split("\n")
27507
+ });
27508
+ }
27509
+ }
27510
+ }
27511
+ }
27512
+ static renderSubAgents(component, subAgents) {
27513
+ for (const agent of subAgents) {
27514
+ if (agent.platforms?.cursor?.exclude) continue;
27515
+ const lines = [];
27516
+ lines.push("---");
27517
+ lines.push(`name: ${agent.name}`);
27518
+ lines.push(`description: >-`);
27519
+ lines.push(` ${agent.description}`);
27520
+ if (agent.platforms?.cursor?.readonly) {
27521
+ lines.push(`readonly: true`);
27522
+ }
27523
+ if (agent.platforms?.cursor?.isBackground) {
27524
+ lines.push(`is_background: true`);
27525
+ }
27526
+ lines.push("---");
27527
+ lines.push("");
27528
+ lines.push(...agent.prompt.split("\n"));
27529
+ new import_textfile2.TextFile(component, `.cursor/agents/${agent.name}.md`, { lines });
27530
+ }
27531
+ }
27532
+ static renderMcpServers(component, mcpServers) {
27533
+ const serverNames = Object.keys(mcpServers);
27534
+ if (serverNames.length === 0) return;
27535
+ const obj = { mcpServers: {} };
27536
+ const servers = obj.mcpServers;
27537
+ for (const [name, config] of Object.entries(mcpServers)) {
27538
+ const server = {};
27539
+ if (config.transport) server.transport = config.transport;
27540
+ if (config.command) server.command = config.command;
27541
+ if (config.args) server.args = [...config.args];
27542
+ if (config.url) server.url = config.url;
27543
+ if (config.headers && Object.keys(config.headers).length > 0) {
27544
+ server.headers = { ...config.headers };
27545
+ }
27546
+ if (config.env) server.env = { ...config.env };
27547
+ servers[name] = server;
27548
+ }
27549
+ new import_projen6.JsonFile(component, ".cursor/mcp.json", { obj });
27550
+ }
27551
+ static renderHooks(component, settings) {
27552
+ if (!settings?.hooks) return;
27553
+ const hooks = {};
27554
+ const hookEntries = settings.hooks;
27555
+ for (const [event, actions] of Object.entries(hookEntries)) {
27556
+ if (actions && actions.length > 0) {
27557
+ hooks[event] = actions.map((h) => ({
27558
+ command: h.command
27559
+ }));
27560
+ }
27561
+ }
27562
+ if (Object.keys(hooks).length === 0) return;
27563
+ new import_projen6.JsonFile(component, ".cursor/hooks.json", {
27564
+ obj: { version: 1, hooks }
27565
+ });
27566
+ }
27567
+ static renderIgnoreFiles(component, settings) {
27568
+ if (settings?.ignorePatterns && settings.ignorePatterns.length > 0) {
27569
+ new import_textfile2.TextFile(component, ".cursorignore", {
27570
+ lines: [GENERATED_MARKER, "", ...settings.ignorePatterns]
27571
+ });
27572
+ }
27573
+ if (settings?.indexingIgnorePatterns && settings.indexingIgnorePatterns.length > 0) {
27574
+ new import_textfile2.TextFile(component, ".cursorindexingignore", {
27575
+ lines: [GENERATED_MARKER, "", ...settings.indexingIgnorePatterns]
27576
+ });
27577
+ }
27578
+ }
27579
+ };
27580
+
27204
27581
  // src/agent/template-resolver.ts
27205
27582
  var FALLBACKS = {
27206
27583
  "repository.owner": "<owner>",
@@ -27256,9 +27633,9 @@ function resolveTemplateVariables(template, metadata) {
27256
27633
  }
27257
27634
 
27258
27635
  // src/agent/renderers/claude-renderer.ts
27259
- var import_projen6 = require("projen");
27260
- var import_textfile2 = require("projen/lib/textfile");
27261
- var GENERATED_MARKER = "<!-- ~~ Generated by @codedrifters/configulator. Edits welcome \u2014 please contribute improvements back. ~~ -->";
27636
+ var import_projen7 = require("projen");
27637
+ var import_textfile3 = require("projen/lib/textfile");
27638
+ var GENERATED_MARKER2 = "<!-- ~~ Generated by @codedrifters/configulator. Edits welcome \u2014 please contribute improvements back. ~~ -->";
27262
27639
  var ClaudeRenderer = class _ClaudeRenderer {
27263
27640
  /**
27264
27641
  * Render all Claude Code configuration files.
@@ -27280,12 +27657,12 @@ var ClaudeRenderer = class _ClaudeRenderer {
27280
27657
  return target === CLAUDE_RULE_TARGET.CLAUDE_MD;
27281
27658
  });
27282
27659
  if (claudeMdRules.length === 0) return;
27283
- const lines = [GENERATED_MARKER, ""];
27660
+ const lines = [GENERATED_MARKER2, ""];
27284
27661
  for (let i = 0; i < claudeMdRules.length; i++) {
27285
27662
  if (i > 0) lines.push("", "---", "");
27286
27663
  lines.push(...claudeMdRules[i].content.split("\n"));
27287
27664
  }
27288
- new import_textfile2.TextFile(component, "CLAUDE.md", { lines });
27665
+ new import_textfile3.TextFile(component, "CLAUDE.md", { lines });
27289
27666
  }
27290
27667
  static renderScopedRules(component, rules) {
27291
27668
  const scopedRules = rules.filter((r) => {
@@ -27305,7 +27682,7 @@ var ClaudeRenderer = class _ClaudeRenderer {
27305
27682
  lines.push("");
27306
27683
  }
27307
27684
  lines.push(...rule.content.split("\n"));
27308
- new import_textfile2.TextFile(component, `.claude/rules/${rule.name}.md`, { lines });
27685
+ new import_textfile3.TextFile(component, `.claude/rules/${rule.name}.md`, { lines });
27309
27686
  }
27310
27687
  }
27311
27688
  static renderSettings(component, mcpServers, settings) {
@@ -27430,7 +27807,7 @@ var ClaudeRenderer = class _ClaudeRenderer {
27430
27807
  hasContent = true;
27431
27808
  }
27432
27809
  if (!hasContent) return;
27433
- new import_projen6.JsonFile(component, ".claude/settings.json", { obj });
27810
+ new import_projen7.JsonFile(component, ".claude/settings.json", { obj });
27434
27811
  }
27435
27812
  static buildSandboxObj(sandbox) {
27436
27813
  const obj = {};
@@ -27517,12 +27894,12 @@ var ClaudeRenderer = class _ClaudeRenderer {
27517
27894
  lines.push("---");
27518
27895
  lines.push("");
27519
27896
  lines.push(...skill.instructions.split("\n"));
27520
- new import_textfile2.TextFile(component, `.claude/skills/${skill.name}/SKILL.md`, {
27897
+ new import_textfile3.TextFile(component, `.claude/skills/${skill.name}/SKILL.md`, {
27521
27898
  lines
27522
27899
  });
27523
27900
  if (skill.referenceFiles && skill.referenceFiles.length > 0) {
27524
27901
  for (const file of skill.referenceFiles) {
27525
- new import_textfile2.TextFile(component, `.claude/skills/${skill.name}/${file.path}`, {
27902
+ new import_textfile3.TextFile(component, `.claude/skills/${skill.name}/${file.path}`, {
27526
27903
  lines: file.content.split("\n")
27527
27904
  });
27528
27905
  }
@@ -27580,7 +27957,7 @@ var ClaudeRenderer = class _ClaudeRenderer {
27580
27957
  lines.push("---");
27581
27958
  lines.push("");
27582
27959
  lines.push(...agent.prompt.split("\n"));
27583
- new import_textfile2.TextFile(component, `.claude/agents/${agent.name}.md`, { lines });
27960
+ new import_textfile3.TextFile(component, `.claude/agents/${agent.name}.md`, { lines });
27584
27961
  }
27585
27962
  }
27586
27963
  static buildMcpServerObj(config) {
@@ -27597,7 +27974,7 @@ var ClaudeRenderer = class _ClaudeRenderer {
27597
27974
  }
27598
27975
  static renderProcedures(component, procedures) {
27599
27976
  for (const proc of procedures) {
27600
- new import_textfile2.TextFile(component, `.claude/procedures/${proc.name}`, {
27977
+ new import_textfile3.TextFile(component, `.claude/procedures/${proc.name}`, {
27601
27978
  lines: proc.content.split("\n"),
27602
27979
  executable: true
27603
27980
  });
@@ -27624,152 +28001,6 @@ var CopilotRenderer = class {
27624
28001
  }
27625
28002
  };
27626
28003
 
27627
- // src/agent/renderers/cursor-renderer.ts
27628
- var import_projen7 = require("projen");
27629
- var import_textfile3 = require("projen/lib/textfile");
27630
- var GENERATED_MARKER2 = "# ~~ Generated by @codedrifters/configulator. Edits welcome \u2014 please contribute improvements back. ~~";
27631
- var CursorRenderer = class _CursorRenderer {
27632
- /**
27633
- * Render all Cursor configuration files.
27634
- */
27635
- static render(component, rules, skills, subAgents, mcpServers, settings) {
27636
- _CursorRenderer.renderRules(component, rules);
27637
- _CursorRenderer.renderSkills(component, skills);
27638
- _CursorRenderer.renderSubAgents(component, subAgents);
27639
- _CursorRenderer.renderMcpServers(component, mcpServers);
27640
- _CursorRenderer.renderHooks(component, settings);
27641
- _CursorRenderer.renderIgnoreFiles(component, settings);
27642
- }
27643
- static renderRules(component, rules) {
27644
- for (const rule of rules) {
27645
- if (rule.platforms?.cursor?.exclude) continue;
27646
- const lines = [];
27647
- const description = rule.platforms?.cursor?.description ?? rule.description;
27648
- const isAlways = rule.scope === AGENT_RULE_SCOPE.ALWAYS;
27649
- lines.push("---");
27650
- lines.push(`description: "${description}"`);
27651
- lines.push(`alwaysApply: ${isAlways}`);
27652
- if (!isAlways && rule.filePatterns && rule.filePatterns.length > 0) {
27653
- lines.push(`path: ${JSON.stringify([...rule.filePatterns])}`);
27654
- }
27655
- lines.push("---");
27656
- lines.push("");
27657
- lines.push(...rule.content.split("\n"));
27658
- new import_textfile3.TextFile(component, `.cursor/rules/${rule.name}.mdc`, { lines });
27659
- }
27660
- }
27661
- static renderSkills(component, skills) {
27662
- for (const skill of skills) {
27663
- if (skill.platforms?.cursor?.exclude) continue;
27664
- const lines = [];
27665
- lines.push("---");
27666
- lines.push(`name: "${skill.name}"`);
27667
- lines.push(`description: "${skill.description}"`);
27668
- if (skill.disableModelInvocation) {
27669
- lines.push(`disable-model-invocation: true`);
27670
- }
27671
- if (skill.userInvocable === false) {
27672
- lines.push(`user-invocable: false`);
27673
- }
27674
- if (skill.context) {
27675
- lines.push(`context: "${skill.context}"`);
27676
- }
27677
- if (skill.agent) {
27678
- lines.push(`agent: "${skill.agent}"`);
27679
- }
27680
- if (skill.shell) {
27681
- lines.push(`shell: "${skill.shell}"`);
27682
- }
27683
- if (skill.allowedTools && skill.allowedTools.length > 0) {
27684
- lines.push(`allowed-tools:`);
27685
- for (const tool of skill.allowedTools) {
27686
- lines.push(` - "${tool}"`);
27687
- }
27688
- }
27689
- lines.push("---");
27690
- lines.push("");
27691
- lines.push(...skill.instructions.split("\n"));
27692
- new import_textfile3.TextFile(component, `.cursor/skills/${skill.name}/SKILL.md`, {
27693
- lines
27694
- });
27695
- if (skill.referenceFiles && skill.referenceFiles.length > 0) {
27696
- for (const file of skill.referenceFiles) {
27697
- new import_textfile3.TextFile(component, `.cursor/skills/${skill.name}/${file.path}`, {
27698
- lines: file.content.split("\n")
27699
- });
27700
- }
27701
- }
27702
- }
27703
- }
27704
- static renderSubAgents(component, subAgents) {
27705
- for (const agent of subAgents) {
27706
- if (agent.platforms?.cursor?.exclude) continue;
27707
- const lines = [];
27708
- lines.push("---");
27709
- lines.push(`name: ${agent.name}`);
27710
- lines.push(`description: >-`);
27711
- lines.push(` ${agent.description}`);
27712
- if (agent.platforms?.cursor?.readonly) {
27713
- lines.push(`readonly: true`);
27714
- }
27715
- if (agent.platforms?.cursor?.isBackground) {
27716
- lines.push(`is_background: true`);
27717
- }
27718
- lines.push("---");
27719
- lines.push("");
27720
- lines.push(...agent.prompt.split("\n"));
27721
- new import_textfile3.TextFile(component, `.cursor/agents/${agent.name}.md`, { lines });
27722
- }
27723
- }
27724
- static renderMcpServers(component, mcpServers) {
27725
- const serverNames = Object.keys(mcpServers);
27726
- if (serverNames.length === 0) return;
27727
- const obj = { mcpServers: {} };
27728
- const servers = obj.mcpServers;
27729
- for (const [name, config] of Object.entries(mcpServers)) {
27730
- const server = {};
27731
- if (config.transport) server.transport = config.transport;
27732
- if (config.command) server.command = config.command;
27733
- if (config.args) server.args = [...config.args];
27734
- if (config.url) server.url = config.url;
27735
- if (config.headers && Object.keys(config.headers).length > 0) {
27736
- server.headers = { ...config.headers };
27737
- }
27738
- if (config.env) server.env = { ...config.env };
27739
- servers[name] = server;
27740
- }
27741
- new import_projen7.JsonFile(component, ".cursor/mcp.json", { obj });
27742
- }
27743
- static renderHooks(component, settings) {
27744
- if (!settings?.hooks) return;
27745
- const hooks = {};
27746
- const hookEntries = settings.hooks;
27747
- for (const [event, actions] of Object.entries(hookEntries)) {
27748
- if (actions && actions.length > 0) {
27749
- hooks[event] = actions.map((h) => ({
27750
- command: h.command
27751
- }));
27752
- }
27753
- }
27754
- if (Object.keys(hooks).length === 0) return;
27755
- new import_projen7.JsonFile(component, ".cursor/hooks.json", {
27756
- obj: { version: 1, hooks }
27757
- });
27758
- }
27759
- static renderIgnoreFiles(component, settings) {
27760
- if (settings?.ignorePatterns && settings.ignorePatterns.length > 0) {
27761
- new import_textfile3.TextFile(component, ".cursorignore", {
27762
- lines: [GENERATED_MARKER2, "", ...settings.ignorePatterns]
27763
- });
27764
- }
27765
- if (settings?.indexingIgnorePatterns && settings.indexingIgnorePatterns.length > 0) {
27766
- new import_textfile3.TextFile(component, ".cursorindexingignore", {
27767
- lines: [GENERATED_MARKER2, "", ...settings.indexingIgnorePatterns]
27768
- });
27769
- }
27770
- }
27771
- };
27772
-
27773
28004
  // src/agent/agent-config.ts
27774
28005
  var DEFAULT_CLAUDE_ALLOW = [
27775
28006
  // ── Git ──────────────────────────────────────────────────────────────
@@ -27995,7 +28226,10 @@ var AgentConfig = class _AgentConfig extends import_projen8.Component {
27995
28226
  */
27996
28227
  get pathAwareBundles() {
27997
28228
  if (!this.cachedBundles) {
27998
- this.cachedBundles = buildBuiltInBundles(this.resolvedPaths);
28229
+ this.cachedBundles = buildBuiltInBundles(
28230
+ this.resolvedPaths,
28231
+ resolveIssueDefaults(this.options.issueDefaults)
28232
+ );
27999
28233
  }
28000
28234
  return this.cachedBundles;
28001
28235
  }
@@ -28041,6 +28275,7 @@ var AgentConfig = class _AgentConfig extends import_projen8.Component {
28041
28275
  this.project.gitignore.addPatterns(`/${resolvedRunRatio.stateFilePath}`);
28042
28276
  }
28043
28277
  validateUnblockDependentsConfig(this.options.unblockDependents);
28278
+ validateIssueDefaultsConfig(this.options.issueDefaults);
28044
28279
  const resolvedProgressFiles = validateProgressFilesConfig(
28045
28280
  this.options.progressFiles
28046
28281
  );
@@ -32916,6 +33151,8 @@ var TypeScriptConfig = class extends import_projen23.Component {
32916
33151
  DEFAULT_DISPATCH_MODEL,
32917
33152
  DEFAULT_DISPATCH_TO_HOUSEKEEPING_RATIO,
32918
33153
  DEFAULT_HOUSEKEEPING_MODEL,
33154
+ DEFAULT_ISSUE_PRIORITY,
33155
+ DEFAULT_ISSUE_STATUS,
32919
33156
  DEFAULT_ISSUE_TEMPLATES_BUNDLE_PATH_PATTERNS,
32920
33157
  DEFAULT_ISSUE_TEMPLATES_EMIT_CHECKER,
32921
33158
  DEFAULT_ISSUE_TEMPLATES_EMIT_STARTER,
@@ -32932,6 +33169,7 @@ var TypeScriptConfig = class extends import_projen23.Component {
32932
33169
  DEFAULT_PROGRESS_FILES_STALE_AFTER_HOURS,
32933
33170
  DEFAULT_PROGRESS_FILES_STATE_DIR,
32934
33171
  DEFAULT_REQUIRE_PRODUCT_CONTEXT,
33172
+ DEFAULT_RESOLVED_ISSUE_DEFAULTS,
32935
33173
  DEFAULT_SAMPLE_COMPILER_OPTIONS,
32936
33174
  DEFAULT_SCHEDULED_TASKS_ROOT,
32937
33175
  DEFAULT_SCHEDULED_TASK_ENTRIES,
@@ -32983,6 +33221,8 @@ var TypeScriptConfig = class extends import_projen23.Component {
32983
33221
  TypeScriptConfig,
32984
33222
  TypeScriptProject,
32985
33223
  UNKNOWN_TYPE_FALLBACK_TIER,
33224
+ VALID_PRIORITY_VALUES,
33225
+ VALID_STATUS_VALUES,
32986
33226
  VERSION,
32987
33227
  VERSION_KEYS_SKIP,
32988
33228
  VERSION_NPM_PACKAGES,
@@ -33041,6 +33281,7 @@ var TypeScriptConfig = class extends import_projen23.Component {
33041
33281
  githubWorkflowBundle,
33042
33282
  industryDiscoveryBundle,
33043
33283
  jestBundle,
33284
+ labelsForPhase,
33044
33285
  maintenanceAuditBundle,
33045
33286
  meetingAnalysisBundle,
33046
33287
  orchestratorBundle,
@@ -33094,6 +33335,7 @@ var TypeScriptConfig = class extends import_projen23.Component {
33094
33335
  resolveAgentTiers,
33095
33336
  resolveAstroProjectOutdir,
33096
33337
  resolveAwsCdkProjectOutdir,
33338
+ resolveIssueDefaults,
33097
33339
  resolveIssueTemplates,
33098
33340
  resolveModelAlias,
33099
33341
  resolveOrchestratorAssets,
@@ -33117,6 +33359,7 @@ var TypeScriptConfig = class extends import_projen23.Component {
33117
33359
  typescriptBundle,
33118
33360
  upstreamConfigulatorDocsBundle,
33119
33361
  validateAgentTierConfig,
33362
+ validateIssueDefaultsConfig,
33120
33363
  validateIssueTemplatesConfig,
33121
33364
  validateMonorepoLayout,
33122
33365
  validateProgressFilesConfig,