AI coding without amnesia: inside the MyGuard workflow

Our AI coding workflow keeps durable knowledge in SQLite while Claude and Codex share Markdown workflow instructions. That’s an ordinary foundation for something people keep trying to sell with pictures of glowing brains.

Good. Ordinary foundations are easier to inspect when something breaks.

The interesting question is whether an agent can find the right project, remember a decision from last month, change a function without touching someone else’s work, test the result, and survive a context reset without starting the investigation again.

Then somebody has to check the work.

At MyGuard, those jobs are divided among mirrored memory, reusable skills, bounded search tools, an autonomous workflow called grind, deterministic checks, and two standing review gates: CodeRabbit and our local PR-agent. Each component has a specific job. Understanding those jobs matters more than memorizing the tool names.

This is a description of our setup as inspected in September 2026. Where a safeguard is documented but its runtime behavior hasn’t been independently established here, I’ll say so. Measured productivity and defect-reduction figures remain an open question.

Table of Contents

What do we mean by memory?

A coding agent’s conversation is temporary working space. It contains the current task, recently read files, tool results, and instructions. Eventually that space fills up, gets summarized, or disappears with the session. Writing a lesson to disk gives the next session something to retrieve; it doesn’t train the model.

Think of a workshop. The conversation is what the people currently on shift remember. Persistent memory is the job board, maintenance log, and note explaining why the apparently redundant valve must stay open.

You want the next shift to read that note before “cleaning up” the plumbing.

The mirror follows the projects

Our memory tree mirrors the repository layout. Project knowledge lives under the corresponding project path, with a small index routing the reader to relevant files. That answers a practical question: whose knowledge is this?

A packaging constraint shouldn’t quietly become a universal rule for every application. A workaround in one nginx module shouldn’t spread into unrelated modules because an agent retrieved a familiar-looking paragraph. Scope is part of the fact.

File or record What belongs there
Project index Where to look next
Issues and TODOs Work that remains, with enough detail to act
Lessons Verified causes, constraints, and decisions worth remembering
History Outcomes that need a durable record
Handoff The current state needed to resume interrupted work

The mirror gives Claude and Codex a common place to read and write. They aren’t maintaining competing notebooks and periodically reconciling them. The shared tree is the working record.

That still requires coordination. Two agents can overwrite the same file. A filesystem is quite willing to preserve the last mistake it receives.

Remember the expensive part

Useful memory captures something costly to rediscover.

“The parser is in this file” is usually cheap to derive through code search. “This apparently harmless configuration change breaks an older consumer, and here is the evidence” has a better claim on permanent storage.

Keeping every command from an investigation produces a transcript. Keeping the cause of the failure and the condition that triggers it produces a lesson. The distinction matters when the next agent has room to read only a few paragraphs.

Our memory workflow includes checks for structure, stale claims, oversized context, orphaned material, and duplication. Cold history can leave the small working files without losing its durable evidence.

Memory needs retirement rules as much as it needs an “add” button. Otherwise it becomes a museum where every exhibit is labelled “current.”

Where does SQLite fit in an AI coding workflow?

SQLite holds the searchable durable corpora, while Markdown remains the editable working surface. The setup separates internal memories from curated external knowledge. A project decision and a paragraph obtained from upstream documentation have different origins, so their provenance and freshness need to remain visible when retrieved.

Memory retrieval in the AI coding workflow.
Working notes and sourced external knowledge use separate durable corpora. Search results still need verification.

Searchable doesn’t mean intelligent

The inspected implementation uses SQLite FTS5, a full-text search extension, with BM25 relevance ranking. It searches words and tokens. It isn’t an embedding database.

That distinction can disappear under the phrase “semantic chunks.” Here, chunks follow meaningful document boundaries such as headings and checklist units. This preserves context around a passage. It doesn’t mean every paragraph has been converted into a mathematical representation of its meaning.

FTS5 supplies the text-matching and ranking machinery. SQLite documents how FTS5 works.

Technical material often contains distinctive project names, function names, and error messages, which makes lexical search a useful fit. But a search using different terminology may miss the right lesson. A highly ranked result may be obsolete. Retrieval supplies candidates to inspect.

Small results protect the working context

The search interface returns bounded results: identifiers, metadata, short snippets, and information about truncation or query widening. The agent can then load the records that matter.

This avoids copying the archive into every conversation. It also makes the search process inspectable. You can see which record supported a decision instead of accepting “I remember something about this” as an engineering reference.

During the research for this article, an older instruction said searches required all query terms. The current implementation attempts that match first, then can widen an empty result to any-term matching. It reports the widening.

That flag carries useful information. A broad fallback deserves a different reading from an exact match. It also exposes a maintenance problem: the instructions describing the search engine can become stale while the search engine keeps working.

Preserve the source, then question it

The durable store uses document manifests and ordered chunks. A manifest records information about a document; the chunks hold its numbered pieces. Verification can reconstruct the document and check recorded lengths and a SHA-256 digest, a compact fingerprint of the bytes.

The fingerprint helps answer, “Did we preserve the same document?” Factual correctness requires a separate check.

External knowledge admission requires provenance fields including source identity, publisher information, a digest, and a retrieval timestamp with a timezone. Those fields make later verification possible. Filling in a publisher field doesn’t authenticate the publisher.

The archive implementation also accounts for interruptions. It commits and verifies the SQLite material before publishing the Markdown archive and replacing the live file. A crash between stages may leave duplicates; that is preferable to losing evidence. Supported retries deduplicate exact ingestion.

That’s the sort of transaction ordering you appreciate after the electricity stops being theoretical.

Use the configuration that exists

The inspected memory store uses SQLite rollback-journal mode, specifically DELETE, with synchronous=FULL, foreign-key enforcement, a busy timeout, and trusted_schema=OFF.

Describing this installation as using write-ahead logging, or WAL, would be wrong. WAL is another SQLite mode with its own concurrency and checkpointing behavior. Under WAL, readers can overlap a writer, but there is still only one writer at a time. SQLite’s WAL documentation explains the constraints.

A popular tuning article isn’t evidence about our database.

Two operational questions deserve equal billing with search. What happens when a record becomes stale? The inspected ranking doesn’t automatically enforce every review deadline, so the reader still checks current evidence. And what survives a clean clone? The databases are gitignored. Cloning the repository alone cannot be assumed to restore the durable corpora.

Database backups, retained source material, and tested restoration procedures need their own attention. A green Git status is a remarkably poor backup strategy.

How do Claude and Codex share skills?

A skill is a reusable procedure: when it applies, which evidence to gather, what actions to take, and how to recognize completion. Memory records what we learned. Skills describe how we work. Our mirror connects both agents to a common workflow source while retaining adapters for their different runtimes.

The canonical MyGuard workflow files live in the Claude skill tree. Codex discovers mirrored entries that largely point to those same files through symbolic links. A symbolic link is a filesystem pointer to another path: two discovery layouts can reach one maintained document.

Fix the canonical procedure, and both routes can reach the correction. That reduces duplicated editing. It doesn’t make the two runtimes identical.

Shared procedure, different adapters

Both products document skills, but the MyGuard bridge is our integration choice, not a promise that their native instruction handling is interchangeable. OpenAI’s skill documentation and Claude Code’s skill documentation describe the respective product interfaces.

The bridge translates workflow intent into mechanisms available in the current runtime. A historical provider-specific model label may describe an intended cost or reasoning tier. It doesn’t authorize pretending that an unavailable model exists.

A specialized workflow can also have a bounded fallback. The fallback must describe what ran. It cannot claim an independent review happened because the current agent reread its own answer with a more serious expression.

Routing has several jobs: identify the repository, select the workflow, check available capabilities, and assign repeatable work to tools. Stronger reasoning belongs where uncertainty or consequences justify it. Separate workers belong where their output can be integrated and checked.

Give tools the repeatable work

Our search order starts with the shared code-context router, then bounded text or structural searches, followed by detailed reading when the evidence calls for it. The router provides project discovery, file lists, symbols, and search without dumping whole repositories into a conversation.

A command-line interface, or CLI, is often enough for local work. The Model Context Protocol, or MCP, supplies another structured interface where appropriate. MCP is a way to expose tools and data; its presence doesn’t establish that a particular tool launched successfully, that the current session can call it, or that returned content is trustworthy.

The division of labor is deliberate. Use a script for a repeated transform, a linter for an established rule, and model judgment for the part that remains ambiguous. Asking a large model to count files is an expensive way to acquire a less reliable wc.

The same economy applies to instructions. The mirror loads a small router, the selected skill, and triggered references. Every worker doesn’t need the entire organization’s procedures. A WordPress publishing rule doesn’t belong in a C ownership investigation unless the task spans both.

Instructions and interlocks are different things

A Markdown rule can tell an agent to stop. A hook can reject a tool call.

Our Codex hook configuration routes shared hook scripts through an adapter that translates runtime payloads. That reduces duplicated enforcement logic. But three states must remain separate:

State What it establishes
Configured A rule or hook is declared
Checked A particular checker examined part of the setup
Enforced The running system applied the restriction

A parity checker can pass without proving universal behavioral equivalence. For example, detecting the presence of a trusted hook hash is weaker than establishing that every current hook hash is trusted.

A diagram containing a box labelled “sandbox” doesn’t establish isolation. The implementation, launch configuration, and observed behavior have to agree.

How does grind’s warden-supervisor-worker workflow work?

Grind is our autonomous backlog workflow. It processes an approved queue through implementation, verification, and delivery. The default has three layers: a warden keeps the run alive, a supervisor manages the engineering work, and a worker implements a bounded assignment. Each layer has its own context and a different reason to exist.

The extra layer at the top solves a practical problem. A backlog can outlive one supervisor’s conversation. Somebody outside that conversation must remain available to start its replacement.

A supervisor cannot reliably arrange its own next shift after its current shift has ended.

Warden, supervisor, and worker responsibilities in grind.
The warden manages lifecycle; the supervisor owns engineering decisions; the worker implements its assigned slice.

The warden keeps the run alive

The warden stays in the main chat. It establishes the approved repository scope and worktree arrangement, starts a supervisor, waits for its return, and decides whether to start another cycle or stop.

It deliberately avoids reading project source and making technical decisions. Its checks are small: does the returned status contain the required fields, did the handoff file change during the cycle, and do claimed merges also appear in the supervisor’s list of verified PRs?

That establishes reporting consistency. It doesn’t establish that a patch is correct. The warden cannot judge an nginx ownership bug from a cycle counter, and the workflow doesn’t ask it to try.

Keeping this role small matters. If the warden reads every diff and debugging transcript, it becomes another overloaded supervisor and loses the reason for its existence.

The supervisor owns the engineering decisions

The supervisor reads the persisted handoff, checks it against current repository state, and selects work from the queue. It owns acceptance criteria, dependencies, tier selection, worker dispatch, verification, review, delivery, and the next handoff.

The queue has two phases: findings first, then the roadmap. In-flight fixes and correctness problems take priority over cosmetic work. Completing a phase triggers the appropriate recount and transition; it doesn’t authorize inventing a new project to work on.

For each item, the supervisor retrieves relevant durable memory once and passes record identifiers and constraints to the worker. A worker shouldn’t spend its first ten minutes rediscovering why last week’s obvious shortcut was rejected.

When the worker returns, the supervisor verifies artifacts. It checks the branch and commits, the actual diff, relevant test evidence, and any reported PR. A worker saying “done” is a claim about the work. The supervisor needs evidence before changing the persistent row to done.

The separate review process still applies. Supervisory verification and the CodeRabbit/PR-agent gates have different responsibilities; accepting a worker’s report doesn’t satisfy independent review.

The worker receives a job, not a blank cheque

A worker implements one assigned queue slice on one assigned branch, at one selected tier. A slice may contain related small sweep items when they share scope and don’t violate dependencies.

The packet names the item, what must remain true, the completion criterion, the verifier, the worktree, and relevant memory. The worker runs required checks, preserves its work, and returns concrete identifiers and evidence.

If the packet requires an architecture or contract decision it cannot settle, the worker returns a decision packet to the supervisor. It doesn’t silently rewrite the acceptance criterion until its patch qualifies.

Workers also don’t spawn more workers, broaden the repository scope, ask the user questions, or certify their own review. Three layers are enough. An organizational chart that reproduces by mitosis is an incident waiting for a budget.

Three layers doesn’t mean a swarm editing one tree

The routine workflow uses foreground delegation: the warden waits for its supervisor, and the supervisor normally dispatches one implementer at a time. This is a chain of responsibility, not a claim that several workers should write the same checkout simultaneously.

External work can remain in flight. A PR may be waiting on remote CI while the supervisor handles another dependency-safe item. The workflow records the branch, PR, review state, last poll, and next action so waiting work doesn’t vanish from view.

The difference matters. Parallel work needs isolated ownership. A slow remote job needs a cursor and a revisit time. Neither problem is solved by letting two agents share an index and hoping they are polite.

A complete cycle has an observable result

A warm cycle begins by reading the handoff and comparing its recorded progress with Git, the queue, verifiers, and remote state. The supervisor checks whether ledger files changed, live-checks the next row, and then dispatches its worker.

After verifying the return, it applies the review and delivery rules, revisits in-flight PRs, updates the ledgers, and writes the next handoff. Related sweep work can reach a validated commit without immediately opening a separate PR for every tiny item.

The return is a compact status record, with counts and identifiers rather than pasted logs. The warden routes it as follows:

Returned state Meaning and next action
continue Resume in a fresh supervisor cycle.
done All approved repositories passed completion checks; stop.
gated Preserve the classified hard blocker and stop.
ask Relay if attended; otherwise record the question and gate.
Invalid return Retry once; stop after a second failure.

A continuation report needs an updated handoff. Without it, the replacement supervisor has no saved state for the cycle it is meant to continue.

The completion check is stronger than finding a heading that says “zero open.” Actual row enumeration and a separate mechanical recount must agree. The warden checks the reported counts; it doesn’t independently read the backlog itself.

Our nginx module template with working CI supplies a foundation for this workflow: a project should already have meaningful checks the worker can run and the supervisor can assess.

What happens when context reaches 150k?

At 150k context, a grind supervisor is already past its documented soft handover ceiling. The current skill sets that ceiling at 125k and an absolute hard stop at 200k. Workers have tier-specific soft ceilings. These are our workflow thresholds, not advertised model limits or a claim that every model fails at the same size.

A token is a piece of text used by the model. “150k context” concerns the text currently carried in that agent’s working context, including instructions and tool results. It doesn’t mean 150,000 words, 150,000 tool calls, or the lifetime usage of the whole multi-agent run.

The thresholds apply separately to each agent. A long run can use many fresh worker and supervisor contexts while keeping the warden small.

Grind context ceilings and the handover margin.
The current supervisor soft ceiling is 125k, after a 15k preparation margin. At 150k it is already past soft.

Start the handover before the window is full

The current rules begin avoiding large or open-ended work 15k before the soft ceiling. Small, bounded work can still fit in that margin. At the soft ceiling, finish the current item only if its remaining work is bounded, persist the state, and return. At 200k, persist and stop regardless.

Role or worker tier Avoid new large work from Soft ceiling Hard stop
Warden / supervisor 110k 125k 200k
Lightweight worker, labelled Haiku 55k 70k 200k
Mid-tier worker, labelled Sonnet 85k 100k 200k
Strong worker, labelled Opus/Fable 125k 140k 200k

The worker labels are the skill’s tier names. The Codex bridge treats provider-specific labels as cost/risk annotations rather than inventing unavailable model choices. The 110k preparation point follows the same soft-minus-15k rule as the worker values.

So the practical meaning of “above 150k, do handover” is right: that is already handover territory. But 150k isn’t the number stored as the supervisor’s trigger. Waiting until 200k to start writing the handoff defeats the margin.

These are documented procedures. This article doesn’t establish that a runtime counter automatically terminates and relaunches every agent at precisely these values. A larger advertised context window also doesn’t cancel the local workflow ceiling.

A fresh worker is cheaper than restarting the whole run

When a worker reaches its ceiling, it preserves the assigned artifact and exact next steps, then returns to the supervisor. The supervisor checks what exists and can give the remaining slice to a fresh worker in the same phase.

The approved scope, acceptance criteria, and delivery cycle survive. A context replacement doesn’t create a new feature or justify another sweep PR.

The supervisor itself may still have plenty of room. Rotating a worker therefore doesn’t require discarding the queue manager’s context.

A fresh supervisor starts from the saved state

Under a warden, the supervisor writes the ledgers and handoff before returning continue. The warden checks the return and starts cycle N+1 with a fresh supervisor context.

The new supervisor reads the handoff. It compares the recorded commit, next item, verifier result, live queue row, and in-flight PR state with what exists now. A mismatch becomes a reconciliation task: find out what changed before taking another action.

It doesn’t rebuild the plan from the original user prompt. It doesn’t reopen a completed criterion because the explanation was lost during the reset. Closed work stays closed unless new contradictory evidence is recorded.

The conversation changes while the engineering state stays anchored to persisted evidence.

Saving state and resuming grind in a fresh supervisor context.
The outgoing supervisor persists state. Its replacement reconciles that state before continuing the same goal.

What must survive the handover?

The handoff is a compact checkpoint, capped at roughly 150 lines or 2k tokens. It points to evidence instead of pasting entire logs or diffs. The durable ledgers retain the backlog, while the checkpoint carries enough state for a stranger to resume.

It includes the approved repositories and active phase, stable goal and acceptance criteria, next item, verified decisions, and exact blockers. For in-flight work it records branch and PR identity, CI and review state, last progress, and the next action.

Polling cursors matter too: when the last check happened and which bot comments or updates were already processed. Otherwise a fresh supervisor can spend its first cycle answering yesterday’s comments again.

The progress fingerprint connects the goal, current commit, next item, named verifier and result, advanced-row count, and compaction count. Ledger timestamps tell the next cycle whether its saved queue view needs refreshing. Escalation history prevents repeatedly paying for the same unresolved decision.

Keep evidence in its own files and record their paths. Each new supervisor pays to read the checkpoint again.

Compaction and handover have different rules

Compaction condenses an existing conversation so it can continue. A handover records the state and lets another context take over. Neither operation should erase the acceptance contract.

Under a warden, supervisors and workers don’t invoke compaction to stretch their windows. They persist and return. The warden may compact its own small control context, retaining its counters and handoff path.

Without a warden, the top-level supervisor is allowed one compaction: persist first, compact, reread the handoff, and reconcile it against observable state before acting. If compaction fails, leaves context too high, or makes the work unreconstructable, the workflow prefers a clean context.

Provider-native automatic compaction still needs the same reconciliation discipline. It can preserve conversational continuity, but it isn’t the auditable record of what was delivered.

A worked example: CI is still running

Suppose a supervisor reaches 150k while a PR’s required CI is progressing. This is an illustrative case, not a claim about a specific run.

It is already above its soft ceiling. It records the PR and head commit, observed CI state, last poll time, review evidence, and next action. After making its local work consistent and persisting the handoff, it returns continue.

The warden starts a fresh supervisor. That supervisor verifies the recorded head and current job state. If the same head is still running, it follows the recorded polling cadence or does useful dependency-safe work. It doesn’t rebuild the patch, reset the review history, or classify normal waiting as a hard blocker.

If the PR head changed, the successor checks which evidence became stale. A fresh context must not inherit a green badge without checking what that badge approved.

A reset must not reset the loop guard

Fresh context is useful only if the run remembers its lack of progress as well as its achievements.

The warden stops after two consecutive no-progress cycles on the same next item, or three consecutive no-progress cycles even if the item name changes. The supervisor also must change method, escalate, park, or stop before a third materially identical failed action. Rewording the plan doesn’t count.

The documented invocation allowance is 25 cycles, with a no-progress cycle counting double. Those controls are separate from context size and from the observational tool-call counter described later in this article.

At major milestones, the workflow calls for a restart drill: using only the saved records and observable repository state, can a fresh context identify the goal, settled criteria, forbidden shortcuts, next action, and verifier? If an answer still lives only in the old conversation, repair the handoff while that conversation is still available.

That’s the useful test of a handover. The next shift should be able to work without holding a seance.

How does a change reach a pull request?

A pull request, or PR, proposes a change for review before it enters a shared branch. Our PR workflow starts by identifying the repository’s delivery policy. Temporary worktrees isolate PR work, deterministic checks establish relevant evidence, and reviews must apply to the candidate that actually gets committed.

The superrepo uses signed direct commits to master. The packaging checkout uses signed direct commits to main. PR-bearing project work follows the temporary-worktree and remote-CI path. CI means continuous integration: automated jobs that build or check a proposed change.

For PR work, the canonical checkout is the control checkout. Changes happen in a temporary linked worktree based on the freshly fetched default branch. A linked worktree gives the task a separate working directory while sharing Git storage.

That keeps the long-lived checkout out of the middle of several unfinished jobs.

The reviewed production PR delivery workflow.
The eligible production PR path. Repository policy controls applicability; repairs renew the relevant review evidence.

Freeze the thing being reviewed

Before final review, the intended candidate is staged and checked. Staging selects the content intended for the next commit. Relevant tests and deterministic lint run first.

The workflow preserves coverage gaps. A missing analyzer hasn’t examined the code. The output must keep that absence visible instead of converting it into a clean result.

Reviewers receive bounded delivery context: intended behavior, relevant constraints, and verified linked issues, or a concrete reason no issue applies. Then the candidate must stay stable.

A review of yesterday’s tree doesn’t approve a function changed five minutes ago. The local process ties evidence to identifiers such as the staged tree and digests of the diff and context. A receipt establishes which artifact was reviewed; it doesn’t certify that the artifact contains no bugs.

Every finding needs an outcome

Reviewer output contains claims to investigate. A confirmed finding gets fixed or recorded in the appropriate ledger. An incorrect finding gets refuted with evidence. “Non-blocking” describes merge risk; it doesn’t make an observation disappear.

This prevents reviews becoming archaeological deposits of unresolved comments.

Repairs change the candidate. PR-agent must produce a receipt for the final tree. CodeRabbit’s repeat policy distinguishes a narrow repair of its own finding from a materially changed candidate. Material changes require renewed review under the applicable gates.

The repeat policy keeps review evidence tied to the change. A moving progress bar proves very little.

Green must belong to the current change

Remote CI must be substantive and green for the current PR head. A successful job for an earlier commit is stale evidence. A job that does almost nothing can also be green. The check’s meaning matters as much as its color.

Our nginx test harness article gives a concrete example of the underlying concern: checking behavior requires deliberately chosen tests. A process starting successfully doesn’t establish every property of its shutdown, reload, or resource handling.

Commits are signed, but a signature establishes a different property from a test: it ties the commit to a signing identity. Neither check substitutes for the other.

After merge, a clean control checkout already on its default branch can be fast-forwarded. A dirty or differently parked checkout is reported instead of forcibly “fixed.” Where the superrepo tracks the project as a submodule, its gitlink records the integrated project commit. That pointer also needs to catch up.

The restraint protects work the current task doesn’t own.

Why both CodeRabbit and PR-agent?

CodeRabbit and PR-agent are the standing local review gates for eligible production code delivery. Eligibility comes first. GitHub hosting alone is insufficient: documentation-only work, memory, repository housekeeping, operations, and infrastructure troubleshooting don’t acquire these gates merely because a script or Git checkout is involved.

This article is outside that code-delivery gate.

What CodeRabbit contributes

CodeRabbit supplies AI-assisted code review through several surfaces, including its CLI. The CLI supports uncommitted-change review and structured agent output. Its documentation distinguishes CLI review from PR review, which serves a different stage and context. CodeRabbit CLI reference

Our local workflow uses CodeRabbit before commit, after deterministic checks. GitHub app feedback can supply further observations but doesn’t replace the required local review.

The benefit is another opportunity to find a mistaken assumption or overlooked behavior. Its output still needs verification. We haven’t established a measured defect-reduction percentage for this setup; claiming that it catches a particular fraction of bugs would be invented.

Our PR-agent is a local harness

The name needs clarification. MyGuard’s PR-agent is a custom local review harness, distinct from the upstream project commonly called PR-Agent.

The local harness runs authenticated Claude Code and Codex CLIs. Its documentation says it doesn’t require another provider API key or copying their login stores. Its jobs include preparing the candidate, selecting the reviewer, supplying bounded context, validating structured results, and recording evidence about what was reviewed.

The blocking lenses include simplification, unit-test coverage, observable engineering problems described as AI slop, linked-issue rationale, and changes outside the intended scope. Warranted docstrings are advisory.

Here, “AI slop” means observable defects: unnecessary abstractions, redundant machinery, misleading text, or unrelated scope. It isn’t permission to reject code because of presumed authorship.

Author and reviewer take different routes

Author or task PR-agent’s documented route
Codex author Claude reviewer
Claude author Codex reviewer
Human or unknown author Deterministic selection based on the diff
High-risk or explicitly requested dual review Both providers independently

These provider choices live inside PR-agent. They aren’t additional standing gates.

A provider availability failure can permit a bounded fallback. An unfavorable finding doesn’t. Otherwise the loop becomes “keep asking until someone says yes,” which is less a quality system than an expensive permission slip.

Different model families can supply different perspectives. They can also share blind spots. Agreement isn’t a correctness proof. The local workflow keeps discovery independent: one reviewer’s candidate findings aren’t fed into the other reviewer’s discovery pass.

Give the reviewer a defined boundary

The inspected implementation builds a separate candidate snapshot and makes its source files read-only. Reviewer configuration restricts source writes and tool networking, while disposable scratch space supports builds, tests, and caches.

That establishes the implementation’s intended boundary. Proving complete isolation needs runtime verification as well; reading configuration isn’t enough. And restricting tool networking doesn’t make hosted-model review offline. Provider communication and arbitrary network access by tools are different questions.

Repository content stays untrusted. A changed instruction file is part of the candidate being examined, not permission for the reviewer to change its own rules. Suggested commands in review output also need scrutiny before execution.

The same separation between declared restrictions and tested behavior appears in our guide to Docker hardening. Controls protect different boundaries, and their configuration has to match the workload.

Why build astgrep-rules?

Once we’ve understood a recurring mistake, we should ask whether a deterministic rule can recognize it. That’s the purpose behind embracing myguard-labs/astgrep-rules: handcrafted structural checks with explicit fixtures and limitations. A reviewed detector can catch the same recognizable mistake on the next change.

Turning a recurring mistake into a tested ast-grep rule.
A rule is a maintained detector: test its positive cases, safe near misses, and integration behavior.

Text search and structural search see different things

Text search sees characters. Structural search works with the parsed shape of code: an abstract syntax tree, or AST. A rule can express relationships such as a particular call occurring inside a particular construct.

Depending on the matcher, words inside comments or strings can be excluded because they aren’t the relevant syntax node. Ast-grep’s rule language combines patterns and structural conditions.

That is useful for local conventions generic scanners may not know. Our nginx work, for example, has project-specific APIs and lifecycle expectations. A repeatable shape can be worth checking automatically even when the original explanation needed considerable reasoning.

Syntax is only part of program behavior. An AST match doesn’t automatically establish types, ownership, dataflow across functions, or whether a reported pattern causes an actual vulnerability. Questions beyond the rule’s reach still belong with other analyzers, tests, and review.

Test the detector’s boundary

A rule needs examples it should detect and examples it should leave alone. Ast-grep supports invalid and valid fixtures for those expectations. Its documentation distinguishes correct detection, correct silence, missed detection, and noise. Ast-grep rule testing

The local authoring workflow requires positive examples, safe near misses, and comment or string controls. Fixtures are parsed as inert snippets rather than executed.

Near misses reveal whether a rule recognizes the intended condition or something nearby. A detector that reports every call to an API might catch all the bad examples. It might also ruin everyone’s afternoon.

Some advisory rules intentionally match code that can be safe. That’s acceptable when the limitation is explicit and the message asks for the right review.

A passing run can still be useless

Did the runner discover the intended fixtures? Does the rule identifier match? Was changed expected output independently reviewed?

An empty run can pass. A snapshot can be regenerated to match a broken detector. The local workflow therefore checks inventory and discovery, requires snapshot review, and expects a behavior fix to fail with the old matcher and pass with the corrected matcher.

Integration needs equal care. A warning may produce output while leaving the process exit status successful. Promotion to a blocking condition must be deliberate and verified. The check doesn’t become a gate because someone wrote “mandatory” above its command.

This feedback loop also explains why a concrete defect story, such as the zstd module fixes, is useful beyond the patch: once the cause is understood, ask which part can be captured in a regression check. That might be a test, a structural rule, or a deeper analysis obligation.

Make a rule when it earns its maintenance

A finding needs a disposition. A new lint rule also needs a convincing maintenance case.

A good candidate repeats, has a recognizable local shape, and can be detected with manageable noise. A poor candidate depends on deep context the matcher can’t represent. Rejected experiments belong outside active rule discovery.

The aim is to move repeatable work into cheap, reviewable checks while leaving uncertain reasoning to tools and reviewers suited to it. No need to hire a philosopher every time somebody forgets the same guard clause.

What still needs attention?

The architecture has more moving parts than “agent writes code.” That gives it useful controls and more things that can drift. The following questions deserve an operational answer, rather than a reassuring box in a diagram.

Does the memory survive a rebuild?

Markdown, database files, retained source documents, configuration, and credentials have different recovery requirements. For the gitignored corpora, the useful test is a demonstrated restore: recover records and reconstruct their documents.

A documented backup command establishes a capability. It doesn’t establish when the last successful backup or restoration occurred. The backup schedule and restore evidence weren’t established for this article, so I won’t pretend they were.

Are stale records getting retired?

Search relevance doesn’t measure truth. Records need source dates, review routes, and a way to mark superseded decisions. Otherwise a well-written obsolete answer can outrank an awkward current one.

The query-widening mismatch found in our instructions is a small example. The maintenance system needs maintenance too.

Do the checks detect what we think they detect?

Coverage needs its own evidence: fixture discovery, negative controls, analyzer availability, correct repository scope, and confirmation that review receipts belong to the final artifact.

More checks can mean more assurance. They can also mean more empty jobs. Counting jobs doesn’t distinguish the two.

Are we measuring the benefits?

Expected benefits include less repeated investigation, more consistent handling of familiar defects, continuity across sessions, and additional review perspectives. No reliable measurements were established here for defect reduction, false-positive rates, total cost savings, or delivery speed.

Useful measurements would include accepted versus refuted reviewer findings, escaped regressions, rule noise, unsuccessful memory searches, and time spent waiting on gates. Track those before claiming the workflow is faster or safer by a particular percentage.

Can the workflow explain why it stopped?

Permissions, unavailable providers, stagnation, and resource limits need distinct outcomes. A provider outage isn’t a finding. A missing analyzer isn’t a clean scan. The stop reason should identify the operation and the recovery path.

In our current shipped runtime configuration, tool calls are counted for observation; there is no configured tool_calls limit. Other controls, including time, API/SSH, repeated-action, and no-progress limits, remain part of the documented runtime design. Counting how much work happened and deciding when work must stop are separate choices.

Start with the smallest useful system

You don’t need our entire arrangement to apply these ideas. Start with repository instructions, a small project memory index, and one task with checkable acceptance criteria. Keep changes isolated. Add meaningful tests and an independent review route.

Then watch what repeats.

If knowledge keeps getting lost, improve retrieval. If the same mistake returns, consider a tested rule. If work repeats after interruptions, improve persistent state and reconciliation. Let observed failures justify the machinery.

The apprentice can type very quickly. Keep the job board readable.

Frequently asked questions

Does persistent memory make the model learn permanently?

It makes information available to future sessions through retrieval. Saving a
Markdown file or SQLite record doesn’t, by itself, update the model’s trained
parameters.

Why keep both Markdown and SQLite?

Markdown is convenient for small, editable working records. SQLite supplies
structured storage and bounded search over durable corpora. Ordered chunks and
document digests support reconstruction checks.

Is this a vector database?

The inspected memory search uses SQLite FTS5 and BM25 text ranking. Its semantic
chunks follow meaningful document structure; that phrase doesn’t imply
embeddings.

Does using Claude and Codex guarantee independent review?

No. Separate discovery passes reduce one source of influence, and provider
diversity can offer another perspective. Shared blind spots remain possible.
Findings still require evidence.

Is MyGuard’s PR-agent the upstream PR-Agent product?

No. The MyGuard installation described here is a custom local harness around
Claude Code and Codex review processes, with its own routing and
candidate-evidence rules.

Can ast-grep replace tests or deeper analysis?

It detects structural patterns within its rules’ capabilities. It doesn’t
establish every runtime property or follow every dependency across a program.
Tests, compilers, deeper analyzers, and review retain distinct jobs.

Why not run every gate on every task?

Checks should match the task and its risk. Our CodeRabbit and PR-agent
eligibility policy excludes categories such as documentation-only work and
operations. Irrelevant gates consume resources without establishing useful
evidence about the change.

Does grind hand over at 150k tokens?

The current supervisor and warden soft ceiling is 125k, with a 200k hard stop.
Workers use 70k, 100k, or 140k soft ceilings by tier. At 150k, a supervisor is
already past its planned handover point. These are local workflow policies.

Does the warden review the worker’s code?

The warden checks lifecycle and reporting consistency. The supervisor verifies
artifacts and owns delivery; CodeRabbit and PR-agent provide the applicable
review gates. The warden doesn’t make project-level technical decisions.

What happens after the supervisor’s context is replaced?

The replacement reads the saved handoff and reconciles its goal, commit,
verifier, queue, and PR state with current evidence before continuing. The
existing acceptance criteria and delivery cycle survive the replacement.