Skip to content

Commit 24dcd08

Browse files
OgeonX-AiAitomatesclaude
authored
ci: harden workflows and contract registry validation (#9)
* ci: add dependabot github-actions updates Add a github-actions package ecosystem entry so third-party actions pinned with mutable tags (e.g. @v4) get auto-updated weekly. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> * ci: harden workflow permissions and timeouts * test(contracts): verify published registry drift * fix(runtime): bound worker request payloads * fix(contracts): restore canonical CAS schema ids * fix(contracts): pin canonical v1.1.1 release --------- Co-authored-by: Kim Harjamäki <kim.harjamaki@prosimo.fi> Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
1 parent 19965cf commit 24dcd08

22 files changed

Lines changed: 435 additions & 24 deletions

.github/workflows/codeql.yml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ jobs:
88
analyze:
99
name: Analyze
1010
runs-on: ubuntu-latest
11+
timeout-minutes: 30
1112
permissions:
1213
actions: read
1314
contents: read
Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
name: Contract registry live drift
2+
3+
on:
4+
workflow_dispatch:
5+
schedule:
6+
- cron: "17 5 * * 1"
7+
8+
permissions:
9+
contents: read
10+
11+
jobs:
12+
verify-v1-1:
13+
runs-on: ubuntu-latest
14+
timeout-minutes: 10
15+
steps:
16+
- uses: actions/checkout@93cb6efe18208431cddfb8368fd83d5badbf9bfd # v5
17+
- name: Compare published v1.1.1 release with vendored contracts
18+
env:
19+
REGISTRY_BASE: https://coding-autopilot-system.github.io/cas-contracts/registry
20+
PINNED_VERSION: 1.1.1
21+
VENDORED_ROOT: tests/contracts/cas-contracts/v1.1.1
22+
shell: python
23+
run: |
24+
import hashlib, json, os, pathlib, urllib.request
25+
base = os.environ["REGISTRY_BASE"]
26+
version = os.environ["PINNED_VERSION"]
27+
root = pathlib.Path(os.environ["VENDORED_ROOT"])
28+
with urllib.request.urlopen(f"{base}/index.json", timeout=20) as response:
29+
index = json.load(response)
30+
if version not in index.get("releases", []):
31+
raise SystemExit(f"published registry is missing release {version}")
32+
with urllib.request.urlopen(f"{base}/releases/v{version}/manifest.json", timeout=20) as response:
33+
manifest = json.load(response)
34+
for entry in manifest["schemas"]:
35+
local = (root / entry["path"]).read_bytes()
36+
if hashlib.sha256(local).hexdigest() != entry["sha256"]:
37+
raise SystemExit(f"vendored digest drift: {entry['path']}")
38+
with urllib.request.urlopen(f"{base}/releases/v{version}/{entry['path']}", timeout=20) as response:
39+
published = response.read()
40+
if published != local:
41+
raise SystemExit(f"published content drift: {entry['path']}")

.github/workflows/pages.yml

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,14 +6,13 @@ on:
66
- master
77
permissions:
88
contents: read
9-
pages: write
10-
id-token: write
119
concurrency:
1210
group: "pages"
1311
cancel-in-progress: false
1412
jobs:
1513
build:
1614
runs-on: ubuntu-latest
15+
timeout-minutes: 15
1716
steps:
1817
- uses: actions/checkout@v4
1918
- uses: actions/setup-python@v5
@@ -25,10 +24,14 @@ jobs:
2524
with:
2625
path: ./site
2726
deploy:
27+
permissions:
28+
pages: write
29+
id-token: write
2830
environment:
2931
name: github-pages
3032
url: ${{ steps.deployment.outputs.page_url }}
3133
runs-on: ubuntu-latest
34+
timeout-minutes: 10
3235
needs: build
3336
steps:
3437
- name: Deploy to GitHub Pages

.github/workflows/pr-lint.yml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,9 @@ on:
99
jobs:
1010
main:
1111
runs-on: ubuntu-latest
12+
timeout-minutes: 5
13+
permissions:
14+
pull-requests: read
1215
steps:
1316
- uses: amannn/action-semantic-pull-request@v5
1417
env:

.github/workflows/stale.yml

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,10 @@ on:
66
jobs:
77
stale:
88
runs-on: ubuntu-latest
9+
timeout-minutes: 10
10+
permissions:
11+
issues: write
12+
pull-requests: write
913
steps:
1014
- uses: actions/stale@v8
1115
with:

maf_starter/loop_worker_cli.py

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,8 @@
1414
run_bounded_specialists,
1515
)
1616

17+
MAX_REQUEST_BYTES = 1_000_000
18+
1719

1820
@dataclass(frozen=True)
1921
class WorkerEnvelope:
@@ -68,7 +70,15 @@ def main() -> int:
6870
parser.add_argument("--request", help="JSON worker request; stdin is used when omitted")
6971
args = parser.parse_args()
7072
try:
71-
payload = json.loads(args.request if args.request is not None else sys.stdin.read())
73+
if args.request is not None:
74+
request_text = args.request
75+
request_size = len(request_text.encode("utf-8"))
76+
else:
77+
request_text = sys.stdin.read(MAX_REQUEST_BYTES + 1)
78+
request_size = len(request_text.encode("utf-8"))
79+
if request_size > MAX_REQUEST_BYTES:
80+
raise ValueError(f"Worker request exceeds {MAX_REQUEST_BYTES} bytes")
81+
payload = json.loads(request_text)
7282
result = asyncio.run(execute_request(payload))
7383
except (ValueError, json.JSONDecodeError) as error:
7484
print(json.dumps({"error": str(error)}), file=sys.stderr)

tests/contracts/cas-contracts/v1.1.0/common.schema.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"$schema": "https://json-schema.org/draft/2020-12/schema",
3-
"$id": "https://schemas.coding-autopilot.dev/v1.1/common.schema.json",
3+
"$id": "https://schemas.coding-autopilot.dev/v1.1/common.schema.json",
44
"title": "CAS Common Definitions v1.1",
55
"$defs": {
66
"actor": {

tests/contracts/cas-contracts/v1.1.0/manifest.json

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -4,32 +4,32 @@
44
{
55
"id": "https://schemas.coding-autopilot.dev/v1.1/common.schema.json",
66
"path": "common.schema.json",
7-
"sha256": "078026d60c219658fe0fc5cf7c4f786acdcf0c492121f7d688d5078b33ca25af"
7+
"sha256": "75d300c99779327d90872373bfc1661ba04ca1bb52335dec45fe926594ea5d7b"
88
},
99
{
1010
"id": "https://schemas.coding-autopilot.dev/v1.1/phase-execution-request.schema.json",
1111
"path": "phase-execution-request.schema.json",
12-
"sha256": "927ffda5ba809e58627ba25b3275355644b510b0ae1c76f446aa7b7f291f08fd"
12+
"sha256": "4577f1dc99bd04b0ccd84255d4f34935a686273f4ed4cd030ba32e2caf54315a"
1313
},
1414
{
1515
"id": "https://schemas.coding-autopilot.dev/v1.1/phase-execution-result.schema.json",
1616
"path": "phase-execution-result.schema.json",
17-
"sha256": "1d353e20cf6338c2de4a9bec0bad83ca0dec6c9feb5434c5e6264fdc075e7c25"
17+
"sha256": "bcffcbcf4e502a1d578ccce3ba0326e91f5562cd1979a83489b394cdeb4b50e1"
1818
},
1919
{
2020
"id": "https://schemas.coding-autopilot.dev/v1.1/phase-verification-result.schema.json",
2121
"path": "phase-verification-result.schema.json",
22-
"sha256": "ec5b97a2bf75892530442f666d23a8b6dbb8f13bda0efe49553d3f64cd41b995"
22+
"sha256": "ec84a47574424a5c148030f87d8a3f3cdd3041ce24056242fb6f81ddfd3c1340"
2323
},
2424
{
2525
"id": "https://schemas.coding-autopilot.dev/v1.1/sdlc-lifecycle-event.schema.json",
2626
"path": "sdlc-lifecycle-event.schema.json",
27-
"sha256": "bd955637761679d3b6e8ee09fb7b693b1d0362615b0865204c5ae3bacb3809dc"
27+
"sha256": "6e397fb7f76703593fcecb95c1b53d6de0657157d7b99272ca2bb310de5d780f"
2828
},
2929
{
3030
"id": "https://schemas.coding-autopilot.dev/v1.1/sdlc-profile.schema.json",
3131
"path": "sdlc-profile.schema.json",
32-
"sha256": "f4974e911e7cb88191c1a331470c8cd7a79d1c7311c963dd70cd9c8f524ebe45"
32+
"sha256": "c435ceadceb9bde7f5c698f9ce896c12f6e5adba3811191a820e472d151ef971"
3333
}
3434
]
3535
}

tests/contracts/cas-contracts/v1.1.0/phase-execution-request.schema.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"$schema": "https://json-schema.org/draft/2020-12/schema",
3-
"$id": "https://schemas.coding-autopilot.dev/v1.1/phase-execution-request.schema.json",
3+
"$id": "https://schemas.coding-autopilot.dev/v1.1/phase-execution-request.schema.json",
44
"title": "PhaseExecutionRequest",
55
"type": "object",
66
"allOf": [

tests/contracts/cas-contracts/v1.1.0/phase-execution-result.schema.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"$schema": "https://json-schema.org/draft/2020-12/schema",
3-
"$id": "https://schemas.coding-autopilot.dev/v1.1/phase-execution-result.schema.json",
3+
"$id": "https://schemas.coding-autopilot.dev/v1.1/phase-execution-result.schema.json",
44
"title": "PhaseExecutionResult",
55
"type": "object",
66
"allOf": [

0 commit comments

Comments
 (0)