From 3771737508a9212607cfbebf5de7866c055515c1 Mon Sep 17 00:00:00 2001 From: "Aryan ." Date: Fri, 11 Sep 2026 17:16:42 +0530 Subject: [PATCH 1/9] feat: add onboarding Bazel module --- AGENTS.md | 31 +++++ MODULE.bazel | 8 ++ tools/__init__.py | 0 tools/onboarding/MODULE.bazel | 25 ++++ tools/onboarding/tools/__init__.py | 0 tools/onboarding/tools/onboarding/BUILD | 57 +++++++++ tools/onboarding/tools/onboarding/__init__.py | 11 ++ tools/onboarding/tools/onboarding/__main__.py | 8 ++ .../onboarding/agent/onboarding.agent.yaml | 27 ++++ .../onboarding/agent/onboarding.skill.md | 48 +++++++ tools/onboarding/tools/onboarding/cli.py | 117 ++++++++++++++++++ .../onboarding/tools/onboarding/discovery.py | 98 +++++++++++++++ .../onboarding/examples/context_example.json | 23 ++++ .../onboarding/examples/sample_session.md | 25 ++++ tools/onboarding/tools/onboarding/models.py | 54 ++++++++ tools/onboarding/tools/onboarding/output.py | 47 +++++++ .../tools/onboarding/recommendation.py | 53 ++++++++ .../onboarding/schemas/context.schema.json | 60 +++++++++ .../tools/onboarding/state_machine.py | 64 ++++++++++ .../tools/onboarding/tests/__init__.py | 0 .../tools/onboarding/tests/test_discovery.py | 51 ++++++++ .../tools/onboarding/tests/test_output.py | 48 +++++++ .../onboarding/tests/test_recommendation.py | 40 ++++++ .../onboarding/tests/test_state_machine.py | 42 +++++++ .../onboarding/tools/onboarding/validators.py | 32 +++++ 25 files changed, 969 insertions(+) create mode 100644 AGENTS.md create mode 100644 tools/__init__.py create mode 100644 tools/onboarding/MODULE.bazel create mode 100644 tools/onboarding/tools/__init__.py create mode 100644 tools/onboarding/tools/onboarding/BUILD create mode 100644 tools/onboarding/tools/onboarding/__init__.py create mode 100644 tools/onboarding/tools/onboarding/__main__.py create mode 100644 tools/onboarding/tools/onboarding/agent/onboarding.agent.yaml create mode 100644 tools/onboarding/tools/onboarding/agent/onboarding.skill.md create mode 100644 tools/onboarding/tools/onboarding/cli.py create mode 100644 tools/onboarding/tools/onboarding/discovery.py create mode 100644 tools/onboarding/tools/onboarding/examples/context_example.json create mode 100644 tools/onboarding/tools/onboarding/examples/sample_session.md create mode 100644 tools/onboarding/tools/onboarding/models.py create mode 100644 tools/onboarding/tools/onboarding/output.py create mode 100644 tools/onboarding/tools/onboarding/recommendation.py create mode 100644 tools/onboarding/tools/onboarding/schemas/context.schema.json create mode 100644 tools/onboarding/tools/onboarding/state_machine.py create mode 100644 tools/onboarding/tools/onboarding/tests/__init__.py create mode 100644 tools/onboarding/tools/onboarding/tests/test_discovery.py create mode 100644 tools/onboarding/tools/onboarding/tests/test_output.py create mode 100644 tools/onboarding/tools/onboarding/tests/test_recommendation.py create mode 100644 tools/onboarding/tools/onboarding/tests/test_state_machine.py create mode 100644 tools/onboarding/tools/onboarding/validators.py diff --git a/AGENTS.md b/AGENTS.md new file mode 100644 index 00000000..7ed885e5 --- /dev/null +++ b/AGENTS.md @@ -0,0 +1,31 @@ + + +# Eclipse S-CORE + +Start onboarding: `/sdlc` (or `bazel run @score_onboarding//tools/onboarding:sdlc`) + +The onboarding agent (`tools/onboarding/`): +- identifies repository context (ASIL, languages, toolchains, build/docs system) +- classifies your contribution (bug fix, improvement, PoC, documentation, feature, question) +- recommends a workflow (SDLC Harness, SpecKit, BMAD, Technical Analysis, Issue Planning, Traditional) +- writes a single context contract to `.onboarding/context.json` +- recommends a handoff to the next agent — it never starts one automatically + +See [`tools/onboarding/tools/onboarding/agent/onboarding.skill.md`](tools/onboarding/tools/onboarding/agent/onboarding.skill.md) +for the full skill definition. + +See [`CONTRIBUTION.md`](CONTRIBUTION.md) for contribution rules, PR/issue +templates, and the ECA/DCO signing requirement. diff --git a/MODULE.bazel b/MODULE.bazel index 24e76dff..0098b1cb 100644 --- a/MODULE.bazel +++ b/MODULE.bazel @@ -14,6 +14,14 @@ module(name = "score_module_template") bazel_dep(name = "rules_python", version = "1.8.5", dev_dependency = True) +# Onboarding agent, nested here as its own module so other repos can depend on +# it directly via `bazel_dep(name = "score_onboarding", ...)`. +bazel_dep(name = "score_onboarding", version = "0.1.0", dev_dependency = True) +local_path_override( + module_name = "score_onboarding", + path = "tools/onboarding", +) + # Python 3.12: Required for testing infrastructure and code generation tools PYTHON_VERSION = "3.12" diff --git a/tools/__init__.py b/tools/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/tools/onboarding/MODULE.bazel b/tools/onboarding/MODULE.bazel new file mode 100644 index 00000000..c30e2d83 --- /dev/null +++ b/tools/onboarding/MODULE.bazel @@ -0,0 +1,25 @@ +# ******************************************************************************* +# Copyright (c) 2026 Contributors to the Eclipse Foundation +# +# See the NOTICE file(s) distributed with this work for additional +# information regarding copyright ownership. +# +# This program and the accompanying materials are made available under the +# terms of the Apache License Version 2.0 which is available at +# https://www.apache.org/licenses/LICENSE-2.0 +# +# SPDX-License-Identifier: Apache-2.0 +# ******************************************************************************* + +# Nested Bazel module so other repos can depend on the onboarding agent +# directly, e.g.: +# bazel_dep(name = "score_onboarding", version = "0.1.0") +# bazel run @score_onboarding//tools/onboarding:sdlc +module( + name = "score_onboarding", + version = "0.1.0", +) + +# Needed to resolve py_library/py_binary/py_test macros; toolchain +# registration is the consuming (root) module's responsibility. +bazel_dep(name = "rules_python", version = "1.8.5") diff --git a/tools/onboarding/tools/__init__.py b/tools/onboarding/tools/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/tools/onboarding/tools/onboarding/BUILD b/tools/onboarding/tools/onboarding/BUILD new file mode 100644 index 00000000..8acf400e --- /dev/null +++ b/tools/onboarding/tools/onboarding/BUILD @@ -0,0 +1,57 @@ +# ******************************************************************************* +# Copyright (c) 2026 Contributors to the Eclipse Foundation +# +# See the NOTICE file(s) distributed with this work for additional +# information regarding copyright ownership. +# +# This program and the accompanying materials are made available under the +# terms of the Apache License Version 2.0 which is available at +# https://www.apache.org/licenses/LICENSE-2.0 +# +# SPDX-License-Identifier: Apache-2.0 +# ******************************************************************************* + +load("@rules_python//python:defs.bzl", "py_binary", "py_library", "py_test") + +package(default_visibility = ["//visibility:public"]) + +py_library( + name = "onboarding_lib", + srcs = [ + "__init__.py", + "cli.py", + "discovery.py", + "models.py", + "output.py", + "recommendation.py", + "state_machine.py", + "validators.py", + ], + data = [ + "agent/onboarding.agent.yaml", + "agent/onboarding.skill.md", + "schemas/context.schema.json", + ], + imports = ["../.."], +) + +py_binary( + name = "sdlc", + srcs = ["__main__.py"], + main = "__main__.py", + deps = [":onboarding_lib"], +) + +[ + py_test( + name = test_file.removesuffix(".py"), + srcs = [test_file], + deps = [":onboarding_lib"], + ) + for test_file in [ + "tests/test_state_machine.py", + "tests/test_discovery.py", + "tests/test_recommendation.py", + "tests/test_output.py", + ] +] diff --git a/tools/onboarding/tools/onboarding/__init__.py b/tools/onboarding/tools/onboarding/__init__.py new file mode 100644 index 00000000..0098af25 --- /dev/null +++ b/tools/onboarding/tools/onboarding/__init__.py @@ -0,0 +1,11 @@ +"""Minimal onboarding agent: collects context, discovers repo, routes workflow.""" + +from .models import ContextEnvelope, ContributorProfile, RepositoryContext, WorkItem, WorkflowSelection + +__all__ = [ + "ContextEnvelope", + "ContributorProfile", + "RepositoryContext", + "WorkItem", + "WorkflowSelection", +] diff --git a/tools/onboarding/tools/onboarding/__main__.py b/tools/onboarding/tools/onboarding/__main__.py new file mode 100644 index 00000000..75f445ba --- /dev/null +++ b/tools/onboarding/tools/onboarding/__main__.py @@ -0,0 +1,8 @@ +import sys + +# Absolute import: Bazel's py_binary stub runs this file as a top-level +# script, so `__package__` is empty and relative imports fail. +from tools.onboarding.cli import cli + +if __name__ == "__main__": + cli(sys.argv[1:]) diff --git a/tools/onboarding/tools/onboarding/agent/onboarding.agent.yaml b/tools/onboarding/tools/onboarding/agent/onboarding.agent.yaml new file mode 100644 index 00000000..590a3b14 --- /dev/null +++ b/tools/onboarding/tools/onboarding/agent/onboarding.agent.yaml @@ -0,0 +1,27 @@ +description: "Type /sdlc or KICKOFF to start Eclipse S-CORE onboarding." +entry_point: "tools.onboarding.cli:sdlc" +skill: "onboarding.skill.md" + +collects: + - role + - repository + - technology + - contribution_type + - workflow + +produces: + - .onboarding/context.json + +handoffs: + - label: Start Issue Planning + agent: plan-issue-creation + - label: Start Technical Analysis + agent: plan-tech-analysis + - label: Start PLAN + agent: plan-requirements + - label: Start CODE (PoC / Spike) + agent: code-design + +notes: > + This agent only recommends a handoff. It never executes downstream agents + automatically; the contributor must confirm before a handoff is started. diff --git a/tools/onboarding/tools/onboarding/agent/onboarding.skill.md b/tools/onboarding/tools/onboarding/agent/onboarding.skill.md new file mode 100644 index 00000000..db3c4300 --- /dev/null +++ b/tools/onboarding/tools/onboarding/agent/onboarding.skill.md @@ -0,0 +1,48 @@ +# Onboarding Skill + +Single entry point into the Eclipse S-CORE AI SDLC ecosystem. Collects +context, classifies the contribution, recommends a workflow, and hands off — +it does not execute SDLC Harness, SpecKit, BMAD, Technical Analysis, or +Planning itself. + +## Role Detection +Ask the contributor for their role: `developer`, `reviewer`, `maintainer`, or +`committer`. Returning contributors may skip the introduction. + +## Repository Discovery +Read (never execute) `MODULE.bazel`, `project_config.bzl`, `README.md`, and +`CONTRIBUTION.md` at the repository root. Extract: repository name, module, +ASIL level, declared languages, build system. + +## Technology Discovery +From `MODULE.bazel`, detect toolchains by dependency name: +- `rules_rust` → Rust +- `rules_cc` → C++ +- `toolchains_llvm` → LLVM +- `qnx` (in `MODULE.bazel` or `scripts/`) → QNX + +## Contribution Classification +Ask for the contribution type: `bug_fix`, `improvement`, `poc`, +`documentation`, `feature`, or `question`. + +## Workflow Recommendation +Map contribution type to a workflow (see `recommendation.py`): +- `bug_fix` → SDLC Harness +- `improvement` → SpecKit +- `poc` → BMAD +- `documentation` → Traditional +- otherwise → Technical Analysis / Issue Planning + +If the repository's ASIL level is not `QM`, always recommend SDLC Harness +regardless of contribution type, since safety-relevant work requires full +traceability. The contributor may always override the recommendation. + +## Guardrails +- Never write outside `.onboarding/context.json`. +- Never auto-start a downstream agent; always require explicit confirmation. +- Never fabricate repository metadata that discovery could not detect — + surface it as `"Unknown"` and let the contributor confirm/correct it. + +## Open-source contribution rules +Point contributors to `CONTRIBUTION.md` for PR/issue templates, the ECA/DCO +signing requirement, and commit message rules before any handoff. diff --git a/tools/onboarding/tools/onboarding/cli.py b/tools/onboarding/tools/onboarding/cli.py new file mode 100644 index 00000000..3f4198f1 --- /dev/null +++ b/tools/onboarding/tools/onboarding/cli.py @@ -0,0 +1,117 @@ +"""Onboarding CLI: single entry point into the S-CORE AI SDLC ecosystem. + +Stdlib-only (argparse + input()) so this binary has no external pip +dependency beyond what //tools/onboarding already needs. + +Usage: + bazel run @score_onboarding//tools/onboarding:sdlc + python -m tools.onboarding +""" + +from __future__ import annotations + +import argparse +import os +from pathlib import Path + +from .discovery import discover_repository +from .output import build_context_envelope, handoff_summary, write_context +from .recommendation import WORKFLOWS, recommend_workflow, select_workflow +from .state_machine import OnboardingStateMachine, State +from .validators import ROLES, validate_contribution_type, validate_role + +ROLE_CHOICES = sorted(ROLES) +CONTRIBUTION_CHOICES = ["bug_fix", "improvement", "poc", "documentation", "feature", "question"] + + +def _prompt_choice(question: str, choices: list[str], default: str | None = None) -> str: + suffix = f" [{default}]" if default else "" + while True: + answer = input(f"{question} ({'/'.join(choices)}){suffix}: ").strip() or (default or "") + if answer in choices: + return answer + print(f"Please choose one of: {', '.join(choices)}") + + +def _prompt_confirm(question: str, default: bool = True) -> bool: + suffix = "Y/n" if default else "y/N" + answer = input(f"{question} [{suffix}]: ").strip().lower() + if not answer: + return default + return answer in ("y", "yes") + + +def run_sdlc(repo_root: Path) -> None: + """Run the interactive onboarding flow and produce .onboarding/context.json.""" + machine = OnboardingStateMachine() + print("Welcome to Eclipse S-CORE onboarding. Type /sdlc anytime to restart.") + machine.advance() # -> CONTRIBUTOR_CHECK + + machine.advance() # -> ROLE_DETECTION + role = _prompt_choice("Your role", ROLE_CHOICES) + validate_role(role) + + machine.advance() # -> REPOSITORY_DISCOVERY + machine.advance() # -> TECHNOLOGY_DISCOVERY + repository = discover_repository(repo_root) + print( + f"Detected repository '{repository.name}': ASIL={repository.asil}, " + f"languages={repository.languages}, toolchains={repository.toolchains}, " + f"build={repository.build_system}, docs={repository.docs_system}" + ) + + machine.advance() # -> CONTRIBUTION_SELECTION + contribution_type = _prompt_choice("Contribution type", CONTRIBUTION_CHOICES) + validate_contribution_type(contribution_type) + + machine.advance() # -> WORKFLOW_STYLE + recommended, reason = recommend_workflow(contribution_type, repository.asil) + print(f"Recommended workflow: {recommended} ({reason})") + + machine.advance() # -> WORKFLOW_FRAMEWORK + user_choice = _prompt_choice("Workflow (or 'recommend' to accept)", [*WORKFLOWS, "recommend"], default="recommend") + selected, overridden = select_workflow(recommended, None if user_choice == "recommend" else user_choice) + + machine.advance() # -> SUMMARY + print(f"\nSummary: role={role}, contribution={contribution_type}, workflow={selected}") + machine.data["summary_confirmed"] = _prompt_confirm("Confirm and generate context.json?") + machine.advance() # -> READY_FOR_HANDOFF (if confirmed) + + if machine.state != State.READY_FOR_HANDOFF: + print("Onboarding cancelled. No context.json was written.") + return + + envelope = build_context_envelope( + repository=repository, + role=role, + contribution_type=contribution_type, + workflow=selected, + workflow_reason=reason, + user_override=overridden, + ) + path = write_context(envelope, repo_root) + print(f"\nContext written to {path}") + + print("\nRecommended next steps (confirm before starting):") + for agent in handoff_summary(envelope): + print(f" - Start {agent}") + + +def _default_repo_root() -> Path: + # Under `bazel run`, cwd is the runfiles sandbox, not the real checkout. + # Bazel sets BUILD_WORKSPACE_DIRECTORY to the actual invocation directory. + workspace_dir = os.environ.get("BUILD_WORKSPACE_DIRECTORY") + return Path(workspace_dir) if workspace_dir else Path.cwd() + + +def cli(argv: list[str] | None = None) -> None: + # The Bazel target is already named "sdlc"; no subcommand needed. + parser = argparse.ArgumentParser(prog="sdlc") + parser.add_argument("--repo-root", type=Path, default=_default_repo_root()) + + args = parser.parse_args(argv) + run_sdlc(args.repo_root) + + +if __name__ == "__main__": + cli() diff --git a/tools/onboarding/tools/onboarding/discovery.py b/tools/onboarding/tools/onboarding/discovery.py new file mode 100644 index 00000000..68e4f34a --- /dev/null +++ b/tools/onboarding/tools/onboarding/discovery.py @@ -0,0 +1,98 @@ +"""Repository discovery: auto-detect ASIL, languages, toolchains, build/docs system. + +Reads MODULE.bazel, project_config.bzl and README.md as plain text (never +executed) to keep discovery safe and dependency-free. +""" + +from __future__ import annotations + +import re +from pathlib import Path + +from .models import RepositoryContext + + +def _read(path: Path) -> str: + try: + return path.read_text(encoding="utf-8") + except OSError: + return "" + + +def _detect_asil(project_config_text: str) -> str: + match = re.search(r'"asil_level"\s*:\s*"([^"]+)"', project_config_text) + return match.group(1) if match else "QM" + + +def _detect_declared_languages(project_config_text: str) -> list[str]: + match = re.search(r'"source_code"\s*:\s*\[([^\]]*)\]', project_config_text) + if not match: + return [] + return [item.strip().strip('"').strip("'") for item in match.group(1).split(",") if item.strip()] + + +def _detect_languages(module_bazel_text: str, declared: list[str]) -> list[str]: + languages = set(lang.lower() for lang in declared) + if "rules_rust" in module_bazel_text: + languages.add("rust") + if "rules_cc" in module_bazel_text: + languages.add("cpp") + return sorted(languages) + + +def _detect_toolchains(module_bazel_text: str) -> list[str]: + toolchains = [] + if "toolchains_llvm" in module_bazel_text: + toolchains.append("llvm") + if "score_bazel_cpp_toolchains" in module_bazel_text or "gcc" in module_bazel_text.lower(): + toolchains.append("gcc") + if "qnx" in module_bazel_text.lower(): + toolchains.append("qnx") + return toolchains + + +def _detect_qnx(root: Path, module_bazel_text: str) -> bool: + if "qnx" in module_bazel_text.lower(): + return True + scripts_dir = root / "scripts" + if scripts_dir.is_dir(): + for script in scripts_dir.glob("*qnx*"): + return True + return False + + +def _detect_build_system(root: Path) -> str: + return "Bazel" if (root / "MODULE.bazel").is_file() else "Unknown" + + +def _detect_docs_system(readme_text: str, root: Path) -> str: + if (root / "docs" / "conf.py").is_file(): + return "Sphinx" + lowered = readme_text.lower() + if "doxygen" in lowered: + return "Doxygen" + if "mdbook" in lowered: + return "mdBook" + return "Unknown" + + +def discover_repository(root: Path, name: str | None = None) -> RepositoryContext: + """Auto-detect repository metadata from MODULE.bazel, project_config.bzl, README.md.""" + module_bazel_text = _read(root / "MODULE.bazel") + project_config_text = _read(root / "project_config.bzl") + readme_text = _read(root / "README.md") + + declared_languages = _detect_declared_languages(project_config_text) + languages = _detect_languages(module_bazel_text, declared_languages) + toolchains = _detect_toolchains(module_bazel_text) + if _detect_qnx(root, module_bazel_text) and "qnx" not in toolchains: + toolchains.append("qnx") + + return RepositoryContext( + name=name or root.name, + asil=_detect_asil(project_config_text), + languages=languages, + toolchains=toolchains, + build_system=_detect_build_system(root), + docs_system=_detect_docs_system(readme_text, root), + ) diff --git a/tools/onboarding/tools/onboarding/examples/context_example.json b/tools/onboarding/tools/onboarding/examples/context_example.json new file mode 100644 index 00000000..1da6fb0e --- /dev/null +++ b/tools/onboarding/tools/onboarding/examples/context_example.json @@ -0,0 +1,23 @@ +{ + "repository": { + "name": "module_template", + "asil": "QM", + "languages": ["rust", "cpp"], + "toolchains": ["llvm"], + "build_system": "Bazel", + "docs_system": "Sphinx" + }, + "contributor": { + "role": "developer", + "module": null + }, + "work_item": { + "type": "bug_fix", + "description": "" + }, + "workflow": { + "selected": "sdlc_harness", + "reason": "Bug fixes benefit from SDLC Harness traceability.", + "user_override": false + } +} diff --git a/tools/onboarding/tools/onboarding/examples/sample_session.md b/tools/onboarding/tools/onboarding/examples/sample_session.md new file mode 100644 index 00000000..4c7d71da --- /dev/null +++ b/tools/onboarding/tools/onboarding/examples/sample_session.md @@ -0,0 +1,25 @@ +# Sample Onboarding Session + +``` +$ python -m tools.onboarding +Welcome to Eclipse S-CORE onboarding. Type /sdlc anytime to restart. +Your role: developer +Detected repository 'module_template': ASIL=QM, languages=['cpp', 'rust'], +toolchains=['llvm'], build=Bazel, docs=Sphinx +Contribution type: bug_fix +Recommended workflow: sdlc_harness (Bug fixes benefit from SDLC Harness traceability.) +Workflow (or 'recommend' to accept) [recommend]: recommend + +Summary: role=developer, contribution=bug_fix, workflow=sdlc_harness +Confirm and generate context.json? [Y/n]: y + +Context written to .onboarding/context.json + +Recommended next steps (confirm before starting): + - Start plan-tech-analysis + - Start plan-requirements + - Start code-design +``` + +No downstream agent is started automatically — the contributor picks one of +the recommended next steps and confirms explicitly. diff --git a/tools/onboarding/tools/onboarding/models.py b/tools/onboarding/tools/onboarding/models.py new file mode 100644 index 00000000..3a24623c --- /dev/null +++ b/tools/onboarding/tools/onboarding/models.py @@ -0,0 +1,54 @@ +"""Data model for the onboarding context envelope. + +A single ``context.json`` replaces the earlier per-workflow input files +(``sdlc_input.json``, ``speckit_input.json``, ``bmad_input.json`` ...). +Every downstream workflow reads the same envelope shape. +""" + +from __future__ import annotations + +import json +from dataclasses import asdict, dataclass, field + + +@dataclass +class RepositoryContext: + name: str + asil: str = "QM" + languages: list[str] = field(default_factory=list) + toolchains: list[str] = field(default_factory=list) + build_system: str = "Unknown" + docs_system: str = "Unknown" + + +@dataclass +class ContributorProfile: + role: str + module: str | None = None + + +@dataclass +class WorkItem: + type: str + description: str = "" + + +@dataclass +class WorkflowSelection: + selected: str + reason: str = "" + user_override: bool = False + + +@dataclass +class ContextEnvelope: + repository: RepositoryContext + contributor: ContributorProfile + work_item: WorkItem + workflow: WorkflowSelection + + def to_dict(self) -> dict: + return asdict(self) + + def to_json(self) -> str: + return json.dumps(self.to_dict(), indent=2) diff --git a/tools/onboarding/tools/onboarding/output.py b/tools/onboarding/tools/onboarding/output.py new file mode 100644 index 00000000..7e20cdf7 --- /dev/null +++ b/tools/onboarding/tools/onboarding/output.py @@ -0,0 +1,47 @@ +"""Builds and writes the single onboarding context contract (Phase 4). + +Replaces the earlier per-workflow files (sdlc_input.json, speckit_input.json, +bmad_input.json, ...) with one ``.onboarding/context.json`` every downstream +workflow can consume. +""" + +from __future__ import annotations + +from pathlib import Path + +from .models import ContextEnvelope, ContributorProfile, RepositoryContext, WorkflowSelection, WorkItem +from .recommendation import get_handoff_recommendations + +DEFAULT_OUTPUT_DIR = ".onboarding" +DEFAULT_OUTPUT_FILE = "context.json" + + +def build_context_envelope( + repository: RepositoryContext, + role: str, + contribution_type: str, + workflow: str, + workflow_reason: str = "", + user_override: bool = False, + module: str | None = None, + description: str = "", +) -> ContextEnvelope: + return ContextEnvelope( + repository=repository, + contributor=ContributorProfile(role=role, module=module), + work_item=WorkItem(type=contribution_type, description=description), + workflow=WorkflowSelection(selected=workflow, reason=workflow_reason, user_override=user_override), + ) + + +def write_context(envelope: ContextEnvelope, root: Path, output_dir: str = DEFAULT_OUTPUT_DIR) -> Path: + target_dir = root / output_dir + target_dir.mkdir(parents=True, exist_ok=True) + target_path = target_dir / DEFAULT_OUTPUT_FILE + target_path.write_text(envelope.to_json() + "\n", encoding="utf-8") + return target_path + + +def handoff_summary(envelope: ContextEnvelope) -> list[str]: + """Recommended next agents; onboarding never executes them itself.""" + return get_handoff_recommendations(envelope.workflow.selected) diff --git a/tools/onboarding/tools/onboarding/recommendation.py b/tools/onboarding/tools/onboarding/recommendation.py new file mode 100644 index 00000000..fd21025f --- /dev/null +++ b/tools/onboarding/tools/onboarding/recommendation.py @@ -0,0 +1,53 @@ +"""Maps onboarding answers to a recommended workflow, allows user override.""" + +from __future__ import annotations + +WORKFLOWS = [ + "sdlc_harness", + "speckit", + "bmad", + "technical_analysis", + "issue_planning", + "traditional", +] + +# Downstream agents each workflow may hand off to (label -> agent id). Onboarding +# only recommends these; it never executes them. +HANDOFF_MAP: dict[str, list[str]] = { + "sdlc_harness": ["plan-tech-analysis", "plan-requirements", "code-design"], + "speckit": ["plan-issue-creation", "plan-requirements"], + "bmad": ["plan-tech-analysis", "plan-requirements"], + "technical_analysis": ["plan-issue-creation", "plan-requirements"], + "issue_planning": ["plan-tech-analysis", "plan-requirements"], + "traditional": ["code-design"], +} + +# Base mapping from contribution_type to workflow, per onboarding.skill.md. +_CONTRIBUTION_MAP: dict[str, tuple[str, str]] = { + "bug_fix": ("sdlc_harness", "Bug fixes benefit from SDLC Harness traceability."), + "improvement": ("speckit", "Improvements are well-suited to spec-driven planning."), + "poc": ("bmad", "Proof-of-concept work fits a Build-Measure-Analyze-Design loop."), + "documentation": ("traditional", "Documentation-only changes can follow the traditional flow."), + "feature": ("sdlc_harness", "New features require the full SDLC lifecycle for traceability."), + "question": ("issue_planning", "Open questions should start with issue definition."), +} + + +def recommend_workflow(contribution_type: str, asil: str = "QM", description: str = "") -> tuple[str, str]: + """Rule-based recommendation. Returns (workflow, reason).""" + if asil and asil.upper() != "QM": + return "sdlc_harness", "Safety-relevant module (ASIL != QM) requires full SDLC Harness traceability." + if contribution_type in _CONTRIBUTION_MAP: + return _CONTRIBUTION_MAP[contribution_type] + return "technical_analysis", "Unclear or complex scope requires decomposition before planning." + + +def select_workflow(recommended: str, user_choice: str | None = None) -> tuple[str, bool]: + """Returns (selected_workflow, was_overridden).""" + if user_choice and user_choice in WORKFLOWS: + return user_choice, user_choice != recommended + return recommended, False + + +def get_handoff_recommendations(workflow: str) -> list[str]: + return HANDOFF_MAP.get(workflow, []) diff --git a/tools/onboarding/tools/onboarding/schemas/context.schema.json b/tools/onboarding/tools/onboarding/schemas/context.schema.json new file mode 100644 index 00000000..8e61a035 --- /dev/null +++ b/tools/onboarding/tools/onboarding/schemas/context.schema.json @@ -0,0 +1,60 @@ +{ + "$schema": "https://json-schema.org/draft/2020-12/schema", + "$id": "https://eclipse-score.org/schemas/onboarding/context.schema.json", + "title": "Onboarding Context Envelope", + "type": "object", + "required": ["repository", "contributor", "work_item", "workflow"], + "additionalProperties": false, + "properties": { + "repository": { + "type": "object", + "required": ["name", "asil"], + "additionalProperties": false, + "properties": { + "name": { "type": "string" }, + "asil": { "type": "string", "enum": ["QM", "A", "B", "C", "D"] }, + "languages": { "type": "array", "items": { "type": "string" } }, + "toolchains": { "type": "array", "items": { "type": "string" } }, + "build_system": { "type": "string" }, + "docs_system": { "type": "string" } + } + }, + "contributor": { + "type": "object", + "required": ["role"], + "additionalProperties": false, + "properties": { + "role": { + "type": "string", + "enum": ["developer", "reviewer", "maintainer", "committer"] + }, + "module": { "type": ["string", "null"] } + } + }, + "work_item": { + "type": "object", + "required": ["type"], + "additionalProperties": false, + "properties": { + "type": { + "type": "string", + "enum": ["bug_fix", "improvement", "poc", "documentation", "feature", "question"] + }, + "description": { "type": "string" } + } + }, + "workflow": { + "type": "object", + "required": ["selected"], + "additionalProperties": false, + "properties": { + "selected": { + "type": "string", + "enum": ["sdlc_harness", "speckit", "bmad", "technical_analysis", "issue_planning", "traditional"] + }, + "reason": { "type": "string" }, + "user_override": { "type": "boolean" } + } + } + } +} diff --git a/tools/onboarding/tools/onboarding/state_machine.py b/tools/onboarding/tools/onboarding/state_machine.py new file mode 100644 index 00000000..a8bbf602 --- /dev/null +++ b/tools/onboarding/tools/onboarding/state_machine.py @@ -0,0 +1,64 @@ +"""Onboarding state machine. + +Linear flow with two branch guards (returning contributor skip, confirmation +gate before handoff). +""" + +from __future__ import annotations + +from enum import Enum +from typing import Callable + + +class State(str, Enum): + GREETING = "greeting" + CONTRIBUTOR_CHECK = "contributor_check" + ROLE_DETECTION = "role_detection" + REPOSITORY_DISCOVERY = "repository_discovery" + TECHNOLOGY_DISCOVERY = "technology_discovery" + CONTRIBUTION_SELECTION = "contribution_selection" + WORKFLOW_STYLE = "workflow_style" + WORKFLOW_FRAMEWORK = "workflow_framework" + SUMMARY = "summary" + READY_FOR_HANDOFF = "ready_for_handoff" + + +def _always(_data: dict) -> bool: + return True + + +def _summary_confirmed(data: dict) -> bool: + return bool(data.get("summary_confirmed")) + + +# Ordered transitions: (from_state, to_state, guard) +_TRANSITIONS: list[tuple[State, State, Callable[[dict], bool]]] = [ + (State.GREETING, State.CONTRIBUTOR_CHECK, _always), + (State.CONTRIBUTOR_CHECK, State.ROLE_DETECTION, _always), + (State.ROLE_DETECTION, State.REPOSITORY_DISCOVERY, _always), + (State.REPOSITORY_DISCOVERY, State.TECHNOLOGY_DISCOVERY, _always), + (State.TECHNOLOGY_DISCOVERY, State.CONTRIBUTION_SELECTION, _always), + (State.CONTRIBUTION_SELECTION, State.WORKFLOW_STYLE, _always), + (State.WORKFLOW_STYLE, State.WORKFLOW_FRAMEWORK, _always), + (State.WORKFLOW_FRAMEWORK, State.SUMMARY, _always), + (State.SUMMARY, State.READY_FOR_HANDOFF, _summary_confirmed), +] + + +class OnboardingStateMachine: + """Drives the onboarding flow one step at a time.""" + + def __init__(self) -> None: + self.state: State = State.GREETING + self.data: dict = {} + + def advance(self) -> State: + """Move to the next state if its guard passes; otherwise stay put.""" + for from_state, to_state, guard in _TRANSITIONS: + if self.state == from_state and guard(self.data): + self.state = to_state + break + return self.state + + def is_done(self) -> bool: + return self.state == State.READY_FOR_HANDOFF diff --git a/tools/onboarding/tools/onboarding/tests/__init__.py b/tools/onboarding/tools/onboarding/tests/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/tools/onboarding/tools/onboarding/tests/test_discovery.py b/tools/onboarding/tools/onboarding/tests/test_discovery.py new file mode 100644 index 00000000..fa3887b8 --- /dev/null +++ b/tools/onboarding/tools/onboarding/tests/test_discovery.py @@ -0,0 +1,51 @@ +import tempfile +import unittest +from pathlib import Path + +from tools.onboarding.discovery import discover_repository + + +def _write(root: Path, name: str, content: str) -> None: + (root / name).write_text(content, encoding="utf-8") + + +class TestDiscovery(unittest.TestCase): + def test_detects_rust_cpp_llvm_qnx(self) -> None: + with tempfile.TemporaryDirectory() as tmp: + root = Path(tmp) + _write( + root, + "MODULE.bazel", + 'bazel_dep(name = "rules_rust", version = "0.70.0")\n' + 'bazel_dep(name = "rules_cc", version = "0.2.18")\n' + 'bazel_dep(name = "toolchains_llvm", version = "1.7.0")\n' + "# target: qnx8\n", + ) + _write(root, "project_config.bzl", 'PROJECT_CONFIG = {\n "asil_level": "QM",\n "source_code": ["rust"],\n}\n') + _write(root, "README.md", "Docs built with Sphinx.\n") + (root / "docs").mkdir() + _write(root / "docs", "conf.py", "# sphinx conf\n") + + repository = discover_repository(root, name="module_template") + + self.assertEqual(repository.name, "module_template") + self.assertEqual(repository.asil, "QM") + self.assertIn("rust", repository.languages) + self.assertIn("cpp", repository.languages) + self.assertIn("llvm", repository.toolchains) + self.assertIn("qnx", repository.toolchains) + self.assertEqual(repository.build_system, "Bazel") + self.assertEqual(repository.docs_system, "Sphinx") + + def test_defaults_when_files_missing(self) -> None: + with tempfile.TemporaryDirectory() as tmp: + root = Path(tmp) + repository = discover_repository(root, name="empty_repo") + self.assertEqual(repository.asil, "QM") + self.assertEqual(repository.languages, []) + self.assertEqual(repository.build_system, "Unknown") + self.assertEqual(repository.docs_system, "Unknown") + + +if __name__ == "__main__": + unittest.main() diff --git a/tools/onboarding/tools/onboarding/tests/test_output.py b/tools/onboarding/tools/onboarding/tests/test_output.py new file mode 100644 index 00000000..f7bb8f28 --- /dev/null +++ b/tools/onboarding/tools/onboarding/tests/test_output.py @@ -0,0 +1,48 @@ +import json +import tempfile +import unittest +from pathlib import Path + +from tools.onboarding.models import RepositoryContext +from tools.onboarding.output import build_context_envelope, handoff_summary, write_context + + +class TestOutput(unittest.TestCase): + def test_build_context_envelope_shape(self) -> None: + repository = RepositoryContext(name="module_template", asil="QM", languages=["rust"]) + envelope = build_context_envelope( + repository=repository, + role="developer", + contribution_type="bug_fix", + workflow="sdlc_harness", + workflow_reason="Bug fixes benefit from SDLC Harness traceability.", + ) + data = envelope.to_dict() + self.assertEqual(data["repository"]["name"], "module_template") + self.assertEqual(data["contributor"]["role"], "developer") + self.assertEqual(data["work_item"]["type"], "bug_fix") + self.assertEqual(data["workflow"]["selected"], "sdlc_harness") + + def test_write_context_creates_single_file(self) -> None: + repository = RepositoryContext(name="module_template", asil="QM") + envelope = build_context_envelope( + repository=repository, role="developer", contribution_type="bug_fix", workflow="sdlc_harness" + ) + with tempfile.TemporaryDirectory() as tmp: + root = Path(tmp) + path = write_context(envelope, root) + self.assertEqual(path, root / ".onboarding" / "context.json") + self.assertTrue(path.is_file()) + written = json.loads(path.read_text(encoding="utf-8")) + self.assertEqual(written["workflow"]["selected"], "sdlc_harness") + + def test_handoff_summary_matches_workflow(self) -> None: + repository = RepositoryContext(name="module_template", asil="QM") + envelope = build_context_envelope( + repository=repository, role="developer", contribution_type="bug_fix", workflow="traditional" + ) + self.assertEqual(handoff_summary(envelope), ["code-design"]) + + +if __name__ == "__main__": + unittest.main() diff --git a/tools/onboarding/tools/onboarding/tests/test_recommendation.py b/tools/onboarding/tools/onboarding/tests/test_recommendation.py new file mode 100644 index 00000000..f0bc91a6 --- /dev/null +++ b/tools/onboarding/tools/onboarding/tests/test_recommendation.py @@ -0,0 +1,40 @@ +import unittest + +from tools.onboarding.recommendation import recommend_workflow, select_workflow + + +class TestRecommendation(unittest.TestCase): + def test_bug_fix_recommends_sdlc_harness(self) -> None: + workflow, _reason = recommend_workflow("bug_fix", asil="QM") + self.assertEqual(workflow, "sdlc_harness") + + def test_improvement_recommends_speckit(self) -> None: + workflow, _reason = recommend_workflow("improvement", asil="QM") + self.assertEqual(workflow, "speckit") + + def test_poc_recommends_bmad(self) -> None: + workflow, _reason = recommend_workflow("poc", asil="QM") + self.assertEqual(workflow, "bmad") + + def test_documentation_recommends_traditional(self) -> None: + workflow, _reason = recommend_workflow("documentation", asil="QM") + self.assertEqual(workflow, "traditional") + + def test_non_qm_asil_forces_sdlc_harness(self) -> None: + workflow, reason = recommend_workflow("documentation", asil="B") + self.assertEqual(workflow, "sdlc_harness") + self.assertIn("ASIL", reason) + + def test_user_override_is_honored(self) -> None: + selected, overridden = select_workflow("sdlc_harness", user_choice="bmad") + self.assertEqual(selected, "bmad") + self.assertTrue(overridden) + + def test_accepting_recommendation_is_not_an_override(self) -> None: + selected, overridden = select_workflow("sdlc_harness", user_choice=None) + self.assertEqual(selected, "sdlc_harness") + self.assertFalse(overridden) + + +if __name__ == "__main__": + unittest.main() diff --git a/tools/onboarding/tools/onboarding/tests/test_state_machine.py b/tools/onboarding/tools/onboarding/tests/test_state_machine.py new file mode 100644 index 00000000..63b8e6cd --- /dev/null +++ b/tools/onboarding/tools/onboarding/tests/test_state_machine.py @@ -0,0 +1,42 @@ +import unittest + +from tools.onboarding.state_machine import OnboardingStateMachine, State + + +class TestOnboardingStateMachine(unittest.TestCase): + def test_linear_flow_reaches_summary(self) -> None: + machine = OnboardingStateMachine() + expected = [ + State.CONTRIBUTOR_CHECK, + State.ROLE_DETECTION, + State.REPOSITORY_DISCOVERY, + State.TECHNOLOGY_DISCOVERY, + State.CONTRIBUTION_SELECTION, + State.WORKFLOW_STYLE, + State.WORKFLOW_FRAMEWORK, + State.SUMMARY, + ] + for state in expected: + self.assertEqual(machine.advance(), state) + + def test_summary_blocks_without_confirmation(self) -> None: + machine = OnboardingStateMachine() + for _ in range(8): + machine.advance() + self.assertEqual(machine.state, State.SUMMARY) + machine.advance() + self.assertEqual(machine.state, State.SUMMARY) + self.assertFalse(machine.is_done()) + + def test_summary_advances_when_confirmed(self) -> None: + machine = OnboardingStateMachine() + for _ in range(8): + machine.advance() + machine.data["summary_confirmed"] = True + machine.advance() + self.assertEqual(machine.state, State.READY_FOR_HANDOFF) + self.assertTrue(machine.is_done()) + + +if __name__ == "__main__": + unittest.main() diff --git a/tools/onboarding/tools/onboarding/validators.py b/tools/onboarding/tools/onboarding/validators.py new file mode 100644 index 00000000..642d73cf --- /dev/null +++ b/tools/onboarding/tools/onboarding/validators.py @@ -0,0 +1,32 @@ +"""Input validation for onboarding answers.""" + +from __future__ import annotations + +from pathlib import Path + +ROLES = {"developer", "reviewer", "maintainer", "committer"} +CONTRIBUTION_TYPES = {"bug_fix", "improvement", "poc", "documentation", "feature", "question"} + + +class ValidationError(ValueError): + """Raised when an onboarding answer fails validation.""" + + +def validate_role(role: str) -> str: + if role not in ROLES: + raise ValidationError(f"Unknown role '{role}'. Expected one of: {sorted(ROLES)}") + return role + + +def validate_contribution_type(contribution_type: str) -> str: + if contribution_type not in CONTRIBUTION_TYPES: + raise ValidationError( + f"Unknown contribution type '{contribution_type}'. Expected one of: {sorted(CONTRIBUTION_TYPES)}" + ) + return contribution_type + + +def validate_repository_path(root: Path) -> Path: + if not (root / "MODULE.bazel").is_file(): + raise ValidationError(f"'{root}' does not look like an S-CORE Bazel repository (no MODULE.bazel).") + return root From 64392fd7ef4286ae74aa08e567f94507fd5c72fb Mon Sep 17 00:00:00 2001 From: "Aryan ." Date: Tue, 15 Sep 2026 17:02:58 +0530 Subject: [PATCH 2/9] docs: describe onboarding module --- README.md | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/README.md b/README.md index 6fda28ba..eb5b3359 100644 --- a/README.md +++ b/README.md @@ -100,6 +100,22 @@ bazel test //tests/... --- +## Onboarding + +The repository includes the `score_onboarding` Bazel module to guide +contributors into the appropriate Eclipse S-CORE SDLC workflow. From the +repository root, start the interactive flow with: + +```sh +bazel run @score_onboarding//tools/onboarding:sdlc +``` + +The tool reads repository metadata, collects the contributor role and change +type, recommends a workflow, and writes the confirmed context to +`.onboarding/context.json`. It does not start downstream agents automatically. + +--- + ## 🛠 Tools & Linters The template integrates **tools and linters** from **centralized repositories** to ensure consistency across projects. From 7b5bedf1e35eea1aac46e4a5d90b81e150853228 Mon Sep 17 00:00:00 2001 From: "Aryan ." Date: Tue, 15 Sep 2026 19:26:31 +0530 Subject: [PATCH 3/9] chore: satisfy onboarding pre-commit checks --- REUSE.toml | 8 ++++++++ tools/onboarding/tools/onboarding/__init__.py | 13 +++++++++++++ tools/onboarding/tools/onboarding/__main__.py | 13 +++++++++++++ .../tools/onboarding/agent/onboarding.agent.yaml | 13 +++++++++++++ .../tools/onboarding/agent/onboarding.skill.md | 15 +++++++++++++++ tools/onboarding/tools/onboarding/cli.py | 13 +++++++++++++ tools/onboarding/tools/onboarding/discovery.py | 13 +++++++++++++ .../tools/onboarding/examples/sample_session.md | 15 +++++++++++++++ tools/onboarding/tools/onboarding/models.py | 13 +++++++++++++ tools/onboarding/tools/onboarding/output.py | 13 +++++++++++++ .../onboarding/tools/onboarding/recommendation.py | 13 +++++++++++++ .../onboarding/tools/onboarding/state_machine.py | 13 +++++++++++++ .../tools/onboarding/tests/test_discovery.py | 13 +++++++++++++ .../tools/onboarding/tests/test_output.py | 13 +++++++++++++ .../tools/onboarding/tests/test_recommendation.py | 13 +++++++++++++ .../tools/onboarding/tests/test_state_machine.py | 13 +++++++++++++ tools/onboarding/tools/onboarding/validators.py | 13 +++++++++++++ 17 files changed, 220 insertions(+) diff --git a/REUSE.toml b/REUSE.toml index 43801e8e..9f0de116 100644 --- a/REUSE.toml +++ b/REUSE.toml @@ -37,3 +37,11 @@ SPDX-License-Identifier = "Apache-2.0" path = [".bazelversion"] SPDX-FileCopyrightText = "Copyright (c) 2026 Contributors to the Eclipse Foundation" SPDX-License-Identifier = "Apache-2.0" + +[[annotations]] +path = [ + "tools/onboarding/tools/onboarding/examples/context_example.json", + "tools/onboarding/tools/onboarding/schemas/context.schema.json", +] +SPDX-FileCopyrightText = "Copyright (c) 2026 Contributors to the Eclipse Foundation" +SPDX-License-Identifier = "Apache-2.0" diff --git a/tools/onboarding/tools/onboarding/__init__.py b/tools/onboarding/tools/onboarding/__init__.py index 0098af25..a7d397d2 100644 --- a/tools/onboarding/tools/onboarding/__init__.py +++ b/tools/onboarding/tools/onboarding/__init__.py @@ -1,3 +1,16 @@ +# ******************************************************************************* +# Copyright (c) 2026 Contributors to the Eclipse Foundation +# +# See the NOTICE file(s) distributed with this work for additional +# information regarding copyright ownership. +# +# This program and the accompanying materials are made available under the +# terms of the Apache License Version 2.0 which is available at +# https://www.apache.org/licenses/LICENSE-2.0 +# +# SPDX-License-Identifier: Apache-2.0 +# ******************************************************************************* + """Minimal onboarding agent: collects context, discovers repo, routes workflow.""" from .models import ContextEnvelope, ContributorProfile, RepositoryContext, WorkItem, WorkflowSelection diff --git a/tools/onboarding/tools/onboarding/__main__.py b/tools/onboarding/tools/onboarding/__main__.py index 75f445ba..6d28cdcc 100644 --- a/tools/onboarding/tools/onboarding/__main__.py +++ b/tools/onboarding/tools/onboarding/__main__.py @@ -1,3 +1,16 @@ +# ******************************************************************************* +# Copyright (c) 2026 Contributors to the Eclipse Foundation +# +# See the NOTICE file(s) distributed with this work for additional +# information regarding copyright ownership. +# +# This program and the accompanying materials are made available under the +# terms of the Apache License Version 2.0 which is available at +# https://www.apache.org/licenses/LICENSE-2.0 +# +# SPDX-License-Identifier: Apache-2.0 +# ******************************************************************************* + import sys # Absolute import: Bazel's py_binary stub runs this file as a top-level diff --git a/tools/onboarding/tools/onboarding/agent/onboarding.agent.yaml b/tools/onboarding/tools/onboarding/agent/onboarding.agent.yaml index 590a3b14..4a156af8 100644 --- a/tools/onboarding/tools/onboarding/agent/onboarding.agent.yaml +++ b/tools/onboarding/tools/onboarding/agent/onboarding.agent.yaml @@ -1,3 +1,16 @@ +# ******************************************************************************* +# Copyright (c) 2026 Contributors to the Eclipse Foundation +# +# See the NOTICE file(s) distributed with this work for additional +# information regarding copyright ownership. +# +# This program and the accompanying materials are made available under the +# terms of the Apache License Version 2.0 which is available at +# https://www.apache.org/licenses/LICENSE-2.0 +# +# SPDX-License-Identifier: Apache-2.0 +# ******************************************************************************* + description: "Type /sdlc or KICKOFF to start Eclipse S-CORE onboarding." entry_point: "tools.onboarding.cli:sdlc" skill: "onboarding.skill.md" diff --git a/tools/onboarding/tools/onboarding/agent/onboarding.skill.md b/tools/onboarding/tools/onboarding/agent/onboarding.skill.md index db3c4300..536c142d 100644 --- a/tools/onboarding/tools/onboarding/agent/onboarding.skill.md +++ b/tools/onboarding/tools/onboarding/agent/onboarding.skill.md @@ -1,3 +1,18 @@ + + # Onboarding Skill Single entry point into the Eclipse S-CORE AI SDLC ecosystem. Collects diff --git a/tools/onboarding/tools/onboarding/cli.py b/tools/onboarding/tools/onboarding/cli.py index 3f4198f1..59ca015f 100644 --- a/tools/onboarding/tools/onboarding/cli.py +++ b/tools/onboarding/tools/onboarding/cli.py @@ -1,3 +1,16 @@ +# ******************************************************************************* +# Copyright (c) 2026 Contributors to the Eclipse Foundation +# +# See the NOTICE file(s) distributed with this work for additional +# information regarding copyright ownership. +# +# This program and the accompanying materials are made available under the +# terms of the Apache License Version 2.0 which is available at +# https://www.apache.org/licenses/LICENSE-2.0 +# +# SPDX-License-Identifier: Apache-2.0 +# ******************************************************************************* + """Onboarding CLI: single entry point into the S-CORE AI SDLC ecosystem. Stdlib-only (argparse + input()) so this binary has no external pip diff --git a/tools/onboarding/tools/onboarding/discovery.py b/tools/onboarding/tools/onboarding/discovery.py index 68e4f34a..0489a5c5 100644 --- a/tools/onboarding/tools/onboarding/discovery.py +++ b/tools/onboarding/tools/onboarding/discovery.py @@ -1,3 +1,16 @@ +# ******************************************************************************* +# Copyright (c) 2026 Contributors to the Eclipse Foundation +# +# See the NOTICE file(s) distributed with this work for additional +# information regarding copyright ownership. +# +# This program and the accompanying materials are made available under the +# terms of the Apache License Version 2.0 which is available at +# https://www.apache.org/licenses/LICENSE-2.0 +# +# SPDX-License-Identifier: Apache-2.0 +# ******************************************************************************* + """Repository discovery: auto-detect ASIL, languages, toolchains, build/docs system. Reads MODULE.bazel, project_config.bzl and README.md as plain text (never diff --git a/tools/onboarding/tools/onboarding/examples/sample_session.md b/tools/onboarding/tools/onboarding/examples/sample_session.md index 4c7d71da..943ccab7 100644 --- a/tools/onboarding/tools/onboarding/examples/sample_session.md +++ b/tools/onboarding/tools/onboarding/examples/sample_session.md @@ -1,3 +1,18 @@ + + # Sample Onboarding Session ``` diff --git a/tools/onboarding/tools/onboarding/models.py b/tools/onboarding/tools/onboarding/models.py index 3a24623c..fc7a979e 100644 --- a/tools/onboarding/tools/onboarding/models.py +++ b/tools/onboarding/tools/onboarding/models.py @@ -1,3 +1,16 @@ +# ******************************************************************************* +# Copyright (c) 2026 Contributors to the Eclipse Foundation +# +# See the NOTICE file(s) distributed with this work for additional +# information regarding copyright ownership. +# +# This program and the accompanying materials are made available under the +# terms of the Apache License Version 2.0 which is available at +# https://www.apache.org/licenses/LICENSE-2.0 +# +# SPDX-License-Identifier: Apache-2.0 +# ******************************************************************************* + """Data model for the onboarding context envelope. A single ``context.json`` replaces the earlier per-workflow input files diff --git a/tools/onboarding/tools/onboarding/output.py b/tools/onboarding/tools/onboarding/output.py index 7e20cdf7..d26139c3 100644 --- a/tools/onboarding/tools/onboarding/output.py +++ b/tools/onboarding/tools/onboarding/output.py @@ -1,3 +1,16 @@ +# ******************************************************************************* +# Copyright (c) 2026 Contributors to the Eclipse Foundation +# +# See the NOTICE file(s) distributed with this work for additional +# information regarding copyright ownership. +# +# This program and the accompanying materials are made available under the +# terms of the Apache License Version 2.0 which is available at +# https://www.apache.org/licenses/LICENSE-2.0 +# +# SPDX-License-Identifier: Apache-2.0 +# ******************************************************************************* + """Builds and writes the single onboarding context contract (Phase 4). Replaces the earlier per-workflow files (sdlc_input.json, speckit_input.json, diff --git a/tools/onboarding/tools/onboarding/recommendation.py b/tools/onboarding/tools/onboarding/recommendation.py index fd21025f..73703c26 100644 --- a/tools/onboarding/tools/onboarding/recommendation.py +++ b/tools/onboarding/tools/onboarding/recommendation.py @@ -1,3 +1,16 @@ +# ******************************************************************************* +# Copyright (c) 2026 Contributors to the Eclipse Foundation +# +# See the NOTICE file(s) distributed with this work for additional +# information regarding copyright ownership. +# +# This program and the accompanying materials are made available under the +# terms of the Apache License Version 2.0 which is available at +# https://www.apache.org/licenses/LICENSE-2.0 +# +# SPDX-License-Identifier: Apache-2.0 +# ******************************************************************************* + """Maps onboarding answers to a recommended workflow, allows user override.""" from __future__ import annotations diff --git a/tools/onboarding/tools/onboarding/state_machine.py b/tools/onboarding/tools/onboarding/state_machine.py index a8bbf602..6906a966 100644 --- a/tools/onboarding/tools/onboarding/state_machine.py +++ b/tools/onboarding/tools/onboarding/state_machine.py @@ -1,3 +1,16 @@ +# ******************************************************************************* +# Copyright (c) 2026 Contributors to the Eclipse Foundation +# +# See the NOTICE file(s) distributed with this work for additional +# information regarding copyright ownership. +# +# This program and the accompanying materials are made available under the +# terms of the Apache License Version 2.0 which is available at +# https://www.apache.org/licenses/LICENSE-2.0 +# +# SPDX-License-Identifier: Apache-2.0 +# ******************************************************************************* + """Onboarding state machine. Linear flow with two branch guards (returning contributor skip, confirmation diff --git a/tools/onboarding/tools/onboarding/tests/test_discovery.py b/tools/onboarding/tools/onboarding/tests/test_discovery.py index fa3887b8..164cb04f 100644 --- a/tools/onboarding/tools/onboarding/tests/test_discovery.py +++ b/tools/onboarding/tools/onboarding/tests/test_discovery.py @@ -1,3 +1,16 @@ +# ******************************************************************************* +# Copyright (c) 2026 Contributors to the Eclipse Foundation +# +# See the NOTICE file(s) distributed with this work for additional +# information regarding copyright ownership. +# +# This program and the accompanying materials are made available under the +# terms of the Apache License Version 2.0 which is available at +# https://www.apache.org/licenses/LICENSE-2.0 +# +# SPDX-License-Identifier: Apache-2.0 +# ******************************************************************************* + import tempfile import unittest from pathlib import Path diff --git a/tools/onboarding/tools/onboarding/tests/test_output.py b/tools/onboarding/tools/onboarding/tests/test_output.py index f7bb8f28..51c86209 100644 --- a/tools/onboarding/tools/onboarding/tests/test_output.py +++ b/tools/onboarding/tools/onboarding/tests/test_output.py @@ -1,3 +1,16 @@ +# ******************************************************************************* +# Copyright (c) 2026 Contributors to the Eclipse Foundation +# +# See the NOTICE file(s) distributed with this work for additional +# information regarding copyright ownership. +# +# This program and the accompanying materials are made available under the +# terms of the Apache License Version 2.0 which is available at +# https://www.apache.org/licenses/LICENSE-2.0 +# +# SPDX-License-Identifier: Apache-2.0 +# ******************************************************************************* + import json import tempfile import unittest diff --git a/tools/onboarding/tools/onboarding/tests/test_recommendation.py b/tools/onboarding/tools/onboarding/tests/test_recommendation.py index f0bc91a6..0b0a0b2f 100644 --- a/tools/onboarding/tools/onboarding/tests/test_recommendation.py +++ b/tools/onboarding/tools/onboarding/tests/test_recommendation.py @@ -1,3 +1,16 @@ +# ******************************************************************************* +# Copyright (c) 2026 Contributors to the Eclipse Foundation +# +# See the NOTICE file(s) distributed with this work for additional +# information regarding copyright ownership. +# +# This program and the accompanying materials are made available under the +# terms of the Apache License Version 2.0 which is available at +# https://www.apache.org/licenses/LICENSE-2.0 +# +# SPDX-License-Identifier: Apache-2.0 +# ******************************************************************************* + import unittest from tools.onboarding.recommendation import recommend_workflow, select_workflow diff --git a/tools/onboarding/tools/onboarding/tests/test_state_machine.py b/tools/onboarding/tools/onboarding/tests/test_state_machine.py index 63b8e6cd..506048ad 100644 --- a/tools/onboarding/tools/onboarding/tests/test_state_machine.py +++ b/tools/onboarding/tools/onboarding/tests/test_state_machine.py @@ -1,3 +1,16 @@ +# ******************************************************************************* +# Copyright (c) 2026 Contributors to the Eclipse Foundation +# +# See the NOTICE file(s) distributed with this work for additional +# information regarding copyright ownership. +# +# This program and the accompanying materials are made available under the +# terms of the Apache License Version 2.0 which is available at +# https://www.apache.org/licenses/LICENSE-2.0 +# +# SPDX-License-Identifier: Apache-2.0 +# ******************************************************************************* + import unittest from tools.onboarding.state_machine import OnboardingStateMachine, State diff --git a/tools/onboarding/tools/onboarding/validators.py b/tools/onboarding/tools/onboarding/validators.py index 642d73cf..4edbf9da 100644 --- a/tools/onboarding/tools/onboarding/validators.py +++ b/tools/onboarding/tools/onboarding/validators.py @@ -1,3 +1,16 @@ +# ******************************************************************************* +# Copyright (c) 2026 Contributors to the Eclipse Foundation +# +# See the NOTICE file(s) distributed with this work for additional +# information regarding copyright ownership. +# +# This program and the accompanying materials are made available under the +# terms of the Apache License Version 2.0 which is available at +# https://www.apache.org/licenses/LICENSE-2.0 +# +# SPDX-License-Identifier: Apache-2.0 +# ******************************************************************************* + """Input validation for onboarding answers.""" from __future__ import annotations From b4dc3c62a52f8415e6cf4795e7ddba4b99e71f37 Mon Sep 17 00:00:00 2001 From: "Aryan ." Date: Tue, 15 Sep 2026 19:30:49 +0530 Subject: [PATCH 4/9] style: apply yamlfmt formatting --- tools/onboarding/tools/onboarding/agent/onboarding.agent.yaml | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/tools/onboarding/tools/onboarding/agent/onboarding.agent.yaml b/tools/onboarding/tools/onboarding/agent/onboarding.agent.yaml index 4a156af8..068fd894 100644 --- a/tools/onboarding/tools/onboarding/agent/onboarding.agent.yaml +++ b/tools/onboarding/tools/onboarding/agent/onboarding.agent.yaml @@ -36,5 +36,4 @@ handoffs: agent: code-design notes: > - This agent only recommends a handoff. It never executes downstream agents - automatically; the contributor must confirm before a handoff is started. + This agent only recommends a handoff. It never executes downstream agents automatically; the contributor must confirm before a handoff is started. From 4ee1a3dd413a6a3fdc31b815eb9d74d5fd56197d Mon Sep 17 00:00:00 2001 From: aryansingh0012 Date: Fri, 18 Sep 2026 14:30:05 +0530 Subject: [PATCH 5/9] Update onboarding.agent.yaml Signed-off-by: aryansingh0012 --- tools/onboarding/tools/onboarding/agent/onboarding.agent.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tools/onboarding/tools/onboarding/agent/onboarding.agent.yaml b/tools/onboarding/tools/onboarding/agent/onboarding.agent.yaml index 068fd894..ed89bc7a 100644 --- a/tools/onboarding/tools/onboarding/agent/onboarding.agent.yaml +++ b/tools/onboarding/tools/onboarding/agent/onboarding.agent.yaml @@ -12,7 +12,7 @@ # ******************************************************************************* description: "Type /sdlc or KICKOFF to start Eclipse S-CORE onboarding." -entry_point: "tools.onboarding.cli:sdlc" +entry_point: "tools.onboarding.cli:cli" skill: "onboarding.skill.md" collects: From b44312f48452d8a260afa7faa8f12b1981f26e04 Mon Sep 17 00:00:00 2001 From: "Aryan ." Date: Wed, 23 Sep 2026 18:51:22 +0530 Subject: [PATCH 6/9] trimmed toml --- REUSE.toml | 5 +-- .../onboarding/examples/context_example.json | 23 ----------- .../onboarding/examples/sample_session.md | 40 ------------------- 3 files changed, 1 insertion(+), 67 deletions(-) delete mode 100644 tools/onboarding/tools/onboarding/examples/context_example.json delete mode 100644 tools/onboarding/tools/onboarding/examples/sample_session.md diff --git a/REUSE.toml b/REUSE.toml index 9f0de116..d712f234 100644 --- a/REUSE.toml +++ b/REUSE.toml @@ -39,9 +39,6 @@ SPDX-FileCopyrightText = "Copyright (c) 2026 Contributors to the Eclipse Foundat SPDX-License-Identifier = "Apache-2.0" [[annotations]] -path = [ - "tools/onboarding/tools/onboarding/examples/context_example.json", - "tools/onboarding/tools/onboarding/schemas/context.schema.json", -] +path = ["tools/onboarding/tools/onboarding/schemas/context.schema.json"] SPDX-FileCopyrightText = "Copyright (c) 2026 Contributors to the Eclipse Foundation" SPDX-License-Identifier = "Apache-2.0" diff --git a/tools/onboarding/tools/onboarding/examples/context_example.json b/tools/onboarding/tools/onboarding/examples/context_example.json deleted file mode 100644 index 1da6fb0e..00000000 --- a/tools/onboarding/tools/onboarding/examples/context_example.json +++ /dev/null @@ -1,23 +0,0 @@ -{ - "repository": { - "name": "module_template", - "asil": "QM", - "languages": ["rust", "cpp"], - "toolchains": ["llvm"], - "build_system": "Bazel", - "docs_system": "Sphinx" - }, - "contributor": { - "role": "developer", - "module": null - }, - "work_item": { - "type": "bug_fix", - "description": "" - }, - "workflow": { - "selected": "sdlc_harness", - "reason": "Bug fixes benefit from SDLC Harness traceability.", - "user_override": false - } -} diff --git a/tools/onboarding/tools/onboarding/examples/sample_session.md b/tools/onboarding/tools/onboarding/examples/sample_session.md deleted file mode 100644 index 943ccab7..00000000 --- a/tools/onboarding/tools/onboarding/examples/sample_session.md +++ /dev/null @@ -1,40 +0,0 @@ - - -# Sample Onboarding Session - -``` -$ python -m tools.onboarding -Welcome to Eclipse S-CORE onboarding. Type /sdlc anytime to restart. -Your role: developer -Detected repository 'module_template': ASIL=QM, languages=['cpp', 'rust'], -toolchains=['llvm'], build=Bazel, docs=Sphinx -Contribution type: bug_fix -Recommended workflow: sdlc_harness (Bug fixes benefit from SDLC Harness traceability.) -Workflow (or 'recommend' to accept) [recommend]: recommend - -Summary: role=developer, contribution=bug_fix, workflow=sdlc_harness -Confirm and generate context.json? [Y/n]: y - -Context written to .onboarding/context.json - -Recommended next steps (confirm before starting): - - Start plan-tech-analysis - - Start plan-requirements - - Start code-design -``` - -No downstream agent is started automatically — the contributor picks one of -the recommended next steps and confirms explicitly. From 92ff0374354fede5a6d1b81a4e512c4648f894db Mon Sep 17 00:00:00 2001 From: "Aryan ." Date: Wed, 23 Sep 2026 18:57:57 +0530 Subject: [PATCH 7/9] removed tools name --- AGENTS.md | 2 +- .../tools/onboarding/agent/onboarding.skill.md | 7 +++---- tools/onboarding/tools/onboarding/models.py | 2 +- tools/onboarding/tools/onboarding/output.py | 4 ++-- tools/onboarding/tools/onboarding/recommendation.py | 8 ++------ .../tools/onboarding/schemas/context.schema.json | 2 +- .../tools/onboarding/tests/test_recommendation.py | 12 ++++++------ 7 files changed, 16 insertions(+), 21 deletions(-) diff --git a/AGENTS.md b/AGENTS.md index 7ed885e5..f948e9c8 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -20,7 +20,7 @@ Start onboarding: `/sdlc` (or `bazel run @score_onboarding//tools/onboarding:sdl The onboarding agent (`tools/onboarding/`): - identifies repository context (ASIL, languages, toolchains, build/docs system) - classifies your contribution (bug fix, improvement, PoC, documentation, feature, question) -- recommends a workflow (SDLC Harness, SpecKit, BMAD, Technical Analysis, Issue Planning, Traditional) +- recommends a workflow (SDLC Harness, Technical Analysis, Issue Planning, Traditional) - writes a single context contract to `.onboarding/context.json` - recommends a handoff to the next agent — it never starts one automatically diff --git a/tools/onboarding/tools/onboarding/agent/onboarding.skill.md b/tools/onboarding/tools/onboarding/agent/onboarding.skill.md index 536c142d..b3129022 100644 --- a/tools/onboarding/tools/onboarding/agent/onboarding.skill.md +++ b/tools/onboarding/tools/onboarding/agent/onboarding.skill.md @@ -17,8 +17,7 @@ SPDX-License-Identifier: Apache-2.0 Single entry point into the Eclipse S-CORE AI SDLC ecosystem. Collects context, classifies the contribution, recommends a workflow, and hands off — -it does not execute SDLC Harness, SpecKit, BMAD, Technical Analysis, or -Planning itself. +it does not execute SDLC Harness, Technical Analysis, or Planning itself. ## Role Detection Ask the contributor for their role: `developer`, `reviewer`, `maintainer`, or @@ -43,8 +42,8 @@ Ask for the contribution type: `bug_fix`, `improvement`, `poc`, ## Workflow Recommendation Map contribution type to a workflow (see `recommendation.py`): - `bug_fix` → SDLC Harness -- `improvement` → SpecKit -- `poc` → BMAD +- `improvement` → SDLC Harness +- `poc` → SDLC Harness - `documentation` → Traditional - otherwise → Technical Analysis / Issue Planning diff --git a/tools/onboarding/tools/onboarding/models.py b/tools/onboarding/tools/onboarding/models.py index fc7a979e..c3f73932 100644 --- a/tools/onboarding/tools/onboarding/models.py +++ b/tools/onboarding/tools/onboarding/models.py @@ -14,7 +14,7 @@ """Data model for the onboarding context envelope. A single ``context.json`` replaces the earlier per-workflow input files -(``sdlc_input.json``, ``speckit_input.json``, ``bmad_input.json`` ...). +(``sdlc_input.json``, ...). Every downstream workflow reads the same envelope shape. """ diff --git a/tools/onboarding/tools/onboarding/output.py b/tools/onboarding/tools/onboarding/output.py index d26139c3..fe2990b6 100644 --- a/tools/onboarding/tools/onboarding/output.py +++ b/tools/onboarding/tools/onboarding/output.py @@ -13,8 +13,8 @@ """Builds and writes the single onboarding context contract (Phase 4). -Replaces the earlier per-workflow files (sdlc_input.json, speckit_input.json, -bmad_input.json, ...) with one ``.onboarding/context.json`` every downstream +Replaces the earlier per-workflow files (sdlc_input.json, ...) with one +``.onboarding/context.json`` every downstream workflow can consume. """ diff --git a/tools/onboarding/tools/onboarding/recommendation.py b/tools/onboarding/tools/onboarding/recommendation.py index 73703c26..4ed9a79b 100644 --- a/tools/onboarding/tools/onboarding/recommendation.py +++ b/tools/onboarding/tools/onboarding/recommendation.py @@ -17,8 +17,6 @@ WORKFLOWS = [ "sdlc_harness", - "speckit", - "bmad", "technical_analysis", "issue_planning", "traditional", @@ -28,8 +26,6 @@ # only recommends these; it never executes them. HANDOFF_MAP: dict[str, list[str]] = { "sdlc_harness": ["plan-tech-analysis", "plan-requirements", "code-design"], - "speckit": ["plan-issue-creation", "plan-requirements"], - "bmad": ["plan-tech-analysis", "plan-requirements"], "technical_analysis": ["plan-issue-creation", "plan-requirements"], "issue_planning": ["plan-tech-analysis", "plan-requirements"], "traditional": ["code-design"], @@ -38,8 +34,8 @@ # Base mapping from contribution_type to workflow, per onboarding.skill.md. _CONTRIBUTION_MAP: dict[str, tuple[str, str]] = { "bug_fix": ("sdlc_harness", "Bug fixes benefit from SDLC Harness traceability."), - "improvement": ("speckit", "Improvements are well-suited to spec-driven planning."), - "poc": ("bmad", "Proof-of-concept work fits a Build-Measure-Analyze-Design loop."), + "improvement": ("sdlc_harness", "Improvements require the full SDLC lifecycle for traceability."), + "poc": ("sdlc_harness", "Proof-of-concept work follows SDLC Harness for traceability."), "documentation": ("traditional", "Documentation-only changes can follow the traditional flow."), "feature": ("sdlc_harness", "New features require the full SDLC lifecycle for traceability."), "question": ("issue_planning", "Open questions should start with issue definition."), diff --git a/tools/onboarding/tools/onboarding/schemas/context.schema.json b/tools/onboarding/tools/onboarding/schemas/context.schema.json index 8e61a035..a0e1d8ad 100644 --- a/tools/onboarding/tools/onboarding/schemas/context.schema.json +++ b/tools/onboarding/tools/onboarding/schemas/context.schema.json @@ -50,7 +50,7 @@ "properties": { "selected": { "type": "string", - "enum": ["sdlc_harness", "speckit", "bmad", "technical_analysis", "issue_planning", "traditional"] + "enum": ["sdlc_harness", "technical_analysis", "issue_planning", "traditional"] }, "reason": { "type": "string" }, "user_override": { "type": "boolean" } diff --git a/tools/onboarding/tools/onboarding/tests/test_recommendation.py b/tools/onboarding/tools/onboarding/tests/test_recommendation.py index 0b0a0b2f..c881061b 100644 --- a/tools/onboarding/tools/onboarding/tests/test_recommendation.py +++ b/tools/onboarding/tools/onboarding/tests/test_recommendation.py @@ -21,13 +21,13 @@ def test_bug_fix_recommends_sdlc_harness(self) -> None: workflow, _reason = recommend_workflow("bug_fix", asil="QM") self.assertEqual(workflow, "sdlc_harness") - def test_improvement_recommends_speckit(self) -> None: + def test_improvement_recommends_sdlc_harness(self) -> None: workflow, _reason = recommend_workflow("improvement", asil="QM") - self.assertEqual(workflow, "speckit") + self.assertEqual(workflow, "sdlc_harness") - def test_poc_recommends_bmad(self) -> None: + def test_poc_recommends_sdlc_harness(self) -> None: workflow, _reason = recommend_workflow("poc", asil="QM") - self.assertEqual(workflow, "bmad") + self.assertEqual(workflow, "sdlc_harness") def test_documentation_recommends_traditional(self) -> None: workflow, _reason = recommend_workflow("documentation", asil="QM") @@ -39,8 +39,8 @@ def test_non_qm_asil_forces_sdlc_harness(self) -> None: self.assertIn("ASIL", reason) def test_user_override_is_honored(self) -> None: - selected, overridden = select_workflow("sdlc_harness", user_choice="bmad") - self.assertEqual(selected, "bmad") + selected, overridden = select_workflow("sdlc_harness", user_choice="traditional") + self.assertEqual(selected, "traditional") self.assertTrue(overridden) def test_accepting_recommendation_is_not_an_override(self) -> None: From 4daa01a41bed4046fcc0fd7835b9bc39a857394b Mon Sep 17 00:00:00 2001 From: "Aryan ." Date: Wed, 23 Sep 2026 19:00:32 +0530 Subject: [PATCH 8/9] removed handoff recom --- AGENTS.md | 1 - .../tools/onboarding/agent/onboarding.agent.yaml | 12 +----------- tools/onboarding/tools/onboarding/cli.py | 6 +----- tools/onboarding/tools/onboarding/output.py | 6 ------ tools/onboarding/tools/onboarding/recommendation.py | 13 ------------- .../tools/onboarding/tests/test_output.py | 9 +-------- 6 files changed, 3 insertions(+), 44 deletions(-) diff --git a/AGENTS.md b/AGENTS.md index f948e9c8..d10b419e 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -22,7 +22,6 @@ The onboarding agent (`tools/onboarding/`): - classifies your contribution (bug fix, improvement, PoC, documentation, feature, question) - recommends a workflow (SDLC Harness, Technical Analysis, Issue Planning, Traditional) - writes a single context contract to `.onboarding/context.json` -- recommends a handoff to the next agent — it never starts one automatically See [`tools/onboarding/tools/onboarding/agent/onboarding.skill.md`](tools/onboarding/tools/onboarding/agent/onboarding.skill.md) for the full skill definition. diff --git a/tools/onboarding/tools/onboarding/agent/onboarding.agent.yaml b/tools/onboarding/tools/onboarding/agent/onboarding.agent.yaml index ed89bc7a..9e94bca3 100644 --- a/tools/onboarding/tools/onboarding/agent/onboarding.agent.yaml +++ b/tools/onboarding/tools/onboarding/agent/onboarding.agent.yaml @@ -25,15 +25,5 @@ collects: produces: - .onboarding/context.json -handoffs: - - label: Start Issue Planning - agent: plan-issue-creation - - label: Start Technical Analysis - agent: plan-tech-analysis - - label: Start PLAN - agent: plan-requirements - - label: Start CODE (PoC / Spike) - agent: code-design - notes: > - This agent only recommends a handoff. It never executes downstream agents automatically; the contributor must confirm before a handoff is started. + This agent hands off to downstream agents only on explicit contributor confirmation; it never executes them automatically. diff --git a/tools/onboarding/tools/onboarding/cli.py b/tools/onboarding/tools/onboarding/cli.py index 59ca015f..ed9bd5e8 100644 --- a/tools/onboarding/tools/onboarding/cli.py +++ b/tools/onboarding/tools/onboarding/cli.py @@ -28,7 +28,7 @@ from pathlib import Path from .discovery import discover_repository -from .output import build_context_envelope, handoff_summary, write_context +from .output import build_context_envelope, write_context from .recommendation import WORKFLOWS, recommend_workflow, select_workflow from .state_machine import OnboardingStateMachine, State from .validators import ROLES, validate_contribution_type, validate_role @@ -105,10 +105,6 @@ def run_sdlc(repo_root: Path) -> None: path = write_context(envelope, repo_root) print(f"\nContext written to {path}") - print("\nRecommended next steps (confirm before starting):") - for agent in handoff_summary(envelope): - print(f" - Start {agent}") - def _default_repo_root() -> Path: # Under `bazel run`, cwd is the runfiles sandbox, not the real checkout. diff --git a/tools/onboarding/tools/onboarding/output.py b/tools/onboarding/tools/onboarding/output.py index fe2990b6..8f2450dc 100644 --- a/tools/onboarding/tools/onboarding/output.py +++ b/tools/onboarding/tools/onboarding/output.py @@ -23,7 +23,6 @@ from pathlib import Path from .models import ContextEnvelope, ContributorProfile, RepositoryContext, WorkflowSelection, WorkItem -from .recommendation import get_handoff_recommendations DEFAULT_OUTPUT_DIR = ".onboarding" DEFAULT_OUTPUT_FILE = "context.json" @@ -53,8 +52,3 @@ def write_context(envelope: ContextEnvelope, root: Path, output_dir: str = DEFAU target_path = target_dir / DEFAULT_OUTPUT_FILE target_path.write_text(envelope.to_json() + "\n", encoding="utf-8") return target_path - - -def handoff_summary(envelope: ContextEnvelope) -> list[str]: - """Recommended next agents; onboarding never executes them itself.""" - return get_handoff_recommendations(envelope.workflow.selected) diff --git a/tools/onboarding/tools/onboarding/recommendation.py b/tools/onboarding/tools/onboarding/recommendation.py index 4ed9a79b..e4b24b07 100644 --- a/tools/onboarding/tools/onboarding/recommendation.py +++ b/tools/onboarding/tools/onboarding/recommendation.py @@ -22,15 +22,6 @@ "traditional", ] -# Downstream agents each workflow may hand off to (label -> agent id). Onboarding -# only recommends these; it never executes them. -HANDOFF_MAP: dict[str, list[str]] = { - "sdlc_harness": ["plan-tech-analysis", "plan-requirements", "code-design"], - "technical_analysis": ["plan-issue-creation", "plan-requirements"], - "issue_planning": ["plan-tech-analysis", "plan-requirements"], - "traditional": ["code-design"], -} - # Base mapping from contribution_type to workflow, per onboarding.skill.md. _CONTRIBUTION_MAP: dict[str, tuple[str, str]] = { "bug_fix": ("sdlc_harness", "Bug fixes benefit from SDLC Harness traceability."), @@ -56,7 +47,3 @@ def select_workflow(recommended: str, user_choice: str | None = None) -> tuple[s if user_choice and user_choice in WORKFLOWS: return user_choice, user_choice != recommended return recommended, False - - -def get_handoff_recommendations(workflow: str) -> list[str]: - return HANDOFF_MAP.get(workflow, []) diff --git a/tools/onboarding/tools/onboarding/tests/test_output.py b/tools/onboarding/tools/onboarding/tests/test_output.py index 51c86209..ac8db8d2 100644 --- a/tools/onboarding/tools/onboarding/tests/test_output.py +++ b/tools/onboarding/tools/onboarding/tests/test_output.py @@ -17,7 +17,7 @@ from pathlib import Path from tools.onboarding.models import RepositoryContext -from tools.onboarding.output import build_context_envelope, handoff_summary, write_context +from tools.onboarding.output import build_context_envelope, write_context class TestOutput(unittest.TestCase): @@ -49,13 +49,6 @@ def test_write_context_creates_single_file(self) -> None: written = json.loads(path.read_text(encoding="utf-8")) self.assertEqual(written["workflow"]["selected"], "sdlc_harness") - def test_handoff_summary_matches_workflow(self) -> None: - repository = RepositoryContext(name="module_template", asil="QM") - envelope = build_context_envelope( - repository=repository, role="developer", contribution_type="bug_fix", workflow="traditional" - ) - self.assertEqual(handoff_summary(envelope), ["code-design"]) - if __name__ == "__main__": unittest.main() From 47533a10197b4693b155439a6d92f72031a88b27 Mon Sep 17 00:00:00 2001 From: "Aryan ." Date: Wed, 23 Sep 2026 19:24:07 +0530 Subject: [PATCH 9/9] fix module directory --- tools/onboarding/.bazelversion | 1 + tools/onboarding/MODULE.bazel.lock | 490 +++++++++++++++++++++++++++++ 2 files changed, 491 insertions(+) create mode 100644 tools/onboarding/.bazelversion create mode 100644 tools/onboarding/MODULE.bazel.lock diff --git a/tools/onboarding/.bazelversion b/tools/onboarding/.bazelversion new file mode 100644 index 00000000..df5119ec --- /dev/null +++ b/tools/onboarding/.bazelversion @@ -0,0 +1 @@ +8.7.0 diff --git a/tools/onboarding/MODULE.bazel.lock b/tools/onboarding/MODULE.bazel.lock new file mode 100644 index 00000000..193d70a2 --- /dev/null +++ b/tools/onboarding/MODULE.bazel.lock @@ -0,0 +1,490 @@ +{ + "lockFileVersion": 24, + "registryFileHashes": { + "https://bcr.bazel.build/bazel_registry.json": "8a28e4aff06ee60aed2a8c281907fb8bcbf3b753c91fb5a5c57da3215d5b3497", + "https://bcr.bazel.build/modules/abseil-cpp/20210324.2/MODULE.bazel": "7cd0312e064fde87c8d1cd79ba06c876bd23630c83466e9500321be55c96ace2", + "https://bcr.bazel.build/modules/abseil-cpp/20211102.0/MODULE.bazel": "70390338f7a5106231d20620712f7cccb659cd0e9d073d1991c038eb9fc57589", + "https://bcr.bazel.build/modules/abseil-cpp/20230125.1/MODULE.bazel": "89047429cb0207707b2dface14ba7f8df85273d484c2572755be4bab7ce9c3a0", + "https://bcr.bazel.build/modules/abseil-cpp/20230802.0.bcr.1/MODULE.bazel": "1c8cec495288dccd14fdae6e3f95f772c1c91857047a098fad772034264cc8cb", + "https://bcr.bazel.build/modules/abseil-cpp/20230802.0/MODULE.bazel": "d253ae36a8bd9ee3c5955384096ccb6baf16a1b1e93e858370da0a3b94f77c16", + "https://bcr.bazel.build/modules/abseil-cpp/20230802.1/MODULE.bazel": "fa92e2eb41a04df73cdabeec37107316f7e5272650f81d6cc096418fe647b915", + "https://bcr.bazel.build/modules/abseil-cpp/20240116.1/MODULE.bazel": "37bcdb4440fbb61df6a1c296ae01b327f19e9bb521f9b8e26ec854b6f97309ed", + "https://bcr.bazel.build/modules/abseil-cpp/20240116.1/source.json": "9be551b8d4e3ef76875c0d744b5d6a504a27e3ae67bc6b28f46415fd2d2957da", + "https://bcr.bazel.build/modules/bazel_features/1.1.1/MODULE.bazel": "27b8c79ef57efe08efccbd9dd6ef70d61b4798320b8d3c134fd571f78963dbcd", + "https://bcr.bazel.build/modules/bazel_features/1.11.0/MODULE.bazel": "f9382337dd5a474c3b7d334c2f83e50b6eaedc284253334cf823044a26de03e8", + "https://bcr.bazel.build/modules/bazel_features/1.15.0/MODULE.bazel": "d38ff6e517149dc509406aca0db3ad1efdd890a85e049585b7234d04238e2a4d", + "https://bcr.bazel.build/modules/bazel_features/1.17.0/MODULE.bazel": "039de32d21b816b47bd42c778e0454217e9c9caac4a3cf8e15c7231ee3ddee4d", + "https://bcr.bazel.build/modules/bazel_features/1.18.0/MODULE.bazel": "1be0ae2557ab3a72a57aeb31b29be347bcdc5d2b1eb1e70f39e3851a7e97041a", + "https://bcr.bazel.build/modules/bazel_features/1.19.0/MODULE.bazel": "59adcdf28230d220f0067b1f435b8537dd033bfff8db21335ef9217919c7fb58", + "https://bcr.bazel.build/modules/bazel_features/1.21.0/MODULE.bazel": "675642261665d8eea09989aa3b8afb5c37627f1be178382c320d1b46afba5e3b", + "https://bcr.bazel.build/modules/bazel_features/1.28.0/MODULE.bazel": "4b4200e6cbf8fa335b2c3f43e1d6ef3e240319c33d43d60cc0fbd4b87ece299d", + "https://bcr.bazel.build/modules/bazel_features/1.30.0/MODULE.bazel": "a14b62d05969a293b80257e72e597c2da7f717e1e69fa8b339703ed6731bec87", + "https://bcr.bazel.build/modules/bazel_features/1.30.0/source.json": "b07e17f067fe4f69f90b03b36ef1e08fe0d1f3cac254c1241a1818773e3423bc", + "https://bcr.bazel.build/modules/bazel_features/1.4.1/MODULE.bazel": "e45b6bb2350aff3e442ae1111c555e27eac1d915e77775f6fdc4b351b758b5d7", + "https://bcr.bazel.build/modules/bazel_features/1.9.1/MODULE.bazel": "8f679097876a9b609ad1f60249c49d68bfab783dd9be012faf9d82547b14815a", + "https://bcr.bazel.build/modules/bazel_skylib/1.0.3/MODULE.bazel": "bcb0fd896384802d1ad283b4e4eb4d718eebd8cb820b0a2c3a347fb971afd9d8", + "https://bcr.bazel.build/modules/bazel_skylib/1.1.1/MODULE.bazel": "1add3e7d93ff2e6998f9e118022c84d163917d912f5afafb3058e3d2f1545b5e", + "https://bcr.bazel.build/modules/bazel_skylib/1.2.0/MODULE.bazel": "44fe84260e454ed94ad326352a698422dbe372b21a1ac9f3eab76eb531223686", + "https://bcr.bazel.build/modules/bazel_skylib/1.2.1/MODULE.bazel": "f35baf9da0efe45fa3da1696ae906eea3d615ad41e2e3def4aeb4e8bc0ef9a7a", + "https://bcr.bazel.build/modules/bazel_skylib/1.3.0/MODULE.bazel": "20228b92868bf5cfc41bda7afc8a8ba2a543201851de39d990ec957b513579c5", + "https://bcr.bazel.build/modules/bazel_skylib/1.4.1/MODULE.bazel": "a0dcb779424be33100dcae821e9e27e4f2901d9dfd5333efe5ac6a8d7ab75e1d", + "https://bcr.bazel.build/modules/bazel_skylib/1.4.2/MODULE.bazel": "3bd40978e7a1fac911d5989e6b09d8f64921865a45822d8b09e815eaa726a651", + "https://bcr.bazel.build/modules/bazel_skylib/1.5.0/MODULE.bazel": "32880f5e2945ce6a03d1fbd588e9198c0a959bb42297b2cfaf1685b7bc32e138", + "https://bcr.bazel.build/modules/bazel_skylib/1.6.1/MODULE.bazel": "8fdee2dbaace6c252131c00e1de4b165dc65af02ea278476187765e1a617b917", + "https://bcr.bazel.build/modules/bazel_skylib/1.7.0/MODULE.bazel": "0db596f4563de7938de764cc8deeabec291f55e8ec15299718b93c4423e9796d", + "https://bcr.bazel.build/modules/bazel_skylib/1.7.1/MODULE.bazel": "3120d80c5861aa616222ec015332e5f8d3171e062e3e804a2a0253e1be26e59b", + "https://bcr.bazel.build/modules/bazel_skylib/1.8.2/MODULE.bazel": "69ad6927098316848b34a9142bcc975e018ba27f08c4ff403f50c1b6e646ca67", + "https://bcr.bazel.build/modules/bazel_skylib/1.8.2/source.json": "34a3c8bcf233b835eb74be9d628899bb32999d3e0eadef1947a0a562a2b16ffb", + "https://bcr.bazel.build/modules/buildozer/7.1.2/MODULE.bazel": "2e8dd40ede9c454042645fd8d8d0cd1527966aa5c919de86661e62953cd73d84", + "https://bcr.bazel.build/modules/buildozer/7.1.2/source.json": "c9028a501d2db85793a6996205c8de120944f50a0d570438fcae0457a5f9d1f8", + "https://bcr.bazel.build/modules/google_benchmark/1.8.2/MODULE.bazel": "a70cf1bba851000ba93b58ae2f6d76490a9feb74192e57ab8e8ff13c34ec50cb", + "https://bcr.bazel.build/modules/googletest/1.11.0/MODULE.bazel": "3a83f095183f66345ca86aa13c58b59f9f94a2f81999c093d4eeaa2d262d12f4", + "https://bcr.bazel.build/modules/googletest/1.14.0.bcr.1/MODULE.bazel": "22c31a561553727960057361aa33bf20fb2e98584bc4fec007906e27053f80c6", + "https://bcr.bazel.build/modules/googletest/1.14.0.bcr.1/source.json": "41e9e129f80d8c8bf103a7acc337b76e54fad1214ac0a7084bf24f4cd924b8b4", + "https://bcr.bazel.build/modules/googletest/1.14.0/MODULE.bazel": "cfbcbf3e6eac06ef9d85900f64424708cc08687d1b527f0ef65aa7517af8118f", + "https://bcr.bazel.build/modules/jsoncpp/1.9.5/MODULE.bazel": "31271aedc59e815656f5736f282bb7509a97c7ecb43e927ac1a37966e0578075", + "https://bcr.bazel.build/modules/jsoncpp/1.9.5/source.json": "4108ee5085dd2885a341c7fab149429db457b3169b86eb081fa245eadf69169d", + "https://bcr.bazel.build/modules/libpfm/4.11.0/MODULE.bazel": "45061ff025b301940f1e30d2c16bea596c25b176c8b6b3087e92615adbd52902", + "https://bcr.bazel.build/modules/platforms/0.0.10/MODULE.bazel": "8cb8efaf200bdeb2150d93e162c40f388529a25852b332cec879373771e48ed5", + "https://bcr.bazel.build/modules/platforms/0.0.11/MODULE.bazel": "0daefc49732e227caa8bfa834d65dc52e8cc18a2faf80df25e8caea151a9413f", + "https://bcr.bazel.build/modules/platforms/0.0.11/source.json": "f7e188b79ebedebfe75e9e1d098b8845226c7992b307e28e1496f23112e8fc29", + "https://bcr.bazel.build/modules/platforms/0.0.4/MODULE.bazel": "9b328e31ee156f53f3c416a64f8491f7eb731742655a47c9eec4703a71644aee", + "https://bcr.bazel.build/modules/platforms/0.0.5/MODULE.bazel": "5733b54ea419d5eaf7997054bb55f6a1d0b5ff8aedf0176fef9eea44f3acda37", + "https://bcr.bazel.build/modules/platforms/0.0.6/MODULE.bazel": "ad6eeef431dc52aefd2d77ed20a4b353f8ebf0f4ecdd26a807d2da5aa8cd0615", + "https://bcr.bazel.build/modules/platforms/0.0.7/MODULE.bazel": "72fd4a0ede9ee5c021f6a8dd92b503e089f46c227ba2813ff183b71616034814", + "https://bcr.bazel.build/modules/platforms/0.0.8/MODULE.bazel": "9f142c03e348f6d263719f5074b21ef3adf0b139ee4c5133e2aa35664da9eb2d", + "https://bcr.bazel.build/modules/protobuf/21.7/MODULE.bazel": "a5a29bb89544f9b97edce05642fac225a808b5b7be74038ea3640fae2f8e66a7", + "https://bcr.bazel.build/modules/protobuf/27.0/MODULE.bazel": "7873b60be88844a0a1d8f80b9d5d20cfbd8495a689b8763e76c6372998d3f64c", + "https://bcr.bazel.build/modules/protobuf/27.1/MODULE.bazel": "703a7b614728bb06647f965264967a8ef1c39e09e8f167b3ca0bb1fd80449c0d", + "https://bcr.bazel.build/modules/protobuf/29.0-rc2/MODULE.bazel": "6241d35983510143049943fc0d57937937122baf1b287862f9dc8590fc4c37df", + "https://bcr.bazel.build/modules/protobuf/29.0-rc3/MODULE.bazel": "33c2dfa286578573afc55a7acaea3cada4122b9631007c594bf0729f41c8de92", + "https://bcr.bazel.build/modules/protobuf/29.0/MODULE.bazel": "319dc8bf4c679ff87e71b1ccfb5a6e90a6dbc4693501d471f48662ac46d04e4e", + "https://bcr.bazel.build/modules/protobuf/29.0/source.json": "b857f93c796750eef95f0d61ee378f3420d00ee1dd38627b27193aa482f4f981", + "https://bcr.bazel.build/modules/protobuf/3.19.0/MODULE.bazel": "6b5fbb433f760a99a22b18b6850ed5784ef0e9928a72668b66e4d7ccd47db9b0", + "https://bcr.bazel.build/modules/pybind11_bazel/2.11.1/MODULE.bazel": "88af1c246226d87e65be78ed49ecd1e6f5e98648558c14ce99176da041dc378e", + "https://bcr.bazel.build/modules/pybind11_bazel/2.11.1/source.json": "be4789e951dd5301282729fe3d4938995dc4c1a81c2ff150afc9f1b0504c6022", + "https://bcr.bazel.build/modules/re2/2023-09-01/MODULE.bazel": "cb3d511531b16cfc78a225a9e2136007a48cf8a677e4264baeab57fe78a80206", + "https://bcr.bazel.build/modules/re2/2023-09-01/source.json": "e044ce89c2883cd957a2969a43e79f7752f9656f6b20050b62f90ede21ec6eb4", + "https://bcr.bazel.build/modules/rules_android/0.1.1/MODULE.bazel": "48809ab0091b07ad0182defb787c4c5328bd3a278938415c00a7b69b50c4d3a8", + "https://bcr.bazel.build/modules/rules_android/0.1.1/source.json": "e6986b41626ee10bdc864937ffb6d6bf275bb5b9c65120e6137d56e6331f089e", + "https://bcr.bazel.build/modules/rules_cc/0.0.1/MODULE.bazel": "cb2aa0747f84c6c3a78dad4e2049c154f08ab9d166b1273835a8174940365647", + "https://bcr.bazel.build/modules/rules_cc/0.0.10/MODULE.bazel": "ec1705118f7eaedd6e118508d3d26deba2a4e76476ada7e0e3965211be012002", + "https://bcr.bazel.build/modules/rules_cc/0.0.13/MODULE.bazel": "0e8529ed7b323dad0775ff924d2ae5af7640b23553dfcd4d34344c7e7a867191", + "https://bcr.bazel.build/modules/rules_cc/0.0.14/MODULE.bazel": "5e343a3aac88b8d7af3b1b6d2093b55c347b8eefc2e7d1442f7a02dc8fea48ac", + "https://bcr.bazel.build/modules/rules_cc/0.0.15/MODULE.bazel": "6704c35f7b4a72502ee81f61bf88706b54f06b3cbe5558ac17e2e14666cd5dcc", + "https://bcr.bazel.build/modules/rules_cc/0.0.16/MODULE.bazel": "7661303b8fc1b4d7f532e54e9d6565771fea666fbdf839e0a86affcd02defe87", + "https://bcr.bazel.build/modules/rules_cc/0.0.2/MODULE.bazel": "6915987c90970493ab97393024c156ea8fb9f3bea953b2f3ec05c34f19b5695c", + "https://bcr.bazel.build/modules/rules_cc/0.0.6/MODULE.bazel": "abf360251023dfe3efcef65ab9d56beefa8394d4176dd29529750e1c57eaa33f", + "https://bcr.bazel.build/modules/rules_cc/0.0.8/MODULE.bazel": "964c85c82cfeb6f3855e6a07054fdb159aced38e99a5eecf7bce9d53990afa3e", + "https://bcr.bazel.build/modules/rules_cc/0.0.9/MODULE.bazel": "836e76439f354b89afe6a911a7adf59a6b2518fafb174483ad78a2a2fde7b1c5", + "https://bcr.bazel.build/modules/rules_cc/0.1.1/MODULE.bazel": "2f0222a6f229f0bf44cd711dc13c858dad98c62d52bd51d8fc3a764a83125513", + "https://bcr.bazel.build/modules/rules_cc/0.1.5/MODULE.bazel": "88dfc9361e8b5ae1008ac38f7cdfd45ad738e4fa676a3ad67d19204f045a1fd8", + "https://bcr.bazel.build/modules/rules_cc/0.1.5/source.json": "4bb4fed7f5499775d495739f785a5494a1f854645fa1bac5de131264f5acdf01", + "https://bcr.bazel.build/modules/rules_foreign_cc/0.9.0/MODULE.bazel": "c9e8c682bf75b0e7c704166d79b599f93b72cfca5ad7477df596947891feeef6", + "https://bcr.bazel.build/modules/rules_fuzzing/0.5.2/MODULE.bazel": "40c97d1144356f52905566c55811f13b299453a14ac7769dfba2ac38192337a8", + "https://bcr.bazel.build/modules/rules_fuzzing/0.5.2/source.json": "c8b1e2c717646f1702290959a3302a178fb639d987ab61d548105019f11e527e", + "https://bcr.bazel.build/modules/rules_java/4.0.0/MODULE.bazel": "5a78a7ae82cd1a33cef56dc578c7d2a46ed0dca12643ee45edbb8417899e6f74", + "https://bcr.bazel.build/modules/rules_java/5.3.5/MODULE.bazel": "a4ec4f2db570171e3e5eb753276ee4b389bae16b96207e9d3230895c99644b86", + "https://bcr.bazel.build/modules/rules_java/6.0.0/MODULE.bazel": "8a43b7df601a7ec1af61d79345c17b31ea1fedc6711fd4abfd013ea612978e39", + "https://bcr.bazel.build/modules/rules_java/6.4.0/MODULE.bazel": "e986a9fe25aeaa84ac17ca093ef13a4637f6107375f64667a15999f77db6c8f6", + "https://bcr.bazel.build/modules/rules_java/6.5.2/MODULE.bazel": "1d440d262d0e08453fa0c4d8f699ba81609ed0e9a9a0f02cd10b3e7942e61e31", + "https://bcr.bazel.build/modules/rules_java/7.10.0/MODULE.bazel": "530c3beb3067e870561739f1144329a21c851ff771cd752a49e06e3dc9c2e71a", + "https://bcr.bazel.build/modules/rules_java/7.12.2/MODULE.bazel": "579c505165ee757a4280ef83cda0150eea193eed3bef50b1004ba88b99da6de6", + "https://bcr.bazel.build/modules/rules_java/7.2.0/MODULE.bazel": "06c0334c9be61e6cef2c8c84a7800cef502063269a5af25ceb100b192453d4ab", + "https://bcr.bazel.build/modules/rules_java/7.3.2/MODULE.bazel": "50dece891cfdf1741ea230d001aa9c14398062f2b7c066470accace78e412bc2", + "https://bcr.bazel.build/modules/rules_java/7.6.1/MODULE.bazel": "2f14b7e8a1aa2f67ae92bc69d1ec0fa8d9f827c4e17ff5e5f02e91caa3b2d0fe", + "https://bcr.bazel.build/modules/rules_java/8.14.0/MODULE.bazel": "717717ed40cc69994596a45aec6ea78135ea434b8402fb91b009b9151dd65615", + "https://bcr.bazel.build/modules/rules_java/8.14.0/source.json": "8a88c4ca9e8759da53cddc88123880565c520503321e2566b4e33d0287a3d4bc", + "https://bcr.bazel.build/modules/rules_java/8.3.2/MODULE.bazel": "7336d5511ad5af0b8615fdc7477535a2e4e723a357b6713af439fe8cf0195017", + "https://bcr.bazel.build/modules/rules_java/8.5.1/MODULE.bazel": "d8a9e38cc5228881f7055a6079f6f7821a073df3744d441978e7a43e20226939", + "https://bcr.bazel.build/modules/rules_jvm_external/4.4.2/MODULE.bazel": "a56b85e418c83eb1839819f0b515c431010160383306d13ec21959ac412d2fe7", + "https://bcr.bazel.build/modules/rules_jvm_external/5.1/MODULE.bazel": "33f6f999e03183f7d088c9be518a63467dfd0be94a11d0055fe2d210f89aa909", + "https://bcr.bazel.build/modules/rules_jvm_external/5.2/MODULE.bazel": "d9351ba35217ad0de03816ef3ed63f89d411349353077348a45348b096615036", + "https://bcr.bazel.build/modules/rules_jvm_external/5.3/MODULE.bazel": "bf93870767689637164657731849fb887ad086739bd5d360d90007a581d5527d", + "https://bcr.bazel.build/modules/rules_jvm_external/6.1/MODULE.bazel": "75b5fec090dbd46cf9b7d8ea08cf84a0472d92ba3585b476f44c326eda8059c4", + "https://bcr.bazel.build/modules/rules_jvm_external/6.3/MODULE.bazel": "c998e060b85f71e00de5ec552019347c8bca255062c990ac02d051bb80a38df0", + "https://bcr.bazel.build/modules/rules_jvm_external/6.3/source.json": "6f5f5a5a4419ae4e37c35a5bb0a6ae657ed40b7abc5a5189111b47fcebe43197", + "https://bcr.bazel.build/modules/rules_kotlin/1.9.0/MODULE.bazel": "ef85697305025e5a61f395d4eaede272a5393cee479ace6686dba707de804d59", + "https://bcr.bazel.build/modules/rules_kotlin/1.9.6/MODULE.bazel": "d269a01a18ee74d0335450b10f62c9ed81f2321d7958a2934e44272fe82dcef3", + "https://bcr.bazel.build/modules/rules_kotlin/1.9.6/source.json": "2faa4794364282db7c06600b7e5e34867a564ae91bda7cae7c29c64e9466b7d5", + "https://bcr.bazel.build/modules/rules_license/0.0.3/MODULE.bazel": "627e9ab0247f7d1e05736b59dbb1b6871373de5ad31c3011880b4133cafd4bd0", + "https://bcr.bazel.build/modules/rules_license/0.0.7/MODULE.bazel": "088fbeb0b6a419005b89cf93fe62d9517c0a2b8bb56af3244af65ecfe37e7d5d", + "https://bcr.bazel.build/modules/rules_license/1.0.0/MODULE.bazel": "a7fda60eefdf3d8c827262ba499957e4df06f659330bbe6cdbdb975b768bb65c", + "https://bcr.bazel.build/modules/rules_license/1.0.0/source.json": "a52c89e54cc311196e478f8382df91c15f7a2bfdf4c6cd0e2675cc2ff0b56efb", + "https://bcr.bazel.build/modules/rules_pkg/0.7.0/MODULE.bazel": "df99f03fc7934a4737122518bb87e667e62d780b610910f0447665a7e2be62dc", + "https://bcr.bazel.build/modules/rules_pkg/1.0.1/MODULE.bazel": "5b1df97dbc29623bccdf2b0dcd0f5cb08e2f2c9050aab1092fd39a41e82686ff", + "https://bcr.bazel.build/modules/rules_pkg/1.0.1/source.json": "bd82e5d7b9ce2d31e380dd9f50c111d678c3bdaca190cb76b0e1c71b05e1ba8a", + "https://bcr.bazel.build/modules/rules_proto/4.0.0/MODULE.bazel": "a7a7b6ce9bee418c1a760b3d84f83a299ad6952f9903c67f19e4edd964894e06", + "https://bcr.bazel.build/modules/rules_proto/5.3.0-21.7/MODULE.bazel": "e8dff86b0971688790ae75528fe1813f71809b5afd57facb44dad9e8eca631b7", + "https://bcr.bazel.build/modules/rules_proto/6.0.2/MODULE.bazel": "ce916b775a62b90b61888052a416ccdda405212b6aaeb39522f7dc53431a5e73", + "https://bcr.bazel.build/modules/rules_proto/7.0.2/MODULE.bazel": "bf81793bd6d2ad89a37a40693e56c61b0ee30f7a7fdbaf3eabbf5f39de47dea2", + "https://bcr.bazel.build/modules/rules_proto/7.0.2/source.json": "1e5e7260ae32ef4f2b52fd1d0de8d03b606a44c91b694d2f1afb1d3b28a48ce1", + "https://bcr.bazel.build/modules/rules_python/0.10.2/MODULE.bazel": "cc82bc96f2997baa545ab3ce73f196d040ffb8756fd2d66125a530031cd90e5f", + "https://bcr.bazel.build/modules/rules_python/0.23.1/MODULE.bazel": "49ffccf0511cb8414de28321f5fcf2a31312b47c40cc21577144b7447f2bf300", + "https://bcr.bazel.build/modules/rules_python/0.25.0/MODULE.bazel": "72f1506841c920a1afec76975b35312410eea3aa7b63267436bfb1dd91d2d382", + "https://bcr.bazel.build/modules/rules_python/0.28.0/MODULE.bazel": "cba2573d870babc976664a912539b320cbaa7114cd3e8f053c720171cde331ed", + "https://bcr.bazel.build/modules/rules_python/0.31.0/MODULE.bazel": "93a43dc47ee570e6ec9f5779b2e64c1476a6ce921c48cc9a1678a91dd5f8fd58", + "https://bcr.bazel.build/modules/rules_python/0.4.0/MODULE.bazel": "9208ee05fd48bf09ac60ed269791cf17fb343db56c8226a720fbb1cdf467166c", + "https://bcr.bazel.build/modules/rules_python/0.40.0/MODULE.bazel": "9d1a3cd88ed7d8e39583d9ffe56ae8a244f67783ae89b60caafc9f5cf318ada7", + "https://bcr.bazel.build/modules/rules_python/1.8.5/MODULE.bazel": "28b2d79ed8368d7d45b34bacc220e3c0b99cbcd9392641961b849e4c3f55dd30", + "https://bcr.bazel.build/modules/rules_python/1.8.5/source.json": "e261b03c8804f2582c9536013f987e1ea105a2b38c238aa2ac8f98fc34c8b18a", + "https://bcr.bazel.build/modules/rules_shell/0.2.0/MODULE.bazel": "fda8a652ab3c7d8fee214de05e7a9916d8b28082234e8d2c0094505c5268ed3c", + "https://bcr.bazel.build/modules/rules_shell/0.2.0/source.json": "7f27af3c28037d9701487c4744b5448d26537cc66cdef0d8df7ae85411f8de95", + "https://bcr.bazel.build/modules/stardoc/0.5.1/MODULE.bazel": "1a05d92974d0c122f5ccf09291442580317cdd859f07a8655f1db9a60374f9f8", + "https://bcr.bazel.build/modules/stardoc/0.5.3/MODULE.bazel": "c7f6948dae6999bf0db32c1858ae345f112cacf98f174c7a8bb707e41b974f1c", + "https://bcr.bazel.build/modules/stardoc/0.5.6/MODULE.bazel": "c43dabc564990eeab55e25ed61c07a1aadafe9ece96a4efabb3f8bf9063b71ef", + "https://bcr.bazel.build/modules/stardoc/0.7.0/MODULE.bazel": "05e3d6d30c099b6770e97da986c53bd31844d7f13d41412480ea265ac9e8079c", + "https://bcr.bazel.build/modules/stardoc/0.7.1/MODULE.bazel": "3548faea4ee5dda5580f9af150e79d0f6aea934fc60c1cc50f4efdd9420759e7", + "https://bcr.bazel.build/modules/stardoc/0.7.2/MODULE.bazel": "fc152419aa2ea0f51c29583fab1e8c99ddefd5b3778421845606ee628629e0e5", + "https://bcr.bazel.build/modules/stardoc/0.7.2/source.json": "58b029e5e901d6802967754adf0a9056747e8176f017cfe3607c0851f4d42216", + "https://bcr.bazel.build/modules/upb/0.0.0-20220923-a547704/MODULE.bazel": "7298990c00040a0e2f121f6c32544bab27d4452f80d9ce51349b1a28f3005c43", + "https://bcr.bazel.build/modules/zlib/1.2.11/MODULE.bazel": "07b389abc85fdbca459b69e2ec656ae5622873af3f845e1c9d80fe179f3effa0", + "https://bcr.bazel.build/modules/zlib/1.3.1.bcr.5/MODULE.bazel": "eec517b5bbe5492629466e11dae908d043364302283de25581e3eb944326c4ca", + "https://bcr.bazel.build/modules/zlib/1.3.1.bcr.5/source.json": "22bc55c47af97246cfc093d0acf683a7869377de362b5d1c552c2c2e16b7a806", + "https://bcr.bazel.build/modules/zlib/1.3.1/MODULE.bazel": "751c9940dcfe869f5f7274e1295422a34623555916eb98c174c1e945594bf198" + }, + "selectedYankedVersions": {}, + "moduleExtensions": { + "@@rules_kotlin+//src/main/starlark/core/repositories:bzlmod_setup.bzl%rules_kotlin_extensions": { + "general": { + "bzlTransitiveDigest": "03Qju4tW0vE+0RBuZGuV2A4Hx6AiSkdNahYvworx2aM=", + "usagesDigest": "QI2z8ZUR+mqtbwsf2fLqYdJAkPOHdOV+tF2yVAUgRzw=", + "recordedFileInputs": {}, + "recordedDirentsInputs": {}, + "envVariables": {}, + "generatedRepoSpecs": { + "com_github_jetbrains_kotlin_git": { + "repoRuleId": "@@rules_kotlin+//src/main/starlark/core/repositories:compiler.bzl%kotlin_compiler_git_repository", + "attributes": { + "urls": [ + "https://github.com/JetBrains/kotlin/releases/download/v1.9.23/kotlin-compiler-1.9.23.zip" + ], + "sha256": "93137d3aab9afa9b27cb06a824c2324195c6b6f6179d8a8653f440f5bd58be88" + } + }, + "com_github_jetbrains_kotlin": { + "repoRuleId": "@@rules_kotlin+//src/main/starlark/core/repositories:compiler.bzl%kotlin_capabilities_repository", + "attributes": { + "git_repository_name": "com_github_jetbrains_kotlin_git", + "compiler_version": "1.9.23" + } + }, + "com_github_google_ksp": { + "repoRuleId": "@@rules_kotlin+//src/main/starlark/core/repositories:ksp.bzl%ksp_compiler_plugin_repository", + "attributes": { + "urls": [ + "https://github.com/google/ksp/releases/download/1.9.23-1.0.20/artifacts.zip" + ], + "sha256": "ee0618755913ef7fd6511288a232e8fad24838b9af6ea73972a76e81053c8c2d", + "strip_version": "1.9.23-1.0.20" + } + }, + "com_github_pinterest_ktlint": { + "repoRuleId": "@@bazel_tools//tools/build_defs/repo:http.bzl%http_file", + "attributes": { + "sha256": "01b2e0ef893383a50dbeb13970fe7fa3be36ca3e83259e01649945b09d736985", + "urls": [ + "https://github.com/pinterest/ktlint/releases/download/1.3.0/ktlint" + ], + "executable": true + } + }, + "rules_android": { + "repoRuleId": "@@bazel_tools//tools/build_defs/repo:http.bzl%http_archive", + "attributes": { + "sha256": "cd06d15dd8bb59926e4d65f9003bfc20f9da4b2519985c27e190cddc8b7a7806", + "strip_prefix": "rules_android-0.1.1", + "urls": [ + "https://github.com/bazelbuild/rules_android/archive/v0.1.1.zip" + ] + } + } + }, + "recordedRepoMappingEntries": [ + [ + "rules_kotlin+", + "bazel_tools", + "bazel_tools" + ] + ] + } + }, + "@@rules_python+//python/extensions:config.bzl%config": { + "general": { + "bzlTransitiveDigest": "EcMcbtKZvYmd5Mi1Fpg4EeBBztLHEE5tjO5tLDBYDuU=", + "usagesDigest": "lDbpRfhoWmZCHSaNxwZv/8fF2y0wu2th0G0f/uqX7VM=", + "recordedFileInputs": {}, + "recordedDirentsInputs": {}, + "envVariables": {}, + "generatedRepoSpecs": { + "rules_python_internal": { + "repoRuleId": "@@rules_python+//python/private:internal_config_repo.bzl%internal_config_repo", + "attributes": { + "transition_setting_generators": {}, + "transition_settings": [] + } + }, + "pypi__build": { + "repoRuleId": "@@bazel_tools//tools/build_defs/repo:http.bzl%http_archive", + "attributes": { + "url": "https://files.pythonhosted.org/packages/e2/03/f3c8ba0a6b6e30d7d18c40faab90807c9bb5e9a1e3b2fe2008af624a9c97/build-1.2.1-py3-none-any.whl", + "sha256": "75e10f767a433d9a86e50d83f418e83efc18ede923ee5ff7df93b6cb0306c5d4", + "type": "zip", + "build_file_content": "package(default_visibility = [\"//visibility:public\"])\n\nload(\"@rules_python//python:py_library.bzl\", \"py_library\")\n\npy_library(\n name = \"lib\",\n srcs = glob([\"**/*.py\"]),\n data = glob([\"**/*\"], exclude=[\n # These entries include those put into user-installed dependencies by\n # data_exclude to avoid non-determinism.\n \"**/*.py\",\n \"**/*.pyc\",\n \"**/*.pyc.*\", # During pyc creation, temp files named *.pyc.NNN are created\n \"**/*.dist-info/RECORD\",\n \"BUILD\",\n \"WORKSPACE\",\n ]),\n # This makes this directory a top-level in the python import\n # search path for anything that depends on this.\n imports = [\".\"],\n)\n" + } + }, + "pypi__click": { + "repoRuleId": "@@bazel_tools//tools/build_defs/repo:http.bzl%http_archive", + "attributes": { + "url": "https://files.pythonhosted.org/packages/00/2e/d53fa4befbf2cfa713304affc7ca780ce4fc1fd8710527771b58311a3229/click-8.1.7-py3-none-any.whl", + "sha256": "ae74fb96c20a0277a1d615f1e4d73c8414f5a98db8b799a7931d1582f3390c28", + "type": "zip", + "build_file_content": "package(default_visibility = [\"//visibility:public\"])\n\nload(\"@rules_python//python:py_library.bzl\", \"py_library\")\n\npy_library(\n name = \"lib\",\n srcs = glob([\"**/*.py\"]),\n data = glob([\"**/*\"], exclude=[\n # These entries include those put into user-installed dependencies by\n # data_exclude to avoid non-determinism.\n \"**/*.py\",\n \"**/*.pyc\",\n \"**/*.pyc.*\", # During pyc creation, temp files named *.pyc.NNN are created\n \"**/*.dist-info/RECORD\",\n \"BUILD\",\n \"WORKSPACE\",\n ]),\n # This makes this directory a top-level in the python import\n # search path for anything that depends on this.\n imports = [\".\"],\n)\n" + } + }, + "pypi__colorama": { + "repoRuleId": "@@bazel_tools//tools/build_defs/repo:http.bzl%http_archive", + "attributes": { + "url": "https://files.pythonhosted.org/packages/d1/d6/3965ed04c63042e047cb6a3e6ed1a63a35087b6a609aa3a15ed8ac56c221/colorama-0.4.6-py2.py3-none-any.whl", + "sha256": "4f1d9991f5acc0ca119f9d443620b77f9d6b33703e51011c16baf57afb285fc6", + "type": "zip", + "build_file_content": "package(default_visibility = [\"//visibility:public\"])\n\nload(\"@rules_python//python:py_library.bzl\", \"py_library\")\n\npy_library(\n name = \"lib\",\n srcs = glob([\"**/*.py\"]),\n data = glob([\"**/*\"], exclude=[\n # These entries include those put into user-installed dependencies by\n # data_exclude to avoid non-determinism.\n \"**/*.py\",\n \"**/*.pyc\",\n \"**/*.pyc.*\", # During pyc creation, temp files named *.pyc.NNN are created\n \"**/*.dist-info/RECORD\",\n \"BUILD\",\n \"WORKSPACE\",\n ]),\n # This makes this directory a top-level in the python import\n # search path for anything that depends on this.\n imports = [\".\"],\n)\n" + } + }, + "pypi__importlib_metadata": { + "repoRuleId": "@@bazel_tools//tools/build_defs/repo:http.bzl%http_archive", + "attributes": { + "url": "https://files.pythonhosted.org/packages/2d/0a/679461c511447ffaf176567d5c496d1de27cbe34a87df6677d7171b2fbd4/importlib_metadata-7.1.0-py3-none-any.whl", + "sha256": "30962b96c0c223483ed6cc7280e7f0199feb01a0e40cfae4d4450fc6fab1f570", + "type": "zip", + "build_file_content": "package(default_visibility = [\"//visibility:public\"])\n\nload(\"@rules_python//python:py_library.bzl\", \"py_library\")\n\npy_library(\n name = \"lib\",\n srcs = glob([\"**/*.py\"]),\n data = glob([\"**/*\"], exclude=[\n # These entries include those put into user-installed dependencies by\n # data_exclude to avoid non-determinism.\n \"**/*.py\",\n \"**/*.pyc\",\n \"**/*.pyc.*\", # During pyc creation, temp files named *.pyc.NNN are created\n \"**/*.dist-info/RECORD\",\n \"BUILD\",\n \"WORKSPACE\",\n ]),\n # This makes this directory a top-level in the python import\n # search path for anything that depends on this.\n imports = [\".\"],\n)\n" + } + }, + "pypi__installer": { + "repoRuleId": "@@bazel_tools//tools/build_defs/repo:http.bzl%http_archive", + "attributes": { + "url": "https://files.pythonhosted.org/packages/e5/ca/1172b6638d52f2d6caa2dd262ec4c811ba59eee96d54a7701930726bce18/installer-0.7.0-py3-none-any.whl", + "sha256": "05d1933f0a5ba7d8d6296bb6d5018e7c94fa473ceb10cf198a92ccea19c27b53", + "type": "zip", + "build_file_content": "package(default_visibility = [\"//visibility:public\"])\n\nload(\"@rules_python//python:py_library.bzl\", \"py_library\")\n\npy_library(\n name = \"lib\",\n srcs = glob([\"**/*.py\"]),\n data = glob([\"**/*\"], exclude=[\n # These entries include those put into user-installed dependencies by\n # data_exclude to avoid non-determinism.\n \"**/*.py\",\n \"**/*.pyc\",\n \"**/*.pyc.*\", # During pyc creation, temp files named *.pyc.NNN are created\n \"**/*.dist-info/RECORD\",\n \"BUILD\",\n \"WORKSPACE\",\n ]),\n # This makes this directory a top-level in the python import\n # search path for anything that depends on this.\n imports = [\".\"],\n)\n" + } + }, + "pypi__more_itertools": { + "repoRuleId": "@@bazel_tools//tools/build_defs/repo:http.bzl%http_archive", + "attributes": { + "url": "https://files.pythonhosted.org/packages/50/e2/8e10e465ee3987bb7c9ab69efb91d867d93959095f4807db102d07995d94/more_itertools-10.2.0-py3-none-any.whl", + "sha256": "686b06abe565edfab151cb8fd385a05651e1fdf8f0a14191e4439283421f8684", + "type": "zip", + "build_file_content": "package(default_visibility = [\"//visibility:public\"])\n\nload(\"@rules_python//python:py_library.bzl\", \"py_library\")\n\npy_library(\n name = \"lib\",\n srcs = glob([\"**/*.py\"]),\n data = glob([\"**/*\"], exclude=[\n # These entries include those put into user-installed dependencies by\n # data_exclude to avoid non-determinism.\n \"**/*.py\",\n \"**/*.pyc\",\n \"**/*.pyc.*\", # During pyc creation, temp files named *.pyc.NNN are created\n \"**/*.dist-info/RECORD\",\n \"BUILD\",\n \"WORKSPACE\",\n ]),\n # This makes this directory a top-level in the python import\n # search path for anything that depends on this.\n imports = [\".\"],\n)\n" + } + }, + "pypi__packaging": { + "repoRuleId": "@@bazel_tools//tools/build_defs/repo:http.bzl%http_archive", + "attributes": { + "url": "https://files.pythonhosted.org/packages/49/df/1fceb2f8900f8639e278b056416d49134fb8d84c5942ffaa01ad34782422/packaging-24.0-py3-none-any.whl", + "sha256": "2ddfb553fdf02fb784c234c7ba6ccc288296ceabec964ad2eae3777778130bc5", + "type": "zip", + "build_file_content": "package(default_visibility = [\"//visibility:public\"])\n\nload(\"@rules_python//python:py_library.bzl\", \"py_library\")\n\npy_library(\n name = \"lib\",\n srcs = glob([\"**/*.py\"]),\n data = glob([\"**/*\"], exclude=[\n # These entries include those put into user-installed dependencies by\n # data_exclude to avoid non-determinism.\n \"**/*.py\",\n \"**/*.pyc\",\n \"**/*.pyc.*\", # During pyc creation, temp files named *.pyc.NNN are created\n \"**/*.dist-info/RECORD\",\n \"BUILD\",\n \"WORKSPACE\",\n ]),\n # This makes this directory a top-level in the python import\n # search path for anything that depends on this.\n imports = [\".\"],\n)\n" + } + }, + "pypi__pep517": { + "repoRuleId": "@@bazel_tools//tools/build_defs/repo:http.bzl%http_archive", + "attributes": { + "url": "https://files.pythonhosted.org/packages/25/6e/ca4a5434eb0e502210f591b97537d322546e4833dcb4d470a48c375c5540/pep517-0.13.1-py3-none-any.whl", + "sha256": "31b206f67165b3536dd577c5c3f1518e8fbaf38cbc57efff8369a392feff1721", + "type": "zip", + "build_file_content": "package(default_visibility = [\"//visibility:public\"])\n\nload(\"@rules_python//python:py_library.bzl\", \"py_library\")\n\npy_library(\n name = \"lib\",\n srcs = glob([\"**/*.py\"]),\n data = glob([\"**/*\"], exclude=[\n # These entries include those put into user-installed dependencies by\n # data_exclude to avoid non-determinism.\n \"**/*.py\",\n \"**/*.pyc\",\n \"**/*.pyc.*\", # During pyc creation, temp files named *.pyc.NNN are created\n \"**/*.dist-info/RECORD\",\n \"BUILD\",\n \"WORKSPACE\",\n ]),\n # This makes this directory a top-level in the python import\n # search path for anything that depends on this.\n imports = [\".\"],\n)\n" + } + }, + "pypi__pip": { + "repoRuleId": "@@bazel_tools//tools/build_defs/repo:http.bzl%http_archive", + "attributes": { + "url": "https://files.pythonhosted.org/packages/8a/6a/19e9fe04fca059ccf770861c7d5721ab4c2aebc539889e97c7977528a53b/pip-24.0-py3-none-any.whl", + "sha256": "ba0d021a166865d2265246961bec0152ff124de910c5cc39f1156ce3fa7c69dc", + "type": "zip", + "build_file_content": "package(default_visibility = [\"//visibility:public\"])\n\nload(\"@rules_python//python:py_library.bzl\", \"py_library\")\n\npy_library(\n name = \"lib\",\n srcs = glob([\"**/*.py\"]),\n data = glob([\"**/*\"], exclude=[\n # These entries include those put into user-installed dependencies by\n # data_exclude to avoid non-determinism.\n \"**/*.py\",\n \"**/*.pyc\",\n \"**/*.pyc.*\", # During pyc creation, temp files named *.pyc.NNN are created\n \"**/*.dist-info/RECORD\",\n \"BUILD\",\n \"WORKSPACE\",\n ]),\n # This makes this directory a top-level in the python import\n # search path for anything that depends on this.\n imports = [\".\"],\n)\n" + } + }, + "pypi__pip_tools": { + "repoRuleId": "@@bazel_tools//tools/build_defs/repo:http.bzl%http_archive", + "attributes": { + "url": "https://files.pythonhosted.org/packages/0d/dc/38f4ce065e92c66f058ea7a368a9c5de4e702272b479c0992059f7693941/pip_tools-7.4.1-py3-none-any.whl", + "sha256": "4c690e5fbae2f21e87843e89c26191f0d9454f362d8acdbd695716493ec8b3a9", + "type": "zip", + "build_file_content": "package(default_visibility = [\"//visibility:public\"])\n\nload(\"@rules_python//python:py_library.bzl\", \"py_library\")\n\npy_library(\n name = \"lib\",\n srcs = glob([\"**/*.py\"]),\n data = glob([\"**/*\"], exclude=[\n # These entries include those put into user-installed dependencies by\n # data_exclude to avoid non-determinism.\n \"**/*.py\",\n \"**/*.pyc\",\n \"**/*.pyc.*\", # During pyc creation, temp files named *.pyc.NNN are created\n \"**/*.dist-info/RECORD\",\n \"BUILD\",\n \"WORKSPACE\",\n ]),\n # This makes this directory a top-level in the python import\n # search path for anything that depends on this.\n imports = [\".\"],\n)\n" + } + }, + "pypi__pyproject_hooks": { + "repoRuleId": "@@bazel_tools//tools/build_defs/repo:http.bzl%http_archive", + "attributes": { + "url": "https://files.pythonhosted.org/packages/ae/f3/431b9d5fe7d14af7a32340792ef43b8a714e7726f1d7b69cc4e8e7a3f1d7/pyproject_hooks-1.1.0-py3-none-any.whl", + "sha256": "7ceeefe9aec63a1064c18d939bdc3adf2d8aa1988a510afec15151578b232aa2", + "type": "zip", + "build_file_content": "package(default_visibility = [\"//visibility:public\"])\n\nload(\"@rules_python//python:py_library.bzl\", \"py_library\")\n\npy_library(\n name = \"lib\",\n srcs = glob([\"**/*.py\"]),\n data = glob([\"**/*\"], exclude=[\n # These entries include those put into user-installed dependencies by\n # data_exclude to avoid non-determinism.\n \"**/*.py\",\n \"**/*.pyc\",\n \"**/*.pyc.*\", # During pyc creation, temp files named *.pyc.NNN are created\n \"**/*.dist-info/RECORD\",\n \"BUILD\",\n \"WORKSPACE\",\n ]),\n # This makes this directory a top-level in the python import\n # search path for anything that depends on this.\n imports = [\".\"],\n)\n" + } + }, + "pypi__setuptools": { + "repoRuleId": "@@bazel_tools//tools/build_defs/repo:http.bzl%http_archive", + "attributes": { + "url": "https://files.pythonhosted.org/packages/90/99/158ad0609729111163fc1f674a5a42f2605371a4cf036d0441070e2f7455/setuptools-78.1.1-py3-none-any.whl", + "sha256": "c3a9c4211ff4c309edb8b8c4f1cbfa7ae324c4ba9f91ff254e3d305b9fd54561", + "type": "zip", + "build_file_content": "package(default_visibility = [\"//visibility:public\"])\n\nload(\"@rules_python//python:py_library.bzl\", \"py_library\")\n\npy_library(\n name = \"lib\",\n srcs = glob([\"**/*.py\"]),\n data = glob([\"**/*\"], exclude=[\n # These entries include those put into user-installed dependencies by\n # data_exclude to avoid non-determinism.\n \"**/*.py\",\n \"**/*.pyc\",\n \"**/*.pyc.*\", # During pyc creation, temp files named *.pyc.NNN are created\n \"**/*.dist-info/RECORD\",\n \"BUILD\",\n \"WORKSPACE\",\n ]),\n # This makes this directory a top-level in the python import\n # search path for anything that depends on this.\n imports = [\".\"],\n)\n" + } + }, + "pypi__tomli": { + "repoRuleId": "@@bazel_tools//tools/build_defs/repo:http.bzl%http_archive", + "attributes": { + "url": "https://files.pythonhosted.org/packages/97/75/10a9ebee3fd790d20926a90a2547f0bf78f371b2f13aa822c759680ca7b9/tomli-2.0.1-py3-none-any.whl", + "sha256": "939de3e7a6161af0c887ef91b7d41a53e7c5a1ca976325f429cb46ea9bc30ecc", + "type": "zip", + "build_file_content": "package(default_visibility = [\"//visibility:public\"])\n\nload(\"@rules_python//python:py_library.bzl\", \"py_library\")\n\npy_library(\n name = \"lib\",\n srcs = glob([\"**/*.py\"]),\n data = glob([\"**/*\"], exclude=[\n # These entries include those put into user-installed dependencies by\n # data_exclude to avoid non-determinism.\n \"**/*.py\",\n \"**/*.pyc\",\n \"**/*.pyc.*\", # During pyc creation, temp files named *.pyc.NNN are created\n \"**/*.dist-info/RECORD\",\n \"BUILD\",\n \"WORKSPACE\",\n ]),\n # This makes this directory a top-level in the python import\n # search path for anything that depends on this.\n imports = [\".\"],\n)\n" + } + }, + "pypi__wheel": { + "repoRuleId": "@@bazel_tools//tools/build_defs/repo:http.bzl%http_archive", + "attributes": { + "url": "https://files.pythonhosted.org/packages/7d/cd/d7460c9a869b16c3dd4e1e403cce337df165368c71d6af229a74699622ce/wheel-0.43.0-py3-none-any.whl", + "sha256": "55c570405f142630c6b9f72fe09d9b67cf1477fcf543ae5b8dcb1f5b7377da81", + "type": "zip", + "build_file_content": "package(default_visibility = [\"//visibility:public\"])\n\nload(\"@rules_python//python:py_library.bzl\", \"py_library\")\n\npy_library(\n name = \"lib\",\n srcs = glob([\"**/*.py\"]),\n data = glob([\"**/*\"], exclude=[\n # These entries include those put into user-installed dependencies by\n # data_exclude to avoid non-determinism.\n \"**/*.py\",\n \"**/*.pyc\",\n \"**/*.pyc.*\", # During pyc creation, temp files named *.pyc.NNN are created\n \"**/*.dist-info/RECORD\",\n \"BUILD\",\n \"WORKSPACE\",\n ]),\n # This makes this directory a top-level in the python import\n # search path for anything that depends on this.\n imports = [\".\"],\n)\n" + } + }, + "pypi__zipp": { + "repoRuleId": "@@bazel_tools//tools/build_defs/repo:http.bzl%http_archive", + "attributes": { + "url": "https://files.pythonhosted.org/packages/da/55/a03fd7240714916507e1fcf7ae355bd9d9ed2e6db492595f1a67f61681be/zipp-3.18.2-py3-none-any.whl", + "sha256": "dce197b859eb796242b0622af1b8beb0a722d52aa2f57133ead08edd5bf5374e", + "type": "zip", + "build_file_content": "package(default_visibility = [\"//visibility:public\"])\n\nload(\"@rules_python//python:py_library.bzl\", \"py_library\")\n\npy_library(\n name = \"lib\",\n srcs = glob([\"**/*.py\"]),\n data = glob([\"**/*\"], exclude=[\n # These entries include those put into user-installed dependencies by\n # data_exclude to avoid non-determinism.\n \"**/*.py\",\n \"**/*.pyc\",\n \"**/*.pyc.*\", # During pyc creation, temp files named *.pyc.NNN are created\n \"**/*.dist-info/RECORD\",\n \"BUILD\",\n \"WORKSPACE\",\n ]),\n # This makes this directory a top-level in the python import\n # search path for anything that depends on this.\n imports = [\".\"],\n)\n" + } + } + }, + "recordedRepoMappingEntries": [ + [ + "rules_python+", + "bazel_tools", + "bazel_tools" + ], + [ + "rules_python+", + "pypi__build", + "rules_python++config+pypi__build" + ], + [ + "rules_python+", + "pypi__click", + "rules_python++config+pypi__click" + ], + [ + "rules_python+", + "pypi__colorama", + "rules_python++config+pypi__colorama" + ], + [ + "rules_python+", + "pypi__importlib_metadata", + "rules_python++config+pypi__importlib_metadata" + ], + [ + "rules_python+", + "pypi__installer", + "rules_python++config+pypi__installer" + ], + [ + "rules_python+", + "pypi__more_itertools", + "rules_python++config+pypi__more_itertools" + ], + [ + "rules_python+", + "pypi__packaging", + "rules_python++config+pypi__packaging" + ], + [ + "rules_python+", + "pypi__pep517", + "rules_python++config+pypi__pep517" + ], + [ + "rules_python+", + "pypi__pip", + "rules_python++config+pypi__pip" + ], + [ + "rules_python+", + "pypi__pip_tools", + "rules_python++config+pypi__pip_tools" + ], + [ + "rules_python+", + "pypi__pyproject_hooks", + "rules_python++config+pypi__pyproject_hooks" + ], + [ + "rules_python+", + "pypi__setuptools", + "rules_python++config+pypi__setuptools" + ], + [ + "rules_python+", + "pypi__tomli", + "rules_python++config+pypi__tomli" + ], + [ + "rules_python+", + "pypi__wheel", + "rules_python++config+pypi__wheel" + ], + [ + "rules_python+", + "pypi__zipp", + "rules_python++config+pypi__zipp" + ] + ] + } + }, + "@@rules_python+//python/uv:uv.bzl%uv": { + "general": { + "bzlTransitiveDigest": "ijW9KS7qsIY+yBVvJ+Nr1mzwQox09j13DnE3iIwaeTM=", + "usagesDigest": "c4BCoL7WnccEomzDYulDuOys9pd6N93KaNI4mTVbqi0=", + "recordedFileInputs": {}, + "recordedDirentsInputs": {}, + "envVariables": {}, + "generatedRepoSpecs": { + "uv": { + "repoRuleId": "@@rules_python+//python/uv/private:uv_toolchains_repo.bzl%uv_toolchains_repo", + "attributes": { + "toolchain_type": "'@@rules_python+//python/uv:uv_toolchain_type'", + "toolchain_names": [ + "none" + ], + "toolchain_implementations": { + "none": "'@@rules_python+//python:none'" + }, + "toolchain_compatible_with": { + "none": [ + "@platforms//:incompatible" + ] + }, + "toolchain_target_settings": {} + } + } + }, + "recordedRepoMappingEntries": [ + [ + "rules_python+", + "bazel_tools", + "bazel_tools" + ], + [ + "rules_python+", + "platforms", + "platforms" + ] + ] + } + } + }, + "facts": {} +}