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
+4 -1
View File
@@ -43,7 +43,10 @@ future are fine; outcomes, commits and identifiers that came later are not.
`build.mjs` enforces the checkable part through `timeline.mjs` and stops with a `build.mjs` enforces the checkable part through `timeline.mjs` and stops with a
list of offending documents when a work product cites: list of offending documents when a work product cites:
- a Git commit created after the document date (dates read from `git log`); - a Git commit created after the document date or after the project end
(`END`), or one that is not on branch `main` (dates read from `git log`);
- any branch other than `main` (the documents describe the delivered software,
which lives on `main` only), or a document dated after `END`;
- the delivery tag `TAG` before the tag was created; - the delivery tag `TAG` before the tag was created;
- an `ISS-nnn` before its detection date in the Correction Register; - an `ISS-nnn` before its detection date in the Correction Register;
- CR, SR, Unit or Test Case IDs before the work product that defines them. - CR, SR, Unit or Test Case IDs before the work product that defines them.
+1 -1
View File
@@ -260,7 +260,7 @@ export const MEETINGS = [
attachment: 'Training Report, Product Operation Guide, Project Repository (Backup)', attachment: 'Training Report, Product Operation Guide, Project Repository (Backup)',
progress: [['Phase 1: Project Initiation', 'เสร็จสมบูรณ์', 100, 'เปิดโครงการและอนุมัติกฎบัตรเรียบร้อย'], ['Phase 2: Project Planning', 'เสร็จสมบูรณ์', 100, 'อนุมัติแผนโครงการและ Baseline ความต้องการ'], ['Phase 3: Project Execution', 'เสร็จสมบูรณ์', 100, 'พัฒนาระบบครบตามขอบเขตและเปิดใช้งานจริง'], ['Phase 4: Verification & Validation', 'เสร็จสมบูรณ์', 100, 'ตรวจสอบ ทดสอบ และ UAT ผ่านครบทุกรายการ'], ['Phase 5: Project Close', 'เสร็จสมบูรณ์', 100, 'อบรม ปิดงานควบคุมปฏิบัติการ และปิดโครงการเรียบร้อย'], ['รวมความคืบหน้าทั้งโครงการ', 'ตามแผน', 100, 'โครงการเสร็จสมบูรณ์ ปิดโครงการอย่างเป็นทางการ']], progress: [['Phase 1: Project Initiation', 'เสร็จสมบูรณ์', 100, 'เปิดโครงการและอนุมัติกฎบัตรเรียบร้อย'], ['Phase 2: Project Planning', 'เสร็จสมบูรณ์', 100, 'อนุมัติแผนโครงการและ Baseline ความต้องการ'], ['Phase 3: Project Execution', 'เสร็จสมบูรณ์', 100, 'พัฒนาระบบครบตามขอบเขตและเปิดใช้งานจริง'], ['Phase 4: Verification & Validation', 'เสร็จสมบูรณ์', 100, 'ตรวจสอบ ทดสอบ และ UAT ผ่านครบทุกรายการ'], ['Phase 5: Project Close', 'เสร็จสมบูรณ์', 100, 'อบรม ปิดงานควบคุมปฏิบัติการ และปิดโครงการเรียบร้อย'], ['รวมความคืบหน้าทั้งโครงการ', 'ตามแผน', 100, 'โครงการเสร็จสมบูรณ์ ปิดโครงการอย่างเป็นทางการ']],
agenda: [['สรุปผลการอบรมผู้ใช้งาน', 'ยืนยันความพร้อมของผู้ใช้ก่อนเปิดใช้งานจริง'], ['สรุปการปิดงานควบคุมการสำรองข้อมูลและการเฝ้าระวัง', 'ยืนยันการปิดรายการ OP-001 และ OP-002'], ['สรุปการสำรอง Repository และเอกสารโครงการ', 'ยืนยันการสำรองและกู้คืนได้จริง'], ['ปิดโครงการอย่างเป็นทางการ', 'ลงมติปิดโครงการและส่งมอบเอกสาร']], agenda: [['สรุปผลการอบรมผู้ใช้งาน', 'ยืนยันความพร้อมของผู้ใช้ก่อนเปิดใช้งานจริง'], ['สรุปการปิดงานควบคุมการสำรองข้อมูลและการเฝ้าระวัง', 'ยืนยันการปิดรายการ OP-001 และ OP-002'], ['สรุปการสำรอง Repository และเอกสารโครงการ', 'ยืนยันการสำรองและกู้คืนได้จริง'], ['ปิดโครงการอย่างเป็นทางการ', 'ลงมติปิดโครงการและส่งมอบเอกสาร']],
discussion: [['ผลการอบรม', 'อบรมผู้ใช้งาน 6 คน เมื่อ 22 ส.ค. 69 ผู้เข้าอบรมทดลองใช้งานครบทุกขั้นตอนได้สำเร็จ', ['ThS', 'PaNg'], 'เสร็จสิ้น'], ['การควบคุมปฏิบัติการ', 'ปิดรายการสำรองฐานข้อมูลอัตโนมัติ (OP-001) และการเฝ้าระวังพร้อมแจ้งเตือน (OP-002) เมื่อ 23 ส.ค. 69', ['ThS'], 'เสร็จสิ้น'], ['การสำรองข้อมูลโครงการ', 'ซิงก์ Branch ไปยัง Backup Remote และทดสอบเรียกคืนสำเร็จ', ['ThS', 'YaB'], 'เสร็จสิ้น'], ['การปิดโครงการ', 'ที่ประชุมมีมติปิดโครงการอย่างเป็นทางการเมื่อ 24 ส.ค. 69', ['SeV', 'ApS'], 'ปิดโครงการ']], discussion: [['ผลการอบรม', 'อบรมผู้ใช้งาน 6 คน เมื่อ 22 ส.ค. 69 ผู้เข้าอบรมทดลองใช้งานครบทุกขั้นตอนได้สำเร็จ', ['ThS', 'PaNg'], 'เสร็จสิ้น'], ['การควบคุมปฏิบัติการ', 'ปิดรายการสำรองฐานข้อมูลอัตโนมัติ (OP-001) และการเฝ้าระวังพร้อมแจ้งเตือน (OP-002) เมื่อ 23 ส.ค. 69', ['ThS'], 'เสร็จสิ้น'], ['การสำรองข้อมูลโครงการ', 'ซิงก์ Branch `main` ไปยัง Backup Remote และทดสอบเรียกคืนสำเร็จ', ['ThS', 'YaB'], 'เสร็จสิ้น'], ['การปิดโครงการ', 'ที่ประชุมมีมติปิดโครงการอย่างเป็นทางการเมื่อ 24 ส.ค. 69', ['SeV', 'ApS'], 'ปิดโครงการ']],
actions: [['จัดเก็บเอกสารโครงการทั้งหมดเข้าระบบควบคุมเอกสาร', ['YaB'], '2026-08-24', 'เสร็จสมบูรณ์'], ['ติดตามการตรวจนับสต๊อกสิ้นเดือนแรกหลังเปิดใช้งานจริง', ['ApS'], '2026-09-30', 'Scheduled']], actions: [['จัดเก็บเอกสารโครงการทั้งหมดเข้าระบบควบคุมเอกสาร', ['YaB'], '2026-08-24', 'เสร็จสมบูรณ์'], ['ติดตามการตรวจนับสต๊อกสิ้นเดือนแรกหลังเปิดใช้งานจริง', ['ApS'], '2026-09-30', 'Scheduled']],
next: null, next: null,
}, },
+11 -2
View File
@@ -3,7 +3,7 @@
// dated 31 Jul cannot record results from the 10–14 Aug test run, and so on. // 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. // Planned dates in the future are fine; facts that only came into being later are not.
import { execFileSync } from 'node:child_process'; import { execFileSync } from 'node:child_process';
import { TAG } from './project.mjs'; import { TAG, END } from './project.mjs';
import { CORRECTIONS } from './history.mjs'; import { CORRECTIONS } from './history.mjs';
/** Document date from its name: "... 25690817 V1.0 ..." -> 2026-08-17 */ /** Document date from its name: "... 25690817 V1.0 ..." -> 2026-08-17 */
@@ -37,6 +37,7 @@ export function hindsightErrors(docs, root) {
if (!commitDates.has(h)) commitDates.set(h, git(root, ['log', '-1', '--format=%ad', '--date=short', `${h}^{commit}`]) || null); if (!commitDates.has(h)) commitDates.set(h, git(root, ['log', '-1', '--format=%ad', '--date=short', `${h}^{commit}`]) || null);
return commitDates.get(h); return commitDates.get(h);
}; };
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 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 detected = new Map(CORRECTIONS.map((c) => [c[0], c[1]]));
const firstDefined = new Map(); const firstDefined = new Map();
@@ -50,12 +51,20 @@ export function hindsightErrors(docs, root) {
const D = docDate(d.name); const D = docDate(d.name);
const found = new Set(); const found = new Set();
const flag = (what) => found.add(what); const flag = (what) => found.add(what);
if (D > END) flag(`dated after the project end ${END}`);
if (hasGit) { if (hasGit) {
for (const [, h] of d.md.matchAll(/(?<![\w/.-])([0-9a-f]{7,40})(?![\w/.-])/g)) { for (const [, h] of d.md.matchAll(/(?<![\w/.-])([0-9a-f]{7,40})(?![\w/.-])/g)) {
const c = commitDate(h); 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'})`); 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)) { for (const [id] of d.md.matchAll(/\bISS-\d{3}\b/g)) {
const at = detected.get(id); const at = detected.get(id);
BIN
View File
Binary file not shown.
@@ -52,7 +52,7 @@
| :---: | --- | --- | :---: | :---: | | :---: | --- | --- | :---: | :---: |
| 1 | ผลการอบรม | อบรมผู้ใช้งาน 6 คน เมื่อ 22 ส.ค. 69 ผู้เข้าอบรมทดลองใช้งานครบทุกขั้นตอนได้สำเร็จ | ThS, PaNg | เสร็จสิ้น | | 1 | ผลการอบรม | อบรมผู้ใช้งาน 6 คน เมื่อ 22 ส.ค. 69 ผู้เข้าอบรมทดลองใช้งานครบทุกขั้นตอนได้สำเร็จ | ThS, PaNg | เสร็จสิ้น |
| 2 | การควบคุมปฏิบัติการ | ปิดรายการสำรองฐานข้อมูลอัตโนมัติ (OP-001) และการเฝ้าระวังพร้อมแจ้งเตือน (OP-002) เมื่อ 23 ส.ค. 69 | ThS | เสร็จสิ้น | | 2 | การควบคุมปฏิบัติการ | ปิดรายการสำรองฐานข้อมูลอัตโนมัติ (OP-001) และการเฝ้าระวังพร้อมแจ้งเตือน (OP-002) เมื่อ 23 ส.ค. 69 | ThS | เสร็จสิ้น |
| 3 | การสำรองข้อมูลโครงการ | ซิงก์ Branch ไปยัง Backup Remote และทดสอบเรียกคืนสำเร็จ | ThS, YaB | เสร็จสิ้น | | 3 | การสำรองข้อมูลโครงการ | ซิงก์ Branch `main` ไปยัง Backup Remote และทดสอบเรียกคืนสำเร็จ | ThS, YaB | เสร็จสิ้น |
| 4 | การปิดโครงการ | ที่ประชุมมีมติปิดโครงการอย่างเป็นทางการเมื่อ 24 ส.ค. 69 | SeV, ApS | ปิดโครงการ | | 4 | การปิดโครงการ | ที่ประชุมมีมติปิดโครงการอย่างเป็นทางการเมื่อ 24 ส.ค. 69 | SeV, ApS | ปิดโครงการ |
## งานที่ต้องติดตาม (Action Item) ## งานที่ต้องติดตาม (Action Item)