fix(ri-050): forge fails closed without providers; explicit typed simulation (#1275)
ci/woodpecker/pr/ci Pipeline failed
ci/woodpecker/pr/ci Pipeline failed
This commit is contained in:
@@ -9,7 +9,16 @@ export const PACKAGE_ROOT = path.resolve(path.dirname(fileURLToPath(import.meta.
|
||||
/** Pipeline asset directory (stages, agents, rails, gates, templates). */
|
||||
export const PIPELINE_DIR = path.join(PACKAGE_ROOT, 'pipeline');
|
||||
|
||||
/** Stage specifications — defines every pipeline stage. */
|
||||
/** Stage specifications — defines every pipeline stage.
|
||||
*\n * Gate semantics (SDLC-D-035): every gate is one of
|
||||
* - a real command string / GateEntry a mechanical runner can execute,
|
||||
* - an `authority` gate (human/board sign-off; produces waiting-for-authority),
|
||||
* - a `provider` gate (requires a wired provider such as a reviewer or CI pipeline).
|
||||
*
|
||||
* Vacuous gates (`true`, echo'd synthetic approvals, placeholder ci-pipeline
|
||||
* commands) are forbidden: a stage whose gate has no real implementation
|
||||
* fails closed instead of passing.
|
||||
*/
|
||||
export const STAGE_SPECS: Record<string, StageSpec> = {
|
||||
'00-intake': {
|
||||
number: '00',
|
||||
@@ -27,7 +36,13 @@ export const STAGE_SPECS: Record<string, StageSpec> = {
|
||||
type: 'research',
|
||||
gate: 'discovery-complete',
|
||||
promptFile: '00b-discovery.md',
|
||||
qualityGates: ['true'],
|
||||
qualityGates: [
|
||||
{
|
||||
kind: 'authority',
|
||||
capability: 'discovery-complete',
|
||||
reason: 'discovery completion is attested by an authority; no mechanical check exists',
|
||||
},
|
||||
],
|
||||
},
|
||||
'01-board': {
|
||||
number: '01',
|
||||
@@ -36,7 +51,13 @@ export const STAGE_SPECS: Record<string, StageSpec> = {
|
||||
type: 'review',
|
||||
gate: 'board-approval',
|
||||
promptFile: '01-board.md',
|
||||
qualityGates: [{ type: 'ci-pipeline', command: 'board-approval (via board-tasks)' }],
|
||||
qualityGates: [
|
||||
{
|
||||
kind: 'authority',
|
||||
capability: 'board-approval',
|
||||
reason: 'board approval is a board/human decision; no mechanical gate exists',
|
||||
},
|
||||
],
|
||||
},
|
||||
'01b-brief-analyzer': {
|
||||
number: '01b',
|
||||
@@ -45,7 +66,13 @@ export const STAGE_SPECS: Record<string, StageSpec> = {
|
||||
type: 'research',
|
||||
gate: 'brief-analysis-complete',
|
||||
promptFile: '01-board.md',
|
||||
qualityGates: ['true'],
|
||||
qualityGates: [
|
||||
{
|
||||
kind: 'authority',
|
||||
capability: 'brief-analysis-complete',
|
||||
reason: 'brief analysis completion is attested by an authority; no mechanical check exists',
|
||||
},
|
||||
],
|
||||
},
|
||||
'02-planning-1': {
|
||||
number: '02',
|
||||
@@ -54,7 +81,13 @@ export const STAGE_SPECS: Record<string, StageSpec> = {
|
||||
type: 'research',
|
||||
gate: 'architecture-approval',
|
||||
promptFile: '02-planning-1-architecture.md',
|
||||
qualityGates: ['true'],
|
||||
qualityGates: [
|
||||
{
|
||||
kind: 'authority',
|
||||
capability: 'architecture-approval',
|
||||
reason: 'ADR approval requires authority sign-off; no mechanical check exists',
|
||||
},
|
||||
],
|
||||
},
|
||||
'03-planning-2': {
|
||||
number: '03',
|
||||
@@ -63,7 +96,14 @@ export const STAGE_SPECS: Record<string, StageSpec> = {
|
||||
type: 'research',
|
||||
gate: 'implementation-approval',
|
||||
promptFile: '03-planning-2-implementation.md',
|
||||
qualityGates: ['true'],
|
||||
qualityGates: [
|
||||
{
|
||||
kind: 'authority',
|
||||
capability: 'implementation-approval',
|
||||
reason:
|
||||
'implementation spec approval requires authority sign-off; no mechanical check exists',
|
||||
},
|
||||
],
|
||||
},
|
||||
'04-planning-3': {
|
||||
number: '04',
|
||||
@@ -72,7 +112,14 @@ export const STAGE_SPECS: Record<string, StageSpec> = {
|
||||
type: 'research',
|
||||
gate: 'decomposition-approval',
|
||||
promptFile: '04-planning-3-decomposition.md',
|
||||
qualityGates: ['true'],
|
||||
qualityGates: [
|
||||
{
|
||||
kind: 'authority',
|
||||
capability: 'decomposition-approval',
|
||||
reason:
|
||||
'task decomposition approval requires authority sign-off; no mechanical check exists',
|
||||
},
|
||||
],
|
||||
},
|
||||
'05-coding': {
|
||||
number: '05',
|
||||
@@ -92,9 +139,10 @@ export const STAGE_SPECS: Record<string, StageSpec> = {
|
||||
promptFile: '06-review.md',
|
||||
qualityGates: [
|
||||
{
|
||||
type: 'ai-review',
|
||||
command:
|
||||
'echo \'{"summary":"review-pass","verdict":"approve","findings":[],"stats":{"blockers":0,"should_fix":0,"suggestions":0}}\'',
|
||||
kind: 'provider',
|
||||
capability: 'reviewer',
|
||||
reason:
|
||||
'review verdicts require a wired reviewer provider; synthetic approvals are not permitted',
|
||||
},
|
||||
],
|
||||
},
|
||||
@@ -105,7 +153,13 @@ export const STAGE_SPECS: Record<string, StageSpec> = {
|
||||
type: 'coding',
|
||||
gate: 're-review',
|
||||
promptFile: '07-remediate.md',
|
||||
qualityGates: ['true'],
|
||||
qualityGates: [
|
||||
{
|
||||
kind: 'authority',
|
||||
capability: 're-review',
|
||||
reason: 'remediation re-review is an approval-based gate; no mechanical check exists',
|
||||
},
|
||||
],
|
||||
},
|
||||
'08-test': {
|
||||
number: '08',
|
||||
@@ -123,7 +177,13 @@ export const STAGE_SPECS: Record<string, StageSpec> = {
|
||||
type: 'deploy',
|
||||
gate: 'deploy-verification',
|
||||
promptFile: '09-deploy.md',
|
||||
qualityGates: [{ type: 'ci-pipeline', command: 'deploy-verification' }],
|
||||
qualityGates: [
|
||||
{
|
||||
kind: 'provider',
|
||||
capability: 'ci-pipeline',
|
||||
reason: 'deploy verification requires a wired CI pipeline provider',
|
||||
},
|
||||
],
|
||||
},
|
||||
};
|
||||
|
||||
|
||||
Reference in New Issue
Block a user