diff --git a/src/cli/commands/init/scaffolds/index.ts b/src/cli/commands/init/scaffolds/index.ts index a1945d9..d2a3179 100644 --- a/src/cli/commands/init/scaffolds/index.ts +++ b/src/cli/commands/init/scaffolds/index.ts @@ -45,6 +45,13 @@ export function safeCiScaffold(): ScaffoldResult { profiles: { quick: profile }, presets: { 'safe-ci': preset }, environments: { local: envLocal }, + // Uncomment to enforce cross-cutting behavioral rules across all matching routes: + // pluginContracts: { + // 'auth-presence': { + // appliesTo: '/api/**', + // hooks: { onRequest: { requires: ['request_headers(this).authorization != null'] } }, + // }, + // }, }; const readmeContent = ` @@ -98,6 +105,9 @@ export function platformObserveScaffold(): ScaffoldResult { parallel: true, chaos: false, observe: true, + sampling: 0.1, + blocking: false, + sinks: { logs: true, metrics: true }, }; const profile: ProfileDefinition = { @@ -115,6 +125,7 @@ export function platformObserveScaffold(): ScaffoldResult { allowChaos: false, allowBlocking: false, requireSink: true, + sinks: { logs: true, metrics: true }, }; const envProduction: EnvironmentPolicy = { @@ -136,6 +147,12 @@ export function platformObserveScaffold(): ScaffoldResult { staging: envStaging, production: envProduction, }, + // pluginContracts: { + // 'request-id': { + // appliesTo: '/api/**', + // hooks: { onSend: { ensures: ['response_headers(this).x-request-id != null'] } }, + // }, + // }, }; const readmeContent = ` @@ -207,6 +224,12 @@ export function llmSafeScaffold(): ScaffoldResult { profiles: { 'llm-check': profile }, presets: { 'llm-safe': preset }, environments: { local: envLocal }, + // pluginContracts: { + // 'auth-presence': { + // appliesTo: '/api/**', + // hooks: { onRequest: { requires: ['request_headers(this).authorization != null'] } }, + // }, + // }, }; const readmeContent = ` @@ -259,6 +282,9 @@ export function protocolLabScaffold(): ScaffoldResult { parallel: false, chaos: true, observe: false, + // chaosStrategy: 'sample', // 'one' | 'all' | 'sample' | 'routes' + // chaosSampleSize: 3, // routes to target when strategy is 'sample' + // chaosSampleRoutes: [], // explicit route list when strategy is 'routes' }; const profile: ProfileDefinition = { @@ -298,6 +324,12 @@ export function protocolLabScaffold(): ScaffoldResult { local: envLocal, test: envTest, }, + // pluginContracts: { + // 'rate-limit': { + // appliesTo: 'POST /api/**', + // hooks: { onResponse: { ensures: ['status != 429'] } }, + // }, + // }, }; const readmeContent = ` diff --git a/src/cli/core/types.ts b/src/cli/core/types.ts index c06eebe..2fc76a1 100644 --- a/src/cli/core/types.ts +++ b/src/cli/core/types.ts @@ -95,6 +95,7 @@ export interface EnvironmentPolicy { allowChaos?: boolean; allowBlocking?: boolean; requireSink?: boolean; + sinks?: Record; } /** @@ -145,6 +146,14 @@ export interface PresetDefinition { parallel?: boolean; chaos?: boolean; observe?: boolean; + runs?: number; + sampling?: number; + blocking?: boolean; + sinks?: Record; + features?: string[]; + chaosStrategy?: 'one' | 'all' | 'sample' | 'routes'; + chaosSampleSize?: number; + chaosSampleRoutes?: string[]; } /**