Compare commits
1 Commits
b24d816cc0
...
fa1bda524d
| Author | SHA1 | Date | |
|---|---|---|---|
| fa1bda524d |
33
.gitea/workflows/int9-guard.yaml
Normal file
33
.gitea/workflows/int9-guard.yaml
Normal file
@@ -0,0 +1,33 @@
|
|||||||
|
name: INV-INT9 issue.status write-ownership
|
||||||
|
|
||||||
|
# Hard gate for INV-INT9 (legal-ai docs/spec/X7-paperclip-client-params.md
|
||||||
|
# §4): `issue.status` has exactly one legitimate writer — the
|
||||||
|
# `sync-case-status` scheduled job (`ctx.jobs.register("sync-case-status", …)`
|
||||||
|
# in src/worker.ts), which mirrors legal-ai's case status onto the linked
|
||||||
|
# Paperclip issue. Built after legal-ai issue #446, where a second, unnoticed
|
||||||
|
# writer flip-flopped an issue `done → in_progress` — nobody caught it because
|
||||||
|
# nothing enforced write-ownership. This gate makes sure a third writer never
|
||||||
|
# lands the same way again: any `ctx.issues.update(...)` call that touches
|
||||||
|
# `status` outside the `sync-case-status` job fails the build, unless it
|
||||||
|
# carries an explicit, justified `// noqa: INT9 — <reason>` (a bare noqa with
|
||||||
|
# no reason is itself a violation — exceptions must be argued in writing).
|
||||||
|
#
|
||||||
|
# Pure Node, zero dependencies (scripts/int9-guard.mjs) — no `npm ci` needed.
|
||||||
|
|
||||||
|
on:
|
||||||
|
pull_request:
|
||||||
|
branches: [main]
|
||||||
|
push:
|
||||||
|
branches: [main]
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
int9-guard:
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v4
|
||||||
|
|
||||||
|
- name: INV-INT9 — issue.status write-ownership guard
|
||||||
|
run: node scripts/int9-guard.mjs
|
||||||
|
|
||||||
|
- name: Self-test — הוכחה שהשער נושך (AC5)
|
||||||
|
run: node scripts/int9-guard.mjs --self-test
|
||||||
@@ -14,9 +14,7 @@
|
|||||||
"format": "biome format --write src/",
|
"format": "biome format --write src/",
|
||||||
"format:check": "biome format src/",
|
"format:check": "biome format src/",
|
||||||
"biome": "biome check src/",
|
"biome": "biome check src/",
|
||||||
"biome:fix": "biome check --write src/",
|
"biome:fix": "biome check --write src/"
|
||||||
"int9:guard": "node scripts/int9-guard.mjs",
|
|
||||||
"int9:guard:self-test": "node scripts/int9-guard.mjs --self-test"
|
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@paperclipai/plugin-sdk": "^2026.722.0",
|
"@paperclipai/plugin-sdk": "^2026.722.0",
|
||||||
|
|||||||
@@ -39,18 +39,6 @@
|
|||||||
* node scripts/int9-guard.mjs <path>... # scan only the given files/directories
|
* node scripts/int9-guard.mjs <path>... # scan only the given files/directories
|
||||||
* node scripts/int9-guard.mjs --self-test # run the fixture suite (scripts/fixtures/int9/), prove the gate bites
|
* node scripts/int9-guard.mjs --self-test # run the fixture suite (scripts/fixtures/int9/), prove the gate bites
|
||||||
*
|
*
|
||||||
* NOT WIRED INTO CI YET: the Gitea Actions runner on this server is
|
|
||||||
* registered at *repository* scope for `legal-ai` only
|
|
||||||
* (`action_runner.repo_id = 6`), so any job queued for `plugin-legal-ai` is
|
|
||||||
* never dispatched — measured on legal-ai issue #618, run 3200 / job 3250
|
|
||||||
* sat in `queued` with `started_at: 1970-01-01`. Until a runner is
|
|
||||||
* registered for this repo, run this by hand:
|
|
||||||
* npm run int9:guard
|
|
||||||
* npm run int9:guard:self-test
|
|
||||||
* The workflow file itself (`.gitea/workflows/int9-guard.yaml`) lives in a
|
|
||||||
* separate, deliberately-blocked PR, so merging it does not leave a
|
|
||||||
* permanently-pending check on every future PR in this repo.
|
|
||||||
*
|
|
||||||
* Zero dependencies (node:fs / node:path / node:process only) — no `npm ci`
|
* Zero dependencies (node:fs / node:path / node:process only) — no `npm ci`
|
||||||
* needed in CI; the runner image ships node 24.
|
* needed in CI; the runner image ships node 24.
|
||||||
*/
|
*/
|
||||||
|
|||||||
Reference in New Issue
Block a user