diff --git a/.github/workflows/agent-performance-analyzer.lock.yml b/.github/workflows/agent-performance-analyzer.lock.yml index dd7376b274..cdff26fe4f 100644 --- a/.github/workflows/agent-performance-analyzer.lock.yml +++ b/.github/workflows/agent-performance-analyzer.lock.yml @@ -308,7 +308,7 @@ jobs: }, "temporary_id": { "description": "Unique temporary identifier for referencing this issue before it's created. Format: 'aw_' followed by 3 to 8 alphanumeric characters (e.g., 'aw_abc1', 'aw_Test123'). Use '#aw_ID' in body text to reference other issues by their temporary_id; these are replaced with actual issue numbers after creation.", - "pattern": "^aw_[A-Za-z0-9]{4,8}$", + "pattern": "^aw_[A-Za-z0-9]{3,8}$", "type": "string" }, "title": { diff --git a/.github/workflows/bot-detection.lock.yml b/.github/workflows/bot-detection.lock.yml index 6521a0b5c0..e43bccd094 100644 --- a/.github/workflows/bot-detection.lock.yml +++ b/.github/workflows/bot-detection.lock.yml @@ -239,7 +239,7 @@ jobs: }, "temporary_id": { "description": "Unique temporary identifier for referencing this issue before it's created. Format: 'aw_' followed by 3 to 8 alphanumeric characters (e.g., 'aw_abc1', 'aw_Test123'). Use '#aw_ID' in body text to reference other issues by their temporary_id; these are replaced with actual issue numbers after creation.", - "pattern": "^aw_[A-Za-z0-9]{4,8}$", + "pattern": "^aw_[A-Za-z0-9]{3,8}$", "type": "string" }, "title": { diff --git a/.github/workflows/breaking-change-checker.lock.yml b/.github/workflows/breaking-change-checker.lock.yml index 6739443561..2b3c519e81 100644 --- a/.github/workflows/breaking-change-checker.lock.yml +++ b/.github/workflows/breaking-change-checker.lock.yml @@ -242,7 +242,7 @@ jobs: }, "temporary_id": { "description": "Unique temporary identifier for referencing this issue before it's created. Format: 'aw_' followed by 3 to 8 alphanumeric characters (e.g., 'aw_abc1', 'aw_Test123'). Use '#aw_ID' in body text to reference other issues by their temporary_id; these are replaced with actual issue numbers after creation.", - "pattern": "^aw_[A-Za-z0-9]{4,8}$", + "pattern": "^aw_[A-Za-z0-9]{3,8}$", "type": "string" }, "title": { diff --git a/.github/workflows/ci-doctor.lock.yml b/.github/workflows/ci-doctor.lock.yml index 635a89913f..5a09230f77 100644 --- a/.github/workflows/ci-doctor.lock.yml +++ b/.github/workflows/ci-doctor.lock.yml @@ -265,7 +265,7 @@ jobs: }, "temporary_id": { "description": "Unique temporary identifier for referencing this issue before it's created. Format: 'aw_' followed by 3 to 8 alphanumeric characters (e.g., 'aw_abc1', 'aw_Test123'). Use '#aw_ID' in body text to reference other issues by their temporary_id; these are replaced with actual issue numbers after creation.", - "pattern": "^aw_[A-Za-z0-9]{4,8}$", + "pattern": "^aw_[A-Za-z0-9]{3,8}$", "type": "string" }, "title": { diff --git a/.github/workflows/cli-consistency-checker.lock.yml b/.github/workflows/cli-consistency-checker.lock.yml index 26611ec7e7..1c04c98da2 100644 --- a/.github/workflows/cli-consistency-checker.lock.yml +++ b/.github/workflows/cli-consistency-checker.lock.yml @@ -240,7 +240,7 @@ jobs: }, "temporary_id": { "description": "Unique temporary identifier for referencing this issue before it's created. Format: 'aw_' followed by 3 to 8 alphanumeric characters (e.g., 'aw_abc1', 'aw_Test123'). Use '#aw_ID' in body text to reference other issues by their temporary_id; these are replaced with actual issue numbers after creation.", - "pattern": "^aw_[A-Za-z0-9]{4,8}$", + "pattern": "^aw_[A-Za-z0-9]{3,8}$", "type": "string" }, "title": { diff --git a/.github/workflows/cli-version-checker.lock.yml b/.github/workflows/cli-version-checker.lock.yml index f7dd5b7bd0..dc177d8744 100644 --- a/.github/workflows/cli-version-checker.lock.yml +++ b/.github/workflows/cli-version-checker.lock.yml @@ -261,7 +261,7 @@ jobs: }, "temporary_id": { "description": "Unique temporary identifier for referencing this issue before it's created. Format: 'aw_' followed by 3 to 8 alphanumeric characters (e.g., 'aw_abc1', 'aw_Test123'). Use '#aw_ID' in body text to reference other issues by their temporary_id; these are replaced with actual issue numbers after creation.", - "pattern": "^aw_[A-Za-z0-9]{4,8}$", + "pattern": "^aw_[A-Za-z0-9]{3,8}$", "type": "string" }, "title": { diff --git a/.github/workflows/daily-cli-performance.lock.yml b/.github/workflows/daily-cli-performance.lock.yml index f907f0e7eb..c4d07a2d72 100644 --- a/.github/workflows/daily-cli-performance.lock.yml +++ b/.github/workflows/daily-cli-performance.lock.yml @@ -251,7 +251,7 @@ jobs: }, "temporary_id": { "description": "Unique temporary identifier for referencing this issue before it's created. Format: 'aw_' followed by 3 to 8 alphanumeric characters (e.g., 'aw_abc1', 'aw_Test123'). Use '#aw_ID' in body text to reference other issues by their temporary_id; these are replaced with actual issue numbers after creation.", - "pattern": "^aw_[A-Za-z0-9]{4,8}$", + "pattern": "^aw_[A-Za-z0-9]{3,8}$", "type": "string" }, "title": { diff --git a/.github/workflows/daily-cli-tools-tester.lock.yml b/.github/workflows/daily-cli-tools-tester.lock.yml index 280ff3a361..8e2293a4bd 100644 --- a/.github/workflows/daily-cli-tools-tester.lock.yml +++ b/.github/workflows/daily-cli-tools-tester.lock.yml @@ -295,7 +295,7 @@ jobs: }, "temporary_id": { "description": "Unique temporary identifier for referencing this issue before it's created. Format: 'aw_' followed by 3 to 8 alphanumeric characters (e.g., 'aw_abc1', 'aw_Test123'). Use '#aw_ID' in body text to reference other issues by their temporary_id; these are replaced with actual issue numbers after creation.", - "pattern": "^aw_[A-Za-z0-9]{4,8}$", + "pattern": "^aw_[A-Za-z0-9]{3,8}$", "type": "string" }, "title": { diff --git a/.github/workflows/daily-file-diet.lock.yml b/.github/workflows/daily-file-diet.lock.yml index 011f11ccdb..a85cac6fa6 100644 --- a/.github/workflows/daily-file-diet.lock.yml +++ b/.github/workflows/daily-file-diet.lock.yml @@ -244,7 +244,7 @@ jobs: }, "temporary_id": { "description": "Unique temporary identifier for referencing this issue before it's created. Format: 'aw_' followed by 3 to 8 alphanumeric characters (e.g., 'aw_abc1', 'aw_Test123'). Use '#aw_ID' in body text to reference other issues by their temporary_id; these are replaced with actual issue numbers after creation.", - "pattern": "^aw_[A-Za-z0-9]{4,8}$", + "pattern": "^aw_[A-Za-z0-9]{3,8}$", "type": "string" }, "title": { diff --git a/.github/workflows/daily-mcp-concurrency-analysis.lock.yml b/.github/workflows/daily-mcp-concurrency-analysis.lock.yml index 15cc464460..17b019ecca 100644 --- a/.github/workflows/daily-mcp-concurrency-analysis.lock.yml +++ b/.github/workflows/daily-mcp-concurrency-analysis.lock.yml @@ -251,7 +251,7 @@ jobs: }, "temporary_id": { "description": "Unique temporary identifier for referencing this issue before it's created. Format: 'aw_' followed by 3 to 8 alphanumeric characters (e.g., 'aw_abc1', 'aw_Test123'). Use '#aw_ID' in body text to reference other issues by their temporary_id; these are replaced with actual issue numbers after creation.", - "pattern": "^aw_[A-Za-z0-9]{4,8}$", + "pattern": "^aw_[A-Za-z0-9]{3,8}$", "type": "string" }, "title": { diff --git a/.github/workflows/daily-multi-device-docs-tester.lock.yml b/.github/workflows/daily-multi-device-docs-tester.lock.yml index d0d703f570..66d4028c04 100644 --- a/.github/workflows/daily-multi-device-docs-tester.lock.yml +++ b/.github/workflows/daily-multi-device-docs-tester.lock.yml @@ -253,7 +253,7 @@ jobs: }, "temporary_id": { "description": "Unique temporary identifier for referencing this issue before it's created. Format: 'aw_' followed by 3 to 8 alphanumeric characters (e.g., 'aw_abc1', 'aw_Test123'). Use '#aw_ID' in body text to reference other issues by their temporary_id; these are replaced with actual issue numbers after creation.", - "pattern": "^aw_[A-Za-z0-9]{4,8}$", + "pattern": "^aw_[A-Za-z0-9]{3,8}$", "type": "string" }, "title": { diff --git a/.github/workflows/daily-safe-output-optimizer.lock.yml b/.github/workflows/daily-safe-output-optimizer.lock.yml index 2ad1b75056..d7a9ece596 100644 --- a/.github/workflows/daily-safe-output-optimizer.lock.yml +++ b/.github/workflows/daily-safe-output-optimizer.lock.yml @@ -323,7 +323,7 @@ jobs: }, "temporary_id": { "description": "Unique temporary identifier for referencing this issue before it's created. Format: 'aw_' followed by 3 to 8 alphanumeric characters (e.g., 'aw_abc1', 'aw_Test123'). Use '#aw_ID' in body text to reference other issues by their temporary_id; these are replaced with actual issue numbers after creation.", - "pattern": "^aw_[A-Za-z0-9]{4,8}$", + "pattern": "^aw_[A-Za-z0-9]{3,8}$", "type": "string" }, "title": { diff --git a/.github/workflows/daily-safe-outputs-conformance.lock.yml b/.github/workflows/daily-safe-outputs-conformance.lock.yml index 76de817e86..d7efd88a56 100644 --- a/.github/workflows/daily-safe-outputs-conformance.lock.yml +++ b/.github/workflows/daily-safe-outputs-conformance.lock.yml @@ -246,7 +246,7 @@ jobs: }, "temporary_id": { "description": "Unique temporary identifier for referencing this issue before it's created. Format: 'aw_' followed by 3 to 8 alphanumeric characters (e.g., 'aw_abc1', 'aw_Test123'). Use '#aw_ID' in body text to reference other issues by their temporary_id; these are replaced with actual issue numbers after creation.", - "pattern": "^aw_[A-Za-z0-9]{4,8}$", + "pattern": "^aw_[A-Za-z0-9]{3,8}$", "type": "string" }, "title": { diff --git a/.github/workflows/daily-security-red-team.lock.yml b/.github/workflows/daily-security-red-team.lock.yml index b877cba91a..2099baff56 100644 --- a/.github/workflows/daily-security-red-team.lock.yml +++ b/.github/workflows/daily-security-red-team.lock.yml @@ -246,7 +246,7 @@ jobs: }, "temporary_id": { "description": "Unique temporary identifier for referencing this issue before it's created. Format: 'aw_' followed by 3 to 8 alphanumeric characters (e.g., 'aw_abc1', 'aw_Test123'). Use '#aw_ID' in body text to reference other issues by their temporary_id; these are replaced with actual issue numbers after creation.", - "pattern": "^aw_[A-Za-z0-9]{4,8}$", + "pattern": "^aw_[A-Za-z0-9]{3,8}$", "type": "string" }, "title": { diff --git a/.github/workflows/daily-syntax-error-quality.lock.yml b/.github/workflows/daily-syntax-error-quality.lock.yml index 3ccdeb7221..46818cd807 100644 --- a/.github/workflows/daily-syntax-error-quality.lock.yml +++ b/.github/workflows/daily-syntax-error-quality.lock.yml @@ -244,7 +244,7 @@ jobs: }, "temporary_id": { "description": "Unique temporary identifier for referencing this issue before it's created. Format: 'aw_' followed by 3 to 8 alphanumeric characters (e.g., 'aw_abc1', 'aw_Test123'). Use '#aw_ID' in body text to reference other issues by their temporary_id; these are replaced with actual issue numbers after creation.", - "pattern": "^aw_[A-Za-z0-9]{4,8}$", + "pattern": "^aw_[A-Za-z0-9]{3,8}$", "type": "string" }, "title": { diff --git a/.github/workflows/daily-team-status.lock.yml b/.github/workflows/daily-team-status.lock.yml index 17ada4c81c..965570cf4d 100644 --- a/.github/workflows/daily-team-status.lock.yml +++ b/.github/workflows/daily-team-status.lock.yml @@ -250,7 +250,7 @@ jobs: }, "temporary_id": { "description": "Unique temporary identifier for referencing this issue before it's created. Format: 'aw_' followed by 3 to 8 alphanumeric characters (e.g., 'aw_abc1', 'aw_Test123'). Use '#aw_ID' in body text to reference other issues by their temporary_id; these are replaced with actual issue numbers after creation.", - "pattern": "^aw_[A-Za-z0-9]{4,8}$", + "pattern": "^aw_[A-Za-z0-9]{3,8}$", "type": "string" }, "title": { diff --git a/.github/workflows/daily-testify-uber-super-expert.lock.yml b/.github/workflows/daily-testify-uber-super-expert.lock.yml index f3ff634366..9cbf9297d3 100644 --- a/.github/workflows/daily-testify-uber-super-expert.lock.yml +++ b/.github/workflows/daily-testify-uber-super-expert.lock.yml @@ -254,7 +254,7 @@ jobs: }, "temporary_id": { "description": "Unique temporary identifier for referencing this issue before it's created. Format: 'aw_' followed by 3 to 8 alphanumeric characters (e.g., 'aw_abc1', 'aw_Test123'). Use '#aw_ID' in body text to reference other issues by their temporary_id; these are replaced with actual issue numbers after creation.", - "pattern": "^aw_[A-Za-z0-9]{4,8}$", + "pattern": "^aw_[A-Za-z0-9]{3,8}$", "type": "string" }, "title": { diff --git a/.github/workflows/deep-report.lock.yml b/.github/workflows/deep-report.lock.yml index 6a1659183e..956525a4d1 100644 --- a/.github/workflows/deep-report.lock.yml +++ b/.github/workflows/deep-report.lock.yml @@ -332,7 +332,7 @@ jobs: }, "temporary_id": { "description": "Unique temporary identifier for referencing this issue before it's created. Format: 'aw_' followed by 3 to 8 alphanumeric characters (e.g., 'aw_abc1', 'aw_Test123'). Use '#aw_ID' in body text to reference other issues by their temporary_id; these are replaced with actual issue numbers after creation.", - "pattern": "^aw_[A-Za-z0-9]{4,8}$", + "pattern": "^aw_[A-Za-z0-9]{3,8}$", "type": "string" }, "title": { diff --git a/.github/workflows/delight.lock.yml b/.github/workflows/delight.lock.yml index ef6353f33f..f858e0ee95 100644 --- a/.github/workflows/delight.lock.yml +++ b/.github/workflows/delight.lock.yml @@ -255,7 +255,7 @@ jobs: }, "temporary_id": { "description": "Unique temporary identifier for referencing this issue before it's created. Format: 'aw_' followed by 3 to 8 alphanumeric characters (e.g., 'aw_abc1', 'aw_Test123'). Use '#aw_ID' in body text to reference other issues by their temporary_id; these are replaced with actual issue numbers after creation.", - "pattern": "^aw_[A-Za-z0-9]{4,8}$", + "pattern": "^aw_[A-Za-z0-9]{3,8}$", "type": "string" }, "title": { diff --git a/.github/workflows/dependabot-burner.lock.yml b/.github/workflows/dependabot-burner.lock.yml index a9939d8079..5c3974c96a 100644 --- a/.github/workflows/dependabot-burner.lock.yml +++ b/.github/workflows/dependabot-burner.lock.yml @@ -237,7 +237,7 @@ jobs: }, "temporary_id": { "description": "Unique temporary identifier for referencing this issue before it's created. Format: 'aw_' followed by 3 to 8 alphanumeric characters (e.g., 'aw_abc1', 'aw_Test123'). Use '#aw_ID' in body text to reference other issues by their temporary_id; these are replaced with actual issue numbers after creation.", - "pattern": "^aw_[A-Za-z0-9]{4,8}$", + "pattern": "^aw_[A-Za-z0-9]{3,8}$", "type": "string" }, "title": { diff --git a/.github/workflows/dependabot-go-checker.lock.yml b/.github/workflows/dependabot-go-checker.lock.yml index 6814213f4d..25ab0c3265 100644 --- a/.github/workflows/dependabot-go-checker.lock.yml +++ b/.github/workflows/dependabot-go-checker.lock.yml @@ -241,7 +241,7 @@ jobs: }, "temporary_id": { "description": "Unique temporary identifier for referencing this issue before it's created. Format: 'aw_' followed by 3 to 8 alphanumeric characters (e.g., 'aw_abc1', 'aw_Test123'). Use '#aw_ID' in body text to reference other issues by their temporary_id; these are replaced with actual issue numbers after creation.", - "pattern": "^aw_[A-Za-z0-9]{4,8}$", + "pattern": "^aw_[A-Za-z0-9]{3,8}$", "type": "string" }, "title": { diff --git a/.github/workflows/dev.lock.yml b/.github/workflows/dev.lock.yml index f543d76ca7..f35fae0e62 100644 --- a/.github/workflows/dev.lock.yml +++ b/.github/workflows/dev.lock.yml @@ -239,7 +239,7 @@ jobs: }, "temporary_id": { "description": "Unique temporary identifier for referencing this issue before it's created. Format: 'aw_' followed by 3 to 8 alphanumeric characters (e.g., 'aw_abc1', 'aw_Test123'). Use '#aw_ID' in body text to reference other issues by their temporary_id; these are replaced with actual issue numbers after creation.", - "pattern": "^aw_[A-Za-z0-9]{4,8}$", + "pattern": "^aw_[A-Za-z0-9]{3,8}$", "type": "string" }, "title": { diff --git a/.github/workflows/discussion-task-miner.lock.yml b/.github/workflows/discussion-task-miner.lock.yml index 71173b563e..37d5ccd08d 100644 --- a/.github/workflows/discussion-task-miner.lock.yml +++ b/.github/workflows/discussion-task-miner.lock.yml @@ -256,7 +256,7 @@ jobs: }, "temporary_id": { "description": "Unique temporary identifier for referencing this issue before it's created. Format: 'aw_' followed by 3 to 8 alphanumeric characters (e.g., 'aw_abc1', 'aw_Test123'). Use '#aw_ID' in body text to reference other issues by their temporary_id; these are replaced with actual issue numbers after creation.", - "pattern": "^aw_[A-Za-z0-9]{4,8}$", + "pattern": "^aw_[A-Za-z0-9]{3,8}$", "type": "string" }, "title": { diff --git a/.github/workflows/duplicate-code-detector.lock.yml b/.github/workflows/duplicate-code-detector.lock.yml index 7fc53d9ab6..d15fd1c52d 100644 --- a/.github/workflows/duplicate-code-detector.lock.yml +++ b/.github/workflows/duplicate-code-detector.lock.yml @@ -246,7 +246,7 @@ jobs: }, "temporary_id": { "description": "Unique temporary identifier for referencing this issue before it's created. Format: 'aw_' followed by 3 to 8 alphanumeric characters (e.g., 'aw_abc1', 'aw_Test123'). Use '#aw_ID' in body text to reference other issues by their temporary_id; these are replaced with actual issue numbers after creation.", - "pattern": "^aw_[A-Za-z0-9]{4,8}$", + "pattern": "^aw_[A-Za-z0-9]{3,8}$", "type": "string" }, "title": { diff --git a/.github/workflows/go-pattern-detector.lock.yml b/.github/workflows/go-pattern-detector.lock.yml index 7420d44f1d..82fd2b4540 100644 --- a/.github/workflows/go-pattern-detector.lock.yml +++ b/.github/workflows/go-pattern-detector.lock.yml @@ -249,7 +249,7 @@ jobs: }, "temporary_id": { "description": "Unique temporary identifier for referencing this issue before it's created. Format: 'aw_' followed by 3 to 8 alphanumeric characters (e.g., 'aw_abc1', 'aw_Test123'). Use '#aw_ID' in body text to reference other issues by their temporary_id; these are replaced with actual issue numbers after creation.", - "pattern": "^aw_[A-Za-z0-9]{4,8}$", + "pattern": "^aw_[A-Za-z0-9]{3,8}$", "type": "string" }, "title": { diff --git a/.github/workflows/gpclean.lock.yml b/.github/workflows/gpclean.lock.yml index 526b202dc4..9a4c092a9d 100644 --- a/.github/workflows/gpclean.lock.yml +++ b/.github/workflows/gpclean.lock.yml @@ -256,7 +256,7 @@ jobs: }, "temporary_id": { "description": "Unique temporary identifier for referencing this issue before it's created. Format: 'aw_' followed by 3 to 8 alphanumeric characters (e.g., 'aw_abc1', 'aw_Test123'). Use '#aw_ID' in body text to reference other issues by their temporary_id; these are replaced with actual issue numbers after creation.", - "pattern": "^aw_[A-Za-z0-9]{4,8}$", + "pattern": "^aw_[A-Za-z0-9]{3,8}$", "type": "string" }, "title": { diff --git a/.github/workflows/issue-arborist.lock.yml b/.github/workflows/issue-arborist.lock.yml index 47d37cc232..1b2636abd7 100644 --- a/.github/workflows/issue-arborist.lock.yml +++ b/.github/workflows/issue-arborist.lock.yml @@ -255,7 +255,7 @@ jobs: }, "temporary_id": { "description": "Unique temporary identifier for referencing this issue before it's created. Format: 'aw_' followed by 3 to 8 alphanumeric characters (e.g., 'aw_abc1', 'aw_Test123'). Use '#aw_ID' in body text to reference other issues by their temporary_id; these are replaced with actual issue numbers after creation.", - "pattern": "^aw_[A-Za-z0-9]{4,8}$", + "pattern": "^aw_[A-Za-z0-9]{3,8}$", "type": "string" }, "title": { diff --git a/.github/workflows/plan.lock.yml b/.github/workflows/plan.lock.yml index 343580aff1..e19cf15700 100644 --- a/.github/workflows/plan.lock.yml +++ b/.github/workflows/plan.lock.yml @@ -254,7 +254,7 @@ jobs: }, "temporary_id": { "description": "Unique temporary identifier for referencing this issue before it's created. Format: 'aw_' followed by 3 to 8 alphanumeric characters (e.g., 'aw_abc1', 'aw_Test123'). Use '#aw_ID' in body text to reference other issues by their temporary_id; these are replaced with actual issue numbers after creation.", - "pattern": "^aw_[A-Za-z0-9]{4,8}$", + "pattern": "^aw_[A-Za-z0-9]{3,8}$", "type": "string" }, "title": { diff --git a/.github/workflows/poem-bot.lock.yml b/.github/workflows/poem-bot.lock.yml index 094452d87f..9ad8fc90f0 100644 --- a/.github/workflows/poem-bot.lock.yml +++ b/.github/workflows/poem-bot.lock.yml @@ -277,7 +277,7 @@ jobs: }, "temporary_id": { "description": "Unique temporary identifier for referencing this issue before it's created. Format: 'aw_' followed by 3 to 8 alphanumeric characters (e.g., 'aw_abc1', 'aw_Test123'). Use '#aw_ID' in body text to reference other issues by their temporary_id; these are replaced with actual issue numbers after creation.", - "pattern": "^aw_[A-Za-z0-9]{4,8}$", + "pattern": "^aw_[A-Za-z0-9]{3,8}$", "type": "string" }, "title": { diff --git a/.github/workflows/pr-triage-agent.lock.yml b/.github/workflows/pr-triage-agent.lock.yml index b472f0ba17..7e04b17849 100644 --- a/.github/workflows/pr-triage-agent.lock.yml +++ b/.github/workflows/pr-triage-agent.lock.yml @@ -249,7 +249,7 @@ jobs: }, "temporary_id": { "description": "Unique temporary identifier for referencing this issue before it's created. Format: 'aw_' followed by 3 to 8 alphanumeric characters (e.g., 'aw_abc1', 'aw_Test123'). Use '#aw_ID' in body text to reference other issues by their temporary_id; these are replaced with actual issue numbers after creation.", - "pattern": "^aw_[A-Za-z0-9]{4,8}$", + "pattern": "^aw_[A-Za-z0-9]{3,8}$", "type": "string" }, "title": { diff --git a/.github/workflows/security-compliance.lock.yml b/.github/workflows/security-compliance.lock.yml index 5882780dc2..c0fb3c221b 100644 --- a/.github/workflows/security-compliance.lock.yml +++ b/.github/workflows/security-compliance.lock.yml @@ -255,7 +255,7 @@ jobs: }, "temporary_id": { "description": "Unique temporary identifier for referencing this issue before it's created. Format: 'aw_' followed by 3 to 8 alphanumeric characters (e.g., 'aw_abc1', 'aw_Test123'). Use '#aw_ID' in body text to reference other issues by their temporary_id; these are replaced with actual issue numbers after creation.", - "pattern": "^aw_[A-Za-z0-9]{4,8}$", + "pattern": "^aw_[A-Za-z0-9]{3,8}$", "type": "string" }, "title": { diff --git a/.github/workflows/semantic-function-refactor.lock.yml b/.github/workflows/semantic-function-refactor.lock.yml index fd33028d35..ca8f2372c9 100644 --- a/.github/workflows/semantic-function-refactor.lock.yml +++ b/.github/workflows/semantic-function-refactor.lock.yml @@ -247,7 +247,7 @@ jobs: }, "temporary_id": { "description": "Unique temporary identifier for referencing this issue before it's created. Format: 'aw_' followed by 3 to 8 alphanumeric characters (e.g., 'aw_abc1', 'aw_Test123'). Use '#aw_ID' in body text to reference other issues by their temporary_id; these are replaced with actual issue numbers after creation.", - "pattern": "^aw_[A-Za-z0-9]{4,8}$", + "pattern": "^aw_[A-Za-z0-9]{3,8}$", "type": "string" }, "title": { diff --git a/.github/workflows/smoke-claude.lock.yml b/.github/workflows/smoke-claude.lock.yml index 7999678cae..d4401d8d74 100644 --- a/.github/workflows/smoke-claude.lock.yml +++ b/.github/workflows/smoke-claude.lock.yml @@ -348,7 +348,7 @@ jobs: }, "temporary_id": { "description": "Unique temporary identifier for referencing this issue before it's created. Format: 'aw_' followed by 3 to 8 alphanumeric characters (e.g., 'aw_abc1', 'aw_Test123'). Use '#aw_ID' in body text to reference other issues by their temporary_id; these are replaced with actual issue numbers after creation.", - "pattern": "^aw_[A-Za-z0-9]{4,8}$", + "pattern": "^aw_[A-Za-z0-9]{3,8}$", "type": "string" }, "title": { diff --git a/.github/workflows/smoke-codex.lock.yml b/.github/workflows/smoke-codex.lock.yml index aa6e422d37..d4c0052c5d 100644 --- a/.github/workflows/smoke-codex.lock.yml +++ b/.github/workflows/smoke-codex.lock.yml @@ -287,7 +287,7 @@ jobs: }, "temporary_id": { "description": "Unique temporary identifier for referencing this issue before it's created. Format: 'aw_' followed by 3 to 8 alphanumeric characters (e.g., 'aw_abc1', 'aw_Test123'). Use '#aw_ID' in body text to reference other issues by their temporary_id; these are replaced with actual issue numbers after creation.", - "pattern": "^aw_[A-Za-z0-9]{4,8}$", + "pattern": "^aw_[A-Za-z0-9]{3,8}$", "type": "string" }, "title": { diff --git a/.github/workflows/smoke-copilot-sdk.lock.yml b/.github/workflows/smoke-copilot-sdk.lock.yml index 9660da0376..4de072281e 100644 --- a/.github/workflows/smoke-copilot-sdk.lock.yml +++ b/.github/workflows/smoke-copilot-sdk.lock.yml @@ -328,7 +328,7 @@ jobs: }, "temporary_id": { "description": "Unique temporary identifier for referencing this issue before it's created. Format: 'aw_' followed by 3 to 8 alphanumeric characters (e.g., 'aw_abc1', 'aw_Test123'). Use '#aw_ID' in body text to reference other issues by their temporary_id; these are replaced with actual issue numbers after creation.", - "pattern": "^aw_[A-Za-z0-9]{4,8}$", + "pattern": "^aw_[A-Za-z0-9]{3,8}$", "type": "string" }, "title": { diff --git a/.github/workflows/smoke-copilot.lock.yml b/.github/workflows/smoke-copilot.lock.yml index 5f7980730f..7c702c2e03 100644 --- a/.github/workflows/smoke-copilot.lock.yml +++ b/.github/workflows/smoke-copilot.lock.yml @@ -338,7 +338,7 @@ jobs: }, "temporary_id": { "description": "Unique temporary identifier for referencing this issue before it's created. Format: 'aw_' followed by 3 to 8 alphanumeric characters (e.g., 'aw_abc1', 'aw_Test123'). Use '#aw_ID' in body text to reference other issues by their temporary_id; these are replaced with actual issue numbers after creation.", - "pattern": "^aw_[A-Za-z0-9]{4,8}$", + "pattern": "^aw_[A-Za-z0-9]{3,8}$", "type": "string" }, "title": { diff --git a/.github/workflows/smoke-opencode.lock.yml b/.github/workflows/smoke-opencode.lock.yml index 34f48fa3c7..3d45bc80cb 100644 --- a/.github/workflows/smoke-opencode.lock.yml +++ b/.github/workflows/smoke-opencode.lock.yml @@ -268,7 +268,7 @@ jobs: }, "temporary_id": { "description": "Unique temporary identifier for referencing this issue before it's created. Format: 'aw_' followed by 3 to 8 alphanumeric characters (e.g., 'aw_abc1', 'aw_Test123'). Use '#aw_ID' in body text to reference other issues by their temporary_id; these are replaced with actual issue numbers after creation.", - "pattern": "^aw_[A-Za-z0-9]{4,8}$", + "pattern": "^aw_[A-Za-z0-9]{3,8}$", "type": "string" }, "title": { diff --git a/.github/workflows/smoke-project.lock.yml b/.github/workflows/smoke-project.lock.yml index 5a494b48f4..eb2ebf8816 100644 --- a/.github/workflows/smoke-project.lock.yml +++ b/.github/workflows/smoke-project.lock.yml @@ -259,7 +259,7 @@ jobs: }, "temporary_id": { "description": "Unique temporary identifier for referencing this issue before it's created. Format: 'aw_' followed by 3 to 8 alphanumeric characters (e.g., 'aw_abc1', 'aw_Test123'). Use '#aw_ID' in body text to reference other issues by their temporary_id; these are replaced with actual issue numbers after creation.", - "pattern": "^aw_[A-Za-z0-9]{4,8}$", + "pattern": "^aw_[A-Za-z0-9]{3,8}$", "type": "string" }, "title": { @@ -446,8 +446,8 @@ jobs: "type": "string" }, "draft_issue_id": { - "description": "Temporary ID of an existing draft issue to update (e.g., 'aw_abc1', 'aw_Test123'). Use this to reference a draft created earlier with a matching temporary_id. When provided, draft_title is not required for updates.", - "pattern": "^aw_[A-Za-z0-9]{4,8}$", + "description": "Temporary ID of an existing draft issue to update (e.g., 'aw_abc1', '#aw_Test123'). Use this to reference a draft created earlier with a matching temporary_id. When provided, draft_title is not required for updates.", + "pattern": "^#?aw_[A-Za-z0-9]{3,8}$", "type": "string" }, "draft_title": { @@ -504,12 +504,12 @@ jobs: }, "project": { "description": "Full GitHub project URL (e.g., 'https://github.com/orgs/myorg/projects/42' or 'https://github.com/users/username/projects/5'), or a temporary project ID from a recent create_project call (e.g., '#aw_abc1', 'aw_Test123'). Project names or numbers alone are NOT accepted.", - "pattern": "^(https://github\\.com/(orgs|users)/[^/]+/projects/\\d+|#?aw_[A-Za-z0-9]{4,8})$", + "pattern": "^(https://github\\.com/(orgs|users)/[^/]+/projects/\\d+|#?aw_[A-Za-z0-9]{3,8})$", "type": "string" }, "temporary_id": { - "description": "Unique temporary identifier for this draft issue (e.g., 'aw_abc1', 'aw_Test123'). Provide this when creating a new draft to enable future updates via draft_issue_id. Format: 'aw_' followed by 3 to 8 alphanumeric characters.", - "pattern": "^aw_[A-Za-z0-9]{4,8}$", + "description": "Unique temporary identifier for this draft issue (e.g., 'aw_abc1', '#aw_Test123'). Provide this when creating a new draft to enable future updates via draft_issue_id. Format: optional leading '#', then 'aw_' followed by 3 to 8 alphanumeric characters.", + "pattern": "^#?aw_[A-Za-z0-9]{3,8}$", "type": "string" }, "view": { diff --git a/.github/workflows/smoke-temporary-id.lock.yml b/.github/workflows/smoke-temporary-id.lock.yml index 337b2991ea..df8068f5c5 100644 --- a/.github/workflows/smoke-temporary-id.lock.yml +++ b/.github/workflows/smoke-temporary-id.lock.yml @@ -258,7 +258,7 @@ jobs: }, "temporary_id": { "description": "Unique temporary identifier for referencing this issue before it's created. Format: 'aw_' followed by 3 to 8 alphanumeric characters (e.g., 'aw_abc1', 'aw_Test123'). Use '#aw_ID' in body text to reference other issues by their temporary_id; these are replaced with actual issue numbers after creation.", - "pattern": "^aw_[A-Za-z0-9]{4,8}$", + "pattern": "^aw_[A-Za-z0-9]{3,8}$", "type": "string" }, "title": { diff --git a/.github/workflows/stale-repo-identifier.lock.yml b/.github/workflows/stale-repo-identifier.lock.yml index 08da801113..e5ca5d336e 100644 --- a/.github/workflows/stale-repo-identifier.lock.yml +++ b/.github/workflows/stale-repo-identifier.lock.yml @@ -322,7 +322,7 @@ jobs: }, "temporary_id": { "description": "Unique temporary identifier for referencing this issue before it's created. Format: 'aw_' followed by 3 to 8 alphanumeric characters (e.g., 'aw_abc1', 'aw_Test123'). Use '#aw_ID' in body text to reference other issues by their temporary_id; these are replaced with actual issue numbers after creation.", - "pattern": "^aw_[A-Za-z0-9]{4,8}$", + "pattern": "^aw_[A-Za-z0-9]{3,8}$", "type": "string" }, "title": { diff --git a/.github/workflows/step-name-alignment.lock.yml b/.github/workflows/step-name-alignment.lock.yml index 9665d1bfc0..fc64ff9b00 100644 --- a/.github/workflows/step-name-alignment.lock.yml +++ b/.github/workflows/step-name-alignment.lock.yml @@ -256,7 +256,7 @@ jobs: }, "temporary_id": { "description": "Unique temporary identifier for referencing this issue before it's created. Format: 'aw_' followed by 3 to 8 alphanumeric characters (e.g., 'aw_abc1', 'aw_Test123'). Use '#aw_ID' in body text to reference other issues by their temporary_id; these are replaced with actual issue numbers after creation.", - "pattern": "^aw_[A-Za-z0-9]{4,8}$", + "pattern": "^aw_[A-Za-z0-9]{3,8}$", "type": "string" }, "title": { diff --git a/.github/workflows/super-linter.lock.yml b/.github/workflows/super-linter.lock.yml index 5b045aa3ce..0758c8299a 100644 --- a/.github/workflows/super-linter.lock.yml +++ b/.github/workflows/super-linter.lock.yml @@ -259,7 +259,7 @@ jobs: }, "temporary_id": { "description": "Unique temporary identifier for referencing this issue before it's created. Format: 'aw_' followed by 3 to 8 alphanumeric characters (e.g., 'aw_abc1', 'aw_Test123'). Use '#aw_ID' in body text to reference other issues by their temporary_id; these are replaced with actual issue numbers after creation.", - "pattern": "^aw_[A-Za-z0-9]{4,8}$", + "pattern": "^aw_[A-Za-z0-9]{3,8}$", "type": "string" }, "title": { diff --git a/.github/workflows/test-project-url-default.lock.yml b/.github/workflows/test-project-url-default.lock.yml index 6d1103190b..6d679928e3 100644 --- a/.github/workflows/test-project-url-default.lock.yml +++ b/.github/workflows/test-project-url-default.lock.yml @@ -281,8 +281,8 @@ jobs: "type": "string" }, "draft_issue_id": { - "description": "Temporary ID of an existing draft issue to update (e.g., 'aw_abc1', 'aw_Test123'). Use this to reference a draft created earlier with a matching temporary_id. When provided, draft_title is not required for updates.", - "pattern": "^aw_[A-Za-z0-9]{4,8}$", + "description": "Temporary ID of an existing draft issue to update (e.g., 'aw_abc1', '#aw_Test123'). Use this to reference a draft created earlier with a matching temporary_id. When provided, draft_title is not required for updates.", + "pattern": "^#?aw_[A-Za-z0-9]{3,8}$", "type": "string" }, "draft_title": { @@ -339,12 +339,12 @@ jobs: }, "project": { "description": "Full GitHub project URL (e.g., 'https://github.com/orgs/myorg/projects/42' or 'https://github.com/users/username/projects/5'), or a temporary project ID from a recent create_project call (e.g., '#aw_abc1', 'aw_Test123'). Project names or numbers alone are NOT accepted.", - "pattern": "^(https://github\\.com/(orgs|users)/[^/]+/projects/\\d+|#?aw_[A-Za-z0-9]{4,8})$", + "pattern": "^(https://github\\.com/(orgs|users)/[^/]+/projects/\\d+|#?aw_[A-Za-z0-9]{3,8})$", "type": "string" }, "temporary_id": { - "description": "Unique temporary identifier for this draft issue (e.g., 'aw_abc1', 'aw_Test123'). Provide this when creating a new draft to enable future updates via draft_issue_id. Format: 'aw_' followed by 3 to 8 alphanumeric characters.", - "pattern": "^aw_[A-Za-z0-9]{4,8}$", + "description": "Unique temporary identifier for this draft issue (e.g., 'aw_abc1', '#aw_Test123'). Provide this when creating a new draft to enable future updates via draft_issue_id. Format: optional leading '#', then 'aw_' followed by 3 to 8 alphanumeric characters.", + "pattern": "^#?aw_[A-Za-z0-9]{3,8}$", "type": "string" }, "view": { diff --git a/.github/workflows/video-analyzer.lock.yml b/.github/workflows/video-analyzer.lock.yml index ae26047311..fb72f05ee6 100644 --- a/.github/workflows/video-analyzer.lock.yml +++ b/.github/workflows/video-analyzer.lock.yml @@ -251,7 +251,7 @@ jobs: }, "temporary_id": { "description": "Unique temporary identifier for referencing this issue before it's created. Format: 'aw_' followed by 3 to 8 alphanumeric characters (e.g., 'aw_abc1', 'aw_Test123'). Use '#aw_ID' in body text to reference other issues by their temporary_id; these are replaced with actual issue numbers after creation.", - "pattern": "^aw_[A-Za-z0-9]{4,8}$", + "pattern": "^aw_[A-Za-z0-9]{3,8}$", "type": "string" }, "title": { diff --git a/.github/workflows/workflow-health-manager.lock.yml b/.github/workflows/workflow-health-manager.lock.yml index 8d1eca18b9..7cc9cebce6 100644 --- a/.github/workflows/workflow-health-manager.lock.yml +++ b/.github/workflows/workflow-health-manager.lock.yml @@ -253,7 +253,7 @@ jobs: }, "temporary_id": { "description": "Unique temporary identifier for referencing this issue before it's created. Format: 'aw_' followed by 3 to 8 alphanumeric characters (e.g., 'aw_abc1', 'aw_Test123'). Use '#aw_ID' in body text to reference other issues by their temporary_id; these are replaced with actual issue numbers after creation.", - "pattern": "^aw_[A-Za-z0-9]{4,8}$", + "pattern": "^aw_[A-Za-z0-9]{3,8}$", "type": "string" }, "title": { diff --git a/.github/workflows/workflow-normalizer.lock.yml b/.github/workflows/workflow-normalizer.lock.yml index 258a9a7f2f..f0f281d098 100644 --- a/.github/workflows/workflow-normalizer.lock.yml +++ b/.github/workflows/workflow-normalizer.lock.yml @@ -296,7 +296,7 @@ jobs: }, "temporary_id": { "description": "Unique temporary identifier for referencing this issue before it's created. Format: 'aw_' followed by 3 to 8 alphanumeric characters (e.g., 'aw_abc1', 'aw_Test123'). Use '#aw_ID' in body text to reference other issues by their temporary_id; these are replaced with actual issue numbers after creation.", - "pattern": "^aw_[A-Za-z0-9]{4,8}$", + "pattern": "^aw_[A-Za-z0-9]{3,8}$", "type": "string" }, "title": { diff --git a/.github/workflows/workflow-skill-extractor.lock.yml b/.github/workflows/workflow-skill-extractor.lock.yml index b5da844c30..4f70548681 100644 --- a/.github/workflows/workflow-skill-extractor.lock.yml +++ b/.github/workflows/workflow-skill-extractor.lock.yml @@ -242,7 +242,7 @@ jobs: }, "temporary_id": { "description": "Unique temporary identifier for referencing this issue before it's created. Format: 'aw_' followed by 3 to 8 alphanumeric characters (e.g., 'aw_abc1', 'aw_Test123'). Use '#aw_ID' in body text to reference other issues by their temporary_id; these are replaced with actual issue numbers after creation.", - "pattern": "^aw_[A-Za-z0-9]{4,8}$", + "pattern": "^aw_[A-Za-z0-9]{3,8}$", "type": "string" }, "title": { diff --git a/actions/setup/js/create_issue.test.cjs b/actions/setup/js/create_issue.test.cjs index b86129b563..4375ee72ee 100644 --- a/actions/setup/js/create_issue.test.cjs +++ b/actions/setup/js/create_issue.test.cjs @@ -318,7 +318,7 @@ describe("create_issue", () => { const handler = await main({}); const result = await handler({ title: "Test" }); - expect(result.temporaryId).toMatch(/^aw_[A-Za-z0-9]{4,8}$/); + expect(result.temporaryId).toMatch(/^aw_[A-Za-z0-9]{3,8}$/); }); it("should use provided temporary ID", async () => { diff --git a/actions/setup/js/create_issue_new_arch.test.cjs b/actions/setup/js/create_issue_new_arch.test.cjs index 49eb6d7f6d..00c9d4170f 100644 --- a/actions/setup/js/create_issue_new_arch.test.cjs +++ b/actions/setup/js/create_issue_new_arch.test.cjs @@ -123,7 +123,7 @@ describe("create_issue.cjs (New Handler Factory Architecture)", () => { const result = await handler(message, {}); expect(result.temporaryId).toBeTruthy(); - expect(result.temporaryId).toMatch(/^aw_[A-Za-z0-9]{4,8}$/i); + expect(result.temporaryId).toMatch(/^aw_[A-Za-z0-9]{3,8}$/i); }); it("should use provided temporary ID if available", async () => { diff --git a/actions/setup/js/safe_outputs_tools.json b/actions/setup/js/safe_outputs_tools.json index bead975bc8..8d45aa8b9d 100644 --- a/actions/setup/js/safe_outputs_tools.json +++ b/actions/setup/js/safe_outputs_tools.json @@ -702,7 +702,7 @@ "properties": { "project": { "type": "string", - "pattern": "^(https://github\\.com/(orgs|users)/[^/]+/projects/\\d+|#?aw_[A-Za-z0-9]{4,8})$", + "pattern": "^(https://github\\.com/(orgs|users)/[^/]+/projects/\\d+|#?aw_[A-Za-z0-9]{3,8})$", "description": "Full GitHub project URL (e.g., 'https://github.com/orgs/myorg/projects/42' or 'https://github.com/users/username/projects/5'), or a temporary project ID from a recent create_project call (e.g., '#aw_abc1', 'aw_Test123'). Project names or numbers alone are NOT accepted." }, "operation": { @@ -729,12 +729,12 @@ }, "draft_issue_id": { "type": "string", - "pattern": "^#?aw_[A-Za-z0-9]{4,8}$", + "pattern": "^#?aw_[A-Za-z0-9]{3,8}$", "description": "Temporary ID of an existing draft issue to update (e.g., 'aw_abc1', '#aw_Test123'). Use this to reference a draft created earlier with a matching temporary_id. When provided, draft_title is not required for updates." }, "temporary_id": { "type": "string", - "pattern": "^#?aw_[A-Za-z0-9]{4,8}$", + "pattern": "^#?aw_[A-Za-z0-9]{3,8}$", "description": "Unique temporary identifier for this draft issue (e.g., 'aw_abc1', '#aw_Test123'). Provide this when creating a new draft to enable future updates via draft_issue_id. Format: optional leading '#', then 'aw_' followed by 3 to 8 alphanumeric characters." }, "fields": { @@ -850,7 +850,7 @@ }, "item_url": { "type": "string", - "pattern": "^(https://github\\\\.com/[^/]+/[^/]+/issues/(\\\\d+|#?aw_[A-Za-z0-9]{4,8})|#?aw_[A-Za-z0-9]{4,8})$", + "pattern": "^(https://github\\\\.com/[^/]+/[^/]+/issues/(\\\\d+|#?aw_[A-Za-z0-9]{3,8})|#?aw_[A-Za-z0-9]{3,8})$", "description": "Optional GitHub issue URL or temporary ID to add as the first item to the project. Accepts either a full URL (e.g., 'https://github.com/owner/repo/issues/123'), a URL with temporary ID (e.g., 'https://github.com/owner/repo/issues/aw_abc1'), or a plain temporary ID (e.g., 'aw_abc1', '#aw_Test123') from a previously created issue in the same workflow run." }, "temporary_id": { diff --git a/actions/setup/js/update_project.cjs b/actions/setup/js/update_project.cjs index 6fded39819..2fc17bcdcc 100644 --- a/actions/setup/js/update_project.cjs +++ b/actions/setup/js/update_project.cjs @@ -1227,10 +1227,11 @@ async function main(config = {}, githubClient = null) { const projectStr = effectiveProjectUrl.trim(); const projectWithoutHash = projectStr.startsWith("#") ? projectStr.substring(1) : projectStr; - // Check if it's a temporary ID (aw_XXXXXXXXXXXX) - if (/^aw_[0-9a-f]{12}$/i.test(projectWithoutHash)) { - // Look up in the unified temporaryIdMap - const resolved = tempIdMap.get(projectWithoutHash.toLowerCase()); + // Check if it's a temporary ID using the canonical pattern (aw_XXX to aw_XXXXXXXX) + if (isTemporaryId(projectWithoutHash)) { + // Look up in the unified temporaryIdMap using normalized (lowercase) ID + const normalizedId = normalizeTemporaryId(projectWithoutHash); + const resolved = tempIdMap.get(normalizedId); if (resolved && typeof resolved === "object" && "projectUrl" in resolved && resolved.projectUrl) { core.info(`Resolved temporary project ID ${projectStr} to ${resolved.projectUrl}`); effectiveProjectUrl = resolved.projectUrl; @@ -1243,6 +1244,23 @@ async function main(config = {}, githubClient = null) { // Create effective message with resolved project URL const resolvedMessage = { ...message, project: effectiveProjectUrl }; + const hasContentNumber = resolvedMessage.content_number !== undefined && resolvedMessage.content_number !== null && String(resolvedMessage.content_number).trim() !== ""; + const hasIssue = resolvedMessage.issue !== undefined && resolvedMessage.issue !== null && String(resolvedMessage.issue).trim() !== ""; + const hasPullRequest = resolvedMessage.pull_request !== undefined && resolvedMessage.pull_request !== null && String(resolvedMessage.pull_request).trim() !== ""; + if (resolvedMessage.content_type !== "draft_issue" && (hasContentNumber || hasIssue || hasPullRequest)) { + const rawContentNumber = hasContentNumber ? resolvedMessage.content_number : hasIssue ? resolvedMessage.issue : resolvedMessage.pull_request; + const sanitizedContentNumber = typeof rawContentNumber === "number" ? rawContentNumber.toString() : String(rawContentNumber).trim(); + const resolved = resolveIssueNumber(sanitizedContentNumber, tempIdMap); + if (resolved.wasTemporaryId && !resolved.resolved) { + core.info(`Deferring update_project: unresolved temporary ID (${sanitizedContentNumber})`); + return { + success: false, + deferred: true, + error: resolved.errorMessage || `Unresolved temporary ID: ${sanitizedContentNumber}`, + }; + } + } + // Store the first project URL for view creation if (!firstProjectUrl && effectiveProjectUrl) { firstProjectUrl = effectiveProjectUrl; diff --git a/actions/setup/js/update_project.test.cjs b/actions/setup/js/update_project.test.cjs index 557d14c483..52b071eda7 100644 --- a/actions/setup/js/update_project.test.cjs +++ b/actions/setup/js/update_project.test.cjs @@ -119,6 +119,30 @@ describe("update_project handler config: field_definitions", () => { }); }); +describe("update_project handler deferral", () => { + it("defers when content_number is an unresolved temporary ID", async () => { + const projectUrl = "https://github.com/orgs/testowner/projects/60"; + + const handler = await updateProjectHandlerFactory({ max: 10 }); + + const result = await handler( + { + type: "update_project", + project: projectUrl, + content_type: "issue", + content_number: "aw_missing1", + }, + {}, + new Map() + ); + + expect(result.success).toBe(false); + expect(result.deferred).toBe(true); + expect(result.error).toMatch(/Temporary ID 'aw_missing1' not found in map/i); + expect(mockGithub.graphql).not.toHaveBeenCalled(); + }); +}); + describe("update_project token guardrails", () => { it("fails fast with a clear error when authenticated as github-actions[bot]", async () => { delete process.env.GH_AW_PROJECT_GITHUB_TOKEN; @@ -1771,3 +1795,145 @@ describe("updateProject", () => { expect(result.error).toContain("transient GitHub API error"); }); }); + +describe("update_project temporary project ID resolution", () => { + let mockSetup; + let messageHandler; + + beforeEach(() => { + vi.clearAllMocks(); + + // Reset mock implementation + mockGithub.graphql.mockReset(); + + // Create a minimal mock setup for the handler + mockSetup = { + core: mockCore, + github: mockGithub, + context: mockContext, + updateProjectHandlerFactory, + }; + }); + + afterEach(() => { + vi.clearAllMocks(); + }); + + it("resolves temporary project ID with 8 alphanumeric characters (generated format)", async () => { + const temporaryId = "aw_AbC12345"; // 8 chars, mixed case + const projectUrl = "https://github.com/orgs/testowner/projects/99"; + const tempIdMap = new Map(); + tempIdMap.set("aw_abc12345", { projectUrl }); // Stored in lowercase + + queueResponses([repoResponse(), viewerResponse(), orgProjectV2Response(projectUrl, 99, "project-resolved"), issueResponse("issue-id-1"), existingItemResponse("issue-id-1", "item-resolved"), fieldsResponse([])]); + + // Create handler with config + const config = { max: 100 }; + messageHandler = await updateProjectHandlerFactory(config); + + const message = { + type: "update_project", + project: temporaryId, // Using temporary ID + content_type: "issue", + content_number: 42, + }; + + const result = await messageHandler(message, {}, tempIdMap); + + expect(result.success).toBe(true); + expect(mockCore.info).toHaveBeenCalledWith(`Resolved temporary project ID ${temporaryId} to ${projectUrl}`); + }); + + it("resolves temporary project ID with # prefix", async () => { + const temporaryId = "#aw_Test99"; // With hash prefix + const projectUrl = "https://github.com/orgs/testowner/projects/88"; + const tempIdMap = new Map(); + tempIdMap.set("aw_test99", { projectUrl }); // Stored without hash, lowercase + + queueResponses([repoResponse(), viewerResponse(), orgProjectV2Response(projectUrl, 88, "project-hash"), issueResponse("issue-id-2"), existingItemResponse("issue-id-2", "item-hash"), fieldsResponse([])]); + + const config = { max: 100 }; + messageHandler = await updateProjectHandlerFactory(config); + + const message = { + type: "update_project", + project: temporaryId, + content_type: "issue", + content_number: 43, + }; + + const result = await messageHandler(message, {}, tempIdMap); + + expect(result.success).toBe(true); + expect(mockCore.info).toHaveBeenCalledWith(`Resolved temporary project ID ${temporaryId} to ${projectUrl}`); + }); + + it("resolves temporary project ID with 3 characters (minimum)", async () => { + const temporaryId = "aw_abc"; // 3 chars minimum + const projectUrl = "https://github.com/orgs/testowner/projects/77"; + const tempIdMap = new Map(); + tempIdMap.set("aw_abc", { projectUrl }); + + queueResponses([repoResponse(), viewerResponse(), orgProjectV2Response(projectUrl, 77, "project-min"), issueResponse("issue-id-3"), existingItemResponse("issue-id-3", "item-min"), fieldsResponse([])]); + + const config = { max: 100 }; + messageHandler = await updateProjectHandlerFactory(config); + + const message = { + type: "update_project", + project: temporaryId, + content_type: "issue", + content_number: 44, + }; + + const result = await messageHandler(message, {}, tempIdMap); + + expect(result.success).toBe(true); + expect(mockCore.info).toHaveBeenCalledWith(`Resolved temporary project ID ${temporaryId} to ${projectUrl}`); + }); + + it("throws error when temporary project ID is not found in map", async () => { + const temporaryId = "aw_NotFound"; + const tempIdMap = new Map(); // Empty map + + const config = { max: 100 }; + messageHandler = await updateProjectHandlerFactory(config); + + const message = { + type: "update_project", + project: temporaryId, + content_type: "issue", + content_number: 45, + }; + + const result = await messageHandler(message, {}, tempIdMap); + + expect(result.success).toBe(false); + expect(result.error).toMatch(/Temporary project ID 'aw_NotFound' not found.*Ensure create_project was called before update_project/); + }); + + it("handles full project URL normally (not treated as temporary ID)", async () => { + const projectUrl = "https://github.com/orgs/testowner/projects/66"; + const tempIdMap = new Map(); + // Map has an entry, but it shouldn't be used since we're passing full URL + tempIdMap.set("aw_other", { projectUrl: "https://github.com/orgs/other/projects/1" }); + + queueResponses([repoResponse(), viewerResponse(), orgProjectV2Response(projectUrl, 66, "project-full"), issueResponse("issue-id-4"), existingItemResponse("issue-id-4", "item-full"), fieldsResponse([])]); + + const config = { max: 100 }; + messageHandler = await updateProjectHandlerFactory(config); + + const message = { + type: "update_project", + project: projectUrl, // Full URL, not temporary ID + content_type: "issue", + content_number: 46, + }; + + const result = await messageHandler(message, {}, tempIdMap); + + expect(result.success).toBe(true); + // Should NOT log temporary ID resolution + expect(mockCore.info).not.toHaveBeenCalledWith(expect.stringContaining("Resolved temporary project ID")); + }); +}); diff --git a/pkg/workflow/compiler_yaml.go b/pkg/workflow/compiler_yaml.go index dc1a528015..541270a373 100644 --- a/pkg/workflow/compiler_yaml.go +++ b/pkg/workflow/compiler_yaml.go @@ -4,6 +4,7 @@ import ( "encoding/json" "fmt" "path/filepath" + "sort" "strings" "github.com/github/gh-aw/pkg/constants" @@ -79,6 +80,8 @@ func (c *Compiler) generateWorkflowHeader(yaml *strings.Builder, data *WorkflowD if len(data.ImportedFiles) > 0 || len(data.IncludedFiles) > 0 { yaml.WriteString("#\n") yaml.WriteString("# Resolved workflow manifest:\n") + includedFiles := append([]string(nil), data.IncludedFiles...) + sort.Strings(includedFiles) if len(data.ImportedFiles) > 0 { yaml.WriteString("# Imports:\n") @@ -90,9 +93,9 @@ func (c *Compiler) generateWorkflowHeader(yaml *strings.Builder, data *WorkflowD } } - if len(data.IncludedFiles) > 0 { + if len(includedFiles) > 0 { yaml.WriteString("# Includes:\n") - for _, file := range data.IncludedFiles { + for _, file := range includedFiles { cleanFile := stringutil.StripANSIEscapeCodes(file) // Normalize to Unix paths (forward slashes) for cross-platform compatibility cleanFile = filepath.ToSlash(cleanFile) diff --git a/pkg/workflow/compiler_yaml_helpers_test.go b/pkg/workflow/compiler_yaml_helpers_test.go index 15efcf1874..2450bf3964 100644 --- a/pkg/workflow/compiler_yaml_helpers_test.go +++ b/pkg/workflow/compiler_yaml_helpers_test.go @@ -194,16 +194,17 @@ func TestGenerateWorkflowHeader(t *testing.T) { { name: "header with imports and includes", data: &WorkflowData{ - ImportedFiles: []string{"import1.md", "import2.md"}, - IncludedFiles: []string{"include1.md"}, + ImportedFiles: []string{"import2.md", "import1.md"}, + IncludedFiles: []string{"include-b.md", "include-a.md"}, }, expectInStr: []string{ "# Resolved workflow manifest:", "# Imports:", - "# - import1.md", "# - import2.md", + "# - import1.md", "# Includes:", - "# - include1.md", + "# - include-a.md", + "# - include-b.md", }, }, { @@ -244,6 +245,13 @@ func TestGenerateWorkflowHeader(t *testing.T) { t.Errorf("generateWorkflowHeader() result missing %q\nGot:\n%s", expected, result) } } + if tt.name == "header with imports and includes" { + includeAPos := strings.Index(result, "# - include-a.md") + includeBPos := strings.Index(result, "# - include-b.md") + if includeAPos == -1 || includeBPos == -1 || includeAPos > includeBPos { + t.Errorf("includes should be sorted deterministically:\n%s", result) + } + } for _, notExpected := range tt.notInStr { if strings.Contains(result, notExpected) { diff --git a/pkg/workflow/js/safe_outputs_tools.json b/pkg/workflow/js/safe_outputs_tools.json index 35ab254719..5f51146f2b 100644 --- a/pkg/workflow/js/safe_outputs_tools.json +++ b/pkg/workflow/js/safe_outputs_tools.json @@ -33,7 +33,7 @@ }, "temporary_id": { "type": "string", - "pattern": "^aw_[A-Za-z0-9]{4,8}$", + "pattern": "^aw_[A-Za-z0-9]{3,8}$", "description": "Unique temporary identifier for referencing this issue before it's created. Format: 'aw_' followed by 3 to 8 alphanumeric characters (e.g., 'aw_abc1', 'aw_Test123'). Use '#aw_ID' in body text to reference other issues by their temporary_id; these are replaced with actual issue numbers after creation." } }, @@ -845,7 +845,7 @@ "properties": { "project": { "type": "string", - "pattern": "^(https://github\\.com/(orgs|users)/[^/]+/projects/\\d+|#?aw_[A-Za-z0-9]{4,8})$", + "pattern": "^(https://github\\.com/(orgs|users)/[^/]+/projects/\\d+|#?aw_[A-Za-z0-9]{3,8})$", "description": "Full GitHub project URL (e.g., 'https://github.com/orgs/myorg/projects/42' or 'https://github.com/users/username/projects/5'), or a temporary project ID from a recent create_project call (e.g., '#aw_abc1', 'aw_Test123'). Project names or numbers alone are NOT accepted." }, "operation": { @@ -882,13 +882,13 @@ }, "draft_issue_id": { "type": "string", - "pattern": "^aw_[A-Za-z0-9]{4,8}$", - "description": "Temporary ID of an existing draft issue to update (e.g., 'aw_abc1', 'aw_Test123'). Use this to reference a draft created earlier with a matching temporary_id. When provided, draft_title is not required for updates." + "pattern": "^#?aw_[A-Za-z0-9]{3,8}$", + "description": "Temporary ID of an existing draft issue to update (e.g., 'aw_abc1', '#aw_Test123'). Use this to reference a draft created earlier with a matching temporary_id. When provided, draft_title is not required for updates." }, "temporary_id": { "type": "string", - "pattern": "^aw_[A-Za-z0-9]{4,8}$", - "description": "Unique temporary identifier for this draft issue (e.g., 'aw_abc1', 'aw_Test123'). Provide this when creating a new draft to enable future updates via draft_issue_id. Format: 'aw_' followed by 3 to 8 alphanumeric characters." + "pattern": "^#?aw_[A-Za-z0-9]{3,8}$", + "description": "Unique temporary identifier for this draft issue (e.g., 'aw_abc1', '#aw_Test123'). Provide this when creating a new draft to enable future updates via draft_issue_id. Format: optional leading '#', then 'aw_' followed by 3 to 8 alphanumeric characters." }, "fields": { "type": "object", @@ -1022,12 +1022,12 @@ }, "item_url": { "type": "string", - "pattern": "^(https://github\\\\.com/[^/]+/[^/]+/issues/(\\\\d+|#?aw_[A-Za-z0-9]{4,8})|#?aw_[A-Za-z0-9]{4,8})$", + "pattern": "^(https://github\\\\.com/[^/]+/[^/]+/issues/(\\\\d+|#?aw_[A-Za-z0-9]{3,8})|#?aw_[A-Za-z0-9]{3,8})$", "description": "Optional GitHub issue URL or temporary ID to add as the first item to the project. Accepts either a full URL (e.g., 'https://github.com/owner/repo/issues/123'), a URL with temporary ID (e.g., 'https://github.com/owner/repo/issues/aw_abc1'), or a plain temporary ID (e.g., 'aw_abc1', '#aw_Test123') from a previously created issue in the same workflow run." }, "temporary_id": { "type": "string", - "pattern": "^aw_[A-Za-z0-9]{4,8}$", + "pattern": "^aw_[A-Za-z0-9]{3,8}$", "description": "Optional temporary identifier for referencing this project before it's created. Format: 'aw_' followed by 3 to 8 alphanumeric characters (e.g., 'aw_abc1', 'aw_Test123'). If not provided, one will be auto-generated and returned in the response. Use '#aw_ID' in update_project to reference this project by its temporary_id." } },