Skip to content

Commit 2e9cfd5

Browse files
ci: restore full cross-platform validation
1 parent 43c7c91 commit 2e9cfd5

1 file changed

Lines changed: 40 additions & 78 deletions

File tree

.github/workflows/ci.yml

Lines changed: 40 additions & 78 deletions
Original file line numberDiff line numberDiff line change
@@ -1,91 +1,53 @@
1-
name: Apply validated fix
1+
name: CI
22

33
on:
44
push:
5-
branches: ['agent/phase2-validated-output']
5+
branches: ['main', 'agent/**']
66
pull_request:
77

88
permissions:
9-
contents: write
9+
contents: read
1010

1111
jobs:
12-
apply-fix:
13-
runs-on: ubuntu-latest
12+
test:
13+
strategy:
14+
fail-fast: false
15+
matrix:
16+
include:
17+
- os: ubuntu-latest
18+
node-version: 22
19+
upload-source: false
20+
- os: ubuntu-latest
21+
node-version: 24
22+
upload-source: true
23+
- os: windows-latest
24+
node-version: 24
25+
upload-source: false
26+
runs-on: ${{ matrix.os }}
1427
steps:
1528
- uses: actions/checkout@v4
16-
with:
17-
ref: agent/phase2-validated-output
1829
- uses: actions/setup-node@v4
1930
with:
20-
node-version: 24
21-
- name: Apply audited regression patch
22-
shell: bash
23-
run: |
24-
if [ "$(git log -1 --pretty=%s)" != "ci: run validated regression fix in PR" ]; then
25-
echo "Patch job is not needed for this commit."
26-
exit 0
27-
fi
28-
python3 <<'PY'
29-
from pathlib import Path
30-
31-
audit = Path('global-template/docgen/lib/audit-guard.mjs')
32-
text = audit.read_text()
33-
old = """ const requested = normalizeClassification(value.classification ?? value.claimClassification ?? value.certainty);
34-
const hasLineEvidence = evidence.some((entry) => entry.startLine && !entry.__stale);
35-
value.classification = requested === 'FACT' && !hasLineEvidence ? 'INFERENCE' : requested;
36-
value.confidence = normalizeConfidence(value.confidence ?? value.confidenceScore, value.classification);
37-
if (value.classification !== 'FACT') value.confidence = Math.min(value.confidence, 0.7);
38-
"""
39-
new = """ const rawClassification = value.classification ?? value.claimClassification ?? value.certainty;
40-
const scalarClassification = rawClassification === undefined || typeof rawClassification === 'string' || typeof rawClassification === 'number';
41-
const requested = normalizeClassification(rawClassification);
42-
const hasLineEvidence = evidence.some((entry) => entry.startLine && !entry.__stale);
43-
const normalizedClassification = requested === 'FACT' && !hasLineEvidence ? 'INFERENCE' : requested;
44-
// A field named `classification` can be a domain catalog rather than semantic
45-
// metadata. Preserve arrays/objects and only normalize scalar metadata.
46-
if (scalarClassification) value.classification = normalizedClassification;
47-
value.confidence = normalizeConfidence(value.confidence ?? value.confidenceScore, normalizedClassification);
48-
if (scalarClassification && normalizedClassification !== 'FACT') value.confidence = Math.min(value.confidence, 0.7);
49-
"""
50-
if text.count(old) != 1:
51-
raise SystemExit(f'audit replacement count was {text.count(old)}, expected 1')
52-
audit.write_text(text.replace(old, new))
53-
54-
test = Path('global-template/docgen/test/semantic-index.test.mjs')
55-
text = test.read_text()
56-
old_name = "test('audit rejects unknown model references and publish rejects stale source artifacts', async () => {"
57-
new_name = "test('audit sanitizes unknown model references and publish rejects stale source artifacts', async () => {"
58-
if text.count(old_name) != 1:
59-
raise SystemExit(f'test-name replacement count was {text.count(old_name)}, expected 1')
60-
text = text.replace(old_name, new_name)
61-
old = """ await assert.rejects(() => audit(root), /Quality failed/); const report = readJson(path.join(p.audit, 'deterministic.json')); assert(report.errors.some((error) => /unknown sourceModelRef/.test(error)));
62-
trace.claims[0].sourceModelRefs = ['system:resource']; writeJson(traceFile, trace); await audit(root);
63-
"""
64-
new = """ const summary = await audit(root);
65-
const sanitizedTrace = readJson(traceFile);
66-
assert.deepEqual(sanitizedTrace.claims[0].sourceModelRefs, []);
67-
assert.equal(summary.deterministicFailures, 0);
68-
"""
69-
if text.count(old) != 1:
70-
raise SystemExit(f'unknown-ref replacement count was {text.count(old)}, expected 1')
71-
text = text.replace(old, new)
72-
old = "assert.match(run.stderr, /modelEnterprise REPAIR \\| bundle omitted decisions/);"
73-
new = "assert.match(run.stderr, /modelEnterprise REPAIR \\| unresolved: decisions/);"
74-
if text.count(old) != 1:
75-
raise SystemExit(f'repair assertion replacement count was {text.count(old)}, expected 1')
76-
test.write_text(text.replace(old, new))
77-
PY
78-
- name: Verify patch
31+
node-version: ${{ matrix.node-version }}
32+
cache: npm
33+
cache-dependency-path: global-template/docgen/package.json
34+
- name: Syntax check
7935
working-directory: global-template/docgen
80-
run: npm run check && npm test
81-
- name: Commit validated patch
82-
shell: bash
83-
run: |
84-
if [ "$(git log -1 --pretty=%s)" != "ci: run validated regression fix in PR" ]; then
85-
exit 0
86-
fi
87-
git config user.name 'docgen-ci'
88-
git config user.email 'actions@users.noreply.github.com'
89-
git add global-template/docgen/lib/audit-guard.mjs global-template/docgen/test/semantic-index.test.mjs
90-
git commit -m 'fix: preserve domain classification catalogs and align audit regressions'
91-
git push origin HEAD:agent/phase2-validated-output
36+
run: npm run check
37+
- name: Unit and integration tests
38+
working-directory: global-template/docgen
39+
run: npm test
40+
- name: Installer dry run
41+
run: node install.mjs --dry-run --no-link-cli
42+
- name: Upload exact CI source
43+
if: always() && matrix.upload-source
44+
uses: actions/upload-artifact@v4
45+
with:
46+
name: docgen-ci-source
47+
if-no-files-found: error
48+
retention-days: 3
49+
path: |
50+
global-template/docgen
51+
global-template/docgen/project-template
52+
install.mjs
53+
VERSION

0 commit comments

Comments
 (0)