Permanent guardrails#
These are doctrine, not per-task decisions. They bind every session and every tool, so the posture cannot drift. They are written as what not to do, because on a WordPress plugin the common compliance reflexes are the dangerous ones.
| Guardrail | The rule |
|---|---|
| Compliance layering | No server-level configuration (strict CSP, TLS headers) injected from plugin code; it breaks core and Gutenberg and is the wrong layer. No .env in a WordPress plugin; configuration is wp-config.php, options, or approved constants. WordPress core owns password hashing; a plugin never shadows the password store. |
| Secure by design | Every change keeps static analysis at its strictest level with zero errors and conforms to the WordPress-Extra lint ruleset. Sanitisation and nonce plus capability checks are mandatory at every entry point. No tree-wide automated fixes; compliance is verified surgically, per unit. No hardcoded secrets. |
| Honest documentation | Every GDPR, CCPA, CRA, or accessibility claim is defensible, source-cited, and mapped to a real status. Fabricated or generalised compliance statements are never written. |
Compliance status#
"Partial" means a real baseline is enforced but a formal end-to-end audit has not been done. "Not assessed" means no claim is made yet. "Not applicable" means the obligation does not arise in the current code. Feed is a parked skeleton: it processes no personal data, so the privacy frameworks do not yet apply.
| Standard | Status | Basis |
|---|---|---|
| OWASP Top 10 | Partial / not assessed | The one stubbed write path verifies a nonce and capability before reading any superglobal. No live input, query, or output paths exist yet to assess for injection or XSS; no third-party penetration test. |
| GDPR | Not applicable (yet) | The skeleton processes no personal data: no analytics, no tracking, no PII collection, no cookies set, no client-side storage. Becomes in-scope when ingestion or account features are built, and the table is re-rated then. |
| CCPA / CPRA | Not applicable (yet) | No sale or sharing of a visitor's personal information because no personal information is processed. A consumer opt-out surface is likely not applicable, but this is re-confirmed once data processing exists. |
| CRA | Partial | Secure-by-default and the doctrine guardrails are documented and bind every change; runtime dependency surface is empty. Not yet verified for Feed, no build, lint, or test pipeline is wired on the skeleton. No SBOM generation yet. |
| EAA / WCAG 2.2 AA | Not assessed | AA is the stated bar, inherited from the shared Gillish design rules. The admin surface is a stub (branding header, dashboard empty state, settings form); no formal accessibility audit has been run because there is no real UI yet. |
Data handling#
- No personal data. The skeleton processes no visitor or user personal data: no analytics, no tracking, no PII, no cookies, no client-side storage.
- Stored state. The only stored state is option stubs (feed source URLs, a webhook URL, a refresh interval) behind a typed options facade; none are personal data and none are written yet (the settings save handler is a nonce-gated stub).
- No phone-home. No activation telemetry and no anonymous usage statistics.
- Documentation site. This site self-hosts its webfont for GDPR; there is no third-party font CDN call.
- Future obligations. When ingestion or optional email intake is built, data-minimisation, opt-in, and deletion/anonymisation move from "not applicable" to in-scope and are reported here at that time.
Security measures#
- Entry points: the one stubbed write path verifies a nonce and a capability before reading any superglobal; this is the mandatory pattern for every future entry point.
- Static analysis and lint: the house bar is the strictest static-analysis level with zero errors and the WordPress-Extra ruleset. Not yet wired on the skeleton; recorded honestly rather than claimed.
- Headers and TLS: deliberately not handled by the plugin. This is correct, not a gap; the plugin layer is the wrong place for site-wide security headers.
- Secrets: none hardcoded in the plugin codebase.
- Pre-submission known issue: the Tailwind Play CDN must be replaced with a compiled local stylesheet before any wp.org submission. Known and tracked.
Accessibility#
Conformance target is WCAG 2.2 AA, inherited from the shared Gillish design rules. Not assessed: the admin chrome is a stub, so there is no real surface to audit yet. When the UI is built the bar is uniform, semantic HTML, required ARIA on dynamic components, full keyboard navigation, and a visible focus indicator on every interactive element, with suppressing the focus outline without a replacement prohibited, and verification is by exercising the real surface in a browser, since a passing test does not prove a surface is usable.
Dependencies and SBOM#
- No runtime dependencies. Feed ships no third-party runtime code and has no Composer or npm manifest; the autoloader is hand-rolled, no Composer at runtime, the house pattern.
- License audit. Every shipped third-party asset must be GPLv2-or-later compatible; this is checked before anything is added.
- SBOM: not applicable today. With no dependency manifest there is nothing to enumerate. If a manifest is introduced, a build-time CycloneDX or SPDX step and a documented dependency-review cadence are added, and not claimed as met until they ship.
Not yet assessed#
The honest gaps, listed so a reviewer can see exactly what is open. Most are deferred by design while Feed is parked:
- Every privacy obligation (GDPR, CCPA/CPRA) once the finder actually processes source data.
- A build, lint, and static-analysis pipeline wired for the Feed plugin.
- SBOM generation and an automated dependency-vulnerability audit, if and when a dependency manifest exists.
- Full third-party WCAG 2.2 AA audit once there is a real UI surface.
- A formal secure-development-lifecycle statement for CRA beyond the doctrine guardrails already in place.
Input on any of this goes back to the maintainer directly. The honest gap a reviewer can name is the most valuable thing on this page.