Commit Graph

16 Commits

Author SHA1 Message Date
peptiderepo
5da4e0fed6 ci: adopt estate CI standard — thin caller + wp-framework PHPUnit + 300-line split
- ci.yml: thin caller → peptide-e2e reusable (tests: wp-framework, has_js: true, line_limit_paths: inc)
- deploy.yml: retire standalone validate; gate deploy on ci.yml via workflow_call
- composer.json: test script → vendor/bin/phpunit (explicit)
- inc/helpers.php: split 311→211 lines; nav walker extracted to nav-walker.php
- inc/nav-walker.php: new — Peptide_Starter_Nav_Walker + menu fallback (123 lines)
- functions.php: require nav-walker.php before helpers.php; version 2.2.2→2.3.0
- style.css: version header 2.2.2→2.3.0
- package.json / package-lock.json: minimal npm manifest for lint-js job

Agent-Session: claude/adopt-ci-20260616
2026-06-16 20:57:25 +07:00
peptiderepo
2b23bb7e2a feat: RCT inline abbreviation tooltip on verdict legend strip (v2.2.1) (#53)
CI green (PHP Lint 8.1/8.2/8.3 ✓, PHPCS ✓, PHPUnit 8.1/8.2/8.3 ✓). QA: PASS.
2026-04-29 13:29:04 +07:00
peptiderepo
aecb4bd1cb fix: PHPCS verdict-meta.php — fix all over-tabbed array keys + for-loop body indent
Four more 'single' keys had incorrect tab counts (same over-indentation
pattern as line 37 fixed in prior commit):
- Line 52 (verdict_text registration): 6 tabs → 3
- Line 66 (signal_row text, inside for loop): 8 tabs → 4
- Line 80 (signal_row glyph, inside for loop): 8 tabs → 4
- Line 97 (has_partner_link): 6 tabs → 3

For-loop body lines 173–175: were at 3 tabs (same level as the 'for'
statement); PHPCS requires body to be indented one level deeper → 4 tabs.

All pre-existing violations in verdict-meta.php are now cleared.
2026-04-26 04:34:09 +00:00
peptiderepo
08dc8480ba fix: PHPCS — replace multi-line HTML comments, fix verdict-meta array indent + PHP tag
front-page.php:
- Replace 3 decorative multi-line HTML comment blocks (tab+space mixed
  indentation) with single-line <!-- SECTION --> comments; eliminates 16
  'Tabs must be used' PHPCS errors at lines 37-41, 93-97, 127-132

inc/verdict-meta.php:
- Line 37: correct over-indented 'single' key (6 tabs → 3 tabs to match
  array alignment of sibling keys)
- Line 171: split '<?php for (...)' onto two lines so opening PHP tag is
  on a line by itself (WordPress PHPCS requirement)

Both are pre-existing violations now exposed because CI runs PHPCS on all
PHP files (not just changed ones). No functional change.
2026-04-26 04:32:27 +00:00
peptiderepo
3942c6b29e v2.1.0 fix — tabs, split verdict helpers, PHPCS clean
- Convert space indentation → tabs in front-page.php (PHPCS)
- Extract verdict taxonomy + config arrays → inc/verdict-helpers.php
- Wire verdict-helpers.php into functions.php
- front-page.php now 254 lines (was 309)
2026-04-26 04:26:59 +00:00
peptiderepo
4188bba014 v2.1.0 — Brand token adoption + homepage verdict sections
- Remap --color-brand-primary/--color-link-hover/--focus-shadow → teal tokens
- Hero search submit → lime-500/ink (CMO brief §6)
- Hero decorative shapes → teal/lime tints
- Hero wavy underline → teal
- front-page.php: verdict taxonomy explainer (5 states) + featured verdict cards
- inc/helpers.php: new brand copy defaults (hero title + subtitle)
2026-04-26 04:22:04 +00:00
peptiderepo
7b5f992a2a fix: CMO walkthrough P1 fixes — verdict_text, per-row glyphs, conditional disclosure, dark mode (v2.0.0-alpha.3)
P1.1: verdict_text meta field + card.php wiring
- Register verdict_text (textarea, show_in_rest) on peptide CPT
- card.php reads verdict_text meta; falls back to placeholder if empty
- Hardcoded generic placeholder no longer the default for published posts
- All 3 monographs populated with CMO-authored verdict text

P1.2: per-row glyph meta fields
- Register signal_row_1/2/3_glyph (enum: ✓|!|?|⊘|⚠, show_in_rest)
- card.php reads per-row glyph from meta instead of hardcoding by position
- Missing glyph renders nothing (not a wrong glyph)
- Semaglutide: ✓✓! | BPC-157: ✓!? | Melanotan-II: !!⚠

P1.3: conditional inline disclosure
- Register has_partner_link (boolean, default false, show_in_rest)
- single-peptide.php only renders inline disclosure when has_partner_link=true
- All 3 loaded monographs set to has_partner_link=false
- Footer disclosure unaffected (always renders)

N.1: dark mode toggle hidden
- header.php: toggle button hidden (display:none + aria-hidden)
- Dark-mode verdict colors not validated for v1; re-enable in v1.1

Meta box updated with textarea, glyph dropdowns, and partner-link checkbox.
2026-04-26 02:12:35 +00:00
peptiderepo
2fe536208b fix: correct CPT slug in verdict-meta.php (pr_peptide -> peptide)
The engineer registered verdict meta and the meta box against 'pr_peptide'
which does not exist. PR Core registers the CPT as 'peptide'. Result: the
verdict meta box was invisible in wp-admin and meta was not exposed in REST.
All functional register_post_meta and add_meta_box calls now target 'peptide'.
No data migration needed — post meta is keyed by meta_key, not CPT.
2026-04-25 20:35:14 +00:00
peptiderepo
e23c141009 feat: brand identity v1.0.0 — Direction C Trusted Guide (theme v2.0.0-alpha.1)
Implements weeks 1–4 of the CMO brand identity sprint.

Key changes:
- CSS token system (assets/css/brand.css): full palette, verdict tokens, component styles
- Poppins/Inter/IBM Plex Mono Google Fonts loading with preload
- Full favicon/PWA/OG asset pack (peptide-repo-brand v1.0.0)
- 5-state verdict badge + card + evidence row components
- verdict_state + signal_row post meta on pr_peptide CPT
- Homepage hero: teal bg, new H1/subhead, lime search bar
- Archive verdict filter chips (CSS + pre_get_posts query hook)
- Affiliate disclosure component (3 contexts)
- page-how-we-review.php + page-about.php templates
- Footer Our Method links
- a11y: skip-to-content, reduced-motion, aria on verdict badges

QA: PASS (0 blockers) — qa-reviews/peptide-starter-theme/2026-04-26-a2bff59.md
Staging verified: https://staging.peptiderepo.com
2026-04-26 02:59:00 +07:00
peptiderepo
a1917d62c2 chore: remove WooCommerce from theme — not used on peptiderepo.com (v1.7.0)
Remove all WC asset dequeue logic, cart icon conditional, and WC-specific tests from the theme. Eliminates the class of fatal errors seen in the 2026-04-23 incident where is_woocommerce() was called after WC deactivation.

Version: 1.6.x → 1.7.0
Reviewed-by: peptiderepo (CTO)
QA: qa-reviews/peptide-starter-theme/2026-04-23-d239bd1e.md
2026-04-24 01:37:31 +07:00
peptiderepo
0c5db51739 fix: guard is_woocommerce() with function_exists() — fatal when WC not active
Call to undefined function is_woocommerce() in perf-asset-policy.php:69
caused a 500 on all page loads. WooCommerce is not active on this site.
Added function_exists() guard so the WC asset dequeue block is skipped
when WooCommerce is not installed.
2026-04-23 23:50:44 +07:00
peptiderepo
d79fc94061 feat(perf): mobile performance Phase 1 — dequeue unused plugin assets + slim fonts + preconnect (#13)
Ships peptide-starter-theme v1.6.0.

Changes:
- New inc/perf-asset-policy.php module: conditional dequeue of WC/Elementor/USMI assets on pages that do not need them, Google Fonts weight slim (Roboto 100..900 → 400/500/700; Roboto Slab → 400/700), wp_resource_hints preconnect for fonts.googleapis.com + fonts.gstatic.com, cookie-notice-front script defer.
- Kill-switch constant PEPTIDE_STARTER_PERF_DEQUEUE (default true) for instant rollback via wp-config.php.
- 4 extensibility filters: peptide_starter_perf_woocommerce_{styles,scripts}, _elementor_{styles,scripts}, _usmi_{styles,scripts}, _font_weights.
- 13 unit tests in tests/test-perf-asset-policy.php.
- Bootstrap: 2 lines in functions.php (require + after_setup_theme action).
- Docs: CHANGELOG [1.6.0], ARCHITECTURE.md, CONVENTIONS.md how-to.

Target: mobile PSI 74 → 90+, LCP 5.4s → ~2.5s.

Post-deploy: purge LiteSpeed CSS bundle.

QA: qa-reviews/peptide-starter-theme/2026-04-23-a54b5c9.md (APPROVE with handle-drift verified false-positive).
2026-04-23 13:24:47 +07:00
peptiderepo
fff3fce432 v1.5.2: CF-peer validated client IP, grandfather migration, de-short-circuit register
Security follow-up to v1.5.1. Closes four items from the v1.5.1 review —
two ship-blockers and two mediums — all within the ADR-0001 envelope.

PSEC-007 — peptide_starter_get_client_ip() now trusts CF-Connecting-IP
only when REMOTE_ADDR falls inside a published Cloudflare edge range.
Previously, any direct-to-origin request (which Hostinger permits) could
forge its rate-limit key by setting the header to a different IP per
attempt, bypassing every abuse control in the theme. New module
inc/cloudflare-ips.php embeds a dated snapshot of CF v4/v6 ranges and a
CIDR matcher covering both families; list is overridable via the
peptide_starter_cloudflare_ip_ranges filter for out-of-band updates.
HTTP_X_FORWARDED_FOR stays ignored unless operators opt in via the
peptide_starter_trust_xff filter.

PSEC-008 — Removed the v1.5.1 user-verification migration (Option A as
confirmed by peptiderepo). The sync-wp_mail-per-subscriber loop on
admin_init would have blocked wp-admin and hammered deliverability.
Existing accounts are now grandfathered: no ps_pending_verification
meta = verified. Verification applies only to registrations from v1.5.2
forward. The ps_verify_migration_version option (written by v1.5.1) is
cleared on theme activation.

PSEC-009 — Registration validation no longer short-circuits. All five
checks (username pattern, email validity, password length,
username_exists, email_exists) evaluate unconditionally before the
combined rejection. Closes the response-time oracle that let an
attacker distinguish microsecond-fast regex rejection from DB-round-trip
rejection and infer which field triggered the failure.

PSEC-010 — Added the happy-path verify test that v1.5.1 was missing.
Covers token match, user meta cleanup, auth cookie set, and the
peptide_starter_user_verified action firing with the correct user ID.

Seven new rate-limiter tests confirm CF-peer validation works
end-to-end: trusted CF peer honours the header, untrusted peer ignores
spoofed headers, invalid values fall through, XFF default-off, XFF
filter opt-in, CF range filter override, IPv6 CIDR match, family
mismatch rejection.

Confirmed with peptiderepo before coding: (1) Option A for PSEC-008
because zero users; (2) Cloudflare IS in front of the origin (dig
confirms 104.21.x / 172.67.x + CF-Ray response header), so PSEC-007 is
a real fix not dead code; (3) no staging — treat prod as staging.

ARCHITECTURE.md gains a client-IP trust model section; CONVENTIONS.md
documents the header-trust rules for future modules.

Version bumped to 1.5.2 in style.css and functions.php.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-04-14 15:39:09 +07:00
peptiderepo
cb8b73f4ab v1.5.1: frontend auth hardening — rate limiting, email verification, honeypots, CSV safety
Security-only release per ADR-0001. Closes all six ship-blockers from the
post-v1.5.0 audit: PSEC-001 (no rate limiting), PSEC-002 (account
enumeration via separate error messages), PSEC-003 (registration auto-login
with no email verification), PSEC-004 (ungated "My Data" templates),
PSEC-005 (CSV formula injection on subscriber export), PSEC-006 (no
honeypot/CAPTCHA on public forms).

Adds inc/config.php (single source of truth for all security thresholds,
filterable via peptide_starter_security_config), inc/rate-limiter.php
(Peptide_Starter_Rate_Limiter + Cloudflare-aware client IP resolver,
transient-backed, never stores raw IPs), and inc/email-verification.php
(43-char token, 24h TTL, /verify rewrite, rate-limited resend endpoint).

Auth handlers rewritten to: unify all failure messages, rate-limit before
any expensive check, drop registrations with a filled honeypot silently,
stop auto-login on register, send a verification email instead. The
require_login() helper lives in inc/helpers.php and is applied at the top
of page-tracker.php, page-subject-log.php, and page-protocol-builder.php;
page-calculator.php stays open (no PII, no writes).

Newsletter signup gains: consent checkbox, privacy link, honeypot,
autoload=false on the wp_options blob, unsubscribe token stored per row,
/newsletter-unsubscribe route, merged success+duplicate into a single "ok"
state. Admin export runs every cell through peptide_starter_csv_safe()
which prefixes leading =/+/-/@/tab/CR with a quote.

Contact handler hardens against email-header injection (rejects name
values with \r \n , < >), rate-limits, honors honeypot, tags mail
failures with a request ID for correlation without logging message
content.

Adds Tools → Mail Test (inc/mail-diagnostic.php): a permanent wp_mail
probe so we can check Hostinger outbound deliverability any time it looks
flaky. Adds a one-time admin_init migration that enrols pre-v1.5.1
subscribers into the verification flow (currently a no-op — zero users —
but guarded for the future).

Other cleanup from the audit: fallback primary menu moved out of
header.php into inc/helpers.php (redeclaration risk), placeholder footer
language links replaced with "Translations coming soon", footer copyright
now reads through the customizer getter, settings-panel gains a proper
Tab/Shift+Tab focus trap and saves/restores body overflow, documentation
heading IDs slugified from heading text with collision counters, JS files
standardized on const/let.

Six new PHPUnit suites cover rate limiter lifecycle, auth handler error
unification and rate limits, email verification token generation and
expiry, contact handler header injection + rate limit + honeypot,
newsletter signup consent + CSV safety, and require_login gate behavior.

ARCHITECTURE.md and CONVENTIONS.md updated in the same commit — new
module layout, data flows, security patterns for rate-limiting,
honeypotting, gating, and CSV-safe export.

Version bumped to 1.5.1 in style.css and functions.php.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-04-14 13:01:22 +07:00
peptiderepo
d28d5f45d5 fix: PHPCS multi-line function call signature violations in customizer.php
Reformat add_setting() and add_control() calls to comply with
PEAR.Functions.FunctionCallSignature — each argument on its own line,
opening paren last on line, closing paren on its own line. Matches the
pattern already used by add_section() calls in the same file.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-04-14 12:24:52 +07:00
peptiderepo
9da702e746 v1.5.0: extend theme with navigation dropdowns, 9 page templates, auth UI, newsletter, contact panel
Major theme extension adding full-featured navigation with dropdown submenus (Tools, My Data, Resources),
9 new page templates (Calculator, Protocol Builder, Tracker, Subject Log, Documentation, Directory,
Science Feed, Profile, Sign In/Register), documentation page with sidebar ToC and scroll spy,
branded AJAX authentication forms, newsletter signup with admin export, slide-out contact/support panel,
Research Modules 6-card grid on front page, and comprehensive footer update.

Split functions.php (554→206 lines) into 6 focused inc/ modules: helpers, customizer, auth-handlers,
contact-handler, page-setup, newsletter-admin. All new components include dark mode support, CSRF
protection, input sanitization, output escaping, and graceful plugin degradation via shortcode_exists().

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-04-14 08:38:30 +07:00