{
  "id": "Q008",
  "title": "Bad Upstream",
  "tier": 2,
  "primary_vm": "web_server",
  "required_vms": ["workstation", "web_server", "build_machine"],
  "ticket_id": "T008",
  "baseline_snapshot": "baseline.post-q006",
  "summary": "The internal package repository on vulcan is serving a broken version of the axiomworks-app package. A deploy on hermes pulled it in through the internal apt repo and the app is now crashing on startup. The player needs to identify that the problem is in the package (not the app config), trace it back to vulcan, find the broken build artifact, and either roll back the package on hermes or fix the build and republish. This is the first multi-VM quest — investigation crosses from hermes to vulcan.",
  "clue_fingerprint": {
    "description": "The app service (axiomworks-app) on hermes is failing. journalctl shows it exits immediately with a non-zero code. The package was updated yesterday via the internal repo at http://vulcan.internal/repo. On vulcan, /srv/repo/axiomworks-app_2.1.1-1_amd64.deb is present but was built from a broken source tarball. The previous version 2.1.0-1 is also in /srv/repo/ and works correctly.",
    "evidence": [
      { "type": "service_state_is", "vm": "web_server", "service": "axiomworks-app", "state": "failed" },
      { "type": "log_contains", "vm": "web_server", "path": "/var/log/axiomworks-app.log", "contains": "Exec format error" },
      { "type": "file_exists", "vm": "build_machine", "path": "/srv/repo/axiomworks-app_2.1.0-1_amd64.deb" },
      { "type": "file_exists", "vm": "build_machine", "path": "/srv/repo/axiomworks-app_2.1.1-1_amd64.deb" }
    ]
  },
  "objectives": [
    {
      "id": "app-running",
      "description": "axiomworks-app is active and running",
      "check_mode": "passive",
      "validation": {
        "type": "service_state",
        "vm": "web_server",
        "service": "axiomworks-app",
        "state": "active"
      }
    },
    {
      "id": "app-port-listening",
      "description": "App is accepting connections on expected port",
      "check_mode": "passive",
      "validation": {
        "type": "port_listening",
        "vm": "web_server",
        "port": 8080,
        "protocol": "tcp",
        "listening": true
      }
    }
  ],
  "solution_branches": [
    {
      "id": "rollback-and-pin",
      "label": "Rollback to 2.1.0 and Pin Version",
      "priority": 100,
      "validation": {
        "type": "and",
        "rules": [
          { "type": "service_state", "vm": "web_server", "service": "axiomworks-app", "state": "active" },
          { "type": "port_listening", "vm": "web_server", "port": 8080, "protocol": "tcp", "listening": true },
          { "type": "package_installed", "vm": "web_server", "package": "axiomworks-app=2.1.0", "installed": true },
          { "type": "file_contains", "vm": "web_server", "path": "/etc/apt/preferences.d/axiomworks-app", "contains": "Pin: version 2.1.0" }
        ]
      },
      "trust_delta": 3,
      "world_flags": ["hermes_app_running", "hermes_app_pinned_2-1-0", "vulcan_bad_build_known"],
      "follow_up_dialogue": "marcus-Q008-complete-rollback",
      "follow_up_dialogues": ["sarah-Q008-complete-pinned"],
      "_note": "Distinguished from rollback-only by an apt pin on hermes. The player must create an apt preferences file after rolling back."
    },
    {
      "id": "rebuild-and-redeploy",
      "label": "Rebuild on Vulcan and Redeploy",
      "priority": 80,
      "validation": {
        "type": "and",
        "rules": [
          { "type": "service_state", "vm": "web_server", "service": "axiomworks-app", "state": "active" },
          { "type": "port_listening", "vm": "web_server", "port": 8080, "protocol": "tcp", "listening": true },
          { "type": "package_installed", "vm": "web_server", "package": "axiomworks-app=2.1.1", "installed": true },
          { "type": "file_exists", "vm": "build_machine", "path": "/srv/repo/axiomworks-app_2.1.1-2_amd64.deb" }
        ]
      },
      "trust_delta": 4,
      "world_flags": ["hermes_app_running", "vulcan_build_fixed"],
      "follow_up_dialogue": "marcus-Q008-complete-rebuild",
      "follow_up_dialogues": ["sarah-Q008-complete-rebuilt"],
      "_note": "Player fixed the build on vulcan and redeployed the corrected 2.1.1 package. This is the most thorough fix and gets highest trust, but is harder and requires understanding both machines. The rebuilt .deb increments the Debian revision from -1 to -2."
    },
    {
      "id": "rollback-only",
      "label": "Rollback Only — Version Not Pinned",
      "priority": 60,
      "validation": {
        "type": "and",
        "rules": [
          { "type": "service_state", "vm": "web_server", "service": "axiomworks-app", "state": "active" },
          { "type": "port_listening", "vm": "web_server", "port": 8080, "protocol": "tcp", "listening": true },
          { "type": "package_installed", "vm": "web_server", "package": "axiomworks-app=2.1.0", "installed": true },
          { "type": "not", "rule": { "type": "file_contains", "vm": "web_server", "path": "/etc/apt/preferences.d/axiomworks-app", "contains": "Pin: version 2.1.0" } }
        ]
      },
      "trust_delta": 1,
      "world_flags": ["hermes_app_running", "vulcan_bad_build_known"],
      "follow_up_incident": "I003",
      "follow_up_dialogue": "marcus-Q008-complete-unpinned",
      "follow_up_dialogues": ["sarah-Q008-complete-unpinned"],
      "_note": "App is running on 2.1.0 but not pinned. No apt preferences pin exists on hermes. The next apt upgrade will pull 2.1.1 back in. I003 re-breaks the app on the next update cycle. The not-rule on the pin file ensures this branch cannot match when rollback-and-pin already matches."
    }
  ],
  "pressure_profile": "app_outage_escalation",
  "blast_radius": ["I003"],
  "unlock_requirements": [
    "world_flag:player_ssh_configured",
    "world_flag:vulcan_ntp_healthy"
  ],
  "narrative_phase": "suspicion",
  "linux_concepts": ["apt", "package pinning", "apt preferences", "internal package mirror", "build pipeline"],
  "failure_conditions": ["axiomworks-app still broken", "bad package not traced to build machine"],
  "behavior_impact": {
    "default": { "curiosity_delta": 1, "obedience_delta": 0, "risk_delta": 0, "suspicion_delta": 0 }
  },
  "hidden_hook": {
    "id": "q008_build_log_anomaly",
    "description": "vulcan's build log for 2.1.1 shows it was triggered by a manual invocation, not the automated pipeline, at 02:14.",
    "discovery_method": "Player reads /var/log/build-pipeline.log on vulcan and notices the timestamp and manual trigger field",
    "significance": "The bad build was triggered manually. Someone made the broken build, and it was not the pipeline."
  },
  "access_requirements": {
    "minimum_access": { "build_machine": "sudo", "web_server": "sudo" },
    "requires_root": false,
    "temporary_grants_allowed": []
  },
  "tags": ["packages", "builds", "multi-vm", "web_server", "build_machine", "deploy"],
  "internal_notes": "This is the first quest that requires the player to move between two target VMs — hermes and vulcan. The symptom is on hermes but the root cause is on vulcan. Players who don't follow the package trail will spend a long time on hermes looking for a config problem that isn't there. The rebuild branch requires understanding the package build enough to fix the source input and republish a corrected .deb — it's hard but rewarding. The rollback branches are now correctly differentiated: rollback-and-pin requires an apt preferences pin on hermes, and rollback-only explicitly requires its absence via a not-rule."
}
