Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
25 commits
Select commit Hold shift + click to select a range
7e5d71d
Stop tracking config/data_model.ttl (generated at runtime)
bbartling Mar 15, 2026
cb70699
Ignore config/data_model.ttl; document dev branch in README
bbartling Mar 15, 2026
d96e930
Merge origin/master into master (resolve README develop branch wording)
bbartling Mar 21, 2026
209cabd
Merge branch 'master' of https://github.com/bbartling/open-fdd
bbartling Mar 23, 2026
c5bd521
Bump project and frontend versions to 2.0.7.
bbartling Mar 23, 2026
7251e8d
building MCP into open fdd
bbartling Mar 24, 2026
98100f7
getting ready to test open claw on modular open fdd
bbartling Mar 24, 2026
974eba1
getting ready to try open claw boot strap
bbartling Mar 24, 2026
f28c2dc
OpenClaw lab: rule/SPARQL catalog docs, bench hardening, MCP RAG fixes
bbartling Mar 24, 2026
0f1ce0e
docs(openclaw): handoff protocol, venv/bootstrap hints, gitignore lab…
bbartling Mar 25, 2026
b4fc266
feat(openclaw): open-fdd-lab SKILL.md, references, scripts, assets
bbartling Mar 25, 2026
963e31c
fix: CodeRabbit nits (mcp_rag, e2e, fault_schedule, ansible); docs: t…
bbartling Mar 25, 2026
55a0fdd
docs(openclaw): issues_log git push resolution note
bbartling Mar 25, 2026
1bf4e67
docs(openclaw): long_run_lab_pass.md in skill bundle (GitHub-backed)
bbartling Mar 25, 2026
891557a
fix(openclaw): verify_with_log.sh + doc avoid mangled ts in nohup
bbartling Mar 25, 2026
0258bf6
docs(openclaw): background-job handoff paste + throttle/context in sk…
bbartling Mar 25, 2026
bf133da
docs(openclaw): legacy automated-testing map and bootstrap read order
bbartling Mar 25, 2026
216251c
docs(openclaw): 5-bullet session status contract + checklists
bbartling Mar 25, 2026
2b378c4
docs: engine-only IoT integration and pandas RuleRunner path
bbartling Mar 25, 2026
71da4a9
ci(docs): PyPI publish workflow for open-fdd + release how-to
bbartling Mar 25, 2026
ddf3d61
chore: release 2.0.8 (open-fdd, frontend, openfdd-engine 0.1.1)
bbartling Mar 25, 2026
803559d
ci(docs): PyPI publish on Python 3.14; document 403 Forbidden causes
bbartling Mar 25, 2026
ae98629
ci(pypi): use Trusted Publishing OIDC via gh-action-pypi-publish
bbartling Mar 25, 2026
c0df15a
chore: resolve merge with master — keep OIDC PyPI workflows
bbartling Mar 25, 2026
2831e17
Merge remote-tracking branch 'origin/develop/v2.0.7' into develop/v2.0.8
bbartling Mar 26, 2026
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
13 changes: 7 additions & 6 deletions .github/workflows/publish-open-fdd.yml
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ on:

permissions:
contents: read
id-token: write

jobs:
build-and-publish:
Expand All @@ -19,7 +20,7 @@ jobs:
- name: Setup Python
uses: actions/setup-python@v5
with:
python-version: "3.12"
python-version: "3.14"

- name: Build package
run: |
Expand All @@ -28,10 +29,10 @@ jobs:
python -m build
twine check dist/*

# PyPI Trusted Publishing (OIDC) — no TWINE_PASSWORD secret required.
# Configure each PyPI project: Publishing → add GitHub trusted publisher for this workflow file.
- name: Publish to PyPI
if: startsWith(github.ref, 'refs/tags/open-fdd-v')
env:
TWINE_USERNAME: __token__
TWINE_PASSWORD: ${{ secrets.PYPI_OPENFDD_TOKEN }}
run: |
twine upload dist/*
uses: pypa/gh-action-pypi-publish@release/v1
with:
packages-dir: dist/
Comment on lines +36 to +38
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo "Current workflow references:"
rg -n 'gh-action-pypi-publish@' .github/workflows

echo
echo "Resolve current commit behind release/v1:"
gh api repos/pypa/gh-action-pypi-publish/commits/release/v1 --jq '.sha'

Repository: bbartling/open-fdd

Length of output: 490


🏁 Script executed:

# Verify the exact content of the file at the specified lines
cat -n .github/workflows/publish-open-fdd.yml | sed -n '30,45p'

Repository: bbartling/open-fdd

Length of output: 519


🌐 Web query:

GitHub Actions pinning to commit SHA security best practices

💡 Result:

Pinning GitHub Actions to a full-length commit SHA is the recommended security best practice to ensure immutability and prevent supply chain attacks where malicious code could be injected via tag overwrites. Key best practices: - Always pin to full-length commit SHAs (40 characters), not short SHAs or tags like 'v1'. Example: - uses: actions/checkout@692973e # v4.1.7 Verify the SHA is from the official repository, not a fork. - Prioritize high-risk third-party actions (those handling secrets or sensitive operations). - Use GitHub policies to enforce SHA pinning at repository/organization level. - Periodically update pins using Dependabot or Renovate (they recognize version comments like # v4.1.7). - Audit action source code and prefer verified creators from GitHub Marketplace. - Tools like Hyland/github-actions-ensure-sha-pinned-actions can automate conversion of tags to SHAs. - Combine with other hardening: minimize GITHUB_TOKEN permissions, use OIDC, restrict permissions. This mitigates risks like tag force-pushing malicious code, as SHAs are immutable (requiring SHA-1 collision attacks, which are infeasible). Note: SHA-pinned actions won't get Dependabot vulnerability alerts (only for semver tags), so monitor manually or via other tools.

Citations:


🏁 Script executed:

# Check how other actions are pinned in this workflow file
cat -n .github/workflows/publish-open-fdd.yml | head -40

Repository: bbartling/open-fdd

Length of output: 1270


🏁 Script executed:

# Check both workflow files that reference gh-action-pypi-publish
echo "=== publish-open-fdd.yml ===" && grep -A 2 -B 2 'gh-action-pypi-publish' .github/workflows/publish-open-fdd.yml
echo
echo "=== publish-openfdd-engine.yml ===" && grep -A 2 -B 2 'gh-action-pypi-publish' .github/workflows/publish-openfdd-engine.yml

Repository: bbartling/open-fdd

Length of output: 528


Pin gh-action-pypi-publish to an immutable commit SHA.

Line 36 uses @release/v1, a mutable ref that can be exploited for supply chain attacks if the tag is force-pushed. Pinning to a full-length commit SHA hardens the release pipeline against upstream tag overwrites.

🔒 Suggested change
-        uses: pypa/gh-action-pypi-publish@release/v1
+        uses: pypa/gh-action-pypi-publish@<FULL_LENGTH_COMMIT_SHA>
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In @.github/workflows/publish-open-fdd.yml around lines 36 - 38, Replace the
mutable ref pypa/gh-action-pypi-publish@release/v1 with an immutable full commit
SHA to harden the workflow: locate the uses entry referencing
"pypa/gh-action-pypi-publish@release/v1" and change it to
"pypa/gh-action-pypi-publish@<full-commit-sha>" (use the repository commit SHA
you validated), keep the existing with: packages-dir: dist/ intact, and commit
the updated workflow so the action is pinned to that specific immutable commit.

13 changes: 5 additions & 8 deletions .github/workflows/publish-openfdd-engine.yml
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ on:

permissions:
contents: read
id-token: write

jobs:
build-and-publish:
Expand All @@ -19,7 +20,7 @@ jobs:
- name: Setup Python
uses: actions/setup-python@v5
with:
python-version: "3.12"
python-version: "3.14"

- name: Build package
working-directory: packages/openfdd-engine
Expand All @@ -31,10 +32,6 @@ jobs:

- name: Publish to PyPI
if: startsWith(github.ref, 'refs/tags/openfdd-engine-v')
working-directory: packages/openfdd-engine
env:
TWINE_USERNAME: __token__
TWINE_PASSWORD: ${{ secrets.PYPI_OPENFDD_ENGINE_TOKEN }}
run: |
twine upload dist/*

uses: pypa/gh-action-pypi-publish@release/v1
with:
packages-dir: packages/openfdd-engine/dist/
Comment on lines +35 to +37
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major

🧩 Analysis chain

🏁 Script executed:

# Check if the file exists and read its contents
cat -n .github/workflows/publish-openfdd-engine.yml

Repository: bbartling/open-fdd

Length of output: 1177


🌐 Web query:

GitHub Actions @release/v1vs@v4 mutable pinning commit SHA best practices

💡 Result:

GitHub Actions best practices recommend pinning actions to full commit SHAs for maximum security against supply chain attacks, as tags like @v4 or @release/v1 are mutable and can be retargeted to malicious commits. @v4 refers to the latest minor/patch in the v4 major version (e.g., actions/checkout@v4 points to the current v4.x.x tag), while @release/v1 likely refers to a custom or action-specific tag like 'release/v1' in some release management actions (e.g., similar to ncipollo/release-action's v1 tag management), which is also mutable. SHA pinning example: uses: actions/checkout@08c6903 # v5.0.0 Add the version comment for readability and Dependabot/Renovate updates. Official GitHub docs emphasize SHA pinning for third-party actions, with policies to enforce it organization-wide. Major version tags (@v4) balance usability and security if you trust the creator, but SHA is preferred. Use tools like pinata, Renovate's pinGitHubActionDigestsToSemver, or Dependabot for automation. @release/v1 vs @v4: Both mutable tags; no specific distinction found, but treat as equivalent risk level—pin to SHA regardless.

Citations:


🏁 Script executed:

# Check for other workflow files
find .github/workflows -name "*.yml" -o -name "*.yaml" | head -20

Repository: bbartling/open-fdd

Length of output: 170


🏁 Script executed:

# Check the other workflow files for action pinning patterns
echo "=== ci.yml ===" && head -40 .github/workflows/ci.yml && echo -e "\n=== publish-open-fdd.yml ===" && head -40 .github/workflows/publish-open-fdd.yml

Repository: bbartling/open-fdd

Length of output: 1992


Pin the publish action to a full commit SHA.

On line 35, @release/v1 is a mutable tag and poses a supply chain security risk. Pin pypa/gh-action-pypi-publish to a full commit SHA with a version comment for readability, following GitHub Actions security best practices.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In @.github/workflows/publish-openfdd-engine.yml around lines 35 - 37, Replace
the mutable tag in the GitHub Actions step that uses
"pypa/gh-action-pypi-publish@release/v1" by pinning to a full commit SHA (e.g.,
@<full-commit-sha>) and add an inline comment indicating the readable version
(for example: # release/v1) to retain clarity; update the "uses:
pypa/gh-action-pypi-publish@release/v1" line to reference the full SHA so the
action is immutable and follows the security best practice described in the
review.

45 changes: 40 additions & 5 deletions docs/howto/openfdd_engine_pypi.md
Original file line number Diff line number Diff line change
Expand Up @@ -23,10 +23,45 @@ Two distributions are relevant for **contractors / pandas + YAML** workflows:
- Root **`pyproject.toml`** → `[project] version` for **`open-fdd`** (e.g. `2.0.8`).
- **`packages/openfdd-engine/pyproject.toml`** → `version` and `dependencies` → `open-fdd>=X.Y.Z` aligned with what you just published (or still satisfied by `>=`).
2. **Changelog / tag message** — note engine-only docs, IoT `RuleRunner` usage, etc., if applicable.
3. **PyPI tokens** (GitHub → repo → **Settings → Secrets**):
- **`PYPI_OPENFDD_TOKEN`** — API token for the **`open-fdd`** project on PyPI.
- **`PYPI_OPENFDD_ENGINE_TOKEN`** — API token for the **`openfdd-engine`** project on PyPI.
(Use [trusted publishing](https://docs.pypi.org/trusted-publishers/) later if you prefer OIDC over long-lived tokens.)

### PyPI upload auth (required once per project)

CI uses **[PyPI Trusted Publishing](https://docs.pypi.org/trusted-publishers/)** (OpenID Connect from GitHub). **No `TWINE_PASSWORD` / repo secrets** are required if this is configured.

For **each** PyPI project (`open-fdd` and `openfdd-engine`):

1. Log in to [pypi.org](https://pypi.org), open the project → **Manage project** → **Publishing**.
2. Under **Manage publishers**, add a **GitHub** publisher:
- **Owner:** `bbartling` (your GitHub org or user)
- **Repository name:** `open-fdd`
- **Workflow name:** must match the file name exactly:
- for **`open-fdd`** uploads → **`publish-open-fdd.yml`**
- for **`openfdd-engine`** uploads → **`publish-openfdd-engine.yml`**
3. Save. PyPI may show a **pending** publisher until the first successful run.

Workflows use **`pypa/gh-action-pypi-publish@release/v1`** with **`permissions: id-token: write`**. Official guide: [Publishing package distribution releases using GitHub Actions CI/CD workflows](https://docs.pypi.org/trusted-publishers/creating-a-project-through-oidc/).

**After changing workflows:** Git tag builds use the workflow YAML from the **tagged commit**. Merge the updated workflows to **`master`**, then either **delete and recreate** the release tags on the new commit or cut a **patch version** (e.g. `2.0.9`) and new tags so Actions picks up OIDC.

### Fallback: API token instead of OIDC

If you cannot use trusted publishing, edit the **Publish to PyPI** step in the workflow to pass a secret, for example:

```yaml
uses: pypa/gh-action-pypi-publish@release/v1
with:
packages-dir: dist/
password: ${{ secrets.PYPI_OPENFDD_TOKEN }}
```
Comment on lines +50 to +55
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟡 Minor

Clarify fallback snippet for openfdd-engine path.

The example on Lines 50-55 uses packages-dir: dist/, which is correct for open-fdd but not for openfdd-engine (that workflow uses packages/openfdd-engine/dist/). A copy/paste here can cause failed uploads.

📝 Suggested doc tweak
 uses: pypa/gh-action-pypi-publish@release/v1
 with:
   packages-dir: dist/
   password: ${{ secrets.PYPI_OPENFDD_TOKEN }}
+
+# For openfdd-engine workflow, use:
+# packages-dir: packages/openfdd-engine/dist/
+# password: ${{ secrets.PYPI_OPENFDD_ENGINE_TOKEN }}
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@docs/howto/openfdd_engine_pypi.md` around lines 50 - 55, The snippet uses
packages-dir: dist/ which is correct for open-fdd but wrong for the
openfdd-engine workflow; update the docs to clarify the fallback path for the
openfdd-engine workflow by adding or replacing the example to show packages-dir:
packages/openfdd-engine/dist/ (or state both options and instruct readers to use
the engine-specific path when publishing openfdd-engine), and mention the exact
YAML key packages-dir so readers know which value to change.


Use a **project-scoped** PyPI token for the matching project. Empty or wrong secret still yields **403**.

### If CI shows `HTTPError: 403 Forbidden`

- **OIDC not configured** on the PyPI project for that **exact** workflow filename, or publisher still **pending**.
- **Wrong workflow name** in PyPI (typo vs `publish-open-fdd.yml` / `publish-openfdd-engine.yml`).
- **Tag points to an old commit** that used `twine` + missing secrets — merge OIDC workflows and re-tag.
- **Version already exists** on PyPI — bump version and use a new tag.

---

Expand Down Expand Up @@ -64,7 +99,7 @@ git push origin open-fdd-v2.0.8
- Package path: **`packages/openfdd-engine`**
- Workflow: **`.github/workflows/publish-openfdd-engine.yml`**
- Tag pattern: **`openfdd-engine-v*`** (e.g. `openfdd-engine-v0.1.1`)
- Secret: **`PYPI_OPENFDD_ENGINE_TOKEN`**
- **CI upload:** same **Trusted Publishing** setup as above (workflow **`publish-openfdd-engine.yml`** on this repo). Optional **token fallback** is documented in §1.

Local build:

Expand Down
Loading