@nuvlore/extension-bds 0.1.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (109) hide show
  1. package/LICENSE +202 -0
  2. package/README.md +3 -0
  3. package/agents/bds-airflow-job-status-readonly.yaml +123 -0
  4. package/agents/bds-disk-investigator.yaml +112 -0
  5. package/agents/bds-inventory-readonly.yaml +60 -0
  6. package/agents/bds-oncall-reporter.yaml +113 -0
  7. package/agents/bds-prism-service-proxy-timeout-readonly.yaml +105 -0
  8. package/agents/bds-scylla-tenant-bucket-readonly.yaml +104 -0
  9. package/agents/bds-tenant-data-operation-log-readonly.yaml +98 -0
  10. package/agents/bds-yarn-app-health-readonly.yaml +114 -0
  11. package/agents/pharos-alert-investigator.yaml +81 -0
  12. package/package.json +60 -0
  13. package/skills/bds-airflow-job-status-investigation/SKILL.md +104 -0
  14. package/skills/bds-airflow-job-status-investigation/references/airflow-access-runbook.md +35 -0
  15. package/skills/bds-airflow-job-status-investigation/references/airflow-bas-dr-runbook.md +42 -0
  16. package/skills/bds-airflow-job-status-investigation/references/airflow-copy-and-migration-runbook.md +63 -0
  17. package/skills/bds-airflow-job-status-investigation/references/airflow-job-status-runbook.md +15 -0
  18. package/skills/bds-airflow-job-status-investigation/references/airflow-output-runbook.md +28 -0
  19. package/skills/bds-airflow-job-status-investigation/references/airflow-snapshot-runbook.md +38 -0
  20. package/skills/bds-disk-io-alert-investigation/SKILL.md +116 -0
  21. package/skills/bds-hadoop-review/SKILL.md +66 -0
  22. package/skills/bds-machine-inventory/SKILL.md +48 -0
  23. package/skills/bds-oncall-followup/SKILL.md +71 -0
  24. package/skills/bds-oncall-followup/references/oncall-followup-runbook.md +58 -0
  25. package/skills/bds-prism-service-proxy-timeout-investigation/SKILL.md +73 -0
  26. package/skills/bds-prism-service-proxy-timeout-investigation/references/service-proxy-timeout-runbook.md +48 -0
  27. package/skills/bds-scylla-tenant-bucket-investigation/SKILL.md +73 -0
  28. package/skills/bds-scylla-tenant-bucket-investigation/references/tenant-bucket-runbook.md +91 -0
  29. package/skills/bds-tenant-data-operation-log-investigation/SKILL.md +89 -0
  30. package/skills/bds-yarn-app-health-investigation/SKILL.md +77 -0
  31. package/skills/bds-yarn-app-health-investigation/references/yarn-app-health-runbook.md +53 -0
  32. package/skills/pharos-alert-investigation/SKILL.md +80 -0
  33. package/src/bds-atomic-log-tools.mjs +300 -0
  34. package/src/bds-team-membership-claude-output.mjs +36 -0
  35. package/src/bds-team-membership-quality.mjs +90 -0
  36. package/tools/bds_airflow_dag_log_read.mjs +24 -0
  37. package/tools/bds_airflow_job_status_command_pack.mjs +587 -0
  38. package/tools/bds_bas_log_read.mjs +23 -0
  39. package/tools/bds_bdm_httpd_log_read.mjs +24 -0
  40. package/tools/bds_chef_client_log_read.mjs +23 -0
  41. package/tools/bds_dashboard_links.mjs +178 -0
  42. package/tools/bds_dashboard_query_knowledge.mjs +258 -0
  43. package/tools/bds_dashboard_query_read.mjs +120 -0
  44. package/tools/bds_disk_io_alert_command_pack.mjs +287 -0
  45. package/tools/bds_environment_host_lookup.mjs +741 -0
  46. package/tools/bds_hdfs_datanode_log_read.mjs +23 -0
  47. package/tools/bds_hdfs_journalnode_log_read.mjs +23 -0
  48. package/tools/bds_hdfs_namenode_log_read.mjs +23 -0
  49. package/tools/bds_hdfs_path_knowledge.mjs +324 -0
  50. package/tools/bds_information_source_knowledge.mjs +356 -0
  51. package/tools/bds_kms_log_read.mjs +23 -0
  52. package/tools/bds_log_path_knowledge.mjs +267 -0
  53. package/tools/bds_machine_inventory.mjs +434 -0
  54. package/tools/bds_mapreduce_historyserver_log_read.mjs +23 -0
  55. package/tools/bds_migration_service_operation_command_pack.mjs +233 -0
  56. package/tools/bds_oncall_followup_payload_draft.mjs +285 -0
  57. package/tools/bds_pharos_query_pack.mjs +218 -0
  58. package/tools/bds_portal_operation_knowledge.mjs +212 -0
  59. package/tools/bds_prism_clone_status_links.mjs +129 -0
  60. package/tools/bds_prism_service_proxy_timeout_query_pack.mjs +224 -0
  61. package/tools/bds_public_cloud_pod_log_read.mjs +18 -0
  62. package/tools/bds_scylla_tenant_bucket_command_pack.mjs +323 -0
  63. package/tools/bds_service_proxy_log_read.mjs +23 -0
  64. package/tools/bds_spark_historyserver_log_read.mjs +32 -0
  65. package/tools/bds_spas_mt_log_read.mjs +23 -0
  66. package/tools/bds_tenant_data_operation_log_command_pack.mjs +321 -0
  67. package/tools/bds_yarn_app_health_command_pack.mjs +529 -0
  68. package/tools/bds_yarn_nodemanager_log_read.mjs +23 -0
  69. package/tools/bds_yarn_resourcemanager_log_read.mjs +23 -0
  70. package/tools/bds_zookeeper_log_read.mjs +23 -0
  71. package/tools/confluence_handoff_page_draft.mjs +173 -0
  72. package/vendor/dashboard/src/grafana-dashboard-query.mjs +61 -0
  73. package/vendor/extension-read-only-toolkit/LICENSE +202 -0
  74. package/vendor/extension-read-only-toolkit/README.md +29 -0
  75. package/vendor/extension-read-only-toolkit/package.json +46 -0
  76. package/vendor/extension-read-only-toolkit/src/devops-data-paths.mjs +222 -0
  77. package/vendor/extension-read-only-toolkit/src/devops-diagnostics.mjs +440 -0
  78. package/vendor/extension-read-only-toolkit/src/enterprise-api-read.mjs +180 -0
  79. package/vendor/extension-read-only-toolkit/src/read-only-command-pack.mjs +1 -0
  80. package/vendor/extension-read-only-toolkit/src/read-only-plan.mjs +45 -0
  81. package/vendor/extension-read-only-toolkit/src/read-only-shell-policy.d.mts +26 -0
  82. package/vendor/extension-read-only-toolkit/src/read-only-shell-policy.mjs +170 -0
  83. package/vendor/extension-workday-infra-access/LICENSE +202 -0
  84. package/vendor/extension-workday-infra-access/README.md +3 -0
  85. package/vendor/extension-workday-infra-access/agents/workday-infra-access-readonly.yaml +183 -0
  86. package/vendor/extension-workday-infra-access/package.json +49 -0
  87. package/vendor/extension-workday-infra-access/skills/workday-infra-access/SKILL.md +102 -0
  88. package/vendor/extension-workday-infra-access/skills/workday-infra-access/references/access-boundary-runbook.md +43 -0
  89. package/vendor/extension-workday-infra-access/skills/workday-infra-access/references/access-runbook.md +15 -0
  90. package/vendor/extension-workday-infra-access/skills/workday-infra-access/references/access-scylla-cloud-runbook.md +39 -0
  91. package/vendor/extension-workday-infra-access/skills/workday-infra-access/references/access-spc-argo-runbook.md +99 -0
  92. package/vendor/extension-workday-infra-access/src/workday-access-profiles.mjs +194 -0
  93. package/vendor/extension-workday-infra-access/tools/aws_cust_federated_readonly_command_pack.mjs +234 -0
  94. package/vendor/extension-workday-infra-access/tools/gcp_readonly_command_pack.mjs +167 -0
  95. package/vendor/extension-workday-infra-access/tools/public_cloud_access_status.mjs +48 -0
  96. package/vendor/extension-workday-infra-access/tools/workday_boundary_login.mjs +460 -0
  97. package/vendor/extension-workday-infra-access/tools/workday_private_cloud_sudo_readonly_command.mjs +386 -0
  98. package/vendor/extension-workday-infra-access/tools/workday_public_cloud_environment_map.mjs +189 -0
  99. package/vendor/extension-workday-infra-access/tools/workday_public_cloud_kubernetes_read.mjs +297 -0
  100. package/vendor/extension-workday-infra-access/tools/workday_public_cloud_spc_login.mjs +505 -0
  101. package/vendor/extension-workday-infra-access/tools/workday_spc_argo_readonly_command_pack.mjs +215 -0
  102. package/vendor/extension-workday-infra-access/workflows/public-cloud-readonly-investigation.js +99 -0
  103. package/workflows/bds-airflow-job-status-investigation.js +168 -0
  104. package/workflows/bds-disk-io-alert-investigation.js +173 -0
  105. package/workflows/bds-oncall-followup.js +112 -0
  106. package/workflows/bds-prism-service-proxy-timeout-investigation.js +69 -0
  107. package/workflows/bds-scylla-tenant-bucket-investigation.js +139 -0
  108. package/workflows/bds-tenant-data-operation-log-investigation.js +189 -0
  109. package/workflows/bds-yarn-app-health-investigation.js +217 -0
@@ -0,0 +1,215 @@
1
+ export const description = "Create a local-only, read-only Workday SPC + Argo UI access command pack using saved Keychain LDAP credentials; does not authenticate, port-forward, or mutate Argo/Kubernetes.";
2
+
3
+ import { z } from "zod";
4
+ import { defineReadOnlyTool, fail, ok } from "@nuvlore/extension-read-only-toolkit/devops-diagnostics";
5
+
6
+ const DEFAULT_TIER = "dev";
7
+ const DEFAULT_KEYCHAIN_SERVICE = "eldwin";
8
+ const DEFAULT_KEYCHAIN_ACCOUNT = "eldwin.workday_prod_ldap";
9
+ const DEFAULT_KUBECONFIG = "$HOME/.kube/spc-config";
10
+ const DEFAULT_ARGO_NAMESPACE = "argocdapp";
11
+ const DEFAULT_ARGO_SERVICE = "argocdapp-server";
12
+ const DEFAULT_LOCAL_PORT = 8080;
13
+
14
+ function normalizeText(value) {
15
+ return typeof value === "string" ? value.trim() : "";
16
+ }
17
+
18
+ function shellQuote(value) {
19
+ return `'${String(value).replaceAll("'", "'\\''")}'`;
20
+ }
21
+
22
+ function spcCommand(input) {
23
+ const developerFlag = input.developerAccess ? " -d" : "";
24
+ return `spc${developerFlag} connect ${shellQuote(input.tier)} ${shellQuote(input.cluster)}`;
25
+ }
26
+
27
+ function spcTtyCommand(input) {
28
+ return `/usr/bin/script -q /tmp/spc-${input.cluster}.out ${spcCommand(input)}`;
29
+ }
30
+
31
+ function portForwardCommand(input) {
32
+ return [
33
+ "kubectl",
34
+ `--kubeconfig=${input.kubeconfig}`,
35
+ "-n",
36
+ shellQuote(input.argoNamespace),
37
+ "port-forward",
38
+ `svc/${shellQuote(input.argoService)}`,
39
+ `${input.localPort}:443`
40
+ ].join(" ");
41
+ }
42
+
43
+ function argocdStatusCommands(input) {
44
+ const appNames = input.appNames.length ? input.appNames.map(shellQuote).join(" ") : "";
45
+ const appSelector = appNames || "-A";
46
+ const kubeconfig = `--kubeconfig=${input.kubeconfig}`;
47
+ return [
48
+ `kubectl ${kubeconfig} get app -n ${shellQuote(input.argoNamespace)} ${appSelector}`,
49
+ `kubectl ${kubeconfig} get app -n ${shellQuote(input.argoNamespace)} ${appSelector} -o json | jq '.items[]? // .'`,
50
+ `kubectl ${kubeconfig} get componentrelease -n ${shellQuote(input.workloadNamespace)} ${appNames || ""} -o wide`,
51
+ `kubectl ${kubeconfig} get componentrelease -n ${shellQuote(input.workloadNamespace)} ${appNames || ""} -o json | jq '.items[]? // . | {name:.metadata.name, chartVersion:.spec.chartVersion, replicas:.spec.chartValues.component.replicas, conditions:.status.conditions}'`,
52
+ `kubectl ${kubeconfig} get helmrelease -n ${shellQuote(input.workloadNamespace)} ${appNames || ""} -o json | jq '.items[]? // . | {name:.metadata.name, ownerReferences:.metadata.ownerReferences, driftDetection:.spec.driftDetection, replicas:.spec.values.component.replicas, conditions:.status.conditions}'`,
53
+ `kubectl ${kubeconfig} get deploy,statefulset -n ${shellQuote(input.workloadNamespace)} -o wide`,
54
+ `kubectl ${kubeconfig} get pods -n ${shellQuote(input.workloadNamespace)} -o wide`,
55
+ `kubectl ${kubeconfig} get svc,endpoints -n ${shellQuote(input.workloadNamespace)} -o wide`,
56
+ `kubectl ${kubeconfig} get pods -n ${shellQuote(input.workloadNamespace)} --show-labels`,
57
+ `kubectl ${kubeconfig} get hpa,vpa,scaledobject -n ${shellQuote(input.workloadNamespace)} 2>/dev/null || true`,
58
+ `kubectl ${kubeconfig} get events -n ${shellQuote(input.workloadNamespace)} --sort-by=.lastTimestamp`
59
+ ].filter((command) => !command.endsWith(" -o wide"));
60
+ }
61
+
62
+ function rbacProbeCommands(input) {
63
+ const kubeconfig = `--kubeconfig=${input.kubeconfig}`;
64
+ const namespace = shellQuote(input.workloadNamespace);
65
+ return [
66
+ `kubectl ${kubeconfig} auth whoami 2>&1 || true`,
67
+ `kubectl ${kubeconfig} auth can-i patch deployments/scale -n ${namespace}`,
68
+ `kubectl ${kubeconfig} auth can-i patch deployments -n ${namespace}`,
69
+ `kubectl ${kubeconfig} auth can-i patch componentreleases.component.workday.com -n ${namespace}`,
70
+ `kubectl ${kubeconfig} auth can-i patch helmreleases.helm.toolkit.fluxcd.io -n ${namespace}`
71
+ ];
72
+ }
73
+
74
+ function smokeDependencyCommands(input) {
75
+ const kubeconfig = `--kubeconfig=${input.kubeconfig}`;
76
+ const namespace = shellQuote(input.workloadNamespace);
77
+ return [
78
+ `kubectl ${kubeconfig} get pods -n ${namespace} -l name=prism -o wide`,
79
+ `kubectl ${kubeconfig} get deploy -n ${namespace} -l name=prism -o wide`,
80
+ `kubectl ${kubeconfig} get svc,endpoints -n ${namespace} | grep -E 'prism|NAME' || true`
81
+ ];
82
+ }
83
+
84
+ function componentControllerCommands(input) {
85
+ const kubeconfig = `--kubeconfig=${input.kubeconfig}`;
86
+ return [
87
+ `kubectl ${kubeconfig} get crd componentreleases.component.workday.com -o json | jq '.spec.versions[]? | select(.served==true) | .schema.openAPIV3Schema.properties.spec.properties | keys'`,
88
+ `kubectl ${kubeconfig} -n isd-component-controller get deploy isd-component-controller-controller-manager -o json | jq '{image:.spec.template.spec.containers[0].image,args:.spec.template.spec.containers[0].args,labels:.metadata.labels}'`,
89
+ `kubectl ${kubeconfig} -n isd-component-controller get configmap isd-component-controller-component-controller-config -o json | jq -r '.data | to_entries[] | .value'`
90
+ ];
91
+ }
92
+
93
+ function normalizeInput(input = {}) {
94
+ const appNames = Array.isArray(input.appNames)
95
+ ? input.appNames.map(normalizeText).filter(Boolean)
96
+ : [];
97
+ const tier = normalizeText(input.tier ?? input.domain) || DEFAULT_TIER;
98
+ const developerAccess = typeof input.developerAccess === "boolean"
99
+ ? input.developerAccess
100
+ : ["dev", "eng"].includes(tier);
101
+ return {
102
+ cluster: normalizeText(input.cluster),
103
+ tier,
104
+ developerAccess,
105
+ workloadNamespace: normalizeText(input.workloadNamespace) || "bds",
106
+ argoNamespace: normalizeText(input.argoNamespace) || DEFAULT_ARGO_NAMESPACE,
107
+ argoService: normalizeText(input.argoService) || DEFAULT_ARGO_SERVICE,
108
+ keychainService: DEFAULT_KEYCHAIN_SERVICE,
109
+ keychainAccount: DEFAULT_KEYCHAIN_ACCOUNT,
110
+ kubeconfig: normalizeText(input.kubeconfig) || DEFAULT_KUBECONFIG,
111
+ localPort: Number.isInteger(input.localPort) ? input.localPort : DEFAULT_LOCAL_PORT,
112
+ appNames
113
+ };
114
+ }
115
+
116
+ export class WorkdaySpcArgoReadonlyPlanService {
117
+ invoke(input) {
118
+ const normalized = normalizeInput(input);
119
+ if (!normalized.cluster) {
120
+ throw new Error("cluster is required, for example proteusaws00020.");
121
+ }
122
+
123
+ return JSON.stringify({
124
+ mode: "atomic-helper",
125
+ target: {
126
+ cluster: normalized.cluster,
127
+ tier: normalized.tier,
128
+ developerAccess: normalized.developerAccess,
129
+ workloadNamespace: normalized.workloadNamespace,
130
+ argoNamespace: normalized.argoNamespace,
131
+ argoService: normalized.argoService,
132
+ appNames: normalized.appNames
133
+ },
134
+ credentialSource: {
135
+ keychainService: normalized.keychainService,
136
+ keychainAccount: normalized.keychainAccount,
137
+ secretHandling: "do not read PROD password in this command pack; use workday_public_cloud_spc_login for SPC login"
138
+ },
139
+ localStateChanges: [
140
+ "spc may open a local session and update local kubeconfig/context state",
141
+ "spc connectivity does not grant Kubernetes RBAC; verify the resulting identity with kubectl auth whoami and can-i",
142
+ "kubectl port-forward opens a localhost listener only"
143
+ ],
144
+ commands: {
145
+ publicCloudLoginTool: `mcp__devops-tool__workday_public_cloud_spc_login ${JSON.stringify({ action: "login", tier: normalized.tier, cluster: normalized.cluster, namespace: normalized.workloadNamespace, humanApprovedLocalWrite: true })}`,
146
+ spcConnect: spcCommand(normalized),
147
+ spcConnectTty: spcTtyCommand(normalized),
148
+ argoPortForward: portForwardCommand(normalized),
149
+ argoUiUrl: `https://localhost:${normalized.localPort}/`,
150
+ readOnlyStatus: argocdStatusCommands(normalized),
151
+ smokeDependencies: smokeDependencyCommands(normalized),
152
+ rbacProbes: rbacProbeCommands(normalized),
153
+ componentControllerStatus: componentControllerCommands(normalized)
154
+ },
155
+ forbiddenActions: [
156
+ "Argo Sync",
157
+ "Argo Hard Refresh",
158
+ "Argo Delete",
159
+ "Argo Rollback",
160
+ "Kubernetes Scale",
161
+ "Kubernetes Patch",
162
+ "Kubernetes Restart"
163
+ ],
164
+ remoteWrite: "not_executed"
165
+ }, null, 2);
166
+ }
167
+ }
168
+
169
+ const defaultService = new WorkdaySpcArgoReadonlyPlanService();
170
+
171
+ function workdaySpcArgoReadonlyPlan(input) {
172
+ return defaultService.invoke(input);
173
+ }
174
+
175
+ export default defineReadOnlyTool({
176
+ name: "workday_spc_argo_readonly_command_pack",
177
+ description: "Create a local-only, read-only Workday SPC + Argo UI access command pack using saved Keychain LDAP credentials; does not authenticate, port-forward, or mutate Argo/Kubernetes.",
178
+ meta: {
179
+ permissions: { rule: "ask" },
180
+ secret_provider: "keychain"
181
+ },
182
+ inputSchema: {
183
+ cluster: z.string().trim().min(1).max(253),
184
+ domain: z.string().trim().min(1).max(64).optional().describe("Deprecated alias for tier. Use tier for the current SPC CLI shape."),
185
+ tier: z.string().trim().min(1).max(64).default(DEFAULT_TIER),
186
+ developerAccess: z.boolean().optional(),
187
+ workloadNamespace: z.string().trim().min(1).max(253).default("bds"),
188
+ argoNamespace: z.string().trim().min(1).max(253).default(DEFAULT_ARGO_NAMESPACE),
189
+ argoService: z.string().trim().min(1).max(253).default(DEFAULT_ARGO_SERVICE),
190
+ appNames: z.array(z.string().trim().min(1).max(253)).max(32).default([]),
191
+ kubeconfig: z.string().trim().min(1).max(2048).default(DEFAULT_KUBECONFIG),
192
+ localPort: z.number().int().min(1024).max(65535).default(DEFAULT_LOCAL_PORT)
193
+ },
194
+ async handler(input) {
195
+ try {
196
+ return ok(workdaySpcArgoReadonlyPlan(input));
197
+ } catch (error) {
198
+ return fail(error);
199
+ }
200
+ }
201
+ });
202
+
203
+ export const __test = {
204
+ WorkdaySpcArgoReadonlyPlanService,
205
+ normalizeInput,
206
+ shellQuote,
207
+ spcCommand,
208
+ spcTtyCommand,
209
+ portForwardCommand,
210
+ argocdStatusCommands,
211
+ smokeDependencyCommands,
212
+ rbacProbeCommands,
213
+ componentControllerCommands,
214
+ workdaySpcArgoReadonlyPlan
215
+ };
@@ -0,0 +1,99 @@
1
+ export const meta = {
2
+ name: "public-cloud-readonly-investigation",
3
+ description: "Investigate AWS CUST or GCP cloud state through approved federation/local identity and read-only evidence commands only.",
4
+ whenToUse: "Use when an incident, Bamboo result, Slack thread, or operator request requires AWS CUST or GCP resource inspection without cloud mutation.",
5
+ phases: ["Plan", "Identity", "Evidence", "Reply"],
6
+ };
7
+
8
+ phase("Plan");
9
+ const plan = await agent(
10
+ [
11
+ "Extract platform, account/account alias or GCP project, region/zone, service, resource, and incident evidence.",
12
+ "For AWS CUST federated access, call only mcp__devops_tool__aws_cust_federated_readonly_command_pack.",
13
+ "For GCP, call only mcp__devops_tool__gcp_readonly_command_pack.",
14
+ "If the platform is ambiguous, report that blocker and do not guess.",
15
+ "Do not authenticate, open browser federation, read credential files, use Bash, or call cloud APIs in this phase.",
16
+ ].join("\n"),
17
+ {
18
+ label: "public-cloud-plan",
19
+ phase: "Plan",
20
+ tools: "mcp__devops_tool__aws_cust_federated_readonly_command_pack,mcp__devops_tool__gcp_readonly_command_pack",
21
+ disallowedTools: "Agent,Task,TaskCreate,Bash,Read,Glob,Grep,WebFetch,WebSearch,Write,Edit,NotebookEdit,AskUserQuestion",
22
+ },
23
+ );
24
+
25
+ phase("Identity");
26
+ const identity = await agent(
27
+ [
28
+ "Verify identity only after approved local federation/login outside this workflow.",
29
+ "For AWS, run the plan's aws sts get-caller-identity via permitted local read-only execution.",
30
+ "For GCP, run the plan's gcloud auth list and gcloud config list via permitted local read-only execution.",
31
+ "If local execution is unavailable or denied, return the exact identity command that must be run manually and mark identity as unverified.",
32
+ "Never run aws configure, gcloud auth login, gcloud config set, or read ~/.aws, ADC, or credential files.",
33
+ "",
34
+ "Plan:",
35
+ plan,
36
+ ].join("\n"),
37
+ {
38
+ label: "public-cloud-identity",
39
+ phase: "Identity",
40
+ tools: "",
41
+ disallowedTools: "Agent,Task,TaskCreate,WebFetch,WebSearch,Write,Edit,NotebookEdit,AskUserQuestion",
42
+ },
43
+ );
44
+
45
+ phase("Evidence");
46
+ const evidence = await agent(
47
+ [
48
+ "Collect read-only cloud evidence using commands emitted by the plan.",
49
+ "Allowed action families are describe, list, get metadata, head, read logs, and get-iam-policy.",
50
+ "For AWS S3, never run cp, mv, rm, sync, put-object, delete-object, or get-object for secrets/private material.",
51
+ "For GCP Storage, never run cp, mv, rm, update, compose, or rewrite.",
52
+ "For IAM/KMS/Secrets Manager, read metadata only; never request secret values, private keys, or key material.",
53
+ "If a command is denied by the read-only runtime or cloud IAM, preserve the denied action as an evidence gap.",
54
+ "",
55
+ "Plan:",
56
+ plan,
57
+ "",
58
+ "Identity:",
59
+ identity,
60
+ ].join("\n"),
61
+ {
62
+ label: "public-cloud-evidence",
63
+ phase: "Evidence",
64
+ tools: "",
65
+ disallowedTools: "Agent,Task,TaskCreate,WebFetch,WebSearch,Write,Edit,NotebookEdit,AskUserQuestion",
66
+ },
67
+ );
68
+
69
+ phase("Reply");
70
+ const reply = await agent(
71
+ [
72
+ "Draft a concise answer from collected cloud evidence only.",
73
+ "State platform, account/project, identity state, commands run/blocked, observations, and evidence gaps.",
74
+ "Distinguish IAM/access denial from resource absence.",
75
+ "State remediation only as a human-reviewed manual recommendation; do not execute writes.",
76
+ "",
77
+ "Plan:",
78
+ plan,
79
+ "",
80
+ "Identity:",
81
+ identity,
82
+ "",
83
+ "Evidence:",
84
+ evidence,
85
+ ].join("\n"),
86
+ {
87
+ label: "public-cloud-reply",
88
+ phase: "Reply",
89
+ tools: "",
90
+ disallowedTools: "Agent,Task,TaskCreate,Bash,Read,Glob,Grep,WebFetch,WebSearch,Write,Edit,NotebookEdit,AskUserQuestion",
91
+ },
92
+ );
93
+
94
+ return {
95
+ plan,
96
+ identity,
97
+ evidence,
98
+ reply,
99
+ };
@@ -0,0 +1,168 @@
1
+ export const meta = {
2
+ name: "bds-airflow-job-status-investigation",
3
+ description: "Investigate BDS datacenter Airflow job status with read-only Kubernetes control-plane and airflow namespace evidence.",
4
+ whenToUse: "Use when BDS jobs run through Airflow and the requester provides or implies an environment JSON with Kubernetes control-plane hosts.",
5
+ phases: ["Plan", "ResolveHost", "Access", "Kubernetes", "Airflow", "Reply"],
6
+ };
7
+
8
+ phase("Plan");
9
+ const plan = await agent(
10
+ [
11
+ "Extract environment/config path, airflow namespace, DAG/run ids, tenant, timestamps, Jira/Slack links, and incident type.",
12
+ "Before local BDS config or Airflow code reads, run git pull --ff-only; if dirty, report the gap without stash/reset/overwrite.",
13
+ "Use the skill flow as the procedure; call bds_airflow_job_status_command_pack so kubernetes.kube_control_planes and the current BDS_ATL_CUST_AZ1 hosts are normalized into read-only command inputs.",
14
+ "For migration-service Slack incidents, also call bds_migration_service_operation_command_pack for migration records, Jira/cutover state, and recovery validation.",
15
+ "For bas_dr_sla_miss, snapshot cleanup, or PRISM timeout, plan only bounded read-only evidence: affected tenants, worker/runtime hints, cookbook_bitbucket schedule, top Airflow delete durations, NameNode long write-lock stack, and hourly hdfs-audit.log correlation.",
16
+ "Do not run mutating kubectl, helm, Airflow, host, or HDFS commands.",
17
+ "Return parsed fields, missing fields, and command-pack output.",
18
+ ].join("\n"),
19
+ {
20
+ label: "bds-airflow-plan",
21
+ phase: "Plan",
22
+ tools: "mcp__devops_tool__bds_airflow_job_status_command_pack,mcp__devops_tool__bds_migration_service_operation_command_pack",
23
+ disallowedTools: "Agent,Task,TaskCreate,Bash,WebFetch,WebSearch,Write,Edit,NotebookEdit,AskUserQuestion",
24
+ },
25
+ );
26
+
27
+ phase("ResolveHost");
28
+ const resolvedHost = await agent(
29
+ [
30
+ "Resolve the concrete BDS Kubernetes control-plane host before Boundary login or remote commands.",
31
+ "Use the exact host lookup tool mcp__devops_tool__bds_environment_host_lookup with the BDS cluster/environment and roles=[\"airflow\",\"kube_control_planes\",\"tenant_data_operation\"].",
32
+ "Prefer refreshed environment inventory over stale Slack/Jira hostnames; keep configJsonPath, cluster, namespace, controlPlaneHost, worker hints, and any alert Source label separate.",
33
+ "If the command pack already returned controlPlaneHosts, confirm them against host lookup instead of assuming they are current.",
34
+ "Do not invent host tools such as workday_host_info, host_info, host_query, or bds_enterprise_host_lookup.",
35
+ "Do not use grep, ls, Read, Glob, repository search, local /hadoop paths, or local kubectl as a substitute for host lookup.",
36
+ "If the exact host lookup MCP tool is unavailable or fails, stop and report the exact tool error as a tooling/access gap.",
37
+ "Return controlPlaneHost, cluster/environment, namespace, lookup evidence, stale host exclusions, and ambiguity.",
38
+ "",
39
+ "Plan:",
40
+ plan,
41
+ ].join("\n"),
42
+ {
43
+ label: "bds-airflow-resolve-host",
44
+ phase: "ResolveHost",
45
+ tools: "mcp__devops_tool__bds_environment_host_lookup,mcp__devops_tool__bds_machine_inventory",
46
+ disallowedTools: "Agent,Task,TaskCreate,Bash,Read,Glob,Grep,WebFetch,WebSearch,Write,Edit,NotebookEdit,AskUserQuestion,mcp__devops_tool__workday_boundary_login,mcp__devops_tool__remote_readonly_command",
47
+ },
48
+ );
49
+
50
+ phase("Access");
51
+ const access = await agent(
52
+ [
53
+ "Use the resolved controlPlaneHost only; for ATL trust the refreshed BDS_ATL_CUST_AZ1 config host over stale names.",
54
+ "Private cloud uses bauth init and ordinary ssh to the explicit host. On banner timeout, retry with the explicit proxy jump host proxy-jump.atl.bnd; do not invent .bnd service-host aliases.",
55
+ "Confirm hostname, UTC clock, user, and kubeconfig behavior with remote_readonly_command.",
56
+ "If normal-user kubectl hits localhost:8080, record it and continue only with approved root read-only checks.",
57
+ "If sudo needs stdin, use only mcp__devops_tool__workday_private_cloud_sudo_readonly_command; agents and command packs must not read Keychain directly.",
58
+ "Never print LDAP passwords, Keychain JSON, tokens, kubeconfig, or sudo stdin.",
59
+ "",
60
+ "Plan:",
61
+ plan,
62
+ "",
63
+ "ResolvedHost:",
64
+ resolvedHost,
65
+ ].join("\n"),
66
+ {
67
+ label: "bds-airflow-access",
68
+ phase: "Access",
69
+ tools: "mcp__devops_tool__workday_boundary_login,mcp__devops_tool__remote_readonly_command",
70
+ disallowedTools: "Agent,Task,TaskCreate,Bash,WebFetch,WebSearch,Write,Edit,NotebookEdit,AskUserQuestion",
71
+ },
72
+ );
73
+
74
+ phase("Kubernetes");
75
+ const kubernetes = await agent(
76
+ [
77
+ "Collect read-only Kubernetes evidence from the airflow namespace: pods -o wide, workloads, describe summaries, and recent events.",
78
+ "For bas_dr_sla_miss, capture DR pod node placement, deletionTimestamp/finalizers/events, and whether any Running pod is actively progressing before remediation guidance.",
79
+ "Do not infer job health from default namespace output.",
80
+ "Do not use kubectl delete/apply/patch/scale/rollout restart/exec mutations or helm writes. Do not stop host processes, restart kubelet/containerd, or uncordon nodes.",
81
+ "",
82
+ "Plan:",
83
+ plan,
84
+ "",
85
+ "ResolvedHost:",
86
+ resolvedHost,
87
+ "",
88
+ "Access:",
89
+ access,
90
+ ].join("\n"),
91
+ {
92
+ label: "bds-airflow-kubernetes",
93
+ phase: "Kubernetes",
94
+ tools: "mcp__devops_tool__remote_readonly_command",
95
+ disallowedTools: "Agent,Task,TaskCreate,Bash,WebFetch,WebSearch,Write,Edit,NotebookEdit,AskUserQuestion",
96
+ },
97
+ );
98
+
99
+ phase("Airflow");
100
+ const airflow = await agent(
101
+ [
102
+ "Collect bounded Airflow scheduler/web logs and read-only metadata only.",
103
+ "Separate healthy components from DAG/config risk: Running/Ready pods, zero restarts, Events:<none>, and /airflow/health HTTP 200 do not clear DagBag Failed to import or FileNotFoundError config issues.",
104
+ "Treat Prometheus response.WriteHeader and sensu read-only filesystem chown lines as noise unless restarts/readiness/container errors also appear.",
105
+ "If a control-panel id like dag_tenant_data_copy_on_demand--1780713387370568 misses metadata, convert epoch microseconds to UTC and read /data/workday-bds-airflow/logs/dag_tenant_data_copy_on_demand/manual__<UTC_ISO>/run_tenant_data_ondemand_restore_copy/1.log.",
106
+ "For tenant copy, use Running command, src/dst clusters, source snapshot/path, Submitted application, map progress, return code, and Marking task as SUCCESS.",
107
+ "For bas_dr_sla_miss, read affected DR task logs for success/failure markers, DistCp/YARN ids, snapshots, stale completed pods, and active Running pods.",
108
+ "For bad worker zombie/runtime evidence, collect read-only uptime/load, D/Z or zombie processes, kubelet/containerd timeout, and stuck runc/mount/cgroup cleanup facts.",
109
+ "After approved operator cleanup only, verify healthy-worker replacement pods, newer mirror snapshots, task success, and BAS lag below 3600 seconds.",
110
+ "For current BDS_ASH_CUST_AZ1 bas_dr_sla_miss count, read s-11rdzb3.sys.az1.cust.ash.wd and run sudo /data/pharos_script_exporter/scripts/bas_dr_sla_miss_metric.rb BDS_ASH_CUST_AZ1; report total, missed >3600, max lag/tenant, and top tenants.",
111
+ "For migration copy/cutover, read migration-service/Airflow callbacks and tenant records for last good/failed snapshot, file counts, state, HDFS authority such as hdfs://bdsatlcustaz11, and Only cutover run allowed state-machine evidence.",
112
+ "For a long-running task pod, extract tenant/process, src/dst clusters, source snapshot, HDFS paths, YARN app id, and latest DistCp map progress; classify progressing Ready pods as slow copy, not Airflow failure.",
113
+ "For snapshot cleanup, read cookbook_bitbucket schedule/timeout, top Airflow delete durations, active NameNode FSNamesystem.deleteSnapshot long write-lock stack, and hourly hdfs-audit.log delete/read-RPC correlation.",
114
+ "Classify backlog or large diff cleanup only when repeated snapshot deletions, elevated durations, matching write locks, and blocked read RPCs align; state direct diff-size evidence gaps unless proven.",
115
+ "Explain getFileInfo/getfileinfo, listStatus, open, and getBlockLocations as read-lock RPCs queued behind deleteSnapshot write locks.",
116
+ "Never run airflow clear, backfill, pause/unpause, trigger, mark_success, or any state mutation.",
117
+ "",
118
+ "Kubernetes:",
119
+ kubernetes,
120
+ ].join("\n"),
121
+ {
122
+ label: "bds-airflow-runtime",
123
+ phase: "Airflow",
124
+ tools: "mcp__devops_tool__remote_readonly_command",
125
+ disallowedTools: "Agent,Task,TaskCreate,Bash,WebFetch,WebSearch,Write,Edit,NotebookEdit,AskUserQuestion",
126
+ },
127
+ );
128
+
129
+ phase("Reply");
130
+ const reply = await agent(
131
+ [
132
+ "Draft a concise requester-ready answer from evidence only.",
133
+ "Include host, kubeconfig/root context, airflow pods/workloads, events/logs, DAG/run state, and exact gaps.",
134
+ "For tenant copy, include src/dst clusters and paths, source snapshot, tenant/env, YARN app id, and latest progress.",
135
+ "For bas_dr_sla_miss, include affected tenants, stale snapshot time, stuck pod/node, log markers, bad worker zombie/runtime evidence, approved-only force-delete/cordon path, replacement pod, mirror snapshot, and live BAS count from s-11rdzb3 versus 3600 seconds.",
136
+ "For migration-service Slack incidents, include event ids, failed copy record, endpoint comparison, cutover status, file counts, bucket sync, PRISM_READY, and COMPLETED.",
137
+ "For snapshot cleanup, include cookbook_bitbucket cron/timeout, top deleteSnapshot durations, tenant/snapshot backlog, NameNode write-lock stack, hourly hdfs-audit.log paths, metadata RPCs, direct diff-size evidence gaps, and timeout boundary.",
138
+ "Separate Airflow component health from DAG/config risks in the conclusion.",
139
+ "Do not claim job health from the default namespace alone.",
140
+ "",
141
+ "Plan:",
142
+ plan,
143
+ "",
144
+ "ResolvedHost:",
145
+ resolvedHost,
146
+ "",
147
+ "Kubernetes:",
148
+ kubernetes,
149
+ "",
150
+ "Airflow:",
151
+ airflow,
152
+ ].join("\n"),
153
+ {
154
+ label: "bds-airflow-reply",
155
+ phase: "Reply",
156
+ tools: "",
157
+ disallowedTools: "Agent,Task,TaskCreate,Bash,WebFetch,WebSearch,Write,Edit,NotebookEdit,AskUserQuestion",
158
+ },
159
+ );
160
+
161
+ return {
162
+ plan,
163
+ resolvedHost,
164
+ access,
165
+ kubernetes,
166
+ airflow,
167
+ reply,
168
+ };
@@ -0,0 +1,173 @@
1
+ export const meta = {
2
+ name: "bds-disk-io-alert-investigation",
3
+ description: "Investigate BDS storage alerts from the source host with read-only filesystem, kernel, Dell storage, HDFS DataNode failed-volume, and RCA evidence.",
4
+ whenToUse: "Use when Slack/PagerDuty reports a BDS storage symptom: kernel disk IO errors, medium errors, bad blocks, HDFS DataNode failed volumes, PERC virtual disk issues, or predictive disk failure on a BDS host.",
5
+ ownershipExamples: [
6
+ "A DataNode failed-volume alert with a BDS cluster and source host starts here because the first evidence boundary is host storage state.",
7
+ "A disk alert should not start in Scylla tenant-bucket, Airflow job-status, or generic YARN workflows unless storage evidence points there.",
8
+ "Resolve the evidence target host before access: active DataNode text, alert Source label, cluster, namespace, and disk path are not always the same signal.",
9
+ "Private-cloud/DC host access must pass the Workday Boundary login gate before any remote host reads."
10
+ ],
11
+ phases: ["Plan", "ResolveHost", "Access", "Host", "Storage", "RCA"],
12
+ };
13
+
14
+ phase("Plan");
15
+ const plan = await agent(
16
+ [
17
+ "Extract alertName, cluster, sourceHost, severity, and alert time.",
18
+ "Preserve all host-like fields separately: active DataNode, alert Source label, namespace, cluster, and disk path.",
19
+ "Classify the symptom by operational domain. If it is DataNode failed volumes or host storage risk, keep this disk workflow as the primary path.",
20
+ "Use the skill flow as the procedure; call only mcp__devops_tool__bds_disk_io_alert_command_pack to normalize inputs and produce the read-only command pack.",
21
+ "No Bash, browser access, WebFetch, local reproduction, or mutating storage commands.",
22
+ "Return parsed alert fields, command-pack output, and missing fields.",
23
+ ].join("\n"),
24
+ {
25
+ label: "bds-disk-plan",
26
+ phase: "Plan",
27
+ tools: "mcp__devops_tool__bds_disk_io_alert_command_pack",
28
+ disallowedTools: "Bash,Read,Glob,Grep,WebFetch,WebSearch,Write,Edit,NotebookEdit,AskUserQuestion",
29
+ },
30
+ );
31
+
32
+ phase("ResolveHost");
33
+ const resolvedHost = await agent(
34
+ [
35
+ "Resolve the concrete BDS host to inspect before any access or SSH attempt.",
36
+ "For DataNode failed-volume alerts, prefer the active DataNode host from the alert sentence as the evidenceTargetHost; keep the alert Source label as alertSourceLabel unless lookup evidence proves it is the same host.",
37
+ "The required first host lookup tool name is exactly mcp__devops_tool__bds_environment_host_lookup. Call it for the BDS cluster with roles=[\"datanodes\"]. Call mcp__devops_tool__bds_machine_inventory only when broader inventory confirmation is needed.",
38
+ "Do not invent or call non-existent tools such as workday_host_info, host_info, host_query, or bds_enterprise_host_lookup.",
39
+ "Do not use grep, ls, Read, Glob, or repository searches to discover host tools or host records. The authoritative host lookup path is the MCP tool call above.",
40
+ "Treat disk paths such as /hadoop/disk5/dfs/dn as remote paths on the resolved DataNode. Never run local execute/Bash/ls against those paths.",
41
+ "If the exact host lookup MCP tool is unavailable or fails, stop and report the tool error as an access/tooling gap; do not fall back to local filesystem checks.",
42
+ "Return evidenceTargetHost, alertSourceLabel, cluster, namespace, diskPath, lookup evidence, and any ambiguity. Do not run SSH, Boundary login, Bash, or remote commands in this phase.",
43
+ "",
44
+ "Plan:",
45
+ plan,
46
+ ].join("\n"),
47
+ {
48
+ label: "bds-disk-resolve-host",
49
+ phase: "ResolveHost",
50
+ tools: "mcp__devops_tool__bds_environment_host_lookup,mcp__devops_tool__bds_machine_inventory",
51
+ disallowedTools: "Bash,Read,Glob,Grep,WebFetch,WebSearch,Write,Edit,NotebookEdit,AskUserQuestion,mcp__devops_tool__remote_readonly_command,mcp__devops_tool__workday_boundary_login",
52
+ },
53
+ );
54
+
55
+ phase("Access");
56
+ const access = await agent(
57
+ [
58
+ "Check private-cloud/DC host access before any remote host evidence, using the resolved evidenceTargetHost.",
59
+ "Use workday_boundary_login action=status first.",
60
+ "If Boundary/SSHCA is not ready, run workday_boundary_login action=login only when the current operator has explicitly approved local auth-state preparation.",
61
+ "Private cloud uses bauth init plus ordinary ssh to the explicit host; do not use SPC and do not invent .bnd service-host aliases.",
62
+ "If login is still not ready, stop host evidence collection and return the exact access gap.",
63
+ "",
64
+ "Plan:",
65
+ plan,
66
+ "",
67
+ "Resolved host:",
68
+ resolvedHost,
69
+ ].join("\n"),
70
+ {
71
+ label: "bds-disk-access",
72
+ phase: "Access",
73
+ tools: "mcp__devops_tool__workday_boundary_login",
74
+ disallowedTools: "Bash,Read,Glob,Grep,WebFetch,WebSearch,Write,Edit,NotebookEdit,AskUserQuestion,mcp__devops_tool__remote_readonly_command",
75
+ },
76
+ );
77
+
78
+ phase("Host");
79
+ const host = await agent(
80
+ [
81
+ "Collect read-only host and filesystem evidence from the resolved evidenceTargetHost, not from an unverified alert Source label.",
82
+ "Proceed only after the Access phase reports Boundary/SSHCA readiness or an approved successful login.",
83
+ "Use remote_readonly_command for the remote DataNode path; never run local execute/Bash/ls for /hadoop paths.",
84
+ "Use remote_readonly_command for host identity, UTC time, boot time, lsblk, df, findmnt, and iostat.",
85
+ "Do not unmount, repair, format, restart services, stop workloads, write files, or change disk state.",
86
+ "Return observations, command labels, timestamps, and evidence gaps.",
87
+ "",
88
+ "Plan:",
89
+ plan,
90
+ "",
91
+ "Resolved host:",
92
+ resolvedHost,
93
+ "",
94
+ "Access:",
95
+ access,
96
+ ].join("\n"),
97
+ {
98
+ label: "bds-disk-host",
99
+ phase: "Host",
100
+ tools: "mcp__devops_tool__remote_readonly_command",
101
+ disallowedTools: "WebFetch,WebSearch,Write,Edit,NotebookEdit,AskUserQuestion",
102
+ },
103
+ );
104
+
105
+ phase("Storage");
106
+ const storage = await agent(
107
+ [
108
+ "Collect read-only storage evidence from kernel journal and Dell storage tools.",
109
+ "Prefer non-sudo omreport reads for controller, virtual disk, physical disk, and alert log.",
110
+ "Use sudo only for bounded read-only journalctl -k if the operator explicitly approved sudo.",
111
+ "Never clear logs, mark disks offline, start rebuilds, change RAID state, run fsck, or repair filesystems.",
112
+ "Return only raw observations, UTC timestamps, and command labels.",
113
+ "",
114
+ "Plan:",
115
+ plan,
116
+ "",
117
+ "Resolved host:",
118
+ resolvedHost,
119
+ "",
120
+ "Access:",
121
+ access,
122
+ "",
123
+ "Host:",
124
+ host,
125
+ ].join("\n"),
126
+ {
127
+ label: "bds-disk-storage",
128
+ phase: "Storage",
129
+ tools: "mcp__devops_tool__remote_readonly_command",
130
+ disallowedTools: "WebFetch,WebSearch,Write,Edit,NotebookEdit,AskUserQuestion",
131
+ },
132
+ );
133
+
134
+ phase("RCA");
135
+ const rca = await agent(
136
+ [
137
+ "Draft a concise Markdown RCA from the collected evidence only.",
138
+ "Include Summary, Evidence table, Timeline, Current State, and Recommendation.",
139
+ "State root cause with confidence and distinguish direct evidence from inference.",
140
+ "Include OS device, mount point, virtual disk, RAID layout, bad-block state, physical disk ID, Failure Predicted, serial, and part number when available.",
141
+ "List follow-ups as manual human-reviewed recommendations only.",
142
+ "",
143
+ "Plan:",
144
+ plan,
145
+ "",
146
+ "Resolved host:",
147
+ resolvedHost,
148
+ "",
149
+ "Access:",
150
+ access,
151
+ "",
152
+ "Host:",
153
+ host,
154
+ "",
155
+ "Storage:",
156
+ storage,
157
+ ].join("\n"),
158
+ {
159
+ label: "bds-disk-rca",
160
+ phase: "RCA",
161
+ tools: "",
162
+ disallowedTools: "Bash,Read,Glob,Grep,WebFetch,WebSearch,Write,Edit,NotebookEdit,AskUserQuestion",
163
+ },
164
+ );
165
+
166
+ return {
167
+ plan,
168
+ resolvedHost,
169
+ access,
170
+ host,
171
+ storage,
172
+ rca,
173
+ };