Roadmap

Where the ship has been, and where it is going

Seven phases are behind us, one of which we built and then deliberately switched off. What follows is grouped by horizon rather than by date, because unshipped work with a date on it is a guess wearing a uniform.

Shipped

In the order it happened. The product went from a well-built demo with no runtime to a live system in a single stretch of work — and the most consequential decision in it was the one to remove a feature.

  1. 01

    Persistence

    SHIPPEDAug 2026

    The deck stopped being a demo. Watches, proposals, and ledger events became real rows scoped to the operator who made them.

    • Cloudflare D1 database with migrations for watches, proposals, and ledger events.
    • Every row scoped to a session address, so wallet and demo sessions never mix.
    • First-visit seeding, so a fresh deck opens with something to steer rather than three empty tables.
  2. 02

    Real prices

    SHIPPEDAug 2026

    Fictional prices became real quotes on the underlying equities — and the deck learned to say which it was showing.

    • Market-data provider behind a cache-first quote service.
    • Shared quote cache in D1: one price for a symbol serves every deck, which is what keeps the system inside an upstream rate limit.
    • Provenance on every response — source, live, stale, and a detail line naming the cause when prices are not live.
  3. 03

    The agent loop

    SHIPPEDAug 2026

    The fleet started doing something while nobody was watching: a scheduled sweep that turns tripped watches into drafted proposals.

    • Cron Trigger every 15 minutes, re-entering the Worker through a self-reference binding.
    • Structured model call per tripped watch, schema-validated on return; invalid drafts are discarded, never repaired.
    • All allocation arithmetic computed in code — the model writes prose and argues, it does not calculate.
    • 30-minute per-watch cooldown, stamped even on failure, so an outage cannot become a spend loop.
  4. 04

    Execution rail

    DROPPED ON PURPOSEAug 2026

    Built, tested, and then deliberately switched off. The decision that followed became the product's architecture.

    • The connection layer is complete: OAuth with PKCE, RFC 7591 dynamic client registration, refresh tokens encrypted under a key held outside the database.
    • Order placement was never built, and now will not be.
    • Reasoning: Oddysey never executes, so holding a credential that could place real orders would buy the highest-value secret in the architecture in exchange for no capability at all.
  5. 05

    Distribution over MCP

    SHIPPEDAug 2026

    Operators' own agents got a way in: a remote MCP server exposing nine tools, and pointedly not a tenth.

    • Streamable HTTP at /api/mcp, protocol 2025-06-18.
    • Revocable deck tokens, stored only as SHA-256 digests and shown in plaintext exactly once.
    • No approve or reject tool, at any permission level — an agent that could sign off on its own drafts would defeat the product.
    • Live in production on Cloudflare Workers with the cron sweep registered.
  6. 06

    Documentation, whitepaper, roadmap

    SHIPPEDAug 2026

    The reasoning behind the design became readable by someone who did not build it.

    • Full documentation: concepts, tutorials, REST and MCP reference, self-hosting, and the security model.
    • A whitepaper arguing the design, including the limitations it does not solve.
    • This page.
  7. 07

    Coverage on the evaluation loop

    SHIPPEDSep 2026

    This page had been claiming there was no test suite. There was one — what it did not cover was the evaluation loop and the allocation arithmetic, the two files the claim itself kept naming. They are covered now, and this entry replaces the claim.

    • The allocation arithmetic branch by branch: the divide-by-zero portfolio, the rounding to one decimal place, the malformed allocations a model can return, and the ±0.5% tolerance asserted at both of its edges.
    • The evaluation loop through its exported surface: the threshold at and either side of the trip point, the 30-minute cooldown, a symbol with no quote, and a sweep that keeps going when one deck's queries fail.
    • The assertion that pays for the file: a failed draft still stamps the cooldown, so a draft that keeps failing costs one model call per half hour instead of one per tick.
    • The correction itself. A suite already existed when this page said none did; what was missing was coverage of the two files it kept pointing at.
  8. 08

    Scoped deck tokens

    SHIPPEDSep 2026

    A deck token opened five surfaces at once — the tools, the agent-to-agent endpoint, the inference API and credit top-ups — so a token issued for a monitoring agent could also spend its operator's model credits. Nobody chose that narrowing; it is simply what one flat bearer token buys.

    • Three scopes, fixed the moment a token is issued: read sees, write arms, inference spends. Changing what a token may do means issuing a new one and revoking the old.
    • Refusals fail closed. The column is nullable with no default, so an insert that forgets its scopes issues a token that grants nothing rather than one that grants everything.
    • Existing tokens kept all three. They are pasted into agents running right now, and narrowing one silently would break somebody's deployment to satisfy a tidiness invented that day.
    • Metering moved with it. A call the scopes will refuse now prices at zero, so a read-only token is never billed for the writes it was never allowed to make.
  9. 09

    Notifications that fire

    SHIPPEDSep 2026

    A drafted proposal is the time-sensitive thing in the whole loop, and it used to wait for somebody to open the deck. Webhook delivery closes that. Email did not ship: it needs a verified sending domain before it can send anything at all, which is most of the work rather than the last of it.

    • Delivery is keyed on the channel and the subject behind a unique index, so a watch that stays tripped across 96 sweeps a day is announced exactly once.
    • Only a title, one line of context, a link back and the commitment digest travel. No allocations, no position sizes, not even the list of symbols.
    • Two attempts, then the row is dropped with a ledger entry. A queue that grows without bound through an outage is a worse failure than a missed alert.
    • The URL guard states plainly what a name check cannot decide. A public hostname that resolves to loopback passes it, and the file names one rather than reading stronger than it is.
  10. 10

    Whole-book watches

    SHIPPEDSep 2026

    Watches were per-symbol. Real concerns are often not: total drawdown, concentration drift, a book that moves together. A watch can now be aimed at the portfolio rather than at one ticker.

    • Three metrics, all computed from prices already in hand: drawdown against a high-water mark, the share sitting in a single position, and the whole book moving one way at once.
    • The mark never resets on the market — not when the watch fires, not on a timer — and re-bases only when holdings change, because a peak taken over different holdings was never a peak on this book.
    • A tripped whole-book watch writes a ledger alert and drafts nothing. Drafting from one needs a prompt that argues about a book, and that does not exist yet.
    • Armed over MCP for now. The deck's own form and table still handle only the per-symbol kind.
  11. 11

    Proposal outcome tracking

    SHIPPEDSep 2026

    Nothing recorded whether approving a proposal turned out well, so neither the operator nor the prompt drafting the next one had any feedback signal. Every decision now carries a decision-time price snapshot and is scored against it.

    • The snapshot is written in the same batch as the decision itself. Taken afterwards it would be a reconstruction, which is the one thing this record exists to rule out.
    • Scored at seven days and thirty: the proposed allocation measured against the one already held.
    • Rejected proposals are scored on the same terms. It is the only way anyone learns that rejecting was right.
    • Both figures are counterfactuals and the deck says so in the open. Oddysey does not execute, so neither allocation was necessarily held.

Planned

Each item says why it is wanted and, where one exists, the unresolved question standing in front of it. Items move between horizons as those questions get answered — or as they turn out to be harder than they looked.

Now

Being worked on, or next off the shelf.

  • A published MCP package

    Connecting a stdio-only client currently means bridging to the remote server by hand. A published package would make it one line.

Next

Decided in principle, not yet started.

  • Execution reconciliation

    Reported fills are claims, not observations. Checking them against a venue's own record would make the last line of the audit trail as trustworthy as the rest of it.

    OPEN: Verification needs read access to the venue, which reopens the credential-custody question that dropping the execution rail closed.

Later

Wanted, unscheduled, and honestly still uncertain.

  • Team decks with separated roles

    There is no notion of a team, a reviewer distinct from an approver, or a four-eyes requirement. For a desk, that is the first structural thing missing.

  • Read-only balance connection

    Holdings are fixtures because the system connects to no account. Reading real balances would make every allocation figure real, and reading is not trading.

    OPEN: It reintroduces credential custody for a read-only benefit. Not obviously worth it, and it will not be done quietly if it happens.

  • Market holidays, which no clock can name

    Most of this dissolved rather than being solved. Chainlink leads the provider order now and prices the tokenized asset on a 24/5 calendar, so the number keeps moving overnight and the old tension with round-the-clock watching went with it. What remained was cheap: the sweep sits out the weekend deliberately, and refuses to draft off any price more than a day old.

    OPEN: Holidays are still not modelled, because they cannot be read off a clock. A shut Thanksgiving and a stalled feed are the same observation from here, and the age bound treats them identically on purpose. Whether that proxy is enough, or whether this eventually wants a real exchange calendar with half-days in it, is the part nobody has decided.

Never

Not “not yet”. These are the commitments the product is built on, and shipping any of them would make Oddysey a different product with the same name.

An execution endpoint

The absence of an order path is the security argument. Adding one would not extend the product — it would replace it with a different, more ordinary one.

An approve or reject tool for agents

An agent that can sign off on its own drafts is an autonomous trader with extra steps. The capability is absent rather than gated, so no misconfiguration or compromised token can produce it.

Custody of brokerage credentials for trading

A refresh token that can place real orders is the highest-value secret such a system could hold. Since Oddysey does not execute, holding one would be pure risk.

An autonomous mode

Not as a setting, not for advanced users, not behind a warning. A supervision layer with an off switch for the supervision is a marketing claim, not a design.

Known gaps, stated plainly

Holdings are fixtures rather than real balances. Reported fills are claims that nothing verifies. The sweep sits out the weekend on purpose, and treats a holiday it cannot name as a stale price rather than guessing at a calendar. None of these are hidden in a changelog — they are in the whitepaper’s limitations section and in the documentation too.