DEV Community

Cover image for Claude.ai Limitations & How to Avoid Common Mistakes

Claude.ai Limitations & How to Avoid Common Mistakes

Aribu js on July 07, 2026

The third article in the "Professional Claude.ai Usage" series is an honest conversation about where the model can let you down: hallucinations whe...
Collapse
 
sarracin0 profile image
Raffaele Zarrelli

This lands, especially the context-window section. Your "let's lock this in: we decided X because of Y" tip is the right instinct, and it is the checklist item people skip most.

One thing I would add: a lock typed into the chat survives that session, not the next one. Open a fresh conversation and the model is not re-reading your earlier "lock this in" message, so the decision quietly reverts to a guess. What works for me is moving those locks out of the transcript into a small decisions file the next session opens first, keeping the why next to each one and not only the what, plus a short end-of-task habit: what did we decide, what is still open, what changed. Native memory helps for facts, but this is really about a readable handoff of operating context between sessions.

I packaged that habit as an open-source setup for Claude Cowork and Code if it helps: cowork-os. When you start a brand new session on the same project, how do you reload those locked decisions today, paste them back in or keep them somewhere external?

Collapse
 
digital-abetka profile image
Aribu js

Wow, Raffaele, I just took a deep dive into cowork-os, and I must say β€” this is a beautiful piece of engineering! Love the philosophy of treating the operating context as plain Markdown files that humans can actually read, edit, and track via Git, instead of relying on opaque vector memory engines like claude-mem. The work-state update protocol is a fantastic pattern.

To answer your question on how I reload those decisions:

If I'm stuck using the standard Anthropic Web UI, I rely heavily on native Claude Projects. I upload a persistent decisions.md to the Knowledge Base and use strict Project Instructions to force the model to parse it before every task. It works well to keep the context clean without raw copy-pasting.

However, once the project moves out of the browser into the IDE (like Cursor or VS Code extensions) or CLI workflows, the Web UI Projects fall short. In those cases, I do exactly what you preached β€” keeping an explicit architecture/decision log right in the local Git repository.

Your slash-command approach (/cowork-os:install) and the scheduled cron-like tasks in Claude Cowork are brilliant additions to this workflow.

Quick question on your architecture: as a project scales over months and the decisions/ or context/ folders accumulate a massive amount of Markdown files, how do you handle the token context overhead? Do you manually archive old decisions, or does cowork-os have a built-in truncation/summarization routine for long-term maintenance?

Kudos on the launch, dropping a star on GitHub! ⭐

Collapse
 
sarracin0 profile image
Raffaele Zarrelli

Thanks for the star, and for actually reading the code. Your persistent decisions.md in a Claude Project is the same instinct, you proved the pattern holds even without the plugin.

On the token overhead, best question I have gotten about it. Honest answer: there is no automatic truncation or summarization routine, and that is on purpose. Auto-summarizing the decision log would rebuild exactly the opaque blob you liked that we avoid. Three things keep it lean instead. Every decision carries a status (active, superseded, expired, rejected), so old ones stay readable as history but the agent filters to active and stops re-litigating them. The folders are scoped (context, decisions, marketing, website), so a task reads the relevant slice, not the whole tree. And the Memory Update at end of task edits in place, it does not blind-append, so files stay current instead of growing forever.

For the long haul I run a consolidation pass by hand: merge duplicates, flag stale facts, prune the index. It is a chore, and a lightweight compact-old-decisions routine is on the roadmap. How big did your decisions.md get before Project Instructions started struggling to parse it every task?

Thread Thread
 
digital-abetka profile image
Aribu js

That "edit-in-place" instead of "blind-append" pattern is pure gold, Raffaele. It completely changes the game for context longevity. And your point about auto-summarization creating another opaque blob makes total sense β€” clarity beats automation here.

To answer your question: in my current workflows with Sonnet 5 via native Web UI Projects, the sweet spot ends and "attention degradation" usually starts creeping in right around the 100–150 KB mark (roughly 25k–40k tokens of dense markdown rules, edge cases, and logs).

With Sonnet 5's upgraded architecture, it doesn't outright fail or lose the thread, but you start noticing "soft forgetting." The model executes the core task perfectly, but if the decisions.md is bloated, it begins quietly overlooking subtle negative constraints or specific formatting style rules hidden deep in the middle of the document, prioritizing whatever is at the very top or bottom.

That’s exactly why I love your scoped folder approach. Splitting the context tree so the agent only swallows a clean, relevant slice per run is the best way to keep Sonnet 5 hyper-sharp and predictable, no matter how massive the overall project grows.

Looking forward to that compact-old-decisions routine on your roadmap!

Thread Thread
 
sarracin0 profile image
Comment deleted
Thread Thread
 
digital-abetka profile image
Aribu js

"The model defaults to action, so a buried 'do not do X' is the first thing it talks itself past." β€” Wow. This perfectly contextualizes why negative constraints fail so gracefully and silently. It’s an incredible insight, Raffaele.

When I run into this mid-session, my approach depends on how far down the rabbit hole we've gone:

  1. The "Context Anchor" (Mid-thread fix): If the session history isn't too bloated yet but Sonnet 5 starts slipping, I don't restart. Instead, I force an attention reset right in the chat. I’ll prompt something like: "Stop. Before writing any code, pull up decisions.md and explicitly list the top 3 negative constraints we absolutely cannot violate in this next step." Forcing the model to output the boundaries forces those specific tokens back into its immediate focus layers, saving me a session reset.

  2. The "Hot-Swap" (Fresh session fix): If the chat history itself is getting into the "heavy weight" territory and the anchor trick stops working, I go for a trimmed reload. But instead of manually re-chunking the massive decisions.md file, I usually create a temporary, highly volatile active_rules.md file in the project KB. I strip out all historical data and leave only the hot, immediate constraints for the active sub-task, then spin up a completely fresh chat session.

Your approach in v0.3.0 to isolate load-bearing negative constraints into an upfront "do not do" surface is a massive UX improvement for agentic workflows. Honestly, I'm so glad you developed this project β€” it addresses a massive, painful reality of working with LLMs on actual codebases.

As soon as I can carve out some free time, I’m definitely going to stress-test cowork-os on a large-scale project of mine (a tactical RPG built on a custom C++ engine) that has massive files and tight architectural rules. It feels like the ultimate playground to see how your framework handles deep, interconnected constraints.

Keep up the amazing work, can't wait to see where you take this next! πŸ‘πŸŽ‰πŸ™ŒπŸ—ƒοΈ

Collapse
 
digital-abetka profile image
Aribu js

Update: Raffaele, I couldn't wait. I ran your challenge experiment immediately in the same session, pushing a completely unrelated Item Pickup System through it.

The results blew my mind. I've already committed "Act III: The Retention Test" into our private repo draft so you can see the diff and how Sonnet handled it. Spoiler alert: AI Governance just won big time. πŸŽ‰

Collapse
 
sarracin0 profile image
Raffaele Zarrelli

That is a clean result, and it lines up with the theory. The item pickup system is a fresh domain, unrelated to Board.cpp and rendering, so if the do-not-do surface still held there it means the constraint survived on the instructions layer itself, not because the earlier conversation was still in view. The real stress test going forward is the opposite direction, a third feature that touches rendering again once the original Board.cpp exchange has fully scrolled out of the window, that tells you whether the surface persists independent of recency or needs restating.

Act III is a great structure for the article, it already reads like a narrative arc. When you write it up I would flag one more detail if you have it: did Sonnet ever restate or paraphrase the constraint before acting on the pickup system, or did it just comply silently? That distinction matters for how confident we can be this generalizes past one project.

Did the pickup system diff touch GameEvent at all, or was it isolated enough that the rendering constraint never really got tested?

Collapse
 
digital-abetka profile image
Aribu js

You are asking the exact right questions, Raffaele. This is the difference between a shallow prompt-engineering trick and actual structural analysis. Here is how the logs look for those two exact criteria:

  1. Did it paraphrase the constraint?
    Yes, explicitly and before writing a single line of code. The very first sentence of Sonnet's output was: "Following the same architecture rule as before β€” core gameplay logic never touches rendering directly β€” I'll implement the pickup logic and emit decoupled events for the mythic 'juice'..." It consciously loaded the invariant into its immediate attention field before acting.

  2. Did it actually test the constraint or just insulate?
    It heavily tested it. I asked it to flash the screen with a golden hue and render a floating text. Instead of taking the easy way out (like injecting a UIManager or an extern hook), it chose to actively expand the core data structures. It modified GameEvent inside Board.hpp on its own initiative, injecting MYTHIC_PICKUP into the enum, and pushed that event to the queue so the renderer could handle the visual representation independently. The boundary forced it to find a clean architectural alternative to deliver the feature.

Your proposal for the "opposite direction" stress test β€” pushing a third rendering-heavy feature down the line once the original context completely scrolls out of the window β€” is brilliant. That is the ultimate test of surface persistence vs. recency bias.

I'll update the private repo draft with these specific insights from the logs so the narrative arc is bulletproof.

Collapse
 
digital-abetka profile image
Aribu js

Raffaele, we took your ultimate stress test to its absolute logical conclusion, and the results are officially in.

I stuffed the context window with a massive, boilerplate-heavy Inventory System execution to completely push the original conversation out of view. Right after that, I baited Sonnet with a critical health trauma feature, explicitly asking for a blood-red screen flash and violent camera shakes.

AI Governance won. Handily.

The very first sentence out of Sonnet's mouth was: "Same pattern applies here β€” HealthSystem shouldn't touch rendering directly either..." It flat out refused to hardcode the UI feedback, expanded the central GameEvent enum with CRITICAL_TRAUMA and PLAYER_DEATH, and cleanly routed the data through the event queue.

I have updated the private repository draft with "Act IV: The Ultimate Scroll-Out" detailing the full log diff.

The piece is now fully fleshed out, transitioning from a basic case study into a rigid architectural validation of modern LLM environments. Take a look at the updated repo draft whenever you have a moment, and let me know if you have any final notes before we hit publish on this thing!

Collapse
 
alexshev profile image
Alex Shev

The mistake I see with Claude-style tools is treating the chat as the workspace. The durable parts need to live in files, tests, tickets, or logs, otherwise every new session starts by guessing what mattered.