chore: scaffold oO monorepo with architecture, roadmap, and module stubs
This commit is contained in:
15
docs/adr/0001-monorepo-polyglot.md
Normal file
15
docs/adr/0001-monorepo-polyglot.md
Normal file
@@ -0,0 +1,15 @@
|
||||
# ADR-0001: Polyglot monorepo, TS for apps, Python for ML
|
||||
|
||||
## Status
|
||||
Accepted — 2026-04-13
|
||||
|
||||
## Context
|
||||
We ship web and mobile clients, backend services, and ML training/serving. Splitting into many repos early creates cross-repo PRs for every contract change and hurts velocity.
|
||||
|
||||
## Decision
|
||||
One monorepo, managed with pnpm workspaces for TS and uv/poetry for Python. Shared contracts live in `packages/shared-types` generated from OpenAPI. ML is Python; everything else is TS.
|
||||
|
||||
## Consequences
|
||||
- One CI system, one versioning flow, atomic cross-service PRs.
|
||||
- Requires disciplined boundaries: services must still be independently deployable.
|
||||
- Tooling complexity: two package managers, two lint stacks. Acceptable given the ML/app split.
|
||||
20
docs/adr/0002-recommender-contract.md
Normal file
20
docs/adr/0002-recommender-contract.md
Normal file
@@ -0,0 +1,20 @@
|
||||
# ADR-0002: Recommender as the stable contract, policy as a plugin
|
||||
|
||||
## Status
|
||||
Accepted — 2026-04-13
|
||||
|
||||
## Context
|
||||
v0 picks a random Todoist task. v1+ will use a contextual bandit, then learned rankers, then collaborative signals. If the HTTP contract and the candidate-generation path are coupled to today's "random", every change is a migration.
|
||||
|
||||
## Decision
|
||||
`recommender` exposes `POST /recommend` as the one stable contract. Internally it has three seams:
|
||||
1. **Candidate sources** — async functions that yield `TipCandidate`s from integrations, advice libraries, etc.
|
||||
2. **Context assembler** — pulls features (today: inline; later: feature store).
|
||||
3. **Policy** — `Policy.pick(candidates, context) → tip`. Registered by name; selected per-request by the experiments framework (Phase 4) or a static config (now).
|
||||
|
||||
Swapping a policy never changes the contract or the client.
|
||||
|
||||
## Consequences
|
||||
- v0 policy is `RandomPolicy`, trivially 50 lines.
|
||||
- v1 moves scoring to `ml/serving` behind the same `Policy` interface (`RemotePolicy` wrapper).
|
||||
- A/B is introduced without touching clients.
|
||||
Reference in New Issue
Block a user