Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
66 commits
Select commit Hold shift + click to select a range
9a079e2
docs(specs): Spec 107 — server edition SSO front door hardened for re…
Dumbris Sep 16, 2026
9fdc58d
test(spec-107): PR-A red tests, server-tag lint job and release notice
Dumbris Sep 16, 2026
43d301d
refactor(serveredition): freeze the latent credential-injection chain…
Dumbris Sep 16, 2026
c255986
fix(storage): enforce the agent-token cap per owner, not per deployme…
Dumbris Sep 16, 2026
3bf4394
fix(spec-107): address adversarial review of PR-A
Dumbris Sep 16, 2026
36e0517
fix(spec-107): codex round 1 for PR-A
Dumbris Sep 16, 2026
e158121
fix(spec-107): codex round 2 for PR-A
Dumbris Sep 16, 2026
03ef19d
fix(spec-107): codex round 3 for PR-A
Dumbris Sep 16, 2026
7a4e8fe
fix(spec-107): codex round 4 for PR-A
Dumbris Sep 16, 2026
fb389e6
Merge origin/main (b1777e865) into 107-a-freeze-cut
Dumbris Sep 16, 2026
14611c9
docs(spec-107): PR-A verification and task ticks
Dumbris Sep 16, 2026
c741f82
docs(roadmap): link PR-A
Dumbris Sep 16, 2026
6cf5427
test(oauthserver): fake OIDC identity provider and server-edition dev…
Dumbris Sep 16, 2026
412dc3a
test(serveredition): red tests for the generic OIDC provider, subject…
Dumbris Sep 16, 2026
c74bfb2
feat(serveredition): generic OIDC provider with JWKS-verified ID toke…
Dumbris Sep 16, 2026
1d88938
test(serveredition): red tests for trusted proxies, public URL, cooki…
Dumbris Sep 16, 2026
07ff5c4
feat(serveredition): front door behind an ingress — public URL, trust…
Dumbris Sep 16, 2026
45d302a
feat(config,telemetry): hot-reload clauses, docs and OAS for the PR-B…
Dumbris Sep 16, 2026
4b8baa3
fix(spec-107): gate fixes for PR-B
Dumbris Sep 16, 2026
516606d
docs(spec-107): PR-B automated-check evidence
Dumbris Sep 16, 2026
fd27d27
fix(spec-107): cross-review round 1 for PR-B
Dumbris Sep 16, 2026
30a93bb
fix(spec-107): cross-review round 2 for PR-B
Dumbris Sep 16, 2026
732329c
fix(spec-107): cross-review round 3 for PR-B
Dumbris Sep 16, 2026
8666dab
fix(spec-107): cross-review round 3 for PR-B
Dumbris Sep 16, 2026
8f2e3d4
fix(spec-107): cross-review round 4 for PR-B
Dumbris Sep 16, 2026
1c976e7
fix(spec-107): cross-review round 5 for PR-B
Dumbris Sep 16, 2026
5ad3a08
fix(spec-107): cross-review round 6 for PR-B
Dumbris Sep 16, 2026
873145b
docs(spec-107): PR-B real-instance verification, gate re-run, task ticks
Dumbris Sep 16, 2026
f3103fd
docs(roadmap): link PR-B
Dumbris Sep 16, 2026
717e580
fix(ci): pull forward the Windows heap-corruption + Pass-2 race fix (…
Dumbris Sep 16, 2026
b4ab0f9
docs(spec-107): record the CI red/fix cycle for PR-B
Dumbris Sep 16, 2026
152f5d5
docs(spec-107): record PR-B CI green
Dumbris Sep 16, 2026
2c35085
fix(spec-107): cross-review round 7 for PR-B
Dumbris Sep 17, 2026
2fdb86b
fix(spec-107): cross-review round 8 for PR-B
Dumbris Sep 17, 2026
1e161d0
test(serveredition): two-fixture non-disclosure harness and single-pr…
Dumbris Sep 17, 2026
e114cc4
test(scope): red tests for group grants, owner resolution, scoped ind…
Dumbris Sep 17, 2026
49b9db9
feat(scope): one entitlement predicate with IdP-group grants, owner r…
Dumbris Sep 17, 2026
fa968e2
test(httpapi,frontend): red tests for the tenant session principal, r…
Dumbris Sep 17, 2026
7561c6b
feat(httpapi,web): tenant session principal on core REST, profiles/SS…
Dumbris Sep 17, 2026
1e379ff
docs(spec-107): access block reference, agent-token invariant, hot-re…
Dumbris Sep 17, 2026
6afc4d0
fix(spec-107): gate fixes for PR-C
Dumbris Sep 17, 2026
bf06b43
fix(spec-107): cross-review round 1 for PR-C
Dumbris Sep 17, 2026
58d2d30
docs(spec-107): record PR-C cross-review round 1
Dumbris Sep 17, 2026
c2e963a
fix(spec-107): cross-review round 2 for PR-C
Dumbris Sep 17, 2026
aac5053
docs(spec-107): record PR-C cross-review round 2
Dumbris Sep 17, 2026
e9776e8
docs(spec-107): PR-C real-instance verification, gate re-run, task ticks
Dumbris Sep 17, 2026
180c249
docs(roadmap): link PR-C
Dumbris Sep 17, 2026
4cdc766
fix(spec-107): cross-review round 3 for PR-C
Dumbris Sep 17, 2026
d735ec7
docs(spec-107): record PR-C cross-review round 3
Dumbris Sep 17, 2026
ff19749
fix(spec-107): wait for PhaseReady before seeding the group-scope fix…
Dumbris Sep 17, 2026
d9aaaa3
test(audit): red tests for JCS canonicalisation, line schema, redacti…
Dumbris Sep 17, 2026
29c43f9
feat(audit): edition-neutral JSONL audit line — JCS args hash, schema…
Dumbris Sep 17, 2026
822a75a
test(server,jsruntime): red tests for the audit funnels, caller deriv…
Dumbris Sep 17, 2026
51b5b67
feat(server): audit lines at the authorization and tool-call funnels,…
Dumbris Sep 17, 2026
b22a6cf
feat(audit): auth_event lines, audit_log config with per-edition defa…
Dumbris Sep 17, 2026
45ce2d5
docs(audit): audit-log reference, team deployment guide, e2e audit as…
Dumbris Sep 17, 2026
c1256ff
fix(spec-107): gate fixes for PR-D
Dumbris Sep 17, 2026
2449600
fix(spec-107): address adversarial review of PR-D
Dumbris Sep 17, 2026
89c66d2
docs(spec-107): PR-D real-instance verification, gate re-run, task ticks
Dumbris Sep 17, 2026
2978a59
docs(roadmap): link PR-D, epic in_review
Dumbris Sep 17, 2026
c4493c8
fix(spec-107): cross-review round 1 for PR-D
Dumbris Sep 17, 2026
c25c98c
fix(spec-107): cross-review round 2 for PR-D
Dumbris Sep 17, 2026
4d192cc
fix(spec-107): cross-review round 3 for PR-D
Dumbris Sep 17, 2026
52a10e6
fix(spec-107): cross-review round 4 for PR-D
Dumbris Sep 17, 2026
6c21c50
Merge remote-tracking branch 'origin/main' into pr1296-merge-main
Dumbris Sep 18, 2026
6af4400
fix(test): loosen TestUpstreamServersListOperation's CI-flaky 100ms b…
Dumbris Sep 18, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 11 additions & 0 deletions .github/RELEASE_NOTICE.md
Original file line number Diff line number Diff line change
Expand Up @@ -107,3 +107,14 @@ A tenant — anyone who signs in through the team's IdP rather than through the
- **Subject-rebind procedure for a re-created IdP account**: if your IdP re-creates a user's account (new subject, same email), the login is refused (`subject_mismatch`) rather than silently taking over the existing record. An administrator re-arms the binding by disabling the user and then re-enabling them — this arms a single-use, persisted rebind window — and the user's *next successful login* accepts the new subject and rebinds automatically. No other action is needed and no record is deleted.
- **Tenant Web UI**: a signed-in tenant now gets a working dashboard, server list and activity view built entirely from the session cookie and the tenant-allowed routes — no `?apikey=`, no calls to administrator-only or global-state endpoints (`/info`, `/routing`, `/docker/status`, `/connect`, `/stats/tokens`, `/security/overview`, `/onboarding/state`, core `/activity*`, core `/config`); those cards, chips and pages are hidden rather than issued-and-403'd — Settings stays an administrator-only page (its own personal-server and token management live under `/my/servers`, `/my/tokens`). Diagnostics and history use the tenant-scoped `/user/diagnostics` and `/user/activity` endpoints. The `access` map is edited by an administrator through Settings' Raw JSON tab and shown read-only as group chips on the admin server page and on `AdminUsers`.
- No action needed if you do not set `server_edition.access` at all: every tenant keeps seeing every `Shared` server exactly as before this release, on group grants alone. To start restricting tenants by IdP group, add the `access` block — from that point on, only a matching group entry (or `default_servers`) grants a shared server; a present-but-empty block denies every tenant until you populate it. Administrators are unaffected either way.

## Server edition: every authorization decision and tool call now writes an audit line

A new `audit_log` writes one JSON line per pre-dispatch authorization decision and one per completed tool call (`authz`/`tool_call` events, spec 107 FR-012..FR-019), plus one per login/logout attempt (`auth_event`, already covered above). Arguments are never logged in the clear: each line carries `args_sha256`, a SHA-256 over the RFC 8785 (JCS) canonical form of the call's arguments, and `args_bytes`, never the arguments themselves. A quarantined or otherwise hidden server name is written for the operator's own record but is never echoed back to the caller — the audit line and the caller-facing refusal stay separately governed. Nested `code_execution` sub-calls get their own `authz`/`tool_call` pair carrying `parent_id`, so a script that fans out into several upstream tools is fully attributable, not collapsed into one line.

- **Personal edition default: off** (`audit_log.enabled: false`); nothing changes unless you turn it on. **Server edition default: on**, writing to stdout, with one line logged at startup announcing the sink. Set `audit_log.path` to a file instead (rotated: `max_size_mb`/`max_backups`/`max_age_days`/`compress`, defaults 50 MB / 10 / 90 days / compressed) if you want the audit stream off your process's own stdout.
- **Under the native stdio transport, stdout is JSON-RPC and can never double as the audit sink.** With `audit_log` absent, the server edition silently falls back to `{enabled:false}` and logs one `WARN` (`audit_log.stdout is ignored under the stdio transport; set audit_log.path`) instead of writing audit JSON into the protocol stream. If you **explicitly** set `audit_log.enabled: true, stdout: true` with no `path` under stdio, that is refused, not silently downgraded: startup fails with exit code 4, `audit_log.stdout cannot be used under the stdio transport (stdout carries JSON-RPC); set audit_log.path`.
- **An unwritable audit path is a boot failure, not a warning.** If `audit_log.path` cannot be opened for append (missing parent directory, permissions), `mcpproxy-server` exits with code 4 and logs `audit_log.path %q cannot be opened for append: %v`. Point the path at a writable location before starting, or use the stdout sink where the transport allows it.
- The sink is a single mutex-guarded synchronous writer (`plan.md` Complexity Tracking) — a write failure after startup increments an always-on counter (visible in `mcpproxy doctor`) rather than blocking or dropping the request; audit lines are best-effort after boot, guaranteed-writable at boot.
- `audit_log` is bound at sink construction, so every key under it (`enabled`, `path`, `stdout`, `max_size_mb`, `max_backups`, `max_age_days`, `compress`) requires a restart to take effect; a hot `PATCH`/`apply` is accepted but only applies on the next start.
- Details: [audit log](https://docs.mcpproxy.app/features/audit-log/).
10 changes: 10 additions & 0 deletions .github/workflows/release-qa-gate.yml
Original file line number Diff line number Diff line change
Expand Up @@ -109,6 +109,13 @@ jobs:
mkdir -p dist-bin
# Candidate headless core (nogui matches the E2E build; no tray deps).
go build -tags nogui -ldflags "${LDFLAGS}" -o dist-bin/mcpproxy ./cmd/mcpproxy
# Server edition (Spec 107 round-3 cross-review finding, PR-D):
# test-api-e2e.sh's audit_log sub-test requires ./mcpproxy-server
# and hard-FAILS ("Audit log: server-edition binary present") when
# it is missing/non-executable rather than skipping — this job
# never built it, so every run of suite/api-e2e deterministically
# failed that test.
go build -tags server,nogui -ldflags "${LDFLAGS}" -o dist-bin/mcpproxy-server ./cmd/mcpproxy
go build -o dist-bin/mcpfixture ./cmd/mcpfixture
go build -o dist-bin/oauthserver ./tests/oauthserver/cmd/server
go build -o dist-bin/release-gate ./cmd/release-gate
Expand Down Expand Up @@ -161,6 +168,9 @@ jobs:
chmod +x dist-bin/*
# test-api-e2e.sh expects the built core at ./mcpproxy (unmodified).
cp dist-bin/mcpproxy ./mcpproxy
# ...and its audit_log sub-test (Spec 107 PR-D) expects the
# server-edition binary at ./mcpproxy-server.
cp dist-bin/mcpproxy-server ./mcpproxy-server

- name: Run API E2E suite
run: |
Expand Down
56 changes: 27 additions & 29 deletions ROADMAP.md
Original file line number Diff line number Diff line change
Expand Up @@ -80,8 +80,8 @@ graph LR
- 🔵 **Release qualification gate (auto-QA matrix blocks the tag)** — In progress · P0
- 🔵 **MCP protocol upgrade to 2026-07-28 revision** — In progress · P1
- 🔵 **Planning/docs truth automation** — In progress · P2
- 🔵 **Spec 107 server edition SSO front door hardened for real IdPs** — In progress · P2
- 🔵 **Discovery-quality eval harness (Spec 065 second half)** — In progress · P3
- 🟡 **Spec 107 server edition SSO front door hardened for real IdPs** — In review · P2
- ⚪ **Windows native tray app** — Todo · P2
- ⚫ **Server marketplace** — Todo · P3 · parked
- ⚫ **Audit SIEM integration** — Todo · P3 · parked
Expand Down Expand Up @@ -406,59 +406,57 @@ graph LR
</details>

<details>
<summary>🔵 Spec 107 server edition SSO front door hardened for real IdPs — In progress · P2</summary>
<summary>🔵 Discovery-quality eval harness (Spec 065 second half) — In progress · P3</summary>

> Generic OIDC, IdP-group -> server allowlist, attributable JSONL audit line; freeze the latent multiuser/credential-injection code. Research: docs/research/server-edition-2026-09-14 (#1281).
> IN PROGRESS — 2026-08-31 audit, corrected on cross-model review: both halves of the HARNESS shipped INDEPENDENTLY (not via token-bench-harness), but spec 065 is NOT fully met, so this is not done. FR-009 and SC-005 require CI to FAIL on a discovery regression beyond tolerance; the retrieval-D1 job is continue-on-error on pull requests, so on the PR path it does not fail — eval.yml itself records the promotion to PR-blocking as still open (MCP-742). A second, weaker tension to adjudicate rather than assume: CN-002 asks that scoring never run against a live drifting corpus, and D1 does boot a live mcpproxy serving 7 reference servers — but #931 pinned all seven upstreams to freeze-era versions and the job gates on the exact corpus ID set, so the corpus is reproducible in practice. Decide whether that satisfies CN-002 or whether a committed snapshot is required. Remaining work is therefore the gating promotion, not the harness. The earlier 'superseded / folded into token-bench-harness' framing was wrong on its own terms: token-bench-harness is still unbuilt, so nothing could have been folded into it. Security recall/FP half: cmd/scan-eval, backing the Spec 076/077 gate in eval.yml. Discovery-quality half: the eval.yml retrieval-d1 job boots mcpproxy and scores retrieval_golden_v1.json against a committed baseline at --tolerance 0.05 via the pinned external mcp-eval repo — note continue-on-error is scoped to github.event_name == 'pull_request', so the job is REPORT-ONLY on PRs (npx/uvx fetch flake) and BLOCKING on both the nightly schedule and manual workflow_dispatch runs. Promoting it to PR-blocking after a green soak is still open (MCP-742). NB the workflow's own inline comment says 'blocking on the nightly schedule' and omits workflow_dispatch. A second in-repo implementation lives in bench/: metrics.go defines RecallAtK/NDCGAtK, and the SC-003 recall@5 = 0.68 +/- 0.05 parity gate through the production Bleve index is asserted in bench/armindex_test.go (armindex.go supplies the production index wiring, not the assertion). Kept as a stable depends_on target; do not build a standalone harness.

Spec: [107-server-edition-sso-hardening](./specs/107-server-edition-sso-hardening/)
Spec: [065-evaluation-foundation](./specs/065-evaluation-foundation/)

```mermaid
graph LR
sso_pr_a_freeze_cut["PR-A freeze/cut latent code + config normalis…"]
sso_pr_b_oidc_front_door["PR-B generic OIDC provider + front door behin…"]
sso_pr_c_group_allowlist["PR-C one entitlement predicate, group grants,…"]
sso_pr_d_audit_line["PR-D attributable JSONL audit line + auth_eve…"]
discovery_eval_pr_blocking["Promote retrieval-D1 from report-only to PR-b…<br/>MCP-742"]

sso_pr_a_freeze_cut --> sso_pr_b_oidc_front_door
sso_pr_b_oidc_front_door --> sso_pr_c_group_allowlist
sso_pr_c_group_allowlist --> sso_pr_d_audit_line

classDef done fill:#1f7a1f,stroke:#0d3d0d,color:#ffffff;
classDef in_progress fill:#1f6feb,stroke:#0b3d91,color:#ffffff;
classDef todo fill:#6e7781,stroke:#3d4248,color:#ffffff;
class sso_pr_a_freeze_cut,sso_pr_b_oidc_front_door done;
class sso_pr_c_group_allowlist in_progress;
class sso_pr_d_audit_line todo;
class discovery_eval_pr_blocking todo;
```

| Task | Status | Refs |
| --- | --- | --- |
| PR-A freeze/cut latent code + config normaliser + per-owner token cap (US5, US6) | 🟢 Done | #1287 |
| PR-B generic OIDC provider + front door behind ingress + telemetry v13 (US2, US7) | 🟢 Done | #1292 |
| PR-C one entitlement predicate, group grants, tenant Web UI session principal (US1, US4) | 🔵 In progress | #1293 |
| PR-D attributable JSONL audit line + auth_event + config/doctor/metrics (US3) | ⚪ Todo | — |
| Promote retrieval-D1 from report-only to PR-blocking (spec 065 FR-009/SC-005), and adjudicate the CN-002 frozen-corpus question | ⚪ Todo | `MCP-742` |

</details>

<details>
<summary>🔵 Discovery-quality eval harness (Spec 065 second half) — In progress · P3</summary>
<summary>🟡 Spec 107 server edition SSO front door hardened for real IdPs — In review · P2</summary>

> IN PROGRESS — 2026-08-31 audit, corrected on cross-model review: both halves of the HARNESS shipped INDEPENDENTLY (not via token-bench-harness), but spec 065 is NOT fully met, so this is not done. FR-009 and SC-005 require CI to FAIL on a discovery regression beyond tolerance; the retrieval-D1 job is continue-on-error on pull requests, so on the PR path it does not fail — eval.yml itself records the promotion to PR-blocking as still open (MCP-742). A second, weaker tension to adjudicate rather than assume: CN-002 asks that scoring never run against a live drifting corpus, and D1 does boot a live mcpproxy serving 7 reference servers — but #931 pinned all seven upstreams to freeze-era versions and the job gates on the exact corpus ID set, so the corpus is reproducible in practice. Decide whether that satisfies CN-002 or whether a committed snapshot is required. Remaining work is therefore the gating promotion, not the harness. The earlier 'superseded / folded into token-bench-harness' framing was wrong on its own terms: token-bench-harness is still unbuilt, so nothing could have been folded into it. Security recall/FP half: cmd/scan-eval, backing the Spec 076/077 gate in eval.yml. Discovery-quality half: the eval.yml retrieval-d1 job boots mcpproxy and scores retrieval_golden_v1.json against a committed baseline at --tolerance 0.05 via the pinned external mcp-eval repo — note continue-on-error is scoped to github.event_name == 'pull_request', so the job is REPORT-ONLY on PRs (npx/uvx fetch flake) and BLOCKING on both the nightly schedule and manual workflow_dispatch runs. Promoting it to PR-blocking after a green soak is still open (MCP-742). NB the workflow's own inline comment says 'blocking on the nightly schedule' and omits workflow_dispatch. A second in-repo implementation lives in bench/: metrics.go defines RecallAtK/NDCGAtK, and the SC-003 recall@5 = 0.68 +/- 0.05 parity gate through the production Bleve index is asserted in bench/armindex_test.go (armindex.go supplies the production index wiring, not the assertion). Kept as a stable depends_on target; do not build a standalone harness.
> Generic OIDC, IdP-group -> server allowlist, attributable JSONL audit line; freeze the latent multiuser/credential-injection code. Research: docs/research/server-edition-2026-09-14 (#1281).

Spec: [065-evaluation-foundation](./specs/065-evaluation-foundation/)
Spec: [107-server-edition-sso-hardening](./specs/107-server-edition-sso-hardening/)

```mermaid
graph LR
discovery_eval_pr_blocking["Promote retrieval-D1 from report-only to PR-b…<br/>MCP-742"]
sso_pr_a_freeze_cut["PR-A freeze/cut latent code + config normalis…"]
sso_pr_b_oidc_front_door["PR-B generic OIDC provider + front door behin…"]
sso_pr_c_group_allowlist["PR-C one entitlement predicate, group grants,…"]
sso_pr_d_audit_line["PR-D attributable JSONL audit line + auth_eve…"]

sso_pr_a_freeze_cut --> sso_pr_b_oidc_front_door
sso_pr_b_oidc_front_door --> sso_pr_c_group_allowlist
sso_pr_c_group_allowlist --> sso_pr_d_audit_line

classDef todo fill:#6e7781,stroke:#3d4248,color:#ffffff;
class discovery_eval_pr_blocking todo;
classDef done fill:#1f7a1f,stroke:#0d3d0d,color:#ffffff;
classDef in_review fill:#9a6700,stroke:#5c3d00,color:#ffffff;
class sso_pr_a_freeze_cut,sso_pr_b_oidc_front_door,sso_pr_c_group_allowlist done;
class sso_pr_d_audit_line in_review;
```

| Task | Status | Refs |
| --- | --- | --- |
| Promote retrieval-D1 from report-only to PR-blocking (spec 065 FR-009/SC-005), and adjudicate the CN-002 frozen-corpus question | ⚪ Todo | `MCP-742` |
| PR-A freeze/cut latent code + config normaliser + per-owner token cap (US5, US6) | 🟢 Done | #1287 |
| PR-B generic OIDC provider + front door behind ingress + telemetry v13 (US2, US7) | 🟢 Done | #1292 |
| PR-C one entitlement predicate, group grants, tenant Web UI session principal (US1, US4) | 🟢 Done | #1293 |
| PR-D attributable JSONL audit line + auth_event + config/doctor/metrics (US3) | 🟡 In review | #1296 |

</details>

Expand Down Expand Up @@ -896,8 +894,8 @@ graph LR
| Telemetry v7: honest funnel + churn instrumentation | In progress | P1 | — | [080-telemetry-v7-churn](./specs/080-telemetry-v7-churn/) | |
| MCP protocol upgrade to 2026-07-28 revision | In progress | P1 | 19/81 (23%) | [058-mcp-2026-upgrade](./specs/058-mcp-2026-upgrade/) | |
| Planning/docs truth automation | In progress | P2 | — | | |
| Spec 107 server edition SSO front door hardened for real IdPs | In progress | P2 | 100/126 (79%) | [107-server-edition-sso-hardening](./specs/107-server-edition-sso-hardening/) | |
| Discovery-quality eval harness (Spec 065 second half) | In progress | P3 | — | [065-evaluation-foundation](./specs/065-evaluation-foundation/) | |
| Spec 107 server edition SSO front door hardened for real IdPs | In review | P2 | 102/126 (81%) | [107-server-edition-sso-hardening](./specs/107-server-edition-sso-hardening/) | |
| tpa-db: versioned TPA signature database for the offline scanner | Todo | P1 | — | [101-tpa-db](./specs/101-tpa-db/) | |
| Auto routing mode: budget-fitted tool surface per session (spec 104) | Todo | P1 | — | [104-auto-routing-mode](./specs/104-auto-routing-mode/) | |
| Windows native tray app `MCP-43` | Todo | P2 | — | | |
Expand Down Expand Up @@ -1038,4 +1036,4 @@ Legend: `shipped` ≥95% checked · `in-flight` 1–94% · `drafted` 0% · `—`
| [104-auto-routing-mode](./specs/104-auto-routing-mode/) | — | — |
| [105-agent-scope-hardening](./specs/105-agent-scope-hardening/) | `in-flight` | 12/109 (11%) |
| [106-security-residual-fixes](./specs/106-security-residual-fixes/) | `shipped` | 18/19 (95%) |
| [107-server-edition-sso-hardening](./specs/107-server-edition-sso-hardening/) | `in-flight` | 100/126 (79%) |
| [107-server-edition-sso-hardening](./specs/107-server-edition-sso-hardening/) | `in-flight` | 102/126 (81%) |
Loading
Loading