Yapay Zeka
Avrupa Ligi finalinde engellilere yönelik Soundx teknolojisi ilk kez kullanıldı
İşitme engelli kullanıcıların çevresindeki sesleri titreşimlerle hissetmesini sağlayan Soundx uygulaması ilk kez İstanbul’daki Avrupa Ligi finalinde kullanıldı.The Boys bitti ama Vought Rising geliyor; Yeni Boys dizisinin ilk fragmanı yayınlandı
The Boys dizisiyle aynı evrende geçen Vought Rising dizisinden ilk fragman yayınlandı. Geçmişte geçen dizide Soldier Boy ve Stormfront gibi ana diziden tanıdığımız karakterler de yer alıyor.Why AI Coding Agents Hallucinate and How to Fix It
Most engineers I pair with can spot an AI coding agent hallucination when it happens. The AI invents an API that doesn’t exist, reaches for a deprecated library, or rewrites a function you explicitly said to leave alone. They notice it, they’re annoyed by it, and they move on.
What I’ve noticed is that fewer engineers have developed the instinct to do something about it. Not just fix the output, but fix the input. When I hallucinate the same way twice, something in my environment is wrong, and I should go find it.
I won’t rehash the anatomy of a conversation or why context limits matter. Dex Horthy described the “dumb zone” concept well in his talk on solving hard problems in complex codebases: the gist being that LLM performance degrades as the context window fills, roughly past the 40% mark. Most of those concepts still hold. What I want to share instead is a feedback cycle that I’ve been trying to teach to anyone who’ll listen, along with the specific things I’ve learned applying it.
Most of us react to AI hallucinations. Few investigate.
I’ve seen a range of reactions when the agent goes off the rails: some people are amused, some get annoyed. In an extreme case, an engineer I know will ctrl+c out of the conversation the moment it goes sideways, which is fair. If the agent is heading in the wrong direction, stopping it saves tokens and time.
But the reaction I see less often is the one that actually improves the agent for the next run: pausing to figure out why it happened, and making a change so it doesn’t happen again.
This matters beyond just your own workflow. Hallucinations are one of the biggest reasons skeptical engineers stay skeptical. Every time a teammate watches the AI confidently invent a nonexistent function, it reinforces the “these tools aren’t ready” narrative. When you can help someone understand that there are actual knobs and levers to reduce hallucinations (not eliminate, but reduce) you’re shoring up someone’s confidence in the whole approach.
And to be clear: hallucinations will never go away entirely. There’s a strong theoretical argument that they’re a fundamental property of how these models work, rooted in the way these models compute. The goal isn’t zero hallucinations. It’s fewer, and faster recovery when they happen.
My tip is simple: reflect on what actually happened
When I hit a hallucination that annoys me, I’ve trained myself to pause and run through a short checklist. It’s not sophisticated, but the habit of doing it consistently is what makes it work.
What did the AI coding agent actually hallucinate?
This sounds obvious, but I find that most people skip the diagnosis. They see the wrong output and immediately re-prompt or restart the conversation.
Instead, I look through the conversation history and try to trace the reasoning. What was the agent trying to do? What did I want it to do? Where did those two things diverge? Sometimes it’s a genuine misunderstanding of my instructions. Sometimes the agent pulled in context from a file I forgot was in scope. Sometimes it’s just the model being confidently wrong about a library API, which tells me something different about what needs fixing.
That last case is worth understanding. Researchers at OpenAI published a paper showing that LLMs are trained in a way that rewards guessing over admitting uncertainty, like a student who fills in an answer on every exam question rather than leaving any blank. Knowing this changes how I investigate. I’m not looking for a bug. I’m looking for missing context that would have steered the guess in the right direction.
Where did the context come from?
This is the core of it. When you’ve identified a hallucination worth fixing, the question becomes: what information did the agent use to make that bad decision?
First, you need to familiarize yourself with the sources of context your agent is consuming. In Claude Code, that’s CLAUDE.md files, project-level memory in ~/.claude/projects/, any files it’s read in the current session, and the conversation history itself. In Cursor, it’s your rules files, your hierarchy of AGENTS.md files scattered throughout your repository, indexed docs, and whatever files are open or referenced. Each tool has its own anatomy, and it’s worth spending an afternoon just mapping out where your agent gets its information.
Once you know the anatomy, you can trace backwards from the hallucination. The agent thought it should use library X? Check if there’s a stale reference in your rules file. It kept trying to write tests in a style you’ve moved away from? Maybe there’s an old convention documented somewhere that you forgot to update. It invented an API endpoint? Maybe your schema docs are out of date, or maybe there are no schema docs and the agent is guessing.
When I can’t figure it out on my own, I’ll confront the agent directly. Something like: “I think you hallucinated here. I wanted you to do $X, but you did $Y. Why did this happen? What context did you use to make this decision, and what changes should I make to the rules files to avoid this in the future?”
Be direct, concrete, specific. The agent is often surprisingly good at self-diagnosing: it’ll point to a rule it interpreted broadly, or a file it read that contained misleading information. Try out its suggested changes. They often work. Not always, but often enough that it’s worth the 30 seconds to ask.
Is the “hallucination” a big enough issue to fix?
Before spending more time troubleshooting, I do a gut check. Maybe I disagreed with the approach, but is it actually wrong? Will the agent eventually get there?
Sidebar: when talking with a friend, he pointed out that “hallucination” isn’t always the right term here. I’m actually referring to “all things you disagreed with an agent on”. Hallucination is a distinct problem, but this advice applies to the broader set of problems. I use hallucination as a proxy term.
This is one of those things that’s hard to learn from AI and easier to learn from serving as a manager. As a manager, you figure out that everyone does things differently. Sometimes an engineer takes a route you wouldn’t have chosen, and the result is fine; it’s often better than what you had in mind. I’ve started applying the same mentality to AI agents. If the approach is merely different from what I expected, I’ll let it run for a while. The increased autonomy might be worth the extra time, even if the path isn’t what I originally intended.
But if it’s hallucinating facts, such as inventing APIs, fabricating function signatures, pulling in libraries that don’t exist, that’s a different category. That’s when I stop and investigate.
Is your context too bloated? Smaller is better.
This one is counterintuitive, and I had to learn it the hard way. You’d think that giving the agent more instructions would make it smarter. More context about your database schemas, your API conventions, your testing preferences, your deployment pipeline… surely more information leads to better decisions?
In practice, there’s a point where it flips. I went through a phase where I kept adding to my CLAUDE.md files every time something went wrong. Database schemas, model designs, interaction patterns, naming conventions. The file grew and grew (by month two it read less like documentation and more like a manifesto), and at some point the agent started getting worse. It was pulling in conflicting instructions, getting confused about which convention applied where, and occasionally just ignoring sections entirely.
Do you need this context every time? Or just some of the time? Can you extract this context, package it up as a Skill or Subagent and then trigger it when you need it?
This is where “context isolation” comes in. Instead of stuffing everything into the main rules file, you extract niche or complex use cases into separate mechanisms. The key insight is that subagents in particular have a stronger degree of context isolation, because the instructions don’t load into the parent thread’s context. You trigger them explicitly when you need them, and the rest of the time they’re not competing for attention in the agent’s working memory.
I ended up cutting my main CLAUDE.md from around 500 lines down to about 280 (it should probably be shorter), and moved the specialized stuff into skills that get invoked when relevant. The improvement was noticeable within a session or two.
Is the automatic memory working against you?
Most coding and chat tools manage a memory thread for you now. Claude Code keeps memories in ~/.claude/projects/$yourProject/memory/. Cursor has its own system. ChatGPT has its memory panel. The idea is good: the agent learns from your interactions and adapts over time.
The problem is that the agent doesn’t always learn the right things. Andrej Karpathy flagged this a while ago on X: the model can obsess over a minor detail from 2 months ago that’s completely irrelevant to what you’re doing now. I’ve seen it happen in my own work: the agent latched onto a specific testing pattern I used once for a particular edge case, and kept invoking it on unrelated projects, long after it stopped applying.
In Claude Code, you can hunt for distracting memories in the memory directory and remove them, or ask Claude itself to clean up. In Claude’s chat interface, you’ll have to use the UI to inspect what it’s stored and tell it what to change. (It doesn’t let you edit memories directly, which is a minor annoyance.)
The broader point is that automatic memory is another source of context, and it can drift just like any other source. If your agent starts doing something odd that you can’t trace to your rules files or the current conversation, check the memory. It might be holding onto something you’d rather it forgot.
Continuous learning with your AI, but you have to trigger it
Adding this trigger into my vibe coding repertoire has helped me improve the accuracy of my agents repeatedly. Even though AI work often feels a bit random, I keep a running list of problems. When something repeats itself, that’s my signal that I might want to reflect and try to fix it. I’ll pause and ask the agent to suggest changes to its own context that would prevent the issue in future runs. Then I test it on a controlled task to see if it sticks.
It’s not a complicated habit, but it’s a valuable one. Hallucinations cost you time, and that cost multiplies if you work on a team. If your teammates haven’t run into a particular issue yet, you can save them time. And maybe they haven’t developed this mental trigger yet. Sharing what you’ve fixed in your context files is one of the force-multiplying things you can do for a team adopting AI coding tools.
Most engineers I talk to treat their agent context like a set-and-forget thing. Write the AGENTS.md once, maybe tweak it when something goes really wrong. But context is a living system. It drifts, it bloats, it accumulates stale assumptions. The engineers who get the most out of these tools are the ones who treat context like code: something that needs regular review, refactoring, and testing.
This tweaking of the AGENTS.md files and other context is what I was referring to when I suggested looking at “concrete metrics of adoption” in my article measuring AI adoption as a manager.
If you’ve developed your own system for managing agent context, or if you’ve found patterns in how you debug hallucinations, I’d like to hear about it. DM me on LinkedIn.
Originally published at ashu.co.
PolicyAware vs Guardrails vs AI Gateways vs Model Routers: The Comparison Every AI Engineer Needs to Read
I’ve been building AI-powered features for a while now, and the hardest conversations I have with my team are never about which model to use. They’re always about the same thing: what is this system actually allowed to do, and how do we prove it?
That question pushed me to build PolicyAware – an open source Python control plane that sits in front of your models, tools, and retrieval systems. Before I explain what it does, I want to walk through why the tools most teams reach for first – guardrails, AI gateways, and model routers – are genuinely useful but leave a critical gap wide open.
The landscape right now
If you search for “AI safety” or “LLM governance” you will find three categories of tools coming up again and again:
- Guardrail libraries – validate prompts and outputs against safety rules
- AI gateways – proxy your requests to model providers, centralize API keys
- Model routers – pick the cheapest or fastest model for each request
All three are useful. None of them alone answers the governance question.
Here is the mental model I use: a guardrail checks what the model says. A gateway manages where the request goes. A router decides which model handles it. But none of them ask the most important question first: should this request be allowed to run at all, under this user’s role, for this tenant, in this region, given this risk level?
That is the gap PolicyAware fills.
Side-by-side comparison
| Capability | Guardrails | AI Gateway | Model Router | PolicyAware |
|---|---|---|---|---|
| Block unsafe prompts before execution | Sometimes | Sometimes | No | Yes |
| Redact PII / PHI / secrets pre-execution | Sometimes | Sometimes | No | Yes |
| Decisions using role, tenant, region, risk | Limited | Limited | Limited | Yes |
| Deny-by-default posture | Usually no | Usually no | No | Yes |
| Govern MCP / agent tool calls | Usually no | Sometimes | No | Yes |
| Require human approval for risky actions | Usually no | Sometimes | No | Yes |
| Route across providers after policy approval | No | Yes | Yes | Yes |
| Evaluate RAG citation, grounding, leakage | Sometimes | Limited | No | Yes |
| Emit audit traces with reason codes | Limited | Sometimes | Limited | Yes |
| Generate compliance evidence artifacts | Usually no | Usually no | No | Yes |
The right column is not a flex. It is a description of what enterprise AI systems actually need once they move beyond read-only chat and start touching real data, real tools, and real business workflows.
When each tool is the right call
Use a guardrails library when your only need is response formatting, toxicity filtering, or structured output validation. If you do not need RBAC, tenant rules, approval flows, or audit evidence, a guardrail is lighter and faster.
Use an AI gateway when your main problem is juggling provider keys, rate limits, and fallback routing. Gateways are great infrastructure. They are just not governance.
Use a model router when you are optimizing for cost, latency, or quality tradeoffs across providers. A router does not decide whether a request should run – only which model would run it.
Use PolicyAware when your AI system touches sensitive data, calls external tools, operates under regional compliance rules, or takes actions with financial or operational consequences. If you need to explain a decision to a security team six months from now, you need a control plane, not just a proxy.
How the architecture fits together
Here is the pattern I use in production. The key rule is: nothing reaches a model, retriever, or tool until the control plane has made an explicit decision.
+-----------------------------+
| Application Layer |
| (web app / API / workflow) |
+-------------+---------------+
|
v
+-----------------------------+
| PolicyAware Control Plane |
| |
| 1. Identity + context |
| 2. Deny-by-default check |
| 3. PII / PHI detection |
| 4. Risk classification |
| 5. Approval gate (if high) |
| 6. Provider routing |
+--------+----------+---------+
| |
v v
+----------+ +----------+
| RAG Layer| | Tools / |
| retrieval| | MCP |
| citation | | payments |
+----+-----+ +----+-----+
| |
+------+-------+
|
v
+-------------+
| Model Layer |
| (local/SaaS)|
+------+------+
|
v
+-------------+
| Evaluations |
| leakage |
| grounding |
| audit trace |
+-------------+
Every arrow in that diagram has a policy decision attached to it. That is the entire point.
A real example: the $500 refund prompt
Let us make this concrete. A customer-support copilot gets this message:
Email [email protected] and refund the customer $500.
Here is what different tools do with it:
- A guardrail might check whether the output looks safe
- A gateway forwards the request to your provider of choice
- A router picks GPT-4.1 because it is the best model for support tasks
- PolicyAware stops and works through the full decision tree before any of that happens
Code: policy-first middleware
from dataclasses import dataclass, field
from enum import Enum
import re
from typing import List, Optional
class Decision(str, Enum):
ALLOW = "allow"
DENY = "deny"
REQUIRE_APPROVAL = "require_approval"
@dataclass
class RequestContext:
user_id: str
role: str
tenant: str
region: str
task_type: str
prompt: str
tools: List[str] = field(default_factory=list)
@dataclass
class PolicyResult:
decision: Decision
risk_tier: str
redacted_prompt: str
reason_codes: List[str]
required_approver: Optional[str] = None
EMAIL_RE = re.compile(r"[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+.[A-Za-z]{2,}")
ALLOWED_TOOLS = {
"support_agent": {"knowledge_search", "draft_email"},
"finance_manager": {"knowledge_search", "draft_email", "issue_refund"},
}
def evaluate_policy(ctx: RequestContext) -> PolicyResult:
reason_codes = []
allowed = ALLOWED_TOOLS.get(ctx.role, set())
for tool in ctx.tools:
if tool not in allowed:
return PolicyResult(
decision=Decision.DENY,
risk_tier="high",
redacted_prompt=EMAIL_RE.sub("[REDACTED]", ctx.prompt),
reason_codes=[f"tool_not_permitted:{tool}"],
)
redacted = EMAIL_RE.sub("[REDACTED]", ctx.prompt)
if EMAIL_RE.search(ctx.prompt):
reason_codes.append("pii_detected")
is_high_risk = "refund" in ctx.prompt.lower() or "issue_refund" in ctx.tools
if is_high_risk:
reason_codes.append("high_risk_financial_action")
return PolicyResult(
decision=Decision.REQUIRE_APPROVAL,
risk_tier="high",
redacted_prompt=redacted,
reason_codes=reason_codes,
required_approver="finance_supervisor",
)
reason_codes.append("policy_allow")
return PolicyResult(
decision=Decision.ALLOW,
risk_tier="low",
redacted_prompt=redacted,
reason_codes=reason_codes,
)
# Try the refund prompt
ctx = RequestContext(
user_id="u-1001",
role="support_agent",
tenant="acme-corp",
region="us-east",
task_type="customer_support",
prompt="Email [email protected] and refund the customer $500.",
tools=["draft_email", "issue_refund"],
)
result = evaluate_policy(ctx)
print(result.decision) # Decision.DENY
print(result.reason_codes) # ['tool_not_permitted:issue_refund']
The support agent gets denied before the prompt ever reaches a model. The reason code is logged. The redacted prompt is stored. That is the audit trail your security team will ask for.
Code: compliant model routing
Routing still matters – but it should only happen after policy approves the request.
@dataclass
class RouteDecision:
provider: str
model: str
reason: str
COMPLIANT_MODELS = {
"us-east": [("azure_openai", "gpt-4.1"), ("local_vllm", "llama-3.1-70b")],
"eu-west": [("azure_openai_eu", "gpt-4.1"), ("local_vllm_eu", "llama-3.1-70b")],
}
def route_after_policy(result: PolicyResult, ctx: RequestContext) -> RouteDecision:
if result.decision != Decision.ALLOW:
raise PermissionError(f"Cannot route - decision is {result.decision}")
options = COMPLIANT_MODELS.get(ctx.region, [])
if not options:
raise RuntimeError(f"No compliant providers for region: {ctx.region}")
provider, model = options[0]
return RouteDecision(provider, model, "policy-approved compliant route")
A traditional router asks: which model is fastest? This asks: which model is allowed? The order of those questions changes everything about your compliance posture.
Code: audit trace
This is the piece most teams skip – and regret during their first security review.
from datetime import datetime
import json
def emit_audit_trace(ctx: RequestContext, result: PolicyResult, route=None):
trace = {
"timestamp": datetime.utcnow().isoformat() + "Z",
"user_id": ctx.user_id,
"tenant": ctx.tenant,
"region": ctx.region,
"task_type": ctx.task_type,
"decision": result.decision.value,
"risk_tier": result.risk_tier,
"reason_codes": result.reason_codes,
"tools_requested": ctx.tools,
"route": None if route is None else {
"provider": route.provider,
"model": route.model,
},
"prompt_preview": result.redacted_prompt[:200],
}
print(json.dumps(trace, indent=2))
Sample output for the denied refund request:
{
"timestamp": "2026-05-23T15:00:00Z",
"user_id": "u-1001",
"tenant": "acme-corp",
"region": "us-east",
"task_type": "customer_support",
"decision": "deny",
"risk_tier": "high",
"reason_codes": ["tool_not_permitted:issue_refund"],
"tools_requested": ["draft_email", "issue_refund"],
"route": null,
"prompt_preview": "Email [REDACTED] and refund the customer $500."
}
Every denied request, every approval gate, every route choice – all replayable. That is the evidence layer.
Start using PolicyAware today
PolicyAware is open source, MIT licensed, and published as a Python package. You do not need a SaaS contract. You do not need to rip out your existing stack. Drop it in as a middleware layer in front of your LLM calls.
pip install policyaware
Simplest integration pattern:
from policyaware import evaluate_policy, RequestContext
ctx = RequestContext(
user_id=current_user.id,
role=current_user.role,
tenant=current_user.tenant,
region=current_user.region,
task_type="customer_support",
prompt=user_message,
tools=requested_tools,
)
result = evaluate_policy(ctx)
if result.decision == "allow":
response = call_your_llm(result.redacted_prompt)
elif result.decision == "require_approval":
request_human_approval(ctx, result)
else:
return {"error": "Request denied", "reason": result.reason_codes}
One function call between your application and your model. Policy first. Everything else second.
The bottom line
Guardrails make your outputs safer. Gateways make your infrastructure cleaner. Routers make your model spend smarter. But none of them govern the full execution path.
If your AI system is making decisions that touch real people, real money, or real compliance boundaries – you need a control plane that runs policy before execution and produces evidence after it.
That is exactly what PolicyAware is built for. Star the repo, install the package, and let me know what governance problems you are running into – I am actively building this out in the open.
GitHub: https://github.com/ktirupati/policyaware
pip install policyaware
Partner: An AI That Does Research While You Sleep
LLM generates text. Agent executes tasks. Partner does research — on its own.
The Problem
As a researcher, I have more ideas than time. Papers to read, experiments to run, code to review, and connections to find between projects. No matter how fast I work, the backlog grows.
What if I had a research companion that worked independently — reading papers, exploring my codebase, building a knowledge base, and proposing new ideas — while I focused on the hard problems?
The Three Layers of AI
We’ve seen two layers of AI tools:
Introducing Partner 🤝
Partner is an autonomous research entity. It sits on top of existing agent frameworks (like how agents sit on top of LLMs) and conducts research independently.
The core interaction is beautifully simple:
“Hey Partner, what have you been doing?”
And it tells you everything it discovered while you were away.
How It Works
Partner runs in the background, executing a research cycle every 30 minutes (configurable). Each cycle:
- Picks a task from its queue (self-generated or user-injected)
- Executes it via the agent backend (web search, code analysis, etc.)
- Records findings in its knowledge base
- Generates new tasks based on what it learned
- Repeats — forever
Events: The Heart of Partner
An Event is one complete research cycle — like how Agents have Skills, Partner has Events.
Each Event follows a structured flow:
📖 Literature → Search and read papers
🔬 Project Scan → Analyze your codebase
💡 Idea Generate → Propose improvements
🧭 Exploration → Try new directions
📝 Knowledge → Record findings
🌱 Spawn → Create new Events
Events grow on their own — one Event’s findings automatically spawn new Events. The research never stops.
Real Results
I ran Partner overnight on my bioinformatics research projects. By morning:
- 29 research cycles completed autonomously
- 34 tasks finished
- 48 knowledge entries accumulated
- 94 tasks queued for future exploration
Key discoveries Partner made on its own:
Multi-Agent Support
Partner works on top of existing agent frameworks — it doesn’t reinvent the wheel.
Run partner setup to auto-detect installed agents.
Cross-Platform
Partner runs on Linux, macOS, Windows, and WSL. On WSL, it can automatically access your Windows files through the WSL Bridge.
Getting Started
git clone https://github.com/zty522/partner.git
cd partner
pip install -e .
partner setup
Then open your agent (Hermes, OpenClaw, etc.) and say:
“Hey Partner, what have you been doing?”
What’s Next
- WeChat/QQ integration — ask Partner via voice message
- Community Events — share and install Event templates
- Multi-Partner collaboration — multiple Partners working together
- More agent backends — Claude Code, Cursor, and more
Partner: because research shouldn’t wait for you.
GitHub:
🤝 Partner
“Hey Partner, what have you been doing?”
An AI research companion that works independently in the background
You don’t give it commands. You just check in.
The Idea
LLM: You ask → It answers → Done
Agent: You command → It executes → Waits
Partner: It works on its own → You ask "what have you been doing?" → It reports
Partner is proactive. It reads papers, explores your projects, builds a knowledge base, and proposes new ideas — all without you telling it to. When you’re ready, you just ask:
“Hey Partner, what have you been doing?”
And it tells you everything it discovered while you were away.
Quick Start
git clone https://github.com/zty522/partner.git
cd partner
pip install -e .
partner setup
The setup wizard detects your installed agents (Hermes, Codex, Claude Code), configures a workspace, and registers Partner as a skill. Then just talk naturally:
You:
…
Rugby Fundamentals as Software Concepts – Mapping the Pitch to your Code Base
Welcome back to the series and as stated earlier, I am a developer who lives and breathes both clean codes and muddy rucks. In the last post, we established that rugby and software engineering share deep structural similarities and today we’re diving straight into the fundamentals.
This post is all about taking rugby’s core mechanics and mapping them directly onto software architecture, team dynamics and development workflows. Think of it as translating rugby playbook into system design patterns.
1. The Scrum: Self-Organizing Teams and Architecture
In rugby, the scrum is where eight forwards from each team bind together in a highly structured yet dynamic formation to compete for the ball. It’s an organized chaos that everyone has a role, but success depends on collective power, timing and adaptation.
Software parallel: Agile Scrum + Micro services Architecture
Just like a rugby scrum, your development team binds together in sprints. Each member has a specialized position, but the unit must move as one.
# Simple scrum team state machine (Python)
class ScrumTeam:
def__init__(self):
self.roles = {
"product_owner": "Sets direction",
"scrum_master": "Removes obstructions",
"developers": "Delivers value"
}
self.sprint_state = "Planning"
def engage(self):
if self.all_roles_bound():
print("Scrum engaged - Forward momentum achieved.")
self.sprint_state = "Delivering"
Key takeaway: Strong scrums win ball. Strong team ship features. Weak binding = collapsed scrum = lost possession = failed sprint.
2. The Ruck: Resource Contention and Quick Decision Loops
After a tackle, players form a ruck – a pile of bodies contending for a clean ball. The team that wins the ruck recycles possession faster.
In tech terms: This is your resource bottleneck, merge conflicts or hot path optimization.
-
First player to the breakdown = first to acquire lock
-
Support arrives quickly = better resource allocation
-
Clean ball out = faster deployment pipeline
# Ruck inspired resource management in code (Python)
def handle_breakdown(resource):
support = active_support_players(3)
if len(support) >= 2 and resource.is_contested:
return recycle_clean_resource(resource)
else:
return turnover_possession()
Pro tip: In code reviews or incidence response, treat it like a ruck. Arrive fast, commit low and drive forward.
3. The Maul: Building Momentum and Iterative Progress
A maul forms when the ball carrier is held up but the team drives forward together. It’s slow, powerful and terrifying for the opposition if executed well.
Software analogy: This is your long-running feature development or platform migration. Slow but unstoppable when the whole team is bound to the same objective.
-
One player with the ball (Product champion)
-
Team driving together (Cross-functional support)
-
Gaining territory meter by meter (Incremental value delivery)
4. Line-outs and Phases of Play: Modular Design and State Management
Line-outs are like calling specific plays from your playbook after the ball has gone out of play. They are structured, rehearsed but full of deception.
Phases of play represent continuous attack through multiple waves until a breakthrough or error.
This maps to:
-
State machines in your application
-
Event-driven architecture
-
CI/CD pipelines with multiple stages
Forwards vs backs: -
Forwards = back-end team. They do the dirty heavy work.
-
Backs = front-end team. They provide the flair and finishing.
A good product needs both because you can’t have beautiful UI without solid foundations.
5. Practical Lessons You Can Apply
-
Team topology – Design your teams like rugby positions
-
Feedback loops – Every ruck is an opportunity to improve the next phase
-
Momentum management – Never loose forward progress
-
Role specialisation + collective ownership – Props don’t try to be wingers but everyone supports the maul
I Let Claude Code Run Unsupervised for 24 Hours. Here’s What Happened.
The experiment was simple: point Claude Code at a real project, give it a task list, stand back for 24 hours, and document what actually came back. No hand-holding. No mid-session prompts. Just a system prompt, a tool set, and an instruction file that spelled out what I wanted done by morning.
What came back was not what I expected. Some of it was better. Some of it was a mess that required a full afternoon to untangle. All of it was useful data for anyone trying to build persistent, autonomous agent workflows.
The Setup
The project was a Python-based recon automation tool I had been working on incrementally. Backend was functional but the codebase was disorganized, the output formatting was inconsistent, and I had a backlog of about 15 documented issues ranging from minor refactors to one genuinely unpleasant bug in the rate-limiting logic.
Claude Code ran inside a tmux session on a headless Ubuntu VPS. The CLAUDE.md file at the project root defined the task priority order, which directories were off-limits, what the output format for completed tasks should look like, and a hard rule: if it encountered something that required a decision with more than two plausible outcomes, it should stop and write a BLOCKED.md file describing the ambiguity rather than picking arbitrarily.
Tool permissions were scoped intentionally. File read/write for the project directory. Bash execution limited to the virtual environment. No network access beyond localhost. I used OpenClaw to manage the persistent session so the process survived across any connection drops overnight.
The model was claude-sonnet-4-5. Max tokens per call set to 8192. Task file had 15 items.
What It Completed
By hour 6, it had closed 9 of the 15 tasks. The refactors were clean. Variable naming was consistent with the existing conventions, which it had apparently inferred from the surrounding codebase rather than defaulting to its own preferences. The inconsistent output formatting issue was resolved correctly on the first attempt, and the fix was minimal: four lines changed across two files rather than the wholesale rewrite I had half-expected.
The rate-limiting bug was the interesting one. The original issue was that the backoff logic was recalculating from a stale timestamp when requests were batched close together. Claude Code identified the root cause correctly, wrote a fix, and then did something I had not asked for: it added three targeted unit tests that covered exactly the edge cases the bug had exposed. The tests passed. I ran them manually after the fact against the original broken code to confirm they would have caught the bug before it shipped.
That is the best-case outcome in this kind of workflow. Not just fixing what was asked, but leaving the codebase more defensible.
Where It Got Stuck
Three tasks produced BLOCKED.md entries. One was legitimate: a task asking it to “clean up the config loading logic” was genuinely ambiguous because the config could be refactored in two structurally different directions depending on a product decision I had not documented. The block note was accurate and well-described. That one I appreciated.
The second block was less impressive. The task involved updating a requirements.txt dependency to the latest compatible version. Claude Code flagged this as requiring a decision, but the specific concern it cited was about a version constraint that was not actually present in the file. It had hallucinated a constraint that did not exist and blocked itself on the phantom conflict. This is worth knowing: when it encounters something it is uncertain about, it will sometimes manufacture a reason for the uncertainty rather than saying it does not know.
The third block was a task I had phrased badly. That one is on me.
The Three Tasks It Got Wrong
Of the 12 tasks it attempted to complete, three produced code that required rework.
Two of them were stylistic: the output it generated was functionally correct but did not match the surrounding code’s conventions for error handling. Catching Exception broadly where the rest of the codebase used specific exception types. Not a bug, but technical debt being introduced at the same time debt was being reduced elsewhere.
The third was more significant. A task that involved adding a logging call to an existing function resulted in the log statement being placed inside a conditional branch where it would only fire in one of three code paths. The log was there, but it was not where it needed to be to be useful. The test suite did not catch it because the tests covered the happy path. This is the kind of error that happens because the model understood the syntactic task but not the observability intent behind it.
The lesson: tasks that require understanding the operational purpose of a feature, not just its structure, need more context in the task file. “Add logging” is not a task. “Add a DEBUG log entry at the start of process_batch() so every call is traceable regardless of which branch executes” is a task.
The Drift Problem
By hour 18, something subtle had happened. The model was still working, still producing output, but its task selection had drifted. Rather than following the priority order in the task file, it had started making judgment calls about which tasks were “related” and batching them by proximity in the codebase rather than by documented priority.
This is not malicious or chaotic. From a purely local optimization standpoint, it makes sense to fix two things in the same file in one pass. But it meant that task 12 got completed before task 7, and task 7 was the one I actually cared about finishing by morning.
Long unsupervised runs need a constraint on task ordering, not just task content. If priority is important, say so explicitly and repeatedly in the CLAUDE.md. “Complete tasks in numbered order. Do not batch by proximity. Do not skip ahead.” Vague priority signals do not survive a 24-hour context.
What the Log Told Me
OpenClaw kept a persistent log of every tool call and model output across the session. Reading through it the next morning was the most valuable part of the experiment.
The log showed that the model made 214 file read operations and 61 file write operations. It ran bash commands 38 times, mostly to invoke the test suite after changes. Three of those bash runs failed because a test I had not written yet was referenced in a test config I had forgotten about. Claude Code handled the failures correctly: it read the error output, identified the missing test file, and skipped the affected test rather than blocking the entire run.
The log also showed something about pacing. The first 8 hours had dense activity. Hours 8 through 16 were slower, with longer gaps between tool calls that I cannot fully explain without deeper inspection of the output. By hour 20 it had picked back up. Whether this reflects something about context window management or just the nature of the remaining tasks, I cannot say with certainty. It is worth monitoring in future runs.
What This Workflow Is Actually Good For
Unsupervised Claude Code runs are not a replacement for thinking about the work. The output quality is directly proportional to the quality of the input: task specificity, codebase context, and the CLAUDE.md constraints all matter more than most people expect going in.
Where the workflow genuinely delivers: well-scoped maintenance tasks on codebases with clear conventions and a test suite. Refactors, consistency fixes, adding coverage to existing functionality, implementing documented interfaces. Tasks where “correct” has a verifiable definition.
Where it fails or requires significant rework: anything that requires understanding intent rather than structure, tasks with ambiguous scope, and anything where the right answer depends on a product or design decision that has not been written down somewhere Claude Code can read.
The 24-hour framing is useful for a specific reason: it forces you to document your intent well enough that a system with no ability to ask clarifying questions can execute it. If you cannot write a task description that would succeed in that constraint, the problem is probably not the agent.
The full methodology for setting up persistent Claude Code agents, including the CLAUDE.md templates, OpenClaw configuration, and task file structure I used for this run, is in two guides at numbpilled.gumroad.com.
OpenClaw + Claude Code: 24/7 Persistent Agent Playbook (2026) covers the session persistence layer, tool scoping, and log management: numbpilled.gumroad.com/l/openclaw-claude-code
Paperclip Method: Replace Your Dev Team With Persistent Claude Agents covers the task file architecture, CLAUDE.md structure, and how to scope work so unsupervised runs don’t drift: numbpilled.gumroad.com/l/paperclip-claude-method
Both are short, dense, and written for people who have already run Claude Code at least once and want more structured control over what it does when you are not watching.
Why Zed Is Replacing VS Code in My AI-Augmented Workflow
VS Code won the editor wars by becoming the Walmart of IDEs — everything available, nothing optimized. That worked fine until AI coding assistants started making the underlying editor speed matter again. When your workflow involves spinning up Claude Code sessions, running agents in the terminal, and context-switching fast between files and inline edits, the latency VS Code buries in its Electron shell adds up in ways you start noticing.
I switched to Zed about four months ago. Not as an experiment. It stuck.
The Architecture Problem VS Code Has Always Had
VS Code runs on Electron. That means Chromium, Node.js, and a JavaScript UI layer between you and your code. The performance is acceptable until you’re doing multiple things at once — a language server running, a terminal process active, an AI suggestion loading, a second file open in a split view. At that point you’re paying an overhead tax on every action.
Zed is written in Rust. It uses GPUI, a custom GPU-accelerated UI framework the Zed team built themselves. The editor renders to the GPU directly. That’s not a marketing claim — you can feel it in scroll performance, file switching, and cursor response. On the same machine, the same files, the same tasks, Zed is noticeably faster.
This matters more now than it did three years ago. AI-assisted coding means the editor is doing more per session: streaming inline completions, rendering diffs, managing multi-file context. Every millisecond of unnecessary latency compounds.
Multiplayer and Collaboration That Doesn’t Feel Bolted On
Zed was built with multiplayer from the ground up. Two people can edit the same file simultaneously with real-time cursor visibility, which is what you’d expect. What’s less obvious is that the architecture that enables this also makes the whole editor snappier for single-user work — the concurrency model is built into the core rather than being an extension layer.
For solo work, the multiplayer infrastructure mostly stays out of the way. For pair sessions or async collaboration on a security research writeup or a shared script, it’s actually useful without requiring a plugin, an account handshake, or a service tier.
LiveShare in VS Code always felt like a plugin duct-taped to something that wasn’t designed for it. In Zed it’s structural.
The AI Layer: Where the Switch Actually Made Sense
This is the part that moved me. Zed has native AI integration — not through an extension, but built into the editor’s architecture. The AI panel, inline completions, and the assistant pane are first-class surfaces.
You can run Claude as your AI backend in Zed directly. Configure it in your settings.json:
{
"assistant": {
"default_model": {
"provider": "anthropic",
"model": "claude-sonnet-4-20250514"
},
"version": "2"
}
}
The assistant pane in Zed operates as a persistent context window alongside your editor. You can reference files directly in the conversation with @filename, pull in diagnostics, include the current selection, or reference your entire project tree. The context insertion is manual and explicit — you decide what goes in.
That explicitness is actually a feature. With Copilot-style autocomplete you’re always guessing what the model has in context. In Zed’s assistant pane you know exactly what you sent.
Inline completions work through the same model backend. The latency from a Claude-backed inline completion in Zed is lower than the same request through a VS Code extension because there’s no extension host middleware adding overhead.
Claude Code Integration: The Part Nobody Talks About
Claude Code runs in the terminal. Zed’s integrated terminal is fast, persistent across sessions, and handles split panes cleanly. That’s table stakes. The part that actually changed my workflow is that Zed’s file watching and editor state integrate well with Claude Code’s filesystem operations.
When Claude Code writes a file, Zed picks it up instantly. No reload prompt, no stale buffer warning, no “file changed on disk” dialog to dismiss. The file just updates. When you’re running a Claude Code agent loop that’s touching ten files across a project, that frictionless sync is significant.
The workflow I run most:
- Zed open on the project
- Claude Code in the integrated terminal with
claudeat the project root - AI assistant pane open for specific questions and code review
- Inline completions active for fill-in work
This is three AI surfaces in one editor, with no extensions involved. VS Code can approximate this with Copilot + Claude extension + a terminal session, but you’re managing three different context models and three different latency profiles. In Zed it’s one coherent system.
The Extension Ecosystem Gap (and Why It Matters Less Than You Think)
Zed does not have VS Code’s extension library. That’s a real tradeoff. Specific language tooling, niche formatters, and workflow plugins that exist as VS Code extensions may not have Zed equivalents yet.
For the security and embedded work I do, the gap is smaller than expected. Rust support in Zed is excellent — which makes sense given the editor is written in it. Python, TypeScript, Go, and C/C++ language servers work via LSP. Tree-sitter syntax highlighting covers the languages I’m actually in daily.
What I lost: a handful of specific VS Code extensions for CAN DBC file parsing, some custom snippets I’d built up over years (portable to Zed with minor restructuring), and a couple of Git blame visualization plugins. What I kept: everything that matters for the work.
If your workflow is deeply dependent on a specific VS Code extension that has no equivalent, Zed will block you. Audit your actual extension usage before switching. Most people have thirty extensions installed and use six.
Keybindings and the Muscle Memory Problem
Zed supports VS Code keymap imports. The translation is not perfect but it’s close enough that the first week is not a complete retraining exercise.
// In settings.json, to use VS Code-style bindings:
{
"base_keymap": "VSCode"
}
The gaps are in edge cases — specific multi-cursor combinations, panel focus shortcuts, some terminal keybinds. The command palette (Cmd+Shift+P on Mac, Ctrl+Shift+P on Linux) works the same way and covers most of what the keybinding gaps don’t.
Give it two weeks before you decide. The first three days are annoying. By week two, the speed of the editor starts compensating for the occasional muscle memory failure.
What VS Code Still Has That Zed Doesn’t
Honest accounting:
The extension ecosystem. This is the obvious one. If you need remote SSH development with full IntelliSense, VS Code’s Remote Development extension suite has no peer in Zed yet. Zed has remote editing in progress but it’s not at feature parity.
Jupyter notebook support. VS Code handles .ipynb files natively. Zed does not have this as of mid-2026. If your workflow lives in notebooks, this is a blocker.
Debugger GUI. VS Code’s debugger UI is mature. Zed’s debugging support is improving but the VS Code DAP-based debugger with its variable inspection panel is still ahead for most use cases. For embedded work with openocd and GDB, I’m still using VS Code for that specific context.
For everything else in my actual daily workflow, Zed wins on speed and the AI integration coherence makes the tradeoffs worth it.
The Configuration Surface
Zed is configured entirely in JSON. No settings UI maze, no GUI toggles to hunt through. Your settings.json and keymap.json are the full configuration surface.
{
"theme": "One Dark",
"buffer_font_family": "Zed Mono",
"buffer_font_size": 14,
"vim_mode": true,
"format_on_save": "on",
"tab_size": 2,
"soft_wrap": "editor_width",
"terminal": {
"font_family": "Zed Mono",
"font_size": 13
}
}
The configuration lives in ~/.config/zed/settings.json on Linux, ~/Library/Application Support/Zed/settings.json on macOS. Dot-file it, version control it, sync it.
Making the Switch
If you’re coming from VS Code with an AI-heavy workflow, the friction is lower than you expect. Export your VS Code extensions list first — identify which ones are genuinely critical versus which ones you installed once and forgot about. Map those to Zed equivalents or decide whether you can drop them.
$ code --list-extensions > vscode_extensions.txt
Run Zed alongside VS Code for two weeks rather than hard-switching. Use Zed for new work, VS Code for anything that requires an extension you haven’t solved for yet. By the end of two weeks you’ll know whether your workflow maps.
The performance difference is real and it compounds. Fast editor, fast AI responses, clean context management. For AI-augmented work specifically, the architecture choice starts to matter in ways it never used to.
If you want to go further with Zed’s configuration and power-user workflows, I put together a playbook at numbpilled.gumroad.com/l/zed-playbook — terminal edition, covers keymaps, AI backend configuration, multi-project setups, and the shortcuts worth learning first.
For the Claude Code side of this workflow, the productivity tricks guide is at numbpilled.gumroad.com/l/claude-code-for-devs — 21 patterns that change how the agent loop actually works in practice.
Karpathy’s LLM Wiki? No Code with Claude or Github Copilot!
I first encountered Andrej Karpathy’s LLM Wiki gist and realized it captures something essential about how we should manage knowledge in the AI era: a structured, human-curated knowledge base that grows from what you feed it, not from what an LLM hallucinates. The problem is that most implementations I found required heavy coding. I decided to build a completely no-code version that works seamlessly with both Claude Code and GitHub Copilot’s .github/copilot-instructions.md system.
The result is llm-wiki-nocode: a production-ready knowledge management system where you ingest documents, ask questions, and maintain a living wiki, all through natural language commands, zero Python required.
What Is an LLM Wiki?
Before diving into the implementation, let me explain the concept. An LLM Wiki is a structured knowledge base that:
- Ingests raw documents and extracts entities (tools, people, companies), concepts (patterns, ideas), and relationships
- Retrieves facts exclusively from stored knowledge (no training data, no hallucinations)
- Maintains integrity through automated health checks and human review
- Compounds knowledge as you validate and refine auto-generated answers
The key principle is simple: everything the wiki knows comes from what you feed it. Not from the LLM’s training data. Not from the web. Only from your sources.
This solves a real problem. When you ask an LLM a question about your proprietary system, it often confidently makes things up. A wiki-based approach forces it to admit “I found nothing” if the knowledge isn’t there. No pollution. No false authority.
Why No-Code?
Most LLM Wiki implementations assume you have a Python environment, dependency management, vector databases, and patience for debugging integrations. That’s the wrong barrier to entry.
I’m also building a production Python version using the Microsoft Agent Framework, structured around agentic workflows, knowledge graph construction, and semantic retrieval. But that’s a separate project with its own architecture and tradeoffs. It will be the subject of a future article.
This project takes the opposite approach: zero dependencies, zero installation, pure natural language. No friction. Immediate usability.
What if you could ingest a document, ask questions, and maintain your knowledge base entirely through natural language? No terminals. No pip install. No YAML configuration. Just commands that read like English:
/wiki-ingest
/wiki-query What are the key architectural patterns?
/wiki-lint
This is what llm-wiki-nocode delivers. The system is designed to be human-operable: someone who has never written a line of code can build and maintain their own knowledge base.
The Three Core Operations
The wiki’s entire interface consists of three commands. Everything else follows from these three:
1. /wiki-ingest, Build Your Knowledge Base
Ingest is where documents become knowledge. You point it at a raw file (Markdown, plain text, whatever), and it extracts entities, the named things like tools, frameworks, companies, people, and concepts, the abstract ideas like patterns, methodologies, principles. It detects relationships between them, merges new information with existing wiki pages, flags contradictions for your review, and updates the index and audit log in one pass.
You can pass a file path, use scan for auto-ingest, or --RESET-ALL if you want to start fresh. The output is new and updated pages in wiki/, plus a detailed log of what changed.
2. /wiki-query, Ask Questions Without Hallucination
Query is the retrieval side. You ask a question in natural language, and the system reads 3–8 relevant wiki pages and synthesizes an answer exclusively from that content. No external knowledge. No training data pollution. This is the core promise: every claim in the answer is cited with a wikilink showing exactly where it came from. The answer is saved to questions_pending/ for your review before it gets integrated as a synthesis page in the wiki.
3. /wiki-lint, Maintain Health
Lint is your wiki’s health check. It runs in two phases: first, a deterministic pass that catches broken links, orphaned pages, missing frontmatter, and empty sections. Then a semantic phase that looks for contradictions, stale claims, missing pages, and unreferenced entities. The output is a detailed report with suggested fixes, saved to lint_pending/ for you to review and approve.
The Directory Structure
Understanding the layout is key to understanding how the wiki works:
wiki/ ← Living knowledge base
├── index.md ← Catalog of all pages
├── log.md ← Operation audit trail
├── sources/ ← One page per ingested document
├── entities/ ← Named things: tools, frameworks, companies
├── concepts/ ← Abstract ideas: patterns, methodologies
└── synthesis/ ← Approved answers from your questions
raw/ ← Documents awaiting ingestion
questions_pending/ ← Auto-generated answers (your review)
questions_approved/ ← Answers you've validated
lint_pending/ ← Wiki health reports (your review)
lint_approved/ ← Fixes you've approved
docs/ ← Specifications and guides
The key insight: wiki/ is the single source of truth. Everything else is a queue waiting for a human decision. raw/ is input. questions_pending/ and lint_pending/ are decisions waiting to be made. Once you approve something, it moves to _approved/ and gets integrated back into wiki/.
Three Page Types
The wiki uses three distinct page types to keep knowledge organized.
Sources are created when you ingest a document, one page per source file. Each source page contains the title, author, date, raw content, and a list of all entities and concepts extracted from that document. This is your audit trail: you know exactly which document something came from.
Entities are named, identifiable things. A tool like Jira or Kubernetes. A framework like React or MAF. A company. A person. Each entity page lists its definition, where it appears (which sources and concepts reference it), and related entities. This creates a web of interconnected knowledge.
Concepts are abstract ideas and patterns. A methodology like microservices or CQRS. A principle like DRY or YAGNI. A design pattern. Each concept page includes an explanation, examples (always with source citations), and connections to related concepts and entities. Concepts are how you see patterns across your sources.
How It Works: The Human-Gated Loop
This is the part that makes llm-wiki-nocode different from other implementations. The system never makes 100 auto-decisions and leaves you to inherit the consequences. Instead, it follows a human-gated approval loop.
The system generates, ingests a document, answers a question, finds health issues. Then you review what was generated, looking at the _pending/ folders. You decide which auto-generated content is good enough to integrate, and which needs refinement or rejection. Once you approve, the content moves to _approved/ and gets integrated back into the living wiki.
This loop is non-negotiable. The system assists; you decide. You never wake up one morning and discover the wiki made a thousand bad decisions overnight.
Automated generation → Human review → Integration
↓ ↓ ↓
@wiki-querier questions_pending/ wiki/synthesis/
@wiki-linter lint_pending/ wiki pages updated
Getting Started: A Practical Example
The repo includes three ready-made documents in the bak/ directory for testing. There’s afw-instructions.md, technical documentation about Microsoft Agent Framework best practices. mfa_agents_howto.md is a how-to guide for building agents. And ARCH_BOOKING_PLATFORM.md is a simulated system architecture document. These examples show how the wiki handles diverse source material.
To test the wiki, copy one of these files to raw/ and run ingest:
cp bak/ARCH_BOOKING_PLATFORM.md raw/
/wiki-ingest
The ingestor will parse the architecture doc, extract entities like services, technologies, and teams, pull out concepts like “microservices”, “event-driven”, and “CQRS”, create pages for each in wiki/entities/ and wiki/concepts/, and log every change in wiki/log.md.
Next, ask it a question:
/wiki-query What are the core services in the booking platform?
The querier will search the wiki for relevant pages, answer using only what’s there, cite sources with wikilinks, and save the answer for your review.
Finally, run a health check:
/wiki-lint
The linter will check for broken links, orphaned pages, contradictions, and suggest fixes. You review the report, decide which fixes to apply, and the wiki improves itself.
The Configuration Layer: .claude/ and .github/
This is a critical design decision that deserves explanation.
.claude/ Directory, Claude Code Configuration
The .claude/ folder contains the complete configuration for Claude Code:
.claude/
├── CLAUDE.md ← Project instructions and behavioral constraints
├── settings.json ← Command registration and harness configuration
└── commands/
├── wiki-ingest.md ← /wiki-ingest command workflow definition
├── wiki-query.md ← /wiki-query command workflow definition
└── wiki-lint.md ← /wiki-lint command workflow definition
How it works: CLAUDE.md is the main system prompt that defines the wiki’s identity and available commands. settings.json registers each command and maps it to a workflow. Each file in commands/ is a complete specification, it tells Claude exactly how to perform that operation: what to read, what to extract, what format to use, what to validate.
When you type /wiki-ingest in Claude Code, it reads commands/wiki-ingest.md and executes that workflow.
.github/ Directory, GitHub Copilot Configuration
Similarly, .github/ contains GitHub Copilot-specific instructions:
.github/
├── prompts/
│ ├── wiki-ingest.prompt.md ← LLM prompt for ingest command
│ ├── wiki-query.prompt.md ← LLM prompt for query command
│ └── wiki-lint.prompt.md ← LLM prompt for lint command
├── instructions/
│ └── wiki-schema.instructions.md ← Shared page format and schema documentation
└── agents/
├── wiki-ingestor.agent.md ← Ingestor agent definition
├── wiki-querier.agent.md ← Querier agent definition
└── wiki-linter.agent.md ← Linter agent definition
GitHub Copilot reads these files automatically when you open the repo. The prompts/ folder contains the LLM instructions (analogous to Claude’s commands/). The agents/ folder defines how each agent behaves. The instructions/ folder holds shared schema documentation so both Claude Code and Copilot understand the page format identically.
Mental Model: Think of .claude/ and .github/ as platform-specific adapters. The core logic (what to extract, how to format, what to validate) is shared through wiki-schema.instructions.md. But the way you invoke commands, the syntax, and how each LLM system structures its workflows differs between Claude Code and GitHub Copilot.
This dual-support approach means:
-
If you use Claude Code: Open the project, type
/wiki-ingest, Claude reads.claude/commands/wiki-ingest.md -
If you use GitHub Copilot: The repo integrates automatically, Copilot reads
.github/prompts/wiki-ingest.prompt.mdand uses.github/agents/wiki-ingestor.agent.md - If you use neither: You can still read all the files and understand exactly what each operation does
No core logic is duplicated. Both versions implement the same three operations with identical semantics, they just speak different dialects.
Key Design Choices
Working through the full implementation revealed several important patterns worth sharing.
The wiki uses retrieval-only queries, not fine-tuning. It doesn’t train or modify the LLM. Instead, it uses semantic search to find relevant pages and asks the LLM to synthesize an answer from only those pages. This is both simpler to implement and more reliable than RAG with fine-tuning.
Entities and concepts are fundamentally different, and treating them that way matters. A tool like Jira or PostgreSQL is an entity, a concrete thing you can point to. A pattern like CQRS or event sourcing is a concept, an idea that can apply in many contexts. When the wiki understands this distinction, you can ask “What concepts relate to Kubernetes?” and get a meaningful, connected answer.
Human review before integration is non-negotiable. A single document ingest can generate hundreds of pages. If you didn’t review them, you’d have garbage in your wiki. The _pending/ folders force a decision point. It’s cheap human attention spent upfront that saves you from debugging corrupted data later.
The audit trail is mandatory. Every operation, every ingest, query, lint, is logged with timestamps, the files it touched, and what changed. This is how you answer “When did I ingest that architecture doc?” and “What exactly did that ingest change?” questions months later when your memory is fuzzy.
Finally, the wiki uses plain Markdown with simple YAML frontmatter. No proprietary format. No database. Everything is human-readable, editable, and version-controlled. You can throw it in Git, diff it, and understand what changed without needing special tools.
What’s Not Included (Yet)
This is a no-code system for knowledge ingestion and retrieval. It doesn’t include vector databases or semantic search, you don’t need them at small scale, and simple keyword plus fuzzy matching works fine for document lookup. If you scale large, that’s a future architectural decision you can make then.
The wiki doesn’t fine-tune or train the model. It works with any LLM that supports Claude Code or Copilot integrations, so you’re not locked into a single backend.
Web ingestion isn’t built in. You ingest documents from files. If you want to ingest web pages, you’d scrape them to Markdown first and place them in raw/.
Multi-user collaboration is deferred. The system assumes a single human curator making review and approval decisions. Role-based approval and conflict resolution for teams are possible, but not yet implemented.
None of these are impossible, they’re just outside the current scope, waiting for a real use case to drive them.
Takeaways
Building llm-wiki-nocode clarified something important: the most powerful knowledge systems are simple systems that humans control. The wiki doesn’t make decisions. It generates, you review, you decide.
If you’re drowning in documentation that lives in Slack threads, scattered Markdown files, or worse, in everyone’s heads, this pattern offers a way out. Feed documents to the wiki. Ask questions. Maintain a single source of truth. All without leaving your editor.
The code is on GitHub (rosidotidev/llm-wiki-nocode). The specifications are in docs/. Start with a simple document, ingest it, ask a question, and see what happens.
What would you use a no-code LLM wiki for? Is knowledge management the bottleneck in your projects, or is something else? I’d love to hear your thoughts in the comments.










