feat(auto): add intent provenance guard for interviews#1493
Conversation
Add an IntentGuard provenance layer that locks artifact-output contracts from inline goals, blocks generated review-only drift before auto answers mutate the ledger, and surfaces guard status through auto status paths. The guard now also wraps interactive ouroboros_interview answers so generated answers fail closed while explicit human contract changes remain recorded with a warning. Normalize Seed QA feedback into bounded repair constraints so diagnostic/lateral prose does not pollute Seed constraints. The MCP auto handler also treats an explicitly supplied agent runtime as a stage-runtime override so nested authoring handlers preserve their intended backend. Services: shared Affected files: - src/ouroboros/auto/answerer.py - src/ouroboros/auto/intent_guard.py - src/ouroboros/auto/interview_driver.py - src/ouroboros/auto/pipeline.py - src/ouroboros/cli/commands/auto.py - src/ouroboros/cli/commands/status.py - src/ouroboros/mcp/tools/authoring_handlers.py - src/ouroboros/mcp/tools/auto_handler.py - src/ouroboros/mcp/tools/query_handlers.py - tests/integration/auto/test_status_unified.py - tests/unit/auto/test_intent_guard.py - tests/unit/auto/test_ledger_grading_answerer.py - tests/unit/auto/test_pipeline_lateral.py - tests/unit/mcp/tools/test_auto_interview_construction.py - tests/unit/mcp/tools/test_interview_intent_guard.py
There was a problem hiding this comment.
Review — ouroboros-agent[bot]
Verdict: REQUEST_CHANGES
Metadata
| Field | Value |
|### Recovery Notes
First recoverable review artifact generated from codex analysis log.
---|---|
| PR | #1493 |
| HEAD checked | 9bb65c08405480327e0124cb1e07ffabd453cb75 |
| Request ID | req_1781966619_134 |
| Review record | 615c387d-4844-4f8e-8e4e-8f1f2aafb6d2 |
What Improved
- Adds IntentGuard checks to keep generated interview answers from overriding explicit artifact-output intent.
- Seeds inline artifact-output goals into auto user preferences and ledger state.
- Normalizes non-lateral Seed QA feedback to avoid pasting raw QA diagnostics into constraints.
- Surfaces IntentGuard diagnostics in CLI/MCP auto status.
Issue Requirements
| Requirement | Status |
|---|---|
| No linked issue requirement captured | N/A |
Prior Findings Status
No prior bot review metadata or human review comments were present in the supplied artifacts, so no prior concerns were maintained or withdrawn.
Blockers
| # | File:Line | Severity | Finding |
|---|---|---|---|
| 1 | src/ouroboros/auto/pipeline.py:4552 | BLOCKING | The lateral Seed QA repair path still writes constraints prefixed with [seed qa lateral repair attempt ...], but the new IntentGuard explicitly classifies that marker as spec_pollution (src/ouroboros/auto/intent_guard.py:147). A normal successful lateral repair therefore creates a Seed that the new status doctor reports as failed. I reproduced this directly: _seed_with_seed_qa_lateral_feedback(...) produced ('[seed qa lateral repair attempt 1] Decision: ...'), and diagnose_auto_state(..., seed_artifact=repaired.to_dict()) returned {'status': 'fail', ... 'code': 'spec_pollution'}. The lateral path needs the same normalization/removal of diagnostic markers as the deterministic QA feedback path. |
Follow-up Findings
| # | File:Line | Priority | Confidence | Suggestion |
|---|---|---|---|---|
| None. |
Non-blocking Suggestions
| None. |
Test Coverage Notes
- Reviewed PR body, human comments, inline comments, prior bot metadata, changed-files list, unified diff, and affected source paths.
- Ran targeted tests:
SETUPTOOLS_SCM_PRETEND_VERSION=0.0.0 /root/.local/bin/uv run python -m pytest ... -q - Passing targeted coverage: 12 tests across IntentGuard, interview guard, inline goal extraction, answerer behavior, Seed QA feedback normalization, and status rendering.
- Also ran
test_resume_pending_emits_response_diagnostic_event; it passed. - Added direct runtime reproduction for the lateral Seed QA repair/status conflict described above.
Design Notes
The IntentGuard direction fits the project’s spec-first boundary: generated framing should not override user artifact intent. The remaining issue is an internal contract mismatch between the new pollution detector and an existing lateral repair writer.
Design / Roadmap Gate
Affected boundaries include auto interview provenance, Seed QA repair constraints, persisted Seed artifacts, and CLI/MCP status diagnostics. The deterministic QA repair path now strips diagnostic markers, but the lateral repair path still persists a marker that the new status layer treats as terminal pollution, so the changed boundary is not internally consistent.
Directional Notes
Maintainer memory made me focus on preserving explicit user intent, avoiding heuristic drift, and ensuring durable status diagnostics reflect real lifecycle facts rather than self-inflicted false failures.
Test Coverage
- Reviewed PR body, human comments, inline comments, prior bot metadata, changed-files list, unified diff, and affected source paths.
- Ran targeted tests:
SETUPTOOLS_SCM_PRETEND_VERSION=0.0.0 /root/.local/bin/uv run python -m pytest ... -q - Passing targeted coverage: 12 tests across IntentGuard, interview guard, inline goal extraction, answerer behavior, Seed QA feedback normalization, and status rendering.
- Also ran
test_resume_pending_emits_response_diagnostic_event; it passed. - Added direct runtime reproduction for the lateral Seed QA repair/status conflict described above.
Merge Recommendation
Do not merge until lateral Seed QA feedback is normalized or excluded consistently so a successful lateral repair does not immediately produce an IntentGuard spec_pollution failure.
Review-Metadata:
verdict: REQUEST_CHANGES
head_sha: 9bb65c0
request_id: req_1781966619_134
review_profile: memory-aware-zero-trust-v2
advisory_memory_only: true
Reviewed by ouroboros-agent[bot] via Codex deep analysis
|
Fixed the requested blocker in 5a367b1: lateral Seed QA repair now removes prior QA/lateral diagnostic constraints, normalizes persona output into bounded implementation constraints, and has a regression test proving IntentGuard status doctor reports spec_pollution as PASS after lateral repair. Also updated the R-run comparison section so the perf-budget gate has visible filled evidence. |
There was a problem hiding this comment.
Review — ouroboros-agent[bot]
Verdict: REQUEST_CHANGES
Metadata
| Field | Value |
|### Recovery Notes
First recoverable review artifact generated from codex analysis log.
---|---|
| PR | #1493 |
| HEAD checked | 34d9c3d6f402fae1b620f336ae3e94bcd85ac7c0 |
| Request ID | supersede-requeue-pr:1493-34d9c3d |
| Review record | 43314605-99bc-4aa6-bc3d-98b8b087bf25 |
What Improved
- Adds IntentGuard checks for auto/interview contract drift and status visibility.
- Cleans Seed QA/lateral repair constraints so diagnostic prose is not persisted as spec text.
Issue Requirements
| Requirement | Status |
|---|---|
| PR body requirements | N/A |
| Lateral Seed QA repair removes prior QA/lateral diagnostic constraints | Met |
| Persona output is normalized into bounded implementation constraints | Partially met |
IntentGuard status doctor reports spec_pollution as PASS after lateral repair |
Met |
Prior Findings Status
Prior bot reviews existed, and the contributor says a previous blocker was addressed. I did not copy prior findings. The blockers above are based on current source evidence in this snapshot.
Blockers
| # | File:Line | Severity | Finding |
|---|---|---|---|
| 1 | src/ouroboros/mcp/tools/auto_handler.py:436 | BLOCKING | MCP ooo_auto now passes runtime_override=runtime_backend whenever self.agent_runtime_backend is set. In production server wiring, that field is populated from the reflect stage runtime, not from a per-call explicit runtime override (adapter.py:1830-1840). resolve_auto_stage_runtime_plan() only loads orchestrator.runtime_profile.stages when runtime_override is None, so this silently collapses interview/execute/evaluate routing to the reflect/default runtime and can bypass configured per-stage agents. This violates the runtime-profile contract and can route critical auto stages to the wrong backend. |
| 2 | src/ouroboros/auto/pipeline.py:4684 | BLOCKING | Deterministic Seed QA repair now drops arbitrary actionable QA feedback. _normalized_seed_qa_feedback() only maps a small hard-coded keyword set; otherwise it emits the generic “Resolve Seed QA feedback...” constraint. _repair_seed_after_qa() uses this fallback whenever no lateral thinker is wired, exhausted, or fails, so a normal QA result like “missing audit-log retention policy / add 30-day retention constraint” no longer carries the requested repair into the Seed. That regresses the documented fallback behavior and can strand valid Seed QA failures until repair exhaustion. |
Follow-up Findings
| # | File:Line | Priority | Confidence | Suggestion |
|---|---|---|---|---|
| None. |
Non-blocking Suggestions
| None. |
Test Coverage Notes
- Ran
SETUPTOOLS_SCM_PRETEND_VERSION=0.0.0 /root/.local/bin/uv run python -m pytest tests/unit/auto/test_intent_guard.py tests/unit/auto/test_pipeline_lateral.py tests/unit/mcp/tools/test_interview_intent_guard.py tests/unit/mcp/tools/test_auto_interview_construction.py tests/integration/auto/test_status_unified.py: 121 passed. - Missing coverage for MCP
AutoHandler._runhonoring configured runtime profiles whenagent_runtime_backendis present. - Missing coverage that generic, non-keyword Seed QA differences/suggestions remain actionable after normalization.
Design Notes
IntentGuard is a reasonable boundary addition, but the PR also changes runtime routing and Seed QA fallback semantics. Those are infrastructure-critical paths and need contract-preserving fixes.
Design / Roadmap Gate
The affected boundary is not just status display: it changes MCP auto runtime selection and the durable Seed repair loop. Runtime-profile compatibility must remain intact unless a true explicit runtime override is supplied. Seed QA repair must remove diagnostic wrappers without discarding the reviewer’s actionable content.
Directional Notes
Reviewed with attention to runtime routing, replay/status surfaces, and Seed QA persistence because these are recurring high-risk Ouroboros boundaries. Memory was advisory only; blockers above use current source evidence.
Test Coverage
- Ran
SETUPTOOLS_SCM_PRETEND_VERSION=0.0.0 /root/.local/bin/uv run python -m pytest tests/unit/auto/test_intent_guard.py tests/unit/auto/test_pipeline_lateral.py tests/unit/mcp/tools/test_interview_intent_guard.py tests/unit/mcp/tools/test_auto_interview_construction.py tests/integration/auto/test_status_unified.py: 121 passed. - Missing coverage for MCP
AutoHandler._runhonoring configured runtime profiles whenagent_runtime_backendis present. - Missing coverage that generic, non-keyword Seed QA differences/suggestions remain actionable after normalization.
Merge Recommendation
Do not merge yet. Fix MCP runtime override handling so profiles remain authoritative, and preserve bounded/sanitized arbitrary QA feedback in deterministic Seed QA repair.
Review-Metadata:
verdict: REQUEST_CHANGES
head_sha: 34d9c3d
request_id: supersede-requeue-pr:1493-34d9c3d
review_profile: memory-aware-zero-trust-v2
advisory_memory_only: true
Reviewed by ouroboros-agent[bot] via Codex deep analysis
|
Addressed the new review blockers in 22770b6. Runtime routing: AutoHandler now passes runtime_override=None into resolve_auto_stage_runtime_plan so configured stage profiles remain authoritative, while self.agent_runtime_backend stays the fallback/runtime state. Added coverage asserting the resolver receives no override. Seed QA repair: deterministic fallback now preserves sanitized arbitrary actionable QA feedback when no canonical keyword mapping applies, with regression coverage for the audit-log retention example. Local verification includes repo-wide ruff check/format and the review-targeted pytest suites listed in the PR body. |
There was a problem hiding this comment.
Review — ouroboros-agent[bot]
Verdict: REQUEST_CHANGES
Metadata
| Field | Value |
|### Recovery Notes
First recoverable review artifact generated from codex analysis log.
---|---|
| PR | #1493 |
| HEAD checked | 22770b66148fdc0eeef66be36ec942ecd1bcf26b |
| Request ID | req_1781968825_139 |
| Review record | ef34995b-7af0-4e43-9097-d58bc369bc94 |
What Improved
- Adds IntentGuard checks to keep generated interview answers subordinate to the user’s artifact-output contract.
- Seeds inline artifact-output goals into auto user preferences.
- Normalizes Seed QA repair constraints and covers runtime-plan override behavior.
Issue Requirements
| Requirement | Status |
|---|---|
| IntentGuard blocks generated review-only framing over explicit artifact-output intent | Met |
| Inline artifact goals seed outputs/acceptance criteria evidence | Met |
AutoHandler runtime routing passes runtime_override=None so configured stage profiles remain authoritative |
Met |
| Seed QA deterministic fallback preserves arbitrary actionable feedback | Met |
Lateral Seed QA repair removes diagnostic pollution and status doctor reports spec_pollution pass |
Partially met |
| R-run comparison/perf-budget evidence updated | N/A |
Prior Findings Status
Prior bot reviews existed. The previously discussed runtime routing and Seed QA repair areas were rechecked against current source; the runtime override fix is present. The blocking finding above is independently evidenced from current HEAD and is not copied from prior review text.
Blockers
| # | File:Line | Severity | Finding |
|---|---|---|---|
| 1 | src/ouroboros/mcp/tools/authoring_handlers.py:3042 | BLOCKING | The non-plugin interview resume path can crash when called with session_id and no answer after the previous round is already answered. In that branch, the handler skips the answer-recording block where intent_guard_report is assigned at line 2804, generates a new question through the else path at lines 2891-2893, then unconditionally serializes intent_guard_report.to_dict() at line 3042. I verified this path returns Interview failed: cannot access local variable 'intent_guard_report' where it is not associated with a value, so a supported “resume without an answer to receive another question” flow now fails instead of returning the next question. |
Follow-up Findings
| # | File:Line | Priority | Confidence | Suggestion |
|---|---|---|---|---|
| 1 | src/ouroboros/auto/pipeline.py:4631 | Medium | Medium | Consider stripping the body of known diagnostic sections, not just their headings. _clean_seed_qa_repair_text() drops lines like QA differences: but keeps subsequent bullet lines, so lateral output can still carry diagnostic prose into constraints under a normalized prefix. |
Non-blocking Suggestions
| 1 | src/ouroboros/auto/intent_guard.py:91 | Maintainability | Artifact/review-only term lists are duplicated with auto_handler.py; future drift could make extraction and guarding disagree. |
Test Coverage Notes
- Reviewed changed tests and source call paths.
- Ran
SETUPTOOLS_SCM_PRETEND_VERSION=0.0.0 /root/.local/bin/uv run python -m pytest tests/unit/auto/test_intent_guard.py tests/unit/mcp/tools/test_interview_intent_guard.py tests/unit/auto/test_pipeline_lateral.py -q: 64 passed. - Added a direct harness for the uncovered no-answer/no-pending resume path; it reproduced the
intent_guard_reportunbound failure.
Design Notes
The IntentGuard direction fits the project’s spec-first boundary: generated defaults should not outrank user intent. The main regression is an integration-state bug in the MCP interview response shape.
Design / Roadmap Gate
Affected boundaries include MCP interview resume, auto interview answer application, status/query diagnostics, runtime routing, and Seed QA repair persistence. The new intent_guard metadata must be optional or initialized on non-answer question-generation paths; otherwise resume compatibility is broken.
Directional Notes
Maintainer memory pushed focus toward runtime/replay boundaries and avoiding documentation/runtime drift. The blocker is based only on current source and direct execution evidence.
Test Coverage
- Reviewed changed tests and source call paths.
- Ran
SETUPTOOLS_SCM_PRETEND_VERSION=0.0.0 /root/.local/bin/uv run python -m pytest tests/unit/auto/test_intent_guard.py tests/unit/mcp/tools/test_interview_intent_guard.py tests/unit/auto/test_pipeline_lateral.py -q: 64 passed. - Added a direct harness for the uncovered no-answer/no-pending resume path; it reproduced the
intent_guard_reportunbound failure.
Merge Recommendation
Do not merge until the non-plugin interview resume-without-answer path initializes or omits intent_guard_report and has regression coverage for a session with no pending unanswered round.
Review-Metadata:
verdict: REQUEST_CHANGES
head_sha: 22770b6
request_id: req_1781968825_139
review_profile: memory-aware-zero-trust-v2
advisory_memory_only: true
Reviewed by ouroboros-agent[bot] via Codex deep analysis
|
Fixed the no-answer interview resume blocker in 6980ca9. The non-plugin resume-without-answer path now initializes the IntentGuard report as optional and only includes intent_guard metadata when an answer was actually guarded. Added regression coverage for a session whose previous round is already answered and resumes with no answer to receive the next question. Also tightened Seed QA/lateral cleaning so diagnostic section bullets under QA differences/suggestions are stripped, addressing the follow-up note. |
There was a problem hiding this comment.
Review — ouroboros-agent[bot]
Verdict: APPROVE
Metadata
| Field | Value |
|### Recovery Notes
First recoverable review artifact generated from codex analysis log.
---|---|
| PR | #1493 |
| HEAD checked | 6980ca9cc1c5a22249360430922fea08a318e300 |
| Request ID | req_1781969438_141 |
| Review record | 039bbade-d891-4dd4-8745-ec3660f8f713 |
What Improved
- Adds IntentGuard checks to keep generated interview answers from overriding an explicit artifact-output contract.
- Surfaces IntentGuard diagnostics in auto status/query output.
- Normalizes Seed QA/lateral repair feedback so diagnostic prose is not persisted as Seed constraints.
- Preserves stage runtime routing profiles by passing no runtime override to the resolver.
Issue Requirements
| Requirement | Status |
|---|---|
| No linked issue requirement captured | N/A |
Prior Findings Status
Prior bot reviews existed. I rechecked the current source snapshot and did not find the previously discussed blocker themes still present in the changed boundaries.
Blockers
No in-scope blocking findings remained after policy filtering.
Follow-up Findings
| # | File:Line | Priority | Confidence | Suggestion |
|---|---|---|---|---|
| None. |
Non-blocking Suggestions
| None. | | | |
Test Coverage Notes
- Reviewed changed source, unified diff, PR comments, inline comments, and prior-review metadata.
- Ran
SETUPTOOLS_SCM_PRETEND_VERSION=0.0.0 /root/.local/bin/uv run python -m pytest tests/unit/auto/test_intent_guard.py tests/unit/auto/test_pipeline_lateral.py tests/unit/mcp/tools/test_interview_intent_guard.py tests/integration/auto/test_status_unified.py— 83 passed. - Ran
SETUPTOOLS_SCM_PRETEND_VERSION=0.0.0 /root/.local/bin/uv run python -m pytest tests/unit/auto/test_surface.py tests/unit/mcp/tools/test_auto_interview_construction.py tests/unit/auto/test_ledger_grading_answerer.py tests/unit/auto/test_interview_pipeline.py -q— 424 passed.
Design Notes
The PR keeps the new policy checks centralized in intent_guard.py and wires them at the auto/interview boundaries before persistence. The Seed QA repair changes preserve durable Seed shape while stripping diagnostic artifacts.
Design / Roadmap Gate
Checked affected contracts across auto interview answer application, MCP interview answer recording, status/query rendering, runtime stage routing, persisted ledger/Seed artifact diagnosis, and Seed QA repair feedback. The changed paths have targeted regression coverage for conflict blocking, human warning behavior, resume without answer, status metadata, runtime-plan resolver arguments, and diagnostic cleanup.
Directional Notes
Maintainer memory pushed review focus toward runtime/resume boundaries, status truthfulness, and persisted diagnostic/spec pollution. Current blockers would still need direct source evidence; none was found.
Test Coverage
- Reviewed changed source, unified diff, PR comments, inline comments, and prior-review metadata.
- Ran
SETUPTOOLS_SCM_PRETEND_VERSION=0.0.0 /root/.local/bin/uv run python -m pytest tests/unit/auto/test_intent_guard.py tests/unit/auto/test_pipeline_lateral.py tests/unit/mcp/tools/test_interview_intent_guard.py tests/integration/auto/test_status_unified.py— 83 passed. - Ran
SETUPTOOLS_SCM_PRETEND_VERSION=0.0.0 /root/.local/bin/uv run python -m pytest tests/unit/auto/test_surface.py tests/unit/mcp/tools/test_auto_interview_construction.py tests/unit/auto/test_ledger_grading_answerer.py tests/unit/auto/test_interview_pipeline.py -q— 424 passed.
Merge Recommendation
Merge is acceptable. Current HEAD has no blocking findings, and targeted plus adjacent test coverage passes for the modified runtime and persistence surfaces.
Review-Metadata:
verdict: APPROVE
head_sha: 6980ca9
request_id: req_1781969438_141
review_profile: memory-aware-zero-trust-v2
advisory_memory_only: true
Reviewed by ouroboros-agent[bot] via Codex deep analysis
Summary
ooo autoandouroboros_interview: auto/generated answers fail closed, while explicit human contract changes surface as warnings.Changes
outputsandacceptance_criteria.IntentGuardreports withpass/warn/failchecks for auto answers, interactive interview turns, persisted auto status, and spec-pollution diagnostics.Verification
PYTHONPATH=src uv run ruff check src/ouroboros/auto/intent_guard.py src/ouroboros/auto/interview_driver.py src/ouroboros/mcp/tools/authoring_handlers.py src/ouroboros/mcp/tools/auto_handler.py src/ouroboros/cli/commands/auto.py src/ouroboros/cli/commands/status.py src/ouroboros/mcp/tools/query_handlers.py tests/unit/auto/test_intent_guard.py tests/unit/mcp/tools/test_interview_intent_guard.py tests/integration/auto/test_status_unified.pyPYTHONPATH=src uv run pytest tests/unit/auto/test_intent_guard.py tests/unit/mcp/tools/test_interview_intent_guard.py tests/unit/mcp/tools/test_auto_interview_construction.py tests/unit/auto/test_user_preference_and_floor.py tests/unit/auto/test_ledger_grading_answerer.py tests/unit/auto/test_pipeline_lateral.py tests/unit/auto/test_answer_source_log.py tests/integration/auto/test_status_unified.pyPYTHONPATH=src uv run ruff check src/ouroboros/auto/pipeline.py tests/unit/auto/test_pipeline_lateral.py tests/unit/auto/test_interview_pipeline.pyPYTHONPATH=src uv run pytest tests/unit/auto/test_interview_pipeline.py::test_pipeline_repairs_seed_qa_feedback_before_run tests/unit/auto/test_interview_pipeline.py::test_pipeline_seed_qa_lateral_repair_falls_back_when_lateral_errors tests/unit/auto/test_interview_pipeline.py::test_pipeline_blocks_qa_repaired_seed_when_review_no_longer_may_run tests/unit/auto/test_pipeline_lateral.py::test_seed_qa_feedback_does_not_pollute_constraints_with_diagnostics tests/unit/auto/test_pipeline_lateral.py::test_seed_qa_lateral_feedback_does_not_trip_intent_guard_pollution -qPYTHONPATH=src uv run pytest tests/unit/auto/test_intent_guard.py tests/unit/auto/test_pipeline_lateral.py -qPYTHONPATH=src uv run ruff check src testsuv run ruff format --check src/ tests/PYTHONPATH=src uv run pytest tests/unit/auto/test_intent_guard.py tests/unit/auto/test_pipeline_lateral.py tests/unit/mcp/tools/test_interview_intent_guard.py tests/unit/mcp/tools/test_auto_interview_construction.py tests/integration/auto/test_status_unified.py tests/unit/auto/test_surface.py::test_auto_handler_routes_interview_and_execute_from_stage_plan -qPYTHONPATH=src uv run pytest tests/unit/auto/test_intent_guard.py tests/unit/mcp/tools/test_interview_intent_guard.py tests/unit/mcp/tools/test_auto_interview_construction.py tests/unit/auto/test_user_preference_and_floor.py tests/unit/auto/test_ledger_grading_answerer.py tests/unit/auto/test_pipeline_lateral.py tests/unit/auto/test_answer_source_log.py tests/integration/auto/test_status_unified.py -qPYTHONPATH=src uv run pytest tests/unit/auto/test_interview_pipeline.py -qPYTHONPATH=src uv run pytest tests/unit/mcp/tools/test_interview_intent_guard.py tests/unit/auto/test_pipeline_lateral.py::test_seed_qa_lateral_feedback_does_not_trip_intent_guard_pollution -qPYTHONPATH=src uv run pytest tests/unit/auto/test_intent_guard.py tests/unit/mcp/tools/test_interview_intent_guard.py tests/unit/auto/test_pipeline_lateral.py -qR-run comparison
This PR changes auto/interview intent provenance, status surfacing, and Seed QA
repair normalization. It does not change dispatch-loop scheduling, model retry
budgets, or per-round execution cadence, so no live canonical R-run was
captured for this patch set.
Budget compliance: [x] N/A (logic-only guard/normalization changes; no
performance-bearing auto loop path changed)