Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions docs/dream-cycle/LEDGER.md
Original file line number Diff line number Diff line change
Expand Up @@ -32,3 +32,5 @@ Schema note (2026-09-14, unmerged): FR6.6 of PRD-augmentation-conditions adds `R
| 2026-09-30 | seo-and-meta | Given the shipped page at `d4e4429` declares an Organization but never declares | NONE | https://github.com/DreamLab-AI/VisionFlow/pull/4 | yes | ACCEPT | | 65a9d02cf480 | | | |
| 2026-10-01 | build-pipeline | Given `website/static/robots.txt` reaches `dist/` only through `build.sh`'s whol | NONE | https://github.com/DreamLab-AI/VisionFlow/pull/11 | yes | ACCEPT | | 7f88b6695afe | | | |
| 2026-10-02 | seo-and-meta | Given the shipped page at `2480a8f` declares its brand only in `<title>`/nav cop | NONE | https://github.com/DreamLab-AI/VisionFlow/pull/12 | yes | ACCEPT | | 369fbc125f52 | | | |
| 2026-10-03 | estate-health | Given canon declares seven sidestr crates on crates.io while `scripts/estate-hea | NONE | https://github.com/DreamLab-AI/VisionFlow/pull/13 | yes | ACCEPT | | 9c56f9ff2d42 | | | |
| 2026-10-04 | content-integrity | Given the shipped page's `href="#…"` anchors all resolve to `id="…"` targets in | NONE | https://github.com/DreamLab-AI/VisionFlow/pull/14 | yes | ACCEPT | | 617ce2f95547 | | | |
23 changes: 20 additions & 3 deletions scripts/dream-link-check.sh
Original file line number Diff line number Diff line change
Expand Up @@ -3,14 +3,20 @@
# the built static site. Emits a surface-dependent count; non-zero missing
# refs prints LINK-INTEGRITY-FAIL. Used as a dream-cycle evaluator entrypoint.
#
# Two ref families are resolved:
# Three ref families are resolved:
# 1. href/src attributes — ordinary markup links and asset references.
# 2. meta[content] media URLs (og:image, twitter:image, …). These were a
# shared blind spot: dream-meta-tags-scan.sh COUNTS the tags but never
# looks at the URL, and this script only ever parsed href/src, so an
# og:image pointing at a file absent from dist/ passed both gates. The
# social card is a required asset in website/assets.manifest.json, and
# this makes that requirement observable from the link surface too.
# 3. in-page hash anchors. href="#id" must resolve to an id="id" target in
# the same document. Family 1's pattern excludes every ref containing
# '#', so pure-hash anchors (the entire nav) were invisible to this gate
# (2026-09-29 ledger). The 2026-10-04 content-integrity night verified a
# 0-dangling baseline, and the operator approved (2026-10-02) promoting
# dangling > 0 to a failing condition.
#
# Social URLs are absolute on the canonical domain (they must be, for the
# crawlers), so "site-relative" here includes same-origin absolute URLs: the
Expand Down Expand Up @@ -38,7 +44,7 @@ resolve_ref() {
esac
}

miss=0; checked=0
miss=0; checked=0; anchors=0; dangling=0
while IFS= read -r f; do
d=$(dirname "$f")

Expand All @@ -58,6 +64,17 @@ while IFS= read -r f; do
checked=$((checked+1))
[ -e "$d/$t" ] || [ -e "./$t" ] || { echo "MISSING: $f -> $ref"; miss=$((miss+1)); }
done

# 3. in-page hash anchors — must resolve to an id= target in the same
# document. Family 1 skips refs containing '#', so a nav or card link
# to a missing section id passed this gate unnoticed.
for ref in $(grep -oE '[[:space:]]href="#[^"]+"' "$f" 2>/dev/null | sed -E 's/.*href="#([^"]*)"/\1/'); do
[ -n "$ref" ] || continue
anchors=$((anchors+1))
grep -qE "[[:space:]]id=\"$ref\"" "$f" 2>/dev/null \
|| { echo "DANGLING-ANCHOR: $f -> #$ref"; dangling=$((dangling+1)); }
done
done < <(find . -name '*.html')
echo "internal-refs-checked: $checked missing: $miss"
[ "$miss" -eq 0 ] && echo LINK-INTEGRITY-OK || echo LINK-INTEGRITY-FAIL
echo "anchors-checked: $anchors dangling: $dangling"
[ "$miss" -eq 0 ] && [ "$dangling" -eq 0 ] && echo LINK-INTEGRITY-OK || echo LINK-INTEGRITY-FAIL
Loading