andrewmusselman opened a new issue, #27:
URL: https://github.com/apache/tooling-gofannon/issues/27
### Summary
Every line printed by an agent appears N times in the api logs when N
parallel passes audit the same ASVS section concurrently. This is not a
framework bug — it's concurrent execution working as designed — but the prints
don't include which pass they belong to, making N simultaneous runs look like a
stutter rather than N distinct runs.
### Details
**Symptom:**
```
Namespaces: ['files:apache/airflow/airflow-core', 'audit_guidance:airflow']
Namespaces: ['files:apache/airflow/airflow-core', 'audit_guidance:airflow']
... (×5 each, every line)
ASVS: 6.1.1
ASVS: 6.1.1
... (×5)
```
All five `Namespaces:` lines flush first, then all five `ASVS:`, then all
five `File scope:`. Classic shape of N coroutines hitting the same `print()` at
the same await boundary.
**Root cause:**
`asvs_orchestrate.py:1613` dispatches all work items in parallel via
`asyncio.gather`. The discovery step allows the same ASVS section to be
assigned to multiple passes (different domain contexts can each consider it
relevant). When that happens, N concurrent `asvs_audit` calls audit the same
section against different file scopes. Each independently prints its setup
block in `asvs_audit.py:393-396`. The count matches `PASS_CONCURRENCY`
(env-overridable, default 4).
The earlier hypothesis about nested stdout-tee in `agent_trace.py` was wrong
— that would produce repeated semantic lines back-to-back, not the observed
`Namespaces:`-then-`ASVS:` interleave. The `_LineBufferingStream`
non-idempotency is still a latent issue but doesn't fire here.
**Impact:**
Unreadable logs during parallel ASVS runs. Operators cannot distinguish
which pass is logging what; debugging interleaved failures is needlessly hard.
### Remediation
Thread the pass name through `input_dict` so each concurrent audit's log
lines are attributable.
In `asvs_orchestrate.py` (~line 1510, single-section dispatch):
```python
"inputText": json.dumps({
"namespaces": namespaces,
"asvs": section_chunk[0],
"passName": pass_name, # NEW — already in scope from line 1502
"includeFiles": include_files,
"domainContext": domain_context,
"severityThreshold": severity_threshold,
"falsePositiveGuidance": false_positive_guidance,
})
```
In `asvs_audit.py` and `asvs_bundle.py` (after `params = json.loads(...)`):
```python
pass_name = params.get("passName", "")
tag = f"[{pass_name}] " if pass_name else ""
print(f"{tag}Namespaces: {namespaces}", flush=True)
print(f"{tag}ASVS: {asvs}", flush=True)
# ... same for the "=== Step N ===" markers
```
### Acceptance Criteria
- [ ] Fixed: `passName` threaded through orchestrator → audit dispatch
- [ ] Fixed: `asvs_audit.py` prefixes prints with `[pass_name]` when present
- [ ] Fixed: `asvs_bundle.py` does the same for bundled audits
- [ ] Test added: parallel run logs distinguishable by pass tag
- [ ] No regression: prints work when `passName` is absent (backward compat)
### References
- File: `apache/tooling-agents:ASVS/agents/asvs_orchestrate.py:1510`
- File: `apache/tooling-agents:ASVS/agents/asvs_audit.py:393-396`
- File: `apache/tooling-agents:ASVS/agents/asvs_bundle.py`
- Tracker: FIXES.md item #8
### Priority
**Medium** - Total change ~10 LOC across two files. Not a framework change;
lives in the ASVS pipeline agents.
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: [email protected]
For queries about this service, please contact Infrastructure at:
[email protected]
---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]