From 479026e79829f3cfccfa56481f0b46458d31bc48 Mon Sep 17 00:00:00 2001 From: Efra Espada Date: Tue, 13 Oct 2026 15:03:08 +0200 Subject: [PATCH] fix: name Doctor issue and PR evidence links accurately --- build/cli/index.js | 8 ++++- build/github_action/index.js | 8 ++++- docs/issues/comment-commands.mdx | 6 ++++ specs/github-runtime-doctor-command.md | 30 +++++++++++++++++ ...runtime_doctor_presentation_policy.test.ts | 33 +++++++++++++++++++ ...thub_runtime_doctor_presentation_policy.ts | 2 +- .../policies/publication_message_catalog.ts | 6 ++++ 7 files changed, 90 insertions(+), 3 deletions(-) diff --git a/build/cli/index.js b/build/cli/index.js index da5f09a08..c285c41fb 100755 --- a/build/cli/index.js +++ b/build/cli/index.js @@ -42254,7 +42254,7 @@ function formatGithubRuntimeDoctor(projection, locale = 'en-US', catalog = (0, p ? message(`source.${evidence}`) : undefined; const mode = group === 'approval-prerequisites' && (evidence === 'off' || evidence === 'recommend' || evidence === 'guarded') ? `${message('mode')}: ${evidence}` : undefined; - lines.push(`- **${message(`group.${group}`)}:** ${message(`state.${state}`)}${policySource ? ` · ${policySource}` : ''}${mode ? ` · ${mode}` : ''}${link ? ` · [${message('source')}](${link})` : ''}`); + lines.push(`- **${message(`group.${group}`)}:** ${message(`state.${state}`)}${policySource ? ` · ${policySource}` : ''}${mode ? ` · ${mode}` : ''}${link ? ` · [${message(target?.kind === 'pull-request' ? 'sourcePullRequest' : 'sourceIssue')}](${link})` : ''}`); } if (source) lines.push('', `[${message('source')}](${source})`); @@ -43145,6 +43145,8 @@ const PUBLICATION_SURFACE_MESSAGE_IDS = Object.freeze([ 'interaction.doctor.checks', 'interaction.doctor.readonly', 'interaction.doctor.source', + 'interaction.doctor.sourceIssue', + 'interaction.doctor.sourcePullRequest', 'interaction.doctor.group.effective-configuration', 'interaction.doctor.group.issue-readiness', 'interaction.doctor.group.linked-branch-readiness', @@ -43336,6 +43338,8 @@ const ENGLISH_MESSAGES = Object.freeze({ 'interaction.doctor.checks': "Checks", 'interaction.doctor.readonly': "This command reads evidence only. Declared approval settings do not prove producer health or write access.", 'interaction.doctor.source': "Inspected repository revision", + 'interaction.doctor.sourceIssue': "Inspected issue", + 'interaction.doctor.sourcePullRequest': "Inspected pull request", 'interaction.doctor.group.effective-configuration': "Effective configuration", 'interaction.doctor.group.issue-readiness': "Issue and SDD prerequisites", 'interaction.doctor.group.linked-branch-readiness': "Native linked branch", @@ -43528,6 +43532,8 @@ const SPANISH_MESSAGES = Object.freeze({ 'interaction.doctor.checks': "Comprobaciones", 'interaction.doctor.readonly': "Este comando solo lee evidencias. La configuración de aprobación declarada no acredita la salud de los productores ni el acceso de escritura.", 'interaction.doctor.source': "Revisión inspeccionada del repositorio", + 'interaction.doctor.sourceIssue': "Issue inspeccionada", + 'interaction.doctor.sourcePullRequest': "PR inspeccionado", 'interaction.doctor.group.effective-configuration': "Configuración efectiva", 'interaction.doctor.group.issue-readiness': "Requisitos de la issue y el SDD", 'interaction.doctor.group.linked-branch-readiness': "Rama enlazada nativa", diff --git a/build/github_action/index.js b/build/github_action/index.js index 2f08214ba..d012d3c85 100644 --- a/build/github_action/index.js +++ b/build/github_action/index.js @@ -44976,7 +44976,7 @@ function formatGithubRuntimeDoctor(projection, locale = 'en-US', catalog = (0, p ? message(`source.${evidence}`) : undefined; const mode = group === 'approval-prerequisites' && (evidence === 'off' || evidence === 'recommend' || evidence === 'guarded') ? `${message('mode')}: ${evidence}` : undefined; - lines.push(`- **${message(`group.${group}`)}:** ${message(`state.${state}`)}${policySource ? ` · ${policySource}` : ''}${mode ? ` · ${mode}` : ''}${link ? ` · [${message('source')}](${link})` : ''}`); + lines.push(`- **${message(`group.${group}`)}:** ${message(`state.${state}`)}${policySource ? ` · ${policySource}` : ''}${mode ? ` · ${mode}` : ''}${link ? ` · [${message(target?.kind === 'pull-request' ? 'sourcePullRequest' : 'sourceIssue')}](${link})` : ''}`); } if (source) lines.push('', `[${message('source')}](${source})`); @@ -46000,6 +46000,8 @@ const PUBLICATION_SURFACE_MESSAGE_IDS = Object.freeze([ 'interaction.doctor.checks', 'interaction.doctor.readonly', 'interaction.doctor.source', + 'interaction.doctor.sourceIssue', + 'interaction.doctor.sourcePullRequest', 'interaction.doctor.group.effective-configuration', 'interaction.doctor.group.issue-readiness', 'interaction.doctor.group.linked-branch-readiness', @@ -46191,6 +46193,8 @@ const ENGLISH_MESSAGES = Object.freeze({ 'interaction.doctor.checks': "Checks", 'interaction.doctor.readonly': "This command reads evidence only. Declared approval settings do not prove producer health or write access.", 'interaction.doctor.source': "Inspected repository revision", + 'interaction.doctor.sourceIssue': "Inspected issue", + 'interaction.doctor.sourcePullRequest': "Inspected pull request", 'interaction.doctor.group.effective-configuration': "Effective configuration", 'interaction.doctor.group.issue-readiness': "Issue and SDD prerequisites", 'interaction.doctor.group.linked-branch-readiness': "Native linked branch", @@ -46383,6 +46387,8 @@ const SPANISH_MESSAGES = Object.freeze({ 'interaction.doctor.checks': "Comprobaciones", 'interaction.doctor.readonly': "Este comando solo lee evidencias. La configuración de aprobación declarada no acredita la salud de los productores ni el acceso de escritura.", 'interaction.doctor.source': "Revisión inspeccionada del repositorio", + 'interaction.doctor.sourceIssue': "Issue inspeccionada", + 'interaction.doctor.sourcePullRequest': "PR inspeccionado", 'interaction.doctor.group.effective-configuration': "Configuración efectiva", 'interaction.doctor.group.issue-readiness': "Requisitos de la issue y el SDD", 'interaction.doctor.group.linked-branch-readiness': "Rama enlazada nativa", diff --git a/docs/issues/comment-commands.mdx b/docs/issues/comment-commands.mdx index 1d57b03ae..43713835b 100644 --- a/docs/issues/comment-commands.mdx +++ b/docs/issues/comment-commands.mdx @@ -508,3 +508,9 @@ An explicit missing-file result is blocked; an omitted or malformed provider entry is unavailable evidence. Doctor never treats an incomplete sample as proof that a file or permission is missing. Successful independent checks remain visible, and the report points to the run and read-access guidance for retry. + +Doctor distinguishes its source links: **Inspected issue** opens the issue context, +**Inspected pull request** opens the exact PR, and **Inspected repository revision** +opens the immutable repository tree that was inspected. Spanish uses the matching +entity captions. These links do not authorize a repair or certify CI, producer +health or write permissions. diff --git a/specs/github-runtime-doctor-command.md b/specs/github-runtime-doctor-command.md index 7264912b1..1776ef5ce 100644 --- a/specs/github-runtime-doctor-command.md +++ b/specs/github-runtime-doctor-command.md @@ -689,3 +689,33 @@ passed. The three whole-map cases additionally cover defensive shape branches an coverage, normal hooks and all native platform gates remain mandatory. Documentation distinguishes missing from incomplete evidence. Current-head review and post-promotion commands/replay/browser acceptance remain required. + +### Descriptive entity source links (dogfooding #484, 2026-10-13) + +Live replies [issue #461](https://github.com/vypdev/copilot/issues/461#issuecomment-6145766292) +and [PR #483](https://github.com/vypdev/copilot/pull/483#issuecomment-6145771529) +from promoted master `c7cfec82` incorrectly called issue/PR destinations +**Inspected repository revision**. Only the validated immutable `/tree/SHA` +footer is a repository revision. The entity links MUST use **Inspected issue** +or **Inspected pull request**; Spanish uses **Issue inspeccionada** and +**PR inspeccionado**, with the existing complete English fallback. + +Keep all existing HTTPS-origin/repository/revision validation, exact issue/PR +numbers, destinations, source witness, semantic reply key/correlation, group +states and no-model/no-write capabilities. No new input, permission, entity, +provider request, role or safety boundary is introduced. Existing one-reply +reconciliation/replay and byte limits remain intact. The two new catalog keys +follow the existing complete-catalog contract and cannot accept arbitrary URLs +or commands. Native not-applicable context links remain entity links and do not +claim a repository revision. + +Eight distinct presentation cases add four entity/locale combinations, complete +fallback, absent/unsafe provenance and unchanged correlated rendering. Six +failed before the fix; the two provenance controls already passed. The dedicated +inventory becomes 300 + 8 = **308** without recounting parent semantic/locale +cases. Global/module coverage remains mandatory. User command docs explain the +three link kinds and unchanged navigation; catalog evidence already owns the +renderer, catalog and suite. Current-head full/native review/platform checks, +source-correlated refresh, EN/ES browser inspection and original locale +restoration are required for native acceptance. Existing historical receipts +are not rewritten as proof of a new operation. diff --git a/src/application/policies/__tests__/github_runtime_doctor_presentation_policy.test.ts b/src/application/policies/__tests__/github_runtime_doctor_presentation_policy.test.ts index 8edea65a3..63b43d82f 100644 --- a/src/application/policies/__tests__/github_runtime_doctor_presentation_policy.test.ts +++ b/src/application/policies/__tests__/github_runtime_doctor_presentation_policy.test.ts @@ -58,3 +58,36 @@ describe('runtime doctor public presentation', () => { expect(issue).not.toEqual(pr); }); }); + +describe('entity and immutable-revision source captions', () => { + it.each(['en-US', 'es-ES'].flatMap(locale => ['issue', 'pull-request'].map(kind => [locale, kind])))('names %s / %s links for their actual destination', (locale, kind) => { + const value = projection(); + const target = kind === 'issue' ? value.report.target : { kind: 'pull-request' as const, repositoryId: 42, pullNumber: 11 }; + const report = aggregateGithubRuntimeDoctorReport({ target, checks: value.report.checks }); + const body = formatGithubRuntimeDoctor({ ...value, report }, locale); + const caption = locale === 'es-ES' ? kind === 'issue' ? 'Issue inspeccionada' : 'PR inspeccionado' : kind === 'issue' ? 'Inspected issue' : 'Inspected pull request'; + const url = kind === 'issue' ? 'https://github.com/o/r/issues/7' : 'https://github.com/o/r/pull/11'; + expect(body).toContain(`[${caption}](${url})`); + const revisionCaption = locale === 'es-ES' ? 'Revisión inspeccionada del repositorio' : 'Inspected repository revision'; + expect(body).toContain(`[${revisionCaption}](https://github.com/o/r/tree/${'a'.repeat(40)})`); + expect(body).not.toContain(`[${revisionCaption}](${url})`); + }); + it('uses complete English entity captions under unsupported-locale fallback', () => { + const body = formatGithubRuntimeDoctor(projection(), 'fr-FR'); + expect(body).toContain('[Inspected issue](https://github.com/o/r/issues/7)'); + expect(body).toEqual(formatGithubRuntimeDoctor(projection(), 'en-US')); + }); + it('withholds entity links when immutable source provenance is absent', () => { + expect(formatGithubRuntimeDoctor({ ...projection(), revision: undefined })).not.toContain(']('); + }); + it('withholds entity links when source provenance is unsafe', () => { + expect(formatGithubRuntimeDoctor({ ...projection(), serverOrigin: 'https://user:secret@github.com' })).not.toContain(']('); + }); + it('keeps the exact correlated request identity and deterministic rendering', () => { + const results = [new Result({ id: 'IssueCommentUseCase.Doctor', success: true, executed: true, payload: { doctor: projection() } })]; + const context = { results, locale: 'es-ES', target: { kind: 'issue' as const, number: 7 }, correlationId: 'comment:42' }; + const [first] = selectSemanticReplyIntents(context); const [replay] = selectSemanticReplyIntents(context); + expect(first).toEqual(replay); expect(renderSemanticReply(first)).toEqual(renderSemanticReply(replay)); + expect(renderSemanticReply(first)).toContain('[Issue inspeccionada](https://github.com/o/r/issues/7)'); + }); +}); diff --git a/src/application/policies/github_runtime_doctor_presentation_policy.ts b/src/application/policies/github_runtime_doctor_presentation_policy.ts index 4577b43ef..ad22f6ec6 100644 --- a/src/application/policies/github_runtime_doctor_presentation_policy.ts +++ b/src/application/policies/github_runtime_doctor_presentation_policy.ts @@ -46,7 +46,7 @@ export function formatGithubRuntimeDoctor(projection: GithubRuntimeDoctorProject ? message(`source.${evidence}`) : undefined; const mode = group === 'approval-prerequisites' && (evidence === 'off' || evidence === 'recommend' || evidence === 'guarded') ? `${message('mode')}: ${evidence}` : undefined; - lines.push(`- **${message(`group.${group}`)}:** ${message(`state.${state}`)}${policySource ? ` · ${policySource}` : ''}${mode ? ` · ${mode}` : ''}${link ? ` · [${message('source')}](${link})` : ''}`); + lines.push(`- **${message(`group.${group}`)}:** ${message(`state.${state}`)}${policySource ? ` · ${policySource}` : ''}${mode ? ` · ${mode}` : ''}${link ? ` · [${message(target?.kind === 'pull-request' ? 'sourcePullRequest' : 'sourceIssue')}](${link})` : ''}`); } if (source) lines.push('', `[${message('source')}](${source})`); return lines.join('\n'); diff --git a/src/application/policies/publication_message_catalog.ts b/src/application/policies/publication_message_catalog.ts index c7306b21b..c5d589a6b 100644 --- a/src/application/policies/publication_message_catalog.ts +++ b/src/application/policies/publication_message_catalog.ts @@ -113,6 +113,8 @@ const PUBLICATION_SURFACE_MESSAGE_IDS = Object.freeze([ 'interaction.doctor.checks', 'interaction.doctor.readonly', 'interaction.doctor.source', + 'interaction.doctor.sourceIssue', + 'interaction.doctor.sourcePullRequest', 'interaction.doctor.group.effective-configuration', 'interaction.doctor.group.issue-readiness', 'interaction.doctor.group.linked-branch-readiness', @@ -347,6 +349,8 @@ const ENGLISH_MESSAGES: Readonly> = 'interaction.doctor.checks': "Checks", 'interaction.doctor.readonly': "This command reads evidence only. Declared approval settings do not prove producer health or write access.", 'interaction.doctor.source': "Inspected repository revision", + 'interaction.doctor.sourceIssue': "Inspected issue", + 'interaction.doctor.sourcePullRequest': "Inspected pull request", 'interaction.doctor.group.effective-configuration': "Effective configuration", 'interaction.doctor.group.issue-readiness': "Issue and SDD prerequisites", 'interaction.doctor.group.linked-branch-readiness': "Native linked branch", @@ -540,6 +544,8 @@ const SPANISH_MESSAGES: Readonly> = 'interaction.doctor.checks': "Comprobaciones", 'interaction.doctor.readonly': "Este comando solo lee evidencias. La configuración de aprobación declarada no acredita la salud de los productores ni el acceso de escritura.", 'interaction.doctor.source': "Revisión inspeccionada del repositorio", + 'interaction.doctor.sourceIssue': "Issue inspeccionada", + 'interaction.doctor.sourcePullRequest': "PR inspeccionado", 'interaction.doctor.group.effective-configuration': "Configuración efectiva", 'interaction.doctor.group.issue-readiness': "Requisitos de la issue y el SDD", 'interaction.doctor.group.linked-branch-readiness': "Rama enlazada nativa",