Files
suaveplan/openspec/archive/2026-05-26-foundation-fix-gap-3-secrets-slot/tasks.md
2026-05-27 23:29:53 +01:00

3.0 KiB

Tasks — foundation-fix-gap-3-secrets-slot

  • Add secrets: SecretsLike REQUIRED field to PluginContext<Caps> in @suaveplan/api-types/plugin-context; verify the Omit<PluginContext, "capabilities"> extension causes RequestContext, JobContext, ConnectionContext to inherit the field.
  • Update plugin-context.md to document the new field on every flavour.
  • Add optional secrets?: SecretsLike to HostAdapters in @suaveplan/api-host/host/host.types.ts; update Zod adapter shape in host.ts to accept the optional field.
  • Add EmptySecrets class at packages/api-stack/api/api-host/src/empty-secrets/{empty-secrets.ts,empty-secrets.test.ts,empty-secrets.md,index.ts}; get returns undefined, require throws SECRETS.SECRET_NOT_FOUND via SecretsError, list returns frozen empty array.
  • Wire ./empty-secrets subpath export in api-host/package.json and re-export from the root barrel.
  • Add @suaveplan/api-secrets workspace dependency to api-host/package.json so SecretsError + SECRETS_CODES are reachable.
  • Thread secrets: SecretsLike through RequestPipelineOptions; update request-pipeline-helpers.buildRequestContext to accept + propagate; update request-pipeline-driver.runPipeline to pass config.options.secrets.
  • Wire LifecycleDriverOptions.secrets and store on the driver; update callUserHook to pass { plugin, secrets } to user hooks instead of {}.
  • In createHost/HostImpl, construct secrets = adapters.secrets ?? new EmptySecrets() and inject into both pipeline options and lifecycle driver options.
  • Update request-pipeline-outcomes.test.ts and request-pipeline.test.ts (3 pipeline constructor sites) to supply secrets: new EmptySecrets().
  • Add request-pipeline-secrets.test.ts covering: (a) handler reads ctx.secrets.require("FOO") via a wired stub, (b) EmptySecrets throws SECRETS.SECRET_NOT_FOUND and yields 500 envelope, (c) ctx.secrets is the same reference passed via options.
  • Remove the buildSecrets() closure + secrets.require(SECRET_KEY) binding from e2e/foundation-stack/src/fixture-plugin.ts; route handler reads via ctx.secrets.require("FOUNDATION_SECRET").
  • Wire createEnvSecrets(...) into HostAdapters.secrets in e2e/foundation-stack/src/server.ts; update the inline gap-3 deviation comment to "CLOSED".
  • Verify gate: bunx turbo lint typecheck test build --filter=@suaveplan/api-host --filter=@suaveplan/api-types --filter=@suaveplan/e2e-foundation-stack → green.
  • Verify coverage: 100% line on touched files (api-host empty-secrets, lifecycle, host, request-pipeline driver/helpers/types).
  • E2E: re-run cd e2e/foundation-stack && bunx playwright test — all 10 tests pass post-shim removal, including the secrets-redaction test.
  • Fold deltas into canonical openspec/specs/api-host/spec.md and openspec/specs/api-types/spec.md; move folder to openspec/archive/2026-05-26-foundation-fix-gap-3-secrets-slot/.