Every change, shipped.
Reverse-chronological log of all 158 commits in the project's history. Sourced directly from git log — what shipped is what's here.
-
feat(seo): bin/submit-urls.sh for weekly IndexNow bulk submission
Pulls the live sitemap (https://cyber.trackr.live/sitemap.xml), extracts every <loc>, auto-discovers the IndexNow key file from /public/, and POSTs the whole lot to the shared IndexNow endpoint at api.indexnow.org. Bing, Yandex, Seznam, Naver, and DuckDuckGo all get the notification in one call.
-
feat(deploy): bin/fix-perms.sh — standard PHP-site permissions
After rsync the perms can drift (especially on DreamHost where the remote user shell sometimes carries umask quirks), and Symfony gets cranky about world-writable cache dirs or files it can't read.
-
feat(deploy): bin/ship.sh for the dev-side push to prod
Companion to bin/deploy.sh.
-
feat(seo): IndexNow pinger + bin/deploy.sh
IndexNow lets us push URL-change notifications directly to Bing / Yandex / Seznam / Naver / DuckDuckGo (Google opted out of the protocol but has its own faster path via Search Console). Search engines re-fetch flagged URLs within minutes instead of waiting on the natural crawl cycle, which for a content site that updates with every DISA sync is a meaningful win.
-
fix(seo): per-page meta descriptions, content-driven where possible
Bing flagged duplicate-template descriptions across pages.
-
refresh changelog snapshot
-
fix(changelog): freeze command + JSON fallback for rsync deploys
Production is rsynced from dev — no .git directory survives the copy — so the original Changelog service that shelled out to git log fell back to the empty state on prod. /changelog showed only the "check the GitHub history instead" message instead of any real entries.
-
feat(seo): dynamic sitemap.xml + flat /stig/index for crawler depth
The static sitemap captured a snapshot from October 2023 — 971 URLs, missing every STIG / SCAP version added since plus the entire feature set shipped this iteration (plans, ckl-viewer, baselines, r4-to-5, changelog, atom feed). Replaces it with a controller-rendered sitemap that walks the toc files at request time so it stays current without any rebuild step.
-
feat(changelog): /changelog page sourced from git log + footer link
Reverse-chronological list of every commit in the project's history, generated at request time directly from git so it's always current without any rebuild step. Linked from the footer About column between Mission and Contact.
-
docs(readme): bring up to date with current app state
The README still reflected the pre-plan-generator era. Substantial features have shipped since: 20-family RMF Plan Generator, browser- only CKL/CKLB viewer with SCAP overlay, baseline coverage heat map, r4 ↔ r5 mapping page (with withdrawal targets harvested from r5's own catalog), STIG Digest of Updates + Atom feed, OSCAL-driven multi-baseline overlays (14 profiles across NIST + FedRAMP + CNSSI 1253), saved searches, share button, and per-page Open Graph / Twitter Card / JSON-LD metadata.
-
feat(nav): share-this-page button in the sticky header
Sits in the right cluster between the site search and the theme menu, matching .theme-toggle's 36px icon-button styling. Clicking shares the current URL — whatever deep-linked page the user is on, a STIG view, a control catalog page, a baseline cell — that exact URL gets shared.
-
feat(search): saved searches — localStorage-backed bookmarks
Drop-down list of saved queries reachable from the hero search box on the home page and from the /search results page header. Each entry stores the query plus an optional user-supplied label; clicking re-runs the search.
-
feat(seo): per-page Open Graph + Twitter Card + JSON-LD metadata
Makes link-previews on Slack / LinkedIn / Discord / X / Mastodon / generic OG-aware tools render with real titles, real descriptions, and a 1200×630 image — instead of the URL-as-fallback every previewer otherwise produces. Drives organic discovery without any moderation cost or runtime overhead.
-
feat(plans): privacy-baseline UX surfaces
The privacy baseline (nist-privacy) was already in the wizard's baseline dropdown — every overlay loaded by OverlayLoader is offered automatically.
-
feat(rmf): baseline coverage heat map at /baselines
Visualizes 800-53 r5 family-by-baseline distribution as a 20×4 grid: each cell shows how many controls + enhancements that NIST baseline selects from that family, color-tinted by intensity (count / max). Click a cell to see the full control list with deep-links into the catalog detail page; click a family-row label to jump directly to that family in /rmf/5.
-
fix(ckl): SCAP file picker no longer steals clicks across the page
The SCAP file input had class .ckl-drop__input, which sets position: absolute; inset: 0; width: 100%; height: 100% on the element. Its parent (.ckl-toolbar__right) had no position: relative, so the input climbed to the next positioned ancestor — in practice covering most of the page with an invisible click target.
-
feat(ckl): browser-only CKL/CKLB viewer + editor + SCAP overlay + CKLB export
Drop a STIG checklist in any DISA-supported format, read it on a polished dashboard, edit every assessor-facing field, optionally apply a SCAP XCCDF scan to auto-update statuses, and export the result as a modern CKLB JSON that DISA STIG Viewer 3.x reads natively. All processing is client-side — no checklist data ever leaves the browser.
-
feat(stig): Digest of Updates section + Atom feed
Two related additions surfacing what changed between consecutive STIG releases.
-
fix(rmf): pair r4 / r5 enhancements correctly + harvest withdrawal targets from r5 XML
Two issues, single root cause: the mapper was treating r4 and r5 catalogs as opaque string keys.
-
chore(nav): group r4 / r5 / mapping under a single 800-53 dropdown
Replaces the three flat top-level links (800-53 r4, 800-53 r5, r4 → r5) with a single "800-53" disclosure containing Rev 4, Rev 5, and r4 → r5 mapping as sub-items. Trims primary nav from 11 items to 9, leaves clear room for future revisions (a Rev 6 sub-item or a 5 → 6 mapping drops in beside the existing three without touching nav layout).
-
feat(rmf): r4 ↔ r5 control mapping page at /rmf/4-to-5
Side-by-side view of every NIST SP 800-53 control across both revisions. Mechanical layer pairs identical numbers, flags withdrawn r4 entries, and surfaces new-in-r5 entries from the catalogs themselves; curated layer adds rationale text from NIST's Rev 4 to Rev 5 mapping for context-rich rows.
-
docs(todo): seed next-version backlog
Seven enhancements selected from the post-plan-generator review, plus a deferred list for items revisited later. All achievable on the current no-DB / schema-driven architecture; none require user accounts or AI generation.
-
chore(nav): rename "Plans" to "Plan Generator" in primary nav
More descriptive label that signals the page generates RMF plans rather than just listing them.
-
feat(plans): unclassified-only banner on every wizard page
Mirrors the banner on the plans index. No additional gate / modal — the user already confirmed at the index click; this banner is a persistent visual reminder while authoring so a deep-link or back-button navigation doesn't lose the policy reminder.
-
feat(plans): unclassified-data-only confirmation modal on plans index
Public site, public internet — users must explicitly confirm before launching any plan generator that they will not enter classified data or CUI. Bootstrap modal triggered on every plan-card click; gated by a checkbox the user must tick before the Continue button activates.
-
feat(plans): PM family plan — ALL 17 FAMILIES SHIP
Program Management — closes Tier 4 alongside PL, SR, PT, and closes the entire Tier 1-4 plan rollout (17 of 17 families). PM is structurally distinct: NIST treats PM controls as organizational, not system-level; PM is not in any LMH baseline (always-required, selected separately).
-
feat(plans): PT family plan (PII Processing and Transparency)
PT — third Tier 4 family. r5-only privacy family with 8 base controls + 13 enhancements.
-
feat(plans): SR family plan (Supply Chain Risk Management)
Supply Chain Risk Management — second Tier 4 family. r5-only family (no r4 predecessor) — extends RA-3(1) into a formal C-SCRM program per NIST SP 800-161 r1.
-
feat(plans): PL family plan — Tier 4 starts
Planning — first Tier 4 family. Meta-family: documents how the SSP itself, the Rules of Behavior, security and privacy architectures, baseline selection (FIPS 199 / 200), and baseline tailoring are governed.
-
feat(plans): AT family plan — Tier 3 COMPLETE
Awareness and Training — closes Tier 3 alongside PE, PS, MA, MP. The smallest 800-53 family at moderate (4 base controls + AT-2(2) / AT-2(3) in baseline).
-
feat(plans): MP family plan (Media Protection)
Media Protection — fourth Tier 3 family. Compact at moderate (7 base controls, no in-baseline enhancements) but the rigor is in classification-driven handling, sanitization-decision discipline (NIST SP 800-88 r1 Decision Tree), and chain-of-custody for transport.
-
feat(plans): MA family plan (Maintenance)
Maintenance — third Tier 3 family. Compact at moderate (6 base controls + MA-3(1)/(2)/(3) in baseline) but the rigor is in vendor escort, sanitization-before-vendor-maintenance, and nonlocal-maintenance session protections (bastion, JIT, recording).
-
feat(plans): PS family plan (Personnel Security)
Personnel Security — second Tier 3 family. Smallest family in 800-53 r5: 9 base controls and no enhancements at moderate.
-
feat(plans): PE family plan — Tier 3 starts
Physical and Environmental Protection — first Tier 3 family. Distinctive in being heavily inheritance-driven for cloud-hosted systems: each guided control carries an explicit `<control>_inherited` extra field so the plan documents the inheritance posture rather than implying implementation.
-
feat(plans): SA family plan — Tier 2 COMPLETE
System and Services Acquisition — closes Tier 2 alongside SC and RA. Renders 101 cards at nist-moderate (11 bases + 90 enhancements — the SA family carries 33 SA-8 enhancements and 12 SA-15 enhancements single-handedly) with 90 ODV inputs and 90 disposition pickers; 38 KB DOCX with valid OOXML.
-
feat(plans): RA family plan (Risk Assessment)
Risk Assessment — second Tier 2 family. Methodology-heavy and smaller than SC: 6 base controls in nist-moderate, but the engineering work is process documentation (categorization, methodology, risk register, acceptance authority) rather than tooling sprawl.
-
feat(plans): SC family plan — Tier 2 starts
System and Communications Protection — the largest technical family in 800-53 r5. Renders 91 cards at nist-moderate (18 bases + 73 enhancements) with 74 ODV inputs and 73 disposition pickers; 36 KB DOCX with valid OOXML.
-
feat(plans): CA family plan — Tier 1 COMPLETE
Eighth family on the Phase 2 baseline. The meta family — every other plan's §7 already references CA-7 (Continuous Monitoring); this plan defines the strategy.
-
feat(plans): SI family plan (System and Information Integrity)
Seventh family on the Phase 2 baseline. Pairs with AU (SI-4 monitoring feeds the audit pipeline), IR (SI-3 malware + SI-7 integrity findings generate incident signals), and RA (SI-2 flaw remediation consumes RA-5 vulnerability scans).
-
feat(plans): CP family plan (Contingency Planning)
Sixth family on the Phase 2 baseline. Pairs with CM (backup_strategy in §6) and IR (recovery phase).
-
feat(plans): IR family plan (Incident Response)
Fifth family on the Phase 2 baseline. Pairs with AU since incidents are detected via the audit pipeline.
-
feat(plans): IA family plan + multi-select template substitution fix
Fourth family on the Phase 2 baseline. Pairs with AC since AC delegates the underlying authenticator strength and identity proofing to IA.
-
feat(plans): AU family plan (Audit and Accountability)
Third family on the Phase 2 baseline. Pure schema work — same pattern as AC.
-
feat(plans): AC family plan + wizard badge clarity fix
First family added on top of the Phase 2 baseline. Pure schema work — no engine changes needed — confirming the schema-driven design pays off on family expansion.
-
feat(plans): Phase 2 — assessability (ODVs, tailoring, structured CM)
Real-RMF-practitioner feedback on the Phase 1 CM Plan flagged 20 assessability gaps: the plan was structurally sound but lacked the enforceable, measurable, organization-defined parameters that ATO evidence requires. Phase 2 closes those gaps and establishes the new assessability floor for every future family schema.
-
feat(plans): schema-driven family-plan generator (Phase 1, CM-first)
A wizard-based generator that produces NIST RMF family compliance plans (Configuration Management Plan first; AC, AU, IR, etc. follow as schema-only effort).
-
feat(cci): link Control column to 800-53 r5 page
Swap ui.ident(r.rmf) for ui.rmf_link(r.rmf) in the CCI table's Control column so AC-3, CM-6, etc. become clickable pills that jump to /rmf/5#rmf_<num> - matching the deep-link behavior already on the STIG/SCAP detail pages.
-
feat(deploy): app:deploy wraps cache:clear + search:rebuild
Single post-deploy entry point so the standard steps can be run with one command (or a single line in CI / a hosting cron):
-
perf(search): shard docs.json to bring per-search memory under 256M
Replaces the single 154 MB docs.json (which parsed to ~400 MB PHP array on every search) with a directory of fixed-size shard files, 1000 docs per shard. The store loads only the shards that contain matched doc indexes, so a typical query touches a handful of shards (~3-5 MB each) instead of the full corpus.
-
fix(search): bump memory_limit on search path so 256M hosts don't OOM
A search currently loads the entire 154 MB docs.json into a PHP array (~400 MB resident, ~544 MB peak during JSON decode) plus postings and trigrams. Production was hitting "Allowed memory size of 268435456 bytes exhausted" - PHP's default 256M cap is below the working set.
-
fix(search): bump memory_limit in IndexBuilder so rebuild runs OOTB
The full rebuild walks ~1.2 GB of STIG XML and holds the postings, docs, and trigram tables in memory simultaneously, peaking around 1.5-2 GB. Default php.ini memory_limit (often 128M-512M) trips a fatal during the build, both from the CLI command and from the post-DISA-pull auto-rebuild hook in the controllers.
-
feat(nav,cci): primary-nav reorder + Mission link, CCI responsive table
Two navigation/UX adjustments:
-
fix(mobile): sticky search visible + stacked rule layout on STIG/SCAP
Two mobile-experience fixes addressing density complaints on phones:
-
feat(home,nav): common-workflows chip strip + 3-level breadcrumbs
Two pieces of feedback addressed without taking on new content to maintain:
-
feat(home): "Why this site" value-prop section + sync cadence fix
Adds a new section between the hero and the tile grid (renumbers existing sections accordingly: Browse → §II, Recent → §III, Colophon → §IV) covering:
-
copy: hero headline → "The reference desk for cyber compliance."
Replaces "A complete reference for the cyber compliant" — the original phrasing didn't quite vibe and "the cyber compliant" reads as the audience descriptor rather than the subject. New headline pairs with the "Free Compliance Library" tagline in the header to set a consistent library/reference frame for first-time visitors landing mid-task.
-
feat(search): inverted index w/ phrase + fuzzy, replaces live xpath
Replace HomeController::search()'s 175-line per-request walk over every STIG XML, the CCI catalog, both 800-53 catalogs, and the AP json with a pre-built inverted index. Old search took tens of seconds; new search returns ~1s cold (mostly JSON parse) and sub-second once Symfony's app cache warms.
-
feat(stig,scap): deep-link controls + CCIs to library pages
Control numbers (CM-6, AU-2, etc.) and CCI ids (CCI-000366) shown on STIG and SCAP detail pages are now clickable .ident pills that jump straight to the relevant entry on the library pages.
-
style: full-width data pages, center prose pages
Lift desktop-cap max-widths so data pages (/stig, /scap, /cci, /rmf, STIG detail, search results, home tile grid) fill the viewport on wide monitors — addresses feedback that dense tables felt cramped in the center column.
-
feat: mission page, theme system, auto sync stamps, dynamic versioning
Footer cleanup - Remove "Ruby gem" placeholder link (never had a gem to point at) - Remove "Diff engine" link — the diff lives on each STIG document page individually, so there's no one engine to link to
-
Updating style for stig compare page
-
chore(scap): persist Amazon Linux 2023 toc entry
The Amazon Linux 2023 STIG SCAP draft XML was committed in e78acdf but its scap_toc.json entry never got written back to disk. The ScapController auto-detects new XML files on every /scap request and rebuilds the toc in-memory; this commit just snapshots that state to disk so the entry shows up without a request-time rebuild.
-
fix(cci): theme bs5 .page-link pagination + default to 10 rows
DataTables 1.13.6's bs5 styling build wraps pagination in Bootstrap's .pagination > .page-item > .page-link markup. The previous theming only overrode the legacy .paginate_button class on the <li>, so the visible blue link color on the <a> still came through.
-
fix(cci): finish DataTables theming so /cci matches the warm-paper aesthetic
Three reported issues:
-
style(rmf): match Rev. 4/5 italics to STIG/SCAP page-title accent
The lib-page__title-large em rule (used by /stig and /scap index pages) gives <em> children golden italics via --accent + opsz/SOFT axis tweaks. The stig-detail__title rule (used by single-STIG, single-SCAP, and both RMF view pages) had no matching em rule, so 'Rev.
-
fix(rmf): chip counts reflect visible rows + show enhancement-only parents
Two related fixes for the overlay filter on /rmf/5:
-
feat(rmf): add CNSSI 1253 Classified + Space overlays
Extends the overlay filter on /rmf/5 with two more CNSS chips, sourced from the standalone overlay PDFs (Attachment 5 — Classified System Overlay, 09/30/2022; Attachment 2 — Space Platform Overlay, Aug 2025).
-
feat(rmf): add CNSSI 1253 baselines for National Security Systems
Extracts the four NSS baselines (Low / Moderate / High / Privacy) from CNSSI 1253 (29 July 2022 revision) and integrates them as a third authority alongside NIST and FedRAMP on /rmf/5.
-
feat(rmf): add FedRAMP Rev 5 baselines + source-prefixed overlay IDs
Recovers the four FedRAMP r5 OSCAL profiles from Wayback Machine snapshots of the now-deleted GSA/fedramp-automation repo and integrates them alongside the four NIST baselines on /rmf/5.
-
feat(rmf): baseline overlay filter on /rmf/5 backed by NIST OSCAL profiles
Adds a chip-group filter above the r5 controls list (All / Low / Moderate / High / Privacy) plus a small color-coded L/M/H/P badge on each control's metadata column.
-
docs: add repo-level README
Covers architecture, dataset inventory, all 14 user-facing routes and 14 REST API endpoints, console commands, local dev setup, and the recently rebuilt design system. Calls out the *Compilation*.zip gitignore rule so the 150 MB DISA sunset bundle can't be re-introduced.
-
feat(scap): DISA download wiring + Amazon Linux 2023 SCAP draft
Restores the legitimate code, template, and dataset changes that were folded into the bad "Disa downloads" + "DISA" commits:
-
fix(table): keep sev-mix on a single line, let Name column give up width
User report: sev-bar + sev pills (H/M/L) wrap to multiple lines on some rows of /stig and /scap.
-
docs(todo): close out every remaining item — TODO is now archival
Final pass over TODO.md to reflect actual completion state:
-
feat(scap): pre-compute sev counts + Severity Mix column on /scap (deferral #6)
Closes the last cross-page inconsistency between /stig and /scap. Mirrors §4.3a's StigTocBuilder pattern.
-
feat(search): add freshness dot to STIG vuln results (deferral #5)
Surfaces the STIG release date alongside each vulnerability result so users can spot-check whether a returned rule is from a current or aged STIG.
-
perf(fonts): self-host Fraunces + IBM Plex, drop Google Fonts dependency
Closes deferral #1 from the §6 Performance pass.
-
docs(todo): mark Group 7 done — redesign TODO complete
-
chore(css/templates): hygiene sweep — extract inline styles to utilities (§7)
Final §7 cleanup pass. Auditing surfaced three patterns of inline style="" left in templates after the redesign; extracted to small utility classes.
-
docs(todo): mark Group 6 done
-
perf: preload font CSS, lazy-apply grain (§6)
Most §6 items already in place from earlier passes: - Homepage table top-100 cap (§4.3 / user request) - Stig + scap list 50/page client-side pagination (§4.5, §4.8) - font-display: swap on the Google Fonts URL (§1.3) - preconnect to fon…
-
docs(todo): mark §5.5 done
-
feat(a11y): focus rings, sortable header keyboard nav, contrast fix (§5.5)
Group 5.5 of the redesign — accessibility audit + fixes.
-
docs(todo): mark §5.4 done
-
feat(responsive): hamburger nav, table card-view below md, touch bumps (§5.4)
Group 5.4 of the redesign — mobile-first responsiveness pass.
-
tweak(report-generator): add § I Report Details divider, renumber to II/III
-
tweak(report-generator): 3-col setup layout (data points / options / files)
User request: collapse the prior two-step setup (Report data points then Render options + Scan files) into one row of three side-by-side columns on large viewports — Data points, Render options, Scan files each as one column. On smaller viewports they stack.
-
docs(todo): mark §4.14 done
-
feat(report-generator): redesign /report_generator page chrome (§4.14)
Group 4.14 of the redesign — Scans-to-Reports page. CSS/HTML shell only; the heavy client-side parser/web-worker JS (lines ~172-2707, untouched) continues to do all the work in the browser.
-
docs(todo): mark §4.13 done
-
feat(contact): redesign /contactus with tokenized form (§4.13)
Group 4.13 of the redesign — Contact page (/contactus). Lightweight template with a 3-field form (email / subject / body) submitting to Formspree.
-
docs(todo): mark §4.12 done
-
feat(search): redesign /search results page with tokenized sections (§4.12)
Group 4.12 of the redesign — search results page (/search/{query}). Replaces the legacy bg-primary-subtle / border-primary Bootstrap section headers with tokenized collapsible blocks; restructures the page using the lib-page shell.
-
docs(todo): mark §4.11 done
-
feat(cci): redesign /cci page header + theme DataTables to tokens (§4.11)
Group 4.11 of the redesign — CCI list page (/cci). Per Group 8 decision, this is the one list page that keeps DataTables (the Excel/CSV/PDF/Print export buttons are heavily used and provide real value the custom .data-table doesn't replicate).
-
docs(todo): mark §4.10 done
-
feat(rmf): redesign RMF v4 page header (§4.10)
Group 4.10 of the redesign — RMF Rev. 4 controls page (/rmf/4).
-
docs(todo): mark §4.9 done
-
feat(rmf): redesign RMF v5 page header (§4.9)
Group 4.9 of the redesign — RMF Rev. 5 controls page (/rmf/5).
-
docs(todo): mark §4.8 done
-
feat(scap): redesign /scap list as managed-table page (§4.8)
Group 4.8 of the redesign — SCAP list page (/scap). Same .lib-page + .data-table pattern as §4.5 STIG list, narrower since the SCAP toc lacks pre-computed severity counts.
-
docs(todo): mark §4.7 done
-
feat(scap): redesign SCAP detail page mirroring STIG detail (§4.7)
Group 4.7 of the redesign — SCAP detail page (/scap/{title}/{v}/{r}).
-
fix(css): override Bootstrap bg-light + border to use theme tokens
The metadata <dl> panel inside each STIG rule (and matching panels in scap/view, rmf/view_v4, rmf/view_v5) used Bootstrap's bg-light + border classes. Bootstrap hardcodes bg-light to #f8f9fa (cool near-white) which produced unreadable light-text-on-near-white in our dark theme.
-
docs(todo): mark §4.6 done
-
feat(stig): redesign STIG detail page with header, stat-cards, versions panel (§4.6)
Group 4.6 of the redesign — STIG detail page (/stig/{title}/{v}/{r}). Rewrites everything above the rule-loop to match spec §20; rule-loop markup is preserved (existing JS depends on it) but its supporting CSS is fully tokenized.
-
docs(todo): mark §4.5 done
-
feat(stig): redesign /stig list as full-library managed table (§4.5)
Group 4.5 of the redesign — STIG list page (/stig). Replaces the old Bootstrap+DataTables view with the same .data-table component shipped on the homepage in §4.3, but operating over the full 1,076- STIG library with client-side pagination at 50/page.
-
content: wire GitHub links to https://github.com/CyberSecDef
Replaces the two aria-disabled GitHub placeholders (homepage colophon secondary CTA + footer About column link) with the real profile URL. Adds target=_blank + rel=noopener noreferrer per safe-external-link convention.
-
docs(todo): mark §4.4 done
-
feat(home): add colophon section with 12-col split + CTAs (§4.4)
Group 4.4 of the redesign — homepage colophon. Replaces the legacy "About Us" 4-col Bootstrap card (which was already removed in §4.3 when the legacy block was deleted) with the spec's 12-col split.
-
tweak(home): bump recent table to 100 rows, clarify placeholder
User feedback: typing 'Windows' in the homepage filter returned nothing because Windows STIGs aren't in the most-recently-released 40 (they're 2023-ish). Two adjustments: - HomeController slices top 100 instead of top 40 — wider window catches more in-demand STIGs without forcing a trip to the full /stig page.
-
docs(todo): mark §4.3 and §4.3a done
-
feat(home): replace DataTable with custom managed Recent updates table (§4.3)
Group 4.3 of the redesign. Replaces the legacy Bootstrap+DataTables "Recent STIGs" block on the homepage with a custom managed table matching the spec exactly.
-
feat(stig): pre-compute severity counts in stig_toc.json (§4.3a)
Data-layer prerequisite for the homepage Severity Mix column and STIG list filtering by severity. Extracts the toc-build logic from StigController into a reusable service and adds a console command for the one-time backfill.
-
docs(todo): mark §4.2 done
-
feat(home): add 12-column tile grid below the hero (§4.2)
Group 4.2 of the redesign — homepage browse tile grid. Composes the .tile component shipped in §2.6.
-
docs(todo): mark §4.1 and §5.3 done
§5.3 folded into §4.1 since the hero entrance animations need the .rise + .delay-N utilities to be present.
-
feat(home): replace 'Welcome' card with magazine-style hero (§4.1 + §5.3)
Group 4.1 of the redesign — homepage hero. Folds in §5.3 (rise entrance animation + delay utilities) since the hero needs them.
-
docs(todo): mark §3.3 and §5.2 done
§5.2 was folded into §3.3 since the footer's Status column needs the sync-status wiring to be functional out of the box.
-
feat(layout): add site footer with sync-status wiring (§3.3 + §5.2)
Group 3.3 of the redesign — site footer. Folds in §5.2 (sync_status JSON + service + Twig globals) since the footer's Status column needs that data to be functional.
-
docs(todo): mark §3.2 done
-
feat(layout): add atmospheric grain overlay and section divider
Group 3.2 of the redesign — small atmospheric polish.
-
docs(todo): mark §3.1 and §5.1 done
§5.1 was folded into §3.1 since the new header's theme toggle button needs JS to be functional out of the box.
-
feat(layout): replace 4-quadrant body grid with sticky top header (§3.1 + §5.1)
Group 3.1 of the redesign — the largest single visual change so far. Folds in §5.1 theme-toggle JS too because the new header's toggle button needs functional JS to ship.
-
docs(todo): mark Group 2.6 done
-
feat(ui): add .tile navigation card component
Group 2.6 of the redesign. Card-shaped clickable region for the homepage browse grid.
-
docs(todo): mark Group 2.5 done
-
feat(ui): add .chip filter component and apply to sort selectors
Group 2.5 of the redesign. Generic pill-shaped clickable token used for filters, query suggestions, category tags, and small multi-choice groups.
-
docs(todo): mark Group 2.4 done
-
feat(ui): add freshness dot/relTime utilities and sweep date displays
Group 2.4 of the redesign. Replaces bare ISO date strings with a colored age dot + human relative-time label everywhere a release or publish date appears.
-
docs(todo): mark Group 2.3 done
-
feat(ui): add .sev-bar proportional severity strip
Group 2.3 of the redesign. 96×5 px inline-flex bar showing high/med/low rule mix at a glance.
-
docs(todo): mark Group 2.2 done
-
feat(ui): add .sev pill component for severity, replace Bootstrap badges/buttons
Group 2.2 of the redesign. Two roles for the .sev component: 1.
-
docs(todo): mark Group 2.1 done
-
feat(ui): add .ident pill component and sweep templates to use it
Group 2.1 of the redesign — highest-impact sweep. Wraps every technical identifier across the site in a monospace pill so the data is visually distinct from prose.
-
docs(todo): mark Group 1 done, note deferrals
- 1.1, 1.2, 1.3 all checked off with implementation notes inline. - Two items deferred with reasons: - Fraunces woff2 preload → Group 6 (Performance) — needs URL strategy.
-
feat(typography): load Fraunces + IBM Plex, add display/mono/eyebrow utilities
Group 1.3 of the redesign. Wires up the three-typeface system the spec calls for and the utility classes that components will use.
-
feat(css): add design tokens (light + dark themes, severity, freshness)
Group 1.2 of the redesign. Introduces the token system that all future custom styles will reference.
-
refactor(css/js): extract inline styles and scripts to public/css/app.css and public/js/app.js
Group 1.1 of the redesign — foundations / file structure. No visual change yet; this purely moves existing rules out of templates so later token + typography work has a single home.
-
docs: add redesign TODO with resolved decisions
Backlog for the Cyber Trackr redesign, grouped by type of change with explicit scope tags. Cross-referenced against actual templates and stylesheets to flag spec assumptions that needed adjustment (Tailwind class translations, sidebar→top-nav shift, DataTables retain-vs-replace per page, file structure for app.css/app.js, sync_status.json source of truth, etc.).
-
fix(stig): default released date to '' when 'Date:' missing
explode('Date:', \$released)[1] threw 'Undefined array key 1' for STIGs whose release-info plain-text didn't contain 'Date:' (or had an empty release-info). Surfaced on /stig listing — STIGs without the substring crashed the loop.
-
fix(twig): guard xpath|first chains against empty results
Twig 3.18+ tightened attribute access: |first on an empty array yields false (PHP current([])), and accessing an attribute on a bool now errors instead of silently returning null/empty. Three templates (stig, scap, rmf v5) chained .references / .title onto xpath()|first results without checking, which broke when the looked-up CCI or related RMF control wasn't in the loaded XML data.
-
chore: gitignore auto-generated config/reference.php
Symfony 7.x's framework-bundle regenerates this PHP-config IDE autocomplete helper after composer scripts run. Useless when using YAML config; keeping it out of version control.
-
chore: apply symfony/security-bundle recipe update
-
chore: apply symfony/framework-bundle recipe update
Adopts new flex 7.x env file pattern: .env is env-neutral default (APP_ENV=dev, empty APP_SECRET), .env.dev holds dev secret, new .env.prod holds the existing prod secret. Prod deploys must set APP_ENV=prod externally (web server, .env.local, or container env).
-
chore: apply symfony/monolog-bundle recipe update
-
chore: apply phpunit/phpunit recipe update
Modernizes for PHPUnit 11: - Strict failure mode (failOnDeprecation, failOnNotice, failOnWarning) - Source restrictions and deprecationTrigger config - Simplified bin/phpunit (single require, PHPUnit handles entry) - .gitignore: result.c…
-
chore: apply symfony/web-profiler-bundle recipe update
-
chore: apply symfony/mailer recipe update
-
chore: apply symfony/twig-bundle recipe update
Adds file_name_pattern: '*.twig' for FrankenPHP hot-reload support, removes redundant default_path. Kept existing base.html.twig customizations (favicons, styles, scripts) — discarded skeleton's SVG fallback favicon and FrankenPHP hot-reload snippet per user direction; UI is being redesigned later.
-
chore: apply symfony/validator recipe update
-
chore: apply symfony/translation recipe update
-
chore: apply symfony/routing recipe update
Switches routes.yaml to use the new logical 'routing.controllers' resource (Symfony 7.4) instead of explicit src/Controller/ scan. Adds DEFAULT_URI env var.
-
chore: apply symfony/console recipe update
Adds defensive vendor-dir check in bin/console.
-
chore: apply symfony/flex recipe update (2.3 → 2.4)
Adds .env.dev placeholder per flex 7.x pattern.
-
Initial Commit