docs(sdlc): cite only main and commits up to project end; guard enforces it

This commit is contained in:
Thanakorn
2026-09-25 15:46:19 +07:00
parent 7b5cc192d9
commit 31f2629ddf
7 changed files with 18 additions and 6 deletions
+12 -3
View File
@@ -3,7 +3,7 @@
// dated 31 Jul cannot record results from the 10–14 Aug test run, and so on.
// Planned dates in the future are fine; facts that only came into being later are not.
import { execFileSync } from 'node:child_process';
import { TAG } from './project.mjs';
import { TAG, END } from './project.mjs';
import { CORRECTIONS } from './history.mjs';
/** Document date from its name: "... 25690817 V1.0 ..." -> 2026-08-17 */
@@ -37,7 +37,8 @@ export function hindsightErrors(docs, root) {
if (!commitDates.has(h)) commitDates.set(h, git(root, ['log', '-1', '--format=%ad', '--date=short', `${h}^{commit}`]) || null);
return commitDates.get(h);
};
const tagDate = hasGit ? git(root, ['for-each-ref', `refs/tags/${TAG}`, '--format=%(creatordate:short)']) || null : null;
const onMain = (h) => git(root, ['merge-base', '--is-ancestor', h, 'main']) !== null;
const tagDate =hasGit ? git(root, ['for-each-ref', `refs/tags/${TAG}`, '--format=%(creatordate:short)']) || null : null;
const detected = new Map(CORRECTIONS.map((c) => [c[0], c[1]]));
const firstDefined = new Map();
for (const f of FAMILIES) {
@@ -50,12 +51,20 @@ export function hindsightErrors(docs, root) {
const D = docDate(d.name);
const found = new Set();
const flag = (what) => found.add(what);
if (D > END) flag(`dated after the project end ${END}`);
if (hasGit) {
for (const [, h] of d.md.matchAll(/(?<![\w/.-])([0-9a-f]{7,40})(?![\w/.-])/g)) {
const c = commitDate(h);
if (c && c > D) flag(`commit ${h} (created ${c})`);
if (!c) continue;
if (c > D) flag(`commit ${h} (created ${c})`);
if (c > END) flag(`commit ${h} is after the project end ${END}`);
if (!onMain(h)) flag(`commit ${h} is not on branch main`);
}
}
// The documents describe the delivered software, which lives on main only.
for (const [, b] of d.md.matchAll(/\bbranch\s+`?([\w./-]+)`?/gi)) {
if (b !== 'main' && /^[a-z]/.test(b)) flag(`branch ${b} (only main may be named)`);
}
if (d.md.includes(TAG) && !(tagDate && tagDate <= D)) flag(`tag ${TAG} (${tagDate ? `created ${tagDate}` : 'not created yet'})`);
for (const [id] of d.md.matchAll(/\bISS-\d{3}\b/g)) {
const at = detected.get(id);