Skip to content

Add Dev Monitor — 7 collector interfaces #17

Description

@AnuragVasanwala

Context

Dev Monitor is the unified developer-tools panel that lives inside wp-php-toolkit (gated by {PREFIX}_DEV_MODE, never loaded in production, excluded from release artifacts via .distignore). It runs an Issues Stream, a Tools bar, a Visual Timeline, and an AI context plane (Sprint 4 plan, gated on WP 7.0).

Before any of the 14 collectors can be implemented (Sprint 3), the contracts they implement must exist. This issue ships the seven interfaces every collector or panel renderer reads from.

The interfaces are deliberately small (1 to 4 methods each). Their job is to make collector implementations interchangeable — the panel never special-cases an individual collector, it iterates over collectors that implement a given interface.

Expected Outcome

A new src/Dev/Interfaces/ namespace with seven PHP interfaces and one shared unit test that asserts every interface is loadable and matches the documented contract.

Files added:

src/Dev/Interfaces/Collector_Interface.php
src/Dev/Interfaces/Profilable.php
src/Dev/Interfaces/Stoppable.php
src/Dev/Interfaces/Renderable.php
src/Dev/Interfaces/Issue_Provider.php
src/Dev/Interfaces/AI_Context_Provider.php
src/Dev/Interfaces/Timeline_Event_Provider.php
tests/Dev/Interfaces/InterfacesTest.php
CHANGELOG.md (Unreleased entry)

Interface contracts:

namespace RtCamp\WPToolkit\Dev\Interfaces;

interface Collector_Interface {
    public function id(): string;                    // unique slug, e.g. "queries"
    public function label(): string;                 // human label for the Tools bar
    public function is_enabled(): bool;              // honours per-collector Feature_Selector flag
    public function setup(): void;                   // wire WordPress hooks
}

interface Profilable {
    public function start(): void;                   // begin timing/measurement
    public function stop(): void;                    // end timing/measurement
    public function summary(): array;                // [ 'time_ms' => float, 'memory_kb' => int, ... ]
}

interface Stoppable {
    public function should_stop( array $context ): bool;   // hard kill switch (e.g. infinite loop guard)
}

interface Renderable {
    public function render(): string;                // HTML for the collector's panel tab
}

interface Issue_Provider {
    public function issues(): array;                 // array of [ 'severity' => 'error|warning|notice', 'message' => string, 'context' => array ]
}

interface AI_Context_Provider {
    public function ai_context(): array;             // metadata only — counts, timings, pattern names. NEVER raw SQL/errors/user data.
}

interface Timeline_Event_Provider {
    public function timeline_events(): array;        // array of [ 'ts_ms' => int, 'label' => string, 'phase' => string, 'meta' => array ]
}

Test shape:

A single PHPUnit test that uses Reflection to assert each interface declares the methods listed above with the correct return types. No behaviour to test — interfaces have no behaviour. Purpose is to lock the contract so a future PR cannot silently change a method signature.

Verification commands (all must exit 0):

composer install
composer phpcs src/Dev/Interfaces/ tests/Dev/Interfaces/
composer phpstan
composer test -- tests/Dev/Interfaces/InterfacesTest.php

Implementation guidance

Self-contained brief. These are pure-contract interfaces — no behaviour to implement here.

Step-by-step

  1. Create the namespace folder src/Dev/Interfaces/.
  2. Add each of the seven interface files with a class-level docblock and the documented method signatures only. No method bodies, no constants.
  3. Use strict types at the top of every file: declare(strict_types=1);.
  4. Use full FQCN in @param / @return doc-blocks where the type is an array shape (e.g. array<int, array{ts_ms: int, label: string, phase: string, meta: array<string, mixed>}>).
  5. Write the AI privacy docblock prominently in AI_Context_Provider.php: include the literal sentence "Implementations MUST return metadata only. SQL, error strings, user input, and any user-identifiable data are forbidden." Reviewers will look for this exact line.
  6. Build the Reflection test. One PHPUnit class with one test method per interface. Each test asserts:
    • interface_exists()
    • Each documented method exists (->hasMethod())
    • Each method signature matches (parameter types + return type via ReflectionMethod)
  7. Run the local checks: PHPCS, PHPStan, PHPUnit. All green before pushing.

Reference patterns

<?php
declare(strict_types=1);

namespace RtCamp\WPToolkit\Dev\Interfaces;

/**
 * Collectors implement this to feed the AI context plane.
 *
 * Implementations MUST return metadata only. SQL, error strings, user input,
 * and any user-identifiable data are forbidden. AI_Data_Sanitizer is the
 * defence-in-depth pass; this contract is the first line.
 */
interface AI_Context_Provider {

    /**
     * @return array<string, mixed> Structured metadata. Counts, timings, pattern names only.
     */
    public function ai_context(): array;
}
// Reflection test pattern
public function test_ai_context_provider_has_ai_context_method(): void {
    $reflection = new \ReflectionClass( AI_Context_Provider::class );
    $this->assertTrue( $reflection->isInterface() );
    $this->assertTrue( $reflection->hasMethod( 'ai_context' ) );

    $method = $reflection->getMethod( 'ai_context' );
    $return_type = $method->getReturnType();
    $this->assertNotNull( $return_type );
    $this->assertSame( 'array', (string) $return_type );
}

Edge cases

  • Do not add default method implementations (interface does not allow them in PHP 8.3 in our context — and even if it did, contracts must stay pure).
  • Do not import anything from WordPress core in the interface files. Interfaces are framework-agnostic.
  • Do not add a setup() default to Collector_Interface (the Singleton trait pattern is class-side, not contract-side).

Pre-PR self-check

  • All 7 interface files created at the documented paths
  • declare(strict_types=1); on every file
  • AI privacy sentence verbatim in AI_Context_Provider.php
  • Reflection test passes for all 7 interfaces
  • composer phpcs, composer phpstan, composer test all green
  • CHANGELOG entry under ## Unreleased

Acceptance Criteria

  • All 7 interfaces created at the paths above with the exact method signatures documented
  • All interfaces in namespace RtCamp\WPToolkit\Dev\Interfaces
  • Each interface has a class-level docblock explaining what it represents and which collectors are expected to implement it
  • PHPCS passes on the new files
  • PHPStan level 5 passes
  • Reflection test verifies all method signatures
  • AI privacy note in AI_Context_Provider docblock: "Implementations MUST return metadata only. SQL, error strings, user input, and any user-identifiable data are forbidden."
  • CHANGELOG.md entry added under ## Unreleased

Notes

  • Depends on the Singleton trait merged (collectors will use it).
  • Depends on the PHPCS baseline (Add shared PHPCS baseline (phpcs.xml.dist) #15) and PHPStan baseline (Add shared PHPStan baseline (phpstan.neon.dist) #16) merged (this PR runs against them).
  • AI implementation itself is plan-only in Sprint 4 — the interface ships now so collectors can implement it and the panel can call it once AI flow lands.
  • The 14 collector implementations are individual issues in Sprint 3 (they all consume these interfaces).
  • PR target: release/v1.0.0. Branch: v1.0.0/task/dev-monitor-interfaces. Commit subject: feat(dev): add Dev Monitor collector interfaces.

Metadata

Metadata

Assignees

No one assigned

    Labels

    Priority: P1High — sprint commitmentScope: Collector Interfaces7 interfaces in src/Dev/Interfaces/Type: TaskSelf-contained unit of work for a milestone

    Type

    No type

    Projects

    No projects

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions