Skip to content

feat(doc): the documentation is world-readable — /Doc links unfurl, docs get indexed - #2838

Merged
rbuergi merged 2 commits into
mainfrom
feat/doc-public-link-previews
Aug 31, 2026
Merged

rbuergi merged 2 commits into
mainfrom
feat/doc-public-link-previews

Conversation

@rbuergi

@rbuergi rbuergi commented Aug 30, 2026

Copy link
Copy Markdown
Contributor

Requested by the maintainer: mesh links pasted into Teams show no card. The outbound SEO pipeline (SeoHead + /api/og/{path}.png) is live and complete — measured today, all 81 store covers on memex serve full OG cards anonymously — but SeoResolver fails closed through the AnonymousGate, so only anonymous-readable pages unfurl. /Doc wasn't one: its seeded policy granted Viewer to Public (all authenticated users) and never carried PublicRead.

Change

Doc/_Policy (code-seeded in DocumentationExtensions) gains PublicRead = true — exactly the shape PartitionAccessPolicy.PublicRead's own docs name Documentation as the intended user of. The docs GitSync from this public repository, so an anonymous reader learns nothing that is not already on github.com. CUD stays false; the Public→Viewer grant stays for the signed-in comment/thread surface.

Everything downstream keys off this one bit: the crawler-facing head (og:*, JSON-LD), the /api/og share card, <noscript> content for indexing.

Also: Doc/Architecture/LinkPreviews

A new doc page conserving today's investigation — the two features both called "OG card" (outbound SEO head vs the inbound OgCard layout-area package), the anonymous-read rule and why a private page must never unfurl, the PublicRead opt-in shape, and how to verify an unfurl with curl instead of pasting into chat. Pairs with MeshWeaver.Plugins (OgCard package description fix + og:site_name empty-string fix).

Tests

SyncedPartitionReadOnlyTest gains Doc_IsAnonymouslyReadable (root + a page): anonymous holds Read and never C/U/D. Suite: 6/6 passed.

🤖 Generated with Claude Code

https://claude.ai/code/session_01QoG4USP5fd8wsxCD7e9q4x

…olicy

Mesh links pasted into Teams/Slack/LinkedIn unfurl only for pages an ANONYMOUS
crawler may read — SeoResolver fails closed through the AnonymousGate, which is
right. Doc was gated to authenticated users (Public→Viewer reaches no logged-out
visitor), so every shared /Doc/… link arrived as a bare URL and the docs were
invisible to search.

Doc/_Policy now carries PublicRead = true — the grant-to-everyone bit whose own
XML docs name Documentation as the intended user. The docs GitSync from the
public MeshWeaver repository, so anonymous read reveals nothing not already on
github.com. CUD stays false; the Public→Viewer grant stays so signed-in users
keep comment/thread.

Also adds Doc/Architecture/LinkPreviews — the investigation's findings as a doc
page: the two features both answering to "OG card" (outbound SEO head vs the
inbound OgCard layout area), the anonymous-read rule, the PublicRead opt-in
shape, and the curl check that stands in for pasting a link into chat.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01QoG4USP5fd8wsxCD7e9q4x
Copilot AI lite review requested due to automatic review settings August 30, 2026 20:18
@rbuergi
rbuergi enabled auto-merge August 30, 2026 20:19

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR makes the Documentation partition (/Doc) anonymously readable by seeding Doc/_Policy with PublicRead = true, enabling Open Graph link unfurling (og:* head + /api/og/{path}.png) and crawler indexing for docs that are already public via GitHub.

Changes:

  • Seed Doc/_Policy with PublicRead = true while keeping C/U/D capped off and preserving the signed-in Public→Viewer grant for comments/threads.
  • Add a regression test ensuring anonymous users have Read (and no C/U/D) on Doc root and a representative doc page.
  • Add a new architecture doc page explaining link preview behavior and the anonymous-read gate.

Reviewed changes

Copilot reviewed 3 out of 3 changed files in this pull request and generated no comments.

File Description
test/MeshWeaver.Content.Test/SyncedPartitionReadOnlyTest.cs Adds coverage for anonymous-read permissions on /Doc (root + a page).
src/MeshWeaver.Documentation/DocumentationExtensions.cs Seeds Doc/_Policy with PublicRead = true to make docs world-readable.
src/MeshWeaver.Documentation/Data/Architecture/LinkPreviews.md Documents how outbound link previews work and why anonymous-read is required.

💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

@github-actions

github-actions Bot commented Aug 30, 2026 •

Copy link
Copy Markdown
Contributor

Test Results (shard 0)

792 tests   788 ✅  4m 30s ⏱️
  7 suites    4 💤
  7 files      0 ❌

Results for commit a535bbf.

♻️ This comment has been updated with latest results.

@github-actions

github-actions Bot commented Aug 30, 2026 •

Copy link
Copy Markdown
Contributor

Test Results (shard 1)

951 tests   951 ✅  5m 13s ⏱️
  7 suites    0 💤
  7 files      0 ❌

Results for commit a535bbf.

♻️ This comment has been updated with latest results.

@github-actions

github-actions Bot commented Aug 30, 2026 •

Copy link
Copy Markdown
Contributor

Test Results (shard 4)

1 085 tests   1 085 ✅  5m 18s ⏱️
    7 suites      0 💤
    7 files        0 ❌

Results for commit a535bbf.

♻️ This comment has been updated with latest results.

@github-actions

github-actions Bot commented Aug 30, 2026 •

Copy link
Copy Markdown
Contributor

Test Results (shard 3)

1 186 tests   1 186 ✅  8m 1s ⏱️
    7 suites      0 💤
    7 files        0 ❌

Results for commit a535bbf.

♻️ This comment has been updated with latest results.

@github-actions

github-actions Bot commented Aug 30, 2026 •

Copy link
Copy Markdown
Contributor

Test Results (shard 5)

    8 files      8 suites   5m 31s ⏱️
1 534 tests 1 533 ✅ 1 💤 0 ❌
2 227 runs  2 226 ✅ 1 💤 0 ❌

Results for commit a535bbf.

♻️ This comment has been updated with latest results.

@github-actions

github-actions Bot commented Aug 30, 2026 •

Copy link
Copy Markdown
Contributor

Test Results (shard 2)

3 025 tests   2 833 ✅  5m 58s ⏱️
    8 suites    192 💤
    8 files        0 ❌

Results for commit a535bbf.

♻️ This comment has been updated with latest results.

@github-actions

github-actions Bot commented Aug 30, 2026 •

Copy link
Copy Markdown
Contributor

Test Results

   44 files     44 suites   34m 34s ⏱️
8 573 tests 8 376 ✅ 197 💤 0 ❌
9 266 runs  9 069 ✅ 197 💤 0 ❌

Results for commit a535bbf.

♻️ This comment has been updated with latest results.

@rbuergi

rbuergi commented Aug 30, 2026

Copy link
Copy Markdown
Contributor Author

This red is not yours — and it is a RECURRENCE of a flake the tree believes it fixed

Triaged while draining the merge queue. Shard 2's failure is:

##[error] MeshWeaver.Hosting.Monolith.Test.MeshNodeLanguageServiceTest
          .ScriptCompletions_FilterByTypedPrefix_NotJustTheAlphabet
##[error] Shard 2: failing tests in trx — failing the shard.

A documentation PR cannot reach the kernel script language service, so this is not attributable to the diff.

🚨 Why it is worth more than a re-run

That test is named verbatim in KernelScriptReferences.cs, as the symptom of the defect #2616/#2769 was written to remove:

"It used to be the answer: a Lazy<Task<ImmutableArray<…>>> whose value GetReferencesAsync returned directly. That FROZE AppDomain.CurrentDomain.GetAssemblies() as of the process's FIRST kernel session — and assemblies load LAZILY … Under parallel shard load the lottery is decided by whichever unrelated test ran first, which is why it presented as a flake reproducing on completely unrelated diffs (ScriptCompletions_FilterByTypedPrefix_NotJustTheAlphabet losing "Mesh")."

#2769 is already merged (ead524e99), so the freeze is gone — GetReferencesAsync now composes the set fresh from the current assembly list on every call. And the test failed anyway, on 2026-08-30 20:33.

That is informative rather than disappointing, because it narrows the remaining cause. The fix removed the permanent freeze; it cannot remove the transient one. A fresh composition still only sees what is loaded at that instant, so a completion computed before the assembly carrying "Mesh" has lazily loaded still shorts the symbol. Under parallel shard load that window is real.

So the residue is a startup-ordering race, not a caching bug — and the fix that would close it is different in kind: the completion path has to wait for (or force) the assembly set it depends on, rather than sample whatever is loaded.

There is no open issue for it — #2616 is closed and was about MeshNodeLanguageServiceTest's teardown, a different aspect. So this recurrence is currently untracked, which is how it will be re-diagnosed from scratch next time.

One more thing in the same log, unexplained

digest-mismatch: error        ← 20:26:16 (shard 2) and again 20:34:12 (consolidate)

I have not chased it and it may be benign, but it appears in both jobs and it is the kind of line that matters given tonight's registry trouble. Flagging rather than asserting.

What I would do with this PR

Nothing to fix here. The shard is red on an unrelated, pre-existing flake with a named mechanism — so a re-run is diagnosis-backed, not the hope-based re-run AGENTS.md forbids. Worth saying so explicitly in the PR record, and worth filing the recurrence separately so the next occurrence is the second data point rather than the first again.

@rbuergi
rbuergi added this pull request to the merge queue Aug 31, 2026
Merged via the queue into main with commit 5751e0e Aug 31, 2026
25 checks passed
@rbuergi
rbuergi deleted the feat/doc-public-link-previews branch September 13, 2026 10:30
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants