RE: https://neuromatch.social/@jonny/116324676116121930

Part 2 of exploring The Claude Code Source Leak Exclusion Zone continues here.

(the reply tree under the prior thread is getting expensive to render and the bottom no longer renders unless you're logged in lol)

end of prior thread: https://neuromatch.social/@jonny/116345400731237947

One thing that's odd about this package is the amount of internal, anthropic-specific tooling that's in it. Aside from the sort of comical gating behind the USER_TYPE='ant' env var, normally in a well designed package you would expect that it would provide proper hooks so that internal tooling could just be a set of plugins rather than in the source itself.

Claude code does have a number of extension points: agents, hooks, plugins, skills, and tools - even if their structure is somewhat, ah, gestural.

Some things could potentially become features (like the MagicDocs thing, even if that's a comically expensive idea, i'll write more about that later tho), but there are also some things that make no sense to be in here. Like in the startBackgroundHousekeeping task there is an 'ant'-gated task to clean their .npm-cache directory.

There are even notes in here like "this used to block the whole event loop" which you think might have indicated that they might have, say, "just written some separate cron task that runs totally outside claude code." So it seems like "writing claude code with claude code" leads to a collapse of separation of concerns, where anthropic can't really manage the distinction between their projects to the point of inlining the devtools - this can also be seen in comments re: code duplication with Cowork, which i'll also get to later. It also confirms what they say publicly, that they just have claude code sessions running 24/7 (where having a task run every 24 hours makes sense)

Something I'm trying to track down is how this remote claude session thing works. A general pattern in the claude code source is that more recent features are implemented in a way more chaotic way than more "core" features, which reflects the nature of vibe coding: because you don't have a solid foundation, and there is a progressive layer of crust and special cases, the only real way to add more features is to keep adding more crust and special cases. Like rather than having a set of blocks that are self contained and you add another block, you need to slice across all the prior blocks and add something to each of them.

There are a number of places, both in comments and code, that rely on "this session is running in claude code remote session" in some VM, and so therefore they use the filesystem for state (e.g. storing the api and oauth keys), but those parts of the code are in no way cleanly isolated from the rest of the code. So I suppose if i were a pentester or security auditor or whatever what i'd be looking for is places where the mashup of "in remote session / not in remote session" assumptions fails, and we do something naughty on the host system rather than a VM. Like I said still reading, just sort of musing about some of the problems with the package that are larger than individual functions and features.

(We are in the more thoughtful, large scale evaluation of this thing, so it may be more boringer than the more popcorn style snapshots of wow that's fucked up. But those small fucked up things are also the easiest to fix, where what I am trying to get across now is the larger intractable problems in how things work and how they are built)

So there is a feature in claude code: /statusline that is a reasonably good example of a feature that promises a natural language interface to do something that should be simple when done programmatically: here's some callback that shows some values or progress or whatever on a line in my TUI while i use the tool. How does that work?

Well when you call /statusline {progress bar on the withering decay of my life} , first you encounter the statusline "command." there's a lot to see even in just this declaration so we'll take it slow.

first is in allowedTools: You might think that ToolName(params) syntax is some standard thing, where tools have a short name, and then everything inside those parens gets passed as some standard argument to a permission checker. That is not the case: the codepath that parses those rules is only used for the filesystem (read, write, edit), shell, and agent tools, the rest just ignore it. There are in fact two implementations of a parser that splits out the tool name from its params: one in permissionSetup and another in permissionRuleParser that do slightly different things, twice.

What does this look like from the point of view of a tool? The permission given here is ~/** , or anything within my home directory, which is neat that that's so easy to declare and entirely escapes any other rules I have declared for directory scoping. The Read tool doesn't receive that, instead it receives a ToolUseContext object, where then one access the whole app state, and then additionally gets the toolPermissionContext which includes all the rules unparsed. So then the Read tool needs to parse every rule in entirely custom logic to even extract those params, let alone process them.

Parsing every single rule happens up to six times per tool call that I can see, but the Read tool doesn't just process the params in a Read(~/**) rule - since it has access to all the rules it might as well use them - it also checks for edit and write access, among a handful of other invisible exceptions: since every tool has access to the entire set of rules every time, not through dependency injection just like "the check permission callback passes the entire program state" kind of way, it sure as hell uses them.

So there's no consistency to how rules are set, there's special behavior to how they are parsed, passed, interpreted, and applied for every single tool, and since it is the tool itself that decides whether it is allowed to run - rather than some idk ORCHESTRATOR THAT SHOULD SERVE AS THE ENTIRE BACKBONE OF WHAT CLAUDE CODE IS, it can just return true and always run. So that's why there aren't any plugin tools for claude code (they say use MCP instead), because they are intrinsically unsafe and have no real structure.

ok having fun? we haven't even talked about statusline

So returning to statusline: what the fuck? A command has some callback getPromptForCommand - there are two basic kinds of commands, those that "do something" and are a function call, and those that are "prompt commands" which just return a prompt back to the main LLM loop.

To to set your statusline, the statusline command creates prompt text that TELLS THE MAIN LOOP to SPAWN AN AGENT with a given prompt. note that this does not directly spawn an agent, it is merely a suggestion. so right off the bat it is POSSIBLE TO FAIL EVEN INVOKING the command.

But before we get there, we have to pass through what happens after a slash command is issued, and one of the steps along the way is "if something looks like a slash command but we don't know about that command, then throw it back up to the main loop with some special Caveat Message that says "ok just ignore this please"

quick aside - is there anything more emblematic of the way this entire thing undermines human agency than the fact that there are some commands that the user cannot invoke and instead must ask the LLM to invoke for them

I am going to breeze past all the code duplication in the processSlashCommand for now - again, as I have said before, every line of this package is fucked up in a unique way so it's very hard to describe just how one thing is fucked up at a time.

There is a special mode for claude "coordinator mode" where the entire thing claude does is dispatch commands to other sub-agents. so in that case, we are three layers deep in self-prompting: the LLM is prompted to output some prompt text that informs a subagent that it should call some skill which then returns a prompt that instructs the LLM to spawn some additional subagent to create statusline for us. sound good?

@jonny this is The Future, Jonny. Get On Board or Get Left Behind
@pikesley
Going to surprise everyone when the conclusion of this thread is "after a deep analysis of the Claude code source, I have concluded it whips ass and everyone should use it"