feat(plane): increment manifests for the 46-candidate validation run (task 7)

Model deepseek-flash (declared provider extension, endpoint prices in
parameters, secretKey naming the DEEPSEEK_API_KEY secret), digest-pinned
Task templates repo-facts / verify / agree, and a generator
(plane/generate.py, `ousast plane workspaces --validation-set ...`) that
emits per case the vulnerable-pin Workspace, a files-only inputs Workspace
(recorded candidates after the recorded triage, declared sites, triage),
per-case Tasks and one Run validation-46: facts -> verify a, verify b ->
agree for the 15 cases, 46 candidates (43 kept), budgets 1.5x the recorded
per-pass share. A Run entry cannot add a binding or env, and Run.inputs
names only task artifacts, so the case is fixed by per-case Tasks.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
Claude-Session: https://claude.ai/code/session_01EmM1j46qgKMh3zqD1QMwEo
This commit is contained in:
Marius Ciepluch
2026-09-29 18:55:38 +02:00
co-authored by Claude Opus 5.5
parent 1a69e50a68
commit a35397c0ec
41 changed files with 3285 additions and 2 deletions
@@ -1,7 +1,7 @@
{ {
"modules": 128, "modules": 129,
"counts": { "counts": {
"load_bearing": 119, "load_bearing": 120,
"standalone_capability": 9 "standalone_capability": 9
}, },
"orphaned": [], "orphaned": [],
@@ -659,6 +659,7 @@
"reason": "ai-service-plane Req 1-4: the service plane package; runner and reconciler integration in tasks 3-4", "reason": "ai-service-plane Req 1-4: the service plane package; runner and reconciler integration in tasks 3-4",
"importers": [ "importers": [
"cli", "cli",
"plane.generate",
"plane.reconciler", "plane.reconciler",
"plane.runner", "plane.runner",
"plane.tasks.verify", "plane.tasks.verify",
@@ -673,11 +674,20 @@
"plane.tasks.verify" "plane.tasks.verify"
] ]
}, },
{
"module": "plane.generate",
"classification": "load_bearing",
"reason": "ai-service-plane task 7: an increment's Workspaces, per-case Tasks and Run from a recorded set",
"importers": [
"cli"
]
},
{ {
"module": "plane.manifests", "module": "plane.manifests",
"classification": "load_bearing", "classification": "load_bearing",
"reason": "ai-service-plane Req 1.1-1.4: ax-shaped Task/Workspace/Model and the Run kind, validated before anything runs", "reason": "ai-service-plane Req 1.1-1.4: ax-shaped Task/Workspace/Model and the Run kind, validated before anything runs",
"importers": [ "importers": [
"plane.generate",
"plane.reconciler", "plane.reconciler",
"plane.runner", "plane.runner",
"plane.workspaces" "plane.workspaces"
@@ -688,6 +698,7 @@
"classification": "load_bearing", "classification": "load_bearing",
"reason": "ai-service-plane Req 3.1-3.5, 7.3: ax-backed Run execution, status attribution and doctor; `ousast plane`", "reason": "ai-service-plane Req 3.1-3.5, 7.3: ax-backed Run execution, status attribution and doctor; `ousast plane`",
"importers": [ "importers": [
"plane.generate",
"plane.workspaces" "plane.workspaces"
] ]
}, },
@@ -702,6 +713,7 @@
"classification": "load_bearing", "classification": "load_bearing",
"reason": "ai-service-plane Req 4.1: the task entrypoint package the runner imports by name; runner integration pending (task 3)", "reason": "ai-service-plane Req 4.1: the task entrypoint package the runner imports by name; runner integration pending (task 3)",
"importers": [ "importers": [
"plane.generate",
"plane.tasks.agree" "plane.tasks.agree"
] ]
}, },
@@ -722,6 +734,7 @@
"classification": "load_bearing", "classification": "load_bearing",
"reason": "ai-service-plane Req 5.3/2.1-2.3/7.2: the batched hunt with known callers, metered and resumable per file hunt", "reason": "ai-service-plane Req 5.3/2.1-2.3/7.2: the batched hunt with known callers, metered and resumable per file hunt",
"importers": [ "importers": [
"plane.generate",
"plane.tasks.agree" "plane.tasks.agree"
] ]
}, },
+22
View File
@@ -0,0 +1,22 @@
# The chat model of the first increment (ai-service-plane Req 1.1, 1.4, 7.1). `deepseek` is not an ax provider;
# the annotation declares the extension instead of hiding it in another field. `secretKey` names the Kubernetes
# Secret and key that hold DEEPSEEK_API_KEY, the variable `tool_hunter.resolve_hunter_client()` reads; the key
# itself is never in a manifest. Prices are `openultrasast.model.endpoint`'s for `deepseek-flash` (USD per million
# tokens); the verify task's meter reads them from OUSAST_MODEL_PARAMS with `budget.prices_from`.
apiVersion: ax.io/v1alpha1
kind: Model
metadata:
name: deepseek-flash
atespace: default
annotations:
openultrasast.io/provider-extension: "true"
spec:
provider: deepseek
model: deepseek-flash
secretKey:
name: deepseek
key: DEEPSEEK_API_KEY
parameters:
cache_hit_per_m: 0.014
input_per_m: 0.44
output_per_m: 1.32
+563
View File
@@ -0,0 +1,563 @@
# generated by `ousast plane workspaces benchmarks/independent/population-v2.toml --validation-set ~/ousast-results/independent-v2-sets/validation.json --candidates ~/ousast-results/independent-v2-modelsinks --triage ~/ousast-results/independent-v2-batched-check/scans --run validation-46`; do not edit, regenerate.
# 15 cases, 46 candidates (43 kept by the recorded triage); usd ceiling 2.02.
apiVersion: openultrasast.io/v1alpha1
kind: Run
metadata:
name: validation-46
spec:
tasks:
- name: budibase-mongo-template-nosqli-facts
task: repo-facts-budibase-mongo-template-nosqli
outputs:
- facts.json
budget: &id001
usd: 0
calls: 0
serialize: repo-facts
- name: budibase-mongo-template-nosqli-va
task: verify-a-budibase-mongo-template-nosqli
inputs:
facts: budibase-mongo-template-nosqli-facts/facts.json
outputs:
- units.jsonl
- summary.json
budget:
usd: 0.06
calls: 16
- name: budibase-mongo-template-nosqli-vb
task: verify-b-budibase-mongo-template-nosqli
inputs:
facts: budibase-mongo-template-nosqli-facts/facts.json
outputs:
- units.jsonl
- summary.json
budget:
usd: 0.06
calls: 16
- name: budibase-mongo-template-nosqli-agree
task: agree-budibase-mongo-template-nosqli
inputs:
pass_a: budibase-mongo-template-nosqli-va/units.jsonl
pass_b: budibase-mongo-template-nosqli-vb/units.jsonl
outputs:
- agreed.json
- disputed.json
budget: *id001
- name: cct-studio-server-cmdi-facts
task: repo-facts-cct-studio-server-cmdi
outputs:
- facts.json
budget: &id002
usd: 0
calls: 0
serialize: repo-facts
- name: cct-studio-server-cmdi-va
task: verify-a-cct-studio-server-cmdi
inputs:
facts: cct-studio-server-cmdi-facts/facts.json
outputs:
- units.jsonl
- summary.json
budget:
usd: 0.04
calls: 8
- name: cct-studio-server-cmdi-vb
task: verify-b-cct-studio-server-cmdi
inputs:
facts: cct-studio-server-cmdi-facts/facts.json
outputs:
- units.jsonl
- summary.json
budget:
usd: 0.04
calls: 8
- name: cct-studio-server-cmdi-agree
task: agree-cct-studio-server-cmdi
inputs:
pass_a: cct-studio-server-cmdi-va/units.jsonl
pass_b: cct-studio-server-cmdi-vb/units.jsonl
outputs:
- agreed.json
- disputed.json
budget: *id002
- name: contextforge-prompt-ssti-facts
task: repo-facts-contextforge-prompt-ssti
outputs:
- facts.json
budget: &id003
usd: 0
calls: 0
serialize: repo-facts
- name: contextforge-prompt-ssti-va
task: verify-a-contextforge-prompt-ssti
inputs:
facts: contextforge-prompt-ssti-facts/facts.json
outputs:
- units.jsonl
- summary.json
budget:
usd: 0.04
calls: 8
- name: contextforge-prompt-ssti-vb
task: verify-b-contextforge-prompt-ssti
inputs:
facts: contextforge-prompt-ssti-facts/facts.json
outputs:
- units.jsonl
- summary.json
budget:
usd: 0.04
calls: 8
- name: contextforge-prompt-ssti-agree
task: agree-contextforge-prompt-ssti
inputs:
pass_a: contextforge-prompt-ssti-va/units.jsonl
pass_b: contextforge-prompt-ssti-vb/units.jsonl
outputs:
- agreed.json
- disputed.json
budget: *id003
- name: froxlor-admin-ip-second-order-sqli-facts
task: repo-facts-froxlor-admin-ip-second-order-sqli
outputs:
- facts.json
budget: &id004
usd: 0
calls: 0
serialize: repo-facts
- name: froxlor-admin-ip-second-order-sqli-va
task: verify-a-froxlor-admin-ip-second-order-sqli
inputs:
facts: froxlor-admin-ip-second-order-sqli-facts/facts.json
outputs:
- units.jsonl
- summary.json
budget:
usd: 0.07
calls: 16
- name: froxlor-admin-ip-second-order-sqli-vb
task: verify-b-froxlor-admin-ip-second-order-sqli
inputs:
facts: froxlor-admin-ip-second-order-sqli-facts/facts.json
outputs:
- units.jsonl
- summary.json
budget:
usd: 0.07
calls: 16
- name: froxlor-admin-ip-second-order-sqli-agree
task: agree-froxlor-admin-ip-second-order-sqli
inputs:
pass_a: froxlor-admin-ip-second-order-sqli-va/units.jsonl
pass_b: froxlor-admin-ip-second-order-sqli-vb/units.jsonl
outputs:
- agreed.json
- disputed.json
budget: *id004
- name: fuxa-tdengine-escape-sqli-facts
task: repo-facts-fuxa-tdengine-escape-sqli
outputs:
- facts.json
budget: &id005
usd: 0
calls: 0
serialize: repo-facts
- name: fuxa-tdengine-escape-sqli-va
task: verify-a-fuxa-tdengine-escape-sqli
inputs:
facts: fuxa-tdengine-escape-sqli-facts/facts.json
outputs:
- units.jsonl
- summary.json
budget:
usd: 0.12
calls: 8
- name: fuxa-tdengine-escape-sqli-vb
task: verify-b-fuxa-tdengine-escape-sqli
inputs:
facts: fuxa-tdengine-escape-sqli-facts/facts.json
outputs:
- units.jsonl
- summary.json
budget:
usd: 0.12
calls: 8
- name: fuxa-tdengine-escape-sqli-agree
task: agree-fuxa-tdengine-escape-sqli
inputs:
pass_a: fuxa-tdengine-escape-sqli-va/units.jsonl
pass_b: fuxa-tdengine-escape-sqli-vb/units.jsonl
outputs:
- agreed.json
- disputed.json
budget: *id005
- name: lmdeploy-media-url-ssrf-facts
task: repo-facts-lmdeploy-media-url-ssrf
outputs:
- facts.json
budget: &id006
usd: 0
calls: 0
serialize: repo-facts
- name: lmdeploy-media-url-ssrf-va
task: verify-a-lmdeploy-media-url-ssrf
inputs:
facts: lmdeploy-media-url-ssrf-facts/facts.json
outputs:
- units.jsonl
- summary.json
budget:
usd: 0.02
calls: 8
- name: lmdeploy-media-url-ssrf-vb
task: verify-b-lmdeploy-media-url-ssrf
inputs:
facts: lmdeploy-media-url-ssrf-facts/facts.json
outputs:
- units.jsonl
- summary.json
budget:
usd: 0.02
calls: 8
- name: lmdeploy-media-url-ssrf-agree
task: agree-lmdeploy-media-url-ssrf
inputs:
pass_a: lmdeploy-media-url-ssrf-va/units.jsonl
pass_b: lmdeploy-media-url-ssrf-vb/units.jsonl
outputs:
- agreed.json
- disputed.json
budget: *id006
- name: medplum-external-auth-open-redirect-facts
task: repo-facts-medplum-external-auth-open-redirect
outputs:
- facts.json
budget: &id007
usd: 0
calls: 0
serialize: repo-facts
- name: medplum-external-auth-open-redirect-va
task: verify-a-medplum-external-auth-open-redirect
inputs:
facts: medplum-external-auth-open-redirect-facts/facts.json
outputs:
- units.jsonl
- summary.json
budget:
usd: 0.02
calls: 8
- name: medplum-external-auth-open-redirect-vb
task: verify-b-medplum-external-auth-open-redirect
inputs:
facts: medplum-external-auth-open-redirect-facts/facts.json
outputs:
- units.jsonl
- summary.json
budget:
usd: 0.02
calls: 8
- name: medplum-external-auth-open-redirect-agree
task: agree-medplum-external-auth-open-redirect
inputs:
pass_a: medplum-external-auth-open-redirect-va/units.jsonl
pass_b: medplum-external-auth-open-redirect-vb/units.jsonl
outputs:
- agreed.json
- disputed.json
budget: *id007
- name: pgadmin-maintenance-sqli-facts
task: repo-facts-pgadmin-maintenance-sqli
outputs:
- facts.json
budget: &id008
usd: 0
calls: 0
serialize: repo-facts
- name: pgadmin-maintenance-sqli-va
task: verify-a-pgadmin-maintenance-sqli
inputs:
facts: pgadmin-maintenance-sqli-facts/facts.json
outputs:
- units.jsonl
- summary.json
budget:
usd: 0.45
calls: 96
- name: pgadmin-maintenance-sqli-vb
task: verify-b-pgadmin-maintenance-sqli
inputs:
facts: pgadmin-maintenance-sqli-facts/facts.json
outputs:
- units.jsonl
- summary.json
budget:
usd: 0.45
calls: 96
- name: pgadmin-maintenance-sqli-agree
task: agree-pgadmin-maintenance-sqli
inputs:
pass_a: pgadmin-maintenance-sqli-va/units.jsonl
pass_b: pgadmin-maintenance-sqli-vb/units.jsonl
outputs:
- agreed.json
- disputed.json
budget: *id008
- name: qwed-sympy-eval-facts
task: repo-facts-qwed-sympy-eval
outputs:
- facts.json
budget: &id009
usd: 0
calls: 0
serialize: repo-facts
- name: qwed-sympy-eval-va
task: verify-a-qwed-sympy-eval
inputs:
facts: qwed-sympy-eval-facts/facts.json
outputs:
- units.jsonl
- summary.json
budget:
usd: 0.02
calls: 8
- name: qwed-sympy-eval-vb
task: verify-b-qwed-sympy-eval
inputs:
facts: qwed-sympy-eval-facts/facts.json
outputs:
- units.jsonl
- summary.json
budget:
usd: 0.02
calls: 8
- name: qwed-sympy-eval-agree
task: agree-qwed-sympy-eval
inputs:
pass_a: qwed-sympy-eval-va/units.jsonl
pass_b: qwed-sympy-eval-vb/units.jsonl
outputs:
- agreed.json
- disputed.json
budget: *id009
- name: reactpress-findall-column-sqli-facts
task: repo-facts-reactpress-findall-column-sqli
outputs:
- facts.json
budget: &id010
usd: 0
calls: 0
serialize: repo-facts
- name: reactpress-findall-column-sqli-va
task: verify-a-reactpress-findall-column-sqli
inputs:
facts: reactpress-findall-column-sqli-facts/facts.json
outputs:
- units.jsonl
- summary.json
budget:
usd: 0.02
calls: 8
- name: reactpress-findall-column-sqli-vb
task: verify-b-reactpress-findall-column-sqli
inputs:
facts: reactpress-findall-column-sqli-facts/facts.json
outputs:
- units.jsonl
- summary.json
budget:
usd: 0.02
calls: 8
- name: reactpress-findall-column-sqli-agree
task: agree-reactpress-findall-column-sqli
inputs:
pass_a: reactpress-findall-column-sqli-va/units.jsonl
pass_b: reactpress-findall-column-sqli-vb/units.jsonl
outputs:
- agreed.json
- disputed.json
budget: *id010
- name: unleash-addon-webhook-ssrf-facts
task: repo-facts-unleash-addon-webhook-ssrf
outputs:
- facts.json
budget: &id011
usd: 0
calls: 0
serialize: repo-facts
- name: unleash-addon-webhook-ssrf-va
task: verify-a-unleash-addon-webhook-ssrf
inputs:
facts: unleash-addon-webhook-ssrf-facts/facts.json
outputs:
- units.jsonl
- summary.json
budget:
usd: 0.03
calls: 8
- name: unleash-addon-webhook-ssrf-vb
task: verify-b-unleash-addon-webhook-ssrf
inputs:
facts: unleash-addon-webhook-ssrf-facts/facts.json
outputs:
- units.jsonl
- summary.json
budget:
usd: 0.03
calls: 8
- name: unleash-addon-webhook-ssrf-agree
task: agree-unleash-addon-webhook-ssrf
inputs:
pass_a: unleash-addon-webhook-ssrf-va/units.jsonl
pass_b: unleash-addon-webhook-ssrf-vb/units.jsonl
outputs:
- agreed.json
- disputed.json
budget: *id011
- name: winml-cli-serve-cors-facts
task: repo-facts-winml-cli-serve-cors
outputs:
- facts.json
budget: &id012
usd: 0
calls: 0
serialize: repo-facts
- name: winml-cli-serve-cors-va
task: verify-a-winml-cli-serve-cors
inputs:
facts: winml-cli-serve-cors-facts/facts.json
outputs:
- units.jsonl
- summary.json
budget:
usd: 0.02
calls: 8
- name: winml-cli-serve-cors-vb
task: verify-b-winml-cli-serve-cors
inputs:
facts: winml-cli-serve-cors-facts/facts.json
outputs:
- units.jsonl
- summary.json
budget:
usd: 0.02
calls: 8
- name: winml-cli-serve-cors-agree
task: agree-winml-cli-serve-cors
inputs:
pass_a: winml-cli-serve-cors-va/units.jsonl
pass_b: winml-cli-serve-cors-vb/units.jsonl
outputs:
- agreed.json
- disputed.json
budget: *id012
- name: wp-directorist-avatar-ssrf-facts
task: repo-facts-wp-directorist-avatar-ssrf
outputs:
- facts.json
budget: &id013
usd: 0
calls: 0
serialize: repo-facts
- name: wp-directorist-avatar-ssrf-va
task: verify-a-wp-directorist-avatar-ssrf
inputs:
facts: wp-directorist-avatar-ssrf-facts/facts.json
outputs:
- units.jsonl
- summary.json
budget:
usd: 0.03
calls: 8
- name: wp-directorist-avatar-ssrf-vb
task: verify-b-wp-directorist-avatar-ssrf
inputs:
facts: wp-directorist-avatar-ssrf-facts/facts.json
outputs:
- units.jsonl
- summary.json
budget:
usd: 0.03
calls: 8
- name: wp-directorist-avatar-ssrf-agree
task: agree-wp-directorist-avatar-ssrf
inputs:
pass_a: wp-directorist-avatar-ssrf-va/units.jsonl
pass_b: wp-directorist-avatar-ssrf-vb/units.jsonl
outputs:
- agreed.json
- disputed.json
budget: *id013
- name: wp-gopay-log-filter-sqli-facts
task: repo-facts-wp-gopay-log-filter-sqli
outputs:
- facts.json
budget: &id014
usd: 0
calls: 0
serialize: repo-facts
- name: wp-gopay-log-filter-sqli-va
task: verify-a-wp-gopay-log-filter-sqli
inputs:
facts: wp-gopay-log-filter-sqli-facts/facts.json
outputs:
- units.jsonl
- summary.json
budget:
usd: 0.02
calls: 8
- name: wp-gopay-log-filter-sqli-vb
task: verify-b-wp-gopay-log-filter-sqli
inputs:
facts: wp-gopay-log-filter-sqli-facts/facts.json
outputs:
- units.jsonl
- summary.json
budget:
usd: 0.02
calls: 8
- name: wp-gopay-log-filter-sqli-agree
task: agree-wp-gopay-log-filter-sqli
inputs:
pass_a: wp-gopay-log-filter-sqli-va/units.jsonl
pass_b: wp-gopay-log-filter-sqli-vb/units.jsonl
outputs:
- agreed.json
- disputed.json
budget: *id014
- name: wp-groundhogg-confirm-redirect-facts
task: repo-facts-wp-groundhogg-confirm-redirect
outputs:
- facts.json
budget: &id015
usd: 0
calls: 0
serialize: repo-facts
- name: wp-groundhogg-confirm-redirect-va
task: verify-a-wp-groundhogg-confirm-redirect
inputs:
facts: wp-groundhogg-confirm-redirect-facts/facts.json
outputs:
- units.jsonl
- summary.json
budget:
usd: 0.05
calls: 8
- name: wp-groundhogg-confirm-redirect-vb
task: verify-b-wp-groundhogg-confirm-redirect
inputs:
facts: wp-groundhogg-confirm-redirect-facts/facts.json
outputs:
- units.jsonl
- summary.json
budget:
usd: 0.05
calls: 8
- name: wp-groundhogg-confirm-redirect-agree
task: agree-wp-groundhogg-confirm-redirect
inputs:
pass_a: wp-groundhogg-confirm-redirect-va/units.jsonl
pass_b: wp-groundhogg-confirm-redirect-vb/units.jsonl
outputs:
- agreed.json
- disputed.json
budget: *id015
+18
View File
@@ -0,0 +1,18 @@
# agree (ai-service-plane Req 5.3, 2.1): agreement across the two verify passes, per-candidate cost and turns,
# declared-site match. No model. This is the template the per-case Tasks of a Run are generated from (bound to the
# case's inputs Workspace for the candidates and declared sites). The image is digest-pinned.
apiVersion: ax.io/v1alpha1
kind: Task
metadata:
name: agree
atespace: default
spec:
image: "localhost:5001/ousast-runner@sha256:318cbe019c1155b43fe59e47368d99e78f6f6011b7c822292251de53cf567bf3"
command: ["agree"]
resources:
requests:
cpu: "100m"
memory: "256Mi"
limits:
cpu: "1"
memory: "512Mi"
+19
View File
@@ -0,0 +1,19 @@
# repo-facts (ai-service-plane Req 5.1/5.2): source only, no model. This is the template the per-case Tasks of a
# Run are generated from (`ousast plane workspaces --validation-set ...` binds the case's pinned Workspace and its
# inputs Workspace, and sets the paths as env). The image is digest-pinned: Agent Substrate rejects tags.
# Heavy for the host (a full-tree scan of the case at 1 CPU / 1.5 GiB per gVisor worker): the Run serializes it.
apiVersion: ax.io/v1alpha1
kind: Task
metadata:
name: repo-facts
atespace: default
spec:
image: "localhost:5001/ousast-runner@sha256:318cbe019c1155b43fe59e47368d99e78f6f6011b7c822292251de53cf567bf3"
command: ["repo-facts"]
resources:
requests:
cpu: "250m"
memory: "512Mi"
limits:
cpu: "1"
memory: "1280Mi"
File diff suppressed because it is too large Load Diff
+21
View File
@@ -0,0 +1,21 @@
# verify (ai-service-plane Req 5.3, 2.1-2.3, 7.2): one batched hunt per file with the known callers from
# repo-facts in the prompt. Bound to its Model by the `openultrasast.io/model` annotation, which the reconciler
# strips and renders as OUSAST_MODEL / OUSAST_MODEL_PARAMS. This is the template the per-case, per-pass Tasks of a
# Run are generated from (the pass is OUSAST_PASS=a|b in their env). The image is digest-pinned.
apiVersion: ax.io/v1alpha1
kind: Task
metadata:
name: verify
atespace: default
annotations:
openultrasast.io/model: deepseek-flash
spec:
image: "localhost:5001/ousast-runner@sha256:318cbe019c1155b43fe59e47368d99e78f6f6011b7c822292251de53cf567bf3"
command: ["verify"]
resources:
requests:
cpu: "250m"
memory: "384Mi"
limits:
cpu: "1"
memory: "1Gi"
@@ -0,0 +1,16 @@
# generated by `ousast plane workspaces benchmarks/independent/population-v2.toml --validation-set ~/ousast-results/independent-v2-sets/validation.json --candidates ~/ousast-results/independent-v2-modelsinks --triage ~/ousast-results/independent-v2-batched-check/scans --run validation-46`; do not edit, regenerate.
apiVersion: ax.io/v1alpha1
kind: Workspace
metadata:
name: budibase-mongo-template-nosqli-inputs
atespace: default
spec:
files:
- path: candidates.json
content: "{\n \"candidates\": [\n [\n \"packages/server/src/integrations/mongodb.ts\",\n \"read\",\n 539\n ],\n [\n \"packages/server/src/sdk/workspace/queries/queries.ts\",\n \"enrichContext\",\n 136\n ]\n ],\n \"family\": \"injection\",\n \"id\": \"budibase-mongo-template-nosqli\"\n}\n"
- path: functions.json
content: "[\n {\n \"function\": \"read\",\n \"line\": 539,\n \"path\": \"packages/server/src/integrations/mongodb.ts\"\n },\n {\n \"function\": \"enrichContext\",\n \"line\": 136,\n \"path\": \"packages/server/src/sdk/workspace/queries/queries.ts\"\n }\n]\n"
- path: case.json
content: "{\n \"family\": \"injection\",\n \"id\": \"budibase-mongo-template-nosqli\",\n \"sites\": [\n \"packages/server/src/sdk/workspace/queries/queries.ts::enrichContext\",\n \"packages/server/src/integrations/mongodb.ts::read\"\n ]\n}\n"
- path: triage.json
content: "{\n \"candidates\": [\n [\n \"packages/server/src/integrations/mongodb.ts\",\n \"read\",\n 539\n ],\n [\n \"packages/server/src/sdk/workspace/queries/queries.ts\",\n \"enrichContext\",\n 136\n ]\n ],\n \"kept\": [\n [\n \"packages/server/src/integrations/mongodb.ts\",\n \"read\",\n 539\n ],\n [\n \"packages/server/src/sdk/workspace/queries/queries.ts\",\n \"enrichContext\",\n 136\n ]\n ],\n \"triage\": {\n \"packages/server/src/integrations/mongodb.ts::read\": \"request\",\n \"packages/server/src/sdk/workspace/queries/queries.ts::enrichContext\": \"parameter\"\n }\n}\n"
@@ -0,0 +1,14 @@
# generated by `ousast plane workspaces benchmarks/independent/population-v2.toml --validation-set ~/ousast-results/independent-v2-sets/validation.json --candidates ~/ousast-results/independent-v2-modelsinks --triage ~/ousast-results/independent-v2-batched-check/scans --run validation-46`; do not edit, regenerate.
apiVersion: ax.io/v1alpha1
kind: Workspace
metadata:
name: budibase-mongo-template-nosqli-vulnerable
atespace: default
annotations:
openultrasast.io/git-commits: repo=b7e63df737eede85d951aa9665b0c0778ece7ccb
spec:
git:
- name: repo
repo: https://github.com/Budibase/budibase
dir: repo
depth: 1
@@ -0,0 +1,16 @@
# generated by `ousast plane workspaces benchmarks/independent/population-v2.toml --validation-set ~/ousast-results/independent-v2-sets/validation.json --candidates ~/ousast-results/independent-v2-modelsinks --triage ~/ousast-results/independent-v2-batched-check/scans --run validation-46`; do not edit, regenerate.
apiVersion: ax.io/v1alpha1
kind: Workspace
metadata:
name: cct-studio-server-cmdi-inputs
atespace: default
spec:
files:
- path: candidates.json
content: "{\n \"candidates\": [\n [\n \"cli-tool/src/sandbox-server.js\",\n \"checkAndInstallAgent\",\n 280\n ],\n [\n \"cli-tool/src/sandbox-server.js\",\n \"executeLocalTask\",\n 464\n ]\n ],\n \"family\": \"injection\",\n \"id\": \"cct-studio-server-cmdi\"\n}\n"
- path: functions.json
content: "[\n {\n \"function\": \"checkAndInstallAgent\",\n \"line\": 280,\n \"path\": \"cli-tool/src/sandbox-server.js\"\n },\n {\n \"function\": \"executeLocalTask\",\n \"line\": 464,\n \"path\": \"cli-tool/src/sandbox-server.js\"\n }\n]\n"
- path: case.json
content: "{\n \"family\": \"injection\",\n \"id\": \"cct-studio-server-cmdi\",\n \"sites\": [\n \"cli-tool/src/sandbox-server.js::executeLocalTask\",\n \"cli-tool/src/sandbox-server.js::checkAndInstallAgent\"\n ]\n}\n"
- path: triage.json
content: "{\n \"candidates\": [\n [\n \"cli-tool/src/sandbox-server.js\",\n \"checkAndInstallAgent\",\n 280\n ],\n [\n \"cli-tool/src/sandbox-server.js\",\n \"executeLocalTask\",\n 464\n ]\n ],\n \"kept\": [\n [\n \"cli-tool/src/sandbox-server.js\",\n \"checkAndInstallAgent\",\n 280\n ],\n [\n \"cli-tool/src/sandbox-server.js\",\n \"executeLocalTask\",\n 464\n ]\n ],\n \"triage\": {\n \"cli-tool/src/sandbox-server.js::checkAndInstallAgent\": \"parameter\",\n \"cli-tool/src/sandbox-server.js::executeLocalTask\": \"request\"\n }\n}\n"
@@ -0,0 +1,14 @@
# generated by `ousast plane workspaces benchmarks/independent/population-v2.toml --validation-set ~/ousast-results/independent-v2-sets/validation.json --candidates ~/ousast-results/independent-v2-modelsinks --triage ~/ousast-results/independent-v2-batched-check/scans --run validation-46`; do not edit, regenerate.
apiVersion: ax.io/v1alpha1
kind: Workspace
metadata:
name: cct-studio-server-cmdi-vulnerable
atespace: default
annotations:
openultrasast.io/git-commits: repo=acdb5893412a81eaec9862ee24a4613bf296ab45
spec:
git:
- name: repo
repo: https://github.com/davila7/claude-code-templates
dir: repo
depth: 1
@@ -0,0 +1,16 @@
# generated by `ousast plane workspaces benchmarks/independent/population-v2.toml --validation-set ~/ousast-results/independent-v2-sets/validation.json --candidates ~/ousast-results/independent-v2-modelsinks --triage ~/ousast-results/independent-v2-batched-check/scans --run validation-46`; do not edit, regenerate.
apiVersion: ax.io/v1alpha1
kind: Workspace
metadata:
name: contextforge-prompt-ssti-inputs
atespace: default
spec:
files:
- path: candidates.json
content: "{\n \"candidates\": [\n [\n \"mcpgateway/services/prompt_service.py\",\n \"_compile_jinja_template\",\n 106\n ],\n [\n \"mcpgateway/services/prompt_service.py\",\n \"_render_template\",\n 2892\n ]\n ],\n \"family\": \"injection\",\n \"id\": \"contextforge-prompt-ssti\"\n}\n"
- path: functions.json
content: "[\n {\n \"function\": \"_compile_jinja_template\",\n \"line\": 106,\n \"path\": \"mcpgateway/services/prompt_service.py\"\n },\n {\n \"function\": \"_render_template\",\n \"line\": 2892,\n \"path\": \"mcpgateway/services/prompt_service.py\"\n }\n]\n"
- path: case.json
content: "{\n \"family\": \"injection\",\n \"id\": \"contextforge-prompt-ssti\",\n \"sites\": [\n \"mcpgateway/services/prompt_service.py::_render_template\",\n \"mcpgateway/services/prompt_service.py::_compile_jinja_template\"\n ]\n}\n"
- path: triage.json
content: "{\n \"candidates\": [\n [\n \"mcpgateway/services/prompt_service.py\",\n \"_compile_jinja_template\",\n 106\n ],\n [\n \"mcpgateway/services/prompt_service.py\",\n \"_render_template\",\n 2892\n ]\n ],\n \"kept\": [\n [\n \"mcpgateway/services/prompt_service.py\",\n \"_compile_jinja_template\",\n 106\n ],\n [\n \"mcpgateway/services/prompt_service.py\",\n \"_render_template\",\n 2892\n ]\n ],\n \"triage\": {\n \"mcpgateway/services/prompt_service.py::_compile_jinja_template\": \"stored\",\n \"mcpgateway/services/prompt_service.py::_render_template\": \"stored\"\n }\n}\n"
@@ -0,0 +1,14 @@
# generated by `ousast plane workspaces benchmarks/independent/population-v2.toml --validation-set ~/ousast-results/independent-v2-sets/validation.json --candidates ~/ousast-results/independent-v2-modelsinks --triage ~/ousast-results/independent-v2-batched-check/scans --run validation-46`; do not edit, regenerate.
apiVersion: ax.io/v1alpha1
kind: Workspace
metadata:
name: contextforge-prompt-ssti-vulnerable
atespace: default
annotations:
openultrasast.io/git-commits: repo=0f8e0ad679f1fff685f486e17f642ac863c8ca9e
spec:
git:
- name: repo
repo: https://github.com/IBM/mcp-context-forge
dir: repo
depth: 1
@@ -0,0 +1,16 @@
# generated by `ousast plane workspaces benchmarks/independent/population-v2.toml --validation-set ~/ousast-results/independent-v2-sets/validation.json --candidates ~/ousast-results/independent-v2-modelsinks --triage ~/ousast-results/independent-v2-batched-check/scans --run validation-46`; do not edit, regenerate.
apiVersion: ax.io/v1alpha1
kind: Workspace
metadata:
name: froxlor-admin-ip-second-order-sqli-inputs
atespace: default
spec:
files:
- path: candidates.json
content: "{\n \"candidates\": [\n [\n \"lib/Froxlor/Api/Commands/Domains.php\",\n \"validateIpAddresses\",\n 1050\n ],\n [\n \"lib/Froxlor/Api/Commands/IpsAndPorts.php\",\n \"listing\",\n 76\n ],\n [\n \"lib/Froxlor/Api/Commands/IpsAndPorts.php\",\n \"listingCount\",\n 108\n ]\n ],\n \"family\": \"injection\",\n \"id\": \"froxlor-admin-ip-second-order-sqli\"\n}\n"
- path: functions.json
content: "[\n {\n \"function\": \"validateIpAddresses\",\n \"line\": 1050,\n \"path\": \"lib/Froxlor/Api/Commands/Domains.php\"\n },\n {\n \"function\": \"listing\",\n \"line\": 76,\n \"path\": \"lib/Froxlor/Api/Commands/IpsAndPorts.php\"\n },\n {\n \"function\": \"listingCount\",\n \"line\": 108,\n \"path\": \"lib/Froxlor/Api/Commands/IpsAndPorts.php\"\n }\n]\n"
- path: case.json
content: "{\n \"family\": \"injection\",\n \"id\": \"froxlor-admin-ip-second-order-sqli\",\n \"sites\": [\n \"lib/Froxlor/Api/Commands/IpsAndPorts.php::listing\",\n \"lib/Froxlor/Api/Commands/IpsAndPorts.php::listingCount\",\n \"lib/Froxlor/Api/Commands/Domains.php::validateIpAddresses\"\n ]\n}\n"
- path: triage.json
content: "{\n \"candidates\": [\n [\n \"lib/Froxlor/Api/Commands/Domains.php\",\n \"validateIpAddresses\",\n 1050\n ],\n [\n \"lib/Froxlor/Api/Commands/IpsAndPorts.php\",\n \"listing\",\n 76\n ],\n [\n \"lib/Froxlor/Api/Commands/IpsAndPorts.php\",\n \"listingCount\",\n 108\n ]\n ],\n \"kept\": [\n [\n \"lib/Froxlor/Api/Commands/Domains.php\",\n \"validateIpAddresses\",\n 1050\n ],\n [\n \"lib/Froxlor/Api/Commands/IpsAndPorts.php\",\n \"listing\",\n 76\n ],\n [\n \"lib/Froxlor/Api/Commands/IpsAndPorts.php\",\n \"listingCount\",\n 108\n ]\n ],\n \"triage\": {\n \"lib/Froxlor/Api/Commands/Domains.php::validateIpAddresses\": \"parameter\",\n \"lib/Froxlor/Api/Commands/IpsAndPorts.php::listing\": \"request\",\n \"lib/Froxlor/Api/Commands/IpsAndPorts.php::listingCount\": \"request\"\n }\n}\n"
@@ -0,0 +1,14 @@
# generated by `ousast plane workspaces benchmarks/independent/population-v2.toml --validation-set ~/ousast-results/independent-v2-sets/validation.json --candidates ~/ousast-results/independent-v2-modelsinks --triage ~/ousast-results/independent-v2-batched-check/scans --run validation-46`; do not edit, regenerate.
apiVersion: ax.io/v1alpha1
kind: Workspace
metadata:
name: froxlor-admin-ip-second-order-sqli-vulnerable
atespace: default
annotations:
openultrasast.io/git-commits: repo=9bf03de643a2edee4642bfc6c94db1f05253da02
spec:
git:
- name: repo
repo: https://github.com/froxlor/froxlor
dir: repo
depth: 1
@@ -0,0 +1,16 @@
# generated by `ousast plane workspaces benchmarks/independent/population-v2.toml --validation-set ~/ousast-results/independent-v2-sets/validation.json --candidates ~/ousast-results/independent-v2-modelsinks --triage ~/ousast-results/independent-v2-batched-check/scans --run validation-46`; do not edit, regenerate.
apiVersion: ax.io/v1alpha1
kind: Workspace
metadata:
name: fuxa-tdengine-escape-sqli-inputs
atespace: default
spec:
files:
- path: candidates.json
content: "{\n \"candidates\": [\n [\n \"server/runtime/storage/tdengine/index.js\",\n \"getDaqValue\",\n 89\n ]\n ],\n \"family\": \"injection\",\n \"id\": \"fuxa-tdengine-escape-sqli\"\n}\n"
- path: functions.json
content: "[\n {\n \"function\": \"getDaqValue\",\n \"line\": 89,\n \"path\": \"server/runtime/storage/tdengine/index.js\"\n }\n]\n"
- path: case.json
content: "{\n \"family\": \"injection\",\n \"id\": \"fuxa-tdengine-escape-sqli\",\n \"sites\": [\n \"server/runtime/storage/tdengine/index.js::getDaqValue\"\n ]\n}\n"
- path: triage.json
content: "{\n \"candidates\": [\n [\n \"server/runtime/storage/tdengine/index.js\",\n \"getDaqValue\",\n 89\n ]\n ],\n \"kept\": [\n [\n \"server/runtime/storage/tdengine/index.js\",\n \"getDaqValue\",\n 89\n ]\n ],\n \"triage\": {\n \"server/runtime/storage/tdengine/index.js::getDaqValue\": \"parameter\"\n }\n}\n"
@@ -0,0 +1,14 @@
# generated by `ousast plane workspaces benchmarks/independent/population-v2.toml --validation-set ~/ousast-results/independent-v2-sets/validation.json --candidates ~/ousast-results/independent-v2-modelsinks --triage ~/ousast-results/independent-v2-batched-check/scans --run validation-46`; do not edit, regenerate.
apiVersion: ax.io/v1alpha1
kind: Workspace
metadata:
name: fuxa-tdengine-escape-sqli-vulnerable
atespace: default
annotations:
openultrasast.io/git-commits: repo=193a888f8e3f805325072829b1644a2c768c948b
spec:
git:
- name: repo
repo: https://github.com/frangoteam/FUXA
dir: repo
depth: 1
@@ -0,0 +1,16 @@
# generated by `ousast plane workspaces benchmarks/independent/population-v2.toml --validation-set ~/ousast-results/independent-v2-sets/validation.json --candidates ~/ousast-results/independent-v2-modelsinks --triage ~/ousast-results/independent-v2-batched-check/scans --run validation-46`; do not edit, regenerate.
apiVersion: ax.io/v1alpha1
kind: Workspace
metadata:
name: lmdeploy-media-url-ssrf-inputs
atespace: default
spec:
files:
- path: candidates.json
content: "{\n \"candidates\": [\n [\n \"lmdeploy/vl/media/connection.py\",\n \"_load_http_url\",\n 68\n ]\n ],\n \"family\": \"untrusted_destination\",\n \"id\": \"lmdeploy-media-url-ssrf\"\n}\n"
- path: functions.json
content: "[\n {\n \"function\": \"_load_http_url\",\n \"line\": 68,\n \"path\": \"lmdeploy/vl/media/connection.py\"\n }\n]\n"
- path: case.json
content: "{\n \"family\": \"untrusted_destination\",\n \"id\": \"lmdeploy-media-url-ssrf\",\n \"sites\": [\n \"lmdeploy/vl/media/connection.py::_load_http_url\"\n ]\n}\n"
- path: triage.json
content: "{\n \"candidates\": [\n [\n \"lmdeploy/vl/media/connection.py\",\n \"_load_http_url\",\n 68\n ]\n ],\n \"kept\": [\n [\n \"lmdeploy/vl/media/connection.py\",\n \"_load_http_url\",\n 68\n ]\n ],\n \"triage\": {\n \"lmdeploy/vl/media/connection.py::_load_http_url\": \"parameter\"\n }\n}\n"
@@ -0,0 +1,14 @@
# generated by `ousast plane workspaces benchmarks/independent/population-v2.toml --validation-set ~/ousast-results/independent-v2-sets/validation.json --candidates ~/ousast-results/independent-v2-modelsinks --triage ~/ousast-results/independent-v2-batched-check/scans --run validation-46`; do not edit, regenerate.
apiVersion: ax.io/v1alpha1
kind: Workspace
metadata:
name: lmdeploy-media-url-ssrf-vulnerable
atespace: default
annotations:
openultrasast.io/git-commits: repo=71648d239c978452720a6d6692fe914efc8a7b94
spec:
git:
- name: repo
repo: https://github.com/InternLM/lmdeploy
dir: repo
depth: 1
@@ -0,0 +1,16 @@
# generated by `ousast plane workspaces benchmarks/independent/population-v2.toml --validation-set ~/ousast-results/independent-v2-sets/validation.json --candidates ~/ousast-results/independent-v2-modelsinks --triage ~/ousast-results/independent-v2-batched-check/scans --run validation-46`; do not edit, regenerate.
apiVersion: ax.io/v1alpha1
kind: Workspace
metadata:
name: medplum-external-auth-open-redirect-inputs
atespace: default
spec:
files:
- path: candidates.json
content: "{\n \"candidates\": [\n [\n \"packages/server/src/auth/external.ts\",\n \"externalCallbackHandler\",\n 166\n ]\n ],\n \"family\": \"untrusted_destination\",\n \"id\": \"medplum-external-auth-open-redirect\"\n}\n"
- path: functions.json
content: "[\n {\n \"function\": \"externalCallbackHandler\",\n \"line\": 166,\n \"path\": \"packages/server/src/auth/external.ts\"\n }\n]\n"
- path: case.json
content: "{\n \"family\": \"untrusted_destination\",\n \"id\": \"medplum-external-auth-open-redirect\",\n \"sites\": [\n \"packages/server/src/auth/external.ts::externalCallbackHandler\"\n ]\n}\n"
- path: triage.json
content: "{\n \"candidates\": [\n [\n \"packages/server/src/auth/external.ts\",\n \"externalCallbackHandler\",\n 166\n ]\n ],\n \"kept\": [\n [\n \"packages/server/src/auth/external.ts\",\n \"externalCallbackHandler\",\n 166\n ]\n ],\n \"triage\": {\n \"packages/server/src/auth/external.ts::externalCallbackHandler\": \"parameter\"\n }\n}\n"
@@ -0,0 +1,14 @@
# generated by `ousast plane workspaces benchmarks/independent/population-v2.toml --validation-set ~/ousast-results/independent-v2-sets/validation.json --candidates ~/ousast-results/independent-v2-modelsinks --triage ~/ousast-results/independent-v2-batched-check/scans --run validation-46`; do not edit, regenerate.
apiVersion: ax.io/v1alpha1
kind: Workspace
metadata:
name: medplum-external-auth-open-redirect-vulnerable
atespace: default
annotations:
openultrasast.io/git-commits: repo=5d4a8654b02aa67c444f96ae1eb5663c09854006
spec:
git:
- name: repo
repo: https://github.com/medplum/medplum
dir: repo
depth: 1
@@ -0,0 +1,31 @@
# generated by `ousast plane workspaces benchmarks/independent/population-v2.toml --validation-set ~/ousast-results/independent-v2-sets/validation.json --candidates ~/ousast-results/independent-v2-modelsinks --triage ~/ousast-results/independent-v2-batched-check/scans --run validation-46`; do not edit, regenerate.
apiVersion: ax.io/v1alpha1
kind: Workspace
metadata:
name: pgadmin-maintenance-sqli-inputs
atespace: default
spec:
files:
- path: candidates.json
content: "{\n \"candidates\": [\n [\n \"web/pgadmin/authenticate/ldap.py\",\n \"login\",\n 169\n ],\n [\n \"web/pgadmin/authenticate/ldap.py\",\n \"search_ldap_user\",\n 288\n ],\n [\n \"web/pgadmin/browser/server_groups/servers/__init__.py\",\n \"create_restore_point\",\n 1881\n ],\n [\n \"web/pgadmin/browser/server_groups/servers/databases/__init__.py\",\n \"_check_rename_db_or_change_table_space\",\n 808\n ],\n [\n \"web/pgadmin/browser/server_groups/servers/databases/__init__.py\",\n \"_fetch_db_details\",\n 831\n ],\n [\n \"web/pgadmin/browser/server_groups/servers/databases/__init__.py\",\n \"create\",\n 761\n ],\n [\n \"web/pgadmin/browser/server_groups/servers/databases/__init__.py\",\n \"delete\",\n 1061\n ],\n [\n \"web/pgadmin/browser/server_groups/servers/databases/__init__.py\",\n \"get_sql\",\n 1107\n ],\n [\n \"web/pgadmin/browser/server_groups/servers/databases/__init__.py\",\n \"update\",\n 936\n\
\ ],\n [\n \"web/pgadmin/browser/server_groups/servers/databases/casts/__init__.py\",\n \"delete\",\n 546\n ],\n [\n \"web/pgadmin/browser/server_groups/servers/databases/dbms_job_scheduler/dbms_jobs/__init__.py\",\n \"_fetch_properties\",\n 362\n ],\n [\n \"web/pgadmin/browser/server_groups/servers/databases/dbms_job_scheduler/dbms_jobs/__init__.py\",\n \"create\",\n 412\n ],\n [\n \"web/pgadmin/browser/server_groups/servers/databases/dbms_job_scheduler/dbms_jobs/__init__.py\",\n \"enable_disable\",\n 662\n ],\n [\n \"web/pgadmin/browser/server_groups/servers/databases/dbms_job_scheduler/dbms_jobs/__init__.py\",\n \"get_job_args_value\",\n 779\n ],\n [\n \"web/pgadmin/browser/server_groups/servers/databases/dbms_job_scheduler/dbms_jobs/__init__.py\",\n \"run_job\",\n 746\n ],\n [\n \"web/pgadmin/browser/server_groups/servers/databases/dbms_job_scheduler/dbms_schedules/__init__.py\",\n \"create\",\n 365\n ],\n [\n \"web/pgadmin/browser/server_groups/servers/databases/dbms_job_scheduler/dbms_schedules/__init__.py\"\
,\n \"msql\",\n 454\n ],\n [\n \"web/pgadmin/browser/server_groups/servers/databases/dbms_job_scheduler/dbms_schedules/__init__.py\",\n \"sql\",\n 492\n ],\n [\n \"web/pgadmin/browser/server_groups/servers/databases/event_triggers/__init__.py\",\n \"msql\",\n 623\n ],\n [\n \"web/pgadmin/browser/server_groups/servers/databases/extensions/__init__.py\",\n \"create\",\n 290\n ],\n [\n \"web/pgadmin/browser/server_groups/servers/databases/extensions/__init__.py\",\n \"delete\",\n 394\n ],\n [\n \"web/pgadmin/browser/server_groups/servers/databases/extensions/utils.py\",\n \"get_extension_details\",\n 30\n ],\n [\n \"web/pgadmin/browser/server_groups/servers/databases/foreign_data_wrappers/__init__.py\",\n \"delete\",\n 601\n ],\n [\n \"web/pgadmin/browser/server_groups/servers/databases/foreign_data_wrappers/foreign_servers/__init__.py\",\n \"create\",\n 464\n ],\n [\n \"web/pgadmin/tools/maintenance/__init__.py\",\n \"\
create_maintenance_job\",\n 222\n ]\n ],\n \"family\": \"injection\",\n \"id\": \"pgadmin-maintenance-sqli\"\n}\n"
- path: functions.json
content: "[\n {\n \"function\": \"login\",\n \"line\": 169,\n \"path\": \"web/pgadmin/authenticate/ldap.py\"\n },\n {\n \"function\": \"search_ldap_user\",\n \"line\": 288,\n \"path\": \"web/pgadmin/authenticate/ldap.py\"\n },\n {\n \"function\": \"create_restore_point\",\n \"line\": 1881,\n \"path\": \"web/pgadmin/browser/server_groups/servers/__init__.py\"\n },\n {\n \"function\": \"_check_rename_db_or_change_table_space\",\n \"line\": 808,\n \"path\": \"web/pgadmin/browser/server_groups/servers/databases/__init__.py\"\n },\n {\n \"function\": \"_fetch_db_details\",\n \"line\": 831,\n \"path\": \"web/pgadmin/browser/server_groups/servers/databases/__init__.py\"\n },\n {\n \"function\": \"create\",\n \"line\": 761,\n \"path\": \"web/pgadmin/browser/server_groups/servers/databases/__init__.py\"\n },\n {\n \"function\": \"delete\",\n \"line\": 1061,\n \"path\": \"web/pgadmin/browser/server_groups/servers/databases/__init__.py\"\n },\n {\n \"function\": \"get_sql\"\
,\n \"line\": 1107,\n \"path\": \"web/pgadmin/browser/server_groups/servers/databases/__init__.py\"\n },\n {\n \"function\": \"update\",\n \"line\": 936,\n \"path\": \"web/pgadmin/browser/server_groups/servers/databases/__init__.py\"\n },\n {\n \"function\": \"delete\",\n \"line\": 546,\n \"path\": \"web/pgadmin/browser/server_groups/servers/databases/casts/__init__.py\"\n },\n {\n \"function\": \"_fetch_properties\",\n \"line\": 362,\n \"path\": \"web/pgadmin/browser/server_groups/servers/databases/dbms_job_scheduler/dbms_jobs/__init__.py\"\n },\n {\n \"function\": \"create\",\n \"line\": 412,\n \"path\": \"web/pgadmin/browser/server_groups/servers/databases/dbms_job_scheduler/dbms_jobs/__init__.py\"\n },\n {\n \"function\": \"enable_disable\",\n \"line\": 662,\n \"path\": \"web/pgadmin/browser/server_groups/servers/databases/dbms_job_scheduler/dbms_jobs/__init__.py\"\n },\n {\n \"function\": \"get_job_args_value\",\n \"line\": 779,\n \"path\": \"web/pgadmin/browser/server_groups/servers/databases/dbms_job_scheduler/dbms_jobs/__init__.py\"\
\n },\n {\n \"function\": \"run_job\",\n \"line\": 746,\n \"path\": \"web/pgadmin/browser/server_groups/servers/databases/dbms_job_scheduler/dbms_jobs/__init__.py\"\n },\n {\n \"function\": \"create\",\n \"line\": 365,\n \"path\": \"web/pgadmin/browser/server_groups/servers/databases/dbms_job_scheduler/dbms_schedules/__init__.py\"\n },\n {\n \"function\": \"msql\",\n \"line\": 454,\n \"path\": \"web/pgadmin/browser/server_groups/servers/databases/dbms_job_scheduler/dbms_schedules/__init__.py\"\n },\n {\n \"function\": \"sql\",\n \"line\": 492,\n \"path\": \"web/pgadmin/browser/server_groups/servers/databases/dbms_job_scheduler/dbms_schedules/__init__.py\"\n },\n {\n \"function\": \"msql\",\n \"line\": 623,\n \"path\": \"web/pgadmin/browser/server_groups/servers/databases/event_triggers/__init__.py\"\n },\n {\n \"function\": \"create\",\n \"line\": 290,\n \"path\": \"web/pgadmin/browser/server_groups/servers/databases/extensions/__init__.py\"\n },\n {\n \"function\"\
: \"delete\",\n \"line\": 394,\n \"path\": \"web/pgadmin/browser/server_groups/servers/databases/extensions/__init__.py\"\n },\n {\n \"function\": \"get_extension_details\",\n \"line\": 30,\n \"path\": \"web/pgadmin/browser/server_groups/servers/databases/extensions/utils.py\"\n },\n {\n \"function\": \"delete\",\n \"line\": 601,\n \"path\": \"web/pgadmin/browser/server_groups/servers/databases/foreign_data_wrappers/__init__.py\"\n },\n {\n \"function\": \"create\",\n \"line\": 464,\n \"path\": \"web/pgadmin/browser/server_groups/servers/databases/foreign_data_wrappers/foreign_servers/__init__.py\"\n },\n {\n \"function\": \"create_maintenance_job\",\n \"line\": 222,\n \"path\": \"web/pgadmin/tools/maintenance/__init__.py\"\n }\n]\n"
- path: case.json
content: "{\n \"family\": \"injection\",\n \"id\": \"pgadmin-maintenance-sqli\",\n \"sites\": [\n \"web/pgadmin/tools/maintenance/__init__.py::create_maintenance_job\"\n ]\n}\n"
- path: triage.json
content: "{\n \"candidates\": [\n [\n \"web/pgadmin/authenticate/ldap.py\",\n \"login\",\n 169\n ],\n [\n \"web/pgadmin/authenticate/ldap.py\",\n \"search_ldap_user\",\n 288\n ],\n [\n \"web/pgadmin/browser/server_groups/servers/__init__.py\",\n \"create_restore_point\",\n 1881\n ],\n [\n \"web/pgadmin/browser/server_groups/servers/databases/__init__.py\",\n \"_check_rename_db_or_change_table_space\",\n 808\n ],\n [\n \"web/pgadmin/browser/server_groups/servers/databases/__init__.py\",\n \"_fetch_db_details\",\n 831\n ],\n [\n \"web/pgadmin/browser/server_groups/servers/databases/__init__.py\",\n \"create\",\n 761\n ],\n [\n \"web/pgadmin/browser/server_groups/servers/databases/__init__.py\",\n \"delete\",\n 1061\n ],\n [\n \"web/pgadmin/browser/server_groups/servers/databases/__init__.py\",\n \"get_ctypes\",\n 651\n ],\n [\n \"web/pgadmin/browser/server_groups/servers/databases/__init__.py\",\n \"get_encodings\",\n\
\ 623\n ],\n [\n \"web/pgadmin/browser/server_groups/servers/databases/__init__.py\",\n \"get_sql\",\n 1107\n ],\n [\n \"web/pgadmin/browser/server_groups/servers/databases/__init__.py\",\n \"update\",\n 936\n ],\n [\n \"web/pgadmin/browser/server_groups/servers/databases/casts/__init__.py\",\n \"delete\",\n 546\n ],\n [\n \"web/pgadmin/browser/server_groups/servers/databases/dbms_job_scheduler/dbms_jobs/__init__.py\",\n \"_fetch_properties\",\n 362\n ],\n [\n \"web/pgadmin/browser/server_groups/servers/databases/dbms_job_scheduler/dbms_jobs/__init__.py\",\n \"create\",\n 412\n ],\n [\n \"web/pgadmin/browser/server_groups/servers/databases/dbms_job_scheduler/dbms_jobs/__init__.py\",\n \"enable_disable\",\n 662\n ],\n [\n \"web/pgadmin/browser/server_groups/servers/databases/dbms_job_scheduler/dbms_jobs/__init__.py\",\n \"get_job_args_value\",\n 779\n ],\n [\n \"web/pgadmin/browser/server_groups/servers/databases/dbms_job_scheduler/dbms_jobs/__init__.py\"\
,\n \"run_job\",\n 746\n ],\n [\n \"web/pgadmin/browser/server_groups/servers/databases/dbms_job_scheduler/dbms_schedules/__init__.py\",\n \"create\",\n 365\n ],\n [\n \"web/pgadmin/browser/server_groups/servers/databases/dbms_job_scheduler/dbms_schedules/__init__.py\",\n \"msql\",\n 454\n ],\n [\n \"web/pgadmin/browser/server_groups/servers/databases/dbms_job_scheduler/dbms_schedules/__init__.py\",\n \"sql\",\n 492\n ],\n [\n \"web/pgadmin/browser/server_groups/servers/databases/event_triggers/__init__.py\",\n \"msql\",\n 623\n ],\n [\n \"web/pgadmin/browser/server_groups/servers/databases/extensions/__init__.py\",\n \"create\",\n 290\n ],\n [\n \"web/pgadmin/browser/server_groups/servers/databases/extensions/__init__.py\",\n \"delete\",\n 394\n ],\n [\n \"web/pgadmin/browser/server_groups/servers/databases/extensions/utils.py\",\n \"get_extension_details\",\n 30\n ],\n [\n \"web/pgadmin/browser/server_groups/servers/databases/foreign_data_wrappers/__init__.py\"\
,\n \"delete\",\n 601\n ],\n [\n \"web/pgadmin/browser/server_groups/servers/databases/foreign_data_wrappers/foreign_servers/__init__.py\",\n \"create\",\n 464\n ],\n [\n \"web/pgadmin/tools/maintenance/__init__.py\",\n \"create_maintenance_job\",\n 222\n ]\n ],\n \"kept\": [\n [\n \"web/pgadmin/authenticate/ldap.py\",\n \"login\",\n 169\n ],\n [\n \"web/pgadmin/authenticate/ldap.py\",\n \"search_ldap_user\",\n 288\n ],\n [\n \"web/pgadmin/browser/server_groups/servers/__init__.py\",\n \"create_restore_point\",\n 1881\n ],\n [\n \"web/pgadmin/browser/server_groups/servers/databases/__init__.py\",\n \"_check_rename_db_or_change_table_space\",\n 808\n ],\n [\n \"web/pgadmin/browser/server_groups/servers/databases/__init__.py\",\n \"_fetch_db_details\",\n 831\n ],\n [\n \"web/pgadmin/browser/server_groups/servers/databases/__init__.py\",\n \"create\",\n 761\n ],\n [\n \"web/pgadmin/browser/server_groups/servers/databases/__init__.py\"\
,\n \"delete\",\n 1061\n ],\n [\n \"web/pgadmin/browser/server_groups/servers/databases/__init__.py\",\n \"get_sql\",\n 1107\n ],\n [\n \"web/pgadmin/browser/server_groups/servers/databases/__init__.py\",\n \"update\",\n 936\n ],\n [\n \"web/pgadmin/browser/server_groups/servers/databases/casts/__init__.py\",\n \"delete\",\n 546\n ],\n [\n \"web/pgadmin/browser/server_groups/servers/databases/dbms_job_scheduler/dbms_jobs/__init__.py\",\n \"_fetch_properties\",\n 362\n ],\n [\n \"web/pgadmin/browser/server_groups/servers/databases/dbms_job_scheduler/dbms_jobs/__init__.py\",\n \"create\",\n 412\n ],\n [\n \"web/pgadmin/browser/server_groups/servers/databases/dbms_job_scheduler/dbms_jobs/__init__.py\",\n \"enable_disable\",\n 662\n ],\n [\n \"web/pgadmin/browser/server_groups/servers/databases/dbms_job_scheduler/dbms_jobs/__init__.py\",\n \"get_job_args_value\",\n 779\n ],\n [\n \"web/pgadmin/browser/server_groups/servers/databases/dbms_job_scheduler/dbms_jobs/__init__.py\"\
,\n \"run_job\",\n 746\n ],\n [\n \"web/pgadmin/browser/server_groups/servers/databases/dbms_job_scheduler/dbms_schedules/__init__.py\",\n \"create\",\n 365\n ],\n [\n \"web/pgadmin/browser/server_groups/servers/databases/dbms_job_scheduler/dbms_schedules/__init__.py\",\n \"msql\",\n 454\n ],\n [\n \"web/pgadmin/browser/server_groups/servers/databases/dbms_job_scheduler/dbms_schedules/__init__.py\",\n \"sql\",\n 492\n ],\n [\n \"web/pgadmin/browser/server_groups/servers/databases/event_triggers/__init__.py\",\n \"msql\",\n 623\n ],\n [\n \"web/pgadmin/browser/server_groups/servers/databases/extensions/__init__.py\",\n \"create\",\n 290\n ],\n [\n \"web/pgadmin/browser/server_groups/servers/databases/extensions/__init__.py\",\n \"delete\",\n 394\n ],\n [\n \"web/pgadmin/browser/server_groups/servers/databases/extensions/utils.py\",\n \"get_extension_details\",\n 30\n ],\n [\n \"web/pgadmin/browser/server_groups/servers/databases/foreign_data_wrappers/__init__.py\"\
,\n \"delete\",\n 601\n ],\n [\n \"web/pgadmin/browser/server_groups/servers/databases/foreign_data_wrappers/foreign_servers/__init__.py\",\n \"create\",\n 464\n ],\n [\n \"web/pgadmin/tools/maintenance/__init__.py\",\n \"create_maintenance_job\",\n 222\n ]\n ],\n \"triage\": {\n \"web/pgadmin/authenticate/ldap.py::login\": \"request\",\n \"web/pgadmin/authenticate/ldap.py::search_ldap_user\": \"request\",\n \"web/pgadmin/browser/server_groups/servers/__init__.py::create_restore_point\": \"request\",\n \"web/pgadmin/browser/server_groups/servers/databases/__init__.py::_check_rename_db_or_change_table_space\": \"request\",\n \"web/pgadmin/browser/server_groups/servers/databases/__init__.py::_fetch_db_details\": \"request\",\n \"web/pgadmin/browser/server_groups/servers/databases/__init__.py::create\": \"request\",\n \"web/pgadmin/browser/server_groups/servers/databases/__init__.py::delete\": \"request\",\n \"web/pgadmin/browser/server_groups/servers/databases/__init__.py::get_ctypes\"\
: \"internal\",\n \"web/pgadmin/browser/server_groups/servers/databases/__init__.py::get_encodings\": \"internal\",\n \"web/pgadmin/browser/server_groups/servers/databases/__init__.py::get_sql\": \"request\",\n \"web/pgadmin/browser/server_groups/servers/databases/__init__.py::update\": \"request\",\n \"web/pgadmin/browser/server_groups/servers/databases/casts/__init__.py::delete\": \"request\",\n \"web/pgadmin/browser/server_groups/servers/databases/dbms_job_scheduler/dbms_jobs/__init__.py::_fetch_properties\": \"parameter\",\n \"web/pgadmin/browser/server_groups/servers/databases/dbms_job_scheduler/dbms_jobs/__init__.py::create\": \"request\",\n \"web/pgadmin/browser/server_groups/servers/databases/dbms_job_scheduler/dbms_jobs/__init__.py::enable_disable\": \"request\",\n \"web/pgadmin/browser/server_groups/servers/databases/dbms_job_scheduler/dbms_jobs/__init__.py::get_job_args_value\": \"stored\",\n \"web/pgadmin/browser/server_groups/servers/databases/dbms_job_scheduler/dbms_jobs/__init__.py::run_job\"\
: \"request\",\n \"web/pgadmin/browser/server_groups/servers/databases/dbms_job_scheduler/dbms_schedules/__init__.py::create\": \"request\",\n \"web/pgadmin/browser/server_groups/servers/databases/dbms_job_scheduler/dbms_schedules/__init__.py::msql\": \"request\",\n \"web/pgadmin/browser/server_groups/servers/databases/dbms_job_scheduler/dbms_schedules/__init__.py::sql\": \"stored\",\n \"web/pgadmin/browser/server_groups/servers/databases/event_triggers/__init__.py::msql\": \"request\",\n \"web/pgadmin/browser/server_groups/servers/databases/extensions/__init__.py::create\": \"request\",\n \"web/pgadmin/browser/server_groups/servers/databases/extensions/__init__.py::delete\": \"request\",\n \"web/pgadmin/browser/server_groups/servers/databases/extensions/utils.py::get_extension_details\": \"parameter\",\n \"web/pgadmin/browser/server_groups/servers/databases/foreign_data_wrappers/__init__.py::delete\": \"request\",\n \"web/pgadmin/browser/server_groups/servers/databases/foreign_data_wrappers/foreign_servers/__init__.py::create\"\
: \"request\",\n \"web/pgadmin/tools/maintenance/__init__.py::create_maintenance_job\": \"request\"\n }\n}\n"
@@ -0,0 +1,14 @@
# generated by `ousast plane workspaces benchmarks/independent/population-v2.toml --validation-set ~/ousast-results/independent-v2-sets/validation.json --candidates ~/ousast-results/independent-v2-modelsinks --triage ~/ousast-results/independent-v2-batched-check/scans --run validation-46`; do not edit, regenerate.
apiVersion: ax.io/v1alpha1
kind: Workspace
metadata:
name: pgadmin-maintenance-sqli-vulnerable
atespace: default
annotations:
openultrasast.io/git-commits: repo=d112dc3b962218efc3613fa727d54f0fc5b1d527
spec:
git:
- name: repo
repo: https://github.com/pgadmin-org/pgadmin4
dir: repo
depth: 1
@@ -0,0 +1,16 @@
# generated by `ousast plane workspaces benchmarks/independent/population-v2.toml --validation-set ~/ousast-results/independent-v2-sets/validation.json --candidates ~/ousast-results/independent-v2-modelsinks --triage ~/ousast-results/independent-v2-batched-check/scans --run validation-46`; do not edit, regenerate.
apiVersion: ax.io/v1alpha1
kind: Workspace
metadata:
name: qwed-sympy-eval-inputs
atespace: default
spec:
files:
- path: candidates.json
content: "{\n \"candidates\": [\n [\n \"src/qwed_new/core/batch.py\",\n \"_verify_item\",\n 239\n ]\n ],\n \"family\": \"injection\",\n \"id\": \"qwed-sympy-eval\"\n}\n"
- path: functions.json
content: "[\n {\n \"function\": \"_verify_item\",\n \"line\": 239,\n \"path\": \"src/qwed_new/core/batch.py\"\n }\n]\n"
- path: case.json
content: "{\n \"family\": \"injection\",\n \"id\": \"qwed-sympy-eval\",\n \"sites\": [\n \"src/qwed_new/api/main.py::verify_math\",\n \"src/qwed_new/core/batch.py::_verify_item\"\n ]\n}\n"
- path: triage.json
content: "{\n \"candidates\": [\n [\n \"src/qwed_new/core/batch.py\",\n \"_verify_item\",\n 239\n ]\n ],\n \"kept\": [\n [\n \"src/qwed_new/core/batch.py\",\n \"_verify_item\",\n 239\n ]\n ],\n \"triage\": {\n \"src/qwed_new/core/batch.py::_verify_item\": \"parameter\"\n }\n}\n"
@@ -0,0 +1,14 @@
# generated by `ousast plane workspaces benchmarks/independent/population-v2.toml --validation-set ~/ousast-results/independent-v2-sets/validation.json --candidates ~/ousast-results/independent-v2-modelsinks --triage ~/ousast-results/independent-v2-batched-check/scans --run validation-46`; do not edit, regenerate.
apiVersion: ax.io/v1alpha1
kind: Workspace
metadata:
name: qwed-sympy-eval-vulnerable
atespace: default
annotations:
openultrasast.io/git-commits: repo=06801f68cbf9c9b5e54cc17f2a61cb2792da7a26
spec:
git:
- name: repo
repo: https://github.com/QWED-AI/qwed-verification
dir: repo
depth: 1
@@ -0,0 +1,16 @@
# generated by `ousast plane workspaces benchmarks/independent/population-v2.toml --validation-set ~/ousast-results/independent-v2-sets/validation.json --candidates ~/ousast-results/independent-v2-modelsinks --triage ~/ousast-results/independent-v2-batched-check/scans --run validation-46`; do not edit, regenerate.
apiVersion: ax.io/v1alpha1
kind: Workspace
metadata:
name: reactpress-findall-column-sqli-inputs
atespace: default
spec:
files:
- path: candidates.json
content: "{\n \"candidates\": [\n [\n \"server/src/modules/article/article.service.ts\",\n \"findAll\",\n 108\n ]\n ],\n \"family\": \"injection\",\n \"id\": \"reactpress-findall-column-sqli\"\n}\n"
- path: functions.json
content: "[\n {\n \"function\": \"findAll\",\n \"line\": 108,\n \"path\": \"server/src/modules/article/article.service.ts\"\n }\n]\n"
- path: case.json
content: "{\n \"family\": \"injection\",\n \"id\": \"reactpress-findall-column-sqli\",\n \"sites\": [\n \"server/src/modules/article/article.service.ts::findAll\"\n ]\n}\n"
- path: triage.json
content: "{\n \"candidates\": [\n [\n \"server/src/modules/article/article.service.ts\",\n \"findAll\",\n 108\n ]\n ],\n \"kept\": [\n [\n \"server/src/modules/article/article.service.ts\",\n \"findAll\",\n 108\n ]\n ],\n \"triage\": {\n \"server/src/modules/article/article.service.ts::findAll\": \"parameter\"\n }\n}\n"
@@ -0,0 +1,14 @@
# generated by `ousast plane workspaces benchmarks/independent/population-v2.toml --validation-set ~/ousast-results/independent-v2-sets/validation.json --candidates ~/ousast-results/independent-v2-modelsinks --triage ~/ousast-results/independent-v2-batched-check/scans --run validation-46`; do not edit, regenerate.
apiVersion: ax.io/v1alpha1
kind: Workspace
metadata:
name: reactpress-findall-column-sqli-vulnerable
atespace: default
annotations:
openultrasast.io/git-commits: repo=c3dd10681b3d2b5e224f7ac647b3769557603975
spec:
git:
- name: repo
repo: https://github.com/fecommunity/reactpress
dir: repo
depth: 1
@@ -0,0 +1,16 @@
# generated by `ousast plane workspaces benchmarks/independent/population-v2.toml --validation-set ~/ousast-results/independent-v2-sets/validation.json --candidates ~/ousast-results/independent-v2-modelsinks --triage ~/ousast-results/independent-v2-batched-check/scans --run validation-46`; do not edit, regenerate.
apiVersion: ax.io/v1alpha1
kind: Workspace
metadata:
name: unleash-addon-webhook-ssrf-inputs
atespace: default
spec:
files:
- path: candidates.json
content: "{\n \"candidates\": [\n [\n \"src/lib/addons/addon.ts\",\n \"fetchRetry\",\n 64\n ]\n ],\n \"family\": \"untrusted_destination\",\n \"id\": \"unleash-addon-webhook-ssrf\"\n}\n"
- path: functions.json
content: "[\n {\n \"function\": \"fetchRetry\",\n \"line\": 64,\n \"path\": \"src/lib/addons/addon.ts\"\n }\n]\n"
- path: case.json
content: "{\n \"family\": \"untrusted_destination\",\n \"id\": \"unleash-addon-webhook-ssrf\",\n \"sites\": [\n \"src/lib/addons/addon.ts::fetchRetry\"\n ]\n}\n"
- path: triage.json
content: "{\n \"candidates\": [\n [\n \"src/lib/addons/addon.ts\",\n \"fetchRetry\",\n 64\n ]\n ],\n \"kept\": [\n [\n \"src/lib/addons/addon.ts\",\n \"fetchRetry\",\n 64\n ]\n ],\n \"triage\": {\n \"src/lib/addons/addon.ts::fetchRetry\": \"parameter\"\n }\n}\n"
@@ -0,0 +1,14 @@
# generated by `ousast plane workspaces benchmarks/independent/population-v2.toml --validation-set ~/ousast-results/independent-v2-sets/validation.json --candidates ~/ousast-results/independent-v2-modelsinks --triage ~/ousast-results/independent-v2-batched-check/scans --run validation-46`; do not edit, regenerate.
apiVersion: ax.io/v1alpha1
kind: Workspace
metadata:
name: unleash-addon-webhook-ssrf-vulnerable
atespace: default
annotations:
openultrasast.io/git-commits: repo=b9f3217d327f24094b4352130baa30387f85cffe
spec:
git:
- name: repo
repo: https://github.com/Unleash/unleash
dir: repo
depth: 1
@@ -0,0 +1,18 @@
# generated by `ousast plane workspaces benchmarks/independent/population-v2.toml --validation-set ~/ousast-results/independent-v2-sets/validation.json --candidates ~/ousast-results/independent-v2-modelsinks --triage ~/ousast-results/independent-v2-batched-check/scans --run validation-46`; do not edit, regenerate.
apiVersion: ax.io/v1alpha1
kind: Workspace
metadata:
name: winml-cli-serve-cors-inputs
atespace: default
spec:
files:
- path: candidates.json
content: "{\n \"candidates\": [],\n \"family\": \"config_secrets\",\n \"id\": \"winml-cli-serve-cors\"\n}\n"
- path: functions.json
content: '[]
'
- path: case.json
content: "{\n \"family\": \"config_secrets\",\n \"id\": \"winml-cli-serve-cors\",\n \"sites\": [\n \"src/winml/modelkit/serve/cli_api.py::<global>\",\n \"src/winml/modelkit/serve/app.py::create_app\"\n ]\n}\n"
- path: triage.json
content: "{\n \"candidates\": [\n [\n \"src/winml/modelkit/serve/cli_api.py\",\n \"<global>\",\n 148\n ]\n ],\n \"kept\": [],\n \"triage\": {\n \"src/winml/modelkit/serve/cli_api.py::<global>\": \"constant\"\n }\n}\n"
@@ -0,0 +1,14 @@
# generated by `ousast plane workspaces benchmarks/independent/population-v2.toml --validation-set ~/ousast-results/independent-v2-sets/validation.json --candidates ~/ousast-results/independent-v2-modelsinks --triage ~/ousast-results/independent-v2-batched-check/scans --run validation-46`; do not edit, regenerate.
apiVersion: ax.io/v1alpha1
kind: Workspace
metadata:
name: winml-cli-serve-cors-vulnerable
atespace: default
annotations:
openultrasast.io/git-commits: repo=02179d185f0e3ac23518236b5ca1f61fd37ef680
spec:
git:
- name: repo
repo: https://github.com/microsoft/winml-cli
dir: repo
depth: 1
@@ -0,0 +1,16 @@
# generated by `ousast plane workspaces benchmarks/independent/population-v2.toml --validation-set ~/ousast-results/independent-v2-sets/validation.json --candidates ~/ousast-results/independent-v2-modelsinks --triage ~/ousast-results/independent-v2-batched-check/scans --run validation-46`; do not edit, regenerate.
apiVersion: ax.io/v1alpha1
kind: Workspace
metadata:
name: wp-directorist-avatar-ssrf-inputs
atespace: default
spec:
files:
- path: candidates.json
content: "{\n \"candidates\": [\n [\n \"includes/rest-api/functions.php\",\n \"directorist_rest_upload_image_from_url\",\n 115\n ]\n ],\n \"family\": \"untrusted_destination\",\n \"id\": \"wp-directorist-avatar-ssrf\"\n}\n"
- path: functions.json
content: "[\n {\n \"function\": \"directorist_rest_upload_image_from_url\",\n \"line\": 115,\n \"path\": \"includes/rest-api/functions.php\"\n }\n]\n"
- path: case.json
content: "{\n \"family\": \"untrusted_destination\",\n \"id\": \"wp-directorist-avatar-ssrf\",\n \"sites\": [\n \"includes/rest-api/functions.php::directorist_rest_upload_image_from_url\"\n ]\n}\n"
- path: triage.json
content: "{\n \"candidates\": [\n [\n \"includes/rest-api/functions.php\",\n \"directorist_rest_upload_image_from_url\",\n 115\n ]\n ],\n \"kept\": [\n [\n \"includes/rest-api/functions.php\",\n \"directorist_rest_upload_image_from_url\",\n 115\n ]\n ],\n \"triage\": {\n \"includes/rest-api/functions.php::directorist_rest_upload_image_from_url\": \"parameter\"\n }\n}\n"
@@ -0,0 +1,14 @@
# generated by `ousast plane workspaces benchmarks/independent/population-v2.toml --validation-set ~/ousast-results/independent-v2-sets/validation.json --candidates ~/ousast-results/independent-v2-modelsinks --triage ~/ousast-results/independent-v2-batched-check/scans --run validation-46`; do not edit, regenerate.
apiVersion: ax.io/v1alpha1
kind: Workspace
metadata:
name: wp-directorist-avatar-ssrf-vulnerable
atespace: default
annotations:
openultrasast.io/git-commits: repo=77cfc9bc8b453f97ab7e720330706fa4ef056867
spec:
git:
- name: repo
repo: https://github.com/sovware/directorist
dir: repo
depth: 1
@@ -0,0 +1,16 @@
# generated by `ousast plane workspaces benchmarks/independent/population-v2.toml --validation-set ~/ousast-results/independent-v2-sets/validation.json --candidates ~/ousast-results/independent-v2-modelsinks --triage ~/ousast-results/independent-v2-batched-check/scans --run validation-46`; do not edit, regenerate.
apiVersion: ax.io/v1alpha1
kind: Workspace
metadata:
name: wp-gopay-log-filter-sqli-inputs
atespace: default
spec:
files:
- path: candidates.json
content: "{\n \"candidates\": [\n [\n \"admin/views/log.php\",\n \"<global>\",\n 35\n ]\n ],\n \"family\": \"injection\",\n \"id\": \"wp-gopay-log-filter-sqli\"\n}\n"
- path: functions.json
content: "[\n {\n \"function\": \"<global>\",\n \"line\": 35,\n \"path\": \"admin/views/log.php\"\n }\n]\n"
- path: case.json
content: "{\n \"family\": \"injection\",\n \"id\": \"wp-gopay-log-filter-sqli\",\n \"sites\": [\n \"admin/views/log.php::<global>\"\n ]\n}\n"
- path: triage.json
content: "{\n \"candidates\": [\n [\n \"admin/views/log.php\",\n \"<global>\",\n 35\n ]\n ],\n \"kept\": [\n [\n \"admin/views/log.php\",\n \"<global>\",\n 35\n ]\n ],\n \"triage\": {\n \"admin/views/log.php::<global>\": \"request\"\n }\n}\n"
@@ -0,0 +1,14 @@
# generated by `ousast plane workspaces benchmarks/independent/population-v2.toml --validation-set ~/ousast-results/independent-v2-sets/validation.json --candidates ~/ousast-results/independent-v2-modelsinks --triage ~/ousast-results/independent-v2-batched-check/scans --run validation-46`; do not edit, regenerate.
apiVersion: ax.io/v1alpha1
kind: Workspace
metadata:
name: wp-gopay-log-filter-sqli-vulnerable
atespace: default
annotations:
openultrasast.io/git-commits: repo=626bc8b5f8d33de6eefd921e3a05ed52ac320bcd
spec:
git:
- name: repo
repo: https://github.com/gopaycommunity/gopay-woocommerce-integration
dir: repo
depth: 1
@@ -0,0 +1,16 @@
# generated by `ousast plane workspaces benchmarks/independent/population-v2.toml --validation-set ~/ousast-results/independent-v2-sets/validation.json --candidates ~/ousast-results/independent-v2-modelsinks --triage ~/ousast-results/independent-v2-batched-check/scans --run validation-46`; do not edit, regenerate.
apiVersion: ax.io/v1alpha1
kind: Workspace
metadata:
name: wp-groundhogg-confirm-redirect-inputs
atespace: default
spec:
files:
- path: candidates.json
content: "{\n \"candidates\": [\n [\n \"templates/preferences.php\",\n \"<global>\",\n 904\n ]\n ],\n \"family\": \"untrusted_destination\",\n \"id\": \"wp-groundhogg-confirm-redirect\"\n}\n"
- path: functions.json
content: "[\n {\n \"function\": \"<global>\",\n \"line\": 904,\n \"path\": \"templates/preferences.php\"\n }\n]\n"
- path: case.json
content: "{\n \"family\": \"untrusted_destination\",\n \"id\": \"wp-groundhogg-confirm-redirect\",\n \"sites\": [\n \"templates/preferences.php::<global>\"\n ]\n}\n"
- path: triage.json
content: "{\n \"candidates\": [\n [\n \"templates/preferences.php\",\n \"<global>\",\n 904\n ]\n ],\n \"kept\": [\n [\n \"templates/preferences.php\",\n \"<global>\",\n 904\n ]\n ],\n \"triage\": {\n \"templates/preferences.php::<global>\": \"request\"\n }\n}\n"
@@ -0,0 +1,14 @@
# generated by `ousast plane workspaces benchmarks/independent/population-v2.toml --validation-set ~/ousast-results/independent-v2-sets/validation.json --candidates ~/ousast-results/independent-v2-modelsinks --triage ~/ousast-results/independent-v2-batched-check/scans --run validation-46`; do not edit, regenerate.
apiVersion: ax.io/v1alpha1
kind: Workspace
metadata:
name: wp-groundhogg-confirm-redirect-vulnerable
atespace: default
annotations:
openultrasast.io/git-commits: repo=9472a1dd79d4556c40eece501a61930793f170d3
spec:
git:
- name: repo
repo: https://github.com/groundhoggwp/groundhogg
dir: repo
depth: 1
+23
View File
@@ -251,6 +251,11 @@ def main(argv: list[str] | None = None) -> int:
plane_ws = plane_sub.add_parser("workspaces", help="one Workspace manifest per case pin of a population file") plane_ws = plane_sub.add_parser("workspaces", help="one Workspace manifest per case pin of a population file")
plane_ws.add_argument("population", type=Path) plane_ws.add_argument("population", type=Path)
plane_ws.add_argument("--out", type=Path, default=Path("plane/workspaces")) plane_ws.add_argument("--out", type=Path, default=Path("plane/workspaces"))
plane_ws.add_argument("--validation-set", type=Path, help="JSON {case: [[path, function], ...]}: emit that set's increment instead")
plane_ws.add_argument("--candidates", type=Path, help="with --validation-set: per-case candidate records (independent-v2-modelsinks)")
plane_ws.add_argument("--triage", type=Path, help="with --validation-set: recorded batched-check scans (<case>--vulnerable_a.jsonl)")
plane_ws.add_argument("--run", default="validation-46", help="with --validation-set: the Run name")
plane_ws.add_argument("--plane", type=Path, default=Path("plane"), help="with --validation-set: the manifest root")
args = parser.parse_args(argv) args = parser.parse_args(argv)
# Diagnosis needs the stage costs, and nothing configures logging, so the default root level of # Diagnosis needs the stage costs, and nothing configures logging, so the default root level of
@@ -1303,6 +1308,8 @@ def _plane(args: argparse.Namespace) -> int:
for name, ok, text in checks: for name, ok, text in checks:
print(f"[{'ok' if ok else 'FAIL'}] {name}: {text}") print(f"[{'ok' if ok else 'FAIL'}] {name}: {text}")
return 0 if all(ok for _, ok, _ in checks) else 1 return 0 if all(ok for _, ok, _ in checks) else 1
if args.validation_set is not None:
return _plane_increment(args)
from .plane.workspaces import workspaces from .plane.workspaces import workspaces
written = workspaces(args.population, args.out) written = workspaces(args.population, args.out)
@@ -1310,6 +1317,22 @@ def _plane(args: argparse.Namespace) -> int:
return 0 return 0
def _plane_increment(args: argparse.Namespace) -> int:
from .plane.generate import increment
if args.candidates is None or args.triage is None:
print("--validation-set needs --candidates and --triage", file=sys.stderr)
return 2
home = str(Path.home())
shown = [str(p).replace(home, "~", 1) for p in (args.population, args.validation_set, args.candidates, args.triage)]
command = f"ousast plane workspaces {shown[0]} --validation-set {shown[1]} --candidates {shown[2]} --triage {shown[3]} --run {args.run}"
written = increment(
args.population, args.validation_set, args.candidates, args.triage, plane=args.plane, run_name=args.run, command=command
)
print(f"{len(written)} manifests written under {args.plane} (Run {args.run})")
return 0
def _model_candidates(args: argparse.Namespace) -> int: def _model_candidates(args: argparse.Namespace) -> int:
"""What the candidate enumerator can reach, per family and per slice. No model is called anywhere here. """What the candidate enumerator can reach, per family and per slice. No model is called anywhere here.
+1
View File
@@ -62,6 +62,7 @@ SPEC_OWNED = {
"plane.tasks.verify": "ai-service-plane Req 5.3/2.1-2.3/7.2: the batched hunt with known callers, metered and resumable per file hunt", "plane.tasks.verify": "ai-service-plane Req 5.3/2.1-2.3/7.2: the batched hunt with known callers, metered and resumable per file hunt",
"plane.tasks.agree": "ai-service-plane Req 5.3/2.1: agreement across two verify passes with per-candidate cost, turns and site match", "plane.tasks.agree": "ai-service-plane Req 5.3/2.1: agreement across two verify passes with per-candidate cost, turns and site match",
"plane.reconciler": "ai-service-plane Req 3.1-3.5, 7.3: ax-backed Run execution, status attribution and doctor; `ousast plane`", "plane.reconciler": "ai-service-plane Req 3.1-3.5, 7.3: ax-backed Run execution, status attribution and doctor; `ousast plane`",
"plane.generate": "ai-service-plane task 7: an increment's Workspaces, per-case Tasks and Run from a recorded set",
"plane.workspaces": "ai-service-plane task 4: Workspace manifests per case pin of a population; `ousast plane workspaces`", "plane.workspaces": "ai-service-plane task 4: Workspace manifests per case pin of a population; `ousast plane workspaces`",
"plane.runner": "ai-service-plane Req 4.1-4.4: the ax-task-runner entrypoint (PID 1 of the task image); delivers the output directory", "plane.runner": "ai-service-plane Req 4.1-4.4: the ax-task-runner entrypoint (PID 1 of the task image); delivers the output directory",
} }
+222
View File
@@ -0,0 +1,222 @@
"""Manifests of a recorded measurement as a Run (ai-service-plane task 7).
``ousast plane workspaces <population.toml> --validation-set <set.json> --candidates <dir> --triage <dir>`` writes,
under ``--plane`` (default ``plane/``), everything a Run over the set needs beside the hand-written templates
(``tasks/repo-facts.yaml``, ``tasks/verify.yaml``, ``tasks/agree.yaml``, ``models/*.yaml``):
- ``workspaces/<case>-vulnerable.yaml``: the case's repository at its vulnerable pin (commit in the
``openultrasast.io/git-commits`` annotation, as :mod:`.workspaces` writes it);
- ``workspaces/<case>-inputs.yaml``: a files-only Workspace with the inputs no task produces -- the recorded
candidates (``candidates.json`` in the ``independent-v2-modelsinks`` shape for ``verify`` and ``agree``,
``functions.json`` as ``{path, function, line}`` rows for ``repo-facts``), the case's declared sites
(``case.json`` for ``agree``) and the recorded triage (``triage.json``, for the measurement);
- ``tasks/<run>.yaml``: per case, one Task per template (two for ``verify``: ``OUSAST_PASS=a|b``) binding the two
Workspaces and naming the files as env;
- ``runs/<run>.yaml``: the Run, per case ``facts -> verify a, verify b -> agree``, with budgets.
Why per-case Tasks rather than one Task per step: an ax Task binds its Workspaces by name and a Run entry adds
neither a binding nor env (it names a Task, artifacts and a budget), and ``Run.inputs`` accepts only
``<task>/<artifact>``. So an input that no task produces is a Workspace ``files`` entry, and the case a step works
on is fixed by the Task it runs. One Run covers every case so the measurement has one state and one attribution
table.
Candidates are the set's ``(path, function)`` pairs with the line of the case record, deduplicated the way
``benchmarks/independent/verify_batched.py`` does (sorted, the last line of a repeated pair wins), and filtered
by the recorded triage (the ``kept`` lists of the batched-check scans): ``verify`` has no triage stage, so the
hunts see exactly the candidates the reference hunts saw. Output is a pure function of the inputs.
"""
from __future__ import annotations
import json
import math
import tomllib
from collections.abc import Mapping, Sequence
from dataclasses import dataclass
from pathlib import Path
from typing import Any
import yaml
from .manifests import GIT_COMMITS_ANNOTATION, RUN_API_VERSION, Task, load_manifests
from .reconciler import _ax_name, _doc
from .tasks.verify import MAX_STEPS, units_of
__all__ = ["CaseInputs", "increment", "read_cases", "render"]
REFERENCE_USD_PER_CANDIDATE = 0.022 # two passes: verifier-batched-check-2026-09-29.json cost.usd_per_candidate_two_passes
HEADROOM = 1.5
CALLS_PER_HUNT = MAX_STEPS + 2 # every tool step, the answer, one empty-content retry
ATESPACE = "default"
CASE_PATH = "/workspace/case"
INPUTS_PATH = "/workspace/inputs"
TEMPLATES = ("repo-facts", "verify", "agree")
Candidate = tuple[str, str, int]
@dataclass(frozen=True)
class CaseInputs:
case: Mapping[str, Any]
candidates: tuple[Candidate, ...]
kept: tuple[Candidate, ...]
triage: Mapping[str, str]
recorded_usd: float
def _scan_rows(triage_dir: Path, case_id: str) -> list[dict[str, Any]]:
path = triage_dir / f"{case_id}--vulnerable_a.jsonl"
if not path.is_file():
raise ValueError(f"{case_id}: no recorded triage at {path}")
rows = [json.loads(line) for line in path.read_text(encoding="utf-8").splitlines() if line.strip()]
rows = [r for r in rows if "unverified" not in r]
if not rows:
raise ValueError(f"{path}: no completed file record")
return rows
def read_cases(validation_set: Path, candidates_dir: Path, triage_dir: Path, population: Path) -> list[CaseInputs]:
"""The set's cases in id order, each with its candidates, the triage-kept subset and the recorded cost."""
subset: dict[str, list[list[str]]] = json.loads(validation_set.read_text(encoding="utf-8"))
records = {c["id"]: c for c in tomllib.loads(population.read_text(encoding="utf-8"))["case"]}
cases: list[CaseInputs] = []
for case_id in sorted(subset):
if case_id not in records:
raise ValueError(f"{validation_set}: case {case_id!r} is not in {population}")
record = json.loads((candidates_dir / f"{case_id}.json").read_text(encoding="utf-8"))
unique = {(str(p), str(fn)): (str(p), str(fn), int(ln)) for p, fn, ln in sorted(record["candidates"])}
wanted = [(str(p), str(fn)) for p, fn, *_ in subset[case_id]]
missing = [f"{p}::{fn}" for p, fn in wanted if (p, fn) not in unique]
if missing:
raise ValueError(f"{case_id}: set candidates absent from {candidates_dir / case_id}.json: {missing[:5]}")
wanted_keys = set(wanted)
chosen = [c for key, c in unique.items() if key in wanted_keys]
rows = _scan_rows(triage_dir, case_id)
asked = {(str(c[0]), str(c[1])): (str(c[0]), str(c[1]), int(c[2])) for r in rows for c in r["candidates"]}
if sorted(asked.values()) != sorted(chosen):
raise ValueError(f"{case_id}: the recorded scans asked {sorted(asked.values())[:3]}..., the set gives {chosen[:3]}...")
kept_keys = {(str(r["path"]), str(fn)) for r in rows for fn in r.get("kept", [c[1] for c in r["candidates"]])}
triage = {f"{r['path']}::{fn}": str(label) for r in rows for fn, label in sorted((r.get("triage") or {}).items())}
cases.append(
CaseInputs(
case=records[case_id],
candidates=tuple(chosen),
kept=tuple(c for c in chosen if (c[0], c[1]) in kept_keys),
triage=dict(sorted(triage.items())),
recorded_usd=round(sum(float(r.get("usd") or 0.0) for r in rows), 6),
)
)
return cases
def _dump(header: str, docs: Sequence[Mapping[str, Any]]) -> str:
return header + str(yaml.safe_dump_all(list(docs), sort_keys=False, width=1000))
def _json(payload: object) -> str:
return json.dumps(payload, indent=1, sort_keys=True) + "\n"
def _workspaces(item: CaseInputs) -> tuple[dict[str, Any], dict[str, Any]]:
case = item.case
git = [{"name": "repo", "repo": case["repo"], "dir": "repo", "depth": 1}]
pinned = _doc("Workspace", _ax_name(case["id"], "vulnerable"), {"git": git}, ATESPACE)
pinned["metadata"]["annotations"] = {GIT_COMMITS_ANNOTATION: f"repo={case['vulnerable']}"}
files = {
"candidates.json": _json({"id": case["id"], "family": case["family"], "candidates": [list(c) for c in item.kept]}),
"functions.json": _json([{"path": p, "function": fn, "line": ln} for p, fn, ln in item.kept]),
"case.json": _json({"id": case["id"], "family": case["family"], "sites": list(case.get("sites", []))}),
"triage.json": _json(
{"candidates": [list(c) for c in item.candidates], "kept": [list(c) for c in item.kept], "triage": dict(item.triage)}
),
}
inputs = _doc("Workspace", _ax_name(case["id"], "inputs"), {"files": [{"path": k, "content": v} for k, v in files.items()]}, ATESPACE)
return pinned, inputs
def _task(template: Task, name: str, env: Mapping[str, str], bindings: Sequence[tuple[str, str]]) -> dict[str, Any]:
spec: dict[str, Any] = {}
if template.image:
spec["image"] = template.image
spec["command"] = list(template.command)
spec["env"] = [{"name": e.name, "value": e.value} for e in template.env] + [{"name": k, "value": v} for k, v in env.items()]
if template.resources:
kinds = {kind: values for kind, values in vars(template.resources).items() if values is not None}
spec["resources"] = {kind: {k: v for k, v in vars(values).items() if v is not None} for kind, values in kinds.items()}
spec["workspaces"] = [{"name": n, "path": p} for n, p in bindings]
if template.debug:
spec["debug"] = True
doc = _doc("Task", name, spec, template.metadata.atespace)
if template.metadata.annotations:
doc["metadata"]["annotations"] = dict(template.metadata.annotations)
return doc
def verify_budget(item: CaseInputs) -> dict[str, float | int]:
"""One verify pass: 1.5x its share of the case's recorded two-pass cost (at least the set's per-candidate
average times the case's candidates), rounded up to a cent; calls: every hunt at its step ceiling."""
share = max(item.recorded_usd, REFERENCE_USD_PER_CANDIDATE * len(item.candidates)) / 2
hunts = len(units_of(list(item.kept)))
return {"usd": math.ceil(HEADROOM * share * 100 - 1e-9) / 100, "calls": max(hunts, 1) * CALLS_PER_HUNT}
def render(cases: Sequence[CaseInputs], templates: Mapping[str, Task], run_name: str, command: str) -> dict[str, str]:
"""Relative path under the plane root -> file text, for every generated manifest."""
header = f"# generated by `{command}`; do not edit, regenerate.\n"
out: dict[str, str] = {}
tasks: list[dict[str, Any]] = []
entries: list[dict[str, Any]] = []
for item in cases:
case_id = item.case["id"]
pinned, inputs = _workspaces(item)
for doc in (pinned, inputs):
out[f"workspaces/{doc['metadata']['name']}.yaml"] = _dump(header, [doc])
repo = [(pinned["metadata"]["name"], CASE_PATH), (inputs["metadata"]["name"], INPUTS_PATH)]
on_repo = {"OUSAST_WORKSPACE_DIR": f"{CASE_PATH}/repo"}
facts_env = {**on_repo, "OUSAST_INPUT_CANDIDATES": f"{INPUTS_PATH}/functions.json"}
tasks.append(_task(templates["repo-facts"], f"repo-facts-{case_id}", facts_env, repo))
for label in ("a", "b"):
env = {**on_repo, "OUSAST_INPUT_CANDIDATES": f"{INPUTS_PATH}/candidates.json", "OUSAST_PASS": label}
tasks.append(_task(templates["verify"], f"verify-{label}-{case_id}", env, repo))
agree_env = {
"OUSAST_INPUT_CANDIDATES": f"{INPUTS_PATH}/candidates.json",
"OUSAST_INPUT_SITES": f"{INPUTS_PATH}/case.json",
"OUSAST_CASE_ID": case_id,
}
tasks.append(_task(templates["agree"], f"agree-{case_id}", agree_env, repo[1:]))
free = {"usd": 0, "calls": 0}
facts = {"name": f"{case_id}-facts", "task": f"repo-facts-{case_id}", "outputs": ["facts.json"], "budget": free}
entries.append({**facts, "serialize": "repo-facts"})
for label in ("a", "b"):
entries.append({
"name": f"{case_id}-v{label}", "task": f"verify-{label}-{case_id}", "inputs": {"facts": f"{case_id}-facts/facts.json"},
"outputs": ["units.jsonl", "summary.json"], "budget": verify_budget(item),
}) # fmt: skip
entries.append({
"name": f"{case_id}-agree", "task": f"agree-{case_id}",
"inputs": {"pass_a": f"{case_id}-va/units.jsonl", "pass_b": f"{case_id}-vb/units.jsonl"},
"outputs": ["agreed.json", "disputed.json"], "budget": free,
}) # fmt: skip
out[f"tasks/{run_name}.yaml"] = _dump(header, tasks)
run = {"apiVersion": RUN_API_VERSION, "kind": "Run", "metadata": {"name": run_name}, "spec": {"tasks": entries}}
total = sum(float(e["budget"]["usd"]) for e in entries)
candidates = sum(len(c.candidates) for c in cases)
kept = sum(len(c.kept) for c in cases)
note = f"# {len(cases)} cases, {candidates} candidates ({kept} kept by the recorded triage); usd ceiling {total:.2f}.\n"
out[f"runs/{run_name}.yaml"] = _dump(header + note, [run])
return out
def increment(
population: Path, validation_set: Path, candidates_dir: Path, triage_dir: Path, *, plane: Path, run_name: str, command: str
) -> list[Path]:
"""Write the generated manifests under ``plane`` from the templates in ``plane/tasks``; returns the paths."""
loaded = load_manifests([plane / "tasks" / f"{name}.yaml" for name in TEMPLATES])
files = render(read_cases(validation_set, candidates_dir, triage_dir, population), loaded.tasks, run_name, command)
written: list[Path] = []
for relative, text in files.items():
path = plane / relative
path.parent.mkdir(parents=True, exist_ok=True)
path.write_text(text, encoding="utf-8")
written.append(path)
return written
+174
View File
@@ -0,0 +1,174 @@
"""The increment's manifests under ``plane/`` (ai-service-plane task 7) and their generator."""
from __future__ import annotations
import json
import re
import shutil
import tomllib
from pathlib import Path
import pytest
import yaml
from test_plane_reconciler import AX_FIELDS, non_ax_fields
from openultrasast.model.endpoint import price_of
from openultrasast.plane import reconciler
from openultrasast.plane.budget import prices_from
from openultrasast.plane.generate import TEMPLATES, increment, read_cases, render
from openultrasast.plane.manifests import load_manifests
PLANE = Path("plane")
RUN = PLANE / "runs" / "validation-46.yaml"
POPULATION = Path("benchmarks/independent/population-v2.toml")
RESULTS = Path.home() / "ousast-results"
PIN = "0123456789abcdef0123456789abcdef01234567"
def _mebibytes(quantity: str) -> float:
number, unit = re.fullmatch(r"([0-9.]+)(Mi|Gi)?", quantity).groups() # type: ignore[union-attr]
return float(number) * {"Mi": 1, "Gi": 1024, None: 1 / 2**20}[unit]
def test_every_manifest_under_plane_loads() -> None:
paths = sorted(PLANE.rglob("*.yaml"))
assert len(paths) >= 36, paths
manifests = load_manifests(paths)
assert set(manifests.models) == {"deepseek-flash"}
assert set(TEMPLATES) <= set(manifests.tasks)
assert len(manifests.workspaces) == 30 and set(manifests.runs) == {"validation-46"}
def test_model_prices_are_the_endpoint_prices() -> None:
model = load_manifests([PLANE / "models" / "deepseek-flash.yaml"]).models["deepseek-flash"]
assert model.provider == "deepseek" and model.model == "deepseek-flash"
assert model.secret_key is not None and model.secret_key.key == "DEEPSEEK_API_KEY"
assert prices_from(model.parameters) == price_of("deepseek-flash")
def test_validation_run_resolves_and_renders_every_task(tmp_path: Path) -> None:
run, manifests = reconciler.load_run(RUN)
assert len(run.tasks) == 60
population = {c["id"]: c for c in tomllib.loads(POPULATION.read_text())["case"]}
ax_names: set[str] = set()
for task in manifests.tasks.values():
assert task.image and "@sha256:" in task.image, task.metadata.name
limits = task.resources.limits if task.resources else None
assert limits and limits.cpu == "1" and _mebibytes(limits.memory or "0") <= 1536, task.metadata.name
for entry in run.tasks:
task = manifests.tasks[entry.task]
model = task.metadata.annotations.get(reconciler.MODEL_ANNOTATION)
assert model is None or model in manifests.models
for binding in task.workspaces:
workspace = manifests.workspaces[binding.name]
for name, sha in workspace.pins.items():
case_id = binding.name.removesuffix("-vulnerable")
assert (name, sha) == ("repo", population[case_id]["vulnerable"])
if entry.name.endswith(("-va", "-vb")):
assert model == "deepseek-flash" and entry.budget and entry.budget.usd and entry.budget.calls
env = {e.name: e.value for e in task.env}
assert env["OUSAST_PASS"] == entry.name[-1]
docs = reconciler.render_task(run, entry, manifests, tmp_path, "http://127.0.0.1:1/")
for doc in docs:
assert not non_ax_fields(doc["spec"], AX_FIELDS[doc["kind"]], doc["kind"])
assert set(doc["metadata"]) <= {"name", "atespace"}
assert len(doc["metadata"]["name"]) <= 63, doc["metadata"]["name"]
assert docs[0]["metadata"]["name"] not in ax_names
ax_names.add(docs[0]["metadata"]["name"])
def test_inputs_carry_the_validation_set() -> None:
manifests = load_manifests(sorted((PLANE / "workspaces").glob("*-inputs.yaml")))
assert len(manifests.workspaces) == 15
candidates = kept = 0
for workspace in manifests.workspaces.values():
files = {f.path: json.loads(f.content) for f in workspace.files}
assert set(files) == {"candidates.json", "functions.json", "case.json", "triage.json"}
candidates += len(files["triage.json"]["candidates"])
kept += len(files["candidates.json"]["candidates"])
assert [[r["path"], r["function"], r["line"]] for r in files["functions.json"]] == files["candidates.json"]["candidates"]
assert (candidates, kept) == (46, 43)
def _committed_command() -> str:
first = RUN.read_text().splitlines()[0]
found = re.search(r"`([^`]+)`", first)
assert found, first
return found.group(1)
@pytest.mark.skipif(not (RESULTS / "independent-v2-batched-check" / "scans").is_dir(), reason="recorded results not on this host")
def test_committed_manifests_match_the_generator() -> None:
templates = load_manifests([PLANE / "tasks" / f"{name}.yaml" for name in TEMPLATES]).tasks
cases = read_cases(
RESULTS / "independent-v2-sets" / "validation.json",
RESULTS / "independent-v2-modelsinks",
RESULTS / "independent-v2-batched-check" / "scans",
POPULATION,
)
for relative, text in render(cases, templates, "validation-46", _committed_command()).items():
assert (PLANE / relative).read_text() == text, relative
# --- the generator on a synthetic set ---------------------------------------------------------------------------
def _fixture(root: Path) -> dict[str, Path]:
population = root / "population.toml"
population.write_text(
"\n".join(
f'[[case]]\nid = "{cid}"\nrepo = "https://example.com/{cid}"\nfamily = "injection"\n'
f'vulnerable = "{PIN}"\nsites = ["a.py::run"]\n'
for cid in ("beta", "alpha")
)
)
candidates, scans = root / "cands", root / "scans"
candidates.mkdir()
scans.mkdir()
rows = [["a.py", "run", 9], ["a.py", "run", 3], ["a.py", "helper", 20], ["b.py", "other", 1]]
for cid in ("alpha", "beta"):
(candidates / f"{cid}.json").write_text(json.dumps({"id": cid, "family": "injection", "candidates": rows}))
asked = [["a.py", "helper", 20], ["a.py", "run", 9]]
scan = {"path": "a.py", "candidates": asked, "kept": ["run"], "triage": {"helper": "internal"}}
(scans / f"{cid}--vulnerable_a.jsonl").write_text(json.dumps({**scan, "usd": 0.5}) + "\n")
validation = root / "set.json"
validation.write_text(json.dumps({"beta": [["a.py", "run"], ["a.py", "helper"]], "alpha": [["a.py", "helper"], ["a.py", "run"]]}))
plane = root / "plane"
(plane / "tasks").mkdir(parents=True)
for name in TEMPLATES:
shutil.copy(PLANE / "tasks" / f"{name}.yaml", plane / "tasks")
shutil.copytree(PLANE / "models", plane / "models")
return {"population": population, "set": validation, "candidates": candidates, "scans": scans, "plane": plane}
def _generate(paths: dict[str, Path], plane: Path) -> list[Path]:
return increment(
paths["population"], paths["set"], paths["candidates"], paths["scans"], plane=plane, run_name="check", command="ousast plane test"
)
def test_generator_is_deterministic_and_follows_the_reference(tmp_path: Path) -> None:
paths = _fixture(tmp_path)
other = tmp_path / "again"
shutil.copytree(paths["plane"], other)
first, second = _generate(paths, paths["plane"]), _generate(paths, other)
assert [p.relative_to(paths["plane"]) for p in first] == [p.relative_to(other) for p in second]
assert all(a.read_bytes() == b.read_bytes() for a, b in zip(first, second, strict=True))
assert first[0].read_text().startswith("# generated by `ousast plane test`")
run, manifests = reconciler.load_run(paths["plane"] / "runs" / "check.yaml")
assert [t.name for t in run.tasks][:4] == ["alpha-facts", "alpha-va", "alpha-vb", "alpha-agree"]
inputs = {f.path: json.loads(f.content) for f in manifests.workspaces["alpha-inputs"].files}
assert inputs["candidates.json"]["candidates"] == [["a.py", "run", 9]] # last line of a repeated pair; triage applied
assert inputs["triage.json"]["candidates"] == [["a.py", "helper", 20], ["a.py", "run", 9]]
assert run.task("alpha-va").budget is not None and run.task("alpha-va").budget.usd == 0.38 # 1.5 * 0.5 / 2, cent up
assert yaml.safe_load(first[0].read_text())["metadata"]["annotations"] == {"openultrasast.io/git-commits": f"repo={PIN}"}
def test_generator_refuses_a_set_the_recorded_scans_did_not_ask(tmp_path: Path) -> None:
paths = _fixture(tmp_path)
paths["set"].write_text(json.dumps({"alpha": [["a.py", "run"], ["b.py", "other"]]}))
with pytest.raises(ValueError, match="recorded scans asked"):
_generate(paths, paths["plane"])
(paths["scans"] / "alpha--vulnerable_a.jsonl").unlink()
with pytest.raises(ValueError, match="no recorded triage"):
_generate(paths, paths["plane"])