docs: remove dead security README nav entry (#46675)

Merged via squash.

Prepared head SHA: 63331a54b8
Co-authored-by: velvet-shark <126378+velvet-shark@users.noreply.github.com>
Co-authored-by: velvet-shark <126378+velvet-shark@users.noreply.github.com>
Reviewed-by: @velvet-shark
This commit is contained in:
Radek Sienkiewicz 2026-03-15 01:40:00 +01:00 committed by GitHub
parent 774b40467b
commit 4c6a7f84a4
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
3 changed files with 51 additions and 19 deletions

View File

@ -1242,7 +1242,6 @@
"group": "Security",
"pages": [
"security/formal-verification",
"security/README",
"security/THREAT-MODEL-ATLAS",
"security/CONTRIBUTING-THREAT-MODEL"
]
@ -1598,7 +1597,6 @@
"zh-CN/tools/apply-patch",
"zh-CN/brave-search",
"zh-CN/perplexity",
"zh-CN/tools/diffs",
"zh-CN/tools/elevated",
"zh-CN/tools/exec",
"zh-CN/tools/exec-approvals",

View File

@ -1,17 +0,0 @@
# OpenClaw Security & Trust
**Live:** [trust.openclaw.ai](https://trust.openclaw.ai)
## Documents
- [Threat Model](/security/THREAT-MODEL-ATLAS) - MITRE ATLAS-based threat model for the OpenClaw ecosystem
- [Contributing to the Threat Model](/security/CONTRIBUTING-THREAT-MODEL) - How to add threats, mitigations, and attack chains
## Reporting Vulnerabilities
See the [Trust page](https://trust.openclaw.ai) for full reporting instructions covering all repos.
## Contact
- **Jamieson O'Reilly** ([@theonejvo](https://twitter.com/theonejvo)) - Security & Trust
- Discord: #security channel

View File

@ -113,6 +113,41 @@ function resolveRoute(route) {
return { ok: routes.has(current), terminal: current };
}
/** @param {unknown} node */
function collectNavPageEntries(node) {
/** @type {string[]} */
const entries = [];
if (Array.isArray(node)) {
for (const item of node) {
entries.push(...collectNavPageEntries(item));
}
return entries;
}
if (!node || typeof node !== "object") {
return entries;
}
const record = /** @type {Record<string, unknown>} */ (node);
if (Array.isArray(record.pages)) {
for (const page of record.pages) {
if (typeof page === "string") {
entries.push(page);
} else {
entries.push(...collectNavPageEntries(page));
}
}
}
for (const value of Object.values(record)) {
if (value !== record.pages) {
entries.push(...collectNavPageEntries(value));
}
}
return entries;
}
const markdownLinkRegex = /!?\[[^\]]*\]\(([^)]+)\)/g;
/** @type {{file: string; line: number; link: string; reason: string}[]} */
@ -221,6 +256,22 @@ for (const abs of markdownFiles) {
}
}
for (const page of collectNavPageEntries(docsConfig.navigation || [])) {
checked++;
const route = normalizeRoute(page);
const resolvedRoute = resolveRoute(route);
if (resolvedRoute.ok) {
continue;
}
broken.push({
file: "docs.json",
line: 0,
link: page,
reason: `navigation page not published (terminal: ${resolvedRoute.terminal})`,
});
}
console.log(`checked_internal_links=${checked}`);
console.log(`broken_links=${broken.length}`);