Files
fusion/plugins/fusion-plugin-cli-printing-press
gsxdsm 5ae6332563 refactor: collapse dead SQLite dual-path code; keep migration-only readers (#2454)
# Remove dead SQLite dual-path code; keep migration-only readers

## Summary
PostgreSQL cutover left hundreds of production dual-path branches
(`backendMode ? PG : SQLite/store.db`) whose SQLite arms only hit
throwing `Database`/`ArchiveDatabase`/`CentralDatabase` stubs. This
change mechanically collapses those unreachable arms so production
authority is AsyncDataLayer/PostgreSQL only, while preserving the six
authorized read-only migration/recovery `DatabaseSync` seams.

## Dual-path mass removed
| Metric | Before | After |
|---|---|---|
| `if (…backendMode)` (non-test) | ~328 | ~70 |
| `store.db` / `this.db` refs in core (non-test) | ~570+ | ~375 (mostly
pure legacy MissionStore/eval/insight SQLite classes + thin getters) |
| Net diff | — | **~6.7k lines removed** across 41 files |

Remaining `backendMode` checks are intentional (incomplete-PG sync
safe-defaults, settings-sync disabled-on-PG, symbol-lock PG-only gates,
“requires PostgreSQL” config versioning throws), not live SQLite
authority.

## Subsystems cleaned
- **Core TaskStore / task-store/***: collapsed if/else and early-return
dual-path across reads, moves, lifecycle, mutations, workflow, archive,
branch/PR, artifacts, comments, audit, project ops, etc. `initImpl` is
PostgreSQL-only (SQLite startup tail deleted).
- **Satellite stores**: automation, agent, routine, plugin, secrets,
approval-request, central-core dual-path arms collapsed.
- **Plugins**: reports async methods, compound-engineering pipeline +
session stores, CLI Printing Press store — SQLite fallbacks removed; PG
required.
- **Engine**: no functional dual-path change beyond whitespace
(settings-sync / peer-exchange PG-disabled behavior kept).

## Six migration-only readers retained (allowlist unchanged)
1. `packages/core/src/postgres/sqlite-migrator.ts`
2. `packages/core/src/project-identity.ts`
3. `packages/core/src/sqlite-validation.ts`
4. `packages/core/src/postgres/startup-factory.ts`
5. `packages/cli/src/commands/db.ts`
6. `scripts/lib/start-local-project.mjs`

Plus low-level `sqlite-adapter` and migrator/startup-import tests.
Inventory ratchet still requires exactly these six `new DatabaseSync(`
production sites, all `readOnly: true`.

## Not treated as SQLite
- `.fusion/project.json`, `task.json`, `agent-log.jsonl` file storage
- AsyncDataLayer / Drizzle PG paths
- Incomplete-PG sync safe-default stubs (still return empty/false/null
under backend without consulting SQLite)

## Verification
- `sqlite-production-reader-inventory.test.ts` — 15/15 pass
- `incomplete-pg-ports.pg.test.ts` — 6/6 pass
- Targeted PG tests (create-task, move, handoff, runtime-persistence,
agent, mission, insight, central-core) — green
- `tsc --noEmit` for `@fusion/core`, `@fusion/engine`,
`@fusion/dashboard` — green
- `scripts/check-no-getdatabase.mjs` — clean

<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit

* **Improvements**
* Improved end-to-end consistency by making PostgreSQL/async persistence
the standard across core task/workflow, automation, agents, plugins,
routines, secrets, approvals, central operations, and session storage.
* Unified scheduling, settings, configuration revision writes,
run/workflow selection, queues/leases/transitions, and audit/lifecycle
updates around consistent async transaction behavior.
* **Bug Fixes**
* Fixed edge cases for archived/deleted reads, unarchive/recovery flows,
not-found handling, and task/artifact/document/log/comment operations,
including more reliable emissions and hydration across search/list and
lifecycle operations.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
2026-07-26 23:28:42 -07:00
..
2026-07-26 18:11:47 -07:00
2026-07-26 18:11:47 -07:00

fusion-plugin-cli-printing-press

Bundled first-party Fusion plugin for generating and managing service CLIs.

Storage & Config Model

Tables

  • cli_press_services: service metadata (id, slug, displayName, description, baseUrl, sourceKind, sourceRef, timestamps)
  • cli_press_cli_specs: generated/spec inputs per service (id, serviceId, name, version, generatorVersion, specJson, generatedAt, status, lastGenerationError, timestamps)
  • cli_press_artifacts: generated artifact metadata (id, cliSpecId, kind, path, executable, checksum, sizeBytes, timestamps)
  • cli_press_credentials: non-OAuth credentials (id, serviceId, name, kind, value envelope, placement, timestamps)
  • cli_press_service_settings: service-scoped key/value settings (id, serviceId, key, value, scope, timestamps)

All IDs are UUIDv4-based with prefixes: svc_, cli_, art_, cred_, set_. Timestamps are ISO-8601 strings.

Exported Types

  • Service: canonical external-service record
  • CliSpec: persisted cli-printing-press spec/generation state
  • CliArtifact: artifact file metadata (path stored relative to <projectRoot>/.fusion/)
  • Credential: persisted secret envelope + placement metadata
  • CredentialKind: closed union of non-OAuth kinds (api_key, bearer_token, basic_auth, header, query_param, env_var)
  • CredentialPlacement: discriminated placement union
  • ServiceSetting: service-level setting entry (runtime | wizard | metadata)
  • OAuthNotSupportedError: thrown when oauth/oauth2 is passed
  • InvalidCredentialPlacementError: thrown on kind/placement mismatch or invalid api_key placement

Credential placement union

  • { kind: "header", header: string }
  • { kind: "query_param", queryParam: string }
  • { kind: "env_var", envVar: string }
  • { kind: "bearer_token", header: string }
  • { kind: "api_key", header?: string, queryParam?: string } (exactly one required)
  • { kind: "basic_auth", header: string }

Credential encoding/materialization

  • Values are stored as { encoding: "base64", value: string } via encodeCredentialValue/decodeCredentialValue.
  • applyCredentialToRequest materializes credentials into { headers, query, env } and rejects OAuth at runtime.

OAuth policy (deferred)

OAuth/OAuth2 flows are intentionally excluded from v1. Any oauth/oauth2 kind is rejected by store-layer and helper-layer guards with OAuthNotSupportedError. Follow-up remains tracked in FN-3762.

Artifact path convention

Generated artifacts are expected under: <projectRoot>/.fusion/plugins/cli-printing-press/artifacts/<serviceId>/<specId>/<artifactFile>

CliArtifact.path stores the path relative to <projectRoot>/.fusion/.

Deletions and filesystem cleanup

deleteService, deleteSpec, and deleteArtifact remove DB records. v1 intentionally does not remove artifact files from disk; cleanup is deferred to FN-3767.

Executor Runtime Exposure

When the plugin contributes executorRuntimeEnv, executor-spawned task commands receive extra runtime wiring:

  • Generated CLI artifact directories for each service's latest generated spec are prepended to task PATH (deduped, absolute paths only).
  • Credentials with kind: "env_var" are decoded and injected as environment variables for task subprocesses, including executor agent-session subprocesses (for example bash tool commands run inside createFnAgent(...)).
  • Non-env credential kinds (header, query_param, basic_auth, bearer_token, api_key) are intentionally excluded from env injection and remain request-time concerns.

Security model:

  • Runtime env is merged per task (process.env base, plugin env overlay, PATH prepend), without mutating global engine process.env.
  • Secrets are never logged; executor diagnostics only report counts of injected keys/paths.
  • OAuth credentials are rejected defensively if encountered.

To opt out for a service, remove generated artifacts or env-var credentials in the FN-3766-backed service configuration model.