Skip to content

Issue map: how the open issues relate, and what blocks what #168

Description

@DEENUU1

Rebuilt 2026-08-13 over 182 open issues and 38 open pull requests. CLAUDE.md
makes reading this a precondition for filing, and it was a title with an empty body
from 2026-08-04 until now — #683 is the issue about that, and this is the answer to
it.

How to use it

Before filing, find the cluster your defect belongs to below and name at least one
issue from it in the body
. "Checked, nothing related" is a fine answer; silence is
not. Then come back and add your number to the cluster, and to the spine if it blocks
something.

Two commands before you write a word — the map is a snapshot and the repository is not:

gh issue list --state open --limit 300 --search "<the words in your title>"
gh issue list --state closed --limit 100 --search "<the same words>"

Search the closed ones too. #659 was filed, worked and merged this week as half of
#437, which had been closed unfixed six days earlier — that is what #687 is about, and
it is the single most expensive mistake this map exists to prevent. A closed issue in
this repository is often closed by hand, with the evidence in a comment and no
closing pull request, so Closes/Refs in a footer is not a reliable signal either
way.

Every issue below appears exactly once, in the cluster that owns it. 48 of the 182
have a pull request in flight — those are marked, and picking one up is duplicated
work.


The clusters

A refusal that quotes the vendor

Who may do what

Channels and bots

Files a turn writes

The frontend's own API surface

English in every locale

Ingestion and retrieval

Unattended runs

What a run costs

Secrets at rest

The database underneath

Middleware written and never registered

The product's surfaces and shells

Models and providers

  • Six answers to "what models and providers exist", and none of them is the authority #923 Six answers to "what models and providers exist", and none of them is the authority - PROVIDERS (27), model_listings.json (20), model_fallbacks.json (7, and not about fallbacks), the genai_prices snapshot, image_models.json and two hand-written tables in docs/models.md, over a run-time authority that is Pydantic AI's own inference. Seven providers answer an empty picker today.

Performance and security (audit 2026-08-19)

The sweep behind these is Audit agenticos 2026-08-19 performance and security. #947 is
the one that is not like the others: it is a live, unauthenticated denial of service.

CI, the suite and the tools

Documentation

  • #29 medium Correct three documentation claims that describe behaviour that does not exist
  • #840 medium validate_webhook_url claims DNS-rebinding protection its callers undo by re-resolving — same shape as #29 and #561; the claim is narrowed rather than delivered — PR #842
    • #860 high MCP OAuth discovery URLs are remote-chosen, and the validated address is not pinned (found reviewing PR #842 — #840's "an operator typed it" reasoning covers the connection URL and the cdp_url, but not mcp_oauth._send, whose every hop the remote server names; this is the delivery half #840 declined) — PR #875
      • #889 low An MCP discovery URL with a bad port answers 500 rather than the refusal — httpx.InvalidURL is not an httpx.HTTPError, so the flow's three catches miss it and #872's fix cannot reach it (pre-existing, found merging main into PR #875)
    • #861 medium A blocked MCP server URL answers a generic 500 instead of naming the refusal — SSRFBlockedError is a ValueError, which no handler maps (pre-existing, found reading the same path) — PR #872
      • #873 medium Importing a spec YAML answers a generic 500 for every kind of mistake in it — a raw pydantic ValidationError is not a RequestValidationError, so no field error reaches the person who edited the file (found sweeping the same defect in PR #872)
      • #874 low An ingestion override with too large a chunk_overlap answers a 500 rather than the form its own docstring says it refuses to (same sweep) — PR #881
        • #882 low A per-field refusal answers with details.errors, which the form cannot mark — the frontend reads details.fields, so all four call sites of that idiom show a sentence and highlight nothing (found fixing #874; #873 added the fourth) — PR #892
          • #891 low The same defect in a third shape: seventeen refusals name one field with a singular details.field and the envelope's message, which no form reads either (deliberately left out of #882 — converging one of eighteen would make it disagree with its siblings) — PR #900
            • #897 low A connector's per-field refusal is flattened to a sentence by validate_config's (bool, str) protocol, so the sync-source wizard marks nothing — the one place #891 could not reach (found fixing #891)
            • #898 low A refused model id is posted back in details={"model": model} — the caller's own submission, serialized and logged — and still marks no input (found fixing #891)
  • #122 Improve README.md
  • #212 low docs/testing.md documents three fixtures and a layout the suite does not have
  • #664 Stale docs: governance.md claims deployment-wide rate limiting; SECURITY.md describes RoleChecker/UserRole — PR #665
  • #783 README: badges, star tracker and product graphics, styled like pydantic-ai / FastAPI (follow-up to the empty-bodied, closed #122)
  • #784 Docs: a readability and visual pass, modelled on pydantic-ai / FastAPI (presentation, not content-correctness like #29/#664)

The roadmap

  • #46 Add Guardrails
  • #47 Add Planning
  • #48 Add Context
  • #49 Add Context manager — PR #775, which also closes #771, #772, #773 and #774
  • #50 Add Tool Search
  • #51 Improve WebSearch and WebFetch capabilities — PR #839 adds the web_fetch capability (SSRF-guarded, own web:fetch scope); search-provider spend metering decided against and recorded on the issue, which found #840
    • #857 Native web search escapes the approval gate, the way native fetch did (found reviewing #839, which fixed the web_fetch half)
  • #52 Agents evaluation & authoring assistant — plan first
  • #54 Add realtime models + transcription
  • #55 Add media
  • #56 Add Dynamic workflows
  • #57 Add Overflowing tool output (harness module renamed to tool_output_limits; reference refreshed)
    • #803 Prune tool_output_limits spills at run end on non-run-scoped workspaces (found reviewing #57)
  • #787 Add System Reminders: re-inject steering guidance mid-run against instruction fade (harness system_reminders)
  • #788 Add a Memory capability: persist and recall facts across runs — plan first
    • #1470 Reshape it into two capabilities a builder picks (memory_files, memory_mem0) and drop the operator console; the native fact store, the origin trust tier and the Memory tab went with it. #1384, #1385 and #1386 were closed as superseded by the same reshape
    • #1077 A plan does not survive to the conversation's next turn, and the agent denies it exists (found adding the chat plan strip; the same question as #788 about state that outlives a run)
  • #789 Add a Conversations Search capability: search past transcripts mid-run — plan first (a tool, unlike #159's UI list search). Shipped on #788's branch (#1383) rather than its own: it needs the same run-level fact — who will hear this run — and a second derivation of that is the thing to avoid
  • #58 Add Image Generation
  • #59 Add Browseruse
  • #62 Agents redesign
  • #63 Admin redesign
  • #64 MCP redesign
  • #65 Knowledge Base redesign
  • #66 Vault redesign
  • #67 Chat redesign
  • #68 Organizations redesign
  • #69 Skills redesign
  • #70 Artefakty — needs a definition before it can be scoped
  • #71 Deep Research mode — blocked on #47, #51
  • #72 Seed Agents
  • #73 Seed Skills
  • #150 A first-class public API: organization API keys, so everything the UI does is doable without it
  • #151 A global assistant in the UI, running the platform through its own API — blocked on #150
  • #276 Render the delegation tree recursively on the agent map

Audit clean-up bags

  • #545 low Backend duplication & quality cleanup (audit 2026-08-10)
  • #557 medium useKBDetail holds server data in useState off React Query; two registered query keys are dead
  • #558 medium Admin query-key factories type params as unknown; admin.ratings is keyed three ways
  • #559 medium The ratings-by-day shape is declared four times under two confusable names
  • #560 medium Two upload routes serialize the same schema differently (response_model_exclude_none)
  • #562 medium Type the dict[str, Any] service contracts in sandbox and connectors - done, 0.0.214
  • #567 low Extract the runner's duplicated prompt-flatten and terminal-state assembly
  • #568 low Unify the two backend-schema form renderers (SchemaForm vs ConfigureStep)
    • #1093 low Converge the backend connector config schema onto JSON Schema (drop ConnectorConfigField) - the L, higher-risk half #568 deferred; #568 unified the renderer, this unifies the wire shape
  • #569 low Frontend duplication & quality cleanup (audit 2026-08-10)

Bookkeeping

  • #168 Issue map: how the open issues relate, and what blocks what
  • #683 The issue map (#168) has an empty body, so the filing rule that depends on it cannot be followed
  • #687 24 issues closed with no closing PR since Aug 5; at least two are still broken on main

The spine — what blocks what

Ordered by how much it unblocks. Everything not named here is independent.

1. #440 blocks the whole refusal cluster, and it was closed in error.
Reopened today after verifying on main: PiiRedactionFilter is attached to the root
logger at app/core/logging.py:73, where it never sees a record from a module
logger, and setup_logging has exactly one caller — app/main.py:217 — so the Prefect
worker never installs it at all. Every fix in that cluster works the same way: stop
putting the vendor's text in the response, keep it in the logger.exception beside the
raise. That remedy is only sound if the log is scrubbed, and it is not. #676, #681,
#686, #695, #699 and #659 all inherit the assumption; app/services/rag/failures.py:19
states the failure in the present tense and cites the number.

2. #311 is why the sweeps keep finding things. The automated reviewer has produced
nothing since 2026-08-05 while reporting success; eleven pull requests merged on a
sentence that read like a verdict. Until it is fixed the only review before a merge is
a human one. Not a formal blocker on anything — but it is the reason clusters like
"the frontend's own API surface" are found in audits rather than in review.

3. #564 is the structural fix for five symptoms. #13, #30, #546, #553 and #702 are
all the same ~40 hand-rolled backendFetch handlers under src/app/api/**: one
unencoded and unauthenticated (#13), eighteen unencoded (#30), the family swallowing
the backend's refusal reason (#546), omitting no-store (#553), and three echoing the
backend's content type (#702). Collapsing them into platformProxy removes the class.
Decide this before PR #668 merges — it already touches about forty of those files
for #546 alone.

4. #150 → #151 and #47 + #51 → #71, both stated in the blocked issue's own
title. #151 (a global assistant driving the platform through its own API) cannot start
before organization API keys exist; #71 (deep research) needs planning and the web
capabilities first.

5. #139 → #282 → #284. One table primitive, then the list-page shell built on it,
then the admin pages standardised onto both. Doing them in the other order means
writing the admin pages twice. Same shape in #136 → #138, #500: one file viewer
before the files page and the header field it needs.

6. #44 + #213 + #53 → #594. Three feature branches — PR #537 (triggers), PR #587
(dashboard layout), PR #624 (onboarding) — that each land alone and then have to agree
with each other on main. #594 is that reconciliation and cannot start until all three
merge.

7. #3, #7 and #12 are acceptance criteria of #39, and PR #634 says Closes #39.
#39's "Done when" list is four items: every surface records a run identically (#3),
EmbedSession takes a session factory rather than a session (#12), rate limits apply
to the public surfaces (#7), and docs/channels.md describes what exists. Three of
those are separate open issues. Either the footer should be Refs #39 with the
checkboxes ticked as they land, or #39 should be re-scoped to what #634 actually
finishes. Closes only when the change genuinely finishes it.

Pairs that want one pull request, not two: #7 + #18 (both are one
app.add_middleware line in create_app), #147 + #148 (adjacent lines of one
aggregation in repositories/rag_document.py:188-189), #548 → #566 (fix the
disagreement, then collapse the two helpers into one).


8. The connector chain, decided in #938. #984 (a web crawler) is first because it needs no credential and waits on nothing; #985 needs a new SecretKind for an Entra app that nothing else wants yet; #988 blocks Azure Blob and GCS and is the condition #938 attached to them - generalize S3Connector before writing either, not alongside. #990 came before all four and is done (0.0.216), which is what makes a change signal worth naming at all. #982 and #983 are not blockers but every connector on the chain inherits them, so they are worth having before the third one rather than after.

  • #1544 (runtime frontend config) → #1545 (published images): no frontend image until the hostnames leave the build

The duplicate register — already adjudicated

Recorded so nobody re-litigates them, and so the next filer can see what "the same
bug" has looked like here.

Filed more than once Survivor What happened
#636 · #638 · #642 #638 One defect at one line, channels/router.py:728, filed three times in eight days. #642 closed 2026-08-12, #636 closed 2026-08-13.
#554 · #611 #554 mcp-server-list.tsx:360 using window.confirm(), filed twice by the same author eleven days apart from two different sweeps. #611's three unique findings copied onto #554 before closing.
#437 → #659 · #676 #437 closed COMPLETED with neither half fixed; both halves re-filed by people who could not find it. #659 is the socket half (PR #675), #676 the run-row half (PR #691). #437 now carries a comment naming them.
#422 → #707 Closed for its first finding while a second, live one sat in a comment. #707 is that finding: rag-source-add writing an unvalidated, unowned collection name.
#452 → #451 Superseded before it was closed; both now closed.
#617 Withdrawn by its author into PR #587 rather than fixed separately.

Pairs that look like duplicates and are not — checked, keep both:

  • #13 / #30 — #30 is the sweep over eighteen unencoded segments; #13 is the one
    instance that is also unauthenticated, which is why it is severity:high where the
    sweep is medium. #13 must be in #30's fix, and #30 must not close without it.
  • #7 / #18 — two different middlewares, both written and never registered. One
    call site, two fixes, two sets of acceptance criteria.
  • #147 / #148 — both make one stats row lie; the fixes are independent and each
    body says so. #147 landed in #834 rather than alone, because #158 could not
    measure its own before/after while the only stored chunk count was a constant 0.
  • #656 / #678 — two shapes the i18n guard misses (hyphen, acronym), two pull
    requests (#677, #688).
  • #48 / #49 — context injection against context compaction. Different
    capabilities, adjacent names.

What has no scope yet

  • #70 Artefakty — says so in its own title. Needs a definition before it can be
    estimated.
  • #122, #124, #127, #128 have empty bodies. All four sit on W1 · Aug 3–7, a
    milestone eight days past, and are unactionable as written: "Fix Agent Builder
    frontend" names no defect and has no acceptance criterion. #168 was the fifth
    empty body and is fixed by this rebuild; these four are not. Either write them or
    close them — leaving them is what makes the open count untrustworthy.
  • #52 carries plan first in its title deliberately.

Known-stale references

An issue body's cross-references were true when written. About 78 of the open bodies
cite at least one number that has since closed — mostly the roadmap family citing #16
(un-metered embeddings), which is done. The one that changes a decision is #39's
second checkbox
, which describes #16 as live; it is not.

Do not chase the rest. Check a referenced number's state before acting on it:

gh issue view <n> --json state,stateReason,title

Triage state, 2026-08-13

Every open issue now has a type, a milestone, an effort:* label and a row on the
VstormOS board. Before today, 84 had no type and 26 — #456 and the whole
2026-08-10 audit batch, #545–#569 — were on no project at all, which made them
invisible to every view the board is read through.

Re-deriving this

gh issue list --state open --limit 300 --json number,title,body,labels,milestone
gh pr list --state open --limit 100 --json number,title,body      # then grep the footers

Pass --limit. It defaults to 30 and caps at 100; under a hundred open issues it
silently drops the lowest numbers, which is how #2–#7 once read as closed and a blocker
chain read as already done.

Refs #683, #687.


Filed 2026-08-28, merging the W4 backlog

Thirty pull requests were merged and released as 0.0.316-0.0.343 in one pass. The
five issues above with 13xx numbers came out of that: four from reviewer findings
on branches that were merged anyway, and one flake. Each is in its cluster.

One pull request was not merged: #1128 (#1079, the knowledge retrieval
store crossing worker event loops). Its fix builds a store with its own pool,
which #948 and #12 removed from main, so a mechanical merge either re-adds the
second pool or stops fixing the bug. #1079 stays open with the new shape written
down on it.

Filed 2026-08-29, from the MCP redesign

Three came out of one branch (docs/site-improvements), all in the #64 MCP
redesign
cluster and all in the same thread of work:

  • #1339 medium A Mattermost conversation was one channel, not one thread — the agent read every thread in a channel as one conversation

  • #1340 medium Starting OAuth from the catalog answered 404

  • #1341 medium The Builder picker keyed its rows on the catalog entry, so an organization with several connections to one server could bind only one of them — one card per server with an account select, and per-binding personal substitution

    • #1342 feature A member holding two accounts on one service cannot say which an agent speaks as — #1341 declines to guess, and nothing records the choice
    • #1343 low A resumed direct-message run stops speaking as the member who started it — agent_runs records the surface but not whether the conversation held one person
  • #1391 feature An MCP binding is either the organization's account or each person's own — a kind, not a flag. Supersedes #1341's per-binding substitution and #1343's private_to_user; builds on #1342's nomination of a default account. Filed 2026-09-04 — PR #1392

    • #1442 medium Publish and run time each decide MCP prefix collisions, and only publish says so
    • #1443 low ownAccountStatus re-implements the server's account rule on the client, and they disagree on unauthorized
    • #1444 low The personal-service briefing builds a frontend URL in the runner, which a locale-prefixed deployment breaks
    • #1445 low An API run authenticated with a user's own JWT is told nobody is signed in

    All four found reviewing PR #1392 before merge; none blocks 0.0.356.

Security programme (milestone W6 and W7 · Sep 7–18, planned 2026-09-05)

The theme for W6 and W7: a client's security review answered in writing, a mechanism and a test behind every row of a controls matrix (HIPAA §164.312, SOC 2 CC6–CC8), an issue behind every gap. #1424 is the epic and the four-area status; docs/security.md (#1412) is the deliverable the rest feeds.

  • #1424 security meta Security programme - the epic
  • #1412 documentation security docs/security.md: threat model, data flows, what is encrypted where, the controls matrix
  • #1413 security Traces sent to Logfire carry full prompts and outputs - a content mode on AgentSpec.observability (same card as #561)
  • #1414 low security frontend CodeQL alert #20 in oauth-return.ts - validate or dismiss with a reason (#135 added the path)
  • #1415 ci security CodeQL on pull requests, a frontend dependency audit, an SBOM per release (parity via #143)
  • #1416 security frontend A real Content-Security-Policy; the widget and hosted page are the framing exception (#702 family)
  • #1417 ci security A security pytest marker naming every refusal test, reported per release
  • #1418 security Encrypted connections to Postgres and Redis, and a doctor line
  • #1419 security Generic OIDC sign-in beside Google; honours the sign-up policy (#914). SAML/SCIM and TOTP are in the roadmap note, unfiled
  • #1420 security Per-organization data retention with an audit floor
  • #1421 security Erasure and export of one person's data - what UserService.delete leaves (#941 neighbour)
  • #1422 security Audit trail export and a hash chain (#20, #983 neighbours)
  • #1423 security S3-compatible file storage with server-side encryption beside the local disk
  • #1448 security A HIPAA deployment profile and a doctor --profile hipaa check that proves a running deployment matches it - the configuration half of #1412

Existing security issues scheduled under the same theme rather than moved here: #943 and #1044 (impersonation),
#913, #1047, #1066, #1245, #555, #1072 and #150. Bartek's 2026-09-05 sweep added #1427 (a deactivated member's
channel turn), #1437 (a WebSocket outliving its session), #1438 (identity binding while impersonating) and #1439
(a password change that revokes nothing) — the same theme, filed independently.

W6 and W7 are one milestone as of 2026-09-05, and everything schedulable was drained out of Later into it.
Seven issues stayed behind: #52 and #56 (themes planned in the roadmap note), #70 (unscoped), #71 and #151
(blocked), #54 (needs an architectural decision for the realtime half), #985 (needs the tenant-consent answer).

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Labels

documentationImprovements or additions to documentationeffort:mA day or twometaAn index or tracking issue, not work in itself

Type

Projects

  • Status
    Backlog

Relationships

None yet

Development

No branches or pull requests

Issue actions