@agile-vibe-coding/avc 0.1.1 → 0.3.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/cli/agent-loader.js +21 -0
- package/cli/agents/agent-selector.md +152 -0
- package/cli/agents/architecture-recommender.md +418 -0
- package/cli/agents/code-implementer.md +117 -0
- package/cli/agents/code-validator.md +80 -0
- package/cli/agents/context-reviewer-epic.md +101 -0
- package/cli/agents/context-reviewer-story.md +92 -0
- package/cli/agents/context-writer-epic.md +145 -0
- package/cli/agents/context-writer-story.md +111 -0
- package/cli/agents/database-deep-dive.md +470 -0
- package/cli/agents/database-recommender.md +634 -0
- package/cli/agents/doc-distributor.md +176 -0
- package/cli/agents/doc-writer-epic.md +42 -0
- package/cli/agents/doc-writer-story.md +43 -0
- package/cli/agents/documentation-updater.md +203 -0
- package/cli/agents/duplicate-detector.md +110 -0
- package/cli/agents/epic-story-decomposer.md +559 -0
- package/cli/agents/feature-context-generator.md +91 -0
- package/cli/agents/gap-checker-epic.md +52 -0
- package/cli/agents/impact-checker-story.md +51 -0
- package/cli/agents/migration-guide-generator.md +305 -0
- package/cli/agents/mission-scope-generator.md +143 -0
- package/cli/agents/mission-scope-validator.md +146 -0
- package/cli/agents/project-context-extractor.md +122 -0
- package/cli/agents/project-documentation-creator.json +226 -0
- package/cli/agents/project-documentation-creator.md +595 -0
- package/cli/agents/question-prefiller.md +269 -0
- package/cli/agents/refiner-epic.md +39 -0
- package/cli/agents/refiner-story.md +42 -0
- package/cli/agents/scaffolding-generator.md +99 -0
- package/cli/agents/seed-validator.md +71 -0
- package/cli/agents/story-doc-enricher.md +133 -0
- package/cli/agents/story-scope-reviewer.md +147 -0
- package/cli/agents/story-splitter.md +83 -0
- package/cli/agents/suggestion-business-analyst.md +88 -0
- package/cli/agents/suggestion-deployment-architect.md +263 -0
- package/cli/agents/suggestion-product-manager.md +129 -0
- package/cli/agents/suggestion-security-specialist.md +156 -0
- package/cli/agents/suggestion-technical-architect.md +269 -0
- package/cli/agents/suggestion-ux-researcher.md +93 -0
- package/cli/agents/task-subtask-decomposer.md +188 -0
- package/cli/agents/validator-documentation.json +183 -0
- package/cli/agents/validator-documentation.md +455 -0
- package/cli/agents/validator-selector.md +211 -0
- package/cli/ansi-colors.js +21 -0
- package/cli/api-reference-tool.js +368 -0
- package/cli/build-docs.js +29 -8
- package/cli/ceremony-history.js +369 -0
- package/cli/checks/catalog.json +76 -0
- package/cli/checks/code/quality.json +26 -0
- package/cli/checks/code/testing.json +14 -0
- package/cli/checks/code/traceability.json +26 -0
- package/cli/checks/cross-refs/epic.json +171 -0
- package/cli/checks/cross-refs/story.json +149 -0
- package/cli/checks/epic/api.json +114 -0
- package/cli/checks/epic/backend.json +126 -0
- package/cli/checks/epic/cloud.json +126 -0
- package/cli/checks/epic/data.json +102 -0
- package/cli/checks/epic/database.json +114 -0
- package/cli/checks/epic/developer.json +182 -0
- package/cli/checks/epic/devops.json +174 -0
- package/cli/checks/epic/frontend.json +162 -0
- package/cli/checks/epic/mobile.json +102 -0
- package/cli/checks/epic/qa.json +90 -0
- package/cli/checks/epic/security.json +184 -0
- package/cli/checks/epic/solution-architect.json +192 -0
- package/cli/checks/epic/test-architect.json +90 -0
- package/cli/checks/epic/ui.json +102 -0
- package/cli/checks/epic/ux.json +90 -0
- package/cli/checks/fixes/epic-fix-template.md +10 -0
- package/cli/checks/fixes/story-fix-template.md +10 -0
- package/cli/checks/story/api.json +186 -0
- package/cli/checks/story/backend.json +102 -0
- package/cli/checks/story/cloud.json +102 -0
- package/cli/checks/story/data.json +210 -0
- package/cli/checks/story/database.json +102 -0
- package/cli/checks/story/developer.json +168 -0
- package/cli/checks/story/devops.json +102 -0
- package/cli/checks/story/frontend.json +174 -0
- package/cli/checks/story/mobile.json +102 -0
- package/cli/checks/story/qa.json +210 -0
- package/cli/checks/story/security.json +198 -0
- package/cli/checks/story/solution-architect.json +230 -0
- package/cli/checks/story/test-architect.json +210 -0
- package/cli/checks/story/ui.json +102 -0
- package/cli/checks/story/ux.json +102 -0
- package/cli/coding-order.js +401 -0
- package/cli/command-logger.js +49 -12
- package/cli/components/static-output.js +63 -0
- package/cli/console-output-manager.js +94 -0
- package/cli/dependency-checker.js +72 -0
- package/cli/docs-sync.js +306 -0
- package/cli/epic-story-validator.js +659 -0
- package/cli/evaluation-prompts.js +1008 -0
- package/cli/execution-context.js +195 -0
- package/cli/generate-summary-table.js +340 -0
- package/cli/init-model-config.js +704 -0
- package/cli/init.js +1737 -278
- package/cli/kanban-server-manager.js +227 -0
- package/cli/llm-claude.js +150 -1
- package/cli/llm-gemini.js +109 -0
- package/cli/llm-local.js +493 -0
- package/cli/llm-mock.js +233 -0
- package/cli/llm-openai.js +454 -0
- package/cli/llm-provider.js +379 -3
- package/cli/llm-token-limits.js +211 -0
- package/cli/llm-verifier.js +662 -0
- package/cli/llm-xiaomi.js +143 -0
- package/cli/message-constants.js +49 -0
- package/cli/message-manager.js +334 -0
- package/cli/message-types.js +96 -0
- package/cli/messaging-api.js +291 -0
- package/cli/micro-check-fixer.js +335 -0
- package/cli/micro-check-runner.js +449 -0
- package/cli/micro-check-scorer.js +148 -0
- package/cli/micro-check-validator.js +538 -0
- package/cli/model-pricing.js +192 -0
- package/cli/model-query-engine.js +468 -0
- package/cli/model-recommendation-analyzer.js +495 -0
- package/cli/model-selector.js +270 -0
- package/cli/output-buffer.js +107 -0
- package/cli/process-manager.js +73 -2
- package/cli/prompt-logger.js +57 -0
- package/cli/repl-ink.js +4625 -1094
- package/cli/repl-old.js +3 -4
- package/cli/seed-processor.js +962 -0
- package/cli/sprint-planning-processor.js +4162 -0
- package/cli/template-processor.js +2149 -105
- package/cli/templates/project.md +25 -8
- package/cli/templates/vitepress-config.mts.template +5 -4
- package/cli/token-tracker.js +547 -0
- package/cli/tools/generate-story-validators.js +317 -0
- package/cli/tools/generate-validators.js +669 -0
- package/cli/update-checker.js +19 -17
- package/cli/update-notifier.js +4 -4
- package/cli/validation-router.js +667 -0
- package/cli/verification-tracker.js +563 -0
- package/cli/worktree-runner.js +654 -0
- package/kanban/README.md +386 -0
- package/kanban/client/README.md +205 -0
- package/kanban/client/components.json +20 -0
- package/kanban/client/dist/assets/index-D_KC5EQT.css +1 -0
- package/kanban/client/dist/assets/index-DjY5zqW7.js +351 -0
- package/kanban/client/dist/index.html +16 -0
- package/kanban/client/dist/vite.svg +1 -0
- package/kanban/client/index.html +15 -0
- package/kanban/client/package-lock.json +9442 -0
- package/kanban/client/package.json +44 -0
- package/kanban/client/postcss.config.js +6 -0
- package/kanban/client/public/vite.svg +1 -0
- package/kanban/client/src/App.jsx +651 -0
- package/kanban/client/src/components/ProjectFileEditorPopup.jsx +117 -0
- package/kanban/client/src/components/ceremony/AskArchPopup.jsx +420 -0
- package/kanban/client/src/components/ceremony/AskModelPopup.jsx +629 -0
- package/kanban/client/src/components/ceremony/CeremonyWorkflowModal.jsx +1133 -0
- package/kanban/client/src/components/ceremony/EpicStorySelectionModal.jsx +254 -0
- package/kanban/client/src/components/ceremony/ProviderSwitcherButton.jsx +290 -0
- package/kanban/client/src/components/ceremony/SponsorCallModal.jsx +686 -0
- package/kanban/client/src/components/ceremony/SprintPlanningModal.jsx +838 -0
- package/kanban/client/src/components/ceremony/steps/ArchitectureStep.jsx +150 -0
- package/kanban/client/src/components/ceremony/steps/CompleteStep.jsx +136 -0
- package/kanban/client/src/components/ceremony/steps/DatabaseStep.jsx +202 -0
- package/kanban/client/src/components/ceremony/steps/DeploymentStep.jsx +123 -0
- package/kanban/client/src/components/ceremony/steps/MissionStep.jsx +106 -0
- package/kanban/client/src/components/ceremony/steps/ReviewAnswersStep.jsx +329 -0
- package/kanban/client/src/components/ceremony/steps/RunningStep.jsx +249 -0
- package/kanban/client/src/components/kanban/CardDetailModal.jsx +646 -0
- package/kanban/client/src/components/kanban/EpicSection.jsx +146 -0
- package/kanban/client/src/components/kanban/FilterToolbar.jsx +222 -0
- package/kanban/client/src/components/kanban/GroupingSelector.jsx +63 -0
- package/kanban/client/src/components/kanban/KanbanBoard.jsx +211 -0
- package/kanban/client/src/components/kanban/KanbanCard.jsx +147 -0
- package/kanban/client/src/components/kanban/KanbanColumn.jsx +90 -0
- package/kanban/client/src/components/kanban/RefineWorkItemPopup.jsx +784 -0
- package/kanban/client/src/components/kanban/RunButton.jsx +162 -0
- package/kanban/client/src/components/kanban/SeedButton.jsx +176 -0
- package/kanban/client/src/components/layout/LoadingScreen.jsx +82 -0
- package/kanban/client/src/components/process/ProcessMonitorBar.jsx +80 -0
- package/kanban/client/src/components/settings/AgentEditorPopup.jsx +171 -0
- package/kanban/client/src/components/settings/AgentsTab.jsx +381 -0
- package/kanban/client/src/components/settings/ApiKeysTab.jsx +142 -0
- package/kanban/client/src/components/settings/CeremonyModelsTab.jsx +105 -0
- package/kanban/client/src/components/settings/CheckEditorPopup.jsx +507 -0
- package/kanban/client/src/components/settings/CostThresholdsTab.jsx +95 -0
- package/kanban/client/src/components/settings/ModelPricingTab.jsx +269 -0
- package/kanban/client/src/components/settings/OpenAIAuthSection.jsx +412 -0
- package/kanban/client/src/components/settings/ServersTab.jsx +121 -0
- package/kanban/client/src/components/settings/SettingsModal.jsx +84 -0
- package/kanban/client/src/components/stats/CostModal.jsx +384 -0
- package/kanban/client/src/components/ui/badge.jsx +27 -0
- package/kanban/client/src/components/ui/dialog.jsx +121 -0
- package/kanban/client/src/components/ui/tabs.jsx +85 -0
- package/kanban/client/src/hooks/__tests__/useGrouping.test.js +232 -0
- package/kanban/client/src/hooks/useGrouping.js +177 -0
- package/kanban/client/src/hooks/useWebSocket.js +120 -0
- package/kanban/client/src/lib/__tests__/api.test.js +196 -0
- package/kanban/client/src/lib/__tests__/status-grouping.test.js +94 -0
- package/kanban/client/src/lib/api.js +515 -0
- package/kanban/client/src/lib/status-grouping.js +154 -0
- package/kanban/client/src/lib/utils.js +11 -0
- package/kanban/client/src/main.jsx +10 -0
- package/kanban/client/src/store/__tests__/kanbanStore.test.js +164 -0
- package/kanban/client/src/store/ceremonyStore.js +172 -0
- package/kanban/client/src/store/filterStore.js +201 -0
- package/kanban/client/src/store/kanbanStore.js +123 -0
- package/kanban/client/src/store/processStore.js +65 -0
- package/kanban/client/src/store/sprintPlanningStore.js +33 -0
- package/kanban/client/src/styles/globals.css +59 -0
- package/kanban/client/tailwind.config.js +77 -0
- package/kanban/client/vite.config.js +28 -0
- package/kanban/client/vitest.config.js +28 -0
- package/kanban/dev-start.sh +47 -0
- package/kanban/package.json +12 -0
- package/kanban/server/index.js +537 -0
- package/kanban/server/routes/ceremony.js +454 -0
- package/kanban/server/routes/costs.js +163 -0
- package/kanban/server/routes/openai-oauth.js +366 -0
- package/kanban/server/routes/processes.js +50 -0
- package/kanban/server/routes/settings.js +736 -0
- package/kanban/server/routes/websocket.js +281 -0
- package/kanban/server/routes/work-items.js +487 -0
- package/kanban/server/services/CeremonyService.js +1441 -0
- package/kanban/server/services/FileSystemScanner.js +95 -0
- package/kanban/server/services/FileWatcher.js +144 -0
- package/kanban/server/services/HierarchyBuilder.js +196 -0
- package/kanban/server/services/ProcessRegistry.js +122 -0
- package/kanban/server/services/TaskRunnerService.js +261 -0
- package/kanban/server/services/WorkItemReader.js +123 -0
- package/kanban/server/services/WorkItemRefineService.js +510 -0
- package/kanban/server/start.js +49 -0
- package/kanban/server/utils/kanban-logger.js +132 -0
- package/kanban/server/utils/markdown.js +91 -0
- package/kanban/server/utils/status-grouping.js +107 -0
- package/kanban/server/workers/run-task-worker.js +121 -0
- package/kanban/server/workers/seed-worker.js +94 -0
- package/kanban/server/workers/sponsor-call-worker.js +92 -0
- package/kanban/server/workers/sprint-planning-worker.js +212 -0
- package/package.json +19 -7
- package/cli/agents/documentation.md +0 -302
|
@@ -0,0 +1,369 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Ceremony History Tracker - Records all ceremony executions with status and metadata
|
|
3
|
+
*
|
|
4
|
+
* Tracks when ceremonies are run, their outcomes, and preserves historical data.
|
|
5
|
+
* Helps detect abrupt terminations and provides audit trail.
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
import fs from 'fs';
|
|
9
|
+
import path from 'path';
|
|
10
|
+
|
|
11
|
+
export class CeremonyHistory {
|
|
12
|
+
constructor(avcPath = path.join(process.cwd(), '.avc')) {
|
|
13
|
+
this.avcPath = avcPath;
|
|
14
|
+
this.historyPath = path.join(avcPath, 'ceremonies-history.json');
|
|
15
|
+
this.data = null;
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
/**
|
|
19
|
+
* Initialize ceremony history file if it doesn't exist
|
|
20
|
+
*/
|
|
21
|
+
init() {
|
|
22
|
+
// Ensure .avc directory exists
|
|
23
|
+
if (!fs.existsSync(this.avcPath)) {
|
|
24
|
+
fs.mkdirSync(this.avcPath, { recursive: true });
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
if (!fs.existsSync(this.historyPath)) {
|
|
28
|
+
const initialData = {
|
|
29
|
+
version: "1.0",
|
|
30
|
+
lastUpdated: new Date().toISOString(),
|
|
31
|
+
ceremonies: {}
|
|
32
|
+
};
|
|
33
|
+
this._writeData(initialData);
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
/**
|
|
38
|
+
* Load ceremony history from disk
|
|
39
|
+
*/
|
|
40
|
+
load() {
|
|
41
|
+
if (fs.existsSync(this.historyPath)) {
|
|
42
|
+
this.data = JSON.parse(fs.readFileSync(this.historyPath, 'utf8'));
|
|
43
|
+
} else {
|
|
44
|
+
this.init();
|
|
45
|
+
this.data = JSON.parse(fs.readFileSync(this.historyPath, 'utf8'));
|
|
46
|
+
}
|
|
47
|
+
return this.data;
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
/**
|
|
51
|
+
* Write data to disk atomically
|
|
52
|
+
*/
|
|
53
|
+
_writeData(data) {
|
|
54
|
+
try {
|
|
55
|
+
const tempPath = this.historyPath + '.tmp';
|
|
56
|
+
fs.writeFileSync(tempPath, JSON.stringify(data, null, 2), 'utf8');
|
|
57
|
+
fs.renameSync(tempPath, this.historyPath);
|
|
58
|
+
} catch (error) {
|
|
59
|
+
// Fallback to direct write if atomic write fails
|
|
60
|
+
try {
|
|
61
|
+
fs.writeFileSync(this.historyPath, JSON.stringify(data, null, 2), 'utf8');
|
|
62
|
+
} catch (fallbackError) {
|
|
63
|
+
console.error(`Failed to write ceremony history: ${fallbackError.message}`);
|
|
64
|
+
console.error(`Path: ${this.historyPath}`);
|
|
65
|
+
throw fallbackError;
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
/**
|
|
71
|
+
* Start a new ceremony execution
|
|
72
|
+
* @param {string} ceremonyName - e.g., 'sponsor-call'
|
|
73
|
+
* @param {string} stage - Initial stage (default: 'questionnaire')
|
|
74
|
+
* @returns {string} Execution ID
|
|
75
|
+
*/
|
|
76
|
+
startExecution(ceremonyName, stage = 'questionnaire') {
|
|
77
|
+
this.load();
|
|
78
|
+
|
|
79
|
+
const now = new Date();
|
|
80
|
+
const timestamp = now.toISOString()
|
|
81
|
+
.replace(/T/, '-')
|
|
82
|
+
.replace(/:/g, '-')
|
|
83
|
+
.replace(/\..+/, '');
|
|
84
|
+
|
|
85
|
+
const executionId = `${ceremonyName}-${timestamp}`;
|
|
86
|
+
|
|
87
|
+
// Initialize ceremony entry if doesn't exist
|
|
88
|
+
if (!this.data.ceremonies[ceremonyName]) {
|
|
89
|
+
this.data.ceremonies[ceremonyName] = {
|
|
90
|
+
executions: [],
|
|
91
|
+
totalExecutions: 0,
|
|
92
|
+
lastRun: null,
|
|
93
|
+
lastSuccess: null
|
|
94
|
+
};
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
// Create execution record
|
|
98
|
+
const execution = {
|
|
99
|
+
id: executionId,
|
|
100
|
+
startTime: now.toISOString(),
|
|
101
|
+
endTime: null,
|
|
102
|
+
status: 'in-progress',
|
|
103
|
+
stage: stage,
|
|
104
|
+
answers: null,
|
|
105
|
+
filesGenerated: [],
|
|
106
|
+
tokenUsage: null,
|
|
107
|
+
duration: null,
|
|
108
|
+
outcome: null
|
|
109
|
+
};
|
|
110
|
+
|
|
111
|
+
// Add to executions array
|
|
112
|
+
this.data.ceremonies[ceremonyName].executions.push(execution);
|
|
113
|
+
this.data.ceremonies[ceremonyName].lastRun = now.toISOString();
|
|
114
|
+
this.data.lastUpdated = now.toISOString();
|
|
115
|
+
|
|
116
|
+
this._writeData(this.data);
|
|
117
|
+
|
|
118
|
+
return executionId;
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
/**
|
|
122
|
+
* Update an existing execution
|
|
123
|
+
* @param {string} ceremonyName - Ceremony name
|
|
124
|
+
* @param {string} executionId - Execution ID
|
|
125
|
+
* @param {Object} updates - Fields to update
|
|
126
|
+
*/
|
|
127
|
+
updateExecution(ceremonyName, executionId, updates) {
|
|
128
|
+
this.load();
|
|
129
|
+
|
|
130
|
+
if (!this.data.ceremonies[ceremonyName]) {
|
|
131
|
+
throw new Error(`Ceremony '${ceremonyName}' not found in history`);
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
const execution = this.data.ceremonies[ceremonyName].executions.find(
|
|
135
|
+
e => e.id === executionId
|
|
136
|
+
);
|
|
137
|
+
|
|
138
|
+
if (!execution) {
|
|
139
|
+
throw new Error(`Execution '${executionId}' not found for ceremony '${ceremonyName}'`);
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
// Update fields
|
|
143
|
+
Object.assign(execution, updates);
|
|
144
|
+
this.data.lastUpdated = new Date().toISOString();
|
|
145
|
+
|
|
146
|
+
this._writeData(this.data);
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
/**
|
|
150
|
+
* Complete an execution
|
|
151
|
+
* @param {string} ceremonyName - Ceremony name
|
|
152
|
+
* @param {string} executionId - Execution ID
|
|
153
|
+
* @param {string} outcome - 'success', 'user-cancelled', or 'abrupt-termination'
|
|
154
|
+
* @param {Object} metadata - Additional data (answers, filesGenerated, tokenUsage, etc.)
|
|
155
|
+
*/
|
|
156
|
+
completeExecution(ceremonyName, executionId, outcome, metadata = {}) {
|
|
157
|
+
this.load();
|
|
158
|
+
|
|
159
|
+
if (!this.data.ceremonies[ceremonyName]) {
|
|
160
|
+
throw new Error(`Ceremony '${ceremonyName}' not found in history`);
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
const execution = this.data.ceremonies[ceremonyName].executions.find(
|
|
164
|
+
e => e.id === executionId
|
|
165
|
+
);
|
|
166
|
+
|
|
167
|
+
if (!execution) {
|
|
168
|
+
throw new Error(`Execution '${executionId}' not found for ceremony '${ceremonyName}'`);
|
|
169
|
+
}
|
|
170
|
+
|
|
171
|
+
const now = new Date();
|
|
172
|
+
const startTime = new Date(execution.startTime);
|
|
173
|
+
const duration = now - startTime;
|
|
174
|
+
|
|
175
|
+
// Determine status based on outcome
|
|
176
|
+
let status;
|
|
177
|
+
switch (outcome) {
|
|
178
|
+
case 'success':
|
|
179
|
+
status = 'completed';
|
|
180
|
+
break;
|
|
181
|
+
case 'user-cancelled':
|
|
182
|
+
status = 'cancelled';
|
|
183
|
+
break;
|
|
184
|
+
case 'abrupt-termination':
|
|
185
|
+
status = 'aborted';
|
|
186
|
+
break;
|
|
187
|
+
default:
|
|
188
|
+
status = 'completed';
|
|
189
|
+
}
|
|
190
|
+
|
|
191
|
+
// Update execution
|
|
192
|
+
execution.status = status;
|
|
193
|
+
execution.endTime = now.toISOString();
|
|
194
|
+
execution.outcome = outcome;
|
|
195
|
+
execution.duration = duration;
|
|
196
|
+
|
|
197
|
+
// Merge metadata
|
|
198
|
+
if (metadata.answers) execution.answers = metadata.answers;
|
|
199
|
+
if (metadata.filesGenerated) execution.filesGenerated = metadata.filesGenerated;
|
|
200
|
+
if (metadata.tokenUsage) execution.tokenUsage = metadata.tokenUsage;
|
|
201
|
+
if (metadata.cost) execution.cost = metadata.cost;
|
|
202
|
+
if (metadata.model) execution.model = metadata.model;
|
|
203
|
+
if (metadata.stage) execution.stage = metadata.stage;
|
|
204
|
+
if (metadata.error) execution.error = metadata.error;
|
|
205
|
+
if (metadata.note) execution.note = metadata.note;
|
|
206
|
+
|
|
207
|
+
// Update ceremony totals
|
|
208
|
+
this.data.ceremonies[ceremonyName].totalExecutions =
|
|
209
|
+
this.data.ceremonies[ceremonyName].executions.length;
|
|
210
|
+
|
|
211
|
+
if (outcome === 'success') {
|
|
212
|
+
this.data.ceremonies[ceremonyName].lastSuccess = now.toISOString();
|
|
213
|
+
}
|
|
214
|
+
|
|
215
|
+
this.data.lastUpdated = now.toISOString();
|
|
216
|
+
|
|
217
|
+
this._writeData(this.data);
|
|
218
|
+
}
|
|
219
|
+
|
|
220
|
+
/**
|
|
221
|
+
* Archive answers to an execution (before LLM generation starts)
|
|
222
|
+
* @param {string} ceremonyName - Ceremony name
|
|
223
|
+
* @param {string} executionId - Execution ID
|
|
224
|
+
* @param {Object} answers - Questionnaire answers
|
|
225
|
+
*/
|
|
226
|
+
archiveAnswers(ceremonyName, executionId, answers) {
|
|
227
|
+
this.updateExecution(ceremonyName, executionId, {
|
|
228
|
+
answers: { ...answers }
|
|
229
|
+
});
|
|
230
|
+
}
|
|
231
|
+
|
|
232
|
+
/**
|
|
233
|
+
* Get the most recent execution for a ceremony
|
|
234
|
+
* @param {string} ceremonyName - Ceremony name
|
|
235
|
+
* @returns {Object|null} Execution record or null
|
|
236
|
+
*/
|
|
237
|
+
getLastExecution(ceremonyName) {
|
|
238
|
+
this.load();
|
|
239
|
+
|
|
240
|
+
if (!this.data.ceremonies[ceremonyName]) {
|
|
241
|
+
return null;
|
|
242
|
+
}
|
|
243
|
+
|
|
244
|
+
const executions = this.data.ceremonies[ceremonyName].executions;
|
|
245
|
+
if (executions.length === 0) {
|
|
246
|
+
return null;
|
|
247
|
+
}
|
|
248
|
+
|
|
249
|
+
// Return most recent (last in array)
|
|
250
|
+
return executions[executions.length - 1];
|
|
251
|
+
}
|
|
252
|
+
|
|
253
|
+
/**
|
|
254
|
+
* Get a specific execution by ID
|
|
255
|
+
* @param {string} ceremonyName - Ceremony name
|
|
256
|
+
* @param {string} executionId - Execution ID
|
|
257
|
+
* @returns {Object|null} Execution record or null
|
|
258
|
+
*/
|
|
259
|
+
getExecutionById(ceremonyName, executionId) {
|
|
260
|
+
this.load();
|
|
261
|
+
|
|
262
|
+
if (!this.data.ceremonies[ceremonyName]) {
|
|
263
|
+
return null;
|
|
264
|
+
}
|
|
265
|
+
|
|
266
|
+
return this.data.ceremonies[ceremonyName].executions.find(
|
|
267
|
+
e => e.id === executionId
|
|
268
|
+
) || null;
|
|
269
|
+
}
|
|
270
|
+
|
|
271
|
+
/**
|
|
272
|
+
* Get all executions for a ceremony
|
|
273
|
+
* @param {string} ceremonyName - Ceremony name
|
|
274
|
+
* @returns {Array} Array of execution records (newest first)
|
|
275
|
+
*/
|
|
276
|
+
getAllExecutions(ceremonyName) {
|
|
277
|
+
this.load();
|
|
278
|
+
|
|
279
|
+
if (!this.data.ceremonies[ceremonyName]) {
|
|
280
|
+
return [];
|
|
281
|
+
}
|
|
282
|
+
|
|
283
|
+
// Return copy, sorted by startTime descending
|
|
284
|
+
return [...this.data.ceremonies[ceremonyName].executions]
|
|
285
|
+
.sort((a, b) => new Date(b.startTime) - new Date(a.startTime));
|
|
286
|
+
}
|
|
287
|
+
|
|
288
|
+
/**
|
|
289
|
+
* Detect if the last execution was abruptly terminated
|
|
290
|
+
* @param {string} ceremonyName - Ceremony name
|
|
291
|
+
* @returns {boolean} True if abrupt termination detected
|
|
292
|
+
*/
|
|
293
|
+
detectAbruptTermination(ceremonyName) {
|
|
294
|
+
const lastExecution = this.getLastExecution(ceremonyName);
|
|
295
|
+
|
|
296
|
+
if (!lastExecution) {
|
|
297
|
+
return false;
|
|
298
|
+
}
|
|
299
|
+
|
|
300
|
+
// Check if last execution is still in-progress and in LLM generation stage
|
|
301
|
+
return lastExecution.status === 'in-progress' &&
|
|
302
|
+
lastExecution.stage === 'llm-generation';
|
|
303
|
+
}
|
|
304
|
+
|
|
305
|
+
/**
|
|
306
|
+
* Clean up abrupt termination (mark as aborted)
|
|
307
|
+
* @param {string} ceremonyName - Ceremony name
|
|
308
|
+
*/
|
|
309
|
+
cleanupAbruptTermination(ceremonyName) {
|
|
310
|
+
const lastExecution = this.getLastExecution(ceremonyName);
|
|
311
|
+
|
|
312
|
+
if (!lastExecution || lastExecution.status !== 'in-progress') {
|
|
313
|
+
return;
|
|
314
|
+
}
|
|
315
|
+
|
|
316
|
+
this.completeExecution(ceremonyName, lastExecution.id, 'abrupt-termination', {
|
|
317
|
+
note: 'Process was interrupted during LLM generation',
|
|
318
|
+
stage: lastExecution.stage
|
|
319
|
+
});
|
|
320
|
+
}
|
|
321
|
+
|
|
322
|
+
/**
|
|
323
|
+
* Get ceremony statistics
|
|
324
|
+
* @param {string} ceremonyName - Ceremony name
|
|
325
|
+
* @returns {Object} Statistics object
|
|
326
|
+
*/
|
|
327
|
+
getStats(ceremonyName) {
|
|
328
|
+
this.load();
|
|
329
|
+
|
|
330
|
+
if (!this.data.ceremonies[ceremonyName]) {
|
|
331
|
+
return {
|
|
332
|
+
totalExecutions: 0,
|
|
333
|
+
successful: 0,
|
|
334
|
+
cancelled: 0,
|
|
335
|
+
aborted: 0,
|
|
336
|
+
lastRun: null,
|
|
337
|
+
lastSuccess: null
|
|
338
|
+
};
|
|
339
|
+
}
|
|
340
|
+
|
|
341
|
+
const ceremony = this.data.ceremonies[ceremonyName];
|
|
342
|
+
const executions = ceremony.executions;
|
|
343
|
+
|
|
344
|
+
return {
|
|
345
|
+
totalExecutions: ceremony.totalExecutions,
|
|
346
|
+
successful: executions.filter(e => e.outcome === 'success').length,
|
|
347
|
+
cancelled: executions.filter(e => e.outcome === 'user-cancelled').length,
|
|
348
|
+
aborted: executions.filter(e => e.outcome === 'abrupt-termination').length,
|
|
349
|
+
lastRun: ceremony.lastRun,
|
|
350
|
+
lastSuccess: ceremony.lastSuccess
|
|
351
|
+
};
|
|
352
|
+
}
|
|
353
|
+
|
|
354
|
+
/**
|
|
355
|
+
* Check if a ceremony has completed successfully at least once
|
|
356
|
+
* @param {string} ceremonyName - Ceremony name
|
|
357
|
+
* @returns {boolean} True if ceremony has a successful completion
|
|
358
|
+
*/
|
|
359
|
+
hasSuccessfulCompletion(ceremonyName) {
|
|
360
|
+
this.load();
|
|
361
|
+
|
|
362
|
+
if (!this.data.ceremonies[ceremonyName]) {
|
|
363
|
+
return false;
|
|
364
|
+
}
|
|
365
|
+
|
|
366
|
+
// Check if lastSuccess is set (indicates at least one successful execution)
|
|
367
|
+
return this.data.ceremonies[ceremonyName].lastSuccess !== null;
|
|
368
|
+
}
|
|
369
|
+
}
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": "1.0.0",
|
|
3
|
+
"description": "Micro-check catalog for AVC validation system",
|
|
4
|
+
"tiers": {
|
|
5
|
+
"1": "Independent micro-checks — one YES/NO question per LLM call",
|
|
6
|
+
"2": "Cross-reference checks — validate consistency across perspectives",
|
|
7
|
+
"3": "Programmatic pattern detection — pure JS, no LLM"
|
|
8
|
+
},
|
|
9
|
+
"perspectives": [
|
|
10
|
+
"solution-architect",
|
|
11
|
+
"security",
|
|
12
|
+
"developer",
|
|
13
|
+
"devops",
|
|
14
|
+
"cloud",
|
|
15
|
+
"backend",
|
|
16
|
+
"database",
|
|
17
|
+
"api",
|
|
18
|
+
"frontend",
|
|
19
|
+
"ui",
|
|
20
|
+
"ux",
|
|
21
|
+
"mobile",
|
|
22
|
+
"data",
|
|
23
|
+
"qa",
|
|
24
|
+
"test-architect"
|
|
25
|
+
],
|
|
26
|
+
"scopes": ["epic", "story"],
|
|
27
|
+
"checkCounts": {
|
|
28
|
+
"epic": {
|
|
29
|
+
"tier1": 157,
|
|
30
|
+
"tier2": 15,
|
|
31
|
+
"byPerspective": {
|
|
32
|
+
"solution-architect": 16,
|
|
33
|
+
"security": 15,
|
|
34
|
+
"developer": 16,
|
|
35
|
+
"devops": 14,
|
|
36
|
+
"cloud": 10,
|
|
37
|
+
"backend": 10,
|
|
38
|
+
"database": 9,
|
|
39
|
+
"api": 9,
|
|
40
|
+
"frontend": 13,
|
|
41
|
+
"ui": 8,
|
|
42
|
+
"ux": 7,
|
|
43
|
+
"mobile": 8,
|
|
44
|
+
"data": 8,
|
|
45
|
+
"qa": 7,
|
|
46
|
+
"test-architect": 7
|
|
47
|
+
}
|
|
48
|
+
},
|
|
49
|
+
"story": {
|
|
50
|
+
"tier1": 185,
|
|
51
|
+
"tier2": 13,
|
|
52
|
+
"byPerspective": {
|
|
53
|
+
"solution-architect": 19,
|
|
54
|
+
"security": 16,
|
|
55
|
+
"developer": 14,
|
|
56
|
+
"devops": 8,
|
|
57
|
+
"cloud": 8,
|
|
58
|
+
"backend": 8,
|
|
59
|
+
"database": 8,
|
|
60
|
+
"api": 15,
|
|
61
|
+
"frontend": 14,
|
|
62
|
+
"ui": 8,
|
|
63
|
+
"ux": 8,
|
|
64
|
+
"mobile": 8,
|
|
65
|
+
"data": 17,
|
|
66
|
+
"qa": 17,
|
|
67
|
+
"test-architect": 17
|
|
68
|
+
}
|
|
69
|
+
},
|
|
70
|
+
"total": {
|
|
71
|
+
"tier1": 342,
|
|
72
|
+
"tier2": 28,
|
|
73
|
+
"all": 370
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
[
|
|
2
|
+
{
|
|
3
|
+
"id": "qual-01",
|
|
4
|
+
"severity": "major",
|
|
5
|
+
"question": "Are ALL functions 25 lines or fewer (excluding JSDoc comments and blank lines)?",
|
|
6
|
+
"evidenceGuide": "Count executable lines per function body. List any function exceeding 25 lines with its actual line count. Orchestration methods up to 50 lines are acceptable if each line is a single function call."
|
|
7
|
+
},
|
|
8
|
+
{
|
|
9
|
+
"id": "qual-02",
|
|
10
|
+
"severity": "major",
|
|
11
|
+
"question": "Are business logic functions pure (no file I/O, no network calls, no database access, no console output)?",
|
|
12
|
+
"evidenceGuide": "Check non-boundary functions for side-effect calls: fs.*, fetch, database queries, console.*. Side effects must be isolated in clearly named boundary functions (e.g., readFromDatabase, writeToFile, sendApiRequest)."
|
|
13
|
+
},
|
|
14
|
+
{
|
|
15
|
+
"id": "qual-03",
|
|
16
|
+
"severity": "minor",
|
|
17
|
+
"question": "Do function names use domain vocabulary from the documentation chain rather than generic programming terms?",
|
|
18
|
+
"evidenceGuide": "Compare function names against domain nouns and verbs found in the task's context.md and doc.md. Flag generic names like processData, handleRequest, doWork, updateDB. Prefer domain terms like bookAppointment, validateSlotAvailability, sendReminderMessage."
|
|
19
|
+
},
|
|
20
|
+
{
|
|
21
|
+
"id": "qual-04",
|
|
22
|
+
"severity": "minor",
|
|
23
|
+
"question": "Is each source file named after its primary exported function using kebab-case with the hierarchy prefix?",
|
|
24
|
+
"evidenceGuide": "Compare file names to their primary export. Expected pattern: e0001-s0002-t0003-function-name.js for export e0001_s0002_t0003_functionName."
|
|
25
|
+
}
|
|
26
|
+
]
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
[
|
|
2
|
+
{
|
|
3
|
+
"id": "test-01",
|
|
4
|
+
"severity": "critical",
|
|
5
|
+
"question": "Do all test describe blocks reference acceptance criterion IDs in the format taskId#ACn (e.g., context-0001-0002-0003#AC1)?",
|
|
6
|
+
"evidenceGuide": "Check every describe() string in test files for an AC ID reference. The format must include the full task ID and AC number. List any describe blocks without a valid reference."
|
|
7
|
+
},
|
|
8
|
+
{
|
|
9
|
+
"id": "test-02",
|
|
10
|
+
"severity": "major",
|
|
11
|
+
"question": "Is there no orphan code — does every function (exported or helper) have a @satisfies tag or belong to a module whose primary export has one?",
|
|
12
|
+
"evidenceGuide": "List any functions that cannot be traced to an acceptance criterion through either a direct @satisfies tag or membership in a file whose primary export has one."
|
|
13
|
+
}
|
|
14
|
+
]
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
[
|
|
2
|
+
{
|
|
3
|
+
"id": "trace-01",
|
|
4
|
+
"severity": "critical",
|
|
5
|
+
"question": "Do ALL exported functions and classes have the correct hierarchy prefix e{X}_s{Y}_t{Z}_ matching the task ID?",
|
|
6
|
+
"evidenceGuide": "Check every export statement. The prefix must match the task's position in the hierarchy: e{epicNum}_s{storyNum}_t{taskNum}_. List any exports missing or using wrong prefix."
|
|
7
|
+
},
|
|
8
|
+
{
|
|
9
|
+
"id": "trace-02",
|
|
10
|
+
"severity": "critical",
|
|
11
|
+
"question": "Does every generated file have a provenance header with @file, @story, @task, @agent, and @generated JSDoc tags?",
|
|
12
|
+
"evidenceGuide": "Check the first JSDoc comment block at the top of each file for all five required tags. List any files missing tags."
|
|
13
|
+
},
|
|
14
|
+
{
|
|
15
|
+
"id": "trace-03",
|
|
16
|
+
"severity": "critical",
|
|
17
|
+
"question": "Does every exported function have a JSDoc comment with a @satisfies tag referencing a specific acceptance criterion (e.g., context-XXXX-XXXX-XXXX#AC1)?",
|
|
18
|
+
"evidenceGuide": "Check the JSDoc block above each exported function for a @satisfies tag with a valid AC reference. List any exports without it."
|
|
19
|
+
},
|
|
20
|
+
{
|
|
21
|
+
"id": "trace-04",
|
|
22
|
+
"severity": "major",
|
|
23
|
+
"question": "Is every acceptance criterion from the task's work.json covered by at least one exported function (@satisfies) AND at least one test (describe block)?",
|
|
24
|
+
"evidenceGuide": "Cross-reference the acceptance criteria array from work.json against @satisfies tags in source files and describe() strings in test files. List any uncovered ACs."
|
|
25
|
+
}
|
|
26
|
+
]
|
|
@@ -0,0 +1,171 @@
|
|
|
1
|
+
{
|
|
2
|
+
"scope": "epic",
|
|
3
|
+
"tier": 2,
|
|
4
|
+
"checks": [
|
|
5
|
+
{
|
|
6
|
+
"id": "xref-sec-api-epic-01",
|
|
7
|
+
"tier": 2,
|
|
8
|
+
"perspectives": ["security", "api"],
|
|
9
|
+
"severity": "critical",
|
|
10
|
+
"category": "consistency",
|
|
11
|
+
"dependsOn": ["sec-epic-08", "api-epic-01"],
|
|
12
|
+
"question": "Security requires: {{sec-epic-08.evidence}}. API defines: {{api-epic-01.evidence}}. Are the named roles and permission boundaries consistent with the API endpoint definitions?",
|
|
13
|
+
"failDescription": "Security role model and API endpoint access control definitions are inconsistent",
|
|
14
|
+
"failSuggestion": "Align API endpoint authorization with the security role model — ensure every endpoint names which roles can access it"
|
|
15
|
+
},
|
|
16
|
+
{
|
|
17
|
+
"id": "xref-sec-api-epic-02",
|
|
18
|
+
"tier": 2,
|
|
19
|
+
"perspectives": ["security", "api"],
|
|
20
|
+
"severity": "major",
|
|
21
|
+
"category": "consistency",
|
|
22
|
+
"dependsOn": ["sec-epic-03", "api-epic-06"],
|
|
23
|
+
"question": "Security defines trust boundaries: {{sec-epic-03.evidence}}. API patterns: {{api-epic-06.evidence}}. Are API error codes consistent with the security error taxonomy?",
|
|
24
|
+
"failDescription": "Security error taxonomy and API error codes are inconsistent",
|
|
25
|
+
"failSuggestion": "Ensure API error codes (401/403/404/422/429) match the security-defined error taxonomy"
|
|
26
|
+
},
|
|
27
|
+
{
|
|
28
|
+
"id": "xref-sec-db-epic-01",
|
|
29
|
+
"tier": 2,
|
|
30
|
+
"perspectives": ["security", "database"],
|
|
31
|
+
"severity": "critical",
|
|
32
|
+
"category": "consistency",
|
|
33
|
+
"dependsOn": ["sec-epic-12", "db-epic-01"],
|
|
34
|
+
"question": "Security identifies PII fields: {{sec-epic-12.evidence}}. Database defines schema: {{db-epic-01.evidence}}. Are PII fields identified in the database schema with appropriate protection?",
|
|
35
|
+
"failDescription": "Security PII requirements and database schema protection are misaligned",
|
|
36
|
+
"failSuggestion": "Ensure PII fields identified by security are protected in the database schema (encryption at rest, access controls)"
|
|
37
|
+
},
|
|
38
|
+
{
|
|
39
|
+
"id": "xref-sec-db-epic-02",
|
|
40
|
+
"tier": 2,
|
|
41
|
+
"perspectives": ["security", "database"],
|
|
42
|
+
"severity": "major",
|
|
43
|
+
"category": "consistency",
|
|
44
|
+
"dependsOn": ["sec-epic-14", "db-epic-06"],
|
|
45
|
+
"question": "Security requires audit logging: {{sec-epic-14.evidence}}. Database architecture: {{db-epic-06.evidence}}. Is the audit log storage aligned with database architecture?",
|
|
46
|
+
"failDescription": "Security audit log requirements and database storage architecture are inconsistent",
|
|
47
|
+
"failSuggestion": "Align audit log storage with database architecture — define where and how audit events are persisted"
|
|
48
|
+
},
|
|
49
|
+
{
|
|
50
|
+
"id": "xref-be-api-epic-01",
|
|
51
|
+
"tier": 2,
|
|
52
|
+
"perspectives": ["backend", "api"],
|
|
53
|
+
"severity": "critical",
|
|
54
|
+
"category": "consistency",
|
|
55
|
+
"dependsOn": ["be-epic-01", "api-epic-01"],
|
|
56
|
+
"question": "Backend defines service boundaries: {{be-epic-01.evidence}}. API defines endpoint surface: {{api-epic-01.evidence}}. Are backend service boundaries consistent with API endpoint definitions?",
|
|
57
|
+
"failDescription": "Backend service boundaries and API endpoint surface are inconsistent",
|
|
58
|
+
"failSuggestion": "Align backend services with API endpoints — each API endpoint should map to a defined backend service"
|
|
59
|
+
},
|
|
60
|
+
{
|
|
61
|
+
"id": "xref-be-api-epic-02",
|
|
62
|
+
"tier": 2,
|
|
63
|
+
"perspectives": ["backend", "api"],
|
|
64
|
+
"severity": "major",
|
|
65
|
+
"category": "consistency",
|
|
66
|
+
"dependsOn": ["be-epic-07", "api-epic-07"],
|
|
67
|
+
"question": "Backend architecture patterns: {{be-epic-07.evidence}}. API performance: {{api-epic-07.evidence}}. Are backend architectural patterns supporting the API performance requirements?",
|
|
68
|
+
"failDescription": "Backend architecture does not adequately support API performance requirements",
|
|
69
|
+
"failSuggestion": "Ensure backend architecture (caching, async processing) supports API performance targets (latency, throughput)"
|
|
70
|
+
},
|
|
71
|
+
{
|
|
72
|
+
"id": "xref-devops-be-epic-01",
|
|
73
|
+
"tier": 2,
|
|
74
|
+
"perspectives": ["devops", "backend"],
|
|
75
|
+
"severity": "major",
|
|
76
|
+
"category": "consistency",
|
|
77
|
+
"dependsOn": ["devops-epic-08", "be-epic-01"],
|
|
78
|
+
"question": "DevOps infrastructure: {{devops-epic-08.evidence}}. Backend boundaries: {{be-epic-01.evidence}}. Are deployment infrastructure patterns aligned with backend service architecture?",
|
|
79
|
+
"failDescription": "DevOps deployment infrastructure and backend service architecture are misaligned",
|
|
80
|
+
"failSuggestion": "Align deployment infrastructure with backend architecture — each service should have a defined deployment strategy"
|
|
81
|
+
},
|
|
82
|
+
{
|
|
83
|
+
"id": "xref-devops-be-epic-02",
|
|
84
|
+
"tier": 2,
|
|
85
|
+
"perspectives": ["devops", "backend"],
|
|
86
|
+
"severity": "major",
|
|
87
|
+
"category": "consistency",
|
|
88
|
+
"dependsOn": ["devops-epic-10", "be-epic-08"],
|
|
89
|
+
"question": "DevOps observability: {{devops-epic-10.evidence}}. Backend performance: {{be-epic-08.evidence}}. Does the observability stack cover backend performance monitoring needs?",
|
|
90
|
+
"failDescription": "DevOps observability stack does not adequately cover backend performance monitoring",
|
|
91
|
+
"failSuggestion": "Ensure observability stack monitors backend performance metrics: latency, error rates, resource utilization"
|
|
92
|
+
},
|
|
93
|
+
{
|
|
94
|
+
"id": "xref-qa-dev-epic-01",
|
|
95
|
+
"tier": 2,
|
|
96
|
+
"perspectives": ["qa", "developer"],
|
|
97
|
+
"severity": "major",
|
|
98
|
+
"category": "consistency",
|
|
99
|
+
"dependsOn": ["qa-epic-01", "dev-epic-06"],
|
|
100
|
+
"question": "QA defines test boundaries: {{qa-epic-01.evidence}}. Developer testing strategy: {{dev-epic-06.evidence}}. Are QA quality gates aligned with the developer testing strategy?",
|
|
101
|
+
"failDescription": "QA quality gates and developer testing strategy are not aligned",
|
|
102
|
+
"failSuggestion": "Align QA quality gates with developer testing — ensure coverage targets, test types, and quality metrics are consistent"
|
|
103
|
+
},
|
|
104
|
+
{
|
|
105
|
+
"id": "xref-qa-sec-epic-01",
|
|
106
|
+
"tier": 2,
|
|
107
|
+
"perspectives": ["qa", "security"],
|
|
108
|
+
"severity": "major",
|
|
109
|
+
"category": "consistency",
|
|
110
|
+
"dependsOn": ["qa-epic-05", "sec-epic-01"],
|
|
111
|
+
"question": "QA test patterns: {{qa-epic-05.evidence}}. Security threat model: {{sec-epic-01.evidence}}. Does the QA test strategy include security testing for identified threat categories?",
|
|
112
|
+
"failDescription": "QA test strategy does not include security testing for identified threats",
|
|
113
|
+
"failSuggestion": "Include security test scenarios in QA strategy for each threat category: auth abuse, authz bypass, injection"
|
|
114
|
+
},
|
|
115
|
+
{
|
|
116
|
+
"id": "xref-sa-be-epic-01",
|
|
117
|
+
"tier": 2,
|
|
118
|
+
"perspectives": ["solution-architect", "backend"],
|
|
119
|
+
"severity": "major",
|
|
120
|
+
"category": "consistency",
|
|
121
|
+
"dependsOn": ["sa-epic-08", "be-epic-03"],
|
|
122
|
+
"question": "SA integration points: {{sa-epic-08.evidence}}. Backend dependencies: {{be-epic-03.evidence}}. Are architecture integration points consistent with backend service dependencies?",
|
|
123
|
+
"failDescription": "Architecture integration points and backend dependencies are inconsistent",
|
|
124
|
+
"failSuggestion": "Align integration points with backend dependencies — every consumed service should be listed in both places"
|
|
125
|
+
},
|
|
126
|
+
{
|
|
127
|
+
"id": "xref-sa-db-epic-01",
|
|
128
|
+
"tier": 2,
|
|
129
|
+
"perspectives": ["solution-architect", "database"],
|
|
130
|
+
"severity": "major",
|
|
131
|
+
"category": "consistency",
|
|
132
|
+
"dependsOn": ["sa-epic-05", "db-epic-01"],
|
|
133
|
+
"question": "SA database technology: {{sa-epic-05.evidence}}. Database boundaries: {{db-epic-01.evidence}}. Are the SA-specified database technology and the database schema design consistent?",
|
|
134
|
+
"failDescription": "SA database technology choice and database schema design are inconsistent",
|
|
135
|
+
"failSuggestion": "Ensure database technology matches across SA and database perspectives — same engine, same ORM, same conventions"
|
|
136
|
+
},
|
|
137
|
+
{
|
|
138
|
+
"id": "xref-fe-api-epic-01",
|
|
139
|
+
"tier": 2,
|
|
140
|
+
"perspectives": ["frontend", "api"],
|
|
141
|
+
"severity": "major",
|
|
142
|
+
"category": "consistency",
|
|
143
|
+
"dependsOn": ["fe-epic-02", "api-epic-01"],
|
|
144
|
+
"question": "Frontend server-state management: {{fe-epic-02.evidence}}. API boundaries: {{api-epic-01.evidence}}. Does the frontend data fetching strategy align with the API endpoint structure?",
|
|
145
|
+
"failDescription": "Frontend data fetching strategy and API endpoint structure are misaligned",
|
|
146
|
+
"failSuggestion": "Align frontend data fetching with API design — cache keys, refetch patterns, and pagination should match API contracts"
|
|
147
|
+
},
|
|
148
|
+
{
|
|
149
|
+
"id": "xref-fe-sec-epic-01",
|
|
150
|
+
"tier": 2,
|
|
151
|
+
"perspectives": ["frontend", "security"],
|
|
152
|
+
"severity": "major",
|
|
153
|
+
"category": "consistency",
|
|
154
|
+
"dependsOn": ["fe-epic-09", "sec-epic-04"],
|
|
155
|
+
"question": "Frontend accessibility standard: {{fe-epic-09.evidence}}. Security session lifecycle: {{sec-epic-04.evidence}}. Does the frontend handle session expiration and token refresh consistently with the security model?",
|
|
156
|
+
"failDescription": "Frontend session handling and security session lifecycle are inconsistent",
|
|
157
|
+
"failSuggestion": "Ensure frontend handles session expiration per security model: redirect on 401, refresh token flow, logout cleanup"
|
|
158
|
+
},
|
|
159
|
+
{
|
|
160
|
+
"id": "xref-ta-devops-epic-01",
|
|
161
|
+
"tier": 2,
|
|
162
|
+
"perspectives": ["test-architect", "devops"],
|
|
163
|
+
"severity": "minor",
|
|
164
|
+
"category": "consistency",
|
|
165
|
+
"dependsOn": ["ta-epic-01", "devops-epic-02"],
|
|
166
|
+
"question": "Test architecture: {{ta-epic-01.evidence}}. DevOps CI/CD: {{devops-epic-02.evidence}}. Is the test automation framework integrated into the CI/CD pipeline?",
|
|
167
|
+
"failDescription": "Test automation framework is not integrated into the CI/CD pipeline",
|
|
168
|
+
"failSuggestion": "Integrate test framework into CI/CD: run unit tests on commit, integration tests on PR, e2e tests before deploy"
|
|
169
|
+
}
|
|
170
|
+
]
|
|
171
|
+
}
|