Skip to content

Commit 7973536

Browse files
Bundle script update
1 parent 1c5f6dc commit 7973536

215 files changed

Lines changed: 18857 additions & 324 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

‎.github/workflows/ci.yml‎

Lines changed: 211 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,211 @@
1+
# CI — initial scaffold landed by BUG-T-001 (Tier 1 / Day 1 PM) from audit/BUGS.md.
2+
#
3+
# Closes BLOCK findings T-001 (no CI pipeline) and prepares the ground for S-004
4+
# (secret-scan gate, Tier 2 / Day 5) which appends to this file as another step.
5+
# See audit/REPORT.md "Top fixes" + audit/BUGS.md (BUG-T-001 acceptance criteria:
6+
# .github/workflows/ci.yml exists; status check is required for merge).
7+
#
8+
# Triggers: PRs targeting main, plus pushes to main (audit gate on direct merges).
9+
#
10+
# Job design rationale:
11+
# - tests-unit pytest tests/ (10 baseline pass per audit CMD-029).
12+
# Required gate from day one.
13+
# - tests-mocks pytest tests/mocks/ (1203 pass + 7 pre-existing
14+
# failures, see HOLD finding T-002 + audit/BUGS.md).
15+
# Known-broken APIs excluded via -k expression so this
16+
# job is required without first having to fix T-002.
17+
# Stays in lockstep: remove an exclusion ONLY after the
18+
# underlying API mock is fixed.
19+
# - lint-ruff ruff check (26 baseline issues per audit CMD-011).
20+
# Initially non-blocking (continue-on-error) so CI lands
21+
# green today; tighten to required after baseline is
22+
# zero per Q-003.
23+
# - sast-bandit bandit -r . (301 baseline issues per audit CMD-012).
24+
# Same staging: --severity-level medium surfaces the
25+
# 24 MEDIUMs first; non-blocking until those are
26+
# triaged.
27+
# - deps-cve pip-audit -r requirements.txt. Now unblocked by
28+
# BUG-D-001 fix (click 8.1.8 → 8.2.1). Surfaces the
29+
# 27 CVE list per finding D-002. Non-blocking until
30+
# the new D-006+ tickets are addressed (Tier 2/Day 3).
31+
#
32+
# All jobs use Python 3.12 to match the production deployment target
33+
# (environment/*-api/Dockerfile pins FROM python:3.12-slim — see S-002).
34+
# Do NOT raise to 3.14 (the audit-host version) until the Dockerfile base
35+
# bumps in lockstep, otherwise CI passes against an unshipped runtime.
36+
37+
name: CI
38+
39+
on:
40+
pull_request:
41+
branches: [main]
42+
push:
43+
branches: [main]
44+
45+
# Cancel in-progress runs when a new commit lands on the same ref —
46+
# avoids wasting compute on stale PR pushes.
47+
concurrency:
48+
group: ci-${{ github.workflow }}-${{ github.ref }}
49+
cancel-in-progress: true
50+
51+
permissions:
52+
contents: read
53+
54+
jobs:
55+
56+
tests-unit:
57+
name: pytest tests/ (host-only)
58+
runs-on: ubuntu-latest
59+
timeout-minutes: 10
60+
steps:
61+
- uses: actions/checkout@v4
62+
63+
- name: Set up Python 3.12
64+
uses: actions/setup-python@v5
65+
with:
66+
python-version: "3.12"
67+
cache: pip
68+
69+
- name: Install runtime requirements
70+
run: |
71+
python -m pip install --upgrade pip
72+
# tests/ has no docker dependency; install the root requirements only.
73+
# Per audit/BUGS.md BUG-D-001, click is now 8.2.1 which resolves the
74+
# pip-audit ResolutionImpossible blocker.
75+
pip install -r requirements.txt
76+
pip install pytest
77+
78+
- name: Run pytest tests/ (ignore tests/mocks)
79+
run: pytest tests/ -q --ignore=tests/mocks
80+
81+
tests-mocks:
82+
name: pytest tests/mocks/ (excluding known-broken APIs)
83+
runs-on: ubuntu-latest
84+
timeout-minutes: 15
85+
steps:
86+
- uses: actions/checkout@v4
87+
88+
- name: Set up Python 3.12
89+
uses: actions/setup-python@v5
90+
with:
91+
python-version: "3.12"
92+
cache: pip
93+
94+
- name: Install runtime requirements
95+
run: |
96+
python -m pip install --upgrade pip
97+
pip install -r requirements.txt
98+
pip install pytest fastapi httpx pyyaml
99+
100+
# The -k expression below excludes the 7 pre-existing failing mocks
101+
# tracked under HOLD finding T-002 (see audit/findings.json) so the
102+
# CI gate is required without first needing to fix T-002. Each
103+
# exclusion MUST be paired with an open ticket; remove the entry the
104+
# moment the underlying API mock is fixed.
105+
- name: Run pytest tests/mocks/ (skip T-002 baseline failures)
106+
run: |
107+
pytest tests/mocks/ -q \
108+
-k "not (contentful or doordash or dropbox or google_analytics or pagerduty or pinterest or spotify)"
109+
110+
lint-ruff:
111+
name: ruff lint (non-blocking baseline)
112+
runs-on: ubuntu-latest
113+
timeout-minutes: 5
114+
# NON-BLOCKING per audit findings.json Q-003 — there are 26 baseline
115+
# ruff issues today. Flip to required (`continue-on-error: false`) after
116+
# the baseline is at zero. Tracked under Q-003.
117+
continue-on-error: true
118+
steps:
119+
- uses: actions/checkout@v4
120+
121+
- name: Set up Python 3.12
122+
uses: actions/setup-python@v5
123+
with:
124+
python-version: "3.12"
125+
cache: pip
126+
127+
- name: Install ruff
128+
run: pip install ruff==0.15.16
129+
130+
- name: ruff check (report-only)
131+
run: ruff check . --output-format=github
132+
133+
sast-bandit:
134+
name: bandit SAST (non-blocking baseline)
135+
runs-on: ubuntu-latest
136+
timeout-minutes: 5
137+
# NON-BLOCKING per audit finding bandit baseline (301 issues, 24 MEDIUM,
138+
# 277 LOW per CMD-012). --severity-level medium surfaces the 24 MEDIUMs
139+
# first; flip to required after those are triaged.
140+
continue-on-error: true
141+
steps:
142+
- uses: actions/checkout@v4
143+
144+
- name: Set up Python 3.12
145+
uses: actions/setup-python@v5
146+
with:
147+
python-version: "3.12"
148+
cache: pip
149+
150+
- name: Install bandit
151+
run: pip install bandit==1.9.4
152+
153+
- name: bandit scan (medium+)
154+
# Scan src/, eval/, scripts/, environment/_mutable_store.py and
155+
# environment/admin_plane.py — the per-API server.py files are
156+
# intentional mock surfaces and would flood the report; their
157+
# subprocess/tmp/etc. risk is covered by C-001 (false positives in
158+
# container context) per audit findings.json.
159+
run: |
160+
bandit -r src/ eval/ scripts/ \
161+
environment/_mutable_store.py \
162+
environment/admin_plane.py \
163+
--severity-level medium \
164+
--confidence-level medium
165+
166+
deps-cve:
167+
name: pip-audit CVE scan (non-blocking baseline)
168+
runs-on: ubuntu-latest
169+
timeout-minutes: 5
170+
# NON-BLOCKING until BUG-D-002 follow-up tickets (D-006+) bump the 27
171+
# CVE-affected packages identified by the cascade unblock from
172+
# BUG-D-001. Tracked in audit/BUGS.md and the Tier 2 / Day 3 work item.
173+
continue-on-error: true
174+
steps:
175+
- uses: actions/checkout@v4
176+
177+
- name: Set up Python 3.12
178+
uses: actions/setup-python@v5
179+
with:
180+
python-version: "3.12"
181+
cache: pip
182+
183+
- name: Install pip-audit
184+
run: pip install pip-audit==2.10.0
185+
186+
- name: pip-audit requirements.txt
187+
run: pip-audit -r requirements.txt --strict
188+
189+
secret-scan:
190+
name: gitleaks (block on detect)
191+
runs-on: ubuntu-latest
192+
timeout-minutes: 5
193+
# REQUIRED gate — closes BUG-S-004 (CVSS 6.5, CWE-200, audit/BUGS.md).
194+
# The audit established zero secret leaks in working tree (CMD-014) and
195+
# bounded git-history (CMD-018, CMD-020) so the baseline is clean; this
196+
# job is required from day one so any future leak hard-fails the PR.
197+
#
198+
# fetch-depth: 0 is load-bearing — gitleaks scans the full commit history,
199+
# not just the PR diff. A shallow clone (the runner default) would miss
200+
# any secret introduced more than a few commits back.
201+
steps:
202+
- name: Checkout (full history for history scan)
203+
uses: actions/checkout@v4
204+
with:
205+
fetch-depth: 0
206+
207+
- name: gitleaks scan
208+
uses: gitleaks/gitleaks-action@v2
209+
env:
210+
# Suppress the optional Pro-license notice; we use the OSS scanner.
211+
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}

‎.gitignore‎

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -50,3 +50,6 @@ logs/
5050
# macOS Finder duplicate-on-copy directories ("foo copy/", "foo copy 2/").
5151
*\ copy/
5252
*\ copy\ [0-9]*/
53+
54+
# Audit deliverables (findings.json, REPORT.md, BUGS.md, REMEDIATION.md, logs/) — local-only, machine-specific.
55+
audit/
Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,10 @@
1-
FROM python:3.12-slim
1+
FROM python:3.12-slim@sha256:090ba77e2958f6af52a5341f788b50b032dd4ca28377d2893dcf1ecbdfdfe203
2+
RUN groupadd -r app && useradd -r -g app -d /app -s /usr/sbin/nologin app
23
WORKDIR /app
3-
COPY requirements.txt .
4-
RUN pip install --no-cache-dir -r requirements.txt
4+
COPY requirements.txt requirements-locked.txt ./
5+
RUN pip install --no-cache-dir --require-hashes -r requirements-locked.txt
56
COPY . .
7+
RUN chown -R app:app /app
68
EXPOSE 8101
9+
USER app
710
CMD ["uvicorn", "server:app", "--host", "0.0.0.0", "--port", "8101"]

0 commit comments

Comments
 (0)