docs(sdlc): cite only main and commits up to project end; guard enforces it
This commit is contained in:
@@ -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.
|
||||||
|
|||||||
@@ -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,
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -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,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);
|
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 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 detected = new Map(CORRECTIONS.map((c) => [c[0], c[1]]));
|
||||||
const firstDefined = new Map();
|
const firstDefined = new Map();
|
||||||
for (const f of FAMILIES) {
|
for (const f of FAMILIES) {
|
||||||
@@ -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);
|
||||||
|
|||||||
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
+1
-1
@@ -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)
|
||||||
|
|||||||
Reference in New Issue
Block a user