DiscussionBridge for Astro Machine Manual
Historical Astro implementation reference. Do not use this page as a current package-family install contract. Use the Alpha Installation and Operator Guide, then the exact README and immutable artifact for the selected platform profile.
This is the exact, reusable implementation memory for DiscussionBridge for Astro. Use it with the Human Manual to generate a site-specific runbook. It may name variables, paths, endpoints, and scopes; it must never contain real secret values.
1. Product And Package
Section titled “1. Product And Package”product: DiscussionBridgearchitecture: Discourse-centered_adapter-drivenoperational_home: DiscussionBridge for Discoursecontrol_plane_host: Discourseportable_core: owns: - connections - identities - mappings - policies - jobs - comparisons - approvals - retries - provenance - audit_evidenceadapters: current: [Astro] planned: [Statamic, future_publishing_systems] rule: adapters_translate_portable_contract_and_do_not_create_control_planestier_1_API_only: status: supported_compatibility_capability natural_operational_center: falseportability: rule: keep_core_domain_logic_host-neutral_where_practical future_host_option: standalone_without_domain_rewriteimplementation_status: architecture_decision: settled core_plugin_adapter_migration: openproduct_family: umbrella: Discussion_Bridge free_products: - Discussion_Bridge_for_Discourse - Discussion_Bridge_for_Astro paid_managed_product: name: Discussion_Bridge_SaaS purpose: multi_CMS_multi_site_multi_community_orchestration paid_services: - implementation - migration - customization - training - operations - extensive_support community: public_docs: true community_support: true team_help: as_capacity_permits commercial_rule: SaaS_sells_managed_operation_scale_governance_convenience_and_operational_relief_not_artificial_limit_removal shared_foundation: portable_Discussion_Bridge_Core_contracts_policies_terminology_identity_and_trust_modelAstro_product: DiscussionBridge for AstroAstro_package: astro-discussion-bridgepackage_root: packages/astro-discussion-bridgecli_source: packages/astro-discussion-bridge/src/cli.tssync_source: packages/astro-discussion-bridge/src/sync/index.tsimport_source: packages/astro-discussion-bridge/src/import-existing.tspublic_docs: docsdefault_starlight_dir: src/content/docsdefault_astro_dir: src/contentClassify new and existing behavior before moving or extending it:
behavior_classification: portable_core: test: owns_domain_policy_state_or_audit_evidence Discourse_host: test: uses_Discourse_users_permissions_jobs_UI_database_APIs_or_operations publishing_adapter: test: maps_portable_contract_to_CMS_content_navigation_rendering_build_or_deployprohibited: - duplicate_control_plane_per_adapter - unnecessary_Discourse_internal_dependency_in_portable_domain_logic - claim_migration_complete_before_reviewed_implementation_evidencePackage commands run from the consuming Astro project root:
npx astro-discussion-bridge --helpnpx astro-discussion-bridge check-discourse [options]npx astro-discussion-bridge publish-new [docsDir] [options]npx astro-discussion-bridge sync-existing [docsDir] [options]npx astro-discussion-bridge publish-and-sync [docsDir] [options]npx astro-discussion-bridge import-existing [docsDir] --topic URL[,URL] [options]sync is a backward-compatible alias for publish-new; do not use it in new
runbooks because the side effect is less obvious.
2. Site-Specific Generation Inputs
Section titled “2. Site-Specific Generation Inputs”Collect and validate before generating a runbook:
site_name: requiredrepository: requiredproject_root: requiredenvironment: dev | staging | live | placeholderframework_preset: astro | starlightsite_url: required absolute HTTPS URL for live usediscourse_url: required absolute URLpost_as: preferred request actor for live writeslegacy_api_username: optional compatibility fallbackpublishing_key_location: private reference only; never key valuediagnostics_key_location: private reference only; never key valueactive_target: optional logical target namecomments_display: simple | full | fullInteractivedeployment_target: optional, e.g. Cloudflare Pagesverification_urls: required for live laneslanes: - name: required docs_dir: required route_base: optional source_mode: astro-managed | discourse-managed | discourse-imported category_id: required for create/update intent tags: [] listed: true | false managing_page_rule: exactly one managing Astro page per topic recovery_owner: required for productionReject or pause generation when source mode, route base, public URL, destination forum, category, or managing page is unknown.
3. Key Model
Section titled “3. Key Model”Publishing Key
Section titled “Publishing Key”Use for publish-new, sync-existing, and publish-and-sync.
Exact settled granular scopes:
categories:listcategories:showposts:editposts:listsearch:showtags:listtopics:writetopics:updatetopics:readtopics:statusKnown allowed-parameter entries from the Discourse granular-key UI:
categories show: id=anyposts edit: id=anysearch show: q=any, page=anytopics write: topic_id=anytopics update: topic_id=any, category_id=anytopics read: topic_id=any, external_id=anytopics status: topic_id=any, category_id=any, status=any, enabled=anyThe API user also needs the forum/category authority required by the action. Retitling replied topics and changing listing status may require staff or moderator capability even when the key has the matching endpoint scope.
Diagnostics Key
Section titled “Diagnostics Key”Current fallback: global/admin-capable, read-oriented setup/source key. Use for
check-discourse and controlled import-existing source reads when the
granular key cannot read the required raw post. Do not use this key for
publishing, reconciliation, CI/build, or routine runtime/deploy paths.
Target future state: a granular diagnostics/read key after required Discourse site metadata scopes are confirmed.
Required Credential Record Blocks
Section titled “Required Credential Record Blocks”Every key-creation interaction MUST present the applicable block with the key description, user, scope, and permissions. The operator MUST copy the block into the respective protected credential file above the secret value. Never request, echo, log, or write the real key outside the protected credential store.
Publishing key:
Purpose: Runtime publishing granular keyUse: publish-new, sync-existing, publish-and-sync, check-discourse basic limitsBot user role: Admin currently; intended future runtime posture is non-admin or least-privilegeKey scope: GranularOperational rule: Use this to validate the minimum permissions needed for normal bridge publishing.Diagnostics key:
Purpose: Diagnostics/setup and protected source-read keyUse: check-discourse; controlled import-existing source reads when granular raw-post access failsBot user role: AdminKey scope: Global or admin-read capableOperational rule: Do not use in CI/build unless explicitly intendedThe complete credential-file templates, including the settled publishing
scopes and secret placeholder, are in docs/KEY_MANAGEMENT.md.
Environment Variables
Section titled “Environment Variables”DISCOURSE_URLSITE_URLDISCOURSE_POST_ASDISCOURSE_API_USERNAMEDISCOURSE_API_KEYDISCOURSE_DIAGNOSTICS_API_KEYDISCOURSE_CATEGORY_IDDISCOURSE_TAGSDISCUSSION_TARGETDISCUSSION_PAGE_URLDISCOURSE_NOTIFY_RECIPIENTSDISCOURSE_TITLE_MIN_LENGTHDISCOURSE_MAX_TOPIC_TITLE_LENGTHDISCOURSE_MAX_POST_LENGTHDISCOURSE_MAX_TAGS_PER_TOPICDISCOURSE_MAX_TAG_LENGTHResolution behavior:
- CLI values override environment values.
check-discourseprefers--diagnostics-api-keyorDISCOURSE_DIAGNOSTICS_API_KEY, then falls back to the publishing key.--dry-runpublish/sync does not require API username/key.- live publish/sync/import requires
DISCOURSE_API_USERNAMEandDISCOURSE_API_KEY.
request_actor: preferred_inputs: environment: DISCOURSE_POST_AS cli: --post-as publishOnBuild_lane_or_default: [postAs, postAsEnv] legacy_fallbacks: environment: DISCOURSE_API_USERNAME cli: --api-username publishOnBuild_lane_or_default: [apiUsername, apiUsernameEnv] precedence: - explicit_or_lane_postAs - named_postAsEnv - DISCOURSE_POST_AS - legacy_apiUsername_controls request_header: Api-Username live_output: "Post as: USER" diagnostics_output: "Request actor" changes_existing_topic_owner: falseapi_key_authority: user_level: All_Users: may_act_for_supplied_Api_Username Single_User: bound_to_selected_user scope: values: [Global, Read-only, Granular] purpose: endpoint_and_action_authority invariant: user_level_and_scope_are_independentservice_identity: collision_rule: no_actual_or_visually_ambiguous_nonhuman_identity_across_forums naming_rule: role_plus_origin_system candidates: - { username: editorbridgeforum, public_name: DiscussionBridge Forum Editor } - { username: editorcanforum, public_name: CAN Forum Editor } verify_before_create: [normalized_username, site_length_limits, availability] preserved_source_identity: obbba-bot inventory_group: name: special-admin grants_admin_status: false grants_API_rights: false grants_category_permissions: falsediscourse_mermaid: official_existing_option: type: theme_component meta: https://meta.discourse.org/t/discourse-mermaid/218242 repository: https://github.com/discourse/discourse-mermaid-theme-component distinct_paths: - existing_official_theme_component - fork_or_extension_of_theme_component - separate_Discussion_Bridge_for_Discourse_plugin - upstream_Discourse_change forbidden_term: Discussion_Bridge_Mermaid_plugin tier_1_API_only_dependency: none4. Source-Mode Contract
Section titled “4. Source-Mode Contract”| Source mode | Required operational guard | Writable by publish/sync? |
|---|---|---|
astro-managed |
explicit ownership decision | yes |
discourse-managed |
discussionSync: false |
no |
discourse-imported |
discussionSync: false until explicit promotion |
no |
Current implementation facts:
discussionSync: falseis read and enforced by sync preflight.- A guarded page reports
skippedwith reasondiscussionSync is false. - Frontmatter parse/update paths accept LF and CRLF boundaries and preserve the source file’s existing line-ending style when writing updates.
- Sync preflight remains guard-driven, while the reviewed import path generates
discussionSourceMode: discourse-importedand booleandiscussionSync: false. - Import preserves the Discourse topic ID and URL.
Therefore, the required Alpha import procedure is:
- run
import-existing --dry-run; - run the live import only after reviewing the destination;
- verify the generated source mode, boolean sync guard, topic ID, and URL;
- review frontmatter before any directory-wide sync;
- preserve and commit the imported source before promotion;
- promote only by changing
discussionSourceModetoastro-managed, settingdiscussionSync: true, and selecting the explicit writable target when target bindings are present; - run
sync-existing --dry-run --detailsbefore the first promoted write.
5. Frontmatter Contract
Section titled “5. Frontmatter Contract”Line-ending invariant:
accepted_frontmatter_boundaries: - LF - CRLFupdate_behavior: preserve existing source line-ending stylerequired_regression_case: discussionSync false is enforced for CRLF frontmatterrequired_write_regression: frontmatter updates preserve CRLF source stylePublishing may write:
discussionTarget: "community" # only when a target is activediscourseTopicId: 123discourseTopicUrl: "https://forum.example.com/t/example/123"discussionSourceHash: "sha256-value"discussionLastSyncedAt: "ISO-8601 timestamp"Import currently writes:
discussionTarget: "community" # optionaldiscourseTopicId: 123discourseTopicUrl: "https://forum.example.com/t/example/123"discussionSourceHash: "sha256-value"discussionImportedAt: "ISO-8601 timestamp"discussionCommentsDisplay: "full" # only when requestedOperator-supplied controls and overrides include:
discussionSync: falsediscussionCommentsDisplay: simple # simple | full | fullInteractivediscussionSummary: | Curated Discourse-safe companion content.discourseCategoryId: 5discussionTags: "product, docs"6. Command Contract And Expected Results
Section titled “6. Command Contract And Expected Results”check-discourse
Section titled “check-discourse”Reconciliation contract:
explicit_existing_topic: input: discourseTopicId embed_config: '{ topicId }' page_url_reconciliation_required: false verification: read and validate the explicit topic directlyurl_owned_topic: input: no discourseTopicId embed_config: '{ discourseEmbedUrl: embedUrl }' page_url_reconciliation_required: trueKeep embed-info/exact-URL-search results in diagnostics even for explicitly
linked topics, but do not treat a 404 or no URL owner as a topic failure when
the explicit topic is healthy.
Read-only endpoints may include:
/site/settings.json/site.json/categories.json/tags.json/embed/info?embed_url=...exact URL search fallbackCanonical command:
npx astro-discussion-bridge check-discourse \ --discourse-url https://forum.example.com \ --category-id 5 \ --tags product,docs \ --page-url https://docs.example.com/example-page/Global diagnostics-key example:
DISCOURSE_DIAGNOSTICS_API_KEY=diagnostics-key \npx astro-discussion-bridge check-discourse \ --discourse-url https://forum.example.com \ --api-username discussionbridge-editor \ --category-id 5 \ --tags product,docs \ --page-url https://docs.example.com/example-page/Granular publishing-key example with reviewed explicit limits:
DISCOURSE_API_KEY=granular-publishing-key \npx astro-discussion-bridge check-discourse \ --discourse-url https://forum.example.com \ --api-username discussionbridge-editor \ --category-id 5 \ --tags product,docs \ --min-topic-title-length 15 \ --max-topic-title-length 255 \ --max-post-length 32000 \ --max-tags-per-topic 6 \ --max-tag-length 30The granular run may still report settings/capabilities/reconciliation as 403 warnings. Explicit limits constrain local validation; they do not manufacture missing read authority.
Expected output sections:
Discourse URLSite settingsSite capabilitiesLimitsTag capabilitiesCategoryRequested tags / Tag inventory / Tag issuesSetup issues / Setup warningsReconciliation lookup (when page URL supplied)Exit code is nonzero when tag issues or setup issues exist. Unavailable metadata may be reported as warnings/unknown values.
publish-new
Section titled “publish-new”Creates only missing companion topics and skips linked pages.
npx astro-discussion-bridge publish-new src/content/docs --dry-run --detailsnpx astro-discussion-bridge publish-new src/content/docsExpected per-page statuses include dry-run-create, created, skipped, and
failure output. A live create writes topic link and sync metadata to frontmatter.
sync-existing
Section titled “sync-existing”Updates only pages with discourseTopicId; skips missing links and guarded pages.
npx astro-discussion-bridge sync-existing src/content/blog \ --route-base blog --dry-run --detailsnpx astro-discussion-bridge sync-existing src/content/blog --route-base blogExpected statuses include dry-run-update, updated, unchanged, and
skipped. --force rewrites the managed first post even when the source hash is
unchanged. --unlist changes topic visibility and may require staff authority.
publish-and-sync
Section titled “publish-and-sync”Creates missing topics and syncs linked topics in one explicit run:
npx astro-discussion-bridge publish-and-sync src/content/releases \ --route-base releases --dry-run --detailsUse only after checking that every non-Astro-managed page in the directory has
discussionSync: false.
import-existing
Section titled “import-existing”npx astro-discussion-bridge import-existing src/content/docs \ --topic https://forum.example.com/t/example/123 \ --source-mode discourse-managed \ --site-url https://docs.example.com \ --comments-display full \ --dry-runHero options:
--hero-image PATH|URL--hero-alt TEXTValidation contract:
pairing: bidirectional_requiredhero_alt: non_empty_after_trimexplicit_errors: - bare option - inline-empty value - whitespace-only alt - hero image without alt - hero alt without imageoutput: placement: leading image before raw body image_syntax: angle-wrapped destination alt_escaping: supported internal_path_spaces: supportedPrune option:
--prune-profile community-call-to-actionprofile: community-call-to-actionmode: opt_inremoval_scope: trailing block after horizontal rulemarkers_all_required: - Join the Conversation Today - /signup - Please share how - /c/stories/failure_before_io: - no verified boundary - unknown profile - duplicate profile - bare option - empty valuesuccess_metadata: discussionImportPolicy: pruned:community-call-to-actionAccepted topic references: numeric ID or URL whose host matches
DISCOURSE_URL. Expected statuses: dry-run-import, dry-run-overwrite,
imported, skipped. Existing files are skipped unless --overwrite is used.
--source-mode accepts discourse-imported or discourse-managed, defaults to
imported, and rejects astro-managed. Generated frontmatter always includes the
selected discussionSourceMode and discussionSync: false. Manifest entries
use sourceMode; the same validation is applied before write.
Alpha Import Discovery / Queue Contract
Section titled “Alpha Import Discovery / Queue Contract”selection_modes: curated: input: explicit topics or manifest ordering: preserve caller-supplied order next_in_category: command: discover-imports operation: read_only_preview category_discovery: list available categories and subcategories category_selector: ID or unambiguous slug/name category_selection: required before queue preview include_descendants: optional default_order: created_at ascending tie_breaker: topic ID ascendingfilters_optional: - tags - created_at range - open/closed status - limitordering_optional: - oldest by created_at - newest by created_at - natural topic title/name for numbered collectionsforbidden_order_fields: - bumped_at - last reply - latest activitypre_import: validate_before: - network_fetch - local_scan - dereference - filesystem_work invalid_runtime_values: fields: [sourceMode, commentsDisplay] result: reject_with_zero_fetch preview_selected_category_queue: required preview_candidates: required exclude_already_imported_topics: source_fields: - opening_frontmatter.discourseTopicId - strictly_parsed_opening_frontmatter.discussionTargetBindings.topicId unrelated_topicId_metadata: eligible descendant_categories: fetch: direct duplicate_topics: deduplicated date_only_created_to: include_full_UTC_daymanifest_output: option: --manifest-out FILE format: strict_v1 overwrite: refused default_sourceMode: discourse-imported selectable_sourceMode: [discourse-imported, discourse-managed] selectable_commentsDisplay: [simple, full, fullInteractive]other_output: JSON: --jsonpublic_category_requirements: site_URL: not_required credentials: not_requiredreview_status: implementation: complete package_suite: 84/84 live_read_only_CDN_proof: forum: https://forum.repealobbba.org category: 18 tags: [TITLE-I] order: natural-title limit: 10 scanned: 320 excluded_already_imported: 5 candidates: [754, 755, 756, 757, 758, 759, 761, 762, 763, 764] files_written: 0 Code_Boss: PASS_after_three_correction_rounds full_attribution_and_package_gate: PASSsite_specific_dry_run_example: site: onebigbeautifulbill.us manifest: discussionbridge-imports-title-i-10106-10306.json topics: [754, 755, 756, 757, 758, 759, 761, 762, 763, 764] target: repeal-obbba route_base: title-i result: { imported: 0, skipped: 0, dry_run: 10, generatedPages: 0 } writes: { Discourse: 0, Astro_content: 0 } completed_followup: granular_attempt: topic_endpoint: { path: /t/754.json, HTTP: 200, first_post_raw: absent } raw_post_fallback: { path: /posts/761.json, resource: first_post_of_topic_754, identifier_kind: post_id, HTTP: 403 } result: stopped_pre_write_invalid_access operational_rule: use_protected_diagnostics_global_key_for_controlled_import_source_reads_when_granular_raw_post_access_fails live_import: { imported: 10, skipped: 0, dry_run: 0, Discourse_writes: 0 } content_commit: 5cfc99a cleanup_commit: a5f5df9 clean_build_HTML: 17 corrected_worker_version: 2fa24e22-2f79-4053-9f3b-436cf9f776b4 live_routes: { expected: 10, HTTP_200: 10 } stock_routes: { expected_404: 3, verified_404: 3 } proven_gate: live_import_build_deploy_and_per_route_verificationalpha_requirement: trueThe stable comparison key for the default queue is (created_at, topic_id).
Community replies must never reorder publishing candidates.
Manifest refresh gate:
command: import-existing --manifest PATH --overwritepurpose: deterministic multi-page refresh with per-topic policyschema: format: strict_json top_level_keys: [version, imports]manifest_entry_fields: - topic - requiredTags - output - commentsDisplay - heroImage - heroAlt - pruneProfilesordering: preserve caller-supplied manifest orderreject: - duplicate_topics - manifest_and_direct_option_mixingvalidation: - runner_revalidation - dry_run_collision_and_path_preflight - path_containment_before_writeswrite_model: - stage_all_entries_before_writes - exclusive_atomic_creation_without_overwrite - atomic_overwrite_with_rollbackregression_coverage: - slug_drift - destination_race - zero_byte_output - path_traversalblanket_update_all_safe: falsepackage_gate: pass_51_of_51obbba_site_live_proof: pass_topics_434_747_751_752_753Every import route has two validated contracts:
WHEREFROM: discourse_base_or_target: required topic_identity_or_curated_manifest_order: required category: required_when_lane_uses_one required_tags_and_filters: validate_against_live_source_before_writeWHERETO: docs_dir: deterministic Astro content root output: safe relative .md or .mdx file public_identity: site_url + route_base navigation: Astro navigation lane invariants: [deterministic, reviewable, path_contained, never_latest_activity]manifest_v1_mapping: wherefrom: [topic, requiredTags] whereto: [docsDir, output, site-url, route-base, astro_navigation_lane_map]future_schema_note: nested from/to may be considered later; do not redesign v1 nowrequiredTags comparisons are case-insensitive assertions against live
Discourse tags and fail before any write. Discourse topic tags may arrive as
strings or objects. output must be a safe relative .md or .mdx path;
nested parent directories are created only after the entire destination passes
validation and containment checks.
Starlight Imported-Page Integration
Section titled “Starlight Imported-Page Integration”Stock Starlight docsSchema() may strip custom bridge fields, and imported
Markdown pages do not contain a hand-written <Discussion> component. A
Starlight consumer must:
- extend
docsSchemawith the DiscussionBridge frontmatter fields; - install
src/components/MarkdownContent.astroat the page boundary; - wire it through
starlight.components.MarkdownContent; - remove per-page explicit
<Discussion>instances when the boundary override is active, preventing duplicate discussions.
Verification requires exactly one discussion instance per linked page with the expected topic ID and display mode.
7. Common CLI Options
Section titled “7. Common CLI Options”--dry-run--details--target NAME--route-base PATH--discourse-url URL--site-url URL--api-username USER--api-key KEY--tags TAG[,TAG]--category-id ID--force--unlist--notify-on-failure--notify-recipients USER[,USER]--title-min-length N--max-topic-title-length N--max-post-length N--max-tags-per-topic N--max-tag-length N--skip-title-validationDo not put real keys on a command line in a runbook; use protected environment variables so keys do not enter shell history.
8. Lanes And Route-Base Rules
Section titled “8. Lanes And Route-Base Rules”URL derivation joins siteUrl, normalized routeBase, and the Markdown path
relative to docsDir, with index collapsed to its parent path.
Examples:
docsDir=src/content/blogfile=src/content/blog/content-lanes.mdrouteBase=blogresult=https://docs.example.com/blog/content-lanes/
docsDir=src/content/releasesfile=src/content/releases/2_1.mdrouteBase=releasesresult=https://docs.example.com/releases/2_1/Pre-write invariants:
- one managing Astro source page per Discourse topic in a run;
- no duplicate managed page URL in a run;
- active
discussionTargetmust match--target/DISCUSSION_TARGET; - display-only comparison pages use
discussionSync: false; - category and tags are checked before live writes;
- computed URLs are reviewed with
--details.
9. Comments Display Contract
Section titled “9. Comments Display Contract”discussionBridge({ provider: "discourse", discourseUrl: "https://forum.example.com", siteUrl: "https://docs.example.com", comments: { display: "full", // simple | full | fullInteractive embedHeight: "800px", dynamicHeight: true, embedMinHeight: "360", embedMaxHeight: "900", className: "discussion-bridge-embed", }, replies: { refreshOnPageLoad: true, refreshEndpoint: "/api/discourse/topics/{topicId}.json", renderMermaid: true, },});simple: Discourse embeddable-comments script; limited display control and metadata.full: Astro-rendered replies; interaction remains in Discourse; browser refresh needs CORS or same-origin proxy.fullInteractive: Discourse full-app iframe; requires full-app embedding and compatible sign-in/cookie configuration.
Rendering boundary:
fullInteractive: owner: cross_origin_Discourse_iframe dynamic_height: default: true initial: 800px min_px: 360 max_px: 900 responsive_max: prohibited_competing_CSS_ceiling legacy_embedViewportMaxHeight: none_only_or_configuration_failure operator_disable: dynamicHeight_false purpose: let_qualified_Discourse_Core_own_dynamic_iframe_height_without_host_clipping host_Astro_transforms_or_CSS_cross_boundary: false mermaid_and_table_styling_owner: Discourse ordinary_topic_434_mermaid_theme_result: SVG full_app_embed_topic_434_mermaid_result: raw_code full_app_embed_theme_component_js_loaded: false table_parse: pass table_presentation: weak_until_embedded_CSS immediate_table_path: Discourse common/embedded.scss targeted by embed class mermaid_embed_solution: open_extension_plugin_or_upstreamfull: owner: Astro_rendered_bridge_component parity_review: pass_d7800d7_code_boss_final renderMermaid_default: true renderMermaid_opt_out: false mermaid_version: 11 security_level: strict loading: lazy_when_reply_contains_mermaid failure: preserve_source_and_allow_module_load_retry tables: readable_borders_padding_and_horizontal_overflow repeated_components: claim_each_replies_container_onceembed_class_hooks: comments.className: forwarded_to_window.DiscourseEmbed.className embedClassName_components: [Discussion, DiscourseDiscussion, DiscourseComments]The lazy Mermaid chunk is emitted during a full-capable build and may trigger
Vite’s greater-than-500-kB warning, but browsers fetch it only when a full-mode
reply contains Mermaid.
Verification matrix:
simple: embed loads, full discussion link worksfull: build/render fetch works, browser refresh works, unavailable state worksfullInteractive: logged-out load, logged-in reply/like/quote, mobile height/CSPFor a live signed-in interaction item, record sanitized evidence:
topic_id: expected topicpost_number: created test post numberdirect_post_url: public verification URLcontent_marker: non-sensitive test textpost_count_after: observed countastro_embed_signature_after: topic_id: expected topic full_app: true retired_renderer: absentprivate_account_identifier: omitCreating the reply is an intentional browser-session action, not a package publish/sync/import operation. Verify the forum result read-only afterward.
Fresh-import gate matrix:
cases: - { hero: false, prune: false } - { hero: true, prune: false, alt_text: required } - { hero: false, prune: true } - { hero: true, prune: true, alt_text: required }per_case_assertions: - discussionSourceMode == discourse-imported - discussionSync == false - topic ID and URL preserved - build/deploy/live render pass - comments pass - no writebackDo not use an existing-page migration or signed-in interaction result as a substitute for this matrix.
Component propagation invariant:
Discussion.astro -> DiscourseDiscussion.astro -> DiscourseComments.astroIf topicId is supplied, every layer must preserve it and the browser embed
configuration must use { topicId }. Regression tests must cover this path.
Shipped browser declaration contract:
type DiscourseEmbedConfig = | { topicId: number; discourseEmbedUrl?: never } | { discourseEmbedUrl: string; topicId?: never };
// Both alternatives may also include:// fullApp?: boolean// embedHeight?: stringDo not model topicId and discourseEmbedUrl as simultaneously required or
freely co-present; they represent alternative ownership/linking paths.
Current comments-boundary credit behavior and configuration:
comments_credit: enabled_by_default: true operator_disable_supported: true prefix: Connected by label: DiscussionBridge href: https://discussionbridge.dev/ href_protocols: [http, https] escaped_plain_text: [prefix, label] independent_of_discourse_powered_by: true placement: centered_after_complete_discussion_surface full_interactive_placement: outside_cross_origin_iframe visually_secondary: true accessible: true reduced_motion: true supported_modes: [simple, full, fullInteractive] hard_coded_in_site_content: false stable_classes: - discussion-bridge-credit - discussion-bridge-credit__prefix - discussion-bridge-credit__brand stable_data_hooks: - data-discussion-bridge-credit10. Cloudflare Pages / Domain Verification
Section titled “10. Cloudflare Pages / Domain Verification”CDN-backed Discourse compatibility evidence
Section titled “CDN-backed Discourse compatibility evidence”verified_at: 2026-07-22forum: https://forum.repealobbba.orgforum_edge: Cloudflare_CDNstatus: PASS_for_exercised_production_workflowstested: - check_discourse_and_API_reads - Discourse_topic_imports_to_Astro - target_topic_reconciliation - protected_source_topic_links - fullInteractive_comments - signed_in_reply_behavior - five_live_source_disclosures - source_and_cross_target_no_writeback - canonical_Astro_production_pagesclaim_limit: no_guarantee_for_every_CDN_WAF_cache_configurationpreserve_through_CDN: - Discourse_API_paths - JSON_endpoints - embed_and_full_app_routes - authentication_and_cookies - websocket_behaviordiagnostic_rule: compare_edge_and_direct_origin_then_investigate_cache_WAFDo not record private Cloudflare account labels, rule identifiers, or access values. If edge and origin results differ, capture sanitized path/status/cache evidence and route the CDN/WAF configuration issue to Ops.
Cloudflare-specific values are site inputs, not package constants. Record:
repository: canonical repository URLproduction_branch: mainroot_directory: consuming Astro project pathbuild_command: npm run buildoutput_directory: site-specific Astro output, commonly distcustom_domain: exact public hostnameastro_site: exact public URLdiscussion_bridge_site_url: exact public URLdiscourse_embed_host: exact hostnameaccount_id: explicit deployment account identifier in approved site configworker_name: exact Worker name when using Workersworker_version: deployment evidenceworkers_dev_endpoint: deployment verification endpointWhen more than one Cloudflare account is available, pin the intended
account_id in the approved deployment configuration so CLI/CI selection is
deterministic. Manuals and support bundles should describe the placement without
copying private account labels or login email addresses.
Verification:
- Pages deployment corresponds to the intended commit and canonical source.
- Custom domain resolves and HTTPS is valid.
- Astro
site, DiscussionBridgesiteUrl, CLISITE_URL, and the public hostname agree. - Discourse allows that exact embed hostname.
- A lane page and its companion topic resolve in both directions.
- The selected comments mode works on desktop and mobile.
- Cache bypass or narrowly scoped purge is tested before declaring stale output a failed sync/deploy.
- The Worker endpoint and canonical domain serve the intended candidate.
- Generated HTML contains the expected package/topic signature and does not contain the retired renderer signature.
Before deployment commits, inspect the consuming site’s worktree. Preserve and report unrelated pre-existing changes; do not absorb them into deployment-only commits.
Build the exact tracked candidate from a clean checkout or detached worktree before release. A dirty local deletion can hide a stale tracked page or asset reference and make the working-tree build pass when the committed candidate fails. Isolate the correction in its own reviewed commit, rebuild that exact commit, and leave unrelated unstaged changes and untracked artifacts untouched.
11. Known Failures And Recovery
Section titled “11. Known Failures And Recovery”| Failure | Detection | Recovery |
|---|---|---|
| Missing credentials | CLI missing-configuration message | Set protected env vars; rerun dry run. |
Site metadata 403 |
check-discourse unavailable/warning |
Use diagnostics key or explicit preflight limits. |
| Title/body/tag validation | Local preflight failure | Correct content/settings; rerun dry run. |
| Embed URL already taken | Publish error or reconciliation output | Prove ownership, resolve with diagnostics, then link/retry. |
Page URL has no embed owner but topicId is explicit |
Embed-info 404 or exact search has no result |
Validate the explicit topic and generated { topicId }; do not auto-relink. |
| Wrong category/route | --details or post-write verification |
Stop writes; correct lane; assess/relink affected topic explicitly. |
| Active target mismatch | skipped with target reason |
Use the matching --target; do not remove labels casually. |
discussionSync is false |
guarded page skipped | Expected for display/import/Discourse-owned pages; remove only on approved promotion. |
| Topic deleted | topic read failure | Prefer Discourse restore; otherwise verify and commit an explicit relink/replacement. Never auto-recreate or match by similar title. |
| First post deleted | missing-first-post failure | Restore with Discourse controls; if identity cannot remain, use the same reviewed topic-replacement procedure. |
| Discourse offline | clear network/API failure | Preserve Astro shell; retry after service recovery. |
| Stale CDN output | source/topic correct but public view stale | Verify commit/topic, bypass cache, then purge relevant cache only. |
CLI/build output is authoritative. Failure-notification PMs are best effort and must not be treated as the only failure record.
Recovery sequence invariant:
recovery: preserve_source_first: true record_old_binding: [topic_id, topic_url, target_name] diagnose: [check_discourse_page_url, sync_existing_dry_run_details] preferred_action: restore_existing_discourse_identity replacement_requires: - explicit_operator_decision - verified_topic_ownership_category_permissions - atomic_topic_id_and_url_source_change - selected_target_binding_update_when_present recreate_requires: - committed_removal_of_stale_binding - prior_binding_retained_in_git_history - publish_new_dry_run_details - stale_plugin_mapping_disposition_when_applicable forbidden: [automatic_guess, title_similarity_match, retry_successful_targets]12. Standard Verification Loop
Section titled “12. Standard Verification Loop”1. Confirm intended package build/version.2. Confirm lane inputs and source modes.3. Run check-discourse.4. Run intended operation with --dry-run --details.5. Review every page URL, target, topic ID, category, tag, and reason.6. Run live command without changing other arguments.7. Verify Discourse topic, first post, metadata, tags, and listing state.8. Verify Astro source/frontmatter and local build.9. Verify deployed URL, comments mode, and cache state.10. Sanitize logs before sharing; update manuals with newly confirmed facts.13. Multi-Target Frontmatter And Execution
Section titled “13. Multi-Target Frontmatter And Execution”The frontmatter values are YAML scalars. CSV fields preserve target order; the binding map is serialized JSON:
discussionSourceMode: discourse-importeddiscussionSync: falsediscussionTarget: repeal-obbbadiscussionSourceTarget: repeal-obbbadiscussionTargets: repeal-obbba,citizen-activistdiscussionPublishTargets: citizen-activistdiscussionPrimaryTarget: repeal-obbbadiscussionTargetBindings: '{"repeal-obbba":{"topicId":434,"topicUrl":"https://forum.repealobbba.org/t/434","status":"synced"},"citizen-activist":{"status":"failed","lastError":"sanitized target error","lastAttemptedAt":"2026-07-22T00:00:00.000Z"}}'Operate one target per CLI invocation:
npx astro-discussion-bridge publish-and-sync src/content/docs --target citizen-activist --dry-runnpx astro-discussion-bridge publish-and-sync src/content/docs --target citizen-activistdiscussionSync: false does not authorize source writeback. The named source
remains protected for discourse-imported and discourse-managed; only a target
listed in discussionPublishTargets is writable. New targeted imports set both
legacy discussionTarget and discussionSourceTarget. A legacy imported page
without the latter protects its legacy discussionTarget.
Run ordered publishOnBuild.lanes sequentially when build-time publishing is
intended. Each lane needs targetName and may override discourseUrl,
apiKey/apiUsername, or named apiKeyEnv/apiUsernameEnv. Do not put secret
values in frontmatter, manuals, or committed configuration.
On failure, inspect only the active target’s binding. Preserve other successful
bindings and retry with the failed --target. A stored error is whitespace-
normalized, truncated, and paired with lastAttemptedAt. A reconciled 422
embed/title collision records the discovered owning topic in the active binding
and clears its failure state. Invalid binding JSON or shape must fail before
network access.
14. Source-Provenance Contract
Section titled “14. Source-Provenance Contract”implementation: commit: a9d2097 review: Code_Boss_PASS tests: 68_of_68_PASS package_dry_run_exports: - dist/source.* - DiscussionSource.astro - package_root_helpers_and_types - astro-discussion-bridge/sourcepublic_api: component: astro-discussion-bridge/DiscussionSource.astro helper: resolveDiscussionSourceNotice types: [DiscussionSourceMode, DiscussionSourceNotice]rendering: placement: near_article_start separate_from: [comments_boundary, Discussion_Bridge_credit] aria_label: Content source prefix: "Source:" default_source_label: Discourse modes: discourse-imported: This page originated in {sourceLabel} and was imported here for publication. discourse-managed: This page is managed in {sourceLabel} and published here for easier reading. astro-managed: no_notice unknown: no_noticesource_url_precedence: - explicit_sourceUrl_prop - discussionImportedFrom - protected_discussionSourceTarget_binding - legacy_discussionTarget_binding_fallback - legacy_discourseTopicUrlaccepted_link_protocols: [http, https]unsafe_or_malformed_candidates: skipno_safe_url: render_notice_without_linkmulti_target_rule: provenance_follows_protected_source_not_publication_targetcustom_props: [sourceLabel, message, linkLabel, class, mode, sourceUrl, targetBindings, frontmatter]site_wiring: plain_Astro: canonical_BlogPost_layout Starlight: MarkdownContent_overrideOBBBA: adoption_status: complete adoption_commit: aa7846d artifact: vendor/astro-discussion-bridge-0.1.0-alpha-a9d2097-f3fbb73e.tgz artifact_sha256: F3FBB73E95D52B5799FBEBE5221298040FD32292EDA8BD76C257C0C19E4267B2 Code_Boss_adoption_review: PASS clean_detached_npm_ci_build: PASS publishOnBuild: false Discourse_writes: none worker_version: 005b9ff2-c880-43e4-b759-31ec2d02bed5 live_routes_verified: 5 per_route: Content_source_asides: 1 source_links: 1 source_forum: forum.repealobbba.org source_label: Repeal OBBBA Forum wording: exact_imported_default_with_custom_label discussion_boundary_preserved: true citizen_activist_topology_gate: separate_and_open15. Alpha Release And Support Inputs
Section titled “15. Alpha Release And Support Inputs”release_scope_doctrine: alpha: nearly_feature_complete_for_declared_product_promise scope_model: cumulative source_of_truth: existing_dashboard_and_build_launch_checklists new_gates_displace_existing_gates: false removal_authority: explicit_Phil_direction beta_primary_work: - usability - compatibility - reliability - performance - packaging - documentation - installation - recovery - support - presentation beta_missing_capability_from_user_evidence: allowed planned_major_pillar_deferral_to_beta: prohibited_by_default long_term_and_layer_3_outside_declared_promise: latertiers: tier_1: transport: Discourse_API plugin_required: false role: free_self_serve_floor optional_discourse_plugin: alpha_vertical_slice_status: installed_and_accepted_on_stable_preproduction_public_release_pending product_repo: separate_from_Astro_package_per_Boss_routing license: GPL_2_0_or_later installability: supported_stock_current_Discourse accepted_preproduction_Discourse_commit: 36698aae084678151dffa875d49c8d59216d2733 accepted_preproduction_plugin_commit: 50c4a92359f672a00b2242e99819a70813ebea19 removal_and_rollback_docs: required CAN_normal_topic_baseline: official_Discourse_Mermaid_theme_component logical_workspace_path: DiscussionBridge/plugins/discourse-discussion-bridge local_development_root: C:\CodeProjects\Products\DiscussionBridge\plugins\discourse-discussion-bridge current_installation_state: host: dev-forum.discussionbridge.dev role: stable_preproduction topology: official_split_data_plus_web_only installed: true enabled: true endpoint_at_rest: disabled core_zero_touch: disabled comments_only_fullInteractive: enabled accepted_on: 2026-08-22 production_released: false core_authority: [authentication, users, topics, posts, permissions, categories, tags, moderation, composer, replies, likes, quotes, edits, notifications, normal_topic_presentation] first_boundary: - durable_contract - default_disabled_plugin - authenticated_create_or_resolve_interface - configured_non_system_service_identity - canonical_connection_plus_absolute_source_URL_identity - database_unique_mapping_and_audit_interfaces - requested_vs_effective_policy - default_unlisted - fail_closed_no_silent_Core_fallback - forum_authoritative_actor_category_and_tags - durable_reservation_and_idempotent_mapping - controlled_unlisted_topic_creation - durable_audit - full_plugin_RSpec_contracts next_boundary: kind: human_admin_installs_of_exact_publicly_published_Alpha_tag_and_SHA_from_public_instructions required_topologies: - { host: sandbox-forum.discussionbridge.dev, topology: standard_single_container_app } - { host: dev-forum.discussionbridge.dev, topology: official_split_data_plus_web_only } separate_acceptance_record_per_host_and_topology: true forum_repealobbba_org: excluded_from_current_two_proofs_later_separate_OBBBA_authorization_and_recovery_gate fullInteractive_contract: accepted_preproduction_state: PASS_installed_migrated_configured_comments_only_ordinary_topic_isolation_admin_operations_and_rollback early_local_evidence_2026_08_02: Discourse_commit: 6b2f4579ba6802a7c556459e596c3150b67403aa non_browser_verification: { rspec: 38_of_38, rubocop: 25_of_25 } focused_authorization_verification: 7_of_7 browser_verification: 4_of_4_empty_replied_actions_ordinary_long_topic_and_reserved_marker_rejection_PASS local_development_runtime: PASS_empty_replied_actions_ordinary_topic_option_rollback_and_reserved_marker_rejection status: historical_qualification_not_current_installation_identity normal_topic_post_1: unchanged embedded_post_1_layout_height: zero preserve: [zero_reply_native_state, replies, login, composer, reply, like, quote, edit, moderation, notifications] prohibited: [host_height_cap_as_fix, unscoped_theme_CSS, post_1_delete, post_1_rewrite, ordinary_topic_regression] security: adapter_values: requests_not_authority forum_operator_policy: final credentials_in_docs_logs_or_audit: prohibited endpoint_default: disabled plugin_default: disabled core_zero_touch_compatibility_default: disabled ordinary_topic_regression: prohibited live_proof: forum.citizenactivist.network_full_app_embed not_current_boundary: [admin_UI, existing_topic_migration, arbitrary_impersonation, PM_automation, general_many_to_many, production_installation] tier_1_dependency: false controlling_contract: docs/evidence/DISCUSSIONBRIDGE_PLUGIN_V0_1_CONTRACT_2026-08-02.mdmulti_target_implementation: commit: 60e41e1 review: Code_Boss_PASS tests: 62_of_62_PASS package_check: PASS package_dry_run: PASS frontmatter: discussionTargets: ordered_CSV_target_names discussionPublishTargets: explicit_writable_subset_CSV discussionSourceTarget: explicit_protected_source discussionTargetBindings: JSON_scalar_map_by_target discussionPrimaryTarget: required_when_multiple_linked cli: one_explicit_--target_per_run publish_on_build: ordered_sequential_lanes recovery: retain_success_retry_failed_target_idempotently malformed_binding_state: fail_before_network public_export: astro-discussion-bridge/targetsconnection_job_product_doctrine: public_lead: Every connection has a job explicit_human_purpose: required_product_behavior_not_yet_implemented visible_label_and_CTA_match_purpose: required independent_replies_silently_merged: prohibited primary_vs_additional: explicit later_scope: [relay, promotion, summary] configuration_design_status: pending_review_not_final_not_implemented candidate_fields: [role_or_purpose, audience, callToAction, description, visibility_context, direction_source_ownership, presentation] candidate_roles: [primary-community, public-community, chapter, internal-review, expert-feedback, source-wiki, syndication]bidirectional_CAN_contract: directions: - Astro_managed_page_to_CAN_companion_topic - CAN_topic_to_Discourse_managed_or_imported_Astro_page separate_page_topic_pairs: required explicit_source_ownership: required same_item_writable_both_directions: prohibited loop_prevention: single_writer_per_itemchapter_national_future_design: status: proposed_not_implemented public_frame: Local ownership. National reach. topology: governed_hub_and_spoke_federation supported_directions_to_design: - local_topic_to_mapped_national_category - national_guidance_to_selected_local_categories required_fields: - source_forum_and_topic - source_chapter_identity - parent_child_relationship - mapped_source_and_destination_categories - required_tags_region_chapter_metadata - automatic_or_moderator_approved_promotion - public_private_eligibility - source_attribution_and_return_link - target_specific_title_CTA_description - one_way_first_post_sync_direction - independent_reply_streams - target_specific_failure_retry_idempotency - moderation_ownership_at_both_levels optional_later: post_as_chapter_identity silent_merge_or_ambiguous_writeback: prohibited current_full_forum_to_forum_orchestration_claim: falsealpha_topology_proof: status: bounded_OBBBA_to_Citizen_Activist_live_proof_complete verified_at: 2026-07-22 adoption_commit: 36df91c98a35251edd6ddd657cca42ddf0acdafa adoption_files: - src/components/MarkdownContent.astro - src/content.config.ts - src/content/docs/title i/10101-impact.mdx Code_Boss_review: PASS clean_detached_build: PASS worker_version: 632db326-bc0d-4047-b74b-7e74d3588dbf canonical_page: https://onebigbeautifulbill.us/title-i/10101-impact/ canonical_page_HTTP: 200 production_obbba_target: https://forum.repealobbba.org citizen_activist_target: canonical: https://forum.citizenactivist.network public_description: A community of activists hostname_policy: literal_forum_prefix_identity_in_copy cloudflare_account_ownership: unresolved_Ops_decision bounded_demo_target: https://forum.discussionbridge.dev exact_matrix: - { from: same_selected_onebigbeautifulbill.us_page, to: https://forum.repealobbba.org } - { from: same_selected_onebigbeautifulbill.us_page, to: https://forum.citizenactivist.network } - { from: bounded_demo_credit_pages, to: https://forum.discussionbridge.dev } - { from: multiple_Astro_public_sites, to: https://forum.repealobbba.org } proof_meaning: one_page_multiple_forums: first_two_edges multiple_sites_one_forum: fourth_edge contract: source_target_distinct_from_publication_discussion_targets: required target_list: explicit_ordered binding_fields: [topic_id, topic_url, source_hash, last_synced_at, status, last_error, last_attempted_at] presentation_policy: explicit_primary_plus_accessible_additional_links source_no_writeback: preserve_for_discourse_imported_and_discourse_managed comments_presentation: explicit_primary_plus_additional_linked_or_rendered silent_primary_selection: prohibited write_semantics: recoverable_partial_success successful_bindings_on_other_target_failure: retain retry: target_specific_idempotent_no_duplicate_topics target_specific_surfaces: [diagnostics, dry_run, CLI_output, manuals, live_proof] required_gate: - { target_diagnostics: PASS } - { target_specific_dry_run: PASS } - { publish_and_independent_bindings: PASS } - { unchanged_idempotent_retry: PASS } - { clean_build_deploy_live_binding: PASS } - { protected_source_no_writeback: PASS } exercised_binding: source_target: repeal-obbba source_topic_id: 434 source_mode: discourse-imported discussionSync: false primary_display: fullInteractive primary_fullApp: true publication_target: citizen-activist publication_topic_id: 9 publication_topic_url: https://forum.citizenactivist.network/t/sec-10101-re-evaluation-of-thrifty-food-plan-impact/9 publication_category: { id: 5, name: One Big Beautiful Bill, slug: one-big-beautiful-bill, public: true } publication_tags: [discussionbridge, obbba, impact, title-i] additional_presentation: one_accessible_link publication_interaction: posts_count: 2 highest_post_number: 2 last_poster: discourseadmin Astro_primary_topic_remained: 434 reachability: accessible_Additional_discussions_link evidence_scope: interaction_and_presentation_only source_post_count: 12 source_first_post_updated_at: 2026-07-01T01:35:12Z lane: docsDir: src/content/docs/title i route_base: title-i active_target: citizen-activist broad_root_dry_run: rejected_before_write_due_to_wrong_index_and_route dependency_audit: total: 10 low: 1 moderate: 1 high: 8 resolved: false action: dependency_review_no_automatic_audit_fix known_notices: [Starlight_docs_to_404, chunk_size, punycode_deprecation] temporary_detached_worktree: removed_after_deployment protected_credentials: records_exist: true public_paths_or_values: prohibited legacy_record_format_cleanup: protected_vault_task claim: bounded_same_page_OBBBA_to_Citizen_Activist_topology later_scope: general_many_to_many_administrationrelease_channel: Astro_package: alpha: GitHub_prerelease_plus_exact_attached_tarball immutable_identity: exact_tag_source_commit_asset_filename_bytes_sha256_inventory public_install: download_then_SHA256_verify_then_npm_install_--save-exact_same_local_tarball post_install_proof: lockfile_resolution_names_verified_asset_and_integrity_matches_release_record source_checkout_or_moving_branch: prohibited_as_release_identity replace_or_delete_asset_in_place: prohibited corrected_release: new_prerelease_tag_and_asset npm_registry_publication: later_separately_authorized_gate Discourse_plugin: npm_distribution_decision_applies: false channel: exact_GitHub_prerelease_tag_and_commit required_for: plugin_backed_fullInteractive_and_forum_control_plane not_required_for: [simple, full] human_install_acceptance: required_before_product_release_acceptance_closes: true actor: human_Discourse_administrator input: public_release_instructions_only required_proofs: - { host: sandbox-forum.discussionbridge.dev, topology: standard_single_container, action: containers/app.yml_then_rebuild_app } - { host: dev-forum.discussionbridge.dev, topology: official_split_data_plus_web_only, action: containers/web_only.yml_then_rebuild_web_only_only } separate_acceptance_record_per_host_and_topology: true forum_repealobbba_org: excluded_from_current_two_proofs_later_separate_OBBBA_authorization_and_recovery_gate initial_settings: all_safe_defaults_off proof: [backup_identity, installed_SHA, migrations, ordinary_forum_health, enable_configure, disable_rollback_removal] failure: new_corrected_prerelease_never_rewrite_existing_identityalpha_feature_lock: status: locked cumulative_scope_source: docs/BUILD_LAUNCH_CHECKLISTS.md allowed_new_work: - close_existing_promise_or_gate - fix_exercised_behavior - explicitly_approved_scope_change software_tracks: astro_package: free_open_source discussionbridge_for_discourse_plugin: free_open_source public_docs_and_community_support: free_open_source paid_value: - implementation_help - handholding - managed_hosting_and_operations - customization - support - consulting third_party_infrastructure: operator_paiddiscussionbridge_dev_dogfood: reviewed_import_support: commit: 1731547 code_boss: PASS tests: 72/72 source_modes: [discourse-imported, discourse-managed] default: discourse-imported rejected: [astro-managed] manifest_field: sourceMode discussionSync: false artifact: astro-discussion-bridge-0.1.0-alpha-1731547-7d8951d1.tgz sha256: 7d8951d15f4b0a4a4f14e238665bc41c28255c6f2cdcb1979105926ba6f4affb node_engine: ">=22.12.0" guide_dry_run: source_forum: https://forum.discussionbridge.dev source_topic_id: 36 destination_route: /guides/how-to-choose-a-discussion-bridge-source-mode/ status: passed live_gate: status: complete_bounded_two_direction_proof apex_commit: d68ffc4 code_boss: PASS clean_detached_build_routes: 5 deployed_at: 2026-07-23T09:00:47-07:00 apex_http: 200 pages_hostname: https://discussionbridge-dev.pages.dev pages_hostname_redirect: 301_to_apex blog: route: /blog/every-connection-has-a-job/ http: 200 topic_id: 37 category_id: 5 wiki: false tags: [discussionbridge, community, product] guide: route: /guides/how-to-choose-a-discussion-bridge-source-mode/ http: 200 topic_id: 36 category_id: 6 wiki: true tags: [discussionbridge, source-mode, guide] source_disclosure: verified primary_comments: fullInteractive sync_existing_dry_run: skipped_discourse_managed_no_writeback npm_audit: { high: 1, automatic_fix: prohibited_not_run } known_warning: Mermaid_chunk_over_500k topic_36_editor_ownership_acceptance: status: open required: - change_first_post_owner_from_discourseadmin_to_selected_bridge_forum_editor - edit_wiki_as_selected_editor - import_refresh_discourse_managed_guide_with_overwrite - verify_content_and_source_ownership - build_deploy_and_verify_live_markers - prove_no_Astro_writebacksource_author_provenance: import_fields: - discussionSourceAuthorUsername - discussionSourceAuthorName overwrite_refresh: update_from_current_Discourse_first_post_author preserved_on_refresh: - discussionSourceMode - discussionSync_false - discourseTopicId rendered_notice: "Source author: Display Name (@username)" profile_link: same_forum_base_preserving_safe_/u/username subfolder_example: topic: https://example.com/forum/t/example/123 profile: https://example.com/forum/u/editorbridgeforum unsafe_username_behavior: omit_author_metadata_and_linkrequest_actor_regressions: - real_CLI_execution_with_--post-as - dry-run_actor_outputpackage_suite: 79/79category_contract: generated_source_field: discussionSourceCategoryId comparison_source: existing_opening_YAML_frontmatter_only parser_safety: [LF, CRLF, BOM, ignore_body_and_code_block_lookalikes] change_reason: "source category changed: OLD -> NEW; Astro route/navigation unchanged" evaluated_during: - existing_file_skip - dry_run_overwrite - live_overwrite overwrite_effect: WHEREFROM: refresh_source_category_metadata WHERETO: preserve_output_file_public_route_and_Astro_navigation_lane manifest_contract: - direct_and_strict_atomic_flows - preserve_reason_in_dry_run_and_live_overwrite - preserve_stable_output_path - preserve_source_mode - preserve_discussionSync_false - preserve_topic_ID_and_source_protections CLI: print_change_reason example_schemas: [Astro, Starlight] astro_managed: configured_category: authoritative_sync_corrects_drift no_configured_category: preserve_manual_Discourse_category discourse_managed_or_imported_source: category_writeback: prohibited multi_target: target_categories: independent evidence_record: docs/evidence/DISCUSSIONBRIDGE_DEV_TWO_WAY_DOGFOOD_2026-07-23.md count_boundary: apex_generated_public_routes: 5 docs_synced_sources: 20 docs_generated_html_pages: 21 direction_1: source: discussionbridge.dev_Astro_managed_blog destination: forum.discussionbridge.dev_public_companion_topic writer: Astro direction_2: source: forum.discussionbridge.dev_community_wiki destination: discussionbridge.dev_durable_public_guide source_mode: discourse-managed discussionSync: false source_provenance: required refresh: deterministic_reviewed_source destination_contract: explicit_public_route_and_Astro_navigation_lane primary_discussion: source_forum_topic writer: Discourse_wiki reply_streams: independent_never_merged public_outcome: The site starts conversations. The community develops durable knowledge. The site publishes what the community learns.support: formal_work: GitHub Issues setup_and_field_reports: Discourse Alpha Support category email_intake: address: alphasupport@discussionbridge.dev destination: Discourse status: planned_pending_verified_route private_help: paid implementation/migrationattribution_and_licensing: implementation: script: scripts/check-attribution.mjs inventory: docs/THIRD_PARTY_PROVENANCE.json reviewed_override_evidence: docs/third-party-licenses/khroma-2.1.0-MIT.txt fresh_checkout_sync: executable: process.execPath shell: false regression: passed full_package_gate: command: npm run check:attribution included_in_package_suite: exact_candidate_total_required status: PASS checks: - root_package_MIT_parity_and_holder - package_license_metadata - production_lock_dependency_license_allowlist_or_reviewed_override - npm_pack_required_contents - README_non_affiliation_and_rendered_links - tracked_media_provenance - protected_path_scan docs_scope_gate: command: npm run check:attribution --docs-scope required_status: PASS (docs scope) npm_package_contents: SKIPPED (requires built release candidate) docs_result: exact_candidate_synced_source_and_HTML_counts_required reporting_invariant: full_package_gate_and_docs_scope_gate_are_not_interchangeable manual_boss: required_result: "Attribution and Licensing: PASS / FAIL / N/A" reviewed_paths: required sanitized_exact_release_record: required current_status: PASS exact_candidate: b09dbce commit_chain: [7127eb1, 462b3ae, b09dbce] remaining_findings: 0 record: docs/evidence/ATTRIBUTION_LICENSING_REVIEW_B09DBCE_2026-07-23.mdrelease_prerequisites: - exact GitHub prerelease tag and reviewed source commit selected - exact attached tarball filename, bytes, SHA-256, and file inventory recorded - clean install of that same immutable tarball in supported Astro and Starlight consumers - exports, Astro components, CLI bin/help, import/sync, comments, source disclosure, and multi-target helpers verified - LICENSE, README, repository, bugs, and homepage metadata verified - credentials, fixtures, local paths, and unintended files absent - Code Boss pass/fail result recorded against the exact release candidate - blocking code-review edits complete and re-reviewed where required - Bridge Boss technical verification complete - Manual Boss quality review complete - Human and Machine Manuals ready for the exact release - Product Boss documentation sign-off recorded - Product Boss release approval recorded - live Alpha Support category verified - email route verified - README, docs, metadata, demos, and release notes agree - GitHub prerelease tag, source commit, release asset, and recorded hash agree - public install from the hash-verified local release asset and matching lockfile integrity verified - human Discourse administration installs the exact published plugin candidate from public instructions on sandbox-forum.discussionbridge.dev as standard single-container app and on dev-forum.discussionbridge.dev as official split data plus web_only - separate human plugin acceptance for each named host/topology proves rollback identity, installed SHA, migrations, safe-default startup, ordinary forum health, enable/configure, and disable/rollback/removal - v0.1.0-alpha.5 is immutable rejected_do_not_install evidence because its human gate found an unreachable synthetic embedded logout trigger and paired adapter clipping - corrected auth acceptance uses signed_out_initial_state, Core_popup_signin, new_user_signup, and separately_induced_Core_owned_session_loss_then_known_Astro_page_reload; Open_discussion_is_not_logout - corrected frame acceptance proves topic_progress, lower_frame_scroll, composer_open_close, and credit_below_complete_iframe without a competing CSS viewport ceiling - forum.repealobbba.org is excluded from these two current proofs and remains a later separately authorized independent real-world gate - upgrade, downgrade, rollback, supersession, and recovery procedure verified - bad assets are warned and superseded by a new tag, never replaced or deleted in place - automatic npm audit fix prohibited - package tests and demo build pass - dry-run CLI checks pass - at least one controlled live smoke sync passesSupport bundles may include package/framework versions, sanitized commands and output, lane name, public URLs, category ID, tags, key type, and dry-run result. They must not include key values, credentials, private account data, or production secrets.
16. Navigation/Taxonomy Manifest
Section titled “16. Navigation/Taxonomy Manifest”Status: official-source navigation contract implemented and package tests 113/113 PASS; exact OBBBA Text candidate reviewed, deployment not authorized.
navigation_taxonomy_contract: product_principle: complete_structure_progressive_presentation authority_by_lane: official_source_lane: authority: authoritative_external_official_source defines: [scope, hierarchy, order, labels, local_routes] forum_join: after_official_inventory_only forum_authored_lane: inputs: [categories, tag_groups, index_topics, content_topic_tags] tag_group_membership_order_canonical: false node_contract: local_or_group_node: topic_required: false must_have: local_URL_or_children forum_linked_node: must_have_together: [topicId, sourceUrl] partial_binding: fail_closed synthetic_topic_for_navigation: prohibited generated_artifact: kind: canonical_navigation_taxonomy_manifest consumers: [Starlight_adapter, plain_Astro_adapter] presentation: global: [content_lenses, Titles] expanded: [current_lens, current_Title, active_descendant_branch] collapsed_user_expandable: other_branches complete_browse_surface: index_pages supporting_navigation: [breadcrumbs, authored_previous_next, search] avoid: - hundreds_of_inactive_Title_VII_links_visible_on_every_route - unnecessary_inactive_deep_branch_DOM candidate_modes_not_config_contract: [progressive, complete, compact] responsive_accessibility: viewports: [desktop, laptop, tablet, mobile] scale_case: Title_VII drawer_opens_active_branch: required keyboard_and_screen_reader: required preserve_expansion_where_appropriate: required proposed_routes: - /obbba-text/title-i/... - /impact/title-i/... redirects_required_at_design_stage: falseimplementation_evidence: package_tests: { status: PASS, count: 113 } OBBBA_Text_candidate: source: GovInfo_PLAW-119publ21 official_sections: 310 local_routes: 310 optional_complete_forum_bindings: 307 official_without_forum_binding: [1, 20009, 71119] section_70310: absent forum_inventory_309_used_as_official_cardinality: false sitemap: { URLs: 331, unique: 331, missing_official_navigation_URLs: 0 } encoded_space_routes: 0 publicationAuthorized: false deploymentAuthorized: false presentation: component: DiscussionNavigation adapters: [Starlight_sidebar, plain_Astro] hierarchy_without_synthetic_topics: PASS Impact_preserved_local_routes: 15 open: - exact_deployment_and_live_acceptance - Law_as_AmendedDo not derive an official-source lane from forum categories, tag groups, topics, bodies, indexes, or counts. Do not manufacture tags or topics for a local hierarchy. Forum-authored lanes may retain their own reviewed discovery rules, but every claimed forum connection must be complete and optional joins must follow authoritative scope establishment.
17. Official-Source Enrichment And Relations
Section titled “17. Official-Source Enrichment And Relations”Status: package implemented at e775af3 plus bc8acb5 and db1c57a;
bounded Section 10101 refreshed live at OBBBA 5a455f1; final zero-write
OBBBA Text batch comparison completed 2026-07-24.
official_source_enrichment: content_source: role: protected_Discourse_source_topic wiki_status: optional_metadata ownership_and_no_writeback_basis: source_mode_contract official_text: authority: authoritative_public_record identity: [document_or_law, sectionId, label] locator: [structural_identifier, citation, official_page_range] URLs: [overview, structured_text, text_fallback, visual_record] evidence: [checkedAt, sourceHash, comparisonResult] OBBBA: document: Public Law 119-21 overview: Congress.gov_text_page structured_text: USLM_XML page_marker_fallback: official_TXT visual_verification: official_PDF citation_rule: Statutes_at_Large_pages_not_PDF_file_pages match_policy: missing_or_duplicate_or_ambiguous: fail_closed_or_review silent_community_text_rewrite: prohibited comparison_results: [exact, presentation-only, substantive-difference, unresolved] presentation_only_may_ignore: - Markdown_links - whitespace_and_line_wrap - typographic_punctuation - official_page_furniture - official_side_notes presentation_only_must_preserve: [substantive_wording, numbering] capitalization_only: normalized_case: preserved classification: substantive-difference path: review_or_explicit_per_entry_override reason: may_identify_legal_defined_terms_or_identifiers batch_mode: { report_all_result_counts: true, content_writes: 0 }bounded_field_evidence: Discourse: { topic_id: 34, post_id: 40 } section: 10101 USLM_id: /us/pl/119/21/tI/stA/s10101 normalized: { tokens_each: 608, characters_each: 3148, substantive_differences: 0 } citation: Public Law 119-21, Section 10101, 139 Stat. 80-81 scope: representative_single_section_not_batch_claimrelationship_graph: aggregate_cardinality: many_to_many stable_key: sectionId lenses: [OBBBA Text, Law as Amended, Impact, Stories] reciprocal_links: generated directional_views: section_to_Stories: one_to_many Story_to_sections: one_to_many update_operation: regenerate_manifest_then_Astro_build body_reimport_required: false manual_per_page_links: prohibited adapters: [Starlight, plain_Astro] provenance_and_authority_separate_from_related_navigation: truelaw_as_amended_authority: reset_date: 2026-07-27 legacy_implementation: disposition: inert_lessons_learned_only repair_base: false salvage_authorized: false prohibited_inputs: - legacy_code_tests_schemas_fixtures - legacy_parsers_caches_generated_evidence - forum_derived_scope_or_cardinality - derivative_source_models clean_room: placement: OBBBA_specific_site_adapter_evidence portable_Core: false reusable_Astro_package: false admitted_legacy_imports: 0 admitted_legacy_artifacts: 0 salvaged_assets: 0 authority_order: - authoritative_official_source_discovery - preserve_raw_identity_retrieval_bytes_hashes - neutral_parse - reviewed_official_scope_and_legal_state - Astro_presentation - optional_forum_context_and_discussion forum_allowed_after_official_scope: - optional_verbatim_title - optional_tags_category_authored_index - optional_legislative_drafting_context - optional_topic_and_discussion_binding forum_prohibited: - legal_body_authority - official_scope - official_cardinality settled_invariants: section_20009: present_mandatory section_70310: phil_boss_settled_does_not_exist_no_targeted_search section_71119: official_source_first_binding forum_count_309: identity_discussion_inventory_only contradiction: BLOCKED_DOCTRINE_EVIDENCE_CONFLICT publication_authorized: false gate_2_authorized: false portable_adoption_authorized: falseimplementation_evidence: profile: us-public-law manifest_version: 2 URL_policy: HTTPS_congress_gov_or_www_through_final_redirect overwrite_policy: no_overwrite_skip_before: [raw_post_read, official_source_read] substantive_result: explicit_per_entry_override_only source_tags_field: discussionSourceTags_JSON_scalar component: DiscussionRelations relationship_manifest: virtual_rebuild_time package_tests: 107/107 npm_run_check: PASS npm_pack: files: 52 bytes: 86864 artifact: file: astro-discussion-bridge-0.1.0-alpha-db1c57a-17b3dba9.tgz SHA256: 17b3dba90891f8a5222389dd351bfb5904ab8c5a32e53dd86745233dda452eb4 core_Astro_build: { status: PASS, public_routes: 3 } importer_fixture: non_routed_scalar_frontmatter_validated open: - batch_comparison_review_and_approved_population_manifest - additional_OBBBA_Text_and_lenses - Law_as_Amended_adoption - broader_Title_VII_scale_and_accessibility_as_content_expands - dependency_vulnerability_reviewOBBBA_current_candidate: official_sections: 310 optional_complete_forum_bindings: 307 official_without_forum_binding: [1, 20009, 71119] section_70310: absent sitemap_routes: 331 Impact_preserved_local_routes: 15 publicationAuthorized: false deploymentAuthorized: false publishOnBuild: false Discourse_writes: 0public_429_policy: tag_group_reads: sequential retry_statuses: [429] max_retries: 3 Retry_After: [seconds_capped, date_capped, fallback_delay] rejected_body_cancel_bound_ms: 50 retry_403: falseThe public-accountability chain is official record → structured section → legal/practical analysis → human consequences → community scrutiny/correction. Do not claim implementation completion from the single-section comparison.
18. Verified Docs Page Metadata
Section titled “18. Verified Docs Page Metadata”docs_page_metadata: implementation_commit: 02206f7 ledger: docs/DOCS_PAGE_METADATA.json ledger_entry: [lastUpdated, SHA-256] membership: exact_synchronized_source_set date_meaning: canonical_source_last_verified_change prohibited_date_sources: [build_timestamp, deploy_timestamp, Git_history] normal_build: refreshes_dates: false fail_closed: [missing_entry, stale_extra_entry, byte_hash_mismatch] explicit_refresh: cwd: sites/docs command: npm run refresh-metadata unchanged_source: preserve_date changed_source: update_date_and_hash new_source: initialize_entry removed_source: remove_entry prebuild_order: - metadata_tests - sync_content - attribution_docs_scope rendered_contract: title_row: - "Last updated: verified source date" - "Applies to: DiscussionBridge Alpha" footer: - Last_updated_only - exact_canonical_GitHub_edit_link responsive: [desktop_1440_PASS, mobile_390_PASS] verification: metadata_tests: 2/2 docs_sources: 21 HTML_pages: 22 attribution_docs_scope: PASS semantic_review_replaced: falseRun refresh only after intentional canonical documentation edits. Commit the changed canonical docs and ledger together. Do not treat synchronized site content as the source of truth, and do not use metadata verification as a substitute for Manual Boss review.
19. Durable Update Rule
Section titled “19. Durable Update Rule”When implementation confirms or changes a command, field, scope, endpoint, failure, recovery path, or deployment invariant:
- update this machine manual;
- update the corresponding human instruction when operator behavior changes;
- update the focused guide or checklist;
- route implementation gaps to Bridge Boss and manual-quality review to Manual Boss.