🔥 Private Service
Superseded — 2026-07-30
The open guest-AI authorization frontier posed here is superseded by the 2026-08-02 F-program packet, which records the operator authorizing the complete guest-AI security substrate (
2026-08-02-f-program.md:20) and a delivered disabled-by-defaultPOST /quizwizz/v1/guest-assistantroute (:45-60). Preserved as observed.
Raw chronology: 2026-07-30 private service log
One-line truth: the confirmed public debug-log exposure is closed with an edge deny policy behind it, recovery is now proven by backup and restore drill, and the open frontier is whether to authorize building the future Quiz Wizzard assistant.
🎯 Mission
| Field | Truth |
|---|---|
| Outcome | An explicit private-hosted-service boundary and a sequenced readiness plan; no plugin publication. |
| User | Private project owner and public-site operator. |
| Success | Public visitors can use only chosen QuizWizz surfaces while the service has an owner, safe ingress, recoverability, privacy disclosure, and maintenance controls. |
| Constraints | Keep plugin unpublished; no code/package/release/publish/deploy action during BBQ; do not treat WRDP bench evidence as canonical plugin-release approval. |
| Non-goals | WordPress.org distribution, plugin ZIP release, canonical-port work, signing, or claiming legal certification. |
🗺️ Territory
flowchart LR V[Public visitor] --> P[Nginx TLS proxy] P --> W[Loopback WordPress] W --> Q[QuizWizz policy and rate limits] Q --> D[MariaDB bind mount] O[Operator] --> P O --> W O --> B[Backups, monitoring, privacy, incident response]
📌 Posture of record
| Dimension | Agreed posture |
|---|---|
| Distribution | Unpublished. No plugin-repository or marketplace release; no release-eligibility claim (D-001, D-002). |
| Target deployment | One privately supplied installation on a separately operated WordPress site; packaging deferred (D-002, D-011). |
| Public surface | Full anonymous self-service on that target site, with WordPress accounts optional for saved library/stats (D-003, D-006). |
| Retention | Signed-in owners retain and delete their own quizzes indefinitely; anonymous artifacts and bearer links cap at 30 days (D-007). |
| Service level | Best-effort private public service, no SLA, without waiving security, data protection, rollback, or truthful communication (D-005). |
| External data | AI and remote banners permitted only under an approved provider/retention/disclosure/abuse policy; nothing enabled by that permission alone (D-004). |
| AI boundary today | Authorized capability-holding users only; anonymous AI stays refused (D-012, F-011). |
| Assistant provider | Future Quiz Wizzard uses direct OpenRouter with an explicitly pinned provider/model; Connector adapter deferred; no automatic fallback (D-013, F-012–F-014). |
| Site policy ownership | Operator identity, contact, Privacy, and Terms remain site-level; QuizWizz keeps minimum configuration scope (D-009). |
| Blocking gate | Public debug.log exposure is closed and proven denied; recovery and health posture are now documented, while assistant authorization remains open (F-003, F-006, F-015–F-017, R-001). |
| Bench role | WRDP remains the master source and non-public verification lab (D-010). |
✅ Confirmed truth
| ID | Fact | Grade | Evidence | Implication |
|---|---|---|---|---|
| F-001 | The current runtime is a WordPress plugin installation, but no plugin artifact needs to be distributed for one operator-controlled site to use it publicly. | E2 | wp/wp-content/plugins/quizwizz/quizwizz.php:17-50; readme.txt:15-37,52-56. | “Unpublished” can mean no plugin marketplace/archive release; it does not make the hosted service non-public. |
| F-002 | WordPress is loopback-bound; Nginx publicly terminates TLS and proxies wrdp.loca.zone to 127.0.0.1:51080. | E3 | docker-compose.yml:26-40; /etc/nginx/sites-enabled/wrdp.loca.zone:1-24; curl -I https://wrdp.loca.zone/ returned 200. | The site has a real public ingress boundary outside Compose. |
| F-003 | The former public /wp-content/debug.log exposure is remediated: WordPress now logs to /var/log/wp/debug.log in the container, the public path returns 404, and a planted in-docroot probe file also returned 404, proving the deny rule rather than only file absence. | E3 | docker-compose.yml; logs/debug.log; curl https://wrdp.loca.zone/wp-content/debug.log; planted /wp-content/deny-probe.log check. | The confirmed exposure is closed; keep the edge deny as a regression guard. |
| F-004 | Public craft, generation, PDF-preview, and play routes are deliberate anonymous workloads, bounded by payload limits and DB-backed session/network/global rate limiting. | E2 | includes/Rest/GenerateController.php:30-77,341-395; includes/Rest/QuizController.php:23-78; includes/RateLimiter.php:43-65. | The product owner must choose which guest outcomes and content controls are publicly allowed; application limits do not replace edge abuse controls. |
| F-005 | Private ephemeral quiz links are bearer credentials: a valid recipient can access the quiz until expiry; the default guest lifecycle is 24 hours. | E2 | includes/QuizAccess.php:11-73; includes/ExposureSettings.php:246-289. | Link-sharing and retention are policy decisions, not merely implementation details. |
| F-006 | WRDP now has a nightly root-owned recovery backup covering the database, wp-content, stack configuration, q5vault, scripts, and the four nginx hardening files; /home/loca/backups/wrdp/20260730T220012Z has valid image digests, a checksum manifest, and a restore drill that extracts content and replays the dump into scratch database wrdp_drill, passing all four assertions with cleanup confirmed. | E3 | scripts/wrdp-backup.sh; scripts/wrdp-restore-drill.sh; /home/loca/backups/wrdp/20260730T220012Z; restore-drill output. | Recovery is proven on-host; the residual gap is off-host copy and patch/rollback cadence. |
| F-010 | The supplied bench lacks the locked tools, lockfiles, and release/source-archive scripts that its own build documentation requires for deterministic ZIP output. | E3 | wp/wp-content/plugins/quizwizz/BUILDING.md:7-12,64-104; exact-path availability check found none of tools/toolchain.json, package-lock.json, composer.lock, tools/build-release.py, or tools/build-source-archive.py. | A private target-site ZIP is a deployment artifact with a separate reproducibility/verification design; it cannot be honestly produced through the documented canonical pipeline from this bench. |
| F-007 | The stack uses wordpress:latest, has WP_DEBUG enabled, disables the authenticated WordPress file editor through DISALLOW_FILE_EDIT, and bind-mounts the entire WordPress tree read-write. | E2 | docker-compose.yml:20-22,33-44. | The disabled editor narrows one public-admin attack surface, but current bench mutability remains inappropriate as an ungoverned public-service baseline. |
| F-008 | Privacy exporter/eraser hooks and suggested policy copy exist, but source evidence does not establish a visitor-visible notice matching enabled AI, remote-banner, cookie, and retention behavior. | E2 | includes/Admin/Privacy.php:19-34,56-235; readme.txt:65-71. | Public operation needs a site-owned notice and an explicit feature/data policy. |
| F-009 | The current bench is release-ineligible because canonical source/provenance, locked pipeline, dataset review, and some notice evidence are missing. | E2 | SOURCE-PROVENANCE.md:3-27; BUILDING.md:64-91; THIRD-PARTY-NOTICES.md:17-62. | This blocks plugin distribution claims; it does not substitute for a hosted-service readiness decision. |
| F-011 | Current QuizWizz AI is a direct, non-streaming OpenRouter client; it accepts only authenticated, capability-authorized users and returns validated, unsaved question drafts. There is no front-end AI chat or library-search assistant. | E2 | includes/Ai/{OpenRouterClient,RequestContext,Ability}.php; includes/Rest/QuizLibraryController.php. | “Quiz Wizzard” is a new assistant surface, not an existing AI setting. |
| F-012 | WordPress 7.0.2 Connectors supplies admin-only connector credential management and an AI-client registry, but this installation has no evidenced configured provider. It does not supply application authorization, guest controls, usage budgets, chat state, or execution-time fallback. | E3 | wp-admin/options-connectors.php; wp-includes/{connectors,ai-client}.php; installed provider registry inspection. | Connectors can be a future provider adapter; it cannot replace QuizWizz’s policy and controls. |
| F-013 | A hypothetical guest context would collapse every visitor to actor_id=0; the current date-only AI ledger also shares one daily budget with authorized features. | E2 | includes/Ai/{RequestContext,AiBudget}.php; includes/Installer.php; reviewer audit. | Guest AI cannot safely reuse the present authenticated AI substrate. |
| F-014 | Core AI model preference silently chooses a first discovered candidate when no match exists and executes only one call; it provides no reliable provider pinning or retry fallback. | E2 | wp-includes/php-ai-client/src/Builders/PromptBuilder.php:812-836,1181-1185. | A professional multi-provider policy must be explicitly owned by QuizWizz. |
| F-015 | The deployed edge policy denies logs, dumps, archives, editor droppings, dotfiles except ACME, uploaded/upgrade PHP, XML-RPC, and legacy packaging files; it adds app security headers and an operator-exempt wrdp_login ceiling at 1r/s burst=10 returning 429. | E3 | /etc/nginx/sites-available/wrdp.loca.zone; /etc/nginx/snippets/wrdp-proxy.conf; /etc/nginx/snippets/security-headers-app.conf; /etc/nginx/conf.d/wrdp_limits.conf; live ingress checks. | Path-deny, header, and credential-endpoint controls are now in force; WAF and edge log/alert policy remain separate future controls. |
| F-016 | Apache mod_remoteip is loaded and trusted for the 172.31.0.0/16 compose network; nginx sends X-Forwarded-For: $remote_addr; RateLimiter::client_ip() returns REMOTE_ADDR directly because quizwizz_trusted_proxies has no subscriber. | E3 | /etc/apache2/conf-available/remoteip.conf; apache2ctl -M; docker network inspect wrdp_wrdp_net; includes/RateLimiter.php:160-189; container access logs. | The plugin’s per-network rate limiting depends on mod_remoteip; the audit concern that all visitors share one bridge-gateway /24 bucket does not apply to this bench. |
| F-017 | The public debug-log exposure is remediated as a distinct verified closure fact: WordPress writes the live log outside the document root at /var/log/wp/debug.log, https://wrdp.loca.zone/wp-content/debug.log returns 404, and a planted in-docroot probe file also returned 404. | E3 | docker-compose.yml; logs/debug.log; curl -I https://wrdp.loca.zone/wp-content/debug.log; planted /wp-content/deny-probe.log check. | R-001 is remediated for the bench; health checks keep the denial path as a regression guard. |
🧭 Decisions
| ID | Status | Choice / next decision | Depends on | Unlocks |
|---|---|---|---|---|
| D-001 | settled | Do not publish or distribute a plugin artifact from WRDP. | Prior user direction and release boundary. | Keeps canonical release work out of scope. |
| D-002 | settled | Use a private ZIP only to install QuizWizz on one separately operated WordPress site; its frontend will be public, but the plugin will not be published to a repository or marketplace. | User direction. | Reframes the objective as a private hosted-service deployment, not a canonical plugin release. |
| D-003 | settled | Expose full self-service to public visitors on the single target site. | User direction. | Requires a deliberately bounded public builder/PDF/key/upload/fine-tune policy and service-grade abuse controls. |
| D-004 | settled | Enable AI and remotely fetched banners only under approved policies covering provider/data flow, retention, visitor disclosure, abuse/budget controls, and support handling. | User direction. | External-data features may be designed into the target policy; nothing is enabled by this decision alone. |
| D-005 | settled | Operate as a best-effort private public service without a formal SLA. | User direction. | Does not waive minimum security, data protection, rollback, or truthful public communication requirements. |
| D-006 | settled | Allow anonymous full self-service with optional WordPress accounts for saved library/stats. | User direction. | Requires truthful guest-retention disclosure, anonymous abuse controls, and secure account operations. |
| D-007 | settled | Signed-in owners may retain and manually delete their quizzes indefinitely; anonymous visitors retain full self-service with generated artifacts/links capped at 30 days. | User direction. | Resolves durable ownership while bounding anonymous bearer-link exposure. |
| D-008 | settled | Recover the canonical source/toolchain and produce a reproducible checksumed private deployment package without publishing it. | User direction. | Canonical source/pipeline recovery is now an external prerequisite before target-package work. |
| D-009 | settled | Site-level operator identity, contact, Privacy, Terms, and best-effort posture are already handled by the running project; QuizWizz work stays at the minimum configuration/integration scope. | User direction. | Avoids duplicate plugin policy/support pages while requiring target settings to match the existing site policy. |
| D-010 | settled | WRDP itself is the master QuizWizz project. Its missing locks/package scripts are therefore gaps to establish in the master project, not an external repository to recover. | User direction plus source inspection. | Reframes canonical-pipeline recovery as a new private packaging-foundation decision. |
| D-011 | deferred | Private-package work is intentionally deferred; no separate builder or target ZIP will be created now. | User direction. | The present alignment remains plugin-scope planning only. |
| D-012 | settled | Preserve authorized-user-only AI now. A future administrator setting may explicitly enable an unregistered visitor-facing “Quiz Wizzard” that finds or crafts quizzes. | User direction. | Separates today’s controlled AI from the future public-assistant feature. |
| D-013 | settled | Future Quiz Wizzard starts with direct OpenRouter using an explicitly pinned provider/model. Connector support is deferred until a compatible provider is installed and verified. | User selection; F-012–F-014. | Deterministic initial provider/data-flow boundary. |
| D-014 | settled | Finding plus unsaved crafting, but only behind the hard guest-AI gate: cookie-bound guest identity distinct from actor_id 0; guest-only operation allowlist; separate guest daily budget defaulting to zero and keyed independently of the site budget; explicitly pinned provider/model with openrouter/auto refused; no guest path reaching persistence or publishing; bounded audit record; guest readiness predicate surfaced in Site Health. | User authority; R-005–R-006; F-013–F-014. | Defines the future assistant prerequisite list without authorizing implementation. |
| D-015 | deferred | Define the external-data and maintenance runbook: remote-banner sources, abuse and budget caps, package verification procedure, and best-effort cadence. | D-014; public-launch decision. | Keeps the remaining provider/data/runbook work explicit and out of silent scope creep. |
⚠️ Assumptions, conflicts, risks
| ID | Type | Statement | Owner/check | Impact |
|---|---|---|---|---|
| R-001 | remediated | debug.log was publicly readable, but the live log now lives outside the document root and the public path plus planted in-docroot probe return 404. | Keep logs/debug.log as the only follow path and retain the deny rule as a health-check regression guard. | Critical information exposure closed for the bench. |
| R-002 | boundary conflict | Release NO-GO addresses a distributable plugin; it is not a public-hosted-service authorization or operating model. | Resolved as a private target-site deployment; do not claim canonical release status. | Prevents false readiness. |
| R-003 | narrowed evidence gap | Path-deny, app security headers, client-IP trust, and a login ceiling now exist; what remains unproven is WAF/bot policy plus proxy access-log retention, review, and alerting. | Future operations decision. | Residual public ingress and abuse risk. |
| R-004 | narrowed evidence gap | On-host backup and restore drill are proven; the drill does not cover off-host copies, patch cadence for moving images, or rollback for a bad image. | Future operations decision. | Residual availability/recovery risk. |
| R-005 | confirmed design blocker | Guest AI needs a distinct cookie-bound guest identity, guest-only operation scope, separate bounded budget, pinned provider/model, and an explicit readiness gate; a logged-out nonce is not an anti-automation control. | Resolve only in a future authorized feature design. | Prevents one visitor from spending/starving AI for all visitors or silently changing processors. |
| R-006 | confirmed design constraint | A fallback may retry only narrow transient failures, must share one logical budget reservation, and must never silently substitute an unreviewed provider/model. | Future provider-policy design. | Prevents duplicate charging, accidental data routing, and 500s. |
| A-001 | settled interpretation | “Private project” means one operator-controlled hosted service and a privately supplied target-site ZIP, not repository/marketplace publication. | User direction. | Scope and policy boundary. |
🐝 Swarm digest
| Wave | Domains | New truth | Remaining gap | Why next wave? |
|---|---|---|---|---|
| 1 | Exposure, operations, product boundary, skeptical audit | Public route model, release-vs-service distinction, debug-log risk, recovery/privacy gaps. | Actual Nginx and public response posture. | Critical ingress fact was system-answerable. |
| 2 | Ingress discrimination | Nginx proxy/TLS confirmed; public debug-log 200 confirmed. | Service intent and owner authority. | Remaining top dependency is user-owned. |
| 3 | Connectors, QuizWizz AI, adversarial review | Connectors is not a provider router; present AI is authorized-only; guest AI needs a separate safe substrate. | Future provider-policy choice. | User asked for the professional default/fallback posture. |
❓ Next best question
Q-015: Authorize building the future Quiz Wizzard assistant under the settled guest-AI gate, or keep the assistant deferred?
Established constraint: D-014 permits finding plus unsaved crafting only after all seven prerequisites exist: cookie-bound guest identity distinct from actor_id 0; guest-only operation allowlist; separate zero-default guest daily budget keyed independently of site budget; explicitly pinned provider/model with openrouter/auto refused; no guest persistence/publishing path; bounded audit record; and Site Health readiness predicate.
Recommended default: keep implementation deferred until the owner explicitly chooses to spend on the assistant and accepts the provider/privacy/runbook work.
Decision options: (1) authorize implementation under the full gate; (2) keep it deferred.
📦 Launch packet
- Acceptance criteria: public log exposure remains denied; restore drill and health probe stay green; assistant implementation remains blocked until Q-015 is answered.
- Implementation constraints: no plugin distribution; no claims of plugin release readiness; WRDP remains a bench-local source with
releaseEligible: false; a target-site ZIP must be clearly labeled noncanonical and development-ineligible until a separate reproducible packaging method is available. - Future guest-assistant constraints: off by default; cookie-bound guest identity distinct from
actor_id 0; guest-only operation allowlist; separate zero-default guest budget keyed independently from site budget; pinned provider/model withopenrouter/autorefused; no guest persistence/publishing path; bounded audit record; guest readiness predicate in Site Health. - Verification: already proven for the bench hardening boundary: metadata-only public ingress denial, planted deny-probe denial, backup restore drill, health checks, and scheduler evidence; future target-site install and policy/role review remain separate.
- Rollback: preserve WRDP as a non-public verification lab; disable the assistant before changing provider policy; remove the target-site ZIP rather than attempting an unverified in-place downgrade.
- Deferred: distribution provenance, canonical pipeline, signing, plugin-directory publication.
🔗 Sources
docker-compose.yml:20-45— runtime binding, mutable WordPress configuration, debug settings and relocated debug log./etc/nginx/sites-available/wrdp.loca.zone;/etc/nginx/snippets/wrdp-proxy.conf;/etc/nginx/snippets/security-headers-app.conf;/etc/nginx/conf.d/wrdp_limits.conf— live edge deny, security-header, proxy, and login-ceiling policy.curl -I https://wrdp.loca.zone/wp-content/debug.log; planted/wp-content/deny-probe.logcheck — remediated public debug-log exposure and proof that deny rules fire even when a matching file exists.wp/wp-content/plugins/quizwizz/includes/{ExposureSettings,QuizAccess,RateLimiter}.php— guest policy, bearer access, and workload controls.wp/wp-content/plugins/quizwizz/includes/Ai/{Ability,OpenRouterClient,RequestContext,AiBudget}.php— current authorized AI boundary and its guest-design limits.wp/wp-admin/options-connectors.php;wp/wp-includes/{connectors,ai-client}.php;wp/wp-includes/php-ai-client/src/Builders/PromptBuilder.php— Connector/AI-client capability and fallback limits.wp/wp-content/plugins/quizwizz/includes/Admin/Privacy.php— privacy hooks and data disclosures.wp/wp-content/plugins/quizwizz/{SOURCE-PROVENANCE,BUILDING,THIRD-PARTY-NOTICES}.md— distribution/release boundary.