How-to › Document and support developers

How to run developer management routines as a fractional CTO#

Set up a weekly update, one-to-ones, an architecture review, a decision log, and an escalation rule that run without you, then check them after a week away.

Audience
Platform team
Level
advanced
Topic
Run developer relations
Verified

You lead an engineering team two days a week. On the other three, the weekly update does not go out and decisions wait in a thread for your return. The team pages you about a sev2 because you fixed the last one. Every routine depends on you being in the room, so the team ships at the pace of your calendar.

What you get

You will end up with four routines and an escalation rule that run without you, plus a checker that reads the record of a week away. This is for you if you lead a small engineering team part-time.

Short answer

Run four routines that work without you in the room: a weekly update with a named author, fortnightly one-to-ones, a monthly architecture review, and a decision log that names each decider. Write an escalation rule that lists what may interrupt an off day, and keep yourself off the incident rota. Then take a week away and check that the update went out, the log grew, and each incident went to its owner.

You will need

An engineering team of three to twelve people, and a tracker the whole team already uses, so the work is visible without a meeting. Node 22 or later for the checker, which uses no packages. The team, its decisions, and its incidents in the sample are fixtures.

Approaches compared

The routines need somewhere to make work visible. Three trackers, compared on that job alone:

ApproachWhen it fitsWhat it costs youWhen to pick something else
GitHub ProjectsThe code and its issues already live on GitHub, and one team works in one projectStatus updates are written by hand per project, so the routine depends on someone rememberingSeveral teams need one roadmap, or the work is not code
JiraThe client already runs Jira, or several teams share one workflowConfiguration is a job of its own, and a two-day CTO cannot also be its administratorA team under twelve with no Jira to inherit
LinearA product team that wants cycles, triage, and project updates with scheduled remindersA seat per person, and a tool the client pays for after you leaveThe client will not add a tool, or the team already lives in GitHub

Pick the one the team already opens every day. Project updates in Linear carry a health indicator. A workspace can also set reminders that ask each project lead for one at a regular cadence, which suits a CTO who is not there to ask. GitHub Projects keeps the work beside the code, but its status updates rely on someone remembering.1 Jira earns its place only when it is already the client’s system of record.

Choose the engagement shape

The shape decides how much control you have and what each day of it is for. More days buys more control, and spreads the same judgment thinner across more hours.

ShapeDaysDecidesFits when
Technical advisorA few hours a monthNothing; advises the founder or CTO who decidesA technical leader exists and wants a second opinion
Retained fractional CTOOne or two days a week, open-endedArchitecture and hiring, through the routines on this pageNo full-time CTO yet, and a team of three to twelve
Interim CTOFour or five days a week, for a fixed termEverything a CTO decides, until a permanent one startsThe previous CTO left, or a crisis needs daily presence

A fractional engagement fails as an interim one done on two days. Every decision then waits two days for you, and the team learns to wait. The routines below are what make two days enough.

Set the four routines

Each routine has an owner who is not you, a cadence, and an artifact a stranger could read.

The weekly update is written by the tech lead and sent by 17:00 UTC on Friday. It names what shipped, what was decided, with decision ids, and who owns incidents next week. Fortnightly one-to-ones run on your in-office days and never move to an off day, which keeps those days free.

The monthly architecture review reads the decision log rather than starting from slides. Any entry can be reopened there, which is what lets you delegate the decision in the first place. The log follows the architecture decision record format at a smaller size: a numbered entry, a date, a decider, and a status.2

Write the escalation rule

Write down what may interrupt an off day, and who decides everything else. The sample keeps it in team.json, where the checker can read it:

  "cto": "Sam Rivera",
  "updateDue": { "weekday": "Friday", "timeUtc": "17:00" },
  "escalation": {
    "interruptCtoFor": ["sev1", "security"],
    "everythingElse": "the incident owner on the rota decides; the tech lead decides architecture inside the guardrails"
  },

Two things interrupt: a sev1, and anything tagged security. A sev2 at 03:00 belongs to the incident owner, who can wake a teammate but not you.

Hand incidents to a named owner

The trap is becoming the on-call senior engineer. You fixed the hardest incident in your first month, so the next one comes to you, and your management days become repair days. Keep yourself off the rota. Each week names one incident owner, and that person runs the incident as its incident commander, delegating the hands-on work rather than doing it.3

  const owner = team.incidentOwners[week]
  const allowed = new Set(team.escalation.interruptCtoFor)
  if (owner === cto) results.push({ held: false, routine: 'incident owner', detail: `the rota names ${cto} for ${week}; take yourself off it` })
  // An incident whose time cannot be read belongs to no week, and would otherwise vanish from all of them.
  for (const inc of incidents.filter((i) => Number.isNaN(instant(i.opened)))) {
    results.push({ held: false, routine: 'incident owner', detail: `${inc.id}: opened "${inc.opened}" needs a date and time with a zone` })
  }
  for (const inc of incidents.filter((i) => inWeek(i.opened))) {
    if (!owner) results.push({ held: false, routine: 'incident owner', detail: `${inc.id}: nobody on the rota for ${week}` })
    else if (inc.handledBy !== owner) results.push({ held: false, routine: 'incident owner', detail: `${inc.id} ${inc.severity} handled by ${inc.handledBy}, not ${owner}` })
    else results.push({ held: true, routine: 'incident owner', detail: `${inc.id} ${inc.severity} handled by ${owner}` })

The checker fails a rota that names you, even in a week with no incidents, because the habit forms before the incident does. It also fails an incident whose opened time has no zone, because Date.parse would read that time in the zone of whichever machine runs the check. The same rule applies to the update’s Sent line.

Take a week away and check

The test of the routines is an unplanned week without you. Afterwards, run the checker on that ISO week and on an earlier one for comparison:

node routines.mjs 2026-W41 2026-W38
2026-W41 (2026-10-05 to 2026-10-11), Sam Rivera away
  held          weekly update  sent by Priya Shah at 2026-10-09T15:40:00Z
  held          decision log   2 entries: D-032 by Priya Shah, D-033 by Tom Okafor
  held          incident owner INC-111 sev2 handled by Tom Okafor
  held          incident owner INC-112 sev1 handled by Tom Okafor
  held          escalation     INC-112 sev1 interrupted Sam Rivera, which the rule allows
  all 5 checks held
2026-W38 (2026-09-14 to 2026-09-20), Sam Rivera away
  DID NOT HOLD  weekly update  written by Sam Rivera, sent 2026-09-21T09:30:00Z
  DID NOT HOLD  decision log   no entries dated in 2026-W38; D-030 (2026-09-21) decided by Sam Rivera on return
  DID NOT HOLD  incident owner INC-108 sev2 handled by Sam Rivera, not Ana Costa
  DID NOT HOLD  escalation     INC-108 sev2 interrupted Sam Rivera, which the rule does not allow

Week 38 is the before picture. The update was written on the Monday after, by the CTO. The one decision raised that week waited for the return. A sev2 went to the person who had fixed the last one instead of the person on the rota. Week 41 is the same team after the routines. The tech lead wrote the update, two people made decisions, and the one interruption was a sev1, which the rule allows.

Check it worked

Run the tests. Thirteen cases cover ISO week boundaries, both fixture weeks, a late update, a missing Sent line, a decision with no decider, an empty rota, a security tag, and a rota that names you. Three of them cover a time with no zone, last week’s update copied with its Sent line, and an incident the checker cannot place in a week.

node --test
1..13
# tests 13
# suites 0
# pass 13
# fail 0
# cancelled 0
# skipped 0
# todo 0
# duration_ms 111.739191

The literal to look for in your own week away is all 5 checks held, or however many checks the week produced. One DID NOT HOLD line names the routine to fix first.

When it goes wrong

The decision log fails in a quiet week. Nothing needed deciding, so nothing was logged. Read the hint: if no decision you made in the three days after your return could have been made while you were gone, the week passed.

The update goes out late, every week, by an hour. The deadline sits on a day the tech lead spends in a customer meeting. Move the deadline, not the author.

The team escalates a sev2 because the rule is ambiguous. “Customer-facing” and “severe” mean different things to each person. Name the severity levels and tags, as interruptCtoFor does, and review each escalation at the next architecture review.

When not to do this

Do not take a fractional role on a team with nobody who can write the update or own an incident. The routines delegate to people, so a team with no tech lead leaves them nobody to delegate to. That team needs an interim CTO or a first senior hire.

Do not use the decision log to approve decisions after the fact. An entry that waits for your signature is a queue, and the checker counts it as one.

Do not install a tracker for the routines’ sake. If the team lives in GitHub, GitHub Projects is enough, and a second tool splits the work you are trying to see.

Do not test the routines with a planned week away. A planned absence gets prepared for, so it tests a team that had warning rather than the one you will have on an ordinary Tuesday.

Last verified

Verified 2026-10-15 against Node 22.22.0. Every output block is what the command preceding it printed. The team, its decision log, its updates, and its incidents are fixtures written for this page; the tracker and incident behavior is quoted from each vendor’s documentation as read on that date.

Footnotes

  1. A new status update in GitHub Projects starts from the last one. The form defaults to the previous update’s status, start date, and target date, so an update nobody edits repeats last week’s. It is sometimes accurate. ↩︎ Back to text

  2. Michael Nygard proposed the format in a 2011 post titled Documenting Architecture Decisions, with sections for context, decision, status, and consequences. Near the end the post points out that it is formatted like an ADR itself. Its status section reads, in full, “Accepted.” ↩︎ Back to text

  3. PagerDuty’s guide for incident commanders says the commander becomes the highest ranking individual on a major incident call, regardless of their day-to-day rank. It asks for someone willing to remove distractions from the call, even if it’s the CEO. A CTO who joins the call can be asked to leave it by the person on the rota. ↩︎ Back to text

Read this page as markdown · All how-to guides

Generate the client instead of writing it#

Retries, timeouts, pagination and auth are the same problems in every client. Voxgig generates them from your OpenAPI description, in 23 languages, from one model.

Listen to Fireside, the Voxgig podcast

Since 2018, Richard Rodger has talked with developer advocates, event organizers, and the people who build developer-facing companies about the specifics of the work.