ข้ามไปยังเนื้อหา

Receipt, สถานะ และความ stale

Receipt คือบันทึกของ Change Loop ว่า provider ตัวหนึ่งสังเกตเห็นผลอย่างหนึ่ง เทียบกับเนื้อหาชุดหนึ่ง ทุกอย่างในนั้นถูกออกแบบให้ receipt อยู่ได้ไม่นานกว่าสิ่งที่มันบรรยาย

provider คืนสถานะหนึ่งในสี่ และสามในสี่นั้นบล็อก

สถานะ ความหมาย Land ได้ไหม
pass provider รันแล้วและ claim เป็นจริง ได้
fail provider รันแล้วแต่ claim ไม่เป็นจริง ไม่ได้
error provider รันไม่ได้ — crash, timeout, spawn ล้มเหลว ไม่ได้
inconclusive provider รันแล้วแต่ไม่ได้ให้คำตัดสินกับ claim นั้น ไม่ได้

inconclusive คือตัวที่ทำให้คนงง และเป็นตัวที่มีประโยชน์ที่สุดในสี่ตัว Playwright ที่รันแล้วเขียวแต่ไม่มี annotation ผูกกับ claim ถือว่า inconclusive ไม่ใช่ผ่าน เพราะมันแสดงว่ามี test บางตัวรัน ไม่ได้แสดงว่า claim ของคุณ เป็นจริง readiness ที่ประกาศไว้แต่ไม่เคยสังเกตเห็นจะเป็น error ไม่ว่าคำสั่งจะ exit เป็นศูนย์หรือไม่ เพราะ suite ที่รันก่อนที่ dependency จะพร้อมไม่ได้พิสูจน์อะไรเลย

receipt แต่ละตัวบันทึกว่าอะไรรัน เห็นอะไร และเห็นเทียบกับอะไร

{
"provider": "test",
"execution": "harness",
"status": "pass",
"workspaceHash": "eb7f67b3…",
"contractFingerprint": "9a456f30…",
"providerFingerprint": "084664fa…",
"inputIdentity": { "mode": "global" },
"claims": ["profile-update"],
"artifacts": [{ "name": "command-log", "sha256": "", "size": 4210 }]
}

fingerprint คือสิ่งที่ทำให้การใช้ซ้ำปลอดภัย contractFingerprint ครอบคลุมเจตนา impact นโยบาย review acceptance และ claim ส่วน providerFingerprint ครอบคลุม adapter คำสั่ง capability สภาพแวดล้อม digest ของ lockfile timeout และตัวระบุ readiness เปลี่ยนอย่างใดอย่างหนึ่ง receipt ก็ไม่ได้บรรยายโลกปัจจุบันอีกต่อไป

workspaceHash ผูก receipt กับเนื้อหาที่มันถูกสร้างขึ้นมาเทียบด้วย มันคำนวณจาก Git index บวกกับตัวตนของไฟล์ที่ยังไม่ commit โดยข้ามไดเรกทอรีผลลัพธ์ ที่สร้างใหม่ได้ และข้าม execution.yaml ของ change นั้นเอง — การแก้การต่อสายของ provider จึงไม่ทำให้หลักฐานหมดอายุโดยตัวมันเอง แต่การแก้ source ทำ

Change Loop แยกหลักฐานที่มันสร้างเอง ออกจากหลักฐานที่คนยื่นให้ และไม่ยอมให้สองอย่างนี้ปนกัน

receipt ที่ระบุ execution: "harness" เขียนได้เฉพาะจากจุดที่รันคำสั่งจริงเท่านั้น และถ้าผ่านก็ต้องแนบ command log เป็น artifact

receipt ที่ระบุ execution: "manual" ต้องมีสิ่งที่สังเกตเห็น แหล่งที่มา และอย่างน้อยหนึ่ง artifact หรือ reference ที่ชี้ไปถึงได้จริง — เป็น URI หรือ path ที่มีอยู่จริง ข้อความลอย ๆ ถูกปฏิเสธ เพราะ “ผมรันแล้วมันผ่าน” ไม่ใช่หลักฐาน

โดยปกติ receipt ผูกกับ workspace ทั้งก้อน การแก้อะไรก็ตามจึงทำให้มันหมดอายุ ซึ่งถูกต้องแต่หยาบ การพิมพ์ผิดในเอกสารไม่ควรล้มผลการสแกนความปลอดภัย

provider แคบขอบเขตนั้นได้ด้วยการประกาศ input ที่มันพึ่งพาจริง

{
"security-static": {
"adapter": "command",
"command": ["npm", "audit", "--audit-level=high"],
"inputs": ["package.json", "package-lock.json"]
}
}

เมื่อประกาศ input ไว้ Change Loop จะบันทึก digest ของไฟล์เหล่านั้นแบบเรียงลำดับ เมื่อ workspace เปลี่ยนแต่ไฟล์เหล่านั้นไม่เปลี่ยน receipt จะถูกผูกใหม่เข้ากับ workspace hash ใหม่แทนที่จะรันซ้ำ และการผูกใหม่ถูกเขียนลง audit log ประกาศ input ตามจริง — provider ที่อ่านมากกว่าที่ประกาศจะใช้ receipt ซ้ำ ทั้งที่ควรต้องพิสูจน์ใหม่

review, acceptance และ semantic-acceptance ประกาศ input ไม่ได้ เพราะคำตัดสิน ผูกกับ change ทั้งก้อน

provider semantic-acceptance ตรวจ envelope ที่ลงลายเซ็น Ed25519 จากระบบภายนอก โดยไม่เปิด hidden input หรือโค้ด oracle ให้ implementation agent เห็น Envelope ผูก case ID, claim, input partition, status และ observation digest เข้ากับ workspace จริง และผูกกับ critical-case observation หรือหลักฐานก่อนแก้ fail / หลังแก้ pass ได้

required case ที่หาย, ถูก skip, ซ้ำ, มาจาก provider ผิด, stale, ถูกแก้ หรือ fail จะบล็อก Proof และ Land โดย review ที่ผ่าน override ไม่ได้ สำหรับ npm repository เดียวที่ระบุได้แน่นอน Change Loop จะเปิดการตรวจ package.json กับ package-lock.json อัตโนมัติโดยไม่ต้องเพิ่ม wiring

provider ที่รันแล้ว fail ทิ้งทางออกไว้สามทาง และคำตัดสิน fail พิมพ์ให้ครบทุกทาง: แก้โค้ด, ต่อสาย provider ใหม่ หรือถอนการบังคับใช้ capability ตัวนั้นตัวเดียว ด้วยการตัดสินใจชัดเจนที่ถูกบันทึกไว้:

Terminal window
claude-foundation change waive <change> --capability <c> --reason <why> --decision-ref <ref>

waiver เดินทางเป็น advisory user-waived เข้าไปใน readiness, บันทึก proof, archive และบรรทัด LAND READY ส่วน --revoke คืนข้อบังคับ มันเป็นการหักออกโดยเจตนา: เปลี่ยนสิ่งที่ provider ตัวอื่นรับรองไว้ไม่ได้ receipt ที่ได้มาแล้วยังใช้ได้ และไม่มีเส้นทางที่พา proof ที่ fail ไป land review กับ acceptance waive ที่นี่ไม่ได้ — สองตัวนั้นมีเส้นทาง waiver ของตัวเองที่ประกาศใน foundation.json

prove จะไม่ยอมทำงานจนกว่าทุก provider ที่ต้องมีจะอยู่ในสถานะถูกต้อง คำตัดสินที่พบบ่อย เรียงตามลำดับที่ตรวจ

คำตัดสิน เกิดอะไรขึ้น
missing provider ไม่เคยสร้าง receipt
contract-stale claim หรือสัญญาเปลี่ยนหลังจากได้ receipt มา
provider-fingerprint-stale คำสั่ง สภาพแวดล้อม หรือ lockfile เปลี่ยน
stale workspace เปลี่ยนและไม่ได้ประกาศ input ไว้
provider-inputs-stale input ที่ประกาศไว้เปลี่ยนเอง
review-not-independent ผู้รีวิวเป็นผู้ implement ด้วย และนโยบายไม่ได้ยกเว้นความเป็นอิสระ
review-not-diverse AI ผู้รีวิวใช้ตระกูลโมเดลเดียวกับผู้ implement
acceptance-invalid ขอบเขต hash หรือเหตุผลเปลี่ยนไปหลังการยอมรับ
semantic-acceptance-invalid case, source observation, transition, issuer หรือตัวผูก workspace ที่ลงลายเซ็นไม่ถูกต้อง
external-observation-missing receipt แบบ manual ขาดสิ่งที่สังเกตเห็นหรือแหล่งที่มา

receipt ที่ stale หลัง จากรันไปแล้วในรอบ proof เดียวกัน มักแปลว่า provider เขียนไฟล์ลงในพื้นที่ที่ถูก hash — คือปล่อย report ลง working tree แทนที่จะเป็นไดเรกทอรีที่ถูก ignore ให้ชี้ report ไปยังที่ที่สร้างใหม่ได้ หรือประกาศมันเป็น artifact

Land ตรวจทั้งหมดนี้ซ้ำอีกรอบ workspace hash ของ proof ต้องยังตรง และ digest ของ receipt ที่ใช้งานอยู่ทุกตัวต้องเท่ากับ digest ที่บันทึกไว้ใน proof manifest receipt จึงถูกสลับระหว่างตอนพิสูจน์กับตอน land ไม่ได้