Tool

create_pin

Create pinChanges data

Description

Pin out-of-scope work you find, or work the user puts off, as soon as it comes up and without asking, so it isn't lost when this session ends. Write it for the agent who'll pick it up with none of your context: what's wrong or wanted, where, how it came up, what to watch out for, and how you'd do it. Duplicates are checked first: the closest pins are read beside yours, and if one is the same issue, nothing is created and it's returned (error possible_duplicates). Then either add_sighting to the match, or call again with confirm_not_duplicate. Related pins come back as related. Resolved pins never block; one whose problem is back comes back as possible_regressions.

Parameters

repostringrequired

Repository as owner/name, from the git remote. Picks the workspace: the one with pins in this repo.

3–200 characters

workspacestring

Workspace slug. Only when the repo has pins in several of your workspaces, or in none yet; otherwise the repo picks it. - acme: Acme (acme/api) - acme-mobile: Acme Mobile (acme/ios)

Your workspaces, e.g.acmeacme-mobile

titlestringrequired

One line.

5–200 characters

summarystringrequired

What's wrong or wanted, in a short paragraph.

10–4000 characters

kindstringrequired

What sort of work this is. feature is new functionality, such as a request the user deferred; dx is friction in the developer experience.

One ofbugdebtperformancesecuritytestingdxdocsfeature

riskstringrequired

Cost of leaving it alone (for a feature, of going without it): how bad it gets when it bites, and how likely it is to bite. Severe harm that's unlikely is medium, not high; a long quiet history is evidence it's unlikely. critical, e.g. a security hole, lost or corrupted data, money charged wrongly, an outage now or imminent. high, e.g. users blocked from something they need, a frequent wrong result, a deadline that will break something, a likely incident. medium, e.g. a visible bug with a workaround, slow pages, flaky tests, code that will trip whoever changes it next. low, e.g. cosmetic issues, rare edge cases, harm that's only theoretical, messy code that works.

One oflowmediumhighcritical

payoffstringrequired

Gain from doing it: how much better it makes things for the people it reaches, and how many it reaches how often; the product's users first, then the team. critical, e.g. a core workflow most users run daily, something customers leave or pay over. high, e.g. a capability users expect and keep asking for, friction or slowness the whole team hits every day, a big unlock for other work. medium, e.g. a real improvement for some users, friction the team hits now and then, a nicer path on a secondary screen. low, e.g. something one person noticed once, tidier code nobody sees, polish nobody would miss. Debt nobody sees stays low; if it blocks other pins, link them, and if waiting makes it costlier, set harder_later.

One oflowmediumhighcritical

scopestringrequired

Size of the fix.

One oftrivialsmallmediumlargeepic

harder_laterboolean

True when waiting makes the fix costlier: data piling up that a migration must convert, an API or format others will start depending on, a one-way door. Raises priority.

areasstring[]

1 to 3 existing areas of the pin's workspace. Required unless new_area is given. acme (acme/api): - auth: Sign-in, sessions and permissions - payments: Billing, invoices and checkout acme-mobile (acme/ios): - offline: Sync and offline storage

Your workspace's areas, e.g.authofflinepayments

1–3 items

filesobject[]

Where it is. Repo-relative, e.g. src/auth.ts. Never absolute. Give the symbol, and a snippet of the lines that show the problem: line numbers drift, they don't.

up to 50 items

pathstringrequired

Repo-relative path, e.g. src/auth.ts. Never absolute.

1–500 characters

linesstring

Line range, e.g. "40-88".

symbolstring

Function or class name.

up to 200 characters

snippetstring

The 1 to 5 lines that show the problem, copied exactly; not the function signature. Most useful when no symbol names the place, so the next agent can find it after the code moves.

up to 2000 characters

commitstring

HEAD SHA when you found it. File lines and snippets are read at this commit.

pattern: ^[0-9a-f]{7,40}$

confidencestring

One ofconfirmedsuspected

discoverystring

How it came up: what you were doing, or what the user said.

1–8000 characters

gotchasstring[]

Traps for whoever fixes it, one per entry.

up to 20 items · each 1–4000 characters

reprostring

Steps to reproduce.

1–8000 characters

approachstring

The fix you'd try, and what you ruled out.

1–8000 characters

approach_stagestring

Whether a person shaped approach. proposed (default): your own idea; leave it. discussed: the user talked the fix through with you, but points are still open. agreed: the user settled the fix with you. Set discussed or agreed only when the user actually worked the approach out with you, at filing or later; never ask them to discuss a pin just to set it. agreed raises priority.

One ofproposeddiscussedagreed

done_whenstring

How to verify the fix.

1–8000 characters

new_areaobject

Only if no existing area fits: a short concept name and a one-line description.

namestringrequired

2–40 characters

descriptionstringrequired

3–200 characters

confirm_new_areastring

Why none of the existing areas fit. Required with new_area after an area_near_match error.

3–500 characters

confirm_not_duplicatestring

Why this differs from the candidates a previous call returned. Skips the duplicate check.

3–500 characters

Response

An example. The result sits in the same envelope as every tool's; see Responses.

JSON
{
  "workspace": {
    "slug": "acme",
    "name": "Acme"
  },
  "result": {
    "pin": {
      "key": "ACME-42",
      "url": "https://laterbase.dev/dashboard/pins/ACME-42",
      "title": "Session refresh races when two tabs refresh at once",
      "status": "open",
      "summary": "Two tabs refreshing an expired session at the same moment both rotate the refresh token; the loser is signed out.",
      "repo": "acme/api",
      "kind": "bug",
      "areas": [
        "auth"
      ],
      "risk": "high",
      "payoff": "high",
      "scope": "small",
      "leverage": "high",
      "priority": "critical",
      "claimed_by": null,
      "sightings": 2,
      "created_at": "2026-10-01T14:03:11.000Z",
      "status_changed_at": "2026-10-01T14:03:11.000Z"
    },
    "tell_user": "In your next reply, say in a line that you pinned [ACME-42](https://laterbase.dev/dashboard/pins/ACME-42) and what it's for."
  }
}

Input schema

Exactly what tools/list sends your agent.

JSON
{
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "type": "object",
  "properties": {
    "repo": {
      "type": "string",
      "minLength": 3,
      "maxLength": 200,
      "description": "Repository as `owner/name`, from the git remote. Picks the workspace: the one with pins in this repo."
    },
    "workspace": {
      "description": "Workspace slug. Only when the repo has pins in several of your workspaces, or in none yet; otherwise the repo picks it.\n- acme: Acme (acme/api)\n- acme-mobile: Acme Mobile (acme/ios)",
      "type": "string",
      "enum": [
        "acme",
        "acme-mobile"
      ]
    },
    "title": {
      "type": "string",
      "minLength": 5,
      "maxLength": 200,
      "description": "One line."
    },
    "summary": {
      "type": "string",
      "minLength": 10,
      "maxLength": 4000,
      "description": "What's wrong or wanted, in a short paragraph."
    },
    "kind": {
      "type": "string",
      "enum": [
        "bug",
        "debt",
        "performance",
        "security",
        "testing",
        "dx",
        "docs",
        "feature"
      ],
      "description": "What sort of work this is. `feature` is new functionality, such as a request the user deferred; `dx` is friction in the developer experience."
    },
    "risk": {
      "type": "string",
      "enum": [
        "low",
        "medium",
        "high",
        "critical"
      ],
      "description": "Cost of leaving it alone (for a feature, of going without it): how bad it gets when it bites, and how likely it is to bite. Severe harm that's unlikely is medium, not high; a long quiet history is evidence it's unlikely. critical, e.g. a security hole, lost or corrupted data, money charged wrongly, an outage now or imminent. high, e.g. users blocked from something they need, a frequent wrong result, a deadline that will break something, a likely incident. medium, e.g. a visible bug with a workaround, slow pages, flaky tests, code that will trip whoever changes it next. low, e.g. cosmetic issues, rare edge cases, harm that's only theoretical, messy code that works."
    },
    "payoff": {
      "type": "string",
      "enum": [
        "low",
        "medium",
        "high",
        "critical"
      ],
      "description": "Gain from doing it: how much better it makes things for the people it reaches, and how many it reaches how often; the product's users first, then the team. critical, e.g. a core workflow most users run daily, something customers leave or pay over. high, e.g. a capability users expect and keep asking for, friction or slowness the whole team hits every day, a big unlock for other work. medium, e.g. a real improvement for some users, friction the team hits now and then, a nicer path on a secondary screen. low, e.g. something one person noticed once, tidier code nobody sees, polish nobody would miss. Debt nobody sees stays low; if it blocks other pins, link them, and if waiting makes it costlier, set harder_later."
    },
    "scope": {
      "type": "string",
      "enum": [
        "trivial",
        "small",
        "medium",
        "large",
        "epic"
      ],
      "description": "Size of the fix."
    },
    "harder_later": {
      "description": "True when waiting makes the fix costlier: data piling up that a migration must convert, an API or format others will start depending on, a one-way door. Raises priority.",
      "type": "boolean"
    },
    "areas": {
      "description": "1 to 3 existing areas of the pin's workspace. Required unless new_area is given.\nacme (acme/api):\n- auth: Sign-in, sessions and permissions\n- payments: Billing, invoices and checkout\nacme-mobile (acme/ios):\n- offline: Sync and offline storage",
      "minItems": 1,
      "maxItems": 3,
      "type": "array",
      "items": {
        "type": "string",
        "enum": [
          "auth",
          "offline",
          "payments"
        ]
      }
    },
    "files": {
      "description": "Where it is. Repo-relative, e.g. `src/auth.ts`. Never absolute. Give the symbol, and a snippet of the lines that show the problem: line numbers drift, they don't.",
      "maxItems": 50,
      "type": "array",
      "items": {
        "type": "object",
        "properties": {
          "path": {
            "type": "string",
            "minLength": 1,
            "maxLength": 500,
            "description": "Repo-relative path, e.g. src/auth.ts. Never absolute."
          },
          "lines": {
            "description": "Line range, e.g. \"40-88\".",
            "type": "string"
          },
          "symbol": {
            "description": "Function or class name.",
            "type": "string",
            "maxLength": 200
          },
          "snippet": {
            "description": "The 1 to 5 lines that show the problem, copied exactly; not the function signature. Most useful when no symbol names the place, so the next agent can find it after the code moves.",
            "type": "string",
            "maxLength": 2000
          }
        },
        "required": [
          "path"
        ]
      }
    },
    "commit": {
      "description": "HEAD SHA when you found it. File lines and snippets are read at this commit.",
      "type": "string",
      "pattern": "^[0-9a-f]{7,40}$"
    },
    "confidence": {
      "type": "string",
      "enum": [
        "confirmed",
        "suspected"
      ]
    },
    "discovery": {
      "description": "How it came up: what you were doing, or what the user said.",
      "type": "string",
      "minLength": 1,
      "maxLength": 8000
    },
    "gotchas": {
      "description": "Traps for whoever fixes it, one per entry.",
      "maxItems": 20,
      "type": "array",
      "items": {
        "type": "string",
        "minLength": 1,
        "maxLength": 4000
      }
    },
    "repro": {
      "description": "Steps to reproduce.",
      "type": "string",
      "minLength": 1,
      "maxLength": 8000
    },
    "approach": {
      "description": "The fix you'd try, and what you ruled out.",
      "type": "string",
      "minLength": 1,
      "maxLength": 8000
    },
    "approach_stage": {
      "description": "Whether a person shaped `approach`. proposed (default): your own idea; leave it. discussed: the user talked the fix through with you, but points are still open. agreed: the user settled the fix with you. Set discussed or agreed only when the user actually worked the approach out with you, at filing or later; never ask them to discuss a pin just to set it. agreed raises priority.",
      "type": "string",
      "enum": [
        "proposed",
        "discussed",
        "agreed"
      ]
    },
    "done_when": {
      "description": "How to verify the fix.",
      "type": "string",
      "minLength": 1,
      "maxLength": 8000
    },
    "links": {
      "description": "How this pin relates to other pins and to PRs, commits, branches, issues or sessions: { relation, pin } or { relation, artifact, kind? }. found_in: where you found it. fixed_in: the PR or commit that fixes it; link it as soon as the PR is open, not only once it merges. related: loosely connected; pin keys, PRs, issues and commits you mention in the pin's text are linked as related for you, so cite them freely. blocks: another pin can't start or ship until this one is done. blocked_by: the same link from the other side, when this pin can't start or ship until another is done; to track a release, give the release pin a blocked_by for each pin it needs. duplicate_of: another pin covers this. e.g. { \"relation\": \"found_in\", \"artifact\": \"#212\" }, { \"relation\": \"blocks\", \"pin\": \"ACME-14\" }, { \"relation\": \"blocked_by\", \"pin\": \"ACME-9\" }.",
      "maxItems": 50,
      "type": "array",
      "items": {
        "type": "object",
        "properties": {
          "relation": {
            "type": "string",
            "enum": [
              "found_in",
              "fixed_in",
              "related",
              "blocks",
              "duplicate_of",
              "blocked_by"
            ]
          },
          "pin": {
            "description": "Another pin's key, e.g. ACME-42.",
            "type": "string",
            "minLength": 1,
            "maxLength": 50
          },
          "artifact": {
            "description": "A URL, owner/name#123, #123 (this pin's repo), a commit SHA or a branch name.",
            "type": "string",
            "minLength": 1,
            "maxLength": 500
          },
          "kind": {
            "description": "What `artifact` is when the text can't say: a branch name, an issue number, an agent session.",
            "type": "string",
            "enum": [
              "pr",
              "commit",
              "branch",
              "issue",
              "session",
              "url"
            ]
          }
        },
        "required": [
          "relation"
        ]
      }
    },
    "new_area": {
      "description": "Only if no existing area fits: a short concept name and a one-line description.",
      "type": "object",
      "properties": {
        "name": {
          "type": "string",
          "minLength": 2,
          "maxLength": 40
        },
        "description": {
          "type": "string",
          "minLength": 3,
          "maxLength": 200
        }
      },
      "required": [
        "name",
        "description"
      ]
    },
    "confirm_new_area": {
      "description": "Why none of the existing areas fit. Required with new_area after an area_near_match error.",
      "type": "string",
      "minLength": 3,
      "maxLength": 500
    },
    "confirm_not_duplicate": {
      "description": "Why this differs from the candidates a previous call returned. Skips the duplicate check.",
      "type": "string",
      "minLength": 3,
      "maxLength": 500
    }
  },
  "required": [
    "repo",
    "title",
    "summary",
    "kind",
    "risk",
    "payoff",
    "scope"
  ]
}