From b6e33831b6e8b872c11868bfd8e72559478cd667 Mon Sep 17 00:00:00 2001 From: MK Date: Mon, 18 May 2026 17:53:04 -0400 Subject: [PATCH] docs: fix 21 broken doc links in README (closes #58) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The top-level README referenced 25 relative .md files. 21 were 404s because the doc tree uses subdirectories with descriptive filenames (docs/core-concepts/runtime-engine.md, docs/security/secret-management.md etc.) while the README linked to canonical flat names that don't exist on disk. Newcomers clicking "Quick Start", "Architecture", "Skills", "Runtime", "Memory", "Channels", etc. all landed on GitHub 404 pages. Mapping applied to README.md (Option A from the issue — pure link rewrite, no new doc files): docs/quickstart.md -> docs/getting-started/quick-start.md docs/installation.md -> docs/getting-started/installation.md docs/architecture.md -> docs/core-concepts/how-forge-works.md docs/skills.md -> docs/skills/writing-custom-skills.md docs/tools.md -> docs/core-concepts/tools-and-builtins.md docs/runtime.md -> docs/core-concepts/runtime-engine.md docs/memory.md -> docs/core-concepts/memory-system.md docs/channels.md -> docs/core-concepts/channels.md docs/scheduling.md -> docs/core-concepts/scheduling.md docs/security/egress.md -> docs/security/egress-control.md docs/security/secrets.md -> docs/security/secret-management.md docs/security/signing.md -> docs/security/build-signing.md docs/commands.md -> docs/reference/cli-reference.md docs/configuration.md -> docs/reference/forge-yaml-schema.md docs/dashboard.md -> docs/reference/web-dashboard.md docs/deployment.md -> docs/deployment/kubernetes.md docs/hooks.md -> docs/core-concepts/hooks.md docs/plugins.md -> docs/reference/framework-plugins.md docs/command-integration.md -> docs/reference/command-integration.md The three ambiguous entries (Skills, Architecture, Deployment) were resolved by matching each row's description-cell text to the closest existing doc — no new index files needed. Add .github/workflows/docs-links.yaml — a tiny Python step that walks every relative .md link in README.md and fails the build if any resolve to a missing file. Path-filtered so it only runs when README or docs/** change, keeping it out of unrelated PRs. Audit results in the fixed README: before: 21 broken, 4 OK after: 0 broken, 25 OK --- .github/workflows/docs-links.yaml | 46 +++++++++++++++++++++++++++++++ README.md | 40 +++++++++++++-------------- 2 files changed, 66 insertions(+), 20 deletions(-) create mode 100644 .github/workflows/docs-links.yaml diff --git a/.github/workflows/docs-links.yaml b/.github/workflows/docs-links.yaml new file mode 100644 index 0000000..e8f8673 --- /dev/null +++ b/.github/workflows/docs-links.yaml @@ -0,0 +1,46 @@ +name: Docs Links + +on: + push: + branches: [main, develop] + paths: + - "README.md" + - "docs/**" + - ".github/workflows/docs-links.yaml" + pull_request: + branches: [main, develop] + paths: + - "README.md" + - "docs/**" + - ".github/workflows/docs-links.yaml" + +permissions: + contents: read + +jobs: + readme-links: + name: README link check + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + + - name: Verify relative .md links in README resolve + run: | + python3 - <<'PY' + import re, os, sys + text = open("README.md").read() + bad = [] + for m in re.finditer(r"\[([^\]]+)\]\(([^)]+\.md)(#[^)]*)?\)", text): + label, target = m.group(1), m.group(2) + if target.startswith("http"): + continue + resolved = os.path.normpath(os.path.join(".", target)) + if not os.path.exists(resolved): + bad.append(f" [{label}]({target})") + if bad: + print("Broken relative .md links in README.md:") + for line in bad: + print(line) + sys.exit(1) + print("README.md: all relative .md links resolve") + PY diff --git a/README.md b/README.md index 62c72e3..35c05ff 100644 --- a/README.md +++ b/README.md @@ -36,7 +36,7 @@ forge init my-agent && cd my-agent && forge run forge run --with slack ``` -See [Quick Start](docs/quickstart.md) for the full walkthrough, or [Installation](docs/installation.md) for all methods. +See [Quick Start](docs/getting-started/quick-start.md) for the full walkthrough, or [Installation](docs/getting-started/installation.md) for all methods. ## How It Works @@ -73,42 +73,42 @@ You write a `SKILL.md`. Forge compiles it into a secure, runnable agent with egr | Document | Description | |----------|-------------| -| [Quick Start](docs/quickstart.md) | Get an agent running in 60 seconds | -| [Installation](docs/installation.md) | Homebrew, binary, and Windows install | -| [Architecture](docs/architecture.md) | System design, module layout, and data flows | +| [Quick Start](docs/getting-started/quick-start.md) | Get an agent running in 60 seconds | +| [Installation](docs/getting-started/installation.md) | Homebrew, binary, and Windows install | +| [Architecture](docs/core-concepts/how-forge-works.md) | System design, module layout, and data flows | ### Core Concepts | Document | Description | |----------|-------------| -| [Skills](docs/skills.md) | Skill definitions, registry, and compilation | -| [Tools](docs/tools.md) | Built-in tools, adapters, and custom tools | -| [Runtime](docs/runtime.md) | LLM providers, fallback chains, running modes | -| [Memory](docs/memory.md) | Session persistence and long-term memory | -| [Channels](docs/channels.md) | Slack and Telegram adapter setup | -| [Scheduling](docs/scheduling.md) | Cron configuration and schedule tools | +| [Skills](docs/skills/writing-custom-skills.md) | Skill definitions, registry, and compilation | +| [Tools](docs/core-concepts/tools-and-builtins.md) | Built-in tools, adapters, and custom tools | +| [Runtime](docs/core-concepts/runtime-engine.md) | LLM providers, fallback chains, running modes | +| [Memory](docs/core-concepts/memory-system.md) | Session persistence and long-term memory | +| [Channels](docs/core-concepts/channels.md) | Slack and Telegram adapter setup | +| [Scheduling](docs/core-concepts/scheduling.md) | Cron configuration and schedule tools | ### Security | Document | Description | |----------|-------------| | [Security Overview](docs/security/overview.md) | Complete security architecture | -| [Egress Security](docs/security/egress.md) | Egress enforcement deep dive | -| [Secrets](docs/security/secrets.md) | Encrypted secret management | -| [Build Signing](docs/security/signing.md) | Ed25519 signing and verification | +| [Egress Security](docs/security/egress-control.md) | Egress enforcement deep dive | +| [Secrets](docs/security/secret-management.md) | Encrypted secret management | +| [Build Signing](docs/security/build-signing.md) | Ed25519 signing and verification | | [Guardrails](docs/security/guardrails.md) | Content filtering and PII detection | ### Operations | Document | Description | |----------|-------------| -| [Commands](docs/commands.md) | Full CLI reference | -| [Configuration](docs/configuration.md) | `forge.yaml` schema and environment variables | -| [Dashboard](docs/dashboard.md) | Web UI features and architecture | -| [Deployment](docs/deployment.md) | Container packaging, Kubernetes, air-gap | -| [Hooks](docs/hooks.md) | Agent loop hook system | -| [Plugins](docs/plugins.md) | Framework plugin system | -| [Command Integration](docs/command-integration.md) | Initializ Command platform guide | +| [Commands](docs/reference/cli-reference.md) | Full CLI reference | +| [Configuration](docs/reference/forge-yaml-schema.md) | `forge.yaml` schema and environment variables | +| [Dashboard](docs/reference/web-dashboard.md) | Web UI features and architecture | +| [Deployment](docs/deployment/kubernetes.md) | Container packaging, Kubernetes, air-gap | +| [Hooks](docs/core-concepts/hooks.md) | Agent loop hook system | +| [Plugins](docs/reference/framework-plugins.md) | Framework plugin system | +| [Command Integration](docs/reference/command-integration.md) | Initializ Command platform guide | ## Philosophy