diff --git a/README.md b/README.md index 82f61d9..381a6bd 100644 --- a/README.md +++ b/README.md @@ -109,6 +109,7 @@ The host business system remains the authority for operational mutations. - `resources/openapi.yaml` — API contract - `tests/` — runtime and workflow checks - `docs/`, `reports/` — architecture and verification evidence +- [`docs/ENGINE_IMPLEMENTATION_AUDIT.md`](docs/ENGINE_IMPLEMENTATION_AUDIT.md) — source-backed scope of the 80 engine pairs and the six documented no-op methods The AI and agent-oriented implementation map is in [`docs/AI_ENGINEERING.md`](docs/AI_ENGINEERING.md). It distinguishes deterministic heuristics, optional cloud-model integration, policy enforcement and host-boundary work from claims the repository does not make. diff --git a/docs/AI_ENGINEERING.md b/docs/AI_ENGINEERING.md index 56b726e..ea79d51 100644 --- a/docs/AI_ENGINEERING.md +++ b/docs/AI_ENGINEERING.md @@ -38,7 +38,11 @@ An intent or prediction never becomes permission by itself. | Optional cloud AI | `src/AI/OpenAIService.php`, `src/Resolver/Resolvers/AIResolver.php` | Optional OpenAI-backed question resolution when enabled and configured. `NullAIService` fails closed when cloud AI is disabled. Cloud output does not bypass policy or command dispatch. | | Authority and safety | `src/Policy/PolicyEngine.php`, `src/Authority/*`, `src/Command/CommandBus.php` | Default-deny capability decisions, approval signatures, role/scope/limit checks, tenant checks and policy callbacks before execution. | | Evidence lineage | `src/Cognition/*`, `src/Events/*`, `src/Http/Controllers/CognitiveEventController.php` | Tenant-scoped cognitive events and outcome links for audit and later learning. | -| Agent-oriented building blocks | `src/Engines/{Planning,Executive,Cognitive,Memory,Learning}/*` | Contract-driven deterministic planning, routing, decision, memory and learning primitives. The 80-engine library is a replaceable baseline library, not 80 trained agents or models. | +| Agent-oriented building blocks | `src/Engines/{Planning,Executive,Cognitive,Memory,Learning}/*` | Contract-driven deterministic planning, routing, decision, memory and learning primitives. Six public methods remain explicit no-op scaffolds and are listed in [the implementation audit](ENGINE_IMPLEMENTATION_AUDIT.md); the library is a replaceable baseline, not 80 trained agents or models. | + +## 80-engine implementation scope + +The repository contains 80 contract/implementation pairs, and the verifier checks that one-to-one structural relationship. That count is not a claim that every method has a complete side effect: six public methods are intentionally recorded as no-op scaffolds in [the implementation audit](ENGINE_IMPLEMENTATION_AUDIT.md). The audit also distinguishes an empty dependency-injection constructor from an empty behavioural method. ## Engineering tradeoffs diff --git a/docs/ENGINE_IMPLEMENTATION_AUDIT.md b/docs/ENGINE_IMPLEMENTATION_AUDIT.md new file mode 100644 index 0000000..34002d9 --- /dev/null +++ b/docs/ENGINE_IMPLEMENTATION_AUDIT.md @@ -0,0 +1,45 @@ +# 80-engine implementation audit + +This is a source-level scope check for the 80 engine pairs listed in [ENGINE_LIBRARY_80.md](ENGINE_LIBRARY_80.md). It answers a narrower question than “is the engine production-ready?”: do the advertised contract/implementation pairs exist, and are any behavioural methods still exact no-ops? + +## Finding + +The repository contains 80 contract files and 80 implementation files. The existing contract-conformance test verifies the one-to-one namespace relationship. A token-aware check now also scans every implementation for empty public method bodies and fails on undocumented placeholders or marker comments. + +Six behavioural methods are exact no-op scaffolds: + +| Method | What the surrounding class does | Honest current scope | +| --- | --- | --- | +| `BusinessIntelligence\\AutomationEngine::trigger` | Records automation task/schedule pairs. | Does not trigger, queue, or schedule a recorded automation. | +| `BusinessIntelligence\\BusinessBuilderEngine::launch` | Generates a small vertical definition and applies parameter overrides. | Does not launch or persist a business configuration. | +| `Learning\\LearningEngine::retrain` | Stores data under a model type and exposes the stored arrays. | Does not retrain a model or calculate model quality. | +| `Memory\\EpisodicMemoryEngine::consolidate` | Stores, recalls, and deletes old episodic rows through the host database. | Does not consolidate or transform episodic records. | +| `Memory\\SemanticMemoryEngine::consolidate` | Stores and keyword-queries semantic rows through the host database. | Does not consolidate, embed, or otherwise enrich semantic records. | +| `Planning\\RetryEngine::retryWithBackoff` | Exposes and updates a retry-policy array. | Does not execute a retry, sleep, enqueue work, or apply backoff. | + +These methods remain in place for interface and provenance compatibility. They should not be described as implemented automation triggering, business launching, retraining, memory consolidation, or retry execution until behaviour and focused tests are added. + +The empty constructor in `Cognitive\\CognitiveOrchestrator` is not in this list: constructor property promotion performs the dependency wiring even though the constructor body is empty. + +## What is verified + +`tests/run.php` checks: + +- 80 contracts and 80 implementations; +- every implementation class satisfies its matching interface; +- the six known no-op methods above are the only empty public behavioural methods; +- implementation files contain no `TODO`, `FIXME`, `not implemented`, `placeholder`, or `stub` markers. + +Run the same package verifier used by CI: + +```bash +composer install +npm ci +php bin/verify.php +``` + +This source check does not prove database connectivity, queue delivery, host integration, model quality, load behaviour, or production readiness. Catalogue readiness is a separate boundary: `reports/workcore-compatibility.json` records 38 template definitions, 29 ready and nine draft, with zero connected-host-verified templates. + +## Recommended next work + +Implement each no-op method only with its owning contract's intended semantics and a focused test. Until then, keep the methods visible as compatibility scaffolds and keep portfolio language at the deterministic baseline level recorded in [AI_ENGINEERING.md](AI_ENGINEERING.md). diff --git a/docs/ENGINE_LIBRARY_80.md b/docs/ENGINE_LIBRARY_80.md index dea22c3..00d0bed 100644 --- a/docs/ENGINE_LIBRARY_80.md +++ b/docs/ENGINE_LIBRARY_80.md @@ -2,6 +2,8 @@ Integrated into the Interaction Engine cumulative package. +The 80-item count is structural library coverage: each named contract has a registered implementation, but it is not a completeness or machine-learning claim. Six public methods remain no-op scaffolds and are documented in [the implementation audit](ENGINE_IMPLEMENTATION_AUDIT.md). + ## Executive 01. `ExecutiveEngine` diff --git a/tests/run.php b/tests/run.php index 2ea355b..709c88f 100644 --- a/tests/run.php +++ b/tests/run.php @@ -87,6 +87,112 @@ }); + +$test('80-engine audit documents no-op methods and rejects new placeholders', function () use ($root, $assert): void { + $expectedNoOps = [ + 'src/Engines/BusinessIntelligence/Implementations/AutomationEngine.php::trigger', + 'src/Engines/BusinessIntelligence/Implementations/BusinessBuilderEngine.php::launch', + 'src/Engines/Learning/Implementations/LearningEngine.php::retrain', + 'src/Engines/Memory/Implementations/EpisodicMemoryEngine.php::consolidate', + 'src/Engines/Memory/Implementations/SemanticMemoryEngine.php::consolidate', + 'src/Engines/Planning/Implementations/RetryEngine.php::retryWithBackoff', + ]; + + $emptyPublicMethods = static function (string $source): array { + $tokens = token_get_all($source); + $empty = []; + $count = count($tokens); + + for ($i = 0; $i < $count; $i++) { + if (!is_array($tokens[$i]) || $tokens[$i][0] !== T_PUBLIC) { + continue; + } + + $cursor = $i + 1; + while ($cursor < $count && is_array($tokens[$cursor]) && in_array($tokens[$cursor][0], [T_WHITESPACE, T_STATIC], true)) { + $cursor++; + } + if ($cursor >= $count || !is_array($tokens[$cursor]) || $tokens[$cursor][0] !== T_FUNCTION) { + continue; + } + + $cursor++; + while ($cursor < $count && is_array($tokens[$cursor]) && $tokens[$cursor][0] === T_WHITESPACE) { + $cursor++; + } + if ($cursor < $count && $tokens[$cursor] === '&') { + $cursor++; + } + while ($cursor < $count && is_array($tokens[$cursor]) && $tokens[$cursor][0] === T_WHITESPACE) { + $cursor++; + } + if ($cursor >= $count || !is_array($tokens[$cursor]) || $tokens[$cursor][0] !== T_STRING) { + continue; + } + $name = $tokens[$cursor][1]; + + while ($cursor < $count && $tokens[$cursor] !== '{') { + $cursor++; + } + if ($cursor >= $count) { + continue; + } + + $depth = 1; + $body = []; + for ($cursor++; $cursor < $count && $depth > 0; $cursor++) { + $token = $tokens[$cursor]; + if ($token === '{') { + $depth++; + } elseif ($token === '}') { + $depth--; + } + if ($depth > 0) { + $body[] = $token; + } + } + + $hasCode = false; + foreach ($body as $token) { + if (is_array($token)) { + if (!in_array($token[0], [T_WHITESPACE, T_COMMENT, T_DOC_COMMENT], true)) { + $hasCode = true; + break; + } + } elseif (trim($token) !== '') { + $hasCode = true; + break; + } + } + if (!$hasCode && $name !== '__construct') { + $empty[] = $name; + } + $i = $cursor; + } + + return $empty; + }; + + $actualNoOps = []; + $markerFiles = []; + foreach (glob($root . '/src/Engines/*/Implementations/*.php') ?: [] as $file) { + $relative = str_replace('\\', '/', substr($file, strlen($root) + 1)); + $source = (string) file_get_contents($file); + if (preg_match('/\b(?:TODO|FIXME|not implemented|placeholder|stub)\b/i', $source) === 1) { + $markerFiles[] = $relative; + } + foreach ($emptyPublicMethods($source) as $method) { + $actualNoOps[] = $relative . '::' . $method; + } + } + + sort($actualNoOps); + sort($expectedNoOps); + sort($markerFiles); + $assert($actualNoOps === $expectedNoOps, 'Unexpected no-op engine methods: ' . implode(', ', array_diff($actualNoOps, $expectedNoOps))); + $assert($markerFiles === [], 'Placeholder markers found in engine implementations: ' . implode(', ', $markerFiles)); +}); + $test('all JSON resources are valid and the five foundation wizards load', function () use ($root, $assert): void { $iterator = new RecursiveIteratorIterator(new RecursiveDirectoryIterator($root, FilesystemIterator::SKIP_DOTS)); foreach ($iterator as $file) {