Developer guide
This guide is for people changing PULSE or building against its API.
Repository layout
| Path | What it holds |
|---|---|
grpc/ | The Go backend, module github.com/org-runink/pulse (Go 1.26) |
grpc/main.go, grpc/cmd/ | The Cobra entry point and every service. cmd/serve.go wires everything together. |
grpc/api/proto/pulse/v1/ | The .proto files: pulse.proto, activity.proto, commons.proto |
grpc/api/proto-vendor/ | A verbatim copy of runink/ui/judgement/v1/judgement.proto, resolved but never generated |
grpc/api/v1/ | Generated Go code, committed |
grpc/internal/ | ai, db, scoring, apply, metasearch, openbias, forecast, connector clients (hubspot, github, googleanalytics, googleads, spotify), telephony, voice, webrtc, and more |
grpc/agents/ | Agent parameters (pulse.ini), prompt templates, and guardrail rules |
flutter/lib/ | The Flutter app: core/ (gRPC channel, generated stubs, cache, theme) and features/ (one folder per screen) |
website/ | This documentation site |
The platform pieces are not here. Self-healing, the event mesh, secrets and PKI, the object store, the inference engine, the operator, and infrastructure code live in CORE or in the extracted libraries. Never add them to this repository.
Build and test
The backend builds only with the sibling repositories checked out next to
pulse/: inference, security, mesh, store, ui, and billing.
cd grpc && go build -o bin/pulse-server .
cd grpc && go test ./...
cd grpc && go vet ./...
cd flutter && flutter analyzeGOWORK file outside the
repository at it. Don’t switch the shared checkout.To run the backend, see Run PULSE locally.
Regenerate the protobuf code
Run both commands from the repository root, and always pass the
grpc/api/proto input:
buf generate grpc/api/proto --template grpc/buf.gen.yaml -o grpc # Go
buf generate grpc/api/proto --template grpc/buf.gen.dart.yaml # Dart, no -o- The Go run needs
-o grpc, or the code lands at the repository root. - The first command does not generate Dart, and nothing tells you. Skip the second and the app compiles against the old messages, and a new field reads as null on the client.
- Running
buffrom insidegrpc/picks up a competingbuf.yamland breaks import resolution. - Codegen uses local plugins on your
PATH:protoc-gen-go,protoc-gen-go-grpc, andprotoc-gen-dart. - When
uichangesjudgement.proto, copy it again intoproto-vendor/.grpc/cmd/judgement_vendored_test.gofails until you do.
The app’s backend address
The Flutter client reads PULSE_BACKEND_URL from a --dart-define, default
http://localhost:50051. The web build bakes it in at compile time.
Shared UI components
Pages that more than one Runink app shows come from org-runink/ui: design
tokens and transport (foundation), billing, datasources, profile, and
access. PULSE mounts the Go handler with its own hooks and depends on the
Flutter package by path. To try an unmerged ui branch, use a private
GOWORK and a gitignored flutter/pubspec_overrides.yaml.
Licence rules for contributions
PULSE is proprietary.
- New files start with an SPDX header:
SPDX-License-Identifier: LicenseRef-Runink-Proprietary. - After a dependency change, run
scripts/gen-third-party-notices.sh. CI fails on stale notices and on disallowed licences. - Release builds stay hardened: Go
-trimpath -ldflags="-s -w", Flutter web--no-source-maps.