Welcome to the final chapter of the Permissions tutorial!
In the previous chapter, Permission Explainer & Debugging, we learned how to analyze commands and understand why the system made a specific decision.
However, up until now, our system has suffered from Amnesia. If you approve npm test today, and then restart the application, the system forgets you approved it. Tomorrow, it will ask you again. This leads to "Click Fatigue."
This chapter introduces the Rule Persistence Manager. This component allows users to turn a one-time "Yes" into a permanent "Always Allow," and decides where that memory should be stored.
Imagine entering a high-security office building.
In our project, the Rule Persistence Manager is the machine that prints these badges. It takes a temporary approval and writes it down permanently.
git status, npm start). Asking for permission every time makes the AI unusable.
The Scenario:
You are working on a web app. You want the AI to be able to run npm run test anytime it wants, without interrupting you.
The Solution:
npm run test.PermissionRuleInput)
This is the form where the user defines the scope of the badge. It might be an exact match (npm test) or a wildcard pattern (npm run *).
Rules can be stored in different places:
ls or git).
This is the logic that actually writes the JSON to the settings file (.claude/settings.json or .vscode/settings.json).
First, we need to let the user type in what they want to allow. We use the component PermissionRuleInput.
It validates the text and converts it into a logical "Rule Value".
// PermissionRuleInput.tsx (Simplified)
const handleSubmit = (value: string) => {
const trimmed = value.trim();
// Convert string "npm test" into a Rule Object
const ruleValue = permissionRuleValueFromString(trimmed);
// Pass it up to the parent component
onSubmit(ruleValue, ruleBehavior);
};
permissionRuleValueFromString: This helper function parses the text. If you type npm run *, it creates an object saying "Allow tool BashTool where command starts with npm run ".
Once the user types a rule, we show them the Add Permission Rules dialog. This component (AddPermissionRules.tsx) asks the user where to store the rule.
We present options based on available configuration files.
// AddPermissionRules.tsx (Simplified)
switch (saveDestination) {
case 'localSettings':
return {
label: 'Project settings (local)',
description: 'Saved in .vscode/settings.json',
value: saveDestination
};
// ... cases for global user settings
}
This logic ensures the user knows exactly where the permission file is located physically on their disk.
Here is what happens when a user decides to create a permanent rule.
When the user makes the final selection, the AddPermissionRules component triggers the save. It does two things: updates the current running app, and writes to the disk.
// AddPermissionRules.tsx (Logic inside onSelect)
const destination = selectedValue as EditableSettingSource;
// 1. Save to the physical file system (The Disk)
persistPermissionUpdate({
type: "addRules",
rules: ruleValues,
destination
});
// 2. Update the live application state (The Memory)
setToolPermissionContext(updatedContext);
persistPermissionUpdate: This function interacts with the File Operations Subsystem logic to write the JSON file safely.setToolPermissionContext: This updates the Central Request Dispatcher immediately, so the user doesn't have to restart the app for the rule to take effect.
Finally, when a user lists their rules, we need to convert the technical data back into English. We use PermissionRuleDescription.
// PermissionRuleDescription.tsx
if (ruleValue.ruleContent.endsWith(":*")) {
// Example: "npm:*"
return (
<Text>
Any Bash command starting with <Text bold>{prefix}</Text>
</Text>
);
}
This ensures that even if the saved rule is cryptic (like bash:ls:*), the user sees a friendly description: "Any Bash command starting with ls".
The Rule Persistence Manager completes the circle of our permissions system.
Congratulations! You have navigated the entire architecture of the Permissions project. You now understand how a secure, user-friendly, and persistent AI permission system is built from the ground up.
Generated by Code IQ