{
  "repo": "tidbcloud/devops",
  "binary": "jump-pod-agent",
  "binary_path": "cmd/jump-pod-agent/main.go",
  "dependencies": {
    "JumpPodAgentLifecycle.Startup": {
      "infrastructure": {},
      "services": []
    },
    "JumpPodAgentLifecycle.InitializeStorage": {
      "infrastructure": {
        "filesystem": {
          "conditions": [
            "Always"
          ],
          "operations": [
            {
              "operation": "MKDIR",
              "trigger": "Ensure input and output directories exist before initializing the agent",
              "conditions": [
                "Always"
              ],
              "implementation": "JumpPodAgent.Init() -> os.Mkdir(inputDir/outputDir, 0777)"
            },
            {
              "operation": "WRITE FILE",
              "trigger": "Write the merged kube config after the first-time rebuild",
              "conditions": [
                "Always"
              ],
              "implementation": "KubernetesCredStore.Rebuild() -> clientcmd.WriteToFile(*final, cfgPath)"
            }
          ]
        }
      },
      "services": []
    },
    "JumpPodAgentLifecycle.StartKubernetesWatcher": {
      "infrastructure": {
        "filesystem_watch": {
          "conditions": [
            "Always"
          ],
          "operations": [
            {
              "operation": "WATCH DIRECTORY",
              "trigger": "Watch the input creds directory and rebuild on every non-Chmod fsnotify event",
              "conditions": [
                "Always"
              ],
              "implementation": "KubernetesCredStore.Init() -> fsnotify.NewWatcher(); watcher.Add(InputCredPath())"
            }
          ]
        }
      },
      "services": []
    },
    "JumpPodAgentLifecycle.StartTailscaled": {
      "infrastructure": {
        "process": {
          "conditions": [
            "Always"
          ],
          "operations": [
            {
              "operation": "EXEC",
              "trigger": "Start tailscaled as a background process and wait for /tmp/tailscaled.sock",
              "conditions": [
                "Always"
              ],
              "implementation": "TailscaleManager.StartTailscaled() -> exec.Command(\"/usr/sbin/tailscaled\", ...)"
            }
          ]
        }
      },
      "services": []
    },
    "JumpPodAgentLifecycle.StartHTTPServer": {
      "infrastructure": {
        "http_server": {
          "conditions": [
            "Always"
          ],
          "operations": [
            {
              "operation": "LISTEN",
              "trigger": "Start the jump-pod-agent HTTP listener",
              "conditions": [
                "Always"
              ],
              "implementation": "cmd/jump-pod-agent/main.go -> server.ListenAndServe()"
            }
          ]
        }
      },
      "services": []
    },
    "JumpPodAgentWatcher.OnCredDirectoryChange": {
      "infrastructure": {
        "filesystem": {
          "conditions": [
            "On fsnotify event except Chmod"
          ],
          "operations": [
            {
              "operation": "REBUILD KUBECONFIG",
              "trigger": "Rebuild the merged kube config when the watched creds directory changes",
              "conditions": [
                "On fsnotify event except Chmod"
              ],
              "implementation": "KubernetesCredStore.Init() goroutine -> s.Rebuild()"
            }
          ]
        }
      },
      "services": []
    },
    "HTTP POST /kubernetes/rebuild": {
      "infrastructure": {
        "filesystem": {
          "conditions": [
            "Always"
          ],
          "operations": [
            {
              "operation": "READ DIRECTORY",
              "trigger": "Walk every input kubeconfig file under the creds directory",
              "conditions": [
                "Always"
              ],
              "implementation": "KubernetesCredStore.Rebuild() -> filepath.Walk(s.InputCredPath(), ...)"
            },
            {
              "operation": "WRITE FILE",
              "trigger": "Persist the merged kube config to the output config path",
              "conditions": [
                "Always"
              ],
              "implementation": "KubernetesCredStore.Rebuild() -> clientcmd.WriteToFile(*final, cfgPath)"
            }
          ]
        }
      },
      "services": []
    },
    "HTTP POST /tailscale/up": {
      "infrastructure": {
        "command": {
          "conditions": [
            "Always"
          ],
          "operations": [
            {
              "operation": "EXEC /usr/bin/tailscale up",
              "trigger": "Bring the jump pod into the tailnet",
              "conditions": [
                "Always"
              ],
              "implementation": "TailscaleManager.TailscaleUp() -> tailscale --socket=/tmp/tailscaled.sock up --accept-dns=true"
            },
            {
              "operation": "ADD --hostname",
              "trigger": "Set the requested hostname on tailscale up",
              "conditions": [
                "Only when request.hostname is not empty"
              ],
              "implementation": "append --hostname <req.Hostname>"
            },
            {
              "operation": "ADD --authkey",
              "trigger": "Authenticate tailscale up with the provided auth key",
              "conditions": [
                "Only when request.authKey is not empty"
              ],
              "implementation": "append --authkey <req.AuthKey>"
            }
          ]
        }
      },
      "services": []
    },
    "HTTP POST /tailscale/down": {
      "infrastructure": {
        "command": {
          "conditions": [
            "Always"
          ],
          "operations": [
            {
              "operation": "EXEC /usr/bin/tailscale logout",
              "trigger": "Log out from the local tailscale session",
              "conditions": [
                "Always"
              ],
              "implementation": "TailscaleManager.TailscaleDown() -> tailscale --socket=/tmp/tailscaled.sock logout"
            }
          ]
        }
      },
      "services": []
    },
    "HTTP GET /tailscale/status": {
      "infrastructure": {
        "command": {
          "conditions": [
            "Always"
          ],
          "operations": [
            {
              "operation": "EXEC /usr/bin/tailscale status --json --active",
              "trigger": "Query the active tailscale status over the local socket",
              "conditions": [
                "Always"
              ],
              "implementation": "TailscaleManager.TailscaleStatus() -> tailscale --socket=/tmp/tailscaled.sock status --json --active"
            }
          ]
        }
      },
      "services": []
    }
  },
  "notes": [
    "The kube-cred rebuild path is both an explicit HTTP method and a background fsnotify side effect.",
    "tailscale commands are serialized by a mutex and always target the local tailscaled socket."
  ]
}
