Coverage for gco_mcp / resources / docs.py: 100.00%

371 statements  

« prev     ^ index     » next       coverage.py v7.13.5, created at 2026-10-28 16:19 +0000

1"""Documentation resources (docs:// scheme) for the GCO MCP server.""" 

2 

3import re 

4from pathlib import Path 

5 

6from cli_runner import PROJECT_ROOT # runtime-resolved checkout root (uvx-safe) 

7from server import mcp 

8 

9DOCS_DIR = PROJECT_ROOT / "docs" 

10EXAMPLES_DIR = PROJECT_ROOT / "examples" 

11ADR_DIR = DOCS_DIR / "adr" 

12 

13# --------------------------------------------------------------------------- 

14# Example metadata — used by both the index and the per-example resource to 

15# give the LLM rich context about what each manifest does and how to adapt it. 

16# --------------------------------------------------------------------------- 

17 

18EXAMPLE_METADATA: dict[str, dict[str, str | list[str]]] = { 

19 "simple-job": { 

20 "category": "Jobs & Training", 

21 "summary": "Basic Kubernetes Job that runs a command and completes. Start here to verify your cluster.", 

22 "gpu": "no", 

23 "opt_in": "", 

24 "submission": "gco jobs submit-sqs examples/simple-job.yaml --region us-east-1", 

25 "keywords": ["simple", "hello", "starter", "basic", "smoke test"], 

26 "instance_types": [], 

27 "use_cases": [ 

28 "verify cluster setup", 

29 "smoke test a new region", 

30 "minimal job example", 

31 ], 

32 "related": ["gpu-job", "sqs-job-submission"], 

33 }, 

34 "gpu-job": { 

35 "category": "Jobs & Training", 

36 "summary": "Requests GPU resources and runs on GPU-enabled nodes.", 

37 "gpu": "NVIDIA", 

38 "opt_in": "", 

39 "submission": "gco jobs submit-sqs examples/gpu-job.yaml --region us-east-1", 

40 "keywords": [ 

41 "gpu", 

42 "nvidia", 

43 "cuda", 

44 "single gpu", 

45 "nvidia.com/gpu", 

46 "g5", 

47 "g6", 

48 "g4dn", 

49 "tolerations", 

50 ], 

51 "instance_types": ["g5.xlarge", "g6.xlarge", "g4dn.xlarge"], 

52 "use_cases": [ 

53 "run a single GPU workload", 

54 "test GPU node provisioning", 

55 "smoke test CUDA", 

56 ], 

57 "related": ["multi-gpu-training", "simple-job"], 

58 }, 

59 "multi-gpu-training": { 

60 "category": "Jobs & Training", 

61 "summary": "PyTorch DistributedDataParallel (DDP) across multiple GPUs with indexed pods and headless service.", 

62 "gpu": "NVIDIA", 

63 "opt_in": "", 

64 "submission": "kubectl apply -f examples/multi-gpu-training.yaml", 

65 "keywords": [ 

66 "ddp", 

67 "distributed", 

68 "pytorch", 

69 "multi gpu", 

70 "training", 

71 "torchrun", 

72 "nccl", 

73 "indexed pods", 

74 "headless service", 

75 ], 

76 "instance_types": ["g5.12xlarge", "g6.12xlarge", "p4d.24xlarge"], 

77 "use_cases": [ 

78 "distributed PyTorch DDP training", 

79 "scale a training job across multiple GPUs", 

80 ], 

81 "related": ["gpu-job", "efa-distributed-training", "trainium-job"], 

82 }, 

83 "efa-distributed-training": { 

84 "category": "Jobs & Training", 

85 "summary": "Elastic Fabric Adapter (EFA) for high-bandwidth inter-node communication (up to 3.2 Tbps on P5, 28.8 Tbps on P6e). For p4d/p5/p5e/p5en/p6-b200/p6-b300/p6e-gb200/trn instances.", 

86 "gpu": "NVIDIA + EFA", 

87 "opt_in": "", 

88 "submission": "gco jobs submit-direct examples/efa-distributed-training.yaml -r us-east-1", 

89 "keywords": ["efa", "elastic fabric adapter", "distributed", "nccl", "high bandwidth"], 

90 "instance_types": [ 

91 "p4d.24xlarge", 

92 "p5.48xlarge", 

93 "trn1.32xlarge", 

94 "trn2.48xlarge", 

95 ], 

96 "use_cases": [ 

97 "multi-node distributed training over EFA", 

98 "high-bandwidth NCCL all-reduce", 

99 "large-scale model pretraining", 

100 ], 

101 "related": ["multi-gpu-training", "trainium-job", "gpu-job"], 

102 }, 

103 "kubeflow-trainjob": { 

104 "category": "Jobs & Training", 

105 "summary": "Kubeflow Trainer v2 TrainJob: 2-node distributed PyTorch through the torch-distributed runtime (CPU-sized; GPU variant documented via runtimePatches).", 

106 "gpu": "no", 

107 "opt_in": "", 

108 "submission": "gco jobs submit-sqs examples/kubeflow-trainjob.yaml --region us-east-1", 

109 "keywords": [ 

110 "kubeflow", 

111 "trainer", 

112 "trainjob", 

113 "torchrun", 

114 "distributed training", 

115 "jobset", 

116 "gang scheduling", 

117 "pytorch", 

118 ], 

119 "instance_types": [], 

120 "use_cases": [ 

121 "multi-node training through the TrainJob API", 

122 "distributed PyTorch without writing JobSets", 

123 "gang-schedule training via the Kueue default queue", 

124 ], 

125 "related": ["multi-gpu-training", "efa-distributed-training", "kueue-job"], 

126 }, 

127 "mlflow-tracking-job": { 

128 "category": "Jobs & Training", 

129 "summary": "Logs params and a loss curve to the in-cluster MLflow tracking server over verified HTTPS, then reads the run back and asserts every value round-tripped.", 

130 "gpu": "no", 

131 "opt_in": "", 

132 "submission": "gco jobs submit-direct examples/mlflow-tracking-job.yaml -r us-east-1", 

133 "keywords": [ 

134 "mlflow", 

135 "experiment tracking", 

136 "metrics", 

137 "tracking server", 

138 "runs", 

139 "observability", 

140 ], 

141 "instance_types": [], 

142 "use_cases": [ 

143 "track training runs in MLflow", 

144 "log metrics from a job", 

145 "verify the tracking pipeline end to end", 

146 ], 

147 "related": ["kubeflow-trainjob", "multi-gpu-training"], 

148 }, 

149 "model-download-job": { 

150 "category": "Jobs & Training", 

151 "summary": "Pre-downloads HuggingFace model weights to shared EFS for inference endpoints.", 

152 "gpu": "no", 

153 "opt_in": "", 

154 "submission": "kubectl apply -f examples/model-download-job.yaml", 

155 "keywords": ["huggingface", "download", "weights", "model cache", "efs"], 

156 "instance_types": [], 

157 "use_cases": [ 

158 "stage HuggingFace weights on EFS", 

159 "warm a model cache before serving", 

160 ], 

161 "related": ["inference-vllm", "inference-sglang", "efs-output-job"], 

162 }, 

163 "sqs-job-submission": { 

164 "category": "Jobs & Training", 

165 "summary": "Demonstrates SQS-based submission (recommended). Contains CPU and GPU job examples.", 

166 "gpu": "optional", 

167 "opt_in": "", 

168 "submission": "gco jobs submit-sqs examples/sqs-job-submission.yaml --region us-east-1", 

169 "keywords": ["sqs", "submission", "queue", "broker"], 

170 "instance_types": [], 

171 "use_cases": [ 

172 "submit jobs through the SQS queue", 

173 "queue-based job submission pattern", 

174 ], 

175 "related": ["simple-job", "gpu-job", "keda-scaled-job"], 

176 }, 

177 "trainium-job": { 

178 "category": "Accelerator Jobs", 

179 "summary": "AWS Trainium instance with Neuron SDK. Lower cost than GPU for training.", 

180 "gpu": "Trainium", 

181 "opt_in": "", 

182 "submission": "gco jobs submit examples/trainium-job.yaml --region us-east-1", 

183 "keywords": ["trainium", "neuron", "trn1", "trn2", "training accelerator"], 

184 "instance_types": ["trn1.2xlarge", "trn1.32xlarge", "trn2.48xlarge"], 

185 "use_cases": [ 

186 "lower-cost training on AWS silicon", 

187 "train with the Neuron SDK", 

188 ], 

189 "related": ["inferentia-job", "efa-distributed-training"], 

190 }, 

191 "inferentia-job": { 

192 "category": "Accelerator Jobs", 

193 "summary": "AWS Inferentia2 with Neuron SDK. Optimized for low-cost, high-throughput inference.", 

194 "gpu": "Inferentia", 

195 "opt_in": "", 

196 "submission": "gco jobs submit examples/inferentia-job.yaml --region us-east-1", 

197 "keywords": ["inferentia", "neuron", "inf2", "inference accelerator"], 

198 "instance_types": ["inf2.xlarge", "inf2.8xlarge", "inf2.24xlarge", "inf2.48xlarge"], 

199 "use_cases": [ 

200 "low-cost inference on AWS silicon", 

201 "high-throughput batch inference", 

202 ], 

203 "related": ["trainium-job", "inference-vllm"], 

204 }, 

205 "inference-vllm": { 

206 "category": "Inference Serving", 

207 "summary": "vLLM OpenAI-compatible LLM serving with PagedAttention.", 

208 "gpu": "NVIDIA", 

209 "opt_in": "", 

210 "submission": "gco inference deploy my-llm -i vllm/vllm-openai:v0.32.0 --gpu-count 1", 

211 "keywords": [ 

212 "vllm", 

213 "openai", 

214 "openai-compatible", 

215 "llm serving", 

216 "pagedattention", 

217 "inference", 

218 "completions", 

219 "chat completions", 

220 "v1/chat/completions", 

221 "model server", 

222 "llama", 

223 "qwen", 

224 "mistral", 

225 ], 

226 "instance_types": ["g5.xlarge", "g5.12xlarge", "g6.xlarge"], 

227 "use_cases": [ 

228 "serve an LLM with an OpenAI-compatible API", 

229 "high-throughput LLM inference", 

230 "deploy a chat completions endpoint", 

231 ], 

232 "related": ["inference-sglang", "inference-triton", "model-download-job"], 

233 }, 

234 "inference-triton": { 

235 "category": "Inference Serving", 

236 "summary": "NVIDIA Triton Inference Server — multi-framework (PyTorch, TensorFlow, ONNX).", 

237 "gpu": "NVIDIA", 

238 "opt_in": "", 

239 "submission": "gco jobs submit-direct examples/inference-triton.yaml -r us-east-1", 

240 "keywords": ["triton", "nvidia", "multi-framework", "onnx", "tensorflow", "inference"], 

241 "instance_types": ["g5.xlarge", "g6.xlarge"], 

242 "use_cases": [ 

243 "multi-framework inference serving", 

244 "serve ONNX or TensorFlow models", 

245 ], 

246 "related": ["inference-vllm", "inference-sglang"], 

247 }, 

248 "inference-sglang": { 

249 "category": "Inference Serving", 

250 "summary": "SGLang high-throughput serving with RadixAttention for prefix caching.", 

251 "gpu": "NVIDIA", 

252 "opt_in": "", 

253 "submission": "gco jobs submit-direct examples/inference-sglang.yaml -r us-east-1", 

254 "keywords": ["sglang", "radixattention", "prefix caching", "llm serving"], 

255 "instance_types": ["g5.xlarge", "g5.12xlarge"], 

256 "use_cases": [ 

257 "high-throughput LLM serving with prefix caching", 

258 "serve LLMs with structured output", 

259 ], 

260 "related": ["inference-vllm", "inference-triton", "model-download-job"], 

261 }, 

262 "efs-output-job": { 

263 "category": "Storage & Persistence", 

264 "summary": "Writes output to shared EFS storage. Results persist after pod termination.", 

265 "gpu": "no", 

266 "opt_in": "", 

267 "submission": "gco jobs submit-direct examples/efs-output-job.yaml --region us-east-1 -n gco-jobs", 

268 "keywords": ["efs", "shared storage", "persistent", "output"], 

269 "instance_types": [], 

270 "use_cases": [ 

271 "persist job output to EFS", 

272 "share data between pods via EFS", 

273 ], 

274 "related": ["fsx-lustre-job", "model-download-job", "cluster-shared-bucket-upload-job"], 

275 }, 

276 "fsx-lustre-job": { 

277 "category": "Storage & Persistence", 

278 "summary": "FSx for Lustre high-performance parallel storage (1000+ GB/s throughput).", 

279 "gpu": "no", 

280 "opt_in": "FSx (gco stacks fsx enable -y)", 

281 "submission": "gco jobs submit-direct examples/fsx-lustre-job.yaml --region us-east-1 -n gco-jobs", 

282 "keywords": ["fsx", "lustre", "parallel storage", "high throughput", "hpc"], 

283 "instance_types": [], 

284 "use_cases": [ 

285 "high-throughput parallel storage for training", 

286 "stream large datasets to GPU nodes", 

287 ], 

288 "related": ["efs-output-job", "multi-gpu-training", "efa-distributed-training"], 

289 }, 

290 "valkey-cache-job": { 

291 "category": "Caching & Databases", 

292 "summary": "Valkey Serverless cache for K/V caching, prompt caching, session state, feature stores.", 

293 "gpu": "no", 

294 "opt_in": 'Valkey ("valkey": {"enabled": true} in cdk.json)', 

295 "submission": "gco jobs submit-direct examples/valkey-cache-job.yaml -r us-east-1", 

296 "keywords": ["valkey", "redis", "cache", "kv store", "session state"], 

297 "instance_types": [], 

298 "use_cases": [ 

299 "cache prompts or session state", 

300 "use Valkey from a job", 

301 "feature store backed by Valkey", 

302 ], 

303 "related": ["aurora-pgvector-job"], 

304 }, 

305 "aurora-pgvector-job": { 

306 "category": "Caching & Databases", 

307 "summary": "Aurora Serverless v2 PostgreSQL with pgvector for RAG and semantic search.", 

308 "gpu": "no", 

309 "opt_in": 'Aurora ("aurora_pgvector": {"enabled": true} in cdk.json)', 

310 "submission": "gco jobs submit-direct examples/aurora-pgvector-job.yaml -r us-east-1", 

311 "keywords": ["aurora", "pgvector", "postgres", "rag", "vector database", "embeddings"], 

312 "instance_types": [], 

313 "use_cases": [ 

314 "RAG with pgvector", 

315 "semantic search backed by Postgres", 

316 "store embeddings in Aurora", 

317 ], 

318 "related": ["valkey-cache-job", "analytics-database-export-job"], 

319 }, 

320 "vector-store-search-job": { 

321 "category": "Caching & Databases", 

322 "summary": "Read-only semantic search against the built-in DynamoDB vector store: Bedrock query embedding + SearchVectors against the local replica, asserting at least one hit.", 

323 "gpu": "no", 

324 "opt_in": 'Vector store ("vector_store": {"enabled": true} in cdk.json)', 

325 "submission": "gco jobs submit-direct examples/vector-store-search-job.yaml -r us-east-1", 

326 "keywords": [ 

327 "vector store", 

328 "dynamodb", 

329 "semantic search", 

330 "embeddings", 

331 "bedrock", 

332 "searchvectors", 

333 "rag", 

334 ], 

335 "instance_types": [], 

336 "use_cases": [ 

337 "semantic search over the ingested corpus", 

338 "RAG retrieval from a job", 

339 "query the vector store from workloads", 

340 ], 

341 "related": ["aurora-pgvector-job", "valkey-cache-job"], 

342 }, 

343 "cluster-shared-bucket-upload-job": { 

344 "category": "Storage & Persistence", 

345 "summary": "Uploads a file to the always-on Cluster_Shared_Bucket using the gco-cluster-shared-bucket ConfigMap via envFrom. Works with analytics disabled.", 

346 "gpu": "no", 

347 "opt_in": "", 

348 "submission": "gco jobs submit-direct examples/cluster-shared-bucket-upload-job.yaml -r us-east-1", 

349 "keywords": ["s3", "shared bucket", "upload", "configmap"], 

350 "instance_types": [], 

351 "use_cases": [ 

352 "upload artifacts to the shared S3 bucket", 

353 "share files across regions via S3", 

354 ], 

355 "related": [ 

356 "efs-output-job", 

357 "analytics-s3-upload-job", 

358 "regional-shared-bucket-upload-job", 

359 ], 

360 }, 

361 "regional-shared-bucket-upload-job": { 

362 "category": "Storage & Persistence", 

363 "summary": "Uploads a file to the always-on Regional_Shared_Bucket using the gco-regional-shared-bucket ConfigMap via envFrom. Same-region as the cluster, so no cross-region egress — the right target for training checkpoints.", 

364 "gpu": "no", 

365 "opt_in": "", 

366 "submission": "gco jobs submit-direct examples/regional-shared-bucket-upload-job.yaml -r us-east-1", 

367 "keywords": [ 

368 "s3", 

369 "regional bucket", 

370 "checkpoint", 

371 "upload", 

372 "configmap", 

373 "same-region", 

374 ], 

375 "instance_types": [], 

376 "use_cases": [ 

377 "write training checkpoints to S3 from a job", 

378 "upload artifacts without cross-region egress", 

379 "persist job outputs to the region's own bucket", 

380 ], 

381 "related": ["cluster-shared-bucket-upload-job", "efs-output-job"], 

382 }, 

383 "analytics-s3-upload-job": { 

384 "category": "Analytics", 

385 "summary": "Publishes a dataset snapshot plus schema manifest to Cluster_Shared_Bucket under analytics-data/ so a SageMaker Studio notebook can read it.", 

386 "gpu": "no", 

387 "opt_in": 'Analytics ("analytics_environment": {"enabled": true} in cdk.json)', 

388 "submission": "gco jobs submit-direct examples/analytics-s3-upload-job.yaml -r us-east-1", 

389 "keywords": ["analytics", "s3", "sagemaker", "dataset", "schema"], 

390 "instance_types": [], 

391 "use_cases": [ 

392 "publish a dataset for a SageMaker Studio notebook", 

393 "share an analytics snapshot via S3", 

394 ], 

395 "related": ["analytics-database-export-job", "cluster-shared-bucket-upload-job"], 

396 }, 

397 "analytics-database-export-job": { 

398 "category": "Analytics", 

399 "summary": "Exports rows from the regional Aurora pgvector cluster to Cluster_Shared_Bucket as CSV for a SageMaker Studio notebook to analyse.", 

400 "gpu": "no", 

401 "opt_in": 'Aurora + Analytics ("aurora_pgvector.enabled" and "analytics_environment.enabled" in cdk.json)', 

402 "submission": "gco jobs submit-direct examples/analytics-database-export-job.yaml -r us-east-1", 

403 "keywords": ["analytics", "aurora", "csv", "export", "sagemaker"], 

404 "instance_types": [], 

405 "use_cases": [ 

406 "export Aurora rows to S3 as CSV", 

407 "feed a SageMaker Studio notebook from Postgres", 

408 ], 

409 "related": ["aurora-pgvector-job", "analytics-s3-upload-job"], 

410 }, 

411 "volcano-gang-job": { 

412 "category": "Schedulers", 

413 "summary": "Volcano gang scheduling — all pods scheduled together or none. Master + workers topology.", 

414 "gpu": "no", 

415 "opt_in": "", 

416 "submission": "kubectl apply -f examples/volcano-gang-job.yaml", 

417 "keywords": ["volcano", "gang scheduling", "batch", "scheduler"], 

418 "instance_types": [], 

419 "use_cases": [ 

420 "schedule all pods at once or none", 

421 "MPI-style master + workers topology", 

422 ], 

423 "related": ["kueue-job", "yunikorn-job", "slurm-cluster-job"], 

424 }, 

425 "kueue-job": { 

426 "category": "Schedulers", 

427 "summary": "Kueue job queueing with ClusterQueue, LocalQueue, ResourceFlavors, and fair-sharing.", 

428 "gpu": "optional", 

429 "opt_in": "", 

430 "submission": "kubectl apply -f examples/kueue-job.yaml", 

431 "keywords": ["kueue", "queueing", "fair sharing", "scheduler", "clusterqueue"], 

432 "instance_types": [], 

433 "use_cases": [ 

434 "queue jobs with quotas and fair sharing", 

435 "multi-tenant batch scheduling", 

436 ], 

437 "related": ["volcano-gang-job", "yunikorn-job"], 

438 }, 

439 "yunikorn-job": { 

440 "category": "Schedulers", 

441 "summary": "Apache YuniKorn app-aware scheduling with hierarchical queues and gang scheduling.", 

442 "gpu": "no", 

443 "opt_in": 'YuniKorn ("helm": {"yunikorn": {"enabled": true}} in cdk.json)', 

444 "submission": "kubectl apply -f examples/yunikorn-job.yaml", 

445 "keywords": ["yunikorn", "scheduler", "hierarchical queues", "gang scheduling"], 

446 "instance_types": [], 

447 "use_cases": [ 

448 "app-aware scheduling with hierarchical queues", 

449 "YuniKorn-style gang scheduling", 

450 ], 

451 "related": ["kueue-job", "volcano-gang-job"], 

452 }, 

453 "keda-scaled-job": { 

454 "category": "Schedulers", 

455 "summary": "KEDA ScaledJob — custom SQS-triggered autoscaling. Template for custom consumers.", 

456 "gpu": "no", 

457 "opt_in": "", 

458 "submission": "kubectl apply -f examples/keda-scaled-job.yaml", 

459 "keywords": ["keda", "scaledjob", "autoscaling", "sqs", "event driven"], 

460 "instance_types": [], 

461 "use_cases": [ 

462 "scale jobs from SQS queue depth", 

463 "event-driven job autoscaling", 

464 ], 

465 "related": ["sqs-job-submission"], 

466 }, 

467 "slurm-cluster-job": { 

468 "category": "Schedulers", 

469 "summary": "Slurm on GCO — an in-cluster client submits through slurmrestd with the operator-minted token, waits on an autoscaled worker and checks the accounting record.", 

470 "gpu": "no", 

471 "opt_in": 'Slurm ("helm": {"slurm": {"enabled": true}} in cdk.json)', 

472 "submission": "kubectl apply -f examples/slurm-cluster-job.yaml", 

473 "keywords": ["slurm", "hpc", "sbatch", "slinky", "slurmrestd", "sacct"], 

474 "instance_types": [], 

475 "use_cases": [ 

476 "submit sbatch jobs on Kubernetes", 

477 "run HPC workloads with Slurm", 

478 ], 

479 "related": ["volcano-gang-job"], 

480 }, 

481 "ray-cluster": { 

482 "category": "Distributed Computing", 

483 "summary": "KubeRay RayCluster for distributed training, tuning, and serving. Auto-scaling workers.", 

484 "gpu": "no", 

485 "opt_in": "", 

486 "submission": "kubectl apply -f examples/ray-cluster.yaml", 

487 "keywords": ["ray", "kuberay", "distributed", "tune", "serve"], 

488 "instance_types": [], 

489 "use_cases": [ 

490 "stand up a Ray cluster on EKS", 

491 "distributed training and tuning with Ray", 

492 ], 

493 "related": ["multi-gpu-training", "pipeline-dag"], 

494 }, 

495 "pipeline-dag": { 

496 "category": "DAG Pipelines", 

497 "summary": "Multi-step pipeline with dependency ordering. Preprocess → Train via shared EFS.", 

498 "gpu": "no", 

499 "opt_in": "", 

500 "submission": "gco dag run examples/pipeline-dag.yaml -r us-east-1", 

501 "keywords": ["dag", "pipeline", "workflow", "dependencies"], 

502 "instance_types": [], 

503 "use_cases": [ 

504 "run a multi-step ML pipeline", 

505 "chain preprocess and train jobs", 

506 ], 

507 "related": ["dag-step-preprocess", "dag-step-train", "ray-cluster"], 

508 }, 

509 "dag-step-preprocess": { 

510 "category": "DAG Pipelines", 

511 "summary": "DAG step 1: generates training data on shared EFS.", 

512 "gpu": "no", 

513 "opt_in": "", 

514 "submission": "(used by pipeline-dag.yaml)", 

515 "keywords": ["dag", "preprocess", "step", "pipeline"], 

516 "instance_types": [], 

517 "use_cases": [ 

518 "preprocessing step of a pipeline", 

519 "generate training data for a downstream step", 

520 ], 

521 "related": ["pipeline-dag", "dag-step-train"], 

522 }, 

523 "dag-step-train": { 

524 "category": "DAG Pipelines", 

525 "summary": "DAG step 2: reads preprocess output, trains model, writes artifacts to EFS.", 

526 "gpu": "no", 

527 "opt_in": "", 

528 "submission": "(used by pipeline-dag.yaml)", 

529 "keywords": ["dag", "train", "step", "pipeline"], 

530 "instance_types": [], 

531 "use_cases": [ 

532 "training step of a pipeline", 

533 "consume preprocess output and train", 

534 ], 

535 "related": ["pipeline-dag", "dag-step-preprocess"], 

536 }, 

537 # --- Platform add-ons: GitOps, platform APIs, AWS resources as objects ----- 

538 "argocd-gitops-job": { 

539 "category": "Platform Add-ons", 

540 "summary": "Argo CD Application that syncs a Job from Git into gco-jobs through the fenced gco-tenants project.", 

541 "gpu": "no", 

542 "opt_in": 'Argo CD ("helm": {"argocd": {"enabled": true}} in cdk.json)', 

543 "submission": "kubectl apply -f examples/argocd-gitops-job.yaml", 

544 "keywords": ["argocd", "argo cd", "gitops", "application", "git", "sync"], 

545 "instance_types": [], 

546 "use_cases": [ 

547 "deploy tenant workloads from a Git repository", 

548 "continuously reconcile a directory into gco-jobs", 

549 ], 

550 "related": ["crossplane-batch-job", "kro-batch-job", "simple-job"], 

551 }, 

552 "crossplane-batch-api": { 

553 "category": "Platform Add-ons", 

554 "summary": "Crossplane XRD + Composition defining a namespaced BatchJob API that composes a Job.", 

555 "gpu": "no", 

556 "opt_in": 'Crossplane ("helm": {"crossplane": {"enabled": true}} in cdk.json)', 

557 "submission": "(applied before crossplane-batch-job.yaml)", 

558 "keywords": ["crossplane", "xrd", "composition", "platform api", "go-templating"], 

559 "instance_types": [], 

560 "use_cases": [ 

561 "define a self-service platform API", 

562 "compose Kubernetes workloads from a custom resource", 

563 ], 

564 "related": ["crossplane-batch-job", "kro-batch-api"], 

565 }, 

566 "crossplane-batch-job": { 

567 "category": "Platform Add-ons", 

568 "summary": "Crossplane BatchJob composite resource; Crossplane composes and runs a Job of the same name.", 

569 "gpu": "no", 

570 "opt_in": 'Crossplane ("helm": {"crossplane": {"enabled": true}} in cdk.json)', 

571 "submission": "kubectl apply -f examples/crossplane-batch-job.yaml", 

572 "keywords": ["crossplane", "composite resource", "xr", "crossview", "platform api"], 

573 "instance_types": [], 

574 "use_cases": [ 

575 "run a Job through a Crossplane platform API", 

576 "see a composition in the Crossview dashboard", 

577 ], 

578 "related": ["crossplane-batch-api", "kro-batch-job", "argocd-gitops-job"], 

579 }, 

580 "kro-batch-api": { 

581 "category": "Platform Add-ons", 

582 "summary": "kro ResourceGraphDefinition defining a namespaced BatchJob API that composes a Job.", 

583 "gpu": "no", 

584 "opt_in": 'kro EKS Capability ("eks_capabilities": {"kro": {"enabled": true}} in cdk.json)', 

585 "submission": "(applied before kro-batch-job.yaml)", 

586 "keywords": ["kro", "resourcegraphdefinition", "rgd", "eks capability", "platform api"], 

587 "instance_types": [], 

588 "use_cases": [ 

589 "define a custom API with kro", 

590 "compose Kubernetes workloads from a custom resource", 

591 ], 

592 "related": ["kro-batch-job", "crossplane-batch-api"], 

593 }, 

594 "kro-batch-job": { 

595 "category": "Platform Add-ons", 

596 "summary": "kro BatchJob instance; the kro EKS Capability composes and runs a Job of the same name.", 

597 "gpu": "no", 

598 "opt_in": 'kro EKS Capability ("eks_capabilities": {"kro": {"enabled": true}} in cdk.json)', 

599 "submission": "kubectl apply -f examples/kro-batch-job.yaml", 

600 "keywords": ["kro", "instance", "eks capability", "composition", "platform api"], 

601 "instance_types": [], 

602 "use_cases": [ 

603 "run a Job through a kro API", 

604 "try the AWS-managed kro capability", 

605 ], 

606 "related": ["kro-batch-api", "crossplane-batch-job", "ack-sqs-queue"], 

607 }, 

608 "ack-sqs-queue": { 

609 "category": "Platform Add-ons", 

610 "summary": "Amazon SQS queue declared as a Kubernetes object and managed by the ACK EKS Capability.", 

611 "gpu": "no", 

612 "opt_in": 'ACK EKS Capability ("eks_capabilities": {"ack": {"enabled": true, "iam_policy_arns": [...]}} in cdk.json)', 

613 "submission": "kubectl apply -f examples/ack-sqs-queue.yaml", 

614 "keywords": ["ack", "aws controllers for kubernetes", "sqs", "queue", "eks capability"], 

615 "instance_types": [], 

616 "use_cases": [ 

617 "create an AWS resource from Kubernetes", 

618 "manage an SQS queue alongside the workloads that use it", 

619 ], 

620 "related": ["kro-batch-job", "keda-scaled-job", "sqs-job-submission"], 

621 }, 

622} 

623 

624 

625# --------------------------------------------------------------------------- 

626# Doc metadata — used by ``find_docs`` and the docs:// discovery resources to 

627# describe every markdown file under ``docs/``. Indexed by basename without 

628# extension (e.g. ``ARCHITECTURE``). The vocabulary in ``topics`` is kept 

629# small and consistent so topic-based search across docs stays predictable. 

630# --------------------------------------------------------------------------- 

631 

632DOC_METADATA: dict[str, dict[str, str | list[str]]] = { 

633 "ANALYTICS": { 

634 "summary": "Optional SageMaker Studio + EMR Serverless analytics environment, enabled via a single cdk.json toggle.", 

635 "topics": ["analytics", "storage", "customization", "gpu"], 

636 "keywords": [ 

637 "sagemaker studio", 

638 "emr serverless", 

639 "cognito", 

640 "data science", 

641 "notebook", 

642 "presigned url", 

643 "studio domain", 

644 "analytics environment", 

645 "user pool", 

646 ], 

647 "related": ["CLUSTER_SHARED_BUCKET", "CUSTOMIZATION"], 

648 }, 

649 "API": { 

650 "summary": ( 

651 "Reference for every GCO HTTP surface: the control plane (manifests, " 

652 "jobs, queue, templates, webhooks, cost), cross-region aggregation, " 

653 "inference, health and observability, plus which paths each API " 

654 "Gateway exposes and the cluster-internal surfaces." 

655 ), 

656 "topics": ["api", "cli", "jobs", "inference", "webhooks", "templates"], 

657 "keywords": [ 

658 "rest", 

659 "manifest processor", 

660 "inference proxy", 

661 "health monitor", 

662 "endpoints", 

663 "auth", 

664 "hmac request envelope", 

665 "api gateway", 

666 "sigv4", 

667 "openapi", 

668 "submit job", 

669 "api surface", 

670 ], 

671 "related": ["CLI", "ARCHITECTURE"], 

672 }, 

673 "ARCHITECTURE": { 

674 "summary": "Deep dive into the multi-region infrastructure, security layers, data flow, and scale characteristics.", 

675 "topics": [ 

676 "architecture", 

677 "concepts", 

678 "security", 

679 "multi-region", 

680 "eks", 

681 "capacity", 

682 "inference", 

683 "gpu", 

684 "monitoring", 

685 "deployment", 

686 "nodepools", 

687 "storage", 

688 "images", 

689 "cost", 

690 "networking", 

691 ], 

692 "keywords": [ 

693 "multi-region", 

694 "eks", 

695 "vpc", 

696 "global accelerator", 

697 "data flow", 

698 "control plane", 

699 "data plane", 

700 "regional stack", 

701 "global stack", 

702 "iam", 

703 "kms", 

704 "high level design", 

705 "blast radius", 

706 ], 

707 "related": ["CONCEPTS", "CUSTOMIZATION", "API"], 

708 }, 

709 "AUTOPILOT": { 

710 "summary": ( 

711 "gco autopilot: one command to a fully configured Claude Code, " 

712 "OpenAI Codex, or OpenCode session on Amazon Bedrock with the GCO " 

713 "MCP server and the recommended companion MCP servers wired in." 

714 ), 

715 "topics": [ 

716 "cli", 

717 "mcp", 

718 "agents", 

719 "bedrock", 

720 "getting-started", 

721 "deployment", 

722 ], 

723 "keywords": [ 

724 "autopilot", 

725 "claude code", 

726 "codex", 

727 "opencode", 

728 "kimi", 

729 "bedrock", 

730 "mcp", 

731 "agent session", 

732 "companion servers", 

733 "feature flags", 

734 "session resume", 

735 "skills", 

736 "plugins", 

737 "dev container", 

738 "front door", 

739 ], 

740 "related": ["CLI", "CONCEPTS"], 

741 }, 

742 "CLI": { 

743 "summary": "Complete command-line interface reference for the gco CLI across jobs, queues, stacks, capacity, inference, and more.", 

744 "topics": [ 

745 "cli", 

746 "api", 

747 "jobs", 

748 "capacity", 

749 "inference", 

750 "cost", 

751 "gpu", 

752 "multi-region", 

753 "images", 

754 "nodepools", 

755 "deployment", 

756 ], 

757 "keywords": [ 

758 "gco", 

759 "command-line", 

760 "subcommand", 

761 "submit job", 

762 "stacks deploy", 

763 "stacks destroy", 

764 "capacity status", 

765 "ai_recommend", 

766 "reserve_capacity", 

767 "images build", 

768 "models upload", 

769 ], 

770 "related": ["API", "RUNBOOKS"], 

771 }, 

772 "CLUSTER_SHARED_BUCKET": { 

773 "summary": "Reference for the always-on Cluster_Shared_Bucket — the S3 bucket every regional cluster can read and write by default.", 

774 "topics": ["storage", "concepts", "multi-region", "security"], 

775 "keywords": [ 

776 "s3", 

777 "shared bucket", 

778 "cross-region", 

779 "configmap", 

780 "envFrom", 

781 "kms", 

782 "iam grant", 

783 "bucket policy", 

784 "always-on", 

785 ], 

786 "related": ["ANALYTICS", "ARCHITECTURE", "REGIONAL_SHARED_BUCKET"], 

787 }, 

788 "REGIONAL_SHARED_BUCKET": { 

789 "summary": "Reference for the always-on Regional_Shared_Bucket — the per-region S3 bucket each cluster's job pods can read and write in their own region, with no cross-region egress.", 

790 "topics": ["storage", "concepts", "security"], 

791 "keywords": [ 

792 "s3", 

793 "regional bucket", 

794 "checkpoint", 

795 "same-region", 

796 "configmap", 

797 "envFrom", 

798 "kms", 

799 "iam grant", 

800 "pod identity", 

801 "always-on", 

802 "teardown", 

803 ], 

804 "related": ["CLUSTER_SHARED_BUCKET", "ARCHITECTURE"], 

805 }, 

806 "EKS_CAPABILITIES": { 

807 "summary": "Opt-in EKS Capabilities — the AWS-managed ACK and kro installations GCO can attach per regional cluster: capability IAM roles, ACK permission models (managed policies or IAM Role Selectors), the tenant RBAC kro composes workloads with, and live status/drift.", 

808 "topics": ["eks", "customization", "security", "cli"], 

809 "keywords": [ 

810 "eks capabilities", 

811 "ack", 

812 "aws controllers for kubernetes", 

813 "kro", 

814 "kube resource orchestrator", 

815 "resourcegraphdefinition", 

816 "iam role selector", 

817 "capability role", 

818 "gco stacks capabilities", 

819 ], 

820 "related": [ 

821 "GITOPS", 

822 "CROSSPLANE", 

823 "CUSTOMIZATION", 

824 "CLI", 

825 "LIVE_RELEASE_VALIDATION", 

826 ], 

827 }, 

828 "CROSSPLANE": { 

829 "summary": "Self-managed Crossplane v2 and the Crossview dashboard (cdk.json helm.crossplane, off by default): namespaced composite resources that compose tenant workloads in gco-jobs and gco-inference only, the go-templating composition function, no provider packages, and the dashboard over a private port-forward.", 

830 "topics": ["customization", "security", "cli", "eks"], 

831 "keywords": [ 

832 "crossplane", 

833 "crossview", 

834 "composite resource", 

835 "compositeresourcedefinition", 

836 "xrd", 

837 "composition", 

838 "function-go-templating", 

839 "platform api", 

840 "gco crossplane", 

841 ], 

842 "related": ["EKS_CAPABILITIES", "GITOPS", "CUSTOMIZATION", "CLI"], 

843 }, 

844 "CONCEPTS": { 

845 "summary": "Fundamental concepts behind GCO — what it is, the problems it solves, and how the key components fit together.", 

846 "topics": [ 

847 "concepts", 

848 "architecture", 

849 "multi-region", 

850 "capacity", 

851 "gpu", 

852 "eks", 

853 "jobs", 

854 "inference", 

855 ], 

856 "keywords": [ 

857 "what is gco", 

858 "fundamentals", 

859 "components", 

860 "global queue", 

861 "capacity orchestration", 

862 "ai/ml workloads", 

863 "gpu allocation", 

864 "regional clusters", 

865 ], 

866 "related": ["ARCHITECTURE", "README"], 

867 }, 

868 "COST_MONITORING": { 

869 "summary": "Cost monitoring and cost-aware scheduling — per-region OpenCost with a Grafana cost dashboard, scheduled Parquet cost reports to S3, cross-region Athena analytics, the /api/v1/cost API, and spot price-gated central-queue dispatch.", 

870 "topics": [ 

871 "cost", 

872 "monitoring", 

873 "observability", 

874 "queue", 

875 "customization", 

876 "api", 

877 "cli", 

878 ], 

879 "keywords": [ 

880 "opencost", 

881 "cost allocation", 

882 "athena", 

883 "glue", 

884 "parquet", 

885 "cost reports", 

886 "cost dashboard", 

887 "spot price", 

888 "max spot price", 

889 "cost-aware scheduling", 

890 "namespace cost", 

891 "finops", 

892 ], 

893 "related": ["MONITORING", "CUSTOMIZATION", "API"], 

894 }, 

895 "CUSTOMIZATION": { 

896 "summary": "How to customize GCO — deployment regions, EKS configuration, GPU nodepools, and more.", 

897 "topics": [ 

898 "customization", 

899 "architecture", 

900 "gpu", 

901 "eks", 

902 "nodepools", 

903 "storage", 

904 "multi-region", 

905 "deployment", 

906 ], 

907 "keywords": [ 

908 "cdk.json", 

909 "regions", 

910 "addons", 

911 "instance types", 

912 "fsx", 

913 "valkey", 

914 "aurora", 

915 "feature toggles", 

916 "queue processor", 

917 "helm charts", 

918 "image registry config", 

919 ], 

920 "related": ["ARCHITECTURE", "ANALYTICS"], 

921 }, 

922 "DISTRIBUTED_TRAINING": { 

923 "summary": ( 

924 "Multi-node distributed training through the Kubeflow Trainer v2 " 

925 "TrainJob API — runtimes, validation semantics, GPU variants, " 

926 "Kueue gang scheduling, and Spot guidance." 

927 ), 

928 "topics": [ 

929 "jobs", 

930 "gpu", 

931 "schedulers", 

932 "architecture", 

933 ], 

934 "keywords": [ 

935 "kubeflow", 

936 "trainer", 

937 "trainjob", 

938 "distributed training", 

939 "torchrun", 

940 "jobset", 

941 "clustertrainingruntime", 

942 "gang scheduling", 

943 "pytorchjob", 

944 "spot", 

945 ], 

946 "related": ["KUEUE", "SCHEDULERS", "MONITORING", "CUSTOMIZATION"], 

947 }, 

948 "FLOCI_TESTING": { 

949 "summary": ( 

950 "Emulated-AWS test layer between in-process mocks and real-account " 

951 "live validation: production code issuing genuine SDK requests " 

952 "against a Floci emulator in CI, with zero AWS credentials." 

953 ), 

954 "topics": [ 

955 "ci", 

956 "deployment", 

957 "security", 

958 "automation", 

959 ], 

960 "keywords": [ 

961 "floci", 

962 "emulator", 

963 "localstack alternative", 

964 "integration tests", 

965 "aws endpoint url", 

966 "emulated aws", 

967 "gco release validate", 

968 "emulator endpoint", 

969 "wire protocol", 

970 "test layers", 

971 "known emulator gaps", 

972 ], 

973 "related": ["LIVE_RELEASE_VALIDATION", "CLI", "MAINTENANCE"], 

974 }, 

975 "FORKING": { 

976 "summary": ( 

977 "Take GCO into your own repository: repoint badges, clone URLs, the " 

978 "GitHub Pages site, and the OIDC trust-policy subject with " 

979 "scripts/migrate_fork.py, plus the follow-ups it cannot decide." 

980 ), 

981 "topics": ["forking", "migration", "repository", "ci", "oidc"], 

982 "keywords": [ 

983 "fork", 

984 "migrate", 

985 "own repository", 

986 "rename repo", 

987 "badges", 

988 "oidc trust policy", 

989 "github pages", 

990 "codeowners", 

991 "solution id", 

992 "upstream remote", 

993 ], 

994 "related": ["CUSTOMIZATION", "MAINTENANCE"], 

995 }, 

996 "GITOPS": { 

997 "summary": "Self-managed Argo CD (cdk.json helm.argocd, off by default): namespaced mode fenced to gco-jobs and gco-inference by the gco-tenants AppProject and RBAC, the optional GitOps hand-off to one repository path per cluster, the repo-server autoscaler, private repositories, and the UI over a private port-forward.", 

998 "topics": ["customization", "security", "cli", "eks"], 

999 "keywords": [ 

1000 "argo cd", 

1001 "argocd", 

1002 "gitops", 

1003 "appproject", 

1004 "application", 

1005 "gco-tenants", 

1006 "repo server", 

1007 "autoscaling", 

1008 "gco gitops", 

1009 ], 

1010 "related": ["EKS_CAPABILITIES", "CROSSPLANE", "CUSTOMIZATION", "CLI"], 

1011 }, 

1012 "IMAGE_MIRROR": { 

1013 "summary": "Mirror third-party container images (chiefly Volcano's docker.io images) into the project's gco/* ECR so the cluster pulls from same-account ECR instead of a rate-limited upstream.", 

1014 "topics": ["images", "customization", "deployment", "eks", "schedulers"], 

1015 "keywords": [ 

1016 "ecr", 

1017 "mirror", 

1018 "docker hub", 

1019 "docker.io", 

1020 "volcano", 

1021 "pull-through cache", 

1022 "multi-arch", 

1023 "image_registry", 

1024 "rate limit", 

1025 "skopeo", 

1026 "buildx", 

1027 ], 

1028 "related": ["VOLCANO", "CUSTOMIZATION"], 

1029 }, 

1030 "INFERENCE": { 

1031 "summary": "Deploy and manage multi-region GPU inference endpoints, including model weight management and supported frameworks.", 

1032 "topics": [ 

1033 "inference", 

1034 "architecture", 

1035 "gpu", 

1036 "multi-region", 

1037 "cost", 

1038 "images", 

1039 "monitoring", 

1040 ], 

1041 "keywords": [ 

1042 "vllm", 

1043 "sglang", 

1044 "triton", 

1045 "endpoints", 

1046 "canary", 

1047 "rolling update", 

1048 "model weights", 

1049 "global accelerator", 

1050 "openai-compatible", 

1051 "inference monitor", 

1052 ], 

1053 "related": ["ARCHITECTURE", "RUNBOOKS"], 

1054 }, 

1055 "KEDA": { 

1056 "summary": "KEDA event-driven autoscaling integration — scales workloads from external sources like SQS, Kafka, and Prometheus.", 

1057 "topics": ["schedulers", "jobs", "autoscaling"], 

1058 "keywords": [ 

1059 "keda", 

1060 "scaledjob", 

1061 "scaledobject", 

1062 "sqs trigger", 

1063 "event-driven", 

1064 "kafka", 

1065 "prometheus", 

1066 "queue depth", 

1067 ], 

1068 "related": ["SCHEDULERS", "VOLCANO"], 

1069 }, 

1070 "KUBERAY": { 

1071 "summary": "KubeRay operator integration — runs Ray distributed computing workloads on Kubernetes for training, tuning, and serving.", 

1072 "topics": ["schedulers", "jobs", "gpu", "training", "distributed"], 

1073 "keywords": [ 

1074 "kuberay", 

1075 "ray", 

1076 "raycluster", 

1077 "rayjob", 

1078 "rayservice", 

1079 "ray tune", 

1080 "ray train", 

1081 "ray serve", 

1082 "distributed", 

1083 ], 

1084 "related": ["SCHEDULERS", "VOLCANO"], 

1085 }, 

1086 "KUEUE": { 

1087 "summary": "Kueue integration for Kubernetes-native job queueing with resource quotas, fair sharing, and priority scheduling.", 

1088 "topics": ["schedulers", "jobs"], 

1089 "keywords": [ 

1090 "kueue", 

1091 "clusterqueue", 

1092 "localqueue", 

1093 "resourceflavor", 

1094 "quota", 

1095 "fair sharing", 

1096 "priority", 

1097 "preemption", 

1098 ], 

1099 "related": ["SCHEDULERS", "VOLCANO", "YUNIKORN"], 

1100 }, 

1101 "LEARNING_PATH": { 

1102 "summary": "Staged, hands-on onboarding path for users new to GCO or Kubernetes — a Kubernetes primer, cost-boundary milestones, and role-based tracks that sequence the other guides.", 

1103 "topics": [ 

1104 "concepts", 

1105 "quickstart", 

1106 "cli", 

1107 "jobs", 

1108 "inference", 

1109 "schedulers", 

1110 ], 

1111 "keywords": [ 

1112 "learning path", 

1113 "onboarding", 

1114 "getting started", 

1115 "tutorial", 

1116 "curriculum", 

1117 "new user", 

1118 "beginner", 

1119 "kubernetes", 

1120 "first job", 

1121 "role based", 

1122 ], 

1123 "related": ["CONCEPTS", "CLI", "SCHEDULERS"], 

1124 }, 

1125 "LIVE_RELEASE_VALIDATION": { 

1126 "summary": "Local operator deploy-test-destroy harness for exact-commit live validation, guaranteed cleanup, and manually attached pull request reports.", 

1127 "topics": [ 

1128 "deployment", 

1129 "runbooks", 

1130 "security", 

1131 "automation", 

1132 "multi-region", 

1133 ], 

1134 "keywords": [ 

1135 "live release validation", 

1136 "local script", 

1137 "dedicated validation account", 

1138 "exact commit", 

1139 "deploy test destroy", 

1140 "checkpoint", 

1141 "resume", 

1142 "kms pending deletion", 

1143 "manual pull request upload", 

1144 "pull request comment", 

1145 ], 

1146 "related": ["RUNBOOKS", "MAINTENANCE", "CLI", "EXAMPLE_VALIDATION"], 

1147 }, 

1148 "EXAMPLE_VALIDATION": { 

1149 "summary": "Deploy-run-destroy validation of every shipped example manifest through its documented submission path, plus the offline static checks CI enforces on any examples/ change.", 

1150 "topics": [ 

1151 "deployment", 

1152 "runbooks", 

1153 "jobs", 

1154 "examples", 

1155 "automation", 

1156 ], 

1157 "keywords": [ 

1158 "example validation", 

1159 "examples", 

1160 "gco examples validate", 

1161 "static checks", 

1162 "documented submission path", 

1163 "kubectl tunnel", 

1164 "per-example report", 

1165 "disclosed mutations", 

1166 "capacity skip", 

1167 "feature enabled overrides", 

1168 ], 

1169 "related": ["LIVE_RELEASE_VALIDATION", "CLI", "KUBERAY", "KUEUE", "SLURM_OPERATOR"], 

1170 }, 

1171 "MAINTENANCE": { 

1172 "summary": "Routine upkeep — adding instance types to the nodepool lists, EKS Kubernetes version upgrades, base-image security-epoch refreshes, CVE-suppression renewals, and acting on the monthly dependency scan.", 

1173 "topics": [ 

1174 "customization", 

1175 "deployment", 

1176 "eks", 

1177 "nodepools", 

1178 "images", 

1179 ], 

1180 "keywords": [ 

1181 "maintenance", 

1182 "upkeep", 

1183 "upgrade", 

1184 "eks version", 

1185 "kubernetes version", 

1186 "instance types", 

1187 "instance family", 

1188 "dependency scan", 

1189 "deps-scan", 

1190 "security epoch", 

1191 "cve suppression", 

1192 "kubectl", 

1193 "helm", 

1194 "addon versions", 

1195 "requirements-lock", 

1196 ], 

1197 "related": ["CUSTOMIZATION", "RUNBOOKS", "ARCHITECTURE"], 

1198 }, 

1199 "MISSION": { 

1200 "summary": "Goal-directed iteration loop — declare a directive, criteria, tool allowlist, and budget; runs deterministic five-phase iterations until a verdict.", 

1201 "topics": [ 

1202 "concepts", 

1203 "cli", 

1204 "api", 

1205 "automation", 

1206 "feature-flags", 

1207 ], 

1208 "keywords": [ 

1209 "mission", 

1210 "directive", 

1211 "criteria", 

1212 "verdict", 

1213 "iteration", 

1214 "goal directed", 

1215 "autonomous loop", 

1216 "sampling", 

1217 "sandbox", 

1218 "predicate", 

1219 "checkpoint", 

1220 "budget", 

1221 "final report", 

1222 ], 

1223 "related": ["CLI", "ARCHITECTURE", "RUNBOOKS"], 

1224 }, 

1225 "SWARM": { 

1226 "summary": "Swarm supervision — one orchestrator Mission session spawns and drives concurrent child Mission sessions under hard rails (fleet cap, pooled iteration budget, finite child budgets) until its deterministic cascade reaches a verdict.", 

1227 "topics": [ 

1228 "concepts", 

1229 "cli", 

1230 "api", 

1231 "automation", 

1232 "feature-flags", 

1233 ], 

1234 "keywords": [ 

1235 "swarm", 

1236 "orchestrator", 

1237 "supervisor", 

1238 "child missions", 

1239 "fleet", 

1240 "spawn", 

1241 "iteration pool", 

1242 "restart policy", 

1243 "respawn", 

1244 "children status", 

1245 "swarm plan", 

1246 "concurrency", 

1247 "gco_enable_swarm", 

1248 ], 

1249 "related": ["MISSION", "CLI", "ARCHITECTURE"], 

1250 }, 

1251 "MONITORING": { 

1252 "summary": "Self-hosted per-cluster observability (kube-prometheus-stack: Prometheus + Alertmanager + Grafana), on by default, with private port-forward access and the gco monitoring CLI.", 

1253 "topics": [ 

1254 "monitoring", 

1255 "observability", 

1256 "gpu", 

1257 "schedulers", 

1258 "cli", 

1259 "concepts", 

1260 "cost", 

1261 ], 

1262 "keywords": [ 

1263 "prometheus", 

1264 "grafana", 

1265 "alertmanager", 

1266 "kube-prometheus-stack", 

1267 "dcgm", 

1268 "servicemonitor", 

1269 "podmonitor", 

1270 "dashboards", 

1271 "port-forward", 

1272 "ssm tunnel", 

1273 "gco monitoring", 

1274 "credential rotation", 

1275 "cluster observability", 

1276 ], 

1277 "related": ["ARCHITECTURE", "RUNBOOKS", "CLI", "INFERENCE"], 

1278 }, 

1279 "README": { 

1280 "summary": "Documentation index — the top-level guide map for the rest of the docs/ tree.", 

1281 "topics": ["concepts", "multi-region", "gpu", "capacity", "inference", "quickstart"], 

1282 "keywords": [ 

1283 "index", 

1284 "overview", 

1285 "guide map", 

1286 "documentation", 

1287 "table of contents", 

1288 "getting started", 

1289 ], 

1290 "related": ["CONCEPTS", "ARCHITECTURE"], 

1291 }, 

1292 "RUNBOOKS": { 

1293 "summary": "Operational runbooks — step-by-step procedures for common operational scenarios with symptoms, diagnosis, and resolution.", 

1294 "topics": [ 

1295 "runbooks", 

1296 "troubleshooting", 

1297 "jobs", 

1298 "inference", 

1299 "capacity", 

1300 "monitoring", 

1301 "deployment", 

1302 ], 

1303 "keywords": [ 

1304 "incident response", 

1305 "operational procedures", 

1306 "stuck job", 

1307 "endpoint down", 

1308 "capacity exhausted", 

1309 "stack rollback", 

1310 "playbook", 

1311 "diagnose", 

1312 "remediation", 

1313 ], 

1314 "related": ["TROUBLESHOOTING", "CLI"], 

1315 }, 

1316 "SCHEDULERS": { 

1317 "summary": "Comparison and overview of the six supported scheduling and orchestration tools — Volcano, Kueue, KubeRay, KEDA, Slurm, YuniKorn.", 

1318 "topics": ["schedulers", "concepts", "jobs", "gpu"], 

1319 "keywords": [ 

1320 "volcano", 

1321 "kueue", 

1322 "kuberay", 

1323 "keda", 

1324 "slurm", 

1325 "yunikorn", 

1326 "gang scheduling", 

1327 "batch scheduler", 

1328 "scheduler comparison", 

1329 "queueing", 

1330 ], 

1331 "related": ["VOLCANO", "KUEUE", "KUBERAY"], 

1332 }, 

1333 "SLURM_OPERATOR": { 

1334 "summary": "Slurm on GCO (Slinky) — autoscaled CPU/GPU/EFA partitions from zero, accounting with S3 backups, a login pod, metrics and alerts, the /api/v1/slurm API and gco slurm CLI, and a comparison with AWS PCS.", 

1335 "topics": ["schedulers", "jobs", "hpc"], 

1336 "keywords": [ 

1337 "slurm", 

1338 "slinky", 

1339 "sbatch", 

1340 "srun", 

1341 "salloc", 

1342 "hpc", 

1343 "scientific computing", 

1344 "mpi", 

1345 "sacct", 

1346 "accounting", 

1347 "pcs", 

1348 "autoscaling", 

1349 "partition", 

1350 ], 

1351 "related": ["SCHEDULERS", "VOLCANO"], 

1352 }, 

1353 "TROUBLESHOOTING": { 

1354 "summary": "Troubleshooting guide — common installation, deployment, kubectl, and pod issues with their resolutions.", 

1355 "topics": [ 

1356 "troubleshooting", 

1357 "runbooks", 

1358 "deployment", 

1359 "eks", 

1360 "jobs", 

1361 "inference", 

1362 "capacity", 

1363 ], 

1364 "keywords": [ 

1365 "kubectl", 

1366 "pod crashloop", 

1367 "imagepullbackoff", 

1368 "stack rollback", 

1369 "deployment failed", 

1370 "credentials", 

1371 "vpc", 

1372 "nodepool not scaling", 

1373 "common errors", 

1374 "fix", 

1375 ], 

1376 "related": ["RUNBOOKS", "CLI"], 

1377 }, 

1378 "UPGRADING": { 

1379 "summary": "Upgrading a deployment with gco upgrade — checks out the latest release tag (preserving cdk.json), refreshes the local install and dev image, scales the workload tier to zero and redeploys; what is destroyed, what to back up to the cluster-shared bucket first, and how to restore it.", 

1380 "topics": [ 

1381 "deployment", 

1382 "customization", 

1383 "cli", 

1384 "runbooks", 

1385 ], 

1386 "keywords": [ 

1387 "upgrade", 

1388 "gco upgrade", 

1389 "release", 

1390 "latest release", 

1391 "release tag", 

1392 "version", 

1393 "checkout", 

1394 "backup", 

1395 "restore", 

1396 "cluster-shared bucket", 

1397 "scale to zero", 

1398 "control plane", 

1399 "keep-control-plane", 

1400 "regional stacks", 

1401 "downgrade", 

1402 "rollback", 

1403 ], 

1404 "related": [ 

1405 "MAINTENANCE", 

1406 "CUSTOMIZATION", 

1407 "CLUSTER_SHARED_BUCKET", 

1408 "CLI", 

1409 "UPGRADE_VALIDATION", 

1410 ], 

1411 }, 

1412 "UPGRADE_VALIDATION": { 

1413 "summary": "Live validation of gco upgrade — deploys the previous release with its own gco from a private clone, upgrades it to the checked-out commit, verifies the control plane kept its stacks and data while the regional stacks were recreated, then tears everything down.", 

1414 "topics": [ 

1415 "deployment", 

1416 "runbooks", 

1417 "automation", 

1418 "cli", 

1419 ], 

1420 "keywords": [ 

1421 "upgrade validation", 

1422 "gco release validate-upgrade", 

1423 "gco upgrade", 

1424 "previous release", 

1425 "base release", 

1426 "run-tag adoption", 

1427 "synthetic release tag", 

1428 "private mirror", 

1429 "sentinel", 

1430 "resume", 

1431 ], 

1432 "related": ["UPGRADING", "LIVE_RELEASE_VALIDATION", "CLI"], 

1433 }, 

1434 "VOLCANO": { 

1435 "summary": "Volcano batch scheduler integration — gang scheduling, fair-share queuing, and job lifecycle management for AI/ML and HPC.", 

1436 "topics": ["schedulers", "jobs", "gpu", "hpc"], 

1437 "keywords": [ 

1438 "volcano", 

1439 "gang scheduling", 

1440 "vcjob", 

1441 "podgroup", 

1442 "queue", 

1443 "fair share", 

1444 "job lifecycle", 

1445 "batch", 

1446 ], 

1447 "related": ["SCHEDULERS", "KUEUE", "YUNIKORN"], 

1448 }, 

1449 "YUNIKORN": { 

1450 "summary": "Apache YuniKorn integration — multi-tenant scheduler with hierarchical queues and gang scheduling.", 

1451 "topics": ["schedulers", "jobs"], 

1452 "keywords": [ 

1453 "yunikorn", 

1454 "hierarchical queues", 

1455 "multi-tenant", 

1456 "gang scheduling", 

1457 "app-aware scheduling", 

1458 "fair share", 

1459 ], 

1460 "related": ["SCHEDULERS", "KUEUE", "VOLCANO"], 

1461 }, 

1462} 

1463 

1464 

1465# --------------------------------------------------------------------------- 

1466# Root-doc metadata — searchable project-level guidance that deliberately lives 

1467# at the repository root rather than under ``docs/``. Keep this separate from 

1468# ``DOC_METADATA`` so the strict 1:1 metadata-to-``docs/*.md`` invariant remains 

1469# meaningful. Root docs use static ``docs://gco/{name}`` resources. 

1470# --------------------------------------------------------------------------- 

1471 

1472ROOT_DOC_METADATA: dict[str, dict[str, str | list[str]]] = { 

1473 "TENETS": { 

1474 "path": "TENETS.md", 

1475 "summary": ( 

1476 "Prioritized project tenets and north-star guidance for safety, truth, " 

1477 "security, global capacity orchestration, automation, operations, cost, " 

1478 "and maintainability." 

1479 ), 

1480 "topics": [ 

1481 "concepts", 

1482 "architecture", 

1483 "security", 

1484 "automation", 

1485 "multi-region", 

1486 "deployment", 

1487 "cost", 

1488 ], 

1489 "keywords": [ 

1490 "tenets", 

1491 "north star", 

1492 "principles", 

1493 "decision framework", 

1494 "project ethos", 

1495 "safety", 

1496 "truth", 

1497 "reversibility", 

1498 "least privilege", 

1499 "capacity policy", 

1500 "deterministic automation", 

1501 "definition of done", 

1502 ], 

1503 "related": ["ARCHITECTURE", "MAINTENANCE", "LIVE_RELEASE_VALIDATION"], 

1504 } 

1505} 

1506 

1507 

1508# --------------------------------------------------------------------------- 

1509# Package-doc metadata — used by ``find_docs`` and the 

1510# ``docs://gco/packages/...`` resources to describe the package-level READMEs 

1511# that live next to the code (under ``gco_mcp/``) rather than in ``docs/``. These 

1512# are developer-facing internals guides (how a package is structured and how to 

1513# customize it), kept in a catalog separate from ``DOC_METADATA`` so the strict 

1514# 1:1 ``docs/*.md`` invariant stays intact. Each entry is keyed by a stable 

1515# slug and carries a ``path`` relative to the project root. A ``related`` entry 

1516# may reference either another package slug or a ``DOC_METADATA`` key. 

1517# --------------------------------------------------------------------------- 

1518 

1519PACKAGE_DOC_METADATA: dict[str, dict[str, str | list[str]]] = { 

1520 "mcp-server": { 

1521 "path": "gco_mcp/README.md", 

1522 "summary": "GCO MCP server guide — setup across MCP clients, feature-flag gating, and the full tool and resource catalog.", 

1523 "topics": ["mcp", "concepts", "feature-flags", "customization"], 

1524 "keywords": [ 

1525 "mcp server", 

1526 "fastmcp", 

1527 "stdio", 

1528 "feature flags", 

1529 "gco_enable", 

1530 "kiro", 

1531 "claude desktop", 

1532 "cursor", 

1533 "tool search", 

1534 "available tools", 

1535 "resources", 

1536 ], 

1537 "related": ["mcp-tools", "mcp-resources", "CLI", "MISSION"], 

1538 }, 

1539 "mcp-tools": { 

1540 "path": "gco_mcp/tools/README.md", 

1541 "summary": "How MCP tools are defined — one module per domain, the @mcp.tool + audit_logged pattern, and how to add a new tool.", 

1542 "topics": ["mcp", "customization"], 

1543 "keywords": [ 

1544 "tool", 

1545 "mcp.tool", 

1546 "audit_logged", 

1547 "cli_runner", 

1548 "adding a tool", 

1549 "tool module", 

1550 "domain", 

1551 ], 

1552 "related": ["mcp-server", "mcp-resources"], 

1553 }, 

1554 "mcp-resources": { 

1555 "path": "gco_mcp/resources/README.md", 

1556 "summary": "MCP resource modules by URI scheme (docs://, source://, k8s://, …) and how to add a new resource group.", 

1557 "topics": ["mcp", "customization"], 

1558 "keywords": [ 

1559 "resource", 

1560 "mcp.resource", 

1561 "uri scheme", 

1562 "docs scheme", 

1563 "source scheme", 

1564 "resource index", 

1565 "adding a resource", 

1566 ], 

1567 "related": ["mcp-server", "mcp-tools"], 

1568 }, 

1569 "mcp-mission": { 

1570 "path": "gco_mcp/mission/README.md", 

1571 "summary": "Mission package internals — the five-phase goal-directed loop, deterministic verdict cascade, sandboxes, and how to extend each piece.", 

1572 "topics": ["mcp", "automation", "customization", "concepts"], 

1573 "keywords": [ 

1574 "mission", 

1575 "engine", 

1576 "verdict", 

1577 "five-phase loop", 

1578 "sandbox", 

1579 "predicate", 

1580 "sampling", 

1581 "criteria", 

1582 "customize mission", 

1583 "module map", 

1584 ], 

1585 "related": ["MISSION", "mcp-metric-readers", "mcp-mission-judge", "mcp-server"], 

1586 }, 

1587 "mcp-metric-readers": { 

1588 "path": "gco_mcp/metric_readers/README.md", 

1589 "summary": "Pure helpers behind the read-only metric-reader tools — and how to add an aggregation mode, file format, error code, or whole new reader source.", 

1590 "topics": ["mcp", "metrics", "customization", "automation"], 

1591 "keywords": [ 

1592 "metric reader", 

1593 "cloudwatch", 

1594 "aggregation mode", 

1595 "file format", 

1596 "parquet", 

1597 "jsonl", 

1598 "error code", 

1599 "metrics_result", 

1600 "customize metrics", 

1601 "local root", 

1602 ], 

1603 "related": ["mcp-mission-judge", "mcp-mission", "MISSION", "mcp-server"], 

1604 }, 

1605 "mcp-mission-judge": { 

1606 "path": "gco_mcp/mission_judge/README.md", 

1607 "summary": "LLM-as-judge progress scoring internals — the versioned rubric, deterministic prompt, score parsing, and how to customize the scoring for your use case.", 

1608 "topics": ["mcp", "metrics", "customization", "automation"], 

1609 "keywords": [ 

1610 "semantic progress", 

1611 "judge", 

1612 "rubric", 

1613 "prompt", 

1614 "score parsing", 

1615 "progress_score", 

1616 "gco_enable_semantic_progress", 

1617 "llm as judge", 

1618 "customize rubric", 

1619 ], 

1620 "related": ["mcp-metric-readers", "mcp-mission", "MISSION", "mcp-server"], 

1621 }, 

1622} 

1623 

1624 

1625@mcp.resource("docs://gco/index") 

1626def docs_index() -> str: 

1627 """List all available GCO documentation, examples, and configuration resources.""" 

1628 sections = ["# GCO Resource Index\n"] 

1629 sections.append("## Project Overview") 

1630 sections.append("- `docs://gco/README` — Project README and overview") 

1631 sections.append("- `docs://gco/QUICKSTART` — Quick start guide (deploy in under 60 minutes)") 

1632 sections.append("- `docs://gco/TENETS` — Prioritized project tenets and north-star guidance") 

1633 sections.append("- `docs://gco/CONTRIBUTING` — Contributing guide\n") 

1634 

1635 sections.append("## Documentation") 

1636 sections.append( 

1637 "- `find_docs(query=..., topic=..., limit=...)` tool — search the docs catalog by topic and free-text query" 

1638 ) 

1639 sections.append( 

1640 "- `docs://gco/docs/by-topic/{topic}` — list every doc tagged with a given topic phrase" 

1641 ) 

1642 sections.append( 

1643 "- `docs://gco/docs/by-related/{doc_name}` — list every doc related to the given doc" 

1644 ) 

1645 for f in sorted(DOCS_DIR.glob("*.md")): 

1646 sections.append(f"- `docs://gco/docs/{f.stem}` — {f.stem}") 

1647 

1648 sections.append("\n## Architecture Decision Records") 

1649 sections.append( 

1650 "Append-only log of significant architectural decisions — the context, " 

1651 "the decision, and its consequences." 

1652 ) 

1653 sections.append("- `docs://gco/adr/index` — every ADR with its status (directory-driven)") 

1654 sections.append("- `docs://gco/adr/README` — when to write an ADR and the authoring process") 

1655 sections.append("- `docs://gco/adr/template` — the blank ADR template") 

1656 sections.append("- `docs://gco/adr/{id}` — read one ADR by four-digit id (e.g. `0001`)") 

1657 

1658 sections.append("\n## Package Internals") 

1659 sections.append( 

1660 "Developer-facing guides to the code packages under `gco_mcp/` — structure and " 

1661 "how to customize each. Also searchable via `find_docs`." 

1662 ) 

1663 for name, meta in PACKAGE_DOC_METADATA.items(): 

1664 sections.append(f"- `docs://gco/packages/{name}` — {meta.get('summary', '')}") 

1665 

1666 sections.append("\n## Example Manifests") 

1667 sections.append("- `docs://gco/examples/README` — Examples overview and usage guide") 

1668 sections.append( 

1669 "- `docs://gco/examples/guide` — How to create new job manifests (patterns & metadata)" 

1670 ) 

1671 

1672 sections.append("\n### Discovery") 

1673 sections.append( 

1674 "- `find_examples(query=..., category=..., gpu=..., opt_in=..., limit=...)` tool — " 

1675 "search the catalog by keyword and filters" 

1676 ) 

1677 sections.append( 

1678 "- `docs://gco/examples/by-category/{category}` — list every example in a given category" 

1679 ) 

1680 sections.append( 

1681 "- `docs://gco/examples/by-use-case/{use_case}` — list every example matching a use-case phrase" 

1682 ) 

1683 sections.append( 

1684 "- `docs://gco/examples/{name}` — full manifest plus metadata header for a single example\n" 

1685 ) 

1686 

1687 # Categorize examples 

1688 categories: dict[str, list[str]] = {} 

1689 for f in sorted(EXAMPLES_DIR.glob("*.yaml")): 

1690 name = f.stem 

1691 meta = EXAMPLE_METADATA.get(name, {}) 

1692 cat_value = meta.get("category", "Other") 

1693 cat = cat_value if isinstance(cat_value, str) else "Other" 

1694 summary_value = meta.get("summary", name) 

1695 summary = summary_value if isinstance(summary_value, str) else name 

1696 entry = f"- `docs://gco/examples/{name}` — {summary}" 

1697 categories.setdefault(cat, []).append(entry) 

1698 

1699 for cat, entries in categories.items(): 

1700 sections.append(f"### {cat}") 

1701 sections.extend(entries) 

1702 sections.append("") 

1703 

1704 sections.append("## Live State") 

1705 sections.append( 

1706 "- `gco://jobs/{region}/{job_name}` — live YAML for a Kubernetes Job in the " 

1707 "explicitly selected regional EKS cluster" 

1708 ) 

1709 sections.append( 

1710 "- `gco://inference/{endpoint_name}` — desired-state record for an inference endpoint " 

1711 "from the DynamoDB store" 

1712 ) 

1713 sections.append( 

1714 "- `gco://k8s/{region}/{namespace}/{kind}/{name}` — live YAML for any Kubernetes " 

1715 "resource from the explicitly selected regional EKS cluster" 

1716 ) 

1717 sections.append( 

1718 "- `gco://cluster/{region}/topology` — Karpenter NodePools plus Pending pods snapshot for one region" 

1719 ) 

1720 sections.append( 

1721 "- `costs://gco/summary/{days_window}` — cost summary for the given day window (positive integer)" 

1722 ) 

1723 sections.append("- `tasks://gco/{task_id}` — current status of a FastMCP background task by ID") 

1724 sections.append( 

1725 "- `mission://sessions/{session_id}` — Mission session state, report, or audit replay " 

1726 "when `GCO_ENABLE_MISSION=true`" 

1727 ) 

1728 sections.append("") 

1729 

1730 sections.append("## Other Resource Groups") 

1731 sections.append("- `k8s://gco/manifests/index` — Kubernetes manifests deployed to EKS") 

1732 sections.append("- `iam://gco/policies/index` — IAM policy templates") 

1733 sections.append("- `infra://gco/index` — Dockerfiles, Helm charts, CI/CD config") 

1734 sections.append("- `ci://gco/index` — GitHub Actions workflows, composite actions, templates") 

1735 sections.append( 

1736 "- `images://gco/index` — ECR repositories, tags, images, and replication status" 

1737 ) 

1738 sections.append("- `source://gco/index` — Source code browser") 

1739 sections.append("- `demos://gco/index` — Demo walkthroughs and scripts") 

1740 sections.append("- `clients://gco/index` — API client examples (Python, curl, AWS CLI)") 

1741 sections.append("- `scripts://gco/index` — Utility scripts") 

1742 sections.append("- `tests://gco/index` — Test suite documentation and patterns") 

1743 sections.append( 

1744 "- `config://gco/index` — authoritative CDK configuration, MCP feature flags, and environment variables" 

1745 ) 

1746 sections.append("- `mcp://gco/tools/index` — live registered-tool catalog") 

1747 sections.append("- `mcp://gco/resources/index` — live static-resource and template catalog") 

1748 sections.append("- `mcp://gco/feature-flags` — authoritative feature-gate mapping") 

1749 return "\n".join(sections) 

1750 

1751 

1752@mcp.resource("docs://gco/README") 

1753def readme_resource() -> str: 

1754 """The main project README with overview and quickstart information.""" 

1755 return (PROJECT_ROOT / "README.md").read_text() 

1756 

1757 

1758@mcp.resource("docs://gco/QUICKSTART") 

1759def quickstart_resource() -> str: 

1760 """Quick start guide — get running in under 60 minutes.""" 

1761 path = PROJECT_ROOT / "QUICKSTART.md" 

1762 if not path.is_file(): 

1763 return "QUICKSTART.md not found." 

1764 return path.read_text() 

1765 

1766 

1767@mcp.resource("docs://gco/TENETS") 

1768def tenets_resource() -> str: 

1769 """Prioritized project tenets and north-star decision guidance.""" 

1770 meta = ROOT_DOC_METADATA["TENETS"] 

1771 rel_path = str(meta["path"]) 

1772 path = PROJECT_ROOT / rel_path 

1773 if not path.is_file(): 

1774 return f"{rel_path} not found." 

1775 content = path.read_text() 

1776 topics = meta.get("topics", []) 

1777 related = meta.get("related", []) 

1778 header_lines = [] 

1779 if isinstance(topics, list) and topics: 

1780 header_lines.append(f"<!-- Topics: {', '.join(str(t) for t in topics)} -->") 

1781 if isinstance(related, list) and related: 

1782 header_lines.append(f"<!-- Related: {', '.join(str(r) for r in related)} -->") 

1783 return "\n".join(header_lines) + "\n\n" + content 

1784 

1785 

1786@mcp.resource("docs://gco/CONTRIBUTING") 

1787def contributing_resource() -> str: 

1788 """Contributing guide — how to contribute to the project.""" 

1789 path = PROJECT_ROOT / "CONTRIBUTING.md" 

1790 if not path.is_file(): 

1791 return "CONTRIBUTING.md not found." 

1792 return path.read_text() 

1793 

1794 

1795@mcp.resource("docs://gco/docs/{doc_name}") 

1796def doc_resource(doc_name: str) -> str: 

1797 """Read a documentation file by name (e.g. ARCHITECTURE, CLI, INFERENCE). 

1798 

1799 Prepends an HTML-comment header with ``Topics:`` and ``Related:`` lines 

1800 pulled from ``DOC_METADATA`` so an LLM consuming the rendered markdown 

1801 sees the doc's classification without it bleeding into the rendered 

1802 output. HTML comments are used rather than ``#`` because docs are 

1803 markdown — Python-style comments would render as text. 

1804 """ 

1805 path = DOCS_DIR / f"{doc_name}.md" 

1806 if not path.is_file(): 

1807 available = [f.stem for f in DOCS_DIR.glob("*.md")] 

1808 return f"Document '{doc_name}' not found. Available: {', '.join(available)}" 

1809 content = path.read_text() 

1810 meta = DOC_METADATA.get(doc_name, {}) 

1811 header_lines = [] 

1812 topics = meta.get("topics", []) 

1813 if isinstance(topics, list) and topics: 

1814 header_lines.append(f"<!-- Topics: {', '.join(str(t) for t in topics)} -->") 

1815 related = meta.get("related", []) 

1816 if isinstance(related, list) and related: 

1817 header_lines.append(f"<!-- Related: {', '.join(str(r) for r in related)} -->") 

1818 if header_lines: 

1819 return "\n".join(header_lines) + "\n\n" + content 

1820 return content 

1821 

1822 

1823@mcp.resource("docs://gco/packages/{package_name}") 

1824def package_doc_resource(package_name: str) -> str: 

1825 """Read a package-level README by slug (e.g. mcp-mission, mcp-metric-readers). 

1826 

1827 Serves the developer-facing internals guides catalogued in 

1828 ``PACKAGE_DOC_METADATA`` — the README files that live next to the code 

1829 under ``gco_mcp/`` rather than in ``docs/``. Prepends an HTML-comment header 

1830 with ``Topics:`` and ``Related:`` lines (mirroring :func:`doc_resource`) 

1831 so a consuming LLM sees the classification without it bleeding into the 

1832 rendered markdown. An unknown slug returns the literal ``Package doc 'X' 

1833 not found. Available: ...`` string so callers can recover. 

1834 """ 

1835 meta = PACKAGE_DOC_METADATA.get(package_name) 

1836 if meta is None: 

1837 available = ", ".join(sorted(PACKAGE_DOC_METADATA.keys())) 

1838 return f"Package doc '{package_name}' not found. Available: {available}" 

1839 rel_path = str(meta.get("path", "")) 

1840 path = PROJECT_ROOT / rel_path 

1841 if not path.is_file(): 

1842 return f"Package doc '{package_name}' file not found at '{rel_path}'." 

1843 content = path.read_text() 

1844 header_lines = [] 

1845 topics = meta.get("topics", []) 

1846 if isinstance(topics, list) and topics: 

1847 header_lines.append(f"<!-- Topics: {', '.join(str(t) for t in topics)} -->") 

1848 related = meta.get("related", []) 

1849 if isinstance(related, list) and related: 

1850 header_lines.append(f"<!-- Related: {', '.join(str(r) for r in related)} -->") 

1851 if header_lines: 

1852 return "\n".join(header_lines) + "\n\n" + content 

1853 return content 

1854 

1855 

1856@mcp.resource("docs://gco/examples/README") 

1857def examples_readme_resource() -> str: 

1858 """Examples README — overview of all example manifests with usage instructions.""" 

1859 path = EXAMPLES_DIR / "README.md" 

1860 if not path.is_file(): 

1861 return "Examples README.md not found." 

1862 return path.read_text() 

1863 

1864 

1865@mcp.resource("docs://gco/examples/guide") 

1866def examples_guide_resource() -> str: 

1867 """How to create new job manifests — patterns, metadata, and best practices. 

1868 

1869 Use this resource when you need to write a new Kubernetes manifest for GCO. 

1870 It provides the metadata for every existing example so you can pick the 

1871 closest one as a starting point and adapt it. 

1872 """ 

1873 lines = ["# GCO Example Manifest Guide\n"] 

1874 lines.append("Use this guide to create new Kubernetes manifests for GCO. Pick the closest") 

1875 lines.append("existing example as a starting point, then adapt it.\n") 

1876 lines.append("## All Examples with Metadata\n") 

1877 lines.append("| Example | Category | Keywords | GPU | Opt-in | How to Submit |") 

1878 lines.append("|---------|----------|----------|-----|--------|---------------|") 

1879 for name, meta in EXAMPLE_METADATA.items(): 

1880 gpu = meta.get("gpu", "no") 

1881 opt_in = meta.get("opt_in", "—") or "—" 

1882 submission = meta.get("submission", "") 

1883 keywords = meta.get("keywords", []) 

1884 keywords_cell = ", ".join(keywords) if isinstance(keywords, list) and keywords else "—" 

1885 lines.append( 

1886 f"| `{name}` | {meta['category']} | {keywords_cell} | {gpu} | {opt_in} | " 

1887 f"`{submission}` |" 

1888 ) 

1889 

1890 lines.append("\n## Common Patterns\n") 

1891 lines.append("### Namespace") 

1892 lines.append( 

1893 "All GCO jobs use `namespace: gco-jobs`. Inference uses `namespace: gco-inference`.\n" 

1894 ) 

1895 lines.append("### Security Context (required)") 

1896 lines.append("```yaml") 

1897 lines.append("securityContext:") 

1898 lines.append(" runAsNonRoot: true") 

1899 lines.append(" runAsUser: 1000") 

1900 lines.append(" runAsGroup: 1000") 

1901 lines.append("containers:") 

1902 lines.append("- securityContext:") 

1903 lines.append(" allowPrivilegeEscalation: false") 

1904 lines.append(" capabilities:") 

1905 lines.append(' drop: ["ALL"]') 

1906 lines.append("```\n") 

1907 lines.append("### GPU Resources") 

1908 lines.append("```yaml") 

1909 lines.append("resources:") 

1910 lines.append(" requests:") 

1911 lines.append(' nvidia.com/gpu: "1"') 

1912 lines.append(" limits:") 

1913 lines.append(' nvidia.com/gpu: "1"') 

1914 lines.append("tolerations:") 

1915 lines.append("- key: nvidia.com/gpu") 

1916 lines.append(" operator: Equal") 

1917 lines.append(' value: "true"') 

1918 lines.append(" effect: NoSchedule") 

1919 lines.append("```\n") 

1920 lines.append("### EFS Shared Storage") 

1921 lines.append("```yaml") 

1922 lines.append("volumeMounts:") 

1923 lines.append("- name: shared-storage") 

1924 lines.append(" mountPath: /mnt/gco") 

1925 lines.append("volumes:") 

1926 lines.append("- name: shared-storage") 

1927 lines.append(" persistentVolumeClaim:") 

1928 lines.append(" claimName: gco-shared-storage") 

1929 lines.append("```\n") 

1930 lines.append("### Prevent Node Consolidation (long-running jobs)") 

1931 lines.append("```yaml") 

1932 lines.append("metadata:") 

1933 lines.append(" annotations:") 

1934 lines.append(' karpenter.sh/do-not-disrupt: "true"') 

1935 lines.append("```\n") 

1936 lines.append("### Submission Methods") 

1937 lines.append("1. **SQS (recommended):** `gco jobs submit-sqs <manifest> --region <region>`") 

1938 lines.append("2. **API Gateway:** `gco jobs submit <manifest>`") 

1939 lines.append("3. **Direct kubectl:** `gco jobs submit-direct <manifest> -r <region>`") 

1940 lines.append("4. **kubectl apply:** `kubectl apply -f <manifest>`") 

1941 return "\n".join(lines) 

1942 

1943 

1944@mcp.resource("docs://gco/examples/{example_name}") 

1945def example_resource(example_name: str) -> str: 

1946 """Read an example manifest by name, with metadata context for creating similar jobs. 

1947 

1948 Returns the raw YAML manifest preceded by a metadata header that describes 

1949 what the example does, its requirements, and how to submit it. 

1950 """ 

1951 path = EXAMPLES_DIR / f"{example_name}.yaml" 

1952 if not path.is_file(): 

1953 available = [f.stem for f in EXAMPLES_DIR.glob("*.yaml")] 

1954 return f"Example '{example_name}' not found. Available: {', '.join(available)}" 

1955 

1956 meta = EXAMPLE_METADATA.get(example_name, {}) 

1957 header_lines = [] 

1958 if meta: 

1959 header_lines.append(f"# Example: {example_name}") 

1960 header_lines.append(f"# Category: {meta.get('category', 'Unknown')}") 

1961 header_lines.append(f"# Summary: {meta.get('summary', '')}") 

1962 if meta.get("gpu", "no") != "no": 

1963 header_lines.append(f"# GPU/Accelerator: {meta['gpu']}") 

1964 if meta.get("opt_in"): 

1965 header_lines.append(f"# Opt-in required: {meta['opt_in']}") 

1966 header_lines.append( 

1967 f"# Submit with: {meta.get('submission', 'kubectl apply -f examples/' + example_name + '.yaml')}" 

1968 ) 

1969 keywords = meta.get("keywords", []) 

1970 if isinstance(keywords, list) and keywords: 

1971 header_lines.append(f"# Keywords: {', '.join(keywords)}") 

1972 instance_types = meta.get("instance_types", []) 

1973 if isinstance(instance_types, list) and instance_types: 

1974 header_lines.append(f"# Instance Types: {', '.join(instance_types)}") 

1975 use_cases = meta.get("use_cases", []) 

1976 if isinstance(use_cases, list) and use_cases: 

1977 header_lines.append(f"# Use Cases: {', '.join(use_cases)}") 

1978 related = meta.get("related", []) 

1979 if isinstance(related, list) and related: 

1980 header_lines.append(f"# Related: {', '.join(related)}") 

1981 header_lines.append("#") 

1982 header_lines.append("# --- Manifest begins below ---\n") 

1983 

1984 manifest = path.read_text() 

1985 if header_lines: 

1986 return "\n".join(header_lines) + manifest 

1987 return manifest 

1988 

1989 

1990@mcp.resource("docs://gco/examples/by-category/{category}") 

1991def examples_by_category_resource(category: str) -> str: 

1992 """List examples grouped by category. 

1993 

1994 Returns a markdown listing of every example in the given category. Match 

1995 is case-insensitive against the entry's ``category`` field. When the 

1996 category is not recognised, returns the literal "Category 'X' not found. 

1997 Available: ..." string so callers can recover. 

1998 """ 

1999 matches = [ 

2000 (name, meta) 

2001 for name, meta in EXAMPLE_METADATA.items() 

2002 if str(meta.get("category", "")).lower() == category.lower() 

2003 ] 

2004 if not matches: 

2005 available = sorted({str(m.get("category", "")) for m in EXAMPLE_METADATA.values()}) 

2006 return f"Category '{category}' not found. Available: {', '.join(available)}" 

2007 lines = [f"# Examples in category: {category}\n"] 

2008 for name, meta in sorted(matches): 

2009 lines.append(f"- `docs://gco/examples/{name}` — {meta.get('summary', '')}") 

2010 return "\n".join(lines) 

2011 

2012 

2013@mcp.resource("docs://gco/examples/by-use-case/{use_case}") 

2014def examples_by_use_case_resource(use_case: str) -> str: 

2015 """List examples whose use_cases include the given phrase (case-insensitive). 

2016 

2017 Substring match against every entry in each example's ``use_cases`` list. 

2018 When nothing matches, returns the literal "No examples match use case 

2019 'X'." string with a pointer to ``find_examples`` for broader search. 

2020 """ 

2021 needle = use_case.lower() 

2022 matches: list[tuple[str, dict[str, str | list[str]]]] = [] 

2023 for name, meta in EXAMPLE_METADATA.items(): 

2024 ucs = meta.get("use_cases", []) 

2025 if isinstance(ucs, list) and any(needle in str(uc).lower() for uc in ucs): 

2026 matches.append((name, meta)) 

2027 if not matches: 

2028 return ( 

2029 f"No examples match use case '{use_case}'. " 

2030 "Try `find_examples(query=...)` for broader search." 

2031 ) 

2032 lines = [f"# Examples matching use case: {use_case}\n"] 

2033 for name, meta in sorted(matches): 

2034 lines.append(f"- `docs://gco/examples/{name}` — {meta.get('summary', '')}") 

2035 return "\n".join(lines) 

2036 

2037 

2038@mcp.resource("docs://gco/docs/by-topic/{topic}") 

2039def docs_by_topic_resource(topic: str) -> str: 

2040 """List docs whose topics include the given phrase (case-insensitive). 

2041 

2042 Substring match against every entry in each doc's ``topics`` list. When 

2043 nothing matches, returns the literal ``Topic 'X' not found. Available: 

2044 ...`` string with the union of every known topic so callers can recover. 

2045 """ 

2046 needle = topic.lower() 

2047 matches: list[tuple[str, dict[str, str | list[str]]]] = [] 

2048 for name, meta in DOC_METADATA.items(): 

2049 topics = meta.get("topics", []) 

2050 if isinstance(topics, list) and any(needle in str(t).lower() for t in topics): 

2051 matches.append((name, meta)) 

2052 if not matches: 

2053 available = sorted( 

2054 { 

2055 str(t) 

2056 for meta in DOC_METADATA.values() 

2057 for t in (meta.get("topics", []) if isinstance(meta.get("topics"), list) else []) 

2058 } 

2059 ) 

2060 return f"Topic '{topic}' not found. Available: {', '.join(available)}" 

2061 lines = [f"# Docs matching topic: {topic}\n"] 

2062 for name, meta in sorted(matches): 

2063 lines.append(f"- `docs://gco/docs/{name}` — {meta.get('summary', '')}") 

2064 return "\n".join(lines) 

2065 

2066 

2067@mcp.resource("docs://gco/docs/by-related/{doc_name}") 

2068def docs_by_related_resource(doc_name: str) -> str: 

2069 """List docs related to ``doc_name``. 

2070 

2071 Combines two views of the bidirectional relation: every doc that lists 

2072 ``doc_name`` in its own ``related`` field (referenced by) and every doc 

2073 ``doc_name`` itself lists (references). Unknown names return the literal 

2074 ``Doc 'X' not found. Available: ...`` string. 

2075 """ 

2076 if doc_name not in DOC_METADATA: 

2077 available = sorted(DOC_METADATA.keys()) 

2078 return f"Doc '{doc_name}' not found. Available: {', '.join(available)}" 

2079 

2080 referenced_by: list[str] = [] 

2081 for name, meta in DOC_METADATA.items(): 

2082 related = meta.get("related", []) 

2083 if isinstance(related, list) and doc_name in related: 

2084 referenced_by.append(name) 

2085 

2086 references: list[str] = [] 

2087 referenced_self = DOC_METADATA[doc_name].get("related", []) 

2088 if isinstance(referenced_self, list): 

2089 references = [str(r) for r in referenced_self] 

2090 

2091 lines = [f"# Docs related to {doc_name}\n"] 

2092 if references: 

2093 lines.append("## Referenced by this doc") 

2094 for ref in sorted(set(references)): 

2095 meta = DOC_METADATA.get(ref, {}) 

2096 lines.append(f"- `docs://gco/docs/{ref}` — {meta.get('summary', '')}") 

2097 lines.append("") 

2098 if referenced_by: 

2099 lines.append("## Docs that reference this one") 

2100 for ref in sorted(set(referenced_by)): 

2101 meta = DOC_METADATA.get(ref, {}) 

2102 lines.append(f"- `docs://gco/docs/{ref}` — {meta.get('summary', '')}") 

2103 return "\n".join(lines) 

2104 

2105 

2106# --------------------------------------------------------------------------- 

2107# Architecture Decision Records (ADRs) — docs://gco/adr/* 

2108# 

2109# The ADR catalog under ``docs/adr/`` is directory-driven: both the index and 

2110# the per-record resource derive everything from the files on disk, so 

2111# recording a new decision needs no change here. ``NNNN-title.md`` files are the 

2112# records; ``README.md`` (process guide) and ``template.md`` (blank form) are 

2113# guides, not records, and are excluded from the record listing. 

2114# --------------------------------------------------------------------------- 

2115 

2116_ADR_ID_RE = re.compile(r"^\d{4}-") 

2117_ADR_TITLE_PREFIX_RE = re.compile(r"^\d+\.\s*") 

2118 

2119 

2120def _adr_record_files() -> list[Path]: 

2121 """Return the numbered ADR record files (``NNNN-*.md``), sorted by id.""" 

2122 if not ADR_DIR.is_dir(): 

2123 return [] 

2124 return sorted(p for p in ADR_DIR.glob("*.md") if _ADR_ID_RE.match(p.name)) 

2125 

2126 

2127def _parse_adr(path: Path) -> dict[str, str]: 

2128 """Extract ``id``, ``title``, and ``status`` from an ADR markdown file. 

2129 

2130 Title is the first level-1 heading with any ``NNNN.`` numeric prefix 

2131 stripped; status is read from the ``- **Status:** ...`` metadata line. Both 

2132 fall back to sensible defaults so a malformed file still lists rather than 

2133 breaking the index. 

2134 """ 

2135 title = "" 

2136 status = "" 

2137 for raw in path.read_text(encoding="utf-8").splitlines(): 

2138 line = raw.strip() 

2139 if not title and line.startswith("# "): 

2140 title = _ADR_TITLE_PREFIX_RE.sub("", line[2:].strip()) 

2141 continue 

2142 if not status: 

2143 # Normalize "- **Status:** Accepted" to "status: accepted" so the 

2144 # label is matched regardless of list marker or emphasis. 

2145 plain = line.lstrip("-* ").replace("*", "") 

2146 if plain.lower().startswith("status"): 

2147 status = plain[len("status") :].lstrip(": ").strip().rstrip(".") 

2148 return { 

2149 "id": path.stem, 

2150 "title": title or path.stem, 

2151 "status": status or "Unknown", 

2152 } 

2153 

2154 

2155def _resolve_adr(adr_id: str) -> Path | None: 

2156 """Resolve an ADR request to a file under ``docs/adr/``, or ``None``. 

2157 

2158 Accepts a full filename stem (``0001-record-architecture-decisions``, 

2159 ``README``, ``template``) or a numeric id in any zero-padding (``1`` -> 

2160 ``0001``). Rejects anything containing a path separator or ``..`` so a 

2161 crafted id cannot escape the directory; because the sanitized candidate has 

2162 no separators, the joined path is always a direct child of ``docs/adr/``. 

2163 """ 

2164 candidate = adr_id.strip() 

2165 if not candidate or "/" in candidate or "\\" in candidate or ".." in candidate: 

2166 return None 

2167 if candidate.isdigit(): 

2168 want = candidate.zfill(4) 

2169 return next((p for p in _adr_record_files() if p.name[:4] == want), None) 

2170 path = ADR_DIR / f"{candidate}.md" 

2171 return path if path.is_file() else None 

2172 

2173 

2174@mcp.resource("docs://gco/adr/index") 

2175def adr_index_resource() -> str: 

2176 """List every Architecture Decision Record with its id, title, and status. 

2177 

2178 Directory-driven: scans ``docs/adr/`` for numbered ``NNNN-title.md`` records 

2179 at read time, so a newly added ADR appears here with no code change. The 

2180 process guide and the blank template are available at 

2181 ``docs://gco/adr/README`` and ``docs://gco/adr/template``. 

2182 """ 

2183 lines = ["# Architecture Decision Records\n"] 

2184 lines.append( 

2185 "Append-only log of significant architectural decisions (context, " 

2186 "decision, consequences). Read the process at `docs://gco/adr/README` " 

2187 "and start a new record from `docs://gco/adr/template`.\n" 

2188 ) 

2189 files = _adr_record_files() 

2190 if not files: 

2191 lines.append("_No ADRs have been recorded yet._") 

2192 return "\n".join(lines) 

2193 for path in files: 

2194 meta = _parse_adr(path) 

2195 lines.append(f"- `docs://gco/adr/{path.name[:4]}` — {meta['title']} ({meta['status']})") 

2196 return "\n".join(lines) 

2197 

2198 

2199@mcp.resource("docs://gco/adr/{adr_id}") 

2200def adr_resource(adr_id: str) -> str: 

2201 """Read a single ADR by id, filename stem, or guide name. 

2202 

2203 Accepts a four-digit id (``0001``), a full stem 

2204 (``0001-record-architecture-decisions``), or the ``README`` / ``template`` 

2205 guides. An unknown id returns the literal ``ADR 'X' not found. Available: 

2206 ...`` string listing the numeric ids so callers can recover. 

2207 """ 

2208 path = _resolve_adr(adr_id) 

2209 if path is None: 

2210 available = ", ".join(p.name[:4] for p in _adr_record_files()) or "none" 

2211 return f"ADR '{adr_id}' not found. Available: {available}" 

2212 return path.read_text(encoding="utf-8")