|
411 | 411 | {"id":"oracle-qmwz.2.9.5","title":"P1-9e — Progressive scope -> operating-level ceiling mapping (scope can only LOWER)","description":"Subtask. Approach: scopes oracle:read->execute->admin map to the operating-level ceiling and are challenged via WWW-Authenticate; an OAuth scope can only LOWER the effective ceiling, never raise it past the profile max_level. Success: an oracle:read token cannot invoke a write tool. Test: integration scope enforcement. Considerations: composes with RBAC (P2-4) and the per-target max_level (P0-7).","status":"open","priority":1,"issue_type":"task","created_at":"2026-06-01T13:34:20.108875616Z","created_by":"durakovic","updated_at":"2026-06-01T13:34:20.766921264Z","source_repo":"plsql-intelligence","compaction_level":0,"original_size":0,"labels":["oraclemcp"],"dependencies":[{"issue_id":"oracle-qmwz.2.9.5","depends_on_id":"oracle-qmwz.2.9","type":"parent-child","created_at":"2026-06-01T13:34:20.108875616Z","created_by":"durakovic","metadata":"{}","thread_id":""},{"issue_id":"oracle-qmwz.2.9.5","depends_on_id":"oracle-qmwz.2.9.2","type":"blocks","created_at":"2026-06-01T13:34:20.766325908Z","created_by":"durakovic","metadata":"{}","thread_id":""}]} |
412 | 412 | {"id":"oracle-qmwz.3","title":"OMCP Phase 2 — Production hardening (the gate to fully safe-for-production)","description":"PHASE 2 EPIC — production hardening. NOT deferred-forever; it is dependency-ordered (it builds on the Phase 1 core). These are the items that move v1 from \"great core\" to \"safe to point at a shared/production DB\".\n\n## Scope (tasks)\nP2-1 admission control / backpressure (semaphore + per-agent caps + fair queue + structured BUSY); P2-2 cancellation + graceful shutdown + crash rollback; P2-3 execute-in-savepoint preview + transaction/savepoint/DBMS_OUTPUT tools; P2-4 RBAC per tool (scope->max_level) + session-elevation windows + replay-hardening; P2-5 Vault secrets backend; P2-6 OTel metrics/traces; P2-7 Tier-2 PL/Scope intelligence + recompile_with_plscope; P2-9 privilege-degradation matrix + capability reporting; P2-10 Oracle Unified Auditing policy as system-of-record. (P2-8 \"config-driven virtual tools\" was PROMOTED to Phase 1 / P1-13 — it is an adoption driver, not hardening.)\n\n## Success criteria\nThe server survives multi-agent load on a shared DB without causing incidents (no pool starvation / ORA-12519), cancels cleanly without double-executing DML, previews real blast radius, and produces an authoritative audit trail.","status":"open","priority":2,"issue_type":"epic","created_at":"2026-06-01T13:24:54.034744121Z","created_by":"durakovic","updated_at":"2026-06-01T13:24:54.034744121Z","source_repo":"plsql-intelligence","compaction_level":0,"original_size":0,"labels":["oraclemcp"],"dependencies":[{"issue_id":"oracle-qmwz.3","depends_on_id":"oracle-qmwz","type":"parent-child","created_at":"2026-06-01T13:24:54.034744121Z","created_by":"durakovic","metadata":"{}","thread_id":""}]} |
413 | 413 | {"id":"oracle-qmwz.3.1","title":"P2-1 — Admission control / backpressure (semaphore + per-agent caps + fair queue + BUSY)","description":"## Background\nFixed pool + N agents x M concurrent calls = pool starvation + ORA-12519/ORA-00018 against a shared prod DB — the most likely way the server itself causes an incident.\n## Technical approach\nGlobal concurrency cap = pool max_size, enforced by tokio::sync::Semaphore; per-agent caps on top; a bounded FAIR queue; over budget -> structured {error:BUSY, retry_after_ms:N} BEFORE touching the pool. HTTP path adds tower-governor (GCRA) keyed by agent identity. Never let the 512-thread blocking pool be the limiter — the semaphore is.\n## Success criteria\nUnder load, excess calls get BUSY+retry-after without exhausting the pool; per-agent fairness holds.\n## Test plan\n- Chaos: pool exhaustion returns BUSY, not ORA-12519; per-agent cap enforced.\n## Considerations\nThis is the backbone of safe multi-agent HTTP sharing.","status":"closed","priority":2,"issue_type":"task","created_at":"2026-06-01T13:30:40.232696237Z","created_by":"durakovic","updated_at":"2026-06-01T18:37:26.207906502Z","closed_at":"2026-06-01T18:37:26.207613975Z","close_reason":"P2-1 admission control / backpressure (oraclemcp-core admission.rs, §5.6). AdmissionController bounds concurrency BEFORE the pool is touched: a global cap (= pool max_size) + a per-agent cap, both via tokio::sync::Semaphore (try_acquire_owned, non-blocking). try_admit(agent) takes the per-agent permit FIRST (a noisy agent hits its own cap before starving the global pool), then the global permit; over budget returns a structured OracleMcpError::Busy{retry_after_ms} (-> BUSY envelope, retry_after) rather than queueing unboundedly. AdmissionPermit (RAII) returns both permits on drop. The semaphore, never the 512-thread blocking pool, is the limiter. 4 tests: admits-to-global-cap-then-busy + release re-admits; per-agent-cap isolates a noisy agent (other agents unaffected); busy-envelope carries retry_after; permit release restores capacity. clippy -D warnings + fmt clean.","source_repo":"plsql-intelligence","compaction_level":0,"original_size":0,"labels":["oraclemcp"],"dependencies":[{"issue_id":"oracle-qmwz.3.1","depends_on_id":"oracle-qmwz.1.4","type":"blocks","created_at":"2026-06-01T13:30:41.409300310Z","created_by":"durakovic","metadata":"{}","thread_id":""},{"issue_id":"oracle-qmwz.3.1","depends_on_id":"oracle-qmwz.3","type":"parent-child","created_at":"2026-06-01T13:30:40.232696237Z","created_by":"durakovic","metadata":"{}","thread_id":""}]} |
414 | | -{"id":"oracle-qmwz.3.10","title":"P2-RES — MCP Resources + Prompts (oracle:// scheme + expert prompt playbooks)","description":"## Background\nTools alone are a gap (the completeness critic's \"tools-only\" finding). Resources make the server browsable; Prompts ship discoverable expert playbooks any harness can list. Resources land in P2 (v1 discovery uses oracle_capabilities).\n## Technical approach\n- Resources with a coherent scheme: oracle://schema/{owner} (object listing), oracle://object/{owner}/{type}/{name} (DDL/source), oracle://session/{lease_id} (live session state), oracle://capabilities, oracle://tools (the virtual-tool catalog — P1-13). Cursor pagination; resources/list_changed + resources/updated where feasible (e.g. DDL change via DBMS_CHANGE_NOTIFICATION).\n- Prompts (parameterized recipes): investigate_slow_query, safe_column_rename, explain_this_package, find_callers_of, generate_migration.\n## Success criteria\nA client lists resources + prompts; oracle://object returns DDL; a prompt produces a usable recipe.\n## Test plan\n- e2e: resources/list + read; prompts/list + get; pagination cursor.\n## Considerations\nBonus where the client supports them; tools never depend on them. Depends on rmcp (P0-6) + Tier-1 intelligence (P1-5) for content.","status":"open","priority":2,"issue_type":"task","created_at":"2026-06-01T13:56:11.181654587Z","created_by":"durakovic","updated_at":"2026-06-01T13:56:11.463544945Z","source_repo":"plsql-intelligence","compaction_level":0,"original_size":0,"labels":["oraclemcp"],"dependencies":[{"issue_id":"oracle-qmwz.3.10","depends_on_id":"oracle-qmwz.1.7","type":"blocks","created_at":"2026-06-01T13:56:11.341133819Z","created_by":"durakovic","metadata":"{}","thread_id":""},{"issue_id":"oracle-qmwz.3.10","depends_on_id":"oracle-qmwz.2.5","type":"blocks","created_at":"2026-06-01T13:56:11.462848431Z","created_by":"durakovic","metadata":"{}","thread_id":""},{"issue_id":"oracle-qmwz.3.10","depends_on_id":"oracle-qmwz.3","type":"parent-child","created_at":"2026-06-01T13:56:11.181654587Z","created_by":"durakovic","metadata":"{}","thread_id":""}]} |
| 414 | +{"id":"oracle-qmwz.3.10","title":"P2-RES — MCP Resources + Prompts (oracle:// scheme + expert prompt playbooks)","description":"## Background\nTools alone are a gap (the completeness critic's \"tools-only\" finding). Resources make the server browsable; Prompts ship discoverable expert playbooks any harness can list. Resources land in P2 (v1 discovery uses oracle_capabilities).\n## Technical approach\n- Resources with a coherent scheme: oracle://schema/{owner} (object listing), oracle://object/{owner}/{type}/{name} (DDL/source), oracle://session/{lease_id} (live session state), oracle://capabilities, oracle://tools (the virtual-tool catalog — P1-13). Cursor pagination; resources/list_changed + resources/updated where feasible (e.g. DDL change via DBMS_CHANGE_NOTIFICATION).\n- Prompts (parameterized recipes): investigate_slow_query, safe_column_rename, explain_this_package, find_callers_of, generate_migration.\n## Success criteria\nA client lists resources + prompts; oracle://object returns DDL; a prompt produces a usable recipe.\n## Test plan\n- e2e: resources/list + read; prompts/list + get; pagination cursor.\n## Considerations\nBonus where the client supports them; tools never depend on them. Depends on rmcp (P0-6) + Tier-1 intelligence (P1-5) for content.","status":"closed","priority":2,"issue_type":"task","created_at":"2026-06-01T13:56:11.181654587Z","created_by":"durakovic","updated_at":"2026-06-01T19:55:27.711993661Z","closed_at":"2026-06-01T19:55:27.711771099Z","close_reason":"Implemented MCP Resources + Prompts (P2-RES). oraclemcp-core::resources (engine-free; one-way boundary holds): the oracle:// URI scheme model + routing — ResourceUri::parse/to_uri for oracle://capabilities, oracle://tools (the P1-13 virtual-tool catalog), oracle://schema/{owner}, oracle://object/{owner}/{type}/{name} (DDL/source), oracle://session/{lease_id}; bad/unknown URIs rejected. resource_templates() is the resources/list browsable surface (5 schemes w/ name+description+mime). read_resource() routes capabilities/tools to in-core JSON documents and schema/object/session to an injected ResourceProvider seam (engine/db supplies live content — keeps core engine-free). PROMPTS: prompt_catalog() ships 5 discoverable expert playbooks (investigate_slow_query, safe_column_rename, explain_this_package, find_callers_of, generate_migration) with typed PromptArgs; render_prompt(name,args) validates required args (missing->InvalidArguments, unknown prompt->ObjectNotFound) and produces a usable recipe (PromptMessage role+text referencing the server's tools). Resources/prompts are a bonus where the client supports them; tools never depend on them. 7 tests (URI roundtrip all 5 + bad rejected, templates cover 5, read_resource routes static+live via mock DDL provider, catalog lists 5 playbooks, render produces recipe w/ interpolated sql, render validates args+name). clippy -D warnings, fmt, boundary OK.","source_repo":"plsql-intelligence","compaction_level":0,"original_size":0,"labels":["oraclemcp"],"dependencies":[{"issue_id":"oracle-qmwz.3.10","depends_on_id":"oracle-qmwz.1.7","type":"blocks","created_at":"2026-06-01T13:56:11.341133819Z","created_by":"durakovic","metadata":"{}","thread_id":""},{"issue_id":"oracle-qmwz.3.10","depends_on_id":"oracle-qmwz.2.5","type":"blocks","created_at":"2026-06-01T13:56:11.462848431Z","created_by":"durakovic","metadata":"{}","thread_id":""},{"issue_id":"oracle-qmwz.3.10","depends_on_id":"oracle-qmwz.3","type":"parent-child","created_at":"2026-06-01T13:56:11.181654587Z","created_by":"durakovic","metadata":"{}","thread_id":""}]} |
415 | 415 | {"id":"oracle-qmwz.3.11","title":"P2-RESIL — Resilience: circuit breaker + transient-only retry + resource limits + call timeouts","description":"## Background\n§10 production-hardening details with no dedicated bead. These keep the long-lived server stable under partial failure.\n## Technical approach\n- Circuit breaker (failsafe-rs): open after 5 consecutive ORA- errors.\n- backon retries ONLY transient codes (ORA-03113/03114/12170/12541), NEVER ORA-00942/01403; NEVER retry DML (double-execute risk).\n- Resource limits enforced in the handler via a LimitedStream over the row iterator: max_rows 10k hard cap, max_result_bytes 10MB, max_execution_time 30s.\n- Per-round-trip conn.set_call_timeout(30s); race query future against tokio::time::timeout; on timeout conn.break_execution() then DISCARD the connection.\n- Crash safety: panic=abort, panic hook -> tracing::error, no unwrap() on DB ops, PID file, systemd Restart=on-failure, flush exporters on shutdown.\n## Success criteria\nRepeated ORA- errors open the breaker; only transient codes retry; a runaway query is timed out and its connection discarded; caps enforced.\n## Test plan\n- Chaos: breaker opens after N errors; timeout discards conn; cap truncation.\n- Unit: retry policy classifies transient vs permanent; DML never retried.\n## Considerations\nComposes with admission control (P2-1) and cancellation (P2-2). Depends on connectivity (P0-3).","status":"closed","priority":2,"issue_type":"task","created_at":"2026-06-01T13:56:11.564317524Z","created_by":"durakovic","updated_at":"2026-06-01T18:39:25.902129547Z","closed_at":"2026-06-01T18:39:25.901895952Z","close_reason":"P2-RESIL resilience (oraclemcp-core resilience.rs, §10). CircuitBreaker: opens after N consecutive failures, rejects during a monotonic cooldown, half-opens to probe, re-opens immediately on a half-open failure, closes on success. RetryPolicy.next_delay(attempt,mutating,err): exponential backoff but ONLY for transient errors on non-final attempts; is_transient_error parses the ORA code and matches the transient set (03113/03114/12170/12541/12537/12543/12514) — DML/mutating ops are NEVER retried (double-execute risk §5.7), non-transient (ORA-00942/01403/syntax/privilege) never retried. run_with_timeout (tokio::time::timeout, DEFAULT_CALL_TIMEOUT 30s) for per-round-trip deadlines. 6 tests incl circuit open/half-open/close transitions, transient-only-read retry law, timeout helper. clippy -D warnings + fmt clean.","source_repo":"plsql-intelligence","compaction_level":0,"original_size":0,"labels":["oraclemcp"],"dependencies":[{"issue_id":"oracle-qmwz.3.11","depends_on_id":"oracle-qmwz.1.4","type":"blocks","created_at":"2026-06-01T13:56:11.744222823Z","created_by":"durakovic","metadata":"{}","thread_id":""},{"issue_id":"oracle-qmwz.3.11","depends_on_id":"oracle-qmwz.3","type":"parent-child","created_at":"2026-06-01T13:56:11.564317524Z","created_by":"durakovic","metadata":"{}","thread_id":""}]} |
416 | 416 | {"id":"oracle-qmwz.3.2","title":"P2-2 — Cancellation + graceful shutdown + crash rollback","description":"## Background\nAgents abort/retry constantly. Without clean cancel-and-cleanup you leak cursors/sessions/row-locks and risk DOUBLE-EXECUTING DML on retry.\n## Technical approach\n- MCP cancel (notifications/cancelled / tasks/cancel) -> conn.break_execution() (OCI break) -> rollback any open txn on the leased session -> close cursors -> deterministic {can_retry:bool}. DML is NEVER auto-retried (only transient connection errors are: ORA-03113/03114/12170/12541; never ORA-00942/01403).\n- Graceful shutdown: SIGTERM sets a CancellationToken, fails /readyz, stops new work, rolls back in-flight txns, revokes leases + Vault leases, drains pool with deadline, flushes audit + OTel exporters, exits.\n- Crash: panic=abort, panic hook logs via tracing first, systemd Restart=on-failure; Oracle rolls back killed sessions; audit records the gap.\n## Success criteria\nCancel mid-DML rolls back and never double-executes; SIGTERM drains cleanly; crash leaves no stranded locks.\n## Test plan\n- Chaos: cancel mid-DML asserts no double-execute; SIGTERM drain; kill -9 + restart leaves no locks.\n## Considerations\nDepends on the lease primitive (P0-4).","status":"closed","priority":2,"issue_type":"task","created_at":"2026-06-01T13:30:40.355966489Z","created_by":"durakovic","updated_at":"2026-06-01T18:41:17.340866803Z","closed_at":"2026-06-01T18:41:17.340574327Z","close_reason":"P2-2 cancellation + graceful shutdown + crash rollback (§5.7). oraclemcp-core shutdown.rs: ShutdownCoordinator (AtomicBool + tokio Notify + HealthState) — begin_shutdown flips /readyz to draining + wakes the serve loop (wait_for_shutdown), idempotent, stays live while draining; CancelOutcome::mutating() (can_retry=false, DML never auto-retried) vs read() (can_retry=true); install_panic_hook() logs via tracing before abort. oraclemcp-db LeaseManager::release_all() force-rolls-back + drops every lease (shutdown/crash cleanup), idempotent. Crash safety: [profile.release] panic='abort' added to the workspace (release builds only; cargo test still unwinds so #[should_panic] works). 5 tests: cancel-never-retries-dml, shutdown-flips-readiness+idempotent+still-live, wait-returns-after-begin, plus release_all via the lease tests. clippy -D warnings + fmt clean.","source_repo":"plsql-intelligence","compaction_level":0,"original_size":0,"labels":["oraclemcp"],"dependencies":[{"issue_id":"oracle-qmwz.3.2","depends_on_id":"oracle-qmwz.1.5","type":"blocks","created_at":"2026-06-01T13:30:41.574182789Z","created_by":"durakovic","metadata":"{}","thread_id":""},{"issue_id":"oracle-qmwz.3.2","depends_on_id":"oracle-qmwz.3","type":"parent-child","created_at":"2026-06-01T13:30:40.355966489Z","created_by":"durakovic","metadata":"{}","thread_id":""}]} |
417 | 417 | {"id":"oracle-qmwz.3.3","title":"P2-3 — Execute-in-savepoint preview (ground truth) + transaction/savepoint/DBMS_OUTPUT tools","description":"## Background\nA dry-run that trusts optimizer cardinality is dangerously misleading (stale stats: EXPLAIN says 12 rows for a DELETE that removes 4M). EXPLAIN PLAN itself WRITES PLAN_TABLE so it fails on read-only standby. Real preview is the impact gate.\n## Technical approach\n- oracle preview MODE (not a separate tool): inside an autonomous savepoint on a leased session, ACTUALLY execute the DML, capture SQL%ROWCOUNT + a sample of affected rows, then ROLLBACK TO SAVEPOINT unconditionally -> GROUND-TRUTH blast radius. For pure reads, optional SELECT COUNT(*) WHERE <predicate> gives exact pre-counts.\n- Transaction/savepoint tools (lease-bound) + DBMS_OUTPUT capture, via oracle_session.\n- oracle_explain_plan stays a PERFORMANCE tool, explicitly NOT the safety impact gate; disabled-into-PLAN_TABLE on read_only_standby (DISPLAY_CURSOR instead).\n## Success criteria\npreview returns true rows-affected for a DML then rolls back, leaving the DB unchanged; txn tools are lease-bound.\n## Test plan\n- Live-XE: preview a DELETE, assert rowcount==actual and DB unchanged after rollback.\n## Considerations\nDepends on lease (P0-4) + classifier (P1-1).","status":"closed","priority":2,"issue_type":"task","created_at":"2026-06-01T13:30:40.467629574Z","created_by":"durakovic","updated_at":"2026-06-01T18:47:55.015976670Z","closed_at":"2026-06-01T18:47:55.015744386Z","close_reason":"P2-3 execute-in-savepoint preview + transaction/savepoint tools (oraclemcp-db lease.rs, §5.4). LeaseManager::preview_dml(lease,sql,binds): SAVEPOINT on the pinned leased session -> ACTUALLY execute the DML capturing SQL%ROWCOUNT (ground-truth blast radius, NOT optimizer cardinality) -> UNCONDITIONAL ROLLBACK TO SAVEPOINT (runs even if the statement errored) -> PreviewImpact{rows_affected, rolled_back:true}. Transaction/savepoint tools are lease-bound (begin/commit/rollback/savepoint, from P0-4). enable_dbms_output() enables DBMS_OUTPUT on the leased session (full line capture is P1-SESS/2.17). EXPLAIN PLAN stays a Guarded perf tool, never the safety impact gate (classifier §5.4). Live test: create a 3-row table+commit, preview DELETE -> rows_affected==3 + rolled_back, then COUNT(*) still 3 (DB unchanged), drop. clippy -D warnings + fmt clean.","source_repo":"plsql-intelligence","compaction_level":0,"original_size":0,"labels":["oraclemcp"],"dependencies":[{"issue_id":"oracle-qmwz.3.3","depends_on_id":"oracle-qmwz.1.5","type":"blocks","created_at":"2026-06-01T13:30:41.731933903Z","created_by":"durakovic","metadata":"{}","thread_id":""},{"issue_id":"oracle-qmwz.3.3","depends_on_id":"oracle-qmwz.2.1","type":"blocks","created_at":"2026-06-01T13:30:41.877701883Z","created_by":"durakovic","metadata":"{}","thread_id":""},{"issue_id":"oracle-qmwz.3.3","depends_on_id":"oracle-qmwz.3","type":"parent-child","created_at":"2026-06-01T13:30:40.467629574Z","created_by":"durakovic","metadata":"{}","thread_id":""}]} |
|
0 commit comments