# Sysadmin Chronicles — Quest Implementation Specification **File:** `sysadmin_chronicles_quest_implementation_spec.md` **Purpose:** Convert the audited quest/story redesign into an implementation-ready content and systems specification. **Authority order:** `SPEC_LOCK.md` is binding. The revised redesign is source content. The audit corrections override redesign defects. `QUEST_AUTHORING.md` remains the current technical schema baseline. --- ## 0. Non-Negotiable Design Constraints This implementation must preserve the core design: - The player is doing sysadmin work, not following an explicit main quest. - Story must leak through real system artifacts, tickets, logs, configs, access records, bash history, package history, and operational consequences. - Existing systems are extended, not replaced: - `trust_delta` - `world_flags` - `solution_branches` - `follow_up_ticket` - `follow_up_incident` - `baseline_snapshot` - observed VM-state validation - Every quest maps to exactly one narrative phase: - `normal_work` - `unease` - `suspicion` - `investigation` - `conflict` - `resolution` - Behavior-driven endings must emerge from accumulated state. - No ending may be selected by one obvious final choice. - Do not turn Marcus, Priya, Sarah, or Kowalski into cartoon villains. - Do not rewrite character identity or role in ways that require new portraits. - Phase 4 and later must remain problem-solving only in ticket wording and clue design, even if the final resolution has lower emotional pressure. --- ## 1. Quest Data Schema ### 1.1 Canonical Quest Object Use this shape for authored quest JSON. ```json { "id": "Q001", "title": "First Day, First Key", "narrative_phase": "normal_work", "tier": 1, "primary_vm": "workstation", "required_vms": ["workstation"], "ticket_id": "T001", "baseline_snapshot": "q001_first_day_first_key", "summary": "Internal author summary of scenario, root cause, and intended branch spread.", "linux_concepts": [ "ssh-keygen", "authorized_keys", "file permissions" ], "systems_used": [ "workstation" ], "clue_fingerprint": { "description": "Author-facing description of seeded evidence.", "evidence": [] }, "objectives": [], "solution_branches": [], "hidden_hook": null, "failure_conditions": [], "behavior_impact": { "default": { "curiosity_delta": 0, "obedience_delta": 0, "risk_delta": 0, "suspicion_delta": 0 } }, "access_requirements": { "minimum_access": { "workstation": "basic_user" }, "requires_root": false, "temporary_grants_allowed": [] }, "unlock_requirements": [], "pressure_profile": null, "blast_radius": [], "tags": [], "internal_notes": "" } ``` ### 1.2 Field Definitions | Field | Type | Required | Notes | |---|---:|---:|---| | `id` | string | yes | Stable quest ID, e.g. `Q001`. | | `title` | string | yes | Player-facing quest title. | | `narrative_phase` | enum string | yes | One of the six locked phases. | | `tier` | int | yes | Existing difficulty tier. Usually `1`, `2`, or `3`. | | `primary_vm` | string | yes | Main VM for the quest. Existing values: `workstation`, `web_server`, `build_machine`. | | `required_vms` | string[] | yes | Every VM, container, or simulated host touched by clues, validation, or prep. | | `ticket_id` | string | yes | Links to `content/tickets/.json`. | | `baseline_snapshot` | string | yes | Snapshot prepared before quest starts. | | `summary` | string | yes | Internal summary. Not shown directly to player. | | `linux_concepts` | string[] | yes | Explicit concepts taught or used. | | `systems_used` | string[] | yes | Player-facing/authorship list of systems involved. Must match `required_vms` unless using user-facing host names. | | `clue_fingerprint` | object | yes | Advisory evidence map seeded by prep scripts. | | `objectives` | object[] | yes | Existing objective objects. | | `solution_branches` | object[] | yes | Existing branch model, extended below. | | `hidden_hook` | object/null | yes | Optional hidden discovery spec. Use `null` when absent. | | `failure_conditions` | string[] | yes | Player-visible/author-facing failure states. | | `behavior_impact` | object | yes | Quest-level default behavior impact. Branch-level values override. | | `access_requirements` | object | yes | Minimum access needed to start/complete quest. | | `unlock_requirements` | string[] | yes | Existing unlock system. May include `world_flag:*`, `trust_min:*`, etc. | | `pressure_profile` | string/null | yes | Existing field, now tied to phase pressure definitions. | | `blast_radius` | string[] | yes | Incident IDs affected or triggered by quest state. | | `tags` | string[] | yes | Search/classification tags. | | `internal_notes` | string | yes | Author-only implementation notes. | ### 1.3 Solution Branch Extension Existing branch schema remains valid. Add `behavior_impact` to every branch. ```json { "id": "clean_fix", "label": "Clean fix", "priority": 100, "validation": { "type": "and", "rules": [] }, "trust_delta": 2, "behavior_impact": { "curiosity_delta": 0, "obedience_delta": 1, "risk_delta": 0, "suspicion_delta": 0 }, "follow_up_dialogue": "D001_CLEAN", "follow_up_incident": null, "follow_up_ticket": "T002", "world_flags": ["player_ssh_configured"], "_note": "Root-cause fix. No downstream incident." } ``` #### Branch Requirements - Branch priorities must be unique per quest. - Highest valid branch wins. - Clean branch should have highest priority. - Regression branch should never block play unless the VM state is unrecoverable. - Missing behavior deltas must normalize to `0`. - `trust_delta` remains professional standing, not moral alignment. - `behavior_impact` must describe player conduct, not just technical success. ### 1.4 How This Extends `QUEST_AUTHORING.md` Without Breaking It This spec does **not** replace the existing quest authoring schema. It adds fields that can be loaded with defaults. Existing fields preserved: - `id` - `title` - `tier` - `primary_vm` - `required_vms` - `ticket_id` - `baseline_snapshot` - `summary` - `clue_fingerprint` - `objectives` - `solution_branches` - `pressure_profile` - `blast_radius` - `unlock_requirements` - `tags` - `internal_notes` - `_note` New fields: - `narrative_phase` - `linux_concepts` - `systems_used` - `hidden_hook` - `failure_conditions` - `behavior_impact` - `access_requirements` Compatibility rules: ```text Old quest file loads: - narrative_phase: infer from quest ID map or default to "normal_work" during migration - linux_concepts: [] - systems_used: required_vms - hidden_hook: null - failure_conditions: [] - behavior_impact: all deltas 0 - access_requirements: derived from primary_vm/tier ``` Do not remove or rename existing validation rule types. New narrative systems should read quest resolution results and hidden-hook state after validation, not replace `ValidationService`. --- ## 2. Behavior Tracking Schema ### 2.1 Global Behavior State Persist these values in save state. ```json { "trust": 0, "curiosity": 0, "obedience": 0, "risk": 0, "suspicion": 0, "behavior_events": [] } ``` Each behavior event should be auditable: ```json { "event_id": "behavior_Q005_clean_fix", "quest_id": "Q005", "source": "solution_branch", "branch_id": "clean_fix", "deltas": { "trust": 2, "curiosity": 0, "obedience": 1, "risk": 0, "suspicion": 0 }, "world_flags_set": ["hermes_cache_ownership_correct"], "timestamp": "game-time-or-save-counter" } ``` ### 2.2 Variable: `curiosity` **Meaning:** The player investigates beyond immediate ticket scope, reads anomalous artifacts, cross-references system history, and notices patterns. #### Increases when - Hidden hook discovered. - Player reads or preserves out-of-scope but relevant evidence. - Player cross-references previous anomalies in a report or audit artifact. - Player checks history deeper than required by the immediate symptom. - Player chooses a branch that documents suspicious system history without making unauthorized changes. #### Decreases when Normally does not decrease. Do not punish curiosity directly. If curiosity creates unauthorized changes, apply `risk` and `suspicion`, not negative curiosity. #### Thresholds | Threshold | Meaning | |---:|---| | `5` | Player has noticed early anomalies. Minor dialogue nuance unlocked. | | `10` | Suspicion/investigation route can begin surfacing optional content. | | `20` | `exposure` becomes eligible if major hooks and trust/risk requirements are also met. | | `30+` | Thorough investigator. Ending text can acknowledge complete evidence chain. | #### Systems that read it - QuestDirector phase routing - HiddenHookService - DialogueService - EndingEvaluator - PressureService, indirectly through `suspicion` #### Affected by | Source | Effect | |---|---| | Solution branches | +0 to +3 when branch includes extra documented investigation. | | Hidden hooks | +1 to +5 depending on hook importance. | | Incidents | +1 if player connects incident to previous branch/flag. | | Optional actions | +1 to +3 when optional evidence is discovered or preserved. | ### 2.3 Variable: `obedience` **Meaning:** The player completes assigned work, stays in scope, follows authority structures, documents before deviating, and escalates appropriately. #### Increases when - Clean or acceptable branch resolves assigned ticket. - Player documents root cause in expected artifact. - Player follows access-review procedure. - Player escalates before changing scope. - Player completes high-pressure tasks without unsafe shortcuts. #### Decreases when Usually does not need direct decreases. Low obedience is represented by failing to gain obedience, plus possible `risk`, `suspicion`, and trust loss. Apply explicit negative obedience only when the player refuses or ignores assigned work while making unrelated changes. #### Thresholds | Threshold | Meaning | |---:|---| | `8` | Reliable junior admin. | | `15` | Strong procedural compliance. | | `25` | `corporate_loop` eligible if curiosity is low and trust is positive. | | `30+` | Highly compliant; useful for subtle ending variation. | #### Systems that read it - QuestDirector - AccessService - DialogueService - EndingEvaluator - PressureService #### Affected by | Source | Effect | |---|---| | Solution branches | Clean branches usually +1. Acceptable branches +0 or +1. | | Hidden hooks | No direct effect unless player escalates properly after discovery. | | Incidents | +1 if player resolves incident procedurally. | | Optional actions | +1 if optional action is documentation/escalation, not snooping. | ### 2.4 Variable: `risk` **Meaning:** Reckless or unsafe conduct: broad permissions, security bypasses, destructive cleanup, evidence destruction, unauthorized access, falsified reporting. #### Increases when - Player bypasses SSL/TLS verification. - Player disables security controls without approval. - Player makes services run as root unnecessarily. - Player makes world-writable directories. - Player deletes logs or evidence instead of archiving. - Player modifies unauthorized systems. - Player falsifies or sanitizes reports. - Player performs a dangerous final change without prior context or escalation. #### Decreases when Risk generally does not decay during active phases. A small reduction is allowed in Phase 6 only if the player performs an accurate self-audit and documents their own footprint. Recommended maximum reduction: `-3`. #### Thresholds | Threshold | Meaning | |---:|---| | `5` | Mildly risky admin. Priya may mention access hygiene. | | `10` | Elevated risk. Access grants become stricter. | | `15` | High risk. Monitoring/interference likely. | | `20` | `chaos` eligible, especially with suspicion or evidence-destruction flags. | #### Systems that read it - AccessService - PressureService - IncidentService - EndingEvaluator - DialogueService #### Affected by | Source | Effect | |---|---| | Solution branches | Regression branches +2 to +5. Severe branches +5 or more. | | Hidden hooks | No direct risk unless acted on recklessly. | | Incidents | Incidents caused by unsafe branch may add +1 to +3. | | Optional actions | Unauthorized modification or evidence destruction adds risk. | ### 2.5 Variable: `trust` **Meaning:** Professional standing. Mostly driven by quality of fixes. #### Increases when - Player completes robust root-cause fixes. - Player documents properly. - Player avoids downstream incidents. - Player handles access or security work carefully. #### Decreases when - Player leaves brittle fixes. - Player introduces regressions. - Player creates security exposure. - Player fails objectives. #### Thresholds | Threshold | Meaning | |---:|---| | `< 0` | Low trust. Access and dialogue become constrained. | | `0–5` | Basic working trust. | | `6–12` | Trusted junior. More access and context. | | `13+` | High trust. Can receive sensitive temporary access if risk/suspicion allow. | #### Systems that read it - AccessService - QuestDirector - DialogueService - EndingEvaluator - PressureService #### Affected by | Source | Effect | |---|---| | Solution branches | Existing `trust_delta`. | | Hidden hooks | No direct effect unless branch resolution includes documentation/escalation. | | Incidents | Trust loss if incident was caused by player's earlier weak branch. | | Optional actions | Trust gain only if optional action produces useful, documented operational outcome. | ### 2.6 Variable: `suspicion` **Meaning:** Management/security attention. Distinct from trust. A competent investigator can have high trust and high suspicion. #### Increases when - Player accesses sensitive paths outside ticket scope. - Player discovers or acts on major hidden hooks. - Player performs unusual audit activity. - Player uses root frequently. - Player triggers risky incidents. - Player touches unauthorized hosts. - Player reports anomalies up the chain. #### Decreases when - Player documents why access was needed. - Player escalates before acting. - Priya approves investigation scope. - Player completes access reviews cleanly. - Player self-audits accurately. #### Thresholds | Threshold | Meaning | |---:|---| | `3` | Mild attention. Priya/Kowalski wording may shift. | | `6` | Monitoring. Access requests reviewed more carefully. | | `10` | High suspicion. Temporary grants restricted. | | `15` | Maximum/critical. Chaos may become eligible if risk is also high or evidence flags exist. | #### Systems that read it - PressureService - AccessService - DialogueService - EndingEvaluator - QuestDirector #### Affected by | Source | Effect | |---|---| | Solution branches | Risky or unusual branches +1 to +3. | | Hidden hooks | Major hooks +1 suspicion when surfaced/reported. Discovery alone may be silent early. | | Incidents | Security incidents +2 to +4. | | Optional actions | Approved documentation can reduce suspicion; unauthorized digging can increase it. | --- ## 3. Access System Schema ### 3.1 Global Access State Access is per machine. Do not use one global permission flag. ```json { "access_level": { "workstation": "basic_user", "web_server": "none", "build_machine": "none", "external_target_10_0_0_47": "none" }, "temporary_grants": [], "access_review_flags": [] } ``` ### 3.2 Access Levels Enum: ```text none basic_user sudo root ``` The user requested levels are `basic_user`, `sudo`, and `root`; `none` is needed internally for systems the player cannot yet access. --- ### 3.3 Level: `basic_user` #### Unlock conditions - Default on `workstation` at game start. - Granted on other machines when a ticket explicitly gives user-level access. - Requires no special trust beyond initial onboarding unless previously revoked. #### Restrictions - No privileged writes. - No service restarts requiring sudo. - No system config edits. - Can inspect user-readable logs, home directories, docs, and assigned files. #### Quest types enabled - Onboarding - Read-only investigation - Basic file inspection - User-level SSH/auth setup - Non-privileged diagnostics #### Possible temporary grants - Read-only access to a project directory. - Temporary account on `hermes` or `vulcan`. - Restricted shell for audit inventory. #### Possible restrictions from suspicion/risk - High suspicion can restrict access to only ticket-specific paths. - High risk can prevent access to sensitive logs or deploy accounts. --- ### 3.4 Level: `sudo` #### Unlock conditions - Positive trust. - Quest requires administrative work. - Risk below elevated threshold. - Suspicion below high threshold or access explicitly approved. - Usually available from Phase 2 onward on `workstation`/`web_server`, later on `build_machine`. #### Restrictions - Sudo should be task-scoped where possible. - Dangerous commands may be audited. - Some actions may require explicit quest grant: - editing sudoers - restarting production-facing services - modifying firewall rules - changing deploy keys - package signing or release publishing #### Quest types enabled - Service repair - Config edits - Package management - Permission/ownership repair - Log rotation repair - Access review cleanup - Build pipeline maintenance #### Possible temporary grants ```json { "grant_id": "grant_Q011_pipeline_svc_sudo_review", "quest_id": "Q011", "vm": "build_machine", "level": "sudo", "scope": ["read:/etc/sudoers.d/pipeline-svc", "write:/etc/sudoers.d/pipeline-svc"], "expires_on": "quest_resolution" } ``` #### Possible restrictions from suspicion/risk - If `risk >= 10`, require Priya or Marcus approval for new sudo grants. - If `suspicion >= 10`, deny broad sudo and allow only scoped sudo. - If `risk >= 15`, revoke nonessential sudo until review quest resolves. --- ### 3.5 Level: `root` Root is rare and usually temporary. It is not a normal promotion. This fixes the audit finding that root was named but not actually modeled. #### Unlock conditions All must be true unless a specific authored exception exists: - `trust > 0` - `risk < 10` - `suspicion < 10`, or Priya explicitly approves the grant - Current phase is `investigation` or `conflict` - Quest has `access_requirements.requires_root: true` - Quest explains why sudo is insufficient #### Restrictions - Root must be logged. - Root grants expire at quest resolution unless ending state explicitly preserves high trust. - Root should be allowed only for: - filesystem recovery - archival preservation - privileged audit capture - service account repair - controlled forensic inventory - Root must not become the default way to solve all admin tasks. That would flatten the game. #### Quest types enabled - Privileged audit capture - Root-owned evidence preservation - Recovery from broken sudo/service account state - Deep backup/restore verification - Controlled incident response #### Possible temporary grants ```json { "grant_id": "grant_Q035_log_archival_root", "quest_id": "Q035", "vm": "web_server", "level": "root", "scope": [ "read:/var/log/**", "read:/root/.bash_history", "write:/var/archive/**" ], "approved_by": "p.nair@axiomworks.internal", "expires_on": "quest_resolution" } ``` #### Possible restrictions from suspicion/risk - `risk >= 10`: deny root unless the quest is explicitly a recovery quest. - `suspicion >= 10`: root requires Priya approval and narrow scope. - `risk >= 15`: root denied except for forced remediation. - Evidence destruction flag: root locked until an access review quest resolves. --- ## 4. Hidden Hook Schema ### 4.1 Canonical Hidden Hook Object ```json { "hook_id": "hook_dale_ssh_key_found", "quest_id": "Q001", "clue_type": "unexpected_ssh_key", "discovery_method": { "type": "state_or_audit", "description": "Player reads authorized_keys before overwriting it or preserves the Dale key entry while adding their own key.", "detection": { "preferred": "state_change", "fallback": "auditd_file_read", "validation": { "type": "file_contains", "vm": "workstation", "path": "/home/player/.ssh/authorized_keys", "contains": "dale@axiomworks.internal" } } }, "evidence_locations": [ { "vm": "workstation", "path": "/home/player/.ssh/authorized_keys", "contains": "dale@axiomworks.internal" } ], "visible_to_player": false, "ignored_result": { "world_flags": [], "behavior_impact": { "curiosity_delta": 0, "obedience_delta": 0, "risk_delta": 0, "suspicion_delta": 0 } }, "discovered_result": { "world_flags": ["hook_dale_ssh_key_found"], "behavior_impact": { "curiosity_delta": 1, "obedience_delta": 0, "risk_delta": 0, "suspicion_delta": 0 } }, "acted_on_result": { "world_flags": ["hook_dale_ssh_key_found", "dale_key_documented"], "behavior_impact": { "curiosity_delta": 1, "obedience_delta": 1, "risk_delta": 0, "suspicion_delta": 1 } }, "world_flags": ["hook_dale_ssh_key_found"], "unlocks": [] } ``` ### 4.2 Field Definitions | Field | Type | Required | Notes | |---|---:|---:|---| | `hook_id` | string | yes | Stable hook ID. | | `quest_id` | string | yes | Owning quest. | | `clue_type` | enum/string | yes | Classification: `unexpected_ssh_key`, `odd_timestamp`, `unknown_service`, etc. | | `discovery_method` | object | yes | How the game can detect discovery. | | `evidence_locations` | object[] | yes | Real seeded locations. | | `visible_to_player` | bool | yes | Usually `false`. Hooks are not quest markers. | | `ignored_result` | object | yes | State if not discovered. Usually no effect. | | `discovered_result` | object | yes | Flags and behavior changes on discovery. | | `acted_on_result` | object | yes | Effects if player documents/escalates/uses the hook. | | `behavior_impact` | object | optional | Alias allowed for legacy convenience; prefer nested results. | | `world_flags` | string[] | yes | Flags set by discovery. | | `unlocks` | string[] | yes | Optional unlocks for later dialogue, quests, or ending eligibility. | ### 4.3 Discovery Detection Strategy Use a consistent strategy per hook. Do not mix half-solutions randomly. #### Preferred strategy by phase | Phase | Recommended detection | |---|---| | Phase 1 | State-change detection | | Phase 2 | State-change detection | | Phase 3 | State-change or audit logging | | Phase 4 | Audit logging preferred | | Phase 5 | Audit logging or explicit documentation artifact | | Phase 6 | Usually no hidden hooks | #### Valid detection types ```text state_change auditd_file_read documentation_artifact command_wrapper_marker branch_context ``` #### Avoid - Fake `command_assert` rules that assume command history is available when it is not. - Hook discovery based only on taking the clean branch. - Double-counting curiosity when the hook is effectively required by the branch. - Explicit UI notifications like “hidden hook discovered.” That is a neon sign bolted to subtlety. ### 4.4 Hook Optionality Rule A hook is valid only if: - The ticket can be completed without discovering it. - The hook is discoverable through plausible sysadmin behavior. - The evidence exists in the VM baseline. - Discovery leaves a detectable state/audit/documentation signal. - Discovery does not require guessing story lore. --- ## 5. Boss / Management Pressure Schema ### 5.1 Canonical Pressure Profile Object ```json { "phase": "suspicion", "behavior_level": "suspicious", "possible_interruptions": [ "status_email", "priority_reassignment", "access_review_notice" ], "access_effects": { "may_delay_grants": true, "may_restrict_root": true, "may_revoke_temporary_grants": false }, "quest_effects": { "ticket_wording_style": "minimal_guidance", "branch_tolerance": "strict", "incident_visibility": "increased" }, "dialogue_style": { "marcus": "terse_forwarded_context", "priya": "procedural_review", "kowalski": "bullet_point_status_pressure" }, "character_sources": [ "Marcus Webb", "Priya Nair", "Dave Kowalski" ] } ``` ### 5.2 Phase Scaling Preserve this exact progression. | Phase | Behavior Level | Pressure Meaning | |---|---|---| | `normal_work` | `annoying` | Basic onboarding friction, reminders, mild evaluation. | | `unease` | `dismissive` | Oddities are treated as legacy cruft or low priority. | | `suspicion` | `suspicious` | Status questions and access posture concerns begin. | | `investigation` | `monitoring` | Audits, approvals, narrower scope, more Priya/Kowalski presence. | | `conflict` | `interfering` | Priority changes, access constraints, formal reviews. | | `resolution` | `outcome_dependent` | Pressure reflects accumulated ending route. | ### 5.3 Possible Interruptions Use sparingly. Pressure is a dynamic constraint, not a cutscene cannon. ```text status_email priority_reassignment delayed_access_approval access_review_notice audit_followup meeting_invite temporary_grant_expiration incident_escalation documentation_request ``` ### 5.4 Access Effects Pressure may: - Delay temporary grants. - Require Priya approval for root. - Restrict broad sudo. - Remove stale temporary access. - Force access review after high-risk branches. - Deny nonessential access during conflict phase. Pressure must not: - Block all play. - Force a single ending. - Accuse the player directly without accumulated cause. - Override branch validation. ### 5.5 Quest Effects Pressure can alter: - Ticket wording - Hint availability - Branch tolerance - Incident timing - Dialogue reaction - Unlock requirements - Access grant latency Pressure should not alter actual Linux realism. A broken service should still be broken for real reasons. ### 5.6 Dialogue Style by Character | Character | Use Under Pressure | |---|---| | Marcus Webb | Short, precise, operational. Does not explain the plot. | | Priya Nair | Calm, procedural, consequence-focused. No alarmism. | | Dave Kowalski | Institutional pressure, bullet points, access posture language. | | Sarah Chen | Product/demo pressure, symptom-focused, not investigative. | | Dave Okonkwo | Ordinary user impact, not plot delivery. | --- ## 6. Ending Schema ### 6.1 Canonical Ending Object ```json { "ending_id": "exposure", "name": "Exposure", "behavior_requirements": { "curiosity_min": 20, "obedience_min": 0, "risk_max": 12, "trust_min": 1, "suspicion_max": 14 }, "world_flag_requirements": { "all": [], "any": [ "archive_record_complete", "unauthorized_access_chain_documented" ], "none": [ "evidence_destroyed_major", "report_falsified_major" ] }, "access_requirements": { "required_history": [ "had_sudo_or_root_for_audited_task" ], "current_access": {} }, "hidden_hook_requirements": { "major_hooks_min": 5, "required_hooks_any": [ "hook_audit_bridge_package", "hook_dh_sudo_grant", "hook_unknown_ip_auth" ] }, "priority_rules": { "priority": 2, "overridden_by": ["chaos"] }, "fallback_conditions": [], "summary": "Player assembled enough evidence through legitimate sysadmin work for the hidden story to surface.", "final_state": { "player_status": "trusted_but_changed", "company_state": "internal_exposure_or_external_review", "marcus_response_style": "minimal_acknowledgment" } } ``` ### 6.2 Ending Priority Order Use this order: ```text chaos → exposure → corporate_loop → burnout ``` Reason: high-risk/destructive behavior should override investigative progress; curiosity beats obedience when both are high; burnout catches passive/low-trust paths. ### 6.3 Ending: `chaos` ```json { "ending_id": "chaos", "name": "Chaos", "behavior_requirements": { "risk_min_any": 20, "suspicion_min_any": 15 }, "world_flag_requirements": { "any_compound": [ { "flag": "final_config_made", "also_requires_any": [ "risk_elevated", "access_review_incomplete", "kowalski_report_sanitized", "backup_test_falsified", "logs_selectively_omitted" ] } ], "serious_flags_min": 2, "serious_flags": [ "evidence_destroyed_major", "report_falsified_major", "unauthorized_proxy_enabled", "ssl_verification_bypassed", "service_run_as_root_unnecessarily", "logs_selectively_omitted" ] }, "access_requirements": {}, "hidden_hook_requirements": {}, "priority_rules": { "priority": 1, "overrides": ["exposure", "corporate_loop", "burnout"] }, "fallback_conditions": [], "summary": "The player's own access footprint becomes part of the incident review.", "final_state": { "player_status": "under_access_review", "company_state": "formal_internal_review", "tone": "administrative" } } ``` Important correction: `final_config_made` is a heavy contributor, not a standalone bad-ending button. ### 6.4 Ending: `exposure` ```json { "ending_id": "exposure", "name": "Exposure", "behavior_requirements": { "curiosity_min": 20, "trust_min": 1, "risk_max": 19 }, "world_flag_requirements": { "any": [ "archive_record_complete", "unauthorized_access_chain_documented", "int0194_thread_documented" ], "none": [ "evidence_destroyed_major", "report_falsified_major" ] }, "hidden_hook_requirements": { "major_hooks_min": 5 }, "priority_rules": { "priority": 2, "overridden_by": ["chaos"], "overrides": ["corporate_loop", "burnout"] }, "fallback_conditions": [], "summary": "The player finds and preserves enough evidence for the truth to surface through normal operational work.", "final_state": { "player_status": "credible_internal_witness", "company_state": "exposed_or_forced_review", "tone": "quiet_consequence" } } ``` ### 6.5 Ending: `corporate_loop` ```json { "ending_id": "corporate_loop", "name": "Corporate Loop", "behavior_requirements": { "obedience_min": 25, "trust_min": 1, "curiosity_max": 14, "risk_max": 19 }, "world_flag_requirements": { "none": [ "archive_record_complete", "unauthorized_access_chain_documented", "int0194_thread_documented" ] }, "hidden_hook_requirements": { "major_hooks_max": 4 }, "priority_rules": { "priority": 3, "overridden_by": ["chaos", "exposure"], "overrides": ["burnout"] }, "fallback_conditions": [], "summary": "The player becomes a reliable operator inside the system without understanding what the system is hiding.", "final_state": { "player_status": "trusted_employee", "company_state": "continues_operating", "tone": "normal_work_resumes" } } ``` ### 6.6 Ending: `burnout` ```json { "ending_id": "burnout", "name": "Burnout", "behavior_requirements": {}, "world_flag_requirements": {}, "access_requirements": {}, "hidden_hook_requirements": {}, "priority_rules": { "priority": 4, "fallback": true }, "fallback_conditions": [ "No other ending matched", "Trust too low for corporate_loop", "Curiosity too low for exposure", "Risk below chaos threshold" ], "summary": "The player completes enough work to continue, but never builds enough trust, curiosity, or coherent evidence to change anything.", "final_state": { "player_status": "worn_down_or_stagnant", "company_state": "unchanged", "tone": "muted" } } ``` --- ## 7. File Organization Recommendation Do not force these paths if the repo already has conventions that differ. Use them as the target shape unless implementation reality says otherwise. ```text content/ quests/ Q001.json Q002.json ... tickets/ T001.json T002.json ... dialogue/ D001_clean.json D001_regression.json ... narrative/ behavior_rules.json access_levels.json pressure_profiles.json endings.json hidden_hooks.json phase_rules.json ``` ### Recommended Files #### `content/quests/*.json` Owns: - Quest schema - Objectives - Solution branches - Access requirements - Quest-local hidden hook link or inline hook - Behavior deltas - Blast radius - Unlock requirements #### `content/tickets/*.json` Owns: - Sender - Recipient - Subject - Body - Phase-appropriate wording - No hidden-hook labels - No explicit solution instructions unless Phase 1 requires it #### `content/dialogue/*.json` Owns: - Branch reaction dialogue - Incident dialogue - Access grant/revocation messages - Pressure interruption text - Ending-adjacent final messages #### `content/narrative/behavior_rules.json` Owns: - Variable definitions - Thresholds - Default deltas - Decay rules, if any - Event audit schema #### `content/narrative/access_levels.json` Owns: - Access enum - Per-phase grants - Trust/risk/suspicion gates - Temporary grant rules - Root restrictions #### `content/narrative/pressure_profiles.json` Owns: - Phase pressure profiles - Interruption types - Access effects - Quest effects - Character source rules #### `content/narrative/endings.json` Owns: - Ending requirements - Priority order - Fallback logic - Final-state outputs #### Optional: `content/narrative/hidden_hooks.json` Use this if hooks become too large to keep inline inside quest JSON. Recommended compromise: - Quest JSON contains `hidden_hook: "hook_id"` or small inline object. - `hidden_hooks.json` contains full hook definitions. --- ## 8. Validation Rules The implementation should enforce all of these. ### 8.1 Quest Schema Validation 1. Every quest must have all required root fields. 2. `id` must match filename. 3. `ticket_id` must point to an existing ticket file. 4. `narrative_phase` must be one of: - `normal_work` - `unease` - `suspicion` - `investigation` - `conflict` - `resolution` 5. Every quest must map to exactly one phase. 6. `tier` must be a positive integer. 7. `primary_vm` must be included in `required_vms`. 8. Every VM in `clue_fingerprint`, `objectives`, `solution_branches`, `hidden_hook`, prep requirements, and validation must appear in `required_vms`. 9. If a quest references `10.0.0.47`, it must declare `external_target_10_0_0_47` or equivalent concrete system in `required_vms`. 10. `systems_used` must not omit any player-touched system. 11. `baseline_snapshot` must be non-empty. 12. `summary` must be non-empty and author-facing. 13. `linux_concepts` must be non-empty. 14. `failure_conditions` must be non-empty. 15. `tags` must be an array. ### 8.2 Branch Validation 16. Every quest must have at least two solution branches unless explicitly approved as a final resolution quest. 17. Every branch must have unique `id`. 18. Every branch must have unique `priority`. 19. Higher priority must represent better or more complete outcome. 20. Every branch must have `validation`. 21. Every branch must have `trust_delta`. 22. Every branch must have explicit `behavior_impact` with all four deltas: - `curiosity_delta` - `obedience_delta` - `risk_delta` - `suspicion_delta` 23. Missing branch deltas must be normalized to `0` during migration only, then written back explicitly. 24. Branch `world_flags` must use stable string keys. 25. `follow_up_ticket`, if present, must point to an existing ticket. 26. `follow_up_incident`, if present, must point to an existing incident definition. 27. Regression branches should not share validation conditions with clean branches unless priority correctly disambiguates. 28. Branches must not make one final choice alone trigger an ending. ### 8.3 Objective Validation 29. Every objective must have: - `id` - `description` - `check_mode` - `validation` 30. `check_mode` must be `passive` or `explicit`. 31. Objectives must not choose the winning branch. 32. Objectives should use state-based validation where possible. ### 8.4 Validation Rule Type Enforcement 33. New quests must use runtime rule names: - `file_mode` - `file_owner` - `service_state` - `service_enabled` - `process_running` - `port_listening` - `package_installed` - `command_assert` 34. Shorthand names like `file_mode_matches` may appear in notes but not runtime JSON. 35. `command_assert` must be used sparingly. 36. Prefer state rules over command rules. 37. Unknown fields may be tolerated by loader but should fail content lint for new authored files. 38. `and`, `or`, and `not` must contain valid nested rule objects. ### 8.5 Hidden Hook Validation 39. `hidden_hook` must be either `null`, a hook ID, or a valid hook object. 40. Every hook must have: - `hook_id` - `quest_id` - `clue_type` - `discovery_method` - `evidence_locations` - `visible_to_player` - `ignored_result` - `discovered_result` - `acted_on_result` - `world_flags` - `unlocks` 41. Hook `quest_id` must match owning quest. 42. Hook evidence locations must exist in the prep baseline. 43. Hook evidence VMs must be in `required_vms`. 44. Hook discovery must be detectable by approved mechanism: - `state_change` - `auditd_file_read` - `documentation_artifact` - `command_wrapper_marker` - `branch_context` 45. Hook discovery must be optional for ticket completion. 46. Hook discovery must not be identical to clean branch resolution unless explicitly marked as unavoidable and worth no separate curiosity. 47. Hook curiosity must not double-count branch curiosity. 48. Hidden hooks must not be visible as quest markers. 49. Hook world flags must be stable and unique. 50. Major hooks must be tagged as major for ending checks. ### 8.6 Behavior State Validation 51. Save state must persist: - `trust` - `curiosity` - `obedience` - `risk` - `suspicion` 52. Save state must persist behavior event history for debugging. 53. Behavior variables should be numeric. 54. Behavior deltas should apply once per branch resolution. 55. Hook deltas should apply once per hook discovery. 56. Replaying/rescanning a quest must not duplicate behavior deltas. 57. `risk` should not decay except explicitly authored Phase 6 self-audit reduction. 58. `curiosity` should not decay. 59. `obedience` should not decay. 60. `suspicion` may decrease only through authored documentation/escalation/review outcomes. 61. `trust` remains governed by existing `trust_delta`. ### 8.7 Access Validation 62. Access state must be per machine. 63. Access level must be one of: - `none` - `basic_user` - `sudo` - `root` 64. `basic_user → sudo → root` must be represented in data and logic. 65. Root access must not be granted as normal promotion. 66. Root grants must require: - quest requires root - trust positive - risk below elevated threshold - suspicion below high threshold or explicit approval 67. Temporary grants must expire. 68. Temporary grants must be logged. 69. High risk must restrict sudo/root grants. 70. High suspicion must add review/approval requirements. 71. Access revocation must not softlock the game; provide remediation quests. 72. Quest start must verify `access_requirements`. ### 8.8 Pressure Validation 73. Every phase must have a pressure profile. 74. Pressure behavior level must preserve: - `annoying` - `dismissive` - `suspicious` - `monitoring` - `interfering` - `outcome_dependent` 75. Pressure may alter interruptions, access effects, ticket effects, and dialogue style. 76. Pressure must not replace VM-state validation. 77. Pressure must not turn characters into villains. 78. Pressure interruptions must be auditable. 79. Pressure effects must not force a single ending. ### 8.9 Ending Validation 80. Ending evaluator must run after final quest or when manually invoked by debug command. 81. Ending priority must be: - `chaos` - `exposure` - `corporate_loop` - `burnout` 82. Every ending must have: - `ending_id` - `name` - `behavior_requirements` - `world_flag_requirements` - `access_requirements` - `hidden_hook_requirements` - `priority_rules` - `fallback_conditions` - `summary` - `final_state` 83. No ending may be triggered by one obvious final branch alone. 84. `final_config_made` must not alone trigger `chaos`. 85. `exposure` must require major hidden hooks plus sufficient curiosity. 86. `corporate_loop` must require obedience and positive trust with low/moderate curiosity. 87. `burnout` must be the fallback. 88. Ending evaluation must explain debug reasons when run in dev mode. 89. Ending evaluation must not expose raw thresholds to player UI unless in debug mode. ### 8.10 File/Prep Validation 90. Every quest must have an idempotent prep script unless generated by an approved fixture system. 91. Prep scripts must not require internet access. 92. Prep scripts must not prompt for input. 93. Prep scripts must create all clue evidence described in `clue_fingerprint`. 94. Prep scripts must create all hook evidence described in `hidden_hook`. 95. Prep scripts must restore or build from the declared baseline snapshot. 96. Prep scripts must accept domain/VM identifier according to current project convention. 97. Prep scripts must not depend on live player session state. 98. Report/documentation-heavy quests must validate concrete artifacts: - file paths - required sections - checksums - timestamps - source evidence references 99. External targets must be concrete: - fourth VM - containerized fake host - simulated network target 100. Do not leave external hosts as off-screen lore blobs. The machines demand receipts. --- ## 9. Debug / Dev Commands Names are recommendations. Wire them to the existing dev console/CLI style. ### 9.1 Force Phase ```text narrative phase set ``` Example: ```text narrative phase set investigation ``` Effects: - Sets current narrative phase. - Recomputes pressure profile. - Does not automatically grant access. - Emits debug event. ### 9.2 Inspect Quest State ```text quest inspect ``` Output: ```json { "quest_id": "Q015", "status": "active", "narrative_phase": "suspicion", "tier": 3, "primary_vm": "build_machine", "required_vms": ["build_machine"], "objectives": [], "valid_branches_now": [], "winning_branch_if_resolved": null, "world_flags_required": [], "hidden_hook": "hook_telemetry_ticket_INT0194" } ``` ### 9.3 Inspect Behavior Variables ```text behavior inspect ``` Output: ```json { "trust": 8, "curiosity": 14, "obedience": 18, "risk": 4, "suspicion": 6, "recent_events": [] } ``` ### 9.4 Modify Behavior Variables ```text behavior add [reason] behavior set [reason] ``` Examples: ```text behavior add curiosity 5 test-major-hook-threshold behavior set risk 20 test-chaos-route ``` Must log dev-origin event. ### 9.5 Inspect Access Level ```text access inspect access inspect ``` Output: ```json { "workstation": "sudo", "web_server": "sudo", "build_machine": "basic_user", "external_target_10_0_0_47": "none", "temporary_grants": [], "access_review_flags": [] } ``` ### 9.6 Force Access Level ```text access set [reason] ``` Example: ```text access set build_machine root test-q035-root-path ``` Allowed levels: ```text none basic_user sudo root ``` Must log dev-origin event. ### 9.7 Trigger Hidden Hook Discovery ```text hook discover [mode] ``` Examples: ```text hook discover hook_dale_ssh_key_found discovered hook discover hook_dh_sudo_grant acted_on ``` Modes: ```text discovered acted_on ignored ``` Effects: - Applies relevant world flags. - Applies relevant behavior deltas. - Does not duplicate effects if already applied unless `--force` is used. ### 9.8 Inspect Hidden Hooks ```text hook inspect hook inspect hook inspect --quest ``` Output: ```json { "hook_id": "hook_dale_ssh_key_found", "quest_id": "Q001", "state": "discovered", "world_flags_set": ["hook_dale_ssh_key_found"], "behavior_applied": { "curiosity_delta": 1, "obedience_delta": 0, "risk_delta": 0, "suspicion_delta": 0 } } ``` ### 9.9 Force Ending Check ```text ending check ending check --explain ``` Output: ```json { "selected_ending": "exposure", "priority_order": ["chaos", "exposure", "corporate_loop", "burnout"], "matched": { "chaos": false, "exposure": true, "corporate_loop": true, "burnout": true }, "reason": [ "exposure matched curiosity_min", "exposure matched major_hooks_min", "chaos did not match risk_min or serious_flags" ] } ``` ### 9.10 Reset Narrative State ```text narrative reset narrative reset --keep-quest-progress narrative reset --hard ``` Recommended behavior: - `narrative reset`: resets behavior variables, pressure, hidden hooks, ending route; keeps save shell. - `--keep-quest-progress`: preserves completed quests and branch history but recomputes derived narrative state. - `--hard`: resets quest progress, behavior, hooks, access, pressure, incidents, and ending route. ### 9.11 Additional Useful Debug Commands ```text flags inspect flags add flags remove pressure inspect pressure set incidents inspect incidents trigger incidents clear narrative audit-log narrative audit-log --quest ``` These are not required by the prompt, but they will save QA time. QA time is where specs go to die quietly. --- ## 10. Implementation Notes for Claude Code and Codex Use this block directly for repo implementation. ```text You are implementing the Sysadmin Chronicles quest/story redesign into the existing repo. Binding authority: 1. SPEC_LOCK.md is binding. 2. sysadmin_chronicles_redesign_audit.md corrections override defects in the revised redesign. 3. sysadmin_chronicles_full_quest_redesign_REVISED.md is the source quest/story content. 4. QUEST_AUTHORING.md is the current quest JSON and validation baseline. 5. new_system_canon_packet.md preserves canon, tone, machines, characters, and existing implementation concepts. Do not write a new story system from scratch. Extend the existing quest, branch, world_flag, trust_delta, incident, ticket, baseline_snapshot, and observed-state validation systems. Core implementation tasks: 1. Add quest schema support for: - narrative_phase - linux_concepts - systems_used - hidden_hook - failure_conditions - behavior_impact - access_requirements 2. Preserve existing QUEST_AUTHORING.md fields and behavior: - id - title - tier - primary_vm - required_vms - ticket_id - baseline_snapshot - summary - clue_fingerprint - objectives - solution_branches - pressure_profile - blast_radius - unlock_requirements - tags - internal_notes - _note 3. Extend solution branches with explicit behavior_impact: - curiosity_delta - obedience_delta - risk_delta - suspicion_delta Missing values may be normalized to 0 during migration, but new content must write all four values explicitly. 4. Add persistent narrative state: - curiosity - obedience - risk - suspicion - trust, using existing trust system - access_level per machine - temporary_grants - access_review_flags - hidden_hooks_discovered - behavior event audit log 5. Implement AccessService: - enum: none, basic_user, sudo, root - per-machine access - temporary grants - root grant/revoke rules - trust/risk/suspicion/phase gates - no softlocks; provide remediation path if access is restricted 6. Implement HiddenHookService: - load hook definitions from quest inline data or content/narrative/hidden_hooks.json - support detection types: - state_change - auditd_file_read - documentation_artifact - command_wrapper_marker - branch_context - apply hook effects only once - set world flags - add behavior deltas - never expose hidden hooks as normal quest markers 7. Implement PressureService: - phase profiles: - normal_work: annoying - unease: dismissive - suspicion: suspicious - investigation: monitoring - conflict: interfering - resolution: outcome_dependent - pressure can affect ticket timing, interruptions, access approvals, and dialogue selection - pressure must not replace VM validation or force endings 8. Implement EndingEvaluator: - priority order: - chaos - exposure - corporate_loop - burnout - chaos must not trigger from final_config_made alone - exposure requires curiosity plus major hidden hooks plus acceptable risk/trust state - corporate_loop requires high obedience, positive trust, and low/moderate curiosity - burnout is fallback - provide debug explanation output 9. Add content linting: - every quest has valid narrative_phase - every VM referenced appears in required_vms - branch priorities unique - behavior deltas explicit - hidden hooks detectable and optional - no one-button ending trigger - report-heavy quests validate concrete files/artifacts - Q036/external target must be represented as an actual VM/container/simulated target if used 10. Add debug commands: - narrative phase set - quest inspect - behavior inspect - behavior add/set - access inspect [vm] - access set - hook discover [discovered|acted_on|ignored] - hook inspect [hook_id] - ending check --explain - narrative reset [--keep-quest-progress|--hard] 11. Content migration: - update Priya references to Priya Nair / p.nair@axiomworks.internal - preserve character roles and portrait-compatible bios - fix Q034 duplicate branch priorities - fix Q036 required_vms and implementation of external_target_10_0_0_47 - fix Q039 so final_config_made contributes to chaos but does not alone trigger it - ensure Phase 4+ ticket text remains problem-solving only - ensure Phase 6 may feel calmer but does not violate the locked difficulty model in authored wording 12. Do not: - create cutscenes - create explicit main-quest markers - make hidden hooks visible achievements - replace trust with behavior variables - make Kowalski a villain - make Marcus explain Dale - let one branch alone select an ending - use story lore where real VM state should exist ``` --- ## 11. Migration Checklist Use this as implementation QA. ### Schema - [ ] Quest loader accepts new fields. - [ ] Old quests load with safe defaults. - [ ] New quests require explicit behavior deltas. - [ ] Branch priority uniqueness is enforced. - [ ] Required VM references are validated globally. ### Narrative State - [ ] Behavior variables persist. - [ ] Behavior event log persists. - [ ] Hidden hook discovery persists. - [ ] Access state persists. - [ ] Ending route can be recomputed. ### Access - [ ] `basic_user`, `sudo`, and `root` are real states. - [ ] Root is temporary and scoped. - [ ] Risk/suspicion restrict elevated grants. - [ ] Restricted access cannot permanently softlock play. ### Hidden Hooks - [ ] Hook discovery works by approved detection mechanism. - [ ] Hook effects apply once. - [ ] Hook discovery is optional. - [ ] Major hooks are tagged for endings. - [ ] No UI calls hooks “hidden hooks” in player-facing mode. ### Pressure - [ ] All six phase pressure levels exist. - [ ] Pressure can affect access/dialogue/ticket flow. - [ ] Pressure does not bypass branch validation. - [ ] Character tone stays canon-compatible. ### Endings - [ ] Ending evaluator applies priority order. - [ ] `final_config_made` is not a standalone chaos trigger. - [ ] `exposure` requires major hooks. - [ ] `corporate_loop` requires obedience and positive trust. - [ ] `burnout` catches unmatched states. - [ ] Debug output explains ending selection. ### Content Fixes from Audit - [ ] Root access progression implemented. - [ ] Q039 chaos trigger corrected. - [ ] Q036 external target declared and implemented. - [ ] Q034 duplicate branch priorities corrected. - [ ] Hidden hook detection strategy selected. - [ ] Documentation-heavy quests validate concrete artifacts. - [ ] Phase 4+ difficulty wording audited. - [ ] Behavior deltas normalized and explicit. --- ## 12. Recommended Implementation Order 1. Add schema fields and migration defaults. 2. Add behavior state and event logging. 3. Add access state and access gating. 4. Add hidden hook definitions and detection. 5. Add pressure profiles. 6. Add ending evaluator. 7. Add debug commands. 8. Add content lint rules. 9. Migrate revised quest content. 10. Fix audit defects: - root progression - Q034 duplicate priorities - Q036 external target - Q039 chaos logic - hook detection ambiguity 11. Run validation over all quest files. 12. Playtest three routes: - obedient clean-fix route - curious low-risk route - high-risk destructive route --- ## 13. Practical Notes - Treat `trust` and behavior variables as parallel systems. - `trust` answers: “Are you professionally reliable?” - `curiosity` answers: “Did you look beyond the ticket?” - `obedience` answers: “Did you stay in process?” - `risk` answers: “Did your actions create danger?” - `suspicion` answers: “Are management/security now watching your activity?” - These variables should create different routes without turning the game into a morality meter. - The best implementation will feel like normal sysadmin consequences. The worst implementation will feel like a branching visual novel wearing a terminal skin. Avoid the second one.