Skip to content

nightly-live

nightly-live #80

Workflow file for this run

name: nightly-live
# Installs the REAL latest ruflo + agentic-qe and runs the kit's checks against
# them — samples upstream drift (e.g. the 3.28 aidefence drop, ruvnet/ruflo#2670).
# Scheduled + manual only; failures can also be runner/network or kit defects.
on:
schedule:
- cron: '17 6 * * *'
workflow_dispatch:
jobs:
live:
name: live (${{ matrix.os }})
runs-on: ${{ matrix.os }}
timeout-minutes: 30
strategy:
fail-fast: false
matrix:
os: [ubuntu-latest, macos-latest]
steps:
- uses: actions/checkout@v7
- uses: actions/setup-node@v7
with:
node-version: 22
- name: Isolate npm globals from the runner image
shell: bash
run: |
echo "npm_config_prefix=$RUNNER_TEMP/npm-prefix" >> "$GITHUB_ENV"
echo "$RUNNER_TEMP/npm-prefix/bin" >> "$GITHUB_PATH"
mkdir -p "$RUNNER_TEMP/npm-prefix"
# Deliberately npm, not pnpm: this simulates the kit's TARGET environment —
# ruflo/agentic-qe installed via `npm i -g`, whose trees the kit heals with
# npm (lib/heal.mjs). pnpm-managed globals are a separate follow-up.
- name: Install latest ruflo + agentic-qe (native build scripts allowed)
run: npm install -g --allow-scripts=ruflo,agentic-qe,@claude-flow/cli,better-sqlite3,hnswlib-node,agentdb,agentic-flow,argon2,onnxruntime-node,sharp,protobufjs,@google/genai,tldjs,vibium ruflo@latest agentic-qe@latest
- name: Kit heals a fresh install (sync --no-upgrade)
env:
HOME: ${{ runner.temp }}/kit-home
USERPROFILE: ${{ runner.temp }}/kit-home
XDG_CONFIG_HOME: ${{ runner.temp }}/kit-home/.config
APPDATA: ${{ runner.temp }}/kit-home/AppData/Roaming
run: |
mkdir -p "$HOME"
node bin/agentic-kit.mjs sync --no-upgrade || true
node bin/agentic-kit.mjs status --json > status.json || true
node -e "
const s = require('./status.json');
console.log(JSON.stringify(s, null, 2));
// Upstream-drift gate: natives + security must be healable to ok.
const bad = s.rows.filter(r => r.level === 'fail' && ['natives','security'].includes(r.subsystem));
if (bad.length) { console.error('UPSTREAM DRIFT:', bad.map(b => b.message).join(' | ')); process.exit(1); }
"
- name: Deep proof against the live packages (security)
env:
HOME: ${{ runner.temp }}/kit-home
USERPROFILE: ${{ runner.temp }}/kit-home
XDG_CONFIG_HOME: ${{ runner.temp }}/kit-home/.config
APPDATA: ${{ runner.temp }}/kit-home/AppData/Roaming
run: node bin/agentic-kit.mjs status --refresh=live --only security
- name: Host-neutral hook contract fixtures
run: node --test tests/kit/hook-audit.test.mjs tests/kit/hook-audit-hosts.test.mjs
- name: Report current host releases for schema review
shell: bash
run: |
{
echo "### Host hook schema release watch"
echo
echo "- Codex: $(npm view @openai/codex version 2>/dev/null || echo unavailable)"
echo "- Claude Code: $(npm view @anthropic-ai/claude-code version 2>/dev/null || echo unavailable)"
echo "- OpenCode: $(npm view opencode-ai version 2>/dev/null || echo unavailable)"
echo
echo "Compare these versions with ADR-0041's evidence profiles before widening compatibility."
} >> "$GITHUB_STEP_SUMMARY"
# Non-blocking: a native libc++abi mutex abort on macos-latest poisons ruflo
# exit codes, tracked upstream at ruvnet/ruflo#2885 (open; the Aug 31 triage
# points at better-sqlite3 with onnxruntime-node on macOS arm64). A hosted
# probe on 2026-09-27 (Ruflo 3.46.1, run 36333572972) aborted 10/10 with the
# default settings and 10/10 with single-threaded ONNX Runtime sessions, so
# that mitigation does not help (issuecomment-5857781254).
# Scope is NOT neural-train-specific: upstream evidence (2026-08-12) shows the
# same teardown abort on store-touching commands (`memory search` → correct
# output, rc 134), so an `--only memory-routes` step added here would need the same
# guard. Remove continue-on-error once that issue closes.
- name: Deep proof against the live packages (learning)
continue-on-error: true
env:
HOME: ${{ runner.temp }}/kit-home
USERPROFILE: ${{ runner.temp }}/kit-home
XDG_CONFIG_HOME: ${{ runner.temp }}/kit-home/.config
APPDATA: ${{ runner.temp }}/kit-home/AppData/Roaming
run: node bin/agentic-kit.mjs status --refresh=live --only learning
clean-mac-setup:
name: clean macOS setup (packed artifact)
runs-on: macos-latest
timeout-minutes: 30
steps:
- uses: actions/checkout@v7
- uses: actions/setup-node@v7
with:
node-version: 22
- name: Install the packed kit into a disposable prefix
shell: bash
run: |
echo "npm_config_prefix=$RUNNER_TEMP/npm-prefix" >> "$GITHUB_ENV"
echo "$RUNNER_TEMP/npm-prefix/bin" >> "$GITHUB_PATH"
mkdir -p "$RUNNER_TEMP/npm-prefix" "$RUNNER_TEMP/package"
npm pack --pack-destination "$RUNNER_TEMP/package"
npm install -g "$RUNNER_TEMP"/package/pacphi-agentic-kit-*.tgz
- name: Install native local embedding service
run: brew install ollama
- name: Run real setup in a disposable HOME and project
shell: bash
env:
HOME: ${{ runner.temp }}/clean-home
USERPROFILE: ${{ runner.temp }}/clean-home
XDG_CONFIG_HOME: ${{ runner.temp }}/clean-home/.config
XDG_STATE_HOME: ${{ runner.temp }}/clean-home/.local/state
APPDATA: ${{ runner.temp }}/clean-home/AppData/Roaming
npm_config_cache: ${{ runner.temp }}/npm-cache
RUVNET_BRAIN_KB: ${{ runner.temp }}/brain-kb
AK_PROJECT: ${{ runner.temp }}/clean-project
OLLAMA_MODELS: ${{ runner.temp }}/clean-ollama-models
OLLAMA_HOST: 127.0.0.1:11434
run: |
mkdir -p "$HOME" "$AK_PROJECT"
ollama serve > "$RUNNER_TEMP/ollama.log" 2>&1 &
AK_OLLAMA_PID=$!
trap 'kill "$AK_OLLAMA_PID" 2>/dev/null || true' EXIT
for attempt in {1..30}; do
curl --fail --silent http://127.0.0.1:11434/api/version >/dev/null && break
sleep 1
done
curl --fail --silent http://127.0.0.1:11434/api/version
git -C "$AK_PROJECT" init
(cd "$AK_PROJECT" && ak setup --yes --no-ruvnet-brain --aqe-embedding-mode local) | tee "$RUNNER_TEMP/setup.log"
(cd "$AK_PROJECT" && ak x aqe-embedding verify --json) | tee "$RUNNER_TEMP/embedding-proof.json"
node --input-type=module -e '
import fs from "node:fs";
import path from "node:path";
const log = fs.readFileSync(process.env.RUNNER_TEMP + "/setup.log", "utf8");
const proof = JSON.parse(fs.readFileSync(process.env.RUNNER_TEMP + "/embedding-proof.json", "utf8"));
if (!proof.ok || proof.evidence?.dimension !== 384) throw new Error("fresh embedding proof failed");
const settings = JSON.parse(fs.readFileSync(path.join(process.env.AK_PROJECT, ".claude", "settings.json"), "utf8"));
const expected = ["Bash(npx @claude-flow*)","Bash(npx claude-flow*)","Bash(node .claude/*)","mcp__claude-flow__*","Bash(npx agentic-qe:*)","Bash(npx @anthropics/agentic-qe:*)","mcp__agentic-qe__*"];
for (const rule of expected) if (!log.includes(rule)) throw new Error(`permission was not disclosed: ${rule}`);
const actual = new Set(settings.permissions?.allow ?? []);
for (const rule of expected) if (!actual.has(rule)) throw new Error(`permission missing after setup: ${rule}`);
if (log.indexOf(expected[0]) > log.indexOf("ruflo init --full")) throw new Error("permission disclosure happened after project mutation");
'
- name: Stop disposable daemons
if: always()
shell: bash
env:
HOME: ${{ runner.temp }}/clean-home
USERPROFILE: ${{ runner.temp }}/clean-home
XDG_CONFIG_HOME: ${{ runner.temp }}/clean-home/.config
APPDATA: ${{ runner.temp }}/clean-home/AppData/Roaming
run: ruflo daemon stop --all || true
- name: Upload disposable-run setup evidence
if: always()
uses: actions/upload-artifact@v7
with:
name: clean-mac-setup-evidence
path: |
${{ runner.temp }}/setup.log
${{ runner.temp }}/embedding-proof.json
${{ runner.temp }}/ollama.log
${{ runner.temp }}/clean-project/.claude/settings.json
links-external:
name: links (external)
runs-on: ubuntu-latest
timeout-minutes: 30
steps:
- uses: actions/checkout@v7
# External link validation runs here, not on PRs: network + rate-limits
# (npm/GitHub 403 bots) make it flaky per-PR. Config + excludes: lychee.toml.
- name: Check all links (internal + external)
uses: lycheeverse/lychee-action@v2
with:
args: "--config lychee.toml README.md CLAUDE.md AGENTS.md 'docker/*.md' 'claude/**/*.md' 'src/templates/**/*.md' 'docs/**/*.md' 'docs/**/*.html'"
fail: true