Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
93 commits
Select commit Hold shift + click to select a range
bd2efa1
feat: support matview_refresh_interval "off" to disable logstore matv…
jeremym-tanium Jul 30, 2026
230157a
V2.0.0 (#4365)
akshaydeo Jul 30, 2026
b4690bb
gomod fixes (#5731)
akshaydeo Jul 30, 2026
114687a
third party notice (#5735)
akshaydeo Jul 31, 2026
81649e5
feat(mcp-guardrails): add MCP log redaction changes (#5744)
Madhuvod Jul 31, 2026
9dba6de
feat(mcp-guardrails): ui changes (#5745)
Madhuvod Jul 31, 2026
7737490
added plugin logs in mcp logs (#5746)
Madhuvod Jul 31, 2026
14ef405
mcp guardrails : config,helm and docs changes (#5758)
Madhuvod Aug 2, 2026
3498510
adds first time setup token to avoid opening new setup to the world (…
akshaydeo Aug 3, 2026
ce0333c
brings back onboarding widget (#5784)
akshaydeo Aug 3, 2026
44f1194
path normalization auth bypass (#5763)
akshaydeo Aug 3, 2026
c9a0bee
mod fix (#5864)
akshaydeo Aug 5, 2026
df743e5
docs: adds a subsection for mcp guardrails (#5869)
Madhuvod Aug 5, 2026
400dcdb
feat: add w3c trace id to context (#5945)
roroghost17 Aug 7, 2026
cf200ac
fix: align budget override validity with calendar boundaries (#5962)
danpiths Aug 7, 2026
b9bcf62
[fix]: schemas- omit absent tool-call function name on streaming delt…
AdityaPainuli Aug 8, 2026
b9ec10d
fix: guard nil ConfigStore, propagate resource, and surface pending-b…
Pratham-Mishra04 May 29, 2026
364b558
fix: address PR review findings - client-scoped test id, popup-blocke…
Pratham-Mishra04 May 29, 2026
14a79dd
feat: add per user oauth mcp support for config.json
Pratham-Mishra04 May 29, 2026
c07c7ec
fix: close verify-headers double-submit race, preserve TLS/timeout/pe…
Pratham-Mishra04 May 29, 2026
8cb9d18
fix: always label the bootstrap action "Authorize" regardless of auth…
Pratham-Mishra04 May 29, 2026
55e52ab
fix: seed linked oauth_configs/config_mcp_clients rows for shared-tok…
Pratham-Mishra04 Jul 28, 2026
22c412b
fix: close leaked sqlDB in flows-table perf setup, make OAuth flow cl…
Pratham-Mishra04 Jul 28, 2026
d3c0537
fix: reject inactive tokens in ValidateToken, document shared/per-ide…
Pratham-Mishra04 Jul 29, 2026
b686207
feat: generalize TokenRefreshWorker's auth-mode scope
Pratham-Mishra04 Jul 29, 2026
f7286a8
fix: gate SSE OnConnectionLost on connection identity, preserve Needs…
Pratham-Mishra04 Jul 29, 2026
36caf61
fix: repair shared connections regardless of destructive hint, fail c…
Pratham-Mishra04 Jul 29, 2026
2e8fdb6
fix: remove 'View sessions' link from the MCP client edit sheet
Pratham-Mishra04 Jul 29, 2026
b8fd7d9
fix: don't silently drop stored oauth scopes on decode failure, skip …
Pratham-Mishra04 Jul 29, 2026
cff8019
fix: restrict Reauthorize to shared OAuth clients, show loading state…
Pratham-Mishra04 Jul 29, 2026
307bdb4
test: seed opposite-auth_mode token in TestAccessToken_MissingToken_R…
Pratham-Mishra04 Jul 29, 2026
0305878
test: cover every field PromoteSharedOauthTokenToAdmin transfers and …
Pratham-Mishra04 Jul 29, 2026
13ce474
fix: add per-entry version so a rejected stale Get can't evict a conc…
Pratham-Mishra04 Jul 30, 2026
e74461c
fix: propagate ctx through userTokenCache.Fill so a canceled request …
Pratham-Mishra04 Jul 30, 2026
369e95a
fix: propagate ctx through headerCredentialCache.Fill so a canceled r…
Pratham-Mishra04 Jul 30, 2026
2863031
fix: carry the ConfigHash-checkpoint regression test forward across O…
Pratham-Mishra04 Jul 2, 2026
796b328
docs: mcp oauth and per user types config json support docs update
Pratham-Mishra04 May 29, 2026
359fb21
docs: note pending_verification state as a 400 trigger for initiate-v…
Pratham-Mishra04 Jul 2, 2026
7c22512
docs: add secret var support to oauth client_id and client_secret docs
Pratham-Mishra04 Jul 2, 2026
79d0813
docs: fix tool_sync_interval nanosecond claim, fix disable_vk_identit…
Pratham-Mishra04 Jul 30, 2026
4ad79dd
fix: wire tool_execution_timeout on MCP client creation, fix reauthor…
Pratham-Mishra04 Jul 30, 2026
61c13bb
fix: select the pending-verification message from whether verificatio…
Pratham-Mishra04 Jul 30, 2026
0cadf18
fix: route pending token_exchange clients through the verify-exchange…
Pratham-Mishra04 Jul 30, 2026
9ca431f
fix: retain completed inflightClientOp in test double, fix idempotent…
Pratham-Mishra04 Jul 30, 2026
c21d20f
fix: bind MCP connect attempts to entry identity, guard AddClient's dial
Pratham-Mishra04 Jul 30, 2026
2819e3e
docs: document make-before-break reconnection and shared-client retry…
Pratham-Mishra04 Jul 30, 2026
d4a2961
fix: enforce non-empty audience/client_id and reject token_exchange f…
Pratham-Mishra04 Jul 30, 2026
999d1b2
fix: configure bounded http.Server timeouts and request-body limit fo…
Pratham-Mishra04 Jul 30, 2026
e36febf
docs: scope needs_reauth's applicable auth types instead of claiming …
Pratham-Mishra04 Aug 2, 2026
82ca934
fix: correct branch-resolution, backup-safety, conflict-marker, and v…
Pratham-Mishra04 Aug 2, 2026
ed07ba4
feat: allow gating OAuthTokenRefreshWorker sweeps
Pratham-Mishra04 Aug 3, 2026
3b99e7f
fix: render MCP client state badges with spaces instead of underscores
Pratham-Mishra04 Aug 3, 2026
bd8ba7c
fix: resolve MCP client verify UX gaps
Pratham-Mishra04 Aug 5, 2026
605a2d8
feat: adds jwt option in sample mcp client
Pratham-Mishra04 Aug 5, 2026
3e24d86
fix: preserve last-known tool maps across close-first reconnects, che…
Pratham-Mishra04 Aug 6, 2026
977496f
fix: rebuild ephemeral client fresh across the whole connect+init ret…
Pratham-Mishra04 Aug 6, 2026
e269b36
feat: redesign MCP client edit sheet into tabbed layout with accessib…
Pratham-Mishra04 Aug 6, 2026
13ff46b
feat: apply MCP edit sheet's design language to the create sheet
Pratham-Mishra04 Aug 6, 2026
b4054d7
fix: break lock-order inversion in ConnectionCheckerManager, close da…
Pratham-Mishra04 Aug 6, 2026
7cb29cd
fix: pin needs_session_stickiness across config.json reconciliation s…
Pratham-Mishra04 Aug 6, 2026
1f3f222
fix: use kebab-case data-testid values in MCP sessions filter sidebar
Pratham-Mishra04 Aug 6, 2026
a6746b3
feat: replace MCP oauth grants' top filter bar with a side filter panel
Pratham-Mishra04 Aug 6, 2026
ed69901
feat: add MCP server filter to Auth Sessions sidebar, scoped to per-u…
Pratham-Mishra04 Aug 6, 2026
993b2a4
fix: don't treat a CAS loss to a still-active concurrent refresh as a…
Pratham-Mishra04 Aug 6, 2026
b146594
docs: document that stateChangeCallback has no cross-transition order…
Pratham-Mishra04 Aug 6, 2026
2c2a987
feat: add Virtual Key and Users filters to MCP Auth Sessions sidebar
Pratham-Mishra04 Aug 6, 2026
f70676f
feat: add VK and Users filters to OAuth Grants sidebar
Pratham-Mishra04 Aug 6, 2026
e28de27
fix: discover tools synchronously for per-call MCP clients, fix share…
Pratham-Mishra04 Aug 7, 2026
9a69fec
feat: persist and resync MCP tool discoveries uniformly across all cl…
Pratham-Mishra04 Aug 7, 2026
63b7eec
fix: persist discovered tools before triggering cluster propagation i…
Pratham-Mishra04 Aug 8, 2026
80e13d7
fix: correct per-user MCP state-projection and reauthorize completion…
Pratham-Mishra04 Aug 8, 2026
cc4478d
docs: document needs_session_stickiness across Web UI, API, and conf…
Pratham-Mishra04 Aug 8, 2026
db6e383
docs: add canonical MCP connections/states/lifecycles page, fix stale…
Pratham-Mishra04 Aug 8, 2026
595c82b
docs(openapi): fix stale MCP connection-state enum, document prematu…
Pratham-Mishra04 Aug 8, 2026
55b26cc
docs: fix remaining reconnect-400 wording and tool-persistence gaps …
Pratham-Mishra04 Aug 8, 2026
e20c99d
[fix]: gemini- map truncated responses to MAX_TOKENS finish reason (#…
AdityaPainuli Aug 9, 2026
cd65b46
fix(ui): skip password validation for redacted credential (#5953)
G-XD Aug 9, 2026
a9645f4
feat: add `roots_only` filter to collapse fallback chains with child …
impoiler Aug 10, 2026
e12fd20
docs: add Bedrock runbooks for Claude Code and Codex (#5868)
R-droid101 Aug 10, 2026
746acaa
chore: doc fixes for config.schema.json (#5938)
roroghost17 Aug 10, 2026
41a236a
cost for prompt guardrails (#4931)
Madhuvod Aug 10, 2026
efd6acb
fix update passthrough docs (#5906)
TejasGhatte Aug 10, 2026
b17b2df
[docs]: docs for prompt guardrails (#5899)
Madhuvod Aug 10, 2026
9dc3431
feat: add support for separate metrics tab independent of traces for …
roroghost17 Aug 10, 2026
3f96ce0
feat: add separate headers support for traces and metrics in OTEL col…
roroghost17 Aug 10, 2026
6523805
chore: update helm-charts for OTEL trace / metrics headers changes (#…
roroghost17 Aug 10, 2026
f3875ec
docs: add OTEL trace / metrics headers doc and fixes the pushed metri…
roroghost17 Aug 10, 2026
db922ad
video requests info in logs ui (#5946)
TejasGhatte Aug 10, 2026
12fdc40
fix: bedrock files handling in inference (#5947)
TejasGhatte Aug 10, 2026
7d572a5
tests: harness tests for bedrock documents (#5949)
TejasGhatte Aug 10, 2026
2c44740
fix: cost in usd ticks for xai usage (#5950)
TejasGhatte Aug 10, 2026
d704af4
fix: add anthropic error branch on stripping on encrypted content (#5…
TejasGhatte Aug 10, 2026
0c4830b
fix: move count_tokens fallback to compat plugin
0xPixelNinja May 21, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
The table of contents is too big for display.
Diff view
Diff view
  •  
  •  
  •  
199 changes: 199 additions & 0 deletions .claude/skills/stack-absorb/SKILL.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,199 @@
---
name: stack-absorb
description: Manually distribute working-tree changes (or a batch of edits already made on the current branch) across the correct branches of a Graphite (gt) stack, when gt absorb's blame-based auto-split doesn't match the logical grouping - e.g. new code with no prior line to blame onto, or changes that conceptually belong with a commit gt's algorithm wouldn't pick. Use when asked to "split these changes into the stack", "absorb this properly", "put this fix on the right branch", or when a change was made on top of a branch but really belongs several branches down.
allowed-tools: Read, Grep, Glob, Bash, Edit, AskUserQuestion
---

# Stack Absorb

Distribute a set of changes across the correct commits in a Graphite stack, by hand,
when `gt absorb`'s blame-based algorithm won't produce a clean result. This is slower
than `gt absorb -f` but gives a coherent, reviewable history: each target branch gets
exactly the hunks that belong to it, described in its own commit message, with nothing
stray swept in.

## When to reach for this vs. plain `gt absorb`

Check `git status --short` first. Untracked (`??`) files are never absorbed even with
`gt absorb -a` - that flag only stages unstaged *tracked* changes, file creations are
never picked up. If any untracked files are part of the intended change, treat them as
part of the manual split below rather than expecting the dry-run to cover them.

Then try `gt absorb -a --dry-run` first - it's free and sometimes it's exactly right.
Read its output critically:

- If every hunk absorbs into a commit that's a good semantic fit, there's no
significant "Not absorbed" leftover, and no untracked files were left out of
consideration, just run `gt absorb -a -f` (or let the user run it) and stop here.
- If it scatters hunks across commits that are a poor conceptual fit (a stale
docs-sync commit, a commit about a different concern that happens to touch the same
lines), or leaves substantial new code as "Not absorbed" (no prior line to blame
onto - new functions, new JSX blocks, new state), that's the signal to do this
manually. Tell the user what `gt absorb --dry-run` would do and why it's messier
than a hand split, and confirm before proceeding (`AskUserQuestion`) - this is a
judgment call about commit history shape, not a mechanical one.

## Step 1: Map every change to its target branch

For each distinct concern in the diff, find the commit that should own it:

```bash
git log --oneline -S"<distinctive string from the change>" --all -- "<file>"
```

Pick a string that's specific to the *concept* being changed (a function name, a UI
label, an error message), not boilerplate. The oldest/most relevant match is usually
the commit that introduced what you're now modifying. Then resolve that commit to a
current branch tip - `git branch --contains` alone is not the answer, only a candidate
list: in a stacked history every branch *above* the true owner also contains that
commit, since it's in their ancestry too.

```bash
git branch --contains "<hash>" # candidates: the owner + everything upstack of it
git branch --points-at "<hash>" # non-empty only if <hash> IS a branch tip itself
gt log long # see the full stack shape with commit messages
```

If `--points-at` returns a branch, that's the owner. Otherwise, treat `--contains`'s
output as candidates only, cross-check against `gt log long` for which branch's own
commits plausibly introduce the concept, and record which one you picked. If more than
one candidate still looks plausible, stop and ask the user (`AskUserQuestion`) rather
than guessing.

Group the diff's hunks by target branch. A single file's changes routinely split
across two or more branches (e.g. a bugfix on an old branch, a rename + new feature on
a newer one) - that's expected, not a problem.

**Judgment, not blame**: the "right" branch is the one that owns the concept being
touched, which is not always the same as the last branch to edit that exact line. A
generated file (e.g. a bundled `openapi.json`) belongs with whichever branch changed
its source, not with whatever branch happens to have last regenerated it.

If a target file/section doesn't exist yet on the candidate branch (check with
`git show "<branch>:<path>"`), the change belongs on a *later* branch - find the commit
that actually introduces that file/section instead.

## Step 2: Back up, then return to clean HEAD

Before touching anything, copy the final intended content of every changed file
somewhere safe (the session scratchpad), preserving each file's relative path so two
files with the same basename in different directories don't clobber each other's
backup. Abort before touching the working tree if any backup fails:

```bash
mkdir -p "<scratchpad>/$(dirname "<file>")" && cp "<file>" "<scratchpad>/<file>" # for each modified file
```

Then restore tracked files to the current branch's committed state. Set aside any
intended untracked (newly-created) files separately first, since they have no
committed state to restore to and `git restore`/`git checkout` won't touch them:

```bash
git status --short # confirm what's dirty first
git restore --source=HEAD --staged --worktree -- "<tracked-files>" # NOT git checkout --
# (checkout only resets the
# worktree from the index,
# not the index itself)
# NOT git stash - never use
# git stash in this repo
git status --short # confirm the tree is clean again
```

Never `git reset --hard` or touch files you didn't back up. If `git status` shows
files you don't recognize as part of this change, stop and ask the user before doing
anything - don't assume it's safe to revert or sweep in.

## Step 3: Apply each branch's slice, bottom-up

Process target branches from the bottom of the stack upward (earliest commit first) -
this matters because later branches' restacks will replay onto whatever the earlier
branch ends up containing.

For each target branch:

1. `gt checkout <branch>` and confirm `git status --short` is clean before editing.
2. Read the current content of each file at this branch's tip - it usually differs
from the top-of-stack version (later branches may have renamed things, added
props, etc.), so re-derive the edit against what's actually here rather than
blindly replaying the final diff. Verify the "before" text matches what you expect
before editing.
3. Apply only this branch's slice of the change.
4. Verify: run the appropriate build/typecheck for whatever you touched (`tsc
--noEmit`, `go build ./...`, etc.) before committing anything.
5. Check `git status --short` again - it must show *only* the files you intended to
touch. If unrelated files are dirty (leftover debug instrumentation, a stray edit
from elsewhere), do not sweep them in with `-a`; stage the intended files
explicitly, or ask the user what to do with the stray diff first.
6. Commit with `gt modify -a -m "<message>"` (amends the branch's existing commit and
auto-restacks everything above it). Use `gt modify -c` instead if this should be a
*new* commit on the branch rather than folded into the existing one. Never use
plain `git commit` here - it won't restack descendants.
7. Before running `gt modify`, regenerate any derived/bundled output that must stay in
sync with the source you just edited - `gt modify` itself does not know about
repository-specific generators. For OpenAPI edits, run `cd docs/openapi && python3
bundle.py`, then confirm `git status --short` lists both the edited source YAML and
`docs/openapi/openapi.json` before committing, so the generated file lands in the
same commit as its source.

## Step 4: Resolve restack conflicts

A restack conflict is expected whenever another stacked branch independently touched
the same lines (e.g. two different features both added a prop to the same component).
`gt modify`/`gt restack` will stop and report it:

```
Hit conflict restacking <branch> on <parent>.
Unmerged files: <path>
```

To resolve:

1. Stay on the conflicted branch with the operation paused - don't `gt checkout` away
or start a new `gt restack`; the conflict markers are already sitting in the working
tree from the operation that just stopped. `gt abort` only cancels the paused
operation entirely, it is not a way to "restart" it.
2. `grep -n "^<<<<<<<\|^=======\|^>>>>>>>" "<file>"` to locate every conflict region in
the file - there is often more than one.
3. Resolve each region by hand. The common case in this workflow is "keep both sides"
(two independent additions near the same spot) - merge them in a sensible order
rather than picking one side and discarding the other.
4. Verify the file typechecks/builds after resolving, with no markers left:
`grep -cE "^(<<<<<<<|=======|>>>>>>>)" "<file>"` should be 0.
5. `gt add "<file>"` for every resolved file, then `gt continue`.
6. Repeat if `gt continue` hits another conflict further up the stack.

## Step 5: Final verification

After the last branch is committed and restacked:

```bash
gt log short # no "(needs restack)" on any branch in your chain
grep -rlE '^(<<<<<<<|=======|>>>>>>>)' -- "<touched dirs>" # must be empty
git status --short # clean
```

Verify from the *highest* branch your changes touched or that got restacked as a
result (not necessarily the branch the user started on) - restacking replays every
commit above your changes, and a downstream branch could in principle break even
without a conflict (e.g. a type that was fine in isolation becomes wrong once combined
with a later branch's edits). If independent branches upstack diverged from each other,
run the full build/typecheck from each affected branch's tip. Only after that, return
to whatever branch the user was originally on.

Report back per-branch: which branch got what, and the verification status of each.
Do not push anything - this workflow only rewrites local branches.

## Guardrails

- Never `git stash` in this repo (see project convention: toolchain/lockfile churn
makes pops conflict).
- Never include unrelated dirty files in a `gt modify -a` - confirm `git status
--short` shows only the intended paths first, every time, even if it was clean a
moment ago (checking out a different branch can surface a different set of stray
changes).
- Never invent commit content: if a file/section a change should modify doesn't exist
yet at the candidate branch, that's a sign you picked the wrong branch, not a reason
to create it early.
- Confirm the overall plan with the user before executing when the mapping required
real judgment (not purely mechanical) - name the target branch for each file/concern
and get a go-ahead before checking out and editing anything.
13 changes: 12 additions & 1 deletion .github/workflows/scripts/cost-accuracy-test.sh
Original file line number Diff line number Diff line change
Expand Up @@ -357,11 +357,22 @@ params = {
"order": "asc",
}

def logs_complete(logs):
# Log writes are fully async (single batched insert in PostLLMHook), so a
# row can be visible before its usage/cost are readable. Poll on the
# predicate we assert (every row has usage and cost), not just row count.
return all(
(item.get("token_usage") or {}).get("prompt_tokens") is not None
and (item.get("token_usage") or {}).get("completion_tokens") is not None
and item.get("cost") is not None
for item in logs
)

logs = []
for _ in range(60):
payload = get_json("/api/logs", params)
logs = payload.get("logs", [])
if len(logs) >= expected_count:
if len(logs) >= expected_count and logs_complete(logs):
break
time.sleep(1)

Expand Down
Loading