Tedix runs persistent, organization-owned AI workers on Cloudflare. Start with
README.md and docs/public/index.md; docs/public/release-status.md says
what is available today.
Start locally
Run bun run-local from the repository root. It needs no login and makes no
model calls by default; docs/public/getting-started.md lists its options.
For UI-only work, use bun run --cwd apps/os dev (fixture data). Never treat
passing local tests as a check of Cloud behavior or a deployment.
Choose a source path
| Change | Read first |
|---|---|
| UI | apps/os/README.md, apps/os/AGENTS.md, then apps/os/src/routes/ |
| API | apps/api/AGENTS.md, contract in packages/api-contract/src/contracts/, router in apps/api/src/rpc/routers/ |
| Persistence | packages/db/AGENTS.md, owning src/schema/ and src/queries/ modules |
| Worker execution | apps/tedi-runtime/AGENTS.md, src/do.ts and the relevant adjacent module |
| MCP tools | apps/mcp/AGENTS.md, src/mcp/handler.ts and packages/db/src/schema/tools.ts |
| CLI | packages/cli/README.md and the command’s implementation |
Read the nearest scoped AGENTS.md, exact callers, and tests before changing
behavior. Keep unrelated work intact. Contracts and current code take priority
over prose; fix stale instructions when you encounter them.
Before each patch, re-read the exact lines it replaces. Never copy context lines from memory or from your own earlier edit, because a formatter may have rewritten them. Keep Markdown line breaks exactly as the file has them.
Validate the change
bun run --cwd <workspace> type-check: TypeScript source.bun run --cwd <workspace> test:run: that workspace’s tests; follow scoped guidance for narrower tests. Never use barebun teston Worker apps.bun run types:check: generated Worker bindings; regenerate withbun run types:generate, never by hand.bun run lint:repo: architecture boundaries.bun run docs:public:check: public documentation and agent references.bun run scan:secrets: public source safety.
The pre-push hook selects relevant checks. Do not weaken a failing check to make it pass. Report exactly what ran, and keep passing tests, a recorded outcome, and a deployment distinct.
Before committing, run bun run format <changed files>; unformatted files are
the most common pre-push failure. Push with bun run push, not git push: it
queues behind other sessions on this machine, rebases onto origin/main, runs
the normal pre-push gates, and retries if main moved elsewhere.
Worktrees and closeout
Agents must create worktrees under .worktrees/ (or harness-managed locations), never sibling clones.
Work in a worktree, never in a checkout another session is using.
Run git worktree list before creating one and reuse your own.
Once your change is pushed or abandoned, remove your worktree and scratch
files; never remove one a live session is in. bun run worktree:gc lists every
worktree of this repo and --apply removes only merged, clean, idle ones. The
worktree-closeout skill in .agents/skills/ is the full procedure.
Hard Invariants
Breaking these is expensive and usually invisible locally. Do not:
- Use
db.transaction(). D1 rejectsBEGIN(error 7500).db.batch()is the transaction primitive. - Select two columns with the same output name in one query. D1 batch results are object rows and silently collapse duplicates before Drizzle maps them. Every query must stay safe when composed into a batch; tests use a D1 facade that rejects both idioms.
- Define oRPC contracts inline in routers. Contracts live in
packages/api-contract/src/contracts/, schemas inpackages/api-contract/src/schemas/; apps import direct@tedix/api-contract/...paths. - Add barrel files or re-export facades. Direct imports everywhere. DB
access goes through
@tedix/db/queries/<domain>modules — never inline Drizzle queries in routers, jobs, services, or workflows (scripts/lint-db-access.tsenforces this). - Hardcode per-tenant behavior in TypeScript. Config-driven behavior (tools, widgets, scopes, policies, schedules) belongs in D1 rows and versioned assets; TypeScript provides the engines, validators, renderers, and adapters.
- Name MCP tools anything but verb-first snake_case.
list_skills,get_skill,run_skill_workflow. A noun prefix is allowed only for multi-product disambiguation (gmail_send). Internal oRPC contract keys keep their TypeScript{noun}.{verb}shape and are exempt. - Edit
worker-configuration.d.tsby hand — regenerate withbun run types:generate. Worker config iswrangler.jsonc, never.toml.
Local work and live access
A local checkout gives no access to any live organization. For permitted live
work, read docs/public/agent-guide.md, check tedix auth status, and discover
the exact tool and schema before calling it. Consent, MFA, and user presence
stay with the human; other approvals go to the designated approver.
Maintainers commit directly to main after validation. Agents never create
GitHub issues or pull requests (pull requests are disabled). File proposals,
bugs and follow-ups as Tedix Work items; GitHub issues are for outside
contributors (CONTRIBUTING.md). Never invent a Work Item or agent identity.
A user-visible CLI change adds a changeset (bun changeset) in the same
commit. Never bump the CLI version, edit its CHANGELOG.md, or tag a release
as part of a change; releases are batched, at most daily (CONTRIBUTING.md, Releases).
Deployment boundary
A commit changing a deployable wrangler.jsonc or cloudflare.config.ts
requires one Ops-Overlay: <full ops commit SHA> <config path> trailer per
changed config before pushing to this repository. Validate the corresponding
private overlay against the exact product config and land it in ops first.
The pre-push gate checks the reference offline; Ship checks compatibility.
This repository owns product source and example configuration, not the live
Tedix Cloud installation. Managed releases run from tedix-hq/tedix-cloud-ops,
which owns the guarded deployment workflow, live configuration and credentials.
Do not hand-deploy Tedix Cloud from this checkout or add its account, database,
organization or resource IDs, secret references, or private runbooks here.
Keep checked-in Worker configuration usable as examples, with placeholders
instead of live installation coordinates. Never commit real .env files,
.dev.vars, credentials or customer data; .env.example contains key names
and placeholders only. Use fictional tenant identities in tests and examples.
Deploying into your own Cloudflare account is experimental operator work. Follow
docs/public/installation-manifests.md and
docs/public/self-hosted-boundary.md only when deployment is the task. A source
checkout is not authorization to operate Tedix Cloud.