Best practices

Syntic Code does its best work when it knows what you want, has a way to check its own results, and has room in its context window to think. Most of the habits on this page come down to one of those three things.

Give it a way to check its work

The single biggest improvement you can make: tell the agent how to prove it is done.

WeakStrong
”Fix the login bug.""Logging in with an expired token returns 500. Write a test that shows it, fix it, and run npm test -- auth."
"Make the table look better.""Here is a screenshot of the design (Ctrl+V). Match it, then describe any differences you could not resolve."
"Speed up the importer.""The importer takes 40 s on fixtures/big.csv. Get it under 10 s and show timings before and after.”

Put the commands it should use in SYNTIC.md (build, test, lint, typecheck) so every session knows them. Syntic Code also checks its own claims at the end of a turn and reports what it verified (Automatic checks). /verify asks it to run the software and show the latest change working.

Look, plan, then build

Jumping straight to code works for small changes. For anything that touches several files, split the work:

  1. Look. Ask it to read the relevant code and explain how things work today. Stay in plan mode (Shift+Tab until the footer says plan) so nothing changes yet.
  2. Plan. Ask for a concrete plan: files to change, the approach, the tests. Push back on anything you dislike. For a large change, /ultraplan <task> writes a longer plan to a file.
  3. Build. Approve the plan and let it work. Ask it to run the tests as it goes.
  4. Ship. /commit or /commit-push-pr once you are happy.

Skip the planning for a one-line fix. Use it whenever you could not describe the change in one sentence.

Be specific

The agent cannot read your mind, but it can read anything you point it at.

  • Name the place. @src/auth/session.ts puts the file straight into the conversation; “the session code” sends it searching.
  • Name the pattern. “Follow the pattern in ProfileCard.tsx” beats a paragraph of style rules.
  • Name the limits. “Do not change the public API.” “No new dependencies.” “Leave the test as is.”
  • Share what you see. Paste error output, attach a screenshot, or pipe a file in: cat build.log | syntic -p "why did this fail?".

Set up the project once

Write a good SYNTIC.md

Run /init in a new project and edit what it writes. Keep the file short; it loads into every request. Good things to include:

  • how to build, test, lint and run the app;
  • conventions the code does not make obvious (“money is integer cents”);
  • traps (“the legacy/ folder is generated, never edit it”);
  • how you like to work (“ask before adding a dependency”).

Leave out what the agent can see by reading the code. Move area-specific detail into .syntic/rules/ files with a paths: filter so it only loads when relevant. When you correct the same thing twice, add it to memory: start a message with # to append a line. See Memory.

Approve less by hand

If you keep allowing the same safe command, make it a rule instead:

{
  "permissions": {
    "allow": ["Bash(npm test:*)", "Bash(npm run lint)", "Edit(src/**)"]
  }
}

/fewer-permission-prompts reads your recent sessions and proposes rules for the commands you approve most. For longer unattended work, auto mode lets a reviewer approve routine actions while still stopping risky ones (Permission modes).

Use command-line tools

The agent is fluent with the tools on your PATH. A gh, glab, kubectl or database client lets it read pull requests, logs and data directly. Mention them in SYNTIC.md if they are not obvious.

Connect what it cannot reach

NeedAdd
Data in another system (tickets, docs, a database)An MCP server.
Something that must happen every time (formatting, a block on edits to migrations/)A hook.
A repeatable procedure (“how we cut a release”)A skill.
A focused specialist (security reviewer, test writer)A custom subagent.
All of the above for many repositoriesA plugin.

Talk to it well

  • Ask questions you would ask a senior colleague. “Why does this retry three times?” “What would break if I removed this flag?” Exploring the code together is cheap and often faster than reading it yourself.
  • Let it interview you. For a fuzzy task, say: “Ask me what you need to know before you start, one question at a time.” It will surface the decisions you had not made yet.
  • Correct course early. Press Esc the moment it heads the wrong way, then say what to change. An interrupted turn costs seconds; a wrong turn that runs for ten minutes costs ten minutes and fills the context.
  • Say why. “Keep the old endpoint, the billing service still calls it” lets it make good calls in situations you did not foresee.

Look after the session

Keep the context clean

Long sessions that wander between topics give worse answers. The context window fills with unrelated file contents and the agent loses focus.

  • /clear when you switch to an unrelated task. The old session stays resumable.
  • /compact when a long task is not finished yet, to fold old turns into a summary before the window fills up.
  • /context shows what is taking space.
  • /btw <question> answers a side question without adding it to the conversation.

See The context window.

Let subagents do the digging

“Use a subagent to find every place we build SQL by string concatenation” keeps dozens of file reads out of your main conversation. The subagent reads, the main session gets a short report. See Subagents.

Undo freely

Every edit is checkpointed. Esc twice on an empty prompt (or /rewind) restores an earlier point in the conversation, the files, or both. That makes it safe to say “try it the other way” and roll back if it was worse. See Checkpointing.

Come back later

syntic -c continues the latest session in this folder, /resume picks an older one, and /rename gives a session a name you will recognize. See Sessions and resume.

Scale up

Script it

syntic -p runs one task and prints the result, which makes it a building block for scripts and CI:

# one-off question
syntic -p "which endpoints have no auth check?"
 
# structured output for another tool
syntic -p "list the public functions in src/lib.rs" --output-format json | jq -r .result
 
# stream events as they happen
syntic -p "run the test suite and fix failures" --output-format stream-json --verbose

See Scripting and CI.

Run several sessions

  • syntic -w <name> opens a session in its own git worktree, so two sessions can edit the same repository without colliding (Worktrees).
  • syntic --bg "<task>" runs a job in the background; syntic agents shows every background run (The agents view).
  • /batch <task> splits a large change across parallel agents, each in its own worktree.

Add a second opinion

Have one agent write and another review. /code-review, /ultrareview and /security-review run reviews in a separate context, so the reviewer is not anchored by the author’s reasoning (Code review).

Common traps

TrapBetter
One session for everything all dayOne task per session; /clear between tasks.
Correcting the same mistake every sessionWrite it into SYNTIC.md once.
A SYNTIC.md that grows to hundreds of linesTrim it; move detail into path-scoped rules or skills.
Accepting work you have not checkedAsk for a test or a demo before you trust it.
Asking it to “investigate” with no endSet a scope: “look in services/billing only, report in five bullets”.
Fixing the same thing over and over in one long thread/clear and restate the task with what you learned. A fresh context with a better prompt beats a long one full of failed attempts.

Build your instinct

None of these rules is absolute. A quick question needs no plan, and an exploratory spike needs no tests. Watch what works: when a session goes well, notice what you gave it. When it goes badly, ask whether the agent lacked context, lacked a way to check, or ran out of room. The fix is almost always one of the three.