From d91ba074159e214ee2c9f1cf6896e64627a55c1a Mon Sep 17 00:00:00 2001 From: "A. B. M. Mahmudul Hasan" Date: Sun, 23 Aug 2026 10:34:17 +0600 Subject: [PATCH 01/51] chore: target Foundation 2.0 branch --- composer.json | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/composer.json b/composer.json index 08f0a6d..514e548 100644 --- a/composer.json +++ b/composer.json @@ -4,8 +4,8 @@ "license": "MIT", "type": "project", "require": { - "php": ">=8.4", - "infocyph/foundation": "^1.3" + "php": "^8.4", + "infocyph/foundation": "dev-feature/foundation-2.0 as 2.0.x-dev" }, "require-dev": { "infocyph/phpforge": "dev-main@dev" From 9545ee27714c4cc6f5002eb78ed5e3e94f281785 Mon Sep 17 00:00:00 2001 From: "A. B. M. Mahmudul Hasan" Date: Sun, 23 Aug 2026 10:34:22 +0600 Subject: [PATCH 02/51] refactor: delegate CLI to Foundation dispatcher --- infbyte | 52 ++++++++++------------------------------------------ 1 file changed, 10 insertions(+), 42 deletions(-) diff --git a/infbyte b/infbyte index 6327240..694f8de 100755 --- a/infbyte +++ b/infbyte @@ -3,49 +3,17 @@ declare(strict_types=1); -use Composer\InstalledVersions; -use Infocyph\Foundation\Application\Application; -use Infocyph\Foundation\Console\FoundationConsole; -use Infocyph\Foundation\Config\EnvironmentLoader; +use Infocyph\Foundation\Command\CommandDispatcher; -require __DIR__ . '/vendor/autoload.php'; - -$basePath = __DIR__; -$commandManifest = $basePath . '/bootstrap/cache/console/commands.php'; -$commands = []; - -new EnvironmentLoader()->load($basePath); -$applicationName = trim(env_string('APP_NAME', 'infbyte')); -if ($applicationName === '') { - $applicationName = 'infbyte'; +$autoload = __DIR__ . '/vendor/autoload.php'; +if (!is_file($autoload)) { + fwrite(STDERR, "Unable to locate vendor/autoload.php; run composer install first.\n"); + exit(1); } -if (!is_file($commandManifest)) { - $commands = require $basePath . '/routes/console.php'; - - if (!is_array($commands)) { - throw new RuntimeException('Console routes must return a command-to-class map.'); - } -} - -$console = FoundationConsole::create( - applicationFactory: static function (?string $profile) use ($basePath): Application { - $application = require $basePath . '/bootstrap/console.php'; - - if ($profile !== null && $application->environment() !== $profile) { - throw new RuntimeException(sprintf( - 'Console profile "%s" does not match the application environment "%s".', - $profile, - $application->environment() ?? '', - )); - } - - return $application; - }, - name: $applicationName, - version: InstalledVersions::getPrettyVersion('infocyph/foundation') ?? 'dev-main', - commands: $commands, - commandManifest: $commandManifest, -); +require $autoload; -exit($console->run()); +exit(CommandDispatcher::project( + ['base_path' => __DIR__], + displayName: 'Infbyte', +)->run($argv)); From 2aad104fdd3407e5b9ede0d8b1bd23f7e6fdac86 Mon Sep 17 00:00:00 2001 From: "A. B. M. Mahmudul Hasan" Date: Sun, 23 Aug 2026 10:34:29 +0600 Subject: [PATCH 03/51] refactor: align provider runtime groups --- bootstrap/providers.php | 16 ++++++++++++++-- 1 file changed, 14 insertions(+), 2 deletions(-) diff --git a/bootstrap/providers.php b/bootstrap/providers.php index 70ceb85..4b0a029 100644 --- a/bootstrap/providers.php +++ b/bootstrap/providers.php @@ -15,10 +15,22 @@ * \App\Providers\WebServiceProvider::class, */ ], - 'console' => [ + 'cli' => [ /** * Usage: - * \App\Providers\ConsoleServiceProvider::class, + * \App\Providers\CliServiceProvider::class, + */ + ], + 'worker' => [ + /** + * Usage: + * \App\Providers\WorkerServiceProvider::class, + */ + ], + 'scheduler' => [ + /** + * Usage: + * \App\Providers\SchedulerServiceProvider::class, */ ], ]; From 9bb4283413965cb0da8805ffe251317b60910ec1 Mon Sep 17 00:00:00 2001 From: "A. B. M. Mahmudul Hasan" Date: Sun, 23 Aug 2026 10:34:39 +0600 Subject: [PATCH 04/51] config: align application defaults with Foundation 2.0 --- config/app.php | 42 ++++++++++++++---------------------------- 1 file changed, 14 insertions(+), 28 deletions(-) diff --git a/config/app.php b/config/app.php index 8c5ecc6..6233f19 100644 --- a/config/app.php +++ b/config/app.php @@ -8,16 +8,15 @@ | Application Identity |-------------------------------------------------------------------------- | - | "name" labels the application in diagnostics and integrations. "env" - | selects environment-sensitive defaults, "debug" enables development - | diagnostics, and "url" is the canonical base URL used to build links. - | Names and environments are free-form strings, for example `Acme API` and - | `staging`; debug accepts `true|false`; URL example: `https://api.acme.test`. + | Infbyte owns application-facing defaults while Foundation owns the runtime + | implementation. "name" labels diagnostics and integrations, "env" selects + | environment-sensitive policy, "debug" enables development diagnostics, + | and "url" is the application's canonical external base URL. | */ 'name' => env('APP_NAME', 'Infbyte'), 'env' => env('APP_ENV', 'local'), - 'debug' => env('APP_DEBUG', true), + 'debug' => env_bool('APP_DEBUG', true), 'url' => env('APP_URL', 'http://localhost'), /* @@ -25,10 +24,9 @@ | Configuration Cache |-------------------------------------------------------------------------- | - | "type" accepts "sharded" or "single". Sharded caches load namespaces - | on demand; single caches load one compiled snapshot. Build either form - | during deployment with `php infbyte config:cache`. Allowed values: - | `sharded|single`. + | Sharded config remains the normal application default so namespaces stay + | lazy. Build the selected artifact explicitly during deployment. + | Allowed values: sharded|single. | */ 'config_cache' => [ @@ -37,34 +35,22 @@ /* |-------------------------------------------------------------------------- - | Dependency Injection Container + | InterMix Container |-------------------------------------------------------------------------- | - | "alias" optionally names a configured container profile. "environment" - | controls environment-aware definitions. "lazy_loading" defers supported - | services, while "request_scope" isolates request-lived entries. - | - | "compiled" selects the application-owned resolver artifact. Activation - | remains off unless a measured deployment explicitly selects "always". - | Debug tracing is disabled by default; "level" selects its detail. - | - | Alias/environment examples: `http` and `production`. Boolean switches use - | `true|false`. The compiled artifact defaults to - | `bootstrap/cache/container.php`; APP_CONTAINER_COMPILED may select another - | application-owned relative or absolute path. - | Compiled activation values: `off|always`. - | Trace levels: `off|node|info|warn|warning|error|verbose`. + | Foundation 2.0 is lazy by default and owns execution scopes directly. + | There is no application request_scope switch. Compiled container activation + | remains opt-in until a deployment deliberately builds and enables it. | */ 'container' => [ 'alias' => env('APP_CONTAINER_ALIAS'), 'environment' => env('APP_ENV', 'local'), - 'lazy_loading' => env('APP_CONTAINER_LAZY_LOADING', false), - 'request_scope' => env('APP_CONTAINER_REQUEST_SCOPE', true), + 'lazy_loading' => env_bool('APP_CONTAINER_LAZY_LOADING', true), 'compiled' => env('APP_CONTAINER_COMPILED', 'bootstrap/cache/container.php'), 'compiled_activation' => env('APP_CONTAINER_COMPILED_ACTIVATION', 'off'), 'debug_tracing' => [ - 'enabled' => env('APP_CONTAINER_DEBUG_TRACING', false), + 'enabled' => env_bool('APP_CONTAINER_DEBUG_TRACING', false), 'level' => env('APP_CONTAINER_DEBUG_TRACE_LEVEL', 'node'), ], ], From d6e771b9309156e672138078af8b75a734d0cde4 Mon Sep 17 00:00:00 2001 From: "A. B. M. Mahmudul Hasan" Date: Sun, 23 Aug 2026 10:34:57 +0600 Subject: [PATCH 05/51] config: remove retired auth ID driver --- config/auth.php | 62 +++++++++++-------------------------------------- 1 file changed, 14 insertions(+), 48 deletions(-) diff --git a/config/auth.php b/config/auth.php index d8664ce..4c6bcc7 100644 --- a/config/auth.php +++ b/config/auth.php @@ -8,18 +8,13 @@ | Authentication Drivers |-------------------------------------------------------------------------- | - | Each key selects the implementation for one authentication capability. - | IDs: `random|uid`. Storage: `memory|database`. Cache: - | `array|cache`. Passwords: `native|security`. Tokens: - | `simple|security`. MFA: `simple|otp`. Notifications: - | `collect|talkingbytes`. Passkeys: `disabled|memory|webauthn`. - | - | The self-contained defaults keep auth adapters optional. Production auth - | must install and explicitly select the durable modules it requires. + | Foundation 2.0 owns identity generation through UID, so authentication no + | longer exposes an ID driver. These switches select only replaceable auth + | capabilities. The Infbyte defaults stay dependency-light; production may + | opt into the durable specialist modules it requires. | */ 'drivers' => [ - 'ids' => env('AUTH_IDS', 'random'), 'storage' => env('AUTH_STORAGE', 'memory'), 'cache' => env('AUTH_CACHE', 'array'), 'passwords' => env('AUTH_PASSWORDS', 'native'), @@ -34,11 +29,8 @@ | Token Signing Secret |-------------------------------------------------------------------------- | - | This secret protects authentication tokens. It has no config-file - | default. Local runtime may supply its development-only fallback, while - | production rejects missing or short values. Set AUTH_TOKEN_SECRET to a - | unique high-entropy secret of at least 32 bytes and never commit it. - | Example format: a randomly generated 64-character hexadecimal string. + | app:install generates this value for a new application. Production must + | use unique high-entropy secret material and must never commit it. | */ 'token_secret' => env('AUTH_TOKEN_SECRET'), @@ -47,39 +39,25 @@ |-------------------------------------------------------------------------- | One-Time Passwords |-------------------------------------------------------------------------- - | - | "issuer" is shown by authenticator applications. "freshness_window" is - | the number of seconds an MFA result remains recent. TOTP "algorithm", - | `digits`, `period`, and `secret_bytes` define provisioning parameters. - | "window" is the accepted number of adjacent time steps. - | - | Recovery-code "count" and "length" control the generated backup set. - | Replay protection records consumed codes when "enabled" and retains each - | marker for "ttl" seconds. Keep replay protection enabled in production. - | - | Issuer example: `Acme`. Algorithm: `sha1|sha256|sha512`. Digits: `4..10`. - | Period: `1..86400` seconds. Window: `0..100` time steps. Secret bytes, - | recovery count/length, freshness, and replay TTL are positive integers. - | Typical values respectively are 64, 10, 10, 900, and 90. Replay accepts - | `true|false`. - | */ 'otp' => [ 'issuer' => env('AUTH_OTP_ISSUER', env('APP_NAME', 'Infbyte')), - 'freshness_window' => env_int('AUTH_OTP_FRESHNESS_WINDOW', 900), + 'hotp' => [ + 'look_ahead' => env_int('AUTH_OTP_HOTP_LOOK_AHEAD', 5), + ], 'totp' => [ 'algorithm' => env('AUTH_OTP_ALGORITHM', 'sha1'), 'digits' => env_int('AUTH_OTP_DIGITS', 6), 'period' => env_int('AUTH_OTP_PERIOD', 30), - 'secret_bytes' => env_int('AUTH_OTP_SECRET_BYTES', 64), + 'secret_bytes' => env_int('AUTH_OTP_SECRET_BYTES', 20), 'window' => env_int('AUTH_OTP_WINDOW', 1), ], 'recovery_codes' => [ 'count' => env_int('AUTH_OTP_RECOVERY_CODES', 10), - 'length' => env_int('AUTH_OTP_RECOVERY_LENGTH', 10), + 'length' => env_int('AUTH_OTP_RECOVERY_LENGTH', 12), ], 'replay' => [ - 'enabled' => env('AUTH_OTP_REPLAY', true), + 'store' => env('AUTH_OTP_REPLAY_STORE'), 'ttl' => env_int('AUTH_OTP_REPLAY_TTL', 90), ], ], @@ -88,24 +66,12 @@ |-------------------------------------------------------------------------- | WebAuthn / Passkeys |-------------------------------------------------------------------------- - | - | "rp_id", "rp_name", and "origin" identify the relying party and must - | match the deployed domain. `attestation` controls authenticator evidence. - | "user_verification" and "resident_key" use WebAuthn preference values. - | "algorithms" lists accepted COSE algorithms and "transports" lists the - | authenticator transports advertised during registration. - | - | RP ID example: `example.com`; RP name example: `Acme`; origin example: - | `https://example.com`. Attestation: `none|direct|indirect|enterprise`. - | User verification and resident key: `required|preferred|discouraged`. - | Algorithms: `ES256|RS256`. Transports: `internal|hybrid|usb|nfc|ble`. - | */ 'webauthn' => [ 'rp_id' => env('WEBAUTHN_RP_ID'), - 'rp_name' => env('WEBAUTHN_RP_NAME', 'Infbyte'), + 'rp_name' => env('WEBAUTHN_RP_NAME', env('APP_NAME', 'Infbyte')), 'origin' => env('WEBAUTHN_ORIGIN'), - 'attestation' => 'none', + 'attestation' => env('WEBAUTHN_ATTESTATION', 'none'), 'user_verification' => env('WEBAUTHN_USER_VERIFICATION', 'preferred'), 'resident_key' => env('WEBAUTHN_RESIDENT_KEY', 'preferred'), 'algorithms' => ['ES256', 'RS256'], From 1963a28bea82257434e1d6897811b5ca6203874e Mon Sep 17 00:00:00 2001 From: "A. B. M. Mahmudul Hasan" Date: Sun, 23 Aug 2026 10:35:03 +0600 Subject: [PATCH 06/51] config: align environment example with Foundation 2.0 --- .env.example | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/.env.example b/.env.example index d6a84f9..260f7b5 100644 --- a/.env.example +++ b/.env.example @@ -8,7 +8,6 @@ APP_CONTAINER_COMPILED_ACTIVATION=off ROUTER_MATCHER=fused -AUTH_IDS=random AUTH_STORAGE=memory AUTH_CACHE=array AUTH_PASSWORDS=native @@ -16,4 +15,4 @@ AUTH_TOKENS=simple AUTH_MFA=simple AUTH_NOTIFICATIONS=collect AUTH_PASSKEY=disabled -AUTH_TOKEN_SECRET=foundation-dev-secret +AUTH_TOKEN_SECRET= From 06659b1d44558929999e2510e7314148a5ddc4e4 Mon Sep 17 00:00:00 2001 From: "A. B. M. Mahmudul Hasan" Date: Sun, 23 Aug 2026 10:35:12 +0600 Subject: [PATCH 07/51] refactor: add CLI runtime bootstrap --- bootstrap/cli.php | 10 ++++++++++ 1 file changed, 10 insertions(+) create mode 100644 bootstrap/cli.php diff --git a/bootstrap/cli.php b/bootstrap/cli.php new file mode 100644 index 0000000..bffc729 --- /dev/null +++ b/bootstrap/cli.php @@ -0,0 +1,10 @@ + $options */ +$options = require __DIR__ . '/options.php'; + +return Foundation::cli($options); From b30436c9ba1cdaf7fa9c51af724f698e9d53fe28 Mon Sep 17 00:00:00 2001 From: "A. B. M. Mahmudul Hasan" Date: Sun, 23 Aug 2026 10:35:17 +0600 Subject: [PATCH 08/51] refactor: remove retired console bootstrap --- bootstrap/console.php | 10 ---------- 1 file changed, 10 deletions(-) delete mode 100644 bootstrap/console.php diff --git a/bootstrap/console.php b/bootstrap/console.php deleted file mode 100644 index 55734cd..0000000 --- a/bootstrap/console.php +++ /dev/null @@ -1,10 +0,0 @@ - $options */ -$options = require __DIR__ . '/options.php'; - -return Foundation::console($options); From ca48996eb49fbb185904865ddb0cf9c48bd8fa57 Mon Sep 17 00:00:00 2001 From: "A. B. M. Mahmudul Hasan" Date: Sun, 23 Aug 2026 10:35:25 +0600 Subject: [PATCH 09/51] config: remove retired ID driver configuration --- config/ids.php | 208 ------------------------------------------------- 1 file changed, 208 deletions(-) delete mode 100644 config/ids.php diff --git a/config/ids.php b/config/ids.php deleted file mode 100644 index cc4e190..0000000 --- a/config/ids.php +++ /dev/null @@ -1,208 +0,0 @@ - env('IDS_DEFAULT', 'uuid7'), - - /* - |-------------------------------------------------------------------------- - | Shared Sequence Coordination - |-------------------------------------------------------------------------- - | - | "driver" selects the sequence backend and "directory" stores filesystem - | sequence state. "wait_time" is the lock retry delay in microseconds and - | "max_attempts" bounds acquisition attempts. Distributed deployments must - | use sequence state that is shared by every participating node. - | Drivers: `file|filesystem|memory`. Directory example: `cache/ids`. - | Wait/max-attempt examples: `1000` microseconds and `1000` attempts. - | - */ - 'sequence' => [ - 'driver' => env('IDS_SEQUENCE_DRIVER', 'filesystem'), - 'directory' => env_string('IDS_SEQUENCE_DIRECTORY', 'cache/ids'), - 'wait_time' => env_int('IDS_SEQUENCE_WAIT_TIME', 1000), - 'max_attempts' => env_int('IDS_SEQUENCE_MAX_ATTEMPTS', 1000), - ], - - /* - |-------------------------------------------------------------------------- - | ULID, NanoID And CUID2 - |-------------------------------------------------------------------------- - | - | ULID "mode" controls random or monotonic ordering. NanoID and CUID2 - | "length" values control their textual output size and collision budget. - | ULID modes: `monotonic|random`. NanoID length: `1..1048576`, example `21`. - | CUID2 length: `2..32`, example `24`. - | - */ - 'ulid' => [ - 'mode' => env('IDS_ULID_MODE', 'monotonic'), - ], - 'nanoid' => [ - 'length' => env_int('IDS_NANOID_LENGTH', 21), - ], - 'cuid2' => [ - 'length' => env_int('IDS_CUID2_LENGTH', 24), - ], - - /* - |-------------------------------------------------------------------------- - | Opaque And Deterministic Identifiers - |-------------------------------------------------------------------------- - | - | Opaque IDs use "length" for output size and "salt" for application-level - | separation. Deterministic IDs use "length" and "namespace" to keep equal - | inputs isolated by purpose. Use high-entropy secrets where the selected - | generator treats a salt as confidential. Opaque length: `1..1024`, example - | `12`; salt example: a random application-specific string. Deterministic - | length: `1..43`, example `24`; namespace example: `invoice`. - | - */ - 'opaque' => [ - 'length' => env_int('IDS_OPAQUE_LENGTH', 12), - 'salt' => env_string('IDS_OPAQUE_SALT', ''), - ], - 'deterministic' => [ - 'length' => env_int('IDS_DETERMINISTIC_LENGTH', 24), - 'namespace' => env_string('IDS_DETERMINISTIC_NAMESPACE', 'default'), - ], - - /* - |-------------------------------------------------------------------------- - | Snowflake Identifiers - |-------------------------------------------------------------------------- - | - | "datacenter_id" and "worker_id" must uniquely identify the generator. - | "custom_epoch" sets the timestamp origin, "clock_backward_policy" controls - | rollback handling, and "output" selects the returned representation. - | Sequence "driver" and "directory" override the shared defaults above. - | Datacenter/worker examples: `3` and `17`; epoch examples: Unix milliseconds - | or `2024-01-01T00:00:00Z`. Clock policy: `wait|throw`. Output: - | `string|int|binary`. Sequence drivers: `file|filesystem|memory`. - | - */ - 'snowflake' => [ - 'datacenter_id' => env_int('IDS_SNOWFLAKE_DATACENTER_ID', 0), - 'worker_id' => env_int('IDS_SNOWFLAKE_WORKER_ID', 0), - 'custom_epoch' => env('IDS_SNOWFLAKE_CUSTOM_EPOCH'), - 'clock_backward_policy' => env('IDS_SNOWFLAKE_CLOCK_BACKWARD_POLICY', 'wait'), - 'output' => env('IDS_SNOWFLAKE_OUTPUT', 'string'), - 'sequence' => [ - 'driver' => env('IDS_SNOWFLAKE_SEQUENCE_DRIVER', env('IDS_SEQUENCE_DRIVER', 'filesystem')), - 'directory' => env_string('IDS_SNOWFLAKE_SEQUENCE_DIRECTORY', env_string('IDS_SEQUENCE_DIRECTORY', 'cache/ids')), - ], - ], - - /* - |-------------------------------------------------------------------------- - | Sonyflake Identifiers - |-------------------------------------------------------------------------- - | - | "machine_id" must be unique among active generators. "custom_epoch", - | "clock_backward_policy", and "output" control time origin, rollback - | handling, and representation. Sequence keys override shared coordination. - | Machine example: `42`; epoch example: `2024-01-01T00:00:00Z`; clock policy: - | `wait|throw`; output: `string|int|binary`; sequence driver: - | `file|filesystem|memory`; directory example: `cache/ids`. - | - */ - 'sonyflake' => [ - 'machine_id' => env_int('IDS_SONYFLAKE_MACHINE_ID', 0), - 'custom_epoch' => env('IDS_SONYFLAKE_CUSTOM_EPOCH'), - 'clock_backward_policy' => env('IDS_SONYFLAKE_CLOCK_BACKWARD_POLICY', 'wait'), - 'output' => env('IDS_SONYFLAKE_OUTPUT', 'string'), - 'sequence' => [ - 'driver' => env('IDS_SONYFLAKE_SEQUENCE_DRIVER', env('IDS_SEQUENCE_DRIVER', 'filesystem')), - 'directory' => env_string('IDS_SONYFLAKE_SEQUENCE_DIRECTORY', env_string('IDS_SEQUENCE_DIRECTORY', 'cache/ids')), - ], - ], - - /* - |-------------------------------------------------------------------------- - | TBSL Identifiers - |-------------------------------------------------------------------------- - | - | "machine_id" identifies the node, "sequenced" enables coordinated values, - | "clock_backward_policy" defines rollback behavior, and "output" selects - | representation. Sequence "driver" and "directory" are profile overrides. - | A machine ID may be 42. Sequenced accepts `true|false`; clock policy accepts - | `wait|throw`; output accepts `string|int|binary`; and sequence driver accepts - | `file|filesystem|memory`. A sequence directory may be `cache/ids`. - | - */ - 'tbsl' => [ - 'machine_id' => env_int('IDS_TBSL_MACHINE_ID', 0), - 'sequenced' => env_bool('IDS_TBSL_SEQUENCED', false), - 'clock_backward_policy' => env('IDS_TBSL_CLOCK_BACKWARD_POLICY', 'wait'), - 'output' => env('IDS_TBSL_OUTPUT', 'string'), - 'sequence' => [ - 'driver' => env('IDS_TBSL_SEQUENCE_DRIVER', env('IDS_SEQUENCE_DRIVER', 'filesystem')), - 'directory' => env_string('IDS_TBSL_SEQUENCE_DIRECTORY', env_string('IDS_SEQUENCE_DIRECTORY', 'cache/ids')), - ], - ], - - /* - |-------------------------------------------------------------------------- - | Randflake Identifiers - |-------------------------------------------------------------------------- - | - | "node_id" identifies the generator. "lease_start" and "lease_end" bound - | its allocated range; "secret" protects generator-specific derivation and - | must be replaced in production. "output" selects representation, while - | sequence "driver" and "directory" override shared coordination settings. - | Node example: `7`; lease example: `100000..199999`; secret example: a - | random 32-byte Base64 string; output: `string|int|binary`; sequence driver: - | `file|filesystem|memory`; directory example: `cache/ids`. - | - */ - 'randflake' => [ - 'node_id' => env_int('IDS_RANDFLAKE_NODE_ID', 0), - 'lease_start' => env_int('IDS_RANDFLAKE_LEASE_START', 0), - 'lease_end' => env_int('IDS_RANDFLAKE_LEASE_END', 0), - 'secret' => env_string('IDS_RANDFLAKE_SECRET', 'change-me'), - 'output' => env('IDS_RANDFLAKE_OUTPUT', 'string'), - 'sequence' => [ - 'driver' => env('IDS_RANDFLAKE_SEQUENCE_DRIVER', env('IDS_SEQUENCE_DRIVER', 'filesystem')), - 'directory' => env_string('IDS_RANDFLAKE_SEQUENCE_DIRECTORY', env_string('IDS_SEQUENCE_DIRECTORY', 'cache/ids')), - ], - ], - - /* - |-------------------------------------------------------------------------- - | Authentication Identifier Purposes - |-------------------------------------------------------------------------- - | - | Each key selects the generator for that auth record type: accounts, audit - | events, challenges, correlations, credentials, devices, grants, - | permissions, roles, and sessions. Keep persisted types stable after data - | exists unless a migration explicitly handles the representation change. - | Every value accepts one of the generator names listed under Default - | Identifier. Example: account `uuid7`, correlation `ulid`, session `uuid7`. - | - */ - 'auth' => [ - 'account' => env('IDS_AUTH_ACCOUNT', 'uuid7'), - 'audit_event' => env('IDS_AUTH_AUDIT_EVENT', 'uuid7'), - 'challenge' => env('IDS_AUTH_CHALLENGE', 'uuid7'), - 'correlation' => env('IDS_AUTH_CORRELATION', 'ulid'), - 'credential' => env('IDS_AUTH_CREDENTIAL', 'uuid7'), - 'device' => env('IDS_AUTH_DEVICE', 'uuid7'), - 'grant' => env('IDS_AUTH_GRANT', 'uuid7'), - 'permission' => env('IDS_AUTH_PERMISSION', 'uuid7'), - 'role' => env('IDS_AUTH_ROLE', 'uuid7'), - 'session' => env('IDS_AUTH_SESSION', 'uuid7'), - ], -]; From d5bdd494ec52a8c58d03d364dd31518138fb6ce3 Mon Sep 17 00:00:00 2001 From: "A. B. M. Mahmudul Hasan" Date: Sun, 23 Aug 2026 10:36:10 +0600 Subject: [PATCH 10/51] deploy: align optimized artifact directories --- deploy.sh | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/deploy.sh b/deploy.sh index e06223d..5843cbd 100755 --- a/deploy.sh +++ b/deploy.sh @@ -28,7 +28,6 @@ fi runtime_directories=( "bootstrap/cache" "bootstrap/cache/config" - "bootstrap/cache/console" "bootstrap/cache/routes" "storage" "storage/app" @@ -74,4 +73,4 @@ php_path="$(command -v "$php_bin")" "$php_path" infbyte optimize -printf 'Deployment directories and application caches are ready.\n' +printf 'Deployment directories and Foundation 2.0 runtime artifacts are ready.\n' From 24f6125ac145f338e2b1214dd5fcd3e67c791256 Mon Sep 17 00:00:00 2001 From: "A. B. M. Mahmudul Hasan" Date: Sun, 23 Aug 2026 10:36:17 +0600 Subject: [PATCH 11/51] chore: ignore generated Foundation artifacts --- .gitignore | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/.gitignore b/.gitignore index af056dd..f9c3dc0 100644 --- a/.gitignore +++ b/.gitignore @@ -9,9 +9,8 @@ /.route-cache-* /.vscode/ /.windsurf/ -/bootstrap/cache/container.php -/bootstrap/cache/modules.php -/bootstrap/cache/optimize.php +/bootstrap/cache/* +!/bootstrap/cache/.gitignore /database/*.sqlite /vendor/ *~ From 456482094f98d82b5f89c37ebac57a11477d2d5e Mon Sep 17 00:00:00 2001 From: "A. B. M. Mahmudul Hasan" Date: Sun, 23 Aug 2026 10:36:23 +0600 Subject: [PATCH 12/51] chore: keep bootstrap cache directory --- bootstrap/cache/.gitignore | 2 ++ 1 file changed, 2 insertions(+) create mode 100644 bootstrap/cache/.gitignore diff --git a/bootstrap/cache/.gitignore b/bootstrap/cache/.gitignore new file mode 100644 index 0000000..d6b7ef3 --- /dev/null +++ b/bootstrap/cache/.gitignore @@ -0,0 +1,2 @@ +* +!.gitignore From 0e99c50fd024213f3859c092ce3a9ed99b2dc1c7 Mon Sep 17 00:00:00 2001 From: "A. B. M. Mahmudul Hasan" Date: Sun, 23 Aug 2026 10:37:06 +0600 Subject: [PATCH 13/51] docs: add Infbyte Foundation 2.0 live plan --- infbyte_work_plan.md | 207 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 207 insertions(+) create mode 100644 infbyte_work_plan.md diff --git a/infbyte_work_plan.md b/infbyte_work_plan.md new file mode 100644 index 0000000..0735ac7 --- /dev/null +++ b/infbyte_work_plan.md @@ -0,0 +1,207 @@ +# Infbyte — Foundation 2.0 Live Work Plan + +> Current execution tracker for migrating the Infbyte application skeleton to Foundation 2.0. + +## Working branches + +- Infbyte: `feature/foundation-2.0` +- Foundation: `feature/foundation-2.0` + +The two branches are developed together. Foundation remains the reusable runtime/framework layer; Infbyte remains the opinionated application skeleton. + +## Maintenance rule + +After each completed joint batch: + +1. record the latest Infbyte and Foundation source checkpoints; +2. move finished work to **Completed**; +3. keep **Immediate next work** limited to the next concrete cross-repo phase; +4. do not reintroduce Foundation 1.x/Console compatibility; +5. keep specialist-library engines in their owning packages; +6. keep the full PHPUnit/static-analysis/PHPForge/release matrix deferred until implementation/config/docs are stable. + +## Current checkpoint + +- Date: 2026-08-23 +- Infbyte source checkpoint: `456482094f98d82b5f89c37ebac57a11477d2d5e` +- Foundation source checkpoint: `7601aa0803e997ce4e960ce367cd0530b9b10dc3` +- Infbyte base branch used to start this work: `main` at `47fb985f266c977504c3dca6bd13e85c9a1b73dc` +- Status: initial Foundation 2.0 migration baseline complete; joint reconciliation continues. +- Full tests/release gates: not run yet. + +# Fixed ownership boundary + +## Foundation owns + +- Application/runtime composition; +- Web, CLI, Worker, Scheduler runtime modes; +- InterMix container/scopes; +- command dispatcher and CLI machinery; +- config loader/cache and optimized runtime artifacts; +- reusable module integration policy; +- reusable framework defaults; +- specialist-package bridges. + +## Infbyte owns + +- application/project bootstrap files; +- application-facing config overrides; +- project provider lists; +- routes and application code; +- root `infbyte` convenience launcher; +- deployment conventions; +- application branding/default namespace choices; +- final developer-facing skeleton documentation. + +Infbyte must not rebuild Foundation runtime machinery. Foundation must not depend on Infbyte. + +# Completed + +## 1. Branch and dependency setup + +- created `feature/foundation-2.0` from Infbyte `main`; +- Infbyte now targets `dev-feature/foundation-2.0 as 2.0.x-dev` while both repositories are under active development; +- final release constraint will become `^2.0` after Foundation 2.0 is released/frozen. + +## 2. CLI ownership migration + +- removed the old Infbyte `FoundationConsole` construction path; +- root `infbyte` now delegates directly to Foundation `CommandDispatcher`; +- Foundation dispatcher gained a small preflight `displayName` input so Infbyte can report `Infbyte ` without booting the application; +- Foundation package CLI remains branded `Foundation` by default; +- no second Console application/container/config hierarchy is retained. + +## 3. Runtime bootstrap/provider migration + +- added `bootstrap/cli.php` using `Foundation::cli()`; +- removed `bootstrap/console.php` and `Foundation::console()` usage; +- provider groups now use exactly: + - `common`; + - `web`; + - `cli`; + - `worker`; + - `scheduler`. + +## 4. Core application config migration + +- removed `app.container.request_scope`; +- application container lazy loading now defaults to true; +- retained explicit opt-in compiled-container activation; +- environment helpers use Foundation 2.0 `env*` contract; +- app-facing name/environment/debug/url remain Infbyte-owned overrides. + +## 5. Auth/UID migration + +- removed `config/ids.php`; +- removed `AUTH_IDS` and the retired `auth.drivers.ids` selector; +- UID remains Foundation-core identity generation; +- auth driver config now covers only replaceable capabilities; +- OTP defaults were aligned with current Foundation 2.0 auth policy; +- auth example secret is blank so `app:install` generates real secret material instead of preserving a committed placeholder. + +## 6. Deployment/cache artifact hygiene + +- removed retired `bootstrap/cache/console` creation from deployment flow; +- `deploy.sh` delegates optimization to `php infbyte optimize`; +- all generated Foundation artifacts under `bootstrap/cache` are ignored; +- `bootstrap/cache/.gitignore` keeps the application cache directory present without tracking generated artifacts. + +# Immediate next work — cross-repo surface reconciliation + +## 1. Application entrypoints and route surface + +Audit and align: + +- `public/index.php`; +- `bootstrap/app.php`; +- `bootstrap/cli.php`; +- any worker/scheduler entry needs; +- `routes/web.php`, `routes/api.php`, `routes/console.php`; +- application command examples/namespaces. + +Do not add worker/scheduler bootstrap files merely for symmetry if Foundation commands already own those runtime transitions. + +## 2. Config and module publication + +Reconcile Infbyte's checked-in config with Foundation 2.0's module catalog and published templates: + +- determine which config belongs in a fresh skeleton by default; +- keep optional module config absent until the module is intentionally installed/published unless Infbyte deliberately chooses otherwise; +- ensure `module:install` publication is the authoritative path for CacheLayer, DBLayer, Epicrypt, OTP, Pathwise, ReqShield, TalkingBytes, Omnibus, etc.; +- remove stale copied config instead of maintaining divergent application versions of Foundation templates; +- verify package-present versus configured/activated semantics. + +## 3. Infbyte application branding + +Foundation defaults are neutral. Decide Infbyte's application defaults deliberately and only at the application layer, including where appropriate: + +- HTTP User-Agent; +- cache namespace; +- lock namespace; +- session cookie; +- remember-me cookie; +- application response metadata. + +Keep optional-module branding with the corresponding module config rather than forcing optional packages into a core-only install. + +## 4. Foundation support discovered by Infbyte + +Any cross-repo integration defect must be fixed in Foundation rather than worked around in Infbyte. Current example already completed: + +- CLI preflight display-name support. + +Continue this rule for module publication, runtime bootstrap, optimized artifacts, and app install behavior. + +## 5. Composer/install lifecycle + +Audit: + +- `post-create-project-cmd`; +- clean create-project flow; +- `.env` creation and secret generation; +- writable runtime directories; +- optional module installation commands; +- final change from Foundation development branch constraint to `^2.0` at release. + +# Later phases + +## Documentation freeze + +After implementation/config surfaces settle: + +- rewrite Infbyte README for the Foundation 2.0 architecture; +- document Infbyte vs Foundation ownership; +- update install/CLI/config/module/deployment examples; +- remove Foundation 1.x and Console-era examples; +- update Foundation docs in parallel where application-facing behavior is shared. + +## Deferred test/release matrix + +When explicitly started: + +- Composer validation; +- PHPForge/static analysis; +- PHPUnit/integration tests; +- clean `composer create-project`/install flow; +- `php infbyte --version`, list/help/completion preflight; +- Web boot; +- CLI command boot; +- Worker/Scheduler command runtime handoff; +- core-only install without optional packages; +- optional module install/remove/config publication matrix; +- optimize/optimize:clear/deploy flow; +- persistent runtime reset/isolation; +- final stale-symbol/config/doc scan; +- final Foundation 2.0 + Infbyte release compatibility review. + +# Do not regress + +- no `FoundationConsole` or `Foundation::console()`; +- no `bootstrap/console.php`; +- no `auth.drivers.ids` / generic IdentifierManager config; +- no `app.container.request_scope`; +- no second CLI container/config/bootstrap hierarchy; +- no broad Foundation manager/facade proxies in Infbyte; +- no duplicated specialist-library engines; +- no generated optimized artifacts committed to the skeleton; +- no workaround in Infbyte when the defect belongs to Foundation. From 0df71a0ee4bd16a63d1948a67e9870af0b709415 Mon Sep 17 00:00:00 2001 From: "A. B. M. Mahmudul Hasan" Date: Sun, 23 Aug 2026 10:38:40 +0600 Subject: [PATCH 14/51] refactor: use Foundation scheduler API --- routes/schedule.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/routes/schedule.php b/routes/schedule.php index d362161..2c064b8 100644 --- a/routes/schedule.php +++ b/routes/schedule.php @@ -2,7 +2,7 @@ declare(strict_types=1); -use Infocyph\Console\Scheduling\Schedule; +use Infocyph\Foundation\Scheduling\Schedule; return static function (Schedule $schedule): void { /** From cfb59cb7617421ae68dbb7105818fed7a1c270e7 Mon Sep 17 00:00:00 2001 From: "A. B. M. Mahmudul Hasan" Date: Sun, 23 Aug 2026 10:38:47 +0600 Subject: [PATCH 15/51] docs: align worker route example --- routes/workers.php | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/routes/workers.php b/routes/workers.php index 651de55..3a60206 100644 --- a/routes/workers.php +++ b/routes/workers.php @@ -4,7 +4,11 @@ return [ /** + * Application maintenance workers implement + * \Infocyph\Foundation\Worker\WorkerProvider and normally live in + * app/Worker. Queue/message workers are configured through Omnibus. + * * Usage: - * 'queue' => \App\Console\Workers\QueueWorker::class, + * 'maintenance' => \App\Worker\MaintenanceWorker::class, */ ]; From fb8aa47cafa88ba71bd16d2a6c5eea5dd2c7f1d5 Mon Sep 17 00:00:00 2001 From: "A. B. M. Mahmudul Hasan" Date: Sun, 23 Aug 2026 10:39:37 +0600 Subject: [PATCH 16/51] docs: align application command namespace --- routes/console.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/routes/console.php b/routes/console.php index eb030cb..dedf624 100644 --- a/routes/console.php +++ b/routes/console.php @@ -5,6 +5,6 @@ return [ /** * Usage: - * 'reports:daily' => \App\Console\Commands\Reports\DailyCommand::class, + * 'reports:daily' => \App\Command\Reports\DailyCommand::class, */ ]; From 894845aa65bff3d3be4c2c2cbc0b3875f323133f Mon Sep 17 00:00:00 2001 From: "A. B. M. Mahmudul Hasan" Date: Sun, 23 Aug 2026 10:39:45 +0600 Subject: [PATCH 17/51] refactor: remove stale Console command directory --- app/Console/Commands/.gitkeep | 1 - 1 file changed, 1 deletion(-) delete mode 100644 app/Console/Commands/.gitkeep diff --git a/app/Console/Commands/.gitkeep b/app/Console/Commands/.gitkeep deleted file mode 100644 index 8b13789..0000000 --- a/app/Console/Commands/.gitkeep +++ /dev/null @@ -1 +0,0 @@ - From 76966293b9469aeccdf955de317a29d38f393653 Mon Sep 17 00:00:00 2001 From: "A. B. M. Mahmudul Hasan" Date: Sun, 23 Aug 2026 10:40:19 +0600 Subject: [PATCH 18/51] refactor: use scoped route registrar --- routes/api.php | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/routes/api.php b/routes/api.php index 9dedb76..0a73ca2 100644 --- a/routes/api.php +++ b/routes/api.php @@ -3,7 +3,8 @@ declare(strict_types=1); use App\Http\Controllers\SystemController; -use Infocyph\Webrick\Router\Facade\Router as Route; +use Infocyph\Webrick\Router\Definition\Registrar; -Route::get('/api/health', SystemController::health(...)); -Route::get('/json', SystemController::json(...), 'json'); +/** @var Registrar $router */ +$router->get('/api/health', SystemController::health(...)); +$router->get('/json', SystemController::json(...), 'json'); From 48fed569f3a621fae5c3829f93786681c4761854 Mon Sep 17 00:00:00 2001 From: "A. B. M. Mahmudul Hasan" Date: Sun, 23 Aug 2026 10:40:40 +0600 Subject: [PATCH 19/51] refactor: simplify web bootstrap --- bootstrap/app.php | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/bootstrap/app.php b/bootstrap/app.php index f5c5e5f..049da00 100644 --- a/bootstrap/app.php +++ b/bootstrap/app.php @@ -4,7 +4,6 @@ use Infocyph\Foundation\Foundation; -/** @var array $options */ -$options = require __DIR__ . '/options.php'; - -return Foundation::web($options); +return Foundation::web([ + 'base_path' => dirname(__DIR__), +]); From 33f6fdca06d69dbf25ca7cdea71fdb796e81cbd6 Mon Sep 17 00:00:00 2001 From: "A. B. M. Mahmudul Hasan" Date: Sun, 23 Aug 2026 10:40:51 +0600 Subject: [PATCH 20/51] refactor: remove unused CLI bootstrap --- bootstrap/cli.php | 10 ---------- 1 file changed, 10 deletions(-) delete mode 100644 bootstrap/cli.php diff --git a/bootstrap/cli.php b/bootstrap/cli.php deleted file mode 100644 index bffc729..0000000 --- a/bootstrap/cli.php +++ /dev/null @@ -1,10 +0,0 @@ - $options */ -$options = require __DIR__ . '/options.php'; - -return Foundation::cli($options); From f47d44dec14c62f5ab5e2889eee8582983e34018 Mon Sep 17 00:00:00 2001 From: "A. B. M. Mahmudul Hasan" Date: Sun, 23 Aug 2026 10:40:57 +0600 Subject: [PATCH 21/51] refactor: remove redundant bootstrap options --- bootstrap/options.php | 9 --------- 1 file changed, 9 deletions(-) delete mode 100644 bootstrap/options.php diff --git a/bootstrap/options.php b/bootstrap/options.php deleted file mode 100644 index e434e74..0000000 --- a/bootstrap/options.php +++ /dev/null @@ -1,9 +0,0 @@ - $basePath, -]; From 93f5ba9666e97b85b97ace6e79312a77134ec76c Mon Sep 17 00:00:00 2001 From: "A. B. M. Mahmudul Hasan" Date: Sun, 23 Aug 2026 10:42:45 +0600 Subject: [PATCH 22/51] config: use typed application environment helpers --- config/app.php | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/config/app.php b/config/app.php index 6233f19..ed119fc 100644 --- a/config/app.php +++ b/config/app.php @@ -14,10 +14,10 @@ | and "url" is the application's canonical external base URL. | */ - 'name' => env('APP_NAME', 'Infbyte'), - 'env' => env('APP_ENV', 'local'), + 'name' => env_string('APP_NAME', 'Infbyte'), + 'env' => env_string('APP_ENV', 'local'), 'debug' => env_bool('APP_DEBUG', true), - 'url' => env('APP_URL', 'http://localhost'), + 'url' => env_string('APP_URL', 'http://localhost'), /* |-------------------------------------------------------------------------- @@ -30,7 +30,7 @@ | */ 'config_cache' => [ - 'type' => env('APP_CONFIG_CACHE_TYPE', 'sharded'), + 'type' => env_string('APP_CONFIG_CACHE_TYPE', 'sharded'), ], /* @@ -45,13 +45,13 @@ */ 'container' => [ 'alias' => env('APP_CONTAINER_ALIAS'), - 'environment' => env('APP_ENV', 'local'), + 'environment' => env_string('APP_ENV', 'local'), 'lazy_loading' => env_bool('APP_CONTAINER_LAZY_LOADING', true), - 'compiled' => env('APP_CONTAINER_COMPILED', 'bootstrap/cache/container.php'), - 'compiled_activation' => env('APP_CONTAINER_COMPILED_ACTIVATION', 'off'), + 'compiled' => env_string('APP_CONTAINER_COMPILED', 'bootstrap/cache/container.php'), + 'compiled_activation' => env_string('APP_CONTAINER_COMPILED_ACTIVATION', 'off'), 'debug_tracing' => [ 'enabled' => env_bool('APP_CONTAINER_DEBUG_TRACING', false), - 'level' => env('APP_CONTAINER_DEBUG_TRACE_LEVEL', 'node'), + 'level' => env_string('APP_CONTAINER_DEBUG_TRACE_LEVEL', 'node'), ], ], ]; From 82d6949b9ddeb4bc33ca04763eaeff817f5db1a0 Mon Sep 17 00:00:00 2001 From: "A. B. M. Mahmudul Hasan" Date: Sun, 23 Aug 2026 10:42:56 +0600 Subject: [PATCH 23/51] config: use typed auth environment helpers --- config/auth.php | 26 +++++++++++++------------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/config/auth.php b/config/auth.php index 4c6bcc7..91e23d0 100644 --- a/config/auth.php +++ b/config/auth.php @@ -15,13 +15,13 @@ | */ 'drivers' => [ - 'storage' => env('AUTH_STORAGE', 'memory'), - 'cache' => env('AUTH_CACHE', 'array'), - 'passwords' => env('AUTH_PASSWORDS', 'native'), - 'tokens' => env('AUTH_TOKENS', 'simple'), - 'mfa' => env('AUTH_MFA', 'simple'), - 'notifications' => env('AUTH_NOTIFICATIONS', 'collect'), - 'passkey' => env('AUTH_PASSKEY', 'disabled'), + 'storage' => env_string('AUTH_STORAGE', 'memory'), + 'cache' => env_string('AUTH_CACHE', 'array'), + 'passwords' => env_string('AUTH_PASSWORDS', 'native'), + 'tokens' => env_string('AUTH_TOKENS', 'simple'), + 'mfa' => env_string('AUTH_MFA', 'simple'), + 'notifications' => env_string('AUTH_NOTIFICATIONS', 'collect'), + 'passkey' => env_string('AUTH_PASSKEY', 'disabled'), ], /* @@ -41,12 +41,12 @@ |-------------------------------------------------------------------------- */ 'otp' => [ - 'issuer' => env('AUTH_OTP_ISSUER', env('APP_NAME', 'Infbyte')), + 'issuer' => env_string('AUTH_OTP_ISSUER', env_string('APP_NAME', 'Infbyte')), 'hotp' => [ 'look_ahead' => env_int('AUTH_OTP_HOTP_LOOK_AHEAD', 5), ], 'totp' => [ - 'algorithm' => env('AUTH_OTP_ALGORITHM', 'sha1'), + 'algorithm' => env_string('AUTH_OTP_ALGORITHM', 'sha1'), 'digits' => env_int('AUTH_OTP_DIGITS', 6), 'period' => env_int('AUTH_OTP_PERIOD', 30), 'secret_bytes' => env_int('AUTH_OTP_SECRET_BYTES', 20), @@ -69,11 +69,11 @@ */ 'webauthn' => [ 'rp_id' => env('WEBAUTHN_RP_ID'), - 'rp_name' => env('WEBAUTHN_RP_NAME', env('APP_NAME', 'Infbyte')), + 'rp_name' => env_string('WEBAUTHN_RP_NAME', env_string('APP_NAME', 'Infbyte')), 'origin' => env('WEBAUTHN_ORIGIN'), - 'attestation' => env('WEBAUTHN_ATTESTATION', 'none'), - 'user_verification' => env('WEBAUTHN_USER_VERIFICATION', 'preferred'), - 'resident_key' => env('WEBAUTHN_RESIDENT_KEY', 'preferred'), + 'attestation' => env_string('WEBAUTHN_ATTESTATION', 'none'), + 'user_verification' => env_string('WEBAUTHN_USER_VERIFICATION', 'preferred'), + 'resident_key' => env_string('WEBAUTHN_RESIDENT_KEY', 'preferred'), 'algorithms' => ['ES256', 'RS256'], 'transports' => ['internal', 'hybrid', 'usb', 'nfc', 'ble'], ], From 783893fc9acd478bfecfb609b86580e738c2965b Mon Sep 17 00:00:00 2001 From: "A. B. M. Mahmudul Hasan" Date: Sun, 23 Aug 2026 10:43:56 +0600 Subject: [PATCH 24/51] config: use typed router environment helper --- config/router.php | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/config/router.php b/config/router.php index f682dd6..879bf1f 100644 --- a/config/router.php +++ b/config/router.php @@ -10,7 +10,7 @@ | | These files are loaded from the routes directory when route metadata has | not been cached. Add a filename for each application-owned route surface. - | Example values: `api.php`, `web.php`, and `admin.php`. + | Example values: api.php, web.php, and admin.php. | */ 'files' => [ @@ -23,9 +23,9 @@ |-------------------------------------------------------------------------- | | The matcher controls how Webrick compiles and dispatches routes. Build the - | selected form during deployment with `php infbyte route:cache`. - | Allowed values: `fused|generated|sharded`. + | selected form during deployment with `php infbyte route:cache` or + | `php infbyte optimize`. Allowed values: fused|generated|sharded. | */ - 'matcher' => env('ROUTER_MATCHER', 'fused'), + 'matcher' => env_string('ROUTER_MATCHER', 'fused'), ]; From 0a0e407bcde2e2b9f3535d6e91fbba58a497c931 Mon Sep 17 00:00:00 2001 From: "A. B. M. Mahmudul Hasan" Date: Sun, 23 Aug 2026 10:44:25 +0600 Subject: [PATCH 25/51] chore: remove retired console cache placeholder --- bootstrap/cache/console/.gitignore | 2 -- 1 file changed, 2 deletions(-) delete mode 100644 bootstrap/cache/console/.gitignore diff --git a/bootstrap/cache/console/.gitignore b/bootstrap/cache/console/.gitignore deleted file mode 100644 index d6b7ef3..0000000 --- a/bootstrap/cache/console/.gitignore +++ /dev/null @@ -1,2 +0,0 @@ -* -!.gitignore From c92b9f4ea4358f02a16cd2eb17073079427cf8e1 Mon Sep 17 00:00:00 2001 From: "A. B. M. Mahmudul Hasan" Date: Sun, 23 Aug 2026 10:44:32 +0600 Subject: [PATCH 26/51] chore: remove redundant config cache placeholder --- bootstrap/cache/config/.gitignore | 2 -- 1 file changed, 2 deletions(-) delete mode 100644 bootstrap/cache/config/.gitignore diff --git a/bootstrap/cache/config/.gitignore b/bootstrap/cache/config/.gitignore deleted file mode 100644 index d6b7ef3..0000000 --- a/bootstrap/cache/config/.gitignore +++ /dev/null @@ -1,2 +0,0 @@ -* -!.gitignore From 297d171f793f083795fba6ee70876a5170ff5f66 Mon Sep 17 00:00:00 2001 From: "A. B. M. Mahmudul Hasan" Date: Sun, 23 Aug 2026 10:44:37 +0600 Subject: [PATCH 27/51] chore: remove redundant route cache placeholder --- bootstrap/cache/routes/.gitignore | 2 -- 1 file changed, 2 deletions(-) delete mode 100644 bootstrap/cache/routes/.gitignore diff --git a/bootstrap/cache/routes/.gitignore b/bootstrap/cache/routes/.gitignore deleted file mode 100644 index d6b7ef3..0000000 --- a/bootstrap/cache/routes/.gitignore +++ /dev/null @@ -1,2 +0,0 @@ -* -!.gitignore From 704549572b176317e8dd5b23905d5d8735f08af2 Mon Sep 17 00:00:00 2001 From: "A. B. M. Mahmudul Hasan" Date: Sun, 23 Aug 2026 10:46:13 +0600 Subject: [PATCH 28/51] docs: checkpoint joint Foundation 2.0 migration --- infbyte_work_plan.md | 235 ++++++++++++++++++++----------------------- 1 file changed, 110 insertions(+), 125 deletions(-) diff --git a/infbyte_work_plan.md b/infbyte_work_plan.md index 0735ac7..57bbacc 100644 --- a/infbyte_work_plan.md +++ b/infbyte_work_plan.md @@ -7,8 +7,6 @@ - Infbyte: `feature/foundation-2.0` - Foundation: `feature/foundation-2.0` -The two branches are developed together. Foundation remains the reusable runtime/framework layer; Infbyte remains the opinionated application skeleton. - ## Maintenance rule After each completed joint batch: @@ -16,192 +14,179 @@ After each completed joint batch: 1. record the latest Infbyte and Foundation source checkpoints; 2. move finished work to **Completed**; 3. keep **Immediate next work** limited to the next concrete cross-repo phase; -4. do not reintroduce Foundation 1.x/Console compatibility; -5. keep specialist-library engines in their owning packages; -6. keep the full PHPUnit/static-analysis/PHPForge/release matrix deferred until implementation/config/docs are stable. +4. fix framework defects in Foundation rather than working around them in Infbyte; +5. do not reintroduce Foundation 1.x/Console compatibility; +6. keep specialist-library engines in their owning packages; +7. keep the full test/release matrix deferred until implementation/config/docs are stable. -## Current checkpoint +# Current checkpoint - Date: 2026-08-23 -- Infbyte source checkpoint: `456482094f98d82b5f89c37ebac57a11477d2d5e` -- Foundation source checkpoint: `7601aa0803e997ce4e960ce367cd0530b9b10dc3` -- Infbyte base branch used to start this work: `main` at `47fb985f266c977504c3dca6bd13e85c9a1b73dc` -- Status: initial Foundation 2.0 migration baseline complete; joint reconciliation continues. -- Full tests/release gates: not run yet. +- Infbyte source checkpoint: `297d171f793f083795fba6ee70876a5170ff5f66` +- Foundation source checkpoint: `2e1415fd871d1564a70d08b18da45ebf243fe4e5` +- Infbyte branch base: `main` at `47fb985f266c977504c3dca6bd13e85c9a1b73dc` +- Status: **Foundation 2.0 implementation/config migration baseline complete; documentation reconciliation is next.** +- Full PHPUnit/static-analysis/PHPForge/release matrix: not run yet. -# Fixed ownership boundary +# Ownership boundary ## Foundation owns - Application/runtime composition; -- Web, CLI, Worker, Scheduler runtime modes; +- Web, CLI, Worker and Scheduler runtime modes; - InterMix container/scopes; -- command dispatcher and CLI machinery; -- config loader/cache and optimized runtime artifacts; -- reusable module integration policy; +- command parsing/preflight/dispatch/execution; +- config/cache/optimized-artifact machinery; +- reusable module installation/publication policy; - reusable framework defaults; - specialist-package bridges. ## Infbyte owns -- application/project bootstrap files; +- project Web bootstrap and public entrypoint; - application-facing config overrides; -- project provider lists; -- routes and application code; +- provider lists; +- routes/application code; - root `infbyte` convenience launcher; - deployment conventions; -- application branding/default namespace choices; -- final developer-facing skeleton documentation. +- application-specific defaults/branding when intentionally configured; +- skeleton documentation/developer experience. Infbyte must not rebuild Foundation runtime machinery. Foundation must not depend on Infbyte. # Completed -## 1. Branch and dependency setup +## 1. Branch/dependency setup - created `feature/foundation-2.0` from Infbyte `main`; -- Infbyte now targets `dev-feature/foundation-2.0 as 2.0.x-dev` while both repositories are under active development; -- final release constraint will become `^2.0` after Foundation 2.0 is released/frozen. +- development Composer constraint is `dev-feature/foundation-2.0 as 2.0.x-dev`; +- final release constraint becomes `^2.0` only when Foundation 2.0 is released/frozen. ## 2. CLI ownership migration -- removed the old Infbyte `FoundationConsole` construction path; -- root `infbyte` now delegates directly to Foundation `CommandDispatcher`; -- Foundation dispatcher gained a small preflight `displayName` input so Infbyte can report `Infbyte ` without booting the application; -- Foundation package CLI remains branded `Foundation` by default; -- no second Console application/container/config hierarchy is retained. - -## 3. Runtime bootstrap/provider migration - -- added `bootstrap/cli.php` using `Foundation::cli()`; -- removed `bootstrap/console.php` and `Foundation::console()` usage; -- provider groups now use exactly: - - `common`; - - `web`; - - `cli`; - - `worker`; - - `scheduler`. - -## 4. Core application config migration - -- removed `app.container.request_scope`; -- application container lazy loading now defaults to true; -- retained explicit opt-in compiled-container activation; -- environment helpers use Foundation 2.0 `env*` contract; -- app-facing name/environment/debug/url remain Infbyte-owned overrides. - -## 5. Auth/UID migration - -- removed `config/ids.php`; -- removed `AUTH_IDS` and the retired `auth.drivers.ids` selector; -- UID remains Foundation-core identity generation; -- auth driver config now covers only replaceable capabilities; -- OTP defaults were aligned with current Foundation 2.0 auth policy; -- auth example secret is blank so `app:install` generates real secret material instead of preserving a committed placeholder. - -## 6. Deployment/cache artifact hygiene +- removed `FoundationConsole` construction and `Foundation::console()` usage; +- root `infbyte` delegates directly to Foundation `CommandDispatcher`; +- Foundation preflight accepts a lightweight display name so Infbyte reports `Infbyte ` without booting Application; +- Foundation package CLI remains `Foundation` by default; +- no second Console application/container/config hierarchy remains; +- no dedicated `bootstrap/cli.php` is retained because it has no runtime owner: `CommandDispatcher` selects CLI/Worker/Scheduler runtime directly. -- removed retired `bootstrap/cache/console` creation from deployment flow; -- `deploy.sh` delegates optimization to `php infbyte optimize`; -- all generated Foundation artifacts under `bootstrap/cache` are ignored; -- `bootstrap/cache/.gitignore` keeps the application cache directory present without tracking generated artifacts. +## 3. Bootstrap/runtime/provider migration -# Immediate next work — cross-repo surface reconciliation +- `bootstrap/console.php` removed; +- redundant `bootstrap/options.php` removed; +- `bootstrap/app.php` is one direct `Foundation::web(['base_path' => ...])` bootstrap; +- `public/index.php` remains minimal and delegates request handling to Foundation/Webrick; +- provider groups are exactly `common|web|cli|worker|scheduler`. -## 1. Application entrypoints and route surface +## 4. Application config migration -Audit and align: +Checked-in core config stays deliberately small: -- `public/index.php`; -- `bootstrap/app.php`; -- `bootstrap/cli.php`; -- any worker/scheduler entry needs; -- `routes/web.php`, `routes/api.php`, `routes/console.php`; -- application command examples/namespaces. +- `config/app.php`; +- `config/auth.php`; +- `config/router.php`. -Do not add worker/scheduler bootstrap files merely for symmetry if Foundation commands already own those runtime transitions. +Completed: -## 2. Config and module publication +- removed `app.container.request_scope`; +- lazy loading defaults to true; +- kept compiled container activation explicit/opt-in; +- uses typed Foundation helpers (`env_string`, `env_bool`, `env_int`) where a typed value is required; +- `config/ids.php`, `AUTH_IDS`, and `auth.drivers.ids` removed; +- UID remains Foundation-core identity generation; +- auth/OTP/WebAuthn application defaults align with Foundation 2.0 schema; +- `.env.example` leaves `AUTH_TOKEN_SECRET` blank so `app:install` generates real secret material. -Reconcile Infbyte's checked-in config with Foundation 2.0's module catalog and published templates: +## 5. Route/schedule/worker surface -- determine which config belongs in a fresh skeleton by default; -- keep optional module config absent until the module is intentionally installed/published unless Infbyte deliberately chooses otherwise; -- ensure `module:install` publication is the authoritative path for CacheLayer, DBLayer, Epicrypt, OTP, Pathwise, ReqShield, TalkingBytes, Omnibus, etc.; -- remove stale copied config instead of maintaining divergent application versions of Foundation templates; -- verify package-present versus configured/activated semantics. +- `routes/api.php` uses the loader-provided scoped Webrick `Registrar` rather than the process-global Router facade; +- source route loading and route-cache compilation expose the same `$router` contract; +- `routes/schedule.php` uses `Infocyph\Foundation\Scheduling\Schedule`; +- worker example uses `App\Worker` and `Infocyph\Foundation\Worker\WorkerProvider` semantics; +- command example uses `App\Command`; +- stale empty `app/Console/Commands` skeleton removed; +- `routes/console.php` filename remains intentionally because it is the Foundation command-route contract, not a Console runtime hierarchy. -## 3. Infbyte application branding +## 6. Module/config publication model -Foundation defaults are neutral. Decide Infbyte's application defaults deliberately and only at the application layer, including where appropriate: +Decision fixed: -- HTTP User-Agent; -- cache namespace; -- lock namespace; -- session cookie; -- remember-me cookie; -- application response metadata. +- do not bulk-copy Foundation module config into a clean Infbyte skeleton; +- built-in logging/resources/session work from Foundation defaults until explicitly published/customized; +- external CacheLayer/DBLayer/Epicrypt/OTP/Pathwise/ReqShield/TalkingBytes/Omnibus/WebAuthn config appears only when the corresponding capability is intentionally installed/configured; +- `module:install` remains the authoritative config publication path; +- published host config is never silently overwritten or deleted by module removal; +- optional package presence remains distinct from configured/activated capability. -Keep optional-module branding with the corresponding module config rather than forcing optional packages into a core-only install. +Foundation defect discovered and fixed during this review: -## 4. Foundation support discovered by Infbyte +- successful non-dry module install/remove now invalidates runtime-specific compiled containers and the optimize manifest so a changed package/provider graph cannot keep a stale prevalidated container active. -Any cross-repo integration defect must be fixed in Foundation rather than worked around in Infbyte. Current example already completed: +## 7. Deployment/generated artifacts -- CLI preflight display-name support. +- `deploy.sh` no longer creates retired Console cache paths; +- deployment delegates aggregate artifact generation to `php infbyte optimize`; +- one root `bootstrap/cache/.gitignore` owns the generated artifact tree; +- redundant tracked `bootstrap/cache/config`, `bootstrap/cache/routes`, and retired `bootstrap/cache/console` placeholders were removed; +- generated Foundation artifacts are not committed. -Continue this rule for module publication, runtime bootstrap, optimized artifacts, and app install behavior. +## 8. Application branding decision -## 5. Composer/install lifecycle +Foundation remains neutral. Infbyte does **not** publish/copy optional or built-in module config solely to rename framework defaults. -Audit: +- application identity is expressed through `app`/auth config; +- cache/User-Agent/session/response branding is applied only when that configuration is actually published/owned by the application; +- this keeps a fresh skeleton core-only and prevents duplicated framework templates from drifting. -- `post-create-project-cmd`; -- clean create-project flow; -- `.env` creation and secret generation; -- writable runtime directories; -- optional module installation commands; -- final change from Foundation development branch constraint to `^2.0` at release. +# Immediate next work — joint documentation reconciliation -# Later phases +Implementation/config architecture is now stable enough to document. -## Documentation freeze +Review Foundation and Infbyte docs together: -After implementation/config surfaces settle: +1. rewrite Infbyte README around Foundation 2.0 rather than the retired Console architecture; +2. update Foundation README/docs with Infbyte as the application skeleton and Foundation as reusable runtime; +3. document exactly four runtime modes: Web, CLI, Worker, Scheduler; +4. document root Infbyte launcher vs package-owned Foundation dispatcher; +5. document `routes/console.php` as command registration, not a Console subsystem; +6. document application worker vs Omnibus message-worker ownership; +7. document module install/config publication and package-present vs activated semantics; +8. document the lean checked-in config policy and how built-in/optional config is published; +9. document deployment-owned `optimize` artifacts and cache invalidation; +10. remove stale `FoundationConsole`, `Foundation::console()`, `App\Console`, `request_scope`, IdentifierManager/IDs-driver, and old cache-path examples; +11. align install/create-project/.env secret-generation documentation; +12. freeze public names/config examples after docs match source. -- rewrite Infbyte README for the Foundation 2.0 architecture; -- document Infbyte vs Foundation ownership; -- update install/CLI/config/module/deployment examples; -- remove Foundation 1.x and Console-era examples; -- update Foundation docs in parallel where application-facing behavior is shared. +If documentation exposes a concrete implementation defect, fix it in the owning repository and update both trackers. -## Deferred test/release matrix +# After docs — deferred test/release matrix When explicitly started: -- Composer validation; +- Composer validation/dependency checks; - PHPForge/static analysis; -- PHPUnit/integration tests; -- clean `composer create-project`/install flow; -- `php infbyte --version`, list/help/completion preflight; -- Web boot; -- CLI command boot; -- Worker/Scheduler command runtime handoff; -- core-only install without optional packages; -- optional module install/remove/config publication matrix; +- PHPUnit/integration suites; +- clean create-project/install flow; +- CLI version/list/help/completion preflight; +- Web/CLI/Worker/Scheduler load isolation; +- core-only runtime without optional packages; +- optional module install/remove/publication matrix; - optimize/optimize:clear/deploy flow; -- persistent runtime reset/isolation; +- persistent runtime reset/fork isolation; +- locking topology checks; +- startup/memory/throughput benchmarks; - final stale-symbol/config/doc scan; - final Foundation 2.0 + Infbyte release compatibility review. # Do not regress -- no `FoundationConsole` or `Foundation::console()`; -- no `bootstrap/console.php`; +- no `FoundationConsole`, `Foundation::console()`, or Console runtime hierarchy; +- no `bootstrap/console.php` or unused runtime bootstrap symmetry files; - no `auth.drivers.ids` / generic IdentifierManager config; - no `app.container.request_scope`; -- no second CLI container/config/bootstrap hierarchy; - no broad Foundation manager/facade proxies in Infbyte; - no duplicated specialist-library engines; -- no generated optimized artifacts committed to the skeleton; -- no workaround in Infbyte when the defect belongs to Foundation. +- no copied optional-module config in the base skeleton; +- no generated optimized artifacts committed; +- no Infbyte workaround when the defect belongs to Foundation. From f11e4cd8c7490db29ece00f9a188ac4321f671e2 Mon Sep 17 00:00:00 2001 From: "A. B. M. Mahmudul Hasan" Date: Sun, 23 Aug 2026 11:42:18 +0600 Subject: [PATCH 29/51] config: align auth with purpose module bundle --- config/auth.php | 20 ++++++++++++++++---- 1 file changed, 16 insertions(+), 4 deletions(-) diff --git a/config/auth.php b/config/auth.php index 91e23d0..b584557 100644 --- a/config/auth.php +++ b/config/auth.php @@ -8,10 +8,13 @@ | Authentication Drivers |-------------------------------------------------------------------------- | - | Foundation 2.0 owns identity generation through UID, so authentication no - | longer exposes an ID driver. These switches select only replaceable auth - | capabilities. The Infbyte defaults stay dependency-light; production may - | opt into the durable specialist modules it requires. + | Foundation owns identity generation through UID. These switches select + | only replaceable authentication capabilities. The dependency-light + | defaults work without optional modules. + | + | Run `php infbyte module:install auth` to install the extended auth bundle + | used by AUTH_MFA=otp and AUTH_PASSKEY=webauthn. The two capabilities stay + | independently selectable even though they share one purpose-level module. | */ 'drivers' => [ @@ -39,6 +42,11 @@ |-------------------------------------------------------------------------- | One-Time Passwords |-------------------------------------------------------------------------- + | + | OTP-backed MFA is provided by the auth module. Enable it with AUTH_MFA=otp + | after installing the module. Replay-safe production use also requires the + | configured shared cache/coordination capability. + | */ 'otp' => [ 'issuer' => env_string('AUTH_OTP_ISSUER', env_string('APP_NAME', 'Infbyte')), @@ -66,6 +74,10 @@ |-------------------------------------------------------------------------- | WebAuthn / Passkeys |-------------------------------------------------------------------------- + | + | WebAuthn is provided by the auth module. Enable it with + | AUTH_PASSKEY=webauthn after installing that module. + | */ 'webauthn' => [ 'rp_id' => env('WEBAUTHN_RP_ID'), From 8e5e9443be1a40a770fc80b4ffaf22322dc08de9 Mon Sep 17 00:00:00 2001 From: "A. B. M. Mahmudul Hasan" Date: Sun, 23 Aug 2026 11:43:35 +0600 Subject: [PATCH 30/51] config: document purpose module dependencies --- config/auth.php | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/config/auth.php b/config/auth.php index b584557..d6273af 100644 --- a/config/auth.php +++ b/config/auth.php @@ -12,9 +12,15 @@ | only replaceable authentication capabilities. The dependency-light | defaults work without optional modules. | - | Run `php infbyte module:install auth` to install the extended auth bundle - | used by AUTH_MFA=otp and AUTH_PASSKEY=webauthn. The two capabilities stay - | independently selectable even though they share one purpose-level module. + | Optional choices map to purpose-level modules: + | storage=database -> module:install database + | cache=cache -> module:install cache + | passwords/tokens=security -> module:install security + | mfa=otp or passkey=webauthn -> module:install auth + | notifications=talkingbytes -> module:install communication + | + | OTP and WebAuthn remain independently selectable even though they share + | the same extended-auth module and installation bundle. | */ 'drivers' => [ From a6dda1f1b75c658b6364695fdd90ff27c0d291e2 Mon Sep 17 00:00:00 2001 From: "A. B. M. Mahmudul Hasan" Date: Sun, 23 Aug 2026 11:45:16 +0600 Subject: [PATCH 31/51] docs: record module cleanup checkpoint --- infbyte_work_plan.md | 227 ++++++++++++------------------------------- 1 file changed, 62 insertions(+), 165 deletions(-) diff --git a/infbyte_work_plan.md b/infbyte_work_plan.md index 57bbacc..a05c5d8 100644 --- a/infbyte_work_plan.md +++ b/infbyte_work_plan.md @@ -1,192 +1,89 @@ # Infbyte — Foundation 2.0 Live Work Plan -> Current execution tracker for migrating the Infbyte application skeleton to Foundation 2.0. - -## Working branches +## Branches - Infbyte: `feature/foundation-2.0` - Foundation: `feature/foundation-2.0` -## Maintenance rule - -After each completed joint batch: - -1. record the latest Infbyte and Foundation source checkpoints; -2. move finished work to **Completed**; -3. keep **Immediate next work** limited to the next concrete cross-repo phase; -4. fix framework defects in Foundation rather than working around them in Infbyte; -5. do not reintroduce Foundation 1.x/Console compatibility; -6. keep specialist-library engines in their owning packages; -7. keep the full test/release matrix deferred until implementation/config/docs are stable. - -# Current checkpoint +## Current checkpoint - Date: 2026-08-23 -- Infbyte source checkpoint: `297d171f793f083795fba6ee70876a5170ff5f66` -- Foundation source checkpoint: `2e1415fd871d1564a70d08b18da45ebf243fe4e5` +- Infbyte source: `8e5e9443be1a40a770fc80b4ffaf22322dc08de9` +- Foundation source: `11801b097f93b593df98e5a3c3d3fdca702166f1` - Infbyte branch base: `main` at `47fb985f266c977504c3dca6bd13e85c9a1b73dc` -- Status: **Foundation 2.0 implementation/config migration baseline complete; documentation reconciliation is next.** -- Full PHPUnit/static-analysis/PHPForge/release matrix: not run yet. +- Phase: pre-documentation cleanup. +- Latest completed cleanup: purpose-first modules and auth config alignment. +- Full tests/release gates remain deferred. + +## Ownership -# Ownership boundary +Foundation owns reusable runtime composition, CLI/runtime machinery, module policy, configuration machinery, optimized artifacts, and integrations. -## Foundation owns +Infbyte owns project bootstrap, application config, routes/code, deployment conventions, and skeleton developer experience. -- Application/runtime composition; -- Web, CLI, Worker and Scheduler runtime modes; -- InterMix container/scopes; -- command parsing/preflight/dispatch/execution; -- config/cache/optimized-artifact machinery; -- reusable module installation/publication policy; -- reusable framework defaults; -- specialist-package bridges. +## Completed migration baseline -## Infbyte owns +- root `infbyte` delegates to Foundation `CommandDispatcher`; +- retired Console bootstrap/runtime removed; +- Web bootstrap delegates to `Foundation::web()`; +- provider groups are `common|web|cli|worker|scheduler`; +- old IDs-driver and request-scope config removed; +- checked-in config stays lean: `app`, `auth`, `router`; +- route files use Foundation's scoped registrar contract; +- generated optimized artifacts are not committed; +- deployment uses `php infbyte optimize`. -- project Web bootstrap and public entrypoint; -- application-facing config overrides; -- provider lists; -- routes/application code; -- root `infbyte` convenience launcher; -- deployment conventions; -- application-specific defaults/branding when intentionally configured; -- skeleton documentation/developer experience. +## Purpose-first module model -Infbyte must not rebuild Foundation runtime machinery. Foundation must not depend on Infbyte. +Public modules represent application capabilities, not Composer packages. -# Completed +| Module | Purpose | +|---|---| +| `auth` | optional OTP/MFA and WebAuthn/passkeys | +| `cache` | cache, shared state, coordination | +| `communication` | HTTP, email, webhook, gRPC | +| `database` | persistence, schema, migrations | +| `filesystem` | storage, files, uploads, archives | +| `logging` | built-in logging | +| `messaging` | events, queues, workers, workflows | +| `resources` | built-in response resources | +| `security` | cryptography, password/token, keys | +| `session` | built-in sessions, CSRF, flash | +| `validation` | request/config/schema/database validation | -## 1. Branch/dependency setup +Naming rules: -- created `feature/foundation-2.0` from Infbyte `main`; -- development Composer constraint is `dev-feature/foundation-2.0 as 2.0.x-dev`; -- final release constraint becomes `^2.0` only when Foundation 2.0 is released/frozen. +- `database` is canonical; `db` remains an alias; +- `security` is canonical; `crypto` remains an alias; +- OTP and passkeys are no longer separate modules; +- `otp`, `mfa`, `passkey`, `passkeys`, and `webauthn` resolve to `auth`; +- `module:install auth` installs both OTP and WebAuthn dependencies; +- runtime configuration still enables OTP and WebAuthn independently. -## 2. CLI ownership migration +Foundation now supports multi-package module bundles and reports `built-in`, `installed`, `partial`, or `available` module status. -- removed `FoundationConsole` construction and `Foundation::console()` usage; -- root `infbyte` delegates directly to Foundation `CommandDispatcher`; -- Foundation preflight accepts a lightweight display name so Infbyte reports `Infbyte ` without booting Application; -- Foundation package CLI remains `Foundation` by default; -- no second Console application/container/config hierarchy remains; -- no dedicated `bootstrap/cli.php` is retained because it has no runtime owner: `CommandDispatcher` selects CLI/Worker/Scheduler runtime directly. +## Auth config alignment -## 3. Bootstrap/runtime/provider migration +`config/auth.php` documents purpose-module requirements for optional choices: -- `bootstrap/console.php` removed; -- redundant `bootstrap/options.php` removed; -- `bootstrap/app.php` is one direct `Foundation::web(['base_path' => ...])` bootstrap; -- `public/index.php` remains minimal and delegates request handling to Foundation/Webrick; -- provider groups are exactly `common|web|cli|worker|scheduler`. +- database-backed auth storage -> `module:install database`; +- cache-backed auth state -> `module:install cache`; +- enhanced password/token drivers -> `module:install security`; +- OTP or WebAuthn -> `module:install auth`; +- external communication notifications -> `module:install communication`. -## 4. Application config migration +Package installation, config publication, and runtime activation remain separate states. -Checked-in core config stays deliberately small: +## Immediate next work -- `config/app.php`; -- `config/auth.php`; -- `config/router.php`. +Continue the joint cleanup pass before documentation freeze. Review remaining public/application-facing naming, CLI, configuration, and ownership surfaces. Then update docs, freeze public names/config, and run the deferred release matrix. -Completed: - -- removed `app.container.request_scope`; -- lazy loading defaults to true; -- kept compiled container activation explicit/opt-in; -- uses typed Foundation helpers (`env_string`, `env_bool`, `env_int`) where a typed value is required; -- `config/ids.php`, `AUTH_IDS`, and `auth.drivers.ids` removed; -- UID remains Foundation-core identity generation; -- auth/OTP/WebAuthn application defaults align with Foundation 2.0 schema; -- `.env.example` leaves `AUTH_TOKEN_SECRET` blank so `app:install` generates real secret material. - -## 5. Route/schedule/worker surface - -- `routes/api.php` uses the loader-provided scoped Webrick `Registrar` rather than the process-global Router facade; -- source route loading and route-cache compilation expose the same `$router` contract; -- `routes/schedule.php` uses `Infocyph\Foundation\Scheduling\Schedule`; -- worker example uses `App\Worker` and `Infocyph\Foundation\Worker\WorkerProvider` semantics; -- command example uses `App\Command`; -- stale empty `app/Console/Commands` skeleton removed; -- `routes/console.php` filename remains intentionally because it is the Foundation command-route contract, not a Console runtime hierarchy. - -## 6. Module/config publication model - -Decision fixed: - -- do not bulk-copy Foundation module config into a clean Infbyte skeleton; -- built-in logging/resources/session work from Foundation defaults until explicitly published/customized; -- external CacheLayer/DBLayer/Epicrypt/OTP/Pathwise/ReqShield/TalkingBytes/Omnibus/WebAuthn config appears only when the corresponding capability is intentionally installed/configured; -- `module:install` remains the authoritative config publication path; -- published host config is never silently overwritten or deleted by module removal; -- optional package presence remains distinct from configured/activated capability. - -Foundation defect discovered and fixed during this review: - -- successful non-dry module install/remove now invalidates runtime-specific compiled containers and the optimize manifest so a changed package/provider graph cannot keep a stale prevalidated container active. - -## 7. Deployment/generated artifacts - -- `deploy.sh` no longer creates retired Console cache paths; -- deployment delegates aggregate artifact generation to `php infbyte optimize`; -- one root `bootstrap/cache/.gitignore` owns the generated artifact tree; -- redundant tracked `bootstrap/cache/config`, `bootstrap/cache/routes`, and retired `bootstrap/cache/console` placeholders were removed; -- generated Foundation artifacts are not committed. - -## 8. Application branding decision - -Foundation remains neutral. Infbyte does **not** publish/copy optional or built-in module config solely to rename framework defaults. - -- application identity is expressed through `app`/auth config; -- cache/User-Agent/session/response branding is applied only when that configuration is actually published/owned by the application; -- this keeps a fresh skeleton core-only and prevents duplicated framework templates from drifting. - -# Immediate next work — joint documentation reconciliation +## Do not regress -Implementation/config architecture is now stable enough to document. - -Review Foundation and Infbyte docs together: - -1. rewrite Infbyte README around Foundation 2.0 rather than the retired Console architecture; -2. update Foundation README/docs with Infbyte as the application skeleton and Foundation as reusable runtime; -3. document exactly four runtime modes: Web, CLI, Worker, Scheduler; -4. document root Infbyte launcher vs package-owned Foundation dispatcher; -5. document `routes/console.php` as command registration, not a Console subsystem; -6. document application worker vs Omnibus message-worker ownership; -7. document module install/config publication and package-present vs activated semantics; -8. document the lean checked-in config policy and how built-in/optional config is published; -9. document deployment-owned `optimize` artifacts and cache invalidation; -10. remove stale `FoundationConsole`, `Foundation::console()`, `App\Console`, `request_scope`, IdentifierManager/IDs-driver, and old cache-path examples; -11. align install/create-project/.env secret-generation documentation; -12. freeze public names/config examples after docs match source. - -If documentation exposes a concrete implementation defect, fix it in the owning repository and update both trackers. - -# After docs — deferred test/release matrix - -When explicitly started: - -- Composer validation/dependency checks; -- PHPForge/static analysis; -- PHPUnit/integration suites; -- clean create-project/install flow; -- CLI version/list/help/completion preflight; -- Web/CLI/Worker/Scheduler load isolation; -- core-only runtime without optional packages; -- optional module install/remove/publication matrix; -- optimize/optimize:clear/deploy flow; -- persistent runtime reset/fork isolation; -- locking topology checks; -- startup/memory/throughput benchmarks; -- final stale-symbol/config/doc scan; -- final Foundation 2.0 + Infbyte release compatibility review. - -# Do not regress - -- no `FoundationConsole`, `Foundation::console()`, or Console runtime hierarchy; -- no `bootstrap/console.php` or unused runtime bootstrap symmetry files; -- no `auth.drivers.ids` / generic IdentifierManager config; -- no `app.container.request_scope`; -- no broad Foundation manager/facade proxies in Infbyte; -- no duplicated specialist-library engines; -- no copied optional-module config in the base skeleton; -- no generated optimized artifacts committed; -- no Infbyte workaround when the defect belongs to Foundation. +- no package-per-module public model; +- no standalone OTP/passkeys modules; +- no retired Console runtime hierarchy; +- no generic ID-driver/request-scope compatibility; +- no broad manager/facade proxies in Infbyte; +- no copied optional-module config by default; +- no generated optimized artifacts committed. From 56cb73e18eab07f34242a929eccbc9e6572d9971 Mon Sep 17 00:00:00 2001 From: "A. B. M. Mahmudul Hasan" Date: Sun, 23 Aug 2026 12:12:55 +0600 Subject: [PATCH 32/51] config: document auth module schema lifecycle --- config/auth.php | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/config/auth.php b/config/auth.php index d6273af..3d7e002 100644 --- a/config/auth.php +++ b/config/auth.php @@ -19,6 +19,11 @@ | mfa=otp or passkey=webauthn -> module:install auth | notifications=talkingbytes -> module:install communication | + | Module installation also synchronizes database schemas required by the + | active configuration. Database-backed authentication uses the auth schema; + | inspect or provision it explicitly with `module:schema:status auth` and + | `module:schema:install auth` when preparing persistence ahead of activation. + | | OTP and WebAuthn remain independently selectable even though they share | the same extended-auth module and installation bundle. | From a65bc237f84d38724159faaa9e543bb0fe383cff Mon Sep 17 00:00:00 2001 From: "A. B. M. Mahmudul Hasan" Date: Sun, 23 Aug 2026 12:21:41 +0600 Subject: [PATCH 33/51] docs: record module schema lifecycle cleanup --- infbyte_work_plan.md | 67 +++++++++++++++++++++++++++++++++++++------- 1 file changed, 57 insertions(+), 10 deletions(-) diff --git a/infbyte_work_plan.md b/infbyte_work_plan.md index a05c5d8..6fbf17a 100644 --- a/infbyte_work_plan.md +++ b/infbyte_work_plan.md @@ -8,19 +8,21 @@ ## Current checkpoint - Date: 2026-08-23 -- Infbyte source: `8e5e9443be1a40a770fc80b4ffaf22322dc08de9` -- Foundation source: `11801b097f93b593df98e5a3c3d3fdca702166f1` +- Infbyte source: `56cb73e18eab07f34242a929eccbc9e6572d9971` +- Foundation source: `b81f508c2d14f1b7bb6a4dc63982ba19cde7fb81` - Infbyte branch base: `main` at `47fb985f266c977504c3dca6bd13e85c9a1b73dc` - Phase: pre-documentation cleanup. -- Latest completed cleanup: purpose-first modules and auth config alignment. +- Latest completed cleanup: purpose-first modules + module-owned schema lifecycle. - Full tests/release gates remain deferred. ## Ownership -Foundation owns reusable runtime composition, CLI/runtime machinery, module policy, configuration machinery, optimized artifacts, and integrations. +Foundation owns reusable runtime composition, CLI/runtime machinery, purpose-module policy, module schema orchestration, configuration machinery, optimized artifacts, and integrations. Infbyte owns project bootstrap, application config, routes/code, deployment conventions, and skeleton developer experience. +Specialist libraries retain their own storage engines and public schema grammar. Foundation orchestrates native schema APIs rather than copying their SQL. + ## Completed migration baseline - root `infbyte` delegates to Foundation `CommandDispatcher`; @@ -56,23 +58,65 @@ Naming rules: - `database` is canonical; `db` remains an alias; - `security` is canonical; `crypto` remains an alias; - OTP and passkeys are no longer separate modules; -- `otp`, `mfa`, `passkey`, `passkeys`, and `webauthn` resolve to `auth`; +- `otp|mfa|passkey|passkeys|webauthn` resolve to `auth`; - `module:install auth` installs both OTP and WebAuthn dependencies; - runtime configuration still enables OTP and WebAuthn independently. -Foundation now supports multi-package module bundles and reports `built-in`, `installed`, `partial`, or `available` module status. +Foundation reports `built-in|installed|partial|available` module status and now includes owned schema metadata in `module:list`. + +## Module-owned schema lifecycle + +A module installation is now operationally complete for database-backed capabilities rather than stopping at Composer/config publication. + +Current database schema ownership: + +| Module | Schema behavior | +|---|---| +| `auth` | Foundation auth schema covering accounts, sessions/tokens, MFA factors/revisions, passkeys and authorization | +| `cache` | CacheLayer native PDO/SQLite cache-entry schema and active PDO invalidation schema | +| `session` | Foundation database-session schema | + +Other modules currently own no application tables. The `database` module provides DB/migration infrastructure rather than another application schema. + +CacheLayer node/tiered SQLite internals continue to self-initialize inside CacheLayer; Infbyte/Foundation do not copy private CacheLayer SQL. + +### Commands + +- `php infbyte module:schema:status ` +- `php infbyte module:schema:install ` +- `php infbyte module:schema:sync` + +All accept `--connection` where applicable. + +Old `auth:schema:*` and `session:schema:*` command families are removed in favor of the single module schema lifecycle. + +### `module:install` lifecycle + +After package/config changes Foundation now: + +1. invalidates compiled runtime container state; +2. launches schema synchronization in a fresh PHP process so the updated Composer autoloader is used; +3. provisions only schemas required by current application configuration; +4. reports schema state and fails when an active required schema cannot be provisioned. + +This makes install order safe: a later `module:install database` can synchronize already-configured database auth/session/cache requirements. + +`module:remove` never drops schemas or user/application data. + +`app:ready` also verifies applicable module schemas, so package installation alone no longer counts as persistence readiness. ## Auth config alignment -`config/auth.php` documents purpose-module requirements for optional choices: +`config/auth.php` documents purpose-module requirements and schema behavior: -- database-backed auth storage -> `module:install database`; +- database-backed auth storage -> `module:install database` plus Foundation auth schema; - cache-backed auth state -> `module:install cache`; - enhanced password/token drivers -> `module:install security`; - OTP or WebAuthn -> `module:install auth`; -- external communication notifications -> `module:install communication`. +- external communication notifications -> `module:install communication`; +- schema state may be checked/prepared with `module:schema:status auth` / `module:schema:install auth`. -Package installation, config publication, and runtime activation remain separate states. +Package installation, config publication, schema readiness, and runtime activation remain distinct states. ## Immediate next work @@ -82,6 +126,9 @@ Continue the joint cleanup pass before documentation freeze. Review remaining pu - no package-per-module public model; - no standalone OTP/passkeys modules; +- no duplicated specialized schema command families; +- no schema/data deletion during module removal; +- no copied specialist-package SQL; - no retired Console runtime hierarchy; - no generic ID-driver/request-scope compatibility; - no broad manager/facade proxies in Infbyte; From 2830b1f3b9381c0f455fd95851e03f4755f667aa Mon Sep 17 00:00:00 2001 From: "A. B. M. Mahmudul Hasan" Date: Sun, 23 Aug 2026 14:16:21 +0600 Subject: [PATCH 34/51] docs: checkpoint Foundation CLI operations integration --- infbyte_work_plan.md | 185 ++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 173 insertions(+), 12 deletions(-) diff --git a/infbyte_work_plan.md b/infbyte_work_plan.md index 6fbf17a..57533f8 100644 --- a/infbyte_work_plan.md +++ b/infbyte_work_plan.md @@ -9,19 +9,19 @@ - Date: 2026-08-23 - Infbyte source: `56cb73e18eab07f34242a929eccbc9e6572d9971` -- Foundation source: `b81f508c2d14f1b7bb6a4dc63982ba19cde7fb81` +- Foundation source: `3d8b2350094fbf8b031290b17a4085643234b563` - Infbyte branch base: `main` at `47fb985f266c977504c3dca6bd13e85c9a1b73dc` -- Phase: pre-documentation cleanup. -- Latest completed cleanup: purpose-first modules + module-owned schema lifecycle. +- Phase: pre-documentation cleanup is complete for modules, schemas, CLI, and operational runtime surfaces. +- Latest completed cleanup: Foundation capability-driven CLI + operations runtime integration. - Full tests/release gates remain deferred. ## Ownership -Foundation owns reusable runtime composition, CLI/runtime machinery, purpose-module policy, module schema orchestration, configuration machinery, optimized artifacts, and integrations. +Foundation owns reusable runtime composition, CLI/runtime machinery, purpose-module policy, module schema orchestration, configuration machinery, optimized artifacts, operational runtime controls, and integrations. Infbyte owns project bootstrap, application config, routes/code, deployment conventions, and skeleton developer experience. -Specialist libraries retain their own storage engines and public schema grammar. Foundation orchestrates native schema APIs rather than copying their SQL. +Specialist libraries retain their own storage/communication/crypto/messaging/database engines and public schema grammar. Foundation orchestrates those APIs rather than copying their implementations. ## Completed migration baseline @@ -48,6 +48,7 @@ Public modules represent application capabilities, not Composer packages. | `filesystem` | storage, files, uploads, archives | | `logging` | built-in logging | | `messaging` | events, queues, workers, workflows | +| `operations` | built-in maintenance, execution history, runtime control and process visibility | | `resources` | built-in response resources | | `security` | cryptography, password/token, keys | | `session` | built-in sessions, CSRF, flash | @@ -59,14 +60,15 @@ Naming rules: - `security` is canonical; `crypto` remains an alias; - OTP and passkeys are no longer separate modules; - `otp|mfa|passkey|passkeys|webauthn` resolve to `auth`; +- `ops|runtime` resolve to `operations`; - `module:install auth` installs both OTP and WebAuthn dependencies; - runtime configuration still enables OTP and WebAuthn independently. -Foundation reports `built-in|installed|partial|available` module status and now includes owned schema metadata in `module:list`. +Foundation reports `built-in|installed|partial|available` module status and includes owned schema metadata in `module:list`. -## Module-owned schema lifecycle +## Module config + schema lifecycle -A module installation is now operationally complete for database-backed capabilities rather than stopping at Composer/config publication. +A module installation is operationally complete for database-backed capabilities rather than stopping at Composer/config publication. Current database schema ownership: @@ -82,17 +84,22 @@ CacheLayer node/tiered SQLite internals continue to self-initialize inside Cache ### Commands +- `php infbyte module:list` +- `php infbyte module:show ` +- `php infbyte module:install ` +- `php infbyte module:remove ` +- `php infbyte module:config:publish [--force]` - `php infbyte module:schema:status ` - `php infbyte module:schema:install ` - `php infbyte module:schema:sync` -All accept `--connection` where applicable. +Schema commands accept `--connection` where applicable. -Old `auth:schema:*` and `session:schema:*` command families are removed in favor of the single module schema lifecycle. +Old `auth:schema:*` and `session:schema:*` command families remain removed in favor of the single module schema lifecycle. ### `module:install` lifecycle -After package/config changes Foundation now: +After package/config changes Foundation: 1. invalidates compiled runtime container state; 2. launches schema synchronization in a fresh PHP process so the updated Composer autoloader is used; @@ -118,9 +125,161 @@ This makes install order safe: a later `module:install database` can synchronize Package installation, config publication, schema readiness, and runtime activation remain distinct states. +## Foundation CLI expansion inherited by Infbyte + +No second Infbyte command layer was added. Because the root launcher already delegates to Foundation `CommandDispatcher`, the expanded Foundation catalog is automatically the Infbyte CLI surface. + +### Database/cache + +New/expanded commands include: + +- `db:monitor`; +- `db:wipe`; +- `migrate --pretend`; +- `migrate:rollback --batch=N`; +- `cache:forget`. + +Foundation delegates database monitoring/migration/schema primitives to DBLayer and cache primitives to CacheLayer. + +### Messaging/queues + +New/expanded commands include: + +- `messaging:list`; +- `queue:failed`; +- `queue:failed:show`; +- `queue:retry`; +- `queue:forget`; +- `queue:flush`; +- `queue:prune-failed`; +- `queue:monitor`. + +Failure/transport/worker mechanics remain Omnibus-owned. + +### Scheduling/storage/auth/logging + +New/expanded commands include: + +- `schedule:test`; +- `schedule:interrupt`; +- richer `schedule:list` execution state; +- `storage:status`; +- `storage:unlink`; +- `auth:prune`; +- `log:tail [--follow]`. + +### Generators + +The Foundation generator surface now includes: + +- `create:config`; +- `create:resource`. + +No fake application abstractions were introduced merely to reproduce Laravel command names. Request/rule/mail/notification generators remain absent until corresponding framework contracts exist. + +## Operations module/runtime + +Foundation now provides built-in `operations` configuration for: + +```text +operations.history.* +operations.maintenance.* +operations.runtime_control.* +operations.runtime_registry.* +``` + +The skeleton does **not** check in `config/operations.php` by default. Foundation defaults make the built-in module usable dependency-free, while applications that need tuning can publish it with: + +```bash +php infbyte module:config:publish operations +``` + +### Execution history + +- `execution:list`; +- `execution:show`; +- `execution:clear`. + +History is opt-in because it writes operational metadata. + +### Maintenance + +- `maintenance:enable`; +- `maintenance:disable`; +- `maintenance:status`. + +The default state driver is file-backed. Cache-backed shared state is available for multi-node deployment. Foundation's HTTP kernel enforces maintenance with HTTP 503 and optional `Retry-After`. + +### Persistent runtime control + +- `runtime:reload`; +- `worker:restart [name]`; +- `worker:status [name]`; +- `schedule:interrupt`. + +Foundation uses generation markers and heartbeat-visible worker/scheduler process records. It requests graceful shutdown; Supervisor/systemd/Docker/Kubernetes or another process manager remains responsible for replacement processes. + +Messaging remains lazily activated only when a configured messaging worker is actually selected. + +## Environment protection + +Infbyte inherits: + +- `env:encrypt`; +- `env:decrypt`. + +Foundation delegates encryption/decryption to Epicrypt. Key material is supplied through an external environment variable (default `ENV_ENCRYPTION_KEY`) or `--key-file`. + +`ENV_ENCRYPTION_KEY` is deliberately **not** added to `.env.example`: storing the key in the environment file being protected would defeat the protection boundary. + +Forced replacement is staged and restores the previous target when publication/finalization fails. + +## Global CLI controls + +The root `infbyte` launcher now automatically exposes Foundation's global command controls: + +- `-q|--quiet`; +- `--silent`; +- `-v|-vv|-vvv`; +- `--profile`; +- `-n|--no-interaction`; +- `--json`; +- `--env=...`; +- help/version/completion. + +`--profile` writes diagnostics to STDERR so command/JSON stdout remains clean. `--silent` suppresses all output and interactive prompting. + +## Deliberate Infbyte non-changes in this batch + +Infbyte source checkpoint remains `56cb73e18eab07f34242a929eccbc9e6572d9971` because no application-side workaround or duplicate command/config layer is needed. + +In particular: + +- `.env.example` remains lean; +- optional operations environment variables are not listed before `operations.php` is published; +- encryption key material is not placed in `.env.example`; +- `config/operations.php` is not copied into the default skeleton; +- no queue/database/cache/security implementation is duplicated in Infbyte. + +This is intentional architecture, not missing implementation. + +## Source-audit status + +Foundation completed a source/config consistency audit of the expanded CLI/operations batch at source checkpoint `3d8b2350094fbf8b031290b17a4085643234b563`. + +The audit confirmed command-to-handler wiring, purpose-module/config consistency, lazy worker capability activation, storage unlink safety, maintenance enforcement, runtime-control key alignment, and staged environment protection. + +No PHPUnit/static-analysis/PHPForge/release matrix was run as part of this cleanup batch. + ## Immediate next work -Continue the joint cleanup pass before documentation freeze. Review remaining public/application-facing naming, CLI, configuration, and ownership surfaces. Then update docs, freeze public names/config, and run the deferred release matrix. +The joint module/schema/CLI/operations cleanup pass is ready for **Foundation + Infbyte documentation reconciliation**, unless another public-surface cleanup topic is intentionally opened first. + +After documentation reconciliation: + +1. freeze public command/module/config names; +2. run the deferred test/release matrix; +3. perform final Foundation 2.0 + Infbyte compatibility/release review. ## Do not regress @@ -129,8 +288,10 @@ Continue the joint cleanup pass before documentation freeze. Review remaining pu - no duplicated specialized schema command families; - no schema/data deletion during module removal; - no copied specialist-package SQL; +- no fake generator-only abstractions; - no retired Console runtime hierarchy; - no generic ID-driver/request-scope compatibility; - no broad manager/facade proxies in Infbyte; - no copied optional-module config by default; +- no environment-protection key in `.env`/`.env.example`; - no generated optimized artifacts committed. From ccf928158bfc1e13aa97476d6c306ae8f92c07a3 Mon Sep 17 00:00:00 2001 From: "A. B. M. Mahmudul Hasan" Date: Sun, 23 Aug 2026 15:42:12 +0600 Subject: [PATCH 35/51] Track Omnibus 2.3 Foundation job integration --- infbyte_work_plan.md | 67 +++++++++++++++++++++++++++++++------------- 1 file changed, 48 insertions(+), 19 deletions(-) diff --git a/infbyte_work_plan.md b/infbyte_work_plan.md index 57533f8..e2b6a8f 100644 --- a/infbyte_work_plan.md +++ b/infbyte_work_plan.md @@ -9,15 +9,15 @@ - Date: 2026-08-23 - Infbyte source: `56cb73e18eab07f34242a929eccbc9e6572d9971` -- Foundation source: `3d8b2350094fbf8b031290b17a4085643234b563` +- Foundation source: `17a3a19cf27ba2d2c39b5722be3cc1d37f8a6eb5` - Infbyte branch base: `main` at `47fb985f266c977504c3dca6bd13e85c9a1b73dc` -- Phase: pre-documentation cleanup is complete for modules, schemas, CLI, and operational runtime surfaces. -- Latest completed cleanup: Foundation capability-driven CLI + operations runtime integration. +- Phase: pre-documentation application-contract cleanup. +- Latest completed cleanup: Omnibus 2.3 + Foundation Job/JobMiddleware messaging integration. - Full tests/release gates remain deferred. ## Ownership -Foundation owns reusable runtime composition, CLI/runtime machinery, purpose-module policy, module schema orchestration, configuration machinery, optimized artifacts, operational runtime controls, and integrations. +Foundation owns reusable runtime composition, CLI/runtime machinery, purpose-module policy, module schema orchestration, configuration machinery, optimized artifacts, operational runtime controls, application-level messaging contracts, and integrations. Infbyte owns project bootstrap, application config, routes/code, deployment conventions, and skeleton developer experience. @@ -47,7 +47,7 @@ Public modules represent application capabilities, not Composer packages. | `database` | persistence, schema, migrations | | `filesystem` | storage, files, uploads, archives | | `logging` | built-in logging | -| `messaging` | events, queues, workers, workflows | +| `messaging` | Omnibus 2.3 events, messages, handler middleware, queues, workers, workflows | | `operations` | built-in maintenance, execution history, runtime control and process visibility | | `resources` | built-in response resources | | `security` | cryptography, password/token, keys | @@ -173,13 +173,39 @@ New/expanded commands include: The Foundation generator surface now includes: - `create:config`; -- `create:resource`. +- `create:resource`; +- `create:job`; +- `create:handler`; +- `create:job-middleware`. -No fake application abstractions were introduced merely to reproduce Laravel command names. Request/rule/mail/notification generators remain absent until corresponding framework contracts exist. +Jobs are generated as data messages implementing Foundation `Job`; handlers remain separate explicit callables. Request/rule/mail/notification generators remain absent until those Foundation application contracts are reviewed. + +## Omnibus 2.3 + Foundation job execution + +Foundation's messaging module now requires `infocyph/omnibus ^2.3` and uses Omnibus' public handler middleware pipeline rather than duplicating execution middleware. + +Application-facing Foundation contracts are: + +- `Infocyph\Foundation\Messaging\Job`; +- `JobContext` with queue/attempt/sync-vs-async metadata; +- `JobMiddleware` with a no-argument continuation. + +Foundation bridges these through one Omnibus `HandlerMiddleware` adapter. The same Omnibus `HandlerInvoker` is shared by synchronous `SyncTransport` and queued Consumer execution, so middleware semantics do not diverge by transport. + +Published messaging configuration provides: + +```text +messaging.handler_middleware +messaging.job_middleware +``` + +`handler_middleware` is the low-level Omnibus surface for all messages. `job_middleware` is the Foundation application surface and applies only to `Job` messages. Ordinary synchronous event listeners remain outside the message-handler middleware pipeline. + +Infbyte does not check in `config/messaging.php`; it remains module-published. Therefore no Infbyte source/config change is required for this feature. ## Operations module/runtime -Foundation now provides built-in `operations` configuration for: +Foundation provides built-in `operations` configuration for: ```text operations.history.* @@ -236,7 +262,7 @@ Forced replacement is staged and restores the previous target when publication/f ## Global CLI controls -The root `infbyte` launcher now automatically exposes Foundation's global command controls: +The root `infbyte` launcher automatically exposes Foundation's global command controls: - `-q|--quiet`; - `--silent`; @@ -249,37 +275,38 @@ The root `infbyte` launcher now automatically exposes Foundation's global comman `--profile` writes diagnostics to STDERR so command/JSON stdout remains clean. `--silent` suppresses all output and interactive prompting. -## Deliberate Infbyte non-changes in this batch +## Deliberate Infbyte non-changes Infbyte source checkpoint remains `56cb73e18eab07f34242a929eccbc9e6572d9971` because no application-side workaround or duplicate command/config layer is needed. In particular: - `.env.example` remains lean; -- optional operations environment variables are not listed before `operations.php` is published; +- optional module environment variables are not listed before their config is published; - encryption key material is not placed in `.env.example`; -- `config/operations.php` is not copied into the default skeleton; +- `config/operations.php` and `config/messaging.php` are not copied into the default skeleton; - no queue/database/cache/security implementation is duplicated in Infbyte. This is intentional architecture, not missing implementation. ## Source-audit status -Foundation completed a source/config consistency audit of the expanded CLI/operations batch at source checkpoint `3d8b2350094fbf8b031290b17a4085643234b563`. +Foundation completed the Omnibus 2.3/job-integration source/config audit at source checkpoint `17a3a19cf27ba2d2c39b5722be3cc1d37f8a6eb5`. -The audit confirmed command-to-handler wiring, purpose-module/config consistency, lazy worker capability activation, storage unlink safety, maintenance enforcement, runtime-control key alignment, and staged environment protection. +The audit confirmed shared sync/async `HandlerInvoker` composition, Omnibus 2.3 capability probing, middleware/default/config-validator alignment, job middleware isolation from Omnibus Envelope details, generator gating, lazy messaging activation and pooled-worker declarative-config safety. No PHPUnit/static-analysis/PHPForge/release matrix was run as part of this cleanup batch. ## Immediate next work -The joint module/schema/CLI/operations cleanup pass is ready for **Foundation + Infbyte documentation reconciliation**, unless another public-surface cleanup topic is intentionally opened first. +Continue Foundation application-contract cleanup for validation/request and notification/mail before documentation freeze. Infbyte should change only if those contracts require actual application-skeleton defaults or structure. -After documentation reconciliation: +After application-contract cleanup: -1. freeze public command/module/config names; -2. run the deferred test/release matrix; -3. perform final Foundation 2.0 + Infbyte compatibility/release review. +1. reconcile Foundation + Infbyte documentation; +2. freeze public command/module/config names; +3. run the deferred test/release matrix; +4. perform final Foundation 2.0 + Infbyte compatibility/release review. ## Do not regress @@ -289,6 +316,8 @@ After documentation reconciliation: - no schema/data deletion during module removal; - no copied specialist-package SQL; - no fake generator-only abstractions; +- no second queue/retry/worker engine above Omnibus; +- no Omnibus Envelope/HandlerContext leakage into Foundation JobMiddleware; - no retired Console runtime hierarchy; - no generic ID-driver/request-scope compatibility; - no broad manager/facade proxies in Infbyte; From 8e0c4b47f5e4eeed1b6f5ca006662be707e1f1ff Mon Sep 17 00:00:00 2001 From: "A. B. M. Mahmudul Hasan" Date: Mon, 24 Aug 2026 05:17:29 +0600 Subject: [PATCH 36/51] Reconcile Infbyte Foundation 2.0 work plan --- infbyte_work_plan.md | 388 +++++++++++++++++-------------------------- 1 file changed, 150 insertions(+), 238 deletions(-) diff --git a/infbyte_work_plan.md b/infbyte_work_plan.md index e2b6a8f..804b883 100644 --- a/infbyte_work_plan.md +++ b/infbyte_work_plan.md @@ -7,320 +7,232 @@ ## Current checkpoint -- Date: 2026-08-23 -- Infbyte source: `56cb73e18eab07f34242a929eccbc9e6572d9971` -- Foundation source: `17a3a19cf27ba2d2c39b5722be3cc1d37f8a6eb5` +- Date: 2026-08-24 +- Infbyte source checkpoint: `56cb73e18eab07f34242a929eccbc9e6572d9971` +- Foundation source checkpoint: `493c39a7a06bac0455397556254f0f8e7e25f973` - Infbyte branch base: `main` at `47fb985f266c977504c3dca6bd13e85c9a1b73dc` -- Phase: pre-documentation application-contract cleanup. -- Latest completed cleanup: Omnibus 2.3 + Foundation Job/JobMiddleware messaging integration. -- Full tests/release gates remain deferred. +- Current phase: **Foundation + Infbyte documentation reconciliation and public-name/config freeze**. +- Application-contract/API cleanup: complete in Foundation. +- Full PHPUnit/static/PHPForge/runtime/release matrix: not run yet. ## Ownership -Foundation owns reusable runtime composition, CLI/runtime machinery, purpose-module policy, module schema orchestration, configuration machinery, optimized artifacts, operational runtime controls, application-level messaging contracts, and integrations. +Foundation owns reusable runtime composition, DI/provider activation policy, CLI/runtime machinery, purpose modules, module schema orchestration, configuration/optimization, operational runtime controls, application contracts and specialist integrations. -Infbyte owns project bootstrap, application config, routes/code, deployment conventions, and skeleton developer experience. +Infbyte owns the opinionated application skeleton: project bootstrap, app-specific config, routes/application code, deployment conventions and final developer experience. -Specialist libraries retain their own storage/communication/crypto/messaging/database engines and public schema grammar. Foundation orchestrates those APIs rather than copying their implementations. +Specialist packages retain their storage/database/cache/communication/crypto/messaging/validation engines. Neither Foundation nor Infbyte copies those implementations. -## Completed migration baseline +## Fixed Infbyte structure - root `infbyte` delegates to Foundation `CommandDispatcher`; -- retired Console bootstrap/runtime removed; -- Web bootstrap delegates to `Foundation::web()`; +- web bootstrap delegates to one `Foundation::web()` application; +- runtime selection for CLI/Worker/Scheduler is Foundation-owned; - provider groups are `common|web|cli|worker|scheduler`; -- old IDs-driver and request-scope config removed; -- checked-in config stays lean: `app`, `auth`, `router`; -- route files use Foundation's scoped registrar contract; +- checked-in config remains deliberately lean: `app.php`, `auth.php`, `router.php`; +- optional module config is published on demand, not copied into the skeleton; +- route files use the loader-provided scoped Webrick registrar; +- `routes/console.php` and `routes/workers.php` remain application registration surfaces; - generated optimized artifacts are not committed; -- deployment uses `php infbyte optimize`. +- deployment optimization uses `php infbyte optimize`. -## Purpose-first module model +## Current Foundation package baseline -Public modules represent application capabilities, not Composer packages. +Core: -| Module | Purpose | -|---|---| -| `auth` | optional OTP/MFA and WebAuthn/passkeys | -| `cache` | cache, shared state, coordination | -| `communication` | HTTP, email, webhook, gRPC | -| `database` | persistence, schema, migrations | -| `filesystem` | storage, files, uploads, archives | -| `logging` | built-in logging | -| `messaging` | Omnibus 2.3 events, messages, handler middleware, queues, workers, workflows | -| `operations` | built-in maintenance, execution history, runtime control and process visibility | -| `resources` | built-in response resources | -| `security` | cryptography, password/token, keys | -| `session` | built-in sessions, CSRF, flash | -| `validation` | request/config/schema/database validation | - -Naming rules: - -- `database` is canonical; `db` remains an alias; -- `security` is canonical; `crypto` remains an alias; -- OTP and passkeys are no longer separate modules; -- `otp|mfa|passkey|passkeys|webauthn` resolve to `auth`; -- `ops|runtime` resolve to `operations`; -- `module:install auth` installs both OTP and WebAuthn dependencies; -- runtime configuration still enables OTP and WebAuthn independently. +- PHP `^8.4` +- `infocyph/arraykit ^5.1.1` +- `infocyph/intermix ^9.2` +- `infocyph/uid ^5.0` +- `infocyph/webrick ^4.0.2` -Foundation reports `built-in|installed|partial|available` module status and includes owned schema metadata in `module:list`. +Optional capability packages: -## Module config + schema lifecycle +- `infocyph/cachelayer ^3.2.0` +- `infocyph/dblayer ^4.1` +- `infocyph/epicrypt ^2.1` +- `infocyph/omnibus ^2.4` +- `infocyph/otp ^6.0` +- `infocyph/pathwise ^3.1` +- `infocyph/reqshield ^3.0.1` +- `infocyph/talkingbytes ^2.0` +- `web-auth/webauthn-lib ^5.3.5` +- `infocyph/phpforge dev-main@dev` -A module installation is operationally complete for database-backed capabilities rather than stopping at Composer/config publication. +## Purpose-first modules -Current database schema ownership: - -| Module | Schema behavior | +| Module | Purpose | |---|---| -| `auth` | Foundation auth schema covering accounts, sessions/tokens, MFA factors/revisions, passkeys and authorization | -| `cache` | CacheLayer native PDO/SQLite cache-entry schema and active PDO invalidation schema | -| `session` | Foundation database-session schema | - -Other modules currently own no application tables. The `database` module provides DB/migration infrastructure rather than another application schema. - -CacheLayer node/tiered SQLite internals continue to self-initialize inside CacheLayer; Infbyte/Foundation do not copy private CacheLayer SQL. - -### Commands - -- `php infbyte module:list` -- `php infbyte module:show ` -- `php infbyte module:install ` -- `php infbyte module:remove ` -- `php infbyte module:config:publish [--force]` -- `php infbyte module:schema:status ` -- `php infbyte module:schema:install ` -- `php infbyte module:schema:sync` - -Schema commands accept `--connection` where applicable. - -Old `auth:schema:*` and `session:schema:*` command families remain removed in favor of the single module schema lifecycle. - -### `module:install` lifecycle - -After package/config changes Foundation: - -1. invalidates compiled runtime container state; -2. launches schema synchronization in a fresh PHP process so the updated Composer autoloader is used; -3. provisions only schemas required by current application configuration; -4. reports schema state and fails when an active required schema cannot be provisioned. - -This makes install order safe: a later `module:install database` can synchronize already-configured database auth/session/cache requirements. - -`module:remove` never drops schemas or user/application data. - -`app:ready` also verifies applicable module schemas, so package installation alone no longer counts as persistence readiness. - -## Auth config alignment - -`config/auth.php` documents purpose-module requirements and schema behavior: - -- database-backed auth storage -> `module:install database` plus Foundation auth schema; -- cache-backed auth state -> `module:install cache`; -- enhanced password/token drivers -> `module:install security`; -- OTP or WebAuthn -> `module:install auth`; -- external communication notifications -> `module:install communication`; -- schema state may be checked/prepared with `module:schema:status auth` / `module:schema:install auth`. - -Package installation, config publication, schema readiness, and runtime activation remain distinct states. - -## Foundation CLI expansion inherited by Infbyte - -No second Infbyte command layer was added. Because the root launcher already delegates to Foundation `CommandDispatcher`, the expanded Foundation catalog is automatically the Infbyte CLI surface. - -### Database/cache - -New/expanded commands include: - -- `db:monitor`; -- `db:wipe`; -- `migrate --pretend`; -- `migrate:rollback --batch=N`; -- `cache:forget`. - -Foundation delegates database monitoring/migration/schema primitives to DBLayer and cache primitives to CacheLayer. - -### Messaging/queues - -New/expanded commands include: - -- `messaging:list`; -- `queue:failed`; -- `queue:failed:show`; -- `queue:retry`; -- `queue:forget`; -- `queue:flush`; -- `queue:prune-failed`; -- `queue:monitor`. - -Failure/transport/worker mechanics remain Omnibus-owned. +| `auth` | OTP/MFA + WebAuthn/passkeys | +| `cache` | cache/shared state/coordination | +| `communication` | HTTP/email/webhook/gRPC | +| `database` | DB/persistence/schema/migrations | +| `filesystem` | storage/files/uploads/downloads/archives | +| `logging` | built-in logging | +| `messaging` | Omnibus 2.4 messages/events/queues/middleware/workers | +| `operations` | built-in maintenance/history/runtime control/process visibility | +| `resources` | built-in response resources | +| `security` | cryptography/password/token/key services | +| `session` | built-in sessions/CSRF/flash/locking | +| `validation` | ReqShield-backed request/config/schema/database validation | -### Scheduling/storage/auth/logging +Canonical aliases remain purpose-oriented: `db|dblayer -> database`, `crypto|epicrypt -> security`, `otp|mfa|passkey|passkeys|webauthn -> auth`, `ops|runtime -> operations`. -New/expanded commands include: +No standalone OTP/passkey public module exists. -- `schedule:test`; -- `schedule:interrupt`; -- richer `schedule:list` execution state; -- `storage:status`; -- `storage:unlink`; -- `auth:prune`; -- `log:tail [--follow]`. +## Module config + schema lifecycle inherited by Infbyte -### Generators +Commands: -The Foundation generator surface now includes: +- `module:list` +- `module:show ` +- `module:install ` +- `module:remove ` +- `module:config:publish [--force]` +- `module:schema:status [--connection=...]` +- `module:schema:install [--connection=...]` +- `module:schema:sync [--connection=...]` -- `create:config`; -- `create:resource`; -- `create:job`; -- `create:handler`; -- `create:job-middleware`. +Schema owners: -Jobs are generated as data messages implementing Foundation `Job`; handlers remain separate explicit callables. Request/rule/mail/notification generators remain absent until those Foundation application contracts are reviewed. +- auth -> Foundation auth schema; +- cache -> CacheLayer native PDO/SQLite/invalidation schemas; +- session -> Foundation database-session schema. -## Omnibus 2.3 + Foundation job execution +Schema status is read-only; explicit installation owns creation. `module:remove` never drops schema/data. -Foundation's messaging module now requires `infocyph/omnibus ^2.3` and uses Omnibus' public handler middleware pipeline rather than duplicating execution middleware. +Forced config publication is transactional, refuses symbolic-link replacement and reports incomplete rollback rather than silently leaving partial files. -Application-facing Foundation contracts are: +## Application contracts now available to Infbyte apps -- `Infocyph\Foundation\Messaging\Job`; -- `JobContext` with queue/attempt/sync-vs-async metadata; -- `JobMiddleware` with a no-argument continuation. +### Validation -Foundation bridges these through one Omnibus `HandlerMiddleware` adapter. The same Omnibus `HandlerInvoker` is shared by synchronous `SyncTransport` and queued Consumer execution, so middleware semantics do not diverge by transport. +- Foundation `FormRequest` composes Webrick request input into ReqShield; +- custom rules implement ReqShield `Contracts\Rule` directly; +- generators: `create:request`, `create:rule`. -Published messaging configuration provides: +### Notifications/mail -```text -messaging.handler_middleware -messaging.job_middleware -``` +Foundation core routing is built in: -`handler_middleware` is the low-level Omnibus surface for all messages. `job_middleware` is the Foundation application surface and applies only to `Job` messages. Ordinary synchronous event listeners remain outside the message-handler middleware pipeline. +- `Notification`; +- `NotificationRecipient`; +- `NotificationChannel`; +- `NotificationDispatcher`/registry. -Infbyte does not check in `config/messaging.php`; it remains module-published. Therefore no Infbyte source/config change is required for this feature. +Custom notification channels do not require TalkingBytes. -## Operations module/runtime +Mail remains optional communication infrastructure: -Foundation provides built-in `operations` configuration for: +- Foundation `MailMessage`/`Mailer` adapt TalkingBytes email; +- `create:mail` and the default mail-based `create:notification` require communication; +- `create:notification-channel` is package-neutral. -```text -operations.history.* -operations.maintenance.* -operations.runtime_control.* -operations.runtime_registry.* -``` +### Messaging/jobs -The skeleton does **not** check in `config/operations.php` by default. Foundation defaults make the built-in module usable dependency-free, while applications that need tuning can publish it with: +- `Job` data-message marker; +- `JobContext`; +- `JobMiddleware`; +- Omnibus-backed handler pipeline; +- generators: `create:job`, `create:handler`, `create:job-middleware`. -```bash -php infbyte module:config:publish operations -``` +### Resources -### Execution history +- built-in `JsonResource`; +- `create:resource` uses the current `resolve(): mixed` contract. -- `execution:list`; -- `execution:show`; -- `execution:clear`. +## Application object rule -History is opt-in because it writes operational metadata. +Foundation `Application` is no longer a broad service facade. It retains runtime/bootstrap state, config/container/provider/service resolution, execution scope, paths and canonical HTTP handling. -### Maintenance +App code should inject/resolve concrete services rather than calling convenience proxies for auth/session/router/responses/testing or specialist managers. -- `maintenance:enable`; -- `maintenance:disable`; -- `maintenance:status`. +## Runtime/operations behavior inherited by Infbyte -The default state driver is file-backed. Cache-backed shared state is available for multi-node deployment. Foundation's HTTP kernel enforces maintenance with HTTP 503 and optional `Retry-After`. +### Omnibus 2.4 workers -### Persistent runtime control +- single messaging workers use Omnibus native `WorkerLifecycle` for heartbeat/reload/stop handling; +- this path no longer requires `pcntl`; +- Unix `WorkerPool` retains the watchdog because the upstream pool itself is pcntl/posix based; +- provider-only workers remain messaging-lazy. -- `runtime:reload`; -- `worker:restart [name]`; -- `worker:status [name]`; -- `schedule:interrupt`. +### Scheduler ownership -Foundation uses generation markers and heartbeat-visible worker/scheduler process records. It requests graceful shutdown; Supervisor/systemd/Docker/Kubernetes or another process manager remains responsible for replacement processes. +- overlap/single-server locks refresh throughout child execution; +- lost lease terminates/fails the child instead of continuing without ownership; +- schedule history uses stable schedule identity, not only command text; +- `schedule:test` reports real failure status. -Messaging remains lazily activated only when a configured messaging worker is actually selected. +### Runtime control -## Environment protection +- generation-map mutations are atomic for file and CacheLayer-backed state; +- cache-backed runtime control requires suitable shared visibility and coordination; +- process registry visibility is `host|shared`, default `host`; +- `worker:status` exposes the registry view; +- process registry remains observability metadata, not a daemon supervisor. -Infbyte inherits: +### Other operations -- `env:encrypt`; -- `env:decrypt`. +- supervised child commands do not duplicate `--profile` output; +- `log:tail --follow` handles truncation/rotation; +- production OTP validation uses production topology assumptions; +- `AuthPruner` covers disposable expired/consumed/revoked auth state; +- environment encryption remains Epicrypt-backed with external key material only. -Foundation delegates encryption/decryption to Epicrypt. Key material is supplied through an external environment variable (default `ENV_ENCRYPTION_KEY`) or `--key-file`. +## Readiness behavior -`ENV_ENCRYPTION_KEY` is deliberately **not** added to `.env.example`: storing the key in the environment file being protected would defeat the protection boundary. +`app:ready` now accounts for capability-specific dependencies, including: -Forced replacement is staged and restores the previous target when publication/finalization fails. +- CacheLayer for session locks; +- CacheLayer for migration locks; +- CacheLayer for cache-backed maintenance/runtime-control state; +- DBLayer for explicit validation DB connections; +- exact active package(s) inside the multi-package auth module; +- applicable auth/cache/session schema readiness. -## Global CLI controls +Infbyte does not add a second readiness layer. -The root `infbyte` launcher automatically exposes Foundation's global command controls: +## CLI inheritance -- `-q|--quiet`; -- `--silent`; -- `-v|-vv|-vvv`; -- `--profile`; -- `-n|--no-interaction`; -- `--json`; -- `--env=...`; -- help/version/completion. +Because `infbyte` directly delegates to Foundation, the skeleton automatically receives the current capability-oriented command catalog and generator surface. No duplicate Infbyte command classes are introduced. -`--profile` writes diagnostics to STDERR so command/JSON stdout remains clean. `--silent` suppresses all output and interactive prompting. +Global controls include `--quiet`, `--silent`, `-v|-vv|-vvv`, `--profile`, `--json`, `--env`, `--no-interaction`, help/version/completion. ## Deliberate Infbyte non-changes -Infbyte source checkpoint remains `56cb73e18eab07f34242a929eccbc9e6572d9971` because no application-side workaround or duplicate command/config layer is needed. +The Infbyte **source** checkpoint remains `56cb73e18eab07f34242a929eccbc9e6572d9971` throughout these Foundation cleanup batches. -In particular: +That is intentional: +- no optional `operations.php`, `messaging.php`, `notifications.php`, validation or other module config is copied into the base skeleton; - `.env.example` remains lean; -- optional module environment variables are not listed before their config is published; -- encryption key material is not placed in `.env.example`; -- `config/operations.php` and `config/messaging.php` are not copied into the default skeleton; -- no queue/database/cache/security implementation is duplicated in Infbyte. +- no environment-encryption key is stored in `.env`/`.env.example`; +- no queue/cache/database/communication/validation/schema implementation is duplicated; +- no workaround is added in Infbyte for a Foundation defect. -This is intentional architecture, not missing implementation. +## Verification status -## Source-audit status - -Foundation completed the Omnibus 2.3/job-integration source/config audit at source checkpoint `17a3a19cf27ba2d2c39b5722be3cc1d37f8a6eb5`. - -The audit confirmed shared sync/async `HandlerInvoker` composition, Omnibus 2.3 capability probing, middleware/default/config-validator alignment, job middleware isolation from Omnibus Envelope details, generator gating, lazy messaging activation and pooled-worker declarative-config safety. - -No PHPUnit/static-analysis/PHPForge/release matrix was run as part of this cleanup batch. +Current work is a source/config/API audit only. The full Foundation 2.0 + Infbyte verification matrix remains intentionally deferred until documentation/public names are frozen. ## Immediate next work -Continue Foundation application-contract cleanup for validation/request and notification/mail before documentation freeze. Infbyte should change only if those contracts require actual application-skeleton defaults or structure. - -After application-contract cleanup: - -1. reconcile Foundation + Infbyte documentation; -2. freeze public command/module/config names; -3. run the deferred test/release matrix; -4. perform final Foundation 2.0 + Infbyte compatibility/release review. +1. reconcile Foundation README/docs with source checkpoint `493c39a7a06bac0455397556254f0f8e7e25f973`; +2. reconcile Infbyte README/examples with that public surface; +3. remove stale Omnibus 2.3 / CacheLayer 3.1 / old generator / old Application-facade references; +4. freeze public command/module/config/class names; +5. run the deferred PHPUnit/static/PHPForge/module/runtime/fork/performance verification matrix; +6. fix verification defects and prepare Foundation 2.0 + Infbyte release alignment. ## Do not regress - no package-per-module public model; -- no standalone OTP/passkeys modules; -- no duplicated specialized schema command families; +- no standalone OTP/passkey module; +- no duplicate specialist schema command families; - no schema/data deletion during module removal; -- no copied specialist-package SQL; -- no fake generator-only abstractions; -- no second queue/retry/worker engine above Omnibus; -- no Omnibus Envelope/HandlerContext leakage into Foundation JobMiddleware; +- no copied specialist SQL/queue/retry/cache/database/communication engine; +- no broad Application/service facade in Infbyte; - no retired Console runtime hierarchy; -- no generic ID-driver/request-scope compatibility; -- no broad manager/facade proxies in Infbyte; -- no copied optional-module config by default; +- no static global application state; +- no optional config copied into the skeleton by default; - no environment-protection key in `.env`/`.env.example`; - no generated optimized artifacts committed. From 26a35da0926285119c31ed880bf1f5aa06f3cf19 Mon Sep 17 00:00:00 2001 From: "A. B. M. Mahmudul Hasan" Date: Mon, 24 Aug 2026 05:23:52 +0600 Subject: [PATCH 37/51] Align Infbyte skeleton README with Foundation 2.0 --- README.md | 308 +++++++++++++++++++++++++++++++++++++++--------------- 1 file changed, 221 insertions(+), 87 deletions(-) diff --git a/README.md b/README.md index 06d90de..8741fcf 100644 --- a/README.md +++ b/README.md @@ -2,10 +2,19 @@ Infbyte is the minimal application skeleton for [Infocyph Foundation](https://github.com/infocyph/Foundation). Foundation owns -the reusable framework runtime; Infbyte provides the application bootstrap, -configuration, routes, storage layout, and starter code. +the reusable framework/runtime layer; Infbyte provides opinionated application +bootstrap, starter configuration, routes, writable layout, and application code. -Infbyte 1.x requires PHP 8.4 or newer. +Infbyte requires PHP 8.4+. + +During Foundation 2.0 development this branch targets: + +```json +"infocyph/foundation": "dev-feature/foundation-2.0 as 2.0.x-dev" +``` + +The release constraint will move to the stable Foundation 2.0 line for the final +application release. ## Quick start @@ -15,146 +24,271 @@ cd my-app php infbyte serve ``` -The development server listens on `http://127.0.0.1:8000` by default. Select a -different address or port when needed: +The built-in server defaults to `127.0.0.1:8000` and is for local development +only: ```bash php infbyte serve --host=0.0.0.0 --port=8080 ``` -The built-in server is intended for local development only. Composer invokes -Foundation's `app:install` command to create `.env` from `.env.example` and -generate a unique authentication secret without replacing an existing one. +Composer invokes Foundation's `app:install` post-create command. The application +root executable remains `infbyte`; there is no separate Artisan/Console runtime. + +## Foundation runtime boundary + +Infbyte does not implement a framework layer above Foundation. + +The Web bootstrap is deliberately small: + +```php +use Infocyph\Foundation\Foundation; + +return Foundation::web([ + 'base_path' => dirname(__DIR__), +]); +``` + +Foundation's `CommandDispatcher` selects CLI, Worker, and Scheduler runtimes for +the root `infbyte` executable when commands require them. + +The four Foundation runtimes are: -The starter application exposes: +- Web +- CLI +- Worker +- Scheduler -- `GET /api/health` -- `GET /json` +Optional package providers remain lazy until configuration/code selects their +capability. -## Console +## CLI -Run `php infbyte list` to see every available command. Frequently used commands -include: +List the current command surface with: + +```bash +php infbyte list +``` + +Common families include: | Purpose | Commands | | --- | --- | -| Inspect the application | `about`, `env:show`, `config:show`, `route:list` | +| Inspect | `about`, `env:show`, `config:show`, `config:validate`, `route:list` | | Local development | `serve`, `create:*` | -| Optional capabilities | `module:list`, `module:install`, `module:remove` | -| Database work | `db:show`, `db:table`, `db:seed`, `migrate*` | -| Runtime maintenance | `app:install`, `cache:clear`, `storage:link`, `secret:generate` | -| Background work | `schedule:*`, `worker:*`, `queue:consume` | -| Deployment | `optimize`, `optimize:clear`, `app:ready` | +| Modules | `module:list`, `module:show`, `module:install`, `module:remove`, `module:config:publish`, `module:schema:*` | +| Database | `db:*`, `migrate*` | +| Operations | `execution:*`, `maintenance:*`, `runtime:reload`, `log:tail` | +| Background work | `schedule:*`, `worker:*`, `queue:*`, `messaging:list` | +| Storage/session/auth | `storage:*`, `session:prune`, `auth:prune` | +| Environment protection | `env:encrypt`, `env:decrypt` | +| Deployment | `optimize`, `optimize:clear`, `optimize:report`, `app:ready` | + +Global controls include `--json`, `-q|--quiet`, `--silent`, `-v|-vv|-vvv`, +`--profile`, `--env`, and `-n|--no-interaction`. + +Application commands are registered explicitly in `routes/console.php`, +schedules in `routes/schedule.php`, and non-message maintenance workers in +`routes/workers.php`. -Some commands become usable only after their corresponding optional module is -installed. Missing capabilities report the exact installation command. +## Application generators -Create application artifacts without adding unused runtime services: +Foundation generators create application starting points without silently +editing registration/configuration: ```bash php infbyte create:controller Admin/User php infbyte create:command Reports/Daily +php infbyte create:request StoreUser +php infbyte create:rule ValidVatNumber +php infbyte create:resource User +php infbyte create:job GenerateReport +php infbyte create:handler GenerateReport +php infbyte create:job-middleware AuditJob +php infbyte create:mail Welcome +php infbyte create:notification PasswordChanged +php infbyte create:notification-channel Sms php infbyte create:repository User -php infbyte create:worker Queue -php infbyte create:test Http/UserAccess +php infbyte create:migration CreateUsers +php infbyte create:seeder Production +php infbyte create:worker Metrics ``` -Existing files are preserved unless `--force` is supplied. Register application -commands explicitly in `routes/console.php`, schedules in `routes/schedule.php`, -and supervised workers in `routes/workers.php`. +Existing files are preserved unless `--force` is supplied. -For an intentionally static controller action, use a first-class callable such -as `Route::get('/reports', ReportsController::show(...))`; route caching converts -that safe form to a plain descriptor. Captured closures and instance handlers -remain supported through the general cached-handler path. +## Purpose-first optional modules -## Optional modules - -A new project installs only the core runtime. Add or publish capabilities as the -application needs them: +A new application keeps only the Foundation core runtime. Add capabilities as +they are needed: ```bash php infbyte module:list -php infbyte module:install db +php infbyte module:install database php infbyte module:install cache +php infbyte module:install communication php infbyte module:install messaging -php infbyte module:install session +php infbyte module:config:publish operations ``` -Available modules include database, cache, communication, cryptography, -filesystem, logging, messaging, OTP, passkeys, JSON resources, sessions, and -validation. Installation publishes documented configuration without activating -global middleware, providers, connections, workers, or sessions. Optional -services remain lazy until selected by application code, a route, or a command. +Canonical modules are: + +- `auth` +- `cache` +- `communication` +- `database` +- `filesystem` +- `logging` (built in) +- `messaging` +- `operations` (built in) +- `resources` (built in) +- `security` +- `session` (built in) +- `validation` + +Aliases such as `db`, `crypto`, `otp`, `passkeys`, and `queue` remain accepted, +but the application documentation uses purpose names. OTP and WebAuthn are +implementations inside the `auth` module rather than standalone public modules. + +Installing a module does not add global middleware, open connections, or start +workers. Optional config is published only when requested/needed and remains +outside the lean checked-in skeleton by default. + +## Module schema lifecycle + +Capability-owned schemas use one command family: + +```bash +php infbyte module:schema:status auth +php infbyte module:schema:install auth +php infbyte module:schema:status cache +php infbyte module:schema:install session +php infbyte module:schema:sync +``` + +The `database` module owns DB/migration infrastructure; it does not own arbitrary +application tables. Removing a module never drops schemas/application data. ## Application structure -- `app/` contains application controllers, commands, and generated code. -- `bootstrap/` contains the isolated web and console composition roots. -- `config/` contains application-owned configuration. -- `routes/` contains HTTP, command, schedule, and worker mappings. -- `public/` contains the web entry point. -- `storage/` contains writable runtime data. -- `tests/Feature/` and `tests/Unit/` contain starter Pest examples. +The starter intentionally stays small: + +```text +app/ +bootstrap/ + app.php + providers.php + cache/ +config/ + app.php + auth.php + router.php +public/ +routes/ + web.php + api.php + auth.php + console.php + schedule.php + workers.php +storage/ +tests/ +composer.json +infbyte +``` + +Only application-default config is checked in. Cache/database/filesystem/ +messaging/operations/security/session/validation/communication config belongs +to optional module publication rather than being bulk-copied into every new +project. -Web requests boot only the HTTP path. CLI requests boot only the command -capabilities they require; the ordinary web path does not load console command, -schedule, or worker definitions. +## Database -## Testing +```bash +php infbyte module:install database +php infbyte migrate +php infbyte migrate --pretend +php infbyte migrate:status +php infbyte db:monitor --section=status +``` + +Application migrations are registered explicitly under +`database.migrations.classes`; Foundation does not scan migration directories. -The generated project includes one feature test and one unit test: +## Messaging and workers + +Omnibus-backed messaging is optional: ```bash -composer ic:tests +php infbyte module:install messaging +php infbyte worker:list +php infbyte worker:run reports +php infbyte worker:status reports +php infbyte queue:failed ``` -Foundation provides a native Webrick HTTP test client, as demonstrated by -`tests/Feature/ExampleTest.php`. Infbyte's repository-only release tests are -excluded from Composer-created projects. +Foundation does not expose a parallel messaging manager. Application services +resolve native Omnibus `MessageBus`, `EventDispatcher`, and related APIs through +DI. + +`routes/workers.php` is only for application maintenance workers; queue worker +loops remain Omnibus-owned. + +## Runtime operations + +Useful production/runtime commands include: + +```bash +php infbyte config:validate --production +php infbyte maintenance:status +php infbyte runtime:reload +php infbyte worker:restart +php infbyte schedule:interrupt +php infbyte storage:status +php infbyte log:tail --follow +``` + +Runtime generation commands request graceful shutdown. Foundation does not +replace Supervisor/systemd/Docker/Kubernetes process supervision. ## Production -Compile application metadata before serving production traffic: +Build deployment-owned optimized artifacts before serving production traffic: ```bash php infbyte optimize +php infbyte optimize:report php infbyte app:ready ``` -`optimize` compiles configuration, route, command, schedule, and module metadata -plus the eligible HTTP container graph so requests do less work. It publishes a -final optimize manifest only after the complete set is ready. `optimize:clear` -removes every generated artifact and leaves uncached execution available. +Clear generated artifacts with: -`APP_CONFIG_CACHE_TYPE=single` loads one snapshot; `sharded` loads configuration -namespaces on demand. Neither is universally faster: measure the application's -minimal, authenticated, and database-backed routes before selecting one. -Compiled-container activation remains `off` by default because small requests -may not amortize its boot cost; use `always` only for a measured deployment, -commonly a persistent worker with OPcache. +```bash +php infbyte optimize:clear +``` -Webrick automatically selects the response emitter. A known deployment may set -`WEBRICK_EMITTER` to `fpm`, `frankenphp`, `lsapi`, `unit`, `swoole`, -`roadrunner`, or `workerman`; leave it unset when runtime detection is desired. +Compiled config/route/command/schedule/container artifacts belong to deployment +and are ignored by the skeleton repository. -The included deployment helper validates writable runtime paths and builds the -same caches: +Before deployment: -```bash -./deploy.sh -``` +- set production environment/debug policy; +- configure only the modules the application actually uses; +- run application migrations; +- provision applicable module schemas; +- require `config:validate --production` / `app:ready` to pass; +- use a production web server and external process manager. + +## Testing and release checks -Before deployment, set `APP_ENV=production`, disable debug output, configure -installed modules, apply required migrations, and require `app:ready` to pass. +The current skeleton Composer file does not invent generic test/release script +aliases. Run the tools/scripts actually installed by the application/release +candidate. Foundation's full Composer/PHPForge/static/PHPUnit/integration and +performance matrix is performed in its dedicated release-verification phase. ## Documentation -- [Foundation](https://github.com/infocyph/Foundation/tree/main/docs) -- [Console](https://github.com/infocyph/Console/tree/main/docs) -- [Omnibus](https://github.com/infocyph/Omnibus/tree/main/docs) -- [Webrick](https://docs.infocyph.com/projects/webrick/en/latest/) -- [JsonDispatch](https://docs.infocyph.com/projects/json-dispatch/) +- [Foundation documentation](https://github.com/infocyph/Foundation/tree/feature/foundation-2.0/docs) +- [Omnibus](https://github.com/infocyph/Omnibus) +- [Webrick](https://github.com/infocyph/Webrick) -Detailed framework and package documentation will expand separately; this -README intentionally remains a concise application quick start. +Infbyte keeps framework details in Foundation documentation rather than copying +them into the application skeleton. From ec466bffac195eaf837a4a5af3932aa573fdfa4d Mon Sep 17 00:00:00 2001 From: "A. B. M. Mahmudul Hasan" Date: Mon, 24 Aug 2026 05:29:45 +0600 Subject: [PATCH 38/51] Freeze Infbyte Foundation 2.0 application surface --- infbyte_work_plan.md | 288 ++++++++++++++++++++++++++----------------- 1 file changed, 172 insertions(+), 116 deletions(-) diff --git a/infbyte_work_plan.md b/infbyte_work_plan.md index 804b883..9e550b8 100644 --- a/infbyte_work_plan.md +++ b/infbyte_work_plan.md @@ -9,36 +9,41 @@ - Date: 2026-08-24 - Infbyte source checkpoint: `56cb73e18eab07f34242a929eccbc9e6572d9971` +- Infbyte documentation checkpoint: `26a35da0926285119c31ed880bf1f5aa06f3cf19` - Foundation source checkpoint: `493c39a7a06bac0455397556254f0f8e7e25f973` +- Foundation documentation checkpoint: `944220490e1c28e9945fd398265dc9d072eb4c93` - Infbyte branch base: `main` at `47fb985f266c977504c3dca6bd13e85c9a1b73dc` -- Current phase: **Foundation + Infbyte documentation reconciliation and public-name/config freeze**. -- Application-contract/API cleanup: complete in Foundation. -- Full PHPUnit/static/PHPForge/runtime/release matrix: not run yet. +- Current phase: **Foundation 2.0 public-name/config freeze complete; ready for deferred verification matrix**. +- Full PHPUnit/static/PHPForge/runtime/release matrix: **not run yet**. -## Ownership +# Ownership boundary -Foundation owns reusable runtime composition, DI/provider activation policy, CLI/runtime machinery, purpose modules, module schema orchestration, configuration/optimization, operational runtime controls, application contracts and specialist integrations. +Foundation owns reusable framework/runtime behavior: explicit runtimes, DI/provider activation, CLI, scheduler/worker composition, purpose modules, schema orchestration, optimization, operational controls, application contracts, and specialist-package integration. -Infbyte owns the opinionated application skeleton: project bootstrap, app-specific config, routes/application code, deployment conventions and final developer experience. +Infbyte owns only the opinionated host skeleton: application bootstrap, app-specific defaults, routes/application code, writable layout, deployment conventions, and final developer experience. -Specialist packages retain their storage/database/cache/communication/crypto/messaging/validation engines. Neither Foundation nor Infbyte copies those implementations. +Specialist packages retain their own database/cache/messaging/communication/crypto/validation/filesystem engines. -## Fixed Infbyte structure +# Frozen Infbyte structure - root `infbyte` delegates to Foundation `CommandDispatcher`; -- web bootstrap delegates to one `Foundation::web()` application; -- runtime selection for CLI/Worker/Scheduler is Foundation-owned; +- Web bootstrap delegates to one `Foundation::web()` application; +- CLI/Worker/Scheduler runtime selection is Foundation-owned; +- Foundation has exactly Web, CLI, Worker, Scheduler runtimes; - provider groups are `common|web|cli|worker|scheduler`; -- checked-in config remains deliberately lean: `app.php`, `auth.php`, `router.php`; -- optional module config is published on demand, not copied into the skeleton; -- route files use the loader-provided scoped Webrick registrar; -- `routes/console.php` and `routes/workers.php` remain application registration surfaces; +- checked-in config remains deliberately only `app.php`, `auth.php`, `router.php`; +- optional capability config is module-published on demand; +- `routes/console.php` registers application commands; +- `routes/schedule.php` registers schedule definitions; +- `routes/workers.php` registers non-message maintenance workers; - generated optimized artifacts are not committed; - deployment optimization uses `php infbyte optimize`. -## Current Foundation package baseline +No retired Console runtime hierarchy is reintroduced. -Core: +# Foundation dependency baseline consumed by Infbyte + +Core Foundation runtime: - PHP `^8.4` - `infocyph/arraykit ^5.1.1` @@ -59,28 +64,45 @@ Optional capability packages: - `web-auth/webauthn-lib ^5.3.5` - `infocyph/phpforge dev-main@dev` -## Purpose-first modules - -| Module | Purpose | -|---|---| -| `auth` | OTP/MFA + WebAuthn/passkeys | -| `cache` | cache/shared state/coordination | -| `communication` | HTTP/email/webhook/gRPC | -| `database` | DB/persistence/schema/migrations | -| `filesystem` | storage/files/uploads/downloads/archives | -| `logging` | built-in logging | -| `messaging` | Omnibus 2.4 messages/events/queues/middleware/workers | -| `operations` | built-in maintenance/history/runtime control/process visibility | -| `resources` | built-in response resources | -| `security` | cryptography/password/token/key services | -| `session` | built-in sessions/CSRF/flash/locking | -| `validation` | ReqShield-backed request/config/schema/database validation | - -Canonical aliases remain purpose-oriented: `db|dblayer -> database`, `crypto|epicrypt -> security`, `otp|mfa|passkey|passkeys|webauthn -> auth`, `ops|runtime -> operations`. +During branch development Infbyte requires: + +```json +"infocyph/foundation": "dev-feature/foundation-2.0 as 2.0.x-dev" +``` + +Final release alignment will move to the stable Foundation 2.0 constraint. + +# Frozen purpose-first modules + +Canonical modules: + +- `auth` +- `cache` +- `communication` +- `database` +- `filesystem` +- `logging` +- `messaging` +- `operations` +- `resources` +- `security` +- `session` +- `validation` + +Canonical aliases include: + +- `db|dblayer -> database` +- `crypto|epicrypt -> security` +- `otp|mfa|passkey|passkeys|webauthn -> auth` +- `notifications|talkingbytes -> communication` +- `events|omnibus|queue|queues -> messaging` +- `files|pathwise|storage -> filesystem` +- `reqshield|validator -> validation` +- `ops|runtime -> operations` No standalone OTP/passkey public module exists. -## Module config + schema lifecycle inherited by Infbyte +# Config/schema lifecycle inherited from Foundation Commands: @@ -95,141 +117,175 @@ Commands: Schema owners: -- auth -> Foundation auth schema; -- cache -> CacheLayer native PDO/SQLite/invalidation schemas; -- session -> Foundation database-session schema. +- `auth` -> Foundation auth schema; +- `cache` -> CacheLayer public PDO/SQLite/invalidation schemas; +- `session` -> Foundation database-session schema. -Schema status is read-only; explicit installation owns creation. `module:remove` never drops schema/data. +Schema status is read-only. Explicit installation owns mutation. Module removal never drops schema/data. -Forced config publication is transactional, refuses symbolic-link replacement and reports incomplete rollback rather than silently leaving partial files. +Infbyte does not copy optional config into the skeleton merely because Foundation supports the capability. -## Application contracts now available to Infbyte apps +# Application API rule -### Validation +Foundation `Application` is a narrow runtime/composition object. Infbyte application code should resolve real services through DI: -- Foundation `FormRequest` composes Webrick request input into ReqShield; -- custom rules implement ReqShield `Contracts\Rule` directly; -- generators: `create:request`, `create:rule`. +```php +$service = $app->make(ServiceClass::class); +``` -### Notifications/mail +Do not rely on or recreate removed convenience facades such as: -Foundation core routing is built in: +- `$app->auth()`; +- `$app->session()` / `$app->browserSession()`; +- `$app->router()`; +- `$app->responses()`; +- `$app->testing()`; +- `$app->messaging()`; +- generic cache/database/filesystem/security manager methods. -- `Notification`; -- `NotificationRecipient`; -- `NotificationChannel`; -- `NotificationDispatcher`/registry. +Concrete Foundation application services and native specialist services are resolved through constructor injection or `Application::make()`. -Custom notification channels do not require TalkingBytes. +# Application contracts available to Infbyte apps -Mail remains optional communication infrastructure: +## Validation -- Foundation `MailMessage`/`Mailer` adapt TalkingBytes email; -- `create:mail` and the default mail-based `create:notification` require communication; -- `create:notification-channel` is package-neutral. +- Foundation `FormRequest` composes Webrick request input with ReqShield; +- custom rules implement ReqShield `Contracts\Rule` directly; +- generators: `create:request`, `create:rule`. -### Messaging/jobs +## Notifications/mail -- `Job` data-message marker; -- `JobContext`; -- `JobMiddleware`; -- Omnibus-backed handler pipeline; -- generators: `create:job`, `create:handler`, `create:job-middleware`. +Foundation application routing: + +- `Notification` +- `NotificationRecipient` +- `NotificationChannel` +- `NotificationDispatcher` / registry + +TalkingBytes-backed mail: -### Resources +- `MailMessage` +- `Mailer` +- `MailNotificationChannel` -- built-in `JsonResource`; -- `create:resource` uses the current `resolve(): mixed` contract. +Generators: `create:mail`, `create:notification`, `create:notification-channel`. -## Application object rule +## Messaging/jobs -Foundation `Application` is no longer a broad service facade. It retains runtime/bootstrap state, config/container/provider/service resolution, execution scope, paths and canonical HTTP handling. +- `Job` +- `JobContext` +- `JobMiddleware` +- Omnibus-backed handler pipeline +- generators: `create:job`, `create:handler`, `create:job-middleware`. + +## Resources/testing -App code should inject/resolve concrete services rather than calling convenience proxies for auth/session/router/responses/testing or specialist managers. +- `JsonResource::resolve(): mixed`; +- `create:resource` targets the current contract; +- resolve `JsonDispatchResponseFactory`, `AuthServices`, and `TestKit` through DI rather than Application shortcuts. -## Runtime/operations behavior inherited by Infbyte +# Runtime/operations inherited by Infbyte -### Omnibus 2.4 workers +## Omnibus 2.4 workers -- single messaging workers use Omnibus native `WorkerLifecycle` for heartbeat/reload/stop handling; -- this path no longer requires `pcntl`; -- Unix `WorkerPool` retains the watchdog because the upstream pool itself is pcntl/posix based; +- single messaging workers use native Omnibus `WorkerLifecycle` for heartbeat/reload/stop; +- no `pcntl` requirement solely for single-worker generation polling; +- Unix `WorkerPool` remains pcntl/posix based and retains the Foundation watchdog; - provider-only workers remain messaging-lazy. -### Scheduler ownership +## Scheduler ownership -- overlap/single-server locks refresh throughout child execution; -- lost lease terminates/fails the child instead of continuing without ownership; -- schedule history uses stable schedule identity, not only command text; -- `schedule:test` reports real failure status. +- overlap/single-server locks refresh during child execution; +- lost lease terminates/fails the child; +- schedule history uses stable identity; +- `schedule:test` reports actual failure status. -### Runtime control +## Runtime control -- generation-map mutations are atomic for file and CacheLayer-backed state; +- file/cache generation-map mutations are atomic/serialized; - cache-backed runtime control requires suitable shared visibility and coordination; -- process registry visibility is `host|shared`, default `host`; -- `worker:status` exposes the registry view; -- process registry remains observability metadata, not a daemon supervisor. +- runtime registry visibility is `host|shared`, default `host`; +- process registry is observability metadata, not process-supervision truth. -### Other operations +## Other operations - supervised child commands do not duplicate `--profile` output; - `log:tail --follow` handles truncation/rotation; - production OTP validation uses production topology assumptions; -- `AuthPruner` covers disposable expired/consumed/revoked auth state; -- environment encryption remains Epicrypt-backed with external key material only. +- environment encryption remains Epicrypt-backed with external key material only; +- cache schema status does not create a missing SQLite file. -## Readiness behavior +# CLI inheritance -`app:ready` now accounts for capability-specific dependencies, including: +Because the root executable delegates directly to Foundation, Infbyte inherits the frozen Foundation command catalog without duplicate command classes. -- CacheLayer for session locks; -- CacheLayer for migration locks; -- CacheLayer for cache-backed maintenance/runtime-control state; -- DBLayer for explicit validation DB connections; -- exact active package(s) inside the multi-package auth module; -- applicable auth/cache/session schema readiness. +Major families: -Infbyte does not add a second readiness layer. +- application/config/cache/optimization; +- database/migrations; +- modules/config/schema lifecycle; +- execution/maintenance/runtime control; +- messaging/queue/scheduling/workers; +- storage/session/auth operations; +- environment protection/logging; +- `create:*` generators. -## CLI inheritance +Global controls include `--quiet`, `--silent`, `-v|-vv|-vvv`, `--profile`, `--json`, `--env`, `--no-interaction`, help/version/completion. -Because `infbyte` directly delegates to Foundation, the skeleton automatically receives the current capability-oriented command catalog and generator surface. No duplicate Infbyte command classes are introduced. +# Documentation alignment completed -Global controls include `--quiet`, `--silent`, `-v|-vv|-vvv`, `--profile`, `--json`, `--env`, `--no-interaction`, help/version/completion. +Infbyte README now reflects: + +- Foundation 2.0 runtime boundary; +- no separate Console framework; +- current purpose-first modules; +- unified module schema lifecycle; +- current generators/operations; +- DI instead of broad Application facades; +- lean checked-in config; +- deployment-owned optimize artifacts; +- absence of invented Composer test/release aliases. -## Deliberate Infbyte non-changes +Foundation documentation is the detailed framework source of truth; Infbyte does not duplicate it. -The Infbyte **source** checkpoint remains `56cb73e18eab07f34242a929eccbc9e6572d9971` throughout these Foundation cleanup batches. +# Deliberate Infbyte non-changes -That is intentional: +Infbyte application source/config checkpoint remains unchanged through the Foundation cleanup/doc-freeze work. This is intentional: -- no optional `operations.php`, `messaging.php`, `notifications.php`, validation or other module config is copied into the base skeleton; -- `.env.example` remains lean; -- no environment-encryption key is stored in `.env`/`.env.example`; +- no optional operations/messaging/notifications/database/cache/etc. config is copied into the base skeleton; +- `.env.example` remains lean and contains no environment-encryption key; - no queue/cache/database/communication/validation/schema implementation is duplicated; -- no workaround is added in Infbyte for a Foundation defect. +- no Infbyte workaround is added for a Foundation defect; +- no generated optimized artifacts are committed. -## Verification status +# Verification status -Current work is a source/config/API audit only. The full Foundation 2.0 + Infbyte verification matrix remains intentionally deferred until documentation/public names are frozen. +Public names/config are frozen. The full Foundation 2.0 + Infbyte verification matrix remains **not run yet**. -## Immediate next work +Next phase: -1. reconcile Foundation README/docs with source checkpoint `493c39a7a06bac0455397556254f0f8e7e25f973`; -2. reconcile Infbyte README/examples with that public surface; -3. remove stale Omnibus 2.3 / CacheLayer 3.1 / old generator / old Application-facade references; -4. freeze public command/module/config/class names; -5. run the deferred PHPUnit/static/PHPForge/module/runtime/fork/performance verification matrix; -6. fix verification defects and prepare Foundation 2.0 + Infbyte release alignment. +1. Composer/dependency validation; +2. PHPForge/static analysis; +3. PHPUnit/integration suites; +4. clean create-project/install path; +5. core-only Foundation/Infbyte runtime; +6. purpose-module install/remove/config/schema matrix, including partial auth bundle/install ordering; +7. `app:ready` / production config diagnostics; +8. CLI/global-option/help/completion matrix; +9. Web/CLI/Worker/Scheduler isolation; +10. maintenance/reload/worker/scheduler lifecycle; +11. queue failure/job middleware/pool/fork behavior; +12. DB/destructive/env/storage/optimization safety; +13. representative performance/soak checks; +14. fix defects and move Foundation/Infbyte constraints to stable release alignment. -## Do not regress +# Do not regress - no package-per-module public model; - no standalone OTP/passkey module; - no duplicate specialist schema command families; - no schema/data deletion during module removal; -- no copied specialist SQL/queue/retry/cache/database/communication engine; +- no copied specialist engine/SQL/queue/retry/cache/database/communication implementation; - no broad Application/service facade in Infbyte; - no retired Console runtime hierarchy; - no static global application state; From 48ffb780958f7bf3d5d59ebdb8c93f9c2c98213e Mon Sep 17 00:00:00 2001 From: "A. B. M. Mahmudul Hasan" Date: Tue, 25 Aug 2026 14:50:08 +0600 Subject: [PATCH 39/51] Align skeleton runtime tests with Foundation 2 --- tests/Feature/FrameworkRuntimeTest.php | 198 +++++++++++-------------- 1 file changed, 87 insertions(+), 111 deletions(-) diff --git a/tests/Feature/FrameworkRuntimeTest.php b/tests/Feature/FrameworkRuntimeTest.php index b45a8d0..ba974b7 100644 --- a/tests/Feature/FrameworkRuntimeTest.php +++ b/tests/Feature/FrameworkRuntimeTest.php @@ -3,27 +3,15 @@ declare(strict_types=1); use Infocyph\Foundation\Application\Application; -use Infocyph\Foundation\Auth\Contract\Notification\AuthNotifierInterface; -use Infocyph\Foundation\Cache\CacheManager; -use Infocyph\Console\Command\CommandContract; -use Infocyph\Foundation\Console\FoundationConsole; -use Infocyph\Foundation\Database\DatabaseManager; -use Infocyph\Foundation\Filesystem\FilesystemManager; +use Infocyph\Foundation\Application\RuntimeMode; +use Infocyph\Foundation\Config\ConfigRepository; +use Infocyph\Foundation\Filesystem\PathManager; use Infocyph\Foundation\Foundation; use Infocyph\Foundation\Http\HttpKernel; -use Infocyph\Foundation\Notifications\NotificationManager; -use Infocyph\Foundation\Routing\RouteFileLoader; -use Infocyph\Foundation\Routing\RouterManager; -use Infocyph\Foundation\Validation\ValidationManager; +use Infocyph\Foundation\Runtime\ExecutionScope; +use Infocyph\Webrick\Request\Request; -function infbyteApp(): Application -{ - return Foundation::web(infbyteTestOptions()); -} - -/** - * @return array - */ +/** @return array */ function infbyteTestOptions(): array { $root = dirname(__DIR__, 2); @@ -31,7 +19,7 @@ function infbyteTestOptions(): array . '/infbyte-runtime-' . getmypid(); - foreach (['app', 'app/public', 'cache', 'logs', 'sessions', 'uploads'] as $directory) { + foreach (['cache', 'logs', 'sessions', 'uploads'] as $directory) { $path = $runtime . DIRECTORY_SEPARATOR . $directory; if (!is_dir($path) && !mkdir($path, 0775, true) && !is_dir($path)) { @@ -42,7 +30,9 @@ function infbyteTestOptions(): array return [ 'base_path' => $root, '_config_cache' => false, - 'env' => 'testing', + 'app' => [ + 'env' => 'testing', + ], 'paths' => [ 'storage' => $runtime, 'cache' => $runtime . '/cache', @@ -50,124 +40,110 @@ function infbyteTestOptions(): array 'sessions' => $runtime . '/sessions', 'uploads' => $runtime . '/uploads', ], - 'auth' => [ - 'drivers' => [ - 'cache' => 'array', - ], - ], 'router' => [ 'cache' => false, ], ]; } -function expectedNotifierClass(Application $app): string -{ - return $app->config()->get('auth.drivers.notifications') === 'talkingbytes' - ? 'Infocyph\\Foundation\\Auth\\Adapter\\TalkingBytes\\TalkingBytesAuthNotifier' - : 'Infocyph\\Foundation\\Auth\\Support\\CollectingAuthNotifier'; -} - -it('boots with the expected application shape', function (): void { - $app = infbyteApp(); +it('constructs exactly the four explicit Foundation runtimes', function (): void { + $options = infbyteTestOptions(); + $cases = [ + [Foundation::web(...), RuntimeMode::Web, 'runningInWeb'], + [Foundation::cli(...), RuntimeMode::Cli, 'runningInCli'], + [Foundation::worker(...), RuntimeMode::Worker, 'runningInWorker'], + [Foundation::scheduler(...), RuntimeMode::Scheduler, 'runningInScheduler'], + ]; - expect($app->environment())->toBeString()->not->toBeEmpty() - ->and($app->runningInWeb())->toBeTrue(); + foreach ($cases as [$factory, $mode, $predicate]) { + /** @var callable(array):Application $factory */ + $app = $factory($options); - $paths = $app->paths()->all(); + expect($app)->toBeInstanceOf(Application::class) + ->and($app->runtimeMode())->toBe($mode) + ->and($app->{$predicate}())->toBeTrue() + ->and($app->booted())->toBeFalse() + ->and($app->environment())->toBe('testing') + ->and($app->basePath())->toBe(dirname(__DIR__, 2)); + } - expect($paths)->toHaveKey('providers'); - expect(is_file($paths['providers']))->toBeTrue(); - expect(is_dir($paths['storage']))->toBeTrue(); + expect(method_exists(Foundation::class, 'console'))->toBeFalse(); }); -it('keeps the console bootstrap outside the web boot graph', function (): void { - $app = Foundation::console(infbyteTestOptions()); - - expect($app)->toBeInstanceOf(Application::class) - ->and($app->runningInConsole())->toBeTrue() - ->and($app->container()->has(RouteFileLoader::class))->toBeFalse() - ->and($app->container()->has(HttpKernel::class))->toBeFalse(); - - $app->boot(); +it('keeps HTTP unavailable outside the web runtime', function (): void { + $app = Foundation::cli(infbyteTestOptions())->boot(); - expect($app->container()->has(RouteFileLoader::class))->toBeFalse() - ->and($app->container()->has(HttpKernel::class))->toBeFalse() + expect($app->runningInCli())->toBeTrue() + ->and($app->booted())->toBeTrue() ->and(fn() => $app->http()) - ->toThrow(LogicException::class, 'HTTP kernel is unavailable'); + ->toThrow(LogicException::class, 'The HTTP kernel is unavailable in the cli runtime.'); }); -it('defines console commands through an explicit command route map', function (): void { - $commands = require dirname(__DIR__, 2) . '/routes/console.php'; +it('resolves only the narrow Foundation application core directly', function (): void { + $app = Foundation::web(infbyteTestOptions())->boot(); + + expect($app->make(Application::class))->toBe($app) + ->and($app->config())->toBeInstanceOf(ConfigRepository::class) + ->and($app->paths())->toBeInstanceOf(PathManager::class) + ->and($app->execution())->toBeInstanceOf(ExecutionScope::class) + ->and($app->http())->toBeInstanceOf(HttpKernel::class) + ->and($app->booted())->toBeTrue(); + + foreach ([ + 'auth', + 'authManager', + 'cache', + 'database', + 'filesystem', + 'ids', + 'notifications', + 'router', + 'testing', + 'validation', + ] as $retiredConvenienceMethod) { + expect(method_exists($app, $retiredConvenienceMethod))->toBeFalse(); + } +}); - expect($commands)->toBeArray() - ->and($commands)->toBe([]); +it('defines application commands through the explicit command route file', function (): void { + $commands = require dirname(__DIR__, 2) . '/routes/console.php'; - foreach ($commands as $command) { - expect(is_string($command) && is_a($command, CommandContract::class, true))->toBeTrue(); - } + expect($commands)->toBeArray()->toBe([]); }); -it('keeps Foundation system commands out of application Composer scripts', function (): void { +it('keeps Foundation system commands out of application Composer script keys', function (): void { $composer = json_decode( - file_get_contents(dirname(__DIR__, 2) . '/composer.json'), + (string) file_get_contents(dirname(__DIR__, 2) . '/composer.json'), true, flags: JSON_THROW_ON_ERROR, ); $scripts = $composer['scripts'] ?? []; - expect($scripts)->toBeArray() - ->and(array_intersect( - array_keys($scripts), - array_keys(FoundationConsole::commands([])), - ))->toBe([]); -}); - -it('registers the core services', function (): void { - $app = infbyteApp()->boot(); - - expect($app->auth())->toBeObject(); - expect($app->authManager())->toBeObject(); - expect($app->authActions())->toBeObject(); - expect($app->http())->toBeObject(); - expect($app->ids())->toBeObject(); - expect($app->has(CacheManager::class))->toBeFalse(); - expect($app->has(DatabaseManager::class))->toBeFalse(); - expect($app->has(FilesystemManager::class))->toBeFalse(); - expect($app->has(NotificationManager::class))->toBeFalse(); - expect($app->has(ValidationManager::class))->toBeFalse(); -}); - -it('serves the health and JSON routes', function (): void { - $app = infbyteApp()->boot(); - $router = $app->make(RouterManager::class); - $registered = []; - - foreach ($router->routes() as $route) { - $registered[$route->getMethod() . ' ' . $route->getPath()] = $route->getHandler(); + expect($scripts)->toBeArray(); + + foreach ([ + 'app:ready', + 'config:cache', + 'db:monitor', + 'module:list', + 'optimize', + 'route:cache', + 'schedule:run', + 'worker:run', + ] as $systemCommand) { + expect(array_key_exists($systemCommand, $scripts))->toBeFalse(); } - - expect(array_keys($registered))->toBe(['GET /api/health', 'GET /json']); - expect($registered['GET /api/health'])->toBeInstanceOf(Closure::class) - ->and($registered['GET /json'])->toBeInstanceOf(Closure::class); - - $http = $app->testing()->http(); - $health = $http->get('/api/health') - ->assertStatus(200) - ->assertHeader('Content-Type') - ->assertJson(['status' => 'ok']); - $json = $http->get('/json') - ->assertStatus(200) - ->assertHeader('Content-Type') - ->json(); - - expect($health->json())->toBe(['status' => 'ok']) - ->and($json)->toHaveKey('memory') - ->and($json['memory'])->toBeInt(); }); -it('uses the self-contained auth notifier without optional modules', function (): void { - $app = infbyteApp()->boot(); +it('serves the skeleton routes through canonical Foundation web handling', function (): void { + $app = Foundation::web(infbyteTestOptions()); + + $health = $app->handle(Request::fake(method: 'GET', uri: 'http://localhost/api/health')); + $json = $app->handle(Request::fake(method: 'GET', uri: 'http://localhost/json')); - expect($app->make(AuthNotifierInterface::class)::class)->toBe(expectedNotifierClass($app)); + expect($app->booted())->toBeTrue() + ->and($health->getStatusCode())->toBe(200) + ->and((string) $health->getBody())->toContain('"status":"ok"') + ->and($json->getStatusCode())->toBe(200) + ->and((string) $json->getBody())->toContain('"memory"'); }); From ed7d72c4411ef76551b96d6351821f9a99a88665 Mon Sep 17 00:00:00 2001 From: "A. B. M. Mahmudul Hasan" Date: Tue, 25 Aug 2026 14:50:48 +0600 Subject: [PATCH 40/51] Align CLI cache tests with Foundation 2 --- tests/Feature/RouteCacheCliTest.php | 132 +++++++++++++--------------- 1 file changed, 61 insertions(+), 71 deletions(-) diff --git a/tests/Feature/RouteCacheCliTest.php b/tests/Feature/RouteCacheCliTest.php index 8eed028..07da2de 100644 --- a/tests/Feature/RouteCacheCliTest.php +++ b/tests/Feature/RouteCacheCliTest.php @@ -2,14 +2,10 @@ declare(strict_types=1); -use Composer\InstalledVersions; use App\Http\Controllers\SystemController; -use Infocyph\Foundation\Auth\AuthManager; -use Infocyph\Foundation\Database\DatabaseManager; +use Composer\InstalledVersions; use Infocyph\Foundation\Foundation; -use Infocyph\Foundation\Messaging\MessagingManager; use Infocyph\Foundation\Routing\RouteCachePath; -use Infocyph\Foundation\Session\SessionManager; use Infocyph\Webrick\Request\Request; use Infocyph\Webrick\Router\Matching\FusedMatcher; @@ -41,7 +37,7 @@ ); }); -it('builds and clears route cache through the infbyte cli wrapper', function (): void { +it('builds, consumes, and clears route cache through the infbyte cli wrapper', function (): void { $root = dirname(__DIR__, 2); $cacheFile = rtrim(sys_get_temp_dir(), DIRECTORY_SEPARATOR) . '/infbyte-route-cache-' . bin2hex(random_bytes(5)) . '.php'; @@ -54,22 +50,15 @@ '--cache=' . $cacheFile, ]); - expect($buildExitCode)->toBe(0); - expect($buildOutput)->toContain('Route cache ready at:'); - expect(is_file($cacheFile))->toBeTrue(); - expect(filesize($cacheFile))->toBeGreaterThan(0); + expect($buildExitCode)->toBe(0) + ->and($buildOutput)->toContain('Route cache ready at:') + ->and($cacheFile)->toBeFile() + ->and(filesize($cacheFile))->toBeGreaterThan(0); $matcher = FusedMatcher::make()->enableCache($cacheFile); [$cachedRoute] = $matcher->match('GET', 'localhost', '/json'); - $cachedHandler = $cachedRoute->getHandler(); - $webrickVersion = InstalledVersions::getVersion('infocyph/webrick') ?? '0.0.0'; - $usesNativeHandler = version_compare($webrickVersion, '3.3.0', '>='); - if ($usesNativeHandler) { - expect($cachedHandler)->toBe([SystemController::class, 'json']) - ->and(class_exists(\Opis\Closure\Serializer::class, false))->toBeFalse(); - } else { - expect($cachedHandler)->toBeInstanceOf(Closure::class); - } + + expect($cachedRoute->getHandler())->toBe([SystemController::class, 'json']); $runtime = rtrim(sys_get_temp_dir(), DIRECTORY_SEPARATOR) . '/infbyte-cached-runtime-' . bin2hex(random_bytes(5)); @@ -92,20 +81,12 @@ 'matcher' => 'fused', ], ]); - $repository = $app->container()->getRepository(); $response = $app->handle(Request::fake(method: 'GET', uri: 'http://localhost/json')); expect($response->getStatusCode())->toBe(200) ->and((string) $response->getBody())->toContain('memory') - ->and($repository->hasResolvedSingleton(AuthManager::class))->toBeFalse() - ->and($repository->hasResolvedSingleton(SessionManager::class))->toBeFalse() - ->and($repository->hasResolvedSingleton(DatabaseManager::class))->toBeFalse() - ->and($repository->hasResolvedSingleton(MessagingManager::class))->toBeFalse() ->and(get_included_files())->not->toContain($runtime . '/routes/missing.php'); } finally { - if (isset($app)) { - $app->container()->unset(); - } unlink($runtimeCache); rmdir(dirname($runtimeCache)); rmdir(dirname(dirname($runtimeCache))); @@ -123,9 +104,9 @@ '--cache=' . $cacheFile, ]); - expect($clearExitCode)->toBe(0); - expect($clearOutput)->toContain('Route cache cleared:'); - expect(file_exists($cacheFile))->toBeFalse(); + expect($clearExitCode)->toBe(0) + ->and($clearOutput)->toContain('Route cache cleared:') + ->and($cacheFile)->not->toBeFile(); }); it('derives the dedicated routes cache path by default', function (): void { @@ -138,7 +119,7 @@ expect(RouteCachePath::for($app->config()))->toBe($root . '/bootstrap/cache/routes/fused.php'); }); -it('builds and clears the default sharded config cache through the infbyte cli wrapper', function (): void { +it('builds and fully clears the default sharded config cache through the infbyte cli wrapper', function (): void { $root = dirname(__DIR__, 2); $cacheDirectory = rtrim(sys_get_temp_dir(), DIRECTORY_SEPARATOR) . '/infbyte-config-cache-' . bin2hex(random_bytes(5)); @@ -150,9 +131,9 @@ '--path=' . $cacheDirectory, ]); - expect($buildExitCode)->toBe(0); - expect($buildOutput)->toContain('Configuration cached (sharded):'); - expect($cacheDirectory . '/__manifest.php')->toBeFile() + expect($buildExitCode)->toBe(0) + ->and($buildOutput)->toContain('Configuration cached (sharded):') + ->and($cacheDirectory . '/__manifest.php')->toBeFile() ->and($cacheDirectory . '/app.php')->toBeFile() ->and($cacheDirectory . '/__flat.php')->not->toBeFile() ->and($cacheDirectory . '/__compiled.php')->not->toBeFile(); @@ -164,16 +145,12 @@ '--path=' . $cacheDirectory, ]); - expect($clearExitCode)->toBe(0); - expect($clearOutput)->toContain('Configuration cache cleared:'); - expect($cacheDirectory . '/__manifest.php')->not->toBeFile() - ->and($cacheDirectory . '/app.php')->not->toBeFile() - ->and($cacheDirectory . '/__flat.php')->not->toBeFile(); - - rmdir($cacheDirectory); + expect($clearExitCode)->toBe(0) + ->and($clearOutput)->toContain('Configuration cache cleared:') + ->and($cacheDirectory)->not->toBeDirectory(); }); -it('can explicitly build a single config cache through the infbyte cli wrapper', function (): void { +it('can explicitly build and fully clear a single config cache', function (): void { $root = dirname(__DIR__, 2); $cacheDirectory = rtrim(sys_get_temp_dir(), DIRECTORY_SEPARATOR) . '/infbyte-single-config-cache-' . bin2hex(random_bytes(5)); @@ -186,9 +163,9 @@ '--path=' . $cacheDirectory, ]); - expect($exitCode)->toBe(0); - expect($output)->toContain('Configuration cached (single):'); - expect($cacheDirectory . '/__manifest.php')->toBeFile() + expect($exitCode)->toBe(0) + ->and($output)->toContain('Configuration cached (single):') + ->and($cacheDirectory . '/__manifest.php')->toBeFile() ->and($cacheDirectory . '/app.php')->not->toBeFile() ->and($cacheDirectory . '/__flat.php')->not->toBeFile(); @@ -199,8 +176,8 @@ '--path=' . $cacheDirectory, ]); - expect($clearExitCode)->toBe(0); - rmdir($cacheDirectory); + expect($clearExitCode)->toBe(0) + ->and($cacheDirectory)->not->toBeDirectory(); }); it('builds and clears compiled command metadata through the infbyte cli wrapper', function (): void { @@ -216,11 +193,11 @@ '--path=' . $manifest, ]); - expect($buildExitCode)->toBe(0); - expect($buildOutput)->toContain('Command manifest ready at:'); - expect($manifest)->toBeFile(); - expect(glob($cacheDirectory . '/commands-*.php') ?: [])->not->toBeEmpty(); - expect($manifest . '.d')->not->toBeDirectory(); + expect($buildExitCode)->toBe(0) + ->and($buildOutput)->toContain('Command manifest ready at:') + ->and($manifest)->toBeFile() + ->and(glob($cacheDirectory . '/commands-*.php') ?: [])->not->toBeEmpty() + ->and($manifest . '.d')->not->toBeDirectory(); [$clearExitCode, $clearOutput] = runInfbyteCommand([ PHP_BINARY, @@ -229,16 +206,18 @@ '--path=' . $manifest, ]); - expect($clearExitCode)->toBe(0); - expect($clearOutput)->toContain('Command manifest cleared:'); - expect($manifest)->not->toBeFile(); - expect(glob($cacheDirectory . '/commands-*.php') ?: [])->toBeEmpty(); - expect($manifest . '.d')->not->toBeDirectory(); + expect($clearExitCode)->toBe(0) + ->and($clearOutput)->toContain('Command manifest cleared:') + ->and($manifest)->not->toBeFile() + ->and(glob($cacheDirectory . '/commands-*.php') ?: [])->toBeEmpty() + ->and($manifest . '.d')->not->toBeDirectory(); - rmdir($cacheDirectory); + if (is_dir($cacheDirectory)) { + rmdir($cacheDirectory); + } }); -it('reports readiness and optional module state through the infbyte cli', function (): void { +it('reports readiness and canonical module state through the infbyte cli', function (): void { $root = dirname(__DIR__, 2); [$readinessExitCode, $readinessOutput] = runInfbyteCommand([ @@ -254,9 +233,9 @@ '--json=true', ]); - expect($readinessExitCode)->toBe(2); - expect(json_decode($readinessOutput, true, flags: JSON_THROW_ON_ERROR)['production_ready'])->toBeFalse(); - expect($modulesExitCode)->toBe(0); + expect($readinessExitCode)->toBe(2) + ->and(json_decode($readinessOutput, true, flags: JSON_THROW_ON_ERROR)['production_ready'])->toBeFalse() + ->and($modulesExitCode)->toBe(0); $modules = array_column( json_decode($modulesOutput, true, flags: JSON_THROW_ON_ERROR)['modules'], @@ -264,16 +243,27 @@ 'name', ); - expect($modules['db']['installed'])->toBeFalse() - ->and($modules['cache']['installed'])->toBeFalse() - ->and($modules['filesystem']['installed'])->toBeFalse() - ->and($modules['logging']['installed'])->toBeTrue() - ->and($modules['messaging']['installed'])->toBeTrue() - ->and($modules['resources']['installed'])->toBeTrue() - ->and($modules['session']['installed'])->toBeTrue(); + expect($modules)->toHaveKeys([ + 'auth', + 'cache', + 'communication', + 'database', + 'filesystem', + 'logging', + 'messaging', + 'operations', + 'resources', + 'security', + 'session', + 'validation', + ])->not->toHaveKey('db'); + + foreach (['logging', 'operations', 'resources', 'session'] as $builtIn) { + expect($modules[$builtIn]['installed'])->toBeTrue(); + } }); -it('explains how to install a service owned by an absent optional module', function (): void { +it('explains the canonical module installation path for absent database support', function (): void { $root = dirname(__DIR__, 2); [$exitCode, $output] = runInfbyteCommand([ @@ -285,7 +275,7 @@ expect($exitCode)->toBe(2) ->and($output)->toContain('requires infocyph/dblayer') - ->and($output)->toContain('php infbyte module:install db'); + ->and($output)->toContain('php infbyte module:install database'); }); /** From cd779ca114c2175fe4c092122b350b3d39a1cb4d Mon Sep 17 00:00:00 2001 From: "A. B. M. Mahmudul Hasan" Date: Tue, 25 Aug 2026 14:55:32 +0600 Subject: [PATCH 41/51] Make runtime response tests format-independent --- tests/Feature/FrameworkRuntimeTest.php | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/tests/Feature/FrameworkRuntimeTest.php b/tests/Feature/FrameworkRuntimeTest.php index ba974b7..04d2bda 100644 --- a/tests/Feature/FrameworkRuntimeTest.php +++ b/tests/Feature/FrameworkRuntimeTest.php @@ -140,10 +140,13 @@ function infbyteTestOptions(): array $health = $app->handle(Request::fake(method: 'GET', uri: 'http://localhost/api/health')); $json = $app->handle(Request::fake(method: 'GET', uri: 'http://localhost/json')); + $healthPayload = json_decode((string) $health->getBody(), true, flags: JSON_THROW_ON_ERROR); + $jsonPayload = json_decode((string) $json->getBody(), true, flags: JSON_THROW_ON_ERROR); expect($app->booted())->toBeTrue() ->and($health->getStatusCode())->toBe(200) - ->and((string) $health->getBody())->toContain('"status":"ok"') + ->and($healthPayload)->toBe(['status' => 'ok']) ->and($json->getStatusCode())->toBe(200) - ->and((string) $json->getBody())->toContain('"memory"'); + ->and($jsonPayload)->toHaveKey('memory') + ->and($jsonPayload['memory'])->toBeInt(); }); From 6543ebc007b6f32bcea540741697c64c947f52d5 Mon Sep 17 00:00:00 2001 From: "A. B. M. Mahmudul Hasan" Date: Tue, 25 Aug 2026 14:57:02 +0600 Subject: [PATCH 42/51] Harden CLI cache integration tests --- tests/Feature/RouteCacheCliTest.php | 37 ++++++++++++++++++++++------- 1 file changed, 29 insertions(+), 8 deletions(-) diff --git a/tests/Feature/RouteCacheCliTest.php b/tests/Feature/RouteCacheCliTest.php index 07da2de..b202017 100644 --- a/tests/Feature/RouteCacheCliTest.php +++ b/tests/Feature/RouteCacheCliTest.php @@ -82,18 +82,14 @@ ], ]); $response = $app->handle(Request::fake(method: 'GET', uri: 'http://localhost/json')); + $payload = json_decode((string) $response->getBody(), true, flags: JSON_THROW_ON_ERROR); expect($response->getStatusCode())->toBe(200) - ->and((string) $response->getBody())->toContain('memory') + ->and($payload)->toHaveKey('memory') + ->and($payload['memory'])->toBeInt() ->and(get_included_files())->not->toContain($runtime . '/routes/missing.php'); } finally { - unlink($runtimeCache); - rmdir(dirname($runtimeCache)); - rmdir(dirname(dirname($runtimeCache))); - rmdir(dirname(dirname(dirname($runtimeCache)))); - unlink($runtime . '/routes/missing.php'); - rmdir($runtime . '/routes'); - rmdir($runtime); + removeInfbyteTestDirectory($runtime); } [$clearExitCode, $clearOutput] = runInfbyteCommand([ @@ -306,3 +302,28 @@ function runInfbyteCommand(array $arguments, array $environment = []): array return [$exitCode, implode("\n", $output)]; } + +function removeInfbyteTestDirectory(string $directory): void +{ + if (!is_dir($directory)) { + return; + } + + $entries = new RecursiveIteratorIterator( + new RecursiveDirectoryIterator($directory, FilesystemIterator::SKIP_DOTS), + RecursiveIteratorIterator::CHILD_FIRST, + ); + + foreach ($entries as $entry) { + $path = $entry->getPathname(); + + if ($entry->isLink() || $entry->isFile()) { + unlink($path); + continue; + } + + rmdir($path); + } + + rmdir($directory); +} From 0e70cc177b65d2dc8148057ffbb1cef53586cf6d Mon Sep 17 00:00:00 2001 From: "A. B. M. Mahmudul Hasan" Date: Tue, 25 Aug 2026 14:58:22 +0600 Subject: [PATCH 43/51] Align CI with current PHPForge workflow inputs --- .github/workflows/security-standards.yml | 18 ------------------ 1 file changed, 18 deletions(-) diff --git a/.github/workflows/security-standards.yml b/.github/workflows/security-standards.yml index f412cfc..d186dfb 100644 --- a/.github/workflows/security-standards.yml +++ b/.github/workflows/security-standards.yml @@ -19,27 +19,9 @@ jobs: php_versions: '["8.4","8.5"]' dependency_versions: '["prefer-lowest","prefer-stable"]' php_extensions: "pcntl" - composer_flags: "" phpstan_memory_limit: "1G" - psalm_threads: "1" run_analysis: true run_svg_report: true fail_on_skipped_tests: true run_clean_install: true - benchmark_composer_script: "" - benchmark_result_file: "" - benchmark_baseline_file: "" - benchmark_max_regression_percent: 2 - benchmark_stable_environment: false - enable_redis_service: false - enable_valkey_service: false - enable_memcached_service: false - enable_postgres_service: false - enable_mysql_service: false - enable_scylladb_service: false - enable_elasticsearch_service: false - enable_mongodb_service: false - service_db_name: "infbyte" - service_db_user: "infbyte" - service_db_password: "infbyte" artifact_retention_days: 61 From 58e134865b51be1f0122bdbd6474e9507e2aa949 Mon Sep 17 00:00:00 2001 From: "A. B. M. Mahmudul Hasan" Date: Tue, 25 Aug 2026 15:03:03 +0600 Subject: [PATCH 44/51] Validate Foundation 2 integration before stable release --- .github/workflows/security-standards.yml | 76 +++++++++++++++++++----- 1 file changed, 60 insertions(+), 16 deletions(-) diff --git a/.github/workflows/security-standards.yml b/.github/workflows/security-standards.yml index d186dfb..f956be5 100644 --- a/.github/workflows/security-standards.yml +++ b/.github/workflows/security-standards.yml @@ -9,19 +9,63 @@ on: branches: [ "main", "master", "develop", "development" ] jobs: - phpforge: - uses: infocyph/phpforge/.github/workflows/security-standards.yml@main - permissions: - security-events: write - actions: read - contents: read - with: - php_versions: '["8.4","8.5"]' - dependency_versions: '["prefer-lowest","prefer-stable"]' - php_extensions: "pcntl" - phpstan_memory_limit: "1G" - run_analysis: true - run_svg_report: true - fail_on_skipped_tests: true - run_clean_install: true - artifact_retention_days: 61 + integration-qa: + name: "Foundation 2 integration - PHP ${{ matrix.php-version }} - ${{ matrix.dependency-version }}" + runs-on: ubuntu-latest + strategy: + fail-fast: false + matrix: + php-version: ["8.4", "8.5"] + dependency-version: ["prefer-lowest", "prefer-stable"] + env: + XDEBUG_MODE: off + IC_PHPSTAN_MEMORY_LIMIT: "1G" + IC_PEST_FAIL_ON_SKIPPED: "true" + IC_TEST_TASK_TIMEOUT: "300" + steps: + - uses: actions/checkout@v7 + + - name: Setup PHP + uses: shivammathur/setup-php@v2 + with: + php-version: ${{ matrix.php-version }} + tools: composer:v2 + extensions: pcntl + coverage: none + + - name: Validate and resolve integration dependencies + shell: bash + run: | + composer validate --strict + composer update --no-interaction --prefer-dist --no-progress --${{ matrix.dependency-version }} + + - name: Run PHPForge quality suite + shell: bash + run: | + if [ "${{ matrix.dependency-version }}" = "prefer-lowest" ]; then + composer ic:ci --prefer-lowest + else + composer ic:ci + fi + + clean-install: + name: "Foundation 2 integration - clean install" + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v7 + + - name: Setup PHP + uses: shivammathur/setup-php@v2 + with: + php-version: "8.5" + tools: composer:v2 + extensions: pcntl + coverage: none + + - name: Validate production install + shell: bash + run: | + composer validate --strict + composer update --no-dev --no-interaction --prefer-dist --no-progress --classmap-authoritative + composer check-platform-reqs --no-dev + php -r 'require "vendor/autoload.php";' From 451fee20acf18fb107b67e96170ff39ee9453f31 Mon Sep 17 00:00:00 2001 From: "A. B. M. Mahmudul Hasan" Date: Tue, 25 Aug 2026 15:07:32 +0600 Subject: [PATCH 45/51] Use canonical web handling in example test --- tests/Feature/ExampleTest.php | 12 +++++------- 1 file changed, 5 insertions(+), 7 deletions(-) diff --git a/tests/Feature/ExampleTest.php b/tests/Feature/ExampleTest.php index 1e8c52b..ac190ff 100644 --- a/tests/Feature/ExampleTest.php +++ b/tests/Feature/ExampleTest.php @@ -3,17 +3,15 @@ declare(strict_types=1); use Infocyph\Foundation\Application\Application; +use Infocyph\Webrick\Request\Request; it('serves the application health endpoint', function (): void { /** @var Application $app */ $app = require dirname(__DIR__, 2) . '/bootstrap/app.php'; - $app->boot(); - $response = $app->testing() - ->http() - ->get('/api/health') - ->assertStatus(200) - ->assertJson(['status' => 'ok']); + $response = $app->handle(Request::fake(method: 'GET', uri: 'http://localhost/api/health')); + $payload = json_decode((string) $response->getBody(), true, flags: JSON_THROW_ON_ERROR); - expect($response->json())->toBe(['status' => 'ok']); + expect($response->getStatusCode())->toBe(200) + ->and($payload)->toBe(['status' => 'ok']); }); From 04ebb1e87ba96acbe371794ac12a792db697bf28 Mon Sep 17 00:00:00 2001 From: "A. B. M. Mahmudul Hasan" Date: Tue, 25 Aug 2026 15:08:25 +0600 Subject: [PATCH 46/51] Align distribution cache exclusions with Foundation 2 --- .gitattributes | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/.gitattributes b/.gitattributes index 8d4d429..c28c300 100644 --- a/.gitattributes +++ b/.gitattributes @@ -33,12 +33,10 @@ /app/Services export-ignore /app/Support export-ignore /bin export-ignore -/bootstrap/cache/config/*.php export-ignore -/bootstrap/cache/console/*.php export-ignore -/bootstrap/cache/container.php export-ignore -/bootstrap/cache/modules.php export-ignore -/bootstrap/cache/optimize.php export-ignore -/bootstrap/cache/routes/*.php export-ignore +/bootstrap/cache/*.php export-ignore +/bootstrap/cache/config export-ignore +/bootstrap/cache/container export-ignore +/bootstrap/cache/routes export-ignore /database export-ignore /resources export-ignore /storage/app export-ignore From 6ce0246c588c69b5cc576fc46dc45edae67ef835 Mon Sep 17 00:00:00 2001 From: "A. B. M. Mahmudul Hasan" Date: Tue, 25 Aug 2026 15:08:59 +0600 Subject: [PATCH 47/51] Align skeleton distribution tests with Foundation 2 artifacts --- tests/Feature/SkeletonDistributionTest.php | 37 +++++++++++++++------- 1 file changed, 25 insertions(+), 12 deletions(-) diff --git a/tests/Feature/SkeletonDistributionTest.php b/tests/Feature/SkeletonDistributionTest.php index 5da994b..ec78ab0 100644 --- a/tests/Feature/SkeletonDistributionTest.php +++ b/tests/Feature/SkeletonDistributionTest.php @@ -13,7 +13,6 @@ expect($config)->toBe([ 'app.php', 'auth.php', - 'ids.php', 'router.php', ]); }); @@ -26,7 +25,11 @@ ->and($attributes)->not->toContain("/tests export-ignore\n") ->and($attributes)->toContain('/tests/Feature/FrameworkRuntimeTest.php export-ignore') ->and($attributes)->toContain('/tests/Feature/RouteCacheCliTest.php export-ignore') - ->and($attributes)->toContain('/tests/Feature/SkeletonDistributionTest.php export-ignore'); + ->and($attributes)->toContain('/tests/Feature/SkeletonDistributionTest.php export-ignore') + ->and($attributes)->toContain('/bootstrap/cache/*.php export-ignore') + ->and($attributes)->toContain('/bootstrap/cache/config export-ignore') + ->and($attributes)->toContain('/bootstrap/cache/container export-ignore') + ->and($attributes)->toContain('/bootstrap/cache/routes export-ignore'); }); it('builds a clean create-project archive and provisions its environment', function (): void { @@ -79,9 +82,10 @@ expect($project . '/composer.json')->toBeFile() ->and($project . '/bootstrap/install.php')->not->toBeFile() - ->and($project . '/bootstrap/cache/config/.gitignore')->toBeFile() - ->and($project . '/bootstrap/cache/console/.gitignore')->toBeFile() - ->and($project . '/bootstrap/cache/routes/.gitignore')->toBeFile() + ->and($project . '/bootstrap/cache/.gitignore')->toBeFile() + ->and($project . '/bootstrap/cache/config')->not->toBeDirectory() + ->and($project . '/bootstrap/cache/container')->not->toBeDirectory() + ->and($project . '/bootstrap/cache/routes')->not->toBeDirectory() ->and($project . '/storage/cache/.gitignore')->toBeFile() ->and($project . '/storage/logs/.gitignore')->toBeFile() ->and($project . '/storage/sessions/.gitignore')->toBeFile() @@ -102,7 +106,6 @@ ->and($project . '/tests/Feature/RouteCacheCliTest.php')->not->toBeFile() ->and($project . '/tests/Feature/SkeletonDistributionTest.php')->not->toBeFile() ->and($project . '/vendor')->not->toBeDirectory() - ->and($project . '/bootstrap/cache/config/__manifest.php')->not->toBeFile() ->and($project . '/database')->not->toBeDirectory() ->and($cachedPhpFiles)->toBe([]) ->and($exportedComposer['require']['infocyph/foundation'] ?? null) @@ -151,8 +154,13 @@ expect($deployExitCode)->toBe(0, implode("\n", $deployOutput)) ->and($project . '/bootstrap/cache/config/__manifest.php')->toBeFile() ->and($project . '/bootstrap/cache/routes/fused.php')->toBeFile() - ->and($project . '/bootstrap/cache/console/commands.php')->toBeFile() - ->and($project . '/bootstrap/cache/modules.php')->toBeFile(); + ->and($project . '/bootstrap/cache/commands.php')->toBeFile() + ->and($project . '/bootstrap/cache/schedule.php')->toBeFile() + ->and($project . '/bootstrap/cache/optimize.php')->toBeFile() + ->and($project . '/bootstrap/cache/container/web.php')->toBeFile() + ->and($project . '/bootstrap/cache/container/cli.php')->toBeFile() + ->and($project . '/bootstrap/cache/container/worker.php')->toBeFile() + ->and($project . '/bootstrap/cache/container/scheduler.php')->toBeFile(); $clearOutput = []; $clearExitCode = 0; @@ -163,10 +171,15 @@ ), $clearOutput, $clearExitCode); expect($clearExitCode)->toBe(0, implode("\n", $clearOutput)) - ->and($project . '/bootstrap/cache/config/__manifest.php')->not->toBeFile() + ->and($project . '/bootstrap/cache/config')->not->toBeDirectory() ->and($project . '/bootstrap/cache/routes/fused.php')->not->toBeFile() - ->and($project . '/bootstrap/cache/console/commands.php')->not->toBeFile() - ->and($project . '/bootstrap/cache/modules.php')->not->toBeFile(); + ->and($project . '/bootstrap/cache/commands.php')->not->toBeFile() + ->and($project . '/bootstrap/cache/schedule.php')->not->toBeFile() + ->and($project . '/bootstrap/cache/optimize.php')->not->toBeFile() + ->and($project . '/bootstrap/cache/container/web.php')->not->toBeFile() + ->and($project . '/bootstrap/cache/container/cli.php')->not->toBeFile() + ->and($project . '/bootstrap/cache/container/worker.php')->not->toBeFile() + ->and($project . '/bootstrap/cache/container/scheduler.php')->not->toBeFile(); } finally { removeInfbyteDistributionFixture($fixture); } @@ -184,7 +197,7 @@ function removeInfbyteDistributionFixture(string $directory): void ); foreach ($files as $file) { - if ($file->isDir()) { + if ($file->isDir() && !$file->isLink()) { rmdir($file->getPathname()); } else { unlink($file->getPathname()); From ab011a48d08a26ed362e5b53278e249144fbe227 Mon Sep 17 00:00:00 2001 From: "A. B. M. Mahmudul Hasan" Date: Tue, 25 Aug 2026 15:10:41 +0600 Subject: [PATCH 48/51] Align CLI integration tests with Foundation 2 commands --- tests/Feature/RouteCacheCliTest.php | 450 +++++++++++++++------------- 1 file changed, 247 insertions(+), 203 deletions(-) diff --git a/tests/Feature/RouteCacheCliTest.php b/tests/Feature/RouteCacheCliTest.php index b202017..58717c7 100644 --- a/tests/Feature/RouteCacheCliTest.php +++ b/tests/Feature/RouteCacheCliTest.php @@ -9,75 +9,57 @@ use Infocyph\Webrick\Request\Request; use Infocyph\Webrick\Router\Matching\FusedMatcher; -it('uses the environment application name and reports the Foundation runtime version', function (): void { - $root = dirname(__DIR__, 2); - [$exitCode, $output] = runInfbyteCommand([ - PHP_BINARY, - $root . '/infbyte', - '--version', - ], ['APP_NAME' => 'Acme Console']); - - expect($exitCode)->toBe(0) - ->and($output)->toBe( - 'Acme Console ' . (InstalledVersions::getPrettyVersion('infocyph/foundation') ?? 'dev-main'), - ); -}); +it('keeps the Infbyte CLI identity independent of the application display name', function (): void { + $fixture = createInfbyteCliFixture(); -it('falls back to infbyte when the environment application name is empty', function (): void { - $root = dirname(__DIR__, 2); - [$exitCode, $output] = runInfbyteCommand([ - PHP_BINARY, - $root . '/infbyte', - '--version', - ], ['APP_NAME' => '']); - - expect($exitCode)->toBe(0) - ->and($output)->toBe( - 'infbyte ' . (InstalledVersions::getPrettyVersion('infocyph/foundation') ?? 'dev-main'), - ); + try { + [$exitCode, $output] = runInfbyteCommand([ + PHP_BINARY, + $fixture . '/infbyte', + '--version', + ], ['APP_NAME' => 'Acme Console']); + + expect($exitCode)->toBe(0) + ->and($output)->toBe( + 'Infbyte ' . (InstalledVersions::getPrettyVersion('infocyph/foundation') ?? 'dev-main'), + ); + } finally { + removeInfbyteTestDirectory($fixture); + } }); it('builds, consumes, and clears route cache through the infbyte cli wrapper', function (): void { - $root = dirname(__DIR__, 2); - $cacheFile = rtrim(sys_get_temp_dir(), DIRECTORY_SEPARATOR) - . '/infbyte-route-cache-' . bin2hex(random_bytes(5)) . '.php'; - - [$buildExitCode, $buildOutput] = runInfbyteCommand([ - PHP_BINARY, - $root . '/infbyte', - 'route:cache', - '--matcher=fused', - '--cache=' . $cacheFile, - ]); + $fixture = createInfbyteCliFixture(); + $cacheFile = $fixture . '/bootstrap/cache/routes/fused.php'; + + try { + [$buildExitCode, $buildOutput] = runInfbyteCommand([ + PHP_BINARY, + $fixture . '/infbyte', + 'route:cache', + ]); - expect($buildExitCode)->toBe(0) - ->and($buildOutput)->toContain('Route cache ready at:') - ->and($cacheFile)->toBeFile() - ->and(filesize($cacheFile))->toBeGreaterThan(0); + expect($buildExitCode)->toBe(0) + ->and($buildOutput)->toContain('Routes cached using fused matcher at ') + ->and($cacheFile)->toBeFile() + ->and(filesize($cacheFile))->toBeGreaterThan(0); - $matcher = FusedMatcher::make()->enableCache($cacheFile); - [$cachedRoute] = $matcher->match('GET', 'localhost', '/json'); + $matcher = FusedMatcher::make()->enableCache($cacheFile); + [$cachedRoute] = $matcher->match('GET', 'localhost', '/json'); - expect($cachedRoute->getHandler())->toBe([SystemController::class, 'json']); + expect($cachedRoute->getHandler())->toBe([SystemController::class, 'json']); - $runtime = rtrim(sys_get_temp_dir(), DIRECTORY_SEPARATOR) - . '/infbyte-cached-runtime-' . bin2hex(random_bytes(5)); - $runtimeCache = $runtime . '/bootstrap/cache/routes/fused.php'; - mkdir(dirname($runtimeCache), 0775, true); - mkdir($runtime . '/routes', 0775, true); - copy($cacheFile, $runtimeCache); - file_put_contents( - $runtime . '/routes/missing.php', - " $runtime, + 'base_path' => $fixture, '_config_cache' => false, 'router' => [ 'cache' => true, - 'files' => ['missing.php'], + 'files' => ['api.php'], 'matcher' => 'fused', ], ]); @@ -87,22 +69,20 @@ expect($response->getStatusCode())->toBe(200) ->and($payload)->toHaveKey('memory') ->and($payload['memory'])->toBeInt() - ->and(get_included_files())->not->toContain($runtime . '/routes/missing.php'); - } finally { - removeInfbyteTestDirectory($runtime); - } + ->and(get_included_files())->not->toContain($fixture . '/routes/api.php'); - [$clearExitCode, $clearOutput] = runInfbyteCommand([ - PHP_BINARY, - $root . '/infbyte', - 'route:clear', - '--matcher=fused', - '--cache=' . $cacheFile, - ]); + [$clearExitCode, $clearOutput] = runInfbyteCommand([ + PHP_BINARY, + $fixture . '/infbyte', + 'route:clear', + ]); - expect($clearExitCode)->toBe(0) - ->and($clearOutput)->toContain('Route cache cleared:') - ->and($cacheFile)->not->toBeFile(); + expect($clearExitCode)->toBe(0) + ->and($clearOutput)->toContain('Route cache cleared.') + ->and($cacheFile)->not->toBeFile(); + } finally { + removeInfbyteTestDirectory($fixture); + } }); it('derives the dedicated routes cache path by default', function (): void { @@ -116,162 +96,172 @@ }); it('builds and fully clears the default sharded config cache through the infbyte cli wrapper', function (): void { - $root = dirname(__DIR__, 2); - $cacheDirectory = rtrim(sys_get_temp_dir(), DIRECTORY_SEPARATOR) - . '/infbyte-config-cache-' . bin2hex(random_bytes(5)); - - [$buildExitCode, $buildOutput] = runInfbyteCommand([ - PHP_BINARY, - $root . '/infbyte', - 'config:cache', - '--path=' . $cacheDirectory, - ]); + $fixture = createInfbyteCliFixture(); + $cacheDirectory = $fixture . '/bootstrap/cache/config'; - expect($buildExitCode)->toBe(0) - ->and($buildOutput)->toContain('Configuration cached (sharded):') - ->and($cacheDirectory . '/__manifest.php')->toBeFile() - ->and($cacheDirectory . '/app.php')->toBeFile() - ->and($cacheDirectory . '/__flat.php')->not->toBeFile() - ->and($cacheDirectory . '/__compiled.php')->not->toBeFile(); - - [$clearExitCode, $clearOutput] = runInfbyteCommand([ - PHP_BINARY, - $root . '/infbyte', - 'config:clear', - '--path=' . $cacheDirectory, - ]); + try { + [$buildExitCode, $buildOutput] = runInfbyteCommand([ + PHP_BINARY, + $fixture . '/infbyte', + 'config:cache', + ]); - expect($clearExitCode)->toBe(0) - ->and($clearOutput)->toContain('Configuration cache cleared:') - ->and($cacheDirectory)->not->toBeDirectory(); + expect($buildExitCode)->toBe(0) + ->and($buildOutput)->toContain('Configuration cached using sharded.') + ->and($cacheDirectory . '/__manifest.php')->toBeFile() + ->and($cacheDirectory . '/app.php')->toBeFile() + ->and($cacheDirectory . '/__flat.php')->toBeFile(); + + [$clearExitCode, $clearOutput] = runInfbyteCommand([ + PHP_BINARY, + $fixture . '/infbyte', + 'config:clear', + ]); + + expect($clearExitCode)->toBe(0) + ->and($clearOutput)->toContain('Configuration cache cleared.') + ->and($cacheDirectory)->not->toBeDirectory(); + } finally { + removeInfbyteTestDirectory($fixture); + } }); -it('can explicitly build and fully clear a single config cache', function (): void { - $root = dirname(__DIR__, 2); - $cacheDirectory = rtrim(sys_get_temp_dir(), DIRECTORY_SEPARATOR) - . '/infbyte-single-config-cache-' . bin2hex(random_bytes(5)); - - [$exitCode, $output] = runInfbyteCommand([ - PHP_BINARY, - $root . '/infbyte', - 'config:cache', - '--type=single', - '--path=' . $cacheDirectory, - ]); +it('can select and fully clear the single config cache through application configuration', function (): void { + $fixture = createInfbyteCliFixture(); + $cacheDirectory = $fixture . '/bootstrap/cache/config'; - expect($exitCode)->toBe(0) - ->and($output)->toContain('Configuration cached (single):') - ->and($cacheDirectory . '/__manifest.php')->toBeFile() - ->and($cacheDirectory . '/app.php')->not->toBeFile() - ->and($cacheDirectory . '/__flat.php')->not->toBeFile(); - - [$clearExitCode] = runInfbyteCommand([ - PHP_BINARY, - $root . '/infbyte', - 'config:clear', - '--path=' . $cacheDirectory, - ]); + try { + [$exitCode, $output] = runInfbyteCommand([ + PHP_BINARY, + $fixture . '/infbyte', + 'config:cache', + ], ['APP_CONFIG_CACHE_TYPE' => 'single']); + + expect($exitCode)->toBe(0) + ->and($output)->toContain('Configuration cached using single.') + ->and($cacheDirectory . '/__manifest.php')->toBeFile() + ->and($cacheDirectory . '/app.php')->not->toBeFile() + ->and($cacheDirectory . '/__flat.php')->not->toBeFile(); + + [$clearExitCode] = runInfbyteCommand([ + PHP_BINARY, + $fixture . '/infbyte', + 'config:clear', + ]); - expect($clearExitCode)->toBe(0) - ->and($cacheDirectory)->not->toBeDirectory(); + expect($clearExitCode)->toBe(0) + ->and($cacheDirectory)->not->toBeDirectory(); + } finally { + removeInfbyteTestDirectory($fixture); + } }); it('builds and clears compiled command metadata through the infbyte cli wrapper', function (): void { - $root = dirname(__DIR__, 2); - $cacheDirectory = rtrim(sys_get_temp_dir(), DIRECTORY_SEPARATOR) - . '/infbyte-command-cache-' . bin2hex(random_bytes(5)); - $manifest = $cacheDirectory . '/commands.php'; - - [$buildExitCode, $buildOutput] = runInfbyteCommand([ - PHP_BINARY, - $root . '/infbyte', - 'command:cache', - '--path=' . $manifest, - ]); + $fixture = createInfbyteCliFixture(); + $manifest = $fixture . '/bootstrap/cache/commands.php'; - expect($buildExitCode)->toBe(0) - ->and($buildOutput)->toContain('Command manifest ready at:') - ->and($manifest)->toBeFile() - ->and(glob($cacheDirectory . '/commands-*.php') ?: [])->not->toBeEmpty() - ->and($manifest . '.d')->not->toBeDirectory(); - - [$clearExitCode, $clearOutput] = runInfbyteCommand([ - PHP_BINARY, - $root . '/infbyte', - 'command:clear', - '--path=' . $manifest, - ]); + try { + [$buildExitCode, $buildOutput] = runInfbyteCommand([ + PHP_BINARY, + $fixture . '/infbyte', + 'command:cache', + ]); + + expect($buildExitCode)->toBe(0) + ->and($buildOutput)->toContain('Command manifest cached: ') + ->and($manifest)->toBeFile() + ->and(glob($fixture . '/bootstrap/cache/.commands-*') ?: [])->toBeEmpty(); - expect($clearExitCode)->toBe(0) - ->and($clearOutput)->toContain('Command manifest cleared:') - ->and($manifest)->not->toBeFile() - ->and(glob($cacheDirectory . '/commands-*.php') ?: [])->toBeEmpty() - ->and($manifest . '.d')->not->toBeDirectory(); + [$clearExitCode, $clearOutput] = runInfbyteCommand([ + PHP_BINARY, + $fixture . '/infbyte', + 'command:clear', + ]); - if (is_dir($cacheDirectory)) { - rmdir($cacheDirectory); + expect($clearExitCode)->toBe(0) + ->and($clearOutput)->toContain('Command manifest cleared.') + ->and($manifest)->not->toBeFile(); + } finally { + removeInfbyteTestDirectory($fixture); } }); it('reports readiness and canonical module state through the infbyte cli', function (): void { - $root = dirname(__DIR__, 2); + $fixture = createInfbyteCliFixture(); - [$readinessExitCode, $readinessOutput] = runInfbyteCommand([ - PHP_BINARY, - $root . '/infbyte', - 'app:ready', - '--json=1', - ]); - [$modulesExitCode, $modulesOutput] = runInfbyteCommand([ - PHP_BINARY, - $root . '/infbyte', - 'module:list', - '--json=true', - ]); - - expect($readinessExitCode)->toBe(2) - ->and(json_decode($readinessOutput, true, flags: JSON_THROW_ON_ERROR)['production_ready'])->toBeFalse() - ->and($modulesExitCode)->toBe(0); - - $modules = array_column( - json_decode($modulesOutput, true, flags: JSON_THROW_ON_ERROR)['modules'], - null, - 'name', - ); + try { + [$readinessExitCode, $readinessOutput] = runInfbyteCommand([ + PHP_BINARY, + $fixture . '/infbyte', + 'app:ready', + '--json=1', + ]); + [$modulesExitCode, $modulesOutput] = runInfbyteCommand([ + PHP_BINARY, + $fixture . '/infbyte', + 'module:list', + '--json=true', + ]); - expect($modules)->toHaveKeys([ - 'auth', - 'cache', - 'communication', - 'database', - 'filesystem', - 'logging', - 'messaging', - 'operations', - 'resources', - 'security', - 'session', - 'validation', - ])->not->toHaveKey('db'); - - foreach (['logging', 'operations', 'resources', 'session'] as $builtIn) { - expect($modules[$builtIn]['installed'])->toBeTrue(); + $readiness = json_decode($readinessOutput, true, flags: JSON_THROW_ON_ERROR); + $moduleRows = json_decode($modulesOutput, true, flags: JSON_THROW_ON_ERROR); + + expect($readinessExitCode)->toBe(1) + ->and($readiness['ready'])->toBeFalse() + ->and($readiness)->toHaveKey('checks') + ->and($modulesExitCode)->toBe(0) + ->and($moduleRows)->toBeArray(); + + $modules = array_column($moduleRows, null, 'name'); + + expect($modules)->toHaveKeys([ + 'auth', + 'cache', + 'communication', + 'database', + 'filesystem', + 'logging', + 'messaging', + 'operations', + 'resources', + 'security', + 'session', + 'validation', + ])->not->toHaveKey('db') + ->and($modules['database']['packages']['infocyph/dblayer']['installed'])->toBeFalse() + ->and($modules['database']['packages']['infocyph/dblayer']['constraint'])->toBe('^5.0'); + + foreach (['logging', 'operations', 'resources', 'session'] as $builtIn) { + expect($modules[$builtIn]['installed'])->toBeTrue(); + } + } finally { + removeInfbyteTestDirectory($fixture); } }); -it('explains the canonical module installation path for absent database support', function (): void { - $root = dirname(__DIR__, 2); +it('reports canonical database installation guidance through module schema metadata', function (): void { + $fixture = createInfbyteCliFixture(); - [$exitCode, $output] = runInfbyteCommand([ - PHP_BINARY, - $root . '/infbyte', - 'auth:schema:status', - '--json=1', - ]); + try { + [$exitCode, $output] = runInfbyteCommand([ + PHP_BINARY, + $fixture . '/infbyte', + 'module:show', + 'auth', + '--json=1', + ]); + + $module = json_decode($output, true, flags: JSON_THROW_ON_ERROR); + $authSchema = $module['schema_status'][0] ?? null; - expect($exitCode)->toBe(2) - ->and($output)->toContain('requires infocyph/dblayer') - ->and($output)->toContain('php infbyte module:install database'); + expect($exitCode)->toBe(0) + ->and($module['name'])->toBe('auth') + ->and($authSchema)->toBeArray() + ->and($authSchema['state'])->toBe('unavailable') + ->and($authSchema['detail'])->toContain('php infbyte module:install database'); + } finally { + removeInfbyteTestDirectory($fixture); + } }); /** @@ -303,6 +293,60 @@ function runInfbyteCommand(array $arguments, array $environment = []): array return [$exitCode, implode("\n", $output)]; } +function createInfbyteCliFixture(): string +{ + $root = dirname(__DIR__, 2); + $fixture = rtrim(sys_get_temp_dir(), DIRECTORY_SEPARATOR) + . '/infbyte-cli-' . bin2hex(random_bytes(6)); + + foreach ([ + $fixture, + $fixture . '/bootstrap/cache', + $fixture . '/storage/cache', + $fixture . '/storage/logs', + $fixture . '/storage/sessions', + $fixture . '/storage/uploads', + $fixture . '/vendor', + ] as $directory) { + if (!mkdir($directory, 0775, true) && !is_dir($directory)) { + throw new RuntimeException(sprintf('Unable to create CLI fixture directory "%s".', $directory)); + } + } + + copy($root . '/infbyte', $fixture . '/infbyte'); + copy($root . '/composer.json', $fixture . '/composer.json'); + copyInfbyteTestDirectory($root . '/config', $fixture . '/config'); + copyInfbyteTestDirectory($root . '/routes', $fixture . '/routes'); + copy($root . '/bootstrap/providers.php', $fixture . '/bootstrap/providers.php'); + file_put_contents( + $fixture . '/vendor/autoload.php', + 'isDot()) { + continue; + } + + $target = $destination . DIRECTORY_SEPARATOR . $entry->getFilename(); + if ($entry->isDir()) { + copyInfbyteTestDirectory($entry->getPathname(), $target); + continue; + } + + copy($entry->getPathname(), $target); + } +} + function removeInfbyteTestDirectory(string $directory): void { if (!is_dir($directory)) { From d397bc45c7b27f6fd12d02552f7a7f64b9bbe080 Mon Sep 17 00:00:00 2001 From: "A. B. M. Mahmudul Hasan" Date: Tue, 25 Aug 2026 15:14:30 +0600 Subject: [PATCH 49/51] Record verified Foundation 2 integration closure --- infbyte_work_plan.md | 205 +++++++++++++++++++++---------------------- 1 file changed, 101 insertions(+), 104 deletions(-) diff --git a/infbyte_work_plan.md b/infbyte_work_plan.md index 9e550b8..2804caa 100644 --- a/infbyte_work_plan.md +++ b/infbyte_work_plan.md @@ -1,35 +1,34 @@ # Infbyte — Foundation 2.0 Live Work Plan +> This is the evidence-driven source of truth for Infbyte's Foundation 2.0 integration. Foundation owns reusable framework/runtime behavior; Infbyte owns the opinionated application skeleton and host composition. + ## Branches - Infbyte: `feature/foundation-2.0` - Foundation: `feature/foundation-2.0` +- Integration PR: draft PR #5, `feature/foundation-2.0` → `main` -## Current checkpoint +## Current checkpoint — 2026-08-25 -- Date: 2026-08-24 -- Infbyte source checkpoint: `56cb73e18eab07f34242a929eccbc9e6572d9971` -- Infbyte documentation checkpoint: `26a35da0926285119c31ed880bf1f5aa06f3cf19` -- Foundation source checkpoint: `493c39a7a06bac0455397556254f0f8e7e25f973` -- Foundation documentation checkpoint: `944220490e1c28e9945fd398265dc9d072eb4c93` -- Infbyte branch base: `main` at `47fb985f266c977504c3dca6bd13e85c9a1b73dc` -- Current phase: **Foundation 2.0 public-name/config freeze complete; ready for deferred verification matrix**. -- Full PHPUnit/static/PHPForge/runtime/release matrix: **not run yet**. +- Verified Infbyte source checkpoint: `ab011a48d08a26ed362e5b53278e249144fbe227` +- Verified Foundation branch checkpoint consumed during integration: `0f71a61b8348173f40de212fe880d6eccacd0a85` +- Infbyte integration Security & Standards run: `32830537262` +- Result: PHP 8.4/8.5 × prefer-lowest/prefer-stable quality suites PASS; clean production install PASS. +- Current phase: **prerelease integration defects resolved; final dependency/API/docs audit and stable Foundation 2.0 constraint transition remain**. -# Ownership boundary +## Ownership boundary Foundation owns reusable framework/runtime behavior: explicit runtimes, DI/provider activation, CLI, scheduler/worker composition, purpose modules, schema orchestration, optimization, operational controls, application contracts, and specialist-package integration. -Infbyte owns only the opinionated host skeleton: application bootstrap, app-specific defaults, routes/application code, writable layout, deployment conventions, and final developer experience. +Infbyte owns only the opinionated host skeleton: application bootstrap, app-specific defaults, routes/application code, writable layout, deployment conventions, distribution/archive rules, and final developer experience. Specialist packages retain their own database/cache/messaging/communication/crypto/validation/filesystem engines. -# Frozen Infbyte structure +## Frozen Infbyte structure - root `infbyte` delegates to Foundation `CommandDispatcher`; -- Web bootstrap delegates to one `Foundation::web()` application; -- CLI/Worker/Scheduler runtime selection is Foundation-owned; -- Foundation has exactly Web, CLI, Worker, Scheduler runtimes; +- Web bootstrap delegates to `Foundation::web()`; +- Foundation exposes exactly Web, CLI, Worker, Scheduler runtimes; - provider groups are `common|web|cli|worker|scheduler`; - checked-in config remains deliberately only `app.php`, `auth.php`, `router.php`; - optional capability config is module-published on demand; @@ -37,11 +36,10 @@ Specialist packages retain their own database/cache/messaging/communication/cryp - `routes/schedule.php` registers schedule definitions; - `routes/workers.php` registers non-message maintenance workers; - generated optimized artifacts are not committed; -- deployment optimization uses `php infbyte optimize`. - -No retired Console runtime hierarchy is reintroduced. +- deployment optimization uses `php infbyte optimize`; +- Foundation 1 convenience APIs/runtime hierarchy are not restored. -# Foundation dependency baseline consumed by Infbyte +## Foundation dependency baseline consumed by Infbyte Core Foundation runtime: @@ -51,28 +49,28 @@ Core Foundation runtime: - `infocyph/uid ^5.0` - `infocyph/webrick ^4.0.2` -Optional capability packages: +Optional capability packages owned by Foundation modules: - `infocyph/cachelayer ^3.2.0` -- `infocyph/dblayer ^4.1` +- `infocyph/dblayer ^5.0` - `infocyph/epicrypt ^2.1` -- `infocyph/omnibus ^2.4` +- `infocyph/omnibus ^2.5` - `infocyph/otp ^6.0` - `infocyph/pathwise ^3.1` -- `infocyph/reqshield ^3.0.1` +- `infocyph/reqshield ^3.1` - `infocyph/talkingbytes ^2.0` - `web-auth/webauthn-lib ^5.3.5` - `infocyph/phpforge dev-main@dev` -During branch development Infbyte requires: +During branch development Infbyte intentionally requires: ```json "infocyph/foundation": "dev-feature/foundation-2.0 as 2.0.x-dev" ``` -Final release alignment will move to the stable Foundation 2.0 constraint. +Final release alignment must replace this with the stable Foundation `^2.0` constraint. -# Frozen purpose-first modules +## Frozen purpose-first modules Canonical modules: @@ -102,7 +100,7 @@ Canonical aliases include: No standalone OTP/passkey public module exists. -# Config/schema lifecycle inherited from Foundation +## Config/schema lifecycle inherited from Foundation Commands: @@ -117,43 +115,38 @@ Commands: Schema owners: -- `auth` -> Foundation auth schema; -- `cache` -> CacheLayer public PDO/SQLite/invalidation schemas; -- `session` -> Foundation database-session schema. +- `auth` → Foundation auth schema; +- `cache` → CacheLayer public PDO/SQLite/invalidation schemas; +- `session` → Foundation database-session schema. Schema status is read-only. Explicit installation owns mutation. Module removal never drops schema/data. Infbyte does not copy optional config into the skeleton merely because Foundation supports the capability. -# Application API rule - -Foundation `Application` is a narrow runtime/composition object. Infbyte application code should resolve real services through DI: +## Application API rule -```php -$service = $app->make(ServiceClass::class); -``` +Foundation `Application` is a narrow runtime/composition object. Infbyte application code resolves concrete services through constructor injection or `Application::make()`. -Do not rely on or recreate removed convenience facades such as: +Do not rely on or recreate retired convenience facades such as: -- `$app->auth()`; +- `$app->auth()` / `$app->authManager()`; - `$app->session()` / `$app->browserSession()`; - `$app->router()`; - `$app->responses()`; - `$app->testing()`; - `$app->messaging()`; -- generic cache/database/filesystem/security manager methods. - -Concrete Foundation application services and native specialist services are resolved through constructor injection or `Application::make()`. +- `$app->ids()`; +- generic cache/database/filesystem/security/validation manager methods. -# Application contracts available to Infbyte apps +## Application contracts available to Infbyte apps -## Validation +### Validation - Foundation `FormRequest` composes Webrick request input with ReqShield; - custom rules implement ReqShield `Contracts\Rule` directly; - generators: `create:request`, `create:rule`. -## Notifications/mail +### Notifications/mail Foundation application routing: @@ -170,7 +163,7 @@ TalkingBytes-backed mail: Generators: `create:mail`, `create:notification`, `create:notification-channel`. -## Messaging/jobs +### Messaging/jobs - `Job` - `JobContext` @@ -178,36 +171,33 @@ Generators: `create:mail`, `create:notification`, `create:notification-channel`. - Omnibus-backed handler pipeline - generators: `create:job`, `create:handler`, `create:job-middleware`. -## Resources/testing +### Resources/testing - `JsonResource::resolve(): mixed`; - `create:resource` targets the current contract; - resolve `JsonDispatchResponseFactory`, `AuthServices`, and `TestKit` through DI rather than Application shortcuts. -# Runtime/operations inherited by Infbyte +## Runtime/operations inherited by Infbyte -## Omnibus 2.4 workers +### Omnibus 2.5 workers - single messaging workers use native Omnibus `WorkerLifecycle` for heartbeat/reload/stop; - no `pcntl` requirement solely for single-worker generation polling; - Unix `WorkerPool` remains pcntl/posix based and retains the Foundation watchdog; - provider-only workers remain messaging-lazy. -## Scheduler ownership +### Scheduler/runtime control - overlap/single-server locks refresh during child execution; - lost lease terminates/fails the child; - schedule history uses stable identity; -- `schedule:test` reports actual failure status. - -## Runtime control - +- `schedule:test` reports actual failure status; - file/cache generation-map mutations are atomic/serialized; - cache-backed runtime control requires suitable shared visibility and coordination; - runtime registry visibility is `host|shared`, default `host`; - process registry is observability metadata, not process-supervision truth. -## Other operations +### Other operations - supervised child commands do not duplicate `--profile` output; - `log:tail --follow` handles truncation/rotation; @@ -215,71 +205,77 @@ Generators: `create:mail`, `create:notification`, `create:notification-channel`. - environment encryption remains Epicrypt-backed with external key material only; - cache schema status does not create a missing SQLite file. -# CLI inheritance +## CLI inheritance -Because the root executable delegates directly to Foundation, Infbyte inherits the frozen Foundation command catalog without duplicate command classes. +The root executable delegates directly to Foundation, so Infbyte inherits the Foundation command catalog without duplicate command classes. -Major families: +Global controls include `--quiet`, `--silent`, `-v|-vv|-vvv`, `--profile`, `--json`, `--env`, `--no-interaction`, help/version/completion. -- application/config/cache/optimization; -- database/migrations; -- modules/config/schema lifecycle; -- execution/maintenance/runtime control; -- messaging/queue/scheduling/workers; -- storage/session/auth operations; -- environment protection/logging; -- `create:*` generators. +## Resolved integration issues — evidence -Global controls include `--quiet`, `--silent`, `-v|-vv|-vvv`, `--profile`, `--json`, `--env`, `--no-interaction`, help/version/completion. +Draft PR #5 at checkpoint `ab011a48d08a26ed362e5b53278e249144fbe227` is validated by run `32830537262`. + +Resolved items: + +- removed stale Foundation 1 test usage such as `Foundation::console()`, `$app->testing()`, broad manager/facade methods and retired schema command names; +- verified the exactly-four-runtime contract and narrow `Application` surface; +- made Web response tests format-independent by decoding JSON; +- aligned route/config/command cache tests to current Foundation 2 CLI contracts and canonical cache paths; +- isolated CLI cache tests in temporary skeletons so runtime artifacts cannot race with distribution tests; +- verified canonical `database` module naming, built-in module status, readiness JSON and `php infbyte module:install database` guidance; +- aligned `.gitattributes` with Foundation 2 cache artifacts (`commands.php`, `schedule.php`, `optimize.php`, `config/`, `container/`, `routes/`); +- aligned create-project archive/deploy/`optimize:clear` tests with current cache-tree ownership; +- removed stale expected `ids.php` base config; checked-in config remains `app.php`, `auth.php`, `router.php`; +- removed obsolete PHPForge reusable-workflow inputs that caused workflow startup failure; +- preserved PHPForge's stable runtime-constraint guard instead of weakening release policy. + +### CI policy during prerelease integration -# Documentation alignment completed +PHPForge's stable-runtime constraint guard correctly rejects the temporary branch alias as a release dependency. Therefore this feature branch currently runs an explicit integration matrix with the same PHPForge quality suite after dependency resolution: -Infbyte README now reflects: +- PHP 8.4 prefer-lowest: PASS; +- PHP 8.4 prefer-stable: PASS; +- PHP 8.5 prefer-lowest: PASS; +- PHP 8.5 prefer-stable: PASS; +- clean production install on PHP 8.5: PASS. -- Foundation 2.0 runtime boundary; -- no separate Console framework; -- current purpose-first modules; -- unified module schema lifecycle; -- current generators/operations; -- DI instead of broad Application facades; -- lean checked-in config; -- deployment-owned optimize artifacts; -- absence of invented Composer test/release aliases. +This is temporary. Once Foundation 2.0 is tagged and Infbyte changes to `^2.0`, restore the normal reusable PHPForge Security & Standards workflow so the stable-runtime constraint guard is a release gate again. -Foundation documentation is the detailed framework source of truth; Infbyte does not duplicate it. +## Distribution contract now verified -# Deliberate Infbyte non-changes +A create-project archive: -Infbyte application source/config checkpoint remains unchanged through the Foundation cleanup/doc-freeze work. This is intentional: +- retains the application example tests and writable-directory placeholders; +- excludes repository-only verification tests and development metadata; +- contains no generated PHP cache artifacts; +- contains no pre-created `bootstrap/cache/config`, `container`, or `routes` runtime trees; +- provisions `.env` idempotently with secure permissions and generated auth secret; +- `deploy.sh` builds Foundation 2 config/route/command/schedule/optimize/container artifacts; +- `optimize:clear` removes every managed artifact and the complete dedicated config cache tree. -- no optional operations/messaging/notifications/database/cache/etc. config is copied into the base skeleton; -- `.env.example` remains lean and contains no environment-encryption key; -- no queue/cache/database/communication/validation/schema implementation is duplicated; -- no Infbyte workaround is added for a Foundation defect; -- no generated optimized artifacts are committed. +## Verification status -# Verification status +Completed with evidence: -Public names/config are frozen. The full Foundation 2.0 + Infbyte verification matrix remains **not run yet**. +1. [x] Composer dependency resolution on PHP 8.4/8.5 lowest/stable. +2. [x] PHPForge quality suite on PHP 8.4/8.5 lowest/stable (`32830537262`). +3. [x] clean production install (`32830537262`). +4. [x] four-runtime and narrow-Application integration tests. +5. [x] canonical Web handling and route cache consumption. +6. [x] config/route/command cache lifecycle through the Infbyte CLI wrapper. +7. [x] canonical module/readiness/install-guidance contracts. +8. [x] clean create-project/archive/install/deploy/optimize-clear path. +9. [x] Foundation 2 cache/distribution `.gitattributes` alignment. +10. [x] stale Foundation 1 test/API expectations removed from the exercised integration suite. -Next phase: +Remaining before stable release: -1. Composer/dependency validation; -2. PHPForge/static analysis; -3. PHPUnit/integration suites; -4. clean create-project/install path; -5. core-only Foundation/Infbyte runtime; -6. purpose-module install/remove/config/schema matrix, including partial auth bundle/install ordering; -7. `app:ready` / production config diagnostics; -8. CLI/global-option/help/completion matrix; -9. Web/CLI/Worker/Scheduler isolation; -10. maintenance/reload/worker/scheduler lifecycle; -11. queue failure/job middleware/pool/fork behavior; -12. DB/destructive/env/storage/optimization safety; -13. representative performance/soak checks; -14. fix defects and move Foundation/Infbyte constraints to stable release alignment. +11. [ ] Finish source/docs/dependency stale-version and retired-API audit across the whole Infbyte branch. +12. [ ] Replace `dev-feature/foundation-2.0 as 2.0.x-dev` with stable `^2.0` after Foundation 2.0 is tagged. +13. [ ] Restore the normal reusable PHPForge release workflow and obtain a full green stable-constraint run. +14. [ ] Record final Infbyte + Foundation source/CI checkpoints and close all release ambiguities. -# Do not regress +## Do not regress - no package-per-module public model; - no standalone OTP/passkey module; @@ -291,4 +287,5 @@ Next phase: - no static global application state; - no optional config copied into the skeleton by default; - no environment-protection key in `.env`/`.env.example`; -- no generated optimized artifacts committed. +- no generated optimized artifacts committed; +- no weakening of PHPForge stable-release dependency policy to accommodate a prerelease branch alias. From f2e81b09a843a3d9ea162ed349790107078cf1f8 Mon Sep 17 00:00:00 2001 From: "A. B. M. Mahmudul Hasan" Date: Tue, 25 Aug 2026 16:24:57 +0600 Subject: [PATCH 50/51] Align skeleton structure documentation --- README.md | 2 -- 1 file changed, 2 deletions(-) diff --git a/README.md b/README.md index 8741fcf..149545c 100644 --- a/README.md +++ b/README.md @@ -183,9 +183,7 @@ config/ router.php public/ routes/ - web.php api.php - auth.php console.php schedule.php workers.php From 1cf7e6ab9bd9ae39609a30d1402df43bea7b2349 Mon Sep 17 00:00:00 2001 From: "A. B. M. Mahmudul Hasan" Date: Tue, 25 Aug 2026 16:28:52 +0600 Subject: [PATCH 51/51] Record final prerelease integration audit --- infbyte_work_plan.md | 39 ++++++++++++++++++++++++++------------- 1 file changed, 26 insertions(+), 13 deletions(-) diff --git a/infbyte_work_plan.md b/infbyte_work_plan.md index 2804caa..bf22ee4 100644 --- a/infbyte_work_plan.md +++ b/infbyte_work_plan.md @@ -10,11 +10,11 @@ ## Current checkpoint — 2026-08-25 -- Verified Infbyte source checkpoint: `ab011a48d08a26ed362e5b53278e249144fbe227` -- Verified Foundation branch checkpoint consumed during integration: `0f71a61b8348173f40de212fe880d6eccacd0a85` -- Infbyte integration Security & Standards run: `32830537262` +- Verified Infbyte source/docs checkpoint: `f2e81b09a843a3d9ea162ed349790107078cf1f8` +- Verified Foundation prerelease checkpoint consumed by the integration line: `f559355b785d4edc56edfde2eadd1aa652c69360` +- Authoritative Infbyte integration Security & Standards run: `32837108534` - Result: PHP 8.4/8.5 × prefer-lowest/prefer-stable quality suites PASS; clean production install PASS. -- Current phase: **prerelease integration defects resolved; final dependency/API/docs audit and stable Foundation 2.0 constraint transition remain**. +- Current phase: **source/dependency/API/docs audit complete; stable Foundation 2.0 publication, constraint cutover, normal release-workflow restoration, and final stable run remain**. ## Ownership boundary @@ -31,6 +31,7 @@ Specialist packages retain their own database/cache/messaging/communication/cryp - Foundation exposes exactly Web, CLI, Worker, Scheduler runtimes; - provider groups are `common|web|cli|worker|scheduler`; - checked-in config remains deliberately only `app.php`, `auth.php`, `router.php`; +- checked-in routes are `api.php`, `console.php`, `schedule.php`, `workers.php`; - optional capability config is module-published on demand; - `routes/console.php` registers application commands; - `routes/schedule.php` registers schedule definitions; @@ -68,7 +69,7 @@ During branch development Infbyte intentionally requires: "infocyph/foundation": "dev-feature/foundation-2.0 as 2.0.x-dev" ``` -Final release alignment must replace this with the stable Foundation `^2.0` constraint. +Final release alignment must replace this with the stable Foundation `^2.0` constraint after Foundation 2.0 is published. ## Frozen purpose-first modules @@ -213,7 +214,7 @@ Global controls include `--quiet`, `--silent`, `-v|-vv|-vvv`, `--profile`, `--js ## Resolved integration issues — evidence -Draft PR #5 at checkpoint `ab011a48d08a26ed362e5b53278e249144fbe227` is validated by run `32830537262`. +The current draft PR #5 head `f2e81b09a843a3d9ea162ed349790107078cf1f8` is validated by run `32837108534`. Resolved items: @@ -227,7 +228,8 @@ Resolved items: - aligned create-project archive/deploy/`optimize:clear` tests with current cache-tree ownership; - removed stale expected `ids.php` base config; checked-in config remains `app.php`, `auth.php`, `router.php`; - removed obsolete PHPForge reusable-workflow inputs that caused workflow startup failure; -- preserved PHPForge's stable runtime-constraint guard instead of weakening release policy. +- preserved PHPForge's stable runtime-constraint guard instead of weakening release policy; +- corrected the README skeleton tree so it no longer advertises nonexistent `routes/web.php` or `routes/auth.php` files. ### CI policy during prerelease integration @@ -239,7 +241,18 @@ PHPForge's stable-runtime constraint guard correctly rejects the temporary branc - PHP 8.5 prefer-stable: PASS; - clean production install on PHP 8.5: PASS. -This is temporary. Once Foundation 2.0 is tagged and Infbyte changes to `^2.0`, restore the normal reusable PHPForge Security & Standards workflow so the stable-runtime constraint guard is a release gate again. +This is temporary. Once Foundation 2.0 is published and Infbyte changes to `^2.0`, restore the normal reusable PHPForge Security & Standards workflow so the stable-runtime constraint guard is a release gate again. + +## Final prerelease audit — 2026-08-25 + +Completed against the active feature branch: + +- Composer remains intentionally minimal: PHP, Foundation, and PHPForge only; Infbyte does not duplicate Foundation's specialist dependencies. +- Foundation module/dependency baseline in this plan is current: CacheLayer 3.2.0, DBLayer 5.0, Omnibus 2.5, ReqShield 3.1 and the other frozen specialist versions. +- no stale `4.1`, `2.4`, or `3.0.1` integration-version references remain in indexed Infbyte release content; +- no active `Foundation::console`, old manager classes, `module:install db`, or retired hyphenated module-schema command usage remains; +- README, Composer, workflow, distribution rules and exercised integration tests are aligned with the actual branch tree; +- draft PR #5 remains mergeable and intentionally draft until the stable Foundation dependency exists. ## Distribution contract now verified @@ -258,8 +271,8 @@ A create-project archive: Completed with evidence: 1. [x] Composer dependency resolution on PHP 8.4/8.5 lowest/stable. -2. [x] PHPForge quality suite on PHP 8.4/8.5 lowest/stable (`32830537262`). -3. [x] clean production install (`32830537262`). +2. [x] PHPForge quality suite on PHP 8.4/8.5 lowest/stable (`32837108534`). +3. [x] clean production install (`32837108534`). 4. [x] four-runtime and narrow-Application integration tests. 5. [x] canonical Web handling and route cache consumption. 6. [x] config/route/command cache lifecycle through the Infbyte CLI wrapper. @@ -267,13 +280,13 @@ Completed with evidence: 8. [x] clean create-project/archive/install/deploy/optimize-clear path. 9. [x] Foundation 2 cache/distribution `.gitattributes` alignment. 10. [x] stale Foundation 1 test/API expectations removed from the exercised integration suite. +11. [x] Finish source/docs/dependency stale-version and retired-API audit across the whole Infbyte branch (`f2e81b09a843a3d9ea162ed349790107078cf1f8`, `32837108534`). Remaining before stable release: -11. [ ] Finish source/docs/dependency stale-version and retired-API audit across the whole Infbyte branch. -12. [ ] Replace `dev-feature/foundation-2.0 as 2.0.x-dev` with stable `^2.0` after Foundation 2.0 is tagged. +12. [ ] Publish Foundation 2.0 and replace `dev-feature/foundation-2.0 as 2.0.x-dev` with stable `^2.0`. 13. [ ] Restore the normal reusable PHPForge release workflow and obtain a full green stable-constraint run. -14. [ ] Record final Infbyte + Foundation source/CI checkpoints and close all release ambiguities. +14. [ ] Record final post-publication Infbyte + Foundation source/CI checkpoints and close all release ambiguities. ## Do not regress