Skip to content

Commit 8919f81

Browse files
author
Paul Kyle
committed
release: v0.8.12
Targeted hot-path patch tail to 0.8.10. Bundles 0.8.11 + 0.8.12 since 0.8.11 was internally tagged but never publicly released. Headline fix: auto_summary moved off the /save synchronous path (#403). Inline LLM generation in the save handler was blocking the response for the model's full first-token cost — surfaced to REST consumers as "write timeouts" while writes were silently succeeding server-side. The watcher already debounces /generate-summaries for files matching the auto-summary criteria; the fix is small (drop the inline call, surface summary_pending=true in the /save response so callers can distinguish "not yet generated" from "not eligible"). The description_pending pattern from #336 is the precedent. Observability for monitor agents: new /health/auto-summary endpoint (auth-exempt, ok/degraded/down with reason) and an auto_summary block in /status surfacing last_run_at, count, errors, duration, and totals. Also in this release: - /search-associative now per-result snippet-enriches its response (#392). The associative endpoint was overlooked when snippet enrichment landed for /search; a single hit on a multi-fact aggregated file could return tens of KB un-truncated, defeating the budget guarantee the rest of the search surface honors. - openclaw-palinode plugin: recallProfile config field with five named presets (#394). autoRecall was previously a binary switch with hardcoded source injection; the new presets compose source enablement, per-source caps, type allow/deny, and a total-budget hard cap. coding (default) preserves existing behavior. monitoring, investigation, writing, conversation, minimal, and off cover the practical range. recallProfileConfig shallow-overrides individual fields without forking a preset. - 0.8.11 hardening (now reaching public): cross-surface session-end timeout normalized to 90s (#377), /wrap pushes before archiving (#353), embedder logging surfaces all Ollama failure paths (#383), silent-failure-returns-success criticals cluster fixed (#384-#387), Ollama context-window hardening (#335), graceful-degrade auto- description (#336), FTS5 sync diagnostic check (#316), server.json version-alignment regression guard (#313), scrub-layer unification (#341). Full changelog: docs/CHANGELOG.md
1 parent 3c9d0cf commit 8919f81

110 files changed

Lines changed: 7900 additions & 4483 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

.github/workflows/ci.yml

Lines changed: 71 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -1,27 +1,31 @@
1+
# CI pipeline for Palinode — runs on every push and pull_request to any branch.
2+
#
3+
# Jobs:
4+
# 1. unit-tests — fast feedback on core logic (no external services)
5+
# 2. integration — tests/integration/ (may need Ollama; continue-on-error)
6+
# 3. mcp-tool-coverage — release-blocking MCP tool gate (#346)
7+
# 4. security-scan — bandit (code) + pip-audit (dependencies)
8+
19
name: CI
210

311
env:
412
FORCE_JAVASCRIPT_ACTIONS_TO_NODE24: true
513

6-
permissions:
7-
contents: read
8-
9-
concurrency:
10-
group: ${{ github.workflow }}-${{ github.event_name == 'pull_request' && github.ref || github.run_id }}
11-
cancel-in-progress: ${{ github.event_name == 'pull_request' }}
12-
1314
on:
1415
push:
1516
pull_request:
1617

1718
jobs:
19+
# ---------------------------------------------------------------------------
20+
# Unit tests — should never need network access or Ollama.
21+
# All embeddings / LLM calls are mocked in the test suite.
22+
# ---------------------------------------------------------------------------
1823
unit-tests:
1924
runs-on: ubuntu-latest
20-
timeout-minutes: 15
2125

2226
strategy:
2327
matrix:
24-
python-version: ["3.11", "3.12", "3.13"]
28+
python-version: ["3.11", "3.12"]
2529

2630
steps:
2731
- uses: actions/checkout@v4
@@ -37,7 +41,9 @@ jobs:
3741
python -m pip install --upgrade pip
3842
pip install -e ".[dev]"
3943
40-
- name: Assert package resolves to the checked-out tree
44+
- name: Assert palinode resolves to the checked-out tree
45+
# Regression guard for editable installs: palinode.__file__ must
46+
# resolve under GITHUB_WORKSPACE, not some other site-packages path.
4147
run: |
4248
RESOLVED=$(python -c "import palinode; print(palinode.__file__)")
4349
echo "palinode.__file__ = $RESOLVED"
@@ -47,15 +53,22 @@ jobs:
4753
exit 1
4854
fi
4955
50-
- name: Smoke console entry points
51-
run: python -m pytest tests/test_console_entry_points.py -q
52-
53-
- name: Run unit tests
56+
- name: Run unit tests (excluding integration)
5457
run: python -m pytest tests/ -x -q --ignore=tests/integration --ignore=tests/live
5558

59+
# ---------------------------------------------------------------------------
60+
# Integration tests — run against tests/integration/.
61+
#
62+
# These tests do not require Ollama directly (embeddings are stubbed), but
63+
# they do spin up FastAPI in-process and exercise the full save/search loop
64+
# against a real SQLite database in a temp directory.
65+
#
66+
# continue-on-error: true — any test tagged @pytest.mark.slow that needs
67+
# a live Ollama instance will fail here; that is expected in CI.
68+
# Run the full suite locally against a host with Ollama for full coverage.
69+
# ---------------------------------------------------------------------------
5670
integration-tests:
5771
runs-on: ubuntu-latest
58-
timeout-minutes: 20
5972

6073
env:
6174
PALINODE_DIR: /tmp/palinode-ci-test
@@ -75,12 +88,50 @@ jobs:
7588
pip install -e ".[dev]"
7689
7790
- name: Run integration tests
91+
# Integration tests that need Ollama will be skipped in CI;
92+
# run locally against a host with Ollama for full Ollama-backed coverage.
7893
run: python -m pytest tests/integration/ -x -q
7994
continue-on-error: true
8095

96+
# ---------------------------------------------------------------------------
97+
# MCP tool coverage — release-blocking gate (#346, parent #342).
98+
#
99+
# Runs the in-process (Phase 1) and stdio (Phase 2) MCP tool-coverage
100+
# tests WITHOUT continue-on-error. A failure here blocks the PR.
101+
# The drift guard in test_mcp_e2e.py ensures new tools cannot ship
102+
# without smoke-args coverage.
103+
# ---------------------------------------------------------------------------
104+
mcp-tool-coverage:
105+
runs-on: ubuntu-latest
106+
107+
env:
108+
PALINODE_DIR: /tmp/palinode-ci-mcp
109+
110+
steps:
111+
- uses: actions/checkout@v4
112+
113+
- name: Set up Python
114+
uses: actions/setup-python@v5
115+
with:
116+
python-version: "3.11"
117+
cache: "pip"
118+
119+
- name: Install dependencies
120+
run: |
121+
python -m pip install --upgrade pip
122+
pip install -e ".[dev]"
123+
124+
- name: Run MCP tool-coverage tests
125+
run: python -m pytest tests/integration/test_mcp_e2e.py tests/integration/test_mcp_stdio.py -v
126+
127+
# ---------------------------------------------------------------------------
128+
# Security scans — informational (continue-on-error: true on pip-audit).
129+
#
130+
# bandit: static analysis for common Python security issues
131+
# pip-audit: checks installed packages against known vulnerability databases
132+
# ---------------------------------------------------------------------------
81133
security-scan:
82134
runs-on: ubuntu-latest
83-
timeout-minutes: 20
84135

85136
steps:
86137
- uses: actions/checkout@v4
@@ -97,9 +148,11 @@ jobs:
97148
pip install -e ".[dev]"
98149
pip install bandit pip-audit
99150
100-
- name: Run bandit
151+
- name: Run bandit (static security analysis)
152+
# -r: recursive, -ll: medium+ severity, -q: quiet output
101153
run: bandit -r palinode/ -ll -q
102154

103-
- name: Run pip-audit
155+
- name: Run pip-audit (dependency vulnerability check)
156+
# continue-on-error: known-vulnerability lists drift; treat as informational
104157
run: pip-audit
105158
continue-on-error: true

.github/workflows/main-ci.yml

Lines changed: 157 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,157 @@
1+
# Rationale: post-merge sweep for main.
2+
# Option A (require branch-up-to-date before merge) is enforced
3+
# in GitHub repo settings → Branches → main branch protection.
4+
# This file is the backstop if that check is bypassed (admin merge, etc.).
5+
#
6+
# Triggered only on push to main (not on PRs — those are covered by ci.yml).
7+
# On any failure, opens a GitHub issue to flag the regression.
8+
9+
name: Main CI (post-merge sweep)
10+
11+
env:
12+
FORCE_JAVASCRIPT_ACTIONS_TO_NODE24: true
13+
14+
on:
15+
push:
16+
branches: [main]
17+
18+
jobs:
19+
# ---------------------------------------------------------------------------
20+
# Unit tests — mirrors ci.yml; catches interaction bugs that slip through
21+
# independent-PR CI (the failure mode documented in #198).
22+
# ---------------------------------------------------------------------------
23+
unit-tests:
24+
runs-on: ubuntu-latest
25+
26+
strategy:
27+
matrix:
28+
python-version: ["3.11", "3.12"]
29+
30+
steps:
31+
- uses: actions/checkout@v4
32+
33+
- name: Set up Python ${{ matrix.python-version }}
34+
uses: actions/setup-python@v5
35+
with:
36+
python-version: ${{ matrix.python-version }}
37+
cache: "pip"
38+
39+
- name: Install dependencies
40+
run: |
41+
python -m pip install --upgrade pip
42+
pip install -e ".[dev]"
43+
44+
- name: Assert palinode resolves to the checked-out tree
45+
run: |
46+
RESOLVED=$(python -c "import palinode; print(palinode.__file__)")
47+
echo "palinode.__file__ = $RESOLVED"
48+
if [[ "$RESOLVED" != "$GITHUB_WORKSPACE"/* ]]; then
49+
echo "ERROR: palinode resolves outside the workspace ($GITHUB_WORKSPACE)"
50+
echo " Got: $RESOLVED"
51+
exit 1
52+
fi
53+
54+
- name: Run unit tests (excluding integration)
55+
run: python -m pytest tests/ -x -q --ignore=tests/integration --ignore=tests/live
56+
57+
# ---------------------------------------------------------------------------
58+
# Integration tests — informational backstop on main.
59+
# continue-on-error: true because Ollama is not available in CI runners.
60+
# ---------------------------------------------------------------------------
61+
integration-tests:
62+
runs-on: ubuntu-latest
63+
64+
env:
65+
PALINODE_DIR: /tmp/palinode-ci-test
66+
67+
steps:
68+
- uses: actions/checkout@v4
69+
70+
- name: Set up Python
71+
uses: actions/setup-python@v5
72+
with:
73+
python-version: "3.11"
74+
cache: "pip"
75+
76+
- name: Install dependencies
77+
run: |
78+
python -m pip install --upgrade pip
79+
pip install -e ".[dev]"
80+
81+
- name: Run integration tests
82+
run: python -m pytest tests/integration/ -x -q
83+
continue-on-error: true
84+
85+
# ---------------------------------------------------------------------------
86+
# MCP tool coverage — mirrors ci.yml; release-blocking on main (#346).
87+
# ---------------------------------------------------------------------------
88+
mcp-tool-coverage:
89+
runs-on: ubuntu-latest
90+
91+
env:
92+
PALINODE_DIR: /tmp/palinode-ci-mcp
93+
94+
steps:
95+
- uses: actions/checkout@v4
96+
97+
- name: Set up Python
98+
uses: actions/setup-python@v5
99+
with:
100+
python-version: "3.11"
101+
cache: "pip"
102+
103+
- name: Install dependencies
104+
run: |
105+
python -m pip install --upgrade pip
106+
pip install -e ".[dev]"
107+
108+
- name: Run MCP tool-coverage tests
109+
run: python -m pytest tests/integration/test_mcp_e2e.py tests/integration/test_mcp_stdio.py -v
110+
111+
# ---------------------------------------------------------------------------
112+
# Security scan — same as ci.yml.
113+
# ---------------------------------------------------------------------------
114+
security-scan:
115+
runs-on: ubuntu-latest
116+
117+
steps:
118+
- uses: actions/checkout@v4
119+
120+
- name: Set up Python
121+
uses: actions/setup-python@v5
122+
with:
123+
python-version: "3.11"
124+
cache: "pip"
125+
126+
- name: Install dependencies
127+
run: |
128+
python -m pip install --upgrade pip
129+
pip install -e ".[dev]"
130+
pip install bandit pip-audit
131+
132+
- name: Run bandit (static security analysis)
133+
run: bandit -r palinode/ -ll -q
134+
135+
- name: Run pip-audit (dependency vulnerability check)
136+
run: pip-audit
137+
continue-on-error: true
138+
139+
# ---------------------------------------------------------------------------
140+
# Regression reporter — fires only when a job above fails.
141+
# Opens a GitHub issue so the regression is visible outside the Actions UI.
142+
# ---------------------------------------------------------------------------
143+
report-regression:
144+
runs-on: ubuntu-latest
145+
needs: [unit-tests, integration-tests, mcp-tool-coverage, security-scan]
146+
if: failure()
147+
148+
steps:
149+
- name: Report regression
150+
if: failure()
151+
env:
152+
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
153+
run: |
154+
gh issue create \
155+
--title "CI regression on main: ${{ github.sha }}" \
156+
--body "Commit ${{ github.sha }} broke CI on main. Run: ${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}" \
157+
--label "bug"

0 commit comments

Comments
 (0)