From e9222460d10a9024dff3c8a2164fc1cc463c4b53 Mon Sep 17 00:00:00 2001 From: Nubenetes Bot Date: Sun, 17 May 2026 12:05:29 +0200 Subject: [PATCH] feat(ai): implement O'Reilly-style knowledge architecture and microservices extraction --- GEMINI.md | 10 +- README.md | 21 ++-- data/special_assets.yaml | 6 +- src/agentic_curator.py | 6 +- src/v2_optimizer.py | 230 +++++++++++++++++++++------------------ 5 files changed, 150 insertions(+), 123 deletions(-) diff --git a/GEMINI.md b/GEMINI.md index d300c726..17b4f2c2 100644 --- a/GEMINI.md +++ b/GEMINI.md @@ -73,10 +73,12 @@ This file contains the accumulated instructions and long-term vision for the aut - **High-Precision Reorganization (V1)**: These files MUST use nested semantic grouping (## and ###) to organize links without ever deleting technically valid content. - **Exhaustive Inclusion (V2)**: Unlike standard categories, V2 pages for Special Assets MUST include 100% of the ALIVE links from V1. - **AI Curation Discovery**: The discovery engine MUST actively search for new high-quality curation sources (e.g., "Awesome" repos) and suggest them for inclusion in `curation_sources.yaml`. -28. **Zero-to-Hero V2 Architecture**: The V2 Portal MUST be structured as a learning journey: - - **Complexity Hierarchy**: Resources MUST be grouped by level: Fundamentals -> Intermediate -> Advanced -> Architect. - - **Strategic Dimensions**: The "AI and Artificial Intelligence" dimension is the primary entry point for agentic innovation. Dimension naming MUST prioritize industry-standard terms over internal terminology. - - **Clickable Navigational Maps**: Every V2 page MUST include a Table of Contents (TOC) with nested anchors for all complexity levels. +28. **Sophisticated V2 Knowledge Architecture**: The V2 Portal MUST be structured like an advanced O'Reilly technical book: + - **Contextual Hierarchy**: Resources MUST NOT be flat lists. They must be organized into a sophisticated hierarchy of nested sections (##) and subsections (###) based on technical areas, topics, and subtopics. + - **Structured Learning**: The organization must facilitate knowledge assimilation, moving from foundations to advanced implementation details in a logical, ordered sequence. + - **Dynamic Indexing**: Every V2 page MUST include a Table of Contents (TOC) with clickable anchors for all technical sub-sections. + - **AI Dimension Naming**: Prioritize industry-standard terms (e.g., "AI and Artificial Intelligence" instead of internal jargon) for top-level navigation. + - **Content Extraction**: High-value sub-topics may be extracted into dedicated documents (e.g., "Microservices" content extracted from `introduction.md` into `microservices.md`) to maintain high-density focus. ## 🛠️ Structural Evolution & Navigation ... diff --git a/README.md b/README.md index 9c16cd80..798fc4a4 100644 --- a/README.md +++ b/README.md @@ -53,7 +53,7 @@ 12. [12. Developer Experience and VSCode Setup](#12-developer-experience-and-vscode-setup) 14. [14. Special Assets and Learning Paths](#14-special-assets-and-learning-paths) * [14.1. Special Assets Management](#141-special-assets-management) - * [14.2. Zero-to-Hero Learning Architecture](#142-zero-to-hero-learning-architecture) + * [14.2. O'Reilly-style Knowledge Architecture](#142-oreilly-style-knowledge-architecture) * [12.1. Extension Recommendations](#121-extension-recommendations) * [12.2. Recommended settings.json](#122-recommended-settingsjson) 13. [13. Repository Inventory and Configuration](#13-repository-inventory-and-configuration) @@ -673,17 +673,16 @@ Nubenetes prioritizes high-value technical documents through a specialized prese ### 📚 Special Assets Management Certain files are designated as **Special Assets** (defined in [`data/special_assets.yaml`](data/special_assets.yaml)) due to their foundational importance. These include: -- **Introduction & Fundamentals**: Specialized grouping to ensure a perfect "Day 0" experience. -- **YAML & JSON Ecosystem**: Exhaustive technical references for configuration languages. +- **Introduction and Fundamentals**: High-impact fundamental selection for V2, with 100% preservation in V1. +- **Microservices Ecosystem**: A dedicated V2 document (`microservices.md`) extracted from the introduction to maintain architectural focus. +- **YAML and JSON Ecosystem**: Exhaustive technical references for configuration languages. - **Awesome Repositories**: Preserved curation lists that act as gateways to specialized sub-ecosystems. **Rules of Engagement:** -1. **Exhaustive V2 Inclusion**: 100% of ALIVE links from these V1 files are migrated to the V2 Elite portal, bypassing standard impact filters. -2. **High-Precision Grouping**: AI agents use nested hierarchies (Sections & Subsections) to organize these files without losing any technically valid reference. +1. **High-Precision Grouping**: AI agents use nested hierarchies (Areas -> Topics -> Subtopics) to organize these files without losing any technically valid reference, following a **Professional Technical Book** (O'Reilly style) structure. +2. **Elite Curation**: For the V2 Portal, `introduction.md` undergoes a specialized "Elite selection" (Impact ≥ 4) to ensure a high-density entry point for global users. -### 🎓 Zero-to-Hero Learning Architecture -The V2 Portal is structured as an educational journey rather than a flat list. Resources are programmatically classified into four expertise tiers: -- **Fundamentals**: Core concepts and "Getting Started" material. -- **Intermediate**: Practical implementations and standard tooling. -- **Advanced**: Performance optimization and complex technical internals. -- **Architect**: System design, trade-offs, and long-term strategic direction. +### 🎓 O'Reilly-style Knowledge Architecture +The V2 Portal is structured as a sophisticated technical reference guide. Resources are programmatically classified and grouped by technical topics and subtopics, transforming the portal into a structured educational journey for Cloud Native engineering. +- **Structured Assimilation**: Information is ordered sections-by-section to facilitate learning from foundational theory to advanced implementation. +- **Contextual Hierarchy**: Every page features a clickable Table of Contents (TOC) with nested anchors for precise navigation across all technical sub-domains. diff --git a/data/special_assets.yaml b/data/special_assets.yaml index ef34592c..cffe4884 100644 --- a/data/special_assets.yaml +++ b/data/special_assets.yaml @@ -13,9 +13,9 @@ special_assets: keywords: ["yaml", "json", "schema"] - file: "introduction.md" - v1_rule: "Semantic clustering: Group by 'Fundamentals', 'Getting Started', and 'Advanced Concepts'." - v2_rule: "Elite curated view: Highlight only high-impact fundamental resources." - keywords: ["introduction", "getting started", "fundamentals"] + v1_rule: "Semantic clustering: Group by technical sub-topics. Preserve 100% of links." + v2_rule: "Elite curated selection (Impact >= 4). EXTRACT all Microservices-related links into a new dedicated V2 document: 'microservices.md'." + keywords: ["introduction", "getting started", "fundamentals", "microservices"] # Navigation Renaming dimension_renaming: diff --git a/src/agentic_curator.py b/src/agentic_curator.py index a235e3ab..9adf02f1 100644 --- a/src/agentic_curator.py +++ b/src/agentic_curator.py @@ -332,8 +332,10 @@ class AgenticCurator: log_event(f" [!] REORGANIZING: {file} ({'Special' if is_special else 'Standard'})") depth_instruction = ( - "SOPHISTICATED HIERARCHY: Create nested sections (##) and subsections (###). " - "Group links by technical theme. Maintain all existing links. No deletions." + "SOPHISTICATED O'REILLY HIERARCHY: Create nested sections (##) and subsections (###). " + "Group links by technical AREAS, TOPICS, and SUBTOPICS (e.g. 'Foundations' -> 'Container Orchestration'). " + "The structure must facilitate knowledge assimilation like a professional technical book. " + "Ensure every valid link is preserved. Maintain professional titles." if is_special else "Group into logical sections (##)." ) diff --git a/src/v2_optimizer.py b/src/v2_optimizer.py index 01b8f487..9640bdb4 100644 --- a/src/v2_optimizer.py +++ b/src/v2_optimizer.py @@ -36,19 +36,19 @@ class V2VisionEngine: } self.library_criteria = ( - "You are a Senior Technical Librarian and Architect in 2026. Your mission is to build a high-density, professional reference library.\n" - "PHASE 1: TECHNICAL PRESERVATION (HIGH INCLUSIVITY)\n" - "- KEEP >90% of technical resources.\n" - "PHASE 2: SOPHISTICATED SYNTHESIS & DATING\n" - "- Extract precise PUBLICATION DATE (YYYY-MM-DD or YYYY).\n" - "- Detect source content LANGUAGE.\n" - "- Identify RESOURCE_TYPE and complexity LEVEL.\n" - "PHASE 3: ZERO-TO-HERO CLASSIFICATION\n" - "- Categorize into: 'Fundamentals', 'Intermediate', 'Advanced', or 'Architect' level.\n" - "- For special curation lists (e.g. Awesome repos), identify the primary curation topic.\n" - "PHASE 4: MANDATORY DESCRIPTIONS (V1 PRIORITY)\n" - "- If 'Current Desc' is empty or too short, generate a professional 1-2 sentence summary.\n" - "- Style: Technical, neutral, and informative. Language: English only.\n" + "You are a Senior Technical Content Architect in 2026. Your mission is to organize a high-density technical reference portal " + "with the structure and logical flow of an advanced O'Reilly technical book.\n" + "PHASE 1: TECHNICAL PRESERVATION & CURATION\n" + "- KEEP >90% of technical resources (except for 'introduction.md' where only high-impact links are kept).\n" + "PHASE 2: SOPHISTICATED HIERARCHICAL CLASSIFICATION\n" + "- Analyze the deep context of each resource to identify its TECHNICAL AREA (e.g., 'Storage Protocols', 'Observability Patterns').\n" + "- Identify a TOPIC and SUBTOPIC for precise nested grouping.\n" + "- For 'introduction.md', identify links related to MICROSERVICES for extraction.\n" + "PHASE 3: KNOWLEDGE ASSIMILATION FLOW\n" + "- Order topics to facilitate a structured learning journey: from architectural foundations to advanced engineering internals.\n" + "- Assign QUALITY level (0-5 stars) and complexity LEVEL.\n" + "PHASE 4: MANDATORY DESCRIPTIONS\n" + "- If 'Current Desc' is empty, generate a professional 1-2 sentence summary. Style: O'Reilly technical, neutral, and informative.\n" ) self.inventory = self._load_inventory() self.structure_map = self._load_structure_map() @@ -314,7 +314,7 @@ class V2VisionEngine: prompt = ( f"{self.library_criteria}\n" - "Respond ONLY with a JSON object: {\"results\": [{\"idx\": int, \"year\": \"YYYY\", \"stars\": 0-5, \"is_video\": bool, \"tag\": \"[TAG]\", \"summary\": \"1-2 sentences description\", \"language\": \"...\", \"type\": \"...\", \"level\": \"Fundamentals|Intermediate|Advanced|Architect\"}, ...]}\n\n" + "Respond ONLY with a JSON object: {\"results\": [{\"idx\": int, \"year\": \"YYYY\", \"stars\": 0-5, \"is_video\": bool, \"tag\": \"[TAG]\", \"summary\": \"...\", \"language\": \"...\", \"type\": \"...\", \"level\": \"...\", \"area\": \"...\", \"topic\": \"...\", \"subtopic\": \"...\", \"is_microservice\": bool}, ...]}\n\n" "LINKS:\n" + "\n".join([f"{idx}. {l['title']} ({l['url']}) - Desc: {l['description'][:60]}" for idx, l in enumerate(batch)]) ) @@ -330,7 +330,7 @@ class V2VisionEngine: norm_url = normalize_url(item["url"]) old_tag = self.inventory.get(norm_url, {}).get("tag") - # SPECIAL ASSET BYPASS: If file is special, force 5 stars or preservation + # SPECIAL ASSET BYPASS is_special = item["original_file"] in special_files eval_data = { @@ -341,7 +341,11 @@ class V2VisionEngine: "ai_summary": res.get("summary", ""), "language": res.get("language", "English"), "resource_type": res.get("type", "Reference"), - "complexity": res.get("level", "Intermediate") + "complexity": res.get("level", "Intermediate"), + "area": res.get("area", "General"), + "topic": res.get("topic", "Uncategorized"), + "subtopic": res.get("subtopic", ""), + "is_microservice": bool(res.get("is_microservice", False)) } item.update(eval_data) @@ -370,7 +374,9 @@ class V2VisionEngine: "is_video": item["is_video"], "ai_summary": item["ai_summary"], "language": item["language"], "resource_type": item["resource_type"], "complexity": item["complexity"], "tag": item["tag"], "status": "online", - "original_file": item["original_file"] + "original_file": item["original_file"], "area": item["area"], + "topic": item["topic"], "subtopic": item["subtopic"], + "is_microservice": item["is_microservice"] } if "gh_stars" in item: self.inventory[norm_url]["gh_stars"] = item["gh_stars"] if "gh_updated" in item: self.inventory[norm_url]["gh_updated"] = item["gh_updated"] @@ -435,8 +441,14 @@ class V2VisionEngine: return {} async def _rebuild_structure(self, library_inventory: List[Dict]) -> Dict[str, Dict]: - special_files = [sa["file"] for sa in self.special_assets_rules.get("special_assets", [])] + """ + REBUILD STRUCTURE: O'REILLY TECHNICAL BOOK ARCHITECTURE. + Implements a sophisticated hierarchy: Dimension -> Category -> Topic -> Subtopic. + Handles Special Asset rules and Microservices extraction. + """ + special_rules = {sa["file"]: sa for sa in self.special_assets_rules.get("special_assets", [])} v2_structure = {dim: {"summary": "", "categories": {}} for dim in self.dimensions.keys()} + file_to_dim = {} for dim, files in self.dimensions.items(): for f in files: file_to_dim[f + ".md"] = dim @@ -445,39 +457,62 @@ class V2VisionEngine: orig_file = item.get("original_file", "unknown.md") dim = file_to_dim.get(orig_file, "Architectural Foundations") cat_name = orig_file.replace(".md", "").replace("-", " ").title() - is_special = orig_file in special_files - # Filtering: Keep if stars >= 3 OR if it's a Special Asset - if not is_special and item.get("stars", 0) < 3: + # --- RULE: Microservices Extraction --- + if item.get("is_microservice"): + cat_name = "Microservices" + # If from introduction, move to Foundations dimension, else keep in current + if orig_file == "introduction.md": dim = "Architectural Foundations" + + # --- RULE: Special Asset Handling --- + rule = special_rules.get(orig_file, {}) + is_special = orig_file in special_rules + + # Elite Curation for Introduction + if orig_file == "introduction.md" and item.get("stars", 0) < 4 and not item.get("is_microservice"): + continue + + # General Filtering for V2 + if not is_special and item.get("stars", 0) < 3 and not item.get("is_microservice"): continue + # Hierarchy: Dimension -> Category -> Topic -> Subtopic if cat_name not in v2_structure[dim]["categories"]: - v2_structure[dim]["categories"][cat_name] = { - "Fundamentals": [], "Intermediate": [], "Advanced": [], "Architect": [] - } + v2_structure[dim]["categories"][cat_name] = {} - level = item.get("complexity", "Intermediate") - if level not in v2_structure[dim]["categories"][cat_name]: level = "Intermediate" - v2_structure[dim]["categories"][cat_name][level].append(item) + topic = item.get("topic", "General Concepts") + if topic not in v2_structure[dim]["categories"][cat_name]: + v2_structure[dim]["categories"][cat_name][topic] = {} + + subtopic = item.get("subtopic", "Other Resources") or "General" + if subtopic not in v2_structure[dim]["categories"][cat_name][topic]: + v2_structure[dim]["categories"][cat_name][topic][subtopic] = [] + + v2_structure[dim]["categories"][cat_name][topic][subtopic].append(item) + # Cleanup and Sorting for dim in v2_structure: for cat in list(v2_structure[dim]["categories"].keys()): - has_content = False - for level in v2_structure[dim]["categories"][cat]: - if v2_structure[dim]["categories"][cat][level]: - has_content = True - v2_structure[dim]["categories"][cat][level].sort( + for topic in v2_structure[dim]["categories"][cat]: + for subtopic in v2_structure[dim]["categories"][cat][topic]: + # Sort by Impact and Year + v2_structure[dim]["categories"][cat][topic][subtopic].sort( key=lambda x: (-x.get("stars", 1), -(int(x["year"]) if str(x.get("year", "")).isdigit() else 0)) ) - if not has_content: + + if not v2_structure[dim]["categories"][cat]: del v2_structure[dim]["categories"][cat] else: - # Maintain Executive Summary for Dimension - prompt = f"Write a professional 2026 executive summary for '{dim}'. Focus on high-density value. 1 sentence only." - try: - v2_structure[dim]["summary"] = await call_gemini_with_retry(prompt, response_format="text", prefer_flash=True) - except: - v2_structure[dim]["summary"] = f"Impact-driven reference library for {dim}." + # Update Executive Summary + cache_key = f"INTRO:{dim}" + if cache_key in self.inventory: + v2_structure[dim]["summary"] = self.inventory[cache_key].get("ai_summary") + else: + prompt = f"Write a professional 1-sentence executive summary for the '{dim}' technical dimension." + try: + v2_structure[dim]["summary"] = await call_gemini_with_retry(prompt, response_format="text", prefer_flash=True) + except: + v2_structure[dim]["summary"] = f"Strategic reference library for {dim}." return v2_structure @@ -588,81 +623,70 @@ class V2VisionEngine: slug = dim.lower().replace(" ", "-").replace("&", "and").replace("(", "").replace(")", "").replace(" ", "-") md = f"# {dim}\n\n" md += f"!!! info \"Architectural Context\"\n {content['summary']}\n\n" - + # --- Table of Contents for the Page --- md += "## Table of Contents\n" - for cat in content["categories"].keys(): + for cat, topics in content["categories"].items(): cat_slug = cat.lower().replace(" ", "-") md += f"- [{cat}](#{cat_slug})\n" - for level, level_links in content["categories"][cat].items(): - if level_links: - level_slug = f"{cat_slug}-{level.lower()}" - md += f" - [{level}](#{level_slug})\n" + for topic, subtopics in topics.items(): + topic_slug = f"{cat_slug}-{topic.lower().replace(' ', '-')}" + md += f" - [{topic}](#{topic_slug})\n" md += "\n---\n\n" - for cat, levels in content["categories"].items(): + for cat, topics in content["categories"].items(): cat_slug = cat.lower().replace(" ", "-") md += f"## {cat}\n\n" - for level, links in levels.items(): - if not links: continue - level_slug = f"{cat_slug}-{level.lower()}" - md += f"### {cat} - {level}\n" - for l in links: - year, stars_val = l.get("year", "N/A"), l.get("stars", 0) - stars = ("🌟" * stars_val) if stars_val > 0 else "" - tag = l.get("tag", "[ENTERPRISE-STABLE]") - - # Determine color mapping - if "STANDARD" in tag or "FOUNDATIONAL" in tag: color = "success" - elif "EMERGING" in tag: color = "warning" - elif "LEGACY" in tag: color = "critical" - elif "STABLE" in tag: color = "info" - else: color = "primary" - - title_clean = l['title'].replace("==", "") - if stars_val >= 3 or "STANDARD" in tag: - title_display = f"**=={title_clean}==**" - elif stars_val == 2: - title_display = f"**{title_clean}**" - else: - title_display = title_clean - - year_prefix = f"**({year})** " if year and year != "N/A" else "" - gh_info = f" ⭐ {l['gh_stars']}" if "gh_stars" in l else "" - icon = " 🎥" if l.get("is_video") else "" - - # Language Tagging - lang = l.get("language", "English") - lang_tag = "" - if lang.lower() != "english": - lang_tag = f" [{lang.upper()} CONTENT]" - - # Complexity Tagging - l_val = l.get("complexity", "Intermediate") - level_tag = "" - if l_val.lower() in ["architect", "advanced"]: - level_tag = f" [{l_val.upper()} LEVEL]" - - # Resource Type Tagging - res_type = l.get("resource_type", "Reference") - type_tag = "" - if res_type.lower() in ["case study", "guide", "documentation"]: - type_tag = f" [{res_type.upper()}]" - # Rich Metadata - rich_tags = "" - if l.get("author"): rich_tags += f" by **{l['author']}**" - if l.get("duration"): rich_tags += f" ⏱️ {l['duration']}" - if l.get("reading_time"): rich_tags += f" 📖 {l['reading_time']}" + for topic, subtopics in topics.items(): + topic_slug = f"{cat_slug}-{topic.lower().replace(' ', '-')}" + md += f"### {topic}\n\n" - md += f" - {year_prefix}[{title_display}]({l['url']}){icon}{gh_info}{lang_tag}{level_tag}{type_tag}{rich_tags} {stars} {tag}\n" - if l['description']: - desc = l['description'] - if "\n" in desc: - md += "\n" + "\n".join([" " + line for line in desc.split("\n")]) + "\n\n" - else: - md += f" {desc}\n" + for subtopic, links in subtopics.items(): + if subtopic and subtopic != "General": + md += f"#### {subtopic}\n" + + for l in links: + year, stars_val = l.get("year", "N/A"), l.get("stars", 0) + stars = ("🌟" * stars_val) if stars_val > 0 else "" + tag = l.get("tag", "[ENTERPRISE-STABLE]") + + # Color mapping + if "STANDARD" in tag or "FOUNDATIONAL" in tag: color = "success" + elif "EMERGING" in tag: color = "warning" + elif "LEGACY" in tag: color = "critical" + elif "STABLE" in tag: color = "info" + else: color = "primary" + + title_clean = l['title'].replace("==", "") + title_display = f"**=={title_clean}==**" if stars_val >= 3 else title_clean + + year_prefix = f"**({year})** " if year and year != "N/A" else "" + gh_info = f" ⭐ {l['gh_stars']}" if "gh_stars" in l else "" + icon = " 🎥" if l.get("is_video") else "" + + lang = l.get("language", "English") + lang_tag = f" [{lang.upper()} CONTENT]" if lang.lower() != "english" else "" + + complexity = l.get("complexity", "Intermediate") + level_tag = f" [{complexity.upper()} LEVEL]" if complexity.lower() in ["architect", "advanced"] else "" + + res_type = l.get("resource_type", "Reference") + type_tag = f" [{res_type.upper()}]" if res_type.lower() in ["case study", "guide", "documentation"] else "" + + # Rich Metadata + rich_tags = "" + if l.get("author"): rich_tags += f" by **{l['author']}**" + if l.get("duration"): rich_tags += f" ⏱️ {l['duration']}" + if l.get("reading_time"): rich_tags += f" 📖 {l['reading_time']}" + + md += f" - {year_prefix}[{title_display}]({l['url']}){icon}{gh_info}{lang_tag}{level_tag}{type_tag}{rich_tags} {stars} {tag}\n" + if l['description']: + desc = l['description'] + md += f"\n {desc}\n\n" + md += "\n" md += "\n" + with open(os.path.join(V2_DIR, f"{slug}.md"), "w") as f: f.write(md) async def _sync_enterprise_navigation(self, data: Dict[str, Dict]):