# GitHub as the source of truth for client engagements

*How we manage client relationships with the same Goals, Problems, and specs we use to ship code.*

**Authors:** [Vadim Zolotokrylin](/c/people/vadim-zolotokrylin)

---

Most consulting engagements have a fragmentation problem.
The contract lives in email.
The backlog lives in Notion or Linear.
Status updates happen in Slack.
Time gets logged in a spreadsheet, or not at all.
Nobody has the full picture in one place,
and nobody agrees on what the full picture even is.

We moved all of it to GitHub —
and the same workflow we use to ship code now runs every client relationship we
have.

## One repo per customer

Each client gets a private repository: `customer-{name}`.
It follows the same Goal → Problem → Solution structure we use in every product
repo.

A Goal issue is the top-level object.
It represents the business aim:
what we are trying to achieve for this customer and by when.
Every problem, conversation, and decision lives under it.

<!-- ref: https://github.com/holdex/customer-truflation-trufnetwork/issues/1
     The TRUF.network customer repo is the live example of this structure. -->

Problems are child issues.
They describe specific blockers — a contract that hasn't been signed,
a team member who's the only developer,
an ambiguity about whether the engagement is continuing.
Each one gets a proposed solution in the issue body
before anyone starts working on it.

The Goal issue body stays minimal: org links, ETA, and a link to the spec.

## Specs for context, not just code

In product repos, a spec describes unimplemented behavior —
a file that shrinks as features ship, deleted when the Goal is complete.
That pattern is described in detail in
[The Spec That Shrinks](./spec-lifecycle.md).

<!-- ref: https://github.com/holdex/marketing/blob/main/docs/articles/spec-lifecycle.md
     The spec-lifecycle article covers the product development use of docs/specs/. -->

In a customer repo, the spec serves a different purpose.
It is a running record of the engagement: what's happening, what's at risk,
what needs to happen next.
It does not shrink — it grows as the relationship evolves.
Each section maps to an open problem or an active goal.
A section about a stalled contract sits next to a section about a team risk.
Both are in one file, in one repo, readable by anyone on the account team.

The file lives at `docs/specs/{customer}.md`,
committed via PR so every change is reviewed and versioned.
Same location, same discipline — different lifecycle.

<!-- ref: https://github.com/holdex/customer-truflation-trufnetwork/pull/17
     First spec doc created for a customer repo, establishing the pattern. -->

## Time tracked where the work lives

Work on a client engagement produces pull requests — spec drafts, issue triage,
onboarding docs.
Time gets submitted on the PR, not in a separate system.

The wizard bot accepts `@holdex pr submit-time 2h30m` in any PR comment.
The format is short: `15m`, `1h`, `2h30m`.
No spreadsheet.
No end-of-week reconciliation — time is logged on the PR when the work happens,
not collected into a separate summary at the end of the week.
The log is attached to the artifact that produced it.

<!-- ref: https://wizard.holdex.io/docs/commands
     Full command reference for the Holdex wizard bot. -->

## Why the same tool matters

The most important property of this setup isn't convenience — it's coherence.

The people doing the client work are the same people using GitHub every day
for product development.
There's no context switch.
When a developer needs to understand the state of the engagement,
they open GitHub.
When an account manager needs to log a decision, they open GitHub.
When a partner needs to see what's at risk, they open GitHub.

A Slack message disappears.
A Notion page drifts.
A GitHub issue with a linked spec and a comment trail is auditable, searchable,
and connected to every PR that touched it.

The engagement has the same shape as the product work: Goals at the top,
Problems underneath, Solutions as pull requests.
That consistency is not an accident —
it's what makes the system usable across roles and across time.
