chore: crush git history - reborn from consolidation on 2026-03-10
This commit is contained in:
@@ -0,0 +1,374 @@
|
||||
/**
|
||||
* S3: Init command scaffold templates
|
||||
* Each preset returns a config object and file contents for the init command.
|
||||
*/
|
||||
|
||||
import type { ApophisConfig, PresetDefinition, ProfileDefinition, EnvironmentPolicy } from '../../../core/types.js';
|
||||
|
||||
export interface ScaffoldResult {
|
||||
config: ApophisConfig;
|
||||
readmeContent: string;
|
||||
}
|
||||
|
||||
// ─────────────────────────────────────────────────────────────────────────────
|
||||
// safe-ci: Minimal CI-safe preset (default)
|
||||
// ─────────────────────────────────────────────────────────────────────────────
|
||||
|
||||
export function safeCiScaffold(): ScaffoldResult {
|
||||
const preset: PresetDefinition = {
|
||||
name: 'safe-ci',
|
||||
depth: 'quick',
|
||||
timeout: 5000,
|
||||
parallel: false,
|
||||
chaos: false,
|
||||
observe: false,
|
||||
};
|
||||
|
||||
const profile: ProfileDefinition = {
|
||||
name: 'quick',
|
||||
mode: 'verify',
|
||||
preset: 'safe-ci',
|
||||
routes: ['POST /users'],
|
||||
};
|
||||
|
||||
const envLocal: EnvironmentPolicy = {
|
||||
name: 'local',
|
||||
allowVerify: true,
|
||||
allowObserve: true,
|
||||
allowQualify: false,
|
||||
allowChaos: false,
|
||||
allowBlocking: true,
|
||||
requireSink: false,
|
||||
};
|
||||
|
||||
const config: ApophisConfig = {
|
||||
mode: 'verify',
|
||||
profiles: { quick: profile },
|
||||
presets: { 'safe-ci': preset },
|
||||
environments: { local: envLocal },
|
||||
};
|
||||
|
||||
const readmeContent = `
|
||||
# APOPHIS Setup — safe-ci preset
|
||||
|
||||
This project was scaffolded with \`apophis init --preset safe-ci\`.
|
||||
|
||||
## Quick Start
|
||||
|
||||
1. Ensure you have a Fastify app with @fastify/swagger registered.
|
||||
2. Add behavioral contracts to your route schemas using \`x-ensures\`.
|
||||
3. Run: apophis verify --profile quick
|
||||
|
||||
## What This Preset Does
|
||||
|
||||
- Runs only behavioral contracts (not schema-only routes).
|
||||
- No chaos, no observe, no stateful testing.
|
||||
- Safe for CI pipelines.
|
||||
- Timeout: 5s per route.
|
||||
|
||||
## Example Behavioral Contract
|
||||
|
||||
Add this inside your route schema to check that a created resource is retrievable:
|
||||
|
||||
\`\`\`javascript
|
||||
"x-ensures": [
|
||||
"response_code(GET /users/{response_body(this).id}) == 200"
|
||||
]
|
||||
\`\`\`
|
||||
|
||||
If \`apophis verify\` says "No behavioral contracts found", it means your routes have schemas but no \`x-ensures\` or \`x-requires\` clauses. Add at least one clause per route you want to verify.
|
||||
|
||||
## Next Steps
|
||||
|
||||
- Add more routes to the \`routes\` array in your profile.
|
||||
- Try \`apophis init --preset platform-observe\` for production readiness.
|
||||
- Try \`apophis init --preset protocol-lab\` for multi-step flows.
|
||||
`;
|
||||
|
||||
return { config, readmeContent };
|
||||
}
|
||||
|
||||
// ─────────────────────────────────────────────────────────────────────────────
|
||||
// platform-observe: Production-ready with observe mode
|
||||
// ─────────────────────────────────────────────────────────────────────────────
|
||||
|
||||
export function platformObserveScaffold(): ScaffoldResult {
|
||||
const preset: PresetDefinition = {
|
||||
name: 'platform-observe',
|
||||
depth: 'standard',
|
||||
timeout: 10000,
|
||||
parallel: true,
|
||||
chaos: false,
|
||||
observe: true,
|
||||
};
|
||||
|
||||
const profile: ProfileDefinition = {
|
||||
name: 'staging-observe',
|
||||
mode: 'observe',
|
||||
preset: 'platform-observe',
|
||||
routes: [],
|
||||
};
|
||||
|
||||
const envStaging: EnvironmentPolicy = {
|
||||
name: 'staging',
|
||||
allowVerify: true,
|
||||
allowObserve: true,
|
||||
allowQualify: true,
|
||||
allowChaos: false,
|
||||
allowBlocking: false,
|
||||
requireSink: true,
|
||||
};
|
||||
|
||||
const envProduction: EnvironmentPolicy = {
|
||||
name: 'production',
|
||||
allowVerify: true,
|
||||
allowObserve: true,
|
||||
allowQualify: false,
|
||||
allowChaos: false,
|
||||
allowBlocking: false,
|
||||
requireSink: true,
|
||||
};
|
||||
|
||||
const config: ApophisConfig = {
|
||||
mode: 'observe',
|
||||
profile: 'staging-observe',
|
||||
profiles: { 'staging-observe': profile },
|
||||
presets: { 'platform-observe': preset },
|
||||
environments: {
|
||||
staging: envStaging,
|
||||
production: envProduction,
|
||||
},
|
||||
};
|
||||
|
||||
const readmeContent = `
|
||||
# APOPHIS Setup — platform-observe preset
|
||||
|
||||
This project was scaffolded with \`apophis init --preset platform-observe\`.
|
||||
|
||||
## Quick Start
|
||||
|
||||
1. Ensure you have a Fastify app with @fastify/swagger registered.
|
||||
2. Configure your reporting sink (see environments.staging.requireSink).
|
||||
3. Run: apophis observe --profile staging-observe
|
||||
|
||||
## What This Preset Does
|
||||
|
||||
- Enables observe mode for production readiness checks.
|
||||
- Validates non-blocking semantics and sink configuration.
|
||||
- Parallel execution for faster feedback.
|
||||
- Requires sink config in staging/production.
|
||||
|
||||
## Safety
|
||||
|
||||
- Observe mode is non-blocking by default.
|
||||
- Production requires explicit policy to enable blocking.
|
||||
- Chaos is disabled in this preset.
|
||||
|
||||
## Next Steps
|
||||
|
||||
- Add a sink configuration to your environment policy.
|
||||
- Run \`apophis doctor\` to validate the full setup.
|
||||
`;
|
||||
|
||||
return { config, readmeContent };
|
||||
}
|
||||
|
||||
// ─────────────────────────────────────────────────────────────────────────────
|
||||
// llm-safe: Minimal preset for LLM-generated codebases
|
||||
// ─────────────────────────────────────────────────────────────────────────────
|
||||
|
||||
export function llmSafeScaffold(): ScaffoldResult {
|
||||
const preset: PresetDefinition = {
|
||||
name: 'llm-safe',
|
||||
depth: 'quick',
|
||||
timeout: 3000,
|
||||
parallel: false,
|
||||
chaos: false,
|
||||
observe: false,
|
||||
};
|
||||
|
||||
const profile: ProfileDefinition = {
|
||||
name: 'llm-check',
|
||||
mode: 'verify',
|
||||
preset: 'llm-safe',
|
||||
routes: [],
|
||||
};
|
||||
|
||||
const envLocal: EnvironmentPolicy = {
|
||||
name: 'local',
|
||||
allowVerify: true,
|
||||
allowObserve: false,
|
||||
allowQualify: false,
|
||||
allowChaos: false,
|
||||
allowBlocking: false,
|
||||
requireSink: false,
|
||||
};
|
||||
|
||||
const config: ApophisConfig = {
|
||||
mode: 'verify',
|
||||
profile: 'llm-check',
|
||||
profiles: { 'llm-check': profile },
|
||||
presets: { 'llm-safe': preset },
|
||||
environments: { local: envLocal },
|
||||
};
|
||||
|
||||
const readmeContent = `
|
||||
# APOPHIS Setup — llm-safe preset
|
||||
|
||||
This project was scaffolded with \`apophis init --preset llm-safe\`.
|
||||
|
||||
## Quick Start
|
||||
|
||||
1. Ensure you have a Fastify app with @fastify/swagger registered.
|
||||
2. Add behavioral contracts to your route schemas using \`x-ensures\`.
|
||||
3. Run: apophis verify --profile llm-check
|
||||
|
||||
## What This Preset Does
|
||||
|
||||
- Ultra-minimal preset for LLM-generated codebases.
|
||||
- 3s timeout per route (fast feedback).
|
||||
- No observe, no qualify, no chaos — verify only.
|
||||
- Conservative defaults to avoid surprising failures.
|
||||
|
||||
## Example Behavioral Contract
|
||||
|
||||
Add this inside your route schema to check that a created resource is retrievable:
|
||||
|
||||
\`\`\`javascript
|
||||
"x-ensures": [
|
||||
"response_code(GET /users/{response_body(this).id}) == 200"
|
||||
]
|
||||
\`\`\`
|
||||
|
||||
If \`apophis verify\` says "No behavioral contracts found", it means your routes have schemas but no \`x-ensures\` or \`x-requires\` clauses. Add at least one clause per route you want to verify.
|
||||
|
||||
## Next Steps
|
||||
|
||||
- Add routes to the \`routes\` array once you have behavioral contracts.
|
||||
- Run \`apophis doctor\` to check for missing dependencies.
|
||||
`;
|
||||
|
||||
return { config, readmeContent };
|
||||
}
|
||||
|
||||
// ─────────────────────────────────────────────────────────────────────────────
|
||||
// protocol-lab: Multi-step flow and stateful testing
|
||||
// ─────────────────────────────────────────────────────────────────────────────
|
||||
|
||||
export function protocolLabScaffold(): ScaffoldResult {
|
||||
const preset: PresetDefinition = {
|
||||
name: 'protocol-lab',
|
||||
depth: 'deep',
|
||||
timeout: 15000,
|
||||
parallel: false,
|
||||
chaos: true,
|
||||
observe: false,
|
||||
};
|
||||
|
||||
const profile: ProfileDefinition = {
|
||||
name: 'oauth-nightly',
|
||||
mode: 'qualify',
|
||||
preset: 'protocol-lab',
|
||||
routes: [],
|
||||
seed: 42,
|
||||
};
|
||||
|
||||
const envLocal: EnvironmentPolicy = {
|
||||
name: 'local',
|
||||
allowVerify: true,
|
||||
allowObserve: true,
|
||||
allowQualify: true,
|
||||
allowChaos: true,
|
||||
allowBlocking: true,
|
||||
requireSink: false,
|
||||
};
|
||||
|
||||
const envTest: EnvironmentPolicy = {
|
||||
name: 'test',
|
||||
allowVerify: true,
|
||||
allowObserve: true,
|
||||
allowQualify: true,
|
||||
allowChaos: true,
|
||||
allowBlocking: true,
|
||||
requireSink: false,
|
||||
};
|
||||
|
||||
const config: ApophisConfig = {
|
||||
mode: 'qualify',
|
||||
profile: 'oauth-nightly',
|
||||
profiles: { 'oauth-nightly': profile },
|
||||
presets: { 'protocol-lab': preset },
|
||||
environments: {
|
||||
local: envLocal,
|
||||
test: envTest,
|
||||
},
|
||||
};
|
||||
|
||||
const readmeContent = `
|
||||
# APOPHIS Setup — protocol-lab preset
|
||||
|
||||
This project was scaffolded with \`apophis init --preset protocol-lab\`.
|
||||
|
||||
## Quick Start
|
||||
|
||||
1. Ensure you have a Fastify app with @fastify/swagger registered.
|
||||
2. Define multi-step flows in your route schemas.
|
||||
3. Run: apophis qualify --profile oauth-nightly --seed 42
|
||||
|
||||
## What This Preset Does
|
||||
|
||||
- Enables qualify mode for stateful and scenario testing.
|
||||
- Chaos engineering enabled (local/test only).
|
||||
- Deep depth for thorough exploration.
|
||||
- 15s timeout per route.
|
||||
|
||||
## Safety
|
||||
|
||||
- Chaos is blocked in production by default.
|
||||
- Use \`apophis doctor\` to validate environment safety before qualifying.
|
||||
|
||||
## Machine Output in CI
|
||||
|
||||
Qualify can produce large output. In CI, use machine-readable formats and filter events:
|
||||
|
||||
- \`--format json\` emits a single stable JSON artifact (good for small-to-medium runs).
|
||||
- \`--format ndjson\` emits one event per line (good for streaming parsers).
|
||||
- Use \`--quiet\` to suppress human progress text.
|
||||
- Pipe ndjson to \`jq\` or a custom filter to extract only failures:
|
||||
\`\`\`bash
|
||||
apophis qualify --profile oauth-nightly --format ndjson | jq 'select(.type == "route.failed")'
|
||||
\`\`\`
|
||||
- For very large runs, consider writing artifacts to a directory and parsing the JSON file instead of stdout:
|
||||
\`\`\`bash
|
||||
apophis qualify --profile oauth-nightly --format json --artifact-dir reports/apophis
|
||||
\`\`\`
|
||||
|
||||
## Next Steps
|
||||
|
||||
- Define scenario sequences in your config.
|
||||
- Add route allowlists for chaos if needed.
|
||||
- Run \`apophis replay --artifact <path>\` to debug failures.
|
||||
`;
|
||||
|
||||
return { config, readmeContent };
|
||||
}
|
||||
|
||||
// ─────────────────────────────────────────────────────────────────────────────
|
||||
// Preset registry
|
||||
// ─────────────────────────────────────────────────────────────────────────────
|
||||
|
||||
export const PRESETS: Record<string, () => ScaffoldResult> = {
|
||||
'safe-ci': safeCiScaffold,
|
||||
'platform-observe': platformObserveScaffold,
|
||||
'llm-safe': llmSafeScaffold,
|
||||
'protocol-lab': protocolLabScaffold,
|
||||
};
|
||||
|
||||
export function getPresetNames(): string[] {
|
||||
return Object.keys(PRESETS);
|
||||
}
|
||||
|
||||
export function getScaffoldForPreset(preset: string): ScaffoldResult | null {
|
||||
const fn = PRESETS[preset];
|
||||
return fn ? fn() : null;
|
||||
}
|
||||
Reference in New Issue
Block a user