Extending Behavioral Rules
Relevant source files
The following files were used as context for generating this wiki page:
Introduction
Extending Behavioral Rules refers to the mechanism within the SynthCrowd (Abee) engine that translates abstract persona traits into deterministic, actionable instructions for AI browser agents. These rules act as constraints that force agents to exhibit specific human behaviors—such as confusion, impatience, or caution—while navigating a target website. By mapping 19 distinct persona traits across 5 categories to specific strings of text, the system ensures that synthetic users do not behave as generic LLM assistants but rather as unique, flawed human individuals.
The rules are primarily handled by the Prompt Compiler, which transforms a PersonaConfig into a comprehensive system prompt. This process is critical for the "Phase 2: Test" and "Phase 5: Rerun" stages of the project pipeline, where agents must maintain high fidelity to their assigned identities to produce valid user testing data.
Sources: plan.md:12-65, README.md:57-75
Architecture of Rule Generation
The behavioral rule system is deterministic rather than LLM-generated to ensure consistency and reliability. The architecture follows a multi-step pipeline where raw persona data is refined into a set of tagged behavioral instructions.
The Compilation Flow
The diagram above illustrates how the PersonaConfig is passed through specialized mapping functions to generate a final set of rules.
Sources: src/engine/promptCompiler.ts:358-400, README.md:57-65
Data Structures
The system utilizes specific interfaces to manage rules and their relationship to the persona's defining traits.
| Structure | Description | Key Fields |
|---|---|---|
PersonaConfig | The source of truth for all 19 traits (demographics, digital behavior, etc.). | tech_literacy, patience, decision_style |
TaggedRule | A wrapper for a rule string that includes metadata for sorting and filtering. | rule (string), trait (string), extremity (number) |
CompiledPersona | The final output containing the full system prompt and all associated rules. | system_prompt, tagged_rules |
Sources: src/engine/promptCompiler.ts:348-356, README.md:123-165
Trait-to-Rule Mapping Logic
Behavioral rules are generated by evaluating numeric traits (normalized 0-1) and categorical enums. Each category of behavior has a dedicated function that returns an array of strings based on specific value thresholds.
Technical Literacy and Digital Behavior
Technical literacy is one of the most impactful traits, controlling between 4 to 7 rules. Low literacy scores (< 0.2) generate rules that restrict the agent's ability to recognize standard UI patterns like hamburger menus or CAPTCHAs.
function techLiteracyRules(level: number): string[] {
if (level < 0.2) {
return [
"You do NOT understand hamburger menus (☰). You look for clearly labeled navigation links.",
"You are confused by dropdown menus and hover-activated elements.",
"If you encounter a CAPTCHA, you struggle and may abandon."
];
}
// ... higher levels include keyboard shortcuts and identifying dark patterns
}
Sources: src/engine/promptCompiler.ts:6-48, README.md:77-85
Decision Styles and Trust
Categorical traits like decision_style map to distinct sets of operational logic.
- Impulsive: Clicks the first CTA without reading.
- Methodical: Compares plans and tiers systematically.
- Cautious: Reads terms, privacy policies, and refund policies.
- Research Heavy: Opens multiple pages and reads FAQs thoroughly.
Sources: src/engine/promptCompiler.ts:182-212, README.md:155-165
Rule Selection and Refinement
To prevent prompt bloat and maintain focus, the system implements a prioritization strategy. While a single persona can accumulate 15-35 rules, the engine is designed to prioritize rules where the persona's traits are most extreme.
Extremity Scoring
Each TaggedRule is assigned an extremity score, calculated as Math.abs(traitValue - 0.5). Traits that deviate furthest from the 0.5 midpoint are considered the most "defining" for that persona and are given priority in the prompt.
function tagRules(rules: string[], trait: string, traitValue: number): TaggedRule[] {
const extremity = Math.abs(traitValue - 0.5);
return rules.map((rule) => ({ rule, trait, extremity }));
}
Sources: src/engine/promptCompiler.ts:358-362, plan.md:78-81
Dynamic Instruction Scaling
Certain instructions are scaled dynamically based on traits rather than just being static strings. For example, the max_steps for an agent session is calculated as:
max_steps = Math.round(15 + 35 * config.patience)
This ensures that "impatient" personas naturally abandon sessions earlier than "patient" ones.
Sources: plan.md:83-85, src/test-smoke.ts:43
Integration with System Prompts
The final stage of extending behavioral rules is their injection into the system_prompt. This prompt includes the persona's identity, the target goal, and the strictly numbered list of behavioral rules.
Summary of Rule Categories
| Category | Trait Influence | Example Rule Logic |
|---|---|---|
| Navigation | tech_literacy, age | Handling of menus, modals, and layout density. |
| Persistence | patience, attention_span | Thresholds for page load speed and form length. |
| Trust/Security | trust_baseline, income | Requirement for security badges or reviews before conversion. |
| Language | english_proficiency | Misunderstanding of jargon or inability to parse long text. |
| Intent | goal_clarity, purchase_intent | Browsing vs. direct navigation to checkout. |
Sources: src/engine/promptCompiler.ts:50-340, README.md:125-165
Conclusion
Extending Behavioral Rules is the core mechanism that enables SynthCrowd to simulate a diverse and realistic crowd. By using a deterministic, trait-based mapping system with extremity scoring, the project achieves high-fidelity agent behavior that authentically reveals friction points in web interfaces. This system allows developers to see exactly how different demographic extremes—such as a low-tech elderly user versus an impatient SF engineer—experience the same code.
Sources: plan.md:5-10, README.md:3-8