Telecraft

Contributing to Telecraft

Telecraft is a Go core with a TypeScript and React console, built against a design corpus that settles most questions before code is written. This section is the developer's half of the documentation: everything about building the product, rather than using it.

Read the page that matches what you are doing:

  • Development covers prerequisites and every build, test and lint command that CI runs.
  • Local development environment runs real collectors under real Supervisors against a real backend, and drives the estate into the states worth looking at.
  • Continuous integration covers the four workflows, what decides which jobs run, and how a change reaches the public demo and the documentation site.
  • Architecture maps the packages, draws the neutral core boundary, and follows a verdict from authored files to output.
  • Providers explains how to implement each seam and pass its conformance kit.
  • Console covers the five Workspaces, the card data contract, the canvas engine, and the zero-CDN rule.
  • Decisions explains the ADR process and maps the ADRs by theme.
  • Documentation explains how this documentation system works, the house style and the rules for interface text, and how to add a page.
  • Releases explains what a version number means, what a release contains, and how to cut one.

Before you write code

Most questions have an answer in the corpus already. Find the decision that governs the area you are touching, and read it before you change anything: the decisions page groups the ADRs by theme, and docs/requirements/traceability.md maps each requirement to the ADRs that decide it.

If you disagree with a decision, that is a new ADR, not a code change. An accepted ADR is amended by a superseding ADR, never edited in place.

If your change needs a term the corpus does not have, add it to docs/glossary.md. Every capitalised domain term used in an ADR has a glossary entry, and ADR-0015 fixes the current vocabulary: Tier, Service Class, Sensitivity, Effective, and Service. The words those replaced are errors, not synonyms.

Issues

Work is tracked in the issue tracker. Open an issue before a substantial change, so the design conversation happens before the diff exists.

A good issue states what the change is, which requirement or ADR it serves, and what "done" looks like as acceptance criteria a reviewer can check. Small fixes (a typo, a broken link, a failing edge case with an obvious cause) need no issue: open the pull request.

Branches and pull requests

Branch off main. Nothing lands on main except through a pull request, and main stays green.

Name the branch after the work, with the build phase or the documentation section as its prefix: p6/demo-deep-links, docs/contributing. If you do not have write access to the repository, push the branch to a fork and open the pull request from there.

Write commit subjects as an area, a colon, and what the commit does:

renderer: OTLP-push self-telemetry in every artefact with the Tier stamp
console: an entry document per Workspace URL, so deep links answer 200 (Refs #50)

The area is the package or component the change belongs to (renderer, console, card, ci). Reference the issue as (issue #34) or (Refs #50), and the decision as (ADR-0041 §4), when either explains why the change looks the way it does. Commit in logical increments: one commit per idea, not one commit per file and not one commit per branch.

What review expects:

  • A decision behind the change. Anything that establishes a rule, a vocabulary, or a seam cites the ADR it follows, or ships a new ADR.
  • Tests that fail without the change. New behaviour arrives with the test that proves it, and a bug fix arrives with the test that reproduced it.
  • No partial work. A merged change works end to end. Placeholder functions, stubs, and unimplemented branches do not merge.
  • Green CI. Every check that ran passes before review, not after it.
  • House style in user-visible prose. Documentation, error messages, and UI text follow the rules on the documentation page. Console surfaces, CLI output and findings carry the extra rules for interface text: no rationale on screen, a label rather than an instruction, and the plain word wherever the glossary does not supply an exact one.

What CI checks

Every pull request runs .github/workflows/ci.yml. A first job diffs the change and decides what the rest of them do, so a documentation-only pull request does not stand up Elasticsearch or install a browser, and a skipped job reports success, which is what makes that safe. The continuous integration page explains the gating, the live suites, and the workflows beyond this one.

Each remaining job guards something specific:

Check What it runs What it guards
Build and test go build ./..., go vet ./..., go test ./... The core compiles, passes vet, and passes its unit tests, with no Docker and no network.
Vendor-word lint (ADR-0001) go run ./tools/vendorlint The neutral core holds. No vendor word appears in cmd/, internal/, console/ or the normative docs, and provider implementations stay product-qualified.
Documentation front matter go run ./tools/docslint Every published page carries front matter the documentation site can read. The site is built in another repository, so a malformed block fails there rather than here.
No tracked binaries (issue #122) go run ./tools/binlint No tracked file is a compiled executable. A build artefact is built, never committed, so nothing ships a platform-specific binary in a clone or a source tarball.
Go formatting (issue #146) go run ./tools/fmtlint Every tracked Go file is gofmt clean, naming the ones that are not. go build, go vet and go test never read layout, so an unformatted file otherwise passes every check the repository has.
Console (ADR-0045) npm ci, npm run typecheck, npm test, npm run check:palette, npm run build, npm run check:zero-cdn, npm run check:bundle-budget, npm run e2e The console typechecks, its unit tests and Playwright suite pass, the design tokens clear their contrast and colour-vision floors (ADR-0047), the built bundle reaches no external host, and its entry chunk stays within its gzipped ceiling (issue #125).
TelemetryProvider live (Elasticsearch) go test ./internal/provider/telemetry/ -run Live -v -count=1 against a single-node Elasticsearch service container The telemetry queries work against a real backend, not only against a test double.
Forge adapter live (GitHub App) go test ./internal/provider/forge/ -run Live -v -count=1 The pull-request flow works against the real forge API. The suite skips loudly when the credentials are absent, so the job stays green without them.
Demo snapshot and bundle (issue #50) npm run build:demo, npm run check:zero-cdn, go run ./cmd/telecraft snapshot, and the entry-document check The public demo's two halves keep working: the snapshot the real evaluators produce, and the console bundle that reads it.

Run all of them locally before you push. The development page lists each command and what it needs.

Where to ask questions

Ask in the issue tracker: open an issue for a question about the product or the design, or comment on the issue or pull request the question belongs to. The repository has no discussion forum, so the tracker is the one place a question and its answer stay findable.

If the answer turns out to be a decision, it becomes an ADR. If it turns out to be missing documentation, it becomes a page in this section or in the user-facing sections.

One kind of report goes somewhere else. A suspected vulnerability belongs in GitHub's private advisory channel rather than the tracker, and SECURITY.md covers how to send it, which versions are supported, and what response to expect.