From 1a761c62e5c83992ebf9412051ec6d90e7cc0942 Mon Sep 17 00:00:00 2001 From: Bill Date: Mon, 23 Feb 2026 19:30:39 -0700 Subject: [PATCH] Add hybrid AST/language pipeline contract and validator --- docs/HYBRID_PIPELINE_CONTRACT.md | 53 ++++++ docs/SPRINT_TASKITEM_EXECUTION_POLICY.md | 13 ++ tools/mcp/README.md | 6 + .../mcp/validate_hybrid_pipeline_contract.sh | 157 ++++++++++++++++++ 4 files changed, 229 insertions(+) create mode 100644 docs/HYBRID_PIPELINE_CONTRACT.md create mode 100755 tools/mcp/validate_hybrid_pipeline_contract.sh diff --git a/docs/HYBRID_PIPELINE_CONTRACT.md b/docs/HYBRID_PIPELINE_CONTRACT.md new file mode 100644 index 0000000..f2f37d4 --- /dev/null +++ b/docs/HYBRID_PIPELINE_CONTRACT.md @@ -0,0 +1,53 @@ +# Hybrid Pipeline Contract + +This editor supports two entry paths: + +1. `language-first`: operate from source text in a target language. +2. `ast-first`: operate directly on canonical AST/IR structures. + +Both paths must converge on shared canonical semantics before projection to a target language. + +## Contract Rules + +1. Canonical-first convergence +- Every sprint result should include canonical signals (for example `AST`, `IR`, `Schema`, `Canonical`, `Semantic`, `Model`) in integration artifacts. + +2. Projection neutrality +- Every sprint should show evidence that behavior is not locked to C++ only. +- Acceptable evidence includes non-C++ language/projection signals (for example `Rust`, `Go`, `Java`, `Python`, `TypeScript`, `Wasm`, SQL-family adapters). + +3. C++ as backend, not source of truth +- C++ implementation artifacts are valid runtime host/projection work. +- They are not sufficient alone to satisfy hybrid pipeline quality. + +## Validation Script + +Use: + +```bash +./tools/mcp/validate_hybrid_pipeline_contract.sh --start 50 --end 90 +``` + +Strict enforcement (fail CI/run if checks fail): + +```bash +./tools/mcp/validate_hybrid_pipeline_contract.sh \ + --start 50 --end 90 --strict --enforce-non-cpp +``` + +Write machine-readable report: + +```bash +./tools/mcp/validate_hybrid_pipeline_contract.sh \ + --start 50 --end 90 --json-out logs/taskitem_runs/hybrid_contract_50_90.json +``` + +## Suggested Workflow Hook + +After finishing a sprint batch: + +1. Run taskitem pipeline. +2. Export LoRA capture. +3. Run hybrid contract validator. +4. Treat failures as blocking when preparing training-ready data. + diff --git a/docs/SPRINT_TASKITEM_EXECUTION_POLICY.md b/docs/SPRINT_TASKITEM_EXECUTION_POLICY.md index 2779b32..62ae3e8 100644 --- a/docs/SPRINT_TASKITEM_EXECUTION_POLICY.md +++ b/docs/SPRINT_TASKITEM_EXECUTION_POLICY.md @@ -51,6 +51,19 @@ Example: - Preserve all run artifacts under `logs/taskitem_runs/` - Preserve JSONL append-only history under `training_data/lora/` +## Hybrid Contract Gate + +To reduce C++-first bias while keeping language-first and AST-first workflows available, +run the hybrid contract validator after sprint execution: + +`tools/mcp/validate_hybrid_pipeline_contract.sh --start --end ` + +Use strict blocking mode for enforcement: + +`tools/mcp/validate_hybrid_pipeline_contract.sh --start --end --strict --enforce-non-cpp` + +Reference: `docs/HYBRID_PIPELINE_CONTRACT.md` + ## Handoff Requirement When finishing a batch, agents must report: diff --git a/tools/mcp/README.md b/tools/mcp/README.md index 1e1c4a7..3224948 100644 --- a/tools/mcp/README.md +++ b/tools/mcp/README.md @@ -21,6 +21,12 @@ Promote a newly built binary only if initialize health check passes: ./tools/mcp/promote_mcp_if_healthy.sh ``` +Validate hybrid AST/language pipeline quality for sprint summaries: + +```bash +./tools/mcp/validate_hybrid_pipeline_contract.sh --start 50 --end 90 +``` + ## Current global MCP config Global MCP config is expected at: diff --git a/tools/mcp/validate_hybrid_pipeline_contract.sh b/tools/mcp/validate_hybrid_pipeline_contract.sh new file mode 100755 index 0000000..371ddc9 --- /dev/null +++ b/tools/mcp/validate_hybrid_pipeline_contract.sh @@ -0,0 +1,157 @@ +#!/usr/bin/env bash +set -euo pipefail + +usage() { + cat <<'USAGE' +Usage: + validate_hybrid_pipeline_contract.sh [--start N] [--end N] [--strict] [--enforce-non-cpp] [--json-out FILE] + +Checks sprint integration summaries for hybrid pipeline signals: + 1) canonical signal (AST/IR/schema/semantic/model) + 2) non-C++ projection signal (Rust/Go/Java/Python/etc.) + +Options: + --start N Start sprint number (default: 50) + --end N End sprint number (default: 90) + --strict Exit non-zero if any sprint fails active checks + --enforce-non-cpp Require non-C++ projection signal (otherwise warning-only) + --json-out FILE Write JSON summary to FILE +USAGE +} + +ROOT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")/../.." && pwd)" +SRC_DIR="$ROOT_DIR/editor/src" + +START=50 +END=90 +STRICT=0 +ENFORCE_NON_CPP=0 +JSON_OUT="" + +while [[ $# -gt 0 ]]; do + case "$1" in + --start) + START="${2:-}" + shift 2 + ;; + --end) + END="${2:-}" + shift 2 + ;; + --strict) + STRICT=1 + shift + ;; + --enforce-non-cpp) + ENFORCE_NON_CPP=1 + shift + ;; + --json-out) + JSON_OUT="${2:-}" + shift 2 + ;; + -h|--help) + usage + exit 0 + ;; + *) + echo "error: unknown argument: $1" >&2 + usage >&2 + exit 2 + ;; + esac +done + +if ! [[ "$START" =~ ^[0-9]+$ && "$END" =~ ^[0-9]+$ ]]; then + echo "error: --start/--end must be integers" >&2 + exit 2 +fi +if (( START > END )); then + echo "error: --start cannot be greater than --end" >&2 + exit 2 +fi + +canonical_re='(AST|IR|Schema|Canonical|Semantic|Model)' +non_cpp_re='(Rust|Go|Java|Python|TypeScript|JavaScript|Kotlin|CSharp|FSharp|Ruby|Lua|Erlang|Elixir|Prolog|PostgreSql|MySql|TSql|Sql|Wasm|ARM|x86|Swift|Scala|CAdapter|CRaising|VbNet)' +cpp_re='(Cpp|C\+\+)' + +missing=0 +failed=0 +warn_non_cpp=0 +checked=0 +json_rows="" + +printf '%-8s %-9s %-9s %-9s %-9s %-s\n' "Sprint" "Summary" "Canonical" "NonCpp" "Result" "Theme" + +for sprint in $(seq "$START" "$END"); do + file="$SRC_DIR/Sprint${sprint}IntegrationSummary.h" + if [[ ! -f "$file" ]]; then + ((missing+=1)) + ((failed+=1)) + printf '%-8s %-9s %-9s %-9s %-9s %-s\n' "$sprint" "missing" "-" "-" "FAIL" "-" + json_rows+="{\"sprint\":$sprint,\"summary\":\"missing\",\"canonical\":false,\"non_cpp\":false,\"result\":\"fail\",\"theme\":\"\"}," + continue + fi + + ((checked+=1)) + theme="$(sed -nE 's/.*theme\s*=\s*"([^"]+)".*/\1/p' "$file" | head -n1)" + if [[ -z "$theme" ]]; then + theme="-" + fi + + canonical="no" + non_cpp="no" + result="PASS" + + if rg -q "$canonical_re" "$file"; then + canonical="yes" + fi + + if rg -q "$non_cpp_re" "$file"; then + non_cpp="yes" + fi + + if [[ "$canonical" != "yes" ]]; then + result="FAIL" + fi + + if (( ENFORCE_NON_CPP == 1 )) && [[ "$non_cpp" != "yes" ]]; then + result="FAIL" + fi + + if [[ "$result" == "FAIL" ]]; then + ((failed+=1)) + elif [[ "$non_cpp" != "yes" ]]; then + ((warn_non_cpp+=1)) + fi + + printf '%-8s %-9s %-9s %-9s %-9s %-s\n' "$sprint" "present" "$canonical" "$non_cpp" "$result" "$theme" + json_rows+="{\"sprint\":$sprint,\"summary\":\"present\",\"canonical\":$([[ "$canonical" == "yes" ]] && echo true || echo false),\"non_cpp\":$([[ "$non_cpp" == "yes" ]] && echo true || echo false),\"result\":\"$(echo "$result" | tr '[:upper:]' '[:lower:]')\",\"theme\":\"${theme//\"/\\\"}\"}," +done + +summary_json="$(cat < "$JSON_OUT" + echo "JSON written: $JSON_OUT" +fi + +if (( STRICT == 1 )) && (( failed > 0 )); then + exit 1 +fi +