Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 12 additions & 1 deletion site/astro.config.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -93,7 +93,18 @@ export default defineConfig({
useStarlightUiThemeColors: false,
styleOverrides: {
borderColor: "var(--kit-line)",
borderRadius: "0.5rem",
// The panel step, taken from the same token the stylesheet uses
// rather than repeated as a number here. Expressive Code emits this
// straight into --ec-brdRad and draws the frame at that plus its
// border width, so a block's outer edge measures 9px and its content
// measures the 8px the scale asks for. That pixel is the border, not
// a fifth radius.
//
// Changing this needs the Astro cache cleared to see the effect. The
// dev server keeps serving the previously generated Expressive Code
// stylesheet, and the stale one renders every block at 0px, which
// reads as a broken value rather than as a stale build.
borderRadius: "var(--kit-radius-panel)",
frames: { frameBoxShadowCssValue: "none" },
},
},
Expand Down
13 changes: 13 additions & 0 deletions site/scripts/generate.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,19 @@ export function parseRules(text) {
})
}

/**
* The first sentence of a rule's Check, for the two homepage panels that are
* too small to hold the whole clause. Quoting a prefix is the only abridgement
* that cannot say something the standard does not: the panel used to carry a
* hand-written summary of R-CI-01's Check, and it dropped the `branches:`
* filter condition, so it told a repository carrying one that it passed.
* @param {string} check
*/
export function leadClause(check) {
const end = check.indexOf(". ")
return end === -1 ? check : check.slice(0, end + 1)
}

/** @param {Record<string,unknown>} fields @param {string} body */
export function frontmatter(fields, body) {
const head = Object.entries(fields)
Expand Down
5 changes: 4 additions & 1 deletion site/src/components/FaIcon.astro
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,10 @@ if (!glyph) throw new Error(`FaIcon: no icon mapped for "${name}"`)
const svg = icon(glyph, {
attributes: {
"aria-hidden": label ? "false" : "true",
"aria-label": label,
// Spread rather than assigned: an undefined label serialized to the literal
// string aria-label="undefined" on every icon the site draws. Masked while
// the icon stays hidden, and live the moment one is given a name.
...(label && { "aria-label": label }),
focusable: "false",
},
}).html.join("")
Expand Down
48 changes: 36 additions & 12 deletions site/src/components/HomeHero.astro
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ FORM: user-pinned lateral control surface based on approved composition A; no co
import DomainIcon from "./FaIcon.astro"
import InlineCode from "./InlineCode.astro"
import InstallCommand from "./InstallCommand.astro"
import { domains, sampleRule } from "../lib/content.mjs"
import { domains, leadClause, sampleRule } from "../lib/content.mjs"
---

<section class="kit-hero" aria-labelledby="kit-hero-title">
Expand All @@ -31,12 +31,17 @@ import { domains, sampleRule } from "../lib/content.mjs"
</div>

<div class="maintenance-map" aria-label="How oss-kit connects repository maintenance domains">
<div class="maintenance-map__rail">
<span>Cross-domain scan</span>
<a href="/skills/oss-audit/">oss-audit</a>
{/* The rail named oss-audit and never said what it produces. Its two
captions read "Cross-domain scan" and "Every standard domain", both were
hidden below 34rem, and the definition a reader needed sat a thousand
pixels down the page in the domain rack. It says it here now, and the
whole strip is the link rather than the one word inside it. */}
<a class="maintenance-map__rail" href="/skills/oss-audit/">
<strong>oss-audit</strong>
<span class="maintenance-map__pulse" aria-hidden="true"></span>
<span>Every standard domain</span>
</div>
<span class="maintenance-map__rail-note">Evidence and gaps across every standard domain</span>
<DomainIcon name="arrow" />
</a>

<div class="maintenance-map__body">
<article class="repo-hub">
Expand Down Expand Up @@ -67,11 +72,14 @@ import { domains, sampleRule } from "../lib/content.mjs"
<span class="domain-bay__count">
{/* The lit bay used to say so in green and in nothing else. The
marker is a shape rather than a second tint, and the word
behind it is what a reader who cannot see either one gets. */}
behind it is what a reader who cannot see either one gets.
That word said "Scanning now.", which described an activity
no visitor had started on a repository none had supplied.
The bay is lit because the route below expands it. */}
{domain.area === "SEC" && (
<>
<i aria-hidden="true" />
<span class="sr-only">Scanning now. </span>
<span class="sr-only">Example domain. </span>
</>
)}
{domain.rules.length} rules
Expand All @@ -84,16 +92,32 @@ import { domains, sampleRule } from "../lib/content.mjs"

{
sampleRule && (
<article class="rule-route">
<article class="rule-route" aria-labelledby="rule-route-label">
<div class="rule-route__head">
<span>Example route</span>
<span id="rule-route-label">Example route</span>
<a href={`/rules/${sampleRule.id.toLowerCase()}/`}>{sampleRule.id}</a>
</div>
<h2>{sampleRule.statement}</h2>
{/* A statement, not a section heading. As an h2 this was the second
heading on the site, ahead of every section, so anyone browsing
by heading met a SHA-pinning rule before the page's structure.
It renders at 11.5px, which is the size that gave it away. */}
<p class="rule-route__statement">{sampleRule.statement}</p>
<dl>
<div>
<dt>Check</dt>
<dd><InlineCode text={sampleRule.check} /></dd>
{/* The whole Check ran to nine wrapped lines of 11px monospace,
the largest text mass in the map and its least readable
panel, at the point the route was meant to arrive. Mono
carries machine-facing facts here, not explanations. */}
<dd>
<InlineCode text={leadClause(sampleRule.check)} />
<a
class="rule-route__more"
href={`/rules/${sampleRule.id.toLowerCase()}/#${sampleRule.id.toLowerCase()}-check`}
>
Read the full check
</a>
</dd>
</div>
<div>
<dt>Fixed by</dt>
Expand Down
29 changes: 19 additions & 10 deletions site/src/content/docs/index.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ tableOfContents: false
---

import DomainRack from "../../components/DomainRack.astro";
import { rules, sampleRule } from "../../lib/content.mjs";
import { FORGE_LABEL, contractRule, leadClause, rules, sampleRule } from "../../lib/content.mjs";

<DomainRack />

Expand Down Expand Up @@ -50,10 +50,12 @@ import { rules, sampleRule } from "../../lib/content.mjs";
<strong>Observable evidence</strong>
{/* The rule's own Check line runs to 400 characters, which in a card this
size is a wall nobody reads and which forced the other three cards to
match its height. The leading clause is quoted here and the link goes
to the whole thing. */}
<p>Every external <code>uses:</code> line resolves to a 40-character commit SHA.</p>
<a href="/rules/r-sec-01/#r-sec-01-check">Read the full check</a>
match its height. Its first sentence is quoted, and the link goes to
the whole thing. The sentence used to be written out here in a shorter
form of its own, which read as a quotation and was not one: it dropped
the composite actions the rule also covers. */}
<p>{leadClause(sampleRule.check)}</p>
<a href={`/rules/${sampleRule.id.toLowerCase()}/#${sampleRule.id.toLowerCase()}-check`}>Read the full check</a>
</li>
<li>
<span className="workflow-trace__step">03 · Fix</span>
Expand All @@ -77,18 +79,25 @@ import { rules, sampleRule } from "../../lib/content.mjs";
<p>The standard states every current opinion as a numbered rule with a reason, a check, one fixing skill, and forge scope.</p>
<a className="kit-button kit-button--secondary" href="/standard/">Read all {rules.length} rules</a>
</div>
{/* Every field here comes from the rule. The panel used to be transcribed by
hand, under a heading inviting the reader to check the bar before adopting
it, and its Check said "The workflow declares both trigger paths." The real
one turns on a `branches:` filter, which a configuration can carry and
still fail. Nothing failed when the two diverged, so the one element on the
page that offered verification was the one element nothing verified. */}
<div className="standard-sheet" aria-label="Structure of an oss-kit rule">
<div className="standard-sheet__head">
<span>Rule contract</span>
<span>R-CI-01</span>
<a href={`/rules/${contractRule.id.toLowerCase()}/`}>{contractRule.id}</a>
</div>
<code>Statement</code>
<p>CI runs on every push to the default branch and on every change request.</p>
<p>{contractRule.statement}.</p>
<code>Check</code>
<p>The workflow declares both trigger paths.</p>
<p>{leadClause(contractRule.check)}</p>
<a className="standard-sheet__more" href={`/rules/${contractRule.id.toLowerCase()}/#${contractRule.id.toLowerCase()}-check`}>Read the full check</a>
<div className="standard-sheet__meta">
<span>Fixed by <strong>oss-ci</strong></span>
<span>GitHub and GitLab</span>
<span>Fixed by <strong>{contractRule.fixedBy}</strong></span>
<span>{FORGE_LABEL[contractRule.forges]}</span>
</div>
</div>
</section>
Expand Down
9 changes: 9 additions & 0 deletions site/src/lib/content.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,10 @@ import readmeText from "../../../README.md?raw"
import standardText from "../../../skills/oss-audit/STANDARD.md?raw"
import { FORGE_LABEL, parseRules, skillSummaries } from "../../scripts/generate.mjs"

// Re-exported so a page quoting the standard reaches for one module rather than
// two, and so nothing on the homepage has a reason to transcribe a rule by hand.
export { FORGE_LABEL, leadClause } from "../../scripts/generate.mjs"

export const rules = parseRules(standardText)

export const domains = [...new Set(rules.map((rule) => rule.section))].map((section) => {
Expand All @@ -20,6 +24,11 @@ export const domains = [...new Set(rules.map((rule) => rule.section))].map((sect

export const sampleRule = rules.find((rule) => rule.id === "R-SEC-01")

// The rule the homepage's contract panel takes apart. A second area, so the page
// does not show the same rule twice, and read from the standard rather than
// transcribed: see leadClause for what the transcription cost.
export const contractRule = rules.find((rule) => rule.id === "R-CI-01")

/** @param {number} n */
const plural = (n) => `${n} ${n === 1 ? "rule" : "rules"}`

Expand Down
Loading
Loading