Book a call
REFERENCE14mVERIFIED 2026-08-05 · CLAUDE CODE 2.1.221 · CODEX CLI 0.146.0 · GITHUB COPILOT CLI 1.0.78 · ANTIGRAVITY CLI 1.1.10 · KIMI CODE CLI 0.31.1

Anti-patterns we've watched teams adopt

Nine ways a team's agent setup goes wrong quietly: the bypass flag in the shared script, the instruction file cut off mid-word, the skill that still points at a decommissioned box.

None of these announce themselves

There are 9 of them on this sheet. We ran 3 ourselves while writing it, and 2 are worth showing up front:

  • AGENTS.md weighs 53,208 bytes, we used the Codex CLI 0.146.0 to ingest it, and it silently consumed exactly 32,768 of those bytes, the rest was lost (including the middle of a word in - Filler convention line that nobody has , without a single word on stderr)

  • The skill whose body runs ssh into a retired machine in March is still being injected into the prompt with its description, so it's available for the model to consider relevant

The limit itself is documented and configurable, and it did exactly what it's set to do. The part where it cuts mid-word and says nothing isn't documented anywhere we could find — and that second half is the shape of all 9

The DORA 2025 report based on almost 5,000 responses describes it as a tool property, not a team property: "AI doesn't fix a team; it amplifies what's already there"

That said, none of these originate with the agent. They're all existing team habits — in the form of scripts, or documentation, or review process — which now operate at agent speed before an audience that reads every word literally

How to read this

For each we've outlined its everyday appearance, the actual cost, and the minimum fix. The fixes are deliberately small, because a proposal to refactor the entire repo is sth nobody ever gets to.

If this is true of your teamThe entry
The bypass flag lives in a script, an alias or a CI jobThe bypass moved into the repo
Your instructions file only ever gets longerThe file nobody owns
Nobody can say who added the tenth MCP serverSomebody else's setup, pasted whole
Something in the config points at a system that's goneConfig that outlived its reason
A credential sits in a file you told everyone to cloneThe secret in the shared file
Leadership is quoting an adoption percentageCounting the tool instead of the work
Diffs got bigger and review times didn'tThe 900-line pull request
One person's laptop is the reference implementationOne person is the setup
There's a policy and there's what people actually runThe rule that moved it onto personal accounts

The bypass moved into the repo

Somebody got tired of approving the same command so they found a flag for it; the flag works so it found itself in a Makefile, a CI job, or the team's dotfiles — at which point it stopped being anybody's decision and became a local default.

All 6 harnesses ship with such a flag (we've compared vendor descriptions):

HarnessFlagThe vendor's own words
Claude Code--dangerously-skip-permissions"Bypass all permission checks. Recommended only for sandboxes with no internet access."
Codex CLI--dangerously-bypass-approvals-and-sandbox"EXTREMELY DANGEROUS. Intended solely for running in environments that are externally sandboxed"
GitHub Copilot CLI--allow-all-tools"Allow all tools to run automatically without confirmation; required for non-interactive mode"
Cursor-f, --force (--yolo)"Force allow commands unless explicitly denied"
Antigravity CLI--dangerously-skip-permissions"Auto-approve all tool permission requests without prompting"
Kimi Code CLI-y, --yolo"Auto-approve regular tool calls; the agent may still ask questions."

Only 2 of them actually reference a sandbox; the rest provide the same functionality without it.

It's worth noting that on the Copilot CLI this flag is not an optimisation, it's actually a requirement — if you want to use it non-interactively you must enable it and the built-in help examples show that: copilot -p "Fix the bug in main.js" --allow-all-tools

Even worse, the Copilot CLI also respects the COPILOT_ALLOW_ALL environment variable so you can enable it in a CI environment block and have no trace of it in any command line.

What it costs is not a vague agent misbehaviour; it's that consent has moved out of the moment. Whoever put the flag in the script had one job in mind, and it now applies to every job anyone runs, on machines holding production credentials, including for people who have no idea the flag is set.

The minimum fix is — allow the flag in the only sensible place, which is where you can contain its blast radius, which means within a credential-free container, CI runner, or the harness's own sandbox. But if you were to use it for example as an alias or a Makefile target on a laptop, it's the wrong mechanism — the real need is an allow-list, 20 minutes of work

The file nobody owns

Another example is AGENTS.md or CLAUDE.md; it starts with 15 genuine lines and then grows by one line per incident. The thing is — six people can write in it, nobody removes anything, and it's not treated as code so nobody ever reviews it.

The costs:

  • It's the default mechanism; you load it on every run

  • It's self-contradictory, as two people have written opposite rules eight months apart without reading each other

  • It silently crossed a line — Codex stops once the combined size of your memory files crosses project_doc_max_bytes, 32 KiB by default, which means it breaks the file in the middle of a word and doesn't say anything on stderr, so yesterday's addition was the first one to get lost

The minimum fix is:

  • Treat it like a piece of code, trace every line back to its context, as any line that can't be traced is one nobody will stand behind once it turns out they're wrong about

  • Anything that's not a fact needs to move to a skill, keeping the body on disk while only the description is injected into the prompt; this trade-off is described in detail elsewhere in the course

Somebody else's setup, pasted whole

Another example is a shared dotfiles repo, or an article about a good setup on a blog, or somebody's setup which was cloned by the entire team — 14 MCP servers, 9 subagents, a hooks file, and nobody can remember what the 10th server is for.

Just a side note here — whether an unused server consumes tokens per turn depends on the harness; Claude Code by default delays the definition of MCP tools, loading only names at session start, while Codex had it implemented at some point and later removed it; there's a lesson elsewhere in this course that measures the difference instead of guessing at it.

The most important thing is that nothing of this was scrutinised — the Anthropic's MCP documentation says it directly: "Verify you trust each server before connecting it. Servers that fetch external content can expose you to prompt injection risk"

Which leads us to the conclusion that this is exactly where such a check hasn't been performed — not because of negligence, but because nobody who could have performed it is part of your team.

The minimum fix is:

  • Nothing joins the shared config without an author's name and a sentence on what breaks if it goes

  • Even for already added entries you can do a similar audit in a few hours by asking yourself per entry: who added this and what would stop working; everything that raises two shrugs comes out (and git revert brings it back if you were wrong)

Config that outlived its reason

The opposite direction — three subagents left after a hackathon, an MCP server aiming for an internal service that got replaced, a skill for a deploy path nobody has used after the migration.

This is what people treat as inert but it's not: We've created a skill in a scratch project called legacy-release and described it like this: "Cut a release from the old deploy box. Use when the user asks to ship a release to the legacy cluster". Then we pointed its body to a machine that got decommissioned in March, and ran this through Codex — the name of the skill and its description appeared in the prompt during a run that wasn't even connected with releases.

The cost is that a description isn't documentation; it's what the model looks at to decide whether to run the body. So an unused skill is a live instruction aiming for a gone system, awaiting a perfectly phrased request — and it gets executed with confidence.

The minimum fix is:

  • Every quarter, list what's actually installed and remove everything that nobody can date

  • Standard tooling-wise — most harnesses have a listing subcommand; we've tried 6 of them and 2 don't provide it: Kimi Code CLI 0.31.1 and Antigravity CLI 1.1.10 (you need to ls the directories manually)

Also worth mentioning — this is one area where reverting is very safe; it's in git, you can always git revert

The secret in the shared file

Another example — the tool tells you to commit this file, which is correct. Then somebody adds an MCP server that requires a token and puts the token there.

We've created a scratch directory, installed Claude Code 2.1.221, created a project-scope MCP server with an inline API key variable:

BASH
claude mcp add --scope project demo-server -e API_KEY=sk-test-do-not-use-123 -- npx -y demo-mcp-server

and here it is — the key in plaintext in .mcp.json, which is the file that the documentation tells you to commit so the entire team has the same MCP tools and services. No warning appeared, it did exactly what we told it to.

It's not even a matter of judgement; removing this line doesn't remove it from the history, and the history is on every machine that ever cloned the repo, so rotation is what you need to do here.

The minimum fix is — use interpolation which is supported and documented by the vendor for this very scenario — a placeholder referring to an environment variable defined in the committed file, "API_KEY": "${DEMO_TOKEN}", with its value stored in the environment

It's also worth noting that Claude Code's MCP listing — claude mcp list — highlights the missing environment variable by name (Missing environment variables: DEMO_TOKEN) instead of showing that the server doesn't work

If you really can't use interpolation, you can put the values in a personal scope, which is called local scope in the Claude Code documentation — for example they say to use it for credentials that you'd rather not keep in version control. All 5 other harnesses have their own configuration files under your home directory

Counting the tool instead of the work

Another example — seats, percentage of pull requests involving an agent, number of lines accepted, and then "AI usage" appearing during a performance discussion.

The thing is — this figure is real, it's just not about anything that matters: METR's 2025 randomised controlled trial — 16 experienced developers worked on 246 issues in their own repositories; they were allowed to use AI tools and turned out to be 19% slower. They predicted a 24% speedup and after the experiment estimated they'd been sped up by 20%.

In other words — the thing to carry forward isn't "AI makes people slower", it's that when self-report was pitted against a stopwatch, they pointed in opposite directions (and the wrong one was the one doing the work)

The minimum fix is — track what you already cared about before: DORA's 2025 data points — AI adoption correlated positively with throughput and product performance, negatively with delivery stability. If you're only looking at the first metric, you'll be happy until you're not

That being said, we should probably point it out that METR have already acknowledged that these results are not fully representative (they've found a few selection effects), and that they think developers are likely more sped up now than that early-2025 number suggests; they're redesigning the study

The 900-line pull request

Another example — the volume of output goes up but the time available for review doesn't, and there's this line: "implement the caching layer". The diff is 900 lines and the author had a quick look at it.

Stack Overflow's 2025 survey says that the top frustration, at 66%, is "AI solutions that are almost right, but not quite", and 45% picked "Debugging AI-generated code is more time-consuming". Almost-correct is the most expensive category as it survives a skim, and a skim is what 900 lines get.

DORA says the general version of it without naming review: "Without robust control systems, like strong automated testing, mature version control practices, and fast feedback loops, an increase in change volume leads to instability." Review is one of those loops, and the most challenging one to scale.

The minimum fix is:

  • A size limit that forces you to split it, as what's being protected here is the attention of the reviewer, which is a finite resource

  • A PR template question: what did you check? (not what the agent says, what you actually ran)

It might look like red tape until the first person can't answer it for themselves and splits their own PR

One person is the setup

Another example — it works because of one person; they have useful skills in their home directory, handy hooks that were never committed, or a piece of reasoning behind a certain rule. The rest run half of it from their home directories and think they must have misconfigured sth.

The cost is clear — the bus factor (and the fact that nobody else can improve it as you can't submit a PR against somebody's home directory, so it can only get better in their spare time)

The minimum fix is — create an empty directory and clone the repo into it as if you were a new joiner; see what the agent knows. What it can't answer is what lives on that laptop, and that list is the work. Do it before they go on holiday, not during.

There's also a variant we should probably mention: "we're a [tool] shop". This looks like standardisation, but is actually the same problem at a higher level; some things are portable:

  • Four of the 6 harnesses read .agents/skills/

  • Two of them use .mcp.json

But:

  • Permission rules are defined using a single vendor's format and can't be moved

  • Hooks work only in their native environment

  • Sandbox configurations are expressed using one vendor's syntax

Which means that if somebody joins on a different tool, they'll have your skills but none of your controls; what you share is the files, not the tool.

The rule that moved it onto personal accounts

The opposite direction — a policy banning agents, or allowing only one, or excluding a repo. And then people who were supposed to use one use it on their personal accounts, in their own editors, with code pasted somewhere you can't see.

Again, we won't give any numbers (as the ones that are being shared come from surveys conducted by vendors and we couldn't verify them), but the mechanism is simple: a rule you can't detect selects for people who don't tell you.

What it means is that the visible version could have been reviewed, but the hidden one can't — and it doesn't inherit anything you've created (no repo instructions, no permission rules, no hooks, just your source in whatever was handy)

The minimum fix is — make the most sensible path of least resistance:

  • The same tool, already set up, already permitted on the repos where it's allowed

  • And then limit the prohibition to what actually needs one, which is almost always a particular repository or type of data, not an entire category of tools

IN YOUR HARNESS

Finding these in Claude Code

Two commands you can run outside a session, one you run inside it, and a grep. The two claude CLI subcommands: one lists servers along with a config-diagnostics section, the other displays a particular server's scope, status and the env it will pass.

BASH
claude mcp list          # includes a config-diagnostics block
claude mcp get <name>    # scope, status, and the env it will pass

Using the first subcommand is usually the most valuable move — it health-checks what's connected and prints a diagnostics section underneath, so you can see whether things work as intended. We found for example that running it on our end showed:

[Warning] [demo-server] mcpServers.demo-server: Missing environment variables: DEMO_TOKEN

If you were to run it in your case you would see that all servers defined in a checked-in .mcp.json file, but that nobody approved yet appear there with a status of ⏸ Pending approval (run claude to approve). Before you blame a colleague for having a messed-up environment, make sure to check this.

Since v2.1.196:

  • A freshly cloned repo can't approve its own servers

  • enableAllProjectMcpServers property defined in .claude/settings.json gets ignored if it's placed under an untrusted folder

That's because the configuration that is version-controlled isn't the same as the one that is in effect.

In terms of the in-session command, /context answers where the instruction file is located, but at the cost of a turn. The documentation describes it as a live per-category breakdown with optimisation ideas, including which CLAUDE.md and auto memory files have been loaded — this is better than what you assume you did or asking Claude directly.

Also, as regards the grep part, there are 3 flags (that might be easy to mix) and one value that's worth it to grep for:

  • --dangerously-skip-permissions to actually enable the bypass

  • --allow-dangerously-skip-permissions which just makes it possible, with a note in the help text that it's not enabled by default — more reasonable to use if you were to create a wrapper (which might be even not necessary)

  • bypassPermissions — this is an option for another flag: --permission-mode, so needs its own grep as it doesn't contain any "red flag" word in itself

We can also see that there's a --max-budget-usd parameter which you can set to cap the spending for --print. We grepped all 6 harnesses' help output for a spend cap and this is the only one that names one.

So for example if you were to create an unattended workflow you could set up a simple spend ceiling for it that's available nowhere else just by using this single-line parameter.

Finding these in Codex CLI

The most powerful command from the group that comes with Codex CLI is codex debug prompt-input which prints the entire payload that gets sent to the LLM. It's a JSON and it contains all the information the model sees without actually sending an API request.

BASH
codex debug prompt-input "hi" | python3 -m json.tool | less

That way you can see a lot of things, for example:

  • If you are wondering how to resolve every instruction- and skill-related checklist item — this command is your friend.

    • It shows you all the skills (with their names, descriptions and resolved paths) so if you have any stale ones — you can see them here. We've created a legacy-release skill pointing to an old machine, which was still referenced in the prompt when we asked it about something totally different. So if you are wondering if you have any abandoned skills — just run this command and check, yours will be listed too.

    • The only thing that's not shown is MCP tool definitions (which are required for the overloaded config checklist item), so in such scenario you need to run codex mcp list instead.

  • If you feel like the prompt is getting cut — you can use this command to find out if it's a truncation. The thing is that once the sum of the memory files sizes reaches project_doc_max_bytes (which defaults to 32KiB) — Codex doesn't even try to load them anymore.

Let's take a look at couple of examples:

Single file: We've created a file called AGENTS.md in the root of the project, put some text in it and added markers both at the beginning and at the end of the file. The file weighs 53,208B. The top marker is present, the bottom marker is not, and the prompt got cut in the middle of a word. But there's no output in stderr.

Just to be clear — "combined" means exactly that, so the size of 32KiB is a limit for all the files together (as opposed to what the docs say).

So we've created another file, 19,753B heavy, and put it in the root of the project. And then another one, 19,751B heavy, in a subdirectory. The first file is OK, but the second one got truncated after 13,015B. Which makes 32,768B in total.

So the budget for AGENTS.md is not per-file but shared between all of them. If you were wondering what the absolute limit is — it's 32KiB, but if you have a monorepo with separate packages and an instruction file per package then you're actually closer to it than this math would suggest.

So if you feel like you're close to this limit — make sure to check if your AGENTS.md files were loaded by grepping the command's output for some phrase from the very end of one of them. For example:

BASH
codex debug prompt-input "hi" | grep -c "phrase from the bottom of AGENTS.md"

We've also mentioned that there are more commands worth using:

  • codex doctor to check if the configuration, authentication and runtime are set up correctly

  • codex mcp list to see the servers

But there are actually 2 flags that are worth looking for in the repository as well. They're both dangerous but also very powerful:

  • --dangerously-bypass-approvals-and-sandbox. Its own description is "EXTREMELY DANGEROUS. Intended solely for running in environments that are externally sandboxed"

  • --dangerously-bypass-hook-trust. It's less obvious one, but still — it runs the hooks that you've committed without trust

Why is it important? Because hook trust is one of two things standing between you cloning a repository and running its code on your colleague's machine. The other thing is project trust which btw per the same docs defines how Codex treats every project-scoped layer under .codex — the local config, hooks, rules and skills.

Finding these in GitHub Copilot CLI

To make sure we include everything, run the two listings first; this harness automatically detects skills from the most directories out of all the six we examined (5), so a lot of clutter accumulates here.

BASH
copilot skill list
copilot mcp list

It's looking for skills in:

  • .github/skills/

  • .agents/skills/

  • .claude/skills/

  • ~/.copilot/skills/

  • ~/.agents/skills/

and it also finds plugins, as well as any directory you define in your configuration.

Given there are three separate paths for skills in this harness — GitHub's, vendor-neutral one, and Anthropic's — you can still end up with a leftover skill even after you've stopped using some of these; usually people mean they removed everything from just one of the directories.

Similarly to other harnesses, the MCP configuration is loaded from ~/.copilot/mcp-config.json, .mcp.json in your workspace (or .github/mcp.json for that matter), and plugins.

What's more important though, the last point is about this harness a little different compared to others: we're not talking here about --allow-all-tools being some sort of secret you can stumble upon. As visible in its docs, it's actually required in non-interactive mode.

This harness comes with examples, and they all use this flag as the standard headless invocation, for example:

BASH
copilot -p "Fix the bug in main.js" --allow-all-tools

So it should be present in CI for this harness (which is totally reasonable given it's CI; the crucial thing is to make sure it hasn't been used anywhere else).

We can find it using grep, looking for these variations:

  • --allow-all

  • --allow-all-paths

  • --yolo

and also for the environment variable:

  • COPILOT_ALLOW_ALL

That env variable is the one that matters, because it means the bypass can be set in an env block and never appear in a command line anyone reviews.

Lastly, regarding the config, the repo-level .github/copilot/settings.json ignores everything but a fixed set of keys. As per the docs, anything that doesn't belong to this set is dropped without warning, including keys that are valid for user-level configuration. So if you were to define a policy under such a key in your team, it'd be as good as not having it.

Finding these in Cursor

In the context of Cursor — there are commands for listing the configured MCP servers with statuses and for listing all the tools registered by a particular server

BASH
agent mcp list                        # servers and their status
agent mcp list-tools <identifier>     # what one server actually contributes

If you face the problem of having too many tools in the config, you can list all the tools that are registered in a particular server; as the server's name doesn't say anything about its contents, it's much more informative to have a number of registered tools and their names rather than the name of the server — often this number is greater than what the person who configured it assumed

The other way round, there's actually a trap that's specific to this harness — the rule that is never being used. As the rules from .cursor/rules/ are being loaded depending on their frontmatter:

  • alwaysApply: true — they're always loaded, no conditions

  • globs — they're being deferred until an access to a matching file happens

  • if there's a description and neither of these options is set, it's up to the model whether it loads it

Anyway, that means that you can have a team standard in place, documented in the repo, and it can actually be there for months and never appear in any session. That's not being displayed as an error, but instead, a teammate says that the agent is ignoring the conventions of their team. So before rewriting the rule's body, always check its frontmatter — usually, the body was fine and it's a matter of how it's loaded

For the bypass entry, there are three flags worth searching your scripts for:

  • -f / --force (or --yolo, which is an alias) — this flag makes all commands available by default (unless they're explicitly denied)

  • --trust — trusting the workspace without asking

  • --approve-mcps — automatically approving every MCP server

Those last two together in a script mean a cloned repo's tool configuration goes live with 0 human interactions.

Finally, -p / --print is also worth looking at as the docs say that it supports calling every tool, write and shell included, so theoretically, using it, you could make a headless run more powerful than you might think by using it in a task in your workflow

Finding these in Antigravity CLI

To examine the setup of this harness from the Antigravity CLI, we can use a few commands to list installed agent profiles, imported plugins or available models (the plugin subcommand without an argument outputs its usage text).

BASH
agy agents        # the agent profiles that are actually installed
agy plugin list   # imported plugins — the bare `agy plugin` just prints usage
agy models

There's also a flag called --dangerously-skip-permissions, named exactly like the one in Claude Code; its whole description here is "Auto-approve all tool permission requests without prompting" — no sandbox caveat, no all-caps warning, nothing about internet access. It's narrower than the equivalent in Codex (which Codex labels EXTREMELY DANGEROUS, as it drops both approvals and sandboxing); here the sandbox is a separate switch, so you can auto-approve everything and leave the sandbox exactly where it was, which is off. Which is the point — if your team's habits were formed on this harness, the flag will feel more ordinary than it is.

There's another flag called --sandbox which says "Run in a sandbox with terminal restrictions enabled". As we can see in the configuration section of the Antigravity docs, its corresponding setting has a default value of false. So if you use the bypass flag anywhere, make sure it's accompanied by the sandbox one.

The last thing to note is that the settings this CLI documents are per user, not per project, which means the division is more prominent here. That means that any commit of the instructions file or a skill will share the knowledge with your team but not the permission settings as everyone has their own toolPermission and separate allow and deny lists; you either need to examine everybody's configuration or assume that the configuration only concerns the memory file and skills.

The workspace skills are kept in .agents/skills/, and if you still have a .gemini/skills/ directory from some previous setup it isn't the path it looks in (although it might seem like a clean sweep).

Finding these in Kimi Code CLI

Start with the built-in config validation command, described as "validating Kimi Code configuration files":

BASH
kimi doctor      # "Validate Kimi Code configuration files."

if you run it, make sure to inspect its output (not only the last line), you'll see that the files it validates all sit under your home directory — hence the machine scope. That's how Kimi Code works generally, so that's why the other 2 points are as follows:

Enforcement — the hooks are defined in the config.toml file in your home directory, under the [[hooks]] key (which is an array). It's a user-level configuration so there's no project-level counterpart documented. The CLI provides a project-level config file at <project-root>/.kimi-code/local.toml but doesn't document hooks as sth that it holds, so the single-maintainer-owns-the-config pattern is basically the built-in one in terms of hooks — there's a gate on your machine, and no (documented) way to commit it. Just accept it and keep the knowledge in the repository; if you need any gates, set them up in CI and stop expecting that anything will be carried from machines by the intermediate layer

Bypass — there are actually 2 different flags here with a semantic difference. The -y / --yolo flag is about making regular tool calls more "yolish" — it automatically approves them, but it still might prompt you if you use it. The --auto flag on the other hand is about the CLI being fully autonomous, not asking any questions. So what happens in practice is that people often create a script that uses --yolo and still get stuck at some point, so they append --auto later but without realising it's a separate thing. So look for both

Graveyard — the least tool support for this one, 0.31.1 doesn't have any skill or mcp subcommands, so there's no way to list them using it. If you run kimi --help, you'll see it lists 10 commands, none of which are about listing anything. So you need to look in 4 locations:

  • .kimi-code/skills/

  • .agents/skills/ (both in the project and under your home directory)

  • and wherever extra_skill_dirs points in config.toml (which is path specified in a config file, not a folder found directly)

Make sure kimi --version reports 0.31.x first — there's another tool called kimi-cli that the kimi migrate command imports from which is a different program. All of the above tested with 0.31.1.

The half-hour that finds most of this

This one is not a programme, but a sit-down; if you run the checks provided by your harness against your agent config you'll find two or three of these. They'll be boring — an MCP server pointing to a dead endpoint, a rule left behind by somebody who no longer works there, a flag added to a Makefile one afternoon 18 months ago — and this is exactly why you haven't found them.

What you need to do instead is treat agent config like everything else in the repo — not a policy but an expectation that somebody reads it before it gets merged

What we'd not bother with

The last section is things that look like fixes, but aren't:

  • An AI usage policy document — read once. The same amount of work spent on committed instructions for the repo will be read on every turn by the thing that does the work

  • A dashboard showing agent metrics — a way to get adoption figures (which is the anti-pattern we've talked about, with better graphics). Track delivery stability instead, you probably already do

  • Standardising on a single harness — not possible unless you own either device management or the billing relationship. The best you can do with this effort is committing the right filenames; standardise on those files

  • Banning the bypass flag — nobody will enforce it. Limit what it can reach and it doesn't matter anymore

j / k to move between lessons