docs: add reference documentation, and actually publish the site - #275
Merged
Conversation
The deploy workflow built the Docusaurus site and then published `./build`, which does not exist -- the site is built at `./documentation/build`. So every push to main published an empty directory, which is why the gh-pages branch holds nothing but .nojekyll and https://stackguardian.github.io/tirith/ has always returned 404. Fixing publish_dir is the whole fix. Alongside it: - url and baseUrl were still the create-docusaurus placeholders. A project site is served under /<projectName>/, so baseUrl has to be /tirith/ or every asset and link on the deployed site resolves to the wrong path. - The homepage was the untouched scaffold: the hero rendered the single word "Tirith", and HomepageFeatures rendered nothing at all because its FeatureList was entirely commented out. It now carries the landing-page copy, derived from README.md so there is one source of truth. All prose sits in one `content` object apart from the markup, so it can be edited without reading JSX. The dead HomepageFeatures component is removed. - npm ci rather than yarn install, in both workflows: package-lock.json is the committed lockfile and there is no yarn.lock, so yarn ignored it and resolved the dependency tree fresh on every deploy. - A new build_docs.yml builds the site on pull requests. The site sets onBrokenLinks: 'throw', so one bad cross-link fails the build -- previously discoverable only after merging to main.
The site documented how to write a policy but never said what you could
actually put in one: no list of providers, no list of operation types and their
arguments, no list of condition types, and no CLI or exit-code reference. This
adds 14 pages covering all of it.
Every claim is taken from the code rather than from the existing prose, and the
examples were executed rather than written from memory -- 6 cookbook recipes,
11 provider policies and ~88 evaluator probes were run against the real CLI,
and the quoted output and exit codes are what came back.
New:
tirith-usage/ cli-reference, exit-codes, ci-integration, platform-check
tirith-providers/ overview + one page per provider, with every operation
type, its arguments and what it returns
tirith-reference/ evaluators (all 13 condition types) and eval-expressions
tirith-policies/ tirith-policy-reference (field-by-field schema) and
tirith-policy-cookbook (6 executed recipes)
Fixed in the existing pages:
- tirith-policy-variables.md used `{{ max_epoch }}`, but the engine's pattern is
`{{ var.NAME }}`. Following that page produced a policy that compared against
the literal placeholder string instead of the variable -- a check that looks
like it passes while measuring nothing. Its policy JSON was also invalid
(missing comma) and lacked the required eval_expression. The corrected
version is one that was run; the quoted output is its real output.
- Cross-links now point at the .md file rather than the URL. Relative URLs
resolve against the page's own directory, so `../tirith-reference/evaluators`
from a page at /docs/tirith-providers/x/ resolved to
/docs/tirith-providers/tirith-reference/evaluators. Linking by file lets
Docusaurus resolve through the file graph, which also survives a slug change.
- sidebars.js is a manual sidebar, so the new pages are registered there under
Using Tirith, Providers and Reference; without an entry a page builds but is
unreachable in navigation.
meta.enforcement is documented as what it is: inert in the engine, and read by
the layer above it. The CLI copies it through untouched, while the GitHub Action
downgrades a failing policy to a warning for soft_mandatory and friends and
blocks on anything it does not recognise.
Codecov Report✅ All modified and coverable lines are covered by tests. 🚀 New features to boost your workflow:
|
Clicking a site's own logo goes to that site's home. This one opened tirith-policy-builder.vercel.app in a new tab, so the one control every reader expects to take them home instead took them off the site, with no way back. The builder is still reachable -- it moves to a named navbar item next to GitHub, which is a clearer place for it than an unlabelled logo. The in-content link on the getting-started page is untouched; that site is live and the reference there is deliberate.
Listing a system purely to say it is unsupported tells a reader nothing the "Works with" list does not already tell them, and reads as a roadmap hint that was never intended. Removed from all three places it appeared: the landing page, the CI integration page and the README. Nothing is claimed about Azure DevOps either way now, which was the point of mentioning it in the first place.
The hand-rolled button rule set the label to var(--ifm-background-color), which resolves to #0000 in light mode -- fully transparent. The result was a purple rectangle with no readable text in it. Replaced with Docusaurus's own button classes, which resolve their foreground through --ifm-button-color to white over the dark purple in light mode and to near-black over the lighter purple in dark mode. That removes the custom rules rather than patching them, so there is one less place to get contrast wrong.
|
❌ The last analysis has failed. |
This was referenced Aug 13, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Adds the reference material the site never had, and fixes the reason none of it would have been visible.
The docs explained how to write a policy but never said what you could put in one: no list of providers, no list of operation types and their arguments, no list of condition types, no CLI or exit-code reference. This adds 14 pages, and publishes the site.
Publishing was broken
deploy_docs.ymlbuilt the site and then published./build. Docusaurus builds to./documentation/build. So every push tomainpublished an empty directory — which is whygh-pagescontains nothing but.nojekylland https://stackguardian.github.io/tirith/ has always returned 404.publish_dir→./documentation/buildurl/baseUrlwere still thecreate-docusaurusplaceholders (your-docusaurus-site.example.com,/). A project site is served under/<projectName>/, sobaseUrlmust be/tirith/or every asset and link on the deployed site resolves to the wrong path.npm cirather thanyarn install, in both workflows:package-lock.jsonis the committed lockfile and there is noyarn.lock, so yarn ignored it and re-resolved the dependency tree on every deploy.build_docs.ymlbuilds the site on pull requests. The site setsonBrokenLinks: 'throw', so one bad cross-link fails the build — previously discoverable only after merging tomain.The homepage
It was the untouched scaffold: the hero rendered the single word "Tirith", and
HomepageFeaturesrendered nothing at all because itsFeatureListwas entirely commented out. It now carries the landing-page copy, derived fromREADME.mdso there is one source of truth. All prose lives in onecontentobject apart from the JSX, so it can be edited without reading markup. The dead component is removed.This supersedes #274, which put the same page in
docs/index.htmlas a standalone file — one site is better than two, and this way the reference pages are reachable from it. I will close that PR when this merges.The new pages
tirith-usage/cli-reference,exit-codes,ci-integration,platform-checktirith-providers/overview+ one page per provider, each with every operation type, its arguments, and what it returnstirith-reference/evaluators(all 13 condition types),eval-expressionstirith-policies/tirith-policy-reference(field-by-field schema),tirith-policy-cookbook(6 recipes)Every claim comes from the code, and the examples were executed rather than written from memory — 6 cookbook recipes, 11 provider policies and roughly 88 evaluator probes were run against the real CLI, and the quoted output and exit codes are what came back. The observed exit codes:
--fail-on-error0--fail-on-error3110Existing pages fixed
tirith-policy-variables.mdwas actively harmful. It used{{ max_epoch }}, but the engine's pattern is{{ var.NAME }}. A reader following that page got a policy that compared against the literal placeholder string — a check that looks like it passes while measuring nothing. Its policy JSON was also invalid (missing comma) and lacked the requiredeval_expression. The corrected version is one that was actually run, and the quoted output is its real output.Cross-links now point at the
.mdfile rather than the URL. Relative URLs resolve against the page's own directory, so../tirith-reference/evaluatorsfrom a page at/docs/tirith-providers/x/resolved to/docs/tirith-providers/tirith-reference/evaluators. Linking by file lets Docusaurus resolve through the file graph, which also survives a slug change. 30 links rewritten.sidebars.jsis a manual sidebar, so the new pages are registered under Using Tirith, Providers and Reference. Without an entry a page builds but is unreachable.meta.enforcementDocumented as what it is: inert in the engine, and read by the layer above it. The CLI copies it through untouched and it never affects the exit code; the GitHub Action downgrades a failing policy to a warning for
soft_mandatoryand friends, and blocks on anything it does not recognise. Both statements are true of different layers, and a reader needs to know which one applies to them.Verification
npm ci && npm run buildpasses locally —[SUCCESS] Generated static files in "build"— and the built site was served and spot-checked: homepage and pages from all four new directories return 200.Bugs found and deliberately not fixed here
These are code changes, and do not belong in a docs PR:
ExitStatus.ERROR_TIMEOUT = 2is unreachable. A platform-run timeout raisesSGError→CheckError→ExitStatus.ERROR, so it exits1. The enum, the README anddocs/platform-check.mdall document2for a timeout and nothing can produce it.TypeError: string indices must be integers. Documented as a caveat.return total_sumsits inside thefor project in ...loop in both cost functions, so later projects are never counted.sg_workflowsilently returns""for an unknownworkflow_attribute, so a typo evaluates an empty string instead of erroring.tests/providers/sg_workflow/policy.jsonfails against its owninput.json, andtests/providers/policy.json/wfPolicy.jsonuse argument names and unprefixed provider names that no longer matchPROVIDERS_DICT.equals.py,not_equals.py,greater_than*.pyandless_than*.pyclaim values are "automatically cast to the same type" — no casting occurs.