Module 2 · Chapter 2: Setting up the workspace
Project instructions and first permissions
In short
An instruction file tells an agent what it should do; permission rules decide what it can do. Write short, checkable instructions, then start permissions narrow: allow, ask, deny.
After this lesson you can
- Write a short project instruction file whose rules can be checked
- Draft first permission rules in three levels: allow, ask, deny
Terms in this lesson
Understand
Every agent session starts with no memory of your project. So that it need not be told the same things every time, most agent tools read a project instruction file at the start of a session. Its content becomes part of the system prompt: rules that apply to every request in that project.
A good instruction file is short and checkable. Compare "write clean code" with "run the relevant tests and the type check before saying you are done". The first cannot be checked; the second can. Write rules whose violation would be visible.
The most useful content is usually:
- How to check work: the test command, the type check, the build, and when each is required.
- How the team works: one branch per task, commit messages, which files belong to whom.
- Clear prohibitions: never add every file to a commit at once, never touch the database on the default port, never merge to the main branch.
- What is easy to get wrong in this project: lessons from earlier incidents, one line per lesson.
What not to write: long explanations of the programming language, motivation, or things the agent can read from the code itself. Every line in the instruction file is reread in every session and costs context, so trim what is not used.
Instructions tell the agent what it should do. Permission rules decide what it can do. The difference matters: a model can misread or be misled by instructions, but permission rules are enforced by the app, outside the model.
Draft first permission rules in three levels:
- Allow without asking: cheap, safe actions, such as reading project files or running specific test commands. This is an allowlist in the true sense: closed, only what is named.
- Ask first: actions that change something outside the workspace, such as pushing changes to a shared repository or installing a new package.
- Deny: actions that must not happen in this session at all, such as reading secret files or deleting folders.
Start narrow. If the agent asks too often about actions that turn out to be safe, move those actions to the allow list one by one, after you have seen them. Do not start from "allow everything" and hope to patch later. Remember too that permission rules matter as much as the instruction file: both live in the repository, are reviewed like code and are changed with a written reason.
A step specific to Anthropic: check the latest version.
As a worked example, this is how it looks in Claude Code. The project instruction file is called CLAUDE.md at the project root and is read at session start. Permission rules live in .claude/settings.json (shared with the team through the repository) or in the personal local settings file in the same folder (only for you, for one project), under the permissions key with allow, ask and deny lists:
{
"permissions": {
"allow": ["Bash(npm run lint)", "Bash(npm run test *)"],
"ask": ["Bash(git push *)"],
"deny": ["Read(./.env)", "Read(./.env.*)"]
}
}deny and ask rules in project files apply at once; allow rules from a committed file apply only after each team member trusts the folder. The /status command shows which settings files were read. A step specific to Anthropic; check the latest version in its documentation, because setting names and behaviour can change.
Before
The prompt
Please follow best practice while working on this project. Work neatly and carefully, do not break anything, and always make sure quality is high.
What came back
Weak output: Understood, I will work neatly and carefully and keep quality high.
After
The prompt
Project rules (read every session): 1. One branch and one working folder per task. 2. Before saying done: run the relevant tests, the type check and the build; paste their output. 3. Commit only files you changed, naming each path; never add every file at once. 4. Do not merge to the main branch, push to the shared repository or release; write the proposal and stop. 5. Database tests only in a throwaway container with the address set explicitly.
What came back
Task done on its own branch. Output: relevant tests pass, type check clean, build succeeded (output attached). The commit holds two files named by path. A proposal to merge into the main branch is written; waiting for your decision.
What changed
- The first instruction sounds good but none of it can be checked; the agent can only answer with a promise.
- The second holds five rules whose violation shows in the trace and in the commit.
- Rules 3 and 4 are lessons from real incidents, not theory.
Common mistake
- Mistake
- Allowing every command from the start so the agent "stops asking", then hoping instructions are enough to prevent dangerous things.
- Why it hurts
- Instructions are read by the model; the model can misread or be misled by text in a file it opens. Without permission rules, one misreading becomes an action at once, including irreversible ones like pushing to a shared repository.
- Do this instead
- Start with a narrow allow list, ask for actions that change things outside the workspace, and deny secrets and deletions. Loosen one at a time after seeing the action is safe.
Try
Sorting card
Put these actions at the right permission level for a developer agent in your project.
Installing a new package from the internet
Reading the file that holds secret keys
Pushing a branch to the shared repository
Reading code files in the project
Deleting a folder recursively
Running the project's test command
6 cards left
Which line most deserves a place in the project instruction file?
Prompt: draft a project instruction file
Works with any AI assistant.
Your prompt
Goal: I need a draft project instruction file for a developer agent in the ‹proyek› project. Reader: the AI agent that reads it at the start of every session, and the teammate who reviews it. Material: our check commands: ‹perintah›. Past incidents: ‹kejadian›. Limits: at most 15 rules; every rule must be checkable from the trace or the commit; no general explanations. Shape: a numbered list, one line per rule, grouped: checking work, how we work, prohibitions. Check: mark any rule you think cannot be checked, and propose a version that can.
Take home
Instruction file and first permissions
- Every instruction rule can be checked from the trace or the commit
- The file is short; what is unused I trim
- The allow list is narrow and closed
- Secrets and deletions are on the deny list
- Instructions and permission rules are reviewed like code
What went wrong for us
A symlink that got committed
- Context
- In one repository, the dependency folder was a symlink so several working copies could share one install.
- What happened
- A command that adds every change at once also committed that symlink. The image build failed because of it, and the container recreate silently kept running the old image.
- Impact
- A release we thought was live was not, until we checked the running version.
- Root cause
- An "add everything" command does not tell work files from environment files, and the deploy step did not check which image was really running.
- What we did
- The symlink was removed from the commit, the image rebuilt, and we confirmed the container ran the new image.
- The guard we keep now
- We add files by explicit path, read the git status before every commit, and check the running image version after a deploy.
The lessonCommit only what you know you changed, and check what is really running.
Sources
- Coding agent docs: settings (accessed 26 October 2026)
- Coding agent docs: configure permissions (accessed 26 October 2026)
