chore: bootstrap lean sysadmin-chronicles repo

Import the runnable game code, content, docs, scripts, and repo guidance while leaving local agent state, dependency installs, build output, and backup copies out of the published tree.
This commit is contained in:
2026-05-02 11:49:07 -04:00
commit 0265afa054
252 changed files with 37574 additions and 0 deletions
+190
View File
@@ -0,0 +1,190 @@
# SYSADMIN CHRONICLES — AGENT WORKING RULES
> Version 2.0 | Status: Enforced
>
> Changelog:
> v2.0 — Rewritten for Node.js + Svelte era. GDScript/Godot rules removed.
> v1.1 — GDScript-specific rules (superseded).
>
> Read this file FIRST before touching anything else. These rules prevent content
> corruption, broken cross-references, and silent design drift.
---
## 0. ALWAYS READ FIRST
Before doing any work, read these files in order:
1. `AGENT_RULES.md` (this file)
2. `OPEN_ISSUES.md` — current known issues and decisions in progress
3. `docs/ARCHITECTURE.md` — system design and constraints
4. `docs/QUEST_AUTHORING.md` — content schema and validation rules
If you are working on a specific domain, also read:
- Content work → `docs/QUEST_AUTHORING.md` + relevant `content/world_flags/world_flags.json`
- VM work → `docs/ARCHITECTURE.md` sections 5 and 6
- Save system work → `docs/SAVE_SYSTEM.md`
- Server work → `server/src/` — read the relevant service file before editing
---
## 1. WHAT YOU MAY DO WITHOUT ASKING
- Add new `.js` or `.svelte` files in `server/src/` or `frontend/src/` following existing conventions
- Add new JSON content files in `content/` that pass content validation
- Add new shell scripts in `tools/` that do not modify VM state
- Edit files you created in the current working session
- Run read-only commands: `cat`, `ls`, `grep`, `diff`, `virsh domstate`, probes
- Run content validation: `node tools/content/validate-content.js`
- Run server tests: `cd server && npm test`
- Create new files in `tools/vm/quest-prep/` for new quests
## 2. WHAT YOU MUST ASK BEFORE DOING
- Modifying `docs/ARCHITECTURE.md`, `docs/QUEST_AUTHORING.md`, `docs/SAVE_SYSTEM.md`, or `docs/ROADMAP.md`
- Modifying `content/world_flags/world_flags.json`
- Modifying any existing quest, ticket, incident, or dialogue JSON file
- Adding a new Express route or WebSocket event type
- Changing any validation rule type name or schema field name
- Changing VM profile IDs, snapshot names, or network profile names
- Any `virsh` command that modifies state: `start`, `destroy`, `snapshot-create`, `snapshot-revert`
- Any `tools/vm/` script that writes to a VM image
## 3. WHAT YOU MUST NEVER DO
- Delete any file (use a rename to `.bak` and ask first)
- Run `virsh undefine`, `virsh pool-delete`, or `virsh net-destroy` without explicit instruction
- Run `tools/vm/snapshot-all.sh --revert-to` without explicit instruction
- Modify a VM's baseline snapshot or `baseline.clean` state
- Run provisioning scripts (`Q0XX-prep.sh`) against any VM without explicit instruction
- Add a world flag reference in any content file without first adding it to `world_flags.json`
- Create a solution branch with a `priority` that duplicates an existing branch in the same quest
- Set `follow_up_incident` to an incident ID that does not exist as a file
- Set `series_id` in a dialogue file without ensuring at least 2 members share that series_id
- Modify the save file schema without updating `server/src/services/SaveState.js` and the migration handler
- Ignore content validation errors and proceed anyway
---
## 4. CONTENT AUTHORING RULES
### World Flags
- Every flag used anywhere must exist in `content/world_flags/world_flags.json`
- When you set a flag in a quest or incident, update `set_by` in the registry
- When you read a flag in a quest, incident, or dialogue, update `read_by`
- Conflicting flags must list each other in `conflicts_with`
- A flag with `persists: false` resets at the start of each new shift (not on load)
### Quests
- Every quest must have a `clue_fingerprint` with at least one evidence entry
- Every quest must declare `required_vms` — list ALL VMs touched, not just the primary
- Branch priorities must be unique within a quest — no two branches share a priority number
- The highest-priority branch that matches wins — author branches so better fixes have higher priority
- Do not author a branch that cannot be distinguished from another branch by validation rules alone
### Tickets
- Both `initial_priority` and `current_priority` must be present and equal at authoring time
- `current_priority` is the only field the runtime modifies — never change `initial_priority` at runtime
### Incidents
- Every incident must declare `blast_radius_quests` (can be empty array, never omit)
- Every incident must declare `blast_radius_incidents` (can be empty array, never omit)
- `follow_up_incident` in a quest branch must map to an incident file that exists
### Dialogue
- If `series_id` is declared, `series_position` must also be declared
- A `series_id` must have at least 2 dialogue files sharing it before content passes validation
- `trigger: "world_flag:{id}"` — the flag ID must exist in the registry
### File Naming
- Quest files: `Q{NNN}-{kebab-case-title}.json`
- Ticket files: `T{NNN}.json`
- Incident files: `I{NNN}-{kebab-case-title}.json`
- Dialogue files: `{character}-Q{NNN}.json` or `{character}-Q{NNN}-{variant}.json`
- Do NOT bundle multiple dialogue characters or quests into one file
- VM profiles: `{snake_case}.json`
- Quest prep scripts: `Q{NNN}-prep.sh`
---
## 5. CODE AUTHORING RULES
### Node.js (server/src/)
- All host commands go through `server/src/lib/ssh.js` or `server/src/lib/virsh.js` — never use `child_process` directly in service files
- All VM lifecycle actions go through `VMManager.js` — never call libvirt directly from quest or validation logic
- Never hardcode VM domain names — use constants from `ContentLoader` or the VM profile JSON
- All world flag reads and writes go through `QuestEngine.js` — never mutate flags directly
- Trust changes go through `TrustSystem.js` — never modify trust score directly
- Services coordinate via `eventBus.js` (Node EventEmitter) — no service may `require()` another service and call its internals directly; emit events instead
- All save-state writes go through `SaveState.js`
### Svelte (frontend/src/)
- All API calls go through `frontend/src/lib/api.js` — no raw `fetch()` in components
- WebSocket events are received in `App.svelte` and distributed to panels via Svelte stores or props — panels do not open their own WebSocket connections
- No game logic in Svelte components — components render state and dispatch user actions only
### Validation Rules
- Every new rule type must be added to `server/src/services/ValidationEngine.js` and the QUEST_AUTHORING.md rule reference table
- Rules must only observe state — they must never modify VM state
### Shell Scripts
- All scripts in `tools/vm/` must print a dry-run summary before modifying anything
- All scripts must be idempotent — running them twice must produce the same result
- Scripts that require root must check for permissions and exit clearly if absent
- Use `sc-` prefix for all libvirt resources created by the game
---
## 6. VM SAFETY RULES
- Never operate on a VM domain that does not start with `sc-`
- Never revert a snapshot during an active quest without explicit player/developer instruction
- The workstation VM (`sc-workstation`) must stay live during all gameplay — never suspend it mid-session
- If a probe or validation script fails, log the failure and return a degraded-state result — never crash the server
- All SSH connections from the host to guests use key-based auth only — no passwords in scripts
---
## 7. HOW TO HANDLE AMBIGUITY
If you are unsure whether something is correct:
1. Check `OPEN_ISSUES.md` — the answer may already be there
2. Check `docs/QUEST_AUTHORING.md` for schema rules
3. Check `content/world_flags/world_flags.json` for flag semantics
4. If still unsure, **stop and ask** rather than making an assumption
Do not proceed with a best-guess implementation of something that is in
`OPEN_ISSUES.md` as unresolved. Wait for a decision.
---
## 8. AFTER MAKING CHANGES
After any content change:
- Run `node tools/content/validate-content.js` and confirm zero errors
- If you added a world flag, confirm it appears in `world_flags.json` with correct `set_by` and `read_by`
- If you added a quest, confirm its prep script exists or is noted as pending in `OPEN_ISSUES.md`
After any server code change:
- Run `cd server && npm test` and confirm no regressions
- If you added a new validation rule type, add it to `docs/QUEST_AUTHORING.md`
After any architectural change (new route, new VM, new service, new WebSocket event):
- Update `docs/PROJECT_MAP.md` — boot flow, service graph, VM identity table, or known gaps as applicable
---
## 9. DO NOT SILENTLY FIX DESIGN ISSUES
If you discover a design inconsistency (e.g., two quests that conflict, a flag used
incorrectly, a branch that cannot be validated), do NOT silently patch it.
Instead:
1. Add it to `OPEN_ISSUES.md` with a clear description
2. Flag it in your response to the developer
3. Wait for a decision before changing any content
The exception is purely mechanical errors (typos, missing commas, wrong field
names) where the intent is unambiguous — those can be fixed directly.