From 6493d52af9d41bf3b14aa61265fbdd647ca18a00 Mon Sep 17 00:00:00 2001 From: Garry Tan Date: Fri, 24 Apr 2026 00:06:22 -0700 Subject: [PATCH] feat(health): integrate gbrain as D6 composite dimension MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Adds a GBrain row to the /health dashboard rubric with weight 10%. Three sub-signals rolled into one 0-10 score: doctor status (0.5), sync queue depth (0.3), last-push age (0.2). Redistributes when gbrain_sync_mode is off so the dimension stays fair. Weights rebalance: typecheck 25→22, lint 20→18, test 30→28, deadcode 15→13, shell 10→9, gbrain +10 — sums to 100. gbrain doctor --json wrapped in timeout 5s so a hung gbrain never stalls the /health dashboard. Dimension is omitted (not red) when gbrain is not installed — running /health on a non-gbrain machine shouldn't penalize that choice. History-JSONL adds a `gbrain` field. Pre-D6 entries read as null for trend comparison; new tracking starts from first post-D6 run. Co-Authored-By: Claude Opus 4.7 (1M context) --- health/SKILL.md | 63 ++++++++++++++++++++++++++++++++------------ health/SKILL.md.tmpl | 63 ++++++++++++++++++++++++++++++++------------ 2 files changed, 92 insertions(+), 34 deletions(-) diff --git a/health/SKILL.md b/health/SKILL.md index 3fabd025..35324171 100644 --- a/health/SKILL.md +++ b/health/SKILL.md @@ -952,6 +952,12 @@ command -v knip >/dev/null 2>&1 && echo "DEADCODE: knip" # Shell linting command -v shellcheck >/dev/null 2>&1 && ls *.sh scripts/*.sh bin/*.sh 2>/dev/null | head -1 | xargs -I{} echo "SHELL: shellcheck" + +# GBrain presence (D6) — only report as a dimension if gbrain is actually +# set up; otherwise skip so machines without gbrain aren't penalized. +if command -v gbrain >/dev/null 2>&1 && [ -f "$HOME/.gbrain/config.json" ]; then + echo "GBRAIN: gbrain doctor --json (wrapped in timeout 5s)" +fi ``` Use Glob to search for shell scripts: @@ -1016,11 +1022,12 @@ Score each category on a 0-10 scale using this rubric: | Category | Weight | 10 | 7 | 4 | 0 | |-----------|--------|------|-----------|------------|-----------| -| Type check | 25% | Clean (exit 0) | <10 errors | <50 errors | >=50 errors | -| Lint | 20% | Clean (exit 0) | <5 warnings | <20 warnings | >=20 warnings | -| Tests | 30% | All pass (exit 0) | >95% pass | >80% pass | <=80% pass | -| Dead code | 15% | Clean (exit 0) | <5 unused exports | <20 unused | >=20 unused | -| Shell lint | 10% | Clean (exit 0) | <5 issues | >=5 issues | N/A (skip) | +| Type check | 22% | Clean (exit 0) | <10 errors | <50 errors | >=50 errors | +| Lint | 18% | Clean (exit 0) | <5 warnings | <20 warnings | >=20 warnings | +| Tests | 28% | All pass (exit 0) | >95% pass | >80% pass | <=80% pass | +| Dead code | 13% | Clean (exit 0) | <5 unused exports | <20 unused | >=20 unused | +| Shell lint | 9% | Clean (exit 0) | <5 issues | >=5 issues | N/A (skip) | +| GBrain (D6) | 10% | doctor=ok, queue<10, pushed <24h | doctor=warnings OR queue<100 OR pushed <72h | doctor broken OR queue>=100 OR pushed >=72h | N/A (gbrain not installed) | **Parsing tool output for counts:** - **tsc:** Count lines matching `error TS` in output. @@ -1031,11 +1038,30 @@ Score each category on a 0-10 scale using this rubric: **Composite score:** ``` -composite = (typecheck_score * 0.25) + (lint_score * 0.20) + (test_score * 0.30) + (deadcode_score * 0.15) + (shell_score * 0.10) +composite = (typecheck_score * 0.22) + (lint_score * 0.18) + (test_score * 0.28) + (deadcode_score * 0.13) + (shell_score * 0.09) + (gbrain_score * 0.10) ``` -If a category is skipped (tool not available), redistribute its weight proportionally -among the remaining categories. +If a category is skipped (tool not available — includes GBrain when gbrain +is not installed), redistribute its weight proportionally among the +remaining categories. + +**GBrain sub-score computation (D6):** + +``` +doctor_component: 10 if `gbrain doctor --json | jq -r .status` == "ok"; + 7 if "warnings"; 0 otherwise (or command times out after 5s). +queue_component: 10 if ~/.gstack/.brain-queue.jsonl has <10 lines; + 7 if 10-100; 0 if >=100 (suggests secret-scan rejections + piling up). N/A if gbrain_sync_mode == off. +push_component: 10 if (now - mtime of ~/.gstack/.brain-last-push) < 24h; + 7 if <72h; 0 if >=72h. N/A if gbrain_sync_mode == off. +gbrain_score = 0.5 * doctor_component + 0.3 * queue_component + 0.2 * push_component + (redistribute 0.3 + 0.2 into doctor when sync_mode is off: + gbrain_score = doctor_component in that case) +``` + +The `gbrain doctor --json` call MUST be wrapped in `timeout 5s` so a hung +or misconfigured gbrain doesn't stall the entire /health dashboard. --- @@ -1058,6 +1084,7 @@ Lint biome check . 8/10 WARNING 2s 3 warnings Tests bun test 10/10 CLEAN 12s 47/47 passed Dead code knip 7/10 WARNING 5s 4 unused exports Shell lint shellcheck 10/10 CLEAN 1s 0 issues +GBrain gbrain doctor 10/10 CLEAN <1s doctor=ok, queue=3, pushed 2h ago COMPOSITE SCORE: 9.1 / 10 @@ -1091,17 +1118,19 @@ eval "$(~/.claude/skills/gstack/bin/gstack-slug 2>/dev/null)" && mkdir -p ~/.gst Append one JSONL line to `~/.gstack/projects/$SLUG/health-history.jsonl`: ```json -{"ts":"2026-03-31T14:30:00Z","branch":"main","score":9.1,"typecheck":10,"lint":8,"test":10,"deadcode":7,"shell":10,"duration_s":23} +{"ts":"2026-03-31T14:30:00Z","branch":"main","score":9.1,"typecheck":10,"lint":8,"test":10,"deadcode":7,"shell":10,"gbrain":10,"duration_s":23} ``` Fields: - `ts` -- ISO 8601 timestamp - `branch` -- current git branch - `score` -- composite score (one decimal) -- `typecheck`, `lint`, `test`, `deadcode`, `shell` -- individual category scores (integer 0-10) +- `typecheck`, `lint`, `test`, `deadcode`, `shell`, `gbrain` -- individual category scores (integer 0-10) - `duration_s` -- total time for all tools in seconds -If a category was skipped, set its value to `null`. +If a category was skipped, set its value to `null`. Pre-D6 history entries +won't have a `gbrain` field — treat them as `null` for trend comparison +and start new tracking from the first post-D6 run. --- @@ -1120,12 +1149,12 @@ tail -10 ~/.gstack/projects/$SLUG/health-history.jsonl 2>/dev/null || echo "NO_H ``` HEALTH TREND (last 5 runs) ========================== -Date Branch Score TC Lint Test Dead Shell ----------- ----------- ----- -- ---- ---- ---- ----- -2026-03-28 main 9.4 10 9 10 8 10 -2026-03-29 feat/auth 8.8 10 7 10 7 10 -2026-03-30 feat/auth 8.2 10 6 9 7 10 -2026-03-31 feat/auth 9.1 10 8 10 7 10 +Date Branch Score TC Lint Test Dead Shell GBrain +---------- ----------- ----- -- ---- ---- ---- ----- ------ +2026-03-28 main 9.4 10 9 10 8 10 10 +2026-03-29 feat/auth 8.8 10 7 10 7 10 10 +2026-03-30 feat/auth 8.2 10 6 9 7 10 7 +2026-03-31 feat/auth 9.1 10 8 10 7 10 10 Trend: IMPROVING (+0.9 since last run) ``` diff --git a/health/SKILL.md.tmpl b/health/SKILL.md.tmpl index c116ce75..ca70c665 100644 --- a/health/SKILL.md.tmpl +++ b/health/SKILL.md.tmpl @@ -69,6 +69,12 @@ command -v knip >/dev/null 2>&1 && echo "DEADCODE: knip" # Shell linting command -v shellcheck >/dev/null 2>&1 && ls *.sh scripts/*.sh bin/*.sh 2>/dev/null | head -1 | xargs -I{} echo "SHELL: shellcheck" + +# GBrain presence (D6) — only report as a dimension if gbrain is actually +# set up; otherwise skip so machines without gbrain aren't penalized. +if command -v gbrain >/dev/null 2>&1 && [ -f "$HOME/.gbrain/config.json" ]; then + echo "GBRAIN: gbrain doctor --json (wrapped in timeout 5s)" +fi ``` Use Glob to search for shell scripts: @@ -133,11 +139,12 @@ Score each category on a 0-10 scale using this rubric: | Category | Weight | 10 | 7 | 4 | 0 | |-----------|--------|------|-----------|------------|-----------| -| Type check | 25% | Clean (exit 0) | <10 errors | <50 errors | >=50 errors | -| Lint | 20% | Clean (exit 0) | <5 warnings | <20 warnings | >=20 warnings | -| Tests | 30% | All pass (exit 0) | >95% pass | >80% pass | <=80% pass | -| Dead code | 15% | Clean (exit 0) | <5 unused exports | <20 unused | >=20 unused | -| Shell lint | 10% | Clean (exit 0) | <5 issues | >=5 issues | N/A (skip) | +| Type check | 22% | Clean (exit 0) | <10 errors | <50 errors | >=50 errors | +| Lint | 18% | Clean (exit 0) | <5 warnings | <20 warnings | >=20 warnings | +| Tests | 28% | All pass (exit 0) | >95% pass | >80% pass | <=80% pass | +| Dead code | 13% | Clean (exit 0) | <5 unused exports | <20 unused | >=20 unused | +| Shell lint | 9% | Clean (exit 0) | <5 issues | >=5 issues | N/A (skip) | +| GBrain (D6) | 10% | doctor=ok, queue<10, pushed <24h | doctor=warnings OR queue<100 OR pushed <72h | doctor broken OR queue>=100 OR pushed >=72h | N/A (gbrain not installed) | **Parsing tool output for counts:** - **tsc:** Count lines matching `error TS` in output. @@ -148,11 +155,30 @@ Score each category on a 0-10 scale using this rubric: **Composite score:** ``` -composite = (typecheck_score * 0.25) + (lint_score * 0.20) + (test_score * 0.30) + (deadcode_score * 0.15) + (shell_score * 0.10) +composite = (typecheck_score * 0.22) + (lint_score * 0.18) + (test_score * 0.28) + (deadcode_score * 0.13) + (shell_score * 0.09) + (gbrain_score * 0.10) ``` -If a category is skipped (tool not available), redistribute its weight proportionally -among the remaining categories. +If a category is skipped (tool not available — includes GBrain when gbrain +is not installed), redistribute its weight proportionally among the +remaining categories. + +**GBrain sub-score computation (D6):** + +``` +doctor_component: 10 if `gbrain doctor --json | jq -r .status` == "ok"; + 7 if "warnings"; 0 otherwise (or command times out after 5s). +queue_component: 10 if ~/.gstack/.brain-queue.jsonl has <10 lines; + 7 if 10-100; 0 if >=100 (suggests secret-scan rejections + piling up). N/A if gbrain_sync_mode == off. +push_component: 10 if (now - mtime of ~/.gstack/.brain-last-push) < 24h; + 7 if <72h; 0 if >=72h. N/A if gbrain_sync_mode == off. +gbrain_score = 0.5 * doctor_component + 0.3 * queue_component + 0.2 * push_component + (redistribute 0.3 + 0.2 into doctor when sync_mode is off: + gbrain_score = doctor_component in that case) +``` + +The `gbrain doctor --json` call MUST be wrapped in `timeout 5s` so a hung +or misconfigured gbrain doesn't stall the entire /health dashboard. --- @@ -175,6 +201,7 @@ Lint biome check . 8/10 WARNING 2s 3 warnings Tests bun test 10/10 CLEAN 12s 47/47 passed Dead code knip 7/10 WARNING 5s 4 unused exports Shell lint shellcheck 10/10 CLEAN 1s 0 issues +GBrain gbrain doctor 10/10 CLEAN <1s doctor=ok, queue=3, pushed 2h ago COMPOSITE SCORE: 9.1 / 10 @@ -208,17 +235,19 @@ DETAILS: Lint (3 warnings) Append one JSONL line to `~/.gstack/projects/$SLUG/health-history.jsonl`: ```json -{"ts":"2026-03-31T14:30:00Z","branch":"main","score":9.1,"typecheck":10,"lint":8,"test":10,"deadcode":7,"shell":10,"duration_s":23} +{"ts":"2026-03-31T14:30:00Z","branch":"main","score":9.1,"typecheck":10,"lint":8,"test":10,"deadcode":7,"shell":10,"gbrain":10,"duration_s":23} ``` Fields: - `ts` -- ISO 8601 timestamp - `branch` -- current git branch - `score` -- composite score (one decimal) -- `typecheck`, `lint`, `test`, `deadcode`, `shell` -- individual category scores (integer 0-10) +- `typecheck`, `lint`, `test`, `deadcode`, `shell`, `gbrain` -- individual category scores (integer 0-10) - `duration_s` -- total time for all tools in seconds -If a category was skipped, set its value to `null`. +If a category was skipped, set its value to `null`. Pre-D6 history entries +won't have a `gbrain` field — treat them as `null` for trend comparison +and start new tracking from the first post-D6 run. --- @@ -237,12 +266,12 @@ tail -10 ~/.gstack/projects/$SLUG/health-history.jsonl 2>/dev/null || echo "NO_H ``` HEALTH TREND (last 5 runs) ========================== -Date Branch Score TC Lint Test Dead Shell ----------- ----------- ----- -- ---- ---- ---- ----- -2026-03-28 main 9.4 10 9 10 8 10 -2026-03-29 feat/auth 8.8 10 7 10 7 10 -2026-03-30 feat/auth 8.2 10 6 9 7 10 -2026-03-31 feat/auth 9.1 10 8 10 7 10 +Date Branch Score TC Lint Test Dead Shell GBrain +---------- ----------- ----- -- ---- ---- ---- ----- ------ +2026-03-28 main 9.4 10 9 10 8 10 10 +2026-03-29 feat/auth 8.8 10 7 10 7 10 10 +2026-03-30 feat/auth 8.2 10 6 9 7 10 7 +2026-03-31 feat/auth 9.1 10 8 10 7 10 10 Trend: IMPROVING (+0.9 since last run) ```