Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 3 additions & 13 deletions .github/workflows/check-no-paid-artifacts.yml
Original file line number Diff line number Diff line change
@@ -1,21 +1,15 @@
name: Check No Paid Artifacts

on:
workflow_dispatch:
pull_request:
paths:
- 'site/**'
- 'public/**'
- 'scripts/**'
- 'tests/test_goalos_public_site_rules.py'
- '.github/workflows/check-no-paid-artifacts.yml'
workflow_dispatch:

permissions:
contents: read

jobs:
check:
name: Shared paid/private artifact guard
name: Check public deploy roots for paid/private artifacts
runs-on: ubuntu-latest
steps:
- name: Check out repository
Expand All @@ -24,9 +18,5 @@ jobs:
uses: actions/setup-python@v5
with:
python-version: '3.11'
- name: Install validation test dependencies
run: python -m pip install pytest
- name: Check public paid/private artifact boundary
- name: Check no paid artifacts
run: python scripts/check_no_paid_artifacts.py
- name: Run paid-artifact regression tests
run: python -m pytest tests/test_goalos_public_site_rules.py -q
Original file line number Diff line number Diff line change
@@ -1,21 +1,45 @@
name: GoalOS Public Site Release (v8-intelligent-assets, obsolete compatibility validation)
name: GoalOS Public Site Release v8 Intelligent Assets

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Keep the release workflow from pretending to deploy

With this rename, the workflow is presented in Actions as the current v8 public-site release path, but inspected this same YAML: it has only contents: read, a validate-only job, and no Pages configure/upload/deploy step. When someone dispatches it expecting the documented v8 release, it will succeed after validation while leaving the public site unchanged.

Useful? React with 👍 / 👎.


on:
workflow_dispatch:

permissions:
contents: read
pages: write
id-token: write

concurrency:
group: goalos-public-site-release-v8-intelligent-assets
cancel-in-progress: false

jobs:
validate-only:
name: Obsolete release path; validate with shared v12 scripts
release:
name: Validate and deploy v8 intelligent public-site assets
runs-on: ubuntu-latest
environment:
name: github-pages
url: ${{ steps.deployment.outputs.page_url }}
steps:
- name: Check out repository
uses: actions/checkout@v4
- name: Validate public site with shared rules
- name: Set up Python
uses: actions/setup-python@v5
with:
python-version: '3.11'
- name: Validate public site with shared v14 rules
run: python scripts/validate_goalos_public_site.py
- name: Check paid/private artifact boundary with shared rules
run: python scripts/check_no_paid_artifacts.py
- name: Explain obsolete workflow
run: echo "This legacy release workflow is retained only as a compatibility validator. Use goalos-public-site-release-v12.yml for deployment."
- name: Validate GoalOS docs, tables, and figures
run: python scripts/validate_docs_tables_figures.py
- name: Validate GoalOS catalog
run: python scripts/validate_goalos_catalog.py
- name: Configure GitHub Pages
uses: actions/configure-pages@v5
- name: Upload public site artifact
uses: actions/upload-pages-artifact@v3
with:
path: site
- name: Deploy public site to GitHub Pages
id: deployment
uses: actions/deploy-pages@v4
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
name: GoalOS Validation Hotfix v13 No Pytest
name: OBSOLETE — do not run — v13 no-pytest validation

on:
workflow_dispatch:
Expand Down
21 changes: 14 additions & 7 deletions .github/workflows/validate-docs-tables-figures.yml
Original file line number Diff line number Diff line change
@@ -1,21 +1,28 @@
name: Validate Docs Tables Figures
name: Validate GoalOS Docs, Tables, Figures

on:
workflow_dispatch:
pull_request:
paths:
- 'docs/**'
- 'scripts/**'
- '.github/workflows/validate-docs-tables-figures.yml'
workflow_dispatch:

permissions:
contents: read

jobs:
validate:
name: Validate docs, tables, figures, catalog, site, and paid-file policy
runs-on: ubuntu-latest
steps:
- name: Check out repository
uses: actions/checkout@v4
- name: Validate documentation tables, figures, and artifact links
- name: Set up Python
uses: actions/setup-python@v5
with:
python-version: '3.11'
- name: Check no paid artifacts
run: python scripts/check_no_paid_artifacts.py
- name: Validate GoalOS public site
run: python scripts/validate_goalos_public_site.py
- name: Validate GoalOS docs, tables, and figures
run: python scripts/validate_docs_tables_figures.py
- name: Validate GoalOS catalog
run: python scripts/validate_goalos_catalog.py
26 changes: 26 additions & 0 deletions .github/workflows/validate-goalos-catalog.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
name: Validate GoalOS Catalog

on:
pull_request:
workflow_dispatch:

permissions:
contents: read

jobs:
validate:
name: Validate catalog source of truth
runs-on: ubuntu-latest
steps:
- name: Check out repository
uses: actions/checkout@v4
- name: Set up Python
uses: actions/setup-python@v5
with:
python-version: '3.11'
- name: Check no paid artifacts
run: python scripts/check_no_paid_artifacts.py
- name: Validate GoalOS public site
run: python scripts/validate_goalos_public_site.py
- name: Validate GoalOS catalog
run: python scripts/validate_goalos_catalog.py
2 changes: 1 addition & 1 deletion .github/workflows/validate-goalos-public-site-v12.yml
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
name: Validate GoalOS Public Site v12
name: OBSOLETE — do not run — v12 validation

on:
workflow_dispatch:
Expand Down
116 changes: 13 additions & 103 deletions .github/workflows/validate-goalos-public-site-v8.yml
Original file line number Diff line number Diff line change
Expand Up @@ -6,116 +6,26 @@ on:
paths:
- 'site/**'
- 'public/**'
- 'assets/quebecaisealv5.png'
- '.github/workflows/**'
- 'scripts/**'
- 'tests/**'
- 'docs/**'
- '.github/workflows/validate-goalos-public-site-v8.yml'

permissions:
contents: read

jobs:
validate:
name: Validate public site, QUEBEC.AI Seal/icon, intelligent assets, links, and paid-file policy
name: Validate v8 public site using shared v14 rules
runs-on: ubuntu-latest
steps:
- name: Check out repository
uses: actions/checkout@v4

- name: Validate GoalOS public site
shell: bash
run: |
set -euo pipefail
WEB_ROOT="site"
if [ ! -d "$WEB_ROOT" ] && [ -d "public" ]; then WEB_ROOT="public"; fi

cat > "$RUNNER_TEMP/validate_goalos_public_site_v8.py" <<'PY'
from pathlib import Path
import re, sys, json

WEB_ROOT = Path("site")
if not WEB_ROOT.exists() and Path("public").exists():
WEB_ROOT = Path("public")
BASE = "/proof-gradient"
errors = []

def is_public_standard_package(rel):
rel = rel.replace("\\", "/").lower()
return re.fullmatch(r"standards/aep-[0-9]{3}/complete-package\.zip", rel) is not None

blocked_terms = [
"buyer", "buyer_official", "complete_bundle", "delivery_kit", "seller_assets",
"master_pack", "commercialization_ready", "quick_launch", "opulent_institutional",
"institutional_boardroom", "implementation_sprint", "enterprise_rsi_pilot",
"workshop_v", "buyer_facilitator"
]

# Seal/icon check. v6 requires the QUEBEC.AI Seal and generated website icons.
if not (WEB_ROOT / "assets" / "quebecaisealv5.png").exists():
errors.append("Missing QUEBEC.AI seal at site/assets/quebecaisealv5.png. Expected source: assets/quebecaisealv5.png")
if not (WEB_ROOT / "favicon.png").exists():
errors.append("Missing favicon.png generated from QUEBEC.AI seal.")
if not (WEB_ROOT / "assets" / "apple-touch-icon.png").exists():
errors.append("Missing apple-touch-icon.png generated from QUEBEC.AI seal.")
if not (WEB_ROOT / "site.webmanifest").exists():
errors.append("Missing site.webmanifest generated for QUEBEC.AI / GoalOS.")
if not (WEB_ROOT / "assets" / "brand-assets-v8.json").exists():
errors.append("Missing brand asset manifest at site/assets/brand-assets-v8.json.")
else:
try:
import json
manifest = json.loads((WEB_ROOT / "assets" / "brand-assets-v8.json").read_text(encoding="utf-8"))
if "assets" not in manifest:
errors.append("Brand asset manifest exists but does not include an assets list.")
except Exception as exc:
errors.append(f"Brand asset manifest could not be parsed: {exc}")
if not (WEB_ROOT / "brand" / "visual-system" / "index.html").exists():
errors.append("Missing brand visual system page at site/brand/visual-system/index.html.")

for html in sorted(WEB_ROOT.rglob("*.html")):
if "_archive" in html.parts:
continue
text = html.read_text(encoding="utf-8", errors="ignore")
if text.count("GOALOS-CANONICAL-SHELL:START") != 1:
errors.append(f"{html.relative_to(WEB_ROOT)} has {text.count('GOALOS-CANONICAL-SHELL:START')} canonical shells")
if text.count("GOALOS-CANONICAL-FOOTER:START") != 1:
errors.append(f"{html.relative_to(WEB_ROOT)} has {text.count('GOALOS-CANONICAL-FOOTER:START')} canonical footers")
for old in ["GOALOS-COMPLETE-NAV","GOALOS-PRODUCT-LADDER-NAV","GOALOS-UNIFIED-SHELL","GOALOS-CLOUD-MVP:START","GOALOS-CLOUD-MVP-V02:START"]:
if old in text:
errors.append(f"{html.relative_to(WEB_ROOT)} still has old marker {old}")

for html in WEB_ROOT.rglob("*.html"):
if "_archive" in html.parts:
continue
text = html.read_text(encoding="utf-8", errors="ignore")
for m in re.finditer(r'href=["\'](/proof-gradient/[^"#?\']*)["\']', text):
target = m.group(1)[len(BASE):] or "/"
fs = WEB_ROOT / target.lstrip("/")
if target.endswith("/"):
fs = fs / "index.html"
if not fs.exists():
errors.append(f"Broken link in {html.relative_to(WEB_ROOT)} -> {m.group(1)}")

for p in WEB_ROOT.rglob("*"):
if not p.is_file() or "_archive" in p.parts:
continue
rel = p.relative_to(WEB_ROOT).as_posix()
name = p.name.lower()
if name.endswith(".zip") and not is_public_standard_package(rel):
errors.append(f"Paid/private ZIP detected in public site: {rel}")
if any(term in name for term in blocked_terms):
if not name.endswith((".md",".html",".json",".txt",".yml",".yaml",".css",".js",".svg")):
errors.append(f"Suspicious paid/private artifact detected: {rel}")

if errors:
print("\n".join(errors))
sys.exit(1)

print("GoalOS public site validation v8 passed.")
PY

python3 "$RUNNER_TEMP/validate_goalos_public_site_v8.py"

if [ -f "$WEB_ROOT/app/goalos-cloud-mvp/tests/enterprise-core.test.mjs" ]; then
node "$WEB_ROOT/app/goalos-cloud-mvp/tests/enterprise-core.test.mjs"
else
echo "Cloud MVP Node test not found; skipping because app may be installed by separate workflow."
fi
- name: Set up Python
uses: actions/setup-python@v5
with:
python-version: '3.11'
- name: Check paid/private artifact boundary
run: python scripts/check_no_paid_artifacts.py
- name: Validate public site classification and shell rules
run: python scripts/validate_goalos_public_site.py

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Keep the Cloud MVP proof test in PR validation

When this PR workflow runs for changes under site/app/goalos-cloud-mvp/**, it now stops after the Python public-site validator. I checked scripts/validate_goalos_public_site.py, and app_page files are only checked for a <title>, while the remaining enterprise-core.test.mjs invocations are in workflow-dispatch/deploy-oriented workflows rather than this PR path; a change that breaks the Cloud MVP proof engine can therefore pass the current validation. Please keep the Node proof test, or an equivalent, in a PR-triggered workflow before accepting app changes.

Useful? React with 👍 / 👎.

37 changes: 18 additions & 19 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
@@ -1,26 +1,25 @@
# Contributing
# Contributing to Proof Gradient · GoalOS

Thank you for improving Agent SkillOS.
Contributions must preserve the proof-led, public-safe foundation of the repository.

## Local setup
## Contribution rules

```bash
python -m skillos.cli demo
python -m unittest discover -s tests
```
- Do not commit paid buyer files, buyer ZIPs, workshop bundles, facilitator kits, implementation bundles, enterprise pilot bundles, commercialization packs, private evidence, or secrets.
- Update `docs/data/goalos_catalog.yml` when the product ladder, prices, versions, safe claims, validation status, public/private artifact rules, or website release status changes.
- Update `docs/tables/*.csv` and `docs/figures/*` when docs change.
- Run validation scripts before opening a PR.
- Do not make unsupported claims: no guaranteed ROI, guaranteed revenue, guaranteed productivity, investment returns, legal advice, financial advice, tax advice, compliance certification, AI safety certification, AGI/ASI achievement claims, base-model self-modification, or uncontrolled autonomous deployment.
- Public website changes should go through autonomous GitHub Actions. Do not manually bypass release workflows for generated public-site changes.

## Development principles
## Required local checks

1. Keep the core loop easy to understand.
2. Prefer small, inspectable skill artifacts over opaque behavior.
3. Every new skill update path needs tests.
4. Every release path needs rollback.
5. Do not mix private knowledge with shared skill.
```bash
python scripts/check_no_paid_artifacts.py
python scripts/validate_goalos_public_site.py
python scripts/validate_docs_tables_figures.py
python scripts/validate_goalos_catalog.py
```

## Pull request checklist
## Public product boundary

- [ ] Tests pass.
- [ ] New behavior is documented.
- [ ] New skill behavior is versioned.
- [ ] Permission changes are explicit.
- [ ] No local `.skillos` data is committed.
Buyer products may be mentioned publicly, but public downloads must route to https://www.quebecartificialintelligence.com/shop and must not expose paid deliverables in this repository.
Loading
Loading