Promote fix/medium-tier-3 to main: tenant write-scoping + strict-mode centralization#13
Merged
Conversation
Read-side tenant isolation was already enforced (ledger_router filters every query by the caller's JWT tenant_id claim via auth_guard.tenant_scope), but the orchestrator write paths built ExecutionTrace with no tenant_id, so every real audit row defaulted to 'default' and the read filter never isolated real traffic. Close the write half: - pi_agent_chain.tenant_context: an async/thread-local current tenant (ContextVar) + tenant_scope() CM + tenant_from_claims(). - Stamp current_tenant() onto ExecutionTrace at the three agent-execution write sites: PiOrchestrator._compile_and_log_output, ChainExecutionEngine.execute_chain, PipelineDriver._log_trace. - Bind the AUTHENTICATED tenant (from the JWT claim, never the forgeable X-Tenant-ID header) into the contextvar in jwt_validation_middleware, with try/finally reset; propagates to sync handlers via the threadpool context copy. - Correct the stale auth_guard docstring (it claimed reads could not yet be scoped; both read and write isolation are now in place). Tests: tenant_context unit; each write path stamps current_tenant() (defaults to 'default' with no scope); end-to-end middleware binding incl. header-cannot-forge and no-cross-request-leak. Full pi-agent-chain + console + orchestrator suites green; strict-mypy(auth_guard) clean. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…l outliers) Commit 986d17c centralized ~205 per-agent is_strict_mode() copies onto pi_micro_agents.strict_mode.resolve_strict_mode but deferred the outliers. Of the remaining outliers, exactly 6 are real, importable modules that still resolved strict mode inline AND read ~/.antigravitycli/config.json directly — the last copies of the scattered-config footgun: orchestrator/core.py, pi_cot_shadow, pi_prompt_shield, pi_schema_ghost, pi_surplus_orchestrator, utils (parameterized). Each now delegates to resolve_strict_mode(env_key). Behavior-IDENTICAL: the per-file bodies had the same resolution order (env -> ~/.antigravitycli -> repo-local config -> default True) the central resolver implements. Net -106 lines; no remaining direct config reads in these files. Out of scope (documented): the other ~19 "outliers" are dead, unparseable string-literal blob files (SyntaxError on import; excluded from CI parse-gate / coverage) — a separate dead-file cleanup, not strict-mode. pi_graph_consistency _checker keeps its degenerate always-True (fail-closed) resolver as-is. Tests: test_strict_mode_consolidation pins delegation (RED->GREEN via monkeypatch), correct env key, env-var behavior preserved, and no config-path reads remain. Verified: pi-micro-agents (18) + integration (499) + conformance/parity-coverage (288) green; full committed sweep exit 0; ruff clean. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…ping feat(ledger): stamp authenticated tenant on execution-trace writes
…idate-outliers refactor(micro-agents): finish strict-mode centralization (last 6 real outliers)
The committed test from PR #11 wasn't ruff-format-clean; the whole-tree `ruff format --check src tests` step in CI flagged it. Pure formatting, no behavior change. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Promotes the two merged follow-ups on
fix/medium-tier-3tomain. Purely additive vsmain(15 files, +396/−136);mainhas no content this branch lacks (verified:git diff fix/medium-tier-3...origin/mainis empty), so there is nothing to regress.Included
#11 — tenant write-scoping (
feat(ledger): stamp authenticated tenant on execution-trace writes)pi_agent_chain/tenant_context.py(ContextVar +tenant_scope+tenant_from_claims).current_tenant()onExecutionTraceat the 3 write sites (orchestrator/core, chain_engine, pipeline).X-Tenant-IDheader) injwt_validation_middleware.auth_guarddocstring. Closes the write half of the console tenant-isolation finding (read side was already enforced).#12 — strict-mode centralization (
refactor(micro-agents): finish strict-mode centralization)~/.antigravityclidirectly now delegate tostrict_mode.resolve_strict_mode— behavior-identical, net −106 lines. (The other ~19 "outliers" are dead unparseable blob files, out of scope.)Verification (local; CI will re-run here)
On the merged branch state: both PRs' suites pass together (29); regression across micro-agents + integration + console + conformance is green (exit 0);
ruffclean; strict-mypy(auth_guard) clean. This PR tomaintriggers the full CI including the Rust↔Python parity build that can't run locally.🤖 Generated with Claude Code