Flow

Flow — Koder Git Forge

  • *rea:*Developer Platform
  • *ath:*products/dev/flow/platform
  • *ind:*Self-hosted git forge, based on *orgejo*(community fork of Gitea)
  • *agline:*From idea to deploy.
  • *tatus:*Production — flow.koder.dev · v1.0.15

Role in the stack

Flow is Koder's git forge — the canonical place to host code. Built on Forgejo and customized as Koder Flow, it runs at https://flow.koder.dev and hosts every Koder repository, including the monorepo itself at Koder/koder.

Features

  • *ightweight*— runs on almost any machine, from a Raspberry Pi to a small cloud instance
  • *roject management*— issues, pull requests, wikis, kanban boards
  • *ublishing*— releases for software downloads, package registry (Docker, npm, and more), granular public access for private repos (public releases, binaries-only, public packages)
  • *rganizations + team permissions* CI integration, code search, LDAP, OAuth
  • *rivacy-first*— built with privacy in mind from the ground up
  • *obile app*— native AndroidiOS client in `app` for onthego access
  • *dbnext integration*— shadowwrite/read to TiKV cluster (Phase 7.1, tenant 1000019)
  • *udit logging*— structured audit log via modules/kall for admin actions
  • *igration manifest*— RFC-005: migrations/v{TAG}.toml at tag commit surfaces upgrade constraints in release UI and API
  • *eriodic backups (RFC004)*— [backups] scheduler + worker pool ship encrypted git mirrors to Google Drive *nd Microsoft OneDrive*(FLOW074 — MultiUploader dispatches by dest.Provider); Phase 4 added adaptive backoff on DriveGraph throttle signals (FLOW073), exponentialbackoff retry on transient failures (FLOW-075), admin CSV export of the policyrun audit trail (FLOW077), and *uided restore*that downloads any successful run's bundle and imports it as a fresh repo (FLOW076) — RFC-004 Phase 4 fully closed.
  • *sync tab counters (#084)*— IssuePR tabs fetch open counts via `GET /issuescount + GET pullscount in parallel after page load; zero layout shift, arialabel for screen readers. kodertabcounters.js + .kftab-counter` CSS.
  • *tateLabel v2 (#083)*— shared/state_label_v2.tmpl dualpath template (9 state combos: 5 issue + 4 PR) with semantic CSS classes (`kfstate*). viewtitle.tmpl migrated. i18n keys in localeenUS.ini`.
  • *ageLayout canonical shell (#082, shipped)*— Threephase layout overhaul: (P1) Issue/PR right sidebar sticky + resizable (200–600px, localStorage); (P2) Code view left filetree sidebar — compact siblingfile listing with activefile highlight, width persistent (kf_code_sidebar_w), toggle persists via sessionStorage; (P3) Mobile fullscreen drawer — position: fixed; transform: translateX(-100%) slidein + animated backdrop, isMobileDrawer() JS branch. `kfcodelayout / kfcodesidebar / kfsidebarbackdrop CSS classes; kfpagelayout.js` handles both left (code) and right (issue) sidebars with directionaware drag. Follow-up: #092 (issue list sidebar + Playwright regression suite).
  • *CP server full surface (#094, #095, #096) — RFC001 Phases 4–5 + RFC003 Phase 2*— HTTP+SSE transport mounted at /api/v1/mcp/{stream,message} with bearertoken auth + persession JSONRPC dispatch (30min idle TTL). resources/list enumerates repos://, meta://, credentials://; the credentials reader walks the repo→org→account hierarchy with perscope ability gates and returns resolved_from provenance + auditlogged decrypt via creds.Reveal. tools/list + tools/call ship the four write tools (create_issue, comment_issue, create_pr, request_review) with JSONSchema inputs, scopemismatch ↔ MCP error mapping, and isErrorwrapped tool failures so the LLM can read and react without aborting. In-process tests cover SSE handshake, URI parsing, dispatch error paths, and validation gates.
  • *redential hierarchy + abilities (#098) — RFC003 Phase 3*— services/credentials.FetchAuthorized wraps the existing walk with an AbilitiesChecker injection point; MembershipAbilities{} is the default (admin sees all; account=owneronly; orgmember; repomember). Scopes the requester cannot see are silently skipped (crosstenant returns 404, not 403, per `specs/multitenancycontract.kmd). Provenance.ResolvedFrom() returns the canonical typeid` string for API/MCP responses.
  • *penTelemetry HTTP + manual spans (#099)*— modules/tracing wraps the main HTTP mux with otelhttp (noop when [tracing].enabled=false); packagescoped tracers in modules/kdb and services/mcp/handler.go emit spans on every shadow op and JSONRPC dispatch with stable attribute keys (kdb.op, mcp.method). Healthcheck paths are skipped via WithFilter. Settings live in [tracing] (enabled / servicename / otlpendpoint / otlpinsecure / excludepaths). OTLP exporter wiring is deferred to #103.
  • *ebrand configs Phase 2 (#100) — RFC005*— Build/contrib sweep aligns the deployed binary name: `Makefile EXECUTABLE = koderflow (removes the transitional ln f shim, fixes a stale main.Koder FlowVersion ldflag with an invalid space), .air.toml reloads koderflow, IDE/autocompletion/legal samples updated, systemd-unit socket-activation comments now reference koderflow.main.socket`. Outof-scope items (models/gitea_migrations package path, gitea_* Prometheus metric names, GITEA_ROOT/GITEA_CONF env vars, Dockerfile WORKDIR) tracked in #102.
  • *uiltin metalint Action (#097) — RFC002 Phase 3*— `koderflowmeta-lint@v1 registered in modulesactions built-in registry (rewrites uses: → in-process run: koderflow actions metalint). servicesmeta.LintFilesystem walks meta and surfaces structural findings (missing/malformed frontmatter, invalid status, intra-layer duplicates of (type, name); cross-layer = valid override). CLI emits GitHub-Actions-compatible ::error fileX,lineY::msg annotations and exits 1 when findings exist. Template workflow shipped at optionsworkflowsmeta-lint.yml`.
  • *TLP gRPC exporter wiring (#103)*— modules/tracing.Init() instantiates sdktrace.NewTracerProvider with otlptracegrpc client when [tracing].enabled=true && [tracing].otlp_endpoint != ""; resource attrs carry service.name=koder-flow, service.version=<AppVer>, deployment.environment=<RunMode>. Sampling via [tracing].sample_ratio (default 1.0, with AlwaysSampleNeverSample shortcuts at the extremes). `cmdweb.go graceful-shutdowns the provider after graceful.Done()` so in-flight spans flush to the collector. Otelsdk + exportersotlpotlptraceotlptracegrpc promoted to direct deps.
  • *ockerfile WORKDIR rebrand (#102 sub1) — RFC005 Phase 3 begin*— /app/gitea//app/koder-flow/ in Dockerfile + Dockerfile.rootless; xx-verify koder-flow (regression fix — the Forgejoera `xxverify gitea would not find the binary after #100's EXECUTABLE = koderflow` flip); inverted backwardcompat symlink (ln -s koder-flow gitea so legacy scripts still work); Makefile reproduce-build consumes new path. Env vars + path mounts + Prometheus metric names + Go package paths remain in sub-tickets #104–#107.
  • *koderflowfmt subcommand (#102 sub-5 / #107)** — buildcodebatchprocess.go ships a koderflowfmt subcommand for make fmt; the legacy giteafmt` invocation continues to work via dualcase (case "koder-flow-fmt", "gitea-fmt":) for one release. Bonus: corrected a stale `koder.devdevflowenginebuildcodeformat` import path (postRFC003 location).
  • *ackage paths rename (#102 sub2 / #104)*— models/gitea_migrations/models/koder_flow_migrations/ (git mv preserves history). Package declaration updated in the 3 root files; 58 files swept via sed for both prefix styles (`koderflow.org... legacy and koder.devproductsdevflowengine... canonical). Symbol references in doctor/cmd/routers/tests + string literal fixturesDir path + configs (Makefile, .air.toml, .golangci.yml, .semgrep, coverage-helper, code-batch-process). Migration history is tracked by integer idNumber` — no data risk from the Go rename.
  • *nv vars rename (#102 sub3 / #105)*— GITEA_ROOT/CONF/RUN_MODE/WORK_DIR/CUSTOM/TEMP/APP_INI*KODER_FLOW_* with a oneshot deprecation warning when the legacy name is read. setting.GetenvAliased(canonical, legacy) is the new helper consumed by setting/{setting,path}.go, base/tool.go::SetupGiteaRoot, and tests/test_utils.go::InitTest. Makefile's 30 testtarget invocations now pass KODER_FLOW_ROOT/CONF; Dockerfile + Dockerfile.rootless ENV names use KODER_FLOW_* while keeping /var/lib/gitea / /data/gitea as ondisk path values so existing mounted volumes still work.
  • *rometheus metrics dualemit (#102 sub4 / #106)*— modules/metrics/collector.go now uses a dualDesc{canonical, legacy} helper so every one of the 27 metrics is published under BOTH the canonical koder_flow_ prefix and the legacy gitea_ prefix during the rebrand transition. The legacy descriptors carry a DEPRECATED suffix in their # HELP line so scrapers see the migration notice. Grafana dashboards in contrib/flow-monitoring-mixin/ are migrated to query koder_flow_* (config + jsonnet locals + dashboard UID renamed). The gitea_* emission stays for a 2release deprecation window before removal. *FC005 Phase 3 umbrella (#102) is now fully shipped — all 5 sub-tickets complete.*
  • *CP createissue labels + assignees (#108)*— extends the MCP `createissue tool input schema with labels: string[] and assignees: string[]. Labels resolve through issuesmodel.GetLabelIDsInRepoByNames (fail loudly when any name doesn't exist on the repo — agentic callers should not silently lose triage data); assignees resolve through usermodel.GetUserByName per login. Both inputs dedup on the way in via the package-local dedupStrings. Schema + Go struct shape locked by a regression test in testsregression004mcpcreateissuelabelsassigneestest.go`.
  • *CP pertoken rate limit (#109)*— wires the previouslydormant setting.MCP.MaxCallsPerMinute (default 1000) into a tokenbucket per Principal.TokenID in services/mcp/ratelimit.go. Handler.Dispatch consults Allow(tokenID) before any dataplane method; control-plane (initialize, ping, `notifications

Source: ../home/koder/dev/koder/meta/docs/stack/modules/flow.md