diff --git a/.github/ci-template/ci.yml b/.github/ci-template/ci.yml index 81aa47991..61e6b907f 100644 --- a/.github/ci-template/ci.yml +++ b/.github/ci-template/ci.yml @@ -1,7 +1,7 @@ # Generated by `flext-infra codegen conform` for flext — DO NOT EDIT. name: CI -on: +"on": pull_request: push: branches: @@ -18,23 +18,23 @@ jobs: timeout-minutes: 120 steps: - name: Checkout repository - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 + uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 with: submodules: false fetch-depth: 0 - name: Setup Python - uses: actions/setup-python@5fda3b95a4ea91299a34e894583c3862153e4b97 # v7.0.0 + uses: actions/setup-python@5fda3b95a4ea91299a34e894583c3862153e4b97 # v7.0.0 with: python-version: "3.13" - name: Install uv - uses: astral-sh/setup-uv@c771a70e6277c0a99b617c7a806ffedaca235ff9 # v9.0.0 + uses: astral-sh/setup-uv@c771a70e6277c0a99b617c7a806ffedaca235ff9 # v9.0.0 with: enable-cache: true - name: Install declared toolchain - uses: jdx/mise-action@9e7f7633ff6f6d6048a9418a68d48f288f50eb14 # v4.2.3 + uses: jdx/mise-action@9e7f7633ff6f6d6048a9418a68d48f288f50eb14 # v4.2.3 - name: Setup run: make setup diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 1aae0a178..dabc3c944 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -50,7 +50,6 @@ jobs: submodules: false fetch-depth: 0 - - name: Install mise toolchain uses: jdx/mise-action@9e7f7633ff6f6d6048a9418a68d48f288f50eb14 # v4.2.3 diff --git a/.github/workflows/docs.yml b/.github/workflows/docs.yml index 20a08c29d..c3c0d317e 100644 --- a/.github/workflows/docs.yml +++ b/.github/workflows/docs.yml @@ -1,7 +1,7 @@ # Generated by `flext-infra codegen conform` for flext — DO NOT EDIT. name: Docs -on: +"on": push: branches: - main @@ -92,18 +92,18 @@ jobs: timeout-minutes: 30 steps: - name: Checkout - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 + uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 with: submodules: false fetch-depth: 0 - name: Setup Python - uses: actions/setup-python@5fda3b95a4ea91299a34e894583c3862153e4b97 # v7.0.0 + uses: actions/setup-python@5fda3b95a4ea91299a34e894583c3862153e4b97 # v7.0.0 with: python-version: "3.13" - name: Install uv - uses: astral-sh/setup-uv@c771a70e6277c0a99b617c7a806ffedaca235ff9 # v9.0.0 + uses: astral-sh/setup-uv@c771a70e6277c0a99b617c7a806ffedaca235ff9 # v9.0.0 with: enable-cache: true @@ -149,7 +149,7 @@ jobs: # upload-artifact v4 skips hidden paths by default (artifact silently empty). - name: Upload docs reports on failure if: failure() - uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4.6.2 + uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4.6.2 with: name: docs-reports path: .reports/ @@ -163,18 +163,18 @@ jobs: timeout-minutes: 60 steps: - name: Checkout - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 + uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 with: submodules: false fetch-depth: 0 - name: Setup Python - uses: actions/setup-python@5fda3b95a4ea91299a34e894583c3862153e4b97 # v7.0.0 + uses: actions/setup-python@5fda3b95a4ea91299a34e894583c3862153e4b97 # v7.0.0 with: python-version: "3.13" - name: Install uv - uses: astral-sh/setup-uv@c771a70e6277c0a99b617c7a806ffedaca235ff9 # v9.0.0 + uses: astral-sh/setup-uv@c771a70e6277c0a99b617c7a806ffedaca235ff9 # v9.0.0 with: enable-cache: true @@ -188,10 +188,10 @@ jobs: run: make docs WHAT=build - name: Configure Pages - uses: actions/configure-pages@45bfe0192ca1faeb007ade9deae92b16b8254a0d # v6.0.0 + uses: actions/configure-pages@45bfe0192ca1faeb007ade9deae92b16b8254a0d # v6.0.0 - name: Upload site artifact - uses: actions/upload-pages-artifact@fc324d3547104276b827a68afc52ff2a11cc49c9 # v5.0.0 + uses: actions/upload-pages-artifact@fc324d3547104276b827a68afc52ff2a11cc49c9 # v5.0.0 with: path: .reports/docs/site @@ -207,4 +207,4 @@ jobs: steps: - name: Deploy to GitHub Pages id: deployment - uses: actions/deploy-pages@cd2ce8fcbc39b97be8ca5fce6e763baed58fa128 # v5.0.0 + uses: actions/deploy-pages@cd2ce8fcbc39b97be8ca5fce6e763baed58fa128 # v5.0.0 diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index ab2b0b4b6..a4b71a8dc 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -1,7 +1,7 @@ # Generated by `flext-infra codegen conform` for flext — DO NOT EDIT. name: Workspace Release -on: +"on": push: tags: - "v*" @@ -71,12 +71,12 @@ jobs: RELEASE_VERSION: ${{ needs.identity.outputs.version }} steps: - name: Checkout repository - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 + uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 with: fetch-depth: 0 persist-credentials: false ref: ${{ github.sha }} - submodules: {{ checkout_submodules }} + submodules: false - name: Verify immutable release source shell: bash @@ -99,12 +99,12 @@ jobs: fi - name: Setup Python - uses: actions/setup-python@5fda3b95a4ea91299a34e894583c3862153e4b97 # v7.0.0 + uses: actions/setup-python@5fda3b95a4ea91299a34e894583c3862153e4b97 # v7.0.0 with: python-version: "3.13" - name: Install uv - uses: astral-sh/setup-uv@c771a70e6277c0a99b617c7a806ffedaca235ff9 # v9.0.0 + uses: astral-sh/setup-uv@c771a70e6277c0a99b617c7a806ffedaca235ff9 # v9.0.0 with: enable-cache: false @@ -216,12 +216,12 @@ jobs: RELEASE_VERSION: ${{ needs.identity.outputs.version }} steps: - name: Checkout immutable canary source - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 + uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 with: fetch-depth: 0 persist-credentials: false ref: ${{ github.sha }} - submodules: {{ checkout_submodules }} + submodules: false - name: Verify immutable canary source id: source @@ -248,12 +248,12 @@ jobs: echo "core_oid=$CORE_OID" >> "$GITHUB_OUTPUT" - name: Setup Python - uses: actions/setup-python@5fda3b95a4ea91299a34e894583c3862153e4b97 # v7.0.0 + uses: actions/setup-python@5fda3b95a4ea91299a34e894583c3862153e4b97 # v7.0.0 with: python-version: "3.13" - name: Install uv - uses: astral-sh/setup-uv@c771a70e6277c0a99b617c7a806ffedaca235ff9 # v9.0.0 + uses: astral-sh/setup-uv@c771a70e6277c0a99b617c7a806ffedaca235ff9 # v9.0.0 with: enable-cache: false diff --git a/.gitignore b/.gitignore index 08dce9cdb..68edf18f5 100644 --- a/.gitignore +++ b/.gitignore @@ -50,6 +50,7 @@ scripts/maintenance/ !.taplo.toml !pyrefly.toml !poetry.lock +!uv.lock !ruff-shared.toml !uv.lock @@ -104,6 +105,8 @@ scripts/maintenance/ # BLOCK: AI/Agent Local Data (NEVER track these) .claude/* + +# WHITELIST: Agent skills owned by the workspace root !.agents/skills/ !.agents/skills/** @@ -179,6 +182,14 @@ fix-report.json **/coverage.xml **/*.cover +# Docs verb report artifacts inside docs trees +**/docs/generate-report.md +**/docs/generate-summary.json +**/docs/fix-report.md +**/docs/fix-summary.json +**/docs/audit-report.md +**/docs/audit-summary.json + # Virtual environments inside allowed directories (should never be committed) **/.venv/ **/venv/ @@ -348,13 +359,10 @@ __pyrefly_virtual__/ .venv.*/ *.egg-info/ build/ -context_test/ dist/ node_modules/ -rope_ws/ site/ target/ -tmp_flow_test/ .pyrefly_cache/ .tox/ .flext-sync.lock diff --git a/AGENTS.md b/AGENTS.md index 3b8ee2d06..fa4ac52f9 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -184,6 +184,7 @@ make build WHAT=artifacts - `flext-infra` defaults via project/workspace `config/` overlays — not forked defaults. - Provisioning adjusts and never destroys dirty work; no `git checkout` / `git reset` in setup or member sync. - `make gen APPLY=Y` must be idempotent (following `make gen` reports no drift). +- `flext-infra` codegen owns fleet CI and hook projections; update its config/templates, then regenerate consumers. ## Workspace providers diff --git a/Makefile b/Makefile index 5ca65f672..c8fabb6e0 100644 --- a/Makefile +++ b/Makefile @@ -48,7 +48,7 @@ BRANCH ?= PYTEST_ARGS ?= PYTEST_DIAG_ARGS ?= -rA --durations=0 --tb=long --showlocals PYTEST_REPORT_ARGS ?= -ra --durations=25 --durations-min=0.001 --tb=short -PYTEST_PROCESS_TIMEOUT_SECONDS ?= 60 +PYTEST_PROCESS_TIMEOUT_SECONDS ?= 360 # mro-99ae: the pytest process inherits a hard wall-clock boundary, mirroring # MYPY_BOUNDED, so a hung run is terminated even if the typed runner stalls. PYTEST_BOUNDED = timeout --signal=TERM --kill-after=5s "$(PYTEST_PROCESS_TIMEOUT_SECONDS)s" @@ -117,21 +117,21 @@ _ALLOWED_WHATS_deps := check lock upgrade $(shell sed -n 's/^_custom_deps_\([a-z _ALLOWED_WHATS_build := artifacts $(shell sed -n 's/^_custom_build_\([a-z0-9_-]*\):.*/\1/p' "$(MAKEFILE_ROOT)/custom.mk" 2>/dev/null | sort -u | tr '\n' ' ') _ALLOWED_WHATS_check := all $(shell sed -n 's/^_custom_check_\([a-z0-9_-]*\):.*/\1/p' "$(MAKEFILE_ROOT)/custom.mk" 2>/dev/null | sort -u | tr '\n' ' ') _ALLOWED_WHATS_test := all $(shell sed -n 's/^_custom_test_\([a-z0-9_-]*\):.*/\1/p' "$(MAKEFILE_ROOT)/custom.mk" 2>/dev/null | sort -u | tr '\n' ' ') -_ALLOWED_WHATS_fmt := check all $(shell sed -n 's/^_custom_fmt_\([a-z0-9_-]*\):.*/\1/p' "$(MAKEFILE_ROOT)/custom.mk" 2>/dev/null | sort -u | tr '\n' ' ') -_ALLOWED_WHATS_fix := check all $(shell sed -n 's/^_custom_fix_\([a-z0-9_-]*\):.*/\1/p' "$(MAKEFILE_ROOT)/custom.mk" 2>/dev/null | sort -u | tr '\n' ' ') +_ALLOWED_WHATS_fmt := check all apply $(shell sed -n 's/^_custom_fmt_\([a-z0-9_-]*\):.*/\1/p' "$(MAKEFILE_ROOT)/custom.mk" 2>/dev/null | sort -u | tr '\n' ' ') +_ALLOWED_WHATS_fix := check all apply $(shell sed -n 's/^_custom_fix_\([a-z0-9_-]*\):.*/\1/p' "$(MAKEFILE_ROOT)/custom.mk" 2>/dev/null | sort -u | tr '\n' ' ') _ALLOWED_WHATS_run := default $(shell sed -n 's/^_custom_run_\([a-z0-9_-]*\):.*/\1/p' "$(MAKEFILE_ROOT)/custom.mk" 2>/dev/null | sort -u | tr '\n' ' ') _ALLOWED_WHATS_status := diagnostics $(shell sed -n 's/^_custom_status_\([a-z0-9_-]*\):.*/\1/p' "$(MAKEFILE_ROOT)/custom.mk" 2>/dev/null | sort -u | tr '\n' ' ') _ALLOWED_WHATS_docs := all generate fix audit build validate $(shell sed -n 's/^_custom_docs_\([a-z0-9_-]*\):.*/\1/p' "$(MAKEFILE_ROOT)/custom.mk" 2>/dev/null | sort -u | tr '\n' ' ') _ALLOWED_WHATS_clean := generated $(shell sed -n 's/^_custom_clean_\([a-z0-9_-]*\):.*/\1/p' "$(MAKEFILE_ROOT)/custom.mk" 2>/dev/null | sort -u | tr '\n' ' ') _ALLOWED_WHATS_release := status $(shell sed -n 's/^_custom_release_\([a-z0-9_-]*\):.*/\1/p' "$(MAKEFILE_ROOT)/custom.mk" 2>/dev/null | sort -u | tr '\n' ' ') -_ALLOWED_WHATS_gen := check all $(shell sed -n 's/^_custom_gen_\([a-z0-9_-]*\):.*/\1/p' "$(MAKEFILE_ROOT)/custom.mk" 2>/dev/null | sort -u | tr '\n' ' ') +_ALLOWED_WHATS_gen := check all apply $(shell sed -n 's/^_custom_gen_\([a-z0-9_-]*\):.*/\1/p' "$(MAKEFILE_ROOT)/custom.mk" 2>/dev/null | sort -u | tr '\n' ' ') _ALLOWED_WHATS_worktree := list add update remove $(shell sed -n 's/^_custom_worktree_\([a-z0-9_-]*\):.*/\1/p' "$(MAKEFILE_ROOT)/custom.mk" 2>/dev/null | sort -u | tr '\n' ' ') CHECK_GATES_ALLOWED := lint format pyrefly mypy pyright security markdown smells CHECK_GATES_DEFAULT := lint pyrefly mypy pyright security markdown smells DOCS_ACTIONS := generate fix audit build validate -SERIALIZED_VERBS := check test gen fmt fix deps clean worktree -SERIALIZED_TARGETS := _serialized_check _serialized_test _serialized_gen _serialized_fmt _serialized_fix _serialized_deps _serialized_clean _serialized_worktree +SERIALIZED_VERBS := check test gen fmt fix deps clean worktree docs +SERIALIZED_TARGETS := _serialized_check _serialized_test _serialized_gen _serialized_fmt _serialized_fix _serialized_deps _serialized_clean _serialized_worktree _serialized_docs # End SECTION: verb dispatch # === SECTION: lint/type paths (managed) === @@ -177,11 +177,12 @@ _DEFAULT_gen := check _DEFAULT_worktree := list _APPLY_WHAT_deps := upgrade -_APPLY_WHAT_fmt := all -_APPLY_WHAT_fix := all +_APPLY_WHAT_fmt := apply +_APPLY_WHAT_fix := apply _APPLY_WHAT_run := default +_APPLY_WHAT_docs := generate _APPLY_WHAT_clean := generated -_APPLY_WHAT_gen := all +_APPLY_WHAT_gen := apply _APPLY_WHAT_worktree := update @@ -373,7 +374,7 @@ define _run_for_selected_projects done endef -.PHONY: $(PUBLIC_VERBS) $(SERIALIZED_TARGETS) _builtin_help_usage _builtin_setup_environment _builtin_deps_check _builtin_deps_lock _builtin_deps_upgrade _builtin_build_artifacts _builtin_check_all _builtin_test_all _builtin_fmt_check _builtin_fmt_all _builtin_fix_check _builtin_fix_all _builtin_run_default _builtin_status_diagnostics _builtin_docs_all _builtin_docs_generate _builtin_docs_fix _builtin_docs_audit _builtin_docs_build _builtin_docs_validate _builtin_clean_generated _builtin_release_status _builtin_gen_check _builtin_gen_all _builtin_worktree_list _builtin_worktree_add _builtin_worktree_update _builtin_worktree_remove +.PHONY: $(PUBLIC_VERBS) $(SERIALIZED_TARGETS) _builtin_help_usage _builtin_setup_environment _builtin_deps_check _builtin_deps_lock _builtin_deps_upgrade _builtin_build_artifacts _builtin_check_all _builtin_test_all _builtin_fmt_check _builtin_fmt_all _builtin_fmt_apply _builtin_fix_check _builtin_fix_all _builtin_fix_apply _builtin_run_default _builtin_status_diagnostics _builtin_docs_all _builtin_docs_generate _builtin_docs_fix _builtin_docs_audit _builtin_docs_build _builtin_docs_validate _builtin_clean_generated _builtin_release_status _builtin_gen_check _builtin_gen_all _builtin_gen_apply _builtin_worktree_list _builtin_worktree_add _builtin_worktree_update _builtin_worktree_remove $(filter-out setup $(SERIALIZED_VERBS),$(PUBLIC_VERBS)): $(call _dispatch,$@) @@ -435,6 +436,13 @@ _serialized_worktree: $(call _dispatch,worktree) +docs: _builtin_require_environment + @$(PROJECT_FLEXT_INFRA) workspace serialize-make --workspace "$(PROJECT_ROOT)" --makefile "$(SELF_MAKEFILE)" --verb "docs" --selector-value "$(WHAT)" --apply-token "$(APPLY)" + +_serialized_docs: + $(call _dispatch,docs) + + # `setup` keeps its own recipe (it must not require the environment it is about # to build), but it still runs the pre-/post-setup lifecycle hooks so a project @@ -494,7 +502,7 @@ _builtin_help_usage: - @printf ' %-10s WHAT=%s\n' 'docs' "$$(printf '%s' '$(_ALLOWED_WHATS_docs)' | awk '{$$1=$$1; gsub(/ /, "|"); print}')"; + @printf ' %-10s WHAT=%s APPLY=Y\n' 'docs' "$$(printf '%s' '$(_ALLOWED_WHATS_docs)' | awk '{$$1=$$1; gsub(/ /, "|"); print}')"; @@ -639,10 +647,16 @@ _builtin_setup_submodules: exit 1; \ fi; \ need_fetch=1; \ - if git -C "$$child_root" rev-parse --verify "$$remote_ref" >/dev/null 2>&1 && \ - git -C "$$child_root" merge-base --is-ancestor "$$gitlink" HEAD && \ - git -C "$$child_root" merge-base --is-ancestor "$$remote_ref" HEAD; then \ - need_fetch=0; \ + if git -C "$$child_root" merge-base --is-ancestor "$$gitlink" HEAD; then \ + if git -C "$$child_root" rev-parse --verify "$$remote_ref" >/dev/null 2>&1; then \ + if git -C "$$child_root" merge-base --is-ancestor "$$remote_ref" HEAD; then \ + need_fetch=0; \ + fi; \ + else \ + # Pin is already present; origin tip may be absent on a shallow CI \ + # clone. Origin lag must not fail verify (setup never destroys). \ + need_fetch=0; \ + fi; \ fi; \ if [ "$$need_fetch" -eq 1 ]; then \ git -C "$$child_root" fetch --quiet origin "$$branch" || { \ @@ -777,6 +791,8 @@ _builtin_fmt_all: _builtin_require_environment $(call _require_apply) @$(WORKSPACE_ORCHESTRATE) --verb fmt $(WORKSPACE_PROJECT_ARGS) --make-arg "APPLY=Y" $(if $(filter 1,$(FAIL_FAST)),--fail-fast) +_builtin_fmt_apply: _builtin_fmt_all + _builtin_fix_check: @printf 'ERROR: make fix requires APPLY=Y\n' >&2; exit 2 @@ -784,6 +800,8 @@ _builtin_fix_all: _builtin_require_environment $(call _require_apply) @$(WORKSPACE_ORCHESTRATE) --verb fix $(WORKSPACE_PROJECT_ARGS) --make-arg "APPLY=Y" $(if $(filter 1,$(FAIL_FAST)),--fail-fast) +_builtin_fix_apply: _builtin_fix_all + _builtin_run_default: _builtin_require_environment @$(UV_RUN) $(PROJECT_NAME) $(ARGS) @@ -860,6 +878,8 @@ _builtin_gen_all: _builtin_require_environment @$(PROJECT_FLEXT_INFRA) deps modernize --workspace "$(PROJECT_ROOT)" --apply @$(PROJECT_FLEXT_INFRA) deps extra-paths --workspace "$(PROJECT_ROOT)" --apply +_builtin_gen_apply: _builtin_gen_all + _builtin_worktree_list: @$(PROJECT_FLEXT_INFRA) workspace worktree --workspace "$(WORKSPACE)" --operation list diff --git a/docs/GOVERNANCE.md b/docs/GOVERNANCE.md index 84825b2d3..a5cd4199c 100644 --- a/docs/GOVERNANCE.md +++ b/docs/GOVERNANCE.md @@ -82,7 +82,7 @@ only after it passes: ```bash make check PROJECT= CHECK_GATES= -make val VALIDATE_SCOPE=workspace +make codegen WHAT=check PROJECT= ``` All FLEXT validation uses the root Make dispatcher; never run bare `ruff`, diff --git a/docs/architecture/adr/003-workspace-tooling-hub-distribution.md b/docs/architecture/adr/003-workspace-tooling-hub-distribution.md index 7520562bb..0beef08e8 100644 --- a/docs/architecture/adr/003-workspace-tooling-hub-distribution.md +++ b/docs/architecture/adr/003-workspace-tooling-hub-distribution.md @@ -26,15 +26,11 @@ owner of transitive FLEXT provenance. ### 1. A typed manifest owns repository topology -Each orchestrated workspace has one validated manifest under `config/`. It -declares members, exclusions, repository URL, branch, relative checkout path, -role, profile, and lifecycle state. A typed repository catalog covers: - -- FLEXT repositories at `https://github.com/flext-sh/.git` on - `0.12.0-dev`; -- Cosmos repositories at `https://github.com/datacosmos-br/.git` on - `main`; -- explicitly declared standalone repositories, with no sibling discovery. +Each consumer has one validated `config/workspace.yaml`. It declares its own +members, independent projects, exclusions with justification, repository URLs, +branches, relative checkout paths, topology profile, capabilities, and command +discovery roots. No catalog in `flext-infra` duplicates consumer identities or +topology. Submodule metadata, generated dependency groups, Makefiles, and inventories are derived from that manifest. No other file may independently declare workspace diff --git a/docs/architecture/adr/005-config-settings-constants-templates-schemas-ssot.md b/docs/architecture/adr/005-config-settings-constants-templates-schemas-ssot.md index 976600e06..f8912019c 100644 --- a/docs/architecture/adr/005-config-settings-constants-templates-schemas-ssot.md +++ b/docs/architecture/adr/005-config-settings-constants-templates-schemas-ssot.md @@ -71,11 +71,12 @@ implementations in `flext-infra` are invalid. ### 3. Repository conformance is data-driven -The typed repository catalog and each workspace manifest under `config/` are -the only topology inputs. `flext-infra codegen conform` maps them into typed -models including repository references, workspace specification, Make -specification, uv environment plan, conform request, codegen plan, and codegen -result. +Each consumer's validated `config/workspace.yaml` is its only topology input. +`flext-infra` owns generic schemas, profiles, capabilities, policies, and +templates, but no external product catalog. `flext-infra codegen conform` maps +the manifest into typed models including repository references, workspace +specification, Make specification, uv environment plan, conform request, +codegen plan, and codegen result. Project creation and existing-project conformance call that same pipeline. The pipeline supports only the three Make profiles defined by ADR-004 and uses one diff --git a/docs/architecture/adr/010-unified-project-standardization-via-codegen.md b/docs/architecture/adr/010-unified-project-standardization-via-codegen.md index fcd21d2bc..0507bded9 100644 --- a/docs/architecture/adr/010-unified-project-standardization-via-codegen.md +++ b/docs/architecture/adr/010-unified-project-standardization-via-codegen.md @@ -1,30 +1,25 @@ -# ADR-010 — Unified project standardization (Make, scripts, tests, structure) via flext-infra codegen and flext-tests +# ADR-010 — Unified project standardization via flext-infra codegen and flext-tests -- **Status:** Accepted (planning) — targets the `0.20.0-dev` line +- **Status:** Accepted — split delivery across `0.12.0-dev` and `0.20.0-dev` - **Date:** 2026-07-18 -- **Target line:** FLEXT `0.20.0-dev` (early development and planning). This is a - forward standardization contract; it does not retro-fit the `0.12.0-dev` - release line. -- **Scope:** One common, generated base for every project the workspace - coordinates — root workspace, internal FLEXT packages, loose internal projects - (treated as independent), and external/independent applications (`dcdoc`, - DataOP, DcBackup) — covering Make verbs, scripts, tests, `.venv`/mise/direnv - setup, `pyproject.toml`, package `**init**.py` facades, directory layout, and - canonical module/class/prefix naming for `src`, `tests`, `examples`, `scripts`. -- **Tracking:** ecosystem-standardization epic and children (labelled - `branch:0.20.0-dev`). +- **Amended:** 2026-07-28 +- **Target lines:** `0.12.0-dev` receives the release-blocking generic + manifest, capability, Make, codegen, and external-compatibility contract. + Facade, naming, runtime-directory, layout, and structural-enforcement + refactors remain forward-only on `0.20.0-dev`. +- **Tracking:** `mro-p68a`, external-compatibility gate `mro-p68a.12`, and the + forward ecosystem-standardization epic. - **Complements:** ADR-003 (topology/profiles), ADR-004 (Make/codegen SSOT ownership), ADR-005 (config/settings/constants/templates/schemas SSOT and facade layering), ADR-007 (operational kernel/CLI/transactional conform), ADR-008 (neutral consumer boundaries), ADR-009 (ecosystem coordination). -This ADR does not create a new owner. It unifies and hardens the existing -`flext-infra codegen` pipeline (SSOT `codegen.yaml` with `tooling.yaml`) and the -`flext-tests` shared base, so one generated base works for every project forever. +This ADR does not create a new owner. It separates the compatibility contract +needed to stabilize `flext-infra 0.12.0` from unrelated forward architecture. ## Context -The workspace already has the right owners: +The workspace already has the right generic owners: - `flext-infra codegen conform` is the sole conformance/generation interface (ADR-004), rendering managed files from `codegen.yaml`/`tooling.yaml` and the @@ -32,172 +27,137 @@ The workspace already has the right owners: `project/base/{Makefile,pyproject.toml,.mise.toml,python-version,custom.mk}.j2`, `module_skeleton.py.j2`, `static_package_init.py.j2`, `lazy_init_root.py.j2`). - `flext-tests` owns the shared test base and generic Make test behavior. -- ADR-005 fixes facade layering `c -> t -> p -> m -> u` and the one-owner rule - for `constants.py`/`utilities.py`/`api.py`/`base.py`/`_settings.py`/`_config.py` - and their `_constants/*`, `_utilities/*` private namespaces. +- each consumer owns its topology and capabilities in its local + `config/workspace.yaml`; +- `flext-tests` owns shared Python test behavior, but it does not own Make + routing. -What is missing is not another tool. It is three things: a single validated standard that -every project — including loose internal projects and external applications — is -measured against; a validation-first rollout that reports drift before it -rewrites; and enforcement so the base cannot silently diverge again. +The former text treated all standardization as `0.20.0-dev` work and presented +`boot`, `fmt`, and `val` beside the ADR-004 grammar. That contradicted the +release requirement: an isolated `flext-infra` artifact must provide one real, +generic Make/codegen surface to all release consumers before `0.12.0` can ship. ## Decision -Adopt one generated, enforced standardization base owned by `flext-infra` -codegen + `flext-tests`, applied to every project through three ordered phases. - -### 1. Single standardization surface (SSOT) - -The standard is data, not prose. It lives only in: - -- `flext-infra/.../config/codegen.yaml` — `toolchain`, `profiles`, `make.verbs`, - `managed_files`, `scaffold`, `templates`, `repositories`, `workspaces`. -- `flext-infra/.../config/tooling.yaml` — tool versions and tool config - (ruff, pyrefly, pyright, mypy, pytest) rendered into `pyproject.toml`. -- `flext-tests` — shared fixtures, `conftest` base, and generic test verbs. - -No project hand-maintains these facts. Any per-project need is expressed through -validated `custom.mk` handlers (ADR-004) or declared config, never a fork of the -base. - -### 2. Common verb surface for every project - -Every project — root, member, loose internal (independent), and external — -exposes the same public Make verbs from `base_verbs.mk`: `help`, `boot`, -`build`, `check`, `fmt`, `scan`, `docs`, `docs-serve`, `test`, `val`, and -`fix-enforcement`, plus the operational verbs defined by ADR-004. Loose internal -projects use the `standalone` profile and behave exactly like independent -projects: they own only themselves and never inspect neighbors (ADR-003). - -`setup`/`boot` provisions the identical environment everywhere: mise-pinned -Python `3.13` and uv `0.9.21`, `.venv` via uv, direnv (`.envrc`), and -`pyproject.toml`/`.mise.toml`/`.python-version` rendered from the toolchain SSOT. - -### 3. Canonical structure, facades, and naming (measured, then enforced) - -The generated base fixes one structure for `src`, `tests`, `examples`, -`scripts`: - -- Package facades: `constants.py`, `typings.py`, `protocols.py`, `models.py`, - `utilities.py`, `settings.py`, `config.py`, exposing `c/t/p/m/u` (+ operational - `r/e/x/h/d/s`); private declarations in `_constants/*`, `_typings/*`, - `_protocols/*`, `_models/*`, `_utilities/*`, `_settings.py`, `_config.py`. -- Composition: `api.py` is the thin MRO facade; `base.py` holds the shared MRO - base and Result helpers; `cli.py` holds declarative routes. -- `**init**.py` are generated from `static_package_init.py.j2` / - `lazy_init_root.py.j2` — never hand-written re-export sprawl. -- Naming is one scheme, rendered/validated by codegen: class prefix per project - namespace (e.g. `Flext`, `DataOP`, `DcBackup`, - `DcdocService`), sub-prefixes per concern, canonical subdirectory names, - and module names matching the facet they own. - -Naming and structure are first reported as drift, then rewritten, then enforced -(phases below). No parallel/legacy structural branch survives a green cycle. - -### 3a. Namespaced runtime directories via `settings` - -Every project resolves its filesystem roots only through `settings`, never -through ad-hoc `Path.home()`/`os.environ` derivations. `flext-core` -`FlextSettings` (layer-0) exposes five XDG-aware directories: - -| Field | Linux default | Purpose | -| --- | --- | --- | -| `work_dir` | `$XDG_CACHE_HOME` or `~/.cache/` | scratch/cache | -| `data_dir` | `$XDG_DATA_HOME` or `~/.local/share/` | durable data | -| `config_dir` | `$XDG_CONFIG_HOME` or `~/.config/` | configuration | -| `state_dir` | `$XDG_STATE_HOME` or `~/.local/state/` | state | -| `runtime_dir` | `$XDG_RUNTIME_DIR/` or `/run` | ephemeral sockets/PIDs | - -macOS and Windows map to their native equivalents (`~/Library/...`, -`%LOCALAPPDATA%`/`%APPDATA%`). Consumers read `settings.data_dir` etc.; deriving -these paths by hand is drift that Phase 3 enforcement rejects. - -**`` is the consuming application's namespace, not the library's.** The -segment `` MUST be the namespace of the running application — the project -that uses `flext-core` as its entrypoint — and is shared by every library and -function call at runtime. When `flext-tap-oracle` runs, all directories are -`~/.cache/flext-tap-oracle/…`, `~/.config/flext-tap-oracle/…`, etc., even when a -`flext-cli`, `flext-meltano`, or `flext-core` function resolves a path -internally. A library MUST NEVER use its own name (`flext-cli`) for the -directory segment; it uses the running app's namespace. - -**Resolution rule (owned by `flext-core` `FlextSettings`).** Two things stay -separate: - -- Normal settings fields keep the per-subclass namespaced pattern (each project - reads its own `settings` singleton and its own namespaced sections). -- The directory properties (`cache_dir`, `work_dir`, `data_dir`, `config_dir`, - `state_dir`, `runtime_dir`) are NOT per-subclass. They ALWAYS resolve from the - **root project namespace held by the settings root singleton** — a single - shared source — never from the `env_prefix` of the subclass that happens to - access them. A `flext-cli`/`flext-meltano`/`flext-core` call under application - X therefore returns `~/./X/…`; a library MUST NEVER use its own name for - the directory segment. - -Namespace precedence for that root value, registration being **optional**: - -1. `FlextSettings.set_app_namespace("flext-tap-oracle")` — an entrypoint may - declare the application identity once (first-wins). -2. `FLEXT_APP_NAMESPACE` — environment override when no bootstrap ran. -3. **Root project namespace (default)** — otherwise the running project's own - namespace prevails; registration is never mandatory. - -Per-application overrides use `__DIR` -(e.g. `FLEXT_TAP_ORACLE_WORK_DIR`); namespaces that are not a single safe path -segment are rejected. - -**Implementation ownership.** The `flext-core` `FlextSettings` change that binds -the `*_dir` resolution to the settings root singleton is implemented by the -`flext-core` maintenance lane, not by this standardization work. This ADR only -fixes the contract every consumer must follow; consumer adoption and enforcement -are tracked in Beads. - -### 4. Three ordered phases (same strategy as ADR-020/008/009) - -1. **Validation-first.** `flext-infra codegen conform --mode check` plus a - standardization audit reports every drift (missing verbs, non-standard - layout, wrong facade/`**init**`, naming violations, toolchain/pyproject - drift, non-standard tests/scripts/examples) across all projects, with zero - writes. Output is evidence, not a rewrite. -2. **Refactoring.** `flext-infra codegen conform --mode apply` (and the - `flext-tests` base) migrates each project to the standard in bounded, - ownership-scoped batches, deletion-first (ADR-005 §5), one cut per concern, - no compatibility shim, each batch validated (`ruff`/`pyrefly`/`pytest`). -3. **Enforcement.** The standard becomes declarative enforcement data in - `flext-infra/config/enforcement/*.yaml` evaluated by the rope-semantic engine - (ADR-005 §6), so drift fails a gate instead of returning silently. Every - project runs the same `check`/`val` gates. - -### 5. Applicability to independent and external projects - -Loose internal projects and external applications (`dcdoc`, DataOP, DcBackup) -consume the same generated base through the `standalone` profile and their own -`flext-infra` invocation. This never changes the dependency law of ADR-008/009: -`flext-infra` is invoked as external tooling and never imported by an -application, and no `flext-*` package depends on an application. Standardization -is generation and validation, not runtime composition. +Adopt one generated base with two explicitly separated delivery scopes. + +### 1. The `0.12.0-dev` stabilization subset is release-blocking + +`0.12.0-dev` receives all of the following before release: + +- a consumer-owned, typed `config/workspace.yaml`; +- separate topology (`workspace-root`, `workspace-member`, or `standalone`) and + declared capabilities (Python, Go, Node/frontend, Helm/GitOps, Docker, + documents/content, and scripts); +- declared command-discovery roots and validated discovery from + `scripts//.*` metadata; +- one generated Make surface and one deterministic codegen transaction; +- proof from an isolated candidate wheel across all 51 executable consumer + surfaces. + +The consumer manifest is the sole topology authority. `flext-infra` +`codegen.yaml` and schemas contain only generic profiles, capability contracts, +defaults, policies, and templates. They must not contain AI Hub, Cosmos, or +other consumer identities, branches, members, or exclusions, and conformance +must not compare a local manifest with a duplicated product catalog. + +### 2. The public Make grammar is singular + +Every surface exposes `help` plus exactly the twelve ADR-004 verbs: + +```text +setup deps build check test format run status docs clean release codegen +``` + +`make WHAT=help` lists the choices actually discovered for that +consumer. `PROJECT`, `CHECK_GATES`, `FILE`, `MATCH`, `FAIL_FAST`, and `ARGS` +have uniform meanings. `APPLY=Y` is the only authorization for mutation. +Unknown verbs, selectors, projects, and capabilities fail precisely. A declared +but non-applicable operation reports typed non-applicability; it never becomes +empty success or an implicit fallback. + +Capabilities provide concrete handlers only for applicable operations. +`custom.mk` is limited to private `_custom__` and `pre/post-*` +hooks. It cannot define public targets, replace environment ownership, or patch +the generator. Legacy `boot`, `fmt`, and `val` aliases and competing Taskfile or +handwritten dispatchers are removed after each consumer completes its cutover. + +### 3. Conformance is artifact-isolated and reaches a fixed point + +The release candidate is built with `uv build --no-sources`, installed into an +empty environment, and executed without a source checkout, `PYTHONPATH`, +editable link, or workspace cache. It must support ordinary clones, worktrees, +workspace roots, attached members, and standalone repositories. + +For every selected surface: + +- check mode performs no writes; +- apply requires `APPLY=Y` and writes the complete validated selection; +- `check -> apply -> check` converges, and the second check has no diff; +- staged output is validated by its real Make consumer before any live + activation, upload, service restart, or cluster rollout. + +### 4. The external compatibility matrix is a predecessor gate + +The 51 executable surfaces are: + +- FLEXT root plus 31 projects; +- `.ai-hub`; +- `cosmos-main` root plus 12 independent subprojects; +- `cosmos-docgen` root plus four document subprojects. + +Every surface passes `make help`, `make status`, applicable +`make WHAT=help`, and `make codegen WHAT=check`. Capability-specific +gates then exercise Python, Go, Node/frontend, serialized Helm/GitOps, +Docker/config/scripts, or document build/stage behavior. Upload and deployment +paths remain dry-run unless separately authorized with `APPLY=Y`; the release +gate never activates AI Hub services, uploads to Google Drive, or rolls out a +cluster. + +`flext-infra 0.12.0` release preparation and publication remain blocked until +this matrix is green against the exact candidate artifact SHA. Representative +profiles also run on Ubuntu, macOS, and Windows. Helm is always serialized. + +### 5. Forward-only `0.20.0-dev` architecture + +The historical broader standardization decision remains accepted for +`0.20.0-dev`. It covers: + +- canonical package facades, MRO composition, and generated `__init__.py`; +- module, class, and namespace naming; +- canonical `src`, `tests`, `examples`, and `scripts` layout; +- application-namespaced runtime directories and `FlextSettings` root-singleton + resolution; +- declarative structural and naming enforcement. + +None of these forward refactors is a prerequisite for `0.12.0`. Their existing +planning and drift reports remain historical evidence for the `0.20.0-dev` +lanes and must not be used to expand the stabilization release. ## Consequences -- One base setup (venv/mise/direnv/pyproject) and one verb surface work in every - project, forever, from a single SSOT. -- Structure, facades, `**init**.py`, and naming are generated and enforced, not - re-invented per project. -- Drift is caught before it lands; the base cannot silently fork again. -- Independent and external projects get the same standard without any reverse - dependency. +- The 0.12 release proves generic generation against real consumers instead of + a `flext-infra` product catalog. +- Topology and technological capability are independent typed dimensions. +- Every consumer has the same public grammar without pretending every operation + applies to every stack. +- Forward architecture remains sequenced on `0.20.0-dev`, without being pulled + into release stabilization. ## Verification contract -1. `flext-infra codegen conform --mode check --scope all` is green (byte-idempotent) - on the standardized set; every managed file matches the rendered SSOT. -2. The standardization audit reports zero drift for verbs, layout, facades, - `**init**.py`, toolchain/pyproject, and naming on enforced projects. -3. Enforcement rules exist as `flext-infra/config/enforcement/*.yaml` data and a - naming/structure violation fails `check`/`val`. -4. `flext-tests` base yields identical generic `test` behavior across projects. -5. Independent/external projects pass the same gates with no `flext-*` - reverse dependency (ADR-008 gate stays green). +1. Valid, invalid, incomplete, and unknown-capability manifests fail or pass + through the typed local-manifest contract as specified. +2. Command discovery has no duplicated `WHAT` catalog, and every public help or + invalid-selection path reports the real discovered surface. +3. An isolated wheel proves no source-checkout dependency and reaches the + codegen fixed point. +4. All 51 Linux surfaces and representative cross-platform profiles pass their + applicable public Make gates with no introduced warning, skip, suppression, + fallback, or stale generated output. +5. Exact artifact SHA, consumer SHA, command, working directory, exit code, + decisive output, and public QA evidence are recorded in `mro-p68a.12`. +6. Forward-only structural gates remain tracked on `0.20.0-dev`. ## References diff --git a/docs/architecture/adr/README.md b/docs/architecture/adr/README.md index 269cde591..4ddb5623e 100644 --- a/docs/architecture/adr/README.md +++ b/docs/architecture/adr/README.md @@ -23,6 +23,7 @@ portal. - [ADR-009: Ecosystem coordination and reusable-library evaluation](009-ecosystem-coordination-and-library-evaluation.md) — _Accepted (planning, `0.20.0-dev`)_ - [ADR-010: Unified project standardization (Make, scripts, tests, structure) via - codegen](010-unified-project-standardization-via-codegen.md) — _Accepted (planning, `0.20.0-dev`)_ + codegen](010-unified-project-standardization-via-codegen.md) — _Accepted (0.12 + compatibility subset; forward architecture on `0.20.0-dev`)_ New ADRs should be added only when they represent a real architectural decision with an owning implementation path. diff --git a/docs/architecture/config-ssot-migration-plan.md b/docs/architecture/config-ssot-migration-plan.md index 54c3423c7..1b701e92b 100644 --- a/docs/architecture/config-ssot-migration-plan.md +++ b/docs/architecture/config-ssot-migration-plan.md @@ -26,7 +26,8 @@ epic `mro-wkii.17`. | Surface | Sole owner | | --- | --- | -| repository catalog and workspace manifest | validated data under `flext-infra/config/` and each workspace `config/` | +| consumer topology and capabilities | each consumer's validated `config/workspace.yaml` | +| generic manifest schema, defaults, profiles, and capability policies | `flext-infra/config/` | | universal config/schema/template/file/process operations | public `u.Cli.*` facades in `flext-cli` | | typed conformance plan, enforcement, and transaction | `flext-infra codegen conform` | | generated Makefiles | the single `flext-infra` template layer | @@ -41,7 +42,8 @@ epic `mro-wkii.17`. process, and output primitives before adding consumer logic. 3. Define the typed repository, workspace, Make, uv environment, request, plan, and result models through the FLEXT facades. -4. Move catalog and manifest rows into validated config plus matching schemas. +4. Validate each consumer-owned manifest against the generic schema; do not + duplicate consumer identities or topology inside `flext-infra`. 5. Implement the single `codegen conform` check/apply transaction by composing the existing project generator and migration capabilities. 6. Make project creation emit the initial manifest and invoke conformance. @@ -95,17 +97,18 @@ Any missing, extra, or unclassified member is a hard inventory failure. 1. Conform the Cosmos root as `workspace-root`. 2. Conform Charts and GitOps as members that also pass in independent clones. -3. Mark content-only repositories explicitly and remove invalid inventory - entries rather than treating them as package members. +3. Declare each repository's real Go, Node/frontend, Helm/GitOps, Docker, + config, document/content, or script capabilities; do not use + `content-only` as a substitute for executable metadata. 4. Preserve real chart release behavior behind the canonical commit and push checks, including the clean-commit prerequisite. ## Phase 5 — Conform standalone repositories -Conform `.ai-hub`, Algar migration, GrupoNOS Meltano Native, and Cosmos Docgen -as explicit standalone manifests. Classify each real capability under the -canonical Make responsibility, delete competing automation surfaces, and test -from temporary clones with no sibling directories. +Conform `.ai-hub`, `cosmos-docgen`, and its four document subprojects through +their explicit manifests. Classify each real capability under the canonical +Make responsibility, delete competing automation surfaces, and test from +temporary clones with no sibling directories. ## Phase 6 — Fleet acceptance and deletion proof diff --git a/docs/architecture/ecosystem-coordination.md b/docs/architecture/ecosystem-coordination.md index 1ef2ab8fc..559c72ab6 100644 --- a/docs/architecture/ecosystem-coordination.md +++ b/docs/architecture/ecosystem-coordination.md @@ -7,9 +7,11 @@ stay consistent with each owner-local ADR. It coordinates internal FLEXT packages and the independent external applications and platforms; it never makes an external repository a FLEXT dependency. -**Target line:** FLEXT `0.20.0-dev` (early development and planning). This is a -forward planning contract for `0.20.0-dev`; it does not retro-fit the -`0.12.0-dev` release line. Every coordination Bead is labelled +**Target line:** FLEXT `0.20.0-dev` (early development and planning) owns this +document's broad ecosystem and application-architecture work. The only +`0.12.0-dev` subset is ADR-010's release-blocking manifest, capability, Make, +codegen, and external-compatibility contract; it does not import the remaining +coordination scope. Forward coordination Beads stay labelled `branch:0.20.0-dev`. ## Projects and owners @@ -121,15 +123,11 @@ evidence. ## Project standardization (ADR-010) -All projects — root, internal members, loose internal (independent), and -external applications — share one generated base owned by `flext-infra` codegen -with `flext-tests`: identical Make verbs, `.venv`/mise/direnv/`pyproject` setup, -directory layout, `__init__.py` facades, `c/t/p/m/u` facade files and -`_constants/*`/`_utilities/*` private namespaces, `api.py`/`base.py`/ -`_settings.py`/`_config.py`, and canonical module/class/prefix naming for `src`, -`tests`, `examples`, `scripts`. Rollout is validation-first, then refactoring, -then declarative enforcement. SSOT: `codegen.yaml` + `tooling.yaml` + -`flext-tests`. See +The release-blocking `0.12.0-dev` subset standardizes only the consumer-owned +manifest, declared capabilities, twelve-verb Make grammar, deterministic +codegen, and external compatibility proof. The broader directory layout, +facades, naming, runtime-directory behavior, and structural enforcement remain +part of this document's forward `0.20.0-dev` coordination scope. See [ADR-010](adr/010-unified-project-standardization-via-codegen.md). ## Extraction gate for any new `flext-*` diff --git a/docs/standards/documentation.md b/docs/standards/documentation.md index d7e872350..f43ebb820 100644 --- a/docs/standards/documentation.md +++ b/docs/standards/documentation.md @@ -13,10 +13,10 @@ it is added to the flext-infra engine, never beside it. The canonical entry point is the `docs` verb of the root `Makefile`: ```bash -make docs DOCS_PHASE=generate PROJECT=flext-core APPLY=Y # regenerate derived docs (mutating) -make docs DOCS_PHASE=build PROJECT=flext-core # mkdocs strict build -> .reports/docs/site -make docs DOCS_PHASE=validate PROJECT=flext-core # link/nav/reference validation -make docs DOCS_PHASE=audit PROJECT=flext-core # docstring + content audit +make docs WHAT=generate PROJECT=flext-core APPLY=Y # regenerate derived docs (mutating) +make docs WHAT=build PROJECT=flext-core # strict build -> .reports/docs/site +make docs WHAT=validate PROJECT=flext-core # link/nav/reference validation +make docs WHAT=audit PROJECT=flext-core # docstring + content audit ``` - `generate` is the only mutating phase and **requires `APPLY=Y`**; without it @@ -93,7 +93,7 @@ The workspace documentation site is published to **docs.flext.sh**: - **Facts, not vibes.** Version numbers, test counts, and capability claims in docs must trace to the project metadata or a command output. When a fact cannot be verified cheaply, omit it and point at the gate that produces it - (`make val`, `make check`, `make docs DOCS_PHASE=audit`). + (`make codegen WHAT=check`, `make check`, `make docs WHAT=audit`). - **One home per topic.** A subject has exactly one canonical page; everything else links to it. No duplicated standards across `docs/`, `README.md`, and skills — pointers only. @@ -103,9 +103,9 @@ The workspace documentation site is published to **docs.flext.sh**: A documentation change is complete only with: ```bash -make docs DOCS_PHASE=build # strict build, 0 errors -make docs DOCS_PHASE=validate # links/nav green -make docs DOCS_PHASE=audit # no new placeholder/stale findings +make docs WHAT=build # strict build, 0 errors +make docs WHAT=validate # links/nav green +make docs WHAT=audit # no new placeholder/stale findings ``` and, for generator or template changes under `flext-infra`, the scoped project diff --git a/docs/ways-of-working/worker-lane-contract.md b/docs/ways-of-working/worker-lane-contract.md index 42cdf079e..b53b13f9f 100644 --- a/docs/ways-of-working/worker-lane-contract.md +++ b/docs/ways-of-working/worker-lane-contract.md @@ -32,7 +32,7 @@ the dispatcher: make check CHECK_GATES=lint,format,pyrefly make check PROJECT= CHECK_GATES=pyright,mypy make test PROJECT= -make val WHAT=workspace +make codegen WHAT=check PROJECT= ``` Run the narrowest changed-scope gate first; widen only after it passes. diff --git a/flext-api b/flext-api index 994a74c50..72f943d2b 160000 --- a/flext-api +++ b/flext-api @@ -1 +1 @@ -Subproject commit 994a74c50ffcc891ad0e5e392098c8860dd76eb4 +Subproject commit 72f943d2ba2aba44a1a965e6436638d7f5838265 diff --git a/flext-auth b/flext-auth index 6e7004838..95737e9d0 160000 --- a/flext-auth +++ b/flext-auth @@ -1 +1 @@ -Subproject commit 6e7004838c83954b2033e688d26db60337722158 +Subproject commit 95737e9d0dbd1875902aaef4f45d19d9576b2b95 diff --git a/flext-cli b/flext-cli index 6fb2c2b16..c2a29ddb7 160000 --- a/flext-cli +++ b/flext-cli @@ -1 +1 @@ -Subproject commit 6fb2c2b164d253b3bd5e3ac738c43f7e241784bd +Subproject commit c2a29ddb7c9a7b817d075f053f917e4cd78c9a4f diff --git a/flext-core b/flext-core index a31e9bcdc..a707ffa14 160000 --- a/flext-core +++ b/flext-core @@ -1 +1 @@ -Subproject commit a31e9bcdc67adce488abba0d4cea54586d1a1755 +Subproject commit a707ffa142e45180d065351da6069b9241081086 diff --git a/flext-db-oracle b/flext-db-oracle index b9b598643..de518bf56 160000 --- a/flext-db-oracle +++ b/flext-db-oracle @@ -1 +1 @@ -Subproject commit b9b598643a4cf7c66a01f71b47d07aa17e65c61f +Subproject commit de518bf568b98f53e4d4e2a0a991b756db1d5cc9 diff --git a/flext-dbt-ldap b/flext-dbt-ldap index c6b703faf..17466b86c 160000 --- a/flext-dbt-ldap +++ b/flext-dbt-ldap @@ -1 +1 @@ -Subproject commit c6b703fafd2a66b2f194bc664336daff941bc179 +Subproject commit 17466b86cec61d5323aa1c0e2ad8438f2b98cb17 diff --git a/flext-dbt-ldif b/flext-dbt-ldif index ea5906710..cc1a9db30 160000 --- a/flext-dbt-ldif +++ b/flext-dbt-ldif @@ -1 +1 @@ -Subproject commit ea590671031b637433820d525c2555dd32edc1ac +Subproject commit cc1a9db30b3dd0ad25ae4d3e5af54a4bae91c9fc diff --git a/flext-dbt-oracle b/flext-dbt-oracle index 896bab27d..3fdf02545 160000 --- a/flext-dbt-oracle +++ b/flext-dbt-oracle @@ -1 +1 @@ -Subproject commit 896bab27dcff4304078be172939897815c1bb736 +Subproject commit 3fdf02545055d05bb71e50eb58192f7ac4f9f629 diff --git a/flext-dbt-oracle-wms b/flext-dbt-oracle-wms index 8afbfc1b6..e9f13aa4d 160000 --- a/flext-dbt-oracle-wms +++ b/flext-dbt-oracle-wms @@ -1 +1 @@ -Subproject commit 8afbfc1b6fc87e6e01f3ef8cffe3669a983e96dc +Subproject commit e9f13aa4d7e11b12dd9a308a035740df33d26121 diff --git a/flext-grpc b/flext-grpc index 92df97698..ed0d39bc4 160000 --- a/flext-grpc +++ b/flext-grpc @@ -1 +1 @@ -Subproject commit 92df97698807e7e9af239a5f94243b0f939c6419 +Subproject commit ed0d39bc408c2380f7dc7bb32c5f6db0946af5bf diff --git a/flext-infra b/flext-infra index 64e7c32f3..439c402ba 160000 --- a/flext-infra +++ b/flext-infra @@ -1 +1 @@ -Subproject commit 64e7c32f3f24e3ab2432524b49627b598f8b4556 +Subproject commit 439c402bac9c7d4d75b33d5d1bd386b19950b4b0 diff --git a/flext-ldap b/flext-ldap index 1e5269a66..fb0de4262 160000 --- a/flext-ldap +++ b/flext-ldap @@ -1 +1 @@ -Subproject commit 1e5269a6656d258b78c3ce621e76ab5c70cd9a67 +Subproject commit fb0de4262e2fd21c3f63f2c8fa9a8a59d8a5a979 diff --git a/flext-ldif b/flext-ldif index 8c4de9052..40ab623a8 160000 --- a/flext-ldif +++ b/flext-ldif @@ -1 +1 @@ -Subproject commit 8c4de9052eb5126d6f2b2185219093e4e97db061 +Subproject commit 40ab623a8ffdfc4d5952c8f9fc45e6159c0dcc67 diff --git a/flext-meltano b/flext-meltano index d7239bfca..748821a2d 160000 --- a/flext-meltano +++ b/flext-meltano @@ -1 +1 @@ -Subproject commit d7239bfca1140a48da300836170795f20d058954 +Subproject commit 748821a2db3ebd1b9bd6331b8cad44fcd0634e71 diff --git a/flext-observability b/flext-observability index 9eae11aac..6aba87345 160000 --- a/flext-observability +++ b/flext-observability @@ -1 +1 @@ -Subproject commit 9eae11aac1192a66d7320ef9e935cb39920cb7d7 +Subproject commit 6aba87345e9ff58b889b4c4cc1d50f041b5ac58e diff --git a/flext-oracle-oic b/flext-oracle-oic index 5b155ca58..85bd3ec5f 160000 --- a/flext-oracle-oic +++ b/flext-oracle-oic @@ -1 +1 @@ -Subproject commit 5b155ca58bad6632830961107b67094f2489ead9 +Subproject commit 85bd3ec5fe2c2677f8f0e744bf7711e5da1c3926 diff --git a/flext-oracle-wms b/flext-oracle-wms index 768c71276..7d9debfd7 160000 --- a/flext-oracle-wms +++ b/flext-oracle-wms @@ -1 +1 @@ -Subproject commit 768c712768a544a72718453e5bcbd1d6535ee16f +Subproject commit 7d9debfd79c0d4caa76e92cbdb8e49879cc8edc4 diff --git a/flext-plugin b/flext-plugin index 2da0b846c..db6686b19 160000 --- a/flext-plugin +++ b/flext-plugin @@ -1 +1 @@ -Subproject commit 2da0b846c2e3966986b7ae5ecc3cb8278189a7c2 +Subproject commit db6686b191ab6cc9d171bab5a36736d7f516b1d3 diff --git a/flext-quality b/flext-quality index 9ef632334..0ffaa3ed4 160000 --- a/flext-quality +++ b/flext-quality @@ -1 +1 @@ -Subproject commit 9ef632334624486ab8792a574e806ac849d0cf60 +Subproject commit 0ffaa3ed42e701d75cd3ffbc4181b5ead0493df7 diff --git a/flext-tap-ldap b/flext-tap-ldap index a0cb7cd08..7a7b788f6 160000 --- a/flext-tap-ldap +++ b/flext-tap-ldap @@ -1 +1 @@ -Subproject commit a0cb7cd086a233227be7b4c9d13f4ad01c0e629b +Subproject commit 7a7b788f694e53b06e13d2d65e4a362758843b56 diff --git a/flext-tap-ldif b/flext-tap-ldif index d6ddadd52..4db073774 160000 --- a/flext-tap-ldif +++ b/flext-tap-ldif @@ -1 +1 @@ -Subproject commit d6ddadd52aa3127f88169e95d8aed49e6c180a43 +Subproject commit 4db07377485fb3733ecd21639585b897555bf154 diff --git a/flext-tap-oracle b/flext-tap-oracle index 759db33ce..dfb93ea48 160000 --- a/flext-tap-oracle +++ b/flext-tap-oracle @@ -1 +1 @@ -Subproject commit 759db33cedc097857f0da3b7a0201433bf861de1 +Subproject commit dfb93ea487393ab848598f61a8bee278a98bda72 diff --git a/flext-tap-oracle-oic b/flext-tap-oracle-oic index 58b3d126a..3298d2798 160000 --- a/flext-tap-oracle-oic +++ b/flext-tap-oracle-oic @@ -1 +1 @@ -Subproject commit 58b3d126adb6cccd38324c64fc74446a4f17d814 +Subproject commit 3298d279856e34536416d64fc529526ed5a635c2 diff --git a/flext-tap-oracle-wms b/flext-tap-oracle-wms index 9e7e0024d..2a9f92278 160000 --- a/flext-tap-oracle-wms +++ b/flext-tap-oracle-wms @@ -1 +1 @@ -Subproject commit 9e7e0024debfca2a0ba9a26e9b9ad3d7c2122872 +Subproject commit 2a9f9227832b33f78a550c3113dd73ff6801858e diff --git a/flext-target-ldap b/flext-target-ldap index c093d2503..9af2c5711 160000 --- a/flext-target-ldap +++ b/flext-target-ldap @@ -1 +1 @@ -Subproject commit c093d25036a2b13b4b9c35a45acfe636fa76dd64 +Subproject commit 9af2c571173adc8fe7466cb587738fe0aae0b031 diff --git a/flext-target-ldif b/flext-target-ldif index bc328c990..9ae7d9adf 160000 --- a/flext-target-ldif +++ b/flext-target-ldif @@ -1 +1 @@ -Subproject commit bc328c9906192e418703c468f8ba037ca0c0454c +Subproject commit 9ae7d9adfdd73f341c9c52e47f5ccc1e888ac9ea diff --git a/flext-target-oracle b/flext-target-oracle index ef0b6d174..c265f4d5c 160000 --- a/flext-target-oracle +++ b/flext-target-oracle @@ -1 +1 @@ -Subproject commit ef0b6d174d0c00420ef506ac35dda266e15d2b2b +Subproject commit c265f4d5c3bf07ada33ec00a2bc655953c697b5e diff --git a/flext-target-oracle-oic b/flext-target-oracle-oic index 721157c9a..94d3c267b 160000 --- a/flext-target-oracle-oic +++ b/flext-target-oracle-oic @@ -1 +1 @@ -Subproject commit 721157c9a033d353df5311fa3bc4ea8fc5a376a0 +Subproject commit 94d3c267b69785268ce7436bf69f00b03df2ba89 diff --git a/flext-target-oracle-wms b/flext-target-oracle-wms index f575e6bcf..23eda1f0e 160000 --- a/flext-target-oracle-wms +++ b/flext-target-oracle-wms @@ -1 +1 @@ -Subproject commit f575e6bcf659d0fb1ea29178e7342654c4bc4fda +Subproject commit 23eda1f0ea969fead52fe2172ded90f8c20c4fb1 diff --git a/flext-tests b/flext-tests index f86b59697..7b45bc332 160000 --- a/flext-tests +++ b/flext-tests @@ -1 +1 @@ -Subproject commit f86b59697878304e2ac658c35605827a9a72409a +Subproject commit 7b45bc3322ed4a074c2fe830761e438c40177e60 diff --git a/flext-web b/flext-web index bcf22c5a1..0d09c20aa 160000 --- a/flext-web +++ b/flext-web @@ -1 +1 @@ -Subproject commit bcf22c5a117368eaa7565954714539040e8979d1 +Subproject commit 0d09c20aa0b3c5a30afd502747f0709f40bc3f55 diff --git a/uv.lock b/uv.lock index b60b452e6..b240a6273 100644 --- a/uv.lock +++ b/uv.lock @@ -42,6 +42,15 @@ members = [ "flext-tests", "flext-web", ] +excludes = [ + { package = { name = "flext-cli" }, dependencies = ["flext-core"] }, + { package = { name = "flext-core" }, dependencies = ["flext-cli"] }, + { package = { name = "flext-infra" }, dependencies = ["flext-cli"] }, + { package = { name = "flext-infra" }, dependencies = ["flext-core"] }, + { package = { name = "flext-infra" }, dependencies = ["flext-tests"] }, + { package = { name = "flext-tests" }, dependencies = ["flext-core"] }, + { package = { name = "flext-tests" }, dependencies = ["flext-infra"] }, +] [[package]] name = "actionlint-py" @@ -598,19 +607,20 @@ wheels = [ [[package]] name = "code-review-graph" -version = "2.3.6" +version = "2.3.7" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "fastmcp" }, { name = "mcp" }, { name = "networkx" }, + { name = "pyyaml" }, { name = "tree-sitter" }, { name = "tree-sitter-language-pack" }, { name = "watchdog" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/1c/29/002537342840a09e90961e1c2eee33b87225720173bbbb4aa7096e0d3719/code_review_graph-2.3.6.tar.gz", hash = "sha256:047d4d8a13f0515c5a9ad73716af1e04d5833637d6ddcc4f1b780171b8702105", size = 354942, upload-time = "2026-06-10T18:30:20.525Z" } +sdist = { url = "https://files.pythonhosted.org/packages/02/b3/e202da5d2bc15975cb94153f071474be9d35121b76475c87ade7381a392a/code_review_graph-2.3.7.tar.gz", hash = "sha256:5a44440fd87607761b2fb06341aaab48ad1767c14b3eb98aa7ee2e357da867b8", size = 455605, upload-time = "2026-07-18T00:34:12.608Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/66/c7/01cc7fa8cc574f26118ce3050d8e01d4303d673bf439b1d8d3e009287605/code_review_graph-2.3.6-py3-none-any.whl", hash = "sha256:001c8604d0e22a1b8aa61a24824ab25ef2db81d5ef8d3770a3de0f62704845c7", size = 334774, upload-time = "2026-06-10T18:30:18.815Z" }, + { url = "https://files.pythonhosted.org/packages/f3/8f/2df3fcca285b489d195706b09cefda3e57e7158185cb83905200d7b27199/code_review_graph-2.3.7-py3-none-any.whl", hash = "sha256:12196dce3e673bdec7fba97ae5c4dff7589adee73a721374f62efae76e0fdd88", size = 426655, upload-time = "2026-07-18T00:34:11.05Z" }, ] [package.optional-dependencies] @@ -1544,7 +1554,7 @@ dev = [ { name = "bandit", specifier = ">=1.8" }, { name = "black", specifier = ">=25.1" }, { name = "blacken-docs", specifier = ">=1.19" }, - { name = "code-review-graph", extras = ["all", "embeddings"], specifier = "==2.3.6" }, + { name = "code-review-graph", extras = ["all", "embeddings"], specifier = "==2.3.7" }, { name = "codespell", specifier = ">=2.3" }, { name = "deptry", specifier = ">=0.23" }, { name = "django-stubs", specifier = ">=6.0.6" }, @@ -2068,7 +2078,6 @@ dependencies = [ { name = "cachetools" }, { name = "click" }, { name = "defusedxml" }, - { name = "flext-core" }, { name = "jinja2" }, { name = "jsonschema" }, { name = "openpyxl" }, @@ -2325,7 +2334,6 @@ dev = [ { name = "django-stubs" }, { name = "factory-boy" }, { name = "faker" }, - { name = "flext-cli" }, { name = "flext-infra" }, { name = "flext-tests" }, { name = "hypothesis" }, @@ -3691,8 +3699,6 @@ source = { editable = "flext-infra" } dependencies = [ { name = "defusedxml" }, { name = "filelock" }, - { name = "flext-cli" }, - { name = "flext-core" }, { name = "gitpython" }, { name = "libcst" }, { name = "mkdocs" }, @@ -3718,7 +3724,6 @@ dev = [ { name = "django-stubs" }, { name = "factory-boy" }, { name = "faker" }, - { name = "flext-tests" }, { name = "hypothesis" }, { name = "isort" }, { name = "matplotlib-stubs" }, @@ -7558,8 +7563,6 @@ dependencies = [ { name = "factory-boy" }, { name = "faker" }, { name = "flext-cli" }, - { name = "flext-core" }, - { name = "flext-infra" }, { name = "hypothesis" }, { name = "pytest" }, { name = "pytest-benchmark" }, @@ -7577,9 +7580,6 @@ dependencies = [ ] [package.dev-dependencies] -codegen = [ - { name = "flext-infra" }, -] dev = [ { name = "actionlint-py" }, { name = "autoflake" },