The development prompt.
The written specification behind this release, including acceptance criteria and honest boundaries.
# ICOM Framework — development prompt Build and deploy an original, understandable PHP framework at framework.icom.la. Target the ease of writing a small Laravel application, explicit modular architecture associated with Symfony, a request lifecycle compatible with persistent PHP workers, practical security defaults, and portable deployments. Treat superiority as a hypothesis to measure, never as a release claim. ## Deliverable Ship a usable, MIT-licensed 0.10 developer preview with source, Composer installation, a command-line entry point, complete local documentation, a live API playground, regression tests and reproducible benchmark commands. Require PHP 8.4.1+. Preserve unrelated hosting data. Deploy only public entry points and assets under the subdomain document root; store application source and secrets outside it. Use HTTPS and production error handling. Earlier version sections below are historical implementation requirements; the current continuation and acceptance requirements are in [docs/RELEASE-PLAN.md](docs/RELEASE-PLAN.md). ## Architecture and behavior - Use PSR-4 autoloading, PSR-7 requests/responses, PSR-15 middleware, PSR-11 dependency injection, PSR-3 logging, PSR-14 events and PSR-16 cache interfaces. Use maintained interface/HTTP-message packages; do not reinvent these standards or vendor modified third-party source. - Provide fluent method routing, named parameters, names/URL generation, route-specific middleware, HEAD/OPTIONS/405 semantics, and a request-bound service container. No global mutable application facade. Detect circular dependencies and disallow singleton capture of scoped services. - Resolve typed controller dependencies and request parameters explicitly. Isolate each request container and release it in finally blocks. Include guarded FrankenPHP and Swoole adapters; document experimental status and runtime restrictions honestly. - Provide deterministic validation with field-level errors and rejection of unknown rules; escaped PHP views; PDO prepared queries, identifier-safe query builder, transactions and a migration command; a file cache with TTL and atomic writes; a locked rate limiter with Retry-After. - Apply CSP, nosniff, referrer and framing controls, unique request IDs, structured logs, generic production error responses, body-size limits, strict host validation and a signed expiring CSRF double-submit cookie for the browser demo. Never trust forwarded client addresses by default. Use password_hash/password_verify and libsodium authenticated encryption helpers. No default user, password or exposed administration console. - Include environment/configuration loading without executable configuration from users. Keep credentials and logs out of public output, downloadable distributions and version control. - Provide liveness/readiness routes, graceful bounded worker loops, Docker/FrankenPHP and Kubernetes deployment examples, CI tests, and rollback instructions. Mark examples not exercised on hosting as unverified. ## Developer experience Use the brand ICOM Framework. Build a restrained, accessible documentation interface with an overview, installation, routing, container, middleware, validation, database, cache, security, authentication/policies, queues, events, ORM, runtime, testing and release status and the full development prompt. Include a working playground for a GET greeting and CSRF-protected POST validation, with response status, timing, JSON output and curl examples. Make the source archive and its SHA-256 digest downloadable. Avoid fictional Packagist/GitHub URLs or fabricated performance numbers. ## Verification and release gates Test route ordering/methods, route URL encoding, request injection, container scope isolation and captive dependency rejection, middleware ordering, validation edge cases, SQL parameterization and identifier injection, cache expiry/corruption, concurrent rate limiting, authenticated-encryption tampering, CSRF tampering/expiry, error redaction and repeated requests through one application instance. Test actual production HTTP routes, headers, CSRF positive/negative cases, hidden-file protection and TLS. Browser-test desktop and mobile, navigation, copy controls and both playground requests. Run composer validate/audit and PHP lint. Record real measurements with workload/runtime/machine details; do not compare against Laravel/Symfony without running equivalent applications under equal conditions. ## Release boundaries and further work A 0.3 preview is not an enterprise certification, a replacement for the Laravel/Symfony ecosystems, or a proven throughput improvement. Password sessions, resource policies, leased SQL queues, PSR-14 events and optional Redis/Doctrine integrations are now included and must have behavior tests. TOTP MFA, one-use recovery codes, administrator-mediated reset, explicit tenant membership policies, local security audit and real MariaDB tests are required in 0.3. OIDC/SAML, recovery delivery services, automatic tenant query scoping, distributed tracing exporters, production SQL/cluster rollout, independent security review and production worker soak tests remain further work. Provide integrations where useful, but never present stubs as completed features. ## Source references checked 2026-09-10 - Laravel 13 release notes (PHP 8.3+): https://laravel.com/framework/docs/releases - Symfony 8.1 current release (PHP 8.4+): https://symfony.com/releases/8.1 - FrankenPHP worker state/reset requirements: https://github.com/php/frankenphp/blob/main/docs/worker.md - PHP-FIG standards: https://www.php-fig.org/psr/ ## Version 0.2 implementation and acceptance requirements 1. Add password authentication, database-backed hashed session tokens, idle/absolute expiration, session revocation and cookie middleware. Provision accounts through CLI only; no default account or public registration. Add role permissions plus explicit object-level policies. Test invalid credentials, timing-work fallback, session fixation/expiry/revocation, role changes and authorization failures. 2. Add a persistent database queue with JSON payloads, explicit named handler registration, delayed jobs, optimistic atomic reservation, ownership tokens, expiring leases, retries/backoff and failed-job inspection/retry. Never deserialize executable job classes from payloads. Use a fresh container scope for each job. Test competing workers, process loss, stale acknowledgements and poison jobs. Describe at-least-once behavior and idempotent-handler responsibilities. 3. Add PSR-14 event dispatch with listener priority and stoppable events. Test ordering, object identity and exception propagation. 4. Add optional, tested Predis-based PSR-16 cache and distributed atomic rate limiter. Separate application namespaces, authenticate serialized cache records, avoid FLUSHDB and fail closed on rate-store failures. Exercise against an actual isolated Redis process. 5. Add a Doctrine ORM integration as an optional maintained component, with per-request EntityManager disposal. Test persistence, query parameterization, relationships and scope isolation on SQLite. Keep core dependencies small; list installation requirements explicitly. 6. Exercise the actual FrankenPHP binary with concurrent/repeated HTTP requests, cookies, 4xx/5xx, worker recycling and response output. Verify its checksum. Publish the precise tested version, configuration, workload and limitations. Test Swoole only if an isolated supported runtime is available; never pretend a syntax check is a runtime test. 7. Expand documentation and the complete prompt, add operational CLI examples, source archive and SHA-256, run lint/audit/core and integration checks, preserve rollback, then deploy a new release. Test live HTTP and desktop/mobile documentation after deployment. Remaining externally dependent work: real OIDC/SAML provider onboarding, external tracing collector, independent security assessment/compliance certification, production cluster testing and equal-workload comparative Laravel/Symfony benchmarks. Implementing local modules does not close these claims. See docs/VERIFICATION.md for measured outcomes and limitations. ## Version 0.3 implementation and acceptance requirements Continue ICOM Framework after v0.2, preserving PHP-FPM hosting and previous releases/downloads. Build actual identity security and exercise a shared SQL service. Keep claims proportional to evidence. 1. Add maintained RFC 6238 TOTP integration, encrypted account-bound secrets, expiring pending enrollment, password reauthentication, confirmation before activation, single-use recovery codes and replay prevention. Enrollment/disable/recovery-code changes revoke sessions. Do not expose a default account or send secrets to QR services. 2. Require a single-use, five-minute challenge after the password for MFA accounts. Bound attempts, serialize factor/token consumption and prevent password-only Sessions::login from bypassing MFA. Invalidate outstanding challenges on password/account/factor changes. 3. Add single-use expiring password reset tokens with administrator-mediated issuance to a private file. Reset preserves enrolled MFA and revokes sessions/challenges/reset tokens. No unauthenticated token issuance, implicit email delivery or MFA bypass. Add password change with current-password and factor verification. 4. Add an append-only application audit API/CLI covering account, session and factor events, excluding credentials, OTPs, raw tokens, email and request bodies. State the database operator can still modify records; no tamper-proof claim. 5. Add explicit tenant membership/policy helpers that check fresh membership and resource tenant equality. No inferred tenant from untrusted headers; trusted application routes select tenant IDs. Test cross-tenant denial and revoked membership. 6. Run an actual isolated MariaDB instance through PDO MySQL: migrations, prepared queries, rollback, sessions/MFA/reset consumption, concurrent queue claims and replay races. Fix found issues; do not relabel MariaDB as an Oracle MySQL/PostgreSQL certification. 7. Extend tests, docs and source distribution. Run server PHP 8.4 core tests, archive install, live HTTPS auth/MFA flows with temporary accounts, and desktop/mobile documentation QA. Snapshot private SQLite before additive migration, use a new release and retain rollback. Remaining external/infrastructure work: real OIDC/SAML provider onboarding and delivery services, independent security assessment, staging cluster deployment/failover, tracing collector and long-duration production worker tests, comparative Laravel/Symfony applications and measurements. ## Continuation 0.4 # Version 0.4 continuation prompt and acceptance plan Continue the original PHP 8.4+ framework from 0.3 without making unsupported comparisons with other frameworks. Preserve existing APIs, MFA policy, APP_KEY, production accounts, shared storage and rollback releases. Deliver functional account pages for sign-in, local MFA, authenticator enrollment, once-only recovery-code display/download, rotation/removal, password change and administrator-issued reset tokens. Follow docs/design/ACCOUNT-UI.md; use escaped HTML and same-origin CSRF-protected APIs. No public registration, secret-bearing URLs, persistent browser token storage or automatic email delivery. Deliver an opt-in OIDC Authorization Code + S256 PKCE client. Operator-configured HTTPS endpoints, verified TLS, bounded no-redirect transport, RS256/JWK verification through a maintained JWT library, strict issuer/audience/authorized-party/nonce/lifetime/hash checks. Store encrypted flow material with hashed state/browser binding and five-minute atomic one-use redemption. Link only an explicit issuer+subject to an existing active account via privileged CLI; never auto-link email claims. Enforce local MFA after SSO. Support PHP-FPM and isolated worker scopes without native PHP sessions or mutable per-request JWT globals. Keep SSO disabled until real provider configuration exists. Acceptance: malicious/expired/wrong-browser/replayed token and configuration tests; actual HTTP provider transport plus browser callback/cookie/MFA flow; signed-in/out and account mutation browser tests on desktop/mobile; SQLite and MariaDB persistence/concurrency; retained core/Redis/Doctrine tests, PHP lint, dependency audit; exact source archive, safe server preflight/backup/migration/symlink deployment and live HTTPS checks. Record actual evidence and exclusions. Production external-provider onboarding, SAML, automated recovery delivery, multi-node failover, long soak, external security review and controlled framework comparisons remain separate work. ### Final deployment patch 0.4.1 Preserve PHP no-referrer account/callback policy in Apache: use Header always setifempty for its default, preserve cPanel-generated handlers/INI, back up the existing subdomain configuration, and verify HTTPS response headers. Publish a new source version rather than rewriting a downloaded artifact. # Version 0.5 continuation prompt and acceptance plan Continue the original PHP 8.4+ framework from 0.4.1. Preserve public APIs, MFA, the production key, accounts, data and previous downloads. Add durable background-work coordination before external delivery providers. Implement a transactional outbox on the same scoped PDO connection as application writes. Require an active producer transaction, validate bounded JSON jobs, hash explicit idempotency keys, reject conflicting reuse and retain published tombstones. Relay each message and its SQL queue insertion in one short transaction. Concurrent relays and process termination must not split that handoff. Keep the queue's at-least-once execution contract. Quarantine malformed records without payload disclosure. Provide bounded relay, status, retry and retention CLI commands. Implement named UTC schedules at whole-minute intervals, offsets and daily/hourly helpers. Persist a definition fingerprint and last slot; atomically record a slot and its outbox message. Concurrent cron processes enqueue one occurrence. Missed runs coalesce to the latest due slot, clock rollback does not replay slots and configuration changes require a new versioned name. No promise of non-overlapping execution, arbitrary cron syntax, local-time DST semantics or remote broker delivery. Wire registered security/session/outbox maintenance jobs and a bounded maintenance command. Back up the production crontab and migrate only the two framework-owned lines into one per-minute command. Preserve unrelated cron tasks. Do not send emails. Acceptance: rollback, malformed input, conflicting idempotency, delayed availability, retention, stale clock and configuration tests; process termination around handoff; competing producers/relays/schedulers on SQLite and MariaDB; core/Redis/Doctrine regressions, lint/audit, isolated PHP 8.4 server tests, archive inspection/clean install, backup/additive migration/atomic deployment, cron readback and live HTTPS/docs checks. Separate current evidence from historical runtime tests. No comparative performance or enterprise-certification claims. # Version 0.6: PHP forward-compatibility prompt Prepare the framework for later PHP 8.x releases through executable checks, not an unsupported promise about future language versions. Keep current production PHP, APP_KEY, storage, authentication behavior and cron intact. Declare a PHP 8.4.1 baseline compatible with the locked optional Symfony packages. Preserve a caret constraint accepting later PHP 8 minors but excluding unreviewed PHP 9. Pin Composer dependency resolution to that baseline and enable actual extension platform checks. Add a vendor-independent CLI preflight that reports the runtime, required extensions, selected PDO driver and optional OIDC requirements without reading secrets or opening connections. Distinguish supported stable series, experimental and unassessed minors; production preflight rejects prereleases/unassessed series. Add a repeatable lint/test verification command using the selected PHP binary. Detect E_ALL runtime diagnostics even when application error middleware catches exceptions; compiler warnings/deprecations must also fail verification. Keep diagnostics test-only, bounded and redacted. Test the gate with an intentional deprecated fixture in a private child process, never a public endpoint. Expand CI to required PHP 8.4/8.5, a latest-stable candidate and experimental 8.6/nightly builds, including locked dependencies and a fresh baseline-constrained dependency solve. Add weekly/manual triggers and retained results; never automatically deploy or change production from those jobs. Parameterize the reference container base image for explicit future runtime selection while retaining its current default. Build a checksum-verified official PHP 8.6 prerelease locally if available, run the same suite and address observed compatibility issues. Verify current stable runtimes, core and optional integrations, CLI preflight, clean source installation and live HTTPS after an atomic source deployment. Keep beta runtimes isolated. Document exact tested builds, skipped integrations, unresolved compatibility limits and the process for promoting a new minor or reviewing PHP 9. Preserve old archives and rollback releases. # Version 0.7: modular application development and developer documentation Continue 0.6 with concrete support for larger applications and an easier learning path. Reference the verified official ThinkPHP 8.1.4 and Laravel 13.31.0 releases as of 2026-09-10. Do not claim feature parity, higher production capacity or comparative speed without equivalent measurements. Implement explicitly configured modules with validated names, dependency ordering, missing/cyclic dependency rejection before lifecycle hooks, registration of all bindings before boot, and failure preventing application request handling. Keep modules optional and production registration empty. Add safe nested route prefixes, name prefixes and inherited middleware with context restoration, plus explicit non-overriding service bindings. Add a CLI module scaffold with contracts, application service, HTTP controller, provider and README. Validate its name/path, reject symlink destinations and never overwrite a module. Make registration deliberate. Add a read-only AST architecture check using a maintained development dependency: cross-module static references must name a declared dependency and its Contracts namespace; code is parsed, not executed. Explain that dynamic PHP and database access are outside this convention check and that modules are trusted code, not a sandbox. Provide an executable two-module example with contract-based collaboration and a real tenant-filtered, bounded SQLite/MariaDB read path. Verify generated code boots and serves correctly, test repeated request scope isolation and invalid dependency graphs, route group nesting, failure restoration, forbidden imports/aliases and allowed public contracts. Retain PHP 8.4/8.5 stable and isolated 8.6 checks, core and optional service regressions and diagnostic gates. Write developer documentation in Lao with copyable commands, expected results, a first-module tutorial, request/module lifecycle, team boundaries, transactions/outbox, database ownership, shared SQL/Redis deployment, bounded queries, staged scaling and troubleshooting. Provide a factual comparison and mark unverified scale and operational requirements. Include source and immutable downloadable evidence. Preserve production PHP, APP_KEY, private data/MFA, schema, cron and existing downloads. Verify a clean source install, desktop/mobile documentation and live HTTPS after consistent backup and atomic deployment. Keep 0.6 as a compatible rollback point. Do not activate demo modules or send external messages in production. # Version 0.8: operational readiness and coordinated maintenance Continue 0.7 by making dependency failures and background-work stalls diagnosable. Keep production PHP, APP_KEY, private data, schema, cron and module configuration unchanged. No new public administration or metrics endpoint. Add private ops:check JSON and ops:metrics Prometheus text CLI commands with fixed fields, explicit alert exit status and configurable age thresholds. Separate queue ready, delayed, leased, exhausted and failed states; expired leases are an overlapping diagnostic. Measure ready age from current eligibility, and outbox relay age from message creation even for future jobs. Read background state without reservation, relay, retry or scheduler advancement. Missing metrics must remain unavailable, not fabricate healthy zero counts. Scheduler lag begins at the earliest missed persisted slot; never-run definitions are explicit alerts. Emit no payloads, lease tokens, account details, DSNs, keys or exception messages. Strengthen public readiness with actual database connectivity, read-only migration status, a short-lived isolated cache set/get/delete and required writable directories. Return only ready/unavailable; dependency failure gives 503. Keep liveness independent of these probes. State I/O timeout and metadata-only migration limitations precisely. Add migrate:status without running source files or creating the ledger. Coordinate MySQL/MariaDB migrate runners through a nonblocking database-scoped advisory lock on the same server, while retaining SQLite file locking. Reject outer transactions before DDL and release locks on every path. Preserve a designated deployment coordinator for clustered databases. Extend worker run bounds with an explicit lease and memory threshold, monotonic elapsed time and graceful signals. Bounds apply between jobs; long-running jobs need supervised timeouts, heartbeats and idempotency. Include queue and duration in safe structured logs. A logging failure after acknowledgment must not falsely mark completed work failed. Provide a Lao operations chapter and integrate it into the downloadable guide. Test actual SQLite/MariaDB queries and process contention, Redis roundtrip and failure behavior, worker SIGTERM/drain, CLI exit codes and metrics syntax, regression suites on stable/server and isolated candidate PHP. Verify clean source installation and desktop/mobile/live HTTPS, back up consistently, switch release atomically and retain 0.7 rollback. Distinguish measured local recovery evidence from unperformed production outage, HA, tracing and long soak tests. # Version 0.9: explicit application features Continue the verified 0.8 release with private local file storage and upload policies; opt-in CORS; expiring signed URLs; immutable localization; strict extra validation rules; public API projections, RFC9457 problem responses and explicit OpenAPI3.1.2 descriptions. Preserve all existing auth/MFA/tenant/module/queue/operations contracts and APP_KEY/private state. Use explicit enablement and bounded inputs. Multipart stays denied except exact configured POST paths; retain CSRF/authentication and trusted SAPI parsing. Store objects outside the document root under opaque IDs with restrictive permissions, bounded streams and atomic no-overwrite publication. Validate actual MIME with optional ext-fileinfo; never imply antivirus or automatic authorization. CORS uses exact trusted origins, bounded methods/headers and correct Vary. Signed URLs bind trusted origin/method/path/raw canonical query/expiry with purpose-separated keys and constant-time verification; reject ambiguity and preserve no-store/no-referrer on signed responses. Document replay, logs, query-parser trust and downstream error middleware boundaries. Keep translation catalogues immutable and locales explicit per call. Extra validation is strict, handles invalid schema even for absent fields and never silently exposes confirmation input. Public resource fields use a defensively copied allowlist. Problem responses accept deliberate public messages only. API specification contains selected reviewed routes and explicit security metadata; CLI checks route existence only, never claims runtime contract/auth enforcement. Provide Lao feature catalogue and task-based guides, runnable disposable example, adversarial regression tests and real PHP multipart checks. Verify official OpenAPI schema and real endpoint samples, full service-backed stable/candidate suites, server production-dependency suites, clean archive installation, desktop/mobile browser and live HTTPS. Preserve previous immutable downloads; back up DB/config/cron and switch releases atomically. No new production upload endpoint, CORS policy, external service, account, migration, cron or PHP-handler change. No claim of all possible features, framework superiority, enterprise certification, malware-free content, untested future PHP compatibility, production HA or completed external provider integration. Keep concrete evidence and remaining integration boundaries public. # Version 0.10: practical configuration, data safety and HTTP reliability Continue the verified 0.9 preview by reproducing operational failure cases and fixing the concrete problems they reveal. Preserve production PHP, APP_KEY, private accounts/MFA/data, schema, cron, module configuration and immutable prior downloads. This is a targeted engineering review and improvement release, not a formal comprehensive security audit or a claim of framework superiority. ## Configuration and installation Preserve exact quoted environment values without interpolation or shell evaluation; reject duplicate keys, malformed quoting and invalid booleans. Snapshot process settings at bootstrap. Validate explicit environment names, HTTPS/debug rules for staging and production, exact host agreement, encoded key, private file destinations and selected optional Redis/OIDC requirements. Check private permissions and resolved targets of any staging/production `.env`, while supporting environment-only secret injection. Provide `config:check [--production]` without application bootstrap, network connections or filesystem mutation, with fixed public-safe diagnostic fields. Support explicit stderr logging and test a fresh installed application rather than relying on an existing populated storage tree. ## Data safety and recovery Make update/delete reject configured orderBy/limit before writing. Never silently drop a caller's intended read bound. Document explicitly selected identifiers, repeated tenant/authorization conditions and application transaction/concurrency requirements; retain the mandatory WHERE guard. Provide `backup:create --output=/absolute/new.sqlite` for existing file-backed SQLite main databases and `backup:verify /absolute/existing.sqlite` without application bootstrap. Use a consistent VACUUM INTO snapshot, private mode-0700 canonical parents, mode-0600 files, no symlinks or overwrite, and no destinations under public/. Verify integrity, foreign keys, stable file/schema hashes and fixed counts through read-only SQLite with locking. Reject outer transactions, attached databases, in-memory/MySQL sources, live WAL artifacts and sidecars. Synchronize and publish using a no-overwrite hard link, remove unpublished partial files during normal failure cleanup, and explain after-publication synchronization failures and abrupt-termination leftovers. Exercise WAL commits, another connection's uncommitted rows, corruption, invalid foreign keys, path/mode guards and competing creators using isolated fixtures. Restore a verified snapshot into a fresh isolated application and check configuration/key continuity, MFA/decryption, sessions, application data, migration status and queued work. Document that point-in-time restoration can revive sessions, recovery codes, reset tokens and jobs; reconcile later revocations and already-applied external effects before a real recovery resumes traffic. No automatic live overwrite or restore command is introduced. Native MySQL recovery, off-host retention, key/configuration/uploads and disaster procedures remain operator responsibilities. ## HTTP and immutable policy state Keep a completed response usable when HTTP access/error logging fails; emit only a fixed fallback diagnostic. Preserve the original generic failure response and security headers. With the standard outer Errors middleware, retain CORS Vary/grant policy and signed-link privacy across downstream HTTP exceptions and unexpected failures, including both nesting orders. Keep denial, CSRF and route authorization enforced; remove obsolete advice requiring a second inner Errors middleware. Snapshot validated identity roles, role-permission maps and CORS policy lists so caller-owned references cannot mutate accepted policy. Share the request creator between SAPI and Swoole without counting a URI-derived Host as another incoming line. When a SAPI omits Host from getallheaders but supplies actual HTTP_HOST, recover that value only if no Host header was supplied. Never deduplicate actual header values or synthesize a signed Host from SERVER_NAME. Check hostless HTTP/1.0, default/nondefault ports, signed GET/HEAD and tampered requests in actual adapters. ## Evidence and release Run diagnostic-aware lint and full suites with actual MariaDB/Redis on stable and isolated candidate PHP, preserving explicit skips. Test configuration/data/HTTP changes on hosting PHP with production dependencies. Run actual SAPI, FrankenPHP and Swoole fault/signed-request regressions, clean archive installation, a restore drill, desktop/mobile documentation and live HTTPS. Keep exact final counts in [VERIFICATION.md](docs/VERIFICATION.md), and reviewed findings/limits in [READINESS-REVIEW.md](docs/READINESS-REVIEW.md). Provide current Lao operational documentation and corrected copyable examples. Back up consistently, compare schema/config/key/account preservation, stage the reviewed release and atomically switch code. No migration, cron or PHP-handler change, public upload/CORS activation, example-module enablement, provider onboarding or external message delivery is required. Retain the previous verified release for coordinated code rollback; code rollback does not restore data or erase the fixes it removes. Current tests establish observed behavior, not production HA, workload capacity, long-soak resilience, independent security certification or comparative framework performance.