ในบทความนี้
In this post
1. ปัญหาทางวิศวกรรม
เป้าหมายบทนี้
ตรวจตัวตน repository และ action ด้วยโค้ด คะแนนความมั่นใจของโมเดลเพิ่มสิทธิ์ไม่ได้
คำว่า guardrail มักรวมกลไกสองอย่าง semantic detector ประเมินว่าเนื้อหามีปัญหาหรือไม่ ส่วน hard guard ตรวจว่า action เฉพาะมีสิทธิ์ทำหรือไม่ อย่างแรกผิดได้เพราะเป็นคำตัดสินจากโมเดล อย่างหลังควรหยุดเมื่อ identity เป้าหมาย หรือ action นอกสัญญา prompt ที่บอกว่า 'ห้าม merge main' ไม่เท่ากับการไม่ให้ credential สำหรับ merge หรือปฏิเสธ action ที่ tool gateway
companion ตรวจ principal จากระบบยืนยันตัวตน repository แบบตรงตัว และ action ก่อนเรียก provider เฉพาะ maintainer + demo/shop + draft_patch จึงผ่าน เปลี่ยน action เป็น merge_main แล้วต้องได้ action_denied ไม่มี call และไม่มีผลภายนอก แม้ fixture จะมั่นใจเต็มที่ก็ตาม นี่คือขอบเขต capability แบบง่าย ระบบ code host จริงควรแยก credential ให้สิทธิ์แคบ ใช้ branch protection และ mediator ที่ตรวจ operation ตอนจะทำผลจริง [1]
2. ขอบเขตที่ต้องออกแบบ
แล็บคืนร่างใน memory ไม่เขียนไฟล์ repository และไม่เปิด PR ตัวแปล arithmetic รับ grammar เล็กมาก ไม่ใช่ sandbox สำหรับ Python ทั่วไป ห้ามเพิ่ม eval หรือ subprocess แล้วถือว่า temporary directory ทำให้ปลอดภัย การรันโค้ดสร้างทั่วไปต้องมี execution environment ที่แยกและเสริมความแข็งแรงจริง จำกัด network ทรัพยากร ไม่มี credential ติดมา และมี threat model ให้ตรงการใช้งาน
3. อ่าน implementation
ส่วนโค้ดจาก companion เพื่ออ่านประกอบ ใช้คำสั่งในหัวข้อ 5 เพื่อรันตัวอย่างที่ครบ dependency
def authorize(request, principal):
# principal comes from the application's auth layer, never from model output.
if principal != "maintainer" or request["repo"] != "demo/shop":
return Gate("reject", "permission_denied")
if request["action"] != "draft_patch":
return Gate("reject", "action_denied")
return Gate("pass", "draft_capability")
ถ้าเพิ่ม action เปิด PR ภายหลัง ต้องผูก approval กับ repository, base revision, candidate hash และ operation ที่แน่นอน ตรวจ binding อีกครั้งก่อนเกิดผล หากแก้ร่าง approval เก่าต้องใช้ไม่ได้ และเมื่อ remote timeout จนไม่รู้ว่าสำเร็จหรือยัง ต้องตรวจสถานะก่อน retry action ข้อนี้เป็นข้อกำหนดสำหรับต่อยอด production ไม่ใช่ feature ที่ companion ทำแล้ว บทเรียนที่ตรวจได้ทันทีคือคำตอบ semantic ที่มั่นใจไม่สามารถล้ม hard deny และต้องรักษากฎนี้แม้เปลี่ยน orchestration library
4. เปรียบเทียบผลที่ได้
| เส้นทาง | ผลที่สังเกตได้ |
|---|---|
| ก่อนเพิ่มด่านนี้ | ใช้ prompt ขอให้ agent ไม่ทำ action ต้องห้าม |
| หลังเพิ่มด่านนี้ | action ต้องห้ามไม่มีทางที่อนุญาตและไม่เรียก provider |
ผลต่อไปนี้มาจาก fixture ที่กำหนดคำตอบไว้เพื่อตรวจสถาปัตยกรรม ไม่ใช่ผลวัดความแม่น ความเร็ว หรือต้นทุนของ Jev จริง
{
"reason": "action_denied",
"calls": 0,
"effects": 0
}
5. รัน ทำให้พัง และอธิบาย
Part 08 code · Implementation · Tests: test_permission_stops_before_inference · Exercise
git clone https://github.com/Anirach/ai-core-engineering-workbench.git
cd ai-core-engineering-workbench
git checkout 18cdfcd4156d3d02acb8badf3b3a0a823113e0ed
python3 -m workbench.lesson 8
python3 -m unittest tests.test_boundaries.BoundaryTests.test_permission_stops_before_inference -vลองทำด้วยตัวเอง
ลอง repository อื่น principal เป็น guest และ action merge_main แล้วตรวจว่าทั้งสามหยุดก่อน inference
สิ่งที่ต้องส่ง: input ที่ลอง สถานะและเหตุผลที่ได้ และคำอธิบายว่าด่านใดเป็นผู้รับผิดชอบ ห้ามแก้ expected result เพียงเพื่อให้ test ผ่าน
6. แหล่งอ้างอิงและขอบเขต
เอกสารต้นทางและข้อจำกัด
ตรวจเอกสาร 2 พฤศจิกายน 2026 ตัวอย่างและ threshold เป็นการออกแบบเพื่อการสอน การอ้าง [1], [2] ตรงกับลำดับข้างล่าง ยังไม่ได้วัด live API
- GitHub, Secure use referenceLeast privilege, credentials and untrusted-code boundaries.
1. The engineering problem
Learning outcome
Put identity, repository and action policy in code; a model confidence value never becomes a capability.
The word guardrail often conflates two mechanisms. A semantic detector estimates whether content is problematic. A hard guard checks whether a concrete action is authorized. The former can be wrong because it is a learned judgment. The latter should fail closed when identity, target or action is outside the application contract. A prompt saying 'never merge main' is not equivalent to withholding a merge credential or refusing a merge action in the tool gateway.
The companion checks the authenticated principal, exact repository and allowed action before any provider call. Only maintainer + demo/shop + draft_patch passes. Changing action to merge_main produces action_denied, zero calls and zero external effects even if the fixture model would be maximally confident. This is a simple capability boundary. In a real code host, use separate credentials with the narrowest scopes, protected branches, and a mediator that validates the concrete operation at commit time [1].
2. The boundary to design
The lab returns an in-memory draft. It neither writes repository files nor opens a PR. Its arithmetic interpreter accepts a tiny expression grammar; it is not a general-purpose Python sandbox. Do not scale this teaching mechanism into 'safe execution' by adding eval or a subprocess and assuming a temporary directory is isolation. General generated code needs an independently hardened execution environment, restricted network, bounded resources, no ambient credentials, and a threat model appropriate to the deployment.
3. Read the implementation
Implementation excerpt from the companion. Run the complete lesson below with its imports and fixtures.
def authorize(request, principal):
# principal comes from the application's auth layer, never from model output.
if principal != "maintainer" or request["repo"] != "demo/shop":
return Gate("reject", "permission_denied")
if request["action"] != "draft_patch":
return Gate("reject", "action_denied")
return Gate("pass", "draft_capability")
If you later add a PR-opening action, bind approval to the exact repository, base revision, candidate hash and operation. Recheck that binding immediately before the effect. A revised candidate must invalidate the old approval; an ambiguous remote timeout needs reconciliation before retrying the action. These are production extension requirements, not implemented features of the companion. The immediate lesson is narrower and testable: a confident semantic answer cannot override a hard deny. Keep that invariant even if the orchestration library changes.
4. Compare the outcomes
| Approach | Observable outcome |
|---|---|
| Before this control | A prompt asks the agent to avoid forbidden actions. |
| After this control | Forbidden actions have no authorized path or provider call. |
The following output comes from scripted fixtures that verify architecture behavior. It is not a measurement of live Jev accuracy, latency, or cost.
{
"reason": "action_denied",
"calls": 0,
"effects": 0
}
5. Run, break, and explain
Part 08 code · Implementation · Tests: test_permission_stops_before_inference · Exercise
git clone https://github.com/Anirach/ai-core-engineering-workbench.git
cd ai-core-engineering-workbench
git checkout 18cdfcd4156d3d02acb8badf3b3a0a823113e0ed
python3 -m workbench.lesson 8
python3 -m unittest tests.test_boundaries.BoundaryTests.test_permission_stops_before_inference -vYour turn
Attempt a different repository, a guest principal and merge_main. Assert that all three stop before inference.
Keep three artifacts: the input you tried, the resulting state and reason, and an explanation of which boundary owns that result. Do not change an expected result merely to make a test pass.
6. Sources and limits
Primary sources and evidence limits
Sources checked 2 November 2026. Examples and thresholds are teaching designs. Inline [1], [2] follow the order below. Live API performance has not been measured.
- GitHub, Secure use referenceLeast privilege, credentials and untrusted-code boundaries.