Skip to main content

verifiable-gates

DOI 10.5281/zenodo.22103110

A gate registry that is enforced two ways against the tests and CI jobs behind it, gates that must carry evidence of having gone red on a real defect, and a portable rule set that lets an AI coding agent work under the same rules in another project.

Archived under a DOI. The state the claims point at is tagged evidence-freeze-1 in both this repository and the reference implementation, and archived at doi:10.5281/zenodo.22103110. That DOI resolves to the latest version; each release also gets one of its own. evidence-freeze-1 and v0.1.0 are different commits on purpose: the freeze is the state the measurements were taken on, the release is the state the package first shipped in.

Status: the extraction is complete (2026-08-28). Every stage has landed. What remains in the reference implementation, sayam/flask-todolist, is the registers — which test, which job, which threshold — read by thin adapters on the paths its hooks and jobs already called. The decision, what moved and what stayed, is ADR 0075 §6 and the file-by-file census is extraction.yaml there, which now records nothing outstanding: 0 to move, 58 that stayed, 13 split between the two. First release: v0.1.0 (2026-08-28) — the point at which this repository and the reference implementation separate. Consume it as a pinned submodule or a versioned dependency, never from main.

Stage What lands Status
1 Package skeleton · CI · hash-pinned tools · registry schema here
2 The nine checks · the doctor · preflight · the skill generator here
3 The governance checkers (ratchets, censuses, platform posture) here
4 The supply-chain checkers here
5 The measurement instruments and the comparison data here
6 Registry handover · citation · DOI here
Extraction closed — census at move 0 / stay 58 / split 13 · v0.1.0 2026-08-28

Stage 6 was taken out of order on purpose. The rules are what this project is; stages 3 to 5 move the machinery that happens to enforce some of them, and a bundle that shipped the machinery before the rules would have had nothing to say about the ones it cannot enforce.

What is here today

rules.yaml — 92 rules, each carrying the incident that produced it. They are rendered into an agent skill in the layout of the Agent Skills specification, so any of the products that read that layout can be handed it unchanged: skills/verifiable-gates/SKILL.md is the front page — how to read the rules, the five practices underneath them, and one line per rule — and the full entries sit beside it in references/baseline.md, the baseline layer, where deviating is a defect, and references/business.md, agreements an application of a given kind may legitimately decide differently. (The two sheets lived at the repository root as SKILL.md and SKILL-BUSINESS.md until v0.1.12; DECISIONS.md the-sheets-live-under-skills says why they moved and why no copy stayed.)

Two ways to take the skill without cloning, through pipes this repository does not own: npx skills add sayam/verifiable-gates puts it into whichever agent you use (the Skills CLI reads the skills/ directory), and in Claude Code claude plugin marketplace add sayam/verifiable-gates then claude plugin install verifiable-gates@verifiable-gates (the one-entry marketplace in .claude-plugin/). Both install the same three files and nothing else — a skill is instructions. The scanners are still pip install verifiable-gates and python -m verifiable_gates.install, because a checker is not something to be handed an agent as prose. DECISIONS.md distribution-is-two-pipes-nobody-here-owns says why there is no marketplace or registry of this project's own.

Three front doors for a project that has installed the bundle. In CI, uses: sayam/verifiable-gates@<commit-sha> runs the doctor the project installed — action.yml is run: steps only, with nothing inside it to pin, and an optional sarif: input. With pre-commit, repo: https://github.com/sayam/verifiable-gates offers gates-doctor and one hook per scanner, by the id of the rule it decides. All three run tools/ as the project has it and none carries a copy, so a SHA, a rev or a plugin update moving changes nothing about what the project is held to (DECISIONS.md ci-runs-the-bundle-the-project-installed). The third opens at edit time: with the plugin enabled in Claude Code and VERIFIABLE_GATES_AT_EDIT=1 in the project's .claude/settings.json under env, a hook runs the installed doctor after every Edit or Write and hands a finding back to the agent while it still holds the file. Off by default; it reports and refuses nothing (DECISIONS.md the-edit-hook-reports-and-does-not-refuse).

A rule and its enforcement live in separate files, because they have separate lifetimes. rules.yaml is what this project publishes; gates.yaml is what this project is itself held to.

import verifiable_gates

catalogue = verifiable_gates.rules.load("rules.yaml")
# `package_dir` is where a rule's `script:` is looked for; without it, only the
# shape of the path is checked — a checker that is not there would go unnoticed.
for problem in verifiable_gates.rules.problems(catalogue, package_dir="src/verifiable_gates"):
    print(problem)

rules.yaml ships with the checkout, not with the wheel — it is the published artefact (CC BY 4.0), and the package is the machinery that reads it.

Also here: the nine stdlib-only checkers, the installer and the doctor that runs them in a project that has installed nothing, preflight, the sheet renderer, and the fail-fix harness.

What the bundle decides, and what it does not. Of the 92 rules, nine have a checker in the bundle (script: in rules.yaml); the doctor and the installer decide those and nothing else. The other 83 are the rule sheets — an agent is held to them by reading, and the Enforced in the reference line on each says how one project turned it into a test. rules.yaml and the sheets are not installed by install() either; they come with the checkout. Two consequences worth knowing before trusting a green: the doctor reports a rule it cannot decide as NA, and a project where every rule is NA exits 0 — that is "nothing was measured", not "the project passed" (a path that scaffold.json names and the project does not have is never NA, though: that is a broken configuration, and it is a finding — and so are a value of the wrong shape, a list where one path goes or a string where a list of names goes, and a path that leads outside the project, each naming the key it came from; and a Dockerfile* the project has but never named is a finding too, not "no Dockerfile"; a directory that is there and holds no file of the kind a checker reads — an app/ of Go, a templates directory of .ejs — is NA naming what it looked for, not a pass, because a rule the tool cannot check must not look like a rule it checked; and a scan that crashes, hangs past its timeout, answers half a verdict before crashing, meets a file it cannot decode, may not open, or that is larger than the 8 MiB a scanner reads whole, cannot read scaffold.json as a configuration at all, or cannot walk the whole tree it was pointed at — a directory closed to it is not the answer a directory that is not there gets, which stays NA — is [error] with its stderr passed through, never [found] — red, but no verdict); and rules.problems() only checks that a script: exists when it is given the package directory (package_dir=), as the doctor does. On a fresh install the only pass is the shipped index (gates-registry-total), which has to be true about itself; the starting workflow the installer wrote is NA to the two pinning checkers until a line of it changes — a green on the bundle's own file says nothing about the project. That index check reads its own direction too: a gate whose job cannot turn the build red — a workflow with no trigger, if: false, or continue-on-error: true — is a finding, because a row nothing can fail is a row and nothing else. And the bundle keeps a record of what it installed: gates_doctor --installed holds every file it wrote to the contents it wrote, not merely to being present, and an upgrade names what this version no longer ships and leaves it in place, because a file in your repository is yours to remove. An install that stopped partway is read as one: the doctor leads with the last install into this tree did not finish rather than reporting the files that did land as files somebody edited — and one still under way is read as one too, because the record is written before the first file and names what each file is about to become. And gates_doctor --rules prints the rules the bundle decides — each with where it came from and which scanner reads it — for the instruction file a project keeps for its agents (AGENTS.md, CLAUDE.md) to point at: read at run time from the installed manifest, so an upgrade cannot leave an agent on yesterday's rule, and only the rules a scanner here can decide, so no instruction stands without a gate behind it. It prints them only off a bundle the installed record still vouches for: an edited manifest, an edited scanner, or no record at all prints no rules and exits 2, because the file it reads lives inside the project it holds to account (DECISIONS.md the-rules-are-read-off-a-bundle-that-is-still-intact). And gates_doctor --sarif FILE writes the same run as SARIF 2.1.0 for code scanning, reviewdog or an IDE — a finding is a result, while NA and a scan that did not answer are notifications on the invocation, never results, so a reader counting results cannot mistake "could not look" for "looked and found nothing". A file already at that path is replaced only if it is this doctor's run over the same root; another tree's run, or anything else, is left where it is and named — two trees given one path lose no answer.

What the two pinning checkers read. ci-tools-hash-pinned and actions-sha-pinned read every workflow, every composite action a workflow names with uses: ./<path> wherever it lives, folded or not, and — for installs — every shell script a run: line hands off to, known by its .sh name or by its shebang, quoted or not, from wherever the shell stands (a cd dir && before it, or the step's working-directory:), with comments stripped first — a # inside a word ($#, ${#PKGS}, \#) is not one. In a workflow only what run: executes is judged — a name: or an env: that quotes the command is prose — and --require-hashes counts only as an argument of the install itself, quoted or not; so do PIP_REQUIRE_HASHES=1 on the command or in the step's own env:, and a requirements file whose every line carries a --hash=, because pip requires hashes in each of those cases on its own; --no-index, and a wheel installed with --no-deps, fetch nothing and are left alone. A command inside $( ), backticks, a ( ) subshell, an sh -c string (-c folded into other flags too — bash -lc), a string python -c hands to os.system, or after a lone & executes and is judged; a bare echo of the words is prose — unless a shell is handed the words, by a pipe (echo … | bash), a here-string or eval, and a ${PIP:-pip} default is read as the word. The YAML shapes uses : and - {uses: …} are read the way the platform reads them — and so are a quoted key ("run":), an alias of an anchor set anywhere in the file (run: *cmd, uses: *co, with the anchor's version comment), a tagged value (!!str), and a plain, quoted or folded (>) scalar that continues onto the next line, which YAML joins with a space before the shell sees it; only a literal block (|) keeps its lines apart, and a uses under with: is an input, not a step. An install is judged whether it says pip, pipx, uv tool install, uv tool run, uv add, uvx, uv run --with, poetry add, pdm add or pipenv install, and on the Node side npm install, npm exec, npx, yarn add, pnpm add or pnpm dlx; pip wheel builds in an isolated environment like python -m build and is held to --no-build-isolation; uv run --locked, uv sync --locked, uv build, npm ci, yarn install --immutable and pnpm install --frozen-lockfile install from a lock and are left alone. A uses: folded onto the next line is read from that line. actions-sha-pinned judges both halves of its title: a floating tag is a finding, and so is a commit SHA with no version comment beside it — a pin nobody can read or move (a docker:// digest needs none). Of the other checkers, adr-index-complete reports two records sharing a number as well as a gap, and csp-no-inline reads ONCLICK=, STYLE= and a <style> element the way a browser does — in any case, split over lines or not (the = on the line after the name too), with comments blanked first (one that never closes runs to the end of the file), entities inside an attribute value decoded before the scheme is read (&#106;avascript:), and .htm, .jinja, .jinja2 and .j2 templates read like .html.

Since the extraction finished, so are the deciders that used to live in the reference implementation: ratchets and the measurements that feed them, the removal census, the synchroniser for numbers a project advertises about itself, the platform-posture reader, the advisory deciders for pip, npm, and container images, the scanner-coverage check, the two censuses that watch what CI cannot see (when a schedule last fired, how long redness stood), the gh wrapper, and the ASVS worksheet builder with the gate-to-ASVS crosswalk — and the research instruments, the ASVS probe and the battery that runs it over a directory of generated applications, together with the experiment they measured. Each arrives with its messages as an input, so a project can keep printing in its own language.

The two schemas — rules.py for this catalogue, registry.py for a project's gates.yaml — encode five rules that came from real traps, not from theory:

  • a gate whose layer is internal cannot be portable — a rule tied to one project's architecture, exported as universal, is an overclaim; that hold is in the gate schema, and the rule schema refuses internal outright, since a rule in this catalogue is published whole (portable on a rule is refused as a gate's field);
  • a key neither schema knows is refused, not skipped — a misspelt born_frm is a rule with no origin that looks like one with;
  • anything exported must name the trap that created it (born_from), because a rule with no origin is a rule nobody knows when to remove;
  • proved_by entries must say what they caught and when — a gate nobody has seen go red is indistinguishable from a gate that checks nothing;
  • the vocabularies for kind, severity, layer, and pillar are closed.

Licence

  • Code: Apache-2.0. Contributors sign CLA.md — one line in the pull request; you keep your copyright.
  • Rules and documentation: CC BY 4.0.

The application this was extracted from stays AGPL-3.0-or-later. The two differ on purpose: a CI tool is not a network service, and a rule meant to be adopted inside an organisation's internal handbook must not require share-alike.


ภาษาไทย

ทะเบียน gate ที่ถูกบังคับให้ตรงกับความจริงสองทิศ · gate ที่ต้องพกหลักฐานว่าเคยแดง ตอนของเสียจริง · และชุดกฎที่ส่งออกไปให้ AI agent ทำงานใต้กติกาเดียวกันในโปรเจกต์อื่นได้

เก็บถาวรใต้ DOI แล้ว — สถานะที่ข้ออ้างชี้ถึงถูกตรึงไว้ที่ tag evidence-freeze-1 ทั้ง repo นี้และ reference implementation · archive อยู่ที่ doi:10.5281/zenodo.22103110 ซึ่งชี้รุ่นล่าสุดเสมอ (แต่ละ release มี DOI ของตัวเองด้วย) · evidence-freeze-1 กับ v0.1.0 เป็นคนละคอมมิตโดยตั้งใจ — tag แรกคือสถานะตอนวัด tag หลังคือสถานะตอนแพ็กเกจออกครั้งแรก

สถานะ: ถอดครบทุกขั้นแล้ว (2026-08-28) — ที่ flask-todolist เหลือ ทะเบียน (เทสต์ไหน · job ไหน · พื้นเท่าไหร่) กับ adapter บาง ๆ บนพาธเดิม ตาม ADR 0075 ข้อ 6 และ extraction.yaml ที่นั่น ซึ่งไม่เหลืออะไรค้างแล้ว (move 0 · stay 58 · split 13) · รุ่นแรก v0.1.0 (2026-08-28) คือจุดที่สอง repo แยกทางกัน — ใช้ผ่าน submodule ที่ pin ไว้หรือ dependency ที่ระบุรุ่น ไม่ใช่จาก main

วันนี้มี คลังกฎ 92 ข้อ (rules.yaml) ที่แต่ละข้อพกกับดักจริงที่ให้กำเนิดมันมาด้วย · ตัวตรวจ stdlib ล้วนเก้าตัว · ตัวติดตั้งกับ doctor · preflight · ตัวเรนเดอร์แผ่นกฎ · harness ของ fail-fix loop · ตัวตัดสินฝั่ง governance กับ supply chain (ratchet · สำมะโนของที่ถอด · ตัวซิงก์เลขที่โฆษณา · ท่าทีแพลตฟอร์ม · advisory ของ pip/npm/image · ขอบเขตของตัวสแกน · สำมะโนตารางเวลากับสายแดงที่ CI มองไม่เห็น · แผ่นงาน ASVS กับ crosswalk) · และ เครื่องมือวิจัย (ASVS probe + battery) พร้อมการทดลองที่มันวัด — ทุกตัวรับถ้อยคำเป็น input โปรเจกต์ปลายทางจึงพิมพ์ภาษาของตัวเองได้

กฎกับตัวบังคับอยู่คนละไฟล์โดยตั้งใจ เพราะอายุไม่เท่ากัน — rules.yaml คือสิ่งที่ repo นี้เผยแพร่ ส่วน gates.yaml คือสิ่งที่ repo นี้ถูกบังคับด้วยตัวเอง

แผ่นกฎเป็น Agent Skill ตาม spec แล้ว อยู่ที่ skills/verifiable-gates/ (หน้าแรก SKILL.md + entry เต็มใน references/) · ติดตั้งโดยไม่ต้อง clone ได้สองทางผ่านท่อที่ repo นี้ไม่ได้เป็นเจ้าของ: npx skills add sayam/verifiable-gates (Skills CLI ลงให้ agent ที่คุณใช้) หรือใน Claude Code claude plugin marketplace add sayam/verifiable-gates แล้ว claude plugin install verifiable-gates@verifiable-gates · ทั้งสองทางลงไฟล์สามไฟล์เดียวกันและไม่มีอะไรอื่น — skill คือคำสั่ง ส่วนตัวสแกนยังเป็น pip install verifiable-gates + python -m verifiable_gates.install เพราะตัวตรวจไม่ใช่ของที่จะยื่นให้ agent เป็นร้อยแก้ว

สามประตูหน้าสำหรับโปรเจกต์ที่ติดตั้ง bundle แล้ว — ใน CI uses: sayam/verifiable-gates@<commit-sha> รัน doctor ที่โปรเจกต์ติดตั้งไว้ (action.yml เป็น run: ล้วน ไม่มีอะไรข้างในให้ pin · มี input sarif: ให้เลือก) · ใน pre-commit repo: https://github.com/sayam/verifiable-gates มี hook gates-doctor กับ hook ต่อ scanner ตาม id ของกฎ · ทั้งสองรัน tools/ ตามที่โปรเจกต์มี ทั้งสามประตูไม่พกสำเนาเลย — SHA · rev · หรือ plugin ขยับ จึงไม่เปลี่ยนสิ่งที่โปรเจกต์ถูกบังคับ · ประตูที่สามเปิดตอน edit: เปิด plugin ใน Claude Code แล้วตั้ง VERIFIABLE_GATES_AT_EDIT=1 ใน .claude/settings.json ของโปรเจกต์ใต้ env — hook (hooks/hooks.json) จะรัน doctor ที่ติดตั้งไว้หลังทุก Edit/Write แล้วส่ง finding กลับให้ agent ตอนที่ยังถือไฟล์อยู่ · ปิดเป็นค่าเริ่มต้น · รายงาน ไม่ปฏิเสธ (DECISIONS.md the-edit-hook-reports-and-does-not-refuse)

บันเดิลตัดสินได้ 9 จาก 92 — เฉพาะกฎที่มี script: เท่านั้นที่ doctor กับ installer ตัดสินให้ อีก 83 ข้อคือแผ่นกฎที่ agent ถูกบังคับด้วยการอ่าน · doctor รายงานกฎที่ตัดสินไม่ได้เป็น NA และโปรเจกต์ที่ทุกข้อเป็น NA ออก 0 แปลว่า "ไม่ได้วัดอะไร" ไม่ใช่ "ผ่าน" · ไดเรกทอรีที่ มีอยู่ แต่ไม่มีไฟล์ชนิดที่ตัวตรวจอ่านเลย — app/ ที่มีแต่ Go หรือไดเรกทอรี template ที่มีแต่ .ejs — เป็น NA พร้อมบอกว่าไปหาอะไร ไม่ใช่ pass เพราะกฎที่เครื่องมือตรวจไม่ได้ต้องไม่หน้าตาเหมือนกฎที่ตรวจแล้ว · สแกนที่ล่ม ค้างเกินเวลา พิมพ์คำตัดสินได้ครึ่งเดียวแล้วพัง เจอไฟล์ที่ถอดรหัสไม่ได้ ไม่มีสิทธิ์เปิด หรือใหญ่เกิน 8 MiB ที่ตัวสแกนอ่านทั้งไฟล์ อ่าน scaffold.json เป็นคอนฟิกไม่ได้เลย หรือเดินต้นไม้ที่ถูกชี้ให้ดูไม่ทั่ว — ไดเรกทอรีที่ปิดไม่ให้เข้าไม่ใช่คำตอบเดียวกับไดเรกทอรีที่ ไม่มีอยู่ ซึ่งยังเป็น NA — รายงานเป็น [error] พร้อมส่ง stderr ต่อ ไม่ใช่ [found] · หลังติดตั้งใหม่ ด่านเดียวที่ pass คือทะเบียนที่ส่งมากับบันเดิล (gates-registry-total) ส่วน workflow ตั้งต้นที่ตัวติดตั้งเขียนให้เป็น NA สำหรับตัวตรวจ pin ทั้งสองจนกว่าจะมีบรรทัดถูกแก้ — เขียวบนไฟล์ของบันเดิลเองไม่ได้บอกอะไรเกี่ยวกับโปรเจกต์ · ตัวตรวจทะเบียนอ่านทิศของตัวเองด้วย: gate ที่งานของมัน ทำให้ build แดงไม่ได้ — workflow ที่ไม่มี trigger, if: false, หรือ continue-on-error: true — เป็น finding เพราะแถวที่ไม่มีอะไรทำให้ล้มได้คือแถวเปล่า ๆ · และบันเดิลจดสิ่งที่มันติดตั้งไว้: gates_doctor --installed ถือทุกไฟล์ที่มันเขียนไว้กับ เนื้อ ที่มันเขียน ไม่ใช่แค่ว่ามีไฟล์อยู่ · และตอนอัปเกรด มันบอกว่ารุ่นนี้เลิกส่งอะไร แล้วปล่อยไฟล์นั้นไว้ เพราะไฟล์ในรีโปของคุณเป็นสิทธิ์ของคุณที่จะลบ · การติดตั้งที่หยุดกลางทางถูกอ่านว่าอย่างนั้น — doctor ขึ้นต้นด้วย การติดตั้งครั้งล่าสุดลงในต้นไม้นี้ยังไม่จบ แทนที่จะรายงานไฟล์ที่ลงไปแล้วว่าเป็นไฟล์ที่ถูกใครแก้ · และ gates_doctor --rules พิมพ์กฎที่บันเดิล ตัดสินได้ — แต่ละข้อพร้อมที่มาและตัวสแกนที่อ่านมัน — ให้ไฟล์คำสั่งที่โปรเจกต์เก็บไว้ให้ agent (AGENTS.md, CLAUDE.md) ชี้มาหา: อ่านตอนรันจาก manifest ที่ติดตั้งอยู่ การอัปเกรดจึงทิ้ง agent ไว้กับกฎเมื่อวานไม่ได้ และมีเฉพาะกฎที่ตัวสแกน ตรงนี้ตัดสินได้ จึงไม่มีคำสั่งข้อไหนยืนอยู่โดยไม่มีด่านหนุนหลัง · และมันพิมพ์กฎเฉพาะจากบันเดิลที่ record ยังรับรอง — manifest ถูกแก้ · scanner ถูกแก้ · หรือไม่มี record เลย = ไม่พิมพ์กฎสักข้อ exit 2 เพราะไฟล์ที่มันอ่านอยู่ในโปรเจกต์ที่มันกำลังตรวจเอง (DECISIONS.md the-rules-are-read-off-a-bundle-that-is-still-intact) · และ gates_doctor --sarif FILE เขียนผลรอบเดียวกันเป็น SARIF 2.1.0 ให้ code scanning, reviewdog หรือ IDE — finding เป็น result ส่วน NA กับสแกนที่ตอบไม่ได้เป็น notification บน invocation ไม่ใช่ result คนที่นับ result จึงเข้าใจ "ดูไม่ได้" เป็น "ดูแล้วไม่เจอ" ไม่ได้ · ไฟล์ที่มีอยู่แล้วที่ path นั้นจะถูกแทนที่ก็ต่อเมื่อเป็นผลรอบของ doctor ตัวนี้บน root เดียวกัน ถ้าเป็นผลของต้นไม้อื่นหรืออย่างอื่นจะถูกทิ้งไว้และบอกชื่อ — สองต้นไม้ที่ใช้ path เดียวกันไม่เสียคำตอบ · ตัวตรวจ pin อ่าน workflow ทุกไฟล์ composite action ที่ uses: ./<path> ชี้ไม่ว่าอยู่ที่ไหนหรือพับบรรทัดอย่างไร และเชลล์สคริปต์ที่ run: เรียกต่อ ไม่ว่าจะรู้จากชื่อ .sh หรือจาก shebang ใส่เครื่องหมายคำพูดหรือไม่ก็ตาม จากที่ที่เชลล์ยืนอยู่ (cd dir && ก่อนหน้า หรือ working-directory: ของ step) โดยตัดคอมเมนต์ก่อน — # ที่อยู่ในคำ ($#, ${#PKGS}, \#) ไม่ใช่คอมเมนต์ · ใน workflow ตัดสินเฉพาะสิ่งที่ run: รันจริง (name: หรือ env: ที่ยกคำสั่งมาพูดถึงเป็นแค่ข้อความ) และ --require-hashes นับเมื่อเป็น อาร์กิวเมนต์ของคำสั่งติดตั้งเองเท่านั้น (จะอยู่ในเครื่องหมายคำพูดหรือไม่ก็ตาม) · PIP_REQUIRE_HASHES=1 บนคำสั่งหรือใน env: ของ step และไฟล์ requirements ที่ทุกบรรทัดมี --hash= ก็นับ เพราะ pip บังคับ hash เองในกรณีเหล่านั้น · --no-index และ wheel ที่ติดตั้งด้วย --no-deps ไม่ดึงอะไรจาก index จึงไม่ถูกตัดสิน · คำสั่งใน $( ) backtick subshell สตริงของ sh -c (รวม -c ที่พับกับ flag อื่นเช่น bash -lc) สตริงที่ python -c ส่งให้ os.system หรือหลัง & เดี่ยว รันจริงจึงถูกตัดสิน ส่วน echo ที่แค่พูดคำนั้นเป็นข้อความ — เว้นแต่คำนั้นถูกส่งให้เชลล์ผ่าน pipe (echo … | bash) here-string หรือ eval และค่าเริ่มต้นของ ${PIP:-pip} ถูกอ่านเป็นคำนั้น · รูป YAML uses : และ - {uses: …} ถูกอ่านแบบเดียวกับที่แพลตฟอร์มอ่าน — เช่นเดียวกับคีย์ในเครื่องหมายคำพูด ("run":) alias ของ anchor ที่ตั้งไว้ที่ใดก็ได้ในไฟล์ (run: *cmd, uses: *co พร้อม comment เวอร์ชันของ anchor) ค่าที่มี tag (!!str) และ scalar แบบ plain quoted หรือ folded (>) ที่ต่อลงบรรทัดถัดไป ซึ่ง YAML เชื่อมด้วยช่องว่างก่อนถึงเชลล์ · มีแต่ literal block (|) ที่คงบรรทัดแยกกัน และ uses ใต้ with: เป็น input ไม่ใช่ step · actions-sha-pinned ตัดสินทั้งสองครึ่งของชื่อกฎ: tag ลอยเป็น finding และ commit SHA ที่ไม่มี comment บอกเวอร์ชันข้าง ๆ ก็เป็น finding (digest ของ docker:// ไม่ต้องมี) · adr-index-complete รายงานบันทึกสองฉบับที่ใช้เลขเดียวกันเช่นเดียวกับเลขที่ขาด · csp-no-inline อ่าน ONCLICK= STYLE= และ <style> แบบไม่สนตัวพิมพ์และไม่สนการตัดบรรทัด (รวม = ที่อยู่บรรทัดถัดจากชื่อ) เหมือนที่เบราว์เซอร์อ่าน โดยลบคอมเมนต์ก่อน (คอมเมนต์ที่ไม่ปิดกินถึงท้ายไฟล์) ถอด entity ในค่าของ attribute ก่อนอ่าน scheme (&#106;avascript:) และอ่าน .htm .jinja .jinja2 .j2 เหมือน .html · Dockerfile* ที่มีอยู่แต่ไม่ได้ตั้งชื่อไว้ใน scaffold.json ถือเป็น finding ไม่ใช่ "ไม่มี Dockerfile" · ค่าใน scaffold.json ที่ผิดรูป — ลิสต์ในที่ที่ต้องเป็นพาธเดียว หรือสตริงในที่ที่ต้อง เป็นลิสต์ของชื่อ — และพาธที่พาออกไปนอกโปรเจกต์ เป็น finding ที่บอกชื่อคีย์ เช่นเดียวกับพาธที่ตั้งชื่อไว้แต่ไม่มีอยู่จริง

คลังเก็บสองภาษา: อังกฤษเป็นข้อความที่เผยแพร่ ส่วนถ้อยคำไทยต้นฉบับอยู่ในฟิลด์ *_th คู่กัน เพราะคำแปลของบันทึกเหตุการณ์คือการเล่าใหม่ และการเล่าใหม่ไม่ใช่ตัวบันทึก

โค้ด: Apache-2.0 (ผู้ร่วมพัฒนาลงนาม CLA.md) · กฎและเอกสาร: CC BY 4.0

Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

verifiable_gates-0.2.0.tar.gz (454.5 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

verifiable_gates-0.2.0-py3-none-any.whl (261.5 kB view details)

Uploaded Python 3

File details

Details for the file verifiable_gates-0.2.0.tar.gz.

File metadata

  • Download URL: verifiable_gates-0.2.0.tar.gz
  • Upload date:
  • Size: 454.5 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/7.0.0 CPython/3.13.14

File hashes

Hashes for verifiable_gates-0.2.0.tar.gz
Algorithm Hash digest
SHA256 f4be89fe408a12fee982c77221031369190fdeb03cddf1b742d93c3fe64f6be9
MD5 84aedb971fcda41afbf74b5a5a1b884a
BLAKE2b-256 34edc79bb04fbf8be4d913d017456b3081ae0dff1704de07124258de63154475

See more details on using hashes here.

Provenance

The following attestation bundles were made for verifiable_gates-0.2.0.tar.gz:

Publisher: release.yml on sayam/verifiable-gates

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file verifiable_gates-0.2.0-py3-none-any.whl.

File metadata

File hashes

Hashes for verifiable_gates-0.2.0-py3-none-any.whl
Algorithm Hash digest
SHA256 31c5481c97883d751d4d3df1b946e60aeae931ee7813f7a352ed2ff62738f229
MD5 da9065a6023ed3616ee4c2ae5fe01e3d
BLAKE2b-256 523418d61792520cb5973af7d94fbb2cba110d1794a69ba8a950f97cd76585dd

See more details on using hashes here.

Provenance

The following attestation bundles were made for verifiable_gates-0.2.0-py3-none-any.whl:

Publisher: release.yml on sayam/verifiable-gates

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Release history Release notifications | RSS feed

0.6.0

2 files

0.5.0

2 files

0.4.0

2 files

0.3.1

2 files

0.3.0

2 files

This release

0.2.0 This release

2 files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page