Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
19 changes: 18 additions & 1 deletion build/api/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -5222,6 +5222,7 @@ exports.canonicalizeLocaleTag = canonicalizeLocaleTag;
exports.normalizeLocaleTag = normalizeLocaleTag;
exports.resolveLocaleProfile = resolveLocaleProfile;
exports.localeForScope = localeForScope;
exports.isLocaleProfile = isLocaleProfile;
exports.localeLanguagesMatch = localeLanguagesMatch;
exports.baseLanguage = baseLanguage;
exports.DEFAULT_REPOSITORY_LOCALE = 'en-US';
Expand Down Expand Up @@ -5291,6 +5292,22 @@ function localeForScope(profile, scope) {
return profile.pullRequest;
return profile.repository;
}
function isLocaleProfile(value) {
if (!value || typeof value !== 'object' || Array.isArray(value))
return false;
const candidate = value;
try {
const resolved = resolveLocaleProfile(candidate.repository, candidate.issueOverride ?? '', candidate.pullRequestOverride ?? '');
return candidate.repository === resolved.repository
&& candidate.issue === resolved.issue
&& candidate.pullRequest === resolved.pullRequest
&& candidate.issueOverride === resolved.issueOverride
&& candidate.pullRequestOverride === resolved.pullRequestOverride;
}
catch {
return false;
}
}
function localeLanguagesMatch(left, right) {
return baseLanguage(canonicalizeLocaleTag(left)) === baseLanguage(canonicalizeLocaleTag(right));
}
Expand Down Expand Up @@ -5452,7 +5469,7 @@ function validMessageText(value) {
function safeDynamicText(value) {
return validMessageText(value)
&& !/[\r\n\u202A-\u202E\u2066-\u2069]/u.test(value)
&& !/<!--|-->|<\/?[A-Za-z]|https?:\/\/|```|[`*_[\]~]|(^|\s)\/(?:copilot)(?:\s|$)|@[A-Za-z0-9]/iu.test(value);
&& !/<!--|-->|<\/?[A-Za-z]|https?:\/\/|```|[`*_[\]~|]|(^|\s)\/(?:copilot)(?:\s|$)|@[A-Za-z0-9]/iu.test(value);
}
function pluralPlaceholderParity(message) {
const expected = placeholdersForTemplate(message.other);
Expand Down
768 changes: 553 additions & 215 deletions build/cli/index.js

Large diffs are not rendered by default.

866 changes: 619 additions & 247 deletions build/github_action/index.js

Large diffs are not rendered by default.

38 changes: 38 additions & 0 deletions docs/issues/deployment-orchestration.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -99,6 +99,44 @@ already be present when a managed promotion PR closes.
The immutable facts are visible in one issue control-center comment. Duplicate
events and retries update that comment instead of creating another operation.

## Language and presentation

Deployment UI follows the repository locale profile. English (`en-US`) is the
default when no locale is configured.

- The issue control center and the four optional milestone notifications use the
effective issue locale.
- Managed promotion and reconciliation PR titles and descriptions use the
effective pull-request locale. The stable `release(...)` or `hotfix(...)`
prefix, refs, SHAs, tags, IDs, and marker fields are not translated.
- The GitHub Actions Job Summary uses the repository locale because it belongs to
the run, not to the issue or PR conversation.

Empty `issues-locale` and `pull-requests-locale` values inherit
`repository-locale`. Complete reviewed catalogs ship for English and Spanish.
Any other valid BCP-47 locale uses the configured planning agent to resolve one
bounded catalog for the destination. If that response is unavailable, incomplete,
or unsafe, the whole artifact falls back to English; Copilot never mixes
languages or creates a separate fallback comment.

The installed release and hotfix workflow templates pass `repository-locale`
and preserve empty issue/PR overrides. This matters when the repository locale is
not English: replacing an empty override with `en-US` would disable inheritance.

The dashboard leads with current status and a required action only when a person
must act. Progress, transition, and links follow, while operation IDs and other
technical facts stay collapsed. Managed PR descriptions explain their single
purpose and consequence without repeating the dashboard. The Job Summary shows
the durable revision, branch/publication facts, retryability, and descriptive
links; it does not replay internal workflow step logs such as “created” or
“reused”.

New operations snapshot the complete canonical locale profile when they start,
so a later Variable change cannot switch an in-flight release between languages.
A version-1 operation created before locale snapshots were added remains valid
and uses the current profile until it completes. Start the next deployment from
a fresh launcher issue to guarantee a newly configured profile.

## Serialization, durable revisions, and safe retries

All release, hotfix, and managed-PR mutation routes for the same launcher issue
Expand Down
4 changes: 3 additions & 1 deletion docs/issues/type/hotfix.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -146,7 +146,9 @@ jobs:
The durable hotfix dashboard owns the issue presentation. Routine orchestration
does not create an “Actions” summary or a decorative image. The legacy
`images-issue-hotfix` input remains accepted only for configuration
compatibility.
compatibility. The dashboard uses the effective issue locale, managed PRs use
the pull-request locale, and the Actions summary uses the English-default
repository locale; see the orchestration guide for inheritance and fallback.

## Template
You can use this template for hotfix issues that helps capture all the necessary information. The template includes fields for:
Expand Down
4 changes: 3 additions & 1 deletion docs/issues/type/release.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -142,7 +142,9 @@ jobs:
The durable release dashboard owns the issue presentation. Routine
orchestration does not create an “Actions” summary or a decorative image. The
legacy `images-issue-release` input remains accepted only for configuration
compatibility.
compatibility. The dashboard uses the effective issue locale, managed PRs use
the pull-request locale, and the Actions summary uses the English-default
repository locale; see the orchestration guide for inheritance and fallback.

## Template
You can use this template for release issues that helps capture all the necessary information. The template includes fields for:
Expand Down
22 changes: 22 additions & 0 deletions scripts/coverage-budgets.json
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,28 @@
],
"successMessage": "deployment handler coverage: PASS (95% lines/statements, 90% branches/functions)"
},
{
"name": "Deployment presentation",
"missingEntryLabel": "deployment presentation",
"rules": [
{
"files": [
"src/application/policies/deployment_message_catalog.ts"
],
"mode": "each",
"thresholdProfile": "exhaustive"
},
{
"files": [
"src/application/policies/deployment_presentation_policy.ts",
"src/application/services/deployment_orchestration_runtime.ts"
],
"mode": "aggregate",
"thresholdProfile": "default"
}
],
"successMessage": "deployment presentation coverage: PASS (catalog 100%; rendered path 95% lines/statements, 90% branches/functions)"
},
{
"name": "Bugbot context",
"missingEntryLabel": "Bugbot context",
Expand Down
5 changes: 3 additions & 2 deletions setup/workflows/hotfix_workflow.yml
Original file line number Diff line number Diff line change
Expand Up @@ -136,8 +136,9 @@ jobs:
orchestration-presentation-mode: ${{ vars.ORCHESTRATION_PRESENTATION_MODE || 'guided' }}
orchestration-diagrams: ${{ vars.ORCHESTRATION_DIAGRAMS || 'true' }}
orchestration-comment-mode: ${{ vars.ORCHESTRATION_COMMENT_MODE || 'update' }}
issues-locale: ${{ vars.ISSUES_LOCALE || 'en-US' }}
pull-requests-locale: ${{ vars.PULL_REQUESTS_LOCALE || 'en-US' }}
repository-locale: ${{ vars.REPOSITORY_LOCALE || 'en-US' }}
issues-locale: ${{ vars.ISSUES_LOCALE || '' }}
pull-requests-locale: ${{ vars.PULL_REQUESTS_LOCALE || '' }}
token: ${{ secrets.PAT }}

publish:
Expand Down
5 changes: 3 additions & 2 deletions setup/workflows/release_workflow.yml
Original file line number Diff line number Diff line change
Expand Up @@ -136,8 +136,9 @@ jobs:
orchestration-presentation-mode: ${{ vars.ORCHESTRATION_PRESENTATION_MODE || 'guided' }}
orchestration-diagrams: ${{ vars.ORCHESTRATION_DIAGRAMS || 'true' }}
orchestration-comment-mode: ${{ vars.ORCHESTRATION_COMMENT_MODE || 'update' }}
issues-locale: ${{ vars.ISSUES_LOCALE || 'en-US' }}
pull-requests-locale: ${{ vars.PULL_REQUESTS_LOCALE || 'en-US' }}
repository-locale: ${{ vars.REPOSITORY_LOCALE || 'en-US' }}
issues-locale: ${{ vars.ISSUES_LOCALE || '' }}
pull-requests-locale: ${{ vars.PULL_REQUESTS_LOCALE || '' }}
token: ${{ secrets.PAT }}

publish:
Expand Down
14 changes: 7 additions & 7 deletions specs/CATALOG.md

Large diffs are not rendered by default.

15 changes: 14 additions & 1 deletion specs/catalog.json
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,7 @@
"src/application/policies/action_summary_policy.ts",
"src/application/policies/branch_sync_notification_policy.ts",
"src/application/policies/bugbot_message_catalog.ts",
"src/application/policies/deployment_message_catalog.ts",
"src/application/usecases/actions/observe_branch_sync_use_case.ts",
"src/application/policies/bugbot_review_presentation_policy.ts",
"src/application/usecases/steps/commit/detect_potential_problems_workflow.ts",
Expand All @@ -76,6 +77,7 @@
"src/application/policies/__tests__/branch_sync_notification_policy.test.ts",
"src/application/usecases/actions/__tests__/observe_branch_sync_use_case.test.ts",
"src/application/policies/__tests__/bugbot_message_catalog.test.ts",
"src/application/policies/__tests__/deployment_message_catalog.test.ts",
"src/application/policies/__tests__/bugbot_review_presentation_policy.test.ts",
"src/application/usecases/steps/commit/__tests__/detect_potential_problems_use_case.test.ts",
"src/application/usecases/steps/commit/bugbot/__tests__/dismiss_bugbot_findings_use_case.test.ts",
Expand Down Expand Up @@ -130,7 +132,7 @@
"status": "implemented",
"scope": "Release and hotfix promotion, publication, reconciliation, and durable recovery",
"owner": "Copilot maintainers",
"lastVerified": "2026-09-12",
"lastVerified": "2026-09-14",
"specs": [
"specs/configurable-release-orchestration.md",
"specs/configurable-release-orchestration-traceability.md",
Expand All @@ -150,10 +152,15 @@
"code": [
"src/domain/deployment_configuration.ts",
"src/domain/deployment_operation.ts",
"src/domain/locale.ts",
"src/domain/message_catalog.ts",
"src/domain/deployment_state_fence.ts",
"src/domain/deployment_publication.ts",
"src/application/policies/deployment_lifecycle_policy.ts",
"src/application/policies/deployment_plan_policy.ts",
"src/application/policies/deployment_message_catalog.ts",
"src/application/policies/deployment_presentation_policy.ts",
"src/application/ports/message_catalog_ports.ts",
"src/application/services/deployment_orchestration_dependencies.ts",
"src/application/services/deployment_orchestration_runtime.ts",
"src/application/services/deployment_state_boundary.ts",
Expand All @@ -172,11 +179,17 @@
],
"tests": [
"src/domain/__tests__/deployment_operation.test.ts",
"src/domain/__tests__/locale.test.ts",
"src/domain/__tests__/message_catalog.test.ts",
"src/domain/__tests__/deployment_state_fence.test.ts",
"src/domain/__tests__/deployment_publication.test.ts",
"src/application/services/__tests__/deployment_state_boundary.test.ts",
"src/application/usecases/actions/__tests__/deployment_orchestration_use_case.test.ts",
"src/application/usecases/actions/__tests__/deployment_phase_handlers.test.ts",
"src/application/policies/__tests__/deployment_message_catalog.test.ts",
"src/application/policies/__tests__/deployment_presentation_policy.test.ts",
"src/actions/__tests__/github_action_completion.test.ts",
"src/application/usecases/__tests__/push_single_action_contexts.test.ts",
"src/data/repository/deployment/__tests__/github_deployment_adapters.test.ts",
"src/application/__tests__/architecture_boundaries.test.ts",
"src/tooling/__tests__/validate_workflow_contract.test.ts"
Expand Down
72 changes: 50 additions & 22 deletions specs/configurable-release-orchestration.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
- Status: Implemented; live rollout, human UX validation, and concurrency
conformance hardening pending
- Date: 2026-09-09
- Last updated: 2026-09-11
- Last updated: 2026-09-14
- Owners: Copilot maintainers
- Scope: release and hotfix promotion, publication, reconciliation, and cleanup
- Related proposals:
Expand Down Expand Up @@ -359,8 +359,18 @@ The following inputs retain their current meaning:
- `hotfix-tree`
- `release-workflow`
- `hotfix-workflow`
- `issues-locale`, used for the issue control center and issue comments
- `pull-requests-locale`, used for managed PR titles and descriptions
- `repository-locale`, default `en-US`, used for repository/run surfaces such as
the deployment Job Summary
- `issues-locale`, an optional override for the issue control center and issue
milestones; empty inherits `repository-locale`
- `pull-requests-locale`, an optional override for managed PR titles and
descriptions; empty inherits `repository-locale`

New operations snapshot the complete canonical locale profile with the branch
and strategy facts, so changing repository Variables cannot switch language
mid-operation. Existing version-1 state created before this field was introduced
remains valid and uses the current effective profile until it completes; it is
not rewritten solely to add locale metadata.

### 6.5 Project publication timing

Expand Down Expand Up @@ -802,13 +812,13 @@ The guided presentation follows this information hierarchy:
```markdown
<!-- copilot-deployment-dashboard operation-id="..." issue="355" -->

# 🚀 Release 3.4.0
## 🚀 Release 3.4.0

> **Current status: waiting for production approval**
>
> No action is required while GitHub checks are running.

## Progress
### Progress

- [x] Release cut from `develop` at [`abc1234`](...)
- [x] Version files, build, validation, and smoke test
Expand All @@ -817,18 +827,18 @@ The guided presentation follows this information hierarchy:
- [ ] Reconciliation into `develop`
- [ ] Cleanup and issue completion

## Current transition
### Current transition

| From | To | State |
|---|---|---|
| `release/3.4.0` | `master` | ⏳ Checks and review |

## What happens next
### What happens next

After [PR #401](...) is merged, Copilot will tag the accepted `master` commit,
publish `@vypdev/copilot@3.4.0`, and start development reconciliation.

## Links
### Links

[Promotion PR](...) · [Compare changes](...) · [Workflow run](...)

Expand Down Expand Up @@ -864,22 +874,22 @@ instruction with a direct link or copyable command.
A blocked presentation uses the following order:

```markdown
# ❌ Release 3.4.0 needs attention
## ❌ Release 3.4.0 needs attention

> **Published package:** No
> **Production updated:** No
> **Development synchronized:** No

## What happened
### What happened

The production PR was closed without merging, so publication was stopped.

## Action required
### Action required

Reopen [PR #401](...) or run `/copilot retry-release` after correcting the
problem.

## What Copilot protected
### What Copilot protected

No npm version, GitHub Release, or version tag was created.

Expand Down Expand Up @@ -1036,14 +1046,24 @@ automation. Labels supplement, but never replace, the PR body status.

### 16.10 Localization

Issue-facing presentation uses `issues-locale`; PR-facing presentation uses
`pull-requests-locale`.
Issue-facing presentation uses the effective issue locale; PR-facing
presentation uses the effective pull-request locale; the Job Summary uses the
repository locale. Empty issue and PR overrides inherit `repository-locale`,
whose default is `en-US`.

All orchestration-owned headings, status sentences, instructions, table labels,
and failure guidance MUST come from a typed message catalog rather than scattered
string literals. The first implementation MUST provide complete `en-US` and
`es-ES` catalogs. An unsupported locale falls back to `en-US` and emits one
visible, non-blocking warning in technical details.
string literals. The implementation provides complete `en-US` and `es-ES`
catalogs. Any other valid BCP-47 locale uses one schema-constrained dynamic
catalog resolution for the required slice. Missing, invalid, unsafe, or
unavailable dynamic output falls back atomically to `en-US`; fallback is recorded
in the Job Summary and never creates a second timeline comment or a mixed-language
artifact.

The localization-evidence heading, table labels, descriptor count, and
fallback-reason labels in that Job Summary use the same repository-locale
catalog. Locale tags, catalog source names, descriptor counts, and
machine-readable fallback reasons remain provider facts and are not translated.

Branch names, package names, tag names, GitHub check names, and copied provider
facts are not translated.
Expand All @@ -1069,16 +1089,23 @@ facts are not translated.

### 16.12 Job Summary

The Job Summary mirrors the issue's current facts but is optimized for operators:
The Job Summary projects the operation's current semantic facts for operators;
it does not replay internal use-case steps:

- result and phase at the top;
- transition performed by this invocation;
- verified input/output SHAs;
- API operations created/reused/skipped;
- durable operation identity, revision, origin, prepared source, and accepted
production fact;
- publication evidence;
- pending external dependency;
- sanitized failure classification and retryability; and
- a final artifact/PR link table.
- a final set of descriptive artifact and PR links.

Raw `Result.steps`, provider narration, and duplicate “created/reused/skipped”
logs remain in machine-searchable logs. They are not copied into the Job Summary
because the operation state and descriptive links already communicate the useful
result.

It MUST distinguish `waiting externally` from `workflow failure`. A workflow that
successfully creates a pending auto-merge PR finishes green and reports the
Expand Down Expand Up @@ -1395,8 +1422,9 @@ deviation. Deviations require an explicit update to this specification.
configuration-controlled fallback.
- Build every URL from verified repository entities and sanitize all untrusted
values before Markdown publication.
- Keep generic `Result.steps` for short generic feedback only; deployment
orchestration uses its dedicated structured presentation boundary.
- Keep `Result.steps` as internal execution evidence; deployment orchestration
uses its dedicated structured presentation boundary and never replays those
steps into GitHub conversation UI or its Job Summary.

### 20.6 Documentation

Expand Down
Loading