Three things about this repo will not be obvious from reading the code, and two of them are failure modes that stay silent. Read this before merging a finding from anyone else, and before assuming the disclosure clock is running.
A finding's markdown body is rendered with markdown.markdown() and raw HTML
passes straight through, so HTML written in a record renders live on that
finding's published page.
This is a deliberate choice, not an oversight. There is one author, security writeups legitimately contain HTML — payload demonstrations, rendered PoC markup, a response body reproduced as it was returned — and escaping it would mean either mangling that content or maintaining an allowlist for a single trusted writer.
The control is pull request review. That control changes character the moment
this repo accepts a finding from anyone else: at that point the body is a stored
XSS path on a github.io origin, and there is nothing else standing in front of
it.
- Anyone merging a third-party finding PR must read the body, specifically
for
<script>, event handlers,<iframe>,<object>, andjavascript:ordata:URLs. validate.ymldoes not inspect body HTML. It runs the test suite and a full generation, which proves the record parses and the site builds — it says nothing about what the body contains. Do not treat a green check as clearance.- If outside contributions ever become normal here, revisit this decision rather than relying on review discipline.
GitHub disables scheduled workflows in a repository that has seen no activity for 60 days. That is the expected steady state for this repo, not an edge case:
- Records change in bursts, and months can pass between them.
- The only thing that pushes commits is
build.yml, and it runs only when a record, a tool, or a dependency file changes. - So a quiet quarter disables
disclosure-clock.yml, and nothing turns red. There are no warning issues, no expiry PRs, no failed runs — the clock simply is not running, and the repo looks exactly as it does when there is nothing due.
This is the worst failure mode in the system, because the clock exists precisely to stop a deadline being missed quietly. Pick at least one mitigation and stick to it:
- Manual dispatch. Run
disclosure-clock.ymlfrom the Actions tab (workflow_dispatchis enabled). A run counts as activity and re-arms the cron. Doing this whenever you touch the repo is usually enough. - Calendar reminder. A recurring monthly reminder to open the Actions tab and confirm the clock ran within the last few days. GitHub also emails the repository owner before disabling a schedule; that email is a prompt to act, not a notification you can ignore.
- Keepalive commit. A low-frequency no-op commit (a dated line in a scratch file) keeps the repo active. Least pleasant, most reliable.
Whichever you choose, the check that matters is the same: the clock's last
successful run should never be more than a few days old while any record is
still in-progress.
The expiry step skips a record rather than failing the whole run, so one bad row cannot starve the others. One of those skips does not resolve itself:
cannot open a PR for disclosure/EL-2026-001-publish
By the time that prints, the branch has already been pushed. On every later run
the git ls-remote guard sees the branch, prints already exists, and skips the
record — so it will never get its preparation PR, and the log line that explains
why appeared once, in a run nobody read.
If you see it, open the PR by hand from the pushed branch (or delete the branch
so the next scheduled run rebuilds it). The same applies to
cannot push/cannot commit messages: they are one-line reports of work that
now needs a human.