mirror of
https://github.com/coder/coder.git
synced 2026-10-16 14:48:56 +08:00
Rewrites the headings and page titles that `Coder.GerundHeading` flags as gerund-leading, using the imperative for tasks and the noun form for concepts. This PR covers only changes that don't rename a page slug. ## Changes - Rewrites 121 in-page headings, bringing `Coder.GerundHeading` findings in `docs/` to zero. - Adds an empty `<a id="old-slug"></a>` above each renamed heading, so existing bookmarks and inbound deep links still land on the section. The legacy IDs were computed with the same slugger the classic renderer uses (`rehype-slug`), and all 115 that exist on production today match the live `id` attributes; the other 6 are on pages not published yet. - Updates the 18 in-docs links that targeted old anchors to use the new slugs, and the link text that quoted the old heading. - De-gerunds seven page titles (frontmatter and `manifest.json`) whose slugs don't change, for example `Upgrading Best Practices` to `Upgrade best practices`. - Scopes a Vale exception around the glossary term `Coding agent`, where "Coding" is an adjective. ## Not in this PR - **Pages with gerund slugs** (`creating-templates`, `getting-started`, `working-with-dev-containers`, `cloning-git-repositories`, `configuring-okta`, and others) keep their current titles, so the title and slug change together in the slug-rename PR. The redirects for those renames come in a third PR. - **Links outside `docs/`** to old anchors (Go notification strings, an applied SQL migration, golden files, and the generated `prometheus.md`) still target old slugs. They keep working through the legacy anchors, and updating them would need code changes. ## Known limitation `coder/docs-engine` prefixes raw-HTML `id` attributes with `user-content-` (DOM-clobbering protection), and inbound deep links aren't rewritten. Once the docs move to docs-engine, these legacy anchors resolve only as `#user-content-<old-slug>` unless docs-engine adds a fragment fallback. They work on the current coder.com renderer and on GitHub. ## Testing - `vale --filter='.Name=="Coder.GerundHeading"' docs`: zero findings, down from 122. - `make lint/markdown`, `make lint/docs-html`, `make lint/emdash`, and the pre-commit hook: all pass. - Scripted check that every relative `#fragment` link into a changed file resolves to a heading slug or a legacy anchor (177 links). - Scripted check that no legacy ID collides with a heading slug on the same page, and that no untouched heading's duplicate-suffix slug shifted. <details> <summary>Heading renames and legacy anchors (121)</summary> | File | Old heading | New heading | Legacy anchor | | --- | --- | --- | --- | | `admin/integrations/opentofu.md` | Using a custom Terraform binary | Use a custom Terraform binary | `#using-a-custom-terraform-binary` | | `admin/monitoring/connection-logs.md` | Capturing/Exporting Connection Logs | Capture and export connection logs | `#capturingexporting-connection-logs` | | `admin/monitoring/metrics.md` | Setting up metrics | Set up metrics | `#setting-up-metrics` | | `admin/networking/port-forwarding.md` | Accessing workspace ports | Access workspace ports | `#accessing-workspace-ports` | | `admin/networking/port-forwarding.md` | Sharing ports | Share ports | `#sharing-ports` | | `admin/networking/port-forwarding.md` | Configuring port protocol | Configure port protocol | `#configuring-port-protocol` | | `admin/networking/workspace-proxies.md` | Running on Kubernetes | Run on Kubernetes | `#running-on-kubernetes` | | `admin/networking/workspace-proxies.md` | Running on a VM | Run on a VM | `#running-on-a-vm` | | `admin/networking/workspace-proxies.md` | Running as a system service | Run as a system service | `#running-as-a-system-service` | | `admin/networking/workspace-proxies.md` | Running in Docker | Run in Docker | `#running-in-docker` | | `admin/networking/workspace-proxies.md` | Selecting a proxy | Select a proxy | `#selecting-a-proxy` | | `admin/security/audit-logs.md` | Capturing/Exporting Audit Logs | Capture and export audit logs | `#capturingexporting-audit-logs` | | `admin/security/audit-logs.md` | Purging Old Audit Logs | Purge old audit logs | `#purging-old-audit-logs` | | `admin/security/database-encryption.md` | Enabling encryption | Turn on encryption | `#enabling-encryption` | | `admin/security/database-encryption.md` | Rotating keys | Rotate keys | `#rotating-keys` | | `admin/security/database-encryption.md` | Disabling encryption | Turn off encryption | `#disabling-encryption` | | `admin/security/database-encryption.md` | Deleting Encrypted Data | Delete encrypted data | `#deleting-encrypted-data` | | `admin/security/secrets.md` | Displaying Secrets | Display secrets | `#displaying-secrets` | | `admin/setup/data-retention.md` | Keeping Data Indefinitely | Keep data indefinitely | `#keeping-data-indefinitely` | | `admin/setup/index.md` | Migrating from the built-in database to an external database | Migrate from the built-in database to an external database | `#migrating-from-the-built-in-database-to-an-external-database` | | `admin/setup/index.md` | Configuring Coder behind a proxy | Configure Coder behind a proxy | `#configuring-coder-behind-a-proxy` | | `admin/setup/telemetry.md` | Toggling | Turn telemetry on or off | `#toggling` | | `admin/templates/creating-templates.md` | Disabling the template builder | Turn off the template builder | `#disabling-the-template-builder` | | `admin/templates/extending-templates/agent-metadata.md` | Managing the database load | Manage the database load | `#managing-the-database-load` | | `admin/templates/extending-templates/docker-in-workspaces.md` | Authenticating with a Private Registry | Authenticate with a private registry | `#authenticating-with-a-private-registry` | | `admin/templates/extending-templates/index.md` | Running scripts on workspace lifecycle | Run scripts on workspace lifecycle events | `#running-scripts-on-workspace-lifecycle` | | `admin/templates/extending-templates/parameters.md` | Validating parameters | Validate parameters | `#validating-parameters` | | `admin/templates/extending-templates/prebuilt-workspaces.md` | Invalidating prebuilds | Invalidate prebuilds | `#invalidating-prebuilds` | | `admin/templates/extending-templates/prebuilt-workspaces.md` | Managing resource quotas | Manage resource quotas | `#managing-resource-quotas` | | `admin/templates/extending-templates/prebuilt-workspaces.md` | Managing prebuild provisioning queues | Manage prebuild provisioning queues | `#managing-prebuild-provisioning-queues` | | `admin/templates/extending-templates/prebuilt-workspaces.md` | Preventing resource replacement | Prevent resource replacement | `#preventing-resource-replacement` | | `admin/templates/extending-templates/prebuilt-workspaces.md` | Preventing prebuild queue contention (recommended) | Prevent prebuild queue contention (recommended) | `#preventing-prebuild-queue-contention-recommended` | | `admin/templates/extending-templates/process-logging.md` | Configuring custom templates to use workspace process logging | Configure custom templates to use workspace process logging | `#configuring-custom-templates-to-use-workspace-process-logging` | | `admin/templates/extending-templates/process-logging.md` | Viewing workspace process logs | View workspace process logs | `#viewing-workspace-process-logs` | | `admin/templates/extending-templates/process-priority.md` | Verifying the feature is enabled | Verify the feature is enabled | `#verifying-the-feature-is-enabled` | | `admin/templates/extending-templates/resource-metadata.md` | Hiding resources in the dashboard | Hide resources in the dashboard | `#hiding-resources-in-the-dashboard` | | `admin/templates/extending-templates/resource-metadata.md` | Using a custom resource icon | Use a custom resource icon | `#using-a-custom-resource-icon` | | `admin/templates/extending-templates/resource-ordering.md` | Using "order" property | Use the "order" property | `#using-order-property` | | `admin/templates/extending-templates/resource-persistence.md` | Disabling persistence | Turn off persistence | `#disabling-persistence` | | `admin/templates/index.md` | Extending templates | Extend templates | `#extending-templates` | | `admin/templates/managing-templates/change-management.md` | Testing and Publishing Coder Templates in CI/CD | Test and publish Coder templates in CI/CD | `#testing-and-publishing-coder-templates-in-cicd` | | `admin/templates/managing-templates/index.md` | Creating templates | Create templates | `#creating-templates` | | `admin/templates/managing-templates/index.md` | Editing templates | Edit templates | `#editing-templates` | | `admin/templates/managing-templates/index.md` | Updating templates | Update templates | `#updating-templates` | | `admin/templates/troubleshooting.md` | Debugging the startup script | Debug the startup script | `#debugging-the-startup-script` | | `admin/users/groups-roles.md` | Creating custom roles | Create custom roles | `#creating-custom-roles` | | `admin/users/index.md` | Configuring SSO | Configure SSO | `#configuring-sso` | | `admin/users/index.md` | Resetting a password on Kubernetes | Reset a password on Kubernetes | `#resetting-a-password-on-kubernetes` | | `admin/users/quotas.md` | Establishing Costs | Establish costs | `#establishing-costs` | | `admin/users/quotas.md` | Establishing Budgets | Establish budgets | `#establishing-budgets` | | `admin/users/sessions-tokens.md` | Creating tokens with scopes | Create tokens with scopes | `#creating-tokens-with-scopes` | | `ai-coder/agent-firewall/index.md` | Getting Started with Agent Firewall | Get started with Agent Firewall | `#getting-started-with-agent-firewall` | | `ai-coder/agent-firewall/index.md` | Viewing Audit Logs | View audit logs | `#viewing-audit-logs` | | `ai-coder/agent-firewall/nsjail/k8s.md` | Running without user namespaces | Run without user namespaces | `#running-without-user-namespaces` | | `ai-coder/agent-firewall/version.md` | Using Coder Before v2.30.0 with Claude Code Module v4.7.0+ | Coder before v2.30.0 with Claude Code module v4.7.0+ | `#using-coder-before-v2300-with-claude-code-module-v470` | | `ai-coder/agent-firewall/version.md` | Using Claude Code Module Before v4.7.0 | Claude Code module before v4.7.0 | `#using-claude-code-module-before-v470` | | `ai-coder/agents/getting-started.md` | Providing feedback | Provide feedback | `#providing-feedback` | | `ai-coder/agents/models.md` | Managing personal API keys | Manage personal API keys | `#managing-personal-api-keys` | | `ai-coder/agents/models.md` | Removing a personal key | Remove a personal key | `#removing-a-personal-key` | | `ai-coder/agents/models.md` | Using an LLM proxy | Use an LLM proxy | `#using-an-llm-proxy` | | `ai-coder/agents/platform-controls/git-providers.md` | Checking logs | Check logs | `#checking-logs` | | `ai-coder/ai-gateway/audit.md` | Navigating the UI | Navigate the UI | `#navigating-the-ui` | | `ai-coder/ai-gateway/audit.md` | Conducting a forensic audit | Conduct a forensic audit | `#conducting-a-forensic-audit` | | `ai-coder/ai-gateway/clients/jetbrains.md` | Using the AI Assistant | Use the AI Assistant | `#using-the-ai-assistant` | | `install/operate/upgrade/best-practices.md` | Diagnosing liveness probe issues | Diagnose liveness probe issues | `#diagnosing-liveness-probe-issues` | | `install/operate/upgrade/best-practices.md` | Recovering from failed database migrations | Recover from failed database migrations | `#recovering-from-failed-database-migrations` | | `install/operate/upgrade/esr-2.24-2.29-upgrade.md` | Upgrading | Upgrade recommendations | `#upgrading` | | `install/operate/upgrade/esr-2.29-2.34-upgrade.md` | Upgrading | Upgrade recommendations | `#upgrading` | | `install/prepare/licensing.md` | Adding your license key | Add your license key | `#adding-your-license-key` | | `install/server/cloud/azure-vm.md` | Creating and Uploading Your First Template | Create and upload your first template | `#creating-and-uploading-your-first-template` | | `install/server/cloud/compute-engine.md` | Configuring the control plane | Configure the control plane | `#configuring-the-control-plane` | | `reference/releases.md` | Installing stable | Install stable | `#installing-stable` | | `start/first-workspace.md` | Creating your first coder workspace | Create your first Coder workspace | `#creating-your-first-coder-workspace` | | `start/local-deploy.md` | Setting up a Coder deployment | Set up a Coder deployment | `#setting-up-a-coder-deployment` | | `tutorials/best-practices/organizations.md` | Managing Organizations at Scale | Manage organizations at scale | `#managing-organizations-at-scale` | | `tutorials/example-guide.md` | Adding Photos | Add photos | `#adding-photos` | | `tutorials/example-guide.md` | Setting the author data | Set the author data | `#setting-the-author-data` | | `tutorials/example-guide.md` | Setting up the routes | Set up the routes | `#setting-up-the-routes` | | `tutorials/persistent-shared-workspaces.md` | Finding shared workspaces | Find shared workspaces | `#finding-shared-workspaces` | | `tutorials/reverse-proxy-caddy.md` | Getting started | Get started | `#getting-started` | | `tutorials/reverse-proxy-caddy.md` | Generating wildcard certificates | Generate wildcard certificates | `#generating-wildcard-certificates` | | `tutorials/reverse-proxy-nginx.md` | Adding Coder deployment subdomain | Add the Coder deployment subdomain | `#adding-coder-deployment-subdomain` | | `tutorials/testing-templates.md` | Creating the headless user | Create the headless user | `#creating-the-headless-user` | | `user-guides/desktop/desktop-connect-sync.md` | Accessing web apps in a secure browser context | Access web apps in a secure browser context | `#accessing-web-apps-in-a-secure-browser-context` | | `user-guides/desktop/index.md` | Testing Your Connection | Test your connection | `#testing-your-connection` | | `user-guides/desktop/index.md` | Getting Help | Get help | `#getting-help` | | `user-guides/desktop/index.md` | Uninstalling | Uninstall Coder Desktop | `#uninstalling` | | `user-guides/devcontainers/index.md` | Getting started | Get started | `#getting-started` | | `user-guides/devcontainers/troubleshooting-dev-containers.md` | Finding your dev container agent | Find your dev container agent | `#finding-your-dev-container-agent` | | `user-guides/devcontainers/troubleshooting-dev-containers.md` | Getting more help | Get more help | `#getting-more-help` | | `user-guides/devcontainers/working-with-dev-containers.md` | Using the Coder CLI | Use the Coder CLI | `#using-the-coder-cli` | | `user-guides/devcontainers/working-with-dev-containers.md` | Using OpenSSH (config-ssh) | Use OpenSSH (config-ssh) | `#using-openssh-config-ssh` | | `user-guides/devcontainers/working-with-dev-containers.md` | Exposing ports on the parent workspace | Expose ports on the parent workspace | `#exposing-ports-on-the-parent-workspace` | | `user-guides/devcontainers/working-with-dev-containers.md` | Rebuilding dev containers | Rebuild dev containers | `#rebuilding-dev-containers` | | `user-guides/shared-workspaces.md` | Getting Started | Get started | `#getting-started` | | `user-guides/shared-workspaces.md` | Sharing your Workspace | Share your workspace | `#sharing-your-workspace` | | `user-guides/shared-workspaces.md` | Using a shared workspace | Use a shared workspace | `#using-a-shared-workspace` | | `user-guides/shared-workspaces.md` | Accessing workspace apps in shared workspaces | Access workspace apps in shared workspaces | `#accessing-workspace-apps-in-shared-workspaces` | | `user-guides/workspace-access/emacs-tramp.md` | Connecting To A Workspace | Connect to a workspace | `#connecting-to-a-workspace` | | `user-guides/workspace-access/emacs-tramp.md` | Using SSH | Use SSH | `#using-ssh` | | `user-guides/workspace-access/index.md` | Running remote commands with quoting | Run remote commands with quoting | `#running-remote-commands-with-quoting` | | `user-guides/workspace-access/jetbrains/gateway.md` | Configuring the Gateway plugin to use internal certificates | Configure the Gateway plugin to use internal certificates | `#configuring-the-gateway-plugin-to-use-internal-certificates` | | `user-guides/workspace-access/jetbrains/gateway.md` | Using an existing JetBrains installation in the workspace | Use an existing JetBrains installation in the workspace | `#using-an-existing-jetbrains-installation-in-the-workspace` | | `user-guides/workspace-access/port-forwarding.md` | Accessing workspace ports | Access workspace ports | `#accessing-workspace-ports` | | `user-guides/workspace-access/port-forwarding.md` | Sharing ports | Share ports | `#sharing-ports` | | `user-guides/workspace-access/port-forwarding.md` | Configuring port protocol | Configure port protocol | `#configuring-port-protocol` | | `user-guides/workspace-access/vscode.md` | Using the public extensions marketplaces | Use the public extensions marketplaces | `#using-the-public-extensions-marketplaces` | | `user-guides/workspace-access/vscode.md` | Adding extensions to custom images | Add extensions to custom images | `#adding-extensions-to-custom-images` | | `user-guides/workspace-access/vscode.md` | Installing extensions using its `vsix` file at the command line | Install extensions using a `vsix` file at the command line | `#installing-extensions-using-its-vsix-file-at-the-command-line` | | `user-guides/workspace-access/vscode.md` | Installing from a marketplace at the command line | Install from a marketplace at the command line | `#installing-from-a-marketplace-at-the-command-line` | | `user-guides/workspace-access/vscode.md` | Using VS Code Desktop | Use VS Code Desktop | `#using-vs-code-desktop` | | `user-guides/workspace-access/web-terminal.md` | Accessing the Terminal | Access the terminal | `#accessing-the-terminal` | | `user-guides/workspace-lifecycle.md` | Stopping workspaces | Stop workspaces | `#stopping-workspaces` | | `user-guides/workspace-lifecycle.md` | Deleting workspaces | Delete workspaces | `#deleting-workspaces` | | `user-guides/workspace-management.md` | Creating workspaces | Create workspaces | `#creating-workspaces` | | `user-guides/workspace-management.md` | Updating workspaces | Update workspaces | `#updating-workspaces` | | `user-guides/workspace-management.md` | Updating via the CLI | Update with the CLI | `#updating-via-the-cli` | | `user-guides/workspace-management.md` | Starting and stopping workspaces | Start and stop workspaces | `#starting-and-stopping-workspaces` | | `user-guides/workspace-management.md` | Repairing workspaces | Repair workspaces | `#repairing-workspaces` | | `user-guides/workspace-scheduling.md` | Working hours | Work schedule | `#working-hours` | | `user-guides/workspace-scheduling.md` | Basing solely on activity detection | Rely solely on activity detection | `#basing-solely-on-activity-detection` | </details> <details> <summary>Plan</summary> The de-gerund work ships as three PRs: 1. This PR: in-page headings and page titles that do not require a page slug rename. 1. Page slug renames for pages whose filenames are gerunds. 1. Redirects for the renamed slugs. Heading rewrites follow the style guide section "No gerund-leading headings": imperative for task headings, noun form for concept headings, sentence case, and "turn on"/"turn off" instead of "enable"/"disable" per word-choice guidance. The legacy anchor sits on its own line above the heading (with a blank line between) rather than inside the heading, so it does not leak into heading text, TOC entries, or Fumadocs slugs. </details> --- _Generated by Coder Agents on behalf of @nickvigilante._