feat: community export workflow — strip script, leak-check hardening, CLA docs

- scripts/strip-commercial.sh: removes agor-pro/, commercial files, SPDX headers
- leak-check.yml: added LICENSE-COMMERCIAL, SPDX header, and feature flag checks
- CONTRIBUTING.md: external contributor guide, commercial content table, sync docs
This commit is contained in:
Hibryda 2026-03-22 04:39:07 +01:00
parent 18364826dc
commit 5836fb7d80
3 changed files with 218 additions and 6 deletions

View file

@ -50,11 +50,32 @@ jobs:
fi fi
echo "No commercial directories with content found." echo "No commercial directories with content found."
- name: Check for commercial license file
run: |
if [ -f "LICENSE-COMMERCIAL" ]; then
echo "::error::LICENSE-COMMERCIAL found in community repo"
exit 1
fi
echo "No commercial license file found."
- name: Check for LicenseRef-Commercial SPDX headers
run: |
files=$(grep -rl "LicenseRef-Commercial" \
--include="*.ts" --include="*.svelte" --include="*.rs" \
--include="*.toml" --include="*.css" \
src/ src-tauri/src/ agor-core/ 2>/dev/null || true)
if [ -n "$files" ]; then
echo "::error::Files with LicenseRef-Commercial SPDX headers found:"
echo "$files"
exit 1
fi
echo "No LicenseRef-Commercial headers found."
- name: Grep for commercial references in source - name: Grep for commercial references in source
run: | run: |
failed=0 failed=0
for pattern in "LicenseRef-Commercial" "agor-pro" "agor_pro"; do for pattern in "agor-pro" "agor_pro"; do
if grep -r --include="*.ts" --include="*.svelte" --include="*.rs" --include="*.toml" \ if grep -r --include="*.ts" --include="*.svelte" --include="*.rs" --include="*.toml" \
"$pattern" src/ src-tauri/src/ 2>/dev/null; then "$pattern" src/ src-tauri/src/ 2>/dev/null; then
echo "::error::Found '$pattern' reference in source code" echo "::error::Found '$pattern' reference in source code"
@ -67,3 +88,21 @@ jobs:
exit 1 exit 1
fi fi
echo "No commercial references found in source." echo "No commercial references found in source."
- name: Check for commercial feature flags in package.json
run: |
failed=0
if grep -q '"commercial\|:pro"' package.json 2>/dev/null; then
echo "::error::Commercial feature flags found in package.json"
grep '"commercial\|:pro"' package.json
failed=1
fi
if grep -q 'agor-pro' package.json 2>/dev/null; then
echo "::error::agor-pro dependency found in package.json"
grep 'agor-pro' package.json
failed=1
fi
if [ "$failed" -eq 1 ]; then
exit 1
fi
echo "No commercial feature flags in package.json."

View file

@ -18,6 +18,20 @@ periodically.
All community contributions go to **DexterFromLab/agent-orchestrator**. Do not open All community contributions go to **DexterFromLab/agent-orchestrator**. Do not open
PRs against this repo for community features. PRs against this repo for community features.
### How to Contribute
1. Fork the community repo at `DexterFromLab/agent-orchestrator`
2. Create a feature branch from `main`
3. Make your changes and commit using conventional commits
4. Open a pull request against `DexterFromLab/agent-orchestrator` `main`
5. Sign the CLA when prompted by the bot on your first PR
6. Address review feedback
7. Once approved, a maintainer will merge your PR
Do **not** fork or open PRs against `agents-orchestrator/agents-orchestrator` for
community contributions. That repository contains commercial code and access is
restricted.
### Contributor License Agreement (CLA) ### Contributor License Agreement (CLA)
Every community contributor must sign the CLA before their first PR is merged. Every community contributor must sign the CLA before their first PR is merged.
@ -25,13 +39,30 @@ CLA signing is automated via [CLA-assistant.io](https://cla-assistant.io/) on
the community repository. The bot will prompt you on your first PR. the community repository. The bot will prompt you on your first PR.
The CLA grants the project maintainers a perpetual, irrevocable license to use The CLA grants the project maintainers a perpetual, irrevocable license to use
your contribution in both the community and commercial editions. your contribution in both the community and commercial editions. You retain full
ownership of your code. See [CLA.md](CLA.md) for the full agreement text.
## Commercial Development ## Commercial Development
Commercial features are developed only in this repository. Access is restricted Commercial features are developed only in this repository. Access is restricted
to authorized team members. to authorized team members.
### What Content Is Commercial-Only
The following paths and markers identify commercial-only content:
| Marker | Description |
|--------|-------------|
| `agor-pro/` | Commercial feature modules |
| `src/lib/commercial/` | Commercial frontend components |
| `tests/commercial/` | Commercial test suites |
| `LICENSE-COMMERCIAL` | Commercial license file |
| `LicenseRef-Commercial` SPDX header | Any file with this header |
| `test:all:commercial` script | Commercial test runner |
This content is automatically stripped during community sync and never appears in
the community repository.
### SPDX License Headers ### SPDX License Headers
All commercial source files must include the following header as the first line: All commercial source files must include the following header as the first line:
@ -58,12 +89,27 @@ Community-shared code uses the MIT identifier:
// SPDX-License-Identifier: MIT // SPDX-License-Identifier: MIT
``` ```
### Commercial Directories ## Community Sync Workflow
Files under these paths are always commercial-only: The community repo is kept in sync with this repo via an automated workflow:
- `agor-pro/` 1. **Trigger**: Manual dispatch or on release tag publication
- `src/lib/commercial/` 2. **Strip**: `scripts/strip-commercial.sh` removes all commercial content
3. **Verify**: Automated checks ensure no commercial references remain
4. **Push**: A sync branch is pushed to `DexterFromLab/agent-orchestrator`
5. **Merge**: A maintainer reviews and merges the sync PR
To preview what would be stripped locally:
```bash
# Dry run — shows what files would be removed (modifies working tree)
bash scripts/strip-commercial.sh
# Reset after preview
git checkout .
```
The leak-check CI workflow runs on every push and PR to `main`, verifying that no
commercial content has been accidentally committed to community-bound code.
## Branch Model ## Branch Model

127
scripts/strip-commercial.sh Executable file
View file

@ -0,0 +1,127 @@
#!/usr/bin/env bash
# strip-commercial.sh — Remove all commercial content from the repository.
# Safe to run locally to preview what would be stripped.
# Used by .github/workflows/community-sync.yml for automated sync.
set -euo pipefail
REPO_ROOT="$(cd "$(dirname "$0")/.." && pwd)"
cd "$REPO_ROOT"
removed=()
echo "=== Stripping commercial content from: $REPO_ROOT ==="
# 1. Remove commercial directories
for dir in agor-pro; do
if [ -d "$dir" ]; then
rm -rf "$dir"
removed+=("$dir/ (directory)")
echo "Removed directory: $dir/"
fi
done
# 2. Remove commercial files in src/lib/commercial/ (keep .gitkeep)
if [ -d "src/lib/commercial" ]; then
while IFS= read -r -d '' file; do
rm -f "$file"
removed+=("$file")
echo "Removed file: $file"
done < <(find src/lib/commercial/ -type f ! -name '.gitkeep' -print0 2>/dev/null)
fi
# 3. Remove commercial files in tests/commercial/ (keep .gitkeep)
if [ -d "tests/commercial" ]; then
while IFS= read -r -d '' file; do
rm -f "$file"
removed+=("$file")
echo "Removed file: $file"
done < <(find tests/commercial/ -type f ! -name '.gitkeep' -print0 2>/dev/null)
fi
# 4. Remove LICENSE-COMMERCIAL
if [ -f "LICENSE-COMMERCIAL" ]; then
rm -f "LICENSE-COMMERCIAL"
removed+=("LICENSE-COMMERCIAL")
echo "Removed file: LICENSE-COMMERCIAL"
fi
# 5. Remove files with LicenseRef-Commercial SPDX headers (outside node_modules)
while IFS= read -r -d '' file; do
if head -5 "$file" | grep -q "LicenseRef-Commercial"; then
rm -f "$file"
removed+=("$file")
echo "Removed SPDX-commercial file: $file"
fi
done < <(find . -type f \( -name '*.ts' -o -name '*.svelte' -o -name '*.rs' -o -name '*.css' \) \
! -path '*/node_modules/*' ! -path '*/target/*' -print0 2>/dev/null)
# 6. Strip commercial references from package.json (pro scripts/deps)
if [ -f "package.json" ]; then
if command -v node >/dev/null 2>&1; then
node -e "
const fs = require('fs');
const pkg = JSON.parse(fs.readFileSync('package.json', 'utf8'));
let changed = false;
if (pkg.scripts) {
for (const key of Object.keys(pkg.scripts)) {
if (key.includes('commercial') || key.includes(':pro')) {
delete pkg.scripts[key];
changed = true;
}
}
}
if (pkg.dependencies) {
for (const key of Object.keys(pkg.dependencies)) {
if (key.includes('agor-pro')) {
delete pkg.dependencies[key];
changed = true;
}
}
}
if (pkg.devDependencies) {
for (const key of Object.keys(pkg.devDependencies)) {
if (key.includes('agor-pro')) {
delete pkg.devDependencies[key];
changed = true;
}
}
}
if (changed) {
fs.writeFileSync('package.json', JSON.stringify(pkg, null, 2) + '\n');
console.log('Cleaned commercial references from package.json');
}
"
else
echo "Warning: node not available, skipping package.json cleanup"
fi
fi
# Summary
echo ""
echo "=== Strip complete ==="
echo "Files removed: ${#removed[@]}"
for f in "${removed[@]}"; do
echo " - $f"
done
# Final verification
echo ""
echo "=== Verification ==="
remaining=$(grep -rl "LicenseRef-Commercial" --include="*.ts" --include="*.svelte" \
--include="*.rs" --include="*.toml" --include="*.css" \
. 2>/dev/null | grep -v node_modules | grep -v target || true)
if [ -n "$remaining" ]; then
echo "WARNING: LicenseRef-Commercial references still found in:"
echo "$remaining"
exit 1
else
echo "No LicenseRef-Commercial references remain."
fi
if [ -d "agor-pro" ]; then
echo "WARNING: agor-pro/ directory still exists"
exit 1
fi
echo "All commercial content stripped successfully."