Skip to content

About

hivecommons.dev — placeholder site (GitHub Pages)

Resources

Code of conduct

Contributing

Security policy

Stars

0 stars

Watchers

0 watching

Forks

Latest commit

 

History

161 Commits

Folders and files

Source for hivecommons.dev (GitHub Pages). Static site: index.html, style.css, and assets/ — no build step.

Custom domain is pinned via CNAME. llms.txt carries a short machine-readable summary for LLM crawlers (its integration and sponsor lists are gated against index.html by scripts/llms-txt.test.mjs), and sitemap.xml lists the canonical top-level pages (not every shortcut redirect) for robots.txt's Sitemap: entry — when adding a new top-level page, add it to sitemap.xml too.

.well-known/security.txt is the RFC 9116 security contact for the domain (it points at security@hivecommons.dev and the org SECURITY.md). Its Expires: field must be at most a year out, so bump it once a year. GitHub Pages builds the site with Jekyll, which drops dot-directories unless they are listed in _config.yml's include: — that is the only reason _config.yml exists; keep .well-known in it.

Shortcut redirects

Short paths like /docs, /code, /discord are meta-refresh redirect pages. All of them are generated by make-redirects.sh: edit the MAP at the top of the script, run ./make-redirects.sh, then commit the regenerated index.html files — don't hand-edit them, since a future run of the script will silently overwrite any hand edit.

scripts/check-redirects.sh enforces this: it regenerates the pages into a scratch directory and fails if any committed redirect page is missing from MAP, any MAP entry has no committed page, or a committed page differs from what the script emits.

Checks

The Link check workflow (.github/workflows/links.yml) runs its links, test and redirects jobs on every pull request and on every push to main, so commits pushed straight to main are checked too and main carries a same-named baseline to compare a red PR job against.

  • scripts/check-links.sh [--external-warn] — resolves every internal link/anchor and probes external URLs (CI runs it with --external-warn on PRs and pushes; the weekly scheduled run and manual dispatch hard-fail on broken external links). Besides every committed page and the make-redirects.sh map, it checks the URI fields of .well-known/security.txt (RFC 9116 Contact, Canonical, Policy, Acknowledgments, Hiring) and every https?:// URL in llms.txt, so a rotted security-contact link or machine-readable-summary link is reported too. It also checks og:image/og:url/twitter:image content= URLs and JSON-LD url/logo/codeRepository/sameAs/license values.
  • scripts/check-links.test.sh — fixture-based self-test of the link checker; runs offline (fake curl).
  • node --test scripts/story-dialog.test.mjs — runs the Share-your-story dialog script from stories/index.html against a stub DOM and checks the prefilled-issue URL, validation, 1500-char trim, and popup-blocked fallback. Zero dependencies.
  • node --test scripts/acmm-levels.test.mjs — runs the ACMM levels tablist script from index.html against a stub DOM with deterministic timers and checks tab activation, roving tabindex, arrow/Home/End keys, auto-rotation, and every pause condition (hover, focus, hidden tab, reduced motion, out of view). Zero dependencies.
  • node --test scripts/carousels.test.mjs — runs the hero carousel and projects carousel scripts from index.html against a stub DOM with deterministic timers and checks dot generation, slide/aria-current state, live-region announcements, keyboard/swipe/hash navigation, auto-rotate and every pause condition, hero height measurement (clones, resize debounce), and projects scroll-sync (debounced scroll, scrollend, IntersectionObserver). Zero dependencies.
  • node --test scripts/page-scripts.test.mjs — static gate over every committed HTML page: each inline <script> parses, each JSON-LD block is valid schema.org JSON, no external <script src> is introduced, every inline behaviour script (other than the one-line no-js toggle) is registered in HARNESSED_SCRIPTS with the harness test that extracts and runs it — so a new inline script cannot ship with only a syntax check — and sitemap.xml lists exactly the canonical top-level pages (redirect shortcuts excluded, new pages required). Zero dependencies.
  • node --test scripts/page-markup.test.mjs — static markup gate over every committed non-redirect HTML page: ids are unique, every ARIA idref (aria-controls, aria-labelledby, aria-describedby, …) and label for resolves to an id on the page, every <img> has alt, <html> declares lang, role="tab"/"tabpanel" carry their ARIA pair, and every [data-*] selector an inline script queries exists in the markup (so a dropped attribute cannot make a carousel silently no-op). Each rule has a fixture self-test. Zero dependencies.
  • node --test scripts/page-structure.test.mjs — static tree gate over every committed HTML page (redirect shortcuts and 404.html included). Browsers never reject malformed HTML, they repair it silently, so the gate parses each page the way the HTML tokenizer does (comments, raw-text <script>/<style>/<textarea>/<title> bodies, quoted attributes, the spec's optional end tags for <li>/<p>/<option>/table parts, foreign content for inline SVG) and fails on anything a browser would have to repair: a stray or mismatched end tag, an element never closed, </br> or a self-closing <div/>, a block element inside <p> (which leaves its </p> stray), an attribute repeated on one element (the second is dropped), a raw </> inside an attribute value (which truncates the tag every sibling gate tokenizes with [^>]*), <li>/<option>/<tr>/<figcaption>/… outside their required parent, interactive content nested inside <a>/<button>/<label>, non-metadata content in <head>, and a page without exactly one <html>, <head> and <body> (plus exactly one <main> on non-redirect pages). Each rule has a fixture self-test. Zero dependencies.
  • node --test scripts/style-contract.test.mjs — static gate over style.css (every local stylesheet the pages link) and the pages' inline <style> blocks: comments, strings, braces and parens balance and every declaration is name: value; every var(--x) without a fallback names a custom property defined somewhere (stylesheet, inline style=, or a script setProperty); every [data-*] selector in CSS matches an element on some page; every class an inline script adds/toggles is styled by a rule (or read back by the script); every custom property a script sets (--hero-h) is read by CSS; every local url() (self-hosted @font-face files, images) names a committed file whose magic bytes match its format() hint or extension; and every font file under assets/fonts/ is referenced by some url(). Each rule has a fixture self-test. Zero dependencies.
  • node --test scripts/no-js-controls.test.mjs — static gate over every committed non-redirect page's script-only controls: each <button type="button"> (the kind that does nothing until an inline script attaches a handler) must be unreachable without JavaScript — it or an ancestor carries hidden (the script reveals it), it sits inside a closed <dialog>, or a .no-js … { display: none; } rule in the page's stylesheets matches it or an ancestor — unless it is a role="tab" whose aria-controls panel is already visible without JavaScript. Submit/reset buttons have native form behaviour and are left alone. A new JavaScript-driven call to action can therefore not ship as a dead button for no-js visitors, the way [data-story-open] on /stories/ did (#216). Each rule has a fixture self-test. Zero dependencies.
  • node --test scripts/font-licenses.test.mjs — static gate over the licence files that must travel with the self-hosted fonts: every font family under assets/fonts/ (the file name up to the first -) has an OFL-<Family>.txt, Apache-2.0-<Family>.txt or UFL-<Family>.txt. Every licence still matches a shipped family and carries the markers for its type (SIL Open Font License 1.1, Apache License 2.0 or Ubuntu Font Licence 1.0); OFL files also open with a Copyright notice. The directory holds only fonts and these licence files. Preserve the upstream licence text and notices, including attribution in the same file. The gate checks markers, not the complete text or whether the licence applies to the font. Additional licence types need a LICENSE_TYPES entry and fixtures in the script. style-contract.test.mjs checks font bytes; this gate catches a deleted licence or a new family added without one. Each rule has a fixture self-test. Zero dependencies.
  • node --test scripts/page-images.test.mjs — static gate over every local image the pages embed (<img src>/srcset, icon and preload as="image" <link>s, og:image): each is a committed, non-empty file whose magic bytes match its extension (a PNG re-exported as SVG under the old .png name fails); every <img> with width/height declares the file's intrinsic aspect ratio (PNG IHDR, JPEG SOF, GIF header, SVG viewBox) and is not drawn larger than a raster's pixels; every <img> SVG has a root viewBox; and every image file under assets/ is referenced by some page or stylesheet url(). Each rule has a fixture self-test. Zero dependencies.
  • node --test scripts/page-meta.test.mjs — static gate over every page's <head> and the Markdown/llms.txt documents: each canonical page has exactly one <title>, a description, charset/viewport, a canonical that matches the path the page is served at, og:url equal to it, the full Open Graph + Twitter card set with og:*/twitter:* pairs in agreement, no duplicated meta, no noindex; og:image is a committed file whose PNG header matches any declared og:image:width/height; each redirect page is noindex with a canonical equal to its refresh target, carries viewport and a Content-Security-Policy with script-src 'none'; and every relative Markdown link and hivecommons.dev URL in README.md, runbooks/*.md and llms.txt resolves to a committed file. Each rule has a fixture self-test. Zero dependencies.
  • node --test scripts/page-404.test.mjs — static gate over the custom error page, which page-meta.test.mjs deliberately skips. GitHub Pages serves /404.html for every unknown path at any depth, so the page must live at the repository root and nowhere else, keep exactly one noindex robots meta, carry no canonical/og:*/twitter:* identity and no meta-refresh, use only root-absolute or external href/src (a relative style.css breaks under /some/deep/path), link back to /, resolve every root-absolute reference to a committed file, and keep body text that scripts/check-links.sh's SOFT_404_RE matches (so a misrouted URL serving the page with HTTP 200 is still flagged); no other page may match that regex. Each rule has a fixture self-test. Zero dependencies.
  • node --test scripts/story-cards.test.mjs — static gate over every <article class="story-card"> in stories/index.html, which are hand-copied per PR: the avatar src, its alt, the handle link href and its text all name the same GitHub handle; the avatar keeps loading="lazy", referrerpolicy="no-referrer", width/height and the onerror hide; exactly one <h3>; at least one <a class="inline-link"> pointing at a GitHub pull/issue/commit; every link in the card is https://github.com/… (the page promises public GitHub evidence only); every Month D, YYYY is a real date; no handle has two cards. Each rule has a fixture self-test. Zero dependencies.
  • node --test scripts/story-form-contract.test.mjs — contract gate between the Share-your-story dialog and the GitHub issue form it prefills in hivecommons/hive (its contributor-story.yml issue template), which story-dialog.test.mjs cannot see: GitHub silently ignores an unknown template= (blank-issue chooser, no contributor-story label) and silently drops unknown field ids. The gate reads the template=, title prefix and field ids buildIssue() sends, the <select id="story-role"> options, the fallback link and the promised label from stories/index.html, fetches the template from the hive's default branch (raw.githubusercontent.com/…/HEAD/…, 10 s timeout) and requires: the promised label is one the template applies; the template title: equals the page's prefix; every id sent is a template field; every template input/textarea and every required non-checkbox field is sent (GitHub never prefills checkboxes from the URL); the role dropdown options equal the page's options in order; the fallback link opens the same template. A transport failure or a non-404 HTTP status (429 rate limit, 5xx outage) skips only the live test (offline node --test stays green and a raw.githubusercontent.com hiccup never reads as drift); a 404 on every template directory fails it. STORY_FORM_TEMPLATE=<path> checks a local copy with no network. Each rule has a fixture self-test. Zero dependencies.
  • node --test scripts/page-csp.test.mjs — static gate over the <meta http-equiv="Content-Security-Policy"> on every non-redirect page. GitHub Pages cannot send response headers, so the policy ships as a <meta> tag and inline scripts are allow-listed by sha256- hash: the test recomputes the hash of every inline <script> body and on*= handler and fails when the policy is missing one or carries a stale one (a drifted hash silently disables that script in every browser — after editing any inline script, run node scripts/update-csp-hashes.mjs to regenerate the hashes in the page's CSP meta; the failure message says so). It also requires exactly one CSP meta and a script-src directive, requires default-src 'none', and rejects 'unsafe-inline', 'unsafe-eval', *, http:, https: and data: in script-src. Inline event handlers require 'unsafe-hashes' plus their hashes; 'unsafe-hashes' without handlers is rejected. The meta must precede every <script>/<link>/<img>/<style> in <head>. Every external <img> origin must be allowed by img-src (or default-src when img-src is absent), either explicitly or via https:. base-uri must contain 'none' or 'self', and form-action must be present. Each rule has a fixture self-test. Zero dependencies.
  • node --test scripts/update-csp-hashes.test.mjs — fixture self-test of scripts/update-csp-hashes.mjs, the tool that regenerates the sha256- allow-list the CSP gate checks: a drifted hash is replaced and the gate then passes; non-hash script-src tokens, the other directives, their order and the ; separators are kept byte-for-byte; 'unsafe-hashes' plus the handler hashes appear exactly when a page has inline on*= handlers; redirect pages are skipped, while missing or duplicate policies and script-src directives are reported as errors, never invented or rewritten; token order is not enforced (a policy the gate accepts is never rewritten); --check reports stale pages and exits 1 without writing. Explicit [page.html ...] arguments update only the selected files, leaving other stale pages untouched. Then pins the live tree: every committed content page is already up to date, so the tool and page-csp.test.mjs agree on what correct means, and a failure names the regenerate command. Zero dependencies.
  • node --test scripts/llms-txt.test.mjs — static gate keeping llms.txt in step with index.html: the agent CLIs it names must equal the Agent CLIs chips, the inference engines/gateways it names must equal the engine and gateway chips (classifier chips excluded), and its infrastructure thanks must equal the infra-thanks logo labels — in both directions, so adding, renaming or dropping a chip without updating llms.txt fails CI. Also requires the "See all integrations" docs URL to appear in llms.txt. Each rule has a fixture self-test. Zero dependencies.
  • node --test scripts/jsonld-contract.test.mjs — static gate keeping the schema.org JSON-LD on index.html in step with the page it describes (page-scripts.test.mjs only checks that it parses): exactly one application/ld+json graph with @context https://schema.org; the Organization's sponsor and funder lists are identical and name exactly the infra-thanks logos (label minus its parenthetical, e.g. Akamai (Linode) → Akamai) with each url equal to that logo chip's link; Organization.url is the site root and logo an absolute site URL; the Hive SoftwareApplication.keywords names every integration chip (classifier chips included), every keyword is a chip or visible page text (case-insensitive, plural allowed), none repeats, and every name an including … list in featureList enumerates is a chip; every url, codeRepository, sameAs and sponsor url is https and linked by an href somewhere on the page (trailing-slash differences ignored); and the Projects carousel and the SoftwareApplication nodes describe the same set of projects — every card (its <h3> minus the tag badge) has a node of that name whose codeRepository is the card's GitHub link, and every node has a card. Each rule has a fixture self-test. Zero dependencies.
  • node --test scripts/availability-probes.test.mjs — static gate over the URL list the scheduled availability job in links.yml probes: every probed URL is https, under hivecommons.dev, carries its trailing slash when it is a directory page (GitHub Pages answers 301 for /docs, which curl without -L reports as a failure) and resolves to a committed page; every canonical page in sitemap.xml and /404.html is probed; at least one redirect shortcut is probed; no duplicates. Fixing a failure means editing the workflow's probe list. Each rule has a fixture self-test. Zero dependencies.
  • node --test scripts/site-origin.test.mjs — static gate tying the site origin to CNAME, the one file GitHub Pages actually reads for the host: CNAME must be a single bare lowercase DNS host (no scheme, path, port, trailing dot, second line or CRLF); every SITE_ORIGIN constant the other gates hardcode, every sitemap.xml <loc>, the robots.txt Sitemap: URL and every canonical page's <link rel="canonical">/og:url must be at https://<CNAME>; and no committed page, stylesheet or text asset may link the hivecommons.github.io fallback host (which bypasses the custom domain). Each rule has a fixture self-test. Zero dependencies.
  • node --test scripts/security-txt.test.mjs — static gate over .well-known/security.txt (RFC 9116), whose Expires field nothing else reads (links.yml only probes that the URL answers 200): exactly one Expires that is a valid RFC 3339 timestamp at least 30 days away and no more than ~1 year ahead, at least one Contact (an https://, mailto: or tel: URI), a Canonical equal to the published URL, https:// for every Canonical/Policy/Acknowledgments/Hiring value, and at most one Preferred-Languages — so the contact is rotated before scanners treat it as abandoned and the file never ships in a shape they reject. Each rule has a fixture self-test. Zero dependencies.
  • node --test scripts/pages-build.test.mjs — static gate over what GitHub Pages' Jekyll build actually deploys, which no other gate sees: _config.yml must parse, carry only include: (the README's "nothing else is configured"), and name only directories that exist; every root dot-directory holding site files (.well-known) must be in include:; every URL the site publishes (each sitemap.xml <loc>, each links.yml availability-probe URL, the security.txt Canonical) must map to a file Jekyll will publish — not under an exclude: or default-exclude path and not behind an _/./#/~ segment that include: does not list; and no published file may open with a --- front matter block (Jekyll would run Liquid over it). Each rule has a fixture self-test. Zero dependencies.
  • node --test scripts/redirect-targets.test.mjs — static gate over what a browser makes of each shortcut-redirect page. make-redirects.sh interpolates every MAP url and label into HTML through its html_escape(), so the gate parses the MAP, rejects any url or label that carries ", < or > or a label that decodes as a character reference (defense in depth: nothing a shortcut target needs), and then decodes each committed page's refresh url=, canonical href and <a href> under HTML attribute rules (legacy no-semicolon entities such as &para, &reg, &copy included) and its <title>/link text under text rules, requiring each to resolve to exactly the MAP url/label; any other ambiguous ampersand on the page is reported (&amp;, &lt;, &gt; and &quot; — what html_escape() emits — are the accepted escapes). It also runs the real generator body against a hostile fixture MAP (raw & separators, legacy/numeric references, ", <, > in url and label) in a scratch directory and requires every emitted page to decode back to exactly its entry, so html_escape() is exercised directly rather than only through the characters the committed MAP happens to contain. Each rule has a fixture self-test. Zero dependencies.
  • scripts/check-redirects.sh — redirect-page drift gate described above.
  • scripts/check-redirects.test.sh — fixture-based self-test of the drift gate; runs offline against throwaway sites with a two-entry generator.
  • node --test scripts/ci-wiring.test.mjs — static gate keeping links.yml, scripts/ and this list in step: every scripts/*.sh gate and *.test.sh self-test is run by a run: step in a job that runs on every PR/push (they are listed by hand, unlike the node --test scripts/*.test.mjs glob, which must itself be present and run on every PR/push). A job-level if: counts as a gate only when it can skip a push or pull_request event: scripts/actions-if.mjs evaluates the expression for both, so the github.event_name != 'schedule' || … trim that lets the 6-hourly cron run availability alone is accepted, while an unrecognised expression is not; every scripts/*.sh gate has a sibling self-test; no .mjs that imports node:test sits outside the glob's *.test.mjs name; the workflow runs on pull_request and on push to main; every shell script is executable; and this ## Checks section names every gate and self-test. Each rule has a fixture self-test. Zero dependencies.
  • node --test scripts/actions-if.test.mjs — direct unit test of scripts/actions-if.mjs, the job-level if: evaluator ci-wiring.test.mjs and workflow-docs.test.mjs share: ==/!= on github.event_name and github.event.schedule, !, && over || precedence, parentheses, escaped string literals, and that every unsupported context, function, operator or malformed expression returns undefined so the caller treats the job as gated rather than guessing. Zero dependencies.
  • node --test scripts/html-pages.test.mjs — direct unit test of scripts/html-pages.mjs, the page-discovery helper every static page gate imports to decide which pages it inspects: htmlFiles() recurses, sorts, keeps only .html, and skips exactly the SKIP_DIRS tooling directories (at any depth, directories only); SKIP_DIRS never names a content directory; isRedirectPage() matches the generator's http-equiv="refresh" in every quote/case/attribute-order spelling and nothing else; lineOf() is 1-based. Then pins the live tree: index.html, 404.html, stories/index.html and every make-redirects.sh MAP page are discovered, nothing under a skipped directory is, and the redirect pages are exactly the MAP paths — so an over-broad SKIP_DIRS or a broken walker cannot make the gates pass vacuously. Zero dependencies.
  • node --test scripts/workflow-docs.test.mjs — static gate keeping the prose about links.yml in step with it: in this README and runbooks/*.md, the workflow name must match the workflow's name:; every job the docs name must exist under jobs:; jobs the docs say run on every PR/push must have no if:, or one that scripts/actions-if.mjs evaluates true for both push and pull_request, and the ones they call weekly-only or manual-only must carry an if: on schedule / workflow_dispatch (which the workflow must declare); every weekday and HH:MM UTC must match the cron: expression; and the --external-warn flag must be what the workflow passes outside schedule/dispatch and what scripts/check-links.sh accepts. Each rule has a fixture self-test. Zero dependencies.
  • node --test scripts/automation-docs.test.mjs — static gate keeping the prose about every workflow under .github/workflows/ in step with it. Wherever this README or runbooks/*.md introduces a workflow as **<name>** … (.github/workflows/), the file must be committed and its name: must equal the bold text, and the introducing paragraph's claims must match the triggers: "push to main" needs a push trigger covering main; "every pull request" needs pull_request; "weekly" needs a schedule with a plain weekly cron; a literal cron `M H * * D` must equal the workflow's cron:; "manual dispatch" needs workflow_dispatch; back-ticked pull request activity types (closed, …) must be exactly pull_request.types; and "code scanning" needs a github/codeql-action/upload-sarif step. Every committed workflow must be introduced that way in this README, so new automation cannot land undocumented. Each rule has a fixture self-test. Zero dependencies.
  • node --test scripts/workflow-hardening.test.mjs — static gate over the supply-chain hardening of every workflow under .github/workflows/: every uses: is pinned to a 40-hex commit SHA with a trailing # <version> comment (./ local actions exempt, docker:// images by @sha256: digest), including the reusable-workflow uses:; the workflow declares a top-level permissions: block and nothing grants write-all; every actions/checkout step sets persist-credentials: false; and every job with runs-on sets timeout-minutes. OpenSSF Scorecard reads the same files but runs only on main and a lower score fails nothing, so a tag re-pin or a dropped persist-credentials: false would otherwise merge green. Each rule has a fixture self-test. Zero dependencies.
  • node --test scripts/dependabot-config.test.mjs — static gate over .github/dependabot.yml, the only thing that moves the SHA pins workflow-hardening.test.mjs requires: the file exists and is version: 2; every updates: entry names a package-ecosystem Dependabot knows, a directory: and a schedule.interval it accepts; every ecosystem the tree contains (workflows under .github/workflows/ → github-actions, a root package.json → npm, …) is covered by an entry at /, no entry names an ecosystem the tree lacks, and no two entries cover the same ecosystem and directory. Without it a deleted or mistyped config leaves every pin valid but silently rotting — Scorecard's Dependency-Update-Tool check reads the same file but only on main, and a lower score fails nothing. Each rule has a fixture self-test. Zero dependencies.
  • node --test scripts/owners-file.test.mjs — static gate over every OWNERS file in the tree and OWNERS_ALIASES when present, the files prow's approve plugin and tide read to decide who may /approve and whether a PR merges: the root OWNERS exists; every file is flat YAML of key: blocks of - item lines indented with spaces; only keys prow knows (approvers, reviewers, emeritus_approvers, emeritus_reviewers, labels, options with its boolean flags); the root file names at least one approver; every entry is a syntactically valid GitHub login (no @, no email) or an alias declared in OWNERS_ALIASES; and no list repeats an entry or names someone as both active and emeritus for the same role. Prow treats every one of those mistakes as "no approvers here", so without the gate a typo would land green and surface only as PRs that never merge. Login syntax only — the gate has no network access. Each rule has a fixture self-test. Zero dependencies.
  • node --test scripts/doc-paths.test.mjs — static gate over the repository paths named in backticks by README.md and runbooks/*.md: a word in an inline code span is a path claim when it starts with ./, or when its first segment is a committed top-level directory or it is root-absolute and it ends in a file extension or / (so /404.html, /stories/ and scripts/*.sh are checked, while URL-path examples such as /some/deep/path, action references and bare basenames are not); every claim must resolve to a committed file or directory, a * in the last segment matching at least one. page-meta.test.mjs resolves Markdown links only and ci-wiring.test.mjs checks that every existing gate is described here, not that every described path still exists, so a renamed script or dropped workflow would otherwise leave the prose pointing at the old name. Each rule has a fixture self-test. Zero dependencies.

Local preview and running the checks

Prerequisites: Python 3 (any recent version) for previewing, and Node.js (the node --test runner) for the gates; no npm install is needed.

python3 -m http.server 8000     # then open http://localhost:8000/
node --test scripts/*.test.mjs  # every Node gate (what CI runs)
scripts/check-links.test.sh     # link-checker self-test (offline)
scripts/check-redirects.test.sh # redirect-gate self-test (offline)
scripts/check-redirects.sh      # redirect-page drift gate
node scripts/update-csp-hashes.mjs  # after editing an inline <script>: refresh its CSP hash

Run these from the repository root before opening a PR. The previewed pages are served from the checkout as-is, so root-absolute links (/stories/) resolve locally the same way they do on the live site. Each gate is described under Checks.

Availability monitoring

The Link check workflow runs every Monday at 09:17 UTC, every 6 hours for the availability probe alone, and can also be run manually from the Actions tab. On those runs, its separate availability job requests the live homepage, /stories/, a sample of the shortcut redirects and /404.html over HTTPS and fails unless every one returns HTTP 200 (the list is kept in step with the committed pages by scripts/availability-probes.test.mjs). Connection/TLS errors and timeouts also fail the job. Requests have bounded retries for transient failures. PR and push-to-main runs only check the checkout; they do not probe the production site.

Review failed runs in Actions and configure GitHub Actions notifications for the workflow if you operate the site. See the availability runbook for a failing probe and the rollback runbook for a bad deploy. This 6-hourly probe is a basic availability signal, not continuous uptime monitoring or a check after every deployment. The 6-hourly runs skip the heavier jobs; the full link check runs weekly. External link failures remain warnings in the separate links job.

Traffic analytics and shortcut usage tracking are not configured. Adding them requires an operator to choose a backend/property and settle privacy and consent requirements first (see issue #73).

Repository automation

OpenSSF Scorecard (.github/workflows/scorecard.yml) — Runs OpenSSF security scorecard analysis on every push to main, weekly (cron 23 5 * * 1), and on manual dispatch from the Actions tab. Results are published to GitHub's code scanning dashboard.

Close linked issues (.github/workflows/close-linked-issues.yml) — Automatically closes issues linked to a closed pull request when a PR transitions to closed.

Incident response — When a bad deploy or incident impacts visitors of hivecommons.dev (broken pages, dead redirects, domain issues), use the postmortem template to document it blamelessly and fact-based. Coordinate recovery using the release-rollback runbook.

Code of Conduct

Hive Commons website contributors are expected to follow the CNCF Code of Conduct.

About

hivecommons.dev — placeholder site (GitHub Pages)

Resources

Code of conduct

Contributing

Security policy

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages