chore: Fix all broken links using OpenCode
- chore: Fix all broken links using OpenCode
There were some broken links in release/docs and I kept running into them. So, I used GitLab's wrapper of OpenCode OpenDuo to fix all the broken links at once. I think it did a good job. Any future broken link addition should be caught by GitLab Duo Reviewer.
For posterity, OpenCode with GitLab Duo as backend is allowed for use at GitLab:
source: Slack (internal-only, until 2026-05-20)
This worked with a single prompt to OpenDuo.
OpenCode: Complete Session Transcript
Fix broken internal Markdown links
Session ID: ses_352d9f8d5ffe83S2KEeVqPDD7M Created: 3/2/2026, 11:34:36 AM Updated: 3/2/2026, 11:44:22 AM
User
Look through this codebase and fix all broken Markdown links that point within the codebase
Assistant
Tool: todowrite
Assistant
Tool: read
Assistant
Tool: glob
Assistant
Tool: glob
Assistant
Let me get the complete list and then run a script to find all broken internal links:
Tool: bash
Assistant
Now let me write a script to find all broken internal links:
Tool: bash
Assistant
Tool: todowrite
Assistant
Now let me read each affected file and understand the correct target for each broken link:
Tool: read
Tool: read
Tool: read
Assistant
Tool: read
Tool: read
Tool: read
Assistant
Tool: read
Tool: read
Tool: read
Assistant
Tool: read
Tool: read
Assistant
Tool: read
Tool: read
Tool: read
Assistant
Tool: read
Tool: read
Tool: read
Assistant
Tool: bash
Tool: read
Tool: read
Assistant
Now I have a good picture of all broken links. Let me check a few more details:
Tool: bash
Tool: bash
Assistant
Tool: bash
Tool: bash
Tool: bash
Assistant
Tool: bash
Tool: bash
Assistant
Tool: bash
Assistant
Tool: bash
Tool: bash
Assistant
Tool: read
Tool: bash
Assistant
Now I have all the information I need. Let me also check the general/README.md issue (referenced by ../README.md#guides from files in general/omnibus-packages/ and general/patch/):
Tool: bash
Tool: bash
Assistant
general/README.md doesn't exist. The links ../README.md#guides from general/omnibus-packages/removing-packages.md and general/patch/readme.md are meant to point to the root README.md which does have a ## Guides section. The correct path from general/omnibus-packages/ is ../../README.md#guides, and from general/patch/ it's also ../../README.md#guides.
Now let me also check the general/images/security-pipeline.png issue:
Tool: bash
Tool: bash
Assistant
The file exists at general/images/security-pipeline.png. The link in general/security/utilities/security_pipeline.md is general/images/security-pipeline.png, which resolves relative to the file's directory (general/security/utilities/) as general/security/utilities/general/images/security-pipeline.png — broken. The correct relative path should be ../../images/security-pipeline.png.
Now let me check all the remaining broken items systematically and also check the general/patch/images/patch_release_pressure_panels.png and the runbooks/qa/images/ ones:
Tool: bash
Tool: bash
Assistant
Tool: bash
Assistant
patch_release_pressure_panels.png and rake-tasks.md don't exist in the repo. Let me check for similar files:
Tool: bash
Assistant
Tool: bash
Tool: bash
Assistant
For dashboard.md, the image patch_release_pressure_panels.png doesn't exist - the closest file is patch_release_pressure.png. The link is ../general/patch/images/patch_release_pressure_panels.png from release_manager/dashboard.md, which would resolve to general/patch/images/patch_release_pressure_panels.png.
For publishing-packages.md:
-
rake-tasks.md#releaseversion- this file doesn't exist anywhere. -
images/release.png- the actual file is atgeneral/images/release.png, notgeneral/omnibus-packages/images/release.png.
Let me check the runbooks/qa images:
Tool: bash
Tool: bash
Assistant
The images exist at runbooks/images/, but the links in runbooks/qa/resolving-auto-deploy-qa-failures.md reference ./images/ (which would look in runbooks/qa/images/). The fix is to change ./images/ to ../images/.
Now let me handle the how_to_sync_security_with_canonical.md self-referencing links and the runbooks/incident.md malformed link. Let me also check the runbooks/manually-sync-release-tag.md:
Tool: bash
Tool: read
Assistant
Now I have all the information. Let me fix all the broken links:
Summary of fixes:
-
README.mdline 110:general/database-migrations/readme.md→general/database-migrations/README.md -
README.mdline 156:runbooks/manually-sync-release-tag.md→runbooks/security/manually-sync-release-tag.md -
components/index.mdline 42:general/security/mirrors.md→../general/security/mirrors.md -
components/managed-versioning/index.mdline 134:components/versioning_rules_exceptions.md→../versioning_rules_exceptions.md -
general/monthly/process.mdline 59:../release-candidates.md→./release-candidates.md -
general/omnibus-packages/publishing-packages.mdline 11:rake-tasks.md#releaseversion- no target exists, remove/fix -
general/omnibus-packages/publishing-packages.mdline 54:images/release.png→../images/release.png -
general/omnibus-packages/removing-packages.mdline 59:../README.md#guides→../../README.md#guides -
general/patch/readme.md:../README.md#guides→../../README.md#guides -
general/permissions.mdline 22:./onboarding.md- file doesn't exist, but it's in a reference context -
general/pro-tips.mdline 7:release-manager.md→ norelease-manager.mdingeneral/ -
general/pro-tips.mdline 39:push-to-multiple-remotes.md→ no such file -
general/security/far_reaching_impact_fixes_or_breaking_change_fixes.mdline 10:developer.md#contact-the-appsec-team→engineer.md#contact-the-appsec-team(check) -
general/security/how_to_sync_security_with_canonical.md: self-referencing absolute-style paths -
general/security/utilities/high_severity_issue.md:utilities/post_deployment_patch.md→./post_deployment_patch.md -
general/security/utilities/security_pipeline.md:general/images/security-pipeline.png→../../images/security-pipeline.png -
general/tooling.mdline 23:../monthly/process.md→./monthly/process.md -
release_manager/dashboard.mdline 106:../general/patch/images/patch_release_pressure_panels.png- file doesn't exist -
release_manager/index.mdline 191:dev.gitlab.org- not a link target issue (it's bold text, not a link) -
runbooks/incident.mdline 109: malformed link with double parenthesis -
runbooks/qa/resolving-auto-deploy-qa-failures.md:./images/→../images/ -
runbooks/security/git-security-patches.mdline 42:../../../runbooks/token-management.md→../token-management/token-management.md -
runbooks/security/git-security-patches.mdline 95:../how_to_handle_gitaly_kas_security_merge_requests.md→../../general/security/how_to_handle_gitaly_kas_security_merge_requests.md -
runbooks/security/git-security-patches.mdline 100:../release-manager.md#Critical-Security-Releases→ check
Let me check a few more things before fixing:
Tool: bash
Tool: bash
Assistant
Tool: bash
Tool: bash
Assistant
Tool: bash
Tool: bash
Assistant
Tool: bash
Assistant
The developer.md file doesn't exist, and engineer.md doesn't have a #contact-the-appsec-team anchor. The anchor doesn't exist in any file. I'll point it to engineer.md since that's the most related file for security engineers:
Now let me check general/pro-tips.md links and general/permissions.md:
Tool: bash
Tool: bash
Assistant
push-to-multiple-remotes.md and onboarding.md don't exist anywhere in the repo. These files are simply gone.
For general/pro-tips.md:
-
release-manager.md- the nearest match isrelease_manager/index.md(not ingeneral/) -
push-to-multiple-remotes.md- doesn't exist
For general/permissions.md:
-
./onboarding.md- doesn't exist
For release_manager/dashboard.md:
-
../general/patch/images/patch_release_pressure_panels.png→ the closest file isgeneral/patch/images/patch_release_pressure.png
For runbooks/security/git-security-patches.md:
-
../release-manager.md#Critical-Security-Releases→../../general/security/release-manager.md(check anchor)
Let me check the anchor:
Tool: bash
Tool: bash
Assistant
Tool: bash
Assistant
Tool: bash
Assistant
Tool: bash
Tool: bash
Assistant
Tool: bash
Assistant
The ../release-manager.md#Critical-Security-Releases link in runbooks/security/git-security-patches.md doesn't have a valid destination. It seems to reference an old file. The nearest concept is in general/patch/unplanned_critical_release.md or the security readme. Let me check:
Tool: bash
Tool: bash
Assistant
The link ../release-manager.md#Critical-Security-Releases from runbooks/security/git-security-patches.md — the .. from runbooks/security/ goes to runbooks/, so it's looking for runbooks/release-manager.md which doesn't exist. The closest existing file about critical security releases is general/patch/unplanned_critical_release.md. Let me look at the context more carefully:
The git-security-patches.md says "open a critical security release issue" linking to what was supposed to be a "release-manager.md#Critical-Security-Releases". The general/security/release-manager.md is the correct target (for the release manager in security releases). The section doesn't exist but the file does. I'll link to ../../general/security/release-manager.md without the anchor since the anchor doesn't exist.
Now let me check the how_to_sync_security_with_canonical.md self-referencing links:
Tool: read
Assistant
The links general/security/how_to_sync_security_with_canonical.md#... are absolute-style paths (they don't start with /) but are treated as relative from the file's own directory, causing them to resolve incorrectly. Since they're self-referencing (same file), they should just be #anchor-name.
Now I have everything I need to make all fixes. Let me proceed:
Tool: edit
Assistant
Tool: edit
Assistant
Tool: edit
Assistant
Tool: edit
Assistant
Tool: read
Assistant
Tool: edit
Assistant
Now fix general/omnibus-packages/publishing-packages.md:
Tool: edit
Assistant
Tool: edit
Assistant
Tool: edit
Assistant
Tool: bash
Assistant
Tool: read
Assistant
Tool: edit
Assistant
Now fix general/permissions.md - ./onboarding.md doesn't exist. Let me remove the link target:
Tool: read
Assistant
Tool: edit
Assistant
Also fix the Return to Guides link in permissions.md which points to ../README.md#guides — from general/permissions.md, ../ goes to the root, so ../README.md is correct! Let me verify:
Tool: bash
Assistant
Good, ../README.md#guides from general/permissions.md is correct. Now fix general/pro-tips.md:
Tool: edit
Assistant
Tool: edit
Assistant
Now fix general/security/far_reaching_impact_fixes_or_breaking_change_fixes.md — developer.md#contact-the-appsec-team doesn't exist. The closest file is engineer.md but it doesn't have that anchor either. I'll link to engineer.md as it's the developer-facing security doc:
Tool: edit
Assistant
Now fix general/security/how_to_sync_security_with_canonical.md — self-referencing links:
Tool: edit
Assistant
Now fix general/security/utilities/high_severity_issue.md:
Tool: edit
Assistant
Now fix general/security/utilities/security_pipeline.md:
Tool: edit
Assistant
Now fix general/tooling.md:
Tool: read
Assistant
The general/tooling.md link says ../monthly/process.md - from general/tooling.md, ../ goes to the root, so this resolves to monthly/process.md which doesn't exist. The correct path is ./monthly/process.md:
Tool: edit
Assistant
Now fix release_manager/dashboard.md — the image patch_release_pressure_panels.png doesn't exist but patch_release_pressure.png does:
Tool: read
Assistant
Tool: edit
Assistant
Now fix release_manager/index.md — dev.gitlab.org is in bold text **For [Dev](dev.gitlab.org) repositories**. This is a link without a protocol:
Tool: edit
Assistant
Now fix runbooks/incident.md — malformed link with double parenthesis:
Tool: read
Assistant
Tool: edit
Assistant
Now fix runbooks/qa/resolving-auto-deploy-qa-failures.md image links:
Tool: edit
Assistant
Tool: edit
Assistant
Now fix runbooks/security/git-security-patches.md:
Tool: edit
Assistant
Tool: edit
Assistant
Tool: edit
Assistant
Now let me run the broken link check again to verify all fixes:
Tool: bash
Assistant
Tool: todowrite
Assistant
All 26 broken links fixed. Here's a summary of the changes:
| File | Fix |
|---|---|
README.md |
general/database-migrations/readme.md → README.md; runbooks/manually-sync-release-tag.md → runbooks/security/manually-sync-release-tag.md
|
components/index.md |
general/security/mirrors.md → ../general/security/mirrors.md
|
components/managed-versioning/index.md |
components/versioning_rules_exceptions.md → ../versioning_rules_exceptions.md
|
general/monthly/process.md |
../release-candidates.md → ./release-candidates.md
|
general/omnibus-packages/publishing-packages.md |
Removed broken rake-tasks.md link (file doesn't exist); images/release.png → ../images/release.png
|
general/omnibus-packages/removing-packages.md |
../README.md#guides → ../../README.md#guides
|
general/patch/readme.md |
../README.md#guides → ../../README.md#guides
|
general/permissions.md |
Removed link to non-existent onboarding.md
|
general/pro-tips.md |
release-manager.md → ../release_manager/index.md; removed link to non-existent push-to-multiple-remotes.md
|
general/security/far_reaching_impact_fixes_or_breaking_change_fixes.md |
developer.md#contact-the-appsec-team → engineer.md
|
general/security/how_to_sync_security_with_canonical.md |
Self-referencing absolute paths → #anchor
|
general/security/utilities/high_severity_issue.md |
utilities/post_deployment_patch.md → ./post_deployment_patch.md
|
general/security/utilities/security_pipeline.md |
general/images/security-pipeline.png → ../../images/security-pipeline.png
|
general/tooling.md |
../monthly/process.md → ./monthly/process.md
|
release_manager/dashboard.md |
patch_release_pressure_panels.png → patch_release_pressure.png
|
release_manager/index.md |
dev.gitlab.org → https://dev.gitlab.org
|
runbooks/incident.md |
Fixed malformed double-parenthesis ((url)) → (url)
|
runbooks/qa/resolving-auto-deploy-qa-failures.md |
./images/ → ../images/ (×2) |
runbooks/security/git-security-patches.md |
../../../runbooks/token-management.md → ../token-management/token-management.md; ../how_to_handle_gitaly_kas_security_merge_requests.md → ../../general/security/...; ../release-manager.md#Critical-Security-Releases → ../../general/security/release-manager.md
|
