Some checks failed
Main Confidence / confidence (push) Failing after 46s
## Summary - implement Spec 211 runtime trend reporting with bounded lane history, drift classification, hotspot trend output, and recalibration evidence handling - extend the repo-truth governance seams and workflow wrappers for comparable-bundle hydration, trend artifact publication, and contract-backed reporting - add the Spec 211 planning artifacts, data model, quickstart, tasks, and repository contract documents ## Validation - parsed `specs/211-runtime-trend-recalibration/contracts/test-runtime-trend-history.schema.json` - parsed `specs/211-runtime-trend-recalibration/contracts/test-runtime-trend.logical.openapi.yaml` - re-ran cross-artifact consistency analysis for the Spec 211 artifact set until no material findings remained - no application test suite was re-run as part of this final commit/push/PR step Co-authored-by: Ahmed Darrazi <ahmed.darrazi@live.de> Reviewed-on: #244
112 lines
4.5 KiB
PHP
112 lines
4.5 KiB
PHP
<?php
|
|
|
|
declare(strict_types=1);
|
|
|
|
use Tests\Support\TestLaneBudget;
|
|
use Tests\Support\TestLaneTrendFixtures;
|
|
|
|
function recalibrationEvidenceHistory(string $laneId, int $count): array
|
|
{
|
|
$report = TestLaneTrendFixtures::buildReport(
|
|
laneId: $laneId,
|
|
wallClockSeconds: $laneId === 'confidence' ? 438.0 : 188.0,
|
|
durationsByFile: [
|
|
'tests/Feature/Guards/TestLaneRecalibrationPolicyTest.php' => 12.0,
|
|
],
|
|
ciContext: [
|
|
'workflowId' => $laneId === 'confidence' ? 'main-confidence' : 'pr-fast-feedback',
|
|
'triggerClass' => $laneId === 'confidence' ? 'mainline-push' : 'pull-request',
|
|
'entryPointResolved' => true,
|
|
'workflowLaneMatched' => true,
|
|
],
|
|
comparisonProfile: in_array($laneId, ['fast-feedback', 'confidence'], true) ? 'shared-test-fixture-slimming' : null,
|
|
);
|
|
|
|
$templateRecord = $report['trendHistoryArtifact']['history'][0];
|
|
|
|
return array_values(array_map(
|
|
static function (int $index) use ($templateRecord): array {
|
|
$record = $templateRecord;
|
|
$record['runRef'] = sprintf('%s-evidence-%d', $templateRecord['laneId'], $index + 1);
|
|
$record['generatedAt'] = sprintf('2026-04-%02dT10:00:00+00:00', $index + 1);
|
|
|
|
return $record;
|
|
},
|
|
range(0, $count - 1),
|
|
));
|
|
}
|
|
|
|
it('keeps baseline and budget recalibration rules separate and enforces the stronger budget evidence window', function (): void {
|
|
$assessment = [
|
|
'recalibrationRecommendation' => 'review-baseline',
|
|
];
|
|
$baselineHistory = recalibrationEvidenceHistory('fast-feedback', 3);
|
|
$budgetHistory = recalibrationEvidenceHistory('confidence', 5);
|
|
|
|
$baselineDecision = TestLaneBudget::buildRecalibrationDecisionRecord(
|
|
laneId: 'fast-feedback',
|
|
targetType: 'baseline',
|
|
assessment: $assessment,
|
|
historyRecords: $baselineHistory,
|
|
decisionStatus: 'approved',
|
|
rationaleCode: 'lane-scope-change',
|
|
recordedIn: 'specs/211-runtime-trend-recalibration/spec.md',
|
|
proposedValueSeconds: 184.0,
|
|
);
|
|
$budgetDecision = TestLaneBudget::buildRecalibrationDecisionRecord(
|
|
laneId: 'confidence',
|
|
targetType: 'budget',
|
|
assessment: ['recalibrationRecommendation' => 'review-budget'],
|
|
historyRecords: $budgetHistory,
|
|
decisionStatus: 'approved',
|
|
rationaleCode: 'sustained-erosion',
|
|
recordedIn: 'specs/211-runtime-trend-recalibration/spec.md',
|
|
proposedValueSeconds: 470.0,
|
|
);
|
|
|
|
expect($baselineDecision['targetType'])->toBe('baseline')
|
|
->and($baselineDecision['decisionStatus'])->toBe('approved')
|
|
->and($budgetDecision['targetType'])->toBe('budget')
|
|
->and($budgetDecision['decisionStatus'])->toBe('approved')
|
|
->and($budgetDecision['evidenceRunRefs'])->toHaveCount(5);
|
|
|
|
expect(static fn () => TestLaneBudget::buildRecalibrationDecisionRecord(
|
|
laneId: 'confidence',
|
|
targetType: 'budget',
|
|
assessment: ['recalibrationRecommendation' => 'review-budget'],
|
|
historyRecords: recalibrationEvidenceHistory('confidence', 4),
|
|
decisionStatus: 'approved',
|
|
rationaleCode: 'sustained-erosion',
|
|
recordedIn: 'specs/211-runtime-trend-recalibration/spec.md',
|
|
proposedValueSeconds: 470.0,
|
|
))->toThrow(InvalidArgumentException::class);
|
|
});
|
|
|
|
it('requires approved versus rejected rationale handling that matches the policy', function (): void {
|
|
$history = recalibrationEvidenceHistory('fast-feedback', 3);
|
|
|
|
$rejectedDecision = TestLaneBudget::buildRecalibrationDecisionRecord(
|
|
laneId: 'fast-feedback',
|
|
targetType: 'budget',
|
|
assessment: ['recalibrationRecommendation' => 'investigate'],
|
|
historyRecords: [$history[0]],
|
|
decisionStatus: 'rejected',
|
|
rationaleCode: 'noise-rejected',
|
|
recordedIn: 'specs/211-runtime-trend-recalibration/spec.md',
|
|
);
|
|
|
|
expect($rejectedDecision['decisionStatus'])->toBe('rejected')
|
|
->and($rejectedDecision['rationaleCode'])->toBe('noise-rejected');
|
|
|
|
expect(static fn () => TestLaneBudget::buildRecalibrationDecisionRecord(
|
|
laneId: 'fast-feedback',
|
|
targetType: 'baseline',
|
|
assessment: ['recalibrationRecommendation' => 'review-baseline'],
|
|
historyRecords: $history,
|
|
decisionStatus: 'approved',
|
|
rationaleCode: 'sustained-erosion',
|
|
recordedIn: 'specs/211-runtime-trend-recalibration/spec.md',
|
|
proposedValueSeconds: 184.0,
|
|
))->toThrow(InvalidArgumentException::class);
|
|
});
|