diff --git a/CHANGELOG.md b/CHANGELOG.md index 639f381..678ab05 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,15 @@ # Changelog +## 2026-08-18 +- Added `docs/ops-hub-v2/AUDIT-2026-08-18.md` — read-only audit of the historical + cross-project dashboard, command center, Ops Hub, Code Dashboard, project + manifest, and public portfolio surfaces, with each artifact classified + preserve / migrate / archive / unlink / remove-from-public. +- Added `docs/ops-hub-v2/OPS_HUB_V2_SPEC.md` — build spec for the consolidated + replacement: registry schema, `ops-state.json` v2 contract, nine enforced + invariants, build order, and acceptance criteria. +- README: linked both documents. + ## 2026-07-06 - Added LICENSE (explicit all-rights-reserved). diff --git a/README.md b/README.md index b5e44c7..dc9fb18 100644 --- a/README.md +++ b/README.md @@ -36,6 +36,20 @@ node notionDashboardUpdate.js --dry-run # print a sample summary, no API calls In production, the script runs unattended via the `Update Notion Dashboard` GitHub Actions workflow, which needs a `NOTION_TOKEN` secret configured on the repo. +## Related documents + +This repo drives the Notion Code Dashboard page, which makes it one artifact in a +longer lineage of cross-project dashboards. That lineage was audited on +2026-08-18: + +| Document | What it covers | +|---|---| +| [`docs/ops-hub-v2/AUDIT-2026-08-18.md`](docs/ops-hub-v2/AUDIT-2026-08-18.md) | Read-only audit of every historical dashboard, command center, manifest, and public portfolio surface, with each artifact classified preserve / migrate / archive / unlink / remove-from-public | +| [`docs/ops-hub-v2/OPS_HUB_V2_SPEC.md`](docs/ops-hub-v2/OPS_HUB_V2_SPEC.md) | Build spec for the consolidated replacement: registry schema, state contract, enforced invariants, and acceptance criteria | + +Both are public-safe by construction and cite only already-public evidence. The +Ops Hub v2 implementation itself belongs in a private repo — see §11 of the spec. + ## License All rights reserved — see [LICENSE](LICENSE). diff --git a/docs/ops-hub-v2/AUDIT-2026-08-18.md b/docs/ops-hub-v2/AUDIT-2026-08-18.md new file mode 100644 index 0000000..7fc41fe --- /dev/null +++ b/docs/ops-hub-v2/AUDIT-2026-08-18.md @@ -0,0 +1,324 @@ +# Cross-Project Dashboard Surface Audit — 2026-08-18 + +> [!IMPORTANT] +> **Read-only audit.** Nothing was archived, unlinked, deleted, de-indexed, or +> republished. Every remediation below is gated behind explicit approval +> (see [Remediation bundles](#remediation-bundles)). + +## Scope + +Every historical surface that has, at some point, tried to answer *"what projects +exist and what state are they in"*: cross-project dashboards, command centers, +Ops Hub, Code Dashboard, the project manifest, and the public portfolio hub. + +Each artifact is classified as **preserve**, **migrate**, **archive**, **unlink**, +or **remove from public**. + +## Publication boundary applied to this document + +`DaveHomeAssist/code-dashboard` is a **public** repository. Since the central +finding of this audit is that internal operations material leaked onto public +infrastructure, publishing an unredacted inventory here would reproduce the exact +defect being reported. This document therefore contains **only facts already +public**: anonymous HTTP crawl results, the contents of the already-public +`project-manifest.json`, and architecture description. + +Deliberately excluded: workspace page titles/URLs/IDs, local filesystem paths, +private project identifiers, run IDs, and client-engagement detail. Where an +internal source is cited it is referred to by **role**, not by name — e.g. +"the dashboard standards governance page". The unredacted inventory belongs in a +private repository. + +## Method + +| Evidence class | How it was obtained | Trust | +|---|---|---| +| HTTP status, redirects, robots meta, page `
` | Anonymous `curl` against the live host, 2026-08-18 | **Confirmed** | +| Sitemap contents | `GET /sitemap.xml` | **Confirmed** | +| Public project inventory | `GET /project-manifest.json` | **Confirmed** | +| Hub rendering logic | Read of the served hub HTML | **Confirmed** | +| Repository visibility | GitHub API | **Confirmed** | +| Dashboard lineage & design intent | Internal workspace records | **Reported** — not independently reproducible here | + +Not available, and therefore **not** asserted anywhere in this document: Search +Console, analytics, CrUX/Lighthouse, indexation state, or traffic outcomes. No +claim below depends on knowing whether a page is actually *indexed* — only on +whether it is *indexable*. + +--- + +## Root cause + +Six dashboard generations were built. All six were rebuilt as a **new surface**; +none established a **contract** underneath. The concrete expression of that today: + +> **`visibility` is decorative metadata. Nothing in any build step converts it +> into a robots directive, a sitemap entry, or a link-rendering decision.** + +Every finding below is a symptom of that single missing invariant. + +### Evidence: `visibility` has no enforcement + +13 projects are marked `visibility: unlisted` in the public manifest. 12 have a +live URL. Their robots directives, fetched anonymously: + +| Live `` | Count | Verdict | +|---|---:|---| +| `noindex,nofollow` | 1 | Matches declared intent | +| *(no robots meta at all)* | 10 | Declared unlisted, fully indexable | +| `index, follow` | 1 | **Explicitly contradicts** its own manifest entry | + +One page carries an affirmative `index, follow` while its manifest row says +`unlisted`. That is not drift — it is two systems asserting opposite things with +no arbiter. + +### Evidence: the sitemap and the manifest are disjoint + +| Measure | Value | +|---|---:| +| On-host project URLs in the manifest | 48 | +| Of those, returning HTTP 200 | **48 / 48** | +| Of those, present in `sitemap.xml` | **1** | +| Sitemap entries that are *not* a manifest project | **8 of 9** | + +The sitemap is not stale — it is an **orphan from a different lineage**. Its 9 +entries are the root hub plus a brand palette, two internal strategy reports, and +four one-off pages. It has never described the project portfolio at all. + +### Evidence: hub links do not exist until JavaScript runs + +The served hub HTML contains no project anchors. The project directory is built +client-side from the manifest, filtered on `visibility === 'public'`. The static +document offers one fallback: a link to the raw JSON. + +This makes the manifest the **sole** discovery path — and it is the same file that +carries the unenforced `visibility` field. + +--- + +## Findings + +### F-001 · Internal operations dashboard is publicly indexable +**Severity: Critical** · **Classification: remove from public** + +`/command-center-061eed/` serves HTTP 200 with a complete internal operations +console: per-project status panels, an attention queue, git sync state, daily run +history, domain status, and a triage lane. + +Verified state of the document ``: + +| Element | Present | +|---|---| +| `` | **No** — the string `noindex` appears **zero** times in the entire 229 KB document | +| `` | No | +| `` | No | +| `