Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
10 changes: 10 additions & 0 deletions .github/workflows/platform.yml
Original file line number Diff line number Diff line change
Expand Up @@ -102,6 +102,16 @@ jobs:
# (on). Set the `CDK_SCHEDULED_RUNS_ENABLED` variable to "false" in
# an environment only to dark-stop the feature there.
CDK_SCHEDULED_RUNS_ENABLED: ${{ vars.CDK_SCHEDULED_RUNS_ENABLED }}
# Memory Spaces (user-owned markdown "second brain" + agent binding).
# Default ON with a kill switch: unset resolves to empty string, which
# config.ts treats as the default (on). Set the `CDK_MEMORY_SPACES_ENABLED`
# variable to "false" in an environment only to dark-stop the feature there.
CDK_MEMORY_SPACES_ENABLED: ${{ vars.CDK_MEMORY_SPACES_ENABLED }}
# Agent Designer /agents surface. Default OFF (opt-in) until the Phase-4
# Designer UI ships — a headless API helps no forker. Set the
# `CDK_AGENTS_API_ENABLED` variable to "true" in an environment (e.g. dev)
# to enable it there for dogfooding.
CDK_AGENTS_API_ENABLED: ${{ vars.CDK_AGENTS_API_ENABLED }}
# Secrets
AWS_ROLE_ARN: ${{ secrets.AWS_ROLE_ARN }}
AWS_ACCESS_KEY_ID: ${{ secrets.AWS_ACCESS_KEY_ID }}
Expand Down
27 changes: 15 additions & 12 deletions infrastructure/lib/config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -160,10 +160,12 @@ export interface ScheduledRunsConfig {
}

/**
* Memory Spaces feature flag. Default OFF with an on switch — the feature
* is opt-in per environment, enabled with CDK_MEMORY_SPACES_ENABLED=true
* (or a `memorySpaces.enabled: true` cdk.json context). Sets the
* MEMORY_SPACES_ENABLED env var on app-api and inference-api.
* Memory Spaces feature flag. Default ON with a kill switch — the feature is
* complete and ships enabled for every deployer (opt-out), disabled per
* environment with CDK_MEMORY_SPACES_ENABLED=false (or a
* `memorySpaces.enabled: false` cdk.json context). Sets the
* MEMORY_SPACES_ENABLED env var on app-api and inference-api. The table + bucket
* are provisioned unconditionally, so this only gates route mounting at runtime.
*/
export interface MemorySpacesConfig {
enabled: boolean;
Expand Down Expand Up @@ -328,15 +330,16 @@ export function loadConfig(scope: cdk.App): AppConfig {
: scope.node.tryGetContext('scheduledRuns')?.enabled ?? true,
},
memorySpaces: {
// Default OFF with an on switch: the feature is opt-in per
// environment, enabled only when explicitly turned on. The workflow
// forwards an EMPTY STRING when the variable is unset, so treat
// empty/unset as "use the default (off)" and only the literal "true"
// as the on switch. A `memorySpaces.enabled` cdk.json context can
// also force it on.
// Default ON with a kill switch: Memory Spaces is a complete feature and
// ships enabled for every deployer (opt-out, not opt-in — matches kbSync /
// scheduledRuns). The table + bucket are provisioned unconditionally, so this
// only toggles the runtime MEMORY_SPACES_ENABLED env var. The workflow forwards
// an EMPTY STRING when the variable is unset, so treat empty/unset as the
// default (on) and only the literal "false" as the kill switch. A
// `memorySpaces.enabled: false` cdk.json context can also disable it.
enabled: process.env.CDK_MEMORY_SPACES_ENABLED
? process.env.CDK_MEMORY_SPACES_ENABLED === 'true'
: scope.node.tryGetContext('memorySpaces')?.enabled ?? false,
? process.env.CDK_MEMORY_SPACES_ENABLED !== 'false'
: scope.node.tryGetContext('memorySpaces')?.enabled ?? true,
},
agents: {
// Default OFF with an on switch (same pattern as memorySpaces): opt-in per
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -283,7 +283,7 @@ export function buildAppApiEnvironment(
// (scheduled-runs PR-1). Cohort access is RBAC (`scheduled-runs`
// capability); this only gates feature existence per environment.
SCHEDULED_RUNS_ENABLED: config.scheduledRuns.enabled ? 'true' : 'false',
// Kill switch for the Memory Spaces feature (default off per env).
// Memory Spaces feature (default ON with a kill switch per env).
// The table/bucket names are always wired (the service reads them lazily);
// only MEMORY_SPACES_ENABLED gates whether the routes are mounted. Without
// these two, app-api falls back to the default "memory-spaces" name and
Expand Down
38 changes: 38 additions & 0 deletions infrastructure/test/config.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -384,6 +384,44 @@ describe('RAG Ingestion Configuration', () => {
});
});

// ============================================================
// Memory Spaces feature flag — default ON with a kill switch
// (complete feature; ships enabled for forkers, empty var must not disable)
// ============================================================

describe('Memory Spaces feature flag', () => {
test('defaults to enabled when CDK_MEMORY_SPACES_ENABLED is unset', () => {
delete process.env.CDK_MEMORY_SPACES_ENABLED;

expect(loadConfig(app).memorySpaces.enabled).toBe(true);
});

test('treats empty string (unset GitHub Actions variable) as enabled', () => {
process.env.CDK_MEMORY_SPACES_ENABLED = '';

expect(loadConfig(app).memorySpaces.enabled).toBe(true);
});

test('CDK_MEMORY_SPACES_ENABLED="false" is the kill switch', () => {
process.env.CDK_MEMORY_SPACES_ENABLED = 'false';

expect(loadConfig(app).memorySpaces.enabled).toBe(false);
});

test('CDK_MEMORY_SPACES_ENABLED="true" stays enabled', () => {
process.env.CDK_MEMORY_SPACES_ENABLED = 'true';

expect(loadConfig(app).memorySpaces.enabled).toBe(true);
});

test('cdk.json context memorySpaces.enabled=false disables when env is unset', () => {
delete process.env.CDK_MEMORY_SPACES_ENABLED;
app.node.setContext('memorySpaces', { enabled: false });

expect(loadConfig(app).memorySpaces.enabled).toBe(false);
});
});

// ============================================================
// Configuration Validation Tests
// ============================================================
Expand Down