Skip to content

2026-05-02

  • Added first-class grouped and normalized lookup support to the ORM query builder. QueryBuilder and model wrappers now expose whereGroup(...) / orWhereGroup(...) for nested boolean scopes and whereNormalized(...) / orWhereNormalized(...) for portable LOWER(TRIM(column)) = ? text equality, fixing the long-standing orWhere(...) behavior bug that previously compiled as AND and removing the need for raw SQL in guest-style identifier and normalized-email lookups across SQLite and D1.

2026-04-30

  • Fixed the release publish shim used by scripts/release/publish-packages.mjs so package builds can type-check against the current @zintrust/core proxy and shutdown-trace API surface during npm release. The temporary shim now exposes ShutdownTrace and WorkerSigning, which unblocks @zintrust/workers, @zintrust/cloudflare-d1-proxy, @zintrust/cloudflare-kv-proxy, and @zintrust/queue-monitor package builds during publish.

  • Fixed System Trace runtime bridge resolution for project roots that differ from the shell cwd. src/boot/registry/runtime.ts now honors ZINTRUST_PROJECT_ROOT before falling back to process.cwd() when resolving a local src/runtime/plugins/trace-runtime.* bridge, and the runtime coverage suite now pins that behavior with a mismatched-cwd regression test. This unblocks trace startup for Docker/new-start layouts that export ZINTRUST_PROJECT_ROOT before boot.

  • Improved fresh-project database DX across Node and Workers. Newly scaffolded apps now keep the existing sqlite default for plain zin s, but generated config/database.ts files no longer fall back to mysql when DB_CONNECTION is unset under zin s --wg; they now default to d1 when CLOUDFLARE_WORKER=true and sqlite otherwise. Scaffolded .env files also now include USE_ENV=false, and when developers set USE_ENV=true ZinTrust skips .dev.vars materialization for Wrangler dev so zin s --wg can read .env directly without requiring .zintrust.json env-key maintenance.

2026-04-28

  • Tightened CLI launcher and watch-process exit tracking around zin s. The top-level bin launchers and SpawnUtil now preserve the exit result but wait for close, and they relay child stdout/stderr through owned pipes instead of handing the terminal through directly. That keeps more of the watch-mode shutdown tail attached to the parent CLI lifecycle while preserving the existing signal-forwarding behavior and focused SpawnUtil regression coverage.

  • Fixed plain zin s shutdown when worker services are disabled. The runtime no longer registers worker management routes or the worker shutdown hook when WORKER_ENABLED=false, which stops the non-worker watch path from importing the workers package during app shutdown and removes the tsx force-kill that still appeared after a single Ctrl+C.

  • Added env-gated shutdown tracing for the worker-enabled watch path. SHUTDOWN_TRACE=true now emits active-handle snapshots and step-level teardown markers across bootstrap shutdown, WorkerFactory, MultiQueueWorker, queue reliability startup/stop, and queue monitor create/close. The traced live run showed that the worker shutdown path now completes, queue monitor cleanup removes two Redis sockets, and the remaining surviving handle after full app shutdown is a single Redis socket that still persists even after shutdownRedisConnections() reports completion.

  • Fixed the BullMQ shared Redis shutdown hang that was still stalling worker-enabled zin s exits inside PriorityQueue.shutdown(). packages/queue-redis/src/BullMQRedisQueue.ts now bounds sharedConnection.quit() and falls back to disconnect() with a warning when Redis does not complete a graceful quit in time, matching the existing tracked-Redis shutdown strategy used elsewhere in core.

  • Tightened the remaining worker shutdown fallback budgets for tsx watch. WorkerFactory async teardown steps now stop waiting sooner, and the BullMQ shared Redis quit fallback now cuts over to disconnect() on a much shorter bound so watch-mode Ctrl+C exits do not spend most of tsx's child-exit window inside queue transport teardown.

  • Fixed PriorityQueue.shutdown() so worker-enabled zin s does not dynamically import @zintrust/queue-redis during Ctrl+C if the process never used priority queues in the first place. That shutdown path is now a cached-module no-op, which removes an unnecessary optional-package load from the exact zero-worker startup/shutdown case that was still reaching tsx force-kill.

  • Fixed the next worker tail hang in DeadLetterQueue.shutdown(). Its Redis client now uses the same short bounded graceful-quit path with forced disconnect() fallback, so worker-enabled zin s no longer spends the remaining watch-exit window waiting on an unbounded DLQ Redis quit.

  • Tightened the remaining dev watch fallback budgets again after parallelizing worker teardown. The worker tail now cuts over from graceful quit to warning-and-continue on much shorter bounds for shared BullMQ Redis, DLQ Redis, and worker-store cleanup so tsx watch exits can complete before its own child kill window.

  • Fixed the outer zin/z/zt/zintrust launcher wrappers so Ctrl+C no longer drops the shell prompt while the child CLI is still printing shutdown logs. The bin wrappers now trap SIGINT/SIGTERM, stay alive until the spawned zintrust-main child actually closes, and only fall back to explicit forwarding when needed.

  • Fixed the bootstrap graceful-shutdown default budget mismatch for live runtimes. src/boot/bootstrap.ts had still been defaulting SHUTDOWN_TIMEOUT to 1500ms even though the env contract, scaffolding, and config surface already use 10000ms. Worker-enabled zin s shutdowns now get the intended default budget before the watch wrapper falls back to force-killing a slow child.

  • Hardened worker-management shutdown so zin s watch mode no longer depends on every worker subsystem quitting cleanly before the child process can exit. WorkerFactory.shutdown() now awaits the async tail teardown steps it previously fire-and-forgot, and each async worker subsystem shutdown is bounded so a stuck Redis/plugin/DLQ quit path logs a warning and lets shutdown continue instead of leaving tsx watch to kill the process.

  • Tightened the plain zin s watch-mode shutdown fallback so the CLI no longer waits indefinitely for a lingering tsx watch parent after the app itself has already logged a clean shutdown. The TTY signal helper now follows its delayed fallback SIGINT with one automatic SIGTERM escalation if the watch parent still has not exited, which removes the recurring need for a second manual Ctrl+C while preserving the earlier single-signal fast path.

  • Fixed the new coverage-test pre-commit regression by removing dead unreachable code from the SQLite schema coverage test and scoping max-nested-callbacks suppression to the handful of mock-heavy coverage files that intentionally build nested vi.doMock(...) factories. This restores .husky/pre-commit without weakening repository-wide lint rules or changing runtime behavior.

  • Stabilized the SQLite CLI migration integration coverage path so it now validates real CLI success in temp-project runs instead of silently passing through hidden subprocess failures. The test helper now mirrors the repo's source path aliases more completely, points the local @zintrust/core shim at the actual router source file, throws immediately on non-zero zin subprocess exits, and allows enough timeout headroom for the full coverage:patch run when the TSX-backed CLI is booted multiple times under suite-wide load.

  • Refined the plain zin s shutdown fix for Node watch mode so tsx watch no longer logs Previous process hasn't exited yet. Force killing... during normal Ctrl+C shutdown. The watch path now keeps direct TTY signal delivery as the primary path and uses a short delayed fallback signal only if the watcher is still alive after the app shutdown grace period, which preserves single-Ctrl+C exits without reintroducing the earlier hanging behavior or touching the already-good zin s --wg path.

  • Ported the Worker parse-safety fixes from the April 28 debugging note into source-owned ZinTrust modules instead of relying on local node_modules edits. src/runtime/WorkerAdapterImports.ts, src/boot/bootstrap.ts, src/runtime/plugins/trace.ts, src/http/RequestContext.ts, and src/runtime/PluginManager.ts no longer rely on parse-time top-level await or eager CLI-only imports, while preserving explicit readiness promises for bootstrap and worker/plugin initialization and on-demand loading for plugin installs. This keeps zin s --wg parseable under Wrangler/Miniflare and still lets the normal startup path reach Ready on http://localhost:7777.

2026-04-27

  • Fixed sqlite-family migration diagnostics for schema.table(...) foreign-key alterations. When a migration tries to add or drop foreign keys, or drop columns, on SQLite/D1-backed tables, ZinTrust now fails with a targeted validation message that names the affected table, foreign key, local column, referenced table and column, and any detected SQLite affinity mismatch such as TEXT versus INTEGER, instead of only throwing the previous generic table-rebuild error.

  • Fact-checked and corrected four historical core-gap notes under newstart/. The current workspace already has the described fixes for single-row hydration and mutator-safe raw hydration, accessor-backed direct model property reads, belongsTo / belongsToMany eager-loading parity, and queue-monitor stale-history retry state handling, so those notes now explicitly describe their verified fixed status instead of presenting them as current gaps.

2026-04-24

  • Added a package-local lint script to @zintrust/storage-gcs so workspace-level checks like npm run lint -- --max-warnings=0 work when run from packages/storage-gcs instead of failing with a missing-script error.

  • Stabilized the Husky pre-push coverage:patch path by raising Vitest testTimeout and hookTimeout only during --coverage runs. Normal npm test still keeps the tighter fast-feedback budget, while full V8 coverage runs now have enough headroom for the repo's slower import-heavy CLI, broadcast, and schedule slices without intermittent timeout failures.

  • Stabilized the remaining per-test timeout overrides that were still bypassing the coverage-only Vitest timeout policy. tests/unit/CoverageBoost.test.ts and tests/integration/cli/ScheduleCli.SourceFirst.integration.test.ts now allow enough time for aggregate patch-coverage runs instead of failing intermittently under Husky with explicit 10s and 30s caps.

  • Fixed the ORM hydration contract so Model.hydrate(...) is now idempotent for already hydrated model instances. Passing an existing model back into hydrate(...) now returns that same instance unchanged instead of rebuilding a second model from enumerable properties, which preserves accessor-backed reads, raw stored attributes, attached relations, dirty tracking, and subsequent save() behavior across helper boundaries.

  • Fixed the package publish pipeline so workspace adapters keep their checked-in peerDependencies['@zintrust/core'] value during npm publish instead of being rewritten to a stale caret range. This closes the release-path regression that republished @zintrust/cache-redis@1.5.0 with @zintrust/core: ^1.2.0 on npm even though the source manifest declared *, and bumps @zintrust/cache-redis to 1.5.1 for the corrective republish.

2026-04-22

  • Extracted a dedicated worker-only signing helper for Cloudflare proxy entrypoints. The D1/KV worker path now goes through WorkerSigning instead of embedding verification logic in shared proxy files or routing through broader runtime signing services, which makes the worker-safe import boundary explicit and keeps the proxy surface off Env and other app-runtime config code.

  • Fixed the shared Cloudflare D1/KV proxy verification path so the worker entrypoints no longer pull SigningService and Env from the broader app runtime config graph. The common proxy helper now verifies signed requests directly with SignedRequest, which keeps both core and standalone Cloudflare proxy bundles on a Worker-safe import surface instead of reintroducing startup failures through shared config imports.

  • Fixed the Cloudflare Worker startup path so WorkerAdapterImports no longer uses top-level await in the core Worker bundle. Worker boot still awaits the same readiness promise at runtime, but the generated service entry now stays parseable under Wrangler/Miniflare instead of failing early with Unexpected reserved word during ZintrustD1Proxy.js startup.

  • Added signed remote trace transport support to @zintrust/trace. Apps can now set TRACE_PROXY=true to send the same write/update/latest-family trace operations they already produce to a remote ingest server via TRACE_PROXY_URL + TRACE_PROXY_PATH, while trace servers can mount registerTraceIngestGateway(...) to verify and persist those requests through the existing TraceStorage flow. The trace runtime also now supports TRACE_SERVICE_TAG, falling back to APP_NAME so multi-project trace servers can tag incoming data consistently.

  • Added arbitrary env-key generation to the CLI. zin key:<ENV_KEY> now normalizes to zin key:env <ENV_KEY>, generates a new secret value, writes it into .env, and prompts before overwriting an existing key unless --yes is provided.

  • Added a first-class date migration helper so you can now write table.date('blocked_date') for date-only columns and keep table.timestamp(...) for date-time values. The migration blueprint/types/compiler all support the new helper.

  • Added a framework-owned ORM contract for model-owned primary keys through Model.primaryKey. Projects can now use Model.primaryKey.uuid('id') or Model.primaryKey.using(...) instead of repeating fragile creating observer guards, and the built-in missing-value check correctly treats undefined, null, empty strings, and whitespace-only strings as missing before insert.

  • Fixed the unified request-input contract so adapter-populated cached raw bodies now go through the same parse-and-set path as streamed request bodies. That keeps req.getBody(), req.data(), and req.get(key) aligned in both Node.js and Workers runtimes.

  • Expanded RemoteSignedJson proxy error extraction so non-2xx signed JSON calls now surface the most specific proxy detail they can find from top-level { code, message }, nested body, nested error, or plain-text/top-level message fallback shapes.

  • Fixed the kv-remote proxy credential gate so it now falls back to the normalized signing identity from APP_NAME and APP_KEY the same way d1-remote already does. When explicit KV_REMOTE_KEY_ID / KV_REMOTE_SECRET values are absent, the driver keeps the signed proxy path available instead of prematurely forcing the Cloudflare KV API path.

  • Fixed npm run release:sync-versions so it now detects changed core source and changed package directories, looks up the currently published npm version for each affected manifest, and bumps only to the next release patch instead of leaving publishable packages stuck at an already-published version. The release sync path now uses ZinTrust's bounded carry rule for patch increments, so it advances sequentially and rolls x.9.99 -> (x+1).0.0 without skipping intermediate publish versions.

  • Updated the npm publish preflight and release publish scripts so they now run npx npm-check-updates -u before install or package publish instead of relying on the older manual dependency-range sync path. The root check-up script now performs the updating variant by default, with check-up:check kept as the read-only listing command.

  • Fixed trace proxy sender startup so @zintrust/trace/register no longer resolves the sender-local trace storage DB before switching to ProxyTraceStorage. This removes the unused local SQLite readiness failure from proxy-mode worker boot, suppresses the local dashboard hint when TRACE_PROXY=true with a real TRACE_PROXY_URL, and stops packages/trace from publishing its raw src/ tree to npm.

2026-04-21

  • Fixed the core auth storage insert contract so the built-in Bulletproof device store, JWT revocation store, and JWT sessions store now keep working when projects switch those core-owned tables from table.id() to table.uuid('id') without adding a database-side default. Each store still attempts the existing insert path first, then retries once with a generated UUID only when the database explicitly rejects the missing id. RemoteSignedJson also now preserves top-level proxy { code, message, status } bodies so D1 remote failures keep their actionable detail.

  • Fixed the remaining @zintrust/trace bootstrap split between dashboard routing and runtime registration. The dashboard registrar now fails fast when no explicit, runtime, or configured trace connection can be resolved instead of silently falling back to the app default database, shared trace connection error helpers now steer eager startup/plugin imports toward @zintrust/trace/plugin, and core boot now falls back to its bundled trace-runtime bridge when a project-local bridge is absent so installed trace packages can initialize without a custom shim.

  • Updated every public workspace package manifest to declare peerDependencies['@zintrust/core'] as ^0.9.2 so the checked-in source package metadata now matches the publish-time caret policy and no longer uses * for the core peer.

  • Changed the package publish transform so @zintrust/core peer dependencies are now rewritten to the live caret release such as ^0.9.2, or * if no core version can be resolved. The release script no longer generates same-minor comparator ranges like >=0.9.0 <0.10.0 during npm publish.

  • Released the remaining public ZinTrust workspace packages on the coordinated 0.9.1 patch line so all npm-published adapters and extensions move off the broken 0.9.0 metadata set. This includes @zintrust/d1-migrator, @zintrust/socket, @zintrust/client-rds-data, @zintrust/storage-s3, @zintrust/queue-redis, @zintrust/storage-gcs, @zintrust/queue-rabbitmq, @zintrust/cloudflare-containers-proxy, @zintrust/cloudflare-d1-proxy, @zintrust/signer, @zintrust/cloudflare-kv-proxy, @zintrust/trace, @zintrust/cache-mongodb, @zintrust/queue-monitor, @zintrust/queue-sqs, @zintrust/storage-r2, @zintrust/expose, @zintrust/workers, @zintrust/governance, and @zintrust/storage, keeping the published package line aligned on corrected @zintrust/core peer metadata.

  • Released @zintrust/mail-smtp@0.9.1, @zintrust/mail-sendgrid@0.9.1, @zintrust/mail-mailgun@0.9.1, and @zintrust/mail-nodemailer@0.9.1 to correct stale npm metadata from the broken 0.9.0 publish. The patched mail adapters keep the broad live @zintrust/core peer range so downstream installs on @zintrust/core@0.9.0 no longer fail with ERESOLVE on the mail packages.

  • Released @zintrust/db-sqlite@0.9.1, @zintrust/db-mysql@0.9.1, @zintrust/db-postgres@0.9.1, @zintrust/db-sqlserver@0.9.1, and @zintrust/db-d1@0.9.1 to correct stale npm metadata from the broken 0.9.0 publish. The patch line keeps the adapters on the live broad @zintrust/core peer range so downstream installs using @zintrust/core@0.9.0 no longer fail with ERESOLVE on the database packages.

  • Released @zintrust/cache-redis@0.9.1 to correct the npm metadata line after the broken 0.9.0 publish. The new patch keeps the adapter on the live broad @zintrust/core peer range so downstream apps installing @zintrust/core@0.9.0 no longer hit an ERESOLVE conflict from the stale >=0.7.0 <0.8.0 peer declaration.

  • Added the isMissingLike(...) helper alias on top of isUndefinedOrNull(...) and updated the helper reference to document the intended null-like split explicitly: isNullish(...) and isDefined(...) for strict TypeScript narrowing, isNull(...) for narrower legacy null markers, and isUndefinedOrNull(...) / isMissingLike(...) for the broad compatibility missing-value bucket.

  • Fixed the remaining future-version leak in ZinTrust package metadata and project scaffolding. Fresh app scaffolds now use the live npm @zintrust/core release when lookup succeeds and fall back to * instead of guessing a future core line from governance metadata when npm lookup fails. The package publish transform now also preserves broad @zintrust/core compatibility for published adapters instead of rewriting peers to an unpublished future ^x.y.z range, which avoids downstream npm install ERESOLVE failures like @zintrust/cache-redis requiring a core version that is not live on npm yet.

  • Tightened the shared @zintrust/core helper contracts around the audited is* edge cases. isBoolean(value, true) now accepts only real booleans or boolean-like strings instead of also passing numeric 1 and 0, isBase64(...) now rejects empty strings and requires a valid padded non-empty Base64 payload, and isUpperCase(...) / isLowerCase(...) now require at least one alphabetic character instead of treating numeric-only strings as valid case matches. Expanded the helper test suite to cover the full exported helper surface and added focused type-safety narrowing tests for the predicate helpers.

2026-04-20

  • Made the remaining Cloudflare proxy workspace packages publishable by removing the last private: true guards from @zintrust/cloudflare-kv-proxy and @zintrust/cloudflare-d1-proxy and setting their package publish access to public, so the release tooling can ship them to npm like the rest of the package line.

  • Added a reusable JwtVerifier helper for verifying externally issued RS256 JWTs with either a single JWK or a remote JWKS endpoint. The helper validates signature, issuer, audience, exp, and nbf, keeps JWKS documents in a small in-memory cache with configurable TTL, returns structured failure reasons when you want non-throwing control flow, and is exported from @zintrust/core for both Node.js and Cloudflare Workers projects. The docs now include a dedicated public guide for Apple Sign In and other provider-token flows.

2026-04-19

  • Fixed Bulletproof auth for fresh/newstart apps by moving the missing device-secret path into core. ZinTrust now exposes req.header(...) as an alias of req.getHeader(...), ships a built-in BulletproofDeviceStore backed by the new zintrust_bulletproof_devices migration, resolves Bulletproof middleware secrets from that store by default before falling back to the shared env secret, and adds a built-in LoginFlow issuer named bulletproof that returns { token, token_type, deviceId, deviceSecret }. The default auth controller and fresh-project template now use that issuer, so normal migrations are enough to make the docs flow work.

  • Fixed CLI project-module discovery for fresh/newstart-style workspaces. zin routes now resolves the active project root first and loads routes/api.ts from the workspace filesystem instead of only relying on the core alias graph, ScheduleCliSupport now prefers project app/Schedules files before alias imports, and optional CLI extension discovery now climbs to the nearest project package.json when commands are launched from a subdirectory.

  • Stabilized the Husky pre-push coverage:patch path by giving a small set of import-heavy integration and worker coverage tests explicit 30s budgets, including the remaining broadcast worker coverage slice. This keeps the behavior checks intact while avoiding false-negative push failures from the default 10s Vitest timeout under aggregate patch-coverage runs.

  • Fixed the remaining schedule CLI mixed-export discovery gap. ScheduleCliSupport now preserves the full project schedule module namespace when it falls back to loading app/Schedules from project files, and the CLI schedule collector now flattens named exports plus default exports consistently while deduplicating by schedule name. This means schedule:list, schedule:run, and schedule:start no longer lose valid schedules just because a project schedule module mixes default and named exports.

  • Fixed the package release helper so repeated or partially completed manual publishes no longer crash the script with Cannot read properties of undefined (reading 'name'). The publish-packages path now keeps @zintrust/d1-migrator transform output defined even if a dependency is already on semver metadata instead of file: form, and failure reporting falls back to the package directory when transformed metadata is unavailable.

  • Hardened the npm publish workflow against stale ZinTrust package version drift before publish. publish-version now runs a dedicated preflight that re-syncs all published @zintrust/* dependency ranges from npm and retries npm install up to three times before failing, which catches peer-resolution conflicts such as a root app still pointing at an older @zintrust/core while an adapter already requires the newer release line.

2026-04-18

  • Fixed the restored npm publish workflow so release CI now normalizes workspace package versions and refreshes the root lockfile before dependency installation instead of failing early on a stale package-lock.json self-link for @zintrust/core. This keeps publish verification aligned with the checked-in release version without letting a transient lockfile mismatch block npm publishing.

  • Merged the remaining open local Dependabot dependency updates into the release branch by aligning the Cloudflare Containers proxy, AWS SQS and Secrets Manager adapters, and the expose package with the newer package versions and refreshing the root workspace lockfile to match.

  • Stabilized the release-branch full-suite and pre-push test path under loaded CI/dev environments by raising local time budgets only for a small set of import-heavy CLI, worker, Cloudflare runtime, and broadcast regression tests that were intermittently timing out during aggregate Vitest runs even though they still passed in focused execution. This keeps the real behavior checks intact while removing false-negative push failures caused by suite-level contention rather than product regressions.

  • Kept the publish-smoke fresh-scaffold cold-start stage and hardened it instead of removing it. The workflow now installs tsx explicitly with --no-save after npm install --omit=dev so the source-first zin start --no-watch smoke boot still has the TypeScript runner it invokes even when scaffold app devDependencies have been pruned for the cold-start check.

  • Hardened the release verification publish-version smoke gate to match the working publish-smoke path. The release workflow now also installs tsx explicitly after npm install --omit=dev, disables worker shutdown side-effects for the cold-start app, and forwards TSX_TSCONFIG_PATH so the scaffold app boots against its own tsconfig instead of failing the publish-to-npm verification with tsx missing or the wrong TypeScript file resolution context.

  • Hardened @zintrust/workers graceful shutdown logging so shutdown completion no longer crashes when a consumer runtime exposes a partial logger surface where Logger.info is unavailable late in teardown. WorkerShutdown now logs through a best-effort level fallback instead of throwing Logger.info is not a function during app exit.

  • Removed the CLI suggestion to install tsx globally when the local runner is missing. ZinTrust now only tells developers to add tsx to the project, which matches the supported local-runtime contract and avoids nudging CI or fresh scaffolds toward machine-global fixes.

  • Fixed zin new fresh-project scaffolding when the destination directory already exists but is still empty, which is a common publish-smoke setup pattern under /tmp. The scaffolder now reuses empty targets, still rejects non-empty directories unless --overwrite or --force is set, and explicitly honors force in the shared scaffolder path. Verified end-to-end by rebuilding dist, creating /tmp/test-a, installing the local dist package into that app, pruning dev dependencies with npm install --omit=dev, and booting node ./node_modules/@zintrust/core/bin/zin.js start --no-watch successfully with the packaged CLI.

  • Fixed schedule CLI source re-entry for fresh scaffold-style apps that do not ship a project-owned bin/zin.ts or bin/zintrust.ts. When source schedule files are present, the schedule commands now fall back to the currently running packaged CLI script if needed, so schedule:list, schedule:run, and schedule:start still work from installed @zintrust/core builds instead of aborting with a missing project CLI entrypoint error.

  • Expanded the @zintrust/trace package docs with explicit guidance for the reserved trace-skip log context contract. The docs now show when to use Logger.withTraceSkipContext(...), when a local wrapper such as withTraceSkipProxyContext(...) is appropriate, and concrete examples from proxy, queue, and raw SQL transport diagnostics so developers can avoid trace-recursion noise without hiding normal application logs.

  • Tightened ProjectScaffolder npm version lookups so the child process now runs with a fixed safe PATH plus a small allowlist of npm/home/proxy/certificate variables instead of cloning the full shell environment, which resolves the Sonar PATH-taint finding without breaking published-version discovery. Removed the publish-smoke preinstall scaffolded dependency-range assertion block as well, since that gate had proven flaky across release runs and duplicated the real cold-start install validation that follows.

  • Added an explicit proxy verification debug gate for the shared SQL/Redis proxy signature path. Healthy per-request Verifying request signature diagnostics are now suppressed by default and only emit when ZT_PROXY_DEBUG or the matching per-proxy flag such as MYSQL_PROXY_DEBUG, POSTGRES_PROXY_DEBUG, REDIS_PROXY_DEBUG, or SQLSERVER_PROXY_DEBUG is enabled. Signature verification failures remain visible, and the gated diagnostics still carry the reserved trace-skip logger metadata so proxy debugging does not reopen the trace-recursion path.

  • Fixed source-first schedule CLI loading so schedule:list, schedule:run, and schedule:start now resolve project schedules through the same rooted source/bootstrap path as normal runtime startup, including source CLI re-entry for TypeScript apps using project aliases.

  • Fixed fresh basic scaffolds and publish-smoke cold starts by restoring a local tsx devDependency in generated apps. New source-first projects can now boot through zin start --no-watch after install without relying on an unreleased framework-side loader change or altering the active release/version line.

  • Added a reserved __zintrustSkipTraceLog logger metadata contract and taught @zintrust/trace to honor it before the older message-text skip list. Low-level proxy/signing/remote transport/raw SQL diagnostics and trace storage degradation warnings now mark themselves as non-traceable, which closes the current log-watcher recursion path without weakening normal application log capture.

  • Re-enabled the repository publish entrypoints so the verified release path can publish the built core dist with npm run pub:ci and workspace packages with npm run release:publish-packages again.

  • Fixed fresh-project scaffolding and the publish-smoke workflow so starter apps now target the live npm release line for @zintrust/core and @zintrust/governance instead of leaking the unreleased repo root version. When npm lookup is unavailable, scaffolding now falls back to the workspace's published peer line rather than the local 1.0.x repo version, and microservice scaffolds now also reuse the live governance release line if the core lookup misses while governance still resolves. Publish-smoke explicitly asserts those scaffolded dependency ranges before the local dist install rewrites them.

  • Added deduplication.collisionBehavior to the shared queue contract and the BullMQ Redis adapter. Queue jobs can now keep the historical suppress behavior for true duplicate dropping or opt into enqueue to preserve an ordered same-key backlog while an overlap lock is already active.

  • Hardened scaffold-time npm view version lookups by forcing the child process PATH to fixed system directories and explicitly carrying NODE_ENV, which addresses the secure-process-environment warning without breaking the ProjectScaffolder type contract.

  • Added a dedicated Database Migrations guide and wired it into the docs sidebar plus the main CLI and getting-started docs. ZinTrust migration commands were already implemented, but the guidance had been split across multiple pages; the new page now centralizes create-table generation, add-column generation, migration execution, D1 notes, and the distinction between zin s and migration commands.

  • Removed the dead Snyk README badge links after the public https://snyk.io/test/github/ZinTrust/ZinTrust endpoint began returning 410 Gone.

  • Removed the default @zintrust/d1-migrator dependency from freshly scaffolded apps, since it is an optional CLI extension rather than a runtime requirement.

  • Updated the publish smoke workflow to install only runtime dependencies for fresh-app cold-start validation, which avoids pre-publish failures on dev-only packages that have not been released yet.

Developer Docs Updates

This page tracks developer-visible documentation changes.

2026-04-17

  • Restored tsx as a runtime dependency of the packaged @zintrust/core distribution and removed the conflicting scaffolded app-level tsx devDependency. Fresh scaffold installs that intentionally omit app dev dependencies still rely on the framework CLI to spawn TypeScript-backed runtime entrypoints such as zin s --no-watch, so the published package now carries the loader it invokes during release smoke and CI cold-start validation without npm install --omit=dev pruning it back out of new apps.

  • Isolated the Husky patch-coverage run into a dedicated temporary Vitest reports directory instead of the shared repository coverage/ output. This prevents intermittent coverage/.tmp/coverage-*.json ENOENT failures when another coverage-producing process or cleanup path touches the default reports directory during the pre-push gate, while leaving normal npm run test:coverage output unchanged.

  • Locked in the ORM model creation contract so Model.create(...) is explicitly covered as equivalent to make(...) plus save() for fillable filtering, mutators, casts, create-time observers, and accessor-visible hydrated state. The new regression coverage protects model-owned encryption, normalization, boolean coercion, and observer-assigned identifiers from drifting out of the create path.

  • Fixed migration scaffolding so generated migration files keep importing MigrationSchema, Blueprint, and IDatabase from @zintrust/core in packaged CLI builds instead of being rewritten to a relative ../../index.js path.

  • Fixed release artifact versioning so local/dist builds now stay on the checked-in repository version instead of auto-incrementing from the latest npm-published core package. This prevents release smoke scaffolds from minting phantom versions such as 0.8.0 while the repo is still on the 0.7.x line.

  • Fixed governance scaffolding to resolve the actual bundled @zintrust/governance version instead of deriving it from the core version. Fresh projects now request the real governance release line and no longer generate non-existent ranges like @zintrust/governance@^0.8.0 when governance has not moved in lockstep with core.

  • Disabled npm publish entrypoints and the old publish workflow for this repository. Release verification still builds and smoke-tests the framework, but package publishing now stops with an explicit "push changes to git instead" message.

  • Added a first Plug & Play auth/login runtime contract through LoginFlow. Core now exposes explicit login provider, issuer, and auditor registration, a staged identify() -> verify() -> issue() -> audit() -> run() flow, a built-in jwt issuer backed by JwtManager.signAccessToken(...), and a built-in trace auditor for normalized success and failure audit hooks. The new docs section also now documents real auth/login Plug & Play examples instead of only a target design.

  • Added a first Plug & Play notification orchestration contract through Notification.compose(...). Core now exposes explicit channel registration, fluent email()/push()/sms()/webhook()/channel() composition, required-versus-best-effort delivery policy, normalized per-channel results, and a dedicated docs page for the new composer contract.

  • Added a first Plug & Play context assembly contract through ContextLoader.create(). Core now exposes dependency-ordered .load(...) resolution, request-scoped resolve memoization, optional shared .batch(...)/.fromBatch(...) fan-out loading, and a new docs page for the context loader pattern.

  • Fixed publish-time @zintrust/core peer rewriting for package releases so adapters such as @zintrust/db-d1 now keep the active release-line peer range instead of being rewritten back to an older published core line. This preserves ^0.6.0 peers for the current release branch instead of emitting stale ^0.5.9 metadata.

  • Fixed the root workspace lockfile self-link for @zintrust/core so CI npm ci can validate the active 0.6.0 release line without treating the root package link as an unversioned dependency. The version sync script now stamps the root node_modules/@zintrust/core lock entry with the root package name and version and verifies that identity during --check runs.

  • Fixed stale Queue Monitor retry actions so retry requests now return distinct outcomes for missing jobs, non-retryable live jobs, and successfully re-queued jobs. The BullMQ driver now reports structured retry state, the retry API returns 404 when a historical row points at a job that no longer exists and 409 when BullMQ refuses retry because the job is in the wrong state, and the package tests lock in all three paths.

  • Extended the core ORM model surface so hydrated models expose accessor-backed attribute values on direct property reads in addition to getAttribute(...). Accessor-backed properties now stay live after model extension and hydration, property writes still flow through mutators and casts, and raw getAttributes() output remains unchanged for compatibility.

  • Hardened the package release publish script so --help and --version now exit without attempting npm publishes, and package publish runs now recreate the temporary core shim before each package copy instead of assuming a prior package left that temp directory intact.

2026-04-13

  • Added first-class form and custom body serialization support to the shared HttpClient. asForm() now sends real application/x-www-form-urlencoded payloads for plain-object bodies, preserves URLSearchParams inputs without routing them through JSON first, and the request builder now supports raw body inputs such as string, URLSearchParams, FormData, and DELETE request bodies across the standard verbs. A new asCustom(...) mode lets applications provide their own serializer and content type for provider-specific request formats while keeping the shared fluent client and trace instrumentation path.
  • Fixed stale persisted worker auto-start cleanup in @zintrust/workers. When a persisted worker record still points at a deleted local processor module, startup now tags that unresolved processorSpec as stale persisted metadata, purges the dead record from persistence, reports the outcome as a skipped purge instead of a normal auto-start failure, and keeps boot moving for the remaining workers. Worker removal is now also idempotent for this cleanup path, so repeated purge attempts do not fail if the persisted record was already removed earlier in the same lifecycle.
  • Hardened the @zintrust/trace content-budget hot path so deferred trace writes now yield to the next event-loop turn instead of running from a microtask. TraceContentBudget.wrapStorage(...) now schedules queue enqueue and fallback persistence through a MessageChannel task boundary, keeps the returned write/update promise tied to the real deferred dispatch result, and uses bounded top-level field dropping instead of the older recursive droppable-path search when queued worker compaction still has to fit oversized content. The package tests now lock in both the next-turn ordering and the restored promise semantics.
  • Added distinct branded SVG favicons for the built-in Workers UI, Telemetry dashboard, and Queue Monitor pages so developers can identify each ZinTrust browser tab by icon at a glance. Each page now keeps the shared ZinTrust mark but overlays a page-specific symbol in the favicon while leaving the on-page branding unchanged.

2026-04-12

  • Changed @zintrust/trace content-budget writes to fail open instead of compacting oversized payloads inline on the request path. Trace writes now return immediately, can offload through a configured trace queue driver and internal drain worker, and when no trace queue is configured oversized content is replaced with a short Trace content exceeded budget and was replaced. notice before persistence instead of running the expensive compaction loop during live requests.
  • Fixed the package publish order for @zintrust/d1-migrator so its npm manifest no longer rewrites local database adapter dependencies to whatever stale versions happen to be on the registry at publish time. Release publishing now forces the db-d1, db-mysql, db-postgres, db-sqlite, and db-sqlserver packages to publish before d1-migrator, and d1-migrator now refuses to publish unless those adapters are already live on npm at the exact current release version.
  • Fixed two core release blockers ahead of the 0.5.1 npm publish. Router.any() now registers OPTIONS alongside the other HTTP methods so CORS and wildcard handlers can match preflight requests, and RemoteSignedJson now sends Connection: close on outbound signed JSON proxy calls to avoid the install-time patch downstream projects were carrying against @zintrust/core@0.5.0.
  • Fixed the built-in trace request detail view so related batch tabs such as Cache, Queries, Logs, Exceptions, HTTP, Middleware, and Models no longer hydrate the full request batch up front. Opening a traced request now fetches only batch counts first, each related tab loads its own first page with a default page size of 10 entries, and large batches can page forward without forcing the browser to deserialize all captured cache/query/log payloads at once.
  • Changed release PR automation to use conventional version bumping again, so release CI now honors fix as patch, feat as minor, and breaking changes as major instead of forcing every releasable change into a patch bump.
  • Added explicit custom carry rules for ZinTrust release numbers so CI now treats the version segments as bounded release digits instead of unbounded SemVer counters. Patch bumps now roll x.y.99 -> x.(y+1).0, and minor carry now rolls x.9.99 -> (x+1).0.0 instead of producing x.10.0.
  • Fixed the remaining TypeScript 6 package-local publish builds for @zintrust/socket, @zintrust/queue-monitor, @zintrust/queue-redis, @zintrust/storage, and @zintrust/workers. The affected packages now add the explicit callback and collection element typing that standalone tsc -p tsconfig.json requires during npm publish, so the release publish queue no longer stalls on implicit-any errors after the TS 6 config cleanup.
  • Removed the temporary TypeScript 6 deprecation suppression from the root tsconfig.json by dropping the deprecated baseUrl, downlevelIteration, and ignoreDeprecations options. The remaining workspace-only imports that had been relying on baseUrl were converted to explicit @zintrust/* package aliases and path mappings so npm run type-check stays clean on TypeScript 6 without config suppression.
  • Fixed the built-in trace dashboard entries runtime path so GET /trace/api/entries now returns compact summary rows instead of full nested trace payloads in list mode. Request-heavy views such as /trace?page=entries&type=request now omit large request and response bodies from list responses, include lightweight detail metadata, and enforce a tighter perPage cap for request rows to keep dashboard serialization bounded under load.
  • Fixed the inline trace dashboard document so the runtime script no longer contains stray duplicated CSS. This removes the browser-side Unexpected token '.' failure on /trace?page=entries&type=request and lets the entries page boot normally again.

2026-04-11

  • Temporarily disabled the new raw-fetch outbound trace capture path for internal service integrations such as SMS, mail, storage, and internal broadcast HTTP while investigating request hangs under the expanded client_request tracing rollout. HttpClient tracing remains available, but tracedFetch(...) and safeFetch(...) now fall back to plain fetch behavior for this test release.
  • Made System Trace startup failures non-fatal for application boot. When trace runtime initialization fails, ZinTrust now logs the failure, disables trace for that boot, and continues starting the app instead of aborting the full runtime.
  • Improved the built-in trace dashboard request experience. Request rows now use HTTP method labels such as Get and Post in the Type column, request summaries no longer repeat the method name, and related request entries now render collapsed by default so developers can expand the specific query, middleware, model, log, exception, HTTP, cache, or other item they need.
  • Extended request trace correlation to include route middleware and ORM model activity. The request detail view now shows attached route middleware, exposes dedicated Middleware and Models tabs, records route middleware execution inside the request batch, and emits model create/update/delete entries into the same request trace context for easier end-to-end debugging.

2026-04-09

  • Normalized null-like database read values across the shared ORM boundary so database results that come back as the literal strings NULL, null, or trimmed variants now reach application code as real null values instead of string sentinels. This applies to the core runtime database manager and the public D1, MySQL, and PostgreSQL adapter packages, keeping read behavior consistent across supported databases.
  • Fixed trace storage failures on large payloads by compacting oversized trace content before persistence. When a request or response body exceeds the trace storage budget, ZinTrust now preserves the rest of the trace entry and replaces the oversized field value with an explicit dropped-value notice instead of sending a too-large storage write that can fail on proxy-backed databases such as the MySQL proxy.
  • Fixed the stock CORS middleware so Electron and other browser clients with custom preflight headers no longer get blocked on local API calls. Preflight OPTIONS responses now merge Access-Control-Request-Headers into the configured allow-list instead of dropping headers such as X-Requested-With or app-specific IDs like z-client, while non-preflight requests keep the configured CORS header set unchanged. Wildcard env overrides such as CORS_ORIGINS=*, CORS_METHODS=*, CORS_ALLOWED_HEADERS=*, and CORS_EXPOSED_HEADERS=* now also behave as real allow-all developer overrides instead of partially bypassing CORS only for origins.
  • Fixed another SQLite trace self-recursion path in core by suppressing adapter-level SQLite query executed logs when the SQL targets trace storage tables such as zin_trace_entries, zin_trace_entries_tags, or zin_trace_monitoring. This closes the remaining infinite-loop case where trace writes could still re-enter the log watcher through generic SQLite query logging and continuously append new type=log trace rows.
  • Raised the repo-wide axios override to ^1.15.0 so the root SonarQube scanner toolchain no longer resolves the critical SSRF-vulnerable <1.15.0 line during npm audit. This keeps the current sonarqube-scanner@4.3.5 workflow intact while forcing the safe Axios patch level in the core workspace install used by CI and release checks.
  • Unified worker Redis key-prefix resolution behind a single shared generator in @zintrust/workers. Worker persistence, auto-start discovery, and DLQ/audit keys now all flow through the same prefix helpers, and legacy overrides such as zintrust:workers: or older worker_* forms are normalized back to the app-based ${Normalize(APP_NAME)}_zintrust:workers: namespace to avoid mixed-prefix startup behavior.
  • Hardened @zintrust/workers app-name normalization for default Redis worker key prefixes by removing the regex-based boundary-underscore trim in favor of linear scans. This keeps the new ${Normalize(APP_NAME)}_zintrust:workers: contract while avoiding the super-linear backtracking pattern SonarQube flagged in worker startup config.
  • Fixed the published @zintrust/storage/register ESM entrypoint so the documented import '@zintrust/storage/register' path now resolves cleanly under Node ESM. The storage package source now emits .js-suffixed relative imports for the multipart registration surface, and the package-local build now runs the shared ESM import fixer before publish so npm publish cannot overwrite the valid entrypoint with extensionless specifiers.
  • Changed the default Redis worker persistence key for @zintrust/workers. New starts now default to ${Normalize(APP_NAME)}_zintrust:workers: instead of the older worker_<appPrefix> hash key shape, so worker registry state is namespaced by the normalized application name and no longer drifts into keys like zintrust:workers:_worker_vi.... Explicit WORKER_PERSISTENCE_REDIS_KEY_PREFIX overrides now remain authoritative as-is.
  • Fixed @zintrust/storage multipart bootstrap and Node upload-abort handling. The documented import '@zintrust/storage/register' entrypoint now registers the streaming multipart parser as a real side effect instead of only re-exporting the helper, and the Busboy-backed parser no longer treats every request close as an abort when req.complete === true. This restores valid authenticated multipart uploads that previously failed downstream with Upload aborted and empty validation payloads.
  • Fixed a trace self-recursion path on SQLite after trace migrations are present. The trace query watcher now excludes zin_trace_entries_tags alongside the other trace tables, and the trace log watcher now skips adapter query-execution logs when the logged SQL targets trace storage tables. This prevents TRACE_ENABLED=true plus SQLite query logging from turning trace writes into an unbounded stream of repeated SQLite query executed inserts.
  • Corrected the bottleneck and memory-retention analysis in [report/bottlenecks-memory-leaks-analysis.md] so it now reflects only verified code facts. Implemented the corresponding fixes in core: plugin dependency installs and opt-in post-install commands now run asynchronously via SpawnUtil instead of execSync, microservice discovery now uses async filesystem reads for service.config.json traversal, and the PostgreSQL adapter manager now exposes releaseInstance(key) for targeted cached-adapter cleanup.

2026-04-08

  • Refreshed the Nodemailer adapter dependency metadata to pick up nodemailer@8.0.5, which clears the moderate SMTP command-injection advisory (GHSA-vvjj-xcjg-gr5g) in both the root workspace install and the package-local @zintrust/mail-nodemailer lockfile used for package-level audits.
  • Fixed the Cloudflare Worker proxy trace path so the built-in D1 and KV proxy entrypoints no longer pull the optional dynamic-import system trace bridge into Wrangler service bundles. Worker-safe proxy tracing now uses a dedicated bridge path, which avoids the recent Unexpected reserved word startup failure in ZintrustD1Proxy.js while keeping D1 and KV proxy trace emission available when a worker trace bridge is registered.
  • Improved proxy-backed trace failure diagnostics for MySQL storage writes. Core now preserves attached proxy response details in [MySQLProxyAdapter] Proxy request failed and [trace] Trace storage write degraded logs, so transport failures include the underlying proxy code/message instead of collapsing everything to a generic MySQL proxy error string.
  • Extended trace into proxy execution paths. When trace is enabled in the proxy runtime, MySQL/PostgreSQL/SQL Server/D1 proxy requests now emit SQL trace entries with the final statement plus bindings, and the SMTP proxy now emits mail trace entries including text and HTML content. This complements the TRACE_QUERY_CONNECTION fallback so proxied transports stay visible whether queries run through the app DB facade or directly inside a proxy.
  • Fixed SQL trace capture when trace storage and application data use different database connections. TRACE_DB_CONNECTION now remains dedicated to trace storage, while TRACE_QUERY_CONNECTION can target the application connection whose final SQL statements and bindings should be observed. If TRACE_QUERY_CONNECTION is omitted and trace storage uses a separate connection, ZinTrust now automatically observes the main DB_CONNECTION instead of accidentally subscribing only to the trace database.
  • Expanded trace payload capture and queue-monitor efficiency. Outbound HTTP client traces now include request bodies, response headers, response bodies, and failed-call errors; cache traces can include payloads when TRACE_CACHE_PAYLOADS=true; SQL query traces now keep bound values by default but can hide them with TRACE_QUERY_BINDINGS=false; mail and notification traces now persist rendered content for richer dashboard inspection; and the trace dashboard renders those richer payloads directly, including HTML mail previews. Queue Monitor SSE subscribers with the same selection now share one polling snapshot pipeline instead of recomputing the same snapshot, recent jobs, and lock analytics per browser connection.
  • Mirrored the direct proxy command env-default wiring across ZinTrust so zin proxy:mysql, zin proxy:postgres, zin proxy:redis, zin proxy:smtp, zin proxy:mongodb, and zin proxy:sqlserver now all resolve the nearest project root, load root .env plus cwd overrides before option registration, and read live Env.get* values when building CLI defaults. This removes the remaining static Env.* snapshot dependency from direct proxy option wiring and keeps proxy defaults aligned with consumer-repo env updates.
  • Fixed a trace self-recursion path when trace storage writes fail through the MySQL proxy. The trace log watcher now ignores core transport-failure logs such as [MySQLProxyAdapter] Proxy request failed and the trace degradation advisory itself, so a single proxy 403 no longer turns into an unbounded stream of trace-triggered proxy retry noise.
  • Ported the rooted local Wrangler proxy-config flow from the newstart fix into core. zin proxy:d1 and zin proxy:kv now write their temporary dev config as .zin.proxy.<env>.jsonc in the project root, rewrite the generated proxy entrypoint paths to root-relative ./src/..., and materialize Wrangler dev vars from that rooted launch context. This avoids the old path/cwd mismatch around .wrangler/tmp temp configs in consumer repos.
  • Fixed the global CLI bootstrap ordering so env files now load before the CLI imports modules that read static Env.* values. This restores project-owned proxy defaults such as MYSQL_PROXY_HOST, MYSQL_PROXY_KEY_ID, and related signing config when running commands like zin proxy:mysql from consumer repos instead of falling back to framework defaults too early.
  • Added an explicit zin proxy:d1 startup warning when the resolved project env still does not provide D1_REMOTE_SECRET or APP_KEY. The proxy can still boot under Wrangler local dev, but ZinTrust now tells developers up front that signed requests will fail with 401 CONFIG_ERROR until one of those signing-secret inputs is present.
  • Fixed shutdown log ordering so ZinTrust only reports Application shut down successfully after bootstrap has finished tearing down tracked Redis connections. Previously the inner runtime shutdown logged success before Redis teardown started, which made shutdowns look stuck even when cleanup was still in progress.
  • Fixed the core Cloudflare D1 proxy entrypoint so zin proxy:d1 again starts under Wrangler local dev without pulling the full framework logging/helper runtime into the Worker bundle. The built-in src/proxy/d1/ZintrustD1Proxy.ts entrypoint now stays Worker-safe like the standalone package implementation, which avoids the recent Unexpected reserved word startup failure in ZintrustD1Proxy.js.
  • Fixed @zintrust/trace request correlation and entry filtering so every monolith request now gets a stable trace batch ID even when no inbound trace header is present, which restores related request tabs such as Queries, Logs, Exceptions, HTTP, Cache, and Other instead of fragmenting them into unrelated batches. The trace config now also supports contains-based include/exclude filters per watcher and per inbound request method, such as request.get.exclude(['report']) semantics via watchers.request.get.exclude = ['report'], and the dashboard now exposes tag filters as real links for new-tab workflows, gives GET/POST/other requests distinct colors, shows Cache as its own request-detail tab, and renders captured response bodies when available.
  • Updated the CLI launcher so a global zin binary now hands off to the project-local node_modules/@zintrust/core install when one exists above the developer's working directory, which keeps normal zin * commands aligned with the repo-local runtime and leaves the global install only as a fallback when no local ZinTrust package is present.
  • Clarified @zintrust/trace monitoring tags in both the dashboard UI and package README with direct examples such as auth, checkout, queue:emails, and nightly-sync, and explained that monitoring tags are saved filter shortcuts rather than stored trace mutations.
  • Fixed the fresh basic-project scaffold so generated tsconfig.json files now use a TypeScript-compatible ignoreDeprecations setting again, which restores npm run type-check in clean starters created with the current CLI template.

2026-04-07

  • Hardened scripts/ci/install-deps.sh for release-line workspace installs. CI now retries npm ci with --legacy-peer-deps before falling back to npm install, which prevents fresh checkouts from failing when workspace packages temporarily peer on a newer local @zintrust/core line than the one already published to npm.
  • Fixed release workspace version sync so package peerDependencies on @zintrust/core now follow the local repo core version during monorepo installs and CI, while package publish still rewrites those peers to the currently published npm core line. This removes the recurring ERESOLVE overriding peer dependency noise from scripts/ci/install-deps.sh on release branches before the new core version is live on npm.
  • Updated the shared Wrangler proxy launcher so zin proxy:d1 and zin proxy:kv now load the developer root .env before resolving proxy defaults and also materialize Wrangler .dev.vars from that same root env during local dev. This fixes the recent behavior where proxy commands were falling back to generated defaults instead of honoring root env values such as app signing/config secrets.
  • Fixed the global zin launcher handoff so commands like zin s now wait for the project-local CLI child to finish shutting down before the wrapper exits. This avoids the recent Ctrl+C behavior where the shell prompt returned early while the handed-off local watcher process was still printing shutdown logs.
  • Hardened @zintrust/trace redaction so sensitive values are masked before persistence, not just in selected watchers. Trace content masking is now recursive, masked values are stored as ****, default sensitive key coverage includes common auth/card/session fields, and developers can extend the masked key lists through config/trace.ts or the TRACE_REDACT_KEYS, TRACE_REDACT_HEADERS, TRACE_REDACT_BODY, and TRACE_REDACT_QUERY env vars. Worker startup config loading now includes config/trace.ts as well.
  • Reduced duplication in the trace CLI command wiring by centralizing shared D1 option registration, trace command construction, and named connection resolution in [src/cli/commands/TraceCommands.ts]. This keeps the trace command surface unchanged while improving Sonar duplication on new code.
  • Fixed @zintrust/trace SQL write compatibility and diagnostics for MySQL-backed installs. Fresh trace entry tables now create created_at as a 64-bit integer, a new follow-up trace migration widens existing SQL created_at columns to BIGINT where needed, tag/monitoring inserts now use dialect-safe ignore syntax instead of SQLite-only INSERT OR IGNORE, and runtime trace storage writes now emit rate-limited degradation warnings instead of failing silently when the backend rejects trace inserts.
  • Fixed migration tracking compatibility for legacy SQL migrations tables during package migrations such as zin migrate:trace. Core now detects older schemas that still use a required migration column, writes both name and migration when needed, treats legacy rows as completed-only tracking, and rejects scoped/service-specific tracking cleanly when the old table shape cannot represent it.
  • Fixed the generated src/zintrust.plugins.ts and src/zintrust.plugins.wg.ts trace stub handshake so they now publish the same __zintrust_system_trace_* globals that core boot checks before auto-mounting the trace dashboard. This restores the stock TRACE_AUTO_MOUNT=true path for /trace after trace/plugin regeneration instead of silently leaving the dashboard unavailable.
  • Added an explicit stock-bootstrap trace dashboard activation path with TRACE_AUTO_MOUNT=true. Core boot now keeps runtime registration and dashboard exposure separate by default, but it can auto-mount registerTraceDashboard(...) at TRACE_BASE_PATH with optional TRACE_MIDDLEWARE when that env flag is enabled, which removes the old partial-success trap where trace storage was active but /trace still returned 404.
  • Added a shared CI install fallback at scripts/ci/install-deps.sh. Root workflows now try npm ci first and automatically fall back to npm install when npm reports lock/package sync drift such as missing internal @zintrust/core entries, so CI self-heals instead of stopping on EUSAGE.
  • Fixed the release/CI version sync flow so internal @zintrust/* peer, dependency, and devDependency ranges stay pinned to currently published npm versions instead of drifting to an unpublished future version such as 0.4.75 before @zintrust/core is actually live. CI, smoke, SonarQube, and security workflows no longer auto-bump the root package ahead of npm ci.
  • Scoped queue deduplication locks by queue name in core and @zintrust/queue-redis, so the same logical deduplication.id can now be reused safely across different queues while still deduplicating true duplicates inside the same queue. Worker-side releaseAfter lock cleanup now uses the same queue-scoped storage key contract.
  • Fixed the release package-publish shim for @zintrust/core so package-local publish builds can type-check and run against the new resolveDeduplicationLockKey(...) export while publishing affected packages such as @zintrust/queue-redis.

2026-04-05

  • Updated the Cloudflare Worker scaffold to include the non-secret runtime vars and env-local bindings needed for first-request boot in new deploys, and relaxed startup secret validation so ENCRYPTION_CIPHER is no longer treated as universally required in production. ZinTrust now only blocks on ENCRYPTION_CIPHER when encrypted-envelope interoperability is actually enabled by encryption-specific env such as ENCRYPTION_CIPHER itself or APP_PREVIOUS_KEYS.
  • Relaxed strict startup env validation so non-critical runtime vars such as APP_NAME, HOST, PORT/APP_PORT, BASE_URL, LOG_LEVEL, and LOG_CHANNEL now surface as startup warnings instead of fatal config errors when STARTUP_REQUIRE_ENV=true. Critical startup requirements such as NODE_ENV, DB_CONNECTION, and APP_KEY remain blocking, and Cloudflare startup failures now log structured config errors, warnings, and startup health report details to make missing Worker runtime env easier to diagnose.
  • Added development-safe Redis lifecycle tracking in core so subsystem-scoped direct Redis clients can be reused across non-production Node reloads, framework shutdown now drains tracked Redis clients before exit, and both app/bootstrap and worker shutdown flows respond to SIGUSR2 hot-reload restarts to reduce BullMQ/worker Redis zombie connections during local watch mode.
  • Added first-class HTTP bridge broadcast support for isolated worker/container runtimes. Core now supports both automatic inmemory bridge forwarding in isolated runtimes and an explicit http-bridge broadcaster, so cross-process local socket delivery no longer requires application-level proxy wrappers.
  • Added compatibility fallback from TIME_ZONE to APP_TIMEZONE and wired scheduler cron defaults to inherit the configured app timezone instead of hardcoded UTC when a schedule does not specify its own timezone.
  • Updated the D1 migrator to normalize null-like string values such as NULL and null into real SQL NULL during data migration and schema default-value generation, preventing those sentinel strings from being preserved as quoted text in D1.
  • Hardened @zintrust/queue-redis/register so official plugin auto-imports no longer treat a partially initialized core Queue export as a hard import failure; the Redis queue driver now registers only when the core queue registry API is actually available.
  • Fixed the advanced queue enqueue path so AdvancedJobOptions.jobId and AdvancedJobOptions.uniqueId are forwarded into the shared queue payload when not already set there, while preserving explicit payload identifiers as the authoritative values.
  • Clarified queued broadcast delivery in core so queued payloads treat channels as the authoritative resolved target list, keep legacy channel only as derived compatibility metadata, and ensure framework-owned broadcast workers publish from channels while preserving socket, delivery, and broadcaster metadata.
  • Added strict helper type guards isNullish(...) and isDefined(...) so application code can get correct TypeScript narrowing for null | undefined checks without changing the legacy null-like semantics of isUndefinedOrNull(...).
  • Enabled fresh-project request-path logging by default, added scaffolded LOG_COLOR=true and LOG_COLOR_THEME=arctic entries for colored text request logs, and aligned the documented logging env defaults with the runtime behavior.
  • Hardened Broadcast.publish(...) so core now normalizes channelScope, tries the package-owned internal socket publish route before falling back to in-process socket or driver delivery, reports explicit transport attempts including internal-http, and surfaces clearer official-plugin auto-import failure details when optional packages are missing or broken.
  • Added named request-log terminal color themes with LOG_COLOR_THEME, set arctic as the default palette, and documented all five supported theme options plus the standalone visual palette sheet for developer preview.
  • Added a framework-owned Broadcast.publish(...) / Broadcast.publishLater(...) surface that prefers the active socket runtime automatically when available, kept the older broadcast helpers as compatibility aliases, updated queued broadcast processing to use the new object-based publish contract, and rewrote the broadcast docs/scaffolds so normal application code no longer needs custom publish helpers or a default /broadcast/send bridge.
  • Updated the release version-sync flow so root and dist internal @zintrust/* dependency pins now resolve to the currently published npm version for each workspace package, falling back to the local workspace version only when a package has not been published yet. This prevents release metadata from pointing core or dist consumers at an unpublished next patch such as 0.4.62 when npm still only has 0.4.61.
  • Removed @zintrust/workers from the root core runtime dependencies so worker support is install-on-demand again, and narrowed the official runtime auto-import sweep to packages explicitly selected by env/config signals instead of warning about every optional adapter package that is not installed.

2026-04-04

  • Fixed socket bootstrap ownership for published consumers. @zintrust/core/start no longer re-exports ZintrustSocketHub, which avoids published core builds resolving @zintrust/socket through internal workspace paths like packages/socket/src/index.js in downstream apps, while the Cloudflare worker entry continues to expose the durable object from @zintrust/socket where it is actually needed.

  • Updated Node bootstrap to always try the official base plugin auto-import set before project-local plugin files, so plain zin s no longer depends on src/zintrust.plugins.ts to discover built-in optional packages such as @zintrust/socket/register.

  • Relaxed socket compatibility route registration for POST /broadcasting/auth so apps with an existing broadcast auth endpoint can keep their own handler when sockets are enabled instead of failing bootstrap with a reserved-route conflict.

  • Fixed repository test and coverage flows so importing the governance ESLint config no longer depends on a previously patched local ESLint install. Vitest setup and pretest hooks now apply the Ajv draft-04 compatibility patch before governance config tests run, matching the existing lint-time workaround used for ESLint 10 with Ajv 8.

  • Fixed queue-monitor recent job visibility for Redis/BullMQ workers at the package level. @zintrust/workers now records completed and failed recent-job history for both BullMQ event-driven workers and pull/dequeue-ack workers using the shared @zintrust/queue-monitor metrics contract, and @zintrust/queue-redis now finalizes acked pulled jobs as completed instead of deleting them immediately so Recent Jobs fallback queries can still see them.

  • Hardened the unified socket compatibility surface so POST /broadcasting/auth is now framework-owned by default with configurable auth middleware, strict default authorization for private-* and presence-* channels, optional application takeover behind SOCKET_ALLOW_AUTH_ROUTE_OVERRIDE=true, startup-fatal reserved-route conflict detection instead of silent app-route shadowing, and a new project-level broadcast.socket.publish policy hook that can approve, reject, or rewrite server-side publish requests before fan-out.

  • Fixed the shared @zintrust/core/start Cloudflare entry so lazy worker imports now resolve module-namespace default exports correctly instead of falling through to a non-function call path under Wrangler after additional named exports are present.

  • Added a unified optional socket runtime surface for ZinTrust. Core now exposes socket runtime contracts and registry hooks, auto-discovers @zintrust/socket/register, intercepts Node upgrade requests and Worker websocket requests before the HTTP adapter path, and the new @zintrust/socket package provides zero-touch Pusher-compatible upgrade/auth/publish endpoints for local in-memory broadcast flows across Node and Cloudflare runtimes.

  • Relaxed the default zin new ESLint scaffold so freshly generated apps no longer fail on relative imports just because the governance preset prefers ZinTrust path aliases. The governance ESLint preset now exposes an enforcePathAliases switch, and the generated app config disables that rule by default while still using the shared preset.

  • Fixed framework-managed CORS preflight handling so OPTIONS requests now terminate with an empty 204 response instead of leaving browser preflight checks hanging after the status code is set.

  • Added a monolith env-precedence gate for manifest-backed microservices. When RUN_AS_MONOLITH=true, zin start/zin s and manifest route registration now keep root env values authoritative for duplicate keys while still loading service-local env files to fill missing values.

  • Fixed zin start / zin s Node startup so importing @zintrust/core/start no longer eagerly links the Worker, Deno, and Lambda handlers before root env loading completes. The Node start() path now lazy-loads those non-Node runtime handlers, which prevents fresh projects from caching fallback config values too early and restores env-driven features such as /queue-monitor under the CLI start path.

  • Updated fresh project scaffolding to generate a default flat ESLint config backed by @zintrust/governance/eslint, add a default lint script, and place both eslint and @zintrust/governance in devDependencies instead of leaving governance tooling unconfigured by default.

  • Fixed the public @zintrust/core/boot Node startup path so it now loads project env files before importing the stock bootstrap lifecycle, matching the existing CLI/bootstrap env parser behavior instead of starting with fallback defaults when apps use the thin src/boot/bootstrap.ts wrapper directly. The boot entry now also emits one structured warning when no env files were loaded for that Node bootstrap path.

  • Fixed fresh Node startup queue-monitor registration so the runtime now prefers the preloaded project config/queue.ts override from StartupConfigFileRegistry before falling back to cached framework defaults or generated runtime config. This keeps /queue-monitor aligned with the same app-owned queue settings used during startup instead of disappearing when only the fallback config had monitor.enabled=false.

  • Unified Node startup around a shared env-first path so @zintrust/core/start, @zintrust/core/boot, and zin start/zin s no longer rely on separate Node bootstrap wrappers. Root project env files now load through one singleton helper before any bootstrap import, and CLI Node starts run through generated @zintrust/core/start runners instead of executing the project bootstrap file directly.

2026-04-03

  • Fixed package Docker and CI builds so workspace package builds no longer run redundant package-local npm install steps that can trigger npm workspace-filter warnings or unpublished-package resolution failures such as @zintrust/governance in filter set, but no workspace folder present and ETARGET for internal packages. The package build orchestrator now reuses the root workspace install by default and only performs a package-local install when FORCE_PACKAGE_INSTALL=true is explicitly set.
  • Fixed local worker dashboard registration so /workers and /queue-monitor now mount in the normal Node runtime even when WORKER_ENABLED=false, while worker execution-only RPC gateways still stay disabled until worker mode is explicitly enabled. Also reduced noisy D1 lifecycle logging to debug level and stopped the System Trace query watcher from recording its own zin_trace_* storage SQL.
  • Fixed Queue Monitor live dashboard stability. @zintrust/queue-monitor can now merge a stable knownQueues inventory into snapshots, the core runtime now feeds that inventory from persisted worker records, per-client SSE polling no longer shares queue selection across subscribers, and the dashboard preserves the selected queue while automatically hard-resetting the page only after the stream stays stale long enough to get out of sync.
  • Improved ORM relation-bootstrap diagnostics so model methods that touch the database during Model.define(...) now emit one structured warning with the model table, relation name, and first probable user-code source frame instead of repeated generic Database connection 'default' is not registered noise. Added opt-in ZINTRUST_DEBUG_RELATIONS=1 tracing for per-relation bootstrap probes.
  • Fixed published package compatibility between @zintrust/core and @zintrust/workers. The generated dist/package.json for core now pins workspace package dependencies like @zintrust/workers to the exact released version instead of a floating caret range, preventing older published core releases from resolving a newer workers patch with a stricter peer requirement. The workers package release sync now also keeps its @zintrust/core peer compatible across the active 0.4.x line so npm install -g @zintrust/core and similar fresh installs do not fail with ETARGET when workers is published ahead of core.

2026-04-02

  • Fixed @zintrust/trace migration packaging so the published package now exports runnable JavaScript migrations from ./migrations instead of relying on TypeScript files in node_modules. The core trace migration command now resolves trace migrations as a package target with an explicit extension, prefers built JS when available, and fails with a packaging-specific error if an installed trace package still exposes TS-only migrations.
  • Split @zintrust/trace activation so plugin/bootstrap loading now registers runtime watchers only, while dashboard UI/routes are an explicit route-level opt-in. Added registerTraceDashboard(router, options) for the common routes/api.ts case, added a lightweight @zintrust/trace/ui export so route code does not need to import the package root re-export surface, removed the stock core auto-mount behavior, and clarified trace route exposure in the CLI/package docs.
  • Added a dedicated npm run lint:strict script and switched CI/publish verification to it so the repository no longer relies on the deprecated npm run lint --max-warnings=0 form that newer npm versions warn about. Use npm run lint:strict or npm run lint -- --max-warnings=0 for zero-warning ESLint runs.
  • Fixed the pre-build npm workspace install topology for unpublished core versions. The root package-lock.json now keeps the local @zintrust/core links pointed at the repository root package instead of dist, the dist lock entry stays version-synced with the root package metadata, and scripts/release/sync-package-versions.mjs --check now fails if either lockfile edge drifts. This prevents npm ci --ignore-scripts from fetching an unpublished @zintrust/core@^... and failing release/CI installs with ETARGET.
  • Added a Model.with(relations) static shorthand on defined models so developers have three equivalent eager-loading signatures: Model.with(['rel1', 'rel2']) (array shorthand that starts a fresh query), Model.query().with('rel1').with('rel2') (chained), and Model.query().with({ rel1: constraint, rel2: constraint }) (constrained object). Updated the eager loading section in docs/models.md with examples of all three signatures.

2026-04-01

  • Added stable outbound trace source names for core HTTP integrations such as termii, twilio, slack, sendgrid, mailgun, ses, s3, and pusher, and extended watchers.clientRequest config so projects can include, exclude, or fully disable specific outbound sources as well as suppress selected request/response sections per source.
  • Replaced regex-based query redaction and stack-frame parsing in @zintrust/trace with deterministic scanners so CodeQL no longer flags ReDoS-prone handling on trace query strings, exception traces, or job failure traces. Also re-synced the trace/default database connection fallback so literal DB_CONNECTION=default resolves to the active runtime default connection while TRACE_DB_CONNECTION still overrides trace migrations and runtime storage when explicitly set.
  • Hardened ORM eager loading so belongsTo now batches on the parent foreign key and related owner key, belongsToMany follows the pivot-join resolution path during eager loading, and lazy-vs-eager parity coverage now spans standard, polymorphic, and through relations plus withCount(...) support for the currently counted relation types.
  • Fixed core ORM hydration and model-instance write semantics so first() and firstOrFail() now return hydrated models like get() and paginate(), raw hydrate(...) no longer re-runs mutators on stored values, and save() now persists model-instance inserts and dirty updates through the query builder with mutator-transformed values intact.
  • Added a reusable core Wrangler local-dev env materialization path driven by .zintrust.json Cloudflare env groups. ZinTrust can now generate manifest-scoped .dev.vars files for Workers through the CLI, and the Wrangler start flow reuses the same resolver instead of maintaining a separate transient-only implementation.
  • Added a dedicated zin wrangler:dev-vars command so Cloudflare local-dev env generation is available as a first-class CLI workflow instead of only as a prepare option.
  • Tightened the @zintrust/trace request-context bridge so trace batching, auth-tag correlation, and route filtering now read the live request context synchronously during runtime hooks. The trace now skips its own /trace/* traffic across watcher emissions instead of recursively recording dashboard requests, SQL writes, and related log noise.
  • Improved the inline @zintrust/trace entry detail views so structured JSON payloads and SQL statements render with type-aware syntax colors plus one-click copy actions, and surfaced execution duration more consistently across request, query, outbound HTTP, and other timed trace entries.
  • Refreshed the inline @zintrust/trace dashboard shell to match the rest of the ZinTrust admin UI more closely: it now uses the shared Inter-based dashboard font stack, swaps the old sidebar-heavy Telescope note for a responsive header-plus-tabs layout, embeds the docs-website/brand/prism-shield-pulse-core.svg mark as the visible logo and favicon, and adds built-in light/dark mode support for the trace experience.
  • Fixed the plugin-driven @zintrust/trace boot path so it no longer recurses back through getKernel() while the application is already booting. ZinTrust now queues trace global middleware registrations through the kernel itself, which prevents repeated Database connection 'default' is not registered noise during Worker reloads and keeps the optional trace package buildable again after the logger/watcher import cleanup.
  • Fixed the trace connection fallback so both the core auto-mount path and @zintrust/trace/register now inherit the app's active DB_CONNECTION when TRACE_DB_CONNECTION is omitted, instead of forcing the literal registry key default. This restores the documented TRACE_ENABLED=true local setup for D1-backed Worker apps and avoids the old Requesting connection: default failure path.
  • Updated @zintrust/trace setup guidance so the supported activation path now goes through src/zintrust.plugins.ts and src/zintrust.plugins.wg.ts via @zintrust/trace/plugin, instead of telling developers to wire trace bootstrap imports into ad hoc start files. The core runtime now only lazy-mounts the trace dashboard after that explicit plugin opt-in is present, and the inline dashboard shell was refreshed toward a lighter request-trace layout while removing the broken showPage inline-handler bug.

2026-03-31

  • Added first-class optional CLI registration for @zintrust/trace, including zin migrate:trace, zin trace:status, zin trace:prune, and zin trace:clear, and wired the stock runtime boot path to auto-mount the trace dashboard when TRACE_ENABLED=true so the package can be enabled and inspected live without hand-editing the example app routes.
  • Added a packed Cloudflare secret compatibility mode to the core env surface. When USE_PACK=true, ZinTrust now expands JSON secret bindings listed in PACK_KEYS into the resolved Env.get(...) view, keeps direct env values above packed values, tracks the winning source for diagnostics, and auto-loads local .env.pack files for Node-side development without overriding the direct control keys.
  • Extended the Cloudflare shared-env manifest workflow so deploy commands now reuse the same target-aware secret selection as zin put cloudflare, letting zin deploy, zin deploy d1-proxy, zin deploy kv-proxy, and zin deploy:ccp sync selected Worker secrets automatically before wrangler deploy unless --no-sync-secrets is passed.
  • Updated microservice scaffolding so new services automatically register their canonical domain/name ID under .zintrust.json -> cloudflare.targets, keeping service-specific Cloudflare secret selection aligned with the generated runtime manifest and service-local Worker config.

2026-04-06

  • Updated scripts/release/sync-package-versions.mjs so CI can opt into --bump-root-to-next, which advances the root package.json version to the next published patch line when needed and pins non-local @zintrust/* dependency specs to the live npm versions while preserving package-local file: links.
  • Reworked the npm-based GitHub workflows to stop failing fast on sync-package-versions.mjs --check. CI, smoke, SonarQube, and security jobs now self-heal by running the sync script plus npm install --package-lock-only --ignore-scripts before npm ci, while the publish workflow refreshes workspace metadata without auto-bumping the publish line.

2026-03-30

  • Added a first-class Cloudflare env-target manifest shape to fresh .zintrust.json scaffolds via cloudflare.shared_env, cloudflare.targets, and cloudflare.wrangler_envs, then wired that manifest into zin put and local zin s --wg snapshots. Fresh projects can now keep one canonical shared secret list plus additive per-target keys, and Wrangler dev no longer needs to dump every loaded env var into every Worker by default.
  • Fixed the zin init:container-workers scaffold so the generated docker-compose.workers.yml keeps WORKER_ENABLED and WORKER_AUTO_START correctly indented inside the workers-api.environment list. This prevents malformed compose output in freshly scaffolded worker container setups.

2026-03-29

  • Fixed the Cloudflare Containers proxy gateway so it now routes both the documented public service prefixes such as /redis/* and the internal ZinTrust proxy paths such as /zin/redis/command to the correct backend container. This prevents Worker startup and auth flows from failing with Redis proxy request failed (404) when a caller reaches the gateway using the raw proxy path.

  • Fixed the release -> master Release PR patch-bump flow so scripts/ci/bump-version.js --apply no longer calls npm install --package-lock-only after bumping to an unpublished workspace version. scripts/release/sync-package-versions.mjs now keeps workspace package manifests and the matching package-lock.json entries in exact lockstep with the core version, which prevents the CI ETARGET No matching version found for @zintrust/core@^... failure during automated release PR bumps.

  • Updated the active dependency-maintenance line on dev by bumping the root ranges for @cloudflare/containers, @faker-js/faker, @types/pg, eslint, miniflare, mongodb, mssql, and typescript-eslint, syncing the Cloudflare Containers proxy workspace package to @cloudflare/containers@^0.2.0 plus newer Workers types, and refreshing pinned GitHub Actions SHAs for actions/checkout, docker/login-action, TruffleHog, and CodeQL. The TypeScript 6.0.2 bump was intentionally left out because typescript-eslint@8.57.2 still requires typescript < 6.0.0 in this repo.

  • Fixed Docker release builds so they keep DIST_SKIP_NPM_VERSION_CHECK=true during the builder stage. This prevents the dist package manifest and build banner from auto-advancing past the published release line during local and CI image builds.

  • Extended the release version sync flow so it now updates and validates root package.json dependencies on workspace packages alongside the workspace manifests themselves. This keeps package-lock.json aligned for npm ci consumers such as the Docker image build, preventing release lines like 0.4.34 from publishing packages successfully while the container build still resolves an older internal package range.

  • Updated Queue Monitor middleware validation so QUEUE_MONITOR_MIDDLEWARE now accepts supported dynamic route middleware keys such as rateLimit:1000:1, then documented that env usage in the queue docs.

  • Hardened the automated release bump flow so scripts/ci/bump-version.js --apply now re-syncs workspace package versions and refreshes the root lockfile immediately after bumping core, and the release PR workflow now commits those workspace manifest updates too. This prevents the workspace version sync CI gate from failing on freshly bumped release branches.

  • Re-synced all workspace package versions, @zintrust/core peer ranges, and the root package-lock.json to 0.4.33 after publish so the node scripts/release/sync-package-versions.mjs --check CI gate stays green for the new release line.

  • Documented the Queue Monitor env surface more clearly, including that QUEUE_MONITOR_MIDDLEWARE is the env key for protecting the dashboard with registered route middleware keys such as auth or auth,jwt, and that invalid keys fail config loading.

  • Expanded the middleware docs to show inline route rate-limit keys alongside the existing RateLimiter.create() registration pattern, and added focused middleware key tests so malformed rateLimit:<max>:<windowInMinutes> strings are rejected while valid parameterized keys remain accepted.

  • Added parameterized route middleware support for rate limiting, so routes can now declare inline keys such as rateLimit:6:1 or rateLimit:100:0.4 and get a lazily created RateLimiter instance without pre-registering a separate middleware name.

  • Synced all workspace package versions and @zintrust/core peer ranges to 0.4.32, regenerated the root lockfile, and added a pre-npm ci workspace-version check in every npm-based CI workflow so package/version drift fails fast with a direct error instead of an ERESOLVE install failure.

  • Updated the fresh project scaffold to generate src/boot/bootstrap.ts as a thin @zintrust/core/boot wrapper, so new apps can reuse the stock ZinTrust Node/Docker bootstrap lifecycle without copying the full core bootstrap source.

  • Published a stable @zintrust/core/boot subpath backed by src/boot.ts so fresh-app and Docker/bootstrap flows can import the side-effect boot entrypoint directly instead of relying on internal @boot/* aliases.

  • Updated the Wrangler-backed zin proxy:d1 and zin proxy:kv commands to accept --port <port> and forward it to wrangler dev, so local Cloudflare proxy Workers can be started on an explicit port like zin proxy:d1 --port 8787.

  • Bumped @zintrust/core to 0.4.31 for the proxy CLI consumer-app fix after correcting both the published scaffold output and the core proxy runtime exports.

  • Updated the generated D1 and KV proxy Worker shims plus the developer docs to use the stable @zintrust/core/proxy export surface instead of nested proxy subpath imports, which fixes fresh consumer apps where Wrangler could not resolve @zintrust/core/proxy/d1/ZintrustD1Proxy or @zintrust/core/proxy/kv/ZintrustKvProxy during local dev.

  • Replaced the core ZintrustD1Proxy and ZintrustKvProxy exports with built-in Worker handlers instead of optional package loaders, which fixes fresh apps that previously failed at runtime with Optional dependency not installed: @zintrust/cloudflare-d1-proxy or the KV equivalent.

  • Updated the zin proxy:d1 scaffold so the generated env.d1-proxy block now includes a commented Wrangler custom-domain route example for d1-proxy.example.com, matching the existing proxy scaffold guidance style.

  • Updated the zin proxy:kv scaffold so the generated env.kv-proxy block now includes a commented Wrangler custom-domain route example for kv-proxy.example.com, matching the existing proxy scaffold guidance style.

2026-03-28

  • Fixed the package release flow for published adapters/packages so it now runs the same ESM relative-import repair and package artifact post-processing used by the normal package builder before publishing, which prevents broken extensionless imports such as the @zintrust/queue-monitor Docker startup failure on fresh installs.
  • Updated zin new --with-d1-proxy so it no longer scaffolds the stale standalone @zintrust/cloudflare-d1-proxy dependency into fresh apps and instead points developers at the supported core entrypoint plus zin proxy:d1 and zin deploy d1-proxy workflow.
  • Added zin proxy:d1 for local D1 proxy development. The command now scaffolds env.d1-proxy into wrangler.jsonc when missing, then starts local Wrangler dev against the core D1 proxy entrypoint, and the docs now point developers to @zintrust/core/proxy/d1/ZintrustD1Proxy.
  • Added zin proxy:kv for local KV proxy development. The command now scaffolds env.kv-proxy into wrangler.jsonc when missing, then starts local Wrangler dev against the core KV proxy entrypoint, and the docs now point developers to @zintrust/core/proxy/kv/ZintrustKvProxy.
  • Updated the Cloudflare proxy docs so the D1, KV, and Containers package pages plus the D1/KV remote guides now show the supported ZinTrust deploy CLI and local dev CLI commands directly after installation/setup, and corrected the D1/KV package pages to reflect that those Worker packages are currently deployed from the repo rather than installed as public npm packages.
  • Updated the container worker scaffold again so docker-compose.workers.yml now boots a single bootstrap-driven workers-api service that serves the worker pages and auto-starts eligible workers in the same process, replacing the previous split workers-api plus worker-runner default.
  • Updated @zintrust/workers so worker discovery can fall back to project worker files when persistence is empty, which lets fresh projects surface worker metadata and details without first creating worker rows in the database.
  • Added an explicit workerDefinition starter worker template for fresh apps, extended worker auto-start to use file-backed definitions only when persisted auto-start candidates are absent, and documented direct zin migrate:worker --connection <name> usage for D1-backed worker persistence.
  • Added an optional src/zintrust.workers.ts project worker bootstrap file for fresh apps, and updated Docker/worker startup so the worker image and worker:start-all can auto-load that entrypoint while also falling back to file-backed worker definitions when persisted worker rows are absent.
  • Updated the container worker scaffold to generate a dedicated Dockerfile.workers overlay image that builds fresh projects with npm run build, then layers compiled worker artifacts onto the published zintrust/zintrust base image so developers can use either app/Workers discovery or an optional src/zintrust.workers.ts entrypoint.

2026-03-27

  • Updated the container worker scaffold so generated database password env vars no longer ship with an insecure hard-coded secret fallback, which removes the Sonar new-code security finding on the release PR while keeping password values configurable through project env files.
  • Updated the basic app scaffold to include the published @zintrust/d1-migrator package by default so fresh projects keep the zin migrate-to-d1 command available without a separate manual install, and clarified the CLI reference to match the optional-package auto-registration flow.

2026-03-26

  • Verified the Cloudflare Workers auth and jwt failure path keeps the default 401 contract by default and honors project responder overrides for custom status/body output, then added a focused regression test covering both cases.
  • Updated the auth-response verification note and middleware failure override docs so they reflect the current @zintrust/core@0.4.22 API surface and the supported responder-based customization path.

2026-03-23

  • Added Microservices Runtime Guide to document the generated manifest, runtime hook files, canonical service IDs, standalone service boot, and layered config overrides.
  • Clarified that generated services use routes/api.ts and src/bootstrap/service-manifest.ts as the main runtime entry files developers work with.
  • Documented the current implementation status: manifest-based route mounting is in place, standalone Node config layering has started, and Worker-specific service-local config integration is still being extended.
  • Documented that scaffolded microservices now generate their own wrangler.jsonc, with service-owned aliases kept local and root-owned aliases mapped back to the root project.
  • Clarified terminology in the developer docs so Cloudflare Worker runtime, generic serverless runtime, and ZinTrust background workers are described explicitly instead of all being shortened to “worker”.
  • Extended that terminology cleanup into broader developer docs including cloud deployment, architecture, worker management, and helpers so Cloudflare Worker runtime and ZinTrust background workers are not conflated.
  • Updated the runtime guide to state explicitly that standalone microservice boot code lives in the microservice src/index.ts, replaced internal-sounding headings like Current behavior and Current Limits, and rewrote the remaining runtime work section in developer-facing terms.
  • Implemented scaffolded Cloudflare Worker / serverless service-local startup config merging so generated microservice wrangler.jsonc files keep root config aliases pointing at the root app while also exposing optional service-local config aliases for layered overrides.
  • Moved scaffolded standalone microservice boot ownership into a first-class core start helper so generated service entrypoints delegate runtime setup to framework code instead of hand-wiring ProjectRuntime.set(...) themselves.
  • Updated generated runtime hook and service manifest files so the built CLI can import source-owned runtime metadata in consumer apps without failing on extensionless local imports, which fixes manifest-backed zin routes loading and standalone service boot in freshly scaffolded projects.
  • Refreshed the maintainer-facing scaffold runtime fix process note so it documents the implemented core behavior, the dist-package consumer validation, and the remaining need for legacy generated-file normalization.
  • Updated CLI service-directory startup env loading so root .env* files load first and service-local .env* files override them, and added clearer developer guidance for the missing tsx runtime dependency during standalone microservice starts.
  • Added monolith-only manifest route prefixes for microservices so standalone services keep their native paths while monolith mounting defaults each service to /<domain>/<name> unless the manifest overrides the prefix.
  • Updated official runtime plugin auto-imports so missing optional ZinTrust adapter packages no longer raise a startup warning in consumer apps, while genuinely broken installed plugin register modules still surface as failures.
  • Added explicit standalone microservice env controls so bootStandaloneService() and zin s can keep root env loading enabled by default, skip it with rootEnv: false or --no-root-env, and override the inferred microservice env source with envPath or --env-path.
  • Upgraded simulate/fresh-check into a generated-style standalone microservice fixture with src/bootstrap/service-manifest.ts, src/zintrust.runtime*.ts, and a focused simulation test that verifies root .env loading plus service-local .env overrides from a service-directory context.
  • Fixed three runtime regressions in the startup path: root monolith starts now preload service-local .env files with service values overriding root duplicates, service-directory zin s now boots the standalone service instead of short-circuiting on partially cached runtime metadata, and Worker startup now avoids eager non-default database instantiation that previously triggered Cloudflare PostgreSQL socket failures during boot.
  • Fixed the remaining standalone Worker env propagation gap so zin s --wg from a microservice directory now injects the merged root-plus-service env set into Wrangler dev bindings, allowing Worker routes to see root values and service overrides consistently in both Env.get(...) and static Env.* reads.
  • Added a per-service loadEnv manifest flag so monolith startup can mount a microservice while explicitly skipping that service's local .env* preload layer.
  • Updated service scaffolding guidance and generated manifest entries to default mounted services to loadEnv: false, avoiding monolith root/global env merging unless developers opt in explicitly.
  • Updated startup so official runtime plugin auto-import failure warnings are only emitted in Docker worker mode, which prevents noisy zin s and freshly scaffolded project flows from showing Loaded 0/16 official plugin imports during normal local development.
  • Added d1 as a first-class zin new database option alongside d1-proxy, so the interactive database list now includes direct Cloudflare D1 as well as the HTTPS proxy mode.
  • Updated zin new project scaffolding so generated .gitignore files include .dev*, which keeps temporary Wrangler-style dev variable files out of git by default.
  • Fixed manifest-backed microservice route loading in zin s --wg for generated apps by generating src/zintrust.plugins.wg.ts with the required ProjectRuntime.set({ serviceManifest }) seed automatically, so developers no longer need to add that block by hand in fresh projects.
  • Fixed zin s --wg startup in fresh projects when the optional @zintrust/workers package is not installed, so Cloudflare/Wrangler No such module "@zintrust/workers" failures now fall back to the disabled worker runtime instead of aborting app boot.
  • Corrected the newstart Worker entry example so it re-exports the core Cloudflare handler instead of calling getKernel() before Worker bindings are initialized; middleware in fresh apps should stay registered through config/middleware.ts and route metadata rather than custom Worker bootstrap wrappers.
  • Updated zin s --wg to force WORKER_ENABLED=false, which prevents background worker package initialization in Wrangler dev even if a custom Worker entrypoint is written incorrectly, and added a start-time warning when src/index.ts calls getKernel() before the core Cloudflare handler.
  • Added project-level custom middleware registration support through config/middleware.ts, updated the middleware docs with the full fresh-app flow, and made zin add middleware <Name> generate and register a route middleware skeleton automatically.
  • Fixed standalone zin s --wg from src/services/<domain>/<name> so it now prefers service-local port env vars like <SERVICE_NAME>_PORT and no longer falls back to a conflicting root APP_PORT; newly scaffolded services now also write APP_PORT, PORT, and SERVICE_PORT into their local .env files.

2026-03-25

  • Merged the typed middleware registry guide into docs/middleware.md so middleware usage, project registration, typed route keys, and governance test guidance now live in one canonical page, and updated the docs site navigation to point at that single doc.
  • Updated JSON request error handling so NotFoundError stacks are still logged server-side but no longer returned in API error payloads.
  • Blocked accidental root-package npm publish so releases fail fast unless they publish the compiled dist package, which fixes the broken global CLI install path where source bin entries tried to resolve aliases like @config/logger at runtime.
  • Updated zin docker to reuse one deterministic .dev.vars*.disabled-by-zin backup per file and remove legacy UUID-suffixed backups automatically, so repeated Docker/Wrangler dev runs no longer keep accumulating stale backup files.
  • Updated request-body XSS sanitization to strip markup without HTML-encoding opaque JSON payload characters like / and =, which preserves base64 and signed token inputs in fresh apps while keeping output escaping in the HTML render layer.
  • Documented and scaffolded the plug-and-play built-in middleware override path for fresh apps, including overriding keys like jwt in config/middleware.ts so developers can customize default auth error payloads without changing route metadata.
  • Updated core middleware assembly so built-in keyed overrides now apply consistently to both route resolution and the shared global middleware slots, making fresh-app plug-and-play overrides factual for framework-owned middleware keys instead of only route-local keys.
  • Added a first-class middleware responder contract for response-writing built-ins so fresh apps can customize default auth, CSRF, rate-limit, validation, and JSON error payloads through config/middleware.ts without replacing the underlying middleware logic.
  • Refreshed vulnerable transitive dependencies so the workspace now resolves picomatch to patched 2.3.2 and 4.0.4 releases and yaml to 2.8.3, clearing the reported npm audit advisories without changing the top-level dependency API.
  • Fixed two Workers DX regressions that previously forced repository-level core patching in fresh apps: SecurityMiddleware.create() now derives default CORS behavior from securityConfig.cors instead of hard-coded values, and the Cloudflare response bridge now preserves middleware-set HTTP status codes when the framework response wrapper writes to res.statusCode.
  • Fixed the Worker startup-config loader so fresh-app overrides from config/middleware.ts are bundled and applied in live zin s --wg runs, which restores app-owned auth/jwt responder customization, and added OPTIONS path fallback routing so global security middleware can answer CORS preflights even when a route only exists under other HTTP methods.
  • Updated core auth/jwt built-in unauthorized fallback bodies to ship a structured { error: { code, message } } contract by default, and fixed @zintrust/queue-redis package builds to normalize dist ESM imports before publish so clean installs no longer depend on downstream rewrite scripts.
  • Split the default middleware failure body helper into a dedicated middleware body module so editor/type-service resolution stays stable when auth and jwt middleware import the structured fallback body factory.
  • Updated @zintrust/queue-redis to publish against a semver peer on @zintrust/core while keeping a local file:../../dist dev dependency, so package-local work still uses the local core build but clean tarball installs resolve like published consumers.

Released under the MIT License.