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
2 changes: 1 addition & 1 deletion .copilot/AGENT_GUIDE.md
Original file line number Diff line number Diff line change
Expand Up @@ -41,4 +41,4 @@ Do not add the `deploy` label, dispatch a deployment, or create a tag/release wi

Never expose credentials, tokens, private keys, or other secrets in issues, commits, pull requests, logs, or diagnostic comments.

For the full contributor flow, read [repository collaboration](../docs/agents/repository-collaboration.mdx). For drift and recovery, read [guidance troubleshooting](../docs/agents/repository-guidance-troubleshooting.mdx).
For the full contributor flow, read [repository collaboration](https://github.com/vypdev/copilot/blob/master/docs/agents/repository-collaboration.mdx). For drift and recovery, read [guidance troubleshooting](https://github.com/vypdev/copilot/blob/master/docs/agents/repository-guidance-troubleshooting.mdx).
2 changes: 1 addition & 1 deletion .copilot/setup-manifest.json
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@
},
".copilot/AGENT_GUIDE.md": {
"role": "guide",
"sha256": "7065adc3383f2b05abda31ea533fe8490c7bde7f003bf12cdfa9516420163ef1"
"sha256": "79d317cfbe614492559812353294b8ea7fb14f5fc61c3d4aacb1b4216b5b00cf"
},
".copilot/repository-profile.json": {
"role": "profile",
Expand Down
2 changes: 1 addition & 1 deletion build/cli/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -45865,7 +45865,7 @@ Do not add the \`${profile.deployment.launcherLabel}\` label, dispatch a deploym

Never expose credentials, tokens, private keys, or other secrets in issues, commits, pull requests, logs, or diagnostic comments.

For the full contributor flow, read [repository collaboration](../docs/agents/repository-collaboration.mdx). For drift and recovery, read [guidance troubleshooting](../docs/agents/repository-guidance-troubleshooting.mdx).
For the full contributor flow, read [repository collaboration](https://github.com/vypdev/copilot/blob/master/docs/agents/repository-collaboration.mdx). For drift and recovery, read [guidance troubleshooting](https://github.com/vypdev/copilot/blob/master/docs/agents/repository-guidance-troubleshooting.mdx).
`;
}
function renderRepositoryAgentSkill() {
Expand Down
2 changes: 1 addition & 1 deletion build/github_action/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -47360,7 +47360,7 @@ Do not add the \`${profile.deployment.launcherLabel}\` label, dispatch a deploym

Never expose credentials, tokens, private keys, or other secrets in issues, commits, pull requests, logs, or diagnostic comments.

For the full contributor flow, read [repository collaboration](../docs/agents/repository-collaboration.mdx). For drift and recovery, read [guidance troubleshooting](../docs/agents/repository-guidance-troubleshooting.mdx).
For the full contributor flow, read [repository collaboration](https://github.com/vypdev/copilot/blob/master/docs/agents/repository-collaboration.mdx). For drift and recovery, read [guidance troubleshooting](https://github.com/vypdev/copilot/blob/master/docs/agents/repository-guidance-troubleshooting.mdx).
`;
}
function renderRepositoryAgentSkill() {
Expand Down
2 changes: 2 additions & 0 deletions docs/agents/repository-collaboration.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,8 @@ Repository collaborator agents use the same public controls as human contributor

The profile contains only enabled kinds, effective forms and labels, required fields, branch roles, relevant release/hotfix workflow names, PR linkage, and deployment boundaries. It contains no token, Secret, arbitrary action input, executable command, or provider response.

The generated guide links to the shared documentation in `vypdev/copilot` through absolute HTTPS URLs. These links follow the source repository's `master` documentation, so destination repositories do not need a copied documentation tree. Links to installed artifacts, such as `repository-profile.json`, remain relative to the generated guide.

## Expected agent flow

1. Read the nearest repository instructions, profile, and guide.
Expand Down
2 changes: 2 additions & 0 deletions docs/agents/repository-guidance-troubleshooting.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -25,4 +25,6 @@ The named checks cover the manifest, profile schema and runtime parity, guide di

Setup writes each generated artifact atomically and the manifest last. Approved replacements and retirements are copied or moved under `.copilot/setup-backups/`. If a run stops before the manifest advances, rerun with the same configuration: desired bytes are recognized, while unrelated or drifted bytes remain untouched.

Older generated guides may link to `../docs/agents/` files that were never installed in the destination repository. Update Copilot and rerun setup with the same configuration to replace an unchanged, setup-owned guide with absolute links to the shared documentation. The previous guide is backed up. If the guide was edited or is not setup-owned, preserve those edits and follow the normal conflict recovery above.

Do not repair drift by editing `.copilot/repository-profile.json` or its hashes. Change the setup configuration and rerun setup so forms, Variables, workflows, guide, skill, and manifest converge from one plan.
4 changes: 2 additions & 2 deletions specs/CATALOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ debt or convert unknown historic intent into a design decision.
| `agent-runtime` | Implemented | Resolve, provision, authenticate, authorize, and execute only the agent roles reachable by a run | [Agent runtime, provider, model, and role routing](./agent-runtime-provider-and-model-routing.md) + 1 companion | 96 paths · 2026-10-14 |
| `cli-and-single-actions` | As-built baseline | Expose bounded local commands and workflow-dispatched operations through the shared application core | [CLI and single-action execution](./cli-and-single-action-execution.md) | 33 paths · 2026-09-16 |
| `configurable-issue-workflows` | Implemented | Select one canonical set of issue workflows and enforce its forms, dependencies, branch policy, runtime admission, migration, and diagnosis | [Configurable issue workflows and fail-closed admission](./configurable-issue-workflows-and-admission.md) | 89 paths · 2026-10-13 |
| `repository-agent-collaboration` | Implemented | Generate safe repository-local profiles, guidance, and a skill for agents contributing through configured issues, Action-managed branches, pull requests, and deployment boundaries | [Repository agent collaboration contract](./repository-agent-collaboration-contract.md) | 47 paths · 2026-10-12 |
| `repository-agent-collaboration` | Implemented | Generate safe repository-local profiles, guidance, and a skill for agents contributing through configured issues, Action-managed branches, pull requests, and deployment boundaries | [Repository agent collaboration contract](./repository-agent-collaboration-contract.md) | 47 paths · 2026-10-17 |
| `guarded-pull-request-approval` | Proposed | Specify and locally implement revision-bound, evidence-gated native bot approvals for eligible human pull requests, with safe setup defaults, read-only doctor checks, and explainable recovery | [Guarded pull-request approval and setup readiness](./guarded-pull-request-approval.md) + 2 companion | 90 paths · 2026-10-17 |

## Evidence map
Expand Down Expand Up @@ -246,7 +246,7 @@ debt or convert unknown historic intent into a design decision.
### `repository-agent-collaboration` — Repository agent collaboration contract

- Owner: Copilot maintainers
- Last verified: 2026-10-12
- Last verified: 2026-10-17
- Specifications: [`specs/repository-agent-collaboration-contract.md`](./repository-agent-collaboration-contract.md)
- Workflows: Not applicable for this capability.
- Entrypoints: [`package.json`](../package.json) · [`src/cli/commands/setup.ts`](../src/cli/commands/setup.ts) · [`src/cli/commands/doctor.ts`](../src/cli/commands/doctor.ts)
Expand Down
2 changes: 1 addition & 1 deletion specs/catalog.json
Original file line number Diff line number Diff line change
Expand Up @@ -2192,7 +2192,7 @@
"status": "implemented",
"scope": "Generate safe repository-local profiles, guidance, and a skill for agents contributing through configured issues, Action-managed branches, pull requests, and deployment boundaries",
"owner": "Copilot maintainers",
"lastVerified": "2026-10-12",
"lastVerified": "2026-10-17",
"specs": [
"specs/repository-agent-collaboration-contract.md"
],
Expand Down
23 changes: 16 additions & 7 deletions specs/repository-agent-collaboration-contract.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,10 @@
- Status: Implemented — automated local gates and Codex dogfood complete; broader agent-discovery UX evidence remains pending
- Date: 2026-09-16
- Catalog capability ID: `repository-agent-collaboration`
- Last verified: 2026-10-12
- Last verified: 2026-10-17 (portable documentation links, issue #539)
- Owners: Copilot maintainers
- Scope: setup-generated, repository-local guidance that lets coding agents collaborate through configured issues, Action-managed branches, pull requests, and deployment boundaries
- Related issues/PRs: none yet; related SDDs are listed in section 20
- Related issues/PRs: [#539](https://github.com/vypdev/copilot/issues/539); related SDDs are listed in section 20
- Required review gates: product UX, architecture, testing, documentation, security/operations
- Open decisions blocking readiness: none

Expand Down Expand Up @@ -761,11 +761,11 @@ optional marker preserves all surrounding `AGENTS.md` text byte-for-byte.
|---|---:|---|
| Profile schema, safe projection, canonical rendering | 18 | enabled subsets, labels/forms/branches, allowlist, ordering, digest, unknown schema/keys, secret exclusion |
| Ownership, setup planning, reconcile, retirement | 20 | new/matching/drifted/unowned, malformed markers, byte preservation, backup, manifest-last, partial rerun, disable/retire |
| Guide and skill semantic contract | 18 | metadata, trigger scope, issue forms, help no-branch, exact branch rule, local tracking, PR flow, labels/deploy, recovery, internal-agent distinction |
| Guide and skill semantic contract | 19 | metadata, trigger scope, issue forms, help no-branch, exact branch rule, local tracking, PR flow, labels/deploy, recovery, internal-agent distinction, links in a documentation-free target |
| Package, doctor, architecture, documentation | 29 | packed assets, installed smoke generation, named read-only checks, no internal prompt import, links/nav, schema fixtures |
| UX, localization, sanitization, security | 12 | five states, narrow/no-color, escaping, no mentions/secrets/paths, locale fallback, conflict actions |
| Integration, migration, rollback, dogfood | 12 | existing AGENTS/skills, pointer declined, schema migration, disable/restore, form/profile parity, positive and negative end-to-end flow |
| **Total** | **109** | No double counting |
| Integration, migration, rollback, dogfood | 13 | existing AGENTS/skills, pointer declined, schema migration, legacy guide link upgrade, disable/restore, form/profile parity, positive and negative end-to-end flow |
| **Total** | **111** | No double counting |

The issue-workflow domain and setup/rendering decision policies named by the
`Configurable issue workflows and repository agent guidance` coverage budget
Expand Down Expand Up @@ -793,8 +793,11 @@ and guide readability on GitHub mobile.

README and `docs/features.mdx` describe repository collaborator guidance without
calling it part of the internal Action runtime. `docs.json` exposes both the
collaboration and troubleshooting pages. Generated guide links are relative
where possible and are checked against packaged/default repository fixtures.
collaboration and troubleshooting pages. Generated links to shared Copilot
documentation MUST use absolute HTTPS URLs in `vypdev/copilot` on `master`,
independent of the destination repository. Relative Markdown links MUST resolve
to artifacts actually installed in that destination; the local profile link
remains relative. Setup does not copy the upstream documentation tree.

## 16. Acceptance scenarios

Expand Down Expand Up @@ -834,6 +837,12 @@ where possible and are checked against packaged/default repository fixtures.
14. Given this repository's existing `AGENTS.md` and skill, then dogfood setup
preserves them, adds the bounded collaboration artifacts, and all package,
doctor, security, and documentation checks pass.
15. Given a fresh destination without the Copilot documentation tree, then all
generated relative Markdown links resolve locally and both shared-document
links identify existing upstream pages by absolute URL.
16. Given a hash-owned legacy guide with relative shared-document links, then
setup backs it up, updates the guide and manifest together, keeps the
profile digest unchanged, and performs no writes on the next identical run.

## 17. Requirements traceability

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -182,7 +182,7 @@ Do not add the \`${profile.deployment.launcherLabel}\` label, dispatch a deploym

Never expose credentials, tokens, private keys, or other secrets in issues, commits, pull requests, logs, or diagnostic comments.

For the full contributor flow, read [repository collaboration](../docs/agents/repository-collaboration.mdx). For drift and recovery, read [guidance troubleshooting](../docs/agents/repository-guidance-troubleshooting.mdx).
For the full contributor flow, read [repository collaboration](https://github.com/vypdev/copilot/blob/master/docs/agents/repository-collaboration.mdx). For drift and recovery, read [guidance troubleshooting](https://github.com/vypdev/copilot/blob/master/docs/agents/repository-guidance-troubleshooting.mdx).
`;
}

Expand Down
63 changes: 63 additions & 0 deletions src/utils/__tests__/setup_files.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -125,6 +125,69 @@ describe('setup_files', () => {
expect(fs.readFileSync(manifestPath, 'utf8')).toBe(manifestBefore);
});

it('resolves generated Markdown links without installing the Copilot documentation tree', () => {
const sourceRoot = path.resolve(__dirname, '../../..');
const configuration = createDefaultSetupConfiguration();
ensureGitHubDirs(tmpDir);
copySetupFiles(tmpDir, path.join(sourceRoot, 'setup'), configuration.features, { setupConfiguration: configuration });

const documentationLinks: string[] = [];
for (const relative of ['.copilot/AGENT_GUIDE.md', '.agents/skills/copilot-repository-workflow/SKILL.md', 'AGENTS.md']) {
const file = path.join(tmpDir, relative);
const content = fs.readFileSync(file, 'utf8');
for (const match of content.matchAll(/\[[^\]]*\]\(([^)]+)\)/gu)) {
const destination = match[1];
if (destination.startsWith('https://')) {
const url = new URL(destination);
expect(url.origin).toBe('https://github.com');
expect(url.pathname).toMatch(/^\/vypdev\/copilot\/blob\/master\/docs\/agents\//u);
expect(fs.existsSync(path.join(sourceRoot, url.pathname.replace('/vypdev/copilot/blob/master/', '')))).toBe(true);
documentationLinks.push(destination);
} else {
expect(fs.existsSync(path.resolve(path.dirname(file), destination))).toBe(true);
}
}
}

expect(documentationLinks).toEqual([
'https://github.com/vypdev/copilot/blob/master/docs/agents/repository-collaboration.mdx',
'https://github.com/vypdev/copilot/blob/master/docs/agents/repository-guidance-troubleshooting.mdx',
]);
expect(fs.existsSync(path.join(tmpDir, 'docs'))).toBe(false);
});

it('upgrades an owned guide with legacy documentation links and keeps its backup and manifest consistent', () => {
const setupDir = path.resolve(__dirname, '../../../setup');
const configuration = createDefaultSetupConfiguration();
ensureGitHubDirs(tmpDir);
copySetupFiles(tmpDir, setupDir, configuration.features, { setupConfiguration: configuration });
const guidePath = path.join(tmpDir, '.copilot/AGENT_GUIDE.md');
const manifestPath = path.join(tmpDir, '.copilot/setup-manifest.json');
const legacyGuide = fs.readFileSync(guidePath, 'utf8')
.split('https://github.com/vypdev/copilot/blob/master/docs/agents/').join('../docs/agents/');
fs.writeFileSync(guidePath, legacyGuide);
const previousManifest = JSON.parse(fs.readFileSync(manifestPath, 'utf8'));
previousManifest.artifacts['.copilot/AGENT_GUIDE.md'].sha256 = createHash('sha256').update(legacyGuide).digest('hex');
fs.writeFileSync(manifestPath, `${JSON.stringify(previousManifest, null, 2)}\n`);

const result = copySetupFiles(tmpDir, setupDir, configuration.features, { setupConfiguration: configuration });

const currentGuide = fs.readFileSync(guidePath, 'utf8');
expect(currentGuide).toContain('https://github.com/vypdev/copilot/blob/master/docs/agents/repository-collaboration.mdx');
expect(currentGuide).not.toContain('](../docs/');
expect(result.copied).toBe(2);
const currentManifest = JSON.parse(fs.readFileSync(manifestPath, 'utf8'));
expect(currentManifest.profileDigest).toBe(previousManifest.profileDigest);
expect(currentManifest.artifacts['.copilot/AGENT_GUIDE.md'].sha256)
.toBe(createHash('sha256').update(currentGuide).digest('hex'));
const backups = fs.readdirSync(path.join(tmpDir, '.copilot/setup-backups'), { recursive: true })
.filter(file => String(file).endsWith('AGENT_GUIDE.md'));
expect(backups).toHaveLength(1);
expect(fs.readFileSync(path.join(tmpDir, '.copilot/setup-backups', String(backups[0])), 'utf8')).toBe(legacyGuide);
expect(inspectRepositoryAgentGuidance(tmpDir, configuration).filter(check => check.status === 'fail')).toEqual([]);
expect(copySetupFiles(tmpDir, setupDir, configuration.features, { setupConfiguration: configuration }).copied).toBe(0);
});

it('treats CRLF-only checkout guidance as owned, current, and unchanged on rerun', () => {
const setupDir = path.resolve(__dirname, '../../../setup');
const configuration = createDefaultSetupConfiguration();
Expand Down
Loading