Conversation
…ch coverage
The search-index coverage item needs all public pages on Google plus a
Bing/DuckDuckGo presence. This packet does the agent-completable half:
- serves the IndexNow key file at /{key}.txt and /.well-known/{key}.txt via
the Worker (run_worker_first so the SPA fallback cannot shadow it),
apex-only, www 301s to apex like every other surface
- shares ROOT_PUBLIC_PATHS between rootSitemap() and the IndexNow payload so
the submission set can never drift from the sitemap
- adds scripts/submit-indexnow.mjs (verify key file live, parse live sitemap,
POST to api.indexnow.org + www.bing.com/indexnow, dry-run mode) with tests
wired into the canonical check gate
- documents live SERP receipts (2026-08-11): Google indexes only the homepage
(Startpage proxy; direct Google CAPTCHA-walled), Bing zero presence, plus
the owner-only Search Console / Bing Webmaster manual kit in
docs/growth/search-index-coverage-2026-08-11.md
There was a problem hiding this comment.
nish3451 has reached the 50-credit limit for trial accounts. To continue receiving code reviews, upgrade your plan.
|
No actionable comments were generated in the recent review. 🎉 ℹ️ Recent review info⚙️ Run configurationConfiguration used: defaults Review profile: CHILL Plan: Pro Plus Run ID: 📒 Files selected for processing (6)
🚧 Files skipped from review as they are similar to previous changes (6)
Included review availability: 1 review is currently available. Your included PR review attempts over the past 7 days set your current allowance at 5 reviews per hour. 📝 WalkthroughWalkthroughThe PR adds shared IndexNow configuration, key-file routes for the Worker and Express server, sitemap submission tooling with dry-run and validation modes, automated tests, package scripts, and operational documentation. ChangesIndexNow infrastructure
Estimated code review effort: 3 (Moderate) | ~20 minutes Merge Risk: ⚪ Minimal · up to The change adds credential-free search-index submission support and verification endpoints without changing public page behavior; no actionable merge-blocking risk remains beyond normal checks and review. Sequence Diagram(s)sequenceDiagram
participant SubmitIndexNow
participant ProductionSitemap
participant KeyFileRoutes
participant IndexNowEndpoints
SubmitIndexNow->>ProductionSitemap: Fetch and parse public URLs
SubmitIndexNow->>KeyFileRoutes: Verify configured key-file paths
KeyFileRoutes-->>SubmitIndexNow: Return matching key content
SubmitIndexNow->>IndexNowEndpoints: Submit URL list payload
IndexNowEndpoints-->>SubmitIndexNow: Return HTTP 200 or 202
Possibly related PRs
🚥 Pre-merge checks | ✅ 4 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (4 passed)
✨ Finishing Touches 💡 1📝 Generate docstrings 💡
🧪 Generate unit tests (beta)
Comment |
There was a problem hiding this comment.
Actionable comments posted: 5
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@docs/growth/search-index-coverage-2026-08-11.md`:
- Around line 5-7: Replace the absolute local workstation path in the document’s
backlog owner reference with a repository-relative backlog path or issue
identifier, while preserving the scout date and ranking metadata.
- Around line 9-19: Revise the status text in the documentation to describe
IndexNow only as requesting URL discovery and confirming notification receipt,
not as guaranteeing Bing or DuckDuckGo crawling, indexing, or search-result
placement. State that Bing and DuckDuckGo independently determine whether to
crawl and index URLs, and remove any claim that DuckDuckGo follows from Bing or
that IndexNow controls first-result presence; apply the same wording correction
to corresponding README content.
In `@README.md`:
- Around line 89-95: Update the README instructions around the IndexNow commands
to clarify that the production key file is required before a real submission,
while --dry-run can preview without it and still completes successfully.
In `@scripts/submit-indexnow.mjs`:
- Around line 55-70: The submitUrlList function currently posts to every
configured endpoint; change it to submit once through a single configured
IndexNow endpoint while preserving the existing outcome shape and error
handling. Update the shared endpoint configuration contract, related tests, and
operational documentation to reflect that only one endpoint is required and
used.
In `@shared/index-now.js`:
- Around line 39-45: Update buildIndexNowPayload so the keyLocation value is
derived from the resolved host rather than the default host. Pass host to
indexNowKeyLocation while preserving the existing default behavior when no
custom host is provided.
🪄 Autofix
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: defaults
Review profile: CHILL
Plan: Pro Plus
Run ID: 7f10c1ae-766b-421c-bc70-347fe17d8aa7
📒 Files selected for processing (11)
README.mddocs/growth/search-index-coverage-2026-08-11.mdpackage.jsonscripts/submit-indexnow.mjsscripts/submit-indexnow.test.mjsserver/index.jsshared/audit-engine.jsshared/index-now.jsworker/index.jsworker/index.test.mjswrangler.jsonc
| (backlog owner: | ||
| `/home/nish/workspaces/agent-state/seo-fix-kit-improvement-loop/backlog.md`, | ||
| [scout 2026-08-09, rank: 2, risk: green]). |
There was a problem hiding this comment.
🔒 Security & Privacy | 🟡 Minor | ⚡ Quick win
Remove the local workstation path.
This public document exposes a developer identifier and local directory layout. Replace it with a repository-relative backlog reference or an issue identifier.
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@docs/growth/search-index-coverage-2026-08-11.md` around lines 5 - 7, Replace
the absolute local workstation path in the document’s backlog owner reference
with a repository-relative backlog path or issue identifier, while preserving
the scout date and ranking metadata.
| Status: **agent-completable half shipped, engine half needs owner credentials + | ||
| time.** This packet (2026-08-11) re-verified the gap live, shipped the | ||
| credential-free IndexNow submission path (key file routes in the Worker, | ||
| submission script, tests, wrangler routing) that gets Bing — and therefore | ||
| DuckDuckGo — crawling all public URLs the moment the release lands, and | ||
| documented the two owner-only legs (Google Search Console request-indexing, | ||
| Bing Webmaster ownership) as an exact manual kit. Search-engine indexing is | ||
| externally owned and time-dependent; the acceptance outcome ("all 7 pages on | ||
| Google, seofixkit.com first on Bing/DDG") cannot be produced from a lane | ||
| without credentials, but every lever that does not need credentials is now | ||
| built and one command away. |
There was a problem hiding this comment.
🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win
🧩 Analysis chain
🌐 Web query:
What do the current official IndexNow documentation and FAQ state about whether a successful IndexNow submission guarantees crawling or indexing, and whether DuckDuckGo is an IndexNow participant?
💡 Result:
The official IndexNow documentation and FAQ explicitly state that a successful submission does not guarantee crawling or indexing [1][2]. When a URL is submitted, search engines receive an HTTP 200 response, which only confirms that the search engine has received the notification [3][4]. After receiving a submission, a search engine evaluates the URL based on its own criteria, including crawl quota, scheduling logic, and content quality signals [1][2]. IndexNow serves to alert search engines that content has changed, which increases the likelihood of faster discovery and prioritization compared to pages not submitted through the protocol, but final decisions on whether to crawl or index remain at the discretion of the search engine's algorithms [1][2]. Regarding DuckDuckGo, the official IndexNow documentation does not list it as a direct participant [5]. However, because DuckDuckGo incorporates results from Bing’s index, it benefits indirectly from IndexNow submissions made to Bing [6][7][8]. Therefore, while DuckDuckGo is not a participant that independently receives and processes IndexNow pings, updates submitted to IndexNow-participating engines like Bing can still be reflected in DuckDuckGo search results [9][7].
Citations:
- 1: https://www.indexnow.org/faq
- 2: https://www.indexnow.org/en_gb/faq
- 3: https://www.indexnow.org/documentation.html
- 4: https://stackoverflow.com/questions/79369544/indexnow-submissions-and-how-they-are-reflected-in-bing-webmaster-tools
- 5: https://www.indexnow.org/searchengines
- 6: https://www.seohack.info/indexnow-seo/
- 7: https://blog.victorijomah.com/how-to-use-indexnow-to-notify-search-engines-about-new-urls/
- 8: https://llmbestpractices.com/seo/indexnow
- 9: https://www.searchenginejournal.com/indexnow-what-we-know/439679/
🏁 Script executed:
#!/bin/bash
set -eu
printf '%s\n' '--- target document ---'
sed -n '1,150p' docs/growth/search-index-coverage-2026-08-11.md
printf '%s\n' '--- related README wording ---'
rg -n -i -C 3 'IndexNow|DuckDuckGo|Bing.*crawl|crawl.*Bing|all 7 pages|seofixkit' --glob 'README*' --glob '*.md' .Repository: nish3451/seo-fix-kit
Length of output: 50377
Qualify IndexNow and DuckDuckGo outcomes
IndexNow acceptance confirms receipt of a notification. It requests discovery but does not guarantee crawling or indexing. Remove claims that IndexNow gets Bing or DuckDuckGo crawling, that DuckDuckGo follows from Bing, or that IndexNow owns first-result presence. State that Bing and DuckDuckGo independently decide whether to crawl and index URLs. Apply the same correction to any README copy.
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@docs/growth/search-index-coverage-2026-08-11.md` around lines 9 - 19, Revise
the status text in the documentation to describe IndexNow only as requesting URL
discovery and confirming notification receipt, not as guaranteeing Bing or
DuckDuckGo crawling, indexing, or search-result placement. State that Bing and
DuckDuckGo independently determine whether to crawl and index URLs, and remove
any claim that DuckDuckGo follows from Bing or that IndexNow controls
first-result presence; apply the same wording correction to corresponding README
content.
| To preview (no network writes) or run the credential-free IndexNow submission | ||
| that tells Bing — and Bing-derived DuckDuckGo — to crawl every public URL | ||
| (the key file must be live on production first; the script refuses otherwise): | ||
|
|
||
| ```bash | ||
| npm run submit:indexnow -- --dry-run # preview URL set + endpoints | ||
| npm run submit:indexnow # verify key file, then submit to Bing/IndexNow |
There was a problem hiding this comment.
🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win
State the dry-run prerequisite accurately.
main() returns code 2 for a missing key file only when dryRun is false. With --dry-run, it logs failed key checks, fetches the sitemap, and returns code 0. State that the key file must be live before a real submission, not before a preview.
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@README.md` around lines 89 - 95, Update the README instructions around the
IndexNow commands to clarify that the production key file is required before a
real submission, while --dry-run can preview without it and still completes
successfully.
| export async function submitUrlList(urlList, { endpoints = INDEX_NOW_ENDPOINTS, fetchImpl = globalThis.fetch } = {}) { | ||
| const payload = buildIndexNowPayload(urlList); | ||
| const outcomes = []; | ||
| for (const endpoint of endpoints) { | ||
| try { | ||
| const res = await fetchImpl(endpoint, { | ||
| method: "POST", | ||
| headers: { "content-type": "application/json; charset=utf-8" }, | ||
| body: JSON.stringify(payload) | ||
| }); | ||
| outcomes.push({ endpoint, status: res.status, ok: res.status === 200 || res.status === 202 }); | ||
| } catch (err) { | ||
| outcomes.push({ endpoint, status: 0, ok: false, error: err.message }); | ||
| } | ||
| } | ||
| return outcomes; |
There was a problem hiding this comment.
🎯 Functional Correctness | 🟠 Major | ⚡ Quick win
🧩 Analysis chain
🌐 Web query:
According to the current official IndexNow FAQ, can a website submit the same URL-list payload to both the global IndexNow endpoint and the Bing endpoint, or should it submit to only one endpoint?
💡 Result:
According to the official IndexNow FAQ, you should submit your URL-list payload to only one of the participating IndexNow endpoints [1][2]. The protocol is designed such that all search engines adopting IndexNow have agreed that URLs submitted to any one participating endpoint will be automatically shared with all other participating search engines [3][4][5]. Therefore, submitting the same list to multiple endpoints is unnecessary [6]. The FAQ explicitly states: "You may submit your request to only one of the following participating endpoints. Each endpoint sends your submission directly to its respective search engine, and your submission will be shared across all IndexNow-enabled search engines" [1][2]. Using the global IndexNow endpoint (api.indexnow.org) is a common and efficient way to reach all participating engines with a single request [7][8][9].
Citations:
- 1: https://www.indexnow.org/faq?referrer=wordpress.com
- 2: https://www.indexnow.org/faq
- 3: https://www.indexnow.org/documentation.html
- 4: https://blogs.bing.com/webmaster/january-2022/IndexNow-Announcing-Sharing-of-Submitted-URLs
- 5: https://www.indexnow.org/en_gb/documentation
- 6: https://jakob-bagterp.github.io/index-now-for-python/user-guide/search-engines/default-endpoints/
- 7: https://indxel.com/blog/indexnow-api-guide
- 8: https://patrickstox.com/technical-seo/how-search-works/discovery/indexnow/
- 9: https://www.seohack.info/indexnow-api-scripts/
🏁 Script executed:
#!/bin/bash
set -eu
printf '%s\n' '--- target file ---'
cat -n scripts/submit-indexnow.mjs | sed -n '1,140p'
printf '%s\n' '--- related references ---'
rg -n -S --glob '!node_modules' 'INDEX_NOW_ENDPOINTS|submitUrlList|IndexNow|api\.indexnow\.org|www\.bing\.com/indexnow|status.*3' .Repository: nish3451/seo-fix-kit
Length of output: 18101
🏁 Script executed:
#!/bin/bash
set -eu
printf '%s\n' '--- shared IndexNow contract ---'
cat -n shared/index-now.js | sed -n '1,100p'
printf '%s\n' '--- submit-indexnow tests ---'
cat -n scripts/submit-indexnow.test.mjs | sed -n '1,130p'
printf '%s\n' '--- operational documentation ---'
cat -n README.md | sed -n '80,105p'
cat -n docs/growth/search-index-coverage-2026-08-11.md | sed -n '48,70p;95,125p'Repository: nish3451/seo-fix-kit
Length of output: 13128
🏁 Script executed:
#!/bin/bash
set -eu
python3 - <<'PY'
from pathlib import Path
import re
source = Path("scripts/submit-indexnow.mjs").read_text()
shared = Path("shared/index-now.js").read_text()
endpoints = re.findall(r'"(https://[^"]+/indexnow)"', shared)
loop = re.search(r'for \(const endpoint of endpoints\)', source)
accepted = re.search(r'res\.status === 200 \|\| res\.status === 202', source)
exit_logic = re.search(r'code: allOk \? 0 : 3', source)
print("configured_endpoints:", endpoints)
print("default_endpoint_count:", len(endpoints))
print("submitUrlList_iterates_each_endpoint:", bool(loop))
print("200_or_202_are_accepted:", bool(accepted))
print("main_returns_3_when_not_all_outcomes_are_ok:", bool(exit_logic))
# Model the source-level aggregation for one accepted response and one rejection.
statuses = [200, 403]
outcomes = [{"status": s, "ok": s in (200, 202)} for s in statuses]
all_ok = all(item["ok"] for item in outcomes)
print("mixed_statuses:", statuses)
print("mixed_outcomes:", outcomes)
print("modeled_exit_code:", 0 if all_ok else 3)
PYRepository: nish3451/seo-fix-kit
Length of output: 524
Submit through one IndexNow endpoint.
IndexNow shares submissions across participating search engines. Configure one endpoint and do not require every endpoint to accept the payload. Update the shared contract, tests, and operational documentation.
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@scripts/submit-indexnow.mjs` around lines 55 - 70, The submitUrlList function
currently posts to every configured endpoint; change it to submit once through a
single configured IndexNow endpoint while preserving the existing outcome shape
and error handling. Update the shared endpoint configuration contract, related
tests, and operational documentation to reflect that only one endpoint is
required and used.
| export function buildIndexNowPayload(urls, { host = INDEX_NOW_HOST } = {}) { | ||
| return { | ||
| host, | ||
| key: INDEX_NOW_KEY, | ||
| keyLocation: indexNowKeyLocation(), | ||
| urlList: [...urls] | ||
| }; |
There was a problem hiding this comment.
🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win
🧩 Analysis chain
🌐 Web query:
Does the IndexNow JSON submission protocol require keyLocationto identify a key file hosted on the same host as the payloadhost field?
💡 Result:
Yes, the IndexNow protocol requires the keyLocation to point to a file hosted on the same host as the one specified in the host field [1][2][3]. The fundamental purpose of the key file is to prove ownership of the domain for which URLs are being submitted [1][4]. Because the protocol requires you to verify your identity as the owner of the host being indexed, the key file must be hosted within that specific host [1][5]. Documentation explicitly states that you must "prove" ownership by hosting the text file within the host, and if you choose to host it in a location other than the root directory, it must still be "within the same host" [1][6]. Furthermore, the location of the key file acts as a scoping mechanism: if the key is not placed in the root directory, its directory path can restrict which URLs are considered valid for that submission [1][4]. For instance, a key file located in a subdirectory (e.g., example.com/catalog/key.txt) typically only validates URLs located within that specific path and its subdirectories [1][4]. Consequently, the key file must reside on the target host to be verifiable and functionally effective for the scope of the URLs submitted [1][5].
Citations:
- 1: https://www.indexnow.org/documentation
- 2: https://www.bing.com/indexnow/getstarted
- 3: https://www.indexnow.org/faq?referrer=wordpress.com
- 4: https://yandex.com/support/webmaster/en/indexnow/key
- 5: https://www.indexnow.org/documentation?hl=en
- 6: https://www.indexnow.org/documentation.html
🏁 Script executed:
#!/bin/bash
set -eu
printf '%s\n' '--- candidate files ---'
fd -t f -a | rg '(^|/)(shared/index-now\.js|package\.json|README|.*index.?now.*)$' || true
printf '%s\n' '--- shared/index-now.js ---'
cat -n shared/index-now.js
printf '%s\n' '--- index-now symbols and call sites ---'
rg -n -C 3 'buildIndexNowPayload|indexNowKeyLocation|INDEX_NOW_HOST|keyLocation' . \
-g '!node_modules' -g '!dist' -g '!build' || trueRepository: nish3451/seo-fix-kit
Length of output: 9705
🏁 Script executed:
#!/bin/bash
set -eu
printf '%s\n' '--- submitUrlList and related configuration ---'
cat -n scripts/submit-indexnow.mjs | sed -n '1,75p'
printf '%s\n' '--- payload tests ---'
cat -n scripts/submit-indexnow.test.mjs | sed -n '20,50p'
printf '%s\n' '--- static behavioral probe for the custom-host case ---'
python3 - <<'PY'
from pathlib import Path
import re
source = Path("shared/index-now.js").read_text()
host_match = re.search(
r"export function buildIndexNowPayload\(urls, \{ host = INDEX_NOW_HOST \} = \{\}\) \{"
r"(?P<body>.*?)\n\}",
source,
re.S,
)
assert host_match, "buildIndexNowPayload declaration not found"
body = host_match.group("body")
assert "host," in body
assert "keyLocation: indexNowKeyLocation()," in body
constant_match = re.search(
r"export const INDEX_NOW_HOST = [\"']([^\"']+)[\"'];", source
)
assert constant_match, "INDEX_NOW_HOST not found"
default_host = constant_match.group(1)
location_match = re.search(
r"export function indexNowKeyLocation\(\) \{\s*"
r"return `https://\$\{INDEX_NOW_HOST\}/\$\{INDEX_NOW_KEY\}\.txt`;",
source,
)
assert location_match, "indexNowKeyLocation implementation changed"
custom_host = "example.test"
payload_host = custom_host
payload_key_location = f"https://{default_host}/<key>.txt"
print({
"payload.host": payload_host,
"payload.keyLocation": payload_key_location,
"same_host": payload_host == default_host,
})
assert payload_host != default_host
assert payload_host not in payload_key_location
PYRepository: nish3451/seo-fix-kit
Length of output: 5462
Keep keyLocation consistent with host.
If a caller passes a custom host, keyLocation still points to seofixkit.com. IndexNow requires the key file to use the target host. Pass host to indexNowKeyLocation, or remove the host override.
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@shared/index-now.js` around lines 39 - 45, Update buildIndexNowPayload so the
keyLocation value is derived from the resolved host rather than the default
host. Pass host to indexNowKeyLocation while preserving the existing default
behavior when no custom host is provided.
There was a problem hiding this comment.
nish3451 has reached the 50-credit limit for trial accounts. To continue receiving code reviews, upgrade your plan.
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 0c9d5676f5
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
| submission script, tests, wrangler routing) that gets Bing — and therefore | ||
| DuckDuckGo — crawling all public URLs the moment the release lands, and |
There was a problem hiding this comment.
Require submission before claiming crawling starts
When the release is deployed but npm run submit:indexnow has not yet been run, it only exposes the verification key; no request is sent to either IndexNow endpoint because the POST occurs exclusively inside the manually invoked script. Saying crawling begins “the moment the release lands” can therefore cause the operator to skip the required resume command and leave the coverage task stalled indefinitely. Describe the release as enabling submission and make running the command a prerequisite for any crawl notification claim.
AGENTS.md reference: AGENTS.md:L7-L7
Useful? React with 👍 / 👎.
- shared/audit-engine.js: hoist ROOT_PUBLIC_PATHS to main's canonical route set (adds /small-business-seo-audit, /rendered-vs-static-seo-audit, /ai-answer-readiness, /proof) so sitemap and IndexNow submission sets match the merged public pages - wrangler.jsonc: take main's run_worker_first:true + 404-page (supersedes the PR's run_worker_first array; Worker still serves the IndexNow key file for all requests) - package.json: merge both script sets and combined check chain - README.md: keep both IndexNow and funnel-walk docs blocks
|
You have reached your Codex usage limits for code reviews. You can see your limits in the Codex usage dashboard. |
There was a problem hiding this comment.
Your trial has ended. Reactivate Greptile to resume code reviews.
|
Duplicate/superseded — closing in favour of #157. Earliest, smallest version of the same IndexNow path. (nothing-sits sweep 2026-08-19) |
What and why
Backlog item (lane-1 scout, rank 2): Establish full search-index coverage: all 7 public pages indexed on Google plus a Bing/DuckDuckGo presence.
Fresh live receipts (2026-08-11):
site:seofixkit.comvia Startpage (Google-index proxy; direct Google is CAPTCHA-walled from this VPS) returns exactly one result — the homepage. Per-pathsite:seofixkit.com/{terms,demo,methodology,packages,check,privacy,support}all return zero. 7 of 8 public routes are unindexed.bing.com/search?q=seofixkit.comreturns ~82k results, none of them seofixkit.com. Zero presence.What this PR ships (the agent-completable half)
/{key}.txtand/.well-known/{key}.txt(both added torun_worker_firstso the SPA asset fallback can't shadow them), apex-only, www keeps 301ing to apex. IndexNow needs no credentials — this is the Bing/DDG crawl trigger.shared/index-now.js: committed key, key paths, payload builder, endpoints (api.indexnow.org,www.bing.com/indexnow).shared/audit-engine.js: hoisted the canonical route list toROOT_PUBLIC_PATHS, shared byrootSitemap()and IndexNow so the submission set can never drift from the sitemap.scripts/submit-indexnow.mjs+ tests: verifies the key file is live at both locations (refuses otherwise), parses the live sitemap, POSTs to both endpoints, per-endpoint accept/reject reporting;--dry-runpreview with no network writes. Wired intonpm run check.server/index.jsdev-server parity;worker/index.test.mjsroute tests (apex 200 + exact key body + noindex, www 301).docs/growth/search-index-coverage-2026-08-11.md: full packet — receipts, resume path, and the owner-only manual kit (Google Search Console request-indexing, Bing Webmaster DNS TXT) with expected outcomes.What remains (credentials + time, not code)
npm run submit:indexnow. Crawler schedule is external.Validation
npm run test:worker-dispatch11/11 (incl. new key-file route test)npm run test:indexnow8/8node --test worker/routes/pages.test.mjs src/app-contract.test.mjs21/21npm run buildgreennpm run submit:indexnow -- --dry-runagainst live site: correctly reports key file not live yet + parses the full 8-URL sitemap setNo public page copy, routes, or product behavior changed — only the new key-file surfaces and submission tooling.
Summary by CodeRabbit
New Features
Documentation
Tests