Skip to content

Latest commit

Β 

History

History
523 lines (393 loc) Β· 37.8 KB

File metadata and controls

523 lines (393 loc) Β· 37.8 KB

SPARXSTAR Sirius β€” Implementation Tracker

Scoreboard: Does the implementation fully represent the spec layer it claims to align to?

This document tracks every component defined in Sirius Context Engine Spec v3.0 against its build state, assigns it to a sprint, and surfaces what work remains. Update this file as sprints close.


Legend

Symbol Meaning
βœ… Built, tested, merged
🟑 Built, not yet tested
πŸ”² Specified, not yet built
⏳ Blocked on external dependency
πŸ—‘οΈ Scheduled for removal (replaced by upstream)

Scoreboard β€” Spec v3.0 Components

Core Engine

Component File Status Sprint Notes
ContextEngine::current() src/core/ContextEngine.php βœ… S-01 Throws ContextBootException, never null/partial
CLI system context src/core/ContextEngine.php βœ… S-01 SYSTEM/GLOBAL/CLI path
SirusContext DTO src/core/SirusContext.php βœ… S-01 Includes trust_score; trust_level typed as TrustLevelPrimitive enum
ContextCache src/core/ContextCache.php βœ… S-01 Cache + TTL eviction
ContextBootException packages/sparxstar-ouroboros-integrity/src/Exceptions/ContextBootException.php βœ… S-04 Migrated to Ouroboros CO-001 β€” Starisian\Sparxstar\Infrastructure\Exceptions
ContextPulse DTO packages/sparxstar-ouroboros-integrity/src/DTOs/ContextPulse.php βœ… S-04 Migrated to Ouroboros CO-001 β€” Starisian\Sparxstar\Infrastructure\DTOs
SirusDatabase schema boot src/core/SirusDatabase.php, src/SirusPlugin.php βœ… S-08 (fixed 2026-08-01) Platform-breaking bug fixed: as a must-use plugin, Sirus never fires register_activation_hook(), so ensure_schema() was never called in a real deployment (only wired to SirusPlugin::onActivation()). Replaced with SirusDatabase::maybe_upgrade_schema() (public SCHEMA_VERSION int constant, one cheap get_option() read, ensure_schema() only on mismatch) called from SirusPlugin::bootSchemaAndCron() on an early init hook. Cron scheduling moved the same way, reusing the existing wp_next_scheduled()-guarded schedule_cron() pattern. onActivation()/onDeactivation() and the lifecycle hook registrations in sparxstar-sirus-context.php are removed. No table/column/index definitions changed β€” only when schema creation runs. Multisite: no explicit per-site loop needed (mirrors SparxstarUECInstaller::activate_site()'s "never loop over sites" rule) β€” each request already executes in its own site's $wpdb/option context.

Trust and Security

Component File Status Sprint Notes
TrustEngine src/core/TrustEngine.php βœ… S-01/S-02 Frozen algorithm; 18 unit tests in TrustEngineTest
TrustResolver src/core/TrustResolver.php βœ… S-01/S-02 Credential-level base + drift/session deductions; 19 unit tests in TrustResolverTest; CREDENTIAL_BASE fixed 2026-08-01 β€” removed dead elder entry (not a CredentialTier case), added missing authority entry (0.95, above user 0.85); added exhaustive-coverage and monotonic-ordering tests
StepUpPolicy src/core/StepUpPolicy.php βœ… S-01/S-02 Frozen policy; requiresStepUp() + TRUST_LEVEL_STEP_UP_REQUIRED pre-flag check; fails closed on LOCKED (checked before STEP_UP_REQUIRED, added 2026-08-01); 21 unit tests
PulseGenerator src/core/PulseGenerator.php βœ… S-01/S-02 HMAC-SHA256 only; consumes enum-backed SirusContext::trust_level; PAM-002-P2 fields wired (behavior_flags, geo_zone, network_effective_type, session_duration); 36 unit tests in PulseGeneratorTest; $now/$ttlSeconds explicit params; signing key constant renamed from its old SIRUS_-prefixed name to SPARXSTAR_PULSE_SIGNING_KEY (2026-08-01, matches Helios); resolveTtl(ResourceSensitivity) implements the sensitivity/connectivity TTL strategy (2026-08-01)

Device and Identity

Component File Status Sprint Notes
DeviceContinuity src/core/DeviceContinuity.php βœ… S-01 Two-stage pipeline: resolveDevice() + evaluateContinuity()
DeviceMatcher src/core/DeviceMatcher.php βœ… S-01 spec Β§14.3: STRONG_MATCH_THRESHOLD=0.8 / WEAK_MATCH_THRESHOLD=0.6; MatchResult enum; classify(); 22 unit tests
DeviceRecord DTO src/core/DeviceRecord.php βœ… S-01
DeviceRepository src/core/DeviceRepository.php βœ… S-01
IdentityResolver src/core/IdentityResolver.php βœ… S-01 Five-tier resolution via Helios
AuthorityResolver src/core/AuthorityResolver.php βœ… S-01 Multi-authority aggregation

Environment and Network

Component File Status Sprint Notes
EnvironmentResolver src/services/EnvironmentResolver.php βœ… S-07 Client-first EnvironmentRecord builder with UA fallback only; compatibility accessors retained
EnvironmentRecord DTO src/core/EnvironmentRecord.php βœ… S-07 Built with IP anonymization, region-level location, network filtering, and capture metadata
NetworkContextBroker src/core/NetworkContextBroker.php βœ… S-01 issueToken(context, secret) / verifyToken(token, secret) β€” explicit secret; portable

Consent and Compliance

Component File Status Sprint Notes
ConsentManager src/core/ConsentManager.php βœ… S-01 Three-level cascade (userβ†’siteβ†’deny); purpose consent; append-only history; 16 tests βœ…

Compatibility

Component File Status Sprint Notes
StarUserEnv facade src/StarUserEnv.php βœ… S-00 FROZEN β€” UEC backward compat; signatures must never change
UECCompatibilityShim src/integrations/UECCompatibilityShim.php βœ… S-00 Namespace alias bridge

Pulse Verification Contract (Spec Β§13)

Ownership ruling: Sirus generates pulses; Helios verifies them (.github/instructions/copilot-instructions.md: "Do not put verification logic here"). The canonical six-check contract and VerificationResult enum are shared types owned by Ouroboros β€” Sirus must not implement runtime verification. Sirus's only obligation is to prove its generated pulses round-trip against the canonical Ouroboros signing material.

Component Owner Status Sprint Notes
PulseGenerator (signing side) Sirus βœ… S-01/S-02 Signs via Ouroboros ContextPulseSigningMaterial::build()
VerificationResult enum Ouroboros ⏳ S-07 Shared type β€” import from Ouroboros, never redefine in Sirus
PulseVerifier six-check Helios / Ouroboros ⏳ S-07 Not built in Sirus by design. S-07 adds a generate↔verify round-trip test only

API, Capability, and Telemetry

Component File Status Sprint Notes
REST /device src/api/SirusRESTController.php βœ… S-01 Registered
REST /context src/api/SirusRESTController.php βœ… S-01 Registered; optional device_id must match the current or token-derived context
REST /pulse src/api/SirusRESTController.php 🟑 S-07 Registered with HttpOnly/SameSite=Strict pulse cookie + metadata body; full validation pending dependency install
REST /identity src/api/SirusRESTController.php 🟑 S-07 Registered; delegates to IdentityResolver; full validation pending dependency install
REST /session src/api/SirusRESTController.php 🟑 S-07 Registered; exposes current session status; full validation pending dependency install
REST /client-report src/api/SirusRESTController.php 🟑 S-07 Registered; delegates to ClientTelemetry; full validation pending dependency install
API contract + seed docs/contracts/sirus-api-contract.v1.json, docs/contracts/sirus-api-seed.v1.json βœ… S-07 Machine-readable OpenAPI contract and seed payloads for downstream repos; smoke-tested without WordPress
CapabilityEngine src/core/CapabilityEngine.php 🟑 S-01 resolve(SirusContext): array; no unit test
AuthorityResolver src/core/AuthorityResolver.php 🟑 S-01 Built; no unit test
ClientTelemetry src/core/ClientTelemetry.php 🟑 S-01 Built; no unit test

Event / Mitigation / Signal Subsystem (Observability β€” Spec Β§6)

The runtime signal-evaluation and mitigation pipeline that backs the trust signals TrustEngine consumes. Built earlier; comprehensive unit coverage landed via PRs #80/#81 ("12 previously uncovered classes"). Tracked here so the subsystem is visible against the S-06 observability theme.

Component File Status Sprint Notes
SirusSignalEvaluator src/helpers/SirusSignalEvaluator.php βœ… S-06 SirusSignalEvaluatorTest
SirusMitigationCoordinator src/services/SirusMitigationCoordinator.php βœ… S-06 SirusMitigationCoordinatorTest
SirusMitigationRuleEngine src/helpers/SirusMitigationRuleEngine.php βœ… S-06 SirusMitigationRuleEngineTest
SirusRuleConfig src/helpers/SirusRuleConfig.php βœ… S-06 SirusRuleConfigTest
SirusImpactScorer src/helpers/SirusImpactScorer.php βœ… S-06 SirusImpactScorerTest
SirusPriorityScorer src/helpers/SirusPriorityScorer.php βœ… S-06 SirusPriorityScorerTest
SirusRateLimit src/helpers/SirusRateLimit.php βœ… S-06 SirusRateLimitTest; REMOTE_ADDR validated before rate-limit keying
SirusEventAggregator src/core/SirusEventAggregator.php βœ… S-06 SirusEventAggregatorTest
SirusEventRepository src/core/SirusEventRepository.php βœ… S-06 SirusEventRepositoryTest
SirusRuleHitRepository src/core/SirusRuleHitRepository.php βœ… S-06 SirusRuleHitRepositoryTest
SirusMitigationActionRepository src/core/SirusMitigationActionRepository.php βœ… S-06 SirusMitigationActionRepositoryTest
SirusEventController (REST) src/api/SirusEventController.php βœ… S-06 SirusEventControllerTest
SirusDirectiveController (REST) src/api/SirusDirectiveController.php βœ… S-06 SirusDirectiveControllerTest
SirusDeviceParser src/services/SirusDeviceParser.php βœ… S-06 SirusDeviceParserTest; Matomo wrapper, empty output without optional dep
HeliosClient src/integrations/HeliosClient.php βœ… S-06 HeliosClientTest
SirusNetworkSettingsPage src/admin/SirusNetworkSettingsPage.php βœ… S-06 SirusNetworkSettingsTest

Scoreboard β€” Test Coverage

Test File Component Status Sprint Tests
ContextEngineTest.php ContextEngine βœ… S-01 6
ContextCacheTest.php ContextCache βœ… S-01 β€”
SirusContextTest.php SirusContext βœ… S-01 β€”
NetworkContextBrokerTest.php NetworkContextBroker βœ… S-01 10 tests: issue/verify round-trip, tamper detection, wrong secret, expired
IdentityResolverTest.php IdentityResolver βœ… S-01 β€”
DeviceContinuityTest.php DeviceContinuity βœ… S-01 +2 STEP_UP_REQUIRED tests
DeviceRecordTest.php DeviceRecord βœ… S-01 β€”
TrustEngineTest.php TrustEngine βœ… S-02 18
PulseGeneratorTest.php PulseGenerator βœ… S-02 20
TrustResolverTest.php TrustResolver βœ… S-02 15
EnvironmentResolverTest.php EnvironmentResolver βœ… S-07 Client signals take precedence; UA/Matomo is fallback only; network filter; EnvironmentRecord output
DeviceMatcherTest.php DeviceMatcher βœ… S-02 22
ConsentManagerTest.php ConsentManager βœ… S-02 16 tests β€” cascade order, privacy-first hard default, anonymous user, invalid meta, multisite isolation, history, purpose consent
StepUpPolicyTest.php StepUpPolicy βœ… S-02 17
AuthorityResolverTest.php AuthorityResolver βœ… S-07 Authority trust paths and precedence coverage
CapabilityEngineTest.php CapabilityEngine βœ… S-07 Named capability issuance + filter coverage
ClientTelemetryTest.php ClientTelemetry βœ… S-07 Report/aggregation/pruning, no post-meta storage assertions
PulseRoundTripTest.php PulseGenerator ↔ Ouroboros βœ… S-07 Generateβ†’verify against canonical Ouroboros signing material
EnvironmentRecordTest.php EnvironmentRecord βœ… S-07 Privacy invariants at construction
RestApiTest.php (integration) SirusRESTController βœ… S-07 Covers all six REST endpoints (Β§18–19)
ContextBootExceptionTest.php ContextBootException πŸ—‘οΈ β€” Removed from Sirus scope β€” type owned by Ouroboros since S-04
ContextPulseTest.php ContextPulse πŸ—‘οΈ β€” Removed from Sirus scope β€” type owned by Ouroboros since S-04

Current Review Notes β€” 2026-08-01 (spec-conformance audit fixes)

Static spec-conformance audit against Sirus Context Engine Spec v3.0 found and fixed six defects (B-1 through B-6) plus a stub-drift CI gap (D-4). Full detail per-component is recorded in the Scoreboard rows above; this note records the cross-cutting decisions.

  • B-1 (πŸ”΄ platform-breaking): the old SIRUS_-prefixed signing-key constant renamed to SPARXSTAR_PULSE_SIGNING_KEY everywhere (code, tests, PUBLIC_API.md, README.md) to match Helios's already-renamed side. Every pulse was failing Helios's signature verification until this landed.
  • B-2 (πŸ”΄ platform-breaking): see the SirusDatabase schema boot row above. Sirus tables were never created in a real deployment because must-use plugins never fire activation hooks.
  • B-3 (🟠) β€” table-name reconciliation: sparxstar-user-environment-check.php and sparxstar-sirus-context.php defined SPX_ENV_CHECK_DB_TABLE_NAME to two different values (sparxstar_uec_snapshots vs sparxstar_env_snapshots) with behavior depending on mu-plugin load order. Decision: keep sparxstar_env_snapshots β€” the value already defined (guarded, "define if not already defined") by sparxstar-sirus-context.php, which is the live/active orchestrator entry point. Reasoning: WordPress loads mu-plugins in filename-alphabetical order; sparxstar-sirus-context.php sorts before sparxstar-user-environment-check.php ('s' < 'u'), so it always defines the constant first in practice even without the new guard. The new guard added in sparxstar-user-environment-check.php (if (defined('SIRUS_VERSION')) { return; }) makes this outcome unconditional rather than order-dependent: the legacy file's own conflicting definition of SPX_ENV_CHECK_DB_TABLE_NAME (sparxstar_uec_snapshots) is now unreachable whenever Sirus is loaded. In practice this also means the legacy SparxstarUECDatabase/SparxstarUECSnapshotRepository code path (the only consumer of that constant) no longer runs at all when Sirus is active β€” it was already superseded by SirusDatabase/SirusEventRepository per the UEC Legacy Scoreboard below. sparxstar-user-environment-check.php was also added to .distignore. Neither legacy file was deleted β€” full removal remains S-03, blocked on the stabilization window.
  • B-4 (🟠): see the TrustResolver row above.
  • B-5 (🟠): see the StepUpPolicy row above.
  • B-6 (🟠): see the PulseGenerator row above (pulse TTL strategy).
  • B-7 β€” known pending follow-up: a parallel Ouroboros-side effort is adding a canonical CredentialTier to sparxstar-ouroboros-integrity (tracked here as OQ-009 in docs/sirus-tech-spec.md). This repo's local provisional src/Infrastructure/DTOs/CredentialTier.php and the "Starisian\\Sparxstar\\Infrastructure\\": "src/Infrastructure/" autoload entry in composer.json were deliberately not touched in this pass β€” they cannot be removed until the promoted Ouroboros version actually ships in a released Composer version. Follow-up: once that ships, delete the local stub, drop the autoload entry, and add CredentialTier to bin/check-ouroboros-stub-drift.php's coverage.
  • D-4 (🟠): added bin/check-ouroboros-stub-drift.php (composer script check:ouroboros-drift) and a new ouroboros-stub-drift CI job in .github/workflows/test.yml (runs after php-tests). Reflects the real installed Ouroboros package and checks TrustLevelPrimitive, ContextPulse, Platform, ContextPulseSigningMaterial, and ContextBootException against the shapes this repo's code assumes β€” the automated version of the check that would have caught the historical drift in docs/DRAFT-OQ-016-trustlevelprimitive-drift.md before it reached CI as 94 failures.
  • Pre-existing failures observed while running the full suite (not caused by this pass, not fixed β€” out of scope): AuthorityResolverTest/CapabilityEngineTest (6 + 8 tests) call a test helper (makeContext(string $credentialTier)) that passes TrustLevelPrimitive string values ('NORMAL', 'STEP_UP_REQUIRED', 'LOCKED') into CredentialTier::from(), which throws ValueError since those are not valid CredentialTier backing values β€” a test-authoring bug confusing the two enums. RestApiTest (2 tests) calls WP_REST_Request::set_body_params(), which the test bootstrap's WP_REST_Request stub does not implement. Both predate this branch.

Current Review Notes β€” 2026-06-09

  • Runtime/security review found /context accepted an optional device_id parameter but did not enforce it. The handler now rejects mismatches for both current-context and ctx_token-derived responses.
  • Dependency validation is currently gated by the installability of sparxstar-ouroboros-integrity. Keep S-07 validation rows 🟑 until CI or a credentialed environment can install dependencies and run the full suite.

Finish-Build Plan

  1. Restore authenticated/package access for starisian/sparxstar-ouroboros-integrity and make composer install --no-interaction --prefer-dist reproducible; keep composer run smoke:api-contract as the no-dependency preflight.
  2. Run composer run test, composer run test:unit, and composer run analyze; flip S-07 validation rows from 🟑 to βœ… only after those commands pass without deprecations or failures.
  3. Complete S-05 by raising PHPStan toward Level 7 in small, no-baseline increments.
  4. After the UEC stabilization window closes, execute S-03 legacy removal while preserving StarUserEnv method signatures.
  5. Verify Helios and Dheghom consume the same Ouroboros release and that pulse verification remains outside Sirus runtime.

Scoreboard β€” Ouroboros Migration

The provisional Sirus mirrors have been removed; these rows record the completed migration to sparxstar-ouroboros-integrity.

Provisional file Canonical owner Migration status
src/exceptions/ContextBootException.php sparxstar-ouroboros-integrity βœ… Migrated β€” Ouroboros CO-001
src/dto/ContextPulse.php sparxstar-ouroboros-integrity βœ… Migrated β€” Ouroboros CO-001

Hard rule:

Keep importing the Ouroboros-owned types directly. Do not reintroduce local mirrors.

Ouroboros must own and export:

  • ContextPulse DTO
  • ContextBootException
  • GovernanceToken DTO
  • AgreementResult enum
  • ValidationHelper
  • All shared cross-repo enums

Scoreboard β€” UEC Legacy Code

Legacy sparxstar-user-environment-check files remain in the codebase during the migration window. Scheduled for removal once all call sites are confirmed migrated.

File Replacement Status Sprint
src/SparxstarUserEnvironmentCheck.php src/SirusPlugin.php πŸ—‘οΈ S-03
src/core/SparxstarUECAssetManager.php src/core/ContextEngine.php πŸ—‘οΈ S-03
src/core/SparxstarUECDatabase.php src/core/SirusDatabase.php πŸ—‘οΈ S-03
src/core/SparxstarUECInstaller.php src/core/SirusDatabase.php πŸ—‘οΈ S-03
src/core/SparxstarUECKernel.php src/SirusPlugin.php πŸ—‘οΈ S-03
src/core/SparxstarUECSnapshotRepository.php src/core/SirusEventRepository.php πŸ—‘οΈ S-03
src/cron/SparxstarUECScheduler.php src/SirusPlugin.php (cron hooks) πŸ—‘οΈ S-03
src/includes/SparxstarUECCacheHelper.php src/core/ContextCache.php πŸ—‘οΈ S-03
src/includes/SparxstarUECSessionManager.php src/core/DeviceContinuity.php πŸ—‘οΈ S-03
src/services/SparxstarUECGeoIPService.php src/services/EnvironmentResolver.php πŸ—‘οΈ S-03
src/api/SparxstarUECRESTController.php src/api/SirusRESTController.php πŸ—‘οΈ S-03
src/admin/SparxstarUECAdmin.php src/admin/SirusDashboardPage.php πŸ—‘οΈ S-03

Sprint Plan

S-00 β€” Foundation (Complete)

UEC compatibility layer established. StarUserEnv facade frozen.

  • StarUserEnv facade (frozen public API)
  • UECCompatibilityShim (namespace aliasing)
  • SirusPlugin, SirusDatabase, SirusEventRepository
  • IpAnonymizer (last-octet zeroing enforced)

S-01 β€” Spec v3.0 Alignment (Complete β€” this PR)

All components from Sirus Context Engine Spec v3.0 built. Behavior locked, not just structure.

  • ContextEngine::current() β€” deterministic, throws ContextBootException, never null
  • CLI system context path (SYSTEM/GLOBAL/CLI)
  • SirusContext DTO β€” trust_score field added
  • TrustEngine β€” frozen algorithm (base 1.0, deductions clamped to [0.0, 1.0])
  • TrustResolver β€” credential-level base + drift/session deductions for buildFromDevice()
  • PulseGenerator β€” HMAC-SHA256, no identity in pulse, key from constant only
  • ContextPulse DTO β€” immutable, provisional Ouroboros mirror
  • ContextBootException β€” provisional Ouroboros mirror
  • EnvironmentResolver β€” Matomo DeviceDetector + regex fallback + Throwable guard
  • DeviceMatcher β€” spec Β§14.3: STRONG_MATCH_THRESHOLD=0.8 / WEAK_MATCH_THRESHOLD=0.6; MatchResult enum (STRONG/WEAK/NO); classify() static method; hardware_concurrency key (not hardware_conc)
  • ConsentManager β€” three-level cascade (user meta β†’ site option β†’ deny), purpose consent, append-only history
  • StepUpPolicy β€” uses ContextPulse + ResourceSensitivity enum; requiresStepUp()/getRequiredLevel() frozen boundary; TRUST_LEVEL_STEP_UP_REQUIRED pre-flag; 17 tests in StepUpPolicyTest
  • NetworkContextBroker β€” issueToken(context, secret) / verifyToken(token, secret) β€” explicit secret; tl/ts round-trip; absent ts derived from tl; 10 tests
  • README.md β€” full spec alignment documentation
  • PUBLIC_API.md β€” public surface document for cross-repo consumers

S-02 β€” Test Coverage for S-01 Components (Complete)

Every S-01 component built without a unit test needs one. PHPUnit ^11.5.50, extends SirusTestCase.

  • TrustEngineTest β€” 18 tests: frozen algorithm, all signal combos, clamping to [0.0, 1.0], level mapping
  • PulseGeneratorTest β€” 20 tests: key validation, pulse fields, no identity_id, TTL = issued_at + default, explicit $now/$ttlSeconds honoured, sig is 64-char hex
  • TrustResolverTest β€” 15 tests: all credential bases, drift deduction, new-session deduction, combined, clamping
  • ContextPulseTest β€” removed from scope; ContextPulse is owned by Ouroboros since S-04
  • ContextBootExceptionTest β€” removed from scope; ContextBootException is owned by Ouroboros since S-04
  • EnvironmentResolverTest β€” delivered in S-07 (client-first signals, UA/regex fallback, network filter)
  • DeviceMatcherTest β€” βœ… COMPLETE (22 tests: classify() three-way branching, STRONG/WEAK/NO_MATCH cases, boundary at 0.8 and 0.6, scoreHash, scoreComponents, hardware_concurrency key validation)
  • ConsentManagerTest β€” cascade order (userβ†’siteβ†’deny), privacy-first hard default, anonymous user skip, invalid meta fallthrough, multisite isolation, history append-only, purpose consent (16 tests βœ…)
  • StepUpPolicyTest β€” βœ… COMPLETE (17 tests β€” includes STEP_UP_REQUIRED trust level pre-flag)

Acceptance criteria: composer run test:unit passes with no failures or deprecations.


S-03 β€” UEC Legacy Removal (After Ouroboros Ships or After Stabilisation Window)

Remove all SparxstarUEC* files. Confirm no production call sites reference old namespace directly.

Prerequisite: 30-day stabilisation window post S-01 deployment closed.

  • Audit all active site call sites for Starisian\SparxstarUEC\ namespace references
  • Remove all 12 legacy UEC files listed in the UEC Legacy Scoreboard above
  • Remove UECCompatibilityShim (no longer needed)
  • Remove src/admin/SparxstarUECAdmin.php
  • Update phpcs.xml and phpstan.neon.dist to drop UEC exclusions
  • Confirm composer run test passes after removals

S-04 β€” Ouroboros Integration (Complete β€” this PR)

Replace provisional mirrors with Ouroboros package imports.

Current gate: sparxstar-ouroboros-integrity must remain installable from the configured Packagist/private VCS source for local and CI validation.

  • Add sparxstar-ouroboros-integrity to composer.json require
  • Delete src/exceptions/ContextBootException.php (provisional)
  • Delete src/dto/ContextPulse.php (provisional)
  • Update all import statements to use Ouroboros namespace
  • Import AgreementResult enum from Ouroboros (remove any local copy)
  • Import ValidationHelper from Ouroboros (remove any local copy)
  • Run composer run test to confirm no regressions
  • Confirm Helios and Dheghom are updated to the same Ouroboros version

S-05 β€” PHPStan Level Increase (Ongoing Quality)

Target PHPStan Level 7 across the entire src/ tree.

  • Resolve all Level 6 findings in src/core/
  • Resolve all Level 6 findings in src/services/
  • Resolve all Level 6 findings in src/helpers/
  • Resolve all Level 6 findings in src/api/
  • Update phpstan.neon.dist to level: 6, confirm clean
  • Repeat for Level 7

S-06 β€” Observability and Telemetry Hardening (Future)

Signal pipeline completeness and cross-layer tracing.

  • Confirm SirusSignalEvaluator covers all signal types defined in spec
  • Add structured logging to TrustEngine (score deltas, reason codes)
  • Add structured logging to PulseGenerator (pulse_id, issued_at, expiry)
  • Add ConsentManager audit log integration with SirusEventRepository
  • Expose GET /sirus/v1/context REST endpoint for debug/admin
  • Add admin UI panel for live trust score and consent status per device

S-07 β€” Spec Completeness and Helios Integration Readiness (Complete except Ouroboros-blocked VerificationResult import)

Close the spec components that exist in the codegen order (Spec Β§24) but were never built, complete the REST surface Helios consumes, and finish the test coverage S-02 left dangling. Theme: make Sirus a complete, integration-ready producer for the edge.

Status (post PR #88): implementation merged in main. Every S-07 item is 🟑 ("validation pending"). Test, PHPCS, and PHPStan verification is blocked on the CI gate consolidation in S-08 (see GATE-AUDIT-PAM003.md). The 10 Ouroboros-coupled tests additionally need v2.0 shared-test-vectors.json and PAM-003 acceptance β€” those flips wait for S-09.

Prerequisite for the verification items: Ouroboros must export VerificationResult and the canonical PulseVerifier contract. If not yet published, item 1 ships the round-trip test against ContextPulseSigningMaterial only and the enum import is deferred.

P0 β€” REST surface for Helios (Spec Β§18–19)

  • Register POST /sparxstar/v1/pulse β€” request a fresh signed ContextPulse (HttpOnly cookie + { pulse_id, expires_at, trust_level } body); server-to-server / Helios re-verification only, not browser-facing
  • Register GET /sparxstar/v1/identity β€” resolve current identity tier
  • Register GET /sparxstar/v1/session β€” session status
  • Register POST /sparxstar/v1/client-report β€” telemetry/error reporting (never stored in post meta, Β§23)
  • Integration tests in tests/integration/RestApiTest.php covering all six endpoints

P0 β€” Pulse generate↔verify compatibility (Spec Β§13)

  • Add PulseRoundTripTest β€” sign a pulse via PulseGenerator, confirm it verifies against the canonical Ouroboros signing material (tamper / expiry / malformed cases)
  • Import VerificationResult from Ouroboros when available β€” never redefine in Sirus
  • Do not add runtime verification logic to Sirus (per .github/instructions/copilot-instructions.md); contradiction resolved β€” PulseVerifier ownership claim removed from that file; it now reads only "Sirus generates, Helios verifies"

P1 β€” EnvironmentRecord DTO (Spec Β§7, Β§23)

  • Build src/core/EnvironmentRecord.php with all spec fields, privacy enforced at construction (IP last-octet zeroed, region-level location only, no exact coords without grant, is_bot, time_zone, brand/model/versions, captured_at)
  • Client-first (AGENTS.md): populate the record from client-submitted signals; never derive browser/OS/device by parsing User-Agent β€” Matomo is fallback/enrichment only
  • Have EnvironmentResolver return an EnvironmentRecord; keep the existing flat accessors as thin wrappers for backward compat
  • EnvironmentResolverTest + EnvironmentRecordTest (privacy invariants asserted at construction; client signals take precedence over UA fallback)

P1 β€” Close S-02 test debt for built components

  • AuthorityResolverTest β€” multi-authority aggregation, most-restrictive conflict outcome (Β§17)
  • CapabilityEngineTest β€” named capability issuance from context (Β§23 codegen)
  • ClientTelemetryTest β€” report/aggregation/pruning, no post-meta storage (Β§23)

Acceptance criteria:

  • composer run test and composer run test:unit pass with no failures or deprecations
  • composer run analyze clean at the configured PHPStan level (currently mid-migration to Level 6 per S-05)
  • All six REST endpoints from Spec Β§18–19 are registered and integration-tested
  • No verification runtime added to Sirus; VerificationResult (if used) is imported from Ouroboros
  • copilot-instructions.md PulseVerifier ownership contradiction resolved

S-08 β€” Make CI Trustworthy (Proposed β€” Next)

Consolidate the three divergent quality gates so PHPCS / PHPStan / tests actually report verified state. Until this lands, S-07's 🟑 items cannot be flipped to βœ…, and the tracker cannot be honestly refreshed. Scope is governed by GATE-AUDIT-PAM003.md Β§A/Β§B "Actionable now" and the in-repo Engineering Standards file.

Prerequisite: none β€” this is the unblocker for everything downstream.

Adopted conventions (decided at sprint open):

  • Class files: PSR-4 PascalCase (filename matches FQCN), as already enforced by the Composer autoloader. Exclude WordPress.Files.FileName from the canonical ruleset.
  • Local variables: camelCase. Exclude WordPress.NamingConventions.ValidVariableName from the canonical ruleset.
  • This codifies the convention the autoloader already requires; the rest of the 386/310 PHPCS noise is convention collision, not latent bugs.

P0 β€” PHPCS gate consolidation (audit Β§A)

  • Consolidate to one canonical PHPCS ruleset. Recommendation: keep phpcs.xml.dist as the committed baseline; either gitignore phpcs.xml (true local override per the existing .dist <description>) or delete it.
  • Unify testVersion to 8.2- across the surviving ruleset and composer.json platform (currently phpcs.xml=8.1-8.4, phpcs.xml.dist=8.2-).
  • Exclude WordPress.Files.FileName (PSR-4 incompatible β€” by policy, not preference).
  • Exclude WordPress.NamingConventions.ValidVariableName (camelCase locals adopted).
  • Drop <arg name="ignore-annotations"/> so reviewed phpcs:ignore waivers work in-line.
  • Resolve phpcs.xml.dist self-contradiction: its <description> says "To override locally, create a phpcs.xml file (gitignored)" but phpcs.xml is committed and is what composer phpcs runs.
  • Run composer lint:fix once across the tree to clear the whitespace/format residue; commit.
  • Confirm composer phpcs and composer lint no longer disagree (the 386 vs 310 discrepancy from PR #88).

P0 β€” Pre-commit gate (audit Β§B)

  • Add lint-staged + husky (or simple-git-hooks) running phpcbf then phpcs on staged PHP.
  • Apply the exit-code-1 guard on phpcbf β€” PHPCBF returns 1 when it successfully fixed violations; the hook must treat exit code 1 as success and only fail on exit code 2. Use a cross-platform wrapper (e.g., a small bin/phpcbf-fix.php script invoked via a Composer script, or a Node wrapper invoked by lint-staged) rather than a bash-only $?-style guard, which breaks on Windows cmd.exe / PowerShell.
  • Document the hook in CONTRIBUTING.md.

P0 β€” Un-mask PHPStan

  • Run PHPStan as an independent CI job, not after the PHPCS hard-fail, so type drift surfaces. (The audit notes PHPStan is currently invisible because composer run test short-circuits on PHPCS.)
  • Fix or baseline residual findings at the level configured in phpstan.neon (currently moving from 5 β†’ 6 per S-05).

P1 β€” Validate S-07 (non-Ouroboros-coupled items only)

With the gate trustworthy, run the suite and flip 🟑 β†’ βœ… in this tracker for items not coupled to the Ouroboros v2.0 vectors:

  • EnvironmentRecord DTO, EnvironmentResolver client-first behavior (EnvironmentRecordTest, EnvironmentResolverTest)
  • REST /pulse, /identity, /session, /client-report (integration test asserts success + permission-denied + malformed)
  • AuthorityResolverTest, CapabilityEngineTest, ClientTelemetryTest
  • copilot-instructions.md PulseVerifier ownership contradiction resolved (remove PulseVerifier from the "What this repository owns" list)
  • Reconcile the GATE-AUDIT citation of "Engineering Standards Β§6.2" β€” the in-repo file .github/instructions/sparxstar-coding-standards-v1.md Β§6.2 is "GraphQL Resolver Rules", not PSR-4 naming. Either correct the audit reference or supply the actual Engineering-Standards-v1.0 document.

Out of scope (moved to S-09):

  • PulseGenerator delegation to Ouroboros's canonical PulseGenerator::generate() (audit Β§C.4).
  • Import VerificationResult, AgreementResult, ValidationHelper from Ouroboros.
  • Rewrite the 10 Ouroboros-coupled tests against shared-test-vectors.json.
  • Lock geo_zone format (PAM-002-O3).

Acceptance criteria:

  • One PHPCS ruleset is canonical; composer phpcs and composer lint agree on the count.
  • composer run test, composer run lint, composer run analyze all run independently and report verified status; none is masked by an upstream short-circuit.
  • A staged PHP file with a fixable violation is corrected by the pre-commit hook and the commit succeeds; an unfixable violation blocks the commit.
  • S-07 non-Ouroboros-coupled items are flipped to βœ… in this tracker, with test counts recorded.
  • copilot-instructions.md no longer contradicts itself on PulseVerifier ownership.

S-09 β€” Ouroboros v2.0 Alignment (Planned β€” After S-08)

Finish the cross-repo migration that the gate audit blocks on. Theme: align Sirus with the canonical Ouroboros v2.0 contracts and PAM-003 acceptance, then flip the 10 Ouroboros-coupled S-07 tests to βœ….

Prerequisites:

  • S-08 merged (CI trustworthy).
  • Ouroboros v2.0.0 shared-test-vectors.json accessible to this repo's CI (currently the private repo proxy returns repository not authorized per GATE-AUDIT-PAM003.md).
  • PAM-003 acceptance criteria supplied as a file in this repo (currently referenced by PAM-002, TRACKER, copilot-instructions, and src/core/* but not present).

Planned scope (full sequencing to be confirmed at sprint open):

  • Migrate Sirus's local pulse issuance to Ouroboros's canonical PulseGenerator::generate() (audit Β§C.4). Signing-material delegation (ContextPulseSigningMaterial::build()) is already done; issuance is the un-migrated half. The composition root is src/SirusPlugin.php:138; consumers receive PulseGenerator via constructor injection (e.g., SirusRESTController).
  • Import VerificationResult enum from Ouroboros (S-07 leftover).
  • Import AgreementResult enum from Ouroboros (S-04 leftover).
  • Import ValidationHelper from Ouroboros (S-04 leftover).
  • Rewrite the 10 Ouroboros-coupled tests against shared-test-vectors.json β€” assertions derived from the spec vectors, never from current code (audit Β§C.1): PulseRoundTripTest, PulseGeneratorTest, SirusContextTest, AuthorityResolverTest, CapabilityEngineTest, StepUpPolicyTest, ContextEngineTest, ContextCacheTest, IdentityResolverTest, NetworkContextBrokerTest.
  • Lock geo_zone format (PAM-002-O3) β€” required before PAM-002-P3 ships.
  • Confirm Sirus's pulse field set still matches PAM-002 Β§3.3 canonical (15 fields including the four PAM-002-P2 restored fields).
  • Confirm Helios and Dheghom are pinned to the same Ouroboros version.

Acceptance criteria (preview):

  • All 10 Ouroboros-coupled tests flipped to βœ… against v2.0 vectors.
  • PulseGenerator issuance routes through Ouroboros; Sirus retains the composition wiring only.
  • Tracker fully refreshed; S-04 leftover items closed.

How to Use This Tracker

  1. On sprint start β€” move items from πŸ”² to a named sprint column and assign owners.
  2. On component build β€” change πŸ”² β†’ 🟑 and add the file reference.
  3. On test pass β€” change 🟑 β†’ βœ….
  4. On Ouroboros ship β€” execute S-04 and flip provisional items to βœ….
  5. On UEC removal β€” execute S-03 and remove the UEC Legacy rows from this tracker.

Last updated: 2026-08-01 | Spec version: Sirus Context Engine Spec v3.0 + PAM-002