fix: qualify patched Python model and cache dependencies
MariaDB persistence qualification / mariadb (push) Has been cancelled
MariaDB persistence qualification / mariadb (push) Has been cancelled
This commit is contained in:
@@ -0,0 +1,40 @@
|
||||
# SEC-M03 — bounded dependency remediation and actual runtime qualification
|
||||
|
||||
Application lock:49→55 packages; six existing versions change, two obsolete transitive dependencies disappear and eight required transitive dependencies enter through the reviewed major-library transitions. This is not an unrestricted upgrade. Exact changes and new graph identities are in [dependency-checkpoint.json](dependency-checkpoint.json).
|
||||
|
||||
| Owner | Before | After | Reason |
|
||||
| --- | --- | --- | --- |
|
||||
| filelock |3.32.4 |4.2.1 |Published fixes; explicit cache security constraint, native/soft/Hub contention qualified |
|
||||
| Torch CPU |2.6.0+cpu |2.13.0+cpu |Latest first-patched bound among reviewed fixable records; actual official CPU wheel, no CUDA download |
|
||||
| Transformers |4.48.3 |5.10.0 |Reviewed fixed bounds; real BART/tokenizer/generation/API qualification |
|
||||
| Hub |0.36.2 |1.33.0 |Required compatible1.x dependency, exact locked/tested choice |
|
||||
| tokenizers |0.21.4 |0.22.2 |Required compatible ABI range, actual pinned BART tokenizer/Unicode roundtrip |
|
||||
| sympy |1.13.1 |1.14.0 |Torch dependency requirement |
|
||||
|
||||
New required graph members: httpcore,httpx,markdown-it-py,mdurl,pygments,rich,shellingham,typer. Requests and charset-normalizer leave this resolved graph; existing reviewed TLS/build constraints remain. Forty-one old pins are unchanged. All55 downloaded Linux wheels were hash-checked and match the committed lock; the real Dockerfile also installs with `--require-hashes`.
|
||||
|
||||
The new `requirements-dev-linux.lock` preserves every one of the55 runtime pins and adds exactly six existing-test dependency requirements. Broader installed-environment scanning found **one additional alias group**, pytest CVE-2025-71176/GHSA-6w46-j5rx-g56g (four overlapping provider records), beyond the original109 application groups. [Vendor9.0.3](https://github.com/pytest-dev/pytest/releases/tag/9.0.3) and [the fix](https://github.com/pytest-dev/pytest/commit/95d8423bd24992deea5b9df32555fa1741679e2c) identify the temporary-directory repair. The dev pin changes8.3.5→9.0.3, the test lock is regenerated and the complete59-case Linux suite passes without warnings. No test assertion is weakened. The other test-only packages are httpcore2,httpx2,iniconfig,pluggy,truststore; bootstrap pip/wheel are separately inventoried. Neither pytest nor these test extras are added to the application lock.
|
||||
|
||||
## Real supported runtime
|
||||
|
||||
The actual source Dockerfile was rebuilt locally with Python3.12.10/Debian12, the exact55-package CPU lock and native Tesseract5.3.0. A derived, network-free qualification layer adds only the six hashed test extras. [RUNTIME.json](model/RUNTIME.json) records the two actual local image IDs; these are not pullable registry manifest references and no image was uploaded or deployed.
|
||||
|
||||
The initial real build revealed stale `.venv-lock-check`/`.venv.stale-*` directories entering the context. Only that owned build client/plugin was cancelled; its log/outcome remain. Changing `.dockerignore` from `.venv` to `.venv*` reduces the clean context to602.86kB. Actual image inventory verifies no `/app/.venv*` exists. Existing local directories and Docker services are untouched.
|
||||
|
||||
[qualification.json](qualification.json) contains actual process outcomes, input hashes and results. All lanes run without an application-source mount: the code is the built source image, checked by SHA256 against the working source. Nonroot65534, read-only root/fixture/helper mounts, network none, private tmpfs, twoCPU,2GiB,128PIDs and a180-second parent deadline are enforced. Containers are verified absent afterward.
|
||||
|
||||
- Complete sidecar:59/59, zero failed/skipped, using pytest9.0.3 and the actual61-package application/test lock.
|
||||
- Safetensors and restricted PyTorch-state profiles: real BART class/tokenizer/native CPU generation, exact Norwegian tokenizer roundtrip,1024-token truncation, finite logits, short/long generation, actual summary/auth/repeat-cache contract. Each profile stays below one second after imports in this bounded fixture; this is not a full-model latency claim.
|
||||
- Cache: five real artifact-integrity failures rejected before loading; native/soft/Hub cross-process contention expires, then acquires after release; missing offline model returns503 with no partially loaded state. Separate same-version Windows native/soft contention passes. No shared-cache upgrade or Windows ACL/symlink attack is claimed.
|
||||
- Parsers: actual resource-bounded TXT/DOCX/PDF children preserve Norwegian content; native OCR on synthetic PNG and image-only PDF preserves the expected phrase. Actual uvicorn readiness/authenticated summary/cache and upload extraction pass over container loopback; the owned server stops afterward. English traineddata SHA256 is retained.
|
||||
- Inventory: Python/native package versions, all55 installed pins,61 test pins plus bootstrap pip/wheel (63 distributions total), pip check, CPU build details, code hashes and OCR artifact hash are recorded.
|
||||
|
||||
The first52PASS/7FAIL Linux suite is retained: an empty harness Ollama URL failed URL construction before seven existing mocks. Its corrected loopback-only successor passed59/59. Early httpx fallback deprecations are retained; the final exact test layer uses the existing supported httpx2 requirement and has no warning. Earlier model/profile runs and focused checks are not added to final suite totals.
|
||||
|
||||
## Security accounting and limits
|
||||
|
||||
Exact installed queries cover63 distributions/126 requests, zero advisory records. OSV accepts the exact CPU local version; PyPI returns404 for `torch==2.13.0+cpu`. That known second-provider coverage gap is retained as INCOMPLETE rather than reported as a clean request. The official CPU wheel identity/hash and current vendor/security source assessment provide separate evidence. Application55 queries likewise have zero records and the same vendor-release limitation. No suppression or owner risk acceptance is asserted.
|
||||
|
||||
Original109 groups remain traceable as65 previous repairs plus44 individual follow-ups. The [current source assessment](advisory-current-scope.md) supports ten explicitly scoped non-applicability dispositions (unshipped/unused conversion, alternate architectures, export archive loader and the disputed numeric chain); it does not claim those upstream flaws globally fixed. Full final dispositions and Phase9 gates are reconciled after broad regression.
|
||||
|
||||
Full trained DistilBART, semantic quality, GPU, production cache ownership/migration, real device/provider/manual acceptance and live filesystem/recovery state remain unqualified. The source Dockerfile still has mutable base/apt/bootstrap inputs: this measured immutable local image is retained, while a future rebuild must record its actual identities and requalify. Production digest/supply-chain pinning and release approval remain separate gates. The bounded worker deadline/parser cancellation controls do not establish application-level cancellation of in-flight full-model inference.
|
||||
@@ -13,3 +13,9 @@ CI-M01: read-only assessment complete; hosted BLOCKED/current isolation UNVERIFI
|
||||
SEC-M03 in progress: candidate55-package CPU lock resolves;110 exact advisory requests report0 records with the known exact-vendor PyPI404 retained. Both real offline BART serialization profiles PASS, including summary/auth/repeat-cache contract. Complete Linux suite initially52PASS/7FAIL because harness supplied an empty Ollama URL; retained predecessor. Corrected isolated loopback fixture passes59/59 with one documented Starlette/httpx deprecation. Current production requirements are not yet replaced by this candidate.
|
||||
|
||||
Shared loader pin repair: new unit test failed missing immutable revision, then complete native Windows suite59/59 PASS. Tokenizer/model now share immutable revision, deny remote code and request weights_only. Same model identity, no deployment or output-quality acceptance.
|
||||
|
||||
SEC-M03 checkpoint: six bounded application/transitive version updates applied;49→55 exact runtime pins,41 old pins unchanged,55 wheel hashes verified. Added61-pin Linux test lock preserving all55 runtime versions. New test-only pytest advisory discovered outside original109; pin9.0.3 repairs its published range. Actual63-distribution rescan has0records,1retained exact CPU vendor PyPI404. Both actual model formats (including1024-token/finite-logit tests),59 sidecar cases,9 cache failures/lock cases,5 parser/OCR children plus actual HTTP startup and full inventory PASS on the rebuilt source runtime plus exact test extras. No inference mocked; no full trained/GPU/semantic claim.
|
||||
|
||||
Build preservation repair: the real source build initially included stale virtualenv directories. Cancelled only its owned Docker/buildx client tree; retained failed/cancelled evidence. `.venv*` context exclusion yields602.86kB and actual image contains no virtualenv directory. No filesystem repair, cache deletion, Docker service restart or production change. Dependency files receive narrow LF attributes for stable Windows/Linux lock identities.
|
||||
|
||||
REG-M01 broad regression remains pending; previous1130/935/362/35/PDF24 counts remain historical until successor execution. Final acceptance and109-group final disposition table are not inferred from a zero-match scan.
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,40 @@
|
||||
# P9-SEC-02 current image advisory scope
|
||||
|
||||
**Nine upstream no-fix groups and CVE-2025-55554 have defensible “Not affected with evidence” dispositions for this exact CPU BART service path. The upstream no-fix states and55554 global patch discrepancy remain visible.** These are scoped applicability conclusions, not a claim that all44 groups are globally fixed.
|
||||
|
||||
Inspected clean runtime image `sha256:4a04ca68fa40b3ec61cb61187b339a4d2895b375b962999e974d75556b5b1331` using two successful network-none, read-only, non-root, bounded static captures. The generation capture needed one recorded repair retry because5.10 lacks optional generation/beam_search.py; initial failure and actual file membership remain in raw evidence. Runtime: torch2.13.0+cpu, Transformers5.10.0, filelock4.2.1, Hub1.33.0, tokenizers0.22.2. App hash matches the qualification checkpoint; lock hash `3a3afc529f0076a1b5d67082c9269c22c12f52c47ecf95ce0c76c37b39d8297a`. Original research files remain unchanged.
|
||||
|
||||
The app now pins `sshleifer/distilbart-cnn-12-6` at `a4f8f3ea906ed274767e9906dbaede7531d660ff`, explicitly rejects remote code and requests weights_only=True. Verified reference config identifies BART/BartForConditionalGeneration; actual5.10 AutoModelForSeq2SeqLM mapping selects that class. The full1,222,317,369-byte model checkpoint is absent: its expected hash is recorded, but its bytes/hash, full inference, resource use and output quality are not verified.
|
||||
|
||||
## What changed in the installed source
|
||||
|
||||
Only one converter remains in the actual5.10 model tree: unrelated Gemma4. The five named vulnerable converter CLIs are absent. Transformer-XL files are removed. GLM4 is now present and Perceiver remains present, but both are absent from the seq2seq AutoModel mapping. BART tokenizer now aliases the RoBERTa backend; no Transformer-XL pickle vocabulary route exists in this flow.
|
||||
|
||||
PyTorch2.13 still exposes unsafe PT2 loading: export.load calls load_pt2, whose package helpers contain weights_only=False and pickle.loads. The app reaches a different boundary: Transformers load_state_dict uses safetensors or torch.load with explicit weights_only=True. There is no export.load call/model-upload API. This is actual indirect-path evidence, not merely an absent direct torch.load application search.
|
||||
|
||||
## Ten retained alias groups
|
||||
|
||||
| Group / all aliases | Current scoped disposition | Actual current-source/application evidence | Limit |
|
||||
| --- | --- | --- | --- |
|
||||
| [CVE-2025-55554](https://gist.github.com/shaoyuyoung/0e7d2a586297ae9c8ed14d8706749efc)<br>BIT-pytorch-2025-55554, PYSEC-2025-206 | Not affected with evidence | Current BART forward, generation utils, logits processors and generation config sources contain ZERO nan_to_num calls. Beam search3278 invokes the model,3295 uses float log_softmax,3020 chooses topk indices,3023/3026 derive beam/token IDs by integer division/modulo; it does not cast sanitized float scores to long. Existing .long calls convert attention masks/beam masks, not nan_to_num results. CPU auto-compile criteria2052 exclude CPU unless explicit _compile_all_devices is configured; app passes no compile configuration. remove_invalid_values defaultsFalse and even its optional processor1674-1678 uses torch.where returning float scores, with no long cast. | Upstream issue151510 remains open and no global fix is verified. Named operation chain is excluded from this exact CPU BART entry-point; this does not prove all native numerical code correct or full trained-model inference qualified. |
|
||||
| [CVE-2026-4538](https://github.com/pytorch/pytorch/)<br>BIT-pytorch-2026-4538, PYSEC-2026-139 | Not affected with evidence | Current2.13 export.load283 still calls load_pt2; pt2_archive/_package.py891-892 and949-950 explicitly load weights_only=False and978 calls pickle.loads. This is real retained unsafe functionality. App.from_pretrained uses Transformers load_state_dict337, whose .bin fallback384 calls torch.load(weights_only=weights_only); app explicitly supplies True. Neither app nor parser accepts .pt2 model uploads or calls export.load. | Do not equate ordinary torch.load(.bin,weights_only=True) with torch.export.load(.pt2). No full checkpoint is needed to prove these distinct entry points; adding export/compile/package APIs invalidates the scoped exemption. |
|
||||
| [CVE-2025-14929](https://osv.dev/vulnerability/PYSEC-2025-217)<br>PYSEC-2025-217 | Not affected with evidence | Five named conversion CLIs are absent from the actual5.10 wheel, including X-CLIP. The sole installed conversion script is unrelated Gemma4. AutoModelForSeq2SeqLM.from_pretrained selects an existing BART class, not a conversion script. HTTP text/uploads cannot choose an X-CLIP checkpoint conversion command. | Named script absent; no new global vendor fix claim. |
|
||||
| [CVE-2025-14926](https://osv.dev/vulnerability/PYSEC-2025-214)<br>PYSEC-2025-214 | Not affected with evidence | SEW conversion script is absent. BART model initialization does not run SEW convert_config, and the service accepts no converter/model-path arguments. | Named script absent; arbitrary operator-installed conversion tooling is outside this image scope. |
|
||||
| [CVE-2025-14930](https://osv.dev/vulnerability/PYSEC-2025-218)<br>PYSEC-2025-218 | Not affected with evidence | Unlike4.48.3, GLM4 modules are present in5.10. Its Glm4ForCausalLM maps to a different AutoModel family; GLM4 is absent from the seq2seq mapping. Verified pinned config declares model_type=bart and BartForConditionalGeneration. Request text cannot change config/model family. | Do not claim GLM4 code is absent or globally fixed. ZDI does not identify a precise loader function; conclusion is family/entry-point separation only. |
|
||||
| [CVE-2025-14920](https://osv.dev/vulnerability/PYSEC-2025-211)<br>PYSEC-2025-211 | Not affected with evidence | Perceiver modules remain installed. Perceiver appears in generic/masked-LM/classification mappings, but not AutoModelForSeq2SeqLM mapping. Verified pinned BART config selects BART. BART tokenizer/generate do not dispatch Perceiver model parsing. | ZDI mechanism is broad; the scoped finding excludes its named architecture, not all deserialization. Shared torch.load boundary is separately patched/qualified, never assumed harmless. |
|
||||
| [CVE-2025-14921](https://osv.dev/vulnerability/PYSEC-2025-212)<br>PYSEC-2025-212 | Not affected with evidence | Actual5.10 installed model inventory contains no transfo_xl package/files. The old4.48.3 unsafe TransfoXL tokenizer path no longer exists. Selected tokenizer implementation is BART/RoBERTa backend, not a pickle vocabulary tokenizer. | Code removal from this wheel is direct current-source evidence; it does not establish an upstream CVE patch release for every distribution. |
|
||||
| [CVE-2025-14924](https://osv.dev/vulnerability/PYSEC-2025-213)<br>PYSEC-2025-213 | Not affected with evidence | Megatron conversion script is absent from5.10 wheel. Fixed BART loader consumes standard weights, not converter CLI inputs or Megatron checkpoint arguments. | General BART .bin loading still uses torch.load; this is a distinct patched weights_only boundary and not a Megatron conversion exemption for all code. |
|
||||
| [CVE-2025-14927](https://osv.dev/vulnerability/PYSEC-2025-215)<br>PYSEC-2025-215 | Not affected with evidence | SEW-D conversion script absent. Auto seq2seq BART loader and request text do not invoke SEW-D convert_config or execute user conversion strings. | Reassess if conversion tooling or audio-model support added. |
|
||||
| [CVE-2025-14928](https://osv.dev/vulnerability/PYSEC-2025-216)<br>PYSEC-2025-216 | Not affected with evidence | HuBERT conversion script absent. App exposes fixed BART text generation and separate PIL/Tesseract/pypdf extraction; no HuBERT audio conversion route. | No global vendor fix claim; boundary is named converter absence plus fixed BART dispatch. |
|
||||
|
||||
## Acceptance criterion and remaining risk
|
||||
|
||||
A scoped Not affected conclusion is legitimate when the exact installed script is absent or the named API/family is excluded by fixed app calls, current loader mapping and verified pinned config, and untrusted HTTP input cannot select a different entry point. Full numerical model weights are not needed to distinguish a conversion CLI or torch.export.load from ordinary BART loading. Preserve upstream no-fix state, aliases and published severity; reopen the finding if accepted model formats, architecture, loader arguments, cache trust or packages change.
|
||||
|
||||
CVE-2025-55554 was reassessed after the additional generation source trace. BART forward, generation utils, logits processors and generation config contain no nan_to_num call. Beam search uses float log_softmax and topk indices with integer division/modulo, not sanitized float-to-long conversion. Existing .long calls convert masks. CPU auto-compile is excluded unless an explicit compile-all-devices config is provided; app supplies none. Even optional InfNanRemoveLogitsProcessor uses torch.where with float output, not nan_to_num().long(). These concrete entry-point facts justify scoped Not affected; synthetic finite logits alone would not. The vendor issue remains open, so no global patch claim follows.
|
||||
|
||||
Falsifiers: introduce a nan_to_num-to-long chain through model/generation/custom logits processing; allow user tensors/models/graphs; enable CPU compilation or change backend/device; or show that the exact named bug reaches these retained operations despite the absent chain. Any such evidence requires reopening this scoped assessment.
|
||||
|
||||
Existing qualification checkpoint passes are local compatibility evidence:59 sidecar tests, synthetic BART weights in safetensors and weights_only formats with the real pinned tokenizer,9 cache cases,5 parser/OCR cases and HTTP startup. This source lane ran no inference or tests. None establishes full selected-model or production acceptance. No owner risk acceptance is asserted.
|
||||
|
||||
Machine-readable detail, source line matches/hashes, scope criteria and all aliases: [advisory-current-scope.json](advisory-current-scope.json). Raw capture/process identity: `.artifacts/p9-sec-02/current-source/`. These10 groups remain part of44;109=65+44 accounting is unchanged.
|
||||
@@ -0,0 +1,62 @@
|
||||
{
|
||||
"observedUtc": "2026-10-25T06:44:48.752890+00:00",
|
||||
"method": "GET metadata only; existing Git credential used only in memory; redirects refused",
|
||||
"requests": {
|
||||
"runs-branch-query": {
|
||||
"httpStatus": 200,
|
||||
"path": ".artifacts/p9-sec-02/ci-postpush/runs-branch-query.json",
|
||||
"bytes": 4128,
|
||||
"sha256": "c9ee5dc4aa1da12276f0607b9886980279188bdecc813eb0ea1329c08f300c7a"
|
||||
},
|
||||
"jobs-856": {
|
||||
"httpStatus": 200,
|
||||
"path": ".artifacts/p9-sec-02/ci-postpush/jobs-856.json",
|
||||
"bytes": 653,
|
||||
"sha256": "199e3c4bbf0b3bb9d97881ee0754b8842144044c6b5a5365ad718a3e05a7d1af"
|
||||
}
|
||||
},
|
||||
"returnedRunCount": 1,
|
||||
"branchRuns": [
|
||||
{
|
||||
"id": 856,
|
||||
"head_sha": "22ef8d003c8afcab7b901060a224e1434a7a761c",
|
||||
"head_branch": "fix/p9-model-cache-and-ci-qualification",
|
||||
"status": "queued",
|
||||
"conclusion": null,
|
||||
"html_url": "https://git.cesnimda.uk/cesnimda/jobtrackingapp/actions/runs/856",
|
||||
"created_at": null,
|
||||
"updated_at": null
|
||||
}
|
||||
],
|
||||
"jobs": [
|
||||
{
|
||||
"runId": 856,
|
||||
"head_sha": "22ef8d003c8afcab7b901060a224e1434a7a761c",
|
||||
"jobs": [
|
||||
{
|
||||
"id": 1746,
|
||||
"name": "mariadb",
|
||||
"status": "queued",
|
||||
"conclusion": null,
|
||||
"runner_id": 0,
|
||||
"runner_name": null,
|
||||
"started_at": "1970-01-01T00:00:00Z",
|
||||
"completed_at": "1970-01-01T00:00:00Z",
|
||||
"labels": [
|
||||
"jobtracker-mariadb-isolated"
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
],
|
||||
"newHostConfigInspected": false,
|
||||
"newLogsDownloaded": false,
|
||||
"baselinePushCommit": "22ef8d003c8afcab7b901060a224e1434a7a761c",
|
||||
"hostedVerdict": "BLOCKED",
|
||||
"isolationProof": false,
|
||||
"limits": "One bounded branch metadata query; no logs, dispatch, cancel, host or production access. Queue/assignment is not isolation proof.",
|
||||
"workflow": {
|
||||
"path": ".gitea/workflows/mariadb-integration.yml",
|
||||
"sha256": "5fb3d4294a7b375b8883f618bbb87ae4028ff87ce623b38910c5898c44902287"
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,90 @@
|
||||
{
|
||||
"exitCode": 0,
|
||||
"command": [
|
||||
"E:\\Storage\\Projects\\Active\\Job tracker\\tools\\summarizer\\.venv\\Scripts\\python.exe",
|
||||
"-m",
|
||||
"uv",
|
||||
"pip",
|
||||
"compile",
|
||||
"requirements.txt",
|
||||
"--generate-hashes",
|
||||
"--python-version",
|
||||
"3.12",
|
||||
"--python-platform",
|
||||
"x86_64-unknown-linux-gnu",
|
||||
"--torch-backend",
|
||||
"cpu",
|
||||
"--output-file",
|
||||
"requirements-linux.lock"
|
||||
],
|
||||
"beforeCount": 49,
|
||||
"afterCount": 55,
|
||||
"sameQualifiedCandidatePins": true,
|
||||
"newLockSha256": "3a3afc529f0076a1b5d67082c9269c22c12f52c47ecf95ce0c76c37b39d8297a",
|
||||
"changes": {
|
||||
"charset-normalizer": {
|
||||
"before": "3.5.1",
|
||||
"after": null
|
||||
},
|
||||
"filelock": {
|
||||
"before": "3.32.4",
|
||||
"after": "4.2.1"
|
||||
},
|
||||
"httpcore": {
|
||||
"before": null,
|
||||
"after": "1.0.9"
|
||||
},
|
||||
"httpx": {
|
||||
"before": null,
|
||||
"after": "0.28.1"
|
||||
},
|
||||
"huggingface-hub": {
|
||||
"before": "0.36.2",
|
||||
"after": "1.33.0"
|
||||
},
|
||||
"markdown-it-py": {
|
||||
"before": null,
|
||||
"after": "4.2.0"
|
||||
},
|
||||
"mdurl": {
|
||||
"before": null,
|
||||
"after": "0.1.2"
|
||||
},
|
||||
"pygments": {
|
||||
"before": null,
|
||||
"after": "2.21.0"
|
||||
},
|
||||
"requests": {
|
||||
"before": "2.34.2",
|
||||
"after": null
|
||||
},
|
||||
"rich": {
|
||||
"before": null,
|
||||
"after": "15.0.0"
|
||||
},
|
||||
"shellingham": {
|
||||
"before": null,
|
||||
"after": "1.5.4"
|
||||
},
|
||||
"sympy": {
|
||||
"before": "1.13.1",
|
||||
"after": "1.14.0"
|
||||
},
|
||||
"tokenizers": {
|
||||
"before": "0.21.4",
|
||||
"after": "0.22.2"
|
||||
},
|
||||
"torch": {
|
||||
"before": "2.6.0+cpu",
|
||||
"after": "2.13.0+cpu"
|
||||
},
|
||||
"transformers": {
|
||||
"before": "4.48.3",
|
||||
"after": "5.10.0"
|
||||
},
|
||||
"typer": {
|
||||
"before": null,
|
||||
"after": "0.27.3"
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,8 @@
|
||||
# Local qualification only; verify the base image identity in RUNTIME.json before building.
|
||||
FROM jobtracker-p9-sec02-python:runtime
|
||||
USER root
|
||||
COPY wheels /qualification-wheels
|
||||
COPY extras.lock /qualification-extras.lock
|
||||
RUN python -m pip install --no-index --find-links /qualification-wheels --require-hashes --no-cache-dir -r /qualification-extras.lock \
|
||||
&& python -m pip check
|
||||
USER app
|
||||
@@ -0,0 +1,7 @@
|
||||
{
|
||||
"runtimeImageId": "sha256:4a04ca68fa40b3ec61cb61187b339a4d2895b375b962999e974d75556b5b1331",
|
||||
"qualificationImageId": "sha256:2fe77e47a6c5ecea66764dbd6264049724f24849141e16af5491c2de34af53c1",
|
||||
"applicationLockSha256": "3a3afc529f0076a1b5d67082c9269c22c12f52c47ecf95ce0c76c37b39d8297a",
|
||||
"testLockSha256": "a234316d8612193551a2c91fb19ae0924f5643b9e52edb907ab99dd55b14cdb9",
|
||||
"scope": "Locally built actual source Dockerfile plus six exact hashed test-only extras. Local image IDs, not asserted pullable registry references; no deployment."
|
||||
}
|
||||
@@ -0,0 +1,64 @@
|
||||
"""Actual isolated lock/cache failures; never opens a developer or production cache."""
|
||||
from pathlib import Path
|
||||
import importlib.metadata
|
||||
import json
|
||||
import os
|
||||
import shutil
|
||||
import subprocess
|
||||
import sys
|
||||
import tempfile
|
||||
from filelock import FileLock, SoftFileLock
|
||||
from huggingface_hub.utils._fixes import WeakFileLock
|
||||
from verify import verify_fixture
|
||||
|
||||
HERE = Path(__file__).resolve().parent
|
||||
manifest = json.loads((HERE / 'ARTIFACTS.json').read_text())['safetensors']
|
||||
source = verify_fixture(Path(sys.argv[1]), manifest)
|
||||
results = []
|
||||
with tempfile.TemporaryDirectory(prefix='jt-model-cache-') as temporary:
|
||||
root = Path(temporary)
|
||||
assert root.stat().st_mode & 0o077 == 0
|
||||
for kind in ['missing', 'corrupt-weights', 'corrupt-config', 'linked', 'extra-code']:
|
||||
directory = root / kind
|
||||
shutil.copytree(source, directory)
|
||||
weights = directory / 'model.safetensors'
|
||||
if kind == 'missing': weights.unlink()
|
||||
elif kind == 'linked':
|
||||
weights.unlink(); weights.symlink_to(source / 'model.safetensors')
|
||||
elif kind == 'extra-code': (directory / 'modeling_unreviewed.py').write_text('raise RuntimeError()')
|
||||
else:
|
||||
file = weights if kind == 'corrupt-weights' else directory / 'config.json'
|
||||
content = bytearray(file.read_bytes()); content[-1] ^= 1; file.write_bytes(content)
|
||||
try: verify_fixture(directory, manifest)
|
||||
except ValueError: results.append({'case': kind, 'rejectedBeforeLoad': True})
|
||||
else: raise AssertionError(kind + ' was accepted')
|
||||
|
||||
child = '''import sys
|
||||
from filelock import FileLock,SoftFileLock,Timeout
|
||||
cls=FileLock if sys.argv[1]=='native' else SoftFileLock
|
||||
try:
|
||||
with cls(sys.argv[2],timeout=0.2): print('acquired')
|
||||
except Timeout: print('timed-out')
|
||||
'''
|
||||
for kind, context in [('native', lambda p: FileLock(p, timeout=1)), ('soft', lambda p: SoftFileLock(p, timeout=1)), ('hub', lambda p: WeakFileLock(p, timeout=1))]:
|
||||
file = root / (kind + '.lock')
|
||||
command = [sys.executable, '-c', child, 'soft' if kind == 'soft' else 'native', str(file)]
|
||||
with context(file):
|
||||
result = subprocess.run(command, capture_output=True, text=True, timeout=5, check=True)
|
||||
assert result.stdout.strip() == 'timed-out', result.stdout
|
||||
result = subprocess.run(command, capture_output=True, text=True, timeout=5, check=True)
|
||||
assert result.stdout.strip() == 'acquired', result.stdout
|
||||
results.append({'case': kind + '-cross-process', 'finiteContentionTimeout': True, 'acquiredAfterRelease': True})
|
||||
|
||||
os.environ['AI_SERVICE_SKIP_MODEL_LOAD'] = '0'
|
||||
sys.path.insert(0, '/app')
|
||||
import app
|
||||
from fastapi.testclient import TestClient
|
||||
app.MODEL_NAME = str(root / 'missing-model')
|
||||
assert app._ensure_runtime_loaded() is False
|
||||
assert app.model is app.tokenizer is None and not app.MODEL_LOADED
|
||||
response = TestClient(app.app).post('/summarize', json={'text': 'Synthetic unavailable model input.'})
|
||||
assert response.status_code == 503 and response.json()['detail']
|
||||
results.append({'case': 'missing-offline-model', 'availability503': True, 'noPartialLoadedState': True})
|
||||
verify_fixture(source, manifest)
|
||||
print(json.dumps({'status': 'PASS', 'filelock': importlib.metadata.version('filelock'), 'hub': importlib.metadata.version('huggingface-hub'), 'cases': results, 'freshPrivateCache': True, 'sourceUnchanged': True, 'limits': 'Linux native/soft/Hub locking in one library generation. No shared-cache migration, Windows fallback, full-model cancellation, GPU or live cache claim.'}), flush=True)
|
||||
Binary file not shown.
@@ -0,0 +1,45 @@
|
||||
%PDF-1.7
|
||||
%µ¶
|
||||
|
||||
1 0 obj
|
||||
<</Type/Catalog/Pages 2 0 R>>
|
||||
endobj
|
||||
|
||||
2 0 obj
|
||||
<</Type/Pages/Count 1/Kids[4 0 R]>>
|
||||
endobj
|
||||
|
||||
3 0 obj
|
||||
<</Font<</helv 5 0 R>>>>
|
||||
endobj
|
||||
|
||||
4 0 obj
|
||||
<</Type/Page/MediaBox[0 0 595 842]/Rotate 0/Resources 3 0 R/Parent 2 0 R/Contents[6 0 R]>>
|
||||
endobj
|
||||
|
||||
5 0 obj
|
||||
<</Type/Font/Subtype/Type1/BaseFont/Helvetica/Encoding/WinAnsiEncoding>>
|
||||
endobj
|
||||
|
||||
6 0 obj
|
||||
<</Length 195/Filter/FlateDecode>>
|
||||
stream
|
||||
xÚE�ÁN!E÷|`[Êí�&nÜ™°3nÞºpã÷{aL^¥”r8¤ŸôÜ“fáÐ\%GXîßéás|ýæ-÷3¿?ºÂ¡&¾ã b‡¢ šØa²×Xù±E ‡E3cWã"¨Ìel˜ƒ$[„YνVñ…ÝzUØ]A1IäO‡X!hœ×ù Ÿ÷"Xsl&Ube81î</VÊmÝÝü‹á˜~Óê"-×ËònâóÆû§�þš^zzK$ŽGz
|
||||
endstream
|
||||
endobj
|
||||
|
||||
xref
|
||||
0 7
|
||||
0000000000 65535 f
|
||||
0000000016 00000 n
|
||||
0000000062 00000 n
|
||||
0000000114 00000 n
|
||||
0000000155 00000 n
|
||||
0000000262 00000 n
|
||||
0000000351 00000 n
|
||||
|
||||
trailer
|
||||
<</Size 7/Root 1 0 R/ID[<C2A562C38EC38E002CC3A5446205C3BB><9B826CB261538573C22FEEA2E273D644>]>>
|
||||
startxref
|
||||
615
|
||||
%%EOF
|
||||
@@ -0,0 +1 @@
|
||||
Ada Lovelace - Åse Østby ærlig erfaring. Backend APIs and reliable data pipelines with Python and C#; platform engineering and testing.
|
||||
@@ -0,0 +1,76 @@
|
||||
"""Resource-bounded actual document/OCR children and real local HTTP startup."""
|
||||
from pathlib import Path
|
||||
import hashlib
|
||||
import json
|
||||
import os
|
||||
import subprocess
|
||||
import sys
|
||||
import tempfile
|
||||
import time
|
||||
from urllib import request, error
|
||||
from PIL import Image, ImageDraw, ImageFont
|
||||
from verify import verify_fixture
|
||||
|
||||
HERE = Path(__file__).resolve().parent
|
||||
manifest = json.loads((HERE / 'ARTIFACTS.json').read_text())['safetensors']
|
||||
verify_fixture('/fixture', manifest)
|
||||
results = []
|
||||
with tempfile.TemporaryDirectory(prefix='jt-parsers-') as temporary:
|
||||
directory = Path(temporary)
|
||||
image = Image.new('RGB', (1000, 180), 'white')
|
||||
ImageDraw.Draw(image).text((40, 50), 'PYTHON CAREER 2026', fill='black', font=ImageFont.load_default(size=48))
|
||||
image.save(directory / 'ocr.png'); image.save(directory / 'ocr.pdf', resolution=150)
|
||||
for file in [*(HERE / 'data').glob('benign.*'), directory / 'ocr.png', directory / 'ocr.pdf']:
|
||||
output = directory / (file.name + '.json')
|
||||
args = [sys.executable, '/app/parser_child.py', '--input', str(file), '--output', str(output), '--extension', file.suffix, '--cpu-seconds', '10', '--memory-bytes', str(512 * 1024 * 1024)]
|
||||
result = subprocess.run(args, capture_output=True, text=True, timeout=20)
|
||||
assert result.returncode == 0, (file.name, result.stdout, result.stderr, output.read_text() if output.exists() else '')
|
||||
parsed = json.loads(output.read_text())
|
||||
assert parsed['ok'] and parsed['text']
|
||||
if file.name.startswith('ocr'):
|
||||
assert all(token in parsed['text'] for token in ['PYTHON','CAREER','2026'])
|
||||
assert parsed['ocr_used'] is True
|
||||
else:
|
||||
assert all(token in parsed['text'] for token in ['Åse','Østby','Python','C#'])
|
||||
results.append({'file':file.name,'sha256':hashlib.sha256(file.read_bytes()).hexdigest(),'text':parsed['text'],'ocrUsed':parsed['ocr_used'],'childExitCode':result.returncode})
|
||||
|
||||
env = os.environ.copy()
|
||||
env.update(AI_SERVICE_SKIP_MODEL_LOAD='0', AI_SERVICE_EAGER_MODEL_LOAD='0', AI_SERVICE_TOKEN='p9-local-qualification-only')
|
||||
code = "import sys;sys.path.insert(0,'/app');import app,uvicorn;app.MODEL_NAME='/fixture';uvicorn.run(app.app,host='127.0.0.1',port=18081,log_level='warning')"
|
||||
with Path('/evidence/server.log').open('w') as log:
|
||||
server = subprocess.Popen([sys.executable,'-c',code],env=env,stdout=log,stderr=subprocess.STDOUT)
|
||||
try:
|
||||
deadline=time.monotonic()+30
|
||||
while True:
|
||||
try:
|
||||
with request.urlopen('http://127.0.0.1:18081/health',timeout=1) as response:health=json.load(response)
|
||||
break
|
||||
except (OSError,error.URLError):
|
||||
assert server.poll() is None,'Server exited before readiness'
|
||||
assert time.monotonic()<deadline,'Server readiness deadline exceeded'
|
||||
time.sleep(.1)
|
||||
assert health['model_loaded'] is False
|
||||
body=json.dumps({'text':'Python engineers build reliable accessible career software.','max_length':24,'min_length':8}).encode()
|
||||
try:request.urlopen(request.Request('http://127.0.0.1:18081/summarize',data=body,headers={'Content-Type':'application/json'}),timeout=10)
|
||||
except error.HTTPError as failure:assert failure.code==401
|
||||
else:raise AssertionError('Missing service token accepted')
|
||||
headers={'Content-Type':'application/json','X-Ai-Service-Token':'p9-local-qualification-only'}
|
||||
replies=[]
|
||||
for _ in range(2):
|
||||
with request.urlopen(request.Request('http://127.0.0.1:18081/summarize',data=body,headers=headers),timeout=20) as response:replies.append(json.load(response))
|
||||
assert replies[0]['cached'] is False and replies[1]['cached'] is True
|
||||
assert replies[0]['summary']==replies[1]['summary']
|
||||
boundary='JtSyntheticQualification'
|
||||
upload=(f'--{boundary}\r\nContent-Disposition: form-data; name="file"; filename="synthetic.txt"\r\nContent-Type: text/plain\r\n\r\n'.encode()+(HERE/'data/benign.txt').read_bytes()+f'\r\n--{boundary}--\r\n'.encode())
|
||||
with request.urlopen(request.Request('http://127.0.0.1:18081/extract-text',data=upload,headers={'Content-Type':'multipart/form-data; boundary='+boundary,'X-Ai-Service-Token':'p9-local-qualification-only'}),timeout=20) as response:extracted=json.load(response)
|
||||
assert 'Åse' in extracted['text'] and 'C#' in extracted['text']
|
||||
results.append({'case':'real-http-startup','health200':True,'unauthenticated401':True,'realSummary200':True,'repeatCache':True,'actualUploadExtraction200':True})
|
||||
finally:
|
||||
server.terminate()
|
||||
try:server.wait(timeout=5)
|
||||
except subprocess.TimeoutExpired:server.kill();server.wait(timeout=5)
|
||||
assert server.poll() is not None
|
||||
|
||||
data=Path('/usr/share/tesseract-ocr/5/tessdata/eng.traineddata')
|
||||
record={'status':'PASS','cases':results,'tesseractVersion':subprocess.check_output(['tesseract','--version'],text=True).splitlines()[0],'englishDataSha256':hashlib.sha256(data.read_bytes()).hexdigest(),'englishDataBytes':data.stat().st_size,'offline':True,'serverStopped':True,'limits':'Synthetic TXT/DOCX/PDF/image/OCR and small BART CPU HTTP contracts; no production documents, full-size model, GPU, external provider or semantic quality.'}
|
||||
print(json.dumps(record),flush=True)
|
||||
@@ -27,12 +27,20 @@ started = time.monotonic()
|
||||
app.MODEL_NAME = str(fixture)
|
||||
assert app._ensure_runtime_loaded(), app.MODEL_LOAD_ERROR
|
||||
assert app.model.__class__.__name__ == 'BartForConditionalGeneration'
|
||||
assert app.model.training is False
|
||||
assert str(app.device) == 'cpu' and not app.GPU_AVAILABLE
|
||||
text = 'Åse Østby builds accessible Python and C# applications for reliable Norwegian career workflows.'
|
||||
encoded = app.tokenizer(text, return_tensors='pt')
|
||||
assert app.tokenizer.decode(encoded.input_ids[0], skip_special_tokens=True) == text
|
||||
summary = app._model_summarize(text, 24, 8)
|
||||
assert isinstance(summary, str) and summary
|
||||
long_input = app.tokenizer(text * 400, return_tensors='pt', truncation=True, max_length=1024)
|
||||
assert long_input.input_ids.shape == (1, 1024)
|
||||
assert long_input.input_ids.dtype == torch.int64
|
||||
with torch.no_grad():
|
||||
logits = app.model(**long_input, decoder_input_ids=torch.tensor([[2, 0, 10]])).logits
|
||||
assert torch.isfinite(logits).all()
|
||||
assert app._model_summarize(text * 400, 24, 8)
|
||||
client = TestClient(app.app)
|
||||
assert client.get('/health').json()['model_loaded'] is True
|
||||
assert client.post('/summarize', json={'text': text}).status_code == 401
|
||||
@@ -46,4 +54,4 @@ assert first.json()['summary'] == second.json()['summary']
|
||||
verify_fixture(fixture, manifests[kind])
|
||||
elapsed = time.monotonic() - started
|
||||
assert elapsed < 60
|
||||
print(json.dumps({'status': 'PASS', 'kind': kind, 'scope': 'Real synthetic BART/tokenizer/native CPU generation plus sidecar summary/auth/cache contract; no full DistilBART or semantic-quality claim.', 'modelClass': app.model.__class__.__name__, 'device': str(app.device), 'cudaAvailable': torch.cuda.is_available(), 'seconds': elapsed, 'maxRssKiB': resource.getrusage(resource.RUSAGE_SELF).ru_maxrss, 'versions': {name: importlib.metadata.version(name) for name in ['torch','transformers','filelock','huggingface-hub','tokenizers','safetensors']}, 'summary': summary, 'cacheRepeatedRead': True, 'fixtureUnchanged': True}), flush=True)
|
||||
print(json.dumps({'status': 'PASS', 'kind': kind, 'scope': 'Real synthetic BART/tokenizer/native CPU generation plus sidecar summary/auth/cache contract; no full DistilBART or semantic-quality claim.', 'modelClass': app.model.__class__.__name__, 'device': str(app.device), 'cudaAvailable': torch.cuda.is_available(), 'seconds': elapsed, 'maxRssKiB': resource.getrusage(resource.RUSAGE_SELF).ru_maxrss, 'versions': {name: importlib.metadata.version(name) for name in ['torch','transformers','filelock','huggingface-hub','tokenizers','safetensors']}, 'summary': summary, 'bounded1024Tokens': True, 'finiteLogits': True, 'cacheRepeatedRead': True, 'fixtureUnchanged': True}), flush=True)
|
||||
|
||||
@@ -0,0 +1,51 @@
|
||||
"""Run one immutable local qualification lane; retain each attempt and teardown outcome."""
|
||||
from pathlib import Path
|
||||
import datetime
|
||||
import json
|
||||
import subprocess
|
||||
import sys
|
||||
import time
|
||||
import uuid
|
||||
|
||||
ROOT=Path(__file__).resolve().parents[5]
|
||||
HERE=Path(__file__).resolve().parent
|
||||
lane=sys.argv[1];attempt=sys.argv[2] if len(sys.argv)>2 else lane
|
||||
assert Path(attempt).name==attempt and attempt not in ['.','..']
|
||||
assert lane in ['safetensors','weights-only','cache','parsers','inventory','sidecar']
|
||||
out=ROOT/'.artifacts/p9-sec-02/qualified'/attempt
|
||||
assert not out.exists(),'Preserve earlier lane evidence.'
|
||||
out.mkdir(parents=True)
|
||||
runtime=json.loads((HERE/'RUNTIME.json').read_text())
|
||||
image=runtime['qualificationImageId']
|
||||
name='jt-sec02-'+lane+'-'+uuid.uuid4().hex[:8]
|
||||
args=['docker','run','--rm','--name',name,'--label','jobtracker.qualification=p9-sec02','--entrypoint','python','--user','65534:65534','--network','none','--read-only','--cap-drop','ALL','--security-opt','no-new-privileges','--pids-limit','128','--cpus','2','--memory','2g','--memory-swap','2g','--tmpfs','/tmp:rw,nosuid,nodev,size=384m,mode=1777']
|
||||
for value in ['HF_HUB_OFFLINE=1','TRANSFORMERS_OFFLINE=1','HF_HUB_DISABLE_TELEMETRY=1','HF_HOME=/tmp/hf-home','OMP_NUM_THREADS=1','MKL_NUM_THREADS=1','OLLAMA_BASE_URL=http://127.0.0.1:11434','OLLAMA_MODEL=','EXTERNAL_AI_ENABLED=0']:
|
||||
args+=['-e',value]
|
||||
args+=['--mount',f'type=bind,src={HERE},dst=/qualification,readonly','--mount',f'type=bind,src={out},dst=/evidence']
|
||||
if lane in ['safetensors','weights-only','cache','parsers']:
|
||||
fixture='artifact-bin' if lane=='weights-only' else 'artifact'
|
||||
args+=['--mount',f'type=bind,src={ROOT/".artifacts/p9-sec-02"/fixture},dst=/fixture,readonly']
|
||||
if lane=='sidecar':args+=['-e','AI_SERVICE_SKIP_MODEL_LOAD=1']
|
||||
args+=[image]
|
||||
if lane in ['safetensors','weights-only']:args+=['/qualification/probe.py',lane,'/fixture']
|
||||
elif lane=='cache':args+=['/qualification/cache_probe.py','/fixture']
|
||||
elif lane=='parsers':args+=['/qualification/parser_probe.py']
|
||||
elif lane=='inventory':args+=['/qualification/runtime_inventory.py']
|
||||
else:args+=['-m','pytest','-q','-o','cache_dir=/tmp/pytest-cache','/app/tests','--junitxml=/evidence/sidecar.xml']
|
||||
started=datetime.datetime.now(datetime.timezone.utc).isoformat()
|
||||
with (out/'process.log').open('w',encoding='utf-8') as log:
|
||||
try:code=subprocess.run(['rtk','proxy',*args],cwd=ROOT,stdout=log,stderr=subprocess.STDOUT,timeout=180).returncode
|
||||
except subprocess.TimeoutExpired:
|
||||
code=124
|
||||
check=subprocess.run(['rtk','proxy','docker','inspect','--format','{{index .Config.Labels "jobtracker.qualification"}}',name],capture_output=True,text=True)
|
||||
if check.returncode==0 and check.stdout.strip()=='p9-sec02':subprocess.run(['rtk','proxy','docker','kill',name],capture_output=True)
|
||||
deadline=time.monotonic()+5
|
||||
while True:
|
||||
absent=subprocess.run(['rtk','proxy','docker','inspect',name],capture_output=True).returncode!=0
|
||||
if absent or time.monotonic()>=deadline:break
|
||||
time.sleep(.1)
|
||||
record={'lane':lane,'attempt':attempt,'startedUtc':started,'finishedUtc':datetime.datetime.now(datetime.timezone.utc).isoformat(),'exitCode':code,'command':args,'localImageId':image,'runtimeImageId':runtime['runtimeImageId'],'containerAbsent':absent,'network':'none','readOnly':True,'user':'65534:65534','memoryLimitBytes':2147483648,'cpuLimit':2,'pidsLimit':128,'wallClockDeadlineSeconds':180,'scope':'Actual locally built source image plus exact test-only extras; no app source mount, production cache, external network, registry push or deployment.'}
|
||||
(out/'process.json').write_text(json.dumps(record,indent=2)+'\n')
|
||||
print(json.dumps(record))
|
||||
print((out/'process.log').read_text(encoding='utf-8',errors='replace')[-2500:].encode('ascii','replace').decode())
|
||||
raise SystemExit(code if absent else 1)
|
||||
@@ -0,0 +1,24 @@
|
||||
"""Fingerprint actual supported runtime and verify every application lock pin."""
|
||||
from pathlib import Path
|
||||
import hashlib
|
||||
import importlib.metadata
|
||||
import json
|
||||
import platform
|
||||
import re
|
||||
import subprocess
|
||||
import sys
|
||||
|
||||
lock=Path('/app/requirements-linux.lock')
|
||||
pins=dict(re.findall(r'^([a-zA-Z0-9_.-]+)==([^\s;]+)',lock.read_text(),re.M))
|
||||
installed={re.sub(r'[-_.]+','-',item.metadata['Name']).lower():item.version for item in importlib.metadata.distributions()}
|
||||
assert len(pins)==55
|
||||
assert all(installed[name]==version for name,version in pins.items())
|
||||
assert not list(Path('/app').glob('.venv*')), 'Development environments leaked into built application image'
|
||||
check=subprocess.run([sys.executable,'-m','pip','check'],capture_output=True,text=True)
|
||||
assert check.returncode==0,check.stdout+check.stderr
|
||||
import torch
|
||||
import transformers
|
||||
data=Path('/usr/share/tesseract-ocr/5/tessdata/eng.traineddata')
|
||||
record={'status':'PASS','python':sys.version,'platform':platform.platform(),'libc':platform.libc_ver(),'applicationLockSha256':hashlib.sha256(lock.read_bytes()).hexdigest(),'applicationPins':pins,'installedDistributions':installed,'extrasOutsideApplicationLock':{name:version for name,version in installed.items() if name not in pins},'pipCheck':check.stdout.strip(),'noDevelopmentEnvironmentsInImage':True,'torchVersion':torch.__version__,'torchBuildCuda':torch.version.cuda,'cudaAvailable':torch.cuda.is_available(),'torchBuild':torch.__config__.show(),'tesseractVersion':subprocess.check_output(['tesseract','--version'],text=True).splitlines()[0],'englishOcrData':{'path':str(data),'bytes':data.stat().st_size,'sha256':hashlib.sha256(data.read_bytes()).hexdigest()},'nativePackages':subprocess.check_output(['dpkg-query','-W'],text=True),'scope':'Actual locally built source Dockerfile and exact55 locked application pins; test-only packages, if any, and bootstrap tools remain explicitly listed separately.'}
|
||||
record['applicationSources']={name:hashlib.sha256((Path('/app')/name).read_bytes()).hexdigest() for name in ['app.py','parser_child.py','requirements.txt','requirements-linux.lock','tests/test_app.py']}
|
||||
print(json.dumps(record),flush=True)
|
||||
@@ -0,0 +1,31 @@
|
||||
"""Supplemental Windows lock compatibility in a new local test directory."""
|
||||
from pathlib import Path
|
||||
import json
|
||||
import subprocess
|
||||
import sys
|
||||
import tempfile
|
||||
|
||||
target = str(Path(sys.argv[1]).resolve())
|
||||
sys.path.insert(0, target)
|
||||
import filelock
|
||||
assert filelock.__version__ == '4.2.1'
|
||||
assert Path(filelock.__file__).resolve().is_relative_to(Path(target))
|
||||
child = '''import sys
|
||||
sys.path.insert(0,sys.argv[1])
|
||||
from filelock import FileLock,SoftFileLock,Timeout
|
||||
cls=FileLock if sys.argv[2]=='native' else SoftFileLock
|
||||
try:
|
||||
with cls(sys.argv[3],timeout=0.2): print('acquired')
|
||||
except Timeout: print('timed-out')
|
||||
'''
|
||||
cases = []
|
||||
with tempfile.TemporaryDirectory(prefix='jt-sec02-windows-lock-') as temporary:
|
||||
for kind, cls in [('native', filelock.FileLock), ('soft', filelock.SoftFileLock)]:
|
||||
command=[sys.executable,'-c',child,target,kind,str(Path(temporary)/(kind+'.lock'))]
|
||||
with cls(command[-1],timeout=1):
|
||||
result=subprocess.run(command,capture_output=True,text=True,timeout=5,check=True)
|
||||
assert result.stdout.strip()=='timed-out',result.stdout
|
||||
result=subprocess.run(command,capture_output=True,text=True,timeout=5,check=True)
|
||||
assert result.stdout.strip()=='acquired',result.stdout
|
||||
cases.append({'case':kind,'finiteContentionTimeout':True,'acquiredAfterRelease':True})
|
||||
print(json.dumps({'status':'PASS','platform':sys.platform,'filelock':filelock.__version__,'cases':cases,'limits':'Two fresh same-version Windows lock participants. No Windows shared-cache ACL/symlink security or cross-version migration claim.'}))
|
||||
@@ -0,0 +1,812 @@
|
||||
{
|
||||
"schemaVersion": 1,
|
||||
"observedUtc": "2026-10-25T07:09:16.503468+00:00",
|
||||
"status": "PASS",
|
||||
"inputs": {
|
||||
"docs/redesign/phase-9/p9-sec-02/model/cache_probe.py": "7376c4cffa12b411d5ee20df640bd2ad9c8891ae28b8fd48bfdbf23702f61bb6",
|
||||
"docs/redesign/phase-9/p9-sec-02/model/parser_probe.py": "3c3b6818316d4f4284765550648fbade16644ae2276454d205c26c3fe12c01d8",
|
||||
"docs/redesign/phase-9/p9-sec-02/model/probe.py": "318241dd5b11269a43c71ca221f0209dbe6828239bb8c6549b22323086bda05d",
|
||||
"docs/redesign/phase-9/p9-sec-02/model/run.py": "b85c543e4020fbbe118ab52746f1290babaee2a640ead3277b16fd4bed6b9f29",
|
||||
"docs/redesign/phase-9/p9-sec-02/model/runtime_inventory.py": "254feb648f568dbbc0faec091cc6a0e49ad8d09ac4840e888603ef26c42a3d6c",
|
||||
"docs/redesign/phase-9/p9-sec-02/model/test_verify.py": "ffac7d2306e9947eed0313e070b1fceccd7b2c1041581e5db1bb97671777c288",
|
||||
"docs/redesign/phase-9/p9-sec-02/model/verify.py": "168a7e349d3e8a02427d80179561a21e278288e18e38ed804ecc816c6197d09f",
|
||||
"docs/redesign/phase-9/p9-sec-02/model/windows_lock_probe.py": "0db37df4bf58daa8953b1e4d8c5f28e605a56a11c4f3930c58a3177d58abe9fa",
|
||||
"docs/redesign/phase-9/p9-sec-02/model/ARTIFACTS.json": "5c606eb95218946242a4867d442450cd1014549220b78120ac37e7aa3477c023",
|
||||
"docs/redesign/phase-9/p9-sec-02/model/RUNTIME.json": "e4321bb4f0bc1bb898b4c427540780f9904464357788d19bfc4433d233190224",
|
||||
"tools/summarizer/app.py": "aab24c7f64868fcb93a6133aa7b2087b23f98469e89e4c84fa040a022b0a8dfc",
|
||||
"tools/summarizer/parser_child.py": "0074a05e9a0d511e26a329a057f98568cdc1723b2cc37168e0b59975b5424451",
|
||||
"tools/summarizer/requirements-linux.lock": "3a3afc529f0076a1b5d67082c9269c22c12f52c47ecf95ce0c76c37b39d8297a",
|
||||
"tools/summarizer/requirements-dev-linux.lock": "a234316d8612193551a2c91fb19ae0924f5643b9e52edb907ab99dd55b14cdb9",
|
||||
"tools/summarizer/Dockerfile": "d0b8777e81a74ed7099fe1d93f608b6601da39efc43b50ec0b3b058613207443",
|
||||
"tools/summarizer/.dockerignore": "b1074aebf95e5d5cb6d7c26617ef49945dca31bc756bbc78ee0e3b15c96e3152"
|
||||
},
|
||||
"results": {
|
||||
"sidecar": {
|
||||
"status": "PASS",
|
||||
"passed": 59,
|
||||
"process": {
|
||||
"lane": "sidecar",
|
||||
"attempt": "qualification-patched-sidecar",
|
||||
"startedUtc": "2026-10-25T07:08:32.877557+00:00",
|
||||
"finishedUtc": "2026-10-25T07:08:45.365675+00:00",
|
||||
"exitCode": 0,
|
||||
"command": [
|
||||
"docker",
|
||||
"run",
|
||||
"--rm",
|
||||
"--name",
|
||||
"jt-sec02-sidecar-b98c7d59",
|
||||
"--label",
|
||||
"jobtracker.qualification=p9-sec02",
|
||||
"--entrypoint",
|
||||
"python",
|
||||
"--user",
|
||||
"65534:65534",
|
||||
"--network",
|
||||
"none",
|
||||
"--read-only",
|
||||
"--cap-drop",
|
||||
"ALL",
|
||||
"--security-opt",
|
||||
"no-new-privileges",
|
||||
"--pids-limit",
|
||||
"128",
|
||||
"--cpus",
|
||||
"2",
|
||||
"--memory",
|
||||
"2g",
|
||||
"--memory-swap",
|
||||
"2g",
|
||||
"--tmpfs",
|
||||
"/tmp:rw,nosuid,nodev,size=384m,mode=1777",
|
||||
"-e",
|
||||
"HF_HUB_OFFLINE=1",
|
||||
"-e",
|
||||
"TRANSFORMERS_OFFLINE=1",
|
||||
"-e",
|
||||
"HF_HUB_DISABLE_TELEMETRY=1",
|
||||
"-e",
|
||||
"HF_HOME=/tmp/hf-home",
|
||||
"-e",
|
||||
"OMP_NUM_THREADS=1",
|
||||
"-e",
|
||||
"MKL_NUM_THREADS=1",
|
||||
"-e",
|
||||
"OLLAMA_BASE_URL=http://127.0.0.1:11434",
|
||||
"-e",
|
||||
"OLLAMA_MODEL=",
|
||||
"-e",
|
||||
"EXTERNAL_AI_ENABLED=0",
|
||||
"--mount",
|
||||
"type=bind,src=E:\\Storage\\Projects\\Active\\Job tracker\\docs\\redesign\\phase-9\\p9-sec-02\\model,dst=/qualification,readonly",
|
||||
"--mount",
|
||||
"type=bind,src=E:\\Storage\\Projects\\Active\\Job tracker\\.artifacts\\p9-sec-02\\qualified\\qualification-patched-sidecar,dst=/evidence",
|
||||
"-e",
|
||||
"AI_SERVICE_SKIP_MODEL_LOAD=1",
|
||||
"sha256:2fe77e47a6c5ecea66764dbd6264049724f24849141e16af5491c2de34af53c1",
|
||||
"-m",
|
||||
"pytest",
|
||||
"-q",
|
||||
"-o",
|
||||
"cache_dir=/tmp/pytest-cache",
|
||||
"/app/tests",
|
||||
"--junitxml=/evidence/sidecar.xml"
|
||||
],
|
||||
"localImageId": "sha256:2fe77e47a6c5ecea66764dbd6264049724f24849141e16af5491c2de34af53c1",
|
||||
"runtimeImageId": "sha256:4a04ca68fa40b3ec61cb61187b339a4d2895b375b962999e974d75556b5b1331",
|
||||
"containerAbsent": true,
|
||||
"network": "none",
|
||||
"readOnly": true,
|
||||
"user": "65534:65534",
|
||||
"memoryLimitBytes": 2147483648,
|
||||
"cpuLimit": 2,
|
||||
"pidsLimit": 128,
|
||||
"wallClockDeadlineSeconds": 180,
|
||||
"scope": "Actual locally built source image plus exact test-only extras; no app source mount, production cache, external network, registry push or deployment."
|
||||
},
|
||||
"reportSha256": "da3b247b2189fa5549cee48c335ffb51b4662da1cf038f5aad0a60e4fa9b582f"
|
||||
},
|
||||
"safetensors": {
|
||||
"status": "PASS",
|
||||
"record": {
|
||||
"status": "PASS",
|
||||
"kind": "safetensors",
|
||||
"scope": "Real synthetic BART/tokenizer/native CPU generation plus sidecar summary/auth/cache contract; no full DistilBART or semantic-quality claim.",
|
||||
"modelClass": "BartForConditionalGeneration",
|
||||
"device": "cpu",
|
||||
"cudaAvailable": false,
|
||||
"seconds": 0.9420173299999988,
|
||||
"maxRssKiB": 410096,
|
||||
"versions": {
|
||||
"torch": "2.13.0+cpu",
|
||||
"transformers": "5.10.0",
|
||||
"filelock": "4.2.1",
|
||||
"huggingface-hub": "1.33.0",
|
||||
"tokenizers": "0.22.2",
|
||||
"safetensors": "0.8.0"
|
||||
},
|
||||
"summary": "Boulevard ski ski ski Joined Joined Joined titles titlesataata told told told beam beam beam told told uncontroll uncontroll equity",
|
||||
"bounded1024Tokens": true,
|
||||
"finiteLogits": true,
|
||||
"cacheRepeatedRead": true,
|
||||
"fixtureUnchanged": true
|
||||
},
|
||||
"process": {
|
||||
"lane": "safetensors",
|
||||
"attempt": "qualification-patched-safetensors",
|
||||
"startedUtc": "2026-10-25T07:08:45.529394+00:00",
|
||||
"finishedUtc": "2026-10-25T07:08:51.395049+00:00",
|
||||
"exitCode": 0,
|
||||
"command": [
|
||||
"docker",
|
||||
"run",
|
||||
"--rm",
|
||||
"--name",
|
||||
"jt-sec02-safetensors-1bfd4b71",
|
||||
"--label",
|
||||
"jobtracker.qualification=p9-sec02",
|
||||
"--entrypoint",
|
||||
"python",
|
||||
"--user",
|
||||
"65534:65534",
|
||||
"--network",
|
||||
"none",
|
||||
"--read-only",
|
||||
"--cap-drop",
|
||||
"ALL",
|
||||
"--security-opt",
|
||||
"no-new-privileges",
|
||||
"--pids-limit",
|
||||
"128",
|
||||
"--cpus",
|
||||
"2",
|
||||
"--memory",
|
||||
"2g",
|
||||
"--memory-swap",
|
||||
"2g",
|
||||
"--tmpfs",
|
||||
"/tmp:rw,nosuid,nodev,size=384m,mode=1777",
|
||||
"-e",
|
||||
"HF_HUB_OFFLINE=1",
|
||||
"-e",
|
||||
"TRANSFORMERS_OFFLINE=1",
|
||||
"-e",
|
||||
"HF_HUB_DISABLE_TELEMETRY=1",
|
||||
"-e",
|
||||
"HF_HOME=/tmp/hf-home",
|
||||
"-e",
|
||||
"OMP_NUM_THREADS=1",
|
||||
"-e",
|
||||
"MKL_NUM_THREADS=1",
|
||||
"-e",
|
||||
"OLLAMA_BASE_URL=http://127.0.0.1:11434",
|
||||
"-e",
|
||||
"OLLAMA_MODEL=",
|
||||
"-e",
|
||||
"EXTERNAL_AI_ENABLED=0",
|
||||
"--mount",
|
||||
"type=bind,src=E:\\Storage\\Projects\\Active\\Job tracker\\docs\\redesign\\phase-9\\p9-sec-02\\model,dst=/qualification,readonly",
|
||||
"--mount",
|
||||
"type=bind,src=E:\\Storage\\Projects\\Active\\Job tracker\\.artifacts\\p9-sec-02\\qualified\\qualification-patched-safetensors,dst=/evidence",
|
||||
"--mount",
|
||||
"type=bind,src=E:\\Storage\\Projects\\Active\\Job tracker\\.artifacts\\p9-sec-02\\artifact,dst=/fixture,readonly",
|
||||
"sha256:2fe77e47a6c5ecea66764dbd6264049724f24849141e16af5491c2de34af53c1",
|
||||
"/qualification/probe.py",
|
||||
"safetensors",
|
||||
"/fixture"
|
||||
],
|
||||
"localImageId": "sha256:2fe77e47a6c5ecea66764dbd6264049724f24849141e16af5491c2de34af53c1",
|
||||
"runtimeImageId": "sha256:4a04ca68fa40b3ec61cb61187b339a4d2895b375b962999e974d75556b5b1331",
|
||||
"containerAbsent": true,
|
||||
"network": "none",
|
||||
"readOnly": true,
|
||||
"user": "65534:65534",
|
||||
"memoryLimitBytes": 2147483648,
|
||||
"cpuLimit": 2,
|
||||
"pidsLimit": 128,
|
||||
"wallClockDeadlineSeconds": 180,
|
||||
"scope": "Actual locally built source image plus exact test-only extras; no app source mount, production cache, external network, registry push or deployment."
|
||||
}
|
||||
},
|
||||
"weights-only": {
|
||||
"status": "PASS",
|
||||
"record": {
|
||||
"status": "PASS",
|
||||
"kind": "weights-only",
|
||||
"scope": "Real synthetic BART/tokenizer/native CPU generation plus sidecar summary/auth/cache contract; no full DistilBART or semantic-quality claim.",
|
||||
"modelClass": "BartForConditionalGeneration",
|
||||
"device": "cpu",
|
||||
"cudaAvailable": false,
|
||||
"seconds": 0.8173885160000509,
|
||||
"maxRssKiB": 411812,
|
||||
"versions": {
|
||||
"torch": "2.13.0+cpu",
|
||||
"transformers": "5.10.0",
|
||||
"filelock": "4.2.1",
|
||||
"huggingface-hub": "1.33.0",
|
||||
"tokenizers": "0.22.2",
|
||||
"safetensors": "0.8.0"
|
||||
},
|
||||
"summary": "Boulevard ski ski ski Joined Joined Joined titles titlesataata told told told beam beam beam told told uncontroll uncontroll equity",
|
||||
"bounded1024Tokens": true,
|
||||
"finiteLogits": true,
|
||||
"cacheRepeatedRead": true,
|
||||
"fixtureUnchanged": true
|
||||
},
|
||||
"process": {
|
||||
"lane": "weights-only",
|
||||
"attempt": "qualification-patched-weights-only",
|
||||
"startedUtc": "2026-10-25T07:08:51.559719+00:00",
|
||||
"finishedUtc": "2026-10-25T07:08:57.438362+00:00",
|
||||
"exitCode": 0,
|
||||
"command": [
|
||||
"docker",
|
||||
"run",
|
||||
"--rm",
|
||||
"--name",
|
||||
"jt-sec02-weights-only-5aec5f06",
|
||||
"--label",
|
||||
"jobtracker.qualification=p9-sec02",
|
||||
"--entrypoint",
|
||||
"python",
|
||||
"--user",
|
||||
"65534:65534",
|
||||
"--network",
|
||||
"none",
|
||||
"--read-only",
|
||||
"--cap-drop",
|
||||
"ALL",
|
||||
"--security-opt",
|
||||
"no-new-privileges",
|
||||
"--pids-limit",
|
||||
"128",
|
||||
"--cpus",
|
||||
"2",
|
||||
"--memory",
|
||||
"2g",
|
||||
"--memory-swap",
|
||||
"2g",
|
||||
"--tmpfs",
|
||||
"/tmp:rw,nosuid,nodev,size=384m,mode=1777",
|
||||
"-e",
|
||||
"HF_HUB_OFFLINE=1",
|
||||
"-e",
|
||||
"TRANSFORMERS_OFFLINE=1",
|
||||
"-e",
|
||||
"HF_HUB_DISABLE_TELEMETRY=1",
|
||||
"-e",
|
||||
"HF_HOME=/tmp/hf-home",
|
||||
"-e",
|
||||
"OMP_NUM_THREADS=1",
|
||||
"-e",
|
||||
"MKL_NUM_THREADS=1",
|
||||
"-e",
|
||||
"OLLAMA_BASE_URL=http://127.0.0.1:11434",
|
||||
"-e",
|
||||
"OLLAMA_MODEL=",
|
||||
"-e",
|
||||
"EXTERNAL_AI_ENABLED=0",
|
||||
"--mount",
|
||||
"type=bind,src=E:\\Storage\\Projects\\Active\\Job tracker\\docs\\redesign\\phase-9\\p9-sec-02\\model,dst=/qualification,readonly",
|
||||
"--mount",
|
||||
"type=bind,src=E:\\Storage\\Projects\\Active\\Job tracker\\.artifacts\\p9-sec-02\\qualified\\qualification-patched-weights-only,dst=/evidence",
|
||||
"--mount",
|
||||
"type=bind,src=E:\\Storage\\Projects\\Active\\Job tracker\\.artifacts\\p9-sec-02\\artifact-bin,dst=/fixture,readonly",
|
||||
"sha256:2fe77e47a6c5ecea66764dbd6264049724f24849141e16af5491c2de34af53c1",
|
||||
"/qualification/probe.py",
|
||||
"weights-only",
|
||||
"/fixture"
|
||||
],
|
||||
"localImageId": "sha256:2fe77e47a6c5ecea66764dbd6264049724f24849141e16af5491c2de34af53c1",
|
||||
"runtimeImageId": "sha256:4a04ca68fa40b3ec61cb61187b339a4d2895b375b962999e974d75556b5b1331",
|
||||
"containerAbsent": true,
|
||||
"network": "none",
|
||||
"readOnly": true,
|
||||
"user": "65534:65534",
|
||||
"memoryLimitBytes": 2147483648,
|
||||
"cpuLimit": 2,
|
||||
"pidsLimit": 128,
|
||||
"wallClockDeadlineSeconds": 180,
|
||||
"scope": "Actual locally built source image plus exact test-only extras; no app source mount, production cache, external network, registry push or deployment."
|
||||
}
|
||||
},
|
||||
"cache": {
|
||||
"status": "PASS",
|
||||
"record": {
|
||||
"status": "PASS",
|
||||
"filelock": "4.2.1",
|
||||
"hub": "1.33.0",
|
||||
"cases": [
|
||||
{
|
||||
"case": "missing",
|
||||
"rejectedBeforeLoad": true
|
||||
},
|
||||
{
|
||||
"case": "corrupt-weights",
|
||||
"rejectedBeforeLoad": true
|
||||
},
|
||||
{
|
||||
"case": "corrupt-config",
|
||||
"rejectedBeforeLoad": true
|
||||
},
|
||||
{
|
||||
"case": "linked",
|
||||
"rejectedBeforeLoad": true
|
||||
},
|
||||
{
|
||||
"case": "extra-code",
|
||||
"rejectedBeforeLoad": true
|
||||
},
|
||||
{
|
||||
"case": "native-cross-process",
|
||||
"finiteContentionTimeout": true,
|
||||
"acquiredAfterRelease": true
|
||||
},
|
||||
{
|
||||
"case": "soft-cross-process",
|
||||
"finiteContentionTimeout": true,
|
||||
"acquiredAfterRelease": true
|
||||
},
|
||||
{
|
||||
"case": "hub-cross-process",
|
||||
"finiteContentionTimeout": true,
|
||||
"acquiredAfterRelease": true
|
||||
},
|
||||
{
|
||||
"case": "missing-offline-model",
|
||||
"availability503": true,
|
||||
"noPartialLoadedState": true
|
||||
}
|
||||
],
|
||||
"freshPrivateCache": true,
|
||||
"sourceUnchanged": true,
|
||||
"limits": "Linux native/soft/Hub locking in one library generation. No shared-cache migration, Windows fallback, full-model cancellation, GPU or live cache claim."
|
||||
},
|
||||
"process": {
|
||||
"lane": "cache",
|
||||
"attempt": "qualification-patched-cache",
|
||||
"startedUtc": "2026-10-25T07:08:57.600935+00:00",
|
||||
"finishedUtc": "2026-10-25T07:09:04.779815+00:00",
|
||||
"exitCode": 0,
|
||||
"command": [
|
||||
"docker",
|
||||
"run",
|
||||
"--rm",
|
||||
"--name",
|
||||
"jt-sec02-cache-7658ca0a",
|
||||
"--label",
|
||||
"jobtracker.qualification=p9-sec02",
|
||||
"--entrypoint",
|
||||
"python",
|
||||
"--user",
|
||||
"65534:65534",
|
||||
"--network",
|
||||
"none",
|
||||
"--read-only",
|
||||
"--cap-drop",
|
||||
"ALL",
|
||||
"--security-opt",
|
||||
"no-new-privileges",
|
||||
"--pids-limit",
|
||||
"128",
|
||||
"--cpus",
|
||||
"2",
|
||||
"--memory",
|
||||
"2g",
|
||||
"--memory-swap",
|
||||
"2g",
|
||||
"--tmpfs",
|
||||
"/tmp:rw,nosuid,nodev,size=384m,mode=1777",
|
||||
"-e",
|
||||
"HF_HUB_OFFLINE=1",
|
||||
"-e",
|
||||
"TRANSFORMERS_OFFLINE=1",
|
||||
"-e",
|
||||
"HF_HUB_DISABLE_TELEMETRY=1",
|
||||
"-e",
|
||||
"HF_HOME=/tmp/hf-home",
|
||||
"-e",
|
||||
"OMP_NUM_THREADS=1",
|
||||
"-e",
|
||||
"MKL_NUM_THREADS=1",
|
||||
"-e",
|
||||
"OLLAMA_BASE_URL=http://127.0.0.1:11434",
|
||||
"-e",
|
||||
"OLLAMA_MODEL=",
|
||||
"-e",
|
||||
"EXTERNAL_AI_ENABLED=0",
|
||||
"--mount",
|
||||
"type=bind,src=E:\\Storage\\Projects\\Active\\Job tracker\\docs\\redesign\\phase-9\\p9-sec-02\\model,dst=/qualification,readonly",
|
||||
"--mount",
|
||||
"type=bind,src=E:\\Storage\\Projects\\Active\\Job tracker\\.artifacts\\p9-sec-02\\qualified\\qualification-patched-cache,dst=/evidence",
|
||||
"--mount",
|
||||
"type=bind,src=E:\\Storage\\Projects\\Active\\Job tracker\\.artifacts\\p9-sec-02\\artifact,dst=/fixture,readonly",
|
||||
"sha256:2fe77e47a6c5ecea66764dbd6264049724f24849141e16af5491c2de34af53c1",
|
||||
"/qualification/cache_probe.py",
|
||||
"/fixture"
|
||||
],
|
||||
"localImageId": "sha256:2fe77e47a6c5ecea66764dbd6264049724f24849141e16af5491c2de34af53c1",
|
||||
"runtimeImageId": "sha256:4a04ca68fa40b3ec61cb61187b339a4d2895b375b962999e974d75556b5b1331",
|
||||
"containerAbsent": true,
|
||||
"network": "none",
|
||||
"readOnly": true,
|
||||
"user": "65534:65534",
|
||||
"memoryLimitBytes": 2147483648,
|
||||
"cpuLimit": 2,
|
||||
"pidsLimit": 128,
|
||||
"wallClockDeadlineSeconds": 180,
|
||||
"scope": "Actual locally built source image plus exact test-only extras; no app source mount, production cache, external network, registry push or deployment."
|
||||
}
|
||||
},
|
||||
"parsers": {
|
||||
"status": "PASS",
|
||||
"record": {
|
||||
"status": "PASS",
|
||||
"cases": [
|
||||
{
|
||||
"file": "benign.docx",
|
||||
"sha256": "d5fd1b4cecb725a6e1aea8f1f5ed938cdd62f1c582be87bf82e2351c6962102c",
|
||||
"text": "Ada Lovelace - \u00c5se \u00d8stby \u00e6rlig erfaring. Backend APIs and reliable data pipelines with Python and C#; platform engineering and testing.",
|
||||
"ocrUsed": false,
|
||||
"childExitCode": 0
|
||||
},
|
||||
{
|
||||
"file": "benign.pdf",
|
||||
"sha256": "227b6b2777eae802b357104771e142539ecec9bde0214386e12dd5f3b1c27f03",
|
||||
"text": "Ada Lovelace - \u00c5se \u00d8stby \u00e6rlig erfaring. Backend APIs and reliable data pipelines with Python and C#; platform engineering and testing.",
|
||||
"ocrUsed": false,
|
||||
"childExitCode": 0
|
||||
},
|
||||
{
|
||||
"file": "benign.txt",
|
||||
"sha256": "0b36e56510902f2c87b8ff96a013216bede136f0d7961829d00738f5e4f78b03",
|
||||
"text": "Ada Lovelace - \u00c5se \u00d8stby \u00e6rlig erfaring. Backend APIs and reliable data pipelines with Python and C#; platform engineering and testing.",
|
||||
"ocrUsed": false,
|
||||
"childExitCode": 0
|
||||
},
|
||||
{
|
||||
"file": "ocr.png",
|
||||
"sha256": "646cceabe868e86f125386e331c3acc86283d765fc376a820cc7d3229012d195",
|
||||
"text": "PYTHON CAREER 2026",
|
||||
"ocrUsed": true,
|
||||
"childExitCode": 0
|
||||
},
|
||||
{
|
||||
"file": "ocr.pdf",
|
||||
"sha256": "42daa4579a8f5879255fb46468c58179d797f18045404db6c6a712d1ca60bd93",
|
||||
"text": "PYTHON CAREER 2026",
|
||||
"ocrUsed": true,
|
||||
"childExitCode": 0
|
||||
},
|
||||
{
|
||||
"case": "real-http-startup",
|
||||
"health200": true,
|
||||
"unauthenticated401": true,
|
||||
"realSummary200": true,
|
||||
"repeatCache": true,
|
||||
"actualUploadExtraction200": true
|
||||
}
|
||||
],
|
||||
"tesseractVersion": "tesseract 5.3.0",
|
||||
"englishDataSha256": "7d4322bd2a7749724879683fc3912cb542f19906c83bcc1a52132556427170b2",
|
||||
"englishDataBytes": 4113088,
|
||||
"offline": true,
|
||||
"serverStopped": true,
|
||||
"limits": "Synthetic TXT/DOCX/PDF/image/OCR and small BART CPU HTTP contracts; no production documents, full-size model, GPU, external provider or semantic quality."
|
||||
},
|
||||
"process": {
|
||||
"lane": "parsers",
|
||||
"attempt": "qualification-patched-parsers",
|
||||
"startedUtc": "2026-10-25T07:09:04.949270+00:00",
|
||||
"finishedUtc": "2026-10-25T07:09:12.511914+00:00",
|
||||
"exitCode": 0,
|
||||
"command": [
|
||||
"docker",
|
||||
"run",
|
||||
"--rm",
|
||||
"--name",
|
||||
"jt-sec02-parsers-09e2d468",
|
||||
"--label",
|
||||
"jobtracker.qualification=p9-sec02",
|
||||
"--entrypoint",
|
||||
"python",
|
||||
"--user",
|
||||
"65534:65534",
|
||||
"--network",
|
||||
"none",
|
||||
"--read-only",
|
||||
"--cap-drop",
|
||||
"ALL",
|
||||
"--security-opt",
|
||||
"no-new-privileges",
|
||||
"--pids-limit",
|
||||
"128",
|
||||
"--cpus",
|
||||
"2",
|
||||
"--memory",
|
||||
"2g",
|
||||
"--memory-swap",
|
||||
"2g",
|
||||
"--tmpfs",
|
||||
"/tmp:rw,nosuid,nodev,size=384m,mode=1777",
|
||||
"-e",
|
||||
"HF_HUB_OFFLINE=1",
|
||||
"-e",
|
||||
"TRANSFORMERS_OFFLINE=1",
|
||||
"-e",
|
||||
"HF_HUB_DISABLE_TELEMETRY=1",
|
||||
"-e",
|
||||
"HF_HOME=/tmp/hf-home",
|
||||
"-e",
|
||||
"OMP_NUM_THREADS=1",
|
||||
"-e",
|
||||
"MKL_NUM_THREADS=1",
|
||||
"-e",
|
||||
"OLLAMA_BASE_URL=http://127.0.0.1:11434",
|
||||
"-e",
|
||||
"OLLAMA_MODEL=",
|
||||
"-e",
|
||||
"EXTERNAL_AI_ENABLED=0",
|
||||
"--mount",
|
||||
"type=bind,src=E:\\Storage\\Projects\\Active\\Job tracker\\docs\\redesign\\phase-9\\p9-sec-02\\model,dst=/qualification,readonly",
|
||||
"--mount",
|
||||
"type=bind,src=E:\\Storage\\Projects\\Active\\Job tracker\\.artifacts\\p9-sec-02\\qualified\\qualification-patched-parsers,dst=/evidence",
|
||||
"--mount",
|
||||
"type=bind,src=E:\\Storage\\Projects\\Active\\Job tracker\\.artifacts\\p9-sec-02\\artifact,dst=/fixture,readonly",
|
||||
"sha256:2fe77e47a6c5ecea66764dbd6264049724f24849141e16af5491c2de34af53c1",
|
||||
"/qualification/parser_probe.py"
|
||||
],
|
||||
"localImageId": "sha256:2fe77e47a6c5ecea66764dbd6264049724f24849141e16af5491c2de34af53c1",
|
||||
"runtimeImageId": "sha256:4a04ca68fa40b3ec61cb61187b339a4d2895b375b962999e974d75556b5b1331",
|
||||
"containerAbsent": true,
|
||||
"network": "none",
|
||||
"readOnly": true,
|
||||
"user": "65534:65534",
|
||||
"memoryLimitBytes": 2147483648,
|
||||
"cpuLimit": 2,
|
||||
"pidsLimit": 128,
|
||||
"wallClockDeadlineSeconds": 180,
|
||||
"scope": "Actual locally built source image plus exact test-only extras; no app source mount, production cache, external network, registry push or deployment."
|
||||
}
|
||||
},
|
||||
"inventory": {
|
||||
"status": "PASS",
|
||||
"record": {
|
||||
"status": "PASS",
|
||||
"python": "3.12.10 (main, May 21 2025, 23:34:56) [GCC 12.2.0]",
|
||||
"platform": "Linux-6.18.33.2-microsoft-standard-WSL2-x86_64-with-glibc2.36",
|
||||
"libc": [
|
||||
"glibc",
|
||||
"2.36"
|
||||
],
|
||||
"applicationLockSha256": "3a3afc529f0076a1b5d67082c9269c22c12f52c47ecf95ce0c76c37b39d8297a",
|
||||
"applicationPins": {
|
||||
"annotated-doc": "0.0.5",
|
||||
"annotated-types": "0.8.0",
|
||||
"anyio": "4.14.2",
|
||||
"cachetools": "5.5.2",
|
||||
"certifi": "2026.10.19",
|
||||
"click": "8.5.0",
|
||||
"fastapi": "0.141.1",
|
||||
"filelock": "4.2.1",
|
||||
"fsspec": "2026.7.0",
|
||||
"h11": "0.16.0",
|
||||
"hf-xet": "1.6.0",
|
||||
"httpcore": "1.0.9",
|
||||
"httptools": "0.8.0",
|
||||
"httpx": "0.28.1",
|
||||
"huggingface-hub": "1.33.0",
|
||||
"idna": "3.19",
|
||||
"jinja2": "3.1.6",
|
||||
"lxml": "6.1.2",
|
||||
"markdown-it-py": "4.2.0",
|
||||
"markupsafe": "3.0.3",
|
||||
"mdurl": "0.1.2",
|
||||
"mpmath": "1.3.0",
|
||||
"networkx": "3.6.1",
|
||||
"numpy": "2.4.6",
|
||||
"packaging": "26.3",
|
||||
"pillow": "13.0.0",
|
||||
"pydantic": "2.10.6",
|
||||
"pydantic-core": "2.27.2",
|
||||
"pygments": "2.21.0",
|
||||
"pymupdf": "1.25.5",
|
||||
"pypdf": "6.21.2",
|
||||
"pytesseract": "0.3.13",
|
||||
"python-docx": "1.1.2",
|
||||
"python-dotenv": "1.2.3",
|
||||
"python-multipart": "0.0.32",
|
||||
"pyyaml": "6.0.3",
|
||||
"regex": "2026.7.19",
|
||||
"rich": "15.0.0",
|
||||
"safetensors": "0.8.0",
|
||||
"setuptools": "84.1.0",
|
||||
"shellingham": "1.5.4",
|
||||
"starlette": "1.6.0",
|
||||
"sympy": "1.14.0",
|
||||
"tokenizers": "0.22.2",
|
||||
"torch": "2.13.0+cpu",
|
||||
"tqdm": "4.70.0",
|
||||
"transformers": "5.10.0",
|
||||
"typer": "0.27.3",
|
||||
"typing-extensions": "4.16.0",
|
||||
"typing-inspection": "0.4.4",
|
||||
"urllib3": "2.8.0",
|
||||
"uvicorn": "0.34.0",
|
||||
"uvloop": "0.22.1",
|
||||
"watchfiles": "1.2.0",
|
||||
"websockets": "17.1"
|
||||
},
|
||||
"installedDistributions": {
|
||||
"httpx2": "2.12.0",
|
||||
"pytest": "9.0.3",
|
||||
"iniconfig": "2.3.1",
|
||||
"pluggy": "1.7.0",
|
||||
"httpcore2": "2.12.0",
|
||||
"truststore": "0.10.5",
|
||||
"setuptools": "84.1.0",
|
||||
"pymupdf": "1.25.5",
|
||||
"numpy": "2.4.6",
|
||||
"mdurl": "0.1.2",
|
||||
"huggingface-hub": "1.33.0",
|
||||
"python-dotenv": "1.2.3",
|
||||
"h11": "0.16.0",
|
||||
"uvicorn": "0.34.0",
|
||||
"transformers": "5.10.0",
|
||||
"anyio": "4.14.2",
|
||||
"pytesseract": "0.3.13",
|
||||
"urllib3": "2.8.0",
|
||||
"pydantic-core": "2.27.2",
|
||||
"annotated-types": "0.8.0",
|
||||
"typing-extensions": "4.16.0",
|
||||
"jinja2": "3.1.6",
|
||||
"regex": "2026.7.19",
|
||||
"fsspec": "2026.7.0",
|
||||
"pyyaml": "6.0.3",
|
||||
"hf-xet": "1.6.0",
|
||||
"pillow": "13.0.0",
|
||||
"watchfiles": "1.2.0",
|
||||
"httpcore": "1.0.9",
|
||||
"shellingham": "1.5.4",
|
||||
"safetensors": "0.8.0",
|
||||
"filelock": "4.2.1",
|
||||
"websockets": "17.1",
|
||||
"mpmath": "1.3.0",
|
||||
"typing-inspection": "0.4.4",
|
||||
"starlette": "1.6.0",
|
||||
"packaging": "26.3",
|
||||
"click": "8.5.0",
|
||||
"lxml": "6.1.2",
|
||||
"fastapi": "0.141.1",
|
||||
"torch": "2.13.0+cpu",
|
||||
"certifi": "2026.10.19",
|
||||
"httptools": "0.8.0",
|
||||
"annotated-doc": "0.0.5",
|
||||
"rich": "15.0.0",
|
||||
"markupsafe": "3.0.3",
|
||||
"networkx": "3.6.1",
|
||||
"uvloop": "0.22.1",
|
||||
"idna": "3.19",
|
||||
"typer": "0.27.3",
|
||||
"markdown-it-py": "4.2.0",
|
||||
"httpx": "0.28.1",
|
||||
"python-multipart": "0.0.32",
|
||||
"pip": "26.2.2",
|
||||
"pygments": "2.21.0",
|
||||
"pypdf": "6.21.2",
|
||||
"tqdm": "4.70.0",
|
||||
"tokenizers": "0.22.2",
|
||||
"pydantic": "2.10.6",
|
||||
"python-docx": "1.1.2",
|
||||
"sympy": "1.14.0",
|
||||
"wheel": "0.48.0",
|
||||
"cachetools": "5.5.2"
|
||||
},
|
||||
"extrasOutsideApplicationLock": {
|
||||
"httpx2": "2.12.0",
|
||||
"pytest": "9.0.3",
|
||||
"iniconfig": "2.3.1",
|
||||
"pluggy": "1.7.0",
|
||||
"httpcore2": "2.12.0",
|
||||
"truststore": "0.10.5",
|
||||
"pip": "26.2.2",
|
||||
"wheel": "0.48.0"
|
||||
},
|
||||
"pipCheck": "No broken requirements found.",
|
||||
"noDevelopmentEnvironmentsInImage": true,
|
||||
"torchVersion": "2.13.0+cpu",
|
||||
"torchBuildCuda": null,
|
||||
"cudaAvailable": false,
|
||||
"torchBuild": "PyTorch built with:\n - GCC 13.3\n - C++ Version: 202002\n - Intel(R) oneAPI Math Kernel Library Version 2024.2-Product Build 20240605 for Intel(R) 64 architecture applications\n - Intel(R) MKL-DNN v3.12.0 (Git Hash 80afa71049cd69a3df32adcccb623b12cd7baa22)\n - OpenMP 201511 (a.k.a. OpenMP 4.5)\n - LAPACK is enabled (usually provided by MKL)\n - NNPACK is enabled\n - CPU capability usage: AVX512\n - Build settings: BLAS_INFO=mkl, BUILD_TYPE=Release, COMMIT_SHA=cf30153c4c131c8164ee7798e5022d810682e2cb, CUDA_FLAGS= -DLIBCUDACXX_ENABLE_SIMPLIFIED_COMPLEX_OPERATIONS -Xfatbin -compress-all -Wno-deprecated-gpu-targets --expt-extended-lambda -DCUB_WRAPPED_NAMESPACE=at_cuda_detail -DDISABLE_CUSPARSE_DEPRECATED -DCUDA_HAS_FP16=1 -D__CUDA_NO_HALF_OPERATORS__ -D__CUDA_NO_HALF_CONVERSIONS__ -D__CUDA_NO_HALF2_OPERATORS__ -D__CUDA_NO_BFLOAT16_CONVERSIONS__ -DC10_NODEPRECATED, CXX_COMPILER=/opt/rh/gcc-toolset-13/root/usr/bin/c++, CXX_FLAGS= -fvisibility-inlines-hidden -DUSE_PTHREADPOOL -DNDEBUG -DUSE_KINETO -DUSE_FBGEMM -DUSE_PYTORCH_QNNPACK -DSYMBOLICATE_MOBILE_DEBUG_HANDLE -O2 -fPIC -DC10_NODEPRECATED -Wall -Wextra -Werror=return-type -Werror=non-virtual-dtor -Werror=range-loop-construct -Werror=bool-operation -Wnarrowing -Wno-missing-field-initializers -Wno-unknown-pragmas -Wno-unused-parameter -Wno-strict-overflow -Wno-strict-aliasing -Wno-stringop-overflow -Wsuggest-override -Wno-psabi -Wno-error=old-style-cast -faligned-new -Wno-maybe-uninitialized -fno-math-errno -fno-trapping-math -Werror=format -Wno-dangling-reference -Wno-error=dangling-reference -Wno-stringop-overflow, LAPACK_INFO=mkl, PERF_WITH_AVX=1, PERF_WITH_AVX2=1, TORCH_VERSION=2.13.0, USE_CUDA=0, USE_CUDNN=OFF, USE_CUSPARSELT=OFF, USE_GFLAGS=OFF, USE_GLOG=OFF, USE_GLOO=ON, USE_MKL=ON, USE_MKLDNN=ON, USE_MPI=OFF, USE_NCCL=OFF, USE_NNPACK=ON, USE_OPENMP=ON, USE_ROCM=OFF, USE_ROCM_KERNEL_ASSERT=OFF, USE_XCCL=OFF, USE_XPU=OFF, \n",
|
||||
"tesseractVersion": "tesseract 5.3.0",
|
||||
"englishOcrData": {
|
||||
"path": "/usr/share/tesseract-ocr/5/tessdata/eng.traineddata",
|
||||
"bytes": 4113088,
|
||||
"sha256": "7d4322bd2a7749724879683fc3912cb542f19906c83bcc1a52132556427170b2"
|
||||
},
|
||||
"nativePackages": "adduser\t3.134\napt\t2.6.1\nbase-files\t12.4+deb12u11\nbase-passwd\t3.6.1\nbash\t5.2.15-2+b8\nbsdutils\t1:2.38.1-5+deb12u3\nca-certificates\t20230311\ncoreutils\t9.1-1\ndash\t0.5.12-2\ndebconf\t1.5.82\ndebian-archive-keyring\t2023.3+deb12u2\ndebianutils\t5.7-0.5~deb12u1\ndiffutils\t1:3.8-4\ndpkg\t1.21.22\ne2fsprogs\t1.47.0-2\nfindutils\t4.9.0-4\nfontconfig\t2.14.1-4\nfontconfig-config\t2.14.1-4\nfonts-dejavu-core\t2.37-6\ngcc-12-base:amd64\t12.2.0-14+deb12u1\ngpgv\t2.2.40-1.1\ngrep\t3.8-5\ngzip\t1.12-1\nhostname\t3.23+nmu1\ninit-system-helpers\t1.65.2\nlibacl1:amd64\t2.3.1-3\nlibapt-pkg6.0:amd64\t2.6.1\nlibarchive13:amd64\t3.6.2-1+deb12u5\nlibattr1:amd64\t1:2.5.1-4\nlibaudit-common\t1:3.0.9-1\nlibaudit1:amd64\t1:3.0.9-1\nlibblkid1:amd64\t2.38.1-5+deb12u3\nlibbrotli1:amd64\t1.0.9-2+deb12u1\nlibbsd0:amd64\t0.11.7-2\nlibbz2-1.0:amd64\t1.0.8-5+b1\nlibc-bin\t2.36-9+deb12u10\nlibc6:amd64\t2.36-9+deb12u10\nlibcairo2:amd64\t1.16.0-7\nlibcap-ng0:amd64\t0.8.3-1+b3\nlibcap2:amd64\t1:2.66-4+deb12u1\nlibcom-err2:amd64\t1.47.0-2\nlibcrypt1:amd64\t1:4.4.33-2\nlibcurl4:amd64\t7.88.1-10+deb12u15\nlibdatrie1:amd64\t0.2.13-2+b1\nlibdb5.3:amd64\t5.3.28+dfsg2-1\nlibdebconfclient0:amd64\t0.270\nlibdeflate0:amd64\t1.14-1\nlibexpat1:amd64\t2.5.0-1+deb12u5\nlibext2fs2:amd64\t1.47.0-2\nlibffi8:amd64\t3.4.4-1\nlibfontconfig1:amd64\t2.14.1-4\nlibfreetype6:amd64\t2.12.1+dfsg-5+deb12u4\nlibfribidi0:amd64\t1.0.8-2.1\nlibgcc-s1:amd64\t12.2.0-14+deb12u1\nlibgcrypt20:amd64\t1.10.1-3\nlibgdbm6:amd64\t1.23-3\nlibgif7:amd64\t5.2.1-2.5+deb12u1\nlibglib2.0-0:amd64\t2.74.6-2+deb12u9\nlibgmp10:amd64\t2:6.2.1+dfsg1-1.1\nlibgnutls30:amd64\t3.7.9-2+deb12u4\nlibgomp1:amd64\t12.2.0-14+deb12u1\nlibgpg-error0:amd64\t1.46-1\nlibgraphite2-3:amd64\t1.3.14-1+deb12u1\nlibgssapi-krb5-2:amd64\t1.20.1-2+deb12u3\nlibharfbuzz0b:amd64\t6.0.0+dfsg-3\nlibhogweed6:amd64\t3.8.1-2\nlibicu72:amd64\t72.1-3+deb12u1\nlibidn2-0:amd64\t2.3.3-1+b1\nlibjbig0:amd64\t2.1-6.1\nlibjpeg62-turbo:amd64\t1:2.1.5-2\nlibk5crypto3:amd64\t1.20.1-2+deb12u3\nlibkeyutils1:amd64\t1.6.3-2\nlibkrb5-3:amd64\t1.20.1-2+deb12u3\nlibkrb5support0:amd64\t1.20.1-2+deb12u3\nlibldap-2.5-0:amd64\t2.5.13+dfsg-5\nliblept5:amd64\t1.82.0-3+b3\nliblerc4:amd64\t4.0.0+ds-2\nliblz4-1:amd64\t1.9.4-1\nliblzma5:amd64\t5.4.1-1\nlibmd0:amd64\t1.0.4-2\nlibmount1:amd64\t2.38.1-5+deb12u3\nlibncursesw6:amd64\t6.4-4\nlibnettle8:amd64\t3.8.1-2\nlibnghttp2-14:amd64\t1.52.0-1+deb12u3\nlibnsl2:amd64\t1.3.0-2\nlibopenjp2-7:amd64\t2.5.0-2+deb12u3\nlibp11-kit0:amd64\t0.24.1-2\nlibpam-modules:amd64\t1.5.2-6+deb12u1\nlibpam-modules-bin\t1.5.2-6+deb12u1\nlibpam-runtime\t1.5.2-6+deb12u1\nlibpam0g:amd64\t1.5.2-6+deb12u1\nlibpango-1.0-0:amd64\t1.50.12+ds-1\nlibpangocairo-1.0-0:amd64\t1.50.12+ds-1\nlibpangoft2-1.0-0:amd64\t1.50.12+ds-1\nlibpcre2-8-0:amd64\t10.42-1\nlibpixman-1-0:amd64\t0.42.2-1\nlibpng16-16:amd64\t1.6.39-2+deb12u6\nlibpsl5:amd64\t0.21.2-1\nlibreadline8:amd64\t8.2-1.3\nlibrtmp1:amd64\t2.4+20151223.gitfa8646d.1-2+b2\nlibsasl2-2:amd64\t2.1.28+dfsg-10\nlibsasl2-modules-db:amd64\t2.1.28+dfsg-10\nlibseccomp2:amd64\t2.5.4-1+deb12u1\nlibselinux1:amd64\t3.4-1+b6\nlibsemanage-common\t3.4-1\nlibsemanage2:amd64\t3.4-1+b5\nlibsepol2:amd64\t3.4-2.1\nlibsmartcols1:amd64\t2.38.1-5+deb12u3\nlibsqlite3-0:amd64\t3.40.1-2+deb12u1\nlibss2:amd64\t1.47.0-2\nlibssh2-1:amd64\t1.10.0-3+deb12u1\nlibssl3:amd64\t3.0.16-1~deb12u1\nlibstdc++6:amd64\t12.2.0-14+deb12u1\nlibsystemd0:amd64\t252.36-1~deb12u1\nlibtasn1-6:amd64\t4.19.0-2+deb12u1\nlibtesseract5:amd64\t5.3.0-2\nlibthai-data\t0.1.29-1\nlibthai0:amd64\t0.1.29-1\nlibtiff6:amd64\t4.5.0-6+deb12u4\nlibtinfo6:amd64\t6.4-4\nlibtirpc-common\t1.3.3+ds-1\nlibtirpc3:amd64\t1.3.3+ds-1\nlibudev1:amd64\t252.36-1~deb12u1\nlibunistring2:amd64\t1.0-2\nlibuuid1:amd64\t2.38.1-5+deb12u3\nlibwebp7:amd64\t1.2.4-0.2+deb12u1\nlibwebpmux3:amd64\t1.2.4-0.2+deb12u1\nlibx11-6:amd64\t2:1.8.4-2+deb12u2\nlibx11-data\t2:1.8.4-2+deb12u2\nlibxau6:amd64\t1:1.0.9-1\nlibxcb-render0:amd64\t1.15-1\nlibxcb-shm0:amd64\t1.15-1\nlibxcb1:amd64\t1.15-1\nlibxdmcp6:amd64\t1:1.1.2-3\nlibxext6:amd64\t2:1.3.4-1+b1\nlibxml2:amd64\t2.9.14+dfsg-1.3~deb12u6\nlibxrender1:amd64\t1:0.9.10-1.1\nlibxxhash0:amd64\t0.8.1-1\nlibzstd1:amd64\t1.5.4+dfsg2-5\nlogin\t1:4.13+dfsg1-1+deb12u1\nlogsave\t1.47.0-2\nmawk\t1.3.4.20200120-3.1\nmount\t2.38.1-5+deb12u3\nncurses-base\t6.4-4\nncurses-bin\t6.4-4\nnetbase\t6.4\nopenssl\t3.0.16-1~deb12u1\npasswd\t1:4.13+dfsg1-1+deb12u1\nperl-base\t5.36.0-7+deb12u2\nreadline-common\t8.2-1.3\nsed\t4.9-1\nsysvinit-utils\t3.06-4\ntar\t1.34+dfsg-1.2+deb12u1\ntesseract-ocr\t5.3.0-2\ntesseract-ocr-eng\t1:4.1.0-2\ntesseract-ocr-osd\t1:4.1.0-2\ntzdata\t2025b-0+deb12u1\nusr-is-merged\t37~deb12u1\nutil-linux\t2.38.1-5+deb12u3\nutil-linux-extra\t2.38.1-5+deb12u3\nzlib1g:amd64\t1:1.2.13.dfsg-1\n",
|
||||
"scope": "Actual locally built source Dockerfile and exact55 locked application pins; test-only packages, if any, and bootstrap tools remain explicitly listed separately.",
|
||||
"applicationSources": {
|
||||
"app.py": "aab24c7f64868fcb93a6133aa7b2087b23f98469e89e4c84fa040a022b0a8dfc",
|
||||
"parser_child.py": "0074a05e9a0d511e26a329a057f98568cdc1723b2cc37168e0b59975b5424451",
|
||||
"requirements.txt": "b74510c7c2033611cc4661bcc26ebec30a0a9a790838be8ec7c69c6dd834f877",
|
||||
"requirements-linux.lock": "3a3afc529f0076a1b5d67082c9269c22c12f52c47ecf95ce0c76c37b39d8297a",
|
||||
"tests/test_app.py": "143c9704c658a91b5ed998504c2aefa4c6326adfebc60ee797d810c3bbd810a2"
|
||||
}
|
||||
},
|
||||
"process": {
|
||||
"lane": "inventory",
|
||||
"attempt": "qualification-patched-inventory",
|
||||
"startedUtc": "2026-10-25T07:09:12.676076+00:00",
|
||||
"finishedUtc": "2026-10-25T07:09:16.479968+00:00",
|
||||
"exitCode": 0,
|
||||
"command": [
|
||||
"docker",
|
||||
"run",
|
||||
"--rm",
|
||||
"--name",
|
||||
"jt-sec02-inventory-95ab2359",
|
||||
"--label",
|
||||
"jobtracker.qualification=p9-sec02",
|
||||
"--entrypoint",
|
||||
"python",
|
||||
"--user",
|
||||
"65534:65534",
|
||||
"--network",
|
||||
"none",
|
||||
"--read-only",
|
||||
"--cap-drop",
|
||||
"ALL",
|
||||
"--security-opt",
|
||||
"no-new-privileges",
|
||||
"--pids-limit",
|
||||
"128",
|
||||
"--cpus",
|
||||
"2",
|
||||
"--memory",
|
||||
"2g",
|
||||
"--memory-swap",
|
||||
"2g",
|
||||
"--tmpfs",
|
||||
"/tmp:rw,nosuid,nodev,size=384m,mode=1777",
|
||||
"-e",
|
||||
"HF_HUB_OFFLINE=1",
|
||||
"-e",
|
||||
"TRANSFORMERS_OFFLINE=1",
|
||||
"-e",
|
||||
"HF_HUB_DISABLE_TELEMETRY=1",
|
||||
"-e",
|
||||
"HF_HOME=/tmp/hf-home",
|
||||
"-e",
|
||||
"OMP_NUM_THREADS=1",
|
||||
"-e",
|
||||
"MKL_NUM_THREADS=1",
|
||||
"-e",
|
||||
"OLLAMA_BASE_URL=http://127.0.0.1:11434",
|
||||
"-e",
|
||||
"OLLAMA_MODEL=",
|
||||
"-e",
|
||||
"EXTERNAL_AI_ENABLED=0",
|
||||
"--mount",
|
||||
"type=bind,src=E:\\Storage\\Projects\\Active\\Job tracker\\docs\\redesign\\phase-9\\p9-sec-02\\model,dst=/qualification,readonly",
|
||||
"--mount",
|
||||
"type=bind,src=E:\\Storage\\Projects\\Active\\Job tracker\\.artifacts\\p9-sec-02\\qualified\\qualification-patched-inventory,dst=/evidence",
|
||||
"sha256:2fe77e47a6c5ecea66764dbd6264049724f24849141e16af5491c2de34af53c1",
|
||||
"/qualification/runtime_inventory.py"
|
||||
],
|
||||
"localImageId": "sha256:2fe77e47a6c5ecea66764dbd6264049724f24849141e16af5491c2de34af53c1",
|
||||
"runtimeImageId": "sha256:4a04ca68fa40b3ec61cb61187b339a4d2895b375b962999e974d75556b5b1331",
|
||||
"containerAbsent": true,
|
||||
"network": "none",
|
||||
"readOnly": true,
|
||||
"user": "65534:65534",
|
||||
"memoryLimitBytes": 2147483648,
|
||||
"cpuLimit": 2,
|
||||
"pidsLimit": 128,
|
||||
"wallClockDeadlineSeconds": 180,
|
||||
"scope": "Actual locally built source image plus exact test-only extras; no app source mount, production cache, external network, registry push or deployment."
|
||||
}
|
||||
}
|
||||
},
|
||||
"scope": "Actual source Dockerfile runtime plus exact six test extras. Synthetic BART weights and real pinned tokenizer/native generation; no full checkpoint, semantic quality, live cache, GPU or production claim."
|
||||
}
|
||||
@@ -0,0 +1,22 @@
|
||||
{
|
||||
"startedUtc": "2026-10-25T07:11:08.705905+00:00",
|
||||
"finishedUtc": "2026-10-25T07:11:16.481575+00:00",
|
||||
"lockSha256": "902dee7aaf758577fed7fbd53b0161f691d598e89ffe75c6ebf375f13f6c456b",
|
||||
"packageCount": 63,
|
||||
"sourceQueryCount": 126,
|
||||
"errors": [
|
||||
{
|
||||
"package": "torch",
|
||||
"version": "2.13.0+cpu",
|
||||
"provider": "pypi",
|
||||
"httpStatus": 404,
|
||||
"error": "HTTPError"
|
||||
}
|
||||
],
|
||||
"findingPackageCount": 0,
|
||||
"advisoryRecords": 0,
|
||||
"status": "INCOMPLETE",
|
||||
"limits": "Exact lock pin queries only; public advisory metadata, no installation/resolution, exploit or reachability assessment. OSV performs upstream version matching. Missing releases are errors, not clean findings. Cross-provider aliases can overlap.",
|
||||
"rawSummarySha256": "804a01d79bb3ba295eab59284018a2060b680307720548ffcf804536a5d66fd0",
|
||||
"scope": "Actual63-distribution qualification image:55 application +6 exact test extras +pip/wheel. Full raw requests retained; exact vendor PyPI404 is not a clean finding."
|
||||
}
|
||||
Reference in New Issue
Block a user