Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
125 commits
Select commit Hold shift + click to select a range
aa292a7
test(integration): require concrete Plugin postgres driver
seonghobae Sep 4, 2026
a8433f1
test(integration): require hosted Plugin production entrypoint
seonghobae Sep 4, 2026
bdd908c
feat(integration): add concrete Plugin postgres driver
seonghobae Sep 4, 2026
7025f52
feat(integration): make hosted Plugin runtime production entrypoint
seonghobae Sep 4, 2026
b695e30
fix(integration): type hosted production starter explicitly
seonghobae Sep 4, 2026
a0b5653
test(integration): require owned postgres dependency evidence
seonghobae Sep 4, 2026
f580d2e
fix(integration): declare owned postgres runtime dependency
seonghobae Sep 4, 2026
d12cb55
chore(integration): adopt hosted runtime envelope repair
seonghobae Sep 4, 2026
85dc8a9
chore(integration): adopt hosted operator authority repair
seonghobae Sep 4, 2026
20f68c8
test(integration): require bounded hosted startup failure
seonghobae Sep 4, 2026
a02e348
fix(integration): bound hosted startup rejection
seonghobae Sep 4, 2026
00dcaad
test(integration): cover hosted entrypoint failure edges
seonghobae Sep 4, 2026
123039b
test(integration): reject incomplete postgres authority
seonghobae Sep 4, 2026
920701c
fix(integration): fence postgres connection authority
seonghobae Sep 4, 2026
6ff78f9
test(integration): reject PostgreSQL URI transport overrides
seonghobae Sep 4, 2026
df8edc2
test(integration): preserve PostgreSQL driver regression fixtures
seonghobae Sep 4, 2026
5790bd2
test(integration): restore exact PostgreSQL query fixture
seonghobae Sep 4, 2026
8f5a6f5
fix(integration): reject PostgreSQL URI transport overrides
seonghobae Sep 4, 2026
38e8edb
test(integration): normalize PostgreSQL authority fixtures
seonghobae Sep 4, 2026
0abdd72
test(integration): restore executable PostgreSQL regression test
seonghobae Sep 4, 2026
9b10a94
test(integration): align PostgreSQL lockfile expectation
seonghobae Sep 4, 2026
f3bc291
fix(integration): include PostgreSQL lockfile importer
seonghobae Sep 4, 2026
b6c1bef
revert(integration): restore exact lockfile before importer repair
seonghobae Sep 4, 2026
de075b0
test(integration): bound PostgreSQL pool lifecycle evidence
seonghobae Sep 4, 2026
733c7f1
fix(integration): bound PostgreSQL pool lifecycle
seonghobae Sep 4, 2026
77bd654
test(integration): cover hostile PostgreSQL error classification
seonghobae Sep 4, 2026
a9e82fc
docs: describe concrete Plugin PostgreSQL runtime
seonghobae Sep 4, 2026
463bfcf
docs: record concrete Plugin PostgreSQL driver
seonghobae Sep 4, 2026
e235a50
test(integration): reject credential-shaped PostgreSQL error classifi…
seonghobae Sep 4, 2026
2c46749
fix(integration): bound PostgreSQL idle-error classifications
seonghobae Sep 4, 2026
931d364
test(integration): reject spoofed SQLSTATE log evidence
seonghobae Sep 4, 2026
f74d417
fix(integration): allowlist retained PostgreSQL SQLSTATE evidence
seonghobae Sep 4, 2026
f2d4267
docs(architecture): bound retained PostgreSQL SQLSTATE evidence
seonghobae Sep 4, 2026
9551b20
docs(changelog): record bounded Plugin SQLSTATE evidence
seonghobae Sep 4, 2026
3d8a4ad
test(integration): fail closed when postgres telemetry sink throws
seonghobae Sep 4, 2026
e7d1d7b
fix(integration): bound postgres telemetry sink failures
seonghobae Sep 4, 2026
0353929
test(integration): require verified PostgreSQL TLS
seonghobae Sep 4, 2026
8ccfb26
fix(integration): require verified PostgreSQL TLS
seonghobae Sep 4, 2026
72515b9
chore(integration): restore test newline
seonghobae Sep 4, 2026
99e3261
docs(architecture): record verified PostgreSQL TLS boundary
seonghobae Sep 4, 2026
9ae8d18
docs(changelog): record verified PostgreSQL TLS
seonghobae Sep 4, 2026
4447567
test(integration): require cleanup on postgres listener registration …
seonghobae Sep 4, 2026
940f2a1
fix(integration): close postgres pool when listener registration fails
seonghobae Sep 4, 2026
d26132d
test(integration): accept awaitable postgres acquisition cleanup
seonghobae Sep 4, 2026
8915c3d
test(integration): require finite PostgreSQL query deadlines
seonghobae Sep 4, 2026
b1c4f38
fix(integration): bound PostgreSQL statement and query execution
seonghobae Sep 4, 2026
2f67ac8
docs(architecture): bound Integration PostgreSQL query execution
seonghobae Sep 4, 2026
9e66cbb
docs(changelog): record finite Plugin PostgreSQL query deadlines
seonghobae Sep 4, 2026
3ddedb8
test(integration): bound PostgreSQL pool constructor failure
seonghobae Sep 4, 2026
c845172
fix(integration): bound PostgreSQL pool constructor failure
seonghobae Sep 4, 2026
808d77f
docs(changelog): record bounded PostgreSQL constructor failure
seonghobae Sep 4, 2026
ffddbf0
test(integration): require PostgreSQL readiness before runtime authority
seonghobae Sep 4, 2026
3eed35d
fix(integration): require PostgreSQL readiness before hosted startup
seonghobae Sep 4, 2026
4067625
test(integration): cover PostgreSQL readiness acceptance
seonghobae Sep 4, 2026
3150693
test(integration): type readiness failure fixture safely
seonghobae Sep 4, 2026
1b20f35
docs(integration): record PostgreSQL readiness acceptance boundary
seonghobae Sep 4, 2026
4b109cc
docs(integration): define PostgreSQL readiness authority boundary
seonghobae Sep 4, 2026
9ed664c
test(integration): freeze accepted postgres query authority
seonghobae Sep 4, 2026
1a36f00
fix(integration): freeze accepted postgres query authority
seonghobae Sep 4, 2026
aacd8e9
docs(changelog): record stable postgres query authority
seonghobae Sep 4, 2026
2234555
style(integration): format postgres method-authority regression
seonghobae Sep 4, 2026
890fae2
test(integration): reject hostile readiness row arrays
seonghobae Sep 4, 2026
7346f57
fix(integration): bound hostile readiness evidence accessors
seonghobae Sep 4, 2026
172ca75
docs(changelog): record bounded readiness evidence access
seonghobae Sep 4, 2026
18c1571
chore(integration): adopt current hosted-runtime parent
seonghobae Sep 4, 2026
95c2318
test(integration): require stable PostgreSQL shutdown authority
seonghobae Sep 4, 2026
0c60653
fix(integration): capture PostgreSQL shutdown authority
seonghobae Sep 4, 2026
7c22132
docs(integration): record stable PostgreSQL shutdown authority
seonghobae Sep 4, 2026
676710c
docs(integration): align PostgreSQL method authority boundary
seonghobae Sep 4, 2026
45b5ad5
test(integration): cover PostgreSQL shutdown capability rejection
seonghobae Sep 4, 2026
c78de4f
fix(integration): repair PostgreSQL frozen-lock importer
seonghobae Sep 5, 2026
0a6fe7b
fix(integration): restore lockfile before importer repair
seonghobae Sep 5, 2026
b8fc4c6
ci(integration): stage atomic lock importer repair
seonghobae Sep 7, 2026
2885874
fix(ci): make lock importer repair workflow executable
seonghobae Sep 7, 2026
9803601
fix(ci): preserve YAML indentation in lock repair
seonghobae Sep 7, 2026
c3cd126
fix(ci): validate self-removal delta before lock publish
seonghobae Sep 7, 2026
45ad598
fix(integration): align PostgreSQL frozen lock importer
github-actions[bot] Sep 7, 2026
069dbd9
test(integration): prove real PostgreSQL TLS acceptance
seonghobae Sep 7, 2026
9dcfebd
test(integration): reject unverifiable PostgreSQL IP authority
seonghobae Sep 7, 2026
46cebfe
fix(integration): reject unverifiable PostgreSQL IP authority
seonghobae Sep 7, 2026
6537f83
fix(integration): isolate PostgreSQL TLS acceptance suites
seonghobae Sep 7, 2026
a55a9bc
test(integration): retain PostgreSQL TLS acceptance regression
github-actions[bot] Sep 7, 2026
d6280b2
docs(integration): record PostgreSQL TLS acceptance boundary
seonghobae Sep 7, 2026
4740637
test(integration): prove credential replay secret authority
seonghobae Sep 7, 2026
6f3dc91
fix(ci): make credential replay repair workflow parseable
seonghobae Sep 7, 2026
547bc2a
fix(ci): repair credential replay acceptance harness
seonghobae Sep 7, 2026
464c212
fix(ci): adapt credential replay repair to full secret-store type con…
seonghobae Sep 7, 2026
2ba1878
fix(ci): execute reviewed replay repair without YAML multiline ambiguity
seonghobae Sep 7, 2026
5593db7
fix(ci): repair Integration runtime type boundary exposed by replay G…
seonghobae Sep 7, 2026
8340efb
fix(ci): adapt replay repair to hosted typecheck evidence
seonghobae Sep 7, 2026
b7131ec
fix(ci): align replay repair with generated fixture indentation
seonghobae Sep 7, 2026
8d1e2d2
fix(ci): repair full Integration suite fixture evidence
seonghobae Sep 7, 2026
7a6beb6
fix(ci): publish replay repair with bounded delta authority
seonghobae Sep 7, 2026
03ad70d
fix(ci): replay immutable verified repair at current ancestry
seonghobae Sep 7, 2026
163109d
fix(ci): include generated regressions in publish delta gate
seonghobae Sep 7, 2026
497bad3
fix(integration): verify credential replay secret evidence
github-actions[bot] Sep 7, 2026
75ad1c0
test(integration): reject credential replay after installation revoca…
seonghobae Sep 7, 2026
a4f92ce
ci(integration): run credential replay revocation regression
seonghobae Sep 7, 2026
96209b3
ci(integration): repair credential replay revocation fence
seonghobae Sep 7, 2026
b1f679a
fix(ci): target replay repair structurally
seonghobae Sep 7, 2026
1c65617
fix(integration): revalidate installation on credential replay
github-actions[bot] Sep 7, 2026
cb22617
ci(integration): format replay revocation repair
seonghobae Sep 7, 2026
773dc24
fix(ci): scope replay formatting to owned TypeScript
seonghobae Sep 7, 2026
a345f82
style(integration): format replay revocation fence
github-actions[bot] Sep 7, 2026
7b1fc46
test(integration): reject credential replay after concurrent revoke
seonghobae Sep 7, 2026
fecaf98
ci(integration): reproduce credential replay revoke race
seonghobae Sep 7, 2026
420689a
ci(integration): verify credential replay revoke repair
seonghobae Sep 7, 2026
afb7720
ci(integration): verify credential replay revoke repair only
seonghobae Sep 7, 2026
e3508eb
fix(integration): revalidate credential replay authority
seonghobae Sep 7, 2026
6aa1723
ci(integration): finalize credential replay revoke fence
seonghobae Sep 7, 2026
056e3da
docs(integration): record credential replay revoke fence
seonghobae Sep 7, 2026
8773460
test(integration): add real Vault PostgreSQL recovery acceptance
seonghobae Sep 7, 2026
0fc4b4b
test(integration): run real Vault PostgreSQL acceptance
seonghobae Sep 7, 2026
e87507f
ci(integration): diagnose acceptance formatting
seonghobae Sep 7, 2026
bc7f3b4
style(integration): format Vault PostgreSQL acceptance
seonghobae Sep 7, 2026
b46086e
ci(integration): remove formatting diagnostic
seonghobae Sep 7, 2026
c873a4c
style(integration): align acceptance test with Prettier
seonghobae Sep 7, 2026
b4b5ce2
ci(integration): isolate Vault PostgreSQL acceptance failure
seonghobae Sep 7, 2026
8eb1043
ci(integration): repair real acceptance formatting
seonghobae Sep 7, 2026
0fbbe54
style(integration): format Vault PostgreSQL acceptance
github-actions[bot] Sep 7, 2026
21b5c20
docs(integration): record Vault PostgreSQL acceptance contract
seonghobae Sep 7, 2026
430a19b
chore(integration): retire Vault PostgreSQL proof workflow
seonghobae Sep 7, 2026
c94caf3
docs(integration): record retained Vault PostgreSQL GREEN
seonghobae Sep 7, 2026
994dcd8
ci(integration): prove PostgreSQL suite expectation repair
seonghobae Sep 8, 2026
39ebec9
test(integration): align PostgreSQL-backed authority expectations
Sep 8, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 8 additions & 4 deletions ARCHITECTURE.md
Original file line number Diff line number Diff line change
Expand Up @@ -53,11 +53,15 @@ The Plugin-owned Vault adapter uses one operator-configured canonical HTTPS Hash

The authenticated Plugin application composition reads only `INTEGRATION_OPERATOR_CONTEXT_SECRET` and the service-owned `INTEGRATION_PLUGIN_VAULT_ORIGIN`, `INTEGRATION_PLUGIN_VAULT_TOKEN`, and `INTEGRATION_PLUGIN_VAULT_MOUNT` configuration names. Generic `PLUGIN_VAULT_*` aliases are not authority. It creates the Vault adapter only behind the existing Integration-owned installation, credential-metadata, and durable replay ports, so signed workspace/user authority and one-time replay consumption remain upstream of credential materialization. Composition failures collapse to one credential-free configuration error rather than reflecting verifier/Vault values.

The hosted Plugin runtime uses only `INTEGRATION_DATABASE_URL` as persistence authority and constructs installation lifecycle, credential metadata, and operator replay adapters over one Integration-owned PostgreSQL pool. A malformed environment or acquired pool fails through one credential-free runtime error; an acquired pool is cleaned up if later composition fails. Runtime shutdown is concurrency-safe and idempotent, and the Nest composition module owns that same runtime so application shutdown closes the pool exactly once. The hosted bootstrap validates its listener port before resource acquisition, creates the PostgreSQL/Vault operator runtime before constructing the HTTP application, registers the operator through the runtime-owning module before `listen`, and closes the runtime on startup failure. This slice accepts an explicit PostgreSQL pool factory rather than borrowing another service's pool or persistence authority; a concrete Integration-owned driver/default deployment factory and real Vault-backed acceptance remain required before hosted credential materialization is production-complete.
The hosted Plugin runtime uses only `INTEGRATION_DATABASE_URL` as persistence authority and constructs installation lifecycle, credential metadata, and operator replay adapters over one Integration-owned PostgreSQL pool. A malformed environment or acquired pool fails through one credential-free runtime error; an acquired pool is cleaned up if later composition fails. Runtime shutdown is concurrency-safe and idempotent, and the Nest composition module owns that same runtime so application shutdown closes the pool exactly once. The hosted bootstrap validates its listener port before resource acquisition, creates the PostgreSQL/Vault operator runtime before constructing the HTTP application, registers the operator through the runtime-owning module before `listen`, and closes the runtime on startup failure.

The concrete Integration PostgreSQL driver accepts only a self-contained `postgres:` or `postgresql:` URI with explicit user, password, host, port, and database and with no query string or fragment. This prevents node-postgres from filling missing target/credential authority from generic libpq-style process settings and prevents URI options from replacing deployment transport policy. The Pool separately requires TLS with certificate verification (`ssl.rejectUnauthorized=true`) through Node's configured trust store, so URI input cannot downgrade transport or substitute its own SSL policy. Pool ownership is explicit and finite: maximum 10 clients, 5-second connection-acquisition timeout, 5-second PostgreSQL `statement_timeout`, 6-second node-postgres `query_timeout`, 30-second idle timeout, and 300-second maximum client lifetime. The client timeout is intentionally longer than the server statement limit so normal server-side cancellation has a bounded interval to reach the caller before the client call itself fails closed. The driver captures both `query` and `end` exactly once while acquiring the Pool; readiness and accepted SQL share the captured query authority, while acquisition rollback and runtime shutdown share the captured cleanup authority, so stateful accessors cannot replace either capability after the resource crosses the boundary. An idle-client `error` listener is registered before the first database probe. Pool construction alone is not accepted as database authority because node-postgres establishes clients lazily: before the Pool reaches hosted adapters, the driver executes the fixed `SELECT 1 AS integration_plugin_runtime_ready` statement and requires exactly one row with the canonical readiness marker. DNS, TLS, authentication, query, malformed-result, or cleanup failures are reduced to the same credential-free configuration error and any acquired Pool is closed before startup can proceed. Idle diagnostics retain only `Error`/`DatabaseError` names plus an explicit PostgreSQL operational SQLSTATE subset needed for pool-health diagnosis—connection exceptions (08), insufficient resources (53), operator intervention (57), and external system errors (58); every other code is discarded rather than trusting a five-character shape. Native messages and connection material are never retained. These source-level readiness semantics, numeric limits, diagnostic allowlist, method-authority capture, and TLS setting are not protected-lineage database acceptance proof; real PostgreSQL load, migration state, statement/query-timeout behavior, connection limits, certificate/hostname failure, handshake, and p95 evidence remain required and can require a reviewed change.

The default Integration entrypoint composes that driver with the hosted Plugin runtime and consumes startup rejection as one credential-free nonzero process failure. A source-level driver and bounded control-flow evidence do not make hosted credential materialization production-complete: the service manifest and frozen lockfile must agree, and real PostgreSQL + Vault acceptance must prove migrations, startup/shutdown, Pool behavior, and verified TLS behavior on protected lineage.

The integration service separately owns `life-os.plugin-delivery-origin.v1` grants that bind one opaque grant ID to an exact installation, workspace, granting user, and normalized HTTPS origin. Grant creation requires active host-owned installation evidence. PostgreSQL grant admission rechecks that lifecycle at INSERT and serializes it against installation revocation. Every read that would expose an active origin grant re-resolves exact installation/workspace/user authority and requires the installation to remain active, so installation revocation fences future use of the origin grant. Revoked grant records remain readable as bounded lifecycle/audit evidence inside their original scope. Grant and installation chronology must also be internally consistent.

Neither credential binding nor origin-grant persistence performs outbound plugin delivery. The Vault adapter, authenticated application composition, and injected-factory hosted runtime are active implementation slices, but hosted credential materialization is not production-complete until the Integration service owns a concrete PostgreSQL driver/default deployment composition and proves the full path against a real Vault on protected lineage. Outbound plugin delivery additionally requires separately reviewed DNS/IP rebinding resistance, connect-time address enforcement, redirect/proxy policy, bounded request/response sizes and phase/total deadlines, retry/dead-letter behavior, revocation fencing, and durable delivery outcome evidence. An origin grant or opaque secret reference alone never implies those capabilities.
Neither credential binding nor origin-grant persistence performs outbound plugin delivery. The Vault adapter, authenticated application composition, hosted runtime, and concrete PostgreSQL/default-entrypoint slice are active implementation slices, but hosted credential materialization remains unshipped until frozen-lock reproducibility and real PostgreSQL/Vault/TLS acceptance integrate through protected lineage. Outbound plugin delivery additionally requires separately reviewed DNS/IP rebinding resistance, connect-time address enforcement, redirect/proxy policy, bounded request/response sizes and phase/total deadlines, retry/dead-letter behavior, revocation fencing, and durable delivery outcome evidence. An origin grant or opaque secret reference alone never implies those capabilities.

## 2. AI proposal safety boundary

Expand Down Expand Up @@ -88,7 +92,7 @@ Production contextual-orchestrator proposal requests send `orchestration_mode: a

## 3. Test-time compute and live conformance

The deterministic proposal evaluator is authoritative for proposal validity, operation conformance, grounding, benign utility, forbidden-text leakage, and prompt-injection resistance. Live provider execution is governance evidence and is not a pull-request availability gate.
The deterministic proposal evaluator is authoritative for proposal validity, semantic operation conformance, evidence grounding, benign utility, forbidden-text leakage, and prompt-injection resistance. Live provider execution is governance evidence and is not a pull-request availability gate.

```mermaid
flowchart TB
Expand Down Expand Up @@ -146,4 +150,4 @@ The pinned OpenCode configuration disables project-local overrides, explicitly r
7. `docs/research/` — standards and research rationale with APA 7 references.
8. `CHANGELOG.md` — user-visible unreleased and released changes.

A behavior or boundary change is incomplete until the relevant level is updated and executable tests prove the claim.
A behavior or boundary change is incomplete until the relevant level is updated and executable tests prove the claim.
16 changes: 15 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,8 @@ All notable changes to LifeOS are documented in this file.

### Added

- An Integration-owned hosted Plugin runtime seam that uses only `INTEGRATION_DATABASE_URL`, constructs installation, credential-metadata, and operator-replay persistence over one PostgreSQL pool, registers the authenticated Vault-backed operator before listener start, and closes the owned runtime exactly once through Nest application shutdown. The deployment still must supply a concrete Integration-owned PostgreSQL driver factory and prove the composed path against a real Vault before production readiness is claimed.
- A concrete Integration-owned node-postgres Plugin runtime and default entrypoint that require one self-contained `INTEGRATION_DATABASE_URL`, reject URI query/fragment transport overrides, require certificate-verified TLS through Node's configured trust store, own finite Pool size/connection-acquisition/statement/query/idle/lifetime bounds, register a credential-free idle-client error boundary before use, copy readonly SQL values before driver calls, close the Pool deterministically, and collapse startup rejection to one credential-free nonzero process failure. Frozen-lock agreement and real PostgreSQL verified-TLS acceptance are retained in the branch lineage; real Vault-backed composed-runtime acceptance remains required before this slice is production-ready.
- An Integration-owned hosted Plugin runtime seam that uses only `INTEGRATION_DATABASE_URL`, constructs installation, credential-metadata, and operator-replay persistence over one PostgreSQL pool, registers the authenticated Vault-backed operator before listener start, and closes the owned runtime exactly once through Nest application shutdown. The deployment still must prove the composed path against a real Vault before production readiness is claimed.
- An authenticated Plugin Vault operator composition that keeps signed workspace/user authority and durable replay consumption upstream of secret materialization, uses only Integration-owned installation/credential/replay ports, and reads Vault origin/token/mount from service-owned `INTEGRATION_PLUGIN_VAULT_*` configuration without making the composition factory a hosted PostgreSQL owner.
- A Plugin-owned HashiCorp Vault KV v2 secret-store adapter that binds one credential UUID to one opaque reference/path, uses create-only CAS for concurrent/retry safety, accepts replay only after exact durable authority-and-secret comparison, rejects redirects, bounds transport deadlines/replay response size, and never stores Vault credentials or provider plaintext in LifeOS persistence.
- Durable PostgreSQL plugin-installation authority with opaque UUIDv4 installation/workspace/installer identity, exact manifest digests, normalized explicit grants, bounded conflict replay, and atomic revocation evidence in the service-owned `plugin_integration` schema.
Expand All @@ -36,6 +37,18 @@ All notable changes to LifeOS are documented in this file.

### Fixed

- Plugin credential replay now revalidates the exact durable credential binding after provider-backed secret verification and installation revalidation, so a concurrent credential revocation cannot be returned as stale active replay authority.
- Plugin credential replay now revalidates the owning installation after provider-backed secret verification; a concurrent installation revocation cannot leave stale active replay metadata accepted after secret-store I/O.
- Plugin credential metadata replays now require exact provider-backed secret evidence before acceptance; reusing a binding identity with different secret bytes, or with missing/conflicting Vault evidence, fails closed instead of returning stale active metadata.
- Integration Plugin PostgreSQL shutdown authority is now captured once during Pool acquisition and reused for acquisition rollback and accepted runtime shutdown, so a stateful or hostile `end` accessor cannot replace cleanup authority after readiness.
- Integration Plugin PostgreSQL readiness validation now treats result, row-array, and row property access as untrusted evidence: throwing proxy/accessor behavior is reduced to `PluginNodePostgresConfigurationError`, and the acquired Pool is closed before runtime authority can escape.
- Integration Plugin PostgreSQL query authority is now captured once before the readiness probe and reused for every accepted adapter query, so a stateful or hostile Pool accessor cannot pass readiness and later replace SQL authority.
- Integration Plugin startup now treats node-postgres Pool construction as provisional rather than accepted database authority: after the idle-error boundary is installed, a fixed `SELECT 1 AS integration_plugin_runtime_ready` must return one canonical row before the pool reaches hosted adapters. DNS/TLS/authentication/query or malformed-result failures close the acquired pool and collapse to `PluginNodePostgresConfigurationError`; real PostgreSQL/Vault protected-lineage acceptance remains separately required.
- Integration Plugin PostgreSQL pool construction failures are now reduced to `PluginNodePostgresConfigurationError` before native driver detail can become startup evidence; listener-registration cleanup remains a separate post-construction boundary.
- Integration Plugin PostgreSQL queries no longer inherit node-postgres's default unbounded statement/query execution. The Pool now applies a 5-second PostgreSQL `statement_timeout` and a 6-second node-postgres `query_timeout` fallback so normal server cancellation can arrive before the client call fails closed; protected-lineage database timing and p95 evidence remain required.
- The concrete Plugin PostgreSQL driver now supplies an explicit verified-TLS Pool policy instead of leaving transport encryption disabled by node-postgres defaults; connection-string query parameters remain rejected so URI input cannot downgrade or replace that service-owned policy.
- Plugin PostgreSQL idle-client diagnostics no longer trust arbitrary five-character `error.code` values as SQLSTATE evidence; retained codes are limited to the explicit operational PostgreSQL classes needed for pool health (08, 53, 57, and 58), while unknown values are discarded without serializing native error detail.
- The concrete Plugin PostgreSQL pool no longer inherits an unbounded connection-acquisition wait or an unhandled idle-client failure surface: acquisition, idle, lifetime, and pool-size limits are explicit, and idle driver errors are reduced to bounded classification evidence without serializing native messages or connection material.
- Hosted Plugin startup now bounds malformed environment/pool/application envelopes before field or method access, cleans an acquired pool if later composition fails, validates the listener port before resource acquisition, and collapses startup/cleanup failure detail into one credential-free runtime error.
- Plugin Vault operator configuration no longer accepts generic `PLUGIN_VAULT_*` aliases as credential authority; origin, token, and mount must come from the Integration service-owned configuration namespace and malformed/incomplete composition still fails through one credential-free error.
- Plugin credential binding now validates command/context envelopes, server-clock evidence, persistence result envelopes, canonical durable UUID/timestamp/lifecycle evidence, and exact absence sentinels before they become authority; malformed durable reads cannot cause fresh secret materialization, malformed create winners trigger secret compensation instead of leaving provider material silently orphaned, and credential/install chronology is fenced so future or pre-installation bindings and future-dated revocation replays cannot become current authority or trigger provider deletion.
Expand All @@ -51,6 +64,7 @@ All notable changes to LifeOS are documented in this file.

### Security

- Plugin PostgreSQL transport is fail-closed to verified TLS using Node's configured trust store; the canonical `INTEGRATION_DATABASE_URL` cannot carry SSL/query options that weaken or replace this policy and accepts DNS hostname authority only. IPv4/IPv6 literal authorities are rejected before node-postgres acquisition until upstream transport can prove certificate identity for IP literals. Protected-lineage PostgreSQL 17.10 acceptance proves encrypted DNS-host operation, hostname mismatch rejection, non-TLS rejection, server-side timeout/cancellation recovery, and the migration/driver suite; real Vault-backed composed-runtime acceptance remains separate.
- Plugin Vault secret creation is create-only per credential binding and reconciles an ambiguous/CAS-losing write only against canonical matching durable evidence; caller and Vault-returned binding/installation/workspace/user UUIDs must already be canonical lowercase and are never normalized into authority, a different secret winner cannot be overwritten or treated as replay, malformed Vault evidence fails closed, and the opaque reference contains no Vault token, address, or provider plaintext.
- Plugin credential persistence now treats exact `undefined` as the only normal application-level absence sentinel, rejects malformed SQL/result/row evidence with bounded errors, requires canonical durable UUIDv4/timestamps, and prevents installation revocation from racing a new durable credential admission.
- Habit create/list/occurrence/completion routes now reject a bare client-selected `x-workspace-id` authority and require the short-lived signed `life-os.workspace.v1` gateway context before domain access.
Expand Down
2 changes: 2 additions & 0 deletions apps/integration-service/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -14,12 +14,14 @@
"@nestjs/common": "^11.1.6",
"@nestjs/core": "^11.1.6",
"@nestjs/platform-express": "^11.1.6",
"pg": "^8.22.0",
"reflect-metadata": "^0.2.2",
"rxjs": "^7.8.2"
},
"devDependencies": {
"@nestjs/cli": "^11.0.10",
"@types/node": "^24.3.0",
"@types/pg": "^8.20.0",
"typescript": "^5.9.2",
"vitest": "^3.2.4"
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -109,6 +109,12 @@ function harness(now: () => Date): {
calls.secretWrites += 1;
return SECRET_REFERENCE;
},
async verifySecret(
_secretReference: string,
_input: PutPluginSecretInput,
): Promise<void> {
throw new Error('unexpected replay verification in fixture');
},
async deleteSecret(_secretReference: string): Promise<void> {
calls.secretDeletes += 1;
},
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -94,6 +94,13 @@ class SecretStore implements PluginSecretStore {
return SECRET_REFERENCE;
}

async verifySecret(
_secretReference: string,
_input: PutPluginSecretInput,
): Promise<void> {
throw new Error('unexpected replay verification in fixture');
}

async deleteSecret(secretReference: string): Promise<void> {
this.deletes.push(secretReference);
}
Expand Down
Loading