Skip to content

feat: add image analysis API guide and test page #146

feat: add image analysis API guide and test page

feat: add image analysis API guide and test page #146

Workflow file for this run

name: PR Checks
on:
pull_request:
branches: [main]
permissions:
contents: read
concurrency:
group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.sha }}
cancel-in-progress: true
jobs:
# ── Non-blocking workflow policy audit ─────────────────────────────
# This remains informational until the team agrees to enforce it in
# the repository ruleset.
policy-audit:
name: policy-audit
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v7
with:
fetch-depth: 0
ref: ${{ github.event.pull_request.head.sha }}
- name: Audit issue, scope, candidate, and risk evidence
env:
BASE_SHA: ${{ github.event.pull_request.base.sha }}
HEAD_SHA: ${{ github.event.pull_request.head.sha }}
PR_BODY: ${{ github.event.pull_request.body }}
PR_DRAFT: ${{ github.event.pull_request.draft }}
run: |
set -uo pipefail
warnings=()
add_warning() {
warnings+=("$1")
echo "::warning::$1"
}
changed_paths=$(git diff --name-only "$BASE_SHA" "$HEAD_SHA")
changed_lines=$(git diff --numstat "$BASE_SHA" "$HEAD_SHA" | awk '
BEGIN { total = 0 }
{
if ($1 ~ /^[0-9]+$/) total += $1
if ($2 ~ /^[0-9]+$/) total += $2
}
END { print total }
')
shopt -s nocasematch
if (( changed_lines > 50 )) && \
[[ ! "$PR_BODY" =~ (close[sd]?|fix(e[sd])?|resolve[sd]?)[[:space:]]+#[0-9]+ ]]; then
add_warning "Changes over 50 lines must use a closing keyword to reference an agreed issue."
fi
shopt -u nocasematch
if [[ "$PR_DRAFT" != "true" ]]; then
for heading in \
"## Related issue" \
"## Root cause" \
"## Scope" \
"## Candidate identity" \
"## Verification" \
"## Acceptance and cleanup"; do
if ! grep -Fqi "$heading" <<< "$PR_BODY"; then
add_warning "PR body is missing required heading: $heading"
fi
done
candidate=$(sed -nE \
's/^[[:space:]-]*Candidate commit:[[:space:]]*`?([0-9a-fA-F]{7,40})`?.*/\1/p' \
<<< "$PR_BODY" | head -n 1)
if [[ -z "$candidate" ]]; then
add_warning "PR body does not record a candidate commit."
elif [[ "$HEAD_SHA" != "$candidate"* ]]; then
add_warning "Recorded candidate commit does not match the current PR HEAD."
fi
fi
risk_notes=()
if grep -Eq '^(src/api/|src/network/)' <<< "$changed_paths"; then
risk_notes+=("API/network changes require authentication, invalid-input, error-response, and lifecycle evidence.")
fi
if grep -Eq '^(src/media/|src/service/media/|src/web/.*(whep|flv|bigScreen))' <<< "$changed_paths"; then
risk_notes+=("Media changes require ownership, first-frame, switching, overlay, and sustained-playback evidence.")
fi
if grep -Eq '^(src/infer/|src/nn/|src/flow/)' <<< "$changed_paths"; then
risk_notes+=("Inference, NN, or flow changes require Sophon package and focused device evidence.")
fi
if grep -Eq '^src/web/' <<< "$changed_paths"; then
risk_notes+=("Frontend changes require the Docker production build and affected UI evidence.")
fi
if grep -Eq '(^|/)(CMakeLists[.]txt|docker-compose[.]sophon[.]yml)$|^(cmake/|data/resource/|scripts/build)' <<< "$changed_paths"; then
risk_notes+=("Build, resource, or package changes require final package checksum and compatibility evidence.")
fi
{
echo "## Workflow policy audit"
echo
echo "This job is informational and does not block merging."
echo
echo "- Changed lines: $changed_lines"
echo "- Candidate HEAD: \`$HEAD_SHA\`"
echo
if (( ${#warnings[@]} == 0 )); then
echo "No policy gaps detected."
else
echo "### Policy gaps"
for warning in "${warnings[@]}"; do
echo "- $warning"
done
fi
if (( ${#risk_notes[@]} > 0 )); then
echo
echo "### Risk-based evidence reminders"
for note in "${risk_notes[@]}"; do
echo "- $note"
done
fi
} >> "$GITHUB_STEP_SUMMARY"
exit 0
# ── Platform-neutral validation tools ─────────────────────────────
validation-tools:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v7
- uses: actions/setup-node@v7
with:
node-version: 22
cache: npm
cache-dependency-path: tools/scenario-bench/package-lock.json
- uses: actions/setup-python@v7
with:
python-version: '3.12'
- name: Test scenario benchmark tooling
working-directory: tools/scenario-bench
run: |
npm ci
npm test
- name: Test offline accuracy comparison
run: python -m unittest discover -s test -p 'test_offline_accuracy_compare.py'
- name: Test agent-assisted workflow safety boundaries
run: python -m unittest discover -s test/agent -p 'test_agent_workflow.py'
- name: Test measured model-conversion workflow
run: python -m unittest discover -s test/agent -p 'test_model_conversion_workflow.py'
- name: Test task-scoped interactive remote access
run: python -m unittest discover -s test/agent -p 'test_remote_access.py'
# ── Windows remains an orchestration, assessment, and SSH entry ───
agent-windows-routing:
runs-on: windows-latest
steps:
- uses: actions/checkout@v7
- uses: actions/setup-python@v7
with:
python-version: '3.12'
- name: Test read-only assessment and Linux routing
working-directory: test/agent
run: >-
python -m unittest
test_agent_workflow.AgentWorkflowTest.test_memory_probe_tolerates_windows_missing_sysconf
test_agent_workflow.AgentWorkflowTest.test_private_json_write_tolerates_windows_missing_fchmod
test_agent_workflow.AgentWorkflowTest.test_unspecified_toolchain_selects_capability_probe_without_version_pin
test_agent_workflow.AgentWorkflowTest.test_assessment_asks_only_for_missing_business_input
test_agent_workflow.AgentWorkflowTest.test_windows_assessment_routes_to_linux_without_calling_windows_unsupported
test_agent_workflow.AgentWorkflowTest.test_remote_linux_assessment_consolidates_missing_authority
test_agent_workflow.AgentWorkflowTest.test_windows_doctor_returns_linux_environment_guidance_not_traceback
test_agent_workflow.AgentWorkflowTest.test_remote_route_requires_explicit_grants_and_authorization_invalidates_assessment
test_remote_access.RemoteAccessTest
# ── Documentation structure, links, build, and rendered smoke ─────
docs:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v7
- uses: actions/setup-node@v7
with:
node-version: 22
cache: npm
cache-dependency-path: package-lock.json
- name: Install documentation dependencies
run: npm ci
- name: Verify tutorial documentation
run: npm run docs:verify
# ── C++ format check via clang-format ──────────────────────────────
# Only checks files changed in the PR (not the entire codebase)
format-check:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v7
with:
fetch-depth: 0 # fetch all history for diff against base
- name: Install clang-format
run: |
sudo apt-get update
sudo apt-get install -y clang-format-18
sudo update-alternatives --install /usr/bin/clang-format clang-format /usr/bin/clang-format-18 100
- name: Check C++ formatting (changed files only)
run: |
clang-format --version
BASE=$(git merge-base HEAD origin/main)
echo "merge-base: $BASE"
CHANGED=$(git diff --name-only --diff-filter=ACMR "$BASE" HEAD -- \
'*.cc' '*.h' | grep -vE '(^|/)(3rd|prebuild|node_modules)/' || true)
if [ -z "$CHANGED" ]; then
echo "No C++ files changed."
exit 0
fi
echo "Checking $(echo "$CHANGED" | wc -l) changed file(s)..."
FAIL=0
for f in $CHANGED; do
if ! diff <(clang-format "$f") "$f" > /dev/null 2>&1; then
echo " ❌ $f"
FAIL=1
fi
done
if [ $FAIL -eq 0 ]; then
echo "✅ All changed files are properly formatted."
else
echo ""
echo "Run 'scripts/format_check.sh --fix' locally to auto-fix."
exit 1
fi
# ── Vue 3 frontend build (includes i18n checks via prebuild hook) ──
frontend-build:
runs-on: ubuntu-latest
defaults:
run:
working-directory: src/web
steps:
- uses: actions/checkout@v7
- uses: actions/setup-node@v7
with:
# Node 22 LTS ships npm 10, matching the build image used for
# production frontend builds. Node 24 ships npm 11, whose stricter
# lockfile validation rejects the npm 10-generated lockfile and
# would test a different dependency resolution than what ships.
node-version: 22
cache: npm
cache-dependency-path: src/web/package-lock.json
- name: Install dependencies
run: npm ci
- name: Build frontend
run: npm run build
# ── cppcheck static analysis (changed files only) ───────────────────
cppcheck:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v7
with:
fetch-depth: 0
- name: Install cppcheck
run: |
sudo apt-get update
sudo apt-get install -y cppcheck
- name: Run cppcheck (changed files only)
run: |
BASE=$(git merge-base HEAD origin/main)
CHANGED=$(git diff --name-only --diff-filter=ACMR "$BASE" HEAD -- \
'src/**/*.cc' 'src/**/*.h' 'test/**/*.cc' 'test/**/*.h')
if [ -z "$CHANGED" ]; then
echo "No C++ files changed."
exit 0
fi
echo "Checking $(echo "$CHANGED" | wc -l) changed file(s)..."
cppcheck \
--std=c++17 \
--language=c++ \
--enable=warning,style,performance,portability \
--inline-suppr \
--suppressions-list=.cppcheck-suppressions \
--quiet \
--template='{file}:{line}: [{severity}] {id}: {message}' \
-I src \
-j"$(nproc)" \
$CHANGED