This manual is the operator-facing path for connecting Astro pages to Discourse.
It explains the decisions, safe sequence, expected results, and points where an
operator should stop. Use the Machine Manual beside it
when exact commands, fields, scopes, or recovery checks matter.
Discussion Bridge keeps each system doing the job it does well:
Astro owns fast, structured public pages.
Discourse owns identity, replies, moderation, notifications, and community
memory.
Discussion Bridge maintains the declared relationship between them.
This is Alpha documentation. Preview every write, keep publishing opt-in, and
verify both systems after a live operation.
Before installing anything, record one row for each content lane:
Decision
Example
Astro site URL
https://docs.example.com
Discourse URL
https://forum.example.com
Content directory
src/content/docs
Route base
empty for docs, blog for /blog/...
Discourse category ID
5
Discourse tags
product,docs
Source mode
astro-managed, discourse-managed, or discourse-imported
Comments mode
simple, full, or fullInteractive
Listing behavior
listed or unlisted
A content lane is one source directory plus its route, category, tags, and
operating behavior. Docs, blog posts, news, and releases should normally be
separate lanes.
Stop if: the public page URL, source owner, category, or managing page is
unclear. A wrong route base or source mode can attach or write to the wrong
discussion.
Visual placeholder: lane-planning worksheet with one completed docs lane.
May publish a new topic and sync its managed first post.
discourse-managed
Discourse
Display or pull from Discourse; do not write back.
discourse-imported
Imported Astro copy
Edit locally if desired, but do not write back until explicitly promoted.
For every discourse-managed or discourse-imported page, add this frontmatter
guard:
discussionSync: false
The named source modes express operating policy, and the CLI write guard is
discussionSync: false. The reviewed Alpha import path generates
discussionSourceMode: discourse-imported, boolean discussionSync: false, and
preserves the topic ID and URL. Review those fields after every import before
running any directory-wide sync command.
Promotion means a human explicitly decides Astro will become the source of
truth, reviews the page and linked topic, and removes the guard. Editing an
imported file by itself is not promotion.
Stop if: an imported or Discourse-owned page lacks discussionSync: false, or promotion was not explicitly approved.
Create a dedicated bot user, such as discussbridge-bot.
Create or choose the destination category.
Create the planned tags, or confirm the bot can create them.
Add the exact Astro hostname as an allowed embedding host.
Create a granular publishing key for routine publish and sync operations.
Create a separate diagnostics key for setup checks when granular reads are
insufficient.
For each key, choose User Level and Scope independently. All Users
allows the request to act for the supplied Api-Username; Single User binds
the key to its selected user. Scope separately limits endpoints. Discussion
Bridge supplies the preferred request actor from --post-as,
DISCOURSE_POST_AS, or lane/default postAs/postAsEnv. Legacy
--api-username, DISCOURSE_API_USERNAME, apiUsername, and apiUsernameEnv
remain fallbacks. The resolved actor is sent as Api-Username. Live operations
show Post as: USER; check-discourse shows Request actor.
When creating either key, show its complete purpose block with the setup
instructions and copy that block into the respective protected credential file
above the secret value.
Bot user role: Admin currently; intended future runtime posture is non-admin or least-privilege
Key user level: Record All Users or Single User; prefer Single User for a fixed runtime actor
Key selected user: Record when User Level is Single User
Request actor: Record resolved postAs / Api-Username
Key scope: Granular
Operational rule: Use this to validate the minimum permissions needed for normal bridge publishing.
Diagnostics key record:
Purpose: Diagnostics/setup key
Use: check-discourse only
Bot user role: Admin
Key user level: Record All Users or Single User and the selected user/actor relationship
Key selected user: Record when User Level is Single User
Request actor: Record resolved postAs / Api-Username used for diagnostics
Key scope: Global or admin-read capable
Operational rule: Do not use in CI/build unless explicitly intended
The settled publishing scopes are:
categories:list
categories:show
posts:edit
posts:list
search:show
tags:list
topics:write
topics:update
topics:read
topics:status
The diagnostics key is currently a global/admin-capable fallback for
check-discourse and controlled troubleshooting. Do not place it in the normal
runtime or deployment path.
Store key values only in a credential vault, session environment, or hosting
provider secret store. Never place them in source files, screenshots, issues,
chat, or build logs.
See Key Management for the complete credential-file
templates, including description, scope, granular permissions, and the secret
placeholder.
Stop if: the routine publishing key is broader than intended without a
recorded reason, the diagnostics key is configured as the normal publishing
key, or a real key appears in a file or screenshot.
Screenshot placeholder: Discourse granular-key screen showing only the
settled User Level and publishing scopes, with no visible key value.
Create a special-admin custom group as the visible inventory for nonhuman
admin/service accounts. Then assign actual admin, category, and API authority
separately; group membership grants none of those by itself.
For connected forums, prevent actual and visually ambiguous service-account
collisions. Candidate forum-source editors are editorbridgeforum /
Discussion Bridge Forum Editor and editorcanforum / CAN Forum Editor.
Verify normalized username length and availability before creation.
Astro-origin actors should identify the source site or brand; keep established
obbba-bot as the OBBBA source identity.
Use preset: "starlight" for Starlight and preset: "astro" for broader
Astro sites. Keep publishOnBuild.enabled false until the lane has passed
explicit CLI dry runs and a controlled live test.
For Starlight placement and the layout override, follow
Alpha Setup. You should see the Astro site build normally
and the discussion area appear only on pages with linked topic metadata.
Set these in the shell running the command or in a protected CI/deployment
secret store:
DISCOURSE_URL
SITE_URL
DISCOURSE_POST_AS
DISCOURSE_API_USERNAME
DISCOURSE_API_KEY
DISCOURSE_DIAGNOSTICS_API_KEY
DISCOURSE_DIAGNOSTICS_API_KEY is optional. When absent,
check-discourse falls back to the publishing key and may report metadata as
unavailable rather than failing.
Prefer DISCOURSE_POST_AS; retain DISCOURSE_API_USERNAME only for backward
compatibility. postAs selects the request actor but does not silently change
ownership of an existing topic.
You should be able to run a command without printing any key value.
You should see discovered limits, tag capabilities, category details, setup
issues or warnings, and reconciliation details when --page-url is present.
Warnings about unavailable site metadata mean the key could not prove the
setting; they are not permission to guess.
Page-URL reconciliation and explicit existing-topic linking are different:
When a page supplies discourseTopicId, that topic ID is authoritative for
the native/full-app embed. A page-URL embed-info 404 or exact search with no
owner does not invalidate a healthy explicit topic.
When no topic ID is supplied, the embed uses the page URL and URL ownership
must reconcile correctly before release.
Always verify the explicit topic directly as well as recording any independent
page-URL reconciliation result.
Pages without discourseTopicId and pages with discussionSync: false are
skipped. Use --force only when deliberately rewriting a first post despite an
unchanged source hash.
Files may use either LF or Windows CRLF line endings. The bridge recognizes both
frontmatter forms and preserves the existing style when it updates frontmatter.
If a valid linked page is unexpectedly reported as not linked, stop before any
write and check frontmatter-boundary parsing rather than relinking the topic.
Both read-side guard recognition and write-side line-ending preservation are
covered by regression tests.
Choose discourse-managed when edits continue in the source topic. Omit
--source-mode or use discourse-imported for the imported-copy default.
astro-managed is rejected because import is a Discourse-to-Astro operation.
discussionSourceMode: discourse-managed
discussionSync: false
You should see the selected source mode and discussionSync: false generated
with a Markdown file linked to the original topic. Review the imported body and
frontmatter before building or editing. Avoid --overwrite unless replacement
is intentional and recoverable. A manifest entry may use sourceMode to make
the same selection per topic.
Stop if: a dry run shows an unexpected page URL, topic ID, target,
category, managing page, overwrite, or writeback-eligible imported page.
To place a hero image at the start of an imported page:
--hero-image and --hero-alt are a required pair. Alt text must contain
meaningful non-whitespace text. The generated Markdown places one angle-wrapped
leading image before the unchanged raw topic body; internal path spaces and
escaped alt text are supported.
Stop if: only one hero option is present, alt text is empty/whitespace, or
the hero insertion changes the normalized Discourse body.
To remove the known trailing community call-to-action block during import:
This opt-in profile removes only a trailing block after a horizontal rule when
all four markers are present: Join the Conversation Today, /signup, Please share how, and /c/stories/. Without a verified boundary, import stops before
writing a file. Unknown, duplicate, bare, or empty profile inputs also fail
before file I/O.
You should see discussionImportPolicy: "pruned:community-call-to-action" only
after a successful profiled import.
Import discovery/queue is required for Alpha. Use either:
an explicit topic list or manifest for curated imports; preserve the order the
operator supplied;
“next in category” for queue work. First list/discover available categories,
including subcategories, then select by category ID or an unambiguous
slug/name. Preview that category’s queue and choose the oldest Discourse
created_at, using topic ID as the stable tie-breaker.
After category selection, optional filters may narrow tags, created-date range,
open/closed status, and result limit. Operators may request oldest-first or
newest-first ordering, but both use created_at.
For numbered collections whose created dates are unreliable, Alpha may use
natural topic-title/name ordering (for example, Section 10102 before 10103).
This never permits ordering by latest activity.
Always preview the candidate list before importing and exclude topics already
represented by imported Astro pages.
For deterministic refresh of pages with different policies, use the reviewed
Alpha import manifest rather than a blanket update-all operation. Its strict
JSON contains only version and ordered imports. Each topic entry retains its
own commentsDisplay, heroImage/heroAlt, and pruneProfiles, and caller
order is preserved. Run import-existing --manifest ... --overwrite.
Preview before writing. The bridge rejects duplicate topics and mixing manifest
mode with direct topic options, revalidates every entry, checks destinations and
path containment, and stages the whole batch before atomic creation or
overwrite rollback. A failed batch must not leave a partial import set.
Treat every import as two joined contracts:
WHEREFROM: the Discourse base or target, explicit topic or curated order,
category when the lane uses one, and required tags or filters;
WHERETO: the Astro content root, explicit output file, public route, and
Astro navigation lane, with the site URL fixed as part of public identity.
Validate the source identity and live tag constraints before writing. Make the
destination deterministic, reviewable, and contained inside the content root.
Manifest v1 keeps these as the existing flat fields—such as topic,
requiredTags, and output—rather than a new nested structure. A nested
from/to form is only a possible future evolution.
If the source topic later moves to another Discourse category, Discussion
Bridge reports:
source category changed: OLD -> NEW; Astro route/navigation unchanged
An overwrite refreshes discussionSourceCategoryId, but it does not silently
move the Astro file, public route, or Astro navigation lane. WHEREFROM changed;
WHERETO remains an explicit operator or manifest decision. Review and change
the destination separately only when that is the intended publishing decision.
Never use:bumped_at, last reply, or latest activity for queue order.
Community participation must not reorder publishing candidates.
Replies and likes render; browser refresh works through CORS or a proxy.
fullInteractive
Logged-in reply, like, quote, and moderation should remain inside Discourse.
Full-app embed, sign-in, iframe height, and mobile behavior work.
For full, configure a same-origin refreshEndpoint when browser CORS does not
allow direct topic JSON reads. For fullInteractive, enable Discourse’s full-app
embed settings and test both signed-in and signed-out users.
To close a live signed-in interaction item, create one clearly labeled test
reply through the browser, then verify its public post URL, content marker, and
updated topic count. Recheck the Astro page’s topic/full-app signature afterward.
Record the evidence without publishing private account identifiers.
An existing-page interaction result does not prove a fresh-import workflow.
Before closing an import gate, separately test: no hero/no prune, hero only with
alt text, prune only, and hero plus prune. For every case, verify generated
source-mode guards, preserved topic linkage, build/deploy/live rendering,
comments, and no accidental writeback.
For an existing topic, pass its topic ID through the complete component path.
The native embed should configure { topicId } when it is present and fall back
to { discourseEmbedUrl: embedUrl } only when there is no explicit topic ID.
Rendering ownership changes by comments mode. The package’s Astro-rendered
full mode now has reviewed first-generation parity: Mermaid replies render
client-side by default, and tables receive readable styling plus horizontal
overflow handling. Set replies.renderMermaid: false to opt out. Mermaid is
loaded only when a reply needs it; a load or render failure preserves the source
code for recovery instead of destroying the reply.
In fullInteractive, the cross-origin iframe belongs to Discourse, so Astro-side
Mermaid transforms and CSS cannot render or restyle content inside it. The
ordinary topic view may render Mermaid while the full-app comments embed still
shows raw Mermaid source because the embed application does not load normal
theme-component JavaScript. Use Discourse embedded CSS, targeted with the bridge
embed class hook, for immediate table presentation. Mermaid still needs a
Discourse-side embed extension, plugin, or upstream solution; do not mark it
fixed.
Screenshot placeholders: one desktop and one mobile capture for each mode.
Video placeholder: sign in, reply, like, and return to the Astro page in
fullInteractive mode.
A future configurable credit may say Discussion connection by Discussion Bridge or Discourse connection by Discussion Bridge. Final wording, default
behavior, and configuration remain undecided. It must link to the canonical
product page, remain visually secondary, be accessible, work across all three
comments modes, and not be hard-coded into site content.
This is a roadmap item and does not change the current reviewed artifact or its
deployment gate.
If src/content/blog/example.md renders at /blog/example/, use:
Terminal window
--route-baseblog
The page URL is part of the Discourse ownership contract. Check it in
--details output before every lane’s first live write. Only one Astro page may
manage a topic in a run; comparison pages should use discussionSync: false.
Keep Astro/template content tags separate from Discourse discussionTags
unless an explicit mapping is introduced later.
Discussion Bridge does not require Cloudflare Pages, but the Alpha demos use it.
For a static Astro site:
Build from the canonical repository and the intended site/example root.
Use the project’s normal install and npm run build commands.
Confirm the output directory matches the Astro/Cloudflare project settings.
Set the final public URL in Astro site and Discussion Bridge siteUrl.
Attach the intended custom domain and wait for HTTPS to become valid.
Add that exact hostname to Discourse’s allowed embed hosts.
Verify the homepage, a lane route, its companion topic, and comments.
When Workers are used, verify both the Worker endpoint and canonical domain.
Confirm the deployed page has the expected package/topic signature and that
any retired renderer is absent.
If more than one Cloudflare account is available, the approved site deployment
configuration should pin the intended account so deployment is repeatable. Keep
private account labels and login addresses out of public manuals and screenshots.
Before making a deployment-only commit, inspect the site worktree. Preserve and
report unrelated pre-existing edits instead of silently including them.
Also build the exact committed candidate from a clean checkout or detached
worktree. A local file deletion can make a dirty build look healthy while the
tracked release still contains the stale page. If the clean build finds one,
isolate the removal or repair in its own reviewed commit and build again.
If the deployed page looks stale, verify the deployment commit and Discourse
topic first. Then test with a cache-bypassing request or clear only the relevant
Cloudflare cache. Do not treat a confirmed sync as failed until cache state is
ruled out.
Discussion Bridge has now been exercised against the production
Cloudflare-CDN-backed Discourse deployment at forum.repealobbba.org.
Diagnostics/API reads, topic imports, target reconciliation and source-topic
links, fullInteractive comments, signed-in replies, five live source notices,
and no-writeback behavior all passed in that bounded environment.
This proves compatibility with that production deployment, not every possible
CDN, WAF, or cache rule. When placing Cloudflare in front of Discourse, preserve
Discourse API paths and JSON endpoints, embed and full-app routes,
authentication/cookies, and websocket behavior. If API or embed behavior differs
from a direct-origin check, investigate cache and WAF handling before treating
the bridge as broken.
Stop if: the deployment uses a transitional copy instead of canonical
source, the custom domain differs from siteUrl, HTTPS is invalid, or the
Discourse embed host does not exactly match the public hostname.
CLI summary reports the expected created, updated, skipped, or unchanged count.
the topic title, category, tags, and listing state are correct;
the first post contains the intended reader-facing content and source link;
frontmatter contains the expected topic link and sync metadata;
the Astro page and full-discussion link work;
comments work in the chosen mode;
no secret appears in source, output, screenshots, or support material.
Never automatically recreate a deleted topic or first post. Confirm whether the
deletion was intentional, then choose restore, relink, or replacement explicitly.
See Troubleshooting for known failures and recovery
guidance.
Code completion alone does not make a release ready. For every Alpha, Beta,
release candidate, patch, and Current release, the release record must show:
Code Boss reviewed the exact release candidate and recorded pass or fail.
All blocking code-review edits are complete and re-reviewed when required.
Bridge Boss completed technical verification.
Manual Boss completed documentation quality review.
The Human and Machine Manuals are ready for the exact release.
Product Boss documentation sign-off is recorded.
Product Boss release approval is recorded.
These last two decisions are different:
Product Boss documentation sign-off confirms that the manuals and product
docs accurately describe the proposed release.
Product Boss release approval confirms that the release is coherent across
intended scope, operator readiness, known limitations, and its documentation
package.
Product Boss release approval does not replace Code Boss review, Bridge Boss
technical verification, or Manual Boss quality review. A failed, unresolved, or
edit-pending Code Boss review blocks Product Boss approval.
Stop if: any required review is missing, a blocking edit is unresolved,
the manuals describe a different build, or either Product Boss decision has
not been recorded for the exact release candidate.
The cumulative Alpha feature/function set is locked in the product checklist.
After the lock, work belongs in Alpha only when it closes an existing promise or
gate, fixes exercised behavior, or is approved explicitly as a scope change.
Unchecked Alpha gates still need to be finished; the lock does not mark them
complete.
Alpha should honestly represent the major capabilities in its declared product
promise and be nearly feature-complete for that promise. Beta should primarily
refine real-user experience, compatibility, reliability, performance,
packaging, documentation, installation, recovery, support, and presentation.
This does not move every future or Layer 3 idea into Alpha.
Tier 1 operation remains API-only, free/self-serve, and independent of any
Discourse plugin. An optional Discourse plugin vertical slice has been proposed
and accepted for Alpha, pending implementation design and proof. It is optional,
not a Tier 1 installation requirement. The first slice is limited to
fullInteractive Mermaid/table parity and a future-safe architecture/test
baseline—not the full control plane, post-as-user, PM automation, or general
many-to-many management.
Current proposed CAN path is to use the existing Discourse Mermaid theme
component for normal topics and design a bounded optional plugin slice for
Mermaid in full-app embeds, table parity, embed-context detection, and tests.
This remains pending design/review and does not change Tier 1 installation.
Discourse Mermaid is the official theme component documented at
Meta topic 218242 and
discourse/discourse-mermaid-theme-component.
It is not a plugin. Keep it distinct from a fork/extension of that theme
component, the separate optional Discussion Bridge for Discourse plugin, and
an upstream Discourse change.
The optional plugin is a separate product/repository under Boss routing. Its
v0.1 Alpha goal is installable and removable on supported stock/current
Discourse with documented rollback, no ordinary-topic regression, and a live
CAN full-app proof. It must detect embed context explicitly and cover Mermaid,
tables, and tests. Full control plane, general forum-to-forum orchestration,
post-as-user, PM automation, and broad many-to-many administration remain out.
Alpha scope is cumulative. Plugin and multi-target work add to every previously
accepted Alpha gate; they do not rewrite or shorten the promise. Use the existing
dashboard and build/launch checklists as the complete source of truth, and remove
an item only when Phil explicitly directs that change.
All three Alpha software tracks remain free/open source unless explicitly
changed later: the Astro package, the optional light Discourse plugin, and
public docs/community support. Paid offerings are implementation help,
handholding, managed hosting/operations, customization, support, and
consulting. Third-party hosting and infrastructure remain operator-paid.
Alpha must demonstrate the product loop in both directions without creating a
two-writer loop:
Publish an Astro-managed discussionbridge.dev blog post to a public
companion discussion on forum.discussionbridge.dev.
Republish a reviewed community wiki/how-to from
forum.discussionbridge.dev as a durable guide on
discussionbridge.dev.
For the wiki lane, use discourse-managed plus discussionSync: false, show
source provenance near the article start, preserve the source topic as the
primary discussion, and define the output route and Astro navigation lane
explicitly. Refresh deterministically from the wiki topic. Editors change the
wiki in Discourse; the site republishes the reviewed source. Do not imply that
replies from separate topics are merged.
You should see: a public guide with a clear source link, an explicit
primary discussion, and predictable navigation placement.
Stop if: the site is able to write back to the wiki source, the source
topic changes unexpectedly, the destination route drifts, or comments
presentation silently selects or merges discussions.
The public outcome is: “The site starts conversations. The community develops
durable knowledge. The site publishes what the community learns.”
Implementation and Code Boss review are complete at 1731547 with 72/72 tests.
Apex adoption commit d68ffc4 also received Code Boss PASS, passed a clean
detached install/build that generated five actual public apex routes, and was
deployed on 2026-07-23. This is distinct from the readable product-docs build,
which synchronized 20 documentation sources and generated 21 HTML pages in this
documentation pass.
Astro-managed blog ──publishes──▶ Forum topic 37
Forum wiki topic 36 ──publishes──▶ Discourse-managed Astro guide
Visuals derived from this diagram must use alt text that names both directions
and says the reply streams remain separate. Do not include admin screens,
credentials, tokens, account identifiers, or protected storage in screenshots
or video.
Live verification shows:
/blog/every-connection-has-a-job/ returns 200 and binds its independent
public companion discussion to topic 37;
/guides/how-to-choose-a-discussion-bridge-source-mode/ returns 200, shows
source disclosure, and renders source wiki topic 36 as the primary
fullInteractive discussion;
a deliberate guide sync-existing --dry-run skips with the
discourse-managed no-writeback reason;
the raw Pages hostname redirects to the canonical apex.
This closes the bounded two-direction dogfood gate. It does not claim merged
reply streams or general forum-to-forum orchestration. The clean install still
reported one high-severity npm audit finding, and the Mermaid chunk remains
larger than 500 kB; neither was hidden or changed with an automatic audit fix.
See the
sanitized verification record
for the live markers and claim boundary.
The topic-36 editor-ownership acceptance test remains open. A human operator
must change the wiki first-post owner from discourseadmin to the selected
Discussion Bridge Forum editor, edit the wiki while signed in as that editor,
re-import/refresh the discourse-managed guide with overwrite, then verify
content and source ownership, build/deploy/live markers, and no Astro
writeback. Actor configuration alone does not complete this test.
Imported pages may now show Source author: Display Name (@username) when
Discourse exposes safe author data. The username links only to the same forum’s
safe /u/username profile, preserving a Discourse subfolder base when present:
https://example.com/forum/t/... becomes
https://example.com/forum/u/editorbridgeforum. Unsafe usernames are omitted
rather than linked.
An explicit overwrite refresh updates discussionSourceAuthorUsername and
discussionSourceAuthorName while preserving source mode,
discussionSync: false, and topic ID.
The Alpha multi-target model is implemented and reviewed. The first two edges
of the bounded live topology proof are complete; the wider matrix still tracks:
the same selected onebigbeautifulbill.us page → forum.repealobbba.org;
that same selected page → forum.citizenactivist.network;
The first two prove one Astro page can explicitly connect to several forums; the
last proves many sites can converge on one forum. Citizen Activist
Network’s forum identity is “A community of activists.” Its Cloudflare/account
ownership placement remains an Ops decision.
Live adoption commit 36df91c98a35251edd6ddd657cca42ddf0acdafa proves the
same 10101 page can retain Repeal OBBBA topic 434 as protected source and primary
fullInteractive discussion while linking an independent Citizen Activist
topic 9 under accessible Additional discussions navigation. Diagnostics,
target-specific dry-run, publication, unchanged retry, clean build, deployment,
live checks, and no-source-writeback verification passed.
Use the narrowest correct content root. For this lane it is
src/content/docs/title i with route base title-i and active target
citizen-activist. An earlier broad dry-run exposed a wrong root/index and a
malformed title-i/title i route before any write. Treat previewed route drift
as a stop condition, correct the lane, and rerun dry-run.
Keep credentials in protected storage. Do not copy storage paths, account
values, or secrets into public docs. Existing record-format cleanup belongs in
the protected vault. The exact clean install reported 10 dependency audit
findings (1 low, 1 moderate, 8 high); route them for dependency review and do not
apply an automatic npm audit fix.
Post-proof interaction remained correctly separated: Citizen Activist topic 9
accepted a live reply as post 2, while the Astro page continued embedding
protected/primary Repeal OBBBA topic 434. Readers could reach the independent
Citizen Activist conversation through the accessible Additional discussions
link. This is interaction/presentation evidence for the closed bounded gate,
not a broader topology claim.
The page must distinguish its protected source target from its ordered
publication/discussion targets. Review each target’s forum, topic binding, sync
and error state, and display policy independently. Keep the imported/managed
source protected from writeback while allowing explicitly approved publication
to another forum.
In frontmatter, list the page’s targets in order with discussionTargets, then
name only writable destinations in discussionPublishTargets. Identify the
protected imported/managed source with discussionSourceTarget. The bridge keeps
each forum’s result independently in discussionTargetBindings.
If more than one discussion is linked, choose discussionPrimaryTarget. You
should see that discussion rendered in the selected comments mode and the other
targets as accessible named links. Optional targetLabels can make those link
names friendlier. Stop if a multi-linked page has no explicit primary; the build
error is protecting the operator from a silent choice.
Run the CLI once per explicit --target. If one target fails after another
succeeds, keep the successful binding and retry only the failed target. The
stored failure is target-specific and sanitized. Do not manually discard a
successful binding or create a replacement topic merely because another target
failed.
Choose the primary rendered discussion and state whether additional targets are
linked or rendered; never let the bridge silently select one. If one target
fails, keep successful bindings, report the failure, and retry only that target
idempotently without duplicate topics. Diagnostics, previews, CLI output, and
live checks must identify the target. General administration remains later.
Every connection has a job. A reader should understand whether
an additional discussion is for the public community, a chapter or region,
internal review, subject-matter feedback, advocacy coordination, or syndication.
Use that purpose in its visible label and call to action. Never imply that
independent replies have been merged.
Lead with the outcome: “Publish from the site. Learn in the community. Turn what
the community knows into durable pages.” Content can begin on either side;
discussion stays where the people are, and durable knowledge can be published
where readers can find it. A destination-only label is not enough.
Possible reader-facing patterns are Discuss with the Citizen Activist
Community, Review with the policy team, Discuss with your state
chapter, and View the source wiki, each followed by a short audience and
context explanation.
CAN can support Astro-to-Discourse and Discourse-to-Astro flows, but only with
separate page/topic pairs and explicit source ownership. Stop if the same item
would be writable in both directions; choose one writer and protect the other
side. Relay, promotion, and summary automation are later features.
Another future pattern is Local ownership. National reach. A chapter can
turn local experience into network knowledge without giving up its community,
context, or voice. The national community can discover and discuss chapter work
while every topic remains connected to where it began. Local and national reply
streams stay separate: one serves local coordination/context, the other national
learning/amplification.
The likely reverse path distributes national campaign guidance into selected
chapter forums for local discussion. Before enabling either direction, require
mapped categories, chapter/region metadata, public/private eligibility,
moderator approval policy, source attribution/return links, explicit one-way
updates, and clear moderation owners. General forum-to-forum orchestration is
future design, not current capability.
12. Show Where Discourse-Sourced Content Came From
Pages imported from or managed in Discourse should disclose their source near
the start of the article. This notice is separate from comments and from any
Discussion Bridge credit at the comments boundary.
Wire DiscussionSource into the canonical page boundary:
The plain Astro BlogPost layout and Starlight MarkdownContent override are the
canonical placements. You should see a quiet aside labeled Content source
with a bold Source: prefix:
discourse-imported: “This page originated in Discourse and was imported
here for publication.”
discourse-managed: “This page is managed in Discourse and published here
for easier reading.”
astro-managed or unknown mode: no notice.
sourceLabel defaults to Discourse. Use sourceLabel, message, and
linkLabel to adapt public wording without hiding provenance. Other component
inputs are class, mode, sourceUrl, targetBindings, and frontmatter.
The source link follows this order: explicit sourceUrl,
discussionImportedFrom, the protected discussionSourceTarget binding (with
legacy discussionTarget fallback), then legacy discourseTopicUrl. Only
absolute http or https URLs become links. If every candidate is unsafe or
malformed, the disclosure remains visible without a link.
Stop if: a multi-target page attributes its origin to an additional
publication target. Provenance must always follow the protected source target.
Package behavior is implemented and reviewed at a9d2097 with Code Boss PASS
and 68/68 tests. OBBBA adopted reviewed artifact
astro-discussion-bridge-0.1.0-alpha-a9d2097-f3fbb73e.tgz at commit aa7846d.
Its clean production build and deployment passed. All five canonical Title I
routes now show exactly one Content source aside and one source link, with
the imported wording, Repeal OBBBA Forum label, and correct protected
forum.repealobbba.org topic. The existing discussion boundary remains present.
This closes OBBBA source-disclosure adoption only; it does not close the separate
Citizen Activist topology gate.
The intended public Alpha channel is a GitHub prerelease plus an npm prerelease
of the same reviewed Astro-package commit. Publish a semver prerelease such as
0.1.0-alpha.1 under npm dist-tag alpha—never latest. The exact first
version remains a release-gate decision. Public installation becomes:
Terminal window
npm install astro-discussion-bridge@alpha
Reserve latest for the first stable release. Beta should deliberately choose
beta, next, or another documented prerelease tag after Alpha learning; npm
does not begin only in Beta. Repository/tarball installs remain useful for
development, recovery, and fallback, but are not the primary public Alpha path.
Do not publish until the release checklist passes package ownership/publisher
authority, account security, exact version/content review, clean packed and
registry installs in plain Astro and Starlight, exports/components/CLI/feature
smokes, metadata and secret/file hygiene, Code Boss and Manual Boss review,
GitHub/npm commit correspondence, dist-tag verification, consumer install, and
rollback/deprecation procedure. Published npm versions are immutable. Never run
an automatic npm audit fix as part of release preparation.
Run the full package suite against the exact built release candidate. Its
passing result includes the automated full attribution gate, covering
root/package MIT parity and holder, package metadata, production dependency
licenses against the explicit allowlist or reviewed override evidence,
required npm package contents, README/non-affiliation and rendered links,
tracked-media provenance, and protected-path scanning. Record the exact suite
total in the candidate-specific evidence.
The readable docs build runs a narrower gate. You should see:
Attribution and licensing gate: PASS (docs scope)
npm package contents: SKIPPED (requires built release candidate)
The synchronized-source and generated-HTML totals mean synchronization,
rendering, and this bounded docs-scope check passed. Record the exact totals in
the candidate-specific evidence. This result does not verify the release
tarball and does not replace the full package gate.
Stop if: either gate fails, the results are conflated, generated
attribution output was not regenerated on a fresh checkout, or a
protected/private path appears.
Automation cannot decide whether attribution is adequate or whether copied,
adapted, branded, or sourced material is appropriate. Before release, Manual
Boss must record Attribution and Licensing: PASS / FAIL / N/A, list the paths
reviewed, and create a sanitized review record tied to the exact release
commit.
For candidate b09dbce atop 7127eb1 and 462b3ae, Manual Boss recorded
Attribution and Licensing: PASS with no remaining findings or blockers. Read
the sanitized exact-candidate review record.
This PASS applies only to that exact candidate; it does not pre-approve later
release changes.
The intended support split is:
GitHub Issues for confirmed bugs, reproducible failures, docs gaps, and
feature work;
the Discussion Bridge Alpha Support category for setup questions, field
reports, screenshots, and community help;
paid help for private implementation and migration work.
The live support category and email route remain release prerequisites until
verified. Never include keys or credentials in a support report. Follow
Support And Feedback for the sanitized diagnostic
fields to include.