{"record":{"id":"3b2a617ba4f0ec7d","repo":"JuliusBrussee/caveman","slug":"cave-harness-incomplete-evidence","errorCode":"cave_harness_incomplete_evidence","errorMessage":"cave_harness_incomplete_evidence","messagePattern":"cave_harness_incomplete_evidence","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"critical","filePath":"packages/agent/src/adapters.ts","lineNumber":354,"sourceCode":"  inputTokens: number;\n  outputTokens: number;\n  cacheReadTokens: number;\n  cacheWriteTokens: number;\n  reasoningTokens: number;\n  totalTokens: number;\n}\n\nfunction harnessExecution(input: {\n  request: Readonly<HarnessRequest>;\n  text: string;\n  provider: string;\n  model: string;\n  usage: NormalizedUsage;\n  latencyMs: number;\n}): HarnessExecution {\n  const expected = expectedProviderModel(input.request.plan);\n  if (input.provider !== expected.provider || input.model !== expected.model) {\n    throw new Error(\"cave_harness_incomplete_evidence\");\n  }\n  const priced = validateProviderUsage({\n    provider: input.provider,\n    model: input.model,\n    ...input.usage,\n  }, { requirePriced: true });\n  return {\n    terminal: true,\n    text: input.text,\n    provider: input.provider,\n    model: input.model,\n    ...input.usage,\n    costUsd: priced.catalogCostUsd,\n    usageBasis: \"provider_reported\",\n    priceBasis: \"public_catalog\",\n    evaluatedTransformIDs: [...input.request.evaluatedTransformIDs],\n    appliedTransformIDs: [...input.request.appliedTransformIDs],\n    recoveryResolved: input.request.recoveryResolved,","sourceCodeStart":336,"sourceCodeEnd":372,"githubUrl":"https://github.com/JuliusBrussee/caveman/blob/27d5a3981a347890211bb1bf2439e5c821a63bc9/packages/agent/src/adapters.ts#L336-L372","documentation":"Returned by validateRuntimeIdentity when the connected identity's current_user differs from session_user. The package requires the authenticated login identity and the effective identity to be identical, because Postgres allows session_user to run SET ROLE NONE and reclaim its original (possibly privileged) identity, which would silently escape the tenant-isolation role. Any connection that logged in as one role and SET ROLE'd into another is rejected.","triggerScenarios":"Connecting with a superuser/owner login and issuing SET ROLE app_runtime before handing the connection to the pool constructor; a proxy or pooler (PgBouncer) that reuses sessions with an active SET ROLE; DATABASE_URL credentials of an admin user with a startup parameter that changes the role.","commonSituations":"Dev setups where the operator connects as postgres and 'drops down' to the runtime role instead of creating a dedicated login; connection strings with options='-c role=app_runtime'; PgBouncer session pooling leaking role state between tenants; migration tools that connect as owner and then run the app in the same process.","solutions":["Create a dedicated LOGIN role for the runtime pool (e.g. app_runtime) and put its credentials in DATABASE_URL so session_user == current_user from the start","Remove any SET ROLE from connection startup SQL, pool 'after_connect' hooks, or PgBouncer startup parameters","If PgBouncer is in front, use transaction pooling with clean state or bypass it for the runtime pool connections","Re-run the identity query (SELECT current_user, session_user) with the same URL via psql to confirm both match"],"exampleFix":"# before\nDATABASE_URL=postgres://app_owner:...@db:5432/app?sslmode=verify-full\n# app_owner does: SET ROLE app_runtime;  -> current_user != session_user -> rejected\n\n# after\nCREATE ROLE app_runtime LOGIN PASSWORD '...' NOLOGIN FALSE;\nGRANT app_runtime TO app_owner; -- if needed for grants\nDATABASE_URL=postgres://app_runtime:...@db:5432/app?sslmode=verify-full","handlingStrategy":"validation","validationCode":"// Assert identity alignment before constructing the runtime pool:\nfunc preflightIdentity(ctx context.Context, dbURL string) error {\n    conn, err := pgx.Connect(ctx, dbURL)\n    if err != nil { return err }\n    defer conn.Close(ctx)\n    var cur, sess string\n    if err := conn.QueryRow(ctx, \"SELECT current_user, session_user\").Scan(&cur, &sess); err != nil {\n        return err\n    }\n    if cur != sess {\n        return fmt.Errorf(\"login as the runtime role directly; %q logged in but effective role is %q (SET ROLE is not permitted)\", sess, cur)\n    }\n    return nil\n}","typeGuard":"func isIdentityMismatchErr(err error) bool {\n    return err != nil && strings.HasPrefix(err.Error(), \"postgres: runtime current_user\")\n}","tryCatchPattern":"if err := preflightIdentity(ctx, dbURL); err != nil {\n    return err // fail with an operator-actionable message before pool construction\n}\npool, err := postgresconfig.NewPool(ctx, dbURL)","preventionTips":["Provision a dedicated LOGIN role for the app and use only its credentials in DATABASE_URL","Never rely on SET ROLE to drop privileges; connect as the least-privileged identity from the start","If a pooler like PgBouncer sits in front, use transaction pooling and verify no session-level SET ROLE leaks","Add a deployment smoke test that asserts current_user == session_user with the production URL (dummy query)"],"tags":["postgres","security","rls","roles","startup"],"backgroundTag":null,"analyzedSha":"27d5a3981a347890211bb1bf2439e5c821a63bc9","analyzedAt":"2026-08-15T09:26:11.751Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}