-
Notifications
You must be signed in to change notification settings - Fork 21
chore: CodeRabbit config for the docs site #60
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Changes from all commits
395ca07
e9471e2
c2d47a9
7d88438
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,221 @@ | ||
| # CodeRabbit configuration for career-ops-docs (career-ops-hq). | ||
| # The documentation site for career-ops: Next.js + Fumadocs, 95 MDX pages in | ||
| # EN/ES/FR, deployed to career-ops.org. Modeled on the core repo's config | ||
| # (career-ops-hq/career-ops#3769, then #3772 for the incremental-review, | ||
| # recipe and post-merge-report levers), adapted to what this repo actually is. | ||
| # Docs: https://docs.coderabbit.ai/reference/configuration | ||
| language: en-US | ||
| tone_instructions: "Be specific and brief. Cite file:line. Use colons, not dashes. Warm to first-time contributors. One precise finding beats three vague ones. A sentence that says something the tool no longer does is a bug; one that merely reads differently is not." | ||
|
|
||
| reviews: | ||
| profile: assertive | ||
| request_changes_workflow: false # humans decide; the review is a signal | ||
| high_level_summary: true | ||
| high_level_summary_instructions: "Explain what changes for a reader of career-ops.org: which page, which guide, which language. Name if the PR touches the agent-facing layer (llms.txt, AGENTS.md, the .md mirrors), routing (next.config.mjs, src/proxy.ts), the schema (src/lib/schema.ts), or anything visual under src/app/(home)." | ||
| poem: false | ||
| collapse_walkthrough: true | ||
| sequence_diagrams: false | ||
| estimate_code_review_effort: true | ||
| assess_linked_issues: true | ||
| related_issues: true | ||
| related_prs: true | ||
| suggested_labels: true | ||
| auto_apply_labels: false # a maintainer applies labels | ||
| suggested_reviewers: false # CODEOWNERS requires @santifer on every path already | ||
| auto_assign_reviewers: false | ||
| abort_on_close: true | ||
|
|
||
| # Low-effort and machine-generated PRs are a real cost on a repo where every | ||
| # merge needs @santifer's own review time. The label is a routing signal for | ||
| # a human to check first: nothing is ever closed on it, and no automation | ||
| # acts on it. (career-ops-hq/career-ops#3772, adapted.) | ||
| slop_detection: | ||
| enabled: true | ||
| label: "quality-check" | ||
|
|
||
| auto_review: | ||
| enabled: true | ||
| drafts: false | ||
| auto_incremental_review: true | ||
| # Default is to pause after 5 reviewed commits in one PR; a contributor | ||
| # who pushes a sixth fix deserves the sixth review too. If this ever hits | ||
| # the hourly review ceiling (shared with the core repo, 10/hour), the | ||
| # ceiling is the thing to raise, not the contributor to ration. | ||
| auto_pause_after_reviewed_commits: 0 | ||
| base_branches: | ||
| - main | ||
| ignore_usernames: | ||
| - renovate[bot] | ||
| - dependabot[bot] | ||
| - github-actions[bot] | ||
| - vercel[bot] | ||
|
|
||
| path_filters: | ||
| - "!package-lock.json" | ||
| - "!**/*.pdf" | ||
| - "!**/*.png" | ||
| - "!**/*.jpg" | ||
| - "!**/*.avif" | ||
| - "!public/**/*.svg" | ||
| - "!.playwright-mcp/**" | ||
|
|
||
| path_instructions: | ||
| - path: "src/app/api/**" | ||
| instructions: "Server routes, including the AI chat. Any change here is security-sensitive: flag new endpoints, changes to what is fetched or where it is sent, and any secret or key. Contributors are not expected to touch this directory at all; say so if a PR does." | ||
| - path: "next.config.mjs" | ||
| instructions: "Routing and headers. The .md twins of every /docs page, the Accept: text/markdown negotiation for locale paths, the noindex on generated images and the security headers all live here as rewrites and header rules. Flag any change to the beforeFiles rewrites or to a header rule, and note that the proxy does NOT run for locale-prefixed paths, so locale negotiation must stay in this file." | ||
| - path: "src/proxy.ts" | ||
| instructions: "Handles Accept: text/markdown for /docs only. It does not run for the homepage or for /es and /fr paths, on purpose. Flag any attempt to extend its matcher to cover those, and any .md interception moved here from next.config.mjs (it 404s under Next 16)." | ||
| - path: "scripts/verify-agent-layer.mjs" | ||
| instructions: "The agent-layer guard. Its checks are three-state on purpose: pass, fail, and could-not-check must all be distinguishable, and could-not-check fails. Flag any change that lets a check pass when it did not run, or that removes an invariant without explanation." | ||
| - path: ".github/workflows/**" | ||
| instructions: "Treat as security-sensitive. Flag pull_request_target with a checkout of the fork, secrets exposed to fork code, unpinned third-party actions, and permissions broader than needed. The agent-layer guard boots the built site and is the merge gate; flag anything that makes it advisory." | ||
| - path: "src/lib/shared.ts" | ||
| instructions: "Frozen canonical strings: the thesis line, the CareerOps definition in EN and ES, the manifesto signature, the stats floors and the release fallback. The thesis and the definition are byte-identical across the site and the core repo by design. Flag ANY edit to their text, however small, and any floor lowered below its current value." | ||
| - path: "src/lib/manifesto-text.ts" | ||
| instructions: "The signed manifesto, frozen. The English body is verified byte-for-byte against the core repo's MANIFESTO.md by the guard; the Spanish body is the canonical Spanish text (the core has no Spanish original). Flag any edit to either body as a change to a signed document." | ||
| - path: "src/lib/schema.ts" | ||
| instructions: "The Schema.org entity graph. Organization and Person are two entities: Organization.sameAs must carry the project's accounts (x.com/careeropshq, the npm scope @santifer/career-ops, the org repo), Person.sameAs the founder's. Flag any sameAs that points at a URL that does not resolve, any Person account placed under Organization or vice versa, and any dateModified that is not conditioned on a live fetch." | ||
| - path: "src/lib/llms-index.ts" | ||
| instructions: "Builds /llms.txt, the index AI assistants ingest. Every figure that moves (stars, members, release) must carry an as-of date and must be omitted, never faked, when its live fetch failed. Flag any hand-typed number, any figure without a date, and any relative link (all links must be absolute .md mirrors)." | ||
| - path: "src/app/AGENTS.md/**" | ||
| instructions: "A thin pointer to the core repo's AGENTS.md. It is never a copy. Flag any content that duplicates instructions from the core instead of linking to them." | ||
| - path: "src/app/(home)/**" | ||
| instructions: "The homepage, including the hero. Visual changes are the maintainer's decision and are not accepted from pull requests without prior discussion. Flag any change to layout, colors, backdrop, scrim or typography and say explicitly that it needs the maintainer's sign-off before review continues." | ||
| - path: "content/**/*.mdx" | ||
| instructions: "The guides. They describe what career-ops-hq/career-ops ships on main today, never what an open PR there proposes. Check commands, flags, script names and the A to H block letters against the core; flag drift. The scoring scale is named '1-5' (decimal thresholds like 4.0 are values and stay). The brand is 'career-ops' lowercase with a hyphen; 'CareerOps' names the practice. Flag hand-typed project numbers (stars, members): they belong to live fetches, not prose." | ||
| - path: "content/**/*.{es,fr}.mdx" | ||
| instructions: "Translations. Each carries translationHash of its English source. If the English sibling changes in the same PR, the hash must be restamped (node .i18n/hash.mjs <english-file>) or the PR must say the translation is now stale. Flag a changed English page whose es/fr siblings were neither updated nor declared stale. Non-translatables (command names, flags, file paths, the thesis line) must match the English exactly." | ||
| - path: "CONTRIBUTING.md" | ||
| instructions: "Public contributor rules. Flag anything that contradicts .github/copilot-instructions.md or the CODEOWNERS comment." | ||
|
|
||
| tools: | ||
| gitleaks: { enabled: true } | ||
| trufflehog: { enabled: true } | ||
| presidio: { enabled: true } # no real personal data in examples | ||
| actionlint: { enabled: true } | ||
| zizmor: { enabled: true } | ||
| shellcheck: { enabled: true } # templates/og-compare-generator.sh | ||
| yamllint: { enabled: true } | ||
| osvScanner: { enabled: true } | ||
| semgrep: { enabled: true } | ||
| github-checks: { enabled: true, timeout_ms: 900000 } | ||
| eslint: { enabled: false } # this repo has no ESLint config or dependency; enabling it is noise | ||
| golangci-lint: { enabled: false } # no Go here | ||
| markdownlint: { enabled: false } # 95 MDX pages: style noise, not review | ||
| languagetool: { enabled: false } | ||
| vale: { enabled: false } | ||
| ast-grep: { enabled: false } | ||
|
|
||
| finishing_touches: | ||
| docstrings: { enabled: false } | ||
| # No test framework or test directory exists in this repo (it is a | ||
| # Next.js/Fumadocs site, not the core's Node scripts). Configuring | ||
| # generation conventions here would invent a testing setup that does not | ||
| # exist; skip until one does. | ||
| unit_tests: { enabled: false } | ||
| simplify: { enabled: false } | ||
| autofix: { enabled: false } # no bot pushes to a contributor's branch | ||
| fix_ci: { enabled: false } | ||
| resolve_merge_conflict: { enabled: false } | ||
| # Recipes run only when asked: @coderabbitai run <name>. Each one encodes | ||
| # a mechanical task that has actually bitten this repo. | ||
| # (career-ops-hq/career-ops#3772 introduced the pattern; these two are | ||
| # specific to career-ops-docs, not copied from the core's recipes.) | ||
| custom: | ||
| - name: register-sitemap-entry | ||
| enabled: true | ||
| instructions: "If this PR adds a new top-level static page (a new route directory under src/app/ with its own page.tsx, other than a page inside (home), docs, es, fr, compare/[slug], or an API route), add it to the entries array in src/app/sitemap.ts, following the existing pattern: url built from SITE_URL, and lastModified from gd('<path to the new page.tsx>') so it degrades to omitted rather than a fabricated date when git has no history for the file. A page invisible to the sitemap is invisible to crawlers even though it renders fine; that already happened once, to /sustain. Do not touch .github/workflows/indexnow.yml: it now derives its URL list from the live sitemap.xml at run time, so nothing there needs registering by hand. Change nothing else." | ||
| - name: sync-translation | ||
| enabled: true | ||
| instructions: "For every content/docs/**/*.mdx page this PR changed in English, bring its .es.mdx and .fr.mdx siblings up to date: same heading structure, same order, same code fences and command output, translated prose. Never touch command names, CLI flags, file paths, or the manifesto/thesis strings imported from src/lib/shared.ts and src/lib/manifesto-text.ts — those are frozen and must read identically to the English source. Do NOT set or guess a translationHash value in the frontmatter: that field is a literal hash of the English body, computed only by running `node .i18n/hash.mjs <path to the English file>`, and writing a plausible-looking value there would make a stale translation look verified. Leave the existing translationHash untouched and note in your summary that it still needs restamping with that command. content/blog/**/*.mdx has no translated siblings; do not create any there. Change nothing else." | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🗄️ Data Integrity & Integration | 🟡 Minor | ⚡ Quick win Handle missing locale siblings consistently. The translation recipe and drift report both assume that every English documentation page has
📍 Affects 1 file
🤖 Prompt for AI Agents |
||
|
|
||
| pre_merge_checks: | ||
| # Frozen strings, hand-typed numbers and personal data carry policy, not | ||
| # taste: the PR's own author should not be the one who waves them through | ||
| # on their own PR. In practice @santifer is both the sole code owner and | ||
| # the author of nearly every PR here, so this mostly blocks self-override | ||
| # until a second collaborator exists to request as a reviewer — same | ||
| # shape as CODEOWNERS itself. (career-ops-hq/career-ops#3772, adapted.) | ||
| override_requested_reviewers_only: true | ||
| docstrings: { mode: off } | ||
| title: | ||
| mode: warning | ||
| requirements: "Conventional Commits prefix (feat, fix, docs, chore, i18n, revert) followed by a scope in parentheses when the change is confined to one area, then a factual summary." | ||
| description: | ||
| mode: warning | ||
| issue_assessment: | ||
| mode: warning | ||
| custom_checks: | ||
| - name: "Frozen strings untouched" | ||
| mode: error | ||
| instructions: "Fail if the PR changes the text of MANIFESTO, CAREEROPS_DEFINITION, CAREEROPS_DEFINITION_ES or MANIFESTO_SIGNATURE in src/lib/shared.ts, or either body in src/lib/manifesto-text.ts. These are signed or canonical strings; a change is a decision the maintainer makes, not a review comment." | ||
| - name: "No hand-typed project numbers" | ||
| mode: error | ||
| instructions: "Fail if the diff adds a star count, member count, contributor count or download count typed into prose or markdown. Those figures come from live fetches with an as-of date. A historical, dated fact (for example the founder's 740 listings evaluated) is fine." | ||
| - name: "Translations restamped or declared stale" | ||
| mode: warning | ||
| instructions: "Warn if an English content/**/*.mdx page changes and a sibling .es.mdx or .fr.mdx exists that was neither modified in this PR nor mentioned in the description as stale." | ||
| - name: "No personal data" | ||
| mode: error | ||
| instructions: "Fail if the diff contains real personal data: a person's real name paired with contact details, real emails, phone numbers, or a real CV. Sample data must use obvious placeholders." | ||
| - name: "Visual change needs the maintainer" | ||
| mode: warning | ||
| instructions: "Warn if the PR changes layout, colors, backdrop, scrim or typography under src/app/(home) or in global.css, unless the description says the maintainer asked for it." | ||
| - name: "Agent-operated PR disclosure" | ||
| mode: warning | ||
| instructions: "If the PR author is a coding agent (branch copilot/* or author app/copilot-swe-agent), warn unless the description contains the sections '## AI assistance' and '## Human review'." | ||
|
|
||
| # Runs after the merge, as a text-only comment on the merged PR. It exists | ||
| # as a backstop for the "Translations restamped or declared stale" check | ||
| # above: that check is a warning, not a gate, so a PR can merge with it | ||
| # unresolved. This leaves a paper trail after the fact so a stale | ||
| # translation is not simply forgotten once the PR closes. | ||
| # (career-ops-hq/career-ops#3772 introduced the pattern; this is the docs | ||
| # repo's one direct analog — a downstream "documentation drift" report | ||
| # does not apply here, since this repo IS the documentation.) | ||
| post_merge_actions: | ||
| - name: "translation drift report" | ||
| enabled: true | ||
| prompt: "Only act if this merge changed an English page under content/docs/**/*.mdx (not a .es.mdx or .fr.mdx file itself, and not anything under content/blog/, which has no translated siblings). For each changed English page, check whether its .es.mdx and .fr.mdx siblings were modified in the same merge or declared stale in the PR description. List every one that was neither: name the file, the heading or section that now diverges from the English source, and a one-sentence description of what changed. If every English change in this merge had its translations updated or declared stale, reply with exactly: no translation drift. Post a text report in the result comment only. Do not open a pull request, do not create or edit issues, do not push commits, do not comment anywhere else." | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🗄️ Data Integrity & Integration | 🟠 Major | ⚡ Quick win Check The report treats a translation as current when its sibling was modified or declared stale. The recipe at Line 131 explicitly leaves Compare each existing sibling's stored hash with 🤖 Prompt for AI Agents |
||
|
|
||
| labeling_instructions: | ||
| - label: "documentation" | ||
| instructions: "Apply when the PR changes anything under content/ or a page's prose." | ||
| - label: "enhancement" | ||
| instructions: "Apply when the PR adds a page, a section, a route or a capability to the site." | ||
| - label: "bug" | ||
| instructions: "Apply when the PR fixes something that was wrong: a broken link, a guide that described behavior the tool no longer has, a 404, a wrong figure." | ||
|
|
||
| chat: | ||
| auto_reply: true | ||
| allow_non_org_members: true | ||
| art: false | ||
|
|
||
| knowledge_base: | ||
| opt_out: false | ||
| web_search: { enabled: true } | ||
| # A week for a maintainer to reject a learning before it sticks. Matters | ||
| # more here than the default of 0 (immediate) because this config links | ||
| # career-ops-hq/career-ops below: a fact CodeRabbit learns from the core's | ||
| # context can get applied to this repo, or vice versa, and the wrong | ||
| # attribution is exactly the failure this window exists to catch. | ||
| learnings: { scope: auto, approval_delay: 7 } | ||
| issues: { scope: auto } | ||
| pull_requests: { scope: auto } | ||
| code_guidelines: | ||
| enabled: true | ||
| filePatterns: | ||
| - "CONTRIBUTING.md" | ||
| - ".github/copilot-instructions.md" | ||
| linked_repositories: | ||
| - repository: career-ops-hq/career-ops | ||
| instructions: "The tool this site documents. When reviewing a guide, check commands, flags, script names and block letters against what main ships there. A guide is wrong if it describes a flag or behavior that repo does not have." | ||
|
|
||
| issue_enrichment: | ||
| auto_enrich: { enabled: false } | ||
| planning: | ||
| enabled: true | ||
| auto_planning: { enabled: false } | ||
| labeling: | ||
| auto_apply_labels: false | ||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win
Register localized routes that the sitemap does not auto-discover.
The recipe excludes every page inside
esandfr.src/app/sitemap.tsonly auto-discovers localized documentation twins and explicitly lists the current localized pages. A new route such assrc/app/es/about/page.tsxwould therefore receive no sitemap entry.Remove the blanket exclusions, or exclude only the locale routes already covered by
src/app/sitemap.ts.🤖 Prompt for AI Agents