Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
8b37efc4a0 | ||
|
|
dca2d269b0 | ||
|
|
645f316c85 | ||
|
|
75cc786184 | ||
|
|
ae5780602c | ||
|
|
5fe4e1d2cf | ||
|
|
dfa2ed6529 | ||
|
|
5d05d4a17c | ||
|
|
250cc564ac | ||
|
|
b65e5681c5 | ||
|
|
2f9bb7f9a2 | ||
|
|
605aa17dad | ||
|
|
bd06e780f2 | ||
|
|
3fdb8f3886 | ||
|
|
c9e5a96ada | ||
|
|
68dfe6b1a7 | ||
|
|
39839f3078 | ||
|
|
e76c4c5951 | ||
|
|
1ba9efb855 | ||
|
|
4c9d00da78 | ||
|
|
f4bfc06e02 | ||
|
|
084f33e3b7 | ||
|
|
ef5b684a76 | ||
|
|
76f32f4740 | ||
|
|
f473ad2392 | ||
|
|
3a5aa4ed50 | ||
|
|
bca58cdad9 | ||
|
|
fbf6712455 | ||
|
|
f5b630890e | ||
|
|
551e580e10 | ||
|
|
8328d2240f | ||
|
|
1e946b1571 | ||
|
|
963ff31b2d | ||
|
|
01c1e35b6e | ||
|
|
3eb9c18eb0 | ||
|
|
e13080994e | ||
|
|
500196c7c0 | ||
|
|
009f654169 | ||
|
|
72b619e3b6 | ||
|
|
73baf72741 | ||
|
|
f639516ca0 | ||
|
|
fda158172d | ||
|
|
aa0c12f143 | ||
|
|
7d7694c809 | ||
|
|
08ef05c091 | ||
|
|
a1fe7b227a | ||
|
|
3e06c6c3b9 | ||
|
|
58522088e6 | ||
|
|
8680b31aa4 | ||
|
|
8acde25134 | ||
|
|
f28793508d | ||
|
|
53e219e032 | ||
|
|
d7dffc5d27 | ||
|
|
b74edfb469 | ||
|
|
5bbc7e832f | ||
|
|
f8b4847889 | ||
|
|
18042841aa | ||
|
|
7246c82e91 | ||
|
|
e42dc07ba8 | ||
|
|
fd4e0924cd | ||
|
|
b35d0c55d7 | ||
|
|
58a4e75621 | ||
|
|
54d004e601 | ||
|
|
fa1852b88f | ||
|
|
01d3a60ce0 | ||
|
|
4cf28b9ea5 | ||
|
|
9a0d2ce7d1 | ||
|
|
89e76b0d6b | ||
|
|
2aea4a0634 | ||
|
|
5b06f98814 | ||
|
|
dfba434cdc | ||
|
|
c2e5772323 | ||
|
|
d76caa085c | ||
|
|
3d13cd83a7 | ||
|
|
a9fe5dded5 | ||
|
|
7a98574000 | ||
|
|
990994ff7a | ||
|
|
7837dde767 | ||
|
|
f574af6537 | ||
|
|
f05842eff7 | ||
|
|
154e6940c4 | ||
|
|
91769ff58e | ||
|
|
d19031a65f | ||
|
|
8420735abd | ||
|
|
ac7e582bcf | ||
|
|
94f7332477 | ||
|
|
01e34b7d28 | ||
|
|
2a39d52726 | ||
|
|
1b60f1829e | ||
|
|
c5ade61e3a | ||
|
|
e37f21b22a | ||
|
|
9313359bd3 | ||
|
|
1570a34697 | ||
|
|
d4d9062e89 | ||
|
|
12254d7495 | ||
|
|
c74fd93ab5 | ||
|
|
038c12f4d8 | ||
|
|
7118e43f73 | ||
|
|
a000b66a97 | ||
|
|
5801b8f311 | ||
|
|
00f1bc3826 | ||
|
|
640cc7d88e | ||
|
|
65d4fc3963 | ||
|
|
94ec98dd8b | ||
|
|
96332b5b00 | ||
|
|
55aeaab54b | ||
|
|
886f823c7f | ||
|
|
eb9d58e13f | ||
|
|
493f587265 | ||
|
|
1e3fefe56a | ||
|
|
0972de24e7 | ||
|
|
f298b586a9 | ||
|
|
def812e809 | ||
|
|
dc2c84066c | ||
|
|
d57210fb9e | ||
|
|
fa1a473b91 | ||
|
|
f413bebd38 | ||
|
|
0f3ed72f62 | ||
|
|
4f1117af89 | ||
|
|
a4cc05bdfc | ||
|
|
87523c5457 | ||
|
|
ba2de00ff2 | ||
|
|
098c33e879 | ||
|
|
d9860a77de | ||
|
|
e22dda5452 | ||
|
|
fd23eaa197 | ||
|
|
d5e36199c6 | ||
|
|
3cc56b9dee | ||
|
|
2f5bbb8246 | ||
|
|
dff7f5da47 | ||
|
|
2818a69da0 | ||
|
|
408344495c | ||
|
|
9047b2af3e | ||
|
|
8cb15cf20c | ||
|
|
3c28f54827 | ||
|
|
2d6c1f16ab | ||
|
|
e5c5b94d46 | ||
|
|
afe7432a55 | ||
|
|
8719fec736 | ||
|
|
ce82aa07ec | ||
|
|
0f57980748 | ||
|
|
9bc0ee991d | ||
|
|
0da202d00d | ||
|
|
42c0006340 | ||
|
|
ddbf3bdd3b | ||
|
|
3fb5fd8606 | ||
|
|
c271c69b1f | ||
|
|
8bda35ffb2 | ||
|
|
bf300df560 | ||
|
|
2963b905e5 | ||
|
|
8e6845a5cf | ||
|
|
72c80a0156 | ||
|
|
b394ee2b75 | ||
|
|
0e80915be8 | ||
|
|
79a13bd9ac | ||
|
|
c3149c3d25 | ||
|
|
76ff2c572d | ||
|
|
d36e33b3d0 | ||
|
|
8906200734 | ||
|
|
193560981c | ||
|
|
b0d1e9d5f8 | ||
|
|
a5b9841142 | ||
|
|
c737d4b52f | ||
|
|
8c44e3f665 | ||
|
|
84e5bd4d47 | ||
|
|
96e0c77d16 | ||
|
|
1c82f00594 | ||
|
|
c1ed9ce150 | ||
|
|
27be15380d | ||
|
|
8b39d2ae8e | ||
|
|
1cb2254877 | ||
|
|
ab53012f35 | ||
|
|
710ab6b536 | ||
|
|
9fdf528665 | ||
|
|
655166b83a | ||
|
|
fb6680e83e | ||
|
|
af4e2a2849 | ||
|
|
23508a4c1b | ||
|
|
cd81458560 | ||
|
|
4ff7402207 | ||
|
|
59b5508fe3 | ||
|
|
eb3efa310d | ||
|
|
56b0f539eb | ||
|
|
9f7d457819 | ||
|
|
27716bbb4c | ||
|
|
8ad4455049 | ||
|
|
59089c4918 | ||
|
|
2697f49e2c | ||
|
|
d5f71a6f84 | ||
|
|
d8fead1146 | ||
|
|
3edd424fd3 | ||
|
|
c80e1fd4b4 | ||
|
|
bba344afa8 | ||
|
|
ca83d27a3d | ||
|
|
7d28bd4e9c | ||
|
|
b015cec250 | ||
|
|
6637f3956b | ||
|
|
b111189475 | ||
|
|
049b994180 | ||
|
|
85e47f12af | ||
|
|
294b10dca5 | ||
|
|
ac1f6be919 | ||
|
|
c9bf1e46c7 | ||
|
|
84bb583cf6 | ||
|
|
466a315151 | ||
|
|
624e2ab543 | ||
|
|
40275974c0 | ||
|
|
0c5e17f874 | ||
|
|
ec8e38a1c2 | ||
|
|
f35c348ff1 | ||
|
|
9ba26201b5 | ||
|
|
a52bd87e00 | ||
|
|
16ed0cc9e1 | ||
|
|
98041bb7b4 | ||
|
|
2081c96b39 | ||
|
|
2d9d1cef09 | ||
|
|
d56192d7db | ||
|
|
088e35feac | ||
|
|
794734ad1c | ||
|
|
68b7029975 | ||
|
|
bfdec79f41 | ||
|
|
1e6c7bbd9a | ||
|
|
06f93282e2 | ||
|
|
8ee10a16ea | ||
|
|
0b3fe9c9c6 | ||
|
|
9971945e9f | ||
|
|
f721c5714b | ||
|
|
4e9d839f2e | ||
|
|
c377b4e4d9 | ||
|
|
bcbb3a2466 | ||
|
|
21a63a1992 | ||
|
|
6ef1580b43 | ||
|
|
1711eb594e | ||
|
|
680d5f83f5 | ||
|
|
b5f1a3d4a4 | ||
|
|
cedd14e128 | ||
|
|
6fb3808850 | ||
|
|
1698351fb9 | ||
|
|
48b1c80a80 | ||
|
|
b73d8315e5 | ||
|
|
d1e1ba5fb3 | ||
|
|
07ac1df305 | ||
|
|
e01f720655 | ||
|
|
8e065c5406 | ||
|
|
6b311deed5 | ||
|
|
2a90ce60ea | ||
|
|
f588a7254b | ||
|
|
a86f8f5c0a | ||
|
|
15aae43489 | ||
|
|
123d53848c | ||
|
|
7bf22fbe43 | ||
|
|
01c514b07b | ||
|
|
4d25baee03 | ||
|
|
3fa1370e30 | ||
|
|
a083fb2af4 | ||
|
|
f16a1ae9c0 | ||
|
|
a6e166661f | ||
|
|
f51d4094a1 | ||
|
|
fcdc4d0ec1 | ||
|
|
fcf47473da | ||
|
|
dcc323ead3 | ||
|
|
16784ce925 | ||
|
|
09d7a68ef8 | ||
|
|
a96919d3ad | ||
|
|
fdb93ccc16 | ||
|
|
e14e78c6e9 | ||
|
|
a07267dd2b | ||
|
|
58d1be6522 | ||
|
|
bff5d72a89 | ||
|
|
266499ac2f | ||
|
|
a6cf0d97ef | ||
|
|
41e4fc9502 | ||
|
|
15ffc91ec2 | ||
|
|
385c7f03da | ||
|
|
088dc12a8e | ||
|
|
a477989bc1 | ||
|
|
e7d9c0eccc | ||
|
|
7c8f36addd | ||
|
|
8643517e2e | ||
|
|
4ef377d62d | ||
|
|
ae0af172dc | ||
|
|
70f64d37b0 | ||
|
|
4d0be41548 | ||
|
|
b79209ab5e | ||
|
|
e21f237fa9 | ||
|
|
b22d1748c4 | ||
|
|
9bbb82b00c | ||
|
|
c7662a35b4 | ||
|
|
f983d787b0 | ||
|
|
c41028e023 | ||
|
|
ea5e6e80df | ||
|
|
d60cd4de4a | ||
|
|
bd5499a9c6 | ||
|
|
bfe743a6cd | ||
|
|
2e281e98ea | ||
|
|
32a2f5925a | ||
|
|
49b3405097 | ||
|
|
d90763f8bd | ||
|
|
17f438553b | ||
|
|
8f6fc3caad | ||
|
|
851efb3050 | ||
|
|
a5ff06cafb | ||
|
|
e1df3938d5 | ||
|
|
f91afaa6d2 | ||
|
|
dc8cdac96d | ||
|
|
44b4b81317 | ||
|
|
b52f793ea5 | ||
|
|
f60d071e40 | ||
|
|
57ebe6cec3 | ||
|
|
60abdc60d5 | ||
|
|
1834227e72 | ||
|
|
19b7b44e20 | ||
|
|
4cd9c4bbf0 | ||
|
|
600dceff4e | ||
|
|
2b7f55ad9d | ||
|
|
c76ad03539 | ||
|
|
ad62e46f9e | ||
|
|
48e8f71b6d | ||
|
|
d1d986bf78 | ||
|
|
81a73acc65 | ||
|
|
c095672810 | ||
|
|
2c9b460462 | ||
|
|
ebba2c81f6 | ||
|
|
92dab5e0ee | ||
|
|
da96dbc08a | ||
|
|
5eec0880f7 | ||
|
|
b470c4acdb | ||
|
|
c70aef8b78 | ||
|
|
3ff5a4e29a | ||
|
|
94ac0b73a2 | ||
|
|
3669753fb1 | ||
|
|
00cf39f19b | ||
|
|
8eea34b1d1 | ||
|
|
8ad8230014 | ||
|
|
ebc7e7a26f | ||
|
|
6a1b944e45 | ||
|
|
a05d33381a | ||
|
|
2b5bb54d94 | ||
|
|
803870adc5 | ||
|
|
eeef76614d | ||
|
|
cc9e7ae220 | ||
|
|
47aec8ed87 | ||
|
|
d31cf94c8d | ||
|
|
9f70c32ff5 | ||
|
|
7425a6a4cb | ||
|
|
891f4b8dbd | ||
|
|
7c467ea752 | ||
|
|
6050b39545 | ||
|
|
29abd31e56 | ||
|
|
6090747083 | ||
|
|
fe08a271f4 | ||
|
|
1fe0509433 | ||
|
|
d9ed471d16 | ||
|
|
6bed317cdc | ||
|
|
a0927d47f7 | ||
|
|
543e3c4d82 | ||
|
|
6a4a1278df | ||
|
|
a6b0b19fbd | ||
|
|
59d6234792 | ||
|
|
e95cd9dc56 | ||
|
|
68078fa253 | ||
|
|
79e0fc7f53 | ||
|
|
5ade4daaec | ||
|
|
421765d66f | ||
|
|
4eb8e1c21c | ||
|
|
9d13a6a21a | ||
|
|
5de57738cb | ||
|
|
c90d45cb4b | ||
|
|
325eb8a83a | ||
|
|
361f34a74a | ||
|
|
89016b7e64 | ||
|
|
4212b1f5ae | ||
|
|
8cd85a35e8 | ||
|
|
f85439c757 | ||
|
|
0d10c89a0f | ||
|
|
919ecd9dfd | ||
|
|
882baa7917 | ||
|
|
1def1edd28 | ||
|
|
4b65cbc9de | ||
|
|
1fe5356c7c | ||
|
|
dcc01e833a | ||
|
|
99c9e2f8f0 | ||
|
|
858f969b93 | ||
|
|
9c3c026f1b | ||
|
|
ce96d91c55 | ||
|
|
546e1df714 | ||
|
|
e773676a70 | ||
|
|
10c20f6665 | ||
|
|
72bb3c5150 | ||
|
|
43fae0f9d0 | ||
|
|
cfe98dcada | ||
|
|
6308fc66ea | ||
|
|
1c182e500d | ||
|
|
608e072dda | ||
|
|
0ae118d85b | ||
|
|
9c4adeb5ac | ||
|
|
1dd0dab308 | ||
|
|
e599793928 | ||
|
|
7f5fbe34ee | ||
|
|
119bd4158f | ||
|
|
a355889969 | ||
|
|
cf717c67ce | ||
|
|
512b37287e | ||
|
|
23256352a7 | ||
|
|
101b341200 | ||
|
|
1b56b77cbf | ||
|
|
655ad7d5ed | ||
|
|
29e2593e42 | ||
|
|
1e89f8af00 | ||
|
|
1a092a5af2 | ||
|
|
f4208bca4d | ||
|
|
90d04e6d6a | ||
|
|
7d845fab3e | ||
|
|
fbfa85c2d3 | ||
|
|
dc4591fb3e | ||
|
|
96706aff90 | ||
|
|
f3cb3a1ff3 | ||
|
|
cc6633dcdd | ||
|
|
759c10ad2c | ||
|
|
58601de338 | ||
|
|
11ebda6187 | ||
|
|
227dc23933 | ||
|
|
56db4d5e53 | ||
|
|
e332af2ea8 | ||
|
|
9d3321d0f0 | ||
|
|
9ed1318a9c | ||
|
|
91da9c8495 | ||
|
|
c9a7b2a8cb | ||
|
|
ad59cb75f0 | ||
|
|
88f891fd4e | ||
|
|
61733937be | ||
|
|
10c70025a2 | ||
|
|
cff4903166 | ||
|
|
16ad26f427 | ||
|
|
3f3a86b62c | ||
|
|
239dd05e6f | ||
|
|
932770b89b | ||
|
|
c8ca878f66 | ||
|
|
64c6e9ea18 | ||
|
|
53b19f1b09 | ||
|
|
f6e60a6487 | ||
|
|
5bfcaf1b03 | ||
|
|
b8144d9253 | ||
|
|
b321169459 | ||
|
|
34610f4671 | ||
|
|
f50fdffd64 | ||
|
|
f5fae99a38 | ||
|
|
ebae3c6e27 | ||
|
|
a8941afd24 | ||
|
|
f4fb5fe19b | ||
|
|
f46886abf3 | ||
|
|
6ccda021e2 | ||
|
|
3f44948119 | ||
|
|
fe024b4fd7 | ||
|
|
bdcedd6950 | ||
|
|
6769fff528 | ||
|
|
5b00ed4824 | ||
|
|
7e85ec6bdd | ||
|
|
dc0e090318 | ||
|
|
6f34ac8569 | ||
|
|
5d7f58c7fa | ||
|
|
52e2560fa0 | ||
|
|
41207ca0f0 | ||
|
|
b5b3dc3ce2 | ||
|
|
f221647646 | ||
|
|
099a40d6b1 | ||
|
|
74cbc47e2e | ||
|
|
f90d66478f | ||
|
|
d846c6f336 | ||
|
|
01634bceb2 | ||
|
|
d456128366 | ||
|
|
13d51e8fa9 | ||
|
|
87809870c5 | ||
|
|
e1b49ab4b5 | ||
|
|
57f9c618f1 | ||
|
|
65ce209183 | ||
|
|
fdd9eac809 | ||
|
|
059b4de3e8 | ||
|
|
a11bfe4ced | ||
|
|
9cb73cadcc | ||
|
|
05b66d006f | ||
|
|
3dc52af391 | ||
|
|
8b04851097 | ||
|
|
782dc1bd06 | ||
|
|
1149a9c8f7 | ||
|
|
4e87c248fd | ||
|
|
51e8ec8cfa | ||
|
|
138b63c69f | ||
|
|
95c7078e6a | ||
|
|
cba67c689c | ||
|
|
e527be5189 | ||
|
|
1cd243ee58 | ||
|
|
0c3ae9661c | ||
|
|
0f53474aa9 | ||
|
|
12402e089d | ||
|
|
871bd30e75 | ||
|
|
78f5600e75 | ||
|
|
d7c9162cb8 | ||
|
|
24b5bbc6a2 | ||
|
|
42442a1a6c | ||
|
|
68c8bf6715 | ||
|
|
5fe5431c53 | ||
|
|
7d2194e923 | ||
|
|
67092bc4d2 | ||
|
|
c2b1c39e1f | ||
|
|
83516999f9 | ||
|
|
03ff019622 | ||
|
|
96557026c0 | ||
|
|
8721f828ac | ||
|
|
bfb00ae1d3 | ||
|
|
ddeda5d5cd | ||
|
|
8f31612b05 | ||
|
|
9635422d33 | ||
|
|
969980f69a | ||
|
|
ced3553734 | ||
|
|
52b5254340 | ||
|
|
1a5e3c6a0a | ||
|
|
fd2cd3c6ad | ||
|
|
095125d8c6 | ||
|
|
11aa0026c8 | ||
|
|
852077cb5b | ||
|
|
5b90fef67b | ||
|
|
9a611d2456 | ||
|
|
8171a464a5 | ||
|
|
58bbec3524 | ||
|
|
4cffc04b2f | ||
|
|
7d76cb862e | ||
|
|
622dcf52ea | ||
|
|
f190c92645 | ||
|
|
51907d4359 | ||
|
|
617c700018 | ||
|
|
6f4b5240d1 | ||
|
|
80c2c65a80 | ||
|
|
469276fbcd | ||
|
|
4d660f6e39 |
@@ -0,0 +1,75 @@
|
||||
# Skill: Local Operations for Awesome-Kubernetes Maintenance
|
||||
|
||||
This skill documents the local verification, editing, and deployment procedures for the Antigravity AI Agent when pair-programming with the repository maintainer.
|
||||
|
||||
---
|
||||
|
||||
## 🛠️ Local Environment & Python Context
|
||||
|
||||
The repository utilizes a virtual environment located in `.venv/` in the project root. Always prefix Python and CLI tool execution with the virtual environment path to ensure the correct dependencies are utilized.
|
||||
|
||||
* **Python Virtual Environment**: `.venv/bin/python`
|
||||
* **MkDocs Command**: `.venv/bin/mkdocs`
|
||||
* **Pip Dependency Installer**: `.venv/bin/pip`
|
||||
|
||||
---
|
||||
|
||||
## 🧪 Local Testing & Verification
|
||||
|
||||
Before promoting changes to master, always verify changes locally using these commands:
|
||||
|
||||
### 1. Markdown Lint Checks
|
||||
Verify that no syntax or styling violations are present. We ignore line length (MD013), bullet indentation (MD005/007), and other formatting conflicts. Run the linter locally:
|
||||
```bash
|
||||
echo '{ "MD004": false, "MD005": false, "MD007": false, "MD009": false, "MD010": false, "MD012": false, "MD013": false, "MD014": false, "MD022": false, "MD028": false, "MD030": false, "MD032": false, "MD033": false, "MD034": false, "MD036": false, "MD038": false, "MD041": false, "MD046": false, "MD047": false, "MD050": false, "MD051": false, "MD055": false, "MD060": false }' > .markdownlint.json
|
||||
npx markdownlint-cli2 "docs/**/*.md" "v2-docs/**/*.md" "README.md"
|
||||
```
|
||||
|
||||
### 2. Static Build Compilations
|
||||
Verify that MkDocs compiles the site targets without warnings or invalid path errors:
|
||||
```bash
|
||||
.venv/bin/mkdocs build -f mkdocs.yml && .venv/bin/mkdocs build -f v2-mkdocs.yml
|
||||
```
|
||||
|
||||
### 3. V2 Elite Portal Generation (Render-Only)
|
||||
If you need to manually recompile V2 markdown files from the inventory database (`data/inventory.yaml`) without running heavy API fetches or network sweeps:
|
||||
```bash
|
||||
PYTHONPATH=. .venv/bin/python -m src.v2_optimizer --render-only
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 📦 Git & Release Lifecycle
|
||||
|
||||
Always follow this exact branch promotion sequence to ensure clean history and trigger the production pipelines:
|
||||
|
||||
### 1. Commit and Push to Develop
|
||||
Keep the `develop` branch updated with all source modifications:
|
||||
```bash
|
||||
git checkout develop
|
||||
git pull origin develop --no-rebase --no-edit
|
||||
git add <modified_files>
|
||||
git commit -m "style/feat/fix: <description>"
|
||||
git push origin develop
|
||||
```
|
||||
|
||||
### 2. Promote to Master
|
||||
Promote verified changes to the master branch to trigger pages deployment:
|
||||
```bash
|
||||
git checkout master
|
||||
git pull origin master --no-rebase --no-edit
|
||||
git merge develop --no-edit
|
||||
# If conflict occurs in auto-generated files (v2-docs/*), accept ours:
|
||||
# git diff --name-only --diff-filter=U | xargs git checkout --ours
|
||||
# git add v2-docs/ && git commit -m "merge develop into master"
|
||||
git push origin master
|
||||
git checkout develop
|
||||
```
|
||||
|
||||
### 3. Generate a GitHub Release
|
||||
Use the GitHub CLI (`gh`) to create a release tag:
|
||||
```bash
|
||||
gh release create v<major>.<minor>.<patch> \
|
||||
--title "v<major>.<minor>.<patch>: <short description>" \
|
||||
--notes "Release summary and key changes"
|
||||
```
|
||||
@@ -178,6 +178,21 @@ jobs:
|
||||
gh workflow run 01.1.agentic_cron.yml -f historical_mode=true -f historical_chunked=true -f historical_until_date=$NEXT_DATE
|
||||
fi
|
||||
|
||||
- name: Run Deduplication Scan
|
||||
if: success()
|
||||
env:
|
||||
PYTHONPATH: .
|
||||
run: |
|
||||
python -u -c "import asyncio; from src.dedup import run_dedup; asyncio.run(run_dedup(dry_run=False))" || echo "Dedup scan skipped"
|
||||
|
||||
- name: Run Enrichment Pipeline
|
||||
if: success()
|
||||
env:
|
||||
PYTHONPATH: .
|
||||
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
run: |
|
||||
python -u -m src.enrichment || echo "Enrichment pipeline skipped"
|
||||
|
||||
- name: Upload Visual Dashboard Artifact
|
||||
if: always()
|
||||
uses: actions/upload-artifact@v7
|
||||
|
||||
@@ -18,7 +18,7 @@ permissions:
|
||||
pull-requests: write
|
||||
|
||||
concurrency:
|
||||
group: develop-git-push-${{ github.ref }}
|
||||
group: develop-git-write-lock
|
||||
cancel-in-progress: false
|
||||
|
||||
jobs:
|
||||
@@ -61,13 +61,17 @@ jobs:
|
||||
run: |
|
||||
git config --global user.name "Nubenetes Bot"
|
||||
git config --global user.email "bot@nubenetes.com"
|
||||
git add data/inventory.yaml
|
||||
git add data/inventory.yaml data/inventory.sql
|
||||
if git diff --staged --quiet; then
|
||||
echo "No changes in inventory.yaml to commit."
|
||||
echo "No changes in inventory to commit."
|
||||
else
|
||||
git commit -m "chore: update inventory stars and licenses [skip ci]"
|
||||
git pull origin develop --rebase
|
||||
git push origin develop
|
||||
# Retry rebase+push to survive concurrent bot pushes to develop.
|
||||
for i in {1..5}; do
|
||||
git pull origin develop --rebase && git push origin develop && exit 0
|
||||
echo "Push attempt $i/5 rejected — retrying..."; sleep $((i * 3))
|
||||
done
|
||||
echo "::error::Inventory metadata push failed after 5 attempts."; exit 1
|
||||
fi
|
||||
|
||||
- name: Persist Incremental Inventory to Cache
|
||||
|
||||
@@ -27,7 +27,7 @@ permissions:
|
||||
pull-requests: write
|
||||
|
||||
concurrency:
|
||||
group: develop-git-push-${{ github.ref }}
|
||||
group: develop-git-write-lock
|
||||
cancel-in-progress: false
|
||||
|
||||
jobs:
|
||||
@@ -75,13 +75,17 @@ jobs:
|
||||
run: |
|
||||
git config --global user.name "Nubenetes Bot"
|
||||
git config --global user.email "bot@nubenetes.com"
|
||||
git add data/inventory.yaml
|
||||
git add data/inventory.yaml data/inventory.sql
|
||||
if git diff --staged --quiet; then
|
||||
echo "No changes in AI analysis to commit."
|
||||
else
|
||||
git commit -m "chore: update inventory AI analysis"
|
||||
git pull origin develop --rebase
|
||||
git push origin develop
|
||||
# Retry rebase+push to survive concurrent bot pushes to develop.
|
||||
for i in {1..5}; do
|
||||
git pull origin develop --rebase && git push origin develop && exit 0
|
||||
echo "Push attempt $i/5 rejected — retrying..."; sleep $((i * 3))
|
||||
done
|
||||
echo "::error::Inventory AI-analysis push failed after 5 attempts."; exit 1
|
||||
fi
|
||||
|
||||
- name: Persist Incremental Inventory to Cache
|
||||
|
||||
@@ -32,7 +32,7 @@ permissions:
|
||||
pull-requests: write
|
||||
|
||||
concurrency:
|
||||
group: develop-git-push-${{ github.ref }}
|
||||
group: develop-git-write-lock
|
||||
cancel-in-progress: false
|
||||
|
||||
jobs:
|
||||
@@ -85,13 +85,17 @@ jobs:
|
||||
run: |
|
||||
git config --global user.name "Nubenetes Bot"
|
||||
git config --global user.email "bot@nubenetes.com"
|
||||
git add data/inventory.yaml v2-docs/videos/
|
||||
git add data/inventory.yaml data/inventory.sql v2-docs/videos/
|
||||
if git diff --staged --quiet; then
|
||||
echo "No automated changes to commit."
|
||||
else
|
||||
git commit -m "docs: update Video Hub with high-fidelity metadata"
|
||||
git pull origin develop --rebase
|
||||
git push origin develop
|
||||
# Retry rebase+push to survive concurrent bot pushes to develop.
|
||||
for i in {1..5}; do
|
||||
git pull origin develop --rebase && git push origin develop && exit 0
|
||||
echo "Push attempt $i/5 rejected — retrying..."; sleep $((i * 3))
|
||||
done
|
||||
echo "::error::Video Hub push failed after 5 attempts."; exit 1
|
||||
fi
|
||||
|
||||
- name: Persist Incremental Inventory Cache
|
||||
|
||||
@@ -23,7 +23,7 @@ permissions:
|
||||
pull-requests: write
|
||||
|
||||
concurrency:
|
||||
group: develop-git-push-${{ github.ref }}
|
||||
group: develop-git-write-lock
|
||||
cancel-in-progress: false
|
||||
|
||||
jobs:
|
||||
@@ -60,7 +60,7 @@ jobs:
|
||||
- name: Installation of Dependencies
|
||||
run: |
|
||||
pip install --no-cache-dir pydantic PyGithub httpx fake-useragent pytz python-dotenv pyyaml tenacity
|
||||
|
||||
|
||||
- name: Execute Video Portal Generator
|
||||
env:
|
||||
PYTHONPATH: ${{ github.workspace }}
|
||||
@@ -73,6 +73,37 @@ jobs:
|
||||
run: |
|
||||
python src/reorganize_mosaic.py
|
||||
|
||||
- name: Run Deduplication Scan
|
||||
env:
|
||||
PYTHONPATH: ${{ github.workspace }}
|
||||
run: |
|
||||
python -u -c "import asyncio; from src.dedup import run_dedup; asyncio.run(run_dedup(dry_run=False))" || echo "Dedup scan skipped"
|
||||
|
||||
- name: Run Enrichment Pipeline
|
||||
env:
|
||||
PYTHONPATH: ${{ github.workspace }}
|
||||
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
run: |
|
||||
python -u -m src.enrichment || echo "Enrichment pipeline skipped (no token or error)"
|
||||
|
||||
- name: Generate News Digest (Incremental)
|
||||
env:
|
||||
PYTHONPATH: ${{ github.workspace }}
|
||||
GEMINI_API_KEY_1: ${{ secrets.GEMINI_API_KEY_1 }}
|
||||
GEMINI_API_KEY_2: ${{ secrets.GEMINI_API_KEY_2 }}
|
||||
run: |
|
||||
# The engine loads news_digest.json from the repo, checks per-cell
|
||||
# hashes, and only calls Gemini for categories with new entries or
|
||||
# results older than MAX_STALENESS_DAYS (30). Typical re-runs with
|
||||
# no inventory changes cost 0 Gemini API calls.
|
||||
python -u -m src.news_digest || echo "News digest generation skipped (no API key or error)"
|
||||
|
||||
- name: Generate RSS Feed
|
||||
env:
|
||||
PYTHONPATH: ${{ github.workspace }}
|
||||
run: |
|
||||
python -u -m src.rss_generator || echo "RSS generation skipped"
|
||||
|
||||
- name: Run V2 Publisher (Render-Only)
|
||||
env:
|
||||
PYTHONPATH: ${{ github.workspace }}
|
||||
@@ -93,34 +124,49 @@ jobs:
|
||||
python -m src.safety_readme
|
||||
|
||||
- name: Commit and Push V2 Elite Updates
|
||||
env:
|
||||
PYTHONPATH: ${{ github.workspace }}
|
||||
run: |
|
||||
git config --global user.name "Nubenetes Bot"
|
||||
git config --global user.email "bot@nubenetes.com"
|
||||
git add -A
|
||||
if git diff --staged --quiet; then
|
||||
echo "No automated changes to commit."
|
||||
else
|
||||
git commit -m "feat: sync V2 elite curated edition and README metrics [skip ci]"
|
||||
# Pull and rebase with automatic resolution of README.md conflicts by regenerating metrics
|
||||
for i in {1..5}; do
|
||||
if git pull origin develop --rebase; then
|
||||
git push origin develop && exit 0
|
||||
else
|
||||
echo "Rebase conflict detected, attempting self-healing..."
|
||||
# Discard local conflicting changes to README.md and accept remote
|
||||
git checkout --ours README.md || git checkout --theirs README.md
|
||||
git add README.md
|
||||
# Continue rebase
|
||||
GIT_EDITOR=true git rebase --continue || { git rebase --abort; git pull origin develop; }
|
||||
# Re-run README sync to update metrics with remote state incorporated
|
||||
python -m src.readme_updater
|
||||
python -m src.safety_readme
|
||||
git add README.md
|
||||
git commit --amend --no-edit
|
||||
fi
|
||||
done
|
||||
git push origin develop
|
||||
exit 0
|
||||
fi
|
||||
git commit -m "feat: sync V2 elite curated edition and README metrics [skip ci]"
|
||||
OUR=$(git rev-parse HEAD)
|
||||
# Deterministic publish loop (replaces the fragile rebase + --ours/--theirs
|
||||
# self-healing that could hang on a conflict and discard the bot's metrics).
|
||||
# The render is authoritative for its generated surface, so each attempt:
|
||||
# 1. hard-resets to the freshest remote tip (no conflict possible),
|
||||
# 2. overlays our generated outputs verbatim (docs/, v2-docs/, inventory,
|
||||
# news_digest) — source configs in data/ are left untouched,
|
||||
# 3. regenerates README.md (a pure function of the inventory) on top,
|
||||
# 4. commits and pushes; on rejection it retries from the new tip.
|
||||
GENERATED="docs v2-docs data/inventory.yaml data/inventory.sql data/news_digest.json"
|
||||
for i in {1..5}; do
|
||||
echo "Publish attempt $i/5..."
|
||||
git fetch origin develop
|
||||
git reset --hard origin/develop
|
||||
git checkout "$OUR" -- $GENERATED
|
||||
python -m src.readme_updater
|
||||
python -m src.safety_readme
|
||||
git add -A
|
||||
if git diff --staged --quiet; then
|
||||
echo "Remote already matches this render. Nothing to push."
|
||||
exit 0
|
||||
fi
|
||||
git commit -m "feat: sync V2 elite curated edition and README metrics [skip ci]"
|
||||
if git push origin develop; then
|
||||
echo "Push succeeded on attempt $i."
|
||||
exit 0
|
||||
fi
|
||||
echo "Attempt $i rejected — remote advanced, retrying from fresh tip..."
|
||||
sleep $((i * 3))
|
||||
done
|
||||
echo "::error::V2 publish push failed after 5 attempts (persistent write contention on develop)."
|
||||
exit 1
|
||||
|
||||
- name: Create or Update Promotion PR to Master
|
||||
env:
|
||||
|
||||
@@ -15,7 +15,7 @@ permissions:
|
||||
contents: write
|
||||
|
||||
concurrency:
|
||||
group: develop-git-push-${{ github.ref }}
|
||||
group: develop-git-write-lock
|
||||
cancel-in-progress: false
|
||||
|
||||
jobs:
|
||||
@@ -58,28 +58,34 @@ jobs:
|
||||
run: |
|
||||
git config --global user.name "Nubenetes Bot"
|
||||
git config --global user.email "bot@nubenetes.com"
|
||||
git add README.md
|
||||
if git diff --staged --quiet; then
|
||||
echo "No changes in README.md to commit."
|
||||
else
|
||||
export PYTHONPATH=$PYTHONPATH:.
|
||||
# README.md is a *pure function* of the inventory, so we never need to
|
||||
# preserve a local README state: each attempt hard-resets to the freshest
|
||||
# remote tip, regenerates, commits and pushes. This eliminates the two
|
||||
# failure classes that previously broke this job:
|
||||
# 1. Dirty-tree abort — the earlier steps modify README.md, then
|
||||
# `git pull` aborted with "local changes would be overwritten by merge".
|
||||
# 2. Merge/rebase --ours/--theirs confusion under concurrent bot pushes.
|
||||
# A push can now only be rejected if the remote advanced between reset and
|
||||
# push; we simply retry from the new tip. No conflict resolution required.
|
||||
for i in {1..5}; do
|
||||
echo "README sync attempt $i/5..."
|
||||
git fetch origin develop
|
||||
git reset --hard origin/develop
|
||||
python src/readme_updater.py
|
||||
python src/safety_readme.py
|
||||
git add README.md
|
||||
if git diff --staged --quiet; then
|
||||
echo "README already in sync with inventory. Nothing to commit."
|
||||
exit 0
|
||||
fi
|
||||
git commit -m "docs: automated README metric synchronization [skip ci]"
|
||||
# Pull and rebase with automatic resolution of README.md conflicts by regenerating metrics
|
||||
for i in {1..5}; do
|
||||
if git pull origin develop --rebase; then
|
||||
git push origin develop && exit 0
|
||||
else
|
||||
echo "Rebase conflict detected, attempting self-healing..."
|
||||
# Discard local conflicting changes to README.md and accept remote
|
||||
git checkout --ours README.md || git checkout --theirs README.md
|
||||
git add README.md
|
||||
# Continue rebase
|
||||
GIT_EDITOR=true git rebase --continue || { git rebase --abort; git pull origin develop; }
|
||||
# Re-run README sync to update metrics with remote state incorporated
|
||||
python -m src.readme_updater
|
||||
python -m src.safety_readme
|
||||
git add README.md
|
||||
git commit --amend --no-edit
|
||||
fi
|
||||
done
|
||||
git push origin develop
|
||||
fi
|
||||
if git push origin develop; then
|
||||
echo "Push succeeded on attempt $i."
|
||||
exit 0
|
||||
fi
|
||||
echo "Attempt $i rejected — remote advanced, retrying from fresh tip..."
|
||||
sleep $((i * 3))
|
||||
done
|
||||
echo "::error::README sync failed after 5 attempts (persistent write contention on develop)."
|
||||
exit 1
|
||||
|
||||
@@ -25,6 +25,9 @@ jobs:
|
||||
uses: actions/checkout@v6
|
||||
with:
|
||||
submodules: true
|
||||
# Full history so mkdocs-git-revision-date-localized can compute the
|
||||
# real per-page "last updated" date (shallow clone => all build-date).
|
||||
fetch-depth: 0
|
||||
|
||||
- name: Setup Python
|
||||
uses: actions/setup-python@v6
|
||||
@@ -49,6 +52,19 @@ jobs:
|
||||
- name: Assemble Final Site
|
||||
run: |
|
||||
mkdir -p site/
|
||||
|
||||
# Safety check: V2 must have a valid index.html and at least 50 pages
|
||||
V2_PAGE_COUNT=$(find site_v2/ -name "*.html" | wc -l)
|
||||
if [ "$V2_PAGE_COUNT" -lt 50 ] || [ ! -f site_v2/index.html ]; then
|
||||
echo "❌ V2 build looks broken (only $V2_PAGE_COUNT HTML pages). Deploying V1 only to protect the site."
|
||||
cp -r site_v1/* site/
|
||||
mkdir -p site/v1/
|
||||
cp -r site_v1/* site/v1/
|
||||
rm -rf site_v1/ site_v2/
|
||||
exit 0
|
||||
fi
|
||||
|
||||
echo "✅ V2 build OK ($V2_PAGE_COUNT pages). Assembling dual-version site."
|
||||
# Copy V1 to root as fallback for any pages not present in V2
|
||||
cp -r site_v1/* site/
|
||||
# Overwrite root with V2 Elite Portal (matching pages will be V2 versions)
|
||||
|
||||
@@ -10,6 +10,11 @@ on:
|
||||
required: false
|
||||
type: string
|
||||
|
||||
# Cancel superseded Guardian runs when a PR is updated (saves CI minutes + Gemini calls).
|
||||
concurrency:
|
||||
group: pr-guardian-${{ github.event.pull_request.number || github.ref }}
|
||||
cancel-in-progress: true
|
||||
|
||||
jobs:
|
||||
agentic-presubmit:
|
||||
runs-on: ubuntu-latest
|
||||
@@ -35,6 +40,11 @@ jobs:
|
||||
pip install --no-cache-dir pydantic PyGithub httpx fake-useragent pytz python-dotenv pyyaml tenacity
|
||||
|
||||
- name: Run PR Guardian Analysis
|
||||
# Advisory gate: the Guardian is an AI heuristic that can misattribute
|
||||
# pre-existing lines or mischaracterize a PR. It always posts its findings
|
||||
# as a PR comment, but a non-zero exit must NOT show the PR as a blocking
|
||||
# red ❌. continue-on-error keeps the check green while preserving the comment.
|
||||
continue-on-error: true
|
||||
env:
|
||||
GEMINI_API_KEY_1: ${{ secrets.GEMINI_API_KEY_1 }}
|
||||
GEMINI_API_KEY_2: ${{ secrets.GEMINI_API_KEY_2 }}
|
||||
@@ -49,7 +59,10 @@ jobs:
|
||||
run: |
|
||||
git config --global user.name "nubenetes-bot"
|
||||
git config --global user.email "bot@nubenetes.com"
|
||||
git add docs/ v2-docs/ README.md data/inventory.yaml src/memory/
|
||||
# NOTE: v2-docs/ is deliberately excluded. It is generated by
|
||||
# src/v2_optimizer.py (single source of truth); re-formatting it here
|
||||
# caused a perpetual cosmetic develop<->master drift (see pr_guardian.py).
|
||||
git add docs/ README.md data/inventory.yaml data/inventory.sql src/memory/
|
||||
if ! git diff --cached --quiet; then
|
||||
git commit -m "style(cleaner): auto-correcting formatting & URL normalization"
|
||||
git push origin HEAD:${{ github.event.pull_request.head.ref }} || echo "⚠️ Push failed (likely fork permission limit)."
|
||||
|
||||
@@ -10,6 +10,11 @@ on:
|
||||
paths:
|
||||
- '**/*.md'
|
||||
|
||||
# Supersede in-flight lint runs for the same PR/branch on new commits.
|
||||
concurrency:
|
||||
group: md-linter-${{ github.event.pull_request.number || github.ref }}
|
||||
cancel-in-progress: true
|
||||
|
||||
jobs:
|
||||
lint:
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
@@ -0,0 +1,78 @@
|
||||
name: 09. Weekly Intelligence Digest
|
||||
|
||||
on:
|
||||
schedule:
|
||||
# Every Monday at 06:00 UTC (08:00 Madrid time)
|
||||
- cron: '0 6 * * 1'
|
||||
workflow_dispatch:
|
||||
|
||||
permissions:
|
||||
contents: write
|
||||
pull-requests: write
|
||||
|
||||
concurrency:
|
||||
group: develop-git-write-lock
|
||||
cancel-in-progress: false
|
||||
|
||||
jobs:
|
||||
weekly-digest:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Repository Synchronization
|
||||
uses: actions/checkout@v6
|
||||
with:
|
||||
ref: develop
|
||||
fetch-depth: 0
|
||||
|
||||
- name: Python 3.11 Environment Provisioning
|
||||
uses: actions/setup-python@v6
|
||||
with:
|
||||
python-version: '3.11'
|
||||
cache: 'pip'
|
||||
|
||||
- name: Install Dependencies
|
||||
run: pip install -r requirements.txt
|
||||
|
||||
- name: Generate News Digest (Incremental)
|
||||
env:
|
||||
PYTHONPATH: ${{ github.workspace }}
|
||||
GEMINI_API_KEY_1: ${{ secrets.GEMINI_API_KEY_1 }}
|
||||
GEMINI_API_KEY_2: ${{ secrets.GEMINI_API_KEY_2 }}
|
||||
run: |
|
||||
# Incremental engine: reuses stored results for unchanged categories.
|
||||
# On Monday, only categories with new entries since the last run
|
||||
# (or older than MAX_STALENESS_DAYS=30) trigger Gemini API calls.
|
||||
python -u -m src.news_digest
|
||||
|
||||
- name: Generate RSS Feed
|
||||
env:
|
||||
PYTHONPATH: ${{ github.workspace }}
|
||||
run: |
|
||||
python -u -m src.rss_generator || echo "RSS generation skipped"
|
||||
|
||||
- name: Render V2 Portal (Digest Pages Only)
|
||||
env:
|
||||
PYTHONPATH: ${{ github.workspace }}
|
||||
PYTHONUNBUFFERED: "1"
|
||||
run: |
|
||||
python -u -m src.v2_optimizer --render-only
|
||||
|
||||
- name: Commit and Push Weekly Digest
|
||||
run: |
|
||||
git config --global user.name "Nubenetes Bot"
|
||||
git config --global user.email "bot@nubenetes.com"
|
||||
git add data/news_digest.json v2-docs/tech-digest.md v2-docs/industry-digest.md v2-docs/feed.xml || true
|
||||
if git diff --staged --quiet; then
|
||||
echo "No digest changes to commit."
|
||||
else
|
||||
git commit -m "feat: weekly intelligence digest update [skip ci]"
|
||||
for i in {1..3}; do
|
||||
git pull origin develop --rebase && git push origin develop && break || sleep 10
|
||||
done
|
||||
fi
|
||||
|
||||
- name: Trigger V2 Publisher
|
||||
uses: peter-evans/repository-dispatch@v3
|
||||
with:
|
||||
token: ${{ secrets.GITHUB_TOKEN }}
|
||||
event-type: weekly-digest-ready
|
||||
@@ -351,6 +351,7 @@ MigrationBackup/
|
||||
# Automatización Nubenetes
|
||||
src/__pycache__/
|
||||
*.json
|
||||
!data/news_digest.json
|
||||
.env
|
||||
nubenetes_agent_env/
|
||||
.venv/
|
||||
|
||||
@@ -5,6 +5,379 @@ All notable changes to this project will be documented in this file.
|
||||
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
|
||||
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
||||
|
||||
## [[2.9.48]](https://github.com/nubenetes/awesome-kubernetes/releases/tag/v2.9.48) - 2026-06-23
|
||||
|
||||
### Fixed
|
||||
- **Trending Now cards: impact badge no longer overlaps the title**: On the V2 home page "🔥 Trending Now — Cloud Native Intelligence" lane, the `CRITICAL`/`HIGH` impact badge (and the optional `🆕 NEW` pill) was `position: absolute` in the top-right corner, so a long celeste category/title flowing in normal document position could slide right underneath it and become unreadable. The badge is now an in-flow, right-aligned pill (`width: fit-content; margin-left: auto`) on its own line at the top of the card, with the `NEW` pill laid out as a flex sibling (`gap`-spaced) — so the red impact text, the celeste title, and the green `NEW` pill can never overlap, on any card width or title length. Cards with short titles stay just as tight as before. `docs/static/v2_elite.css` only; cache-bust auto-versions from the release tag.
|
||||
|
||||
## [[2.9.38]](https://github.com/nubenetes/awesome-kubernetes/releases/tag/v2.9.38) - 2026-06-20
|
||||
|
||||
### Added
|
||||
- **OpenShift submenu + grouped Kubernetes distros**: The Kubernetes menu's OpenShift entry only linked to the generic overview, hiding the substantial OpenShift 4 page (`ocp4`, 29 links) amid the ocp3-deprecated/openshift/ocp4 confusion. OpenShift is now a nested submenu (OpenShift ▸ → OpenShift 4 (current) · Overview · OpenShift 3 (legacy)), reusing the AWS nested-submenu mechanism. The Kubernetes distributions/platforms are grouped at the end of the menu — Managed K8s · OpenShift ▸ · Rancher · Distros & Alternatives (`kubernetes-alternatives` moved here and relabeled). The 2-column Kubernetes menu was also switched from CSS multicol to a deterministic column-major grid (11 rows × 2 cols, `overflow:visible`), removing a faint sub-pixel scrollbar. Verified in Chrome 148 (Playwright + screenshot): clean 2-column card with no scrollbar at viewport heights 768–1080; the OpenShift submenu opens to the side and keeps the parent open. Cache-bust `?v=2.9.38`; V2-only.
|
||||
|
||||
## [[2.9.37]](https://github.com/nubenetes/awesome-kubernetes/releases/tag/v2.9.37) - 2026-06-20
|
||||
|
||||
### Fixed
|
||||
- **Kubernetes quick-nav menu reliability**: The Kubernetes dropdown (22 items) was the only menu tall enough to need a scrollbar on an anchor-positioned popover, which made it open/behave unreliably compared to the others. It now uses a 2-column layout (`column-count: 2`), halving its height (~731px → ~353px) so it shows in full without a scrollbar at any realistic viewport; multicol is column-major, so reading order is preserved. Also removed `flip-block` from the menu position-try fallbacks (kept `flip-inline`): the quick-nav is a sticky top bar, so a tall menu flipping above would shoot off the top of the screen — menus now always open downward. Verified in Chrome 148 (Playwright) at viewport heights 700–1080. Cache-bust `?v=2.9.37`; V2-only.
|
||||
|
||||
## [[2.9.36]](https://github.com/nubenetes/awesome-kubernetes/releases/tag/v2.9.36) - 2026-06-20
|
||||
|
||||
### Changed
|
||||
- **Quick-nav fully regrouped into 11 thematic menus + nested AWS submenu**: Reorganized the quick-nav into one direct pill (Topic Map) plus 11 category dropdowns that group related topics so every destination has a sensible home: Digest · Kubernetes (Overview · Docker · Tools · Helm · kubectl · all kubernetes-* · Managed · OpenShift · Rancher) · Delivery (GitOps · CI/CD · DevOps · Argo · Flux · Tekton · Jenkins · …) · IaC (Terraform · IaC · Ansible · Pulumi · Crossplane · Kustomize) · Cloud · Network · Security · Observability & SRE · AI & Data · Dev & Platform · More. Docker now lives inside Kubernetes; GitOps + CI/CD + DevOps share Delivery; Terraform + IaC share IaC. **AWS is a nested submenu inside Cloud** (Cloud → AWS ▸ → 8 AWS pages), built with nested Popover API + explicit `anchor()` side-positioning (position-area's horizontal axis isn't honored when the anchor is inside another popover). Pages may appear in more than one menu where it aids discovery; menus get `max-height:82vh` + scroll for the tall Kubernetes menu. Verified in Chrome 148 (Playwright). Cache-bust `?v=2.9.36`; V2-only.
|
||||
- **AWS + Kubernetes provider hubs now live**: This release also publishes the regenerated v2-docs from v2.9.34/v2.9.35 — the AWS landing page (3 → ~40 links + "Deep-Dive Topic Pages" hub, trivial sub-pages consolidated) and the Kubernetes sub-page hub.
|
||||
|
||||
## [[2.9.35]](https://github.com/nubenetes/awesome-kubernetes/releases/tag/v2.9.35) - 2026-06-20
|
||||
|
||||
### Added
|
||||
- **Kubernetes provider hub**: A fragmentation audit found only two prefix clusters — `aws` (fixed in v2.9.34) and `kubernetes`. Unlike AWS, Kubernetes is well-classified (rich parent at 157 links + substantial distinct children: tools 144, networking 64, security 52, monitoring 24, …), so nothing is merged. This adds a "Deep-Dive Topic Pages" hub to `kubernetes.md` indexing its 14 substantial sub-pages (Tools · Networking · Security · Monitoring · Storage · Autoscaling · Operators · Alternatives · Big Data · Tutorials · Backup & Migrations · Client Libraries · Local Dev · On-Premise) — purely additive navigation, no merging or pruning. Other small pages (pulumi, kustomize, registries, …) are legitimate distinct topics and were intentionally left alone. Generator-only (`src/v2_optimizer.py`); republished on the next curation run.
|
||||
|
||||
## [[2.9.34]](https://github.com/nubenetes/awesome-kubernetes/releases/tag/v2.9.34) - 2026-06-20
|
||||
|
||||
### Changed
|
||||
- **AWS page de-fragmentation + provider hub**: The AWS landing page rendered with only ~3 links because AWS content was split across ~20 granular pages (Azure/GCP use a single rich page each), many with just 1-5 links. Two generator changes in `src/v2_optimizer.py` fix this: (A) `aws.md` now renders a "Deep-Dive Topic Pages" hub linking to the substantial sub-pages that remain (Serverless · Storage · Networking · Security · IaC · Backup · New Features) via a new `subpage_hubs` map; (B) the near-empty / junk-drawer AWS sub-pages (≤7 links + "miscellaneous": aws-pricing, aws-training, aws-data, aws-messaging, aws-tools-scripts, aws-monitoring, aws-architecture, aws-containers, aws-devops, aws-databases, aws-miscellaneous) merge into `aws.md` via the existing `merge_map`, with their slugs removed from `dimensions` so the pipeline prunes the orphans and auto-syncs the nav. Verified with `--render-only`: aws.md goes from 3 to 44 links plus the 7-child hub. V1 (`docs/`) is untouched by design (exhaustive archive + merge source). Generator-only; the AWS pages are republished on the next curation run.
|
||||
|
||||
## [[2.9.33]](https://github.com/nubenetes/awesome-kubernetes/releases/tag/v2.9.33) - 2026-06-20
|
||||
|
||||
### Added
|
||||
- **Quick-nav menu expansion — 38 destinations**: Data-driven expansion of the hybrid quick-nav (ranked by per-page link count + relevance). New 📊 Digest menu pairs both editions (Tech & Cloud Digest + Industry & Geo Digest); new 🧰 K8s menu surfaces the Kubernetes ecosystem (Kubernetes Tools · Helm · Managed K8s · OpenShift · Tutorials). Existing menus grew: ☁️ Cloud += Serverless · FinOps; 🌐 Network += Service Mesh (Istio emoji → ⛵); ⚙️ Ops += IaC · Developer Portals; ⋯ More += Technical Tags · Demos. 38 destinations total across 6 direct pills + 7 Popover menus; chip font trimmed to 0.62rem with tighter gap/padding so all 13 bar chips fit one row down to ~1280px. Verified in Chrome 148 (Playwright): every menu opens below its button, flips near the right edge, and closes on Esc. Cache-bust `?v=2.9.33`; V2-only.
|
||||
|
||||
## [[2.9.32]](https://github.com/nubenetes/awesome-kubernetes/releases/tag/v2.9.32) - 2026-06-20
|
||||
|
||||
### Fixed
|
||||
- **Quick-nav menus open below their button + fit one row**: Fixed two issues in the v2.9.31 hybrid quick-nav (verified in Chrome 148 via Playwright). (1) The Popover category menus did not visibly open on click — they used `position-area: bottom span-inline-end`, which mixes a physical keyword (`bottom`) with a logical one (`span-inline-end`); that is invalid CSS and silently computed to `none`, leaving the menu in its static position on top of the button. Fixed with a valid all-physical `position-area: bottom span-right` plus explicit `anchor-name` / `position-anchor` pairs per button↔menu, so each menu reliably drops below its trigger and auto-flips near the right edge. (2) The bar wrapped to a second row on common displays — reduced the chip font ~1pt (`0.7rem → 0.64rem`) and trimmed the column-gap/padding so all 7 pills + 5 menus fit a single row down to 1280px viewports. Cache-bust `?v=2.9.32`; V2-only, CSS-only.
|
||||
|
||||
## [[2.9.31]](https://github.com/nubenetes/awesome-kubernetes/releases/tag/v2.9.31) - 2026-06-20
|
||||
|
||||
### Changed
|
||||
- **Hybrid quick-nav — direct pills + Popover category menus**: Collapsed the 25-destination quick-nav from 3 wrapped rows to a single slim row that stays one row regardless of how many destinations are added. The most-used flagships remain direct one-click pills (Topic Map · Digest · Kubernetes · Docker · GitOps · Terraform · AI & MCP); the long-tail clusters fold into five category menus — ☁️ Cloud, 🌐 Network, 🔐 Security, ⚙️ Ops, ⋯ More — built with the native HTML Popover API + CSS Anchor Positioning (Baseline 2026), zero JS. Menus drop below their button via `position-area` with flip fallbacks, animate in with `@starting-style`, rotate their caret via `:has()`, and inherit the Popover API's built-in Esc / click-outside dismissal and focus management (identical on touch and desktop); `prefers-reduced-motion` honored. All 25 destinations preserved. Touches `docs/overrides/main.html` + `docs/static/v2_elite.css` (cache-bust `?v=2.9.31`); V2-only, no page regeneration.
|
||||
|
||||
## [[2.9.30]](https://github.com/nubenetes/awesome-kubernetes/releases/tag/v2.9.30) - 2026-06-20
|
||||
|
||||
### Changed
|
||||
- **Quick-nav — networking cluster + DevSecOps**: Grew the quick-nav bar to 25 destinations. Added a new networking cluster after the cloud providers (🌐 Networking · 🕸️ Istio · 🔗 K8s Net) and DevSecOps alongside Security (🔐 Security · 🛡️ DevSecOps), keeping short labels and category grouping. Template-only change to `docs/overrides/main.html` reusing the existing `.nb-quicknav` pill styling — no CSS change, no page regeneration. V2-only.
|
||||
|
||||
## [[2.9.29]](https://github.com/nubenetes/awesome-kubernetes/releases/tag/v2.9.29) - 2026-06-20
|
||||
|
||||
### Changed
|
||||
- **Quick-nav redesign — centered category-grouped pill chips**: Grew the quick-nav bar to 21 destinations and restyled it as a modern, centered chip bar. Added CI/CD, Ansible, and the three hyperscalers (AWS, Azure, GCP), and reordered every tab into related category clusters with short labels: discovery (Topic Map · Digest · Videos) → platform (Kubernetes · Docker) → delivery (GitOps · CI/CD) → IaC (Terraform · Ansible) → cloud (AWS · Azure · GCP) → security → ops (Observability · SRE · DevOps) → data (Messaging) → AI/ML (AI & MCP · MLOps) → Methodology → V1 Archive (muted). Chip background/border/glow are derived from the theme accent via `color-mix(in srgb, …)` (Chrome 111+) so the bar restyles automatically with the palette; rows are centered (`justify-content: center`) for a balanced multi-row layout, with hover lift, `:focus-visible` outline, `prefers-reduced-motion` support, and a mobile single-row horizontal scroll. Touches `docs/overrides/main.html` + `docs/static/v2_elite.css` (cache-bust `?v=2.9.29`); V2-only, no page regeneration.
|
||||
|
||||
## [[2.9.28]](https://github.com/nubenetes/awesome-kubernetes/releases/tag/v2.9.28) - 2026-06-20
|
||||
|
||||
### Changed
|
||||
- **Expanded quick-nav bar**: Grew the slim quick-nav bar from 6 to 16 curated one-click destinations, surfacing the principal topics across all of Nubenetes from any page. Added the cloud-native pillars (Kubernetes · Docker · GitOps · Terraform · K8s Security · Observability), the ops disciplines (SRE · DevOps), data/messaging (Message Queue), and MLOps alongside the existing AI & MCP hub. Template-only change to `docs/overrides/main.html` (no CSS change, no page regeneration); reuses the existing `.nb-quicknav__link` styling with `flex-wrap` handling density on narrow viewports. Still under the 18-tab overflow line the bar was designed to avoid. V2-only.
|
||||
|
||||
## [[2.9.27]](https://github.com/nubenetes/awesome-kubernetes/releases/tag/v2.9.27) - 2026-06-20
|
||||
|
||||
### Added
|
||||
- **Slim quick-nav bar**: A thin horizontal bar below the header on every V2 page with six curated one-click destinations (Topic Map · Intelligence Digest · Video Hub · AI & MCP · Methodology · V1 Archive). These cross-cutting destinations previously only existed as badge cards on the home; the bar makes them persistently reachable from any depth. Implemented by overriding Material's `tabs` block (empty since `navigation.tabs` is disabled) plus `.nb-quicknav` CSS — so it adds persistent shortcuts WITHOUT reintroducing the 18-tab overflow and WITHOUT collapsing the full collapsible left navigation tree. Template/CSS-only (no page regeneration); V2-only.
|
||||
|
||||
## [[2.9.26]](https://github.com/nubenetes/awesome-kubernetes/releases/tag/v2.9.26) - 2026-06-20
|
||||
|
||||
### Changed
|
||||
- **Collapsible, nested left navigation**: After moving the sections to the left sidebar in 2.9.25, they rendered as a *flat* list of 18 labels with no expand/indent — `navigation.sections` made them non-collapsible group labels and `navigation.prune` stripped the inactive children. Disabled both so the sidebar is now a proper collapsible, nested, indented tree (14 toggles / chevrons, collapsed by default, click to expand). No size penalty (88,213 vs 88,516 bytes per page).
|
||||
|
||||
### Added
|
||||
- **Home section headings**: The V2 home had a single H2, leaving its right-hand "On this page" TOC empty. Added `## Explore the Ecosystem` (badge cards) and `## Trending Now` (Intelligence Digest) alongside the existing `## The Cloud Native Universe We Track`, so the home's right TOC now lists three real sections. Net effect: both side columns are now useful on every page — left = full collapsible directory, right = per-page section map.
|
||||
|
||||
## [[2.9.25]](https://github.com/nubenetes/awesome-kubernetes/releases/tag/v2.9.25) - 2026-06-20
|
||||
|
||||
### Changed
|
||||
- **V2 navigation: tabs → left sidebar**: The 18 top-level sections were rendered as a horizontal tab bar (`navigation.tabs`), whose labels total ~3300px and overflowed a typical ~1400px laptop viewport — forcing horizontal scroll to reach the right-side dimensions and leaving the left sidebar nearly empty on top-level pages like the home. Disabled `navigation.tabs` (+ `.sticky`) so the sections render in the standard vertical left sidebar: it handles all 18 collapsed sections via normal scroll, stays populated on every page (the home's rendered nav goes from 23 links to the full 178-link tree), and nothing clips. Theme-only change preserved across publishes (the optimizer's nav-sync only rewrites the `nav:` block).
|
||||
|
||||
## [[2.9.24]](https://github.com/nubenetes/awesome-kubernetes/releases/tag/v2.9.24) - 2026-06-20
|
||||
|
||||
### Added
|
||||
- **Per-page JSON-LD structured data**: Each V2 content page now emits a second JSON-LD block — a schema.org `CollectionPage` tied to the existing `WebSite`/`Organization` `@graph` — carrying the page name, description, URL, and `datePublished` / `dateModified` fed by the `git-revision-date-localized` plugin's raw ISO dates (the creation/last-update dates from 2.9.23). This enables article/collection rich snippets in search results with real freshness dates. Template-only change (`docs/overrides/main.html`), applied at build time; the homepage is skipped (it is already the `WebSite` entity), and JSON is built with `| tojson` for safe escaping.
|
||||
|
||||
## [[2.9.23]](https://github.com/nubenetes/awesome-kubernetes/releases/tag/v2.9.23) - 2026-06-20
|
||||
|
||||
### Changed
|
||||
- **Richer per-page SEO meta descriptions**: The unique-but-templated descriptions from 2.9.22 now lead with each page's **top-ranked resource names** (long-tail keywords) — e.g. *"Top Kubernetes resources for 2026, AI-ranked: Helm, kube-prometheus and more — curated Cloud Native tools, guides and references."* URL/path-like and emoji-laden titles are filtered out, pages whose top links are all URL-like fall back to the clean template, and the text is capped at ~160 chars on a word boundary. (There is no per-page AI intro to mine, so the page's own top resources are the cleanest source.)
|
||||
|
||||
### Added
|
||||
- **Per-page creation dates**: Enabled `enable_creation_date` on the `git-revision-date-localized` plugin, so every V2 page footer now shows both **Created** and **Last update** — an additional age/freshness signal alongside the last-modified date introduced in 2.9.18.
|
||||
|
||||
## [[2.9.22]](https://github.com/nubenetes/awesome-kubernetes/releases/tag/v2.9.22) - 2026-06-20
|
||||
|
||||
### Added
|
||||
- **robots.txt**: Added `v2-docs/robots.txt` (deployed at the site root) that allows full crawl and references both the V2 (root) and V1 (`/v1/`) sitemaps — previously the site shipped a `sitemap.xml` with no `robots.txt` pointing at it.
|
||||
|
||||
### Changed
|
||||
- **Unique per-page SEO meta descriptions**: Every V2 page previously fell back to the identical global `site_description`, so ~140 pages shared one `<meta name="description">` (a duplicate-content SEO penalty). `v2_optimizer.py` now emits a unique `description:` front-matter per page — derived from the page title and its strategic dimension — which Material renders as `<meta name="description">` and `og:description`. The Topic Map and Methodology pages get tailored descriptions. The 12 redirect-stub pages were intentionally left untouched (they already 0s meta-refresh redirect with `canonical` pointing at the target, which passes authority better than `noindex`).
|
||||
|
||||
## [[2.9.21]](https://github.com/nubenetes/awesome-kubernetes/releases/tag/v2.9.21) - 2026-06-20
|
||||
|
||||
### Added
|
||||
- **README database & lifecycle diagrams**: Added two new collapsible Mermaid diagrams — a **Database Architecture** diagram (§6.1.3) detailing the YAML + SQLite coexistence engine (`inventory.sql` Git source-of-truth → in-memory SQLite → `inventory.yaml` mirror, plus the per-resource schema), and a **full Data Lifecycle** diagram (§6.3) tracing a resource from discovery and ingestion through cached maintenance/enrichment to render and deploy, with background garbage collection.
|
||||
|
||||
### Changed
|
||||
- **Grouped, compact Technical Tags Index TOC**: The `tags.md` table of contents was a flat 80-entry numbered list that buried the 8 maturity tags under a long tail of one-resource "X Content" language tags. It is now grouped into *Maturity and Quality* (numbered) plus *Technical Domains* / *Language and Format* (compact, count-sorted inline rows). Generator (`v2_optimizer.py`) now emits unique explicit heading anchors (`{#slug}`) shared by the TOC and section headers — fixing collisions where `C` / `C#` / `C++` all resolved to `#c-content` — corrects the `1 resource` grammar, and filters non-language values (`En`, `Not Applicable`, `Multi-Language`, `Polyglot`, …) that previously created meaningless tag buckets.
|
||||
- **README mermaid legibility & accuracy**: Fixed text overflow in four diagrams (Division of Labor, Agentic Data Flow, Debate Protocol, Deployment Lifecycle) by wrapping long node labels, removed a duplicate edge, and refreshed the V2 feature documentation with the v2.9.16–v2.9.20 work (Topic Map & Methodology pages, per-page last-updated dates, JSON-LD, branded 404, deterministic generated artifacts).
|
||||
|
||||
## [[2.9.20]](https://github.com/nubenetes/awesome-kubernetes/releases/tag/v2.9.20) - 2026-06-20
|
||||
|
||||
### Fixed
|
||||
- **RSS feed drift fully eliminated**: The 2.9.19 fix derived the feed's `<lastBuildDate>` from `_meta.last_updated`, but that analysis timestamp is bumped on every publish even when the ranked content is unchanged, so `v2-docs/feed.xml` still drifted between `develop` and `master`. `src/rss_generator.py` now derives `lastBuildDate` from the **freshest item's content date** (the items only change when the ranking actually changes), with `_meta.last_updated`/a constant as fallbacks. Verified deterministic across reruns, and the `develop` and `master` digests both yield `2026-06-18` — so `feed.xml` is now byte-identical across branches and no longer spawns no-op promotion diffs.
|
||||
|
||||
## [[2.9.19]](https://github.com/nubenetes/awesome-kubernetes/releases/tag/v2.9.19) - 2026-06-20
|
||||
|
||||
### Fixed
|
||||
- **Deterministic RSS `lastBuildDate` (residual develop↔master drift)**: `src/rss_generator.py` set the feed's `<lastBuildDate>` to `datetime.utcnow()`, so every republish rewrote it even when the digest was unchanged — leaving a perpetual 1-line diff in `v2-docs/feed.xml` (the last residual after the PR Guardian drift fix in 2.9.18). It now derives the date from the digest's `_meta.last_updated` (the actual analysis timestamp), falling back to the most recent item date then a fixed constant, making the feed a pure function of its input. Verified byte-identical output across repeated runs; the feed now changes only when the digest content actually changes.
|
||||
- **In-page filter no longer injected on Topic Map & Methodology**: The resource search / maturity-tag widget (`static/v2_filter.js`) auto-injects wherever a page has `<ul><li>` items. Topic Map lists category links (with counts) and Methodology lists legend rows — neither carries `.md-tag` maturity tags, so the pills always filtered to zero and the "Showing X of Y resources" counter mis-counted categories/rows as resources. Added both pages to the widget's existing `<h1>`-based skip-list (alongside the home, Video Hub, Tags and Digest pages). Cache-bust `v2_filter.js?v=2.9.19`.
|
||||
|
||||
## [[2.9.18]](https://github.com/nubenetes/awesome-kubernetes/releases/tag/v2.9.18) - 2026-06-20
|
||||
|
||||
### Added
|
||||
- **Per-page "Last update" dates (SEO freshness)**: Enabled the `git-revision-date-localized` MkDocs plugin on the V2 portal, surfacing a real last-modified date on every page. Added the dependency to `requirements.txt`, configured it in `v2-mkdocs.yml` (`type: date`, `fallback_to_build_date: true` so a missing git history never fails the build), and set `fetch-depth: 0` on the `06.deploy_final.yml` checkout so the plugin reads full history instead of collapsing every page to the build date.
|
||||
- **JSON-LD structured data**: Injected schema.org `WebSite` (with a sitelinks `SearchAction`) + publishing `Organization` markup via an `extrahead` block in `docs/overrides/main.html`, making the canonical `nubenetes.com` root eligible for richer search results and knowledge-panel association. Validated: build exits 0 and the emitted JSON-LD parses to `[WebSite, Organization]`.
|
||||
|
||||
### Fixed
|
||||
- **`develop ↔ master` cosmetic drift loop (recurring no-op release PRs)**: The PR Guardian (`07.1.pr_guardian.yml` → `src/pr_guardian.py`) ran its auto-formatter ("&"→"and" in headings, URL trailing-slash/tracking-param stripping) on every changed `.md` — including the **generated** `v2-docs/` tree — and committed the result back to the PR branch. Because feature PRs land on `develop` (Guardian runs) but release branches merge to `master` via plain `git merge` (Guardian does not run), `develop` accumulated the normalized form while `master` kept the generator's raw form, producing a perpetual cosmetic diff that spawned recurring no-op "🚀 Release: Agentic V2 Portal Update" PRs (e.g. #399). Since `v2_optimizer.py` is the single source of truth for `v2-docs/` formatting, the Guardian now skips that tree in its auto-format loop and drops it from the auto-commit `git add`; hand-authored `docs/` and `README`/`inventory` are unaffected.
|
||||
|
||||
## [[2.9.17]](https://github.com/nubenetes/awesome-kubernetes/releases/tag/v2.9.17) - 2026-06-20
|
||||
|
||||
### Fixed
|
||||
- **Topic Map heading increment (MD001 lint failure)**: The new `topic-map.md` page emitted its per-dimension headings as `###` (h3) directly under the page `#` (h1) title, skipping h2. This tripped `markdownlint` **MD001/heading-increment**, turning the `07.2. Markdown Linter` workflow red on both `develop` and `master` right after the v2.9.16 release. Fixed the generator (`v2_optimizer.py`) and the committed page to emit dimensions as `##` (h2), and updated the CSS selector to `.topic-map-dim h2`. As a bonus, the h2 dimensions now populate the right-hand "On this page" TOC with a clean per-dimension index. Verified with the exact CI `markdownlint` config (0 errors); cache-bust bumped to `?v=2.9.17`.
|
||||
|
||||
## [[2.9.16]](https://github.com/nubenetes/awesome-kubernetes/releases/tag/v2.9.16) - 2026-06-20
|
||||
|
||||
### Added
|
||||
- **V2 Topic Map page**: A new `topic-map.md` (generated by `v2_optimizer.py`) presents the complete category directory grouped by strategic dimension in a **responsive multi-column CSS grid** (3 → 2 → 1 columns), with a **per-category resource count** badge derived from a recursive walk of each category's link tree. This replaces the ~130-link "Strategic Dimensions" dump that previously bloated the home page, and is reachable from a new hero badge card and the top-level nav.
|
||||
- **V2 Methodology page**: The Maturity Taxonomy and Technical Impact (star score) legend tables moved out of the home into a dedicated `methodology.md`, leaving the landing page focused while keeping the reference one click away.
|
||||
- **Branded 404 page** (`docs/overrides/404.html`, shared V1/V2): replaces the theme's bare "404 - Not found" with a helpful page offering Home / Topic Map / V1 Archive — a safety net for the deep-link stability the portal depends on.
|
||||
|
||||
### Changed
|
||||
- **Home landing page restructured for altitude**: Moved the fresh, dynamic **Trending Now / Intelligence Digest** block *above* the signature YouTube channel mosaic (previously the static mosaic pushed the live content below the fold). The mosaic is preserved as a brand showcase and now closes the page under a new **"The Cloud Native Universe We Track"** heading, with a slim reference footer linking the Topic Map, Methodology and Video Hub.
|
||||
- **YouTube mosaic legibility & performance**: Surfaced the seven per-group category labels that were previously hidden in a `title=` tooltip (visible accent-bordered labels), and added `loading="lazy"` to the ~150 channel logos for a meaningful LCP/initial-load improvement.
|
||||
- **About page videos hardened**: The two embedded videos now use `youtube-nocookie.com` (no tracking cookies until play — consistent with the active `privacy` plugin), `loading="lazy"`, and a responsive `aspect-ratio` wrapper that no longer overflows on mobile.
|
||||
- **Collapsed left navigation**: Disabled `navigation.expand` in `v2-mkdocs.yml`; with ~169 nav entries it forced every section open (heavy DOM, overwhelming). The new Topic Map page now serves as the full scannable directory.
|
||||
- **CSS hygiene**: Hoisted repeated inline styles (hero badge row) into `v2_elite.css` classes and bumped the cache-bust to `?v=2.9.16`.
|
||||
|
||||
## [[2.9.15]](https://github.com/nubenetes/awesome-kubernetes/releases/tag/v2.9.15) - 2026-06-19
|
||||
|
||||
### Changed
|
||||
- **Navigable Intelligence Digest TOC**: The Tech & Cloud and Industry & Geo digest pages now show their sections in the right-hand "On this page" TOC. They were rendered period-first (three time-window tabs, each nesting every category as **bold text**), so the pages had zero real headings and an empty TOC. Inverted the layout in `_generate_digest_pages()` to **category-first**: each category is a real `##` heading (Kubernetes & Orchestration, Containers & Runtime, … / Americas, Europe, Spain, Asia-Pacific), with the three time-windows (3 / 6 / 12 months) as content tabs *inside* each category. The TOC now lists all 22 tech categories and 4 geo regions exactly once, headings sit at column 0 (no more MD023 workaround), and the tabbed UX is preserved.
|
||||
|
||||
## [[2.9.14]](https://github.com/nubenetes/awesome-kubernetes/releases/tag/v2.9.14) - 2026-06-19
|
||||
|
||||
### Changed
|
||||
- **Deterministic V2 Publisher Push (04.1)**: Replaced the fragile rebase + `git checkout --ours/--theirs README.md` self-healing in `04.1.agentic_v2_publish.yml` — which could hang on a non-README conflict and silently discard the bot's README metrics — with the same deterministic model now used by `05.1`. The render is authoritative for its generated surface, so each attempt hard-resets to the freshest `origin/develop` tip, overlays the generated outputs verbatim (`docs/`, `v2-docs/`, `data/inventory.yaml`, `data/inventory.sql`, `data/news_digest.json` — source configs like `link_rules.yaml`/`special_assets.yaml` are deliberately left untouched), regenerates `README.md` on top, then commits and pushes with a 5-attempt retry. This never hangs on a conflict and never loses data. Also pinned `PYTHONPATH` on the step so the in-loop `readme_updater`/`safety_readme` calls always resolve `src`.
|
||||
|
||||
## [[2.9.13]](https://github.com/nubenetes/awesome-kubernetes/releases/tag/v2.9.13) - 2026-06-19
|
||||
|
||||
### Fixed
|
||||
- **README Sync Dirty-Tree / Race Failure (root cause)**: `05.1.readme_sync.yml` modified `README.md` in earlier steps and then ran `git pull`, which aborted with *"Your local changes to README.md would be overwritten by merge"* — guaranteed to fail whenever a concurrent bot commit (e.g. the V2 Publisher's `[skip ci]` sync) advanced `develop` first. Rewrote the commit step as a `fetch → reset --hard origin/develop → regenerate → commit → push` retry loop. Since `README.md` is a *pure function* of the inventory, hard-resetting to the freshest remote tip is always safe and removes the merge-conflict and `--ours/--theirs` confusion classes entirely. A push is now only rejected if the remote advances mid-attempt, in which case it retries from the new tip.
|
||||
|
||||
### Changed
|
||||
- **Inventory Push Retries (03.1 / 03.2 / 03.3)**: The metadata, AI-analysis and Video-Hub workflows did a single `git pull --rebase && git push` with no retry, so any rejection from a concurrent push failed the run. Wrapped each in a 5-attempt rebase+push loop (matching the proven `09.weekly_digest.yml` idiom).
|
||||
- **PR Guardian is now advisory (07.1)**: The AI presubmit is a heuristic that can misattribute pre-existing lines or mischaracterize a PR (it flagged an untouched `about.md` line on PR #392). It still posts its findings as a PR comment, but `continue-on-error: true` stops a non-zero exit from showing the PR as a blocking red ❌. Added PR-scoped `concurrency` so superseded runs are cancelled (saving CI minutes and Gemini calls).
|
||||
- **Markdown Linter concurrency (07.2)**: Added PR/branch-scoped `concurrency` with `cancel-in-progress` so new commits supersede in-flight lint runs.
|
||||
|
||||
## [[2.9.12]](https://github.com/nubenetes/awesome-kubernetes/releases/tag/v2.9.12) - 2026-06-19
|
||||
|
||||
### Fixed
|
||||
- **V2 In-Page Search/Tag Filter Disappeared**: The per-page resource search box with maturity tag-pills (`static/v2_filter.js`) stopped appearing on every page after `navigation.instant` was enabled in the `2026-06-19` MkDocs UX overhaul. The widget hooked only `DOMContentLoaded`, which under Material's instant (SPA) navigation fires solely on the first load — subsequent in-nav page swaps never re-injected it. Reworked the script to initialize through Material's `document$` observable (emits on every instant navigation, with a `DOMContentLoaded` fallback), guard against double-injection, bind the clickable-tag delegation once on `document`, and show a "no results" state. Cache-bust bumped to `?v=2.9.12`.
|
||||
|
||||
### Changed
|
||||
- **Removed Redundant In-Page Table of Contents**: Dropped the Markdown `## Table of Contents` block from all 156 V2 content pages and from the renderer (`v2_optimizer.py`). It duplicated the theme's heading index and, on large pages, forced hundreds of links of scroll before any content (e.g. `kubernetes-tools` 297 lines, `kubernetes` 295, `demos` 227). Replaced by the MkDocs Material native sticky **"On this page"** TOC: removed `toc.integrate` and added `toc.follow` in `v2-mkdocs.yml` so headings render in the right sidebar and track scroll position. The `tags.md` index page keeps its TOC (it *is* a navigation index).
|
||||
|
||||
## [[2.9.10]](https://github.com/nubenetes/awesome-kubernetes/releases/tag/v2.9.10) - 2026-06-19
|
||||
|
||||
### Fixed
|
||||
- **README Sync Push Loop**: Rewrote the `05.1.readme_sync.yml` retry logic to use a push-first / merge-on-rejection loop instead of a pull-first / rebase loop. The old rebase loop never attempted a push after self-healing — it cycled back to `git pull --rebase`, hitting a fresh conflict on every iteration (×5) because a concurrent V2 sync workflow kept advancing `develop`. Additionally, `--ours` during a rebase refers to the *upstream* side, so the bot's README metrics were silently discarded each round. The fix: pull latest before committing (shrinks conflict window), then retry with `git merge -X ours` (correct semantics) after each rejected push.
|
||||
- **Digest Table Broken by Pipe in Title**: Titles containing ` | ` (e.g. "Neo, Now in the Terminal | Pulumi Blog") broke the Markdown table in `tech-digest.md` because the unescaped pipe was parsed as a column separator. Root cause in `v2_optimizer.py`: the `why` column escaped pipes (`.replace("|", "-")`) but the link title `t` did not. Fixed with `.replace("|", r"\|")` on the title. The 4 already-rendered broken entries in `tech-digest.md` are corrected directly.
|
||||
|
||||
## [[2.9.9]](https://github.com/nubenetes/awesome-kubernetes/releases/tag/v2.9.9) - 2026-06-19
|
||||
|
||||
### Changed
|
||||
- **Changelog Backfill**: Reconstructed the missing `2.6.0`–`2.9.1` entries from the GitHub Release notes, closing the gap where `CHANGELOG.md` had stalled at `2.5.8` while releases reached `2.9.x`. The changelog is now complete and continuous.
|
||||
|
||||
## [[2.9.8]](https://github.com/nubenetes/awesome-kubernetes/releases/tag/v2.9.8) - 2026-06-19
|
||||
|
||||
### Changed
|
||||
- **Inventory `gh_pushed` Data Cleanup**: Normalized 281 existing inventory entries whose `gh_pushed` date field held the literal string `"N/A"` to `null`, completing the `2.9.4` source fix. Deterministic and CI-reproducible (`last_checked` already migrated to integer by the pipeline).
|
||||
- **Changelog Maintenance**: Documented releases `2.9.2`–`2.9.8` in `CHANGELOG.md`.
|
||||
|
||||
## [[2.9.7]](https://github.com/nubenetes/awesome-kubernetes/releases/tag/v2.9.7) - 2026-06-19
|
||||
|
||||
### Fixed
|
||||
- **Hero Card Height Consistency**: Aligned the emoji-based "Intelligence Digest" hero card with the other four logo cards on the V2 index by giving `.hero-badge-icon` a 100px flex-centered box in `v2_elite.css` (was ~32px tall). Cache-bust bumped to `?v=2.9.7`.
|
||||
|
||||
## [[2.9.6]](https://github.com/nubenetes/awesome-kubernetes/releases/tag/v2.9.6) - 2026-06-19
|
||||
|
||||
### Fixed
|
||||
- **Deterministic Inventory Dump**: Stored `last_checked` as an `INTEGER` (epoch seconds) instead of a `REAL` in `inventory_manager.py`, normalizing the value on the entry before both the SQL and YAML dump. SQLite's version-specific `REAL`→text float printing previously rewrote ~every row of `inventory.sql` when regenerated outside CI. Verified `load→save` idempotent and byte-identical between local SQLite 3.40.1 and the CI-equivalent `python:3.11` (SQLite 3.46.1).
|
||||
|
||||
## [[2.9.5]](https://github.com/nubenetes/awesome-kubernetes/releases/tag/v2.9.5) - 2026-06-19
|
||||
|
||||
### Fixed
|
||||
- **Index Outage (Runaway YouTube Mosaic)**: Fixed `reorganize_mosaic.load_inventory_channels()` selecting channels by `'youtube_mosaic' in entry` (key presence). Because the SQL round-trip materializes that column as an empty dict `{}` on every entry, the filter matched all ~18,647 inventory entries and emitted ~18.6k inline image links on a single line — producing a 4 MB `v2-docs/index.md` (and 2.9 MB `docs/index.md`) that hung both the V1 and V2 index pages. Now only entries with a non-empty `youtube_mosaic` dict and a logo image are rendered (136 curated channels).
|
||||
|
||||
## [[2.9.4]](https://github.com/nubenetes/awesome-kubernetes/releases/tag/v2.9.4) - 2026-06-19
|
||||
|
||||
### Fixed
|
||||
- **`gh_pushed` Source Normalization**: The enrichment writers (`fast_enrich.py`, `gemini_utils.py`) now store `gh_pushed` as `None` when GitHub data is unavailable, instead of the string `"N/A"` that reached `datetime.fromisoformat()` downstream. `gh_license` keeps its displayed `"N/A"` string sentinel.
|
||||
- **Curator Date-Parse Hardening**: Guarded the twin `fromisoformat()` call in `agentic_curator.py`'s MVQ-penalty check so a bad date value can't crash a curation batch.
|
||||
|
||||
### Added
|
||||
- **Inventory Migration Script**: Added `scripts/normalize_gh_pushed.py` to clean existing `gh_pushed: "N/A"` rows.
|
||||
|
||||
## [[2.9.3]](https://github.com/nubenetes/awesome-kubernetes/releases/tag/v2.9.3) - 2026-06-19
|
||||
|
||||
### Fixed
|
||||
- **Platinum Audit Null Handling**: Hardened `safety_guard.py` against null/`"N/A"` inventory fields. The MVQ compliance check no longer passes `"N/A"` to `datetime.fromisoformat()` or multiplies a `None` star count; the linguistic-tagging check no longer calls `None.lower()` on a null `language` (which had aborted the entire audit). Each mandate now runs in isolation so one bad entry cannot kill the whole report.
|
||||
|
||||
## [[2.9.2]](https://github.com/nubenetes/awesome-kubernetes/releases/tag/v2.9.2) - 2026-06-19
|
||||
|
||||
### Fixed
|
||||
- **Dark-Theme CSS Flashes**: Removed `content-visibility: auto` from broad `<ul>`/`<ol>` selectors and `.v2-tag-section` in `v2_elite.css`. On the slate (dark) theme it caused black flashes while scrolling and made link lists below the index mosaic appear collapsed (intrinsic-size mismatch). The tags page already uses collapsed `<details>` for native render-skipping, so the optimization was redundant. Cache-bust bumped to `?v=2.9.2`.
|
||||
|
||||
## [[2.9.1]](https://github.com/nubenetes/awesome-kubernetes/releases/tag/v2.9.1) - 2026-06-19
|
||||
|
||||
### Changed
|
||||
- **Incremental Digest Engine**: Each `(category × period)` cell in `news_digest.json` now stores a fingerprint (`entry_hash`, `entry_count`, `last_analyzed`, `method`) of its entry pool. Before calling Gemini, the engine checks the hash and staleness (`MAX_STALENESS_DAYS=30`) and reuses the stored result on a match — dropping Gemini calls from 66 to 0 when the inventory is unchanged, and to ~5–10 for a new ingestion batch.
|
||||
- **Trending Badge Source**: The freshness badge now shows the actual Gemini analysis date from `_meta.last_updated`.
|
||||
|
||||
### Removed
|
||||
- Redundant GitHub Actions digest cache (the committed `news_digest.json` is the persistent store) and the invalid `extra_head` key from `v2-mkdocs.yml`.
|
||||
|
||||
## [[2.9.0]](https://github.com/nubenetes/awesome-kubernetes/releases/tag/v2.9.0) - 2026-06-19
|
||||
|
||||
### Fixed
|
||||
- **Portal Outage — Publisher/Deploy Safety**: Resolved a multi-bug portal outage. Pruning and nav sync are now skipped entirely in `--render-only` mode (CI uses it, and pruning had deleted pages that the render pass didn't regenerate); page deletion is gated on `_sync_enterprise_navigation` returning success; the fragile `nav:` regex was replaced with a string split; and the deploy now verifies the V2 build has a minimum page count (50+ HTML pages + `index.html`) before overwriting V1, falling back to V1-only if V2 looks broken. Pages in `self.dimensions` are never pruned.
|
||||
|
||||
## [[2.8.5]](https://github.com/nubenetes/awesome-kubernetes/releases/tag/v2.8.5) - 2026-06-19
|
||||
|
||||
### Fixed
|
||||
- **V2 Build**: Removed the invalid `extra_head` key from `v2-mkdocs.yml` (was breaking V2 HTML generation) and fixed a broken `digital-money.md → finops.md` redirect (now points to `kubernetes.md` since `finops.md` was removed by the publisher).
|
||||
|
||||
## [[2.8.4]](https://github.com/nubenetes/awesome-kubernetes/releases/tag/v2.8.4) - 2026-06-19
|
||||
|
||||
### Fixed
|
||||
- **Comprehensive None-Stars Guard**: Replaced all `.get('stars', 0)` patterns in `v2_optimizer.py` with `.get('stars') or 0`, fixing `TypeError: '>=' not supported between NoneType and int` in `_render_single_link` and 13 other comparison/arithmetic sites.
|
||||
|
||||
## [[2.8.3]](https://github.com/nubenetes/awesome-kubernetes/releases/tag/v2.8.3) - 2026-06-19
|
||||
|
||||
### Added
|
||||
- **Digest Cache**: The publisher and weekly cron now cache `data/news_digest.json` with a day-scoped key (`news-digest-YYYY-MM-DD`). Same-day re-runs restore from cache and skip Gemini entirely (~20 min CI + 66 API calls saved per skipped run).
|
||||
|
||||
## [[2.8.2]](https://github.com/nubenetes/awesome-kubernetes/releases/tag/v2.8.2) - 2026-06-19
|
||||
|
||||
### Fixed
|
||||
- **None-Stars Sort Crashes**: Fixed three `-x.get('stars', default)` sites in `v2_optimizer.py` that crashed with `TypeError: bad operand for unary -: 'NoneType'` when `stars` was null, using the `-(x.get('stars') or default)` pattern (`sort_rec`, `trending_pool`, `sorted_links`).
|
||||
|
||||
## [[2.8.1]](https://github.com/nubenetes/awesome-kubernetes/releases/tag/v2.8.1) - 2026-06-19
|
||||
|
||||
### Fixed
|
||||
- **None `resource_type` Crash**: Fixed `AttributeError: 'NoneType' object has no attribute 'lower'` in `_calculate_tags` when `resource_type` was present but null, via `(item.get('resource_type') or 'Reference')`.
|
||||
|
||||
## [[2.8.0]](https://github.com/nubenetes/awesome-kubernetes/releases/tag/v2.8.0) - 2026-06-19
|
||||
|
||||
### Added
|
||||
- **geo_region Inference**: `_infer_geo_from_url()` maps URL TLDs to regions (`.es`→España, EU TLDs→Europe, APAC TLDs→Asia-Pacific, Americas TLDs→Americas), populating the industry digest.
|
||||
- **Freshness Badge**: The Trending section header shows an `Updated <date>` pill derived from `news_digest.json` mtime.
|
||||
- **Search Boost**: `tech-digest.md` and `industry-digest.md` are generated with `search.boost: 2` frontmatter.
|
||||
- **RSS Feed**: New `src/rss_generator.py` emits `v2-docs/feed.xml` (top-20 from the 3-month digest) with autodiscovery links, at `https://nubenetes.com/feed.xml`.
|
||||
- **Weekly Cron**: `.github/workflows/09.weekly_digest.yml` runs Mondays 06:00 UTC to regenerate the digest and trigger the publisher.
|
||||
|
||||
## [[2.7.1]](https://github.com/nubenetes/awesome-kubernetes/releases/tag/v2.7.1) - 2026-06-19
|
||||
|
||||
### Changed
|
||||
- **Cleaner Index**: Removed the `digest-preview` list from the index — the trending cards already show the same content with better design. Flow is now hero amber card → trending cards → `/tech-digest/`.
|
||||
|
||||
## [[2.7.0]](https://github.com/nubenetes/awesome-kubernetes/releases/tag/v2.7.0) - 2026-06-19
|
||||
|
||||
### Added
|
||||
- **Intelligence Digest Hero Card**: New amber `Intelligence Digest` card on the V2 index linking to `/tech-digest/`, plus a `digest-preview` mini-block showing the top pick from 5 priority categories. New `hero-badge-card--amber` and `digest-preview` CSS components.
|
||||
|
||||
## [[2.6.9]](https://github.com/nubenetes/awesome-kubernetes/releases/tag/v2.6.9) - 2026-06-19
|
||||
|
||||
### Fixed
|
||||
- **NoneType Crashes Across Pipeline**: Inventory entries with `stars: null` crashed `_calculate_tags` (`v2_optimizer.py`), the title-dedup index and entry scoring (`dedup.py`), and category sorting (`news_digest.py`). Replaced `.get("stars", 0)` with `.get("stars") or 0`.
|
||||
|
||||
## [[2.6.8]](https://github.com/nubenetes/awesome-kubernetes/releases/tag/v2.6.8) - 2026-06-19
|
||||
|
||||
### Fixed
|
||||
- **Unbounded License Check**: `detect_license_changes()` iterated every entry with `gh_license` set (thousands of GitHub API calls). Applied the `MAX_REPOS_DEFAULT=200` cap, bringing total enrichment time to ~3–4 min.
|
||||
|
||||
## [[2.6.7]](https://github.com/nubenetes/awesome-kubernetes/releases/tag/v2.6.7) - 2026-06-19
|
||||
|
||||
### Changed
|
||||
- **Enrichment 7.5× Faster**: Reduced GitHub activity enrichment from 2 API calls/repo to 1 (`open_issues_count` already includes PRs), capped at 200 repos/run, 0.5s delay, with 429 backoff — ~100s vs 12.5 min.
|
||||
|
||||
## [[2.6.6]](https://github.com/nubenetes/awesome-kubernetes/releases/tag/v2.6.6) - 2026-06-19
|
||||
|
||||
### Fixed
|
||||
- **CNCF Enrichment API**: The CNCF Landscape API became a SPA and stopped returning JSON. Enrichment now queries the GitHub Search API with official CNCF maturity topics (`cncf-graduated`/`cncf-incubating`/`cncf-sandbox`) using the existing `GH_TOKEN`.
|
||||
|
||||
## [[2.6.4]](https://github.com/nubenetes/awesome-kubernetes/releases/tag/v2.6.4) - 2026-06-19
|
||||
|
||||
### Fixed
|
||||
- **Differentiated Digest Periods**: 3/6/12-month windows now yield 10/15/20 items per category; backfilled `discovered_at` entries appear in wider windows; null-`stars` entries no longer crash the generator.
|
||||
|
||||
## [[2.6.3]](https://github.com/nubenetes/awesome-kubernetes/releases/tag/v2.6.3) - 2026-06-19
|
||||
|
||||
### Added
|
||||
- **First Real Intelligence Digest**: Generated locally with 0 Gemini tokens — 22 categories, 660 items (220 per period) from the 18,647-entry inventory, with star-based ranking (upgrades to AI ranking on the next keyed pipeline run).
|
||||
|
||||
## [[2.6.2]](https://github.com/nubenetes/awesome-kubernetes/releases/tag/v2.6.2) - 2026-06-19
|
||||
|
||||
### Fixed
|
||||
- **Clean URL Policy**: Removed the `offline` plugin that forced `.html` suffixes on all V2 URLs (breaking SEO/deep-links) and added placeholder `tech-digest.md`/`industry-digest.md` pages to prevent 404s before the first Gemini run. `use_directory_urls: true` is now mandatory and `offline` permanently forbidden (documented in `CLAUDE.md`/`GEMINI.md`/`README`).
|
||||
|
||||
## [[2.6.1]](https://github.com/nubenetes/awesome-kubernetes/releases/tag/v2.6.1) - 2026-06-19
|
||||
|
||||
### Added
|
||||
- **Agent Instructions**: Created `CLAUDE.md` (Gitflow, repo structure, build commands, conventions) and added a Gitflow section to `GEMINI.md` so both AI agents follow the branching model automatically.
|
||||
|
||||
## [[2.6.0]](https://github.com/nubenetes/awesome-kubernetes/releases/tag/v2.6.0) - 2026-06-19
|
||||
|
||||
### Added
|
||||
- **AI-Powered Intelligence Digest**: 26-category news digest engine with Gemini ranking, 3/6/12-month temporal panels, Trending Now cards, and dedicated `tech-digest`/`industry-digest` pages with company & geo_region extraction.
|
||||
- **Data Quality Pipeline**: CNCF Landscape integration, GitHub activity enrichment, license-change detection, a deduplication engine (URL + content-hash + 85% title similarity), and AI re-evaluation flagging for stale entries.
|
||||
- **MkDocs UX Overhaul**: Enabled tags/RSS/minify/PWA plugins, instant navigation with prefetch, breadcrumbs, footer nav, and an announcement bar (28 improvements across 31 files, 4 new modules, 18,647 entries backfilled).
|
||||
|
||||
### Fixed
|
||||
- **Disabled Plugins**: Fixed plugins being nested under `theme:` in MkDocs config (silently disabled since deployment).
|
||||
|
||||
## [[2.5.8]](https://github.com/nubenetes/awesome-kubernetes/releases/tag/v2.5.8) - 2026-06-18
|
||||
|
||||
### Added
|
||||
- **Debate & Ingestion Documentation**: Documented the Fast-Pass screening evaluator, Twikit toggle, failure-aware domain timeouts, mobile identity rotation, and tag pagination limits in `README.md`.
|
||||
- **Consensus Flow Visualization**: Redesigned the multi-agent consensus protocol Mermaid diagram in `README.md` to map the Fast-Pass screening logic.
|
||||
|
||||
## [[2.5.7]](https://github.com/nubenetes/awesome-kubernetes/releases/tag/v2.5.7) - 2026-06-18
|
||||
|
||||
### Added
|
||||
- **Fast-Pass Debate Evaluator (Recommendation #3)**: Optimized the consensus debate engine in `src/v2_debate.py` with a Fast-Pass Evaluator tier using a single Flash model call. Borderline scores between 60 and 75 escalate to the full Multi-Agent panel (Security, SRE, AI Architect), while clear cases bypass it.
|
||||
- **Resilient Health Checking (Recommendation #2)**: Introduced the `ENABLE_TWITTER_CURATION` toggle to optionally bypass Twikit/Playwright scraping. Integrates domain failure tracking in `src/memory/health_learning.json` to dynamically adjust timeouts and rotate User-Agents under consecutive failure conditions.
|
||||
- **Tag Page Cap (Recommendation #5)**: Prevented tag page DOM bloat in `v2-docs/tags.md` by capping the rendered links per tag to 100 (sorted by stars and year) and adding fallback links to the V1 Historical Archive.
|
||||
|
||||
## [[2.5.6]](https://github.com/nubenetes/awesome-kubernetes/releases/tag/v2.5.6) - 2026-06-18
|
||||
|
||||
### Added
|
||||
- **AI Agent Skill Runbook**: Integrated a local workspace operations skill at `.gemini/skills/awesome-kubernetes-ops/SKILL.md` to guide Antigravity interactive assistant commands, test checks, and release promotions.
|
||||
- **AI Operations Documentation**: Expanded the `README.md` with a detailed collapsible section and Mermaid architecture diagram explaining the Division of Labor between automated cloud runners (`GEMINI.md` curation rules) and local interactive coding assistants (`SKILL.md` runbook).
|
||||
|
||||
## [[2.5.5]](https://github.com/nubenetes/awesome-kubernetes/releases/tag/v2.5.5) - 2026-06-18
|
||||
|
||||
### Added
|
||||
- **Modern CSS Enhancements**: Implemented browser-native CSS enhancements in `v2_elite.css` including typographic header balancing (`text-wrap: balance`), orphan word prevention (`text-wrap: pretty`), native auto-sizing form inputs (`field-sizing: content`), and coarser target sizes (`min-block-size: 44px`) for mobile tag/button targets.
|
||||
- **Unified Pipeline Concurrency**: Set up a shared static concurrency group `develop-git-write-lock` across workflows (`03.1`, `03.2`, `03.3`, `04.1`, `05.1`) to prevent git push race conditions on the `develop` branch.
|
||||
- **Push Fail Recovery**: Enhanced the git push rebase retry loops in publisher and sync workflows to verify push success and back-off before retrying.
|
||||
|
||||
### Fixed
|
||||
- **Markdown Horizontal Rule Linting**: Corrected horizontal rule style in `docs/about.md` to use four-hyphen `----` to comply with markdownlint rules.
|
||||
|
||||
## [[2.5.4]](https://github.com/nubenetes/awesome-kubernetes/releases/tag/v2.5.4) - 2026-06-18
|
||||
|
||||
### Added
|
||||
- **AI Tool Integration**: Integrated verified references for Cursor AI Code Editor (`https://cursor.com`), Google Antigravity Agentic Platform (`https://antigravity.google`), Anthropic Claude Code CLI (`https://docs.anthropic.com/en/docs/agents-and-tools/claude-code/overview`), GitHub Copilot Workspace, Copilot Agent Mode, and GitHub Actions continuous delivery best practices.
|
||||
- **Centralized Metadata Registry**: Registered all new developer productivity and AI agent tools in the centralized `data/inventory.yaml` database.
|
||||
|
||||
### Fixed
|
||||
- **V2 Link Parsing Regex**: Modified the parser in `v2_optimizer.py` to correctly identify and process links prefixed with `**(YYYY)**` year metadata.
|
||||
|
||||
## [[2.5.2]](https://github.com/nubenetes/awesome-kubernetes/releases/tag/v2.5.2) - 2026-06-18
|
||||
|
||||
### Added
|
||||
|
||||
@@ -0,0 +1,93 @@
|
||||
# CLAUDE.md — Nubenetes Project Instructions for Claude Code
|
||||
|
||||
## Git Workflow: Gitflow
|
||||
|
||||
This repository uses **Gitflow**. All agents MUST follow this branching model:
|
||||
|
||||
### Branches
|
||||
- **`master`** — Production. Only receives merges from release branches. Every merge to master gets a **tag** and a **GitHub Release**.
|
||||
- **`develop`** — Integration branch. All feature branches merge here first.
|
||||
- **`feat/*`** — Feature branches. Created from `develop`, merged back to `develop` via PR.
|
||||
- **`release/vX.Y.Z`** — Release branches. Created from `develop` when ready to release, merged to both `master` AND back to `develop`.
|
||||
- **`gh-pages`** — Deployment. Never touch directly.
|
||||
|
||||
### Release Process (mandatory for all releases)
|
||||
1. Create feature branch from `develop`: `git checkout -b feat/description develop`
|
||||
2. Implement changes, commit, push feature branch
|
||||
3. Create PR: `gh pr create --base develop --head feat/description`
|
||||
4. Merge PR to develop: `gh pr merge N --merge`
|
||||
5. Create release branch: `git checkout -b release/vX.Y.Z develop`
|
||||
6. Merge release to master: `git checkout master && git merge release/vX.Y.Z --no-ff`
|
||||
7. Tag: `git tag -a vX.Y.Z -m "description"`
|
||||
8. Push master + tag: `git push origin master && git push origin vX.Y.Z`
|
||||
9. Back-merge master to develop: `git checkout develop && git merge master --no-ff && git push origin develop`
|
||||
10. Create GitHub Release: `gh release create vX.Y.Z --title "..." --notes "..."`
|
||||
|
||||
### Versioning
|
||||
- Current: `v2.9.2`
|
||||
- Format: `v{major}.{minor}.{patch}`
|
||||
- Major: breaking changes or architectural shifts
|
||||
- Minor: new features (like the digest engine, new modules)
|
||||
- Patch: bug fixes, config tweaks
|
||||
|
||||
### Protected Branches
|
||||
`master`, `develop`, and `gh-pages` are NEVER deleted. Branch cleanup runs bi-monthly for merged feature branches.
|
||||
|
||||
## Repository Structure
|
||||
|
||||
### Key Directories
|
||||
- `docs/` — V1 source (exhaustive archive, source of truth)
|
||||
- `v2-docs/` — V2 source (AI-curated elite portal, derived from V1)
|
||||
- `src/` — Python pipeline source code
|
||||
- `data/` — Inventory (YAML + SQL), config files, digest JSON
|
||||
- `scripts/` — Utility scripts (backfill, etc.)
|
||||
- `.github/workflows/` — CI/CD (15 workflows)
|
||||
|
||||
### Key Config Files
|
||||
- `v2-mkdocs.yml` — V2 MkDocs Material configuration
|
||||
- `mkdocs.yml` — V1 MkDocs configuration
|
||||
- `data/inventory.yaml` / `data/inventory.sql` — Unified inventory (18K+ entries)
|
||||
- `data/curation_sources.yaml` — RSS feeds and X/Twitter accounts
|
||||
- `data/link_rules.yaml` — Curation policies
|
||||
- `GEMINI.md` — AI mandates and learning roadmap (read by Gemini agents)
|
||||
|
||||
### Pipeline Modules
|
||||
- `src/v2_optimizer.py` — Main rendering engine (V2VisionEngine class)
|
||||
- `src/news_digest.py` — 26-category temporal digest with Gemini ranking
|
||||
- `src/enrichment.py` — CNCF Landscape + GitHub activity + license detection
|
||||
- `src/dedup.py` — URL/hash/title deduplication engine
|
||||
- `src/agentic_curator.py` — Ingestion pipeline with AI evaluation
|
||||
- `src/autonomous_discovery.py` — GitHub trending discovery (14 queries)
|
||||
- `src/gemini_utils.py` — Gemini API wrapper with key rotation
|
||||
- `src/inventory_manager.py` — Dual YAML+SQL inventory management
|
||||
|
||||
## Build and Run
|
||||
|
||||
### Local testing (no API keys needed)
|
||||
```bash
|
||||
pip install -r requirements.txt
|
||||
mkdocs serve -f v2-mkdocs.yml # Preview V2 portal
|
||||
mkdocs serve -f mkdocs.yml # Preview V1 portal
|
||||
```
|
||||
|
||||
### Pipeline commands
|
||||
```bash
|
||||
python3 -m scripts.backfill_discovered_at # Backfill discovered_at field
|
||||
python3 -m src.news_digest # Generate digest (needs Gemini API key)
|
||||
python3 -m src.enrichment # CNCF + GitHub enrichment (needs GH_TOKEN)
|
||||
python3 -m src.dedup # Dedup scan (dry-run by default)
|
||||
python3 -m src.v2_optimizer --render-only # Render V2 portal (no AI calls)
|
||||
```
|
||||
|
||||
## Coding Conventions
|
||||
- All Python exceptions must use `except Exception as e: log_event(f"[WARN] context: {str(e)[:100]}")` — never bare `except: pass`
|
||||
- Use `from src.logger import log_event` for logging
|
||||
- Use `from src.config import MADRID_TZ` for timezone-aware timestamps
|
||||
- Inventory fields: `discovered_at` (ISO), `last_ai_eval` (ISO), `company`, `geo_region` must be preserved during merges
|
||||
- The `update_inventory_entry()` function preserves `discovered_at` — never overwrite it with new data
|
||||
|
||||
## URL Policy: Clean URLs, No .html Suffix
|
||||
Both V1 and V2 MUST use `use_directory_urls: true` in their mkdocs.yml. This produces clean URLs like `/kubernetes/` instead of `/kubernetes.html`. **NEVER** enable the `offline` plugin — it forces `.html` suffixes on all URLs, breaking SEO and existing deep-links. This is a hard rule.
|
||||
|
||||
## RSS/Twitter Sources
|
||||
RSS feeds are limited to those that actually work (many block bots). Don't add new RSS feeds without testing. Current working feeds are defined in `data/curation_sources.yaml`.
|
||||
@@ -376,4 +376,31 @@ The bot must rotate between profiles to avoid detection:
|
||||
- **V2 Index Metrics Protocol**: The "Knowledge Architecture and AI Coverage Status" report in the V2 index MUST include a direct comparison between V1 and V2 inventory. This report MUST display: 1. **V1 Base Inventory** (Total resources in the master archive), 2. **V2 Elite Selection** (Count of candidates and the resulting density ratio), 3. **AI Enrichment Coverage**, and 4. **GitHub Metadata Coverage**. This ensures transparency in the knowledge distillation process.
|
||||
- **Redundancy-Free Branding**: To ensure professional UI density, the V2 Portal header MUST NOT repeat the "Nubenetes" brand. The title MUST follow the pattern: "Nubenetes Elite Portal (V2) | Awesome Kubernetes and Cloud".
|
||||
- **Decoupled Workflow Architecture**: The Agentic V2 ecosystem MUST utilize a decoupled micro-workflow structure (Health Monitor, Metadata Engine, AI Curator, and Publisher) to optimize compute quotas and minimize Gemini token consumption. Any update to the V2 rendering logic MUST use the `--render-only` flag in the Publisher pipeline to maintain execution speed.
|
||||
to maintain execution speed.
|
||||
|
||||
## Git Workflow: Gitflow (Mandatory)
|
||||
|
||||
This repository uses **Gitflow**. All agents and automated processes MUST follow this branching model:
|
||||
|
||||
- **`master`**: Production branch. Only receives merges from `release/*` branches. Every merge to master gets a **semantic version tag** (`vX.Y.Z`) and a **GitHub Release** with detailed release notes.
|
||||
- **`develop`**: Integration branch. All feature branches merge here via PR. Back-merged from master after each release.
|
||||
- **`feat/*`**: Feature branches. Created from `develop`, merged back to `develop` via PR.
|
||||
- **`release/vX.Y.Z`**: Release branches. Created from `develop`, merged to `master` with `--no-ff`, then back-merged to `develop`.
|
||||
- **`gh-pages`**: Deployment. NEVER modified directly.
|
||||
- **Protected branches**: `master`, `develop`, `gh-pages` — NEVER deleted.
|
||||
|
||||
### Release Sequence
|
||||
1. Feature branch → PR to `develop` → merge
|
||||
2. Create `release/vX.Y.Z` from `develop`
|
||||
3. Merge release to `master` (`--no-ff`)
|
||||
4. Create annotated tag: `git tag -a vX.Y.Z -m "..."`
|
||||
5. Push master + tag
|
||||
6. Back-merge master to develop (`--no-ff`)
|
||||
7. Create GitHub Release with `gh release create`
|
||||
|
||||
### Versioning: `v{major}.{minor}.{patch}`
|
||||
- **Major**: breaking changes or architectural shifts
|
||||
- **Minor**: new features (modules, digest categories, new pipelines)
|
||||
- **Patch**: bug fixes, config tweaks, content updates
|
||||
|
||||
## URL Policy: Clean URLs (Mandatory)
|
||||
Both V1 (`mkdocs.yml`) and V2 (`v2-mkdocs.yml`) MUST use `use_directory_urls: true` to produce clean URLs like `/kubernetes/` instead of `/kubernetes.html`. **NEVER** enable the MkDocs `offline` plugin — it forces `.html` suffixes on all URLs, breaking SEO authority and thousands of existing deep-links. This is a hard, non-negotiable rule.
|
||||
|
||||
@@ -32,6 +32,7 @@
|
||||
* [4.2. Hardened Architecture (2026)](#42-hardened-architecture-2026)
|
||||
* [4.3. Adaptive AI Tiering and Real-time Grounding](#43-adaptive-ai-tiering-and-real-time-grounding)
|
||||
* [4.4. Doc-as-Behavior Mandate Bridge](#44-doc-as-behavior-mandate-bridge)
|
||||
* [4.5. AI Operations Division of Labor (Local vs. Cloud)](#45-ai-operations-division-of-labor-local-vs-cloud)
|
||||
5. [5. Dual-Edition Architecture (V1 vs V2)](#5-dual-edition-architecture-v1-vs-v2)
|
||||
* [5.1. V1: The Exhaustive Archive](#51-v1-the-exhaustive-archive)
|
||||
* [5.2. V2: The Agentic Elite Edition](#52-v2-the-agentic-elite-edition)
|
||||
@@ -39,7 +40,7 @@
|
||||
* [5.4. The Incremental Elite Engine](#54-the-incremental-elite-engine)
|
||||
* [5.5. Decoupled Knowledge Lifecycle (V2 Architecture)](#55-decoupled-knowledge-lifecycle-v2-architecture)
|
||||
* [5.6. Multi-Language Support Policy](#56-multi-language-support-policy)
|
||||
6. [6. The Unified Agentic Database (Knowledge Graph)](#6-the-unified-agentic-database-knowledge-graph)
|
||||
6. [6. The Unified Agentic Database (Coexistence Knowledge Graph)](#6-the-unified-agentic-database-coexistence-knowledge-graph)
|
||||
* [6.1. Database Components](#61-database-components)
|
||||
* [6.2. The 'Database-First' Reasoning Protocol (Zero-Redundancy)](#62-the-database-first-reasoning-protocol-zero-redundancy)
|
||||
* [6.3. Database Lifecycle and Hygiene](#63-database-lifecycle-and-hygiene)
|
||||
@@ -134,14 +135,14 @@ Additionally, as of May 2026, Nubenetes has reached the **Platinum Operational T
|
||||
## 2. Repository Metrics and Evolution
|
||||
|
||||
### 2.1. The "Heart" of Nubenetes
|
||||
(Stats as of 2026-06-18)
|
||||
(Stats as of 2026-06-25)
|
||||
|
||||
<!-- HEART_STATS_START -->
|
||||
| Metric | Value |
|
||||
| :--- | :--- |
|
||||
| **Total Technical Resources (Links)** | **18639+** |
|
||||
| **Total Technical Resources (Links)** | **18655+** |
|
||||
| **Specialized MD Pages** | **162** |
|
||||
| **Total Commits** | **5934+** |
|
||||
| **Total Commits** | **6496+** |
|
||||
| **Primary AI Engine** | **Google Gemini (Agentic)** |
|
||||
<!-- HEART_STATS_END -->
|
||||
|
||||
@@ -156,7 +157,7 @@ Top 10 categories by link volume in the exhaustive V1 archive.
|
||||
| [Terraform](docs/terraform.md) | 414 |
|
||||
| [Demos](docs/demos.md) | 363 |
|
||||
| [Azure](docs/azure.md) | 296 |
|
||||
| [Git](docs/git.md) | 265 |
|
||||
| [Git](docs/git.md) | 268 |
|
||||
| [Visual Studio](docs/visual-studio.md) | 262 |
|
||||
| [Monitoring](docs/monitoring.md) | 254 |
|
||||
| [Devsecops](docs/devsecops.md) | 232 |
|
||||
@@ -179,7 +180,7 @@ The growth of Nubenetes reflects the acceleration of the Cloud Native ecosystem.
|
||||
| 6 | 2023 | 30 | 123 | Maintenance & Refinement |
|
||||
| 7 | 2024 | 53 | 218 | Curation Strategy Pivot |
|
||||
| 8 | 2025 | 5 | 20 | Stability & Research Phase |
|
||||
| 9 | 2026 | 2375 | 9,808 | **Agentic AI Surge** (May 2026 Inception) |
|
||||
| 9 | 2026 | 2937 | 12,129 | **Agentic AI Surge** (May 2026 Inception) |
|
||||
<!-- ANNUAL_GROWTH_END -->
|
||||
|
||||
<!-- ANNUAL_CHART_START -->
|
||||
@@ -194,9 +195,9 @@ config:
|
||||
xychart-beta
|
||||
title "Nubenetes Annual Growth Metrics (2018–2026)"
|
||||
x-axis ["2018", "2019", "2020", "2021", "2022", "2023", "2024", "2025", "2026"]
|
||||
y-axis "Volume (Commits / Estimated New Refs)" 0 --> 10000
|
||||
bar [1445, 586, 8449, 2193, 1660, 123, 218, 20, 9808]
|
||||
bar [350, 142, 2046, 531, 402, 30, 53, 5, 2375]
|
||||
y-axis "Volume (Commits / Estimated New Refs)" 0 --> 13000
|
||||
bar [1445, 586, 8449, 2193, 1660, 123, 218, 20, 12129]
|
||||
bar [350, 142, 2046, 531, 402, 30, 53, 5, 2937]
|
||||
```
|
||||
<!-- ANNUAL_CHART_END -->
|
||||
|
||||
@@ -206,7 +207,7 @@ xychart-beta
|
||||
| :--- | :---: | :---: | :--- |
|
||||
| 2026-04 | 25 | 103 | Active Curation |
|
||||
| 2026-05 | 2101 | 8,677 | **Agentic Inception (Gemini Era)** |
|
||||
| 2026-06 | 249 | 1,028 | Active Curation |
|
||||
| 2026-06 | 811 | 3,349 | Active Curation |
|
||||
<!-- MONTHLY_SURGE_END -->
|
||||
|
||||
### 2.4. Content Distribution and Semantic Clustering
|
||||
@@ -219,7 +220,7 @@ This chart shows the high-level distribution across the primary domains of Cloud
|
||||
<!-- PILLAR_CHART_START -->
|
||||
```mermaid
|
||||
pie title Nubenetes Major Ecosystem Pillars
|
||||
"Specialized Topics" : 4239
|
||||
"Specialized Topics" : 4255
|
||||
"Kubernetes Ecosystem" : 3500
|
||||
"Developer Ecosystem" : 3000
|
||||
"Public/Private Cloud" : 2500
|
||||
@@ -240,8 +241,8 @@ Reflecting Nubenetes' mission of global access while maintaining technical Engli
|
||||
<!-- SUB_ECO_CHART_START -->
|
||||
```mermaid
|
||||
pie title Linguistic Diversity (Global Access)
|
||||
"English" : 16775
|
||||
"Spanish" : 1118
|
||||
"English" : 16789
|
||||
"Spanish" : 1119
|
||||
"French" : 186
|
||||
"Others" : 559
|
||||
```
|
||||
@@ -267,6 +268,10 @@ The autonomy of Nubenetes is powered by a modern, resilient tech stack that ensu
|
||||
| **Discovery** | Twikit and Playwright | Autonomous scraping and account rotation. |
|
||||
| **Resilience** | Identity Rotation | Evasion of anti-bot blocks using multiple profiles. |
|
||||
| **Deployment** | MkDocs Material & Native GH Pages | High-performance static site generation via native artifact deployment. |
|
||||
| **Intelligence** | News Digest Engine | AI-powered temporal digest across 26 categories (3/6/12 months). |
|
||||
| **Enrichment** | CNCF + GitHub Activity | Landscape graduation status, issue/PR velocity, license change detection. |
|
||||
| **Dedup** | Similarity Engine | URL, content-hash, and title-similarity deduplication (85% threshold). |
|
||||
| **Offline** | PWA Support | Service Worker caching for offline reading of the portal. |
|
||||
|
||||
---
|
||||
|
||||
@@ -315,8 +320,8 @@ graph TD
|
||||
</details>
|
||||
|
||||
**Key Architectural Hardening:**
|
||||
- **Concurrency Guard:** Prevents race conditions by managing parallel workflow execution using GitHub Concurrency Groups. Workflows that write metadata/metrics (`03.1`, `03.2`, `03.3`, `04.1`, `05.1`) share a common concurrency group `develop-git-push` to serialize git pushes on `develop`.
|
||||
- **Self-Healing Git Rebase:** Incorporates a rebase retry loop that automatically resolves conflicts in generated files (like `README.md`) by checking out remote HEAD and re-running generators, preventing CI/CD pipeline failures.
|
||||
- **Concurrency Guard:** Prevents race conditions by managing parallel workflow execution using GitHub Concurrency Groups. Workflows that write metadata/metrics (`03.1`, `03.2`, `03.3`, `04.1`, `05.1`) share a static, unified concurrency group `develop-git-write-lock` to serialize git write operations on `develop` across all branches and event triggers.
|
||||
- **Self-Healing Git Rebase & Push Recovery:** Incorporates a rebase and push retry loop that automatically resolves conflicts in generated files (like `README.md`) by checking out remote HEAD, re-running generators, and validating both the rebase and push commands before exiting successfully, ensuring total CI/CD pipeline stability.
|
||||
- **Trigger Loop Prevention:** Uses the `[skip ci]` protocol to break infinite recursive loops during automated PR merges.
|
||||
- **Setup Acceleration:** Playwright caching reduces the environment initialization time from 5 minutes to under 60 seconds.
|
||||
- **Dependency Caching:** Global Pip caching via `requirements.txt` slashes build times across all pipelines.
|
||||
@@ -336,6 +341,36 @@ Nubenetes implements a direct bridge between documentation and AI behavior:
|
||||
- **Mandate Ingestion**: At the start of every workflow, the `MandateIngestor` parses the natural language instructions in [`GEMINI.md`](GEMINI.md).
|
||||
- **Dynamic Context**: These mandates are injected directly into the AI's system instructions, ensuring that the bot's reasoning is always aligned with the latest project policies without requiring manual code updates.
|
||||
|
||||
### 4.5. AI Operations Division of Labor (Local vs. Cloud)
|
||||
|
||||
Nubenetes partitions AI Agent tasks between the automated cloud pipeline and local developer environments to optimize resource usage and support interactive collaboration:
|
||||
|
||||
<details>
|
||||
<summary><b>View Division of Labor Architecture Diagram & Technical Details (Click to expand!)</b></summary>
|
||||
|
||||
```mermaid
|
||||
graph TD
|
||||
A["awesome-kubernetes Repository"] --> B["GEMINI.md<br>(Curation and Data Mandates)"]
|
||||
A --> C[".gemini/skills/<br>awesome-kubernetes-ops/SKILL.md<br>(Local Dev Operations Guide)"]
|
||||
|
||||
B --> D["Cloud Automation<br>(GitHub Actions runner)"]
|
||||
B --> E["Local Workspace<br>(Antigravity Coding Session)"]
|
||||
|
||||
C --> E
|
||||
style C fill:#f9f,stroke:#333,stroke-width:2px
|
||||
```
|
||||
|
||||
#### Shared Curation and Data Policies (`GEMINI.md`)
|
||||
* **Target**: Ephemeral CI/CD runners (GitHub Actions) and local coding assistants.
|
||||
* **Purpose**: Dictates *what* the repository structure, link formatting, language metadata tagging, and minimum quality levels must look like.
|
||||
* **Automation integration**: Ingested by the build scripts to programmatically construct system prompts for API LLM completions.
|
||||
|
||||
#### Local Assistant Operations (`SKILL.md`)
|
||||
* **Target**: Local pair-programming assistant (**Antigravity**).
|
||||
* **Purpose**: Instructs the assistant on *how* to execute local developer commands, perform test compilations, resolve merge conflicts, and manage production git deployment lifecycles.
|
||||
* **Automation integration**: Strictly local; ignored by cloud runners to keep pipelines lightweight.
|
||||
</details>
|
||||
|
||||
---
|
||||
|
||||
## 5. Dual-Edition Architecture (V1 vs V2)
|
||||
@@ -363,11 +398,60 @@ Nubenetes operates with two distinct editions to serve different engineering nee
|
||||
- **No stars**: Standard reference documentation and technical resources.
|
||||
- **Multi-Dimensional Tagging (1:N):** Every resource is classified with multiple semantic tags (e.g., `[DE FACTO STANDARD]`, `[GUIDE]`, `[CASE STUDY]`, `[EMERGING]`) providing deep technical context and maturity status.
|
||||
- **Minimalist Inline Summaries**: Resources feature a **"Deep-Dive"** inline tag (using native HTML5 `<details>`) that expands into a rich technical summary without consuming space when collapsed. These summaries use the **Double-Evidence Synthesis** protocol to provide verified architectural insights.
|
||||
- **Semantic Cross-Linking:** The portal autonomously identifies and links related categories within the same strategic dimension (e.g., suggesting `Flux` when reading about `Argo`), creating a cohesive **Industrial Knowledge Graph**.
|
||||
- **Semantic Cross-Linking:** The portal autonomously identifies and links related categories within the same strategic dimension (e.g., suggesting `Flux` when reading about `Argo`), creating a cohesive **Industrial Knowledge Graph**. Additionally, **cross-dimension "See Also" links** connect pages that share technical tags across different dimensions.
|
||||
- **Executive Context**: Every strategic dimension features an AI-generated **State-of-the-Art Introduction** providing high-level architectural context and industry direction before the link listings.
|
||||
- **Source of Truth:** The `v2-docs/` directory (Derived from V1).
|
||||
- **Deployment:** [nubenetes.com/v2/](https://nubenetes.com/v2)
|
||||
|
||||
#### V2 Intelligence Digest (June 2026)
|
||||
The V2 portal includes an **AI-powered Intelligence Digest** system that surfaces the most relevant resources from the last 3, 6, and 12 months across **26 curated categories**:
|
||||
|
||||
| Category Group | Categories |
|
||||
| :--- | :--- |
|
||||
| **Tech Core (9)** | Kubernetes & Orchestration, Containers & Runtime, Networking & Service Mesh, Architecture & Microservices, Data/Messaging/Storage, AI & Agents, MLOps & Data Science, Python/Java/Dev Ecosystem, Linux & System Foundations |
|
||||
| **Platform & Ops (8)** | Security & Compliance, Infrastructure as Code, CI/CD & GitOps, Observability/SRE/Testing, DevOps & Culture, Platform Engineering & DevEx, FinOps & Cloud Cost, Certification & Training |
|
||||
| **Cloud & Enterprise (5)** | AWS, Azure, GCP/OCI/Others, OpenShift/Red Hat, Virtualization & Private Cloud (VMware/Broadcom, Proxmox, Nutanix, KubeVirt) |
|
||||
| **Industry / Geo (4)** | Americas, Europe, Spain, Asia-Pacific |
|
||||
|
||||
**Key features:**
|
||||
- **Trending Now** cards on the index page with the top cross-category items ranked by Gemini AI
|
||||
- **Dedicated digest pages** (`tech-digest.md`, `industry-digest.md`) with tabbed 3/6/12 month views
|
||||
- **Temporal tracking** via `discovered_at` field on all 18,000+ inventory entries
|
||||
- **Company & geo-region classification** extracted by Gemini during ingestion for industry digest
|
||||
- **Automatic staleness detection**: entries enriched >6 months ago are re-evaluated by AI (`last_ai_eval`)
|
||||
|
||||
#### V2 Data Quality and Pipeline Hardening (June 2026)
|
||||
- **CNCF Landscape Integration** (`src/enrichment.py`): Auto-fetches graduation status (Sandbox/Incubating/Graduated/Archived) for CNCF projects to power maturity tags.
|
||||
- **GitHub Activity Enrichment**: Fetches issue/PR velocity and assigns community health scores (active/healthy/low/dormant).
|
||||
- **License Change Detection**: Compares stored licenses with current GitHub data, flagging high-impact changes (e.g., BSL, SSPL switches).
|
||||
- **Deduplication Engine** (`src/dedup.py`): URL normalization, content-hash matching, and title-similarity detection (85% threshold) to eliminate duplicate entries.
|
||||
- **Exception Observability**: All 50+ bare `except: pass` patterns across the pipeline replaced with contextual logging.
|
||||
- **Expanded Discovery**: Autonomous GitHub trending discovery expanded from 6 to 14 search queries covering DevOps, observability, security, IaC, databases, CI/CD, service mesh, and platform engineering.
|
||||
- **Stale Health Re-check**: Online entries older than 30 days are automatically re-validated instead of being skipped.
|
||||
|
||||
#### V2 MkDocs Material Enhancements (June 2026)
|
||||
- **Instant Navigation** with prefetch for SPA-like experience across 140+ pages
|
||||
- **Breadcrumbs** (`navigation.path`) for orientation in deep category hierarchies
|
||||
- **Announcement Bar** promoting the Intelligence Digest
|
||||
- **Tags Plugin** for native clickable cross-page tag navigation
|
||||
- **RSS Feed** for digest page subscription
|
||||
- **PWA/Offline Support** for cached offline reading
|
||||
- **Minify Plugin** for production HTML optimization
|
||||
- **12 Stub Pages Merged** into parent categories with automatic redirects (e.g., `react.md` → `javascript.md`, `chef.md` → `ansible.md`, `oauth.md` → `securityascode.md`)
|
||||
|
||||
#### V2 URL Policy (June 2026)
|
||||
- **Clean URLs enforced**: Both V1 and V2 use `use_directory_urls: true` producing SEO-friendly URLs (e.g., `/kubernetes/` not `/kubernetes.html`).
|
||||
- **Offline plugin permanently removed**: The MkDocs `offline` plugin forces `.html` suffixes on all URLs, breaking thousands of existing deep-links and SEO authority. It is explicitly forbidden in both `CLAUDE.md` and `GEMINI.md` mandates.
|
||||
|
||||
#### V2 Home Restructure and SEO (v2.9.16–v2.9.20)
|
||||
- **Category-first landing page**: The home leads with the dynamic **Trending Now / Intelligence Digest**, followed by the signature YouTube mosaic (now framed under a *"The Cloud Native Universe We Track"* heading with **visible per-group category labels** and `loading="lazy"` on its ~150 logos).
|
||||
- **Topic Map page** ([`topic-map.md`](v2-docs/topic-map.md)): The complete category directory grouped by strategic dimension in a **responsive multi-column CSS grid**, with a **per-category resource count** derived from a recursive walk of each category's link tree. Replaces the long flat "Strategic Dimensions" list that previously bloated the home.
|
||||
- **Methodology page** ([`methodology.md`](v2-docs/methodology.md)): The Maturity Taxonomy and Technical Impact (star-score) legend tables, moved off the home into a dedicated reference page.
|
||||
- **Per-page "Last update" dates**: The `git-revision-date-localized` plugin surfaces a real last-modified date on every page (freshness signal for SEO and readers); the deploy checkout uses `fetch-depth: 0` for full history.
|
||||
- **JSON-LD structured data**: schema.org `WebSite` (with a sitelinks `SearchAction`) + publishing `Organization` markup injected via `docs/overrides/main.html` for richer search results.
|
||||
- **Branded 404 page** and **privacy-friendly video embeds** (`youtube-nocookie.com` + lazy-loading + responsive `aspect-ratio` wrapper).
|
||||
- **Deterministic generated artifacts**: the RSS feed's `lastBuildDate` derives from item content dates (not wall-clock), and the PR Guardian no longer auto-formats the generated `v2-docs/` tree — both eliminating spurious `develop ↔ master` churn.
|
||||
|
||||
### 5.3. Architecture Comparison Matrix: V1 vs. V2
|
||||
To better understand the dual-nature of the project, the following matrix details the technical and philosophical differences between the two editions:
|
||||
|
||||
@@ -459,27 +543,110 @@ To embrace the diverse global Cloud Native community while maintaining internati
|
||||
|
||||
---
|
||||
|
||||
## 6. The Unified Agentic Database (Knowledge Graph)
|
||||
## 6. The Unified Agentic Database (Coexistence Knowledge Graph)
|
||||
|
||||
Nubenetes now utilizes a **Unified Metadata Architecture** to maintain consistency across V1 and V2 while optimizing AI performance. All links are indexed in a local YAML database that serves as the **Persistent Memory** for our autonomous agents.
|
||||
Nubenetes now utilizes a **Unified SQL & YAML Database Architecture** to maintain consistency across V1 and V2 while optimizing agentic operations and repository efficiency. All curated links and metadata are managed via a coexisting local database engine.
|
||||
|
||||
### 6.1. Database Components
|
||||
1. **Central Inventory ([`data/inventory.yaml`](data/inventory.yaml))**: The universal single source of truth for technical metadata and resource lifecycle.
|
||||
* **Core Data**: `title`, `year`, `stars` (0-5), `description` (V1 Native), `ai_summary` (V2 English), `category`.
|
||||
* **Structural Intelligence**: `hierarchy` (Recursive list up to 10 levels), `v1_locations`, `v2_locations`.
|
||||
* **Platinum Lifecycle**: `content_hash` (SHA256), `health_score` (0-100), `source_provenance`, `social_preview_url`, `mentions_count`.
|
||||
### 6.1. Database Components and SQLite Engine (Option 3 Coexistence)
|
||||
|
||||
To guarantee backward compatibility and Git efficiency, the system operates on a dual-save database coexistence model:
|
||||
1. **SQLite Database & SQL Text ([`data/inventory.sql`](data/inventory.sql))**: The Git source-of-truth. During execution, the SQL script compiles into a temporary in-memory SQLite database, enabling full relational schema access and SQL query optimization. On save, SQLite's native `iterdump()` decompiles it back into a flat SQL text database file where each resource insert occupies a single line for perfect git diff readability.
|
||||
2. **Central Backup Inventory ([`data/inventory.yaml`](data/inventory.yaml))**: Automatically synchronized during database saves. Serves as a backward-compatible interface for legacy markdown parsing scripts.
|
||||
3. **High-Speed Parsing (C-Loader Integration)**: Direct YAML parsing utilizes high-speed native C-extensions (`yaml.CSafeLoader` and `yaml.CSafeDumper`) across all Python scripts (e.g. `v2_optimizer.py`, `reorganize_mosaic.py`, `safety_guard.py`) for a 10x-20x speedup in parsing operations.
|
||||
|
||||
#### 6.1.2. Platinum Lifecycle Schema
|
||||
* **Core Data**: `url` (Primary Key), `title`, `year`, `stars` (0-5), `description` (V1 Native), `ai_summary` (V2 English), `category`.
|
||||
* **Structural Intelligence**: `hierarchy` (Recursive JSON list), `tags` (JSON list), `v1_locations`, `v2_locations`, `youtube_mosaic` (JSON dict).
|
||||
* **Platinum Lifecycle**: `content_hash` (SHA256 fingerprint), `health_score` (0-100), `source_provenance`, `social_preview_url`, `mentions_count`, `addition_method`.
|
||||
|
||||
#### 6.1.3. Database Architecture Diagram (YAML + SQLite Coexistence)
|
||||
The following diagram details the dual-format storage engine: the flat `inventory.sql` text file is the Git source of truth, compiled into an in-memory SQLite database at runtime for relational queries, then decompiled back on save and mirrored to `inventory.yaml` for backward-compatible, high-speed parsing.
|
||||
|
||||
<details><summary>🗺️ <b>View Database Architecture Diagram</b></summary>
|
||||
|
||||
```mermaid
|
||||
graph TD
|
||||
subgraph GIT["Git Source of Truth (versioned · 1 line per resource)"]
|
||||
SQL["data/inventory.sql<br/>flat SQL text"]
|
||||
YAML["data/inventory.yaml<br/>backward-compatible mirror"]
|
||||
end
|
||||
|
||||
SQL -->|"compile on load"| MEM[("In-memory SQLite<br/>relational schema + SQL queries")]
|
||||
MEM -->|"iterdump() on save"| SQL
|
||||
MEM -->|"dual-save sync"| YAML
|
||||
YAML -->|"CSafeLoader / CSafeDumper<br/>native C speed (10-20x)"| PARSE["Python consumers<br/>v2_optimizer · reorganize_mosaic<br/>safety_guard"]
|
||||
AI["Gemini AI agents"] -->|"JSON messages in / out"| MEM
|
||||
|
||||
subgraph SCHEMA["Per-resource record — url = Primary Key"]
|
||||
CORE["Core<br/>title · year · stars 0-5<br/>description V1 · ai_summary V2 · category"]
|
||||
STRUCT["Structural<br/>hierarchy JSON · tags JSON<br/>v1/v2_locations · youtube_mosaic JSON"]
|
||||
PLAT["Platinum lifecycle<br/>content_hash SHA256 · health_score<br/>discovered_at · last_ai_eval · addition_method"]
|
||||
end
|
||||
|
||||
MEM -.->|"defines"| CORE
|
||||
MEM -.->|"defines"| STRUCT
|
||||
MEM -.->|"defines"| PLAT
|
||||
|
||||
style SQL fill:#bbf,stroke:#333,stroke-width:2px
|
||||
style MEM fill:#f96,stroke:#333,stroke-width:2px
|
||||
style YAML fill:#86efac,stroke:#333,stroke-width:2px
|
||||
```
|
||||
|
||||
</details>
|
||||
|
||||
### 6.2. The 'Database-First' Reasoning Protocol (Zero-Redundancy)
|
||||
To maximize economic efficiency and maintain the **30-minute execution standard**, all AI agents follow a **Database-First** and **Zero-Redundancy** protocol:
|
||||
1. **Local Lookup**: Before initiating any Gemini call, the agent checks if the URL is already indexed in [`data/inventory.yaml`](data/inventory.yaml).
|
||||
2. **Zero-Redundancy Pipeline**: The V2 Optimizer leverages health and metadata (`gh_stars`, `gh_license`) already validated by the `IntelligentLinkCleaner`. If a resource is marked as `status: online` and has recent metadata, V2 bypasses redundant network checks.
|
||||
3. **Smart Grounding (Search Retrieval)**: AI agents only activate grounding-heavy calls (Google Search) for resources that are new, missing metadata, or flagged for `needs_ai_refresh`. This reduces latencia by >80% for 15k+ link archives.
|
||||
4. **Insight Reuse**: If the resource exists with valid metadata, the agent **reuses existing insights**, reducing API traffic to zero.
|
||||
5. **Memory Efficiency Tracking**: The system tracks **Cache Hit Ratios** and **Estimated Token Savings** in every Intelligence Report.
|
||||
6. **Mandatory Persistence**: Modified YAML files are automatically injected into Pull Requests, ensuring that "System Memory" is version-controlled and shared across all workflows.
|
||||
1. **Local Lookup**: Before initiating any Gemini call, the agent queries the compiled SQLite/SQL database to see if the URL is already indexed.
|
||||
2. **Domain Reputation Registry**: In `main.py`, scraping/health-check success rates are recorded under `domain_reputation` inside `health_learning.json` for adaptive timeout and scraping rotation.
|
||||
3. **Stateful Debate Caching**: In `v2_debate.py`, consensus evaluations for borderline resources are cached based on the SHA256 hash of their combined metadata (`title`, `description`, `tags`). On cache hits, the agent skips redundant LLM calls and retrieves the score directly.
|
||||
4. **Pre-Commit Markdown Lint Hook**: In `src/pre_commit_schema_check.py`, a local Git pre-commit hook automatically runs on developer changes to enforce heading rules (no emojis/ampersands in titles), protocol integrity, link bracket spacing, and duplicate checks in docs markdown.
|
||||
5. **Insight Reuse**: If the resource exists with valid metadata, the agent **uses existing insights**, reducing API traffic to zero.
|
||||
6. **Memory Efficiency Tracking**: The system tracks **Cache Hit Ratios** and **Estimated Token Savings** in every Intelligence Report.
|
||||
7. **Mandatory Persistence**: Modified databases are automatically injected into Pull Requests, ensuring that "System Memory" is version-controlled and shared across all workflows.
|
||||
|
||||
### 6.3. Database Lifecycle and Hygiene
|
||||
To maintain a high-performance "Single Source of Truth", Nubenetes implements automated hygiene protocols:
|
||||
To maintain a high-performance "Single Source of Truth", Nubenetes implements automated hygiene protocols. The diagram below traces a resource's full lifecycle — from autonomous discovery and ingestion, through incremental (cached) maintenance and enrichment, to rendering and deployment — with continuous background garbage collection.
|
||||
|
||||
<details><summary>🗺️ <b>View Full Data Lifecycle Diagram</b></summary>
|
||||
|
||||
```mermaid
|
||||
graph TD
|
||||
subgraph S1["1 · Discovery and Ingestion"]
|
||||
SRC["X.com · RSS · GitHub Trending<br/>autonomous source discovery"] --> CUR["Agentic Curator<br/>dedup · vaporware filter · scoring"]
|
||||
end
|
||||
CUR -->|"new resources"| DB[("Unified DB<br/>inventory.sql + inventory.yaml")]
|
||||
|
||||
subgraph S2["2 · Maintenance and Enrichment (incremental + cached)"]
|
||||
HEALTH["Health Monitor<br/>200 OK · rescue 404s"]
|
||||
META["Metadata Engine<br/>GitHub stars · license · CNCF status"]
|
||||
AIEVAL["AI Curator<br/>summary · hierarchy · tags · debate"]
|
||||
DRIFT["Drift and Staleness<br/>SHA256 · re-eval after 6 months"]
|
||||
end
|
||||
DB <--> HEALTH
|
||||
DB <--> META
|
||||
DB <--> AIEVAL
|
||||
DB <--> DRIFT
|
||||
|
||||
subgraph S3["3 · Render"]
|
||||
DB -->|"surgical line edits"| V1["V1 Archive<br/>docs/"]
|
||||
DB -->|"elite selection + rebuild"| V2["V2 Portal<br/>v2-docs/"]
|
||||
DB --> AUX["RSS feed · digest<br/>README metrics"]
|
||||
end
|
||||
|
||||
subgraph S4["4 · Publish and Deploy"]
|
||||
V1 --> REL["develop → master<br/>tag + GitHub Release"]
|
||||
V2 --> REL
|
||||
REL --> PAGES["Native GH Pages<br/>nubenetes.com"]
|
||||
end
|
||||
|
||||
GC["Bi-monthly GC<br/>orphan pruning · audit log"] -.->|"hygiene"| DB
|
||||
|
||||
style DB fill:#f96,stroke:#333,stroke-width:2px
|
||||
style PAGES fill:#86efac,stroke:#333,stroke-width:2px
|
||||
```
|
||||
|
||||
</details>
|
||||
|
||||
- **Universal Rescue Protocol (The Resurrection Rule)**: For ALL technical resources, the engine refuses to delete a link immediately upon a 404 or generic redirect. Instead, it triggers a "Technical Resurrection" cycle using **Real-time Web Grounding** to identify specific paths on destination domains. This is essential for preserving legendary content during massive corporate site migrations (e.g., **Nginx** to **F5**, or the **Ansible Blog** move to personal domains).
|
||||
- **High-Value Preservation (The 'Review Required' Rule)**: Resources identified as **High-Value** (marked with 🌟 or bold formatting) are exempt from automatic deletion. If rescue fails, they are marked as `status: review_required` for manual verification, ensuring no significant technical assets are lost during autonomous cleaning.
|
||||
|
||||
@@ -679,10 +846,10 @@ graph TD
|
||||
end
|
||||
|
||||
subgraph "Agentic Tiering and Debate (Multi-Agent)"
|
||||
AA["Analyst Agent (Flash)"]
|
||||
AV["Auditor Agent (Pro)"]
|
||||
MCP[["MCP Grounding (Search)"]]
|
||||
DBT["Consensus and Debate (Flash and Pro)"]
|
||||
AA["Analyst Agent<br/>(Flash)"]
|
||||
AV["Auditor Agent<br/>(Pro)"]
|
||||
MCP[["MCP Grounding<br/>(Search)"]]
|
||||
DBT["Consensus and Debate<br/>(Flash and Pro)"]
|
||||
end
|
||||
|
||||
AC -->|"Raw Discovery"| AA
|
||||
@@ -743,6 +910,7 @@ The following matrix defines our strategic model tiering across all workflows:
|
||||
| **PR Guardian** | PR Presubmit | **Gemini Flash/Lite** | Tier 1 | Rapid syntax and mandate format linting. | **Medium** |
|
||||
| **Curator (X/RSS)** | Agentic Curator | **Gemini Pro** | Tier 2 | Deep reasoning for human/social context. | **Low (Burst)** |
|
||||
| **Auditor** | V2 Elite Builder | **Gemini Pro** | Tier 2 | High-fidelity verification of [ELITE] resources. | **Medium** |
|
||||
| **Fast-Pass Evaluator** | Curation / V2 Builder | **Gemini Flash/Lite** | Tier 1 | Rapid single-call screening for obvious consensus/non-consensus. | **High** |
|
||||
| **Debater Personas** | Curation / V2 Builder | **Gemini Flash/Lite** | Tier 1 | Independent multi-perspective evaluations and rebuttals. | **High** |
|
||||
| **Debate Synthesis** | Curation / V2 Builder | **Gemini Pro** | Tier 2 | High-fidelity final consensus and summary synthesis. | **Medium** |
|
||||
|
||||
@@ -762,17 +930,22 @@ The heart of the new Nubenetes is a suite of AI Agents that operate on our `deve
|
||||
- **Elite Selection:** Scans the massive V1 archive to select the "Elite" top-tier resources.
|
||||
- **2026 Taxonomy:** Reorganizes content into high-density dimensions using **relevance-first sorting**.
|
||||
- **MVQ Hardening:** Automatically identifies stale repositories to exclude them from the Elite portal.
|
||||
- **Tags Page Cap (Recommendation #5)**: Caps the technical tag listings in `tags.md` to 100 entries per tag block (sorted by stars/year) to prevent DOM bloat, providing fallback links to the V1 Historical Archive.
|
||||
3. **IntelligentHealthChecker ([`src/intelligent_health_checker.py`](src/intelligent_health_checker.py))**:
|
||||
- **Resilience:** asynchronous health checks with 3x retry and identity rotation.
|
||||
- **V1 Integrity:** Focuses on link validity (removing 404s) to ensure the exhaustive V1 archive remains accessible.
|
||||
- **Domain failure audits (Recommendation #2)**: Automatically logs consecutive connection failures per domain in `health_learning.json` and drops check timeouts from 12s to 3s when consecutive failures $\ge 3$ to avoid hanging.
|
||||
- **Transparency:** Provides detailed, real-time unbuffered logging of all cleaning operations.
|
||||
4. **DebatePanelEngine ([`src/v2_debate.py`](src/v2_debate.py))**:
|
||||
- **Persona-based Evaluation**: Coordinates specialized opinions across Security Architect, SRE, and AI Engineer personas.
|
||||
- **Fast-Pass screening (Recommendation #3)**: Runs a single Flash model call at start; clear-cut cases bypass the full panel debate immediately.
|
||||
- **Persona-based Evaluation**: Coordinates specialized expert opinions (Security Architect, SRE, and AI Engineer personas) for borderline cases (initial scores in `[60, 75]`).
|
||||
- **Consensus Resolution**: Resolves high score-divergences (>= 15 points) using a round-robin debate structure.
|
||||
- **Auto-Corrective Memory**: Appends resolution logs to `src/memory/health_learning.json` for persistent, few-shot alignment.
|
||||
5. **Resilient Architecture Core**:
|
||||
- **Exponential Backoff**: Intelligent `tenacity`-based retry logic in `gemini_utils.py` gracefully handles 429 Rate Limits before triggering the Circuit Breaker.
|
||||
- **Flash-First Architecture**: Prioritizes Gemini Flash/Lite models for high-density Analyst tasks, enabling processing of 10,000+ resources within the 6-hour GitHub Actions limit through 100-item batching and 2-second safety delays.
|
||||
- **Curation Ingestion Toggle**: Supports `ENABLE_TWITTER_CURATION` environment flag to dynamically toggle Playwright-based Twikit extraction when remote scraping blocks.
|
||||
- **Adaptive Timeout & UA Rotation**: Adapts request headers and reduces health check timeouts dynamically under network throttle/block conditions.
|
||||
- **Programmatic Smart Injection (Option B)**: The system extracts document headers and has Gemini Flash choose the target header, performing the actual line insertion using Python. This bypasses the need for Gemini Pro to rewrite entire documents, slashing API usage and preventing 429 errors.
|
||||
- **Incremental Persistence (Mandate 22)**: Implements a dual-phase auto-save mechanism that flushes the `inventory.yaml` database to disk periodically **without waiting for the workflow to finish**:
|
||||
* **Metadata Phase**: Saves every **500 GitHub repositories** processed.
|
||||
@@ -788,17 +961,20 @@ To eliminate individual LLM rating bias, resolve borderline cases, and prevent a
|
||||
|
||||
```mermaid
|
||||
graph TD
|
||||
A["New Resource Found"] --> B["Persona 1: Security Architect"]
|
||||
A --> C["Persona 2: Cloud Native SRE"]
|
||||
A --> D["Persona 3: AI Platform Engineer"]
|
||||
B --> E["Independent Evaluations"]
|
||||
A["New Resource Found"] --> FP["Fast-Pass Evaluator<br/>(Flash)"]
|
||||
FP -->|Confident Score Outside 60-75| G["Accept /<br/>Reject Directly"]
|
||||
FP -->|Borderline Score 60-75| B["Persona 1:<br/>Security Architect"]
|
||||
FP -->|Borderline Score 60-75| C["Persona 2:<br/>Cloud Native SRE"]
|
||||
FP -->|Borderline Score 60-75| D["Persona 3:<br/>AI Platform Engineer"]
|
||||
B --> E["Independent Expert<br/>Evaluations"]
|
||||
C --> E
|
||||
D --> E
|
||||
E -->|Scores Diverge >= 15 points| F["Trigger Debate Round"]
|
||||
E -->|Scores Converge| G["Accept / Reject Directly"]
|
||||
F --> H["Round-Robin Discussion: Argue Pros and Cons"]
|
||||
H --> I["Consensus Reached and Final Score Assigned"]
|
||||
I --> J["Save Decision to Persistent Memory JSON"]
|
||||
E -->|Expert Scores Diverge >= 15 points| F["Trigger<br/>Debate Round"]
|
||||
E -->|Expert Scores Converge| G
|
||||
F --> H["Round-Robin Discussion:<br/>Argue Pros and Cons"]
|
||||
H --> I["Consensus Reached and<br/>Final Score Assigned"]
|
||||
I --> J["Save Decision to<br/>Persistent Memory JSON"]
|
||||
G --> J
|
||||
```
|
||||
|
||||
#### 8.3.1. Panel of Expert Personas
|
||||
@@ -808,14 +984,15 @@ The panel consists of three distinct virtual expert roles, each prompting Gemini
|
||||
* **AI Platform Engineer**: Judges developer productivity, ease of integration with the modern AI stack (e.g., Model Context Protocol (MCP) tools), and overall 2026 Cloud Native architectural relevance.
|
||||
|
||||
#### 8.3.2. Protocol Execution Flow
|
||||
The debate protocol executes asynchronously in three distinct phases:
|
||||
1. **Phase 1: Independent Evaluation**: Each expert persona independently evaluates the resource (using Google Search Grounding to check the live state of the project). They assign an architectural impact score (0–100) and write a 1–2 sentence justification.
|
||||
2. **Phase 2: Divergence Assessment and Rebuttal**: If the difference between the highest and lowest assigned scores is **$\ge 15$ points**, a debate round is triggered. Each expert receives the scores and justifications of their peers and is asked to defend or revise their score in a rebuttal round.
|
||||
3. **Phase 3: Consensus and Synthesis**: The final consensus score is the average of the revised scores of the three personas. A fourth agent (Curation Synthesis Agent) compiles the justifications and rebuttals, generating a refined, high-density technical summary (2–5 sentences) and selecting precise ecosystem tags (e.g., `[DE FACTO STANDARD]`, `[ENTERPRISE-STABLE]`, `[EMERGING]`).
|
||||
The debate protocol executes in the following phases:
|
||||
1. **Fast-Pass Screening**: A single-call evaluator rates the resource. If the rating is highly confident (score $\le 59$ or $\ge 76$), it bypasses the expert panel entirely.
|
||||
2. **Expert Evaluation (Borderline Cases)**: If the screening rating is borderline (`[60, 75]`), the three expert personas (Security, SRE, and AI/Developer DX) independently evaluate the resource (using Google Search Grounding to check the live state of the project). They assign an architectural impact score (0–100) and write a 1–2 sentence justification.
|
||||
3. **Divergence Assessment and Rebuttal**: If the difference between the highest and lowest assigned scores is **$\ge 15$ points**, a debate round is triggered. Each expert receives the scores and justifications of their peers and is asked to defend or revise their score in a rebuttal round.
|
||||
4. **Consensus and Synthesis**: The final consensus score is the average of the revised scores of the three personas. A curation synthesis agent compiles the justifications and rebuttals, generating a refined, high-density technical summary (2–5 sentences) and selecting precise ecosystem tags (e.g., `[DE FACTO STANDARD]`, `[ENTERPRISE-STABLE]`, `[EMERGING]`).
|
||||
|
||||
#### 8.3.3. Integration Points
|
||||
* **Discovery Ingestion**: Hooked into [`src/agentic_curator.py`](src/agentic_curator.py) for new links with borderline initial scores between `70` and `85`.
|
||||
* **V2 Portal Auditing**: Hooked into [`src/v2_optimizer.py`](src/v2_optimizer.py) during builds for high-impact candidates (`[DE FACTO STANDARD]`, `[ENTERPRISE-STABLE]`) or borderline candidates (3–4 stars).
|
||||
* **Discovery Ingestion**: Hooked into [`src/agentic_curator.py`](src/agentic_curator.py) for new links with borderline initial scores.
|
||||
* **V2 Portal Auditing**: Hooked into [`src/v2_optimizer.py`](src/v2_optimizer.py) during builds for high-impact candidates or borderline candidates.
|
||||
* **Persistent Memory Log**: The final consensus score, justifications, rebuttals, and metadata are saved to `src/memory/health_learning.json` under `resolved_debates` to serve as few-shot training examples for future curation runs.
|
||||
|
||||
---
|
||||
@@ -987,11 +1164,10 @@ graph LR
|
||||
B --> D["V2 Vision Engine"]
|
||||
B --> Z["README Sync"]
|
||||
D --> E["V2 Update (develop)"]
|
||||
M["Sync to 'master'"] --> C["Pip Cache & CI/CD Build"]
|
||||
M["Sync to 'master'"] --> C["Pip Cache and<br/>CI/CD Build"]
|
||||
C --> F["Upload Pages Artifact"]
|
||||
F --> G["Native Deploy: V1 (Root/SEO), V2 (/v2/), V1 Fallback (/v1/)"]
|
||||
G --> H["Inject Root Redirect to /v2/"]
|
||||
Z --> B
|
||||
F --> G["Native Deploy:<br/>V1 (Root/SEO) · V2 (/v2/)<br/>· V1 Fallback (/v1/)"]
|
||||
G --> H["Inject Root<br/>Redirect to /v2/"]
|
||||
Z --> B
|
||||
```
|
||||
|
||||
@@ -1142,7 +1318,11 @@ To maintain transparency and ease of navigation, all key configuration, database
|
||||
- **Health Check Logic:** [`src/intelligent_health_checker.py`](src/intelligent_health_checker.py) - Link rot prevention and canonical updates.
|
||||
- **Twikit Ingestion:** [`src/ingestion_twikit.py`](src/ingestion_twikit.py) - X.com scraping and account rotation logic.
|
||||
- **Backup Ingestion:** [`src/ingestion_backup.py`](src/ingestion_backup.py) - Manual and historical JSON data processing.
|
||||
- **Discovery Engine:** [`src/autonomous_discovery.py`](src/autonomous_discovery.py) - Multi-source technical news extraction.
|
||||
- **Discovery Engine:** [`src/autonomous_discovery.py`](src/autonomous_discovery.py) - Multi-source technical news extraction (14 GitHub search queries).
|
||||
- **News Digest Engine:** [`src/news_digest.py`](src/news_digest.py) - AI-powered temporal digest across 26 categories with Gemini ranking (3/6/12 months).
|
||||
- **Enrichment Pipeline:** [`src/enrichment.py`](src/enrichment.py) - CNCF Landscape integration, GitHub activity enrichment, and license change detection.
|
||||
- **Deduplication Engine:** [`src/dedup.py`](src/dedup.py) - URL normalization, content-hash, and title-similarity dedup (85% threshold).
|
||||
- **Backfill Utility:** [`scripts/backfill_discovered_at.py`](scripts/backfill_discovered_at.py) - One-shot `discovered_at` population for existing entries.
|
||||
- **Gemini Utils:** [`src/gemini_utils.py`](src/gemini_utils.py) - AI model discovery, rate limiting, and session tracking.
|
||||
- **Markdown Logic:** [`src/markdown_ast.py`](src/markdown_ast.py) - Sophisticated parsing of repository content.
|
||||
- **Observability:** [`src/logger.py`](src/logger.py) | [`src/report_generator.py`](src/report_generator.py) - Execution transparency and visual reporting.
|
||||
|
||||
@@ -231,7 +231,7 @@ These are the core tools and frameworks that have been or are significant in my
|
||||
</details>
|
||||
</details>
|
||||
|
||||
---
|
||||
----
|
||||
<center markdown="1">
|
||||
|
||||
[](https://probably.co.uk/posts/migrating-the-runbook-a-journey-from-legacy-to-devops)
|
||||
|
||||
@@ -14,6 +14,8 @@ Resources, tools, and projects related to autonomous AI agents, Model Context Pr
|
||||
- [modelcontextprotocol.io: MCP Official Documentation](https://modelcontextprotocol.io/docs/getting-started/intro)
|
||||
|
||||
## AI Agents
|
||||
- **(2026)** [antigravity.google: Google Antigravity Agentic Platform](https://antigravity.google) 🌟 - Google's unified development platform for building, evaluating, and deploying stateful AI agents, integrating with the Gemini Enterprise Agent Platform and Google Kubernetes Engine (GKE) for production runtimes.
|
||||
- **(2025)** [docs.anthropic.com: Claude Code CLI](https://docs.anthropic.com/en/docs/agents-and-tools/claude-code/overview) 🌟 - Anthropic's agentic command-line interface (CLI) tool designed to assist with software development, offering capabilities to read codebases, execute shell commands, edit files, run tests, and manage Git workflows directly from the terminal.
|
||||
- [IBM IAM for AI Agents](https://t.co/EKsVgKA4xn) -how IBM Identity and Access Management (IAM) provides native IAM for AI agents, enabling them to have an identity and deliver least privileged access.
|
||||
- [Level Up Your Agents: Announcing Google's Official Skills Repository](https://cloud.google.com/blog/topics/developers-practitioners/level-up-your-agents-announcing-googles-official-skills-repository) 🌟 - This blog post announces the launch of Google's official Agent Skills repository on GitHub, designed to equip AI agents with condensed expertise on specific technologies and tasks. Skills are presented in an open Markdown format, including reference files and code snippets, to provide agent-first documentation. This approach aims to reduce 'context bloat' often encountered when using Model Context Protocol (MCP) servers, leading to more efficient and cost-effective AI agent interactions with Google Cloud products like Gemini API, BigQuery, and GKE.
|
||||
- [Claude Code Best Practice](https://github.com/shanraisshan/claude-code-best-practice) - A GitHub repository focused on 'vibe coding to agentic engineering', providing practices and examples for interacting with AI models like Claude. It includes sections on agents, commands, skills, development workflows, and implementation details.
|
||||
|
||||
@@ -97,6 +97,7 @@
|
||||
- [IDE extension for AWS Application Composer enhances visual modern applications development with AI-generated IaC](https://aws.amazon.com/blogs/aws/ide-extension-for-aws-application-composer-enhances-visual-modern-applications-development-with-ai-generated-iac)
|
||||
|
||||
## Programming
|
||||
- **(2025)** [cursor.com: Cursor AI Code Editor](https://cursor.com) 🌟 - The premier AI-first code editor, built as a fork of VS Code, offering features like Cursor Tab (smart autocomplete), Cmd+K (inline edits), Composer (multi-file agentic code generation), and deep codebase indexing.
|
||||
- [Tech companies cutting devs for AI](https://www.reddit.com/r/ProgrammerHumor/comments/1tbzih8/techcompaniescuttingdevsforai) - A Reddit post from r/ProgrammerHumor discussing the trend of tech companies reducing their developer workforce in favor of AI.
|
||||
- [Extend your coding agent with .NET Skills](https://devblogs.microsoft.com/dotnet/extend-your-coding-agent-with-dotnet-skills) 🌟 - This blog post introduces the dotnet/skills repository, a collection of agent skills designed to enhance coding agents for .NET developers. These skills provide specialized knowledge and context that coding agents can discover and utilize, improving their ability to solve tasks with less trial and error. The post explains the concept of agent skills and their adherence to the Agent Skills specification, which is supported by various coding agents like GitHub Copilot CLI, Visual Studio, and VS Code.
|
||||
- [Best Practices for Using GitHub Copilot](https://docs.github.com/en/copilot/get-started/best-practices) 🌟 - A guide detailing the strengths, weaknesses, and optimal usage scenarios for GitHub Copilot, differentiating between inline suggestions and Copilot Chat for various coding tasks, including writing tests, debugging, code generation, and explanation.
|
||||
|
||||
@@ -114,6 +114,7 @@
|
||||
- https://aws.amazon.com/whitepapers
|
||||
- https://docs.aws.amazon.com
|
||||
- https://www.aws.training
|
||||
- [skillbuilder.aws: AWS Skill Builder](https://skillbuilder.aws) - AWS's official digital learning center with free and paid courses, hands-on labs, and learning paths for cloud certifications
|
||||
- https://aws.amazon.com/solutions/case-studies
|
||||
- https://www.youtube.com/user/amazonWebServices
|
||||
- https://repost.aws
|
||||
|
||||
@@ -583,6 +583,7 @@ git rebase -i HEAD~5
|
||||
- [github.com/giscus/giscus](https://github.com/giscus/giscus) A comments system powered by [GitHub Discussions](https://docs.github.com/en/discussions). Let visitors leave comments and reactions on your website via GitHub! Heavily inspired by [utterances](https://github.com/utterance/utterances).
|
||||
|
||||
### GitHub Actions
|
||||
- **(2025)** [github.blog: Continuous Delivery with GitHub Actions](https://github.blog/enterprise-software/ci-cd/continuous-delivery-github-actions-best-practices) 🌟 - Enterprise-level guidelines and best practices for scaling continuous delivery workflows safely and securely using GitHub Actions.
|
||||
- [Gama: Terminal UI for GitHub Actions](https://github.com/termkit/gama) - *(Related to cicd topic)*
|
||||
|
||||
- [github.blog: Testing cloud apps with GitHub Actions and cloud-native open source tools](https://github.blog/enterprise-software/devops/devops-cloud-testing)
|
||||
@@ -643,6 +644,8 @@ git rebase -i HEAD~5
|
||||
|
||||
### GitHub Copilot
|
||||
|
||||
- **(2025)** [githubnext.com: GitHub Copilot Workspace](https://githubnext.com/projects/copilot-workspace) 🌟 - A collaborative, agentic developer environment by GitHub Next that enables engineers to brainstorm, plan, and build software features using autonomous AI agents.
|
||||
- **(2025)** [learn.microsoft.com: Use Agent Mode in GitHub Copilot](https://learn.microsoft.com/en-us/visualstudio/ide/copilot-agent-mode) 🌟 - Official documentation detailing the usage of Copilot's Agent Mode inside modern IDE environments to automate multi-file refactoring and codebase investigations.
|
||||
- [GitHub Copilot 🌟](https://github.com/copilot) Your AI pair programmer. With GitHub Copilot, get suggestions for whole lines or entire functions right inside your editor.
|
||||
- [hipertextual.com: GitHub une fuerzas con OpenIA para crear una inteligencia artificial capaz de autocompletar código](https://hipertextual.com/2021/06/github-inteligencia-artificial-autocompletar-codigo) GitHub Copilot funciona con la inteligencia artificial de OpenAI. La herramienta busca mejorar el aprendizaje de lenguajes de programación.
|
||||
- [xataka.com: Para qué programar cuando una máquina lo hace (un poco) por ti: así es Github Copilot, un sistema que se nutre del prodigioso GPT-3](https://www.xataka.com/robotica-e-ia/programar-cuando-maquina-hace-poco-ti-asi-github-copilot-sistema-que-se-nutre-prodigioso-gpt-3)
|
||||
|
||||
@@ -0,0 +1 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" height="64" viewBox="0 0 32 32" width="64"><path d="M19.62 11.558l-3.203 2.98-2.972-5.995 1.538-3.448c.4-.7 1.024-.692 1.414 0z" fill="#ffa000"/><path d="M13.445 8.543l2.972 5.995-11.97 11.135z" fill="#f57f17"/><path d="M23.123 7.003c.572-.55 1.164-.362 1.315.417l3.116 18.105-10.328 6.2c-.36.2-1.32.286-1.32.286s-.874-.104-1.207-.3L4.447 25.673z" fill="#ffca28"/><path d="M13.445 8.543l-8.997 17.13L8.455.638c.148-.78.592-.855.988-.167z" fill="#ffa000"/></svg>
|
||||
|
After Width: | Height: | Size: 501 B |
|
After Width: | Height: | Size: 551 B |
|
After Width: | Height: | Size: 8.2 KiB |
|
After Width: | Height: | Size: 1.8 KiB |
|
After Width: | Height: | Size: 6.7 KiB |
|
After Width: | Height: | Size: 462 B |
@@ -0,0 +1,99 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<svg
|
||||
xmlns:dc="http://purl.org/dc/elements/1.1/"
|
||||
xmlns:cc="http://creativecommons.org/ns#"
|
||||
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
|
||||
xmlns:svg="http://www.w3.org/2000/svg"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
||||
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
||||
width="64"
|
||||
height="64"
|
||||
viewBox="0 0 64 64"
|
||||
version="1.1"
|
||||
id="svg20"
|
||||
sodipodi:docname="supabase-icon.svg"
|
||||
style="fill:none"
|
||||
inkscape:version="0.92.4 (5da689c313, 2019-01-14)">
|
||||
<metadata
|
||||
id="metadata24">
|
||||
<rdf:RDF>
|
||||
<cc:Work
|
||||
rdf:about="">
|
||||
<dc:format>image/svg+xml</dc:format>
|
||||
<dc:type
|
||||
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
|
||||
<dc:title></dc:title>
|
||||
</cc:Work>
|
||||
</rdf:RDF>
|
||||
</metadata>
|
||||
<sodipodi:namedview
|
||||
pagecolor="#ffffff"
|
||||
bordercolor="#666666"
|
||||
borderopacity="1"
|
||||
objecttolerance="10"
|
||||
gridtolerance="10"
|
||||
guidetolerance="10"
|
||||
inkscape:pageopacity="0"
|
||||
inkscape:pageshadow="2"
|
||||
inkscape:window-width="1687"
|
||||
inkscape:window-height="849"
|
||||
id="namedview22"
|
||||
showgrid="false"
|
||||
inkscape:zoom="2.0884956"
|
||||
inkscape:cx="54.5"
|
||||
inkscape:cy="56.5"
|
||||
inkscape:window-x="70"
|
||||
inkscape:window-y="0"
|
||||
inkscape:window-maximized="0"
|
||||
inkscape:current-layer="svg20" />
|
||||
<path
|
||||
d="m 37.41219,62.936701 c -1.634985,2.05896 -4.950068,0.93085 -4.989463,-1.69817 L 31.846665,22.786035 h 25.855406 c 4.683108,0 7.294967,5.409033 4.382927,9.07673 z"
|
||||
id="path2"
|
||||
style="fill:url(#paint0_linear);stroke-width:0.57177335"
|
||||
inkscape:connector-curvature="0" />
|
||||
<path
|
||||
d="m 37.41219,62.936701 c -1.634985,2.05896 -4.950068,0.93085 -4.989463,-1.69817 L 31.846665,22.786035 h 25.855406 c 4.683108,0 7.294967,5.409033 4.382927,9.07673 z"
|
||||
id="path4"
|
||||
style="fill:url(#paint1_linear);fill-opacity:0.2;stroke-width:0.57177335"
|
||||
inkscape:connector-curvature="0" />
|
||||
<path
|
||||
d="m 26.89694,1.0634102 c 1.634986,-2.05918508 4.950125,-0.93090008 4.989521,1.698149 L 32.138899,41.214003 H 6.607076 c -4.6832501,0 -7.29518376,-5.409032 -4.3830007,-9.07673 z"
|
||||
id="path6"
|
||||
inkscape:connector-curvature="0"
|
||||
style="fill:#3ecf8e;stroke-width:0.57177335" />
|
||||
<defs
|
||||
id="defs18">
|
||||
<linearGradient
|
||||
id="paint0_linear"
|
||||
x1="53.973801"
|
||||
y1="54.973999"
|
||||
x2="94.163498"
|
||||
y2="71.829498"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
gradientTransform="matrix(0.57177306,0,0,0.57177334,0.98590077,-0.12074988)">
|
||||
<stop
|
||||
stop-color="#249361"
|
||||
id="stop8" />
|
||||
<stop
|
||||
offset="1"
|
||||
stop-color="#3ECF8E"
|
||||
id="stop10" />
|
||||
</linearGradient>
|
||||
<linearGradient
|
||||
id="paint1_linear"
|
||||
x1="36.1558"
|
||||
y1="30.577999"
|
||||
x2="54.484402"
|
||||
y2="65.080597"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
gradientTransform="matrix(0.57177306,0,0,0.57177334,0.98590077,-0.12074988)">
|
||||
<stop
|
||||
id="stop13" />
|
||||
<stop
|
||||
offset="1"
|
||||
stop-opacity="0"
|
||||
id="stop15" />
|
||||
</linearGradient>
|
||||
</defs>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 3.2 KiB |
|
After Width: | Height: | Size: 979 B |
@@ -352,7 +352,8 @@ A curated list of awesome references collected since 2018. Microservices archite
|
||||
[{: style="width:7%"}](https://www.youtube.com/c/ContinuousDeliveryFoundation) [{: style="width:7%"}](https://www.youtube.com/c/TinaHuang1) [{: style="width:7%"}](https://www.youtube.com/c/AzureDevOps) [{: style="width:7%"}](https://www.youtube.com/channel/UC2Pk9GcHhlVV0R9CQIU6gLw) [{: style="width:7%"}](https://www.youtube.com/c/AlibabaCloud) [{: style="width:7%"}](https://www.youtube.com/c/linode) [{: style="width:7%"}](https://www.youtube.com/channel/UCB5WMc2FfrxKzfd7XIODoMw) [{: style="width:7%"}](https://www.youtube.com/c/MadeByGPS) [{: style="width:7%"}](https://www.youtube.com/c/keptn) [{: style="width:7%"}](https://www.youtube.com/c/AnaisUrlichs) [{: style="width:7%"}](https://www.youtube.com/c/TheDigitalLifeTech)<br/>
|
||||
[{: style="width:7%"}](https://www.youtube.com/@azure-terraformer) [{: style="width:7%"}](https://www.youtube.com/@NedintheCloud) [{: style="width:7%"}](https://www.youtube.com/@NetBoxLabs) [{: style="width:7%"}](https://www.youtube.com/@techwithhelen) [{: style="width:7%"}](https://www.youtube.com/@ByteByteGo) [{: style="width:7%"}](https://www.youtube.com/@DotCSV) [{: style="width:7%"}](https://www.youtube.com/@midulive) [{: style="width:7%"}](https://www.youtube.com/@returngis) [{: style="width:7%"}](https://www.youtube.com/@kubefm) [{: style="width:7%"}](https://www.youtube.com/@OlenaKutsenko) [{: style="width:7%"}](https://www.youtube.com/@mouredev)<br/>
|
||||
[{: style="width:7%"}](https://www.youtube.com/@CloudNativeMadrid) [{: style="width:7%"}](https://www.youtube.com/@kyndryl) [{: style="width:7%"}](https://www.youtube.com/@ITOpsTalk) [{: style="width:7%"}](https://www.youtube.com/@googlecloudtech) [{: style="width:7%"}](https://www.youtube.com/@GoogleGemini) [{: style="width:7%"}](https://www.youtube.com/@googledeepmind) [{: style="width:7%"}](https://www.youtube.com/@anthropic-ai) [{: style="width:7%"}](https://www.youtube.com/@Microsoft.Copilot) [{: style="width:7%"}](https://www.youtube.com/OpenAI) [{: style="width:7%"}](https://www.youtube.com/@aiatmeta) [{: style="width:7%"}](https://www.youtube.com/@MicrosoftReactor)<br/>
|
||||
[{: style="width:7%"}](https://www.youtube.com/@Playwrightdev) [{: style="width:7%"}](https://www.youtube.com/@arsys) [{: style="width:7%"}](https://www.youtube.com/@ClickHouseDB) [{: style="width:7%"}](https://www.youtube.com/@gustavo-entrala)
|
||||
[{: style="width:7%"}](https://www.youtube.com/@Playwrightdev) [{: style="width:7%"}](https://www.youtube.com/@arsys) [{: style="width:7%"}](https://www.youtube.com/@ClickHouseDB) [{: style="width:7%"}](https://www.youtube.com/@gustavo-entrala) [{: style="width:7%"}](https://www.youtube.com/@Firebase) [{: style="width:7%"}](https://www.youtube.com/c/supabase) [{: style="width:7%"}](https://www.youtube.com/@IONOSUK) [{: style="width:7%"}](https://www.youtube.com/nutanix) [{: style="width:7%"}](https://www.youtube.com/vmware) [{: style="width:7%"}](https://www.youtube.com/ProxmoxVE) [{: style="width:7%"}](https://www.youtube.com/Salesforce)<br/>
|
||||
[{: style="width:7%"}](https://www.youtube.com/user/SAP)
|
||||
|
||||
</center>
|
||||
|
||||
|
||||
@@ -169,6 +169,7 @@
|
||||
- [analyticsvidhya.com: Bring DevOps To Data Science With MLOps](https://www.analyticsvidhya.com/blog/2021/04/bring-devops-to-data-science-with-continuous-mlops)
|
||||
- [analyticsindiamag.com: Is coding necessary to work as a data scientist?](https://analyticsindiamag.com/is-coding-necessary-to-work-as-a-data-scientist) Non-programmers with a no-coding background can have a glorious career in data science and programming, and coding knowledge is more like a skill and not a criterion.
|
||||
- [redhat.com: Introducing Red Hat OpenShift Data Science](https://www.redhat.com/en/blog/introducing-red-hat-openshift-data-science)
|
||||
- [redhat.com: Bring Your Own Knowledge - Automation Intelligent Assistant (RAG)](https://www.redhat.com/en/blog/bring-your-own-knowledge-automation-intelligent-assistant)
|
||||
- [towardsdatascience.com: From DevOps to MLOPS: Integrate Machine Learning Models using Jenkins and Docker](https://towardsdatascience.com/from-devops-to-mlops-integrate-machine-learning-models-using-jenkins-and-docker-79034dbedf1) How to automate data science code with Jenkins and Docker: MLOps = ML + DEV + OPS
|
||||
|
||||
## Machine Learning workloads in kubernetes using Nix and NVIDIA. Running NVIDIA GPUs on Kubernetes
|
||||
|
||||
@@ -0,0 +1,23 @@
|
||||
{% extends "main.html" %}
|
||||
|
||||
<!--
|
||||
Branded 404. The portal cares about deep-link stability (see CLAUDE.md URL
|
||||
policy), so a dead link lands on a helpful page with clear ways back rather
|
||||
than the theme's bare "404 - Not found". Shared by V1 and V2 (custom_dir is
|
||||
docs/overrides for both), so styling is self-contained and links are root-relative.
|
||||
-->
|
||||
{% block content %}
|
||||
<div style="text-align:center; max-width:42rem; margin:3rem auto; padding:0 1rem;">
|
||||
<p style="font-size:6rem; font-weight:700; line-height:1; margin:0; opacity:0.15;">404</p>
|
||||
<h1 style="margin-top:0.5rem;">This page took a wrong turn</h1>
|
||||
<p style="font-size:0.9rem; opacity:0.8;">
|
||||
The resource you are looking for may have moved or never existed. Use the
|
||||
search at the top, or jump back to a known starting point below.
|
||||
</p>
|
||||
<div style="display:flex; gap:0.75rem; justify-content:center; flex-wrap:wrap; margin-top:1.5rem;">
|
||||
<a href="/" class="md-button md-button--primary">🏠 Home</a>
|
||||
<a href="/topic-map/" class="md-button">🗺️ Topic Map</a>
|
||||
<a href="/v1/" class="md-button">📚 V1 Archive</a>
|
||||
</div>
|
||||
</div>
|
||||
{% endblock %}
|
||||
@@ -0,0 +1,299 @@
|
||||
{% extends "base.html" %}
|
||||
|
||||
{% block announce %}
|
||||
<strong>New:</strong> <a href="./tech-digest/">Intelligence Digest</a> — AI-curated trending resources across 26 categories
|
||||
{% endblock %}
|
||||
|
||||
{#-
|
||||
Quick-nav bar rendered below the header on every page (via the `tabs` block,
|
||||
which is empty here since navigation.tabs is disabled). Single slim row that
|
||||
stays one row no matter how many destinations are added: the most-used
|
||||
flagships are direct one-click pills, and the long-tail clusters collapse into
|
||||
category menus built with the native HTML Popover API + CSS Anchor Positioning
|
||||
(Baseline 2026) — zero JS, with free Esc/click-outside dismissal and focus
|
||||
management. Adding a leaf grows a menu, never the bar.
|
||||
|
||||
Fully category-grouped into 13 thematic dropdowns (no direct pills).
|
||||
Related topics live together (CI/CD · GitOps · DevOps in Delivery; Terraform ·
|
||||
IaC in IaC; Docker in Kubernetes; …). AWS is a NESTED submenu inside Cloud,
|
||||
OpenShift a NESTED submenu inside Kubernetes.
|
||||
Pages may appear in more than one menu when that aids discovery.
|
||||
Portal Guide (Topic Map · Methodology · Tags · About) · Digest · Videos
|
||||
· Kubernetes (+Docker, OpenShift▸) · Delivery (CI/CD·GitOps·DevOps) · IaC
|
||||
· Cloud (AWS▸ · Azure · GCP · …) · Network · Security · Observability & SRE
|
||||
· AI & Data · Dev & Platform · More
|
||||
-#}
|
||||
{% block tabs %}
|
||||
<nav class="nb-quicknav" aria-label="Quick navigation">
|
||||
<div class="nb-quicknav__inner">
|
||||
<span class="nb-quicknav__group">
|
||||
<button class="nb-quicknav__link nb-quicknav__btn" popovertarget="nb-pop-guide" type="button">🧭 Portal Guide <span class="nb-quicknav__caret" aria-hidden="true">▾</span></button>
|
||||
<div class="nb-quicknav__menu" id="nb-pop-guide" popover>
|
||||
<a href="/topic-map/">🗺️ Topic Map</a>
|
||||
<a href="/methodology/">📐 Methodology</a>
|
||||
<a href="/tags/">🏷️ Technical Tags</a>
|
||||
<a href="/about/">ℹ️ About</a>
|
||||
</div>
|
||||
</span>
|
||||
|
||||
<span class="nb-quicknav__group">
|
||||
<button class="nb-quicknav__link nb-quicknav__btn" popovertarget="nb-pop-digest" type="button">📊 Digest <span class="nb-quicknav__caret" aria-hidden="true">▾</span></button>
|
||||
<div class="nb-quicknav__menu" id="nb-pop-digest" popover>
|
||||
<a href="/tech-digest/">📊 Tech & Cloud Digest</a>
|
||||
<a href="/industry-digest/">🌍 Industry & Geo Digest</a>
|
||||
</div>
|
||||
</span>
|
||||
|
||||
<span class="nb-quicknav__group">
|
||||
<button class="nb-quicknav__link nb-quicknav__btn" popovertarget="nb-pop-videos" type="button">🎥 Videos <span class="nb-quicknav__caret" aria-hidden="true">▾</span></button>
|
||||
<div class="nb-quicknav__menu" id="nb-pop-videos" popover>
|
||||
<a href="/videos/">🎥 Video Hub</a>
|
||||
<a href="/videos/ai-agents/">🤖 AI Agents & MCP</a>
|
||||
<a href="/videos/devops-iac/">♾️ DevOps, IaC & SRE</a>
|
||||
<a href="/videos/cloud-native/">☸️ Cloud Native Core</a>
|
||||
<a href="/videos/fundamentals/">🎓 Fundamentals</a>
|
||||
</div>
|
||||
</span>
|
||||
|
||||
<span class="nb-quicknav__group">
|
||||
<button class="nb-quicknav__link nb-quicknav__btn" popovertarget="nb-pop-k8s" type="button">☸️ Kubernetes <span class="nb-quicknav__caret" aria-hidden="true">▾</span></button>
|
||||
<div class="nb-quicknav__menu nb-quicknav__menu--cols" id="nb-pop-k8s" popover>
|
||||
<a href="/kubernetes/">☸️ Overview</a>
|
||||
<a href="/docker/">🐳 Docker</a>
|
||||
<a href="/kubernetes-tools/">🧰 Tools</a>
|
||||
<a href="/helm/">📦 Helm</a>
|
||||
<a href="/kubectl-commands/">⌨️ kubectl</a>
|
||||
<a href="/container-managers/">📦 Container Managers</a>
|
||||
<a href="/kubernetes-networking/">🌐 Networking</a>
|
||||
<a href="/kubernetes-security/">🔐 Security</a>
|
||||
<a href="/kubernetes-monitoring/">📈 Monitoring</a>
|
||||
<a href="/kubernetes-storage/">💾 Storage</a>
|
||||
<a href="/kubernetes-autoscaling/">⚖️ Autoscaling</a>
|
||||
<a href="/kubernetes-operators-controllers/">🎛️ Operators</a>
|
||||
<a href="/kubernetes-bigdata/">📊 Big Data</a>
|
||||
<a href="/kubernetes-tutorials/">🎓 Tutorials</a>
|
||||
<a href="/kubernetes-backup-migrations/">🗄️ Backup & Migrations</a>
|
||||
<a href="/kubernetes-client-libraries/">📚 Client Libraries</a>
|
||||
<a href="/kubernetes-based-devel/">💻 Local Dev</a>
|
||||
<a href="/kubernetes-on-premise/">🏢 On-Premise</a>
|
||||
<a href="/managed-kubernetes-in-public-cloud/">☁️ Managed K8s</a>
|
||||
<span class="nb-quicknav__subwrap">
|
||||
<button class="nb-quicknav__subtrigger" popovertarget="nb-pop-ocp" type="button"><span>🎩 OpenShift</span><span class="nb-quicknav__caret" aria-hidden="true">▸</span></button>
|
||||
<div class="nb-quicknav__menu nb-quicknav__submenu" id="nb-pop-ocp" popover>
|
||||
<a href="/ocp4/">🎩 OpenShift 4 (current)</a>
|
||||
<a href="/openshift/">🎩 Overview</a>
|
||||
<a href="/ocp3/">🎩 OpenShift 3 (legacy)</a>
|
||||
</div>
|
||||
</span>
|
||||
<a href="/rancher/">🐮 Rancher</a>
|
||||
<a href="/kubernetes-alternatives/">🔀 Distros & Alternatives</a>
|
||||
</div>
|
||||
</span>
|
||||
|
||||
<span class="nb-quicknav__group">
|
||||
<button class="nb-quicknav__link nb-quicknav__btn" popovertarget="nb-pop-delivery" type="button">🔄 Delivery <span class="nb-quicknav__caret" aria-hidden="true">▾</span></button>
|
||||
<div class="nb-quicknav__menu" id="nb-pop-delivery" popover>
|
||||
<a href="/gitops/">🔄 GitOps</a>
|
||||
<a href="/cicd/">🚀 CI/CD</a>
|
||||
<a href="/devops/">♾️ DevOps</a>
|
||||
<a href="/argo/">🐙 Argo</a>
|
||||
<a href="/flux/">🔱 Flux</a>
|
||||
<a href="/tekton/">🛠️ Tekton</a>
|
||||
<a href="/jenkins/">🤵 Jenkins</a>
|
||||
<a href="/registries/">📦 Registries</a>
|
||||
<a href="/sonarqube/">🔎 SonarQube</a>
|
||||
<a href="/keptn/">🎯 Keptn</a>
|
||||
</div>
|
||||
</span>
|
||||
|
||||
<span class="nb-quicknav__group">
|
||||
<button class="nb-quicknav__link nb-quicknav__btn" popovertarget="nb-pop-iac" type="button">🏗️ IaC <span class="nb-quicknav__caret" aria-hidden="true">▾</span></button>
|
||||
<div class="nb-quicknav__menu" id="nb-pop-iac" popover>
|
||||
<a href="/terraform/">🏗️ Terraform</a>
|
||||
<a href="/iac/">📜 IaC</a>
|
||||
<a href="/ansible/">📋 Ansible</a>
|
||||
<a href="/pulumi/">🧩 Pulumi</a>
|
||||
<a href="/crossplane/">✈️ Crossplane</a>
|
||||
<a href="/kustomize/">🧱 Kustomize</a>
|
||||
</div>
|
||||
</span>
|
||||
|
||||
<span class="nb-quicknav__group">
|
||||
<button class="nb-quicknav__link nb-quicknav__btn" popovertarget="nb-pop-cloud" type="button">☁️ Cloud <span class="nb-quicknav__caret" aria-hidden="true">▾</span></button>
|
||||
<div class="nb-quicknav__menu" id="nb-pop-cloud" popover>
|
||||
<span class="nb-quicknav__subwrap">
|
||||
<button class="nb-quicknav__subtrigger" popovertarget="nb-pop-aws" type="button"><span>☁️ AWS</span><span class="nb-quicknav__caret" aria-hidden="true">▸</span></button>
|
||||
<div class="nb-quicknav__menu nb-quicknav__submenu" id="nb-pop-aws" popover>
|
||||
<a href="/aws/">☁️ AWS Overview</a>
|
||||
<a href="/aws-serverless/">⚡ Serverless</a>
|
||||
<a href="/aws-storage/">💾 Storage</a>
|
||||
<a href="/aws-networking/">🌐 Networking</a>
|
||||
<a href="/aws-security/">🔐 Security</a>
|
||||
<a href="/aws-iac/">📜 IaC</a>
|
||||
<a href="/aws-backup/">🗄️ Backup</a>
|
||||
<a href="/aws-newfeatures/">🆕 New Features</a>
|
||||
</div>
|
||||
</span>
|
||||
<a href="/azure/">☁️ Azure</a>
|
||||
<a href="/GoogleCloudPlatform/">☁️ GCP</a>
|
||||
<a href="/serverless/">⚡ Serverless</a>
|
||||
<a href="/finops/">💰 FinOps</a>
|
||||
<a href="/edge-computing/">🌍 Edge</a>
|
||||
<a href="/digitalocean/">🌊 DigitalOcean</a>
|
||||
<a href="/oraclecloud/">🔴 Oracle</a>
|
||||
<a href="/ibm_cloud/">🔵 IBM Cloud</a>
|
||||
</div>
|
||||
</span>
|
||||
|
||||
<span class="nb-quicknav__group">
|
||||
<button class="nb-quicknav__link nb-quicknav__btn" popovertarget="nb-pop-net" type="button">🌐 Network <span class="nb-quicknav__caret" aria-hidden="true">▾</span></button>
|
||||
<div class="nb-quicknav__menu" id="nb-pop-net" popover>
|
||||
<a href="/networking/">🌐 Networking</a>
|
||||
<a href="/istio/">⛵ Istio</a>
|
||||
<a href="/servicemesh/">🕸️ Service Mesh</a>
|
||||
<a href="/kubernetes-networking/">🔗 K8s Net</a>
|
||||
<a href="/caching/">⚡ Caching</a>
|
||||
<a href="/web-servers/">🖥️ Web Servers</a>
|
||||
</div>
|
||||
</span>
|
||||
|
||||
<span class="nb-quicknav__group">
|
||||
<button class="nb-quicknav__link nb-quicknav__btn" popovertarget="nb-pop-sec" type="button">🔐 Security <span class="nb-quicknav__caret" aria-hidden="true">▾</span></button>
|
||||
<div class="nb-quicknav__menu" id="nb-pop-sec" popover>
|
||||
<a href="/kubernetes-security/">🔐 K8s Security</a>
|
||||
<a href="/devsecops/">🛡️ DevSecOps</a>
|
||||
<a href="/securityascode/">📜 Security as Code</a>
|
||||
<a href="/aws-security/">☁️ AWS Security</a>
|
||||
</div>
|
||||
</span>
|
||||
|
||||
<span class="nb-quicknav__group">
|
||||
<button class="nb-quicknav__link nb-quicknav__btn" popovertarget="nb-pop-obs" type="button">📈 Observability <span class="nb-quicknav__caret" aria-hidden="true">▾</span></button>
|
||||
<div class="nb-quicknav__menu" id="nb-pop-obs" popover>
|
||||
<a href="/monitoring/">📈 Observability</a>
|
||||
<a href="/prometheus/">🔥 Prometheus</a>
|
||||
<a href="/grafana/">📊 Grafana</a>
|
||||
<a href="/sre/">🛠️ SRE</a>
|
||||
<a href="/chaos-engineering/">🌪️ Chaos Engineering</a>
|
||||
<a href="/performance-testing-with-jenkins-and-jmeter/">⏱️ Performance Testing</a>
|
||||
<a href="/qa/">✅ QA</a>
|
||||
<a href="/test-automation-frameworks/">🤖 Test Automation</a>
|
||||
</div>
|
||||
</span>
|
||||
|
||||
<span class="nb-quicknav__group">
|
||||
<button class="nb-quicknav__link nb-quicknav__btn" popovertarget="nb-pop-aidata" type="button">🤖 AI & Data <span class="nb-quicknav__caret" aria-hidden="true">▾</span></button>
|
||||
<div class="nb-quicknav__menu" id="nb-pop-aidata" popover>
|
||||
<a href="/ai-agents-mcp/">🤖 AI & MCP</a>
|
||||
<a href="/mlops/">🧠 MLOps</a>
|
||||
<a href="/ai/">🤖 AI</a>
|
||||
<a href="/chatgpt/">💬 ChatGPT</a>
|
||||
<a href="/databases/">🗃️ Databases</a>
|
||||
<a href="/nosql/">🍃 NoSQL</a>
|
||||
<a href="/message-queue/">📨 Messaging</a>
|
||||
</div>
|
||||
</span>
|
||||
|
||||
<span class="nb-quicknav__group">
|
||||
<button class="nb-quicknav__link nb-quicknav__btn" popovertarget="nb-pop-dev" type="button">🧑💻 Dev <span class="nb-quicknav__caret" aria-hidden="true">▾</span></button>
|
||||
<div class="nb-quicknav__menu" id="nb-pop-dev" popover>
|
||||
<a href="/developerportals/">🏛️ Developer Portals</a>
|
||||
<a href="/python/">🐍 Python</a>
|
||||
<a href="/golang/">🐹 Go</a>
|
||||
<a href="/java_frameworks/">☕ Java</a>
|
||||
<a href="/javascript/">🟨 JavaScript</a>
|
||||
<a href="/dotnet/">🟣 .NET</a>
|
||||
<a href="/api/">🔌 API</a>
|
||||
<a href="/postman/">📮 Postman</a>
|
||||
</div>
|
||||
</span>
|
||||
|
||||
<span class="nb-quicknav__group">
|
||||
<button class="nb-quicknav__link nb-quicknav__btn" popovertarget="nb-pop-more" type="button">⋯ More <span class="nb-quicknav__caret" aria-hidden="true">▾</span></button>
|
||||
<div class="nb-quicknav__menu" id="nb-pop-more" popover>
|
||||
<a href="/demos/">🧪 Demos</a>
|
||||
<a href="/faq/">❓ FAQ</a>
|
||||
<a href="/recruitment/">💼 Career</a>
|
||||
<a class="nb-quicknav__menu-muted" href="/v1/">📚 V1 Archive</a>
|
||||
</div>
|
||||
</span>
|
||||
</div>
|
||||
</nav>
|
||||
{% endblock %}
|
||||
|
||||
{#-
|
||||
JSON-LD structured data (schema.org) for richer search results: declares the
|
||||
WebSite (with a sitelinks SearchAction) and the publishing Organization.
|
||||
Only the V2 portal uses this overrides dir (custom_dir: docs/overrides), so
|
||||
this injects on the canonical nubenetes.com root; V1 uses the stock theme.
|
||||
-#}
|
||||
{% block extrahead %}
|
||||
{{ super() }}
|
||||
<script type="application/ld+json">
|
||||
{
|
||||
"@context": "https://schema.org",
|
||||
"@graph": [
|
||||
{
|
||||
"@type": "WebSite",
|
||||
"@id": "https://nubenetes.com/#website",
|
||||
"url": "https://nubenetes.com/",
|
||||
"name": "Nubenetes",
|
||||
"description": "AI-curated portal for the modern Cloud Native ecosystem: high-density, ranked selection of top-tier Kubernetes, DevOps and Cloud resources.",
|
||||
"publisher": { "@id": "https://nubenetes.com/#organization" },
|
||||
"potentialAction": {
|
||||
"@type": "SearchAction",
|
||||
"target": {
|
||||
"@type": "EntryPoint",
|
||||
"urlTemplate": "https://nubenetes.com/?q={search_term_string}"
|
||||
},
|
||||
"query-input": "required name=search_term_string"
|
||||
}
|
||||
},
|
||||
{
|
||||
"@type": "Organization",
|
||||
"@id": "https://nubenetes.com/#organization",
|
||||
"name": "Nubenetes",
|
||||
"url": "https://nubenetes.com/",
|
||||
"logo": {
|
||||
"@type": "ImageObject",
|
||||
"url": "https://nubenetes.com/images/favicon-ultra.png"
|
||||
},
|
||||
"sameAs": [
|
||||
"https://github.com/nubenetes/awesome-kubernetes",
|
||||
"https://twitter.com/nubenetes",
|
||||
"https://www.linkedin.com/groups/1937212/"
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
</script>
|
||||
{#-
|
||||
Per-page structured data: a CollectionPage (each V2 page is a curated
|
||||
collection of resources) tied to the WebSite/Organization above, with
|
||||
datePublished / dateModified fed by the git-revision-date plugin. Enables
|
||||
richer search results. Skipped on the homepage (already the WebSite entity).
|
||||
-#}
|
||||
{% if page and not page.is_homepage and page.canonical_url %}
|
||||
<script type="application/ld+json">
|
||||
{
|
||||
"@context": "https://schema.org",
|
||||
"@type": "CollectionPage",
|
||||
"@id": {{ (page.canonical_url ~ "#webpage") | tojson }},
|
||||
"url": {{ page.canonical_url | tojson }},
|
||||
"name": {{ (page.title or config.site_name) | tojson }},
|
||||
"isPartOf": { "@id": "https://nubenetes.com/#website" },
|
||||
"publisher": { "@id": "https://nubenetes.com/#organization" },
|
||||
"inLanguage": "en"
|
||||
{%- if page.meta and page.meta.description %},
|
||||
"description": {{ page.meta.description | tojson }}
|
||||
{%- endif %}
|
||||
{%- if page.meta and page.meta.git_creation_date_localized_raw_iso_date %},
|
||||
"datePublished": {{ page.meta.git_creation_date_localized_raw_iso_date | tojson }}
|
||||
{%- endif %}
|
||||
{%- if page.meta and page.meta.git_revision_date_localized_raw_iso_date %},
|
||||
"dateModified": {{ page.meta.git_revision_date_localized_raw_iso_date | tojson }}
|
||||
{%- endif %}
|
||||
}
|
||||
</script>
|
||||
{% endif %}
|
||||
{% endblock %}
|
||||
@@ -3,6 +3,15 @@
|
||||
* Color Palette: Deep Space Black & Neon Cyan
|
||||
*/
|
||||
|
||||
html {
|
||||
scroll-behavior: smooth;
|
||||
}
|
||||
|
||||
.md-content {
|
||||
max-width: 1600px;
|
||||
margin: 0 auto;
|
||||
}
|
||||
|
||||
:root {
|
||||
/* LIGHT MODE - Modern, Crisp, High Contrast */
|
||||
--md-primary-fg-color: #09090b; /* Zinc 950 */
|
||||
@@ -167,6 +176,62 @@
|
||||
color: #c4b5fd;
|
||||
}
|
||||
|
||||
/* ---------------------------------------------------- */
|
||||
/* LABEL HEATMAP (Confluence-style popular-labels cloud) */
|
||||
/* ---------------------------------------------------- */
|
||||
|
||||
.v2-tag-heatmap {
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
gap: 0.45rem 0.7rem;
|
||||
align-items: baseline;
|
||||
padding: 1.1rem 1.2rem;
|
||||
margin: 1rem 0 1.75rem;
|
||||
border: 1px solid rgba(38, 50, 56, 0.12);
|
||||
border-radius: 10px;
|
||||
background: rgba(38, 50, 56, 0.04);
|
||||
}
|
||||
|
||||
[data-md-color-scheme="slate"] .v2-tag-heatmap {
|
||||
background: rgba(255, 255, 255, 0.03);
|
||||
border-color: rgba(255, 255, 255, 0.1);
|
||||
}
|
||||
|
||||
.v2-heat-tag {
|
||||
display: inline-flex;
|
||||
align-items: baseline;
|
||||
gap: 0.2em;
|
||||
line-height: 1.1;
|
||||
font-weight: 600;
|
||||
text-decoration: none;
|
||||
color: #455a64;
|
||||
transition: color 0.15s ease, transform 0.15s ease;
|
||||
}
|
||||
|
||||
.v2-heat-tag:hover {
|
||||
transform: translateY(-1px);
|
||||
color: var(--md-accent-fg-color);
|
||||
}
|
||||
|
||||
.v2-heat-n {
|
||||
font-size: 0.6em;
|
||||
font-weight: 700;
|
||||
opacity: 0.55;
|
||||
vertical-align: super;
|
||||
}
|
||||
|
||||
/* Size + warmth ramp: level 1 = least used, level 6 = most used. */
|
||||
.v2-heat-1 { font-size: 0.8rem; opacity: 0.7; }
|
||||
.v2-heat-2 { font-size: 0.95rem; }
|
||||
.v2-heat-3 { font-size: 1.15rem; }
|
||||
.v2-heat-4 { font-size: 1.45rem; }
|
||||
.v2-heat-5 { font-size: 1.8rem; color: #ef6c00; }
|
||||
.v2-heat-6 { font-size: 2.25rem; color: #d84315; font-weight: 700; }
|
||||
|
||||
[data-md-color-scheme="slate"] .v2-heat-tag { color: #b0bec5; }
|
||||
[data-md-color-scheme="slate"] .v2-heat-5 { color: #ffb74d; }
|
||||
[data-md-color-scheme="slate"] .v2-heat-6 { color: #ff8a65; }
|
||||
|
||||
/* ---------------------------------------------------- */
|
||||
/* MICRO-ANIMATIONS & HOVER STATES */
|
||||
/* ---------------------------------------------------- */
|
||||
@@ -269,6 +334,14 @@ a {
|
||||
border-radius: 4px;
|
||||
}
|
||||
|
||||
/* Dark-logo fix: invert black-on-transparent logos so they remain visible in dark mode */
|
||||
[data-md-color-scheme="slate"] img[src*="nutanix_logo"] {
|
||||
filter: invert(1);
|
||||
}
|
||||
[data-md-color-scheme="slate"] img[src*="nutanix_logo"]:hover {
|
||||
filter: invert(1) brightness(1.25);
|
||||
}
|
||||
|
||||
/* V2 Homepage Hero Dashboard Cards */
|
||||
.hero-badge-card {
|
||||
flex: 1;
|
||||
@@ -343,6 +416,28 @@ a {
|
||||
border-color: #2dd4bf !important;
|
||||
}
|
||||
|
||||
.hero-badge-card--amber {
|
||||
border-color: rgba(245, 158, 11, 0.2);
|
||||
background: rgba(245, 158, 11, 0.02);
|
||||
}
|
||||
.hero-badge-card--amber:hover {
|
||||
background: rgba(245, 158, 11, 0.06) !important;
|
||||
box-shadow: 0 8px 24px rgba(245, 158, 11, 0.18);
|
||||
border-color: #f59e0b !important;
|
||||
}
|
||||
|
||||
.hero-badge-icon {
|
||||
/* Match the 100px logo <img> box on the other hero cards so the
|
||||
emoji-based Intelligence Digest card is the same height. */
|
||||
height: 100px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
font-size: 3.5rem;
|
||||
line-height: 1;
|
||||
margin-bottom: 12px;
|
||||
}
|
||||
|
||||
.hero-badge-title {
|
||||
font-weight: bold;
|
||||
font-size: 0.95rem;
|
||||
@@ -355,6 +450,56 @@ a {
|
||||
margin-top: 4px;
|
||||
}
|
||||
|
||||
/* Intelligence Digest mini-preview on index */
|
||||
.digest-preview {
|
||||
background: rgba(245, 158, 11, 0.04);
|
||||
border: 1px solid rgba(245, 158, 11, 0.15);
|
||||
border-radius: 12px;
|
||||
padding: 20px 24px;
|
||||
margin: 24px 0;
|
||||
}
|
||||
.digest-preview-header {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
margin-bottom: 12px;
|
||||
}
|
||||
.digest-preview-title {
|
||||
font-weight: 700;
|
||||
font-size: 1rem;
|
||||
color: var(--md-primary-fg-color);
|
||||
}
|
||||
.digest-preview-link {
|
||||
font-size: 0.8rem;
|
||||
color: #f59e0b;
|
||||
text-decoration: none;
|
||||
font-weight: 600;
|
||||
letter-spacing: 0.02em;
|
||||
}
|
||||
.digest-preview-link:hover { text-decoration: underline; }
|
||||
.digest-preview-list {
|
||||
list-style: none;
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
}
|
||||
.digest-preview-list li {
|
||||
padding: 5px 0;
|
||||
border-bottom: 1px solid rgba(245, 158, 11, 0.08);
|
||||
font-size: 0.875rem;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 8px;
|
||||
}
|
||||
.digest-preview-list li:last-child { border-bottom: none; }
|
||||
.digest-preview-cat {
|
||||
font-size: 0.7rem;
|
||||
color: #f59e0b;
|
||||
background: rgba(245, 158, 11, 0.1);
|
||||
border-radius: 4px;
|
||||
padding: 1px 6px;
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
/* Hero Showcase Image wrapper (4 cars in a container) */
|
||||
.hero-showcase-wrapper {
|
||||
margin: 24px auto;
|
||||
@@ -801,11 +946,13 @@ a {
|
||||
/* PERFORMANCE OPTIMIZATIONS FOR DENSE INDEXES */
|
||||
/* ---------------------------------------------------- */
|
||||
|
||||
/* Defer rendering of heavy tag sections on the tags index page */
|
||||
.v2-tag-section {
|
||||
content-visibility: auto;
|
||||
contain-intrinsic-size: auto 500px;
|
||||
}
|
||||
/* NOTE: `content-visibility: auto` was removed here (v2.9.2). It deferred
|
||||
painting of off-screen <ul>/<ol> lists, which on the dark (slate) theme
|
||||
produced black flashes while scrolling and made the link lists below the
|
||||
index mosaic appear broken/collapsed (intrinsic-size mismatch caused
|
||||
scrollbar jumps). The tags page already uses collapsed <details>, which
|
||||
skip rendering natively, so the optimization was both redundant and
|
||||
harmful. Do NOT reintroduce content-visibility on broad selectors. */
|
||||
|
||||
/* Collapsible tag lists on the tags index page */
|
||||
.v2-tag-section details {
|
||||
@@ -876,6 +1023,784 @@ a {
|
||||
border-top-color: rgba(255, 255, 255, 0.06);
|
||||
}
|
||||
|
||||
/* ---------------------------------------------------- */
|
||||
/* MODERN BROWSER-NATIVE CSS FEATURES */
|
||||
/* ---------------------------------------------------- */
|
||||
|
||||
/* Typography Enhancements: Balanced headings & orphan prevention */
|
||||
.md-typeset h1,
|
||||
.md-typeset h2,
|
||||
.md-typeset h3 {
|
||||
text-wrap: balance;
|
||||
}
|
||||
|
||||
.md-typeset p,
|
||||
.md-typeset li {
|
||||
text-wrap: pretty;
|
||||
}
|
||||
|
||||
/* Textarea and input field auto-sizing */
|
||||
textarea,
|
||||
input[type="text"] {
|
||||
field-sizing: content;
|
||||
}
|
||||
|
||||
/* Keyboard focus accessibility indicators */
|
||||
.md-typeset a:focus-visible,
|
||||
.md-button:focus-visible,
|
||||
.v2-tag-section summary:focus-visible {
|
||||
outline: 2px solid var(--md-accent-fg-color);
|
||||
outline-offset: 4px;
|
||||
}
|
||||
|
||||
/* Coarse touch pointer optimizations (Mobile AA targets) */
|
||||
@media (pointer: coarse) {
|
||||
.md-tag,
|
||||
.md-button,
|
||||
.v2-tag-section summary {
|
||||
min-block-size: 44px;
|
||||
}
|
||||
}
|
||||
|
||||
/* ---------------------------------------------------- */
|
||||
/* ANNOUNCEMENT BAR */
|
||||
/* ---------------------------------------------------- */
|
||||
|
||||
.md-banner {
|
||||
background: linear-gradient(135deg, #0ea5e9, #22d3ee);
|
||||
color: #ffffff;
|
||||
font-weight: 500;
|
||||
text-align: center;
|
||||
padding: 8px 16px;
|
||||
}
|
||||
|
||||
.md-banner a {
|
||||
color: #ffffff;
|
||||
text-decoration: underline;
|
||||
font-weight: 700;
|
||||
}
|
||||
|
||||
[data-md-color-scheme="slate"] .md-banner {
|
||||
background: linear-gradient(135deg, #0284c7, #06b6d4);
|
||||
}
|
||||
|
||||
/* ---------------------------------------------------- */
|
||||
/* TRENDING NOW — NEWS DIGEST CARDS */
|
||||
/* ---------------------------------------------------- */
|
||||
|
||||
.trending-section {
|
||||
margin: 32px 0;
|
||||
padding: 24px;
|
||||
border-radius: 16px;
|
||||
border: 1px solid rgba(14, 165, 233, 0.15);
|
||||
background: linear-gradient(180deg, rgba(14, 165, 233, 0.03) 0%, transparent 100%);
|
||||
}
|
||||
|
||||
[data-md-color-scheme="slate"] .trending-section {
|
||||
border-color: rgba(34, 211, 238, 0.15);
|
||||
background: linear-gradient(180deg, rgba(34, 211, 238, 0.05) 0%, transparent 100%);
|
||||
}
|
||||
|
||||
.trending-section__title {
|
||||
font-size: 1.4em;
|
||||
font-weight: 700;
|
||||
margin-bottom: 20px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 8px;
|
||||
flex-wrap: wrap;
|
||||
}
|
||||
|
||||
.trending-section__updated {
|
||||
font-size: 0.55em;
|
||||
font-weight: 500;
|
||||
padding: 2px 10px;
|
||||
border-radius: 20px;
|
||||
background: rgba(14, 165, 233, 0.12);
|
||||
color: var(--md-accent-fg-color);
|
||||
border: 1px solid rgba(14, 165, 233, 0.25);
|
||||
letter-spacing: 0.02em;
|
||||
}
|
||||
|
||||
.trending-grid {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(auto-fill, minmax(300px, 1fr));
|
||||
gap: 16px;
|
||||
margin: 16px 0;
|
||||
}
|
||||
|
||||
/* --- Collapsible "Show more" lane (pure CSS, no JS) --- */
|
||||
.trending-lane {
|
||||
margin-bottom: 4px;
|
||||
}
|
||||
|
||||
.trending-toggle {
|
||||
position: absolute;
|
||||
opacity: 0;
|
||||
width: 0;
|
||||
height: 0;
|
||||
pointer-events: none;
|
||||
}
|
||||
|
||||
.trending-card--extra {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.trending-toggle:checked ~ .trending-grid .trending-card--extra {
|
||||
display: block;
|
||||
animation: trending-fade-in 0.25s ease;
|
||||
}
|
||||
|
||||
@keyframes trending-fade-in {
|
||||
from { opacity: 0; transform: translateY(6px); }
|
||||
to { opacity: 1; transform: translateY(0); }
|
||||
}
|
||||
|
||||
.trending-showmore {
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
gap: 6px;
|
||||
margin-top: 2px;
|
||||
padding: 7px 18px;
|
||||
font-size: 0.8em;
|
||||
font-weight: 600;
|
||||
cursor: pointer;
|
||||
user-select: none;
|
||||
color: var(--md-accent-fg-color);
|
||||
background: rgba(14, 165, 233, 0.08);
|
||||
border: 1px solid rgba(14, 165, 233, 0.25);
|
||||
border-radius: 20px;
|
||||
transition: background 0.15s ease, transform 0.15s ease;
|
||||
}
|
||||
|
||||
.trending-showmore:hover {
|
||||
background: rgba(14, 165, 233, 0.16);
|
||||
transform: translateY(-1px);
|
||||
}
|
||||
|
||||
[data-md-color-scheme="slate"] .trending-showmore {
|
||||
background: rgba(34, 211, 238, 0.10);
|
||||
border-color: rgba(34, 211, 238, 0.25);
|
||||
}
|
||||
|
||||
.trending-showmore__less {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.trending-toggle:checked ~ .trending-showmore .trending-showmore__more {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.trending-toggle:checked ~ .trending-showmore .trending-showmore__less {
|
||||
display: inline;
|
||||
}
|
||||
|
||||
.trending-card {
|
||||
border: 1px solid rgba(0, 0, 0, 0.08);
|
||||
border-radius: 12px;
|
||||
padding: 16px 20px;
|
||||
background: var(--md-primary-bg-color--light);
|
||||
transition: transform 0.2s ease, box-shadow 0.2s ease;
|
||||
position: relative;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.trending-card:hover {
|
||||
transform: translateY(-2px);
|
||||
box-shadow: 0 8px 24px rgba(14, 165, 233, 0.12);
|
||||
}
|
||||
|
||||
[data-md-color-scheme="slate"] .trending-card {
|
||||
border-color: rgba(255, 255, 255, 0.08);
|
||||
background: rgba(24, 24, 27, 0.4);
|
||||
}
|
||||
|
||||
[data-md-color-scheme="slate"] .trending-card:hover {
|
||||
box-shadow: 0 8px 24px rgba(34, 211, 238, 0.12);
|
||||
}
|
||||
|
||||
.trending-card__category {
|
||||
font-size: 0.75em;
|
||||
font-weight: 700;
|
||||
text-transform: uppercase;
|
||||
letter-spacing: 0.05em;
|
||||
color: var(--md-accent-fg-color);
|
||||
margin-bottom: 8px;
|
||||
}
|
||||
|
||||
.trending-card__title {
|
||||
font-size: 0.95em;
|
||||
font-weight: 600;
|
||||
margin-bottom: 6px;
|
||||
line-height: 1.3;
|
||||
}
|
||||
|
||||
.trending-card__title a {
|
||||
color: inherit;
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
.trending-card__title a:hover {
|
||||
color: var(--md-accent-fg-color);
|
||||
}
|
||||
|
||||
.trending-card__meta {
|
||||
font-size: 0.8em;
|
||||
color: var(--md-primary-fg-color--dark);
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 8px;
|
||||
margin-bottom: 8px;
|
||||
}
|
||||
|
||||
.trending-card__why {
|
||||
font-size: 0.82em;
|
||||
line-height: 1.45;
|
||||
color: var(--md-primary-fg-color--light);
|
||||
}
|
||||
|
||||
.trending-card__impact {
|
||||
/* In normal flow as a right-aligned pill on its own line, so a long celeste
|
||||
category/title can never slide underneath it. `width: fit-content` keeps the
|
||||
colored pill wrapped tightly around "CRITICAL"/"HIGH" + the optional NEW
|
||||
pill; `margin-left: auto` pins it to the top-right corner. */
|
||||
width: fit-content;
|
||||
max-width: 100%;
|
||||
margin-left: auto;
|
||||
margin-bottom: 8px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
flex-wrap: wrap;
|
||||
gap: 6px;
|
||||
font-size: 0.75em;
|
||||
font-weight: 700;
|
||||
padding: 2px 8px;
|
||||
border-radius: 6px;
|
||||
}
|
||||
|
||||
.trending-card__impact--critical {
|
||||
background: rgba(239, 68, 68, 0.15);
|
||||
color: #ef4444;
|
||||
}
|
||||
|
||||
.trending-card__impact--high {
|
||||
background: rgba(245, 158, 11, 0.15);
|
||||
color: #f59e0b;
|
||||
}
|
||||
|
||||
.trending-card__impact--medium {
|
||||
background: rgba(14, 165, 233, 0.15);
|
||||
color: #0ea5e9;
|
||||
}
|
||||
|
||||
.trending-card__new {
|
||||
padding: 1px 6px;
|
||||
border-radius: 6px;
|
||||
font-size: 0.85em;
|
||||
font-weight: 800;
|
||||
letter-spacing: 0.03em;
|
||||
background: rgba(16, 185, 129, 0.18);
|
||||
color: #10b981;
|
||||
}
|
||||
|
||||
/* Digest link cards (CTA to full digest pages) */
|
||||
.digest-links {
|
||||
display: flex;
|
||||
gap: 16px;
|
||||
margin-top: 20px;
|
||||
flex-wrap: wrap;
|
||||
}
|
||||
|
||||
.digest-link-card {
|
||||
flex: 1;
|
||||
min-width: 240px;
|
||||
padding: 16px 24px;
|
||||
border-radius: 12px;
|
||||
border: 2px solid var(--md-accent-fg-color);
|
||||
text-align: center;
|
||||
text-decoration: none;
|
||||
color: inherit;
|
||||
font-weight: 600;
|
||||
transition: all 0.2s ease;
|
||||
}
|
||||
|
||||
.digest-link-card:hover {
|
||||
background: var(--md-accent-fg-color);
|
||||
color: #ffffff;
|
||||
transform: translateY(-2px);
|
||||
}
|
||||
|
||||
[data-md-color-scheme="slate"] .digest-link-card:hover {
|
||||
color: #09090b;
|
||||
}
|
||||
|
||||
/* ===================================================================
|
||||
v2.9.16 — Home restructure: hero badge row, Topic Map grid,
|
||||
mosaic labels, responsive video embeds
|
||||
=================================================================== */
|
||||
|
||||
/* Hero badge row (was an inline flexbox style on the index) */
|
||||
.hero-badge-row {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
gap: 24px;
|
||||
margin: 16px 0;
|
||||
flex-wrap: wrap;
|
||||
}
|
||||
|
||||
/* Indigo accent for the new Topic Map badge card */
|
||||
.hero-badge-card--indigo {
|
||||
border-color: rgba(99, 102, 241, 0.2);
|
||||
background: rgba(99, 102, 241, 0.02);
|
||||
}
|
||||
.hero-badge-card--indigo:hover {
|
||||
background: rgba(99, 102, 241, 0.06) !important;
|
||||
box-shadow: 0 8px 24px rgba(99, 102, 241, 0.18);
|
||||
border-color: #6366f1 !important;
|
||||
}
|
||||
|
||||
/* Topic Map: full category directory as a multi-column grid.
|
||||
CSS columns flow the per-dimension sections into 3 (then 2, then 1)
|
||||
columns; break-inside keeps a dimension block intact across columns. */
|
||||
.topic-map-grid {
|
||||
column-count: 3;
|
||||
column-gap: 2.5rem;
|
||||
margin-top: 1.5rem;
|
||||
}
|
||||
.topic-map-dim {
|
||||
break-inside: avoid;
|
||||
-webkit-column-break-inside: avoid;
|
||||
page-break-inside: avoid;
|
||||
display: inline-block; /* helps WebKit honor break-inside */
|
||||
width: 100%;
|
||||
margin: 0 0 1.4rem;
|
||||
}
|
||||
.topic-map-dim h2 {
|
||||
margin-top: 0;
|
||||
font-size: 1.05rem;
|
||||
}
|
||||
|
||||
/* ===================================================================
|
||||
Slim quick-nav bar (rendered in the theme `tabs` block, below header)
|
||||
Persistent one-click access to key destinations on every page.
|
||||
=================================================================== */
|
||||
.nb-quicknav {
|
||||
background: var(--md-header-bg-color);
|
||||
border-bottom: 1px solid color-mix(in srgb, var(--md-accent-fg-color) 22%, transparent);
|
||||
}
|
||||
.nb-quicknav__inner {
|
||||
max-width: 1600px;
|
||||
margin-inline: auto;
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
align-items: center;
|
||||
justify-content: center; /* centered rows read as a balanced command bar */
|
||||
gap: 0.4rem 0.32rem;
|
||||
padding-block: 0.5rem;
|
||||
padding-inline: 0.7rem;
|
||||
}
|
||||
.nb-quicknav__link {
|
||||
/* chip colors derived from the theme accent via color-mix (Chrome 111+) */
|
||||
--nb-chip-bg: color-mix(in srgb, var(--md-accent-fg-color) 8%, transparent);
|
||||
--nb-chip-bd: color-mix(in srgb, var(--md-accent-fg-color) 18%, transparent);
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
gap: 0.3em;
|
||||
color: rgba(255, 255, 255, 0.82) !important;
|
||||
text-decoration: none;
|
||||
font-size: 0.62rem; /* sized so all pills + menus fit one row down to ~1280px */
|
||||
font-weight: 600;
|
||||
letter-spacing: 0.01em;
|
||||
white-space: nowrap;
|
||||
padding: 0.22rem 0.55rem;
|
||||
border-radius: 999px;
|
||||
background: var(--nb-chip-bg);
|
||||
border: 1px solid var(--nb-chip-bd);
|
||||
transition: background 0.18s ease, border-color 0.18s ease,
|
||||
color 0.18s ease, transform 0.18s ease, box-shadow 0.18s ease;
|
||||
}
|
||||
.nb-quicknav__link:hover {
|
||||
color: #fff !important;
|
||||
background: color-mix(in srgb, var(--md-accent-fg-color) 32%, transparent);
|
||||
border-color: var(--md-accent-fg-color);
|
||||
transform: translateY(-1px);
|
||||
box-shadow: 0 2px 10px color-mix(in srgb, var(--md-accent-fg-color) 40%, transparent);
|
||||
}
|
||||
.nb-quicknav__link:focus-visible {
|
||||
outline: 2px solid var(--md-accent-fg-color);
|
||||
outline-offset: 2px;
|
||||
}
|
||||
.nb-quicknav__link--muted {
|
||||
opacity: 0.6;
|
||||
}
|
||||
.nb-quicknav__link--muted:hover {
|
||||
opacity: 1;
|
||||
}
|
||||
|
||||
/* ── Category menus: native Popover API + CSS Anchor Positioning (Baseline 2026)
|
||||
The long-tail clusters collapse behind category buttons so the bar stays one
|
||||
row. Opening is click-driven via the Popover API (free Esc / click-outside
|
||||
dismissal + focus management); zero JS. ── */
|
||||
.nb-quicknav__group {
|
||||
display: inline-flex;
|
||||
}
|
||||
/* thin divider between the direct pills and the category menus */
|
||||
.nb-quicknav__group:first-of-type {
|
||||
margin-inline-start: 0.3rem;
|
||||
padding-inline-start: 0.55rem;
|
||||
border-inline-start: 1px solid color-mix(in srgb, var(--md-accent-fg-color) 18%, transparent);
|
||||
}
|
||||
.nb-quicknav__btn {
|
||||
font-family: inherit;
|
||||
cursor: pointer;
|
||||
}
|
||||
.nb-quicknav__caret {
|
||||
font-size: 0.85em;
|
||||
opacity: 0.75;
|
||||
transition: transform 0.18s ease;
|
||||
}
|
||||
.nb-quicknav__group:has(.nb-quicknav__menu:popover-open) .nb-quicknav__caret {
|
||||
transform: rotate(180deg);
|
||||
}
|
||||
/* Explicit anchor pairing per button↔menu — do NOT rely on the popover's
|
||||
implicit anchor (it isn't established reliably, leaving the menu in its
|
||||
static position over the button). */
|
||||
[popovertarget="nb-pop-guide"] { anchor-name: --nb-a-guide; }
|
||||
#nb-pop-guide { position-anchor: --nb-a-guide; }
|
||||
[popovertarget="nb-pop-digest"] { anchor-name: --nb-a-digest; }
|
||||
#nb-pop-digest { position-anchor: --nb-a-digest; }
|
||||
[popovertarget="nb-pop-videos"] { anchor-name: --nb-a-videos; }
|
||||
#nb-pop-videos { position-anchor: --nb-a-videos; }
|
||||
[popovertarget="nb-pop-k8s"] { anchor-name: --nb-a-k8s; }
|
||||
#nb-pop-k8s { position-anchor: --nb-a-k8s; }
|
||||
[popovertarget="nb-pop-delivery"] { anchor-name: --nb-a-delivery; }
|
||||
#nb-pop-delivery { position-anchor: --nb-a-delivery; }
|
||||
[popovertarget="nb-pop-iac"] { anchor-name: --nb-a-iac; }
|
||||
#nb-pop-iac { position-anchor: --nb-a-iac; }
|
||||
[popovertarget="nb-pop-cloud"] { anchor-name: --nb-a-cloud; }
|
||||
#nb-pop-cloud { position-anchor: --nb-a-cloud; }
|
||||
[popovertarget="nb-pop-net"] { anchor-name: --nb-a-net; }
|
||||
#nb-pop-net { position-anchor: --nb-a-net; }
|
||||
[popovertarget="nb-pop-sec"] { anchor-name: --nb-a-sec; }
|
||||
#nb-pop-sec { position-anchor: --nb-a-sec; }
|
||||
[popovertarget="nb-pop-obs"] { anchor-name: --nb-a-obs; }
|
||||
#nb-pop-obs { position-anchor: --nb-a-obs; }
|
||||
[popovertarget="nb-pop-aidata"] { anchor-name: --nb-a-aidata; }
|
||||
#nb-pop-aidata { position-anchor: --nb-a-aidata; }
|
||||
[popovertarget="nb-pop-dev"] { anchor-name: --nb-a-dev; }
|
||||
#nb-pop-dev { position-anchor: --nb-a-dev; }
|
||||
[popovertarget="nb-pop-more"] { anchor-name: --nb-a-more; }
|
||||
#nb-pop-more { position-anchor: --nb-a-more; }
|
||||
/* nested submenus anchor to their in-menu trigger */
|
||||
[popovertarget="nb-pop-aws"] { anchor-name: --nb-a-aws; }
|
||||
#nb-pop-aws { position-anchor: --nb-a-aws; }
|
||||
[popovertarget="nb-pop-ocp"] { anchor-name: --nb-a-ocp; }
|
||||
#nb-pop-ocp { position-anchor: --nb-a-ocp; }
|
||||
.nb-quicknav__menu {
|
||||
inset: auto; /* reset the UA-centered popover defaults */
|
||||
margin: 0;
|
||||
max-height: 82vh; /* tall menus (e.g. Kubernetes) scroll instead of overflowing */
|
||||
overflow-y: auto;
|
||||
overscroll-behavior: contain;
|
||||
/* drop below the invoking button, left-aligned. NB: position-area values must
|
||||
be all-physical or all-logical — mixing (e.g. `bottom span-inline-end`) is
|
||||
invalid and silently computes to `none`, leaving the menu over the button. */
|
||||
position-area: bottom span-right;
|
||||
/* Only flip horizontally near the right edge. NEVER flip-block: the quick-nav
|
||||
is a sticky top bar, so a tall menu flipped above would shoot off-screen. */
|
||||
position-try-fallbacks: flip-inline;
|
||||
margin-block-start: 0.45rem;
|
||||
min-width: 9.5rem;
|
||||
padding: 0.35rem;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 0.1rem;
|
||||
border: 1px solid color-mix(in srgb, var(--md-accent-fg-color) 30%, transparent);
|
||||
border-radius: 0.6rem;
|
||||
background: color-mix(in srgb, var(--md-header-bg-color) 86%, #000);
|
||||
box-shadow: 0 10px 30px rgba(0, 0, 0, 0.45);
|
||||
/* entry/exit animation across the display toggle */
|
||||
opacity: 0;
|
||||
transform: translateY(-4px);
|
||||
transition: opacity 0.16s ease, transform 0.16s ease,
|
||||
overlay 0.16s allow-discrete, display 0.16s allow-discrete;
|
||||
}
|
||||
.nb-quicknav__menu:popover-open {
|
||||
opacity: 1;
|
||||
transform: translateY(0);
|
||||
}
|
||||
@starting-style {
|
||||
.nb-quicknav__menu:popover-open {
|
||||
opacity: 0;
|
||||
transform: translateY(-4px);
|
||||
}
|
||||
}
|
||||
.nb-quicknav__menu a {
|
||||
display: block;
|
||||
padding: 0.34rem 0.6rem;
|
||||
border-radius: 0.4rem;
|
||||
color: rgba(255, 255, 255, 0.86);
|
||||
text-decoration: none;
|
||||
font-size: 0.72rem;
|
||||
font-weight: 600;
|
||||
white-space: nowrap;
|
||||
transition: background 0.14s ease, color 0.14s ease;
|
||||
}
|
||||
.nb-quicknav__menu a:hover,
|
||||
.nb-quicknav__menu a:focus-visible {
|
||||
background: color-mix(in srgb, var(--md-accent-fg-color) 30%, transparent);
|
||||
color: #fff;
|
||||
outline: none;
|
||||
}
|
||||
.nb-quicknav__menu-muted {
|
||||
opacity: 0.62;
|
||||
margin-block-start: 0.15rem;
|
||||
padding-block-start: 0.42rem !important;
|
||||
border-block-start: 1px solid rgba(255, 255, 255, 0.1);
|
||||
}
|
||||
|
||||
/* Two-column layout for long menus (e.g. Kubernetes, 22 items) so they stay
|
||||
short enough to show in full WITHOUT a scrollbar — the scrollable tall popover
|
||||
was unreliable. Multicol is column-major, so reading order is preserved. */
|
||||
/* Deterministic 2-column layout (column-major grid) so the menu height equals
|
||||
the row count exactly — no balancing remainder, hence no stray scrollbar.
|
||||
11 rows × 2 cols fits the 22 top-level Kubernetes entries. */
|
||||
.nb-quicknav__menu--cols {
|
||||
display: grid;
|
||||
grid-auto-flow: column;
|
||||
grid-template-rows: repeat(11, auto);
|
||||
grid-template-columns: repeat(2, minmax(0, 1fr));
|
||||
column-gap: 0.4rem;
|
||||
min-width: 22rem;
|
||||
/* a 2-column menu (~370px) always fits below the sticky bar, so never
|
||||
scroll — avoids the sub-pixel grid/overflow scrollbar entirely */
|
||||
max-height: none;
|
||||
overflow: visible;
|
||||
}
|
||||
/* the submenu wrapper must be a real block (not display:contents) so its
|
||||
trigger occupies one grid cell cleanly */
|
||||
.nb-quicknav__menu--cols .nb-quicknav__subwrap {
|
||||
display: block;
|
||||
}
|
||||
|
||||
/* ── Nested submenu (e.g. Cloud → AWS ▸ → AWS pages) ──
|
||||
A second-level popover invoked from inside a menu. The trigger looks like a
|
||||
menu item; the submenu opens to the side (inline-end) of the trigger, with a
|
||||
flip fallback so it never leaves the viewport. Popover nesting keeps the
|
||||
parent menu open while the submenu is shown. */
|
||||
.nb-quicknav__subwrap { display: contents; }
|
||||
.nb-quicknav__subtrigger {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
gap: 0.6rem;
|
||||
width: 100%;
|
||||
padding: 0.34rem 0.6rem;
|
||||
border: none;
|
||||
border-radius: 0.4rem;
|
||||
background: none;
|
||||
color: rgba(255, 255, 255, 0.86);
|
||||
font-family: inherit;
|
||||
font-size: 0.72rem;
|
||||
font-weight: 600;
|
||||
text-align: left;
|
||||
white-space: nowrap;
|
||||
cursor: pointer;
|
||||
transition: background 0.14s ease, color 0.14s ease;
|
||||
}
|
||||
.nb-quicknav__subtrigger:hover,
|
||||
.nb-quicknav__subtrigger:focus-visible {
|
||||
background: color-mix(in srgb, var(--md-accent-fg-color) 30%, transparent);
|
||||
color: #fff;
|
||||
outline: none;
|
||||
}
|
||||
.nb-quicknav__subwrap:has(.nb-quicknav__submenu:popover-open) .nb-quicknav__caret {
|
||||
transform: rotate(0); /* caret is a side-arrow ▸, keep it static */
|
||||
}
|
||||
.nb-quicknav__submenu {
|
||||
/* Open to the RIGHT of the trigger, top-aligned. position-area's horizontal
|
||||
axis isn't honored reliably when the anchor lives inside another popover,
|
||||
so place explicitly with anchor(): left edge at the trigger's right edge. */
|
||||
position-area: none;
|
||||
top: anchor(top);
|
||||
left: anchor(right);
|
||||
right: auto;
|
||||
bottom: auto;
|
||||
position-try-fallbacks: flip-inline;
|
||||
margin-block-start: 0;
|
||||
margin-inline-start: 0.35rem;
|
||||
}
|
||||
|
||||
@media (prefers-reduced-motion: reduce) {
|
||||
.nb-quicknav__link,
|
||||
.nb-quicknav__caret,
|
||||
.nb-quicknav__menu { transition: none; }
|
||||
.nb-quicknav__link:hover { transform: none; }
|
||||
}
|
||||
/* On phones the left drawer already exposes navigation; one scrollable row. */
|
||||
@media screen and (max-width: 44.9375em) {
|
||||
.nb-quicknav__inner {
|
||||
flex-wrap: nowrap;
|
||||
justify-content: flex-start;
|
||||
overflow-x: auto;
|
||||
scrollbar-width: none; /* Firefox */
|
||||
}
|
||||
.nb-quicknav__inner::-webkit-scrollbar { display: none; } /* WebKit/Blink */
|
||||
}
|
||||
.topic-map-dim ul {
|
||||
margin-top: 0.3rem;
|
||||
}
|
||||
.topic-count {
|
||||
display: inline-block;
|
||||
margin-left: 0.35rem;
|
||||
padding: 0 0.45rem;
|
||||
font-size: 0.68rem;
|
||||
font-weight: 600;
|
||||
line-height: 1.4;
|
||||
border-radius: 10px;
|
||||
color: var(--md-default-fg-color--light);
|
||||
background: var(--md-default-fg-color--lightest);
|
||||
vertical-align: middle;
|
||||
}
|
||||
@media screen and (max-width: 76.1875em) {
|
||||
.topic-map-grid { column-count: 2; }
|
||||
}
|
||||
@media screen and (max-width: 44.9375em) {
|
||||
.topic-map-grid { column-count: 1; }
|
||||
}
|
||||
|
||||
/* ===================================================================
|
||||
Topic Map: Resource Density Heatmap
|
||||
A true colour matrix (distinct from the size-based Label cloud). Each
|
||||
category is a tile whose warmth (.th-1..6) encodes resource density,
|
||||
grouped by strategic dimension. Generated by v2_optimizer.py.
|
||||
=================================================================== */
|
||||
.topic-heatmap {
|
||||
margin: 1rem 0 2rem;
|
||||
padding: 1.1rem 1.2rem 1.3rem;
|
||||
border: 1px solid rgba(38, 50, 56, 0.12);
|
||||
border-radius: 10px;
|
||||
background: rgba(38, 50, 56, 0.04);
|
||||
}
|
||||
[data-md-color-scheme="slate"] .topic-heatmap {
|
||||
background: rgba(255, 255, 255, 0.03);
|
||||
border-color: rgba(255, 255, 255, 0.1);
|
||||
}
|
||||
.topic-heatmap__legend {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 0.3rem;
|
||||
margin-bottom: 1rem;
|
||||
font-size: 0.7rem;
|
||||
font-weight: 600;
|
||||
letter-spacing: 0.03em;
|
||||
color: var(--md-default-fg-color--light);
|
||||
}
|
||||
.topic-heatmap__legend .topic-heatcell {
|
||||
width: 26px;
|
||||
height: 14px;
|
||||
padding: 0;
|
||||
border-radius: 3px;
|
||||
}
|
||||
.topic-heatmap__cap { text-transform: uppercase; opacity: 0.7; }
|
||||
.topic-heatmap__row {
|
||||
display: grid;
|
||||
grid-template-columns: 190px 1fr;
|
||||
gap: 0.5rem 1rem;
|
||||
align-items: start;
|
||||
padding: 0.6rem 0;
|
||||
border-top: 1px solid rgba(38, 50, 56, 0.08);
|
||||
}
|
||||
[data-md-color-scheme="slate"] .topic-heatmap__row {
|
||||
border-top-color: rgba(255, 255, 255, 0.07);
|
||||
}
|
||||
.topic-heatmap__row:first-of-type { border-top: none; padding-top: 0; }
|
||||
.topic-heatmap__dim {
|
||||
font-size: 0.78rem;
|
||||
font-weight: 700;
|
||||
line-height: 1.25;
|
||||
padding-top: 0.25rem;
|
||||
color: var(--md-default-fg-color);
|
||||
}
|
||||
.topic-heatmap__cells {
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
gap: 0.35rem;
|
||||
}
|
||||
.topic-heatcell {
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
gap: 0.3em;
|
||||
padding: 0.28rem 0.5rem;
|
||||
border-radius: 5px;
|
||||
font-size: 0.7rem;
|
||||
font-weight: 600;
|
||||
line-height: 1.2;
|
||||
text-decoration: none;
|
||||
color: #1a2327;
|
||||
transition: transform 0.12s ease, box-shadow 0.12s ease;
|
||||
}
|
||||
.topic-heatcell:hover {
|
||||
transform: translateY(-2px);
|
||||
box-shadow: 0 3px 9px rgba(0, 0, 0, 0.18);
|
||||
}
|
||||
.topic-heatcell__n {
|
||||
font-size: 0.62em;
|
||||
font-weight: 700;
|
||||
opacity: 0.7;
|
||||
}
|
||||
/* Sequential warmth ramp: th-1 = sparsest, th-6 = densest. */
|
||||
.th-1 { background: #e3f2fd; }
|
||||
.th-2 { background: #ffe0b2; }
|
||||
.th-3 { background: #ffcc80; }
|
||||
.th-4 { background: #ffa726; }
|
||||
.th-5 { background: #fb8c00; color: #fff; }
|
||||
.th-6 { background: #e64a19; color: #fff; }
|
||||
[data-md-color-scheme="slate"] .th-1 { background: #2d4456; color: #d7e3ea; }
|
||||
[data-md-color-scheme="slate"] .th-2 { background: #6d4c1f; color: #f5e7d3; }
|
||||
[data-md-color-scheme="slate"] .th-3 { background: #97601f; color: #fff3e0; }
|
||||
[data-md-color-scheme="slate"] .th-4 { background: #c2701a; color: #fff; }
|
||||
[data-md-color-scheme="slate"] .th-5 { background: #e2701a; color: #fff; }
|
||||
[data-md-color-scheme="slate"] .th-6 { background: #ff5722; color: #fff; }
|
||||
@media screen and (max-width: 44.9375em) {
|
||||
.topic-heatmap__row { grid-template-columns: 1fr; gap: 0.35rem; }
|
||||
.topic-heatmap__dim { padding-top: 0; }
|
||||
}
|
||||
|
||||
/* Visible label for each YouTube mosaic category block (was hidden in title=) */
|
||||
.mosaic-cat-label {
|
||||
margin: 0 0 0.5rem;
|
||||
padding-left: 0.55rem;
|
||||
border-left: 3px solid var(--cat-color, #64748b);
|
||||
font-size: 0.72rem;
|
||||
font-weight: 700;
|
||||
letter-spacing: 0.04em;
|
||||
text-transform: uppercase;
|
||||
color: var(--md-default-fg-color--light);
|
||||
text-align: left;
|
||||
}
|
||||
|
||||
/* Responsive, privacy-friendly video embeds (about page) */
|
||||
.video-embed-grid {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
gap: 16px;
|
||||
flex-wrap: wrap;
|
||||
margin: 24px 0;
|
||||
}
|
||||
.video-embed {
|
||||
flex: 1 1 420px;
|
||||
max-width: 480px;
|
||||
aspect-ratio: 16 / 9;
|
||||
}
|
||||
.video-embed iframe {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
border: 0;
|
||||
border-radius: 8px;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -1,262 +1,275 @@
|
||||
document.addEventListener("DOMContentLoaded", function () {
|
||||
// Initialize the filter only if we are on a page with resource lists
|
||||
const contentArea = document.querySelector(".md-content__inner");
|
||||
if (!contentArea) return;
|
||||
// Nubenetes V2 — in-page resource search & tag filter widget.
|
||||
//
|
||||
// IMPORTANT: The V2 theme enables `navigation.instant` (SPA-style page swaps),
|
||||
// so `DOMContentLoaded` fires only on the very first load. We therefore drive
|
||||
// initialization through Material's `document$` observable, which emits on every
|
||||
// (instant) navigation. We fall back to `DOMContentLoaded` when the observable
|
||||
// is unavailable (e.g. instant nav disabled or local preview without the bundle).
|
||||
|
||||
// Check if there are any resource items on the page (li or details)
|
||||
const listItems = Array.from(contentArea.querySelectorAll("ul > li"));
|
||||
const detailsItems = Array.from(contentArea.querySelectorAll("details.note"));
|
||||
|
||||
// If there are no list items and no details items, do not inject the filter
|
||||
if (listItems.length === 0 && detailsItems.length === 0) return;
|
||||
(function () {
|
||||
"use strict";
|
||||
|
||||
// Do not show on the homepage, video hub index page, or technical tags index page (performance)
|
||||
const h1 = contentArea.querySelector("h1");
|
||||
if (h1 && (
|
||||
h1.textContent.includes("Nubenetes Elite Portal (V2)") ||
|
||||
h1.textContent.includes("Agentic Video Hub") ||
|
||||
h1.textContent.includes("Technical Tags Index")
|
||||
)) {
|
||||
return;
|
||||
}
|
||||
function initFilterWidget() {
|
||||
const contentArea = document.querySelector(".md-content__inner");
|
||||
if (!contentArea) return;
|
||||
|
||||
// Build the filter container element
|
||||
const filterContainer = document.createElement("div");
|
||||
filterContainer.className = "v2-filter-container";
|
||||
filterContainer.innerHTML = `
|
||||
<div class="v2-search-wrapper">
|
||||
<input type="text" class="v2-search-input" placeholder="Search resources in this page..." />
|
||||
<span class="v2-search-clear" style="display:none;">×</span>
|
||||
</div>
|
||||
<div class="v2-tag-pills">
|
||||
<button class="v2-pill active" data-filter="all">All</button>
|
||||
<button class="v2-pill" data-filter="DE FACTO STANDARD">De Facto Standard</button>
|
||||
<button class="v2-pill" data-filter="ENTERPRISE-STABLE">Enterprise Stable</button>
|
||||
<button class="v2-pill" data-filter="EMERGING">Emerging</button>
|
||||
<button class="v2-pill" data-filter="GUIDE">Guide</button>
|
||||
<button class="v2-pill" data-filter="CASE STUDY">Case Study</button>
|
||||
<button class="v2-pill" data-filter="COMMUNITY-TOOL">Community Tool</button>
|
||||
<button class="v2-pill" data-filter="SPANISH">Spanish</button>
|
||||
</div>
|
||||
<div class="v2-filter-stats">
|
||||
<span>Showing <strong class="v2-visible-count">0</strong> of <strong class="v2-total-count">0</strong> resources</span>
|
||||
<span class="v2-active-filters" style="font-style: italic;"></span>
|
||||
</div>
|
||||
`;
|
||||
// Guard against double-injection (document$ can emit more than once).
|
||||
if (contentArea.querySelector(".v2-filter-container")) return;
|
||||
|
||||
// Insert the filter container right after the main H1
|
||||
if (h1 && h1.nextSibling) {
|
||||
h1.parentNode.insertBefore(filterContainer, h1.nextSibling);
|
||||
} else {
|
||||
contentArea.insertBefore(filterContainer, contentArea.firstChild);
|
||||
}
|
||||
// Only inject where there are resources to filter.
|
||||
const listItems = Array.from(contentArea.querySelectorAll("ul > li"));
|
||||
const detailsItems = Array.from(contentArea.querySelectorAll("details.note"));
|
||||
if (listItems.length === 0 && detailsItems.length === 0) return;
|
||||
|
||||
const searchInput = filterContainer.querySelector(".v2-search-input");
|
||||
const searchClear = filterContainer.querySelector(".v2-search-clear");
|
||||
const pills = filterContainer.querySelectorAll(".v2-pill");
|
||||
const visibleCountSpan = filterContainer.querySelector(".v2-visible-count");
|
||||
const totalCountSpan = filterContainer.querySelector(".v2-total-count");
|
||||
|
||||
// All target elements we want to filter
|
||||
const targets = [];
|
||||
|
||||
// Prepare list items
|
||||
listItems.forEach(item => {
|
||||
// Make sure it's a resource list item (has a link and some content)
|
||||
if (item.querySelector("a")) {
|
||||
targets.push({
|
||||
element: item,
|
||||
type: "li",
|
||||
text: item.textContent.toLowerCase(),
|
||||
tags: Array.from(item.querySelectorAll(".md-tag")).map(t => t.textContent.toUpperCase())
|
||||
});
|
||||
// Skip on curated landing/index pages where the widget adds no value.
|
||||
const h1 = contentArea.querySelector("h1");
|
||||
if (h1 && (
|
||||
h1.textContent.includes("Nubenetes Elite Portal (V2)") ||
|
||||
h1.textContent.includes("Agentic Video Hub") ||
|
||||
h1.textContent.includes("Technical Tags Index") ||
|
||||
h1.textContent.includes("Intelligence Digest") ||
|
||||
// Topic Map / Methodology list categories and legend rows, not
|
||||
// tagged resources: their <li> items carry no .md-tag, so the
|
||||
// maturity pills would always filter to zero and the "X of Y
|
||||
// resources" count is misleading. Skip them.
|
||||
h1.textContent.includes("Topic Map") ||
|
||||
h1.textContent.includes("Methodology")
|
||||
)) {
|
||||
return;
|
||||
}
|
||||
});
|
||||
|
||||
// Prepare details.note items (if any, like in some V2 structures)
|
||||
detailsItems.forEach(detail => {
|
||||
const summary = detail.querySelector("summary");
|
||||
targets.push({
|
||||
element: detail,
|
||||
type: "details",
|
||||
text: detail.textContent.toLowerCase(),
|
||||
tags: summary ? [summary.textContent.toUpperCase()] : []
|
||||
});
|
||||
});
|
||||
const filterContainer = document.createElement("div");
|
||||
filterContainer.className = "v2-filter-container";
|
||||
filterContainer.innerHTML = `
|
||||
<div class="v2-search-wrapper">
|
||||
<input type="text" class="v2-search-input" placeholder="Search resources in this page..." aria-label="Search resources in this page" />
|
||||
<span class="v2-search-clear" style="display:none;" title="Clear search">×</span>
|
||||
</div>
|
||||
<div class="v2-tag-pills">
|
||||
<button class="v2-pill active" data-filter="all">All</button>
|
||||
<button class="v2-pill" data-filter="DE FACTO STANDARD">De Facto Standard</button>
|
||||
<button class="v2-pill" data-filter="ENTERPRISE-STABLE">Enterprise Stable</button>
|
||||
<button class="v2-pill" data-filter="EMERGING">Emerging</button>
|
||||
<button class="v2-pill" data-filter="GUIDE">Guide</button>
|
||||
<button class="v2-pill" data-filter="CASE STUDY">Case Study</button>
|
||||
<button class="v2-pill" data-filter="COMMUNITY-TOOL">Community Tool</button>
|
||||
<button class="v2-pill" data-filter="SPANISH">Spanish</button>
|
||||
</div>
|
||||
<div class="v2-filter-stats">
|
||||
<span>Showing <strong class="v2-visible-count">0</strong> of <strong class="v2-total-count">0</strong> resources</span>
|
||||
<span class="v2-active-filters" style="font-style: italic;"></span>
|
||||
<span class="v2-no-results" style="display:none; color: var(--md-typeset-color); opacity:.75;">No resources match your filter.</span>
|
||||
</div>
|
||||
`;
|
||||
|
||||
totalCountSpan.textContent = targets.length;
|
||||
visibleCountSpan.textContent = targets.length;
|
||||
// Insert directly after the main H1.
|
||||
if (h1 && h1.nextSibling) {
|
||||
h1.parentNode.insertBefore(filterContainer, h1.nextSibling);
|
||||
} else {
|
||||
contentArea.insertBefore(filterContainer, contentArea.firstChild);
|
||||
}
|
||||
|
||||
let activeFilter = "all";
|
||||
let searchText = "";
|
||||
const searchInput = filterContainer.querySelector(".v2-search-input");
|
||||
const searchClear = filterContainer.querySelector(".v2-search-clear");
|
||||
const pills = filterContainer.querySelectorAll(".v2-pill");
|
||||
const visibleCountSpan = filterContainer.querySelector(".v2-visible-count");
|
||||
const totalCountSpan = filterContainer.querySelector(".v2-total-count");
|
||||
const noResultsSpan = filterContainer.querySelector(".v2-no-results");
|
||||
|
||||
function updateFilters() {
|
||||
let visibleCount = 0;
|
||||
|
||||
targets.forEach(item => {
|
||||
let matchesSearch = true;
|
||||
let matchesPill = true;
|
||||
|
||||
// 1. Search text filter
|
||||
if (searchText) {
|
||||
matchesSearch = item.text.includes(searchText);
|
||||
// Collect filter targets (resource <li> and details.note blocks).
|
||||
const targets = [];
|
||||
listItems.forEach(item => {
|
||||
if (item.querySelector("a")) {
|
||||
targets.push({
|
||||
element: item,
|
||||
type: "li",
|
||||
text: item.textContent.toLowerCase(),
|
||||
tags: Array.from(item.querySelectorAll(".md-tag")).map(t => t.textContent.toUpperCase())
|
||||
});
|
||||
}
|
||||
});
|
||||
detailsItems.forEach(detail => {
|
||||
const summary = detail.querySelector("summary");
|
||||
targets.push({
|
||||
element: detail,
|
||||
type: "details",
|
||||
text: detail.textContent.toLowerCase(),
|
||||
tags: summary ? [summary.textContent.toUpperCase()] : []
|
||||
});
|
||||
});
|
||||
|
||||
// 2. Pill/Category filter
|
||||
if (activeFilter !== "all") {
|
||||
if (activeFilter === "SPANISH") {
|
||||
matchesPill = item.tags.some(tag => tag.includes("SPANISH"));
|
||||
} else {
|
||||
matchesPill = item.tags.some(tag => tag.includes(activeFilter));
|
||||
totalCountSpan.textContent = targets.length;
|
||||
visibleCountSpan.textContent = targets.length;
|
||||
|
||||
let activeFilter = "all";
|
||||
let searchText = "";
|
||||
|
||||
function updateFilters() {
|
||||
let visibleCount = 0;
|
||||
|
||||
targets.forEach(item => {
|
||||
let matchesSearch = true;
|
||||
let matchesPill = true;
|
||||
|
||||
if (searchText) {
|
||||
matchesSearch = item.text.includes(searchText);
|
||||
}
|
||||
}
|
||||
|
||||
if (matchesSearch && matchesPill) {
|
||||
item.element.classList.remove("v2-filtered-hidden");
|
||||
visibleCount++;
|
||||
} else {
|
||||
item.element.classList.add("v2-filtered-hidden");
|
||||
}
|
||||
});
|
||||
|
||||
visibleCountSpan.textContent = visibleCount;
|
||||
|
||||
// 3. Hide empty headers and subheadings
|
||||
// If a section (e.g., under h2, h3, h4) has no visible items, hide the section header
|
||||
const headings = Array.from(contentArea.querySelectorAll("h2, h3, h4"));
|
||||
headings.forEach(heading => {
|
||||
let next = heading.nextElementSibling;
|
||||
let totalItemsInSection = 0;
|
||||
let hiddenItemsInSection = 0;
|
||||
|
||||
while (next && !["H1", "H2", "H3", "H4"].includes(next.tagName)) {
|
||||
if (next.tagName === "UL") {
|
||||
const lis = Array.from(next.querySelectorAll("li"));
|
||||
lis.forEach(li => {
|
||||
if (targets.some(t => t.element === li)) {
|
||||
totalItemsInSection++;
|
||||
if (li.classList.contains("v2-filtered-hidden")) {
|
||||
hiddenItemsInSection++;
|
||||
}
|
||||
}
|
||||
});
|
||||
} else if (next.tagName === "DETAILS" && next.classList.contains("note")) {
|
||||
totalItemsInSection++;
|
||||
if (next.classList.contains("v2-filtered-hidden")) {
|
||||
hiddenItemsInSection++;
|
||||
if (activeFilter !== "all") {
|
||||
if (activeFilter === "SPANISH") {
|
||||
matchesPill = item.tags.some(tag => tag.includes("SPANISH"));
|
||||
} else {
|
||||
matchesPill = item.tags.some(tag => tag.includes(activeFilter));
|
||||
}
|
||||
}
|
||||
next = next.nextElementSibling;
|
||||
}
|
||||
|
||||
if (totalItemsInSection > 0 && totalItemsInSection === hiddenItemsInSection) {
|
||||
heading.classList.add("v2-filtered-hidden");
|
||||
} else {
|
||||
heading.classList.remove("v2-filtered-hidden");
|
||||
}
|
||||
});
|
||||
}
|
||||
if (matchesSearch && matchesPill) {
|
||||
item.element.classList.remove("v2-filtered-hidden");
|
||||
visibleCount++;
|
||||
} else {
|
||||
item.element.classList.add("v2-filtered-hidden");
|
||||
}
|
||||
});
|
||||
|
||||
// Input event listener
|
||||
searchInput.addEventListener("input", function (e) {
|
||||
searchText = e.target.value.toLowerCase().trim();
|
||||
if (searchText) {
|
||||
searchClear.style.display = "block";
|
||||
} else {
|
||||
searchClear.style.display = "none";
|
||||
visibleCountSpan.textContent = visibleCount;
|
||||
noResultsSpan.style.display = visibleCount === 0 ? "inline" : "none";
|
||||
|
||||
// Hide section headings whose every resource is filtered out.
|
||||
const headings = Array.from(contentArea.querySelectorAll("h2, h3, h4"));
|
||||
headings.forEach(heading => {
|
||||
let next = heading.nextElementSibling;
|
||||
let totalItemsInSection = 0;
|
||||
let hiddenItemsInSection = 0;
|
||||
|
||||
while (next && !["H1", "H2", "H3", "H4"].includes(next.tagName)) {
|
||||
if (next.tagName === "UL") {
|
||||
Array.from(next.querySelectorAll("li")).forEach(li => {
|
||||
if (targets.some(t => t.element === li)) {
|
||||
totalItemsInSection++;
|
||||
if (li.classList.contains("v2-filtered-hidden")) hiddenItemsInSection++;
|
||||
}
|
||||
});
|
||||
} else if (next.tagName === "DETAILS" && next.classList.contains("note")) {
|
||||
totalItemsInSection++;
|
||||
if (next.classList.contains("v2-filtered-hidden")) hiddenItemsInSection++;
|
||||
}
|
||||
next = next.nextElementSibling;
|
||||
}
|
||||
|
||||
if (totalItemsInSection > 0 && totalItemsInSection === hiddenItemsInSection) {
|
||||
heading.classList.add("v2-filtered-hidden");
|
||||
} else {
|
||||
heading.classList.remove("v2-filtered-hidden");
|
||||
}
|
||||
});
|
||||
}
|
||||
updateFilters();
|
||||
});
|
||||
|
||||
// Clear search
|
||||
searchClear.addEventListener("click", function () {
|
||||
searchInput.value = "";
|
||||
searchText = "";
|
||||
searchClear.style.display = "none";
|
||||
updateFilters();
|
||||
searchInput.focus();
|
||||
});
|
||||
|
||||
// Pill click event listener
|
||||
pills.forEach(pill => {
|
||||
pill.addEventListener("click", function () {
|
||||
pills.forEach(p => p.classList.remove("active"));
|
||||
this.classList.add("active");
|
||||
activeFilter = this.getAttribute("data-filter");
|
||||
searchInput.addEventListener("input", function (e) {
|
||||
searchText = e.target.value.toLowerCase().trim();
|
||||
searchClear.style.display = searchText ? "block" : "none";
|
||||
updateFilters();
|
||||
});
|
||||
});
|
||||
|
||||
// Make tag badges clickable to trigger filtering
|
||||
document.addEventListener("click", function (e) {
|
||||
const tagSpan = e.target.closest(".md-tag");
|
||||
if (!tagSpan) return;
|
||||
|
||||
// Skip if inside the filter container itself to avoid loop
|
||||
if (e.target.closest(".v2-filter-container")) return;
|
||||
|
||||
let tagText = tagSpan.textContent.trim().replace(/[\[\]]/g, "").toUpperCase();
|
||||
if (tagText.includes("CONTENT")) {
|
||||
tagText = tagText.replace(" CONTENT", "");
|
||||
}
|
||||
|
||||
// 1. Check if the tag matches a predefined filter pill
|
||||
const matchingPill = Array.from(pills).find(p => p.getAttribute("data-filter") === tagText);
|
||||
if (matchingPill) {
|
||||
pills.forEach(p => p.classList.remove("active"));
|
||||
matchingPill.classList.add("active");
|
||||
activeFilter = tagText;
|
||||
// Reset search input
|
||||
searchClear.addEventListener("click", function () {
|
||||
searchInput.value = "";
|
||||
searchText = "";
|
||||
searchClear.style.display = "none";
|
||||
updateFilters();
|
||||
filterContainer.scrollIntoView({ behavior: "smooth", block: "nearest" });
|
||||
} else {
|
||||
// 2. If it's a technical stack tag, use it as search input query
|
||||
pills.forEach(p => p.classList.remove("active"));
|
||||
const allPill = Array.from(pills).find(p => p.getAttribute("data-filter") === "all");
|
||||
if (allPill) allPill.classList.add("active");
|
||||
activeFilter = "all";
|
||||
|
||||
// Populate search input and fire input event
|
||||
searchInput.value = tagSpan.textContent.trim().toLowerCase();
|
||||
searchText = searchInput.value;
|
||||
searchClear.style.display = "block";
|
||||
updateFilters();
|
||||
filterContainer.scrollIntoView({ behavior: "smooth", block: "nearest" });
|
||||
searchInput.focus();
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
// Lazy Loading Video Playback Integration
|
||||
document.addEventListener("DOMContentLoaded", function() {
|
||||
const lazyContainers = document.querySelectorAll(".video-lazy-container");
|
||||
lazyContainers.forEach(container => {
|
||||
container.addEventListener("click", function() {
|
||||
const videoUrl = this.getAttribute("data-video-url");
|
||||
const videoId = this.getAttribute("data-video-id");
|
||||
if (!videoUrl || !videoId) return;
|
||||
|
||||
const iframe = document.createElement("iframe");
|
||||
iframe.setAttribute("width", "720");
|
||||
iframe.setAttribute("height", "405");
|
||||
const autoplayUrl = videoUrl.includes("?") ? `${videoUrl}&autoplay=1` : `${videoUrl}?autoplay=1`;
|
||||
iframe.setAttribute("src", autoplayUrl);
|
||||
iframe.setAttribute("title", "YouTube Video");
|
||||
iframe.setAttribute("frameborder", "0");
|
||||
iframe.setAttribute("allow", "accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture");
|
||||
iframe.setAttribute("allowfullscreen", "true");
|
||||
iframe.style.border = "none";
|
||||
iframe.style.width = "100%";
|
||||
iframe.style.height = "100%";
|
||||
iframe.style.borderRadius = "8px";
|
||||
|
||||
this.innerHTML = "";
|
||||
this.appendChild(iframe);
|
||||
this.style.cursor = "default";
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
pills.forEach(pill => {
|
||||
pill.addEventListener("click", function () {
|
||||
pills.forEach(p => p.classList.remove("active"));
|
||||
this.classList.add("active");
|
||||
activeFilter = this.getAttribute("data-filter");
|
||||
updateFilters();
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
// Make tag badges anywhere in the content act as filter triggers.
|
||||
// Bound once on `document` (which survives instant navigation) and resolves
|
||||
// the current page's widget lazily, dispatching native events so the
|
||||
// per-page listeners above stay the single source of truth.
|
||||
function bindTagClicksOnce() {
|
||||
if (window.__v2TagClickBound) return;
|
||||
window.__v2TagClickBound = true;
|
||||
|
||||
document.addEventListener("click", function (e) {
|
||||
const tagSpan = e.target.closest(".md-tag");
|
||||
if (!tagSpan) return;
|
||||
if (e.target.closest(".v2-filter-container")) return;
|
||||
|
||||
const filterContainer = document.querySelector(".v2-filter-container");
|
||||
if (!filterContainer) return;
|
||||
|
||||
const pills = filterContainer.querySelectorAll(".v2-pill");
|
||||
const searchInput = filterContainer.querySelector(".v2-search-input");
|
||||
|
||||
let tagText = tagSpan.textContent.trim().replace(/[\[\]]/g, "").toUpperCase();
|
||||
if (tagText.includes("CONTENT")) tagText = tagText.replace(" CONTENT", "");
|
||||
|
||||
const matchingPill = Array.from(pills).find(p => p.getAttribute("data-filter") === tagText);
|
||||
if (matchingPill) {
|
||||
// Reset search, then activate the matching maturity pill.
|
||||
searchInput.value = "";
|
||||
searchInput.dispatchEvent(new Event("input", { bubbles: true }));
|
||||
matchingPill.click();
|
||||
} else {
|
||||
// Treat fine-grained technical tags as a search query.
|
||||
const allPill = Array.from(pills).find(p => p.getAttribute("data-filter") === "all");
|
||||
if (allPill) allPill.click();
|
||||
searchInput.value = tagSpan.textContent.trim().toLowerCase();
|
||||
searchInput.dispatchEvent(new Event("input", { bubbles: true }));
|
||||
}
|
||||
filterContainer.scrollIntoView({ behavior: "smooth", block: "nearest" });
|
||||
});
|
||||
}
|
||||
|
||||
// Lazy YouTube playback: click a poster to swap in the iframe.
|
||||
function initLazyVideos() {
|
||||
document.querySelectorAll(".video-lazy-container").forEach(container => {
|
||||
if (container.dataset.lazyBound) return;
|
||||
container.dataset.lazyBound = "1";
|
||||
container.addEventListener("click", function () {
|
||||
const videoUrl = this.getAttribute("data-video-url");
|
||||
const videoId = this.getAttribute("data-video-id");
|
||||
if (!videoUrl || !videoId) return;
|
||||
|
||||
const iframe = document.createElement("iframe");
|
||||
iframe.setAttribute("width", "720");
|
||||
iframe.setAttribute("height", "405");
|
||||
const autoplayUrl = videoUrl.includes("?") ? `${videoUrl}&autoplay=1` : `${videoUrl}?autoplay=1`;
|
||||
iframe.setAttribute("src", autoplayUrl);
|
||||
iframe.setAttribute("title", "YouTube Video");
|
||||
iframe.setAttribute("frameborder", "0");
|
||||
iframe.setAttribute("allow", "accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture");
|
||||
iframe.setAttribute("allowfullscreen", "true");
|
||||
iframe.style.border = "none";
|
||||
iframe.style.width = "100%";
|
||||
iframe.style.height = "100%";
|
||||
iframe.style.borderRadius = "8px";
|
||||
|
||||
this.innerHTML = "";
|
||||
this.appendChild(iframe);
|
||||
this.style.cursor = "default";
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
function init() {
|
||||
initFilterWidget();
|
||||
initLazyVideos();
|
||||
}
|
||||
|
||||
bindTagClicksOnce();
|
||||
|
||||
// Material exposes `document$` (an RxJS observable) that emits on every
|
||||
// instant navigation. Prefer it; fall back to DOMContentLoaded otherwise.
|
||||
if (typeof window.document$ !== "undefined" && typeof window.document$.subscribe === "function") {
|
||||
window.document$.subscribe(init);
|
||||
} else {
|
||||
document.addEventListener("DOMContentLoaded", init);
|
||||
}
|
||||
})();
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
mkdocs-material>=9.7.6
|
||||
pymdown-extensions>=10.21.3
|
||||
pymdown-extensions>=11.0
|
||||
yt-dlp
|
||||
youtube-transcript-api
|
||||
mkdocs-redirects>=1.2.3
|
||||
mkdocs-minify-plugin>=0.8.0
|
||||
mkdocs-rss-plugin>=1.19.0
|
||||
mkdocs-git-revision-date-localized-plugin>=1.5.3
|
||||
|
||||
@@ -0,0 +1,59 @@
|
||||
"""
|
||||
Backfill script: adds discovered_at to inventory entries that lack it.
|
||||
Priority: gh_pushed > last_checked > year > default "2024-01-01T00:00:00"
|
||||
Run once: python -m scripts.backfill_discovered_at
|
||||
"""
|
||||
import sys
|
||||
import os
|
||||
sys.path.insert(0, os.path.dirname(os.path.dirname(os.path.abspath(__file__))))
|
||||
|
||||
from datetime import datetime
|
||||
from src.inventory_manager import load_inventory, save_inventory
|
||||
from src.config import MADRID_TZ
|
||||
|
||||
|
||||
def backfill():
|
||||
inv = load_inventory()
|
||||
updated = 0
|
||||
total = 0
|
||||
|
||||
for url, entry in inv.items():
|
||||
if not isinstance(entry, dict):
|
||||
continue
|
||||
total += 1
|
||||
if entry.get("discovered_at"):
|
||||
continue
|
||||
|
||||
discovered = None
|
||||
|
||||
gh_pushed = entry.get("gh_pushed")
|
||||
if gh_pushed and isinstance(gh_pushed, str) and len(gh_pushed) >= 10:
|
||||
discovered = gh_pushed
|
||||
|
||||
if not discovered:
|
||||
last_checked = entry.get("last_checked")
|
||||
if isinstance(last_checked, (int, float)) and last_checked > 0:
|
||||
try:
|
||||
discovered = datetime.fromtimestamp(last_checked, tz=MADRID_TZ).isoformat()
|
||||
except (OSError, ValueError):
|
||||
pass
|
||||
|
||||
if not discovered:
|
||||
year = entry.get("year", "")
|
||||
if isinstance(year, str) and year.isdigit() and len(year) == 4:
|
||||
discovered = f"{year}-06-01T00:00:00+02:00"
|
||||
elif isinstance(year, int):
|
||||
discovered = f"{year}-06-01T00:00:00+02:00"
|
||||
|
||||
if not discovered:
|
||||
discovered = "2024-01-01T00:00:00+02:00"
|
||||
|
||||
entry["discovered_at"] = discovered
|
||||
updated += 1
|
||||
|
||||
print(f"Backfill complete: {updated}/{total} entries updated with discovered_at")
|
||||
save_inventory(inv)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
backfill()
|
||||
@@ -0,0 +1,57 @@
|
||||
"""MkDocs build hooks for the Nubenetes V2 portal.
|
||||
|
||||
Auto-versions cache-busted static assets so a CSS/JS change never goes stale
|
||||
behind a hand-maintained `?v=` query string again (see v2.9.45 regression where
|
||||
the Trending "Show more" disclosure was invisible to returning visitors because
|
||||
`?v=` was pinned to 2.9.42).
|
||||
|
||||
The version is resolved from, in order:
|
||||
1. $SITE_VERSION (set explicitly by the deploy workflow)
|
||||
2. the latest git tag (`git describe --tags --abbrev=0`)
|
||||
If neither is available (e.g. a local `mkdocs serve` in a shallow checkout),
|
||||
the asset URLs are left untouched so the build never fails.
|
||||
"""
|
||||
import os
|
||||
import subprocess
|
||||
|
||||
# Static assets whose URL should carry the release version as a cache-buster.
|
||||
_VERSIONED_ASSETS = ("v2_elite.css", "v2_filter.js")
|
||||
|
||||
|
||||
def _resolve_version():
|
||||
v = os.environ.get("SITE_VERSION", "").strip()
|
||||
if not v:
|
||||
try:
|
||||
v = subprocess.check_output(
|
||||
["git", "describe", "--tags", "--abbrev=0"],
|
||||
stderr=subprocess.DEVNULL,
|
||||
).decode().strip()
|
||||
except Exception:
|
||||
return None
|
||||
return v.lstrip("v") or None
|
||||
|
||||
|
||||
def _bump(items, version):
|
||||
out = []
|
||||
for item in items:
|
||||
# extra_javascript entries may be plain strings or ExtraScript objects.
|
||||
path = item if isinstance(item, str) else getattr(item, "path", None)
|
||||
if path and any(name in path for name in _VERSIONED_ASSETS):
|
||||
new_path = f"{path.split('?')[0]}?v={version}"
|
||||
if isinstance(item, str):
|
||||
out.append(new_path)
|
||||
else:
|
||||
item.path = new_path
|
||||
out.append(item)
|
||||
else:
|
||||
out.append(item)
|
||||
return out
|
||||
|
||||
|
||||
def on_config(config, **kwargs):
|
||||
version = _resolve_version()
|
||||
if not version:
|
||||
return config
|
||||
config["extra_css"] = _bump(config.get("extra_css", []), version)
|
||||
config["extra_javascript"] = _bump(config.get("extra_javascript", []), version)
|
||||
return config
|
||||
@@ -0,0 +1,53 @@
|
||||
"""One-off migration: normalize `gh_pushed` to None.
|
||||
|
||||
The enrichment writers historically stored the string "N/A" in the date
|
||||
field `gh_pushed` when GitHub data was unavailable. That literal reached
|
||||
`datetime.fromisoformat()` in the safety audit and curator, producing
|
||||
"Invalid isoformat string: 'N/A'" warnings (and, combined with other null
|
||||
fields, an aborted audit). The writers now emit None; this script cleans
|
||||
the existing inventory so the stored data matches.
|
||||
|
||||
Usage:
|
||||
python3 -m scripts.normalize_gh_pushed --dry-run # report only
|
||||
python3 -m scripts.normalize_gh_pushed # apply + save (YAML+SQL)
|
||||
|
||||
NOTE: save_inventory() round-trips through in-memory SQLite, and SQLite's
|
||||
iterdump renders REAL columns (e.g. epoch timestamps) with version-specific
|
||||
float precision. Running this on a machine whose SQLite differs from the one
|
||||
that generated the committed inventory.sql will rewrite ~all rows with no
|
||||
semantic change. Run it in CI (same SQLite as the pipeline) so the committed
|
||||
diff stays limited to the actual gh_pushed values.
|
||||
"""
|
||||
import sys
|
||||
|
||||
from src.inventory_manager import load_inventory, save_inventory
|
||||
from src.logger import log_event
|
||||
|
||||
BAD_VALUES = {"N/A", "NONE", ""}
|
||||
|
||||
|
||||
def main(dry_run: bool):
|
||||
inv = load_inventory()
|
||||
changed = 0
|
||||
for url, meta in inv.items():
|
||||
if not isinstance(meta, dict):
|
||||
continue
|
||||
pushed = meta.get("gh_pushed")
|
||||
if isinstance(pushed, str) and pushed.strip().upper() in BAD_VALUES:
|
||||
changed += 1
|
||||
if not dry_run:
|
||||
meta["gh_pushed"] = None
|
||||
|
||||
log_event(f"[Migration] gh_pushed normalize: {changed} entries with non-date value")
|
||||
if dry_run:
|
||||
log_event("[Migration] dry-run — no files written")
|
||||
return
|
||||
if changed:
|
||||
save_inventory(inv)
|
||||
log_event(f"[Migration] saved inventory (YAML+SQL); normalized {changed} entries")
|
||||
else:
|
||||
log_event("[Migration] nothing to change")
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main(dry_run="--dry-run" in sys.argv)
|
||||
@@ -3217,7 +3217,7 @@
|
||||
<h4 id="terraform-boilerplates">Terraform Boilerplates<a class="headerlink" href="#terraform-boilerplates" title="Permanent link">¶</a></h4>
|
||||
<details class="note">
|
||||
<summary>Terraform Kubernetes Boilerplates 🌟</summary>
|
||||
<p><strong><a href="https://nubenetes.com/terraform">Access Resource</a></strong> 🌟🌟🌟🌟🌟 | Level: Advanced</p>
|
||||
<p><strong><a href="https://nubenetes.com/terraform/">Access Resource</a></strong> 🌟🌟🌟🌟🌟 | Level: Advanced</p>
|
||||
<p>A library of enterprise-stable Terraform templates configured specifically for modern Kubernetes environments (EKS, GKE, AKS). Includes pre-tested infrastructure specifications for VPC topologies, private nodes, and dynamic ingress setups.</p>
|
||||
</details>
|
||||
<h4 id="terraform-provider">Terraform Provider<a class="headerlink" href="#terraform-provider" title="Permanent link">¶</a></h4>
|
||||
|
||||
@@ -900,6 +900,79 @@
|
||||
</span>
|
||||
</a>
|
||||
|
||||
</li>
|
||||
|
||||
<li class="md-nav__item">
|
||||
<a href="#ai-and-agents" class="md-nav__link">
|
||||
<span class="md-ellipsis">
|
||||
|
||||
AI and Agents
|
||||
|
||||
</span>
|
||||
</a>
|
||||
|
||||
<nav class="md-nav" aria-label="AI and Agents">
|
||||
<ul class="md-nav__list">
|
||||
|
||||
<li class="md-nav__item">
|
||||
<a href="#environments" class="md-nav__link">
|
||||
<span class="md-ellipsis">
|
||||
|
||||
Environments
|
||||
|
||||
</span>
|
||||
</a>
|
||||
|
||||
<nav class="md-nav" aria-label="Environments">
|
||||
<ul class="md-nav__list">
|
||||
|
||||
<li class="md-nav__item">
|
||||
<a href="#claude" class="md-nav__link">
|
||||
<span class="md-ellipsis">
|
||||
|
||||
Claude
|
||||
|
||||
</span>
|
||||
</a>
|
||||
|
||||
</li>
|
||||
|
||||
</ul>
|
||||
</nav>
|
||||
|
||||
</li>
|
||||
|
||||
<li class="md-nav__item">
|
||||
<a href="#frameworks" class="md-nav__link">
|
||||
<span class="md-ellipsis">
|
||||
|
||||
Frameworks
|
||||
|
||||
</span>
|
||||
</a>
|
||||
|
||||
<nav class="md-nav" aria-label="Frameworks">
|
||||
<ul class="md-nav__list">
|
||||
|
||||
<li class="md-nav__item">
|
||||
<a href="#google-cloud" class="md-nav__link">
|
||||
<span class="md-ellipsis">
|
||||
|
||||
Google Cloud
|
||||
|
||||
</span>
|
||||
</a>
|
||||
|
||||
</li>
|
||||
|
||||
</ul>
|
||||
</nav>
|
||||
|
||||
</li>
|
||||
|
||||
</ul>
|
||||
</nav>
|
||||
|
||||
</li>
|
||||
|
||||
<li class="md-nav__item">
|
||||
@@ -940,34 +1013,6 @@
|
||||
</ul>
|
||||
</nav>
|
||||
|
||||
</li>
|
||||
|
||||
<li class="md-nav__item">
|
||||
<a href="#agentic-frameworks" class="md-nav__link">
|
||||
<span class="md-ellipsis">
|
||||
|
||||
Agentic Frameworks
|
||||
|
||||
</span>
|
||||
</a>
|
||||
|
||||
<nav class="md-nav" aria-label="Agentic Frameworks">
|
||||
<ul class="md-nav__list">
|
||||
|
||||
<li class="md-nav__item">
|
||||
<a href="#developer-experience" class="md-nav__link">
|
||||
<span class="md-ellipsis">
|
||||
|
||||
Developer Experience
|
||||
|
||||
</span>
|
||||
</a>
|
||||
|
||||
</li>
|
||||
|
||||
</ul>
|
||||
</nav>
|
||||
|
||||
</li>
|
||||
|
||||
<li class="md-nav__item">
|
||||
@@ -1005,10 +1050,10 @@
|
||||
</li>
|
||||
|
||||
<li class="md-nav__item">
|
||||
<a href="#developer-experience-1" class="md-nav__link">
|
||||
<a href="#developer-experience" class="md-nav__link">
|
||||
<span class="md-ellipsis">
|
||||
|
||||
Developer Experience (1)
|
||||
Developer Experience
|
||||
|
||||
</span>
|
||||
</a>
|
||||
@@ -1016,10 +1061,10 @@
|
||||
</li>
|
||||
|
||||
<li class="md-nav__item">
|
||||
<a href="#google-cloud" class="md-nav__link">
|
||||
<a href="#google-cloud-1" class="md-nav__link">
|
||||
<span class="md-ellipsis">
|
||||
|
||||
Google Cloud
|
||||
Google Cloud (1)
|
||||
|
||||
</span>
|
||||
</a>
|
||||
@@ -1213,51 +1258,6 @@
|
||||
</ul>
|
||||
</nav>
|
||||
|
||||
</li>
|
||||
|
||||
<li class="md-nav__item">
|
||||
<a href="#automation" class="md-nav__link">
|
||||
<span class="md-ellipsis">
|
||||
|
||||
Automation
|
||||
|
||||
</span>
|
||||
</a>
|
||||
|
||||
<nav class="md-nav" aria-label="Automation">
|
||||
<ul class="md-nav__list">
|
||||
|
||||
<li class="md-nav__item">
|
||||
<a href="#agentic-systems" class="md-nav__link">
|
||||
<span class="md-ellipsis">
|
||||
|
||||
Agentic Systems
|
||||
|
||||
</span>
|
||||
</a>
|
||||
|
||||
<nav class="md-nav" aria-label="Agentic Systems">
|
||||
<ul class="md-nav__list">
|
||||
|
||||
<li class="md-nav__item">
|
||||
<a href="#mcp-server" class="md-nav__link">
|
||||
<span class="md-ellipsis">
|
||||
|
||||
MCP Server
|
||||
|
||||
</span>
|
||||
</a>
|
||||
|
||||
</li>
|
||||
|
||||
</ul>
|
||||
</nav>
|
||||
|
||||
</li>
|
||||
|
||||
</ul>
|
||||
</nav>
|
||||
|
||||
</li>
|
||||
|
||||
<li class="md-nav__item">
|
||||
@@ -1306,15 +1306,15 @@
|
||||
</li>
|
||||
|
||||
<li class="md-nav__item">
|
||||
<a href="#developer-experience-2" class="md-nav__link">
|
||||
<a href="#developer-experience-1" class="md-nav__link">
|
||||
<span class="md-ellipsis">
|
||||
|
||||
Developer Experience (2)
|
||||
Developer Experience (1)
|
||||
|
||||
</span>
|
||||
</a>
|
||||
|
||||
<nav class="md-nav" aria-label="Developer Experience (2)">
|
||||
<nav class="md-nav" aria-label="Developer Experience (1)">
|
||||
<ul class="md-nav__list">
|
||||
|
||||
<li class="md-nav__item">
|
||||
@@ -1338,17 +1338,6 @@
|
||||
</span>
|
||||
</a>
|
||||
|
||||
</li>
|
||||
|
||||
<li class="md-nav__item">
|
||||
<a href="#cursor-ide" class="md-nav__link">
|
||||
<span class="md-ellipsis">
|
||||
|
||||
Cursor IDE
|
||||
|
||||
</span>
|
||||
</a>
|
||||
|
||||
</li>
|
||||
|
||||
</ul>
|
||||
@@ -2410,20 +2399,25 @@
|
||||
</div>
|
||||
<h2 id="table-of-contents">Table of Contents<a class="headerlink" href="#table-of-contents" title="Permanent link">¶</a></h2>
|
||||
<ol>
|
||||
<li><a href="#ai-and-agents">AI and Agents</a></li>
|
||||
<li><a href="#environments">Environments</a><ul>
|
||||
<li><a href="#claude">Claude</a></li>
|
||||
</ul>
|
||||
</li>
|
||||
<li><a href="#frameworks">Frameworks</a><ul>
|
||||
<li><a href="#google-cloud">Google Cloud</a></li>
|
||||
</ul>
|
||||
</li>
|
||||
<li><a href="#ai-engineering">AI Engineering</a></li>
|
||||
<li><a href="#ai-agents">AI Agents</a><ul>
|
||||
<li><a href="#web-automation">Web Automation</a></li>
|
||||
</ul>
|
||||
</li>
|
||||
<li><a href="#agentic-frameworks">Agentic Frameworks</a><ul>
|
||||
<li><a href="#developer-experience">Developer Experience</a></li>
|
||||
</ul>
|
||||
</li>
|
||||
<li><a href="#model-context-protocol">Model Context Protocol</a><ul>
|
||||
<li><a href="#architecture">Architecture</a></li>
|
||||
<li><a href="#awesome-lists">Awesome Lists</a></li>
|
||||
<li><a href="#developer-experience-1">Developer Experience</a></li>
|
||||
<li><a href="#google-cloud">Google Cloud</a></li>
|
||||
<li><a href="#developer-experience">Developer Experience</a></li>
|
||||
<li><a href="#google-cloud-1">Google Cloud</a></li>
|
||||
<li><a href="#official-servers">Official Servers</a></li>
|
||||
<li><a href="#specifications">Specifications</a></li>
|
||||
</ul>
|
||||
@@ -2447,20 +2441,14 @@
|
||||
<li><a href="#general-reference">General Reference</a></li>
|
||||
</ul>
|
||||
</li>
|
||||
<li><a href="#automation">Automation</a></li>
|
||||
<li><a href="#agentic-systems">Agentic Systems</a><ul>
|
||||
<li><a href="#mcp-server">MCP Server</a></li>
|
||||
</ul>
|
||||
</li>
|
||||
<li><a href="#cloud-native-operations">Cloud Native Operations</a></li>
|
||||
<li><a href="#ai-aiops">AI AIOps</a><ul>
|
||||
<li><a href="#kubernetes-troubleshooting">Kubernetes Troubleshooting</a></li>
|
||||
</ul>
|
||||
</li>
|
||||
<li><a href="#developer-experience-2">Developer Experience</a></li>
|
||||
<li><a href="#developer-experience-1">Developer Experience</a></li>
|
||||
<li><a href="#ai-assisted-coding">AI-Assisted Coding</a><ul>
|
||||
<li><a href="#claude-code">Claude Code</a></li>
|
||||
<li><a href="#cursor-ide">Cursor IDE</a></li>
|
||||
</ul>
|
||||
</li>
|
||||
<li><a href="#software-engineering">Software Engineering</a></li>
|
||||
@@ -2469,17 +2457,25 @@
|
||||
</ul>
|
||||
</li>
|
||||
</ol>
|
||||
<h2 id="ai-and-agents">AI and Agents<a class="headerlink" href="#ai-and-agents" title="Permanent link">¶</a></h2>
|
||||
<h3 id="environments">Environments<a class="headerlink" href="#environments" title="Permanent link">¶</a></h3>
|
||||
<h4 id="claude">Claude<a class="headerlink" href="#claude" title="Permanent link">¶</a></h4>
|
||||
<ul>
|
||||
<li><strong>(2025)</strong> <a href="https://docs.anthropic.com/en/docs/agents-and-tools/claude-code/overview"><mark>docs.anthropic.com: Claude Code CLI</mark></a> 🌟🌟🌟🌟🌟 <span class='md-tag md-tag--success'>[DE FACTO STANDARD]</span> — Anthropic's official command-line interface (CLI) tool designed for autonomous agentic software engineering.
|
||||
Claude Code can read codebases, execute commands, run tests, and manage git workflows directly in terminal environments.</li>
|
||||
</ul>
|
||||
<h3 id="frameworks">Frameworks<a class="headerlink" href="#frameworks" title="Permanent link">¶</a></h3>
|
||||
<h4 id="google-cloud">Google Cloud<a class="headerlink" href="#google-cloud" title="Permanent link">¶</a></h4>
|
||||
<ul>
|
||||
<li><strong>(2026)</strong> <a href="https://antigravity.google"><mark>antigravity.google: Google Antigravity Agentic Platform</mark></a> <span class='md-tag md-tag--warning'>[PYTHON CONTENT]</span> <span class='md-tag md-tag--critical'>[ADVANCED LEVEL]</span> 🌟🌟🌟🌟🌟 <span class='md-tag md-tag--success'>[DE FACTO STANDARD]</span> — Google's unified development platform and SDK (google-antigravity) for building, evaluating, and deploying stateful AI agents.
|
||||
Enables developers to transition from local prototype builds to secure GKE production environments and leverage the Gemini Enterprise Agent Platform.</li>
|
||||
</ul>
|
||||
<h2 id="ai-engineering">AI Engineering<a class="headerlink" href="#ai-engineering" title="Permanent link">¶</a></h2>
|
||||
<h3 id="ai-agents">AI Agents<a class="headerlink" href="#ai-agents" title="Permanent link">¶</a></h3>
|
||||
<h4 id="web-automation">Web Automation<a class="headerlink" href="#web-automation" title="Permanent link">¶</a></h4>
|
||||
<ul>
|
||||
<li><strong>(2025)</strong> <a href="https://github.com/Skyvern-ai/Skyvern"><mark>Skyvern</mark></a> <span class='md-tag md-tag--info'>⭐ 21899</span> <svg class="v2-sparkline" width="50" height="15" viewBox="0 0 50 15" style="vertical-align: middle; display: inline-block; margin-left: 6px;" title="Activity Trend"><defs><linearGradient id="spark-grad-3038a3b2" x1="0" y1="0" x2="1" y2="0"><stop offset="0%" stop-color="rgba(34, 211, 238, 0.2)" /><stop offset="100%" stop-color="var(--md-accent-fg-color)" /></linearGradient></defs><path class="v2-sparkline-path" d="M 0 2 L 10 12 L 20 13 L 30 3 L 40 11 L 50 5" fill="none" stroke="url(#spark-grad-3038a3b2)" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round" /><circle cx="50" cy="5" r="2" fill="var(--md-accent-fg-color)" /></svg> <span class='md-tag md-tag--warning'>[PYTHON CONTENT]</span> <span class='md-tag md-tag--critical'>[ADVANCED LEVEL]</span> 🌟🌟🌟🌟🌟 <span class='md-tag md-tag--success'>[DE FACTO STANDARD]</span> — Curator Insight: An AI-powered web browser automation agent designed to extract data and execute workflows on complex interfaces. Live Grounding: Translates plain-text instructions into resilient selenium-style interactions, dynamically adapting to DOM mutations and bypassing rigid selector patterns.</li>
|
||||
</ul>
|
||||
<h3 id="agentic-frameworks">Agentic Frameworks<a class="headerlink" href="#agentic-frameworks" title="Permanent link">¶</a></h3>
|
||||
<h4 id="developer-experience">Developer Experience<a class="headerlink" href="#developer-experience" title="Permanent link">¶</a></h4>
|
||||
<ul>
|
||||
<li><strong>(2025)</strong> <a href="https://kiro.dev">Kiro: Engineering Rigor for Agentic Development</a> <span class='md-tag md-tag--warning'>[TYPESCRIPT CONTENT]</span> <span class='md-tag md-tag--critical'>[ADVANCED LEVEL]</span> <span class='md-tag md-tag--info'>[COMMUNITY-TOOL]</span> — Kiro is a testing and engineering framework designed to bring traditional software discipline—such as regression testing, linting, and sandbox executing—to LLM agents and multi-agent workflows. It establishes strict validation steps to ensure agent behaviors remain deterministic, secure, and aligned with standard corporate software engineering guidelines.</li>
|
||||
</ul>
|
||||
<h3 id="model-context-protocol">Model Context Protocol<a class="headerlink" href="#model-context-protocol" title="Permanent link">¶</a></h3>
|
||||
<h4 id="architecture">Architecture<a class="headerlink" href="#architecture" title="Permanent link">¶</a></h4>
|
||||
<ul>
|
||||
@@ -2489,11 +2485,11 @@
|
||||
<ul>
|
||||
<li><strong>(2025)</strong> <a href="https://github.com/punkpeye/awesome-mcp-servers"><mark>Awesome MCP Servers</mark></a> <span class='md-tag md-tag--info'>⭐ 89112</span> <svg class="v2-sparkline" width="50" height="15" viewBox="0 0 50 15" style="vertical-align: middle; display: inline-block; margin-left: 6px;" title="Activity Trend"><defs><linearGradient id="spark-grad-396cb5e3" x1="0" y1="0" x2="1" y2="0"><stop offset="0%" stop-color="rgba(34, 211, 238, 0.2)" /><stop offset="100%" stop-color="var(--md-accent-fg-color)" /></linearGradient></defs><path class="v2-sparkline-path" d="M 0 12 L 10 4 L 20 9 L 30 10 L 40 3 L 50 5" fill="none" stroke="url(#spark-grad-396cb5e3)" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round" /><circle cx="50" cy="5" r="2" fill="var(--md-accent-fg-color)" /></svg> <span class='md-tag md-tag--warning'>[MARKDOWN CONTENT]</span> 🌟🌟🌟🌟🌟 <span class='md-tag md-tag--success'>[DE FACTO STANDARD]</span> <span class='md-tag md-tag--secondary'>[GUIDE]</span> — Curator Insight: A community-curated collection of servers implementing the Model Context Protocol. Live Grounding: Aggregates verified integrations linking AI models to tools like relational databases, enterprise APIs, version control providers, and local execution runtimes.</li>
|
||||
</ul>
|
||||
<h4 id="developer-experience-1">Developer Experience (1)<a class="headerlink" href="#developer-experience-1" title="Permanent link">¶</a></h4>
|
||||
<h4 id="developer-experience">Developer Experience<a class="headerlink" href="#developer-experience" title="Permanent link">¶</a></h4>
|
||||
<ul>
|
||||
<li><strong>(2025)</strong> <a href="https://www.mcpbundles.com">MCPBundles</a> <span class='md-tag md-tag--warning'>[TYPESCRIPT CONTENT]</span> <span class='md-tag md-tag--info'>[COMMUNITY-TOOL]</span> — MCPBundles is a discovery and packaging platform designed to bundle various Model Context Protocol servers for rapid deployment. It simplifies agentic application building by providing curated, pre-configured groupings of tools (e.g., database drivers, git utilities, API endpoints) that can be integrated into AI hosts in a single setup operation.</li>
|
||||
</ul>
|
||||
<h4 id="google-cloud">Google Cloud<a class="headerlink" href="#google-cloud" title="Permanent link">¶</a></h4>
|
||||
<h4 id="google-cloud-1">Google Cloud (1)<a class="headerlink" href="#google-cloud-1" title="Permanent link">¶</a></h4>
|
||||
<ul>
|
||||
<li><strong>(2025)</strong> <a href="https://cloud.google.com/blog/products/ai-machine-learning/google-cloud-managed-mcp-for-gemini">Google Cloud Managed MCP</a> <span class='md-tag md-tag--warning'>[NONE CONTENT]</span> <span class='md-tag md-tag--critical'>[ADVANCED LEVEL]</span> <span class='md-tag md-tag--info'>[COMMUNITY-TOOL]</span> — Google Cloud's managed solution for Model Context Protocol, allowing enterprise Gemini models to safely interact with local data sources and external enterprise systems. By hosting and scaling MCP servers inside Google's managed environment, it minimizes operational overhead while securing transactional agentic workflows with native cloud IAM.</li>
|
||||
</ul>
|
||||
@@ -2532,28 +2528,17 @@
|
||||
<li><a href="https://t.co/EKsVgKA4xn">IBM IAM for AI Agents</a> <span class='md-tag md-tag--info'>[COMMUNITY-TOOL]</span> — A curated technical resource and architectural guide covering IBM IAM for AI Agents in the Kubernetes Tools ecosystem.</li>
|
||||
<li><a href="https://pulsemcp.com">PulseMCP</a> <span class='md-tag md-tag--info'>[COMMUNITY-TOOL]</span> — A curated technical resource and architectural guide covering PulseMCP in the Kubernetes Tools ecosystem.</li>
|
||||
</ul>
|
||||
<h2 id="automation">Automation<a class="headerlink" href="#automation" title="Permanent link">¶</a></h2>
|
||||
<h3 id="agentic-systems">Agentic Systems<a class="headerlink" href="#agentic-systems" title="Permanent link">¶</a></h3>
|
||||
<h4 id="mcp-server">MCP Server<a class="headerlink" href="#mcp-server" title="Permanent link">¶</a></h4>
|
||||
<ul>
|
||||
<li><strong>(2026)</strong> <a href="https://devblogs.microsoft.com/azure-sdk/announcing-azure-mcp-server-2-0-stable-release">Announcing Azure MCP Server 2.0 Stable Release for Self-Hosted Agentic Cloud Automation</a> <span class='md-tag md-tag--warning'>[TYPESCRIPT CONTENT]</span> <span class='md-tag md-tag--critical'>[ADVANCED LEVEL]</span> <span class='md-tag md-tag--info'>[COMMUNITY-TOOL]</span> — Details the stable release of Azure MCP (Model Context Protocol) Server 2.0, enabling secure, self-hosted agentic automation workflows. It provides architectural patterns for running local AI agents with direct, API-driven access to Azure resource management, optimizing operational automation via language model integrations.</li>
|
||||
</ul>
|
||||
<h2 id="cloud-native-operations">Cloud Native Operations<a class="headerlink" href="#cloud-native-operations" title="Permanent link">¶</a></h2>
|
||||
<h3 id="ai-aiops">AI AIOps<a class="headerlink" href="#ai-aiops" title="Permanent link">¶</a></h3>
|
||||
<h4 id="kubernetes-troubleshooting">Kubernetes Troubleshooting<a class="headerlink" href="#kubernetes-troubleshooting" title="Permanent link">¶</a></h4>
|
||||
<ul>
|
||||
<li><strong>(2025)</strong> <a href="https://github.com/HolmesGPT/holmesgpt">HolmesGPT (Robusta)</a> <span class='md-tag md-tag--info'>⭐ 2623</span> <svg class="v2-sparkline" width="50" height="15" viewBox="0 0 50 15" style="vertical-align: middle; display: inline-block; margin-left: 6px;" title="Activity Trend"><defs><linearGradient id="spark-grad-892577ed" x1="0" y1="0" x2="1" y2="0"><stop offset="0%" stop-color="rgba(34, 211, 238, 0.2)" /><stop offset="100%" stop-color="var(--md-accent-fg-color)" /></linearGradient></defs><path class="v2-sparkline-path" d="M 0 5 L 10 5 L 20 6 L 30 13 L 40 13 L 50 5" fill="none" stroke="url(#spark-grad-892577ed)" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round" /><circle cx="50" cy="5" r="2" fill="var(--md-accent-fg-color)" /></svg> <span class='md-tag md-tag--warning'>[PYTHON CONTENT]</span> <span class='md-tag md-tag--critical'>[ADVANCED LEVEL]</span> 🌟🌟 <span class='md-tag md-tag--info'>[COMMUNITY-TOOL]</span> — Curator Insight: An AI-driven troubleshooting assistant for Kubernetes clusters by Robusta. Live Grounding: Utilizes LLM agents to autonomously parse Prometheus alerts, collect pod logs, inspect live status, and deliver actionable remediation steps for infrastructure incidents.</li>
|
||||
</ul>
|
||||
<h2 id="developer-experience-2">Developer Experience (2)<a class="headerlink" href="#developer-experience-2" title="Permanent link">¶</a></h2>
|
||||
<h2 id="developer-experience-1">Developer Experience (1)<a class="headerlink" href="#developer-experience-1" title="Permanent link">¶</a></h2>
|
||||
<h3 id="ai-assisted-coding">AI-Assisted Coding<a class="headerlink" href="#ai-assisted-coding" title="Permanent link">¶</a></h3>
|
||||
<h4 id="claude-code">Claude Code<a class="headerlink" href="#claude-code" title="Permanent link">¶</a></h4>
|
||||
<ul>
|
||||
<li><strong>(2025)</strong> <a href="https://github.com/shanraisshan/claude-code-best-practice"><mark>Claude Code Best Practice</mark></a> <span class='md-tag md-tag--info'>⭐ 57660</span> <svg class="v2-sparkline" width="50" height="15" viewBox="0 0 50 15" style="vertical-align: middle; display: inline-block; margin-left: 6px;" title="Activity Trend"><defs><linearGradient id="spark-grad-26ea52d5" x1="0" y1="0" x2="1" y2="0"><stop offset="0%" stop-color="rgba(34, 211, 238, 0.2)" /><stop offset="100%" stop-color="var(--md-accent-fg-color)" /></linearGradient></defs><path class="v2-sparkline-path" d="M 0 3 L 10 2 L 20 3 L 30 5 L 40 3 L 50 2" fill="none" stroke="url(#spark-grad-26ea52d5)" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round" /><circle cx="50" cy="2" r="2" fill="var(--md-accent-fg-color)" /></svg> <span class='md-tag md-tag--warning'>[MARKDOWN CONTENT]</span> 🌟🌟🌟🌟🌟 <span class='md-tag md-tag--success'>[DE FACTO STANDARD]</span> <span class='md-tag md-tag--secondary'>[GUIDE]</span> — Curator Insight: Curated collection of best practices, system prompts, and architecture layouts for Claude Code. Live Grounding: Explores advanced CLI-driven agent workflows, highlighting configuration optimizations, shell integration strategies, and secure execution configurations in local and remote environments.</li>
|
||||
<li><strong>(2025)</strong> <a href="https://anthropic.skilljar.com/claude-code-in-action">Claude Code in Action</a> <span class='md-tag md-tag--warning'>[NONE CONTENT]</span> <span class='md-tag md-tag--info'>[COMMUNITY-TOOL]</span> <span class='md-tag md-tag--secondary'>[GUIDE]</span> — An official hands-on tutorial and demonstration course by Anthropic showing the real-world utility of Claude Code. It covers basic terminal setups, interactive file refactoring, automated git commit orchestration, and contextual testing loops. Highly valuable for teams integrating terminal-based AI agents directly into daily engineering pipelines.</li>
|
||||
</ul>
|
||||
<h4 id="cursor-ide">Cursor IDE<a class="headerlink" href="#cursor-ide" title="Permanent link">¶</a></h4>
|
||||
<ul>
|
||||
<li><strong>(2025)</strong> <a href="https://cursor.com/es/learn">Cursor AI Fundamentals Course</a> <span class='md-tag md-tag--warning'>[NONE CONTENT]</span> <span class='md-tag md-tag--secondary'>[GUIDE]</span> <span class='md-tag md-tag--critical'>[LEGACY]</span> — An educational program designed to train engineers on utilizing the Cursor AI code editor effectively. The curriculum covers foundational concepts of context inclusion, codebase indexing, and multi-file code transformations. It teaches developers how to write highly optimized prompts to synthesize software architecture and debug legacy systems directly inside the IDE.</li>
|
||||
</ul>
|
||||
<h2 id="software-engineering">Software Engineering<a class="headerlink" href="#software-engineering" title="Permanent link">¶</a></h2>
|
||||
<h3 id="ai-tools">AI Tools<a class="headerlink" href="#ai-tools" title="Permanent link">¶</a></h3>
|
||||
|
||||
@@ -1469,62 +1469,6 @@
|
||||
</ul>
|
||||
</nav>
|
||||
|
||||
</li>
|
||||
|
||||
<li class="md-nav__item">
|
||||
<a href="#cicd-pipelines" class="md-nav__link">
|
||||
<span class="md-ellipsis">
|
||||
|
||||
CICD Pipelines
|
||||
|
||||
</span>
|
||||
</a>
|
||||
|
||||
<nav class="md-nav" aria-label="CICD Pipelines">
|
||||
<ul class="md-nav__list">
|
||||
|
||||
<li class="md-nav__item">
|
||||
<a href="#ai-and-automation" class="md-nav__link">
|
||||
<span class="md-ellipsis">
|
||||
|
||||
AI and Automation
|
||||
|
||||
</span>
|
||||
</a>
|
||||
|
||||
<nav class="md-nav" aria-label="AI and Automation">
|
||||
<ul class="md-nav__list">
|
||||
|
||||
<li class="md-nav__item">
|
||||
<a href="#ai-pr-automation" class="md-nav__link">
|
||||
<span class="md-ellipsis">
|
||||
|
||||
AI PR Automation
|
||||
|
||||
</span>
|
||||
</a>
|
||||
|
||||
</li>
|
||||
|
||||
<li class="md-nav__item">
|
||||
<a href="#model-context-protocol-1" class="md-nav__link">
|
||||
<span class="md-ellipsis">
|
||||
|
||||
Model Context Protocol (1)
|
||||
|
||||
</span>
|
||||
</a>
|
||||
|
||||
</li>
|
||||
|
||||
</ul>
|
||||
</nav>
|
||||
|
||||
</li>
|
||||
|
||||
</ul>
|
||||
</nav>
|
||||
|
||||
</li>
|
||||
|
||||
<li class="md-nav__item">
|
||||
@@ -1794,51 +1738,6 @@
|
||||
</ul>
|
||||
</nav>
|
||||
|
||||
</li>
|
||||
|
||||
<li class="md-nav__item">
|
||||
<a href="#container-orchestration" class="md-nav__link">
|
||||
<span class="md-ellipsis">
|
||||
|
||||
Container Orchestration
|
||||
|
||||
</span>
|
||||
</a>
|
||||
|
||||
<nav class="md-nav" aria-label="Container Orchestration">
|
||||
<ul class="md-nav__list">
|
||||
|
||||
<li class="md-nav__item">
|
||||
<a href="#azure-kubernetes-service" class="md-nav__link">
|
||||
<span class="md-ellipsis">
|
||||
|
||||
Azure Kubernetes Service
|
||||
|
||||
</span>
|
||||
</a>
|
||||
|
||||
<nav class="md-nav" aria-label="Azure Kubernetes Service">
|
||||
<ul class="md-nav__list">
|
||||
|
||||
<li class="md-nav__item">
|
||||
<a href="#aks-fleet-manager" class="md-nav__link">
|
||||
<span class="md-ellipsis">
|
||||
|
||||
AKS Fleet Manager
|
||||
|
||||
</span>
|
||||
</a>
|
||||
|
||||
</li>
|
||||
|
||||
</ul>
|
||||
</nav>
|
||||
|
||||
</li>
|
||||
|
||||
</ul>
|
||||
</nav>
|
||||
|
||||
</li>
|
||||
|
||||
<li class="md-nav__item">
|
||||
@@ -1879,51 +1778,6 @@
|
||||
</ul>
|
||||
</nav>
|
||||
|
||||
</li>
|
||||
|
||||
<li class="md-nav__item">
|
||||
<a href="#infrastructure-as-code-2" class="md-nav__link">
|
||||
<span class="md-ellipsis">
|
||||
|
||||
Infrastructure as Code (2)
|
||||
|
||||
</span>
|
||||
</a>
|
||||
|
||||
<nav class="md-nav" aria-label="Infrastructure as Code (2)">
|
||||
<ul class="md-nav__list">
|
||||
|
||||
<li class="md-nav__item">
|
||||
<a href="#ai-integration" class="md-nav__link">
|
||||
<span class="md-ellipsis">
|
||||
|
||||
AI Integration
|
||||
|
||||
</span>
|
||||
</a>
|
||||
|
||||
<nav class="md-nav" aria-label="AI Integration">
|
||||
<ul class="md-nav__list">
|
||||
|
||||
<li class="md-nav__item">
|
||||
<a href="#terraform" class="md-nav__link">
|
||||
<span class="md-ellipsis">
|
||||
|
||||
Terraform
|
||||
|
||||
</span>
|
||||
</a>
|
||||
|
||||
</li>
|
||||
|
||||
</ul>
|
||||
</nav>
|
||||
|
||||
</li>
|
||||
|
||||
</ul>
|
||||
</nav>
|
||||
|
||||
</li>
|
||||
|
||||
</ul>
|
||||
@@ -1974,6 +1828,51 @@
|
||||
</ul>
|
||||
</nav>
|
||||
|
||||
</li>
|
||||
|
||||
<li class="md-nav__item">
|
||||
<a href="#developer-productivity-1" class="md-nav__link">
|
||||
<span class="md-ellipsis">
|
||||
|
||||
Developer Productivity (1)
|
||||
|
||||
</span>
|
||||
</a>
|
||||
|
||||
<nav class="md-nav" aria-label="Developer Productivity (1)">
|
||||
<ul class="md-nav__list">
|
||||
|
||||
<li class="md-nav__item">
|
||||
<a href="#ides" class="md-nav__link">
|
||||
<span class="md-ellipsis">
|
||||
|
||||
IDEs
|
||||
|
||||
</span>
|
||||
</a>
|
||||
|
||||
<nav class="md-nav" aria-label="IDEs">
|
||||
<ul class="md-nav__list">
|
||||
|
||||
<li class="md-nav__item">
|
||||
<a href="#cursor" class="md-nav__link">
|
||||
<span class="md-ellipsis">
|
||||
|
||||
Cursor
|
||||
|
||||
</span>
|
||||
</a>
|
||||
|
||||
</li>
|
||||
|
||||
</ul>
|
||||
</nav>
|
||||
|
||||
</li>
|
||||
|
||||
</ul>
|
||||
</nav>
|
||||
|
||||
</li>
|
||||
|
||||
<li class="md-nav__item">
|
||||
@@ -2000,17 +1899,6 @@
|
||||
<nav class="md-nav" aria-label="AI Code Assistants">
|
||||
<ul class="md-nav__list">
|
||||
|
||||
<li class="md-nav__item">
|
||||
<a href="#effort-frameworks" class="md-nav__link">
|
||||
<span class="md-ellipsis">
|
||||
|
||||
Effort Frameworks
|
||||
|
||||
</span>
|
||||
</a>
|
||||
|
||||
</li>
|
||||
|
||||
<li class="md-nav__item">
|
||||
<a href="#prompt-templates" class="md-nav__link">
|
||||
<span class="md-ellipsis">
|
||||
@@ -2030,51 +1918,6 @@
|
||||
</ul>
|
||||
</nav>
|
||||
|
||||
</li>
|
||||
|
||||
<li class="md-nav__item">
|
||||
<a href="#emerging-technology" class="md-nav__link">
|
||||
<span class="md-ellipsis">
|
||||
|
||||
Emerging Technology
|
||||
|
||||
</span>
|
||||
</a>
|
||||
|
||||
<nav class="md-nav" aria-label="Emerging Technology">
|
||||
<ul class="md-nav__list">
|
||||
|
||||
<li class="md-nav__item">
|
||||
<a href="#machine-learning" class="md-nav__link">
|
||||
<span class="md-ellipsis">
|
||||
|
||||
Machine Learning
|
||||
|
||||
</span>
|
||||
</a>
|
||||
|
||||
<nav class="md-nav" aria-label="Machine Learning">
|
||||
<ul class="md-nav__list">
|
||||
|
||||
<li class="md-nav__item">
|
||||
<a href="#course" class="md-nav__link">
|
||||
<span class="md-ellipsis">
|
||||
|
||||
Course
|
||||
|
||||
</span>
|
||||
</a>
|
||||
|
||||
</li>
|
||||
|
||||
</ul>
|
||||
</nav>
|
||||
|
||||
</li>
|
||||
|
||||
</ul>
|
||||
</nav>
|
||||
|
||||
</li>
|
||||
|
||||
<li class="md-nav__item">
|
||||
@@ -2156,34 +1999,6 @@
|
||||
<nav class="md-nav" aria-label="FinOps and Cloud Cost">
|
||||
<ul class="md-nav__list">
|
||||
|
||||
<li class="md-nav__item">
|
||||
<a href="#azure-optimization" class="md-nav__link">
|
||||
<span class="md-ellipsis">
|
||||
|
||||
Azure Optimization
|
||||
|
||||
</span>
|
||||
</a>
|
||||
|
||||
<nav class="md-nav" aria-label="Azure Optimization">
|
||||
<ul class="md-nav__list">
|
||||
|
||||
<li class="md-nav__item">
|
||||
<a href="#ai-cost-management" class="md-nav__link">
|
||||
<span class="md-ellipsis">
|
||||
|
||||
AI Cost Management
|
||||
|
||||
</span>
|
||||
</a>
|
||||
|
||||
</li>
|
||||
|
||||
</ul>
|
||||
</nav>
|
||||
|
||||
</li>
|
||||
|
||||
<li class="md-nav__item">
|
||||
<a href="#iac-finops" class="md-nav__link">
|
||||
<span class="md-ellipsis">
|
||||
@@ -2210,79 +2025,6 @@
|
||||
</ul>
|
||||
</nav>
|
||||
|
||||
</li>
|
||||
|
||||
<li class="md-nav__item">
|
||||
<a href="#kubernetes-finops" class="md-nav__link">
|
||||
<span class="md-ellipsis">
|
||||
|
||||
Kubernetes FinOps
|
||||
|
||||
</span>
|
||||
</a>
|
||||
|
||||
<nav class="md-nav" aria-label="Kubernetes FinOps">
|
||||
<ul class="md-nav__list">
|
||||
|
||||
<li class="md-nav__item">
|
||||
<a href="#automated-optimization" class="md-nav__link">
|
||||
<span class="md-ellipsis">
|
||||
|
||||
Automated Optimization
|
||||
|
||||
</span>
|
||||
</a>
|
||||
|
||||
</li>
|
||||
|
||||
</ul>
|
||||
</nav>
|
||||
|
||||
</li>
|
||||
|
||||
</ul>
|
||||
</nav>
|
||||
|
||||
</li>
|
||||
|
||||
<li class="md-nav__item">
|
||||
<a href="#infrastructure-as-code-3" class="md-nav__link">
|
||||
<span class="md-ellipsis">
|
||||
|
||||
Infrastructure as Code (3)
|
||||
|
||||
</span>
|
||||
</a>
|
||||
|
||||
<nav class="md-nav" aria-label="Infrastructure as Code (3)">
|
||||
<ul class="md-nav__list">
|
||||
|
||||
<li class="md-nav__item">
|
||||
<a href="#ai-integrations" class="md-nav__link">
|
||||
<span class="md-ellipsis">
|
||||
|
||||
AI Integrations
|
||||
|
||||
</span>
|
||||
</a>
|
||||
|
||||
<nav class="md-nav" aria-label="AI Integrations">
|
||||
<ul class="md-nav__list">
|
||||
|
||||
<li class="md-nav__item">
|
||||
<a href="#validation-and-testing" class="md-nav__link">
|
||||
<span class="md-ellipsis">
|
||||
|
||||
Validation and Testing
|
||||
|
||||
</span>
|
||||
</a>
|
||||
|
||||
</li>
|
||||
|
||||
</ul>
|
||||
</nav>
|
||||
|
||||
</li>
|
||||
|
||||
</ul>
|
||||
@@ -2315,55 +2057,10 @@
|
||||
<ul class="md-nav__list">
|
||||
|
||||
<li class="md-nav__item">
|
||||
<a href="#ai-integration-1" class="md-nav__link">
|
||||
<a href="#ai-integration" class="md-nav__link">
|
||||
<span class="md-ellipsis">
|
||||
|
||||
AI Integration (1)
|
||||
|
||||
</span>
|
||||
</a>
|
||||
|
||||
</li>
|
||||
|
||||
</ul>
|
||||
</nav>
|
||||
|
||||
</li>
|
||||
|
||||
</ul>
|
||||
</nav>
|
||||
|
||||
</li>
|
||||
|
||||
<li class="md-nav__item">
|
||||
<a href="#software-architecture-and-net-development" class="md-nav__link">
|
||||
<span class="md-ellipsis">
|
||||
|
||||
Software Architecture and .NET Development
|
||||
|
||||
</span>
|
||||
</a>
|
||||
|
||||
<nav class="md-nav" aria-label="Software Architecture and .NET Development">
|
||||
<ul class="md-nav__list">
|
||||
|
||||
<li class="md-nav__item">
|
||||
<a href="#artificial-intelligence-2" class="md-nav__link">
|
||||
<span class="md-ellipsis">
|
||||
|
||||
Artificial Intelligence (2)
|
||||
|
||||
</span>
|
||||
</a>
|
||||
|
||||
<nav class="md-nav" aria-label="Artificial Intelligence (2)">
|
||||
<ul class="md-nav__list">
|
||||
|
||||
<li class="md-nav__item">
|
||||
<a href="#agent-integration" class="md-nav__link">
|
||||
<span class="md-ellipsis">
|
||||
|
||||
Agent Integration
|
||||
AI Integration
|
||||
|
||||
</span>
|
||||
</a>
|
||||
@@ -2392,34 +2089,6 @@
|
||||
<nav class="md-nav" aria-label="Software Engineering">
|
||||
<ul class="md-nav__list">
|
||||
|
||||
<li class="md-nav__item">
|
||||
<a href="#ai-tools" class="md-nav__link">
|
||||
<span class="md-ellipsis">
|
||||
|
||||
AI Tools
|
||||
|
||||
</span>
|
||||
</a>
|
||||
|
||||
<nav class="md-nav" aria-label="AI Tools">
|
||||
<ul class="md-nav__list">
|
||||
|
||||
<li class="md-nav__item">
|
||||
<a href="#developer-productivity-1" class="md-nav__link">
|
||||
<span class="md-ellipsis">
|
||||
|
||||
Developer Productivity (1)
|
||||
|
||||
</span>
|
||||
</a>
|
||||
|
||||
</li>
|
||||
|
||||
</ul>
|
||||
</nav>
|
||||
|
||||
</li>
|
||||
|
||||
<li class="md-nav__item">
|
||||
<a href="#ai-assisted-development" class="md-nav__link">
|
||||
<span class="md-ellipsis">
|
||||
@@ -2432,17 +2101,6 @@
|
||||
<nav class="md-nav" aria-label="AI-Assisted Development">
|
||||
<ul class="md-nav__list">
|
||||
|
||||
<li class="md-nav__item">
|
||||
<a href="#cli-tools" class="md-nav__link">
|
||||
<span class="md-ellipsis">
|
||||
|
||||
CLI Tools
|
||||
|
||||
</span>
|
||||
</a>
|
||||
|
||||
</li>
|
||||
|
||||
<li class="md-nav__item">
|
||||
<a href="#github-copilot" class="md-nav__link">
|
||||
<span class="md-ellipsis">
|
||||
@@ -2463,17 +2121,6 @@
|
||||
</span>
|
||||
</a>
|
||||
|
||||
</li>
|
||||
|
||||
<li class="md-nav__item">
|
||||
<a href="#multi-repository-architecture" class="md-nav__link">
|
||||
<span class="md-ellipsis">
|
||||
|
||||
Multi-Repository Architecture
|
||||
|
||||
</span>
|
||||
</a>
|
||||
|
||||
</li>
|
||||
|
||||
<li class="md-nav__item">
|
||||
@@ -2490,34 +2137,6 @@
|
||||
</ul>
|
||||
</nav>
|
||||
|
||||
</li>
|
||||
|
||||
<li class="md-nav__item">
|
||||
<a href="#command-line-utilities" class="md-nav__link">
|
||||
<span class="md-ellipsis">
|
||||
|
||||
Command-Line Utilities
|
||||
|
||||
</span>
|
||||
</a>
|
||||
|
||||
<nav class="md-nav" aria-label="Command-Line Utilities">
|
||||
<ul class="md-nav__list">
|
||||
|
||||
<li class="md-nav__item">
|
||||
<a href="#terminal-emulators" class="md-nav__link">
|
||||
<span class="md-ellipsis">
|
||||
|
||||
Terminal Emulators
|
||||
|
||||
</span>
|
||||
</a>
|
||||
|
||||
</li>
|
||||
|
||||
</ul>
|
||||
</nav>
|
||||
|
||||
</li>
|
||||
|
||||
<li class="md-nav__item">
|
||||
@@ -2533,10 +2152,10 @@
|
||||
<ul class="md-nav__list">
|
||||
|
||||
<li class="md-nav__item">
|
||||
<a href="#model-context-protocol-2" class="md-nav__link">
|
||||
<a href="#model-context-protocol-1" class="md-nav__link">
|
||||
<span class="md-ellipsis">
|
||||
|
||||
Model Context Protocol (2)
|
||||
Model Context Protocol (1)
|
||||
|
||||
</span>
|
||||
</a>
|
||||
@@ -3618,12 +3237,6 @@
|
||||
<li><a href="#developer-productivity">Developer Productivity</a></li>
|
||||
</ul>
|
||||
</li>
|
||||
<li><a href="#cicd-pipelines">CICD Pipelines</a></li>
|
||||
<li><a href="#ai-and-automation">AI and Automation</a><ul>
|
||||
<li><a href="#ai-pr-automation">AI PR Automation</a></li>
|
||||
<li><a href="#model-context-protocol-1">Model Context Protocol</a></li>
|
||||
</ul>
|
||||
</li>
|
||||
<li><a href="#cloud-infrastructure">Cloud Infrastructure</a></li>
|
||||
<li><a href="#cicd-and-devops">CICD and DevOps</a><ul>
|
||||
<li><a href="#devsecops">DevSecOps</a></li>
|
||||
@@ -3657,35 +3270,24 @@
|
||||
<li><a href="#ml-notebooks">ML Notebooks</a></li>
|
||||
</ul>
|
||||
</li>
|
||||
<li><a href="#container-orchestration">Container Orchestration</a></li>
|
||||
<li><a href="#azure-kubernetes-service">Azure Kubernetes Service</a><ul>
|
||||
<li><a href="#aks-fleet-manager">AKS Fleet Manager</a></li>
|
||||
</ul>
|
||||
</li>
|
||||
<li><a href="#devops">DevOps</a></li>
|
||||
<li><a href="#automation">Automation</a><ul>
|
||||
<li><a href="#education-tooling">Education Tooling</a></li>
|
||||
</ul>
|
||||
</li>
|
||||
<li><a href="#infrastructure-as-code-2">Infrastructure as Code</a><ul>
|
||||
<li><a href="#ai-integration">AI Integration</a></li>
|
||||
<li><a href="#terraform">Terraform</a></li>
|
||||
</ul>
|
||||
</li>
|
||||
<li><a href="#developer-experience">Developer Experience</a></li>
|
||||
<li><a href="#ai-assisted-coding">AI-Assisted Coding</a><ul>
|
||||
<li><a href="#claude-code">Claude Code</a></li>
|
||||
</ul>
|
||||
</li>
|
||||
<li><a href="#developer-tooling">Developer Tooling</a></li>
|
||||
<li><a href="#ai-code-assistants">AI Code Assistants</a><ul>
|
||||
<li><a href="#effort-frameworks">Effort Frameworks</a></li>
|
||||
<li><a href="#prompt-templates">Prompt Templates</a></li>
|
||||
<li><a href="#developer-productivity-1">Developer Productivity</a></li>
|
||||
<li><a href="#ides">IDEs</a><ul>
|
||||
<li><a href="#cursor">Cursor</a></li>
|
||||
</ul>
|
||||
</li>
|
||||
<li><a href="#emerging-technology">Emerging Technology</a></li>
|
||||
<li><a href="#machine-learning">Machine Learning</a><ul>
|
||||
<li><a href="#course">Course</a></li>
|
||||
<li><a href="#developer-tooling">Developer Tooling</a></li>
|
||||
<li><a href="#ai-code-assistants">AI Code Assistants</a><ul>
|
||||
<li><a href="#prompt-templates">Prompt Templates</a></li>
|
||||
</ul>
|
||||
</li>
|
||||
<li><a href="#enterprise-architecture">Enterprise Architecture</a></li>
|
||||
@@ -3696,52 +3298,24 @@
|
||||
</ul>
|
||||
</li>
|
||||
<li><a href="#finops-and-cloud-cost">FinOps and Cloud Cost</a></li>
|
||||
<li><a href="#azure-optimization">Azure Optimization</a><ul>
|
||||
<li><a href="#ai-cost-management">AI Cost Management</a></li>
|
||||
</ul>
|
||||
</li>
|
||||
<li><a href="#iac-finops">IaC FinOps</a><ul>
|
||||
<li><a href="#ai-optimization">AI Optimization</a></li>
|
||||
</ul>
|
||||
</li>
|
||||
<li><a href="#kubernetes-finops">Kubernetes FinOps</a><ul>
|
||||
<li><a href="#automated-optimization">Automated Optimization</a></li>
|
||||
</ul>
|
||||
</li>
|
||||
<li><a href="#infrastructure-as-code-3">Infrastructure as Code</a></li>
|
||||
<li><a href="#ai-integrations">AI Integrations</a><ul>
|
||||
<li><a href="#validation-and-testing">Validation and Testing</a></li>
|
||||
</ul>
|
||||
</li>
|
||||
<li><a href="#kubernetes-and-platform-engineering">Kubernetes and Platform Engineering</a></li>
|
||||
<li><a href="#platform-engineering-trends">Platform Engineering Trends</a><ul>
|
||||
<li><a href="#ai-integration-1">AI Integration</a></li>
|
||||
</ul>
|
||||
</li>
|
||||
<li><a href="#software-architecture-and-net-development">Software Architecture and .NET Development</a></li>
|
||||
<li><a href="#artificial-intelligence-2">Artificial Intelligence</a><ul>
|
||||
<li><a href="#agent-integration">Agent Integration</a></li>
|
||||
<li><a href="#ai-integration">AI Integration</a></li>
|
||||
</ul>
|
||||
</li>
|
||||
<li><a href="#software-engineering">Software Engineering</a></li>
|
||||
<li><a href="#ai-tools">AI Tools</a><ul>
|
||||
<li><a href="#developer-productivity-1">Developer Productivity</a></li>
|
||||
</ul>
|
||||
</li>
|
||||
<li><a href="#ai-assisted-development">AI-Assisted Development</a><ul>
|
||||
<li><a href="#cli-tools">CLI Tools</a></li>
|
||||
<li><a href="#github-copilot">GitHub Copilot</a></li>
|
||||
<li><a href="#industry-impact">Industry Impact</a></li>
|
||||
<li><a href="#multi-repository-architecture">Multi-Repository Architecture</a></li>
|
||||
<li><a href="#next-gen-platforms">Next-Gen Platforms</a></li>
|
||||
</ul>
|
||||
</li>
|
||||
<li><a href="#command-line-utilities">Command-Line Utilities</a><ul>
|
||||
<li><a href="#terminal-emulators">Terminal Emulators</a></li>
|
||||
</ul>
|
||||
</li>
|
||||
<li><a href="#database-management">Database Management</a><ul>
|
||||
<li><a href="#model-context-protocol-2">Model Context Protocol</a></li>
|
||||
<li><a href="#model-context-protocol-1">Model Context Protocol</a></li>
|
||||
</ul>
|
||||
</li>
|
||||
<li><a href="#professional-development">Professional Development</a><ul>
|
||||
@@ -3768,11 +3342,11 @@
|
||||
<li><a href="https://www.reddit.com/r/Terraform/comments/1l7my1x/where_is_ai_still_completely_useless_for">Discussion: Where is AI Still Completely Useless?</a> <span class='md-tag md-tag--info'>[COMMUNITY-TOOL]</span> — A curated technical resource and architectural guide covering Discussion: Where is AI Still Completely Useless? in the Kubernetes Tools ecosystem.</li>
|
||||
<li><a href="https://www.reddit.com/r/ProgrammerHumor/comments/1tbzih8/techcompaniescuttingdevsforai">Tech companies cutting devs for AI</a> <span class='md-tag md-tag--info'>[COMMUNITY-TOOL]</span> — A curated technical resource and architectural guide covering Tech companies cutting devs for AI in the Kubernetes Tools ecosystem.</li>
|
||||
<li><a href="https://www.docker.com/llm">Docker for LLMs</a> <span class='md-tag md-tag--info'>[COMMUNITY-TOOL]</span> — A curated technical resource and architectural guide covering Docker for LLMs in the Kubernetes Tools ecosystem.</li>
|
||||
<li><a href="https://www.hashicorp.com/blog/accelerate-your-terraform-development-with-amazon-codewhisperer">hashicorp.com: Accelerate your Terraform development with Amazon CodeWhisperer</a> <span class='md-tag md-tag--info'>[COMMUNITY-TOOL]</span> — A curated technical resource and architectural guide covering hashicorp.com: Accelerate your Terraform development with Amazon CodeWhisperer in the Kubernetes Tools ecosystem.</li>
|
||||
<li><a href="https://markrosscloud.medium.com/introducing-kiro-aws-agentic-ai-based-ide-cded711b1409">Introducing Kiro: AWS Agentic AI-Based IDE</a> <span class='md-tag md-tag--info'>[COMMUNITY-TOOL]</span> — A curated technical resource and architectural guide covering Introducing Kiro: AWS Agentic AI-Based IDE in the Kubernetes Tools ecosystem.</li>
|
||||
<li><a href="https://www.guru99.com/ai-tutorial.html">guru99.com: Artificial Intelligence Tutorial for Beginners: Learn Basics' of AI 🌟🌟🌟</a> <span class='md-tag md-tag--info'>[COMMUNITY-TOOL]</span> — A curated technical resource and architectural guide covering <mark>guru99.com: Artificial Intelligence Tutorial for Beginners: Learn Basics' of AI</mark> 🌟🌟🌟 in the Kubernetes Tools ecosystem.</li>
|
||||
<li><a href="https://www.technologyreview.es/s/13258/las-empresas-que-empiezan-lo-grande-con-la-ia-fracasan-mas">technologyreview.es: "Las empresas que empiezan a lo grande con la IA' fracasan más" 🌟</a> <span class='md-tag md-tag--info'>[COMMUNITY-TOOL]</span> — A curated technical resource and architectural guide covering <mark>technologyreview.es: "Las empresas que empiezan a lo grande con la IA' fracasan más"</mark> 🌟 in the Kubernetes Tools ecosystem.</li>
|
||||
<li><a href="https://hipertextual.com/2023/02/diferencias-ia-machine-learning">hipertextual.com: Diferencias entre Inteligencia Artificial, Machine Learning' y Deep Learning</a> <span class='md-tag md-tag--info'>[COMMUNITY-TOOL]</span> — A curated technical resource and architectural guide covering hipertextual.com: Diferencias entre Inteligencia Artificial, Machine Learning' y Deep Learning in the Kubernetes Tools ecosystem.</li>
|
||||
<li><a href="https://markrosscloud.medium.com/introducing-kiro-aws-agentic-ai-based-ide-cded711b1409">Introducing Kiro: AWS Agentic AI-Based IDE</a> <span class='md-tag md-tag--info'>[COMMUNITY-TOOL]</span> — A curated technical resource and architectural guide covering Introducing Kiro: AWS Agentic AI-Based IDE in the Kubernetes Tools ecosystem.</li>
|
||||
<li><a href="https://www.hashicorp.com/blog/accelerate-your-terraform-development-with-amazon-codewhisperer">hashicorp.com: Accelerate your Terraform development with Amazon CodeWhisperer</a> <span class='md-tag md-tag--info'>[COMMUNITY-TOOL]</span> — A curated technical resource and architectural guide covering hashicorp.com: Accelerate your Terraform development with Amazon CodeWhisperer in the Kubernetes Tools ecosystem.</li>
|
||||
<li><a href="https://blog.redbrickai.com/blog-posts/fast-meta-sam-for-medical-imaging">blog.redbrickai.com: F.A.S.T. ⚡️ Meta AI’s Segment Anything for Medical' Imaging</a> <span class='md-tag md-tag--info'>[COMMUNITY-TOOL]</span> — A curated technical resource and architectural guide covering blog.redbrickai.com: F.A.S.T. ⚡️ Meta AI’s Segment Anything for Medical' Imaging in the Kubernetes Tools ecosystem.</li>
|
||||
<li><a href="https://www.hashicorp.com/blog/accelerating-ai-adoption-on-azure-with-terraform">hashicorp.com: Accelerating AI adoption on Azure with Terraform</a> <span class='md-tag md-tag--info'>[COMMUNITY-TOOL]</span> — A curated technical resource and architectural guide covering hashicorp.com: Accelerating AI adoption on Azure with Terraform in the Kubernetes Tools ecosystem.</li>
|
||||
<li><a href="https://www.hashicorp.com/solutions/ai-infrastructure-management">hashicorp.com: AI for infrastructure management</a> <span class='md-tag md-tag--info'>[COMMUNITY-TOOL]</span> — A curated technical resource and architectural guide covering hashicorp.com: AI for infrastructure management in the Kubernetes Tools ecosystem.</li>
|
||||
@@ -3880,16 +3454,6 @@
|
||||
<ul>
|
||||
<li><strong>(2024)</strong> <a href="https://github.com/serenakeyitan/awesome-notebookLM-prompts"><strong>Awesome NotebookLM Slide Prompts</strong></a> <span class='md-tag md-tag--info'>⭐ 3761</span> <svg class="v2-sparkline" width="50" height="15" viewBox="0 0 50 15" style="vertical-align: middle; display: inline-block; margin-left: 6px;" title="Activity Trend"><defs><linearGradient id="spark-grad-1f241f0c" x1="0" y1="0" x2="1" y2="0"><stop offset="0%" stop-color="rgba(34, 211, 238, 0.2)" /><stop offset="100%" stop-color="var(--md-accent-fg-color)" /></linearGradient></defs><path class="v2-sparkline-path" d="M 0 7 L 10 13 L 20 2 L 30 2 L 40 2 L 50 5" fill="none" stroke="url(#spark-grad-1f241f0c)" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round" /><circle cx="50" cy="5" r="2" fill="var(--md-accent-fg-color)" /></svg> <span class='md-tag md-tag--warning'>[MARKDOWN CONTENT]</span> 🌟🌟🌟🌟 <span class='md-tag md-tag--success'>[ENTERPRISE-STABLE]</span> — A master curation of system-level prompt templates specifically optimized for Google NotebookLM. It accelerates complex source material ingestions, contextual extractions, and structured summarizing processes for technical architects. (Live Grounding: Highlights the 2026 intersection of AI workflow orchestration and engineering documentation maintenance).</li>
|
||||
</ul>
|
||||
<h2 id="cicd-pipelines">CICD Pipelines<a class="headerlink" href="#cicd-pipelines" title="Permanent link">¶</a></h2>
|
||||
<h3 id="ai-and-automation">AI and Automation<a class="headerlink" href="#ai-and-automation" title="Permanent link">¶</a></h3>
|
||||
<h4 id="ai-pr-automation">AI PR Automation<a class="headerlink" href="#ai-pr-automation" title="Permanent link">¶</a></h4>
|
||||
<ul>
|
||||
<li><strong>(2025)</strong> <a href="https://johnlokerse.dev/2025/02/10/automate-pull-request-descriptions-in-azure-devops-with-azure-openai">Automate Pull Request Descriptions in Azure DevOps with Azure OpenAI</a> <span class='md-tag md-tag--warning'>[YAML CONTENT]</span> <span class='md-tag md-tag--info'>[COMMUNITY-TOOL]</span> — A tutorial showing how to automate the generation of pull request descriptions within Azure DevOps pipelines using Azure OpenAI APIs. Streamlines developer velocity and documentation standards.</li>
|
||||
</ul>
|
||||
<h4 id="model-context-protocol-1">Model Context Protocol (1)<a class="headerlink" href="#model-context-protocol-1" title="Permanent link">¶</a></h4>
|
||||
<ul>
|
||||
<li><strong>(2025)</strong> <a href="https://devblogs.microsoft.com/devops/azure-devops-mcp-server-public-preview">Azure DevOps MCP Server Public Preview</a> <span class='md-tag md-tag--warning'>[NONE CONTENT]</span> <span class='md-tag md-tag--info'>[COMMUNITY-TOOL]</span> — Official Microsoft announcement outlining the preview release of the Azure DevOps MCP Server. Details how developer agents leverage safe API contexts to build and deploy complex assets.</li>
|
||||
</ul>
|
||||
<h2 id="cloud-infrastructure">Cloud Infrastructure<a class="headerlink" href="#cloud-infrastructure" title="Permanent link">¶</a></h2>
|
||||
<h3 id="cicd-and-devops">CICD and DevOps<a class="headerlink" href="#cicd-and-devops" title="Permanent link">¶</a></h3>
|
||||
<h4 id="devsecops">DevSecOps<a class="headerlink" href="#devsecops" title="Permanent link">¶</a></h4>
|
||||
@@ -3936,46 +3500,30 @@
|
||||
<ul>
|
||||
<li><strong>(2023)</strong> <a href="https://github.com/jupyterlab/jupyter-ai"><mark>github.com/jupyterlab/jupyter-ai</mark></a> <span class='md-tag md-tag--info'>⭐ 4272</span> <svg class="v2-sparkline" width="50" height="15" viewBox="0 0 50 15" style="vertical-align: middle; display: inline-block; margin-left: 6px;" title="Activity Trend"><defs><linearGradient id="spark-grad-9bc86074" x1="0" y1="0" x2="1" y2="0"><stop offset="0%" stop-color="rgba(34, 211, 238, 0.2)" /><stop offset="100%" stop-color="var(--md-accent-fg-color)" /></linearGradient></defs><path class="v2-sparkline-path" d="M 0 10 L 10 10 L 20 4 L 30 8 L 40 2 L 50 5" fill="none" stroke="url(#spark-grad-9bc86074)" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round" /><circle cx="50" cy="5" r="2" fill="var(--md-accent-fg-color)" /></svg> 🌟🌟🌟🌟🌟 <span class='md-tag md-tag--success'>[DE FACTO STANDARD]</span> — An official JupyterLab extension that brings generative AI capabilities to interactive notebooks. It supports inline code synthesis, explanation, and error correction across multiple model APIs.</li>
|
||||
</ul>
|
||||
<h2 id="container-orchestration">Container Orchestration<a class="headerlink" href="#container-orchestration" title="Permanent link">¶</a></h2>
|
||||
<h3 id="azure-kubernetes-service">Azure Kubernetes Service<a class="headerlink" href="#azure-kubernetes-service" title="Permanent link">¶</a></h3>
|
||||
<h4 id="aks-fleet-manager">AKS Fleet Manager<a class="headerlink" href="#aks-fleet-manager" title="Permanent link">¶</a></h4>
|
||||
<ul>
|
||||
<li><strong>(2025)</strong> <a href="https://blog.aks.azure.com/2025/04/02/Scaling-Kubernetes-for-AI-and-Data-intensive-Workloads">Limitless Kubernetes Scaling for AI and Data-intensive Workloads: The AKS Fleet Strategy</a> <span class='md-tag md-tag--warning'>[NONE CONTENT]</span> <span class='md-tag md-tag--critical'>[ADVANCED LEVEL]</span> <span class='md-tag md-tag--info'>[COMMUNITY-TOOL]</span> — Focuses on utilizing Azure Kubernetes Service (AKS) Fleet Manager to coordinate multi-cluster scaling for modern AI and data-heavy services. It details multi-cluster updates, global load balancing, and orchestration patterns that bypass single-cluster scaling bottlenecks, supporting highly distributed deep learning and large-scale analytical runtimes.</li>
|
||||
</ul>
|
||||
<h2 id="devops">DevOps<a class="headerlink" href="#devops" title="Permanent link">¶</a></h2>
|
||||
<h3 id="automation">Automation<a class="headerlink" href="#automation" title="Permanent link">¶</a></h3>
|
||||
<h4 id="education-tooling">Education Tooling<a class="headerlink" href="#education-tooling" title="Permanent link">¶</a></h4>
|
||||
<ul>
|
||||
<li><strong>(2023)</strong> <a href="https://github.com/ned1313/quiz-grader">Quiz Grader</a> <span class='md-tag md-tag--warning'>[PYTHON CONTENT]</span> <span class='md-tag md-tag--info'>[COMMUNITY-TOOL]</span> — A lightweight utility engineered to automate the grading and feedback of quizzes and programming assignments. Processes markdown-based inputs to generate structured performance assessments, supporting classroom and self-assessment operations.</li>
|
||||
</ul>
|
||||
<h3 id="infrastructure-as-code-2">Infrastructure as Code (2)<a class="headerlink" href="#infrastructure-as-code-2" title="Permanent link">¶</a></h3>
|
||||
<h4 id="ai-integration">AI Integration<a class="headerlink" href="#ai-integration" title="Permanent link">¶</a></h4>
|
||||
<h5 id="terraform">Terraform<a class="headerlink" href="#terraform" title="Permanent link">¶</a></h5>
|
||||
<ul>
|
||||
<li><strong>(2024)</strong> <a href="https://markaicode.com/terraform-ai-infrastructure-as-code">Terraform 2.0 in Practice: Using AI to Generate Infrastructure as Code</a> <span class='md-tag md-tag--info'>[COMMUNITY-TOOL]</span> — Examines workflow improvements, automated code validation, and prompt-to-infrastructure engineering using modern LLM integrations in Terraform development lifecycles.</li>
|
||||
</ul>
|
||||
<h2 id="developer-experience">Developer Experience<a class="headerlink" href="#developer-experience" title="Permanent link">¶</a></h2>
|
||||
<h3 id="ai-assisted-coding">AI-Assisted Coding<a class="headerlink" href="#ai-assisted-coding" title="Permanent link">¶</a></h3>
|
||||
<h4 id="claude-code">Claude Code<a class="headerlink" href="#claude-code" title="Permanent link">¶</a></h4>
|
||||
<ul>
|
||||
<li><strong>(2025)</strong> <a href="https://github.com/shanraisshan/claude-code-best-practice"><mark>Claude Code Best Practice</mark></a> <span class='md-tag md-tag--info'>⭐ 57660</span> <svg class="v2-sparkline" width="50" height="15" viewBox="0 0 50 15" style="vertical-align: middle; display: inline-block; margin-left: 6px;" title="Activity Trend"><defs><linearGradient id="spark-grad-26ea52d5" x1="0" y1="0" x2="1" y2="0"><stop offset="0%" stop-color="rgba(34, 211, 238, 0.2)" /><stop offset="100%" stop-color="var(--md-accent-fg-color)" /></linearGradient></defs><path class="v2-sparkline-path" d="M 0 3 L 10 2 L 20 3 L 30 5 L 40 3 L 50 2" fill="none" stroke="url(#spark-grad-26ea52d5)" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round" /><circle cx="50" cy="2" r="2" fill="var(--md-accent-fg-color)" /></svg> <span class='md-tag md-tag--warning'>[MARKDOWN CONTENT]</span> 🌟🌟🌟🌟🌟 <span class='md-tag md-tag--success'>[DE FACTO STANDARD]</span> <span class='md-tag md-tag--secondary'>[GUIDE]</span> — Curator Insight: Curated collection of best practices, system prompts, and architecture layouts for Claude Code. Live Grounding: Explores advanced CLI-driven agent workflows, highlighting configuration optimizations, shell integration strategies, and secure execution configurations in local and remote environments.</li>
|
||||
</ul>
|
||||
<h2 id="developer-productivity-1">Developer Productivity (1)<a class="headerlink" href="#developer-productivity-1" title="Permanent link">¶</a></h2>
|
||||
<h3 id="ides">IDEs<a class="headerlink" href="#ides" title="Permanent link">¶</a></h3>
|
||||
<h4 id="cursor">Cursor<a class="headerlink" href="#cursor" title="Permanent link">¶</a></h4>
|
||||
<ul>
|
||||
<li><strong>(2025)</strong> <a href="https://cursor.com"><mark>cursor.com: Cursor AI Code Editor</mark></a> 🌟🌟🌟🌟🌟 <span class='md-tag md-tag--success'>[DE FACTO STANDARD]</span> — The premier AI-first code editor, built as a fork of VS Code, offering features like Cursor Tab (smart autocomplete), Cmd+K (inline edits), Composer (multi-file agentic code generation), and deep codebase indexing.</li>
|
||||
</ul>
|
||||
<h2 id="developer-tooling">Developer Tooling<a class="headerlink" href="#developer-tooling" title="Permanent link">¶</a></h2>
|
||||
<h3 id="ai-code-assistants">AI Code Assistants<a class="headerlink" href="#ai-code-assistants" title="Permanent link">¶</a></h3>
|
||||
<h4 id="effort-frameworks">Effort Frameworks<a class="headerlink" href="#effort-frameworks" title="Permanent link">¶</a></h4>
|
||||
<ul>
|
||||
<li><strong>(2026)</strong> <a href="https://cursor.com/docs/bugbot">Cursor Bugbot Effort Levels Documentation</a> <span class='md-tag md-tag--warning'>[N/A CONTENT]</span> <span class='md-tag md-tag--primary'>[DOCUMENTATION]</span> <span class='md-tag md-tag--info'>[COMMUNITY-TOOL]</span> — This reference document outlines the effort metrics and execution paradigms utilized by Cursor's Bugbot tool inside the editor context. It guides development teams in managing priority levels for automated debugging routines across repositories.</li>
|
||||
</ul>
|
||||
<h4 id="prompt-templates">Prompt Templates<a class="headerlink" href="#prompt-templates" title="Permanent link">¶</a></h4>
|
||||
<ul>
|
||||
<li><strong>(2026)</strong> <a href="https://github.com/davila7/claude-code-templates"><mark>Claude Code Templates</mark></a> <span class='md-tag md-tag--info'>⭐ 28036</span> <svg class="v2-sparkline" width="50" height="15" viewBox="0 0 50 15" style="vertical-align: middle; display: inline-block; margin-left: 6px;" title="Activity Trend"><defs><linearGradient id="spark-grad-95ae7120" x1="0" y1="0" x2="1" y2="0"><stop offset="0%" stop-color="rgba(34, 211, 238, 0.2)" /><stop offset="100%" stop-color="var(--md-accent-fg-color)" /></linearGradient></defs><path class="v2-sparkline-path" d="M 0 12 L 10 2 L 20 11 L 30 13 L 40 7 L 50 5" fill="none" stroke="url(#spark-grad-95ae7120)" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round" /><circle cx="50" cy="5" r="2" fill="var(--md-accent-fg-color)" /></svg> <span class='md-tag md-tag--warning'>[MARKDOWN CONTENT]</span> <span class='md-tag md-tag--critical'>[ADVANCED LEVEL]</span> 🌟🌟🌟🌟🌟 <span class='md-tag md-tag--success'>[DE FACTO STANDARD]</span> — Claude Code Templates is an extensive community library containing structured system designs, context guidelines, and prompt schemas optimized for Anthropic's Claude Code and CLI. It helps teams configure context-aware coding agents that integrate smoothly into microservice development cycles.</li>
|
||||
</ul>
|
||||
<h2 id="emerging-technology">Emerging Technology<a class="headerlink" href="#emerging-technology" title="Permanent link">¶</a></h2>
|
||||
<h3 id="machine-learning">Machine Learning<a class="headerlink" href="#machine-learning" title="Permanent link">¶</a></h3>
|
||||
<h4 id="course">Course<a class="headerlink" href="#course" title="Permanent link">¶</a></h4>
|
||||
<ul>
|
||||
<li><strong>(2024)</strong> <a href="https://developers.google.com/machine-learning/crash-course?hl=es-419">Machine Learning Crash Course</a> <span class='md-tag md-tag--warning'>[SPANISH CONTENT]</span> <span class='md-tag md-tag--info'>[COMMUNITY-TOOL]</span> <span class='md-tag md-tag--secondary'>[GUIDE]</span> — Google's structured technical course on ML foundations. Covers gradient descent, model loss, deep neural networks, and scalable tensor processing, serving as an entry point for engineers integrating ML systems into modern APIs.</li>
|
||||
</ul>
|
||||
<h2 id="enterprise-architecture">Enterprise Architecture<a class="headerlink" href="#enterprise-architecture" title="Permanent link">¶</a></h2>
|
||||
<h3 id="aiops-and-observability">AIOps and Observability<a class="headerlink" href="#aiops-and-observability" title="Permanent link">¶</a></h3>
|
||||
<h4 id="incident-response">Incident Response<a class="headerlink" href="#incident-response" title="Permanent link">¶</a></h4>
|
||||
@@ -3992,50 +3540,19 @@
|
||||
<li><strong>(2023)</strong> <a href="https://thenewstack.io/the-urgency-driving-aiops-into-your-enterprise">thenewstack.io: The Urgency Driving AIOps into Your Enterprise</a> <span class='md-tag md-tag--info'>[COMMUNITY-TOOL]</span> — Analyzes the business and technology drivers forcing rapid enterprise integration of AIOps platforms. Addresses the challenge of telemetry overload and details how automated correlation engines optimize modern cloud networks.</li>
|
||||
</ul>
|
||||
<h2 id="finops-and-cloud-cost">FinOps and Cloud Cost<a class="headerlink" href="#finops-and-cloud-cost" title="Permanent link">¶</a></h2>
|
||||
<h3 id="azure-optimization">Azure Optimization<a class="headerlink" href="#azure-optimization" title="Permanent link">¶</a></h3>
|
||||
<h4 id="ai-cost-management">AI Cost Management<a class="headerlink" href="#ai-cost-management" title="Permanent link">¶</a></h4>
|
||||
<ul>
|
||||
<li><strong>(2025)</strong> <a href="https://techcommunity.microsoft.com/blog/finopsblog/learn-to-manage-investments-and-cost-efficiency-of-azure-and-ai-workloads/4396862"><strong>Learn to Manage Investments and Cost Efficiency of Azure and AI Workloads</strong></a> <span class='md-tag md-tag--critical'>[ADVANCED LEVEL]</span> 🌟🌟🌟🌟 <span class='md-tag md-tag--success'>[ENTERPRISE-STABLE]</span> — Addresses cost-optimization techniques for AI and large language model (LLM) workloads running on Azure. Discusses GPU node autoprovisioning, vector database optimization, and Azure OpenAI API consumption pricing models.</li>
|
||||
</ul>
|
||||
<h3 id="iac-finops">IaC FinOps<a class="headerlink" href="#iac-finops" title="Permanent link">¶</a></h3>
|
||||
<h4 id="ai-optimization">AI Optimization<a class="headerlink" href="#ai-optimization" title="Permanent link">¶</a></h4>
|
||||
<ul>
|
||||
<li><strong>(2024)</strong> <a href="https://github.com/openops-cloud/openops"><strong>OpenOps: No-Code FinOps Automation Platform with AI</strong></a> <span class='md-tag md-tag--info'>⭐ 1035</span> <svg class="v2-sparkline" width="50" height="15" viewBox="0 0 50 15" style="vertical-align: middle; display: inline-block; margin-left: 6px;" title="Activity Trend"><defs><linearGradient id="spark-grad-b1fe04f8" x1="0" y1="0" x2="1" y2="0"><stop offset="0%" stop-color="rgba(34, 211, 238, 0.2)" /><stop offset="100%" stop-color="var(--md-accent-fg-color)" /></linearGradient></defs><path class="v2-sparkline-path" d="M 0 13 L 10 11 L 20 8 L 30 2 L 40 8 L 50 5" fill="none" stroke="url(#spark-grad-b1fe04f8)" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round" /><circle cx="50" cy="5" r="2" fill="var(--md-accent-fg-color)" /></svg> <span class='md-tag md-tag--warning'>[GO CONTENT]</span> <span class='md-tag md-tag--critical'>[ADVANCED LEVEL]</span> 🌟🌟🌟🌟 <span class='md-tag md-tag--success'>[ENTERPRISE-STABLE]</span> — An open-source, no-code platform utilizing AI to identify and automate cloud cost optimizations. Connects directly with Kubernetes metrics to suggest sizing adjustments and automatically remove unused resources.</li>
|
||||
</ul>
|
||||
<h3 id="kubernetes-finops">Kubernetes FinOps<a class="headerlink" href="#kubernetes-finops" title="Permanent link">¶</a></h3>
|
||||
<h4 id="automated-optimization">Automated Optimization<a class="headerlink" href="#automated-optimization" title="Permanent link">¶</a></h4>
|
||||
<ul>
|
||||
<li><strong>(2025)</strong> <a href="https://cast.ai"><mark>CAST AI</mark></a> <span class='md-tag md-tag--critical'>[ADVANCED LEVEL]</span> 🌟🌟🌟🌟🌟 <span class='md-tag md-tag--success'>[DE FACTO STANDARD]</span> — Introduces CAST AI, an automated cost-reduction system for EKS, AKS, and GKE. Highlights how its real-time algorithms adjust cluster sizing, configure spot instances, and scale down resources without manual developer effort.</li>
|
||||
</ul>
|
||||
<h2 id="infrastructure-as-code-3">Infrastructure as Code (3)<a class="headerlink" href="#infrastructure-as-code-3" title="Permanent link">¶</a></h2>
|
||||
<h3 id="ai-integrations">AI Integrations<a class="headerlink" href="#ai-integrations" title="Permanent link">¶</a></h3>
|
||||
<h4 id="validation-and-testing">Validation and Testing<a class="headerlink" href="#validation-and-testing" title="Permanent link">¶</a></h4>
|
||||
<ul>
|
||||
<li><strong>(2024)</strong> <a href="https://masterpoint.io/blog/ai-meets-tf-prompt-strategies-for-test-generation">AI Meets Terraform: Prompt Strategies for Test Generation</a> <span class='md-tag md-tag--warning'>[NONE CONTENT]</span> <span class='md-tag md-tag--critical'>[ADVANCED LEVEL]</span> <span class='md-tag md-tag--info'>[COMMUNITY-TOOL]</span> — Explores LLM prompting strategies designed to automatically generate high-quality integration testing assertions for Terraform infrastructure codebases. Outlines systematic framework specifications to minimize manual testing overhead.</li>
|
||||
</ul>
|
||||
<h2 id="kubernetes-and-platform-engineering">Kubernetes and Platform Engineering<a class="headerlink" href="#kubernetes-and-platform-engineering" title="Permanent link">¶</a></h2>
|
||||
<h3 id="platform-engineering-trends">Platform Engineering Trends<a class="headerlink" href="#platform-engineering-trends" title="Permanent link">¶</a></h3>
|
||||
<h4 id="ai-integration-1">AI Integration (1)<a class="headerlink" href="#ai-integration-1" title="Permanent link">¶</a></h4>
|
||||
<h4 id="ai-integration">AI Integration<a class="headerlink" href="#ai-integration" title="Permanent link">¶</a></h4>
|
||||
<ul>
|
||||
<li><strong>(2024)</strong> <a href="https://platformengineering.org/blog/ai-is-changing-the-future-of-platform-engineering-are-you-ready">platformengineering.org: AI is changing the future of platform engineering. Are you ready?</a> <span class='md-tag md-tag--info'>[COMMUNITY-TOOL]</span> — Discusses how generative AI is shifting internal developer platform (IDP) dynamics. Details how AI assistance simplifies configuration management, infrastructure provisioning, and self-service portals for developer teams.</li>
|
||||
</ul>
|
||||
<h2 id="software-architecture-and-net-development">Software Architecture and .NET Development<a class="headerlink" href="#software-architecture-and-net-development" title="Permanent link">¶</a></h2>
|
||||
<h3 id="artificial-intelligence-2">Artificial Intelligence (2)<a class="headerlink" href="#artificial-intelligence-2" title="Permanent link">¶</a></h3>
|
||||
<h4 id="agent-integration">Agent Integration<a class="headerlink" href="#agent-integration" title="Permanent link">¶</a></h4>
|
||||
<ul>
|
||||
<li><strong>(2024)</strong> <a href="https://devblogs.microsoft.com/dotnet/extend-your-coding-agent-with-dotnet-skills">Extend your coding agent with .NET Skills</a> <span class='md-tag md-tag--warning'>[C# CONTENT]</span> <span class='md-tag md-tag--critical'>[ADVANCED LEVEL]</span> <span class='md-tag md-tag--info'>[COMMUNITY-TOOL]</span> — Examines methods for extending autonomous AI coding agents with direct .NET skill injection. Uses Semantic Kernel to build tools enabling LLMs to execute C# compilations, format files, and interact natively with code bases.</li>
|
||||
</ul>
|
||||
<h2 id="software-engineering">Software Engineering<a class="headerlink" href="#software-engineering" title="Permanent link">¶</a></h2>
|
||||
<h3 id="ai-tools">AI Tools<a class="headerlink" href="#ai-tools" title="Permanent link">¶</a></h3>
|
||||
<h4 id="developer-productivity-1">Developer Productivity (1)<a class="headerlink" href="#developer-productivity-1" title="Permanent link">¶</a></h4>
|
||||
<ul>
|
||||
<li><strong>(2024)</strong> <a href="https://techcommunity.microsoft.com/blog/azuredevcommunityblog/programming-with-github-copilot-agent-mode/4400630"><strong>Programming with GitHub Copilot Agent Mode</strong></a> 🌟🌟🌟🌟 <span class='md-tag md-tag--success'>[ENTERPRISE-STABLE]</span> — A deep dive into the engineering capabilities of GitHub Copilot's 'Agent Mode.' It details how the agent acts autonomously to analyze workspace dependencies, generate multi-file modifications, run localized compilations, and iterate on test suites based on natural language prompts.</li>
|
||||
</ul>
|
||||
<h3 id="ai-assisted-development">AI-Assisted Development<a class="headerlink" href="#ai-assisted-development" title="Permanent link">¶</a></h3>
|
||||
<h4 id="cli-tools">CLI Tools<a class="headerlink" href="#cli-tools" title="Permanent link">¶</a></h4>
|
||||
<ul>
|
||||
<li><strong>(2026)</strong> <a href="https://github.blog/ai-and-ml/github-copilot/github-copilot-cli-for-beginners-getting-started-with-github-copilot-cli">GitHub Copilot CLI for Beginners: Getting Started</a> <span class='md-tag md-tag--info'>[COMMUNITY-TOOL]</span> <span class='md-tag md-tag--secondary'>[GUIDE]</span> — Highlights setup and early integration techniques for GitHub Copilot CLI, translating natural language prompts into executable terminal and shell scripts. Enhances sysadmin and shell workflow automation while maintaining a human-in-the-loop review step for safety and correctness.</li>
|
||||
</ul>
|
||||
<h4 id="github-copilot">GitHub Copilot<a class="headerlink" href="#github-copilot" title="Permanent link">¶</a></h4>
|
||||
<ul>
|
||||
<li><strong>(2026)</strong> <a href="https://docs.github.com/en/copilot/get-started/best-practices">Best Practices for Using GitHub Copilot</a> <span class='md-tag md-tag--primary'>[DOCUMENTATION]</span> <span class='md-tag md-tag--info'>[COMMUNITY-TOOL]</span> — Authoritative guidelines from GitHub designed to optimize interaction with Copilot. Covers prompt engineering tactics (such as context-setting files and comments), managing AI security and license compliance, and verifying generated output.</li>
|
||||
@@ -4044,21 +3561,12 @@
|
||||
<ul>
|
||||
<li><strong>(2023)</strong> <a href="https://www.xataka.com/servicios/copilot-chatgpt-gpt-4-han-cambiado-para-siempre-mundo-programacion-esto-que-opinan-expertos">xataka.com: https://www.xataka.com/servicios/copilot-chatgpt-gpt-4-han-cambiado-para-siempre-mundo-programacion-esto-que-opinan-expertos</a> <span class='md-tag md-tag--warning'>[SPANISH CONTENT]</span> <span class='md-tag md-tag--info'>[COMMUNITY-TOOL]</span> — A comprehensive expert-driven review of how GPT-4 and Copilot have structurally altered the software engineering lifecycle. Evaluates productivity shifts, risks of cognitive offloading, and structural changes in junior developer onboarding processes.</li>
|
||||
</ul>
|
||||
<h4 id="multi-repository-architecture">Multi-Repository Architecture<a class="headerlink" href="#multi-repository-architecture" title="Permanent link">¶</a></h4>
|
||||
<ul>
|
||||
<li><strong>(2025)</strong> <a href="https://ettema.dev/posts/ai-multi-repo-workspaces">Using Workspaces for AI Changes Across Multiple Repos</a> <span class='md-tag md-tag--critical'>[ADVANCED LEVEL]</span> <span class='md-tag md-tag--info'>[COMMUNITY-TOOL]</span> — Details advanced patterns for orchestrating automated codebase modifications across distributed multi-repository environments using AI workspaces. Evaluates dependency resolution, unified context indexing, and coordinate git-commit strategies during systemic API breaking updates.</li>
|
||||
</ul>
|
||||
<h4 id="next-gen-platforms">Next-Gen Platforms<a class="headerlink" href="#next-gen-platforms" title="Permanent link">¶</a></h4>
|
||||
<ul>
|
||||
<li><strong>(2023)</strong> <a href="https://computerhoy.20minutos.es">computerhoy.com: GitHub Copilot X: así es la nueva IA parecida a ChatGPT y destinada a ayudar a programadores</a> <span class='md-tag md-tag--warning'>[SPANISH CONTENT]</span> <span class='md-tag md-tag--info'>[COMMUNITY-TOOL]</span> — Analyzes the technical specifications of Copilot X, including terminal tool integration, automated PR description synthesis, and integrated chat widgets. Examines the performance gains from switching to OpenAI's GPT-4 framework.</li>
|
||||
</ul>
|
||||
<h3 id="command-line-utilities">Command-Line Utilities<a class="headerlink" href="#command-line-utilities" title="Permanent link">¶</a></h3>
|
||||
<h4 id="terminal-emulators">Terminal Emulators<a class="headerlink" href="#terminal-emulators" title="Permanent link">¶</a></h4>
|
||||
<ul>
|
||||
<li><strong>(2026)</strong> <a href="https://www.warp.dev">Warp: The Agentic Development Environment</a> <span class='md-tag md-tag--info'>[COMMUNITY-TOOL]</span> — A modern, Rust-based terminal emulator incorporating AI agent assistance directly into the command-line interface. Reimagines input fields like text editors, supports real-time workspace collaboration, and native context-sharing for accelerated platform ops troubleshooting.</li>
|
||||
</ul>
|
||||
<h3 id="database-management">Database Management<a class="headerlink" href="#database-management" title="Permanent link">¶</a></h3>
|
||||
<h4 id="model-context-protocol-2">Model Context Protocol (2)<a class="headerlink" href="#model-context-protocol-2" title="Permanent link">¶</a></h4>
|
||||
<h4 id="model-context-protocol-1">Model Context Protocol (1)<a class="headerlink" href="#model-context-protocol-1" title="Permanent link">¶</a></h4>
|
||||
<ul>
|
||||
<li><strong>(2024)</strong> <a href="https://github.com/TabularisDB/tabularis/blob/main/README.es.md"><mark>Tabularis: Open Source Desktop Client for Modern Databases with AI and MCP' Integration</mark></a> <span class='md-tag md-tag--info'>⭐ 2422</span> <svg class="v2-sparkline" width="50" height="15" viewBox="0 0 50 15" style="vertical-align: middle; display: inline-block; margin-left: 6px;" title="Activity Trend"><defs><linearGradient id="spark-grad-6df57ab1" x1="0" y1="0" x2="1" y2="0"><stop offset="0%" stop-color="rgba(34, 211, 238, 0.2)" /><stop offset="100%" stop-color="var(--md-accent-fg-color)" /></linearGradient></defs><path class="v2-sparkline-path" d="M 0 13 L 10 5 L 20 2 L 30 12 L 40 13 L 50 2" fill="none" stroke="url(#spark-grad-6df57ab1)" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round" /><circle cx="50" cy="2" r="2" fill="var(--md-accent-fg-color)" /></svg> <span class='md-tag md-tag--warning'>[SPANISH CONTENT]</span> 🌟🌟🌟🌟🌟 <span class='md-tag md-tag--success'>[DE FACTO STANDARD]</span> — An open-source desktop database client featuring Model Context Protocol (MCP) integrations. This compliance allows local LLMs to safely query, analyze, and update database schemas within strict user security boundaries.</li>
|
||||
</ul>
|
||||
|
||||
@@ -3155,10 +3155,10 @@
|
||||
<h3 id="kubernetes-tools">Kubernetes Tools<a class="headerlink" href="#kubernetes-tools" title="Permanent link">¶</a></h3>
|
||||
<h4 id="general-reference">General Reference<a class="headerlink" href="#general-reference" title="Permanent link">¶</a></h4>
|
||||
<ul>
|
||||
<li><a href="https://www.hashicorp.com/blog/accelerate-your-terraform-development-with-amazon-codewhisperer">hashicorp.com: Accelerate your Terraform development with Amazon CodeWhisperer</a> <span class='md-tag md-tag--info'>[COMMUNITY-TOOL]</span> — A curated technical resource and architectural guide covering hashicorp.com: Accelerate your Terraform development with Amazon CodeWhisperer in the Kubernetes Tools ecosystem.</li>
|
||||
<li><a href="https://www.cloudcatalog.dev">cloudcatalog.dev</a> <span class='md-tag md-tag--info'>[COMMUNITY-TOOL]</span> — A curated technical resource and architectural guide covering <mark>cloudcatalog.dev</mark> in the Kubernetes Tools ecosystem.</li>
|
||||
<li><a href="https://medium.com/circuitpeople/aws-cli-with-jq-and-bash-9d54e2eabaf1">medium: AWS CLI with jq and Bash</a> <span class='md-tag md-tag--info'>[COMMUNITY-TOOL]</span> — A curated technical resource and architectural guide covering medium: AWS CLI with jq and Bash in the Kubernetes Tools ecosystem.</li>
|
||||
<li><a href="https://aws.plainenglish.io/lessons-learned-from-switching-to-aws-sdk-v3-6babe1530a59">aws.plainenglish.io: Lessons Learned From Switching to AWS SDK v3</a> <span class='md-tag md-tag--info'>[COMMUNITY-TOOL]</span> — A curated technical resource and architectural guide covering aws.plainenglish.io: Lessons Learned From Switching to AWS SDK v3 in the Kubernetes Tools ecosystem.</li>
|
||||
<li><a href="https://www.hashicorp.com/blog/accelerate-your-terraform-development-with-amazon-codewhisperer">hashicorp.com: Accelerate your Terraform development with Amazon CodeWhisperer</a> <span class='md-tag md-tag--info'>[COMMUNITY-TOOL]</span> — A curated technical resource and architectural guide covering hashicorp.com: Accelerate your Terraform development with Amazon CodeWhisperer in the Kubernetes Tools ecosystem.</li>
|
||||
</ul>
|
||||
<h2 id="artificial-intelligence">Artificial Intelligence<a class="headerlink" href="#artificial-intelligence" title="Permanent link">¶</a></h2>
|
||||
<h3 id="developer-agents">Developer Agents<a class="headerlink" href="#developer-agents" title="Permanent link">¶</a></h3>
|
||||
|
||||
@@ -3648,7 +3648,6 @@
|
||||
<h4 id="general-reference">General Reference<a class="headerlink" href="#general-reference" title="Permanent link">¶</a></h4>
|
||||
<ul>
|
||||
<li><a href="https://aws.amazon.com/premiumsupport/knowledge-center">AWS Knowledge Center</a> <span class='md-tag md-tag--info'>[COMMUNITY-TOOL]</span> — A curated technical resource and architectural guide covering aws.amazon.com in the Kubernetes Tools ecosystem.</li>
|
||||
<li><a href="https://markrosscloud.medium.com/introducing-kiro-aws-agentic-ai-based-ide-cded711b1409">Introducing Kiro: AWS Agentic AI-Based IDE</a> <span class='md-tag md-tag--info'>[COMMUNITY-TOOL]</span> — A curated technical resource and architectural guide covering Introducing Kiro: AWS Agentic AI-Based IDE in the Kubernetes Tools ecosystem.</li>
|
||||
<li><a href="https://medium.com/towards-cloud-computing/7-free-aws-practice-labs-and-aws-workshops-resources-d0a861f05d3">medium.com/towards-cloud-computing: 7 Free AWS Practice Labs and AWS Workshops' resources</a> <span class='md-tag md-tag--info'>[COMMUNITY-TOOL]</span> — A curated technical resource and architectural guide covering <mark>medium.com/towards-cloud-computing: 7 Free AWS Practice Labs and AWS Workshops' resources</mark> in the Kubernetes Tools ecosystem.</li>
|
||||
<li><a href="https://dzone.com/articles/aws-basics">dzone: AWS Basics</a> <span class='md-tag md-tag--info'>[COMMUNITY-TOOL]</span> — A curated technical resource and architectural guide covering dzone: AWS Basics in the Kubernetes Tools ecosystem.</li>
|
||||
<li><a href="https://dzone.com/articles/aws-basics-bastian-hosts-and-nat">dzone: AWS Basics: Bastion Hosts and NAT</a> <span class='md-tag md-tag--info'>[COMMUNITY-TOOL]</span> — A curated technical resource and architectural guide covering dzone: AWS Basics: Bastion Hosts and NAT in the Kubernetes Tools ecosystem.</li>
|
||||
@@ -3666,6 +3665,7 @@
|
||||
<li><a href="https://awstip.com/how-to-list-all-resources-in-your-aws-account-c3f18061f71b">awstip.com: How to list all resources in your AWS account</a> <span class='md-tag md-tag--info'>[COMMUNITY-TOOL]</span> — A curated technical resource and architectural guide covering awstip.com: How to list all resources in your AWS account in the Kubernetes Tools ecosystem.</li>
|
||||
<li><a href="https://terminalsandcoffee.com/setting-up-the-aws-cli-iam-user-api-keys-b83554e314e4">terminalsandcoffee.com: Setting Up the AWS CLI & IAM User API Keys 🌟</a> <span class='md-tag md-tag--info'>[COMMUNITY-TOOL]</span> — A curated technical resource and architectural guide covering terminalsandcoffee.com: Setting Up the AWS CLI & IAM User API Keys 🌟 in the Kubernetes Tools ecosystem.</li>
|
||||
<li><a href="https://mrdevops.hashnode.dev/how-to-create-ec2-instance-in-aws-step-by-step-tutorial">mrdevops.hashnode.dev: How to Create EC2 Instance in AWS: Step by Step' Tutorial</a> <span class='md-tag md-tag--info'>[COMMUNITY-TOOL]</span> — A curated technical resource and architectural guide covering <mark>mrdevops.hashnode.dev: How to Create EC2 Instance in AWS: Step by Step' Tutorial</mark> in the Kubernetes Tools ecosystem.</li>
|
||||
<li><a href="https://markrosscloud.medium.com/introducing-kiro-aws-agentic-ai-based-ide-cded711b1409">Introducing Kiro: AWS Agentic AI-Based IDE</a> <span class='md-tag md-tag--info'>[COMMUNITY-TOOL]</span> — A curated technical resource and architectural guide covering Introducing Kiro: AWS Agentic AI-Based IDE in the Kubernetes Tools ecosystem.</li>
|
||||
<li><a href="https://aws.plainenglish.io">aws.plainenglish.io</a> <span class='md-tag md-tag--info'>[COMMUNITY-TOOL]</span> — A curated technical resource and architectural guide covering aws.plainenglish.io in the Kubernetes Tools ecosystem.</li>
|
||||
<li><a href="https://awstip.com">AWStip.com</a> <span class='md-tag md-tag--info'>[COMMUNITY-TOOL]</span> — A curated technical resource and architectural guide covering AWStip.com in the Kubernetes Tools ecosystem.</li>
|
||||
<li><a href="https://medium.com/aws-activate-startup-blog/bitmovin-improving-video-quality-on-the-web-8670039c4334">bitmovin: Improving Video Quality on the Web</a> <span class='md-tag md-tag--info'>[COMMUNITY-TOOL]</span> — A curated technical resource and architectural guide covering bitmovin: Improving Video Quality on the Web in the Kubernetes Tools ecosystem.</li>
|
||||
|
||||
@@ -2364,6 +2364,17 @@
|
||||
<nav class="md-nav" aria-label="AI and Automation">
|
||||
<ul class="md-nav__list">
|
||||
|
||||
<li class="md-nav__item">
|
||||
<a href="#ai-pr-automation" class="md-nav__link">
|
||||
<span class="md-ellipsis">
|
||||
|
||||
AI PR Automation
|
||||
|
||||
</span>
|
||||
</a>
|
||||
|
||||
</li>
|
||||
|
||||
<li class="md-nav__item">
|
||||
<a href="#model-context-protocol" class="md-nav__link">
|
||||
<span class="md-ellipsis">
|
||||
@@ -5871,6 +5882,34 @@
|
||||
</ul>
|
||||
</nav>
|
||||
|
||||
</li>
|
||||
|
||||
<li class="md-nav__item">
|
||||
<a href="#azure-kubernetes-service" class="md-nav__link">
|
||||
<span class="md-ellipsis">
|
||||
|
||||
Azure Kubernetes Service
|
||||
|
||||
</span>
|
||||
</a>
|
||||
|
||||
<nav class="md-nav" aria-label="Azure Kubernetes Service">
|
||||
<ul class="md-nav__list">
|
||||
|
||||
<li class="md-nav__item">
|
||||
<a href="#aks-fleet-manager-1" class="md-nav__link">
|
||||
<span class="md-ellipsis">
|
||||
|
||||
AKS Fleet Manager (1)
|
||||
|
||||
</span>
|
||||
</a>
|
||||
|
||||
</li>
|
||||
|
||||
</ul>
|
||||
</nav>
|
||||
|
||||
</li>
|
||||
|
||||
<li class="md-nav__item">
|
||||
@@ -6791,6 +6830,17 @@
|
||||
<nav class="md-nav" aria-label="Azure Optimization">
|
||||
<ul class="md-nav__list">
|
||||
|
||||
<li class="md-nav__item">
|
||||
<a href="#ai-cost-management" class="md-nav__link">
|
||||
<span class="md-ellipsis">
|
||||
|
||||
AI Cost Management
|
||||
|
||||
</span>
|
||||
</a>
|
||||
|
||||
</li>
|
||||
|
||||
<li class="md-nav__item">
|
||||
<a href="#landing-zones-2" class="md-nav__link">
|
||||
<span class="md-ellipsis">
|
||||
@@ -11408,6 +11458,7 @@
|
||||
</li>
|
||||
<li><a href="#cicd-pipelines">CICD Pipelines</a></li>
|
||||
<li><a href="#ai-and-automation">AI and Automation</a><ul>
|
||||
<li><a href="#ai-pr-automation">AI PR Automation</a></li>
|
||||
<li><a href="#model-context-protocol">Model Context Protocol</a></li>
|
||||
</ul>
|
||||
</li>
|
||||
@@ -11818,6 +11869,10 @@
|
||||
<li><a href="#hands-on-learning">Hands-on Learning</a></li>
|
||||
</ul>
|
||||
</li>
|
||||
<li><a href="#azure-kubernetes-service">Azure Kubernetes Service</a><ul>
|
||||
<li><a href="#aks-fleet-manager-1">AKS Fleet Manager</a></li>
|
||||
</ul>
|
||||
</li>
|
||||
<li><a href="#operating-systems">Operating Systems</a><ul>
|
||||
<li><a href="#azure-linux">Azure Linux</a></li>
|
||||
</ul>
|
||||
@@ -11919,6 +11974,7 @@
|
||||
</li>
|
||||
<li><a href="#finops-and-cloud-cost">FinOps and Cloud Cost</a></li>
|
||||
<li><a href="#azure-optimization">Azure Optimization</a><ul>
|
||||
<li><a href="#ai-cost-management">AI Cost Management</a></li>
|
||||
<li><a href="#landing-zones-2">Landing Zones</a></li>
|
||||
</ul>
|
||||
</li>
|
||||
@@ -12468,9 +12524,14 @@
|
||||
</ul>
|
||||
<h2 id="cicd-pipelines">CICD Pipelines<a class="headerlink" href="#cicd-pipelines" title="Permanent link">¶</a></h2>
|
||||
<h3 id="ai-and-automation">AI and Automation<a class="headerlink" href="#ai-and-automation" title="Permanent link">¶</a></h3>
|
||||
<h4 id="ai-pr-automation">AI PR Automation<a class="headerlink" href="#ai-pr-automation" title="Permanent link">¶</a></h4>
|
||||
<ul>
|
||||
<li><strong>(2025)</strong> <a href="https://johnlokerse.dev/2025/02/10/automate-pull-request-descriptions-in-azure-devops-with-azure-openai">Automate Pull Request Descriptions in Azure DevOps with Azure OpenAI</a> <span class='md-tag md-tag--warning'>[YAML CONTENT]</span> <span class='md-tag md-tag--info'>[COMMUNITY-TOOL]</span> — A tutorial showing how to automate the generation of pull request descriptions within Azure DevOps pipelines using Azure OpenAI APIs. Streamlines developer velocity and documentation standards.</li>
|
||||
</ul>
|
||||
<h4 id="model-context-protocol">Model Context Protocol<a class="headerlink" href="#model-context-protocol" title="Permanent link">¶</a></h4>
|
||||
<ul>
|
||||
<li><strong>(2025)</strong> <a href="https://github.com/microsoft/azure-devops-mcp"><mark>Azure DevOps MCP Server</mark></a> <span class='md-tag md-tag--info'>⭐ 1813</span> <svg class="v2-sparkline" width="50" height="15" viewBox="0 0 50 15" style="vertical-align: middle; display: inline-block; margin-left: 6px;" title="Activity Trend"><defs><linearGradient id="spark-grad-2b346c75" x1="0" y1="0" x2="1" y2="0"><stop offset="0%" stop-color="rgba(34, 211, 238, 0.2)" /><stop offset="100%" stop-color="var(--md-accent-fg-color)" /></linearGradient></defs><path class="v2-sparkline-path" d="M 0 4 L 10 12 L 20 2 L 30 11 L 40 6 L 50 5" fill="none" stroke="url(#spark-grad-2b346c75)" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round" /><circle cx="50" cy="5" r="2" fill="var(--md-accent-fg-color)" /></svg> <span class='md-tag md-tag--warning'>[TYPESCRIPT CONTENT]</span> <span class='md-tag md-tag--critical'>[ADVANCED LEVEL]</span> 🌟🌟🌟🌟🌟 <span class='md-tag md-tag--success'>[DE FACTO STANDARD]</span> — An official Microsoft MCP server repository enabling AI Agents (like Claude or GitHub Copilot) to interact seamlessly with Azure DevOps. Allows agents to manage work items, query repositories, and orchestrate pipeline runs.</li>
|
||||
<li><strong>(2025)</strong> <a href="https://devblogs.microsoft.com/devops/azure-devops-mcp-server-public-preview">Azure DevOps MCP Server Public Preview</a> <span class='md-tag md-tag--warning'>[NONE CONTENT]</span> <span class='md-tag md-tag--info'>[COMMUNITY-TOOL]</span> — Official Microsoft announcement outlining the preview release of the Azure DevOps MCP Server. Details how developer agents leverage safe API contexts to build and deploy complex assets.</li>
|
||||
</ul>
|
||||
<h3 id="devops-platforms">DevOps Platforms<a class="headerlink" href="#devops-platforms" title="Permanent link">¶</a></h3>
|
||||
<h4 id="devtest-labs">DevTest Labs<a class="headerlink" href="#devtest-labs" title="Permanent link">¶</a></h4>
|
||||
@@ -13183,6 +13244,11 @@
|
||||
<ul>
|
||||
<li><strong>(2026)</strong> <a href="https://azure-samples.github.io/aks-labs/docs/intro">AKS Labs - Introduction</a> <span class='md-tag md-tag--warning'>[MARKDOWN CONTENT]</span> <span class='md-tag md-tag--primary'>[DOCUMENTATION]</span> <span class='md-tag md-tag--info'>[COMMUNITY-TOOL]</span> — Hands-on, engineer-designed technical playground for AKS configurations. Deep dives into Advanced CNI options, Cilium-driven security schemas, network boundaries, and workload identity bindings.</li>
|
||||
</ul>
|
||||
<h3 id="azure-kubernetes-service">Azure Kubernetes Service<a class="headerlink" href="#azure-kubernetes-service" title="Permanent link">¶</a></h3>
|
||||
<h4 id="aks-fleet-manager-1">AKS Fleet Manager (1)<a class="headerlink" href="#aks-fleet-manager-1" title="Permanent link">¶</a></h4>
|
||||
<ul>
|
||||
<li><strong>(2025)</strong> <a href="https://blog.aks.azure.com/2025/04/02/Scaling-Kubernetes-for-AI-and-Data-intensive-Workloads">Limitless Kubernetes Scaling for AI and Data-intensive Workloads: The AKS Fleet Strategy</a> <span class='md-tag md-tag--warning'>[NONE CONTENT]</span> <span class='md-tag md-tag--critical'>[ADVANCED LEVEL]</span> <span class='md-tag md-tag--info'>[COMMUNITY-TOOL]</span> — Focuses on utilizing Azure Kubernetes Service (AKS) Fleet Manager to coordinate multi-cluster scaling for modern AI and data-heavy services. It details multi-cluster updates, global load balancing, and orchestration patterns that bypass single-cluster scaling bottlenecks, supporting highly distributed deep learning and large-scale analytical runtimes.</li>
|
||||
</ul>
|
||||
<h3 id="operating-systems">Operating Systems<a class="headerlink" href="#operating-systems" title="Permanent link">¶</a></h3>
|
||||
<h4 id="azure-linux">Azure Linux<a class="headerlink" href="#azure-linux" title="Permanent link">¶</a></h4>
|
||||
<ul>
|
||||
@@ -13361,6 +13427,10 @@
|
||||
</ul>
|
||||
<h2 id="finops-and-cloud-cost">FinOps and Cloud Cost<a class="headerlink" href="#finops-and-cloud-cost" title="Permanent link">¶</a></h2>
|
||||
<h3 id="azure-optimization">Azure Optimization<a class="headerlink" href="#azure-optimization" title="Permanent link">¶</a></h3>
|
||||
<h4 id="ai-cost-management">AI Cost Management<a class="headerlink" href="#ai-cost-management" title="Permanent link">¶</a></h4>
|
||||
<ul>
|
||||
<li><strong>(2025)</strong> <a href="https://techcommunity.microsoft.com/blog/finopsblog/learn-to-manage-investments-and-cost-efficiency-of-azure-and-ai-workloads/4396862"><strong>Learn to Manage Investments and Cost Efficiency of Azure and AI Workloads</strong></a> <span class='md-tag md-tag--critical'>[ADVANCED LEVEL]</span> 🌟🌟🌟🌟 <span class='md-tag md-tag--success'>[ENTERPRISE-STABLE]</span> — Addresses cost-optimization techniques for AI and large language model (LLM) workloads running on Azure. Discusses GPU node autoprovisioning, vector database optimization, and Azure OpenAI API consumption pricing models.</li>
|
||||
</ul>
|
||||
<h4 id="landing-zones-2">Landing Zones (2)<a class="headerlink" href="#landing-zones-2" title="Permanent link">¶</a></h4>
|
||||
<ul>
|
||||
<li><strong>(2025)</strong> <a href="https://techcommunity.microsoft.com/blog/AzureInfrastructureBlog/building-a-finops-ready-azure-landing-zone-infrastructure-foundations-for-cost-o/4411706"><mark>Building a FinOps-Ready Azure Landing Zone: Infrastructure Foundations for Cost Optimization</mark></a> <span class='md-tag md-tag--critical'>[ADVANCED LEVEL]</span> 🌟🌟🌟🌟🌟 <span class='md-tag md-tag--success'>[DE FACTO STANDARD]</span> — Details how to configure a FinOps-compliant Azure Landing Zone. Uses Azure Policy and management groups to enforce resource tag policies, mandate budget limits at subscription boundaries, and automate continuous cost governance.</li>
|
||||
|
||||
@@ -1683,6 +1683,51 @@
|
||||
</ul>
|
||||
</nav>
|
||||
|
||||
</li>
|
||||
|
||||
<li class="md-nav__item">
|
||||
<a href="#ai-engineering" class="md-nav__link">
|
||||
<span class="md-ellipsis">
|
||||
|
||||
AI Engineering
|
||||
|
||||
</span>
|
||||
</a>
|
||||
|
||||
<nav class="md-nav" aria-label="AI Engineering">
|
||||
<ul class="md-nav__list">
|
||||
|
||||
<li class="md-nav__item">
|
||||
<a href="#agentic-frameworks" class="md-nav__link">
|
||||
<span class="md-ellipsis">
|
||||
|
||||
Agentic Frameworks
|
||||
|
||||
</span>
|
||||
</a>
|
||||
|
||||
<nav class="md-nav" aria-label="Agentic Frameworks">
|
||||
<ul class="md-nav__list">
|
||||
|
||||
<li class="md-nav__item">
|
||||
<a href="#developer-experience" class="md-nav__link">
|
||||
<span class="md-ellipsis">
|
||||
|
||||
Developer Experience
|
||||
|
||||
</span>
|
||||
</a>
|
||||
|
||||
</li>
|
||||
|
||||
</ul>
|
||||
</nav>
|
||||
|
||||
</li>
|
||||
|
||||
</ul>
|
||||
</nav>
|
||||
|
||||
</li>
|
||||
|
||||
<li class="md-nav__item">
|
||||
@@ -2852,6 +2897,51 @@
|
||||
</ul>
|
||||
</nav>
|
||||
|
||||
</li>
|
||||
|
||||
<li class="md-nav__item">
|
||||
<a href="#developer-experience-1" class="md-nav__link">
|
||||
<span class="md-ellipsis">
|
||||
|
||||
Developer Experience (1)
|
||||
|
||||
</span>
|
||||
</a>
|
||||
|
||||
<nav class="md-nav" aria-label="Developer Experience (1)">
|
||||
<ul class="md-nav__list">
|
||||
|
||||
<li class="md-nav__item">
|
||||
<a href="#ai-assisted-coding" class="md-nav__link">
|
||||
<span class="md-ellipsis">
|
||||
|
||||
AI-Assisted Coding
|
||||
|
||||
</span>
|
||||
</a>
|
||||
|
||||
<nav class="md-nav" aria-label="AI-Assisted Coding">
|
||||
<ul class="md-nav__list">
|
||||
|
||||
<li class="md-nav__item">
|
||||
<a href="#claude-code" class="md-nav__link">
|
||||
<span class="md-ellipsis">
|
||||
|
||||
Claude Code
|
||||
|
||||
</span>
|
||||
</a>
|
||||
|
||||
</li>
|
||||
|
||||
</ul>
|
||||
</nav>
|
||||
|
||||
</li>
|
||||
|
||||
</ul>
|
||||
</nav>
|
||||
|
||||
</li>
|
||||
|
||||
<li class="md-nav__item">
|
||||
@@ -3153,15 +3243,15 @@
|
||||
<ul class="md-nav__list">
|
||||
|
||||
<li class="md-nav__item">
|
||||
<a href="#developer-experience" class="md-nav__link">
|
||||
<a href="#developer-experience-2" class="md-nav__link">
|
||||
<span class="md-ellipsis">
|
||||
|
||||
Developer Experience
|
||||
Developer Experience (2)
|
||||
|
||||
</span>
|
||||
</a>
|
||||
|
||||
<nav class="md-nav" aria-label="Developer Experience">
|
||||
<nav class="md-nav" aria-label="Developer Experience (2)">
|
||||
<ul class="md-nav__list">
|
||||
|
||||
<li class="md-nav__item">
|
||||
@@ -3197,6 +3287,34 @@
|
||||
<nav class="md-nav" aria-label="Software Engineering">
|
||||
<ul class="md-nav__list">
|
||||
|
||||
<li class="md-nav__item">
|
||||
<a href="#ai-tools" class="md-nav__link">
|
||||
<span class="md-ellipsis">
|
||||
|
||||
AI Tools
|
||||
|
||||
</span>
|
||||
</a>
|
||||
|
||||
<nav class="md-nav" aria-label="AI Tools">
|
||||
<ul class="md-nav__list">
|
||||
|
||||
<li class="md-nav__item">
|
||||
<a href="#developer-productivity-2" class="md-nav__link">
|
||||
<span class="md-ellipsis">
|
||||
|
||||
Developer Productivity (2)
|
||||
|
||||
</span>
|
||||
</a>
|
||||
|
||||
</li>
|
||||
|
||||
</ul>
|
||||
</nav>
|
||||
|
||||
</li>
|
||||
|
||||
<li class="md-nav__item">
|
||||
<a href="#ai-assisted-development" class="md-nav__link">
|
||||
<span class="md-ellipsis">
|
||||
@@ -3837,6 +3955,11 @@
|
||||
<li><a href="#developer-productivity">Developer Productivity</a></li>
|
||||
</ul>
|
||||
</li>
|
||||
<li><a href="#ai-engineering">AI Engineering</a></li>
|
||||
<li><a href="#agentic-frameworks">Agentic Frameworks</a><ul>
|
||||
<li><a href="#developer-experience">Developer Experience</a></li>
|
||||
</ul>
|
||||
</li>
|
||||
<li><a href="#architectural-foundations">Architectural Foundations</a></li>
|
||||
<li><a href="#kubernetes-tools">Kubernetes Tools</a><ul>
|
||||
<li><a href="#general-reference">General Reference</a></li>
|
||||
@@ -3980,6 +4103,11 @@
|
||||
<li><a href="#terraform-release-management">Terraform Release Management</a></li>
|
||||
</ul>
|
||||
</li>
|
||||
<li><a href="#developer-experience-1">Developer Experience</a></li>
|
||||
<li><a href="#ai-assisted-coding">AI-Assisted Coding</a><ul>
|
||||
<li><a href="#claude-code">Claude Code</a></li>
|
||||
</ul>
|
||||
</li>
|
||||
<li><a href="#finops-and-cloud-cost">FinOps and Cloud Cost</a></li>
|
||||
<li><a href="#iac-finops">IaC FinOps</a><ul>
|
||||
<li><a href="#terraform-integration">Terraform Integration</a></li>
|
||||
@@ -4011,11 +4139,15 @@
|
||||
<li><a href="#foundational-reading">Foundational Reading</a></li>
|
||||
<li><a href="#introduction">Introduction</a></li>
|
||||
<li><a href="#platform-engineering-1">Platform Engineering</a></li>
|
||||
<li><a href="#developer-experience">Developer Experience</a><ul>
|
||||
<li><a href="#developer-experience-2">Developer Experience</a><ul>
|
||||
<li><a href="#continuous-delivery-3">Continuous Delivery</a></li>
|
||||
</ul>
|
||||
</li>
|
||||
<li><a href="#software-engineering">Software Engineering</a></li>
|
||||
<li><a href="#ai-tools">AI Tools</a><ul>
|
||||
<li><a href="#developer-productivity-2">Developer Productivity</a></li>
|
||||
</ul>
|
||||
</li>
|
||||
<li><a href="#ai-assisted-development">AI-Assisted Development</a><ul>
|
||||
<li><a href="#github-copilot">GitHub Copilot</a></li>
|
||||
</ul>
|
||||
@@ -4039,6 +4171,12 @@
|
||||
<ul>
|
||||
<li><strong>(2024)</strong> <a href="https://www.youtube.com/watch?si=dWSDPD4eXvF3dx5r&v=gnYU0jtQbug&feature=youtu.be">GitBook Webinar: GitBook for Public Docs</a> <span class='md-tag md-tag--info'>[COMMUNITY-TOOL]</span> — Webinar presentation highlighting standard configurations for establishing clear, highly readable public documentation using GitBook, emphasizing real-time integrations and Markdown-based code setups.</li>
|
||||
</ul>
|
||||
<h2 id="ai-engineering">AI Engineering<a class="headerlink" href="#ai-engineering" title="Permanent link">¶</a></h2>
|
||||
<h3 id="agentic-frameworks">Agentic Frameworks<a class="headerlink" href="#agentic-frameworks" title="Permanent link">¶</a></h3>
|
||||
<h4 id="developer-experience">Developer Experience<a class="headerlink" href="#developer-experience" title="Permanent link">¶</a></h4>
|
||||
<ul>
|
||||
<li><strong>(2025)</strong> <a href="https://kiro.dev">Kiro: Engineering Rigor for Agentic Development</a> <span class='md-tag md-tag--warning'>[TYPESCRIPT CONTENT]</span> <span class='md-tag md-tag--critical'>[ADVANCED LEVEL]</span> <span class='md-tag md-tag--info'>[COMMUNITY-TOOL]</span> — Kiro is a testing and engineering framework designed to bring traditional software discipline—such as regression testing, linting, and sandbox executing—to LLM agents and multi-agent workflows. It establishes strict validation steps to ensure agent behaviors remain deterministic, secure, and aligned with standard corporate software engineering guidelines.</li>
|
||||
</ul>
|
||||
<h2 id="architectural-foundations">Architectural Foundations<a class="headerlink" href="#architectural-foundations" title="Permanent link">¶</a></h2>
|
||||
<h3 id="kubernetes-tools">Kubernetes Tools<a class="headerlink" href="#kubernetes-tools" title="Permanent link">¶</a></h3>
|
||||
<h4 id="general-reference">General Reference<a class="headerlink" href="#general-reference" title="Permanent link">¶</a></h4>
|
||||
@@ -4318,6 +4456,12 @@
|
||||
<ul>
|
||||
<li><strong>(2026)</strong> <a href="https://github.com/techpivot/terraform-module-releaser">Terraform Module Releaser GitHub Action</a> <span class='md-tag md-tag--info'>⭐ 223</span> <svg class="v2-sparkline" width="50" height="15" viewBox="0 0 50 15" style="vertical-align: middle; display: inline-block; margin-left: 6px;" title="Activity Trend"><defs><linearGradient id="spark-grad-2ab0fdde" x1="0" y1="0" x2="1" y2="0"><stop offset="0%" stop-color="rgba(34, 211, 238, 0.2)" /><stop offset="100%" stop-color="var(--md-accent-fg-color)" /></linearGradient></defs><path class="v2-sparkline-path" d="M 0 7 L 10 10 L 20 12 L 30 5 L 40 2 L 50 11" fill="none" stroke="url(#spark-grad-2ab0fdde)" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round" /><circle cx="50" cy="11" r="2" fill="var(--md-accent-fg-color)" /></svg> <span class='md-tag md-tag--warning'>[TYPESCRIPT CONTENT]</span> 🌟🌟 <span class='md-tag md-tag--info'>[COMMUNITY-TOOL]</span> — An automated GitHub Action that manages release tagging, semantic version tracking, and registration publication processes for Terraform modules. Mitigates distribution overhead by auto-generating changelogs and managing tags.</li>
|
||||
</ul>
|
||||
<h2 id="developer-experience-1">Developer Experience (1)<a class="headerlink" href="#developer-experience-1" title="Permanent link">¶</a></h2>
|
||||
<h3 id="ai-assisted-coding">AI-Assisted Coding<a class="headerlink" href="#ai-assisted-coding" title="Permanent link">¶</a></h3>
|
||||
<h4 id="claude-code">Claude Code<a class="headerlink" href="#claude-code" title="Permanent link">¶</a></h4>
|
||||
<ul>
|
||||
<li><strong>(2025)</strong> <a href="https://anthropic.skilljar.com/claude-code-in-action">Claude Code in Action</a> <span class='md-tag md-tag--warning'>[NONE CONTENT]</span> <span class='md-tag md-tag--info'>[COMMUNITY-TOOL]</span> <span class='md-tag md-tag--secondary'>[GUIDE]</span> — An official hands-on tutorial and demonstration course by Anthropic showing the real-world utility of Claude Code. It covers basic terminal setups, interactive file refactoring, automated git commit orchestration, and contextual testing loops. Highly valuable for teams integrating terminal-based AI agents directly into daily engineering pipelines.</li>
|
||||
</ul>
|
||||
<h2 id="finops-and-cloud-cost">FinOps and Cloud Cost<a class="headerlink" href="#finops-and-cloud-cost" title="Permanent link">¶</a></h2>
|
||||
<h3 id="iac-finops">IaC FinOps<a class="headerlink" href="#iac-finops" title="Permanent link">¶</a></h3>
|
||||
<h4 id="terraform-integration">Terraform Integration<a class="headerlink" href="#terraform-integration" title="Permanent link">¶</a></h4>
|
||||
@@ -4366,12 +4510,17 @@
|
||||
<li><strong>(2018)</strong> <a href="https://opensource.com/article/18/8/what-cicd">opensource.com: What is CI/CD?</a> <span class='md-tag md-tag--info'>[COMMUNITY-TOOL]</span> — A foundational educational guide detailing the concepts, benefits, and components of Continuous Integration and Continuous Deployment (CI/CD). It explains how pipeline automation accelerates software delivery, guarantees build consistency, and serves as the operational substrate for DevOps cultures.</li>
|
||||
</ul>
|
||||
<h2 id="platform-engineering-1">Platform Engineering (1)<a class="headerlink" href="#platform-engineering-1" title="Permanent link">¶</a></h2>
|
||||
<h3 id="developer-experience">Developer Experience<a class="headerlink" href="#developer-experience" title="Permanent link">¶</a></h3>
|
||||
<h3 id="developer-experience-2">Developer Experience (2)<a class="headerlink" href="#developer-experience-2" title="Permanent link">¶</a></h3>
|
||||
<h4 id="continuous-delivery-3">Continuous Delivery (3)<a class="headerlink" href="#continuous-delivery-3" title="Permanent link">¶</a></h4>
|
||||
<ul>
|
||||
<li><strong>(2023)</strong> <a href="https://thenewstack.io/improve-dev-experience-to-maximize-the-business-value-of-cd">thenewstack.io: Improve Dev Experience to Maximize the Business Value of CD</a> <span class='md-tag md-tag--info'>[COMMUNITY-TOOL]</span> — Explores developer experience (DevEx) as an accelerator for continuous deployment initiatives. Details how centralized developer portals and self-service pipeline catalogs eliminate delivery friction.</li>
|
||||
</ul>
|
||||
<h2 id="software-engineering">Software Engineering<a class="headerlink" href="#software-engineering" title="Permanent link">¶</a></h2>
|
||||
<h3 id="ai-tools">AI Tools<a class="headerlink" href="#ai-tools" title="Permanent link">¶</a></h3>
|
||||
<h4 id="developer-productivity-2">Developer Productivity (2)<a class="headerlink" href="#developer-productivity-2" title="Permanent link">¶</a></h4>
|
||||
<ul>
|
||||
<li><strong>(2024)</strong> <a href="https://techcommunity.microsoft.com/blog/azuredevcommunityblog/programming-with-github-copilot-agent-mode/4400630"><strong>Programming with GitHub Copilot Agent Mode</strong></a> 🌟🌟🌟🌟 <span class='md-tag md-tag--success'>[ENTERPRISE-STABLE]</span> — A deep dive into the engineering capabilities of GitHub Copilot's 'Agent Mode.' It details how the agent acts autonomously to analyze workspace dependencies, generate multi-file modifications, run localized compilations, and iterate on test suites based on natural language prompts.</li>
|
||||
</ul>
|
||||
<h3 id="ai-assisted-development">AI-Assisted Development<a class="headerlink" href="#ai-assisted-development" title="Permanent link">¶</a></h3>
|
||||
<h4 id="github-copilot">GitHub Copilot<a class="headerlink" href="#github-copilot" title="Permanent link">¶</a></h4>
|
||||
<ul>
|
||||
|
||||
@@ -1482,6 +1482,17 @@
|
||||
</span>
|
||||
</a>
|
||||
|
||||
</li>
|
||||
|
||||
<li class="md-nav__item">
|
||||
<a href="#cursor-ide" class="md-nav__link">
|
||||
<span class="md-ellipsis">
|
||||
|
||||
Cursor IDE
|
||||
|
||||
</span>
|
||||
</a>
|
||||
|
||||
</li>
|
||||
|
||||
</ul>
|
||||
@@ -2090,6 +2101,51 @@
|
||||
</ul>
|
||||
</nav>
|
||||
|
||||
</li>
|
||||
|
||||
<li class="md-nav__item">
|
||||
<a href="#software-architecture-and-net-development" class="md-nav__link">
|
||||
<span class="md-ellipsis">
|
||||
|
||||
Software Architecture and .NET Development
|
||||
|
||||
</span>
|
||||
</a>
|
||||
|
||||
<nav class="md-nav" aria-label="Software Architecture and .NET Development">
|
||||
<ul class="md-nav__list">
|
||||
|
||||
<li class="md-nav__item">
|
||||
<a href="#artificial-intelligence" class="md-nav__link">
|
||||
<span class="md-ellipsis">
|
||||
|
||||
Artificial Intelligence
|
||||
|
||||
</span>
|
||||
</a>
|
||||
|
||||
<nav class="md-nav" aria-label="Artificial Intelligence">
|
||||
<ul class="md-nav__list">
|
||||
|
||||
<li class="md-nav__item">
|
||||
<a href="#agent-integration" class="md-nav__link">
|
||||
<span class="md-ellipsis">
|
||||
|
||||
Agent Integration
|
||||
|
||||
</span>
|
||||
</a>
|
||||
|
||||
</li>
|
||||
|
||||
</ul>
|
||||
</nav>
|
||||
|
||||
</li>
|
||||
|
||||
</ul>
|
||||
</nav>
|
||||
|
||||
</li>
|
||||
|
||||
<li class="md-nav__item">
|
||||
@@ -2116,6 +2172,17 @@
|
||||
<nav class="md-nav" aria-label="AI-Assisted Development">
|
||||
<ul class="md-nav__list">
|
||||
|
||||
<li class="md-nav__item">
|
||||
<a href="#cli-tools" class="md-nav__link">
|
||||
<span class="md-ellipsis">
|
||||
|
||||
CLI Tools
|
||||
|
||||
</span>
|
||||
</a>
|
||||
|
||||
</li>
|
||||
|
||||
<li class="md-nav__item">
|
||||
<a href="#github-copilot" class="md-nav__link">
|
||||
<span class="md-ellipsis">
|
||||
@@ -2125,6 +2192,17 @@
|
||||
</span>
|
||||
</a>
|
||||
|
||||
</li>
|
||||
|
||||
<li class="md-nav__item">
|
||||
<a href="#multi-repository-architecture" class="md-nav__link">
|
||||
<span class="md-ellipsis">
|
||||
|
||||
Multi-Repository Architecture
|
||||
|
||||
</span>
|
||||
</a>
|
||||
|
||||
</li>
|
||||
|
||||
</ul>
|
||||
@@ -2158,6 +2236,34 @@
|
||||
</ul>
|
||||
</nav>
|
||||
|
||||
</li>
|
||||
|
||||
<li class="md-nav__item">
|
||||
<a href="#command-line-utilities" class="md-nav__link">
|
||||
<span class="md-ellipsis">
|
||||
|
||||
Command-Line Utilities
|
||||
|
||||
</span>
|
||||
</a>
|
||||
|
||||
<nav class="md-nav" aria-label="Command-Line Utilities">
|
||||
<ul class="md-nav__list">
|
||||
|
||||
<li class="md-nav__item">
|
||||
<a href="#terminal-emulators" class="md-nav__link">
|
||||
<span class="md-ellipsis">
|
||||
|
||||
Terminal Emulators
|
||||
|
||||
</span>
|
||||
</a>
|
||||
|
||||
</li>
|
||||
|
||||
</ul>
|
||||
</nav>
|
||||
|
||||
</li>
|
||||
|
||||
<li class="md-nav__item">
|
||||
@@ -3231,6 +3337,7 @@
|
||||
<li><a href="#developer-experience">Developer Experience</a></li>
|
||||
<li><a href="#ai-assisted-coding">AI-Assisted Coding</a><ul>
|
||||
<li><a href="#claude-code">Claude Code</a></li>
|
||||
<li><a href="#cursor-ide">Cursor IDE</a></li>
|
||||
</ul>
|
||||
</li>
|
||||
<li><a href="#developer-platforms">Developer Platforms</a></li>
|
||||
@@ -3299,15 +3406,26 @@
|
||||
<li><a href="#tutorials-1">Tutorials</a></li>
|
||||
</ul>
|
||||
</li>
|
||||
<li><a href="#software-architecture-and-net-development">Software Architecture and .NET Development</a></li>
|
||||
<li><a href="#artificial-intelligence">Artificial Intelligence</a><ul>
|
||||
<li><a href="#agent-integration">Agent Integration</a></li>
|
||||
</ul>
|
||||
</li>
|
||||
<li><a href="#software-engineering">Software Engineering</a></li>
|
||||
<li><a href="#ai-assisted-development">AI-Assisted Development</a><ul>
|
||||
<li><a href="#cli-tools">CLI Tools</a></li>
|
||||
<li><a href="#github-copilot">GitHub Copilot</a></li>
|
||||
<li><a href="#multi-repository-architecture">Multi-Repository Architecture</a></li>
|
||||
</ul>
|
||||
</li>
|
||||
<li><a href="#collaboration">Collaboration</a><ul>
|
||||
<li><a href="#documentation-specifications">Documentation Specifications</a></li>
|
||||
</ul>
|
||||
</li>
|
||||
<li><a href="#command-line-utilities">Command-Line Utilities</a><ul>
|
||||
<li><a href="#terminal-emulators">Terminal Emulators</a></li>
|
||||
</ul>
|
||||
</li>
|
||||
<li><a href="#programming-paradigms">Programming Paradigms</a><ul>
|
||||
<li><a href="#functional-programming">Functional Programming</a></li>
|
||||
</ul>
|
||||
@@ -3439,6 +3557,10 @@
|
||||
<ul>
|
||||
<li><strong>(2025)</strong> <a href="https://github.com/shanraisshan/claude-code-best-practice"><mark>Claude Code Best Practice</mark></a> <span class='md-tag md-tag--info'>⭐ 57660</span> <svg class="v2-sparkline" width="50" height="15" viewBox="0 0 50 15" style="vertical-align: middle; display: inline-block; margin-left: 6px;" title="Activity Trend"><defs><linearGradient id="spark-grad-26ea52d5" x1="0" y1="0" x2="1" y2="0"><stop offset="0%" stop-color="rgba(34, 211, 238, 0.2)" /><stop offset="100%" stop-color="var(--md-accent-fg-color)" /></linearGradient></defs><path class="v2-sparkline-path" d="M 0 3 L 10 2 L 20 3 L 30 5 L 40 3 L 50 2" fill="none" stroke="url(#spark-grad-26ea52d5)" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round" /><circle cx="50" cy="2" r="2" fill="var(--md-accent-fg-color)" /></svg> <span class='md-tag md-tag--warning'>[MARKDOWN CONTENT]</span> 🌟🌟🌟🌟🌟 <span class='md-tag md-tag--success'>[DE FACTO STANDARD]</span> <span class='md-tag md-tag--secondary'>[GUIDE]</span> — Curator Insight: Curated collection of best practices, system prompts, and architecture layouts for Claude Code. Live Grounding: Explores advanced CLI-driven agent workflows, highlighting configuration optimizations, shell integration strategies, and secure execution configurations in local and remote environments.</li>
|
||||
</ul>
|
||||
<h4 id="cursor-ide">Cursor IDE<a class="headerlink" href="#cursor-ide" title="Permanent link">¶</a></h4>
|
||||
<ul>
|
||||
<li><strong>(2025)</strong> <a href="https://cursor.com/es/learn">Cursor AI Fundamentals Course</a> <span class='md-tag md-tag--warning'>[NONE CONTENT]</span> <span class='md-tag md-tag--secondary'>[GUIDE]</span> <span class='md-tag md-tag--critical'>[LEGACY]</span> — An educational program designed to train engineers on utilizing the Cursor AI code editor effectively. The curriculum covers foundational concepts of context inclusion, codebase indexing, and multi-file code transformations. It teaches developers how to write highly optimized prompts to synthesize software architecture and debug legacy systems directly inside the IDE.</li>
|
||||
</ul>
|
||||
<h2 id="developer-platforms">Developer Platforms<a class="headerlink" href="#developer-platforms" title="Permanent link">¶</a></h2>
|
||||
<h3 id="documentation">Documentation<a class="headerlink" href="#documentation" title="Permanent link">¶</a></h3>
|
||||
<h4 id="github-wiki">GitHub Wiki<a class="headerlink" href="#github-wiki" title="Permanent link">¶</a></h4>
|
||||
@@ -3617,17 +3739,36 @@
|
||||
<ul>
|
||||
<li><strong>(2024)</strong> <a href="https://piotrminkowski.com/2024/06/13/getting-started-with-backstage">piotrminkowski.com: Getting Started with Backstage</a> 🌟🌟🌟 <span class='md-tag md-tag--info'>[COMMUNITY-TOOL]</span> — A comprehensive technical guide to bootstrapping Backstage, configuring the software catalog, and writing custom templates. The resource outlines practical steps to integrate local tooling with the developer portal, enabling swift adoption of self-service developer templates.</li>
|
||||
</ul>
|
||||
<h2 id="software-architecture-and-net-development">Software Architecture and .NET Development<a class="headerlink" href="#software-architecture-and-net-development" title="Permanent link">¶</a></h2>
|
||||
<h3 id="artificial-intelligence">Artificial Intelligence<a class="headerlink" href="#artificial-intelligence" title="Permanent link">¶</a></h3>
|
||||
<h4 id="agent-integration">Agent Integration<a class="headerlink" href="#agent-integration" title="Permanent link">¶</a></h4>
|
||||
<ul>
|
||||
<li><strong>(2024)</strong> <a href="https://devblogs.microsoft.com/dotnet/extend-your-coding-agent-with-dotnet-skills">Extend your coding agent with .NET Skills</a> <span class='md-tag md-tag--warning'>[C# CONTENT]</span> <span class='md-tag md-tag--critical'>[ADVANCED LEVEL]</span> <span class='md-tag md-tag--info'>[COMMUNITY-TOOL]</span> — Examines methods for extending autonomous AI coding agents with direct .NET skill injection. Uses Semantic Kernel to build tools enabling LLMs to execute C# compilations, format files, and interact natively with code bases.</li>
|
||||
</ul>
|
||||
<h2 id="software-engineering">Software Engineering<a class="headerlink" href="#software-engineering" title="Permanent link">¶</a></h2>
|
||||
<h3 id="ai-assisted-development">AI-Assisted Development<a class="headerlink" href="#ai-assisted-development" title="Permanent link">¶</a></h3>
|
||||
<h4 id="cli-tools">CLI Tools<a class="headerlink" href="#cli-tools" title="Permanent link">¶</a></h4>
|
||||
<ul>
|
||||
<li><strong>(2026)</strong> <a href="https://github.blog/ai-and-ml/github-copilot/github-copilot-cli-for-beginners-getting-started-with-github-copilot-cli">GitHub Copilot CLI for Beginners: Getting Started</a> <span class='md-tag md-tag--info'>[COMMUNITY-TOOL]</span> <span class='md-tag md-tag--secondary'>[GUIDE]</span> — Highlights setup and early integration techniques for GitHub Copilot CLI, translating natural language prompts into executable terminal and shell scripts. Enhances sysadmin and shell workflow automation while maintaining a human-in-the-loop review step for safety and correctness.</li>
|
||||
</ul>
|
||||
<h4 id="github-copilot">GitHub Copilot<a class="headerlink" href="#github-copilot" title="Permanent link">¶</a></h4>
|
||||
<ul>
|
||||
<li><strong>(2026)</strong> <a href="https://docs.github.com/en/copilot/get-started/best-practices">Best Practices for Using GitHub Copilot</a> <span class='md-tag md-tag--primary'>[DOCUMENTATION]</span> <span class='md-tag md-tag--info'>[COMMUNITY-TOOL]</span> — Authoritative guidelines from GitHub designed to optimize interaction with Copilot. Covers prompt engineering tactics (such as context-setting files and comments), managing AI security and license compliance, and verifying generated output.</li>
|
||||
</ul>
|
||||
<h4 id="multi-repository-architecture">Multi-Repository Architecture<a class="headerlink" href="#multi-repository-architecture" title="Permanent link">¶</a></h4>
|
||||
<ul>
|
||||
<li><strong>(2025)</strong> <a href="https://ettema.dev/posts/ai-multi-repo-workspaces">Using Workspaces for AI Changes Across Multiple Repos</a> <span class='md-tag md-tag--critical'>[ADVANCED LEVEL]</span> <span class='md-tag md-tag--info'>[COMMUNITY-TOOL]</span> — Details advanced patterns for orchestrating automated codebase modifications across distributed multi-repository environments using AI workspaces. Evaluates dependency resolution, unified context indexing, and coordinate git-commit strategies during systemic API breaking updates.</li>
|
||||
</ul>
|
||||
<h3 id="collaboration">Collaboration<a class="headerlink" href="#collaboration" title="Permanent link">¶</a></h3>
|
||||
<h4 id="documentation-specifications">Documentation Specifications<a class="headerlink" href="#documentation-specifications" title="Permanent link">¶</a></h4>
|
||||
<ul>
|
||||
<li><strong>(2023)</strong> <a href="https://www.youtube.com/live/2IArMAhkJcE?si=_LlIjakRXHUzERjy">Open Source Friday: Spec Kit - What it is, the problems it solves, and how clear specs make collaboration work</a> <span class='md-tag md-tag--info'>[COMMUNITY-TOOL]</span> — Focuses on 'Spec Kit' - an open framework designed to facilitate collaborative creation of technical specifications. Details how clear, shared specification templates improve open-source contributions, bridge communication gaps between product and engineering, and keep technical debt in check.</li>
|
||||
</ul>
|
||||
<h3 id="command-line-utilities">Command-Line Utilities<a class="headerlink" href="#command-line-utilities" title="Permanent link">¶</a></h3>
|
||||
<h4 id="terminal-emulators">Terminal Emulators<a class="headerlink" href="#terminal-emulators" title="Permanent link">¶</a></h4>
|
||||
<ul>
|
||||
<li><strong>(2026)</strong> <a href="https://www.warp.dev">Warp: The Agentic Development Environment</a> <span class='md-tag md-tag--info'>[COMMUNITY-TOOL]</span> — A modern, Rust-based terminal emulator incorporating AI agent assistance directly into the command-line interface. Reimagines input fields like text editors, supports real-time workspace collaboration, and native context-sharing for accelerated platform ops troubleshooting.</li>
|
||||
</ul>
|
||||
<h3 id="programming-paradigms">Programming Paradigms<a class="headerlink" href="#programming-paradigms" title="Permanent link">¶</a></h3>
|
||||
<h4 id="functional-programming">Functional Programming<a class="headerlink" href="#functional-programming" title="Permanent link">¶</a></h4>
|
||||
<ul>
|
||||
|
||||
@@ -1584,6 +1584,17 @@
|
||||
<nav class="md-nav" aria-label="AI Code Assistants">
|
||||
<ul class="md-nav__list">
|
||||
|
||||
<li class="md-nav__item">
|
||||
<a href="#effort-frameworks" class="md-nav__link">
|
||||
<span class="md-ellipsis">
|
||||
|
||||
Effort Frameworks
|
||||
|
||||
</span>
|
||||
</a>
|
||||
|
||||
</li>
|
||||
|
||||
<li class="md-nav__item">
|
||||
<a href="#prompt-templates" class="md-nav__link">
|
||||
<span class="md-ellipsis">
|
||||
@@ -3195,6 +3206,7 @@
|
||||
</li>
|
||||
<li><a href="#developer-tooling">Developer Tooling</a></li>
|
||||
<li><a href="#ai-code-assistants">AI Code Assistants</a><ul>
|
||||
<li><a href="#effort-frameworks">Effort Frameworks</a></li>
|
||||
<li><a href="#prompt-templates">Prompt Templates</a></li>
|
||||
</ul>
|
||||
</li>
|
||||
@@ -3352,6 +3364,10 @@
|
||||
</ul>
|
||||
<h2 id="developer-tooling">Developer Tooling<a class="headerlink" href="#developer-tooling" title="Permanent link">¶</a></h2>
|
||||
<h3 id="ai-code-assistants">AI Code Assistants<a class="headerlink" href="#ai-code-assistants" title="Permanent link">¶</a></h3>
|
||||
<h4 id="effort-frameworks">Effort Frameworks<a class="headerlink" href="#effort-frameworks" title="Permanent link">¶</a></h4>
|
||||
<ul>
|
||||
<li><strong>(2026)</strong> <a href="https://cursor.com/docs/bugbot">Cursor Bugbot Effort Levels Documentation</a> <span class='md-tag md-tag--warning'>[N/A CONTENT]</span> <span class='md-tag md-tag--primary'>[DOCUMENTATION]</span> <span class='md-tag md-tag--info'>[COMMUNITY-TOOL]</span> — This reference document outlines the effort metrics and execution paradigms utilized by Cursor's Bugbot tool inside the editor context. It guides development teams in managing priority levels for automated debugging routines across repositories.</li>
|
||||
</ul>
|
||||
<h4 id="prompt-templates">Prompt Templates<a class="headerlink" href="#prompt-templates" title="Permanent link">¶</a></h4>
|
||||
<ul>
|
||||
<li><strong>(2026)</strong> <a href="https://github.com/davila7/claude-code-templates"><mark>Claude Code Templates</mark></a> <span class='md-tag md-tag--info'>⭐ 28036</span> <svg class="v2-sparkline" width="50" height="15" viewBox="0 0 50 15" style="vertical-align: middle; display: inline-block; margin-left: 6px;" title="Activity Trend"><defs><linearGradient id="spark-grad-95ae7120" x1="0" y1="0" x2="1" y2="0"><stop offset="0%" stop-color="rgba(34, 211, 238, 0.2)" /><stop offset="100%" stop-color="var(--md-accent-fg-color)" /></linearGradient></defs><path class="v2-sparkline-path" d="M 0 12 L 10 2 L 20 11 L 30 13 L 40 7 L 50 5" fill="none" stroke="url(#spark-grad-95ae7120)" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round" /><circle cx="50" cy="5" r="2" fill="var(--md-accent-fg-color)" /></svg> <span class='md-tag md-tag--warning'>[MARKDOWN CONTENT]</span> <span class='md-tag md-tag--critical'>[ADVANCED LEVEL]</span> 🌟🌟🌟🌟🌟 <span class='md-tag md-tag--success'>[DE FACTO STANDARD]</span> — Claude Code Templates is an extensive community library containing structured system designs, context guidelines, and prompt schemas optimized for Anthropic's Claude Code and CLI. It helps teams configure context-aware coding agents that integrate smoothly into microservice development cycles.</li>
|
||||
|
||||
@@ -1279,6 +1279,34 @@
|
||||
<nav class="md-nav" aria-label="Automation">
|
||||
<ul class="md-nav__list">
|
||||
|
||||
<li class="md-nav__item">
|
||||
<a href="#agentic-systems" class="md-nav__link">
|
||||
<span class="md-ellipsis">
|
||||
|
||||
Agentic Systems
|
||||
|
||||
</span>
|
||||
</a>
|
||||
|
||||
<nav class="md-nav" aria-label="Agentic Systems">
|
||||
<ul class="md-nav__list">
|
||||
|
||||
<li class="md-nav__item">
|
||||
<a href="#mcp-server" class="md-nav__link">
|
||||
<span class="md-ellipsis">
|
||||
|
||||
MCP Server
|
||||
|
||||
</span>
|
||||
</a>
|
||||
|
||||
</li>
|
||||
|
||||
</ul>
|
||||
</nav>
|
||||
|
||||
</li>
|
||||
|
||||
<li class="md-nav__item">
|
||||
<a href="#noops-evolution" class="md-nav__link">
|
||||
<span class="md-ellipsis">
|
||||
@@ -7439,6 +7467,10 @@
|
||||
</ul>
|
||||
</li>
|
||||
<li><a href="#automation">Automation</a></li>
|
||||
<li><a href="#agentic-systems">Agentic Systems</a><ul>
|
||||
<li><a href="#mcp-server">MCP Server</a></li>
|
||||
</ul>
|
||||
</li>
|
||||
<li><a href="#noops-evolution">NoOps Evolution</a></li>
|
||||
<li><a href="#automation-and-orchestration">Automation and Orchestration</a></li>
|
||||
<li><a href="#ansible">Ansible</a><ul>
|
||||
@@ -8138,6 +8170,11 @@
|
||||
<li><strong>(2023)</strong> <a href="https://newsletter.francofernando.com/p/the-12-factor-app-an-updated-guide">The 12-Factor App: An Updated Guide</a> <span class='md-tag md-tag--info'>[COMMUNITY-TOOL]</span> <span class='md-tag md-tag--secondary'>[GUIDE]</span> — Revisits the classic 12-Factor app principles through a modern cloud-native lens. Analyzes how declarations like declarative formats, clean environment parity, and port binding apply to contemporary container networks.</li>
|
||||
</ul>
|
||||
<h2 id="automation">Automation<a class="headerlink" href="#automation" title="Permanent link">¶</a></h2>
|
||||
<h3 id="agentic-systems">Agentic Systems<a class="headerlink" href="#agentic-systems" title="Permanent link">¶</a></h3>
|
||||
<h4 id="mcp-server">MCP Server<a class="headerlink" href="#mcp-server" title="Permanent link">¶</a></h4>
|
||||
<ul>
|
||||
<li><strong>(2026)</strong> <a href="https://devblogs.microsoft.com/azure-sdk/announcing-azure-mcp-server-2-0-stable-release">Announcing Azure MCP Server 2.0 Stable Release for Self-Hosted Agentic Cloud Automation</a> <span class='md-tag md-tag--warning'>[TYPESCRIPT CONTENT]</span> <span class='md-tag md-tag--critical'>[ADVANCED LEVEL]</span> <span class='md-tag md-tag--info'>[COMMUNITY-TOOL]</span> — Details the stable release of Azure MCP (Model Context Protocol) Server 2.0, enabling secure, self-hosted agentic automation workflows. It provides architectural patterns for running local AI agents with direct, API-driven access to Azure resource management, optimizing operational automation via language model integrations.</li>
|
||||
</ul>
|
||||
<h3 id="noops-evolution">NoOps Evolution<a class="headerlink" href="#noops-evolution" title="Permanent link">¶</a></h3>
|
||||
<ul>
|
||||
<li><strong>(2020)</strong> <a href="https://enterprisersproject.com/article/2020/3/how-get-devops-noops-5-steps">How to get from DevOps to NoOps: 5 steps</a> <span class='md-tag md-tag--warning'>[N/A CONTENT]</span> <span class='md-tag md-tag--critical'>[ADVANCED LEVEL]</span> 🌟 <span class='md-tag md-tag--info'>[COMMUNITY-TOOL]</span> — Proposes a five-step path toward fully abstracted, frictionless environments (NoOps). Argues that standard automation must evolve into self-healing platforms that hide low-level operations from microservice developers.</li>
|
||||
|
||||
@@ -1968,6 +1968,51 @@
|
||||
</ul>
|
||||
</nav>
|
||||
|
||||
</li>
|
||||
|
||||
<li class="md-nav__item">
|
||||
<a href="#emerging-technology" class="md-nav__link">
|
||||
<span class="md-ellipsis">
|
||||
|
||||
Emerging Technology
|
||||
|
||||
</span>
|
||||
</a>
|
||||
|
||||
<nav class="md-nav" aria-label="Emerging Technology">
|
||||
<ul class="md-nav__list">
|
||||
|
||||
<li class="md-nav__item">
|
||||
<a href="#machine-learning" class="md-nav__link">
|
||||
<span class="md-ellipsis">
|
||||
|
||||
Machine Learning
|
||||
|
||||
</span>
|
||||
</a>
|
||||
|
||||
<nav class="md-nav" aria-label="Machine Learning">
|
||||
<ul class="md-nav__list">
|
||||
|
||||
<li class="md-nav__item">
|
||||
<a href="#course" class="md-nav__link">
|
||||
<span class="md-ellipsis">
|
||||
|
||||
Course
|
||||
|
||||
</span>
|
||||
</a>
|
||||
|
||||
</li>
|
||||
|
||||
</ul>
|
||||
</nav>
|
||||
|
||||
</li>
|
||||
|
||||
</ul>
|
||||
</nav>
|
||||
|
||||
</li>
|
||||
|
||||
<li class="md-nav__item">
|
||||
@@ -2892,6 +2937,11 @@
|
||||
<li><a href="#gamified-learning">Gamified Learning</a></li>
|
||||
</ul>
|
||||
</li>
|
||||
<li><a href="#emerging-technology">Emerging Technology</a></li>
|
||||
<li><a href="#machine-learning">Machine Learning</a><ul>
|
||||
<li><a href="#course">Course</a></li>
|
||||
</ul>
|
||||
</li>
|
||||
<li><a href="#operating-systems-and-infrastructure">Operating Systems and Infrastructure</a></li>
|
||||
<li><a href="#linux">Linux</a><ul>
|
||||
<li><a href="#sysadmin-tutorials">SysAdmin Tutorials</a></li>
|
||||
@@ -3001,6 +3051,12 @@
|
||||
<ul>
|
||||
<li><strong>(2025)</strong> <a href="https://sqlpd.com">SQL Police Department</a> 🌟🌟🌟 <span class='md-tag md-tag--info'>[COMMUNITY-TOOL]</span> — A specialized gamified engine where users solve mock criminal investigations writing relational SQL queries. Highly effective for building structural query efficiency and database logic before moving to complex stateful containerization.</li>
|
||||
</ul>
|
||||
<h2 id="emerging-technology">Emerging Technology<a class="headerlink" href="#emerging-technology" title="Permanent link">¶</a></h2>
|
||||
<h3 id="machine-learning">Machine Learning<a class="headerlink" href="#machine-learning" title="Permanent link">¶</a></h3>
|
||||
<h4 id="course">Course<a class="headerlink" href="#course" title="Permanent link">¶</a></h4>
|
||||
<ul>
|
||||
<li><strong>(2024)</strong> <a href="https://developers.google.com/machine-learning/crash-course?hl=es-419">Machine Learning Crash Course</a> <span class='md-tag md-tag--warning'>[SPANISH CONTENT]</span> <span class='md-tag md-tag--info'>[COMMUNITY-TOOL]</span> <span class='md-tag md-tag--secondary'>[GUIDE]</span> — Google's structured technical course on ML foundations. Covers gradient descent, model loss, deep neural networks, and scalable tensor processing, serving as an entry point for engineers integrating ML systems into modern APIs.</li>
|
||||
</ul>
|
||||
<h2 id="operating-systems-and-infrastructure">Operating Systems and Infrastructure<a class="headerlink" href="#operating-systems-and-infrastructure" title="Permanent link">¶</a></h2>
|
||||
<h3 id="linux">Linux<a class="headerlink" href="#linux" title="Permanent link">¶</a></h3>
|
||||
<h4 id="sysadmin-tutorials">SysAdmin Tutorials<a class="headerlink" href="#sysadmin-tutorials" title="Permanent link">¶</a></h4>
|
||||
|
||||
@@ -2140,6 +2140,17 @@
|
||||
</span>
|
||||
</a>
|
||||
|
||||
</li>
|
||||
|
||||
<li class="md-nav__item">
|
||||
<a href="#automated-optimization" class="md-nav__link">
|
||||
<span class="md-ellipsis">
|
||||
|
||||
Automated Optimization
|
||||
|
||||
</span>
|
||||
</a>
|
||||
|
||||
</li>
|
||||
|
||||
<li class="md-nav__item">
|
||||
@@ -2734,6 +2745,7 @@
|
||||
<li><a href="#kubernetes-finops">Kubernetes FinOps</a><ul>
|
||||
<li><a href="#aks-cost-allocation">AKS Cost Allocation</a></li>
|
||||
<li><a href="#actionable-frameworks">Actionable Frameworks</a></li>
|
||||
<li><a href="#automated-optimization">Automated Optimization</a></li>
|
||||
<li><a href="#cost-management">Cost Management</a></li>
|
||||
<li><a href="#cost-platforms">Cost Platforms</a></li>
|
||||
<li><a href="#foundational-concepts">Foundational Concepts</a></li>
|
||||
@@ -2860,6 +2872,10 @@
|
||||
<ul>
|
||||
<li><strong>(2023)</strong> <a href="https://www.infoworld.com/article/2338303/5-steps-to-bringing-kubernetes-costs-in-line.html"><strong>infoworld.com: 5 steps to bringing Kubernetes costs in line</strong></a> 🌟🌟🌟🌟 <span class='md-tag md-tag--success'>[ENTERPRISE-STABLE]</span> — Presents a clear five-step methodology to control Kubernetes infrastructure spend. Covers standard practices like adjusting request/limit ratios, configuring cluster autoscalers (VPA/HPA), and moving non-critical workloads to spot instance pools.</li>
|
||||
</ul>
|
||||
<h4 id="automated-optimization">Automated Optimization<a class="headerlink" href="#automated-optimization" title="Permanent link">¶</a></h4>
|
||||
<ul>
|
||||
<li><strong>(2025)</strong> <a href="https://cast.ai"><mark>CAST AI</mark></a> <span class='md-tag md-tag--critical'>[ADVANCED LEVEL]</span> 🌟🌟🌟🌟🌟 <span class='md-tag md-tag--success'>[DE FACTO STANDARD]</span> — Introduces CAST AI, an automated cost-reduction system for EKS, AKS, and GKE. Highlights how its real-time algorithms adjust cluster sizing, configure spot instances, and scale down resources without manual developer effort.</li>
|
||||
</ul>
|
||||
<h4 id="cost-management">Cost Management<a class="headerlink" href="#cost-management" title="Permanent link">¶</a></h4>
|
||||
<ul>
|
||||
<li><strong>(2023)</strong> <a href="https://www.infoworld.com/article/2338428/kubernetes-cost-management-for-the-real-world.html"><mark>infoworld.com: Kubernetes cost management for the real world</mark></a> <span class='md-tag md-tag--critical'>[ADVANCED LEVEL]</span> 🌟🌟🌟🌟🌟 <span class='md-tag md-tag--success'>[DE FACTO STANDARD]</span> — A deep dive into the challenges of multi-tenant Kubernetes cost attribution across dynamic namespaces. Contrasts raw hyper-scaler billing records against granular container resource consumption metrics, detailing how Kubecost and OpenCost establish accurate, real-world chargeback frameworks.</li>
|
||||
|
||||
@@ -1751,51 +1751,6 @@
|
||||
</ul>
|
||||
</nav>
|
||||
|
||||
</li>
|
||||
|
||||
<li class="md-nav__item">
|
||||
<a href="#cloud-native-operations" class="md-nav__link">
|
||||
<span class="md-ellipsis">
|
||||
|
||||
Cloud Native Operations
|
||||
|
||||
</span>
|
||||
</a>
|
||||
|
||||
<nav class="md-nav" aria-label="Cloud Native Operations">
|
||||
<ul class="md-nav__list">
|
||||
|
||||
<li class="md-nav__item">
|
||||
<a href="#kubernetes" class="md-nav__link">
|
||||
<span class="md-ellipsis">
|
||||
|
||||
Kubernetes
|
||||
|
||||
</span>
|
||||
</a>
|
||||
|
||||
<nav class="md-nav" aria-label="Kubernetes">
|
||||
<ul class="md-nav__list">
|
||||
|
||||
<li class="md-nav__item">
|
||||
<a href="#policy-enforcement" class="md-nav__link">
|
||||
<span class="md-ellipsis">
|
||||
|
||||
Policy Enforcement
|
||||
|
||||
</span>
|
||||
</a>
|
||||
|
||||
</li>
|
||||
|
||||
</ul>
|
||||
</nav>
|
||||
|
||||
</li>
|
||||
|
||||
</ul>
|
||||
</nav>
|
||||
|
||||
</li>
|
||||
|
||||
<li class="md-nav__item">
|
||||
@@ -2031,10 +1986,10 @@
|
||||
<ul class="md-nav__list">
|
||||
|
||||
<li class="md-nav__item">
|
||||
<a href="#kubernetes-1" class="md-nav__link">
|
||||
<a href="#kubernetes" class="md-nav__link">
|
||||
<span class="md-ellipsis">
|
||||
|
||||
Kubernetes (1)
|
||||
Kubernetes
|
||||
|
||||
</span>
|
||||
</a>
|
||||
@@ -3655,6 +3610,79 @@
|
||||
</ul>
|
||||
</nav>
|
||||
|
||||
</li>
|
||||
|
||||
<li class="md-nav__item">
|
||||
<a href="#developer-productivity-2" class="md-nav__link">
|
||||
<span class="md-ellipsis">
|
||||
|
||||
Developer Productivity (2)
|
||||
|
||||
</span>
|
||||
</a>
|
||||
|
||||
<nav class="md-nav" aria-label="Developer Productivity (2)">
|
||||
<ul class="md-nav__list">
|
||||
|
||||
<li class="md-nav__item">
|
||||
<a href="#cicd" class="md-nav__link">
|
||||
<span class="md-ellipsis">
|
||||
|
||||
CICD
|
||||
|
||||
</span>
|
||||
</a>
|
||||
|
||||
<nav class="md-nav" aria-label="CICD">
|
||||
<ul class="md-nav__list">
|
||||
|
||||
<li class="md-nav__item">
|
||||
<a href="#github-actions-3" class="md-nav__link">
|
||||
<span class="md-ellipsis">
|
||||
|
||||
GitHub Actions (3)
|
||||
|
||||
</span>
|
||||
</a>
|
||||
|
||||
</li>
|
||||
|
||||
</ul>
|
||||
</nav>
|
||||
|
||||
</li>
|
||||
|
||||
<li class="md-nav__item">
|
||||
<a href="#ides" class="md-nav__link">
|
||||
<span class="md-ellipsis">
|
||||
|
||||
IDEs
|
||||
|
||||
</span>
|
||||
</a>
|
||||
|
||||
<nav class="md-nav" aria-label="IDEs">
|
||||
<ul class="md-nav__list">
|
||||
|
||||
<li class="md-nav__item">
|
||||
<a href="#github-copilot" class="md-nav__link">
|
||||
<span class="md-ellipsis">
|
||||
|
||||
GitHub Copilot
|
||||
|
||||
</span>
|
||||
</a>
|
||||
|
||||
</li>
|
||||
|
||||
</ul>
|
||||
</nav>
|
||||
|
||||
</li>
|
||||
|
||||
</ul>
|
||||
</nav>
|
||||
|
||||
</li>
|
||||
|
||||
<li class="md-nav__item">
|
||||
@@ -4074,10 +4102,10 @@
|
||||
</li>
|
||||
|
||||
<li class="md-nav__item">
|
||||
<a href="#developer-productivity-2" class="md-nav__link">
|
||||
<a href="#developer-productivity-3" class="md-nav__link">
|
||||
<span class="md-ellipsis">
|
||||
|
||||
Developer Productivity (2)
|
||||
Developer Productivity (3)
|
||||
|
||||
</span>
|
||||
</a>
|
||||
@@ -4300,15 +4328,15 @@
|
||||
</li>
|
||||
|
||||
<li class="md-nav__item">
|
||||
<a href="#developer-productivity-3" class="md-nav__link">
|
||||
<a href="#developer-productivity-4" class="md-nav__link">
|
||||
<span class="md-ellipsis">
|
||||
|
||||
Developer Productivity (3)
|
||||
Developer Productivity (4)
|
||||
|
||||
</span>
|
||||
</a>
|
||||
|
||||
<nav class="md-nav" aria-label="Developer Productivity (3)">
|
||||
<nav class="md-nav" aria-label="Developer Productivity (4)">
|
||||
<ul class="md-nav__list">
|
||||
|
||||
<li class="md-nav__item">
|
||||
@@ -6507,11 +6535,6 @@
|
||||
<li><a href="#gitlab-integrations">GitLab Integrations</a></li>
|
||||
</ul>
|
||||
</li>
|
||||
<li><a href="#cloud-native-operations">Cloud Native Operations</a></li>
|
||||
<li><a href="#kubernetes">Kubernetes</a><ul>
|
||||
<li><a href="#policy-enforcement">Policy Enforcement</a></li>
|
||||
</ul>
|
||||
</li>
|
||||
<li><a href="#community">Community</a></li>
|
||||
<li><a href="#developer-relations">Developer Relations</a><ul>
|
||||
<li><a href="#stack-overflow">Stack Overflow</a></li>
|
||||
@@ -6537,7 +6560,7 @@
|
||||
</li>
|
||||
<li><a href="#container-management">Container Management</a><ul>
|
||||
<li><a href="#github-container-registry">GitHub Container Registry</a></li>
|
||||
<li><a href="#kubernetes-1">Kubernetes</a></li>
|
||||
<li><a href="#kubernetes">Kubernetes</a></li>
|
||||
</ul>
|
||||
</li>
|
||||
<li><a href="#container-orchestration">Container Orchestration</a><ul>
|
||||
@@ -6715,6 +6738,15 @@
|
||||
<li><a href="#github-roadmap">GitHub Roadmap</a></li>
|
||||
</ul>
|
||||
</li>
|
||||
<li><a href="#developer-productivity-2">Developer Productivity</a></li>
|
||||
<li><a href="#cicd">CICD</a><ul>
|
||||
<li><a href="#github-actions-3">GitHub Actions</a></li>
|
||||
</ul>
|
||||
</li>
|
||||
<li><a href="#ides">IDEs</a><ul>
|
||||
<li><a href="#github-copilot">GitHub Copilot</a></li>
|
||||
</ul>
|
||||
</li>
|
||||
<li><a href="#engineering-education">Engineering Education</a></li>
|
||||
<li><a href="#developer-platform-1">Developer Platform</a><ul>
|
||||
<li><a href="#git-workflows-2">Git Workflows</a></li>
|
||||
@@ -6761,7 +6793,7 @@
|
||||
<li><a href="#case-studies">Case Studies</a></li>
|
||||
<li><a href="#competitive-landscape">Competitive Landscape</a></li>
|
||||
<li><a href="#copilot-ecosystem">Copilot Ecosystem</a></li>
|
||||
<li><a href="#developer-productivity-2">Developer Productivity</a></li>
|
||||
<li><a href="#developer-productivity-3">Developer Productivity</a></li>
|
||||
<li><a href="#ecosystem-launch">Ecosystem Launch</a></li>
|
||||
<li><a href="#education-and-prompts">Education and Prompts</a></li>
|
||||
<li><a href="#industry-analysis">Industry Analysis</a></li>
|
||||
@@ -6786,7 +6818,7 @@
|
||||
<li><a href="#kubernetes-integration">Kubernetes Integration</a></li>
|
||||
</ul>
|
||||
</li>
|
||||
<li><a href="#developer-productivity-3">Developer Productivity</a><ul>
|
||||
<li><a href="#developer-productivity-4">Developer Productivity</a><ul>
|
||||
<li><a href="#desktop-clients">Desktop Clients</a></li>
|
||||
<li><a href="#grafana-github-integration">Grafana GitHub Integration</a></li>
|
||||
<li><a href="#vs-code-extensions">VS Code Extensions</a></li>
|
||||
@@ -7013,12 +7045,6 @@
|
||||
<ul>
|
||||
<li><strong>(2022)</strong> <a href="https://about.gitlab.com/blog/simple-kubernetes-management-with-gitlab">about.gitlab.com: Simple Kubernetes management with GitLab</a> <span class='md-tag md-tag--info'>[COMMUNITY-TOOL]</span> — An architectural guide on using GitLab as a unified management plane for Kubernetes. Covers cluster connecting procedures, security posture monitoring, and automated Auto DevOps pipelines.</li>
|
||||
</ul>
|
||||
<h2 id="cloud-native-operations">Cloud Native Operations<a class="headerlink" href="#cloud-native-operations" title="Permanent link">¶</a></h2>
|
||||
<h3 id="kubernetes">Kubernetes<a class="headerlink" href="#kubernetes" title="Permanent link">¶</a></h3>
|
||||
<h4 id="policy-enforcement">Policy Enforcement<a class="headerlink" href="#policy-enforcement" title="Permanent link">¶</a></h4>
|
||||
<ul>
|
||||
<li><strong>(2022)</strong> <a href="https://www.datree.io"><mark>datree.io</mark></a> <span class='md-tag md-tag--warning'>[GO CONTENT]</span> 🌟🌟🌟🌟🌟 <span class='md-tag md-tag--success'>[DE FACTO STANDARD]</span> — An enterprise-grade CLI validation engine built to run policy and configuration checks on Kubernetes manifests. Datree evaluates configurations against schema rules and security standards before they reach clusters. This is a critical validation step for CI/CD GitOps pipelines.</li>
|
||||
</ul>
|
||||
<h2 id="community">Community<a class="headerlink" href="#community" title="Permanent link">¶</a></h2>
|
||||
<h3 id="developer-relations">Developer Relations<a class="headerlink" href="#developer-relations" title="Permanent link">¶</a></h3>
|
||||
<h4 id="stack-overflow">Stack Overflow<a class="headerlink" href="#stack-overflow" title="Permanent link">¶</a></h4>
|
||||
@@ -7058,7 +7084,7 @@
|
||||
</ul>
|
||||
<h3 id="container-management">Container Management<a class="headerlink" href="#container-management" title="Permanent link">¶</a></h3>
|
||||
<h4 id="github-container-registry">GitHub Container Registry<a class="headerlink" href="#github-container-registry" title="Permanent link">¶</a></h4>
|
||||
<h5 id="kubernetes-1">Kubernetes (1)<a class="headerlink" href="#kubernetes-1" title="Permanent link">¶</a></h5>
|
||||
<h5 id="kubernetes">Kubernetes<a class="headerlink" href="#kubernetes" title="Permanent link">¶</a></h5>
|
||||
<ul>
|
||||
<li><strong>(2021)</strong> <a href="https://itnext.io/build-ship-github-container-registry-kubernetes-aa06029b3f21">itnext.io: Build & Ship: GitHub Container Registry & Kubernetes</a> <span class='md-tag md-tag--warning'>[YAML CONTENT]</span> <span class='md-tag md-tag--info'>[COMMUNITY-TOOL]</span> — Deep technical walkthrough demonstrating CI/CD container assembly, pushing artifacts to GitHub Container Registry (GHCR), and orchestration within live Kubernetes endpoints.</li>
|
||||
</ul>
|
||||
@@ -7440,6 +7466,21 @@
|
||||
<ul>
|
||||
<li><strong>(2026)</strong> <a href="https://github.com/github/roadmap"><mark>GitHub public roadmap 🌟</mark></a> <span class='md-tag md-tag--info'>⭐ 8766</span> <svg class="v2-sparkline" width="50" height="15" viewBox="0 0 50 15" style="vertical-align: middle; display: inline-block; margin-left: 6px;" title="Activity Trend"><defs><linearGradient id="spark-grad-d51b664f" x1="0" y1="0" x2="1" y2="0"><stop offset="0%" stop-color="rgba(34, 211, 238, 0.2)" /><stop offset="100%" stop-color="var(--md-accent-fg-color)" /></linearGradient></defs><path class="v2-sparkline-path" d="M 0 10 L 10 6 L 20 8 L 30 5 L 40 11 L 50 5" fill="none" stroke="url(#spark-grad-d51b664f)" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round" /><circle cx="50" cy="5" r="2" fill="var(--md-accent-fg-color)" /></svg> <span class='md-tag md-tag--warning'>[MARKDOWN CONTENT]</span> 🌟🌟🌟🌟🌟 <span class='md-tag md-tag--success'>[DE FACTO STANDARD]</span> — Open-source repository compiling features and timelines across the GitHub product spectrum. Enables platform architects to plan internal upgrades matching upcoming core features.</li>
|
||||
</ul>
|
||||
<h2 id="developer-productivity-2">Developer Productivity (2)<a class="headerlink" href="#developer-productivity-2" title="Permanent link">¶</a></h2>
|
||||
<h3 id="cicd">CICD<a class="headerlink" href="#cicd" title="Permanent link">¶</a></h3>
|
||||
<h4 id="github-actions-3">GitHub Actions (3)<a class="headerlink" href="#github-actions-3" title="Permanent link">¶</a></h4>
|
||||
<ul>
|
||||
<li><strong>(2025)</strong> <a href="https://github.blog/enterprise-software/ci-cd/continuous-delivery-github-actions-best-practices"><mark>github.blog: Continuous Delivery with GitHub Actions</mark></a> 🌟🌟🌟🌟🌟 <span class='md-tag md-tag--success'>[DE FACTO STANDARD]</span> — Enterprise patterns and best practices for continuous delivery (CD) using GitHub Actions.
|
||||
Highlights secure credential management, least privilege, runner isolation, environment checks, and GITHUB_TOKEN configurations.</li>
|
||||
</ul>
|
||||
<h3 id="ides">IDEs<a class="headerlink" href="#ides" title="Permanent link">¶</a></h3>
|
||||
<h4 id="github-copilot">GitHub Copilot<a class="headerlink" href="#github-copilot" title="Permanent link">¶</a></h4>
|
||||
<ul>
|
||||
<li><strong>(2025)</strong> <a href="https://githubnext.com/projects/copilot-workspace"><mark>githubnext.com: GitHub Copilot Workspace</mark></a> 🌟🌟🌟🌟🌟 <span class='md-tag md-tag--success'>[DE FACTO STANDARD]</span> — An agentic development environment by GitHub Next designed to orchestrate software changes using autonomous developer agents.
|
||||
Assists developers from specification to implementation, verification, and code generation across complex repositories.</li>
|
||||
<li><strong>(2025)</strong> <a href="https://learn.microsoft.com/en-us/visualstudio/ide/copilot-agent-mode"><mark>learn.microsoft.com: Use Agent Mode in GitHub Copilot</mark></a> 🌟🌟🌟🌟🌟 <span class='md-tag md-tag--success'>[DE FACTO STANDARD]</span> — Official documentation for the Agent Mode inside GitHub Copilot.
|
||||
Guides developers on configuring autonomous multi-file refactoring, debugging, and advanced prompt engineering patterns.</li>
|
||||
</ul>
|
||||
<h2 id="engineering-education">Engineering Education<a class="headerlink" href="#engineering-education" title="Permanent link">¶</a></h2>
|
||||
<h3 id="developer-platform-1">Developer Platform (1)<a class="headerlink" href="#developer-platform-1" title="Permanent link">¶</a></h3>
|
||||
<h4 id="git-workflows-2">Git Workflows (2)<a class="headerlink" href="#git-workflows-2" title="Permanent link">¶</a></h4>
|
||||
@@ -7470,6 +7511,7 @@
|
||||
<li><a href="https://about.gitlab.com/gitlab-org/gitlab/-/issues/2785">Auto-merge between release branches</a> <span class='md-tag md-tag--info'>[COMMUNITY-TOOL]</span> — A curated technical resource and architectural guide covering about.gitlab.com in the Kubernetes Tools ecosystem.</li>
|
||||
<li><a href="https://about.gitlab.com/gitlab-org/gitlab/-/issues/14595">Provide merge bot functionality</a> <span class='md-tag md-tag--info'>[COMMUNITY-TOOL]</span> — A curated technical resource and architectural guide covering about.gitlab.com in the Kubernetes Tools ecosystem.</li>
|
||||
<li><a href="https://dzone.com/refcardz/getting-started-git">dzone.com: refcard - getting started with git</a> <span class='md-tag md-tag--info'>[COMMUNITY-TOOL]</span> — A curated technical resource and architectural guide covering dzone.com: refcard - getting started with git in the Kubernetes Tools ecosystem.</li>
|
||||
<li><a href="https://www.previous.cloudbees.com/press/cloudbees-releases-another-industry-first-feature-flagging-premise-use">CloudBees Releases Another Industry First: Feature Flagging for On-Premise' Use 🌟</a> <span class='md-tag md-tag--info'>[COMMUNITY-TOOL]</span> — A curated technical resource and architectural guide covering CloudBees Releases Another Industry First: Feature Flagging for On-Premise' Use 🌟 in the Kubernetes Tools ecosystem.</li>
|
||||
<li><a href="https://en.wikipedia.org/wiki/Git">Wikipedia: Git</a> <span class='md-tag md-tag--info'>[COMMUNITY-TOOL]</span> — A curated technical resource and architectural guide covering Wikipedia: Git in the Kubernetes Tools ecosystem.</li>
|
||||
<li><a href="https://dzone.com/articles/top-20-git-commands-with-examples">dzone.com: Top 20 git commands with examples 🌟</a> <span class='md-tag md-tag--info'>[COMMUNITY-TOOL]</span> — A curated technical resource and architectural guide covering dzone.com: Top 20 git commands with examples 🌟 in the Kubernetes Tools ecosystem.</li>
|
||||
<li><a href="https://medium.com/javarevisited/7-best-courses-to-master-git-and-github-for-programmers-d671859a68b2">medium: 7 Best Courses to Master Git and Github for Programmers</a> <span class='md-tag md-tag--info'>[COMMUNITY-TOOL]</span> — A curated technical resource and architectural guide covering medium: 7 Best Courses to Master Git and Github for Programmers in the Kubernetes Tools ecosystem.</li>
|
||||
@@ -7514,7 +7556,6 @@
|
||||
<li><a href="https://www.toptal.com/software/trunk-based-development-git-flow">toptal.com: Trunk-based Development vs. Git Flow</a> <span class='md-tag md-tag--info'>[COMMUNITY-TOOL]</span> — A curated technical resource and architectural guide covering toptal.com: Trunk-based Development vs. Git Flow in the Kubernetes Tools ecosystem.</li>
|
||||
<li><a href="https://medium.com/@vafrcor2009/gitflow-vs-trunk-based-development-3beff578030b">medium: GitFlow VS Trunk-Based-Development</a> <span class='md-tag md-tag--info'>[COMMUNITY-TOOL]</span> — A curated technical resource and architectural guide covering medium: GitFlow VS Trunk-Based-Development in the Kubernetes Tools ecosystem.</li>
|
||||
<li><a href="https://dzone.com/articles/why-i-prefer-trunk-based-development-over-feature">Dzone: Why I Prefer Trunk-Based Development Over Feature Branching and GitFlow' 🌟</a> <span class='md-tag md-tag--info'>[COMMUNITY-TOOL]</span> — A curated technical resource and architectural guide covering Dzone: Why I Prefer Trunk-Based Development Over Feature Branching and GitFlow' 🌟 in the Kubernetes Tools ecosystem.</li>
|
||||
<li><a href="https://www.previous.cloudbees.com/press/cloudbees-releases-another-industry-first-feature-flagging-premise-use">CloudBees Releases Another Industry First: Feature Flagging for On-Premise' Use 🌟</a> <span class='md-tag md-tag--info'>[COMMUNITY-TOOL]</span> — A curated technical resource and architectural guide covering CloudBees Releases Another Industry First: Feature Flagging for On-Premise' Use 🌟 in the Kubernetes Tools ecosystem.</li>
|
||||
<li><a href="https://cioperu.pe/articulo/30477/devops-5-formas-de-impulsar-la-utilizacion-de-feature-flags">cioperu.pe: 5 formas de impulsar la utilización de feature flags</a> <span class='md-tag md-tag--info'>[COMMUNITY-TOOL]</span> — A curated technical resource and architectural guide covering cioperu.pe: 5 formas de impulsar la utilización de feature flags in the Kubernetes Tools ecosystem.</li>
|
||||
<li><a href="https://dzone.com/articles/using-gitlab-rest-api-to-create-projects">Dzone: using gitlab API to create projects</a> <span class='md-tag md-tag--info'>[COMMUNITY-TOOL]</span> — A curated technical resource and architectural guide covering Dzone: using gitlab API to create projects in the Kubernetes Tools ecosystem.</li>
|
||||
<li><a href="https://levelup.gitconnected.com/automating-integration-and-deployment-to-remote-server-63a2b6576ebf">levelup.gitconnected.com: Automating Integration and Deployment to Remote' Server</a> <span class='md-tag md-tag--info'>[COMMUNITY-TOOL]</span> — A curated technical resource and architectural guide covering levelup.gitconnected.com: Automating Integration and Deployment to Remote' Server in the Kubernetes Tools ecosystem.</li>
|
||||
@@ -7597,7 +7638,7 @@
|
||||
<ul>
|
||||
<li><strong>(2023)</strong> <a href="https://github.com/copilot"><mark>GitHub Copilot 🌟</mark></a> <span class='md-tag md-tag--warning'>[TYPESCRIPT CONTENT]</span> <span class='md-tag md-tag--critical'>[ADVANCED LEVEL]</span> 🌟🌟🌟🌟🌟 <span class='md-tag md-tag--success'>[DE FACTO STANDARD]</span> — The main landing framework for GitHub Copilot's developer organization. As an AI-assisted development standard, it houses the core SDK components, extension configurations, and telemetry hooks driving modern contextual code synthesis inside major integrated development environments (IDEs).</li>
|
||||
</ul>
|
||||
<h4 id="developer-productivity-2">Developer Productivity (2)<a class="headerlink" href="#developer-productivity-2" title="Permanent link">¶</a></h4>
|
||||
<h4 id="developer-productivity-3">Developer Productivity (3)<a class="headerlink" href="#developer-productivity-3" title="Permanent link">¶</a></h4>
|
||||
<ul>
|
||||
<li><strong>(2023)</strong> <a href="https://github.blog/developer-skills/programming-languages-and-frameworks/10-unexpected-ways-to-use-github-copilot">github.blog/developer-skills: 10 unexpected ways to use GitHub Copilot</a> <span class='md-tag md-tag--critical'>[LEGACY]</span> — Highlights non-traditional applications of GitHub Copilot, including automated test orchestration, translating deprecated structural syntax, and simplifying complex regular expressions. Useful for engineers attempting to extract maximum value from active AI subscriptions.</li>
|
||||
</ul>
|
||||
@@ -7675,7 +7716,7 @@
|
||||
<ul>
|
||||
<li><strong>(2021)</strong> <a href="https://docs.gitlab.com/runner/install/openshift.html">docs.gitlab.com: Install GitLab Runner on Red Hat OpenShift</a> <span class='md-tag md-tag--warning'>[YAML CONTENT]</span> <span class='md-tag md-tag--critical'>[ADVANCED LEVEL]</span> <span class='md-tag md-tag--info'>[COMMUNITY-TOOL]</span> <span class='md-tag md-tag--secondary'>[GUIDE]</span> — The official guide for installing GitLab Runner on Red Hat OpenShift using the GitLab Runner Operator. Outlines configuration steps, security context constraints (SCC), and custom resource designs for managing secure, scalable pipeline workloads.</li>
|
||||
</ul>
|
||||
<h3 id="developer-productivity-3">Developer Productivity (3)<a class="headerlink" href="#developer-productivity-3" title="Permanent link">¶</a></h3>
|
||||
<h3 id="developer-productivity-4">Developer Productivity (4)<a class="headerlink" href="#developer-productivity-4" title="Permanent link">¶</a></h3>
|
||||
<h4 id="desktop-clients">Desktop Clients<a class="headerlink" href="#desktop-clients" title="Permanent link">¶</a></h4>
|
||||
<ul>
|
||||
<li><strong>(2021)</strong> <a href="https://about.gitlab.com/blog/gitpod-desktop-app-personal-activities">about.gitlab.com: Why we built GitDock, our desktop app to navigate your GitLab activities</a> <span class='md-tag md-tag--info'>[COMMUNITY-TOOL]</span> — Introduces GitDock, a desktop application designed to centralize GitLab tasks, merge requests, and build pipelines in a unified status panel.</li>
|
||||
|
||||
@@ -1546,6 +1546,23 @@
|
||||
</span>
|
||||
</a>
|
||||
|
||||
<nav class="md-nav" aria-label="AI Integration">
|
||||
<ul class="md-nav__list">
|
||||
|
||||
<li class="md-nav__item">
|
||||
<a href="#terraform" class="md-nav__link">
|
||||
<span class="md-ellipsis">
|
||||
|
||||
Terraform
|
||||
|
||||
</span>
|
||||
</a>
|
||||
|
||||
</li>
|
||||
|
||||
</ul>
|
||||
</nav>
|
||||
|
||||
</li>
|
||||
|
||||
<li class="md-nav__item">
|
||||
@@ -1692,15 +1709,15 @@
|
||||
</li>
|
||||
|
||||
<li class="md-nav__item">
|
||||
<a href="#terraform" class="md-nav__link">
|
||||
<a href="#terraform-1" class="md-nav__link">
|
||||
<span class="md-ellipsis">
|
||||
|
||||
Terraform
|
||||
Terraform (1)
|
||||
|
||||
</span>
|
||||
</a>
|
||||
|
||||
<nav class="md-nav" aria-label="Terraform">
|
||||
<nav class="md-nav" aria-label="Terraform (1)">
|
||||
<ul class="md-nav__list">
|
||||
|
||||
<li class="md-nav__item">
|
||||
@@ -2970,6 +2987,7 @@
|
||||
<li><a href="#infrastructure-as-code-1">Infrastructure as Code</a><ul>
|
||||
<li><a href="#ai-assisted">AI Assisted</a></li>
|
||||
<li><a href="#ai-integration">AI Integration</a></li>
|
||||
<li><a href="#terraform">Terraform</a></li>
|
||||
<li><a href="#architecture">Architecture</a></li>
|
||||
<li><a href="#best-practices">Best Practices</a></li>
|
||||
<li><a href="#cicd-platforms">CICD Platforms</a></li>
|
||||
@@ -2983,7 +3001,7 @@
|
||||
<li><a href="#security">Security</a></li>
|
||||
<li><a href="#strategy">Strategy</a></li>
|
||||
<li><a href="#terminology">Terminology</a></li>
|
||||
<li><a href="#terraform">Terraform</a></li>
|
||||
<li><a href="#terraform-1">Terraform</a></li>
|
||||
<li><a href="#secrets">Secrets</a></li>
|
||||
<li><a href="#tool-comparison">Tool Comparison</a></li>
|
||||
<li><a href="#tooling">Tooling</a></li>
|
||||
@@ -3034,7 +3052,6 @@
|
||||
<h4 id="general-reference">General Reference<a class="headerlink" href="#general-reference" title="Permanent link">¶</a></h4>
|
||||
<ul>
|
||||
<li><a href="https://www.hashicorp.com/en/blog/terraform-provider-for-google-cloud-7-0-is-now-ga">Terraform Provider for Google Cloud 7.0 is now GA</a> <span class='md-tag md-tag--info'>[COMMUNITY-TOOL]</span> — A curated technical resource and architectural guide covering Terraform Provider for Google Cloud 7.0 is now GA in the Kubernetes Tools ecosystem.</li>
|
||||
<li><a href="https://t.co/EKsVgKA4xn">IBM IAM for AI Agents</a> <span class='md-tag md-tag--info'>[COMMUNITY-TOOL]</span> — A curated technical resource and architectural guide covering IBM IAM for AI Agents in the Kubernetes Tools ecosystem.</li>
|
||||
<li><a href="https://t.co/5E4FLUyh98">Terraform for Standardizing AWS Deployments</a> <span class='md-tag md-tag--info'>[COMMUNITY-TOOL]</span> — A curated technical resource and architectural guide covering Terraform for Standardizing AWS Deployments in the Kubernetes Tools ecosystem.</li>
|
||||
<li><a href="https://azure.github.io/Azure-Landing-Zones/accelerator">Azure Landing Zone IaC Accelerator</a> <span class='md-tag md-tag--info'>[COMMUNITY-TOOL]</span> — A curated technical resource and architectural guide covering Azure Landing Zone IaC Accelerator in the Kubernetes Tools ecosystem.</li>
|
||||
<li><a href="https://t.co/UmacHpStqI">Terraform Enterprise 2.0</a> <span class='md-tag md-tag--info'>[COMMUNITY-TOOL]</span> — A curated technical resource and architectural guide covering Terraform Enterprise 2.0 in the Kubernetes Tools ecosystem.</li>
|
||||
@@ -3049,6 +3066,7 @@
|
||||
<li><a href="https://levelup.gitconnected.com/short-using-iac-over-clickops-229e919b5373">levelup.gitconnected.com: Short: Using IaC over Clickops</a> <span class='md-tag md-tag--info'>[COMMUNITY-TOOL]</span> — A curated technical resource and architectural guide covering levelup.gitconnected.com: Short: Using IaC over Clickops in the Kubernetes Tools ecosystem.</li>
|
||||
<li><a href="https://www.cncf.io/blog/2021/04/06/cloudformation-vs-terraform-which-is-better">cncf.io: Cloudformation vs. Terraform: Which is better?</a> <span class='md-tag md-tag--info'>[COMMUNITY-TOOL]</span> — A curated technical resource and architectural guide covering cncf.io: Cloudformation vs. Terraform: Which is better? in the Kubernetes Tools ecosystem.</li>
|
||||
<li><a href="https://t.co/C6uicr7ZPS">Terraform 1.15: Flexible Module Management, Deprecation Warnings, and Windows' ARM64 Support</a> <span class='md-tag md-tag--info'>[COMMUNITY-TOOL]</span> — A curated technical resource and architectural guide covering Terraform 1.15: Flexible Module Management, Deprecation Warnings, and Windows' ARM64 Support in the Kubernetes Tools ecosystem.</li>
|
||||
<li><a href="https://t.co/EKsVgKA4xn">IBM IAM for AI Agents</a> <span class='md-tag md-tag--info'>[COMMUNITY-TOOL]</span> — A curated technical resource and architectural guide covering IBM IAM for AI Agents in the Kubernetes Tools ecosystem.</li>
|
||||
<li><a href="https://cloudtips.nl/the-maester-terraform-module-8c68b2b68c51">The Maester - Terraform Module</a> <span class='md-tag md-tag--info'>[COMMUNITY-TOOL]</span> — A curated technical resource and architectural guide covering The Maester - Terraform Module in the Kubernetes Tools ecosystem.</li>
|
||||
<li><a href="https://medium.com/nerd-for-tech/kubernetes-declaratively-deploying-infrastructure-iac-789f14d999c6">medium.com/nerd-for-tech: Kubernetes: Declaratively Deploying Infrastructure' (IaC)</a> <span class='md-tag md-tag--info'>[COMMUNITY-TOOL]</span> — A curated technical resource and architectural guide covering medium.com/nerd-for-tech: Kubernetes: Declaratively Deploying Infrastructure' (IaC) in the Kubernetes Tools ecosystem.</li>
|
||||
<li><a href="https://medium.com/globant/infrastructure-as-code-using-kubernetes-d3d329446517">medium.com/globant: Infrastructure as Code using Kubernetes</a> <span class='md-tag md-tag--info'>[COMMUNITY-TOOL]</span> — A curated technical resource and architectural guide covering medium.com/globant: Infrastructure as Code using Kubernetes in the Kubernetes Tools ecosystem.</li>
|
||||
@@ -3099,7 +3117,9 @@
|
||||
<li><strong>(2023)</strong> <a href="https://mattrickard.com/infrastructure-as-code-will-be-written-by-ai">matt-rickard.com: Infrastructure as Code Will be Written by AI</a> <span class='md-tag md-tag--info'>[COMMUNITY-TOOL]</span> — Explores how generative AI can be used to compile declarative DSL configurations. Argues that structural files (such as Terraform or Pulumi definitions) are excellent translation targets for LLMs due to explicit syntax schemas.</li>
|
||||
</ul>
|
||||
<h4 id="ai-integration">AI Integration<a class="headerlink" href="#ai-integration" title="Permanent link">¶</a></h4>
|
||||
<h5 id="terraform">Terraform<a class="headerlink" href="#terraform" title="Permanent link">¶</a></h5>
|
||||
<ul>
|
||||
<li><strong>(2024)</strong> <a href="https://markaicode.com/terraform-ai-infrastructure-as-code">Terraform 2.0 in Practice: Using AI to Generate Infrastructure as Code</a> <span class='md-tag md-tag--info'>[COMMUNITY-TOOL]</span> — Examines workflow improvements, automated code validation, and prompt-to-infrastructure engineering using modern LLM integrations in Terraform development lifecycles.</li>
|
||||
<li><strong>(2026)</strong> <a href="https://github.com/antonbabenko/terraform-skill"><strong>Terraform & OpenTofu Skill for AI Agents</strong></a> <span class='md-tag md-tag--info'>⭐ 2012</span> <svg class="v2-sparkline" width="50" height="15" viewBox="0 0 50 15" style="vertical-align: middle; display: inline-block; margin-left: 6px;" title="Activity Trend"><defs><linearGradient id="spark-grad-581800ca" x1="0" y1="0" x2="1" y2="0"><stop offset="0%" stop-color="rgba(34, 211, 238, 0.2)" /><stop offset="100%" stop-color="var(--md-accent-fg-color)" /></linearGradient></defs><path class="v2-sparkline-path" d="M 0 4 L 10 12 L 20 4 L 30 7 L 40 11 L 50 5" fill="none" stroke="url(#spark-grad-581800ca)" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round" /><circle cx="50" cy="5" r="2" fill="var(--md-accent-fg-color)" /></svg> <span class='md-tag md-tag--warning'>[TYPESCRIPT CONTENT]</span> <span class='md-tag md-tag--critical'>[ADVANCED LEVEL]</span> 🌟🌟🌟🌟 <span class='md-tag md-tag--success'>[ENTERPRISE-STABLE]</span> — An open-source Model Context Protocol (MCP) skill set built for AI agents. Simplifies parsing, validating, and managing Terraform and OpenTofu infrastructure configurations through intelligent, context-aware LLM tool calls.</li>
|
||||
</ul>
|
||||
<h4 id="architecture">Architecture<a class="headerlink" href="#architecture" title="Permanent link">¶</a></h4>
|
||||
@@ -3156,7 +3176,7 @@
|
||||
<ul>
|
||||
<li><strong>(2022)</strong> <a href="https://thenewstack.io/guis-cli-apis-learn-basic-terms-of-infrastructure-as-code">thenewstack.io: GUIs, CLI, APIs: Learn Basic Terms of Infrastructure-as-Code</a> <span class='md-tag md-tag--info'>[COMMUNITY-TOOL]</span> — Clarifies foundational interfaces—GUIs, CLIs, and APIs—used in automated provisioning workflows. Details how modern declarative execution pipelines abstract these layers to guarantee predictable environment configurations.</li>
|
||||
</ul>
|
||||
<h4 id="terraform">Terraform<a class="headerlink" href="#terraform" title="Permanent link">¶</a></h4>
|
||||
<h4 id="terraform-1">Terraform (1)<a class="headerlink" href="#terraform-1" title="Permanent link">¶</a></h4>
|
||||
<h5 id="secrets">Secrets<a class="headerlink" href="#secrets" title="Permanent link">¶</a></h5>
|
||||
<ul>
|
||||
<li><strong>(2025)</strong> <a href="https://nedinthecloud.com/2025/07/01/ephemeral-values-in-terraform">Ephemeral Values in Terraform</a> <span class='md-tag md-tag--warning'>[HCL CONTENT]</span> <span class='md-tag md-tag--critical'>[ADVANCED LEVEL]</span> <span class='md-tag md-tag--info'>[COMMUNITY-TOOL]</span> — Explains the design and execution mechanics of Ephemeral Values introduced in modern Terraform releases. Discusses preventing credential leakages by keeping sensitive short-lived resources completely out of persistent state logs.</li>
|
||||
|
||||
@@ -1994,9 +1994,9 @@
|
||||
1. <strong>Elite Layer (AI-Enriched)</strong>: Resources individually analyzed by our Agentic AI with high-density summaries and hierarchical indexing.
|
||||
2. <strong>Standard Layer (Mapped)</strong>: Resources identified as candidates for Elite status but pending deep AI analysis.</p>
|
||||
<p><strong>Current Inventory Coverage:</strong>
|
||||
- <strong>V1 Base Inventory</strong>: 18641 total resources analyzed.
|
||||
- <strong>V2 Elite Selection</strong>: 14473 candidates identified (77.64% density ratio).
|
||||
- <strong>AI Enrichment Coverage</strong>: 14473 / 14473 (100.0%)
|
||||
- <strong>V1 Base Inventory</strong>: 18647 total resources analyzed.
|
||||
- <strong>V2 Elite Selection</strong>: 14479 candidates identified (77.65% density ratio).
|
||||
- <strong>AI Enrichment Coverage</strong>: 14479 / 14479 (100.0%)
|
||||
- <strong>GitHub Metadata Coverage</strong>: 1764 / 1764 (100.0%) - <em>Critical for Maturity Tagging</em>
|
||||
- <strong>Status</strong>: The system is incrementally processing pending resources to complete the knowledge graph.</p>
|
||||
</details>
|
||||
|
||||
@@ -6993,7 +6993,6 @@
|
||||
<li><a href="https://www.reddit.com/r/jenkinsci">reddit.com/r/jenkinsci</a> <span class='md-tag md-tag--info'>[COMMUNITY-TOOL]</span> — A curated technical resource and architectural guide covering reddit.com/r/jenkinsci in the Kubernetes Tools ecosystem.</li>
|
||||
<li><a href="https://dzone.com/articles/running-ansible-playbooks-from-jenkins">Dzone: Running Ansible Playbooks From Jenkins</a> <span class='md-tag md-tag--info'>[COMMUNITY-TOOL]</span> — A curated technical resource and architectural guide covering Dzone: Running Ansible Playbooks From Jenkins in the Kubernetes Tools ecosystem.</li>
|
||||
<li><a href="https://hostadvice.com/blog/devops-toolbox-jenkins-ansible-chef-puppet-vagrant-saltstack">DevOps Toolbox: Jenkins, Ansible, Chef, Puppet, Vagrant, & SaltStack</a> <span class='md-tag md-tag--info'>[COMMUNITY-TOOL]</span> — A curated technical resource and architectural guide covering DevOps Toolbox: Jenkins, Ansible, Chef, Puppet, Vagrant, & SaltStack in the Kubernetes Tools ecosystem.</li>
|
||||
<li><a href="https://www.previous.cloudbees.com/press/cloudbees-releases-another-industry-first-feature-flagging-premise-use">CloudBees Releases Another Industry First: Feature Flagging for On-Premise' Use 🌟</a> <span class='md-tag md-tag--info'>[COMMUNITY-TOOL]</span> — A curated technical resource and architectural guide covering CloudBees Releases Another Industry First: Feature Flagging for On-Premise' Use 🌟 in the Kubernetes Tools ecosystem.</li>
|
||||
<li><a href="https://medium.com/criciumadev/its-time-migrating-to-java-11-5eb3868354f9">It’s time! Migrating to Java 11 🌟</a> <span class='md-tag md-tag--info'>[COMMUNITY-TOOL]</span> — A curated technical resource and architectural guide covering It’s time! Migrating to Java 11 🌟 in the Kubernetes Tools ecosystem.</li>
|
||||
<li><a href="https://dzone.com/articles/getting-started-with-jenkins-the-ultimate-guide">dzone: getting started with jenkins the ultimate guide</a> <span class='md-tag md-tag--info'>[COMMUNITY-TOOL]</span> — A curated technical resource and architectural guide covering dzone: getting started with jenkins the ultimate guide in the Kubernetes Tools ecosystem.</li>
|
||||
<li><a href="https://dzone.com/articles/jenkins-in-a-nutshell">dzone: jenkins in a nutshell</a> <span class='md-tag md-tag--info'>[COMMUNITY-TOOL]</span> — A curated technical resource and architectural guide covering dzone: jenkins in a nutshell in the Kubernetes Tools ecosystem.</li>
|
||||
@@ -7058,6 +7057,7 @@
|
||||
<li><a href="https://medium.com/@gangsta_black/grafana-cool-dashboard-for-monitoring-jenkins-with-prometheus-c7ba4f1c6297">medium: prometheus and grafana dashboard</a> <span class='md-tag md-tag--info'>[COMMUNITY-TOOL]</span> — A curated technical resource and architectural guide covering medium: prometheus and grafana dashboard in the Kubernetes Tools ecosystem.</li>
|
||||
<li><a href="https://www.reddit.com/r/jenkinsci/comments/ctirsc/building_docker_images_when_running_jenkins_in">Building Docker images when running Jenkins in Kubernetes</a> <span class='md-tag md-tag--info'>[COMMUNITY-TOOL]</span> — A curated technical resource and architectural guide covering Building Docker images when running Jenkins in Kubernetes in the Kubernetes Tools ecosystem.</li>
|
||||
<li><a href="https://medium.com/swlh/quickstart-ci-with-jenkins-and-docker-in-docker-c3f7174ee9ff">medium: quickstart ci with jenkins and docker in docker</a> <span class='md-tag md-tag--info'>[COMMUNITY-TOOL]</span> — A curated technical resource and architectural guide covering medium: quickstart ci with jenkins and docker in docker in the Kubernetes Tools ecosystem.</li>
|
||||
<li><a href="https://www.previous.cloudbees.com/press/cloudbees-releases-another-industry-first-feature-flagging-premise-use">CloudBees Releases Another Industry First: Feature Flagging for On-Premise' Use 🌟</a> <span class='md-tag md-tag--info'>[COMMUNITY-TOOL]</span> — A curated technical resource and architectural guide covering CloudBees Releases Another Industry First: Feature Flagging for On-Premise' Use 🌟 in the Kubernetes Tools ecosystem.</li>
|
||||
</ul>
|
||||
<h2 id="ci-cd">CI-CD<a class="headerlink" href="#ci-cd" title="Permanent link">¶</a></h2>
|
||||
<h3 id="build-acceleration">Build Acceleration<a class="headerlink" href="#build-acceleration" title="Permanent link">¶</a></h3>
|
||||
|
||||
@@ -3127,6 +3127,51 @@
|
||||
</ul>
|
||||
</nav>
|
||||
|
||||
</li>
|
||||
|
||||
<li class="md-nav__item">
|
||||
<a href="#infrastructure-as-code_1" class="md-nav__link">
|
||||
<span class="md-ellipsis">
|
||||
|
||||
Infrastructure as Code
|
||||
|
||||
</span>
|
||||
</a>
|
||||
|
||||
<nav class="md-nav" aria-label="Infrastructure as Code">
|
||||
<ul class="md-nav__list">
|
||||
|
||||
<li class="md-nav__item">
|
||||
<a href="#ai-integrations" class="md-nav__link">
|
||||
<span class="md-ellipsis">
|
||||
|
||||
AI Integrations
|
||||
|
||||
</span>
|
||||
</a>
|
||||
|
||||
<nav class="md-nav" aria-label="AI Integrations">
|
||||
<ul class="md-nav__list">
|
||||
|
||||
<li class="md-nav__item">
|
||||
<a href="#validation-and-testing" class="md-nav__link">
|
||||
<span class="md-ellipsis">
|
||||
|
||||
Validation and Testing
|
||||
|
||||
</span>
|
||||
</a>
|
||||
|
||||
</li>
|
||||
|
||||
</ul>
|
||||
</nav>
|
||||
|
||||
</li>
|
||||
|
||||
</ul>
|
||||
</nav>
|
||||
|
||||
</li>
|
||||
|
||||
<li class="md-nav__item">
|
||||
@@ -5951,6 +5996,11 @@
|
||||
<li><a href="#hardware-integration">Hardware Integration</a></li>
|
||||
</ul>
|
||||
</li>
|
||||
<li><a href="#infrastructure-as-code">Infrastructure as Code</a></li>
|
||||
<li><a href="#ai-integrations">AI Integrations</a><ul>
|
||||
<li><a href="#validation-and-testing">Validation and Testing</a></li>
|
||||
</ul>
|
||||
</li>
|
||||
<li><a href="#kubernetes-gitops-and-packaging">Kubernetes GitOps and Packaging</a></li>
|
||||
<li><a href="#argo-project-ecosystem">Argo Project Ecosystem</a><ul>
|
||||
<li><a href="#ui-visualization">UI Visualization</a></li>
|
||||
@@ -6430,6 +6480,12 @@
|
||||
<ul>
|
||||
<li><strong>(2026)</strong> <a href="https://github.com/NVIDIA/k8s-device-plugin"><mark>NVIDIA/k8s-device-plugin: NVIDIA device plugin for Kubernetes</mark></a> <span class='md-tag md-tag--info'>⭐ 3788</span> <svg class="v2-sparkline" width="50" height="15" viewBox="0 0 50 15" style="vertical-align: middle; display: inline-block; margin-left: 6px;" title="Activity Trend"><defs><linearGradient id="spark-grad-8308a262" x1="0" y1="0" x2="1" y2="0"><stop offset="0%" stop-color="rgba(34, 211, 238, 0.2)" /><stop offset="100%" stop-color="var(--md-accent-fg-color)" /></linearGradient></defs><path class="v2-sparkline-path" d="M 0 10 L 10 9 L 20 7 L 30 8 L 40 9 L 50 5" fill="none" stroke="url(#spark-grad-8308a262)" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round" /><circle cx="50" cy="5" r="2" fill="var(--md-accent-fg-color)" /></svg> <span class='md-tag md-tag--warning'>[GO CONTENT]</span> 🌟🌟🌟🌟🌟 <span class='md-tag md-tag--success'>[DE FACTO STANDARD]</span> — This specialized DaemonSet exposes physical GPU properties to the local kubelet node manager. Operating as the essential link for hardware-accelerated workloads, it handles task-scheduling configurations and sets device-isolation runtimes so container systems can safely slice and access host GPU hardware.</li>
|
||||
</ul>
|
||||
<h2 id="infrastructure-as-code_1">Infrastructure as Code<a class="headerlink" href="#infrastructure-as-code_1" title="Permanent link">¶</a></h2>
|
||||
<h3 id="ai-integrations">AI Integrations<a class="headerlink" href="#ai-integrations" title="Permanent link">¶</a></h3>
|
||||
<h4 id="validation-and-testing">Validation and Testing<a class="headerlink" href="#validation-and-testing" title="Permanent link">¶</a></h4>
|
||||
<ul>
|
||||
<li><strong>(2024)</strong> <a href="https://masterpoint.io/blog/ai-meets-tf-prompt-strategies-for-test-generation">AI Meets Terraform: Prompt Strategies for Test Generation</a> <span class='md-tag md-tag--warning'>[NONE CONTENT]</span> <span class='md-tag md-tag--critical'>[ADVANCED LEVEL]</span> <span class='md-tag md-tag--info'>[COMMUNITY-TOOL]</span> — Explores LLM prompting strategies designed to automatically generate high-quality integration testing assertions for Terraform infrastructure codebases. Outlines systematic framework specifications to minimize manual testing overhead.</li>
|
||||
</ul>
|
||||
<h2 id="kubernetes-gitops-and-packaging">Kubernetes GitOps and Packaging<a class="headerlink" href="#kubernetes-gitops-and-packaging" title="Permanent link">¶</a></h2>
|
||||
<h3 id="argo-project-ecosystem">Argo Project Ecosystem<a class="headerlink" href="#argo-project-ecosystem" title="Permanent link">¶</a></h3>
|
||||
<h4 id="ui-visualization">UI Visualization<a class="headerlink" href="#ui-visualization" title="Permanent link">¶</a></h4>
|
||||
|
||||
@@ -18176,6 +18176,7 @@
|
||||
</ul>
|
||||
<h4 id="policy-enforcement">Policy Enforcement<a class="headerlink" href="#policy-enforcement" title="Permanent link">¶</a></h4>
|
||||
<ul>
|
||||
<li><strong>(2022)</strong> <a href="https://www.datree.io"><mark>datree.io</mark></a> <span class='md-tag md-tag--warning'>[GO CONTENT]</span> 🌟🌟🌟🌟🌟 <span class='md-tag md-tag--success'>[DE FACTO STANDARD]</span> — An enterprise-grade CLI validation engine built to run policy and configuration checks on Kubernetes manifests. Datree evaluates configurations against schema rules and security standards before they reach clusters. This is a critical validation step for CI/CD GitOps pipelines.</li>
|
||||
<li><strong>(2021)</strong> <a href="https://dev.to/wkrzywiec/automating-quality-checks-for-kubernetes-yamls-398"><strong>dev.to: Automating quality checks for Kubernetes YAMLs</strong></a> <span class='md-tag md-tag--warning'>[N/A CONTENT]</span> 🌟🌟🌟🌟 <span class='md-tag md-tag--success'>[ENTERPRISE-STABLE]</span> — A detailed technical guide demonstrating how to integrate automated quality controls for Kubernetes manifests within build pipelines. It explains how to combine linters and security checks to validate configurations before they are deployed.</li>
|
||||
</ul>
|
||||
<h2 id="cloud-native-platforms">Cloud Native Platforms<a class="headerlink" href="#cloud-native-platforms" title="Permanent link">¶</a></h2>
|
||||
|
||||
@@ -2076,7 +2076,7 @@
|
||||
<li><a href="https://muratbuffalo.blogspot.com/2021/11/whats-really-new-with-newsql.html">muratbuffalo.blogspot.com: What’s Really New with NewSQL?</a> <span class='md-tag md-tag--critical'>[ADVANCED LEVEL]</span> <span class='md-tag md-tag--info'>[COMMUNITY-TOOL]</span> — A comprehensive conceptual deep-dive comparing NewSQL architectures with traditional relational and NoSQL engines. Explores transactional guarantees, distributed consensus (Raft/Paxos), and cloud-native database scaling.</li>
|
||||
</ul>
|
||||
<hr />
|
||||
<p>💡 <strong>Explore Related:</strong> <a href="../yaml/">Yaml</a> | <a href="../nosql/">NoSQL</a> | <a href="../databases/">Databases</a></p>
|
||||
<p>💡 <strong>Explore Related:</strong> <a href="../yaml/">Yaml</a> | <a href="../nosql/">NoSQL</a> | <a href="../crunchydata/">Crunchydata</a></p>
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -2661,7 +2661,7 @@
|
||||
<li><strong>(2021)</strong> <a href="https://github.com/oslabs-beta/OdinsEye">github.com/oslabs-beta: Odin's Eye</a> <span class='md-tag md-tag--warning'>[JAVASCRIPT CONTENT]</span> 🌟 <span class='md-tag md-tag--info'>[COMMUNITY-TOOL]</span> — Open-source developer utility designed to monitor distributed microservices architecture patterns, tracking internal query metrics and communication flows. Primarily active within the community sandbox.</li>
|
||||
</ul>
|
||||
<hr />
|
||||
<p>💡 <strong>Explore Related:</strong> <a href="../yaml/">Yaml</a> | <a href="../newsql/">Newsql</a> | <a href="../databases/">Databases</a></p>
|
||||
<p>💡 <strong>Explore Related:</strong> <a href="../yaml/">Yaml</a> | <a href="../newsql/">Newsql</a> | <a href="../crunchydata/">Crunchydata</a></p>
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -2925,10 +2925,10 @@
|
||||
<h3 id="kubernetes-tools">Kubernetes Tools<a class="headerlink" href="#kubernetes-tools" title="Permanent link">¶</a></h3>
|
||||
<h4 id="general-reference">General Reference<a class="headerlink" href="#general-reference" title="Permanent link">¶</a></h4>
|
||||
<ul>
|
||||
<li><a href="https://t.co/EKsVgKA4xn">IBM IAM for AI Agents</a> <span class='md-tag md-tag--info'>[COMMUNITY-TOOL]</span> — A curated technical resource and architectural guide covering IBM IAM for AI Agents in the Kubernetes Tools ecosystem.</li>
|
||||
<li><a href="https://t.co/cvOceuueCF">IBM Vault 2.0 UI Enhancements and Reporting Improvements</a> <span class='md-tag md-tag--info'>[COMMUNITY-TOOL]</span> — A curated technical resource and architectural guide covering IBM Vault 2.0 UI Enhancements and Reporting Improvements in the Kubernetes Tools ecosystem.</li>
|
||||
<li><a href="https://web-check.xyz">Web-Check</a> <span class='md-tag md-tag--info'>[COMMUNITY-TOOL]</span> — A curated technical resource and architectural guide covering Web-Check in the Kubernetes Tools ecosystem.</li>
|
||||
<li><a href="https://www.docker.com/blog/docker-hardened-images-for-every-developer">Docker Hardened Images for Every Developer</a> <span class='md-tag md-tag--info'>[COMMUNITY-TOOL]</span> — A curated technical resource and architectural guide covering Docker Hardened Images for Every Developer in the Kubernetes Tools ecosystem.</li>
|
||||
<li><a href="https://t.co/EKsVgKA4xn">IBM IAM for AI Agents</a> <span class='md-tag md-tag--info'>[COMMUNITY-TOOL]</span> — A curated technical resource and architectural guide covering IBM IAM for AI Agents in the Kubernetes Tools ecosystem.</li>
|
||||
<li><a href="https://medium.com/airwalk/automate-policies-enforcement-with-policy-as-code-2f20aac9e2b0">medium: Automate policies enforcement with Policy-as-Code 🌟</a> <span class='md-tag md-tag--info'>[COMMUNITY-TOOL]</span> — A curated technical resource and architectural guide covering medium: Automate policies enforcement with Policy-as-Code 🌟 in the Kubernetes Tools ecosystem.</li>
|
||||
<li><a href="https://www.magalix.com/blog/integrating-open-policy-agent-opa-with-kubernetes-a-deep-dive-tutorial">magalix.com: Integrating Open Policy Agent (OPA) With Kubernetes 🌟</a> <span class='md-tag md-tag--info'>[COMMUNITY-TOOL]</span> — A curated technical resource and architectural guide covering magalix.com: Integrating Open Policy Agent (OPA) With Kubernetes 🌟 in the Kubernetes Tools ecosystem.</li>
|
||||
<li><a href="https://blog.styra.com/blog/integrating-identity-oauth2-and-openid-connect-in-open-policy-agent">blog.styra.com: Integrating Identity: OAUTH2 and OPENID CONNECT in Open' Policy Agent</a> <span class='md-tag md-tag--info'>[COMMUNITY-TOOL]</span> — A curated technical resource and architectural guide covering blog.styra.com: Integrating Identity: OAUTH2 and OPENID CONNECT in Open' Policy Agent in the Kubernetes Tools ecosystem.</li>
|
||||
|
||||
@@ -876,6 +876,46 @@ a {
|
||||
border-top-color: rgba(255, 255, 255, 0.06);
|
||||
}
|
||||
|
||||
/* ---------------------------------------------------- */
|
||||
/* MODERN BROWSER-NATIVE CSS FEATURES */
|
||||
/* ---------------------------------------------------- */
|
||||
|
||||
/* Typography Enhancements: Balanced headings & orphan prevention */
|
||||
.md-typeset h1,
|
||||
.md-typeset h2,
|
||||
.md-typeset h3 {
|
||||
text-wrap: balance;
|
||||
}
|
||||
|
||||
.md-typeset p,
|
||||
.md-typeset li {
|
||||
text-wrap: pretty;
|
||||
}
|
||||
|
||||
/* Textarea and input field auto-sizing */
|
||||
textarea,
|
||||
input[type="text"] {
|
||||
field-sizing: content;
|
||||
}
|
||||
|
||||
/* Keyboard focus accessibility indicators */
|
||||
.md-typeset a:focus-visible,
|
||||
.md-button:focus-visible,
|
||||
.v2-tag-section summary:focus-visible {
|
||||
outline: 2px solid var(--md-accent-fg-color);
|
||||
outline-offset: 4px;
|
||||
}
|
||||
|
||||
/* Coarse touch pointer optimizations (Mobile AA targets) */
|
||||
@media (pointer: coarse) {
|
||||
.md-tag,
|
||||
.md-button,
|
||||
.v2-tag-section summary {
|
||||
min-block-size: 44px;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -2103,6 +2103,10 @@
|
||||
|
||||
|
||||
<h1 id="ai-agents-and-mcp">🎥 AI Agents and MCP<a class="headerlink" href="#ai-agents-and-mcp" title="Permanent link">¶</a></h1>
|
||||
<div class="admonition tip">
|
||||
<p class="admonition-title">Nubenetes V2 Elite Portal</p>
|
||||
<p>You are browsing the AI-Curated V2 Elite Edition. Looking for the exhaustive list of references? Check out the <a href="/v1/"><strong>V1 Historical Archive</strong></a>.</p>
|
||||
</div>
|
||||
<p>Welcome to the <strong>AI Agents and MCP</strong> section of the V2 Video Hub. Explore curated high-density videos with architectural summaries.</p>
|
||||
<h2 id="table-of-contents">Table of Contents<a class="headerlink" href="#table-of-contents" title="Permanent link">¶</a></h2>
|
||||
<ol>
|
||||
|
||||
@@ -2081,6 +2081,10 @@
|
||||
|
||||
|
||||
<h1 id="cloud-native-core">🎥 Cloud Native Core<a class="headerlink" href="#cloud-native-core" title="Permanent link">¶</a></h1>
|
||||
<div class="admonition tip">
|
||||
<p class="admonition-title">Nubenetes V2 Elite Portal</p>
|
||||
<p>You are browsing the AI-Curated V2 Elite Edition. Looking for the exhaustive list of references? Check out the <a href="/v1/"><strong>V1 Historical Archive</strong></a>.</p>
|
||||
</div>
|
||||
<p>Welcome to the <strong>Cloud Native Core</strong> section of the V2 Video Hub. Explore curated high-density videos with architectural summaries.</p>
|
||||
<h2 id="table-of-contents">Table of Contents<a class="headerlink" href="#table-of-contents" title="Permanent link">¶</a></h2>
|
||||
<ol>
|
||||
|
||||
@@ -1960,6 +1960,10 @@
|
||||
|
||||
|
||||
<h1 id="devops-iac-and-sre">🎥 DevOps, IaC, and SRE<a class="headerlink" href="#devops-iac-and-sre" title="Permanent link">¶</a></h1>
|
||||
<div class="admonition tip">
|
||||
<p class="admonition-title">Nubenetes V2 Elite Portal</p>
|
||||
<p>You are browsing the AI-Curated V2 Elite Edition. Looking for the exhaustive list of references? Check out the <a href="/v1/"><strong>V1 Historical Archive</strong></a>.</p>
|
||||
</div>
|
||||
<p>Welcome to the <strong>DevOps, IaC, and SRE</strong> section of the V2 Video Hub. Explore curated high-density videos with architectural summaries.</p>
|
||||
<h2 id="table-of-contents">Table of Contents<a class="headerlink" href="#table-of-contents" title="Permanent link">¶</a></h2>
|
||||
<ol>
|
||||
|
||||
@@ -1938,6 +1938,10 @@
|
||||
|
||||
|
||||
<h1 id="fundamentals">🎥 Fundamentals<a class="headerlink" href="#fundamentals" title="Permanent link">¶</a></h1>
|
||||
<div class="admonition tip">
|
||||
<p class="admonition-title">Nubenetes V2 Elite Portal</p>
|
||||
<p>You are browsing the AI-Curated V2 Elite Edition. Looking for the exhaustive list of references? Check out the <a href="/v1/"><strong>V1 Historical Archive</strong></a>.</p>
|
||||
</div>
|
||||
<p>Welcome to the <strong>Fundamentals</strong> section of the V2 Video Hub. Explore curated high-density videos with architectural summaries.</p>
|
||||
<h2 id="table-of-contents">Table of Contents<a class="headerlink" href="#table-of-contents" title="Permanent link">¶</a></h2>
|
||||
<ol>
|
||||
|
||||
@@ -1847,6 +1847,10 @@
|
||||
|
||||
|
||||
<h1 id="agentic-video-hub">Agentic Video Hub<a class="headerlink" href="#agentic-video-hub" title="Permanent link">¶</a></h1>
|
||||
<div class="admonition tip">
|
||||
<p class="admonition-title">Nubenetes V2 Elite Portal</p>
|
||||
<p>You are browsing the AI-Curated V2 Elite Edition. Looking for the exhaustive list of references? Check out the <a href="/v1/"><strong>V1 Historical Archive</strong></a>.</p>
|
||||
</div>
|
||||
<p>Welcome to the <strong>Nubenetes Elite Video Hub</strong>. Discover highly-curated architectural video resources organized into logical learning paths:</p>
|
||||
<h2 id="learning-dimensions">Learning Dimensions<a class="headerlink" href="#learning-dimensions" title="Permanent link">¶</a></h2>
|
||||
<div style="display: flex; justify-content: center; gap: 24px; margin: 24px 0; flex-wrap: wrap;">
|
||||
|
||||
@@ -3195,7 +3195,7 @@
|
||||
<li><strong>(2023)</strong> <a href="https://kubevious.io/blog/post/top-kubernetes-yaml-validation-tools">kubevious.io: Top Kubernetes YAML Validation Tools</a> <span class='md-tag md-tag--warning'>[NONE CONTENT]</span> <span class='md-tag md-tag--info'>[COMMUNITY-TOOL]</span> — A market breakdown contrasting modern validation utilities for Kubernetes platforms. Reviews differences between structural validators, OPA-based policy enforcement engines, and semantic layout detectors.</li>
|
||||
</ul>
|
||||
<hr />
|
||||
<p>💡 <strong>Explore Related:</strong> <a href="../newsql/">Newsql</a> | <a href="../nosql/">NoSQL</a> | <a href="../databases/">Databases</a></p>
|
||||
<p>💡 <strong>Explore Related:</strong> <a href="../newsql/">Newsql</a> | <a href="../nosql/">NoSQL</a> | <a href="../crunchydata/">Crunchydata</a></p>
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -38,7 +38,8 @@ async def _get_github_activity(url: str) -> Dict:
|
||||
"gh_pushed": data.get("pushed_at"),
|
||||
"gh_license": data.get("license", {}).get("spdx_id", "N/A")
|
||||
}
|
||||
except: pass
|
||||
except Exception as e:
|
||||
log_event(f"[WARN] fetch GitHub activity for {url}: {str(e)[:100]}")
|
||||
return {}
|
||||
|
||||
async def _deep_fetch_content(url: str) -> Tuple[str, Dict]:
|
||||
@@ -61,7 +62,8 @@ async def _deep_fetch_content(url: str) -> Tuple[str, Dict]:
|
||||
img_match = re.search(r'meta property="og:image" content="(.*?)"', resp.text)
|
||||
if img_match: og_image = img_match.group(1)
|
||||
return resp.text, {"og_image": og_image}
|
||||
except: pass
|
||||
except Exception as e:
|
||||
log_event(f"[WARN] deep fetch content for {url}: {str(e)[:100]}")
|
||||
return "", {}
|
||||
|
||||
async def evaluate_extracted_assets(raw_assets: List[Dict]) -> Dict[str, Dict]:
|
||||
@@ -76,7 +78,8 @@ async def evaluate_extracted_assets(raw_assets: List[Dict]) -> Dict[str, Dict]:
|
||||
try:
|
||||
memory_data = json.load(open(memory_file, "r"))
|
||||
domain_blacklist = set(memory_data.get("blacklisted_domains", []))
|
||||
except: pass
|
||||
except Exception as e:
|
||||
log_event(f"[WARN] load blacklist from health_learning.json: {str(e)[:100]}")
|
||||
|
||||
# 1. Pre-filter
|
||||
for asset in raw_assets:
|
||||
@@ -112,9 +115,13 @@ async def evaluate_extracted_assets(raw_assets: List[Dict]) -> Dict[str, Dict]:
|
||||
gh_meta = await _get_github_activity(asset["url"]) if "github.com" in asset["url"] else {}
|
||||
|
||||
mvq_penalty = False
|
||||
if gh_meta.get("gh_pushed"):
|
||||
ld = datetime.fromisoformat(gh_meta["gh_pushed"].replace("Z", "+00:00"))
|
||||
if (datetime.now(ld.tzinfo) - ld).days > (365 * 4): mvq_penalty = True
|
||||
pushed = gh_meta.get("gh_pushed")
|
||||
if pushed and str(pushed).strip().upper() not in ("N/A", "NONE"):
|
||||
try:
|
||||
ld = datetime.fromisoformat(str(pushed).replace("Z", "+00:00"))
|
||||
if (datetime.now(ld.tzinfo) - ld).days > (365 * 4): mvq_penalty = True
|
||||
except Exception as e:
|
||||
log_event(f"[WARN] MVQ penalty date parse for {asset['url']}: {str(e)[:100]}")
|
||||
|
||||
batch_data.append({
|
||||
"asset": asset, "content": web_content[:1500], "hash": c_hash,
|
||||
@@ -140,7 +147,10 @@ async def evaluate_extracted_assets(raw_assets: List[Dict]) -> Dict[str, Dict]:
|
||||
"- Assign tags. You MUST include:\n"
|
||||
" 1. 1 to 2 maturity tags from: [DE FACTO STANDARD], [ENTERPRISE-STABLE], [EMERGING], [GUIDE], [CASE STUDY], [COMMUNITY-TOOL], [LEGACY].\n"
|
||||
" 2. Fine-grained technical/architectural tags from the content (e.g., [EBPF], [WASM], [GITOPS], [IAC], [SERVICE-MESH], [SERVERLESS], [MLOPS], [DB]). Keep them uppercase and wrapped in brackets.\n"
|
||||
"Respond ONLY JSON list: [{\"url\": \"...\", \"impact_score\": int, \"reputation_penalty\": bool, \"reputation_summary\": \"...\", \"pub_date\": \"YYYY-MM-DD\", \"primary_category\": \"...\", \"suggested_new_category\": \"...\", \"title\": \"...\", \"desc\": \"...\", \"en_summary\": \"High-density summary...\", \"language\": \"...\", \"type\": \"...\", \"level\": \"...\", \"technical_hierarchy\": [...], \"tags\": [...], \"is_microservice\": bool}, ...]\n\n"
|
||||
"PHASE 5: COMPANY & GEO CLASSIFICATION\n"
|
||||
"- Identify 'company': The company/organization that authored or is the primary subject (e.g., 'Google', 'Netflix', 'CNCF', 'Independent').\n"
|
||||
"- Identify 'geo_region': The HQ region of that company. Use one of: 'americas', 'europe', 'spain', 'asia_pacific', 'global'.\n"
|
||||
"Respond ONLY JSON list: [{\"url\": \"...\", \"impact_score\": int, \"reputation_penalty\": bool, \"reputation_summary\": \"...\", \"pub_date\": \"YYYY-MM-DD\", \"primary_category\": \"...\", \"suggested_new_category\": \"...\", \"title\": \"...\", \"desc\": \"...\", \"en_summary\": \"High-density summary...\", \"language\": \"...\", \"type\": \"...\", \"level\": \"...\", \"technical_hierarchy\": [...], \"tags\": [...], \"is_microservice\": bool, \"company\": \"...\", \"geo_region\": \"...\"}, ...]\n\n"
|
||||
"RESOURCES:\n" + "\n".join([f"- {d['asset']['url']}: (MVQ Penalty: {d['mvq_penalty']}) {d['content']}" for d in batch_data])
|
||||
)
|
||||
|
||||
@@ -205,9 +215,16 @@ async def evaluate_extracted_assets(raw_assets: List[Dict]) -> Dict[str, Dict]:
|
||||
"reputation_status": "Vetted" if not data.get("reputation_penalty") else "Suspicious",
|
||||
"reputation_summary": data.get("reputation_summary", ""),
|
||||
"source_provenance": d["asset"].get("source_type", "Social"), "social_preview_url": d["rich_meta"].get("og_image", ""),
|
||||
"company": data.get("company", ""), "geo_region": data.get("geo_region", ""),
|
||||
"category": primary_cat, "status": "online", "last_checked": datetime.now().timestamp(),
|
||||
"discovered_at": datetime.now(MADRID_TZ).isoformat(),
|
||||
"last_ai_eval": datetime.now(MADRID_TZ).isoformat(),
|
||||
"suggested_new_category": data.get("suggested_new_category", ""),
|
||||
"addition_method": "automatic", **d["gh_meta"]
|
||||
"addition_method": {
|
||||
"rss": "rss_ingestion", "GitHub Trending": "github_trending",
|
||||
"Twitter": "twitter_ingestion", "nubenetes": "manual"
|
||||
}.get(d["asset"].get("source_type", ""), "automatic"),
|
||||
**d["gh_meta"]
|
||||
}
|
||||
if "youtube.com" in url or "youtu.be" in url:
|
||||
title_desc = f"{data['title']} {data['desc']}".lower()
|
||||
@@ -250,7 +267,9 @@ class AgenticCurator:
|
||||
prompt = "Identify 5 high-quality Cloud Native or K8s engineering blogs or 'Awesome' repos active in 2026. Return ONLY JSON list of URLs."
|
||||
try:
|
||||
return await call_gemini_with_retry(prompt, use_grounding=True)
|
||||
except: return []
|
||||
except Exception as e:
|
||||
log_event(f"[WARN] autonomous source discovery: {str(e)[:100]}")
|
||||
return []
|
||||
|
||||
async def decide_smart_injection(self, content: str, asset: Dict) -> str:
|
||||
# Extract headers from the markdown content
|
||||
|
||||
@@ -2,20 +2,31 @@ import aiohttp
|
||||
import json
|
||||
import httpx
|
||||
import re
|
||||
from src.config import GEMINI_API_KEY, NUBENETES_CATEGORIES
|
||||
from src.config import GEMINI_API_KEY, NUBENETES_CATEGORIES, GH_TOKEN
|
||||
from src.gemini_utils import call_gemini_with_retry
|
||||
from src.logger import log_event
|
||||
|
||||
async def fetch_github_trending_cloud_native() -> list[dict]:
|
||||
queries = [
|
||||
"topic:kubernetes+stars:>1000",
|
||||
"topic:mcp-server+stars:>0",
|
||||
"topic:kubernetes+stars:>1000",
|
||||
"topic:mcp-server+stars:>0",
|
||||
"topic:model-context-protocol+stars:>0",
|
||||
"topic:ai-agents+stars:>50",
|
||||
"awesome+stars:>1000",
|
||||
"topic:generative-ai+stars:>500"
|
||||
"topic:generative-ai+stars:>500",
|
||||
"topic:devops+stars:>500",
|
||||
"topic:observability+stars:>200",
|
||||
"topic:cloud-security+stars:>200",
|
||||
"topic:terraform+stars:>500",
|
||||
"topic:database+stars:>500",
|
||||
"topic:cicd+stars:>200",
|
||||
"topic:service-mesh+stars:>100",
|
||||
"topic:platform-engineering+stars:>100",
|
||||
]
|
||||
all_repos = []
|
||||
headers = {'Accept': 'application/vnd.github.v3+json'}
|
||||
if GH_TOKEN:
|
||||
headers['Authorization'] = f'token {GH_TOKEN}'
|
||||
async with aiohttp.ClientSession(headers=headers) as session:
|
||||
for q in queries:
|
||||
url = f"https://api.github.com/search/repositories?q={q}&sort=updated&order=desc"
|
||||
@@ -29,7 +40,9 @@ async def fetch_github_trending_cloud_native() -> list[dict]:
|
||||
"url": repo['html_url'],
|
||||
"desc": repo['description'] or "No description provided."
|
||||
})
|
||||
except: continue
|
||||
except Exception as e:
|
||||
log_event(f"[WARN] GitHub search query '{q}': {str(e)[:100]}")
|
||||
continue
|
||||
return all_repos
|
||||
|
||||
async def discover_trending_assets() -> list[dict]:
|
||||
|
||||
@@ -0,0 +1,194 @@
|
||||
from __future__ import annotations
|
||||
|
||||
import re
|
||||
import asyncio
|
||||
from collections import defaultdict
|
||||
from difflib import SequenceMatcher
|
||||
from typing import Dict, List, Tuple
|
||||
from urllib.parse import urlparse, parse_qs, urlencode, urlunparse
|
||||
|
||||
from src.inventory_manager import load_inventory, save_inventory
|
||||
from src.logger import log_event
|
||||
|
||||
TRACKING_PARAMS = {"utm_source", "utm_medium", "utm_campaign", "utm_content", "utm_term",
|
||||
"ref", "source", "fbclid", "gclid", "mc_cid", "mc_eid", "s", "share"}
|
||||
|
||||
|
||||
def normalize_url_deep(url: str) -> str:
|
||||
parsed = urlparse(url.strip().lower())
|
||||
scheme = "https"
|
||||
netloc = parsed.netloc.removeprefix("www.")
|
||||
path = parsed.path.rstrip("/") or "/"
|
||||
params = parse_qs(parsed.query)
|
||||
clean_params = {k: v for k, v in params.items() if k not in TRACKING_PARAMS}
|
||||
query = urlencode(clean_params, doseq=True) if clean_params else ""
|
||||
return urlunparse((scheme, netloc, path, "", query, ""))
|
||||
|
||||
|
||||
def normalize_title(title: str) -> str:
|
||||
if not title:
|
||||
return ""
|
||||
t = title.lower().strip()
|
||||
t = re.sub(r'^[\w.-]+\.\w{2,}:\s*', '', t)
|
||||
t = re.sub(r'[^\w\s]', ' ', t)
|
||||
t = re.sub(r'\s+', ' ', t).strip()
|
||||
return t
|
||||
|
||||
|
||||
def find_url_duplicates(inventory: Dict) -> List[Tuple[str, str]]:
|
||||
norm_map = defaultdict(list)
|
||||
for url in inventory:
|
||||
if not isinstance(inventory[url], dict):
|
||||
continue
|
||||
deep = normalize_url_deep(url)
|
||||
norm_map[deep].append(url)
|
||||
|
||||
duplicates = []
|
||||
for norm, urls in norm_map.items():
|
||||
if len(urls) > 1:
|
||||
for i in range(1, len(urls)):
|
||||
duplicates.append((urls[0], urls[i]))
|
||||
return duplicates
|
||||
|
||||
|
||||
def find_hash_duplicates(inventory: Dict) -> List[List[str]]:
|
||||
hash_map = defaultdict(list)
|
||||
for url, entry in inventory.items():
|
||||
if not isinstance(entry, dict):
|
||||
continue
|
||||
ch = entry.get("content_hash")
|
||||
if ch and ch != "N/A":
|
||||
hash_map[ch].append(url)
|
||||
return [urls for urls in hash_map.values() if len(urls) > 1]
|
||||
|
||||
|
||||
def find_title_duplicates(inventory: Dict, threshold: float = 0.85) -> List[Tuple[str, str, float]]:
|
||||
entries = []
|
||||
for url, entry in inventory.items():
|
||||
if not isinstance(entry, dict):
|
||||
continue
|
||||
title = entry.get("title", "")
|
||||
norm = normalize_title(title)
|
||||
if len(norm) < 10:
|
||||
continue
|
||||
entries.append((url, norm, entry.get("stars") or 0))
|
||||
|
||||
log_event(f"[Dedup] Building title index for {len(entries)} entries...")
|
||||
|
||||
prefix_groups = defaultdict(list)
|
||||
for url, norm, stars in entries:
|
||||
words = norm.split()
|
||||
prefix = " ".join(words[:3]) if len(words) >= 3 else norm
|
||||
prefix_groups[prefix].append((url, norm, stars))
|
||||
|
||||
duplicates = []
|
||||
checked = 0
|
||||
for prefix, group in prefix_groups.items():
|
||||
if len(group) < 2:
|
||||
continue
|
||||
for i in range(len(group)):
|
||||
for j in range(i + 1, len(group)):
|
||||
url1, norm1, stars1 = group[i]
|
||||
url2, norm2, stars2 = group[j]
|
||||
if stars1 >= 4 and stars2 >= 4:
|
||||
continue
|
||||
ratio = SequenceMatcher(None, norm1, norm2).ratio()
|
||||
if ratio >= threshold:
|
||||
duplicates.append((url1, url2, ratio))
|
||||
checked += 1
|
||||
if checked % 500 == 0:
|
||||
log_event(f"[Dedup] Checked {checked}/{len(prefix_groups)} prefix groups...")
|
||||
|
||||
log_event(f"[Dedup] Title scan complete: {len(duplicates)} potential duplicates found")
|
||||
return duplicates
|
||||
|
||||
|
||||
def _entry_score(entry: Dict) -> Tuple:
|
||||
return (
|
||||
entry.get("stars") or 0,
|
||||
1 if entry.get("ai_summary") else 0,
|
||||
1 if entry.get("hierarchy") else 0,
|
||||
len(entry.get("tags", [])),
|
||||
-len(str(entry.get("url", "")))
|
||||
)
|
||||
|
||||
|
||||
def resolve_duplicates(inventory: Dict, duplicate_pairs: List[Tuple[str, str, float]]) -> int:
|
||||
resolved = 0
|
||||
seen = set()
|
||||
|
||||
for url1, url2, score in sorted(duplicate_pairs, key=lambda x: -x[2]):
|
||||
if url1 in seen or url2 in seen:
|
||||
continue
|
||||
|
||||
entry1 = inventory.get(url1, {})
|
||||
entry2 = inventory.get(url2, {})
|
||||
|
||||
if not isinstance(entry1, dict) or not isinstance(entry2, dict):
|
||||
continue
|
||||
|
||||
score1 = _entry_score(entry1)
|
||||
score2 = _entry_score(entry2)
|
||||
|
||||
if score1 >= score2:
|
||||
winner, loser = url1, url2
|
||||
else:
|
||||
winner, loser = url2, url1
|
||||
|
||||
inventory[loser]["status"] = "duplicate"
|
||||
inventory[loser]["duplicate_of"] = winner
|
||||
seen.add(loser)
|
||||
resolved += 1
|
||||
|
||||
return resolved
|
||||
|
||||
|
||||
async def run_dedup(dry_run: bool = True) -> Dict:
|
||||
log_event("STARTING DEDUPLICATION SCAN", section_break=True)
|
||||
inventory = load_inventory()
|
||||
|
||||
url_dups = find_url_duplicates(inventory)
|
||||
log_event(f"[Dedup] URL duplicates: {len(url_dups)}")
|
||||
|
||||
hash_groups = find_hash_duplicates(inventory)
|
||||
hash_dups = []
|
||||
for group in hash_groups:
|
||||
for i in range(1, len(group)):
|
||||
hash_dups.append((group[0], group[i], 1.0))
|
||||
log_event(f"[Dedup] Content hash duplicates: {len(hash_dups)}")
|
||||
|
||||
title_dups = find_title_duplicates(inventory)
|
||||
|
||||
all_dups = [(u1, u2, 1.0) for u1, u2 in url_dups] + hash_dups + title_dups
|
||||
unique_pairs = {}
|
||||
for u1, u2, s in all_dups:
|
||||
key = tuple(sorted([u1, u2]))
|
||||
if key not in unique_pairs or s > unique_pairs[key]:
|
||||
unique_pairs[key] = s
|
||||
deduped_pairs = [(k[0], k[1], v) for k, v in unique_pairs.items()]
|
||||
|
||||
stats = {
|
||||
"url_duplicates": len(url_dups),
|
||||
"hash_duplicates": len(hash_dups),
|
||||
"title_duplicates": len(title_dups),
|
||||
"total_unique_pairs": len(deduped_pairs),
|
||||
}
|
||||
|
||||
if dry_run:
|
||||
log_event(f"[Dedup] DRY RUN — {len(deduped_pairs)} duplicates found, no changes made")
|
||||
for u1, u2, score in sorted(deduped_pairs, key=lambda x: -x[2])[:20]:
|
||||
t1 = inventory.get(u1, {}).get("title", "?")[:60]
|
||||
t2 = inventory.get(u2, {}).get("title", "?")[:60]
|
||||
log_event(f" [{score:.0%}] {t1} <-> {t2}")
|
||||
else:
|
||||
resolved = resolve_duplicates(inventory, deduped_pairs)
|
||||
stats["resolved"] = resolved
|
||||
save_inventory(inventory)
|
||||
log_event(f"[Dedup] Resolved {resolved} duplicates")
|
||||
|
||||
log_event(f"DEDUP COMPLETE: {stats}")
|
||||
return stats
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
asyncio.run(run_dedup(dry_run=True))
|
||||
@@ -5,6 +5,7 @@ import asyncio
|
||||
import httpx
|
||||
from src.logger import log_event
|
||||
from src.gemini_utils import call_gemini_with_retry, fetch_youtube_metadata
|
||||
from src.inventory_manager import load_inventory, save_inventory
|
||||
|
||||
INVENTORY_PATH = "data/inventory.yaml"
|
||||
|
||||
@@ -72,8 +73,7 @@ async def main():
|
||||
|
||||
force_enrich = os.getenv("FORCE_ENRICH", "false").lower() == "true"
|
||||
|
||||
with open(INVENTORY_PATH, "r") as f:
|
||||
inventory = yaml.safe_load(f)
|
||||
inventory = load_inventory()
|
||||
|
||||
video_urls = [u for u, e in inventory.items() if e.get("is_featured_video")]
|
||||
|
||||
@@ -99,8 +99,7 @@ async def main():
|
||||
await asyncio.gather(*batch)
|
||||
|
||||
# Incremental Persistence: Save after each batch
|
||||
with open(INVENTORY_PATH, "w") as f:
|
||||
yaml.dump(inventory, f, sort_keys=False, allow_unicode=True)
|
||||
save_inventory(inventory)
|
||||
log_event(f" [💾] Saved progress: {min(i + batch_size, len(tasks))}/{len(tasks)} videos.")
|
||||
|
||||
if i + batch_size < len(tasks):
|
||||
|
||||
@@ -0,0 +1,373 @@
|
||||
from __future__ import annotations
|
||||
|
||||
import asyncio
|
||||
import re
|
||||
from datetime import datetime, timedelta
|
||||
from typing import Dict, List, Optional, Tuple
|
||||
|
||||
import httpx
|
||||
|
||||
from src.config import GH_TOKEN, MADRID_TZ
|
||||
from src.logger import log_event
|
||||
|
||||
# ---------------------------------------------------------------------------
|
||||
# Constants
|
||||
# ---------------------------------------------------------------------------
|
||||
CNCF_LANDSCAPE_URL = "https://landscape.cncf.io/api/items" # Legacy, now SPA — fallback to GitHub topic search
|
||||
GITHUB_API_BASE = "https://api.github.com"
|
||||
GITHUB_RATE_DELAY = 0.5 # seconds between GitHub API calls (5000/hr limit = ~1.4/s safe)
|
||||
MAX_REPOS_DEFAULT = 200 # cap per run — 200 × 0.5s = ~100s, well within CI timeout
|
||||
ACTIVITY_STALENESS_DAYS = 30
|
||||
|
||||
# Community health thresholds
|
||||
HEALTH_ACTIVE = 50
|
||||
HEALTH_HEALTHY = 10
|
||||
|
||||
# ---------------------------------------------------------------------------
|
||||
# Helpers
|
||||
# ---------------------------------------------------------------------------
|
||||
|
||||
def _github_headers() -> Dict[str, str]:
|
||||
"""Build GitHub API request headers with optional auth."""
|
||||
headers = {"Accept": "application/vnd.github.v3+json"}
|
||||
if GH_TOKEN:
|
||||
headers["Authorization"] = f"token {GH_TOKEN}"
|
||||
return headers
|
||||
|
||||
|
||||
def _parse_github_repo(url: str) -> Optional[str]:
|
||||
"""Extract 'owner/repo' from a GitHub URL. Returns None if not a GitHub URL."""
|
||||
match = re.search(r"github\.com/([^/]+/[^/]+)", url)
|
||||
if not match:
|
||||
return None
|
||||
repo = match.group(1).split("#")[0].split("?")[0].rstrip("/")
|
||||
# Strip trailing .git if present
|
||||
if repo.endswith(".git"):
|
||||
repo = repo[:-4]
|
||||
return repo
|
||||
|
||||
|
||||
def _normalize_repo_url(url: str) -> str:
|
||||
"""Normalize a GitHub repo URL for comparison (lowercase, no trailing slash)."""
|
||||
url = url.lower().rstrip("/")
|
||||
if url.endswith(".git"):
|
||||
url = url[:-4]
|
||||
# Strip protocol
|
||||
url = re.sub(r"^https?://", "", url)
|
||||
return url
|
||||
|
||||
|
||||
def _is_activity_stale(entry: Dict) -> bool:
|
||||
"""Check whether an entry's activity data is older than ACTIVITY_STALENESS_DAYS."""
|
||||
checked = entry.get("gh_activity_checked")
|
||||
if not checked:
|
||||
return True
|
||||
try:
|
||||
checked_dt = datetime.fromisoformat(checked)
|
||||
return datetime.now(MADRID_TZ) - checked_dt > timedelta(days=ACTIVITY_STALENESS_DAYS)
|
||||
except (ValueError, TypeError):
|
||||
return True
|
||||
|
||||
|
||||
# ---------------------------------------------------------------------------
|
||||
# Module 1: CNCF Landscape Status
|
||||
# ---------------------------------------------------------------------------
|
||||
|
||||
async def fetch_cncf_landscape() -> Dict[str, str]:
|
||||
"""Fetch CNCF project graduation status via GitHub topic search.
|
||||
|
||||
The legacy landscape.cncf.io/api/items endpoint is now a SPA and no
|
||||
longer returns JSON. Instead, we search GitHub for repos with CNCF
|
||||
maturity topics (cncf-sandbox, cncf-incubating, cncf-graduated).
|
||||
|
||||
Returns dict mapping repo_url (normalized) -> maturity.
|
||||
"""
|
||||
result: Dict[str, str] = {}
|
||||
headers = _github_headers()
|
||||
maturity_queries = {
|
||||
"graduated": "topic:cncf-graduated",
|
||||
"incubating": "topic:cncf-incubating",
|
||||
"sandbox": "topic:cncf-sandbox",
|
||||
}
|
||||
|
||||
async with httpx.AsyncClient(timeout=30.0) as client:
|
||||
for maturity, query in maturity_queries.items():
|
||||
try:
|
||||
url = f"{GITHUB_API_BASE}/search/repositories?q={query}&per_page=100"
|
||||
resp = await client.get(url, headers=headers)
|
||||
resp.raise_for_status()
|
||||
data = resp.json()
|
||||
for repo in data.get("items", []):
|
||||
repo_url = repo.get("html_url", "")
|
||||
if repo_url:
|
||||
result[_normalize_repo_url(repo_url)] = maturity
|
||||
log_event(f" [CNCF] {maturity}: {len(data.get('items', []))} repos found")
|
||||
except Exception as e:
|
||||
log_event(f"[WARN] CNCF {maturity} search failed: {str(e)[:100]}")
|
||||
await asyncio.sleep(GITHUB_RATE_DELAY)
|
||||
|
||||
log_event(f"[CNCF] Fetched {len(result)} projects from CNCF landscape")
|
||||
return result
|
||||
|
||||
|
||||
async def enrich_cncf_status(inventory: Dict) -> int:
|
||||
"""Update inventory entries with cncf_status field.
|
||||
|
||||
If an entry maps to a CNCF-graduated project and lacks the
|
||||
``[DE FACTO STANDARD]`` tag, the tag is appended.
|
||||
|
||||
Returns count of entries updated.
|
||||
"""
|
||||
landscape = await fetch_cncf_landscape()
|
||||
if not landscape:
|
||||
return 0
|
||||
|
||||
updated = 0
|
||||
for url, entry in inventory.items():
|
||||
if url.startswith("INTRO:"):
|
||||
continue
|
||||
normalized = _normalize_repo_url(url)
|
||||
maturity = landscape.get(normalized)
|
||||
if not maturity:
|
||||
continue
|
||||
|
||||
old_status = entry.get("cncf_status")
|
||||
entry["cncf_status"] = maturity
|
||||
if old_status != maturity:
|
||||
updated += 1
|
||||
|
||||
# Auto-tag graduated projects
|
||||
if maturity == "graduated":
|
||||
tags = entry.get("tags")
|
||||
if isinstance(tags, list) and "[DE FACTO STANDARD]" not in tags:
|
||||
tags.append("[DE FACTO STANDARD]")
|
||||
entry["tags"] = tags
|
||||
|
||||
log_event(f"[CNCF] Enriched {updated} inventory entries with CNCF status")
|
||||
return updated
|
||||
|
||||
|
||||
# ---------------------------------------------------------------------------
|
||||
# Module 2: Social Signal Enrichment (GitHub Activity)
|
||||
# ---------------------------------------------------------------------------
|
||||
|
||||
async def _fetch_repo_activity(
|
||||
client: httpx.AsyncClient,
|
||||
owner_repo: str,
|
||||
) -> Tuple[int, int]:
|
||||
"""Fetch open issue + PR count for a single repo in one API call.
|
||||
|
||||
GitHub's open_issues_count includes PRs, so a single /repos endpoint
|
||||
call is sufficient. Returns (open_issues_count, 0) — the caller uses
|
||||
the combined metric for health classification.
|
||||
"""
|
||||
headers = _github_headers()
|
||||
open_issues = 0
|
||||
|
||||
try:
|
||||
resp = await client.get(
|
||||
f"{GITHUB_API_BASE}/repos/{owner_repo}",
|
||||
headers=headers,
|
||||
timeout=15.0,
|
||||
)
|
||||
if resp.status_code == 200:
|
||||
data = resp.json()
|
||||
open_issues = data.get("open_issues_count", 0)
|
||||
elif resp.status_code == 429:
|
||||
# Rate limited — back off
|
||||
await asyncio.sleep(5.0)
|
||||
except Exception as e:
|
||||
log_event(f"[WARN] GitHub repo fetch failed for {owner_repo}: {str(e)[:120]}")
|
||||
|
||||
await asyncio.sleep(GITHUB_RATE_DELAY)
|
||||
|
||||
return open_issues, 0
|
||||
|
||||
|
||||
def _classify_health(total_activity: int) -> str:
|
||||
"""Classify community health based on combined issue + PR activity."""
|
||||
if total_activity > HEALTH_ACTIVE:
|
||||
return "active"
|
||||
if total_activity >= HEALTH_HEALTHY:
|
||||
return "healthy"
|
||||
if total_activity > 0:
|
||||
return "low"
|
||||
return "dormant"
|
||||
|
||||
|
||||
async def enrich_github_activity(inventory: Dict, max_repos: int = MAX_REPOS_DEFAULT) -> int:
|
||||
"""Fetch recent issue/PR velocity for GitHub repos in the inventory.
|
||||
|
||||
Adds fields:
|
||||
- ``gh_open_issues_30d``
|
||||
- ``gh_open_prs_30d``
|
||||
- ``gh_community_health`` ("active" | "healthy" | "low" | "dormant")
|
||||
- ``gh_activity_checked`` (ISO timestamp)
|
||||
|
||||
Skips entries whose ``gh_activity_checked`` is less than 30 days old.
|
||||
Processes at most *max_repos* repos per run.
|
||||
|
||||
Returns count of entries enriched.
|
||||
"""
|
||||
candidates: List[Tuple[str, str]] = [] # (url, owner/repo)
|
||||
|
||||
for url, entry in inventory.items():
|
||||
if url.startswith("INTRO:"):
|
||||
continue
|
||||
repo = _parse_github_repo(url)
|
||||
if not repo:
|
||||
continue
|
||||
if not _is_activity_stale(entry):
|
||||
continue
|
||||
candidates.append((url, repo))
|
||||
if len(candidates) >= max_repos:
|
||||
break
|
||||
|
||||
if not candidates:
|
||||
log_event("[Activity] No GitHub repos require activity enrichment")
|
||||
return 0
|
||||
|
||||
log_event(f"[Activity] Enriching {len(candidates)} GitHub repos (max {max_repos})")
|
||||
|
||||
enriched = 0
|
||||
async with httpx.AsyncClient() as client:
|
||||
for url, owner_repo in candidates:
|
||||
try:
|
||||
open_issues, open_prs = await _fetch_repo_activity(client, owner_repo)
|
||||
total = open_issues + open_prs
|
||||
health = _classify_health(total)
|
||||
|
||||
entry = inventory[url]
|
||||
entry["gh_open_issues_30d"] = open_issues
|
||||
entry["gh_open_prs_30d"] = open_prs
|
||||
entry["gh_community_health"] = health
|
||||
entry["gh_activity_checked"] = datetime.now(MADRID_TZ).isoformat()
|
||||
enriched += 1
|
||||
except Exception as e:
|
||||
log_event(f"[WARN] Activity enrichment failed for {owner_repo}: {str(e)[:150]}")
|
||||
|
||||
log_event(f"[Activity] Enriched {enriched}/{len(candidates)} repos with community health data")
|
||||
return enriched
|
||||
|
||||
|
||||
# ---------------------------------------------------------------------------
|
||||
# Module 3: License Change Detection
|
||||
# ---------------------------------------------------------------------------
|
||||
|
||||
async def _fetch_current_license(
|
||||
client: httpx.AsyncClient,
|
||||
owner_repo: str,
|
||||
) -> Optional[str]:
|
||||
"""Fetch the current SPDX license identifier for a GitHub repo."""
|
||||
headers = _github_headers()
|
||||
try:
|
||||
resp = await client.get(
|
||||
f"{GITHUB_API_BASE}/repos/{owner_repo}",
|
||||
headers=headers,
|
||||
timeout=15.0,
|
||||
)
|
||||
if resp.status_code == 200:
|
||||
data = resp.json()
|
||||
lic = data.get("license")
|
||||
if isinstance(lic, dict):
|
||||
return lic.get("spdx_id", "N/A")
|
||||
return "N/A"
|
||||
elif resp.status_code == 404:
|
||||
return None # repo not found / deleted
|
||||
except Exception as e:
|
||||
log_event(f"[WARN] License fetch failed for {owner_repo}: {str(e)[:120]}")
|
||||
return None
|
||||
|
||||
|
||||
async def detect_license_changes(inventory: Dict) -> List[Dict]:
|
||||
"""Compare current gh_license with stored license, flag changes.
|
||||
|
||||
For each GitHub repo in inventory that has ``gh_license``:
|
||||
- Fetches the current license from the GitHub API.
|
||||
- Compares with the stored ``gh_license``.
|
||||
- If different, updates the entry: sets ``gh_license`` to the new value
|
||||
and stores the old value in ``gh_license_previous``.
|
||||
|
||||
Returns list of ``{url, old_license, new_license, title}`` dicts.
|
||||
"""
|
||||
candidates: List[Tuple[str, str, Dict]] = [] # (url, owner/repo, entry)
|
||||
|
||||
for url, entry in inventory.items():
|
||||
if url.startswith("INTRO:"):
|
||||
continue
|
||||
if not entry.get("gh_license") or entry["gh_license"] == "N/A":
|
||||
continue
|
||||
repo = _parse_github_repo(url)
|
||||
if not repo:
|
||||
continue
|
||||
candidates.append((url, repo, entry))
|
||||
|
||||
if not candidates:
|
||||
log_event("[License] No repos with stored licenses to check")
|
||||
return []
|
||||
|
||||
candidates = candidates[:MAX_REPOS_DEFAULT] # cap to same limit as activity enrichment
|
||||
log_event(f"[License] Checking {len(candidates)} repos for license changes")
|
||||
|
||||
changes: List[Dict] = []
|
||||
async with httpx.AsyncClient() as client:
|
||||
for url, owner_repo, entry in candidates:
|
||||
try:
|
||||
current = await _fetch_current_license(client, owner_repo)
|
||||
if current is None:
|
||||
# Repo not found or API error — skip
|
||||
continue
|
||||
|
||||
stored = entry.get("gh_license", "N/A")
|
||||
if current != stored:
|
||||
change_record = {
|
||||
"url": url,
|
||||
"old_license": stored,
|
||||
"new_license": current,
|
||||
"title": entry.get("title", url),
|
||||
}
|
||||
changes.append(change_record)
|
||||
entry["gh_license_previous"] = stored
|
||||
entry["gh_license"] = current
|
||||
log_event(
|
||||
f"[License] Change detected: {owner_repo} "
|
||||
f"{stored} -> {current}"
|
||||
)
|
||||
except Exception as e:
|
||||
log_event(f"[WARN] License check failed for {owner_repo}: {str(e)[:150]}")
|
||||
|
||||
await asyncio.sleep(GITHUB_RATE_DELAY)
|
||||
|
||||
log_event(f"[License] Detected {len(changes)} license change(s)")
|
||||
return changes
|
||||
|
||||
|
||||
# ---------------------------------------------------------------------------
|
||||
# Full Enrichment Pipeline
|
||||
# ---------------------------------------------------------------------------
|
||||
|
||||
async def run_enrichment():
|
||||
"""Full enrichment pipeline: CNCF + GitHub activity + license detection."""
|
||||
from src.inventory_manager import load_inventory, save_inventory
|
||||
|
||||
log_event("ENRICHMENT PIPELINE STARTING", section_break=True)
|
||||
inventory = load_inventory()
|
||||
log_event(f"[*] Loaded {len(inventory)} inventory entries")
|
||||
|
||||
cncf_count = await enrich_cncf_status(inventory)
|
||||
activity_count = await enrich_github_activity(inventory)
|
||||
license_changes = await detect_license_changes(inventory)
|
||||
|
||||
save_inventory(inventory)
|
||||
log_event(
|
||||
f"Enrichment complete: {cncf_count} CNCF, "
|
||||
f"{activity_count} activity, "
|
||||
f"{len(license_changes)} license changes",
|
||||
section_break=True,
|
||||
)
|
||||
|
||||
return license_changes
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
asyncio.run(run_enrichment())
|
||||
@@ -50,7 +50,7 @@ def get_readable_category(category: str) -> str:
|
||||
async def fetch_github_metadata(client: httpx.AsyncClient, url: str, sem: asyncio.Semaphore) -> tuple[str, dict]:
|
||||
default_meta = {
|
||||
"gh_stars": 0,
|
||||
"gh_pushed": "N/A",
|
||||
"gh_pushed": None, # date field: unknown = None, never the string "N/A"
|
||||
"gh_license": "N/A"
|
||||
}
|
||||
match = re.search(r'github\.com/([^/]+/[^/]+)', url)
|
||||
@@ -72,20 +72,20 @@ async def fetch_github_metadata(client: httpx.AsyncClient, url: str, sem: asynci
|
||||
lic_id = lic.get("spdx_id", "N/A") if isinstance(lic, dict) else "N/A"
|
||||
return url, {
|
||||
"gh_stars": data.get("stargazers_count", 0),
|
||||
"gh_pushed": data.get("pushed_at", "N/A"),
|
||||
"gh_pushed": data.get("pushed_at"),
|
||||
"gh_license": lic_id
|
||||
}
|
||||
elif resp.status_code == 404:
|
||||
return url, {
|
||||
"gh_stars": 0,
|
||||
"gh_pushed": "N/A",
|
||||
"gh_pushed": None,
|
||||
"gh_license": "N/A",
|
||||
"status": "dead"
|
||||
}
|
||||
else:
|
||||
return url, {
|
||||
"gh_stars": 0,
|
||||
"gh_pushed": "N/A",
|
||||
"gh_pushed": None,
|
||||
"gh_license": "N/A",
|
||||
"status": "unreachable"
|
||||
}
|
||||
@@ -94,10 +94,11 @@ async def fetch_github_metadata(client: httpx.AsyncClient, url: str, sem: asynci
|
||||
return url, default_meta
|
||||
|
||||
|
||||
from src.inventory_manager import load_inventory
|
||||
|
||||
async def run_enrichment():
|
||||
print("[*] Loading inventory database...")
|
||||
with open(INVENTORY_PATH, "r") as f:
|
||||
inventory = yaml.safe_load(f) or {}
|
||||
inventory = load_inventory()
|
||||
|
||||
print(f"[*] Loaded {len(inventory)} total entries.")
|
||||
|
||||
|
||||
@@ -122,7 +122,8 @@ async def discover_optimal_models():
|
||||
if name not in all_supported: all_supported.append(name)
|
||||
elif resp.status_code == 429:
|
||||
log_event(f" [!] Discovery Key is rate-limited (429). Skipping.")
|
||||
except: pass
|
||||
except Exception as e:
|
||||
log_event(f"[WARN] model discovery for key: {str(e)[:100]}")
|
||||
|
||||
if not all_supported:
|
||||
log_event(" [!] Discovery failed. Falling back to safe defaults.")
|
||||
@@ -136,7 +137,8 @@ async def discover_optimal_models():
|
||||
try:
|
||||
version = float(version_match.group(1))
|
||||
score += version * 50
|
||||
except: pass
|
||||
except Exception as e:
|
||||
log_event(f"[WARN] parse model version for {name}: {str(e)[:100]}")
|
||||
if "-ultra" in name: score += 100
|
||||
elif "-pro" in name: score += 50
|
||||
elif "-flash" in name: score += 25
|
||||
@@ -169,7 +171,9 @@ class GeminiDiagnostics:
|
||||
async def resolve_url(url: str) -> str:
|
||||
shorteners = ['t.co', 'bit.ly', 'buff.ly', 'goo.gl', 'tinyurl.com', 't.ly', 'rb.gy', 'is.gd', 'drp.li', 't.me', 'lnkd.in']
|
||||
try: domain = url.split("//")[-1].split("/")[0].lower()
|
||||
except: return url
|
||||
except Exception as e:
|
||||
log_event(f"[WARN] parse domain from URL {url[:50]}: {str(e)[:100]}")
|
||||
return url
|
||||
final_url, max_hops, current_hop = url, 5, 0
|
||||
async with httpx.AsyncClient(follow_redirects=True, timeout=8) as client:
|
||||
while current_hop < max_hops:
|
||||
@@ -180,7 +184,9 @@ async def resolve_url(url: str) -> str:
|
||||
new_url = str(resp.url)
|
||||
if new_url == final_url: break
|
||||
final_url, current_hop = new_url, current_hop + 1
|
||||
except: break
|
||||
except Exception as e:
|
||||
log_event(f"[WARN] resolve URL hop for {final_url[:50]}: {str(e)[:100]}")
|
||||
break
|
||||
|
||||
# Mandate 34: Prevent multiple trailing slashes using centralized utility
|
||||
return sanitize_trailing_slashes(final_url)
|
||||
@@ -205,7 +211,7 @@ async def get_github_activity(url: str) -> Dict:
|
||||
"""
|
||||
default_meta = {
|
||||
"gh_stars": 0,
|
||||
"gh_pushed": "N/A",
|
||||
"gh_pushed": None, # date field: unknown = None, never the string "N/A"
|
||||
"gh_license": "N/A"
|
||||
}
|
||||
match = re.search(r'github\.com/([^/]+/[^/]+)', url)
|
||||
@@ -217,7 +223,8 @@ async def get_github_activity(url: str) -> Dict:
|
||||
try:
|
||||
from src.config import GH_TOKEN
|
||||
headers = {"Authorization": f"token {GH_TOKEN}"} if GH_TOKEN else {}
|
||||
except:
|
||||
except Exception as e:
|
||||
log_event(f"[WARN] import GH_TOKEN for GitHub activity: {str(e)[:100]}")
|
||||
headers = {}
|
||||
|
||||
try:
|
||||
@@ -229,10 +236,11 @@ async def get_github_activity(url: str) -> Dict:
|
||||
lic_id = lic.get("spdx_id", "N/A") if isinstance(lic, dict) else "N/A"
|
||||
return {
|
||||
"gh_stars": data.get("stargazers_count", 0),
|
||||
"gh_pushed": data.get("pushed_at", "N/A"),
|
||||
"gh_pushed": data.get("pushed_at"),
|
||||
"gh_license": lic_id
|
||||
}
|
||||
except: pass
|
||||
except Exception as e:
|
||||
log_event(f"[WARN] fetch GitHub activity for {url}: {str(e)[:100]}")
|
||||
return default_meta
|
||||
|
||||
|
||||
@@ -436,7 +444,8 @@ async def call_gemini_with_retry(prompt: str, response_format: str = "json", max
|
||||
|
||||
resp_json = {}
|
||||
try: resp_json = response.json()
|
||||
except: pass
|
||||
except Exception as e:
|
||||
log_event(f"[WARN] parse Gemini response JSON: {str(e)[:100]}")
|
||||
|
||||
usage = resp_json.get("usageMetadata", {})
|
||||
SESSION_TRACKER.track_call(current_idx, model, response.status_code, usage, role=role)
|
||||
@@ -452,7 +461,8 @@ async def call_gemini_with_retry(prompt: str, response_format: str = "json", max
|
||||
try:
|
||||
data = json.loads(match.group(0))
|
||||
return data
|
||||
except: pass
|
||||
except Exception as e:
|
||||
log_event(f"[WARN] parse Gemini content JSON for model {model}: {str(e)[:100]}")
|
||||
|
||||
# QUALITY UPGRADE: If flash failed parsing, don't give up on the key, try a Pro model
|
||||
if ("flash" in model or "lite" in model) and any("pro" in m for m in models):
|
||||
@@ -574,7 +584,8 @@ async def fetch_youtube_metadata(url: str) -> Optional[Dict]:
|
||||
try:
|
||||
transcript = YouTubeTranscriptApi.get_transcript(vid, languages=['en', 'es'])
|
||||
transcript_text = " ".join([t['text'] for t in transcript[:100]])
|
||||
except: pass
|
||||
except Exception as e:
|
||||
log_event(f"[WARN] fetch YouTube transcript for {vid}: {str(e)[:100]}")
|
||||
|
||||
full_description = f"{description}\n\n[Transcript Snippet]: {transcript_text}" if transcript_text else description
|
||||
|
||||
|
||||
@@ -21,14 +21,16 @@ class RepositoryController:
|
||||
try:
|
||||
file_meta = self.repository.get_contents(file_path, ref=branch_name)
|
||||
return base64.b64decode(file_meta.content).decode("utf-8")
|
||||
except:
|
||||
except Exception as e:
|
||||
print(f"[WARN] Failed to get file '{file_path}' from branch '{branch_name}': {str(e)[:100]}")
|
||||
return ""
|
||||
|
||||
def apply_historical_chunk(self, updates: dict, next_since: str) -> None:
|
||||
branch_name = "bot/historical-accumulator"
|
||||
try:
|
||||
self.repository.get_branch(branch_name)
|
||||
except:
|
||||
except Exception as e:
|
||||
print(f"[WARN] Branch '{branch_name}' not found, creating: {str(e)[:100]}")
|
||||
self._create_feature_branch(branch_name)
|
||||
|
||||
for file_path, content in updates.items():
|
||||
@@ -54,7 +56,8 @@ class RepositoryController:
|
||||
|
||||
try:
|
||||
self._create_feature_branch(branch_name)
|
||||
except:
|
||||
except Exception as e:
|
||||
print(f"[WARN] Branch creation failed, retrying with unique suffix: {str(e)[:100]}")
|
||||
branch_name = f"bot/knowledge-update-{timestamp_slug}-{id(updates)}"
|
||||
self._create_feature_branch(branch_name)
|
||||
|
||||
|
||||
@@ -88,11 +88,12 @@ class BackupDataExtractor:
|
||||
def parse_date(x):
|
||||
try:
|
||||
return datetime.strptime(x["timestamp"], '%a %b %d %H:%M:%S +0000 %Y')
|
||||
except:
|
||||
except Exception as e:
|
||||
print(f"[WARN] Date parse failed for timestamp: {str(e)[:100]}")
|
||||
return datetime.min
|
||||
results.sort(key=parse_date)
|
||||
except:
|
||||
pass
|
||||
except Exception as e:
|
||||
print(f"[WARN] Sorting results by date failed: {str(e)[:100]}")
|
||||
|
||||
self.log_audit("Backup Ingestion", True, f"Total links extracted: {len(results)}")
|
||||
return results
|
||||
|
||||
@@ -52,8 +52,8 @@ class SocialDataExtractor:
|
||||
try:
|
||||
from playwright.async_api import async_playwright
|
||||
import playwright_stealth
|
||||
except:
|
||||
self.log_audit("Playwright", False, "Libraries not available.")
|
||||
except Exception as e:
|
||||
self.log_audit("Playwright", False, f"Libraries not available: {str(e)[:100]}")
|
||||
return []
|
||||
|
||||
collected_tweets = {}
|
||||
@@ -74,14 +74,16 @@ class SocialDataExtractor:
|
||||
for k in ['sameSite', 'storeId', 'id']: c.pop(k, None)
|
||||
formatted.append(c)
|
||||
await context.add_cookies(formatted)
|
||||
except: pass
|
||||
except Exception as e:
|
||||
log_event(f"[WARN] Failed to load Twitter cookies: {str(e)[:100]}")
|
||||
|
||||
for account in accounts:
|
||||
page = await context.new_page()
|
||||
try:
|
||||
if hasattr(playwright_stealth, 'stealth_async'): await playwright_stealth.stealth_async(page)
|
||||
elif hasattr(playwright_stealth, 'stealth'): playwright_stealth.stealth(page)
|
||||
except: pass
|
||||
except Exception as e:
|
||||
log_event(f"[WARN] Playwright stealth setup failed: {str(e)[:100]}")
|
||||
|
||||
if strategy == "search":
|
||||
import urllib.parse
|
||||
|
||||
@@ -44,7 +44,8 @@ class IntelligentLinkCleaner:
|
||||
def _load_memory(self) -> Dict:
|
||||
if os.path.exists(MEMORY_FILE):
|
||||
try: return json.load(open(MEMORY_FILE, 'r'))
|
||||
except: pass
|
||||
except Exception as e:
|
||||
log_event(f"[WARN] load health learning memory: {str(e)[:100]}")
|
||||
return {"domains": {}, "known_soft_404_patterns": []}
|
||||
|
||||
def _save_memory(self):
|
||||
@@ -198,8 +199,10 @@ class IntelligentLinkCleaner:
|
||||
else:
|
||||
log_event(f" [✨] RESCUED: {u} -> {new_loc}")
|
||||
check_results[u] = (True, "resurrected", new_loc)
|
||||
except: pass
|
||||
except: pass
|
||||
except Exception as e:
|
||||
log_event(f"[WARN] verify rescued URL {new_loc[:50]}: {str(e)[:100]}")
|
||||
except Exception as e:
|
||||
log_event(f"[WARN] AI rescue batch: {str(e)[:100]}")
|
||||
|
||||
# 2.8. Finalize Status
|
||||
log_event("FINALIZING STATUS AND METRICS...", section_break=True)
|
||||
@@ -309,7 +312,8 @@ class IntelligentLinkCleaner:
|
||||
log_event(f" [⚖️] LICENSE ALERT: {url} -> {new_lic}")
|
||||
entry["status"] = "review_required"
|
||||
entry["gh_license"] = new_lic
|
||||
except: pass
|
||||
except Exception as e:
|
||||
log_event(f"[WARN] license guard check for {url}: {str(e)[:100]}")
|
||||
|
||||
if final_url != url:
|
||||
u_p = url.split("://")[-1].rstrip("/"); f_p = final_url.split("://")[-1].rstrip("/")
|
||||
@@ -325,12 +329,15 @@ class IntelligentLinkCleaner:
|
||||
h = url.replace("/master/", "/main/")
|
||||
try:
|
||||
if (await client.get(h)).status_code < 400: return True, "healed", h
|
||||
except: pass
|
||||
except Exception as e:
|
||||
log_event(f"[WARN] heal master->main for {url}: {str(e)[:100]}")
|
||||
m = re.search(r'(https?://github\.com/[^/]+/[^/]+)', url)
|
||||
if m and (await client.get(m.group(1))).status_code < 400: return True, "consolidated", m.group(1)
|
||||
return False, "404", None
|
||||
return True, f"Soft Block {resp.status_code}", None
|
||||
except: return True, "Error", None
|
||||
except Exception as e:
|
||||
log_event(f"[WARN] URL check logic for {url}: {str(e)[:100]}")
|
||||
return True, "Error", None
|
||||
|
||||
async def prune_orphaned_metadata(self):
|
||||
valid_map = {}
|
||||
|
||||
@@ -1,46 +1,207 @@
|
||||
import os
|
||||
import json
|
||||
import sqlite3
|
||||
import yaml
|
||||
from typing import Dict
|
||||
|
||||
INVENTORY_PATH = "data/inventory.yaml"
|
||||
SQL_PATH = "data/inventory.sql"
|
||||
|
||||
try:
|
||||
from yaml import CSafeLoader as Loader, CSafeDumper as Dumper
|
||||
except ImportError:
|
||||
from yaml import SafeLoader as Loader, SafeDumper as Dumper
|
||||
|
||||
def load_inventory(shard_file: str = None) -> Dict:
|
||||
"""
|
||||
Loads the entire inventory from a single YAML file.
|
||||
Legacy/Fast-Track standard restored: Zero-sharding complexity.
|
||||
Loads the entire inventory.
|
||||
Option 3: Imports inventory.sql to temporary SQLite database in-memory,
|
||||
queries the database to reconstruct the Python dictionary, and returns it.
|
||||
Falls back to inventory.yaml if SQL file is not present.
|
||||
"""
|
||||
if os.path.exists(INVENTORY_PATH):
|
||||
if not os.path.exists(SQL_PATH) and os.path.exists(INVENTORY_PATH):
|
||||
try:
|
||||
with open(INVENTORY_PATH, "r") as file:
|
||||
return yaml.safe_load(file) or {}
|
||||
except: pass
|
||||
return {}
|
||||
with open(INVENTORY_PATH, "r", encoding="utf-8") as file:
|
||||
return yaml.load(file, Loader=Loader) or {}
|
||||
except Exception as e:
|
||||
pass
|
||||
return {}
|
||||
|
||||
if not os.path.exists(SQL_PATH):
|
||||
return {}
|
||||
|
||||
conn = sqlite3.connect(":memory:")
|
||||
try:
|
||||
with open(SQL_PATH, "r", encoding="utf-8") as f:
|
||||
conn.executescript(f.read())
|
||||
except Exception as e:
|
||||
conn.close()
|
||||
# Fallback to YAML if SQL import fails
|
||||
if os.path.exists(INVENTORY_PATH):
|
||||
try:
|
||||
with open(INVENTORY_PATH, "r", encoding="utf-8") as file:
|
||||
return yaml.load(file, Loader=Loader) or {}
|
||||
except Exception as e:
|
||||
print(f"[WARN] YAML fallback load failed: {str(e)[:100]}")
|
||||
return {}
|
||||
|
||||
cursor = conn.cursor()
|
||||
try:
|
||||
cursor.execute("SELECT * FROM resources")
|
||||
rows = cursor.fetchall()
|
||||
col_names = [description[0] for description in cursor.description]
|
||||
except Exception as e:
|
||||
conn.close()
|
||||
return {}
|
||||
|
||||
inv = {}
|
||||
for row in rows:
|
||||
record = dict(zip(col_names, row))
|
||||
url = record.pop("url")
|
||||
|
||||
# Deserialize JSON lists/dicts
|
||||
for json_field in ["hierarchy", "tags", "v1_locations", "v2_locations", "youtube_mosaic", "extra_metadata"]:
|
||||
val = record.get(json_field)
|
||||
if val:
|
||||
try:
|
||||
record[json_field] = json.loads(val)
|
||||
except Exception as e:
|
||||
print(f"[WARN] JSON parse failed for field '{json_field}': {str(e)[:100]}")
|
||||
record[json_field] = [] if json_field not in ["youtube_mosaic", "extra_metadata"] else {}
|
||||
else:
|
||||
record[json_field] = [] if json_field not in ["youtube_mosaic", "extra_metadata"] else {}
|
||||
|
||||
# Merge extra_metadata keys back into the record dictionary
|
||||
extra = record.pop("extra_metadata", {})
|
||||
if isinstance(extra, dict):
|
||||
record.update(extra)
|
||||
|
||||
# Restore types
|
||||
if record.get("is_microservice") is not None:
|
||||
record["is_microservice"] = bool(record["is_microservice"])
|
||||
if record.get("needs_ai_refresh") is not None:
|
||||
record["needs_ai_refresh"] = bool(record["needs_ai_refresh"])
|
||||
|
||||
inv[url] = record
|
||||
|
||||
conn.close()
|
||||
return inv
|
||||
|
||||
def save_inventory(inv: Dict, shard_file: str = None):
|
||||
"""
|
||||
Saves the entire inventory to a single YAML file.
|
||||
Saves the entire inventory.
|
||||
Option 3: Creates an in-memory SQLite table, populates it,
|
||||
and exports it back to inventory.sql.
|
||||
Also dual-saves a backup to inventory.yaml using fast CDumper.
|
||||
"""
|
||||
conn = sqlite3.connect(":memory:")
|
||||
cursor = conn.cursor()
|
||||
|
||||
cursor.execute("""
|
||||
CREATE TABLE IF NOT EXISTS resources (
|
||||
url TEXT PRIMARY KEY,
|
||||
title TEXT,
|
||||
description TEXT,
|
||||
year TEXT,
|
||||
stars INTEGER,
|
||||
ai_summary TEXT,
|
||||
language TEXT,
|
||||
resource_type TEXT,
|
||||
complexity TEXT,
|
||||
is_microservice BOOLEAN,
|
||||
status TEXT,
|
||||
addition_method TEXT,
|
||||
content_hash TEXT,
|
||||
health_score REAL,
|
||||
last_checked INTEGER,
|
||||
needs_ai_refresh BOOLEAN,
|
||||
discovered_at TEXT,
|
||||
last_ai_eval TEXT,
|
||||
company TEXT,
|
||||
geo_region TEXT,
|
||||
hierarchy TEXT,
|
||||
tags TEXT,
|
||||
v1_locations TEXT,
|
||||
v2_locations TEXT,
|
||||
youtube_mosaic TEXT,
|
||||
extra_metadata TEXT
|
||||
);
|
||||
""")
|
||||
|
||||
columns = [
|
||||
"url", "title", "description", "year", "stars", "ai_summary", "language",
|
||||
"resource_type", "complexity", "is_microservice", "status", "addition_method",
|
||||
"content_hash", "health_score", "last_checked", "needs_ai_refresh",
|
||||
"discovered_at", "last_ai_eval", "company", "geo_region",
|
||||
"hierarchy", "tags", "v1_locations", "v2_locations", "youtube_mosaic", "extra_metadata"
|
||||
]
|
||||
|
||||
for url, entry in inv.items():
|
||||
if not isinstance(entry, dict):
|
||||
continue
|
||||
|
||||
# last_checked is a coarse staleness timestamp (epoch seconds). Normalize
|
||||
# it to int on the entry itself — before building the SQL record AND the
|
||||
# YAML dump below — so both serializations agree, and SQLite's
|
||||
# version-specific REAL->text float formatting can't rewrite every row on
|
||||
# dump. Sub-second precision is not used by any reader.
|
||||
lc = entry.get("last_checked")
|
||||
if isinstance(lc, float):
|
||||
entry["last_checked"] = int(lc)
|
||||
|
||||
record = {col: entry.get(col) for col in columns if col not in ["hierarchy", "tags", "v1_locations", "v2_locations", "youtube_mosaic", "extra_metadata"]}
|
||||
record["url"] = url
|
||||
|
||||
# Serialize lists/dicts
|
||||
record["hierarchy"] = json.dumps(entry.get("hierarchy", []))
|
||||
record["tags"] = json.dumps(entry.get("tags", []))
|
||||
record["v1_locations"] = json.dumps(entry.get("v1_locations", []))
|
||||
record["v2_locations"] = json.dumps(entry.get("v2_locations", []))
|
||||
record["youtube_mosaic"] = json.dumps(entry.get("youtube_mosaic", {}))
|
||||
|
||||
# Pull arbitrary extra fields
|
||||
extra = {}
|
||||
for k, v in entry.items():
|
||||
if k not in columns:
|
||||
extra[k] = v
|
||||
record["extra_metadata"] = json.dumps(extra)
|
||||
|
||||
# Conversions
|
||||
record["is_microservice"] = 1 if record.get("is_microservice") else 0
|
||||
record["needs_ai_refresh"] = 1 if record.get("needs_ai_refresh") else 0
|
||||
|
||||
placeholders = ", ".join(["?"] * len(columns))
|
||||
values = [record[col] for col in columns]
|
||||
cursor.execute(f"INSERT OR REPLACE INTO resources ({', '.join(columns)}) VALUES ({placeholders})", values)
|
||||
|
||||
conn.commit()
|
||||
|
||||
# Dump to SQL
|
||||
os.makedirs(os.path.dirname(SQL_PATH), exist_ok=True)
|
||||
with open(SQL_PATH, "w", encoding="utf-8") as f:
|
||||
for line in conn.iterdump():
|
||||
f.write(f"{line}\n")
|
||||
|
||||
conn.close()
|
||||
|
||||
# Dual-Save to YAML (Fast C-Dumper)
|
||||
os.makedirs(os.path.dirname(INVENTORY_PATH), exist_ok=True)
|
||||
with open(INVENTORY_PATH, "w") as file:
|
||||
yaml.dump(inv, file, sort_keys=False, allow_unicode=True)
|
||||
with open(INVENTORY_PATH, "w", encoding="utf-8") as file:
|
||||
yaml.dump(inv, file, Dumper=Dumper, sort_keys=False, allow_unicode=True)
|
||||
|
||||
def get_shard_name(url: str) -> str:
|
||||
# Kept for backward compatibility but unused in single-file mode
|
||||
return "inventory.yaml"
|
||||
|
||||
def update_inventory_entry(inventory: Dict, norm_url: str, new_data: Dict):
|
||||
"""
|
||||
Updates an inventory entry by merging new_data with existing data,
|
||||
preserving metadata keys like 'youtube_mosaic' if they are not in new_data.
|
||||
"""
|
||||
if norm_url not in inventory:
|
||||
inventory[norm_url] = {}
|
||||
|
||||
existing = inventory[norm_url]
|
||||
if isinstance(existing, dict):
|
||||
merged = existing.copy()
|
||||
existing_discovered = existing.get("discovered_at")
|
||||
merged.update(new_data)
|
||||
if existing_discovered:
|
||||
merged["discovered_at"] = existing_discovered
|
||||
inventory[norm_url] = merged
|
||||
else:
|
||||
inventory[norm_url] = new_data
|
||||
|
||||
|
||||
@@ -32,5 +32,5 @@ def _write_to_file(message: str):
|
||||
os.makedirs(os.path.dirname(DEFAULT_LOG_PATH), exist_ok=True)
|
||||
with open(DEFAULT_LOG_PATH, "a") as f:
|
||||
f.write(message + "\n")
|
||||
except:
|
||||
pass
|
||||
except Exception as e:
|
||||
print(f"[WARN] write to log file: {str(e)[:100]}")
|
||||
|
||||
@@ -4,6 +4,12 @@ import os
|
||||
import json
|
||||
import re
|
||||
import yaml
|
||||
try:
|
||||
from yaml import CSafeLoader as Loader
|
||||
except ImportError:
|
||||
from yaml import SafeLoader as Loader
|
||||
import httpx
|
||||
from urllib.parse import urlparse
|
||||
from datetime import datetime, timedelta
|
||||
from src.config import TARGET_REPO, MADRID_TZ, GH_TOKEN, NUBENETES_CATEGORIES
|
||||
from src.ingestion_twikit import SocialDataExtractor
|
||||
@@ -16,6 +22,18 @@ from src.gemini_utils import call_gemini_with_retry, resolve_url, normalize_url,
|
||||
from src.state_manager import get_last_date, save_state
|
||||
|
||||
async def master_orchestrator():
|
||||
# Load domain health history (Recommendation #2)
|
||||
health_learning_path = "src/memory/health_learning.json"
|
||||
health_learning = {}
|
||||
if os.path.exists(health_learning_path):
|
||||
try:
|
||||
with open(health_learning_path, "r") as f:
|
||||
health_learning = json.load(f)
|
||||
except Exception as e:
|
||||
log_event(f"[!] Error loading health_learning.json: {e}")
|
||||
if "domains" not in health_learning:
|
||||
health_learning["domains"] = {}
|
||||
|
||||
# 0. Ingest Mandates from GEMINI.md (Mandate Bridge)
|
||||
try:
|
||||
from src.mandate_ingestor import MandateIngestor
|
||||
@@ -41,7 +59,8 @@ async def master_orchestrator():
|
||||
since_date = until_date - timedelta(days=days)
|
||||
log_event(f"[*] Mode: Relative range (Last {days} days) -> {since_date.date()}")
|
||||
is_historical = False # Force normal mode for relative range
|
||||
except:
|
||||
except Exception as e:
|
||||
log_event(f"[WARN] parse CURATION_DAYS_BACK: {str(e)[:100]}")
|
||||
since_date = get_last_date()
|
||||
elif is_historical:
|
||||
# DEFAULT START DATE: 2026-05-15 (as requested)
|
||||
@@ -68,7 +87,8 @@ async def master_orchestrator():
|
||||
try:
|
||||
since_date = datetime.fromisoformat(env_start).replace(tzinfo=MADRID_TZ)
|
||||
log_event(f"[*] Normal Mode: From manual workflow date {since_date.date()}")
|
||||
except:
|
||||
except Exception as e:
|
||||
log_event(f"[WARN] parse CURATION_START_DATE: {str(e)[:100]}")
|
||||
since_date = get_last_date()
|
||||
log_event(f"[*] Normal Mode: Error parsing manual date, using state.json {since_date.date()}")
|
||||
else:
|
||||
@@ -100,8 +120,8 @@ async def master_orchestrator():
|
||||
|
||||
if os.path.exists(sources_file):
|
||||
try:
|
||||
with open(sources_file, 'r') as f:
|
||||
data = yaml.safe_load(f)
|
||||
with open(sources_file, 'r', encoding='utf-8') as f:
|
||||
data = yaml.load(f, Loader=Loader)
|
||||
all_accounts = set()
|
||||
for topic_data in data.get("sources", []):
|
||||
topic_name = topic_data.get("topic")
|
||||
@@ -135,11 +155,15 @@ async def master_orchestrator():
|
||||
raw_social = await extractor.fetch_links()
|
||||
x_audit_trail = extractor.audit_trail
|
||||
else:
|
||||
# A. X.com Extraction
|
||||
strategy = os.getenv("EXTRACTION_STRATEGY", "search")
|
||||
twitter_client = SocialDataExtractor()
|
||||
raw_social = await twitter_client.fetch_links_since(since_date, until_date=until_date, strategy=strategy, accounts=accounts_to_scan)
|
||||
x_audit_trail = twitter_client.audit_trail
|
||||
# A. X.com Extraction (Toggleable via ENABLE_TWITTER_CURATION - Recommendation #2)
|
||||
if os.getenv("ENABLE_TWITTER_CURATION", "false").lower() == "true":
|
||||
strategy = os.getenv("EXTRACTION_STRATEGY", "search")
|
||||
twitter_client = SocialDataExtractor()
|
||||
raw_social = await twitter_client.fetch_links_since(since_date, until_date=until_date, strategy=strategy, accounts=accounts_to_scan)
|
||||
x_audit_trail = twitter_client.audit_trail
|
||||
else:
|
||||
log_event("[*] Twitter curation is disabled (ENABLE_TWITTER_CURATION != true). Skipping X.com extraction.")
|
||||
raw_social = []
|
||||
|
||||
# B. RSS Extraction
|
||||
if feeds_to_scan:
|
||||
@@ -172,6 +196,11 @@ async def master_orchestrator():
|
||||
"Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/123.0.0.0 Safari/537.36",
|
||||
"Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/124.0.0.0 Safari/537.36"
|
||||
]
|
||||
fallback_user_agents = [
|
||||
"Mozilla/5.0 (iPhone; CPU iPhone OS 17_4 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/17.4 Mobile/15E148 Safari/604.1",
|
||||
"Mozilla/5.0 (iPad; CPU OS 17_4 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) FxiOS/124.0 Mobile/15E148 Safari/605.1.15",
|
||||
"Mozilla/5.0 (Linux; Android 10; K) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/124.0.0.0 Mobile Safari/537.36"
|
||||
]
|
||||
|
||||
async def process_asset(asset, idx):
|
||||
async with semaphore:
|
||||
@@ -179,20 +208,46 @@ async def master_orchestrator():
|
||||
expanded_url = await resolve_url(asset["url"])
|
||||
asset["url"] = expanded_url
|
||||
|
||||
# 2. Resilient Health Check (Identity Rotation)
|
||||
ua = user_agents[idx % len(user_agents)]
|
||||
# 2. Resilient Health Check (Identity Rotation & Domain failure stats - Recommendation #2)
|
||||
parsed = urlparse(expanded_url)
|
||||
domain = parsed.netloc.lower()
|
||||
|
||||
domain_info = health_learning["domains"].setdefault(domain, {"attempts": 0, "failures": 0, "consecutive_failures": 0, "success_rate": 100.0})
|
||||
consecutive_failures = domain_info.get("consecutive_failures", 0)
|
||||
success_rate = domain_info.get("success_rate", 100.0)
|
||||
|
||||
timeout_val = 12.0
|
||||
if consecutive_failures >= 3 or success_rate < 50.0:
|
||||
timeout_val = 3.0
|
||||
ua = fallback_user_agents[idx % len(fallback_user_agents)]
|
||||
else:
|
||||
ua = user_agents[idx % len(user_agents)]
|
||||
|
||||
headers = {"User-Agent": ua, "Referer": "https://www.google.com/"}
|
||||
|
||||
|
||||
domain_info["attempts"] = domain_info.get("attempts", 0) + 1
|
||||
|
||||
# NOTE: All domains must be checked to ensure the link isn't a 404.
|
||||
try:
|
||||
async with httpx.AsyncClient(headers=headers, follow_redirects=True, timeout=12, verify=False) as client:
|
||||
async with httpx.AsyncClient(headers=headers, follow_redirects=True, timeout=timeout_val, verify=False) as client:
|
||||
resp = await client.get(expanded_url)
|
||||
if resp.status_code == 404:
|
||||
asset["health"] = "dead" # Definitively dead
|
||||
domain_info["failures"] = domain_info.get("failures", 0) + 1
|
||||
domain_info["consecutive_failures"] = domain_info.get("consecutive_failures", 0) + 1
|
||||
else:
|
||||
asset["health"] = "online"
|
||||
except:
|
||||
domain_info["consecutive_failures"] = 0
|
||||
except Exception as e:
|
||||
log_event(f"[WARN] health check for {expanded_url}: {str(e)[:100]}")
|
||||
asset["health"] = "timeout" # Assume alive but unreachable for now
|
||||
domain_info["failures"] = domain_info.get("failures", 0) + 1
|
||||
domain_info["consecutive_failures"] = domain_info.get("consecutive_failures", 0) + 1
|
||||
|
||||
# Recalculate success rate and store it
|
||||
attempts = domain_info.get("attempts", 1)
|
||||
failures = domain_info.get("failures", 0)
|
||||
domain_info["success_rate"] = round(((attempts - failures) / attempts) * 100.0, 2)
|
||||
|
||||
# 3. GitHub Metadata Enrichment
|
||||
if "github.com" in expanded_url:
|
||||
@@ -209,7 +264,8 @@ async def master_orchestrator():
|
||||
gh_data = gh_resp.json()
|
||||
asset["gh_stars"] = gh_data.get("stargazers_count")
|
||||
asset["gh_updated"] = gh_data.get("updated_at", "").split("T")[0]
|
||||
except: pass
|
||||
except Exception as e:
|
||||
log_event(f"[WARN] GitHub metadata enrichment for {expanded_url}: {str(e)[:100]}")
|
||||
|
||||
return asset
|
||||
|
||||
@@ -246,7 +302,8 @@ async def master_orchestrator():
|
||||
found = re.findall(r'\]\((https?://[^\)]+)\)', content)
|
||||
for url in found:
|
||||
existing_urls.add(url.split('#')[0].rstrip('/').lower())
|
||||
except: pass
|
||||
except Exception as e:
|
||||
log_event(f"[WARN] read docs/{file} for URL extraction: {str(e)[:100]}")
|
||||
|
||||
log_event(f"[*] Global Deduplication: {len(existing_urls)} existing URLs loaded.")
|
||||
|
||||
@@ -284,12 +341,14 @@ async def master_orchestrator():
|
||||
if isinstance(ts, str):
|
||||
try:
|
||||
asset_date = datetime.strptime(ts, '%a %b %d %H:%M:%S +0000 %Y').replace(tzinfo=MADRID_TZ)
|
||||
except:
|
||||
except Exception as e:
|
||||
try: asset_date = datetime.fromisoformat(ts.replace('Z', '+00:00'))
|
||||
except: pass
|
||||
except Exception as e2:
|
||||
log_event(f"[WARN] parse timestamp '{ts[:30]}': {str(e2)[:100]}")
|
||||
if asset_date and asset_date > max_tweet_date:
|
||||
max_tweet_date = asset_date
|
||||
except: pass
|
||||
except Exception as e:
|
||||
log_event(f"[WARN] process asset timestamp: {str(e)[:100]}")
|
||||
|
||||
assets_to_evaluate.append(asset)
|
||||
|
||||
@@ -416,6 +475,14 @@ async def master_orchestrator():
|
||||
if is_historical and is_chunked and since_date > final_stop_date:
|
||||
print(f"\nNEXT_CHUNK_START: {since_date.isoformat()}")
|
||||
|
||||
# Save domain health history (Recommendation #2)
|
||||
try:
|
||||
with open(health_learning_path, "w") as f:
|
||||
json.dump(health_learning, f, indent=2)
|
||||
log_event("[*] Domain health history updated in health_learning.json")
|
||||
except Exception as e:
|
||||
log_event(f" [!] Failed to save health_learning.json: {e}")
|
||||
|
||||
log_event("PROCESS FINISHED SUCCESSFULLY.", section_break=True)
|
||||
|
||||
if __name__ == "__main__":
|
||||
|
||||
@@ -66,7 +66,9 @@ def get_system_mandates() -> str:
|
||||
if os.path.exists(MANDATES_JSON):
|
||||
try:
|
||||
return json.load(open(MANDATES_JSON, "r")).get("system_snippet", "")
|
||||
except: return ""
|
||||
except Exception as e:
|
||||
log_event(f"[WARN] Failed to load system mandates: {str(e)[:100]}")
|
||||
return ""
|
||||
return ""
|
||||
|
||||
if __name__ == "__main__":
|
||||
|
||||
@@ -0,0 +1,570 @@
|
||||
from __future__ import annotations
|
||||
|
||||
import os
|
||||
import json
|
||||
import hashlib
|
||||
import asyncio
|
||||
from datetime import datetime, timedelta
|
||||
from typing import Dict, List, Any, Tuple
|
||||
|
||||
from src.inventory_manager import load_inventory
|
||||
from src.gemini_utils import call_gemini_with_retry
|
||||
from src.config import MADRID_TZ
|
||||
from src.logger import log_event
|
||||
|
||||
DIGEST_OUTPUT_PATH = "data/news_digest.json"
|
||||
|
||||
# Refresh a cell even when hash matches if last_analyzed is older than this.
|
||||
# Ensures Gemini rankings stay fresh even for stable categories.
|
||||
MAX_STALENESS_DAYS = 30
|
||||
|
||||
|
||||
class NewsDigestEngine:
|
||||
"""Generates a curated news digest by filtering inventory entries by
|
||||
recency and using Gemini AI to rank the most relevant ones per category.
|
||||
|
||||
Three time windows (3 / 6 / 12 months) are produced in a single run.
|
||||
Each window contains up to 10 AI-ranked items per digest category.
|
||||
"""
|
||||
|
||||
# ------------------------------------------------------------------ #
|
||||
# 26 Digest Categories – mapped from V2 category slugs #
|
||||
# ------------------------------------------------------------------ #
|
||||
DIGEST_CATEGORIES: Dict[str, List[str]] = {
|
||||
# --- TECH CORE (9) ---
|
||||
"Kubernetes & Orchestration": [
|
||||
"kubernetes", "kubernetes-tools", "kubernetes-tutorials",
|
||||
"kubectl-commands", "kubernetes-releases", "kubernetes-autoscaling",
|
||||
"kubernetes-operators-controllers", "kubernetes-based-devel",
|
||||
"kubernetes-alternatives", "kubernetes-client-libraries",
|
||||
"kubernetes-bigdata", "managed-kubernetes-in-public-cloud", "helm",
|
||||
],
|
||||
"Containers & Runtime": [
|
||||
"docker", "container-managers", "serverless", "noops", "registries",
|
||||
],
|
||||
"Networking & Service Mesh": [
|
||||
"networking", "kubernetes-networking", "servicemesh", "istio",
|
||||
"caching", "web-servers", "cloudflare",
|
||||
],
|
||||
"Architecture & Microservices": [
|
||||
"introduction", "faq", "cloud-arch-diagrams", "matrix-table",
|
||||
"other-awesome-lists", "about",
|
||||
],
|
||||
"Data, Messaging & Storage": [
|
||||
"databases", "nosql", "newsql", "message-queue", "crunchydata",
|
||||
"yaml", "kubernetes-storage", "kubernetes-backup-migrations",
|
||||
],
|
||||
"AI & Agents": [
|
||||
"ai", "ai-agents-mcp", "chatgpt",
|
||||
],
|
||||
"MLOps & Data Science": [
|
||||
"mlops",
|
||||
],
|
||||
"Python, Java & Developer Ecosystem": [
|
||||
"python", "golang", "java_frameworks", "java_app_servers",
|
||||
"java-and-java-performance-optimization", "javascript", "dotnet",
|
||||
"angular", "react", "web3", "api",
|
||||
"swagger-code-generator-for-rest-apis", "postman",
|
||||
"lowcode-nocode", "devel-sites", "dom", "linux-dev-env",
|
||||
"ChromeDevTools", "xamarin", "jvm-parameters-matrix-table",
|
||||
"maven-gradle", "embedded-servlet-containers", "visual-studio",
|
||||
],
|
||||
"Linux & System Foundations": [
|
||||
"linux", "git",
|
||||
],
|
||||
# --- PLATFORM & OPS (8) ---
|
||||
"Security & Compliance": [
|
||||
"securityascode", "kubernetes-security", "aws-security", "oauth",
|
||||
"devsecops",
|
||||
],
|
||||
"Infrastructure as Code": [
|
||||
"iac", "terraform", "pulumi", "crossplane", "ansible",
|
||||
"kustomize", "chef", "liquibase",
|
||||
],
|
||||
"CI/CD & GitOps": [
|
||||
"cicd", "gitops", "argo", "flux", "tekton", "jenkins",
|
||||
"jenkins-alternatives", "sonarqube", "cicd-kubernetes-plugins",
|
||||
"openshift-pipelines", "stackstorm", "keptn",
|
||||
],
|
||||
"Observability, SRE & Testing": [
|
||||
"sre", "monitoring", "prometheus", "grafana",
|
||||
"kubernetes-monitoring", "chaos-engineering", "qa",
|
||||
"test-automation-frameworks", "testops",
|
||||
"performance-testing-with-jenkins-and-jmeter",
|
||||
"kubernetes-troubleshooting",
|
||||
],
|
||||
"DevOps & Culture": [
|
||||
"devops", "devops-tools", "project-management-methodology",
|
||||
"project-management-tools",
|
||||
],
|
||||
"Platform Engineering & DevEx": [
|
||||
"developerportals", "scaffolding", "mkdocs",
|
||||
],
|
||||
"FinOps & Cloud Cost": [
|
||||
"finops", "aws-pricing",
|
||||
],
|
||||
"Certification & Training": [
|
||||
"elearning", "interview-questions", "aws-training", "cheatsheets",
|
||||
"demos",
|
||||
],
|
||||
# --- CLOUD & ENTERPRISE (5) ---
|
||||
"AWS": [
|
||||
"aws", "aws-architecture", "aws-security", "aws-networking",
|
||||
"aws-databases", "aws-storage", "aws-monitoring", "aws-iac",
|
||||
"aws-tools-scripts", "aws-messaging", "aws-data", "aws-devops",
|
||||
"aws-serverless", "aws-containers", "aws-backup",
|
||||
"aws-newfeatures", "aws-miscellaneous", "aws-spain",
|
||||
],
|
||||
"Azure": [
|
||||
"azure",
|
||||
],
|
||||
"GCP, OCI & Others": [
|
||||
"GoogleCloudPlatform", "ibm_cloud", "oraclecloud",
|
||||
"digitalocean", "scaleway", "edge-computing",
|
||||
"public-cloud-solutions",
|
||||
],
|
||||
"OpenShift / Red Hat": [
|
||||
"openshift", "ocp3", "ocp4", "openshift-pipelines", "rancher",
|
||||
],
|
||||
"Virtualization & Private Cloud": [
|
||||
"kubernetes-on-premise", "kubernetes-alternatives",
|
||||
"private-cloud-solutions",
|
||||
],
|
||||
# --- INDUSTRY / GEO (4) – resolved via geo_region, not slugs ---
|
||||
"Americas": [],
|
||||
"Europe": [],
|
||||
"Spain": [],
|
||||
"Asia-Pacific": [],
|
||||
}
|
||||
|
||||
GEO_CATEGORIES: Dict[str, str] = {
|
||||
"Americas": "americas",
|
||||
"Europe": "europe",
|
||||
"Spain": "spain",
|
||||
"Asia-Pacific": "asia_pacific",
|
||||
}
|
||||
|
||||
PERIODS: Dict[str, int] = {
|
||||
"3_months": 90,
|
||||
"6_months": 180,
|
||||
"12_months": 365,
|
||||
}
|
||||
|
||||
ITEMS_PER_PERIOD: Dict[str, int] = {
|
||||
"3_months": 10,
|
||||
"6_months": 15,
|
||||
"12_months": 20,
|
||||
}
|
||||
|
||||
# ------------------------------------------------------------------ #
|
||||
|
||||
def __init__(self) -> None:
|
||||
self.inventory: Dict[str, Any] = load_inventory()
|
||||
|
||||
# Reverse map: v2_category_slug -> digest_category_name
|
||||
self.category_map: Dict[str, str] = {}
|
||||
for digest_cat, slugs in self.DIGEST_CATEGORIES.items():
|
||||
for slug in slugs:
|
||||
self.category_map[slug] = digest_cat
|
||||
|
||||
# ------------------------------------------------------------------ #
|
||||
# Classification helpers #
|
||||
# ------------------------------------------------------------------ #
|
||||
|
||||
def _get_entry_category(self, entry: dict) -> str | None:
|
||||
"""Determine which digest category an entry belongs to.
|
||||
|
||||
Checks ``v2_locations`` paths first (more specific), then falls
|
||||
back to the ``category`` field.
|
||||
"""
|
||||
for loc in entry.get("v2_locations", []):
|
||||
slug = loc.replace(".md", "")
|
||||
if slug in self.category_map:
|
||||
return self.category_map[slug]
|
||||
cat = entry.get("category", "")
|
||||
if cat in self.category_map:
|
||||
return self.category_map[cat]
|
||||
return None
|
||||
|
||||
def _get_entry_geo(self, entry: dict, url: str = "") -> str | None:
|
||||
"""Return the geo digest category using geo_region field, falling back to URL TLD inference."""
|
||||
region = entry.get("geo_region", "")
|
||||
for geo_name, geo_val in self.GEO_CATEGORIES.items():
|
||||
if region == geo_val:
|
||||
return geo_name
|
||||
# Fallback: infer from URL TLD (entry.get("url") populated only after url injection)
|
||||
return self._infer_geo_from_url(entry.get("url", "") or url)
|
||||
|
||||
@staticmethod
|
||||
def _infer_geo_from_url(url: str) -> str | None:
|
||||
"""Infer geo category from URL TLD. Returns GEO_CATEGORIES key or None."""
|
||||
try:
|
||||
from urllib.parse import urlparse
|
||||
host = urlparse(url).hostname or ""
|
||||
# Ordered longest-first to avoid .uk matching before .co.uk
|
||||
tld_to_region = [
|
||||
(".com.au", "Asia-Pacific"), (".co.uk", "Europe"), (".co.jp", "Asia-Pacific"),
|
||||
(".co.kr", "Asia-Pacific"), (".com.br", "Americas"), (".com.mx", "Americas"),
|
||||
(".es", "Spain"), (".de", "Europe"), (".fr", "Europe"), (".it", "Europe"),
|
||||
(".pt", "Europe"), (".nl", "Europe"), (".be", "Europe"), (".se", "Europe"),
|
||||
(".dk", "Europe"), (".fi", "Europe"), (".no", "Europe"), (".ch", "Europe"),
|
||||
(".at", "Europe"), (".pl", "Europe"), (".cz", "Europe"), (".uk", "Europe"),
|
||||
(".ie", "Europe"), (".eu", "Europe"), (".cn", "Asia-Pacific"),
|
||||
(".jp", "Asia-Pacific"), (".kr", "Asia-Pacific"), (".sg", "Asia-Pacific"),
|
||||
(".in", "Asia-Pacific"), (".au", "Asia-Pacific"), (".nz", "Asia-Pacific"),
|
||||
(".ca", "Americas"), (".mx", "Americas"), (".br", "Americas"),
|
||||
]
|
||||
for tld, region in tld_to_region:
|
||||
if host.endswith(tld):
|
||||
return region
|
||||
except Exception:
|
||||
pass
|
||||
return None
|
||||
|
||||
@staticmethod
|
||||
def _is_within_period(entry: dict, cutoff_iso: str) -> bool:
|
||||
"""Check if entry falls within the time period using discovered_at,
|
||||
with year field as fallback for backfilled entries."""
|
||||
discovered = entry.get("discovered_at", "")
|
||||
if discovered:
|
||||
try:
|
||||
if discovered >= cutoff_iso:
|
||||
return True
|
||||
except Exception:
|
||||
pass
|
||||
year = entry.get("year", "")
|
||||
if year and isinstance(year, str) and year.isdigit():
|
||||
cutoff_year = cutoff_iso[:4] if len(cutoff_iso) >= 4 else "2020"
|
||||
return year >= cutoff_year
|
||||
return False
|
||||
|
||||
# ------------------------------------------------------------------ #
|
||||
# Prompt builder #
|
||||
# ------------------------------------------------------------------ #
|
||||
|
||||
@staticmethod
|
||||
def _build_ranking_prompt(
|
||||
category: str, entries: List[dict], period: str
|
||||
) -> str:
|
||||
"""Assemble the Gemini prompt that asks for a ranked TOP-10."""
|
||||
period_label = period.replace("_", " ")
|
||||
lines: List[str] = []
|
||||
for i, e in enumerate(entries[:50]):
|
||||
summary_fragment = (e.get("ai_summary", "") or "")[:200]
|
||||
lines.append(
|
||||
f'{i}. "{e.get("title", "Unknown")}" '
|
||||
f'({e.get("url", "")}) | '
|
||||
f'Stars: {e.get("stars", 0)} | '
|
||||
f'Year: {e.get("year", "N/A")} | '
|
||||
f'Summary: {summary_fragment}'
|
||||
)
|
||||
entries_text = "\n".join(lines)
|
||||
|
||||
return (
|
||||
"You are a Senior Technical Curator for a Cloud Native "
|
||||
"knowledge portal.\n"
|
||||
f'Given these resources discovered in the last {period_label} '
|
||||
f'for "{category}", select the TOP 10 most relevant.\n\n'
|
||||
"SCORING CRITERIA:\n"
|
||||
"- Industry Impact (30%): Does this change how teams "
|
||||
"build/operate?\n"
|
||||
"- Technical Novelty (25%): New capability, paradigm shift, "
|
||||
"major release?\n"
|
||||
"- Enterprise Adoption (20%): GA releases, production-ready?\n"
|
||||
"- Community Signal (15%): CNCF graduations, major blog posts?\n"
|
||||
"- Nubenetes Relevance (10%): Directly related to cloud native?\n\n"
|
||||
'Respond ONLY JSON: {"items": [{"idx": int, '
|
||||
'"impact": "critical|high|medium", '
|
||||
'"why": "1 sentence explaining why this matters"}]}\n\n'
|
||||
f"RESOURCES:\n{entries_text}"
|
||||
)
|
||||
|
||||
# ------------------------------------------------------------------ #
|
||||
# Star-based fallback (used when Gemini is unavailable / < 3 entries) #
|
||||
# ------------------------------------------------------------------ #
|
||||
|
||||
@staticmethod
|
||||
def _fallback_items(
|
||||
entries: List[dict], cat_name: str, limit: int = 10
|
||||
) -> List[dict]:
|
||||
"""Return up to *limit* items using a deterministic star-based
|
||||
ranking (no AI call required)."""
|
||||
return [
|
||||
{
|
||||
"url": e["url"],
|
||||
"title": e.get("title", "Unknown"),
|
||||
"date": e.get("discovered_at", "")[:10],
|
||||
"stars": e.get("stars") or 0,
|
||||
"impact": "high" if (e.get("stars") or 0) >= 4 else "medium",
|
||||
"why": (e.get("ai_summary", "") or "")[:200],
|
||||
"category": cat_name,
|
||||
}
|
||||
for e in entries[:limit]
|
||||
]
|
||||
|
||||
# ------------------------------------------------------------------ #
|
||||
# Incremental cache helpers #
|
||||
# ------------------------------------------------------------------ #
|
||||
|
||||
@staticmethod
|
||||
def _compute_pool_hash(entries: List[dict]) -> str:
|
||||
"""Stable fingerprint of a category entry pool.
|
||||
|
||||
Uses sorted URLs so the hash only changes when the actual set of
|
||||
entries changes — not when their order or metadata is updated.
|
||||
Returns first 16 hex chars (64-bit fingerprint, collision-safe).
|
||||
"""
|
||||
sorted_urls = sorted(e["url"] for e in entries if e.get("url"))
|
||||
return hashlib.sha256("|".join(sorted_urls).encode()).hexdigest()[:16]
|
||||
|
||||
def _load_existing_digest(self) -> Tuple[dict, dict]:
|
||||
"""Load existing digest + meta block from disk.
|
||||
|
||||
Returns ``(periods_dict, meta_dict)``. Both are empty dicts if the
|
||||
file does not exist or cannot be parsed. The ``_meta`` key is
|
||||
stripped from *periods_dict* so callers only see period data.
|
||||
"""
|
||||
if not os.path.exists(DIGEST_OUTPUT_PATH):
|
||||
return {}, {}
|
||||
try:
|
||||
with open(DIGEST_OUTPUT_PATH, encoding="utf-8") as f:
|
||||
raw = json.load(f)
|
||||
meta = raw.pop("_meta", {})
|
||||
return raw, meta
|
||||
except Exception as e:
|
||||
log_event(
|
||||
f"[Digest WARN] Could not load existing digest: {str(e)[:100]}"
|
||||
)
|
||||
return {}, {}
|
||||
|
||||
def _is_cache_valid(
|
||||
self, period: str, cat: str, pool_hash: str, meta: dict
|
||||
) -> bool:
|
||||
"""Return True when the stored result can be reused without Gemini.
|
||||
|
||||
Conditions (both must hold):
|
||||
1. Entry-pool hash matches (same URLs, same period).
|
||||
2. Result was analysed no more than MAX_STALENESS_DAYS ago.
|
||||
"""
|
||||
cell = meta.get(period, {}).get(cat)
|
||||
if not cell:
|
||||
return False
|
||||
if cell.get("entry_hash") != pool_hash:
|
||||
return False
|
||||
last = cell.get("last_analyzed", "")
|
||||
if not last:
|
||||
return False
|
||||
try:
|
||||
age = (
|
||||
datetime.now(MADRID_TZ) - datetime.fromisoformat(last)
|
||||
).days
|
||||
return age <= MAX_STALENESS_DAYS
|
||||
except Exception:
|
||||
return False
|
||||
|
||||
# ------------------------------------------------------------------ #
|
||||
# Core generation loop #
|
||||
# ------------------------------------------------------------------ #
|
||||
|
||||
async def generate_digest(self) -> dict:
|
||||
"""Incrementally generate the digest for all categories / periods.
|
||||
|
||||
For each (category, period) cell the engine checks whether the
|
||||
inventory pool hash has changed since the last run. If the hash
|
||||
is identical *and* the result is not stale, the existing ranked
|
||||
list is reused with zero Gemini API calls. Gemini is only invoked
|
||||
for cells whose entry pool has actually changed or exceeded
|
||||
MAX_STALENESS_DAYS.
|
||||
|
||||
Returns a nested dict::
|
||||
|
||||
{
|
||||
"3_months": { "Kubernetes & Orchestration": [...], ... },
|
||||
"6_months": { ... },
|
||||
"12_months": { ... },
|
||||
"_meta": { ... } ← persistence metadata, internal use
|
||||
}
|
||||
"""
|
||||
existing, old_meta = self._load_existing_digest()
|
||||
new_meta: Dict[str, Dict[str, dict]] = {}
|
||||
digest: Dict[str, Dict[str, List[dict]]] = {}
|
||||
|
||||
n_cached = n_refreshed = n_fallback = 0
|
||||
|
||||
for period_name, days in self.PERIODS.items():
|
||||
cutoff = (
|
||||
datetime.now(MADRID_TZ) - timedelta(days=days)
|
||||
).isoformat()
|
||||
digest[period_name] = {}
|
||||
new_meta[period_name] = {}
|
||||
|
||||
# Build per-category entry pools for this period
|
||||
category_pools: Dict[str, List[dict]] = {}
|
||||
for url, entry in self.inventory.items():
|
||||
if not isinstance(entry, dict):
|
||||
continue
|
||||
if not self._is_within_period(entry, cutoff):
|
||||
continue
|
||||
cat = self._get_entry_category(entry)
|
||||
if cat:
|
||||
category_pools.setdefault(cat, []).append(
|
||||
dict(entry, url=url)
|
||||
)
|
||||
geo = self._get_entry_geo(entry, url=url)
|
||||
if geo:
|
||||
category_pools.setdefault(geo, []).append(
|
||||
dict(entry, url=url)
|
||||
)
|
||||
|
||||
for cat_name, entries in category_pools.items():
|
||||
entries.sort(
|
||||
key=lambda x: (
|
||||
x.get("stars") or 0,
|
||||
x.get("discovered_at") or "",
|
||||
),
|
||||
reverse=True,
|
||||
)
|
||||
max_items = self.ITEMS_PER_PERIOD.get(period_name, 10)
|
||||
pool_hash = self._compute_pool_hash(entries)
|
||||
|
||||
# ── Cache hit: reuse without calling Gemini ──
|
||||
if self._is_cache_valid(period_name, cat_name, pool_hash, old_meta):
|
||||
cached_items = existing.get(period_name, {}).get(cat_name, [])
|
||||
if cached_items:
|
||||
digest[period_name][cat_name] = cached_items
|
||||
new_meta[period_name][cat_name] = (
|
||||
old_meta[period_name][cat_name]
|
||||
)
|
||||
n_cached += 1
|
||||
continue
|
||||
|
||||
# ── Fewer than 3 entries: star-based fallback (no AI) ──
|
||||
if len(entries) < 3:
|
||||
digest[period_name][cat_name] = self._fallback_items(
|
||||
entries, cat_name, limit=max_items
|
||||
)
|
||||
new_meta[period_name][cat_name] = {
|
||||
"last_analyzed": datetime.now(MADRID_TZ).isoformat(),
|
||||
"entry_hash": pool_hash,
|
||||
"entry_count": len(entries),
|
||||
"method": "fallback_small",
|
||||
}
|
||||
n_fallback += 1
|
||||
continue
|
||||
|
||||
# ── Gemini ranking ──
|
||||
try:
|
||||
prompt = self._build_ranking_prompt(
|
||||
cat_name, entries, period_name
|
||||
)
|
||||
result = await call_gemini_with_retry(
|
||||
prompt, prefer_flash=True, role="Digest-Analyst"
|
||||
)
|
||||
ranked: List[dict] = []
|
||||
for item in result.get("items", []):
|
||||
idx = int(item.get("idx", -1))
|
||||
if 0 <= idx < len(entries):
|
||||
e = entries[idx]
|
||||
ranked.append(
|
||||
{
|
||||
"url": e["url"],
|
||||
"title": e.get("title", "Unknown"),
|
||||
"date": e.get("discovered_at", "")[:10],
|
||||
"stars": e.get("stars", 0),
|
||||
"impact": item.get("impact", "medium"),
|
||||
"why": item.get("why", ""),
|
||||
"category": cat_name,
|
||||
}
|
||||
)
|
||||
digest[period_name][cat_name] = ranked[:max_items]
|
||||
new_meta[period_name][cat_name] = {
|
||||
"last_analyzed": datetime.now(MADRID_TZ).isoformat(),
|
||||
"entry_hash": pool_hash,
|
||||
"entry_count": len(entries),
|
||||
"method": "gemini",
|
||||
}
|
||||
n_refreshed += 1
|
||||
log_event(
|
||||
f" [Digest] {period_name}/{cat_name}: "
|
||||
f"{len(ranked)} items ranked (Gemini)"
|
||||
)
|
||||
except Exception as exc:
|
||||
log_event(
|
||||
f" [Digest WARN] {period_name}/{cat_name}: "
|
||||
f"Gemini failed ({str(exc)[:80]}), using fallback"
|
||||
)
|
||||
digest[period_name][cat_name] = self._fallback_items(
|
||||
entries, cat_name, limit=max_items
|
||||
)
|
||||
new_meta[period_name][cat_name] = {
|
||||
"last_analyzed": datetime.now(MADRID_TZ).isoformat(),
|
||||
"entry_hash": pool_hash,
|
||||
"entry_count": len(entries),
|
||||
"method": "fallback_error",
|
||||
}
|
||||
n_fallback += 1
|
||||
|
||||
await asyncio.sleep(1.0)
|
||||
|
||||
log_event(
|
||||
f"[Digest] {n_cached} cells reused (0 API calls), "
|
||||
f"{n_refreshed} refreshed via Gemini, "
|
||||
f"{n_fallback} fallback"
|
||||
)
|
||||
new_meta["last_updated"] = datetime.now(MADRID_TZ).isoformat()
|
||||
digest["_meta"] = new_meta
|
||||
return digest
|
||||
|
||||
# ------------------------------------------------------------------ #
|
||||
# Persistence #
|
||||
# ------------------------------------------------------------------ #
|
||||
|
||||
@staticmethod
|
||||
def save_digest(digest: dict) -> None:
|
||||
"""Serialise digest (including ``_meta``) to ``data/news_digest.json``."""
|
||||
os.makedirs(os.path.dirname(DIGEST_OUTPUT_PATH), exist_ok=True)
|
||||
with open(DIGEST_OUTPUT_PATH, "w", encoding="utf-8") as fh:
|
||||
json.dump(digest, fh, indent=2, ensure_ascii=False)
|
||||
# Count only period keys for the total-items stat
|
||||
total_items = sum(
|
||||
len(items)
|
||||
for key, period in digest.items()
|
||||
if key != "_meta" and isinstance(period, dict)
|
||||
for items in period.values()
|
||||
if isinstance(items, list)
|
||||
)
|
||||
gemini_cells = sum(
|
||||
1
|
||||
for period_meta in digest.get("_meta", {}).values()
|
||||
if isinstance(period_meta, dict)
|
||||
for cell in period_meta.values()
|
||||
if isinstance(cell, dict) and cell.get("method") == "gemini"
|
||||
)
|
||||
log_event(
|
||||
f"[Digest] Saved to {DIGEST_OUTPUT_PATH} — "
|
||||
f"{total_items} items, {gemini_cells} Gemini calls this run"
|
||||
)
|
||||
|
||||
|
||||
# ====================================================================== #
|
||||
# CLI / CI entry point #
|
||||
# ====================================================================== #
|
||||
|
||||
|
||||
async def run_news_digest() -> None:
|
||||
"""Entry point for the CI pipeline."""
|
||||
log_event("STARTING NEWS DIGEST GENERATION", section_break=True)
|
||||
engine = NewsDigestEngine()
|
||||
digest = await engine.generate_digest()
|
||||
engine.save_digest(digest)
|
||||
|
||||
total_items = sum(
|
||||
len(items) for period in digest.values() for items in period.values()
|
||||
)
|
||||
log_event(
|
||||
f"NEWS DIGEST COMPLETE: {total_items} total items across all periods"
|
||||
)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
asyncio.run(run_news_digest())
|
||||
@@ -47,7 +47,8 @@ def auto_format_file(filepath: str):
|
||||
try:
|
||||
cleaned = normalize_url(url)
|
||||
return f"[{text}]({cleaned})"
|
||||
except:
|
||||
except Exception as e:
|
||||
print(f"[WARN] URL normalization failed for '{url[:60]}': {str(e)[:100]}")
|
||||
return match.group(0)
|
||||
return match.group(0)
|
||||
|
||||
@@ -94,7 +95,13 @@ def main():
|
||||
files = pr.get_files()
|
||||
modified_files = [f.filename for f in files if f.status in ["modified", "added"]]
|
||||
for filepath in modified_files:
|
||||
if filepath.endswith(".md"):
|
||||
# The v2-docs/ tree is generated by src/v2_optimizer.py, which is its
|
||||
# single source of truth for formatting. Auto-formatting it here
|
||||
# ("&"->"and" in headings, URL trailing-slash stripping) only fights
|
||||
# the generator: the rewrite lands on develop via the PR while master
|
||||
# gets the generator's raw form via release merges, producing a
|
||||
# perpetual cosmetic develop<->master drift. Skip the generated tree.
|
||||
if filepath.endswith(".md") and not filepath.startswith("v2-docs/"):
|
||||
auto_format_file(filepath)
|
||||
except Exception as e:
|
||||
print(f"Warning: Failed to fetch files for auto-formatting: {e}")
|
||||
|
||||
@@ -0,0 +1,107 @@
|
||||
#!/usr/bin/env python3
|
||||
import os
|
||||
import re
|
||||
import sys
|
||||
|
||||
def check_file(file_path):
|
||||
errors = []
|
||||
warnings = []
|
||||
|
||||
with open(file_path, "r", encoding="utf-8") as f:
|
||||
content = f.read()
|
||||
lines = content.splitlines()
|
||||
|
||||
seen_urls = set()
|
||||
|
||||
for line_num, line in enumerate(lines, 1):
|
||||
# 1. Check section titles (H2-H6) for Emojis, Special Characters, and Ampersands (Mandate 32)
|
||||
if line.startswith("#"):
|
||||
header_level = len(line) - len(line.lstrip('#'))
|
||||
if 2 <= header_level <= 6:
|
||||
title_text = line.lstrip('#').strip()
|
||||
# Check for ampersand
|
||||
if "&" in title_text:
|
||||
errors.append(f"Line {line_num}: Title contains ampersand '&': '{title_text}' (replace with 'and')")
|
||||
|
||||
# Check for emojis or special characters
|
||||
for char in title_text:
|
||||
# Allow alphanumeric, spaces, hyphens, colons, parentheses, commas, periods, quotes
|
||||
if ord(char) > 0x2000 and ord(char) not in (0x2013, 0x2014, 0x2018, 0x2019, 0x201c, 0x201d):
|
||||
errors.append(f"Line {line_num}: Title contains emojis or special characters: '{char}' in '{title_text}'")
|
||||
|
||||
# 2. Check for Markdown link rules (Mandate 33)
|
||||
# Match [ Link ](URL) - space at start or end of brackets
|
||||
if re.search(r'\[\s+[^\]]*\]\(', line) or re.search(r'\[[^\]]*\s+\]\(', line):
|
||||
errors.append(f"Line {line_num}: Link text contains leading or trailing spaces inside brackets: '{line.strip()}'")
|
||||
|
||||
# 3. Extract and validate URLs
|
||||
links = re.findall(r'\[([^\]]+)\]\(([^)]+)\)', line)
|
||||
for link_text, url in links:
|
||||
url = url.strip()
|
||||
if url.startswith("http://") or url.startswith("https://"):
|
||||
if url.startswith("https:/") and not url.startswith("https://"):
|
||||
errors.append(f"Line {line_num}: Corrupted protocol prefix: '{url}'")
|
||||
elif url.startswith("http:/") and not url.startswith("http://"):
|
||||
errors.append(f"Line {line_num}: Corrupted protocol prefix: '{url}'")
|
||||
|
||||
# Check for duplicates in this category file
|
||||
if os.path.basename(file_path) not in ["index.md", "about.md"]:
|
||||
# Normalize URL to check duplicate
|
||||
clean_url = url.split("?")[0].split("#")[0].lower().rstrip('/')
|
||||
if clean_url in seen_urls:
|
||||
# Report as warning rather than blocking error
|
||||
warnings.append(f"Line {line_num}: Duplicate URL found in this file: '{url}'")
|
||||
else:
|
||||
seen_urls.add(clean_url)
|
||||
|
||||
# Check year tag if present
|
||||
match_year = re.search(r'\*\*\(([0-9]{4})\)\*\*', line)
|
||||
if match_year:
|
||||
year = int(match_year.group(1))
|
||||
if not (1990 <= year <= 2030):
|
||||
errors.append(f"Line {line_num}: Year tag '{year}' is outside reasonable bounds: '{line.strip()}'")
|
||||
|
||||
# Global multi-line check for link text line breaks
|
||||
if re.search(r'\[[^\]]*\n[^\]]*\]\(', content):
|
||||
errors.append("Global: Found a link with a line break inside the link text brackets.")
|
||||
|
||||
return errors, warnings
|
||||
|
||||
def main():
|
||||
docs_dir = "docs"
|
||||
if not os.path.exists(docs_dir):
|
||||
print(f"Directory {docs_dir} not found.")
|
||||
sys.exit(0)
|
||||
|
||||
total_errors = 0
|
||||
total_warnings = 0
|
||||
|
||||
for root, dirs, files in os.walk(docs_dir):
|
||||
if "images" in root or "static" in root:
|
||||
continue
|
||||
for file in files:
|
||||
if file.endswith(".md"):
|
||||
path = os.path.join(root, file)
|
||||
errors, warnings = check_file(path)
|
||||
if errors:
|
||||
print(f"❌ {path}:")
|
||||
for err in errors:
|
||||
print(f" {err}")
|
||||
total_errors += len(errors)
|
||||
if warnings:
|
||||
# By default do not flood output with duplicate warnings unless verbose
|
||||
if "--verbose" in sys.argv:
|
||||
print(f"⚠️ {path}:")
|
||||
for warn in warnings:
|
||||
print(f" {warn}")
|
||||
total_warnings += len(warnings)
|
||||
|
||||
print(f"\nScan complete: Found {total_errors} errors and {total_warnings} warnings in markdown files.")
|
||||
if total_errors > 0:
|
||||
sys.exit(1)
|
||||
else:
|
||||
print("All Markdown files passed the schema check successfully!")
|
||||
sys.exit(0)
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
@@ -12,7 +12,9 @@ V2_DIR = "v2-docs"
|
||||
def run_command(cmd):
|
||||
try:
|
||||
return subprocess.check_output(cmd, shell=True).decode('utf-8').strip()
|
||||
except: return "0"
|
||||
except Exception as e:
|
||||
print(f"[WARN] Command '{cmd[:60]}' failed: {str(e)[:100]}")
|
||||
return "0"
|
||||
|
||||
def clean_text(text: str) -> str:
|
||||
"""Strips emojis and ampersands for README compatibility."""
|
||||
@@ -26,7 +28,8 @@ def get_stats():
|
||||
inventory = {}
|
||||
try:
|
||||
inventory = load_inventory()
|
||||
except: pass
|
||||
except Exception as e:
|
||||
print(f"[WARN] Failed to load inventory: {str(e)[:100]}")
|
||||
|
||||
# 2. Basic Metrics
|
||||
total_links = len([u for u in inventory.keys() if not u.startswith("INTRO:")])
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
import yaml
|
||||
import os
|
||||
from src.inventory_manager import load_inventory
|
||||
|
||||
# Map category IDs to their friendly names and outline border colors (V2 only)
|
||||
CATEGORIES = {
|
||||
@@ -13,23 +14,28 @@ CATEGORIES = {
|
||||
}
|
||||
|
||||
def load_inventory_channels():
|
||||
repo_root = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
|
||||
inventory_path = os.path.join(repo_root, 'data', 'inventory.yaml')
|
||||
with open(inventory_path, 'r', encoding='utf-8') as f:
|
||||
inventory = yaml.safe_load(f) or {}
|
||||
inventory = load_inventory()
|
||||
|
||||
channels = []
|
||||
for url, entry in inventory.items():
|
||||
if isinstance(entry, dict) and 'youtube_mosaic' in entry:
|
||||
metadata = entry['youtube_mosaic']
|
||||
channels.append({
|
||||
'title': entry.get('title', 'Unknown Channel'),
|
||||
'url': url,
|
||||
'image': metadata.get('image', ''),
|
||||
'category': metadata.get('category', 'learning_influencers_communities'),
|
||||
'order_v1': metadata.get('order_v1', 9999),
|
||||
'order_v2': metadata.get('order_v2', 9999)
|
||||
})
|
||||
if not isinstance(entry, dict):
|
||||
continue
|
||||
metadata = entry.get('youtube_mosaic')
|
||||
# Every inventory entry carries a 'youtube_mosaic' column that the SQL
|
||||
# round-trip materializes as an empty dict {}, so a bare key-presence
|
||||
# check matches the entire inventory and explodes the mosaic to ~18k
|
||||
# logos. Only treat an entry as a mosaic channel when it actually has
|
||||
# mosaic metadata with a logo image.
|
||||
if not isinstance(metadata, dict) or not metadata.get('image'):
|
||||
continue
|
||||
channels.append({
|
||||
'title': entry.get('title', 'Unknown Channel'),
|
||||
'url': url,
|
||||
'image': metadata.get('image', ''),
|
||||
'category': metadata.get('category', 'learning_influencers_communities'),
|
||||
'order_v1': metadata.get('order_v1', 9999),
|
||||
'order_v2': metadata.get('order_v2', 9999)
|
||||
})
|
||||
return channels
|
||||
|
||||
def build_v2_mosaic_markdown_from_channels(channels):
|
||||
@@ -54,13 +60,17 @@ def build_v2_mosaic_markdown_from_channels(channels):
|
||||
cat_chans.sort(key=lambda x: x['order_v2'])
|
||||
|
||||
# Open category block container
|
||||
lines.append(f'<div markdown="1" style="border: 1px solid {cat_info["color"]}; border-radius: 8px; padding: 10px; margin: 8px 0; background: rgba(255, 255, 255, 0.01);" title="{cat_info["name"]}">')
|
||||
lines.append(f'<div markdown="1" class="mosaic-cat-block" style="border: 1px solid {cat_info["color"]}; border-radius: 8px; padding: 10px; margin: 8px 0; background: rgba(255, 255, 255, 0.01);" title="{cat_info["name"]}">')
|
||||
lines.append('') # Mandatory blank line after block tag
|
||||
|
||||
# Channel links
|
||||
|
||||
# Visible category label (previously only exposed via the hidden title= tooltip)
|
||||
lines.append(f'<p class="mosaic-cat-label" style="--cat-color: {cat_info["color"]}">{cat_info["name"]}</p>')
|
||||
lines.append('')
|
||||
|
||||
# Channel links (loading="lazy" — ~150 logos, almost all below the fold)
|
||||
chan_links = []
|
||||
for chan in cat_chans:
|
||||
chan_links.append(f"[![{chan['title']}]({chan['image']}){{: style=\"width:48px; height:48px; object-fit:contain; margin:6px;\" .channel-logo}}]({chan['url']})")
|
||||
chan_links.append(f"[![{chan['title']}]({chan['image']}){{: style=\"width:48px; height:48px; object-fit:contain; margin:6px;\" loading=\"lazy\" .channel-logo}}]({chan['url']})")
|
||||
|
||||
lines.append(" ".join(chan_links))
|
||||
lines.append('')
|
||||
|
||||
@@ -0,0 +1,132 @@
|
||||
"""RSS 2.0 feed generator for the Nubenetes Intelligence Digest.
|
||||
|
||||
Reads data/news_digest.json and writes v2-docs/feed.xml with the top
|
||||
items from the 3-month digest window across all tech categories.
|
||||
"""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
import json
|
||||
import os
|
||||
from datetime import datetime
|
||||
from email.utils import format_datetime
|
||||
from xml.sax.saxutils import escape
|
||||
|
||||
from src.logger import log_event
|
||||
|
||||
DIGEST_PATH = "data/news_digest.json"
|
||||
OUTPUT_PATH = "v2-docs/feed.xml"
|
||||
FEED_TITLE = "Nubenetes Intelligence Digest"
|
||||
FEED_LINK = "https://nubenetes.com/"
|
||||
FEED_DESCRIPTION = "AI-curated top picks from the Cloud Native & Kubernetes ecosystem"
|
||||
FEED_LANGUAGE = "en"
|
||||
ITEMS_PER_FEED = 20
|
||||
|
||||
TECH_CATS = [
|
||||
"Kubernetes & Orchestration", "AI & Agents", "Security & Compliance",
|
||||
"CI/CD & GitOps", "Observability, SRE & Testing", "Infrastructure as Code",
|
||||
"Containers & Runtime", "Networking & Service Mesh", "Cloud Providers & FinOps",
|
||||
"MLOps & Data Science", "Data, Messaging & Storage",
|
||||
]
|
||||
|
||||
|
||||
def _rfc822(dt: datetime) -> str:
|
||||
return format_datetime(dt)
|
||||
|
||||
|
||||
def generate_rss() -> None:
|
||||
if not os.path.exists(DIGEST_PATH):
|
||||
log_event("[WARN] rss_generator: news_digest.json not found, skipping RSS generation")
|
||||
return
|
||||
|
||||
try:
|
||||
with open(DIGEST_PATH, "r", encoding="utf-8") as f:
|
||||
digest = json.load(f)
|
||||
except Exception as e:
|
||||
log_event(f"[WARN] rss_generator: failed to load digest: {str(e)[:100]}")
|
||||
return
|
||||
|
||||
period_data = digest.get("3_months", {})
|
||||
items: list[dict] = []
|
||||
|
||||
for cat in TECH_CATS:
|
||||
for entry in period_data.get(cat, []):
|
||||
items.append({**entry, "_cat": cat})
|
||||
|
||||
# Sort by impact then date
|
||||
impact_rank = {"critical": 3, "high": 2, "medium": 1}
|
||||
items.sort(
|
||||
key=lambda x: (impact_rank.get(x.get("impact", "medium"), 0), x.get("date", "")),
|
||||
reverse=True,
|
||||
)
|
||||
items = items[:ITEMS_PER_FEED]
|
||||
|
||||
# Deterministic build date = the freshest item's content date, so the feed
|
||||
# is a pure function of its items. (This used wall-clock now() — rewritten on
|
||||
# every republish — then _meta.last_updated, but that analysis timestamp is
|
||||
# itself bumped on each publish even when the ranked content is unchanged, so
|
||||
# the feed still drifted between develop and master. The item dates only move
|
||||
# when the content actually changes.) Falls back to _meta.last_updated, then
|
||||
# a fixed constant, only when no item carries a parseable date.
|
||||
item_dates = []
|
||||
for _it in items:
|
||||
try:
|
||||
item_dates.append(datetime.strptime(_it.get("date", ""), "%Y-%m-%d"))
|
||||
except Exception:
|
||||
pass
|
||||
if item_dates:
|
||||
build_dt = max(item_dates)
|
||||
else:
|
||||
meta_updated = digest.get("_meta", {}).get("last_updated", "")
|
||||
try:
|
||||
build_dt = datetime.fromisoformat(meta_updated) if meta_updated else datetime(2026, 1, 1)
|
||||
except Exception:
|
||||
build_dt = datetime(2026, 1, 1)
|
||||
build_date = _rfc822(build_dt)
|
||||
|
||||
lines = [
|
||||
'<?xml version="1.0" encoding="UTF-8"?>',
|
||||
'<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">',
|
||||
" <channel>",
|
||||
f" <title>{escape(FEED_TITLE)}</title>",
|
||||
f" <link>{FEED_LINK}</link>",
|
||||
f" <description>{escape(FEED_DESCRIPTION)}</description>",
|
||||
f" <language>{FEED_LANGUAGE}</language>",
|
||||
f" <lastBuildDate>{build_date}</lastBuildDate>",
|
||||
f' <atom:link href="{FEED_LINK}feed.xml" rel="self" type="application/rss+xml"/>',
|
||||
]
|
||||
|
||||
for item in items:
|
||||
title = escape(item.get("title", "Unknown"))
|
||||
url = item.get("url", "#")
|
||||
why = escape(item.get("why", ""))
|
||||
cat = escape(item.get("_cat", ""))
|
||||
impact = item.get("impact", "medium")
|
||||
date_str = item.get("date", "")
|
||||
try:
|
||||
pub_date = _rfc822(datetime.strptime(date_str, "%Y-%m-%d")) if date_str else build_date
|
||||
except Exception:
|
||||
pub_date = build_date
|
||||
|
||||
lines += [
|
||||
" <item>",
|
||||
f" <title>{title}</title>",
|
||||
f" <link>{url}</link>",
|
||||
f" <guid isPermaLink=\"true\">{url}</guid>",
|
||||
f" <pubDate>{pub_date}</pubDate>",
|
||||
f" <category>{cat}</category>",
|
||||
f" <description>[{impact.upper()}] {why}</description>",
|
||||
" </item>",
|
||||
]
|
||||
|
||||
lines += [" </channel>", "</rss>"]
|
||||
|
||||
os.makedirs(os.path.dirname(OUTPUT_PATH), exist_ok=True)
|
||||
with open(OUTPUT_PATH, "w", encoding="utf-8") as f:
|
||||
f.write("\n".join(lines) + "\n")
|
||||
|
||||
log_event(f"[INFO] rss_generator: wrote {len(items)} items to {OUTPUT_PATH}")
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
generate_rss()
|
||||
@@ -6,6 +6,12 @@ from datetime import datetime
|
||||
from src.logger import log_event
|
||||
from src.gemini_utils import normalize_url, clean_toc_text
|
||||
from src.config import INVENTORY_PATH
|
||||
from src.inventory_manager import load_inventory
|
||||
|
||||
try:
|
||||
from yaml import CSafeLoader as Loader
|
||||
except ImportError:
|
||||
from yaml import SafeLoader as Loader
|
||||
|
||||
V1_DIR = "docs"
|
||||
V2_DIR = "v2-docs"
|
||||
@@ -20,19 +26,16 @@ class SafetyGuard:
|
||||
self.inventory = self._load_inventory()
|
||||
|
||||
def _load_inventory(self):
|
||||
if os.path.exists(INVENTORY_PATH):
|
||||
try:
|
||||
with open(INVENTORY_PATH, "r") as f:
|
||||
return yaml.safe_load(f) or {}
|
||||
except: return {}
|
||||
return {}
|
||||
return load_inventory()
|
||||
|
||||
def _load_exempt_files(self):
|
||||
try:
|
||||
with open("data/link_rules.yaml", "r") as f:
|
||||
rules = yaml.safe_load(f)
|
||||
with open("data/link_rules.yaml", "r", encoding="utf-8") as f:
|
||||
rules = yaml.load(f, Loader=Loader)
|
||||
return rules.get("hierarchy_rules", {}).get("toc_exempt_files", [])
|
||||
except: return []
|
||||
except Exception as e:
|
||||
log_event(f"[WARN] load exempt files from link_rules.yaml: {str(e)[:100]}")
|
||||
return []
|
||||
|
||||
def validate_data_integrity(self, old_inventory: dict):
|
||||
"""Mandate 1: Información Preservation."""
|
||||
@@ -59,9 +62,11 @@ class SafetyGuard:
|
||||
"""Mandate 27: Special Assets Exhaustive Inclusion."""
|
||||
if not os.path.exists(SPECIAL_ASSETS_PATH): return
|
||||
try:
|
||||
with open(SPECIAL_ASSETS_PATH, "r") as f:
|
||||
special = yaml.safe_load(f).get("special_assets", [])
|
||||
except: return
|
||||
with open(SPECIAL_ASSETS_PATH, "r", encoding="utf-8") as f:
|
||||
special = yaml.load(f, Loader=Loader).get("special_assets", [])
|
||||
except Exception as e:
|
||||
log_event(f"[WARN] load special_assets.yaml for validation: {str(e)[:100]}")
|
||||
return
|
||||
|
||||
for sa in special:
|
||||
if "Include 100%" in sa.get("v2_rule", "") or "Exhaustive" in sa.get("v2_rule", ""):
|
||||
@@ -81,14 +86,23 @@ class SafetyGuard:
|
||||
for url, meta in self.inventory.items():
|
||||
if "github.com" in url and meta.get("v2_locations"):
|
||||
pushed = meta.get("gh_pushed", "")
|
||||
if pushed:
|
||||
try:
|
||||
last_date = datetime.fromisoformat(pushed.replace("Z", "+00:00"))
|
||||
inactive_years = (datetime.now(last_date.tzinfo) - last_date).days / 365
|
||||
stars = meta.get("gh_stars", meta.get("stars", 0) * 100)
|
||||
if inactive_years > 4 and stars < 30:
|
||||
self.warnings.append(f"🏚️ **MVQ Violation**: Stale repo `{url}` (>4yrs) in V2 with low impact")
|
||||
except: pass
|
||||
# Skip entries with no usable push date. Enrichment stores "N/A"
|
||||
# (and historically None/empty) when GitHub data is unavailable;
|
||||
# these are not ISO dates and must not reach fromisoformat().
|
||||
if not pushed or str(pushed).strip().upper() in ("N/A", "NONE"):
|
||||
continue
|
||||
try:
|
||||
last_date = datetime.fromisoformat(str(pushed).replace("Z", "+00:00"))
|
||||
inactive_years = (datetime.now(last_date.tzinfo) - last_date).days / 365
|
||||
# gh_stars may be missing; fall back to V1 stars (×100 heuristic).
|
||||
# Coalesce None so a stored null never reaches the multiplication.
|
||||
stars = meta.get("gh_stars")
|
||||
if stars is None:
|
||||
stars = (meta.get("stars") or 0) * 100
|
||||
if inactive_years > 4 and stars < 30:
|
||||
self.warnings.append(f"🏚️ **MVQ Violation**: Stale repo `{url}` (>4yrs) in V2 with low impact")
|
||||
except Exception as e:
|
||||
log_event(f"[WARN] MVQ compliance check for {url}: {str(e)[:100]}")
|
||||
|
||||
def validate_linguistic_tagging(self):
|
||||
"""Mandate 10: Explicit Language Tagging."""
|
||||
@@ -98,7 +112,9 @@ class SafetyGuard:
|
||||
with open(os.path.join(V2_DIR, file), "r") as f:
|
||||
content = f.read()
|
||||
for url, meta in self.inventory.items():
|
||||
lang = meta.get("language", "English")
|
||||
# language may be stored as null; coalesce to avoid None.lower()
|
||||
# aborting the entire audit.
|
||||
lang = meta.get("language") or "English"
|
||||
if lang.lower() != "english" and url in content:
|
||||
tag = f"[{lang.upper()} CONTENT]"
|
||||
if tag not in content:
|
||||
@@ -175,9 +191,11 @@ class SafetyGuard:
|
||||
"""Mandate 11: Workflow-Config Synchronization."""
|
||||
if not os.path.exists(WORKFLOW_PATH) or not os.path.exists(CURATION_SOURCES_PATH): return
|
||||
try:
|
||||
with open(CURATION_SOURCES_PATH, "r") as f:
|
||||
sources = yaml.safe_load(f).get("sources", [])
|
||||
except: return
|
||||
with open(CURATION_SOURCES_PATH, "r", encoding="utf-8") as f:
|
||||
sources = yaml.load(f, Loader=Loader).get("sources", [])
|
||||
except Exception as e:
|
||||
log_event(f"[WARN] load curation_sources.yaml for nav sync: {str(e)[:100]}")
|
||||
return
|
||||
|
||||
topics = [s["topic"] for s in sources]
|
||||
with open(WORKFLOW_PATH, "r") as f:
|
||||
@@ -191,10 +209,11 @@ class SafetyGuard:
|
||||
def validate_forbidden_tags(self):
|
||||
"""Mandate 51/Safety: Check for forbidden HTML tags in docs and v2-docs, except allowing iframes in videos."""
|
||||
try:
|
||||
with open("data/link_rules.yaml", "r") as f:
|
||||
rules = yaml.safe_load(f)
|
||||
with open("data/link_rules.yaml", "r", encoding="utf-8") as f:
|
||||
rules = yaml.load(f, Loader=Loader)
|
||||
forbidden = rules.get("safety_guard", {}).get("forbidden_tags", [])
|
||||
except:
|
||||
except Exception as e:
|
||||
log_event(f"[WARN] load forbidden tags from link_rules.yaml: {str(e)[:100]}")
|
||||
return
|
||||
|
||||
if not forbidden:
|
||||
@@ -275,19 +294,29 @@ class SafetyGuard:
|
||||
# 2. Run standard validations
|
||||
if old_inv_path and os.path.exists(old_inv_path):
|
||||
try:
|
||||
with open(old_inv_path, "r") as f:
|
||||
self.validate_data_integrity(yaml.safe_load(f) or {})
|
||||
except: pass
|
||||
with open(old_inv_path, "r", encoding="utf-8") as f:
|
||||
self.validate_data_integrity(yaml.load(f, Loader=Loader) or {})
|
||||
except Exception as e:
|
||||
log_event(f"[WARN] load old inventory for data integrity check: {str(e)[:100]}")
|
||||
|
||||
self.validate_semantic_interlinking()
|
||||
self.validate_special_assets_completeness()
|
||||
self.validate_mvq_compliance()
|
||||
self.validate_linguistic_tagging()
|
||||
self.validate_platinum_schema()
|
||||
self.validate_structural_standards() # Mandate 30 & 19
|
||||
self.validate_v2_architecture()
|
||||
self.validate_navigation_sync() # Mandate 11
|
||||
self.validate_forbidden_tags() # Safety Hardening
|
||||
# Run each mandate in isolation so one bad entry can't abort the
|
||||
# entire audit (e.g. a null field raising mid-validation).
|
||||
validations = [
|
||||
self.validate_semantic_interlinking,
|
||||
self.validate_special_assets_completeness,
|
||||
self.validate_mvq_compliance,
|
||||
self.validate_linguistic_tagging,
|
||||
self.validate_platinum_schema,
|
||||
self.validate_structural_standards, # Mandate 30 & 19
|
||||
self.validate_v2_architecture,
|
||||
self.validate_navigation_sync, # Mandate 11
|
||||
self.validate_forbidden_tags, # Safety Hardening
|
||||
]
|
||||
for check in validations:
|
||||
try:
|
||||
check()
|
||||
except Exception as e:
|
||||
log_event(f"[WARN] audit mandate {check.__name__} failed: {str(e)[:100]}")
|
||||
|
||||
status = "✅ PASS" if not self.errors else "❌ FAILED"
|
||||
if not self.errors and self.warnings: status = "⚠️ WARNING"
|
||||
|
||||
@@ -8,7 +8,7 @@ REQUIRED_SECTIONS = [
|
||||
"3. The Agentic Stack",
|
||||
"4. The 2026 Architectural Shift",
|
||||
"5. Dual-Edition Architecture (V1 vs V2)",
|
||||
"6. The Unified Agentic Database (Knowledge Graph)",
|
||||
"6. The Unified Agentic Database (Coexistence Knowledge Graph)",
|
||||
"7. AI Economic Architecture and Cost Analysis",
|
||||
"8. The Agentic AI Engine",
|
||||
"9. GitHub Workflows and Automation",
|
||||
|
||||
@@ -6,6 +6,11 @@ from src.logger import log_event
|
||||
CURATION_SOURCES_PATH = "data/curation_sources.yaml"
|
||||
WORKFLOW_PATH = ".github/workflows/01.1.agentic_cron.yml"
|
||||
|
||||
try:
|
||||
from yaml import CSafeLoader as Loader
|
||||
except ImportError:
|
||||
from yaml import SafeLoader as Loader
|
||||
|
||||
class WorkflowUISync:
|
||||
"""
|
||||
Automates Mandate 11: Workflow-Config Synchronization.
|
||||
@@ -16,8 +21,8 @@ class WorkflowUISync:
|
||||
return False
|
||||
|
||||
try:
|
||||
with open(CURATION_SOURCES_PATH, "r") as f:
|
||||
sources = yaml.safe_load(f).get("sources", [])
|
||||
with open(CURATION_SOURCES_PATH, "r", encoding="utf-8") as f:
|
||||
sources = yaml.load(f, Loader=Loader).get("sources", [])
|
||||
except Exception as e:
|
||||
log_event(f" [!] Error loading curation sources: {e}")
|
||||
return False
|
||||
|
||||
@@ -31,6 +31,27 @@ async def run_debate_protocol(item: Dict, is_new_link: bool = False) -> Tuple[in
|
||||
tags = item.get("tags", [])
|
||||
initial_score = item.get("impact_score", item.get("stars", 3) * 20) # Fallback mapping if stars is used
|
||||
|
||||
# 0. Check cache using content hash (Recommendation #4)
|
||||
import hashlib
|
||||
raw_content = f"{title}||{desc}||{','.join(sorted(tags))}"
|
||||
content_hash = hashlib.sha256(raw_content.encode("utf-8")).hexdigest()
|
||||
|
||||
if os.path.exists(DEBATE_MEMORY_FILE):
|
||||
try:
|
||||
with open(DEBATE_MEMORY_FILE, "r") as f:
|
||||
memory_data = json.load(f)
|
||||
cached = memory_data.get("resolved_debates", {}).get(normalize_url(url))
|
||||
if cached and cached.get("content_hash") == content_hash:
|
||||
log_event(f" [⚖️] CACHE HIT: Skipping debate for '{title}'. Returning cached consensus.")
|
||||
return (
|
||||
cached["final_consensus_score"],
|
||||
cached.get("final_tags", tags),
|
||||
cached.get("refined_summary", desc),
|
||||
cached
|
||||
)
|
||||
except Exception as e:
|
||||
log_event(f" [!] Error checking debate cache: {e}")
|
||||
|
||||
log_event(f" [⚖️] DEBATE TRIGGERED: '{title}' (Initial Score: {initial_score})", section_break=False)
|
||||
|
||||
# 0. Check if mock mode is requested or required (no keys configured)
|
||||
@@ -128,7 +149,10 @@ async def run_debate_protocol(item: Dict, is_new_link: bool = False) -> Tuple[in
|
||||
"scores": scores,
|
||||
"justifications": justifications,
|
||||
"rebuttals": debate_transcript,
|
||||
"timestamp": datetime.now().isoformat()
|
||||
"timestamp": datetime.now().isoformat(),
|
||||
"final_tags": sorted(list(final_tags)),
|
||||
"refined_summary": refined_summary,
|
||||
"content_hash": content_hash
|
||||
}
|
||||
|
||||
try:
|
||||
@@ -136,17 +160,81 @@ async def run_debate_protocol(item: Dict, is_new_link: bool = False) -> Tuple[in
|
||||
if os.path.exists(DEBATE_MEMORY_FILE):
|
||||
try:
|
||||
memory_data = json.load(open(DEBATE_MEMORY_FILE, "r"))
|
||||
except: pass
|
||||
except Exception as e:
|
||||
log_event(f"[WARN] load debate memory for mock persist: {str(e)[:100]}")
|
||||
memory_data.setdefault("resolved_debates", {})[normalize_url(url)] = debate_data
|
||||
with open(DEBATE_MEMORY_FILE, "w") as f:
|
||||
json.dump(memory_data, f, indent=2)
|
||||
except Exception as e:
|
||||
log_event(f" [!] Failed to persist debate memory: {e}")
|
||||
|
||||
|
||||
return final_score, sorted(list(final_tags)), refined_summary, debate_data
|
||||
|
||||
system_mandates = get_system_mandates()
|
||||
|
||||
# Fast-Pass Evaluator call (Recommendation #3)
|
||||
fast_pass_prompt = (
|
||||
"You are the Nubenetes Fast-Pass Evaluator (2026).\n"
|
||||
f"Analyze the following resource details:\n"
|
||||
f"- Title: {title}\n"
|
||||
f"- URL: {url}\n"
|
||||
f"- Context: {desc}\n"
|
||||
f"- Proposed Tags: {tags}\n\n"
|
||||
f"{system_mandates}\n\n"
|
||||
"Evaluate this resource across Security, SRE, and AI/Developer DX aspects and assign a score (0 to 100).\n"
|
||||
"Also generate a high-density, professional technical summary (2-5 sentences, O'Reilly technical style) and select appropriate tags.\n"
|
||||
"Respond ONLY in valid JSON format: {\"score\": int, \"justification\": \"string\", \"summary\": \"string\", \"tags\": [\"string\"]}"
|
||||
)
|
||||
|
||||
fast_pass_score = int(initial_score)
|
||||
fast_pass_justification = "Failed to run fast-pass."
|
||||
fast_pass_summary = desc
|
||||
fast_pass_tags = tags
|
||||
|
||||
try:
|
||||
res = await call_gemini_with_retry(fast_pass_prompt, prefer_flash=True, use_grounding=True, role="FastPass-Evaluator")
|
||||
fast_pass_score = min(max(int(res.get("score", 50)), 0), 100)
|
||||
fast_pass_justification = res.get("justification", "No justification provided.")
|
||||
fast_pass_summary = res.get("summary", desc)
|
||||
fast_pass_tags = res.get("tags", tags)
|
||||
log_event(f" [🔍] Fast-Pass Evaluator rated score: {fast_pass_score}")
|
||||
except Exception as e:
|
||||
log_event(f" [!] Fast-Pass Evaluator failed: {e}")
|
||||
|
||||
# Check if the score falls outside the borderline uncertainty margin [60, 75]
|
||||
if fast_pass_score >= 76 or fast_pass_score <= 59:
|
||||
log_event(f" [⚡] Fast-Pass Consensus reached ({fast_pass_score}). Skipping full debate panel!")
|
||||
|
||||
debate_data = {
|
||||
"url": url,
|
||||
"title": title,
|
||||
"initial_score": initial_score,
|
||||
"final_consensus_score": fast_pass_score,
|
||||
"fast_pass": True,
|
||||
"justification": fast_pass_justification,
|
||||
"timestamp": datetime.now().isoformat(),
|
||||
"final_tags": fast_pass_tags,
|
||||
"refined_summary": fast_pass_summary,
|
||||
"content_hash": content_hash
|
||||
}
|
||||
|
||||
try:
|
||||
memory_data = {}
|
||||
if os.path.exists(DEBATE_MEMORY_FILE):
|
||||
try:
|
||||
memory_data = json.load(open(DEBATE_MEMORY_FILE, "r"))
|
||||
except Exception as e:
|
||||
log_event(f"[WARN] load debate memory for fast-pass persist: {str(e)[:100]}")
|
||||
memory_data.setdefault("resolved_debates", {})[normalize_url(url)] = debate_data
|
||||
with open(DEBATE_MEMORY_FILE, "w") as f:
|
||||
json.dump(memory_data, f, indent=2)
|
||||
except Exception as e:
|
||||
log_event(f" [!] Failed to persist debate memory: {e}")
|
||||
|
||||
return fast_pass_score, fast_pass_tags, fast_pass_summary, debate_data
|
||||
|
||||
log_event(f" [⚖️] Borderline score detected ({fast_pass_score}). Escalating to full Multi-Agent Debate Panel...")
|
||||
|
||||
# 1. Independent Evaluation Round
|
||||
personas = {
|
||||
"Security Architect": "Focus on licensing (MIT/Apache vs BSL/SSPL), supply chain security, access control, vulnerabilities, and enterprise compliance.",
|
||||
@@ -266,7 +354,10 @@ async def run_debate_protocol(item: Dict, is_new_link: bool = False) -> Tuple[in
|
||||
"scores": scores,
|
||||
"justifications": justifications,
|
||||
"rebuttals": debate_transcript,
|
||||
"timestamp": datetime.now().isoformat()
|
||||
"timestamp": datetime.now().isoformat(),
|
||||
"final_tags": final_tags,
|
||||
"refined_summary": refined_summary,
|
||||
"content_hash": content_hash
|
||||
}
|
||||
|
||||
# Persist the resolved debate to memory log (Mandate 3.1)
|
||||
@@ -275,10 +366,11 @@ async def run_debate_protocol(item: Dict, is_new_link: bool = False) -> Tuple[in
|
||||
if os.path.exists(DEBATE_MEMORY_FILE):
|
||||
try:
|
||||
memory_data = json.load(open(DEBATE_MEMORY_FILE, "r"))
|
||||
except: pass
|
||||
|
||||
except Exception as e:
|
||||
log_event(f"[WARN] load debate memory for final persist: {str(e)[:100]}")
|
||||
|
||||
memory_data.setdefault("resolved_debates", {})[normalize_url(url)] = debate_data
|
||||
|
||||
|
||||
# Keep blacklist and other fields intact
|
||||
with open(DEBATE_MEMORY_FILE, "w") as f:
|
||||
json.dump(memory_data, f, indent=2)
|
||||
|
||||
@@ -78,22 +78,41 @@ def extract_youtube_id(url):
|
||||
def get_target_file(category, technology):
|
||||
cat_lower = category.lower()
|
||||
tech_lower = technology.lower()
|
||||
|
||||
if "agent" in tech_lower or "mcp" in tech_lower or "ai and future operations" in cat_lower:
|
||||
|
||||
if "agent" in tech_lower or "mcp" in tech_lower or "ai and future operations" in cat_lower or "llm" in tech_lower or "chatgpt" in tech_lower:
|
||||
return "ai-agents.md", "AI Agents and MCP"
|
||||
elif "infrastructure as code" in cat_lower or "security" in cat_lower or "observability" in cat_lower or "monitoring" in cat_lower or "devops" in tech_lower or "iac" in tech_lower or "sre" in tech_lower:
|
||||
elif "mlops" in tech_lower or "data science" in cat_lower or "machine learning" in tech_lower:
|
||||
return "ai-agents.md", "AI Agents and MCP"
|
||||
elif "security" in cat_lower or "devsecops" in tech_lower or "zero trust" in tech_lower or "vulnerability" in tech_lower:
|
||||
return "devops-iac.md", "DevOps, IaC, and SRE"
|
||||
elif "fundamentals" in cat_lower:
|
||||
elif "infrastructure as code" in cat_lower or "observability" in cat_lower or "monitoring" in cat_lower or "devops" in tech_lower or "iac" in tech_lower or "sre" in tech_lower:
|
||||
return "devops-iac.md", "DevOps, IaC, and SRE"
|
||||
elif "terraform" in tech_lower or "ansible" in tech_lower or "pulumi" in tech_lower or "crossplane" in tech_lower:
|
||||
return "devops-iac.md", "DevOps, IaC, and SRE"
|
||||
elif "gitops" in tech_lower or "argo" in tech_lower or "flux" in tech_lower or "tekton" in tech_lower or "jenkins" in tech_lower or "cicd" in tech_lower:
|
||||
return "devops-iac.md", "DevOps, IaC, and SRE"
|
||||
elif "prometheus" in tech_lower or "grafana" in tech_lower or "opentelemetry" in tech_lower or "otel" in tech_lower:
|
||||
return "devops-iac.md", "DevOps, IaC, and SRE"
|
||||
elif "finops" in tech_lower or "cost" in tech_lower or "kubecost" in tech_lower:
|
||||
return "devops-iac.md", "DevOps, IaC, and SRE"
|
||||
elif "fundamentals" in cat_lower or "certification" in tech_lower or "cka" in tech_lower or "training" in cat_lower:
|
||||
return "fundamentals.md", "Fundamentals"
|
||||
elif "aws" in tech_lower or "azure" in tech_lower or "gcp" in tech_lower or "google cloud" in tech_lower:
|
||||
return "cloud-native.md", "Cloud Native Core"
|
||||
elif "openshift" in tech_lower or "red hat" in tech_lower or "rancher" in tech_lower:
|
||||
return "cloud-native.md", "Cloud Native Core"
|
||||
elif "vmware" in tech_lower or "proxmox" in tech_lower or "virtualization" in tech_lower:
|
||||
return "cloud-native.md", "Cloud Native Core"
|
||||
elif "docker" in tech_lower or "container" in tech_lower or "podman" in tech_lower:
|
||||
return "cloud-native.md", "Cloud Native Core"
|
||||
elif "python" in tech_lower or "golang" in tech_lower or "java" in tech_lower or "javascript" in tech_lower:
|
||||
return "fundamentals.md", "Fundamentals"
|
||||
else:
|
||||
return "cloud-native.md", "Cloud Native Core"
|
||||
|
||||
def generate_v2_videos():
|
||||
if not os.path.exists(INVENTORY_PATH):
|
||||
return
|
||||
|
||||
with open(INVENTORY_PATH, "r") as f:
|
||||
inventory = yaml.safe_load(f)
|
||||
from src.inventory_manager import load_inventory
|
||||
inventory = load_inventory()
|
||||
|
||||
featured_videos = []
|
||||
for url, entry in inventory.items():
|
||||
@@ -162,25 +181,19 @@ def generate_v2_videos():
|
||||
" You are browsing the AI-Curated V2 Elite Edition. Looking for the exhaustive list of references? Check out the [**V1 Historical Archive**](/v1/).",
|
||||
"",
|
||||
f"Welcome to the **{theme_title}** section of the V2 Video Hub. Explore curated high-density videos with architectural summaries.",
|
||||
"",
|
||||
"## Table of Contents",
|
||||
""
|
||||
]
|
||||
|
||||
# Group by Technology for TOC
|
||||
# In-page Markdown Table of Contents intentionally omitted: it duplicates
|
||||
# Material's native right-column "On this page" TOC (toc.follow). We still
|
||||
# build the ordered technology list below because it drives the rendering
|
||||
# order of the grouped video sections.
|
||||
techs = []
|
||||
for v in videos:
|
||||
tech = v.get("technology", "Cloud Native")
|
||||
if tech not in techs:
|
||||
techs.append(tech)
|
||||
|
||||
for idx, tech in enumerate(techs, 1):
|
||||
clean_tech = clean_header(tech)
|
||||
slug = get_slug(tech)
|
||||
content.append(f"{idx}. [{clean_tech}](#{slug})")
|
||||
|
||||
content.append("")
|
||||
|
||||
# Render Grouped Videos
|
||||
grouped_by_tech = {}
|
||||
for v in videos:
|
||||
|
||||
@@ -6,14 +6,6 @@
|
||||
!!! info "Architectural Context"
|
||||
Detailed reference for Chrome and Firefox DevTools. HTTP Protocols and WebSockets in the context of Developer Ecosystem.
|
||||
|
||||
## Table of Contents
|
||||
|
||||
1. [Developer Workspace](#developer-workspace)
|
||||
- [Command-Line Tooling](#command-line-tooling)
|
||||
- [JSON and YAML Manipulators](#json-and-yaml-manipulators)
|
||||
- [Diagnostics and Debugging](#diagnostics-and-debugging)
|
||||
- [Browser Developer Tools](#browser-developer-tools)
|
||||
|
||||
## Developer Workspace
|
||||
|
||||
### Command-Line Tooling
|
||||
|
||||
@@ -1,3 +1,6 @@
|
||||
---
|
||||
description: "Top Googlecloudplatform resources for 2026, AI-ranked: Google Cloud Buildpacks, Google Agents CLI and more — curated Cloud Native tools, guides and references."
|
||||
---
|
||||
# Google Cloud Platform
|
||||
|
||||
!!! tip "Nubenetes V2 Elite Portal"
|
||||
@@ -6,138 +9,6 @@
|
||||
!!! info "Architectural Context"
|
||||
Detailed reference for Google Cloud Platform in the context of Cloud Providers (Hyperscalers).
|
||||
|
||||
## Table of Contents
|
||||
|
||||
1. [AI and Orchestration](#ai-and-orchestration)
|
||||
- [Agentic Workflows](#agentic-workflows)
|
||||
- [Command-Line Tools](#command-line-tools)
|
||||
1. [AI Engineering](#ai-engineering)
|
||||
- [Agentic Frameworks](#agentic-frameworks)
|
||||
- [Google Cloud](#google-cloud)
|
||||
1. [Application Development](#application-development)
|
||||
- [API Management](#api-management)
|
||||
- [Apigee Integration](#apigee-integration)
|
||||
- [Automation](#automation)
|
||||
- [Python](#python)
|
||||
- [Data Engineering](#data-engineering)
|
||||
- [Google Sheets](#google-sheets)
|
||||
- [Developer Portal](#developer-portal)
|
||||
- [Open Source Showcase](#open-source-showcase)
|
||||
- [Low-CodeNo-Code](#low-codeno-code)
|
||||
- [Platform Review](#platform-review)
|
||||
- [Productivity](#productivity)
|
||||
- [Workflows](#workflows)
|
||||
- [Orchestration](#orchestration)
|
||||
1. [Architectural Foundations](#architectural-foundations)
|
||||
- [Kubernetes Tools](#kubernetes-tools)
|
||||
- [General Reference](#general-reference)
|
||||
1. [Cloud Infrastructure](#cloud-infrastructure)
|
||||
- [Compute](#compute)
|
||||
- [Architectural Decision](#architectural-decision)
|
||||
- [Cost Optimization](#cost-optimization)
|
||||
- [Containers](#containers)
|
||||
- [Google Kubernetes Engine](#google-kubernetes-engine)
|
||||
- [Data Migration](#data-migration)
|
||||
- [Storage](#storage)
|
||||
- [Databases](#databases)
|
||||
- [Cloud Spanner](#cloud-spanner)
|
||||
- [Managed Services](#managed-services)
|
||||
- [Resiliency Testing](#resiliency-testing)
|
||||
- [Developer Tooling](#developer-tooling)
|
||||
- [Cloud Shell](#cloud-shell)
|
||||
- [GCP Ecosystem](#gcp-ecosystem)
|
||||
- [CICD Pipelines](#cicd-pipelines)
|
||||
- [DevOps Frameworks](#devops-frameworks)
|
||||
- [Developer Tools](#developer-tools)
|
||||
- [IDE Integrations](#ide-integrations)
|
||||
- [Google Cloud Platform](#google-cloud-platform-1)
|
||||
- [Product Catalog](#product-catalog)
|
||||
- [High Availability](#high-availability)
|
||||
- [Architecture](#architecture)
|
||||
- [Microservices](#microservices)
|
||||
- [Google Cloud](#google-cloud-1)
|
||||
- [Networking](#networking)
|
||||
- [Private Service Connect](#private-service-connect)
|
||||
- [VPC VPN](#vpc-vpn)
|
||||
- [Observability](#observability)
|
||||
- [Google Cloud Operations](#google-cloud-operations)
|
||||
- [Public Cloud](#public-cloud)
|
||||
- [Analysis](#analysis)
|
||||
- [Google Cloud](#google-cloud-2)
|
||||
- [Reference Sheets](#reference-sheets)
|
||||
- [Training](#training)
|
||||
- [Security](#security)
|
||||
- [IAM](#iam)
|
||||
- [PKI](#pki)
|
||||
- [Platform Threat Intelligence](#platform-threat-intelligence)
|
||||
- [Secrets Management](#secrets-management)
|
||||
- [Serverless](#serverless)
|
||||
- [Cloud Run](#cloud-run)
|
||||
- [VPC Networking](#vpc-networking)
|
||||
1. [Cloud Providers](#cloud-providers)
|
||||
- [GCP](#gcp)
|
||||
- [Product Catalog](#product-catalog-1)
|
||||
- [Google Kubernetes Engine GKE](#google-kubernetes-engine-gke)
|
||||
- [GKE Core](#gke-core)
|
||||
1. [Cloud Strategy](#cloud-strategy)
|
||||
- [Service Mapping](#service-mapping)
|
||||
- [GCP Translation](#gcp-translation)
|
||||
1. [Cluster Management](#cluster-management)
|
||||
- [GitOps](#gitops)
|
||||
- [Config Sync](#config-sync)
|
||||
1. [Containers and Orchestration](#containers-and-orchestration)
|
||||
- [GitOps](#gitops-1)
|
||||
- [Config Connector](#config-connector)
|
||||
1. [DevOps and Delivery](#devops-and-delivery)
|
||||
- [CICD](#cicd)
|
||||
- [Containerization](#containerization)
|
||||
- [Lifecycle Management](#lifecycle-management)
|
||||
- [Continuous Delivery](#continuous-delivery)
|
||||
- [GKE](#gke)
|
||||
- [GKE GA](#gke-ga)
|
||||
- [Industry Assessment](#industry-assessment)
|
||||
- [Developer Tools](#developer-tools-1)
|
||||
- [CLI Automation](#cli-automation)
|
||||
- [CLI References](#cli-references)
|
||||
- [Infrastructure as Code](#infrastructure-as-code)
|
||||
- [Terraform](#terraform)
|
||||
1. [DevSecOps](#devsecops)
|
||||
- [CICD Pipelines](#cicd-pipelines-1)
|
||||
- [Hybrid Cloud Architecture](#hybrid-cloud-architecture)
|
||||
1. [DevSecOps and IDEs](#devsecops-and-ides)
|
||||
- [Google Cloud Code](#google-cloud-code)
|
||||
- [Developer Experience](#developer-experience)
|
||||
1. [Hybrid and Multi-Cloud](#hybrid-and-multi-cloud)
|
||||
- [Anthos](#anthos)
|
||||
- [Ingress](#ingress)
|
||||
- [Multi-Cloud Support](#multi-cloud-support)
|
||||
- [Multi-Cluster](#multi-cluster)
|
||||
- [Strategic Guide](#strategic-guide)
|
||||
- [Windows Containers](#windows-containers)
|
||||
1. [Networking and Security](#networking-and-security)
|
||||
- [Content Delivery](#content-delivery)
|
||||
- [Caching](#caching)
|
||||
- [Core Services](#core-services)
|
||||
- [DNS](#dns)
|
||||
- [IAM](#iam-1)
|
||||
- [Federated Identity](#federated-identity)
|
||||
- [Identity and Access](#identity-and-access)
|
||||
- [Database Proxy](#database-proxy)
|
||||
- [Infrastructure](#infrastructure)
|
||||
- [Fundamentals](#fundamentals)
|
||||
- [VPC](#vpc)
|
||||
- [Service Discovery](#service-discovery)
|
||||
- [Registry](#registry)
|
||||
- [Service Mesh](#service-mesh)
|
||||
- [Traffic Management](#traffic-management)
|
||||
- [Threat Detection](#threat-detection)
|
||||
- [Intrusion Detection](#intrusion-detection)
|
||||
- [Traffic Management](#traffic-management-1)
|
||||
- [Load Balancing](#load-balancing)
|
||||
1. [Public Cloud Providers](#public-cloud-providers)
|
||||
- [GCP](#gcp-1)
|
||||
- [Enterprise Platform](#enterprise-platform)
|
||||
|
||||
## AI and Orchestration
|
||||
|
||||
### Agentic Workflows
|
||||
@@ -145,13 +16,6 @@
|
||||
#### Command-Line Tools
|
||||
|
||||
- **(2025)** [**Google Agents CLI**](https://github.com/google/agents-cli) <span class='md-tag md-tag--info'>⭐ 2853</span> <svg class="v2-sparkline" width="50" height="15" viewBox="0 0 50 15" style="vertical-align: middle; display: inline-block; margin-left: 6px;" title="Activity Trend"><defs><linearGradient id="spark-grad-f7881b53" x1="0" y1="0" x2="1" y2="0"><stop offset="0%" stop-color="rgba(34, 211, 238, 0.2)" /><stop offset="100%" stop-color="var(--md-accent-fg-color)" /></linearGradient></defs><path class="v2-sparkline-path" d="M 0 11 L 10 6 L 20 6 L 30 13 L 40 7 L 50 4" fill="none" stroke="url(#spark-grad-f7881b53)" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round" /><circle cx="50" cy="4" r="2" fill="var(--md-accent-fg-color)" /></svg> <span class='md-tag md-tag--warning'>[TYPESCRIPT CONTENT]</span> <span class='md-tag md-tag--critical'>[ADVANCED LEVEL]</span> 🌟🌟🌟🌟 <span class='md-tag md-tag--success'>[ENTERPRISE-STABLE]</span> — An official command-line tool from Google built to design, test, and deploy agentic AI workflows. Leveraging the Model Context Protocol (MCP) and Google LLM APIs, it facilitates automated task orchestration across local filesystems and remote cloud APIs.
|
||||
## AI Engineering
|
||||
|
||||
### Agentic Frameworks
|
||||
|
||||
#### Google Cloud
|
||||
|
||||
- **(2025)** [Level Up Your Agents: Announcing Google's Official Skills Repository](https://cloud.google.com/blog/topics/developers-practitioners/level-up-your-agents-announcing-googles-official-skills-repository) <span class='md-tag md-tag--warning'>[PYTHON CONTENT]</span> <span class='md-tag md-tag--info'>[COMMUNITY-TOOL]</span> — Google Cloud's announcement of its official skills repository designed for AI agents. This resource provides ready-made functions, connectors, and tools that can be bound to Gemini-powered agents, enabling them to query enterprise databases, execute administrative tasks, and integrate with standard GCP APIs with strict security guarantees.
|
||||
## Application Development
|
||||
|
||||
### API Management
|
||||
@@ -159,46 +23,11 @@
|
||||
#### Apigee Integration
|
||||
|
||||
- **(2021)** [Announcing Apigee Integration: An API-first approach for connecting data and applications](https://cloud.google.com/blog/products/api-management/google-cloud-announces-apigee-integration) <span class='md-tag md-tag--critical'>[ADVANCED LEVEL]</span> <span class='md-tag md-tag--primary'>[DOCUMENTATION]</span> <span class='md-tag md-tag--info'>[COMMUNITY-TOOL]</span> — Introduces Apigee Integration, combining Apigee's API management platform with native application integration engines. Facilitates low-latency connection patterns between enterprise systems, SaaS endpoints, and custom REST/gRPC microservices.
|
||||
### Automation
|
||||
|
||||
#### Python
|
||||
|
||||
- **(2021)** [anderfernandez.com: Cómo automatizar un script de Python en Google Cloud](https://anderfernandez.com/blog/automatizar-script-python-google-cloud) <span class='md-tag md-tag--warning'>[SPANISH CONTENT]</span> <span class='md-tag md-tag--info'>[COMMUNITY-TOOL]</span> — A step-by-step developer tutorial demonstrating execution of Python automation workflows inside Google Cloud. Reviews orchestration using Cloud Scheduler, Cloud Functions, and Compute Engine to automate data extraction, scraping, and processing routines.
|
||||
### Data Engineering
|
||||
|
||||
#### Google Sheets
|
||||
|
||||
- **(2021)** [freecodecamp.org: Web Scraping with Google Sheets – How to Scrape Web Pages with Built-in Functions](https://www.freecodecamp.org/news/web-scraping-google-sheets) <span class='md-tag md-tag--info'>[COMMUNITY-TOOL]</span> — Evaluates techniques for scraping and parsing web pages using built-in Google Sheets functions like IMPORTXML and IMPORTHTML. Provides direct patterns for light ETL, rapid data extraction, and spreadsheet automation workflows.
|
||||
### Developer Portal
|
||||
|
||||
#### Open Source Showcase
|
||||
|
||||
- **(2021)** [devlibrary.withgoogle.com 🌟](https://devlibrary.withgoogle.com) <span class='md-tag md-tag--info'>[COMMUNITY-TOOL]</span> — Google’s curated repository showcasing real-world, high-quality open-source projects, libraries, and architecture demonstrations built with GCP and Flutter. Serves as a peer-reviewed knowledge engine for production-proven software architectures.
|
||||
### Low-CodeNo-Code
|
||||
|
||||
#### Platform Review
|
||||
|
||||
- **(2020)** [infoworld.com: Google Cloud AppSheet review: No-code with extras](https://www.infoworld.com/article/2270941/google-cloud-appsheet-review-no-code-with-extras.html) <span class='md-tag md-tag--info'>[COMMUNITY-TOOL]</span> — A critical, technical review analyzing AppSheet's feature set, emphasizing its data-modeling capabilities, native integration with GCP resources, and automated workflow triggers. Assesses how the platform scales for rapid application delivery compared to traditional development.
|
||||
#### Productivity
|
||||
|
||||
- **(2020)** [Google Cloud AppSheet](https://about.appsheet.com/home) <span class='md-tag md-tag--info'>[COMMUNITY-TOOL]</span> — AppSheet delivers a robust, no-code application development platform that integrates directly with Google Workspace, databases, and third-party APIs. Enables business developers to engineer secure mobile and web automation interfaces with zero infrastructure overhead.
|
||||
### Workflows
|
||||
|
||||
#### Orchestration
|
||||
|
||||
- **(2021)** [cloud.google.com: Service orchestration on Google Cloud](https://cloud.google.com/blog/topics/developers-practitioners/service-orchestration-google-cloud) <span class='md-tag md-tag--primary'>[DOCUMENTATION]</span> <span class='md-tag md-tag--info'>[COMMUNITY-TOOL]</span> — Analyzes service orchestration methodologies in Google Cloud, highlighting Cloud Workflows. Illustrates how architects can coordinate microservices, serverless architectures, and external API gateways with low-latency, stateful orchestration mechanisms.
|
||||
## Architectural Foundations
|
||||
|
||||
### Kubernetes Tools
|
||||
|
||||
#### General Reference
|
||||
|
||||
- [medium.com/google-cloud/tagged/devops](https://medium.com/google-cloud/tagged/devops) <span class='md-tag md-tag--info'>[COMMUNITY-TOOL]</span> — A curated technical resource and architectural guide covering medium.com/google-cloud/tagged/devops in the Kubernetes Tools ecosystem.
|
||||
- [venturebeat.com: Google Cloud announces Network Connectivity Center to simplify' hybrid cloud management](https://venturebeat.com/2021/03/23/google-cloud-announces-network-connectivity-center-to-simplify-hybrid-cloud-management) <span class='md-tag md-tag--info'>[COMMUNITY-TOOL]</span> — A curated technical resource and architectural guide covering venturebeat.com: Google Cloud announces Network Connectivity Center to simplify' hybrid cloud management in the Kubernetes Tools ecosystem.
|
||||
- [medium.com/google-cloud: Design your Landing Zone — Design Considerations' Part 4— IaC, GitOps and CI/CD (Google Cloud Adoption Series)](https://medium.com/google-cloud/design-your-landing-zone-design-considerations-part-4-iac-gitops-and-ci-cd-google-cloud-ae3f533c6dbd) <span class='md-tag md-tag--info'>[COMMUNITY-TOOL]</span> — A curated technical resource and architectural guide covering medium.com/google-cloud: Design your Landing Zone — Design Considerations' Part 4— IaC, GitOps and CI/CD (Google Cloud Adoption Series) in the Kubernetes Tools ecosystem.
|
||||
- [engineering.mercari.com: Kubernetes based autoscaler for Cloud Spanner](https://engineering.mercari.com/en/blog/entry/20211222-kubernetes-based-spanner-autoscaler) <span class='md-tag md-tag--info'>[COMMUNITY-TOOL]</span> — A curated technical resource and architectural guide covering engineering.mercari.com: Kubernetes based autoscaler for Cloud Spanner in the Kubernetes Tools ecosystem.
|
||||
- [medium.com/google-cloud: Anthos-at-Home: Spinning Up a Bare-Metal Anthos' Cluster on Dumpster Servers](https://medium.com/google-cloud/anthos-at-home-spinning-up-a-bare-metal-anthos-cluster-on-dumpster-servers-5bcef301cfa5) <span class='md-tag md-tag--info'>[COMMUNITY-TOOL]</span> — A curated technical resource and architectural guide covering medium.com/google-cloud: Anthos-at-Home: Spinning Up a Bare-Metal Anthos' Cluster on Dumpster Servers in the Kubernetes Tools ecosystem.
|
||||
- [Terraform Provider for Google Cloud 7.0 is now GA](https://www.hashicorp.com/en/blog/terraform-provider-for-google-cloud-7-0-is-now-ga) <span class='md-tag md-tag--info'>[COMMUNITY-TOOL]</span> — A curated technical resource and architectural guide covering Terraform Provider for Google Cloud 7.0 is now GA in the Kubernetes Tools ecosystem.
|
||||
## Cloud Infrastructure
|
||||
|
||||
### Compute
|
||||
@@ -206,35 +35,16 @@
|
||||
#### Architectural Decision
|
||||
|
||||
- **(2021)** [cloud.google.com: Where should I run my stuff? Choosing a Google Cloud compute option](https://cloud.google.com/blog/topics/developers-practitioners/where-should-i-run-my-stuff-choosing-google-cloud-compute-option) <span class='md-tag md-tag--primary'>[DOCUMENTATION]</span> <span class='md-tag md-tag--info'>[COMMUNITY-TOOL]</span> — An architectural decision matrix evaluating Google Cloud's compute execution environments, ranging from Compute Engine and GKE to Cloud Run and App Engine. It guides architects to match runtime characteristics, scaling requirements, and operational overhead boundaries with the appropriate hosting platform.
|
||||
#### Cost Optimization
|
||||
|
||||
- **(2021)** [cloud.google.com: Save money and time with automated VM management and suspend/resume](https://cloud.google.com/blog/products/compute/guide-to-cost-optimization-through-automated-vm-management) <span class='md-tag md-tag--primary'>[DOCUMENTATION]</span> <span class='md-tag md-tag--info'>[COMMUNITY-TOOL]</span> — Explores cost-efficiency frameworks in Compute Engine, focusing on automated VM lifecycle management, suspension, and resumption states. This guide provides technical patterns for eliminating idle compute costs during off-peak hours without sacrificing state or deployment velocity.
|
||||
### Containers
|
||||
|
||||
#### Google Kubernetes Engine
|
||||
|
||||
- **(2021)** [cloud.google.com: A container story - Google Kubernetes Engine](https://cloud.google.com/blog/topics/developers-practitioners/container-story-google-kubernetes-engine) <span class='md-tag md-tag--info'>[COMMUNITY-TOOL]</span> — Outlines the evolutionary architecture of container orchestration leading to Google Kubernetes Engine (GKE). It covers GKE's managed control plane, automated node provisioning, and deep integration with GCP networking, offering a foundational narrative on production-grade containerization.
|
||||
### Data Migration
|
||||
|
||||
#### Storage
|
||||
|
||||
- **(2021)** [cloud.google.com: How to transfer your data to Google Cloud](https://cloud.google.com/blog/topics/developers-practitioners/how-transfer-your-data-google-cloud) <span class='md-tag md-tag--primary'>[DOCUMENTATION]</span> <span class='md-tag md-tag--info'>[COMMUNITY-TOOL]</span> — Demystifies data ingestion and migration strategies into GCP, categorizing methods by data volume, network bandwidth, and velocity. Focuses on Storage Transfer Service, Transfer Appliance, and programmatic transfer workflows to optimize offline and online pipeline migration.
|
||||
### Databases
|
||||
|
||||
#### Cloud Spanner
|
||||
|
||||
- **(2026)** [cloud.google.com: Demystifying Cloud Spanner multi-region configurations](https://cloud.google.com/blog/topics/developers-practitioners/demystifying-cloud-spanner-multi-region-configurations) <span class='md-tag md-tag--critical'>[ADVANCED LEVEL]</span> <span class='md-tag md-tag--info'>[COMMUNITY-TOOL]</span> <span class='md-tag md-tag--secondary'>[GUIDE]</span> — Technical exploration of Cloud Spanner's synchronous, multi-region replication. Explains Paxos consensus algorithms, TrueTime API synchronization, and consistency guarantees across continents.
|
||||
#### Managed Services
|
||||
|
||||
- **(2021)** [cloud.google.com: Your Google Cloud database options, explained](https://cloud.google.com/blog/topics/developers-practitioners/your-google-cloud-database-options-explained) <span class='md-tag md-tag--primary'>[DOCUMENTATION]</span> <span class='md-tag md-tag--info'>[COMMUNITY-TOOL]</span> — A comprehensive analytical overview of Google Cloud's managed database portfolio, mapping structured, unstructured, relational, and NoSQL engines (such as Cloud Spanner, Cloud SQL, and Firestore) to specific enterprise workloads. It guides architects through selecting storage paradigms based on consistency models, scale, and transaction volumes.
|
||||
#### Resiliency Testing
|
||||
|
||||
- **(2021)** [Testing Cloud SQL failover: Where to begin](https://cloud.google.com/blog/topics/developers-practitioners/testing-cloud-sql-failover-where-begin) <span class='md-tag md-tag--critical'>[ADVANCED LEVEL]</span> <span class='md-tag md-tag--primary'>[DOCUMENTATION]</span> <span class='md-tag md-tag--info'>[COMMUNITY-TOOL]</span> — Deeply evaluates failover mechanics inside Google Cloud SQL. Discusses High Availability (HA) topologies, read replica behavior, and how engineers can safely initiate manual failover triggers to evaluate database reconnection and application resilience.
|
||||
### Developer Tooling
|
||||
|
||||
#### Cloud Shell
|
||||
|
||||
- **(2026)** [New Cloud Shell Editor: Get your first cloud-native app running in minutes](https://cloud.google.com/blog/products/application-development/introducing-cloud-shell-editor) <span class='md-tag md-tag--info'>[COMMUNITY-TOOL]</span> — Introduces GCP's modernized web-based IDE powered by Eclipse Theia. It provides a preconfigured container workspace, dynamic terminal access, and direct integration with local source controls.
|
||||
### GCP Ecosystem
|
||||
|
||||
#### CICD Pipelines
|
||||
@@ -249,11 +59,6 @@
|
||||
#### IDE Integrations
|
||||
|
||||
- **(2025)** [Google Cloud Code](https://cloud.google.com/code) <span class='md-tag md-tag--warning'>[JAVASCRIPT CONTENT]</span> <span class='md-tag md-tag--info'>[COMMUNITY-TOOL]</span> — A powerful suite of IDE plugins (VS Code, IntelliJ) designed to accelerate development of cloud-native systems on GCP. Curator highlights focus on debugging Kubernetes clusters directly from local workstations. Live engineering teams use Cloud Code to minimize the gap between local code changes and GCP deployment environments, driving faster development feedback loops.
|
||||
### Google Cloud Platform (1)
|
||||
|
||||
#### Product Catalog
|
||||
|
||||
- **(2026)** [console.cloud.google.com/products](https://accounts.google.com/v3/signin/identifier?continue=https%3A%2F%2Fconsole.cloud.google.com%2Fproducts&dsh=S-837258255%3A1779033921742301&followup=https%3A%2F%2Fconsole.cloud.google.com%2Fproducts&osid=1&passive=1209600&service=cloudconsole&flowName=WebLiteSignIn&flowEntry=ServiceLogin&ifkv=AWa2PavdLijoZE8HgBUBXNoU1YfsOf-olUjJ8JfmhFG_0QoTjdDv1sVmFwi8Eo6EXbpyWStjzuTRaQ) <span class='md-tag md-tag--critical'>[ADVANCED LEVEL]</span> <span class='md-tag md-tag--primary'>[DOCUMENTATION]</span> <span class='md-tag md-tag--info'>[COMMUNITY-TOOL]</span> — The comprehensive management control plane for Google Cloud Platform (GCP) services, showcasing serverless runtimes, managed databases, and enterprise networking. It provides native Kubernetes (GKE), AI services, and IAM frameworks to construct highly available applications. Curated portal access maps directly to programmatic infrastructure control and cloud service catalogs.
|
||||
### High Availability
|
||||
|
||||
#### Architecture
|
||||
@@ -261,7 +66,7 @@
|
||||
- **(2026)** [thenewstack.io: Configuring the Google Cloud Platform for High Availability](https://thenewstack.io/configuring-for-high-availability-in-google-cloud-platform) <span class='md-tag md-tag--critical'>[ADVANCED LEVEL]</span> <span class='md-tag md-tag--info'>[COMMUNITY-TOOL]</span> <span class='md-tag md-tag--secondary'>[GUIDE]</span> — Architectural playbook on designing high-availability systems on GCP, describing regional failovers, managed instance groups, cloud load balancing strategies, and automated scaling policies.
|
||||
### Microservices
|
||||
|
||||
#### Google Cloud (1)
|
||||
#### Google Cloud
|
||||
|
||||
- **(2026)** [cloud.google.com: Microservices architecture on Google Cloud](https://cloud.google.com/blog/topics/developers-practitioners/microservices-architecture-google-cloud) <span class='md-tag md-tag--critical'>[ADVANCED LEVEL]</span> <span class='md-tag md-tag--info'>[COMMUNITY-TOOL]</span> <span class='md-tag md-tag--secondary'>[GUIDE]</span> — Architect's blueprint for designing, deploying, and managing microservices topologies on GCP using GKE, Cloud Run, API gateways, Cloud SQL, and service mesh frameworks like Anthos Service Mesh.
|
||||
### Networking
|
||||
@@ -269,30 +74,11 @@
|
||||
#### Private Service Connect
|
||||
|
||||
- **(2026)** [cloud.google.com: Consume services faster, privately and securely - Private Service Connect now in GA](https://cloud.google.com/blog/products/networking/private-service-connect-is-now-generally-available) <span class='md-tag md-tag--critical'>[ADVANCED LEVEL]</span> <span class='md-tag md-tag--info'>[COMMUNITY-TOOL]</span> — Highlights the GA release of Google Cloud Private Service Connect, allowing private endpoint connections across separate GCP networks, projects, and SaaS ecosystems over a secure Google backbone without complex VPC peering.
|
||||
#### VPC VPN
|
||||
|
||||
- **(2026)** [cloud.google.com: VPN network overview](https://docs.cloud.google.com/vpc/docs/vpc) <span class='md-tag md-tag--critical'>[ADVANCED LEVEL]</span> <span class='md-tag md-tag--primary'>[DOCUMENTATION]</span> <span class='md-tag md-tag--info'>[COMMUNITY-TOOL]</span> — Reference documentation on GCP Cloud VPN network architecture. Highlights dynamic routing via Cloud Router, high-availability setups with IPSec protocols, and encrypted on-premises-to-cloud integrations.
|
||||
### Observability
|
||||
|
||||
#### Google Cloud Operations
|
||||
|
||||
- **(2026)** [cloud.google.com: Monitor and troubleshoot your VMs in context for faster resolution](https://cloud.google.com/blog/products/operations/better-access-to-observability-data-for-virtual-machines) <span class='md-tag md-tag--info'>[COMMUNITY-TOOL]</span> — Introduces contextual VM troubleshooting features in Google Cloud Operations (formerly Stackdriver), allowing developers to analyze metrics, traces, and system logs in unified dashboards to lower MTTR.
|
||||
### Public Cloud
|
||||
|
||||
#### Analysis
|
||||
|
||||
- **(2026)** [kinsta.com: Top 7 Advantages of Choosing Google Cloud Hosting](https://kinsta.com/blog/cloud-platform-for-developers) <span class='md-tag md-tag--info'>[COMMUNITY-TOOL]</span> — Details key structural advantages of hosting sites and microservices on GCP, highlighting performance perks, live VM migration capabilities, cost-effective pricing models, and private global networks.
|
||||
#### Google Cloud (2)
|
||||
#### Google Cloud (1)
|
||||
|
||||
- **(2026)** [cloud.google.com](https://cloud.google.com) <span class='md-tag md-tag--critical'>[ADVANCED LEVEL]</span> <span class='md-tag md-tag--info'>[COMMUNITY-TOOL]</span> — Google Cloud Platform (GCP) official portal. It features premium tier global networking, fully managed Kubernetes engines (GKE), advanced analytical and machine learning toolsets, and highly scalable data storage.
|
||||
#### Reference Sheets
|
||||
|
||||
- **(2026)** [cloud.google.com: 5 cheat sheets to help you get started on your Google Cloud journey 🌟](https://cloud.google.com/blog/products/gcp/5-google-cloud-product-cheat-sheets-2021) <span class='md-tag md-tag--info'>[COMMUNITY-TOOL]</span> <span class='md-tag md-tag--secondary'>[GUIDE]</span> — A visual curation of visual decision trees and cheat sheets for GCP products. Useful for quick architecture mapping of compute options, database services, and hybrid setups.
|
||||
#### Training
|
||||
|
||||
- **(2026)** [whizlabs.com: Introduction To Google Cloud Platform](https://www.whizlabs.com/blog/google-cloud-platform) <span class='md-tag md-tag--info'>[COMMUNITY-TOOL]</span> — A comprehensive introductory article mapping out GCP foundational structures, virtual machine instances, VPC networking, storage classes, and certification paths for beginners.
|
||||
- **(2026)** [cloud.google.com: Training more than 40 million new people on Google Cloud skills](https://cloud.google.com/blog/topics/training-certifications/google-cloud-to-train-more-than-40-million-with-cloud-skills) <span class='md-tag md-tag--info'>[COMMUNITY-TOOL]</span> — Overview of Google Cloud's strategic global training initiative, aiming to upskill developers via Google Cloud Skills Boost, interactive learning labs, and modular path certifications.
|
||||
- **(2026)** [cloud.google.com: How to get started with Google Cloud: Introducing our new learning hub and learning benefits for Innovators](https://cloud.google.com/blog/topics/training-certifications/new-learning-hub-and-benefits-for-google-cloud-innovators) <span class='md-tag md-tag--info'>[COMMUNITY-TOOL]</span> — Announces Google Cloud's community-driven learning hub for Innovators, detailing access to free learning resources, interactive codelabs, live expert sessions, and peer-to-peer networking.
|
||||
### Security
|
||||
|
||||
#### IAM
|
||||
@@ -301,9 +87,6 @@
|
||||
#### PKI
|
||||
|
||||
- **(2026)** [infoq.com: Google Releases Its Certificate Authority Service into General Availability](https://www.infoq.com/news/2021/08/google-cloud-cas-ga) <span class='md-tag md-tag--critical'>[ADVANCED LEVEL]</span> <span class='md-tag md-tag--info'>[COMMUNITY-TOOL]</span> — Detailing GCP's Certificate Authority Service (CAS) GA release, a highly scalable, fully managed PKI engine designed to simplify CA deployment and cryptographic management for secure microservice communication.
|
||||
#### Platform Threat Intelligence
|
||||
|
||||
- **(2026)** [zdnet.com: Google Cloud rolls out new security tools as threat landscape heats up](https://www.zdnet.com/article/google-cloud-rolls-out-new-security-tools-as-threat-landscape-heats-up) <span class='md-tag md-tag--critical'>[ADVANCED LEVEL]</span> <span class='md-tag md-tag--info'>[COMMUNITY-TOOL]</span> — Analysis of Google Cloud's enhanced security integrations, detailing updates to Security Command Center, zero-trust tools, and threat protection measures to counter cloud-targeted attacks.
|
||||
#### Secrets Management
|
||||
|
||||
- **(2026)** [techradar.com: Google Cloud is making it easier for developers to smuggle ‘secrets’ in their code](https://www.techradar.com/news/google-cloud-is-making-it-easier-for-developers-to-smuggle-secrets-in-their-code) <span class='md-tag md-tag--info'>[COMMUNITY-TOOL]</span> — Highlights GCP developer platform updates aimed at facilitating secure, automated secret consumption in source codes, eliminating plain-text secrets risk using native IDE-to-Secret Manager integrations.
|
||||
@@ -316,39 +99,6 @@
|
||||
#### VPC Networking
|
||||
|
||||
- **(2021)** [Cloud Functions, meet VPC functionality](https://cloud.google.com/blog/products/serverless/learn-how-to-use-advanced-vpc-functionality-with-your-cloud-functions) <span class='md-tag md-tag--primary'>[DOCUMENTATION]</span> <span class='md-tag md-tag--info'>[COMMUNITY-TOOL]</span> — Explains how Google Cloud Functions natively interact with VPC resources using Serverless VPC Access connectors. This integration permits secure, private database queries, internal API routing, and system execution behind private networks without public IP exposure.
|
||||
## Cloud Providers
|
||||
|
||||
### GCP
|
||||
|
||||
#### Product Catalog (1)
|
||||
|
||||
- **(2026)** [**googlecloudcheatsheet.withgoogle.com: Google Cloud Developer cheat sheet**](https://cloud.google.com/products) <span class='md-tag md-tag--warning'>[HTML CONTENT]</span> <span class='md-tag md-tag--primary'>[DOCUMENTATION]</span> 🌟🌟🌟🌟 <span class='md-tag md-tag--success'>[ENTERPRISE-STABLE]</span> — Google's official product portal mapping its enterprise suite of cloud computing, data analytics, and machine learning services. Serves as a primary reference for system architects evaluating Google's managed offerings, providing documentation and pathing for product integration.
|
||||
### Google Kubernetes Engine GKE
|
||||
|
||||
#### GKE Core
|
||||
|
||||
- **(2025)** [Google Kubernetes Engine](https://cloud.google.com/kubernetes-engine) <span class='md-tag md-tag--warning'>[N/A CONTENT]</span> <span class='md-tag md-tag--critical'>[ADVANCED LEVEL]</span> <span class='md-tag md-tag--primary'>[DOCUMENTATION]</span> <span class='md-tag md-tag--info'>[COMMUNITY-TOOL]</span> — Core landing documentation for Google Kubernetes Engine (GKE), highlighting GKE's industry-standard capabilities. Specifically focuses on setting up node pools with custom kernel parameters, eliminating post-bootstrap script workarounds. Provides the baseline reference for standard-setting enterprise container management.
|
||||
## Cloud Strategy
|
||||
|
||||
### Service Mapping
|
||||
|
||||
#### GCP Translation
|
||||
|
||||
- **(2026)** [cloud.google.com: Compare AWS and Azure services to Google Cloud](https://docs.cloud.google.com/docs/get-started/aws-azure-gcp-service-comparison) <span class='md-tag md-tag--info'>[COMMUNITY-TOOL]</span> — Google Cloud's official engineering guide to translating AWS and Azure infrastructure paradigms into GCP equivalents. It describes VPC networks, database engines, and container services. Live grounding establishes its role as the industry-standard translation manual for cross-cloud architects.
|
||||
## Cluster Management
|
||||
|
||||
### GitOps
|
||||
|
||||
#### Config Sync
|
||||
|
||||
- **(2025)** [Config Sync](https://docs.cloud.google.com/kubernetes-engine/config-sync/docs/overview) <span class='md-tag md-tag--warning'>[GO CONTENT]</span> <span class='md-tag md-tag--critical'>[ADVANCED LEVEL]</span> <span class='md-tag md-tag--info'>[COMMUNITY-TOOL]</span> — Config Sync is Google Cloud's GitOps-native configuration engine optimized for Anthos and GKE clusters. It securely syncs cluster state configurations and namespace boundaries directly from trusted Git, OCI, or Helm registries with continuous validation.
|
||||
## Containers and Orchestration
|
||||
|
||||
### GitOps (1)
|
||||
|
||||
#### Config Connector
|
||||
|
||||
- **(2020)** [==github.com/GoogleCloudPlatform/k8s-config-connector: GCP Config Connector==](https://github.com/GoogleCloudPlatform/k8s-config-connector) <span class='md-tag md-tag--info'>⭐ 1042</span> <svg class="v2-sparkline" width="50" height="15" viewBox="0 0 50 15" style="vertical-align: middle; display: inline-block; margin-left: 6px;" title="Activity Trend"><defs><linearGradient id="spark-grad-fec39680" x1="0" y1="0" x2="1" y2="0"><stop offset="0%" stop-color="rgba(34, 211, 238, 0.2)" /><stop offset="100%" stop-color="var(--md-accent-fg-color)" /></linearGradient></defs><path class="v2-sparkline-path" d="M 0 13 L 10 5 L 20 7 L 30 8 L 40 10 L 50 5" fill="none" stroke="url(#spark-grad-fec39680)" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round" /><circle cx="50" cy="5" r="2" fill="var(--md-accent-fg-color)" /></svg> <span class='md-tag md-tag--warning'>[GO CONTENT]</span> <span class='md-tag md-tag--critical'>[ADVANCED LEVEL]</span> 🌟🌟🌟🌟🌟 <span class='md-tag md-tag--success'>[DE FACTO STANDARD]</span> — Config Connector is a Kubernetes Custom Resource Definition (CRD) controller that allows operators to manage Google Cloud resources natively as if they were standard Kubernetes objects. It bridges GitOps configurations with physical cloud infrastructure provisioning.
|
||||
## DevOps and Delivery
|
||||
|
||||
### CICD
|
||||
@@ -370,19 +120,6 @@
|
||||
#### Industry Assessment
|
||||
|
||||
- **(2022)** [infoq.com: Google's Managed Continuous Delivery Service for Kubernetes Moves to GA](https://www.infoq.com/news/2022/02/google-cloud-deploy) <span class='md-tag md-tag--critical'>[ADVANCED LEVEL]</span> <span class='md-tag md-tag--info'>[COMMUNITY-TOOL]</span> — A technical industry overview reporting on Google Cloud Deploy’s general availability. Analyzes its competitive positioning against GitOps tools (ArgoCD, Flux) and how it simplifies CI/CD platform engineering for cloud-native enterprises.
|
||||
### Developer Tools (1)
|
||||
|
||||
#### CLI Automation
|
||||
|
||||
- **(2020)** [kelseyhightower/cmd-tutorial](https://github.com/kelseyhightower/cmd-tutorial) <span class='md-tag md-tag--warning'>[SHELL CONTENT]</span> <span class='md-tag md-tag--info'>[COMMUNITY-TOOL]</span> — An educational reference by Kelsey Hightower showcasing CLI orchestration, process controls, and shell command integration. Provides idiomatic patterns for system administrators and automation engineers writing resilient command wrapper scripts.
|
||||
#### CLI References
|
||||
|
||||
- **(2021)** [cloud.google.com: The gcloud tool cheat sheet](https://docs.cloud.google.com/sdk/docs/cheatsheet?hl=en) <span class='md-tag md-tag--primary'>[DOCUMENTATION]</span> <span class='md-tag md-tag--info'>[COMMUNITY-TOOL]</span> — A dense CLI reference guide outlining crucial command groupings for managing IAM, Compute Engine, GKE clusters, and networking components. Provides syntax, flag paradigms, and programmatic output formatting tricks.
|
||||
### Infrastructure as Code
|
||||
|
||||
#### Terraform
|
||||
|
||||
- **(2021)** [cloud.google.com: Declarative Export. Build your perfect Google Cloud infrastructure using Terraform and the gcloud CLI](https://cloud.google.com/blog/products/application-development/google-cloud-cli-declarative-export-preview) <span class='md-tag md-tag--primary'>[DOCUMENTATION]</span> <span class='md-tag md-tag--info'>[COMMUNITY-TOOL]</span> — Outlines the gcloud CLI declarative export feature, allowing operators to automatically translate active GCP live resource states into production-ready Terraform configurations or Kubernetes Config Connector manifests.
|
||||
## DevSecOps
|
||||
|
||||
### CICD Pipelines (1)
|
||||
@@ -404,12 +141,6 @@
|
||||
#### Ingress
|
||||
|
||||
- **(2020)** [itnext.io: Ingress for Anthos — Multi-cluster Ingress and Global Service Load Balancing](https://itnext.io/ingress-for-anthos-multi-cluster-ingress-and-global-service-load-balancing-c56c57b97e82) <span class='md-tag md-tag--critical'>[ADVANCED LEVEL]</span> <span class='md-tag md-tag--info'>[COMMUNITY-TOOL]</span> — Examines the technical design of Multi-cluster Ingress (MCI) on Anthos. Illustrates how a unified global load balancer acts as a single endpoint, intelligently routing traffic to healthy microservice clusters distributed globally based on geographical proximity and backend capacity.
|
||||
#### Multi-Cloud Support
|
||||
|
||||
- **(2021)** [cloud.google.com: Anthos makes multi-cloud easier with new API, support for Azure](https://cloud.google.com/blog/products/containers-kubernetes/google-cloud-anthos-multicloud-api-and-gke-on-azure-ga) <span class='md-tag md-tag--critical'>[ADVANCED LEVEL]</span> <span class='md-tag md-tag--primary'>[DOCUMENTATION]</span> <span class='md-tag md-tag--info'>[COMMUNITY-TOOL]</span> — Details the operational release of GKE on Microsoft Azure and the standardized Multi-cloud API. Analyzes how GKE clusters on AWS and Azure are provisioned, updated, and consolidated using unified control plane paradigms.
|
||||
#### Multi-Cluster
|
||||
|
||||
- **(2020)** [itnext.io: Anthos — Multi-cluster Management](https://itnext.io/anthos-multi-cluster-management-aa6f2c03120d) <span class='md-tag md-tag--critical'>[ADVANCED LEVEL]</span> <span class='md-tag md-tag--info'>[COMMUNITY-TOOL]</span> — Investigates the operational mechanics of Anthos multi-cluster registration, hub-and-spoke configuration, and telemetry collection. Shows how operators can deploy, manage, and monitor unified GKE environments spanning physical data centers and hyperscalers.
|
||||
#### Strategic Guide
|
||||
|
||||
- **(2019)** [Everything You Want To Know About Anthos - Google's Hybrid And Multi-Cloud Platform](https://www.forbes.com/sites/janakirammsv/2019/04/14/everything-you-want-to-know-about-anthos-googles-hybrid-and-multi-cloud-platform) <span class='md-tag md-tag--info'>[COMMUNITY-TOOL]</span> — A strategic market review analyzing Google’s motivations behind launching Anthos. Describes how Anthos decouples Kubernetes management from specific underlying cloud fabrics to standardize operations, deployment, and service meshes across disparate architectures.
|
||||
@@ -418,34 +149,6 @@
|
||||
- **(2020)** [Bringing Kubernetes’ goodness to Windows Server apps with Anthos](https://cloud.google.com/blog/topics/anthos/windows-server-support-comes-to-anthos-on-prem) <span class='md-tag md-tag--critical'>[ADVANCED LEVEL]</span> <span class='md-tag md-tag--critical'>[LEGACY]</span> — Explores Anthos’ platform integration of Windows Server containers. Outlines the technical processes of running, orchestrating, and scaling legacy Microsoft .NET and IIS-based web workloads alongside modern Linux microservices in hybrid GKE clusters.
|
||||
## Networking and Security
|
||||
|
||||
### Content Delivery
|
||||
|
||||
#### Caching
|
||||
|
||||
- **(2021)** [cloud.google.com: What is Cloud CDN and how does it work?](https://cloud.google.com/blog/topics/developers-practitioners/what-cloud-cdn-and-how-does-it-work) <span class='md-tag md-tag--primary'>[DOCUMENTATION]</span> <span class='md-tag md-tag--info'>[COMMUNITY-TOOL]</span> — Decodes Cloud CDN's architectural operations, explaining how cache virtualization at Google’s global edge locations minimizes latency and back-end server load. Highlights integration with HTTP(S) load balancers, SSL certificate offloading, and dynamic compression.
|
||||
### Core Services
|
||||
|
||||
#### DNS
|
||||
|
||||
- **(2021)** [cloud.google.com: Cloud DNS explained!](https://cloud.google.com/blog/topics/developers-practitioners/cloud-dns-explained) <span class='md-tag md-tag--primary'>[DOCUMENTATION]</span> <span class='md-tag md-tag--info'>[COMMUNITY-TOOL]</span> — A technical breakdown of Cloud DNS, Google Cloud's high-performance, resilient, global Domain Name System. Details private DNS zones, split-horizon configurations, and integration with VPC networks, which together ensure robust service discovery within enterprise infrastructures.
|
||||
### IAM (1)
|
||||
|
||||
#### Federated Identity
|
||||
|
||||
- **(2021)** [cloud.google.com: Enabling keyless authentication from GitHub Actions](https://cloud.google.com/blog/products/identity-security/enabling-keyless-authentication-from-github-actions) <span class='md-tag md-tag--critical'>[ADVANCED LEVEL]</span> <span class='md-tag md-tag--primary'>[DOCUMENTATION]</span> <span class='md-tag md-tag--info'>[COMMUNITY-TOOL]</span> — Details the architectural implementation of Workload Identity Federation to eliminate hardcoded service account keys within GitHub Actions CI/CD workflows. By leveraging OpenID Connect (OIDC), it establishes a secure, temporary trust relationship between external platforms and GCP.
|
||||
### Identity and Access
|
||||
|
||||
#### Database Proxy
|
||||
|
||||
- **(2021)** [==db-auth-gateway==](https://github.com/kloeckner-i/db-auth-gateway) <span class='md-tag md-tag--info'>⭐ 26</span> <svg class="v2-sparkline" width="50" height="15" viewBox="0 0 50 15" style="vertical-align: middle; display: inline-block; margin-left: 6px;" title="Activity Trend"><defs><linearGradient id="spark-grad-cdf285ba" x1="0" y1="0" x2="1" y2="0"><stop offset="0%" stop-color="rgba(34, 211, 238, 0.2)" /><stop offset="100%" stop-color="var(--md-accent-fg-color)" /></linearGradient></defs><path class="v2-sparkline-path" d="M 0 12 L 10 2 L 20 3 L 30 7 L 40 3 L 50 2" fill="none" stroke="url(#spark-grad-cdf285ba)" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round" /><circle cx="50" cy="2" r="2" fill="var(--md-accent-fg-color)" /></svg> <span class='md-tag md-tag--warning'>[GO CONTENT]</span> <span class='md-tag md-tag--critical'>[ADVANCED LEVEL]</span> 🌟🌟🌟🌟🌟 <span class='md-tag md-tag--success'>[DE FACTO STANDARD]</span> — An open-source authentication gateway proxy designed to facilitate secure, IAM-mediated database connections. Minimizes credential sprawl by mapping incoming traffic identities directly to modern database authorization schemas.
|
||||
### Infrastructure
|
||||
|
||||
#### Fundamentals
|
||||
|
||||
- **(2020)** [networkmanagementsoftware.com: Google Cloud Platform (GCP) Networking Fundamentals](https://www.networkmanagementsoftware.com/google-cloud-platform-gcp-networking-fundamentals) <span class='md-tag md-tag--info'>[COMMUNITY-TOOL]</span> — A deep dive into core networking primitives within GCP, mapping subnets, firewall rules, routes, and IP address management. Provides clear mental models for engineering reliable, segmented network boundaries for enterprise topologies.
|
||||
#### VPC
|
||||
|
||||
- **(2021)** [cloud.google.com: Google Cloud Networking overview 🌟🌟](https://cloud.google.com/blog/topics/developers-practitioners/google-cloud-networking-overview) <span class='md-tag md-tag--primary'>[DOCUMENTATION]</span> <span class='md-tag md-tag--info'>[COMMUNITY-TOOL]</span> — A comprehensive baseline analysis of GCP's Software-Defined Networking (SDN) topology. Focuses on Global VPCs, subnets, peering, Cloud Interconnect, and private service access networks, highlighting Google’s unique global fiber infrastructure.
|
||||
### Service Discovery
|
||||
|
||||
#### Registry
|
||||
@@ -456,24 +159,14 @@
|
||||
#### Traffic Management
|
||||
|
||||
- **(2021)** [cloud.google.com: Traffic Director explained!](https://cloud.google.com/blog/topics/developers-practitioners/traffic-director-explained) <span class='md-tag md-tag--critical'>[ADVANCED LEVEL]</span> <span class='md-tag md-tag--primary'>[DOCUMENTATION]</span> <span class='md-tag md-tag--info'>[COMMUNITY-TOOL]</span> — Examines Google Cloud's fully managed traffic control plane for service meshes, Traffic Director (supporting Envoy-based proxies). It details how the platform delivers global load balancing, health checking, and advanced traffic steering patterns across multi-region containerized and VM-based workloads.
|
||||
### Threat Detection
|
||||
|
||||
#### Intrusion Detection
|
||||
|
||||
- **(2021)** [cloud.google.com: Cloud IDS for network-based threat detection is now generally available](https://cloud.google.com/blog/products/identity-security/announcing-general-availability-of-google-cloud-ids) <span class='md-tag md-tag--critical'>[ADVANCED LEVEL]</span> <span class='md-tag md-tag--primary'>[DOCUMENTATION]</span> <span class='md-tag md-tag--info'>[COMMUNITY-TOOL]</span> — Details Cloud IDS (Intrusion Detection System), a managed service delivering deep packet inspection and network threat protection powered by Palo Alto Networks. It intercepts and monitors VPC traffic mirroring to detect malware, exploits, and anomalous behavior.
|
||||
### Traffic Management (1)
|
||||
|
||||
#### Load Balancing
|
||||
|
||||
- **(2021)** [cloud.google.com: What is Cloud Load Balancing?](https://cloud.google.com/blog/topics/developers-practitioners/what-cloud-load-balancing) <span class='md-tag md-tag--primary'>[DOCUMENTATION]</span> <span class='md-tag md-tag--info'>[COMMUNITY-TOOL]</span> — Explains the design of GCP's global, distributed Anycast Cloud Load Balancing system. Illustrates how Layer 4 and Layer 7 load balancers distribute traffic dynamically across regions with minimal latency, auto-scaling up to millions of requests per second.
|
||||
## Public Cloud Providers
|
||||
|
||||
### GCP (1)
|
||||
|
||||
#### Enterprise Platform
|
||||
|
||||
- **(2026)** [github.com/GoogleCloudPlatform](https://github.com/GoogleCloudPlatform) <span class='md-tag md-tag--warning'>[MULTI CONTENT]</span> <span class='md-tag md-tag--critical'>[ADVANCED LEVEL]</span> <span class='md-tag md-tag--info'>[COMMUNITY-TOOL]</span> — The master landing organization for Google Cloud Platform's open-source projects, APIs, and CLI utilities. Holds structural frameworks, SDKs, and enterprise infrastructure design tools.
|
||||
|
||||
---
|
||||
💡 **Explore Related:** [AWS Pricing](./aws-pricing.md) | [AWS Spain](./aws-spain.md) | [Azure](./azure.md)
|
||||
💡 **Explore Related:** [Edge Computing](./edge-computing.md) | [Oraclecloud](./oraclecloud.md) | [AWS](./aws.md)
|
||||
|
||||
🔗 **See Also:** [About](./about.md) | [Postman](./postman.md)
|
||||
|
||||
|
||||