Repository navigation
fix(deps): patch open security alerts #324
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,5 @@ | ||
| # Chunk Map: WS-SEC-001 Dependency Alert Remediation | ||
|
|
||
| | Chunk | Goal | Risk | State | | ||
| |---|---|---:|---| | ||
| | `WS-SEC-001-01` | Upgrade six Dependabot-alerted runtime and tooling dependency records without changing product behavior | L1 | Complete | |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,10 @@ | ||
| # Status: WS-SEC-001 Dependency Alert Remediation | ||
|
|
||
| - Initiative state: complete on merge of `WS-SEC-001-01` | ||
| - Runtime dependency outcome: `cryptography` and `pypdf` use patched versions. | ||
| - Tooling dependency outcome: backend manifests use patched `pytest` and | ||
| `pytest-asyncio`; mutation-tool manifests use patched `pytest` and `uv` | ||
| versions. | ||
| - Product behavior changed: no | ||
|
|
||
| Future dependency alerts use fresh bounded changes against current `main`. |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,63 @@ | ||
| # WS-SEC-001-01: Patch Dependency Alerts | ||
|
|
||
| ## Intent | ||
|
|
||
| Close the six open Dependabot alerts by moving direct and transitive runtime | ||
| dependencies and retained development tooling to patched versions. | ||
|
|
||
| ## Allowed files | ||
|
|
||
| - `backend/pyproject.toml` | ||
| - `backend/uv.lock` | ||
| - `backend/config/guide_extractor_dependencies.json` | ||
| - `scripts/mutation-requirements.in` | ||
| - `scripts/mutation-requirements.txt` | ||
| - focused dependency tests or documentation if compatibility requires them | ||
| - `.agent-loop/CURRENT_STATE.md` | ||
| - `.agent-loop/initiatives/WS-SEC-001-dependency-alert-remediation/**` | ||
|
|
||
| ## Not allowed | ||
|
|
||
| - Product behavior, API, persistence, migration, authorization, or workflow changes | ||
| - Disabling or dismissing alerts without a patched dependency | ||
| - Weakening dependency hashes, parser isolation, tests, coverage, or CI gates | ||
| - Unrelated dependency upgrades | ||
|
|
||
| ## Acceptance criteria | ||
|
|
||
| - `cryptography` resolves to at least 50.0.0. | ||
| - `pypdf` is exactly 6.15.0 in the direct hash pin, approval manifest, and lock. | ||
| - Backend pytest resolves to at least 9.0.3 after compatibility validation. | ||
| - `pytest-asyncio` resolves to the tested pytest-9-compatible 1.4.x line. | ||
| - Retained mutation tooling pins pytest at least 9.0.3 and uv at least 0.11.15 with hashes. | ||
| - Guide dependency integrity and focused parser, auth, and mutation-policy tests pass. | ||
| - No Workstream product behavior changes. | ||
|
|
||
| ## Risk and review | ||
|
|
||
| Risk: L1 security/dependency integrity. Required review: security, CI integrity, | ||
| test delta, and senior engineering. | ||
|
|
||
| ## Verification | ||
|
|
||
| ```bash | ||
| set -euo pipefail | ||
| cd backend | ||
| uv lock --check | ||
| uv run python scripts/check_guide_extractor_dependencies.py | ||
| uv pip install --dry-run --require-hashes \ | ||
| -r ../scripts/mutation-requirements.txt | ||
| uv run pytest -q tests/test_guide_extractor_dependencies.py tests/test_guide_pdf.py tests/test_mutation_policy.py | ||
| WORKSTREAM_TEST_ADMIN_DATABASE_URL=postgresql+asyncpg://workstream:workstream@localhost:5433/postgres \ | ||
| uv run python scripts/run_isolated_tests.py \ | ||
| --metadata-json /tmp/ws-sec-001-auth-test.json \ | ||
| --timeout-seconds 600 -- uv run pytest -q tests/test_auth.py | ||
| cd .. | ||
| python3 scripts/check_markdown_links.py | ||
| python3 scripts/check_chunk_state_sync.py --base-ref origin/main | ||
| git diff --check | ||
| ``` | ||
|
|
||
| ## Merge state | ||
|
|
||
| - Outcome on merge: `complete` | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,43 @@ | ||
| # External Review Response: WS-SEC-001-01 | ||
|
|
||
| ## Comments Addressed | ||
|
|
||
| - Raised the backend `pytest-asyncio` lower bound to the tested 1.4 line so the | ||
| declared range cannot select an earlier release that excludes pytest 9. | ||
| - Made the recorded verification sequence fail fast and added a hash-locked | ||
| dry run for the retained mutation-tool requirements. | ||
| - Named the backend `pytest`/`pytest-asyncio` pair and mutation `pytest`/`uv` | ||
| pair explicitly in the initiative outcome. | ||
| - Reverified that the direct pin, approval manifest, lock, and normative | ||
| specification agree on `pypdf` 6.15.0. No additional change was required for | ||
| that already-satisfied thread. | ||
| - Expanded the GitHub PR description to the repository trust-bundle structure. | ||
|
|
||
| ## Comments Deferred | ||
|
|
||
| None. | ||
|
|
||
| ## Human Decisions Needed | ||
|
|
||
| None beyond normal review and explicit merge approval. | ||
|
|
||
| ## Commands Rerun | ||
|
|
||
| ```bash | ||
| cd backend | ||
| uv lock --check | ||
| uv run python scripts/check_guide_extractor_dependencies.py | ||
| uv pip install --dry-run --require-hashes \ | ||
| -r ../scripts/mutation-requirements.txt | ||
| uv run pytest -q tests/test_guide_extractor_dependencies.py \ | ||
| tests/test_guide_pdf.py tests/test_mutation_policy.py | ||
| cd .. | ||
| python3 scripts/check_markdown_links.py | ||
| python3 scripts/check_chunk_state_sync.py --base-ref origin/main | ||
| git diff --check | ||
| ``` | ||
|
|
||
| ## Remaining Risks | ||
|
|
||
| The full semantic-lane and coverage suite remains the exact-head GitHub | ||
| Backend workflow's responsibility. |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,59 @@ | ||
| # PR Trust Bundle: WS-SEC-001-01 | ||
|
|
||
| ## Chunk | ||
|
|
||
| `WS-SEC-001-01` - Patch dependency alerts | ||
|
|
||
| ## Goal And Context | ||
|
|
||
| Patch the six open Dependabot findings without changing Workstream product | ||
| behavior. The bounded contract is | ||
| [`WS-SEC-001-01-patch-dependency-alerts.md`](../chunks/WS-SEC-001-01-patch-dependency-alerts.md). | ||
|
|
||
| ## What Changed And Why | ||
|
|
||
| - Upgraded `cryptography` and the approved `pypdf` artifact to patched lines. | ||
| - Upgraded backend pytest/pytest-asyncio and retained mutation pytest/uv | ||
| tooling to mutually compatible patched lines. | ||
| - Preserved exact artifact and mutation-manifest hashes. | ||
| - Synchronized the parser approval manifest, normative specification, and | ||
| durable initiative state. | ||
|
|
||
| ## Scope Control | ||
|
|
||
| Only dependency declarations, generated locks, dependency approval records, | ||
| the matching normative version declarations, and WS-SEC-001 loop evidence | ||
| changed. No product behavior, API, persistence, migration, authorization, | ||
| workflow, test, coverage, or CI gate changed. | ||
|
|
||
| ## Acceptance Proof | ||
|
|
||
| - Backend lock resolves `cryptography` 50.0.0, `pypdf` 6.15.0, pytest 9.1.1, | ||
| and pytest-asyncio 1.4.0. | ||
| - Mutation requirements hash-install pytest 9.0.3 and uv 0.11.15. | ||
| - The direct PDF pin, approval manifest, lock, and normative specification | ||
| agree on the approved version and artifact identity. | ||
| - Focused dependency/parser/mutation tests and real-PostgreSQL authorization | ||
| tests passed before publication; the exact-head GitHub workflow supplies the | ||
| complete semantic-lane and coverage proof. | ||
|
|
||
| ## Reviewer Results | ||
|
|
||
| | Reviewer | Result | Blocking findings | Notes | | ||
| |---|---:|---|---| | ||
| | Security | PASS WITH LOW RISKS | None | Stale normative pypdf references fixed | | ||
| | CI integrity | PASS WITH LOW RISKS | None | No CI files or gates changed | | ||
| | Test delta | PASS WITH LOW RISKS | None | No tests or thresholds changed | | ||
| | Senior engineering | PASS WITH LOW RISKS | None | Resolver-marker churn noted as non-blocking | | ||
| | CodeRabbit | Addressed | None open after fixes | Three threads triaged; valid findings fixed | | ||
|
|
||
| ## CI Integrity And Remaining Risks | ||
|
|
||
| No workflow, test, lint, coverage, or package-script gate was weakened. Backend | ||
| dev ranges may resolve later compatible minor releases in future fresh pip | ||
| installs; the exact PR head must pass GitHub Backend before merge. | ||
|
|
||
| ## Human Review And Merge Ownership | ||
|
|
||
| Review the dependency versions, exact hashes, synchronized pypdf records, and | ||
| green exact-head checks. Only the user may approve and merge this PR. |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -18,7 +18,7 @@ dependencies = [ | |
| "Pillow @ https://files.pythonhosted.org/packages/84/21/a35af28dcc61f37ed850a2d64c65c701321dfbf25085e469d5559360cbbf/pillow-12.3.0-cp312-cp312-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl#sha256=78cb2c6865a35ab8ff8b75fd122f6033b92a62c82801110e48ddd6c936a45d91 ; python_version == \"3.12\" and sys_platform == \"linux\" and platform_machine == \"x86_64\" and platform_python_implementation == \"CPython\"", | ||
| "PyJWT[crypto]>=2.13,<3.0", | ||
| "pydantic-settings>=2.6,<3.0", | ||
| "pypdf @ https://files.pythonhosted.org/packages/49/e6/136aa8993a2ae7214e0b0ef2edaa0d2e08d1d4e4982635b08a835ff31ec8/pypdf-6.14.2-py3-none-any.whl#sha256=3f07891af76dc002657e04993ab9b4de81de29f9013b9761d0b7968bff12e946", | ||
| "pypdf @ https://files.pythonhosted.org/packages/af/72/ce3067ac31e214a66388159f8462ddb8c13dd00170f24d555a1f1ae8ee91/pypdf-6.15.0-py3-none-any.whl#sha256=14e001d6504822cb1ca9c7ed9a69bccb320f59b320730f55af804361abe4d5ee", | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🗄️ Data Integrity & Integration | 🟡 Minor | ⚡ Quick win 🧩 Analysis chain🏁 Script executed: #!/usr/bin/env bash
set -euo pipefail
url='https://files.pythonhosted.org/packages/af/72/ce3067ac31e214a66388159f8462ddb8c13dd00170f24d555a1f1ae8ee91/pypdf-6.15.0-py3-none-any.whl'
sha256='14e001d6504822cb1ca9c7ed9a69bccb320f59b320730f55af804361abe4d5ee'
for file in \
backend/pyproject.toml \
backend/config/guide_extractor_dependencies.json \
docs/spec_artifact_storage_service.md
do
test -f "$file"
rg -n -F "$url" "$file"
rg -n -F "$sha256" "$file"
doneRepository: Flow-Research/workstream Length of output: 862 🏁 Script executed: #!/usr/bin/env bash
set -euo pipefail
printf '%s\n' '--- candidate dependency and lock files ---'
git ls-files | rg '(^|/)(pyproject\.toml|.*(lock|dependencies|artifact_storage).*)$' || true
printf '%s\n' '--- all pypdf references ---'
rg -n -i -C 2 'pypdf|14e001d6504822cb1ca9c7ed9a69bccb320f59b320730f55af804361abe4d5ee|pypdf-6\.15\.0' . --glob '!*.pyc' || true
printf '%s\n' '--- relevant tracked-file excerpts ---'
for file in backend/pyproject.toml backend/config/guide_extractor_dependencies.json docs/spec_artifact_storage_service.md; do
if test -f "$file"; then
echo "### $file"
rg -n -i -C 4 'pypdf|pdf|dependency|lock' "$file" || true
else
echo "### $file (missing)"
fi
doneRepository: Flow-Research/workstream Length of output: 50382 🏁 Script executed: #!/usr/bin/env bash
set -euo pipefail
python3 - <<'PY'
import json
import re
import tomllib
from pathlib import Path
expected = {
"version": "6.15.0",
"filename": "pypdf-6.15.0-py3-none-any.whl",
"url": "https://files.pythonhosted.org/packages/af/72/ce3067ac31e214a66388159f8462ddb8c13dd00170f24d555a1f1ae8ee91/pypdf-6.15.0-py3-none-any.whl",
"sha256": "14e001d6504822cb1ca9c7ed9a69bccb320f59b320730f55af804361abe4d5ee",
}
pyproject = tomllib.loads(Path("backend/pyproject.toml").read_text())
requirements = pyproject["project"]["dependencies"]
pinned = [r for r in requirements if r.startswith("pypdf @ ")]
print("pyproject:", pinned)
assert len(pinned) == 1
assert expected["url"] in pinned[0]
assert f"`#sha256`={expected['sha256']}" in pinned[0]
manifest = json.loads(Path("backend/config/guide_extractor_dependencies.json").read_text())
entry = next(d for d in manifest["dependencies"] if d["name"] == "pypdf")
artifact = entry["approved_artifacts"][0]
print("manifest:", entry["version"], artifact)
assert entry["version"] == expected["version"]
assert artifact["filename"] == expected["filename"]
assert artifact["url"] == expected["url"]
assert artifact["sha256"] == expected["sha256"]
lock = Path("backend/uv.lock").read_text()
package = re.search(
r'(?ms)^\[\[package\]\]\n(?:(?!^\[\[package\]\]).)*?^name = "pypdf"\n(?:(?!^\[\[package\]\]).)*?^version = "([^"]+)".*?^source = \{ url = "([^"]+)" \}.*?^wheels = \[\n\s+\{ url = "([^"]+)", hash = "sha256:([^"]+)" \ },\n\]',
lock,
)
assert package, "pypdf package record not found in backend/uv.lock"
print("uv.lock:", package.groups())
assert package.group(1) == expected["version"]
assert package.group(2) == expected["url"]
assert package.group(3) == expected["url"]
assert package.group(4) == expected["sha256"]
docs = Path("docs/spec_artifact_storage_service.md").read_text()
versions = re.findall(r"`pypdf==([^`]+)`", docs)
print("docs pypdf version declarations:", versions)
assert versions and all(v == expected["version"] for v in versions)
print("all authoritative records agree")
PY
printf '%s\n' '--- dependency synchronization checks ---'
rg -n -C 3 'guide_extractor_dependencies|uv\.lock|pyproject\.toml|approved_artifacts|canonical allowlist|exact wheel URLs and hashes' \
backend/scripts/check_guide_extractor_dependencies.py \
backend/tests/test_guide_extractor_dependencies.py \
docs/spec_artifact_storage_service.md | head -200Repository: Flow-Research/workstream Length of output: 282 Keep the pinned
🤖 Prompt for AI Agents |
||
| "sqlalchemy[asyncio]>=2.0,<3.0", | ||
| "uvicorn[standard]>=0.30,<1.0", | ||
| ] | ||
|
|
@@ -38,8 +38,8 @@ agents = [ | |
| dev = [ | ||
| "docstr-coverage>=2.3,<3.0", | ||
| "jsonschema==4.26.0", | ||
| "pytest>=8.0,<9.0", | ||
| "pytest-asyncio>=0.24,<1.0", | ||
| "pytest>=9.0.3,<10.0", | ||
| "pytest-asyncio>=1.4,<2.0", | ||
| "pytest-cov==7.1.0", | ||
| "ruff>=0.8,<0.16", | ||
| ] | ||
|
|
||
Uh oh!
There was an error while loading. Please reload this page.