Skip to content

v0.34.0: vstack.timeline + vstack.cost_sim + vstack.findings_router m… #171

v0.34.0: vstack.timeline + vstack.cost_sim + vstack.findings_router m…

v0.34.0: vstack.timeline + vstack.cost_sim + vstack.findings_router m… #171

Workflow file for this run

name: CI
on:
push:
branches: [main]
pull_request:
branches: [main]
permissions:
contents: read
concurrency:
group: ci-${{ github.ref }}
cancel-in-progress: true
jobs:
test:
name: Test (Python ${{ matrix.python-version }} on ${{ matrix.os }})
runs-on: ${{ matrix.os }}
strategy:
fail-fast: false
matrix:
os: [ubuntu-latest, macos-latest]
python-version: ["3.11", "3.12", "3.13"]
steps:
- uses: actions/checkout@v4
- name: Set up Python
uses: actions/setup-python@v5
with:
python-version: ${{ matrix.python-version }}
cache: pip
- name: Install package + test deps
run: |
python -m pip install --upgrade pip
python -m pip install -e ".[mcp,api]"
python -m pip install pytest pytest-cov pyyaml httpx
# Framework-gated adapter tests skip when their framework is
# missing; install the lightweight ones so CI actually runs
# them. CrewAI's dep tree is heavier and slower; we leave it
# gated unless someone needs that signal locally.
python -m pip install langchain-core langgraph llama-index-core 'pydantic-ai>=0.0.20'
- name: Run tests (all patterns + surfaces, with coverage)
run: |
pytest module-1-individual/ module-2-team/ module-3-organization/ \
_mcp/ _memory/ _upgrade/ _api/ \
_adapters/ _learnings/ _analytics/ \
_browser/ _gbrain/ _benchmarks/ \
_security/ _cache/ _observability/ _doctor/ \
_hello/ \
-v --tb=short \
--cov=vstack \
--cov-report=term-missing \
--cov-report=xml
- name: Upload coverage artifact
if: matrix.os == 'ubuntu-latest' && matrix.python-version == '3.13'
uses: actions/upload-artifact@v4
with:
name: coverage-xml
path: coverage.xml
retention-days: 14
lint:
name: Lint (ruff)
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Set up Python
uses: actions/setup-python@v5
with:
python-version: "3.13"
cache: pip
- name: Install ruff
run: python -m pip install ruff
- name: Run ruff check
run: |
ruff check module-1-individual/ module-2-team/ module-3-organization/ \
_mcp/ _memory/ _upgrade/ _api/ _adapters/ _learnings/ _analytics/ \
_browser/ _gbrain/ _benchmarks/ examples/ _baselines/scripts/ \
_security/ _cache/ _observability/ _doctor/ _hello/
- name: Run ruff format check
run: |
ruff format --check module-1-individual/ module-2-team/ module-3-organization/ \
_mcp/ _memory/ _upgrade/ _api/ _adapters/ _learnings/ _analytics/ \
_browser/ _gbrain/ _benchmarks/ examples/ _baselines/scripts/ \
_security/ _cache/ _observability/ _doctor/ _hello/
typecheck:
name: Typecheck (mypy)
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Set up Python
uses: actions/setup-python@v5
with:
python-version: "3.13"
cache: pip
- name: Install mypy and dependencies
run: |
python -m pip install mypy pydantic mcp fastapi 'uvicorn[standard]' httpx \
langchain-core langgraph llama-index-core 'pydantic-ai>=0.0.20'
python -m pip install -e .
- name: Run mypy per-pattern
# Each pattern's lib is its own logical package (via pyproject's
# force-include mapping). Running mypy across all patterns at once
# produces a 'Duplicate module named "lib"' error; running each
# pattern's lib separately avoids that and gives clearer per-pattern
# output. New patterns add another line here.
run: |
set -e
for pattern in \
_mcp \
_memory \
_upgrade \
_api \
_adapters \
_learnings \
_analytics \
_browser \
_gbrain \
_benchmarks \
_security \
_cache \
_observability \
_doctor \
_hello \
module-2-team/30-aar-generator \
module-2-team/17-lencioni-diagnostic \
module-2-team/18-trust-triangle-audit \
module-1-individual/03-johari-window \
module-2-team/13-grpi-working-agreement \
module-2-team/27-bias-stack-detector \
module-2-team/20-edmondson-psych-safety \
module-2-team/29-thomas-kilmann-selector \
module-2-team/22-stone-heen-feedback-triggers \
module-2-team/28-devils-advocate-separator \
module-1-individual/01-lewin-formula \
module-2-team/19-mcallister-trust-dimensions \
module-2-team/15-social-loafing-detector \
module-2-team/26-groupthink-polarization-contagion \
module-2-team/14-process-gain-loss-detector \
module-2-team/24-smart-goal-generator \
module-1-individual/11-mcgregor-orchestrator-mode \
module-2-team/25-group-decision-models \
module-3-organization/31-schein-iceberg-culture \
module-1-individual/08-grant-strengths-as-weaknesses \
module-2-team/23-plus-delta-feedback-format \
module-3-organization/32-robbins-judge-7-culture \
module-2-team/16-heffernan-superflocks-detector \
module-1-individual/06-yerkes-dodson-workload \
module-3-organization/33-org-structure-matrix \
module-1-individual/09-motivation-traps \
module-2-team/21-glaser-conversation-steering \
module-1-individual/02-goleman-ei-audit \
module-1-individual/10-sdt-intrinsic-reward \
module-3-organization/34-span-of-control \
module-1-individual/04-danva-emotion-reader \
module-1-individual/05-cognitive-reappraisal \
module-1-individual/07-hexaco-personality \
module-1-individual/12-vroom-expectancy; do
echo "=== mypy: $pattern ==="
mypy "$pattern/lib" --strict --ignore-missing-imports
done
security:
name: Security (bandit + pip-audit)
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Set up Python
uses: actions/setup-python@v5
with:
python-version: "3.13"
cache: pip
- name: Install security tools
run: python -m pip install "bandit[toml]" pip-audit
- name: Run bandit (library code only)
# Tests and demos exercise the library deliberately, so they may
# trip rules that flag exec / subprocess / hardcoded "secrets" in
# canned fixtures. Scan only the shipping library code.
run: |
bandit -r \
module-1-individual/*/lib \
module-2-team/*/lib \
module-3-organization/*/lib \
-ll -ii -f txt
- name: Run pip-audit (declared deps)
# The library itself only pins pydantic + (optional) anthropic /
# openai / mcp / fastapi / framework adapters. pip-audit on the
# installed environment surfaces both first-party and transitive
# issues. The framework adapter dep trees (langchain / langgraph
# / llama-index / pydantic-ai / crewai) pull in dozens of
# transitives we can't pin, so we treat the audit as informational:
# the report is logged, and bandit (above) is the security gate.
run: |
python -m pip install -e ".[all]"
pip-audit --strict --progress-spinner=off \
|| pip-audit --progress-spinner=off \
|| echo "pip-audit found advisories; see report above (warn-only)."
build:
name: Build wheel + sdist
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Set up Python
uses: actions/setup-python@v5
with:
python-version: "3.13"
cache: pip
- name: Install build
run: python -m pip install build
- name: Build
run: python -m build
- name: Verify wheel ships all 34 namespaces + py.typed marker
run: |
python -m pip install dist/valanistack-*-py3-none-any.whl
python -c "
import importlib, os
import vstack
assert vstack.__version__, 'top-level __version__ missing'
print(f'vstack v{vstack.__version__}')
assert os.path.exists(os.path.join(os.path.dirname(vstack.__file__), 'py.typed')), 'py.typed marker missing from wheel'
print('py.typed marker present')
namespaces = [
'vstack.aar',
'vstack.lencioni',
'vstack.trust_triangle',
'vstack.johari',
'vstack.grpi',
'vstack.bias_stack',
'vstack.psych_safety',
'vstack.thomas_kilmann',
'vstack.feedback_triggers',
'vstack.devils_advocate',
'vstack.lewin',
'vstack.mcallister_trust',
'vstack.social_loafing',
'vstack.debate_pathology',
'vstack.process_gain_loss',
'vstack.smart_goal',
'vstack.mcgregor',
'vstack.group_decision',
'vstack.schein_culture',
'vstack.grant_strengths',
'vstack.plus_delta',
'vstack.robbins_culture',
'vstack.superflocks',
'vstack.yerkes_dodson',
'vstack.org_structure',
'vstack.motivation_traps',
'vstack.glaser_conversation',
'vstack.goleman_ei',
'vstack.sdt_reward',
'vstack.span_of_control',
'vstack.danva_emotion',
'vstack.cognitive_reappraisal',
'vstack.hexaco',
'vstack.vroom_expectancy',
]
for ns in namespaces:
mod = importlib.import_module(ns)
assert hasattr(mod, '__all__'), f'{ns} missing __all__'
print(f'All {len(namespaces)} pattern namespaces import cleanly')
"
- name: Upload artifacts
uses: actions/upload-artifact@v4
with:
name: dist-${{ github.sha }}
path: dist/
retention-days: 14